Repository: wpCloud/wp-stateless Branch: latest Commit: 2a64ef967e77 Files: 2439 Total size: 15.3 MB Directory structure: gitextract_pxv_oo3a/ ├── .github/ │ ├── dependabot.yml │ └── workflows/ │ ├── publish-release.yml │ └── security-scan.yml ├── .gitignore ├── LICENSE ├── SECURITY.md ├── changelog.txt ├── changes.md ├── composer.json ├── l10n.php ├── lib/ │ ├── Google/ │ │ ├── CHANGELOG.md │ │ ├── CODE_OF_CONDUCT.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── SECURITY.md │ │ ├── UPGRADING.md │ │ ├── composer.json │ │ ├── phpstan.neon.dist │ │ ├── src/ │ │ │ ├── AccessToken/ │ │ │ │ ├── Revoke.php │ │ │ │ └── Verify.php │ │ │ ├── AuthHandler/ │ │ │ │ ├── AuthHandlerFactory.php │ │ │ │ ├── Guzzle6AuthHandler.php │ │ │ │ └── Guzzle7AuthHandler.php │ │ │ ├── Client.php │ │ │ ├── Collection.php │ │ │ ├── Exception.php │ │ │ ├── Http/ │ │ │ │ ├── Batch.php │ │ │ │ ├── MediaFileUpload.php │ │ │ │ └── REST.php │ │ │ ├── Model.php │ │ │ ├── Service/ │ │ │ │ ├── Exception.php │ │ │ │ ├── README.md │ │ │ │ └── Resource.php │ │ │ ├── Service.php │ │ │ ├── Task/ │ │ │ │ ├── Composer.php │ │ │ │ ├── Exception.php │ │ │ │ ├── Retryable.php │ │ │ │ └── Runner.php │ │ │ ├── Utils/ │ │ │ │ └── UriTemplate.php │ │ │ └── aliases.php │ │ └── vendor/ │ │ ├── autoload.php │ │ ├── bin/ │ │ │ └── google-cloud-batch │ │ ├── brick/ │ │ │ └── math/ │ │ │ ├── CHANGELOG.md │ │ │ ├── LICENSE │ │ │ ├── composer.json │ │ │ ├── psalm-baseline.xml │ │ │ └── src/ │ │ │ ├── BigDecimal.php │ │ │ ├── BigInteger.php │ │ │ ├── BigNumber.php │ │ │ ├── BigRational.php │ │ │ ├── Exception/ │ │ │ │ ├── DivisionByZeroException.php │ │ │ │ ├── IntegerOverflowException.php │ │ │ │ ├── MathException.php │ │ │ │ ├── NegativeNumberException.php │ │ │ │ ├── NumberFormatException.php │ │ │ │ └── RoundingNecessaryException.php │ │ │ ├── Internal/ │ │ │ │ ├── Calculator/ │ │ │ │ │ ├── BcMathCalculator.php │ │ │ │ │ ├── GmpCalculator.php │ │ │ │ │ └── NativeCalculator.php │ │ │ │ └── Calculator.php │ │ │ └── RoundingMode.php │ │ ├── composer/ │ │ │ ├── ClassLoader.php │ │ │ ├── InstalledVersions.php │ │ │ ├── LICENSE │ │ │ ├── autoload_classmap.php │ │ │ ├── autoload_files.php │ │ │ ├── autoload_namespaces.php │ │ │ ├── autoload_psr4.php │ │ │ ├── autoload_real.php │ │ │ ├── autoload_static.php │ │ │ ├── installed.json │ │ │ ├── installed.php │ │ │ └── platform_check.php │ │ ├── firebase/ │ │ │ └── php-jwt/ │ │ │ ├── CHANGELOG.md │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── composer.json │ │ │ └── src/ │ │ │ ├── BeforeValidException.php │ │ │ ├── CachedKeySet.php │ │ │ ├── ExpiredException.php │ │ │ ├── JWK.php │ │ │ ├── JWT.php │ │ │ ├── JWTExceptionWithPayloadInterface.php │ │ │ ├── Key.php │ │ │ └── SignatureInvalidException.php │ │ ├── google/ │ │ │ ├── apiclient-services/ │ │ │ │ ├── LICENSE │ │ │ │ ├── README.md │ │ │ │ ├── SECURITY.md │ │ │ │ ├── autoload.php │ │ │ │ ├── composer.json │ │ │ │ └── src/ │ │ │ │ ├── Storage/ │ │ │ │ │ ├── AdvanceRelocateBucketOperationRequest.php │ │ │ │ │ ├── AnywhereCache.php │ │ │ │ │ ├── AnywhereCaches.php │ │ │ │ │ ├── Bucket.php │ │ │ │ │ ├── BucketAccessControl.php │ │ │ │ │ ├── BucketAccessControlProjectTeam.php │ │ │ │ │ ├── BucketAccessControls.php │ │ │ │ │ ├── BucketAutoclass.php │ │ │ │ │ ├── BucketBilling.php │ │ │ │ │ ├── BucketCors.php │ │ │ │ │ ├── BucketCustomPlacementConfig.php │ │ │ │ │ ├── BucketEncryption.php │ │ │ │ │ ├── BucketEncryptionCustomerManagedEncryptionEnforcementConfig.php │ │ │ │ │ ├── BucketEncryptionCustomerSuppliedEncryptionEnforcementConfig.php │ │ │ │ │ ├── BucketEncryptionGoogleManagedEncryptionEnforcementConfig.php │ │ │ │ │ ├── BucketHierarchicalNamespace.php │ │ │ │ │ ├── BucketIamConfiguration.php │ │ │ │ │ ├── BucketIamConfigurationBucketPolicyOnly.php │ │ │ │ │ ├── BucketIamConfigurationUniformBucketLevelAccess.php │ │ │ │ │ ├── BucketIpFilter.php │ │ │ │ │ ├── BucketIpFilterPublicNetworkSource.php │ │ │ │ │ ├── BucketIpFilterVpcNetworkSources.php │ │ │ │ │ ├── BucketLifecycle.php │ │ │ │ │ ├── BucketLifecycleRule.php │ │ │ │ │ ├── BucketLifecycleRuleAction.php │ │ │ │ │ ├── BucketLifecycleRuleCondition.php │ │ │ │ │ ├── BucketLogging.php │ │ │ │ │ ├── BucketObjectRetention.php │ │ │ │ │ ├── BucketOwner.php │ │ │ │ │ ├── BucketRetentionPolicy.php │ │ │ │ │ ├── BucketSoftDeletePolicy.php │ │ │ │ │ ├── BucketStorageLayout.php │ │ │ │ │ ├── BucketStorageLayoutCustomPlacementConfig.php │ │ │ │ │ ├── BucketStorageLayoutHierarchicalNamespace.php │ │ │ │ │ ├── BucketVersioning.php │ │ │ │ │ ├── BucketWebsite.php │ │ │ │ │ ├── Buckets.php │ │ │ │ │ ├── BulkRestoreObjectsRequest.php │ │ │ │ │ ├── Channel.php │ │ │ │ │ ├── ComposeRequest.php │ │ │ │ │ ├── ComposeRequestSourceObjects.php │ │ │ │ │ ├── ComposeRequestSourceObjectsObjectPreconditions.php │ │ │ │ │ ├── Expr.php │ │ │ │ │ ├── Folder.php │ │ │ │ │ ├── FolderPendingRenameInfo.php │ │ │ │ │ ├── Folders.php │ │ │ │ │ ├── GoogleLongrunningListOperationsResponse.php │ │ │ │ │ ├── GoogleLongrunningOperation.php │ │ │ │ │ ├── GoogleRpcStatus.php │ │ │ │ │ ├── HmacKey.php │ │ │ │ │ ├── HmacKeyMetadata.php │ │ │ │ │ ├── HmacKeysMetadata.php │ │ │ │ │ ├── ManagedFolder.php │ │ │ │ │ ├── ManagedFolders.php │ │ │ │ │ ├── Notification.php │ │ │ │ │ ├── Notifications.php │ │ │ │ │ ├── ObjectAccessControl.php │ │ │ │ │ ├── ObjectAccessControlProjectTeam.php │ │ │ │ │ ├── ObjectAccessControls.php │ │ │ │ │ ├── ObjectCustomContextPayload.php │ │ │ │ │ ├── Objects.php │ │ │ │ │ ├── Policy.php │ │ │ │ │ ├── PolicyBindings.php │ │ │ │ │ ├── RelocateBucketRequest.php │ │ │ │ │ ├── RelocateBucketRequestDestinationCustomPlacementConfig.php │ │ │ │ │ ├── Resource/ │ │ │ │ │ │ ├── AnywhereCache.php │ │ │ │ │ │ ├── AnywhereCaches.php │ │ │ │ │ │ ├── BucketAccessControls.php │ │ │ │ │ │ ├── Buckets.php │ │ │ │ │ │ ├── Channels.php │ │ │ │ │ │ ├── DefaultObjectAccessControls.php │ │ │ │ │ │ ├── Folders.php │ │ │ │ │ │ ├── ManagedFolders.php │ │ │ │ │ │ ├── Notifications.php │ │ │ │ │ │ ├── ObjectAccessControls.php │ │ │ │ │ │ ├── Objects.php │ │ │ │ │ │ ├── Operations.php │ │ │ │ │ │ ├── Projects.php │ │ │ │ │ │ ├── ProjectsHmacKeys.php │ │ │ │ │ │ └── ProjectsServiceAccount.php │ │ │ │ │ ├── RewriteResponse.php │ │ │ │ │ ├── ServiceAccount.php │ │ │ │ │ ├── StorageObject.php │ │ │ │ │ ├── StorageObjectContexts.php │ │ │ │ │ ├── StorageObjectCustomerEncryption.php │ │ │ │ │ ├── StorageObjectOwner.php │ │ │ │ │ ├── StorageObjectRetention.php │ │ │ │ │ └── TestIamPermissionsResponse.php │ │ │ │ └── Storage.php │ │ │ ├── auth/ │ │ │ │ ├── .repo-metadata.json │ │ │ │ ├── COPYING │ │ │ │ ├── LICENSE │ │ │ │ ├── README.md │ │ │ │ ├── SECURITY.md │ │ │ │ ├── VERSION │ │ │ │ ├── composer.json │ │ │ │ └── src/ │ │ │ │ ├── AccessToken.php │ │ │ │ ├── ApplicationDefaultCredentials.php │ │ │ │ ├── Cache/ │ │ │ │ │ ├── FileSystemCacheItemPool.php │ │ │ │ │ ├── InvalidArgumentException.php │ │ │ │ │ ├── MemoryCacheItemPool.php │ │ │ │ │ ├── SysVCacheItemPool.php │ │ │ │ │ └── TypedItem.php │ │ │ │ ├── CacheTrait.php │ │ │ │ ├── CredentialSource/ │ │ │ │ │ ├── AwsNativeSource.php │ │ │ │ │ ├── ExecutableSource.php │ │ │ │ │ ├── FileSource.php │ │ │ │ │ └── UrlSource.php │ │ │ │ ├── Credentials/ │ │ │ │ │ ├── AppIdentityCredentials.php │ │ │ │ │ ├── ExternalAccountCredentials.php │ │ │ │ │ ├── GCECredentials.php │ │ │ │ │ ├── IAMCredentials.php │ │ │ │ │ ├── ImpersonatedServiceAccountCredentials.php │ │ │ │ │ ├── InsecureCredentials.php │ │ │ │ │ ├── ServiceAccountCredentials.php │ │ │ │ │ ├── ServiceAccountJwtAccessCredentials.php │ │ │ │ │ └── UserRefreshCredentials.php │ │ │ │ ├── CredentialsLoader.php │ │ │ │ ├── ExecutableHandler/ │ │ │ │ │ ├── ExecutableHandler.php │ │ │ │ │ └── ExecutableResponseError.php │ │ │ │ ├── ExternalAccountCredentialSourceInterface.php │ │ │ │ ├── FetchAuthTokenCache.php │ │ │ │ ├── FetchAuthTokenInterface.php │ │ │ │ ├── GCECache.php │ │ │ │ ├── GetQuotaProjectInterface.php │ │ │ │ ├── GetUniverseDomainInterface.php │ │ │ │ ├── HttpHandler/ │ │ │ │ │ ├── Guzzle6HttpHandler.php │ │ │ │ │ ├── Guzzle7HttpHandler.php │ │ │ │ │ ├── HttpClientCache.php │ │ │ │ │ └── HttpHandlerFactory.php │ │ │ │ ├── Iam.php │ │ │ │ ├── IamSignerTrait.php │ │ │ │ ├── Logging/ │ │ │ │ │ ├── LoggingTrait.php │ │ │ │ │ ├── RpcLogEvent.php │ │ │ │ │ └── StdOutLogger.php │ │ │ │ ├── MetricsTrait.php │ │ │ │ ├── Middleware/ │ │ │ │ │ ├── AuthTokenMiddleware.php │ │ │ │ │ ├── ProxyAuthTokenMiddleware.php │ │ │ │ │ ├── ScopedAccessTokenMiddleware.php │ │ │ │ │ └── SimpleMiddleware.php │ │ │ │ ├── OAuth2.php │ │ │ │ ├── ProjectIdProviderInterface.php │ │ │ │ ├── ServiceAccountSignerTrait.php │ │ │ │ ├── SignBlobInterface.php │ │ │ │ ├── UpdateMetadataInterface.php │ │ │ │ └── UpdateMetadataTrait.php │ │ │ ├── cloud-core/ │ │ │ │ ├── .gitattributes │ │ │ │ ├── CODE_OF_CONDUCT.md │ │ │ │ ├── CONTRIBUTING.md │ │ │ │ ├── LICENSE │ │ │ │ ├── README.md │ │ │ │ ├── SECURITY.md │ │ │ │ ├── VERSION │ │ │ │ ├── bin/ │ │ │ │ │ └── google-cloud-batch │ │ │ │ ├── composer.json │ │ │ │ ├── perf-bootstrap.php │ │ │ │ ├── snippet-bootstrap.php │ │ │ │ ├── src/ │ │ │ │ │ ├── AnonymousCredentials.php │ │ │ │ │ ├── ApiHelperTrait.php │ │ │ │ │ ├── ArrayTrait.php │ │ │ │ │ ├── Batch/ │ │ │ │ │ │ ├── BatchDaemon.php │ │ │ │ │ │ ├── BatchDaemonTrait.php │ │ │ │ │ │ ├── BatchJob.php │ │ │ │ │ │ ├── BatchRunner.php │ │ │ │ │ │ ├── BatchTrait.php │ │ │ │ │ │ ├── ClosureSerializerInterface.php │ │ │ │ │ │ ├── ConfigStorageInterface.php │ │ │ │ │ │ ├── HandleFailureTrait.php │ │ │ │ │ │ ├── InMemoryConfigStorage.php │ │ │ │ │ │ ├── InterruptTrait.php │ │ │ │ │ │ ├── JobConfig.php │ │ │ │ │ │ ├── JobInterface.php │ │ │ │ │ │ ├── JobTrait.php │ │ │ │ │ │ ├── OpisClosureSerializer.php │ │ │ │ │ │ ├── OpisClosureSerializerV4.php │ │ │ │ │ │ ├── ProcessItemInterface.php │ │ │ │ │ │ ├── QueueOverflowException.php │ │ │ │ │ │ ├── Retry.php │ │ │ │ │ │ ├── SerializableClientTrait.php │ │ │ │ │ │ ├── SimpleJob.php │ │ │ │ │ │ ├── SimpleJobTrait.php │ │ │ │ │ │ ├── SysvConfigStorage.php │ │ │ │ │ │ └── SysvProcessor.php │ │ │ │ │ ├── Blob.php │ │ │ │ │ ├── ClientTrait.php │ │ │ │ │ ├── Compute/ │ │ │ │ │ │ ├── Metadata/ │ │ │ │ │ │ │ └── Readers/ │ │ │ │ │ │ │ ├── HttpHandlerReader.php │ │ │ │ │ │ │ ├── ReaderInterface.php │ │ │ │ │ │ │ └── StreamReader.php │ │ │ │ │ │ └── Metadata.php │ │ │ │ │ ├── ConcurrencyControlTrait.php │ │ │ │ │ ├── DebugInfoTrait.php │ │ │ │ │ ├── DetectProjectIdTrait.php │ │ │ │ │ ├── Duration.php │ │ │ │ │ ├── EmulatorTrait.php │ │ │ │ │ ├── Exception/ │ │ │ │ │ │ ├── AbortedException.php │ │ │ │ │ │ ├── BadRequestException.php │ │ │ │ │ │ ├── ConflictException.php │ │ │ │ │ │ ├── DeadlineExceededException.php │ │ │ │ │ │ ├── FailedPreconditionException.php │ │ │ │ │ │ ├── GoogleException.php │ │ │ │ │ │ ├── NotFoundException.php │ │ │ │ │ │ ├── ServerException.php │ │ │ │ │ │ └── ServiceException.php │ │ │ │ │ ├── ExponentialBackoff.php │ │ │ │ │ ├── GeoPoint.php │ │ │ │ │ ├── GrpcRequestWrapper.php │ │ │ │ │ ├── GrpcTrait.php │ │ │ │ │ ├── Iam/ │ │ │ │ │ │ ├── Iam.php │ │ │ │ │ │ ├── IamConnectionInterface.php │ │ │ │ │ │ ├── IamManager.php │ │ │ │ │ │ └── PolicyBuilder.php │ │ │ │ │ ├── InsecureCredentialsWrapper.php │ │ │ │ │ ├── Int64.php │ │ │ │ │ ├── Iterator/ │ │ │ │ │ │ ├── ItemIterator.php │ │ │ │ │ │ ├── ItemIteratorTrait.php │ │ │ │ │ │ ├── PageIterator.php │ │ │ │ │ │ └── PageIteratorTrait.php │ │ │ │ │ ├── JsonTrait.php │ │ │ │ │ ├── Lock/ │ │ │ │ │ │ ├── FlockLock.php │ │ │ │ │ │ ├── LockInterface.php │ │ │ │ │ │ ├── LockTrait.php │ │ │ │ │ │ ├── SemaphoreLock.php │ │ │ │ │ │ └── SymfonyLockAdapter.php │ │ │ │ │ ├── Logger/ │ │ │ │ │ │ ├── AppEngineFlexFormatter.php │ │ │ │ │ │ ├── AppEngineFlexFormatterV2.php │ │ │ │ │ │ ├── AppEngineFlexFormatterV3.php │ │ │ │ │ │ ├── AppEngineFlexHandler.php │ │ │ │ │ │ ├── AppEngineFlexHandlerFactory.php │ │ │ │ │ │ ├── AppEngineFlexHandlerV2.php │ │ │ │ │ │ ├── AppEngineFlexHandlerV3.php │ │ │ │ │ │ └── FormatterTrait.php │ │ │ │ │ ├── LongRunning/ │ │ │ │ │ │ ├── LROTrait.php │ │ │ │ │ │ ├── LongRunningClientConnection.php │ │ │ │ │ │ ├── LongRunningConnectionInterface.php │ │ │ │ │ │ ├── LongRunningOperation.php │ │ │ │ │ │ └── OperationResponseTrait.php │ │ │ │ │ ├── OptionsValidator.php │ │ │ │ │ ├── PhpArray.php │ │ │ │ │ ├── Report/ │ │ │ │ │ │ ├── CloudRunJobMetadataProvider.php │ │ │ │ │ │ ├── CloudRunMetadataProvider.php │ │ │ │ │ │ ├── CloudRunServiceMetadataProvider.php │ │ │ │ │ │ ├── EmptyMetadataProvider.php │ │ │ │ │ │ ├── GAEFlexMetadataProvider.php │ │ │ │ │ │ ├── GAEMetadataProvider.php │ │ │ │ │ │ ├── GAEStandardMetadataProvider.php │ │ │ │ │ │ ├── MetadataProviderInterface.php │ │ │ │ │ │ ├── MetadataProviderUtils.php │ │ │ │ │ │ └── SimpleMetadataProvider.php │ │ │ │ │ ├── RequestBuilder.php │ │ │ │ │ ├── RequestHandler.php │ │ │ │ │ ├── RequestProcessorTrait.php │ │ │ │ │ ├── RequestWrapper.php │ │ │ │ │ ├── RequestWrapperTrait.php │ │ │ │ │ ├── RestTrait.php │ │ │ │ │ ├── Retry.php │ │ │ │ │ ├── RetryDeciderTrait.php │ │ │ │ │ ├── ServiceBuilder.php │ │ │ │ │ ├── SysvTrait.php │ │ │ │ │ ├── Testing/ │ │ │ │ │ │ ├── ArrayHasSameValuesToken.php │ │ │ │ │ │ ├── CheckForClassTrait.php │ │ │ │ │ │ ├── DatastoreOperationRefreshTrait.php │ │ │ │ │ │ ├── FileListFilterIterator.php │ │ │ │ │ │ ├── GcTestListener.php │ │ │ │ │ │ ├── GrpcTestTrait.php │ │ │ │ │ │ ├── KeyPairGenerateTrait.php │ │ │ │ │ │ ├── Lock/ │ │ │ │ │ │ │ ├── MockGlobals.php │ │ │ │ │ │ │ └── MockValues.php │ │ │ │ │ │ ├── README.md │ │ │ │ │ │ ├── Reflection/ │ │ │ │ │ │ │ ├── DescriptionFactory.php │ │ │ │ │ │ │ ├── ReflectionHandlerFactory.php │ │ │ │ │ │ │ └── ReflectionHandlerV6.php │ │ │ │ │ │ ├── RegexFileFilter.php │ │ │ │ │ │ ├── Snippet/ │ │ │ │ │ │ │ ├── Container.php │ │ │ │ │ │ │ ├── Coverage/ │ │ │ │ │ │ │ │ ├── Coverage.php │ │ │ │ │ │ │ │ ├── ExcludeFilter.php │ │ │ │ │ │ │ │ ├── Scanner.php │ │ │ │ │ │ │ │ └── ScannerInterface.php │ │ │ │ │ │ │ ├── Fixtures.php │ │ │ │ │ │ │ ├── Parser/ │ │ │ │ │ │ │ │ ├── InvokeResult.php │ │ │ │ │ │ │ │ ├── Parser.php │ │ │ │ │ │ │ │ └── Snippet.php │ │ │ │ │ │ │ ├── SnippetTestCase.php │ │ │ │ │ │ │ └── keyfile-stub.json │ │ │ │ │ │ ├── StubTrait.php │ │ │ │ │ │ ├── System/ │ │ │ │ │ │ │ ├── DeletionQueue.php │ │ │ │ │ │ │ ├── KeyManager.php │ │ │ │ │ │ │ └── SystemTestCase.php │ │ │ │ │ │ └── TestHelpers.php │ │ │ │ │ ├── TimeTrait.php │ │ │ │ │ ├── Timestamp.php │ │ │ │ │ ├── TimestampTrait.php │ │ │ │ │ ├── Upload/ │ │ │ │ │ │ ├── AbstractUploader.php │ │ │ │ │ │ ├── MultipartUploader.php │ │ │ │ │ │ ├── ResumableUploader.php │ │ │ │ │ │ ├── SignedUrlUploader.php │ │ │ │ │ │ └── StreamableUploader.php │ │ │ │ │ ├── UriTrait.php │ │ │ │ │ ├── ValidateTrait.php │ │ │ │ │ ├── ValueMapperTrait.php │ │ │ │ │ └── WhitelistTrait.php │ │ │ │ ├── system-bootstrap.php │ │ │ │ └── unit-bootstrap.php │ │ │ ├── cloud-storage/ │ │ │ │ ├── .gitattributes │ │ │ │ ├── CODE_OF_CONDUCT.md │ │ │ │ ├── CONTRIBUTING.md │ │ │ │ ├── LICENSE │ │ │ │ ├── README.md │ │ │ │ ├── SECURITY.md │ │ │ │ ├── VERSION │ │ │ │ ├── composer.json │ │ │ │ └── src/ │ │ │ │ ├── Acl.php │ │ │ │ ├── Bucket.php │ │ │ │ ├── BucketIterator.php │ │ │ │ ├── Connection/ │ │ │ │ │ ├── ConnectionInterface.php │ │ │ │ │ ├── IamBucket.php │ │ │ │ │ ├── Rest.php │ │ │ │ │ ├── RetryTrait.php │ │ │ │ │ └── ServiceDefinition/ │ │ │ │ │ └── storage-v1.json │ │ │ │ ├── CreatedHmacKey.php │ │ │ │ ├── EncryptionTrait.php │ │ │ │ ├── HmacKey.php │ │ │ │ ├── Lifecycle.php │ │ │ │ ├── Notification.php │ │ │ │ ├── ObjectIterator.php │ │ │ │ ├── ObjectPageIterator.php │ │ │ │ ├── ReadStream.php │ │ │ │ ├── SigningHelper.php │ │ │ │ ├── StorageClient.php │ │ │ │ ├── StorageObject.php │ │ │ │ ├── StreamWrapper.php │ │ │ │ └── WriteStream.php │ │ │ ├── common-protos/ │ │ │ │ ├── CHANGELOG.md │ │ │ │ ├── CODE_OF_CONDUCT.md │ │ │ │ ├── CONTRIBUTING.md │ │ │ │ ├── LICENSE │ │ │ │ ├── README.md │ │ │ │ ├── SECURITY.md │ │ │ │ ├── VERSION │ │ │ │ ├── composer.json │ │ │ │ ├── metadata/ │ │ │ │ │ ├── Api/ │ │ │ │ │ │ ├── Annotations.php │ │ │ │ │ │ ├── Auth.php │ │ │ │ │ │ ├── Backend.php │ │ │ │ │ │ ├── Billing.php │ │ │ │ │ │ ├── Client.php │ │ │ │ │ │ ├── ConfigChange.php │ │ │ │ │ │ ├── Consumer.php │ │ │ │ │ │ ├── Context.php │ │ │ │ │ │ ├── Control.php │ │ │ │ │ │ ├── Distribution.php │ │ │ │ │ │ ├── Documentation.php │ │ │ │ │ │ ├── Endpoint.php │ │ │ │ │ │ ├── ErrorReason.php │ │ │ │ │ │ ├── FieldBehavior.php │ │ │ │ │ │ ├── FieldInfo.php │ │ │ │ │ │ ├── Http.php │ │ │ │ │ │ ├── Httpbody.php │ │ │ │ │ │ ├── Label.php │ │ │ │ │ │ ├── LaunchStage.php │ │ │ │ │ │ ├── Log.php │ │ │ │ │ │ ├── Logging.php │ │ │ │ │ │ ├── Metric.php │ │ │ │ │ │ ├── MonitoredResource.php │ │ │ │ │ │ ├── Monitoring.php │ │ │ │ │ │ ├── Policy.php │ │ │ │ │ │ ├── Quota.php │ │ │ │ │ │ ├── Resource.php │ │ │ │ │ │ ├── Routing.php │ │ │ │ │ │ ├── Service.php │ │ │ │ │ │ ├── SourceInfo.php │ │ │ │ │ │ ├── SystemParameter.php │ │ │ │ │ │ ├── Usage.php │ │ │ │ │ │ └── Visibility.php │ │ │ │ │ ├── Cloud/ │ │ │ │ │ │ ├── ExtendedOperations.php │ │ │ │ │ │ └── Location/ │ │ │ │ │ │ └── Locations.php │ │ │ │ │ ├── Google/ │ │ │ │ │ │ ├── Iam/ │ │ │ │ │ │ │ └── V1/ │ │ │ │ │ │ │ ├── IamPolicy.php │ │ │ │ │ │ │ ├── Logging/ │ │ │ │ │ │ │ │ └── AuditData.php │ │ │ │ │ │ │ ├── Options.php │ │ │ │ │ │ │ ├── Policy.php │ │ │ │ │ │ │ └── ResourcePolicyMember.php │ │ │ │ │ │ └── Logging/ │ │ │ │ │ │ └── Type/ │ │ │ │ │ │ ├── HttpRequest.php │ │ │ │ │ │ └── LogSeverity.php │ │ │ │ │ ├── Iam/ │ │ │ │ │ │ └── V1/ │ │ │ │ │ │ ├── IamPolicy.php │ │ │ │ │ │ ├── Logging/ │ │ │ │ │ │ │ └── AuditData.php │ │ │ │ │ │ ├── Options.php │ │ │ │ │ │ ├── Policy.php │ │ │ │ │ │ └── ResourcePolicyMember.php │ │ │ │ │ ├── Logging/ │ │ │ │ │ │ └── Type/ │ │ │ │ │ │ ├── HttpRequest.php │ │ │ │ │ │ └── LogSeverity.php │ │ │ │ │ ├── Rpc/ │ │ │ │ │ │ ├── Code.php │ │ │ │ │ │ ├── Context/ │ │ │ │ │ │ │ ├── AttributeContext.php │ │ │ │ │ │ │ └── AuditContext.php │ │ │ │ │ │ ├── ErrorDetails.php │ │ │ │ │ │ └── Status.php │ │ │ │ │ └── Type/ │ │ │ │ │ ├── CalendarPeriod.php │ │ │ │ │ ├── Color.php │ │ │ │ │ ├── Date.php │ │ │ │ │ ├── Datetime.php │ │ │ │ │ ├── Dayofweek.php │ │ │ │ │ ├── Decimal.php │ │ │ │ │ ├── Expr.php │ │ │ │ │ ├── Fraction.php │ │ │ │ │ ├── Interval.php │ │ │ │ │ ├── Latlng.php │ │ │ │ │ ├── LocalizedText.php │ │ │ │ │ ├── Money.php │ │ │ │ │ ├── Month.php │ │ │ │ │ ├── PhoneNumber.php │ │ │ │ │ ├── PostalAddress.php │ │ │ │ │ ├── Quaternion.php │ │ │ │ │ └── Timeofday.php │ │ │ │ ├── renovate.json │ │ │ │ └── src/ │ │ │ │ ├── Api/ │ │ │ │ │ ├── Advice.php │ │ │ │ │ ├── AuthProvider.php │ │ │ │ │ ├── AuthRequirement.php │ │ │ │ │ ├── Authentication.php │ │ │ │ │ ├── AuthenticationRule.php │ │ │ │ │ ├── Backend.php │ │ │ │ │ ├── BackendRule/ │ │ │ │ │ │ └── PathTranslation.php │ │ │ │ │ ├── BackendRule.php │ │ │ │ │ ├── Billing/ │ │ │ │ │ │ └── BillingDestination.php │ │ │ │ │ ├── Billing.php │ │ │ │ │ ├── ChangeType.php │ │ │ │ │ ├── ClientLibraryDestination.php │ │ │ │ │ ├── ClientLibraryOrganization.php │ │ │ │ │ ├── ClientLibrarySettings.php │ │ │ │ │ ├── CommonLanguageSettings.php │ │ │ │ │ ├── ConfigChange.php │ │ │ │ │ ├── Context.php │ │ │ │ │ ├── ContextRule.php │ │ │ │ │ ├── Control.php │ │ │ │ │ ├── CppSettings.php │ │ │ │ │ ├── CustomHttpPattern.php │ │ │ │ │ ├── Distribution/ │ │ │ │ │ │ ├── BucketOptions/ │ │ │ │ │ │ │ ├── Explicit.php │ │ │ │ │ │ │ ├── Exponential.php │ │ │ │ │ │ │ └── Linear.php │ │ │ │ │ │ ├── BucketOptions.php │ │ │ │ │ │ ├── Exemplar.php │ │ │ │ │ │ └── Range.php │ │ │ │ │ ├── Distribution.php │ │ │ │ │ ├── Documentation.php │ │ │ │ │ ├── DocumentationRule.php │ │ │ │ │ ├── DotnetSettings.php │ │ │ │ │ ├── Endpoint.php │ │ │ │ │ ├── ErrorReason.php │ │ │ │ │ ├── FieldBehavior.php │ │ │ │ │ ├── FieldInfo/ │ │ │ │ │ │ └── Format.php │ │ │ │ │ ├── FieldInfo.php │ │ │ │ │ ├── FieldPolicy.php │ │ │ │ │ ├── GoSettings.php │ │ │ │ │ ├── Http.php │ │ │ │ │ ├── HttpBody.php │ │ │ │ │ ├── HttpRule.php │ │ │ │ │ ├── JavaSettings.php │ │ │ │ │ ├── JwtLocation.php │ │ │ │ │ ├── LabelDescriptor/ │ │ │ │ │ │ └── ValueType.php │ │ │ │ │ ├── LabelDescriptor.php │ │ │ │ │ ├── LaunchStage.php │ │ │ │ │ ├── LogDescriptor.php │ │ │ │ │ ├── Logging/ │ │ │ │ │ │ └── LoggingDestination.php │ │ │ │ │ ├── Logging.php │ │ │ │ │ ├── MethodPolicy.php │ │ │ │ │ ├── MethodSettings/ │ │ │ │ │ │ └── LongRunning.php │ │ │ │ │ ├── MethodSettings.php │ │ │ │ │ ├── Metric.php │ │ │ │ │ ├── MetricDescriptor/ │ │ │ │ │ │ ├── MetricDescriptorMetadata/ │ │ │ │ │ │ │ └── TimeSeriesResourceHierarchyLevel.php │ │ │ │ │ │ ├── MetricDescriptorMetadata.php │ │ │ │ │ │ ├── MetricKind.php │ │ │ │ │ │ └── ValueType.php │ │ │ │ │ ├── MetricDescriptor.php │ │ │ │ │ ├── MetricRule.php │ │ │ │ │ ├── MonitoredResource.php │ │ │ │ │ ├── MonitoredResourceDescriptor.php │ │ │ │ │ ├── MonitoredResourceMetadata.php │ │ │ │ │ ├── Monitoring/ │ │ │ │ │ │ └── MonitoringDestination.php │ │ │ │ │ ├── Monitoring.php │ │ │ │ │ ├── NodeSettings.php │ │ │ │ │ ├── OAuthRequirements.php │ │ │ │ │ ├── Page.php │ │ │ │ │ ├── PhpSettings.php │ │ │ │ │ ├── ProjectProperties.php │ │ │ │ │ ├── Property/ │ │ │ │ │ │ └── PropertyType.php │ │ │ │ │ ├── Property.php │ │ │ │ │ ├── Publishing.php │ │ │ │ │ ├── PythonSettings/ │ │ │ │ │ │ └── ExperimentalFeatures.php │ │ │ │ │ ├── PythonSettings.php │ │ │ │ │ ├── Quota.php │ │ │ │ │ ├── QuotaLimit.php │ │ │ │ │ ├── ResourceDescriptor/ │ │ │ │ │ │ ├── History.php │ │ │ │ │ │ └── Style.php │ │ │ │ │ ├── ResourceDescriptor.php │ │ │ │ │ ├── ResourceReference.php │ │ │ │ │ ├── RoutingParameter.php │ │ │ │ │ ├── RoutingRule.php │ │ │ │ │ ├── RubySettings.php │ │ │ │ │ ├── SelectiveGapicGeneration.php │ │ │ │ │ ├── Service.php │ │ │ │ │ ├── SourceInfo.php │ │ │ │ │ ├── SystemParameter.php │ │ │ │ │ ├── SystemParameterRule.php │ │ │ │ │ ├── SystemParameters.php │ │ │ │ │ ├── TypeReference.php │ │ │ │ │ ├── Usage.php │ │ │ │ │ ├── UsageRule.php │ │ │ │ │ ├── Visibility.php │ │ │ │ │ └── VisibilityRule.php │ │ │ │ ├── Cloud/ │ │ │ │ │ ├── Iam/ │ │ │ │ │ │ └── V1/ │ │ │ │ │ │ ├── AuditConfig.php │ │ │ │ │ │ ├── AuditConfigDelta/ │ │ │ │ │ │ │ └── Action.php │ │ │ │ │ │ ├── AuditConfigDelta.php │ │ │ │ │ │ ├── AuditLogConfig/ │ │ │ │ │ │ │ └── LogType.php │ │ │ │ │ │ ├── AuditLogConfig.php │ │ │ │ │ │ ├── Binding.php │ │ │ │ │ │ ├── BindingDelta/ │ │ │ │ │ │ │ └── Action.php │ │ │ │ │ │ ├── BindingDelta.php │ │ │ │ │ │ ├── GetIamPolicyRequest.php │ │ │ │ │ │ ├── GetPolicyOptions.php │ │ │ │ │ │ ├── Policy.php │ │ │ │ │ │ ├── PolicyDelta.php │ │ │ │ │ │ ├── ResourcePolicyMember.php │ │ │ │ │ │ ├── SetIamPolicyRequest.php │ │ │ │ │ │ ├── TestIamPermissionsRequest.php │ │ │ │ │ │ └── TestIamPermissionsResponse.php │ │ │ │ │ ├── Location/ │ │ │ │ │ │ ├── GetLocationRequest.php │ │ │ │ │ │ ├── ListLocationsRequest.php │ │ │ │ │ │ ├── ListLocationsResponse.php │ │ │ │ │ │ └── Location.php │ │ │ │ │ ├── Logging/ │ │ │ │ │ │ └── Type/ │ │ │ │ │ │ ├── HttpRequest.php │ │ │ │ │ │ └── LogSeverity.php │ │ │ │ │ └── OperationResponseMapping.php │ │ │ │ ├── Iam/ │ │ │ │ │ └── V1/ │ │ │ │ │ └── Logging/ │ │ │ │ │ └── AuditData.php │ │ │ │ ├── Rpc/ │ │ │ │ │ ├── BadRequest/ │ │ │ │ │ │ └── FieldViolation.php │ │ │ │ │ ├── BadRequest.php │ │ │ │ │ ├── Code.php │ │ │ │ │ ├── Context/ │ │ │ │ │ │ ├── AttributeContext/ │ │ │ │ │ │ │ ├── Api.php │ │ │ │ │ │ │ ├── Auth.php │ │ │ │ │ │ │ ├── Peer.php │ │ │ │ │ │ │ ├── Request.php │ │ │ │ │ │ │ ├── Resource.php │ │ │ │ │ │ │ └── Response.php │ │ │ │ │ │ ├── AttributeContext.php │ │ │ │ │ │ └── AuditContext.php │ │ │ │ │ ├── DebugInfo.php │ │ │ │ │ ├── ErrorInfo.php │ │ │ │ │ ├── Help/ │ │ │ │ │ │ └── Link.php │ │ │ │ │ ├── Help.php │ │ │ │ │ ├── LocalizedMessage.php │ │ │ │ │ ├── PreconditionFailure/ │ │ │ │ │ │ └── Violation.php │ │ │ │ │ ├── PreconditionFailure.php │ │ │ │ │ ├── QuotaFailure/ │ │ │ │ │ │ └── Violation.php │ │ │ │ │ ├── QuotaFailure.php │ │ │ │ │ ├── RequestInfo.php │ │ │ │ │ ├── ResourceInfo.php │ │ │ │ │ ├── RetryInfo.php │ │ │ │ │ └── Status.php │ │ │ │ └── Type/ │ │ │ │ ├── CalendarPeriod.php │ │ │ │ ├── Color.php │ │ │ │ ├── Date.php │ │ │ │ ├── DateTime.php │ │ │ │ ├── DayOfWeek.php │ │ │ │ ├── Decimal.php │ │ │ │ ├── Expr.php │ │ │ │ ├── Fraction.php │ │ │ │ ├── Interval.php │ │ │ │ ├── LatLng.php │ │ │ │ ├── LocalizedText.php │ │ │ │ ├── Money.php │ │ │ │ ├── Month.php │ │ │ │ ├── PhoneNumber/ │ │ │ │ │ └── ShortCode.php │ │ │ │ ├── PhoneNumber.php │ │ │ │ ├── PostalAddress.php │ │ │ │ ├── Quaternion.php │ │ │ │ ├── TimeOfDay.php │ │ │ │ └── TimeZone.php │ │ │ ├── gax/ │ │ │ │ ├── .repo-metadata.json │ │ │ │ ├── CHANGELOG.md │ │ │ │ ├── CODE_OF_CONDUCT.md │ │ │ │ ├── LICENSE │ │ │ │ ├── README.md │ │ │ │ ├── SECURITY.md │ │ │ │ ├── VERSION │ │ │ │ ├── composer.json │ │ │ │ ├── metadata/ │ │ │ │ │ ├── ApiCore/ │ │ │ │ │ │ └── Testing/ │ │ │ │ │ │ └── Mocks.php │ │ │ │ │ ├── Google/ │ │ │ │ │ │ └── ApiCore/ │ │ │ │ │ │ └── Tests/ │ │ │ │ │ │ └── Unit/ │ │ │ │ │ │ └── Example.php │ │ │ │ │ └── README.md │ │ │ │ ├── phpstan.neon.dist │ │ │ │ ├── phpunit.xml.dist │ │ │ │ ├── renovate.json │ │ │ │ └── src/ │ │ │ │ ├── AgentHeader.php │ │ │ │ ├── ApiException.php │ │ │ │ ├── ApiKeyHeaderCredentials.php │ │ │ │ ├── ApiStatus.php │ │ │ │ ├── ArrayTrait.php │ │ │ │ ├── BidiStream.php │ │ │ │ ├── Call.php │ │ │ │ ├── ClientOptionsTrait.php │ │ │ │ ├── ClientStream.php │ │ │ │ ├── CredentialsWrapper.php │ │ │ │ ├── FixedSizeCollection.php │ │ │ │ ├── GPBLabel.php │ │ │ │ ├── GPBType.php │ │ │ │ ├── GapicClientTrait.php │ │ │ │ ├── GrpcSupportTrait.php │ │ │ │ ├── HeaderCredentialsInterface.php │ │ │ │ ├── InsecureCredentialsWrapper.php │ │ │ │ ├── InsecureRequestBuilder.php │ │ │ │ ├── Middleware/ │ │ │ │ │ ├── CredentialsWrapperMiddleware.php │ │ │ │ │ ├── FixedHeaderMiddleware.php │ │ │ │ │ ├── MiddlewareInterface.php │ │ │ │ │ ├── OperationsMiddleware.php │ │ │ │ │ ├── OptionsFilterMiddleware.php │ │ │ │ │ ├── PagedMiddleware.php │ │ │ │ │ ├── RequestAutoPopulationMiddleware.php │ │ │ │ │ ├── ResponseMetadataMiddleware.php │ │ │ │ │ ├── RetryMiddleware.php │ │ │ │ │ └── TransportCallMiddleware.php │ │ │ │ ├── OperationResponse.php │ │ │ │ ├── Options/ │ │ │ │ │ ├── CallOptions.php │ │ │ │ │ ├── ClientOptions.php │ │ │ │ │ ├── OptionsInterface.php │ │ │ │ │ ├── OptionsTrait.php │ │ │ │ │ ├── TransportOptions/ │ │ │ │ │ │ ├── GrpcFallbackTransportOptions.php │ │ │ │ │ │ ├── GrpcTransportOptions.php │ │ │ │ │ │ └── RestTransportOptions.php │ │ │ │ │ └── TransportOptions.php │ │ │ │ ├── Page.php │ │ │ │ ├── PageStreamingDescriptor.php │ │ │ │ ├── PagedListResponse.php │ │ │ │ ├── PathTemplate.php │ │ │ │ ├── PollingTrait.php │ │ │ │ ├── RequestBuilder.php │ │ │ │ ├── RequestParamsHeaderDescriptor.php │ │ │ │ ├── ResourceHelperTrait.php │ │ │ │ ├── ResourceTemplate/ │ │ │ │ │ ├── AbsoluteResourceTemplate.php │ │ │ │ │ ├── Parser.php │ │ │ │ │ ├── RelativeResourceTemplate.php │ │ │ │ │ ├── ResourceTemplateInterface.php │ │ │ │ │ └── Segment.php │ │ │ │ ├── RetrySettings.php │ │ │ │ ├── Serializer.php │ │ │ │ ├── ServerStream.php │ │ │ │ ├── ServerStreamingCallInterface.php │ │ │ │ ├── ServiceAddressTrait.php │ │ │ │ ├── Testing/ │ │ │ │ │ ├── GeneratedTest.php │ │ │ │ │ ├── MessageAwareArrayComparator.php │ │ │ │ │ ├── MessageAwareExporter.php │ │ │ │ │ ├── MockBidiStreamingCall.php │ │ │ │ │ ├── MockClientStreamingCall.php │ │ │ │ │ ├── MockGrpcTransport.php │ │ │ │ │ ├── MockRequest.php │ │ │ │ │ ├── MockRequestBody.php │ │ │ │ │ ├── MockResponse.php │ │ │ │ │ ├── MockServerStreamingCall.php │ │ │ │ │ ├── MockStatus.php │ │ │ │ │ ├── MockStubTrait.php │ │ │ │ │ ├── MockTransport.php │ │ │ │ │ ├── MockUnaryCall.php │ │ │ │ │ ├── ProtobufGPBEmptyComparator.php │ │ │ │ │ ├── ProtobufMessageComparator.php │ │ │ │ │ ├── ReceivedRequest.php │ │ │ │ │ ├── SerializationTrait.php │ │ │ │ │ └── mocks.proto │ │ │ │ ├── Transport/ │ │ │ │ │ ├── Grpc/ │ │ │ │ │ │ ├── ForwardingCall.php │ │ │ │ │ │ ├── ForwardingServerStreamingCall.php │ │ │ │ │ │ ├── ForwardingUnaryCall.php │ │ │ │ │ │ ├── ServerStreamingCallWrapper.php │ │ │ │ │ │ └── UnaryInterceptorInterface.php │ │ │ │ │ ├── GrpcFallbackTransport.php │ │ │ │ │ ├── GrpcTransport.php │ │ │ │ │ ├── HttpUnaryTransportTrait.php │ │ │ │ │ ├── Rest/ │ │ │ │ │ │ ├── JsonStreamDecoder.php │ │ │ │ │ │ └── RestServerStreamingCall.php │ │ │ │ │ ├── RestTransport.php │ │ │ │ │ └── TransportInterface.php │ │ │ │ ├── UriTrait.php │ │ │ │ ├── ValidationException.php │ │ │ │ ├── ValidationTrait.php │ │ │ │ └── Version.php │ │ │ ├── grpc-gcp/ │ │ │ │ ├── .github/ │ │ │ │ │ ├── release-please.yml │ │ │ │ │ └── workflows/ │ │ │ │ │ └── tests.yml │ │ │ │ ├── .gitmodules │ │ │ │ ├── .php_cs.dist │ │ │ │ ├── LICENSE │ │ │ │ ├── README.md │ │ │ │ ├── cloudprober/ │ │ │ │ │ ├── bins/ │ │ │ │ │ │ └── opt/ │ │ │ │ │ │ └── grpc_php_plugin │ │ │ │ │ ├── cloudprober.cfg │ │ │ │ │ ├── codegen.sh │ │ │ │ │ ├── composer.json │ │ │ │ │ └── grpc_gpc_prober/ │ │ │ │ │ ├── firestore_probes.php │ │ │ │ │ ├── prober.php │ │ │ │ │ ├── spanner_probes.php │ │ │ │ │ └── stackdriver_util.php │ │ │ │ ├── composer.json │ │ │ │ ├── doc/ │ │ │ │ │ └── gRPC-client-user-guide.md │ │ │ │ └── src/ │ │ │ │ ├── ChannelRef.php │ │ │ │ ├── Config.php │ │ │ │ ├── CreatedByDeserializeCheck.php │ │ │ │ ├── GCPBidiStreamingCall.php │ │ │ │ ├── GCPCallInvoker.php │ │ │ │ ├── GCPClientStreamCall.php │ │ │ │ ├── GCPServerStreamCall.php │ │ │ │ ├── GCPUnaryCall.php │ │ │ │ ├── GcpBaseCall.php │ │ │ │ ├── GcpExtensionChannel.php │ │ │ │ ├── generated/ │ │ │ │ │ ├── GPBMetadata/ │ │ │ │ │ │ └── GrpcGcp.php │ │ │ │ │ └── Grpc/ │ │ │ │ │ └── Gcp/ │ │ │ │ │ ├── AffinityConfig.php │ │ │ │ │ ├── AffinityConfig_Command.php │ │ │ │ │ ├── ApiConfig.php │ │ │ │ │ ├── ChannelPoolConfig.php │ │ │ │ │ └── MethodConfig.php │ │ │ │ └── grpc_gcp.proto │ │ │ ├── longrunning/ │ │ │ │ ├── .gitattributes │ │ │ │ ├── CODE_OF_CONDUCT.md │ │ │ │ ├── CONTRIBUTING.md │ │ │ │ ├── LICENSE │ │ │ │ ├── README.md │ │ │ │ ├── SECURITY.md │ │ │ │ ├── VERSION │ │ │ │ ├── composer.json │ │ │ │ ├── metadata/ │ │ │ │ │ ├── Longrunning/ │ │ │ │ │ │ └── Operations.php │ │ │ │ │ └── README.md │ │ │ │ └── src/ │ │ │ │ ├── ApiCore/ │ │ │ │ │ └── LongRunning/ │ │ │ │ │ ├── Gapic/ │ │ │ │ │ │ └── OperationsGapicClient.php │ │ │ │ │ └── OperationsClient.php │ │ │ │ └── LongRunning/ │ │ │ │ ├── CancelOperationRequest.php │ │ │ │ ├── Client/ │ │ │ │ │ └── OperationsClient.php │ │ │ │ ├── DeleteOperationRequest.php │ │ │ │ ├── Gapic/ │ │ │ │ │ └── OperationsGapicClient.php │ │ │ │ ├── GetOperationRequest.php │ │ │ │ ├── ListOperationsRequest.php │ │ │ │ ├── ListOperationsResponse.php │ │ │ │ ├── Operation.php │ │ │ │ ├── OperationInfo.php │ │ │ │ ├── OperationsClient.php │ │ │ │ ├── OperationsGrpcClient.php │ │ │ │ ├── WaitOperationRequest.php │ │ │ │ └── resources/ │ │ │ │ ├── operations_client_config.json │ │ │ │ ├── operations_descriptor_config.php │ │ │ │ └── operations_rest_client_config.php │ │ │ └── protobuf/ │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── composer.json │ │ │ └── src/ │ │ │ ├── GPBMetadata/ │ │ │ │ └── Google/ │ │ │ │ └── Protobuf/ │ │ │ │ ├── Any.php │ │ │ │ ├── Api.php │ │ │ │ ├── Duration.php │ │ │ │ ├── FieldMask.php │ │ │ │ ├── GPBEmpty.php │ │ │ │ ├── Internal/ │ │ │ │ │ └── Descriptor.php │ │ │ │ ├── SourceContext.php │ │ │ │ ├── Struct.php │ │ │ │ ├── Timestamp.php │ │ │ │ ├── Type.php │ │ │ │ └── Wrappers.php │ │ │ ├── Google/ │ │ │ │ └── Protobuf/ │ │ │ │ ├── Any.php │ │ │ │ ├── Api.php │ │ │ │ ├── BoolValue.php │ │ │ │ ├── BytesValue.php │ │ │ │ ├── Descriptor.php │ │ │ │ ├── DescriptorPool.php │ │ │ │ ├── DoubleValue.php │ │ │ │ ├── Duration.php │ │ │ │ ├── Enum.php │ │ │ │ ├── EnumDescriptor.php │ │ │ │ ├── EnumValue.php │ │ │ │ ├── EnumValueDescriptor.php │ │ │ │ ├── Field/ │ │ │ │ │ ├── Cardinality.php │ │ │ │ │ └── Kind.php │ │ │ │ ├── Field.php │ │ │ │ ├── FieldDescriptor.php │ │ │ │ ├── FieldMask.php │ │ │ │ ├── Field_Cardinality.php │ │ │ │ ├── Field_Kind.php │ │ │ │ ├── FloatValue.php │ │ │ │ ├── GPBEmpty.php │ │ │ │ ├── Int32Value.php │ │ │ │ ├── Int64Value.php │ │ │ │ ├── Internal/ │ │ │ │ │ ├── AnyBase.php │ │ │ │ │ ├── CodedInputStream.php │ │ │ │ │ ├── CodedOutputStream.php │ │ │ │ │ ├── Descriptor.php │ │ │ │ │ ├── DescriptorPool.php │ │ │ │ │ ├── DescriptorProto/ │ │ │ │ │ │ ├── ExtensionRange.php │ │ │ │ │ │ └── ReservedRange.php │ │ │ │ │ ├── DescriptorProto.php │ │ │ │ │ ├── Edition.php │ │ │ │ │ ├── EnumBuilderContext.php │ │ │ │ │ ├── EnumDescriptor.php │ │ │ │ │ ├── EnumDescriptorProto/ │ │ │ │ │ │ └── EnumReservedRange.php │ │ │ │ │ ├── EnumDescriptorProto.php │ │ │ │ │ ├── EnumOptions.php │ │ │ │ │ ├── EnumValueDescriptorProto.php │ │ │ │ │ ├── EnumValueOptions.php │ │ │ │ │ ├── ExtensionRangeOptions/ │ │ │ │ │ │ ├── Declaration.php │ │ │ │ │ │ └── VerificationState.php │ │ │ │ │ ├── ExtensionRangeOptions.php │ │ │ │ │ ├── FeatureSet/ │ │ │ │ │ │ ├── EnforceNamingStyle.php │ │ │ │ │ │ ├── EnumType.php │ │ │ │ │ │ ├── FieldPresence.php │ │ │ │ │ │ ├── JsonFormat.php │ │ │ │ │ │ ├── MessageEncoding.php │ │ │ │ │ │ ├── RepeatedFieldEncoding.php │ │ │ │ │ │ ├── Utf8Validation.php │ │ │ │ │ │ ├── VisibilityFeature/ │ │ │ │ │ │ │ └── DefaultSymbolVisibility.php │ │ │ │ │ │ └── VisibilityFeature.php │ │ │ │ │ ├── FeatureSet.php │ │ │ │ │ ├── FeatureSetDefaults/ │ │ │ │ │ │ └── FeatureSetEditionDefault.php │ │ │ │ │ ├── FeatureSetDefaults.php │ │ │ │ │ ├── FieldDescriptor.php │ │ │ │ │ ├── FieldDescriptorProto/ │ │ │ │ │ │ ├── Label.php │ │ │ │ │ │ └── Type.php │ │ │ │ │ ├── FieldDescriptorProto.php │ │ │ │ │ ├── FieldOptions/ │ │ │ │ │ │ ├── CType.php │ │ │ │ │ │ ├── EditionDefault.php │ │ │ │ │ │ ├── FeatureSupport.php │ │ │ │ │ │ ├── JSType.php │ │ │ │ │ │ ├── OptionRetention.php │ │ │ │ │ │ └── OptionTargetType.php │ │ │ │ │ ├── FieldOptions.php │ │ │ │ │ ├── FileDescriptor.php │ │ │ │ │ ├── FileDescriptorProto.php │ │ │ │ │ ├── FileDescriptorSet.php │ │ │ │ │ ├── FileOptions/ │ │ │ │ │ │ └── OptimizeMode.php │ │ │ │ │ ├── FileOptions.php │ │ │ │ │ ├── GPBDecodeException.php │ │ │ │ │ ├── GPBJsonWire.php │ │ │ │ │ ├── GPBLabel.php │ │ │ │ │ ├── GPBType.php │ │ │ │ │ ├── GPBUtil.php │ │ │ │ │ ├── GPBWire.php │ │ │ │ │ ├── GPBWireType.php │ │ │ │ │ ├── GeneratedCodeInfo/ │ │ │ │ │ │ ├── Annotation/ │ │ │ │ │ │ │ └── Semantic.php │ │ │ │ │ │ └── Annotation.php │ │ │ │ │ ├── GeneratedCodeInfo.php │ │ │ │ │ ├── GetPublicDescriptorTrait.php │ │ │ │ │ ├── HasPublicDescriptorTrait.php │ │ │ │ │ ├── MapEntry.php │ │ │ │ │ ├── MapField.php │ │ │ │ │ ├── MapFieldIter.php │ │ │ │ │ ├── Message.php │ │ │ │ │ ├── MessageBuilderContext.php │ │ │ │ │ ├── MessageOptions.php │ │ │ │ │ ├── MethodDescriptorProto.php │ │ │ │ │ ├── MethodOptions/ │ │ │ │ │ │ └── IdempotencyLevel.php │ │ │ │ │ ├── MethodOptions.php │ │ │ │ │ ├── OneofDescriptor.php │ │ │ │ │ ├── OneofDescriptorProto.php │ │ │ │ │ ├── OneofField.php │ │ │ │ │ ├── OneofOptions.php │ │ │ │ │ ├── RawInputStream.php │ │ │ │ │ ├── RepeatedField.php │ │ │ │ │ ├── RepeatedFieldIter.php │ │ │ │ │ ├── ServiceDescriptorProto.php │ │ │ │ │ ├── ServiceOptions.php │ │ │ │ │ ├── SourceCodeInfo/ │ │ │ │ │ │ └── Location.php │ │ │ │ │ ├── SourceCodeInfo.php │ │ │ │ │ ├── SymbolVisibility.php │ │ │ │ │ ├── TimestampBase.php │ │ │ │ │ ├── UninterpretedOption/ │ │ │ │ │ │ └── NamePart.php │ │ │ │ │ └── UninterpretedOption.php │ │ │ │ ├── ListValue.php │ │ │ │ ├── Method.php │ │ │ │ ├── Mixin.php │ │ │ │ ├── NullValue.php │ │ │ │ ├── OneofDescriptor.php │ │ │ │ ├── Option.php │ │ │ │ ├── PrintOptions.php │ │ │ │ ├── RepeatedField.php │ │ │ │ ├── SourceContext.php │ │ │ │ ├── StringValue.php │ │ │ │ ├── Struct.php │ │ │ │ ├── Syntax.php │ │ │ │ ├── Timestamp.php │ │ │ │ ├── Type.php │ │ │ │ ├── UInt32Value.php │ │ │ │ ├── UInt64Value.php │ │ │ │ └── Value.php │ │ │ └── phpdoc.dist.xml │ │ ├── grpc/ │ │ │ └── grpc/ │ │ │ ├── LICENSE │ │ │ ├── MAINTAINERS.md │ │ │ ├── README.md │ │ │ ├── composer.json │ │ │ ├── etc/ │ │ │ │ └── roots.pem │ │ │ └── src/ │ │ │ └── lib/ │ │ │ ├── AbstractCall.php │ │ │ ├── BaseStub.php │ │ │ ├── BidiStreamingCall.php │ │ │ ├── CallInvoker.php │ │ │ ├── ClientStreamingCall.php │ │ │ ├── DefaultCallInvoker.php │ │ │ ├── Interceptor.php │ │ │ ├── Internal/ │ │ │ │ └── InterceptorChannel.php │ │ │ ├── MethodDescriptor.php │ │ │ ├── RpcServer.php │ │ │ ├── ServerCallReader.php │ │ │ ├── ServerCallWriter.php │ │ │ ├── ServerContext.php │ │ │ ├── ServerStreamingCall.php │ │ │ ├── Status.php │ │ │ └── UnaryCall.php │ │ ├── guzzlehttp/ │ │ │ ├── guzzle/ │ │ │ │ ├── CHANGELOG.md │ │ │ │ ├── LICENSE │ │ │ │ ├── README.md │ │ │ │ ├── UPGRADING.md │ │ │ │ ├── composer.json │ │ │ │ └── src/ │ │ │ │ ├── BodySummarizer.php │ │ │ │ ├── BodySummarizerInterface.php │ │ │ │ ├── Client.php │ │ │ │ ├── ClientInterface.php │ │ │ │ ├── ClientTrait.php │ │ │ │ ├── Cookie/ │ │ │ │ │ ├── CookieJar.php │ │ │ │ │ ├── CookieJarInterface.php │ │ │ │ │ ├── FileCookieJar.php │ │ │ │ │ ├── SessionCookieJar.php │ │ │ │ │ └── SetCookie.php │ │ │ │ ├── Exception/ │ │ │ │ │ ├── BadResponseException.php │ │ │ │ │ ├── ClientException.php │ │ │ │ │ ├── ConnectException.php │ │ │ │ │ ├── GuzzleException.php │ │ │ │ │ ├── InvalidArgumentException.php │ │ │ │ │ ├── RequestException.php │ │ │ │ │ ├── ServerException.php │ │ │ │ │ ├── TooManyRedirectsException.php │ │ │ │ │ └── TransferException.php │ │ │ │ ├── Handler/ │ │ │ │ │ ├── CurlFactory.php │ │ │ │ │ ├── CurlFactoryInterface.php │ │ │ │ │ ├── CurlHandler.php │ │ │ │ │ ├── CurlMultiHandler.php │ │ │ │ │ ├── EasyHandle.php │ │ │ │ │ ├── HeaderProcessor.php │ │ │ │ │ ├── MockHandler.php │ │ │ │ │ ├── Proxy.php │ │ │ │ │ └── StreamHandler.php │ │ │ │ ├── HandlerStack.php │ │ │ │ ├── MessageFormatter.php │ │ │ │ ├── MessageFormatterInterface.php │ │ │ │ ├── Middleware.php │ │ │ │ ├── Pool.php │ │ │ │ ├── PrepareBodyMiddleware.php │ │ │ │ ├── RedirectMiddleware.php │ │ │ │ ├── RequestOptions.php │ │ │ │ ├── RetryMiddleware.php │ │ │ │ ├── TransferStats.php │ │ │ │ ├── Utils.php │ │ │ │ ├── functions.php │ │ │ │ └── functions_include.php │ │ │ ├── promises/ │ │ │ │ ├── CHANGELOG.md │ │ │ │ ├── LICENSE │ │ │ │ ├── README.md │ │ │ │ ├── composer.json │ │ │ │ └── src/ │ │ │ │ ├── AggregateException.php │ │ │ │ ├── CancellationException.php │ │ │ │ ├── Coroutine.php │ │ │ │ ├── Create.php │ │ │ │ ├── Each.php │ │ │ │ ├── EachPromise.php │ │ │ │ ├── FulfilledPromise.php │ │ │ │ ├── Is.php │ │ │ │ ├── Promise.php │ │ │ │ ├── PromiseInterface.php │ │ │ │ ├── PromisorInterface.php │ │ │ │ ├── RejectedPromise.php │ │ │ │ ├── RejectionException.php │ │ │ │ ├── TaskQueue.php │ │ │ │ ├── TaskQueueInterface.php │ │ │ │ └── Utils.php │ │ │ └── psr7/ │ │ │ ├── CHANGELOG.md │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── composer.json │ │ │ └── src/ │ │ │ ├── AppendStream.php │ │ │ ├── BufferStream.php │ │ │ ├── CachingStream.php │ │ │ ├── DroppingStream.php │ │ │ ├── Exception/ │ │ │ │ └── MalformedUriException.php │ │ │ ├── FnStream.php │ │ │ ├── Header.php │ │ │ ├── HttpFactory.php │ │ │ ├── InflateStream.php │ │ │ ├── LazyOpenStream.php │ │ │ ├── LimitStream.php │ │ │ ├── Message.php │ │ │ ├── MessageTrait.php │ │ │ ├── MimeType.php │ │ │ ├── MultipartStream.php │ │ │ ├── NoSeekStream.php │ │ │ ├── PumpStream.php │ │ │ ├── Query.php │ │ │ ├── Request.php │ │ │ ├── Response.php │ │ │ ├── Rfc7230.php │ │ │ ├── ServerRequest.php │ │ │ ├── Stream.php │ │ │ ├── StreamDecoratorTrait.php │ │ │ ├── StreamWrapper.php │ │ │ ├── UploadedFile.php │ │ │ ├── Uri.php │ │ │ ├── UriComparator.php │ │ │ ├── UriNormalizer.php │ │ │ ├── UriResolver.php │ │ │ └── Utils.php │ │ ├── monolog/ │ │ │ └── monolog/ │ │ │ ├── CHANGELOG.md │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── composer.json │ │ │ └── src/ │ │ │ └── Monolog/ │ │ │ ├── Attribute/ │ │ │ │ ├── AsMonologProcessor.php │ │ │ │ └── WithMonologChannel.php │ │ │ ├── DateTimeImmutable.php │ │ │ ├── ErrorHandler.php │ │ │ ├── Formatter/ │ │ │ │ ├── ChromePHPFormatter.php │ │ │ │ ├── ElasticaFormatter.php │ │ │ │ ├── ElasticsearchFormatter.php │ │ │ │ ├── FlowdockFormatter.php │ │ │ │ ├── FluentdFormatter.php │ │ │ │ ├── FormatterInterface.php │ │ │ │ ├── GelfMessageFormatter.php │ │ │ │ ├── GoogleCloudLoggingFormatter.php │ │ │ │ ├── HtmlFormatter.php │ │ │ │ ├── JsonFormatter.php │ │ │ │ ├── LineFormatter.php │ │ │ │ ├── LogglyFormatter.php │ │ │ │ ├── LogmaticFormatter.php │ │ │ │ ├── LogstashFormatter.php │ │ │ │ ├── MongoDBFormatter.php │ │ │ │ ├── NormalizerFormatter.php │ │ │ │ ├── ScalarFormatter.php │ │ │ │ ├── SyslogFormatter.php │ │ │ │ └── WildfireFormatter.php │ │ │ ├── Handler/ │ │ │ │ ├── AbstractHandler.php │ │ │ │ ├── AbstractProcessingHandler.php │ │ │ │ ├── AbstractSyslogHandler.php │ │ │ │ ├── AmqpHandler.php │ │ │ │ ├── BrowserConsoleHandler.php │ │ │ │ ├── BufferHandler.php │ │ │ │ ├── ChromePHPHandler.php │ │ │ │ ├── CouchDBHandler.php │ │ │ │ ├── CubeHandler.php │ │ │ │ ├── Curl/ │ │ │ │ │ └── Util.php │ │ │ │ ├── DeduplicationHandler.php │ │ │ │ ├── DoctrineCouchDBHandler.php │ │ │ │ ├── DynamoDbHandler.php │ │ │ │ ├── ElasticaHandler.php │ │ │ │ ├── ElasticsearchHandler.php │ │ │ │ ├── ErrorLogHandler.php │ │ │ │ ├── FallbackGroupHandler.php │ │ │ │ ├── FilterHandler.php │ │ │ │ ├── FingersCrossed/ │ │ │ │ │ ├── ActivationStrategyInterface.php │ │ │ │ │ ├── ChannelLevelActivationStrategy.php │ │ │ │ │ └── ErrorLevelActivationStrategy.php │ │ │ │ ├── FingersCrossedHandler.php │ │ │ │ ├── FirePHPHandler.php │ │ │ │ ├── FleepHookHandler.php │ │ │ │ ├── FlowdockHandler.php │ │ │ │ ├── FormattableHandlerInterface.php │ │ │ │ ├── FormattableHandlerTrait.php │ │ │ │ ├── GelfHandler.php │ │ │ │ ├── GroupHandler.php │ │ │ │ ├── Handler.php │ │ │ │ ├── HandlerInterface.php │ │ │ │ ├── HandlerWrapper.php │ │ │ │ ├── IFTTTHandler.php │ │ │ │ ├── InsightOpsHandler.php │ │ │ │ ├── LogEntriesHandler.php │ │ │ │ ├── LogglyHandler.php │ │ │ │ ├── LogmaticHandler.php │ │ │ │ ├── MailHandler.php │ │ │ │ ├── MandrillHandler.php │ │ │ │ ├── MissingExtensionException.php │ │ │ │ ├── MongoDBHandler.php │ │ │ │ ├── NativeMailerHandler.php │ │ │ │ ├── NewRelicHandler.php │ │ │ │ ├── NoopHandler.php │ │ │ │ ├── NullHandler.php │ │ │ │ ├── OverflowHandler.php │ │ │ │ ├── PHPConsoleHandler.php │ │ │ │ ├── ProcessHandler.php │ │ │ │ ├── ProcessableHandlerInterface.php │ │ │ │ ├── ProcessableHandlerTrait.php │ │ │ │ ├── PsrHandler.php │ │ │ │ ├── PushoverHandler.php │ │ │ │ ├── RedisHandler.php │ │ │ │ ├── RedisPubSubHandler.php │ │ │ │ ├── RollbarHandler.php │ │ │ │ ├── RotatingFileHandler.php │ │ │ │ ├── SamplingHandler.php │ │ │ │ ├── SendGridHandler.php │ │ │ │ ├── Slack/ │ │ │ │ │ └── SlackRecord.php │ │ │ │ ├── SlackHandler.php │ │ │ │ ├── SlackWebhookHandler.php │ │ │ │ ├── SocketHandler.php │ │ │ │ ├── SqsHandler.php │ │ │ │ ├── StreamHandler.php │ │ │ │ ├── SymfonyMailerHandler.php │ │ │ │ ├── SyslogHandler.php │ │ │ │ ├── SyslogUdp/ │ │ │ │ │ └── UdpSocket.php │ │ │ │ ├── SyslogUdpHandler.php │ │ │ │ ├── TelegramBotHandler.php │ │ │ │ ├── TestHandler.php │ │ │ │ ├── WebRequestRecognizerTrait.php │ │ │ │ ├── WhatFailureGroupHandler.php │ │ │ │ └── ZendMonitorHandler.php │ │ │ ├── JsonSerializableDateTimeImmutable.php │ │ │ ├── Level.php │ │ │ ├── LogRecord.php │ │ │ ├── Logger.php │ │ │ ├── Processor/ │ │ │ │ ├── ClosureContextProcessor.php │ │ │ │ ├── GitProcessor.php │ │ │ │ ├── HostnameProcessor.php │ │ │ │ ├── IntrospectionProcessor.php │ │ │ │ ├── LoadAverageProcessor.php │ │ │ │ ├── MemoryPeakUsageProcessor.php │ │ │ │ ├── MemoryProcessor.php │ │ │ │ ├── MemoryUsageProcessor.php │ │ │ │ ├── MercurialProcessor.php │ │ │ │ ├── ProcessIdProcessor.php │ │ │ │ ├── ProcessorInterface.php │ │ │ │ ├── PsrLogMessageProcessor.php │ │ │ │ ├── TagProcessor.php │ │ │ │ ├── UidProcessor.php │ │ │ │ └── WebProcessor.php │ │ │ ├── Registry.php │ │ │ ├── ResettableInterface.php │ │ │ ├── SignalHandler.php │ │ │ ├── Test/ │ │ │ │ ├── MonologTestCase.php │ │ │ │ └── TestCase.php │ │ │ └── Utils.php │ │ ├── paragonie/ │ │ │ ├── constant_time_encoding/ │ │ │ │ ├── LICENSE.txt │ │ │ │ ├── README.md │ │ │ │ ├── composer.json │ │ │ │ └── src/ │ │ │ │ ├── Base32.php │ │ │ │ ├── Base32Hex.php │ │ │ │ ├── Base64.php │ │ │ │ ├── Base64DotSlash.php │ │ │ │ ├── Base64DotSlashOrdered.php │ │ │ │ ├── Base64UrlSafe.php │ │ │ │ ├── Binary.php │ │ │ │ ├── EncoderInterface.php │ │ │ │ ├── Encoding.php │ │ │ │ ├── Hex.php │ │ │ │ └── RFC4648.php │ │ │ └── random_compat/ │ │ │ ├── LICENSE │ │ │ ├── build-phar.sh │ │ │ ├── composer.json │ │ │ ├── dist/ │ │ │ │ ├── random_compat.phar.pubkey │ │ │ │ └── random_compat.phar.pubkey.asc │ │ │ ├── lib/ │ │ │ │ └── random.php │ │ │ ├── other/ │ │ │ │ └── build_phar.php │ │ │ ├── psalm-autoload.php │ │ │ └── psalm.xml │ │ ├── phpseclib/ │ │ │ └── phpseclib/ │ │ │ ├── AUTHORS │ │ │ ├── BACKERS.md │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── SECURITY.md │ │ │ ├── composer.json │ │ │ └── phpseclib/ │ │ │ ├── Common/ │ │ │ │ └── Functions/ │ │ │ │ └── Strings.php │ │ │ ├── Crypt/ │ │ │ │ ├── AES.php │ │ │ │ ├── Blowfish.php │ │ │ │ ├── ChaCha20.php │ │ │ │ ├── Common/ │ │ │ │ │ ├── AsymmetricKey.php │ │ │ │ │ ├── BlockCipher.php │ │ │ │ │ ├── Formats/ │ │ │ │ │ │ ├── Keys/ │ │ │ │ │ │ │ ├── JWK.php │ │ │ │ │ │ │ ├── OpenSSH.php │ │ │ │ │ │ │ ├── PKCS.php │ │ │ │ │ │ │ ├── PKCS1.php │ │ │ │ │ │ │ ├── PKCS8.php │ │ │ │ │ │ │ └── PuTTY.php │ │ │ │ │ │ └── Signature/ │ │ │ │ │ │ └── Raw.php │ │ │ │ │ ├── PrivateKey.php │ │ │ │ │ ├── PublicKey.php │ │ │ │ │ ├── StreamCipher.php │ │ │ │ │ ├── SymmetricKey.php │ │ │ │ │ └── Traits/ │ │ │ │ │ ├── Fingerprint.php │ │ │ │ │ └── PasswordProtected.php │ │ │ │ ├── DES.php │ │ │ │ ├── DH/ │ │ │ │ │ ├── Formats/ │ │ │ │ │ │ └── Keys/ │ │ │ │ │ │ ├── PKCS1.php │ │ │ │ │ │ └── PKCS8.php │ │ │ │ │ ├── Parameters.php │ │ │ │ │ ├── PrivateKey.php │ │ │ │ │ └── PublicKey.php │ │ │ │ ├── DH.php │ │ │ │ ├── DSA/ │ │ │ │ │ ├── Formats/ │ │ │ │ │ │ ├── Keys/ │ │ │ │ │ │ │ ├── OpenSSH.php │ │ │ │ │ │ │ ├── PKCS1.php │ │ │ │ │ │ │ ├── PKCS8.php │ │ │ │ │ │ │ ├── PuTTY.php │ │ │ │ │ │ │ ├── Raw.php │ │ │ │ │ │ │ └── XML.php │ │ │ │ │ │ └── Signature/ │ │ │ │ │ │ ├── ASN1.php │ │ │ │ │ │ ├── Raw.php │ │ │ │ │ │ └── SSH2.php │ │ │ │ │ ├── Parameters.php │ │ │ │ │ ├── PrivateKey.php │ │ │ │ │ └── PublicKey.php │ │ │ │ ├── DSA.php │ │ │ │ ├── EC/ │ │ │ │ │ ├── BaseCurves/ │ │ │ │ │ │ ├── Base.php │ │ │ │ │ │ ├── Binary.php │ │ │ │ │ │ ├── KoblitzPrime.php │ │ │ │ │ │ ├── Montgomery.php │ │ │ │ │ │ ├── Prime.php │ │ │ │ │ │ └── TwistedEdwards.php │ │ │ │ │ ├── Curves/ │ │ │ │ │ │ ├── Curve25519.php │ │ │ │ │ │ ├── Curve448.php │ │ │ │ │ │ ├── Ed25519.php │ │ │ │ │ │ ├── Ed448.php │ │ │ │ │ │ ├── brainpoolP160r1.php │ │ │ │ │ │ ├── brainpoolP160t1.php │ │ │ │ │ │ ├── brainpoolP192r1.php │ │ │ │ │ │ ├── brainpoolP192t1.php │ │ │ │ │ │ ├── brainpoolP224r1.php │ │ │ │ │ │ ├── brainpoolP224t1.php │ │ │ │ │ │ ├── brainpoolP256r1.php │ │ │ │ │ │ ├── brainpoolP256t1.php │ │ │ │ │ │ ├── brainpoolP320r1.php │ │ │ │ │ │ ├── brainpoolP320t1.php │ │ │ │ │ │ ├── brainpoolP384r1.php │ │ │ │ │ │ ├── brainpoolP384t1.php │ │ │ │ │ │ ├── brainpoolP512r1.php │ │ │ │ │ │ ├── brainpoolP512t1.php │ │ │ │ │ │ ├── nistb233.php │ │ │ │ │ │ ├── nistb409.php │ │ │ │ │ │ ├── nistk163.php │ │ │ │ │ │ ├── nistk233.php │ │ │ │ │ │ ├── nistk283.php │ │ │ │ │ │ ├── nistk409.php │ │ │ │ │ │ ├── nistp192.php │ │ │ │ │ │ ├── nistp224.php │ │ │ │ │ │ ├── nistp256.php │ │ │ │ │ │ ├── nistp384.php │ │ │ │ │ │ ├── nistp521.php │ │ │ │ │ │ ├── nistt571.php │ │ │ │ │ │ ├── prime192v1.php │ │ │ │ │ │ ├── prime192v2.php │ │ │ │ │ │ ├── prime192v3.php │ │ │ │ │ │ ├── prime239v1.php │ │ │ │ │ │ ├── prime239v2.php │ │ │ │ │ │ ├── prime239v3.php │ │ │ │ │ │ ├── prime256v1.php │ │ │ │ │ │ ├── secp112r1.php │ │ │ │ │ │ ├── secp112r2.php │ │ │ │ │ │ ├── secp128r1.php │ │ │ │ │ │ ├── secp128r2.php │ │ │ │ │ │ ├── secp160k1.php │ │ │ │ │ │ ├── secp160r1.php │ │ │ │ │ │ ├── secp160r2.php │ │ │ │ │ │ ├── secp192k1.php │ │ │ │ │ │ ├── secp192r1.php │ │ │ │ │ │ ├── secp224k1.php │ │ │ │ │ │ ├── secp224r1.php │ │ │ │ │ │ ├── secp256k1.php │ │ │ │ │ │ ├── secp256r1.php │ │ │ │ │ │ ├── secp384r1.php │ │ │ │ │ │ ├── secp521r1.php │ │ │ │ │ │ ├── sect113r1.php │ │ │ │ │ │ ├── sect113r2.php │ │ │ │ │ │ ├── sect131r1.php │ │ │ │ │ │ ├── sect131r2.php │ │ │ │ │ │ ├── sect163k1.php │ │ │ │ │ │ ├── sect163r1.php │ │ │ │ │ │ ├── sect163r2.php │ │ │ │ │ │ ├── sect193r1.php │ │ │ │ │ │ ├── sect193r2.php │ │ │ │ │ │ ├── sect233k1.php │ │ │ │ │ │ ├── sect233r1.php │ │ │ │ │ │ ├── sect239k1.php │ │ │ │ │ │ ├── sect283k1.php │ │ │ │ │ │ ├── sect283r1.php │ │ │ │ │ │ ├── sect409k1.php │ │ │ │ │ │ ├── sect409r1.php │ │ │ │ │ │ ├── sect571k1.php │ │ │ │ │ │ └── sect571r1.php │ │ │ │ │ ├── Formats/ │ │ │ │ │ │ ├── Keys/ │ │ │ │ │ │ │ ├── Common.php │ │ │ │ │ │ │ ├── JWK.php │ │ │ │ │ │ │ ├── MontgomeryPrivate.php │ │ │ │ │ │ │ ├── MontgomeryPublic.php │ │ │ │ │ │ │ ├── OpenSSH.php │ │ │ │ │ │ │ ├── PKCS1.php │ │ │ │ │ │ │ ├── PKCS8.php │ │ │ │ │ │ │ ├── PuTTY.php │ │ │ │ │ │ │ ├── XML.php │ │ │ │ │ │ │ └── libsodium.php │ │ │ │ │ │ └── Signature/ │ │ │ │ │ │ ├── ASN1.php │ │ │ │ │ │ ├── IEEE.php │ │ │ │ │ │ ├── Raw.php │ │ │ │ │ │ └── SSH2.php │ │ │ │ │ ├── Parameters.php │ │ │ │ │ ├── PrivateKey.php │ │ │ │ │ └── PublicKey.php │ │ │ │ ├── EC.php │ │ │ │ ├── Hash.php │ │ │ │ ├── PublicKeyLoader.php │ │ │ │ ├── RC2.php │ │ │ │ ├── RC4.php │ │ │ │ ├── RSA/ │ │ │ │ │ ├── Formats/ │ │ │ │ │ │ └── Keys/ │ │ │ │ │ │ ├── JWK.php │ │ │ │ │ │ ├── MSBLOB.php │ │ │ │ │ │ ├── OpenSSH.php │ │ │ │ │ │ ├── PKCS1.php │ │ │ │ │ │ ├── PKCS8.php │ │ │ │ │ │ ├── PSS.php │ │ │ │ │ │ ├── PuTTY.php │ │ │ │ │ │ ├── Raw.php │ │ │ │ │ │ └── XML.php │ │ │ │ │ ├── PrivateKey.php │ │ │ │ │ └── PublicKey.php │ │ │ │ ├── RSA.php │ │ │ │ ├── Random.php │ │ │ │ ├── Rijndael.php │ │ │ │ ├── Salsa20.php │ │ │ │ ├── TripleDES.php │ │ │ │ └── Twofish.php │ │ │ ├── Exception/ │ │ │ │ ├── BadConfigurationException.php │ │ │ │ ├── BadDecryptionException.php │ │ │ │ ├── BadModeException.php │ │ │ │ ├── ConnectionClosedException.php │ │ │ │ ├── FileNotFoundException.php │ │ │ │ ├── InconsistentSetupException.php │ │ │ │ ├── InsufficientSetupException.php │ │ │ │ ├── InvalidPacketLengthException.php │ │ │ │ ├── NoKeyLoadedException.php │ │ │ │ ├── NoSupportedAlgorithmsException.php │ │ │ │ ├── TimeoutException.php │ │ │ │ ├── UnableToConnectException.php │ │ │ │ ├── UnsupportedAlgorithmException.php │ │ │ │ ├── UnsupportedCurveException.php │ │ │ │ ├── UnsupportedFormatException.php │ │ │ │ └── UnsupportedOperationException.php │ │ │ ├── File/ │ │ │ │ ├── ANSI.php │ │ │ │ ├── ASN1/ │ │ │ │ │ ├── Element.php │ │ │ │ │ └── Maps/ │ │ │ │ │ ├── AccessDescription.php │ │ │ │ │ ├── AdministrationDomainName.php │ │ │ │ │ ├── AlgorithmIdentifier.php │ │ │ │ │ ├── AnotherName.php │ │ │ │ │ ├── Attribute.php │ │ │ │ │ ├── AttributeType.php │ │ │ │ │ ├── AttributeTypeAndValue.php │ │ │ │ │ ├── AttributeValue.php │ │ │ │ │ ├── Attributes.php │ │ │ │ │ ├── AuthorityInfoAccessSyntax.php │ │ │ │ │ ├── AuthorityKeyIdentifier.php │ │ │ │ │ ├── BaseDistance.php │ │ │ │ │ ├── BasicConstraints.php │ │ │ │ │ ├── BuiltInDomainDefinedAttribute.php │ │ │ │ │ ├── BuiltInDomainDefinedAttributes.php │ │ │ │ │ ├── BuiltInStandardAttributes.php │ │ │ │ │ ├── CPSuri.php │ │ │ │ │ ├── CRLDistributionPoints.php │ │ │ │ │ ├── CRLNumber.php │ │ │ │ │ ├── CRLReason.php │ │ │ │ │ ├── CertPolicyId.php │ │ │ │ │ ├── Certificate.php │ │ │ │ │ ├── CertificateIssuer.php │ │ │ │ │ ├── CertificateList.php │ │ │ │ │ ├── CertificatePolicies.php │ │ │ │ │ ├── CertificateSerialNumber.php │ │ │ │ │ ├── CertificationRequest.php │ │ │ │ │ ├── CertificationRequestInfo.php │ │ │ │ │ ├── Characteristic_two.php │ │ │ │ │ ├── CountryName.php │ │ │ │ │ ├── Curve.php │ │ │ │ │ ├── DHParameter.php │ │ │ │ │ ├── DSAParams.php │ │ │ │ │ ├── DSAPrivateKey.php │ │ │ │ │ ├── DSAPublicKey.php │ │ │ │ │ ├── DigestInfo.php │ │ │ │ │ ├── DirectoryString.php │ │ │ │ │ ├── DisplayText.php │ │ │ │ │ ├── DistributionPoint.php │ │ │ │ │ ├── DistributionPointName.php │ │ │ │ │ ├── DssSigValue.php │ │ │ │ │ ├── ECParameters.php │ │ │ │ │ ├── ECPoint.php │ │ │ │ │ ├── ECPrivateKey.php │ │ │ │ │ ├── EDIPartyName.php │ │ │ │ │ ├── EcdsaSigValue.php │ │ │ │ │ ├── EncryptedData.php │ │ │ │ │ ├── EncryptedPrivateKeyInfo.php │ │ │ │ │ ├── ExtKeyUsageSyntax.php │ │ │ │ │ ├── Extension.php │ │ │ │ │ ├── ExtensionAttribute.php │ │ │ │ │ ├── ExtensionAttributes.php │ │ │ │ │ ├── Extensions.php │ │ │ │ │ ├── FieldElement.php │ │ │ │ │ ├── FieldID.php │ │ │ │ │ ├── GeneralName.php │ │ │ │ │ ├── GeneralNames.php │ │ │ │ │ ├── GeneralSubtree.php │ │ │ │ │ ├── GeneralSubtrees.php │ │ │ │ │ ├── HashAlgorithm.php │ │ │ │ │ ├── HoldInstructionCode.php │ │ │ │ │ ├── InvalidityDate.php │ │ │ │ │ ├── IssuerAltName.php │ │ │ │ │ ├── IssuingDistributionPoint.php │ │ │ │ │ ├── KeyIdentifier.php │ │ │ │ │ ├── KeyPurposeId.php │ │ │ │ │ ├── KeyUsage.php │ │ │ │ │ ├── MaskGenAlgorithm.php │ │ │ │ │ ├── Name.php │ │ │ │ │ ├── NameConstraints.php │ │ │ │ │ ├── NetworkAddress.php │ │ │ │ │ ├── NoticeReference.php │ │ │ │ │ ├── NumericUserIdentifier.php │ │ │ │ │ ├── ORAddress.php │ │ │ │ │ ├── OneAsymmetricKey.php │ │ │ │ │ ├── OrganizationName.php │ │ │ │ │ ├── OrganizationalUnitNames.php │ │ │ │ │ ├── OtherPrimeInfo.php │ │ │ │ │ ├── OtherPrimeInfos.php │ │ │ │ │ ├── PBEParameter.php │ │ │ │ │ ├── PBES2params.php │ │ │ │ │ ├── PBKDF2params.php │ │ │ │ │ ├── PBMAC1params.php │ │ │ │ │ ├── PKCS9String.php │ │ │ │ │ ├── Pentanomial.php │ │ │ │ │ ├── PersonalName.php │ │ │ │ │ ├── PolicyInformation.php │ │ │ │ │ ├── PolicyMappings.php │ │ │ │ │ ├── PolicyQualifierId.php │ │ │ │ │ ├── PolicyQualifierInfo.php │ │ │ │ │ ├── PostalAddress.php │ │ │ │ │ ├── Prime_p.php │ │ │ │ │ ├── PrivateDomainName.php │ │ │ │ │ ├── PrivateKey.php │ │ │ │ │ ├── PrivateKeyInfo.php │ │ │ │ │ ├── PrivateKeyUsagePeriod.php │ │ │ │ │ ├── PublicKey.php │ │ │ │ │ ├── PublicKeyAndChallenge.php │ │ │ │ │ ├── PublicKeyInfo.php │ │ │ │ │ ├── RC2CBCParameter.php │ │ │ │ │ ├── RDNSequence.php │ │ │ │ │ ├── RSAPrivateKey.php │ │ │ │ │ ├── RSAPublicKey.php │ │ │ │ │ ├── RSASSA_PSS_params.php │ │ │ │ │ ├── ReasonFlags.php │ │ │ │ │ ├── RelativeDistinguishedName.php │ │ │ │ │ ├── RevokedCertificate.php │ │ │ │ │ ├── SignedPublicKeyAndChallenge.php │ │ │ │ │ ├── SpecifiedECDomain.php │ │ │ │ │ ├── SubjectAltName.php │ │ │ │ │ ├── SubjectDirectoryAttributes.php │ │ │ │ │ ├── SubjectInfoAccessSyntax.php │ │ │ │ │ ├── SubjectPublicKeyInfo.php │ │ │ │ │ ├── TBSCertList.php │ │ │ │ │ ├── TBSCertificate.php │ │ │ │ │ ├── TerminalIdentifier.php │ │ │ │ │ ├── Time.php │ │ │ │ │ ├── Trinomial.php │ │ │ │ │ ├── UniqueIdentifier.php │ │ │ │ │ ├── UserNotice.php │ │ │ │ │ ├── Validity.php │ │ │ │ │ ├── netscape_ca_policy_url.php │ │ │ │ │ ├── netscape_cert_type.php │ │ │ │ │ └── netscape_comment.php │ │ │ │ ├── ASN1.php │ │ │ │ └── X509.php │ │ │ ├── Math/ │ │ │ │ ├── BigInteger/ │ │ │ │ │ └── Engines/ │ │ │ │ │ ├── BCMath/ │ │ │ │ │ │ ├── Base.php │ │ │ │ │ │ ├── BuiltIn.php │ │ │ │ │ │ ├── DefaultEngine.php │ │ │ │ │ │ ├── OpenSSL.php │ │ │ │ │ │ └── Reductions/ │ │ │ │ │ │ ├── Barrett.php │ │ │ │ │ │ └── EvalBarrett.php │ │ │ │ │ ├── BCMath.php │ │ │ │ │ ├── Engine.php │ │ │ │ │ ├── GMP/ │ │ │ │ │ │ └── DefaultEngine.php │ │ │ │ │ ├── GMP.php │ │ │ │ │ ├── OpenSSL.php │ │ │ │ │ ├── PHP/ │ │ │ │ │ │ ├── Base.php │ │ │ │ │ │ ├── DefaultEngine.php │ │ │ │ │ │ ├── Montgomery.php │ │ │ │ │ │ ├── OpenSSL.php │ │ │ │ │ │ └── Reductions/ │ │ │ │ │ │ ├── Barrett.php │ │ │ │ │ │ ├── Classic.php │ │ │ │ │ │ ├── EvalBarrett.php │ │ │ │ │ │ ├── Montgomery.php │ │ │ │ │ │ ├── MontgomeryMult.php │ │ │ │ │ │ └── PowerOfTwo.php │ │ │ │ │ ├── PHP.php │ │ │ │ │ ├── PHP32.php │ │ │ │ │ └── PHP64.php │ │ │ │ ├── BigInteger.php │ │ │ │ ├── BinaryField/ │ │ │ │ │ └── Integer.php │ │ │ │ ├── BinaryField.php │ │ │ │ ├── Common/ │ │ │ │ │ ├── FiniteField/ │ │ │ │ │ │ └── Integer.php │ │ │ │ │ └── FiniteField.php │ │ │ │ ├── PrimeField/ │ │ │ │ │ └── Integer.php │ │ │ │ └── PrimeField.php │ │ │ ├── Net/ │ │ │ │ ├── SCP.php │ │ │ │ ├── SFTP/ │ │ │ │ │ └── Stream.php │ │ │ │ ├── SFTP.php │ │ │ │ └── SSH2.php │ │ │ ├── System/ │ │ │ │ └── SSH/ │ │ │ │ ├── Agent/ │ │ │ │ │ └── Identity.php │ │ │ │ ├── Agent.php │ │ │ │ └── Common/ │ │ │ │ └── Traits/ │ │ │ │ └── ReadBytes.php │ │ │ ├── bootstrap.php │ │ │ └── openssl.cnf │ │ ├── psr/ │ │ │ ├── cache/ │ │ │ │ ├── CHANGELOG.md │ │ │ │ ├── LICENSE.txt │ │ │ │ ├── README.md │ │ │ │ ├── composer.json │ │ │ │ └── src/ │ │ │ │ ├── CacheException.php │ │ │ │ ├── CacheItemInterface.php │ │ │ │ ├── CacheItemPoolInterface.php │ │ │ │ └── InvalidArgumentException.php │ │ │ ├── http-client/ │ │ │ │ ├── CHANGELOG.md │ │ │ │ ├── LICENSE │ │ │ │ ├── README.md │ │ │ │ ├── composer.json │ │ │ │ └── src/ │ │ │ │ ├── ClientExceptionInterface.php │ │ │ │ ├── ClientInterface.php │ │ │ │ ├── NetworkExceptionInterface.php │ │ │ │ └── RequestExceptionInterface.php │ │ │ ├── http-factory/ │ │ │ │ ├── LICENSE │ │ │ │ ├── README.md │ │ │ │ ├── composer.json │ │ │ │ └── src/ │ │ │ │ ├── RequestFactoryInterface.php │ │ │ │ ├── ResponseFactoryInterface.php │ │ │ │ ├── ServerRequestFactoryInterface.php │ │ │ │ ├── StreamFactoryInterface.php │ │ │ │ ├── UploadedFileFactoryInterface.php │ │ │ │ └── UriFactoryInterface.php │ │ │ ├── http-message/ │ │ │ │ ├── CHANGELOG.md │ │ │ │ ├── LICENSE │ │ │ │ ├── README.md │ │ │ │ ├── composer.json │ │ │ │ ├── docs/ │ │ │ │ │ ├── PSR7-Interfaces.md │ │ │ │ │ └── PSR7-Usage.md │ │ │ │ └── src/ │ │ │ │ ├── MessageInterface.php │ │ │ │ ├── RequestInterface.php │ │ │ │ ├── ResponseInterface.php │ │ │ │ ├── ServerRequestInterface.php │ │ │ │ ├── StreamInterface.php │ │ │ │ ├── UploadedFileInterface.php │ │ │ │ └── UriInterface.php │ │ │ └── log/ │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── composer.json │ │ │ └── src/ │ │ │ ├── AbstractLogger.php │ │ │ ├── InvalidArgumentException.php │ │ │ ├── LogLevel.php │ │ │ ├── LoggerAwareInterface.php │ │ │ ├── LoggerAwareTrait.php │ │ │ ├── LoggerInterface.php │ │ │ ├── LoggerTrait.php │ │ │ └── NullLogger.php │ │ ├── ralouphie/ │ │ │ └── getallheaders/ │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── composer.json │ │ │ └── src/ │ │ │ └── getallheaders.php │ │ ├── ramsey/ │ │ │ ├── collection/ │ │ │ │ ├── LICENSE │ │ │ │ ├── README.md │ │ │ │ ├── SECURITY.md │ │ │ │ ├── composer.json │ │ │ │ └── src/ │ │ │ │ ├── AbstractArray.php │ │ │ │ ├── AbstractCollection.php │ │ │ │ ├── AbstractSet.php │ │ │ │ ├── ArrayInterface.php │ │ │ │ ├── Collection.php │ │ │ │ ├── CollectionInterface.php │ │ │ │ ├── DoubleEndedQueue.php │ │ │ │ ├── DoubleEndedQueueInterface.php │ │ │ │ ├── Exception/ │ │ │ │ │ ├── CollectionException.php │ │ │ │ │ ├── CollectionMismatchException.php │ │ │ │ │ ├── InvalidArgumentException.php │ │ │ │ │ ├── InvalidPropertyOrMethod.php │ │ │ │ │ ├── NoSuchElementException.php │ │ │ │ │ ├── OutOfBoundsException.php │ │ │ │ │ └── UnsupportedOperationException.php │ │ │ │ ├── GenericArray.php │ │ │ │ ├── Map/ │ │ │ │ │ ├── AbstractMap.php │ │ │ │ │ ├── AbstractTypedMap.php │ │ │ │ │ ├── AssociativeArrayMap.php │ │ │ │ │ ├── MapInterface.php │ │ │ │ │ ├── NamedParameterMap.php │ │ │ │ │ ├── TypedMap.php │ │ │ │ │ └── TypedMapInterface.php │ │ │ │ ├── Queue.php │ │ │ │ ├── QueueInterface.php │ │ │ │ ├── Set.php │ │ │ │ ├── Sort.php │ │ │ │ └── Tool/ │ │ │ │ ├── TypeTrait.php │ │ │ │ ├── ValueExtractorTrait.php │ │ │ │ └── ValueToStringTrait.php │ │ │ └── uuid/ │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── composer.json │ │ │ └── src/ │ │ │ ├── BinaryUtils.php │ │ │ ├── Builder/ │ │ │ │ ├── BuilderCollection.php │ │ │ │ ├── DefaultUuidBuilder.php │ │ │ │ ├── DegradedUuidBuilder.php │ │ │ │ ├── FallbackBuilder.php │ │ │ │ └── UuidBuilderInterface.php │ │ │ ├── Codec/ │ │ │ │ ├── CodecInterface.php │ │ │ │ ├── GuidStringCodec.php │ │ │ │ ├── OrderedTimeCodec.php │ │ │ │ ├── StringCodec.php │ │ │ │ ├── TimestampFirstCombCodec.php │ │ │ │ └── TimestampLastCombCodec.php │ │ │ ├── Converter/ │ │ │ │ ├── Number/ │ │ │ │ │ ├── BigNumberConverter.php │ │ │ │ │ ├── DegradedNumberConverter.php │ │ │ │ │ └── GenericNumberConverter.php │ │ │ │ ├── NumberConverterInterface.php │ │ │ │ ├── Time/ │ │ │ │ │ ├── BigNumberTimeConverter.php │ │ │ │ │ ├── DegradedTimeConverter.php │ │ │ │ │ ├── GenericTimeConverter.php │ │ │ │ │ ├── PhpTimeConverter.php │ │ │ │ │ └── UnixTimeConverter.php │ │ │ │ └── TimeConverterInterface.php │ │ │ ├── DegradedUuid.php │ │ │ ├── DeprecatedUuidInterface.php │ │ │ ├── DeprecatedUuidMethodsTrait.php │ │ │ ├── Exception/ │ │ │ │ ├── BuilderNotFoundException.php │ │ │ │ ├── DateTimeException.php │ │ │ │ ├── DceSecurityException.php │ │ │ │ ├── InvalidArgumentException.php │ │ │ │ ├── InvalidBytesException.php │ │ │ │ ├── InvalidUuidStringException.php │ │ │ │ ├── NameException.php │ │ │ │ ├── NodeException.php │ │ │ │ ├── RandomSourceException.php │ │ │ │ ├── TimeSourceException.php │ │ │ │ ├── UnableToBuildUuidException.php │ │ │ │ ├── UnsupportedOperationException.php │ │ │ │ └── UuidExceptionInterface.php │ │ │ ├── FeatureSet.php │ │ │ ├── Fields/ │ │ │ │ ├── FieldsInterface.php │ │ │ │ └── SerializableFieldsTrait.php │ │ │ ├── Generator/ │ │ │ │ ├── CombGenerator.php │ │ │ │ ├── DceSecurityGenerator.php │ │ │ │ ├── DceSecurityGeneratorInterface.php │ │ │ │ ├── DefaultNameGenerator.php │ │ │ │ ├── DefaultTimeGenerator.php │ │ │ │ ├── NameGeneratorFactory.php │ │ │ │ ├── NameGeneratorInterface.php │ │ │ │ ├── PeclUuidNameGenerator.php │ │ │ │ ├── PeclUuidRandomGenerator.php │ │ │ │ ├── PeclUuidTimeGenerator.php │ │ │ │ ├── RandomBytesGenerator.php │ │ │ │ ├── RandomGeneratorFactory.php │ │ │ │ ├── RandomGeneratorInterface.php │ │ │ │ ├── RandomLibAdapter.php │ │ │ │ ├── TimeGeneratorFactory.php │ │ │ │ ├── TimeGeneratorInterface.php │ │ │ │ └── UnixTimeGenerator.php │ │ │ ├── Guid/ │ │ │ │ ├── Fields.php │ │ │ │ ├── Guid.php │ │ │ │ └── GuidBuilder.php │ │ │ ├── Lazy/ │ │ │ │ └── LazyUuidFromString.php │ │ │ ├── Math/ │ │ │ │ ├── BrickMathCalculator.php │ │ │ │ ├── CalculatorInterface.php │ │ │ │ └── RoundingMode.php │ │ │ ├── Nonstandard/ │ │ │ │ ├── Fields.php │ │ │ │ ├── Uuid.php │ │ │ │ ├── UuidBuilder.php │ │ │ │ └── UuidV6.php │ │ │ ├── Provider/ │ │ │ │ ├── Dce/ │ │ │ │ │ └── SystemDceSecurityProvider.php │ │ │ │ ├── DceSecurityProviderInterface.php │ │ │ │ ├── Node/ │ │ │ │ │ ├── FallbackNodeProvider.php │ │ │ │ │ ├── NodeProviderCollection.php │ │ │ │ │ ├── RandomNodeProvider.php │ │ │ │ │ ├── StaticNodeProvider.php │ │ │ │ │ └── SystemNodeProvider.php │ │ │ │ ├── NodeProviderInterface.php │ │ │ │ ├── Time/ │ │ │ │ │ ├── FixedTimeProvider.php │ │ │ │ │ └── SystemTimeProvider.php │ │ │ │ └── TimeProviderInterface.php │ │ │ ├── Rfc4122/ │ │ │ │ ├── Fields.php │ │ │ │ ├── FieldsInterface.php │ │ │ │ ├── MaxTrait.php │ │ │ │ ├── MaxUuid.php │ │ │ │ ├── NilTrait.php │ │ │ │ ├── NilUuid.php │ │ │ │ ├── TimeTrait.php │ │ │ │ ├── UuidBuilder.php │ │ │ │ ├── UuidInterface.php │ │ │ │ ├── UuidV1.php │ │ │ │ ├── UuidV2.php │ │ │ │ ├── UuidV3.php │ │ │ │ ├── UuidV4.php │ │ │ │ ├── UuidV5.php │ │ │ │ ├── UuidV6.php │ │ │ │ ├── UuidV7.php │ │ │ │ ├── UuidV8.php │ │ │ │ ├── Validator.php │ │ │ │ ├── VariantTrait.php │ │ │ │ └── VersionTrait.php │ │ │ ├── Type/ │ │ │ │ ├── Decimal.php │ │ │ │ ├── Hexadecimal.php │ │ │ │ ├── Integer.php │ │ │ │ ├── NumberInterface.php │ │ │ │ ├── Time.php │ │ │ │ └── TypeInterface.php │ │ │ ├── Uuid.php │ │ │ ├── UuidFactory.php │ │ │ ├── UuidFactoryInterface.php │ │ │ ├── UuidInterface.php │ │ │ ├── Validator/ │ │ │ │ ├── GenericValidator.php │ │ │ │ └── ValidatorInterface.php │ │ │ └── functions.php │ │ ├── rize/ │ │ │ └── uri-template/ │ │ │ ├── .php-cs-fixer.dist.php │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── composer.json │ │ │ ├── phpstan.neon │ │ │ ├── phpunit.xml │ │ │ ├── src/ │ │ │ │ └── Rize/ │ │ │ │ ├── UriTemplate/ │ │ │ │ │ ├── Node/ │ │ │ │ │ │ ├── Abstraction.php │ │ │ │ │ │ ├── Expression.php │ │ │ │ │ │ ├── Literal.php │ │ │ │ │ │ └── Variable.php │ │ │ │ │ ├── Operator/ │ │ │ │ │ │ ├── Abstraction.php │ │ │ │ │ │ ├── Named.php │ │ │ │ │ │ └── UnNamed.php │ │ │ │ │ ├── Parser.php │ │ │ │ │ └── UriTemplate.php │ │ │ │ └── UriTemplate.php │ │ │ └── tests/ │ │ │ ├── Rize/ │ │ │ │ ├── Uri/ │ │ │ │ │ └── Node/ │ │ │ │ │ └── ParserTest.php │ │ │ │ └── UriTemplateTest.php │ │ │ └── fixtures/ │ │ │ ├── README.md │ │ │ ├── extended-tests.json │ │ │ ├── json2xml.xslt │ │ │ ├── negative-tests.json │ │ │ ├── spec-examples-by-section.json │ │ │ ├── spec-examples.json │ │ │ └── transform-json-tests.xslt │ │ └── symfony/ │ │ └── deprecation-contracts/ │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── composer.json │ │ └── function.php │ ├── classes/ │ │ ├── batch/ │ │ │ ├── class-batch-task-manager.php │ │ │ ├── class-batch-task.php │ │ │ ├── class-migration.php │ │ │ └── interface-batch.php │ │ ├── class-addons.php │ │ ├── class-ajax.php │ │ ├── class-api.php │ │ ├── class-bootstrap.php │ │ ├── class-compatibility.php │ │ ├── class-db.php │ │ ├── class-dynamic-image-support.php │ │ ├── class-errors.php │ │ ├── class-google-app-engine.php │ │ ├── class-gs-client.php │ │ ├── class-gs-stream-wrapper.php │ │ ├── class-helper.php │ │ ├── class-logger.php │ │ ├── class-migrator.php │ │ ├── class-module.php │ │ ├── class-settings.php │ │ ├── class-status.php │ │ ├── class-sync-non-media.php │ │ ├── class-upgrader.php │ │ ├── class-utility.php │ │ ├── compatibility/ │ │ │ ├── ewww.php │ │ │ ├── imagify.php │ │ │ ├── js/ │ │ │ │ └── shortpixel.js │ │ │ ├── learn-dash.php │ │ │ ├── shortpixel.php │ │ │ ├── the-events-calendar.php │ │ │ ├── wp-smush.php │ │ │ └── wpbakery-page-builder.php │ │ ├── exception-fatal.php │ │ ├── exception-unprocessable.php │ │ ├── status/ │ │ │ ├── class-info-google_cloud.php │ │ │ ├── class-info-stateless.php │ │ │ ├── class-info.php │ │ │ └── class-migrations.php │ │ ├── sync/ │ │ │ ├── class-background-sync.php │ │ │ ├── class-file-sync.php │ │ │ ├── class-helper-window.php │ │ │ ├── class-image-sync.php │ │ │ ├── class-library-sync.php │ │ │ ├── class-non-library-sync.php │ │ │ └── interface-sync.php │ │ └── trait-singleton.php │ ├── cli/ │ │ ├── class-sm-cli-command.php │ │ ├── class-sm-cli-process.php │ │ ├── class-sm-cli-scaffold.php │ │ ├── class-sm-cli-sync.php │ │ ├── class-sm-cli-upgrade.php │ │ └── class-sm-cli.php │ ├── includes/ │ │ ├── class-settings.php │ │ └── class-utility.php │ ├── meta-box-tabs/ │ │ ├── CHANGELOG.md │ │ ├── meta-box-tabs.php │ │ ├── tabs.css │ │ └── tabs.js │ └── ns-vendor/ │ └── classes/ │ ├── .gitkeep │ └── deliciousbrains/ │ └── wp-background-processing/ │ └── classes/ │ ├── wp-async-request.php │ └── wp-background-process.php ├── readme.md ├── readme.txt ├── static/ │ ├── data/ │ │ └── addons.php │ ├── migrations/ │ │ ├── 20240219175240.php │ │ └── 20240423174109.php │ ├── scripts/ │ │ ├── error-notice.js │ │ ├── i18n/ │ │ │ ├── af.js │ │ │ ├── ar.js │ │ │ ├── az.js │ │ │ ├── bg.js │ │ │ ├── bn.js │ │ │ ├── bs.js │ │ │ ├── ca.js │ │ │ ├── cs.js │ │ │ ├── da.js │ │ │ ├── de.js │ │ │ ├── dsb.js │ │ │ ├── el.js │ │ │ ├── en.js │ │ │ ├── es.js │ │ │ ├── et.js │ │ │ ├── eu.js │ │ │ ├── fa.js │ │ │ ├── fi.js │ │ │ ├── fr.js │ │ │ ├── gl.js │ │ │ ├── he.js │ │ │ ├── hi.js │ │ │ ├── hr.js │ │ │ ├── hsb.js │ │ │ ├── hu.js │ │ │ ├── hy.js │ │ │ ├── id.js │ │ │ ├── is.js │ │ │ ├── it.js │ │ │ ├── ja.js │ │ │ ├── ka.js │ │ │ ├── km.js │ │ │ ├── ko.js │ │ │ ├── lt.js │ │ │ ├── lv.js │ │ │ ├── mk.js │ │ │ ├── ms.js │ │ │ ├── nb.js │ │ │ ├── ne.js │ │ │ ├── nl.js │ │ │ ├── pl.js │ │ │ ├── ps.js │ │ │ ├── pt-BR.js │ │ │ ├── pt.js │ │ │ ├── ro.js │ │ │ ├── ru.js │ │ │ ├── sk.js │ │ │ ├── sl.js │ │ │ ├── sq.js │ │ │ ├── sr-Cyrl.js │ │ │ ├── sr.js │ │ │ ├── sv.js │ │ │ ├── th.js │ │ │ ├── tk.js │ │ │ ├── tr.js │ │ │ ├── uk.js │ │ │ ├── vi.js │ │ │ ├── zh-CN.js │ │ │ └── zh-TW.js │ │ ├── jquery-ui/ │ │ │ ├── jquery.ui.progressbar.min.1.7.2.js │ │ │ └── redmond/ │ │ │ └── jquery-ui-1.7.2.custom.css │ │ ├── wp-stateless-batch.js │ │ ├── wp-stateless-settings.js │ │ ├── wp-stateless-uploads.js │ │ └── wp-stateless.js │ ├── styles/ │ │ ├── error-notice.css │ │ ├── wp-stateless-addons.css │ │ ├── wp-stateless-settings.css │ │ ├── wp-stateless-setup-wizard.css │ │ ├── wp-stateless-status.css │ │ └── wp-stateless.css │ ├── views/ │ │ ├── .gitkeep │ │ ├── addons-tab.php │ │ ├── compatibility-tab.php │ │ ├── error-notice.php │ │ ├── processing_interface.php │ │ ├── settings-sections/ │ │ │ ├── file-url.php │ │ │ ├── general.php │ │ │ ├── google-cloud-storage.php │ │ │ └── network.php │ │ ├── settings-tab.php │ │ ├── settings_interface.php │ │ ├── setup_wizard_interface.php │ │ └── status-sections/ │ │ ├── info.php │ │ └── migrations.php │ └── wiki/ │ └── Media-Object.md ├── vendor/ │ ├── autoload.php │ ├── ccampbell/ │ │ └── chromephp/ │ │ ├── ChromePhp.php │ │ ├── README.md │ │ └── composer.json │ ├── composer/ │ │ ├── ClassLoader.php │ │ ├── InstalledVersions.php │ │ ├── LICENSE │ │ ├── autoload_classmap.php │ │ ├── autoload_namespaces.php │ │ ├── autoload_psr4.php │ │ ├── autoload_real.php │ │ ├── autoload_static.php │ │ ├── installed.json │ │ ├── installed.php │ │ ├── installers/ │ │ │ ├── .github/ │ │ │ │ └── workflows/ │ │ │ │ ├── continuous-integration.yml │ │ │ │ ├── lint.yml │ │ │ │ └── phpstan.yml │ │ │ ├── LICENSE │ │ │ ├── composer.json │ │ │ └── src/ │ │ │ ├── Composer/ │ │ │ │ └── Installers/ │ │ │ │ ├── AglInstaller.php │ │ │ │ ├── AkauntingInstaller.php │ │ │ │ ├── AnnotateCmsInstaller.php │ │ │ │ ├── AsgardInstaller.php │ │ │ │ ├── AttogramInstaller.php │ │ │ │ ├── BaseInstaller.php │ │ │ │ ├── BitrixInstaller.php │ │ │ │ ├── BonefishInstaller.php │ │ │ │ ├── BotbleInstaller.php │ │ │ │ ├── CakePHPInstaller.php │ │ │ │ ├── ChefInstaller.php │ │ │ │ ├── CiviCrmInstaller.php │ │ │ │ ├── ClanCatsFrameworkInstaller.php │ │ │ │ ├── CockpitInstaller.php │ │ │ │ ├── CodeIgniterInstaller.php │ │ │ │ ├── Concrete5Installer.php │ │ │ │ ├── ConcreteCMSInstaller.php │ │ │ │ ├── CroogoInstaller.php │ │ │ │ ├── DecibelInstaller.php │ │ │ │ ├── DframeInstaller.php │ │ │ │ ├── DokuWikiInstaller.php │ │ │ │ ├── DolibarrInstaller.php │ │ │ │ ├── DrupalInstaller.php │ │ │ │ ├── ElggInstaller.php │ │ │ │ ├── EliasisInstaller.php │ │ │ │ ├── ExpressionEngineInstaller.php │ │ │ │ ├── EzPlatformInstaller.php │ │ │ │ ├── ForkCMSInstaller.php │ │ │ │ ├── FuelInstaller.php │ │ │ │ ├── FuelphpInstaller.php │ │ │ │ ├── GravInstaller.php │ │ │ │ ├── HuradInstaller.php │ │ │ │ ├── ImageCMSInstaller.php │ │ │ │ ├── Installer.php │ │ │ │ ├── ItopInstaller.php │ │ │ │ ├── KanboardInstaller.php │ │ │ │ ├── KnownInstaller.php │ │ │ │ ├── KodiCMSInstaller.php │ │ │ │ ├── KohanaInstaller.php │ │ │ │ ├── LanManagementSystemInstaller.php │ │ │ │ ├── LaravelInstaller.php │ │ │ │ ├── LavaLiteInstaller.php │ │ │ │ ├── LithiumInstaller.php │ │ │ │ ├── MODULEWorkInstaller.php │ │ │ │ ├── MODXEvoInstaller.php │ │ │ │ ├── MagentoInstaller.php │ │ │ │ ├── MajimaInstaller.php │ │ │ │ ├── MakoInstaller.php │ │ │ │ ├── MantisBTInstaller.php │ │ │ │ ├── MatomoInstaller.php │ │ │ │ ├── MauticInstaller.php │ │ │ │ ├── MayaInstaller.php │ │ │ │ ├── MediaWikiInstaller.php │ │ │ │ ├── MiaoxingInstaller.php │ │ │ │ ├── MicroweberInstaller.php │ │ │ │ ├── ModxInstaller.php │ │ │ │ ├── MoodleInstaller.php │ │ │ │ ├── OctoberInstaller.php │ │ │ │ ├── OntoWikiInstaller.php │ │ │ │ ├── OsclassInstaller.php │ │ │ │ ├── OxidInstaller.php │ │ │ │ ├── PPIInstaller.php │ │ │ │ ├── PantheonInstaller.php │ │ │ │ ├── PhiftyInstaller.php │ │ │ │ ├── PhpBBInstaller.php │ │ │ │ ├── PiwikInstaller.php │ │ │ │ ├── PlentymarketsInstaller.php │ │ │ │ ├── Plugin.php │ │ │ │ ├── PortoInstaller.php │ │ │ │ ├── PrestashopInstaller.php │ │ │ │ ├── ProcessWireInstaller.php │ │ │ │ ├── PuppetInstaller.php │ │ │ │ ├── PxcmsInstaller.php │ │ │ │ ├── RadPHPInstaller.php │ │ │ │ ├── ReIndexInstaller.php │ │ │ │ ├── Redaxo5Installer.php │ │ │ │ ├── RedaxoInstaller.php │ │ │ │ ├── RoundcubeInstaller.php │ │ │ │ ├── SMFInstaller.php │ │ │ │ ├── ShopwareInstaller.php │ │ │ │ ├── SilverStripeInstaller.php │ │ │ │ ├── SiteDirectInstaller.php │ │ │ │ ├── StarbugInstaller.php │ │ │ │ ├── SyDESInstaller.php │ │ │ │ ├── SyliusInstaller.php │ │ │ │ ├── TaoInstaller.php │ │ │ │ ├── TastyIgniterInstaller.php │ │ │ │ ├── TheliaInstaller.php │ │ │ │ ├── TuskInstaller.php │ │ │ │ ├── UserFrostingInstaller.php │ │ │ │ ├── VanillaInstaller.php │ │ │ │ ├── VgmcpInstaller.php │ │ │ │ ├── WHMCSInstaller.php │ │ │ │ ├── WinterInstaller.php │ │ │ │ ├── WolfCMSInstaller.php │ │ │ │ ├── WordPressInstaller.php │ │ │ │ ├── YawikInstaller.php │ │ │ │ ├── ZendInstaller.php │ │ │ │ └── ZikulaInstaller.php │ │ │ └── bootstrap.php │ │ └── platform_check.php │ ├── firebase/ │ │ └── php-jwt/ │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── composer.json │ │ └── src/ │ │ ├── BeforeValidException.php │ │ ├── CachedKeySet.php │ │ ├── ExpiredException.php │ │ ├── JWK.php │ │ ├── JWT.php │ │ ├── JWTExceptionWithPayloadInterface.php │ │ ├── Key.php │ │ └── SignatureInvalidException.php │ ├── udx/ │ │ ├── lib-ud-api-client/ │ │ │ ├── .gitignore │ │ │ ├── .scrutinizer.yml │ │ │ ├── changes.md │ │ │ ├── composer.json │ │ │ ├── gruntfile.js │ │ │ ├── lib/ │ │ │ │ └── classes/ │ │ │ │ ├── class-admin.php │ │ │ │ ├── class-api.php │ │ │ │ ├── class-bootstrap.php │ │ │ │ ├── class-licenses-table.php │ │ │ │ ├── class-manager.php │ │ │ │ ├── class-more-products-table.php │ │ │ │ ├── class-scaffold.php │ │ │ │ ├── class-ui.php │ │ │ │ ├── class-update-checker.php │ │ │ │ └── class-utility.php │ │ │ ├── package.json │ │ │ ├── readme.md │ │ │ └── static/ │ │ │ ├── css/ │ │ │ │ ├── admin.css │ │ │ │ └── src/ │ │ │ │ └── admin.less │ │ │ └── templates/ │ │ │ ├── admin-notice.php │ │ │ ├── screen-manage-plugin.php │ │ │ ├── screen-manage-theme.php │ │ │ └── screen-more.php │ │ └── lib-wp-bootstrap/ │ │ ├── .gitignore │ │ ├── changes.md │ │ ├── composer.json │ │ ├── lib/ │ │ │ └── classes/ │ │ │ ├── class-bootstrap-plugin.php │ │ │ ├── class-bootstrap-theme.php │ │ │ ├── class-bootstrap.php │ │ │ ├── class-dashboard.php │ │ │ ├── class-errors.php │ │ │ ├── class-scaffold.php │ │ │ ├── class-tgm-bulk-installer.php │ │ │ ├── class-tgm-list-table.php │ │ │ ├── class-tgm-plugin-activation.php │ │ │ └── class-utility.php │ │ ├── readme.md │ │ └── static/ │ │ └── scripts/ │ │ └── ud-dismiss.js │ └── wpmetabox/ │ └── meta-box/ │ ├── css/ │ │ ├── autocomplete.css │ │ ├── background.css │ │ ├── button-group.css │ │ ├── color.css │ │ ├── date.css │ │ ├── divider.css │ │ ├── fieldset-text.css │ │ ├── file-input.css │ │ ├── file.css │ │ ├── fontawesome/ │ │ │ └── icons.json │ │ ├── heading.css │ │ ├── icon.css │ │ ├── image-select.css │ │ ├── image.css │ │ ├── input-list.css │ │ ├── input.css │ │ ├── jqueryui/ │ │ │ ├── core.css │ │ │ ├── datepicker.css │ │ │ ├── slider.css │ │ │ └── theme.css │ │ ├── key-value.css │ │ ├── map.css │ │ ├── media.css │ │ ├── modal.css │ │ ├── oembed.css │ │ ├── osm-frontend.css │ │ ├── osm.css │ │ ├── password.css │ │ ├── range.css │ │ ├── select-advanced.css │ │ ├── select-tree.css │ │ ├── select.css │ │ ├── select2/ │ │ │ └── select2.css │ │ ├── slider.css │ │ ├── style-rtl.css │ │ ├── style.css │ │ ├── switch.css │ │ ├── text-list.css │ │ ├── upload.css │ │ ├── video.css │ │ └── wysiwyg.css │ ├── inc/ │ │ ├── autoloader.php │ │ ├── clone.php │ │ ├── core.php │ │ ├── field-registry.php │ │ ├── field.php │ │ ├── fields/ │ │ │ ├── autocomplete.php │ │ │ ├── background.php │ │ │ ├── button-group.php │ │ │ ├── button.php │ │ │ ├── checkbox-list.php │ │ │ ├── checkbox.php │ │ │ ├── choice.php │ │ │ ├── color.php │ │ │ ├── custom-html.php │ │ │ ├── date.php │ │ │ ├── datetime.php │ │ │ ├── divider.php │ │ │ ├── fieldset-text.php │ │ │ ├── file-input.php │ │ │ ├── file-upload.php │ │ │ ├── file.php │ │ │ ├── heading.php │ │ │ ├── icon.php │ │ │ ├── image-advanced.php │ │ │ ├── image-select.php │ │ │ ├── image-upload.php │ │ │ ├── image.php │ │ │ ├── input-list.php │ │ │ ├── input.php │ │ │ ├── key-value.php │ │ │ ├── map.php │ │ │ ├── media.php │ │ │ ├── multiple-values.php │ │ │ ├── number.php │ │ │ ├── object-choice.php │ │ │ ├── oembed.php │ │ │ ├── osm.php │ │ │ ├── password.php │ │ │ ├── post.php │ │ │ ├── radio.php │ │ │ ├── range.php │ │ │ ├── select-advanced.php │ │ │ ├── select-tree.php │ │ │ ├── select.php │ │ │ ├── sidebar.php │ │ │ ├── single-image.php │ │ │ ├── slider.php │ │ │ ├── switch.php │ │ │ ├── taxonomy-advanced.php │ │ │ ├── taxonomy.php │ │ │ ├── text-list.php │ │ │ ├── textarea.php │ │ │ ├── time.php │ │ │ ├── user.php │ │ │ ├── video.php │ │ │ └── wysiwyg.php │ │ ├── functions.php │ │ ├── helpers/ │ │ │ ├── array.php │ │ │ ├── field.php │ │ │ ├── string.php │ │ │ └── value.php │ │ ├── interfaces/ │ │ │ └── storage.php │ │ ├── loader.php │ │ ├── media-modal.php │ │ ├── meta-box-registry.php │ │ ├── meta-box.php │ │ ├── request.php │ │ ├── sanitizer.php │ │ ├── shortcode.php │ │ ├── storage-registry.php │ │ ├── storages/ │ │ │ ├── base.php │ │ │ └── post.php │ │ ├── validation.php │ │ └── walkers/ │ │ ├── base.php │ │ ├── input-list.php │ │ ├── select-tree.php │ │ └── select.php │ ├── js/ │ │ ├── autocomplete.js │ │ ├── autosave.js │ │ ├── button-group.js │ │ ├── clone.js │ │ ├── color.js │ │ ├── date.js │ │ ├── datetime.js │ │ ├── file-input.js │ │ ├── file-upload.js │ │ ├── file.js │ │ ├── icon.js │ │ ├── image-advanced.js │ │ ├── image-upload.js │ │ ├── input-list.js │ │ ├── jqueryui/ │ │ │ └── jquery-ui-sliderAccess.js │ │ ├── leaflet/ │ │ │ ├── leaflet.css │ │ │ └── leaflet.js │ │ ├── map-frontend.js │ │ ├── map.js │ │ ├── media.js │ │ ├── modal.js │ │ ├── oembed.js │ │ ├── osm-frontend.js │ │ ├── osm.js │ │ ├── password.js │ │ ├── post.js │ │ ├── range.js │ │ ├── script.js │ │ ├── select-advanced.js │ │ ├── select-tree.js │ │ ├── select.js │ │ ├── select2/ │ │ │ └── i18n/ │ │ │ ├── af.js │ │ │ ├── ar.js │ │ │ ├── az.js │ │ │ ├── bg.js │ │ │ ├── bn.js │ │ │ ├── bs.js │ │ │ ├── ca.js │ │ │ ├── cs.js │ │ │ ├── da.js │ │ │ ├── de.js │ │ │ ├── dsb.js │ │ │ ├── el.js │ │ │ ├── en.js │ │ │ ├── es.js │ │ │ ├── et.js │ │ │ ├── eu.js │ │ │ ├── fa.js │ │ │ ├── fi.js │ │ │ ├── fr.js │ │ │ ├── gl.js │ │ │ ├── he.js │ │ │ ├── hi.js │ │ │ ├── hr.js │ │ │ ├── hsb.js │ │ │ ├── hu.js │ │ │ ├── hy.js │ │ │ ├── id.js │ │ │ ├── is.js │ │ │ ├── it.js │ │ │ ├── ja.js │ │ │ ├── ka.js │ │ │ ├── km.js │ │ │ ├── ko.js │ │ │ ├── lt.js │ │ │ ├── lv.js │ │ │ ├── mk.js │ │ │ ├── ms.js │ │ │ ├── nb.js │ │ │ ├── ne.js │ │ │ ├── nl.js │ │ │ ├── pl.js │ │ │ ├── ps.js │ │ │ ├── pt-BR.js │ │ │ ├── pt.js │ │ │ ├── ro.js │ │ │ ├── ru.js │ │ │ ├── sk.js │ │ │ ├── sl.js │ │ │ ├── sq.js │ │ │ ├── sr-Cyrl.js │ │ │ ├── sr.js │ │ │ ├── sv.js │ │ │ ├── th.js │ │ │ ├── tk.js │ │ │ ├── tr.js │ │ │ ├── uk.js │ │ │ ├── vi.js │ │ │ ├── zh-CN.js │ │ │ └── zh-TW.js │ │ ├── slider.js │ │ ├── taxonomy.js │ │ ├── time.js │ │ ├── user.js │ │ ├── validation/ │ │ │ ├── additional-methods.js │ │ │ ├── i18n/ │ │ │ │ ├── messages_ar.js │ │ │ │ ├── messages_az.js │ │ │ │ ├── messages_bg.js │ │ │ │ ├── messages_bn_BD.js │ │ │ │ ├── messages_ca.js │ │ │ │ ├── messages_cs.js │ │ │ │ ├── messages_da.js │ │ │ │ ├── messages_de.js │ │ │ │ ├── messages_el.js │ │ │ │ ├── messages_es.js │ │ │ │ ├── messages_es_AR.js │ │ │ │ ├── messages_es_PE.js │ │ │ │ ├── messages_et.js │ │ │ │ ├── messages_eu.js │ │ │ │ ├── messages_fa.js │ │ │ │ ├── messages_fi.js │ │ │ │ ├── messages_fr.js │ │ │ │ ├── messages_ge.js │ │ │ │ ├── messages_gl.js │ │ │ │ ├── messages_he.js │ │ │ │ ├── messages_hi.js │ │ │ │ ├── messages_hr.js │ │ │ │ ├── messages_hu.js │ │ │ │ ├── messages_hy_AM.js │ │ │ │ ├── messages_id.js │ │ │ │ ├── messages_is.js │ │ │ │ ├── messages_it.js │ │ │ │ ├── messages_ja.js │ │ │ │ ├── messages_ka.js │ │ │ │ ├── messages_kk.js │ │ │ │ ├── messages_ko.js │ │ │ │ ├── messages_lt.js │ │ │ │ ├── messages_lv.js │ │ │ │ ├── messages_mk.js │ │ │ │ ├── messages_my.js │ │ │ │ ├── messages_nl.js │ │ │ │ ├── messages_no.js │ │ │ │ ├── messages_pl.js │ │ │ │ ├── messages_pt_BR.js │ │ │ │ ├── messages_pt_PT.js │ │ │ │ ├── messages_ro.js │ │ │ │ ├── messages_ru.js │ │ │ │ ├── messages_sd.js │ │ │ │ ├── messages_si.js │ │ │ │ ├── messages_sk.js │ │ │ │ ├── messages_sl.js │ │ │ │ ├── messages_sr.js │ │ │ │ ├── messages_sr_lat.js │ │ │ │ ├── messages_sv.js │ │ │ │ ├── messages_th.js │ │ │ │ ├── messages_tj.js │ │ │ │ ├── messages_tr.js │ │ │ │ ├── messages_uk.js │ │ │ │ ├── messages_ur.js │ │ │ │ ├── messages_vi.js │ │ │ │ ├── messages_zh.js │ │ │ │ └── messages_zh_TW.js │ │ │ ├── jquery.validate.js │ │ │ └── validation.js │ │ ├── video.js │ │ └── wysiwyg.js │ ├── meta-box.php │ ├── readme.txt │ ├── src/ │ │ ├── Dashboard/ │ │ │ ├── Dashboard.php │ │ │ ├── assets/ │ │ │ │ ├── css/ │ │ │ │ │ ├── dashboard.css │ │ │ │ │ └── dashboard.scss │ │ │ │ └── js/ │ │ │ │ └── dashboard.js │ │ │ └── content.php │ │ ├── FeaturedPlugins.php │ │ ├── Integrations/ │ │ │ ├── Block.php │ │ │ ├── Bricks.php │ │ │ ├── Elementor.php │ │ │ ├── Oxygen.php │ │ │ └── WPML.php │ │ └── Updater/ │ │ ├── Checker.php │ │ ├── Notification.php │ │ ├── Option.php │ │ └── Settings.php │ └── vendor/ │ ├── autoload.php │ ├── composer/ │ │ ├── ClassLoader.php │ │ ├── InstalledVersions.php │ │ ├── LICENSE │ │ ├── autoload_classmap.php │ │ ├── autoload_namespaces.php │ │ ├── autoload_psr4.php │ │ ├── autoload_real.php │ │ ├── autoload_static.php │ │ ├── installed.json │ │ └── installed.php │ └── wpmetabox/ │ └── support/ │ ├── Arr.php │ └── Data.php └── wp-stateless-media.php ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/dependabot.yml ================================================ version: 2 updates: # Enable checks for the default vendor folder - package-ecosystem: "composer" directory: "/" schedule: interval: "weekly" # Enable checks for Google API Client package - package-ecosystem: "composer" directory: "/lib/Google" schedule: interval: "weekly" # Enable checks for GitHub Actions - package-ecosystem: "github-actions" directory: "/" schedule: interval: "weekly" ================================================ FILE: .github/workflows/publish-release.yml ================================================ name: Publish Release run-name: Publish Release on: workflow_dispatch: inputs: tag: description: 'Release tag (e.g. 1.2.3a)' required: true version: description: 'Release version (e.g. 1.2.3), default: latest' required: false prerelease: description: 'Pre-release version (e.g. RC1, beta, etc...)' required: false permissions: contents: write jobs: release: uses: udx/reusable-workflows/.github/workflows/wp-gh-release-ops.yml@master with: tag: ${{ github.event.inputs.tag }} version: ${{ github.event.inputs.version }} prerelease: ${{ github.event.inputs.prerelease }} ================================================ FILE: .github/workflows/security-scan.yml ================================================ name: Security Scan run-name: Security Scan on: push: pull_request: workflow_dispatch: jobs: code-scanning: name: Code Scanning (grype) runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v6 - name: Run Security Check id: test uses: anchore/scan-action@v6 with: path: . output-format: table ================================================ FILE: .gitignore ================================================ temp .vscode** node_modules static/cache static/codex npm-debug.log wp-test-config.php /test package-lock.json .git .svn .idea .idea/workspace.xml .DS_Store .dynamic .Trashes *.sublime-project *.sublime-workspace *.seed *.log *.csv *.dat *.out *.pid *.gz wp-stateless.wiki ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2018 Usability Dynamics 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. ================================================ FILE: SECURITY.md ================================================ # Security Policy Overview Thank you for using and contributing to our product. At [UDX](https://udx.io), we take the security of our products seriously and appreciate collaborative efforts to ensure the safety of our users and contributors. ## Reporting a Security Vulnerability **Please do not report security vulnerabilities through public GitHub issues.** If you find a security vulnerability, please [submit a vulnerability report](https://github.com/udx/wp-stateless/security/advisories/new). Provide detailed information about the vulnerability to help us understand and address the issue promptly. We kindly request that you avoid public disclosure until we've had the opportunity to analyze and resolve the reported issue. ## Responsible Disclosure Responsible disclosure is crucial to maintaining the security of our product. We ask for your cooperation in allowing us sufficient time to investigate and address the reported vulnerability before making it public. We will keep you informed of our progress and make every effort to address the issue promptly. ## Supported Versions Security updates are provided for the latest stable release. Please ensure that you are using a supported version before reporting a security vulnerability. ## Contact Information For security-related matters, please contact our security team at [security@udx.io](mailto:security@udx.io). For general inquiries, feature requests, and other non-security-related discussions, please use our regular [issue tracker](https://github.com/udx/wp-stateless/issues). Thank you for helping us ensure the security of WP-Stateless. Your contributions are greatly appreciated. ================================================ FILE: changelog.txt ================================================ == Changelog == = 4.4.1 - 2026-01-16 = * COMPATIBILITY - WooCommerce Extra Product Options Compatibility replaced with [WP-Stateless – WooCommerce Extra Product Options Addon](https://wordpress.org/plugins/wp-stateless-woocommerce-extra-product-options-addon/). * FIX - resolve critical errors with `firebase/php-jwt` library if `AUTH_SALT` WordPress constant is not set or too short. = 4.4.0 - 2026-01-10 = * NEW - plugin requires PHP 8.1+. * ENHANCEMENT - updated `firebase/php-jwt` library from 6.11.1 to 7.0.2. * ENHANCEMENT - Updated Client library for Google APIs from 2.18.3 to 2.19.0. * ENHANCEMENT - updated `wpmetabox/meta-box` library from 5.10.15 to 5.10.19. * ENHANCEMENT - updated `Meta Box Tabs` library from 1.1.18 to 1.2.0. * FIX - `udx/lib-wp-bootstrap` package correctly loads text domain to prevent PHP notices. = 4.3.0 = * ENHANCEMENT - update dependencies for Google APIs Client Library. * COMPATIBILITY - Simple Local Avatars Compatibility replaced with [WP-Stateless - Simple Local Avatars Addon](https://wordpress.org/plugins/wp-stateless-simple-local-avatars-addon/). = 4.2.1 = * ENHANCEMENT - updated `wpmetabox/meta-box` library from 5.10.11 to 5.10.15. * FIX - correctly loads text domain to prevent PHP notices. * FIX - `udx/lib-ud-api-client` package correctly loads text domain to prevent PHP notices. = 4.2.0 = * ENHANCEMENT - Updated Client library for Google APIs from 2.18.2 to 2.18.3. * ENHANCEMENT - updated `firebase/php-jwt` library from 6.10.2 to 6.11.1. * ENHANCEMENT - updated `wpmetabox/meta-box` library from 5.10.1 to 5.10.11. * DEPRECATED - Setup Assistant removed. = 4.1.3 = * COMPATIBILITY - PolyLang Compatibility replaced with [WP-Stateless – Polylang Pro Addon](https://wordpress.org/plugins/wp-stateless-polylang-pro-addon/). * ENHANCEMENT - updated `wpmetabox/meta-box` library from from 5.10.1 to 5.10.7. * ENHANCEMENT - updated `Meta Box Tabs` library from 1.1.18 to 1.2.0. * ENHANCEMENT - updated `firebase/php-jwt` library from from 6.10.1 to 6.10.2. * ENHANCEMENT - Updated Client library for Google APIs from 2.17.0 to 2.18.2. * FIX - apply `Cache Control` setting to all files (previously applied only to images). = 4.1.2 = * ENHANCEMENT - added `REST API Endpoint` setting, which useful when WordPress dashboard and frontend website utilize different domain names. * ENHANCEMENT - extended `Status Info` with the information to help diagnose REST API or AJAX issues. * COMPATIBILITY - SiteOrigin Widgets Bundle Compatibility replaced with [WP-Stateless - SiteOrigin Widgets Bundle Addon](https://wordpress.org/plugins/wp-stateless-siteorigin-widgets-bundle-addon/). * COMPATIBILITY - WPForms Compatibility replaced with [WP-Stateless - WPForms Addon](https://wordpress.org/plugins/wp-stateless-wpforms-addon/). * COMPATIBILITY - Easy Digital Downloads Compatibility replaced with [WP-Stateless - Easy Digital Downloads Addon](https://wordpress.org/plugins/wp-stateless-easy-digital-downloads-addon/). * COMPATIBILITY - LiteSpeed Cache Compatibility replaced with [WP-Stateless - LiteSpeed Cache Addon](https://wordpress.org/plugins/wp-stateless-litespeed-cache-addon/). * COMPATIBILITY - BuddyPress Compatibility replaced with [WP-Stateless - BuddyPress Addon](https://wordpress.org/plugin/wp-stateless-buddypress-addon/). * FIX: remove PHP warning on `Status` settings tab. * FIX: database updates to resolve conflicts with Polylang Pro compatibility. = 4.1.1 = * FIX - cache issues during Data Optimization. = 4.1.0 = * NEW - move compatibilities files from `wp_sm_sync` to `wp_stateless_files` table with extended information. * COMPATIBILITY - WooCommerce Compatibility replaced with [WP-Stateless – WooCommerce Addon](https://wordpress.org/plugins/wp-stateless-woocommerce-addon/). * COMPATIBILITY - Gravity Forms Compatibility replaced with [WP-Stateless – Gravity Forms Addon](https://wordpress.org/plugins/wp-stateless-gravity-forms-addon/). * COMPATIBILITY - Gravity Forms Signature Compatibility replaced with [WP-Stateless – Gravity Forms Signature Addon](https://wordpress.org/plugins/wp-stateless-gravity-forms-signature-addon/). * COMPATIBILITY - Divi Theme Compatibility replaced with [WP-Stateless – Divi Theme Addon](https://wordpress.org/plugins/wp-stateless-divi-theme-addon/). * COMPATIBILITY - SiteOrigin CSS Compatibility replaced with [WP-Stateless – SiteOrigin CSS Addon](https://wordpress.org/plugins/wp-stateless-siteorigin-css-addon/). * ENHANCEMENT - CLI command `wp stateless migrate` supports `auto` parameter to run all required Data Optimizations automatically. * ENHANCEMENT - Updated Client library for Google APIs from 2.15.1 to 2.17.0. * ENHANCEMENT - updated `firebase/php-jwt` library from from 6.9.0 to 6.10.1. * ENHANCEMENT - updated `wpmetabox/meta-box` library from from 5.8.2 to 5.10.1. * ENHANCEMENT - updated `deliciousbrains/wp-background-processing` library from from 1.1.1 to 1.3.1. * ENHANCEMENT - updated `composer/installers` library from from 1.12.1 to 2.3.0. * ENHANCEMENT - updated `Meta Box Tabs` library from 1.1.17 to 1.1.18. * ENHANCEMENT - action `sm:sync::addFile` format changed, now it passes media object instead of file name. * ENHANCEMENT - for installed Addons replace Download action with Activate. * ENHANCEMENT - count compatibility files from the DB instead of listing actual files to increase performance. * FIX - CLI command `wp stateless migrate` supports `--yes` parameter to skip confirmation. * FIX - CLI command `wp stateless migrate` correctly works with `--progress` parameter in multisite. * FIX - fixed synchronization for Compatibility files in Stateless Mode. * FIX - CLI command `wp stateless upgrade` fixed when running with `--b` switch. * FIX - fixed SiteOrigin Widgets Bundle Compatibility in `Stateless` mode. * FIX - fixed WPForms Compatibility in `Stateless` mode. * FIX - limit index size for compatibility with different DB engines [757](https://github.com/udx/wp-stateless/issues/757). * FIX - correctly disable `Cache-Busting` setting for Ephemeral Mode [758](https://github.com/udx/wp-stateless/issues/758), credits [@Jessedev1](https://github.com/Jessedev1). * FIX - Data Optimization UI adjustments. = 4.0.4 = * ENHANCEMENT - display success message after copying Status Info. * FIX - `Settings` page does not open or slow when there is big amount of attachments. * FIX - in multisite network, removing custom tables properly when deleting site. * FIX - skip setting ACL in Stateless mode and during Sync for the buckets with Uniform access, support WP_STATELESS_SKIP_ACL_SET constant [#712](https://github.com/udx/wp-stateless/issues/712). = 4.0.3 = * NEW - added `Info` section to the `Status` tab on the Settings page, which contains the system info and the ability to copy report to clipboard. * ENHANCEMENT - added `Documentation` link on the Plugins page. * ENHANCEMENT - added `Addons` link on the Plugins page. * ENHANCEMENT - added `Documentation` link on the Settings page. * FIX - fixed `Settings` shortcut on the Plugins page. * FIX - in multisite network, do not show Data Optimization on the Network Admin Page. * FIX - properly set `Content Disposition` fields for media objects. * FIX - properly use `Cache Control` setting for media objects. * FIX - fixed `Creation of dynamic property` PHP deprecation notice. * FIX - fixed `Cannot use ::class with dynamic class name` PHP warning. * FIX - avoid PHP warning when unable to get file path in `Stateless` mode [728](https://github.com/udx/wp-stateless/issues/728). * FIX - fixed links to the constants documentation. = 4.0.2 = * FIX - in multisite network, deleting site can potentially remove WP-Stateless tables from another site. * COMPATIBILITY - Gravity Forms Compatibility updated for the newest Gravity Forms version. = 4.0.1 = * FIX - improvements to Data Optimization process. * FIX - Data Optimization fixed for multisite environment. = 4.0.0 = * NEW - use custom database tables to store GCS file data. This increases plugin performance and will be used for future improvements. * NEW - added filter `wp_stateless_get_file`, retrieves the GCS file data, should be used instead of getting `sm_cloud` postmeta directly. * NEW - added filter `wp_stateless_get_file_sizes`, retrieves the GCS file data for image sizes, should be used instead of getting `sm_cloud` postmeta directly. * NEW - added filter `wp_stateless_get_file_meta`, retrieves all GCS file meta data, should be used instead of getting `sm_cloud` postmeta directly. * NEW - added filter `wp_stateless_get_file_meta_value`, retrieves the GCS file meta data by meta_key, should be used instead of getting `sm_cloud` postmeta directly. * NEW - added filter `wp_stateless_get_setting_...` which allows to override any WP-Stateless setting. * NEW - added setting "Send Status Emails" allowing to change email for WP-Stateless notifications. * NEW - added setting "Use Post Meta" allowing to switch back to using `postmeta` instead of custom DB tables. Can be used in case of issues after upgrading to 4.0.0. * NEW - added new Settings tab `Addons`, which contains the list of WP-Stateless Addons, which replace Compatibilities. * NEW - added new Settings tab `Status`, which contains status and health information related to Google Cloud Storage and WP-Stateless. * NEW - CLI command `wp stateless migrate` to list and operate data optimizations. * NEW - configuration constant [`WP_STATELESS_POSTMETA`](https://stateless.udx.io/docs/constants/#wp_stateless_postmeta) allows to read the GCS file data from postmeta instead of the new custom database tables. * NEW - configuration constant [`WP_STATELESS_BATCH_HEALTHCHECK_INTERVAL`](https://stateless.udx.io/docs/constants/#wp_stateless_batch_healthcheck_interval) defines an interval in minutes for periodical health checks of a batch background process (like data optimization). * COMPATIBILITY - BuddyBoss Compatibility replaced with [WP-Stateless – BuddyBoss Platform Addon](https://wordpress.org/plugins/wp-stateless-buddyboss-platform-addon/). * COMPATIBILITY - Elementor Compatibility replaced with [WP-Stateless – Elementor Website Builder Addon](https://wordpress.org/plugins/wp-stateless-elementor-website-builder-addon/). * COMPATIBILITY - Gravity Form Compatibility does not support older version of Gravity Forms (< 2.3). * ENHANCEMENT - Allow dismissing notices in Admin Panel only for logged in users. * ENHANCEMENT - Updated `wp-background-processing` library from from 1.0.2 to 1.1.1. * ENHANCEMENT - Updated `phpseclib` 3.0.34 to 3.0.37. * FIX - proper use of infinite timeout in `set_time_limit` function to avoid issues with PHP 8.1 and above [#704](https://github.com/udx/wp-stateless/issues/704). = 3.4.1 = * FIX - improve security while processing AJAX requests in Admin Panel = 3.4.0 = * ENHANCEMENT - removed `udx/lib-settings` package dependency for security reasons. * ENHANCEMENT - removed `udx/lib-utility` package dependency for security reasons. * ENHANCEMENT - refactored `Settings` admin page to remove Angular dependency. * ENHANCEMENT - including Software Bill of Materials (SBOM) to GitHub release. * FIX - updated package dependencies for Google Client Library for security reasons. * FIX - replaced `utf8_encode` with `mb_convert_encoding` to support PHP 8.2 and above [#678](https://github.com/udx/wp-stateless/issues/678). * FIX - Fatal Error in `Stateless` mode if GCP access credentials are wrong [#693](https://github.com/udx/wp-stateless/issues/693). * COMPATIBILITY - preventing PHP warnings while working with WooCommerce version 8.4.0 and above [696](https://github.com/udx/wp-stateless/issues/696). * COMPATIBILITY - avoiding conflicts between builtin compatibilities and WP-Stateless Addon plugins. = 3.3.0 = * NEW - Added new filter `wp_stateless_attachment_url`. Allows to customize attachment URL after WP-Stateless generates it based on it's internal conditions. * FIX - Stateless mode Incompatible with Media Uploader in Media Library Grid mode [#675](https://github.com/udx/wp-stateless/issues/675). * FIX - Prevent duplicating messages in Admin Panel. * COMPATIBILITY - Dynamic Image Support is now part of the core. * COMPATIBILITY - Google App Engine is now part of the core. Automatically enables **Stateless** mode when Google App Engine detected. Can be disabled using `WP_STATELESS_COMPATIBILITY_GAE` constant. * COMPATIBILITY - Removed compatibility with "Advanced Custom Fields: Image Crop Add-on", because plugin is deprecated. * COMPATIBILITY - Removed compatibility with "VidoRev" plugin. * COMPATIBILITY - Removed compatibility with "WP Retina 2x" plugin. * ENHANCEMENT - Updated Client library for Google APIs from 2.15.0 to 2.15.1. * ENHANCEMENT - Updated Meta Box library from 5.6.3 to 5.8.2. * ENHANCEMENT - Updated Meta Box Tabs to version 1.1.17. * ENHANCEMENT - Updated PHP JWT library from 6.6.0 to 6.9.0. = 3.2.5 = * FIX - Folder setting does not allow custom structure [#608](https://github.com/udx/wp-stateless/issues/608). * FIX - Stateless mode Incompatible with Inline Uploader [#675](https://github.com/udx/wp-stateless/issues/675). * FIX - html tags incorrectly applied in notice [#680](https://github.com/udx/wp-stateless/issues/680). * ENHANCEMENT - Add WP_STATELESS_SKIP_ACL_SET for skip ACL set for GCS [#625](https://github.com/udx/wp-stateless/issues/625). * COMPATIBILITY - Add support for The Events Calendar [#599](https://github.com/udx/wp-stateless/issues/599). = 3.2.4 = * FIX - Website unresponsive after Upgrade [#669](https://github.com/udx/wp-stateless/issues/669). = 3.2.3 = * ENHANCEMENT - Updated Client library for Google APIs. * ENHANCEMENT - Updated Monolog library to version 3. * ENHANCEMENT - Updated JWT library. * FIX - Fixed vulnerability issues. * FIX - Fixed an errors and warnings on PHP 8.1. * FIX - Fixed an error that occured when WP_STATELESS_MEDIA_UPLOAD_CHUNK_SIZE is set. = 3.2.2 = * FIX - Folder setting can't be saved from the settings page [#639](https://github.com/udx/wp-stateless/issues/639). = 3.2.1 = * FIX - Updated requirments. * FIX - WP-Stateless 3.2.0 doesn’t upload docs, only images [#638](https://github.com/udx/wp-stateless/issues/638). = 3.2.0 = * ENHANCEMENT - Upgraded `wpmetabox` library. * ENHANCEMENT - Updated Client library for Google APIs. * ENHANCEMENT - Updated Guzzle library to version 7. * ENHANCEMENT - Updated JWT library. * ENHANCEMENT - Updated `license` functionality, removed `update checker`. * FIX - Fixed vulnerability issues. * FIX - Fixed erros and warnings on PHP 8. * FIX - problem after the upgrade [#628](https://github.com/udx/wp-stateless/issues/628). * FIX - image_downsize() PHP8 Required parameter $id follows optional parameter $false [#619](https://github.com/udx/wp-stateless/issues/619). = 3.1.1 = * ENHANCEMENT - Notification for the administrator about finished synchronization. GitHub issue [#576](https://github.com/udx/wp-stateless/issues/576). * FIX - Fixed an issue with PDF thumbnails. GitHub issue [#577](https://github.com/udx/wp-stateless/issues/577). * FIX - Fixed an issue with synchronization in `Stateless` mode. GitHub issue [#575](https://github.com/udx/wp-stateless/issues/575). * COMPATIBILITY - Changed the way compatibility files are stored on Multisite. GitHub issue [#588](https://github.com/udx/wp-stateless/issues/588). = 3.1.0 = * NEW - Completely rewritten the synchronization tool. GitHub issue [#523](https://github.com/udx/wp-stateless/issues/523). * NEW - New configuration constant `WP_STATELESS_SYNC_MAX_BATCH_SIZE`. Sets the maximum size of a background sync batch of items to be saved in a single row in the database. [More details](https://stateless.udx.io/docs/constants/#wp_stateless_sync_max_batch_size). * NEW - New configuration constant `WP_STATELESS_SYNC_LOG`. Sets a path to a log file where to output logging information during the background sync. [More details](https://stateless.udx.io/docs/constants/#wp_stateless_sync_log). * NEW - New configuration constant `WP_STATELESS_SYNC_HEALTHCHECK_INTERVAL`. Defines an interval in minutes for a cron task that periodically checks the health of a particular background sync process. [More details](https://stateless.udx.io/docs/constants/#wp_stateless_sync_healthcheck_interval). * FIX - Fixed an issue when original files were not deleted from the server in the Ephemeral mode. GitHub issue [#484](https://github.com/udx/wp-stateless/issues/484). * FIX - Fixed an incorrect behavior of image `srcset` attribute in the Backup mode. GitHub issue [#558](https://github.com/udx/wp-stateless/issues/558). * COMPATIBILITY - Litespeed Cache - Fixed an incorrect upload folder determination. GitHub issue [#527](https://github.com/udx/wp-stateless/issues/527). = 3.0.4 = * FIX - Fixed inability to use dashes in the upload folder name. GitHub issue [#565](https://github.com/udx/wp-stateless/issues/565). * COMPATIBILITY - Elementor - Fixed wrong upload directory. GitHub issue [#560](https://github.com/udx/wp-stateless/issues/560). = 3.0.3 = * FIX - Fixed an incorrect file URL in Stateless mode on Edit Media screen. GitHub issue [#544](https://github.com/udx/wp-stateless/issues/544). = 3.0.2 = * FIX - Refactored the way files are being uploaded to GCS when `WP_STATELESS_MEDIA_UPLOAD_CHUNK_SIZE` constant is defined. GitHub issue [#553](https://github.com/udx/wp-stateless/issues/553). * FIX - Fixed the process of upgrading to 3.0 for multisite installations. GitHub issue [#549](https://github.com/udx/wp-stateless/issues/549). = 3.0.1 = * FIX - Fatal Error in Stateless mode. GitHub issue [#546](https://github.com/udx/wp-stateless/issues/546). = 3.0 = * NEW - Setup assistant rewrite. GitHub issue [#477](https://github.com/udx/wp-stateless/issues/477). * NEW - Recreate attachment metabox panel using metabox.io. GitHub issue [#470](https://github.com/udx/wp-stateless/issues/470). * NEW - Updated the `Stateless` mode to not use local storage at all. Current `Stateless` mode setting mapped to new `Ephemeral` mode. GitHub issue [#482](https://github.com/udx/wp-stateless/issues/482). * NEW - Files are now uploaded to GCS in chunks and chunk size will be determined based on free memory available. GitHub issue [#478](https://github.com/udx/wp-stateless/issues/478). * NEW - File upload chunk size can be controlled with `WP_STATELESS_MEDIA_UPLOAD_CHUNK_SIZE` constant. GitHub issue [#478](https://github.com/udx/wp-stateless/issues/478). * FIX - Changed the default value for the Cache-Busting setting. GitHub issue [#361](https://github.com/udx/wp-stateless/issues/361). * FIX - Fixed network override of Cache-Busting. GitHub issue [#468](https://github.com/udx/wp-stateless/issues/468). * FIX - Fixed "Passing glue string after array is deprecated.". GitHub issue [#444](https://github.com/udx/wp-stateless/issues/444). * FIX - Fixed Compatibility default value in multisite. GitHub issue [#464](https://github.com/udx/wp-stateless/issues/464). * FIX - Fixed multisite wrong GCS path. GitHub issue [#407](https://github.com/udx/wp-stateless/issues/407). * FIX - Don't check for Google Cloud Storage connectivity in stateless mode unless uploading. GitHub issue [#442](https://github.com/udx/wp-stateless/issues/442). * COMPATIBILITY - Google App Engine - Added new compatibility support for Google App Engine. [#486](https://github.com/udx/wp-stateless/issues/486) * COMPATIBILITY - Elementor - Fixed wrong MIME type for CSS files. GitHub issue [#395](https://github.com/udx/wp-stateless/issues/395). * COMPATIBILITY - Polylang - Fixed missing metadata issue. GitHub issue [#378](https://github.com/udx/wp-stateless/issues/378). * COMPATIBILITY - EWWW - Fixed mime type for WEBP images. GitHub issue [#371](https://github.com/udx/wp-stateless/issues/371). * COMPATIBILITY - Simple Local Avatars - Added new compatibility support for Simple Local Avatars. GitHub issue [#297](https://github.com/udx/wp-stateless/issues/297). * COMPATIBILITY - BuddyPress - Fixed BuddyPress compatibility. GitHub issue [#275](https://github.com/udx/wp-stateless/issues/275). * COMPATIBILITY - Divi - Fixed Divi cache issue. GitHub issue [#430](https://github.com/udx/wp-stateless/issues/430). * COMPATIBILITY - Gravity Forms - add compatibility for Gravity Forms Signature Add-On. [#501](https://github.com/udx/wp-stateless/issues/501). * COMPATIBILITY - Litespeed - Fixed fatal error and warnings. [#491](https://github.com/udx/wp-stateless/issues/491). * COMPATIBILITY - Imagify - Added support for webp. [#403](https://github.com/udx/wp-stateless/issues/403). * ENHANCEMENT - Update Client library for Google APIs. [#446](https://github.com/udx/wp-stateless/issues/446). * ENHANCEMENT - Wildcards for bucket folder settings. GitHub issue [#149](https://github.com/udx/wp-stateless/issues/149). * ENHANCEMENT - Better CLI integration. GitHub issue [#447](https://github.com/udx/wp-stateless/issues/447), [#450](https://github.com/udx/wp-stateless/issues/450) and [#451](https://github.com/udx/wp-stateless/issues/451). * ENHANCEMENT - Sync media according to new Bucket Folder settings. GitHub issue [#449](https://github.com/udx/wp-stateless/issues/449). * ENHANCEMENT - Moved Bucket Folder setting in the File URL section. GitHub issue [#463](https://github.com/udx/wp-stateless/issues/463). * ENHANCEMENT - Hide Regenerate and Sync with GCS when the mode is Disabled. GitHub issue [#440](https://github.com/udx/wp-stateless/issues/440). * ENHANCEMENT - New endpoint for the Google Cloud Storage JSON API. GitHub issue [#384](https://github.com/udx/wp-stateless/issues/384). * ENHANCEMENT - Renamed current `Stateless` mode to `Ephemeral`. GitHub issue [#481](https://github.com/udx/wp-stateless/issues/481). = 2.3.2 = * FIX - Fixed video file doesn't get deleted from the server in `Stateless` mode. GitHub issue [#418](https://github.com/wpCloud/wp-stateless/issues/418). * FIX - Fixed file size doesn't show under attachment details in `Stateless` mode. GitHub issue [#413](https://github.com/wpCloud/wp-stateless/issues/413). * FIX - Fixed Cache-Busting feature works even if the Mode is `Disabled`. GitHub issue [#405](https://github.com/wpCloud/wp-stateless/issues/405). * COMPATIBILITY - Fixed Gravity Form Post Image didn't include `Bucket Folder`. GitHub issue [#421](https://github.com/wpCloud/wp-stateless/issues/421). * COMPATIBILITY - Fixed Divi Builder Export. GitHub issue [#420](https://github.com/wpCloud/wp-stateless/issues/420). * COMPATIBILITY - Fixed BuddyBoss pages breaking after updating to 2.3.0. GitHub issue [#417](https://github.com/wpCloud/wp-stateless/issues/417). = 2.3.1 = * Fix - Fixed fatal error, undefined function `is_wp_version_compatible`. GitHub issue [#414](https://github.com/wpCloud/wp-stateless/issues/414). = 2.3.0 = * FIX - Fixed problem with WordPress 5.3. GitHub issue [#406](https://github.com/wpCloud/wp-stateless/issues/406). * FIX - Fixed problem with the Cache Busting feature. GitHub issue [#377](https://github.com/wpCloud/wp-stateless/issues/377). * COMPATIBILITY - Added compatibility support for WP Retina 2x pro. GitHub issue [#380](https://github.com/wpCloud/wp-stateless/issues/380). * COMPATIBILITY - Enhanced compatibility support for LiteSpeed Cache. GitHub issue [#365](https://github.com/wpCloud/wp-stateless/issues/365). * COMPATIBILITY - Enhanced compatibility support for ShortPixel Image Optimizer. GitHub issue [#364](https://github.com/wpCloud/wp-stateless/issues/364), [#398](https://github.com/wpCloud/wp-stateless/issues/398). * COMPATIBILITY - Fixed Gravity Form export. GitHub issue [#408](https://github.com/wpCloud/wp-stateless/issues/408). * ENHANCEMENT - Improved upon add_media function for better compatibility support. GitHub issue [#382](https://github.com/wpCloud/wp-stateless/issues/382). = 2.2.7 = * FIX - WP-Smush compatibility enhanced. GitHub Issue [#366](https://github.com/wpCloud/wp-stateless/issues/366). * FIX - Fixed multisite installation support. GitHub Issue [#370](https://github.com/wpCloud/wp-stateless/issues/370). * FIX - Fixed settings UI problems related to Cache-Busting option. GitHub Issue [#373](https://github.com/wpCloud/wp-stateless/issues/373). * FIX - Other minor fixes. = 2.2.6 = * FIX - Multisite Network Settings page fixed. GitHub Issue [#369](https://github.com/wpCloud/wp-stateless/issues/369). * FIX - Fixed incorrect Compatibilities behavior when Bucket Folder is set. GitHub Issue [#368](https://github.com/wpCloud/wp-stateless/issues/368). * FIX - Other minor fixes. = 2.2.5 = * NEW - Added ability to start sync process from specific Attachment ID. GitHub Issue [#360](https://github.com/wpCloud/wp-stateless/issues/360). * COMPATIBILITY - Added compatibility support for LiteSpeed Cache plugin. Especially to support optimized .webp images. GitHub Issue [#357](https://github.com/wpCloud/wp-stateless/issues/357). * FIX - Other minor fixes. = 2.2.4 = * NEW - Added new filter `wp_stateless_skip_add_media`. Allows skipping synchronization of the media object with GCS depending on custom condition. GitHub Issue [#344](https://github.com/wpCloud/wp-stateless/issues/344). * FIX - Compatibility Manager is considering Child Themes now. GitHub Issue [#351](https://github.com/wpCloud/wp-stateless/issues/351). * FIX - Custom domains handling has been fixed. GitHub Issue [#358](https://github.com/wpCloud/wp-stateless/issues/358). * ENHANCEMENT - Imagify Image Optimizer and WP Smush compatibilities improved. GitHub Issue [#359](https://github.com/wpCloud/wp-stateless/issues/359). = 2.2.3 = * FIX - get_post_metadata does not break multi-dimensional arrays anymore. GitHub Issue [#352](https://github.com/wpCloud/wp-stateless/issues/352). * FIX - PHP Warning: substr_compare() fixed. GitHub Issue [#350](https://github.com/wpCloud/wp-stateless/issues/350). * FIX - Filtering Domain setting before saving in order to get rid of possible empty spaces. GitHub Issue [#348](https://github.com/wpCloud/wp-stateless/issues/348). * FIX - Incorrect remote file path generated when disabled Organization setting. GitHub Issue [#343](https://github.com/wpCloud/wp-stateless/issues/343). * FIX - Hiding admin notices correctly. GitHub Pull Request [#355](https://github.com/wpCloud/wp-stateless/pull/355). = 2.2.2 = * FIX - Proper 'srcset' attribute handling. GitHub Issue [#342](https://github.com/wpCloud/wp-stateless/issues/342). * ENHANCEMENT - Minor fixes code quality. = 2.2.1 = * Fix - Security patch for Authenticated Remote Code Execution (RCE) vulnerability. = 2.2.0 = * FIX - Slow page generation when File URL Replacement is enabled. https://github.com/wpCloud/wp-stateless/issues/265 * FIX - Fatal error when WP Smush Pro compatibility is enabled. https://github.com/wpCloud/wp-stateless/issues/325 * FIX - Issue with Imagify. https://github.com/wpCloud/wp-stateless/issues/326 * FIX - Return correct srcset images. https://github.com/wpCloud/wp-stateless/issues/328 * FIX - Fatal error with GFForms. https://github.com/wpCloud/wp-stateless/issues/330 * FIX - Typo in admin notices. https://github.com/wpCloud/wp-stateless/issues/337 * ENHANCEMENT - Extended “File URL Replacement” options. https://github.com/wpCloud/wp-stateless/issues/336 * ENHANCEMENT - Service Account JSON is now hidden if set via constant. https://github.com/wpCloud/wp-stateless/issues/320 * ENHANCEMENT - New database table for tracking files not tracked in media library. https://github.com/wpCloud/wp-stateless/issues/307 * ENHANCEMENT - Updated depreciated function flagged by security software. https://github.com/wpCloud/wp-stateless/issues/300 = 2.1.9 = * FIX - Resolved fatal error with OneCodeShop RML Amazon S3 plugin. GitHub Issue [#317](https://github.com/wpCloud/wp-stateless/issues/317). * FIX - Resolved missing bucket in file URL when “storage.googleapis.com” was supplied in Domain field. GitHub Issue [318](https://github.com/wpCloud/wp-stateless/issues/318). * ENHANCEMENT - Support synchronization of files without metadata, such as .doc and .docx files. GitHub Issue [316](https://github.com/wpCloud/wp-stateless/issues/316). = 2.1.8 = * FIX - Woocommerce product export. * FIX - Allow webmaster to control http or https. * FIX - PDF preview sync. * ENHANCEMENT - Improved error message when there is nothing to sync. * ENHANCEMENT - Renamed constant WP_STATELESS_MEDIA_HASH_FILENAME to WP_STATELESS_MEDIA_CACHE_BUSTING. * ENHANCEMENT - Domain field functionality now allows webmaster to control http or https * ENHANCEMENT - Message about Stateless mode now requires the Cache-Busting option now see only those who using Stateless mode. * ENHANCEMENT - Upload full size image before generating thumbnails. * COMPATIBILITY - Added support for Learndash plugin. * COMPATIBILITY - Added support for BuddyPress plugin. * COMPATIBILITY - Added support for Divi builder export. * COMPATIBILITY - Added support for Elementor plugin. = 2.1.7 = * ENHANCEMENT - Display dashboard-wide notice for existing users explaining stateless mode now enables cache-busting option. * ENHANCEMENT - Display notice when selecting stateless mode explaining stateless mode now enables cache-busting option. * ENHANCEMENT - Display required message on cache-busting setting description when stateless mode is enabled. = 2.1.6 = * FIX - Resolved Google SDK conflict. * FIX - ICompatibility.php errors notice. * FIX - Undefined index: gs_link in class-bootstrap.php. * FIX - Media files with accent characters would not upload correctly to the bucket. * ENHANCEMENT - Force `Cache-Busting` when using `Stateless` mode. * ENHANCEMENT - New admin notice design. * ENHANCEMENT - Improved and clear error message. * ENHANCEMENT - Renamed constant `WP_STATELESS_MEDIA_ON_FLY` to `WP_STATELESS_DYNAMIC_IMAGE_SUPPORT`. * ENHANCEMENT - Update Google Libraries. * ENHANCEMENT - Renamed constant `WP_STATELESS_MEDIA_HASH_FILENAME` to `WP_STATELESS_MEDIA_CACHE_BUSTING`. * COMPATIBILITY - Renamed constant `WP_STATELESS_COMPATIBILITY_WPSmush` to `WP_STATELESS_COMPATIBILITY_WPSMUSH`. * COMPATIBILITY - Added support for `WooCommerce Extra Product Options`. * COMPATIBILITY - Added support for `WPForms Pro`. * COMPATIBILITY - Improved `ShortPixel` compatibility. * COMPATIBILITY - Fixed `ACF Image Crop` compatibility. = 2.1.5 = * FIX - Fatal error with PHP 5.4.45 on activation. * FIX - E_WARNING: Illegal string offset ‘gs_bucket’. * FIX - Resolved ‘save_network_settings’ message when saving network settings. * COMPATIBILITY - Added support for WP Forms plugin * COMPATIBILITY - Added support for WP Smush plugin * COMPATIBILITY - Added support for ShortPixel Image Optimizer plugin. * COMPATIBILITY - Added support for Imagify Image Optimizer plugin. * COMPATIBILITY - Added support for SiteOrigin CSS plugin. * COMPATIBILITY - Added support for Gravity Forms plugin. * COMPATIBILITY - Added support for WPBakery Page Builder plugin. * COMPATIBILITY - Added wp-config constant support for compatibility options. = 2.1.4 = * ENHANCEMENT - Updated Google OAuth URL for Setup Assistant. = 2.1.3 = * ENHANCEMENT - Updates to text explainers in Setup Assistant. * ENHANCEMENT - Refined redirection logic when activating plugin. * FIX - Removed extra space in converted URLs. = 2.1.2 = * ENHANCEMENT - Improved support for Easy Digital Downloads. * ENHANCEMENT - Added constant WP_STATELESS_CONSOLE_LOG check before logging to console. * ENHANCEMENT - Changed service account default permissions on creation. * COMPATIBILITY - Added support for SiteOrigin generated CSS files. * ENHANCEMENT - Moved Dynamic Image Support to Capability tab. * COMPATIBILITY - Added support for ACF Image Crop addon. * FIX - Fixed compatibility issue with wp-smush plugin. * FIX - Added required blog param for multi-sites. * FIX - Updated media library and mediaItem API endpoints. * COMPATIBILITY - Added support for EDD download method option. = 2.1.1 = * FIX - Fixed double slash when Organization is disabled. * FIX - Fatal error with GuzzleHttp. * FIX - Fixed content-type assignment. * ENHANCEMENT - Added support for https URLs in Domain field. * COMPATIBILITY - Advanced Custom Fields Image Crop Addon. = 2.1.0 = * FIX - Fixed read only for Service Account JSON if constant or environment variable is defined. * FIX - Override default cache control. * FIX - Fixed custom domain bucket support with setup assistant. * FIX - Improved support for wp_calculate_image_srcset. * FIX - Synchronizing non-image files will now delete the local copy. * NEW - Support for GOOGLE_APPLICATION_CREDENTIALS environment variable. * NEW - Added bucket region option to setup assistant. * NEW - Added custom file type support for File URL Replacement setting. * NEW - Added failover to image url when not found on disk for sync tool. * ENHANCEMENT - updated service account role to Storage Object Admin. = 2.0.3 = * FIX - Fixed Fatal Error which was occurring on WordPress Multisite after upgrading plugin from 1.x to 2.x. * ENHANCEMENT - Improved support of PDF files. = 2.0.2 = * FIX - Fixed Fatal Error which were caused by using PHP 5.4 and less. * FIX - Fixed Fatal Error which was caused on Media page when WP Smush Pro plugin is activated. * FIX - Fixed detection of plugin files paths. The issue was occurring on installations with custom file structures ( e.g. Bedrock platform ). * FIX - Fixed redirection URL to Setup Wizard on plugin activation. * ENHANCEMENT - Updated the minimum requirements for PHP to 5.5 to prevent fatal errors and possible warnings. = 2.0.1 = * ENHANCEMENT - Added compatibility with Google SDK v1.x version to prevent conflicts with third-party plugins. * ENHANCEMENT - Added warning message if old Google SDK version is loaded by third-party plugin. = 2.0.0 = * NEW - Added stateless mode. * NEW - Dedicated settings panel. * NEW - Setup assistant for initial plugin activation. * NEW - Support for replacing default GCS domain with custom domain. * ENHANCEMENT - Expanded network setting overrides. * ENHANCEMENT - Expanded wp-config constants. * ENHANCEMENT - Relocated synchronization and regeneration tools to new settings panel. = 1.9.2 = * ENHANCEMENT - Added ability to modify default bucket link via 'wp_stateless_bucket_link' filter. * ENHANCEMENT - Added checking of connection to GCS once per four hours instead of doing it on every page load. * ENHANCEMENT - Google SDK was moved from vendor dir. So it's not loaded on every page load anymore, but only when it's required. * ENHANCEMENT - Updated Composer Autoload logic. * ENHANCEMENT - Reverted all changes included to 1.9.1 version because of conflicts. = 1.9.0 = * NEW - Added new ability to define cacheControl for remote objects. * NEW - Added new option that adds random hashes to file names. = 1.8.0 = * FIX - Fixed the issue on multisite setup (switch_to_blog now works as expected). * FIX - Performance fixes. * NEW - Added the ability to regenerate and synchronize separate Media file from the list. * NEW - Added the ability to regenerate and synchronize Media file from edit screen. * ENHANCEMENT - UI cleanup. = 1.7.3 = * Initial public release. ================================================ FILE: changes.md ================================================ #### 4.4.1 - 2026-01-16 * COMPATIBILITY - WooCommerce Extra Product Options Compatibility replaced with [WP-Stateless – WooCommerce Extra Product Options Addon](https://wordpress.org/plugins/wp-stateless-woocommerce-extra-product-options-addon/). * FIX - resolve critical errors with `firebase/php-jwt` library if `AUTH_SALT` WordPress constant is not set or too short. #### 4.4.0 - 2026-01-10 * NEW - plugin requires PHP 8.1+. * ENHANCEMENT - updated `firebase/php-jwt` library from 6.11.1 to 7.0.2. * ENHANCEMENT - Updated Client library for Google APIs from 2.18.3 to 2.19.0. * ENHANCEMENT - updated `wpmetabox/meta-box` library from 5.10.15 to 5.10.19. * ENHANCEMENT - updated `Meta Box Tabs` library from 1.1.18 to 1.2.0. * FIX - `udx/lib-wp-bootstrap` package correctly loads text domain to prevent PHP notices. #### 4.3.0 * ENHANCEMENT - update dependencies for Google APIs Client Library. * COMPATIBILITY - Simple Local Avatars Compatibility replaced with [WP-Stateless - Simple Local Avatars Addon](https://wordpress.org/plugins/wp-stateless-simple-local-avatars-addon/). #### 4.2.1 * ENHANCEMENT - updated `wpmetabox/meta-box` library from 5.10.11 to 5.10.15. * FIX - correctly loads text domain to prevent PHP notices. * FIX - `udx/lib-ud-api-client` package correctly loads text domain to prevent PHP notices. #### 4.2.0 * ENHANCEMENT - Updated Client library for Google APIs from 2.18.2 to 2.18.3. * ENHANCEMENT - updated `firebase/php-jwt` library from 6.10.2 to 6.11.1. * ENHANCEMENT - updated `wpmetabox/meta-box` library from 5.10.1 to 5.10.11. * DEPRECATED - Setup Assistant removed. #### 4.1.3 * COMPATIBILITY - PolyLang Compatibility replaced with [WP-Stateless – Polylang Pro Addon](https://wordpress.org/plugins/wp-stateless-polylang-pro-addon/). * ENHANCEMENT - updated `wpmetabox/meta-box` library from from 5.10.1 to 5.10.7. * ENHANCEMENT - updated `Meta Box Tabs` library from 1.1.18 to 1.2.0. * ENHANCEMENT - updated `firebase/php-jwt` library from from 6.10.1 to 6.10.2. * ENHANCEMENT - Updated Client library for Google APIs from 2.17.0 to 2.18.2. * FIX - apply `Cache Control` setting to all files (previously applied only to images). #### 4.1.2 * ENHANCEMENT - added `REST API Endpoint` setting, which useful when WordPress dashboard and frontend website utilize different domain names. * ENHANCEMENT - extended `Status Info` with the information to help diagnose REST API or AJAX issues. * COMPATIBILITY - SiteOrigin Widgets Bundle Compatibility replaced with [WP-Stateless - SiteOrigin Widgets Bundle Addon](https://wordpress.org/plugins/wp-stateless-siteorigin-widgets-bundle-addon/). * COMPATIBILITY - WPForms Compatibility replaced with [WP-Stateless - WPForms Addon](https://wordpress.org/plugins/wp-stateless-wpforms-addon/). * COMPATIBILITY - Easy Digital Downloads Compatibility replaced with [WP-Stateless - Easy Digital Downloads Addon](https://wordpress.org/plugins/wp-stateless-easy-digital-downloads-addon/). * COMPATIBILITY - LiteSpeed Cache Compatibility replaced with [WP-Stateless - LiteSpeed Cache Addon](https://wordpress.org/plugins/wp-stateless-litespeed-cache-addon/). * COMPATIBILITY - BuddyPress Compatibility replaced with [WP-Stateless - BuddyPress Addon](https://wordpress.org/plugin/wp-stateless-buddypress-addon/). * FIX: PHP warning on `Status` settings tab. * FIX: database updates to resolve conflicts with Polylang Pro compatibility. #### 4.1.1 * FIX - cache issues during Data Optimization. #### 4.1.0 * NEW - move compatibilities files from `wp_sm_sync` to `wp_stateless_files` table with extended information. * COMPATIBILITY - WooCommerce Compatibility replaced with [WP-Stateless – WooCommerce Addon](https://wordpress.org/plugins/wp-stateless-woocommerce-addon/). * COMPATIBILITY - Gravity Forms Compatibility replaced with [WP-Stateless – Gravity Forms Addon](https://wordpress.org/plugins/wp-stateless-gravity-forms-addon/). * COMPATIBILITY - Gravity Forms Signature Compatibility replaced with [WP-Stateless – Gravity Forms Signature Addon](https://wordpress.org/plugins/wp-stateless-gravity-forms-signature-addon/). * COMPATIBILITY - Divi Theme Compatibility replaced with [WP-Stateless – Divi Theme Addon](https://wordpress.org/plugins/wp-stateless-divi-theme-addon/). * COMPATIBILITY - SiteOrigin CSS Compatibility replaced with [WP-Stateless – SiteOrigin CSS Addon](https://wordpress.org/plugins/wp-stateless-siteorigin-css-addon/). * ENHANCEMENT - CLI command `wp stateless migrate` supports `auto` parameter to run all required Data Optimizations automatically. * ENHANCEMENT - Updated Client library for Google APIs from 2.15.1 to 2.17.0. * ENHANCEMENT - updated `firebase/php-jwt` library from from 6.9.0 to 6.10.1. * ENHANCEMENT - updated `wpmetabox/meta-box` library from from 5.8.2 to 5.10.1. * ENHANCEMENT - updated `deliciousbrains/wp-background-processing` library from from 1.1.1 to 1.3.1. * ENHANCEMENT - updated `composer/installers` library from from 1.12.1 to 2.3.0. * ENHANCEMENT - updated `Meta Box Tabs` library from 1.1.17 to 1.1.18. * ENHANCEMENT - action `sm:sync::addFile` format changed, now it passes media object instead of file name. * ENHANCEMENT - for installed Addons replace Download action with Activate. * ENHANCEMENT - count compatibility files from the DB instead of listing actual files to increase performance. * FIX - CLI command `wp stateless migrate` supports `--yes` parameter to skip confirmation. * FIX - CLI command `wp stateless migrate` correctly works with `--progress` parameter in multisite. * FIX - fixed synchronization for Compatibility files in Stateless Mode. * FIX - CLI command `wp stateless upgrade` fixed when running with `--b` switch. * FIX - fixed SiteOrigin Widgets Bundle Compatibility in `Stateless` mode. * FIX - fixed WPForms Compatibility in `Stateless` mode. * FIX - limit index size for compatibility with different DB engines [757](https://github.com/udx/wp-stateless/issues/757). * FIX - correctly disable `Cache-Busting` setting for Ephemeral Mode [758](https://github.com/udx/wp-stateless/issues/758), credits [@Jessedev1](https://github.com/Jessedev1). * FIX - Data Optimization UI adjustments. #### 4.0.4 * ENHANCEMENT - display success message after copying Status Info. * FIX - `Settings` page does not open or slow when there is big amount of attachments. * FIX - in multisite network, removing custom tables properly when deleting site. * FIX - skip setting ACL in Stateless mode and during Sync for the buckets with Uniform access, support WP_STATELESS_SKIP_ACL_SET constant [#712](https://github.com/udx/wp-stateless/issues/712). #### 4.0.3 * NEW - added `Info` section to the `Status` tab on the Settings page, which contains the system info and the ability to copy report to clipboard. * ENHANCEMENT - added `Documentation` link on the Plugins page. * ENHANCEMENT - added `Addons` link on the Plugins page. * ENHANCEMENT - added `Documentation` link on the Settings page. * FIX - fixed `Settings` shortcut on the Plugins page. * FIX - in multisite network, do not show Data Optimization on the Network Admin Page. * FIX - properly set `Content Disposition` fields for media objects. * FIX - properly use `Cache Control` setting for media objects. * FIX - fixed `Creation of dynamic property` PHP deprecation notice. * FIX - fixed `Cannot use ::class with dynamic class name` PHP warning. * FIX - avoid PHP warning when unable to get file path in `Stateless` mode [728](https://github.com/udx/wp-stateless/issues/728). * FIX - fixed links to the constants documentation. #### 4.0.2 * FIX - in multisite network, deleting site can potentially remove WP-Stateless tables from another site. * COMPATIBILITY - Gravity Forms Compatibility updated for the newest Gravity Forms version. #### 4.0.1 * FIX - improvements to Data Optimization process. * FIX - Data Optimization fixed for multisite environment. #### 4.0.0 * NEW - use custom database tables to store GCS file data. This increases plugin performance and will be used for future improvements. * NEW - added filter `wp_stateless_get_file`, retrieves the GCS file data, should be used instead of getting `sm_cloud` postmeta directly. * NEW - added filter `wp_stateless_get_file_sizes`, retrieves the GCS file data for image sizes, should be used instead of getting `sm_cloud` postmeta directly. * NEW - added filter `wp_stateless_get_file_meta`, retrieves all GCS file meta data, should be used instead of getting `sm_cloud` postmeta directly. * NEW - added filter `wp_stateless_get_file_meta_value`, retrieves the GCS file meta data by meta_key, should be used instead of getting `sm_cloud` postmeta directly. * NEW - added filter `wp_stateless_get_setting_...` which allows to override any WP-Stateless setting. * NEW - added setting "Send Status Emails" allowing to change email for WP-Stateless notifications. * NEW - added setting "Use Post Meta" allowing to switch back to using `postmeta` instead of custom DB tables. Can be used in case of issues after upgrading to 4.0.0. * NEW - added new Settings tab `Addons`, which contains the list of WP-Stateless Addons, which replace Compatibilities. * NEW - added new Settings tab `Status`, which contains status and health information related to Google Cloud Storage and WP-Stateless. * NEW - CLI command `wp stateless migrate` to list and operate data optimizations. * NEW - configuration constant [`WP_STATELESS_POSTMETA`](https://stateless.udx.io/docs/constants/#wp_stateless_postmeta) allows to read the GCS file data from postmeta instead of the new custom database tables. * NEW - configuration constant [`WP_STATELESS_BATCH_HEALTHCHECK_INTERVAL`](https://stateless.udx.io/docs/constants/#wp_stateless_batch_healthcheck_interval) defines an interval in minutes for periodical health checks of a batch background process (like data optimization). * COMPATIBILITY - BuddyBoss Compatibility replaced with [WP-Stateless – BuddyBoss Platform Addon](https://wordpress.org/plugins/wp-stateless-buddyboss-platform-addon/). * COMPATIBILITY - Elementor Compatibility replaced with [WP-Stateless – Elementor Website Builder Addon](https://wordpress.org/plugins/wp-stateless-elementor-website-builder-addon/). * COMPATIBILITY - Gravity Form Compatibility does not support older version of Gravity Forms (< 2.3). * ENHANCEMENT - Allow dismissing notices in Admin Panel only for logged in users. * ENHANCEMENT - Updated `wp-background-processing` library from from 1.0.2 to 1.1.1. * ENHANCEMENT - Updated `phpseclib` 3.0.34 to 3.0.37. * FIX - proper use of infinite timeout in `set_time_limit` function to avoid issues with PHP 8.1 and above [#704](https://github.com/udx/wp-stateless/issues/704). #### 3.4.1 * FIX - improve security while processing AJAX requests in Admin Panel #### 3.4.0 * ENHANCEMENT - removed `udx/lib-settings` package dependency for security reasons. * ENHANCEMENT - removed `udx/lib-utility` package dependency for security reasons. * ENHANCEMENT - refactored `Settings` admin page to remove Angular dependency. * ENHANCEMENT - including Software Bill of Materials (SBOM) to GitHub release. * FIX - updated package dependencies for Google Client Library for security reasons. * FIX - replaced `utf8_encode` with `mb_convert_encoding` to support PHP 8.2 and above [#678](https://github.com/udx/wp-stateless/issues/678). * FIX - Fatal Error in `Stateless` mode if GCP access credentials are wrong [#693](https://github.com/udx/wp-stateless/issues/693). * COMPATIBILITY - preventing PHP warnings while working with WooCommerce version 8.4.0 and above [696](https://github.com/udx/wp-stateless/issues/696). * COMPATIBILITY - avoiding conflicts between builtin compatibilities and WP-Stateless Addon plugins. #### 3.3.0 * NEW - Added new filter `wp_stateless_attachment_url`. Allows to customize attachment URL after WP-Stateless generates it based on it's internal conditions. * FIX - Stateless mode Incompatible with Media Uploader in Media Library Grid mode [#675](https://github.com/udx/wp-stateless/issues/675). * FIX - Prevent duplicating messages in Admin Panel. * COMPATIBILITY - Dynamic Image Support is now part of the core. * COMPATIBILITY - Google App Engine is now part of the core. Automatically enables **Stateless** mode when Google App Engine detected. Can be disabled using `WP_STATELESS_COMPATIBILITY_GAE` constant. * COMPATIBILITY - Removed compatibility with "Advanced Custom Fields: Image Crop Add-on", because plugin is deprecated. * COMPATIBILITY - Removed compatibility with "VidoRev" plugin. * COMPATIBILITY - Removed compatibility with "WP Retina 2x" plugin. * ENHANCEMENT - Updated Client library for Google APIs from 2.15.0 to 2.15.1. * ENHANCEMENT - Updated Meta Box library from 5.6.3 to 5.8.2. * ENHANCEMENT - Updated Meta Box Tabs to version 1.1.17. * ENHANCEMENT - Updated PHP JWT library from 6.6.0 to 6.9.0. #### 3.2.5 * FIX - Folder setting does not allow custom structure [#608](https://github.com/udx/wp-stateless/issues/608). * FIX - Stateless mode Incompatible with Inline Uploader [#675](https://github.com/udx/wp-stateless/issues/675). * FIX - html tags incorrectly applied in notice [#680](https://github.com/udx/wp-stateless/issues/680). * ENHANCEMENT - Add WP_STATELESS_SKIP_ACL_SET for skip ACL set for GCS [#625](https://github.com/udx/wp-stateless/issues/625). * COMPATIBILITY - Add support for The Events Calendar [#599](https://github.com/udx/wp-stateless/issues/599). #### 3.2.4 - FIX - Website unresponsive after Upgrade [#669](https://github.com/udx/wp-stateless/issues/669). #### 3.2.3 - ENHANCEMENT - Updated Client library for Google APIs. - ENHANCEMENT - Updated Monolog library to version 3. - ENHANCEMENT - Updated JWT library. - FIX - Fixed vulnerability issues. - FIX - Fixed an errors and warnings on PHP 8.1. - FIX - Fixed an error that occured when WP_STATELESS_MEDIA_UPLOAD_CHUNK_SIZE is set. #### 3.2.2 - FIX - Folder setting can't be saved from the settings page [#639](https://github.com/udx/wp-stateless/issues/639). #### 3.2.1 - FIX - Updated requirments. - FIX - WP-Stateless 3.2.0 doesn’t upload docs, only images [#638](https://github.com/udx/wp-stateless/issues/638). #### 3.2.0 - ENHANCEMENT - Upgraded `wpmetabox` library. - ENHANCEMENT - Updated Client library for Google APIs. - ENHANCEMENT - Updated Guzzle library to version 7. - ENHANCEMENT - Updated JWT library. - ENHANCEMENT - Updated `license` functionality, removed `update checker`. - FIX - Fixed vulnerability issues. - FIX - Fixed erros and warnings on PHP 8. - FIX - problem after the upgrade [#628](https://github.com/udx/wp-stateless/issues/628). - FIX - image_downsize() PHP8 Required parameter $id follows optional parameter $false [#619](https://github.com/udx/wp-stateless/issues/619). #### 3.1.1 - ENHANCEMENT - Notification for the administrator about finished synchronization. GitHub issue [#576](https://github.com/udx/wp-stateless/issues/576). - FIX - Fixed an issue with PDF thumbnails. GitHub issue [#577](https://github.com/udx/wp-stateless/issues/577). - FIX - Fixed an issue with synchronization in `Stateless` mode. GitHub issue [#575](https://github.com/udx/wp-stateless/issues/575). - COMPATIBILITY - Changed the way compatibility files are stored on Multisite. GitHub issue [#588](https://github.com/udx/wp-stateless/issues/588). #### 3.1.0 - NEW - Completely rewritten the synchronization tool. GitHub issue [#523](https://github.com/udx/wp-stateless/issues/523). - NEW - New configuration constant `WP_STATELESS_SYNC_MAX_BATCH_SIZE`. Sets the maximum size of a background sync batch of items to be saved in a single row in the database. [More details](https://stateless.udx.io/docs/constants/#wp_stateless_sync_max_batch_size). - NEW - New configuration constant `WP_STATELESS_SYNC_LOG`. Sets a path to a log file where to output logging information during the background sync. [More details](https://stateless.udx.io/docs/constants/#wp_stateless_sync_log). - NEW - New configuration constant `WP_STATELESS_SYNC_HEALTHCHECK_INTERVAL`. Defines an interval in minutes for a cron task that periodically checks the health of a particular background sync process. [More details](https://stateless.udx.io/docs/constants/#wp_stateless_sync_healthcheck_interval). - FIX - Fixed an issue when original files were not deleted from the server in the Ephemeral mode. GitHub issue [#484](https://github.com/udx/wp-stateless/issues/484). - FIX - Fixed an incorrect behavior of image `srcset` attribute in the Backup mode. GitHub issue [#558](https://github.com/udx/wp-stateless/issues/558). - COMPATIBILITY - Litespeed Cache - Fixed an incorrect upload folder determination. GitHub issue [#527](https://github.com/udx/wp-stateless/issues/527). #### 3.0.4 - FIX - Fixed inability to use dashes in the upload folder name. GitHub issue [#565](https://github.com/udx/wp-stateless/issues/565). - COMPATIBILITY - Elementor - Fixed wrong upload directory. GitHub issue [#560](https://github.com/udx/wp-stateless/issues/560). #### 3.0.3 - FIX - Fixed an incorrect file URL in Stateless mode on Edit Media screen. GitHub issue [#544](https://github.com/udx/wp-stateless/issues/544). #### 3.0.2 - FIX - Refactored the way files are being uploaded to GCS when `WP_STATELESS_MEDIA_UPLOAD_CHUNK_SIZE` constant is defined. GitHub issue [#553](https://github.com/udx/wp-stateless/issues/553). - FIX - Fixed the process of upgrading to 3.0 for multisite installations. GitHub issue [#549](https://github.com/udx/wp-stateless/issues/549). #### 3.0.1 - FIX - Fatal Error in Stateless mode. GitHub issue [#546](https://github.com/udx/wp-stateless/issues/546). #### 3.0 - NEW - Setup assistant rewrite. GitHub issue [#477](https://github.com/udx/wp-stateless/issues/477). - NEW - Recreate attachment metabox panel using metabox.io. GitHub issue [#470](https://github.com/udx/wp-stateless/issues/470). - NEW - Updated the `Stateless` mode to not use local storage at all. Current `Stateless` mode setting mapped to new `Ephemeral` mode. GitHub issue [#482](https://github.com/udx/wp-stateless/issues/482). - NEW - Files are now uploaded to GCS in chunks and chunk size will be determined based on free memory available. GitHub issue [#478](https://github.com/udx/wp-stateless/issues/478). - NEW - File upload chunk size can be controlled with `WP_STATELESS_MEDIA_UPLOAD_CHUNK_SIZE` constant. GitHub issue [#478](https://github.com/udx/wp-stateless/issues/478). - FIX - Changed the default value for the Cache-Busting setting. GitHub issue [#361](https://github.com/udx/wp-stateless/issues/361). - FIX - Fixed network override of Cache-Busting. GitHub issue [#468](https://github.com/udx/wp-stateless/issues/468). - FIX - Fixed "Passing glue string after array is deprecated.". GitHub issue [#444](https://github.com/udx/wp-stateless/issues/444). - FIX - Fixed Compatibility default value in multisite. GitHub issue [#464](https://github.com/udx/wp-stateless/issues/464). - FIX - Fixed multisite wrong GCS path. GitHub issue [#407](https://github.com/udx/wp-stateless/issues/407). - FIX - Don't check for Google Cloud Storage connectivity in stateless mode unless uploading. GitHub issue [#442](https://github.com/udx/wp-stateless/issues/442). - COMPATIBILITY - Google App Engine - Added new compatibility support for Google App Engine. [#486](https://github.com/udx/wp-stateless/issues/486) - COMPATIBILITY - Elementor - Fixed wrong MIME type for CSS files. GitHub issue [#395](https://github.com/udx/wp-stateless/issues/395). - COMPATIBILITY - Polylang - Fixed missing metadata issue. GitHub issue [#378](https://github.com/udx/wp-stateless/issues/378). - COMPATIBILITY - EWWW - Fixed mime type for WEBP images. GitHub issue [#371](https://github.com/udx/wp-stateless/issues/371). - COMPATIBILITY - Simple Local Avatars - Added new compatibility support for Simple Local Avatars. GitHub issue [#297](https://github.com/udx/wp-stateless/issues/297). - COMPATIBILITY - BuddyPress - Fixed BuddyPress compatibility. GitHub issue [#275](https://github.com/udx/wp-stateless/issues/275). - COMPATIBILITY - Divi - Fixed Divi cache issue. GitHub issue [#430](https://github.com/udx/wp-stateless/issues/430). - COMPATIBILITY - Gravity Forms - add compatibility for Gravity Forms Signature Add-On. [#501](https://github.com/udx/wp-stateless/issues/501). - COMPATIBILITY - Litespeed - Fixed fatal error and warnings. [#491](https://github.com/udx/wp-stateless/issues/491). - COMPATIBILITY - Imagify - Added support for webp. [#403](https://github.com/udx/wp-stateless/issues/403). - ENHANCEMENT - Update Client library for Google APIs. [#446](https://github.com/udx/wp-stateless/issues/446). - ENHANCEMENT - Wildcards for bucket folder settings. GitHub issue [#149](https://github.com/udx/wp-stateless/issues/149). - ENHANCEMENT - Better CLI integration. GitHub issue [#447](https://github.com/udx/wp-stateless/issues/447), [#450](https://github.com/udx/wp-stateless/issues/450) and [#451](https://github.com/udx/wp-stateless/issues/451). - ENHANCEMENT - Sync media according to new Bucket Folder settings. GitHub issue [#449](https://github.com/udx/wp-stateless/issues/449). - ENHANCEMENT - Moved Bucket Folder setting in the File URL section. GitHub issue [#463](https://github.com/udx/wp-stateless/issues/463). - ENHANCEMENT - Hide Regenerate and Sync with GCS when the mode is Disabled. GitHub issue [#440](https://github.com/udx/wp-stateless/issues/440). - ENHANCEMENT - New endpoint for the Google Cloud Storage JSON API. GitHub issue [#384](https://github.com/udx/wp-stateless/issues/384). - ENHANCEMENT - Renamed current `Stateless` mode to `Ephemeral`. GitHub issue [#481](https://github.com/udx/wp-stateless/issues/481). #### 2.3.2 - FIX - Fixed video file doesn't get deleted from the server in `Stateless` mode. GitHub issue [#418](https://github.com/wpCloud/wp-stateless/issues/418). - FIX - Fixed file size doesn't show under attachment details in `Stateless` mode. GitHub issue [#413](https://github.com/wpCloud/wp-stateless/issues/413). - FIX - Fixed Cache-Busting feature works even if the Mode is `Disabled`. GitHub issue [#405](https://github.com/wpCloud/wp-stateless/issues/405). - COMPATIBILITY - Fixed Gravity Form Post Image didn't include `Bucket Folder`. GitHub issue [#421](https://github.com/wpCloud/wp-stateless/issues/421). - COMPATIBILITY - Fixed Divi Builder Export. GitHub issue [#420](https://github.com/wpCloud/wp-stateless/issues/420). - COMPATIBILITY - Fixed BuddyBoss pages breaking after updating to 2.3.0. GitHub issue [#417](https://github.com/wpCloud/wp-stateless/issues/417). #### 2.3.1 - Fix - Fixed fatal error, undefined function `is_wp_version_compatible`. GitHub issue [#414](https://github.com/wpCloud/wp-stateless/issues/414). #### 2.3.0 - FIX - Fixed problem with WordPress 5.3. GitHub issue [#406](https://github.com/wpCloud/wp-stateless/issues/406). - FIX - Fixed problem with the Cache Busting feature. GitHub issue [#377](https://github.com/wpCloud/wp-stateless/issues/377). - COMPATIBILITY - Added compatibility support for WP Retina 2x pro. GitHub issue [#380](https://github.com/wpCloud/wp-stateless/issues/380). - COMPATIBILITY - Enhanced compatibility support for LiteSpeed Cache. GitHub issue [#365](https://github.com/wpCloud/wp-stateless/issues/365). - COMPATIBILITY - Enhanced compatibility support for ShortPixel Image Optimizer. GitHub issue [#364](https://github.com/wpCloud/wp-stateless/issues/364), [#398](https://github.com/wpCloud/wp-stateless/issues/398). - COMPATIBILITY - Fixed Gravity Form export. GitHub issue [#408](https://github.com/wpCloud/wp-stateless/issues/408). - ENHANCEMENT - Improved upon add_media function for better compatibility support. GitHub issue [#382](https://github.com/wpCloud/wp-stateless/issues/382). #### 2.2.7 - FIX - WP-Smush compatibility enhanced. GitHub Issue [#366](https://github.com/wpCloud/wp-stateless/issues/366). - FIX - Fixed multisite installation support. GitHub Issue [#370](https://github.com/wpCloud/wp-stateless/issues/370). - FIX - Fixed settings UI problems related to Cache-Busting option. GitHub Issue [#373](https://github.com/wpCloud/wp-stateless/issues/373). - FIX - Other minor fixes. #### 2.2.6 - FIX - Multisite Network Settings page fixed. GitHub Issue [#369](https://github.com/wpCloud/wp-stateless/issues/369). - FIX - Fixed incorrect Compatibilities behavior when Bucket Folder is set. GitHub Issue [#368](https://github.com/wpCloud/wp-stateless/issues/368). - FIX - Other minor fixes. #### 2.2.5 - NEW - Added ability to start sync process from specific Attachment ID. GitHub Issue [#360](https://github.com/wpCloud/wp-stateless/issues/360). - COMPATIBILITY - Added compatibility support for LiteSpeed Cache plugin. Especially to support optimized .webp images. GitHub Issue [#357](https://github.com/wpCloud/wp-stateless/issues/357). - FIX - Other minor fixes. #### 2.2.4 - NEW - Added new filter `wp_stateless_skip_add_media`. Allows skipping synchronization of the media object with GCS depending on custom condition. GitHub Issue [#344](https://github.com/wpCloud/wp-stateless/issues/344). - FIX - Compatibility Manager is considering Child Themes now. GitHub Issue [#351](https://github.com/wpCloud/wp-stateless/issues/351). - FIX - Custom domains handling has been fixed. GitHub Issue [#358](https://github.com/wpCloud/wp-stateless/issues/358). - ENHANCEMENT - Imagify Image Optimizer and WP Smush compatibilities improved. GitHub Issue [#359](https://github.com/wpCloud/wp-stateless/issues/359). #### 2.2.3 - FIX - `get_post_metadata` does not break multi-dimensional arrays anymore. GitHub Issue [#352](https://github.com/wpCloud/wp-stateless/issues/352). - FIX - `PHP Warning: substr_compare()` fixed. GitHub Issue [#350](https://github.com/wpCloud/wp-stateless/issues/350). - FIX - Filtering Domain setting before saving in order to get rid of possible empty spaces. GitHub Issue [#348](https://github.com/wpCloud/wp-stateless/issues/348). - FIX - Incorrect remote file path generated when disabled Organization setting. GitHub Issue [#343](https://github.com/wpCloud/wp-stateless/issues/343). - FIX - Hiding admin notices correctly. GitHub Pull Request [#355](https://github.com/wpCloud/wp-stateless/pull/355). #### 2.2.2 - FIX - Proper 'srcset' attribute handling. GitHub Issue [#342](https://github.com/wpCloud/wp-stateless/issues/342). - ENHANCEMENT - Minor fixes code quality. #### 2.2.1 - Fix - Security patch for Authenticated Remote Code Execution (RCE) vulnerability. #### 2.2.0 - FIX - Slow page generation when File URL Replacement is enabled [#265](https://github.com/wpCloud/wp-stateless/issues/265). - FIX - Fatal error when WP Smush Pro compatibility is enabled [#325](https://github.com/wpCloud/wp-stateless/issues/325). - FIX - Issue with Imagify [#326](https://github.com/wpCloud/wp-stateless/issues/326). - FIX - Return correct srcset images [#328](https://github.com/wpCloud/wp-stateless/issues/328). - FIX - Fatal error with GFForms [#330](https://github.com/wpCloud/wp-stateless/issues/330). - FIX - Typo in admin notices [#337](https://github.com/wpCloud/wp-stateless/issues/337). - ENHANCEMENT - Extended “File URL Replacement” options [#336](https://github.com/wpCloud/wp-stateless/issues/336). - ENHANCEMENT - Service Account JSON is now hidden if set via constant [#320](https://github.com/wpCloud/wp-stateless/issues/320). - ENHANCEMENT - New database table for tracking files not tracked in media library [#307](https://github.com/wpCloud/wp-stateless/issues/307). - ENHANCEMENT - Updated depreciated function flagged by security software [#300](https://github.com/wpCloud/wp-stateless/issues/300). #### 2.1.9 - FIX - Resolved fatal error with OneCodeShop RML Amazon S3 plugin. GitHub Issue [#317](https://github.com/wpCloud/wp-stateless/issues/317). - FIX - Resolved missing bucket in file URL when “storage.googleapis.com” was supplied in Domain field. GitHub Issue [#318](https://github.com/wpCloud/wp-stateless/issues/318). - ENHANCEMENT - Support synchronization of files without metadata, such as .doc and .docx files. GitHub Issue [#316](https://github.com/wpCloud/wp-stateless/issues/316). #### 2.1.8 - FIX - WooCommerce product export. - FIX - PDF previews in media library now supported. - ENHANCEMENT - Improved error message when there is nothing to sync. - ENHANCEMENT - Renamed constant WP_STATELESS_MEDIA_HASH_FILENAME to WP_STATELESS_MEDIA_CACHE_BUSTING. - ENHANCEMENT - Domain field functionality now allows webmaster to control http or https - ENHANCEMENT - Notice about Stateless mode requiring the Cache-Busting option is displayed to those using Stateless mode. - ENHANCEMENT - Upload full size image before generating thumbnails. - COMPATIBILITY - Added compatibility support for Learndash plugin. - COMPATIBILITY - Added compatibility support for BuddyPress plugin. - COMPATIBILITY - Added compatibility support for Divi Builder export. - COMPATIBILITY - Added compatibility support for Elementor plugin. #### 2.1.7 - ENHANCEMENT - Display dashboard-wide notice for existing users explaining stateless mode now enables cache-busting option. - ENHANCEMENT - Display notice when selecting stateless mode explaining stateless mode now enables cache-busting option. - ENHANCEMENT - Display required message on cache-busting setting description when stateless mode is enabled. #### 2.1.6 - FIX - Resolved Google SDK conflict. - FIX - ICompatibility.php errors notice. - FIX - Undefined index: gs_link in class-bootstrap.php. - FIX - Media files with accent characters would not upload correctly to the bucket. - ENHANCEMENT - Force `Cache-Busting` when using `Stateless` mode. - ENHANCEMENT - New admin notice design. - ENHANCEMENT - Improved and clear error message. - ENHANCEMENT - Renamed constant `WP_STATELESS_MEDIA_ON_FLY` to `WP_STATELESS_DYNAMIC_IMAGE_SUPPORT`. - ENHANCEMENT - Update Google Libraries. - ENHANCEMENT - Renamed constant `WP_STATELESS_MEDIA_HASH_FILENAME` to `WP_STATELESS_MEDIA_CACHE_BUSTING`. - COMPATIBILITY - Renamed constant `WP_STATELESS_COMPATIBILITY_WPSmush` to `WP_STATELESS_COMPATIBILITY_WPSMUSH`. - COMPATIBILITY - Added support for `WooCommerce Extra Product Options`. - COMPATIBILITY - Added support for `WPForms Pro`. - COMPATIBILITY - Improved `ShortPixel` compatibility. - COMPATIBILITY - Fixed `ACF Image Crop` compatibility. #### 2.1.5 - FIX - Fatal error with PHP 5.4.45 on activation. - FIX - E_WARNING: Illegal string offset ‘gs_bucket’. - FIX - Resolved ‘save_network_settings’ message when saving network settings. - COMPATIBILITY - Added support for WP Forms plugin - COMPATIBILITY - Added support for WP Smush plugin - COMPATIBILITY - Added support for ShortPixel Image Optimizer plugin. - COMPATIBILITY - Added support for Imagify Image Optimizer plugin. - COMPATIBILITY - Added support for SiteOrigin CSS plugin. - COMPATIBILITY - Added support for Gravity Forms plugin. - COMPATIBILITY - Added support for WPBakery Page Builder plugin. - COMPATIBILITY - Added wp-config constant support for compatibility options. #### 2.1.4 - ENHANCEMENT - Updated Google OAuth URL for Setup Assistant. #### 2.1.3 - ENHANCEMENT - Updates to text explainers in Setup Assistant. - ENHANCEMENT - Refined redirection logic when activating plugin. - FIX - Removed extra space in converted URLs. #### 2.1.2 - ENHANCEMENT - Improved support for Easy Digital Downloads. - ENHANCEMENT - Added constant WP_STATELESS_CONSOLE_LOG check before logging to console. - ENHANCEMENT - Changed service account default permissions on creation. - COMPATIBILITY - Added support for SiteOrigin generated CSS files. - ENHANCEMENT - Moved Dynamic Image Support to Capability tab. - COMPATIBILITY - Added support for ACF Image Crop addon. - FIX - Fixed compatibility issue with wp-smush plugin. - FIX - Added required blog param for multi-sites. - FIX - Updated media library and mediaItem API endpoints. - COMPATIBILITY - Added support for EDD download method option. #### 2.1.1 - FIX - Fixed double slash when Organization is disabled. - FIX - Fatal error with GuzzleHttp. - FIX - Fixed content-type assignment. - ENHANCEMENT - Added support for https URLs in Domain field. - COMPATIBILITY - Advanced Custom Fields Image Crop Addon. #### 2.1.0 - FIX - Fixed read only for Service Account JSON if constant or environment variable is defined. - FIX - Override default cache control. - FIX - Fixed custom domain bucket support with setup assistant. - FIX - Improved support for wp_calculate_image_srcset. - FIX - Synchronizing non-image files will now delete the local copy. - NEW - Support for GOOGLE_APPLICATION_CREDENTIALS environment variable. - NEW - Added bucket region option to setup assistant. - NEW - Added custom file type support for File URL Replacement setting. - NEW - Added failover to image url when not found on disk for sync tool. - ENHANCEMENT - updated service account role to Storage Object Admin. #### 2.0.3 - FIX - Fixed Fatal Error which was occurring on WordPress Multisite after upgrading plugin from 1.x to 2.x. - ENHANCEMENT - Improved support of PDF files. #### 2.0.2 - FIX - Fixed Fatal Errors which were caused by using PHP 5.4 and less. - FIX - Fixed Fatal Error which was caused on Media page when WP Smush Pro plugin is activated. - FIX - Fixed detection of plugin files paths. The issue was occurring on installations with custom file structures ( e.g. Bedrock platform ). - FIX - Fixed redirection URL to Setup Wizard on plugin activation. - ENHANCEMENT - Updated the minimum requirements for PHP to 5.5 to prevent fatal errors and possible warnings. #### 2.0.1 - ENHANCEMENT - Added compatibility with Google SDK v1.x version to prevent conflicts with third-party plugins. - ENHANCEMENT - Added warning message if old Google SDK version is loaded by third-party plugin. #### 2.0.0 - NEW - Added stateless mode. - NEW - Dedicated settings panel. - NEW - Setup assistant for initial plugin activation. - NEW - Support for replacing default GCS domain with a custom domain. - ENHANCEMENT - Expanded network setting overrides. - ENHANCEMENT - Expanded wp-config constants. - ENHANCEMENT - Relocated synchronization and regeneration tools to the new settings panel. #### 1.9.2 - ENHANCEMENT - Added ability to modify default bucket link via 'wp_stateless_bucket_link' filter. - ENHANCEMENT - Added checking of connection to GCS once per four hours instead of doing it on every page load. - ENHANCEMENT - Google SDK was moved from vendor dir. So it's not loaded on every page load anymore, but only when it's required. - ENHANCEMENT - Updated Composer Autoload logic. - ENHANCEMENT - Reverted all changes included to 1.9.1 version because of conflicts. #### 1.9.0 - Added new ability to define cacheControl for remote objects. - Added new option that adds random hashes to file names. #### 1.8.0 - Added the ability to regenerate and synchronize separate Media file from the list. - Added the ability to regenerate and synchronize Media file from edit screen. - Fixed the issue on multisite setup (switch_to_blog now works as expected). - Performance fixes. - UI cleanup. #### 1.7.3 - Added ability to fix previously failed items. #### 1.7.1 - Migrated from p12 to JSON. - New feature of media sync. - New option Root Directory. - Optimized uploading process. - Other options. #### 1.7.0 - Fixed conflict with SSL forcing plugin. #### 1.6.0 - Plugin Updates ability added. - WordPress 4.4 compatibility fixed. - Post content filter fixed. #### 1.5.0 - Migration into wp-stateless from wp-stateless-media. - Version bump to resolve bucket permissions issues. #### 1.3.2 - Fixed issue with wp_normalize_path causing a fatal error on older installs. - Removed \$\_SESSION usage for transients. #### 1.3.1 - Added ability to upload non-images to bucket. - Fixed issue with running batches in WP CLI #### 1.3.0 - Added WP CLI functionality. - Added WP CLI command to move all legacy meta data to serialized array. - Changed the way of storing SM cloud meta data. #### 1.2.0 - Added Imagemagic/GD check to warn admin that thumbnails will not be generated. - Added mediaLink, mediaLink and id storage for uploaded objects. - Added support for cacheControl with default settings based on Mime type of upload. - Added sm:item:cacheControl and sm:item:contentDisposition filters. - Cleaned-up metadata that is made available to GCS and visible in response headers. - Removed app_name, using blog domain name automatically. - Added Cache Control to media editor. #### 1.1.0 - Added support for WP_STATELESS_MEDIA_MODE. - Renamed constants STATELESS_MEDIA_SERVICE_ACCOUNT_NAME and STATELESS_MEDIA_KEY_FILE_PATH to WP_STATELESS_MEDIA_SERVICE_ACCOUNT and WP_STATELESS_MEDIA_KEY_FILE_PATH. #### 1.0.2 - Added a _view_ link to media edit page for synchronized items. - Added some _wp_get_attachment_image_ dynamic attributes. #### 1.0.1 - Added Network Management option. - Added support for WP_STATELESS_MEDIA_SERVICE_ACCOUNT_NAME and WP_STATELESS_MEDIA_KEY_FILE_PATH. #### 1.0.0 - Set branch to v1.0. - Removed autocompletion from Email Address and Application Name fields. - Moved lib/classes into just lib. - Rename class-Bootstrap.php to be lowercased. - Added composer/installers to composer.json 'required' dependencies. - Rename stateless-media.php to wp-stateless-media.php so there aren't unexpected plugin basename issues. - Change package name to wp-stateless-media in package.json - Rename 'wpCloud/wp-stateless-media' to 'wpcloud/wp-stateless-media' in composer.json, Composer does not allow uppercase names. #### 0.2.1 - Added 'Settings' link to plugin list. ================================================ FILE: composer.json ================================================ { "name": "wpcloud/wp-stateless", "description": "WP-Stateless WordPress plugin", "type": "wordpress-plugin", "minimum-stability": "stable", "homepage": "https://udx.io", "authors": [ { "name": "UDX", "homepage": "https://udx.io" } ], "repositories": [ { "type": "composer", "url": "https://repository.usabilitydynamics.com" }, { "type": "git", "url": "https://github.com/wpCloud/wp-stateless.git" }, { "type":"composer", "url":"https://wpackagist.org", "only": [ "wpackagist-plugin/*", "wpackagist-theme/*" ] } ], "require": { "php": ">=7.4", "composer/installers": "~2.3", "ccampbell/chromephp": "^4.1", "firebase/php-jwt": "^6.1.2", "udx/lib-ud-api-client": "^1.2", "udx/lib-wp-bootstrap": "^1.3", "wpackagist-plugin/meta-box": "^5.10" }, "autoload": { "classmap": [ "lib/classes", "lib/includes" ] }, "archive": { "exclude": [ "node_modules", ".gitignore", "test", "circle.yml", "composer.lock", "gruntfile.js", "package.json" ] }, "extra": { "mozart": { "dep_namespace": "wpCloud\\StatelessMedia\\", "dep_directory": "/lib/ns-vendor/deps", "classmap_directory": "/lib/ns-vendor/classes", "classmap_prefix": "UDX_", "packages": [ "deliciousbrains/wp-background-processing" ] }, "featureFlags": [ { "name": "Google Login", "constant": "WP_STATELESS_GOOGLE_LOGIN", "description": "Allows for quicker setup by letting admin login to their Google Account from the control panel. Fetches available projects and buckets.", "since": "1.9.2", "enabled": true }, { "name": "Legacy Settings", "constant": "WP_STATELESS_LEGACY_SETTINGS", "description": "Shows legacy settings options.", "since": "1.9.2", "enabled": false } ], "schemas": { "dependencies": { "modules": {}, "plugins": [] }, "licenses": { "client": { "slug": "wpcloud/wp-stateless", "screen": { "parent": "upload.php?page=stateless-settings", "hide_menu": true } }, "product": false } }, "installer-paths": { "vendor/wpmetabox/meta-box": ["wpackagist-plugin/meta-box"] } }, "require-dev": { "coenjacobs/mozart": "0.7.1", "deliciousbrains/wp-background-processing": "1.3.1" }, "config": { "allow-plugins": { "composer/installers": true } } } ================================================ FILE: l10n.php ================================================ __( "Something went wrong", ud_get_stateless_media()->domain ), 'invalid_input' => __( "Form has invalid input. Please fix them.", ud_get_stateless_media()->domain ), 'json_api_enabled' => __( "Google Cloud Storage JSON API Service Enabled", ud_get_stateless_media()->domain ), 'json_api_enabled_failed' => __( "Google Cloud Storage JSON API Service failed.", ud_get_stateless_media()->domain ), 'project_cant_be_empty' => __( "Project name can't be empty.", ud_get_stateless_media()->domain ), 'project_length_notice' => __( "Project name must be between 5 and 30 characters.", ud_get_stateless_media()->domain ), 'project_invalid_char' => __( "Project name has invalid characters. Enter letters, numbers, quotes, hyphens, spaces or exclamation points.", ud_get_stateless_media()->domain ), 'project_creation_started' => __( "Project creation started.", ud_get_stateless_media()->domain ), 'project_exists' => __( "Project Exists", ud_get_stateless_media()->domain ), 'project_creation_complete' => __( "Project creation complete.", ud_get_stateless_media()->domain ), 'project_creation_failed' => __( "Project creation failed.", ud_get_stateless_media()->domain ), 'bucket_cant_be_empty' => __( "Bucket name can't be empty.", ud_get_stateless_media()->domain ), 'bucket_length_notice' => __( "Bucket name must be between 5 and 30 characters.", ud_get_stateless_media()->domain ), 'bucket_invalid_char' => __( "A bucket name can contain lowercase alphanumeric characters, hyphens, and underscores. Bucket names must start and end with an alphanumeric character.", ud_get_stateless_media()->domain ), 'bucket_created' => __( "Bucket Created", ud_get_stateless_media()->domain ), 'bucket_creation_failed' => __( "Bucket creation failed", ud_get_stateless_media()->domain ), 'bucket_exists' => __( "Bucket Exist", ud_get_stateless_media()->domain ), 'bucket_access_controls_success' => __( "Bucket access control inserted.", ud_get_stateless_media()->domain ), 'bucket_access_controls_failed' => __( "Bucket access control failed.", ud_get_stateless_media()->domain ), 'select_billing_account' => __( "Select a billing account.", ud_get_stateless_media()->domain ), 'billing_enabled' => __( "Billing Enabled", ud_get_stateless_media()->domain ), 'billing_already_enabled' => __( "Billing already enabled.", ud_get_stateless_media()->domain ), 'billing_failed' => __( "Field to enable billing.", ud_get_stateless_media()->domain ), 'billing_info' => __( "Billing Info", ud_get_stateless_media()->domain ), 'service_account_exist' => __( "Service Account Exists", ud_get_stateless_media()->domain ), 'service_account_created' => __( "Service Account Created", ud_get_stateless_media()->domain ), 'service_account_creation_failed' => __( "Service Account creation failed", ud_get_stateless_media()->domain ), 'service_account_key_created' => __( "Service Account Key Created", ud_get_stateless_media()->domain ), 'service_account_key_creation_failed' => __( "Service Account Key creation failed", ud_get_stateless_media()->domain ), 'service_account_key_saved' => __( "Service Account Key Saved", ud_get_stateless_media()->domain ), 'service_account_key_save_failed' => __( "Failed to Save Service Account Key", ud_get_stateless_media()->domain ), 'service_account_role_granted' => __( "Service Account Role Granted", ud_get_stateless_media()->domain ), 'service_account_role_grant_failed' => __( "Service Account Role Grant Failed", ud_get_stateless_media()->domain ), 'unable_to_connect_to_the_server' => __( "Unable to connect to the server", ud_get_stateless_media()->domain ), 'could_not_retrieve_progress' => __( "Could not retrieve progress", ud_get_stateless_media()->domain ), 'could_not_get_fails' => __( "Could not get fails", ud_get_stateless_media()->domain ), 'could_not_reset_progress' => __( "Could not reset progress", ud_get_stateless_media()->domain ), 'loading_images_media_objects' => __( "Loading Images Media Objects...", ud_get_stateless_media()->domain ), 'stopping' => __( "Stopping...", ud_get_stateless_media()->domain ), 'finished' => __( "Finished", ud_get_stateless_media()->domain ), 'cancelled' => __( "Cancelled", ud_get_stateless_media()->domain ), 'ids_are_malformed' => __( "IDs are malformed", ud_get_stateless_media()->domain ), 'unable_to_get_images_media_id' => __( "Unable to get Images Media ID", ud_get_stateless_media()->domain ), 'wp_stateless_get_images_media_id' => __( "WP-Stateless get Images Media ID", ud_get_stateless_media()->domain ), 'request_failed' => __( "Request failed", ud_get_stateless_media()->domain ), 'get_images_media_id' => __( "Get Images Media ID", ud_get_stateless_media()->domain ), 'loading_non_image_media_objects' => __( "Loading non-image Media Objects...", ud_get_stateless_media()->domain ), 'unable_to_get_non_images_media_id' => __('Unable to get non Images Media ID', ud_get_stateless_media()->domain ), 'non_libraries_files_are_not_found' => __('There are no files to process.', ud_get_stateless_media()->domain ), 'get_non_library_files_request_failed' => __('Get non library files: Request failed', ud_get_stateless_media()->domain ), 'regenerate_single_image_failed' => __('Regenerate single image: Failed', ud_get_stateless_media()->domain ), 'sync_single_file_failed' => __('Sync single file: Failed', ud_get_stateless_media()->domain ), 'sync_single_file_request_failed' => __('Sync single file: Request failed', ud_get_stateless_media()->domain ), 'failed_to_sync' => __('Failed to sync ', ud_get_stateless_media()->domain ), 'sync_non_library_file_failed' => __('Sync non library file: Failed', ud_get_stateless_media()->domain ), 'sync_non_library_file_request_failed' => __('Sync non library file: Request failed', ud_get_stateless_media()->domain ), 'response_code' => __('Response code: ', ud_get_stateless_media()->domain ), 'loading_non_library_objects' => __('Loading non library Objects...', ud_get_stateless_media()->domain ), 'processing_files' => __('Processing files (', ud_get_stateless_media()->domain ), '_total___' => __(' total)...', ud_get_stateless_media()->domain ), 'processing_images' => __('Processing images (', ud_get_stateless_media()->domain ), 'get_non_images_media_id_request_failed' => __('Get non Images Media ID: Request failed', ud_get_stateless_media()->domain ), 'regenerate_single_image_request_failed' => __('Regenerate single image: Request failed', ud_get_stateless_media()->domain ), 'confirm' => __('Confirm', ud_get_stateless_media()->domain ), 'cancel' => __('Cancel', ud_get_stateless_media()->domain ), 'start_optimization' => __('Start Data Optimization', ud_get_stateless_media()->domain ), 'starting' => __('Starting...', ud_get_stateless_media()->domain ), ); ================================================ FILE: lib/Google/CHANGELOG.md ================================================ # Changelog ## [2.19.0](https://github.com/googleapis/google-api-php-client/compare/v2.18.4...v2.19.0) (2026-01-09) ### Features * Support firebase/php-jwt version 6.0 and 7.0 ([#2696](https://github.com/googleapis/google-api-php-client/issues/2696)) ([70ea42a](https://github.com/googleapis/google-api-php-client/commit/70ea42a6aa29a1321825c3dcda39cf39174390ea)) ### Bug Fixes * Upload assets release job ([#2671](https://github.com/googleapis/google-api-php-client/issues/2671)) ([0f56ea7](https://github.com/googleapis/google-api-php-client/commit/0f56ea773cb51cc6131c442d112d7fd630b49b5c)) ## [2.18.4](https://github.com/googleapis/google-api-php-client/compare/v2.18.3...v2.18.4) (2025-09-29) ### Bug Fixes * Ensure credentials can be of type FetchAuthTokenInterface ([#2684](https://github.com/googleapis/google-api-php-client/issues/2684)) ([ed70802](https://github.com/googleapis/google-api-php-client/commit/ed70802cc4886ef1f513a2c0b56a8a972db5e7ab)) ## [2.18.3](https://github.com/googleapis/google-api-php-client/compare/v2.18.2...v2.18.3) (2025-04-08) ### Bug Fixes * Convert Finder lazy iterator to array before deletion ([#2663](https://github.com/googleapis/google-api-php-client/issues/2663)) ([c699405](https://github.com/googleapis/google-api-php-client/commit/c6994051af1568359c97d267d9ef34ccbda31387)) ## [2.18.2](https://github.com/googleapis/google-api-php-client/compare/v2.18.1...v2.18.2) (2024-12-16) ### Bug Fixes * Correct type for jwt constructor arg ([#2648](https://github.com/googleapis/google-api-php-client/issues/2648)) ([31a9861](https://github.com/googleapis/google-api-php-client/commit/31a9861af02a8e9070b395f05caed7ffce0ef8be)) ## [2.18.1](https://github.com/googleapis/google-api-php-client/compare/v2.18.0...v2.18.1) (2024-11-24) ### Bug Fixes * Implicitly marking parameter as nullable is deprecated ([#2638](https://github.com/googleapis/google-api-php-client/issues/2638)) ([de57db2](https://github.com/googleapis/google-api-php-client/commit/de57db2fdc0d56de1abbf778b28b77c3347eb3fd)) ## [2.18.0](https://github.com/googleapis/google-api-php-client/compare/v2.17.0...v2.18.0) (2024-10-16) ### Features * **docs:** Use doctum shared workflow for reference docs ([#2618](https://github.com/googleapis/google-api-php-client/issues/2618)) ([242e2cb](https://github.com/googleapis/google-api-php-client/commit/242e2cb09ad5b25b047a862b4d521037e74cae29)) ### Bug Fixes * Explicit token caching issue ([#2358](https://github.com/googleapis/google-api-php-client/issues/2358)) ([dc13e5e](https://github.com/googleapis/google-api-php-client/commit/dc13e5e3f517148d3c66d151a5ab133b7840d8fb)) ## [2.17.0](https://github.com/googleapis/google-api-php-client/compare/v2.16.0...v2.17.0) (2024-07-10) ### Features * Add logger to client constructor config ([#2606](https://github.com/googleapis/google-api-php-client/issues/2606)) ([1f47133](https://github.com/googleapis/google-api-php-client/commit/1f4713329d71111a317cda8ef8603fa1bdc88858)) * Add the protected apiVersion property ([#2588](https://github.com/googleapis/google-api-php-client/issues/2588)) ([7e79f3d](https://github.com/googleapis/google-api-php-client/commit/7e79f3d7be4811f760e19cc4a2c558e04196ec1d)) ## [2.16.0](https://github.com/googleapis/google-api-php-client/compare/v2.15.4...v2.16.0) (2024-04-24) ### Features * Add universe domain support ([#2563](https://github.com/googleapis/google-api-php-client/issues/2563)) ([35895de](https://github.com/googleapis/google-api-php-client/commit/35895ded90b507074b3430a94a5790ddd01f39f0)) ## [2.15.4](https://github.com/googleapis/google-api-php-client/compare/v2.15.3...v2.15.4) (2024-03-06) ### Bug Fixes * Updates phpseclib because of a security issue ([#2574](https://github.com/googleapis/google-api-php-client/issues/2574)) ([633d41f](https://github.com/googleapis/google-api-php-client/commit/633d41f1b65fdb71a83bf747f7a3ad9857f6d02a)) ## [2.15.3](https://github.com/googleapis/google-api-php-client/compare/v2.15.2...v2.15.3) (2024-01-04) ### Bug Fixes * Guzzle dependency version ([#2546](https://github.com/googleapis/google-api-php-client/issues/2546)) ([c270f28](https://github.com/googleapis/google-api-php-client/commit/c270f28b00594a151a887edd3cfd205594a1256a)) ## [2.15.2](https://github.com/googleapis/google-api-php-client/compare/v2.15.1...v2.15.2) (2024-01-03) ### Bug Fixes * Disallow vulnerable guzzle versions ([#2536](https://github.com/googleapis/google-api-php-client/issues/2536)) ([d1830ed](https://github.com/googleapis/google-api-php-client/commit/d1830ede17114a4951ab9e60b3b9bcd9393b8668)) * Php 8.3 deprecated get_class method call without argument ([#2509](https://github.com/googleapis/google-api-php-client/issues/2509)) ([8c66021](https://github.com/googleapis/google-api-php-client/commit/8c6602119b631e1a9da4dbe219af18d51c8dab8e)) * Phpseclib security vulnerability ([#2524](https://github.com/googleapis/google-api-php-client/issues/2524)) ([73705c2](https://github.com/googleapis/google-api-php-client/commit/73705c2a65bfc01fa6d7717b7f401b8288fe0587)) ## [2.15.1](https://github.com/googleapis/google-api-php-client/compare/v2.15.0...v2.15.1) (2023-09-12) ### Bug Fixes * Upgrade min phpseclib version ([#2499](https://github.com/googleapis/google-api-php-client/issues/2499)) ([8e7fae2](https://github.com/googleapis/google-api-php-client/commit/8e7fae2b79cfc1b72026347abf6314d91442a018)) ## [2.15.0](https://github.com/googleapis/google-api-php-client/compare/v2.14.0...v2.15.0) (2023-05-18) ### Features * Add pkce support and upgrade examples ([#2438](https://github.com/googleapis/google-api-php-client/issues/2438)) ([bded223](https://github.com/googleapis/google-api-php-client/commit/bded223ece445a6130cde82417b20180b1d6698a)) * Drop support for 7.3 and below ([#2431](https://github.com/googleapis/google-api-php-client/issues/2431)) ([c765b37](https://github.com/googleapis/google-api-php-client/commit/c765b379e95ab272b6a87aa802d9f5507eaeb2e7)) ## [2.14.0](https://github.com/googleapis/google-api-php-client/compare/v2.13.2...v2.14.0) (2023-05-11) ### Features * User-supplied query params for auth url ([#2432](https://github.com/googleapis/google-api-php-client/issues/2432)) ([74a7d7b](https://github.com/googleapis/google-api-php-client/commit/74a7d7b838acb08afc02b449f338fbe6577cb03c)) ## [2.13.2](https://github.com/googleapis/google-api-php-client/compare/v2.13.1...v2.13.2) (2023-03-23) ### Bug Fixes * Calling class_exists with null in Google\Model ([#2405](https://github.com/googleapis/google-api-php-client/issues/2405)) ([5ed4edc](https://github.com/googleapis/google-api-php-client/commit/5ed4edc9315110a715e9763d27ee6761e1aaa00a)) ## [2.13.1](https://github.com/googleapis/google-api-php-client/compare/v2.13.0...v2.13.1) (2023-03-13) ### Bug Fixes * Allow dynamic properties on model classes ([#2408](https://github.com/googleapis/google-api-php-client/issues/2408)) ([11080d5](https://github.com/googleapis/google-api-php-client/commit/11080d5e85a040751a13aca8131f93c7d910db11)) ## [2.13.0](https://github.com/googleapis/google-api-php-client/compare/v2.12.6...v2.13.0) (2022-12-19) ### Features * Make auth http client config extends from default client config ([#2348](https://github.com/googleapis/google-api-php-client/issues/2348)) ([2640250](https://github.com/googleapis/google-api-php-client/commit/2640250c7bab479f378972733dcc0a3e9b2e14f8)) ### Bug Fixes * Don't send content-type header if no post body exists ([#2288](https://github.com/googleapis/google-api-php-client/issues/2288)) ([654c0e2](https://github.com/googleapis/google-api-php-client/commit/654c0e29ab78aba8bfef52fd3d06a3b2b39c4e0d)) * Ensure new redirect_uri propogates to OAuth2 class ([#2282](https://github.com/googleapis/google-api-php-client/issues/2282)) ([a69131b](https://github.com/googleapis/google-api-php-client/commit/a69131b6488735d112a529a278cfc8b875e18647)) * Lint errors ([#2315](https://github.com/googleapis/google-api-php-client/issues/2315)) ([88cc63c](https://github.com/googleapis/google-api-php-client/commit/88cc63c38b0cf88629f66fdf8ba6006f6c6d5a2c)) * Update accounts.google.com authorization URI ([#2275](https://github.com/googleapis/google-api-php-client/issues/2275)) ([b2624d2](https://github.com/googleapis/google-api-php-client/commit/b2624d21fce894126b9975a872cf5cda8038b254)) ================================================ FILE: lib/Google/CODE_OF_CONDUCT.md ================================================ # Contributor Code of Conduct As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities. We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality. Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery * Personal attacks * Trolling or insulting/derogatory comments * Public or private harassment * Publishing other's private information, such as physical or electronic addresses, without explicit permission * Other unethical or unprofessional conduct. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team. This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers. This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0, available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/) ================================================ FILE: lib/Google/LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: lib/Google/README.md ================================================ ![](https://github.com/googleapis/google-api-php-client/workflows/.github/workflows/tests.yml/badge.svg) # Google APIs Client Library for PHP # **NOTE**: please check to see if the package you'd like to install is available in our list of [Google cloud packages](https://cloud.google.com/php/docs/reference) first, as these are the recommended libraries.
Reference Docs
https://googleapis.github.io/google-api-php-client/
License
Apache 2.0
The Google API Client Library enables you to work with Google APIs such as Gmail, Drive or YouTube on your server. These client libraries are officially supported by Google. However, the libraries are considered complete and are in maintenance mode. This means that we will address critical bugs and security issues but will not add any new features. ## Google Cloud Platform For Google Cloud Platform APIs such as [Datastore][cloud-datastore], [Cloud Storage][cloud-storage], [Pub/Sub][cloud-pubsub], and [Compute Engine][cloud-compute], we recommend using the Google Cloud client libraries. For a complete list of supported Google Cloud client libraries, see [googleapis/google-cloud-php](https://github.com/googleapis/google-cloud-php). [cloud-datastore]: https://github.com/googleapis/google-cloud-php-datastore [cloud-pubsub]: https://github.com/googleapis/google-cloud-php-pubsub [cloud-storage]: https://github.com/googleapis/google-cloud-php-storage [cloud-compute]: https://github.com/googleapis/google-cloud-php-compute ## Requirements ## * [PHP 8.0 or higher](https://www.php.net/) ## Developer Documentation ## The [docs folder](docs/) provides detailed guides for using this library. ## Installation ## You can use **Composer** or simply **Download the Release** ### Composer The preferred method is via [composer](https://getcomposer.org/). Follow the [installation instructions](https://getcomposer.org/doc/00-intro.md) if you do not already have composer installed. Once composer is installed, execute the following command in your project root to install this library: ```sh composer require google/apiclient ``` If you're facing a timeout error then either increase the timeout for composer by adding the env flag as `COMPOSER_PROCESS_TIMEOUT=600 composer install` or you can put this in the `config` section of the composer schema: ``` { "config": { "process-timeout": 600 } } ``` Finally, be sure to include the autoloader: ```php require_once '/path/to/your-project/vendor/autoload.php'; ``` This library relies on `google/apiclient-services`. That library provides up-to-date API wrappers for a large number of Google APIs. In order that users may make use of the latest API clients, this library does not pin to a specific version of `google/apiclient-services`. **In order to prevent the accidental installation of API wrappers with breaking changes**, it is highly recommended that you pin to the [latest version](https://github.com/googleapis/google-api-php-client-services/releases) yourself prior to using this library in production. #### Cleaning up unused services There are over 200 Google API services. The chances are good that you will not want them all. In order to avoid shipping these dependencies with your code, you can run the `Google\Task\Composer::cleanup` task and specify the services you want to keep in `composer.json`: ```json { "require": { "google/apiclient": "^2.15.0" }, "scripts": { "pre-autoload-dump": "Google\\Task\\Composer::cleanup" }, "extra": { "google/apiclient-services": [ "Drive", "YouTube" ] } } ``` This example will remove all services other than "Drive" and "YouTube" when `composer update` or a fresh `composer install` is run. **IMPORTANT**: If you add any services back in `composer.json`, you will need to remove the `vendor/google/apiclient-services` directory explicitly for the change you made to have effect: ```sh rm -r vendor/google/apiclient-services composer update ``` **NOTE**: This command performs an exact match on the service name, so to keep `YouTubeReporting` and `YouTubeAnalytics` as well, you'd need to add each of them explicitly: ```json { "extra": { "google/apiclient-services": [ "Drive", "YouTube", "YouTubeAnalytics", "YouTubeReporting" ] } } ``` ### Download the Release If you prefer not to use composer, you can download the package in its entirety. The [Releases](https://github.com/googleapis/google-api-php-client/releases) page lists all stable versions. Download any file with the name `google-api-php-client-[RELEASE_NAME].zip` for a package including this library and its dependencies. Uncompress the zip file you download, and include the autoloader in your project: ```php require_once '/path/to/google-api-php-client/vendor/autoload.php'; ``` For additional installation and setup instructions, see [the documentation](docs/). ## Examples ## See the [`examples/`](examples) directory for examples of the key client features. You can view them in your browser by running the php built-in web server. ``` $ php -S localhost:8000 -t examples/ ``` And then browsing to the host and port you specified (in the above example, `http://localhost:8000`). ### Basic Example ### ```php // include your composer dependencies require_once 'vendor/autoload.php'; $client = new Google\Client(); $client->setApplicationName("Client_Library_Examples"); $client->setDeveloperKey("YOUR_APP_KEY"); $service = new Google\Service\Books($client); $query = 'Henry David Thoreau'; $optParams = [ 'filter' => 'free-ebooks', ]; $results = $service->volumes->listVolumes($query, $optParams); foreach ($results->getItems() as $item) { echo $item['volumeInfo']['title'], "
\n"; } ``` ### Authentication with OAuth ### > An example of this can be seen in [`examples/simple-file-upload.php`](examples/simple-file-upload.php). 1. Follow the instructions to [Create Web Application Credentials](docs/oauth-web.md#create-authorization-credentials) 1. Download the JSON credentials 1. Set the path to these credentials using `Google\Client::setAuthConfig`: ```php $client = new Google\Client(); $client->setAuthConfig('/path/to/client_credentials.json'); ``` 1. Set the scopes required for the API you are going to call ```php $client->addScope(Google\Service\Drive::DRIVE); ``` 1. Set your application's redirect URI ```php // Your redirect URI can be any registered URI, but in this example // we redirect back to this same page $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']; $client->setRedirectUri($redirect_uri); ``` 1. In the script handling the redirect URI, exchange the authorization code for an access token: ```php if (isset($_GET['code'])) { $token = $client->fetchAccessTokenWithAuthCode($_GET['code']); } ``` ### Authentication with Service Accounts ### > An example of this can be seen in [`examples/service-account.php`](examples/service-account.php). Some APIs (such as the [YouTube Data API](https://developers.google.com/youtube/v3/)) do not support service accounts. Check with the specific API documentation if API calls return unexpected 401 or 403 errors. 1. Follow the instructions to [Create a Service Account](docs/oauth-server.md#creating-a-service-account) 1. Download the JSON credentials 1. Set the path to these credentials using the `GOOGLE_APPLICATION_CREDENTIALS` environment variable: ```php putenv('GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json'); ``` 1. Tell the Google client to use your service account credentials to authenticate: ```php $client = new Google\Client(); $client->useApplicationDefaultCredentials(); ``` 1. Set the scopes required for the API you are going to call ```php $client->addScope(Google\Service\Drive::DRIVE); ``` 1. If you have delegated domain-wide access to the service account and you want to impersonate a user account, specify the email address of the user account using the method setSubject: ```php $client->setSubject($user_to_impersonate); ``` #### How to use a specific JSON key If you want to a specific JSON key instead of using `GOOGLE_APPLICATION_CREDENTIALS` environment variable, you can do this: ```php $jsonKey = [ 'type' => 'service_account', // ... ]; $client = new Google\Client(); $client->setAuthConfig($jsonKey); ``` ### Making Requests ### The classes used to call the API in [google-api-php-client-services](https://github.com/googleapis/google-api-php-client-services) are autogenerated. They map directly to the JSON requests and responses found in the [APIs Explorer](https://developers.google.com/apis-explorer/#p/). A JSON request to the [Datastore API](https://developers.google.com/apis-explorer/#p/datastore/v1beta3/datastore.projects.runQuery) would look like this: ``` POST https://datastore.googleapis.com/v1beta3/projects/YOUR_PROJECT_ID:runQuery?key=YOUR_API_KEY ``` ```json { "query": { "kind": [{ "name": "Book" }], "order": [{ "property": { "name": "title" }, "direction": "descending" }], "limit": 10 } } ``` Using this library, the same call would look something like this: ```php // create the datastore service class $datastore = new Google\Service\Datastore($client); // build the query - this maps directly to the JSON $query = new Google\Service\Datastore\Query([ 'kind' => [ [ 'name' => 'Book', ], ], 'order' => [ 'property' => [ 'name' => 'title', ], 'direction' => 'descending', ], 'limit' => 10, ]); // build the request and response $request = new Google\Service\Datastore\RunQueryRequest(['query' => $query]); $response = $datastore->projects->runQuery('YOUR_DATASET_ID', $request); ``` However, as each property of the JSON API has a corresponding generated class, the above code could also be written like this: ```php // create the datastore service class $datastore = new Google\Service\Datastore($client); // build the query $request = new Google\Service\Datastore_RunQueryRequest(); $query = new Google\Service\Datastore\Query(); // - set the order $order = new Google\Service\Datastore_PropertyOrder(); $order->setDirection('descending'); $property = new Google\Service\Datastore\PropertyReference(); $property->setName('title'); $order->setProperty($property); $query->setOrder([$order]); // - set the kinds $kind = new Google\Service\Datastore\KindExpression(); $kind->setName('Book'); $query->setKinds([$kind]); // - set the limit $query->setLimit(10); // add the query to the request and make the request $request->setQuery($query); $response = $datastore->projects->runQuery('YOUR_DATASET_ID', $request); ``` The method used is a matter of preference, but *it will be very difficult to use this library without first understanding the JSON syntax for the API*, so it is recommended to look at the [APIs Explorer](https://developers.google.com/apis-explorer/#p/) before using any of the services here. ### Making HTTP Requests Directly ### If Google Authentication is desired for external applications, or a Google API is not available yet in this library, HTTP requests can be made directly. If you are installing this client only to authenticate your own HTTP client requests, you should use [`google/auth`](https://github.com/googleapis/google-auth-library-php#call-the-apis) instead. The `authorize` method returns an authorized [Guzzle Client](http://docs.guzzlephp.org/), so any request made using the client will contain the corresponding authorization. ```php // create the Google client $client = new Google\Client(); /** * Set your method for authentication. Depending on the API, This could be * directly with an access token, API key, or (recommended) using * Application Default Credentials. */ $client->useApplicationDefaultCredentials(); $client->addScope(Google\Service\Plus::PLUS_ME); // returns a Guzzle HTTP Client $httpClient = $client->authorize(); // make an HTTP request $response = $httpClient->get('https://www.googleapis.com/plus/v1/people/me'); ``` ### Caching ### It is recommended to use another caching library to improve performance. This can be done by passing a [PSR-6](https://www.php-fig.org/psr/psr-6/) compatible library to the client: ```php use League\Flysystem\Adapter\Local; use League\Flysystem\Filesystem; use Cache\Adapter\Filesystem\FilesystemCachePool; $filesystemAdapter = new Local(__DIR__.'/'); $filesystem = new Filesystem($filesystemAdapter); $cache = new FilesystemCachePool($filesystem); $client->setCache($cache); ``` In this example we use [PHP Cache](http://www.php-cache.com/). Add this to your project with composer: ``` composer require cache/filesystem-adapter ``` ### Updating Tokens ### When using [Refresh Tokens](https://developers.google.com/identity/protocols/OAuth2InstalledApp#offline) or [Service Account Credentials](https://developers.google.com/identity/protocols/OAuth2ServiceAccount#overview), it may be useful to perform some action when a new access token is granted. To do this, pass a callable to the `setTokenCallback` method on the client: ```php $logger = new Monolog\Logger(); $tokenCallback = function ($cacheKey, $accessToken) use ($logger) { $logger->debug(sprintf('new access token received at cache key %s', $cacheKey)); }; $client->setTokenCallback($tokenCallback); ``` ### Debugging Your HTTP Request using Charles ### It is often very useful to debug your API calls by viewing the raw HTTP request. This library supports the use of [Charles Web Proxy](https://www.charlesproxy.com/documentation/getting-started/). Download and run Charles, and then capture all HTTP traffic through Charles with the following code: ```php // FOR DEBUGGING ONLY $httpClient = new GuzzleHttp\Client([ 'proxy' => 'localhost:8888', // by default, Charles runs on localhost port 8888 'verify' => false, // otherwise HTTPS requests will fail. ]); $client = new Google\Client(); $client->setHttpClient($httpClient); ``` Now all calls made by this library will appear in the Charles UI. One additional step is required in Charles to view SSL requests. Go to **Charles > Proxy > SSL Proxying Settings** and add the domain you'd like captured. In the case of the Google APIs, this is usually `*.googleapis.com`. ### Controlling HTTP Client Configuration Directly Google API Client uses [Guzzle](http://docs.guzzlephp.org/) as its default HTTP client. That means that you can control your HTTP requests in the same manner you would for any application using Guzzle. Let's say, for instance, we wished to apply a referrer to each request. ```php use GuzzleHttp\Client; $httpClient = new Client([ 'headers' => [ 'referer' => 'mysite.com' ] ]); $client = new Google\Client(); $client->setHttpClient($httpClient); ``` Other Guzzle features such as [Handlers and Middleware](http://docs.guzzlephp.org/en/stable/handlers-and-middleware.html) offer even more control. ### Partial Consent and Granted Scopes When using OAuth2 3LO (e.g. you're a client requesting credentials from a 3rd party, such as in the [simple file upload example](examples/simple-file-upload.php)), you may want to take advantage of Partial Consent. To allow clients to only grant certain scopes in the OAuth2 screen, pass the querystring parameter for `enable_serial_consent` when generating the authorization URL: ```php $authUrl = $client->createAuthUrl($scope, ['enable_serial_consent' => 'true']); ``` Once the flow is completed, you can see which scopes were granted by calling `getGrantedScope` on the OAuth2 object: ```php // Space-separated string of granted scopes if it exists, otherwise null. echo $client->getOAuth2Service()->getGrantedScope(); ``` ### Service Specific Examples ### YouTube: https://github.com/youtube/api-samples/tree/master/php ## How Do I Contribute? ## Please see the [contributing](.github/CONTRIBUTING.md) page for more information. In particular, we love pull requests - but please make sure to sign the contributor license agreement. ## Frequently Asked Questions ## ### What do I do if something isn't working? ### For support with the library the best place to ask is via the google-api-php-client tag on StackOverflow: https://stackoverflow.com/questions/tagged/google-api-php-client If there is a specific bug with the library, please [file an issue](https://github.com/googleapis/google-api-php-client/issues) in the GitHub issues tracker, including an example of the failing code and any specific errors retrieved. Feature requests can also be filed, as long as they are core library requests, and not-API specific: for those, refer to the documentation for the individual APIs for the best place to file requests. Please try to provide a clear statement of the problem that the feature would address. ### I want an example of X! ### If X is a feature of the library, file away! If X is an example of using a specific service, the best place to go is to the teams for those specific APIs - our preference is to link to their examples rather than add them to the library, as they can then pin to specific versions of the library. If you have any examples for other APIs, let us know and we will happily add a link to the README above! ### Why do some Google\Service classes have weird names? ### The _Google\Service_ classes are generally automatically generated from the API discovery documents: https://developers.google.com/discovery/. Sometimes new features are added to APIs with unusual names, which can cause some unexpected or non-standard style naming in the PHP classes. ### How do I deal with non-JSON response types? ### Some services return XML or similar by default, rather than JSON, which is what the library supports. You can request a JSON response by adding an 'alt' argument to optional params that is normally the last argument to a method call: ```php $opt_params = array( 'alt' => "json" ); ``` ### How do I set a field to null? ### The library strips out nulls from the objects sent to the Google APIs as it is the default value of all of the uninitialized properties. To work around this, set the field you want to null to `Google\Model::NULL_VALUE`. This is a placeholder that will be replaced with a true null when sent over the wire. ## Code Quality ## Run the PHPUnit tests with PHPUnit. You can configure an API key and token in BaseTest.php to run all calls, but this will require some setup on the Google Developer Console. phpunit tests/ ### Coding Style To check for coding style violations, run ``` vendor/bin/phpcs src --standard=style/ruleset.xml -np ``` To automatically fix (fixable) coding style violations, run ``` vendor/bin/phpcbf src --standard=style/ruleset.xml ``` ================================================ FILE: lib/Google/SECURITY.md ================================================ # Security Policy To report a security issue, please use [g.co/vulnz](https://g.co/vulnz). The Google Security Team will respond within 5 working days of your report on g.co/vulnz. We use g.co/vulnz for our intake, and do coordination and disclosure here using GitHub Security Advisory to privately discuss and fix the issue. ================================================ FILE: lib/Google/UPGRADING.md ================================================ Google API Client Upgrade Guide =============================== 2.x to 2.10.0 ------------- ### Namespaces The Google API Client for PHP now uses namespaces for all classes. Code using the legacy classnames will continue to work, but it is advised to upgrade to the underspaced names, as the legacy classnames will be deprecated some time in the future. **Before** ```php $client = new Google_Client(); $service = new Google_Service_Books($client); ``` **After** ```php $client = new Google\Client(); $service = new Google\Service\Books($client); ``` ### Service class constructors Service class constructors now accept an optional `Google\Client|array` parameter as their first argument, rather than requiring an instance of `Google\Client`. **Before** ```php $client = new Google_Client(); $client->setApplicationName("Client_Library_Examples"); $client->setDeveloperKey("YOUR_APP_KEY"); $service = new Google_Service_Books($client); ``` **After** ```php $service = new Google\Service\Books([ 'application_name' => "Client_Library_Examples", 'developer_key' => "YOUR_APP_KEY", ]); ``` 1.0 to 2.0 ---------- The Google API Client for PHP has undergone major internal changes in `2.0`. Please read through the list below in order to upgrade to the latest version: ## Installation now uses `Composer` **Before** The project was cloned in your project and you would run the autoloader from wherever: ```php // the autoload file was included require_once 'google-api-php-client/src/Google/autoload.php'; // or wherever autoload.php is located // OR classes were added one-by-one require_once 'Google/Client.php'; require_once 'Google/Service/YouTube.php'; ``` **After** This library now uses [composer](https://getcomposer.org) (We suggest installing composer [globally](http://symfony.com/doc/current/cookbook/composer.html)). Add this library by running the following in the root of your project: ``` $ composer require google/apiclient:~2.0 ``` This will install this library and generate an autoload file in `vendor/autoload.php` in the root of your project. You can now include this library with the following code: ```php require_once 'vendor/autoload.php'; ``` ## Access Tokens are passed around as arrays instead of JSON strings **Before** ```php $accessToken = $client->getAccessToken(); print_r($accessToken); // would output: // string(153) "{"access_token":"ya29.FAKsaByOPoddfzvKRo_LBpWWCpVTiAm4BjsvBwxtN7IgSNoUfcErBk_VPl4iAiE1ntb_","token_type":"Bearer","expires_in":3593,"created":1445548590}" file_put_contents($credentialsPath, $accessToken); ``` **After** ```php $accessToken = $client->getAccessToken(); print_r($accessToken); // will output: // array(4) { // ["access_token"]=> // string(73) "ya29.FAKsaByOPoddfzvKRo_LBpWWCpVTiAm4BjsvBwxtN7IgSNoUfcErBk_VPl4iAiE1ntb_" // ["token_type"]=> // string(6) "Bearer" // ["expires_in"]=> // int(3593) // ["created"]=> // int(1445548590) // } file_put_contents($credentialsPath, json_encode($accessToken)); ``` ## ID Token data is returned as an array **Before** ```php $ticket = $client->verifyIdToken($idToken); $data = $ticket->getAttributes(); $userId = $data['payload']['sub']; ``` **After** ```php $userData = $client->verifyIdToken($idToken); $userId = $userData['sub']; ``` ## `Google_Auth_AssertionCredentials` has been removed For service accounts, we now use `setAuthConfig` or `useApplicationDefaultCredentials` **Before** ```php $client_email = '1234567890-a1b2c3d4e5f6g7h8i@developer.gserviceaccount.com'; $private_key = file_get_contents('MyProject.p12'); $scopes = array('https://www.googleapis.com/auth/sqlservice.admin'); $credentials = new Google_Auth_AssertionCredentials( $client_email, $scopes, $private_key ); ``` **After** ```php $client->setAuthConfig('/path/to/service-account.json'); // OR use environment variables (recommended) putenv('GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json'); $client->useApplicationDefaultCredentials(); ``` > Note: P12s are deprecated in favor of service account JSON, which can be generated in the > Credentials section of Google Developer Console. In order to impersonate a user, call `setSubject` when your service account credentials are being used. **Before** ```php $user_to_impersonate = 'user@example.org'; $credentials = new Google_Auth_AssertionCredentials( $client_email, $scopes, $private_key, 'notasecret', // Default P12 password 'http://oauth.net/grant_type/jwt/1.0/bearer', // Default grant type $user_to_impersonate, ); ``` **After** ```php $user_to_impersonate = 'user@example.org'; $client->setSubject($user_to_impersonate); ``` Additionally, `Google_Client::loadServiceAccountJson` has been removed in favor of `Google_Client::setAuthConfig`: **Before** ```php $scopes = [ Google_Service_Books::BOOKS ]; $client->loadServiceAccountJson('/path/to/service-account.json', $scopes); ``` **After** ```php $scopes = [ Google_Service_Books::BOOKS ]; $client->setAuthConfig('/path/to/service-account.json'); $client->setScopes($scopes); ``` ## `Google_Auth_AppIdentity` has been removed For App Engine authentication, we now use the underlying [`google/auth`][Google Auth] and call `useApplicationDefaultCredentials`: **Before** ```php $client->setAuth(new Google_Auth_AppIdentity($client)); $client->getAuth() ->authenticateForScope('https://www.googleapis.com/auth/sqlservice.admin') ``` **After** ```php $client->useApplicationDefaultCredentials(); $client->addScope('https://www.googleapis.com/auth/sqlservice.admin'); ``` This will detect when the App Engine environment is present, and use the appropriate credentials. ## `Google_Auth_Abstract` classes have been removed [`google/auth`][Google Auth] is now used for authentication. As a result, all `Google_Auth`-related functionality has been removed. The methods that were a part of `Google_Auth_Abstract` have been moved into the `Google_Client` object. **Before** ```php $request = new Google_Http_Request(); $client->getAuth()->sign($request); ``` **After** ```php // create an authorized HTTP client $httpClient = $client->authorize(); // OR add authorization to an existing client $httpClient = new GuzzleHttp\Client(); $httpClient = $client->authorize($httpClient); ``` **Before** ```php $request = new Google_Http_Request(); $response = $client->getAuth()->authenticatedRequest($request); ``` **After** ```php $httpClient = $client->authorize(); $request = new GuzzleHttp\Psr7\Request('POST', $url); $response = $httpClient->send($request); ``` > NOTE: `$request` can be any class implementing > `Psr\Http\Message\RequestInterface` In addition, other methods that were callable on `Google_Auth_OAuth2` are now called on the `Google_Client` object: **Before** ```php $client->getAuth()->refreshToken($token); $client->getAuth()->refreshTokenWithAssertion(); $client->getAuth()->revokeToken($token); $client->getAuth()->isAccessTokenExpired(); ``` **After** ```php $client->refreshToken($token); $client->refreshTokenWithAssertion(); $client->revokeToken($token); $client->isAccessTokenExpired(); ``` ## PHP 5.6 is now the minimum supported PHP version This was previously `PHP 5.2`. If you still need to use PHP 5.2, please continue to use the [v1-master](https://github.com/google/google-api-php-client/tree/v1-master) branch. ## Guzzle and PSR-7 are used for HTTP Requests The HTTP library Guzzle is used for all HTTP Requests. By default, [`Guzzle 6`][Guzzle 6] is used, but this library is also compatible with [`Guzzle 5`][Guzzle 5]. As a result, all `Google_IO`-related functionality and `Google_Http`-related functionality has been changed or removed. 1. Removed `Google_Http_Request` 1. Removed `Google_IO_Abstract`, `Google_IO_Exception`, `Google_IO_Curl`, and `Google_IO_Stream` 1. Removed methods `Google_Client::getIo` and `Google_Client::setIo` 1. Refactored `Google_Http_Batch` and `Google_Http_MediaFileUpload` for Guzzle 1. Added `Google_Client::getHttpClient` and `Google_Client::setHttpClient` for getting and setting the Guzzle `GuzzleHttp\ClientInterface` object. > NOTE: `PSR-7`-compatible libraries can now be used with this library. ## Other Changes - [`PSR 3`][PSR 3] `LoggerInterface` is now supported, and [Monolog][Monolog] is used for all logging. As a result, all `Google_Logger`-related functionality has been removed: 1. Removed `Google_Logger_Abstract`, `Google_Logger_Exception`, `Google_Logger_File`, `Google_Logger_Null`, and `Google_Logger_Psr` 1. `Google_Client::setLogger` now requires `Psr\Log\LoggerInterface` - [`firebase/jwt`][Firebase JWT] is now used for all JWT signing and verifying. As a result, the following classes have been changed or removed: 1. Removed `Google_Signer_P12` 1. Removed `Google_Verifier_Pem` 1. Removed `Google_Auth_LoginTicket` (see below) - The following classes and methods have been removed in favor of [`google/auth`][Google Auth]: 1. Removed methods `Google_Client::getAuth` and `Google_Client::setAuth` 1. Removed `Google_Auth_Abstract` - `Google_Auth_Abstract::sign` and `Google_Auth_Abstract::authenticatedRequest` have been replaced by `Google_Client::authorize`. See the above examples for more details. 1. Removed `Google_Auth_AppIdentity`. This is now supported in [`google/auth`][Google Auth AppIdentity] and is used automatically when `Google_Client::useApplicationDefaultCredentials` is called. 1. Removed `Google_Auth_AssertionCredentials`. Use `Google_Client::setAuthConfig` instead. 1. Removed `Google_Auth_ComputeEngine`. This is now supported in [`google/auth`][Google Auth GCE], and is used automatically when `Google_Client::useApplicationDefaultCredentials` is called. 1. Removed `Google_Auth_Exception` 1. Removed `Google_Auth_LoginTicket`. Calls to `Google_Client::verifyIdToken` now returns the payload of the ID Token as an array if the verification is successful. 1. Removed `Google_Auth_OAuth2`. This functionality is now supported in [`google/auth`][Google Auth OAuth2] and wrapped in `Google_Client`. These changes will only affect applications calling `Google_Client::getAuth`, as the methods on `Google_Client` have not changed. 1. Removed `Google_Auth_Simple`. This is now supported in [`google/auth`][Google Auth Simple] and is used automatically when `Google_Client::setDeveloperKey` is called. - `Google_Client::sign` has been replaced by `Google_Client::authorize`. This function now takes a `GuzzleHttp\ClientInterface` object and uses the following decision tree for authentication: 1. Uses Application Default Credentials when `Google_Client::useApplicationDefaultCredentials` is called - Looks for `GOOGLE_APPLICATION_CREDENTIALS` environment variable if set - Looks in `~/.config/gcloud/application_default_credentials.json` - Otherwise, uses `GCECredentials` 1. Uses API Key if set (see `Client::setDeveloperKey`) 1. Uses Access Token if set (call `Client::setAccessToken`) 1. Automatically refreshes access tokens if one is set and the access token is expired - Removed `Google_Config` - Removed `Google_Utils` - [`PSR-6`][PSR 6] cache is used for all caching. As a result: 1. Removed `Google_Cache_Abstract` 1. Classes `Google_Cache_Apc`, `Google_Cache_File`, `Google_Cache_Memcache`, and `Google_Cache_Null` now implement `Google\Auth\CacheInterface`. 1. Google Auth provides simple [caching utilities][Google Auth Cache] which are used by default unless you provide alternatives. - Removed `$boundary` constructor argument for `Google_Http_MediaFileUpload` [PSR 3]: https://www.php-fig.org/psr/psr-3/ [PSR 6]: https://www.php-fig.org/psr/psr-6/ [Guzzle 5]: https://github.com/guzzle/guzzle [Guzzle 6]: http://docs.guzzlephp.org/en/latest/psr7.html [Monolog]: https://github.com/Seldaek/monolog [Google Auth]: https://github.com/google/google-auth-library-php [Google Auth Cache]: https://github.com/googleapis/google-auth-library-php/tree/master/src/Cache [Google Auth GCE]: https://github.com/google/google-auth-library-php/blob/master/src/GCECredentials.php [Google Auth OAuth2]: https://github.com/google/google-auth-library-php/blob/master/src/OAuth2.php [Google Auth Simple]: https://github.com/google/google-auth-library-php/blob/master/src/Simple.php [Google Auth AppIdentity]: https://github.com/google/google-auth-library-php/blob/master/src/AppIdentityCredentials.php [Firebase JWT]: https://github.com/firebase/php-jwt ================================================ FILE: lib/Google/composer.json ================================================ { "name": "google/apiclient", "type": "library", "description": "Client library for Google APIs", "keywords": ["google"], "homepage": "http://developers.google.com/api-client-library/php", "license": "Apache-2.0", "require": { "php": "^8.1", "google/auth": "^1.37", "google/apiclient-services": "~0.350", "firebase/php-jwt": "^6.0||^7.0", "monolog/monolog": "^2.9||^3.0", "phpseclib/phpseclib": "^3.0.36", "guzzlehttp/guzzle": "^7.4.5", "guzzlehttp/psr7": "^2.6", "google/cloud-storage": "^1.49", "google/cloud-core": "^1.60" }, "require-dev": { "squizlabs/php_codesniffer": "^3.8", "symfony/dom-crawler": "~2.1", "symfony/css-selector": "~2.1", "phpcompatibility/php-compatibility": "^9.2", "composer/composer": "^2.9.3", "phpspec/prophecy-phpunit": "^2.1", "phpunit/phpunit": "^9.6", "symfony/process": "^6.4" }, "suggest": { "cache/filesystem-adapter": "For caching certs and tokens (using Google\\Client::setCache)" }, "autoload": { "psr-4": { "Google\\": "src/" }, "files": [ "src/aliases.php" ], "classmap": [ "src/aliases.php" ] }, "scripts": { "pre-autoload-dump": "Google\\Task\\Composer::cleanup" }, "extra": { "google/apiclient-services": [ "Storage" ], "branch-alias": { "dev-main": "2.x-dev" } } } ================================================ FILE: lib/Google/phpstan.neon.dist ================================================ parameters: treatPhpDocTypesAsCertain: false level: 5 paths: - src ================================================ FILE: lib/Google/src/AccessToken/Revoke.php ================================================ http = $http; } /** * Revoke an OAuth2 access token or refresh token. This method will revoke the current access * token, if a token isn't provided. * * @param string|array $token The token (access token or a refresh token) that should be revoked. * @return boolean Returns True if the revocation was successful, otherwise False. */ public function revokeToken($token) { if (is_array($token)) { if (isset($token['refresh_token'])) { $token = $token['refresh_token']; } else { $token = $token['access_token']; } } $body = Psr7\Utils::streamFor(http_build_query(['token' => $token])); $request = new Request( 'POST', Client::OAUTH2_REVOKE_URI, [ 'Cache-Control' => 'no-store', 'Content-Type' => 'application/x-www-form-urlencoded', ], $body ); $httpHandler = HttpHandlerFactory::build($this->http); $response = $httpHandler($request); return $response->getStatusCode() == 200; } } ================================================ FILE: lib/Google/src/AccessToken/Verify.php ================================================ http = $http; $this->cache = $cache; $this->jwt = $jwt ?: $this->getJwtService(); } /** * Verifies an id token and returns the authenticated apiLoginTicket. * Throws an exception if the id token is not valid. * The audience parameter can be used to control which id tokens are * accepted. By default, the id token must have been issued to this OAuth2 client. * * @param string $idToken the ID token in JWT format * @param string $audience Optional. The audience to verify against JWt "aud" * @return array|false the token payload, if successful */ public function verifyIdToken($idToken, $audience = null) { if (empty($idToken)) { throw new LogicException('id_token cannot be null'); } // set phpseclib constants if applicable $this->setPhpsecConstants(); // Check signature $certs = $this->getFederatedSignOnCerts(); foreach ($certs as $cert) { try { $args = [$idToken]; $publicKey = $this->getPublicKey($cert); if (class_exists(Key::class)) { $args[] = new Key($publicKey, 'RS256'); } else { $args[] = $publicKey; $args[] = ['RS256']; } $payload = \call_user_func_array([$this->jwt, 'decode'], $args); if (property_exists($payload, 'aud')) { if ($audience && $payload->aud != $audience) { return false; } } // support HTTP and HTTPS issuers // @see https://developers.google.com/identity/sign-in/web/backend-auth $issuers = [self::OAUTH2_ISSUER, self::OAUTH2_ISSUER_HTTPS]; if (!isset($payload->iss) || !in_array($payload->iss, $issuers)) { return false; } return (array)$payload; } catch (ExpiredException $e) { // @phpstan-ignore-line return false; } catch (ExpiredExceptionV3 $e) { return false; } catch (SignatureInvalidException $e) { // continue } catch (DomainException $e) { // continue } } return false; } private function getCache() { return $this->cache; } /** * Retrieve and cache a certificates file. * * @param string $url location * @return array certificates * @throws \Google\Exception */ private function retrieveCertsFromLocation($url) { // If we're retrieving a local file, just grab it. if (0 !== strpos($url, 'http')) { if (!$file = file_get_contents($url)) { throw new GoogleException( "Failed to retrieve verification certificates: '". $url."'." ); } return json_decode($file, true); } // @phpstan-ignore-next-line $response = $this->http->get($url); if ($response->getStatusCode() == 200) { return json_decode((string)$response->getBody(), true); } throw new GoogleException( sprintf( 'Failed to retrieve verification certificates: "%s".', $response->getBody()->getContents() ), $response->getStatusCode() ); } // Gets federated sign-on certificates to use for verifying identity tokens. // Returns certs as array structure, where keys are key ids, and values // are PEM encoded certificates. private function getFederatedSignOnCerts() { $certs = null; if ($cache = $this->getCache()) { $cacheItem = $cache->getItem('federated_signon_certs_v3'); $certs = $cacheItem->get(); } if (!$certs) { $certs = $this->retrieveCertsFromLocation( self::FEDERATED_SIGNON_CERT_URL ); if ($cache) { $cacheItem->expiresAt(new DateTime('+1 hour')); $cacheItem->set($certs); $cache->save($cacheItem); } } if (!isset($certs['keys'])) { throw new InvalidArgumentException( 'federated sign-on certs expects "keys" to be set' ); } return $certs['keys']; } private function getJwtService() { $jwt = new JWT(); if ($jwt::$leeway < 1) { // Ensures JWT leeway is at least 1 // @see https://github.com/google/google-api-php-client/issues/827 $jwt::$leeway = 1; } return $jwt; } private function getPublicKey($cert) { $modulus = new BigInteger($this->jwt->urlsafeB64Decode($cert['n']), 256); $exponent = new BigInteger($this->jwt->urlsafeB64Decode($cert['e']), 256); $component = ['n' => $modulus, 'e' => $exponent]; $loader = PublicKeyLoader::load($component); return $loader->toString('PKCS8'); } /** * phpseclib calls "phpinfo" by default, which requires special * whitelisting in the AppEngine VM environment. This function * sets constants to bypass the need for phpseclib to check phpinfo * * @see phpseclib/Math/BigInteger * @see https://github.com/GoogleCloudPlatform/getting-started-php/issues/85 */ private function setPhpsecConstants() { if (filter_var(getenv('GAE_VM'), FILTER_VALIDATE_BOOLEAN)) { if (!defined('MATH_BIGINTEGER_OPENSSL_ENABLED')) { define('MATH_BIGINTEGER_OPENSSL_ENABLED', true); } if (!defined('CRYPT_RSA_MODE')) { define('CRYPT_RSA_MODE', AES::ENGINE_OPENSSL); } } } } ================================================ FILE: lib/Google/src/AuthHandler/AuthHandlerFactory.php ================================================ cache = $cache; $this->cacheConfig = $cacheConfig; } public function attachCredentials( ClientInterface $http, FetchAuthTokenInterface $credentials, ?callable $tokenCallback = null ) { // use the provided cache if ($this->cache) { $credentials = new FetchAuthTokenCache( $credentials, $this->cacheConfig, $this->cache ); } return $this->attachToHttp($http, $credentials, $tokenCallback); } public function attachCredentialsCache( ClientInterface $http, FetchAuthTokenCache $credentials, ?callable $tokenCallback = null ) { return $this->attachToHttp($http, $credentials, $tokenCallback); } private function attachToHttp( ClientInterface $http, FetchAuthTokenInterface $credentials, ?callable $tokenCallback = null ) { // if we end up needing to make an HTTP request to retrieve credentials, we // can use our existing one, but we need to throw exceptions so the error // bubbles up. $authHttp = $this->createAuthHttp($http); $authHttpHandler = HttpHandlerFactory::build($authHttp); $middleware = new AuthTokenMiddleware( $credentials, $authHttpHandler, $tokenCallback ); $config = $http->getConfig(); $config['handler']->remove('google_auth'); $config['handler']->push($middleware, 'google_auth'); $config['auth'] = 'google_auth'; return new Client($config); } public function attachToken(ClientInterface $http, array $token, array $scopes) { $tokenFunc = function ($scopes) use ($token) { return $token['access_token']; }; // Derive a cache prefix from the token, to ensure setting a new token // results in a cache-miss. // Note: Supplying a custom "prefix" will bust this behavior. $cacheConfig = $this->cacheConfig; if (!isset($cacheConfig['prefix']) && isset($token['access_token'])) { $cacheConfig['prefix'] = substr(sha1($token['access_token']), -10); } $middleware = new ScopedAccessTokenMiddleware( $tokenFunc, $scopes, $cacheConfig, $this->cache ); $config = $http->getConfig(); $config['handler']->remove('google_auth'); $config['handler']->push($middleware, 'google_auth'); $config['auth'] = 'scoped'; $http = new Client($config); return $http; } public function attachKey(ClientInterface $http, $key) { $middleware = new SimpleMiddleware(['key' => $key]); $config = $http->getConfig(); $config['handler']->remove('google_auth'); $config['handler']->push($middleware, 'google_auth'); $config['auth'] = 'simple'; $http = new Client($config); return $http; } private function createAuthHttp(ClientInterface $http) { return new Client(['http_errors' => true] + $http->getConfig()); } } ================================================ FILE: lib/Google/src/AuthHandler/Guzzle7AuthHandler.php ================================================ config = array_merge([ 'application_name' => '', 'base_path' => self::API_BASE_PATH, 'client_id' => '', 'client_secret' => '', 'credentials' => null, 'scopes' => null, 'quota_project' => null, 'redirect_uri' => null, 'state' => null, 'developer_key' => '', 'use_application_default_credentials' => false, 'signing_key' => null, 'signing_algorithm' => null, 'subject' => null, 'hd' => '', 'prompt' => '', 'openid.realm' => '', 'include_granted_scopes' => null, 'logger' => null, 'login_hint' => '', 'request_visible_actions' => '', 'access_type' => 'online', 'approval_prompt' => 'auto', 'retry' => [], 'retry_map' => null, 'cache' => null, 'cache_config' => [], 'token_callback' => null, 'jwt' => null, 'api_format_v2' => false, 'universe_domain' => getenv('GOOGLE_CLOUD_UNIVERSE_DOMAIN') ?: GetUniverseDomainInterface::DEFAULT_UNIVERSE_DOMAIN, ], $config); if (!is_null($this->config['credentials'])) { if ($this->config['credentials'] instanceof FetchAuthTokenInterface) { $this->credentials = $this->config['credentials']; } else { $this->setAuthConfig($this->config['credentials']); } unset($this->config['credentials']); } if (!is_null($this->config['scopes'])) { $this->setScopes($this->config['scopes']); unset($this->config['scopes']); } // Set a default token callback to update the in-memory access token if (is_null($this->config['token_callback'])) { $this->config['token_callback'] = function ($cacheKey, $newAccessToken) { $this->setAccessToken( [ 'access_token' => $newAccessToken, 'expires_in' => 3600, // Google default 'created' => time(), ] ); }; } if (!is_null($this->config['cache'])) { $this->setCache($this->config['cache']); unset($this->config['cache']); } if (!is_null($this->config['logger'])) { $this->setLogger($this->config['logger']); unset($this->config['logger']); } } /** * Get a string containing the version of the library. * * @return string */ public function getLibraryVersion() { return self::LIBVER; } /** * For backwards compatibility * alias for fetchAccessTokenWithAuthCode * * @param string $code string code from accounts.google.com * @return array access token * @deprecated */ public function authenticate($code) { return $this->fetchAccessTokenWithAuthCode($code); } /** * Attempt to exchange a code for an valid authentication token. * Helper wrapped around the OAuth 2.0 implementation. * * @param string $code code from accounts.google.com * @param string $codeVerifier the code verifier used for PKCE (if applicable) * @return array access token */ public function fetchAccessTokenWithAuthCode($code, $codeVerifier = null) { if (strlen($code) == 0) { throw new InvalidArgumentException("Invalid code"); } $auth = $this->getOAuth2Service(); $auth->setCode($code); $auth->setRedirectUri($this->getRedirectUri()); if ($codeVerifier) { $auth->setCodeVerifier($codeVerifier); } $httpHandler = HttpHandlerFactory::build($this->getHttpClient()); $creds = $auth->fetchAuthToken($httpHandler); if ($creds && isset($creds['access_token'])) { $creds['created'] = time(); $this->setAccessToken($creds); } return $creds; } /** * For backwards compatibility * alias for fetchAccessTokenWithAssertion * * @return array access token * @deprecated */ public function refreshTokenWithAssertion() { return $this->fetchAccessTokenWithAssertion(); } /** * Fetches a fresh access token with a given assertion token. * @param ClientInterface $authHttp optional. * @return array access token */ public function fetchAccessTokenWithAssertion(?ClientInterface $authHttp = null) { if (!$this->isUsingApplicationDefaultCredentials()) { throw new DomainException( 'set the JSON service account credentials using' . ' Google\Client::setAuthConfig or set the path to your JSON file' . ' with the "GOOGLE_APPLICATION_CREDENTIALS" environment variable' . ' and call Google\Client::useApplicationDefaultCredentials to' . ' refresh a token with assertion.' ); } $this->getLogger()->log( 'info', 'OAuth2 access token refresh with Signed JWT assertion grants.' ); $credentials = $this->createApplicationDefaultCredentials(); $httpHandler = HttpHandlerFactory::build($authHttp); $creds = $credentials->fetchAuthToken($httpHandler); if ($creds && isset($creds['access_token'])) { $creds['created'] = time(); $this->setAccessToken($creds); } return $creds; } /** * For backwards compatibility * alias for fetchAccessTokenWithRefreshToken * * @param string $refreshToken * @return array access token */ public function refreshToken($refreshToken) { return $this->fetchAccessTokenWithRefreshToken($refreshToken); } /** * Fetches a fresh OAuth 2.0 access token with the given refresh token. * @param string $refreshToken * @return array access token */ public function fetchAccessTokenWithRefreshToken($refreshToken = null) { if (null === $refreshToken) { if (!isset($this->token['refresh_token'])) { throw new LogicException( 'refresh token must be passed in or set as part of setAccessToken' ); } $refreshToken = $this->token['refresh_token']; } $this->getLogger()->info('OAuth2 access token refresh'); $auth = $this->getOAuth2Service(); $auth->setRefreshToken($refreshToken); $httpHandler = HttpHandlerFactory::build($this->getHttpClient()); $creds = $auth->fetchAuthToken($httpHandler); if ($creds && isset($creds['access_token'])) { $creds['created'] = time(); if (!isset($creds['refresh_token'])) { $creds['refresh_token'] = $refreshToken; } $this->setAccessToken($creds); } return $creds; } /** * Create a URL to obtain user authorization. * The authorization endpoint allows the user to first * authenticate, and then grant/deny the access request. * @param string|array $scope The scope is expressed as an array or list of space-delimited strings. * @param array $queryParams Querystring params to add to the authorization URL. * @return string */ public function createAuthUrl($scope = null, array $queryParams = []) { if (empty($scope)) { $scope = $this->prepareScopes(); } if (is_array($scope)) { $scope = implode(' ', $scope); } // only accept one of prompt or approval_prompt $approvalPrompt = $this->config['prompt'] ? null : $this->config['approval_prompt']; // include_granted_scopes should be string "true", string "false", or null $includeGrantedScopes = $this->config['include_granted_scopes'] === null ? null : var_export($this->config['include_granted_scopes'], true); $params = array_filter([ 'access_type' => $this->config['access_type'], 'approval_prompt' => $approvalPrompt, 'hd' => $this->config['hd'], 'include_granted_scopes' => $includeGrantedScopes, 'login_hint' => $this->config['login_hint'], 'openid.realm' => $this->config['openid.realm'], 'prompt' => $this->config['prompt'], 'redirect_uri' => $this->config['redirect_uri'], 'response_type' => 'code', 'scope' => $scope, 'state' => $this->config['state'], ]) + $queryParams; // If the list of scopes contains plus.login, add request_visible_actions // to auth URL. $rva = $this->config['request_visible_actions']; if (strlen($rva) > 0 && false !== strpos($scope, 'plus.login')) { $params['request_visible_actions'] = $rva; } $auth = $this->getOAuth2Service(); return (string) $auth->buildFullAuthorizationUri($params); } /** * Adds auth listeners to the HTTP client based on the credentials * set in the Google API Client object * * @param ClientInterface $http the http client object. * @return ClientInterface the http client object */ public function authorize(?ClientInterface $http = null) { $http = $http ?: $this->getHttpClient(); $authHandler = $this->getAuthHandler(); // These conditionals represent the decision tree for authentication // 1. Check if an instance of Google\Auth\FetchAuthTokenInterface has // been supplied via the "credentials" option // 2. Check for Application Default Credentials // 3a. Check for an Access Token // 3b. If access token exists but is expired, try to refresh it // 4. Check for API Key if ($this->credentials) { $this->checkUniverseDomain($this->credentials); return $authHandler->attachCredentials( $http, $this->credentials, $this->config['token_callback'] ); } if ($this->isUsingApplicationDefaultCredentials()) { $credentials = $this->createApplicationDefaultCredentials(); $this->checkUniverseDomain($credentials); return $authHandler->attachCredentialsCache( $http, $credentials, $this->config['token_callback'] ); } if ($token = $this->getAccessToken()) { $scopes = $this->prepareScopes(); // add refresh subscriber to request a new token if (isset($token['refresh_token']) && $this->isAccessTokenExpired()) { $credentials = $this->createUserRefreshCredentials( $scopes, $token['refresh_token'] ); $this->checkUniverseDomain($credentials); return $authHandler->attachCredentials( $http, $credentials, $this->config['token_callback'] ); } return $authHandler->attachToken($http, $token, (array) $scopes); } if ($key = $this->config['developer_key']) { return $authHandler->attachKey($http, $key); } return $http; } /** * Set the configuration to use application default credentials for * authentication * * @see https://developers.google.com/identity/protocols/application-default-credentials * @param boolean $useAppCreds */ public function useApplicationDefaultCredentials($useAppCreds = true) { $this->config['use_application_default_credentials'] = $useAppCreds; } /** * To prevent useApplicationDefaultCredentials from inappropriately being * called in a conditional * * @see https://developers.google.com/identity/protocols/application-default-credentials */ public function isUsingApplicationDefaultCredentials() { return $this->config['use_application_default_credentials']; } /** * Set the access token used for requests. * * Note that at the time requests are sent, tokens are cached. A token will be * cached for each combination of service and authentication scopes. If a * cache pool is not provided, creating a new instance of the client will * allow modification of access tokens. If a persistent cache pool is * provided, in order to change the access token, you must clear the cached * token by calling `$client->getCache()->clear()`. (Use caution in this case, * as calling `clear()` will remove all cache items, including any items not * related to Google API PHP Client.) * * **NOTE:** The universe domain is assumed to be "googleapis.com" unless * explicitly set. When setting an access token directly via this method, there * is no way to verify the universe domain. Be sure to set the "universe_domain" * option if "googleapis.com" is not intended. * * @param string|array $token * @throws InvalidArgumentException */ public function setAccessToken($token) { if (is_string($token)) { if ($json = json_decode($token, true)) { $token = $json; } else { // assume $token is just the token string $token = [ 'access_token' => $token, ]; } } if ($token == null) { throw new InvalidArgumentException('invalid json token'); } if (!isset($token['access_token'])) { throw new InvalidArgumentException("Invalid token format"); } $this->token = $token; } public function getAccessToken() { return $this->token; } /** * @return string|null */ public function getRefreshToken() { if (isset($this->token['refresh_token'])) { return $this->token['refresh_token']; } return null; } /** * Returns if the access_token is expired. * @return bool Returns True if the access_token is expired. */ public function isAccessTokenExpired() { if (!$this->token) { return true; } $created = 0; if (isset($this->token['created'])) { $created = $this->token['created']; } elseif (isset($this->token['id_token'])) { // check the ID token for "iat" // signature verification is not required here, as we are just // using this for convenience to save a round trip request // to the Google API server $idToken = $this->token['id_token']; if (substr_count($idToken, '.') == 2) { $parts = explode('.', $idToken); $payload = json_decode(base64_decode($parts[1]), true); if ($payload && isset($payload['iat'])) { $created = $payload['iat']; } } } if (!isset($this->token['expires_in'])) { // if the token does not have an "expires_in", then it's considered expired return true; } // If the token is set to expire in the next 30 seconds. return ($created + ($this->token['expires_in'] - 30)) < time(); } /** * @deprecated See UPGRADING.md for more information */ public function getAuth() { throw new BadMethodCallException( 'This function no longer exists. See UPGRADING.md for more information' ); } /** * @deprecated See UPGRADING.md for more information */ public function setAuth($auth) { throw new BadMethodCallException( 'This function no longer exists. See UPGRADING.md for more information' ); } /** * Set the OAuth 2.0 Client ID. * @param string $clientId */ public function setClientId($clientId) { $this->config['client_id'] = $clientId; } public function getClientId() { return $this->config['client_id']; } /** * Set the OAuth 2.0 Client Secret. * @param string $clientSecret */ public function setClientSecret($clientSecret) { $this->config['client_secret'] = $clientSecret; } public function getClientSecret() { return $this->config['client_secret']; } /** * Set the OAuth 2.0 Redirect URI. * @param string $redirectUri */ public function setRedirectUri($redirectUri) { $this->config['redirect_uri'] = $redirectUri; } public function getRedirectUri() { return $this->config['redirect_uri']; } /** * Set OAuth 2.0 "state" parameter to achieve per-request customization. * @see http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-3.1.2.2 * @param string $state */ public function setState($state) { $this->config['state'] = $state; } /** * @param string $accessType Possible values for access_type include: * {@code "offline"} to request offline access from the user. * {@code "online"} to request online access from the user. */ public function setAccessType($accessType) { $this->config['access_type'] = $accessType; } /** * @param string $approvalPrompt Possible values for approval_prompt include: * {@code "force"} to force the approval UI to appear. * {@code "auto"} to request auto-approval when possible. (This is the default value) */ public function setApprovalPrompt($approvalPrompt) { $this->config['approval_prompt'] = $approvalPrompt; } /** * Set the login hint, email address or sub id. * @param string $loginHint */ public function setLoginHint($loginHint) { $this->config['login_hint'] = $loginHint; } /** * Set the application name, this is included in the User-Agent HTTP header. * @param string $applicationName */ public function setApplicationName($applicationName) { $this->config['application_name'] = $applicationName; } /** * If 'plus.login' is included in the list of requested scopes, you can use * this method to define types of app activities that your app will write. * You can find a list of available types here: * @link https://developers.google.com/+/api/moment-types * * @param array $requestVisibleActions Array of app activity types */ public function setRequestVisibleActions($requestVisibleActions) { if (is_array($requestVisibleActions)) { $requestVisibleActions = implode(" ", $requestVisibleActions); } $this->config['request_visible_actions'] = $requestVisibleActions; } /** * Set the developer key to use, these are obtained through the API Console. * @see http://code.google.com/apis/console-help/#generatingdevkeys * @param string $developerKey */ public function setDeveloperKey($developerKey) { $this->config['developer_key'] = $developerKey; } /** * Set the hd (hosted domain) parameter streamlines the login process for * Google Apps hosted accounts. By including the domain of the user, you * restrict sign-in to accounts at that domain. * @param string $hd the domain to use. */ public function setHostedDomain($hd) { $this->config['hd'] = $hd; } /** * Set the prompt hint. Valid values are none, consent and select_account. * If no value is specified and the user has not previously authorized * access, then the user is shown a consent screen. * @param string $prompt * {@code "none"} Do not display any authentication or consent screens. Must not be specified with other values. * {@code "consent"} Prompt the user for consent. * {@code "select_account"} Prompt the user to select an account. */ public function setPrompt($prompt) { $this->config['prompt'] = $prompt; } /** * openid.realm is a parameter from the OpenID 2.0 protocol, not from OAuth * 2.0. It is used in OpenID 2.0 requests to signify the URL-space for which * an authentication request is valid. * @param string $realm the URL-space to use. */ public function setOpenidRealm($realm) { $this->config['openid.realm'] = $realm; } /** * If this is provided with the value true, and the authorization request is * granted, the authorization will include any previous authorizations * granted to this user/application combination for other scopes. * @param bool $include the URL-space to use. */ public function setIncludeGrantedScopes($include) { $this->config['include_granted_scopes'] = $include; } /** * sets function to be called when an access token is fetched * @param callable $tokenCallback - function ($cacheKey, $accessToken) */ public function setTokenCallback(callable $tokenCallback) { $this->config['token_callback'] = $tokenCallback; } /** * Revoke an OAuth2 access token or refresh token. This method will revoke the current access * token, if a token isn't provided. * * @param string|array|null $token The token (access token or a refresh token) that should be revoked. * @return boolean Returns True if the revocation was successful, otherwise False. */ public function revokeToken($token = null) { $tokenRevoker = new Revoke($this->getHttpClient()); return $tokenRevoker->revokeToken($token ?: $this->getAccessToken()); } /** * Verify an id_token. This method will verify the current id_token, if one * isn't provided. * * @throws LogicException If no token was provided and no token was set using `setAccessToken`. * @throws UnexpectedValueException If the token is not a valid JWT. * @param string|null $idToken The token (id_token) that should be verified. * @return array|false Returns the token payload as an array if the verification was * successful, false otherwise. */ public function verifyIdToken($idToken = null) { $tokenVerifier = new Verify( $this->getHttpClient(), $this->getCache(), $this->config['jwt'] ); if (null === $idToken) { $token = $this->getAccessToken(); if (!isset($token['id_token'])) { throw new LogicException( 'id_token must be passed in or set as part of setAccessToken' ); } $idToken = $token['id_token']; } return $tokenVerifier->verifyIdToken( $idToken, $this->getClientId() ); } /** * Set the scopes to be requested. Must be called before createAuthUrl(). * Will remove any previously configured scopes. * @param string|array $scope_or_scopes, ie: * array( * 'https://www.googleapis.com/auth/plus.login', * 'https://www.googleapis.com/auth/moderator' * ); */ public function setScopes($scope_or_scopes) { $this->requestedScopes = []; $this->addScope($scope_or_scopes); } /** * This functions adds a scope to be requested as part of the OAuth2.0 flow. * Will append any scopes not previously requested to the scope parameter. * A single string will be treated as a scope to request. An array of strings * will each be appended. * @param string|string[] $scope_or_scopes e.g. "profile" */ public function addScope($scope_or_scopes) { if (is_string($scope_or_scopes) && !in_array($scope_or_scopes, $this->requestedScopes)) { $this->requestedScopes[] = $scope_or_scopes; } elseif (is_array($scope_or_scopes)) { foreach ($scope_or_scopes as $scope) { $this->addScope($scope); } } } /** * Returns the list of scopes requested by the client * @return array the list of scopes * */ public function getScopes() { return $this->requestedScopes; } /** * @return string|null * @visible For Testing */ public function prepareScopes() { if (empty($this->requestedScopes)) { return null; } return implode(' ', $this->requestedScopes); } /** * Helper method to execute deferred HTTP requests. * * @template T * @param RequestInterface $request * @param class-string|false|null $expectedClass * @throws \Google\Exception * @return mixed|T|ResponseInterface */ public function execute(RequestInterface $request, $expectedClass = null) { $request = $request ->withHeader( 'User-Agent', sprintf( '%s %s%s', $this->config['application_name'], self::USER_AGENT_SUFFIX, $this->getLibraryVersion() ) ) ->withHeader( 'x-goog-api-client', sprintf( 'gl-php/%s gdcl/%s', phpversion(), $this->getLibraryVersion() ) ); if ($this->config['api_format_v2']) { $request = $request->withHeader( 'X-GOOG-API-FORMAT-VERSION', '2' ); } // call the authorize method // this is where most of the grunt work is done $http = $this->authorize(); return REST::execute( $http, $request, $expectedClass, $this->config['retry'], $this->config['retry_map'] ); } /** * Declare whether batch calls should be used. This may increase throughput * by making multiple requests in one connection. * * @param boolean $useBatch True if the batch support should * be enabled. Defaults to False. */ public function setUseBatch($useBatch) { // This is actually an alias for setDefer. $this->setDefer($useBatch); } /** * Are we running in Google AppEngine? * return bool */ public function isAppEngine() { return (isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'Google App Engine') !== false); } public function setConfig($name, $value) { $this->config[$name] = $value; } public function getConfig($name, $default = null) { return isset($this->config[$name]) ? $this->config[$name] : $default; } /** * For backwards compatibility * alias for setAuthConfig * * @param string $file the configuration file * @throws \Google\Exception * @deprecated */ public function setAuthConfigFile($file) { $this->setAuthConfig($file); } /** * Set the auth config from new or deprecated JSON config. * This structure should match the file downloaded from * the "Download JSON" button on in the Google Developer * Console. * @param string|array $config the configuration json * @throws \Google\Exception */ public function setAuthConfig($config) { if (is_string($config)) { if (!file_exists($config)) { throw new InvalidArgumentException(sprintf('file "%s" does not exist', $config)); } $json = file_get_contents($config); if (!$config = json_decode($json, true)) { throw new LogicException('invalid json for auth config'); } } $key = isset($config['installed']) ? 'installed' : 'web'; if (isset($config['type']) && $config['type'] == 'service_account') { // @TODO(v3): Remove this, as it isn't accurate. ADC applies only to determining // credentials based on the user's environment. $this->useApplicationDefaultCredentials(); // set the information from the config $this->setClientId($config['client_id']); $this->config['client_email'] = $config['client_email']; $this->config['signing_key'] = $config['private_key']; $this->config['signing_algorithm'] = 'HS256'; } elseif (isset($config[$key])) { // old-style $this->setClientId($config[$key]['client_id']); $this->setClientSecret($config[$key]['client_secret']); if (isset($config[$key]['redirect_uris'])) { $this->setRedirectUri($config[$key]['redirect_uris'][0]); } } else { // new-style $this->setClientId($config['client_id']); $this->setClientSecret($config['client_secret']); if (isset($config['redirect_uris'])) { $this->setRedirectUri($config['redirect_uris'][0]); } } } /** * Use when the service account has been delegated domain wide access. * * @param string $subject an email address account to impersonate */ public function setSubject($subject) { $this->config['subject'] = $subject; } /** * Declare whether making API calls should make the call immediately, or * return a request which can be called with ->execute(); * * @param boolean $defer True if calls should not be executed right away. */ public function setDefer($defer) { $this->deferExecution = $defer; } /** * Whether or not to return raw requests * @return boolean */ public function shouldDefer() { return $this->deferExecution; } /** * @return OAuth2 implementation */ public function getOAuth2Service() { if (!isset($this->auth)) { $this->auth = $this->createOAuth2Service(); } return $this->auth; } /** * create a default google auth object */ protected function createOAuth2Service() { $auth = new OAuth2([ 'clientId' => $this->getClientId(), 'clientSecret' => $this->getClientSecret(), 'authorizationUri' => self::OAUTH2_AUTH_URL, 'tokenCredentialUri' => self::OAUTH2_TOKEN_URI, 'redirectUri' => $this->getRedirectUri(), 'issuer' => $this->config['client_id'], 'signingKey' => $this->config['signing_key'], 'signingAlgorithm' => $this->config['signing_algorithm'], ]); return $auth; } /** * Set the Cache object * @param CacheItemPoolInterface $cache */ public function setCache(CacheItemPoolInterface $cache) { $this->cache = $cache; } /** * @return CacheItemPoolInterface */ public function getCache() { if (!$this->cache) { $this->cache = $this->createDefaultCache(); } return $this->cache; } /** * @param array $cacheConfig */ public function setCacheConfig(array $cacheConfig) { $this->config['cache_config'] = $cacheConfig; } /** * Set the Logger object * @param LoggerInterface $logger */ public function setLogger(LoggerInterface $logger) { $this->logger = $logger; } /** * @return LoggerInterface */ public function getLogger() { if (!isset($this->logger)) { $this->logger = $this->createDefaultLogger(); } return $this->logger; } protected function createDefaultLogger() { $logger = new Logger('google-api-php-client'); if ($this->isAppEngine()) { $handler = new MonologSyslogHandler('app', LOG_USER, Logger::NOTICE); } else { $handler = new MonologStreamHandler('php://stderr', Logger::NOTICE); } $logger->pushHandler($handler); return $logger; } protected function createDefaultCache() { return new MemoryCacheItemPool(); } /** * Set the Http Client object * @param ClientInterface $http */ public function setHttpClient(ClientInterface $http) { $this->http = $http; } /** * @return ClientInterface */ public function getHttpClient() { if (null === $this->http) { $this->http = $this->createDefaultHttpClient(); } return $this->http; } /** * Set the API format version. * * `true` will use V2, which may return more useful error messages. * * @param bool $value */ public function setApiFormatV2($value) { $this->config['api_format_v2'] = (bool) $value; } protected function createDefaultHttpClient() { $guzzleVersion = null; if (defined('\GuzzleHttp\ClientInterface::MAJOR_VERSION')) { $guzzleVersion = ClientInterface::MAJOR_VERSION; } elseif (defined('\GuzzleHttp\ClientInterface::VERSION')) { $guzzleVersion = (int)substr(ClientInterface::VERSION, 0, 1); } if (5 === $guzzleVersion) { $options = [ 'base_url' => $this->config['base_path'], 'defaults' => ['exceptions' => false], ]; if ($this->isAppEngine()) { if (class_exists(StreamHandler::class)) { // set StreamHandler on AppEngine by default $options['handler'] = new StreamHandler(); $options['defaults']['verify'] = '/etc/ca-certificates.crt'; } } } elseif (6 === $guzzleVersion || 7 === $guzzleVersion) { // guzzle 6 or 7 $options = [ 'base_uri' => $this->config['base_path'], 'http_errors' => false, ]; } else { throw new LogicException('Could not find supported version of Guzzle.'); } return new GuzzleClient($options); } /** * @return FetchAuthTokenCache */ private function createApplicationDefaultCredentials() { $scopes = $this->prepareScopes(); $sub = $this->config['subject']; $signingKey = $this->config['signing_key']; // create credentials using values supplied in setAuthConfig if ($signingKey) { $serviceAccountCredentials = [ 'client_id' => $this->config['client_id'], 'client_email' => $this->config['client_email'], 'private_key' => $signingKey, 'type' => 'service_account', 'quota_project_id' => $this->config['quota_project'], ]; $credentials = CredentialsLoader::makeCredentials( $scopes, $serviceAccountCredentials ); } else { // When $sub is provided, we cannot pass cache classes to ::getCredentials // because FetchAuthTokenCache::setSub does not exist. // The result is when $sub is provided, calls to ::onGce are not cached. $credentials = ApplicationDefaultCredentials::getCredentials( $scopes, null, $sub ? null : $this->config['cache_config'], $sub ? null : $this->getCache(), $this->config['quota_project'] ); } // for service account domain-wide authority (impersonating a user) // @see https://developers.google.com/identity/protocols/OAuth2ServiceAccount if ($sub) { if (!$credentials instanceof ServiceAccountCredentials) { throw new DomainException('domain-wide authority requires service account credentials'); } $credentials->setSub($sub); } // If we are not using FetchAuthTokenCache yet, create it now if (!$credentials instanceof FetchAuthTokenCache) { $credentials = new FetchAuthTokenCache( $credentials, $this->config['cache_config'], $this->getCache() ); } return $credentials; } protected function getAuthHandler() { // Be very careful using the cache, as the underlying auth library's cache // implementation is naive, and the cache keys do not account for user // sessions. // // @see https://github.com/google/google-api-php-client/issues/821 return AuthHandlerFactory::build( $this->getCache(), $this->config['cache_config'] ); } private function createUserRefreshCredentials($scope, $refreshToken) { $creds = array_filter([ 'client_id' => $this->getClientId(), 'client_secret' => $this->getClientSecret(), 'refresh_token' => $refreshToken, ]); return new UserRefreshCredentials($scope, $creds); } private function checkUniverseDomain($credentials) { $credentialsUniverse = $credentials instanceof GetUniverseDomainInterface ? $credentials->getUniverseDomain() : GetUniverseDomainInterface::DEFAULT_UNIVERSE_DOMAIN; if ($credentialsUniverse !== $this->getUniverseDomain()) { throw new DomainException(sprintf( 'The configured universe domain (%s) does not match the credential universe domain (%s)', $this->getUniverseDomain(), $credentialsUniverse )); } } public function getUniverseDomain() { return $this->config['universe_domain']; } } ================================================ FILE: lib/Google/src/Collection.php ================================================ {$this->collection_key}) && is_array($this->{$this->collection_key}) ) { reset($this->{$this->collection_key}); } } /** @return mixed */ #[\ReturnTypeWillChange] public function current() { $this->coerceType($this->key()); if (is_array($this->{$this->collection_key})) { return current($this->{$this->collection_key}); } } /** @return mixed */ #[\ReturnTypeWillChange] public function key() { if ( isset($this->{$this->collection_key}) && is_array($this->{$this->collection_key}) ) { return key($this->{$this->collection_key}); } } /** @return mixed */ #[\ReturnTypeWillChange] public function next() { return next($this->{$this->collection_key}); } /** @return bool */ #[\ReturnTypeWillChange] public function valid() { $key = $this->key(); return $key !== null && $key !== false; } /** @return int */ #[\ReturnTypeWillChange] public function count() { if (!isset($this->{$this->collection_key})) { return 0; } return count($this->{$this->collection_key}); } /** @return bool */ #[\ReturnTypeWillChange] public function offsetExists($offset) { if (!is_numeric($offset)) { return parent::offsetExists($offset); } return isset($this->{$this->collection_key}[$offset]); } /** @return mixed */ #[\ReturnTypeWillChange] public function offsetGet($offset) { if (!is_numeric($offset)) { return parent::offsetGet($offset); } $this->coerceType($offset); return $this->{$this->collection_key}[$offset]; } /** @return void */ #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { if (!is_numeric($offset)) { parent::offsetSet($offset, $value); } $this->{$this->collection_key}[$offset] = $value; } /** @return void */ #[\ReturnTypeWillChange] public function offsetUnset($offset) { if (!is_numeric($offset)) { parent::offsetUnset($offset); } unset($this->{$this->collection_key}[$offset]); } private function coerceType($offset) { $keyType = $this->keyType($this->collection_key); if ($keyType && !is_object($this->{$this->collection_key}[$offset])) { $this->{$this->collection_key}[$offset] = new $keyType($this->{$this->collection_key}[$offset]); } } } ================================================ FILE: lib/Google/src/Exception.php ================================================ client = $client; $this->boundary = $boundary ?: mt_rand(); $rootUrl = rtrim($rootUrl ?: $this->client->getConfig('base_path'), '/'); $this->rootUrl = str_replace( 'UNIVERSE_DOMAIN', $this->client->getUniverseDomain(), $rootUrl ); $this->batchPath = $batchPath ?: self::BATCH_PATH; } public function add(RequestInterface $request, $key = false) { if (false == $key) { $key = mt_rand(); } $this->requests[$key] = $request; } public function execute() { $body = ''; $classes = []; $batchHttpTemplate = <<requests as $key => $request) { $firstLine = sprintf( '%s %s HTTP/%s', $request->getMethod(), $request->getRequestTarget(), $request->getProtocolVersion() ); $content = (string) $request->getBody(); $headers = ''; foreach ($request->getHeaders() as $name => $values) { $headers .= sprintf("%s:%s\r\n", $name, implode(', ', $values)); } $body .= sprintf( $batchHttpTemplate, $this->boundary, $key, $firstLine, $headers, $content ? "\n" . $content : '' ); $classes['response-' . $key] = $request->getHeaderLine('X-Php-Expected-Class'); } $body .= "--{$this->boundary}--"; $body = trim($body); $url = $this->rootUrl . '/' . $this->batchPath; $headers = [ 'Content-Type' => sprintf('multipart/mixed; boundary=%s', $this->boundary), 'Content-Length' => (string) strlen($body), ]; $request = new Request( 'POST', $url, $headers, $body ); $response = $this->client->execute($request); return $this->parseResponse($response, $classes); } public function parseResponse(ResponseInterface $response, $classes = []) { $contentType = $response->getHeaderLine('content-type'); $contentType = explode(';', $contentType); $boundary = false; foreach ($contentType as $part) { $part = explode('=', $part, 2); if (isset($part[0]) && 'boundary' == trim($part[0])) { $boundary = $part[1]; } } $body = (string) $response->getBody(); if (!empty($body)) { $body = str_replace("--$boundary--", "--$boundary", $body); $parts = explode("--$boundary", $body); $responses = []; $requests = array_values($this->requests); foreach ($parts as $i => $part) { $part = trim($part); if (!empty($part)) { list($rawHeaders, $part) = explode("\r\n\r\n", $part, 2); $headers = $this->parseRawHeaders($rawHeaders); $status = substr($part, 0, strpos($part, "\n")); $status = explode(" ", $status); $status = $status[1]; list($partHeaders, $partBody) = $this->parseHttpResponse($part, 0); $response = new Response( (int) $status, $partHeaders, Psr7\Utils::streamFor($partBody) ); // Need content id. $key = $headers['content-id']; try { $response = REST::decodeHttpResponse($response, $requests[$i-1]); } catch (GoogleServiceException $e) { // Store the exception as the response, so successful responses // can be processed. $response = $e; } $responses[$key] = $response; } } return $responses; } return null; } private function parseRawHeaders($rawHeaders) { $headers = []; $responseHeaderLines = explode("\r\n", $rawHeaders); foreach ($responseHeaderLines as $headerLine) { if ($headerLine && strpos($headerLine, ':') !== false) { list($header, $value) = explode(': ', $headerLine, 2); $header = strtolower($header); if (isset($headers[$header])) { $headers[$header] = array_merge((array)$headers[$header], (array)$value); } else { $headers[$header] = $value; } } } return $headers; } /** * Used by the IO lib and also the batch processing. * * @param string $respData * @param int $headerSize * @return array */ private function parseHttpResponse($respData, $headerSize) { // check proxy header foreach (self::$CONNECTION_ESTABLISHED_HEADERS as $established_header) { if (stripos($respData, $established_header) !== false) { // existed, remove it $respData = str_ireplace($established_header, '', $respData); // Subtract the proxy header size unless the cURL bug prior to 7.30.0 // is present which prevented the proxy header size from being taken into // account. // @TODO look into this // if (!$this->needsQuirk()) { // $headerSize -= strlen($established_header); // } break; } } if ($headerSize) { $responseBody = substr($respData, $headerSize); $responseHeaders = substr($respData, 0, $headerSize); } else { $responseSegments = explode("\r\n\r\n", $respData, 2); $responseHeaders = $responseSegments[0]; $responseBody = isset($responseSegments[1]) ? $responseSegments[1] : null; } $responseHeaders = $this->parseRawHeaders($responseHeaders); return [$responseHeaders, $responseBody]; } } ================================================ FILE: lib/Google/src/Http/MediaFileUpload.php ================================================ client = $client; $this->request = $request; $this->mimeType = $mimeType; $this->data = $data; $this->resumable = $resumable; $this->chunkSize = $chunkSize; $this->progress = 0; $this->process(); } /** * Set the size of the file that is being uploaded. * @param int $size - int file size in bytes */ public function setFileSize($size) { $this->size = $size; } /** * Return the progress on the upload * @return int progress in bytes uploaded. */ public function getProgress() { return $this->progress; } /** * Send the next part of the file to upload. * @param string|bool $chunk Optional. The next set of bytes to send. If false will * use $data passed at construct time. */ public function nextChunk($chunk = false) { $resumeUri = $this->getResumeUri(); if (false == $chunk) { $chunk = substr($this->data, $this->progress, $this->chunkSize); } $lastBytePos = $this->progress + strlen($chunk) - 1; $headers = [ 'content-range' => "bytes $this->progress-$lastBytePos/$this->size", 'content-length' => (string) strlen($chunk), 'expect' => '', ]; $request = new Request( 'PUT', $resumeUri, $headers, Psr7\Utils::streamFor($chunk) ); return $this->makePutRequest($request); } /** * Return the HTTP result code from the last call made. * @return int code */ public function getHttpResultCode() { return $this->httpResultCode; } /** * Sends a PUT-Request to google drive and parses the response, * setting the appropiate variables from the response() * * @param RequestInterface $request the Request which will be send * * @return false|mixed false when the upload is unfinished or the decoded http response * */ private function makePutRequest(RequestInterface $request) { $response = $this->client->execute($request); $this->httpResultCode = $response->getStatusCode(); if (308 == $this->httpResultCode) { // Track the amount uploaded. $range = $response->getHeaderLine('range'); if ($range) { $range_array = explode('-', $range); $this->progress = ((int) $range_array[1]) + 1; } // Allow for changing upload URLs. $location = $response->getHeaderLine('location'); if ($location) { $this->resumeUri = $location; } // No problems, but upload not complete. return false; } return REST::decodeHttpResponse($response, $this->request); } /** * Resume a previously unfinished upload * @param string $resumeUri the resume-URI of the unfinished, resumable upload. */ public function resume($resumeUri) { $this->resumeUri = $resumeUri; $headers = [ 'content-range' => "bytes */$this->size", 'content-length' => '0', ]; $httpRequest = new Request( 'PUT', $this->resumeUri, $headers ); return $this->makePutRequest($httpRequest); } /** * @return RequestInterface * @visible for testing */ private function process() { $this->transformToUploadUrl(); $request = $this->request; $postBody = ''; $contentType = false; $meta = json_decode((string) $request->getBody(), true); $uploadType = $this->getUploadType($meta); $request = $request->withUri( Uri::withQueryValue($request->getUri(), 'uploadType', $uploadType) ); $mimeType = $this->mimeType ?: $request->getHeaderLine('content-type'); if (self::UPLOAD_RESUMABLE_TYPE == $uploadType) { $contentType = $mimeType; $postBody = is_string($meta) ? $meta : json_encode($meta); } elseif (self::UPLOAD_MEDIA_TYPE == $uploadType) { $contentType = $mimeType; $postBody = $this->data; } elseif (self::UPLOAD_MULTIPART_TYPE == $uploadType) { // This is a multipart/related upload. $boundary = $this->boundary ?: mt_rand(); $boundary = str_replace('"', '', $boundary); $contentType = 'multipart/related; boundary=' . $boundary; $related = "--$boundary\r\n"; $related .= "Content-Type: application/json; charset=UTF-8\r\n"; $related .= "\r\n" . json_encode($meta) . "\r\n"; $related .= "--$boundary\r\n"; $related .= "Content-Type: $mimeType\r\n"; $related .= "Content-Transfer-Encoding: base64\r\n"; $related .= "\r\n" . base64_encode($this->data) . "\r\n"; $related .= "--$boundary--"; $postBody = $related; } $request = $request->withBody(Psr7\Utils::streamFor($postBody)); if ($contentType) { $request = $request->withHeader('content-type', $contentType); } return $this->request = $request; } /** * Valid upload types: * - resumable (UPLOAD_RESUMABLE_TYPE) * - media (UPLOAD_MEDIA_TYPE) * - multipart (UPLOAD_MULTIPART_TYPE) * @param string|false $meta * @return string * @visible for testing */ public function getUploadType($meta) { if ($this->resumable) { return self::UPLOAD_RESUMABLE_TYPE; } if (false == $meta && $this->data) { return self::UPLOAD_MEDIA_TYPE; } return self::UPLOAD_MULTIPART_TYPE; } public function getResumeUri() { if (null === $this->resumeUri) { $this->resumeUri = $this->fetchResumeUri(); } return $this->resumeUri; } private function fetchResumeUri() { $body = $this->request->getBody(); $headers = [ 'content-type' => 'application/json; charset=UTF-8', 'content-length' => $body->getSize(), 'x-upload-content-type' => $this->mimeType, 'x-upload-content-length' => $this->size, 'expect' => '', ]; foreach ($headers as $key => $value) { $this->request = $this->request->withHeader($key, $value); } $response = $this->client->execute($this->request, false); $location = $response->getHeaderLine('location'); $code = $response->getStatusCode(); if (200 == $code && true == $location) { return $location; } $message = $code; $body = json_decode((string) $this->request->getBody(), true); if (isset($body['error']['errors'])) { $message .= ': '; foreach ($body['error']['errors'] as $error) { $message .= "{$error['domain']}, {$error['message']};"; } $message = rtrim($message, ';'); } $error = "Failed to start the resumable upload (HTTP {$message})"; $this->client->getLogger()->error($error); throw new GoogleException($error); } private function transformToUploadUrl() { $parts = parse_url((string) $this->request->getUri()); if (!isset($parts['path'])) { $parts['path'] = ''; } $parts['path'] = '/upload' . $parts['path']; $uri = Uri::fromParts($parts); $this->request = $this->request->withUri($uri); } public function setChunkSize($chunkSize) { $this->chunkSize = $chunkSize; } public function getRequest() { return $this->request; } } ================================================ FILE: lib/Google/src/Http/REST.php ================================================ |false|null $expectedClass * @param array $config * @param array $retryMap * @return mixed|T|null * @throws \Google\Service\Exception on server side error (ie: not authenticated, * invalid or malformed post body, invalid url) */ public static function execute( ClientInterface $client, RequestInterface $request, $expectedClass = null, $config = [], $retryMap = null ) { $runner = new Runner( $config, sprintf('%s %s', $request->getMethod(), (string)$request->getUri()), [self::class, 'doExecute'], [$client, $request, $expectedClass] ); if (null !== $retryMap) { $runner->setRetryMap($retryMap); } return $runner->run(); } /** * Executes a Psr\Http\Message\RequestInterface * * @template T * @param ClientInterface $client * @param RequestInterface $request * @param class-string|false|null $expectedClass * @return mixed|T|null * @throws \Google\Service\Exception on server side error (ie: not authenticated, * invalid or malformed post body, invalid url) */ public static function doExecute(ClientInterface $client, RequestInterface $request, $expectedClass = null) { try { $httpHandler = HttpHandlerFactory::build($client); $response = $httpHandler($request); } catch (RequestException $e) { // if Guzzle throws an exception, catch it and handle the response if (!$e->hasResponse()) { throw $e; } $response = $e->getResponse(); } return self::decodeHttpResponse($response, $request, $expectedClass); } /** * Decode an HTTP Response. * @static * * @template T * @param RequestInterface $response The http response to be decoded. * @param ResponseInterface $response * @param class-string|false|null $expectedClass * @return mixed|T|null * @throws \Google\Service\Exception */ public static function decodeHttpResponse( ResponseInterface $response, ?RequestInterface $request = null, $expectedClass = null ) { $code = $response->getStatusCode(); // retry strategy if (intVal($code) >= 400) { // if we errored out, it should be safe to grab the response body $body = (string)$response->getBody(); // Check if we received errors, and add those to the Exception for convenience throw new GoogleServiceException($body, $code, null, self::getResponseErrors($body)); } // Ensure we only pull the entire body into memory if the request is not // of media type $body = self::decodeBody($response, $request); if ($expectedClass = self::determineExpectedClass($expectedClass, $request)) { $json = json_decode($body, true); return new $expectedClass($json); } return $response; } private static function decodeBody(ResponseInterface $response, ?RequestInterface $request = null) { if (self::isAltMedia($request)) { // don't decode the body, it's probably a really long string return ''; } return (string)$response->getBody(); } private static function determineExpectedClass($expectedClass, ?RequestInterface $request = null) { // "false" is used to explicitly prevent an expected class from being returned if (false === $expectedClass) { return null; } // if we don't have a request, we just use what's passed in if (null === $request) { return $expectedClass; } // return what we have in the request header if one was not supplied return $expectedClass ?: $request->getHeaderLine('X-Php-Expected-Class'); } private static function getResponseErrors($body) { $json = json_decode($body, true); if (isset($json['error']['errors'])) { return $json['error']['errors']; } return null; } private static function isAltMedia(?RequestInterface $request = null) { if ($request && $qs = $request->getUri()->getQuery()) { parse_str($qs, $query); if (isset($query['alt']) && $query['alt'] == 'media') { return true; } } return false; } } ================================================ FILE: lib/Google/src/Model.php ================================================ mapTypes($array); } $this->gapiInit(); } /** * Getter that handles passthrough access to the data array, and lazy object creation. * @param string $key Property name. * @return mixed The value if any, or null. */ public function __get($key) { $keyType = $this->keyType($key); $keyDataType = $this->dataType($key); if ($keyType && !isset($this->processed[$key])) { if (isset($this->modelData[$key])) { $val = $this->modelData[$key]; } elseif ($keyDataType == 'array' || $keyDataType == 'map') { $val = []; } else { $val = null; } if ($this->isAssociativeArray($val)) { if ($keyDataType && 'map' == $keyDataType) { foreach ($val as $arrayKey => $arrayItem) { $this->modelData[$key][$arrayKey] = new $keyType($arrayItem); } } else { $this->modelData[$key] = new $keyType($val); } } elseif (is_array($val)) { $arrayObject = []; foreach ($val as $arrayIndex => $arrayItem) { $arrayObject[$arrayIndex] = new $keyType($arrayItem); } $this->modelData[$key] = $arrayObject; } $this->processed[$key] = true; } return isset($this->modelData[$key]) ? $this->modelData[$key] : null; } /** * Initialize this object's properties from an array. * * @param array $array Used to seed this object's properties. * @return void */ protected function mapTypes($array) { // Hard initialise simple types, lazy load more complex ones. foreach ($array as $key => $val) { if ($keyType = $this->keyType($key)) { $dataType = $this->dataType($key); if ($dataType == 'array' || $dataType == 'map') { $this->$key = []; foreach ($val as $itemKey => $itemVal) { if ($itemVal instanceof $keyType) { $this->{$key}[$itemKey] = $itemVal; } else { $this->{$key}[$itemKey] = new $keyType($itemVal); } } } elseif ($val instanceof $keyType) { $this->$key = $val; } else { $this->$key = new $keyType($val); } unset($array[$key]); } elseif (property_exists($this, $key)) { $this->$key = $val; unset($array[$key]); } elseif (property_exists($this, $camelKey = $this->camelCase($key))) { // This checks if property exists as camelCase, leaving it in array as snake_case // in case of backwards compatibility issues. $this->$camelKey = $val; } } $this->modelData = $array; } /** * Blank initialiser to be used in subclasses to do post-construction initialisation - this * avoids the need for subclasses to have to implement the variadics handling in their * constructors. */ protected function gapiInit() { return; } /** * Create a simplified object suitable for straightforward * conversion to JSON. This is relatively expensive * due to the usage of reflection, but shouldn't be called * a whole lot, and is the most straightforward way to filter. */ public function toSimpleObject() { $object = new stdClass(); // Process all other data. foreach ($this->modelData as $key => $val) { $result = $this->getSimpleValue($val); if ($result !== null) { $object->$key = $this->nullPlaceholderCheck($result); } } // Process all public properties. $reflect = new ReflectionObject($this); $props = $reflect->getProperties(ReflectionProperty::IS_PUBLIC); foreach ($props as $member) { $name = $member->getName(); $result = $this->getSimpleValue($this->$name); if ($result !== null) { $name = $this->getMappedName($name); $object->$name = $this->nullPlaceholderCheck($result); } } return $object; } /** * Handle different types of values, primarily * other objects and map and array data types. */ private function getSimpleValue($value) { if ($value instanceof Model) { return $value->toSimpleObject(); } elseif (is_array($value)) { $return = []; foreach ($value as $key => $a_value) { $a_value = $this->getSimpleValue($a_value); if ($a_value !== null) { $key = $this->getMappedName($key); $return[$key] = $this->nullPlaceholderCheck($a_value); } } return $return; } return $value; } /** * Check whether the value is the null placeholder and return true null. */ private function nullPlaceholderCheck($value) { if ($value === self::NULL_VALUE) { return null; } return $value; } /** * If there is an internal name mapping, use that. */ private function getMappedName($key) { if (isset($this->internal_gapi_mappings, $this->internal_gapi_mappings[$key])) { $key = $this->internal_gapi_mappings[$key]; } return $key; } /** * Returns true only if the array is associative. * @param array $array * @return bool True if the array is associative. */ protected function isAssociativeArray($array) { if (!is_array($array)) { return false; } $keys = array_keys($array); foreach ($keys as $key) { if (is_string($key)) { return true; } } return false; } /** * Verify if $obj is an array. * @throws \Google\Exception Thrown if $obj isn't an array. * @param array $obj Items that should be validated. * @param string $method Method expecting an array as an argument. */ public function assertIsArray($obj, $method) { if ($obj && !is_array($obj)) { throw new GoogleException( "Incorrect parameter type passed to $method(). Expected an array." ); } } /** @return bool */ #[\ReturnTypeWillChange] public function offsetExists($offset) { return isset($this->$offset) || isset($this->modelData[$offset]); } /** @return mixed */ #[\ReturnTypeWillChange] public function offsetGet($offset) { return isset($this->$offset) ? $this->$offset : $this->__get($offset); } /** @return void */ #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { if (property_exists($this, $offset)) { $this->$offset = $value; } else { $this->modelData[$offset] = $value; $this->processed[$offset] = true; } } /** @return void */ #[\ReturnTypeWillChange] public function offsetUnset($offset) { unset($this->modelData[$offset]); } protected function keyType($key) { $keyType = $key . "Type"; // ensure keyType is a valid class if (property_exists($this, $keyType) && $this->$keyType !== null && class_exists($this->$keyType)) { return $this->$keyType; } } protected function dataType($key) { $dataType = $key . "DataType"; if (property_exists($this, $dataType)) { return $this->$dataType; } } public function __isset($key) { return isset($this->modelData[$key]); } public function __unset($key) { unset($this->modelData[$key]); } /** * Convert a string to camelCase * @param string $value * @return string */ private function camelCase($value) { $value = ucwords(str_replace(['-', '_'], ' ', $value)); $value = str_replace(' ', '', $value); $value[0] = strtolower($value[0]); return $value; } } ================================================ FILE: lib/Google/src/Service/Exception.php ================================================ >|null $errors List of errors returned in an HTTP * response or null. Defaults to []. */ public function __construct( $message, $code = 0, ?Exception $previous = null, $errors = [] ) { if (version_compare(PHP_VERSION, '5.3.0') >= 0) { parent::__construct($message, $code, $previous); } else { parent::__construct($message, $code); } $this->errors = $errors; } /** * An example of the possible errors returned. * * [ * { * "domain": "global", * "reason": "authError", * "message": "Invalid Credentials", * "locationType": "header", * "location": "Authorization", * } * ] * * @return array>|null List of errors returned in an HTTP response or null. */ public function getErrors() { return $this->errors; } } ================================================ FILE: lib/Google/src/Service/README.md ================================================ # Google API Client Services Google API Client Service classes have been moved to the [google-api-php-client-services](https://github.com/google/google-api-php-client-services) repository. ================================================ FILE: lib/Google/src/Service/Resource.php ================================================ ['type' => 'string', 'location' => 'query'], 'fields' => ['type' => 'string', 'location' => 'query'], 'trace' => ['type' => 'string', 'location' => 'query'], 'userIp' => ['type' => 'string', 'location' => 'query'], 'quotaUser' => ['type' => 'string', 'location' => 'query'], 'data' => ['type' => 'string', 'location' => 'body'], 'mimeType' => ['type' => 'string', 'location' => 'header'], 'uploadType' => ['type' => 'string', 'location' => 'query'], 'mediaUpload' => ['type' => 'complex', 'location' => 'query'], 'prettyPrint' => ['type' => 'string', 'location' => 'query'], ]; /** @var string $rootUrlTemplate */ private $rootUrlTemplate; /** @var string $apiVersion */ protected $apiVersion; /** @var \Google\Client $client */ private $client; /** @var string $serviceName */ private $serviceName; /** @var string $servicePath */ private $servicePath; /** @var string $resourceName */ private $resourceName; /** @var array $methods */ private $methods; public function __construct($service, $serviceName, $resourceName, $resource) { $this->rootUrlTemplate = $service->rootUrlTemplate ?? $service->rootUrl; $this->client = $service->getClient(); $this->servicePath = $service->servicePath; $this->serviceName = $serviceName; $this->resourceName = $resourceName; $this->methods = is_array($resource) && isset($resource['methods']) ? $resource['methods'] : [$resourceName => $resource]; } /** * TODO: This function needs simplifying. * * @template T * @param string $name * @param array $arguments * @param class-string $expectedClass - optional, the expected class name * @return mixed|T|ResponseInterface|RequestInterface * @throws \Google\Exception */ public function call($name, $arguments, $expectedClass = null) { if (! isset($this->methods[$name])) { $this->client->getLogger()->error( 'Service method unknown', [ 'service' => $this->serviceName, 'resource' => $this->resourceName, 'method' => $name ] ); throw new GoogleException( "Unknown function: " . "{$this->serviceName}->{$this->resourceName}->{$name}()" ); } $method = $this->methods[$name]; $parameters = $arguments[0]; // postBody is a special case since it's not defined in the discovery // document as parameter, but we abuse the param entry for storing it. $postBody = null; if (isset($parameters['postBody'])) { if ($parameters['postBody'] instanceof Model) { // In the cases the post body is an existing object, we want // to use the smart method to create a simple object for // for JSONification. $parameters['postBody'] = $parameters['postBody']->toSimpleObject(); } elseif (is_object($parameters['postBody'])) { // If the post body is another kind of object, we will try and // wrangle it into a sensible format. $parameters['postBody'] = $this->convertToArrayAndStripNulls($parameters['postBody']); } $postBody = (array) $parameters['postBody']; unset($parameters['postBody']); } // TODO: optParams here probably should have been // handled already - this may well be redundant code. if (isset($parameters['optParams'])) { $optParams = $parameters['optParams']; unset($parameters['optParams']); $parameters = array_merge($parameters, $optParams); } if (!isset($method['parameters'])) { $method['parameters'] = []; } $method['parameters'] = array_merge( $this->stackParameters, $method['parameters'] ); foreach ($parameters as $key => $val) { if ($key != 'postBody' && !isset($method['parameters'][$key])) { $this->client->getLogger()->error( 'Service parameter unknown', [ 'service' => $this->serviceName, 'resource' => $this->resourceName, 'method' => $name, 'parameter' => $key ] ); throw new GoogleException("($name) unknown parameter: '$key'"); } } foreach ($method['parameters'] as $paramName => $paramSpec) { if ( isset($paramSpec['required']) && $paramSpec['required'] && ! isset($parameters[$paramName]) ) { $this->client->getLogger()->error( 'Service parameter missing', [ 'service' => $this->serviceName, 'resource' => $this->resourceName, 'method' => $name, 'parameter' => $paramName ] ); throw new GoogleException("($name) missing required param: '$paramName'"); } if (isset($parameters[$paramName])) { $value = $parameters[$paramName]; $parameters[$paramName] = $paramSpec; $parameters[$paramName]['value'] = $value; unset($parameters[$paramName]['required']); } else { // Ensure we don't pass nulls. unset($parameters[$paramName]); } } $this->client->getLogger()->info( 'Service Call', [ 'service' => $this->serviceName, 'resource' => $this->resourceName, 'method' => $name, 'arguments' => $parameters, ] ); // build the service uri $url = $this->createRequestUri($method['path'], $parameters); // NOTE: because we're creating the request by hand, // and because the service has a rootUrl property // the "base_uri" of the Http Client is not accounted for $request = new Request( $method['httpMethod'], $url, $postBody ? ['content-type' => 'application/json'] : [], $postBody ? json_encode($postBody) : '' ); // support uploads if (isset($parameters['data'])) { $mimeType = isset($parameters['mimeType']) ? $parameters['mimeType']['value'] : 'application/octet-stream'; $data = $parameters['data']['value']; $upload = new MediaFileUpload($this->client, $request, $mimeType, $data); // pull down the modified request $request = $upload->getRequest(); } // if this is a media type, we will return the raw response // rather than using an expected class if (isset($parameters['alt']) && $parameters['alt']['value'] == 'media') { $expectedClass = null; } // If the class which is extending from this one contains // an Api Version, add it to the header if ($this->apiVersion) { $request = $request ->withHeader('X-Goog-Api-Version', $this->apiVersion); } // if the client is marked for deferring, rather than // execute the request, return the response if ($this->client->shouldDefer()) { // @TODO find a better way to do this $request = $request ->withHeader('X-Php-Expected-Class', $expectedClass); return $request; } return $this->client->execute($request, $expectedClass); } protected function convertToArrayAndStripNulls($o) { $o = (array) $o; foreach ($o as $k => $v) { if ($v === null) { unset($o[$k]); } elseif (is_object($v) || is_array($v)) { $o[$k] = $this->convertToArrayAndStripNulls($o[$k]); } } return $o; } /** * Parse/expand request parameters and create a fully qualified * request uri. * @static * @param string $restPath * @param array $params * @return string $requestUrl */ public function createRequestUri($restPath, $params) { // Override the default servicePath address if the $restPath use a / if ('/' == substr($restPath, 0, 1)) { $requestUrl = substr($restPath, 1); } else { $requestUrl = $this->servicePath . $restPath; } if ($this->rootUrlTemplate) { // code for universe domain $rootUrl = str_replace('UNIVERSE_DOMAIN', $this->client->getUniverseDomain(), $this->rootUrlTemplate); // code for leading slash if ('/' !== substr($rootUrl, -1) && '/' !== substr($requestUrl, 0, 1)) { $requestUrl = '/' . $requestUrl; } $requestUrl = $rootUrl . $requestUrl; } $uriTemplateVars = []; $queryVars = []; foreach ($params as $paramName => $paramSpec) { if ($paramSpec['type'] == 'boolean') { $paramSpec['value'] = $paramSpec['value'] ? 'true' : 'false'; } if ($paramSpec['location'] == 'path') { $uriTemplateVars[$paramName] = $paramSpec['value']; } elseif ($paramSpec['location'] == 'query') { if (is_array($paramSpec['value'])) { foreach ($paramSpec['value'] as $value) { $queryVars[] = $paramName . '=' . rawurlencode(rawurldecode($value)); } } else { $queryVars[] = $paramName . '=' . rawurlencode(rawurldecode($paramSpec['value'])); } } } if (count($uriTemplateVars)) { $uriTemplateParser = new UriTemplate(); $requestUrl = $uriTemplateParser->parse($requestUrl, $uriTemplateVars); } if (count($queryVars)) { $requestUrl .= '?' . implode('&', $queryVars); } return $requestUrl; } } ================================================ FILE: lib/Google/src/Service.php ================================================ client = $clientOrConfig; } elseif (is_array($clientOrConfig)) { $this->client = new Client($clientOrConfig ?: []); } else { $errorMessage = 'constructor must be array or instance of Google\Client'; if (class_exists('TypeError')) { throw new TypeError($errorMessage); } trigger_error($errorMessage, E_USER_ERROR); } } /** * Return the associated Google\Client class. * @return \Google\Client */ public function getClient() { return $this->client; } /** * Create a new HTTP Batch handler for this service * * @return Batch */ public function createBatch() { return new Batch( $this->client, false, $this->rootUrlTemplate ?? $this->rootUrl, $this->batchPath ); } } ================================================ FILE: lib/Google/src/Task/Composer.php ================================================ getComposer(); $extra = $composer->getPackage()->getExtra(); $servicesToKeep = $extra['google/apiclient-services'] ?? []; if (empty($servicesToKeep)) { return; } $vendorDir = $composer->getConfig()->get('vendor-dir'); $serviceDir = sprintf( '%s/google/apiclient-services/src/Google/Service', $vendorDir ); if (!is_dir($serviceDir)) { // path for google/apiclient-services >= 0.200.0 $serviceDir = sprintf( '%s/google/apiclient-services/src', $vendorDir ); } self::verifyServicesToKeep($serviceDir, $servicesToKeep); $finder = self::getServicesToRemove($serviceDir, $servicesToKeep); $filesystem = $filesystem ?: new Filesystem(); $servicesToRemoveCount = $finder->count(); if (0 === $servicesToRemoveCount) { return; } $event->getIO()->write( sprintf('Removing %d google services', $servicesToRemoveCount) ); $pathsToRemove = iterator_to_array($finder); foreach ($pathsToRemove as $pathToRemove) { $realpath = $pathToRemove->getRealPath(); $filesystem->remove($realpath); $filesystem->remove($realpath . '.php'); } } /** * @throws InvalidArgumentException when the service doesn't exist */ private static function verifyServicesToKeep( $serviceDir, array $servicesToKeep ) { $finder = (new Finder()) ->directories() ->depth('== 0'); foreach ($servicesToKeep as $service) { if (!preg_match('/^[a-zA-Z0-9]*$/', $service)) { throw new InvalidArgumentException( sprintf( 'Invalid Google service name "%s"', $service ) ); } try { $finder->in($serviceDir . '/' . $service); } catch (InvalidArgumentException $e) { throw new InvalidArgumentException( sprintf( 'Google service "%s" does not exist or was removed previously', $service ) ); } } } private static function getServicesToRemove( $serviceDir, array $servicesToKeep ) { // find all files in the current directory return (new Finder()) ->directories() ->depth('== 0') ->in($serviceDir) ->exclude($servicesToKeep); } } ================================================ FILE: lib/Google/src/Task/Exception.php ================================================ self::TASK_RETRY_ALWAYS, '503' => self::TASK_RETRY_ALWAYS, 'rateLimitExceeded' => self::TASK_RETRY_ALWAYS, 'userRateLimitExceeded' => self::TASK_RETRY_ALWAYS, 6 => self::TASK_RETRY_ALWAYS, // CURLE_COULDNT_RESOLVE_HOST 7 => self::TASK_RETRY_ALWAYS, // CURLE_COULDNT_CONNECT 28 => self::TASK_RETRY_ALWAYS, // CURLE_OPERATION_TIMEOUTED 35 => self::TASK_RETRY_ALWAYS, // CURLE_SSL_CONNECT_ERROR 52 => self::TASK_RETRY_ALWAYS, // CURLE_GOT_NOTHING 'lighthouseError' => self::TASK_RETRY_NEVER ]; /** * Creates a new task runner with exponential backoff support. * * @param array $config The task runner config * @param string $name The name of the current task (used for logging) * @param callable $action The task to run and possibly retry * @param array $arguments The task arguments * @throws \Google\Task\Exception when misconfigured */ // @phpstan-ignore-next-line public function __construct( $config, $name, $action, array $arguments = [] ) { if (isset($config['initial_delay'])) { if ($config['initial_delay'] < 0) { throw new GoogleTaskException( 'Task configuration `initial_delay` must not be negative.' ); } $this->delay = $config['initial_delay']; } if (isset($config['max_delay'])) { if ($config['max_delay'] <= 0) { throw new GoogleTaskException( 'Task configuration `max_delay` must be greater than 0.' ); } $this->maxDelay = $config['max_delay']; } if (isset($config['factor'])) { if ($config['factor'] <= 0) { throw new GoogleTaskException( 'Task configuration `factor` must be greater than 0.' ); } $this->factor = $config['factor']; } if (isset($config['jitter'])) { if ($config['jitter'] <= 0) { throw new GoogleTaskException( 'Task configuration `jitter` must be greater than 0.' ); } $this->jitter = $config['jitter']; } if (isset($config['retries'])) { if ($config['retries'] < 0) { throw new GoogleTaskException( 'Task configuration `retries` must not be negative.' ); } $this->maxAttempts += $config['retries']; } if (!is_callable($action)) { throw new GoogleTaskException( 'Task argument `$action` must be a valid callable.' ); } $this->action = $action; $this->arguments = $arguments; } /** * Checks if a retry can be attempted. * * @return boolean */ public function canAttempt() { return $this->attempts < $this->maxAttempts; } /** * Runs the task and (if applicable) automatically retries when errors occur. * * @return mixed * @throws \Google\Service\Exception on failure when no retries are available. */ public function run() { while ($this->attempt()) { try { return call_user_func_array($this->action, $this->arguments); } catch (GoogleServiceException $exception) { $allowedRetries = $this->allowedRetries( $exception->getCode(), $exception->getErrors() ); if (!$this->canAttempt() || !$allowedRetries) { throw $exception; } if ($allowedRetries > 0) { $this->maxAttempts = min( $this->maxAttempts, $this->attempts + $allowedRetries ); } } } } /** * Runs a task once, if possible. This is useful for bypassing the `run()` * loop. * * NOTE: If this is not the first attempt, this function will sleep in * accordance to the backoff configurations before running the task. * * @return boolean */ public function attempt() { if (!$this->canAttempt()) { return false; } if ($this->attempts > 0) { $this->backOff(); } $this->attempts++; return true; } /** * Sleeps in accordance to the backoff configurations. */ private function backOff() { $delay = $this->getDelay(); usleep((int) ($delay * 1000000)); } /** * Gets the delay (in seconds) for the current backoff period. * * @return int */ private function getDelay() { $jitter = $this->getJitter(); $factor = $this->attempts > 1 ? $this->factor + $jitter : 1 + abs($jitter); return $this->delay = min($this->maxDelay, $this->delay * $factor); } /** * Gets the current jitter (random number between -$this->jitter and * $this->jitter). * * @return float */ private function getJitter() { return $this->jitter * 2 * mt_rand() / mt_getrandmax() - $this->jitter; } /** * Gets the number of times the associated task can be retried. * * NOTE: -1 is returned if the task can be retried indefinitely * * @return integer */ public function allowedRetries($code, $errors = []) { if (isset($this->retryMap[$code])) { return $this->retryMap[$code]; } if ( !empty($errors) && isset($errors[0]['reason'], $this->retryMap[$errors[0]['reason']]) ) { return $this->retryMap[$errors[0]['reason']]; } return 0; } public function setRetryMap($retryMap) { $this->retryMap = $retryMap; } } ================================================ FILE: lib/Google/src/Utils/UriTemplate.php ================================================ "reserved", "/" => "segments", "." => "dotprefix", "#" => "fragment", ";" => "semicolon", "?" => "form", "&" => "continuation" ]; /** * @var array * These are the characters which should not be URL encoded in reserved * strings. */ private $reserved = [ "=", ",", "!", "@", "|", ":", "/", "?", "#", "[", "]", '$', "&", "'", "(", ")", "*", "+", ";" ]; private $reservedEncoded = [ "%3D", "%2C", "%21", "%40", "%7C", "%3A", "%2F", "%3F", "%23", "%5B", "%5D", "%24", "%26", "%27", "%28", "%29", "%2A", "%2B", "%3B" ]; public function parse($string, array $parameters) { return $this->resolveNextSection($string, $parameters); } /** * This function finds the first matching {...} block and * executes the replacement. It then calls itself to find * subsequent blocks, if any. */ private function resolveNextSection($string, $parameters) { $start = strpos($string, "{"); if ($start === false) { return $string; } $end = strpos($string, "}"); if ($end === false) { return $string; } $string = $this->replace($string, $start, $end, $parameters); return $this->resolveNextSection($string, $parameters); } private function replace($string, $start, $end, $parameters) { // We know a data block will have {} round it, so we can strip that. $data = substr($string, $start + 1, $end - $start - 1); // If the first character is one of the reserved operators, it effects // the processing of the stream. if (isset($this->operators[$data[0]])) { $op = $this->operators[$data[0]]; $data = substr($data, 1); $prefix = ""; $prefix_on_missing = false; switch ($op) { case "reserved": // Reserved means certain characters should not be URL encoded $data = $this->replaceVars($data, $parameters, ",", null, true); break; case "fragment": // Comma separated with fragment prefix. Bare values only. $prefix = "#"; $prefix_on_missing = true; $data = $this->replaceVars($data, $parameters, ",", null, true); break; case "segments": // Slash separated data. Bare values only. $prefix = "/"; $data =$this->replaceVars($data, $parameters, "/"); break; case "dotprefix": // Dot separated data. Bare values only. $prefix = "."; $prefix_on_missing = true; $data = $this->replaceVars($data, $parameters, "."); break; case "semicolon": // Semicolon prefixed and separated. Uses the key name $prefix = ";"; $data = $this->replaceVars($data, $parameters, ";", "=", false, true, false); break; case "form": // Standard URL format. Uses the key name $prefix = "?"; $data = $this->replaceVars($data, $parameters, "&", "="); break; case "continuation": // Standard URL, but with leading ampersand. Uses key name. $prefix = "&"; $data = $this->replaceVars($data, $parameters, "&", "="); break; } // Add the initial prefix character if data is valid. if ($data || ($data !== false && $prefix_on_missing)) { $data = $prefix . $data; } } else { // If no operator we replace with the defaults. $data = $this->replaceVars($data, $parameters); } // This is chops out the {...} and replaces with the new section. return substr($string, 0, $start) . $data . substr($string, $end + 1); } private function replaceVars( $section, $parameters, $sep = ",", $combine = null, $reserved = false, $tag_empty = false, $combine_on_empty = true ) { if (strpos($section, ",") === false) { // If we only have a single value, we can immediately process. return $this->combine( $section, $parameters, $sep, $combine, $reserved, $tag_empty, $combine_on_empty ); } else { // If we have multiple values, we need to split and loop over them. // Each is treated individually, then glued together with the // separator character. $vars = explode(",", $section); return $this->combineList( $vars, $sep, $parameters, $combine, $reserved, false, // Never emit empty strings in multi-param replacements $combine_on_empty ); } } public function combine( $key, $parameters, $sep, $combine, $reserved, $tag_empty, $combine_on_empty ) { $length = false; $explode = false; $skip_final_combine = false; $value = false; // Check for length restriction. if (strpos($key, ":") !== false) { list($key, $length) = explode(":", $key); } // Check for explode parameter. if ($key[strlen($key) - 1] == "*") { $explode = true; $key = substr($key, 0, -1); $skip_final_combine = true; } // Define the list separator. $list_sep = $explode ? $sep : ","; if (isset($parameters[$key])) { $data_type = $this->getDataType($parameters[$key]); switch ($data_type) { case self::TYPE_SCALAR: $value = $this->getValue($parameters[$key], $length); break; case self::TYPE_LIST: $values = []; foreach ($parameters[$key] as $pkey => $pvalue) { $pvalue = $this->getValue($pvalue, $length); if ($combine && $explode) { $values[$pkey] = $key . $combine . $pvalue; } else { $values[$pkey] = $pvalue; } } $value = implode($list_sep, $values); if ($value == '') { return ''; } break; case self::TYPE_MAP: $values = []; foreach ($parameters[$key] as $pkey => $pvalue) { $pvalue = $this->getValue($pvalue, $length); if ($explode) { $pkey = $this->getValue($pkey, $length); $values[] = $pkey . "=" . $pvalue; // Explode triggers = combine. } else { $values[] = $pkey; $values[] = $pvalue; } } $value = implode($list_sep, $values); if ($value == '') { return false; } break; } } elseif ($tag_empty) { // If we are just indicating empty values with their key name, return that. return $key; } else { // Otherwise we can skip this variable due to not being defined. return false; } if ($reserved) { $value = str_replace($this->reservedEncoded, $this->reserved, $value); } // If we do not need to include the key name, we just return the raw // value. if (!$combine || $skip_final_combine) { return $value; } // Else we combine the key name: foo=bar, if value is not the empty string. return $key . ($value != '' || $combine_on_empty ? $combine . $value : ''); } /** * Return the type of a passed in value */ private function getDataType($data) { if (is_array($data)) { reset($data); if (key($data) !== 0) { return self::TYPE_MAP; } return self::TYPE_LIST; } return self::TYPE_SCALAR; } /** * Utility function that merges multiple combine calls * for multi-key templates. */ private function combineList( $vars, $sep, $parameters, $combine, $reserved, $tag_empty, $combine_on_empty ) { $ret = []; foreach ($vars as $var) { $response = $this->combine( $var, $parameters, $sep, $combine, $reserved, $tag_empty, $combine_on_empty ); if ($response === false) { continue; } $ret[] = $response; } return implode($sep, $ret); } /** * Utility function to encode and trim values */ private function getValue($value, $length) { if ($length) { $value = substr($value, 0, $length); } $value = rawurlencode($value); return $value; } } ================================================ FILE: lib/Google/src/aliases.php ================================================ 'Google_Client', 'Google\\Service' => 'Google_Service', 'Google\\AccessToken\\Revoke' => 'Google_AccessToken_Revoke', 'Google\\AccessToken\\Verify' => 'Google_AccessToken_Verify', 'Google\\Model' => 'Google_Model', 'Google\\Utils\\UriTemplate' => 'Google_Utils_UriTemplate', 'Google\\AuthHandler\\Guzzle6AuthHandler' => 'Google_AuthHandler_Guzzle6AuthHandler', 'Google\\AuthHandler\\Guzzle7AuthHandler' => 'Google_AuthHandler_Guzzle7AuthHandler', 'Google\\AuthHandler\\AuthHandlerFactory' => 'Google_AuthHandler_AuthHandlerFactory', 'Google\\Http\\Batch' => 'Google_Http_Batch', 'Google\\Http\\MediaFileUpload' => 'Google_Http_MediaFileUpload', 'Google\\Http\\REST' => 'Google_Http_REST', 'Google\\Task\\Retryable' => 'Google_Task_Retryable', 'Google\\Task\\Exception' => 'Google_Task_Exception', 'Google\\Task\\Runner' => 'Google_Task_Runner', 'Google\\Collection' => 'Google_Collection', 'Google\\Service\\Exception' => 'Google_Service_Exception', 'Google\\Service\\Resource' => 'Google_Service_Resource', 'Google\\Exception' => 'Google_Exception', ]; foreach ($classMap as $class => $alias) { class_alias($class, $alias); } /** * This class needs to be defined explicitly as scripts must be recognized by * the autoloader. */ class Google_Task_Composer extends \Google\Task\Composer { } /** @phpstan-ignore-next-line */ if (\false) { class Google_AccessToken_Revoke extends \Google\AccessToken\Revoke { } class Google_AccessToken_Verify extends \Google\AccessToken\Verify { } class Google_AuthHandler_AuthHandlerFactory extends \Google\AuthHandler\AuthHandlerFactory { } class Google_AuthHandler_Guzzle6AuthHandler extends \Google\AuthHandler\Guzzle6AuthHandler { } class Google_AuthHandler_Guzzle7AuthHandler extends \Google\AuthHandler\Guzzle7AuthHandler { } class Google_Client extends \Google\Client { } class Google_Collection extends \Google\Collection { } class Google_Exception extends \Google\Exception { } class Google_Http_Batch extends \Google\Http\Batch { } class Google_Http_MediaFileUpload extends \Google\Http\MediaFileUpload { } class Google_Http_REST extends \Google\Http\REST { } class Google_Model extends \Google\Model { } class Google_Service extends \Google\Service { } class Google_Service_Exception extends \Google\Service\Exception { } class Google_Service_Resource extends \Google\Service\Resource { } class Google_Task_Exception extends \Google\Task\Exception { } interface Google_Task_Retryable extends \Google\Task\Retryable { } class Google_Task_Runner extends \Google\Task\Runner { } class Google_Utils_UriTemplate extends \Google\Utils\UriTemplate { } } ================================================ FILE: lib/Google/vendor/autoload.php ================================================ 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', 'Composer\BinProxyWrapper')) ) { return include("phpvfscomposer://" . __DIR__ . '/..'.'/google/cloud-core/bin/google-cloud-batch'); } } return include __DIR__ . '/..'.'/google/cloud-core/bin/google-cloud-batch'; ================================================ FILE: lib/Google/vendor/brick/math/CHANGELOG.md ================================================ # Changelog All notable changes to this project will be documented in this file. ## [0.13.1](https://github.com/brick/math/releases/tag/0.13.1) - 2025-03-29 ✨ **Improvements** - `__toString()` methods of `BigInteger` and `BigDecimal` are now type-hinted as returning `numeric-string` instead of `string` (#90 by @vudaltsov) ## [0.13.0](https://github.com/brick/math/releases/tag/0.13.0) - 2025-03-03 💥 **Breaking changes** - `BigDecimal::ofUnscaledValue()` no longer throws an exception if the scale is negative - `MathException` now extends `RuntimeException` instead of `Exception`; this reverts the change introduced in version `0.11.0` (#82) ✨ **New features** - `BigDecimal::ofUnscaledValue()` allows a negative scale (and converts the values to create a zero scale number) ## [0.12.3](https://github.com/brick/math/releases/tag/0.12.3) - 2025-02-28 ✨ **New features** - `BigDecimal::getPrecision()` Returns the number of significant digits in a decimal number ## [0.12.2](https://github.com/brick/math/releases/tag/0.12.2) - 2025-02-26 ⚡️ **Performance improvements** - Division in `NativeCalculator` is now faster for small divisors, thanks to [@Izumi-kun](https://github.com/Izumi-kun) in [#87](https://github.com/brick/math/pull/87). 👌 **Improvements** - Add missing `RoundingNecessaryException` to the `@throws` annotation of `BigNumber::of()` ## [0.12.1](https://github.com/brick/math/releases/tag/0.12.1) - 2023-11-29 ⚡️ **Performance improvements** - `BigNumber::of()` is now faster, thanks to [@SebastienDug](https://github.com/SebastienDug) in [#77](https://github.com/brick/math/pull/77). ## [0.12.0](https://github.com/brick/math/releases/tag/0.12.0) - 2023-11-26 💥 **Breaking changes** - Minimum PHP version is now 8.1 - `RoundingMode` is now an `enum`; if you're type-hinting rounding modes, you need to type-hint against `RoundingMode` instead of `int` now - `BigNumber` classes do not implement the `Serializable` interface anymore (they use the [new custom object serialization mechanism](https://wiki.php.net/rfc/custom_object_serialization)) - The following breaking changes only affect you if you're creating your own `BigNumber` subclasses: - the return type of `BigNumber::of()` is now `static` - `BigNumber` has a new abstract method `from()` - all `public` and `protected` functions of `BigNumber` are now `final` ## [0.11.0](https://github.com/brick/math/releases/tag/0.11.0) - 2023-01-16 💥 **Breaking changes** - Minimum PHP version is now 8.0 - Methods accepting a union of types are now strongly typed* - `MathException` now extends `Exception` instead of `RuntimeException` * You may now run into type errors if you were passing `Stringable` objects to `of()` or any of the methods internally calling `of()`, with `strict_types` enabled. You can fix this by casting `Stringable` objects to `string` first. ## [0.10.2](https://github.com/brick/math/releases/tag/0.10.2) - 2022-08-11 👌 **Improvements** - `BigRational::toFloat()` now simplifies the fraction before performing division (#73) thanks to @olsavmic ## [0.10.1](https://github.com/brick/math/releases/tag/0.10.1) - 2022-08-02 ✨ **New features** - `BigInteger::gcdMultiple()` returns the GCD of multiple `BigInteger` numbers ## [0.10.0](https://github.com/brick/math/releases/tag/0.10.0) - 2022-06-18 💥 **Breaking changes** - Minimum PHP version is now 7.4 ## [0.9.3](https://github.com/brick/math/releases/tag/0.9.3) - 2021-08-15 🚀 **Compatibility with PHP 8.1** - Support for custom object serialization; this removes a warning on PHP 8.1 due to the `Serializable` interface being deprecated (#60) thanks @TRowbotham ## [0.9.2](https://github.com/brick/math/releases/tag/0.9.2) - 2021-01-20 🐛 **Bug fix** - Incorrect results could be returned when using the BCMath calculator, with a default scale set with `bcscale()`, on PHP >= 7.2 (#55). ## [0.9.1](https://github.com/brick/math/releases/tag/0.9.1) - 2020-08-19 ✨ **New features** - `BigInteger::not()` returns the bitwise `NOT` value 🐛 **Bug fixes** - `BigInteger::toBytes()` could return an incorrect binary representation for some numbers - The bitwise operations `and()`, `or()`, `xor()` on `BigInteger` could return an incorrect result when the GMP extension is not available ## [0.9.0](https://github.com/brick/math/releases/tag/0.9.0) - 2020-08-18 👌 **Improvements** - `BigNumber::of()` now accepts `.123` and `123.` formats, both of which return a `BigDecimal` 💥 **Breaking changes** - Deprecated method `BigInteger::powerMod()` has been removed - use `modPow()` instead - Deprecated method `BigInteger::parse()` has been removed - use `fromBase()` instead ## [0.8.17](https://github.com/brick/math/releases/tag/0.8.17) - 2020-08-19 🐛 **Bug fix** - `BigInteger::toBytes()` could return an incorrect binary representation for some numbers - The bitwise operations `and()`, `or()`, `xor()` on `BigInteger` could return an incorrect result when the GMP extension is not available ## [0.8.16](https://github.com/brick/math/releases/tag/0.8.16) - 2020-08-18 🚑 **Critical fix** - This version reintroduces the deprecated `BigInteger::parse()` method, that has been removed by mistake in version `0.8.9` and should have lasted for the whole `0.8` release cycle. ✨ **New features** - `BigInteger::modInverse()` calculates a modular multiplicative inverse - `BigInteger::fromBytes()` creates a `BigInteger` from a byte string - `BigInteger::toBytes()` converts a `BigInteger` to a byte string - `BigInteger::randomBits()` creates a pseudo-random `BigInteger` of a given bit length - `BigInteger::randomRange()` creates a pseudo-random `BigInteger` between two bounds 💩 **Deprecations** - `BigInteger::powerMod()` is now deprecated in favour of `modPow()` ## [0.8.15](https://github.com/brick/math/releases/tag/0.8.15) - 2020-04-15 🐛 **Fixes** - added missing `ext-json` requirement, due to `BigNumber` implementing `JsonSerializable` ⚡️ **Optimizations** - additional optimization in `BigInteger::remainder()` ## [0.8.14](https://github.com/brick/math/releases/tag/0.8.14) - 2020-02-18 ✨ **New features** - `BigInteger::getLowestSetBit()` returns the index of the rightmost one bit ## [0.8.13](https://github.com/brick/math/releases/tag/0.8.13) - 2020-02-16 ✨ **New features** - `BigInteger::isEven()` tests whether the number is even - `BigInteger::isOdd()` tests whether the number is odd - `BigInteger::testBit()` tests if a bit is set - `BigInteger::getBitLength()` returns the number of bits in the minimal representation of the number ## [0.8.12](https://github.com/brick/math/releases/tag/0.8.12) - 2020-02-03 🛠️ **Maintenance release** Classes are now annotated for better static analysis with [psalm](https://psalm.dev/). This is a maintenance release: no bug fixes, no new features, no breaking changes. ## [0.8.11](https://github.com/brick/math/releases/tag/0.8.11) - 2020-01-23 ✨ **New feature** `BigInteger::powerMod()` performs a power-with-modulo operation. Useful for crypto. ## [0.8.10](https://github.com/brick/math/releases/tag/0.8.10) - 2020-01-21 ✨ **New feature** `BigInteger::mod()` returns the **modulo** of two numbers. The *modulo* differs from the *remainder* when the signs of the operands are different. ## [0.8.9](https://github.com/brick/math/releases/tag/0.8.9) - 2020-01-08 ⚡️ **Performance improvements** A few additional optimizations in `BigInteger` and `BigDecimal` when one of the operands can be returned as is. Thanks to @tomtomsen in #24. ## [0.8.8](https://github.com/brick/math/releases/tag/0.8.8) - 2019-04-25 🐛 **Bug fixes** - `BigInteger::toBase()` could return an empty string for zero values (BCMath & Native calculators only, GMP calculator unaffected) ✨ **New features** - `BigInteger::toArbitraryBase()` converts a number to an arbitrary base, using a custom alphabet - `BigInteger::fromArbitraryBase()` converts a string in an arbitrary base, using a custom alphabet, back to a number These methods can be used as the foundation to convert strings between different bases/alphabets, using BigInteger as an intermediate representation. 💩 **Deprecations** - `BigInteger::parse()` is now deprecated in favour of `fromBase()` `BigInteger::fromBase()` works the same way as `parse()`, with 2 minor differences: - the `$base` parameter is required, it does not default to `10` - it throws a `NumberFormatException` instead of an `InvalidArgumentException` when the number is malformed ## [0.8.7](https://github.com/brick/math/releases/tag/0.8.7) - 2019-04-20 **Improvements** - Safer conversion from `float` when using custom locales - **Much faster** `NativeCalculator` implementation 🚀 You can expect **at least a 3x performance improvement** for common arithmetic operations when using the library on systems without GMP or BCMath; it gets exponentially faster on multiplications with a high number of digits. This is due to calculations now being performed on whole blocks of digits (the block size depending on the platform, 32-bit or 64-bit) instead of digit-by-digit as before. ## [0.8.6](https://github.com/brick/math/releases/tag/0.8.6) - 2019-04-11 **New method** `BigNumber::sum()` returns the sum of one or more numbers. ## [0.8.5](https://github.com/brick/math/releases/tag/0.8.5) - 2019-02-12 **Bug fix**: `of()` factory methods could fail when passing a `float` in environments using a `LC_NUMERIC` locale with a decimal separator other than `'.'` (#20). Thanks @manowark 👍 ## [0.8.4](https://github.com/brick/math/releases/tag/0.8.4) - 2018-12-07 **New method** `BigDecimal::sqrt()` calculates the square root of a decimal number, to a given scale. ## [0.8.3](https://github.com/brick/math/releases/tag/0.8.3) - 2018-12-06 **New method** `BigInteger::sqrt()` calculates the square root of a number (thanks @peter279k). **New exception** `NegativeNumberException` is thrown when calling `sqrt()` on a negative number. ## [0.8.2](https://github.com/brick/math/releases/tag/0.8.2) - 2018-11-08 **Performance update** - Further improvement of `toInt()` performance - `NativeCalculator` can now perform some multiplications more efficiently ## [0.8.1](https://github.com/brick/math/releases/tag/0.8.1) - 2018-11-07 Performance optimization of `toInt()` methods. ## [0.8.0](https://github.com/brick/math/releases/tag/0.8.0) - 2018-10-13 **Breaking changes** The following deprecated methods have been removed. Use the new method name instead: | Method removed | Replacement method | | --- | --- | | `BigDecimal::getIntegral()` | `BigDecimal::getIntegralPart()` | | `BigDecimal::getFraction()` | `BigDecimal::getFractionalPart()` | --- **New features** `BigInteger` has been augmented with 5 new methods for bitwise operations: | New method | Description | | --- | --- | | `and()` | performs a bitwise `AND` operation on two numbers | | `or()` | performs a bitwise `OR` operation on two numbers | | `xor()` | performs a bitwise `XOR` operation on two numbers | | `shiftedLeft()` | returns the number shifted left by a number of bits | | `shiftedRight()` | returns the number shifted right by a number of bits | Thanks to @DASPRiD 👍 ## [0.7.3](https://github.com/brick/math/releases/tag/0.7.3) - 2018-08-20 **New method:** `BigDecimal::hasNonZeroFractionalPart()` **Renamed/deprecated methods:** - `BigDecimal::getIntegral()` has been renamed to `getIntegralPart()` and is now deprecated - `BigDecimal::getFraction()` has been renamed to `getFractionalPart()` and is now deprecated ## [0.7.2](https://github.com/brick/math/releases/tag/0.7.2) - 2018-07-21 **Performance update** `BigInteger::parse()` and `toBase()` now use GMP's built-in base conversion features when available. ## [0.7.1](https://github.com/brick/math/releases/tag/0.7.1) - 2018-03-01 This is a maintenance release, no code has been changed. - When installed with `--no-dev`, the autoloader does not autoload tests anymore - Tests and other files unnecessary for production are excluded from the dist package This will help make installations more compact. ## [0.7.0](https://github.com/brick/math/releases/tag/0.7.0) - 2017-10-02 Methods renamed: - `BigNumber:sign()` has been renamed to `getSign()` - `BigDecimal::unscaledValue()` has been renamed to `getUnscaledValue()` - `BigDecimal::scale()` has been renamed to `getScale()` - `BigDecimal::integral()` has been renamed to `getIntegral()` - `BigDecimal::fraction()` has been renamed to `getFraction()` - `BigRational::numerator()` has been renamed to `getNumerator()` - `BigRational::denominator()` has been renamed to `getDenominator()` Classes renamed: - `ArithmeticException` has been renamed to `MathException` ## [0.6.2](https://github.com/brick/math/releases/tag/0.6.2) - 2017-10-02 The base class for all exceptions is now `MathException`. `ArithmeticException` has been deprecated, and will be removed in 0.7.0. ## [0.6.1](https://github.com/brick/math/releases/tag/0.6.1) - 2017-10-02 A number of methods have been renamed: - `BigNumber:sign()` is deprecated; use `getSign()` instead - `BigDecimal::unscaledValue()` is deprecated; use `getUnscaledValue()` instead - `BigDecimal::scale()` is deprecated; use `getScale()` instead - `BigDecimal::integral()` is deprecated; use `getIntegral()` instead - `BigDecimal::fraction()` is deprecated; use `getFraction()` instead - `BigRational::numerator()` is deprecated; use `getNumerator()` instead - `BigRational::denominator()` is deprecated; use `getDenominator()` instead The old methods will be removed in version 0.7.0. ## [0.6.0](https://github.com/brick/math/releases/tag/0.6.0) - 2017-08-25 - Minimum PHP version is now [7.1](https://gophp71.org/); for PHP 5.6 and PHP 7.0 support, use version `0.5` - Deprecated method `BigDecimal::withScale()` has been removed; use `toScale()` instead - Method `BigNumber::toInteger()` has been renamed to `toInt()` ## [0.5.4](https://github.com/brick/math/releases/tag/0.5.4) - 2016-10-17 `BigNumber` classes now implement [JsonSerializable](http://php.net/manual/en/class.jsonserializable.php). The JSON output is always a string. ## [0.5.3](https://github.com/brick/math/releases/tag/0.5.3) - 2016-03-31 This is a bugfix release. Dividing by a negative power of 1 with the same scale as the dividend could trigger an incorrect optimization which resulted in a wrong result. See #6. ## [0.5.2](https://github.com/brick/math/releases/tag/0.5.2) - 2015-08-06 The `$scale` parameter of `BigDecimal::dividedBy()` is now optional again. ## [0.5.1](https://github.com/brick/math/releases/tag/0.5.1) - 2015-07-05 **New method: `BigNumber::toScale()`** This allows to convert any `BigNumber` to a `BigDecimal` with a given scale, using rounding if necessary. ## [0.5.0](https://github.com/brick/math/releases/tag/0.5.0) - 2015-07-04 **New features** - Common `BigNumber` interface for all classes, with the following methods: - `sign()` and derived methods (`isZero()`, `isPositive()`, ...) - `compareTo()` and derived methods (`isEqualTo()`, `isGreaterThan()`, ...) that work across different `BigNumber` types - `toBigInteger()`, `toBigDecimal()`, `toBigRational`() conversion methods - `toInteger()` and `toFloat()` conversion methods to native types - Unified `of()` behaviour: every class now accepts any type of number, provided that it can be safely converted to the current type - New method: `BigDecimal::exactlyDividedBy()`; this method automatically computes the scale of the result, provided that the division yields a finite number of digits - New methods: `BigRational::quotient()` and `remainder()` - Fine-grained exceptions: `DivisionByZeroException`, `RoundingNecessaryException`, `NumberFormatException` - Factory methods `zero()`, `one()` and `ten()` available in all classes - Rounding mode reintroduced in `BigInteger::dividedBy()` This release also comes with many performance improvements. --- **Breaking changes** - `BigInteger`: - `getSign()` is renamed to `sign()` - `toString()` is renamed to `toBase()` - `BigInteger::dividedBy()` now throws an exception by default if the remainder is not zero; use `quotient()` to get the previous behaviour - `BigDecimal`: - `getSign()` is renamed to `sign()` - `getUnscaledValue()` is renamed to `unscaledValue()` - `getScale()` is renamed to `scale()` - `getIntegral()` is renamed to `integral()` - `getFraction()` is renamed to `fraction()` - `divideAndRemainder()` is renamed to `quotientAndRemainder()` - `dividedBy()` now takes a **mandatory** `$scale` parameter **before** the rounding mode - `toBigInteger()` does not accept a `$roundingMode` parameter anymore - `toBigRational()` does not simplify the fraction anymore; explicitly add `->simplified()` to get the previous behaviour - `BigRational`: - `getSign()` is renamed to `sign()` - `getNumerator()` is renamed to `numerator()` - `getDenominator()` is renamed to `denominator()` - `of()` is renamed to `nd()`, while `parse()` is renamed to `of()` - Miscellaneous: - `ArithmeticException` is moved to an `Exception\` sub-namespace - `of()` factory methods now throw `NumberFormatException` instead of `InvalidArgumentException` ## [0.4.3](https://github.com/brick/math/releases/tag/0.4.3) - 2016-03-31 Backport of two bug fixes from the 0.5 branch: - `BigInteger::parse()` did not always throw `InvalidArgumentException` as expected - Dividing by a negative power of 1 with the same scale as the dividend could trigger an incorrect optimization which resulted in a wrong result. See #6. ## [0.4.2](https://github.com/brick/math/releases/tag/0.4.2) - 2015-06-16 New method: `BigDecimal::stripTrailingZeros()` ## [0.4.1](https://github.com/brick/math/releases/tag/0.4.1) - 2015-06-12 Introducing a `BigRational` class, to perform calculations on fractions of any size. ## [0.4.0](https://github.com/brick/math/releases/tag/0.4.0) - 2015-06-12 Rounding modes have been removed from `BigInteger`, and are now a concept specific to `BigDecimal`. `BigInteger::dividedBy()` now always returns the quotient of the division. ## [0.3.5](https://github.com/brick/math/releases/tag/0.3.5) - 2016-03-31 Backport of two bug fixes from the 0.5 branch: - `BigInteger::parse()` did not always throw `InvalidArgumentException` as expected - Dividing by a negative power of 1 with the same scale as the dividend could trigger an incorrect optimization which resulted in a wrong result. See #6. ## [0.3.4](https://github.com/brick/math/releases/tag/0.3.4) - 2015-06-11 New methods: - `BigInteger::remainder()` returns the remainder of a division only - `BigInteger::gcd()` returns the greatest common divisor of two numbers ## [0.3.3](https://github.com/brick/math/releases/tag/0.3.3) - 2015-06-07 Fix `toString()` not handling negative numbers. ## [0.3.2](https://github.com/brick/math/releases/tag/0.3.2) - 2015-06-07 `BigInteger` and `BigDecimal` now have a `getSign()` method that returns: - `-1` if the number is negative - `0` if the number is zero - `1` if the number is positive ## [0.3.1](https://github.com/brick/math/releases/tag/0.3.1) - 2015-06-05 Minor performance improvements ## [0.3.0](https://github.com/brick/math/releases/tag/0.3.0) - 2015-06-04 The `$roundingMode` and `$scale` parameters have been swapped in `BigDecimal::dividedBy()`. ## [0.2.2](https://github.com/brick/math/releases/tag/0.2.2) - 2015-06-04 Stronger immutability guarantee for `BigInteger` and `BigDecimal`. So far, it would have been possible to break immutability of these classes by calling the `unserialize()` internal function. This release fixes that. ## [0.2.1](https://github.com/brick/math/releases/tag/0.2.1) - 2015-06-02 Added `BigDecimal::divideAndRemainder()` ## [0.2.0](https://github.com/brick/math/releases/tag/0.2.0) - 2015-05-22 - `min()` and `max()` do not accept an `array` anymore, but a variable number of parameters - **minimum PHP version is now 5.6** - continuous integration with PHP 7 ## [0.1.1](https://github.com/brick/math/releases/tag/0.1.1) - 2014-09-01 - Added `BigInteger::power()` - Added HHVM support ## [0.1.0](https://github.com/brick/math/releases/tag/0.1.0) - 2014-08-31 First beta release. ================================================ FILE: lib/Google/vendor/brick/math/LICENSE ================================================ The MIT License (MIT) Copyright (c) 2013-present Benjamin Morel 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. ================================================ FILE: lib/Google/vendor/brick/math/composer.json ================================================ { "name": "brick/math", "description": "Arbitrary-precision arithmetic library", "type": "library", "keywords": [ "Brick", "Math", "Mathematics", "Arbitrary-precision", "Arithmetic", "BigInteger", "BigDecimal", "BigRational", "BigNumber", "Bignum", "Decimal", "Rational", "Integer" ], "license": "MIT", "require": { "php": "^8.1" }, "require-dev": { "phpunit/phpunit": "^10.1", "php-coveralls/php-coveralls": "^2.2", "vimeo/psalm": "6.8.8" }, "autoload": { "psr-4": { "Brick\\Math\\": "src/" } }, "autoload-dev": { "psr-4": { "Brick\\Math\\Tests\\": "tests/" } } } ================================================ FILE: lib/Google/vendor/brick/math/psalm-baseline.xml ================================================ ================================================ FILE: lib/Google/vendor/brick/math/src/BigDecimal.php ================================================ value = $value; $this->scale = $scale; } /** * @psalm-pure */ #[Override] protected static function from(BigNumber $number): static { return $number->toBigDecimal(); } /** * Creates a BigDecimal from an unscaled value and a scale. * * Example: `(12345, 3)` will result in the BigDecimal `12.345`. * * @param BigNumber|int|float|string $value The unscaled value. Must be convertible to a BigInteger. * @param int $scale The scale of the number. If negative, the scale will be set to zero * and the unscaled value will be adjusted accordingly. * * @psalm-pure */ public static function ofUnscaledValue(BigNumber|int|float|string $value, int $scale = 0) : BigDecimal { $value = (string) BigInteger::of($value); if ($scale < 0) { if ($value !== '0') { $value .= \str_repeat('0', -$scale); } $scale = 0; } return new BigDecimal($value, $scale); } /** * Returns a BigDecimal representing zero, with a scale of zero. * * @psalm-pure */ public static function zero() : BigDecimal { /** * @psalm-suppress ImpureStaticVariable * @var BigDecimal|null $zero */ static $zero; if ($zero === null) { $zero = new BigDecimal('0'); } return $zero; } /** * Returns a BigDecimal representing one, with a scale of zero. * * @psalm-pure */ public static function one() : BigDecimal { /** * @psalm-suppress ImpureStaticVariable * @var BigDecimal|null $one */ static $one; if ($one === null) { $one = new BigDecimal('1'); } return $one; } /** * Returns a BigDecimal representing ten, with a scale of zero. * * @psalm-pure */ public static function ten() : BigDecimal { /** * @psalm-suppress ImpureStaticVariable * @var BigDecimal|null $ten */ static $ten; if ($ten === null) { $ten = new BigDecimal('10'); } return $ten; } /** * Returns the sum of this number and the given one. * * The result has a scale of `max($this->scale, $that->scale)`. * * @param BigNumber|int|float|string $that The number to add. Must be convertible to a BigDecimal. * * @throws MathException If the number is not valid, or is not convertible to a BigDecimal. */ public function plus(BigNumber|int|float|string $that) : BigDecimal { $that = BigDecimal::of($that); if ($that->value === '0' && $that->scale <= $this->scale) { return $this; } if ($this->value === '0' && $this->scale <= $that->scale) { return $that; } [$a, $b] = $this->scaleValues($this, $that); $value = Calculator::get()->add($a, $b); $scale = $this->scale > $that->scale ? $this->scale : $that->scale; return new BigDecimal($value, $scale); } /** * Returns the difference of this number and the given one. * * The result has a scale of `max($this->scale, $that->scale)`. * * @param BigNumber|int|float|string $that The number to subtract. Must be convertible to a BigDecimal. * * @throws MathException If the number is not valid, or is not convertible to a BigDecimal. */ public function minus(BigNumber|int|float|string $that) : BigDecimal { $that = BigDecimal::of($that); if ($that->value === '0' && $that->scale <= $this->scale) { return $this; } [$a, $b] = $this->scaleValues($this, $that); $value = Calculator::get()->sub($a, $b); $scale = $this->scale > $that->scale ? $this->scale : $that->scale; return new BigDecimal($value, $scale); } /** * Returns the product of this number and the given one. * * The result has a scale of `$this->scale + $that->scale`. * * @param BigNumber|int|float|string $that The multiplier. Must be convertible to a BigDecimal. * * @throws MathException If the multiplier is not a valid number, or is not convertible to a BigDecimal. */ public function multipliedBy(BigNumber|int|float|string $that) : BigDecimal { $that = BigDecimal::of($that); if ($that->value === '1' && $that->scale === 0) { return $this; } if ($this->value === '1' && $this->scale === 0) { return $that; } $value = Calculator::get()->mul($this->value, $that->value); $scale = $this->scale + $that->scale; return new BigDecimal($value, $scale); } /** * Returns the result of the division of this number by the given one, at the given scale. * * @param BigNumber|int|float|string $that The divisor. * @param int|null $scale The desired scale, or null to use the scale of this number. * @param RoundingMode $roundingMode An optional rounding mode, defaults to UNNECESSARY. * * @throws \InvalidArgumentException If the scale or rounding mode is invalid. * @throws MathException If the number is invalid, is zero, or rounding was necessary. */ public function dividedBy(BigNumber|int|float|string $that, ?int $scale = null, RoundingMode $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal { $that = BigDecimal::of($that); if ($that->isZero()) { throw DivisionByZeroException::divisionByZero(); } if ($scale === null) { $scale = $this->scale; } elseif ($scale < 0) { throw new \InvalidArgumentException('Scale cannot be negative.'); } if ($that->value === '1' && $that->scale === 0 && $scale === $this->scale) { return $this; } $p = $this->valueWithMinScale($that->scale + $scale); $q = $that->valueWithMinScale($this->scale - $scale); $result = Calculator::get()->divRound($p, $q, $roundingMode); return new BigDecimal($result, $scale); } /** * Returns the exact result of the division of this number by the given one. * * The scale of the result is automatically calculated to fit all the fraction digits. * * @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigDecimal. * * @throws MathException If the divisor is not a valid number, is not convertible to a BigDecimal, is zero, * or the result yields an infinite number of digits. */ public function exactlyDividedBy(BigNumber|int|float|string $that) : BigDecimal { $that = BigDecimal::of($that); if ($that->value === '0') { throw DivisionByZeroException::divisionByZero(); } [, $b] = $this->scaleValues($this, $that); $d = \rtrim($b, '0'); $scale = \strlen($b) - \strlen($d); $calculator = Calculator::get(); foreach ([5, 2] as $prime) { for (;;) { $lastDigit = (int) $d[-1]; if ($lastDigit % $prime !== 0) { break; } $d = $calculator->divQ($d, (string) $prime); $scale++; } } return $this->dividedBy($that, $scale)->stripTrailingZeros(); } /** * Returns this number exponentiated to the given value. * * The result has a scale of `$this->scale * $exponent`. * * @throws \InvalidArgumentException If the exponent is not in the range 0 to 1,000,000. */ public function power(int $exponent) : BigDecimal { if ($exponent === 0) { return BigDecimal::one(); } if ($exponent === 1) { return $this; } if ($exponent < 0 || $exponent > Calculator::MAX_POWER) { throw new \InvalidArgumentException(\sprintf( 'The exponent %d is not in the range 0 to %d.', $exponent, Calculator::MAX_POWER )); } return new BigDecimal(Calculator::get()->pow($this->value, $exponent), $this->scale * $exponent); } /** * Returns the quotient of the division of this number by the given one. * * The quotient has a scale of `0`. * * @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigDecimal. * * @throws MathException If the divisor is not a valid decimal number, or is zero. */ public function quotient(BigNumber|int|float|string $that) : BigDecimal { $that = BigDecimal::of($that); if ($that->isZero()) { throw DivisionByZeroException::divisionByZero(); } $p = $this->valueWithMinScale($that->scale); $q = $that->valueWithMinScale($this->scale); $quotient = Calculator::get()->divQ($p, $q); return new BigDecimal($quotient, 0); } /** * Returns the remainder of the division of this number by the given one. * * The remainder has a scale of `max($this->scale, $that->scale)`. * * @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigDecimal. * * @throws MathException If the divisor is not a valid decimal number, or is zero. */ public function remainder(BigNumber|int|float|string $that) : BigDecimal { $that = BigDecimal::of($that); if ($that->isZero()) { throw DivisionByZeroException::divisionByZero(); } $p = $this->valueWithMinScale($that->scale); $q = $that->valueWithMinScale($this->scale); $remainder = Calculator::get()->divR($p, $q); $scale = $this->scale > $that->scale ? $this->scale : $that->scale; return new BigDecimal($remainder, $scale); } /** * Returns the quotient and remainder of the division of this number by the given one. * * The quotient has a scale of `0`, and the remainder has a scale of `max($this->scale, $that->scale)`. * * @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigDecimal. * * @return BigDecimal[] An array containing the quotient and the remainder. * * @psalm-return array{BigDecimal, BigDecimal} * * @throws MathException If the divisor is not a valid decimal number, or is zero. */ public function quotientAndRemainder(BigNumber|int|float|string $that) : array { $that = BigDecimal::of($that); if ($that->isZero()) { throw DivisionByZeroException::divisionByZero(); } $p = $this->valueWithMinScale($that->scale); $q = $that->valueWithMinScale($this->scale); [$quotient, $remainder] = Calculator::get()->divQR($p, $q); $scale = $this->scale > $that->scale ? $this->scale : $that->scale; $quotient = new BigDecimal($quotient, 0); $remainder = new BigDecimal($remainder, $scale); return [$quotient, $remainder]; } /** * Returns the square root of this number, rounded down to the given number of decimals. * * @throws \InvalidArgumentException If the scale is negative. * @throws NegativeNumberException If this number is negative. */ public function sqrt(int $scale) : BigDecimal { if ($scale < 0) { throw new \InvalidArgumentException('Scale cannot be negative.'); } if ($this->value === '0') { return new BigDecimal('0', $scale); } if ($this->value[0] === '-') { throw new NegativeNumberException('Cannot calculate the square root of a negative number.'); } $value = $this->value; $addDigits = 2 * $scale - $this->scale; if ($addDigits > 0) { // add zeros $value .= \str_repeat('0', $addDigits); } elseif ($addDigits < 0) { // trim digits if (-$addDigits >= \strlen($this->value)) { // requesting a scale too low, will always yield a zero result return new BigDecimal('0', $scale); } $value = \substr($value, 0, $addDigits); } $value = Calculator::get()->sqrt($value); return new BigDecimal($value, $scale); } /** * Returns a copy of this BigDecimal with the decimal point moved $n places to the left. */ public function withPointMovedLeft(int $n) : BigDecimal { if ($n === 0) { return $this; } if ($n < 0) { return $this->withPointMovedRight(-$n); } return new BigDecimal($this->value, $this->scale + $n); } /** * Returns a copy of this BigDecimal with the decimal point moved $n places to the right. */ public function withPointMovedRight(int $n) : BigDecimal { if ($n === 0) { return $this; } if ($n < 0) { return $this->withPointMovedLeft(-$n); } $value = $this->value; $scale = $this->scale - $n; if ($scale < 0) { if ($value !== '0') { $value .= \str_repeat('0', -$scale); } $scale = 0; } return new BigDecimal($value, $scale); } /** * Returns a copy of this BigDecimal with any trailing zeros removed from the fractional part. */ public function stripTrailingZeros() : BigDecimal { if ($this->scale === 0) { return $this; } $trimmedValue = \rtrim($this->value, '0'); if ($trimmedValue === '') { return BigDecimal::zero(); } $trimmableZeros = \strlen($this->value) - \strlen($trimmedValue); if ($trimmableZeros === 0) { return $this; } if ($trimmableZeros > $this->scale) { $trimmableZeros = $this->scale; } $value = \substr($this->value, 0, -$trimmableZeros); $scale = $this->scale - $trimmableZeros; return new BigDecimal($value, $scale); } /** * Returns the absolute value of this number. */ public function abs() : BigDecimal { return $this->isNegative() ? $this->negated() : $this; } /** * Returns the negated value of this number. */ public function negated() : BigDecimal { return new BigDecimal(Calculator::get()->neg($this->value), $this->scale); } #[Override] public function compareTo(BigNumber|int|float|string $that) : int { $that = BigNumber::of($that); if ($that instanceof BigInteger) { $that = $that->toBigDecimal(); } if ($that instanceof BigDecimal) { [$a, $b] = $this->scaleValues($this, $that); return Calculator::get()->cmp($a, $b); } return - $that->compareTo($this); } #[Override] public function getSign() : int { return ($this->value === '0') ? 0 : (($this->value[0] === '-') ? -1 : 1); } public function getUnscaledValue() : BigInteger { return self::newBigInteger($this->value); } public function getScale() : int { return $this->scale; } /** * Returns the number of significant digits in the number. * * This is the number of digits to both sides of the decimal point, stripped of leading zeros. * The sign has no impact on the result. * * Examples: * 0 => 0 * 0.0 => 0 * 123 => 3 * 123.456 => 6 * 0.00123 => 3 * 0.0012300 => 5 */ public function getPrecision(): int { $value = $this->value; if ($value === '0') { return 0; } $length = \strlen($value); return ($value[0] === '-') ? $length - 1 : $length; } /** * Returns a string representing the integral part of this decimal number. * * Example: `-123.456` => `-123`. */ public function getIntegralPart() : string { if ($this->scale === 0) { return $this->value; } $value = $this->getUnscaledValueWithLeadingZeros(); return \substr($value, 0, -$this->scale); } /** * Returns a string representing the fractional part of this decimal number. * * If the scale is zero, an empty string is returned. * * Examples: `-123.456` => '456', `123` => ''. */ public function getFractionalPart() : string { if ($this->scale === 0) { return ''; } $value = $this->getUnscaledValueWithLeadingZeros(); return \substr($value, -$this->scale); } /** * Returns whether this decimal number has a non-zero fractional part. */ public function hasNonZeroFractionalPart() : bool { return $this->getFractionalPart() !== \str_repeat('0', $this->scale); } #[Override] public function toBigInteger() : BigInteger { $zeroScaleDecimal = $this->scale === 0 ? $this : $this->dividedBy(1, 0); return self::newBigInteger($zeroScaleDecimal->value); } #[Override] public function toBigDecimal() : BigDecimal { return $this; } #[Override] public function toBigRational() : BigRational { $numerator = self::newBigInteger($this->value); $denominator = self::newBigInteger('1' . \str_repeat('0', $this->scale)); return self::newBigRational($numerator, $denominator, false); } #[Override] public function toScale(int $scale, RoundingMode $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal { if ($scale === $this->scale) { return $this; } return $this->dividedBy(BigDecimal::one(), $scale, $roundingMode); } #[Override] public function toInt() : int { return $this->toBigInteger()->toInt(); } #[Override] public function toFloat() : float { return (float) (string) $this; } /** * @return numeric-string */ #[Override] public function __toString() : string { if ($this->scale === 0) { /** @var numeric-string */ return $this->value; } $value = $this->getUnscaledValueWithLeadingZeros(); /** @var numeric-string */ return \substr($value, 0, -$this->scale) . '.' . \substr($value, -$this->scale); } /** * This method is required for serializing the object and SHOULD NOT be accessed directly. * * @internal * * @return array{value: string, scale: int} */ public function __serialize(): array { return ['value' => $this->value, 'scale' => $this->scale]; } /** * This method is only here to allow unserializing the object and cannot be accessed directly. * * @internal * @psalm-suppress RedundantPropertyInitializationCheck * * @param array{value: string, scale: int} $data * * @throws \LogicException */ public function __unserialize(array $data): void { if (isset($this->value)) { throw new \LogicException('__unserialize() is an internal function, it must not be called directly.'); } $this->value = $data['value']; $this->scale = $data['scale']; } /** * Puts the internal values of the given decimal numbers on the same scale. * * @return array{string, string} The scaled integer values of $x and $y. */ private function scaleValues(BigDecimal $x, BigDecimal $y) : array { $a = $x->value; $b = $y->value; if ($b !== '0' && $x->scale > $y->scale) { $b .= \str_repeat('0', $x->scale - $y->scale); } elseif ($a !== '0' && $x->scale < $y->scale) { $a .= \str_repeat('0', $y->scale - $x->scale); } return [$a, $b]; } private function valueWithMinScale(int $scale) : string { $value = $this->value; if ($this->value !== '0' && $scale > $this->scale) { $value .= \str_repeat('0', $scale - $this->scale); } return $value; } /** * Adds leading zeros if necessary to the unscaled value to represent the full decimal number. */ private function getUnscaledValueWithLeadingZeros() : string { $value = $this->value; $targetLength = $this->scale + 1; $negative = ($value[0] === '-'); $length = \strlen($value); if ($negative) { $length--; } if ($length >= $targetLength) { return $this->value; } if ($negative) { $value = \substr($value, 1); } $value = \str_pad($value, $targetLength, '0', STR_PAD_LEFT); if ($negative) { $value = '-' . $value; } return $value; } } ================================================ FILE: lib/Google/vendor/brick/math/src/BigInteger.php ================================================ value = $value; } /** * @psalm-pure */ #[Override] protected static function from(BigNumber $number): static { return $number->toBigInteger(); } /** * Creates a number from a string in a given base. * * The string can optionally be prefixed with the `+` or `-` sign. * * Bases greater than 36 are not supported by this method, as there is no clear consensus on which of the lowercase * or uppercase characters should come first. Instead, this method accepts any base up to 36, and does not * differentiate lowercase and uppercase characters, which are considered equal. * * For bases greater than 36, and/or custom alphabets, use the fromArbitraryBase() method. * * @param string $number The number to convert, in the given base. * @param int $base The base of the number, between 2 and 36. * * @throws NumberFormatException If the number is empty, or contains invalid chars for the given base. * @throws \InvalidArgumentException If the base is out of range. * * @psalm-pure */ public static function fromBase(string $number, int $base) : BigInteger { if ($number === '') { throw new NumberFormatException('The number cannot be empty.'); } if ($base < 2 || $base > 36) { throw new \InvalidArgumentException(\sprintf('Base %d is not in range 2 to 36.', $base)); } if ($number[0] === '-') { $sign = '-'; $number = \substr($number, 1); } elseif ($number[0] === '+') { $sign = ''; $number = \substr($number, 1); } else { $sign = ''; } if ($number === '') { throw new NumberFormatException('The number cannot be empty.'); } $number = \ltrim($number, '0'); if ($number === '') { // The result will be the same in any base, avoid further calculation. return BigInteger::zero(); } if ($number === '1') { // The result will be the same in any base, avoid further calculation. return new BigInteger($sign . '1'); } $pattern = '/[^' . \substr(Calculator::ALPHABET, 0, $base) . ']/'; if (\preg_match($pattern, \strtolower($number), $matches) === 1) { throw new NumberFormatException(\sprintf('"%s" is not a valid character in base %d.', $matches[0], $base)); } if ($base === 10) { // The number is usable as is, avoid further calculation. return new BigInteger($sign . $number); } $result = Calculator::get()->fromBase($number, $base); return new BigInteger($sign . $result); } /** * Parses a string containing an integer in an arbitrary base, using a custom alphabet. * * Because this method accepts an alphabet with any character, including dash, it does not handle negative numbers. * * @param string $number The number to parse. * @param string $alphabet The alphabet, for example '01' for base 2, or '01234567' for base 8. * * @throws NumberFormatException If the given number is empty or contains invalid chars for the given alphabet. * @throws \InvalidArgumentException If the alphabet does not contain at least 2 chars. * * @psalm-pure */ public static function fromArbitraryBase(string $number, string $alphabet) : BigInteger { if ($number === '') { throw new NumberFormatException('The number cannot be empty.'); } $base = \strlen($alphabet); if ($base < 2) { throw new \InvalidArgumentException('The alphabet must contain at least 2 chars.'); } $pattern = '/[^' . \preg_quote($alphabet, '/') . ']/'; if (\preg_match($pattern, $number, $matches) === 1) { throw NumberFormatException::charNotInAlphabet($matches[0]); } $number = Calculator::get()->fromArbitraryBase($number, $alphabet, $base); return new BigInteger($number); } /** * Translates a string of bytes containing the binary representation of a BigInteger into a BigInteger. * * The input string is assumed to be in big-endian byte-order: the most significant byte is in the zeroth element. * * If `$signed` is true, the input is assumed to be in two's-complement representation, and the leading bit is * interpreted as a sign bit. If `$signed` is false, the input is interpreted as an unsigned number, and the * resulting BigInteger will always be positive or zero. * * This method can be used to retrieve a number exported by `toBytes()`, as long as the `$signed` flags match. * * @param string $value The byte string. * @param bool $signed Whether to interpret as a signed number in two's-complement representation with a leading * sign bit. * * @throws NumberFormatException If the string is empty. */ public static function fromBytes(string $value, bool $signed = true) : BigInteger { if ($value === '') { throw new NumberFormatException('The byte string must not be empty.'); } $twosComplement = false; if ($signed) { $x = \ord($value[0]); if (($twosComplement = ($x >= 0x80))) { $value = ~$value; } } $number = self::fromBase(\bin2hex($value), 16); if ($twosComplement) { return $number->plus(1)->negated(); } return $number; } /** * Generates a pseudo-random number in the range 0 to 2^numBits - 1. * * Using the default random bytes generator, this method is suitable for cryptographic use. * * @psalm-param (callable(int): string)|null $randomBytesGenerator * * @param int $numBits The number of bits. * @param callable|null $randomBytesGenerator A function that accepts a number of bytes as an integer, and returns a * string of random bytes of the given length. Defaults to the * `random_bytes()` function. * * @throws \InvalidArgumentException If $numBits is negative. */ public static function randomBits(int $numBits, ?callable $randomBytesGenerator = null) : BigInteger { if ($numBits < 0) { throw new \InvalidArgumentException('The number of bits cannot be negative.'); } if ($numBits === 0) { return BigInteger::zero(); } if ($randomBytesGenerator === null) { $randomBytesGenerator = random_bytes(...); } /** @var int<1, max> $byteLength */ $byteLength = \intdiv($numBits - 1, 8) + 1; $extraBits = ($byteLength * 8 - $numBits); $bitmask = \chr(0xFF >> $extraBits); $randomBytes = $randomBytesGenerator($byteLength); $randomBytes[0] = $randomBytes[0] & $bitmask; return self::fromBytes($randomBytes, false); } /** * Generates a pseudo-random number between `$min` and `$max`. * * Using the default random bytes generator, this method is suitable for cryptographic use. * * @psalm-param (callable(int): string)|null $randomBytesGenerator * * @param BigNumber|int|float|string $min The lower bound. Must be convertible to a BigInteger. * @param BigNumber|int|float|string $max The upper bound. Must be convertible to a BigInteger. * @param callable|null $randomBytesGenerator A function that accepts a number of bytes as an integer, * and returns a string of random bytes of the given length. * Defaults to the `random_bytes()` function. * * @throws MathException If one of the parameters cannot be converted to a BigInteger, * or `$min` is greater than `$max`. */ public static function randomRange( BigNumber|int|float|string $min, BigNumber|int|float|string $max, ?callable $randomBytesGenerator = null ) : BigInteger { $min = BigInteger::of($min); $max = BigInteger::of($max); if ($min->isGreaterThan($max)) { throw new MathException('$min cannot be greater than $max.'); } if ($min->isEqualTo($max)) { return $min; } $diff = $max->minus($min); $bitLength = $diff->getBitLength(); // try until the number is in range (50% to 100% chance of success) do { $randomNumber = self::randomBits($bitLength, $randomBytesGenerator); } while ($randomNumber->isGreaterThan($diff)); return $randomNumber->plus($min); } /** * Returns a BigInteger representing zero. * * @psalm-pure */ public static function zero() : BigInteger { /** * @psalm-suppress ImpureStaticVariable * @var BigInteger|null $zero */ static $zero; if ($zero === null) { $zero = new BigInteger('0'); } return $zero; } /** * Returns a BigInteger representing one. * * @psalm-pure */ public static function one() : BigInteger { /** * @psalm-suppress ImpureStaticVariable * @var BigInteger|null $one */ static $one; if ($one === null) { $one = new BigInteger('1'); } return $one; } /** * Returns a BigInteger representing ten. * * @psalm-pure */ public static function ten() : BigInteger { /** * @psalm-suppress ImpureStaticVariable * @var BigInteger|null $ten */ static $ten; if ($ten === null) { $ten = new BigInteger('10'); } return $ten; } public static function gcdMultiple(BigInteger $a, BigInteger ...$n): BigInteger { $result = $a; foreach ($n as $next) { $result = $result->gcd($next); if ($result->isEqualTo(1)) { return $result; } } return $result; } /** * Returns the sum of this number and the given one. * * @param BigNumber|int|float|string $that The number to add. Must be convertible to a BigInteger. * * @throws MathException If the number is not valid, or is not convertible to a BigInteger. */ public function plus(BigNumber|int|float|string $that) : BigInteger { $that = BigInteger::of($that); if ($that->value === '0') { return $this; } if ($this->value === '0') { return $that; } $value = Calculator::get()->add($this->value, $that->value); return new BigInteger($value); } /** * Returns the difference of this number and the given one. * * @param BigNumber|int|float|string $that The number to subtract. Must be convertible to a BigInteger. * * @throws MathException If the number is not valid, or is not convertible to a BigInteger. */ public function minus(BigNumber|int|float|string $that) : BigInteger { $that = BigInteger::of($that); if ($that->value === '0') { return $this; } $value = Calculator::get()->sub($this->value, $that->value); return new BigInteger($value); } /** * Returns the product of this number and the given one. * * @param BigNumber|int|float|string $that The multiplier. Must be convertible to a BigInteger. * * @throws MathException If the multiplier is not a valid number, or is not convertible to a BigInteger. */ public function multipliedBy(BigNumber|int|float|string $that) : BigInteger { $that = BigInteger::of($that); if ($that->value === '1') { return $this; } if ($this->value === '1') { return $that; } $value = Calculator::get()->mul($this->value, $that->value); return new BigInteger($value); } /** * Returns the result of the division of this number by the given one. * * @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigInteger. * @param RoundingMode $roundingMode An optional rounding mode, defaults to UNNECESSARY. * * @throws MathException If the divisor is not a valid number, is not convertible to a BigInteger, is zero, * or RoundingMode::UNNECESSARY is used and the remainder is not zero. */ public function dividedBy(BigNumber|int|float|string $that, RoundingMode $roundingMode = RoundingMode::UNNECESSARY) : BigInteger { $that = BigInteger::of($that); if ($that->value === '1') { return $this; } if ($that->value === '0') { throw DivisionByZeroException::divisionByZero(); } $result = Calculator::get()->divRound($this->value, $that->value, $roundingMode); return new BigInteger($result); } /** * Returns this number exponentiated to the given value. * * @throws \InvalidArgumentException If the exponent is not in the range 0 to 1,000,000. */ public function power(int $exponent) : BigInteger { if ($exponent === 0) { return BigInteger::one(); } if ($exponent === 1) { return $this; } if ($exponent < 0 || $exponent > Calculator::MAX_POWER) { throw new \InvalidArgumentException(\sprintf( 'The exponent %d is not in the range 0 to %d.', $exponent, Calculator::MAX_POWER )); } return new BigInteger(Calculator::get()->pow($this->value, $exponent)); } /** * Returns the quotient of the division of this number by the given one. * * @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigInteger. * * @throws DivisionByZeroException If the divisor is zero. */ public function quotient(BigNumber|int|float|string $that) : BigInteger { $that = BigInteger::of($that); if ($that->value === '1') { return $this; } if ($that->value === '0') { throw DivisionByZeroException::divisionByZero(); } $quotient = Calculator::get()->divQ($this->value, $that->value); return new BigInteger($quotient); } /** * Returns the remainder of the division of this number by the given one. * * The remainder, when non-zero, has the same sign as the dividend. * * @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigInteger. * * @throws DivisionByZeroException If the divisor is zero. */ public function remainder(BigNumber|int|float|string $that) : BigInteger { $that = BigInteger::of($that); if ($that->value === '1') { return BigInteger::zero(); } if ($that->value === '0') { throw DivisionByZeroException::divisionByZero(); } $remainder = Calculator::get()->divR($this->value, $that->value); return new BigInteger($remainder); } /** * Returns the quotient and remainder of the division of this number by the given one. * * @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigInteger. * * @return BigInteger[] An array containing the quotient and the remainder. * * @psalm-return array{BigInteger, BigInteger} * * @throws DivisionByZeroException If the divisor is zero. */ public function quotientAndRemainder(BigNumber|int|float|string $that) : array { $that = BigInteger::of($that); if ($that->value === '0') { throw DivisionByZeroException::divisionByZero(); } [$quotient, $remainder] = Calculator::get()->divQR($this->value, $that->value); return [ new BigInteger($quotient), new BigInteger($remainder) ]; } /** * Returns the modulo of this number and the given one. * * The modulo operation yields the same result as the remainder operation when both operands are of the same sign, * and may differ when signs are different. * * The result of the modulo operation, when non-zero, has the same sign as the divisor. * * @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigInteger. * * @throws DivisionByZeroException If the divisor is zero. */ public function mod(BigNumber|int|float|string $that) : BigInteger { $that = BigInteger::of($that); if ($that->value === '0') { throw DivisionByZeroException::modulusMustNotBeZero(); } $value = Calculator::get()->mod($this->value, $that->value); return new BigInteger($value); } /** * Returns the modular multiplicative inverse of this BigInteger modulo $m. * * @throws DivisionByZeroException If $m is zero. * @throws NegativeNumberException If $m is negative. * @throws MathException If this BigInteger has no multiplicative inverse mod m (that is, this BigInteger * is not relatively prime to m). */ public function modInverse(BigInteger $m) : BigInteger { if ($m->value === '0') { throw DivisionByZeroException::modulusMustNotBeZero(); } if ($m->isNegative()) { throw new NegativeNumberException('Modulus must not be negative.'); } if ($m->value === '1') { return BigInteger::zero(); } $value = Calculator::get()->modInverse($this->value, $m->value); if ($value === null) { throw new MathException('Unable to compute the modInverse for the given modulus.'); } return new BigInteger($value); } /** * Returns this number raised into power with modulo. * * This operation only works on positive numbers. * * @param BigNumber|int|float|string $exp The exponent. Must be positive or zero. * @param BigNumber|int|float|string $mod The modulus. Must be strictly positive. * * @throws NegativeNumberException If any of the operands is negative. * @throws DivisionByZeroException If the modulus is zero. */ public function modPow(BigNumber|int|float|string $exp, BigNumber|int|float|string $mod) : BigInteger { $exp = BigInteger::of($exp); $mod = BigInteger::of($mod); if ($this->isNegative() || $exp->isNegative() || $mod->isNegative()) { throw new NegativeNumberException('The operands cannot be negative.'); } if ($mod->isZero()) { throw DivisionByZeroException::modulusMustNotBeZero(); } $result = Calculator::get()->modPow($this->value, $exp->value, $mod->value); return new BigInteger($result); } /** * Returns the greatest common divisor of this number and the given one. * * The GCD is always positive, unless both operands are zero, in which case it is zero. * * @param BigNumber|int|float|string $that The operand. Must be convertible to an integer number. */ public function gcd(BigNumber|int|float|string $that) : BigInteger { $that = BigInteger::of($that); if ($that->value === '0' && $this->value[0] !== '-') { return $this; } if ($this->value === '0' && $that->value[0] !== '-') { return $that; } $value = Calculator::get()->gcd($this->value, $that->value); return new BigInteger($value); } /** * Returns the integer square root number of this number, rounded down. * * The result is the largest x such that x² ≤ n. * * @throws NegativeNumberException If this number is negative. */ public function sqrt() : BigInteger { if ($this->value[0] === '-') { throw new NegativeNumberException('Cannot calculate the square root of a negative number.'); } $value = Calculator::get()->sqrt($this->value); return new BigInteger($value); } /** * Returns the absolute value of this number. */ public function abs() : BigInteger { return $this->isNegative() ? $this->negated() : $this; } /** * Returns the inverse of this number. */ public function negated() : BigInteger { return new BigInteger(Calculator::get()->neg($this->value)); } /** * Returns the integer bitwise-and combined with another integer. * * This method returns a negative BigInteger if and only if both operands are negative. * * @param BigNumber|int|float|string $that The operand. Must be convertible to an integer number. */ public function and(BigNumber|int|float|string $that) : BigInteger { $that = BigInteger::of($that); return new BigInteger(Calculator::get()->and($this->value, $that->value)); } /** * Returns the integer bitwise-or combined with another integer. * * This method returns a negative BigInteger if and only if either of the operands is negative. * * @param BigNumber|int|float|string $that The operand. Must be convertible to an integer number. */ public function or(BigNumber|int|float|string $that) : BigInteger { $that = BigInteger::of($that); return new BigInteger(Calculator::get()->or($this->value, $that->value)); } /** * Returns the integer bitwise-xor combined with another integer. * * This method returns a negative BigInteger if and only if exactly one of the operands is negative. * * @param BigNumber|int|float|string $that The operand. Must be convertible to an integer number. */ public function xor(BigNumber|int|float|string $that) : BigInteger { $that = BigInteger::of($that); return new BigInteger(Calculator::get()->xor($this->value, $that->value)); } /** * Returns the bitwise-not of this BigInteger. */ public function not() : BigInteger { return $this->negated()->minus(1); } /** * Returns the integer left shifted by a given number of bits. */ public function shiftedLeft(int $distance) : BigInteger { if ($distance === 0) { return $this; } if ($distance < 0) { return $this->shiftedRight(- $distance); } return $this->multipliedBy(BigInteger::of(2)->power($distance)); } /** * Returns the integer right shifted by a given number of bits. */ public function shiftedRight(int $distance) : BigInteger { if ($distance === 0) { return $this; } if ($distance < 0) { return $this->shiftedLeft(- $distance); } $operand = BigInteger::of(2)->power($distance); if ($this->isPositiveOrZero()) { return $this->quotient($operand); } return $this->dividedBy($operand, RoundingMode::UP); } /** * Returns the number of bits in the minimal two's-complement representation of this BigInteger, excluding a sign bit. * * For positive BigIntegers, this is equivalent to the number of bits in the ordinary binary representation. * Computes (ceil(log2(this < 0 ? -this : this+1))). */ public function getBitLength() : int { if ($this->value === '0') { return 0; } if ($this->isNegative()) { return $this->abs()->minus(1)->getBitLength(); } return \strlen($this->toBase(2)); } /** * Returns the index of the rightmost (lowest-order) one bit in this BigInteger. * * Returns -1 if this BigInteger contains no one bits. */ public function getLowestSetBit() : int { $n = $this; $bitLength = $this->getBitLength(); for ($i = 0; $i <= $bitLength; $i++) { if ($n->isOdd()) { return $i; } $n = $n->shiftedRight(1); } return -1; } /** * Returns whether this number is even. */ public function isEven() : bool { return \in_array($this->value[-1], ['0', '2', '4', '6', '8'], true); } /** * Returns whether this number is odd. */ public function isOdd() : bool { return \in_array($this->value[-1], ['1', '3', '5', '7', '9'], true); } /** * Returns true if and only if the designated bit is set. * * Computes ((this & (1<shiftedRight($n)->isOdd(); } #[Override] public function compareTo(BigNumber|int|float|string $that) : int { $that = BigNumber::of($that); if ($that instanceof BigInteger) { return Calculator::get()->cmp($this->value, $that->value); } return - $that->compareTo($this); } #[Override] public function getSign() : int { return ($this->value === '0') ? 0 : (($this->value[0] === '-') ? -1 : 1); } #[Override] public function toBigInteger() : BigInteger { return $this; } #[Override] public function toBigDecimal() : BigDecimal { return self::newBigDecimal($this->value); } #[Override] public function toBigRational() : BigRational { return self::newBigRational($this, BigInteger::one(), false); } #[Override] public function toScale(int $scale, RoundingMode $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal { return $this->toBigDecimal()->toScale($scale, $roundingMode); } #[Override] public function toInt() : int { $intValue = (int) $this->value; if ($this->value !== (string) $intValue) { throw IntegerOverflowException::toIntOverflow($this); } return $intValue; } #[Override] public function toFloat() : float { return (float) $this->value; } /** * Returns a string representation of this number in the given base. * * The output will always be lowercase for bases greater than 10. * * @throws \InvalidArgumentException If the base is out of range. */ public function toBase(int $base) : string { if ($base === 10) { return $this->value; } if ($base < 2 || $base > 36) { throw new \InvalidArgumentException(\sprintf('Base %d is out of range [2, 36]', $base)); } return Calculator::get()->toBase($this->value, $base); } /** * Returns a string representation of this number in an arbitrary base with a custom alphabet. * * Because this method accepts an alphabet with any character, including dash, it does not handle negative numbers; * a NegativeNumberException will be thrown when attempting to call this method on a negative number. * * @param string $alphabet The alphabet, for example '01' for base 2, or '01234567' for base 8. * * @throws NegativeNumberException If this number is negative. * @throws \InvalidArgumentException If the given alphabet does not contain at least 2 chars. */ public function toArbitraryBase(string $alphabet) : string { $base = \strlen($alphabet); if ($base < 2) { throw new \InvalidArgumentException('The alphabet must contain at least 2 chars.'); } if ($this->value[0] === '-') { throw new NegativeNumberException(__FUNCTION__ . '() does not support negative numbers.'); } return Calculator::get()->toArbitraryBase($this->value, $alphabet, $base); } /** * Returns a string of bytes containing the binary representation of this BigInteger. * * The string is in big-endian byte-order: the most significant byte is in the zeroth element. * * If `$signed` is true, the output will be in two's-complement representation, and a sign bit will be prepended to * the output. If `$signed` is false, no sign bit will be prepended, and this method will throw an exception if the * number is negative. * * The string will contain the minimum number of bytes required to represent this BigInteger, including a sign bit * if `$signed` is true. * * This representation is compatible with the `fromBytes()` factory method, as long as the `$signed` flags match. * * @param bool $signed Whether to output a signed number in two's-complement representation with a leading sign bit. * * @throws NegativeNumberException If $signed is false, and the number is negative. */ public function toBytes(bool $signed = true) : string { if (! $signed && $this->isNegative()) { throw new NegativeNumberException('Cannot convert a negative number to a byte string when $signed is false.'); } $hex = $this->abs()->toBase(16); if (\strlen($hex) % 2 !== 0) { $hex = '0' . $hex; } $baseHexLength = \strlen($hex); if ($signed) { if ($this->isNegative()) { $bin = \hex2bin($hex); assert($bin !== false); $hex = \bin2hex(~$bin); $hex = self::fromBase($hex, 16)->plus(1)->toBase(16); $hexLength = \strlen($hex); if ($hexLength < $baseHexLength) { $hex = \str_repeat('0', $baseHexLength - $hexLength) . $hex; } if ($hex[0] < '8') { $hex = 'FF' . $hex; } } else { if ($hex[0] >= '8') { $hex = '00' . $hex; } } } return \hex2bin($hex); } /** * @return numeric-string */ #[Override] public function __toString() : string { /** @var numeric-string */ return $this->value; } /** * This method is required for serializing the object and SHOULD NOT be accessed directly. * * @internal * * @return array{value: string} */ public function __serialize(): array { return ['value' => $this->value]; } /** * This method is only here to allow unserializing the object and cannot be accessed directly. * * @internal * @psalm-suppress RedundantPropertyInitializationCheck * * @param array{value: string} $data * * @throws \LogicException */ public function __unserialize(array $data): void { if (isset($this->value)) { throw new \LogicException('__unserialize() is an internal function, it must not be called directly.'); } $this->value = $data['value']; } } ================================================ FILE: lib/Google/vendor/brick/math/src/BigNumber.php ================================================ [\-\+])?' . '(?[0-9]+)?' . '(?\.)?' . '(?[0-9]+)?' . '(?:[eE](?[\-\+]?[0-9]+))?' . '$/'; /** * The regular expression used to parse rational numbers. */ private const PARSE_REGEXP_RATIONAL = '/^' . '(?[\-\+])?' . '(?[0-9]+)' . '\/?' . '(?[0-9]+)' . '$/'; /** * Creates a BigNumber of the given value. * * The concrete return type is dependent on the given value, with the following rules: * * - BigNumber instances are returned as is * - integer numbers are returned as BigInteger * - floating point numbers are converted to a string then parsed as such * - strings containing a `/` character are returned as BigRational * - strings containing a `.` character or using an exponential notation are returned as BigDecimal * - strings containing only digits with an optional leading `+` or `-` sign are returned as BigInteger * * @throws NumberFormatException If the format of the number is not valid. * @throws DivisionByZeroException If the value represents a rational number with a denominator of zero. * @throws RoundingNecessaryException If the value cannot be converted to an instance of the subclass without rounding. * * @psalm-pure */ final public static function of(BigNumber|int|float|string $value) : static { $value = self::_of($value); if (static::class === BigNumber::class) { // https://github.com/vimeo/psalm/issues/10309 assert($value instanceof static); return $value; } return static::from($value); } /** * @throws NumberFormatException If the format of the number is not valid. * @throws DivisionByZeroException If the value represents a rational number with a denominator of zero. * * @psalm-pure */ private static function _of(BigNumber|int|float|string $value) : BigNumber { if ($value instanceof BigNumber) { return $value; } if (\is_int($value)) { return new BigInteger((string) $value); } if (is_float($value)) { $value = (string) $value; } if (str_contains($value, '/')) { // Rational number if (\preg_match(self::PARSE_REGEXP_RATIONAL, $value, $matches, PREG_UNMATCHED_AS_NULL) !== 1) { throw NumberFormatException::invalidFormat($value); } $sign = $matches['sign']; $numerator = $matches['numerator']; $denominator = $matches['denominator']; assert($numerator !== null); assert($denominator !== null); $numerator = self::cleanUp($sign, $numerator); $denominator = self::cleanUp(null, $denominator); if ($denominator === '0') { throw DivisionByZeroException::denominatorMustNotBeZero(); } return new BigRational( new BigInteger($numerator), new BigInteger($denominator), false ); } else { // Integer or decimal number if (\preg_match(self::PARSE_REGEXP_NUMERICAL, $value, $matches, PREG_UNMATCHED_AS_NULL) !== 1) { throw NumberFormatException::invalidFormat($value); } $sign = $matches['sign']; $point = $matches['point']; $integral = $matches['integral']; $fractional = $matches['fractional']; $exponent = $matches['exponent']; if ($integral === null && $fractional === null) { throw NumberFormatException::invalidFormat($value); } if ($integral === null) { $integral = '0'; } if ($point !== null || $exponent !== null) { $fractional = ($fractional ?? ''); $exponent = ($exponent !== null) ? (int)$exponent : 0; if ($exponent === PHP_INT_MIN || $exponent === PHP_INT_MAX) { throw new NumberFormatException('Exponent too large.'); } $unscaledValue = self::cleanUp($sign, $integral . $fractional); $scale = \strlen($fractional) - $exponent; if ($scale < 0) { if ($unscaledValue !== '0') { $unscaledValue .= \str_repeat('0', -$scale); } $scale = 0; } return new BigDecimal($unscaledValue, $scale); } $integral = self::cleanUp($sign, $integral); return new BigInteger($integral); } } /** * Overridden by subclasses to convert a BigNumber to an instance of the subclass. * * @throws RoundingNecessaryException If the value cannot be converted. * * @psalm-pure */ abstract protected static function from(BigNumber $number): static; /** * Proxy method to access BigInteger's protected constructor from sibling classes. * * @internal * @psalm-pure */ final protected function newBigInteger(string $value) : BigInteger { return new BigInteger($value); } /** * Proxy method to access BigDecimal's protected constructor from sibling classes. * * @internal * @psalm-pure */ final protected function newBigDecimal(string $value, int $scale = 0) : BigDecimal { return new BigDecimal($value, $scale); } /** * Proxy method to access BigRational's protected constructor from sibling classes. * * @internal * @psalm-pure */ final protected function newBigRational(BigInteger $numerator, BigInteger $denominator, bool $checkDenominator) : BigRational { return new BigRational($numerator, $denominator, $checkDenominator); } /** * Returns the minimum of the given values. * * @param BigNumber|int|float|string ...$values The numbers to compare. All the numbers need to be convertible * to an instance of the class this method is called on. * * @throws \InvalidArgumentException If no values are given. * @throws MathException If an argument is not valid. * * @psalm-pure */ final public static function min(BigNumber|int|float|string ...$values) : static { $min = null; foreach ($values as $value) { $value = static::of($value); if ($min === null || $value->isLessThan($min)) { $min = $value; } } if ($min === null) { throw new \InvalidArgumentException(__METHOD__ . '() expects at least one value.'); } return $min; } /** * Returns the maximum of the given values. * * @param BigNumber|int|float|string ...$values The numbers to compare. All the numbers need to be convertible * to an instance of the class this method is called on. * * @throws \InvalidArgumentException If no values are given. * @throws MathException If an argument is not valid. * * @psalm-pure */ final public static function max(BigNumber|int|float|string ...$values) : static { $max = null; foreach ($values as $value) { $value = static::of($value); if ($max === null || $value->isGreaterThan($max)) { $max = $value; } } if ($max === null) { throw new \InvalidArgumentException(__METHOD__ . '() expects at least one value.'); } return $max; } /** * Returns the sum of the given values. * * @param BigNumber|int|float|string ...$values The numbers to add. All the numbers need to be convertible * to an instance of the class this method is called on. * * @throws \InvalidArgumentException If no values are given. * @throws MathException If an argument is not valid. * * @psalm-pure */ final public static function sum(BigNumber|int|float|string ...$values) : static { /** @var static|null $sum */ $sum = null; foreach ($values as $value) { $value = static::of($value); $sum = $sum === null ? $value : self::add($sum, $value); } if ($sum === null) { throw new \InvalidArgumentException(__METHOD__ . '() expects at least one value.'); } return $sum; } /** * Adds two BigNumber instances in the correct order to avoid a RoundingNecessaryException. * * @todo This could be better resolved by creating an abstract protected method in BigNumber, and leaving to * concrete classes the responsibility to perform the addition themselves or delegate it to the given number, * depending on their ability to perform the operation. This will also require a version bump because we're * potentially breaking custom BigNumber implementations (if any...) * * @psalm-pure */ private static function add(BigNumber $a, BigNumber $b) : BigNumber { if ($a instanceof BigRational) { return $a->plus($b); } if ($b instanceof BigRational) { return $b->plus($a); } if ($a instanceof BigDecimal) { return $a->plus($b); } if ($b instanceof BigDecimal) { return $b->plus($a); } /** @var BigInteger $a */ return $a->plus($b); } /** * Removes optional leading zeros and applies sign. * * @param string|null $sign The sign, '+' or '-', optional. Null is allowed for convenience and treated as '+'. * @param string $number The number, validated as a non-empty string of digits. * * @psalm-pure */ private static function cleanUp(string|null $sign, string $number) : string { $number = \ltrim($number, '0'); if ($number === '') { return '0'; } return $sign === '-' ? '-' . $number : $number; } /** * Checks if this number is equal to the given one. */ final public function isEqualTo(BigNumber|int|float|string $that) : bool { return $this->compareTo($that) === 0; } /** * Checks if this number is strictly lower than the given one. */ final public function isLessThan(BigNumber|int|float|string $that) : bool { return $this->compareTo($that) < 0; } /** * Checks if this number is lower than or equal to the given one. */ final public function isLessThanOrEqualTo(BigNumber|int|float|string $that) : bool { return $this->compareTo($that) <= 0; } /** * Checks if this number is strictly greater than the given one. */ final public function isGreaterThan(BigNumber|int|float|string $that) : bool { return $this->compareTo($that) > 0; } /** * Checks if this number is greater than or equal to the given one. */ final public function isGreaterThanOrEqualTo(BigNumber|int|float|string $that) : bool { return $this->compareTo($that) >= 0; } /** * Checks if this number equals zero. */ final public function isZero() : bool { return $this->getSign() === 0; } /** * Checks if this number is strictly negative. */ final public function isNegative() : bool { return $this->getSign() < 0; } /** * Checks if this number is negative or zero. */ final public function isNegativeOrZero() : bool { return $this->getSign() <= 0; } /** * Checks if this number is strictly positive. */ final public function isPositive() : bool { return $this->getSign() > 0; } /** * Checks if this number is positive or zero. */ final public function isPositiveOrZero() : bool { return $this->getSign() >= 0; } /** * Returns the sign of this number. * * @psalm-return -1|0|1 * * @return int -1 if the number is negative, 0 if zero, 1 if positive. */ abstract public function getSign() : int; /** * Compares this number to the given one. * * @psalm-return -1|0|1 * * @return int -1 if `$this` is lower than, 0 if equal to, 1 if greater than `$that`. * * @throws MathException If the number is not valid. */ abstract public function compareTo(BigNumber|int|float|string $that) : int; /** * Converts this number to a BigInteger. * * @throws RoundingNecessaryException If this number cannot be converted to a BigInteger without rounding. */ abstract public function toBigInteger() : BigInteger; /** * Converts this number to a BigDecimal. * * @throws RoundingNecessaryException If this number cannot be converted to a BigDecimal without rounding. */ abstract public function toBigDecimal() : BigDecimal; /** * Converts this number to a BigRational. */ abstract public function toBigRational() : BigRational; /** * Converts this number to a BigDecimal with the given scale, using rounding if necessary. * * @param int $scale The scale of the resulting `BigDecimal`. * @param RoundingMode $roundingMode An optional rounding mode, defaults to UNNECESSARY. * * @throws RoundingNecessaryException If this number cannot be converted to the given scale without rounding. * This only applies when RoundingMode::UNNECESSARY is used. */ abstract public function toScale(int $scale, RoundingMode $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal; /** * Returns the exact value of this number as a native integer. * * If this number cannot be converted to a native integer without losing precision, an exception is thrown. * Note that the acceptable range for an integer depends on the platform and differs for 32-bit and 64-bit. * * @throws MathException If this number cannot be exactly converted to a native integer. */ abstract public function toInt() : int; /** * Returns an approximation of this number as a floating-point value. * * Note that this method can discard information as the precision of a floating-point value * is inherently limited. * * If the number is greater than the largest representable floating point number, positive infinity is returned. * If the number is less than the smallest representable floating point number, negative infinity is returned. */ abstract public function toFloat() : float; /** * Returns a string representation of this number. * * The output of this method can be parsed by the `of()` factory method; * this will yield an object equal to this one, without any information loss. */ abstract public function __toString() : string; #[Override] final public function jsonSerialize() : string { return $this->__toString(); } } ================================================ FILE: lib/Google/vendor/brick/math/src/BigRational.php ================================================ isZero()) { throw DivisionByZeroException::denominatorMustNotBeZero(); } if ($denominator->isNegative()) { $numerator = $numerator->negated(); $denominator = $denominator->negated(); } } $this->numerator = $numerator; $this->denominator = $denominator; } /** * @psalm-pure */ #[Override] protected static function from(BigNumber $number): static { return $number->toBigRational(); } /** * Creates a BigRational out of a numerator and a denominator. * * If the denominator is negative, the signs of both the numerator and the denominator * will be inverted to ensure that the denominator is always positive. * * @param BigNumber|int|float|string $numerator The numerator. Must be convertible to a BigInteger. * @param BigNumber|int|float|string $denominator The denominator. Must be convertible to a BigInteger. * * @throws NumberFormatException If an argument does not represent a valid number. * @throws RoundingNecessaryException If an argument represents a non-integer number. * @throws DivisionByZeroException If the denominator is zero. * * @psalm-pure */ public static function nd( BigNumber|int|float|string $numerator, BigNumber|int|float|string $denominator, ) : BigRational { $numerator = BigInteger::of($numerator); $denominator = BigInteger::of($denominator); return new BigRational($numerator, $denominator, true); } /** * Returns a BigRational representing zero. * * @psalm-pure */ public static function zero() : BigRational { /** * @psalm-suppress ImpureStaticVariable * @var BigRational|null $zero */ static $zero; if ($zero === null) { $zero = new BigRational(BigInteger::zero(), BigInteger::one(), false); } return $zero; } /** * Returns a BigRational representing one. * * @psalm-pure */ public static function one() : BigRational { /** * @psalm-suppress ImpureStaticVariable * @var BigRational|null $one */ static $one; if ($one === null) { $one = new BigRational(BigInteger::one(), BigInteger::one(), false); } return $one; } /** * Returns a BigRational representing ten. * * @psalm-pure */ public static function ten() : BigRational { /** * @psalm-suppress ImpureStaticVariable * @var BigRational|null $ten */ static $ten; if ($ten === null) { $ten = new BigRational(BigInteger::ten(), BigInteger::one(), false); } return $ten; } public function getNumerator() : BigInteger { return $this->numerator; } public function getDenominator() : BigInteger { return $this->denominator; } /** * Returns the quotient of the division of the numerator by the denominator. */ public function quotient() : BigInteger { return $this->numerator->quotient($this->denominator); } /** * Returns the remainder of the division of the numerator by the denominator. */ public function remainder() : BigInteger { return $this->numerator->remainder($this->denominator); } /** * Returns the quotient and remainder of the division of the numerator by the denominator. * * @return BigInteger[] * * @psalm-return array{BigInteger, BigInteger} */ public function quotientAndRemainder() : array { return $this->numerator->quotientAndRemainder($this->denominator); } /** * Returns the sum of this number and the given one. * * @param BigNumber|int|float|string $that The number to add. * * @throws MathException If the number is not valid. */ public function plus(BigNumber|int|float|string $that) : BigRational { $that = BigRational::of($that); $numerator = $this->numerator->multipliedBy($that->denominator); $numerator = $numerator->plus($that->numerator->multipliedBy($this->denominator)); $denominator = $this->denominator->multipliedBy($that->denominator); return new BigRational($numerator, $denominator, false); } /** * Returns the difference of this number and the given one. * * @param BigNumber|int|float|string $that The number to subtract. * * @throws MathException If the number is not valid. */ public function minus(BigNumber|int|float|string $that) : BigRational { $that = BigRational::of($that); $numerator = $this->numerator->multipliedBy($that->denominator); $numerator = $numerator->minus($that->numerator->multipliedBy($this->denominator)); $denominator = $this->denominator->multipliedBy($that->denominator); return new BigRational($numerator, $denominator, false); } /** * Returns the product of this number and the given one. * * @param BigNumber|int|float|string $that The multiplier. * * @throws MathException If the multiplier is not a valid number. */ public function multipliedBy(BigNumber|int|float|string $that) : BigRational { $that = BigRational::of($that); $numerator = $this->numerator->multipliedBy($that->numerator); $denominator = $this->denominator->multipliedBy($that->denominator); return new BigRational($numerator, $denominator, false); } /** * Returns the result of the division of this number by the given one. * * @param BigNumber|int|float|string $that The divisor. * * @throws MathException If the divisor is not a valid number, or is zero. */ public function dividedBy(BigNumber|int|float|string $that) : BigRational { $that = BigRational::of($that); $numerator = $this->numerator->multipliedBy($that->denominator); $denominator = $this->denominator->multipliedBy($that->numerator); return new BigRational($numerator, $denominator, true); } /** * Returns this number exponentiated to the given value. * * @throws \InvalidArgumentException If the exponent is not in the range 0 to 1,000,000. */ public function power(int $exponent) : BigRational { if ($exponent === 0) { $one = BigInteger::one(); return new BigRational($one, $one, false); } if ($exponent === 1) { return $this; } return new BigRational( $this->numerator->power($exponent), $this->denominator->power($exponent), false ); } /** * Returns the reciprocal of this BigRational. * * The reciprocal has the numerator and denominator swapped. * * @throws DivisionByZeroException If the numerator is zero. */ public function reciprocal() : BigRational { return new BigRational($this->denominator, $this->numerator, true); } /** * Returns the absolute value of this BigRational. */ public function abs() : BigRational { return new BigRational($this->numerator->abs(), $this->denominator, false); } /** * Returns the negated value of this BigRational. */ public function negated() : BigRational { return new BigRational($this->numerator->negated(), $this->denominator, false); } /** * Returns the simplified value of this BigRational. */ public function simplified() : BigRational { $gcd = $this->numerator->gcd($this->denominator); $numerator = $this->numerator->quotient($gcd); $denominator = $this->denominator->quotient($gcd); return new BigRational($numerator, $denominator, false); } #[Override] public function compareTo(BigNumber|int|float|string $that) : int { return $this->minus($that)->getSign(); } #[Override] public function getSign() : int { return $this->numerator->getSign(); } #[Override] public function toBigInteger() : BigInteger { $simplified = $this->simplified(); if (! $simplified->denominator->isEqualTo(1)) { throw new RoundingNecessaryException('This rational number cannot be represented as an integer value without rounding.'); } return $simplified->numerator; } #[Override] public function toBigDecimal() : BigDecimal { return $this->numerator->toBigDecimal()->exactlyDividedBy($this->denominator); } #[Override] public function toBigRational() : BigRational { return $this; } #[Override] public function toScale(int $scale, RoundingMode $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal { return $this->numerator->toBigDecimal()->dividedBy($this->denominator, $scale, $roundingMode); } #[Override] public function toInt() : int { return $this->toBigInteger()->toInt(); } #[Override] public function toFloat() : float { $simplified = $this->simplified(); return $simplified->numerator->toFloat() / $simplified->denominator->toFloat(); } #[Override] public function __toString() : string { $numerator = (string) $this->numerator; $denominator = (string) $this->denominator; if ($denominator === '1') { return $numerator; } return $numerator . '/' . $denominator; } /** * This method is required for serializing the object and SHOULD NOT be accessed directly. * * @internal * * @return array{numerator: BigInteger, denominator: BigInteger} */ public function __serialize(): array { return ['numerator' => $this->numerator, 'denominator' => $this->denominator]; } /** * This method is only here to allow unserializing the object and cannot be accessed directly. * * @internal * @psalm-suppress RedundantPropertyInitializationCheck * * @param array{numerator: BigInteger, denominator: BigInteger} $data * * @throws \LogicException */ public function __unserialize(array $data): void { if (isset($this->numerator)) { throw new \LogicException('__unserialize() is an internal function, it must not be called directly.'); } $this->numerator = $data['numerator']; $this->denominator = $data['denominator']; } } ================================================ FILE: lib/Google/vendor/brick/math/src/Exception/DivisionByZeroException.php ================================================ 126) { $char = \strtoupper(\dechex($ord)); if ($ord < 10) { $char = '0' . $char; } } else { $char = '"' . $char . '"'; } return new self(\sprintf('Char %s is not a valid character in the given alphabet.', $char)); } } ================================================ FILE: lib/Google/vendor/brick/math/src/Exception/RoundingNecessaryException.php ================================================ maxDigits = match (PHP_INT_SIZE) { 4 => 9, 8 => 18, default => throw new \RuntimeException('The platform is not 32-bit or 64-bit as expected.') }; } #[Override] public function add(string $a, string $b) : string { /** * @psalm-var numeric-string $a * @psalm-var numeric-string $b */ $result = $a + $b; if (is_int($result)) { return (string) $result; } if ($a === '0') { return $b; } if ($b === '0') { return $a; } [$aNeg, $bNeg, $aDig, $bDig] = $this->init($a, $b); $result = $aNeg === $bNeg ? $this->doAdd($aDig, $bDig) : $this->doSub($aDig, $bDig); if ($aNeg) { $result = $this->neg($result); } return $result; } #[Override] public function sub(string $a, string $b) : string { return $this->add($a, $this->neg($b)); } #[Override] public function mul(string $a, string $b) : string { /** * @psalm-var numeric-string $a * @psalm-var numeric-string $b */ $result = $a * $b; if (is_int($result)) { return (string) $result; } if ($a === '0' || $b === '0') { return '0'; } if ($a === '1') { return $b; } if ($b === '1') { return $a; } if ($a === '-1') { return $this->neg($b); } if ($b === '-1') { return $this->neg($a); } [$aNeg, $bNeg, $aDig, $bDig] = $this->init($a, $b); $result = $this->doMul($aDig, $bDig); if ($aNeg !== $bNeg) { $result = $this->neg($result); } return $result; } #[Override] public function divQ(string $a, string $b) : string { return $this->divQR($a, $b)[0]; } #[Override] public function divR(string $a, string $b): string { return $this->divQR($a, $b)[1]; } #[Override] public function divQR(string $a, string $b) : array { if ($a === '0') { return ['0', '0']; } if ($a === $b) { return ['1', '0']; } if ($b === '1') { return [$a, '0']; } if ($b === '-1') { return [$this->neg($a), '0']; } /** @psalm-var numeric-string $a */ $na = $a * 1; // cast to number if (is_int($na)) { /** @psalm-var numeric-string $b */ $nb = $b * 1; if (is_int($nb)) { // the only division that may overflow is PHP_INT_MIN / -1, // which cannot happen here as we've already handled a divisor of -1 above. $q = intdiv($na, $nb); $r = $na % $nb; return [ (string) $q, (string) $r ]; } } [$aNeg, $bNeg, $aDig, $bDig] = $this->init($a, $b); [$q, $r] = $this->doDiv($aDig, $bDig); if ($aNeg !== $bNeg) { $q = $this->neg($q); } if ($aNeg) { $r = $this->neg($r); } return [$q, $r]; } #[Override] public function pow(string $a, int $e) : string { if ($e === 0) { return '1'; } if ($e === 1) { return $a; } $odd = $e % 2; $e -= $odd; $aa = $this->mul($a, $a); /** @psalm-suppress PossiblyInvalidArgument We're sure that $e / 2 is an int now */ $result = $this->pow($aa, $e / 2); if ($odd === 1) { $result = $this->mul($result, $a); } return $result; } /** * Algorithm from: https://www.geeksforgeeks.org/modular-exponentiation-power-in-modular-arithmetic/ */ #[Override] public function modPow(string $base, string $exp, string $mod) : string { // special case: the algorithm below fails with 0 power 0 mod 1 (returns 1 instead of 0) if ($base === '0' && $exp === '0' && $mod === '1') { return '0'; } // special case: the algorithm below fails with power 0 mod 1 (returns 1 instead of 0) if ($exp === '0' && $mod === '1') { return '0'; } $x = $base; $res = '1'; // numbers are positive, so we can use remainder instead of modulo $x = $this->divR($x, $mod); while ($exp !== '0') { if (in_array($exp[-1], ['1', '3', '5', '7', '9'])) { // odd $res = $this->divR($this->mul($res, $x), $mod); } $exp = $this->divQ($exp, '2'); $x = $this->divR($this->mul($x, $x), $mod); } return $res; } /** * Adapted from https://cp-algorithms.com/num_methods/roots_newton.html */ #[Override] public function sqrt(string $n) : string { if ($n === '0') { return '0'; } // initial approximation $x = \str_repeat('9', \intdiv(\strlen($n), 2) ?: 1); $decreased = false; for (;;) { $nx = $this->divQ($this->add($x, $this->divQ($n, $x)), '2'); if ($x === $nx || $this->cmp($nx, $x) > 0 && $decreased) { break; } $decreased = $this->cmp($nx, $x) < 0; $x = $nx; } return $x; } /** * Performs the addition of two non-signed large integers. */ private function doAdd(string $a, string $b) : string { [$a, $b, $length] = $this->pad($a, $b); $carry = 0; $result = ''; for ($i = $length - $this->maxDigits;; $i -= $this->maxDigits) { $blockLength = $this->maxDigits; if ($i < 0) { $blockLength += $i; /** @psalm-suppress LoopInvalidation */ $i = 0; } /** @psalm-var numeric-string $blockA */ $blockA = \substr($a, $i, $blockLength); /** @psalm-var numeric-string $blockB */ $blockB = \substr($b, $i, $blockLength); $sum = (string) ($blockA + $blockB + $carry); $sumLength = \strlen($sum); if ($sumLength > $blockLength) { $sum = \substr($sum, 1); $carry = 1; } else { if ($sumLength < $blockLength) { $sum = \str_repeat('0', $blockLength - $sumLength) . $sum; } $carry = 0; } $result = $sum . $result; if ($i === 0) { break; } } if ($carry === 1) { $result = '1' . $result; } return $result; } /** * Performs the subtraction of two non-signed large integers. */ private function doSub(string $a, string $b) : string { if ($a === $b) { return '0'; } // Ensure that we always subtract to a positive result: biggest minus smallest. $cmp = $this->doCmp($a, $b); $invert = ($cmp === -1); if ($invert) { $c = $a; $a = $b; $b = $c; } [$a, $b, $length] = $this->pad($a, $b); $carry = 0; $result = ''; $complement = 10 ** $this->maxDigits; for ($i = $length - $this->maxDigits;; $i -= $this->maxDigits) { $blockLength = $this->maxDigits; if ($i < 0) { $blockLength += $i; /** @psalm-suppress LoopInvalidation */ $i = 0; } /** @psalm-var numeric-string $blockA */ $blockA = \substr($a, $i, $blockLength); /** @psalm-var numeric-string $blockB */ $blockB = \substr($b, $i, $blockLength); $sum = $blockA - $blockB - $carry; if ($sum < 0) { $sum += $complement; $carry = 1; } else { $carry = 0; } $sum = (string) $sum; $sumLength = \strlen($sum); if ($sumLength < $blockLength) { $sum = \str_repeat('0', $blockLength - $sumLength) . $sum; } $result = $sum . $result; if ($i === 0) { break; } } // Carry cannot be 1 when the loop ends, as a > b assert($carry === 0); $result = \ltrim($result, '0'); if ($invert) { $result = $this->neg($result); } return $result; } /** * Performs the multiplication of two non-signed large integers. */ private function doMul(string $a, string $b) : string { $x = \strlen($a); $y = \strlen($b); $maxDigits = \intdiv($this->maxDigits, 2); $complement = 10 ** $maxDigits; $result = '0'; for ($i = $x - $maxDigits;; $i -= $maxDigits) { $blockALength = $maxDigits; if ($i < 0) { $blockALength += $i; /** @psalm-suppress LoopInvalidation */ $i = 0; } $blockA = (int) \substr($a, $i, $blockALength); $line = ''; $carry = 0; for ($j = $y - $maxDigits;; $j -= $maxDigits) { $blockBLength = $maxDigits; if ($j < 0) { $blockBLength += $j; /** @psalm-suppress LoopInvalidation */ $j = 0; } $blockB = (int) \substr($b, $j, $blockBLength); $mul = $blockA * $blockB + $carry; $value = $mul % $complement; $carry = ($mul - $value) / $complement; $value = (string) $value; $value = \str_pad($value, $maxDigits, '0', STR_PAD_LEFT); $line = $value . $line; if ($j === 0) { break; } } if ($carry !== 0) { $line = $carry . $line; } $line = \ltrim($line, '0'); if ($line !== '') { $line .= \str_repeat('0', $x - $blockALength - $i); $result = $this->add($result, $line); } if ($i === 0) { break; } } return $result; } /** * Performs the division of two non-signed large integers. * * @return string[] The quotient and remainder. */ private function doDiv(string $a, string $b) : array { $cmp = $this->doCmp($a, $b); if ($cmp === -1) { return ['0', $a]; } $x = \strlen($a); $y = \strlen($b); // we now know that a >= b && x >= y $q = '0'; // quotient $r = $a; // remainder $z = $y; // focus length, always $y or $y+1 /** @psalm-var numeric-string $b */ $nb = $b * 1; // cast to number // performance optimization in cases where the remainder will never cause int overflow if (is_int(($nb - 1) * 10 + 9)) { $r = (int) \substr($a, 0, $z - 1); for ($i = $z - 1; $i < $x; $i++) { $n = $r * 10 + (int) $a[$i]; /** @psalm-var int $nb */ $q .= \intdiv($n, $nb); $r = $n % $nb; } return [\ltrim($q, '0') ?: '0', (string) $r]; } for (;;) { $focus = \substr($a, 0, $z); $cmp = $this->doCmp($focus, $b); if ($cmp === -1) { if ($z === $x) { // remainder < dividend break; } $z++; } $zeros = \str_repeat('0', $x - $z); $q = $this->add($q, '1' . $zeros); $a = $this->sub($a, $b . $zeros); $r = $a; if ($r === '0') { // remainder == 0 break; } $x = \strlen($a); if ($x < $y) { // remainder < dividend break; } $z = $y; } return [$q, $r]; } /** * Compares two non-signed large numbers. * * @psalm-return -1|0|1 */ private function doCmp(string $a, string $b) : int { $x = \strlen($a); $y = \strlen($b); $cmp = $x <=> $y; if ($cmp !== 0) { return $cmp; } return \strcmp($a, $b) <=> 0; // enforce -1|0|1 } /** * Pads the left of one of the given numbers with zeros if necessary to make both numbers the same length. * * The numbers must only consist of digits, without leading minus sign. * * @return array{string, string, int} */ private function pad(string $a, string $b) : array { $x = \strlen($a); $y = \strlen($b); if ($x > $y) { $b = \str_repeat('0', $x - $y) . $b; return [$a, $b, $x]; } if ($x < $y) { $a = \str_repeat('0', $y - $x) . $a; return [$a, $b, $y]; } return [$a, $b, $x]; } } ================================================ FILE: lib/Google/vendor/brick/math/src/Internal/Calculator.php ================================================ init($a, $b); if ($aNeg && ! $bNeg) { return -1; } if ($bNeg && ! $aNeg) { return 1; } $aLen = \strlen($aDig); $bLen = \strlen($bDig); if ($aLen < $bLen) { $result = -1; } elseif ($aLen > $bLen) { $result = 1; } else { $result = $aDig <=> $bDig; } return $aNeg ? -$result : $result; } /** * Adds two numbers. */ abstract public function add(string $a, string $b) : string; /** * Subtracts two numbers. */ abstract public function sub(string $a, string $b) : string; /** * Multiplies two numbers. */ abstract public function mul(string $a, string $b) : string; /** * Returns the quotient of the division of two numbers. * * @param string $a The dividend. * @param string $b The divisor, must not be zero. * * @return string The quotient. */ abstract public function divQ(string $a, string $b) : string; /** * Returns the remainder of the division of two numbers. * * @param string $a The dividend. * @param string $b The divisor, must not be zero. * * @return string The remainder. */ abstract public function divR(string $a, string $b) : string; /** * Returns the quotient and remainder of the division of two numbers. * * @param string $a The dividend. * @param string $b The divisor, must not be zero. * * @return array{string, string} An array containing the quotient and remainder. */ abstract public function divQR(string $a, string $b) : array; /** * Exponentiates a number. * * @param string $a The base number. * @param int $e The exponent, validated as an integer between 0 and MAX_POWER. * * @return string The power. */ abstract public function pow(string $a, int $e) : string; /** * @param string $b The modulus; must not be zero. */ public function mod(string $a, string $b) : string { return $this->divR($this->add($this->divR($a, $b), $b), $b); } /** * Returns the modular multiplicative inverse of $x modulo $m. * * If $x has no multiplicative inverse mod m, this method must return null. * * This method can be overridden by the concrete implementation if the underlying library has built-in support. * * @param string $m The modulus; must not be negative or zero. */ public function modInverse(string $x, string $m) : ?string { if ($m === '1') { return '0'; } $modVal = $x; if ($x[0] === '-' || ($this->cmp($this->abs($x), $m) >= 0)) { $modVal = $this->mod($x, $m); } [$g, $x] = $this->gcdExtended($modVal, $m); if ($g !== '1') { return null; } return $this->mod($this->add($this->mod($x, $m), $m), $m); } /** * Raises a number into power with modulo. * * @param string $base The base number; must be positive or zero. * @param string $exp The exponent; must be positive or zero. * @param string $mod The modulus; must be strictly positive. */ abstract public function modPow(string $base, string $exp, string $mod) : string; /** * Returns the greatest common divisor of the two numbers. * * This method can be overridden by the concrete implementation if the underlying library * has built-in support for GCD calculations. * * @return string The GCD, always positive, or zero if both arguments are zero. */ public function gcd(string $a, string $b) : string { if ($a === '0') { return $this->abs($b); } if ($b === '0') { return $this->abs($a); } return $this->gcd($b, $this->divR($a, $b)); } /** * @return array{string, string, string} GCD, X, Y */ private function gcdExtended(string $a, string $b) : array { if ($a === '0') { return [$b, '0', '1']; } [$gcd, $x1, $y1] = $this->gcdExtended($this->mod($b, $a), $a); $x = $this->sub($y1, $this->mul($this->divQ($b, $a), $x1)); $y = $x1; return [$gcd, $x, $y]; } /** * Returns the square root of the given number, rounded down. * * The result is the largest x such that x² ≤ n. * The input MUST NOT be negative. */ abstract public function sqrt(string $n) : string; /** * Converts a number from an arbitrary base. * * This method can be overridden by the concrete implementation if the underlying library * has built-in support for base conversion. * * @param string $number The number, positive or zero, non-empty, case-insensitively validated for the given base. * @param int $base The base of the number, validated from 2 to 36. * * @return string The converted number, following the Calculator conventions. */ public function fromBase(string $number, int $base) : string { return $this->fromArbitraryBase(\strtolower($number), self::ALPHABET, $base); } /** * Converts a number to an arbitrary base. * * This method can be overridden by the concrete implementation if the underlying library * has built-in support for base conversion. * * @param string $number The number to convert, following the Calculator conventions. * @param int $base The base to convert to, validated from 2 to 36. * * @return string The converted number, lowercase. */ public function toBase(string $number, int $base) : string { $negative = ($number[0] === '-'); if ($negative) { $number = \substr($number, 1); } $number = $this->toArbitraryBase($number, self::ALPHABET, $base); if ($negative) { return '-' . $number; } return $number; } /** * Converts a non-negative number in an arbitrary base using a custom alphabet, to base 10. * * @param string $number The number to convert, validated as a non-empty string, * containing only chars in the given alphabet/base. * @param string $alphabet The alphabet that contains every digit, validated as 2 chars minimum. * @param int $base The base of the number, validated from 2 to alphabet length. * * @return string The number in base 10, following the Calculator conventions. */ final public function fromArbitraryBase(string $number, string $alphabet, int $base) : string { // remove leading "zeros" $number = \ltrim($number, $alphabet[0]); if ($number === '') { return '0'; } // optimize for "one" if ($number === $alphabet[1]) { return '1'; } $result = '0'; $power = '1'; $base = (string) $base; for ($i = \strlen($number) - 1; $i >= 0; $i--) { $index = \strpos($alphabet, $number[$i]); if ($index !== 0) { $result = $this->add($result, ($index === 1) ? $power : $this->mul($power, (string) $index) ); } if ($i !== 0) { $power = $this->mul($power, $base); } } return $result; } /** * Converts a non-negative number to an arbitrary base using a custom alphabet. * * @param string $number The number to convert, positive or zero, following the Calculator conventions. * @param string $alphabet The alphabet that contains every digit, validated as 2 chars minimum. * @param int $base The base to convert to, validated from 2 to alphabet length. * * @return string The converted number in the given alphabet. */ final public function toArbitraryBase(string $number, string $alphabet, int $base) : string { if ($number === '0') { return $alphabet[0]; } $base = (string) $base; $result = ''; while ($number !== '0') { [$number, $remainder] = $this->divQR($number, $base); $remainder = (int) $remainder; $result .= $alphabet[$remainder]; } return \strrev($result); } /** * Performs a rounded division. * * Rounding is performed when the remainder of the division is not zero. * * @param string $a The dividend. * @param string $b The divisor, must not be zero. * @param RoundingMode $roundingMode The rounding mode. * * @throws \InvalidArgumentException If the rounding mode is invalid. * @throws RoundingNecessaryException If RoundingMode::UNNECESSARY is provided but rounding is necessary. * * @psalm-suppress ImpureFunctionCall */ final public function divRound(string $a, string $b, RoundingMode $roundingMode) : string { [$quotient, $remainder] = $this->divQR($a, $b); $hasDiscardedFraction = ($remainder !== '0'); $isPositiveOrZero = ($a[0] === '-') === ($b[0] === '-'); $discardedFractionSign = function() use ($remainder, $b) : int { $r = $this->abs($this->mul($remainder, '2')); $b = $this->abs($b); return $this->cmp($r, $b); }; $increment = false; switch ($roundingMode) { case RoundingMode::UNNECESSARY: if ($hasDiscardedFraction) { throw RoundingNecessaryException::roundingNecessary(); } break; case RoundingMode::UP: $increment = $hasDiscardedFraction; break; case RoundingMode::DOWN: break; case RoundingMode::CEILING: $increment = $hasDiscardedFraction && $isPositiveOrZero; break; case RoundingMode::FLOOR: $increment = $hasDiscardedFraction && ! $isPositiveOrZero; break; case RoundingMode::HALF_UP: $increment = $discardedFractionSign() >= 0; break; case RoundingMode::HALF_DOWN: $increment = $discardedFractionSign() > 0; break; case RoundingMode::HALF_CEILING: $increment = $isPositiveOrZero ? $discardedFractionSign() >= 0 : $discardedFractionSign() > 0; break; case RoundingMode::HALF_FLOOR: $increment = $isPositiveOrZero ? $discardedFractionSign() > 0 : $discardedFractionSign() >= 0; break; case RoundingMode::HALF_EVEN: $lastDigit = (int) $quotient[-1]; $lastDigitIsEven = ($lastDigit % 2 === 0); $increment = $lastDigitIsEven ? $discardedFractionSign() > 0 : $discardedFractionSign() >= 0; break; default: throw new \InvalidArgumentException('Invalid rounding mode.'); } if ($increment) { return $this->add($quotient, $isPositiveOrZero ? '1' : '-1'); } return $quotient; } /** * Calculates bitwise AND of two numbers. * * This method can be overridden by the concrete implementation if the underlying library * has built-in support for bitwise operations. */ public function and(string $a, string $b) : string { return $this->bitwise('and', $a, $b); } /** * Calculates bitwise OR of two numbers. * * This method can be overridden by the concrete implementation if the underlying library * has built-in support for bitwise operations. */ public function or(string $a, string $b) : string { return $this->bitwise('or', $a, $b); } /** * Calculates bitwise XOR of two numbers. * * This method can be overridden by the concrete implementation if the underlying library * has built-in support for bitwise operations. */ public function xor(string $a, string $b) : string { return $this->bitwise('xor', $a, $b); } /** * Performs a bitwise operation on a decimal number. * * @param 'and'|'or'|'xor' $operator The operator to use. * @param string $a The left operand. * @param string $b The right operand. */ private function bitwise(string $operator, string $a, string $b) : string { [$aNeg, $bNeg, $aDig, $bDig] = $this->init($a, $b); $aBin = $this->toBinary($aDig); $bBin = $this->toBinary($bDig); $aLen = \strlen($aBin); $bLen = \strlen($bBin); if ($aLen > $bLen) { $bBin = \str_repeat("\x00", $aLen - $bLen) . $bBin; } elseif ($bLen > $aLen) { $aBin = \str_repeat("\x00", $bLen - $aLen) . $aBin; } if ($aNeg) { $aBin = $this->twosComplement($aBin); } if ($bNeg) { $bBin = $this->twosComplement($bBin); } $value = match ($operator) { 'and' => $aBin & $bBin, 'or' => $aBin | $bBin, 'xor' => $aBin ^ $bBin, }; $negative = match ($operator) { 'and' => $aNeg and $bNeg, 'or' => $aNeg or $bNeg, 'xor' => $aNeg xor $bNeg, }; if ($negative) { $value = $this->twosComplement($value); } $result = $this->toDecimal($value); return $negative ? $this->neg($result) : $result; } /** * @param string $number A positive, binary number. */ private function twosComplement(string $number) : string { $xor = \str_repeat("\xff", \strlen($number)); $number ^= $xor; for ($i = \strlen($number) - 1; $i >= 0; $i--) { $byte = \ord($number[$i]); if (++$byte !== 256) { $number[$i] = \chr($byte); break; } $number[$i] = "\x00"; if ($i === 0) { $number = "\x01" . $number; } } return $number; } /** * Converts a decimal number to a binary string. * * @param string $number The number to convert, positive or zero, only digits. */ private function toBinary(string $number) : string { $result = ''; while ($number !== '0') { [$number, $remainder] = $this->divQR($number, '256'); $result .= \chr((int) $remainder); } return \strrev($result); } /** * Returns the positive decimal representation of a binary number. * * @param string $bytes The bytes representing the number. */ private function toDecimal(string $bytes) : string { $result = '0'; $power = '1'; for ($i = \strlen($bytes) - 1; $i >= 0; $i--) { $index = \ord($bytes[$i]); if ($index !== 0) { $result = $this->add($result, ($index === 1) ? $power : $this->mul($power, (string) $index) ); } if ($i !== 0) { $power = $this->mul($power, '256'); } } return $result; } } ================================================ FILE: lib/Google/vendor/brick/math/src/RoundingMode.php ================================================ = 0.5; otherwise, behaves as for DOWN. * Note that this is the rounding mode commonly taught at school. */ case HALF_UP; /** * Rounds towards "nearest neighbor" unless both neighbors are equidistant, in which case round down. * * Behaves as for UP if the discarded fraction is > 0.5; otherwise, behaves as for DOWN. */ case HALF_DOWN; /** * Rounds towards "nearest neighbor" unless both neighbors are equidistant, in which case round towards positive infinity. * * If the result is positive, behaves as for HALF_UP; if negative, behaves as for HALF_DOWN. */ case HALF_CEILING; /** * Rounds towards "nearest neighbor" unless both neighbors are equidistant, in which case round towards negative infinity. * * If the result is positive, behaves as for HALF_DOWN; if negative, behaves as for HALF_UP. */ case HALF_FLOOR; /** * Rounds towards the "nearest neighbor" unless both neighbors are equidistant, in which case rounds towards the even neighbor. * * Behaves as for HALF_UP if the digit to the left of the discarded fraction is odd; * behaves as for HALF_DOWN if it's even. * * Note that this is the rounding mode that statistically minimizes * cumulative error when applied repeatedly over a sequence of calculations. * It is sometimes known as "Banker's rounding", and is chiefly used in the USA. */ case HALF_EVEN; } ================================================ FILE: lib/Google/vendor/composer/ClassLoader.php ================================================ * 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); } } ================================================ FILE: lib/Google/vendor/composer/InstalledVersions.php ================================================ * Jordi Boggiano * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Composer; use Composer\Autoload\ClassLoader; use 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 string|null if set (by reflection by Composer), this should be set to the path where this class is being copied to * @internal */ private static $selfDir = null; /** * @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 */ private static $installedIsLocalDir; /** * @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(); // when using reload, we disable the duplicate protection to ensure that self::$installed data is // always returned, but we cannot know whether it comes from the installed.php in __DIR__ or not, // so we have to assume it does not, and that may result in duplicate data being returned when listing // all installed packages for example self::$installedIsLocalDir = false; } /** * @return string */ private static function getSelfDir() { if (self::$selfDir === null) { self::$selfDir = strtr(__DIR__, '\\', '/'); } return self::$selfDir; } /** * @return array[] * @psalm-return list}> */ private static function getInstalled() { if (null === self::$canGetVendors) { self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders'); } $installed = array(); $copiedLocalDir = false; if (self::$canGetVendors) { $selfDir = self::getSelfDir(); foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { $vendorDir = strtr($vendorDir, '\\', '/'); 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'; self::$installedByVendor[$vendorDir] = $required; $installed[] = $required; if (self::$installed === null && $vendorDir.'/composer' === $selfDir) { self::$installed = $required; self::$installedIsLocalDir = true; } } if (self::$installedIsLocalDir && $vendorDir.'/composer' === $selfDir) { $copiedLocalDir = true; } } } 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() && !$copiedLocalDir) { $installed[] = self::$installed; } return $installed; } } ================================================ FILE: lib/Google/vendor/composer/LICENSE ================================================ 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. ================================================ FILE: lib/Google/vendor/composer/autoload_classmap.php ================================================ $vendorDir . '/composer/InstalledVersions.php', 'GPBMetadata\\GrpcGcp' => $vendorDir . '/google/grpc-gcp/src/generated/GPBMetadata/GrpcGcp.php', 'Google_AccessToken_Revoke' => $baseDir . '/src/aliases.php', 'Google_AccessToken_Verify' => $baseDir . '/src/aliases.php', 'Google_AuthHandler_AuthHandlerFactory' => $baseDir . '/src/aliases.php', 'Google_AuthHandler_Guzzle6AuthHandler' => $baseDir . '/src/aliases.php', 'Google_AuthHandler_Guzzle7AuthHandler' => $baseDir . '/src/aliases.php', 'Google_Client' => $baseDir . '/src/aliases.php', 'Google_Collection' => $baseDir . '/src/aliases.php', 'Google_Exception' => $baseDir . '/src/aliases.php', 'Google_Http_Batch' => $baseDir . '/src/aliases.php', 'Google_Http_MediaFileUpload' => $baseDir . '/src/aliases.php', 'Google_Http_REST' => $baseDir . '/src/aliases.php', 'Google_Model' => $baseDir . '/src/aliases.php', 'Google_Service' => $baseDir . '/src/aliases.php', 'Google_Service_Exception' => $baseDir . '/src/aliases.php', 'Google_Service_Resource' => $baseDir . '/src/aliases.php', 'Google_Task_Composer' => $baseDir . '/src/aliases.php', 'Google_Task_Exception' => $baseDir . '/src/aliases.php', 'Google_Task_Retryable' => $baseDir . '/src/aliases.php', 'Google_Task_Runner' => $baseDir . '/src/aliases.php', 'Google_Utils_UriTemplate' => $baseDir . '/src/aliases.php', 'Grpc\\Gcp\\AffinityConfig' => $vendorDir . '/google/grpc-gcp/src/generated/Grpc/Gcp/AffinityConfig.php', 'Grpc\\Gcp\\AffinityConfig_Command' => $vendorDir . '/google/grpc-gcp/src/generated/Grpc/Gcp/AffinityConfig_Command.php', 'Grpc\\Gcp\\ApiConfig' => $vendorDir . '/google/grpc-gcp/src/generated/Grpc/Gcp/ApiConfig.php', 'Grpc\\Gcp\\ChannelPoolConfig' => $vendorDir . '/google/grpc-gcp/src/generated/Grpc/Gcp/ChannelPoolConfig.php', 'Grpc\\Gcp\\MethodConfig' => $vendorDir . '/google/grpc-gcp/src/generated/Grpc/Gcp/MethodConfig.php', ); ================================================ FILE: lib/Google/vendor/composer/autoload_files.php ================================================ $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php', '6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php', '37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php', 'e39a8b23c42d4e1452234d762b03835a' => $vendorDir . '/ramsey/uuid/src/functions.php', '1f87db08236948d07391152dccb70f04' => $vendorDir . '/google/apiclient-services/autoload.php', 'decc78cc4436b1292c6c0d151b19445c' => $vendorDir . '/phpseclib/phpseclib/phpseclib/bootstrap.php', 'a8d3953fd9959404dd22d3dfcd0a79f0' => $baseDir . '/src/aliases.php', ); ================================================ FILE: lib/Google/vendor/composer/autoload_namespaces.php ================================================ array($vendorDir . '/phpseclib/phpseclib/phpseclib'), 'Rize\\' => array($vendorDir . '/rize/uri-template/src/Rize'), 'Ramsey\\Uuid\\' => array($vendorDir . '/ramsey/uuid/src'), 'Ramsey\\Collection\\' => array($vendorDir . '/ramsey/collection/src'), 'Psr\\Log\\' => array($vendorDir . '/psr/log/src'), 'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-factory/src', $vendorDir . '/psr/http-message/src'), 'Psr\\Http\\Client\\' => array($vendorDir . '/psr/http-client/src'), 'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'), 'ParagonIE\\ConstantTime\\' => array($vendorDir . '/paragonie/constant_time_encoding/src'), 'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'), 'GuzzleHttp\\Psr7\\' => array($vendorDir . '/guzzlehttp/psr7/src'), 'GuzzleHttp\\Promise\\' => array($vendorDir . '/guzzlehttp/promises/src'), 'GuzzleHttp\\' => array($vendorDir . '/guzzlehttp/guzzle/src'), 'Grpc\\Gcp\\' => array($vendorDir . '/google/grpc-gcp/src'), 'Grpc\\' => array($vendorDir . '/grpc/grpc/src/lib'), 'Google\\Type\\' => array($vendorDir . '/google/common-protos/src/Type'), 'Google\\Service\\' => array($vendorDir . '/google/apiclient-services/src'), 'Google\\Rpc\\' => array($vendorDir . '/google/common-protos/src/Rpc'), 'Google\\Protobuf\\' => array($vendorDir . '/google/protobuf/src/Google/Protobuf'), 'Google\\LongRunning\\' => array($vendorDir . '/google/longrunning/src/LongRunning'), 'Google\\Iam\\' => array($vendorDir . '/google/common-protos/src/Iam'), 'Google\\Cloud\\Storage\\' => array($vendorDir . '/google/cloud-storage/src'), 'Google\\Cloud\\Core\\' => array($vendorDir . '/google/cloud-core/src'), 'Google\\Cloud\\' => array($vendorDir . '/google/common-protos/src/Cloud'), 'Google\\Auth\\' => array($vendorDir . '/google/auth/src'), 'Google\\Api\\' => array($vendorDir . '/google/common-protos/src/Api'), 'Google\\ApiCore\\LongRunning\\' => array($vendorDir . '/google/longrunning/src/ApiCore/LongRunning'), 'Google\\ApiCore\\' => array($vendorDir . '/google/gax/src'), 'Google\\' => array($baseDir . '/src'), 'GPBMetadata\\Google\\Type\\' => array($vendorDir . '/google/common-protos/metadata/Type'), 'GPBMetadata\\Google\\Rpc\\' => array($vendorDir . '/google/common-protos/metadata/Rpc'), 'GPBMetadata\\Google\\Protobuf\\' => array($vendorDir . '/google/protobuf/src/GPBMetadata/Google/Protobuf'), 'GPBMetadata\\Google\\Longrunning\\' => array($vendorDir . '/google/longrunning/metadata/Longrunning'), 'GPBMetadata\\Google\\Logging\\' => array($vendorDir . '/google/common-protos/metadata/Logging'), 'GPBMetadata\\Google\\Iam\\' => array($vendorDir . '/google/common-protos/metadata/Iam'), 'GPBMetadata\\Google\\Cloud\\' => array($vendorDir . '/google/common-protos/metadata/Cloud'), 'GPBMetadata\\Google\\Api\\' => array($vendorDir . '/google/common-protos/metadata/Api'), 'GPBMetadata\\ApiCore\\' => array($vendorDir . '/google/gax/metadata/ApiCore'), 'Firebase\\JWT\\' => array($vendorDir . '/firebase/php-jwt/src'), 'Brick\\Math\\' => array($vendorDir . '/brick/math/src'), ); ================================================ FILE: lib/Google/vendor/composer/autoload_real.php ================================================ register(true); $filesToLoad = \Composer\Autoload\ComposerStaticInitc1ba3d113640ecbb1bd5645a9bacb037::$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; } } ================================================ FILE: lib/Google/vendor/composer/autoload_static.php ================================================ __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php', '6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php', '37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php', 'e39a8b23c42d4e1452234d762b03835a' => __DIR__ . '/..' . '/ramsey/uuid/src/functions.php', '1f87db08236948d07391152dccb70f04' => __DIR__ . '/..' . '/google/apiclient-services/autoload.php', 'decc78cc4436b1292c6c0d151b19445c' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/bootstrap.php', 'a8d3953fd9959404dd22d3dfcd0a79f0' => __DIR__ . '/../..' . '/src/aliases.php', ); public static $prefixLengthsPsr4 = array ( 'p' => array ( 'phpseclib3\\' => 11, ), 'R' => array ( 'Rize\\' => 5, 'Ramsey\\Uuid\\' => 12, 'Ramsey\\Collection\\' => 18, ), 'P' => array ( 'Psr\\Log\\' => 8, 'Psr\\Http\\Message\\' => 17, 'Psr\\Http\\Client\\' => 16, 'Psr\\Cache\\' => 10, 'ParagonIE\\ConstantTime\\' => 23, ), 'M' => array ( 'Monolog\\' => 8, ), 'G' => array ( 'GuzzleHttp\\Psr7\\' => 16, 'GuzzleHttp\\Promise\\' => 19, 'GuzzleHttp\\' => 11, 'Grpc\\Gcp\\' => 9, 'Grpc\\' => 5, 'Google\\Type\\' => 12, 'Google\\Service\\' => 15, 'Google\\Rpc\\' => 11, 'Google\\Protobuf\\' => 16, 'Google\\LongRunning\\' => 19, 'Google\\Iam\\' => 11, 'Google\\Cloud\\Storage\\' => 21, 'Google\\Cloud\\Core\\' => 18, 'Google\\Cloud\\' => 13, 'Google\\Auth\\' => 12, 'Google\\Api\\' => 11, 'Google\\ApiCore\\LongRunning\\' => 27, 'Google\\ApiCore\\' => 15, 'Google\\' => 7, 'GPBMetadata\\Google\\Type\\' => 24, 'GPBMetadata\\Google\\Rpc\\' => 23, 'GPBMetadata\\Google\\Protobuf\\' => 28, 'GPBMetadata\\Google\\Longrunning\\' => 31, 'GPBMetadata\\Google\\Logging\\' => 27, 'GPBMetadata\\Google\\Iam\\' => 23, 'GPBMetadata\\Google\\Cloud\\' => 25, 'GPBMetadata\\Google\\Api\\' => 23, 'GPBMetadata\\ApiCore\\' => 20, ), 'F' => array ( 'Firebase\\JWT\\' => 13, ), 'B' => array ( 'Brick\\Math\\' => 11, ), ); public static $prefixDirsPsr4 = array ( 'phpseclib3\\' => array ( 0 => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib', ), 'Rize\\' => array ( 0 => __DIR__ . '/..' . '/rize/uri-template/src/Rize', ), 'Ramsey\\Uuid\\' => array ( 0 => __DIR__ . '/..' . '/ramsey/uuid/src', ), 'Ramsey\\Collection\\' => array ( 0 => __DIR__ . '/..' . '/ramsey/collection/src', ), 'Psr\\Log\\' => array ( 0 => __DIR__ . '/..' . '/psr/log/src', ), 'Psr\\Http\\Message\\' => array ( 0 => __DIR__ . '/..' . '/psr/http-factory/src', 1 => __DIR__ . '/..' . '/psr/http-message/src', ), 'Psr\\Http\\Client\\' => array ( 0 => __DIR__ . '/..' . '/psr/http-client/src', ), 'Psr\\Cache\\' => array ( 0 => __DIR__ . '/..' . '/psr/cache/src', ), 'ParagonIE\\ConstantTime\\' => array ( 0 => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src', ), 'Monolog\\' => array ( 0 => __DIR__ . '/..' . '/monolog/monolog/src/Monolog', ), 'GuzzleHttp\\Psr7\\' => array ( 0 => __DIR__ . '/..' . '/guzzlehttp/psr7/src', ), 'GuzzleHttp\\Promise\\' => array ( 0 => __DIR__ . '/..' . '/guzzlehttp/promises/src', ), 'GuzzleHttp\\' => array ( 0 => __DIR__ . '/..' . '/guzzlehttp/guzzle/src', ), 'Grpc\\Gcp\\' => array ( 0 => __DIR__ . '/..' . '/google/grpc-gcp/src', ), 'Grpc\\' => array ( 0 => __DIR__ . '/..' . '/grpc/grpc/src/lib', ), 'Google\\Type\\' => array ( 0 => __DIR__ . '/..' . '/google/common-protos/src/Type', ), 'Google\\Service\\' => array ( 0 => __DIR__ . '/..' . '/google/apiclient-services/src', ), 'Google\\Rpc\\' => array ( 0 => __DIR__ . '/..' . '/google/common-protos/src/Rpc', ), 'Google\\Protobuf\\' => array ( 0 => __DIR__ . '/..' . '/google/protobuf/src/Google/Protobuf', ), 'Google\\LongRunning\\' => array ( 0 => __DIR__ . '/..' . '/google/longrunning/src/LongRunning', ), 'Google\\Iam\\' => array ( 0 => __DIR__ . '/..' . '/google/common-protos/src/Iam', ), 'Google\\Cloud\\Storage\\' => array ( 0 => __DIR__ . '/..' . '/google/cloud-storage/src', ), 'Google\\Cloud\\Core\\' => array ( 0 => __DIR__ . '/..' . '/google/cloud-core/src', ), 'Google\\Cloud\\' => array ( 0 => __DIR__ . '/..' . '/google/common-protos/src/Cloud', ), 'Google\\Auth\\' => array ( 0 => __DIR__ . '/..' . '/google/auth/src', ), 'Google\\Api\\' => array ( 0 => __DIR__ . '/..' . '/google/common-protos/src/Api', ), 'Google\\ApiCore\\LongRunning\\' => array ( 0 => __DIR__ . '/..' . '/google/longrunning/src/ApiCore/LongRunning', ), 'Google\\ApiCore\\' => array ( 0 => __DIR__ . '/..' . '/google/gax/src', ), 'Google\\' => array ( 0 => __DIR__ . '/../..' . '/src', ), 'GPBMetadata\\Google\\Type\\' => array ( 0 => __DIR__ . '/..' . '/google/common-protos/metadata/Type', ), 'GPBMetadata\\Google\\Rpc\\' => array ( 0 => __DIR__ . '/..' . '/google/common-protos/metadata/Rpc', ), 'GPBMetadata\\Google\\Protobuf\\' => array ( 0 => __DIR__ . '/..' . '/google/protobuf/src/GPBMetadata/Google/Protobuf', ), 'GPBMetadata\\Google\\Longrunning\\' => array ( 0 => __DIR__ . '/..' . '/google/longrunning/metadata/Longrunning', ), 'GPBMetadata\\Google\\Logging\\' => array ( 0 => __DIR__ . '/..' . '/google/common-protos/metadata/Logging', ), 'GPBMetadata\\Google\\Iam\\' => array ( 0 => __DIR__ . '/..' . '/google/common-protos/metadata/Iam', ), 'GPBMetadata\\Google\\Cloud\\' => array ( 0 => __DIR__ . '/..' . '/google/common-protos/metadata/Cloud', ), 'GPBMetadata\\Google\\Api\\' => array ( 0 => __DIR__ . '/..' . '/google/common-protos/metadata/Api', ), 'GPBMetadata\\ApiCore\\' => array ( 0 => __DIR__ . '/..' . '/google/gax/metadata/ApiCore', ), 'Firebase\\JWT\\' => array ( 0 => __DIR__ . '/..' . '/firebase/php-jwt/src', ), 'Brick\\Math\\' => array ( 0 => __DIR__ . '/..' . '/brick/math/src', ), ); public static $classMap = array ( 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', 'GPBMetadata\\GrpcGcp' => __DIR__ . '/..' . '/google/grpc-gcp/src/generated/GPBMetadata/GrpcGcp.php', 'Google_AccessToken_Revoke' => __DIR__ . '/../..' . '/src/aliases.php', 'Google_AccessToken_Verify' => __DIR__ . '/../..' . '/src/aliases.php', 'Google_AuthHandler_AuthHandlerFactory' => __DIR__ . '/../..' . '/src/aliases.php', 'Google_AuthHandler_Guzzle6AuthHandler' => __DIR__ . '/../..' . '/src/aliases.php', 'Google_AuthHandler_Guzzle7AuthHandler' => __DIR__ . '/../..' . '/src/aliases.php', 'Google_Client' => __DIR__ . '/../..' . '/src/aliases.php', 'Google_Collection' => __DIR__ . '/../..' . '/src/aliases.php', 'Google_Exception' => __DIR__ . '/../..' . '/src/aliases.php', 'Google_Http_Batch' => __DIR__ . '/../..' . '/src/aliases.php', 'Google_Http_MediaFileUpload' => __DIR__ . '/../..' . '/src/aliases.php', 'Google_Http_REST' => __DIR__ . '/../..' . '/src/aliases.php', 'Google_Model' => __DIR__ . '/../..' . '/src/aliases.php', 'Google_Service' => __DIR__ . '/../..' . '/src/aliases.php', 'Google_Service_Exception' => __DIR__ . '/../..' . '/src/aliases.php', 'Google_Service_Resource' => __DIR__ . '/../..' . '/src/aliases.php', 'Google_Task_Composer' => __DIR__ . '/../..' . '/src/aliases.php', 'Google_Task_Exception' => __DIR__ . '/../..' . '/src/aliases.php', 'Google_Task_Retryable' => __DIR__ . '/../..' . '/src/aliases.php', 'Google_Task_Runner' => __DIR__ . '/../..' . '/src/aliases.php', 'Google_Utils_UriTemplate' => __DIR__ . '/../..' . '/src/aliases.php', 'Grpc\\Gcp\\AffinityConfig' => __DIR__ . '/..' . '/google/grpc-gcp/src/generated/Grpc/Gcp/AffinityConfig.php', 'Grpc\\Gcp\\AffinityConfig_Command' => __DIR__ . '/..' . '/google/grpc-gcp/src/generated/Grpc/Gcp/AffinityConfig_Command.php', 'Grpc\\Gcp\\ApiConfig' => __DIR__ . '/..' . '/google/grpc-gcp/src/generated/Grpc/Gcp/ApiConfig.php', 'Grpc\\Gcp\\ChannelPoolConfig' => __DIR__ . '/..' . '/google/grpc-gcp/src/generated/Grpc/Gcp/ChannelPoolConfig.php', 'Grpc\\Gcp\\MethodConfig' => __DIR__ . '/..' . '/google/grpc-gcp/src/generated/Grpc/Gcp/MethodConfig.php', ); public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { $loader->prefixLengthsPsr4 = ComposerStaticInitc1ba3d113640ecbb1bd5645a9bacb037::$prefixLengthsPsr4; $loader->prefixDirsPsr4 = ComposerStaticInitc1ba3d113640ecbb1bd5645a9bacb037::$prefixDirsPsr4; $loader->classMap = ComposerStaticInitc1ba3d113640ecbb1bd5645a9bacb037::$classMap; }, null, ClassLoader::class); } } ================================================ FILE: lib/Google/vendor/composer/installed.json ================================================ { "packages": [ { "name": "brick/math", "version": "0.13.1", "version_normalized": "0.13.1.0", "source": { "type": "git", "url": "https://github.com/brick/math.git", "reference": "fc7ed316430118cc7836bf45faff18d5dfc8de04" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/brick/math/zipball/fc7ed316430118cc7836bf45faff18d5dfc8de04", "reference": "fc7ed316430118cc7836bf45faff18d5dfc8de04", "shasum": "" }, "require": { "php": "^8.1" }, "require-dev": { "php-coveralls/php-coveralls": "^2.2", "phpunit/phpunit": "^10.1", "vimeo/psalm": "6.8.8" }, "time": "2025-03-29T13:50:30+00:00", "type": "library", "installation-source": "dist", "autoload": { "psr-4": { "Brick\\Math\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "description": "Arbitrary-precision arithmetic library", "keywords": [ "Arbitrary-precision", "BigInteger", "BigRational", "arithmetic", "bigdecimal", "bignum", "bignumber", "brick", "decimal", "integer", "math", "mathematics", "rational" ], "support": { "issues": "https://github.com/brick/math/issues", "source": "https://github.com/brick/math/tree/0.13.1" }, "funding": [ { "url": "https://github.com/BenMorel", "type": "github" } ], "install-path": "../brick/math" }, { "name": "firebase/php-jwt", "version": "v7.0.2", "version_normalized": "7.0.2.0", "source": { "type": "git", "url": "https://github.com/firebase/php-jwt.git", "reference": "5645b43af647b6947daac1d0f659dd1fbe8d3b65" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/firebase/php-jwt/zipball/5645b43af647b6947daac1d0f659dd1fbe8d3b65", "reference": "5645b43af647b6947daac1d0f659dd1fbe8d3b65", "shasum": "" }, "require": { "php": "^8.0" }, "require-dev": { "guzzlehttp/guzzle": "^7.4", "phpspec/prophecy-phpunit": "^2.0", "phpunit/phpunit": "^9.5", "psr/cache": "^2.0||^3.0", "psr/http-client": "^1.0", "psr/http-factory": "^1.0" }, "suggest": { "ext-sodium": "Support EdDSA (Ed25519) signatures", "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present" }, "time": "2025-12-16T22:17:28+00:00", "type": "library", "installation-source": "dist", "autoload": { "psr-4": { "Firebase\\JWT\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Neuman Vong", "email": "neuman+pear@twilio.com", "role": "Developer" }, { "name": "Anant Narayanan", "email": "anant@php.net", "role": "Developer" } ], "description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.", "homepage": "https://github.com/firebase/php-jwt", "keywords": [ "jwt", "php" ], "support": { "issues": "https://github.com/firebase/php-jwt/issues", "source": "https://github.com/firebase/php-jwt/tree/v7.0.2" }, "install-path": "../firebase/php-jwt" }, { "name": "google/apiclient-services", "version": "v0.427.0", "version_normalized": "0.427.0.0", "source": { "type": "git", "url": "https://github.com/googleapis/google-api-php-client-services.git", "reference": "cc74cd104a1ed1cf545480c52f13831e6eb0efe2" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/cc74cd104a1ed1cf545480c52f13831e6eb0efe2", "reference": "cc74cd104a1ed1cf545480c52f13831e6eb0efe2", "shasum": "" }, "require": { "php": "^8.1" }, "require-dev": { "phpunit/phpunit": "^9.6" }, "time": "2025-12-24T01:04:22+00:00", "type": "library", "installation-source": "dist", "autoload": { "files": [ "autoload.php" ], "psr-4": { "Google\\Service\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "Apache-2.0" ], "description": "Client library for Google APIs", "homepage": "http://developers.google.com/api-client-library/php", "keywords": [ "google" ], "support": { "issues": "https://github.com/googleapis/google-api-php-client-services/issues", "source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.427.0" }, "install-path": "../google/apiclient-services" }, { "name": "google/auth", "version": "v1.50.0", "version_normalized": "1.50.0.0", "source": { "type": "git", "url": "https://github.com/googleapis/google-auth-library-php.git", "reference": "e1c26a718198e16d8a3c69b1cae136b73f959b0f" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/googleapis/google-auth-library-php/zipball/e1c26a718198e16d8a3c69b1cae136b73f959b0f", "reference": "e1c26a718198e16d8a3c69b1cae136b73f959b0f", "shasum": "" }, "require": { "firebase/php-jwt": "^6.0||^7.0", "guzzlehttp/guzzle": "^7.4.5", "guzzlehttp/psr7": "^2.4.5", "php": "^8.1", "psr/cache": "^2.0||^3.0", "psr/http-message": "^1.1||^2.0", "psr/log": "^3.0" }, "require-dev": { "guzzlehttp/promises": "^2.0", "kelvinmo/simplejwt": "^1.1.0", "phpseclib/phpseclib": "^3.0.35", "phpspec/prophecy-phpunit": "^2.1", "phpunit/phpunit": "^9.6", "sebastian/comparator": ">=1.2.3", "squizlabs/php_codesniffer": "^4.0", "symfony/filesystem": "^6.3||^7.3", "symfony/process": "^6.0||^7.0", "webmozart/assert": "^1.11||^2.0" }, "suggest": { "phpseclib/phpseclib": "May be used in place of OpenSSL for signing strings or for token management. Please require version ^2." }, "time": "2026-01-08T21:33:57+00:00", "type": "library", "installation-source": "dist", "autoload": { "psr-4": { "Google\\Auth\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "Apache-2.0" ], "description": "Google Auth Library for PHP", "homepage": "https://github.com/google/google-auth-library-php", "keywords": [ "Authentication", "google", "oauth2" ], "support": { "docs": "https://cloud.google.com/php/docs/reference/auth/latest", "issues": "https://github.com/googleapis/google-auth-library-php/issues", "source": "https://github.com/googleapis/google-auth-library-php/tree/v1.50.0" }, "install-path": "../google/auth" }, { "name": "google/cloud-core", "version": "v1.69.0", "version_normalized": "1.69.0.0", "source": { "type": "git", "url": "https://github.com/googleapis/google-cloud-php-core.git", "reference": "a35bcf9d79f7007eaaf325e00011d08f40494fb1" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/googleapis/google-cloud-php-core/zipball/a35bcf9d79f7007eaaf325e00011d08f40494fb1", "reference": "a35bcf9d79f7007eaaf325e00011d08f40494fb1", "shasum": "" }, "require": { "google/auth": "^1.34", "google/gax": "^1.38.0", "guzzlehttp/guzzle": "^6.5.8||^7.4.4", "guzzlehttp/promises": "^1.4||^2.0", "guzzlehttp/psr7": "^2.6", "monolog/monolog": "^2.9||^3.0", "php": "^8.1", "psr/http-message": "^1.0||^2.0", "rize/uri-template": "~0.3||~0.4" }, "require-dev": { "erusev/parsedown": "^1.6", "google/cloud-common-protos": "~0.5", "nikic/php-parser": "^5.6", "opis/closure": "^3.7|^4.0", "phpdocumentor/reflection": "^6.0", "phpdocumentor/reflection-docblock": "^5.3", "phpspec/prophecy-phpunit": "^2.0", "phpunit/phpunit": "^9.0", "squizlabs/php_codesniffer": "2.*" }, "suggest": { "opis/closure": "May be used to serialize closures to process jobs in the batch daemon. Please require version ^3.", "symfony/lock": "Required for the Spanner cached based session pool. Please require the following commit: 3.3.x-dev#1ba6ac9" }, "time": "2025-12-06T04:51:04+00:00", "bin": [ "bin/google-cloud-batch" ], "type": "library", "extra": { "component": { "id": "cloud-core", "path": "Core", "entry": "src/ServiceBuilder.php", "target": "googleapis/google-cloud-php-core.git" } }, "installation-source": "dist", "autoload": { "psr-4": { "Google\\Cloud\\Core\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "Apache-2.0" ], "description": "Google Cloud PHP shared dependency, providing functionality useful to all components.", "support": { "source": "https://github.com/googleapis/google-cloud-php-core/tree/v1.69.0" }, "install-path": "../google/cloud-core" }, { "name": "google/cloud-storage", "version": "v1.49.0", "version_normalized": "1.49.0.0", "source": { "type": "git", "url": "https://github.com/googleapis/google-cloud-php-storage.git", "reference": "30aefa19ce5af165cef8bb39c224cfa865461541" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/googleapis/google-cloud-php-storage/zipball/30aefa19ce5af165cef8bb39c224cfa865461541", "reference": "30aefa19ce5af165cef8bb39c224cfa865461541", "shasum": "" }, "require": { "google/cloud-core": "^1.57", "php": "^8.1", "ramsey/uuid": "^4.2.3" }, "require-dev": { "erusev/parsedown": "^1.6", "google/cloud-pubsub": "^2.0", "phpdocumentor/reflection": "^5.3.3||^6.0", "phpdocumentor/reflection-docblock": "^5.3", "phpseclib/phpseclib": "^2.0||^3.0", "phpspec/prophecy-phpunit": "^2.0", "phpunit/phpunit": "^9.0", "squizlabs/php_codesniffer": "2.*" }, "suggest": { "google/cloud-pubsub": "May be used to register a topic to receive bucket notifications.", "phpseclib/phpseclib": "May be used in place of OpenSSL for creating signed Cloud Storage URLs. Please require version ^2." }, "time": "2025-12-06T04:51:04+00:00", "type": "library", "extra": { "component": { "id": "cloud-storage", "path": "Storage", "entry": "src/StorageClient.php", "target": "googleapis/google-cloud-php-storage.git" } }, "installation-source": "dist", "autoload": { "psr-4": { "Google\\Cloud\\Storage\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "Apache-2.0" ], "description": "Cloud Storage Client for PHP", "support": { "source": "https://github.com/googleapis/google-cloud-php-storage/tree/v1.49.0" }, "install-path": "../google/cloud-storage" }, { "name": "google/common-protos", "version": "4.12.4", "version_normalized": "4.12.4.0", "source": { "type": "git", "url": "https://github.com/googleapis/common-protos-php.git", "reference": "0127156899af0df2681bd42024c60bd5360d64e3" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/googleapis/common-protos-php/zipball/0127156899af0df2681bd42024c60bd5360d64e3", "reference": "0127156899af0df2681bd42024c60bd5360d64e3", "shasum": "" }, "require": { "google/protobuf": "^4.31", "php": "^8.1" }, "require-dev": { "phpunit/phpunit": "^9.6" }, "time": "2025-09-20T01:29:44+00:00", "type": "library", "extra": { "component": { "id": "common-protos", "path": "CommonProtos", "entry": "README.md", "target": "googleapis/common-protos-php.git" } }, "installation-source": "dist", "autoload": { "psr-4": { "Google\\Api\\": "src/Api", "Google\\Iam\\": "src/Iam", "Google\\Rpc\\": "src/Rpc", "Google\\Type\\": "src/Type", "Google\\Cloud\\": "src/Cloud", "GPBMetadata\\Google\\Api\\": "metadata/Api", "GPBMetadata\\Google\\Iam\\": "metadata/Iam", "GPBMetadata\\Google\\Rpc\\": "metadata/Rpc", "GPBMetadata\\Google\\Type\\": "metadata/Type", "GPBMetadata\\Google\\Cloud\\": "metadata/Cloud", "GPBMetadata\\Google\\Logging\\": "metadata/Logging" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "Apache-2.0" ], "description": "Google API Common Protos for PHP", "homepage": "https://github.com/googleapis/common-protos-php", "keywords": [ "google" ], "support": { "source": "https://github.com/googleapis/common-protos-php/tree/v4.12.4" }, "install-path": "../google/common-protos" }, { "name": "google/gax", "version": "v1.40.0", "version_normalized": "1.40.0.0", "source": { "type": "git", "url": "https://github.com/googleapis/gax-php.git", "reference": "1d3834d60b3f0794427c64d2b27d7c627fbba92c" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/googleapis/gax-php/zipball/1d3834d60b3f0794427c64d2b27d7c627fbba92c", "reference": "1d3834d60b3f0794427c64d2b27d7c627fbba92c", "shasum": "" }, "require": { "google/auth": "^1.49", "google/common-protos": "^4.4", "google/grpc-gcp": "^0.4", "google/longrunning": "~0.4", "google/protobuf": "^4.31", "grpc/grpc": "^1.13", "guzzlehttp/promises": "^2.0", "guzzlehttp/psr7": "^2.0", "php": "^8.1", "ramsey/uuid": "^4.0" }, "conflict": { "ext-protobuf": "<4.31.0" }, "require-dev": { "phpspec/prophecy-phpunit": "^2.1", "phpstan/phpstan": "^2.0", "phpunit/phpunit": "^9.6", "squizlabs/php_codesniffer": "4.*" }, "time": "2025-12-04T18:45:15+00:00", "type": "library", "installation-source": "dist", "autoload": { "psr-4": { "Google\\ApiCore\\": "src", "GPBMetadata\\ApiCore\\": "metadata/ApiCore" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "description": "Google API Core for PHP", "homepage": "https://github.com/googleapis/gax-php", "keywords": [ "google" ], "support": { "issues": "https://github.com/googleapis/gax-php/issues", "source": "https://github.com/googleapis/gax-php/tree/v1.40.0" }, "install-path": "../google/gax" }, { "name": "google/grpc-gcp", "version": "v0.4.1", "version_normalized": "0.4.1.0", "source": { "type": "git", "url": "https://github.com/GoogleCloudPlatform/grpc-gcp-php.git", "reference": "e585b7721bbe806ef45b5c52ae43dfc2bff89968" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/GoogleCloudPlatform/grpc-gcp-php/zipball/e585b7721bbe806ef45b5c52ae43dfc2bff89968", "reference": "e585b7721bbe806ef45b5c52ae43dfc2bff89968", "shasum": "" }, "require": { "google/auth": "^1.3", "google/protobuf": "^v3.25.3||^4.26.1", "grpc/grpc": "^v1.13.0", "php": "^8.0", "psr/cache": "^1.0.1||^2.0.0||^3.0.0" }, "require-dev": { "google/cloud-spanner": "^1.7", "phpunit/phpunit": "^9.0" }, "time": "2025-02-19T21:53:22+00:00", "type": "library", "installation-source": "dist", "autoload": { "psr-4": { "Grpc\\Gcp\\": "src/" }, "classmap": [ "src/generated/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "Apache-2.0" ], "description": "gRPC GCP library for channel management", "support": { "issues": "https://github.com/GoogleCloudPlatform/grpc-gcp-php/issues", "source": "https://github.com/GoogleCloudPlatform/grpc-gcp-php/tree/v0.4.1" }, "install-path": "../google/grpc-gcp" }, { "name": "google/longrunning", "version": "0.6.0", "version_normalized": "0.6.0.0", "source": { "type": "git", "url": "https://github.com/googleapis/php-longrunning.git", "reference": "226d3b5166eaa13754cc5e452b37872478e23375" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/googleapis/php-longrunning/zipball/226d3b5166eaa13754cc5e452b37872478e23375", "reference": "226d3b5166eaa13754cc5e452b37872478e23375", "shasum": "" }, "require-dev": { "google/gax": "^1.38.0", "phpunit/phpunit": "^9.0" }, "time": "2025-10-07T18:41:09+00:00", "type": "library", "extra": { "component": { "id": "longrunning", "path": "LongRunning", "entry": null, "target": "googleapis/php-longrunning" } }, "installation-source": "dist", "autoload": { "psr-4": { "Google\\LongRunning\\": "src/LongRunning", "Google\\ApiCore\\LongRunning\\": "src/ApiCore/LongRunning", "GPBMetadata\\Google\\Longrunning\\": "metadata/Longrunning" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "Apache-2.0" ], "description": "Google LongRunning Client for PHP", "support": { "source": "https://github.com/googleapis/php-longrunning/tree/v0.6.0" }, "install-path": "../google/longrunning" }, { "name": "google/protobuf", "version": "v4.33.2", "version_normalized": "4.33.2.0", "source": { "type": "git", "url": "https://github.com/protocolbuffers/protobuf-php.git", "reference": "fbd96b7bf1343f4b0d8fb358526c7ba4d72f1318" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/protocolbuffers/protobuf-php/zipball/fbd96b7bf1343f4b0d8fb358526c7ba4d72f1318", "reference": "fbd96b7bf1343f4b0d8fb358526c7ba4d72f1318", "shasum": "" }, "require": { "php": ">=8.1.0" }, "require-dev": { "phpunit/phpunit": ">=5.0.0 <8.5.27" }, "suggest": { "ext-bcmath": "Need to support JSON deserialization" }, "time": "2025-12-05T22:12:22+00:00", "type": "library", "installation-source": "dist", "autoload": { "psr-4": { "Google\\Protobuf\\": "src/Google/Protobuf", "GPBMetadata\\Google\\Protobuf\\": "src/GPBMetadata/Google/Protobuf" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "description": "proto library for PHP", "homepage": "https://developers.google.com/protocol-buffers/", "keywords": [ "proto" ], "support": { "source": "https://github.com/protocolbuffers/protobuf-php/tree/v4.33.2" }, "install-path": "../google/protobuf" }, { "name": "grpc/grpc", "version": "1.74.0", "version_normalized": "1.74.0.0", "source": { "type": "git", "url": "https://github.com/grpc/grpc-php.git", "reference": "32bf4dba256d60d395582fb6e4e8d3936bcdb713" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/grpc/grpc-php/zipball/32bf4dba256d60d395582fb6e4e8d3936bcdb713", "reference": "32bf4dba256d60d395582fb6e4e8d3936bcdb713", "shasum": "" }, "require": { "php": ">=7.0.0" }, "require-dev": { "google/auth": "^v1.3.0" }, "suggest": { "ext-protobuf": "For better performance, install the protobuf C extension.", "google/protobuf": "To get started using grpc quickly, install the native protobuf library." }, "time": "2025-07-24T20:02:16+00:00", "type": "library", "installation-source": "dist", "autoload": { "psr-4": { "Grpc\\": "src/lib/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "Apache-2.0" ], "description": "gRPC library for PHP", "homepage": "https://grpc.io", "keywords": [ "rpc" ], "support": { "source": "https://github.com/grpc/grpc-php/tree/v1.74.0" }, "install-path": "../grpc/grpc" }, { "name": "guzzlehttp/guzzle", "version": "7.10.0", "version_normalized": "7.10.0.0", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", "reference": "b51ac707cfa420b7bfd4e4d5e510ba8008e822b4" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b51ac707cfa420b7bfd4e4d5e510ba8008e822b4", "reference": "b51ac707cfa420b7bfd4e4d5e510ba8008e822b4", "shasum": "" }, "require": { "ext-json": "*", "guzzlehttp/promises": "^2.3", "guzzlehttp/psr7": "^2.8", "php": "^7.2.5 || ^8.0", "psr/http-client": "^1.0", "symfony/deprecation-contracts": "^2.2 || ^3.0" }, "provide": { "psr/http-client-implementation": "1.0" }, "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", "ext-curl": "*", "guzzle/client-integration-tests": "3.0.2", "php-http/message-factory": "^1.1", "phpunit/phpunit": "^8.5.39 || ^9.6.20", "psr/log": "^1.1 || ^2.0 || ^3.0" }, "suggest": { "ext-curl": "Required for CURL handler support", "ext-intl": "Required for Internationalized Domain Name (IDN) support", "psr/log": "Required for using the Log middleware" }, "time": "2025-08-23T22:36:01+00:00", "type": "library", "extra": { "bamarni-bin": { "bin-links": true, "forward-command": false } }, "installation-source": "dist", "autoload": { "files": [ "src/functions_include.php" ], "psr-4": { "GuzzleHttp\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Graham Campbell", "email": "hello@gjcampbell.co.uk", "homepage": "https://github.com/GrahamCampbell" }, { "name": "Michael Dowling", "email": "mtdowling@gmail.com", "homepage": "https://github.com/mtdowling" }, { "name": "Jeremy Lindblom", "email": "jeremeamia@gmail.com", "homepage": "https://github.com/jeremeamia" }, { "name": "George Mponos", "email": "gmponos@gmail.com", "homepage": "https://github.com/gmponos" }, { "name": "Tobias Nyholm", "email": "tobias.nyholm@gmail.com", "homepage": "https://github.com/Nyholm" }, { "name": "Márk Sági-Kazár", "email": "mark.sagikazar@gmail.com", "homepage": "https://github.com/sagikazarmark" }, { "name": "Tobias Schultze", "email": "webmaster@tubo-world.de", "homepage": "https://github.com/Tobion" } ], "description": "Guzzle is a PHP HTTP client library", "keywords": [ "client", "curl", "framework", "http", "http client", "psr-18", "psr-7", "rest", "web service" ], "support": { "issues": "https://github.com/guzzle/guzzle/issues", "source": "https://github.com/guzzle/guzzle/tree/7.10.0" }, "funding": [ { "url": "https://github.com/GrahamCampbell", "type": "github" }, { "url": "https://github.com/Nyholm", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle", "type": "tidelift" } ], "install-path": "../guzzlehttp/guzzle" }, { "name": "guzzlehttp/promises", "version": "2.3.0", "version_normalized": "2.3.0.0", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", "reference": "481557b130ef3790cf82b713667b43030dc9c957" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/guzzle/promises/zipball/481557b130ef3790cf82b713667b43030dc9c957", "reference": "481557b130ef3790cf82b713667b43030dc9c957", "shasum": "" }, "require": { "php": "^7.2.5 || ^8.0" }, "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", "phpunit/phpunit": "^8.5.44 || ^9.6.25" }, "time": "2025-08-22T14:34:08+00:00", "type": "library", "extra": { "bamarni-bin": { "bin-links": true, "forward-command": false } }, "installation-source": "dist", "autoload": { "psr-4": { "GuzzleHttp\\Promise\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Graham Campbell", "email": "hello@gjcampbell.co.uk", "homepage": "https://github.com/GrahamCampbell" }, { "name": "Michael Dowling", "email": "mtdowling@gmail.com", "homepage": "https://github.com/mtdowling" }, { "name": "Tobias Nyholm", "email": "tobias.nyholm@gmail.com", "homepage": "https://github.com/Nyholm" }, { "name": "Tobias Schultze", "email": "webmaster@tubo-world.de", "homepage": "https://github.com/Tobion" } ], "description": "Guzzle promises library", "keywords": [ "promise" ], "support": { "issues": "https://github.com/guzzle/promises/issues", "source": "https://github.com/guzzle/promises/tree/2.3.0" }, "funding": [ { "url": "https://github.com/GrahamCampbell", "type": "github" }, { "url": "https://github.com/Nyholm", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", "type": "tidelift" } ], "install-path": "../guzzlehttp/promises" }, { "name": "guzzlehttp/psr7", "version": "2.8.0", "version_normalized": "2.8.0.0", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", "reference": "21dc724a0583619cd1652f673303492272778051" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/guzzle/psr7/zipball/21dc724a0583619cd1652f673303492272778051", "reference": "21dc724a0583619cd1652f673303492272778051", "shasum": "" }, "require": { "php": "^7.2.5 || ^8.0", "psr/http-factory": "^1.0", "psr/http-message": "^1.1 || ^2.0", "ralouphie/getallheaders": "^3.0" }, "provide": { "psr/http-factory-implementation": "1.0", "psr/http-message-implementation": "1.0" }, "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", "http-interop/http-factory-tests": "0.9.0", "phpunit/phpunit": "^8.5.44 || ^9.6.25" }, "suggest": { "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" }, "time": "2025-08-23T21:21:41+00:00", "type": "library", "extra": { "bamarni-bin": { "bin-links": true, "forward-command": false } }, "installation-source": "dist", "autoload": { "psr-4": { "GuzzleHttp\\Psr7\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Graham Campbell", "email": "hello@gjcampbell.co.uk", "homepage": "https://github.com/GrahamCampbell" }, { "name": "Michael Dowling", "email": "mtdowling@gmail.com", "homepage": "https://github.com/mtdowling" }, { "name": "George Mponos", "email": "gmponos@gmail.com", "homepage": "https://github.com/gmponos" }, { "name": "Tobias Nyholm", "email": "tobias.nyholm@gmail.com", "homepage": "https://github.com/Nyholm" }, { "name": "Márk Sági-Kazár", "email": "mark.sagikazar@gmail.com", "homepage": "https://github.com/sagikazarmark" }, { "name": "Tobias Schultze", "email": "webmaster@tubo-world.de", "homepage": "https://github.com/Tobion" }, { "name": "Márk Sági-Kazár", "email": "mark.sagikazar@gmail.com", "homepage": "https://sagikazarmark.hu" } ], "description": "PSR-7 message implementation that also provides common utility methods", "keywords": [ "http", "message", "psr-7", "request", "response", "stream", "uri", "url" ], "support": { "issues": "https://github.com/guzzle/psr7/issues", "source": "https://github.com/guzzle/psr7/tree/2.8.0" }, "funding": [ { "url": "https://github.com/GrahamCampbell", "type": "github" }, { "url": "https://github.com/Nyholm", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", "type": "tidelift" } ], "install-path": "../guzzlehttp/psr7" }, { "name": "monolog/monolog", "version": "3.10.0", "version_normalized": "3.10.0.0", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", "reference": "b321dd6749f0bf7189444158a3ce785cc16d69b0" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/Seldaek/monolog/zipball/b321dd6749f0bf7189444158a3ce785cc16d69b0", "reference": "b321dd6749f0bf7189444158a3ce785cc16d69b0", "shasum": "" }, "require": { "php": ">=8.1", "psr/log": "^2.0 || ^3.0" }, "provide": { "psr/log-implementation": "3.0.0" }, "require-dev": { "aws/aws-sdk-php": "^3.0", "doctrine/couchdb": "~1.0@dev", "elasticsearch/elasticsearch": "^7 || ^8", "ext-json": "*", "graylog2/gelf-php": "^1.4.2 || ^2.0", "guzzlehttp/guzzle": "^7.4.5", "guzzlehttp/psr7": "^2.2", "mongodb/mongodb": "^1.8 || ^2.0", "php-amqplib/php-amqplib": "~2.4 || ^3", "php-console/php-console": "^3.1.8", "phpstan/phpstan": "^2", "phpstan/phpstan-deprecation-rules": "^2", "phpstan/phpstan-strict-rules": "^2", "phpunit/phpunit": "^10.5.17 || ^11.0.7", "predis/predis": "^1.1 || ^2", "rollbar/rollbar": "^4.0", "ruflin/elastica": "^7 || ^8", "symfony/mailer": "^5.4 || ^6", "symfony/mime": "^5.4 || ^6" }, "suggest": { "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", "doctrine/couchdb": "Allow sending log messages to a CouchDB server", "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client", "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler", "ext-mbstring": "Allow to work properly with unicode symbols", "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)", "ext-openssl": "Required to send log messages using SSL", "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)", "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)", "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", "rollbar/rollbar": "Allow sending log messages to Rollbar", "ruflin/elastica": "Allow sending log messages to an Elastic Search server" }, "time": "2026-01-02T08:56:05+00:00", "type": "library", "extra": { "branch-alias": { "dev-main": "3.x-dev" } }, "installation-source": "dist", "autoload": { "psr-4": { "Monolog\\": "src/Monolog" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Jordi Boggiano", "email": "j.boggiano@seld.be", "homepage": "https://seld.be" } ], "description": "Sends your logs to files, sockets, inboxes, databases and various web services", "homepage": "https://github.com/Seldaek/monolog", "keywords": [ "log", "logging", "psr-3" ], "support": { "issues": "https://github.com/Seldaek/monolog/issues", "source": "https://github.com/Seldaek/monolog/tree/3.10.0" }, "funding": [ { "url": "https://github.com/Seldaek", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/monolog/monolog", "type": "tidelift" } ], "install-path": "../monolog/monolog" }, { "name": "paragonie/constant_time_encoding", "version": "v3.1.3", "version_normalized": "3.1.3.0", "source": { "type": "git", "url": "https://github.com/paragonie/constant_time_encoding.git", "reference": "d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77", "reference": "d5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77", "shasum": "" }, "require": { "php": "^8" }, "require-dev": { "infection/infection": "^0", "nikic/php-fuzzer": "^0", "phpunit/phpunit": "^9|^10|^11", "vimeo/psalm": "^4|^5|^6" }, "time": "2025-09-24T15:06:41+00:00", "type": "library", "installation-source": "dist", "autoload": { "psr-4": { "ParagonIE\\ConstantTime\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Paragon Initiative Enterprises", "email": "security@paragonie.com", "homepage": "https://paragonie.com", "role": "Maintainer" }, { "name": "Steve 'Sc00bz' Thomas", "email": "steve@tobtu.com", "homepage": "https://www.tobtu.com", "role": "Original Developer" } ], "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)", "keywords": [ "base16", "base32", "base32_decode", "base32_encode", "base64", "base64_decode", "base64_encode", "bin2hex", "encoding", "hex", "hex2bin", "rfc4648" ], "support": { "email": "info@paragonie.com", "issues": "https://github.com/paragonie/constant_time_encoding/issues", "source": "https://github.com/paragonie/constant_time_encoding" }, "install-path": "../paragonie/constant_time_encoding" }, { "name": "paragonie/random_compat", "version": "v9.99.100", "version_normalized": "9.99.100.0", "source": { "type": "git", "url": "https://github.com/paragonie/random_compat.git", "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a", "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a", "shasum": "" }, "require": { "php": ">= 7" }, "require-dev": { "phpunit/phpunit": "4.*|5.*", "vimeo/psalm": "^1" }, "suggest": { "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." }, "time": "2020-10-15T08:29:30+00:00", "type": "library", "installation-source": "dist", "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Paragon Initiative Enterprises", "email": "security@paragonie.com", "homepage": "https://paragonie.com" } ], "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", "keywords": [ "csprng", "polyfill", "pseudorandom", "random" ], "support": { "email": "info@paragonie.com", "issues": "https://github.com/paragonie/random_compat/issues", "source": "https://github.com/paragonie/random_compat" }, "install-path": "../paragonie/random_compat" }, { "name": "phpseclib/phpseclib", "version": "3.0.48", "version_normalized": "3.0.48.0", "source": { "type": "git", "url": "https://github.com/phpseclib/phpseclib.git", "reference": "64065a5679c50acb886e82c07aa139b0f757bb89" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/64065a5679c50acb886e82c07aa139b0f757bb89", "reference": "64065a5679c50acb886e82c07aa139b0f757bb89", "shasum": "" }, "require": { "paragonie/constant_time_encoding": "^1|^2|^3", "paragonie/random_compat": "^1.4|^2.0|^9.99.99", "php": ">=5.6.1" }, "require-dev": { "phpunit/phpunit": "*" }, "suggest": { "ext-dom": "Install the DOM extension to load XML formatted public keys.", "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations." }, "time": "2025-12-15T11:51:42+00:00", "type": "library", "installation-source": "dist", "autoload": { "files": [ "phpseclib/bootstrap.php" ], "psr-4": { "phpseclib3\\": "phpseclib/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Jim Wigginton", "email": "terrafrost@php.net", "role": "Lead Developer" }, { "name": "Patrick Monnerat", "email": "pm@datasphere.ch", "role": "Developer" }, { "name": "Andreas Fischer", "email": "bantu@phpbb.com", "role": "Developer" }, { "name": "Hans-Jürgen Petrich", "email": "petrich@tronic-media.com", "role": "Developer" }, { "name": "Graham Campbell", "email": "graham@alt-three.com", "role": "Developer" } ], "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", "homepage": "http://phpseclib.sourceforge.net", "keywords": [ "BigInteger", "aes", "asn.1", "asn1", "blowfish", "crypto", "cryptography", "encryption", "rsa", "security", "sftp", "signature", "signing", "ssh", "twofish", "x.509", "x509" ], "support": { "issues": "https://github.com/phpseclib/phpseclib/issues", "source": "https://github.com/phpseclib/phpseclib/tree/3.0.48" }, "funding": [ { "url": "https://github.com/terrafrost", "type": "github" }, { "url": "https://www.patreon.com/phpseclib", "type": "patreon" }, { "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib", "type": "tidelift" } ], "install-path": "../phpseclib/phpseclib" }, { "name": "psr/cache", "version": "3.0.0", "version_normalized": "3.0.0.0", "source": { "type": "git", "url": "https://github.com/php-fig/cache.git", "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", "shasum": "" }, "require": { "php": ">=8.0.0" }, "time": "2021-02-03T23:26:27+00:00", "type": "library", "extra": { "branch-alias": { "dev-master": "1.0.x-dev" } }, "installation-source": "dist", "autoload": { "psr-4": { "Psr\\Cache\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "PHP-FIG", "homepage": "https://www.php-fig.org/" } ], "description": "Common interface for caching libraries", "keywords": [ "cache", "psr", "psr-6" ], "support": { "source": "https://github.com/php-fig/cache/tree/3.0.0" }, "install-path": "../psr/cache" }, { "name": "psr/http-client", "version": "1.0.3", "version_normalized": "1.0.3.0", "source": { "type": "git", "url": "https://github.com/php-fig/http-client.git", "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", "shasum": "" }, "require": { "php": "^7.0 || ^8.0", "psr/http-message": "^1.0 || ^2.0" }, "time": "2023-09-23T14:17:50+00:00", "type": "library", "extra": { "branch-alias": { "dev-master": "1.0.x-dev" } }, "installation-source": "dist", "autoload": { "psr-4": { "Psr\\Http\\Client\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "PHP-FIG", "homepage": "https://www.php-fig.org/" } ], "description": "Common interface for HTTP clients", "homepage": "https://github.com/php-fig/http-client", "keywords": [ "http", "http-client", "psr", "psr-18" ], "support": { "source": "https://github.com/php-fig/http-client" }, "install-path": "../psr/http-client" }, { "name": "psr/http-factory", "version": "1.1.0", "version_normalized": "1.1.0.0", "source": { "type": "git", "url": "https://github.com/php-fig/http-factory.git", "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a", "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a", "shasum": "" }, "require": { "php": ">=7.1", "psr/http-message": "^1.0 || ^2.0" }, "time": "2024-04-15T12:06:14+00:00", "type": "library", "extra": { "branch-alias": { "dev-master": "1.0.x-dev" } }, "installation-source": "dist", "autoload": { "psr-4": { "Psr\\Http\\Message\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "PHP-FIG", "homepage": "https://www.php-fig.org/" } ], "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories", "keywords": [ "factory", "http", "message", "psr", "psr-17", "psr-7", "request", "response" ], "support": { "source": "https://github.com/php-fig/http-factory" }, "install-path": "../psr/http-factory" }, { "name": "psr/http-message", "version": "2.0", "version_normalized": "2.0.0.0", "source": { "type": "git", "url": "https://github.com/php-fig/http-message.git", "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", "shasum": "" }, "require": { "php": "^7.2 || ^8.0" }, "time": "2023-04-04T09:54:51+00:00", "type": "library", "extra": { "branch-alias": { "dev-master": "2.0.x-dev" } }, "installation-source": "dist", "autoload": { "psr-4": { "Psr\\Http\\Message\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "PHP-FIG", "homepage": "https://www.php-fig.org/" } ], "description": "Common interface for HTTP messages", "homepage": "https://github.com/php-fig/http-message", "keywords": [ "http", "http-message", "psr", "psr-7", "request", "response" ], "support": { "source": "https://github.com/php-fig/http-message/tree/2.0" }, "install-path": "../psr/http-message" }, { "name": "psr/log", "version": "3.0.2", "version_normalized": "3.0.2.0", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", "shasum": "" }, "require": { "php": ">=8.0.0" }, "time": "2024-09-11T13:17:53+00:00", "type": "library", "extra": { "branch-alias": { "dev-master": "3.x-dev" } }, "installation-source": "dist", "autoload": { "psr-4": { "Psr\\Log\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "PHP-FIG", "homepage": "https://www.php-fig.org/" } ], "description": "Common interface for logging libraries", "homepage": "https://github.com/php-fig/log", "keywords": [ "log", "psr", "psr-3" ], "support": { "source": "https://github.com/php-fig/log/tree/3.0.2" }, "install-path": "../psr/log" }, { "name": "ralouphie/getallheaders", "version": "3.0.3", "version_normalized": "3.0.3.0", "source": { "type": "git", "url": "https://github.com/ralouphie/getallheaders.git", "reference": "120b605dfeb996808c31b6477290a714d356e822" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", "reference": "120b605dfeb996808c31b6477290a714d356e822", "shasum": "" }, "require": { "php": ">=5.6" }, "require-dev": { "php-coveralls/php-coveralls": "^2.1", "phpunit/phpunit": "^5 || ^6.5" }, "time": "2019-03-08T08:55:37+00:00", "type": "library", "installation-source": "dist", "autoload": { "files": [ "src/getallheaders.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Ralph Khattar", "email": "ralph.khattar@gmail.com" } ], "description": "A polyfill for getallheaders.", "support": { "issues": "https://github.com/ralouphie/getallheaders/issues", "source": "https://github.com/ralouphie/getallheaders/tree/develop" }, "install-path": "../ralouphie/getallheaders" }, { "name": "ramsey/collection", "version": "2.1.1", "version_normalized": "2.1.1.0", "source": { "type": "git", "url": "https://github.com/ramsey/collection.git", "reference": "344572933ad0181accbf4ba763e85a0306a8c5e2" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/ramsey/collection/zipball/344572933ad0181accbf4ba763e85a0306a8c5e2", "reference": "344572933ad0181accbf4ba763e85a0306a8c5e2", "shasum": "" }, "require": { "php": "^8.1" }, "require-dev": { "captainhook/plugin-composer": "^5.3", "ergebnis/composer-normalize": "^2.45", "fakerphp/faker": "^1.24", "hamcrest/hamcrest-php": "^2.0", "jangregor/phpstan-prophecy": "^2.1", "mockery/mockery": "^1.6", "php-parallel-lint/php-console-highlighter": "^1.0", "php-parallel-lint/php-parallel-lint": "^1.4", "phpspec/prophecy-phpunit": "^2.3", "phpstan/extension-installer": "^1.4", "phpstan/phpstan": "^2.1", "phpstan/phpstan-mockery": "^2.0", "phpstan/phpstan-phpunit": "^2.0", "phpunit/phpunit": "^10.5", "ramsey/coding-standard": "^2.3", "ramsey/conventional-commits": "^1.6", "roave/security-advisories": "dev-latest" }, "time": "2025-03-22T05:38:12+00:00", "type": "library", "extra": { "captainhook": { "force-install": true }, "ramsey/conventional-commits": { "configFile": "conventional-commits.json" } }, "installation-source": "dist", "autoload": { "psr-4": { "Ramsey\\Collection\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Ben Ramsey", "email": "ben@benramsey.com", "homepage": "https://benramsey.com" } ], "description": "A PHP library for representing and manipulating collections.", "keywords": [ "array", "collection", "hash", "map", "queue", "set" ], "support": { "issues": "https://github.com/ramsey/collection/issues", "source": "https://github.com/ramsey/collection/tree/2.1.1" }, "install-path": "../ramsey/collection" }, { "name": "ramsey/uuid", "version": "4.9.2", "version_normalized": "4.9.2.0", "source": { "type": "git", "url": "https://github.com/ramsey/uuid.git", "reference": "8429c78ca35a09f27565311b98101e2826affde0" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/ramsey/uuid/zipball/8429c78ca35a09f27565311b98101e2826affde0", "reference": "8429c78ca35a09f27565311b98101e2826affde0", "shasum": "" }, "require": { "brick/math": "^0.8.16 || ^0.9 || ^0.10 || ^0.11 || ^0.12 || ^0.13 || ^0.14", "php": "^8.0", "ramsey/collection": "^1.2 || ^2.0" }, "replace": { "rhumsaa/uuid": "self.version" }, "require-dev": { "captainhook/captainhook": "^5.25", "captainhook/plugin-composer": "^5.3", "dealerdirect/phpcodesniffer-composer-installer": "^1.0", "ergebnis/composer-normalize": "^2.47", "mockery/mockery": "^1.6", "paragonie/random-lib": "^2", "php-mock/php-mock": "^2.6", "php-mock/php-mock-mockery": "^1.5", "php-parallel-lint/php-parallel-lint": "^1.4.0", "phpbench/phpbench": "^1.2.14", "phpstan/extension-installer": "^1.4", "phpstan/phpstan": "^2.1", "phpstan/phpstan-mockery": "^2.0", "phpstan/phpstan-phpunit": "^2.0", "phpunit/phpunit": "^9.6", "slevomat/coding-standard": "^8.18", "squizlabs/php_codesniffer": "^3.13" }, "suggest": { "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", "ext-gmp": "Enables faster math with arbitrary-precision integers using GMP.", "ext-uuid": "Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.", "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." }, "time": "2025-12-14T04:43:48+00:00", "type": "library", "extra": { "captainhook": { "force-install": true } }, "installation-source": "dist", "autoload": { "files": [ "src/functions.php" ], "psr-4": { "Ramsey\\Uuid\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "description": "A PHP library for generating and working with universally unique identifiers (UUIDs).", "keywords": [ "guid", "identifier", "uuid" ], "support": { "issues": "https://github.com/ramsey/uuid/issues", "source": "https://github.com/ramsey/uuid/tree/4.9.2" }, "install-path": "../ramsey/uuid" }, { "name": "rize/uri-template", "version": "0.4.1", "version_normalized": "0.4.1.0", "source": { "type": "git", "url": "https://github.com/rize/UriTemplate.git", "reference": "abb53c8b73a5b6c24e11f49036ab842f560cad33" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/rize/UriTemplate/zipball/abb53c8b73a5b6c24e11f49036ab842f560cad33", "reference": "abb53c8b73a5b6c24e11f49036ab842f560cad33", "shasum": "" }, "require": { "php": ">=8.1" }, "require-dev": { "friendsofphp/php-cs-fixer": "^3.63", "phpstan/phpstan": "^1.12", "phpunit/phpunit": "~10.0" }, "time": "2025-12-02T15:19:04+00:00", "type": "library", "installation-source": "dist", "autoload": { "psr-4": { "Rize\\": "src/Rize" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Marut K", "homepage": "http://twitter.com/rezigned" } ], "description": "PHP URI Template (RFC 6570) supports both expansion & extraction", "keywords": [ "RFC 6570", "template", "uri" ], "support": { "issues": "https://github.com/rize/UriTemplate/issues", "source": "https://github.com/rize/UriTemplate/tree/0.4.1" }, "funding": [ { "url": "https://www.paypal.me/rezigned", "type": "custom" }, { "url": "https://github.com/rezigned", "type": "github" }, { "url": "https://opencollective.com/rize-uri-template", "type": "open_collective" } ], "install-path": "../rize/uri-template" }, { "name": "symfony/deprecation-contracts", "version": "v3.6.0", "version_normalized": "3.6.0.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62", "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62", "shasum": "" }, "require": { "php": ">=8.1" }, "time": "2024-09-25T14:21:43+00:00", "type": "library", "extra": { "thanks": { "url": "https://github.com/symfony/contracts", "name": "symfony/contracts" }, "branch-alias": { "dev-main": "3.6-dev" } }, "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.6.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" } ], "dev": false, "dev-package-names": [] } ================================================ FILE: lib/Google/vendor/composer/installed.php ================================================ array( 'name' => 'google/apiclient', 'pretty_version' => 'dev-latest', 'version' => 'dev-latest', 'reference' => '9c990229a1ed5cd1870e57633f92abd945628365', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev' => false, ), 'versions' => array( 'brick/math' => array( 'pretty_version' => '0.13.1', 'version' => '0.13.1.0', 'reference' => 'fc7ed316430118cc7836bf45faff18d5dfc8de04', 'type' => 'library', 'install_path' => __DIR__ . '/../brick/math', 'aliases' => array(), 'dev_requirement' => false, ), 'firebase/php-jwt' => array( 'pretty_version' => 'v7.0.2', 'version' => '7.0.2.0', 'reference' => '5645b43af647b6947daac1d0f659dd1fbe8d3b65', 'type' => 'library', 'install_path' => __DIR__ . '/../firebase/php-jwt', 'aliases' => array(), 'dev_requirement' => false, ), 'google/apiclient' => array( 'pretty_version' => 'dev-latest', 'version' => 'dev-latest', 'reference' => '9c990229a1ed5cd1870e57633f92abd945628365', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev_requirement' => false, ), 'google/apiclient-services' => array( 'pretty_version' => 'v0.427.0', 'version' => '0.427.0.0', 'reference' => 'cc74cd104a1ed1cf545480c52f13831e6eb0efe2', 'type' => 'library', 'install_path' => __DIR__ . '/../google/apiclient-services', 'aliases' => array(), 'dev_requirement' => false, ), 'google/auth' => array( 'pretty_version' => 'v1.50.0', 'version' => '1.50.0.0', 'reference' => 'e1c26a718198e16d8a3c69b1cae136b73f959b0f', 'type' => 'library', 'install_path' => __DIR__ . '/../google/auth', 'aliases' => array(), 'dev_requirement' => false, ), 'google/cloud-core' => array( 'pretty_version' => 'v1.69.0', 'version' => '1.69.0.0', 'reference' => 'a35bcf9d79f7007eaaf325e00011d08f40494fb1', 'type' => 'library', 'install_path' => __DIR__ . '/../google/cloud-core', 'aliases' => array(), 'dev_requirement' => false, ), 'google/cloud-storage' => array( 'pretty_version' => 'v1.49.0', 'version' => '1.49.0.0', 'reference' => '30aefa19ce5af165cef8bb39c224cfa865461541', 'type' => 'library', 'install_path' => __DIR__ . '/../google/cloud-storage', 'aliases' => array(), 'dev_requirement' => false, ), 'google/common-protos' => array( 'pretty_version' => '4.12.4', 'version' => '4.12.4.0', 'reference' => '0127156899af0df2681bd42024c60bd5360d64e3', 'type' => 'library', 'install_path' => __DIR__ . '/../google/common-protos', 'aliases' => array(), 'dev_requirement' => false, ), 'google/gax' => array( 'pretty_version' => 'v1.40.0', 'version' => '1.40.0.0', 'reference' => '1d3834d60b3f0794427c64d2b27d7c627fbba92c', 'type' => 'library', 'install_path' => __DIR__ . '/../google/gax', 'aliases' => array(), 'dev_requirement' => false, ), 'google/grpc-gcp' => array( 'pretty_version' => 'v0.4.1', 'version' => '0.4.1.0', 'reference' => 'e585b7721bbe806ef45b5c52ae43dfc2bff89968', 'type' => 'library', 'install_path' => __DIR__ . '/../google/grpc-gcp', 'aliases' => array(), 'dev_requirement' => false, ), 'google/longrunning' => array( 'pretty_version' => '0.6.0', 'version' => '0.6.0.0', 'reference' => '226d3b5166eaa13754cc5e452b37872478e23375', 'type' => 'library', 'install_path' => __DIR__ . '/../google/longrunning', 'aliases' => array(), 'dev_requirement' => false, ), 'google/protobuf' => array( 'pretty_version' => 'v4.33.2', 'version' => '4.33.2.0', 'reference' => 'fbd96b7bf1343f4b0d8fb358526c7ba4d72f1318', 'type' => 'library', 'install_path' => __DIR__ . '/../google/protobuf', 'aliases' => array(), 'dev_requirement' => false, ), 'grpc/grpc' => array( 'pretty_version' => '1.74.0', 'version' => '1.74.0.0', 'reference' => '32bf4dba256d60d395582fb6e4e8d3936bcdb713', 'type' => 'library', 'install_path' => __DIR__ . '/../grpc/grpc', 'aliases' => array(), 'dev_requirement' => false, ), 'guzzlehttp/guzzle' => array( 'pretty_version' => '7.10.0', 'version' => '7.10.0.0', 'reference' => 'b51ac707cfa420b7bfd4e4d5e510ba8008e822b4', 'type' => 'library', 'install_path' => __DIR__ . '/../guzzlehttp/guzzle', 'aliases' => array(), 'dev_requirement' => false, ), 'guzzlehttp/promises' => array( 'pretty_version' => '2.3.0', 'version' => '2.3.0.0', 'reference' => '481557b130ef3790cf82b713667b43030dc9c957', 'type' => 'library', 'install_path' => __DIR__ . '/../guzzlehttp/promises', 'aliases' => array(), 'dev_requirement' => false, ), 'guzzlehttp/psr7' => array( 'pretty_version' => '2.8.0', 'version' => '2.8.0.0', 'reference' => '21dc724a0583619cd1652f673303492272778051', 'type' => 'library', 'install_path' => __DIR__ . '/../guzzlehttp/psr7', 'aliases' => array(), 'dev_requirement' => false, ), 'monolog/monolog' => array( 'pretty_version' => '3.10.0', 'version' => '3.10.0.0', 'reference' => 'b321dd6749f0bf7189444158a3ce785cc16d69b0', 'type' => 'library', 'install_path' => __DIR__ . '/../monolog/monolog', 'aliases' => array(), 'dev_requirement' => false, ), 'paragonie/constant_time_encoding' => array( 'pretty_version' => 'v3.1.3', 'version' => '3.1.3.0', 'reference' => 'd5b01a39b3415c2cd581d3bd3a3575c1ebbd8e77', 'type' => 'library', 'install_path' => __DIR__ . '/../paragonie/constant_time_encoding', 'aliases' => array(), 'dev_requirement' => false, ), 'paragonie/random_compat' => array( 'pretty_version' => 'v9.99.100', 'version' => '9.99.100.0', 'reference' => '996434e5492cb4c3edcb9168db6fbb1359ef965a', 'type' => 'library', 'install_path' => __DIR__ . '/../paragonie/random_compat', 'aliases' => array(), 'dev_requirement' => false, ), 'phpseclib/phpseclib' => array( 'pretty_version' => '3.0.48', 'version' => '3.0.48.0', 'reference' => '64065a5679c50acb886e82c07aa139b0f757bb89', 'type' => 'library', 'install_path' => __DIR__ . '/../phpseclib/phpseclib', 'aliases' => array(), 'dev_requirement' => false, ), 'psr/cache' => array( 'pretty_version' => '3.0.0', 'version' => '3.0.0.0', 'reference' => 'aa5030cfa5405eccfdcb1083ce040c2cb8d253bf', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/cache', 'aliases' => array(), 'dev_requirement' => false, ), 'psr/http-client' => array( 'pretty_version' => '1.0.3', 'version' => '1.0.3.0', 'reference' => 'bb5906edc1c324c9a05aa0873d40117941e5fa90', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/http-client', 'aliases' => array(), 'dev_requirement' => false, ), 'psr/http-client-implementation' => array( 'dev_requirement' => false, 'provided' => array( 0 => '1.0', ), ), 'psr/http-factory' => array( 'pretty_version' => '1.1.0', 'version' => '1.1.0.0', 'reference' => '2b4765fddfe3b508ac62f829e852b1501d3f6e8a', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/http-factory', 'aliases' => array(), 'dev_requirement' => false, ), 'psr/http-factory-implementation' => array( 'dev_requirement' => false, 'provided' => array( 0 => '1.0', ), ), 'psr/http-message' => array( 'pretty_version' => '2.0', 'version' => '2.0.0.0', 'reference' => '402d35bcb92c70c026d1a6a9883f06b2ead23d71', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/http-message', 'aliases' => array(), 'dev_requirement' => false, ), 'psr/http-message-implementation' => array( 'dev_requirement' => false, 'provided' => array( 0 => '1.0', ), ), 'psr/log' => array( 'pretty_version' => '3.0.2', 'version' => '3.0.2.0', 'reference' => 'f16e1d5863e37f8d8c2a01719f5b34baa2b714d3', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/log', 'aliases' => array(), 'dev_requirement' => false, ), 'psr/log-implementation' => array( 'dev_requirement' => false, 'provided' => array( 0 => '3.0.0', ), ), 'ralouphie/getallheaders' => array( 'pretty_version' => '3.0.3', 'version' => '3.0.3.0', 'reference' => '120b605dfeb996808c31b6477290a714d356e822', 'type' => 'library', 'install_path' => __DIR__ . '/../ralouphie/getallheaders', 'aliases' => array(), 'dev_requirement' => false, ), 'ramsey/collection' => array( 'pretty_version' => '2.1.1', 'version' => '2.1.1.0', 'reference' => '344572933ad0181accbf4ba763e85a0306a8c5e2', 'type' => 'library', 'install_path' => __DIR__ . '/../ramsey/collection', 'aliases' => array(), 'dev_requirement' => false, ), 'ramsey/uuid' => array( 'pretty_version' => '4.9.2', 'version' => '4.9.2.0', 'reference' => '8429c78ca35a09f27565311b98101e2826affde0', 'type' => 'library', 'install_path' => __DIR__ . '/../ramsey/uuid', 'aliases' => array(), 'dev_requirement' => false, ), 'rhumsaa/uuid' => array( 'dev_requirement' => false, 'replaced' => array( 0 => '4.9.2', ), ), 'rize/uri-template' => array( 'pretty_version' => '0.4.1', 'version' => '0.4.1.0', 'reference' => 'abb53c8b73a5b6c24e11f49036ab842f560cad33', 'type' => 'library', 'install_path' => __DIR__ . '/../rize/uri-template', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/deprecation-contracts' => array( 'pretty_version' => 'v3.6.0', 'version' => '3.6.0.0', 'reference' => '63afe740e99a13ba87ec199bb07bbdee937a5b62', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/deprecation-contracts', 'aliases' => array(), 'dev_requirement' => false, ), ), ); ================================================ FILE: lib/Google/vendor/composer/platform_check.php ================================================ = 80100)) { $issues[] = 'Your Composer dependencies require a PHP version ">= 8.1.0". You are running ' . PHP_VERSION . '.'; } if ($issues) { if (!headers_sent()) { header('HTTP/1.1 500 Internal Server Error'); } if (!ini_get('display_errors')) { if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL); } elseif (!headers_sent()) { echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; } } throw new \RuntimeException( 'Composer detected issues in your platform: ' . implode(' ', $issues) ); } ================================================ FILE: lib/Google/vendor/firebase/php-jwt/CHANGELOG.md ================================================ # Changelog ## [7.0.2](https://github.com/firebase/php-jwt/compare/v7.0.1...v7.0.2) (2025-12-16) ### Bug Fixes * add key length validation for ec keys ([#615](https://github.com/firebase/php-jwt/issues/615)) ([7044f9a](https://github.com/firebase/php-jwt/commit/7044f9ae7e7d175d28cca71714feb236f1c0e252)) ## [7.0.0](https://github.com/firebase/php-jwt/compare/v6.11.1...v7.0.0) (2025-12-15) ### ⚠️ ⚠️ ⚠️ Security Fixes ⚠️ ⚠️ ⚠️ * add key size validation ([#613](https://github.com/firebase/php-jwt/issues/613)) ([6b80341](https://github.com/firebase/php-jwt/commit/6b80341bf57838ea2d011487917337901cd71576)) **NOTE**: This fix will cause keys with a size below the minimally allowed size to break. ### Features * add SensitiveParameter attribute to security-critical parameters ([#603](https://github.com/firebase/php-jwt/issues/603)) ([4dbfac0](https://github.com/firebase/php-jwt/commit/4dbfac0260eeb0e9e643063c99998e3219cc539b)) * store timestamp in `ExpiredException` ([#604](https://github.com/firebase/php-jwt/issues/604)) ([f174826](https://github.com/firebase/php-jwt/commit/f1748260d218a856b6a0c23715ac7fae1d7ca95b)) ### Bug Fixes * validate iat and nbf on payload ([#568](https://github.com/firebase/php-jwt/issues/568)) ([953b2c8](https://github.com/firebase/php-jwt/commit/953b2c88bb445b7e3bb82a5141928f13d7343afd)) ## [6.11.1](https://github.com/firebase/php-jwt/compare/v6.11.0...v6.11.1) (2025-04-09) ### Bug Fixes * update error text for consistency ([#528](https://github.com/firebase/php-jwt/issues/528)) ([c11113a](https://github.com/firebase/php-jwt/commit/c11113afa13265e016a669e75494b9203b8a7775)) ## [6.11.0](https://github.com/firebase/php-jwt/compare/v6.10.2...v6.11.0) (2025-01-23) ### Features * support octet typed JWK ([#587](https://github.com/firebase/php-jwt/issues/587)) ([7cb8a26](https://github.com/firebase/php-jwt/commit/7cb8a265fa81edf2fa6ef8098f5bc5ae573c33ad)) ### Bug Fixes * refactor constructor Key to use PHP 8.0 syntax ([#577](https://github.com/firebase/php-jwt/issues/577)) ([29fa2ce](https://github.com/firebase/php-jwt/commit/29fa2ce9e0582cd397711eec1e80c05ce20fabca)) ## [6.10.2](https://github.com/firebase/php-jwt/compare/v6.10.1...v6.10.2) (2024-11-24) ### Bug Fixes * Mitigate PHP8.4 deprecation warnings ([#570](https://github.com/firebase/php-jwt/issues/570)) ([76808fa](https://github.com/firebase/php-jwt/commit/76808fa227f3811aa5cdb3bf81233714b799a5b5)) * support php 8.4 ([#583](https://github.com/firebase/php-jwt/issues/583)) ([e3d68b0](https://github.com/firebase/php-jwt/commit/e3d68b044421339443c74199edd020e03fb1887e)) ## [6.10.1](https://github.com/firebase/php-jwt/compare/v6.10.0...v6.10.1) (2024-05-18) ### Bug Fixes * ensure ratelimit expiry is set every time ([#556](https://github.com/firebase/php-jwt/issues/556)) ([09cb208](https://github.com/firebase/php-jwt/commit/09cb2081c2c3bc0f61e2f2a5fbea5741f7498648)) * ratelimit cache expiration ([#550](https://github.com/firebase/php-jwt/issues/550)) ([dda7250](https://github.com/firebase/php-jwt/commit/dda725033585ece30ff8cae8937320d7e9f18bae)) ## [6.10.0](https://github.com/firebase/php-jwt/compare/v6.9.0...v6.10.0) (2023-11-28) ### Features * allow typ header override ([#546](https://github.com/firebase/php-jwt/issues/546)) ([79cb30b](https://github.com/firebase/php-jwt/commit/79cb30b729a22931b2fbd6b53f20629a83031ba9)) ## [6.9.0](https://github.com/firebase/php-jwt/compare/v6.8.1...v6.9.0) (2023-10-04) ### Features * add payload to jwt exception ([#521](https://github.com/firebase/php-jwt/issues/521)) ([175edf9](https://github.com/firebase/php-jwt/commit/175edf958bb61922ec135b2333acf5622f2238a2)) ## [6.8.1](https://github.com/firebase/php-jwt/compare/v6.8.0...v6.8.1) (2023-07-14) ### Bug Fixes * accept float claims but round down to ignore them ([#492](https://github.com/firebase/php-jwt/issues/492)) ([3936842](https://github.com/firebase/php-jwt/commit/39368423beeaacb3002afa7dcb75baebf204fe7e)) * different BeforeValidException messages for nbf and iat ([#526](https://github.com/firebase/php-jwt/issues/526)) ([0a53cf2](https://github.com/firebase/php-jwt/commit/0a53cf2986e45c2bcbf1a269f313ebf56a154ee4)) ## [6.8.0](https://github.com/firebase/php-jwt/compare/v6.7.0...v6.8.0) (2023-06-14) ### Features * add support for P-384 curve ([#515](https://github.com/firebase/php-jwt/issues/515)) ([5de4323](https://github.com/firebase/php-jwt/commit/5de4323f4baf4d70bca8663bd87682a69c656c3d)) ### Bug Fixes * handle invalid http responses ([#508](https://github.com/firebase/php-jwt/issues/508)) ([91c39c7](https://github.com/firebase/php-jwt/commit/91c39c72b22fc3e1191e574089552c1f2041c718)) ## [6.7.0](https://github.com/firebase/php-jwt/compare/v6.6.0...v6.7.0) (2023-06-14) ### Features * add ed25519 support to JWK (public keys) ([#452](https://github.com/firebase/php-jwt/issues/452)) ([e53979a](https://github.com/firebase/php-jwt/commit/e53979abae927de916a75b9d239cfda8ce32be2a)) ## [6.6.0](https://github.com/firebase/php-jwt/compare/v6.5.0...v6.6.0) (2023-06-13) ### Features * allow get headers when decoding token ([#442](https://github.com/firebase/php-jwt/issues/442)) ([fb85f47](https://github.com/firebase/php-jwt/commit/fb85f47cfaeffdd94faf8defdf07164abcdad6c3)) ### Bug Fixes * only check iat if nbf is not used ([#493](https://github.com/firebase/php-jwt/issues/493)) ([398ccd2](https://github.com/firebase/php-jwt/commit/398ccd25ea12fa84b9e4f1085d5ff448c21ec797)) ## [6.5.0](https://github.com/firebase/php-jwt/compare/v6.4.0...v6.5.0) (2023-05-12) ### Bug Fixes * allow KID of '0' ([#505](https://github.com/firebase/php-jwt/issues/505)) ([9dc46a9](https://github.com/firebase/php-jwt/commit/9dc46a9c3e5801294249cfd2554c5363c9f9326a)) ### Miscellaneous Chores * drop support for PHP 7.3 ([#495](https://github.com/firebase/php-jwt/issues/495)) ## [6.4.0](https://github.com/firebase/php-jwt/compare/v6.3.2...v6.4.0) (2023-02-08) ### Features * add support for W3C ES256K ([#462](https://github.com/firebase/php-jwt/issues/462)) ([213924f](https://github.com/firebase/php-jwt/commit/213924f51936291fbbca99158b11bd4ae56c2c95)) * improve caching by only decoding jwks when necessary ([#486](https://github.com/firebase/php-jwt/issues/486)) ([78d3ed1](https://github.com/firebase/php-jwt/commit/78d3ed1073553f7d0bbffa6c2010009a0d483d5c)) ## [6.3.2](https://github.com/firebase/php-jwt/compare/v6.3.1...v6.3.2) (2022-11-01) ### Bug Fixes * check kid before using as array index ([bad1b04](https://github.com/firebase/php-jwt/commit/bad1b040d0c736bbf86814c6b5ae614f517cf7bd)) ## [6.3.1](https://github.com/firebase/php-jwt/compare/v6.3.0...v6.3.1) (2022-11-01) ### Bug Fixes * casing of GET for PSR compat ([#451](https://github.com/firebase/php-jwt/issues/451)) ([60b52b7](https://github.com/firebase/php-jwt/commit/60b52b71978790eafcf3b95cfbd83db0439e8d22)) * string interpolation format for php 8.2 ([#446](https://github.com/firebase/php-jwt/issues/446)) ([2e07d8a](https://github.com/firebase/php-jwt/commit/2e07d8a1524d12b69b110ad649f17461d068b8f2)) ## 6.3.0 / 2022-07-15 - Added ES256 support to JWK parsing ([#399](https://github.com/firebase/php-jwt/pull/399)) - Fixed potential caching error in `CachedKeySet` by caching jwks as strings ([#435](https://github.com/firebase/php-jwt/pull/435)) ## 6.2.0 / 2022-05-14 - Added `CachedKeySet` ([#397](https://github.com/firebase/php-jwt/pull/397)) - Added `$defaultAlg` parameter to `JWT::parseKey` and `JWT::parseKeySet` ([#426](https://github.com/firebase/php-jwt/pull/426)). ## 6.1.0 / 2022-03-23 - Drop support for PHP 5.3, 5.4, 5.5, 5.6, and 7.0 - Add parameter typing and return types where possible ## 6.0.0 / 2022-01-24 - **Backwards-Compatibility Breaking Changes**: See the [Release Notes](https://github.com/firebase/php-jwt/releases/tag/v6.0.0) for more information. - New Key object to prevent key/algorithm type confusion (#365) - Add JWK support (#273) - Add ES256 support (#256) - Add ES384 support (#324) - Add Ed25519 support (#343) ## 5.0.0 / 2017-06-26 - Support RS384 and RS512. See [#117](https://github.com/firebase/php-jwt/pull/117). Thanks [@joostfaassen](https://github.com/joostfaassen)! - Add an example for RS256 openssl. See [#125](https://github.com/firebase/php-jwt/pull/125). Thanks [@akeeman](https://github.com/akeeman)! - Detect invalid Base64 encoding in signature. See [#162](https://github.com/firebase/php-jwt/pull/162). Thanks [@psignoret](https://github.com/psignoret)! - Update `JWT::verify` to handle OpenSSL errors. See [#159](https://github.com/firebase/php-jwt/pull/159). Thanks [@bshaffer](https://github.com/bshaffer)! - Add `array` type hinting to `decode` method See [#101](https://github.com/firebase/php-jwt/pull/101). Thanks [@hywak](https://github.com/hywak)! - Add all JSON error types. See [#110](https://github.com/firebase/php-jwt/pull/110). Thanks [@gbalduzzi](https://github.com/gbalduzzi)! - Bugfix 'kid' not in given key list. See [#129](https://github.com/firebase/php-jwt/pull/129). Thanks [@stampycode](https://github.com/stampycode)! - Miscellaneous cleanup, documentation and test fixes. See [#107](https://github.com/firebase/php-jwt/pull/107), [#115](https://github.com/firebase/php-jwt/pull/115), [#160](https://github.com/firebase/php-jwt/pull/160), [#161](https://github.com/firebase/php-jwt/pull/161), and [#165](https://github.com/firebase/php-jwt/pull/165). Thanks [@akeeman](https://github.com/akeeman), [@chinedufn](https://github.com/chinedufn), and [@bshaffer](https://github.com/bshaffer)! ## 4.0.0 / 2016-07-17 - Add support for late static binding. See [#88](https://github.com/firebase/php-jwt/pull/88) for details. Thanks to [@chappy84](https://github.com/chappy84)! - Use static `$timestamp` instead of `time()` to improve unit testing. See [#93](https://github.com/firebase/php-jwt/pull/93) for details. Thanks to [@josephmcdermott](https://github.com/josephmcdermott)! - Fixes to exceptions classes. See [#81](https://github.com/firebase/php-jwt/pull/81) for details. Thanks to [@Maks3w](https://github.com/Maks3w)! - Fixes to PHPDoc. See [#76](https://github.com/firebase/php-jwt/pull/76) for details. Thanks to [@akeeman](https://github.com/akeeman)! ## 3.0.0 / 2015-07-22 - Minimum PHP version updated from `5.2.0` to `5.3.0`. - Add `\Firebase\JWT` namespace. See [#59](https://github.com/firebase/php-jwt/pull/59) for details. Thanks to [@Dashron](https://github.com/Dashron)! - Require a non-empty key to decode and verify a JWT. See [#60](https://github.com/firebase/php-jwt/pull/60) for details. Thanks to [@sjones608](https://github.com/sjones608)! - Cleaner documentation blocks in the code. See [#62](https://github.com/firebase/php-jwt/pull/62) for details. Thanks to [@johanderuijter](https://github.com/johanderuijter)! ## 2.2.0 / 2015-06-22 - Add support for adding custom, optional JWT headers to `JWT::encode()`. See [#53](https://github.com/firebase/php-jwt/pull/53/files) for details. Thanks to [@mcocaro](https://github.com/mcocaro)! ## 2.1.0 / 2015-05-20 - Add support for adding a leeway to `JWT:decode()` that accounts for clock skew between signing and verifying entities. Thanks to [@lcabral](https://github.com/lcabral)! - Add support for passing an object implementing the `ArrayAccess` interface for `$keys` argument in `JWT::decode()`. Thanks to [@aztech-dev](https://github.com/aztech-dev)! ## 2.0.0 / 2015-04-01 - **Note**: It is strongly recommended that you update to > v2.0.0 to address known security vulnerabilities in prior versions when both symmetric and asymmetric keys are used together. - Update signature for `JWT::decode(...)` to require an array of supported algorithms to use when verifying token signatures. ================================================ FILE: lib/Google/vendor/firebase/php-jwt/LICENSE ================================================ Copyright (c) 2011, Neuman Vong 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 other 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. ================================================ FILE: lib/Google/vendor/firebase/php-jwt/README.md ================================================ ![Build Status](https://github.com/firebase/php-jwt/actions/workflows/tests.yml/badge.svg) [![Latest Stable Version](https://poser.pugx.org/firebase/php-jwt/v/stable)](https://packagist.org/packages/firebase/php-jwt) [![Total Downloads](https://poser.pugx.org/firebase/php-jwt/downloads)](https://packagist.org/packages/firebase/php-jwt) [![License](https://poser.pugx.org/firebase/php-jwt/license)](https://packagist.org/packages/firebase/php-jwt) PHP-JWT ======= A simple library to encode and decode JSON Web Tokens (JWT) in PHP, conforming to [RFC 7519](https://tools.ietf.org/html/rfc7519). Installation ------------ Use composer to manage your dependencies and download PHP-JWT: ```bash composer require firebase/php-jwt ``` Optionally, install the `paragonie/sodium_compat` package from composer if your php env does not have libsodium installed: ```bash composer require paragonie/sodium_compat ``` Example ------- ```php use Firebase\JWT\JWT; use Firebase\JWT\Key; $key = 'example_key'; $payload = [ 'iss' => 'http://example.org', 'aud' => 'http://example.com', 'iat' => 1356999524, 'nbf' => 1357000000 ]; /** * IMPORTANT: * You must specify supported algorithms for your application. See * https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40 * for a list of spec-compliant algorithms. */ $jwt = JWT::encode($payload, $key, 'HS256'); $decoded = JWT::decode($jwt, new Key($key, 'HS256')); print_r($decoded); // Pass a stdClass in as the third parameter to get the decoded header values $headers = new stdClass(); $decoded = JWT::decode($jwt, new Key($key, 'HS256'), $headers); print_r($headers); /* NOTE: This will now be an object instead of an associative array. To get an associative array, you will need to cast it as such: */ $decoded_array = (array) $decoded; /** * You can add a leeway to account for when there is a clock skew times between * the signing and verifying servers. It is recommended that this leeway should * not be bigger than a few minutes. * * Source: http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html#nbfDef */ JWT::$leeway = 60; // $leeway in seconds $decoded = JWT::decode($jwt, new Key($key, 'HS256')); ``` Example encode/decode headers ------- Decoding the JWT headers without verifying the JWT first is NOT recommended, and is not supported by this library. This is because without verifying the JWT, the header values could have been tampered with. Any value pulled from an unverified header should be treated as if it could be any string sent in from an attacker. If this is something you still want to do in your application for whatever reason, it's possible to decode the header values manually simply by calling `json_decode` and `base64_decode` on the JWT header part: ```php use Firebase\JWT\JWT; $key = 'example_key'; $payload = [ 'iss' => 'http://example.org', 'aud' => 'http://example.com', 'iat' => 1356999524, 'nbf' => 1357000000 ]; $headers = [ 'x-forwarded-for' => 'www.google.com' ]; // Encode headers in the JWT string $jwt = JWT::encode($payload, $key, 'HS256', null, $headers); // Decode headers from the JWT string WITHOUT validation // **IMPORTANT**: This operation is vulnerable to attacks, as the JWT has not yet been verified. // These headers could be any value sent by an attacker. list($headersB64, $payloadB64, $sig) = explode('.', $jwt); $decoded = json_decode(base64_decode($headersB64), true); print_r($decoded); ``` Example with RS256 (openssl) ---------------------------- ```php use Firebase\JWT\JWT; use Firebase\JWT\Key; $privateKey = << 'example.org', 'aud' => 'example.com', 'iat' => 1356999524, 'nbf' => 1357000000 ]; $jwt = JWT::encode($payload, $privateKey, 'RS256'); echo "Encode:\n" . print_r($jwt, true) . "\n"; $decoded = JWT::decode($jwt, new Key($publicKey, 'RS256')); /* NOTE: This will now be an object instead of an associative array. To get an associative array, you will need to cast it as such: */ $decoded_array = (array) $decoded; echo "Decode:\n" . print_r($decoded_array, true) . "\n"; ``` Example with a passphrase ------------------------- ```php use Firebase\JWT\JWT; use Firebase\JWT\Key; // Your passphrase $passphrase = '[YOUR_PASSPHRASE]'; // Your private key file with passphrase // Can be generated with "ssh-keygen -t rsa -m pem" $privateKeyFile = '/path/to/key-with-passphrase.pem'; /** @var OpenSSLAsymmetricKey $privateKey */ $privateKey = openssl_pkey_get_private( file_get_contents($privateKeyFile), $passphrase ); $payload = [ 'iss' => 'example.org', 'aud' => 'example.com', 'iat' => 1356999524, 'nbf' => 1357000000 ]; $jwt = JWT::encode($payload, $privateKey, 'RS256'); echo "Encode:\n" . print_r($jwt, true) . "\n"; // Get public key from the private key, or pull from from a file. $publicKey = openssl_pkey_get_details($privateKey)['key']; $decoded = JWT::decode($jwt, new Key($publicKey, 'RS256')); echo "Decode:\n" . print_r((array) $decoded, true) . "\n"; ``` Example with EdDSA (libsodium and Ed25519 signature) ---------------------------- ```php use Firebase\JWT\JWT; use Firebase\JWT\Key; // Public and private keys are expected to be Base64 encoded. The last // non-empty line is used so that keys can be generated with // sodium_crypto_sign_keypair(). The secret keys generated by other tools may // need to be adjusted to match the input expected by libsodium. $keyPair = sodium_crypto_sign_keypair(); $privateKey = base64_encode(sodium_crypto_sign_secretkey($keyPair)); $publicKey = base64_encode(sodium_crypto_sign_publickey($keyPair)); $payload = [ 'iss' => 'example.org', 'aud' => 'example.com', 'iat' => 1356999524, 'nbf' => 1357000000 ]; $jwt = JWT::encode($payload, $privateKey, 'EdDSA'); echo "Encode:\n" . print_r($jwt, true) . "\n"; $decoded = JWT::decode($jwt, new Key($publicKey, 'EdDSA')); echo "Decode:\n" . print_r((array) $decoded, true) . "\n"; ```` Example with multiple keys -------------------------- ```php use Firebase\JWT\JWT; use Firebase\JWT\Key; // Example RSA keys from previous example // $privateKey1 = '...'; // $publicKey1 = '...'; // Example EdDSA keys from previous example // $privateKey2 = '...'; // $publicKey2 = '...'; $payload = [ 'iss' => 'example.org', 'aud' => 'example.com', 'iat' => 1356999524, 'nbf' => 1357000000 ]; $jwt1 = JWT::encode($payload, $privateKey1, 'RS256', 'kid1'); $jwt2 = JWT::encode($payload, $privateKey2, 'EdDSA', 'kid2'); echo "Encode 1:\n" . print_r($jwt1, true) . "\n"; echo "Encode 2:\n" . print_r($jwt2, true) . "\n"; $keys = [ 'kid1' => new Key($publicKey1, 'RS256'), 'kid2' => new Key($publicKey2, 'EdDSA'), ]; $decoded1 = JWT::decode($jwt1, $keys); $decoded2 = JWT::decode($jwt2, $keys); echo "Decode 1:\n" . print_r((array) $decoded1, true) . "\n"; echo "Decode 2:\n" . print_r((array) $decoded2, true) . "\n"; ``` Using JWKs ---------- ```php use Firebase\JWT\JWK; use Firebase\JWT\JWT; // Set of keys. The "keys" key is required. For example, the JSON response to // this endpoint: https://www.gstatic.com/iap/verify/public_key-jwk $jwks = ['keys' => []]; // JWK::parseKeySet($jwks) returns an associative array of **kid** to Firebase\JWT\Key // objects. Pass this as the second parameter to JWT::decode. JWT::decode($jwt, JWK::parseKeySet($jwks)); ``` Using Cached Key Sets --------------------- The `CachedKeySet` class can be used to fetch and cache JWKS (JSON Web Key Sets) from a public URI. This has the following advantages: 1. The results are cached for performance. 2. If an unrecognized key is requested, the cache is refreshed, to accomodate for key rotation. 3. If rate limiting is enabled, the JWKS URI will not make more than 10 requests a second. ```php use Firebase\JWT\CachedKeySet; use Firebase\JWT\JWT; // The URI for the JWKS you wish to cache the results from $jwksUri = 'https://www.gstatic.com/iap/verify/public_key-jwk'; // Create an HTTP client (can be any PSR-7 compatible HTTP client) $httpClient = new GuzzleHttp\Client(); // Create an HTTP request factory (can be any PSR-17 compatible HTTP request factory) $httpFactory = new GuzzleHttp\Psr\HttpFactory(); // Create a cache item pool (can be any PSR-6 compatible cache item pool) $cacheItemPool = Phpfastcache\CacheManager::getInstance('files'); $keySet = new CachedKeySet( $jwksUri, $httpClient, $httpFactory, $cacheItemPool, null, // $expiresAfter int seconds to set the JWKS to expire true // $rateLimit true to enable rate limit of 10 RPS on lookup of invalid keys ); $jwt = 'eyJhbGci...'; // Some JWT signed by a key from the $jwkUri above $decoded = JWT::decode($jwt, $keySet); ``` Miscellaneous ------------- #### Exception Handling When a call to `JWT::decode` is invalid, it will throw one of the following exceptions: ```php use Firebase\JWT\JWT; use Firebase\JWT\SignatureInvalidException; use Firebase\JWT\BeforeValidException; use Firebase\JWT\ExpiredException; use DomainException; use InvalidArgumentException; use UnexpectedValueException; try { $decoded = JWT::decode($jwt, $keys); } catch (InvalidArgumentException $e) { // provided key/key-array is empty or malformed. } catch (DomainException $e) { // provided algorithm is unsupported OR // provided key is invalid OR // unknown error thrown in openSSL or libsodium OR // libsodium is required but not available. } catch (SignatureInvalidException $e) { // provided JWT signature verification failed. } catch (BeforeValidException $e) { // provided JWT is trying to be used before "nbf" claim OR // provided JWT is trying to be used before "iat" claim. } catch (ExpiredException $e) { // provided JWT is trying to be used after "exp" claim. } catch (UnexpectedValueException $e) { // provided JWT is malformed OR // provided JWT is missing an algorithm / using an unsupported algorithm OR // provided JWT algorithm does not match provided key OR // provided key ID in key/key-array is empty or invalid. } ``` All exceptions in the `Firebase\JWT` namespace extend `UnexpectedValueException`, and can be simplified like this: ```php use Firebase\JWT\JWT; use UnexpectedValueException; try { $decoded = JWT::decode($jwt, $keys); } catch (LogicException $e) { // errors having to do with environmental setup or malformed JWT Keys } catch (UnexpectedValueException $e) { // errors having to do with JWT signature and claims } ``` #### Casting to array The return value of `JWT::decode` is the generic PHP object `stdClass`. If you'd like to handle with arrays instead, you can do the following: ```php // return type is stdClass $decoded = JWT::decode($jwt, $keys); // cast to array $decoded = json_decode(json_encode($decoded), true); ``` Tests ----- Run the tests using phpunit: ```bash $ pear install PHPUnit $ phpunit --configuration phpunit.xml.dist PHPUnit 3.7.10 by Sebastian Bergmann. ..... Time: 0 seconds, Memory: 2.50Mb OK (5 tests, 5 assertions) ``` New Lines in private keys ----- If your private key contains `\n` characters, be sure to wrap it in double quotes `""` and not single quotes `''` in order to properly interpret the escaped characters. License ------- [3-Clause BSD](http://opensource.org/licenses/BSD-3-Clause). ================================================ FILE: lib/Google/vendor/firebase/php-jwt/composer.json ================================================ { "name": "firebase/php-jwt", "description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.", "homepage": "https://github.com/firebase/php-jwt", "keywords": [ "php", "jwt" ], "authors": [ { "name": "Neuman Vong", "email": "neuman+pear@twilio.com", "role": "Developer" }, { "name": "Anant Narayanan", "email": "anant@php.net", "role": "Developer" } ], "license": "BSD-3-Clause", "require": { "php": "^8.0" }, "suggest": { "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present", "ext-sodium": "Support EdDSA (Ed25519) signatures" }, "autoload": { "psr-4": { "Firebase\\JWT\\": "src" } }, "require-dev": { "guzzlehttp/guzzle": "^7.4", "phpspec/prophecy-phpunit": "^2.0", "phpunit/phpunit": "^9.5", "psr/cache": "^2.0||^3.0", "psr/http-client": "^1.0", "psr/http-factory": "^1.0" } } ================================================ FILE: lib/Google/vendor/firebase/php-jwt/src/BeforeValidException.php ================================================ payload = $payload; } public function getPayload(): object { return $this->payload; } } ================================================ FILE: lib/Google/vendor/firebase/php-jwt/src/CachedKeySet.php ================================================ */ class CachedKeySet implements ArrayAccess { /** * @var string */ private $jwksUri; /** * @var ClientInterface */ private $httpClient; /** * @var RequestFactoryInterface */ private $httpFactory; /** * @var CacheItemPoolInterface */ private $cache; /** * @var ?int */ private $expiresAfter; /** * @var ?CacheItemInterface */ private $cacheItem; /** * @var array> */ private $keySet; /** * @var string */ private $cacheKey; /** * @var string */ private $cacheKeyPrefix = 'jwks'; /** * @var int */ private $maxKeyLength = 64; /** * @var bool */ private $rateLimit; /** * @var string */ private $rateLimitCacheKey; /** * @var int */ private $maxCallsPerMinute = 10; /** * @var string|null */ private $defaultAlg; public function __construct( string $jwksUri, ClientInterface $httpClient, RequestFactoryInterface $httpFactory, CacheItemPoolInterface $cache, ?int $expiresAfter = null, bool $rateLimit = false, ?string $defaultAlg = null ) { $this->jwksUri = $jwksUri; $this->httpClient = $httpClient; $this->httpFactory = $httpFactory; $this->cache = $cache; $this->expiresAfter = $expiresAfter; $this->rateLimit = $rateLimit; $this->defaultAlg = $defaultAlg; $this->setCacheKeys(); } /** * @param string $keyId * @return Key */ public function offsetGet($keyId): Key { if (!$this->keyIdExists($keyId)) { throw new OutOfBoundsException('Key ID not found'); } return JWK::parseKey($this->keySet[$keyId], $this->defaultAlg); } /** * @param string $keyId * @return bool */ public function offsetExists($keyId): bool { return $this->keyIdExists($keyId); } /** * @param string $offset * @param Key $value */ public function offsetSet($offset, $value): void { throw new LogicException('Method not implemented'); } /** * @param string $offset */ public function offsetUnset($offset): void { throw new LogicException('Method not implemented'); } /** * @return array */ private function formatJwksForCache(string $jwks): array { $jwks = json_decode($jwks, true); if (!isset($jwks['keys'])) { throw new UnexpectedValueException('"keys" member must exist in the JWK Set'); } if (empty($jwks['keys'])) { throw new InvalidArgumentException('JWK Set did not contain any keys'); } $keys = []; foreach ($jwks['keys'] as $k => $v) { $kid = isset($v['kid']) ? $v['kid'] : $k; $keys[(string) $kid] = $v; } return $keys; } private function keyIdExists(string $keyId): bool { if (null === $this->keySet) { $item = $this->getCacheItem(); // Try to load keys from cache if ($item->isHit()) { // item found! retrieve it $this->keySet = $item->get(); // If the cached item is a string, the JWKS response was cached (previous behavior). // Parse this into expected format array instead. if (\is_string($this->keySet)) { $this->keySet = $this->formatJwksForCache($this->keySet); } } } if (!isset($this->keySet[$keyId])) { if ($this->rateLimitExceeded()) { return false; } $request = $this->httpFactory->createRequest('GET', $this->jwksUri); $jwksResponse = $this->httpClient->sendRequest($request); if ($jwksResponse->getStatusCode() !== 200) { throw new UnexpectedValueException( \sprintf('HTTP Error: %d %s for URI "%s"', $jwksResponse->getStatusCode(), $jwksResponse->getReasonPhrase(), $this->jwksUri, ), $jwksResponse->getStatusCode() ); } $this->keySet = $this->formatJwksForCache((string) $jwksResponse->getBody()); if (!isset($this->keySet[$keyId])) { return false; } $item = $this->getCacheItem(); $item->set($this->keySet); if ($this->expiresAfter) { $item->expiresAfter($this->expiresAfter); } $this->cache->save($item); } return true; } private function rateLimitExceeded(): bool { if (!$this->rateLimit) { return false; } $cacheItem = $this->cache->getItem($this->rateLimitCacheKey); $cacheItemData = []; if ($cacheItem->isHit() && \is_array($data = $cacheItem->get())) { $cacheItemData = $data; } $callsPerMinute = $cacheItemData['callsPerMinute'] ?? 0; $expiry = $cacheItemData['expiry'] ?? new \DateTime('+60 seconds', new \DateTimeZone('UTC')); if (++$callsPerMinute > $this->maxCallsPerMinute) { return true; } $cacheItem->set(['expiry' => $expiry, 'callsPerMinute' => $callsPerMinute]); $cacheItem->expiresAt($expiry); $this->cache->save($cacheItem); return false; } private function getCacheItem(): CacheItemInterface { if (\is_null($this->cacheItem)) { $this->cacheItem = $this->cache->getItem($this->cacheKey); } return $this->cacheItem; } private function setCacheKeys(): void { if (empty($this->jwksUri)) { throw new RuntimeException('JWKS URI is empty'); } // ensure we do not have illegal characters $key = preg_replace('|[^a-zA-Z0-9_\.!]|', '', $this->jwksUri); // add prefix $key = $this->cacheKeyPrefix . $key; // Hash keys if they exceed $maxKeyLength of 64 if (\strlen($key) > $this->maxKeyLength) { $key = substr(hash('sha256', $key), 0, $this->maxKeyLength); } $this->cacheKey = $key; if ($this->rateLimit) { // add prefix $rateLimitKey = $this->cacheKeyPrefix . 'ratelimit' . $key; // Hash keys if they exceed $maxKeyLength of 64 if (\strlen($rateLimitKey) > $this->maxKeyLength) { $rateLimitKey = substr(hash('sha256', $rateLimitKey), 0, $this->maxKeyLength); } $this->rateLimitCacheKey = $rateLimitKey; } } } ================================================ FILE: lib/Google/vendor/firebase/php-jwt/src/ExpiredException.php ================================================ payload = $payload; } public function getPayload(): object { return $this->payload; } public function setTimestamp(int $timestamp): void { $this->timestamp = $timestamp; } public function getTimestamp(): ?int { return $this->timestamp; } } ================================================ FILE: lib/Google/vendor/firebase/php-jwt/src/JWK.php ================================================ * @license http://opensource.org/licenses/BSD-3-Clause 3-clause BSD * @link https://github.com/firebase/php-jwt */ class JWK { private const OID = '1.2.840.10045.2.1'; private const ASN1_OBJECT_IDENTIFIER = 0x06; private const ASN1_SEQUENCE = 0x10; // also defined in JWT private const ASN1_BIT_STRING = 0x03; private const EC_CURVES = [ 'P-256' => '1.2.840.10045.3.1.7', // Len: 64 'secp256k1' => '1.3.132.0.10', // Len: 64 'P-384' => '1.3.132.0.34', // Len: 96 // 'P-521' => '1.3.132.0.35', // Len: 132 (not supported) ]; // For keys with "kty" equal to "OKP" (Octet Key Pair), the "crv" parameter must contain the key subtype. // This library supports the following subtypes: private const OKP_SUBTYPES = [ 'Ed25519' => true, // RFC 8037 ]; /** * Parse a set of JWK keys * * @param array $jwks The JSON Web Key Set as an associative array * @param string $defaultAlg The algorithm for the Key object if "alg" is not set in the * JSON Web Key Set * * @return array An associative array of key IDs (kid) to Key objects * * @throws InvalidArgumentException Provided JWK Set is empty * @throws UnexpectedValueException Provided JWK Set was invalid * @throws DomainException OpenSSL failure * * @uses parseKey */ public static function parseKeySet(#[\SensitiveParameter] array $jwks, ?string $defaultAlg = null): array { $keys = []; if (!isset($jwks['keys'])) { throw new UnexpectedValueException('"keys" member must exist in the JWK Set'); } if (empty($jwks['keys'])) { throw new InvalidArgumentException('JWK Set did not contain any keys'); } foreach ($jwks['keys'] as $k => $v) { $kid = isset($v['kid']) ? $v['kid'] : $k; if ($key = self::parseKey($v, $defaultAlg)) { $keys[(string) $kid] = $key; } } if (0 === \count($keys)) { throw new UnexpectedValueException('No supported algorithms found in JWK Set'); } return $keys; } /** * Parse a JWK key * * @param array $jwk An individual JWK * @param string $defaultAlg The algorithm for the Key object if "alg" is not set in the * JSON Web Key Set * * @return Key The key object for the JWK * * @throws InvalidArgumentException Provided JWK is empty * @throws UnexpectedValueException Provided JWK was invalid * @throws DomainException OpenSSL failure * * @uses createPemFromModulusAndExponent */ public static function parseKey(#[\SensitiveParameter] array $jwk, ?string $defaultAlg = null): ?Key { if (empty($jwk)) { throw new InvalidArgumentException('JWK must not be empty'); } if (!isset($jwk['kty'])) { throw new UnexpectedValueException('JWK must contain a "kty" parameter'); } if (!isset($jwk['alg'])) { if (\is_null($defaultAlg)) { // The "alg" parameter is optional in a KTY, but an algorithm is required // for parsing in this library. Use the $defaultAlg parameter when parsing the // key set in order to prevent this error. // @see https://datatracker.ietf.org/doc/html/rfc7517#section-4.4 throw new UnexpectedValueException('JWK must contain an "alg" parameter'); } $jwk['alg'] = $defaultAlg; } switch ($jwk['kty']) { case 'RSA': if (!empty($jwk['d'])) { throw new UnexpectedValueException('RSA private keys are not supported'); } if (!isset($jwk['n']) || !isset($jwk['e'])) { throw new UnexpectedValueException('RSA keys must contain values for both "n" and "e"'); } $pem = self::createPemFromModulusAndExponent($jwk['n'], $jwk['e']); $publicKey = \openssl_pkey_get_public($pem); if (false === $publicKey) { throw new DomainException( 'OpenSSL error: ' . \openssl_error_string() ); } return new Key($publicKey, $jwk['alg']); case 'EC': if (isset($jwk['d'])) { // The key is actually a private key throw new UnexpectedValueException('Key data must be for a public key'); } if (empty($jwk['crv'])) { throw new UnexpectedValueException('crv not set'); } if (!isset(self::EC_CURVES[$jwk['crv']])) { throw new DomainException('Unrecognised or unsupported EC curve'); } if (empty($jwk['x']) || empty($jwk['y'])) { throw new UnexpectedValueException('x and y not set'); } $publicKey = self::createPemFromCrvAndXYCoordinates($jwk['crv'], $jwk['x'], $jwk['y']); return new Key($publicKey, $jwk['alg']); case 'OKP': if (isset($jwk['d'])) { // The key is actually a private key throw new UnexpectedValueException('Key data must be for a public key'); } if (!isset($jwk['crv'])) { throw new UnexpectedValueException('crv not set'); } if (empty(self::OKP_SUBTYPES[$jwk['crv']])) { throw new DomainException('Unrecognised or unsupported OKP key subtype'); } if (empty($jwk['x'])) { throw new UnexpectedValueException('x not set'); } // This library works internally with EdDSA keys (Ed25519) encoded in standard base64. $publicKey = JWT::convertBase64urlToBase64($jwk['x']); return new Key($publicKey, $jwk['alg']); case 'oct': if (!isset($jwk['k'])) { throw new UnexpectedValueException('k not set'); } return new Key(JWT::urlsafeB64Decode($jwk['k']), $jwk['alg']); default: break; } return null; } /** * Converts the EC JWK values to pem format. * * @param string $crv The EC curve (only P-256 & P-384 is supported) * @param string $x The EC x-coordinate * @param string $y The EC y-coordinate * * @return string */ private static function createPemFromCrvAndXYCoordinates(string $crv, string $x, string $y): string { $pem = self::encodeDER( self::ASN1_SEQUENCE, self::encodeDER( self::ASN1_SEQUENCE, self::encodeDER( self::ASN1_OBJECT_IDENTIFIER, self::encodeOID(self::OID) ) . self::encodeDER( self::ASN1_OBJECT_IDENTIFIER, self::encodeOID(self::EC_CURVES[$crv]) ) ) . self::encodeDER( self::ASN1_BIT_STRING, \chr(0x00) . \chr(0x04) . JWT::urlsafeB64Decode($x) . JWT::urlsafeB64Decode($y) ) ); return \sprintf( "-----BEGIN PUBLIC KEY-----\n%s\n-----END PUBLIC KEY-----\n", wordwrap(base64_encode($pem), 64, "\n", true) ); } /** * Create a public key represented in PEM format from RSA modulus and exponent information * * @param string $n The RSA modulus encoded in Base64 * @param string $e The RSA exponent encoded in Base64 * * @return string The RSA public key represented in PEM format * * @uses encodeLength */ private static function createPemFromModulusAndExponent( string $n, string $e ): string { $mod = JWT::urlsafeB64Decode($n); $exp = JWT::urlsafeB64Decode($e); $modulus = \pack('Ca*a*', 2, self::encodeLength(\strlen($mod)), $mod); $publicExponent = \pack('Ca*a*', 2, self::encodeLength(\strlen($exp)), $exp); $rsaPublicKey = \pack( 'Ca*a*a*', 48, self::encodeLength(\strlen($modulus) + \strlen($publicExponent)), $modulus, $publicExponent ); // sequence(oid(1.2.840.113549.1.1.1), null)) = rsaEncryption. $rsaOID = \pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA $rsaPublicKey = \chr(0) . $rsaPublicKey; $rsaPublicKey = \chr(3) . self::encodeLength(\strlen($rsaPublicKey)) . $rsaPublicKey; $rsaPublicKey = \pack( 'Ca*a*', 48, self::encodeLength(\strlen($rsaOID . $rsaPublicKey)), $rsaOID . $rsaPublicKey ); return "-----BEGIN PUBLIC KEY-----\r\n" . \chunk_split(\base64_encode($rsaPublicKey), 64) . '-----END PUBLIC KEY-----'; } /** * DER-encode the length * * DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See * {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information. * * @param int $length * @return string */ private static function encodeLength(int $length): string { if ($length <= 0x7F) { return \chr($length); } $temp = \ltrim(\pack('N', $length), \chr(0)); return \pack('Ca*', 0x80 | \strlen($temp), $temp); } /** * Encodes a value into a DER object. * Also defined in Firebase\JWT\JWT * * @param int $type DER tag * @param string $value the value to encode * @return string the encoded object */ private static function encodeDER(int $type, string $value): string { $tag_header = 0; if ($type === self::ASN1_SEQUENCE) { $tag_header |= 0x20; } // Type $der = \chr($tag_header | $type); // Length $der .= \chr(\strlen($value)); return $der . $value; } /** * Encodes a string into a DER-encoded OID. * * @param string $oid the OID string * @return string the binary DER-encoded OID */ private static function encodeOID(string $oid): string { $octets = explode('.', $oid); // Get the first octet $first = (int) array_shift($octets); $second = (int) array_shift($octets); $oid = \chr($first * 40 + $second); // Iterate over subsequent octets foreach ($octets as $octet) { if ($octet == 0) { $oid .= \chr(0x00); continue; } $bin = ''; while ($octet) { $bin .= \chr(0x80 | ($octet & 0x7f)); $octet >>= 7; } $bin[0] = $bin[0] & \chr(0x7f); // Convert to big endian if necessary if (pack('V', 65534) == pack('L', 65534)) { $oid .= strrev($bin); } else { $oid .= $bin; } } return $oid; } } ================================================ FILE: lib/Google/vendor/firebase/php-jwt/src/JWT.php ================================================ * @author Anant Narayanan * @license http://opensource.org/licenses/BSD-3-Clause 3-clause BSD * @link https://github.com/firebase/php-jwt */ class JWT { private const ASN1_INTEGER = 0x02; private const ASN1_SEQUENCE = 0x10; private const ASN1_BIT_STRING = 0x03; private const RSA_KEY_MIN_LENGTH=2048; /** * When checking nbf, iat or expiration times, * we want to provide some extra leeway time to * account for clock skew. * * @var int */ public static $leeway = 0; /** * Allow the current timestamp to be specified. * Useful for fixing a value within unit testing. * Will default to PHP time() value if null. * * @var ?int */ public static $timestamp = null; /** * @var array */ public static $supported_algs = [ 'ES384' => ['openssl', 'SHA384'], 'ES256' => ['openssl', 'SHA256'], 'ES256K' => ['openssl', 'SHA256'], 'HS256' => ['hash_hmac', 'SHA256'], 'HS384' => ['hash_hmac', 'SHA384'], 'HS512' => ['hash_hmac', 'SHA512'], 'RS256' => ['openssl', 'SHA256'], 'RS384' => ['openssl', 'SHA384'], 'RS512' => ['openssl', 'SHA512'], 'EdDSA' => ['sodium_crypto', 'EdDSA'], ]; /** * Decodes a JWT string into a PHP object. * * @param string $jwt The JWT * @param Key|ArrayAccess|array $keyOrKeyArray The Key or associative array of key IDs * (kid) to Key objects. * If the algorithm used is asymmetric, this is * the public key. * Each Key object contains an algorithm and * matching key. * Supported algorithms are 'ES384','ES256', * 'HS256', 'HS384', 'HS512', 'RS256', 'RS384' * and 'RS512'. * @param stdClass $headers Optional. Populates stdClass with headers. * * @return stdClass The JWT's payload as a PHP object * * @throws InvalidArgumentException Provided key/key-array was empty or malformed * @throws DomainException Provided JWT is malformed * @throws UnexpectedValueException Provided JWT was invalid * @throws SignatureInvalidException Provided JWT was invalid because the signature verification failed * @throws BeforeValidException Provided JWT is trying to be used before it's eligible as defined by 'nbf' * @throws BeforeValidException Provided JWT is trying to be used before it's been created as defined by 'iat' * @throws ExpiredException Provided JWT has since expired, as defined by the 'exp' claim * * @uses jsonDecode * @uses urlsafeB64Decode */ public static function decode( string $jwt, #[\SensitiveParameter] $keyOrKeyArray, ?stdClass &$headers = null ): stdClass { // Validate JWT $timestamp = \is_null(static::$timestamp) ? \time() : static::$timestamp; if (empty($keyOrKeyArray)) { throw new InvalidArgumentException('Key may not be empty'); } $tks = \explode('.', $jwt); if (\count($tks) !== 3) { throw new UnexpectedValueException('Wrong number of segments'); } list($headb64, $bodyb64, $cryptob64) = $tks; $headerRaw = static::urlsafeB64Decode($headb64); if (null === ($header = static::jsonDecode($headerRaw))) { throw new UnexpectedValueException('Invalid header encoding'); } if ($headers !== null) { $headers = $header; } $payloadRaw = static::urlsafeB64Decode($bodyb64); if (null === ($payload = static::jsonDecode($payloadRaw))) { throw new UnexpectedValueException('Invalid claims encoding'); } if (\is_array($payload)) { // prevent PHP Fatal Error in edge-cases when payload is empty array $payload = (object) $payload; } if (!$payload instanceof stdClass) { throw new UnexpectedValueException('Payload must be a JSON object'); } if (isset($payload->iat) && !\is_numeric($payload->iat)) { throw new UnexpectedValueException('Payload iat must be a number'); } if (isset($payload->nbf) && !\is_numeric($payload->nbf)) { throw new UnexpectedValueException('Payload nbf must be a number'); } if (isset($payload->exp) && !\is_numeric($payload->exp)) { throw new UnexpectedValueException('Payload exp must be a number'); } $sig = static::urlsafeB64Decode($cryptob64); if (empty($header->alg)) { throw new UnexpectedValueException('Empty algorithm'); } if (empty(static::$supported_algs[$header->alg])) { throw new UnexpectedValueException('Algorithm not supported'); } $key = self::getKey($keyOrKeyArray, property_exists($header, 'kid') ? $header->kid : null); // Check the algorithm if (!self::constantTimeEquals($key->getAlgorithm(), $header->alg)) { // See issue #351 throw new UnexpectedValueException('Incorrect key for this algorithm'); } if (\in_array($header->alg, ['ES256', 'ES256K', 'ES384'], true)) { // OpenSSL expects an ASN.1 DER sequence for ES256/ES256K/ES384 signatures $sig = self::signatureToDER($sig); } if (!self::verify("{$headb64}.{$bodyb64}", $sig, $key->getKeyMaterial(), $header->alg)) { throw new SignatureInvalidException('Signature verification failed'); } // Check the nbf if it is defined. This is the time that the // token can actually be used. If it's not yet that time, abort. if (isset($payload->nbf) && floor($payload->nbf) > ($timestamp + static::$leeway)) { $ex = new BeforeValidException( 'Cannot handle token with nbf prior to ' . \date(DateTime::ATOM, (int) floor($payload->nbf)) ); $ex->setPayload($payload); throw $ex; } // Check that this token has been created before 'now'. This prevents // using tokens that have been created for later use (and haven't // correctly used the nbf claim). if (!isset($payload->nbf) && isset($payload->iat) && floor($payload->iat) > ($timestamp + static::$leeway)) { $ex = new BeforeValidException( 'Cannot handle token with iat prior to ' . \date(DateTime::ATOM, (int) floor($payload->iat)) ); $ex->setPayload($payload); throw $ex; } // Check if this token has expired. if (isset($payload->exp) && ($timestamp - static::$leeway) >= $payload->exp) { $ex = new ExpiredException('Expired token'); $ex->setPayload($payload); $ex->setTimestamp($timestamp); throw $ex; } return $payload; } /** * Converts and signs a PHP array into a JWT string. * * @param array $payload PHP array * @param string|OpenSSLAsymmetricKey|OpenSSLCertificate $key The secret key. * @param string $alg Supported algorithms are 'ES384','ES256', 'ES256K', 'HS256', * 'HS384', 'HS512', 'RS256', 'RS384', and 'RS512' * @param string $keyId * @param array $head An array with header elements to attach * * @return string A signed JWT * * @uses jsonEncode * @uses urlsafeB64Encode */ public static function encode( array $payload, #[\SensitiveParameter] $key, string $alg, ?string $keyId = null, ?array $head = null ): string { $header = ['typ' => 'JWT']; if (isset($head)) { $header = \array_merge($header, $head); } $header['alg'] = $alg; if ($keyId !== null) { $header['kid'] = $keyId; } $segments = []; $segments[] = static::urlsafeB64Encode((string) static::jsonEncode($header)); $segments[] = static::urlsafeB64Encode((string) static::jsonEncode($payload)); $signing_input = \implode('.', $segments); $signature = static::sign($signing_input, $key, $alg); $segments[] = static::urlsafeB64Encode($signature); return \implode('.', $segments); } /** * Sign a string with a given key and algorithm. * * @param string $msg The message to sign * @param string|OpenSSLAsymmetricKey|OpenSSLCertificate $key The secret key. * @param string $alg Supported algorithms are 'EdDSA', 'ES384', 'ES256', 'ES256K', 'HS256', * 'HS384', 'HS512', 'RS256', 'RS384', and 'RS512' * * @return string An encrypted message * * @throws DomainException Unsupported algorithm or bad key was specified */ public static function sign( string $msg, #[\SensitiveParameter] $key, string $alg ): string { if (empty(static::$supported_algs[$alg])) { throw new DomainException('Algorithm not supported'); } list($function, $algorithm) = static::$supported_algs[$alg]; switch ($function) { case 'hash_hmac': if (!\is_string($key)) { throw new InvalidArgumentException('key must be a string when using hmac'); } self::validateHmacKeyLength($key, $algorithm); return \hash_hmac($algorithm, $msg, $key, true); case 'openssl': $signature = ''; if (!$key = openssl_pkey_get_private($key)) { throw new DomainException('OpenSSL unable to validate key'); } if (str_starts_with($alg, 'RS')) { self::validateRsaKeyLength($key); } elseif (str_starts_with($alg, 'ES')) { self::validateEcKeyLength($key, $alg); } $success = \openssl_sign($msg, $signature, $key, $algorithm); if (!$success) { throw new DomainException('OpenSSL unable to sign data'); } if ($alg === 'ES256' || $alg === 'ES256K') { $signature = self::signatureFromDER($signature, 256); } elseif ($alg === 'ES384') { $signature = self::signatureFromDER($signature, 384); } return $signature; case 'sodium_crypto': if (!\function_exists('sodium_crypto_sign_detached')) { throw new DomainException('libsodium is not available'); } if (!\is_string($key)) { throw new InvalidArgumentException('key must be a string when using EdDSA'); } try { // The last non-empty line is used as the key. $lines = array_filter(explode("\n", $key)); $key = base64_decode((string) end($lines)); if (\strlen($key) === 0) { throw new DomainException('Key cannot be empty string'); } return sodium_crypto_sign_detached($msg, $key); } catch (Exception $e) { throw new DomainException($e->getMessage(), 0, $e); } } throw new DomainException('Algorithm not supported'); } /** * Verify a signature with the message, key and method. Not all methods * are symmetric, so we must have a separate verify and sign method. * * @param string $msg The original message (header and body) * @param string $signature The original signature * @param string|OpenSSLAsymmetricKey|OpenSSLCertificate $keyMaterial For Ed*, ES*, HS*, a string key works. for RS*, must be an instance of OpenSSLAsymmetricKey * @param string $alg The algorithm * * @return bool * * @throws DomainException Invalid Algorithm, bad key, or OpenSSL failure */ private static function verify( string $msg, string $signature, #[\SensitiveParameter] $keyMaterial, string $alg ): bool { if (empty(static::$supported_algs[$alg])) { throw new DomainException('Algorithm not supported'); } list($function, $algorithm) = static::$supported_algs[$alg]; switch ($function) { case 'openssl': if (!$key = openssl_pkey_get_public($keyMaterial)) { throw new DomainException('OpenSSL unable to validate key'); } if (str_starts_with($alg, 'RS')) { self::validateRsaKeyLength($key); } elseif (str_starts_with($alg, 'ES')) { self::validateEcKeyLength($key, $alg); } $success = \openssl_verify($msg, $signature, $keyMaterial, $algorithm); if ($success === 1) { return true; } if ($success === 0) { return false; } // returns 1 on success, 0 on failure, -1 on error. throw new DomainException( 'OpenSSL error: ' . \openssl_error_string() ); case 'sodium_crypto': if (!\function_exists('sodium_crypto_sign_verify_detached')) { throw new DomainException('libsodium is not available'); } if (!\is_string($keyMaterial)) { throw new InvalidArgumentException('key must be a string when using EdDSA'); } try { // The last non-empty line is used as the key. $lines = array_filter(explode("\n", $keyMaterial)); $key = base64_decode((string) end($lines)); if (\strlen($key) === 0) { throw new DomainException('Key cannot be empty string'); } if (\strlen($signature) === 0) { throw new DomainException('Signature cannot be empty string'); } return sodium_crypto_sign_verify_detached($signature, $msg, $key); } catch (Exception $e) { throw new DomainException($e->getMessage(), 0, $e); } case 'hash_hmac': default: if (!\is_string($keyMaterial)) { throw new InvalidArgumentException('key must be a string when using hmac'); } self::validateHmacKeyLength($keyMaterial, $algorithm); $hash = \hash_hmac($algorithm, $msg, $keyMaterial, true); return self::constantTimeEquals($hash, $signature); } } /** * Decode a JSON string into a PHP object. * * @param string $input JSON string * * @return mixed The decoded JSON string * * @throws DomainException Provided string was invalid JSON */ public static function jsonDecode(string $input) { $obj = \json_decode($input, false, 512, JSON_BIGINT_AS_STRING); if ($errno = \json_last_error()) { self::handleJsonError($errno); } elseif ($obj === null && $input !== 'null') { throw new DomainException('Null result with non-null input'); } return $obj; } /** * Encode a PHP array into a JSON string. * * @param array $input A PHP array * * @return string JSON representation of the PHP array * * @throws DomainException Provided object could not be encoded to valid JSON */ public static function jsonEncode(array $input): string { $json = \json_encode($input, \JSON_UNESCAPED_SLASHES); if ($errno = \json_last_error()) { self::handleJsonError($errno); } elseif ($json === 'null') { throw new DomainException('Null result with non-null input'); } if ($json === false) { throw new DomainException('Provided object could not be encoded to valid JSON'); } return $json; } /** * Decode a string with URL-safe Base64. * * @param string $input A Base64 encoded string * * @return string A decoded string * * @throws InvalidArgumentException invalid base64 characters */ public static function urlsafeB64Decode(string $input): string { return \base64_decode(self::convertBase64UrlToBase64($input)); } /** * Convert a string in the base64url (URL-safe Base64) encoding to standard base64. * * @param string $input A Base64 encoded string with URL-safe characters (-_ and no padding) * * @return string A Base64 encoded string with standard characters (+/) and padding (=), when * needed. * * @see https://www.rfc-editor.org/rfc/rfc4648 */ public static function convertBase64UrlToBase64(string $input): string { $remainder = \strlen($input) % 4; if ($remainder) { $padlen = 4 - $remainder; $input .= \str_repeat('=', $padlen); } return \strtr($input, '-_', '+/'); } /** * Encode a string with URL-safe Base64. * * @param string $input The string you want encoded * * @return string The base64 encode of what you passed in */ public static function urlsafeB64Encode(string $input): string { return \str_replace('=', '', \strtr(\base64_encode($input), '+/', '-_')); } /** * Determine if an algorithm has been provided for each Key * * @param Key|ArrayAccess|array $keyOrKeyArray * @param string|null $kid * * @throws UnexpectedValueException * * @return Key */ private static function getKey( #[\SensitiveParameter] $keyOrKeyArray, ?string $kid ): Key { if ($keyOrKeyArray instanceof Key) { return $keyOrKeyArray; } if (empty($kid) && $kid !== '0') { throw new UnexpectedValueException('"kid" empty, unable to lookup correct key'); } if ($keyOrKeyArray instanceof CachedKeySet) { // Skip "isset" check, as this will automatically refresh if not set return $keyOrKeyArray[$kid]; } if (!isset($keyOrKeyArray[$kid])) { throw new UnexpectedValueException('"kid" invalid, unable to lookup correct key'); } return $keyOrKeyArray[$kid]; } /** * @param string $left The string of known length to compare against * @param string $right The user-supplied string * @return bool */ public static function constantTimeEquals(string $left, string $right): bool { if (\function_exists('hash_equals')) { return \hash_equals($left, $right); } $len = \min(self::safeStrlen($left), self::safeStrlen($right)); $status = 0; for ($i = 0; $i < $len; $i++) { $status |= (\ord($left[$i]) ^ \ord($right[$i])); } $status |= (self::safeStrlen($left) ^ self::safeStrlen($right)); return ($status === 0); } /** * Helper method to create a JSON error. * * @param int $errno An error number from json_last_error() * * @throws DomainException * * @return void */ private static function handleJsonError(int $errno): void { $messages = [ JSON_ERROR_DEPTH => 'Maximum stack depth exceeded', JSON_ERROR_STATE_MISMATCH => 'Invalid or malformed JSON', JSON_ERROR_CTRL_CHAR => 'Unexpected control character found', JSON_ERROR_SYNTAX => 'Syntax error, malformed JSON', JSON_ERROR_UTF8 => 'Malformed UTF-8 characters' //PHP >= 5.3.3 ]; throw new DomainException( isset($messages[$errno]) ? $messages[$errno] : 'Unknown JSON error: ' . $errno ); } /** * Get the number of bytes in cryptographic strings. * * @param string $str * * @return int */ private static function safeStrlen(string $str): int { if (\function_exists('mb_strlen')) { return \mb_strlen($str, '8bit'); } return \strlen($str); } /** * Convert an ECDSA signature to an ASN.1 DER sequence * * @param string $sig The ECDSA signature to convert * @return string The encoded DER object */ private static function signatureToDER(string $sig): string { // Separate the signature into r-value and s-value $length = max(1, (int) (\strlen($sig) / 2)); list($r, $s) = \str_split($sig, $length); // Trim leading zeros $r = \ltrim($r, "\x00"); $s = \ltrim($s, "\x00"); // Convert r-value and s-value from unsigned big-endian integers to // signed two's complement if (\ord($r[0]) > 0x7f) { $r = "\x00" . $r; } if (\ord($s[0]) > 0x7f) { $s = "\x00" . $s; } return self::encodeDER( self::ASN1_SEQUENCE, self::encodeDER(self::ASN1_INTEGER, $r) . self::encodeDER(self::ASN1_INTEGER, $s) ); } /** * Encodes a value into a DER object. * * @param int $type DER tag * @param string $value the value to encode * * @return string the encoded object */ private static function encodeDER(int $type, string $value): string { $tag_header = 0; if ($type === self::ASN1_SEQUENCE) { $tag_header |= 0x20; } // Type $der = \chr($tag_header | $type); // Length $der .= \chr(\strlen($value)); return $der . $value; } /** * Encodes signature from a DER object. * * @param string $der binary signature in DER format * @param int $keySize the number of bits in the key * * @return string the signature */ private static function signatureFromDER(string $der, int $keySize): string { // OpenSSL returns the ECDSA signatures as a binary ASN.1 DER SEQUENCE list($offset, $_) = self::readDER($der); list($offset, $r) = self::readDER($der, $offset); list($offset, $s) = self::readDER($der, $offset); // Convert r-value and s-value from signed two's compliment to unsigned // big-endian integers $r = \ltrim($r, "\x00"); $s = \ltrim($s, "\x00"); // Pad out r and s so that they are $keySize bits long $r = \str_pad($r, $keySize / 8, "\x00", STR_PAD_LEFT); $s = \str_pad($s, $keySize / 8, "\x00", STR_PAD_LEFT); return $r . $s; } /** * Reads binary DER-encoded data and decodes into a single object * * @param string $der the binary data in DER format * @param int $offset the offset of the data stream containing the object * to decode * * @return array{int, string|null} the new offset and the decoded object */ private static function readDER(string $der, int $offset = 0): array { $pos = $offset; $size = \strlen($der); $constructed = (\ord($der[$pos]) >> 5) & 0x01; $type = \ord($der[$pos++]) & 0x1f; // Length $len = \ord($der[$pos++]); if ($len & 0x80) { $n = $len & 0x1f; $len = 0; while ($n-- && $pos < $size) { $len = ($len << 8) | \ord($der[$pos++]); } } // Value if ($type === self::ASN1_BIT_STRING) { $pos++; // Skip the first contents octet (padding indicator) $data = \substr($der, $pos, $len - 1); $pos += $len - 1; } elseif (!$constructed) { $data = \substr($der, $pos, $len); $pos += $len; } else { $data = null; } return [$pos, $data]; } /** * Validate HMAC key length * * @param string $key HMAC key material * @param string $algorithm The algorithm * * @throws DomainException Provided key is too short */ private static function validateHmacKeyLength(string $key, string $algorithm): void { $keyLength = \strlen($key) * 8; $minKeyLength = (int) \str_replace('SHA', '', $algorithm); if ($keyLength < $minKeyLength) { throw new DomainException('Provided key is too short'); } } /** * Validate RSA key length * * @param OpenSSLAsymmetricKey $key RSA key material * @throws DomainException Provided key is too short */ private static function validateRsaKeyLength(#[\SensitiveParameter] OpenSSLAsymmetricKey $key): void { if (!$keyDetails = openssl_pkey_get_details($key)) { throw new DomainException('Unable to validate key'); } if ($keyDetails['bits'] < self::RSA_KEY_MIN_LENGTH) { throw new DomainException('Provided key is too short'); } } /** * Validate RSA key length * * @param OpenSSLAsymmetricKey $key RSA key material * @param string $algorithm The algorithm * @throws DomainException Provided key is too short */ private static function validateEcKeyLength( #[\SensitiveParameter] OpenSSLAsymmetricKey $key, string $algorithm ): void { if (!$keyDetails = openssl_pkey_get_details($key)) { throw new DomainException('Unable to validate key'); } $minKeyLength = (int) \str_replace('ES', '', $algorithm); if ($keyDetails['bits'] < $minKeyLength) { throw new DomainException('Provided key is too short'); } } } ================================================ FILE: lib/Google/vendor/firebase/php-jwt/src/JWTExceptionWithPayloadInterface.php ================================================ algorithm; } /** * @return string|OpenSSLAsymmetricKey|OpenSSLCertificate */ public function getKeyMaterial() { return $this->keyMaterial; } } ================================================ FILE: lib/Google/vendor/firebase/php-jwt/src/SignatureInvalidException.php ================================================ 'Google_Client', 'Google\\Service' => 'Google_Service', 'Google\\Service\\Resource' => 'Google_Service_Resource', 'Google\\Model' => 'Google_Model', 'Google\\Collection' => 'Google_Collection', ]; foreach ($servicesClassMap as $alias => $class) { class_alias($class, $alias); } } } spl_autoload_register(function ($class) { if (0 === strpos($class, 'Google_Service_')) { // Autoload the new class, which will also create an alias for the // old class by changing underscores to namespaces: // Google_Service_Speech_Resource_Operations // => Google\Service\Speech\Resource\Operations $classExists = class_exists($newClass = str_replace('_', '\\', $class)); if ($classExists) { return true; } } }, true, true); ================================================ FILE: lib/Google/vendor/google/apiclient-services/composer.json ================================================ { "name": "google/apiclient-services", "type": "library", "description": "Client library for Google APIs", "keywords": ["google"], "homepage": "http://developers.google.com/api-client-library/php", "license": "Apache-2.0", "require": { "php": "^8.1" }, "require-dev": { "phpunit/phpunit": "^9.6" }, "autoload": { "psr-4": { "Google\\Service\\": "src" }, "files": [ "autoload.php" ] }, "autoload-dev": { "psr-4": { "Google\\": "tests/mocks" } } } ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/AdvanceRelocateBucketOperationRequest.php ================================================ expireTime = $expireTime; } /** * @return string */ public function getExpireTime() { return $this->expireTime; } /** * Specifies the duration after which the relocation will revert to the sync * stage if the relocation hasn't succeeded. Optional, if not supplied, a * default value of 12h will be used. * * @param string $ttl */ public function setTtl($ttl) { $this->ttl = $ttl; } /** * @return string */ public function getTtl() { return $this->ttl; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(AdvanceRelocateBucketOperationRequest::class, 'Google_Service_Storage_AdvanceRelocateBucketOperationRequest'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/AnywhereCache.php ================================================ admissionPolicy = $admissionPolicy; } /** * @return string */ public function getAdmissionPolicy() { return $this->admissionPolicy; } /** * The ID of the Anywhere cache instance. * * @param string $anywhereCacheId */ public function setAnywhereCacheId($anywhereCacheId) { $this->anywhereCacheId = $anywhereCacheId; } /** * @return string */ public function getAnywhereCacheId() { return $this->anywhereCacheId; } /** * The name of the bucket containing this cache instance. * * @param string $bucket */ public function setBucket($bucket) { $this->bucket = $bucket; } /** * @return string */ public function getBucket() { return $this->bucket; } /** * The creation time of the cache instance in RFC 3339 format. * * @param string $createTime */ public function setCreateTime($createTime) { $this->createTime = $createTime; } /** * @return string */ public function getCreateTime() { return $this->createTime; } /** * The ID of the resource, including the project number, bucket name and * anywhere cache ID. * * @param string $id */ public function setId($id) { $this->id = $id; } /** * @return string */ public function getId() { return $this->id; } /** * The kind of item this is. For Anywhere Cache, this is always * storage#anywhereCache. * * @param string $kind */ public function setKind($kind) { $this->kind = $kind; } /** * @return string */ public function getKind() { return $this->kind; } /** * True if the cache instance has an active Update long-running operation. * * @param bool $pendingUpdate */ public function setPendingUpdate($pendingUpdate) { $this->pendingUpdate = $pendingUpdate; } /** * @return bool */ public function getPendingUpdate() { return $this->pendingUpdate; } /** * The link to this cache instance. * * @param string $selfLink */ public function setSelfLink($selfLink) { $this->selfLink = $selfLink; } /** * @return string */ public function getSelfLink() { return $this->selfLink; } /** * The current state of the cache instance. * * @param string $state */ public function setState($state) { $this->state = $state; } /** * @return string */ public function getState() { return $this->state; } /** * The TTL of all cache entries in whole seconds. e.g., "7200s". * * @param string $ttl */ public function setTtl($ttl) { $this->ttl = $ttl; } /** * @return string */ public function getTtl() { return $this->ttl; } /** * The modification time of the cache instance metadata in RFC 3339 format. * * @param string $updateTime */ public function setUpdateTime($updateTime) { $this->updateTime = $updateTime; } /** * @return string */ public function getUpdateTime() { return $this->updateTime; } /** * The zone in which the cache instance is running. For example, us- * central1-a. * * @param string $zone */ public function setZone($zone) { $this->zone = $zone; } /** * @return string */ public function getZone() { return $this->zone; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(AnywhereCache::class, 'Google_Service_Storage_AnywhereCache'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/AnywhereCaches.php ================================================ items = $items; } /** * @return AnywhereCache[] */ public function getItems() { return $this->items; } /** * The kind of item this is. For lists of Anywhere Caches, this is always * storage#anywhereCaches. * * @param string $kind */ public function setKind($kind) { $this->kind = $kind; } /** * @return string */ public function getKind() { return $this->kind; } /** * The continuation token, used to page through large result sets. Provide * this value in a subsequent request to return the next page of results. * * @param string $nextPageToken */ public function setNextPageToken($nextPageToken) { $this->nextPageToken = $nextPageToken; } /** * @return string */ public function getNextPageToken() { return $this->nextPageToken; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(AnywhereCaches::class, 'Google_Service_Storage_AnywhereCaches'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/Bucket.php ================================================ acl = $acl; } /** * @return BucketAccessControl[] */ public function getAcl() { return $this->acl; } /** * The bucket's Autoclass configuration. * * @param BucketAutoclass $autoclass */ public function setAutoclass(BucketAutoclass $autoclass) { $this->autoclass = $autoclass; } /** * @return BucketAutoclass */ public function getAutoclass() { return $this->autoclass; } /** * The bucket's billing configuration. * * @param BucketBilling $billing */ public function setBilling(BucketBilling $billing) { $this->billing = $billing; } /** * @return BucketBilling */ public function getBilling() { return $this->billing; } /** * The bucket's Cross-Origin Resource Sharing (CORS) configuration. * * @param BucketCors[] $cors */ public function setCors($cors) { $this->cors = $cors; } /** * @return BucketCors[] */ public function getCors() { return $this->cors; } /** * The bucket's custom placement configuration for Custom Dual Regions. * * @param BucketCustomPlacementConfig $customPlacementConfig */ public function setCustomPlacementConfig(BucketCustomPlacementConfig $customPlacementConfig) { $this->customPlacementConfig = $customPlacementConfig; } /** * @return BucketCustomPlacementConfig */ public function getCustomPlacementConfig() { return $this->customPlacementConfig; } /** * The default value for event-based hold on newly created objects in this * bucket. Event-based hold is a way to retain objects indefinitely until an * event occurs, signified by the hold's release. After being released, such * objects will be subject to bucket-level retention (if any). One sample use * case of this flag is for banks to hold loan documents for at least 3 years * after loan is paid in full. Here, bucket-level retention is 3 years and the * event is loan being paid in full. In this example, these objects will be * held intact for any number of years until the event has occurred (event- * based hold on the object is released) and then 3 more years after that. * That means retention duration of the objects begins from the moment event- * based hold transitioned from true to false. Objects under event-based hold * cannot be deleted, overwritten or archived until the hold is removed. * * @param bool $defaultEventBasedHold */ public function setDefaultEventBasedHold($defaultEventBasedHold) { $this->defaultEventBasedHold = $defaultEventBasedHold; } /** * @return bool */ public function getDefaultEventBasedHold() { return $this->defaultEventBasedHold; } /** * Default access controls to apply to new objects when no ACL is provided. * * @param ObjectAccessControl[] $defaultObjectAcl */ public function setDefaultObjectAcl($defaultObjectAcl) { $this->defaultObjectAcl = $defaultObjectAcl; } /** * @return ObjectAccessControl[] */ public function getDefaultObjectAcl() { return $this->defaultObjectAcl; } /** * Encryption configuration for a bucket. * * @param BucketEncryption $encryption */ public function setEncryption(BucketEncryption $encryption) { $this->encryption = $encryption; } /** * @return BucketEncryption */ public function getEncryption() { return $this->encryption; } /** * HTTP 1.1 Entity tag for the bucket. * * @param string $etag */ public function setEtag($etag) { $this->etag = $etag; } /** * @return string */ public function getEtag() { return $this->etag; } /** * The generation of this bucket. * * @param string $generation */ public function setGeneration($generation) { $this->generation = $generation; } /** * @return string */ public function getGeneration() { return $this->generation; } /** * The hard delete time of the bucket in RFC 3339 format. * * @param string $hardDeleteTime */ public function setHardDeleteTime($hardDeleteTime) { $this->hardDeleteTime = $hardDeleteTime; } /** * @return string */ public function getHardDeleteTime() { return $this->hardDeleteTime; } /** * The bucket's hierarchical namespace configuration. * * @param BucketHierarchicalNamespace $hierarchicalNamespace */ public function setHierarchicalNamespace(BucketHierarchicalNamespace $hierarchicalNamespace) { $this->hierarchicalNamespace = $hierarchicalNamespace; } /** * @return BucketHierarchicalNamespace */ public function getHierarchicalNamespace() { return $this->hierarchicalNamespace; } /** * The bucket's IAM configuration. * * @param BucketIamConfiguration $iamConfiguration */ public function setIamConfiguration(BucketIamConfiguration $iamConfiguration) { $this->iamConfiguration = $iamConfiguration; } /** * @return BucketIamConfiguration */ public function getIamConfiguration() { return $this->iamConfiguration; } /** * The ID of the bucket. For buckets, the id and name properties are the same. * * @param string $id */ public function setId($id) { $this->id = $id; } /** * @return string */ public function getId() { return $this->id; } /** * The bucket's IP filter configuration. Specifies the network sources that * are allowed to access the operations on the bucket, as well as its * underlying objects. Only enforced when the mode is set to 'Enabled'. * * @param BucketIpFilter $ipFilter */ public function setIpFilter(BucketIpFilter $ipFilter) { $this->ipFilter = $ipFilter; } /** * @return BucketIpFilter */ public function getIpFilter() { return $this->ipFilter; } /** * The kind of item this is. For buckets, this is always storage#bucket. * * @param string $kind */ public function setKind($kind) { $this->kind = $kind; } /** * @return string */ public function getKind() { return $this->kind; } /** * User-provided labels, in key/value pairs. * * @param string[] $labels */ public function setLabels($labels) { $this->labels = $labels; } /** * @return string[] */ public function getLabels() { return $this->labels; } /** * The bucket's lifecycle configuration. See [Lifecycle * Management](https://cloud.google.com/storage/docs/lifecycle) for more * information. * * @param BucketLifecycle $lifecycle */ public function setLifecycle(BucketLifecycle $lifecycle) { $this->lifecycle = $lifecycle; } /** * @return BucketLifecycle */ public function getLifecycle() { return $this->lifecycle; } /** * The location of the bucket. Object data for objects in the bucket resides * in physical storage within this region. Defaults to US. See the * [Developer's Guide](https://cloud.google.com/storage/docs/locations) for * the authoritative list. * * @param string $location */ public function setLocation($location) { $this->location = $location; } /** * @return string */ public function getLocation() { return $this->location; } /** * The type of the bucket location. * * @param string $locationType */ public function setLocationType($locationType) { $this->locationType = $locationType; } /** * @return string */ public function getLocationType() { return $this->locationType; } /** * The bucket's logging configuration, which defines the destination bucket * and optional name prefix for the current bucket's logs. * * @param BucketLogging $logging */ public function setLogging(BucketLogging $logging) { $this->logging = $logging; } /** * @return BucketLogging */ public function getLogging() { return $this->logging; } /** * The metadata generation of this bucket. * * @param string $metageneration */ public function setMetageneration($metageneration) { $this->metageneration = $metageneration; } /** * @return string */ public function getMetageneration() { return $this->metageneration; } /** * The name of the bucket. * * @param string $name */ public function setName($name) { $this->name = $name; } /** * @return string */ public function getName() { return $this->name; } /** * The bucket's object retention config. * * @param BucketObjectRetention $objectRetention */ public function setObjectRetention(BucketObjectRetention $objectRetention) { $this->objectRetention = $objectRetention; } /** * @return BucketObjectRetention */ public function getObjectRetention() { return $this->objectRetention; } /** * The owner of the bucket. This is always the project team's owner group. * * @param BucketOwner $owner */ public function setOwner(BucketOwner $owner) { $this->owner = $owner; } /** * @return BucketOwner */ public function getOwner() { return $this->owner; } /** * The project number of the project the bucket belongs to. * * @param string $projectNumber */ public function setProjectNumber($projectNumber) { $this->projectNumber = $projectNumber; } /** * @return string */ public function getProjectNumber() { return $this->projectNumber; } /** * The bucket's retention policy. The retention policy enforces a minimum * retention time for all objects contained in the bucket, based on their * creation time. Any attempt to overwrite or delete objects younger than the * retention period will result in a PERMISSION_DENIED error. An unlocked * retention policy can be modified or removed from the bucket via a * storage.buckets.update operation. A locked retention policy cannot be * removed or shortened in duration for the lifetime of the bucket. Attempting * to remove or decrease period of a locked retention policy will result in a * PERMISSION_DENIED error. * * @param BucketRetentionPolicy $retentionPolicy */ public function setRetentionPolicy(BucketRetentionPolicy $retentionPolicy) { $this->retentionPolicy = $retentionPolicy; } /** * @return BucketRetentionPolicy */ public function getRetentionPolicy() { return $this->retentionPolicy; } /** * The Recovery Point Objective (RPO) of this bucket. Set to ASYNC_TURBO to * turn on Turbo Replication on a bucket. * * @param string $rpo */ public function setRpo($rpo) { $this->rpo = $rpo; } /** * @return string */ public function getRpo() { return $this->rpo; } /** * Reserved for future use. * * @param bool $satisfiesPZI */ public function setSatisfiesPZI($satisfiesPZI) { $this->satisfiesPZI = $satisfiesPZI; } /** * @return bool */ public function getSatisfiesPZI() { return $this->satisfiesPZI; } /** * Reserved for future use. * * @param bool $satisfiesPZS */ public function setSatisfiesPZS($satisfiesPZS) { $this->satisfiesPZS = $satisfiesPZS; } /** * @return bool */ public function getSatisfiesPZS() { return $this->satisfiesPZS; } /** * The URI of this bucket. * * @param string $selfLink */ public function setSelfLink($selfLink) { $this->selfLink = $selfLink; } /** * @return string */ public function getSelfLink() { return $this->selfLink; } /** * The bucket's soft delete policy, which defines the period of time that * soft-deleted objects will be retained, and cannot be permanently deleted. * * @param BucketSoftDeletePolicy $softDeletePolicy */ public function setSoftDeletePolicy(BucketSoftDeletePolicy $softDeletePolicy) { $this->softDeletePolicy = $softDeletePolicy; } /** * @return BucketSoftDeletePolicy */ public function getSoftDeletePolicy() { return $this->softDeletePolicy; } /** * The soft delete time of the bucket in RFC 3339 format. * * @param string $softDeleteTime */ public function setSoftDeleteTime($softDeleteTime) { $this->softDeleteTime = $softDeleteTime; } /** * @return string */ public function getSoftDeleteTime() { return $this->softDeleteTime; } /** * The bucket's default storage class, used whenever no storageClass is * specified for a newly-created object. This defines how objects in the * bucket are stored and determines the SLA and the cost of storage. Values * include MULTI_REGIONAL, REGIONAL, STANDARD, NEARLINE, COLDLINE, ARCHIVE, * and DURABLE_REDUCED_AVAILABILITY. If this value is not specified when the * bucket is created, it will default to STANDARD. For more information, see * [Storage Classes](https://cloud.google.com/storage/docs/storage-classes). * * @param string $storageClass */ public function setStorageClass($storageClass) { $this->storageClass = $storageClass; } /** * @return string */ public function getStorageClass() { return $this->storageClass; } /** * The creation time of the bucket in RFC 3339 format. * * @param string $timeCreated */ public function setTimeCreated($timeCreated) { $this->timeCreated = $timeCreated; } /** * @return string */ public function getTimeCreated() { return $this->timeCreated; } /** * The modification time of the bucket in RFC 3339 format. * * @param string $updated */ public function setUpdated($updated) { $this->updated = $updated; } /** * @return string */ public function getUpdated() { return $this->updated; } /** * The bucket's versioning configuration. * * @param BucketVersioning $versioning */ public function setVersioning(BucketVersioning $versioning) { $this->versioning = $versioning; } /** * @return BucketVersioning */ public function getVersioning() { return $this->versioning; } /** * The bucket's website configuration, controlling how the service behaves * when accessing bucket contents as a web site. See the [Static Website * Examples](https://cloud.google.com/storage/docs/static-website) for more * information. * * @param BucketWebsite $website */ public function setWebsite(BucketWebsite $website) { $this->website = $website; } /** * @return BucketWebsite */ public function getWebsite() { return $this->website; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(Bucket::class, 'Google_Service_Storage_Bucket'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/BucketAccessControl.php ================================================ bucket = $bucket; } /** * @return string */ public function getBucket() { return $this->bucket; } /** * The domain associated with the entity, if any. * * @param string $domain */ public function setDomain($domain) { $this->domain = $domain; } /** * @return string */ public function getDomain() { return $this->domain; } /** * The email address associated with the entity, if any. * * @param string $email */ public function setEmail($email) { $this->email = $email; } /** * @return string */ public function getEmail() { return $this->email; } /** * The entity holding the permission, in one of the following forms: - user- * userId - user-email - group-groupId - group-email - domain-domain - * project-team-projectId - allUsers - allAuthenticatedUsers Examples: - * The user liz@example.com would be user-liz@example.com. - The group * example@googlegroups.com would be group-example@googlegroups.com. - To * refer to all members of the Google Apps for Business domain example.com, * the entity would be domain-example.com. * * @param string $entity */ public function setEntity($entity) { $this->entity = $entity; } /** * @return string */ public function getEntity() { return $this->entity; } /** * The ID for the entity, if any. * * @param string $entityId */ public function setEntityId($entityId) { $this->entityId = $entityId; } /** * @return string */ public function getEntityId() { return $this->entityId; } /** * HTTP 1.1 Entity tag for the access-control entry. * * @param string $etag */ public function setEtag($etag) { $this->etag = $etag; } /** * @return string */ public function getEtag() { return $this->etag; } /** * The ID of the access-control entry. * * @param string $id */ public function setId($id) { $this->id = $id; } /** * @return string */ public function getId() { return $this->id; } /** * The kind of item this is. For bucket access control entries, this is always * storage#bucketAccessControl. * * @param string $kind */ public function setKind($kind) { $this->kind = $kind; } /** * @return string */ public function getKind() { return $this->kind; } /** * The project team associated with the entity, if any. * * @param BucketAccessControlProjectTeam $projectTeam */ public function setProjectTeam(BucketAccessControlProjectTeam $projectTeam) { $this->projectTeam = $projectTeam; } /** * @return BucketAccessControlProjectTeam */ public function getProjectTeam() { return $this->projectTeam; } /** * The access permission for the entity. * * @param string $role */ public function setRole($role) { $this->role = $role; } /** * @return string */ public function getRole() { return $this->role; } /** * The link to this access-control entry. * * @param string $selfLink */ public function setSelfLink($selfLink) { $this->selfLink = $selfLink; } /** * @return string */ public function getSelfLink() { return $this->selfLink; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(BucketAccessControl::class, 'Google_Service_Storage_BucketAccessControl'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/BucketAccessControlProjectTeam.php ================================================ projectNumber = $projectNumber; } /** * @return string */ public function getProjectNumber() { return $this->projectNumber; } /** * The team. * * @param string $team */ public function setTeam($team) { $this->team = $team; } /** * @return string */ public function getTeam() { return $this->team; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(BucketAccessControlProjectTeam::class, 'Google_Service_Storage_BucketAccessControlProjectTeam'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/BucketAccessControls.php ================================================ items = $items; } /** * @return BucketAccessControl[] */ public function getItems() { return $this->items; } /** * The kind of item this is. For lists of bucket access control entries, this * is always storage#bucketAccessControls. * * @param string $kind */ public function setKind($kind) { $this->kind = $kind; } /** * @return string */ public function getKind() { return $this->kind; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(BucketAccessControls::class, 'Google_Service_Storage_BucketAccessControls'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/BucketAutoclass.php ================================================ enabled = $enabled; } /** * @return bool */ public function getEnabled() { return $this->enabled; } /** * The storage class that objects in the bucket eventually transition to if * they are not read for a certain length of time. Valid values are NEARLINE * and ARCHIVE. * * @param string $terminalStorageClass */ public function setTerminalStorageClass($terminalStorageClass) { $this->terminalStorageClass = $terminalStorageClass; } /** * @return string */ public function getTerminalStorageClass() { return $this->terminalStorageClass; } /** * A date and time in RFC 3339 format representing the time of the most recent * update to "terminalStorageClass". * * @param string $terminalStorageClassUpdateTime */ public function setTerminalStorageClassUpdateTime($terminalStorageClassUpdateTime) { $this->terminalStorageClassUpdateTime = $terminalStorageClassUpdateTime; } /** * @return string */ public function getTerminalStorageClassUpdateTime() { return $this->terminalStorageClassUpdateTime; } /** * A date and time in RFC 3339 format representing the instant at which * "enabled" was last toggled. * * @param string $toggleTime */ public function setToggleTime($toggleTime) { $this->toggleTime = $toggleTime; } /** * @return string */ public function getToggleTime() { return $this->toggleTime; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(BucketAutoclass::class, 'Google_Service_Storage_BucketAutoclass'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/BucketBilling.php ================================================ requesterPays = $requesterPays; } /** * @return bool */ public function getRequesterPays() { return $this->requesterPays; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(BucketBilling::class, 'Google_Service_Storage_BucketBilling'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/BucketCors.php ================================================ maxAgeSeconds = $maxAgeSeconds; } /** * @return int */ public function getMaxAgeSeconds() { return $this->maxAgeSeconds; } /** * The list of HTTP methods on which to include CORS response headers, (GET, * OPTIONS, POST, etc) Note: "*" is permitted in the list of methods, and * means "any method". * * @param string[] $method */ public function setMethod($method) { $this->method = $method; } /** * @return string[] */ public function getMethod() { return $this->method; } /** * The list of Origins eligible to receive CORS response headers. Note: "*" is * permitted in the list of origins, and means "any Origin". * * @param string[] $origin */ public function setOrigin($origin) { $this->origin = $origin; } /** * @return string[] */ public function getOrigin() { return $this->origin; } /** * The list of HTTP headers other than the simple response headers to give * permission for the user-agent to share across domains. * * @param string[] $responseHeader */ public function setResponseHeader($responseHeader) { $this->responseHeader = $responseHeader; } /** * @return string[] */ public function getResponseHeader() { return $this->responseHeader; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(BucketCors::class, 'Google_Service_Storage_BucketCors'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/BucketCustomPlacementConfig.php ================================================ dataLocations = $dataLocations; } /** * @return string[] */ public function getDataLocations() { return $this->dataLocations; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(BucketCustomPlacementConfig::class, 'Google_Service_Storage_BucketCustomPlacementConfig'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/BucketEncryption.php ================================================ customerManagedEncryptionEnforcementConfig = $customerManagedEncryptionEnforcementConfig; } /** * @return BucketEncryptionCustomerManagedEncryptionEnforcementConfig */ public function getCustomerManagedEncryptionEnforcementConfig() { return $this->customerManagedEncryptionEnforcementConfig; } /** * If set, the new objects created in this bucket must comply with this * enforcement config. Changing this has no effect on existing objects; it * applies to new objects only. If omitted, the new objects are allowed to be * encrypted with Customer Supplied Encryption type by default. * * @param BucketEncryptionCustomerSuppliedEncryptionEnforcementConfig $customerSuppliedEncryptionEnforcementConfig */ public function setCustomerSuppliedEncryptionEnforcementConfig(BucketEncryptionCustomerSuppliedEncryptionEnforcementConfig $customerSuppliedEncryptionEnforcementConfig) { $this->customerSuppliedEncryptionEnforcementConfig = $customerSuppliedEncryptionEnforcementConfig; } /** * @return BucketEncryptionCustomerSuppliedEncryptionEnforcementConfig */ public function getCustomerSuppliedEncryptionEnforcementConfig() { return $this->customerSuppliedEncryptionEnforcementConfig; } /** * A Cloud KMS key that will be used to encrypt objects inserted into this * bucket, if no encryption method is specified. * * @param string $defaultKmsKeyName */ public function setDefaultKmsKeyName($defaultKmsKeyName) { $this->defaultKmsKeyName = $defaultKmsKeyName; } /** * @return string */ public function getDefaultKmsKeyName() { return $this->defaultKmsKeyName; } /** * If set, the new objects created in this bucket must comply with this * enforcement config. Changing this has no effect on existing objects; it * applies to new objects only. If omitted, the new objects are allowed to be * encrypted with Google Managed Encryption type by default. * * @param BucketEncryptionGoogleManagedEncryptionEnforcementConfig $googleManagedEncryptionEnforcementConfig */ public function setGoogleManagedEncryptionEnforcementConfig(BucketEncryptionGoogleManagedEncryptionEnforcementConfig $googleManagedEncryptionEnforcementConfig) { $this->googleManagedEncryptionEnforcementConfig = $googleManagedEncryptionEnforcementConfig; } /** * @return BucketEncryptionGoogleManagedEncryptionEnforcementConfig */ public function getGoogleManagedEncryptionEnforcementConfig() { return $this->googleManagedEncryptionEnforcementConfig; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(BucketEncryption::class, 'Google_Service_Storage_BucketEncryption'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/BucketEncryptionCustomerManagedEncryptionEnforcementConfig.php ================================================ effectiveTime = $effectiveTime; } /** * @return string */ public function getEffectiveTime() { return $this->effectiveTime; } /** * Restriction mode for Customer-Managed Encryption Keys. Defaults to * NotRestricted. * * Accepted values: NotRestricted, FullyRestricted * * @param self::RESTRICTION_MODE_* $restrictionMode */ public function setRestrictionMode($restrictionMode) { $this->restrictionMode = $restrictionMode; } /** * @return self::RESTRICTION_MODE_* */ public function getRestrictionMode() { return $this->restrictionMode; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(BucketEncryptionCustomerManagedEncryptionEnforcementConfig::class, 'Google_Service_Storage_BucketEncryptionCustomerManagedEncryptionEnforcementConfig'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/BucketEncryptionCustomerSuppliedEncryptionEnforcementConfig.php ================================================ effectiveTime = $effectiveTime; } /** * @return string */ public function getEffectiveTime() { return $this->effectiveTime; } /** * Restriction mode for Customer-Supplied Encryption Keys. Defaults to * NotRestricted. * * Accepted values: NotRestricted, FullyRestricted * * @param self::RESTRICTION_MODE_* $restrictionMode */ public function setRestrictionMode($restrictionMode) { $this->restrictionMode = $restrictionMode; } /** * @return self::RESTRICTION_MODE_* */ public function getRestrictionMode() { return $this->restrictionMode; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(BucketEncryptionCustomerSuppliedEncryptionEnforcementConfig::class, 'Google_Service_Storage_BucketEncryptionCustomerSuppliedEncryptionEnforcementConfig'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/BucketEncryptionGoogleManagedEncryptionEnforcementConfig.php ================================================ effectiveTime = $effectiveTime; } /** * @return string */ public function getEffectiveTime() { return $this->effectiveTime; } /** * Restriction mode for Google-Managed Encryption Keys. Defaults to * NotRestricted. * * Accepted values: NotRestricted, FullyRestricted * * @param self::RESTRICTION_MODE_* $restrictionMode */ public function setRestrictionMode($restrictionMode) { $this->restrictionMode = $restrictionMode; } /** * @return self::RESTRICTION_MODE_* */ public function getRestrictionMode() { return $this->restrictionMode; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(BucketEncryptionGoogleManagedEncryptionEnforcementConfig::class, 'Google_Service_Storage_BucketEncryptionGoogleManagedEncryptionEnforcementConfig'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/BucketHierarchicalNamespace.php ================================================ enabled = $enabled; } /** * @return bool */ public function getEnabled() { return $this->enabled; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(BucketHierarchicalNamespace::class, 'Google_Service_Storage_BucketHierarchicalNamespace'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/BucketIamConfiguration.php ================================================ bucketPolicyOnly = $bucketPolicyOnly; } /** * @return BucketIamConfigurationBucketPolicyOnly */ public function getBucketPolicyOnly() { return $this->bucketPolicyOnly; } /** * The bucket's Public Access Prevention configuration. Currently, 'inherited' * and 'enforced' are supported. * * @param string $publicAccessPrevention */ public function setPublicAccessPrevention($publicAccessPrevention) { $this->publicAccessPrevention = $publicAccessPrevention; } /** * @return string */ public function getPublicAccessPrevention() { return $this->publicAccessPrevention; } /** * The bucket's uniform bucket-level access configuration. * * @param BucketIamConfigurationUniformBucketLevelAccess $uniformBucketLevelAccess */ public function setUniformBucketLevelAccess(BucketIamConfigurationUniformBucketLevelAccess $uniformBucketLevelAccess) { $this->uniformBucketLevelAccess = $uniformBucketLevelAccess; } /** * @return BucketIamConfigurationUniformBucketLevelAccess */ public function getUniformBucketLevelAccess() { return $this->uniformBucketLevelAccess; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(BucketIamConfiguration::class, 'Google_Service_Storage_BucketIamConfiguration'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/BucketIamConfigurationBucketPolicyOnly.php ================================================ enabled = $enabled; } /** * @return bool */ public function getEnabled() { return $this->enabled; } /** * The deadline for changing iamConfiguration.bucketPolicyOnly.enabled from * true to false in RFC 3339 format. iamConfiguration.bucketPolicyOnly.enabled * may be changed from true to false until the locked time, after which the * field is immutable. * * @param string $lockedTime */ public function setLockedTime($lockedTime) { $this->lockedTime = $lockedTime; } /** * @return string */ public function getLockedTime() { return $this->lockedTime; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(BucketIamConfigurationBucketPolicyOnly::class, 'Google_Service_Storage_BucketIamConfigurationBucketPolicyOnly'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/BucketIamConfigurationUniformBucketLevelAccess.php ================================================ enabled = $enabled; } /** * @return bool */ public function getEnabled() { return $this->enabled; } /** * The deadline for changing iamConfiguration.uniformBucketLevelAccess.enabled * from true to false in RFC 3339 format. * iamConfiguration.uniformBucketLevelAccess.enabled may be changed from true * to false until the locked time, after which the field is immutable. * * @param string $lockedTime */ public function setLockedTime($lockedTime) { $this->lockedTime = $lockedTime; } /** * @return string */ public function getLockedTime() { return $this->lockedTime; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(BucketIamConfigurationUniformBucketLevelAccess::class, 'Google_Service_Storage_BucketIamConfigurationUniformBucketLevelAccess'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/BucketIpFilter.php ================================================ allowAllServiceAgentAccess = $allowAllServiceAgentAccess; } /** * @return bool */ public function getAllowAllServiceAgentAccess() { return $this->allowAllServiceAgentAccess; } /** * Whether to allow cross-org VPCs in the bucket's IP filter configuration. * * @param bool $allowCrossOrgVpcs */ public function setAllowCrossOrgVpcs($allowCrossOrgVpcs) { $this->allowCrossOrgVpcs = $allowCrossOrgVpcs; } /** * @return bool */ public function getAllowCrossOrgVpcs() { return $this->allowCrossOrgVpcs; } /** * The mode of the IP filter. Valid values are 'Enabled' and 'Disabled'. * * @param string $mode */ public function setMode($mode) { $this->mode = $mode; } /** * @return string */ public function getMode() { return $this->mode; } /** * The public network source of the bucket's IP filter. * * @param BucketIpFilterPublicNetworkSource $publicNetworkSource */ public function setPublicNetworkSource(BucketIpFilterPublicNetworkSource $publicNetworkSource) { $this->publicNetworkSource = $publicNetworkSource; } /** * @return BucketIpFilterPublicNetworkSource */ public function getPublicNetworkSource() { return $this->publicNetworkSource; } /** * The list of [VPC network](https://cloud.google.com/vpc/docs/vpc) sources of * the bucket's IP filter. * * @param BucketIpFilterVpcNetworkSources[] $vpcNetworkSources */ public function setVpcNetworkSources($vpcNetworkSources) { $this->vpcNetworkSources = $vpcNetworkSources; } /** * @return BucketIpFilterVpcNetworkSources[] */ public function getVpcNetworkSources() { return $this->vpcNetworkSources; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(BucketIpFilter::class, 'Google_Service_Storage_BucketIpFilter'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/BucketIpFilterPublicNetworkSource.php ================================================ allowedIpCidrRanges = $allowedIpCidrRanges; } /** * @return string[] */ public function getAllowedIpCidrRanges() { return $this->allowedIpCidrRanges; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(BucketIpFilterPublicNetworkSource::class, 'Google_Service_Storage_BucketIpFilterPublicNetworkSource'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/BucketIpFilterVpcNetworkSources.php ================================================ allowedIpCidrRanges = $allowedIpCidrRanges; } /** * @return string[] */ public function getAllowedIpCidrRanges() { return $this->allowedIpCidrRanges; } /** * Name of the network. Format: * projects/{PROJECT_ID}/global/networks/{NETWORK_NAME} * * @param string $network */ public function setNetwork($network) { $this->network = $network; } /** * @return string */ public function getNetwork() { return $this->network; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(BucketIpFilterVpcNetworkSources::class, 'Google_Service_Storage_BucketIpFilterVpcNetworkSources'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/BucketLifecycle.php ================================================ rule = $rule; } /** * @return BucketLifecycleRule[] */ public function getRule() { return $this->rule; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(BucketLifecycle::class, 'Google_Service_Storage_BucketLifecycle'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/BucketLifecycleRule.php ================================================ action = $action; } /** * @return BucketLifecycleRuleAction */ public function getAction() { return $this->action; } /** * The condition(s) under which the action will be taken. * * @param BucketLifecycleRuleCondition $condition */ public function setCondition(BucketLifecycleRuleCondition $condition) { $this->condition = $condition; } /** * @return BucketLifecycleRuleCondition */ public function getCondition() { return $this->condition; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(BucketLifecycleRule::class, 'Google_Service_Storage_BucketLifecycleRule'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/BucketLifecycleRuleAction.php ================================================ storageClass = $storageClass; } /** * @return string */ public function getStorageClass() { return $this->storageClass; } /** * Type of the action. Currently, only Delete, SetStorageClass, and * AbortIncompleteMultipartUpload are supported. * * @param string $type */ public function setType($type) { $this->type = $type; } /** * @return string */ public function getType() { return $this->type; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(BucketLifecycleRuleAction::class, 'Google_Service_Storage_BucketLifecycleRuleAction'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/BucketLifecycleRuleCondition.php ================================================ age = $age; } /** * @return int */ public function getAge() { return $this->age; } /** * A date in RFC 3339 format with only the date part (for instance, * "2013-01-15"). This condition is satisfied when an object is created before * midnight of the specified date in UTC. * * @param string $createdBefore */ public function setCreatedBefore($createdBefore) { $this->createdBefore = $createdBefore; } /** * @return string */ public function getCreatedBefore() { return $this->createdBefore; } /** * A date in RFC 3339 format with only the date part (for instance, * "2013-01-15"). This condition is satisfied when the custom time on an * object is before this date in UTC. * * @param string $customTimeBefore */ public function setCustomTimeBefore($customTimeBefore) { $this->customTimeBefore = $customTimeBefore; } /** * @return string */ public function getCustomTimeBefore() { return $this->customTimeBefore; } /** * Number of days elapsed since the user-specified timestamp set on an object. * The condition is satisfied if the days elapsed is at least this number. If * no custom timestamp is specified on an object, the condition does not * apply. * * @param int $daysSinceCustomTime */ public function setDaysSinceCustomTime($daysSinceCustomTime) { $this->daysSinceCustomTime = $daysSinceCustomTime; } /** * @return int */ public function getDaysSinceCustomTime() { return $this->daysSinceCustomTime; } /** * Number of days elapsed since the noncurrent timestamp of an object. The * condition is satisfied if the days elapsed is at least this number. This * condition is relevant only for versioned objects. The value of the field * must be a nonnegative integer. If it's zero, the object version will become * eligible for Lifecycle action as soon as it becomes noncurrent. * * @param int $daysSinceNoncurrentTime */ public function setDaysSinceNoncurrentTime($daysSinceNoncurrentTime) { $this->daysSinceNoncurrentTime = $daysSinceNoncurrentTime; } /** * @return int */ public function getDaysSinceNoncurrentTime() { return $this->daysSinceNoncurrentTime; } /** * Relevant only for versioned objects. If the value is true, this condition * matches live objects; if the value is false, it matches archived objects. * * @param bool $isLive */ public function setIsLive($isLive) { $this->isLive = $isLive; } /** * @return bool */ public function getIsLive() { return $this->isLive; } /** * A regular expression that satisfies the RE2 syntax. This condition is * satisfied when the name of the object matches the RE2 pattern. Note: This * feature is currently in the "Early Access" launch stage and is only * available to a whitelisted set of users; that means that this feature may * be changed in backward-incompatible ways and that it is not guaranteed to * be released. * * @param string $matchesPattern */ public function setMatchesPattern($matchesPattern) { $this->matchesPattern = $matchesPattern; } /** * @return string */ public function getMatchesPattern() { return $this->matchesPattern; } /** * List of object name prefixes. This condition will be satisfied when at * least one of the prefixes exactly matches the beginning of the object name. * * @param string[] $matchesPrefix */ public function setMatchesPrefix($matchesPrefix) { $this->matchesPrefix = $matchesPrefix; } /** * @return string[] */ public function getMatchesPrefix() { return $this->matchesPrefix; } /** * Objects having any of the storage classes specified by this condition will * be matched. Values include MULTI_REGIONAL, REGIONAL, NEARLINE, COLDLINE, * ARCHIVE, STANDARD, and DURABLE_REDUCED_AVAILABILITY. * * @param string[] $matchesStorageClass */ public function setMatchesStorageClass($matchesStorageClass) { $this->matchesStorageClass = $matchesStorageClass; } /** * @return string[] */ public function getMatchesStorageClass() { return $this->matchesStorageClass; } /** * List of object name suffixes. This condition will be satisfied when at * least one of the suffixes exactly matches the end of the object name. * * @param string[] $matchesSuffix */ public function setMatchesSuffix($matchesSuffix) { $this->matchesSuffix = $matchesSuffix; } /** * @return string[] */ public function getMatchesSuffix() { return $this->matchesSuffix; } /** * A date in RFC 3339 format with only the date part (for instance, * "2013-01-15"). This condition is satisfied when the noncurrent time on an * object is before this date in UTC. This condition is relevant only for * versioned objects. * * @param string $noncurrentTimeBefore */ public function setNoncurrentTimeBefore($noncurrentTimeBefore) { $this->noncurrentTimeBefore = $noncurrentTimeBefore; } /** * @return string */ public function getNoncurrentTimeBefore() { return $this->noncurrentTimeBefore; } /** * Relevant only for versioned objects. If the value is N, this condition is * satisfied when there are at least N versions (including the live version) * newer than this version of the object. * * @param int $numNewerVersions */ public function setNumNewerVersions($numNewerVersions) { $this->numNewerVersions = $numNewerVersions; } /** * @return int */ public function getNumNewerVersions() { return $this->numNewerVersions; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(BucketLifecycleRuleCondition::class, 'Google_Service_Storage_BucketLifecycleRuleCondition'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/BucketLogging.php ================================================ logBucket = $logBucket; } /** * @return string */ public function getLogBucket() { return $this->logBucket; } /** * A prefix for log object names. * * @param string $logObjectPrefix */ public function setLogObjectPrefix($logObjectPrefix) { $this->logObjectPrefix = $logObjectPrefix; } /** * @return string */ public function getLogObjectPrefix() { return $this->logObjectPrefix; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(BucketLogging::class, 'Google_Service_Storage_BucketLogging'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/BucketObjectRetention.php ================================================ mode = $mode; } /** * @return string */ public function getMode() { return $this->mode; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(BucketObjectRetention::class, 'Google_Service_Storage_BucketObjectRetention'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/BucketOwner.php ================================================ entity = $entity; } /** * @return string */ public function getEntity() { return $this->entity; } /** * The ID for the entity. * * @param string $entityId */ public function setEntityId($entityId) { $this->entityId = $entityId; } /** * @return string */ public function getEntityId() { return $this->entityId; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(BucketOwner::class, 'Google_Service_Storage_BucketOwner'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/BucketRetentionPolicy.php ================================================ effectiveTime = $effectiveTime; } /** * @return string */ public function getEffectiveTime() { return $this->effectiveTime; } /** * Once locked, an object retention policy cannot be modified. * * @param bool $isLocked */ public function setIsLocked($isLocked) { $this->isLocked = $isLocked; } /** * @return bool */ public function getIsLocked() { return $this->isLocked; } /** * The duration in seconds that objects need to be retained. Retention * duration must be greater than zero and less than 100 years. Note that * enforcement of retention periods less than a day is not guaranteed. Such * periods should only be used for testing purposes. * * @param string $retentionPeriod */ public function setRetentionPeriod($retentionPeriod) { $this->retentionPeriod = $retentionPeriod; } /** * @return string */ public function getRetentionPeriod() { return $this->retentionPeriod; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(BucketRetentionPolicy::class, 'Google_Service_Storage_BucketRetentionPolicy'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/BucketSoftDeletePolicy.php ================================================ effectiveTime = $effectiveTime; } /** * @return string */ public function getEffectiveTime() { return $this->effectiveTime; } /** * The duration in seconds that soft-deleted objects in the bucket will be * retained and cannot be permanently deleted. * * @param string $retentionDurationSeconds */ public function setRetentionDurationSeconds($retentionDurationSeconds) { $this->retentionDurationSeconds = $retentionDurationSeconds; } /** * @return string */ public function getRetentionDurationSeconds() { return $this->retentionDurationSeconds; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(BucketSoftDeletePolicy::class, 'Google_Service_Storage_BucketSoftDeletePolicy'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/BucketStorageLayout.php ================================================ bucket = $bucket; } /** * @return string */ public function getBucket() { return $this->bucket; } /** * The bucket's custom placement configuration for Custom Dual Regions. * * @param BucketStorageLayoutCustomPlacementConfig $customPlacementConfig */ public function setCustomPlacementConfig(BucketStorageLayoutCustomPlacementConfig $customPlacementConfig) { $this->customPlacementConfig = $customPlacementConfig; } /** * @return BucketStorageLayoutCustomPlacementConfig */ public function getCustomPlacementConfig() { return $this->customPlacementConfig; } /** * The bucket's hierarchical namespace configuration. * * @param BucketStorageLayoutHierarchicalNamespace $hierarchicalNamespace */ public function setHierarchicalNamespace(BucketStorageLayoutHierarchicalNamespace $hierarchicalNamespace) { $this->hierarchicalNamespace = $hierarchicalNamespace; } /** * @return BucketStorageLayoutHierarchicalNamespace */ public function getHierarchicalNamespace() { return $this->hierarchicalNamespace; } /** * The kind of item this is. For storage layout, this is always * storage#storageLayout. * * @param string $kind */ public function setKind($kind) { $this->kind = $kind; } /** * @return string */ public function getKind() { return $this->kind; } /** * The location of the bucket. * * @param string $location */ public function setLocation($location) { $this->location = $location; } /** * @return string */ public function getLocation() { return $this->location; } /** * The type of the bucket location. * * @param string $locationType */ public function setLocationType($locationType) { $this->locationType = $locationType; } /** * @return string */ public function getLocationType() { return $this->locationType; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(BucketStorageLayout::class, 'Google_Service_Storage_BucketStorageLayout'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/BucketStorageLayoutCustomPlacementConfig.php ================================================ dataLocations = $dataLocations; } /** * @return string[] */ public function getDataLocations() { return $this->dataLocations; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(BucketStorageLayoutCustomPlacementConfig::class, 'Google_Service_Storage_BucketStorageLayoutCustomPlacementConfig'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/BucketStorageLayoutHierarchicalNamespace.php ================================================ enabled = $enabled; } /** * @return bool */ public function getEnabled() { return $this->enabled; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(BucketStorageLayoutHierarchicalNamespace::class, 'Google_Service_Storage_BucketStorageLayoutHierarchicalNamespace'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/BucketVersioning.php ================================================ enabled = $enabled; } /** * @return bool */ public function getEnabled() { return $this->enabled; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(BucketVersioning::class, 'Google_Service_Storage_BucketVersioning'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/BucketWebsite.php ================================================ mainPageSuffix = $mainPageSuffix; } /** * @return string */ public function getMainPageSuffix() { return $this->mainPageSuffix; } /** * If the requested object path is missing, and any mainPageSuffix object is * missing, if applicable, the service will return the named object from this * bucket as the content for a 404 Not Found result. * * @param string $notFoundPage */ public function setNotFoundPage($notFoundPage) { $this->notFoundPage = $notFoundPage; } /** * @return string */ public function getNotFoundPage() { return $this->notFoundPage; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(BucketWebsite::class, 'Google_Service_Storage_BucketWebsite'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/Buckets.php ================================================ items = $items; } /** * @return Bucket[] */ public function getItems() { return $this->items; } /** * The kind of item this is. For lists of buckets, this is always * storage#buckets. * * @param string $kind */ public function setKind($kind) { $this->kind = $kind; } /** * @return string */ public function getKind() { return $this->kind; } /** * The continuation token, used to page through large result sets. Provide * this value in a subsequent request to return the next page of results. * * @param string $nextPageToken */ public function setNextPageToken($nextPageToken) { $this->nextPageToken = $nextPageToken; } /** * @return string */ public function getNextPageToken() { return $this->nextPageToken; } /** * The list of bucket resource names that could not be reached during the * listing operation. * * @param string[] $unreachable */ public function setUnreachable($unreachable) { $this->unreachable = $unreachable; } /** * @return string[] */ public function getUnreachable() { return $this->unreachable; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(Buckets::class, 'Google_Service_Storage_Buckets'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/BulkRestoreObjectsRequest.php ================================================ allowOverwrite = $allowOverwrite; } /** * @return bool */ public function getAllowOverwrite() { return $this->allowOverwrite; } /** * If true, copies the source object's ACL; otherwise, uses the bucket's * default object ACL. The default is false. * * @param bool $copySourceAcl */ public function setCopySourceAcl($copySourceAcl) { $this->copySourceAcl = $copySourceAcl; } /** * @return bool */ public function getCopySourceAcl() { return $this->copySourceAcl; } /** * Restores only the objects that were created after this time. * * @param string $createdAfterTime */ public function setCreatedAfterTime($createdAfterTime) { $this->createdAfterTime = $createdAfterTime; } /** * @return string */ public function getCreatedAfterTime() { return $this->createdAfterTime; } /** * Restores only the objects that were created before this time. * * @param string $createdBeforeTime */ public function setCreatedBeforeTime($createdBeforeTime) { $this->createdBeforeTime = $createdBeforeTime; } /** * @return string */ public function getCreatedBeforeTime() { return $this->createdBeforeTime; } /** * Restores only the objects matching any of the specified glob(s). If this * parameter is not specified, all objects will be restored within the * specified time range. * * @param string[] $matchGlobs */ public function setMatchGlobs($matchGlobs) { $this->matchGlobs = $matchGlobs; } /** * @return string[] */ public function getMatchGlobs() { return $this->matchGlobs; } /** * Restores only the objects that were soft-deleted after this time. * * @param string $softDeletedAfterTime */ public function setSoftDeletedAfterTime($softDeletedAfterTime) { $this->softDeletedAfterTime = $softDeletedAfterTime; } /** * @return string */ public function getSoftDeletedAfterTime() { return $this->softDeletedAfterTime; } /** * Restores only the objects that were soft-deleted before this time. * * @param string $softDeletedBeforeTime */ public function setSoftDeletedBeforeTime($softDeletedBeforeTime) { $this->softDeletedBeforeTime = $softDeletedBeforeTime; } /** * @return string */ public function getSoftDeletedBeforeTime() { return $this->softDeletedBeforeTime; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(BulkRestoreObjectsRequest::class, 'Google_Service_Storage_BulkRestoreObjectsRequest'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/Channel.php ================================================ address = $address; } /** * @return string */ public function getAddress() { return $this->address; } /** * Date and time of notification channel expiration, expressed as a Unix * timestamp, in milliseconds. Optional. * * @param string $expiration */ public function setExpiration($expiration) { $this->expiration = $expiration; } /** * @return string */ public function getExpiration() { return $this->expiration; } /** * A UUID or similar unique string that identifies this channel. * * @param string $id */ public function setId($id) { $this->id = $id; } /** * @return string */ public function getId() { return $this->id; } /** * Identifies this as a notification channel used to watch for changes to a * resource, which is "api#channel". * * @param string $kind */ public function setKind($kind) { $this->kind = $kind; } /** * @return string */ public function getKind() { return $this->kind; } /** * Additional parameters controlling delivery channel behavior. Optional. * * @param string[] $params */ public function setParams($params) { $this->params = $params; } /** * @return string[] */ public function getParams() { return $this->params; } /** * A Boolean value to indicate whether payload is wanted. Optional. * * @param bool $payload */ public function setPayload($payload) { $this->payload = $payload; } /** * @return bool */ public function getPayload() { return $this->payload; } /** * An opaque ID that identifies the resource being watched on this channel. * Stable across different API versions. * * @param string $resourceId */ public function setResourceId($resourceId) { $this->resourceId = $resourceId; } /** * @return string */ public function getResourceId() { return $this->resourceId; } /** * A version-specific identifier for the watched resource. * * @param string $resourceUri */ public function setResourceUri($resourceUri) { $this->resourceUri = $resourceUri; } /** * @return string */ public function getResourceUri() { return $this->resourceUri; } /** * An arbitrary string delivered to the target address with each notification * delivered over this channel. Optional. * * @param string $token */ public function setToken($token) { $this->token = $token; } /** * @return string */ public function getToken() { return $this->token; } /** * The type of delivery mechanism used for this channel. * * @param string $type */ public function setType($type) { $this->type = $type; } /** * @return string */ public function getType() { return $this->type; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(Channel::class, 'Google_Service_Storage_Channel'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/ComposeRequest.php ================================================ deleteSourceObjects = $deleteSourceObjects; } /** * @return bool */ public function getDeleteSourceObjects() { return $this->deleteSourceObjects; } /** * Properties of the resulting object. * * @param StorageObject $destination */ public function setDestination(StorageObject $destination) { $this->destination = $destination; } /** * @return StorageObject */ public function getDestination() { return $this->destination; } /** * The kind of item this is. * * @param string $kind */ public function setKind($kind) { $this->kind = $kind; } /** * @return string */ public function getKind() { return $this->kind; } /** * The list of source objects that will be concatenated into a single object. * * @param ComposeRequestSourceObjects[] $sourceObjects */ public function setSourceObjects($sourceObjects) { $this->sourceObjects = $sourceObjects; } /** * @return ComposeRequestSourceObjects[] */ public function getSourceObjects() { return $this->sourceObjects; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(ComposeRequest::class, 'Google_Service_Storage_ComposeRequest'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/ComposeRequestSourceObjects.php ================================================ generation = $generation; } /** * @return string */ public function getGeneration() { return $this->generation; } /** * The source object's name. All source objects must reside in the same * bucket. * * @param string $name */ public function setName($name) { $this->name = $name; } /** * @return string */ public function getName() { return $this->name; } /** * Conditions that must be met for this operation to execute. * * @param ComposeRequestSourceObjectsObjectPreconditions $objectPreconditions */ public function setObjectPreconditions(ComposeRequestSourceObjectsObjectPreconditions $objectPreconditions) { $this->objectPreconditions = $objectPreconditions; } /** * @return ComposeRequestSourceObjectsObjectPreconditions */ public function getObjectPreconditions() { return $this->objectPreconditions; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(ComposeRequestSourceObjects::class, 'Google_Service_Storage_ComposeRequestSourceObjects'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/ComposeRequestSourceObjectsObjectPreconditions.php ================================================ ifGenerationMatch = $ifGenerationMatch; } /** * @return string */ public function getIfGenerationMatch() { return $this->ifGenerationMatch; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(ComposeRequestSourceObjectsObjectPreconditions::class, 'Google_Service_Storage_ComposeRequestSourceObjectsObjectPreconditions'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/Expr.php ================================================ description = $description; } /** * @return string */ public function getDescription() { return $this->description; } /** * Textual representation of an expression in Common Expression Language * syntax. The application context of the containing message determines which * well-known feature set of CEL is supported. * * @param string $expression */ public function setExpression($expression) { $this->expression = $expression; } /** * @return string */ public function getExpression() { return $this->expression; } /** * An optional string indicating the location of the expression for error * reporting, e.g. a file name and a position in the file. * * @param string $location */ public function setLocation($location) { $this->location = $location; } /** * @return string */ public function getLocation() { return $this->location; } /** * An optional title for the expression, i.e. a short string describing its * purpose. This can be used e.g. in UIs which allow to enter the expression. * * @param string $title */ public function setTitle($title) { $this->title = $title; } /** * @return string */ public function getTitle() { return $this->title; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(Expr::class, 'Google_Service_Storage_Expr'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/Folder.php ================================================ bucket = $bucket; } /** * @return string */ public function getBucket() { return $this->bucket; } /** * The creation time of the folder in RFC 3339 format. * * @param string $createTime */ public function setCreateTime($createTime) { $this->createTime = $createTime; } /** * @return string */ public function getCreateTime() { return $this->createTime; } /** * The ID of the folder, including the bucket name, folder name. * * @param string $id */ public function setId($id) { $this->id = $id; } /** * @return string */ public function getId() { return $this->id; } /** * The kind of item this is. For folders, this is always storage#folder. * * @param string $kind */ public function setKind($kind) { $this->kind = $kind; } /** * @return string */ public function getKind() { return $this->kind; } /** * The version of the metadata for this folder. Used for preconditions and for * detecting changes in metadata. * * @param string $metageneration */ public function setMetageneration($metageneration) { $this->metageneration = $metageneration; } /** * @return string */ public function getMetageneration() { return $this->metageneration; } /** * The name of the folder. Required if not specified by URL parameter. * * @param string $name */ public function setName($name) { $this->name = $name; } /** * @return string */ public function getName() { return $this->name; } /** * Only present if the folder is part of an ongoing rename folder operation. * Contains information which can be used to query the operation status. * * @param FolderPendingRenameInfo $pendingRenameInfo */ public function setPendingRenameInfo(FolderPendingRenameInfo $pendingRenameInfo) { $this->pendingRenameInfo = $pendingRenameInfo; } /** * @return FolderPendingRenameInfo */ public function getPendingRenameInfo() { return $this->pendingRenameInfo; } /** * The link to this folder. * * @param string $selfLink */ public function setSelfLink($selfLink) { $this->selfLink = $selfLink; } /** * @return string */ public function getSelfLink() { return $this->selfLink; } /** * The modification time of the folder metadata in RFC 3339 format. * * @param string $updateTime */ public function setUpdateTime($updateTime) { $this->updateTime = $updateTime; } /** * @return string */ public function getUpdateTime() { return $this->updateTime; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(Folder::class, 'Google_Service_Storage_Folder'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/FolderPendingRenameInfo.php ================================================ operationId = $operationId; } /** * @return string */ public function getOperationId() { return $this->operationId; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(FolderPendingRenameInfo::class, 'Google_Service_Storage_FolderPendingRenameInfo'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/Folders.php ================================================ items = $items; } /** * @return Folder[] */ public function getItems() { return $this->items; } /** * The kind of item this is. For lists of folders, this is always * storage#folders. * * @param string $kind */ public function setKind($kind) { $this->kind = $kind; } /** * @return string */ public function getKind() { return $this->kind; } /** * The continuation token, used to page through large result sets. Provide * this value in a subsequent request to return the next page of results. * * @param string $nextPageToken */ public function setNextPageToken($nextPageToken) { $this->nextPageToken = $nextPageToken; } /** * @return string */ public function getNextPageToken() { return $this->nextPageToken; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(Folders::class, 'Google_Service_Storage_Folders'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/GoogleLongrunningListOperationsResponse.php ================================================ kind = $kind; } /** * @return string */ public function getKind() { return $this->kind; } /** * The continuation token, used to page through large result sets. Provide * this value in a subsequent request to return the next page of results. * * @param string $nextPageToken */ public function setNextPageToken($nextPageToken) { $this->nextPageToken = $nextPageToken; } /** * @return string */ public function getNextPageToken() { return $this->nextPageToken; } /** * A list of operations that matches the specified filter in the request. * * @param GoogleLongrunningOperation[] $operations */ public function setOperations($operations) { $this->operations = $operations; } /** * @return GoogleLongrunningOperation[] */ public function getOperations() { return $this->operations; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(GoogleLongrunningListOperationsResponse::class, 'Google_Service_Storage_GoogleLongrunningListOperationsResponse'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/GoogleLongrunningOperation.php ================================================ done = $done; } /** * @return bool */ public function getDone() { return $this->done; } /** * The error result of the operation in case of failure or cancellation. * * @param GoogleRpcStatus $error */ public function setError(GoogleRpcStatus $error) { $this->error = $error; } /** * @return GoogleRpcStatus */ public function getError() { return $this->error; } /** * The kind of item this is. For operations, this is always storage#operation. * * @param string $kind */ public function setKind($kind) { $this->kind = $kind; } /** * @return string */ public function getKind() { return $this->kind; } /** * Service-specific metadata associated with the operation. It typically * contains progress information and common metadata such as create time. Some * services might not provide such metadata. Any method that returns a long- * running operation should document the metadata type, if any. * * @param array[] $metadata */ public function setMetadata($metadata) { $this->metadata = $metadata; } /** * @return array[] */ public function getMetadata() { return $this->metadata; } /** * The server-assigned name, which is only unique within the same service that * originally returns it. If you use the default HTTP mapping, the "name" * should be a resource name ending with "operations/{operationId}". * * @param string $name */ public function setName($name) { $this->name = $name; } /** * @return string */ public function getName() { return $this->name; } /** * The normal response of the operation in case of success. If the original * method returns no data on success, such as "Delete", the response is * google.protobuf.Empty. If the original method is standard * Get/Create/Update, the response should be the resource. For other methods, * the response should have the type "XxxResponse", where "Xxx" is the * original method name. For example, if the original method name is * "TakeSnapshot()", the inferred response type is "TakeSnapshotResponse". * * @param array[] $response */ public function setResponse($response) { $this->response = $response; } /** * @return array[] */ public function getResponse() { return $this->response; } /** * The link to this long running operation. * * @param string $selfLink */ public function setSelfLink($selfLink) { $this->selfLink = $selfLink; } /** * @return string */ public function getSelfLink() { return $this->selfLink; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(GoogleLongrunningOperation::class, 'Google_Service_Storage_GoogleLongrunningOperation'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/GoogleRpcStatus.php ================================================ code = $code; } /** * @return int */ public function getCode() { return $this->code; } /** * A list of messages that carry the error details. There is a common set of * message types for APIs to use. * * @param array[] $details */ public function setDetails($details) { $this->details = $details; } /** * @return array[] */ public function getDetails() { return $this->details; } /** * A developer-facing error message, which should be in English. * * @param string $message */ public function setMessage($message) { $this->message = $message; } /** * @return string */ public function getMessage() { return $this->message; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(GoogleRpcStatus::class, 'Google_Service_Storage_GoogleRpcStatus'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/HmacKey.php ================================================ kind = $kind; } /** * @return string */ public function getKind() { return $this->kind; } /** * Key metadata. * * @param HmacKeyMetadata $metadata */ public function setMetadata(HmacKeyMetadata $metadata) { $this->metadata = $metadata; } /** * @return HmacKeyMetadata */ public function getMetadata() { return $this->metadata; } /** * HMAC secret key material. * * @param string $secret */ public function setSecret($secret) { $this->secret = $secret; } /** * @return string */ public function getSecret() { return $this->secret; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(HmacKey::class, 'Google_Service_Storage_HmacKey'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/HmacKeyMetadata.php ================================================ accessId = $accessId; } /** * @return string */ public function getAccessId() { return $this->accessId; } /** * HTTP 1.1 Entity tag for the HMAC key. * * @param string $etag */ public function setEtag($etag) { $this->etag = $etag; } /** * @return string */ public function getEtag() { return $this->etag; } /** * The ID of the HMAC key, including the Project ID and the Access ID. * * @param string $id */ public function setId($id) { $this->id = $id; } /** * @return string */ public function getId() { return $this->id; } /** * The kind of item this is. For HMAC Key metadata, this is always * storage#hmacKeyMetadata. * * @param string $kind */ public function setKind($kind) { $this->kind = $kind; } /** * @return string */ public function getKind() { return $this->kind; } /** * Project ID owning the service account to which the key authenticates. * * @param string $projectId */ public function setProjectId($projectId) { $this->projectId = $projectId; } /** * @return string */ public function getProjectId() { return $this->projectId; } /** * The link to this resource. * * @param string $selfLink */ public function setSelfLink($selfLink) { $this->selfLink = $selfLink; } /** * @return string */ public function getSelfLink() { return $this->selfLink; } /** * The email address of the key's associated service account. * * @param string $serviceAccountEmail */ public function setServiceAccountEmail($serviceAccountEmail) { $this->serviceAccountEmail = $serviceAccountEmail; } /** * @return string */ public function getServiceAccountEmail() { return $this->serviceAccountEmail; } /** * The state of the key. Can be one of ACTIVE, INACTIVE, or DELETED. * * @param string $state */ public function setState($state) { $this->state = $state; } /** * @return string */ public function getState() { return $this->state; } /** * The creation time of the HMAC key in RFC 3339 format. * * @param string $timeCreated */ public function setTimeCreated($timeCreated) { $this->timeCreated = $timeCreated; } /** * @return string */ public function getTimeCreated() { return $this->timeCreated; } /** * The last modification time of the HMAC key metadata in RFC 3339 format. * * @param string $updated */ public function setUpdated($updated) { $this->updated = $updated; } /** * @return string */ public function getUpdated() { return $this->updated; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(HmacKeyMetadata::class, 'Google_Service_Storage_HmacKeyMetadata'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/HmacKeysMetadata.php ================================================ items = $items; } /** * @return HmacKeyMetadata[] */ public function getItems() { return $this->items; } /** * The kind of item this is. For lists of hmacKeys, this is always * storage#hmacKeysMetadata. * * @param string $kind */ public function setKind($kind) { $this->kind = $kind; } /** * @return string */ public function getKind() { return $this->kind; } /** * The continuation token, used to page through large result sets. Provide * this value in a subsequent request to return the next page of results. * * @param string $nextPageToken */ public function setNextPageToken($nextPageToken) { $this->nextPageToken = $nextPageToken; } /** * @return string */ public function getNextPageToken() { return $this->nextPageToken; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(HmacKeysMetadata::class, 'Google_Service_Storage_HmacKeysMetadata'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/ManagedFolder.php ================================================ bucket = $bucket; } /** * @return string */ public function getBucket() { return $this->bucket; } /** * The creation time of the managed folder in RFC 3339 format. * * @param string $createTime */ public function setCreateTime($createTime) { $this->createTime = $createTime; } /** * @return string */ public function getCreateTime() { return $this->createTime; } /** * The ID of the managed folder, including the bucket name and managed folder * name. * * @param string $id */ public function setId($id) { $this->id = $id; } /** * @return string */ public function getId() { return $this->id; } /** * The kind of item this is. For managed folders, this is always * storage#managedFolder. * * @param string $kind */ public function setKind($kind) { $this->kind = $kind; } /** * @return string */ public function getKind() { return $this->kind; } /** * The version of the metadata for this managed folder. Used for preconditions * and for detecting changes in metadata. * * @param string $metageneration */ public function setMetageneration($metageneration) { $this->metageneration = $metageneration; } /** * @return string */ public function getMetageneration() { return $this->metageneration; } /** * The name of the managed folder. Required if not specified by URL parameter. * * @param string $name */ public function setName($name) { $this->name = $name; } /** * @return string */ public function getName() { return $this->name; } /** * The link to this managed folder. * * @param string $selfLink */ public function setSelfLink($selfLink) { $this->selfLink = $selfLink; } /** * @return string */ public function getSelfLink() { return $this->selfLink; } /** * The last update time of the managed folder metadata in RFC 3339 format. * * @param string $updateTime */ public function setUpdateTime($updateTime) { $this->updateTime = $updateTime; } /** * @return string */ public function getUpdateTime() { return $this->updateTime; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(ManagedFolder::class, 'Google_Service_Storage_ManagedFolder'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/ManagedFolders.php ================================================ items = $items; } /** * @return ManagedFolder[] */ public function getItems() { return $this->items; } /** * The kind of item this is. For lists of managed folders, this is always * storage#managedFolders. * * @param string $kind */ public function setKind($kind) { $this->kind = $kind; } /** * @return string */ public function getKind() { return $this->kind; } /** * The continuation token, used to page through large result sets. Provide * this value in a subsequent request to return the next page of results. * * @param string $nextPageToken */ public function setNextPageToken($nextPageToken) { $this->nextPageToken = $nextPageToken; } /** * @return string */ public function getNextPageToken() { return $this->nextPageToken; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(ManagedFolders::class, 'Google_Service_Storage_ManagedFolders'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/Notification.php ================================================ "custom_attributes", "eventTypes" => "event_types", "objectNamePrefix" => "object_name_prefix", "payloadFormat" => "payload_format", ]; /** * An optional list of additional attributes to attach to each Cloud PubSub * message published for this notification subscription. * * @var string[] */ public $customAttributes; /** * HTTP 1.1 Entity tag for this subscription notification. * * @var string */ public $etag; /** * If present, only send notifications about listed event types. If empty, * sent notifications for all event types. * * @var string[] */ public $eventTypes; /** * The ID of the notification. * * @var string */ public $id; /** * The kind of item this is. For notifications, this is always * storage#notification. * * @var string */ public $kind; /** * If present, only apply this notification configuration to object names that * begin with this prefix. * * @var string */ public $objectNamePrefix; /** * The desired content of the Payload. * * @var string */ public $payloadFormat; /** * The canonical URL of this notification. * * @var string */ public $selfLink; /** * The Cloud PubSub topic to which this subscription publishes. Formatted as: * '//pubsub.googleapis.com/projects/{project-identifier}/topics/{my-topic}' * * @var string */ public $topic; /** * An optional list of additional attributes to attach to each Cloud PubSub * message published for this notification subscription. * * @param string[] $customAttributes */ public function setCustomAttributes($customAttributes) { $this->customAttributes = $customAttributes; } /** * @return string[] */ public function getCustomAttributes() { return $this->customAttributes; } /** * HTTP 1.1 Entity tag for this subscription notification. * * @param string $etag */ public function setEtag($etag) { $this->etag = $etag; } /** * @return string */ public function getEtag() { return $this->etag; } /** * If present, only send notifications about listed event types. If empty, * sent notifications for all event types. * * @param string[] $eventTypes */ public function setEventTypes($eventTypes) { $this->eventTypes = $eventTypes; } /** * @return string[] */ public function getEventTypes() { return $this->eventTypes; } /** * The ID of the notification. * * @param string $id */ public function setId($id) { $this->id = $id; } /** * @return string */ public function getId() { return $this->id; } /** * The kind of item this is. For notifications, this is always * storage#notification. * * @param string $kind */ public function setKind($kind) { $this->kind = $kind; } /** * @return string */ public function getKind() { return $this->kind; } /** * If present, only apply this notification configuration to object names that * begin with this prefix. * * @param string $objectNamePrefix */ public function setObjectNamePrefix($objectNamePrefix) { $this->objectNamePrefix = $objectNamePrefix; } /** * @return string */ public function getObjectNamePrefix() { return $this->objectNamePrefix; } /** * The desired content of the Payload. * * @param string $payloadFormat */ public function setPayloadFormat($payloadFormat) { $this->payloadFormat = $payloadFormat; } /** * @return string */ public function getPayloadFormat() { return $this->payloadFormat; } /** * The canonical URL of this notification. * * @param string $selfLink */ public function setSelfLink($selfLink) { $this->selfLink = $selfLink; } /** * @return string */ public function getSelfLink() { return $this->selfLink; } /** * The Cloud PubSub topic to which this subscription publishes. Formatted as: * '//pubsub.googleapis.com/projects/{project-identifier}/topics/{my-topic}' * * @param string $topic */ public function setTopic($topic) { $this->topic = $topic; } /** * @return string */ public function getTopic() { return $this->topic; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(Notification::class, 'Google_Service_Storage_Notification'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/Notifications.php ================================================ items = $items; } /** * @return Notification[] */ public function getItems() { return $this->items; } /** * The kind of item this is. For lists of notifications, this is always * storage#notifications. * * @param string $kind */ public function setKind($kind) { $this->kind = $kind; } /** * @return string */ public function getKind() { return $this->kind; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(Notifications::class, 'Google_Service_Storage_Notifications'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/ObjectAccessControl.php ================================================ bucket = $bucket; } /** * @return string */ public function getBucket() { return $this->bucket; } /** * The domain associated with the entity, if any. * * @param string $domain */ public function setDomain($domain) { $this->domain = $domain; } /** * @return string */ public function getDomain() { return $this->domain; } /** * The email address associated with the entity, if any. * * @param string $email */ public function setEmail($email) { $this->email = $email; } /** * @return string */ public function getEmail() { return $this->email; } /** * The entity holding the permission, in one of the following forms: - user- * userId - user-email - group-groupId - group-email - domain-domain - * project-team-projectId - allUsers - allAuthenticatedUsers Examples: - * The user liz@example.com would be user-liz@example.com. - The group * example@googlegroups.com would be group-example@googlegroups.com. - To * refer to all members of the Google Apps for Business domain example.com, * the entity would be domain-example.com. * * @param string $entity */ public function setEntity($entity) { $this->entity = $entity; } /** * @return string */ public function getEntity() { return $this->entity; } /** * The ID for the entity, if any. * * @param string $entityId */ public function setEntityId($entityId) { $this->entityId = $entityId; } /** * @return string */ public function getEntityId() { return $this->entityId; } /** * HTTP 1.1 Entity tag for the access-control entry. * * @param string $etag */ public function setEtag($etag) { $this->etag = $etag; } /** * @return string */ public function getEtag() { return $this->etag; } /** * The content generation of the object, if applied to an object. * * @param string $generation */ public function setGeneration($generation) { $this->generation = $generation; } /** * @return string */ public function getGeneration() { return $this->generation; } /** * The ID of the access-control entry. * * @param string $id */ public function setId($id) { $this->id = $id; } /** * @return string */ public function getId() { return $this->id; } /** * The kind of item this is. For object access control entries, this is always * storage#objectAccessControl. * * @param string $kind */ public function setKind($kind) { $this->kind = $kind; } /** * @return string */ public function getKind() { return $this->kind; } /** * The name of the object, if applied to an object. * * @param string $object */ public function setObject($object) { $this->object = $object; } /** * @return string */ public function getObject() { return $this->object; } /** * The project team associated with the entity, if any. * * @param ObjectAccessControlProjectTeam $projectTeam */ public function setProjectTeam(ObjectAccessControlProjectTeam $projectTeam) { $this->projectTeam = $projectTeam; } /** * @return ObjectAccessControlProjectTeam */ public function getProjectTeam() { return $this->projectTeam; } /** * The access permission for the entity. * * @param string $role */ public function setRole($role) { $this->role = $role; } /** * @return string */ public function getRole() { return $this->role; } /** * The link to this access-control entry. * * @param string $selfLink */ public function setSelfLink($selfLink) { $this->selfLink = $selfLink; } /** * @return string */ public function getSelfLink() { return $this->selfLink; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(ObjectAccessControl::class, 'Google_Service_Storage_ObjectAccessControl'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/ObjectAccessControlProjectTeam.php ================================================ projectNumber = $projectNumber; } /** * @return string */ public function getProjectNumber() { return $this->projectNumber; } /** * The team. * * @param string $team */ public function setTeam($team) { $this->team = $team; } /** * @return string */ public function getTeam() { return $this->team; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(ObjectAccessControlProjectTeam::class, 'Google_Service_Storage_ObjectAccessControlProjectTeam'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/ObjectAccessControls.php ================================================ items = $items; } /** * @return ObjectAccessControl[] */ public function getItems() { return $this->items; } /** * The kind of item this is. For lists of object access control entries, this * is always storage#objectAccessControls. * * @param string $kind */ public function setKind($kind) { $this->kind = $kind; } /** * @return string */ public function getKind() { return $this->kind; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(ObjectAccessControls::class, 'Google_Service_Storage_ObjectAccessControls'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/ObjectCustomContextPayload.php ================================================ createTime = $createTime; } /** * @return string */ public function getCreateTime() { return $this->createTime; } /** * The time at which the object context was last updated in RFC 3339 format. * * @param string $updateTime */ public function setUpdateTime($updateTime) { $this->updateTime = $updateTime; } /** * @return string */ public function getUpdateTime() { return $this->updateTime; } /** * The value of the object context. * * @param string $value */ public function setValue($value) { $this->value = $value; } /** * @return string */ public function getValue() { return $this->value; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(ObjectCustomContextPayload::class, 'Google_Service_Storage_ObjectCustomContextPayload'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/Objects.php ================================================ items = $items; } /** * @return StorageObject[] */ public function getItems() { return $this->items; } /** * The kind of item this is. For lists of objects, this is always * storage#objects. * * @param string $kind */ public function setKind($kind) { $this->kind = $kind; } /** * @return string */ public function getKind() { return $this->kind; } /** * The continuation token, used to page through large result sets. Provide * this value in a subsequent request to return the next page of results. * * @param string $nextPageToken */ public function setNextPageToken($nextPageToken) { $this->nextPageToken = $nextPageToken; } /** * @return string */ public function getNextPageToken() { return $this->nextPageToken; } /** * The list of prefixes of objects matching-but-not-listed up to and including * the requested delimiter. * * @param string[] $prefixes */ public function setPrefixes($prefixes) { $this->prefixes = $prefixes; } /** * @return string[] */ public function getPrefixes() { return $this->prefixes; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(Objects::class, 'Google_Service_Storage_Objects'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/Policy.php ================================================ bindings = $bindings; } /** * @return PolicyBindings[] */ public function getBindings() { return $this->bindings; } /** * HTTP 1.1 Entity tag for the policy. * * @param string $etag */ public function setEtag($etag) { $this->etag = $etag; } /** * @return string */ public function getEtag() { return $this->etag; } /** * The kind of item this is. For policies, this is always storage#policy. This * field is ignored on input. * * @param string $kind */ public function setKind($kind) { $this->kind = $kind; } /** * @return string */ public function getKind() { return $this->kind; } /** * The ID of the resource to which this policy belongs. Will be of the form * projects/_/buckets/bucket for buckets, * projects/_/buckets/bucket/objects/object for objects, and * projects/_/buckets/bucket/managedFolders/managedFolder. A specific * generation may be specified by appending #generationNumber to the end of * the object name, e.g. projects/_/buckets/my-bucket/objects/data.txt#17. The * current generation can be denoted with #0. This field is ignored on input. * * @param string $resourceId */ public function setResourceId($resourceId) { $this->resourceId = $resourceId; } /** * @return string */ public function getResourceId() { return $this->resourceId; } /** * The IAM policy format version. * * @param int $version */ public function setVersion($version) { $this->version = $version; } /** * @return int */ public function getVersion() { return $this->version; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(Policy::class, 'Google_Service_Storage_Policy'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/PolicyBindings.php ================================================ condition = $condition; } /** * @return Expr */ public function getCondition() { return $this->condition; } /** * A collection of identifiers for members who may assume the provided role. * Recognized identifiers are as follows: - allUsers - A special identifier * that represents anyone on the internet; with or without a Google account. * - allAuthenticatedUsers - A special identifier that represents anyone who * is authenticated with a Google account or a service account. - * user:emailid - An email address that represents a specific account. For * example, user:alice@gmail.com or user:joe@example.com. - * serviceAccount:emailid - An email address that represents a service * account. For example, serviceAccount:my-other- * app@appspot.gserviceaccount.com . - group:emailid - An email address that * represents a Google group. For example, group:admins@example.com. - * domain:domain - A Google Apps domain name that represents all the users of * that domain. For example, domain:google.com or domain:example.com. - * projectOwner:projectid - Owners of the given project. For example, * projectOwner:my-example-project - projectEditor:projectid - Editors of * the given project. For example, projectEditor:my-example-project - * projectViewer:projectid - Viewers of the given project. For example, * projectViewer:my-example-project * * @param string[] $members */ public function setMembers($members) { $this->members = $members; } /** * @return string[] */ public function getMembers() { return $this->members; } /** * The role to which members belong. Two types of roles are supported: new IAM * roles, which grant permissions that do not map directly to those provided * by ACLs, and legacy IAM roles, which do map directly to ACL permissions. * All roles are of the format roles/storage.specificRole. The new IAM roles * are: - roles/storage.admin - Full control of Google Cloud Storage * resources. - roles/storage.objectViewer - Read-Only access to Google * Cloud Storage objects. - roles/storage.objectCreator - Access to create * objects in Google Cloud Storage. - roles/storage.objectAdmin - Full * control of Google Cloud Storage objects. The legacy IAM roles are: - * roles/storage.legacyObjectReader - Read-only access to objects without * listing. Equivalent to an ACL entry on an object with the READER role. - * roles/storage.legacyObjectOwner - Read/write access to existing objects * without listing. Equivalent to an ACL entry on an object with the OWNER * role. - roles/storage.legacyBucketReader - Read access to buckets with * object listing. Equivalent to an ACL entry on a bucket with the READER * role. - roles/storage.legacyBucketWriter - Read access to buckets with * object listing/creation/deletion. Equivalent to an ACL entry on a bucket * with the WRITER role. - roles/storage.legacyBucketOwner - Read and write * access to existing buckets with object listing/creation/deletion. * Equivalent to an ACL entry on a bucket with the OWNER role. * * @param string $role */ public function setRole($role) { $this->role = $role; } /** * @return string */ public function getRole() { return $this->role; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(PolicyBindings::class, 'Google_Service_Storage_PolicyBindings'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/RelocateBucketRequest.php ================================================ destinationCustomPlacementConfig = $destinationCustomPlacementConfig; } /** * @return RelocateBucketRequestDestinationCustomPlacementConfig */ public function getDestinationCustomPlacementConfig() { return $this->destinationCustomPlacementConfig; } /** * The new location the bucket will be relocated to. * * @param string $destinationLocation */ public function setDestinationLocation($destinationLocation) { $this->destinationLocation = $destinationLocation; } /** * @return string */ public function getDestinationLocation() { return $this->destinationLocation; } /** * If true, validate the operation, but do not actually relocate the bucket. * * @param bool $validateOnly */ public function setValidateOnly($validateOnly) { $this->validateOnly = $validateOnly; } /** * @return bool */ public function getValidateOnly() { return $this->validateOnly; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(RelocateBucketRequest::class, 'Google_Service_Storage_RelocateBucketRequest'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/RelocateBucketRequestDestinationCustomPlacementConfig.php ================================================ dataLocations = $dataLocations; } /** * @return string[] */ public function getDataLocations() { return $this->dataLocations; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(RelocateBucketRequestDestinationCustomPlacementConfig::class, 'Google_Service_Storage_RelocateBucketRequestDestinationCustomPlacementConfig'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/Resource/AnywhereCache.php ================================================ * $storageService = new Google\Service\Storage(...); * $anywhereCache = $storageService->anywhereCache; * */ class AnywhereCache extends \Google\Service\Resource { /** * Disables an Anywhere Cache instance. (anywhereCache.disable) * * @param string $bucket Name of the parent bucket. * @param string $anywhereCacheId The ID of requested Anywhere Cache instance. * @param array $optParams Optional parameters. * @return AnywhereCacheModel */ public function disable($bucket, $anywhereCacheId, $optParams = []) { $params = ['bucket' => $bucket, 'anywhereCacheId' => $anywhereCacheId]; $params = array_merge($params, $optParams); return $this->call('disable', [$params], AnywhereCacheModel::class); } /** * Returns the metadata of an Anywhere Cache instance. (anywhereCache.get) * * @param string $bucket Name of the parent bucket. * @param string $anywhereCacheId The ID of requested Anywhere Cache instance. * @param array $optParams Optional parameters. * @return AnywhereCacheModel */ public function get($bucket, $anywhereCacheId, $optParams = []) { $params = ['bucket' => $bucket, 'anywhereCacheId' => $anywhereCacheId]; $params = array_merge($params, $optParams); return $this->call('get', [$params], AnywhereCacheModel::class); } /** * Creates an Anywhere Cache instance. (anywhereCache.insert) * * @param string $bucket Name of the parent bucket. * @param AnywhereCacheModel $postBody * @param array $optParams Optional parameters. * @return GoogleLongrunningOperation */ public function insert($bucket, AnywhereCacheModel $postBody, $optParams = []) { $params = ['bucket' => $bucket, 'postBody' => $postBody]; $params = array_merge($params, $optParams); return $this->call('insert', [$params], GoogleLongrunningOperation::class); } /** * Returns a list of Anywhere Cache instances of the bucket matching the * criteria. (anywhereCache.listAnywhereCache) * * @param string $bucket Name of the parent bucket. * @param array $optParams Optional parameters. * * @opt_param int pageSize Maximum number of items return in a single page of * responses. Maximum 1000. * @opt_param string pageToken A previously-returned page token representing * part of the larger set of results to view. * @return AnywhereCaches */ public function listAnywhereCache($bucket, $optParams = []) { $params = ['bucket' => $bucket]; $params = array_merge($params, $optParams); return $this->call('list', [$params], AnywhereCaches::class); } /** * Pauses an Anywhere Cache instance. (anywhereCache.pause) * * @param string $bucket Name of the parent bucket. * @param string $anywhereCacheId The ID of requested Anywhere Cache instance. * @param array $optParams Optional parameters. * @return AnywhereCacheModel */ public function pause($bucket, $anywhereCacheId, $optParams = []) { $params = ['bucket' => $bucket, 'anywhereCacheId' => $anywhereCacheId]; $params = array_merge($params, $optParams); return $this->call('pause', [$params], AnywhereCacheModel::class); } /** * Resumes a paused or disabled Anywhere Cache instance. (anywhereCache.resume) * * @param string $bucket Name of the parent bucket. * @param string $anywhereCacheId The ID of requested Anywhere Cache instance. * @param array $optParams Optional parameters. * @return AnywhereCacheModel */ public function resume($bucket, $anywhereCacheId, $optParams = []) { $params = ['bucket' => $bucket, 'anywhereCacheId' => $anywhereCacheId]; $params = array_merge($params, $optParams); return $this->call('resume', [$params], AnywhereCacheModel::class); } /** * Updates the config(ttl and admissionPolicy) of an Anywhere Cache instance. * (anywhereCache.update) * * @param string $bucket Name of the parent bucket. * @param string $anywhereCacheId The ID of requested Anywhere Cache instance. * @param AnywhereCacheModel $postBody * @param array $optParams Optional parameters. * @return GoogleLongrunningOperation */ public function update($bucket, $anywhereCacheId, AnywhereCacheModel $postBody, $optParams = []) { $params = ['bucket' => $bucket, 'anywhereCacheId' => $anywhereCacheId, 'postBody' => $postBody]; $params = array_merge($params, $optParams); return $this->call('update', [$params], GoogleLongrunningOperation::class); } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(AnywhereCache::class, 'Google_Service_Storage_Resource_AnywhereCache'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/Resource/AnywhereCaches.php ================================================ * $storageService = new Google\Service\Storage(...); * $anywhereCaches = $storageService->anywhereCaches; * */ class AnywhereCaches extends \Google\Service\Resource { /** * Disables an Anywhere Cache instance. (anywhereCaches.disable) * * @param string $bucket Name of the parent bucket. * @param string $anywhereCacheId The ID of requested Anywhere Cache instance. * @param array $optParams Optional parameters. * @return AnywhereCache * @throws \Google\Service\Exception */ public function disable($bucket, $anywhereCacheId, $optParams = []) { $params = ['bucket' => $bucket, 'anywhereCacheId' => $anywhereCacheId]; $params = array_merge($params, $optParams); return $this->call('disable', [$params], AnywhereCache::class); } /** * Returns the metadata of an Anywhere Cache instance. (anywhereCaches.get) * * @param string $bucket Name of the parent bucket. * @param string $anywhereCacheId The ID of requested Anywhere Cache instance. * @param array $optParams Optional parameters. * @return AnywhereCache * @throws \Google\Service\Exception */ public function get($bucket, $anywhereCacheId, $optParams = []) { $params = ['bucket' => $bucket, 'anywhereCacheId' => $anywhereCacheId]; $params = array_merge($params, $optParams); return $this->call('get', [$params], AnywhereCache::class); } /** * Creates an Anywhere Cache instance. (anywhereCaches.insert) * * @param string $bucket Name of the parent bucket. * @param AnywhereCache $postBody * @param array $optParams Optional parameters. * @return GoogleLongrunningOperation * @throws \Google\Service\Exception */ public function insert($bucket, AnywhereCache $postBody, $optParams = []) { $params = ['bucket' => $bucket, 'postBody' => $postBody]; $params = array_merge($params, $optParams); return $this->call('insert', [$params], GoogleLongrunningOperation::class); } /** * Returns a list of Anywhere Cache instances of the bucket matching the * criteria. (anywhereCaches.listAnywhereCaches) * * @param string $bucket Name of the parent bucket. * @param array $optParams Optional parameters. * * @opt_param int pageSize Maximum number of items to return in a single page of * responses. Maximum 1000. * @opt_param string pageToken A previously-returned page token representing * part of the larger set of results to view. * @return AnywhereCachesModel * @throws \Google\Service\Exception */ public function listAnywhereCaches($bucket, $optParams = []) { $params = ['bucket' => $bucket]; $params = array_merge($params, $optParams); return $this->call('list', [$params], AnywhereCachesModel::class); } /** * Pauses an Anywhere Cache instance. (anywhereCaches.pause) * * @param string $bucket Name of the parent bucket. * @param string $anywhereCacheId The ID of requested Anywhere Cache instance. * @param array $optParams Optional parameters. * @return AnywhereCache * @throws \Google\Service\Exception */ public function pause($bucket, $anywhereCacheId, $optParams = []) { $params = ['bucket' => $bucket, 'anywhereCacheId' => $anywhereCacheId]; $params = array_merge($params, $optParams); return $this->call('pause', [$params], AnywhereCache::class); } /** * Resumes a paused or disabled Anywhere Cache instance. (anywhereCaches.resume) * * @param string $bucket Name of the parent bucket. * @param string $anywhereCacheId The ID of requested Anywhere Cache instance. * @param array $optParams Optional parameters. * @return AnywhereCache * @throws \Google\Service\Exception */ public function resume($bucket, $anywhereCacheId, $optParams = []) { $params = ['bucket' => $bucket, 'anywhereCacheId' => $anywhereCacheId]; $params = array_merge($params, $optParams); return $this->call('resume', [$params], AnywhereCache::class); } /** * Updates the config(ttl and admissionPolicy) of an Anywhere Cache instance. * (anywhereCaches.update) * * @param string $bucket Name of the parent bucket. * @param string $anywhereCacheId The ID of requested Anywhere Cache instance. * @param AnywhereCache $postBody * @param array $optParams Optional parameters. * @return GoogleLongrunningOperation * @throws \Google\Service\Exception */ public function update($bucket, $anywhereCacheId, AnywhereCache $postBody, $optParams = []) { $params = ['bucket' => $bucket, 'anywhereCacheId' => $anywhereCacheId, 'postBody' => $postBody]; $params = array_merge($params, $optParams); return $this->call('update', [$params], GoogleLongrunningOperation::class); } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(AnywhereCaches::class, 'Google_Service_Storage_Resource_AnywhereCaches'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/Resource/BucketAccessControls.php ================================================ * $storageService = new Google\Service\Storage(...); * $bucketAccessControls = $storageService->bucketAccessControls; * */ class BucketAccessControls extends \Google\Service\Resource { /** * Permanently deletes the ACL entry for the specified entity on the specified * bucket. (bucketAccessControls.delete) * * @param string $bucket Name of a bucket. * @param string $entity The entity holding the permission. Can be user-userId, * user-emailAddress, group-groupId, group-emailAddress, allUsers, or * allAuthenticatedUsers. * @param array $optParams Optional parameters. * * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @throws \Google\Service\Exception */ public function delete($bucket, $entity, $optParams = []) { $params = ['bucket' => $bucket, 'entity' => $entity]; $params = array_merge($params, $optParams); return $this->call('delete', [$params]); } /** * Returns the ACL entry for the specified entity on the specified bucket. * (bucketAccessControls.get) * * @param string $bucket Name of a bucket. * @param string $entity The entity holding the permission. Can be user-userId, * user-emailAddress, group-groupId, group-emailAddress, allUsers, or * allAuthenticatedUsers. * @param array $optParams Optional parameters. * * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @return BucketAccessControl * @throws \Google\Service\Exception */ public function get($bucket, $entity, $optParams = []) { $params = ['bucket' => $bucket, 'entity' => $entity]; $params = array_merge($params, $optParams); return $this->call('get', [$params], BucketAccessControl::class); } /** * Creates a new ACL entry on the specified bucket. * (bucketAccessControls.insert) * * @param string $bucket Name of a bucket. * @param BucketAccessControl $postBody * @param array $optParams Optional parameters. * * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @return BucketAccessControl * @throws \Google\Service\Exception */ public function insert($bucket, BucketAccessControl $postBody, $optParams = []) { $params = ['bucket' => $bucket, 'postBody' => $postBody]; $params = array_merge($params, $optParams); return $this->call('insert', [$params], BucketAccessControl::class); } /** * Retrieves ACL entries on the specified bucket. * (bucketAccessControls.listBucketAccessControls) * * @param string $bucket Name of a bucket. * @param array $optParams Optional parameters. * * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @return BucketAccessControlsModel * @throws \Google\Service\Exception */ public function listBucketAccessControls($bucket, $optParams = []) { $params = ['bucket' => $bucket]; $params = array_merge($params, $optParams); return $this->call('list', [$params], BucketAccessControlsModel::class); } /** * Patches an ACL entry on the specified bucket. (bucketAccessControls.patch) * * @param string $bucket Name of a bucket. * @param string $entity The entity holding the permission. Can be user-userId, * user-emailAddress, group-groupId, group-emailAddress, allUsers, or * allAuthenticatedUsers. * @param BucketAccessControl $postBody * @param array $optParams Optional parameters. * * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @return BucketAccessControl * @throws \Google\Service\Exception */ public function patch($bucket, $entity, BucketAccessControl $postBody, $optParams = []) { $params = ['bucket' => $bucket, 'entity' => $entity, 'postBody' => $postBody]; $params = array_merge($params, $optParams); return $this->call('patch', [$params], BucketAccessControl::class); } /** * Updates an ACL entry on the specified bucket. (bucketAccessControls.update) * * @param string $bucket Name of a bucket. * @param string $entity The entity holding the permission. Can be user-userId, * user-emailAddress, group-groupId, group-emailAddress, allUsers, or * allAuthenticatedUsers. * @param BucketAccessControl $postBody * @param array $optParams Optional parameters. * * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @return BucketAccessControl * @throws \Google\Service\Exception */ public function update($bucket, $entity, BucketAccessControl $postBody, $optParams = []) { $params = ['bucket' => $bucket, 'entity' => $entity, 'postBody' => $postBody]; $params = array_merge($params, $optParams); return $this->call('update', [$params], BucketAccessControl::class); } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(BucketAccessControls::class, 'Google_Service_Storage_Resource_BucketAccessControls'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/Resource/Buckets.php ================================================ * $storageService = new Google\Service\Storage(...); * $buckets = $storageService->buckets; * */ class Buckets extends \Google\Service\Resource { /** * Deletes an empty bucket. Deletions are permanent unless soft delete is * enabled on the bucket. (buckets.delete) * * @param string $bucket Name of a bucket. * @param array $optParams Optional parameters. * * @opt_param string ifMetagenerationMatch If set, only deletes the bucket if * its metageneration matches this value. * @opt_param string ifMetagenerationNotMatch If set, only deletes the bucket if * its metageneration does not match this value. * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @throws \Google\Service\Exception */ public function delete($bucket, $optParams = []) { $params = ['bucket' => $bucket]; $params = array_merge($params, $optParams); return $this->call('delete', [$params]); } /** * Returns metadata for the specified bucket. (buckets.get) * * @param string $bucket Name of a bucket. * @param array $optParams Optional parameters. * * @opt_param string generation If present, specifies the generation of the * bucket. This is required if softDeleted is true. * @opt_param string ifMetagenerationMatch Makes the return of the bucket * metadata conditional on whether the bucket's current metageneration matches * the given value. * @opt_param string ifMetagenerationNotMatch Makes the return of the bucket * metadata conditional on whether the bucket's current metageneration does not * match the given value. * @opt_param string projection Set of properties to return. Defaults to noAcl. * @opt_param bool softDeleted If true, return the soft-deleted version of this * bucket. The default is false. For more information, see [Soft * Delete](https://cloud.google.com/storage/docs/soft-delete). * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @return Bucket * @throws \Google\Service\Exception */ public function get($bucket, $optParams = []) { $params = ['bucket' => $bucket]; $params = array_merge($params, $optParams); return $this->call('get', [$params], Bucket::class); } /** * Returns an IAM policy for the specified bucket. (buckets.getIamPolicy) * * @param string $bucket Name of a bucket. * @param array $optParams Optional parameters. * * @opt_param int optionsRequestedPolicyVersion The IAM policy format version to * be returned. If the optionsRequestedPolicyVersion is for an older version * that doesn't support part of the requested IAM policy, the request fails. * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @return Policy * @throws \Google\Service\Exception */ public function getIamPolicy($bucket, $optParams = []) { $params = ['bucket' => $bucket]; $params = array_merge($params, $optParams); return $this->call('getIamPolicy', [$params], Policy::class); } /** * Returns the storage layout configuration for the specified bucket. Note that * this operation requires storage.objects.list permission. * (buckets.getStorageLayout) * * @param string $bucket Name of a bucket. * @param array $optParams Optional parameters. * * @opt_param string prefix An optional prefix used for permission check. It is * useful when the caller only has storage.objects.list permission under a * specific prefix. * @return BucketStorageLayout * @throws \Google\Service\Exception */ public function getStorageLayout($bucket, $optParams = []) { $params = ['bucket' => $bucket]; $params = array_merge($params, $optParams); return $this->call('getStorageLayout', [$params], BucketStorageLayout::class); } /** * Creates a new bucket. (buckets.insert) * * @param string $project A valid API project identifier. * @param Bucket $postBody * @param array $optParams Optional parameters. * * @opt_param bool enableObjectRetention When set to true, object retention is * enabled for this bucket. * @opt_param string predefinedAcl Apply a predefined set of access controls to * this bucket. * @opt_param string predefinedDefaultObjectAcl Apply a predefined set of * default object access controls to this bucket. * @opt_param string projection Set of properties to return. Defaults to noAcl, * unless the bucket resource specifies acl or defaultObjectAcl properties, when * it defaults to full. * @opt_param string userProject The project to be billed for this request. * @return Bucket * @throws \Google\Service\Exception */ public function insert($project, Bucket $postBody, $optParams = []) { $params = ['project' => $project, 'postBody' => $postBody]; $params = array_merge($params, $optParams); return $this->call('insert', [$params], Bucket::class); } /** * Retrieves a list of buckets for a given project. (buckets.listBuckets) * * @param string $project A valid API project identifier. * @param array $optParams Optional parameters. * * @opt_param string maxResults Maximum number of buckets to return in a single * response. The service will use this parameter or 1,000 items, whichever is * smaller. * @opt_param string pageToken A previously-returned page token representing * part of the larger set of results to view. * @opt_param string prefix Filter results to buckets whose names begin with * this prefix. * @opt_param string projection Set of properties to return. Defaults to noAcl. * @opt_param bool returnPartialSuccess If true, return a list of bucket * resource names for buckets that are in unreachable locations. * @opt_param bool softDeleted If true, only soft-deleted bucket versions will * be returned. The default is false. For more information, see [Soft * Delete](https://cloud.google.com/storage/docs/soft-delete). * @opt_param string userProject The project to be billed for this request. * @return BucketsModel * @throws \Google\Service\Exception */ public function listBuckets($project, $optParams = []) { $params = ['project' => $project]; $params = array_merge($params, $optParams); return $this->call('list', [$params], BucketsModel::class); } /** * Locks retention policy on a bucket. (buckets.lockRetentionPolicy) * * @param string $bucket Name of a bucket. * @param string $ifMetagenerationMatch Makes the operation conditional on * whether bucket's current metageneration matches the given value. * @param array $optParams Optional parameters. * * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @return Bucket * @throws \Google\Service\Exception */ public function lockRetentionPolicy($bucket, $ifMetagenerationMatch, $optParams = []) { $params = ['bucket' => $bucket, 'ifMetagenerationMatch' => $ifMetagenerationMatch]; $params = array_merge($params, $optParams); return $this->call('lockRetentionPolicy', [$params], Bucket::class); } /** * Patches a bucket. Changes to the bucket will be readable immediately after * writing, but configuration changes may take time to propagate. * (buckets.patch) * * @param string $bucket Name of a bucket. * @param Bucket $postBody * @param array $optParams Optional parameters. * * @opt_param string ifMetagenerationMatch Makes the return of the bucket * metadata conditional on whether the bucket's current metageneration matches * the given value. * @opt_param string ifMetagenerationNotMatch Makes the return of the bucket * metadata conditional on whether the bucket's current metageneration does not * match the given value. * @opt_param string predefinedAcl Apply a predefined set of access controls to * this bucket. * @opt_param string predefinedDefaultObjectAcl Apply a predefined set of * default object access controls to this bucket. * @opt_param string projection Set of properties to return. Defaults to full. * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @return Bucket * @throws \Google\Service\Exception */ public function patch($bucket, Bucket $postBody, $optParams = []) { $params = ['bucket' => $bucket, 'postBody' => $postBody]; $params = array_merge($params, $optParams); return $this->call('patch', [$params], Bucket::class); } /** * Initiates a long-running Relocate Bucket operation on the specified bucket. * (buckets.relocate) * * @param string $bucket Name of the bucket to be moved. * @param RelocateBucketRequest $postBody * @param array $optParams Optional parameters. * @return GoogleLongrunningOperation * @throws \Google\Service\Exception */ public function relocate($bucket, RelocateBucketRequest $postBody, $optParams = []) { $params = ['bucket' => $bucket, 'postBody' => $postBody]; $params = array_merge($params, $optParams); return $this->call('relocate', [$params], GoogleLongrunningOperation::class); } /** * Restores a soft-deleted bucket. (buckets.restore) * * @param string $bucket Name of a bucket. * @param string $generation Generation of a bucket. * @param array $optParams Optional parameters. * * @opt_param string projection Set of properties to return. Defaults to full. * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @return Bucket * @throws \Google\Service\Exception */ public function restore($bucket, $generation, $optParams = []) { $params = ['bucket' => $bucket, 'generation' => $generation]; $params = array_merge($params, $optParams); return $this->call('restore', [$params], Bucket::class); } /** * Updates an IAM policy for the specified bucket. (buckets.setIamPolicy) * * @param string $bucket Name of a bucket. * @param Policy $postBody * @param array $optParams Optional parameters. * * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @return Policy * @throws \Google\Service\Exception */ public function setIamPolicy($bucket, Policy $postBody, $optParams = []) { $params = ['bucket' => $bucket, 'postBody' => $postBody]; $params = array_merge($params, $optParams); return $this->call('setIamPolicy', [$params], Policy::class); } /** * Tests a set of permissions on the given bucket to see which, if any, are held * by the caller. (buckets.testIamPermissions) * * @param string $bucket Name of a bucket. * @param string|array $permissions Permissions to test. * @param array $optParams Optional parameters. * * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @return TestIamPermissionsResponse * @throws \Google\Service\Exception */ public function testIamPermissions($bucket, $permissions, $optParams = []) { $params = ['bucket' => $bucket, 'permissions' => $permissions]; $params = array_merge($params, $optParams); return $this->call('testIamPermissions', [$params], TestIamPermissionsResponse::class); } /** * Updates a bucket. Changes to the bucket will be readable immediately after * writing, but configuration changes may take time to propagate. * (buckets.update) * * @param string $bucket Name of a bucket. * @param Bucket $postBody * @param array $optParams Optional parameters. * * @opt_param string ifMetagenerationMatch Makes the return of the bucket * metadata conditional on whether the bucket's current metageneration matches * the given value. * @opt_param string ifMetagenerationNotMatch Makes the return of the bucket * metadata conditional on whether the bucket's current metageneration does not * match the given value. * @opt_param string predefinedAcl Apply a predefined set of access controls to * this bucket. * @opt_param string predefinedDefaultObjectAcl Apply a predefined set of * default object access controls to this bucket. * @opt_param string projection Set of properties to return. Defaults to full. * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @return Bucket * @throws \Google\Service\Exception */ public function update($bucket, Bucket $postBody, $optParams = []) { $params = ['bucket' => $bucket, 'postBody' => $postBody]; $params = array_merge($params, $optParams); return $this->call('update', [$params], Bucket::class); } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(Buckets::class, 'Google_Service_Storage_Resource_Buckets'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/Resource/Channels.php ================================================ * $storageService = new Google\Service\Storage(...); * $channels = $storageService->channels; * */ class Channels extends \Google\Service\Resource { /** * Stop watching resources through this channel (channels.stop) * * @param Channel $postBody * @param array $optParams Optional parameters. * @throws \Google\Service\Exception */ public function stop(Channel $postBody, $optParams = []) { $params = ['postBody' => $postBody]; $params = array_merge($params, $optParams); return $this->call('stop', [$params]); } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(Channels::class, 'Google_Service_Storage_Resource_Channels'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/Resource/DefaultObjectAccessControls.php ================================================ * $storageService = new Google\Service\Storage(...); * $defaultObjectAccessControls = $storageService->defaultObjectAccessControls; * */ class DefaultObjectAccessControls extends \Google\Service\Resource { /** * Permanently deletes the default object ACL entry for the specified entity on * the specified bucket. (defaultObjectAccessControls.delete) * * @param string $bucket Name of a bucket. * @param string $entity The entity holding the permission. Can be user-userId, * user-emailAddress, group-groupId, group-emailAddress, allUsers, or * allAuthenticatedUsers. * @param array $optParams Optional parameters. * * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @throws \Google\Service\Exception */ public function delete($bucket, $entity, $optParams = []) { $params = ['bucket' => $bucket, 'entity' => $entity]; $params = array_merge($params, $optParams); return $this->call('delete', [$params]); } /** * Returns the default object ACL entry for the specified entity on the * specified bucket. (defaultObjectAccessControls.get) * * @param string $bucket Name of a bucket. * @param string $entity The entity holding the permission. Can be user-userId, * user-emailAddress, group-groupId, group-emailAddress, allUsers, or * allAuthenticatedUsers. * @param array $optParams Optional parameters. * * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @return ObjectAccessControl * @throws \Google\Service\Exception */ public function get($bucket, $entity, $optParams = []) { $params = ['bucket' => $bucket, 'entity' => $entity]; $params = array_merge($params, $optParams); return $this->call('get', [$params], ObjectAccessControl::class); } /** * Creates a new default object ACL entry on the specified bucket. * (defaultObjectAccessControls.insert) * * @param string $bucket Name of a bucket. * @param ObjectAccessControl $postBody * @param array $optParams Optional parameters. * * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @return ObjectAccessControl * @throws \Google\Service\Exception */ public function insert($bucket, ObjectAccessControl $postBody, $optParams = []) { $params = ['bucket' => $bucket, 'postBody' => $postBody]; $params = array_merge($params, $optParams); return $this->call('insert', [$params], ObjectAccessControl::class); } /** * Retrieves default object ACL entries on the specified bucket. * (defaultObjectAccessControls.listDefaultObjectAccessControls) * * @param string $bucket Name of a bucket. * @param array $optParams Optional parameters. * * @opt_param string ifMetagenerationMatch If present, only return default ACL * listing if the bucket's current metageneration matches this value. * @opt_param string ifMetagenerationNotMatch If present, only return default * ACL listing if the bucket's current metageneration does not match the given * value. * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @return ObjectAccessControlsModel * @throws \Google\Service\Exception */ public function listDefaultObjectAccessControls($bucket, $optParams = []) { $params = ['bucket' => $bucket]; $params = array_merge($params, $optParams); return $this->call('list', [$params], ObjectAccessControlsModel::class); } /** * Patches a default object ACL entry on the specified bucket. * (defaultObjectAccessControls.patch) * * @param string $bucket Name of a bucket. * @param string $entity The entity holding the permission. Can be user-userId, * user-emailAddress, group-groupId, group-emailAddress, allUsers, or * allAuthenticatedUsers. * @param ObjectAccessControl $postBody * @param array $optParams Optional parameters. * * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @return ObjectAccessControl * @throws \Google\Service\Exception */ public function patch($bucket, $entity, ObjectAccessControl $postBody, $optParams = []) { $params = ['bucket' => $bucket, 'entity' => $entity, 'postBody' => $postBody]; $params = array_merge($params, $optParams); return $this->call('patch', [$params], ObjectAccessControl::class); } /** * Updates a default object ACL entry on the specified bucket. * (defaultObjectAccessControls.update) * * @param string $bucket Name of a bucket. * @param string $entity The entity holding the permission. Can be user-userId, * user-emailAddress, group-groupId, group-emailAddress, allUsers, or * allAuthenticatedUsers. * @param ObjectAccessControl $postBody * @param array $optParams Optional parameters. * * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @return ObjectAccessControl * @throws \Google\Service\Exception */ public function update($bucket, $entity, ObjectAccessControl $postBody, $optParams = []) { $params = ['bucket' => $bucket, 'entity' => $entity, 'postBody' => $postBody]; $params = array_merge($params, $optParams); return $this->call('update', [$params], ObjectAccessControl::class); } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(DefaultObjectAccessControls::class, 'Google_Service_Storage_Resource_DefaultObjectAccessControls'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/Resource/Folders.php ================================================ * $storageService = new Google\Service\Storage(...); * $folders = $storageService->folders; * */ class Folders extends \Google\Service\Resource { /** * Permanently deletes a folder. Only applicable to buckets with hierarchical * namespace enabled. (folders.delete) * * @param string $bucket Name of the bucket in which the folder resides. * @param string $folder Name of a folder. * @param array $optParams Optional parameters. * * @opt_param string ifMetagenerationMatch If set, only deletes the folder if * its metageneration matches this value. * @opt_param string ifMetagenerationNotMatch If set, only deletes the folder if * its metageneration does not match this value. * @throws \Google\Service\Exception */ public function delete($bucket, $folder, $optParams = []) { $params = ['bucket' => $bucket, 'folder' => $folder]; $params = array_merge($params, $optParams); return $this->call('delete', [$params]); } /** * Returns metadata for the specified folder. Only applicable to buckets with * hierarchical namespace enabled. (folders.get) * * @param string $bucket Name of the bucket in which the folder resides. * @param string $folder Name of a folder. * @param array $optParams Optional parameters. * * @opt_param string ifMetagenerationMatch Makes the return of the folder * metadata conditional on whether the folder's current metageneration matches * the given value. * @opt_param string ifMetagenerationNotMatch Makes the return of the folder * metadata conditional on whether the folder's current metageneration does not * match the given value. * @return Folder * @throws \Google\Service\Exception */ public function get($bucket, $folder, $optParams = []) { $params = ['bucket' => $bucket, 'folder' => $folder]; $params = array_merge($params, $optParams); return $this->call('get', [$params], Folder::class); } /** * Creates a new folder. Only applicable to buckets with hierarchical namespace * enabled. (folders.insert) * * @param string $bucket Name of the bucket in which the folder resides. * @param Folder $postBody * @param array $optParams Optional parameters. * * @opt_param bool recursive If true, any parent folder which doesn't exist will * be created automatically. * @return Folder * @throws \Google\Service\Exception */ public function insert($bucket, Folder $postBody, $optParams = []) { $params = ['bucket' => $bucket, 'postBody' => $postBody]; $params = array_merge($params, $optParams); return $this->call('insert', [$params], Folder::class); } /** * Retrieves a list of folders matching the criteria. Only applicable to buckets * with hierarchical namespace enabled. (folders.listFolders) * * @param string $bucket Name of the bucket in which to look for folders. * @param array $optParams Optional parameters. * * @opt_param string delimiter Returns results in a directory-like mode. The * only supported value is '/'. If set, items will only contain folders that * either exactly match the prefix, or are one level below the prefix. * @opt_param string endOffset Filter results to folders whose names are * lexicographically before endOffset. If startOffset is also set, the folders * listed will have names between startOffset (inclusive) and endOffset * (exclusive). * @opt_param int pageSize Maximum number of items to return in a single page of * responses. * @opt_param string pageToken A previously-returned page token representing * part of the larger set of results to view. * @opt_param string prefix Filter results to folders whose paths begin with * this prefix. If set, the value must either be an empty string or end with a * '/'. * @opt_param string startOffset Filter results to folders whose names are * lexicographically equal to or after startOffset. If endOffset is also set, * the folders listed will have names between startOffset (inclusive) and * endOffset (exclusive). * @return FoldersModel * @throws \Google\Service\Exception */ public function listFolders($bucket, $optParams = []) { $params = ['bucket' => $bucket]; $params = array_merge($params, $optParams); return $this->call('list', [$params], FoldersModel::class); } /** * Renames a source folder to a destination folder. Only applicable to buckets * with hierarchical namespace enabled. (folders.rename) * * @param string $bucket Name of the bucket in which the folders are in. * @param string $sourceFolder Name of the source folder. * @param string $destinationFolder Name of the destination folder. * @param array $optParams Optional parameters. * * @opt_param string ifSourceMetagenerationMatch Makes the operation conditional * on whether the source object's current metageneration matches the given * value. * @opt_param string ifSourceMetagenerationNotMatch Makes the operation * conditional on whether the source object's current metageneration does not * match the given value. * @return GoogleLongrunningOperation * @throws \Google\Service\Exception */ public function rename($bucket, $sourceFolder, $destinationFolder, $optParams = []) { $params = ['bucket' => $bucket, 'sourceFolder' => $sourceFolder, 'destinationFolder' => $destinationFolder]; $params = array_merge($params, $optParams); return $this->call('rename', [$params], GoogleLongrunningOperation::class); } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(Folders::class, 'Google_Service_Storage_Resource_Folders'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/Resource/ManagedFolders.php ================================================ * $storageService = new Google\Service\Storage(...); * $managedFolders = $storageService->managedFolders; * */ class ManagedFolders extends \Google\Service\Resource { /** * Permanently deletes a managed folder. (managedFolders.delete) * * @param string $bucket Name of the bucket containing the managed folder. * @param string $managedFolder The managed folder name/path. * @param array $optParams Optional parameters. * * @opt_param bool allowNonEmpty Allows the deletion of a managed folder even if * it is not empty. A managed folder is empty if there are no objects or managed * folders that it applies to. Callers must have * storage.managedFolders.setIamPolicy permission. * @opt_param string ifMetagenerationMatch If set, only deletes the managed * folder if its metageneration matches this value. * @opt_param string ifMetagenerationNotMatch If set, only deletes the managed * folder if its metageneration does not match this value. * @throws \Google\Service\Exception */ public function delete($bucket, $managedFolder, $optParams = []) { $params = ['bucket' => $bucket, 'managedFolder' => $managedFolder]; $params = array_merge($params, $optParams); return $this->call('delete', [$params]); } /** * Returns metadata of the specified managed folder. (managedFolders.get) * * @param string $bucket Name of the bucket containing the managed folder. * @param string $managedFolder The managed folder name/path. * @param array $optParams Optional parameters. * * @opt_param string ifMetagenerationMatch Makes the return of the managed * folder metadata conditional on whether the managed folder's current * metageneration matches the given value. * @opt_param string ifMetagenerationNotMatch Makes the return of the managed * folder metadata conditional on whether the managed folder's current * metageneration does not match the given value. * @return ManagedFolder * @throws \Google\Service\Exception */ public function get($bucket, $managedFolder, $optParams = []) { $params = ['bucket' => $bucket, 'managedFolder' => $managedFolder]; $params = array_merge($params, $optParams); return $this->call('get', [$params], ManagedFolder::class); } /** * Returns an IAM policy for the specified managed folder. * (managedFolders.getIamPolicy) * * @param string $bucket Name of the bucket containing the managed folder. * @param string $managedFolder The managed folder name/path. * @param array $optParams Optional parameters. * * @opt_param int optionsRequestedPolicyVersion The IAM policy format version to * be returned. If the optionsRequestedPolicyVersion is for an older version * that doesn't support part of the requested IAM policy, the request fails. * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @return Policy * @throws \Google\Service\Exception */ public function getIamPolicy($bucket, $managedFolder, $optParams = []) { $params = ['bucket' => $bucket, 'managedFolder' => $managedFolder]; $params = array_merge($params, $optParams); return $this->call('getIamPolicy', [$params], Policy::class); } /** * Creates a new managed folder. (managedFolders.insert) * * @param string $bucket Name of the bucket containing the managed folder. * @param ManagedFolder $postBody * @param array $optParams Optional parameters. * @return ManagedFolder * @throws \Google\Service\Exception */ public function insert($bucket, ManagedFolder $postBody, $optParams = []) { $params = ['bucket' => $bucket, 'postBody' => $postBody]; $params = array_merge($params, $optParams); return $this->call('insert', [$params], ManagedFolder::class); } /** * Lists managed folders in the given bucket. * (managedFolders.listManagedFolders) * * @param string $bucket Name of the bucket containing the managed folder. * @param array $optParams Optional parameters. * * @opt_param int pageSize Maximum number of items to return in a single page of * responses. * @opt_param string pageToken A previously-returned page token representing * part of the larger set of results to view. * @opt_param string prefix The managed folder name/path prefix to filter the * output list of results. * @return ManagedFoldersModel * @throws \Google\Service\Exception */ public function listManagedFolders($bucket, $optParams = []) { $params = ['bucket' => $bucket]; $params = array_merge($params, $optParams); return $this->call('list', [$params], ManagedFoldersModel::class); } /** * Updates an IAM policy for the specified managed folder. * (managedFolders.setIamPolicy) * * @param string $bucket Name of the bucket containing the managed folder. * @param string $managedFolder The managed folder name/path. * @param Policy $postBody * @param array $optParams Optional parameters. * * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @return Policy * @throws \Google\Service\Exception */ public function setIamPolicy($bucket, $managedFolder, Policy $postBody, $optParams = []) { $params = ['bucket' => $bucket, 'managedFolder' => $managedFolder, 'postBody' => $postBody]; $params = array_merge($params, $optParams); return $this->call('setIamPolicy', [$params], Policy::class); } /** * Tests a set of permissions on the given managed folder to see which, if any, * are held by the caller. (managedFolders.testIamPermissions) * * @param string $bucket Name of the bucket containing the managed folder. * @param string $managedFolder The managed folder name/path. * @param string|array $permissions Permissions to test. * @param array $optParams Optional parameters. * * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @return TestIamPermissionsResponse * @throws \Google\Service\Exception */ public function testIamPermissions($bucket, $managedFolder, $permissions, $optParams = []) { $params = ['bucket' => $bucket, 'managedFolder' => $managedFolder, 'permissions' => $permissions]; $params = array_merge($params, $optParams); return $this->call('testIamPermissions', [$params], TestIamPermissionsResponse::class); } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(ManagedFolders::class, 'Google_Service_Storage_Resource_ManagedFolders'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/Resource/Notifications.php ================================================ * $storageService = new Google\Service\Storage(...); * $notifications = $storageService->notifications; * */ class Notifications extends \Google\Service\Resource { /** * Permanently deletes a notification subscription. (notifications.delete) * * @param string $bucket The parent bucket of the notification. * @param string $notification ID of the notification to delete. * @param array $optParams Optional parameters. * * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @throws \Google\Service\Exception */ public function delete($bucket, $notification, $optParams = []) { $params = ['bucket' => $bucket, 'notification' => $notification]; $params = array_merge($params, $optParams); return $this->call('delete', [$params]); } /** * View a notification configuration. (notifications.get) * * @param string $bucket The parent bucket of the notification. * @param string $notification Notification ID * @param array $optParams Optional parameters. * * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @return Notification * @throws \Google\Service\Exception */ public function get($bucket, $notification, $optParams = []) { $params = ['bucket' => $bucket, 'notification' => $notification]; $params = array_merge($params, $optParams); return $this->call('get', [$params], Notification::class); } /** * Creates a notification subscription for a given bucket. * (notifications.insert) * * @param string $bucket The parent bucket of the notification. * @param Notification $postBody * @param array $optParams Optional parameters. * * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @return Notification * @throws \Google\Service\Exception */ public function insert($bucket, Notification $postBody, $optParams = []) { $params = ['bucket' => $bucket, 'postBody' => $postBody]; $params = array_merge($params, $optParams); return $this->call('insert', [$params], Notification::class); } /** * Retrieves a list of notification subscriptions for a given bucket. * (notifications.listNotifications) * * @param string $bucket Name of a Google Cloud Storage bucket. * @param array $optParams Optional parameters. * * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @return NotificationsModel * @throws \Google\Service\Exception */ public function listNotifications($bucket, $optParams = []) { $params = ['bucket' => $bucket]; $params = array_merge($params, $optParams); return $this->call('list', [$params], NotificationsModel::class); } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(Notifications::class, 'Google_Service_Storage_Resource_Notifications'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/Resource/ObjectAccessControls.php ================================================ * $storageService = new Google\Service\Storage(...); * $objectAccessControls = $storageService->objectAccessControls; * */ class ObjectAccessControls extends \Google\Service\Resource { /** * Permanently deletes the ACL entry for the specified entity on the specified * object. (objectAccessControls.delete) * * @param string $bucket Name of a bucket. * @param string $object Name of the object. For information about how to URL * encode object names to be path safe, see [Encoding URI Path * Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding). * @param string $entity The entity holding the permission. Can be user-userId, * user-emailAddress, group-groupId, group-emailAddress, allUsers, or * allAuthenticatedUsers. * @param array $optParams Optional parameters. * * @opt_param string generation If present, selects a specific revision of this * object (as opposed to the latest version, the default). * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @throws \Google\Service\Exception */ public function delete($bucket, $object, $entity, $optParams = []) { $params = ['bucket' => $bucket, 'object' => $object, 'entity' => $entity]; $params = array_merge($params, $optParams); return $this->call('delete', [$params]); } /** * Returns the ACL entry for the specified entity on the specified object. * (objectAccessControls.get) * * @param string $bucket Name of a bucket. * @param string $object Name of the object. For information about how to URL * encode object names to be path safe, see [Encoding URI Path * Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding). * @param string $entity The entity holding the permission. Can be user-userId, * user-emailAddress, group-groupId, group-emailAddress, allUsers, or * allAuthenticatedUsers. * @param array $optParams Optional parameters. * * @opt_param string generation If present, selects a specific revision of this * object (as opposed to the latest version, the default). * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @return ObjectAccessControl * @throws \Google\Service\Exception */ public function get($bucket, $object, $entity, $optParams = []) { $params = ['bucket' => $bucket, 'object' => $object, 'entity' => $entity]; $params = array_merge($params, $optParams); return $this->call('get', [$params], ObjectAccessControl::class); } /** * Creates a new ACL entry on the specified object. * (objectAccessControls.insert) * * @param string $bucket Name of a bucket. * @param string $object Name of the object. For information about how to URL * encode object names to be path safe, see [Encoding URI Path * Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding). * @param ObjectAccessControl $postBody * @param array $optParams Optional parameters. * * @opt_param string generation If present, selects a specific revision of this * object (as opposed to the latest version, the default). * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @return ObjectAccessControl * @throws \Google\Service\Exception */ public function insert($bucket, $object, ObjectAccessControl $postBody, $optParams = []) { $params = ['bucket' => $bucket, 'object' => $object, 'postBody' => $postBody]; $params = array_merge($params, $optParams); return $this->call('insert', [$params], ObjectAccessControl::class); } /** * Retrieves ACL entries on the specified object. * (objectAccessControls.listObjectAccessControls) * * @param string $bucket Name of a bucket. * @param string $object Name of the object. For information about how to URL * encode object names to be path safe, see [Encoding URI Path * Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding). * @param array $optParams Optional parameters. * * @opt_param string generation If present, selects a specific revision of this * object (as opposed to the latest version, the default). * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @return ObjectAccessControlsModel * @throws \Google\Service\Exception */ public function listObjectAccessControls($bucket, $object, $optParams = []) { $params = ['bucket' => $bucket, 'object' => $object]; $params = array_merge($params, $optParams); return $this->call('list', [$params], ObjectAccessControlsModel::class); } /** * Patches an ACL entry on the specified object. (objectAccessControls.patch) * * @param string $bucket Name of a bucket. * @param string $object Name of the object. For information about how to URL * encode object names to be path safe, see [Encoding URI Path * Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding). * @param string $entity The entity holding the permission. Can be user-userId, * user-emailAddress, group-groupId, group-emailAddress, allUsers, or * allAuthenticatedUsers. * @param ObjectAccessControl $postBody * @param array $optParams Optional parameters. * * @opt_param string generation If present, selects a specific revision of this * object (as opposed to the latest version, the default). * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @return ObjectAccessControl * @throws \Google\Service\Exception */ public function patch($bucket, $object, $entity, ObjectAccessControl $postBody, $optParams = []) { $params = ['bucket' => $bucket, 'object' => $object, 'entity' => $entity, 'postBody' => $postBody]; $params = array_merge($params, $optParams); return $this->call('patch', [$params], ObjectAccessControl::class); } /** * Updates an ACL entry on the specified object. (objectAccessControls.update) * * @param string $bucket Name of a bucket. * @param string $object Name of the object. For information about how to URL * encode object names to be path safe, see [Encoding URI Path * Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding). * @param string $entity The entity holding the permission. Can be user-userId, * user-emailAddress, group-groupId, group-emailAddress, allUsers, or * allAuthenticatedUsers. * @param ObjectAccessControl $postBody * @param array $optParams Optional parameters. * * @opt_param string generation If present, selects a specific revision of this * object (as opposed to the latest version, the default). * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @return ObjectAccessControl * @throws \Google\Service\Exception */ public function update($bucket, $object, $entity, ObjectAccessControl $postBody, $optParams = []) { $params = ['bucket' => $bucket, 'object' => $object, 'entity' => $entity, 'postBody' => $postBody]; $params = array_merge($params, $optParams); return $this->call('update', [$params], ObjectAccessControl::class); } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(ObjectAccessControls::class, 'Google_Service_Storage_Resource_ObjectAccessControls'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/Resource/Objects.php ================================================ * $storageService = new Google\Service\Storage(...); * $objects = $storageService->objects; * */ class Objects extends \Google\Service\Resource { /** * Initiates a long-running bulk restore operation on the specified bucket. * (objects.bulkRestore) * * @param string $bucket Name of the bucket in which the object resides. * @param BulkRestoreObjectsRequest $postBody * @param array $optParams Optional parameters. * @return GoogleLongrunningOperation * @throws \Google\Service\Exception */ public function bulkRestore($bucket, BulkRestoreObjectsRequest $postBody, $optParams = []) { $params = ['bucket' => $bucket, 'postBody' => $postBody]; $params = array_merge($params, $optParams); return $this->call('bulkRestore', [$params], GoogleLongrunningOperation::class); } /** * Concatenates a list of existing objects into a new object in the same bucket. * (objects.compose) * * @param string $destinationBucket Name of the bucket containing the source * objects. The destination object is stored in this bucket. * @param string $destinationObject Name of the new object. For information * about how to URL encode object names to be path safe, see [Encoding URI Path * Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding). * @param ComposeRequest $postBody * @param array $optParams Optional parameters. * * @opt_param string destinationPredefinedAcl Apply a predefined set of access * controls to the destination object. * @opt_param string ifGenerationMatch Makes the operation conditional on * whether the object's current generation matches the given value. Setting to 0 * makes the operation succeed only if there are no live versions of the object. * @opt_param string ifMetagenerationMatch Makes the operation conditional on * whether the object's current metageneration matches the given value. * @opt_param string kmsKeyName Resource name of the Cloud KMS key, of the form * projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key, that * will be used to encrypt the object. Overrides the object metadata's * kms_key_name value, if any. * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @return StorageObject * @throws \Google\Service\Exception */ public function compose($destinationBucket, $destinationObject, ComposeRequest $postBody, $optParams = []) { $params = ['destinationBucket' => $destinationBucket, 'destinationObject' => $destinationObject, 'postBody' => $postBody]; $params = array_merge($params, $optParams); return $this->call('compose', [$params], StorageObject::class); } /** * Copies a source object to a destination object. Optionally overrides * metadata. (objects.copy) * * @param string $sourceBucket Name of the bucket in which to find the source * object. * @param string $sourceObject Name of the source object. For information about * how to URL encode object names to be path safe, see [Encoding URI Path * Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding). * @param string $destinationBucket Name of the bucket in which to store the new * object. Overrides the provided object metadata's bucket value, if any.For * information about how to URL encode object names to be path safe, see * [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request- * endpoints#encoding). * @param string $destinationObject Name of the new object. Required when the * object metadata is not otherwise provided. Overrides the object metadata's * name value, if any. * @param StorageObject $postBody * @param array $optParams Optional parameters. * * @opt_param string destinationKmsKeyName Resource name of the Cloud KMS key, * of the form projects/my-project/locations/global/keyRings/my- * kr/cryptoKeys/my-key, that will be used to encrypt the object. Overrides the * object metadata's kms_key_name value, if any. * @opt_param string destinationPredefinedAcl Apply a predefined set of access * controls to the destination object. * @opt_param string ifGenerationMatch Makes the operation conditional on * whether the destination object's current generation matches the given value. * Setting to 0 makes the operation succeed only if there are no live versions * of the object. * @opt_param string ifGenerationNotMatch Makes the operation conditional on * whether the destination object's current generation does not match the given * value. If no live object exists, the precondition fails. Setting to 0 makes * the operation succeed only if there is a live version of the object. * @opt_param string ifMetagenerationMatch Makes the operation conditional on * whether the destination object's current metageneration matches the given * value. * @opt_param string ifMetagenerationNotMatch Makes the operation conditional on * whether the destination object's current metageneration does not match the * given value. * @opt_param string ifSourceGenerationMatch Makes the operation conditional on * whether the source object's current generation matches the given value. * @opt_param string ifSourceGenerationNotMatch Makes the operation conditional * on whether the source object's current generation does not match the given * value. * @opt_param string ifSourceMetagenerationMatch Makes the operation conditional * on whether the source object's current metageneration matches the given * value. * @opt_param string ifSourceMetagenerationNotMatch Makes the operation * conditional on whether the source object's current metageneration does not * match the given value. * @opt_param string projection Set of properties to return. Defaults to noAcl, * unless the object resource specifies the acl property, when it defaults to * full. * @opt_param string sourceGeneration If present, selects a specific revision of * the source object (as opposed to the latest version, the default). * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @return StorageObject * @throws \Google\Service\Exception */ public function copy($sourceBucket, $sourceObject, $destinationBucket, $destinationObject, StorageObject $postBody, $optParams = []) { $params = ['sourceBucket' => $sourceBucket, 'sourceObject' => $sourceObject, 'destinationBucket' => $destinationBucket, 'destinationObject' => $destinationObject, 'postBody' => $postBody]; $params = array_merge($params, $optParams); return $this->call('copy', [$params], StorageObject::class); } /** * Deletes an object and its metadata. Deletions are permanent if versioning is * not enabled for the bucket, or if the generation parameter is used. * (objects.delete) * * @param string $bucket Name of the bucket in which the object resides. * @param string $object Name of the object. For information about how to URL * encode object names to be path safe, see [Encoding URI Path * Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding). * @param array $optParams Optional parameters. * * @opt_param string generation If present, permanently deletes a specific * revision of this object (as opposed to the latest version, the default). * @opt_param string ifGenerationMatch Makes the operation conditional on * whether the object's current generation matches the given value. Setting to 0 * makes the operation succeed only if there are no live versions of the object. * @opt_param string ifGenerationNotMatch Makes the operation conditional on * whether the object's current generation does not match the given value. If no * live object exists, the precondition fails. Setting to 0 makes the operation * succeed only if there is a live version of the object. * @opt_param string ifMetagenerationMatch Makes the operation conditional on * whether the object's current metageneration matches the given value. * @opt_param string ifMetagenerationNotMatch Makes the operation conditional on * whether the object's current metageneration does not match the given value. * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @throws \Google\Service\Exception */ public function delete($bucket, $object, $optParams = []) { $params = ['bucket' => $bucket, 'object' => $object]; $params = array_merge($params, $optParams); return $this->call('delete', [$params]); } /** * Retrieves an object or its metadata. (objects.get) * * @param string $bucket Name of the bucket in which the object resides. * @param string $object Name of the object. For information about how to URL * encode object names to be path safe, see [Encoding URI Path * Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding). * @param array $optParams Optional parameters. * * @opt_param string generation If present, selects a specific revision of this * object (as opposed to the latest version, the default). * @opt_param string ifGenerationMatch Makes the operation conditional on * whether the object's current generation matches the given value. Setting to 0 * makes the operation succeed only if there are no live versions of the object. * @opt_param string ifGenerationNotMatch Makes the operation conditional on * whether the object's current generation does not match the given value. If no * live object exists, the precondition fails. Setting to 0 makes the operation * succeed only if there is a live version of the object. * @opt_param string ifMetagenerationMatch Makes the operation conditional on * whether the object's current metageneration matches the given value. * @opt_param string ifMetagenerationNotMatch Makes the operation conditional on * whether the object's current metageneration does not match the given value. * @opt_param string projection Set of properties to return. Defaults to noAcl. * @opt_param string restoreToken Restore token used to differentiate soft- * deleted objects with the same name and generation. Only applicable for * hierarchical namespace buckets and if softDeleted is set to true. This * parameter is optional, and is only required in the rare case when there are * multiple soft-deleted objects with the same name and generation. * @opt_param bool softDeleted If true, only soft-deleted object versions will * be listed. The default is false. For more information, see [Soft * Delete](https://cloud.google.com/storage/docs/soft-delete). * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @return StorageObject * @throws \Google\Service\Exception */ public function get($bucket, $object, $optParams = []) { $params = ['bucket' => $bucket, 'object' => $object]; $params = array_merge($params, $optParams); return $this->call('get', [$params], StorageObject::class); } /** * Returns an IAM policy for the specified object. (objects.getIamPolicy) * * @param string $bucket Name of the bucket in which the object resides. * @param string $object Name of the object. For information about how to URL * encode object names to be path safe, see [Encoding URI Path * Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding). * @param array $optParams Optional parameters. * * @opt_param string generation If present, selects a specific revision of this * object (as opposed to the latest version, the default). * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @return Policy * @throws \Google\Service\Exception */ public function getIamPolicy($bucket, $object, $optParams = []) { $params = ['bucket' => $bucket, 'object' => $object]; $params = array_merge($params, $optParams); return $this->call('getIamPolicy', [$params], Policy::class); } /** * Stores a new object and metadata. (objects.insert) * * @param string $bucket Name of the bucket in which to store the new object. * Overrides the provided object metadata's bucket value, if any. * @param StorageObject $postBody * @param array $optParams Optional parameters. * * @opt_param string contentEncoding If set, sets the contentEncoding property * of the final object to this value. Setting this parameter is equivalent to * setting the contentEncoding metadata property. This can be useful when * uploading an object with uploadType=media to indicate the encoding of the * content being uploaded. * @opt_param string ifGenerationMatch Makes the operation conditional on * whether the object's current generation matches the given value. Setting to 0 * makes the operation succeed only if there are no live versions of the object. * @opt_param string ifGenerationNotMatch Makes the operation conditional on * whether the object's current generation does not match the given value. If no * live object exists, the precondition fails. Setting to 0 makes the operation * succeed only if there is a live version of the object. * @opt_param string ifMetagenerationMatch Makes the operation conditional on * whether the object's current metageneration matches the given value. * @opt_param string ifMetagenerationNotMatch Makes the operation conditional on * whether the object's current metageneration does not match the given value. * @opt_param string kmsKeyName Resource name of the Cloud KMS key, of the form * projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key, that * will be used to encrypt the object. Overrides the object metadata's * kms_key_name value, if any. * @opt_param string name Name of the object. Required when the object metadata * is not otherwise provided. Overrides the object metadata's name value, if * any. For information about how to URL encode object names to be path safe, * see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request- * endpoints#encoding). * @opt_param string predefinedAcl Apply a predefined set of access controls to * this object. * @opt_param string projection Set of properties to return. Defaults to noAcl, * unless the object resource specifies the acl property, when it defaults to * full. * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @return StorageObject * @throws \Google\Service\Exception */ public function insert($bucket, StorageObject $postBody, $optParams = []) { $params = ['bucket' => $bucket, 'postBody' => $postBody]; $params = array_merge($params, $optParams); return $this->call('insert', [$params], StorageObject::class); } /** * Retrieves a list of objects matching the criteria. (objects.listObjects) * * @param string $bucket Name of the bucket in which to look for objects. * @param array $optParams Optional parameters. * * @opt_param string delimiter Returns results in a directory-like mode. items * will contain only objects whose names, aside from the prefix, do not contain * delimiter. Objects whose names, aside from the prefix, contain delimiter will * have their name, truncated after the delimiter, returned in prefixes. * Duplicate prefixes are omitted. * @opt_param string endOffset Filter results to objects whose names are * lexicographically before endOffset. If startOffset is also set, the objects * listed will have names between startOffset (inclusive) and endOffset * (exclusive). * @opt_param string filter Filter the returned objects. Currently only * supported for the contexts field. If delimiter is set, the returned prefixes * are exempt from this filter. * @opt_param bool includeFoldersAsPrefixes Only applicable if delimiter is set * to '/'. If true, will also include folders and managed folders (besides * objects) in the returned prefixes. * @opt_param bool includeTrailingDelimiter If true, objects that end in exactly * one instance of delimiter will have their metadata included in items in * addition to prefixes. * @opt_param string matchGlob Filter results to objects and prefixes that match * this glob pattern. * @opt_param string maxResults Maximum number of items plus prefixes to return * in a single page of responses. As duplicate prefixes are omitted, fewer total * results may be returned than requested. The service will use this parameter * or 1,000 items, whichever is smaller. * @opt_param string pageToken A previously-returned page token representing * part of the larger set of results to view. * @opt_param string prefix Filter results to objects whose names begin with * this prefix. * @opt_param string projection Set of properties to return. Defaults to noAcl. * @opt_param bool softDeleted If true, only soft-deleted object versions will * be listed. The default is false. For more information, see [Soft * Delete](https://cloud.google.com/storage/docs/soft-delete). * @opt_param string startOffset Filter results to objects whose names are * lexicographically equal to or after startOffset. If endOffset is also set, * the objects listed will have names between startOffset (inclusive) and * endOffset (exclusive). * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @opt_param bool versions If true, lists all versions of an object as distinct * results. The default is false. For more information, see [Object * Versioning](https://cloud.google.com/storage/docs/object-versioning). * @return ObjectsModel * @throws \Google\Service\Exception */ public function listObjects($bucket, $optParams = []) { $params = ['bucket' => $bucket]; $params = array_merge($params, $optParams); return $this->call('list', [$params], ObjectsModel::class); } /** * Moves the source object to the destination object in the same bucket. * (objects.move) * * @param string $bucket Name of the bucket in which the object resides. * @param string $sourceObject Name of the source object. For information about * how to URL encode object names to be path safe, see [Encoding URI Path * Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding). * @param string $destinationObject Name of the destination object. For * information about how to URL encode object names to be path safe, see * [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request- * endpoints#encoding). * @param array $optParams Optional parameters. * * @opt_param string ifGenerationMatch Makes the operation conditional on * whether the destination object's current generation matches the given value. * Setting to 0 makes the operation succeed only if there are no live versions * of the object. `ifGenerationMatch` and `ifGenerationNotMatch` conditions are * mutually exclusive: it's an error for both of them to be set in the request. * @opt_param string ifGenerationNotMatch Makes the operation conditional on * whether the destination object's current generation does not match the given * value. If no live object exists, the precondition fails. Setting to 0 makes * the operation succeed only if there is a live version of the * object.`ifGenerationMatch` and `ifGenerationNotMatch` conditions are mutually * exclusive: it's an error for both of them to be set in the request. * @opt_param string ifMetagenerationMatch Makes the operation conditional on * whether the destination object's current metageneration matches the given * value. `ifMetagenerationMatch` and `ifMetagenerationNotMatch` conditions are * mutually exclusive: it's an error for both of them to be set in the request. * @opt_param string ifMetagenerationNotMatch Makes the operation conditional on * whether the destination object's current metageneration does not match the * given value. `ifMetagenerationMatch` and `ifMetagenerationNotMatch` * conditions are mutually exclusive: it's an error for both of them to be set * in the request. * @opt_param string ifSourceGenerationMatch Makes the operation conditional on * whether the source object's current generation matches the given value. * `ifSourceGenerationMatch` and `ifSourceGenerationNotMatch` conditions are * mutually exclusive: it's an error for both of them to be set in the request. * @opt_param string ifSourceGenerationNotMatch Makes the operation conditional * on whether the source object's current generation does not match the given * value. `ifSourceGenerationMatch` and `ifSourceGenerationNotMatch` conditions * are mutually exclusive: it's an error for both of them to be set in the * request. * @opt_param string ifSourceMetagenerationMatch Makes the operation conditional * on whether the source object's current metageneration matches the given * value. `ifSourceMetagenerationMatch` and `ifSourceMetagenerationNotMatch` * conditions are mutually exclusive: it's an error for both of them to be set * in the request. * @opt_param string ifSourceMetagenerationNotMatch Makes the operation * conditional on whether the source object's current metageneration does not * match the given value. `ifSourceMetagenerationMatch` and * `ifSourceMetagenerationNotMatch` conditions are mutually exclusive: it's an * error for both of them to be set in the request. * @opt_param string projection Set of properties to return. Defaults to noAcl. * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @return StorageObject * @throws \Google\Service\Exception */ public function move($bucket, $sourceObject, $destinationObject, $optParams = []) { $params = ['bucket' => $bucket, 'sourceObject' => $sourceObject, 'destinationObject' => $destinationObject]; $params = array_merge($params, $optParams); return $this->call('move', [$params], StorageObject::class); } /** * Patches an object's metadata. (objects.patch) * * @param string $bucket Name of the bucket in which the object resides. * @param string $object Name of the object. For information about how to URL * encode object names to be path safe, see [Encoding URI Path * Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding). * @param StorageObject $postBody * @param array $optParams Optional parameters. * * @opt_param string generation If present, selects a specific revision of this * object (as opposed to the latest version, the default). * @opt_param string ifGenerationMatch Makes the operation conditional on * whether the object's current generation matches the given value. Setting to 0 * makes the operation succeed only if there are no live versions of the object. * @opt_param string ifGenerationNotMatch Makes the operation conditional on * whether the object's current generation does not match the given value. If no * live object exists, the precondition fails. Setting to 0 makes the operation * succeed only if there is a live version of the object. * @opt_param string ifMetagenerationMatch Makes the operation conditional on * whether the object's current metageneration matches the given value. * @opt_param string ifMetagenerationNotMatch Makes the operation conditional on * whether the object's current metageneration does not match the given value. * @opt_param bool overrideUnlockedRetention Must be true to remove the * retention configuration, reduce its unlocked retention period, or change its * mode from unlocked to locked. * @opt_param string predefinedAcl Apply a predefined set of access controls to * this object. * @opt_param string projection Set of properties to return. Defaults to full. * @opt_param string userProject The project to be billed for this request, for * Requester Pays buckets. * @return StorageObject * @throws \Google\Service\Exception */ public function patch($bucket, $object, StorageObject $postBody, $optParams = []) { $params = ['bucket' => $bucket, 'object' => $object, 'postBody' => $postBody]; $params = array_merge($params, $optParams); return $this->call('patch', [$params], StorageObject::class); } /** * Restores a soft-deleted object. (objects.restore) * * @param string $bucket Name of the bucket in which the object resides. * @param string $object Name of the object. For information about how to URL * encode object names to be path safe, see [Encoding URI Path * Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding). * @param string $generation Selects a specific revision of this object. * @param array $optParams Optional parameters. * * @opt_param bool copySourceAcl If true, copies the source object's ACL; * otherwise, uses the bucket's default object ACL. The default is false. * @opt_param string ifGenerationMatch Makes the operation conditional on * whether the object's one live generation matches the given value. Setting to * 0 makes the operation succeed only if there are no live versions of the * object. * @opt_param string ifGenerationNotMatch Makes the operation conditional on * whether none of the object's live generations match the given value. If no * live object exists, the precondition fails. Setting to 0 makes the operation * succeed only if there is a live version of the object. * @opt_param string ifMetagenerationMatch Makes the operation conditional on * whether the object's one live metageneration matches the given value. * @opt_param string ifMetagenerationNotMatch Makes the operation conditional on * whether none of the object's live metagenerations match the given value. * @opt_param string projection Set of properties to return. Defaults to full. * @opt_param string restoreToken Restore token used to differentiate sof- * deleted objects with the same name and generation. Only applicable for * hierarchical namespace buckets. This parameter is optional, and is only * required in the rare case when there are multiple soft-deleted objects with * the same name and generation. * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @return StorageObject * @throws \Google\Service\Exception */ public function restore($bucket, $object, $generation, $optParams = []) { $params = ['bucket' => $bucket, 'object' => $object, 'generation' => $generation]; $params = array_merge($params, $optParams); return $this->call('restore', [$params], StorageObject::class); } /** * Rewrites a source object to a destination object. Optionally overrides * metadata. (objects.rewrite) * * @param string $sourceBucket Name of the bucket in which to find the source * object. * @param string $sourceObject Name of the source object. For information about * how to URL encode object names to be path safe, see [Encoding URI Path * Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding). * @param string $destinationBucket Name of the bucket in which to store the new * object. Overrides the provided object metadata's bucket value, if any. * @param string $destinationObject Name of the new object. Required when the * object metadata is not otherwise provided. Overrides the object metadata's * name value, if any. For information about how to URL encode object names to * be path safe, see [Encoding URI Path * Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding). * @param StorageObject $postBody * @param array $optParams Optional parameters. * * @opt_param string destinationKmsKeyName Resource name of the Cloud KMS key, * of the form projects/my-project/locations/global/keyRings/my- * kr/cryptoKeys/my-key, that will be used to encrypt the object. Overrides the * object metadata's kms_key_name value, if any. * @opt_param string destinationPredefinedAcl Apply a predefined set of access * controls to the destination object. * @opt_param string ifGenerationMatch Makes the operation conditional on * whether the object's current generation matches the given value. Setting to 0 * makes the operation succeed only if there are no live versions of the object. * @opt_param string ifGenerationNotMatch Makes the operation conditional on * whether the object's current generation does not match the given value. If no * live object exists, the precondition fails. Setting to 0 makes the operation * succeed only if there is a live version of the object. * @opt_param string ifMetagenerationMatch Makes the operation conditional on * whether the destination object's current metageneration matches the given * value. * @opt_param string ifMetagenerationNotMatch Makes the operation conditional on * whether the destination object's current metageneration does not match the * given value. * @opt_param string ifSourceGenerationMatch Makes the operation conditional on * whether the source object's current generation matches the given value. * @opt_param string ifSourceGenerationNotMatch Makes the operation conditional * on whether the source object's current generation does not match the given * value. * @opt_param string ifSourceMetagenerationMatch Makes the operation conditional * on whether the source object's current metageneration matches the given * value. * @opt_param string ifSourceMetagenerationNotMatch Makes the operation * conditional on whether the source object's current metageneration does not * match the given value. * @opt_param string maxBytesRewrittenPerCall The maximum number of bytes that * will be rewritten per rewrite request. Most callers shouldn't need to specify * this parameter - it is primarily in place to support testing. If specified * the value must be an integral multiple of 1 MiB (1048576). Also, this only * applies to requests where the source and destination span locations and/or * storage classes. Finally, this value must not change across rewrite calls * else you'll get an error that the rewriteToken is invalid. * @opt_param string projection Set of properties to return. Defaults to noAcl, * unless the object resource specifies the acl property, when it defaults to * full. * @opt_param string rewriteToken Include this field (from the previous rewrite * response) on each rewrite request after the first one, until the rewrite * response 'done' flag is true. Calls that provide a rewriteToken can omit all * other request fields, but if included those fields must match the values * provided in the first rewrite request. * @opt_param string sourceGeneration If present, selects a specific revision of * the source object (as opposed to the latest version, the default). * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @return RewriteResponse * @throws \Google\Service\Exception */ public function rewrite($sourceBucket, $sourceObject, $destinationBucket, $destinationObject, StorageObject $postBody, $optParams = []) { $params = ['sourceBucket' => $sourceBucket, 'sourceObject' => $sourceObject, 'destinationBucket' => $destinationBucket, 'destinationObject' => $destinationObject, 'postBody' => $postBody]; $params = array_merge($params, $optParams); return $this->call('rewrite', [$params], RewriteResponse::class); } /** * Updates an IAM policy for the specified object. (objects.setIamPolicy) * * @param string $bucket Name of the bucket in which the object resides. * @param string $object Name of the object. For information about how to URL * encode object names to be path safe, see [Encoding URI Path * Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding). * @param Policy $postBody * @param array $optParams Optional parameters. * * @opt_param string generation If present, selects a specific revision of this * object (as opposed to the latest version, the default). * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @return Policy * @throws \Google\Service\Exception */ public function setIamPolicy($bucket, $object, Policy $postBody, $optParams = []) { $params = ['bucket' => $bucket, 'object' => $object, 'postBody' => $postBody]; $params = array_merge($params, $optParams); return $this->call('setIamPolicy', [$params], Policy::class); } /** * Tests a set of permissions on the given object to see which, if any, are held * by the caller. (objects.testIamPermissions) * * @param string $bucket Name of the bucket in which the object resides. * @param string $object Name of the object. For information about how to URL * encode object names to be path safe, see [Encoding URI Path * Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding). * @param string|array $permissions Permissions to test. * @param array $optParams Optional parameters. * * @opt_param string generation If present, selects a specific revision of this * object (as opposed to the latest version, the default). * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @return TestIamPermissionsResponse * @throws \Google\Service\Exception */ public function testIamPermissions($bucket, $object, $permissions, $optParams = []) { $params = ['bucket' => $bucket, 'object' => $object, 'permissions' => $permissions]; $params = array_merge($params, $optParams); return $this->call('testIamPermissions', [$params], TestIamPermissionsResponse::class); } /** * Updates an object's metadata. (objects.update) * * @param string $bucket Name of the bucket in which the object resides. * @param string $object Name of the object. For information about how to URL * encode object names to be path safe, see [Encoding URI Path * Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding). * @param StorageObject $postBody * @param array $optParams Optional parameters. * * @opt_param string generation If present, selects a specific revision of this * object (as opposed to the latest version, the default). * @opt_param string ifGenerationMatch Makes the operation conditional on * whether the object's current generation matches the given value. Setting to 0 * makes the operation succeed only if there are no live versions of the object. * @opt_param string ifGenerationNotMatch Makes the operation conditional on * whether the object's current generation does not match the given value. If no * live object exists, the precondition fails. Setting to 0 makes the operation * succeed only if there is a live version of the object. * @opt_param string ifMetagenerationMatch Makes the operation conditional on * whether the object's current metageneration matches the given value. * @opt_param string ifMetagenerationNotMatch Makes the operation conditional on * whether the object's current metageneration does not match the given value. * @opt_param bool overrideUnlockedRetention Must be true to remove the * retention configuration, reduce its unlocked retention period, or change its * mode from unlocked to locked. * @opt_param string predefinedAcl Apply a predefined set of access controls to * this object. * @opt_param string projection Set of properties to return. Defaults to full. * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @return StorageObject * @throws \Google\Service\Exception */ public function update($bucket, $object, StorageObject $postBody, $optParams = []) { $params = ['bucket' => $bucket, 'object' => $object, 'postBody' => $postBody]; $params = array_merge($params, $optParams); return $this->call('update', [$params], StorageObject::class); } /** * Watch for changes on all objects in a bucket. (objects.watchAll) * * @param string $bucket Name of the bucket in which to look for objects. * @param Channel $postBody * @param array $optParams Optional parameters. * * @opt_param string delimiter Returns results in a directory-like mode. items * will contain only objects whose names, aside from the prefix, do not contain * delimiter. Objects whose names, aside from the prefix, contain delimiter will * have their name, truncated after the delimiter, returned in prefixes. * Duplicate prefixes are omitted. * @opt_param string endOffset Filter results to objects whose names are * lexicographically before endOffset. If startOffset is also set, the objects * listed will have names between startOffset (inclusive) and endOffset * (exclusive). * @opt_param bool includeTrailingDelimiter If true, objects that end in exactly * one instance of delimiter will have their metadata included in items in * addition to prefixes. * @opt_param string maxResults Maximum number of items plus prefixes to return * in a single page of responses. As duplicate prefixes are omitted, fewer total * results may be returned than requested. The service will use this parameter * or 1,000 items, whichever is smaller. * @opt_param string pageToken A previously-returned page token representing * part of the larger set of results to view. * @opt_param string prefix Filter results to objects whose names begin with * this prefix. * @opt_param string projection Set of properties to return. Defaults to noAcl. * @opt_param string startOffset Filter results to objects whose names are * lexicographically equal to or after startOffset. If endOffset is also set, * the objects listed will have names between startOffset (inclusive) and * endOffset (exclusive). * @opt_param string userProject The project to be billed for this request. * Required for Requester Pays buckets. * @opt_param bool versions If true, lists all versions of an object as distinct * results. The default is false. For more information, see [Object * Versioning](https://cloud.google.com/storage/docs/object-versioning). * @return Channel * @throws \Google\Service\Exception */ public function watchAll($bucket, Channel $postBody, $optParams = []) { $params = ['bucket' => $bucket, 'postBody' => $postBody]; $params = array_merge($params, $optParams); return $this->call('watchAll', [$params], Channel::class); } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(Objects::class, 'Google_Service_Storage_Resource_Objects'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/Resource/Operations.php ================================================ * $storageService = new Google\Service\Storage(...); * $operations = $storageService->operations; * */ class Operations extends \Google\Service\Resource { /** * Starts asynchronous advancement of the relocate bucket operation in the case * of required write downtime, to allow it to lock the bucket at the source * location, and proceed with the bucket location swap. The server makes a best * effort to advance the relocate bucket operation, but success is not * guaranteed. (operations.advanceRelocateBucket) * * @param string $bucket Name of the bucket to advance the relocate for. * @param string $operationId ID of the operation resource. * @param AdvanceRelocateBucketOperationRequest $postBody * @param array $optParams Optional parameters. * @throws \Google\Service\Exception */ public function advanceRelocateBucket($bucket, $operationId, AdvanceRelocateBucketOperationRequest $postBody, $optParams = []) { $params = ['bucket' => $bucket, 'operationId' => $operationId, 'postBody' => $postBody]; $params = array_merge($params, $optParams); return $this->call('advanceRelocateBucket', [$params]); } /** * Starts asynchronous cancellation on a long-running operation. The server * makes a best effort to cancel the operation, but success is not guaranteed. * (operations.cancel) * * @param string $bucket The parent bucket of the operation resource. * @param string $operationId The ID of the operation resource. * @param array $optParams Optional parameters. * @throws \Google\Service\Exception */ public function cancel($bucket, $operationId, $optParams = []) { $params = ['bucket' => $bucket, 'operationId' => $operationId]; $params = array_merge($params, $optParams); return $this->call('cancel', [$params]); } /** * Gets the latest state of a long-running operation. (operations.get) * * @param string $bucket The parent bucket of the operation resource. * @param string $operationId The ID of the operation resource. * @param array $optParams Optional parameters. * @return GoogleLongrunningOperation * @throws \Google\Service\Exception */ public function get($bucket, $operationId, $optParams = []) { $params = ['bucket' => $bucket, 'operationId' => $operationId]; $params = array_merge($params, $optParams); return $this->call('get', [$params], GoogleLongrunningOperation::class); } /** * Lists operations that match the specified filter in the request. * (operations.listOperations) * * @param string $bucket Name of the bucket in which to look for operations. * @param array $optParams Optional parameters. * * @opt_param string filter A filter to narrow down results to a preferred * subset. The filtering language is documented in more detail in * [AIP-160](https://google.aip.dev/160). * @opt_param int pageSize Maximum number of items to return in a single page of * responses. Fewer total results may be returned than requested. The service * uses this parameter or 100 items, whichever is smaller. * @opt_param string pageToken A previously-returned page token representing * part of the larger set of results to view. * @return GoogleLongrunningListOperationsResponse * @throws \Google\Service\Exception */ public function listOperations($bucket, $optParams = []) { $params = ['bucket' => $bucket]; $params = array_merge($params, $optParams); return $this->call('list', [$params], GoogleLongrunningListOperationsResponse::class); } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(Operations::class, 'Google_Service_Storage_Resource_Operations'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/Resource/Projects.php ================================================ * $storageService = new Google\Service\Storage(...); * $projects = $storageService->projects; * */ class Projects extends \Google\Service\Resource { } // Adding a class alias for backwards compatibility with the previous class name. class_alias(Projects::class, 'Google_Service_Storage_Resource_Projects'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/Resource/ProjectsHmacKeys.php ================================================ * $storageService = new Google\Service\Storage(...); * $hmacKeys = $storageService->projects_hmacKeys; * */ class ProjectsHmacKeys extends \Google\Service\Resource { /** * Creates a new HMAC key for the specified service account. (hmacKeys.create) * * @param string $projectId Project ID owning the service account. * @param string $serviceAccountEmail Email address of the service account. * @param array $optParams Optional parameters. * * @opt_param string userProject The project to be billed for this request. * @return HmacKey * @throws \Google\Service\Exception */ public function create($projectId, $serviceAccountEmail, $optParams = []) { $params = ['projectId' => $projectId, 'serviceAccountEmail' => $serviceAccountEmail]; $params = array_merge($params, $optParams); return $this->call('create', [$params], HmacKey::class); } /** * Deletes an HMAC key. (hmacKeys.delete) * * @param string $projectId Project ID owning the requested key * @param string $accessId Name of the HMAC key to be deleted. * @param array $optParams Optional parameters. * * @opt_param string userProject The project to be billed for this request. * @throws \Google\Service\Exception */ public function delete($projectId, $accessId, $optParams = []) { $params = ['projectId' => $projectId, 'accessId' => $accessId]; $params = array_merge($params, $optParams); return $this->call('delete', [$params]); } /** * Retrieves an HMAC key's metadata (hmacKeys.get) * * @param string $projectId Project ID owning the service account of the * requested key. * @param string $accessId Name of the HMAC key. * @param array $optParams Optional parameters. * * @opt_param string userProject The project to be billed for this request. * @return HmacKeyMetadata * @throws \Google\Service\Exception */ public function get($projectId, $accessId, $optParams = []) { $params = ['projectId' => $projectId, 'accessId' => $accessId]; $params = array_merge($params, $optParams); return $this->call('get', [$params], HmacKeyMetadata::class); } /** * Retrieves a list of HMAC keys matching the criteria. * (hmacKeys.listProjectsHmacKeys) * * @param string $projectId Name of the project in which to look for HMAC keys. * @param array $optParams Optional parameters. * * @opt_param string maxResults Maximum number of items to return in a single * page of responses. The service uses this parameter or 250 items, whichever is * smaller. The max number of items per page will also be limited by the number * of distinct service accounts in the response. If the number of service * accounts in a single response is too high, the page will truncated and a next * page token will be returned. * @opt_param string pageToken A previously-returned page token representing * part of the larger set of results to view. * @opt_param string serviceAccountEmail If present, only keys for the given * service account are returned. * @opt_param bool showDeletedKeys Whether or not to show keys in the DELETED * state. * @opt_param string userProject The project to be billed for this request. * @return HmacKeysMetadata * @throws \Google\Service\Exception */ public function listProjectsHmacKeys($projectId, $optParams = []) { $params = ['projectId' => $projectId]; $params = array_merge($params, $optParams); return $this->call('list', [$params], HmacKeysMetadata::class); } /** * Updates the state of an HMAC key. See the [HMAC Key resource descriptor](http * s://cloud.google.com/storage/docs/json_api/v1/projects/hmacKeys/update#reques * t-body) for valid states. (hmacKeys.update) * * @param string $projectId Project ID owning the service account of the updated * key. * @param string $accessId Name of the HMAC key being updated. * @param HmacKeyMetadata $postBody * @param array $optParams Optional parameters. * * @opt_param string userProject The project to be billed for this request. * @return HmacKeyMetadata * @throws \Google\Service\Exception */ public function update($projectId, $accessId, HmacKeyMetadata $postBody, $optParams = []) { $params = ['projectId' => $projectId, 'accessId' => $accessId, 'postBody' => $postBody]; $params = array_merge($params, $optParams); return $this->call('update', [$params], HmacKeyMetadata::class); } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(ProjectsHmacKeys::class, 'Google_Service_Storage_Resource_ProjectsHmacKeys'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/Resource/ProjectsServiceAccount.php ================================================ * $storageService = new Google\Service\Storage(...); * $serviceAccount = $storageService->projects_serviceAccount; * */ class ProjectsServiceAccount extends \Google\Service\Resource { /** * Get the email address of this project's Google Cloud Storage service account. * (serviceAccount.get) * * @param string $projectId Project ID * @param array $optParams Optional parameters. * * @opt_param string userProject The project to be billed for this request. * @return ServiceAccount * @throws \Google\Service\Exception */ public function get($projectId, $optParams = []) { $params = ['projectId' => $projectId]; $params = array_merge($params, $optParams); return $this->call('get', [$params], ServiceAccount::class); } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(ProjectsServiceAccount::class, 'Google_Service_Storage_Resource_ProjectsServiceAccount'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/RewriteResponse.php ================================================ done = $done; } /** * @return bool */ public function getDone() { return $this->done; } /** * The kind of item this is. * * @param string $kind */ public function setKind($kind) { $this->kind = $kind; } /** * @return string */ public function getKind() { return $this->kind; } /** * The total size of the object being copied in bytes. This property is always * present in the response. * * @param string $objectSize */ public function setObjectSize($objectSize) { $this->objectSize = $objectSize; } /** * @return string */ public function getObjectSize() { return $this->objectSize; } /** * A resource containing the metadata for the copied-to object. This property * is present in the response only when copying completes. * * @param StorageObject $resource */ public function setResource(StorageObject $resource) { $this->resource = $resource; } /** * @return StorageObject */ public function getResource() { return $this->resource; } /** * A token to use in subsequent requests to continue copying data. This token * is present in the response only when there is more data to copy. * * @param string $rewriteToken */ public function setRewriteToken($rewriteToken) { $this->rewriteToken = $rewriteToken; } /** * @return string */ public function getRewriteToken() { return $this->rewriteToken; } /** * The total bytes written so far, which can be used to provide a waiting user * with a progress indicator. This property is always present in the response. * * @param string $totalBytesRewritten */ public function setTotalBytesRewritten($totalBytesRewritten) { $this->totalBytesRewritten = $totalBytesRewritten; } /** * @return string */ public function getTotalBytesRewritten() { return $this->totalBytesRewritten; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(RewriteResponse::class, 'Google_Service_Storage_RewriteResponse'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/ServiceAccount.php ================================================ "email_address", ]; /** * The ID of the notification. * * @var string */ public $emailAddress; /** * The kind of item this is. For notifications, this is always * storage#notification. * * @var string */ public $kind; /** * The ID of the notification. * * @param string $emailAddress */ public function setEmailAddress($emailAddress) { $this->emailAddress = $emailAddress; } /** * @return string */ public function getEmailAddress() { return $this->emailAddress; } /** * The kind of item this is. For notifications, this is always * storage#notification. * * @param string $kind */ public function setKind($kind) { $this->kind = $kind; } /** * @return string */ public function getKind() { return $this->kind; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(ServiceAccount::class, 'Google_Service_Storage_ServiceAccount'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/StorageObject.php ================================================ acl = $acl; } /** * @return ObjectAccessControl[] */ public function getAcl() { return $this->acl; } /** * The name of the bucket containing this object. * * @param string $bucket */ public function setBucket($bucket) { $this->bucket = $bucket; } /** * @return string */ public function getBucket() { return $this->bucket; } /** * Cache-Control directive for the object data. If omitted, and the object is * accessible to all anonymous users, the default will be public, max- * age=3600. * * @param string $cacheControl */ public function setCacheControl($cacheControl) { $this->cacheControl = $cacheControl; } /** * @return string */ public function getCacheControl() { return $this->cacheControl; } /** * Number of underlying components that make up this object. Components are * accumulated by compose operations. * * @param int $componentCount */ public function setComponentCount($componentCount) { $this->componentCount = $componentCount; } /** * @return int */ public function getComponentCount() { return $this->componentCount; } /** * Content-Disposition of the object data. * * @param string $contentDisposition */ public function setContentDisposition($contentDisposition) { $this->contentDisposition = $contentDisposition; } /** * @return string */ public function getContentDisposition() { return $this->contentDisposition; } /** * Content-Encoding of the object data. * * @param string $contentEncoding */ public function setContentEncoding($contentEncoding) { $this->contentEncoding = $contentEncoding; } /** * @return string */ public function getContentEncoding() { return $this->contentEncoding; } /** * Content-Language of the object data. * * @param string $contentLanguage */ public function setContentLanguage($contentLanguage) { $this->contentLanguage = $contentLanguage; } /** * @return string */ public function getContentLanguage() { return $this->contentLanguage; } /** * Content-Type of the object data. If an object is stored without a Content- * Type, it is served as application/octet-stream. * * @param string $contentType */ public function setContentType($contentType) { $this->contentType = $contentType; } /** * @return string */ public function getContentType() { return $this->contentType; } /** * User-defined or system-defined object contexts. Each object context is a * key-payload pair, where the key provides the identification and the payload * holds the associated value and additional metadata. * * @param StorageObjectContexts $contexts */ public function setContexts(StorageObjectContexts $contexts) { $this->contexts = $contexts; } /** * @return StorageObjectContexts */ public function getContexts() { return $this->contexts; } /** * CRC32c checksum, as described in RFC 4960, Appendix B; encoded using base64 * in big-endian byte order. For more information about using the CRC32c * checksum, see [Data Validation and Change * Detection](https://cloud.google.com/storage/docs/data-validation). * * @param string $crc32c */ public function setCrc32c($crc32c) { $this->crc32c = $crc32c; } /** * @return string */ public function getCrc32c() { return $this->crc32c; } /** * A timestamp in RFC 3339 format specified by the user for an object. * * @param string $customTime */ public function setCustomTime($customTime) { $this->customTime = $customTime; } /** * @return string */ public function getCustomTime() { return $this->customTime; } /** * Metadata of customer-supplied encryption key, if the object is encrypted by * such a key. * * @param StorageObjectCustomerEncryption $customerEncryption */ public function setCustomerEncryption(StorageObjectCustomerEncryption $customerEncryption) { $this->customerEncryption = $customerEncryption; } /** * @return StorageObjectCustomerEncryption */ public function getCustomerEncryption() { return $this->customerEncryption; } /** * HTTP 1.1 Entity tag for the object. * * @param string $etag */ public function setEtag($etag) { $this->etag = $etag; } /** * @return string */ public function getEtag() { return $this->etag; } /** * Whether an object is under event-based hold. Event-based hold is a way to * retain objects until an event occurs, which is signified by the hold's * release (i.e. this value is set to false). After being released (set to * false), such objects will be subject to bucket-level retention (if any). * One sample use case of this flag is for banks to hold loan documents for at * least 3 years after loan is paid in full. Here, bucket-level retention is 3 * years and the event is the loan being paid in full. In this example, these * objects will be held intact for any number of years until the event has * occurred (event-based hold on the object is released) and then 3 more years * after that. That means retention duration of the objects begins from the * moment event-based hold transitioned from true to false. * * @param bool $eventBasedHold */ public function setEventBasedHold($eventBasedHold) { $this->eventBasedHold = $eventBasedHold; } /** * @return bool */ public function getEventBasedHold() { return $this->eventBasedHold; } /** * The content generation of this object. Used for object versioning. * * @param string $generation */ public function setGeneration($generation) { $this->generation = $generation; } /** * @return string */ public function getGeneration() { return $this->generation; } /** * This is the time (in the future) when the soft-deleted object will no * longer be restorable. It is equal to the soft delete time plus the current * soft delete retention duration of the bucket. * * @param string $hardDeleteTime */ public function setHardDeleteTime($hardDeleteTime) { $this->hardDeleteTime = $hardDeleteTime; } /** * @return string */ public function getHardDeleteTime() { return $this->hardDeleteTime; } /** * The ID of the object, including the bucket name, object name, and * generation number. * * @param string $id */ public function setId($id) { $this->id = $id; } /** * @return string */ public function getId() { return $this->id; } /** * The kind of item this is. For objects, this is always storage#object. * * @param string $kind */ public function setKind($kind) { $this->kind = $kind; } /** * @return string */ public function getKind() { return $this->kind; } /** * Not currently supported. Specifying the parameter causes the request to * fail with status code 400 - Bad Request. * * @param string $kmsKeyName */ public function setKmsKeyName($kmsKeyName) { $this->kmsKeyName = $kmsKeyName; } /** * @return string */ public function getKmsKeyName() { return $this->kmsKeyName; } /** * MD5 hash of the data; encoded using base64. For more information about * using the MD5 hash, see [Data Validation and Change * Detection](https://cloud.google.com/storage/docs/data-validation). * * @param string $md5Hash */ public function setMd5Hash($md5Hash) { $this->md5Hash = $md5Hash; } /** * @return string */ public function getMd5Hash() { return $this->md5Hash; } /** * Media download link. * * @param string $mediaLink */ public function setMediaLink($mediaLink) { $this->mediaLink = $mediaLink; } /** * @return string */ public function getMediaLink() { return $this->mediaLink; } /** * User-provided metadata, in key/value pairs. * * @param string[] $metadata */ public function setMetadata($metadata) { $this->metadata = $metadata; } /** * @return string[] */ public function getMetadata() { return $this->metadata; } /** * The version of the metadata for this object at this generation. Used for * preconditions and for detecting changes in metadata. A metageneration * number is only meaningful in the context of a particular generation of a * particular object. * * @param string $metageneration */ public function setMetageneration($metageneration) { $this->metageneration = $metageneration; } /** * @return string */ public function getMetageneration() { return $this->metageneration; } /** * The name of the object. Required if not specified by URL parameter. * * @param string $name */ public function setName($name) { $this->name = $name; } /** * @return string */ public function getName() { return $this->name; } /** * The owner of the object. This will always be the uploader of the object. * * @param StorageObjectOwner $owner */ public function setOwner(StorageObjectOwner $owner) { $this->owner = $owner; } /** * @return StorageObjectOwner */ public function getOwner() { return $this->owner; } /** * Restore token used to differentiate deleted objects with the same name and * generation. This field is only returned for deleted objects in hierarchical * namespace buckets. * * @param string $restoreToken */ public function setRestoreToken($restoreToken) { $this->restoreToken = $restoreToken; } /** * @return string */ public function getRestoreToken() { return $this->restoreToken; } /** * A collection of object level retention parameters. * * @param StorageObjectRetention $retention */ public function setRetention(StorageObjectRetention $retention) { $this->retention = $retention; } /** * @return StorageObjectRetention */ public function getRetention() { return $this->retention; } /** * A server-determined value that specifies the earliest time that the * object's retention period expires. This value is in RFC 3339 format. Note * 1: This field is not provided for objects with an active event-based hold, * since retention expiration is unknown until the hold is removed. Note 2: * This value can be provided even when temporary hold is set (so that the * user can reason about policy without having to first unset the temporary * hold). * * @param string $retentionExpirationTime */ public function setRetentionExpirationTime($retentionExpirationTime) { $this->retentionExpirationTime = $retentionExpirationTime; } /** * @return string */ public function getRetentionExpirationTime() { return $this->retentionExpirationTime; } /** * The link to this object. * * @param string $selfLink */ public function setSelfLink($selfLink) { $this->selfLink = $selfLink; } /** * @return string */ public function getSelfLink() { return $this->selfLink; } /** * Content-Length of the data in bytes. * * @param string $size */ public function setSize($size) { $this->size = $size; } /** * @return string */ public function getSize() { return $this->size; } /** * The time at which the object became soft-deleted in RFC 3339 format. * * @param string $softDeleteTime */ public function setSoftDeleteTime($softDeleteTime) { $this->softDeleteTime = $softDeleteTime; } /** * @return string */ public function getSoftDeleteTime() { return $this->softDeleteTime; } /** * Storage class of the object. * * @param string $storageClass */ public function setStorageClass($storageClass) { $this->storageClass = $storageClass; } /** * @return string */ public function getStorageClass() { return $this->storageClass; } /** * Whether an object is under temporary hold. While this flag is set to true, * the object is protected against deletion and overwrites. A common use case * of this flag is regulatory investigations where objects need to be retained * while the investigation is ongoing. Note that unlike event-based hold, * temporary hold does not impact retention expiration time of an object. * * @param bool $temporaryHold */ public function setTemporaryHold($temporaryHold) { $this->temporaryHold = $temporaryHold; } /** * @return bool */ public function getTemporaryHold() { return $this->temporaryHold; } /** * The creation time of the object in RFC 3339 format. * * @param string $timeCreated */ public function setTimeCreated($timeCreated) { $this->timeCreated = $timeCreated; } /** * @return string */ public function getTimeCreated() { return $this->timeCreated; } /** * The time at which the object became noncurrent in RFC 3339 format. Will be * returned if and only if this version of the object has been deleted. * * @param string $timeDeleted */ public function setTimeDeleted($timeDeleted) { $this->timeDeleted = $timeDeleted; } /** * @return string */ public function getTimeDeleted() { return $this->timeDeleted; } /** * The time when the object was finalized. * * @param string $timeFinalized */ public function setTimeFinalized($timeFinalized) { $this->timeFinalized = $timeFinalized; } /** * @return string */ public function getTimeFinalized() { return $this->timeFinalized; } /** * The time at which the object's storage class was last changed. When the * object is initially created, it will be set to timeCreated. * * @param string $timeStorageClassUpdated */ public function setTimeStorageClassUpdated($timeStorageClassUpdated) { $this->timeStorageClassUpdated = $timeStorageClassUpdated; } /** * @return string */ public function getTimeStorageClassUpdated() { return $this->timeStorageClassUpdated; } /** * The modification time of the object metadata in RFC 3339 format. Set * initially to object creation time and then updated whenever any metadata of * the object changes. This includes changes made by a requester, such as * modifying custom metadata, as well as changes made by Cloud Storage on * behalf of a requester, such as changing the storage class based on an * Object Lifecycle Configuration. * * @param string $updated */ public function setUpdated($updated) { $this->updated = $updated; } /** * @return string */ public function getUpdated() { return $this->updated; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(StorageObject::class, 'Google_Service_Storage_StorageObject'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/StorageObjectContexts.php ================================================ custom = $custom; } /** * @return ObjectCustomContextPayload[] */ public function getCustom() { return $this->custom; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(StorageObjectContexts::class, 'Google_Service_Storage_StorageObjectContexts'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/StorageObjectCustomerEncryption.php ================================================ encryptionAlgorithm = $encryptionAlgorithm; } /** * @return string */ public function getEncryptionAlgorithm() { return $this->encryptionAlgorithm; } /** * SHA256 hash value of the encryption key. * * @param string $keySha256 */ public function setKeySha256($keySha256) { $this->keySha256 = $keySha256; } /** * @return string */ public function getKeySha256() { return $this->keySha256; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(StorageObjectCustomerEncryption::class, 'Google_Service_Storage_StorageObjectCustomerEncryption'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/StorageObjectOwner.php ================================================ entity = $entity; } /** * @return string */ public function getEntity() { return $this->entity; } /** * The ID for the entity. * * @param string $entityId */ public function setEntityId($entityId) { $this->entityId = $entityId; } /** * @return string */ public function getEntityId() { return $this->entityId; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(StorageObjectOwner::class, 'Google_Service_Storage_StorageObjectOwner'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/StorageObjectRetention.php ================================================ mode = $mode; } /** * @return string */ public function getMode() { return $this->mode; } /** * A time in RFC 3339 format until which object retention protects this * object. * * @param string $retainUntilTime */ public function setRetainUntilTime($retainUntilTime) { $this->retainUntilTime = $retainUntilTime; } /** * @return string */ public function getRetainUntilTime() { return $this->retainUntilTime; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(StorageObjectRetention::class, 'Google_Service_Storage_StorageObjectRetention'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage/TestIamPermissionsResponse.php ================================================ kind = $kind; } /** * @return string */ public function getKind() { return $this->kind; } /** * The permissions held by the caller. Permissions are always of the format * storage.resource.capability, where resource is one of buckets, objects, or * managedFolders. The supported permissions are as follows: - * storage.buckets.delete - Delete bucket. - storage.buckets.get - Read * bucket metadata. - storage.buckets.getIamPolicy - Read bucket IAM policy. * - storage.buckets.create - Create bucket. - storage.buckets.list - List * buckets. - storage.buckets.setIamPolicy - Update bucket IAM policy. - * storage.buckets.update - Update bucket metadata. - storage.objects.delete * - Delete object. - storage.objects.get - Read object data and metadata. * - storage.objects.getIamPolicy - Read object IAM policy. - * storage.objects.create - Create object. - storage.objects.list - List * objects. - storage.objects.setIamPolicy - Update object IAM policy. - * storage.objects.update - Update object metadata. - * storage.managedFolders.delete - Delete managed folder. - * storage.managedFolders.get - Read managed folder metadata. - * storage.managedFolders.getIamPolicy - Read managed folder IAM policy. - * storage.managedFolders.create - Create managed folder. - * storage.managedFolders.list - List managed folders. - * storage.managedFolders.setIamPolicy - Update managed folder IAM policy. * * @param string[] $permissions */ public function setPermissions($permissions) { $this->permissions = $permissions; } /** * @return string[] */ public function getPermissions() { return $this->permissions; } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(TestIamPermissionsResponse::class, 'Google_Service_Storage_TestIamPermissionsResponse'); ================================================ FILE: lib/Google/vendor/google/apiclient-services/src/Storage.php ================================================ * Stores and retrieves potentially large, immutable data objects.

* *

* For more information about this service, see the API * Documentation *

* * @author Google, Inc. */ class Storage extends \Google\Service { /** View and manage your data across Google Cloud Platform services. */ const CLOUD_PLATFORM = "https://www.googleapis.com/auth/cloud-platform"; /** View your data across Google Cloud Platform services. */ const CLOUD_PLATFORM_READ_ONLY = "https://www.googleapis.com/auth/cloud-platform.read-only"; /** Manage your data and permissions in Google Cloud Storage. */ const DEVSTORAGE_FULL_CONTROL = "https://www.googleapis.com/auth/devstorage.full_control"; /** View your data in Google Cloud Storage. */ const DEVSTORAGE_READ_ONLY = "https://www.googleapis.com/auth/devstorage.read_only"; /** Manage your data in Google Cloud Storage. */ const DEVSTORAGE_READ_WRITE = "https://www.googleapis.com/auth/devstorage.read_write"; public $anywhereCaches; public $bucketAccessControls; public $buckets; public $channels; public $defaultObjectAccessControls; public $folders; public $managedFolders; public $notifications; public $objectAccessControls; public $objects; public $operations; public $projects_hmacKeys; public $projects_serviceAccount; public $rootUrlTemplate; /** * Constructs the internal representation of the Storage service. * * @param Client|array $clientOrConfig The client used to deliver requests, or a * config array to pass to a new Client instance. * @param string $rootUrl The root URL used for requests to the service. */ public function __construct($clientOrConfig = [], $rootUrl = null) { parent::__construct($clientOrConfig); $this->rootUrl = $rootUrl ?: 'https://storage.googleapis.com/'; $this->rootUrlTemplate = $rootUrl ?: 'https://storage.UNIVERSE_DOMAIN/'; $this->servicePath = 'storage/v1/'; $this->batchPath = 'batch/storage/v1'; $this->version = 'v1'; $this->serviceName = 'storage'; $this->anywhereCaches = new Storage\Resource\AnywhereCaches( $this, $this->serviceName, 'anywhereCaches', [ 'methods' => [ 'disable' => [ 'path' => 'b/{bucket}/anywhereCaches/{anywhereCacheId}/disable', 'httpMethod' => 'POST', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'anywhereCacheId' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], ], ],'get' => [ 'path' => 'b/{bucket}/anywhereCaches/{anywhereCacheId}', 'httpMethod' => 'GET', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'anywhereCacheId' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], ], ],'insert' => [ 'path' => 'b/{bucket}/anywhereCaches', 'httpMethod' => 'POST', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], ], ],'list' => [ 'path' => 'b/{bucket}/anywhereCaches', 'httpMethod' => 'GET', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'pageSize' => [ 'location' => 'query', 'type' => 'integer', ], 'pageToken' => [ 'location' => 'query', 'type' => 'string', ], ], ],'pause' => [ 'path' => 'b/{bucket}/anywhereCaches/{anywhereCacheId}/pause', 'httpMethod' => 'POST', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'anywhereCacheId' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], ], ],'resume' => [ 'path' => 'b/{bucket}/anywhereCaches/{anywhereCacheId}/resume', 'httpMethod' => 'POST', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'anywhereCacheId' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], ], ],'update' => [ 'path' => 'b/{bucket}/anywhereCaches/{anywhereCacheId}', 'httpMethod' => 'PATCH', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'anywhereCacheId' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], ], ], ] ] ); $this->bucketAccessControls = new Storage\Resource\BucketAccessControls( $this, $this->serviceName, 'bucketAccessControls', [ 'methods' => [ 'delete' => [ 'path' => 'b/{bucket}/acl/{entity}', 'httpMethod' => 'DELETE', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'entity' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'get' => [ 'path' => 'b/{bucket}/acl/{entity}', 'httpMethod' => 'GET', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'entity' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'insert' => [ 'path' => 'b/{bucket}/acl', 'httpMethod' => 'POST', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'list' => [ 'path' => 'b/{bucket}/acl', 'httpMethod' => 'GET', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'patch' => [ 'path' => 'b/{bucket}/acl/{entity}', 'httpMethod' => 'PATCH', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'entity' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'update' => [ 'path' => 'b/{bucket}/acl/{entity}', 'httpMethod' => 'PUT', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'entity' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ], ] ] ); $this->buckets = new Storage\Resource\Buckets( $this, $this->serviceName, 'buckets', [ 'methods' => [ 'delete' => [ 'path' => 'b/{bucket}', 'httpMethod' => 'DELETE', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'ifMetagenerationMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifMetagenerationNotMatch' => [ 'location' => 'query', 'type' => 'string', ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'get' => [ 'path' => 'b/{bucket}', 'httpMethod' => 'GET', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'generation' => [ 'location' => 'query', 'type' => 'string', ], 'ifMetagenerationMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifMetagenerationNotMatch' => [ 'location' => 'query', 'type' => 'string', ], 'projection' => [ 'location' => 'query', 'type' => 'string', ], 'softDeleted' => [ 'location' => 'query', 'type' => 'boolean', ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'getIamPolicy' => [ 'path' => 'b/{bucket}/iam', 'httpMethod' => 'GET', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'optionsRequestedPolicyVersion' => [ 'location' => 'query', 'type' => 'integer', ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'getStorageLayout' => [ 'path' => 'b/{bucket}/storageLayout', 'httpMethod' => 'GET', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'prefix' => [ 'location' => 'query', 'type' => 'string', ], ], ],'insert' => [ 'path' => 'b', 'httpMethod' => 'POST', 'parameters' => [ 'project' => [ 'location' => 'query', 'type' => 'string', 'required' => true, ], 'enableObjectRetention' => [ 'location' => 'query', 'type' => 'boolean', ], 'predefinedAcl' => [ 'location' => 'query', 'type' => 'string', ], 'predefinedDefaultObjectAcl' => [ 'location' => 'query', 'type' => 'string', ], 'projection' => [ 'location' => 'query', 'type' => 'string', ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'list' => [ 'path' => 'b', 'httpMethod' => 'GET', 'parameters' => [ 'project' => [ 'location' => 'query', 'type' => 'string', 'required' => true, ], 'maxResults' => [ 'location' => 'query', 'type' => 'integer', ], 'pageToken' => [ 'location' => 'query', 'type' => 'string', ], 'prefix' => [ 'location' => 'query', 'type' => 'string', ], 'projection' => [ 'location' => 'query', 'type' => 'string', ], 'returnPartialSuccess' => [ 'location' => 'query', 'type' => 'boolean', ], 'softDeleted' => [ 'location' => 'query', 'type' => 'boolean', ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'lockRetentionPolicy' => [ 'path' => 'b/{bucket}/lockRetentionPolicy', 'httpMethod' => 'POST', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'ifMetagenerationMatch' => [ 'location' => 'query', 'type' => 'string', 'required' => true, ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'patch' => [ 'path' => 'b/{bucket}', 'httpMethod' => 'PATCH', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'ifMetagenerationMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifMetagenerationNotMatch' => [ 'location' => 'query', 'type' => 'string', ], 'predefinedAcl' => [ 'location' => 'query', 'type' => 'string', ], 'predefinedDefaultObjectAcl' => [ 'location' => 'query', 'type' => 'string', ], 'projection' => [ 'location' => 'query', 'type' => 'string', ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'relocate' => [ 'path' => 'b/{bucket}/relocate', 'httpMethod' => 'POST', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], ], ],'restore' => [ 'path' => 'b/{bucket}/restore', 'httpMethod' => 'POST', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'generation' => [ 'location' => 'query', 'type' => 'string', 'required' => true, ], 'projection' => [ 'location' => 'query', 'type' => 'string', ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'setIamPolicy' => [ 'path' => 'b/{bucket}/iam', 'httpMethod' => 'PUT', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'testIamPermissions' => [ 'path' => 'b/{bucket}/iam/testPermissions', 'httpMethod' => 'GET', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'permissions' => [ 'location' => 'query', 'type' => 'string', 'repeated' => true, 'required' => true, ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'update' => [ 'path' => 'b/{bucket}', 'httpMethod' => 'PUT', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'ifMetagenerationMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifMetagenerationNotMatch' => [ 'location' => 'query', 'type' => 'string', ], 'predefinedAcl' => [ 'location' => 'query', 'type' => 'string', ], 'predefinedDefaultObjectAcl' => [ 'location' => 'query', 'type' => 'string', ], 'projection' => [ 'location' => 'query', 'type' => 'string', ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ], ] ] ); $this->channels = new Storage\Resource\Channels( $this, $this->serviceName, 'channels', [ 'methods' => [ 'stop' => [ 'path' => 'channels/stop', 'httpMethod' => 'POST', 'parameters' => [], ], ] ] ); $this->defaultObjectAccessControls = new Storage\Resource\DefaultObjectAccessControls( $this, $this->serviceName, 'defaultObjectAccessControls', [ 'methods' => [ 'delete' => [ 'path' => 'b/{bucket}/defaultObjectAcl/{entity}', 'httpMethod' => 'DELETE', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'entity' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'get' => [ 'path' => 'b/{bucket}/defaultObjectAcl/{entity}', 'httpMethod' => 'GET', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'entity' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'insert' => [ 'path' => 'b/{bucket}/defaultObjectAcl', 'httpMethod' => 'POST', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'list' => [ 'path' => 'b/{bucket}/defaultObjectAcl', 'httpMethod' => 'GET', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'ifMetagenerationMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifMetagenerationNotMatch' => [ 'location' => 'query', 'type' => 'string', ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'patch' => [ 'path' => 'b/{bucket}/defaultObjectAcl/{entity}', 'httpMethod' => 'PATCH', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'entity' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'update' => [ 'path' => 'b/{bucket}/defaultObjectAcl/{entity}', 'httpMethod' => 'PUT', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'entity' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ], ] ] ); $this->folders = new Storage\Resource\Folders( $this, $this->serviceName, 'folders', [ 'methods' => [ 'delete' => [ 'path' => 'b/{bucket}/folders/{folder}', 'httpMethod' => 'DELETE', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'folder' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'ifMetagenerationMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifMetagenerationNotMatch' => [ 'location' => 'query', 'type' => 'string', ], ], ],'get' => [ 'path' => 'b/{bucket}/folders/{folder}', 'httpMethod' => 'GET', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'folder' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'ifMetagenerationMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifMetagenerationNotMatch' => [ 'location' => 'query', 'type' => 'string', ], ], ],'insert' => [ 'path' => 'b/{bucket}/folders', 'httpMethod' => 'POST', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'recursive' => [ 'location' => 'query', 'type' => 'boolean', ], ], ],'list' => [ 'path' => 'b/{bucket}/folders', 'httpMethod' => 'GET', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'delimiter' => [ 'location' => 'query', 'type' => 'string', ], 'endOffset' => [ 'location' => 'query', 'type' => 'string', ], 'pageSize' => [ 'location' => 'query', 'type' => 'integer', ], 'pageToken' => [ 'location' => 'query', 'type' => 'string', ], 'prefix' => [ 'location' => 'query', 'type' => 'string', ], 'startOffset' => [ 'location' => 'query', 'type' => 'string', ], ], ],'rename' => [ 'path' => 'b/{bucket}/folders/{sourceFolder}/renameTo/folders/{destinationFolder}', 'httpMethod' => 'POST', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'sourceFolder' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'destinationFolder' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'ifSourceMetagenerationMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifSourceMetagenerationNotMatch' => [ 'location' => 'query', 'type' => 'string', ], ], ], ] ] ); $this->managedFolders = new Storage\Resource\ManagedFolders( $this, $this->serviceName, 'managedFolders', [ 'methods' => [ 'delete' => [ 'path' => 'b/{bucket}/managedFolders/{managedFolder}', 'httpMethod' => 'DELETE', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'managedFolder' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'allowNonEmpty' => [ 'location' => 'query', 'type' => 'boolean', ], 'ifMetagenerationMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifMetagenerationNotMatch' => [ 'location' => 'query', 'type' => 'string', ], ], ],'get' => [ 'path' => 'b/{bucket}/managedFolders/{managedFolder}', 'httpMethod' => 'GET', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'managedFolder' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'ifMetagenerationMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifMetagenerationNotMatch' => [ 'location' => 'query', 'type' => 'string', ], ], ],'getIamPolicy' => [ 'path' => 'b/{bucket}/managedFolders/{managedFolder}/iam', 'httpMethod' => 'GET', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'managedFolder' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'optionsRequestedPolicyVersion' => [ 'location' => 'query', 'type' => 'integer', ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'insert' => [ 'path' => 'b/{bucket}/managedFolders', 'httpMethod' => 'POST', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], ], ],'list' => [ 'path' => 'b/{bucket}/managedFolders', 'httpMethod' => 'GET', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'pageSize' => [ 'location' => 'query', 'type' => 'integer', ], 'pageToken' => [ 'location' => 'query', 'type' => 'string', ], 'prefix' => [ 'location' => 'query', 'type' => 'string', ], ], ],'setIamPolicy' => [ 'path' => 'b/{bucket}/managedFolders/{managedFolder}/iam', 'httpMethod' => 'PUT', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'managedFolder' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'testIamPermissions' => [ 'path' => 'b/{bucket}/managedFolders/{managedFolder}/iam/testPermissions', 'httpMethod' => 'GET', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'managedFolder' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'permissions' => [ 'location' => 'query', 'type' => 'string', 'repeated' => true, 'required' => true, ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ], ] ] ); $this->notifications = new Storage\Resource\Notifications( $this, $this->serviceName, 'notifications', [ 'methods' => [ 'delete' => [ 'path' => 'b/{bucket}/notificationConfigs/{notification}', 'httpMethod' => 'DELETE', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'notification' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'get' => [ 'path' => 'b/{bucket}/notificationConfigs/{notification}', 'httpMethod' => 'GET', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'notification' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'insert' => [ 'path' => 'b/{bucket}/notificationConfigs', 'httpMethod' => 'POST', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'list' => [ 'path' => 'b/{bucket}/notificationConfigs', 'httpMethod' => 'GET', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ], ] ] ); $this->objectAccessControls = new Storage\Resource\ObjectAccessControls( $this, $this->serviceName, 'objectAccessControls', [ 'methods' => [ 'delete' => [ 'path' => 'b/{bucket}/o/{object}/acl/{entity}', 'httpMethod' => 'DELETE', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'object' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'entity' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'generation' => [ 'location' => 'query', 'type' => 'string', ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'get' => [ 'path' => 'b/{bucket}/o/{object}/acl/{entity}', 'httpMethod' => 'GET', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'object' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'entity' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'generation' => [ 'location' => 'query', 'type' => 'string', ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'insert' => [ 'path' => 'b/{bucket}/o/{object}/acl', 'httpMethod' => 'POST', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'object' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'generation' => [ 'location' => 'query', 'type' => 'string', ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'list' => [ 'path' => 'b/{bucket}/o/{object}/acl', 'httpMethod' => 'GET', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'object' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'generation' => [ 'location' => 'query', 'type' => 'string', ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'patch' => [ 'path' => 'b/{bucket}/o/{object}/acl/{entity}', 'httpMethod' => 'PATCH', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'object' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'entity' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'generation' => [ 'location' => 'query', 'type' => 'string', ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'update' => [ 'path' => 'b/{bucket}/o/{object}/acl/{entity}', 'httpMethod' => 'PUT', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'object' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'entity' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'generation' => [ 'location' => 'query', 'type' => 'string', ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ], ] ] ); $this->objects = new Storage\Resource\Objects( $this, $this->serviceName, 'objects', [ 'methods' => [ 'bulkRestore' => [ 'path' => 'b/{bucket}/o/bulkRestore', 'httpMethod' => 'POST', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], ], ],'compose' => [ 'path' => 'b/{destinationBucket}/o/{destinationObject}/compose', 'httpMethod' => 'POST', 'parameters' => [ 'destinationBucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'destinationObject' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'destinationPredefinedAcl' => [ 'location' => 'query', 'type' => 'string', ], 'ifGenerationMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifMetagenerationMatch' => [ 'location' => 'query', 'type' => 'string', ], 'kmsKeyName' => [ 'location' => 'query', 'type' => 'string', ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'copy' => [ 'path' => 'b/{sourceBucket}/o/{sourceObject}/copyTo/b/{destinationBucket}/o/{destinationObject}', 'httpMethod' => 'POST', 'parameters' => [ 'sourceBucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'sourceObject' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'destinationBucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'destinationObject' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'destinationKmsKeyName' => [ 'location' => 'query', 'type' => 'string', ], 'destinationPredefinedAcl' => [ 'location' => 'query', 'type' => 'string', ], 'ifGenerationMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifGenerationNotMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifMetagenerationMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifMetagenerationNotMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifSourceGenerationMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifSourceGenerationNotMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifSourceMetagenerationMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifSourceMetagenerationNotMatch' => [ 'location' => 'query', 'type' => 'string', ], 'projection' => [ 'location' => 'query', 'type' => 'string', ], 'sourceGeneration' => [ 'location' => 'query', 'type' => 'string', ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'delete' => [ 'path' => 'b/{bucket}/o/{object}', 'httpMethod' => 'DELETE', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'object' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'generation' => [ 'location' => 'query', 'type' => 'string', ], 'ifGenerationMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifGenerationNotMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifMetagenerationMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifMetagenerationNotMatch' => [ 'location' => 'query', 'type' => 'string', ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'get' => [ 'path' => 'b/{bucket}/o/{object}', 'httpMethod' => 'GET', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'object' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'generation' => [ 'location' => 'query', 'type' => 'string', ], 'ifGenerationMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifGenerationNotMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifMetagenerationMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifMetagenerationNotMatch' => [ 'location' => 'query', 'type' => 'string', ], 'projection' => [ 'location' => 'query', 'type' => 'string', ], 'restoreToken' => [ 'location' => 'query', 'type' => 'string', ], 'softDeleted' => [ 'location' => 'query', 'type' => 'boolean', ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'getIamPolicy' => [ 'path' => 'b/{bucket}/o/{object}/iam', 'httpMethod' => 'GET', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'object' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'generation' => [ 'location' => 'query', 'type' => 'string', ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'insert' => [ 'path' => 'b/{bucket}/o', 'httpMethod' => 'POST', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'contentEncoding' => [ 'location' => 'query', 'type' => 'string', ], 'ifGenerationMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifGenerationNotMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifMetagenerationMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifMetagenerationNotMatch' => [ 'location' => 'query', 'type' => 'string', ], 'kmsKeyName' => [ 'location' => 'query', 'type' => 'string', ], 'name' => [ 'location' => 'query', 'type' => 'string', ], 'predefinedAcl' => [ 'location' => 'query', 'type' => 'string', ], 'projection' => [ 'location' => 'query', 'type' => 'string', ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'list' => [ 'path' => 'b/{bucket}/o', 'httpMethod' => 'GET', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'delimiter' => [ 'location' => 'query', 'type' => 'string', ], 'endOffset' => [ 'location' => 'query', 'type' => 'string', ], 'filter' => [ 'location' => 'query', 'type' => 'string', ], 'includeFoldersAsPrefixes' => [ 'location' => 'query', 'type' => 'boolean', ], 'includeTrailingDelimiter' => [ 'location' => 'query', 'type' => 'boolean', ], 'matchGlob' => [ 'location' => 'query', 'type' => 'string', ], 'maxResults' => [ 'location' => 'query', 'type' => 'integer', ], 'pageToken' => [ 'location' => 'query', 'type' => 'string', ], 'prefix' => [ 'location' => 'query', 'type' => 'string', ], 'projection' => [ 'location' => 'query', 'type' => 'string', ], 'softDeleted' => [ 'location' => 'query', 'type' => 'boolean', ], 'startOffset' => [ 'location' => 'query', 'type' => 'string', ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], 'versions' => [ 'location' => 'query', 'type' => 'boolean', ], ], ],'move' => [ 'path' => 'b/{bucket}/o/{sourceObject}/moveTo/o/{destinationObject}', 'httpMethod' => 'POST', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'sourceObject' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'destinationObject' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'ifGenerationMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifGenerationNotMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifMetagenerationMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifMetagenerationNotMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifSourceGenerationMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifSourceGenerationNotMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifSourceMetagenerationMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifSourceMetagenerationNotMatch' => [ 'location' => 'query', 'type' => 'string', ], 'projection' => [ 'location' => 'query', 'type' => 'string', ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'patch' => [ 'path' => 'b/{bucket}/o/{object}', 'httpMethod' => 'PATCH', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'object' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'generation' => [ 'location' => 'query', 'type' => 'string', ], 'ifGenerationMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifGenerationNotMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifMetagenerationMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifMetagenerationNotMatch' => [ 'location' => 'query', 'type' => 'string', ], 'overrideUnlockedRetention' => [ 'location' => 'query', 'type' => 'boolean', ], 'predefinedAcl' => [ 'location' => 'query', 'type' => 'string', ], 'projection' => [ 'location' => 'query', 'type' => 'string', ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'restore' => [ 'path' => 'b/{bucket}/o/{object}/restore', 'httpMethod' => 'POST', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'object' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'generation' => [ 'location' => 'query', 'type' => 'string', 'required' => true, ], 'copySourceAcl' => [ 'location' => 'query', 'type' => 'boolean', ], 'ifGenerationMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifGenerationNotMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifMetagenerationMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifMetagenerationNotMatch' => [ 'location' => 'query', 'type' => 'string', ], 'projection' => [ 'location' => 'query', 'type' => 'string', ], 'restoreToken' => [ 'location' => 'query', 'type' => 'string', ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'rewrite' => [ 'path' => 'b/{sourceBucket}/o/{sourceObject}/rewriteTo/b/{destinationBucket}/o/{destinationObject}', 'httpMethod' => 'POST', 'parameters' => [ 'sourceBucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'sourceObject' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'destinationBucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'destinationObject' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'destinationKmsKeyName' => [ 'location' => 'query', 'type' => 'string', ], 'destinationPredefinedAcl' => [ 'location' => 'query', 'type' => 'string', ], 'ifGenerationMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifGenerationNotMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifMetagenerationMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifMetagenerationNotMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifSourceGenerationMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifSourceGenerationNotMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifSourceMetagenerationMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifSourceMetagenerationNotMatch' => [ 'location' => 'query', 'type' => 'string', ], 'maxBytesRewrittenPerCall' => [ 'location' => 'query', 'type' => 'string', ], 'projection' => [ 'location' => 'query', 'type' => 'string', ], 'rewriteToken' => [ 'location' => 'query', 'type' => 'string', ], 'sourceGeneration' => [ 'location' => 'query', 'type' => 'string', ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'setIamPolicy' => [ 'path' => 'b/{bucket}/o/{object}/iam', 'httpMethod' => 'PUT', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'object' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'generation' => [ 'location' => 'query', 'type' => 'string', ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'testIamPermissions' => [ 'path' => 'b/{bucket}/o/{object}/iam/testPermissions', 'httpMethod' => 'GET', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'object' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'permissions' => [ 'location' => 'query', 'type' => 'string', 'repeated' => true, 'required' => true, ], 'generation' => [ 'location' => 'query', 'type' => 'string', ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'update' => [ 'path' => 'b/{bucket}/o/{object}', 'httpMethod' => 'PUT', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'object' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'generation' => [ 'location' => 'query', 'type' => 'string', ], 'ifGenerationMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifGenerationNotMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifMetagenerationMatch' => [ 'location' => 'query', 'type' => 'string', ], 'ifMetagenerationNotMatch' => [ 'location' => 'query', 'type' => 'string', ], 'overrideUnlockedRetention' => [ 'location' => 'query', 'type' => 'boolean', ], 'predefinedAcl' => [ 'location' => 'query', 'type' => 'string', ], 'projection' => [ 'location' => 'query', 'type' => 'string', ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'watchAll' => [ 'path' => 'b/{bucket}/o/watch', 'httpMethod' => 'POST', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'delimiter' => [ 'location' => 'query', 'type' => 'string', ], 'endOffset' => [ 'location' => 'query', 'type' => 'string', ], 'includeTrailingDelimiter' => [ 'location' => 'query', 'type' => 'boolean', ], 'maxResults' => [ 'location' => 'query', 'type' => 'integer', ], 'pageToken' => [ 'location' => 'query', 'type' => 'string', ], 'prefix' => [ 'location' => 'query', 'type' => 'string', ], 'projection' => [ 'location' => 'query', 'type' => 'string', ], 'startOffset' => [ 'location' => 'query', 'type' => 'string', ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], 'versions' => [ 'location' => 'query', 'type' => 'boolean', ], ], ], ] ] ); $this->operations = new Storage\Resource\Operations( $this, $this->serviceName, 'operations', [ 'methods' => [ 'advanceRelocateBucket' => [ 'path' => 'b/{bucket}/operations/{operationId}/advanceRelocateBucket', 'httpMethod' => 'POST', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'operationId' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], ], ],'cancel' => [ 'path' => 'b/{bucket}/operations/{operationId}/cancel', 'httpMethod' => 'POST', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'operationId' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], ], ],'get' => [ 'path' => 'b/{bucket}/operations/{operationId}', 'httpMethod' => 'GET', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'operationId' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], ], ],'list' => [ 'path' => 'b/{bucket}/operations', 'httpMethod' => 'GET', 'parameters' => [ 'bucket' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'filter' => [ 'location' => 'query', 'type' => 'string', ], 'pageSize' => [ 'location' => 'query', 'type' => 'integer', ], 'pageToken' => [ 'location' => 'query', 'type' => 'string', ], ], ], ] ] ); $this->projects_hmacKeys = new Storage\Resource\ProjectsHmacKeys( $this, $this->serviceName, 'hmacKeys', [ 'methods' => [ 'create' => [ 'path' => 'projects/{projectId}/hmacKeys', 'httpMethod' => 'POST', 'parameters' => [ 'projectId' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'serviceAccountEmail' => [ 'location' => 'query', 'type' => 'string', 'required' => true, ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'delete' => [ 'path' => 'projects/{projectId}/hmacKeys/{accessId}', 'httpMethod' => 'DELETE', 'parameters' => [ 'projectId' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'accessId' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'get' => [ 'path' => 'projects/{projectId}/hmacKeys/{accessId}', 'httpMethod' => 'GET', 'parameters' => [ 'projectId' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'accessId' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'list' => [ 'path' => 'projects/{projectId}/hmacKeys', 'httpMethod' => 'GET', 'parameters' => [ 'projectId' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'maxResults' => [ 'location' => 'query', 'type' => 'integer', ], 'pageToken' => [ 'location' => 'query', 'type' => 'string', ], 'serviceAccountEmail' => [ 'location' => 'query', 'type' => 'string', ], 'showDeletedKeys' => [ 'location' => 'query', 'type' => 'boolean', ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ],'update' => [ 'path' => 'projects/{projectId}/hmacKeys/{accessId}', 'httpMethod' => 'PUT', 'parameters' => [ 'projectId' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'accessId' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ], ] ] ); $this->projects_serviceAccount = new Storage\Resource\ProjectsServiceAccount( $this, $this->serviceName, 'serviceAccount', [ 'methods' => [ 'get' => [ 'path' => 'projects/{projectId}/serviceAccount', 'httpMethod' => 'GET', 'parameters' => [ 'projectId' => [ 'location' => 'path', 'type' => 'string', 'required' => true, ], 'userProject' => [ 'location' => 'query', 'type' => 'string', ], ], ], ] ] ); } } // Adding a class alias for backwards compatibility with the previous class name. class_alias(Storage::class, 'Google_Service_Storage'); ================================================ FILE: lib/Google/vendor/google/auth/.repo-metadata.json ================================================ { "language": "php", "distribution_name": "google/auth", "release_level": "stable", "client_documentation": "https://cloud.google.com/php/docs/reference/auth/latest", "library_type": "CORE" } ================================================ FILE: lib/Google/vendor/google/auth/COPYING ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright 2015 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: lib/Google/vendor/google/auth/LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: lib/Google/vendor/google/auth/README.md ================================================ # Google Auth Library for PHP Reference Docs ## Description This is Google's officially supported PHP client library for using OAuth 2.0 authorization and authentication with Google APIs. ### Installing via Composer The recommended way to install the google auth library is through [Composer](http://getcomposer.org). ```bash # Install Composer curl -sS https://getcomposer.org/installer | php ``` Next, run the Composer command to install the latest stable version: ```bash composer.phar require google/auth ``` ## Application Default Credentials This library provides an implementation of [Application Default Credentials (ADC)][application default credentials] for PHP. Application Default Credentials provides a simple way to get authorization credentials for use in calling Google APIs, and is the recommended approach to authorize calls to Cloud APIs. **Important**: If you accept a credential configuration (credential JSON/File/Stream) from an external source for authentication to Google Cloud Platform, you must validate it before providing it to any Google API or library. Providing an unvalidated credential configuration to Google APIs can compromise the security of your systems and data. For more information, refer to [Validate credential configurations from external sources][externally-sourced-credentials]. [externally-sourced-credentials]: https://cloud.google.com/docs/authentication/external/externally-sourced-credentials ### Set up ADC To use ADC, you must set it up by providing credentials. How you set up ADC depends on the environment where your code is running, and whether you are running code in a test or production environment. For more information, see [Set up Application Default Credentials][set-up-adc]. ### Enable the API you want to use Before making your API call, you must be sure the API you're calling has been enabled. Go to **APIs & Auth** > **APIs** in the [Google Developers Console][developer console] and enable the APIs you'd like to call. For the example below, you must enable the `Drive API`. ### Call the APIs As long as you update the environment variable below to point to *your* JSON credentials file, the following code should output a list of your Drive files. ```php use Google\Auth\ApplicationDefaultCredentials; use GuzzleHttp\Client; use GuzzleHttp\HandlerStack; // specify the path to your application credentials putenv('GOOGLE_APPLICATION_CREDENTIALS=/path/to/my/credentials.json'); // define the scopes for your API call $scopes = ['https://www.googleapis.com/auth/drive.readonly']; // create middleware $middleware = ApplicationDefaultCredentials::getMiddleware($scopes); $stack = HandlerStack::create(); $stack->push($middleware); // create the HTTP client $client = new Client([ 'handler' => $stack, 'base_uri' => 'https://www.googleapis.com', 'auth' => 'google_auth' // authorize all requests ]); // make the request $response = $client->get('drive/v2/files'); // show the result! print_r((string) $response->getBody()); ``` ##### Guzzle 5 Compatibility If you are using [Guzzle 5][Guzzle 5], replace the `create middleware` and `create the HTTP Client` steps with the following: ```php // create the HTTP client $client = new Client([ 'base_url' => 'https://www.googleapis.com', 'auth' => 'google_auth' // authorize all requests ]); // create subscriber $subscriber = ApplicationDefaultCredentials::getSubscriber($scopes); $client->getEmitter()->attach($subscriber); ``` #### Call using an ID Token If your application is running behind Cloud Run, or using Cloud Identity-Aware Proxy (IAP), you will need to fetch an ID token to access your application. For this, use the static method `getIdTokenMiddleware` on `ApplicationDefaultCredentials`. ```php use Google\Auth\ApplicationDefaultCredentials; use GuzzleHttp\Client; use GuzzleHttp\HandlerStack; // specify the path to your application credentials putenv('GOOGLE_APPLICATION_CREDENTIALS=/path/to/my/credentials.json'); // Provide the ID token audience. This can be a Client ID associated with an IAP application, // Or the URL associated with a CloudRun App // $targetAudience = 'IAP_CLIENT_ID.apps.googleusercontent.com'; // $targetAudience = 'https://service-1234-uc.a.run.app'; $targetAudience = 'YOUR_ID_TOKEN_AUDIENCE'; // create middleware $middleware = ApplicationDefaultCredentials::getIdTokenMiddleware($targetAudience); $stack = HandlerStack::create(); $stack->push($middleware); // create the HTTP client $client = new Client([ 'handler' => $stack, 'auth' => 'google_auth', // Cloud Run, IAP, or custom resource URL 'base_uri' => 'https://YOUR_PROTECTED_RESOURCE', ]); // make the request $response = $client->get('/'); // show the result! print_r((string) $response->getBody()); ``` For invoking Cloud Run services, your service account will need the [`Cloud Run Invoker`](https://cloud.google.com/run/docs/authenticating/service-to-service) IAM permission. For invoking Cloud Identity-Aware Proxy, you will need to pass the Client ID used when you set up your protected resource as the target audience. See how to [secure your IAP app with signed headers](https://cloud.google.com/iap/docs/signed-headers-howto). #### Call using a specific JSON key If you want to use a specific JSON key instead of using `GOOGLE_APPLICATION_CREDENTIALS` environment variable, you can do this: ```php use Google\Auth\CredentialsLoader; use Google\Auth\Middleware\AuthTokenMiddleware; use GuzzleHttp\Client; use GuzzleHttp\HandlerStack; // Define the Google Application Credentials array $jsonKey = ['key' => 'value']; // define the scopes for your API call $scopes = ['https://www.googleapis.com/auth/drive.readonly']; // Load credentials from JSON containing service account credentials. $creds = new ServiceAccountCredentials($scopes, $jsonKey), // For other credentials types, create those classes explicitly using the // "type" field in the JSON key, for example: $creds = match ($jsonKey['type']) { 'service_account' => new ServiceAccountCredentials($scope, $jsonKey), 'authorized_user' => new UserRefreshCredentials($scope, $jsonKey), default => throw new InvalidArgumentException('This application only supports service account and user account credentials'), }; // optional caching $creds = new FetchAuthTokenCache($creds, $cacheConfig, $cache); // create middleware $middleware = new AuthTokenMiddleware($creds); $stack = HandlerStack::create(); $stack->push($middleware); // create the HTTP client $client = new Client([ 'handler' => $stack, 'base_uri' => 'https://www.googleapis.com', 'auth' => 'google_auth' // authorize all requests ]); // make the request $response = $client->get('drive/v2/files'); // show the result! print_r((string) $response->getBody()); ``` #### Call using Proxy-Authorization Header If your application is behind a proxy such as [Google Cloud IAP][iap-proxy-header], and your application occupies the `Authorization` request header, you can include the ID token in a `Proxy-Authorization: Bearer` header instead. If a valid ID token is found in a `Proxy-Authorization` header, IAP authorizes the request with it. After authorizing the request, IAP passes the Authorization header to your application without processing the content. For this, use the static method `getProxyIdTokenMiddleware` on `ApplicationDefaultCredentials`. ```php use Google\Auth\ApplicationDefaultCredentials; use GuzzleHttp\Client; use GuzzleHttp\HandlerStack; // specify the path to your application credentials putenv('GOOGLE_APPLICATION_CREDENTIALS=/path/to/my/credentials.json'); // Provide the ID token audience. This can be a Client ID associated with an IAP application // $targetAudience = 'IAP_CLIENT_ID.apps.googleusercontent.com'; $targetAudience = 'YOUR_ID_TOKEN_AUDIENCE'; // create middleware $middleware = ApplicationDefaultCredentials::getProxyIdTokenMiddleware($targetAudience); $stack = HandlerStack::create(); $stack->push($middleware); // create the HTTP client $client = new Client([ 'handler' => $stack, 'auth' => ['username', 'pass'], // auth option handled by your application 'proxy_auth' => 'google_auth', ]); // make the request $response = $client->get('/'); // show the result! print_r((string) $response->getBody()); ``` [iap-proxy-header]: https://cloud.google.com/iap/docs/authentication-howto#authenticating_from_proxy-authorization_header #### External credentials (Workload identity federation) Using workload identity federation, your application can access Google Cloud resources from Amazon Web Services (AWS), Microsoft Azure or any identity provider that supports OpenID Connect (OIDC). Traditionally, applications running outside Google Cloud have used service account keys to access Google Cloud resources. Using identity federation, you can allow your workload to impersonate a service account. This lets you access Google Cloud resources directly, eliminating the maintenance and security burden associated with service account keys. Follow the detailed instructions on how to [Configure Workload Identity Federation](https://cloud.google.com/iam/docs/workload-identity-federation-with-other-clouds). #### Verifying JWTs If you are [using Google ID tokens to authenticate users][google-id-tokens], use the `Google\Auth\AccessToken` class to verify the ID token: ```php use Google\Auth\AccessToken; $auth = new AccessToken(); $auth->verify($idToken); ``` If your app is running behind [Google Identity-Aware Proxy][iap-id-tokens] (IAP), you can verify the ID token coming from the IAP server by pointing to the appropriate certificate URL for IAP. This is because IAP signs the ID tokens with a different key than the Google Identity service: ```php use Google\Auth\AccessToken; $auth = new AccessToken(); $auth->verify($idToken, [ 'certsLocation' => AccessToken::IAP_CERT_URL ]); ``` [google-id-tokens]: https://developers.google.com/identity/sign-in/web/backend-auth [iap-id-tokens]: https://cloud.google.com/iap/docs/signed-headers-howto ## Caching Caching is enabled by passing a PSR-6 `CacheItemPoolInterface` instance to the constructor when instantiating the credentials. We offer some caching classes out of the box under the `Google\Auth\Cache` namespace. ```php use Google\Auth\ApplicationDefaultCredentials; use Google\Auth\Cache\MemoryCacheItemPool; // Cache Instance $memoryCache = new MemoryCacheItemPool; // Get the credentials // From here, the credentials will cache the access token $middleware = ApplicationDefaultCredentials::getCredentials($scope, cache: $memoryCache); ``` ### FileSystemCacheItemPool Cache The `FileSystemCacheItemPool` class is a `PSR-6` compliant cache that stores its serialized objects on disk, caching data between processes and making it possible to use data between different requests. ```php use Google\Auth\Cache\FileSystemCacheItemPool; use Google\Auth\ApplicationDefaultCredentials; // Create a Cache pool instance $cache = new FileSystemCacheItemPool(__DIR__ . '/cache'); // Pass your Cache to the Auth Library $credentials = ApplicationDefaultCredentials::getCredentials($scope, cache: $cache); // This token will be cached and be able to be used for the next request $token = $credentials->fetchAuthToken(); ``` ### Integrating with a third party cache You can use a third party that follows the `PSR-6` interface of your choice. ```php // run "composer require symfony/cache" use Google\Auth\ApplicationDefaultCredentials; use Symfony\Component\Cache\Adapter\FilesystemAdapter; // Create the cache instance $filesystemCache = new FilesystemAdapter(); // Create Get the credentials $credentials = ApplicationDefaultCredentials::getCredentials($targetAudience, cache: $filesystemCache); ``` ## License This library is licensed under Apache 2.0. Full license text is available in [COPYING][copying]. ## Contributing See [CONTRIBUTING][contributing]. ## Support Please [report bugs at the project on Github](https://github.com/google/google-auth-library-php/issues). Don't hesitate to [ask questions](http://stackoverflow.com/questions/tagged/google-auth-library-php) about the client or APIs on [StackOverflow](http://stackoverflow.com). [google-apis-php-client]: https://github.com/google/google-api-php-client [application default credentials]: https://cloud.google.com/docs/authentication/application-default-credentials [contributing]: https://github.com/google/google-auth-library-php/tree/main/.github/CONTRIBUTING.md [copying]: https://github.com/google/google-auth-library-php/tree/main/COPYING [Guzzle]: https://github.com/guzzle/guzzle [Guzzle 5]: http://docs.guzzlephp.org/en/5.3 [developer console]: https://console.developers.google.com [set-up-adc]: https://cloud.google.com/docs/authentication/provide-credentials-adc ================================================ FILE: lib/Google/vendor/google/auth/SECURITY.md ================================================ # Security Policy To report a security issue, please use [g.co/vulnz](https://g.co/vulnz). The Google Security Team will respond within 5 working days of your report on g.co/vulnz. We use g.co/vulnz for our intake, and do coordination and disclosure here using GitHub Security Advisory to privately discuss and fix the issue. ================================================ FILE: lib/Google/vendor/google/auth/VERSION ================================================ 1.50.0 ================================================ FILE: lib/Google/vendor/google/auth/composer.json ================================================ { "name": "google/auth", "type": "library", "description": "Google Auth Library for PHP", "keywords": ["google", "oauth2", "authentication"], "homepage": "https://github.com/google/google-auth-library-php", "license": "Apache-2.0", "support": { "docs": "https://cloud.google.com/php/docs/reference/auth/latest" }, "require": { "php": "^8.1", "firebase/php-jwt": "^6.0||^7.0", "guzzlehttp/guzzle": "^7.4.5", "guzzlehttp/psr7": "^2.4.5", "psr/http-message": "^1.1||^2.0", "psr/cache": "^2.0||^3.0", "psr/log": "^3.0" }, "require-dev": { "guzzlehttp/promises": "^2.0", "squizlabs/php_codesniffer": "^4.0", "phpunit/phpunit": "^9.6", "phpspec/prophecy-phpunit": "^2.1", "sebastian/comparator": ">=1.2.3", "phpseclib/phpseclib": "^3.0.35", "kelvinmo/simplejwt": "^1.1.0", "webmozart/assert": "^1.11||^2.0", "symfony/process": "^6.0||^7.0", "symfony/filesystem": "^6.3||^7.3" }, "suggest": { "phpseclib/phpseclib": "May be used in place of OpenSSL for signing strings or for token management. Please require version ^2." }, "autoload": { "psr-4": { "Google\\Auth\\": "src" } }, "autoload-dev": { "psr-4": { "Google\\Auth\\Tests\\": "tests" } } } ================================================ FILE: lib/Google/vendor/google/auth/src/AccessToken.php ================================================ httpHandler = $httpHandler ?: HttpHandlerFactory::build(HttpClientCache::getHttpClient()); $this->cache = $cache ?: new MemoryCacheItemPool(); } /** * Verifies an id token and returns the authenticated apiLoginTicket. * Throws an exception if the id token is not valid. * The audience parameter can be used to control which id tokens are * accepted. By default, the id token must have been issued to this OAuth2 client. * * @param string $token The JSON Web Token to be verified. * @param array $options [optional] { * Configuration options. * @type string $audience The indended recipient of the token. * @type string $issuer The intended issuer of the token. * @type string $cacheKey The cache key of the cached certs. Defaults to * the sha1 of $certsLocation if provided, otherwise is set to * "federated_signon_certs_v3". * @type string $certsLocation The location (remote or local) from which * to retrieve certificates, if not cached. This value should only be * provided in limited circumstances in which you are sure of the * behavior. * @type bool $throwException Whether the function should throw an * exception if the verification fails. This is useful for * determining the reason verification failed. * } * @return array|false the token payload, if successful, or false if not. * @throws InvalidArgumentException If certs could not be retrieved from a local file. * @throws InvalidArgumentException If received certs are in an invalid format. * @throws InvalidArgumentException If the cert alg is not supported. * @throws RuntimeException If certs could not be retrieved from a remote location. * @throws UnexpectedValueException If the token issuer does not match. * @throws UnexpectedValueException If the token audience does not match. */ public function verify($token, array $options = []) { $audience = $options['audience'] ?? null; $issuer = $options['issuer'] ?? null; $certsLocation = $options['certsLocation'] ?? self::FEDERATED_SIGNON_CERT_URL; $cacheKey = $options['cacheKey'] ?? $this->getCacheKeyFromCertLocation($certsLocation); $throwException = $options['throwException'] ?? false; // for backwards compatibility // Check signature against each available cert. $certs = $this->getCerts($certsLocation, $cacheKey, $options); $alg = $this->determineAlg($certs); if (!in_array($alg, ['RS256', 'ES256'])) { throw new InvalidArgumentException( 'unrecognized "alg" in certs, expected ES256 or RS256' ); } try { if ($alg == 'RS256') { return $this->verifyRs256($token, $certs, $audience, $issuer); } return $this->verifyEs256($token, $certs, $audience, $issuer); } catch (ExpiredException $e) { // firebase/php-jwt 5+ } catch (SignatureInvalidException $e) { // firebase/php-jwt 5+ } catch (InvalidTokenException $e) { // simplejwt } catch (InvalidArgumentException $e) { } catch (UnexpectedValueException $e) { } if ($throwException) { throw $e; } return false; } /** * Identifies the expected algorithm to verify by looking at the "alg" key * of the provided certs. * * @param array $certs Certificate array according to the JWK spec (see * https://tools.ietf.org/html/rfc7517). * @return string The expected algorithm, such as "ES256" or "RS256". */ private function determineAlg(array $certs) { $alg = null; foreach ($certs as $cert) { if (empty($cert['alg'])) { throw new InvalidArgumentException( 'certs expects "alg" to be set' ); } $alg = $alg ?: $cert['alg']; if ($alg != $cert['alg']) { throw new InvalidArgumentException( 'More than one alg detected in certs' ); } } return $alg; } /** * Verifies an ES256-signed JWT. * * @param string $token The JSON Web Token to be verified. * @param array $certs Certificate array according to the JWK spec (see * https://tools.ietf.org/html/rfc7517). * @param string|null $audience If set, returns false if the provided * audience does not match the "aud" claim on the JWT. * @param string|null $issuer If set, returns false if the provided * issuer does not match the "iss" claim on the JWT. * @return array the token payload, if successful, or false if not. */ private function verifyEs256($token, array $certs, $audience = null, $issuer = null) { $this->checkSimpleJwt(); $jwkset = new KeySet(); foreach ($certs as $cert) { $jwkset->add(KeyFactory::create($cert, 'php')); } // Validate the signature using the key set and ES256 algorithm. $jwt = $this->callSimpleJwtDecode([$token, $jwkset, 'ES256']); $payload = $jwt->getClaims(); if ($audience) { if (!isset($payload['aud']) || $payload['aud'] != $audience) { throw new UnexpectedValueException('Audience does not match'); } } // @see https://cloud.google.com/iap/docs/signed-headers-howto#verifying_the_jwt_payload $issuer = $issuer ?: self::IAP_ISSUER; if (!isset($payload['iss']) || $payload['iss'] !== $issuer) { throw new UnexpectedValueException('Issuer does not match'); } return $payload; } /** * Verifies an RS256-signed JWT. * * @param string $token The JSON Web Token to be verified. * @param array $certs Certificate array according to the JWK spec (see * https://tools.ietf.org/html/rfc7517). * @param string|null $audience If set, returns false if the provided * audience does not match the "aud" claim on the JWT. * @param string|null $issuer If set, returns false if the provided * issuer does not match the "iss" claim on the JWT. * @return array the token payload, if successful, or false if not. */ private function verifyRs256($token, array $certs, $audience = null, $issuer = null) { $this->checkAndInitializePhpsec(); $keys = []; foreach ($certs as $cert) { if (empty($cert['kid'])) { throw new InvalidArgumentException( 'certs expects "kid" to be set' ); } if (empty($cert['n']) || empty($cert['e'])) { throw new InvalidArgumentException( 'RSA certs expects "n" and "e" to be set' ); } $publicKey = $this->loadPhpsecPublicKey($cert['n'], $cert['e']); // create an array of key IDs to certs for the JWT library $keys[$cert['kid']] = new Key($publicKey, 'RS256'); } $payload = $this->callJwtStatic('decode', [ $token, $keys, ]); if ($audience) { if (!property_exists($payload, 'aud') || $payload->aud != $audience) { throw new UnexpectedValueException('Audience does not match'); } } // support HTTP and HTTPS issuers // @see https://developers.google.com/identity/sign-in/web/backend-auth $issuers = $issuer ? [$issuer] : [self::OAUTH2_ISSUER, self::OAUTH2_ISSUER_HTTPS]; if (!isset($payload->iss) || !in_array($payload->iss, $issuers)) { throw new UnexpectedValueException('Issuer does not match'); } return (array) $payload; } /** * Revoke an OAuth2 access token or refresh token. This method will revoke the current access * token, if a token isn't provided. * * @param string|array $token The token (access token or a refresh token) that should be revoked. * @param array $options [optional] Configuration options. * @return bool Returns True if the revocation was successful, otherwise False. */ public function revoke($token, array $options = []) { if (is_array($token)) { if (isset($token['refresh_token'])) { $token = $token['refresh_token']; } else { $token = $token['access_token']; } } $body = Utils::streamFor(http_build_query(['token' => $token])); $request = new Request('POST', self::OAUTH2_REVOKE_URI, [ 'Cache-Control' => 'no-store', 'Content-Type' => 'application/x-www-form-urlencoded', ], $body); $httpHandler = $this->httpHandler; $response = $httpHandler($request, $options); return $response->getStatusCode() == 200; } /** * Gets federated sign-on certificates to use for verifying identity tokens. * Returns certs as array structure, where keys are key ids, and values * are PEM encoded certificates. * * @param string $location The location from which to retrieve certs. * @param string $cacheKey The key under which to cache the retrieved certs. * @param array $options [optional] Configuration options. * @return array * @throws InvalidArgumentException If received certs are in an invalid format. */ private function getCerts($location, $cacheKey, array $options = []) { $cacheItem = $this->cache->getItem($cacheKey); $certs = $cacheItem ? $cacheItem->get() : null; $expireTime = null; if (!$certs) { list($certs, $expireTime) = $this->retrieveCertsFromLocation($location, $options); } if (!isset($certs['keys'])) { if ($location !== self::IAP_CERT_URL) { throw new InvalidArgumentException( 'federated sign-on certs expects "keys" to be set' ); } throw new InvalidArgumentException( 'certs expects "keys" to be set' ); } // Push caching off until after verifying certs are in a valid format. // Don't want to cache bad data. if ($expireTime) { $cacheItem->expiresAt(new DateTime($expireTime)); $cacheItem->set($certs); $this->cache->save($cacheItem); } return $certs['keys']; } /** * Retrieve and cache a certificates file. * * @param string $url location * @param array $options [optional] Configuration options. * @return array{array, string} * @throws InvalidArgumentException If certs could not be retrieved from a local file. * @throws RuntimeException If certs could not be retrieved from a remote location. */ private function retrieveCertsFromLocation($url, array $options = []) { // If we're retrieving a local file, just grab it. $expireTime = '+1 hour'; if (strpos($url, 'http') !== 0) { if (!file_exists($url)) { throw new InvalidArgumentException(sprintf( 'Failed to retrieve verification certificates from path: %s.', $url )); } return [ json_decode((string) file_get_contents($url), true), $expireTime ]; } $httpHandler = $this->httpHandler; $response = $httpHandler(new Request('GET', $url), $options); if ($response->getStatusCode() == 200) { if ($cacheControl = $response->getHeaderLine('Cache-Control')) { array_map(function ($value) use (&$expireTime) { list($key, $value) = explode('=', $value) + [null, null]; if (trim($key) == 'max-age') { $expireTime = '+' . $value . ' seconds'; } }, explode(',', $cacheControl)); } return [ json_decode((string) $response->getBody(), true), $expireTime ]; } throw new RuntimeException(sprintf( 'Failed to retrieve verification certificates: "%s".', $response->getBody()->getContents() ), $response->getStatusCode()); } /** * @return void */ private function checkAndInitializePhpsec() { if (!class_exists(RSA::class)) { throw new RuntimeException('Please require phpseclib/phpseclib v3 to use this utility.'); } } /** * @return string * @throws TypeError If the key cannot be initialized to a string. */ private function loadPhpsecPublicKey(string $modulus, string $exponent): string { $key = PublicKeyLoader::load([ 'n' => new BigInteger($this->callJwtStatic('urlsafeB64Decode', [ $modulus, ]), 256), 'e' => new BigInteger($this->callJwtStatic('urlsafeB64Decode', [ $exponent ]), 256), ]); $formattedPublicKey = $key->toString('PKCS8'); if (!is_string($formattedPublicKey)) { throw new TypeError('Failed to initialize the key'); } return $formattedPublicKey; } /** * @return void */ private function checkSimpleJwt() { // @codeCoverageIgnoreStart if (!class_exists(SimpleJwt::class)) { throw new RuntimeException('Please require kelvinmo/simplejwt ^0.2 to use this utility.'); } // @codeCoverageIgnoreEnd } /** * Provide a hook to mock calls to the JWT static methods. * * @param string $method * @param array $args * @return mixed */ protected function callJwtStatic($method, array $args = []) { return call_user_func_array([JWT::class, $method], $args); // @phpstan-ignore-line } /** * Provide a hook to mock calls to the JWT static methods. * * @param array $args * @return mixed */ protected function callSimpleJwtDecode(array $args = []) { return call_user_func_array([SimpleJwt::class, 'decode'], $args); } /** * Generate a cache key based on the cert location using sha1 with the * exception of using "federated_signon_certs_v3" to preserve BC. * * @param string $certsLocation * @return string */ private function getCacheKeyFromCertLocation($certsLocation) { $key = $certsLocation === self::FEDERATED_SIGNON_CERT_URL ? 'federated_signon_certs_v3' : sha1($certsLocation); return 'google_auth_certs_cache|' . $key; } } ================================================ FILE: lib/Google/vendor/google/auth/src/ApplicationDefaultCredentials.php ================================================ push($middleware); * * $client = new Client([ * 'handler' => $stack, * 'base_uri' => 'https://www.googleapis.com/taskqueue/v1beta2/projects/', * 'auth' => 'google_auth' // authorize all requests * ]); * * $res = $client->get('myproject/taskqueues/myqueue'); * ``` */ class ApplicationDefaultCredentials { private const SDK_DEBUG_ENV_VAR = 'GOOGLE_SDK_PHP_LOGGING'; /** * @deprecated * * Obtains an AuthTokenSubscriber that uses the default FetchAuthTokenInterface * implementation to use in this environment. * * If supplied, $scope is used to in creating the credentials instance if * this does not fallback to the compute engine defaults. * * @param string|string[] $scope the scope of the access request, expressed * either as an Array or as a space-delimited String. * @param callable|null $httpHandler callback which delivers psr7 request * @param array|null $cacheConfig configuration for the cache when it's present * @param CacheItemPoolInterface|null $cache A cache implementation, may be * provided if you have one already available for use. * @return AuthTokenSubscriber * @throws DomainException if no implementation can be obtained. */ public static function getSubscriber(// @phpstan-ignore-line $scope = null, ?callable $httpHandler = null, ?array $cacheConfig = null, ?CacheItemPoolInterface $cache = null ) { $creds = self::getCredentials($scope, $httpHandler, $cacheConfig, $cache); /** @phpstan-ignore-next-line */ return new AuthTokenSubscriber($creds, $httpHandler); } /** * Obtains an AuthTokenMiddleware that uses the default FetchAuthTokenInterface * implementation to use in this environment. * * If supplied, $scope is used to in creating the credentials instance if * this does not fallback to the compute engine defaults. * * @param string|string[] $scope the scope of the access request, expressed * either as an Array or as a space-delimited String. * @param callable|null $httpHandler callback which delivers psr7 request * @param array|null $cacheConfig configuration for the cache when it's present * @param CacheItemPoolInterface|null $cache A cache implementation, may be * provided if you have one already available for use. * @param string $quotaProject specifies a project to bill for access * charges associated with the request. * @return AuthTokenMiddleware * @throws DomainException if no implementation can be obtained. */ public static function getMiddleware( $scope = null, ?callable $httpHandler = null, ?array $cacheConfig = null, ?CacheItemPoolInterface $cache = null, $quotaProject = null ) { $creds = self::getCredentials($scope, $httpHandler, $cacheConfig, $cache, $quotaProject); return new AuthTokenMiddleware($creds, $httpHandler); } /** * Obtains the default FetchAuthTokenInterface implementation to use * in this environment. * * @param string|string[] $scope the scope of the access request, expressed * either as an Array or as a space-delimited String. * @param callable|null $httpHandler callback which delivers psr7 request * @param array|null $cacheConfig configuration for the cache when it's present * @param CacheItemPoolInterface|null $cache A cache implementation, may be * provided if you have one already available for use. * @param string|null $quotaProject specifies a project to bill for access * charges associated with the request. * @param string|string[]|null $defaultScope The default scope to use if no * user-defined scopes exist, expressed either as an Array or as a * space-delimited string. * @param string|null $universeDomain Specifies a universe domain to use for the * calling client library. * @param null|false|LoggerInterface $logger A PSR3 compliant LoggerInterface. * * @return FetchAuthTokenInterface * @throws DomainException if no implementation can be obtained. */ public static function getCredentials( $scope = null, ?callable $httpHandler = null, ?array $cacheConfig = null, ?CacheItemPoolInterface $cache = null, $quotaProject = null, $defaultScope = null, ?string $universeDomain = null, null|false|LoggerInterface $logger = null, ) { $creds = null; $jsonKey = CredentialsLoader::fromEnv() ?: CredentialsLoader::fromWellKnownFile(); $anyScope = $scope ?: $defaultScope; if (!$httpHandler) { if (!($client = HttpClientCache::getHttpClient())) { $client = new Client(); HttpClientCache::setHttpClient($client); } $httpHandler = HttpHandlerFactory::build($client, $logger); } if (is_null($quotaProject)) { // if a quota project isn't specified, try to get one from the env var $quotaProject = CredentialsLoader::quotaProjectFromEnv(); } if (!is_null($jsonKey)) { if ($quotaProject) { $jsonKey['quota_project_id'] = $quotaProject; } if ($universeDomain) { $jsonKey['universe_domain'] = $universeDomain; } $creds = CredentialsLoader::makeCredentials( $scope, $jsonKey, $defaultScope ); } elseif (AppIdentityCredentials::onAppEngine() && !GCECredentials::onAppEngineFlexible()) { $creds = new AppIdentityCredentials($anyScope); } elseif (self::onGce($httpHandler, $cacheConfig, $cache)) { $creds = new GCECredentials(null, $anyScope, null, $quotaProject, null, $universeDomain); $creds->setIsOnGce(true); // save the credentials a trip to the metadata server } if (is_null($creds)) { throw new DomainException(self::notFound()); } if (!is_null($cache)) { $creds = new FetchAuthTokenCache($creds, $cacheConfig, $cache); } return $creds; } /** * Obtains an AuthTokenMiddleware which will fetch an ID token to use in the * Authorization header. The middleware is configured with the default * FetchAuthTokenInterface implementation to use in this environment. * * If supplied, $targetAudience is used to set the "aud" on the resulting * ID token. * * @param string $targetAudience The audience for the ID token. * @param callable|null $httpHandler callback which delivers psr7 request * @param array|null $cacheConfig configuration for the cache when it's present * @param CacheItemPoolInterface|null $cache A cache implementation, may be * provided if you have one already available for use. * @return AuthTokenMiddleware * @throws DomainException if no implementation can be obtained. */ public static function getIdTokenMiddleware( $targetAudience, ?callable $httpHandler = null, ?array $cacheConfig = null, ?CacheItemPoolInterface $cache = null ) { $creds = self::getIdTokenCredentials($targetAudience, $httpHandler, $cacheConfig, $cache); return new AuthTokenMiddleware($creds, $httpHandler); } /** * Obtains an ProxyAuthTokenMiddleware which will fetch an ID token to use in the * Authorization header. The middleware is configured with the default * FetchAuthTokenInterface implementation to use in this environment. * * If supplied, $targetAudience is used to set the "aud" on the resulting * ID token. * * @param string $targetAudience The audience for the ID token. * @param callable|null $httpHandler callback which delivers psr7 request * @param array|null $cacheConfig configuration for the cache when it's present * @param CacheItemPoolInterface|null $cache A cache implementation, may be * provided if you have one already available for use. * @return ProxyAuthTokenMiddleware * @throws DomainException if no implementation can be obtained. */ public static function getProxyIdTokenMiddleware( $targetAudience, ?callable $httpHandler = null, ?array $cacheConfig = null, ?CacheItemPoolInterface $cache = null ) { $creds = self::getIdTokenCredentials($targetAudience, $httpHandler, $cacheConfig, $cache); return new ProxyAuthTokenMiddleware($creds, $httpHandler); } /** * Obtains the default FetchAuthTokenInterface implementation to use * in this environment, configured with a $targetAudience for fetching an ID * token. * * @param string $targetAudience The audience for the ID token. * @param callable|null $httpHandler callback which delivers psr7 request * @param array|null $cacheConfig configuration for the cache when it's present * @param CacheItemPoolInterface|null $cache A cache implementation, may be * provided if you have one already available for use. * @return FetchAuthTokenInterface * @throws DomainException if no implementation can be obtained. * @throws InvalidArgumentException if JSON "type" key is invalid */ public static function getIdTokenCredentials( $targetAudience, ?callable $httpHandler = null, ?array $cacheConfig = null, ?CacheItemPoolInterface $cache = null ) { $creds = null; $jsonKey = CredentialsLoader::fromEnv() ?: CredentialsLoader::fromWellKnownFile(); if (!$httpHandler) { if (!($client = HttpClientCache::getHttpClient())) { $client = new Client(); HttpClientCache::setHttpClient($client); } $httpHandler = HttpHandlerFactory::build($client); } if (!is_null($jsonKey)) { if (!array_key_exists('type', $jsonKey)) { throw new \InvalidArgumentException('json key is missing the type field'); } $creds = match ($jsonKey['type']) { 'authorized_user' => new UserRefreshCredentials(null, $jsonKey, $targetAudience), 'impersonated_service_account' => new ImpersonatedServiceAccountCredentials(null, $jsonKey, $targetAudience), 'service_account' => new ServiceAccountCredentials(null, $jsonKey, null, $targetAudience), default => throw new InvalidArgumentException('invalid value in the type field') }; } elseif (self::onGce($httpHandler, $cacheConfig, $cache)) { $creds = new GCECredentials(null, null, $targetAudience); $creds->setIsOnGce(true); // save the credentials a trip to the metadata server } if (is_null($creds)) { throw new DomainException(self::notFound()); } if (!is_null($cache)) { $creds = new FetchAuthTokenCache($creds, $cacheConfig, $cache); } return $creds; } /** * Returns a StdOutLogger instance * * @internal * * @return null|LoggerInterface */ public static function getDefaultLogger(): null|LoggerInterface { $loggingFlag = getenv(self::SDK_DEBUG_ENV_VAR); // Env var is not set if (empty($loggingFlag)) { return null; } $loggingFlag = strtolower($loggingFlag); // Env Var is not true if ($loggingFlag !== 'true') { if ($loggingFlag !== 'false') { trigger_error('The ' . self::SDK_DEBUG_ENV_VAR . ' is set, but it is set to another value than false or true. Logging is disabled'); } return null; } return new StdOutLogger(); } /** * @return string */ private static function notFound() { $msg = 'Your default credentials were not found. To set up '; $msg .= 'Application Default Credentials, see '; $msg .= 'https://cloud.google.com/docs/authentication/external/set-up-adc'; return $msg; } /** * @param callable|null $httpHandler * @param array|null $cacheConfig * @param CacheItemPoolInterface|null $cache * @return bool */ private static function onGce( ?callable $httpHandler = null, ?array $cacheConfig = null, ?CacheItemPoolInterface $cache = null ) { $gceCacheConfig = []; foreach (['lifetime', 'prefix'] as $key) { if (isset($cacheConfig['gce_' . $key])) { $gceCacheConfig[$key] = $cacheConfig['gce_' . $key]; } } return (new GCECache($gceCacheConfig, $cache))->onGce($httpHandler); } } ================================================ FILE: lib/Google/vendor/google/auth/src/Cache/FileSystemCacheItemPool.php ================================================ */ private array $buffer = []; /** * Creates a FileSystemCacheItemPool cache that stores values in local storage * * @param string $path The string representation of the path where the cache will store the serialized objects. */ public function __construct(string $path) { $this->cachePath = $path; if (is_dir($this->cachePath)) { return; } // Suppress the error for when the directory already exists because of a // race condition if (!@mkdir($this->cachePath, 0777, true) && !is_dir($this->cachePath)) { throw new ErrorException("Cache folder couldn't be created."); } } /** * {@inheritdoc} */ public function getItem(string $key): CacheItemInterface { if (!$this->validKey($key)) { throw new InvalidArgumentException("The key '$key' is not valid. The key should follow the pattern |^[a-zA-Z0-9_\.! ]+$|"); } $item = new TypedItem($key); $itemPath = $this->cacheFilePath($key); if (!file_exists($itemPath)) { return $item; } $serializedItem = file_get_contents($itemPath); if ($serializedItem === false) { return $item; } $item->set(unserialize($serializedItem)); return $item; } /** * {@inheritdoc} * * @return iterable An iterable object containing all the * A traversable collection of Cache Items keyed by the cache keys of * each item. A Cache item will be returned for each key, even if that * key is not found. However, if no keys are specified then an empty * traversable MUST be returned instead. */ public function getItems(array $keys = []): iterable { $result = []; foreach ($keys as $key) { $result[$key] = $this->getItem($key); } return $result; } /** * {@inheritdoc} */ public function save(CacheItemInterface $item): bool { if (!$this->validKey($item->getKey())) { return false; } $itemPath = $this->cacheFilePath($item->getKey()); $serializedItem = serialize($item->get()); $result = file_put_contents($itemPath, $serializedItem, LOCK_EX); // 0 bytes write is considered a successful operation if ($result === false) { return false; } return true; } /** * {@inheritdoc} */ public function hasItem(string $key): bool { return $this->getItem($key)->isHit(); } /** * {@inheritdoc} */ public function clear(): bool { $this->buffer = []; if (!is_dir($this->cachePath)) { return false; } $files = scandir($this->cachePath); if (!$files) { return false; } foreach ($files as $fileName) { if ($fileName === '.' || $fileName === '..') { continue; } if (!unlink($this->cachePath . '/' . $fileName)) { return false; } } return true; } /** * {@inheritdoc} */ public function deleteItem(string $key): bool { if (!$this->validKey($key)) { throw new InvalidArgumentException("The key '$key' is not valid. The key should follow the pattern |^[a-zA-Z0-9_\.! ]+$|"); } $itemPath = $this->cacheFilePath($key); if (!file_exists($itemPath)) { return true; } return unlink($itemPath); } /** * {@inheritdoc} */ public function deleteItems(array $keys): bool { $result = true; foreach ($keys as $key) { if (!$this->deleteItem($key)) { $result = false; } } return $result; } /** * {@inheritdoc} */ public function saveDeferred(CacheItemInterface $item): bool { array_push($this->buffer, $item); return true; } /** * {@inheritdoc} */ public function commit(): bool { $result = true; foreach ($this->buffer as $item) { if (!$this->save($item)) { $result = false; } } return $result; } private function cacheFilePath(string $key): string { return $this->cachePath . '/' . $key; } private function validKey(string $key): bool { return (bool) preg_match('|^[a-zA-Z0-9_\.]+$|', $key); } } ================================================ FILE: lib/Google/vendor/google/auth/src/Cache/InvalidArgumentException.php ================================================ getItems([$key])); // @phpstan-ignore-line } /** * {@inheritdoc} * * @return iterable * A traversable collection of Cache Items keyed by the cache keys of * each item. A Cache item will be returned for each key, even if that * key is not found. However, if no keys are specified then an empty * traversable MUST be returned instead. */ public function getItems(array $keys = []): iterable { $items = []; foreach ($keys as $key) { $items[$key] = $this->hasItem($key) ? clone $this->items[$key] : new TypedItem($key); } return $items; } /** * {@inheritdoc} * * @return bool * True if item exists in the cache, false otherwise. */ public function hasItem($key): bool { $this->isValidKey($key); return isset($this->items[$key]) && $this->items[$key]->isHit(); } /** * {@inheritdoc} * * @return bool * True if the pool was successfully cleared. False if there was an error. */ public function clear(): bool { $this->items = []; $this->deferredItems = []; return true; } /** * {@inheritdoc} * * @return bool * True if the item was successfully removed. False if there was an error. */ public function deleteItem($key): bool { return $this->deleteItems([$key]); } /** * {@inheritdoc} * * @return bool * True if the items were successfully removed. False if there was an error. */ public function deleteItems(array $keys): bool { array_walk($keys, [$this, 'isValidKey']); foreach ($keys as $key) { unset($this->items[$key]); } return true; } /** * {@inheritdoc} * * @return bool * True if the item was successfully persisted. False if there was an error. */ public function save(CacheItemInterface $item): bool { $this->items[$item->getKey()] = $item; return true; } /** * {@inheritdoc} * * @return bool * False if the item could not be queued or if a commit was attempted and failed. True otherwise. */ public function saveDeferred(CacheItemInterface $item): bool { $this->deferredItems[$item->getKey()] = $item; return true; } /** * {@inheritdoc} * * @return bool * True if all not-yet-saved items were successfully saved or there were none. False otherwise. */ public function commit(): bool { foreach ($this->deferredItems as $item) { $this->save($item); } $this->deferredItems = []; return true; } /** * Determines if the provided key is valid. * * @param string $key * @return bool * @throws InvalidArgumentException */ private function isValidKey($key) { $invalidCharacters = '{}()/\\\\@:'; if (!is_string($key) || preg_match("#[$invalidCharacters]#", $key)) { throw new InvalidArgumentException('The provided key is not valid: ' . var_export($key, true)); } return true; } } ================================================ FILE: lib/Google/vendor/google/auth/src/Cache/SysVCacheItemPool.php ================================================ */ private $options; /** * @var bool */ private $hasLoadedItems = false; /** * @var SysvSemaphore|false */ private SysvSemaphore|false $semId = false; /** * Maintain the process which is currently holding the semaphore to prevent deadlock. * * @var int|null */ private ?int $lockOwnerPid = null; /** * Create a SystemV shared memory based CacheItemPool. * * @param array $options { * [optional] Configuration options. * * @type int $variableKey The variable key for getting the data from the shared memory. **Defaults to** 1. * @type string $proj The project identifier for ftok. This needs to be a one character string. * **Defaults to** 'A'. * @type string $semProj The project identifier for ftok to provide to `sem_get`. This needs to be a one * character string. * **Defaults to** 'B'. * @type int $memsize The memory size in bytes for shm_attach. **Defaults to** 10000. * @type int $perm The permission for shm_attach. **Defaults to** 0600. * } */ public function __construct($options = []) { if (!extension_loaded('sysvshm')) { throw new \RuntimeException( 'sysvshm extension is required to use this ItemPool' ); } $this->options = $options + [ 'variableKey' => self::VAR_KEY, 'proj' => self::DEFAULT_PROJ, 'semProj' => self::DEFAULT_SEM_PROJ, 'memsize' => self::DEFAULT_MEMSIZE, 'perm' => self::DEFAULT_PERM ]; $this->items = []; $this->deferredItems = []; $this->sysvKey = ftok(__FILE__, $this->options['proj']); // gracefully handle when `sysvsem` isn't loaded // @TODO(v2): throw an exception when the extension isn't loaded if (extension_loaded('sysvsem')) { $semKey = ftok(__FILE__, $this->options['semProj']); $this->semId = sem_get($semKey, 1, $this->options['perm'], true); } } /** * @param mixed $key * @return CacheItemInterface */ public function getItem($key): CacheItemInterface { $this->loadItems(); return current($this->getItems([$key])); // @phpstan-ignore-line } /** * @param array $keys * @return iterable */ public function getItems(array $keys = []): iterable { $this->loadItems(); $items = []; foreach ($keys as $key) { $items[$key] = $this->hasItem($key) ? clone $this->items[$key] : new TypedItem($key); } return $items; } /** * {@inheritdoc} */ public function hasItem($key): bool { $this->loadItems(); return isset($this->items[$key]) && $this->items[$key]->isHit(); } /** * {@inheritdoc} */ public function clear(): bool { if (!$this->acquireLock()) { return false; } $this->items = []; $this->deferredItems = []; $ret = $this->saveCurrentItems(); $this->resetShm(); $this->releaseLock(); return $ret; } /** * {@inheritdoc} */ public function deleteItem($key): bool { return $this->deleteItems([$key]); } /** * {@inheritdoc} */ public function deleteItems(array $keys): bool { if (!$this->acquireLock()) { return false; } if (!$this->hasLoadedItems) { $this->loadItems(); } foreach ($keys as $key) { unset($this->items[$key]); } $ret = $this->saveCurrentItems(); $this->resetShm(); $this->releaseLock(); return $ret; } /** * {@inheritdoc} */ public function save(CacheItemInterface $item): bool { if (!$this->acquireLock()) { return false; } if (!$this->hasLoadedItems) { $this->loadItems(); } $this->items[$item->getKey()] = $item; $ret = $this->saveCurrentItems(); $this->releaseLock(); return $ret; } /** * {@inheritdoc} */ public function saveDeferred(CacheItemInterface $item): bool { $this->deferredItems[$item->getKey()] = $item; return true; } /** * {@inheritdoc} */ public function commit(): bool { if (!$this->acquireLock()) { return false; } foreach ($this->deferredItems as $item) { if ($this->save($item) === false) { $this->releaseLock(); return false; } } $this->deferredItems = []; $this->releaseLock(); return true; } /** * Save the current items. * * @return bool true when success, false upon failure */ private function saveCurrentItems() { if (!$this->acquireLock()) { return false; } if (false !== $shmid = $this->attachShm()) { $success = shm_put_var( $shmid, $this->options['variableKey'], $this->items ); shm_detach($shmid); $this->releaseLock(); return $success; } $this->releaseLock(); return false; } /** * Load the items from the shared memory. * * @return bool true when success, false upon failure */ private function loadItems() { if (!$this->acquireLock()) { return false; } if (false !== $shmid = $this->attachShm()) { $data = @shm_get_var($shmid, $this->options['variableKey']); $this->items = $data ?: []; shm_detach($shmid); $this->hasLoadedItems = true; $this->releaseLock(); return true; } $this->releaseLock(); return false; } private function acquireLock(): bool { if ($this->semId === false) { // if `sysvsem` isn't loaded, or if `sem_get` fails, return true // this ensures BC with previous versions of the auth library. // @TODO consider better handling when `sem_get` fails. return true; } $currentPid = getmypid(); if ($this->lockOwnerPid === $currentPid) { // We already have the lock return true; } if (sem_acquire($this->semId)) { $this->lockOwnerPid = (int) $currentPid; return true; } return false; } private function releaseLock(): bool { if ($this->semId === false || $this->lockOwnerPid !== getmypid()) { return true; } $this->lockOwnerPid = null; return sem_release($this->semId); } private function resetShm(): void { // Remove the shared memory segment and semaphore when clearing the cache $shmid = @shm_attach($this->sysvKey); if ($shmid !== false) { @shm_remove($shmid); @shm_detach($shmid); } } private function attachShm(): SysvSharedMemory|false { return shm_attach( $this->sysvKey, $this->options['memsize'], $this->options['perm'] ); } } ================================================ FILE: lib/Google/vendor/google/auth/src/Cache/TypedItem.php ================================================ key = $key; $this->expiration = null; } /** * {@inheritdoc} */ public function getKey(): string { return $this->key; } /** * {@inheritdoc} */ public function get(): mixed { return $this->isHit() ? $this->value : null; } /** * {@inheritdoc} */ public function isHit(): bool { if (!$this->isHit) { return false; } if ($this->expiration === null) { return true; } return $this->currentTime()->getTimestamp() < $this->expiration->getTimestamp(); } /** * {@inheritdoc} */ public function set(mixed $value): static { $this->isHit = true; $this->value = $value; return $this; } /** * {@inheritdoc} */ public function expiresAt($expiration): static { if ($this->isValidExpiration($expiration)) { $this->expiration = $expiration; return $this; } $error = sprintf( 'Argument 1 passed to %s::expiresAt() must implement interface DateTimeInterface, %s given', get_class($this), gettype($expiration) ); throw new \TypeError($error); } /** * {@inheritdoc} */ public function expiresAfter($time): static { if (is_int($time)) { $this->expiration = $this->currentTime()->add(new \DateInterval("PT{$time}S")); } elseif ($time instanceof \DateInterval) { $this->expiration = $this->currentTime()->add($time); } elseif ($time === null) { $this->expiration = $time; } else { $message = 'Argument 1 passed to %s::expiresAfter() must be an ' . 'instance of DateInterval or of the type integer, %s given'; $error = sprintf($message, get_class($this), gettype($time)); throw new \TypeError($error); } return $this; } /** * Determines if an expiration is valid based on the rules defined by PSR6. * * @param mixed $expiration * @return bool */ private function isValidExpiration($expiration) { if ($expiration === null) { return true; } // We test for two types here due to the fact the DateTimeInterface // was not introduced until PHP 5.5. Checking for the DateTime type as // well allows us to support 5.4. if ($expiration instanceof \DateTimeInterface) { return true; } return false; } /** * @return \DateTime */ protected function currentTime() { return new \DateTime('now', new \DateTimeZone('UTC')); } } ================================================ FILE: lib/Google/vendor/google/auth/src/CacheTrait.php ================================================ */ private $cacheConfig; /** * @var ?CacheItemPoolInterface */ private $cache; /** * Gets the cached value if it is present in the cache when that is * available. * * @param mixed $k * * @return mixed */ private function getCachedValue($k) { if (is_null($this->cache)) { return null; } $key = $this->getFullCacheKey($k); if (is_null($key)) { return null; } $cacheItem = $this->cache->getItem($key); if ($cacheItem->isHit()) { return $cacheItem->get(); } } /** * Saves the value in the cache when that is available. * * @param mixed $k * @param mixed $v * @return mixed */ private function setCachedValue($k, $v) { if (is_null($this->cache)) { return null; } $key = $this->getFullCacheKey($k); if (is_null($key)) { return null; } $cacheItem = $this->cache->getItem($key); $cacheItem->set($v); $cacheItem->expiresAfter($this->cacheConfig['lifetime']); return $this->cache->save($cacheItem); } /** * @param null|string $key * @return null|string */ private function getFullCacheKey($key) { if (is_null($key)) { return null; } $key = ($this->cacheConfig['prefix'] ?? '') . $key; // ensure we do not have illegal characters $key = preg_replace('|[^a-zA-Z0-9_\.!]|', '', $key); // Hash keys if they exceed $maxKeyLength (defaults to 64) if ($this->maxKeyLength && strlen($key) > $this->maxKeyLength) { $key = substr(hash('sha256', $key), 0, $this->maxKeyLength); } return $key; } } ================================================ FILE: lib/Google/vendor/google/auth/src/CredentialSource/AwsNativeSource.php ================================================ audience = $audience; $this->regionalCredVerificationUrl = $regionalCredVerificationUrl; $this->regionUrl = $regionUrl; $this->securityCredentialsUrl = $securityCredentialsUrl; $this->imdsv2SessionTokenUrl = $imdsv2SessionTokenUrl; } public function fetchSubjectToken(?callable $httpHandler = null): string { if (is_null($httpHandler)) { $httpHandler = HttpHandlerFactory::build(HttpClientCache::getHttpClient()); } $headers = []; if ($this->imdsv2SessionTokenUrl) { $headers = [ 'X-aws-ec2-metadata-token' => self::getImdsV2SessionToken($this->imdsv2SessionTokenUrl, $httpHandler) ]; } if (!$signingVars = self::getSigningVarsFromEnv()) { if (!$this->securityCredentialsUrl) { throw new \LogicException('Unable to get credentials from ENV, and no security credentials URL provided'); } $signingVars = self::getSigningVarsFromUrl( $httpHandler, $this->securityCredentialsUrl, self::getRoleName($httpHandler, $this->securityCredentialsUrl, $headers), $headers ); } if (!$region = self::getRegionFromEnv()) { if (!$this->regionUrl) { throw new \LogicException('Unable to get region from ENV, and no region URL provided'); } $region = self::getRegionFromUrl($httpHandler, $this->regionUrl, $headers); } $url = str_replace('{region}', $region, $this->regionalCredVerificationUrl); $host = parse_url($url)['host'] ?? ''; // From here we use the signing vars to create the signed request to receive a token [$accessKeyId, $secretAccessKey, $securityToken] = $signingVars; $headers = self::getSignedRequestHeaders($region, $host, $accessKeyId, $secretAccessKey, $securityToken); // Inject x-goog-cloud-target-resource into header $headers['x-goog-cloud-target-resource'] = $this->audience; // Format headers as they're expected in the subject token $formattedHeaders = array_map( fn ($k, $v) => ['key' => $k, 'value' => $v], array_keys($headers), $headers, ); $request = [ 'headers' => $formattedHeaders, 'method' => 'POST', 'url' => $url, ]; return urlencode(json_encode($request) ?: ''); } /** * @internal */ public static function getImdsV2SessionToken(string $imdsV2Url, callable $httpHandler): string { $headers = [ 'X-aws-ec2-metadata-token-ttl-seconds' => '21600' ]; $request = new Request( 'PUT', $imdsV2Url, $headers ); $response = $httpHandler($request); return (string) $response->getBody(); } /** * @see http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html * * @internal * * @return array */ public static function getSignedRequestHeaders( string $region, string $host, string $accessKeyId, string $secretAccessKey, ?string $securityToken ): array { $service = 'sts'; # Create a date for headers and the credential string in ISO-8601 format $amzdate = gmdate('Ymd\THis\Z'); $datestamp = gmdate('Ymd'); # Date w/o time, used in credential scope # Create the canonical headers and signed headers. Header names # must be trimmed and lowercase, and sorted in code point order from # low to high. Note that there is a trailing \n. $canonicalHeaders = sprintf("host:%s\nx-amz-date:%s\n", $host, $amzdate); if ($securityToken) { $canonicalHeaders .= sprintf("x-amz-security-token:%s\n", $securityToken); } # Step 5: Create the list of signed headers. This lists the headers # in the canonicalHeaders list, delimited with ";" and in alpha order. # Note: The request can include any headers; $canonicalHeaders and # $signedHeaders lists those that you want to be included in the # hash of the request. "Host" and "x-amz-date" are always required. $signedHeaders = 'host;x-amz-date'; if ($securityToken) { $signedHeaders .= ';x-amz-security-token'; } # Step 6: Create payload hash (hash of the request body content). For GET # requests, the payload is an empty string (""). $payloadHash = hash('sha256', ''); # Step 7: Combine elements to create canonical request $canonicalRequest = implode("\n", [ 'POST', // method '/', // canonical URL self::CRED_VERIFICATION_QUERY, // query string $canonicalHeaders, $signedHeaders, $payloadHash ]); # ************* TASK 2: CREATE THE STRING TO SIGN************* # Match the algorithm to the hashing algorithm you use, either SHA-1 or # SHA-256 (recommended) $algorithm = 'AWS4-HMAC-SHA256'; $scope = implode('/', [$datestamp, $region, $service, 'aws4_request']); $stringToSign = implode("\n", [$algorithm, $amzdate, $scope, hash('sha256', $canonicalRequest)]); # ************* TASK 3: CALCULATE THE SIGNATURE ************* # Create the signing key using the function defined above. // (done above) $signingKey = self::getSignatureKey($secretAccessKey, $datestamp, $region, $service); # Sign the string_to_sign using the signing_key $signature = bin2hex(self::hmacSign($signingKey, $stringToSign)); # ************* TASK 4: ADD SIGNING INFORMATION TO THE REQUEST ************* # The signing information can be either in a query string value or in # a header named Authorization. This code shows how to use a header. # Create authorization header and add to request headers $authorizationHeader = sprintf( '%s Credential=%s/%s, SignedHeaders=%s, Signature=%s', $algorithm, $accessKeyId, $scope, $signedHeaders, $signature ); # The request can include any headers, but MUST include "host", "x-amz-date", # and (for this scenario) "Authorization". "host" and "x-amz-date" must # be included in the canonical_headers and signed_headers, as noted # earlier. Order here is not significant. $headers = [ 'host' => $host, 'x-amz-date' => $amzdate, 'Authorization' => $authorizationHeader, ]; if ($securityToken) { $headers['x-amz-security-token'] = $securityToken; } return $headers; } /** * @internal */ public static function getRegionFromEnv(): ?string { $region = getenv('AWS_REGION'); if (empty($region)) { $region = getenv('AWS_DEFAULT_REGION'); } return $region ?: null; } /** * @internal * * @param callable $httpHandler * @param string $regionUrl * @param array $headers Request headers to send in with the request. */ public static function getRegionFromUrl(callable $httpHandler, string $regionUrl, array $headers): string { // get the region/zone from the region URL $regionRequest = new Request('GET', $regionUrl, $headers); $regionResponse = $httpHandler($regionRequest); // Remove last character. For example, if us-east-2b is returned, // the region would be us-east-2. return substr((string) $regionResponse->getBody(), 0, -1); } /** * @internal * * @param callable $httpHandler * @param string $securityCredentialsUrl * @param array $headers Request headers to send in with the request. */ public static function getRoleName(callable $httpHandler, string $securityCredentialsUrl, array $headers): string { // Get the AWS role name $roleRequest = new Request('GET', $securityCredentialsUrl, $headers); $roleResponse = $httpHandler($roleRequest); $roleName = (string) $roleResponse->getBody(); return $roleName; } /** * @internal * * @param callable $httpHandler * @param string $securityCredentialsUrl * @param array $headers Request headers to send in with the request. * @return array{string, string, ?string} */ public static function getSigningVarsFromUrl( callable $httpHandler, string $securityCredentialsUrl, string $roleName, array $headers ): array { // Get the AWS credentials $credsRequest = new Request( 'GET', $securityCredentialsUrl . '/' . $roleName, $headers ); $credsResponse = $httpHandler($credsRequest); $awsCreds = json_decode((string) $credsResponse->getBody(), true); return [ $awsCreds['AccessKeyId'], // accessKeyId $awsCreds['SecretAccessKey'], // secretAccessKey $awsCreds['Token'], // token ]; } /** * @internal * * @return array{string, string, ?string} */ public static function getSigningVarsFromEnv(): ?array { $accessKeyId = getenv('AWS_ACCESS_KEY_ID'); $secretAccessKey = getenv('AWS_SECRET_ACCESS_KEY'); if ($accessKeyId && $secretAccessKey) { return [ $accessKeyId, $secretAccessKey, getenv('AWS_SESSION_TOKEN') ?: null, // session token (can be null) ]; } return null; } /** * Gets the unique key for caching * For AwsNativeSource the values are: * Imdsv2SessionTokenUrl.SecurityCredentialsUrl.RegionUrl.RegionalCredVerificationUrl * * @return string */ public function getCacheKey(): string { return ($this->imdsv2SessionTokenUrl ?? '') . '.' . ($this->securityCredentialsUrl ?? '') . '.' . $this->regionUrl . '.' . $this->regionalCredVerificationUrl; } /** * Return HMAC hash in binary string */ private static function hmacSign(string $key, string $msg): string { return hash_hmac('sha256', self::utf8Encode($msg), $key, true); } /** * @TODO add a fallback when mbstring is not available */ private static function utf8Encode(string $string): string { return (string) mb_convert_encoding($string, 'UTF-8', 'ISO-8859-1'); } private static function getSignatureKey( string $key, string $dateStamp, string $regionName, string $serviceName ): string { $kDate = self::hmacSign(self::utf8Encode('AWS4' . $key), $dateStamp); $kRegion = self::hmacSign($kDate, $regionName); $kService = self::hmacSign($kRegion, $serviceName); $kSigning = self::hmacSign($kService, 'aws4_request'); return $kSigning; } } ================================================ FILE: lib/Google/vendor/google/auth/src/CredentialSource/ExecutableSource.php ================================================ * OIDC response sample: * { * "version": 1, * "success": true, * "token_type": "urn:ietf:params:oauth:token-type:id_token", * "id_token": "HEADER.PAYLOAD.SIGNATURE", * "expiration_time": 1620433341 * } * * SAML2 response sample: * { * "version": 1, * "success": true, * "token_type": "urn:ietf:params:oauth:token-type:saml2", * "saml_response": "...", * "expiration_time": 1620433341 * } * * Error response sample: * { * "version": 1, * "success": false, * "code": "401", * "message": "Error message." * } * * * The "expiration_time" field in the JSON response is only required for successful * responses when an output file was specified in the credential configuration * * The auth libraries will populate certain environment variables that will be accessible by the * executable, such as: GOOGLE_EXTERNAL_ACCOUNT_AUDIENCE, GOOGLE_EXTERNAL_ACCOUNT_TOKEN_TYPE, * GOOGLE_EXTERNAL_ACCOUNT_INTERACTIVE, GOOGLE_EXTERNAL_ACCOUNT_IMPERSONATED_EMAIL, and * GOOGLE_EXTERNAL_ACCOUNT_OUTPUT_FILE. */ class ExecutableSource implements ExternalAccountCredentialSourceInterface { private const GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES = 'GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES'; private const SAML_SUBJECT_TOKEN_TYPE = 'urn:ietf:params:oauth:token-type:saml2'; private const OIDC_SUBJECT_TOKEN_TYPE1 = 'urn:ietf:params:oauth:token-type:id_token'; private const OIDC_SUBJECT_TOKEN_TYPE2 = 'urn:ietf:params:oauth:token-type:jwt'; private string $command; private ExecutableHandler $executableHandler; private ?string $outputFile; /** * @param string $command The string command to run to get the subject token. * @param string|null $outputFile */ public function __construct( string $command, ?string $outputFile, ?ExecutableHandler $executableHandler = null, ) { $this->command = $command; $this->outputFile = $outputFile; $this->executableHandler = $executableHandler ?: new ExecutableHandler(); } /** * Gets the unique key for caching * The format for the cache key is: * Command.OutputFile * * @return ?string */ public function getCacheKey(): ?string { return $this->command . '.' . $this->outputFile; } /** * @param callable|null $httpHandler unused. * @return string * @throws RuntimeException if the executable is not allowed to run. * @throws ExecutableResponseError if the executable response is invalid. */ public function fetchSubjectToken(?callable $httpHandler = null): string { // Check if the executable is allowed to run. if (getenv(self::GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES) !== '1') { throw new RuntimeException( 'Pluggable Auth executables need to be explicitly allowed to run by ' . 'setting the GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES environment ' . 'Variable to 1.' ); } if (!$executableResponse = $this->getCachedExecutableResponse()) { // Run the executable. $exitCode = ($this->executableHandler)($this->command); $output = $this->executableHandler->getOutput(); // If the exit code is not 0, throw an exception with the output as the error details if ($exitCode !== 0) { throw new ExecutableResponseError( 'The executable failed to run' . ($output ? ' with the following error: ' . $output : '.'), (string) $exitCode ); } $executableResponse = $this->parseExecutableResponse($output); // Validate expiration. if (isset($executableResponse['expiration_time']) && time() >= $executableResponse['expiration_time']) { throw new ExecutableResponseError('Executable response is expired.'); } } // Throw error when the request was unsuccessful if ($executableResponse['success'] === false) { throw new ExecutableResponseError($executableResponse['message'], (string) $executableResponse['code']); } // Return subject token field based on the token type return $executableResponse['token_type'] === self::SAML_SUBJECT_TOKEN_TYPE ? $executableResponse['saml_response'] : $executableResponse['id_token']; } /** * @return array|null */ private function getCachedExecutableResponse(): ?array { if ( $this->outputFile && file_exists($this->outputFile) && !empty(trim($outputFileContents = (string) file_get_contents($this->outputFile))) ) { try { $executableResponse = $this->parseExecutableResponse($outputFileContents); } catch (ExecutableResponseError $e) { throw new ExecutableResponseError( 'Error in output file: ' . $e->getMessage(), 'INVALID_OUTPUT_FILE' ); } if ($executableResponse['success'] === false) { // If the cached token was unsuccessful, run the executable to get a new one. return null; } if (isset($executableResponse['expiration_time']) && time() >= $executableResponse['expiration_time']) { // If the cached token is expired, run the executable to get a new one. return null; } return $executableResponse; } return null; } /** * @return array */ private function parseExecutableResponse(string $response): array { $executableResponse = json_decode($response, true); if (json_last_error() !== JSON_ERROR_NONE) { throw new ExecutableResponseError( 'The executable returned an invalid response: ' . $response, 'INVALID_RESPONSE' ); } if (!array_key_exists('version', $executableResponse)) { throw new ExecutableResponseError('Executable response must contain a "version" field.'); } if (!array_key_exists('success', $executableResponse)) { throw new ExecutableResponseError('Executable response must contain a "success" field.'); } // Validate required fields for a successful response. if ($executableResponse['success']) { // Validate token type field. $tokenTypes = [self::SAML_SUBJECT_TOKEN_TYPE, self::OIDC_SUBJECT_TOKEN_TYPE1, self::OIDC_SUBJECT_TOKEN_TYPE2]; if (!isset($executableResponse['token_type'])) { throw new ExecutableResponseError( 'Executable response must contain a "token_type" field when successful' ); } if (!in_array($executableResponse['token_type'], $tokenTypes)) { throw new ExecutableResponseError(sprintf( 'Executable response "token_type" field must be one of %s.', implode(', ', $tokenTypes) )); } // Validate subject token for SAML and OIDC. if ($executableResponse['token_type'] === self::SAML_SUBJECT_TOKEN_TYPE) { if (empty($executableResponse['saml_response'])) { throw new ExecutableResponseError(sprintf( 'Executable response must contain a "saml_response" field when token_type=%s.', self::SAML_SUBJECT_TOKEN_TYPE )); } } elseif (empty($executableResponse['id_token'])) { throw new ExecutableResponseError(sprintf( 'Executable response must contain a "id_token" field when ' . 'token_type=%s.', $executableResponse['token_type'] )); } // Validate expiration exists when an output file is specified. if ($this->outputFile) { if (!isset($executableResponse['expiration_time'])) { throw new ExecutableResponseError( 'The executable response must contain a "expiration_time" field for successful responses ' . 'when an output_file has been specified in the configuration.' ); } } } else { // Both code and message must be provided for unsuccessful responses. if (!array_key_exists('code', $executableResponse)) { throw new ExecutableResponseError('Executable response must contain a "code" field when unsuccessful.'); } if (empty($executableResponse['message'])) { throw new ExecutableResponseError('Executable response must contain a "message" field when unsuccessful.'); } } return $executableResponse; } } ================================================ FILE: lib/Google/vendor/google/auth/src/CredentialSource/FileSource.php ================================================ file = $file; if ($format === 'json' && is_null($subjectTokenFieldName)) { throw new InvalidArgumentException( 'subject_token_field_name must be set when format is JSON' ); } $this->format = $format; $this->subjectTokenFieldName = $subjectTokenFieldName; } public function fetchSubjectToken(?callable $httpHandler = null): string { $contents = file_get_contents($this->file); if ($this->format === 'json') { if (!$json = json_decode((string) $contents, true)) { throw new UnexpectedValueException( 'Unable to decode JSON file' ); } if (!isset($json[$this->subjectTokenFieldName])) { throw new UnexpectedValueException( 'subject_token_field_name not found in JSON file' ); } $contents = $json[$this->subjectTokenFieldName]; } return $contents; } /** * Gets the unique key for caching. * The format for the cache key one of the following: * Filename * * @return string */ public function getCacheKey(): ?string { return $this->file; } } ================================================ FILE: lib/Google/vendor/google/auth/src/CredentialSource/UrlSource.php ================================================ */ private ?array $headers; /** * @param string $url The URL to fetch the subject token from. * @param string|null $format The format of the token in the response. Can be null or "json". * @param string|null $subjectTokenFieldName The name of the field containing the token in the response. This is required * when format is "json". * @param array|null $headers Request headers to send in with the request to the URL. */ public function __construct( string $url, ?string $format = null, ?string $subjectTokenFieldName = null, ?array $headers = null ) { $this->url = $url; if ($format === 'json' && is_null($subjectTokenFieldName)) { throw new InvalidArgumentException( 'subject_token_field_name must be set when format is JSON' ); } $this->format = $format; $this->subjectTokenFieldName = $subjectTokenFieldName; $this->headers = $headers; } public function fetchSubjectToken(?callable $httpHandler = null): string { if (is_null($httpHandler)) { $httpHandler = HttpHandlerFactory::build(HttpClientCache::getHttpClient()); } $request = new Request( 'GET', $this->url, $this->headers ?: [] ); $response = $httpHandler($request); $body = (string) $response->getBody(); if ($this->format === 'json') { if (!$json = json_decode((string) $body, true)) { throw new UnexpectedValueException( 'Unable to decode JSON response' ); } if (!isset($json[$this->subjectTokenFieldName])) { throw new UnexpectedValueException( 'subject_token_field_name not found in JSON file' ); } $body = $json[$this->subjectTokenFieldName]; } return $body; } /** * Get the cache key for the credentials. * The format for the cache key is: * URL * * @return ?string */ public function getCacheKey(): ?string { return $this->url; } } ================================================ FILE: lib/Google/vendor/google/auth/src/Credentials/AppIdentityCredentials.php ================================================ push($middleware); * * $client = new Client([ * 'handler' => $stack, * 'base_uri' => 'https://www.googleapis.com/books/v1', * 'auth' => 'google_auth' * ]); * * $res = $client->get('volumes?q=Henry+David+Thoreau&country=US'); * ``` */ class AppIdentityCredentials extends CredentialsLoader implements SignBlobInterface, ProjectIdProviderInterface { /** * Result of fetchAuthToken. * * @var array */ protected $lastReceivedToken; /** * Array of OAuth2 scopes to be requested. * * @var string[] */ private $scope; /** * @var string */ private $clientName; /** * @param string|string[] $scope One or more scopes. */ public function __construct($scope = []) { $this->scope = is_array($scope) ? $scope : explode(' ', (string) $scope); } /** * Determines if this an App Engine instance, by accessing the * SERVER_SOFTWARE environment variable (prod) or the APPENGINE_RUNTIME * environment variable (dev). * * @return bool true if this an App Engine Instance, false otherwise */ public static function onAppEngine() { $appEngineProduction = isset($_SERVER['SERVER_SOFTWARE']) && 0 === strpos($_SERVER['SERVER_SOFTWARE'], 'Google App Engine'); if ($appEngineProduction) { return true; } $appEngineDevAppServer = isset($_SERVER['APPENGINE_RUNTIME']) && $_SERVER['APPENGINE_RUNTIME'] == 'php'; if ($appEngineDevAppServer) { return true; } return false; } /** * Implements FetchAuthTokenInterface#fetchAuthToken. * * Fetches the auth tokens using the AppIdentityService if available. * As the AppIdentityService uses protobufs to fetch the access token, * the GuzzleHttp\ClientInterface instance passed in will not be used. * * @param callable|null $httpHandler callback which delivers psr7 request * @return array { * A set of auth related metadata, containing the following * * @type string $access_token * @type string $expiration_time * } */ public function fetchAuthToken(?callable $httpHandler = null) { try { $this->checkAppEngineContext(); } catch (\Exception $e) { return []; } /** @phpstan-ignore-next-line */ $token = AppIdentityService::getAccessToken($this->scope); $this->lastReceivedToken = $token; return $token; } /** * Sign a string using AppIdentityService. * * @param string $stringToSign The string to sign. * @param bool $forceOpenSsl [optional] Does not apply to this credentials * type. * @return string The signature, base64-encoded. * @throws \Exception If AppEngine SDK or mock is not available. */ public function signBlob($stringToSign, $forceOpenSsl = false) { $this->checkAppEngineContext(); /** @phpstan-ignore-next-line */ return base64_encode(AppIdentityService::signForApp($stringToSign)['signature']); } /** * Get the project ID from AppIdentityService. * * Returns null if AppIdentityService is unavailable. * * @param callable|null $httpHandler Not used by this type. * @return string|null */ public function getProjectId(?callable $httpHandler = null) { try { $this->checkAppEngineContext(); } catch (\Exception $e) { return null; } /** @phpstan-ignore-next-line */ return AppIdentityService::getApplicationId(); } /** * Get the client name from AppIdentityService. * * Subsequent calls to this method will return a cached value. * * @param callable|null $httpHandler Not used in this implementation. * @return string * @throws \Exception If AppEngine SDK or mock is not available. */ public function getClientName(?callable $httpHandler = null) { $this->checkAppEngineContext(); if (!$this->clientName) { /** @phpstan-ignore-next-line */ $this->clientName = AppIdentityService::getServiceAccountName(); } return $this->clientName; } /** * @return array{access_token:string,expires_at:int}|null */ public function getLastReceivedToken() { if ($this->lastReceivedToken) { return [ 'access_token' => $this->lastReceivedToken['access_token'], 'expires_at' => $this->lastReceivedToken['expiration_time'], ]; } return null; } /** * Caching is handled by the underlying AppIdentityService, return empty string * to prevent caching. * * @return string */ public function getCacheKey() { return ''; } /** * @return void */ private function checkAppEngineContext() { if (!self::onAppEngine() || !class_exists('google\appengine\api\app_identity\AppIdentityService')) { throw new \Exception( 'This class must be run in App Engine, or you must include the AppIdentityService ' . 'mock class defined in tests/mocks/AppIdentityService.php' ); } } } ================================================ FILE: lib/Google/vendor/google/auth/src/Credentials/ExternalAccountCredentials.php ================================================ */ private ?array $lastImpersonatedAccessToken; private string $universeDomain; /** * @param string|string[] $scope The scope of the access request, expressed either as an array * or as a space-delimited string. * @param array $jsonKey JSON credentials as an associative array. */ public function __construct( $scope, array $jsonKey ) { if (!array_key_exists('type', $jsonKey)) { throw new InvalidArgumentException('json key is missing the type field'); } if ($jsonKey['type'] !== self::EXTERNAL_ACCOUNT_TYPE) { throw new InvalidArgumentException(sprintf( 'expected "%s" type but received "%s"', self::EXTERNAL_ACCOUNT_TYPE, $jsonKey['type'] )); } if (!array_key_exists('token_url', $jsonKey)) { throw new InvalidArgumentException( 'json key is missing the token_url field' ); } if (!array_key_exists('audience', $jsonKey)) { throw new InvalidArgumentException( 'json key is missing the audience field' ); } if (!array_key_exists('subject_token_type', $jsonKey)) { throw new InvalidArgumentException( 'json key is missing the subject_token_type field' ); } if (!array_key_exists('credential_source', $jsonKey)) { throw new InvalidArgumentException( 'json key is missing the credential_source field' ); } $this->serviceAccountImpersonationUrl = $jsonKey['service_account_impersonation_url'] ?? null; $this->quotaProject = $jsonKey['quota_project_id'] ?? null; $this->workforcePoolUserProject = $jsonKey['workforce_pool_user_project'] ?? null; $this->universeDomain = $jsonKey['universe_domain'] ?? GetUniverseDomainInterface::DEFAULT_UNIVERSE_DOMAIN; $this->auth = new OAuth2([ 'tokenCredentialUri' => $jsonKey['token_url'], 'audience' => $jsonKey['audience'], 'scope' => $scope, 'subjectTokenType' => $jsonKey['subject_token_type'], 'subjectTokenFetcher' => self::buildCredentialSource($jsonKey), 'additionalOptions' => $this->workforcePoolUserProject ? ['userProject' => $this->workforcePoolUserProject] : [], ]); if (!$this->isWorkforcePool() && $this->workforcePoolUserProject) { throw new InvalidArgumentException( 'workforce_pool_user_project should not be set for non-workforce pool credentials.' ); } } /** * @param array $jsonKey */ private static function buildCredentialSource(array $jsonKey): ExternalAccountCredentialSourceInterface { $credentialSource = $jsonKey['credential_source']; if (isset($credentialSource['file'])) { return new FileSource( $credentialSource['file'], $credentialSource['format']['type'] ?? null, $credentialSource['format']['subject_token_field_name'] ?? null ); } if ( isset($credentialSource['environment_id']) && 1 === preg_match('/^aws(\d+)$/', $credentialSource['environment_id'], $matches) ) { if ($matches[1] !== '1') { throw new InvalidArgumentException( "aws version \"$matches[1]\" is not supported in the current build." ); } if (!array_key_exists('regional_cred_verification_url', $credentialSource)) { throw new InvalidArgumentException( 'The regional_cred_verification_url field is required for aws1 credential source.' ); } return new AwsNativeSource( $jsonKey['audience'], $credentialSource['regional_cred_verification_url'], // $regionalCredVerificationUrl $credentialSource['region_url'] ?? null, // $regionUrl $credentialSource['url'] ?? null, // $securityCredentialsUrl $credentialSource['imdsv2_session_token_url'] ?? null, // $imdsV2TokenUrl ); } if (isset($credentialSource['url'])) { return new UrlSource( $credentialSource['url'], $credentialSource['format']['type'] ?? null, $credentialSource['format']['subject_token_field_name'] ?? null, $credentialSource['headers'] ?? null, ); } if (isset($credentialSource['executable'])) { if (!array_key_exists('command', $credentialSource['executable'])) { throw new InvalidArgumentException( 'executable source requires a command to be set in the JSON file.' ); } // Build command environment variables $env = [ 'GOOGLE_EXTERNAL_ACCOUNT_AUDIENCE' => $jsonKey['audience'], 'GOOGLE_EXTERNAL_ACCOUNT_TOKEN_TYPE' => $jsonKey['subject_token_type'], // Always set to 0 because interactive mode is not supported. 'GOOGLE_EXTERNAL_ACCOUNT_INTERACTIVE' => '0', ]; if ($outputFile = $credentialSource['executable']['output_file'] ?? null) { $env['GOOGLE_EXTERNAL_ACCOUNT_OUTPUT_FILE'] = $outputFile; } if ($serviceAccountImpersonationUrl = $jsonKey['service_account_impersonation_url'] ?? null) { // Parse email from URL. The formal looks as follows: // https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/name@project-id.iam.gserviceaccount.com:generateAccessToken $regex = '/serviceAccounts\/(?[^:]+):generateAccessToken$/'; if (preg_match($regex, $serviceAccountImpersonationUrl, $matches)) { $env['GOOGLE_EXTERNAL_ACCOUNT_IMPERSONATED_EMAIL'] = $matches['email']; } } $timeoutMs = $credentialSource['executable']['timeout_millis'] ?? null; return new ExecutableSource( $credentialSource['executable']['command'], $outputFile, $timeoutMs ? new ExecutableHandler($env, $timeoutMs) : new ExecutableHandler($env) ); } throw new InvalidArgumentException('Unable to determine credential source from json key.'); } /** * @param string $stsToken * @param callable|null $httpHandler * * @return array { * A set of auth related metadata, containing the following * * @type string $access_token * @type int $expires_at * } */ private function getImpersonatedAccessToken(string $stsToken, ?callable $httpHandler = null): array { if (!isset($this->serviceAccountImpersonationUrl)) { throw new InvalidArgumentException( 'service_account_impersonation_url must be set in JSON credentials.' ); } $request = new Request( 'POST', $this->serviceAccountImpersonationUrl, [ 'Content-Type' => 'application/json', 'Authorization' => 'Bearer ' . $stsToken, ], (string) json_encode([ 'lifetime' => sprintf('%ss', OAuth2::DEFAULT_EXPIRY_SECONDS), 'scope' => explode(' ', $this->auth->getScope()), ]), ); if (is_null($httpHandler)) { $httpHandler = HttpHandlerFactory::build(HttpClientCache::getHttpClient()); } $response = $httpHandler($request); $body = json_decode((string) $response->getBody(), true); return [ 'access_token' => $body['accessToken'], 'expires_at' => strtotime($body['expireTime']), ]; } /** * @param callable|null $httpHandler * @param array $headers [optional] Metrics headers to be inserted * into the token endpoint request present. * * @return array { * A set of auth related metadata, containing the following * * @type string $access_token * @type int $expires_at (impersonated service accounts only) * @type int $expires_in (identity pool only) * @type string $issued_token_type (identity pool only) * @type string $token_type (identity pool only) * } */ public function fetchAuthToken(?callable $httpHandler = null, array $headers = []) { $stsToken = $this->auth->fetchAuthToken($httpHandler, $headers); if (isset($this->serviceAccountImpersonationUrl)) { return $this->lastImpersonatedAccessToken = $this->getImpersonatedAccessToken( $stsToken['access_token'], $httpHandler ); } return $stsToken; } /** * Get the cache token key for the credentials. * The cache token key format depends on the type of source * The format for the cache key one of the following: * FetcherCacheKey.Scope.[ServiceAccount].[TokenType].[WorkforcePoolUserProject] * FetcherCacheKey.Audience.[ServiceAccount].[TokenType].[WorkforcePoolUserProject] * * @return ?string; */ public function getCacheKey(): ?string { $scopeOrAudience = $this->auth->getAudience(); if (!$scopeOrAudience) { $scopeOrAudience = $this->auth->getScope(); } return $this->auth->getSubjectTokenFetcher()->getCacheKey() . '.' . $scopeOrAudience . '.' . ($this->serviceAccountImpersonationUrl ?? '') . '.' . ($this->auth->getSubjectTokenType() ?? '') . '.' . ($this->workforcePoolUserProject ?? ''); } public function getLastReceivedToken() { return $this->lastImpersonatedAccessToken ?? $this->auth->getLastReceivedToken(); } /** * Get the quota project used for this API request * * @return string|null */ public function getQuotaProject() { return $this->quotaProject; } /** * Get the universe domain used for this API request * * @return string */ public function getUniverseDomain(): string { return $this->universeDomain; } /** * Get the project ID. * * @param callable|null $httpHandler Callback which delivers psr7 request * @param string|null $accessToken The access token to use to sign the blob. If * provided, saves a call to the metadata server for a new access * token. **Defaults to** `null`. * @return string|null */ public function getProjectId(?callable $httpHandler = null, ?string $accessToken = null) { if (isset($this->projectId)) { return $this->projectId; } $projectNumber = $this->getProjectNumber() ?: $this->workforcePoolUserProject; if (!$projectNumber) { return null; } if (is_null($httpHandler)) { $httpHandler = HttpHandlerFactory::build(HttpClientCache::getHttpClient()); } $url = str_replace( 'UNIVERSE_DOMAIN', $this->getUniverseDomain(), sprintf(self::CLOUD_RESOURCE_MANAGER_URL, $projectNumber) ); if (is_null($accessToken)) { $accessToken = $this->fetchAuthToken($httpHandler)['access_token']; } $request = new Request('GET', $url, ['authorization' => 'Bearer ' . $accessToken]); $response = $httpHandler($request); $body = json_decode((string) $response->getBody(), true); return $this->projectId = $body['projectId']; } private function getProjectNumber(): ?string { $parts = explode('/', $this->auth->getAudience()); $i = array_search('projects', $parts); return $parts[$i + 1] ?? null; } private function isWorkforcePool(): bool { $regex = '#//iam\.googleapis\.com/locations/[^/]+/workforcePools/#'; return preg_match($regex, $this->auth->getAudience()) === 1; } } ================================================ FILE: lib/Google/vendor/google/auth/src/Credentials/GCECredentials.php ================================================ push($middleware); * * $client = new Client([ * 'handler' => $stack, * 'base_uri' => 'https://www.googleapis.com/taskqueue/v1beta2/projects/', * 'auth' => 'google_auth' * ]); * * $res = $client->get('myproject/taskqueues/myqueue'); */ class GCECredentials extends CredentialsLoader implements SignBlobInterface, ProjectIdProviderInterface, GetQuotaProjectInterface { use IamSignerTrait; // phpcs:disable const cacheKey = 'GOOGLE_AUTH_PHP_GCE'; // phpcs:enable /** * The metadata IP address on appengine instances. * * The IP is used instead of the domain 'metadata' to avoid slow responses * when not on Compute Engine. */ const METADATA_IP = '169.254.169.254'; /** * The metadata path of the default token. */ const TOKEN_URI_PATH = 'v1/instance/service-accounts/default/token'; /** * The metadata path of the default id token. */ const ID_TOKEN_URI_PATH = 'v1/instance/service-accounts/default/identity'; /** * The metadata path of the client ID. */ const CLIENT_ID_URI_PATH = 'v1/instance/service-accounts/default/email'; /** * The metadata path of the project ID. */ const PROJECT_ID_URI_PATH = 'v1/project/project-id'; /** * The metadata path of the project ID. */ const UNIVERSE_DOMAIN_URI_PATH = 'v1/universe/universe-domain'; /** * The header whose presence indicates GCE presence. */ const FLAVOR_HEADER = 'Metadata-Flavor'; /** * The Linux file which contains the product name. */ private const GKE_PRODUCT_NAME_FILE = '/sys/class/dmi/id/product_name'; /** * The Windows Registry key path to the product name */ private const WINDOWS_REGISTRY_KEY_PATH = 'HKEY_LOCAL_MACHINE\\SYSTEM\\HardwareConfig\\Current\\'; /** * The Windows registry key name for the product name */ private const WINDOWS_REGISTRY_KEY_NAME = 'SystemProductName'; /** * The Name of the product expected from the windows registry */ private const PRODUCT_NAME = 'Google'; private const CRED_TYPE = 'mds'; /** * Note: the explicit `timeout` and `tries` below is a workaround. The underlying * issue is that resolving an unknown host on some networks will take * 20-30 seconds; making this timeout short fixes the issue, but * could lead to false negatives in the event that we are on GCE, but * the metadata resolution was particularly slow. The latter case is * "unlikely" since the expected 4-nines time is about 0.5 seconds. * This allows us to limit the total ping maximum timeout to 1.5 seconds * for developer desktop scenarios. */ const MAX_COMPUTE_PING_TRIES = 3; const COMPUTE_PING_CONNECTION_TIMEOUT_S = 0.5; /** * Flag used to ensure that the onGCE test is only done once;. * * @var bool */ private $hasCheckedOnGce = false; /** * Flag that stores the value of the onGCE check. * * @var bool */ private $isOnGce = false; /** * Result of fetchAuthToken. * * @var array */ protected $lastReceivedToken; /** * @var string|null */ private $clientName; /** * @var string|null */ private $projectId; /** * @var string */ private $tokenUri; /** * @var string */ private $targetAudience; /** * @var string|null */ private $quotaProject; /** * @var string|null */ private $serviceAccountIdentity; /** * @var string */ private ?string $universeDomain; /** * @param Iam|null $iam [optional] An IAM instance. * @param string|string[] $scope [optional] the scope of the access request, * expressed either as an array or as a space-delimited string. * @param string $targetAudience [optional] The audience for the ID token. * @param string $quotaProject [optional] Specifies a project to bill for access * charges associated with the request. * @param string $serviceAccountIdentity [optional] Specify a service * account identity name to use instead of "default". * @param string|null $universeDomain [optional] Specify a universe domain to use * instead of fetching one from the metadata server. */ public function __construct( ?Iam $iam = null, $scope = null, $targetAudience = null, $quotaProject = null, $serviceAccountIdentity = null, ?string $universeDomain = null ) { $this->iam = $iam; if ($scope && $targetAudience) { throw new InvalidArgumentException( 'Scope and targetAudience cannot both be supplied' ); } $tokenUri = self::getTokenUri($serviceAccountIdentity); if ($scope) { if (is_string($scope)) { $scope = explode(' ', $scope); } $scope = implode(',', $scope); $tokenUri = $tokenUri . '?scopes=' . $scope; } elseif ($targetAudience) { $tokenUri = self::getIdTokenUri($serviceAccountIdentity); $tokenUri = $tokenUri . '?audience=' . $targetAudience; $this->targetAudience = $targetAudience; } $this->tokenUri = $tokenUri; $this->quotaProject = $quotaProject; $this->serviceAccountIdentity = $serviceAccountIdentity; $this->universeDomain = $universeDomain; } /** * The full uri for accessing the default token. * * @param string $serviceAccountIdentity [optional] Specify a service * account identity name to use instead of "default". * @return string */ public static function getTokenUri($serviceAccountIdentity = null) { $base = 'http://' . self::METADATA_IP . '/computeMetadata/'; $base .= self::TOKEN_URI_PATH; if ($serviceAccountIdentity) { return str_replace( '/default/', '/' . $serviceAccountIdentity . '/', $base ); } return $base; } /** * The full uri for accessing the default service account. * * @param string $serviceAccountIdentity [optional] Specify a service * account identity name to use instead of "default". * @return string */ public static function getClientNameUri($serviceAccountIdentity = null) { $base = 'http://' . self::METADATA_IP . '/computeMetadata/'; $base .= self::CLIENT_ID_URI_PATH; if ($serviceAccountIdentity) { return str_replace( '/default/', '/' . $serviceAccountIdentity . '/', $base ); } return $base; } /** * The full uri for accesesing the default identity token. * * @param string $serviceAccountIdentity [optional] Specify a service * account identity name to use instead of "default". * @return string */ private static function getIdTokenUri($serviceAccountIdentity = null) { $base = 'http://' . self::METADATA_IP . '/computeMetadata/'; $base .= self::ID_TOKEN_URI_PATH; if ($serviceAccountIdentity) { return str_replace( '/default/', '/' . $serviceAccountIdentity . '/', $base ); } return $base; } /** * The full uri for accessing the default project ID. * * @return string */ private static function getProjectIdUri() { $base = 'http://' . self::METADATA_IP . '/computeMetadata/'; return $base . self::PROJECT_ID_URI_PATH; } /** * The full uri for accessing the default universe domain. * * @return string */ private static function getUniverseDomainUri() { $base = 'http://' . self::METADATA_IP . '/computeMetadata/'; return $base . self::UNIVERSE_DOMAIN_URI_PATH; } /** * Determines if this an App Engine Flexible instance, by accessing the * GAE_INSTANCE environment variable. * * @return bool true if this an App Engine Flexible Instance, false otherwise */ public static function onAppEngineFlexible() { return substr((string) getenv('GAE_INSTANCE'), 0, 4) === 'aef-'; } /** * Determines if this a GCE instance, by accessing the expected metadata * host. * If $httpHandler is not specified a the default HttpHandler is used. * * @param callable|null $httpHandler callback which delivers psr7 request * @return bool True if this a GCEInstance, false otherwise */ public static function onGce(?callable $httpHandler = null) { $httpHandler = $httpHandler ?: HttpHandlerFactory::build(HttpClientCache::getHttpClient()); $checkUri = 'http://' . self::METADATA_IP; for ($i = 1; $i <= self::MAX_COMPUTE_PING_TRIES; $i++) { try { // Comment from: oauth2client/client.py // // Note: the explicit `timeout` below is a workaround. The underlying // issue is that resolving an unknown host on some networks will take // 20-30 seconds; making this timeout short fixes the issue, but // could lead to false negatives in the event that we are on GCE, but // the metadata resolution was particularly slow. The latter case is // "unlikely". $resp = $httpHandler( new Request( 'GET', $checkUri, [ self::FLAVOR_HEADER => 'Google', self::$metricMetadataKey => self::getMetricsHeader('', 'mds') ] ), ['timeout' => self::COMPUTE_PING_CONNECTION_TIMEOUT_S] ); return $resp->getHeaderLine(self::FLAVOR_HEADER) == 'Google'; } catch (ClientException $e) { } catch (ServerException $e) { } catch (RequestException $e) { } catch (ConnectException $e) { } } if (PHP_OS === 'Windows' || PHP_OS === 'WINNT') { return self::detectResidencyWindows( self::WINDOWS_REGISTRY_KEY_PATH . self::WINDOWS_REGISTRY_KEY_NAME ); } // Detect GCE residency on Linux return self::detectResidencyLinux(self::GKE_PRODUCT_NAME_FILE); } private static function detectResidencyLinux(string $productNameFile): bool { if (file_exists($productNameFile)) { $productName = trim((string) file_get_contents($productNameFile)); return 0 === strpos($productName, self::PRODUCT_NAME); } return false; } private static function detectResidencyWindows(string $registryProductKey): bool { if (!class_exists(COM::class)) { // the COM extension must be installed and enabled to detect Windows residency // see https://www.php.net/manual/en/book.com.php return false; } $shell = new COM('WScript.Shell'); $productName = null; try { $productName = $shell->regRead($registryProductKey); } catch (com_exception) { // This means that we tried to read a key that doesn't exist on the registry // which might mean that it is a windows instance that is not on GCE return false; } return 0 === strpos($productName, self::PRODUCT_NAME); } /** * Implements FetchAuthTokenInterface#fetchAuthToken. * * Fetches the auth tokens from the GCE metadata host if it is available. * If $httpHandler is not specified a the default HttpHandler is used. * * @param callable|null $httpHandler callback which delivers psr7 request * @param array $headers [optional] Headers to be inserted * into the token endpoint request present. * * @return array { * A set of auth related metadata, based on the token type. * * @type string $access_token for access tokens * @type int $expires_in for access tokens * @type string $token_type for access tokens * @type string $id_token for ID tokens * } * @throws \Exception */ public function fetchAuthToken(?callable $httpHandler = null, array $headers = []) { $httpHandler = $httpHandler ?: HttpHandlerFactory::build(HttpClientCache::getHttpClient()); if (!$this->hasCheckedOnGce) { $this->isOnGce = self::onGce($httpHandler); $this->hasCheckedOnGce = true; } if (!$this->isOnGce) { return []; // return an empty array with no access token } $response = $this->getFromMetadata( $httpHandler, $this->tokenUri, $this->applyTokenEndpointMetrics($headers, $this->targetAudience ? 'it' : 'at') ); if ($this->targetAudience) { return $this->lastReceivedToken = ['id_token' => $response]; } if (null === $json = json_decode($response, true)) { throw new \Exception('Invalid JSON response'); } $json['expires_at'] = time() + $json['expires_in']; // store this so we can retrieve it later $this->lastReceivedToken = $json; return $json; } /** * Returns the Cache Key for the credential token. * The format for the cache key is: * TokenURI * * @return string */ public function getCacheKey() { return $this->tokenUri; } /** * @return array|null */ public function getLastReceivedToken() { if ($this->lastReceivedToken) { if (array_key_exists('id_token', $this->lastReceivedToken)) { return $this->lastReceivedToken; } return [ 'access_token' => $this->lastReceivedToken['access_token'], 'expires_at' => $this->lastReceivedToken['expires_at'] ]; } return null; } /** * Get the client name from GCE metadata. * * Subsequent calls will return a cached value. * * @param callable|null $httpHandler callback which delivers psr7 request * @return string */ public function getClientName(?callable $httpHandler = null) { if ($this->clientName) { return $this->clientName; } $httpHandler = $httpHandler ?: HttpHandlerFactory::build(HttpClientCache::getHttpClient()); if (!$this->hasCheckedOnGce) { $this->isOnGce = self::onGce($httpHandler); $this->hasCheckedOnGce = true; } if (!$this->isOnGce) { return ''; } $this->clientName = $this->getFromMetadata( $httpHandler, self::getClientNameUri($this->serviceAccountIdentity) ); return $this->clientName; } /** * Fetch the default Project ID from compute engine. * * Returns null if called outside GCE. * * @param callable|null $httpHandler Callback which delivers psr7 request * @return string|null */ public function getProjectId(?callable $httpHandler = null) { if ($this->projectId) { return $this->projectId; } $httpHandler = $httpHandler ?: HttpHandlerFactory::build(HttpClientCache::getHttpClient()); if (!$this->hasCheckedOnGce) { $this->isOnGce = self::onGce($httpHandler); $this->hasCheckedOnGce = true; } if (!$this->isOnGce) { return null; } $this->projectId = $this->getFromMetadata($httpHandler, self::getProjectIdUri()); return $this->projectId; } /** * Fetch the default universe domain from the metadata server. * * @param callable|null $httpHandler Callback which delivers psr7 request * @return string */ public function getUniverseDomain(?callable $httpHandler = null): string { if (null !== $this->universeDomain) { return $this->universeDomain; } $httpHandler = $httpHandler ?: HttpHandlerFactory::build(HttpClientCache::getHttpClient()); if (!$this->hasCheckedOnGce) { $this->isOnGce = self::onGce($httpHandler); $this->hasCheckedOnGce = true; } try { $this->universeDomain = $this->getFromMetadata( $httpHandler, self::getUniverseDomainUri() ); } catch (ClientException $e) { // If the metadata server exists, but returns a 404 for the universe domain, the auth // libraries should safely assume this is an older metadata server running in GCU, and // should return the default universe domain. if (!$e->hasResponse() || 404 != $e->getResponse()->getStatusCode()) { throw $e; } $this->universeDomain = self::DEFAULT_UNIVERSE_DOMAIN; } // We expect in some cases the metadata server will return an empty string for the universe // domain. In this case, the auth library MUST return the default universe domain. if ('' === $this->universeDomain) { $this->universeDomain = self::DEFAULT_UNIVERSE_DOMAIN; } return $this->universeDomain; } /** * Fetch the value of a GCE metadata server URI. * * @param callable $httpHandler An HTTP Handler to deliver PSR7 requests. * @param string $uri The metadata URI. * @param array $headers [optional] If present, add these headers to the token * endpoint request. * * @return string */ private function getFromMetadata(callable $httpHandler, $uri, array $headers = []) { $resp = $httpHandler( new Request( 'GET', $uri, [self::FLAVOR_HEADER => 'Google'] + $headers ) ); return (string) $resp->getBody(); } /** * Get the quota project used for this API request * * @return string|null */ public function getQuotaProject() { return $this->quotaProject; } /** * Set whether or not we've already checked the GCE environment. * * @param bool $isOnGce * * @return void */ public function setIsOnGce($isOnGce) { // Implicitly set hasCheckedGce to true $this->hasCheckedOnGce = true; // Set isOnGce $this->isOnGce = $isOnGce; } protected function getCredType(): string { return self::CRED_TYPE; } } ================================================ FILE: lib/Google/vendor/google/auth/src/Credentials/IAMCredentials.php ================================================ selector = $selector; $this->token = $token; } /** * export a callback function which updates runtime metadata. * * @return callable updateMetadata function */ public function getUpdateMetadataFunc() { return [$this, 'updateMetadata']; } /** * Updates metadata with the appropriate header metadata. * * @param array $metadata metadata hashmap * @param string $unusedAuthUri optional auth uri * @param callable|null $httpHandler callback which delivers psr7 request * Note: this param is unused here, only included here for * consistency with other credentials class * * @return array updated metadata hashmap */ public function updateMetadata( $metadata, $unusedAuthUri = null, ?callable $httpHandler = null ) { $metadata_copy = $metadata; $metadata_copy[self::SELECTOR_KEY] = $this->selector; $metadata_copy[self::TOKEN_KEY] = $this->token; return $metadata_copy; } } ================================================ FILE: lib/Google/vendor/google/auth/src/Credentials/ImpersonatedServiceAccountCredentials.php ================================================ $jsonKey JSON credential file path or JSON array credentials { * JSON credentials as an associative array. * * @type string $service_account_impersonation_url The URL to the service account * @type string|FetchAuthTokenInterface $source_credentials The source credentials to impersonate * @type int $lifetime The lifetime of the impersonated credentials * @type string[] $delegates The delegates to impersonate * } * @param string|null $targetAudience The audience to request an ID token. * @param string|string[]|null $defaultScope The scopes to be used if no "scopes" field exists * in the `$jsonKey`. */ public function __construct( string|array|null $scope, string|array $jsonKey, private ?string $targetAudience = null, string|array|null $defaultScope = null, ) { if (is_string($jsonKey)) { if (!file_exists($jsonKey)) { throw new InvalidArgumentException('file does not exist'); } $json = file_get_contents($jsonKey); if (!$jsonKey = json_decode((string) $json, true)) { throw new LogicException('invalid json for auth config'); } } if (!array_key_exists('service_account_impersonation_url', $jsonKey)) { throw new LogicException( 'json key is missing the service_account_impersonation_url field' ); } if (!array_key_exists('source_credentials', $jsonKey)) { throw new LogicException('json key is missing the source_credentials field'); } $jsonKeyScope = $jsonKey['scopes'] ?? null; $scope = $scope ?: $jsonKeyScope ?: $defaultScope; if ($scope && $targetAudience) { throw new InvalidArgumentException( 'Scope and targetAudience cannot both be supplied' ); } if (is_array($jsonKey['source_credentials'])) { if (!array_key_exists('type', $jsonKey['source_credentials'])) { throw new InvalidArgumentException('json key source credentials are missing the type field'); } if ( $targetAudience !== null && $jsonKey['source_credentials']['type'] === 'service_account' ) { // Service account tokens MUST request a scope, and as this token is only used to impersonate // an ID token, the narrowest scope we can request is `iam`. $scope = self::IAM_SCOPE; } $jsonKey['source_credentials'] = match ($jsonKey['source_credentials']['type'] ?? null) { // Do not pass $defaultScope to ServiceAccountCredentials 'service_account' => new ServiceAccountCredentials($scope, $jsonKey['source_credentials']), 'authorized_user' => new UserRefreshCredentials($scope, $jsonKey['source_credentials']), 'external_account' => new ExternalAccountCredentials($scope, $jsonKey['source_credentials']), default => throw new \InvalidArgumentException('invalid value in the type field'), }; } $this->targetScope = $scope ?? []; $this->lifetime = $jsonKey['lifetime'] ?? 3600; $this->delegates = $jsonKey['delegates'] ?? []; $this->serviceAccountImpersonationUrl = $jsonKey['service_account_impersonation_url']; $this->impersonatedServiceAccountName = $this->getImpersonatedServiceAccountNameFromUrl( $this->serviceAccountImpersonationUrl ); $this->sourceCredentials = $jsonKey['source_credentials']; } /** * Helper function for extracting the Server Account Name from the URL saved in the account * credentials file. * * @param $serviceAccountImpersonationUrl string URL from "service_account_impersonation_url" * @return string Service account email or ID. */ private function getImpersonatedServiceAccountNameFromUrl( string $serviceAccountImpersonationUrl ): string { $fields = explode('/', $serviceAccountImpersonationUrl); $lastField = end($fields); $splitter = explode(':', $lastField); return $splitter[0]; } /** * Get the client name from the keyfile * * In this implementation, it will return the issuers email from the oauth token. * * @param callable|null $unusedHttpHandler not used by this credentials type. * @return string Token issuer email */ public function getClientName(?callable $unusedHttpHandler = null) { return $this->impersonatedServiceAccountName; } /** * @param callable|null $httpHandler * * @return array { * A set of auth related metadata, containing the following * * @type string $access_token * @type int $expires_in * @type string $scope * @type string $token_type * @type string $id_token * } */ public function fetchAuthToken(?callable $httpHandler = null) { $httpHandler = $httpHandler ?? HttpHandlerFactory::build(HttpClientCache::getHttpClient()); // The FetchAuthTokenInterface technically does not have a "headers" argument, but all of // the implementations do. Additionally, passing in more parameters than the function has // defined is allowed in PHP. So we'll just ignore the phpstan error here. // @phpstan-ignore-next-line $authToken = $this->sourceCredentials->fetchAuthToken( $httpHandler, $this->applyTokenEndpointMetrics([], 'at') ); $headers = $this->applyTokenEndpointMetrics([ 'Content-Type' => 'application/json', 'Cache-Control' => 'no-store', 'Authorization' => sprintf('Bearer %s', $authToken['access_token'] ?? $authToken['id_token']), ], $this->isIdTokenRequest() ? 'it' : 'at'); $body = match ($this->isIdTokenRequest()) { true => [ 'audience' => $this->targetAudience, 'includeEmail' => true, ], false => [ 'scope' => $this->targetScope, 'delegates' => $this->delegates, 'lifetime' => sprintf('%ss', $this->lifetime), ] }; $url = $this->serviceAccountImpersonationUrl; if ($this->isIdTokenRequest()) { $regex = '/serviceAccounts\/(?[^:]+):generateAccessToken$/'; if (!preg_match($regex, $url, $matches)) { throw new InvalidArgumentException( 'Invalid service account impersonation URL - unable to parse service account email' ); } $url = str_replace( 'UNIVERSE_DOMAIN', $this->getUniverseDomain(), sprintf(self::ID_TOKEN_IMPERSONATION_URL, $matches['email']) ); } $request = new Request( 'POST', $url, $headers, (string) json_encode($body) ); $response = $httpHandler($request); $body = json_decode((string) $response->getBody(), true); return match ($this->isIdTokenRequest()) { true => ['id_token' => $body['token']], false => [ 'access_token' => $body['accessToken'], 'expires_at' => strtotime($body['expireTime']), ] }; } /** * Returns the Cache Key for the credentials * The cache key is the same as the UserRefreshCredentials class * * @return string */ public function getCacheKey() { return $this->getFullCacheKey( $this->serviceAccountImpersonationUrl . $this->sourceCredentials->getCacheKey() ); } /** * @return array */ public function getLastReceivedToken() { return $this->sourceCredentials->getLastReceivedToken(); } protected function getCredType(): string { return self::CRED_TYPE; } private function isIdTokenRequest(): bool { return !is_null($this->targetAudience); } public function getUniverseDomain(): string { return $this->sourceCredentials instanceof GetUniverseDomainInterface ? $this->sourceCredentials->getUniverseDomain() : self::DEFAULT_UNIVERSE_DOMAIN; } } ================================================ FILE: lib/Google/vendor/google/auth/src/Credentials/InsecureCredentials.php ================================================ '' ]; /** * Fetches the auth token. In this case it returns an empty string. * * @param callable|null $httpHandler * @return array{access_token:string} A set of auth related metadata */ public function fetchAuthToken(?callable $httpHandler = null) { return $this->token; } /** * Returns the cache key. In this case it returns a null value, disabling * caching. * * @return string|null */ public function getCacheKey() { return null; } /** * Fetches the last received token. In this case, it returns the same empty string * auth token. * * @return array{access_token:string} */ public function getLastReceivedToken() { return $this->token; } } ================================================ FILE: lib/Google/vendor/google/auth/src/Credentials/ServiceAccountCredentials.php ================================================ push($middleware); * * $client = new Client([ * 'handler' => $stack, * 'base_uri' => 'https://www.googleapis.com/taskqueue/v1beta2/projects/', * 'auth' => 'google_auth' // authorize all requests * ]); * * $res = $client->get('myproject/taskqueues/myqueue'); */ class ServiceAccountCredentials extends CredentialsLoader implements GetQuotaProjectInterface, SignBlobInterface, ProjectIdProviderInterface { use ServiceAccountSignerTrait; /** * Used in observability metric headers * * @var string */ private const CRED_TYPE = 'sa'; private const IAM_SCOPE = 'https://www.googleapis.com/auth/iam'; /** * The OAuth2 instance used to conduct authorization. * * @var OAuth2 */ protected $auth; /** * The quota project associated with the JSON credentials * * @var string */ protected $quotaProject; /** * @var string|null */ protected $projectId; /** * @var array|null */ private $lastReceivedJwtAccessToken; /** * @var bool */ private $useJwtAccessWithScope = false; /** * @var ServiceAccountJwtAccessCredentials|null */ private $jwtAccessCredentials; /** * @var string */ private string $universeDomain; /** * Whether this is an ID token request or an access token request. Used when * building the metric header. */ private bool $isIdTokenRequest = false; /** * Create a new ServiceAccountCredentials. * * @param string|string[]|null $scope the scope of the access request, expressed * either as an Array or as a space-delimited String. * @param string|array $jsonKey JSON credential file path or JSON credentials * as an associative array * @param string $sub an email address account to impersonate, in situations when * the service account has been delegated domain wide access. * @param string $targetAudience The audience for the ID token. */ public function __construct( $scope, $jsonKey, $sub = null, $targetAudience = null ) { if (is_string($jsonKey)) { if (!file_exists($jsonKey)) { throw new \InvalidArgumentException('file does not exist'); } $jsonKeyStream = file_get_contents($jsonKey); if (!$jsonKey = json_decode((string) $jsonKeyStream, true)) { throw new \LogicException('invalid json for auth config'); } } if (!array_key_exists('client_email', $jsonKey)) { throw new \InvalidArgumentException( 'json key is missing the client_email field' ); } if (!array_key_exists('private_key', $jsonKey)) { throw new \InvalidArgumentException( 'json key is missing the private_key field' ); } if (array_key_exists('quota_project_id', $jsonKey)) { $this->quotaProject = (string) $jsonKey['quota_project_id']; } if ($scope && $targetAudience) { throw new InvalidArgumentException( 'Scope and targetAudience cannot both be supplied' ); } $additionalClaims = []; if ($targetAudience) { $additionalClaims = ['target_audience' => $targetAudience]; $this->isIdTokenRequest = true; } $this->auth = new OAuth2([ 'audience' => self::TOKEN_CREDENTIAL_URI, 'issuer' => $jsonKey['client_email'], 'scope' => $scope, 'signingAlgorithm' => 'RS256', 'signingKey' => $jsonKey['private_key'], 'signingKeyId' => $jsonKey['private_key_id'] ?? null, 'sub' => $sub, 'tokenCredentialUri' => self::TOKEN_CREDENTIAL_URI, 'additionalClaims' => $additionalClaims, ]); $this->projectId = $jsonKey['project_id'] ?? null; $this->universeDomain = $jsonKey['universe_domain'] ?? self::DEFAULT_UNIVERSE_DOMAIN; } /** * When called, the ServiceAccountCredentials will use an instance of * ServiceAccountJwtAccessCredentials to fetch (self-sign) an access token * even when only scopes are supplied. Otherwise, * ServiceAccountJwtAccessCredentials is only called when no scopes and an * authUrl (audience) is suppled. * * @return void */ public function useJwtAccessWithScope() { $this->useJwtAccessWithScope = true; } /** * @param callable|null $httpHandler * @param array $headers [optional] Headers to be inserted * into the token endpoint request present. * * @return array { * A set of auth related metadata, containing the following * * @type string $access_token * @type int $expires_in * @type string $token_type * } */ public function fetchAuthToken(?callable $httpHandler = null, array $headers = []) { if ($this->useSelfSignedJwt()) { $jwtCreds = $this->createJwtAccessCredentials(); $accessToken = $jwtCreds->fetchAuthToken($httpHandler); if ($lastReceivedToken = $jwtCreds->getLastReceivedToken()) { // Keep self-signed JWTs in memory as the last received token $this->lastReceivedJwtAccessToken = $lastReceivedToken; } return $accessToken; } if ($this->isIdTokenRequest && $this->getUniverseDomain() !== self::DEFAULT_UNIVERSE_DOMAIN) { $now = time(); $jwt = Jwt::encode( [ 'iss' => $this->auth->getIssuer(), 'sub' => $this->auth->getIssuer(), 'scope' => self::IAM_SCOPE, 'exp' => ($now + $this->auth->getExpiry()), 'iat' => ($now - OAuth2::DEFAULT_SKEW_SECONDS), ], $this->auth->getSigningKey(), $this->auth->getSigningAlgorithm(), $this->auth->getSigningKeyId() ); // We create a new instance of Iam each time because the `$httpHandler` might change. $idToken = (new Iam($httpHandler, $this->getUniverseDomain()))->generateIdToken( $this->auth->getIssuer(), $this->auth->getAdditionalClaims()['target_audience'], $jwt, $this->applyTokenEndpointMetrics($headers, 'it') ); return ['id_token' => $idToken]; } return $this->auth->fetchAuthToken( $httpHandler, $this->applyTokenEndpointMetrics($headers, $this->isIdTokenRequest ? 'it' : 'at') ); } /** * Return the Cache Key for the credentials. * For the cache key format is one of the following: * ClientEmail.Scope[.Sub] * ClientEmail.Audience[.Sub] * * @return string */ public function getCacheKey() { $scopeOrAudience = $this->auth->getScope(); if (!$scopeOrAudience) { $scopeOrAudience = $this->auth->getAudience(); } $key = $this->auth->getIssuer() . '.' . $scopeOrAudience; if ($sub = $this->auth->getSub()) { $key .= '.' . $sub; } return $key; } /** * @return array */ public function getLastReceivedToken() { // If self-signed JWTs are being used, fetch the last received token // from memory. Else, fetch it from OAuth2 return $this->useSelfSignedJwt() ? $this->lastReceivedJwtAccessToken : $this->auth->getLastReceivedToken(); } /** * Get the project ID from the service account keyfile. * * Returns null if the project ID does not exist in the keyfile. * * @param callable|null $httpHandler Not used by this credentials type. * @return string|null */ public function getProjectId(?callable $httpHandler = null) { return $this->projectId; } /** * Updates metadata with the authorization token. * * @param array $metadata metadata hashmap * @param string $authUri optional auth uri * @param callable|null $httpHandler callback which delivers psr7 request * @return array updated metadata hashmap */ public function updateMetadata( $metadata, $authUri = null, ?callable $httpHandler = null ) { // scope exists. use oauth implementation if (!$this->useSelfSignedJwt()) { return parent::updateMetadata($metadata, $authUri, $httpHandler); } $jwtCreds = $this->createJwtAccessCredentials(); if ($this->auth->getScope()) { // Prefer user-provided "scope" to "audience" $updatedMetadata = $jwtCreds->updateMetadata($metadata, null, $httpHandler); } else { $updatedMetadata = $jwtCreds->updateMetadata($metadata, $authUri, $httpHandler); } if ($lastReceivedToken = $jwtCreds->getLastReceivedToken()) { // Keep self-signed JWTs in memory as the last received token $this->lastReceivedJwtAccessToken = $lastReceivedToken; } return $updatedMetadata; } /** * @return ServiceAccountJwtAccessCredentials */ private function createJwtAccessCredentials() { if (!$this->jwtAccessCredentials) { // Create credentials for self-signing a JWT (JwtAccess) $credJson = [ 'private_key' => $this->auth->getSigningKey(), 'client_email' => $this->auth->getIssuer(), ]; $this->jwtAccessCredentials = new ServiceAccountJwtAccessCredentials( $credJson, $this->auth->getScope() ); } return $this->jwtAccessCredentials; } /** * @param string $sub an email address account to impersonate, in situations when * the service account has been delegated domain wide access. * @return void */ public function setSub($sub) { $this->auth->setSub($sub); } /** * Get the client name from the keyfile. * * In this case, it returns the keyfile's client_email key. * * @param callable|null $httpHandler Not used by this credentials type. * @return string */ public function getClientName(?callable $httpHandler = null) { return $this->auth->getIssuer(); } /** * Get the private key from the keyfile. * * In this case, it returns the keyfile's private_key key, needed for JWT signing. * * @return string */ public function getPrivateKey() { return $this->auth->getSigningKey(); } /** * Get the quota project used for this API request * * @return string|null */ public function getQuotaProject() { return $this->quotaProject; } /** * Get the universe domain configured in the JSON credential. * * @return string */ public function getUniverseDomain(): string { return $this->universeDomain; } protected function getCredType(): string { return self::CRED_TYPE; } /** * @return bool */ private function useSelfSignedJwt() { // When a sub is supplied, the user is using domain-wide delegation, which not available // with self-signed JWTs if (null !== $this->auth->getSub()) { // If we are outside the GDU, we can't use domain-wide delegation if ($this->getUniverseDomain() !== self::DEFAULT_UNIVERSE_DOMAIN) { throw new \LogicException(sprintf( 'Service Account subject is configured for the credential. Domain-wide ' . 'delegation is not supported in universes other than %s.', self::DEFAULT_UNIVERSE_DOMAIN )); } return false; } // Do not use self-signed JWT for ID tokens if ($this->isIdTokenRequest) { return false; } // When true, ServiceAccountCredentials will always use JwtAccess for access tokens if ($this->useJwtAccessWithScope) { return true; } // If the universe domain is outside the GDU, use JwtAccess for access tokens if ($this->getUniverseDomain() !== self::DEFAULT_UNIVERSE_DOMAIN) { return true; } return is_null($this->auth->getScope()); } } ================================================ FILE: lib/Google/vendor/google/auth/src/Credentials/ServiceAccountJwtAccessCredentials.php ================================================ $jsonKey JSON credential file path or JSON credentials * as an associative array * @param string|string[] $scope the scope of the access request, expressed * either as an Array or as a space-delimited String. */ public function __construct($jsonKey, $scope = null) { if (is_string($jsonKey)) { if (!file_exists($jsonKey)) { throw new \InvalidArgumentException('file does not exist'); } $jsonKeyStream = file_get_contents($jsonKey); if (!$jsonKey = json_decode((string) $jsonKeyStream, true)) { throw new \LogicException('invalid json for auth config'); } } if (!array_key_exists('client_email', $jsonKey)) { throw new \InvalidArgumentException( 'json key is missing the client_email field' ); } if (!array_key_exists('private_key', $jsonKey)) { throw new \InvalidArgumentException( 'json key is missing the private_key field' ); } if (array_key_exists('quota_project_id', $jsonKey)) { $this->quotaProject = (string) $jsonKey['quota_project_id']; } $this->auth = new OAuth2([ 'issuer' => $jsonKey['client_email'], 'sub' => $jsonKey['client_email'], 'signingAlgorithm' => 'RS256', 'signingKey' => $jsonKey['private_key'], 'scope' => $scope, ]); $this->projectId = $jsonKey['project_id'] ?? null; } /** * Updates metadata with the authorization token. * * @param array $metadata metadata hashmap * @param string $authUri optional auth uri * @param callable|null $httpHandler callback which delivers psr7 request * @return array updated metadata hashmap */ public function updateMetadata( $metadata, $authUri = null, ?callable $httpHandler = null ) { $scope = $this->auth->getScope(); if (empty($authUri) && empty($scope)) { return $metadata; } $this->auth->setAudience($authUri); return parent::updateMetadata($metadata, $authUri, $httpHandler); } /** * Implements FetchAuthTokenInterface#fetchAuthToken. * * @param callable|null $httpHandler * * @return null|array{access_token:string} A set of auth related metadata */ public function fetchAuthToken(?callable $httpHandler = null) { $audience = $this->auth->getAudience(); $scope = $this->auth->getScope(); if (empty($audience) && empty($scope)) { return null; } if (!empty($audience) && !empty($scope)) { throw new \UnexpectedValueException( 'Cannot sign both audience and scope in JwtAccess' ); } $access_token = $this->auth->toJwt(); // Set the self-signed access token in OAuth2 for getLastReceivedToken $this->auth->setAccessToken($access_token); return [ 'access_token' => $access_token, 'expires_in' => $this->auth->getExpiry(), 'token_type' => 'Bearer' ]; } /** * Return the cache key for the credentials. * The format for the Cache Key one of the following: * ClientEmail.Scope * ClientEmail.Audience * * @return string */ public function getCacheKey() { $scopeOrAudience = $this->auth->getScope(); if (!$scopeOrAudience) { $scopeOrAudience = $this->auth->getAudience(); } return $this->auth->getIssuer() . '.' . $scopeOrAudience; } /** * @return array */ public function getLastReceivedToken() { return $this->auth->getLastReceivedToken(); } /** * Get the project ID from the service account keyfile. * * Returns null if the project ID does not exist in the keyfile. * * @param callable|null $httpHandler Not used by this credentials type. * @return string|null */ public function getProjectId(?callable $httpHandler = null) { return $this->projectId; } /** * Get the client name from the keyfile. * * In this case, it returns the keyfile's client_email key. * * @param callable|null $httpHandler Not used by this credentials type. * @return string */ public function getClientName(?callable $httpHandler = null) { return $this->auth->getIssuer(); } /** * Get the private key from the keyfile. * * In this case, it returns the keyfile's private_key key, needed for JWT signing. * * @return string */ public function getPrivateKey() { return $this->auth->getSigningKey(); } /** * Get the quota project used for this API request * * @return string|null */ public function getQuotaProject() { return $this->quotaProject; } protected function getCredType(): string { return self::CRED_TYPE; } } ================================================ FILE: lib/Google/vendor/google/auth/src/Credentials/UserRefreshCredentials.php ================================================ $jsonKey JSON credential file path or JSON credentials * as an associative array * @param string|null $targetAudience The audience for the ID token. */ public function __construct( $scope, $jsonKey, ?string $targetAudience = null ) { if (is_string($jsonKey)) { if (!file_exists($jsonKey)) { throw new InvalidArgumentException('file does not exist or is unreadable'); } $json = file_get_contents($jsonKey); if (!$jsonKey = json_decode((string) $json, true)) { throw new LogicException('invalid json for auth config'); } } if (!array_key_exists('client_id', $jsonKey)) { throw new InvalidArgumentException( 'json key is missing the client_id field' ); } if (!array_key_exists('client_secret', $jsonKey)) { throw new InvalidArgumentException( 'json key is missing the client_secret field' ); } if (!array_key_exists('refresh_token', $jsonKey)) { throw new InvalidArgumentException( 'json key is missing the refresh_token field' ); } if ($scope && $targetAudience) { throw new InvalidArgumentException( 'Scope and targetAudience cannot both be supplied' ); } $additionalClaims = []; if ($targetAudience) { $additionalClaims = ['target_audience' => $targetAudience]; $this->isIdTokenRequest = true; } $this->auth = new OAuth2([ 'clientId' => $jsonKey['client_id'], 'clientSecret' => $jsonKey['client_secret'], 'refresh_token' => $jsonKey['refresh_token'], 'scope' => $scope, 'tokenCredentialUri' => self::TOKEN_CREDENTIAL_URI, 'additionalClaims' => $additionalClaims, ]); if (array_key_exists('quota_project_id', $jsonKey)) { $this->quotaProject = (string) $jsonKey['quota_project_id']; } } /** * @param callable|null $httpHandler * @param array $headers [optional] Metrics headers to be inserted * into the token endpoint request present. * This could be passed from ImersonatedServiceAccountCredentials as it uses * UserRefreshCredentials as source credentials. * * @return array { * A set of auth related metadata, containing the following * * @type string $access_token * @type int $expires_in * @type string $scope * @type string $token_type * @type string $id_token * } */ public function fetchAuthToken(?callable $httpHandler = null, array $headers = []) { return $this->auth->fetchAuthToken( $httpHandler, $this->applyTokenEndpointMetrics($headers, $this->isIdTokenRequest ? 'it' : 'at') ); } /** * Return the Cache Key for the credentials. * The format for the Cache key is one of the following: * ClientId.Scope * ClientId.Audience * * @return string */ public function getCacheKey() { $scopeOrAudience = $this->auth->getScope(); if (!$scopeOrAudience) { $scopeOrAudience = $this->auth->getAudience(); } return $this->auth->getClientId() . '.' . $scopeOrAudience; } /** * @return array */ public function getLastReceivedToken() { return $this->auth->getLastReceivedToken(); } /** * Get the quota project used for this API request * * @return string|null */ public function getQuotaProject() { return $this->quotaProject; } /** * Get the granted scopes (if they exist) for the last fetched token. * * @return string|null */ public function getGrantedScope() { return $this->auth->getGrantedScope(); } protected function getCredType(): string { return self::CRED_TYPE; } } ================================================ FILE: lib/Google/vendor/google/auth/src/CredentialsLoader.php ================================================ |null JSON key | null */ public static function fromEnv() { $path = self::getEnv(self::ENV_VAR); if (empty($path)) { return null; } if (!file_exists($path)) { $cause = 'file ' . $path . ' does not exist'; throw new \DomainException(self::unableToReadEnv($cause)); } $jsonKey = file_get_contents($path); return json_decode((string) $jsonKey, true); } /** * Load a JSON key from a well known path. * * The well known path is OS dependent: * * * windows: %APPDATA%/gcloud/application_default_credentials.json * * others: $HOME/.config/gcloud/application_default_credentials.json * * If the file does not exist, this returns null. * * @return array|null JSON key | null */ public static function fromWellKnownFile() { $rootEnv = self::isOnWindows() ? 'APPDATA' : 'HOME'; $path = [self::getEnv($rootEnv)]; if (!self::isOnWindows()) { $path[] = self::NON_WINDOWS_WELL_KNOWN_PATH_BASE; } $path[] = self::WELL_KNOWN_PATH; $path = implode(DIRECTORY_SEPARATOR, $path); if (!file_exists($path)) { return null; } $jsonKey = file_get_contents($path); return json_decode((string) $jsonKey, true); } /** * Create a new Credentials instance. * * @deprecated This method is being deprecated because of a potential security risk. * * This method does not validate the credential configuration. The security * risk occurs when a credential configuration is accepted from a source * that is not under your control and used without validation on your side. * * If you know that you will be loading credential configurations of a * specific type, it is recommended to use a credential-type-specific * method. * This will ensure that an unexpected credential type with potential for * malicious intent is not loaded unintentionally. You might still have to do * validation for certain credential types. Please follow the recommendation * for that method. For example, if you want to load only service accounts, * you can create the {@see ServiceAccountCredentials} explicitly: * * ``` * use Google\Auth\Credentials\ServiceAccountCredentials; * $creds = new ServiceAccountCredentials($scopes, $json); * ``` * * If you are loading your credential configuration from an untrusted source and have * not mitigated the risks (e.g. by validating the configuration yourself), make * these changes as soon as possible to prevent security risks to your environment. * * Regardless of the method used, it is always your responsibility to validate * configurations received from external sources. * * @see https://cloud.google.com/docs/authentication/external/externally-sourced-credentials * * @param string|string[] $scope * @param array $jsonKey * @param string|string[] $defaultScope * @return ServiceAccountCredentials|UserRefreshCredentials|ImpersonatedServiceAccountCredentials|ExternalAccountCredentials */ public static function makeCredentials( $scope, array $jsonKey, $defaultScope = null ) { if (!array_key_exists('type', $jsonKey)) { throw new \InvalidArgumentException('json key is missing the type field'); } if ($jsonKey['type'] == 'service_account') { // Do not pass $defaultScope to ServiceAccountCredentials return new ServiceAccountCredentials($scope, $jsonKey); } if ($jsonKey['type'] == 'authorized_user') { $anyScope = $scope ?: $defaultScope; return new UserRefreshCredentials($anyScope, $jsonKey); } if ($jsonKey['type'] == 'impersonated_service_account') { return new ImpersonatedServiceAccountCredentials($scope, $jsonKey, null, $defaultScope); } if ($jsonKey['type'] == 'external_account') { $anyScope = $scope ?: $defaultScope; return new ExternalAccountCredentials($anyScope, $jsonKey); } throw new \InvalidArgumentException('invalid value in the type field'); } /** * Create an authorized HTTP Client from an instance of FetchAuthTokenInterface. * * @param FetchAuthTokenInterface $fetcher is used to fetch the auth token * @param array $httpClientOptions (optional) Array of request options to apply. * @param callable|null $httpHandler (optional) http client to fetch the token. * @param callable|null $tokenCallback (optional) function to be called when a new token is fetched. * @return \GuzzleHttp\Client */ public static function makeHttpClient( FetchAuthTokenInterface $fetcher, array $httpClientOptions = [], ?callable $httpHandler = null, ?callable $tokenCallback = null ) { $middleware = new Middleware\AuthTokenMiddleware( $fetcher, $httpHandler, $tokenCallback ); $stack = \GuzzleHttp\HandlerStack::create(); $stack->push($middleware); return new \GuzzleHttp\Client([ 'handler' => $stack, 'auth' => 'google_auth', ] + $httpClientOptions); } /** * Create a new instance of InsecureCredentials. * * @return InsecureCredentials */ public static function makeInsecureCredentials() { return new InsecureCredentials(); } /** * Fetch a quota project from the environment variable * GOOGLE_CLOUD_QUOTA_PROJECT. Return null if * GOOGLE_CLOUD_QUOTA_PROJECT is not specified. * * @return string|null */ public static function quotaProjectFromEnv() { return self::getEnv(self::QUOTA_PROJECT_ENV_VAR) ?: null; } /** * Gets a callable which returns the default device certification. * * @throws UnexpectedValueException * @return callable|null */ public static function getDefaultClientCertSource() { if (!$clientCertSourceJson = self::loadDefaultClientCertSourceFile()) { return null; } $clientCertSourceCmd = $clientCertSourceJson['cert_provider_command']; return function () use ($clientCertSourceCmd) { $cmd = array_map('escapeshellarg', $clientCertSourceCmd); exec(implode(' ', $cmd), $output, $returnVar); if (0 === $returnVar) { return implode(PHP_EOL, $output); } throw new RuntimeException( '"cert_provider_command" failed with a nonzero exit code' ); }; } /** * Determines whether or not the default device certificate should be loaded. * * @return bool */ public static function shouldLoadClientCertSource() { return filter_var(self::getEnv(self::MTLS_CERT_ENV_VAR), FILTER_VALIDATE_BOOLEAN); } /** * @return array{cert_provider_command:string[]}|null */ private static function loadDefaultClientCertSourceFile() { $rootEnv = self::isOnWindows() ? 'APPDATA' : 'HOME'; $path = sprintf('%s/%s', self::getEnv($rootEnv), self::MTLS_WELL_KNOWN_PATH); if (!file_exists($path)) { return null; } $jsonKey = file_get_contents($path); $clientCertSourceJson = json_decode((string) $jsonKey, true); if (!$clientCertSourceJson) { throw new UnexpectedValueException('Invalid client cert source JSON'); } if (!isset($clientCertSourceJson['cert_provider_command'])) { throw new UnexpectedValueException( 'cert source requires "cert_provider_command"' ); } if (!is_array($clientCertSourceJson['cert_provider_command'])) { throw new UnexpectedValueException( 'cert source expects "cert_provider_command" to be an array' ); } return $clientCertSourceJson; } /** * Get the universe domain from the credential. Defaults to "googleapis.com" * for all credential types which do not support universe domain. * * @return string */ public function getUniverseDomain(): string { return self::DEFAULT_UNIVERSE_DOMAIN; } private static function getEnv(string $env): mixed { return getenv($env) ?: $_ENV[$env] ?? null; } } ================================================ FILE: lib/Google/vendor/google/auth/src/ExecutableHandler/ExecutableHandler.php ================================================ */ private array $env = []; private ?string $output = null; /** * @param array $env */ public function __construct( array $env = [], int $timeoutMs = self::DEFAULT_EXECUTABLE_TIMEOUT_MILLIS, ) { if (!class_exists(Process::class)) { throw new RuntimeException(sprintf( 'The "symfony/process" package is required to use %s.', self::class )); } $this->env = $env; $this->timeoutMs = $timeoutMs; } /** * @param string $command * @return int */ public function __invoke(string $command): int { $process = Process::fromShellCommandline( $command, null, $this->env, null, ($this->timeoutMs / 1000) ); try { $process->run(); } catch (ProcessTimedOutException $e) { throw new ExecutableResponseError( 'The executable failed to finish within the timeout specified.', 'TIMEOUT_EXCEEDED' ); } $this->output = $process->getOutput() . $process->getErrorOutput(); return $process->getExitCode(); } public function getOutput(): ?string { return $this->output; } } ================================================ FILE: lib/Google/vendor/google/auth/src/ExecutableHandler/ExecutableResponseError.php ================================================ |null $cacheConfig Configuration for the cache * @param CacheItemPoolInterface $cache */ public function __construct( FetchAuthTokenInterface $fetcher, ?array $cacheConfig = null, ?CacheItemPoolInterface $cache = null ) { $this->fetcher = $fetcher; $this->cache = $cache; $this->cacheConfig = array_merge([ 'lifetime' => 1500, 'prefix' => '', 'cacheUniverseDomain' => $fetcher instanceof Credentials\GCECredentials, ], (array) $cacheConfig); } /** * @return FetchAuthTokenInterface */ public function getFetcher() { return $this->fetcher; } /** * Implements FetchAuthTokenInterface#fetchAuthToken. * * Checks the cache for a valid auth token and fetches the auth tokens * from the supplied fetcher. * * @param callable|null $httpHandler callback which delivers psr7 request * @return array the response * @throws \Exception */ public function fetchAuthToken(?callable $httpHandler = null) { if ($cached = $this->fetchAuthTokenFromCache()) { return $cached; } $auth_token = $this->fetcher->fetchAuthToken($httpHandler); $this->saveAuthTokenInCache($auth_token); return $auth_token; } /** * @return string */ public function getCacheKey() { return $this->getFullCacheKey($this->fetcher->getCacheKey()); } /** * @return array|null */ public function getLastReceivedToken() { return $this->fetcher->getLastReceivedToken(); } /** * Get the client name from the fetcher. * * @param callable|null $httpHandler An HTTP handler to deliver PSR7 requests. * @return string */ public function getClientName(?callable $httpHandler = null) { if (!$this->fetcher instanceof SignBlobInterface) { throw new \RuntimeException( 'Credentials fetcher does not implement ' . 'Google\Auth\SignBlobInterface' ); } return $this->fetcher->getClientName($httpHandler); } /** * Sign a blob using the fetcher. * * @param string $stringToSign The string to sign. * @param bool $forceOpenSsl Require use of OpenSSL for local signing. Does * not apply to signing done using external services. **Defaults to** * `false`. * @return string The resulting signature. * @throws \RuntimeException If the fetcher does not implement * `Google\Auth\SignBlobInterface`. */ public function signBlob($stringToSign, $forceOpenSsl = false) { if (!$this->fetcher instanceof SignBlobInterface) { throw new \RuntimeException( 'Credentials fetcher does not implement ' . 'Google\Auth\SignBlobInterface' ); } // Pass the access token from cache for credentials that sign blobs // using the IAM API. This saves a call to fetch an access token when a // cached token exists. if ($this->fetcher instanceof Credentials\GCECredentials || $this->fetcher instanceof Credentials\ImpersonatedServiceAccountCredentials ) { $cached = $this->fetchAuthTokenFromCache(); $accessToken = $cached['access_token'] ?? null; return $this->fetcher->signBlob($stringToSign, $forceOpenSsl, $accessToken); } return $this->fetcher->signBlob($stringToSign, $forceOpenSsl); } /** * Get the quota project used for this API request from the credentials * fetcher. * * @return string|null */ public function getQuotaProject() { if ($this->fetcher instanceof GetQuotaProjectInterface) { return $this->fetcher->getQuotaProject(); } return null; } /** * Get the Project ID from the fetcher. * * @param callable|null $httpHandler Callback which delivers psr7 request * @return string|null * @throws \RuntimeException If the fetcher does not implement * `Google\Auth\ProvidesProjectIdInterface`. */ public function getProjectId(?callable $httpHandler = null) { if (!$this->fetcher instanceof ProjectIdProviderInterface) { throw new \RuntimeException( 'Credentials fetcher does not implement ' . 'Google\Auth\ProvidesProjectIdInterface' ); } // Pass the access token from cache for credentials that require an // access token to fetch the project ID. This saves a call to fetch an // access token when a cached token exists. if ($this->fetcher instanceof Credentials\ExternalAccountCredentials) { $cached = $this->fetchAuthTokenFromCache(); $accessToken = $cached['access_token'] ?? null; return $this->fetcher->getProjectId($httpHandler, $accessToken); } return $this->fetcher->getProjectId($httpHandler); } /* * Get the Universe Domain from the fetcher. * * @return string */ public function getUniverseDomain(): string { if ($this->fetcher instanceof GetUniverseDomainInterface) { if ($this->cacheConfig['cacheUniverseDomain']) { return $this->getCachedUniverseDomain($this->fetcher); } return $this->fetcher->getUniverseDomain(); } return GetUniverseDomainInterface::DEFAULT_UNIVERSE_DOMAIN; } /** * Updates metadata with the authorization token. * * @param array $metadata metadata hashmap * @param string $authUri optional auth uri * @param callable|null $httpHandler callback which delivers psr7 request * @return array updated metadata hashmap * @throws \RuntimeException If the fetcher does not implement * `Google\Auth\UpdateMetadataInterface`. */ public function updateMetadata( $metadata, $authUri = null, ?callable $httpHandler = null ) { if (!$this->fetcher instanceof UpdateMetadataInterface) { throw new \RuntimeException( 'Credentials fetcher does not implement ' . 'Google\Auth\UpdateMetadataInterface' ); } $cached = $this->fetchAuthTokenFromCache($authUri); if ($cached) { // Set the access token in the `Authorization` metadata header so // the downstream call to updateMetadata know they don't need to // fetch another token. if (isset($cached['access_token'])) { $metadata[self::AUTH_METADATA_KEY] = [ 'Bearer ' . $cached['access_token'] ]; } elseif (isset($cached['id_token'])) { $metadata[self::AUTH_METADATA_KEY] = [ 'Bearer ' . $cached['id_token'] ]; } } $newMetadata = $this->fetcher->updateMetadata( $metadata, $authUri, $httpHandler ); if (!$cached && $token = $this->fetcher->getLastReceivedToken()) { $this->saveAuthTokenInCache($token, $authUri); } return $newMetadata; } /** * @param string|null $authUri * @return array|null */ private function fetchAuthTokenFromCache($authUri = null) { // Use the cached value if its available. // // TODO: correct caching; update the call to setCachedValue to set the expiry // to the value returned with the auth token. // // TODO: correct caching; enable the cache to be cleared. // if $authUri is set, use it as the cache key $cacheKey = $authUri ? $this->getFullCacheKey($authUri) : $this->fetcher->getCacheKey(); $cached = $this->getCachedValue($cacheKey); if (is_array($cached)) { if (empty($cached['expires_at'])) { // If there is no expiration data, assume token is not expired. // (for JwtAccess and ID tokens) return $cached; } if ((time() + $this->eagerRefreshThresholdSeconds) < $cached['expires_at']) { // access token is not expired return $cached; } } return null; } /** * @param array $authToken * @param string|null $authUri * @return void */ private function saveAuthTokenInCache($authToken, $authUri = null) { if (isset($authToken['access_token']) || isset($authToken['id_token'])) { // if $authUri is set, use it as the cache key $cacheKey = $authUri ? $this->getFullCacheKey($authUri) : $this->fetcher->getCacheKey(); $this->setCachedValue($cacheKey, $authToken); } } private function getCachedUniverseDomain(GetUniverseDomainInterface $fetcher): string { $cacheKey = $this->getFullCacheKey($fetcher->getCacheKey() . 'universe_domain'); // @phpstan-ignore-line if ($universeDomain = $this->getCachedValue($cacheKey)) { return $universeDomain; } $universeDomain = $fetcher->getUniverseDomain(); $this->setCachedValue($cacheKey, $universeDomain); return $universeDomain; } } ================================================ FILE: lib/Google/vendor/google/auth/src/FetchAuthTokenInterface.php ================================================ a hash of auth tokens */ public function fetchAuthToken(?callable $httpHandler = null); /** * Obtains a key that can used to cache the results of #fetchAuthToken. * * If the value is empty, the auth token is not cached. * * @return string a key that may be used to cache the auth token. */ public function getCacheKey(); /** * Returns an associative array with the token and * expiration time. * * @return null|array { * The last received access token. * * @type string $access_token The access token string. * @type int $expires_at The time the token expires as a UNIX timestamp. * } */ public function getLastReceivedToken(); } ================================================ FILE: lib/Google/vendor/google/auth/src/GCECache.php ================================================ $cacheConfig Configuration for the cache * @param CacheItemPoolInterface $cache */ public function __construct( ?array $cacheConfig = null, ?CacheItemPoolInterface $cache = null ) { $this->cache = $cache; $this->cacheConfig = array_merge([ 'lifetime' => 1500, 'prefix' => '', ], (array) $cacheConfig); } /** * Caches the result of onGce so the metadata server is not called multiple * times. * * @param callable|null $httpHandler callback which delivers psr7 request * @return bool True if this a GCEInstance, false otherwise */ public function onGce(?callable $httpHandler = null) { if (is_null($this->cache)) { return GCECredentials::onGce($httpHandler); } $cacheKey = self::GCE_CACHE_KEY; $onGce = $this->getCachedValue($cacheKey); if (is_null($onGce)) { $onGce = GCECredentials::onGce($httpHandler); $this->setCachedValue($cacheKey, $onGce); } return $onGce; } } ================================================ FILE: lib/Google/vendor/google/auth/src/GetQuotaProjectInterface.php ================================================ client = $client; $this->logger = $logger; } /** * Accepts a PSR-7 request and an array of options and returns a PSR-7 response. * * @param RequestInterface $request * @param array $options * @return ResponseInterface */ public function __invoke(RequestInterface $request, array $options = []) { $requestEvent = null; if ($this->logger) { $requestEvent = $this->requestLog($request, $options); } $response = $this->client->send($request, $options); if ($this->logger) { $this->responseLog($response, $requestEvent); } return $response; } /** * Accepts a PSR-7 request and an array of options and returns a PromiseInterface * * @param RequestInterface $request * @param array $options * * @return \GuzzleHttp\Promise\PromiseInterface */ public function async(RequestInterface $request, array $options = []) { $requestEvent = null; if ($this->logger) { $requestEvent = $this->requestLog($request, $options); } $promise = $this->client->sendAsync($request, $options); if ($this->logger) { $promise->then(function (ResponseInterface $response) use ($requestEvent) { $this->responseLog($response, $requestEvent); return $response; }); } return $promise; } /** * @internal * @param RequestInterface $request * @param array $options */ public function requestLog(RequestInterface $request, array $options): RpcLogEvent { $requestEvent = new RpcLogEvent(); $requestEvent->method = $request->getMethod(); $requestEvent->url = (string) $request->getUri(); $requestEvent->headers = $request->getHeaders(); $requestEvent->payload = $request->getBody()->getContents(); $requestEvent->retryAttempt = $options['retryAttempt'] ?? null; $requestEvent->serviceName = $options['serviceName'] ?? null; $requestEvent->processId = (int) getmypid(); $requestEvent->requestId = $options['requestId'] ?? crc32((string) spl_object_id($request) . getmypid()); $this->logRequest($requestEvent); return $requestEvent; } /** * @internal */ public function responseLog(ResponseInterface $response, RpcLogEvent $requestEvent): void { $responseEvent = new RpcLogEvent($requestEvent->milliseconds); $responseEvent->headers = $response->getHeaders(); $responseEvent->payload = $response->getBody()->getContents(); $responseEvent->status = $response->getStatusCode(); $responseEvent->processId = $requestEvent->processId; $responseEvent->requestId = $requestEvent->requestId; $this->logResponse($responseEvent); } } ================================================ FILE: lib/Google/vendor/google/auth/src/HttpHandler/Guzzle7HttpHandler.php ================================================ remove('http_errors'); $stack->unshift(Middleware::httpErrors($bodySummarizer), 'http_errors'); } $client = new Client(['handler' => $stack]); } $logger = ($logger === false) ? null : $logger ?? ApplicationDefaultCredentials::getDefaultLogger(); $version = null; if (defined('GuzzleHttp\ClientInterface::MAJOR_VERSION')) { $version = ClientInterface::MAJOR_VERSION; } elseif (defined('GuzzleHttp\ClientInterface::VERSION')) { $version = (int) substr(ClientInterface::VERSION, 0, 1); } switch ($version) { case 6: return new Guzzle6HttpHandler($client, $logger); case 7: return new Guzzle7HttpHandler($client, $logger); default: throw new \Exception('Version not supported'); } } } ================================================ FILE: lib/Google/vendor/google/auth/src/Iam.php ================================================ httpHandler = $httpHandler ?: HttpHandlerFactory::build(HttpClientCache::getHttpClient()); $this->universeDomain = $universeDomain; } /** * Sign a string using the IAM signBlob API. * * Note that signing using IAM requires your service account to have the * `iam.serviceAccounts.signBlob` permission, part of the "Service Account * Token Creator" IAM role. * * @param string $email The service account email. * @param string $accessToken An access token from the service account. * @param string $stringToSign The string to be signed. * @param array $delegates [optional] A list of service account emails to * add to the delegate chain. If omitted, the value of `$email` will * be used. * @return string The signed string, base64-encoded. */ public function signBlob($email, $accessToken, $stringToSign, array $delegates = []) { $name = sprintf(self::SERVICE_ACCOUNT_NAME, $email); $apiRoot = str_replace('UNIVERSE_DOMAIN', $this->universeDomain, self::IAM_API_ROOT_TEMPLATE); $uri = $apiRoot . '/' . sprintf(self::SIGN_BLOB_PATH, $name); if ($delegates) { foreach ($delegates as &$delegate) { $delegate = sprintf(self::SERVICE_ACCOUNT_NAME, $delegate); } } else { $delegates = [$name]; } $body = [ 'delegates' => $delegates, 'payload' => base64_encode($stringToSign), ]; $headers = [ 'Authorization' => 'Bearer ' . $accessToken ]; $request = new Psr7\Request( 'POST', $uri, $headers, Utils::streamFor(json_encode($body)) ); $res = ($this->httpHandler)($request); $body = json_decode((string) $res->getBody(), true); return $body['signedBlob']; } /** * Sign a string using the IAM signBlob API. * * Note that signing using IAM requires your service account to have the * `iam.serviceAccounts.signBlob` permission, part of the "Service Account * Token Creator" IAM role. * * @param string $clientEmail The service account email. * @param string $targetAudience The audience for the ID token. * @param string $bearerToken The token to authenticate the IAM request. * @param array $headers [optional] Additional headers to send with the request. * * @return string The signed string, base64-encoded. */ public function generateIdToken( string $clientEmail, string $targetAudience, string $bearerToken, array $headers = [] ): string { $name = sprintf(self::SERVICE_ACCOUNT_NAME, $clientEmail); $apiRoot = str_replace('UNIVERSE_DOMAIN', $this->universeDomain, self::IAM_API_ROOT_TEMPLATE); $uri = $apiRoot . '/' . sprintf(self::GENERATE_ID_TOKEN_PATH, $name); $headers['Authorization'] = 'Bearer ' . $bearerToken; $body = [ 'audience' => $targetAudience, 'includeEmail' => true, 'useEmailAzp' => true, ]; $request = new Psr7\Request( 'POST', $uri, $headers, Utils::streamFor(json_encode($body)) ); $res = ($this->httpHandler)($request); $body = json_decode((string) $res->getBody(), true); return $body['token']; } } ================================================ FILE: lib/Google/vendor/google/auth/src/IamSignerTrait.php ================================================ iam; if (!$signer) { $signer = $this instanceof GetUniverseDomainInterface ? new Iam($httpHandler, $this->getUniverseDomain()) : new Iam($httpHandler); } $email = $this->getClientName($httpHandler); if (is_null($accessToken)) { $previousToken = $this->getLastReceivedToken(); $accessToken = $previousToken ? $previousToken['access_token'] : $this->fetchAuthToken($httpHandler)['access_token']; } return $signer->signBlob($email, $accessToken, $stringToSign); } } ================================================ FILE: lib/Google/vendor/google/auth/src/Logging/LoggingTrait.php ================================================ $event->timestamp, 'severity' => strtoupper(LogLevel::DEBUG), 'processId' => $event->processId ?? null, 'requestId' => $event->requestId ?? null, 'rpcName' => $event->rpcName ?? null, ]; $debugEvent = array_filter($debugEvent, fn ($value) => !is_null($value)); $jsonPayload = [ 'request.method' => $event->method, 'request.url' => $event->url, 'request.headers' => $event->headers, 'request.payload' => $this->truncatePayload($event->payload), 'request.jwt' => $this->getJwtToken($event->headers ?? []), 'retryAttempt' => $event->retryAttempt ]; // Remove null values $debugEvent['jsonPayload'] = array_filter($jsonPayload, fn ($value) => !is_null($value)); $stringifiedEvent = json_encode($debugEvent, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); // There was an error stringifying the event, return to not break execution if ($stringifiedEvent === false) { return; } $this->logger->debug($stringifiedEvent); } /** * @param RpcLogEvent $event */ private function logResponse(RpcLogEvent $event): void { $debugEvent = [ 'timestamp' => $event->timestamp, 'severity' => strtoupper(LogLevel::DEBUG), 'processId' => $event->processId ?? null, 'requestId' => $event->requestId ?? null, 'jsonPayload' => [ 'response.status' => $event->status, 'response.headers' => $event->headers, 'response.payload' => $this->truncatePayload($event->payload), 'latencyMillis' => $event->latency, ] ]; // Remove null values $debugEvent = array_filter($debugEvent, fn ($value) => !is_null($value)); $debugEvent['jsonPayload'] = array_filter( $debugEvent['jsonPayload'], fn ($value) => !is_null($value) ); $stringifiedEvent = json_encode($debugEvent, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); // There was an error stringifying the event, return to not break execution if ($stringifiedEvent !== false) { $this->logger->debug($stringifiedEvent); } } /** * @param array $headers * @return null|array */ private function getJwtToken(array $headers): null|array { if (empty($headers)) { return null; } $tokenHeader = $headers['Authorization'] ?? ''; $token = str_replace('Bearer ', '', $tokenHeader); if (substr_count($token, '.') !== 2) { return null; } [$header, $token, $_] = explode('.', $token); return [ 'header' => base64_decode($header), 'token' => base64_decode($token) ]; } /** * @param null|string $payload * @return string */ private function truncatePayload(null|string $payload): null|string { $maxLength = 500; if (is_null($payload) || strlen($payload) <= $maxLength) { return $payload; } return substr($payload, 0, $maxLength) . '...'; } } ================================================ FILE: lib/Google/vendor/google/auth/src/Logging/RpcLogEvent.php ================================================ */ public null|array $headers = null; /** * An array representation of JSON for the response or request * * @var null|string */ public null|string $payload = null; /** * Status code for REST or gRPC methods * * @var null|int|string */ public null|int|string $status = null; /** * The latency in milliseconds * * @var null|int */ public null|int $latency = null; /** * The retry attempt number * * @var null|int */ public null|int $retryAttempt = null; /** * The name of the gRPC method being called * * @var null|string */ public null|string $rpcName = null; /** * The Service Name of the gRPC * * @var null|string $serviceName */ public null|string $serviceName = null; /** * The Process ID for tracing logs * * @var null|int $processId */ public null|int $processId = null; /** * The Request id for tracing logs * * @var null|int $requestId; */ public null|int $requestId = null; /** * Creates an object with all the fields required for logging * Passing a string representation of a timestamp calculates the difference between * these two times and sets the latency field with the result. * * @param null|float $startTime (Optional) Parameter to calculate the latency */ public function __construct(null|float $startTime = null) { $this->timestamp = date(DATE_RFC3339); // Takes the micro time and convets it to millis $this->milliseconds = round(microtime(true) * 1000); if ($startTime) { $this->latency = (int) round($this->milliseconds - $startTime); } } } ================================================ FILE: lib/Google/vendor/google/auth/src/Logging/StdOutLogger.php ================================================ */ private array $levelMapping = [ LogLevel::EMERGENCY => 7, LogLevel::ALERT => 6, LogLevel::CRITICAL => 5, LogLevel::ERROR => 4, LogLevel::WARNING => 3, LogLevel::NOTICE => 2, LogLevel::INFO => 1, LogLevel::DEBUG => 0, ]; private int $level; /** * Constructs a basic PSR-3 logger class that logs into StdOut for GCP Logging * * @param string $level The level of the logger instance. */ public function __construct(string $level = LogLevel::DEBUG) { $this->level = $this->getLevelFromName($level); } /** * {@inheritdoc} */ public function log($level, string|Stringable $message, array $context = []): void { if ($this->getLevelFromName($level) < $this->level) { return; } print($message . "\n"); } /** * @param string $levelName * @return int * @throws InvalidArgumentException */ private function getLevelFromName(string $levelName): int { if (!array_key_exists($levelName, $this->levelMapping)) { throw new InvalidArgumentException('The level supplied to the Logger is not valid'); } return $this->levelMapping[$levelName]; } } ================================================ FILE: lib/Google/vendor/google/auth/src/MetricsTrait.php ================================================ $metadata The metadata to update and return. * @return array The updated metadata. */ protected function applyServiceApiUsageMetrics($metadata) { if ($credType = $this->getCredType()) { // Add service api usage observability metrics info into metadata // We expect upstream libries to have the metadata key populated already $value = 'cred-type/' . $credType; if (!isset($metadata[self::$metricMetadataKey])) { // This case will happen only when someone invokes the updateMetadata // method on the credentials fetcher themselves. $metadata[self::$metricMetadataKey] = [$value]; } elseif (is_array($metadata[self::$metricMetadataKey])) { $metadata[self::$metricMetadataKey][0] .= ' ' . $value; } else { $metadata[self::$metricMetadataKey] .= ' ' . $value; } } return $metadata; } /** * @param array $metadata The metadata to update and return. * @param string $authRequestType The auth request type. Possible values are * `'at'`, `'it'`, `'mds'`. * @return array The updated metadata. */ protected function applyTokenEndpointMetrics($metadata, $authRequestType) { $metricsHeader = self::getMetricsHeader($this->getCredType(), $authRequestType); if (!isset($metadata[self::$metricMetadataKey])) { $metadata[self::$metricMetadataKey] = $metricsHeader; } return $metadata; } protected static function getVersion(): string { if (is_null(self::$version)) { $versionFilePath = __DIR__ . '/../VERSION'; self::$version = trim((string) file_get_contents($versionFilePath)); } return self::$version; } protected function getCredType(): string { return ''; } } ================================================ FILE: lib/Google/vendor/google/auth/src/Middleware/AuthTokenMiddleware.php ================================================ ' */ class AuthTokenMiddleware { /** * @var callable */ private $httpHandler; /** * It must be an implementation of FetchAuthTokenInterface. * It may also implement UpdateMetadataInterface allowing direct * retrieval of auth related headers * @var FetchAuthTokenInterface */ private $fetcher; /** * @var ?callable */ private $tokenCallback; /** * Creates a new AuthTokenMiddleware. * * @param FetchAuthTokenInterface $fetcher is used to fetch the auth token * @param callable|null $httpHandler (optional) callback which delivers psr7 request * @param callable|null $tokenCallback (optional) function to be called when a new token is fetched. */ public function __construct( FetchAuthTokenInterface $fetcher, ?callable $httpHandler = null, ?callable $tokenCallback = null ) { $this->fetcher = $fetcher; $this->httpHandler = $httpHandler; $this->tokenCallback = $tokenCallback; } /** * Updates the request with an Authorization header when auth is 'google_auth'. * * use Google\Auth\Middleware\AuthTokenMiddleware; * use Google\Auth\OAuth2; * use GuzzleHttp\Client; * use GuzzleHttp\HandlerStack; * * $config = [...]; * $oauth2 = new OAuth2($config) * $middleware = new AuthTokenMiddleware($oauth2); * $stack = HandlerStack::create(); * $stack->push($middleware); * * $client = new Client([ * 'handler' => $stack, * 'base_uri' => 'https://www.googleapis.com/taskqueue/v1beta2/projects/', * 'auth' => 'google_auth' // authorize all requests * ]); * * $res = $client->get('myproject/taskqueues/myqueue'); * * @param callable $handler * @return \Closure */ public function __invoke(callable $handler) { return function (RequestInterface $request, array $options) use ($handler) { // Requests using "auth"="google_auth" will be authorized. if (!isset($options['auth']) || $options['auth'] !== 'google_auth') { return $handler($request, $options); } $request = $this->addAuthHeaders($request); if ($quotaProject = $this->getQuotaProject()) { $request = $request->withHeader( GetQuotaProjectInterface::X_GOOG_USER_PROJECT_HEADER, $quotaProject ); } return $handler($request, $options); }; } /** * Adds auth related headers to the request. * * @param RequestInterface $request * @return RequestInterface */ private function addAuthHeaders(RequestInterface $request) { if (!$this->fetcher instanceof UpdateMetadataInterface || ($this->fetcher instanceof FetchAuthTokenCache && !$this->fetcher->getFetcher() instanceof UpdateMetadataInterface) ) { $token = $this->fetcher->fetchAuthToken(); $request = $request->withHeader( 'authorization', 'Bearer ' . ($token['access_token'] ?? $token['id_token'] ?? '') ); } else { $headers = $this->fetcher->updateMetadata($request->getHeaders(), null, $this->httpHandler); $request = Utils::modifyRequest($request, ['set_headers' => $headers]); } if ($this->tokenCallback && ($token = $this->fetcher->getLastReceivedToken())) { if (array_key_exists('access_token', $token)) { call_user_func($this->tokenCallback, $this->fetcher->getCacheKey(), $token['access_token']); } } return $request; } /** * @return string|null */ private function getQuotaProject() { if ($this->fetcher instanceof GetQuotaProjectInterface) { return $this->fetcher->getQuotaProject(); } return null; } } ================================================ FILE: lib/Google/vendor/google/auth/src/Middleware/ProxyAuthTokenMiddleware.php ================================================ ' */ class ProxyAuthTokenMiddleware { /** * @var callable */ private $httpHandler; /** * @var FetchAuthTokenInterface */ private $fetcher; /** * @var ?callable */ private $tokenCallback; /** * Creates a new ProxyAuthTokenMiddleware. * * @param FetchAuthTokenInterface $fetcher is used to fetch the auth token * @param callable|null $httpHandler (optional) callback which delivers psr7 request * @param callable|null $tokenCallback (optional) function to be called when a new token is fetched. */ public function __construct( FetchAuthTokenInterface $fetcher, ?callable $httpHandler = null, ?callable $tokenCallback = null ) { $this->fetcher = $fetcher; $this->httpHandler = $httpHandler; $this->tokenCallback = $tokenCallback; } /** * Updates the request with an Authorization header when auth is 'google_auth'. * * use Google\Auth\Middleware\ProxyAuthTokenMiddleware; * use Google\Auth\OAuth2; * use GuzzleHttp\Client; * use GuzzleHttp\HandlerStack; * * $config = [...]; * $oauth2 = new OAuth2($config) * $middleware = new ProxyAuthTokenMiddleware($oauth2); * $stack = HandlerStack::create(); * $stack->push($middleware); * * $client = new Client([ * 'handler' => $stack, * 'base_uri' => 'https://www.googleapis.com/taskqueue/v1beta2/projects/', * 'proxy_auth' => 'google_auth' // authorize all requests * ]); * * $res = $client->get('myproject/taskqueues/myqueue'); * * @param callable $handler * @return \Closure */ public function __invoke(callable $handler) { return function (RequestInterface $request, array $options) use ($handler) { // Requests using "proxy_auth"="google_auth" will be authorized. if (!isset($options['proxy_auth']) || $options['proxy_auth'] !== 'google_auth') { return $handler($request, $options); } $request = $request->withHeader('proxy-authorization', 'Bearer ' . $this->fetchToken()); if ($quotaProject = $this->getQuotaProject()) { $request = $request->withHeader( GetQuotaProjectInterface::X_GOOG_USER_PROJECT_HEADER, $quotaProject ); } return $handler($request, $options); }; } /** * Call fetcher to fetch the token. * * @return string|null */ private function fetchToken() { $auth_tokens = $this->fetcher->fetchAuthToken($this->httpHandler); if (array_key_exists('access_token', $auth_tokens)) { // notify the callback if applicable if ($this->tokenCallback) { call_user_func( $this->tokenCallback, $this->fetcher->getCacheKey(), $auth_tokens['access_token'] ); } return $auth_tokens['access_token']; } if (array_key_exists('id_token', $auth_tokens)) { return $auth_tokens['id_token']; } return null; } /** * @return string|null; */ private function getQuotaProject() { if ($this->fetcher instanceof GetQuotaProjectInterface) { return $this->fetcher->getQuotaProject(); } return null; } } ================================================ FILE: lib/Google/vendor/google/auth/src/Middleware/ScopedAccessTokenMiddleware.php ================================================ ' */ class ScopedAccessTokenMiddleware { use CacheTrait; const DEFAULT_CACHE_LIFETIME = 1500; /** * @var callable */ private $tokenFunc; /** * @var array|string */ private $scopes; /** * Creates a new ScopedAccessTokenMiddleware. * * @param callable $tokenFunc a token generator function * @param array|string $scopes the token authentication scopes * @param array|null $cacheConfig configuration for the cache when it's present * @param CacheItemPoolInterface|null $cache an implementation of CacheItemPoolInterface */ public function __construct( callable $tokenFunc, $scopes, ?array $cacheConfig = null, ?CacheItemPoolInterface $cache = null ) { $this->tokenFunc = $tokenFunc; if (!(is_string($scopes) || is_array($scopes))) { throw new \InvalidArgumentException( 'wants scope should be string or array' ); } $this->scopes = $scopes; if (!is_null($cache)) { $this->cache = $cache; $this->cacheConfig = array_merge([ 'lifetime' => self::DEFAULT_CACHE_LIFETIME, 'prefix' => '', ], $cacheConfig); } } /** * Updates the request with an Authorization header when auth is 'scoped'. * * E.g this could be used to authenticate using the AppEngine * AppIdentityService. * * use google\appengine\api\app_identity\AppIdentityService; * use Google\Auth\Middleware\ScopedAccessTokenMiddleware; * use GuzzleHttp\Client; * use GuzzleHttp\HandlerStack; * * $scope = 'https://www.googleapis.com/auth/taskqueue' * $middleware = new ScopedAccessTokenMiddleware( * 'AppIdentityService::getAccessToken', * $scope, * [ 'prefix' => 'Google\Auth\ScopedAccessToken::' ], * $cache = new Memcache() * ); * $stack = HandlerStack::create(); * $stack->push($middleware); * * $client = new Client([ * 'handler' => $stack, * 'base_url' => 'https://www.googleapis.com/taskqueue/v1beta2/projects/', * 'auth' => 'scoped' // authorize all requests * ]); * * $res = $client->get('myproject/taskqueues/myqueue'); * * @param callable $handler * @return \Closure */ public function __invoke(callable $handler) { return function (RequestInterface $request, array $options) use ($handler) { // Requests using "auth"="scoped" will be authorized. if (!isset($options['auth']) || $options['auth'] !== 'scoped') { return $handler($request, $options); } $request = $request->withHeader('authorization', 'Bearer ' . $this->fetchToken()); return $handler($request, $options); }; } /** * @return string */ private function getCacheKey() { $key = null; if (is_string($this->scopes)) { $key .= $this->scopes; } elseif (is_array($this->scopes)) { $key .= implode(':', $this->scopes); } return $key; } /** * Determine if token is available in the cache, if not call tokenFunc to * fetch it. * * @return string */ private function fetchToken() { $cacheKey = $this->getCacheKey(); $cached = $this->getCachedValue($cacheKey); if (!empty($cached)) { return $cached; } $token = call_user_func($this->tokenFunc, $this->scopes); $this->setCachedValue($cacheKey, $token); return $token; } } ================================================ FILE: lib/Google/vendor/google/auth/src/Middleware/SimpleMiddleware.php ================================================ */ private $config; /** * Create a new Simple plugin. * * The configuration array expects one option * - key: required, otherwise InvalidArgumentException is thrown * * @param array $config Configuration array */ public function __construct(array $config) { if (!isset($config['key'])) { throw new \InvalidArgumentException('requires a key to have been set'); } $this->config = array_merge(['key' => null], $config); } /** * Updates the request query with the developer key if auth is set to simple. * * use Google\Auth\Middleware\SimpleMiddleware; * use GuzzleHttp\Client; * use GuzzleHttp\HandlerStack; * * $my_key = 'is not the same as yours'; * $middleware = new SimpleMiddleware(['key' => $my_key]); * $stack = HandlerStack::create(); * $stack->push($middleware); * * $client = new Client([ * 'handler' => $stack, * 'base_uri' => 'https://www.googleapis.com/discovery/v1/', * 'auth' => 'simple' * ]); * * $res = $client->get('drive/v2/rest'); * * @param callable $handler * @return \Closure */ public function __invoke(callable $handler) { return function (RequestInterface $request, array $options) use ($handler) { // Requests using "auth"="scoped" will be authorized. if (!isset($options['auth']) || $options['auth'] !== 'simple') { return $handler($request, $options); } $query = Query::parse($request->getUri()->getQuery()); $params = array_merge($query, $this->config); $uri = $request->getUri()->withQuery(Query::build($params)); $request = $request->withUri($uri); return $handler($request, $options); }; } } ================================================ FILE: lib/Google/vendor/google/auth/src/OAuth2.php ================================================ */ public static $knownSigningAlgorithms = [ 'HS256', 'HS512', 'HS384', 'RS256', ]; /** * The well known grant types. * * @var array */ public static $knownGrantTypes = [ 'authorization_code', 'refresh_token', 'password', 'client_credentials', ]; /** * - authorizationUri * The authorization server's HTTP endpoint capable of * authenticating the end-user and obtaining authorization. * * @var ?UriInterface */ private $authorizationUri; /** * - tokenCredentialUri * The authorization server's HTTP endpoint capable of issuing * tokens and refreshing expired tokens. * * @var UriInterface */ private $tokenCredentialUri; /** * The redirection URI used in the initial request. * * @var ?string */ private $redirectUri; /** * A unique identifier issued to the client to identify itself to the * authorization server. * * @var string */ private $clientId; /** * A shared symmetric secret issued by the authorization server, which is * used to authenticate the client. * * @var string */ private $clientSecret; /** * The resource owner's username. * * @var ?string */ private $username; /** * The resource owner's password. * * @var ?string */ private $password; /** * The scope of the access request, expressed either as an Array or as a * space-delimited string. * * @var ?array */ private $scope; /** * An arbitrary string designed to allow the client to maintain state. * * @var string */ private $state; /** * The authorization code issued to this client. * * Only used by the authorization code access grant type. * * @var ?string */ private $code; /** * The issuer ID when using assertion profile. * * @var ?string */ private $issuer; /** * The target audience for assertions. * * @var string */ private $audience; /** * The target sub when issuing assertions. * * @var string */ private $sub; /** * The number of seconds assertions are valid for. * * @var int */ private $expiry; /** * The signing key when using assertion profile. * * @var ?string */ private $signingKey; /** * The signing key id when using assertion profile. Param kid in jwt header * * @var string */ private $signingKeyId; /** * The signing algorithm when using an assertion profile. * * @var ?string */ private $signingAlgorithm; /** * The refresh token associated with the access token to be refreshed. * * @var ?string */ private $refreshToken; /** * The current access token. * * @var string */ private $accessToken; /** * The current ID token. * * @var string */ private $idToken; /** * The scopes granted to the current access token * * @var string */ private $grantedScope; /** * The lifetime in seconds of the current access token. * * @var ?int */ private $expiresIn; /** * The expiration time of the access token as a number of seconds since the * unix epoch. * * @var ?int */ private $expiresAt; /** * The issue time of the access token as a number of seconds since the unix * epoch. * * @var ?int */ private $issuedAt; /** * The current grant type. * * @var ?string */ private $grantType; /** * When using an extension grant type, this is the set of parameters used by * that extension. * * @var array */ private $extensionParams; /** * When using the toJwt function, these claims will be added to the JWT * payload. * * @var array */ private $additionalClaims; /** * The code verifier for PKCE for OAuth 2.0. When set, the authorization * URI will contain the Code Challenge and Code Challenge Method querystring * parameters, and the token URI will contain the Code Verifier parameter. * * @see https://datatracker.ietf.org/doc/html/rfc7636 * @var ?string */ private $codeVerifier; /** * For STS requests. * A URI that indicates the target service or resource where the client * intends to use the requested security token. */ private ?string $resource; /** * For STS requests. * A fetcher for the "subject_token", which is a security token that * represents the identity of the party on behalf of whom the request is * being made. */ private ?ExternalAccountCredentialSourceInterface $subjectTokenFetcher; /** * For STS requests. * An identifier, that indicates the type of the security token in the * subjectToken parameter. */ private ?string $subjectTokenType; /** * For STS requests. * A security token that represents the identity of the acting party. */ private ?string $actorToken; /** * For STS requests. * An identifier that indicates the type of the security token in the * actorToken parameter. */ private ?string $actorTokenType; /** * From STS response. * An identifier for the representation of the issued security token. */ private ?string $issuedTokenType = null; /** * From STS response. * An identifier for the representation of the issued security token. * * @var array */ private array $additionalOptions; /** * Create a new OAuthCredentials. * * The configuration array accepts various options * * - authorizationUri * The authorization server's HTTP endpoint capable of * authenticating the end-user and obtaining authorization. * * - tokenCredentialUri * The authorization server's HTTP endpoint capable of issuing * tokens and refreshing expired tokens. * * - clientId * A unique identifier issued to the client to identify itself to the * authorization server. * * - clientSecret * A shared symmetric secret issued by the authorization server, * which is used to authenticate the client. * * - scope * The scope of the access request, expressed either as an Array * or as a space-delimited String. * * - state * An arbitrary string designed to allow the client to maintain state. * * - redirectUri * The redirection URI used in the initial request. * * - username * The resource owner's username. * * - password * The resource owner's password. * * - issuer * Issuer ID when using assertion profile * * - audience * Target audience for assertions * * - expiry * Number of seconds assertions are valid for * * - signingKey * Signing key when using assertion profile * * - signingKeyId * Signing key id when using assertion profile * * - refreshToken * The refresh token associated with the access token * to be refreshed. * * - accessToken * The current access token for this client. * * - idToken * The current ID token for this client. * * - extensionParams * When using an extension grant type, this is the set of parameters used * by that extension. * * - codeVerifier * The code verifier for PKCE for OAuth 2.0. * * - resource * The target service or resource where the client ntends to use the * requested security token. * * - subjectTokenFetcher * A fetcher for the "subject_token", which is a security token that * represents the identity of the party on behalf of whom the request is * being made. * * - subjectTokenType * An identifier that indicates the type of the security token in the * subjectToken parameter. * * - actorToken * A security token that represents the identity of the acting party. * * - actorTokenType * An identifier for the representation of the issued security token. * * @param array $config Configuration array */ public function __construct(array $config) { $opts = array_merge([ 'expiry' => self::DEFAULT_EXPIRY_SECONDS, 'extensionParams' => [], 'authorizationUri' => null, 'redirectUri' => null, 'tokenCredentialUri' => null, 'state' => null, 'username' => null, 'password' => null, 'clientId' => null, 'clientSecret' => null, 'issuer' => null, 'sub' => null, 'audience' => null, 'signingKey' => null, 'signingKeyId' => null, 'signingAlgorithm' => null, 'scope' => null, 'additionalClaims' => [], 'codeVerifier' => null, 'resource' => null, 'subjectTokenFetcher' => null, 'subjectTokenType' => null, 'actorToken' => null, 'actorTokenType' => null, 'additionalOptions' => [], ], $config); $this->setAuthorizationUri($opts['authorizationUri']); $this->setRedirectUri($opts['redirectUri']); $this->setTokenCredentialUri($opts['tokenCredentialUri']); $this->setState($opts['state']); $this->setUsername($opts['username']); $this->setPassword($opts['password']); $this->setClientId($opts['clientId']); $this->setClientSecret($opts['clientSecret']); $this->setIssuer($opts['issuer']); $this->setSub($opts['sub']); $this->setExpiry($opts['expiry']); $this->setAudience($opts['audience']); $this->setSigningKey($opts['signingKey']); $this->setSigningKeyId($opts['signingKeyId']); $this->setSigningAlgorithm($opts['signingAlgorithm']); $this->setScope($opts['scope']); $this->setExtensionParams($opts['extensionParams']); $this->setAdditionalClaims($opts['additionalClaims']); $this->setCodeVerifier($opts['codeVerifier']); // for STS $this->resource = $opts['resource']; $this->subjectTokenFetcher = $opts['subjectTokenFetcher']; $this->subjectTokenType = $opts['subjectTokenType']; $this->actorToken = $opts['actorToken']; $this->actorTokenType = $opts['actorTokenType']; $this->additionalOptions = $opts['additionalOptions']; $this->updateToken($opts); } /** * Verifies the idToken if present. * * - if none is present, return null * - if present, but invalid, raises DomainException. * - otherwise returns the payload in the idtoken as a PHP object. * * The behavior of this method varies depending on the version of * `firebase/php-jwt` you are using. In versions 6.0 and above, you cannot * provide multiple $allowed_algs, and instead must provide an array of Key * objects as the $publicKey. * * @param string|Key|Key[] $publicKey The public key to use to authenticate the token * @param string|array $allowed_algs algorithm or array of supported verification algorithms. * Providing more than one algorithm will throw an exception. * @throws \DomainException if the token is missing an audience. * @throws \DomainException if the audience does not match the one set in * the OAuth2 class instance. * @throws \UnexpectedValueException If the token is invalid * @throws \InvalidArgumentException If more than one value for allowed_algs is supplied * @throws \Firebase\JWT\SignatureInvalidException If the signature is invalid. * @throws \Firebase\JWT\BeforeValidException If the token is not yet valid. * @throws \Firebase\JWT\ExpiredException If the token has expired. * @return null|object */ public function verifyIdToken($publicKey = null, $allowed_algs = []) { $idToken = $this->getIdToken(); if (is_null($idToken)) { return null; } $resp = $this->jwtDecode($idToken, $publicKey, $allowed_algs); if (!property_exists($resp, 'aud')) { throw new \DomainException('No audience found the id token'); } if ($resp->aud != $this->getAudience()) { throw new \DomainException('Wrong audience present in the id token'); } return $resp; } /** * Obtains the encoded jwt from the instance data. * * @param array $config array optional configuration parameters * @return string */ public function toJwt(array $config = []) { if (is_null($this->getSigningKey())) { throw new \DomainException('No signing key available'); } if (is_null($this->getSigningAlgorithm())) { throw new \DomainException('No signing algorithm specified'); } $now = time(); $opts = array_merge([ 'skew' => self::DEFAULT_SKEW_SECONDS, ], $config); $assertion = [ 'iss' => $this->getIssuer(), 'exp' => ($now + $this->getExpiry()), 'iat' => ($now - $opts['skew']), ]; foreach ($assertion as $k => $v) { if (is_null($v)) { throw new \DomainException($k . ' should not be null'); } } if (!(is_null($this->getAudience()))) { $assertion['aud'] = $this->getAudience(); } if (!(is_null($this->getScope()))) { $assertion['scope'] = $this->getScope(); } if (empty($assertion['scope']) && empty($assertion['aud'])) { throw new \DomainException('one of scope or aud should not be null'); } if (!(is_null($this->getSub()))) { $assertion['sub'] = $this->getSub(); } $assertion += $this->getAdditionalClaims(); return JWT::encode( $assertion, $this->getSigningKey(), $this->getSigningAlgorithm(), $this->getSigningKeyId() ); } /** * Generates a request for token credentials. * * @param callable|null $httpHandler callback which delivers psr7 request * @param array $headers [optional] Additional headers to pass to * the token endpoint request. * @return RequestInterface the authorization Url. */ public function generateCredentialsRequest(?callable $httpHandler = null, array $headers = []) { $uri = $this->getTokenCredentialUri(); if (is_null($uri)) { throw new \DomainException('No token credential URI was set.'); } $grantType = $this->getGrantType(); $params = ['grant_type' => $grantType]; switch ($grantType) { case 'authorization_code': $params['code'] = $this->getCode(); $params['redirect_uri'] = $this->getRedirectUri(); if ($this->codeVerifier) { $params['code_verifier'] = $this->codeVerifier; } $this->addClientCredentials($params); break; case 'password': $params['username'] = $this->getUsername(); $params['password'] = $this->getPassword(); $this->addClientCredentials($params); break; case 'refresh_token': $params['refresh_token'] = $this->getRefreshToken(); if (isset($this->getAdditionalClaims()['target_audience'])) { $params['target_audience'] = $this->getAdditionalClaims()['target_audience']; } $this->addClientCredentials($params); break; case self::JWT_URN: $params['assertion'] = $this->toJwt(); break; case self::STS_URN: $token = $this->subjectTokenFetcher->fetchSubjectToken($httpHandler); $params['subject_token'] = $token; $params['subject_token_type'] = $this->subjectTokenType; $params += array_filter([ 'resource' => $this->resource, 'audience' => $this->audience, 'scope' => $this->getScope(), 'requested_token_type' => self::STS_REQUESTED_TOKEN_TYPE, 'actor_token' => $this->actorToken, 'actor_token_type' => $this->actorTokenType, ]); if ($this->additionalOptions) { $params['options'] = json_encode($this->additionalOptions); } break; default: if (!is_null($this->getRedirectUri())) { # Grant type was supposed to be 'authorization_code', as there # is a redirect URI. throw new \DomainException('Missing authorization code'); } unset($params['grant_type']); if (!is_null($grantType)) { $params['grant_type'] = $grantType; } $params = array_merge($params, $this->getExtensionParams()); } $headers = [ 'Cache-Control' => 'no-store', 'Content-Type' => 'application/x-www-form-urlencoded', ] + $headers; return new Request( 'POST', $uri, $headers, Query::build($params) ); } /** * Fetches the auth tokens based on the current state. * * @param callable|null $httpHandler callback which delivers psr7 request * @param array $headers [optional] If present, add these headers to the token * endpoint request. * @return array the response */ public function fetchAuthToken(?callable $httpHandler = null, array $headers = []) { if (is_null($httpHandler)) { $httpHandler = HttpHandlerFactory::build(HttpClientCache::getHttpClient()); } $response = $httpHandler($this->generateCredentialsRequest($httpHandler, $headers)); $credentials = $this->parseTokenResponse($response); $this->updateToken($credentials); if (isset($credentials['scope'])) { $this->setGrantedScope($credentials['scope']); } return $credentials; } /** * @deprecated * * Obtains a key that can used to cache the results of #fetchAuthToken. * * The key is derived from the scopes. * * @return ?string a key that may be used to cache the auth token. */ public function getCacheKey() { if (is_array($this->scope)) { return implode(':', $this->scope); } if ($this->audience) { return $this->audience; } // If scope has not set, return null to indicate no caching. return null; } /** * Gets this instance's SubjectTokenFetcher * * @return null|ExternalAccountCredentialSourceInterface */ public function getSubjectTokenFetcher(): ?ExternalAccountCredentialSourceInterface { return $this->subjectTokenFetcher; } /** * Parses the fetched tokens. * * @param ResponseInterface $resp the response. * @return array the tokens parsed from the response body. * @throws \Exception */ public function parseTokenResponse(ResponseInterface $resp) { $body = (string) $resp->getBody(); if ($resp->hasHeader('Content-Type') && $resp->getHeaderLine('Content-Type') == 'application/x-www-form-urlencoded' ) { $res = []; parse_str($body, $res); return $res; } // Assume it's JSON; if it's not throw an exception if (null === $res = json_decode($body, true)) { throw new \Exception('Invalid JSON response'); } return $res; } /** * Updates an OAuth 2.0 client. * * Example: * ``` * $oauth->updateToken([ * 'refresh_token' => 'n4E9O119d', * 'access_token' => 'FJQbwq9', * 'expires_in' => 3600 * ]); * ``` * * @param array $config * The configuration parameters related to the token. * * - refresh_token * The refresh token associated with the access token * to be refreshed. * * - access_token * The current access token for this client. * * - id_token * The current ID token for this client. * * - expires_in * The time in seconds until access token expiration. * * - expires_at * The time as an integer number of seconds since the Epoch * * - issued_at * The timestamp that the token was issued at. * @return void */ public function updateToken(array $config) { $opts = array_merge([ 'extensionParams' => [], 'access_token' => null, 'id_token' => null, 'expires_in' => null, 'expires_at' => null, 'issued_at' => null, 'scope' => null, ], $config); $this->setExpiresAt($opts['expires_at']); $this->setExpiresIn($opts['expires_in']); // By default, the token is issued at `Time.now` when `expiresIn` is set, // but this can be used to supply a more precise time. if (!is_null($opts['issued_at'])) { $this->setIssuedAt($opts['issued_at']); } $this->setAccessToken($opts['access_token']); $this->setIdToken($opts['id_token']); // The refresh token should only be updated if a value is explicitly // passed in, as some access token responses do not include a refresh // token. if (array_key_exists('refresh_token', $opts)) { $this->setRefreshToken($opts['refresh_token']); } // Required for STS response. An identifier for the representation of // the issued security token. if (array_key_exists('issued_token_type', $opts)) { $this->issuedTokenType = $opts['issued_token_type']; } } /** * Builds the authorization Uri that the user should be redirected to. * * @param array $config configuration options that customize the return url. * @return UriInterface the authorization Url. * @throws InvalidArgumentException */ public function buildFullAuthorizationUri(array $config = []) { if (is_null($this->getAuthorizationUri())) { throw new InvalidArgumentException( 'requires an authorizationUri to have been set' ); } $params = array_merge([ 'response_type' => 'code', 'access_type' => 'offline', 'client_id' => $this->clientId, 'redirect_uri' => $this->redirectUri, 'state' => $this->state, 'scope' => $this->getScope(), ], $config); // Validate the auth_params if (is_null($params['client_id'])) { throw new InvalidArgumentException( 'missing the required client identifier' ); } if (is_null($params['redirect_uri'])) { throw new InvalidArgumentException('missing the required redirect URI'); } if (!empty($params['prompt']) && !empty($params['approval_prompt'])) { throw new InvalidArgumentException( 'prompt and approval_prompt are mutually exclusive' ); } if ($this->codeVerifier) { $params['code_challenge'] = $this->getCodeChallenge($this->codeVerifier); $params['code_challenge_method'] = $this->getCodeChallengeMethod(); } // Construct the uri object; return it if it is valid. $result = clone $this->authorizationUri; $existingParams = Query::parse($result->getQuery()); $result = $result->withQuery( Query::build(array_merge($existingParams, $params)) ); if ($result->getScheme() != 'https') { throw new InvalidArgumentException( 'Authorization endpoint must be protected by TLS' ); } return $result; } /** * @return string|null */ public function getCodeVerifier(): ?string { return $this->codeVerifier; } /** * A cryptographically random string that is used to correlate the * authorization request to the token request. * * The code verifier for PKCE for OAuth 2.0. When set, the authorization * URI will contain the Code Challenge and Code Challenge Method querystring * parameters, and the token URI will contain the Code Verifier parameter. * * @see https://datatracker.ietf.org/doc/html/rfc7636 * * @param string|null $codeVerifier */ public function setCodeVerifier(?string $codeVerifier): void { $this->codeVerifier = $codeVerifier; } /** * Generates a random 128-character string for the "code_verifier" parameter * in PKCE for OAuth 2.0. This is a cryptographically random string that is * determined using random_int, hashed using "hash" and sha256, and base64 * encoded. * * When this method is called, the code verifier is set on the object. * * @return string */ public function generateCodeVerifier(): string { return $this->codeVerifier = $this->generateRandomString(128); } private function getCodeChallenge(string $randomString): string { return rtrim(strtr(base64_encode(hash('sha256', $randomString, true)), '+/', '-_'), '='); } private function getCodeChallengeMethod(): string { return 'S256'; } private function generateRandomString(int $length): string { $validChars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~'; $validCharsLen = strlen($validChars); $str = ''; $i = 0; while ($i++ < $length) { $str .= $validChars[random_int(0, $validCharsLen - 1)]; } return $str; } /** * Sets the authorization server's HTTP endpoint capable of authenticating * the end-user and obtaining authorization. * * @param string $uri * @return void */ public function setAuthorizationUri($uri) { $this->authorizationUri = $this->coerceUri($uri); } /** * Gets the authorization server's HTTP endpoint capable of authenticating * the end-user and obtaining authorization. * * @return ?UriInterface */ public function getAuthorizationUri() { return $this->authorizationUri; } /** * Gets the authorization server's HTTP endpoint capable of issuing tokens * and refreshing expired tokens. * * @return ?UriInterface */ public function getTokenCredentialUri() { return $this->tokenCredentialUri; } /** * Sets the authorization server's HTTP endpoint capable of issuing tokens * and refreshing expired tokens. * * @param string $uri * @return void */ public function setTokenCredentialUri($uri) { $this->tokenCredentialUri = $this->coerceUri($uri); } /** * Gets the redirection URI used in the initial request. * * @return ?string */ public function getRedirectUri() { return $this->redirectUri; } /** * Sets the redirection URI used in the initial request. * * @param ?string $uri * @return void */ public function setRedirectUri($uri) { if (is_null($uri)) { $this->redirectUri = null; return; } // redirect URI must be absolute if (!$this->isAbsoluteUri($uri)) { // "postmessage" is a reserved URI string in Google-land // @see https://developers.google.com/identity/sign-in/web/server-side-flow if ('postmessage' !== (string) $uri) { throw new InvalidArgumentException( 'Redirect URI must be absolute' ); } } $this->redirectUri = (string) $uri; } /** * Gets the scope of the access requests as a space-delimited String. * * @return ?string */ public function getScope() { if (is_null($this->scope)) { return $this->scope; } return implode(' ', $this->scope); } /** * Gets the subject token type * * @return ?string */ public function getSubjectTokenType(): ?string { return $this->subjectTokenType; } /** * Sets the scope of the access request, expressed either as an Array or as * a space-delimited String. * * @param string|array|null $scope * @return void * @throws InvalidArgumentException */ public function setScope($scope) { if (is_null($scope)) { $this->scope = null; } elseif (is_string($scope)) { $this->scope = explode(' ', $scope); } elseif (is_array($scope)) { foreach ($scope as $s) { $pos = strpos($s, ' '); if ($pos !== false) { throw new InvalidArgumentException( 'array scope values should not contain spaces' ); } } $this->scope = $scope; } else { throw new InvalidArgumentException( 'scopes should be a string or array of strings' ); } } /** * Gets the current grant type. * * @return ?string */ public function getGrantType() { if (!is_null($this->grantType)) { return $this->grantType; } // Returns the inferred grant type, based on the current object instance // state. if (!is_null($this->code)) { return 'authorization_code'; } if (!is_null($this->refreshToken)) { return 'refresh_token'; } if (!is_null($this->username) && !is_null($this->password)) { return 'password'; } if (!is_null($this->issuer) && !is_null($this->signingKey)) { return self::JWT_URN; } if (!is_null($this->subjectTokenFetcher) && !is_null($this->subjectTokenType)) { return self::STS_URN; } return null; } /** * Sets the current grant type. * * @param string $grantType * @return void * @throws InvalidArgumentException */ public function setGrantType($grantType) { if (in_array($grantType, self::$knownGrantTypes)) { $this->grantType = $grantType; } else { // validate URI if (!$this->isAbsoluteUri($grantType)) { throw new InvalidArgumentException( 'invalid grant type' ); } $this->grantType = (string) $grantType; } } /** * Gets an arbitrary string designed to allow the client to maintain state. * * @return string */ public function getState() { return $this->state; } /** * Sets an arbitrary string designed to allow the client to maintain state. * * @param string $state * @return void */ public function setState($state) { $this->state = $state; } /** * Gets the authorization code issued to this client. * * @return string */ public function getCode() { return $this->code; } /** * Sets the authorization code issued to this client. * * @param string $code * @return void */ public function setCode($code) { $this->code = $code; } /** * Gets the resource owner's username. * * @return string */ public function getUsername() { return $this->username; } /** * Sets the resource owner's username. * * @param string $username * @return void */ public function setUsername($username) { $this->username = $username; } /** * Gets the resource owner's password. * * @return string */ public function getPassword() { return $this->password; } /** * Sets the resource owner's password. * * @param string $password * @return void */ public function setPassword($password) { $this->password = $password; } /** * Sets a unique identifier issued to the client to identify itself to the * authorization server. * * @return string */ public function getClientId() { return $this->clientId; } /** * Sets a unique identifier issued to the client to identify itself to the * authorization server. * * @param string $clientId * @return void */ public function setClientId($clientId) { $this->clientId = $clientId; } /** * Gets a shared symmetric secret issued by the authorization server, which * is used to authenticate the client. * * @return string */ public function getClientSecret() { return $this->clientSecret; } /** * Sets a shared symmetric secret issued by the authorization server, which * is used to authenticate the client. * * @param string $clientSecret * @return void */ public function setClientSecret($clientSecret) { $this->clientSecret = $clientSecret; } /** * Gets the Issuer ID when using assertion profile. * * @return ?string */ public function getIssuer() { return $this->issuer; } /** * Sets the Issuer ID when using assertion profile. * * @param string $issuer * @return void */ public function setIssuer($issuer) { $this->issuer = $issuer; } /** * Gets the target sub when issuing assertions. * * @return ?string */ public function getSub() { return $this->sub; } /** * Sets the target sub when issuing assertions. * * @param string $sub * @return void */ public function setSub($sub) { $this->sub = $sub; } /** * Gets the target audience when issuing assertions. * * @return ?string */ public function getAudience() { return $this->audience; } /** * Sets the target audience when issuing assertions. * * @param string $audience * @return void */ public function setAudience($audience) { $this->audience = $audience; } /** * Gets the signing key when using an assertion profile. * * @return ?string */ public function getSigningKey() { return $this->signingKey; } /** * Sets the signing key when using an assertion profile. * * @param string $signingKey * @return void */ public function setSigningKey($signingKey) { $this->signingKey = $signingKey; } /** * Gets the signing key id when using an assertion profile. * * @return ?string */ public function getSigningKeyId() { return $this->signingKeyId; } /** * Sets the signing key id when using an assertion profile. * * @param string $signingKeyId * @return void */ public function setSigningKeyId($signingKeyId) { $this->signingKeyId = $signingKeyId; } /** * Gets the signing algorithm when using an assertion profile. * * @return ?string */ public function getSigningAlgorithm() { return $this->signingAlgorithm; } /** * Sets the signing algorithm when using an assertion profile. * * @param ?string $signingAlgorithm * @return void */ public function setSigningAlgorithm($signingAlgorithm) { if (is_null($signingAlgorithm)) { $this->signingAlgorithm = null; } elseif (!in_array($signingAlgorithm, self::$knownSigningAlgorithms)) { throw new InvalidArgumentException('unknown signing algorithm'); } else { $this->signingAlgorithm = $signingAlgorithm; } } /** * Gets the set of parameters used by extension when using an extension * grant type. * * @return array */ public function getExtensionParams() { return $this->extensionParams; } /** * Sets the set of parameters used by extension when using an extension * grant type. * * @param array $extensionParams * @return void */ public function setExtensionParams($extensionParams) { $this->extensionParams = $extensionParams; } /** * Gets the number of seconds assertions are valid for. * * @return int */ public function getExpiry() { return $this->expiry; } /** * Sets the number of seconds assertions are valid for. * * @param int $expiry * @return void */ public function setExpiry($expiry) { $this->expiry = $expiry; } /** * Gets the lifetime of the access token in seconds. * * @return int */ public function getExpiresIn() { return $this->expiresIn; } /** * Sets the lifetime of the access token in seconds. * * @param ?int $expiresIn * @return void */ public function setExpiresIn($expiresIn) { if (is_null($expiresIn)) { $this->expiresIn = null; $this->issuedAt = null; } else { $this->issuedAt = time(); $this->expiresIn = (int) $expiresIn; } } /** * Gets the time the current access token expires at. * * @return ?int */ public function getExpiresAt() { if (!is_null($this->expiresAt)) { return $this->expiresAt; } if (!is_null($this->issuedAt) && !is_null($this->expiresIn)) { return $this->issuedAt + $this->expiresIn; } return null; } /** * Returns true if the acccess token has expired. * * @return bool */ public function isExpired() { $expiration = $this->getExpiresAt(); $now = time(); return !is_null($expiration) && $now >= $expiration; } /** * Sets the time the current access token expires at. * * @param int $expiresAt * @return void */ public function setExpiresAt($expiresAt) { $this->expiresAt = $expiresAt; } /** * Gets the time the current access token was issued at. * * @return ?int */ public function getIssuedAt() { return $this->issuedAt; } /** * Sets the time the current access token was issued at. * * @param int $issuedAt * @return void */ public function setIssuedAt($issuedAt) { $this->issuedAt = $issuedAt; } /** * Gets the current access token. * * @return ?string */ public function getAccessToken() { return $this->accessToken; } /** * Sets the current access token. * * @param string $accessToken * @return void */ public function setAccessToken($accessToken) { $this->accessToken = $accessToken; } /** * Gets the current ID token. * * @return ?string */ public function getIdToken() { return $this->idToken; } /** * Sets the current ID token. * * @param string $idToken * @return void */ public function setIdToken($idToken) { $this->idToken = $idToken; } /** * Get the granted space-separated scopes (if they exist) for the last * fetched token. * * @return string|null */ public function getGrantedScope() { return $this->grantedScope; } /** * Sets the current ID token. * * @param string $grantedScope * @return void */ public function setGrantedScope($grantedScope) { $this->grantedScope = $grantedScope; } /** * Gets the refresh token associated with the current access token. * * @return ?string */ public function getRefreshToken() { return $this->refreshToken; } /** * Sets the refresh token associated with the current access token. * * @param string $refreshToken * @return void */ public function setRefreshToken($refreshToken) { $this->refreshToken = $refreshToken; } /** * Sets additional claims to be included in the JWT token * * @param array $additionalClaims * @return void */ public function setAdditionalClaims(array $additionalClaims) { $this->additionalClaims = $additionalClaims; } /** * Gets the additional claims to be included in the JWT token. * * @return array */ public function getAdditionalClaims() { return $this->additionalClaims; } /** * Gets the additional claims to be included in the JWT token. * * @return ?string */ public function getIssuedTokenType() { return $this->issuedTokenType; } /** * The expiration of the last received token. * * @return array|null */ public function getLastReceivedToken() { if ($token = $this->getAccessToken()) { // the bare necessity of an auth token $authToken = [ 'access_token' => $token, 'expires_at' => $this->getExpiresAt(), ]; } elseif ($idToken = $this->getIdToken()) { $authToken = [ 'id_token' => $idToken, 'expires_at' => $this->getExpiresAt(), ]; } else { return null; } if ($expiresIn = $this->getExpiresIn()) { $authToken['expires_in'] = $expiresIn; } if ($issuedAt = $this->getIssuedAt()) { $authToken['issued_at'] = $issuedAt; } if ($refreshToken = $this->getRefreshToken()) { $authToken['refresh_token'] = $refreshToken; } return $authToken; } /** * Get the client ID. * * Alias of {@see OAuth2::getClientId()}. * * @param callable|null $httpHandler * @return string * @access private */ public function getClientName(?callable $httpHandler = null) { return $this->getClientId(); } /** * @todo handle uri as array * * @param ?string $uri * @return null|UriInterface */ private function coerceUri($uri) { if (is_null($uri)) { return null; } return Utils::uriFor($uri); } /** * @param string $idToken * @param Key|Key[]|string|string[] $publicKey * @param string|string[] $allowedAlgs * @return object */ private function jwtDecode($idToken, $publicKey, $allowedAlgs) { $keys = $this->getFirebaseJwtKeys($publicKey, $allowedAlgs); // Default exception if none are caught. We are using the same exception // class and message from firebase/php-jwt to preserve backwards // compatibility. $e = new \InvalidArgumentException('Key may not be empty'); foreach ($keys as $key) { try { return JWT::decode($idToken, $key); } catch (\Exception $e) { // try next alg } } throw $e; } /** * @param Key|Key[]|string|string[] $publicKey * @param string|string[] $allowedAlgs * @return Key[] */ private function getFirebaseJwtKeys($publicKey, $allowedAlgs) { // If $publicKey is instance of Key, return it if ($publicKey instanceof Key) { return [$publicKey]; } // If $allowedAlgs is empty, $publicKey must be Key or Key[]. if (empty($allowedAlgs)) { $keys = []; foreach ((array) $publicKey as $kid => $pubKey) { if (!$pubKey instanceof Key) { throw new \InvalidArgumentException(sprintf( 'When allowed algorithms is empty, the public key must' . 'be an instance of %s or an array of %s objects', Key::class, Key::class )); } $keys[$kid] = $pubKey; } return $keys; } $allowedAlg = null; if (is_string($allowedAlgs)) { $allowedAlg = $allowedAlgs; } elseif (is_array($allowedAlgs)) { if (count($allowedAlgs) > 1) { throw new \InvalidArgumentException( 'To have multiple allowed algorithms, You must provide an' . ' array of Firebase\JWT\Key objects.' . ' See https://github.com/firebase/php-jwt for more information.' ); } $allowedAlg = array_pop($allowedAlgs); } else { throw new \InvalidArgumentException('allowed algorithms must be a string or array.'); } if (is_array($publicKey)) { // When publicKey is greater than 1, create keys with the single alg. $keys = []; foreach ($publicKey as $kid => $pubKey) { if ($pubKey instanceof Key) { $keys[$kid] = $pubKey; } else { $keys[$kid] = new Key($pubKey, $allowedAlg); } } return $keys; } return [new Key($publicKey, $allowedAlg)]; } /** * Determines if the URI is absolute based on its scheme and host or path * (RFC 3986). * * @param string $uri * @return bool */ private function isAbsoluteUri($uri) { $uri = $this->coerceUri($uri); return $uri->getScheme() && ($uri->getHost() || $uri->getPath()); } /** * @param array $params * @return array */ private function addClientCredentials(&$params) { $clientId = $this->getClientId(); $clientSecret = $this->getClientSecret(); if ($clientId && $clientSecret) { $params['client_id'] = $clientId; $params['client_secret'] = $clientSecret; } return $params; } } ================================================ FILE: lib/Google/vendor/google/auth/src/ProjectIdProviderInterface.php ================================================ auth->getSigningKey(); $signedString = ''; if (class_exists(phpseclib3\Crypt\RSA::class) && !$forceOpenssl) { $key = PublicKeyLoader::load($privateKey); $rsa = $key->withHash('sha256')->withPadding(RSA::SIGNATURE_PKCS1); $signedString = $rsa->sign($stringToSign); } elseif (extension_loaded('openssl')) { openssl_sign($stringToSign, $signedString, $privateKey, 'sha256WithRSAEncryption'); } else { // @codeCoverageIgnoreStart throw new \RuntimeException('OpenSSL is not installed.'); } // @codeCoverageIgnoreEnd return base64_encode($signedString); } } ================================================ FILE: lib/Google/vendor/google/auth/src/SignBlobInterface.php ================================================ $metadata metadata hashmap * @param string $authUri optional auth uri * @param callable|null $httpHandler callback which delivers psr7 request * @return array updated metadata hashmap */ public function updateMetadata( $metadata, $authUri = null, ?callable $httpHandler = null ); } ================================================ FILE: lib/Google/vendor/google/auth/src/UpdateMetadataTrait.php ================================================ $metadata metadata hashmap * @param string $authUri optional auth uri * @param callable|null $httpHandler callback which delivers psr7 request * @return array updated metadata hashmap */ public function updateMetadata( $metadata, $authUri = null, ?callable $httpHandler = null ) { $metadata_copy = $metadata; // We do need to set the service api usage metrics irrespective even if // the auth token is set because invoking this method with auth tokens // would mean the intention is to just explicitly set the metrics metadata. $metadata_copy = $this->applyServiceApiUsageMetrics($metadata_copy); if (isset($metadata_copy[self::AUTH_METADATA_KEY])) { // Auth metadata has already been set return $metadata_copy; } $result = $this->fetchAuthToken($httpHandler); if (isset($result['access_token'])) { $metadata_copy[self::AUTH_METADATA_KEY] = ['Bearer ' . $result['access_token']]; } elseif (isset($result['id_token'])) { $metadata_copy[self::AUTH_METADATA_KEY] = ['Bearer ' . $result['id_token']]; } return $metadata_copy; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/.gitattributes ================================================ /*.xml.dist export-ignore /tests export-ignore /.github export-ignore ================================================ FILE: lib/Google/vendor/google/cloud-core/CODE_OF_CONDUCT.md ================================================ # Contributor Code of Conduct As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities. We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality. Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery * Personal attacks * Trolling or insulting/derogatory comments * Public or private harassment * Publishing other's private information, such as physical or electronic addresses, without explicit permission * Other unethical or unprofessional conduct. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team. This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers. This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0, available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/) ================================================ FILE: lib/Google/vendor/google/cloud-core/CONTRIBUTING.md ================================================ # How to Contribute We'd love to accept your patches and contributions to this project. We accept and review pull requests against the main [Google Cloud PHP](https://github.com/googleapis/google-cloud-php) repository, which contains all of our client libraries. You will also need to sign a Contributor License Agreement. For more details about how to contribute, see the [CONTRIBUTING.md](https://github.com/googleapis/google-cloud-php/blob/main/CONTRIBUTING.md) file in the main Google Cloud PHP repository. ================================================ FILE: lib/Google/vendor/google/cloud-core/LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright {yyyy} {name of copyright owner} Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: lib/Google/vendor/google/cloud-core/README.md ================================================ # Google Cloud Core Libraries for PHP [![Latest Stable Version](https://poser.pugx.org/google/cloud-core/v/stable)](https://packagist.org/packages/google/cloud-core) [![Packagist](https://img.shields.io/packagist/dm/google/cloud-core.svg)](https://packagist.org/packages/google/cloud-core) * [API documentation](https://cloud.google.com/php/docs/reference/cloud-core/latest) **NOTE:** This repository is part of [Google Cloud PHP](https://github.com/googleapis/google-cloud-php). Any support requests, bug reports, or development contributions should be directed to that project. ### Installation **NOTE** This package is not intended for direct use. It provides common infrastructure to the rest of the Google Cloud PHP components. ```sh $ composer require google/cloud-core ``` ### Debugging Please see our [Debugging guide](https://github.com/googleapis/google-cloud-php/blob/main/DEBUG.md) for more information about the debugging tools. ### Version This component is considered GA (generally available). As such, it will not introduce backwards-incompatible changes in any minor or patch releases. We will address issues and requests with the highest priority. ================================================ FILE: lib/Google/vendor/google/cloud-core/SECURITY.md ================================================ # Security Policy To report a security issue, please use [g.co/vulnz](https://g.co/vulnz). The Google Security Team will respond within 5 working days of your report on g.co/vulnz. We use g.co/vulnz for our intake, and do coordination and disclosure here using GitHub Security Advisory to privately discuss and fix the issue. ================================================ FILE: lib/Google/vendor/google/cloud-core/VERSION ================================================ 1.69.0 ================================================ FILE: lib/Google/vendor/google/cloud-core/bin/google-cloud-batch ================================================ #!/usr/bin/env php run(); } else { $idNum = (int) $argv[2]; $job = $daemon->job($idNum); $job->run(); } } elseif ($argv[1] === 'retry') { $retry = new Retry(); $retry->retryAll(); } else { showUsageAndDie(); } ================================================ FILE: lib/Google/vendor/google/cloud-core/composer.json ================================================ { "name": "google/cloud-core", "description": "Google Cloud PHP shared dependency, providing functionality useful to all components.", "license": "Apache-2.0", "minimum-stability": "stable", "require": { "php": "^8.1", "rize/uri-template": "~0.3||~0.4", "google/auth": "^1.34", "guzzlehttp/guzzle": "^6.5.8||^7.4.4", "guzzlehttp/promises": "^1.4||^2.0", "guzzlehttp/psr7": "^2.6", "monolog/monolog": "^2.9||^3.0", "psr/http-message": "^1.0||^2.0", "google/gax": "^1.38.0" }, "require-dev": { "phpunit/phpunit": "^9.0", "phpspec/prophecy-phpunit": "^2.0", "squizlabs/php_codesniffer": "2.*", "phpdocumentor/reflection": "^6.0", "phpdocumentor/reflection-docblock": "^5.3", "erusev/parsedown": "^1.6", "opis/closure": "^3.7|^4.0", "google/cloud-common-protos": "~0.5", "nikic/php-parser": "^5.6" }, "suggest": { "opis/closure": "May be used to serialize closures to process jobs in the batch daemon. Please require version ^3.", "symfony/lock": "Required for the Spanner cached based session pool. Please require the following commit: 3.3.x-dev#1ba6ac9" }, "extra": { "component": { "id": "cloud-core", "target": "googleapis/google-cloud-php-core.git", "path": "Core", "entry": "src/ServiceBuilder.php" } }, "bin": [ "bin/google-cloud-batch" ], "autoload": { "psr-4": { "Google\\Cloud\\Core\\": "src" } }, "autoload-dev": { "psr-4": { "Google\\Cloud\\Core\\Tests\\": "tests" } } } ================================================ FILE: lib/Google/vendor/google/cloud-core/perf-bootstrap.php ================================================ null ]; /** * Fetches the auth token. In this case it returns a null value. * * @param callable $httpHandler * @return array */ public function fetchAuthToken(?callable $httpHandler = null) { return $this->token; } /** * Returns the cache key. In this case it returns a null value, disabling * caching. * * @return string|null */ public function getCacheKey() { return null; } /** * Fetches the last received token. In this case, it returns the same null * auth token. * * @return array */ public function getLastReceivedToken() { return $this->token; } /** * This method has no effect for AnonymousCredentials. * * @param array $metadata metadata hashmap * @param string $authUri optional auth uri * @param callable $httpHandler callback which delivers psr7 request * @return array updated metadata hashmap */ public function updateMetadata( $metadata, $authUri = null, ?callable $httpHandler = null ) { return $metadata; } /** * This method always returns null for AnonymousCredentials. * * @return string|null */ public function getQuotaProject() { return null; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/ApiHelperTrait.php ================================================ $value) { $fFields[$key] = $this->formatValueForApi($value); } return ['fields' => $fFields]; } private function unpackStructFromApi(array $struct) { $vals = []; foreach ($struct['fields'] as $key => $val) { $vals[$key] = $this->unpackValue($val); } return $vals; } private function unpackValue($value) { if (count($value) > 1) { throw new \RuntimeException("Unexpected fields in struct: $value"); } foreach ($value as $setField => $setValue) { switch ($setField) { case 'listValue': $valueList = []; foreach ($setValue['values'] as $innerValue) { $valueList[] = $this->unpackValue($innerValue); } return $valueList; case 'structValue': return $this->unpackStructFromApi($value['structValue']); default: return $setValue; } } } private function flattenStruct(array $struct) { return $struct['fields']; } private function flattenValue(array $value) { if (count($value) > 1) { throw new \RuntimeException("Unexpected fields in struct: $value"); } if (isset($value['nullValue'])) { return null; } return array_pop($value); } private function flattenListValue(array $value) { return $value['values']; } /** * Format a list for the API. * * @param array $list * @return array */ private function formatListForApi(array $list) { $values = []; foreach ($list as $value) { $values[] = $this->formatValueForApi($value); } return ['values' => $values]; } /** * Format a value for the API. * * @param mixed $value * @return array */ private function formatValueForApi($value) { $type = gettype($value); switch ($type) { case 'string': return ['string_value' => $value]; case 'double': case 'integer': return ['number_value' => $value]; case 'boolean': return ['bool_value' => $value]; case 'NULL': return ['null_value' => NullValue::NULL_VALUE]; case 'array': if (!empty($value) && $this->isAssoc($value)) { return ['struct_value' => $this->formatStructForApi($value)]; } return ['list_value' => $this->formatListForApi($value)]; } return []; } /** * Format a gRPC timestamp to match the format returned by the REST API. * * @param array $timestamp * @return string */ private function formatTimestampFromApi(array $timestamp) { $timestamp += [ 'seconds' => 0, 'nanos' => 0 ]; $dt = $this->createDateTimeFromSeconds($timestamp['seconds']); return $this->formatTimeAsString($dt, $timestamp['nanos']); } /** * Format a timestamp for the API with nanosecond precision. * * @param string $value * @return array */ private function formatTimestampForApi($value) { list($dt, $nanos) = $this->parseTimeString($value); return [ 'seconds' => (int) $dt->format('U'), 'nanos' => (int) $nanos ]; } /** * Format a duration for the API. * * @param string|mixed $value * @return array */ private function formatDurationForApi($value) { if (is_string($value)) { $d = explode('.', trim($value, 's')); if (count($d) < 2) { $seconds = $d[0]; $nanos = 0; } else { $seconds = (int) $d[0]; $nanos = $this->convertFractionToNanoSeconds($d[1]); } } elseif ($value instanceof Duration) { $d = $value->get(); $seconds = $d['seconds']; $nanos = $d['nanos']; } return [ 'seconds' => $seconds, 'nanos' => $nanos ]; } /** * Construct a gapic client. Allows for tests to intercept. * * @param string $gapicName * @param array $config * @return mixed */ protected function constructGapic($gapicName, array $config) { return new $gapicName($config); } /** * Helper function to convert selective elements into protos out of a given input array. * * Example: * ``` * $output = $topic->convertDataToProtos(['schema' =>[], 'other vals'], ['schema' => Schema::class]); * $output['schema']; // This will be of the Schema type. * ``` * * @param array $input The input array. * @param array $map The key,value pairs specifying the elements and the proto classes. * * @return array The modified array */ private function convertDataToProtos(array $input, array $map): array { if (!isset($this->serializer)) { throw new \LogicException('Serializer must be set to use this function'); } foreach ($map as $key => $className) { if (isset($input[$key])) { $input[$key] = $this->serializer->decodeMessage(new $className(), $input[$key]); } } return $input; } /** * Helper method used to split a supplied set of options into parameters that are passed into * a proto message and optional args. * We strictly treat the parameters allowed by `CallOptions` in GAX as the optional params * and everything else that is passed is passed to the Proto message constructor. */ private function splitOptionalArgs(array $input, array $extraAllowedKeys = []): array { $callOptionFields = array_keys((new CallOptions([]))->toArray()); $keys = array_merge($callOptionFields, $extraAllowedKeys); $callOptions = $this->pluckArray($keys, $input); return [$input, $callOptions]; } /** * Helper method used to validate optons based on the supplied $optionTypes * $optionTypes can be an array of string keys, a protobuf Message classname, or a * the CallOptions classname. Parameters are split and returned in the order * that the options types are provided. * * @throws LogicException */ private function validateOptions(array $options, array|Message|string ...$optionTypes): array { if (!isset($this->optionsValidator)) { $this->optionsValidator = new OptionsValidator(); } return $this->optionsValidator->validateOptions($options, ...$optionTypes); } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/ArrayTrait.php ================================================ pluck($key, $arr, false); } } return $values; } /** * Determine whether given array is associative. * If $arr is empty, then $onEmpty will be returned * $onEmpty defaults to true to maintain compatibility * with the current usage. * * @param array $arr * @param bool $onEmpty * @return bool */ private function isAssoc(array $arr, $onEmpty = true) { if (empty($arr)) { return $onEmpty; } return array_keys($arr) !== range(0, count($arr) - 1); } /** * Just like array_filter(), but preserves falsey values except null. * * @param array $arr * @return array */ private function arrayFilterRemoveNull(array $arr) { return array_filter($arr, function ($element) { return !is_null($element); }); } /** * A method, similar to PHP's `array_merge_recursive`, with two differences. * * 1. Keys in $array2 take precedence over keys in $array1. * 2. Non-array keys found in both inputs are not transformed into an array * and appended. Rather, the value in $array2 is used. * * @param array $array1 * @param array $array2 * @return array */ private function arrayMergeRecursive(array $array1, array $array2) { foreach ($array2 as $key => $value) { if (array_key_exists($key, $array1) && is_array($array1[$key]) && is_array($value)) { $array1[$key] = ($this->isAssoc($array1[$key]) && $this->isAssoc($value)) ? $this->arrayMergeRecursive($array1[$key], $value) : array_merge($array1[$key], $value); } else { $array1[$key] = $value; } } return $array1; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Batch/BatchDaemon.php ================================================ isSysvIPCLoaded()) { throw new \RuntimeException('SystemV IPC extensions are missing.'); } $this->runner = new BatchRunner( new SysvConfigStorage(), new SysvProcessor() ); $this->shutdown = false; // Just share the usual descriptors. $this->descriptorSpec = [ 0 => ['file', 'php://stdin', 'r'], 1 => ['file', 'php://stdout', 'w'], 2 => ['file', 'php://stderr', 'w'] ]; $this->command = sprintf('exec php -d auto_prepend_file="" %s daemon', $entrypoint); $this->initFailureFile(); } /** * A loop for the parent. * * @return void */ public function run() { $this->setupSignalHandlers(); $procs = []; while (true) { $jobs = $this->runner->getJobs(); foreach ($jobs as $job) { if (! array_key_exists($job->identifier(), $procs)) { $procs[$job->identifier()] = []; } while (count($procs[$job->identifier()]) > $job->numWorkers()) { // Stopping an excessive child. echo 'Stopping an excessive child.' . PHP_EOL; $proc = array_pop($procs[$job->identifier()]); $status = proc_get_status($proc); // Keep sending SIGTERM until the child exits. while ($status['running'] === true) { @proc_terminate($proc); usleep(50000); $status = proc_get_status($proc); } @proc_close($proc); } for ($i = 0; $i < $job->numWorkers(); $i++) { $needStart = false; if (array_key_exists($i, $procs[$job->identifier()])) { $status = proc_get_status($procs[$job->identifier()][$i]); if ($status['running'] !== true) { $needStart = true; } } else { $needStart = true; } if ($needStart) { echo 'Starting a child.' . PHP_EOL; $procs[$job->identifier()][$i] = proc_open( sprintf('%s %d', $this->command, $job->id()), $this->descriptorSpec, $pipes ); } } } usleep(1000000); // Reload the config after 1 second pcntl_signal_dispatch(); if ($this->shutdown) { echo 'Shutting down, waiting for the children' . PHP_EOL; foreach ($procs as $k => $v) { foreach ($v as $proc) { $status = proc_get_status($proc); // Keep sending SIGTERM until the child exits. while ($status['running'] === true) { @proc_terminate($proc); usleep(50000); $status = proc_get_status($proc); } @proc_close($proc); } } echo 'BatchDaemon exiting' . PHP_EOL; exit; } // Reload the config $this->runner->loadConfig(); gc_collect_cycles(); } } /** * Fetch the child job by id. * * @param int $idNum The id of the job to find * @return JobInterface */ public function job($idNum) { return $this->runner->getJobFromIdNum($idNum); } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Batch/BatchDaemonTrait.php ================================================ self::DEFAULT_BATCH_SIZE, 'callPeriod' => self::DEFAULT_CALL_PERIOD, 'bootstrapFile' => null, 'numWorkers' => self::DEFAULT_WORKERS ]; $this->identifier = $identifier; $this->func = $func; $this->id = $idNum; $this->batchSize = $options['batchSize']; $this->callPeriod = $options['callPeriod']; $this->bootstrapFile = $options['bootstrapFile']; $this->numWorkers = $options['numWorkers']; $this->initFailureFile(); } /** * Run the job. */ public function run() { $this->setupSignalHandlers(); $sysvKey = $this->getSysvKey($this->id); $q = msg_get_queue($sysvKey); $items = []; $lastInvoked = microtime(true); if (!is_null($this->bootstrapFile)) { require_once($this->bootstrapFile); } while (true) { // Fire SIGALRM after 1 second to unblock the blocking call. pcntl_alarm(1); if (msg_receive( $q, 0, $type, 8192, $message, true, 0, // blocking mode $errorcode )) { if ($type === self::$typeDirect) { $items[] = $message; } elseif ($type === self::$typeFile) { $items[] = unserialize(file_get_contents($message)); @unlink($message); } } pcntl_signal_dispatch(); // It runs the job when // 1. Number of items reaches the batchSize. // 2-a. Count is >0 and the current time is larger than lastInvoked + period. // 2-b. Count is >0 and the shutdown flag is true. if ((count($items) >= $this->batchSize) || (count($items) > 0 && (microtime(true) > $lastInvoked + $this->callPeriod || $this->shutdown))) { printf( 'Running the job with %d items' . PHP_EOL, count($items) ); $this->flush($items); $items = []; $lastInvoked = microtime(true); } gc_collect_cycles(); if ($this->shutdown) { return; } } } /** * Finish any pending activity for this job. * * @param array $items * @return bool */ public function flush(array $items = []) { if (! $this->callFunc($items)) { $this->handleFailure($this->id, $items); return false; } return true; } /** * Finish any pending activity for this job. * * @access private * @internal * * @param array $items * @return bool */ public function callFunc(array $items = []) { return call_user_func_array($this->func, [$items]); } /** * Returns the period in seconds from the last execution to force * executing the job. * * @return float */ public function getCallPeriod() { return $this->callPeriod; } /** * Returns the batch size. * * @return int */ public function getBatchSize() { return $this->batchSize; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Batch/BatchRunner.php ================================================ isSysvIPCLoaded() && $this->isDaemonRunning()) { $configStorage = new SysvConfigStorage(); $processor = new SysvProcessor(); } else { $configStorage = InMemoryConfigStorage::getInstance(); $processor = $configStorage; } } $this->configStorage = $configStorage; $this->processor = $processor; $this->loadConfig(); } /** * Register a job for batch execution. * * @param string $identifier Unique identifier of the job. * @param callable $func Any Callable except for Closure. The callable * should accept an array of items as the first argument. * @param array $options [optional] { * Configuration options. * * @type int $batchSize The size of the batch. * @type float $callPeriod The period in seconds from the last execution * to force executing the job. * @type int $numWorkers The number of child processes. It only takes * effect with the {@see \Google\Cloud\Core\Batch\BatchDaemon}. * @type string $bootstrapFile A file to load before executing the * job. It's needed for registering global functions. * } * @return bool true on success, false on failure * @throws \InvalidArgumentException When receiving a Closure. */ public function registerJob($identifier, $func, array $options = []) { if ($func instanceof \Closure) { throw new \InvalidArgumentException('Closure is not allowed'); } // Always work on the latest data $result = $this->configStorage->lock(); if ($result === false) { return false; } $this->config = $this->configStorage->load(); $this->config->registerJob( $identifier, function ($id) use ($identifier, $func, $options) { return new BatchJob($identifier, $func, $id, $options); } ); try { $result = $this->configStorage->save($this->config); } finally { $this->configStorage->unlock(); } return $result; } /** * Submit an item. * * @param string $identifier Unique identifier of the job. * @param mixed $item It needs to be serializable. * * @return void * @throws \RuntimeException */ public function submitItem($identifier, $item) { $job = $this->getJobFromId($identifier); if ($job === null) { throw new \RuntimeException( "The identifier does not exist: $identifier" ); } $idNum = $job->id(); $this->processor->submit($item, $idNum); } /** * Get the job with the given identifier. * * @param string $identifier Unique identifier of the job. * * @return BatchJob|null */ public function getJobFromId($identifier) { return $this->config->getJobFromId($identifier); } /** * Get the job with the given numeric id. * * @param int $idNum A numeric id of the job. * * @return BatchJob|null */ public function getJobFromIdNum($idNum) { return $this->config->getJobFromIdNum($idNum); } /** * Get all the jobs. * * @return BatchJob[] */ public function getJobs() { return $this->config->getJobs(); } /** * Load the config from the storage. * * @return bool true on success * @throws \RuntimeException when it fails to load the config. */ public function loadConfig() { $result = $this->configStorage->lock(); if ($result === false) { throw new \RuntimeException('Failed to lock the configStorage'); } try { $result = $this->configStorage->load(); } catch (\RuntimeException $e) { $this->configStorage->clear(); throw $e; } finally { $this->configStorage->unlock(); } $this->config = $result; return true; } /** * Gets the item processor. * * @return ProcessItemInterface */ public function getProcessor() { return $this->processor; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Batch/BatchTrait.php ================================================ batchRunner ->getJobFromId($this->identifier) ->id(); return $this->batchRunner ->getProcessor() ->flush($id); } /** * Deliver a list of items in a batch call. * * @param array $items * @return bool * @access private */ public function send(array $items) { $start = microtime(true); try { call_user_func_array($this->getCallback(), [$items]); } catch (\Exception $e) { if ($this->debugOutput) { fwrite( $this->debugOutputResource, $e->getMessage() . PHP_EOL . PHP_EOL . $e->getTraceAsString() . PHP_EOL ); } return false; } $end = microtime(true); if ($this->debugOutput) { fwrite( $this->debugOutputResource, sprintf( '%f seconds for %s: %d items' . PHP_EOL, $end - $start, $this->batchMethod, count($items) ) ); fwrite( $this->debugOutputResource, sprintf( 'memory used: %d' . PHP_EOL, memory_get_usage() ) ); } return true; } /** * Returns an array representation of a callback which will be used to write * batch items. * * @return array */ abstract protected function getCallback(); /** * @param array $options [optional] { * Configuration options. * * @type resource $debugOutputResource A resource to output debug output * to. **Defaults to** `php://stderr`. * @type bool $debugOutput Whether or not to output debug information. * Please note that unless a debug output resource is configured * this setting will only apply to CLI based applications. * **Defaults to** `false`. * @type array $batchOptions A set of options for a BatchJob. * {@see \Google\Cloud\Core\Batch\BatchJob::__construct()} for * more details. * **Defaults to** ['batchSize' => 1000, * 'callPeriod' => 2.0, * 'numWorkers' => 2]. * @type array $clientConfig A config used to construct the client upon * which requests will be made. * @type BatchRunner $batchRunner A BatchRunner object. Mainly used for * the tests to inject a mock. **Defaults to** a newly created * BatchRunner. * @type string $identifier An identifier for the batch job. This * value must be unique across all job configs. * @type string $batchMethod The name of the batch method used to * deliver items. * @type ClosureSerializerInterface $closureSerializer An implementation * responsible for serializing closures used in the * `$clientConfig`. This is especially important when using the * batch daemon. **Defaults to** * {@see \Google\Cloud\Core\Batch\OpisClosureSerializer} if the * `opis/closure` library is installed. * } * @throws \InvalidArgumentException */ private function setCommonBatchProperties(array $options = []) { if (!isset($options['identifier'])) { throw new \InvalidArgumentException( 'A valid identifier is required in order to register a job.' ); } if (!isset($options['batchMethod'])) { throw new \InvalidArgumentException( 'A batchMethod is required.' ); } $this->setSerializableClientOptions($options); $this->batchMethod = $options['batchMethod']; $this->identifier = $options['identifier']; $this->debugOutputResource = $options['debugOutputResource'] ?? fopen('php://stderr', 'w'); $this->debugOutput = $options['debugOutput'] ?? false; $batchOptions = $options['batchOptions'] ?? []; $this->batchOptions = $batchOptions + [ 'batchSize' => 1000, 'callPeriod' => 2.0, 'numWorkers' => 2 ]; $this->batchRunner = $options['batchRunner'] ?? new BatchRunner(); $this->batchRunner->registerJob( $this->identifier, [$this, 'send'], $this->batchOptions ); } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Batch/ClosureSerializerInterface.php ================================================ baseDir = getenv('GOOGLE_CLOUD_BATCH_DAEMON_FAILURE_DIR'); if ('false' === $this->baseDir) { // setting the file to the string "false" will prevent logging of failed items return; } if ($this->baseDir === false) { $this->baseDir = sprintf( '%s/batch-daemon-failure', sys_get_temp_dir() ); } if (!is_dir($this->baseDir) && !@mkdir($this->baseDir, 0700, true) && !is_dir($this->baseDir)) { throw new \RuntimeException( sprintf( 'Could not create a directory: %s', $this->baseDir ) ); } // Use getmypid for simplicity. $this->failureFile = sprintf( '%s/failed-items-%d', $this->baseDir, getmypid() ); } /** * Save the items to the failureFile. We silently abandon the items upon * failures in this method because there's nothing we can do. * * @param int $idNum A numeric id for the job. * @param array $items Items to save. */ public function handleFailure($idNum, array $items) { if (!$this->failureFile) { $this->initFailureFile(); } if ($this->failureFile) { $fp = @fopen($this->failureFile, 'a'); @fwrite($fp, json_encode(serialize([$idNum => $items])) . PHP_EOL); @fclose($fp); } } /** * Get all the filenames for the failure files. * * @return array Filenames for all the failure files. */ private function getFailedFiles() { $pattern = sprintf('%s/failed-items-*', $this->baseDir); return glob($pattern) ?: []; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Batch/InMemoryConfigStorage.php ================================================ config = new JobConfig(); $this->created = microtime(true); $this->initFailureFile(); $this->hasShutdownHookRegistered = false; } /** * Just return true * * @return bool */ public function lock() { return true; } /** * Just return true * * @return bool */ public function unlock() { return true; } /** * Save the given JobConfig. * * @param JobConfig $config A JobConfig to save. * @return bool */ public function save(JobConfig $config) { $this->config = $config; return true; } /** * Load a JobConfig from the storage. * * @return JobConfig * @throws \RuntimeException when failed to load the JobConfig. */ public function load() { return $this->config; } /** * Clear the JobConfig from storage. */ public function clear() { $this->config = new JobConfig(); } /** * Hold the items in memory and run the job in the same process when it * meets the condition. * * We want to delay registering the shutdown function. The error * reporter also registers a shutdown function and the order matters. * * @see \Google\Cloud\ErrorReporting\Bootstrap::init() * @see http://php.net/manual/en/function.register-shutdown-function.php * * @param mixed $item An item to submit. * @param int $idNum A numeric id for the job. * @return void */ public function submit($item, $idNum) { if (!$this->hasShutdownHookRegistered) { register_shutdown_function([$this, 'shutdown']); $this->hasShutdownHookRegistered = true; } if (!array_key_exists($idNum, $this->items)) { $this->items[$idNum] = []; $this->lastInvoked[$idNum] = $this->created; } $this->items[$idNum][] = $item; $job = $this->config->getJobFromIdNum($idNum); $batchSize = $job->getBatchSize(); $period = $job->getCallPeriod(); if ((count($this->items[$idNum]) >= $batchSize) || (count($this->items[$idNum]) !== 0 && microtime(true) > $this->lastInvoked[$idNum] + $period)) { $this->flush($idNum); $this->items[$idNum] = []; $this->lastInvoked[$idNum] = microtime(true); } } /** * Run the job with the given id. * * @param int $idNum A numeric id for the job. * @return bool */ public function flush($idNum) { if (isset($this->items[$idNum])) { $job = $this->config->getJobFromIdNum($idNum); if (!$job->flush($this->items[$idNum])) { $this->handleFailure($idNum, $this->items[$idNum]); } $this->items[$idNum] = []; $this->lastInvoked[$idNum] = microtime(true); } return true; } /** * Run the job for remainder items. */ public function shutdown() { foreach ($this->items as $idNum => $items) { if (count($items) !== 0) { $this->flush($idNum); } } } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Batch/InterruptTrait.php ================================================ shutdown = true; break; } } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Batch/JobConfig.php ================================================ identifierToId) ? $this->jobs[$identifier] : null; } /** * Get the job with the given numeric id. * * @param int $idNum A numeric id of the job. * * @return JobInterface|null */ public function getJobFromIdNum($idNum) { return array_key_exists($idNum, $this->idToIdentifier) ? $this->jobs[$this->idToIdentifier[$idNum]] : null; } /** * Register a job for executing in batch. * * @param string $identifier Unique identifier of the job. * @param callable $callback Callback that accepts the job $idNum * and returns a JobInterface instance. * @return void */ public function registerJob($identifier, $callback) { if (array_key_exists($identifier, $this->identifierToId)) { $idNum = $this->identifierToId[$identifier]; } else { $idNum = count($this->identifierToId) + 1; $this->idToIdentifier[$idNum] = $identifier; } $this->jobs[$identifier] = call_user_func( $callback, $idNum ); $this->identifierToId[$identifier] = $idNum; } /** * Get all the jobs indexed by the job's identifier. * * @return array Associative array of JobInterface instances keyed by a * string identifier. */ public function getJobs() { return $this->jobs; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Batch/JobInterface.php ================================================ identifier; } /** * Return the job id * * @return int */ public function id() { return $this->id; } /** * Returns the number of workers for this job. **Defaults to* 1. * * @return int */ public function numWorkers() { return $this->numWorkers; } /** * Returns the optional file required to run this job. * * @return string|null */ public function bootstrapFile() { return $this->bootstrapFile; } /** * Runs the job loop. This is expected to be a blocking call. */ abstract public function run(); /** * Finish any pending activity for this job. * * @param array $items * @return bool */ public function flush(array $items = []) { return false; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Batch/OpisClosureSerializer.php ================================================ runner = $runner ?: new BatchRunner(); $this->initFailureFile(); } /** * Retry all the failed items. */ public function retryAll() { foreach ($this->getFailedFiles() as $file) { // Rename the file first $tmpFile = dirname($file) . '/retrying-' . basename($file); rename($file, $tmpFile); $fp = @fopen($tmpFile, 'r'); if ($fp === false) { fwrite( STDERR, sprintf('Could not open the file: %s' . PHP_EOL, $tmpFile) ); continue; } while ($line = fgets($fp)) { $jsonDecodedValue = json_decode($line); // Check if data json_encoded after serialization if ($jsonDecodedValue !== null || $jsonDecodedValue !== false) { $line = $jsonDecodedValue; } $a = unserialize($line); $idNum = key($a); $job = $this->runner->getJobFromIdNum($idNum); if (! $job->callFunc($a[$idNum])) { $this->handleFailure($idNum, $a[$idNum]); } } @fclose($fp); @unlink($tmpFile); } } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Batch/SerializableClientTrait.php ================================================ null, 'clientConfig' => [] ]; $this->closureSerializer = $options['closureSerializer'] ?? $this->getDefaultClosureSerializer(); $this->setWrappedClientConfig($options); } /** * @param array $options */ private function setWrappedClientConfig(array $options) { $config = $options['clientConfig'] ?? []; if ($config && $this->closureSerializer) { $this->closureSerializer->wrapClosures($config); } $this->clientConfig = $config; } /** * @return array */ private function getUnwrappedClientConfig() { if ($this->clientConfig && $this->closureSerializer) { $this->closureSerializer->unwrapClosures($this->clientConfig); } return $this->clientConfig; } /** * @return ClosureSerializerInterface|null */ private function getDefaultClosureSerializer() { if (function_exists('Opis\Closure\serialize')) { return new OpisClosureSerializerV4(); } if (class_exists(SerializableClosure::class)) { return new OpisClosureSerializer(); } } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Batch/SimpleJob.php ================================================ identifier = $identifier; $this->func = $func; $this->id = $id; $options += [ 'bootstrapFile' => null, 'numWorkers' => 1 ]; $this->numWorkers = $options['numWorkers']; $this->bootstrapFile = $options['bootstrapFile']; } /** * Runs the job loop. This is expected to be a blocking call. */ public function run() { if ($this->bootstrapFile) { require_once $this->bootstrapFile; } call_user_func($this->func); } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Batch/SimpleJobTrait.php ================================================ null, ]; $this->setSerializableClientOptions($options); $identifier = $options['identifier']; $configStorage = $options['configStorage'] ?: $this->defaultConfigStorage(); $result = $configStorage->lock(); if ($result === false) { return false; } $config = $configStorage->load(); $config->registerJob( $identifier, function ($id) use ($identifier, $options) { return new SimpleJob($identifier, [$this, 'run'], $id, $options); } ); try { $result = $configStorage->save($config); } finally { $configStorage->unlock(); } return $result; } private function defaultConfigStorage() { if ($this->isSysvIPCLoaded() && $this->isDaemonRunning()) { return new SysvConfigStorage(); } else { return InMemoryConfigStorage::getInstance(); } } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Batch/SysvConfigStorage.php ================================================ shmSize = intval(getenv('GOOGLE_CLOUD_BATCH_SHM_SIZE')); if ($this->shmSize === 0) { $this->shmSize = self::DEFAULT_SHM_SIZE; } $this->perm = octdec(getenv('GOOGLE_CLOUD_BATCH_PERM')); if ($this->perm === 0) { $this->perm = self::DEFAULT_PERM; } $this->project = getenv('GOOGLE_CLOUD_BATCH_PROJECT'); if ($this->project === false) { $this->project = self::DEFAULT_PROJECT; } $this->sysvKey = ftok(__FILE__, $this->project); $this->semid = sem_get($this->sysvKey, 1, $this->perm, 1); } /** * Acquire a lock. * * @return bool */ public function lock() { return sem_acquire($this->semid); } /** * Release a lock. * * @return bool */ public function unlock() { return sem_release($this->semid); } /** * Save the given JobConfig. * * @param JobConfig $config A JobConfig to save. * @return bool * @throws \RuntimeException when failed to attach to the shared memory or serialization fails */ public function save(JobConfig $config) { $shmid = shm_attach($this->sysvKey, $this->shmSize, $this->perm); if ($shmid === false) { throw new \RuntimeException( 'Failed to attach to the shared memory' ); } // If the variable write fails, clear the memory and re-raise the exception try { $result = shm_put_var($shmid, self::VAR_KEY, $config); } catch (\Exception $e) { $this->clear(); throw new \RuntimeException($e->getMessage()); } finally { shm_detach($shmid); } return $result; } /** * Load a JobConfig from the storage. * * @return JobConfig * @throws \RuntimeException when failed to attach to the shared memory or deserialization fails */ public function load() { $shmid = shm_attach($this->sysvKey, $this->shmSize, $this->perm); if ($shmid === false) { throw new \RuntimeException( 'Failed to attach to the shared memory' ); } if (! shm_has_var($shmid, self::VAR_KEY)) { $result = new JobConfig(); } else { $result = shm_get_var($shmid, self::VAR_KEY); } shm_detach($shmid); if ($result === false) { throw new \RuntimeException( 'Failed to deserialize data from shared memory' ); } return $result; } /** * Clear the JobConfig from storage. */ public function clear() { $shmid = shm_attach($this->sysvKey, $this->shmSize, $this->perm); shm_remove_var($shmid, self::VAR_KEY); } /** * Serialize the object */ public function __serialize() { $vars = get_object_vars($this); // As of PHP 8.0, "semid" is the unserializable object "SysvSemaphore" // @see https://github.com/googleapis/google-cloud-php/issues/3749 unset($vars['semid']); return $vars; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Batch/SysvProcessor.php ================================================ sysvQs)) { $this->sysvQs[$idNum] = msg_get_queue($this->getSysvKey($idNum)); } $result = @msg_send( $this->sysvQs[$idNum], self::$typeDirect, $item, true, false ); if ($result === false) { // Try to put the content in a temp file and send the filename. $tempFile = tempnam(sys_get_temp_dir(), 'Item'); $result = file_put_contents($tempFile, serialize($item)); if ($result === false) { throw new \RuntimeException( "Failed to write to $tempFile while submiting the item" ); } $result = @msg_send( $this->sysvQs[$idNum], self::$typeFile, $tempFile, true, false ); if ($result === false) { @unlink($tempFile); throw new QueueOverflowException(); } } } /** * Run the job with the given id. This has no effect and simply always * returns false when using the batch daemon. * * @param int $idNum A numeric id of the job. * @return bool */ public function flush($idNum) { return false; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Blob.php ================================================ value = Utils::streamFor($value); } /** * Get the blob contents as a stream * * Example: * ``` * $value = $blob->get(); * ``` * * @return StreamInterface */ public function get() { return $this->value; } /** * Cast the blob to a string * * @access private * @return string */ public function __toString() { return (string) $this->value; } /** * Implement JsonSerializable by returning a base64 encoded string of the blob * * @return string * @access private */ #[\ReturnTypeWillChange] public function jsonSerialize() { return base64_encode((string) $this->value); } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/ClientTrait.php ================================================ isGrpcLoaded(); $defaultTransport = $isGrpcExtensionLoaded ? 'grpc' : 'rest'; $transport = strtolower($config['transport'] ?? $defaultTransport); if ($transport === 'grpc') { if (!$isGrpcExtensionLoaded) { throw new GoogleException( 'gRPC support has been requested but required dependencies ' . 'have not been found. ' . $this->getGrpcInstallationMessage() ); } } return $transport; } /** * Throw an exception if the gRPC extension is not loaded. * * @throws GoogleException */ private function requireGrpc() { if (!$this->isGrpcLoaded()) { throw new GoogleException( 'The requested client requires the gRPC extension. ' . $this->getGrpcInstallationMessage() ); } } /** * @return string */ private function getGrpcInstallationMessage() { return 'Please see https://cloud.google.com/php/grpc for installation ' . 'instructions.'; } /** * Fetch and validate the keyfile and set the project ID. * * @param array $config * @return array * @throws GoogleException */ private function configureAuthentication(array $config) { $credentialsFetcher = $config['credentialsFetcher'] ?? null; if (!($credentialsFetcher instanceof FetchAuthTokenInterface)) { $config['keyFile'] = $this->getKeyFile($config); } $this->projectId = $this->detectProjectId($config); return $config; } /** * Get a keyfile if it exists. * * Process: * 1. If $config['keyFile'] is set, use that. * 2. If $config['keyFilePath'] is set, load the file and use that. * 3. If GOOGLE_APPLICATION_CREDENTIALS environment variable is set, load * from that location and use that. * 4. If OS-specific well-known-file is set, load from that location and use * that. * * @param array $config * @return array|null Key data * @throws GoogleException */ private function getKeyFile(array $config = []) { $config += [ 'keyFile' => null, 'keyFilePath' => null, ]; if ($config['keyFile']) { return $config['keyFile']; } if ($config['keyFilePath']) { if (!file_exists($config['keyFilePath'])) { throw new GoogleException(sprintf( 'Given keyfile path %s does not exist', $config['keyFilePath'] )); } try { $keyFileData = $this->jsonDecode(file_get_contents($config['keyFilePath']), true); } catch (\InvalidArgumentException $ex) { throw new GoogleException(sprintf( 'Given keyfile at path %s was invalid', $config['keyFilePath'] )); } return $keyFileData; } return CredentialsLoader::fromEnv() ?: CredentialsLoader::fromWellKnownFile(); } /** * Detect and return a project ID. * * Process: * 1. If $config['projectId'] is set, use that. * 2. If an emulator is enabled, return a dummy value. * 3. If $config['keyFile'] is set, attempt to retrieve a project ID from * that. * 4. Check `GOOGLE_CLOUD_PROJECT` environment variable. * 5. Check `GCLOUD_PROJECT` environment variable. * 6. If code is running on compute engine, try to get the project ID from * the metadata store. * 7. Throw exception. * * @param array $config * @return string * @throws GoogleException */ private function detectProjectId(array $config) { $config += [ 'credentialsFetcher' => null, 'httpHandler' => null, 'projectId' => null, 'projectIdRequired' => false, 'hasEmulator' => false, 'preferNumericProjectId' => false, 'suppressKeyFileNotice' => false ]; if ($config['projectId']) { return $config['projectId']; } if ($config['hasEmulator']) { return 'emulator-project'; } if ($config['credentialsFetcher'] instanceof ProjectIdProviderInterface) { return $config['credentialsFetcher']->getProjectId(); } if (isset($config['keyFile'])) { if (isset($config['keyFile']['project_id'])) { return $config['keyFile']['project_id']; } if ($config['suppressKeyFileNotice'] !== true) { $serviceAccountUri = 'https://cloud.google.com/iam/docs/' . 'creating-managing-service-account-keys#creating_service_account_keys'; trigger_error( sprintf( 'A keyfile was given, but it does not contain a project ' . 'ID. This can indicate an old and obsolete keyfile, ' . 'in which case you should create a new one. To suppress ' . 'this message, set `suppressKeyFileNotice` to `true` in your client configuration. ' . 'To learn more about generating new keys, see this URL: %s', $serviceAccountUri ), E_USER_NOTICE ); } } if (getenv('GOOGLE_CLOUD_PROJECT')) { return getenv('GOOGLE_CLOUD_PROJECT'); } if (getenv('GCLOUD_PROJECT')) { return getenv('GCLOUD_PROJECT'); } if ($this->onGce($config['httpHandler'])) { $metadata = $this->getMetaData(); $projectId = $config['preferNumericProjectId'] ? $metadata->getNumericProjectId() : $metadata->getProjectId(); if ($projectId) { return $projectId; } } if ($config['projectIdRequired']) { throw new GoogleException( 'No project ID was provided, ' . 'and we were unable to detect a default project ID.' ); } return ''; } /** * Abstract the GCECredentials call so we can mock it in the unit tests! * * @codeCoverageIgnore * @return bool */ protected function onGce($httpHandler) { return GCECredentials::onGce($httpHandler); } /** * Abstract the Metadata instantiation for unit testing * * @codeCoverageIgnore * @return Metadata */ protected function getMetaData() { return new Metadata(); } /** * Abstract the checking of the grpc extension for unit testing. * * @codeCoverageIgnore * @return bool */ protected function isGrpcLoaded() { return extension_loaded('grpc'); } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Compute/Metadata/Readers/HttpHandlerReader.php ================================================ httpHandler = $httpHandler ?: HttpHandlerFactory::build(HttpClientCache::getHttpClient()); } /** * Read the metadata for a given path. * * @param string $path The metadata path, relative to `/computeMetadata/v1/`. * @return string */ public function read($path) { $url = sprintf( 'http://%s/computeMetadata/v1/%s', GCECredentials::METADATA_IP, $path ); $request = new Request('GET', $url, [ GCECredentials::FLAVOR_HEADER => 'Google' ]); $handler = $this->httpHandler; $res = $handler($request); return (string) $res->getBody(); } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Compute/Metadata/Readers/ReaderInterface.php ================================================ [ 'method' => 'GET', 'header' => GCECredentials::FLAVOR_HEADER . ': Google' ], ]; $this->context = $this->createStreamContext($options); } /** * Read the metadata for a given path. * * @param string $path The metadata path, relative to `/computeMetadata/v1/`. * @return string */ public function read($path) { $url = sprintf( 'http://%s/computeMetadata/v1/%s', GCECredentials::METADATA_IP, $path ); return $this->getMetadata($url); } /** * Abstracted for testing. * * @param array $options * @return resource * @codeCoverageIgnore */ protected function createStreamContext(array $options) { return stream_context_create($options); } /** * Abstracted for testing. * * @param string $url * @return string * @codeCoverageIgnore */ protected function getMetadata($url) { return file_get_contents($url, false, $this->context); } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Compute/Metadata.php ================================================ getProjectId(); * ``` * * ``` * // It is easy to get any metadata from a project. * $val = $metadata->getProjectMetadata($key); * ``` */ class Metadata { /** * @var ReaderInterface The metadata reader. */ private $reader; /** * @var string The project id. */ private $projectId; /** * @var int The numeric project id. */ private $numericProjectId; /** * @param ReaderInterface $reader [optional] A metadata reader implementation. */ public function __construct(?ReaderInterface $reader = null) { $this->reader = $reader ?: new HttpHandlerReader(); } /** * Replace the default reader implementation * * @deprecated If a custom reader implementation is desired, provide it at * construction. * @param ReaderInterface $reader The reader implementation */ public function setReader(ReaderInterface $reader) { $this->reader = $reader; } /** * Fetch a metadata item by its path * * Example: * ``` * $projectId = $metadata->get('project/project-id'); * ``` * * @param string $path The path of the item to retrieve. */ public function get($path) { return $this->reader->read($path); } /** * Detect and return the project ID * * Example: * ``` * $projectId = $metadata->getProjectId(); * ``` * * @return string */ public function getProjectId() { if (!isset($this->projectId)) { $this->projectId = $this->get('project/project-id'); } return $this->projectId; } /** * Detect and return the numeric project ID * * Example: * ``` * $projectId = $metadata->getNumericProjectId(); * ``` * * @return string */ public function getNumericProjectId() { if (!isset($this->numericProjectId)) { $this->numericProjectId = $this->get('project/numeric-project-id'); } return $this->numericProjectId; } /** * Fetch an item from the project metadata * * Example: * ``` * $foo = $metadata->getProjectMetadata('foo'); * ``` * * @param string $key The metadata key * @return string */ public function getProjectMetadata($key) { $path = 'project/attributes/' . $key; return $this->get($path); } /** * Fetch an item from the instance metadata * * Example: * ``` * $foo = $metadata->getInstanceMetadata('foo'); * ``` * * @param string $key The instance metadata key * @return string */ public function getInstanceMetadata($key) { $path = 'instance/attributes/' . $key; return $this->get($path); } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/ConcurrencyControlTrait.php ================================================ connection)) { $props['connection'] = get_class($this->connection); } if (isset($props['__excludeFromDebug'])) { $exclude = $props['__excludeFromDebug']; unset($props['__excludeFromDebug']); foreach ($exclude as $e) { unset($props[$e]); } } return $props; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/DetectProjectIdTrait.php ================================================ null, 'projectId' => null, 'projectIdRequired' => false, 'hasEmulator' => false, 'credentials' => null, ]; if ($config['projectId']) { return $config['projectId']; } if ($config['hasEmulator']) { return 'emulator-project'; } if ($config['credentials'] && $config['credentials'] instanceof ProjectIdProviderInterface && $projectId = $config['credentials']->getProjectId()) { return $projectId; } if (getenv('GOOGLE_CLOUD_PROJECT')) { return getenv('GOOGLE_CLOUD_PROJECT'); } if (getenv('GCLOUD_PROJECT')) { return getenv('GCLOUD_PROJECT'); } $this->throwExceptionIfProjectIdRequired($config); return ''; } /** * Throws an exception if project id is required. * @param array $config * @throws GoogleException */ private function throwExceptionIfProjectIdRequired(array $config) { if ($config['projectIdRequired']) { throw new GoogleException( 'No project ID was provided, ' . 'and we were unable to detect a default project ID.' ); } } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Duration.php ================================================ seconds = $seconds; $this->nanos = $nanos; } /** * Get the duration * * Example: * ``` * $res = $duration->get(); * ``` * * @return array */ public function get() { return [ 'seconds' => $this->seconds, 'nanos' => $this->nanos ]; } /** * Format the value as a string. * * Example: * ``` * echo $duration->formatAsString(); * ``` * * @return string */ public function formatAsString() { return json_encode($this->get()); } /** * Format the value as a string. * * @return string * @access private */ public function __toString() { return $this->formatAsString(); } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/EmulatorTrait.php ================================================ $emulatorHost, 'credentials' => new InsecureCredentialsWrapper(), ]; if (class_exists('Grpc\ChannelCredentials')) { $config['transportConfig'] = [ 'grpc' => [ 'stubOpts' => [ 'credentials' => \Grpc\ChannelCredentials::createInsecure() ] ] ]; } return $config; } /** * Retrieve a valid base uri for a service emulator. * * @param string $emulatorHost * @return string */ private function emulatorBaseUri($emulatorHost) { $emulatorUriComponents = parse_url($emulatorHost); $emulatorUriComponents = array_merge(['scheme' => 'http', 'port' => ''], $emulatorUriComponents); $baseUri = "{$emulatorUriComponents['scheme']}://{$emulatorUriComponents['host']}"; $baseUri .= $emulatorUriComponents['port'] ? ":{$emulatorUriComponents['port']}/" : '/'; return $baseUri; } /** * When emulators are enabled, use them as the service host. * * This method is deprecated and will be removed in a future major release. * * @param string $baseUri * @param string $emulatorHost [optional] * @return string * * @deprecated * @access private */ public function getEmulatorBaseUri($baseUri, $emulatorHost = null) { if ($emulatorHost) { $baseUri = $this->emulatorBaseUri($emulatorHost); } return $baseUri; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Exception/AbortedException.php ================================================ message = $message; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Exception/ServerException.php ================================================ serviceException = $serviceException; $this->metadata = $metadata; $this->errorInfo = null; $this->errorInfoMetadata = null; $this->errorReason = null; parent::__construct($message ?: '', $code); } /** * If $serviceException is set, return true. * * @return bool */ public function hasServiceException() { return (bool) $this->serviceException; } /** * Return the service exception object. * * @return Exception|null */ public function getServiceException() { return $this->serviceException; } /** * Get exception metadata. */ public function getMetadata() { return $this->metadata; } /** * Returns the metadata from the ErrorInfo part of the exception * * @return array */ public function getErrorInfoMetadata() { // Only calc the metadata if we haven't cached it if (is_null($this->errorInfoMetadata)) { // For response originated from the GAPIC layer, the current exception would have // an ApiException within itself if ($this->getServiceException() instanceof ApiException) { return $this->getServiceException()->getErrorInfoMetadata(); } $errorInfo = $this->getErrorInfoFromRestException(); // Cache the result to be reused if needed $this->errorInfoMetadata = $errorInfo['metadata'] ?? []; } return $this->errorInfoMetadata; } /** * Returns the reason from the ErrorInfo part of the exception * * @return string */ public function getReason() { // Only calc the errorReason if we haven't cached it if (is_null($this->errorReason)) { // For a response originated from the GAPIC layer, the current exception would have // an ApiException within itself if ($this->getServiceException() instanceof ApiException) { return $this->getServiceException()->getReason(); } $errorInfo = $this->getErrorInfoFromRestException(); // Cache the result to be reused if needed $this->errorReason = $errorInfo['reason'] ?? ''; } return $this->errorReason; } /** * Return the delay in seconds and nanos before retrying the failed request. * * @return array */ public function getRetryDelay() { $metadata = array_filter($this->metadata, function ($metadataItem) { return array_key_exists('retryDelay', $metadataItem); }); if (count($metadata) === 0) { return ['seconds' => 0, 'nanos' => 0]; } return $metadata[0]['retryDelay'] + [ 'seconds' => 0, 'nanos' => 0 ]; } /** * Helper to return the error info from an exception * which is not raised from the GAPIC layer * * @return array */ private function getErrorInfoFromRestException() { // Only calc errorInfo if it isn't cached if (is_null($this->errorInfo)) { $this->errorInfo = []; $arr = json_decode($this->getMessage(), true); if (!isset($arr['error']['details'])) { return $this->errorInfo; } foreach ($arr['error']['details'] as $row) { if (isset($row['@type']) && $row['@type'] === self::ERRORINFO_TYPE_REST) { // save this in cache $this->errorInfo = $row; break; } } } return $this->errorInfo; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/ExponentialBackoff.php ================================================ retries = $retries !== null ? (int) $retries : 3; $this->retryFunction = $retryFunction; $this->retryListener = $retryListener; // @todo revisit this approach // @codeCoverageIgnoreStart $this->delayFunction = static function ($delay) { usleep($delay); }; // @codeCoverageIgnoreEnd } /** * Executes the retry process. * * @param callable $function * @param array $arguments [optional] * @return mixed * @throws \Exception The last exception caught while retrying. */ public function execute(callable $function, array $arguments = []) { $delayFunction = $this->delayFunction; $calcDelayFunction = $this->calcDelayFunction ?: [$this, 'calculateDelay']; $retryAttempt = 0; $exception = null; while (true) { try { return call_user_func_array($function, $arguments); } catch (\Exception $exception) { if ($this->retryFunction) { if (!call_user_func($this->retryFunction, $exception, $retryAttempt)) { throw $exception; } } if ($retryAttempt >= $this->retries) { break; } $delayFunction($calcDelayFunction($retryAttempt)); $retryAttempt++; if ($this->retryListener) { // Developer can modify the $arguments using the retryListener // callback. call_user_func_array( $this->retryListener, [$exception, $retryAttempt, &$arguments] ); } } } throw $exception; } /** * If not set, defaults to using `usleep`. * * @param callable $delayFunction * @return void */ public function setDelayFunction(callable $delayFunction) { $this->delayFunction = $delayFunction; } /** * If not set, defaults to using * {@see \Google\Cloud\Core\ExponentialBackoff::calculateDelay()}. * * @param callable $calcDelayFunction * @return void */ public function setCalcDelayFunction(callable $calcDelayFunction) { $this->calcDelayFunction = $calcDelayFunction; } /** * Calculates exponential delay. * * @param int $attempt The attempt number used to calculate the delay. * @return int */ public static function calculateDelay($attempt) { return min( mt_rand(0, 1000000) + (pow(2, $attempt) * 1000000), self::MAX_DELAY_MICROSECONDS ); } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/GeoPoint.php ================================================ latitude = $this->validateValue($latitude, 'latitude', $allowNull); $this->longitude = $this->validateValue($longitude, 'longitude', $allowNull); } /** * Get the latitude * * Example: * ``` * $latitude = $point->latitude(); * ``` * * @return float|null */ public function latitude() { $this->checkContext('latitude', func_get_args()); return $this->latitude; } /** * Set the latitude * * Non-numeric values will result in an exception * * Example: * ``` * $point->setLatitude(42.279594); * ``` * * @param int|float $latitude The new latitude * @return GeoPoint * @throws \InvalidArgumentException */ public function setLatitude($latitude) { $this->latitude = $this->validateValue($latitude, 'latitude'); return $this; } /** * Get the longitude * * Example: * ``` * $longitude = $point->longitude(); * ``` * * @return float|null */ public function longitude() { $this->checkContext('longitude', func_get_args()); return $this->longitude; } /** * Set the longitude * * Non-numeric values will result in an exception. * * Example: * ``` * $point->setLongitude(-83.732124); * ``` * * @param float|int $longitude The new longitude value * @return GeoPoint * @throws \InvalidArgumentException */ public function setLongitude($longitude) { $this->longitude = $this->validateValue($longitude, 'longitude'); return $this; } /** * Return a GeoPoint * * Example: * ``` * $point = $point->point(); * ``` * * @return array [LatLng](https://cloud.google.com/datastore/reference/rest/Shared.Types/LatLng) */ public function point() { return [ 'latitude' => $this->latitude, 'longitude' => $this->longitude ]; } /** * Let people know if they accidentally use the getter in setter context. * * @param string $method the method name * @param array $args The method arguments * @throws \InvalidArgumentException * @return void */ private function checkContext($method, array $args) { if (count($args) > 0) { throw new InvalidArgumentException(sprintf( 'Calling method %s with arguments is unsupported.', $method )); } } /** * Check a given value's validity as a coordinate. * * Numeric values will be cast to type `float`. All other values will raise * an exception with the exception of `null`, if `$allowNull` is set to true. * * @param mixed $value The coordinate value. * @param string $type The coordinate type for error reporting. * @param bool $allowNull [optional] Whether null values should be allowed. * **Defaults to** `false`. * @return float|null */ private function validateValue($value, $type, $allowNull = false) { if (!is_numeric($value) && (!$allowNull || ($allowNull && $value !== null))) { throw new InvalidArgumentException(sprintf( 'Given %s must be a numeric value.', $type )); } return $allowNull && $value === null ? $value : (float) $value; } /** * Implement JsonSerializable by representing GeoPoint as a JSON-object: * * ``` * { * latitude: 31.778333 * longitude: 35.229722 * } * ``` * * @return object * @access private */ #[\ReturnTypeWillChange] public function jsonSerialize() { return (object) $this->point(); } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/GrpcRequestWrapper.php ================================================ setCommonDefaults($config); $config += [ 'authHttpHandler' => null, 'serializer' => new Serializer(), 'grpcOptions' => [] ]; $this->authHttpHandler = $config['authHttpHandler'] ?: HttpHandlerFactory::build(); $this->serializer = $config['serializer']; $this->grpcOptions = $config['grpcOptions']; } /** * Deliver the request. * * @param callable $request The request to execute. * @param array $args The arguments for the request. * @param array $options [optional] { * Request options. * * @type float $requestTimeout Seconds to wait before timing out the * request. **Defaults to** `60`. * @type int $retries Number of retries for a failed request. * **Defaults to** `3`. * @type callable $grpcRetryFunction Sets the conditions for whether or * not a request should attempt to retry. Function signature should * match: `function (\Exception $ex) : bool`. * @type array $grpcOptions gRPC specific configuration options. * } * @return array * @throws Exception\ServiceException */ public function send(callable $request, array $args, array $options = []) { $retries = $options['retries'] ?? $this->retries; $retryFunction = $options['grpcRetryFunction'] ?? function (\Exception $ex) { $statusCode = $ex->getCode(); return in_array($statusCode, $this->grpcRetryCodes); }; $grpcOptions = $options['grpcOptions'] ?? $this->grpcOptions; $timeout = $options['requestTimeout'] ?? $this->requestTimeout; $backoff = new ExponentialBackoff($retries, $retryFunction); if (!isset($grpcOptions['retrySettings'])) { $retrySettings = [ 'retriesEnabled' => false ]; if ($timeout) { $retrySettings['noRetriesRpcTimeoutMillis'] = $timeout * 1000; } $grpcOptions['retrySettings'] = $retrySettings; } $optionalArgs = &$args[count($args) - 1]; $optionalArgs += $grpcOptions; try { return $this->handleResponse($backoff->execute($request, $args)); } catch (\Exception $ex) { if ($ex instanceof ApiException) { throw $this->convertToGoogleException($ex); } throw $ex; } } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/GrpcTrait.php ================================================ requestWrapper = $requestWrapper; } /** * Get the GrpcRequestWrapper. * * @return GrpcRequestWrapper|null */ public function requestWrapper() { return $this->requestWrapper; } /** * Delivers a request. * * @param callable $request * @param array $args * @param bool $whitelisted * @return \Generator|array * @throws ServiceException */ public function send(callable $request, array $args, $whitelisted = false) { $requestOptions = $this->pluckArray([ 'grpcOptions', 'retries', 'requestTimeout', 'grpcRetryFunction' ], $args[count($args) - 1]); try { return $this->requestWrapper->send($request, $args, $requestOptions); } catch (NotFoundException $e) { if ($whitelisted) { throw $this->modifyWhitelistedError($e); } throw $e; } } /** * Gets the default configuration for generated clients. * * @param string $version * @param callable|null $authHttpHandler * @param string|null $universeDomain * @return array */ private function getGaxConfig( $version, ?callable $authHttpHandler = null, ?string $universeDomain = null ) { $config = [ 'libName' => 'gccl', 'libVersion' => $version, 'transport' => 'grpc' ]; // GAX v0.32.0 introduced the CredentialsWrapper class and a different // way to configure credentials. If the class exists, use this new method // otherwise default to legacy usage. if (class_exists(CredentialsWrapper::class)) { $config['credentials'] = new CredentialsWrapper( $this->requestWrapper->getCredentialsFetcher(), $authHttpHandler, // If the universe domain hasn't been explicitly set, check the the environment variable, // otherwise assume GDU ("googleapis.com"). $universeDomain ?: getenv('GOOGLE_CLOUD_UNIVERSE_DOMAIN') ?: GetUniverseDomainInterface::DEFAULT_UNIVERSE_DOMAIN ); } else { $config += [ 'credentialsLoader' => $this->requestWrapper->getCredentialsFetcher(), 'authHttpHandler' => $authHttpHandler, 'enableCaching' => false ]; } return $config; } use TimeTrait; /** * Format a struct for the API. * * @param array $fields * @return array */ private function formatStructForApi(array $fields) { $fFields = []; foreach ($fields as $key => $value) { $fFields[$key] = $this->formatValueForApi($value); } return ['fields' => $fFields]; } private function unpackStructFromApi(array $struct) { $vals = []; foreach ($struct['fields'] as $key => $val) { $vals[$key] = $this->unpackValue($val); } return $vals; } private function unpackValue($value) { if (count($value) > 1) { throw new \RuntimeException("Unexpected fields in struct: $value"); } foreach ($value as $setField => $setValue) { switch ($setField) { case 'listValue': $valueList = []; foreach ($setValue['values'] as $innerValue) { $valueList[] = $this->unpackValue($innerValue); } return $valueList; case 'structValue': return $this->unpackStructFromApi($value['structValue']); default: return $setValue; } } } private function flattenStruct(array $struct) { return $struct['fields']; } private function flattenValue(array $value) { if (count($value) > 1) { throw new \RuntimeException("Unexpected fields in struct: $value"); } if (isset($value['nullValue'])) { return null; } return array_pop($value); } private function flattenListValue(array $value) { return $value['values']; } /** * Format a list for the API. * * @param array $list * @return array */ private function formatListForApi(array $list) { $values = []; foreach ($list as $value) { $values[] = $this->formatValueForApi($value); } return ['values' => $values]; } /** * Format a value for the API. * * @param mixed $value * @return array */ private function formatValueForApi($value) { $type = gettype($value); switch ($type) { case 'string': return ['string_value' => $value]; case 'double': case 'integer': return ['number_value' => $value]; case 'boolean': return ['bool_value' => $value]; case 'NULL': return ['null_value' => NullValue::NULL_VALUE]; case 'array': if (!empty($value) && $this->isAssoc($value)) { return ['struct_value' => $this->formatStructForApi($value)]; } return ['list_value' => $this->formatListForApi($value)]; } return []; } /** * Format a gRPC timestamp to match the format returned by the REST API. * * @param array $timestamp * @return string */ private function formatTimestampFromApi(array $timestamp) { $timestamp += [ 'seconds' => 0, 'nanos' => 0 ]; $dt = $this->createDateTimeFromSeconds($timestamp['seconds']); return $this->formatTimeAsString($dt, $timestamp['nanos']); } /** * Format a timestamp for the API with nanosecond precision. * * @param string $value * @return array */ private function formatTimestampForApi($value) { list($dt, $nanos) = $this->parseTimeString($value); return [ 'seconds' => (int) $dt->format('U'), 'nanos' => (int) $nanos ]; } /** * Format a duration for the API. * * @param string|mixed $value * @return array */ private function formatDurationForApi($value) { if (is_string($value)) { $d = explode('.', trim($value, 's')); if (count($d) < 2) { $seconds = $d[0]; $nanos = 0; } else { $seconds = (int) $d[0]; $nanos = $this->convertFractionToNanoSeconds($d[1]); } } elseif ($value instanceof Duration) { $d = $value->get(); $seconds = $d['seconds']; $nanos = $d['nanos']; } return [ 'seconds' => $seconds, 'nanos' => $nanos ]; } /** * Format a duration from the API * * @param array $value * @return string */ private function formatDurationFromApi($value): string { $seconds = $value['seconds']; $nanos = str_pad($value['nanos'], 9, 0, STR_PAD_LEFT); return "{$seconds}.{$nanos}s"; } /** * Construct a gapic client. Allows for tests to intercept. * * @param string $gapicName * @param array $config * @return mixed */ protected function constructGapic($gapicName, array $config) { return new $gapicName($config); } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Iam/Iam.php ================================================ 'my-project']); * $instance = $spanner->instance('my-new-instance'); * * $iam = $instance->iam(); * ``` */ class Iam { /** * @var IamConnectionInterface */ private $connection; /** * @var string */ private $resource; /** * @var array */ private $policy; /** * @var array */ private $args; /** * @var array */ private $options; /** * @param IamConnectionInterface $connection * @param string $resource * @param array $options [optional] { * Configuration Options * * @type string|null $parent The parent request parameter for the policy. * If set, policy data will be sent as `request.{$parent}`. * Otherwise, policy will be sent in request root. **Defaults to** * `policy`. * @type array $args Arbitrary data to be sent with the request. * } * @access private */ public function __construct(IamConnectionInterface $connection, $resource, array $options = []) { $options += [ 'parent' => 'policy', 'args' => [] ]; $this->connection = $connection; $this->resource = $resource; $this->options = $options; } /** * Get the existing IAM policy for this resource. * * If a policy has already been retrieved from the API, it will be returned. * To fetch a fresh copy of the policy, use * {@see \Google\Cloud\Core\Iam\Iam::reload()}. * * Example: * ``` * $policy = $iam->policy(); * ``` * * @param array $options Configuration Options * @param int $options['requestedPolicyVersion'] Specify the policy version to * request from the server. Please see * [policy versioning](https://cloud.google.com/iam/docs/policies#versions) * for more information. * @return array An array of policy data */ public function policy(array $options = []) { if (!$this->policy) { $this->reload($options); } return $this->policy; } /** * Set the IAM policy for this resource. * * Bindings with invalid roles, or non-existent members will raise a server * error. * * Example: * ``` * $oldPolicy = $iam->policy(); * $oldPolicy['bindings'][0]['members'] = 'user:test@example.com'; * * $policy = $iam->setPolicy($oldPolicy); * ``` * * @param array|PolicyBuilder $policy The new policy, as an array or an * instance of {@see \Google\Cloud\Core\Iam\PolicyBuilder}. * @param array $options Configuration Options * @return array An array of policy data * @throws \InvalidArgumentException If the given policy is not an array or PolicyBuilder. */ public function setPolicy($policy, array $options = []) { if ($policy instanceof PolicyBuilder) { $policy = $policy->result(); } if (!is_array($policy)) { throw new \InvalidArgumentException('Given policy data must be an array or an instance of PolicyBuilder.'); } $request = []; if ($this->options['parent']) { $parent = $this->options['parent']; $request[$parent] = $policy; } else { $request = $policy; } return $this->policy = $this->connection->setPolicy([ 'resource' => $this->resource ] + $request + $options + $this->options['args']); } /** * Test if the current user has the given permissions on this resource. * * Invalid permissions will raise a BadRequestException. * * Example: * ``` * $allowedPermissions = $iam->testPermissions([ * 'pubsub.topics.publish', * 'pubsub.topics.attachSubscription' * ]); * ``` * * @param array $permissions A list of permissions to test * @param array $options Configuration Options * @return array A subset of $permissions, with only those allowed included. */ public function testPermissions(array $permissions, array $options = []) { $res = $this->connection->testPermissions([ 'permissions' => $permissions, 'resource' => $this->resource ] + $options + $this->options['args']); return (isset($res['permissions'])) ? $res['permissions'] : []; } /** * Refresh the IAM policy for this resource. * * Example: * ``` * $policy = $iam->reload(); * ``` * * @param array $options Configuration Options * @return array An array of policy data */ public function reload(array $options = []) { return $this->policy = $this->connection->getPolicy([ 'resource' => $this->resource ] + $options + $this->options['args']); } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Iam/IamConnectionInterface.php ================================================ topic('my-new-topic'); * * $iam = $topic->iam(); * ``` * * @internal */ class IamManager { use ArrayTrait; private RequestHandler $requestHandler; private Serializer $serializer; private string $clientClass; private string $resource; private ?array $policy; /** * @param RequestHandler $requestHandler * @param Serializer $serializer The serializer instance to encode/decode messages. * @param string $clientClass The client class that will be passed on to the * sendRequest method of the $requestHandler. * @param string $resource * @access private */ public function __construct( RequestHandler $requestHandler, Serializer $serializer, string $clientClass, string $resource ) { $this->requestHandler = $requestHandler; $this->serializer = $serializer; $this->clientClass = $clientClass; $this->resource = $resource; $this->policy = null; } /** * Get the existing IAM policy for this resource. * * If a policy has already been retrieved from the API, it will be returned. * To fetch a fresh copy of the policy, use * {@see IamManager::reload()}. * * Example: * ``` * $policy = $iam->policy(); * ``` * * @param array $options Configuration Options * @param int $options['requestedPolicyVersion'] Specify the policy version to * request from the server. Please see * [policy versioning](https://cloud.google.com/iam/docs/policies#versions) * for more information. * @return array An array of policy data */ public function policy(array $options = []) { if (!$this->policy) { $this->reload($options); } return $this->policy; } /** * Set the IAM policy for this resource. * * Bindings with invalid roles, or non-existent members will raise a server * error. * * Example: * ``` * $policy = [ * 'bindings' => [[ * 'role' => 'roles/editor', * 'members' => ['user:test@example.com'], * ]] * ]; * $policy = $iam->setPolicy($policy); * ``` * ``` * $oldPolicy = $iam->policy(); * $oldPolicy['bindings'][0]['members'] = 'user:test@example.com'; * * $policy = $iam->setPolicy($oldPolicy); * ``` * * @param array|PolicyBuilder $policy The new policy, as an array or an * instance of {@see PolicyBuilder}. * @param array $options Configuration Options * @return array An array of policy data * @throws InvalidArgumentException If the given policy is not an array or PolicyBuilder. */ public function setPolicy($policy, array $options = []) { if ($policy instanceof PolicyBuilder) { $policy = $policy->result(); } if (!is_array($policy)) { throw new InvalidArgumentException('Given policy data must be an array or an instance of PolicyBuilder.'); } $policy = $this->serializer->decodeMessage( new Policy(), $policy ); $updateMask = $options['updateMask'] ?? []; $data = ['resource' => $this->resource, 'policy' => $policy, 'updateMask' => $updateMask]; $request = $this->serializer->decodeMessage(new SetIamPolicyRequest(), $data); $this->policy = $this->requestHandler->sendRequest( $this->clientClass, 'setIamPolicy', $request, $options ); return $this->policy; } /** * Test if the current user has the given permissions on this resource. * * Invalid permissions will raise a BadRequestException. * * Example: * ``` * $allowedPermissions = $iam->testPermissions([ * 'pubsub.topics.publish', * 'pubsub.topics.attachSubscription' * ]); * ``` * * @param array $permissions A list of permissions to test * @param array $options Configuration Options * @return array A subset of $permissions, with only those allowed included. */ public function testPermissions(array $permissions, array $options = []) { $data = ['resource' => $this->resource, 'permissions' => $permissions]; $request = $this->serializer->decodeMessage(new TestIamPermissionsRequest(), $data); $res = $this->requestHandler->sendRequest( $this->clientClass, 'testIamPermissions', $request, $options ); return isset($res['permissions']) ? $res['permissions'] : []; } /** * Refresh the IAM policy for this resource. * * Example: * ``` * $policy = $iam->reload(); * ``` * * @param array $options Configuration Options * @return array An array of policy data */ public function reload(array $options = []) { $policyOptions = $this->pluck('policyOptions', $options, false) ?: []; $policyOptions = $this->serializer->decodeMessage(new GetPolicyOptions(), $policyOptions); $data = ['resource' => $this->resource, 'options' => $policyOptions]; $request = $this->serializer->decodeMessage(new GetIamPolicyRequest(), $data); $this->policy = $this->requestHandler->sendRequest( $this->clientClass, 'getIamPolicy', $request, $options ); return $this->policy; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Iam/PolicyBuilder.php ================================================ addBinding('roles/admin', [ 'user:admin@domain.com' ]); * $result = $builder->result(); * ``` */ class PolicyBuilder { /** * @var array */ private $bindings; /** * @var string */ private $etag; /** * @var int */ private $version; /** * Create a PolicyBuilder. * * To use conditions in the bindings, the version of the policy must be set * to 3. * * @see https://cloud.google.com/iam/docs/policies#versions Policy versioning * @see https://cloud-dot-devsite.googleplex.com/storage/docs/access-control/using-iam-permissions#conditions-iam * Using Cloud IAM Conditions on buckets * * Example: * ``` * $policy = [ * 'etag' => 'AgIc==', * 'version' => 3, * 'bindings' => [ * [ * 'role' => 'roles/admin', * 'members' => [ * 'user:admin@domain.com', * 'user2:admin@domain.com' * ], * 'condition' => [ * 'title' => 'match-prefix', * 'description' => 'Applies to objects matching a prefix', * 'expression' => * 'resource.name.startsWith("projects/_/buckets/bucket-name/objects/prefix-a-")' * ] * ] * ], * ]; * * $builder = new PolicyBuilder($policy); * ``` * * @param array $policy A policy array * @throws \InvalidArgumentException */ public function __construct(array $policy = []) { if (isset($policy['bindings'])) { $this->setBindings($policy['bindings']); } elseif (!empty($policy)) { throw new InvalidArgumentException('Invalid Policy'); } if (isset($policy['etag'])) { $this->setEtag($policy['etag']); } if (isset($policy['version'])) { $this->setVersion($policy['version']); } } /** * Override all stored bindings on the policy. * * Example: * ``` * $builder->setBindings([ * [ * 'role' => 'roles/admin', * 'members' => [ * 'user:admin@domain.com' * ], * 'condition' => [ * 'expression' => * 'request.time < timestamp("2020-07-01T00:00:00.000Z")' * ] * ] * ]); * ``` * * @param array $bindings [optional] An array of bindings * @return PolicyBuilder * @throws \InvalidArgumentException */ public function setBindings(array $bindings = []) { $this->bindings = $bindings; return $this; } /** * Add a new binding to the policy. * * This method will fail with an InvalidOpereationException if it is * called on a Policy with a version greater than 1 as that indicates * a more complicated policy than this method is prepared to handle. * Changes to such policies must be made manually by the setBindings() * method. * * * Example: * ``` * $builder->addBinding('roles/admin', [ 'user:admin@domain.com' ]); * ``` * * @param string $role A valid role for the service * @param array $members An array of members to assign to the binding * @return PolicyBuilder * @throws \InvalidArgumentException * @throws BadMethodCallException if the policy's version is greater than 1. * @deprecated */ public function addBinding($role, array $members) { $this->validatePolicyVersion(); $this->bindings[] = [ 'role' => $role, 'members' => $members ]; return $this; } /** * Remove a binding from the policy. * * This method will fail with a BadMethodCallException if it is * called on a Policy with a version greater than 1 as that indicates * a more complicated policy than this method is prepared to handle. * Changes to such policies must be made manually by the setBindings() * method. * * Example: * ``` * $builder->setBindings([ * [ * 'role' => 'roles/admin', * 'members' => [ * 'user:admin@domain.com', * 'user2:admin@domain.com' * ] * ] * ]); * $builder->removeBinding('roles/admin', [ 'user:admin@domain.com' ]); * ``` * * @param string $role A valid role for the service * @param array $members An array of members to remove from the role * @return PolicyBuilder * @throws \InvalidArgumentException * @throws BadMethodCallException if the policy's version is greater than 1. * @deprecated */ public function removeBinding($role, array $members) { $this->validatePolicyVersion(); $bindings = $this->bindings; foreach ((array) $bindings as $i => $binding) { if ($binding['role'] == $role) { $newMembers = array_diff($binding['members'], $members); if (count($newMembers) != count($binding['members']) - count($members)) { throw new InvalidArgumentException('One or more role-members were not found.'); } if (empty($newMembers)) { unset($bindings[$i]); $bindings = array_values($bindings); } else { $binding['members'] = array_values($newMembers); $bindings[$i] = $binding; } $this->bindings = $bindings; return $this; } } throw new InvalidArgumentException('The role was not found.'); } /** * Update the etag on the policy. * * Example: * ``` * $builder->setEtag($oldPolicy['etag']); * ``` * * @param string $etag used for optimistic concurrency control as a way to help prevent simultaneous updates of a * policy from overwriting each other. It is strongly suggested that updates to existing policies make use * of the etag to avoid race conditions. * @return PolicyBuilder */ public function setEtag($etag) { $this->etag = $etag; return $this; } /** * Update the version of the policy. * * Example: * ``` * $builder->setVersion(1); * ``` * * @param int $version Version of the Policy. **Defaults to** `0`. * @return PolicyBuilder */ public function setVersion($version) { $this->version = $version; return $this; } /** * Create a policy array with data in the correct format. * * Example: * ``` * $policy = $builder->result(); * ``` * * @return array An array of policy data */ public function result() { return array_filter([ 'etag' => $this->etag, 'bindings' => $this->bindings, 'version' => $this->version ]); } private function validatePolicyVersion() { if (isset($this->version) && $this->version > 1) { throw new BadMethodCallException('Helper methods cannot be ' . "invoked on policies with version {$this->version}."); } $this->validateConditions(); } private function validateConditions() { if (!$this->bindings) { return; } foreach ($this->bindings as $binding) { if (isset($binding['condition'])) { throw new BadMethodCallException('Helper methods cannot ' . 'be invoked on policies containing conditions.'); } } } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/InsecureCredentialsWrapper.php ================================================ value = $value; } /** * Get the value. * * Example: * ``` * $value = $int64->get(); * ``` * * @return string */ public function get() { return $this->value; } /** * Provides a convenient way to access the value. * * @access private */ public function __toString() { return $this->value; } /** * Implement JsonSerializable by returning the 64 bit integer as a string * * @return string * @access private */ #[\ReturnTypeWillChange] public function jsonSerialize() { return $this->value; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Iterator/ItemIterator.php ================================================ */ class ItemIterator implements \Iterator { use ItemIteratorTrait; } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Iterator/ItemIteratorTrait.php ================================================ pageIterator = $pageIterator; } /** * Fetch the token used to get the next set of results. * * @return string|null */ public function nextResultToken() { return method_exists($this->pageIterator, 'nextResultToken') ? $this->pageIterator->nextResultToken() : null; } /** * Iterate over the results on a per page basis. * * @return \Iterator */ public function iterateByPage() { return $this->pageIterator; } /** * Rewind the iterator. * * @return null */ #[\ReturnTypeWillChange] public function rewind() { $this->pageIndex = 0; $this->position = 0; $this->pageIterator->rewind(); } /** * Get the current item. * * @return mixed */ #[\ReturnTypeWillChange] public function current() { $page = $this->pageIterator->current(); return isset($page[$this->pageIndex]) ? $page[$this->pageIndex] : null; } /** * Get the key current item's key. * * @return int */ #[\ReturnTypeWillChange] public function key() { return $this->position; } /** * Advances to the next item. * * @return null */ #[\ReturnTypeWillChange] public function next() { $this->pageIndex++; $this->position++; if (count($this->pageIterator->current()) <= $this->pageIndex && $this->nextResultToken()) { $this->pageIterator->next(); $this->pageIndex = 0; } } /** * Determines if the current position is valid. * * @return bool */ #[\ReturnTypeWillChange] public function valid() { $page = $this->pageIterator->current(); if (isset($page[$this->pageIndex])) { return true; } // If there are no results, but a token for the next page // exists let's continue paging until there are results. while ($this->nextResultToken()) { $this->pageIterator->next(); $page = $this->pageIterator->current(); if (isset($page[$this->pageIndex])) { return true; } } return false; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Iterator/PageIterator.php ================================================ resultMapper = $resultMapper; $this->call = $call; $this->config = $config + [ 'itemsKey' => 'items', 'nextResultTokenKey' => 'nextPageToken', 'resultTokenKey' => 'pageToken', 'firstPage' => null, 'resultLimit' => 0, 'setNextResultTokenCondition' => function () { return true; } ]; $this->callOptions = $callOptions; $this->resultTokenPath = explode('.', $this->config['resultTokenKey']); $this->nextResultTokenPath = explode('.', $this->config['nextResultTokenKey']); $this->itemsPath = explode('.', $this->config['itemsKey']); $this->initialResultToken = $this->nextResultToken(); } /** * Fetch the token used to get the next set of results. * * @return string|null */ public function nextResultToken() { return $this->get($this->resultTokenPath, $this->callOptions); } /** * Rewind the iterator. * * @return null */ #[\ReturnTypeWillChange] public function rewind() { $this->itemCount = 0; $this->position = 0; if ($this->config['firstPage']) { list($this->page, $shouldContinue) = $this->mapResults($this->config['firstPage']); $nextResultToken = $this->determineNextResultToken($this->page, $shouldContinue); } else { $this->page = null; $nextResultToken = $this->initialResultToken; } if ($nextResultToken) { $this->set($this->resultTokenPath, $this->callOptions, $nextResultToken); } } /** * Get the current page. * * @return array|null */ #[\ReturnTypeWillChange] public function current() { if ($this->page === null) { $this->page = $this->executeCall(); } $page = $this->get($this->itemsPath, $this->page); if ($this->nextResultToken()) { return $page ?: []; } return $page; } /** * Get the key current page's key. * * @return int */ #[\ReturnTypeWillChange] public function key() { return $this->position; } /** * Advances to the next page. * * @return null */ #[\ReturnTypeWillChange] public function next() { $this->position++; $this->page = $this->nextResultToken() ? $this->executeCall() : null; } /** * Determines if the current position is valid. * * @return bool */ #[\ReturnTypeWillChange] public function valid() { if (!$this->page && $this->position) { return false; } return true; } /** * Executes the provided call to get a set of results. * * @return array */ private function executeCall() { $call = $this->call; list($results, $shouldContinue) = $this->mapResults( $call($this->callOptions) ); $this->set( $this->resultTokenPath, $this->callOptions, $this->determineNextResultToken($results, $shouldContinue) ); return $results; } /** * @param array $results * @return array */ private function mapResults(array $results) { $items = $this->get($this->itemsPath, $results); $resultMapper = $this->resultMapper; $shouldContinue = true; if ($items) { foreach ($items as $key => $item) { $items[$key] = $resultMapper($item); $this->itemCount++; if ($this->config['resultLimit'] && $this->config['resultLimit'] <= $this->itemCount) { $items = array_slice($items, 0, $key + 1); $shouldContinue = false; break; } } $this->set($this->itemsPath, $results, $items); } return [$results, $shouldContinue]; } /** * @param array $results * @param bool $shouldContinue * @return null */ private function determineNextResultToken(array $results, $shouldContinue = true) { return $shouldContinue && $this->config['setNextResultTokenCondition']($results) ? $this->get($this->nextResultTokenPath, $results) : null; } /** * @param array $path * @param array $array * @return mixed */ private function get(array $path, array $array) { $result = $array; foreach ($path as $key) { if (!isset($result[$key])) { return null; } $result = $result[$key]; } return $result; } /** * @param array $path * @param array $array * @param mixed $value * @return null */ private function set(array $path, array &$array, $value) { $temp = &$array; foreach ($path as $key) { $temp = &$temp[$key]; } $temp = $value; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/JsonTrait.php ================================================ true ]; $this->exclusive = $options['exclusive']; $this->filePath = sprintf( self::FILE_PATH_TEMPLATE, sys_get_temp_dir(), $fileName ); } /** * Acquires a lock that will block until released. * * @param array $options [optional] { * Configuration options. * * @type bool $blocking Whether the process should block while waiting * to acquire the lock. **Defaults to** true. * } * @return bool * @throws \RuntimeException If the lock fails to be acquired. */ public function acquire(array $options = []) { if ($this->handle) { return true; } $this->handle = $this->initializeHandle(); if (!flock($this->handle, $this->lockType($options))) { fclose($this->handle); $this->handle = null; throw new \RuntimeException('Failed to acquire lock.'); } return true; } /** * Releases the lock. * * @throws \RuntimeException If the lock fails to release. */ public function release() { if ($this->handle) { $released = flock($this->handle, LOCK_UN); fclose($this->handle); $this->handle = null; if (!$released) { throw new \RuntimeException('Failed to release lock.'); } } } /** * Initializes the handle. * * @return resource * @throws \RuntimeException If the lock file fails to open. */ private function initializeHandle() { $handle = @fopen($this->filePath, 'c'); if (!$handle) { throw new \RuntimeException('Failed to open lock file.'); } return $handle; } private function lockType(array $options) { $options += [ 'blocking' => true ]; $lockType = $this->exclusive ? LOCK_EX : LOCK_SH; if (!$options['blocking']) { $lockType |= LOCK_UN; } return $lockType; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Lock/LockInterface.php ================================================ acquire($options)) { try { $result = $func(); } catch (\Exception $ex) { $exception = $ex; } $this->release(); } if ($exception) { throw $exception; } return $result; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Lock/SemaphoreLock.php ================================================ isSysvIPCLoaded()) { throw new \RuntimeException('SystemV IPC extensions are required.'); } if (!is_int($key)) { throw new \InvalidArgumentException('The provided key must be an integer.'); } $this->key = $key; } /** * Acquires a lock that will block until released. * * @param array $options [optional] { * Configuration options. * * @type bool $blocking Whether the process should block while waiting * to acquire the lock. **Defaults to** true. * } * @return bool * @throws \RuntimeException If the lock fails to be acquired. */ public function acquire(array $options = []) { $options += [ 'blocking' => true ]; if ($this->semaphoreId) { return true; } $this->semaphoreId = $this->initializeId(); if (!sem_acquire($this->semaphoreId, !$options['blocking'])) { $this->semaphoreId = null; throw new \RuntimeException('Failed to acquire lock.'); } return true; } /** * Releases the lock. * * @throws \RuntimeException If the lock fails to release. */ public function release() { if ($this->semaphoreId) { $released = sem_release($this->semaphoreId); $this->semaphoreId = null; if (!$released) { throw new \RuntimeException('Failed to release lock.'); } } } /** * Initializes the semaphore ID. * * @return resource * @throws \RuntimeException If semaphore ID fails to generate. */ private function initializeId() { $semaphoreId = sem_get($this->key); if (!$semaphoreId) { throw new \RuntimeException('Failed to generate semaphore ID.'); } return $semaphoreId; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Lock/SymfonyLockAdapter.php ================================================ lock = $lock; } /** * Acquires a lock that will block until released. * * @param array $options [optional] { * Configuration options. * * @type bool $blocking Whether the process should block while waiting * to acquire the lock. **Defaults to** true. * } * @return bool * @throws \RuntimeException If the lock fails to be acquired. */ public function acquire(array $options = []) { $options += [ 'blocking' => true ]; try { return $this->lock->acquire($options['blocking']); } catch (\Exception $ex) { throw new \RuntimeException( sprintf( 'Acquiring the lock failed with the following message: %s', $ex->getMessage() ), 0, $ex ); } } /** * Releases the lock. * * @throws \RuntimeException */ public function release() { try { $this->lock->release(); } catch (\Exception $ex) { throw new \RuntimeException( sprintf( 'Releasing the lock failed with the following message: %s', $ex->getMessage() ), 0, $ex ); } } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Logger/AppEngineFlexFormatter.php ================================================ formatPayload($record, parent::format($record)); } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Logger/AppEngineFlexFormatterV2.php ================================================ formatPayload($record, parent::format($record)); } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Logger/AppEngineFlexFormatterV3.php ================================================ formatPayload($record, parent::format($record)); } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Logger/AppEngineFlexHandler.php ================================================ toArray(); } list($usec, $sec) = explode(' ', microtime()); $usec = (int) (((float) $usec) * 1000000000); $sec = (int) $sec; $payload = [ 'message' => $message, 'timestamp' => ['seconds' => $sec, 'nanos' => $usec], 'thread' => '', 'severity' => $record['level_name'], ]; if (isset($_SERVER['HTTP_X_CLOUD_TRACE_CONTEXT'])) { $payload['traceId'] = explode( '/', $_SERVER['HTTP_X_CLOUD_TRACE_CONTEXT'] )[0]; } return "\n" . json_encode($payload); } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/LongRunning/LROTrait.php ================================================ lroConnection = $lroConnection; $this->lroCallables = $lroCallables; $this->lroResource = $resource; } /** * Resume a Long Running Operation * * @param string $operationName The Long Running Operation name. * @param array $info [optional] The operation data. * @return LongRunningOperation */ public function resumeOperation($operationName, array $info = []) { return new LongRunningOperation( $this->lroConnection, $operationName, $this->lroCallables, $info ); } /** * List long running operations. * * @param array $options [optional] { * Configuration Options. * * @type string $name The name of the operation collection. * @type string $filter The standard list filter. * @type int $pageSize Maximum number of results to return per * request. * @type int $resultLimit Limit the number of results returned in total. * **Defaults to** `0` (return all results). * @type string $pageToken A previously-returned page token used to * resume the loading of results from a specific point. * } * @return ItemIterator */ public function longRunningOperations(array $options = []) { if (is_null($this->lroResource)) { throw new \BadMethodCallException('This service does list support listing operations.'); } $resultLimit = $this->pluck('resultLimit', $options, false) ?: 0; $options['name'] = $this->lroResource . '/operations'; return new ItemIterator( new PageIterator( function (array $operation) { return $this->resumeOperation($operation['name'], $operation); }, [$this->lroConnection, 'operations'], $options, [ 'itemsKey' => 'operations', 'resultLimit' => $resultLimit ] ) ); } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/LongRunning/LongRunningClientConnection.php ================================================ gapicClient->resumeOperation($args['name']); return $this->operationResponseToArray($operationResponse); } /** * @param array $args * @return array */ public function cancel(array $args): array { $operationResponse = $this->gapicClient->resumeOperation( $args['name'], $args['method'] ?? null ); $operationResponse->cancel(); return $this->operationResponseToArray($operationResponse); } /** * @param array $args * @return array */ public function delete(array $args): array { $operationResponse = $this->gapicClient->resumeOperation( $args['name'], $args['method'] ?? null ); $operationResponse->cancel(); return $this->operationResponseToArray($operationResponse); } /** * @param array $args * @return array */ public function operations(array $args): array { $request = ListOperationsRequest::build($args['name'], $args['filter'] ?? null); $response = $this->gapicClient->getOperationsClient()->listOperations($request); return $this->handleResponse($response); } private function operationResponseToArray(OperationResponse $operationResponse): array { $response = $this->handleResponse($operationResponse->getLastProtoResponse()); $metaType = $response['metadata']['typeUrl']; // unpack result Any type $result = $operationResponse->getResult(); if ($result instanceof Any) { // For some reason we aren't doing this in GAX OperationResponse (but we should) $result = $result->unpack(); } $response['response'] = $this->handleResponse($result); // unpack error Any type $response['error'] = $this->handleResponse($operationResponse->getError()); $metadata = $operationResponse->getMetadata(); if ($metadata instanceof Any) { // For some reason we aren't doing this in GAX OperationResponse (but we should) $metadata = $metadata->unpack(); } $response['metadata'] = $this->handleResponse($metadata); // Used in LongRunningOperation to invoke callables $response['metadata'] += ['typeUrl' => $metaType]; return $response; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/LongRunning/LongRunningConnectionInterface.php ================================================ connection = $connection; $this->name = $name; $this->callablesMap = $callablesMap; $this->info = $info; } /** * Return the Operation name. * * Example: * ``` * $name = $operation->name(); * ``` * * @return string */ public function name() { return $this->name; } /** * Check if the Operation is done. * * If the Operation state is not available, a service request may be executed * by this method. * * Example: * ``` * if ($operation->done()) { * echo "The operation is done!"; * } * ``` * * @param array $options [optional] Configuration options. * @return bool */ public function done(array $options = []) { return (isset($this->info($options)['done'])) ? $this->info['done'] : false; } /** * Get the state of the Operation. * * Return value will be one of `LongRunningOperation::STATE_IN_PROGRESS`, * `LongRunningOperation::STATE_SUCCESS` or * `LongRunningOperation::STATE_ERROR`. * * If the Operation state is not available, a service request may be executed * by this method. * * Example: * ``` * switch ($operation->state()) { * case LongRunningOperation::STATE_IN_PROGRESS: * echo "Operation is in progress"; * break; * * case LongRunningOperation::STATE_SUCCESS: * echo "Operation succeeded"; * break; * * case LongRunningOperation::STATE_ERROR: * echo "Operation failed"; * break; * } * ``` * * @param array $options [optional] Configuration options. * @return string */ public function state(array $options = []) { if (!$this->done($options)) { return self::STATE_IN_PROGRESS; } if ($this->done() && $this->result()) { return self::STATE_SUCCESS; } return self::STATE_ERROR; } /** * Get the Operation result. * * The return type of this method is dictated by the type of Operation. * * Returns null if the Operation is not yet complete, or if an error occurred. * * If the Operation state is not available, a service request may be executed * by this method. * * Example: * ``` * $result = $operation->result(); * ``` * * @param array $options [optional] Configuration options. * @return T|mixed|null */ public function result(array $options = []) { $this->info($options); return $this->result; } /** * Get the Operation error. * * Returns null if the Operation is not yet complete, or if no error occurred. * * If the Operation state is not available, a service request may be executed * by this method. * * Example: * ``` * $error = $operation->error(); * ``` * * @param array $options [optional] Configuration options. * @return array|null */ public function error(array $options = []) { $this->info($options); return $this->error; } /** * Get the Operation info. * * If the Operation state is not available, a service request may be executed * by this method. * * Example: * ``` * $info = $operation->info(); * ``` * * @codingStandardsIgnoreStart * @param array $options [optional] Configuration options. * @return array [google.longrunning.Operation](https://cloud.google.com/spanner/docs/reference/rpc/google.longrunning#google.longrunning.Operation) * @codingStandardsIgnoreEnd */ public function info(array $options = []) { return $this->info ?: $this->reload($options); } /** * Reload the Operation to check its status. * * Example: * ``` * $result = $operation->reload(); * ``` * * @codingStandardsIgnoreStart * @param array $options [optional] Configuration Options. * @return array [google.longrunning.Operation](https://cloud.google.com/spanner/docs/reference/rpc/google.longrunning#google.longrunning.Operation) * @codingStandardsIgnoreEnd */ public function reload(array $options = []) { $res = $this->connection->get([ 'name' => $this->name, ] + $options); $this->result = null; $this->error = null; if ($res['done'] ?? false && isset($res['metadata']['typeUrl'])) { $type = $res['metadata']['typeUrl']; $this->result = $this->executeDoneCallback($type, $res['response']); $this->error = $res['error'] ?? null; } return $this->info = $res; } /** * Reload the operation until it is complete. * * The return type of this method is dictated by the type of Operation. If * `$options.maxPollingDurationSeconds` is set, and the poll exceeds the * limit, the return will be `null`. * * Example: * ``` * $result = $operation->pollUntilComplete(); * ``` * * @param array $options { * Configuration Options * * @type float $pollingIntervalSeconds The polling interval to use, in * seconds. **Defaults to** `1.0`. * @type float $maxPollingDurationSeconds The maximum amount of time to * continue polling. **Defaults to** `0.0`. * } * @return mixed|null */ public function pollUntilComplete(array $options = []) { $options += [ 'pollingIntervalSeconds' => $this::WAIT_INTERVAL, 'maxPollingDurationSeconds' => 0.0, ]; $pollingIntervalMicros = $options['pollingIntervalSeconds'] * 1000000; $maxPollingDuration = $options['maxPollingDurationSeconds']; $hasMaxPollingDuration = $maxPollingDuration > 0.0; $endTime = microtime(true) + $maxPollingDuration; do { usleep($pollingIntervalMicros); $this->reload($options); } while (!$this->done() && (!$hasMaxPollingDuration || microtime(true) < $endTime)); return $this->result; } /** * Cancel a Long Running Operation. * * Example: * ``` * $operation->cancel(); * ``` * * @param array $options Configuration options. * @return void */ public function cancel(array $options = []) { $this->connection->cancel([ 'name' => $this->name ]); } /** * Delete a Long Running Operation. * * Example: * ``` * $operation->delete(); * ``` * * @param array $options Configuration Options. * @return void */ public function delete(array $options = []) { $this->connection->delete([ 'name' => $this->name ]); } /** * When the Operation is complete, there may be a callback enqueued to * handle the response. If so, execute it and return the result. * * @param string $type The response type. * @param mixed $response The response data. * @return mixed */ private function executeDoneCallback($type, $response) { if (is_null($response)) { return null; } $callables = array_filter($this->callablesMap, function ($callable) use ($type) { return $callable['typeUrl'] === $type; }); if (count($callables) === 0) { return $response; } $callable = current($callables); $fn = $callable['callable']; return call_user_func($fn, $response); } /** * @access private */ public function __debugInfo() { return [ 'connection' => get_class($this->connection), 'name' => $this->name, 'callablesMap' => array_keys($this->callablesMap), 'info' => $this->info ]; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/LongRunning/OperationResponseTrait.php ================================================ getLastProtoResponse(); if (is_null($response)) { return null; } $response = $serializer->encodeMessage($response); $result = null; if ($operation->isDone() && isset($response['response']['typeUrl'])) { $type = $response['response']['typeUrl']; $result = $this->deserializeResult($operation, $type, $serializer, $lroMappers); } $metaType = $response['metadata']['typeUrl']; $metaResult = $this->deserializeMetadata($operation, $metaType, $serializer, $lroMappers); /** @see LongRunningOperation#reload() */ $metaResult += ['typeUrl' => $metaType]; $error = $operation->getError(); if (!is_null($error)) { $error = $serializer->encodeMessage($error); } $response['response'] = $result; $response['metadata'] = $metaResult; $response['error'] = $error; return $response; } /** * Fetch an OperationResponse object from a gapic client. * * @param mixed $client A generated client with a `resumeOperation` method. * @param string $name The Operation name. * @param string|null $method The method name. * @return OperationResponse */ private function getOperationByName($client, $name, $method = null) { return $client->resumeOperation($name, $method); } /** * Convert an operation response to an array * * @param OperationResponse|GaxOperationResponse $operation The operation to * serialize. * @param string $type The Operation type. The type should correspond to a * member of $mappers.typeUrl. * @param Serializer|GaxSerializer $serializer The gRPC serializer to use * for the deserialization. * @param array $mappers A list of mappers. * @return array|null */ private function deserializeResult($operation, $type, $serializer, array $mappers) { $mappers = array_filter($mappers, function ($mapper) use ($type) { return $mapper['typeUrl'] === $type; }); if (count($mappers) === 0) { throw new \RuntimeException(sprintf('No mapper exists for operation response type %s.', $type)); } $mapper = current($mappers); $message = $mapper['message']; $response = new $message(); $anyResponse = $operation->getLastProtoResponse()->getResponse(); if (is_null($anyResponse)) { return null; } $response->mergeFromString($anyResponse->getValue()); return $serializer->encodeMessage($response); } /** * Convert an operation metadata to an array * * @param OperationResponse|GaxOperationResponse $operation The operation to * serialize. * @param string $type The Operation type. The type should correspond to a * member of $mappers.typeUrl. * @param Serializer|GaxSerializer $serializer The gRPC serializer to use * for the deserialization. * @param array $mappers A list of mappers. * @return array|null */ private function deserializeMetadata($operation, $type, $serializer, array $mappers) { $mappers = array_filter($mappers, function ($mapper) use ($type) { return $mapper['typeUrl'] === $type; }); if (count($mappers) === 0) { throw new \RuntimeException(sprintf('No mapper exists for operation metadata type %s.', $type)); } $mapper = current($mappers); $message = $mapper['message']; $response = new $message(); $anyResponse = $operation->getLastProtoResponse()->getMetadata(); if (is_null($anyResponse)) { return null; } $response->mergeFromString($anyResponse->getValue()); return $serializer->encodeMessage($response); } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/OptionsValidator.php ================================================ vaidateOptions( * $options, * ['customOp1', 'customOp2'], * new CommitRequest(), * CallOptions::class, * ); * ``` * * @param array $options * @param array|Message|string ...$optionTypes * @return array * @throws LogicException when a value exists which is not supported by any of the `$optionTypes`. */ public function validateOptions(array $options, array|Message|string ...$optionTypes): array { $splitOptions = []; foreach ($optionTypes as $optionType) { if (is_array($optionType)) { $splitOptions[] = $this->pluckArray($optionType, $options); } elseif ($optionType === CallOptions::class) { $callOptionKeys = array_keys((new CallOptions([]))->toArray()); $splitOptions[] = $this->pluckArray($callOptionKeys, $options); } elseif ($optionType instanceof Message) { $messageKeys = array_map( fn ($method) => lcfirst(substr($method, 3)), array_filter( get_class_methods($optionType), fn ($m) => 0 === strpos($m, 'get') ) ); $messageOptions = $this->pluckArray($messageKeys, $options); if ($this->serializer) { $optionType = $this->serializer->decodeMessage($optionType, $messageOptions); } else { $optionType->mergeFromJsonString(json_encode($messageOptions, JSON_FORCE_OBJECT)); } $splitOptions[] = $optionType; } elseif (is_string($optionType)) { $splitOptions[] = $this->pluck($optionType, $options, false); } else { throw new LogicException(sprintf('Invalid option type: %s', $optionType)); } } if (!empty($options)) { throw new LogicException( 'Unexpected option(s) provided: ' . implode(', ', array_keys($options)) ); } return $splitOptions; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/PhpArray.php ================================================ customFilters = $customFilters; $this->useCamelCase = $useCamelCase; } /** * Borrowed heavily from {@see DrSlump\Protobuf\Codec\PhpArray::encodeMessage()}. * With this approach we are able to transform the response with minimal * overhead. */ protected function encodeMessage(Protobuf\Message $message) { $descriptor = Protobuf::getRegistry()->getDescriptor($message); $data = []; foreach ($descriptor->getFields() as $tag => $field) { $empty = !$message->_has($tag); if ($field->isRequired() && $empty) { throw new \UnexpectedValueException( sprintf( 'Message %s\'s field tag %s(%s) is required but has no value', get_class($message), $tag, $field->getName() ) ); } if ($empty) { continue; } $key = $this->useTagNumber ? $field->getNumber() : $field->getName(); $v = $message->_get($tag); if ($field->isRepeated()) { // Make sure the value is an array of values $v = is_array($v) ? $v : [$v]; $arr = []; foreach ($v as $k => $vv) { // Skip nullified repeated values if (null === $vv) { continue; } $filteredValue = $this->filterValue($vv, $field); if ($this->isKeyValueMessage($vv)) { $arr[key($filteredValue)] = current($filteredValue); } else { $arr[$k] = $filteredValue; } $v = $arr; } } else { $v = $this->filterValue($v, $field); } $key = ($this->useCamelCase) ? $this->toCamelCase($key) : $key; if (isset($this->customFilters[$key])) { $v = call_user_func($this->customFilters[$key], $v); } $data[$key] = $v; } return $data; } /** * Borrowed heavily from {@see DrSlump\Protobuf\Codec\PhpArray::decodeMessage()}. * The only addition here is converting camel case field names to snake case. */ protected function decodeMessage(Protobuf\Message $message, $data) { // Get message descriptor $descriptor = Protobuf::getRegistry()->getDescriptor($message); foreach ($data as $key => $v) { // Get the field by tag number or name $field = $this->useTagNumber ? $descriptor->getField($key) : $descriptor->getFieldByName($this->toSnakeCase($key)); // Unknown field found if (!$field) { $unknown = new Protobuf\Codec\PhpArray\Unknown($key, gettype($v), $v); $message->addUnknown($unknown); continue; } if ($field->isRepeated()) { // Make sure the value is an array of values $v = is_array($v) && is_int(key($v)) ? $v : [$v]; foreach ($v as $k => $vv) { $v[$k] = $this->filterValue($vv, $field); } } else { $v = $this->filterValue($v, $field); } $message->_set($field->getNumber(), $v); } return $message; } protected function filterValue($value, Protobuf\Field $field) { if (trim($field->getReference(), '\\') === NullValue::class) { return null; } if ($value instanceof Protobuf\Message) { if ($this->isKeyValueMessage($value)) { $v = $value->getValue(); return [ $value->getKey() => $v instanceof Protobuf\Message ? $this->encodeMessage($v) : $v ]; } if ($value instanceof Struct) { $vals = []; foreach ($value->getFields() as $field) { $val = $this->filterValue( $field->getValue(), $field->descriptor()->getFieldByName('value') ); $vals[$field->getKey()] = $val; } return $vals; } if ($value instanceof ListValue) { $vals = []; foreach ($value->getValuesList() as $val) { $fields = $val->descriptor()->getFields(); foreach ($fields as $field) { $name = $field->getName(); if ($val->$name !== null) { $vals[] = $this->filterValue($val->$name, $field); } } } return $vals; } if ($value instanceof Value) { $fields = $value->descriptor()->getFields(); foreach ($fields as $field) { $name = $field->getName(); if ($value->$name !== null) { return $this->filterValue($value->$name, $field); } } } } return parent::filterValue($value, $field); } private function toSnakeCase($key) { return strtolower(preg_replace(['/([a-z\d])([A-Z])/', '/([^_])([A-Z][a-z])/'], '$1_$2', $key)); } private function toCamelCase($key) { return lcfirst(str_replace(' ', '', ucwords(str_replace('_', ' ', $key)))); } private function isKeyValueMessage($value) { return property_exists($value, 'key') && property_exists($value, 'value'); } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Report/CloudRunJobMetadataProvider.php ================================================ serviceId = $env['CLOUD_RUN_JOB'] ?? 'unknown-job'; $this->revisionId = $env['CLOUD_RUN_EXECUTION'] ?? ''; $this->taskIndex = $env['CLOUD_RUN_TASK_INDEX'] ?? ''; $this->taskAttempt = $env['CLOUD_RUN_TASK_ATTEMPT'] ?? ''; $this->traceId = isset($env['HTTP_X_CLOUD_TRACE_CONTEXT']) ? \substr($env['HTTP_X_CLOUD_TRACE_CONTEXT'], 0, 32) : null; $this->metadata = $metadata ?? new Metadata(); $this->region = \basename($this->metadata->get('instance/region') ?? ''); $this->instanceId = $this->metadata->get('instance/id'); } /** * @return array */ public function monitoredResource() { return [ 'type' => 'cloud_run_job', 'labels' => [ 'job_name' => $this->serviceId, 'location' => $this->region, 'project_id' => $this->projectId(), ], ]; } /** * Return the project id. * @return string */ public function projectId() { return $this->metadata->getProjectId(); } /** * Return the service id. * @return string */ public function serviceId() { return $this->serviceId; } /** * Return the version id. * @return string */ public function versionId() { return $this->revisionId; } /** * Return the labels. * @return array */ public function labels() { $labels = [ 'instanceId' => $this->instanceId, 'run.googleapis.com/execution_name' => $this->revisionId, 'run.googleapis.com/task_attempt' => $this->taskAttempt, 'run.googleapis.com/task_index' => $this->taskIndex, 'run.googleapis.com/trace_id' => $this->traceId, ]; return \array_filter($labels); } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Report/CloudRunMetadataProvider.php ================================================ configurationId = $env['K_CONFIGURATION'] ?? 'unknown-configuration'; $this->serviceId = $env['K_SERVICE'] ?? 'unknown-service'; $this->revisionId = $env['K_REVISION'] ?? 'unknown-revision'; $this->traceId = isset($env['HTTP_X_CLOUD_TRACE_CONTEXT']) ? \substr($env['HTTP_X_CLOUD_TRACE_CONTEXT'], 0, 32) : null; $this->metadata = $metadata ?? new Metadata(); $this->region = \basename($this->metadata->get('instance/region') ?? ''); $this->instanceId = $this->metadata->get('instance/id'); } /** * @return array */ public function monitoredResource() { return [ 'type' => 'cloud_run_revision', 'labels' => [ 'configuration_name' => $this->configurationId, 'location' => $this->region, 'project_id' => $this->projectId(), 'revision_name' => $this->revisionId, 'service_name' => $this->serviceId, ], ]; } /** * Return the project id. * @return string */ public function projectId() { return $this->metadata->getProjectId(); } /** * Return the service id. * @return string */ public function serviceId() { return $this->serviceId; } /** * Return the version id. * @return string */ public function versionId() { return $this->revisionId; } /** * Return the labels. We need to evaluate $_SERVER for each request. * * @return array * @todo Figure out where to get the `container_name` from */ public function labels() { $labels = [ 'instanceId' => $this->instanceId, 'run.googleapis.com/trace_id' => $this->traceId, ]; return \array_filter($labels); } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Report/EmptyMetadataProvider.php ================================================ $this->getTraceValue($server)] : []; $this->data = [ 'resource' => [ 'type' => 'gae_app', 'labels' => [ 'project_id' => $projectId, 'version_id' => $versionId, 'module_id' => $serviceId ] ], 'projectId' => $projectId, 'serviceId' => $serviceId, 'versionId' => $versionId, 'labels' => $labels ]; } /** * Return an array representing MonitoredResource. * * @see https://cloud.google.com/logging/docs/reference/v2/rest/v2/MonitoredResource * * @return array */ public function monitoredResource() { return $this->data['resource']; } /** * Return the project id. * @return string */ public function projectId() { return $this->data['projectId']; } /** * Return the service id. * @return string */ public function serviceId() { return $this->data['serviceId']; } /** * Return the version id. * @return string */ public function versionId() { return $this->data['versionId']; } /** * Return the labels. We need to evaluate $_SERVER for each request. * @return array */ public function labels() { return $this->data['labels']; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Report/GAEStandardMetadataProvider.php ================================================ data['monitoredResource'] = $monitoredResource; $this->data['projectId'] = $projectId; $this->data['serviceId'] = $serviceId; $this->data['versionId'] = $versionId; $this->data['labels'] = $labels; } /** * Return an array representing MonitoredResource. * * @see https://cloud.google.com/logging/docs/reference/v2/rest/v2/MonitoredResource * * @return array */ public function monitoredResource() { return $this->data['monitoredResource']; } /** * Return the project id. * @return string */ public function projectId() { return $this->data['projectId']; } /** * Return the service id. * @return string */ public function serviceId() { return $this->data['serviceId']; } /** * Return the version id. * @return string */ public function versionId() { return $this->data['versionId']; } /** * Return the labels. * @return array */ public function labels() { return $this->data['labels']; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/RequestBuilder.php ================================================ service = $this->loadServiceDefinition($servicePath); $this->resourceRoot = $resourceRoot; // Append service definition base path if bare apiEndpoint domain is given. if (isset($this->service['basePath'])) { $uriParts = parse_url($baseUri) + ['path' => null]; if (!$uriParts['path'] || $uriParts['path'] === '/') { $uriParts['path'] = $this->service['basePath']; // Recreate the URI from its modified parts and ensure it ends in a single slash. $this->baseUri = rtrim((string) Uri::fromParts($uriParts), '/') . '/'; return; } } $this->baseUri = rtrim($baseUri, '/') . '/'; } /** * Build the request. * * @param string $resource * @param string $method * @param array $options [optional] * @return RequestInterface * @todo complexity high, revisit * @todo consider validating against the schemas */ public function build($resource, $method, array $options = []) { $root = $this->resourceRoot; array_push($root, 'resources'); $root = array_merge($root, explode('.', $resource)); array_push($root, 'methods', $method); $action = $this->service; foreach ($root as $rootItem) { if (!isset($action[$rootItem])) { throw new \InvalidArgumentException('Provided path item ' . $rootItem . ' does not exist.'); } $action = $action[$rootItem]; } $path = []; $query = []; $body = []; if (isset($action['parameters'])) { foreach ($action['parameters'] as $parameter => $parameterOptions) { if ($parameterOptions['location'] === 'path' && array_key_exists($parameter, $options)) { $path[$parameter] = $options[$parameter]; unset($options[$parameter]); } if ($parameterOptions['location'] === 'query') { // flatten nested querystring parameters into dot-syntax if (false !== strpos($parameter, '.')) { list($object, $property) = explode('.', $parameter, 2); if (isset($options[$object][$property])) { $options[$parameter] = $options[$object][$property]; } } if (array_key_exists($parameter, $options)) { $query[$parameter] = $options[$parameter]; } } } } if (isset($this->service['parameters'])) { foreach ($this->service['parameters'] as $parameter => $parameterOptions) { if ($parameterOptions['location'] === 'query' && array_key_exists($parameter, $options)) { $query[$parameter] = $options[$parameter]; } } } if (isset($action['request'])) { $schema = $action['request']['$ref']; foreach ($this->service['schemas'][$schema]['properties'] as $property => $propertyOptions) { if (array_key_exists($property, $options)) { $body[$property] = $options[$property]; } } } $uri = $this->buildUriWithQuery( $this->expandUri($this->baseUri . $action['path'], $path), $query ); return new Request( $action['httpMethod'], $uri, ['Content-Type' => 'application/json'], $body ? $this->jsonEncode($body) : null ); } /** * @param string $servicePath * @return array */ private function loadServiceDefinition($servicePath) { return $this->jsonDecode( file_get_contents($servicePath, true), true ); } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/RequestHandler.php ================================================ $clients * @param array $clientConfig */ public function __construct( Serializer $serializer, array $clients, array $clientConfig = [] ) { //@codeCoverageIgnoreStart $this->serializer = $serializer; $clientConfig['serializer'] = $serializer; // Adds some defaults // gccl needs to be present for handwritten clients $clientConfig += [ 'libName' => 'gccl', 'emulatorHost' => null ]; if ((bool) $clientConfig['emulatorHost']) { $emulatorConfig = $this->emulatorGapicConfig($clientConfig['emulatorHost']); $clientConfig = array_merge( $clientConfig, $emulatorConfig ); } //@codeCoverageIgnoreEnd // Initialize the client classes and store them in memory foreach ($clients as $client) { if (is_object($client)) { $this->clients[get_class($client)] = $client; } else { $this->clients[$client] = new $client($clientConfig); } } } /** * Helper function that forwards the request to a client obj. * * @param string $clientClass The request will be forwarded to this client class. * @param string $method This method needs to be called on the client obj. * @param Message $request The protobuf Request instance to pass as the first argument to the $method. * @param array $optionalArgs The optional args. * @param bool $whitelisted This decides the behaviour when a NotFoundException is encountered. * * @return \Generator|OperationResponse|array|null * * @throws ServiceException */ public function sendRequest( string $clientClass, string $method, Message $request, array $optionalArgs, bool $whitelisted = false ) { $clientObj = $this->getClientObject($clientClass); if (!$clientObj) { return null; } $allArgs = [$request]; $allArgs[] = $optionalArgs; try { $callable = [$clientObj, $method]; $response = call_user_func_array($callable, $allArgs); return $this->handleResponse($response); } catch (ApiException $ex) { throw $this->convertToGoogleException($ex); } catch (NotFoundException $e) { if ($whitelisted) { throw $this->modifyWhitelistedError($e); } throw $e; } } /** * Helper function that returns a client object stored in memory * using the client class as key. * @param $clientClass The client class whose object we need. * @return mixed */ private function getClientObject(string $clientClass) { return $this->clients[$clientClass] ?? null; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/RequestProcessorTrait.php ================================================ RetryInfo::class, 'google.rpc.badrequest-bin' => BadRequest::class ]; /** * Serializes a gRPC response. * * @param mixed $response * @return \Generator|OperationResponse|array|null */ private function handleResponse($response) { if ($response instanceof PagedListResponse) { $response = $response->getPage()->getResponseObject(); } if ($response instanceof Message) { return $this->serializer->encodeMessage($response); } if ($response instanceof OperationResponse) { return $response; } if ($response instanceof ServerStream) { return $this->handleStream($response); } return null; } /** * Handles a streaming response. * * @param ServerStream $response * @return \Generator|array|null * @throws Exception\ServiceException */ private function handleStream(ServerStream $response) { try { foreach ($response->readAll() as $count => $result) { $res = $this->serializer->encodeMessage($result); yield $res; } } catch (\Exception $ex) { throw $this->convertToGoogleException($ex); } } /** * Convert a ApiCore exception to a Google Exception. * * @param \Exception $ex * @return ServiceException */ private function convertToGoogleException(\Exception $ex): ServiceException { switch ($ex->getCode()) { case Code::INVALID_ARGUMENT: $exception = Exception\BadRequestException::class; break; case Code::NOT_FOUND: case Code::UNIMPLEMENTED: $exception = Exception\NotFoundException::class; break; case Code::ALREADY_EXISTS: $exception = Exception\ConflictException::class; break; case Code::FAILED_PRECONDITION: $exception = Exception\FailedPreconditionException::class; break; case Code::UNKNOWN: $exception = Exception\ServerException::class; break; case Code::INTERNAL: $exception = Exception\ServerException::class; break; case Code::ABORTED: $exception = Exception\AbortedException::class; break; case Code::DEADLINE_EXCEEDED: $exception = Exception\DeadlineExceededException::class; break; default: $exception = Exception\ServiceException::class; break; } $metadata = []; if (method_exists($ex, 'getMetadata') && $ex->getMetadata()) { foreach ($ex->getMetadata() as $type => $binaryValue) { if (!isset($this->metadataTypes[$type])) { continue; } $metadataElement = new $this->metadataTypes[$type](); $metadataElement->mergeFromString($binaryValue[0]); $metadata[] = $this->serializer->encodeMessage($metadataElement); } } return new $exception($ex->getMessage(), $ex->getCode(), $ex, $metadata); } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/RequestWrapper.php ================================================ `. * @type callable $authHttpHandler A handler used to deliver PSR-7 * requests specifically for authentication. Function signature * should match: * `function (RequestInterface $request, array $options = []) : ResponseInterface`. * @type callable $httpHandler A handler used to deliver PSR-7 requests. * Function signature should match: * `function (RequestInterface $request, array $options = []) : ResponseInterface`. * @type array $restOptions HTTP client specific configuration options. * @type bool $shouldSignRequest Whether to enable request signing. * @type callable $restRetryFunction Sets the conditions for whether or * not a request should attempt to retry. Function signature should * match: `function (\Exception $ex) : bool`. * @type callable $restDelayFunction Executes a delay, defaults to * utilizing `usleep`. Function signature should match: * `function (int $delay) : void`. * @type callable $restCalcDelayFunction Sets the conditions for * determining how long to wait between attempts to retry. Function * signature should match: `function (int $attempt) : int`. * @type string $universeDomain The expected universe of the credentials. Defaults to "googleapis.com". * } */ public function __construct(array $config = []) { $this->setCommonDefaults($config); $config += [ 'accessToken' => null, 'asyncHttpHandler' => null, 'authHttpHandler' => null, 'httpHandler' => null, 'restOptions' => [], 'shouldSignRequest' => true, 'componentVersion' => null, 'restRetryFunction' => null, 'restDelayFunction' => null, 'restCalcDelayFunction' => null, 'universeDomain' => GetUniverseDomainInterface::DEFAULT_UNIVERSE_DOMAIN, ]; $this->componentVersion = $config['componentVersion']; $this->accessToken = $config['accessToken']; $this->restOptions = $config['restOptions']; $this->shouldSignRequest = $config['shouldSignRequest']; $this->retryFunction = $config['restRetryFunction'] ?: $this->getRetryFunction(); $this->delayFunction = $config['restDelayFunction'] ?: function ($delay) { usleep($delay); }; $this->calcDelayFunction = $config['restCalcDelayFunction']; $this->httpHandler = $config['httpHandler'] ?: HttpHandlerFactory::build(); $this->authHttpHandler = $config['authHttpHandler'] ?: $this->httpHandler; $this->asyncHttpHandler = $config['asyncHttpHandler'] ?: $this->buildDefaultAsyncHandler(); $this->universeDomain = $config['universeDomain']; if ($this->credentialsFetcher instanceof AnonymousCredentials) { $this->shouldSignRequest = false; } } /** * Deliver the request. * * @param RequestInterface $request A PSR-7 request. * @param array $options [optional] { * Request options. * * @type float $requestTimeout Seconds to wait before timing out the * request. **Defaults to** `0`. * @type int $retries Number of retries for a failed request. * **Defaults to** `3`. * @type callable $restRetryFunction Sets the conditions for whether or * not a request should attempt to retry. Function signature should * match: `function (\Exception $ex) : bool`. * @type callable $restRetryListener Runs after the restRetryFunction. * This might be used to simply consume the exception and * $arguments b/w retries. This returns the new $arguments thus * allowing modification on demand for $arguments. For ex: * changing the headers in b/w retries. * @type callable $restDelayFunction Executes a delay, defaults to * utilizing `usleep`. Function signature should match: * `function (int $delay) : void`. * @type callable $restCalcDelayFunction Sets the conditions for * determining how long to wait between attempts to retry. Function * signature should match: `function (int $attempt) : int`. * @type array $restOptions HTTP client specific configuration options. * } * @return ResponseInterface * @throws ServiceException */ public function send(RequestInterface $request, array $options = []) { $retryOptions = $this->getRetryOptions($options); $backoff = new ExponentialBackoff( $retryOptions['retries'], $retryOptions['retryFunction'], $retryOptions['retryListener'], ); if ($retryOptions['delayFunction']) { $backoff->setDelayFunction($retryOptions['delayFunction']); } if ($retryOptions['calcDelayFunction']) { $backoff->setCalcDelayFunction($retryOptions['calcDelayFunction']); } try { return $backoff->execute($this->httpHandler, [ $this->applyHeaders($request, $options), $this->getRequestOptions($options) ]); } catch (\Exception $ex) { throw $this->convertToGoogleException($ex); } } /** * Deliver the request asynchronously. * * @param RequestInterface $request A PSR-7 request. * @param array $options [optional] { * Request options. * * @type float $requestTimeout Seconds to wait before timing out the * request. **Defaults to** `0`. * @type int $retries Number of retries for a failed request. * **Defaults to** `3`. * @type callable $restRetryFunction Sets the conditions for whether or * not a request should attempt to retry. Function signature should * match: `function (\Exception $ex, int $retryAttempt) : bool`. * @type callable $restDelayFunction Executes a delay, defaults to * utilizing `usleep`. Function signature should match: * `function (int $delay) : void`. * @type callable $restCalcDelayFunction Sets the conditions for * determining how long to wait between attempts to retry. Function * signature should match: `function (int $attempt) : int`. * @type array $restOptions HTTP client specific configuration options. * } * @return PromiseInterface * @throws ServiceException * @experimental The experimental flag means that while we believe this method * or class is ready for use, it may change before release in backwards- * incompatible ways. Please use with caution, and test thoroughly when * upgrading. */ public function sendAsync(RequestInterface $request, array $options = []) { // Unfortunately, the current ExponentialBackoff implementation doesn't // play nicely with promises. $retryAttempt = 0; $fn = function ($retryAttempt) use (&$fn, $request, $options) { $asyncHttpHandler = $this->asyncHttpHandler; $retryOptions = $this->getRetryOptions($options); if (!$retryOptions['calcDelayFunction']) { $retryOptions['calcDelayFunction'] = [ExponentialBackoff::class, 'calculateDelay']; } return $asyncHttpHandler( $this->applyHeaders($request, $options), $this->getRequestOptions($options) )->then(null, function (\Exception $ex) use ($fn, $retryAttempt, $retryOptions) { $shouldRetry = $retryOptions['retryFunction']($ex, $retryAttempt); if ($shouldRetry === false || $retryAttempt >= $retryOptions['retries']) { throw $this->convertToGoogleException($ex); } $delay = $retryOptions['calcDelayFunction']($retryAttempt); $retryOptions['delayFunction']($delay); $retryAttempt++; return $fn($retryAttempt); }); }; return $fn($retryAttempt); } /** * Applies headers to the request. * * @param RequestInterface $request A PSR-7 request. * @param array $options * @return RequestInterface */ private function applyHeaders(RequestInterface $request, array $options = []) { $headers = [ 'User-Agent' => 'gcloud-php/' . $this->componentVersion, Retry::RETRY_HEADER_KEY => sprintf( 'gl-php/%s gccl/%s', PHP_VERSION, $this->componentVersion ), ]; if (isset($options['retryHeaders'])) { $headers[Retry::RETRY_HEADER_KEY] = sprintf( '%s %s', $headers[Retry::RETRY_HEADER_KEY], implode(' ', $options['retryHeaders']) ); unset($options['retryHeaders']); } $request = Utils::modifyRequest($request, ['set_headers' => $headers]); if ($this->shouldSignRequest) { $quotaProject = $this->quotaProject; if ($this->accessToken) { // if an access token is provided, check the universe domain against "googleapis.com" $this->checkUniverseDomain(null); $request = $request->withHeader('authorization', 'Bearer ' . $this->accessToken); } else { // if a credentials fetcher is provided, check the universe domain against the // credential's universe domain $credentialsFetcher = $this->getCredentialsFetcher(); $this->checkUniverseDomain($credentialsFetcher); $request = $this->addAuthHeaders($request, $credentialsFetcher); if ($credentialsFetcher instanceof GetQuotaProjectInterface) { $quotaProject = $credentialsFetcher->getQuotaProject(); } } if ($quotaProject) { $request = $request->withHeader('X-Goog-User-Project', $quotaProject); } } else { // If we are not signing the request, check the universe domain against "googleapis.com" $this->checkUniverseDomain(null); } return $request; } /** * Adds auth headers to the request. * * @param RequestInterface $request * @param FetchAuthTokenInterface $fetcher * @return array * @throws ServiceException */ private function addAuthHeaders(RequestInterface $request, FetchAuthTokenInterface $fetcher) { $backoff = new ExponentialBackoff($this->retries, $this->getRetryFunction()); try { return $backoff->execute( function () use ($request, $fetcher) { if (!$fetcher instanceof UpdateMetadataInterface || ( $fetcher instanceof FetchAuthTokenCache && !$fetcher->getFetcher() instanceof UpdateMetadataInterface ) ) { // This covers an edge case where the token fetcher does not implement UpdateMetadataInterface, // which only would happen if a user implemented a custom fetcher if ($token = $fetcher->fetchAuthToken($this->authHttpHandler)) { return $request->withHeader('authorization', 'Bearer ' . $token['access_token']); } } else { $headers = $fetcher->updateMetadata($request->getHeaders(), null, $this->authHttpHandler); return Utils::modifyRequest($request, ['set_headers' => $headers]); } // As we do not know the reason the credentials fetcher could not fetch the // token, we should not retry. throw new \RuntimeException('Unable to fetch token'); } ); } catch (\Exception $ex) { throw $this->convertToGoogleException($ex); } } /** * Convert any exception to a Google Exception. * * @param \Exception $ex * @return Exception\ServiceException */ private function convertToGoogleException(\Exception $ex) { switch ($ex->getCode()) { case 400: $exception = Exception\BadRequestException::class; break; case 404: $exception = Exception\NotFoundException::class; break; case 409: $exception = Exception\ConflictException::class; break; case 412: $exception = Exception\FailedPreconditionException::class; break; case 500: $exception = Exception\ServerException::class; break; case 504: $exception = Exception\DeadlineExceededException::class; break; default: $exception = Exception\ServiceException::class; break; } return new $exception($this->getExceptionMessage($ex), $ex->getCode(), $ex); } /** * Gets the exception message. * * @access private * @param \Exception $ex * @return string */ private function getExceptionMessage(\Exception $ex) { if ($ex instanceof RequestException && $ex->hasResponse()) { return (string) $ex->getResponse()->getBody(); } return $ex->getMessage(); } /** * Gets a set of request options. * * @param array $options * @return array */ private function getRequestOptions(array $options) { $restOptions = $options['restOptions'] ?? $this->restOptions; $timeout = $options['requestTimeout'] ?? $this->requestTimeout; if ($timeout && !array_key_exists('timeout', $restOptions)) { $restOptions['timeout'] = $timeout; } return $restOptions; } /** * Gets a set of retry options. * * @param array $options * @return array */ private function getRetryOptions(array $options) { return [ 'retries' => isset($options['retries']) ? $options['retries'] : $this->retries, 'retryFunction' => isset($options['restRetryFunction']) ? $options['restRetryFunction'] : $this->retryFunction, 'retryListener' => isset($options['restRetryListener']) ? $options['restRetryListener'] : null, 'delayFunction' => isset($options['restDelayFunction']) ? $options['restDelayFunction'] : $this->delayFunction, 'calcDelayFunction' => isset($options['restCalcDelayFunction']) ? $options['restCalcDelayFunction'] : $this->calcDelayFunction ]; } /** * Builds the default async HTTP handler. * * @return callable */ private function buildDefaultAsyncHandler() { return $this->httpHandler instanceof Guzzle6HttpHandler ? [$this->httpHandler, 'async'] : [HttpHandlerFactory::build(), 'async']; } /** * Verify that the expected universe domain matches the universe domain from the credentials. */ private function checkUniverseDomain(?FetchAuthTokenInterface $credentialsFetcher = null) { if (false === $this->hasCheckedUniverse) { if ($this->universeDomain === '') { throw new GoogleException('The universe domain cannot be empty.'); } if (is_null($credentialsFetcher)) { if ($this->universeDomain !== GetUniverseDomainInterface::DEFAULT_UNIVERSE_DOMAIN) { throw new GoogleException(sprintf( 'The accessToken option is not supported outside of the default universe domain (%s).', GetUniverseDomainInterface::DEFAULT_UNIVERSE_DOMAIN )); } } else { $credentialsUniverse = $credentialsFetcher instanceof GetUniverseDomainInterface ? $credentialsFetcher->getUniverseDomain() : GetUniverseDomainInterface::DEFAULT_UNIVERSE_DOMAIN; if ($credentialsUniverse !== $this->universeDomain) { throw new GoogleException(sprintf( 'The configured universe domain (%s) does not match the credential universe domain (%s)', $this->universeDomain, $credentialsUniverse )); } } $this->hasCheckedUniverse = true; } } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/RequestWrapperTrait.php ================================================ new MemoryCacheItemPool(), 'authCacheOptions' => [], 'credentialsFetcher' => null, 'keyFile' => null, 'requestTimeout' => null, 'retries' => 3, 'scopes' => null, 'quotaProject' => null ]; if ($config['credentialsFetcher'] && !$config['credentialsFetcher'] instanceof FetchAuthTokenInterface) { throw new \InvalidArgumentException('credentialsFetcher must implement FetchAuthTokenInterface.'); } if (!$config['authCache'] instanceof CacheItemPoolInterface) { throw new \InvalidArgumentException('authCache must implement CacheItemPoolInterface.'); } $this->authCache = $config['authCache']; $this->authCacheOptions = $config['authCacheOptions']; $this->credentialsFetcher = $config['credentialsFetcher']; $this->retries = $config['retries']; $this->scopes = $config['scopes']; $this->keyFile = $config['keyFile']; $this->requestTimeout = $config['requestTimeout']; $this->quotaProject = $config['quotaProject']; } /** * Get the Keyfile. * * @return array */ public function keyFile() { return $this->keyFile; } /** * Get the scopes * * @return array */ public function scopes() { return $this->scopes; } /** * Gets the credentials fetcher and sets up caching. Precedence is as * follows: * * - A user supplied credentials fetcher instance. * - Credentials created from a keyfile. * - Application default credentials. * - Anonymous credentials. * * @return FetchAuthTokenInterface */ public function getCredentialsFetcher() { $fetcher = null; if ($this->credentialsFetcher) { $fetcher = $this->credentialsFetcher; } else { if ($this->keyFile) { if ($this->quotaProject) { $this->keyFile['quota_project_id'] = $this->quotaProject; } $fetcher = CredentialsLoader::makeCredentials($this->scopes, $this->keyFile); } else { try { $fetcher = $this->getADC(); } catch (\DomainException $ex) { $fetcher = new AnonymousCredentials(); } } // Note: If authCache is set and keyFile is not set, the resulting // credentials instance will be FetchAuthTokenCache, and we will be // unable to enable "useJwtAccessWithScope". This is unlikely, as // keyFile is automatically set in ClientTrait::configureAuthentication, // and so should always exist when ServiceAccountCredentials are in use. if ($fetcher instanceof ServiceAccountCredentials) { $fetcher->useJwtAccessWithScope(); } } if ($fetcher instanceof FetchAuthTokenCache) { // The fetcher has already been wrapped in a cache by `ApplicationDefaultCredentials`; // no need to wrap it another time. return $fetcher; } else { return new FetchAuthTokenCache( $fetcher, $this->authCacheOptions, $this->authCache ); } } /** * Returns application default credentials. Abstracted out for unit testing. * * @return FetchAuthTokenInterface * @throws \DomainException */ protected function getADC() { return ApplicationDefaultCredentials::getCredentials( $this->scopes, $this->authHttpHandler, $this->authCacheOptions, $this->authCache, $this->quotaProject ); } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/RestTrait.php ================================================ requestBuilder = $requestBuilder; } /** * Sets the request wrapper. * * @param RequestWrapper $requestWrapper Wrapper used to handle sending * requests to the JSON API. */ public function setRequestWrapper(RequestWrapper $requestWrapper) { $this->requestWrapper = $requestWrapper; } /** * Get the RequestWrapper. * * @return RequestWrapper|null */ public function requestWrapper() { return $this->requestWrapper; } /** * Delivers a request built from the service definition. * * @param string $resource The resource type used for the request. * @param string $method The method used for the request. * @param array $options [optional] Options used to build out the request. * @param array $whitelisted [optional] * @return array * @throws ServiceException */ public function send($resource, $method, array $options = [], $whitelisted = false) { $options += [ 'prettyPrint' => false, ]; $requestOptions = $this->pluckArray([ 'restOptions', 'retries', 'retryHeaders', 'requestTimeout', 'restRetryFunction', 'restRetryListener', 'restDelayFunction', 'restCalcDelayFunction', ], $options); try { return json_decode( $this->requestWrapper->send( $this->requestBuilder->build($resource, $method, $options), $requestOptions )->getBody(), true ); } catch (NotFoundException $e) { if ($whitelisted) { throw $this->modifyWhitelistedError($e); } throw $e; } } /** * Return a custom API endpoint in the proper format, or default if none provided. * * @param string $default * @param array $config * @param string $apiEndpointTemplate * @return string */ private function getApiEndpoint($default, array $config, ?string $apiEndpointTemplate = null) { // If the $default parameter is provided, or the user has set an "apiEndoint" config option, // fall back to the previous behavior. if ($res = $config['apiEndpoint'] ?? $default) { if (substr($res, -1) !== '/') { $res = $res . '/'; } if (strpos($res, '//') === false) { $res = 'https://' . $res; } return $res; } // One of the $default or the $template must always be set if (!$apiEndpointTemplate) { throw new UnexpectedValueException( 'An API endpoint template must be provided if no "apiEndpoint" or default endpoint is set.' ); } if (!isset($config['universeDomain'])) { throw new UnexpectedValueException( 'The "universeDomain" config value must be set to use the default API endpoint template.' ); } $apiEndpoint = str_replace( 'UNIVERSE_DOMAIN', $config['universeDomain'], $apiEndpointTemplate ); // Preserve the behavior of guaranteeing a trailing "/" return $apiEndpoint . (substr($apiEndpoint, -1) !== '/' ? '/' : ''); } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Retry.php ================================================ (int >= 0), 'nanos' => (int >= 0)] specifying how * long an operation should pause before retrying. Should accept a * single argument of type `\Exception`. * @param callable $retryFunction [optional] returns bool for whether or not * to retry. */ public function __construct( $retries, callable $delayFunction, ?callable $retryFunction = null ) { $this->retries = $retries !== null ? (int) $retries : 3; $this->delayFunction = $delayFunction; $this->retryFunction = $retryFunction; } /** * Executes the retry process. * * @param callable $function * @param array $arguments [optional] * @return mixed * @throws \Exception The last exception caught while retrying. */ public function execute(callable $function, array $arguments = []) { $delayFunction = $this->delayFunction; $retryAttempt = 0; $continue = true; do { try { $res = call_user_func_array($function, $arguments); $continue = false; return $res; } catch (\Exception $exception) { if ($this->retryFunction) { if (!call_user_func($this->retryFunction, $exception, $retryAttempt)) { throw $exception; } } if ($retryAttempt < $this->retries) { $delay = $delayFunction($exception); $delay += [ 'seconds' => 0, 'nanos' => 0 ]; time_nanosleep($delay['seconds'], $delay['nanos']); $retryAttempt++; } else { $continue = false; throw $exception; } } } while ($continue); } /** * @param callable $delayFunction * @return void */ public function setDelayFunction(callable $delayFunction) { $this->delayFunction = $delayFunction; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/RetryDeciderTrait.php ================================================ httpRetryCodes; $httpRetryMessages = $this->httpRetryMessages; return function (\Exception $ex) use ($httpRetryCodes, $httpRetryMessages, $shouldRetryMessages) { $statusCode = $ex->getCode(); if (in_array($statusCode, $httpRetryCodes)) { return true; } if (!$shouldRetryMessages) { return false; } $message = ($ex instanceof RequestException && $ex->hasResponse()) ? (string) $ex->getResponse()->getBody() : $ex->getMessage(); try { $message = $this->jsonDecode( $message, true ); } catch (\InvalidArgumentException $ex) { return false; } if (!isset($message['error']['errors'])) { return false; } foreach ($message['error']['errors'] as $error) { if (in_array($error['reason'], $httpRetryMessages)) { return true; } } return false; }; } /** * @param array $codes */ private function setHttpRetryCodes(array $codes) { $this->httpRetryCodes = $codes; } /** * @param array $messages */ private function setHttpRetryMessages(array $messages) { $this->httpRetryMessages = $messages; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/ServiceBuilder.php ================================================ 'myAwesomeProject' * ]); * ``` * * @param array $config [optional] { * Configuration options. * * @type string $projectId The project ID from the Google Developer's * Console. * @type CacheItemPoolInterface $authCache A cache for storing access * tokens. **Defaults to** a simple in memory implementation. * @type array $authCacheOptions Cache configuration options. * @type callable $authHttpHandler A handler used to deliver Psr7 * requests specifically for authentication. * @type callable $httpHandler A handler used to deliver Psr7 requests. * Only valid for requests sent over REST. * @type array $keyFile [DEPRECATED] * @type string $keyFilePath [DEPRECATED] * @type int $retries Number of retries for a failed request. * **Defaults to** `3`. * @type array $scopes Scopes to be used for the request. * } */ public function __construct(array $config = []) { $this->config = $this->resolveConfig($config); } /** * Google Cloud BigQuery allows you to create, manage, share and query * data. Find more information at the * [Google Cloud BigQuery Docs](https://cloud.google.com/bigquery/docs). * * Example: * ``` * $bigQuery = $cloud->bigQuery(); * ``` * * @param array $config [optional] { * Configuration options. See * {@see \Google\Cloud\Core\ServiceBuilder::__construct()} for the other available options. * * @type bool $returnInt64AsObject If true, 64 bit integers will be * returned as a {@see \Google\Cloud\Core\Int64} object for 32 bit * platform compatibility. **Defaults to** false. * @type string $location If provided, determines the default geographic * location used when creating datasets and managing jobs. Please * note: This is only required for jobs started outside of the US * and EU regions. Also, if location metadata has already been * fetched over the network it will take precedent over this * setting. * } * @return BigQueryClient */ public function bigQuery(array $config = []) { return $this->createClient(BigQueryClient::class, 'bigquery', $config); } /** * Google Cloud Datastore is a highly-scalable NoSQL database for your * applications. Find more information at the * [Google Cloud Datastore docs](https://cloud.google.com/datastore/docs/). * * Example: * ``` * $datastore = $cloud->datastore(); * ``` * * @param array $config [optional] { * Configuration options. See * {@see \Google\Cloud\Core\ServiceBuilder::__construct()} for the other available options. * * @type bool $returnInt64AsObject If true, 64 bit integers will be * returned as a {@see \Google\Cloud\Core\Int64} object for 32 bit * platform compatibility. **Defaults to** false. * @return DatastoreClient */ public function datastore(array $config = []) { return $this->createClient(DatastoreClient::class, 'datastore', $config); } /** * Cloud Firestore is a flexible, scalable, realtime database for mobile, * web, and server development. Find more information at the * [Google Cloud firestore docs](https://cloud.google.com/firestore/docs/). * * Example: * ``` * $firestore = $cloud->firestore(); * ``` * * @param array $config [optional] { * Configuration options. See * {@see \Google\Cloud\Core\ServiceBuilder::__construct()} for the other available options. * * @type bool $returnInt64AsObject If true, 64 bit integers will be * returned as a {@see \Google\Cloud\Core\Int64} object for 32 bit * platform compatibility. **Defaults to** false. * @return FirestoreClient */ public function firestore(array $config = []) { return $this->createClient(FirestoreClient::class, 'firestore', $config); } /** * Google Stackdriver Logging allows you to store, search, analyze, monitor, * and alert on log data and events from Google Cloud Platform and Amazon * Web Services. Find more information at the * [Google Stackdriver Logging docs](https://cloud.google.com/logging/docs/). * * Example: * ``` * $logging = $cloud->logging(); * ``` * * @param array $config [optional] Configuration options. See * {@see \Google\Cloud\Core\ServiceBuilder::__construct()} for the available options. * @return LoggingClient */ public function logging(array $config = []) { return $this->createClient(LoggingClient::class, 'logging', $config); } /** * Google Cloud Natural Language provides natural language understanding * technologies to developers, including sentiment analysis, entity * recognition, and syntax analysis. Currently only English, Spanish, * and Japanese textual context are supported. Find more information at the * [Google Cloud Natural Language docs](https://cloud.google.com/natural-language/docs/). * * Example: * ``` * $language = $cloud->language(); * ``` * * @param array $config [optional] Configuration options. See * {@see \Google\Cloud\Core\ServiceBuilder::__construct()} for the available options. * @return LanguageServiceClient */ public function language(array $config = []) { if (class_exists(DeprecatedLanguageClient::class)) { return $this->createClient(DeprecatedLanguageClient::class, 'vision', $config); } throw new \BadMethodCallException(sprintf( 'This method is no longer supported, create %s directly instead.', LanguageServiceClient::class )); } /** * Google Cloud Pub/Sub allows you to send and receive messages between * independent applications. Find more information at the * [Google Cloud Pub/Sub docs](https://cloud.google.com/pubsub/docs/). * * Example: * ``` * $pubsub = $cloud->pubsub(['projectId' => 'my-project']); * ``` * * @param array $config [optional] { * Configuration options. See * {@see \Google\Cloud\Core\ServiceBuilder::__construct()} for the other available options. * * @type string $transport The transport type used for requests. May be * either `grpc` or `rest`. **Defaults to** `grpc` if gRPC support * is detected on the system. * @return PubSubClient */ public function pubsub(array $config = []) { return $this->createClient(PubSubClient::class, 'pubsub', $config); } /** * Google Cloud Spanner is a highly scalable, transactional, managed, NewSQL * database service. Find more information at * [Google Cloud Spanner API docs](https://cloud.google.com/spanner/). * * Example: * ``` * $spanner = $cloud->spanner(['projectId' => 'my-project']); * ``` * * @param array $config [optional] { * Configuration options. See * {@see \Google\Cloud\Core\ServiceBuilder::__construct()} for the other available options. * * @type bool $returnInt64AsObject If true, 64 bit integers will be * returned as a {@see \Google\Cloud\Core\Int64} object for 32 bit * platform compatibility. **Defaults to** false. * } * @return SpannerClient */ public function spanner(array $config = []) { return $this->createClient(SpannerClient::class, 'spanner', $config); } /** * @deprecated * @see SpeechClient * @throws \BadMethodCallException */ public function speech(array $config = []) { if (class_exists(DeprecatedSpeechClient::class)) { return $this->createClient(DeprecatedSpeechClient::class, 'speech', $config); } throw new \BadMethodCallException(sprintf( 'This method is no longer supported, create %s directly instead.', SpeechClient::class )); } /** * Google Cloud Storage allows you to store and retrieve data on Google's * infrastructure. Find more information at the * [Google Cloud Storage API docs](https://developers.google.com/storage). * * Example: * ``` * $storage = $cloud->storage(); * ``` * * @param array $config [optional] Configuration options. See * {@see \Google\Cloud\Core\ServiceBuilder::__construct()} for the available options. * @return StorageClient */ public function storage(array $config = []) { return $this->createClient(StorageClient::class, 'storage', $config); } /** * Google Stackdriver Trace allows you to collect latency data from your applications * and display it in the Google Cloud Platform Console. Find more information at * [Stackdriver Trace API docs](https://cloud.google.com/trace/docs/). * * Example: * ``` * $trace = $cloud->trace(); * ``` * * @param array $config [optional] Configuration options. See * {@see \Google\Cloud\Core\ServiceBuilder::__construct()} for the available options. * @return TraceClient */ public function trace(array $config = []) { return $this->createClient(TraceClient::class, 'trace', $config); } /** * @deprecated * @see ImageAnnotatorClient * @throws \BadMethodCallException */ public function vision(array $config = []) { if (class_exists(DeprecatedVisionClient::class)) { return $this->createClient(DeprecatedVisionClient::class, 'vision', $config); } throw new \BadMethodCallException(sprintf( 'This method is no longer supported, create %s directly instead.', ImageAnnotatorClient::class )); } /** * @deprecated * @see TranslationServiceClient * @throws \BadMethodCallException */ public function translate(array $config = []) { if (class_exists(DeprecatedTranslateClient::class)) { return $this->createClient(DeprecatedTranslateClient::class, 'translate', $config); } throw new \BadMethodCallException(sprintf( 'This method is no longer supported, create %s directly instead.', TranslationServiceClient::class )); } /** * Create the client library, or error if not installed. * * @param string $class The class to create. * @param string $packageName The name of the package * @param array $config Configuration options. */ private function createClient($class, $packageName, array $config = []) { if (class_exists($class)) { return new $class($this->resolveConfig($config + $this->config)); } throw new \Exception(sprintf( 'The google/cloud-%s package is missing and must be installed.', $packageName )); } /** * Resolves configuration options. * * @param array $config * @return array */ private function resolveConfig(array $config) { if (!isset($config['httpHandler'])) { $config['httpHandler'] = HttpHandlerFactory::build(); } if (!isset($config['asyncHttpHandler'])) { $config['asyncHttpHandler'] = $config['httpHandler'] instanceof Guzzle6HttpHandler ? [$config['httpHandler'], 'async'] : [HttpHandlerFactory::build(), 'async']; } return array_merge($this->config, $config); } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/SysvTrait.php ================================================ value = $value; $this->util = $util ?: new StringUtil(); } /** * @param mixed $argument * @return bool|int * * @experimental * @internal */ public function scoreArgument($argument) { return $this->compare($this->value, $argument) ? 11 : false; } private function compare(array $value, array $argument) { array_multisort($value); array_multisort($argument); return $value == $argument; } /** * @return bool * * @experimental * @internal */ public function isLast() { return false; } /** * @return string * * @experimental * @internal */ public function __toString() { if ($this->string) { $string = $this->string .': (%s)'; } else { $string = 'same(%s)'; } return sprintf($string, $this->util->stringify($this->value)); } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Testing/CheckForClassTrait.php ================================================ markTestSkipped("Missing required class: $class"); return; } } } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Testing/DatastoreOperationRefreshTrait.php ================================================ null, 'returnInt64AsObject' => false, 'encode' => false ]; $mapper = new EntityMapper( $options['projectId'], $options['encode'], $options['returnInt64AsObject'] ); $stub->___setProperty('operation', new Operation( $connection, $options['projectId'], $options['returnInt64AsObject'], $mapper )); return $stub; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Testing/FileListFilterIterator.php ================================================ projectRootPath = $projectRootPath; $this->fileTypes = $fileTypes; $this->testPaths = $testPaths; $this->excludes = $excludes; parent::__construct($iterator); } /** * Decides whether to include the file or exclude it. * * @return bool * * @experimental * @internal */ #[\ReturnTypeWillChange] public function accept() { /** @var \SplFileInfo */ $file = parent::current(); $path = '/' . trim(str_replace($this->projectRootPath, '', realpath($file->getPathName())), '/'); if (!in_array($file->getExtension(), $this->fileTypes)) { return false; } foreach ($this->excludes as $exclude) { if ($exclude instanceof RegexFileFilter) { $pattern = $exclude->regex; if (preg_match($pattern, $path) === 1) { return false; } continue; } if (strpos($exclude, '/') !== 0 && strpos($path, $exclude) !== false) { return false; } if (strpos($path, $exclude) === 0) { return false; } } foreach ($this->testPaths as $testPath) { if (strpos($path, $testPath) !== false) { return false; } } return true; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Testing/GcTestListener.php ================================================ markTestSkipped('Must have the grpc extension installed to run this test.'); } if (defined('HHVM_VERSION')) { $this->markTestSkipped('gRPC is not supported on HHVM.'); } } /** * @return bool True if grpc tests should be skipped, otherwise false * * @experimental * @internal */ public function shouldSkipGrpcTests() { return !extension_loaded('grpc') || defined('HHVM_VERSION'); } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Testing/KeyPairGenerateTrait.php ================================================ withPadding(RSA3::SIGNATURE_PKCS1) ->withHash('sha256'); return [$key->toString('PKCS1'), $key->getPublicKey()]; } $rsa = new RSA2; $rsa->setSignatureMode(RSA2::SIGNATURE_PKCS1); $rsa->setHash('sha256'); $key = $rsa->createKey(); usleep(500); return [$key['privatekey'], $key['publickey']]; } private function verifySignature($privateKey, $input, $signature) { $verify = $this->signString($privateKey, $input); return urlencode(base64_encode($verify)) === $signature; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Testing/Lock/MockGlobals.php ================================================ tagFactory = $tagFactory; } public function getTagFactory() { return $this->tagFactory; } /** * Returns the parsed text of this description. */ public function create(string $contents, ?TypeContext $context = null): Description { $tokens = $this->lex($contents); $count = count($tokens); $tagCount = 0; $tags = []; for ($i = 1; $i < $count; $i += 2) { $tags[] = $this->tagFactory->create($tokens[$i], $context); $tokens[$i] = '%' . ++$tagCount . '$s'; } //In order to allow "literal" inline tags, the otherwise invalid //sequence "{@}" is changed to "@", and "{}" is changed to "}". //"%" is escaped to "%%" because of vsprintf. //See unit tests for examples. for ($i = 0; $i < $count; $i += 2) { // @TODO: Modified the following line so that "{}" is not replaced // with "}". So far we have not seen any adverse effects // $tokens[$i] = str_replace(['{@}', '{}', '%'], ['@', '}', '%%'], $tokens[$i]); $tokens[$i] = str_replace(['{@}', '%'], ['@', '%%'], $tokens[$i]); } return new Description(implode('', $tokens), $tags); } /** * Strips the contents from superfluous whitespace and splits the description into a series of tokens. * * @return string[] A series of tokens of which the description text is composed. */ private function lex(string $contents): array { $contents = $this->removeSuperfluousStartingWhitespace($contents); // performance optimalization; if there is no inline tag, don't bother splitting it up. if (strpos($contents, '{@') === false) { return [$contents]; } return Utils::pregSplit( '/\{ # "{@}" is not a valid inline tag. This ensures that we do not treat it as one, but treat it literally. (?!@\}) # We want to capture the whole tag line, but without the inline tag delimiters. (\@ # Match everything up to the next delimiter. [^{}]* # Nested inline tag content should not be captured, or it will appear in the result separately. (?: # Match nested inline tags. (?: # Because we did not catch the tag delimiters earlier, we must be explicit with them here. # Notice that this also matches "{}", as a way to later introduce it as an escape sequence. \{(?1)?\} | # Make sure we match hanging "{". \{ ) # Match content after the nested inline tag. [^{}]* )* # If there are more inline tags, match them as well. We use "*" since there may not be any # nested inline tags. ) \}/Sux', $contents, 0, PREG_SPLIT_DELIM_CAPTURE ); } /** * Removes the superfluous from a multi-line description. * * When a description has more than one line then it can happen that the second and subsequent lines have an * additional indentation. This is commonly in use with tags like this: * * {@}since 1.1.0 This is an example * description where we have an * indentation in the second and * subsequent lines. * * If we do not normalize the indentation then we have superfluous whitespace on the second and subsequent * lines and this may cause rendering issues when, for example, using a Markdown converter. */ private function removeSuperfluousStartingWhitespace(string $contents): string { $lines = explode("\n", $contents); // if there is only one line then we don't have lines with superfluous whitespace and // can use the contents as-is if (count($lines) <= 1) { return $contents; } // determine how many whitespace characters need to be stripped $startingSpaceCount = 9999999; for ($i = 1, $iMax = count($lines); $i < $iMax; ++$i) { // lines with a no length do not count as they are not indented at all if (trim($lines[$i]) === '') { continue; } // determine the number of prefixing spaces by checking the difference in line length before and after // an ltrim $startingSpaceCount = min($startingSpaceCount, strlen($lines[$i]) - strlen(ltrim($lines[$i]))); } // strip the number of spaces from each line if ($startingSpaceCount > 0) { for ($i = 1, $iMax = count($lines); $i < $iMax; ++$i) { $lines[$i] = substr($lines[$i], $startingSpaceCount); } } return implode("\n", $lines); } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Testing/Reflection/ReflectionHandlerFactory.php ================================================ descriptionFactory = $this->createDescriptionFactory(); $this->docBlockFactory = $this->createDocBlockFactory($this->descriptionFactory); } /** * @param string $class * @return DocBlock */ public function createDocBlock($classOrMethod) { return $this->docBlockFactory->create($classOrMethod); } /** * @param DocBlock $docBlock * @return string */ public function getDocBlockText(DocBlock $docBlock) { $description = $this->descriptionFactory->create( $docBlock->getSummary() . "\n\n" . $docBlock->getDescription(), $docBlock->getContext() ); return $description->render(); } /** * @param array $files * @return string[] */ public function classes(array $files) { $projectFactory = $this->createProjectFactory(); $localFiles = []; foreach ($files as $file) { $localFiles[] = new LocalFile($file); } $project = $projectFactory->create('My Project', $localFiles); $classes = []; foreach ($files as $file) { $classesInFile = $project->getFiles()[$file]->getClasses(); foreach ($classesInFile as $class) { $classes[] = (string) $class->getFqsen(); } } return $classes; } /** * @return ProjectFactory */ public function createProjectFactory() { $phpVersion = PhpVersion::fromString('8.1'); // PHP 8.1.0 $parser = (new ParserFactory())->createForVersion($phpVersion); $nodeTraverser = new NodeTraverser(); $nodeTraverser->addVisitor(new NameResolver()); $nodeTraverser->addVisitor(new ElementNameResolver()); $nodesFactory = new NodesFactory($parser, $nodeTraverser); $docblockFactory = $this->createDocBlockFactory($this->createDescriptionFactory()); $methodStrategy = new Factory\Method($docblockFactory); $strategies = new ProjectFactoryStrategies( [ new Factory\Namespace_(), new Factory\Class_($docblockFactory), new Factory\Enum_($docblockFactory), new Factory\EnumCase($docblockFactory, new PrettyPrinter()), new Factory\Define($docblockFactory, new PrettyPrinter()), new Factory\GlobalConstant($docblockFactory, new PrettyPrinter()), new Factory\ClassConstant($docblockFactory, new PrettyPrinter()), new Factory\File($docblockFactory, $nodesFactory), new Factory\Function_($docblockFactory), new Factory\Interface_($docblockFactory), $methodStrategy, new Factory\Property($docblockFactory, new PrettyPrinter()), new Factory\Trait_($docblockFactory), new Factory\IfStatement(), new TraitUse(), ] ); $strategies->addStrategy( new Factory\ConstructorPromotion($methodStrategy, $docblockFactory, new PrettyPrinter()), 1100 ); $strategies->addStrategy(new Noop(), -PHP_INT_MAX); return new ProjectFactory($strategies); } /** * @return DescriptionFactory */ public function createDescriptionFactory() { $fqsenResolver = new FqsenResolver(); $tagFactory = new StandardTagFactory($fqsenResolver); $descriptionFactory = new CoreDescriptionFactory($tagFactory); $tagFactory->addService($descriptionFactory, DescriptionFactory::class); $tagFactory->addService(new TypeResolver($fqsenResolver)); return $descriptionFactory; } /** * @return DocBlockFactory */ private function createDocBlockFactory($descriptionFactory) { $tagFactory = $descriptionFactory->getTagFactory(); return new DocBlockFactory($descriptionFactory, $tagFactory); } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Testing/RegexFileFilter.php ================================================ regex = $regex; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Testing/Snippet/Container.php ================================================ scanner = $scanner; } private function getSnippetExcludeList() { return static::$snippetExcludeList; } /** * Creates a list of all snippets which should be covered. * * @return Snippet[] * * @experimental * @internal */ public function buildListToCover() { $files = $this->scanner->files(); $classes = $this->scanner->classes($files, $this->getSnippetExcludeList()); $this->snippets = $this->scanner->snippets($classes); return $this->snippets; } /** * Mark a snippet as covered. * * @param string $identifier The identifier of the snippet being covered. * @return void * * @experimental * @internal */ public function cover($identifier) { $this->covered[] = $identifier; } /** * Return a list of all snippets not marked a covered. * * @return Snippet[] * * @experimental * @internal */ public function uncovered() { return array_diff_key($this->snippets, array_flip($this->covered)); } /** * @param string|int $identifier * @return Snippet|null * * @experimental * @internal */ public function cache($identifier) { return (array_key_exists($identifier, $this->snippets)) ? $this->snippets[$identifier] : null; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Testing/Snippet/Coverage/ExcludeFilter.php ================================================ excludeDirs = $excludeDirs; } /** * @return bool Determines whether to accept or exclude a path */ #[\ReturnTypeWillChange] public function accept() { // Accept the current item if we can recurse into it // or it is a value starting with "test" foreach ($this->excludeDirs as $excludeDir) { if (strpos($this->current(), $excludeDir) !== false) { return false; } } return true; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Testing/Snippet/Coverage/Scanner.php ================================================ parser = $parser; if (is_string($basePath)) { $basePath = [$basePath]; } $this->basePath = $basePath; $this->exclude = $exclude; } /** * Retrieve a list of PHP files to scan. * * @return string[] * * @experimental * @internal */ public function files() { $files = []; foreach ($this->basePath as $path) { $directoryIterator = new \RecursiveDirectoryIterator($path); $iterator = new \RecursiveIteratorIterator($directoryIterator); $fileList = new FileListFilterIterator( $path, $iterator, ['php'], [ '/tests/' ], $this->exclude ); foreach ($fileList as $item) { array_push($files, realPath($item->getPathName())); } } return $files; } private function checkExclude($className, array $exclude) { foreach ($exclude as $pattern) { if (preg_match($pattern, $className)) { return true; } } return false; } /** * Retrieve a list of classes in the given PHP files. * * @param array $files * @param array $exclude * @return string[] * * @experimental * @internal */ public function classes(array $files, array $exclude = []) { $handler = ReflectionHandlerFactory::create(); $classes = []; foreach ($handler->classes($files) as $class) { if ($this->checkExclude($class, $exclude)) { continue; } $classes[] = $class; } return $classes; } /** * Get a list of all snippets from the given classes. * * @return \Google\Cloud\Core\Testing\Snippet\Parser\Snippet[] * * @experimental * @internal * @throws \ReflectionException */ public function snippets(array $classes) { $snippets = []; foreach ($classes as $class) { try { $snippets = array_merge( $snippets, $this->parser->allExamples(new \ReflectionClass($class)) ); } catch (\ReflectionException $e) { throw new \RuntimeException(sprintf( "Error in class %s: %s", $class, $e->getMessage() )); } } return $snippets; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Testing/Snippet/Coverage/ScannerInterface.php ================================================ returnVal = $returnVal; $this->output = $output; } /** * @return mixed */ public function returnVal() { return $this->returnVal; } /** * @return mixed */ public function output() { return $this->output; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Testing/Snippet/Parser/Parser.php ================================================ reflection = ReflectionHandlerFactory::create(); } /** * Get a snippet from a class. * * Example: * ``` * use Google\Cloud\Core\Testing\Snippet\Parser\Parser; * * $snippet = $parser->classExample(Parser::class); * ``` * * @param string $class the name of the class * @param int|string $index The index of the example to return. * @return Snippet * @throws \Exception */ public function classExample($class, $index = 0) { $class = new ReflectionClass($class); $examples = $this->examplesFromClass($class); $result = array_filter($examples, function ($example) use ($index) { return ($example->index() == $index); }); if (empty($result)) { throw new \Exception(sprintf( 'Given snippet index %d does not exist for class %s', $index, $class->getName() )); } return current($result); } /** * Get a snippet from a method. * * Example: * ``` * use Google\Cloud\Core\Testing\Snippet\Parser\Parser; * * $snippet = $parser->methodExample(Parser::class, 'methodExample'); * ``` * * ``` * use Google\Cloud\Core\Testing\Snippet\Parser\Parser; * * // Get the 2nd example (index=1) * $snippet = $parser->methodExample(Parser::class, 'methodExample', 1); * ``` * * @param string $class The name of the class. * @param string $method The name of the method. * @param int $index The 0-indexed example to return. * @return Snippet * @throws Exception */ public function methodExample($class, $method, $index = 0) { $examples = $this->examplesFromMethod($class, $method); $result = array_filter($examples, function ($example) use ($index) { return ($example->index() === $index); }); if (empty($result)) { throw new \Exception(sprintf( 'Given snippet index %d does not exist for method %s::%s', $index, $class, $method )); } return current($result); } /** * Retrieve all examples from a class Doc Block. * * Example: * ``` * $examples = $parser->examplesFromClass($parser); * ``` * * @param object|ReflectionClass $class An instance or reflector of the * class to parse examples from. * @return array */ public function examplesFromClass($class) { if (!($class instanceof ReflectionClass)) { $class = new ReflectionClass($class); } if (!$class->getDocComment()) { return []; } $doc = $this->reflection->createDocBlock($class); $magic = []; if ($doc->getTags()) { $magicMethods = array_filter($doc->getTags(), function ($tag) { return ($tag->getName() === 'method'); }); $methods = $this->buildMagicMethods($magicMethods, $class->getName()); foreach ($methods as $method) { $magicExamples = $this->examples( $method['doc'], $class->getName() .'::'. $method['name'], $class->getFileName(), $class->getStartLine() ); foreach ($magicExamples as $ex) { $magic[$ex->identifier()] = $ex; } } } return $this->examples( $doc, $class->getName(), $class->getFileName(), $class->getStartLine(), $magic ); } /** * Retrieve all examples from a method's Doc Block. * * Example: * ``` * $examples = $parser->examplesFromMethod($parser, 'examplesFromMethod'); * ``` * * @param object|string $class An instance of the class to parse examples, * or the name of the class. * @param string|ReflectionMethod $method The name of the method to parse * examples from. * @return array */ public function examplesFromMethod($class, $method) { if (!($method instanceof ReflectionMethod)) { $method = new ReflectionMethod($class, $method); } if (!$method->isPublic()) { return []; } if (!$method->getDocComment()) { return []; } $doc = $this->reflection->createDocBlock($method); $parent = $method->getDeclaringClass(); $class = $parent->getName(); return $this->examples( $doc, $class .'::'. $method->getName(), $method->getFileName(), $method->getStartLine() ); } /** * Retrieve all examples from a class and its methods. * * Example: * ``` * $examples = $parser->allExamples($parser); * ``` * * @param object|ReflectionClass $class An instance or reflector of the class to parse. * @return array */ public function allExamples($class) { if (!($class instanceof ReflectionClass)) { $class = new ReflectionClass($class); } $snippets = $this->examplesFromClass($class); $methods = $class->getMethods(); foreach ($methods as $method) { if ($method->getDeclaringClass()->name !== $class->getName()) { continue; } $snippets = array_merge($snippets, $this->examplesFromMethod($class, $method)); } return $snippets; } /** * Parse examples from a DocBlock object. * * @param DocBlock $docBlock The DocBlock to parse * @param string $file The filename the docblock is in * @param int $line The line where the tested method or class is declared. * @return array */ public function examples(DocBlock $docBlock, $fullyQualifiedName, $file, $line, array $magicMethods = []) { $text = $this->reflection->getDocBlockText($docBlock); $parts = []; if (strpos($text, 'Example:' . PHP_EOL . '```') !== false) { $parts = explode('Example:' . PHP_EOL, $text); } else { return []; } $converter = new Parsedown; $document = new DOMDocument; $parsedText = $converter->text($parts[1]); $document->loadHTML($parsedText); $examples = $document->getElementsByTagName('code'); $index = 0; $res = []; foreach ($examples as $example) { $name = $this->extractSnippetName($example->textContent); $indexOrName = $name; if (!$name) { $indexOrName = $index; } $identifier = $this->createIdentifier($fullyQualifiedName, $indexOrName); $snippet = new Snippet($identifier, [ 'content' => $example->textContent, 'fqn' => $fullyQualifiedName, 'index' => $indexOrName, 'name' => $name, 'file' => $file, 'line' => $line ]); $res[$identifier] = $snippet; $index++; } $res = array_merge($res, $magicMethods); return $res; } /** * Create identifier * * @param string $fqn * @param int|string $indexOrName * @return string */ public function createIdentifier($fqn, $indexOrName) { return sha1($fqn . $indexOrName); } private function extractSnippetName($content) { $matches = []; if (!preg_match(self::SNIPPET_NAME_REGEX, $content, $matches)) { return null; } return $matches[1]; } private function buildMagicMethods($magicMethods, $className) { $res = []; foreach ($magicMethods as $method) { $description = $method->getDescription(); if (is_null($description)) { continue; } $class = substr($method->getDescription(), 1, -1); $doc = $this->reflection->createDocBlock($class); $res[] = [ 'name' => $method->getMethodName(), 'doc' => $doc ]; } return $res; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Testing/Snippet/Parser/Snippet.php ================================================ identifier = $identifier; $this->config = $config + [ 'content' => '', 'fqn' => '', 'index' => 0, 'file' => '', 'line' => 0, 'name' => null ]; } /** * A unique identifier for the snippet. * * This identifier is deterministic and will remain constant unless the * snippet is modified or moved. * * @return string */ public function identifier() { return $this->identifier; } /** * The file in which the snippet is found. * * @return string */ public function file() { return $this->config['file']; } /** * The Snippet fully-qualified name. * * @return string */ public function fqn() { return $this->config['fqn']; } /** * The line number where the snippet's method or class is declared. * * Note that this is NOT the line number where the snippet is declared. It * indicates the method or class which the snippet annotates. * * @return int */ public function line() { return $this->config['line']; } /** * The snippet content. * * @return string */ public function content() { return $this->config['content']; } /** * The Snippet Index * * @return int */ public function index() { return $this->config['index']; } /** * The snippet name * * @return string */ public function name() { return $this->config['name']; } /** * Eval the snippet and return the result. * * @return mixed */ public function invoke($returnVar = null) { $content = $this->config['content']; $return = ($returnVar) ? sprintf('return %s;', $this->createReturnVar($returnVar)) : ''; $use = []; foreach ($this->use as $class) { $use[] = 'use '. $class .';'; } if (!empty($use)) { $content = implode("\n", $use) . $content; } $cb = function ($return) use ($content) { extract($this->locals); try { ob_start(); $res = eval($content ."\n\n". $return); $out = ob_get_clean(); } catch (\Exception $e) { ob_end_clean(); throw $e; } return new InvokeResult($res, $out); }; return $cb($return); } /** * Add a local variable to make available in the snippet execution scope. * * @param string $name The variable name * @param mixed $value The variable value * @return void */ public function addLocal($name, $value) { $this->locals[$name] = $value; } /** * Add a local variables to make available in the snippet execution scope. * * @param array $locals * @return void */ public function addLocals(array $locals) { foreach ($locals as $name => $value) { $this->addLocal($name, $value); } } /** * Add a `use` statement for a class. * * @param string $name The class name to import. * @return void */ public function addUse($name) { $this->use[] = $name; } /** * Replace a line with new code. * * Hopefully this is obvious, but be careful using this, and only use it * when no other feasible options present themselves. It's pretty easy to * make your test useless when you're overwriting the thing you are trying * to test. * * This is provided for cases when a snippet relies on a global, or on * something else which can not be overridden or mocked. * * @param int $line The line number (0-indexed) to replace. * @param string $content The PHP code to inject. * @return void */ public function setLine($line, $content) { $snippet = explode("\n", $this->config['content']); $snippet[$line] = $content; $this->config['content'] = implode("\n", $snippet); } /** * Inject new code after a given line. * * Hopefully this is obvious, but be careful using this, and only use it * when no other feasible options present themselves. It's pretty easy to * make your test useless when you're modifying the thing you are trying * to test. * * This is provided for cases when a snippet relies on a global, or on * something else which can not be overridden or mocked. * * @param int $line The line number (0-indexed) to write in after. * @param string $content The PHP code to inject. * @return void */ public function insertAfterLine($line, $content) { $snippet = explode("\n", $this->config['content']); array_splice($snippet, $line+1, 0, $content); $this->config['content'] = implode("\n", $snippet); } /** * Replace a string in the snippet with a new one. * * Hopefully this is obvious, but be careful using this, and only use it * when no other feasible options present themselves. It's pretty easy to * make your test useless when you're modifying the thing you are trying * to test. * * This is provided for cases when a snippet relies on a global, or on * something else which can not be overridden or mocked. * * @param string $old The string to be replaced. * @param string $new The new string to insert. * @return void */ public function replace($old, $new) { $this->config['content'] = str_replace($old, $new, $this->config['content']); } /** * Find something with a regex and replace it. * * Hopefully this is obvious, but be careful using this, and only use it * when no other feasible options present themselves. It's pretty easy to * make your test useless when you're modifying the thing you are trying * to test. * * This is provided for cases when a snippet relies on a global, or on * something else which can not be overridden or mocked. * * @param string $pattern The regex pattern to search for. * @param string $new The new string to insert. * @return void */ public function regexReplace($pattern, $new) { $this->config['content'] = preg_replace($pattern, $new, $this->config['content']); } /** * Serialize to json * * @return array */ #[\ReturnTypeWillChange] public function jsonSerialize() { return $this->config; } private function createReturnVar($returnVar) { if (is_array($returnVar)) { foreach ($returnVar as $index => $var) { $returnVar[$index] = '$'.$var; } return '['. implode(',', $returnVar) .']'; } return '$'. $returnVar; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Testing/Snippet/SnippetTestCase.php ================================================ createIdentifier($class, $indexOrName); $snippet = self::$coverage->cache($identifier); if (!$snippet) { $snippet = self::$parser->classExample($class, $indexOrName); } self::$coverage->cover($snippet->identifier()); return clone $snippet; } /** * Retrieve a snippet from a magic method docblock (i.e. `@method` tag * nexted inside a class-level docblock). * * @param string $class The class name * @param string $method The method name * @param string|int $indexOrName The index of the snippet, or its name. * @return Snippet * * @experimental * @internal */ public static function snippetFromMagicMethod($class, $method, $indexOrName = 0) { $name = $class .'::'. $method; $identifier = self::$parser->createIdentifier($name, $indexOrName); $snippet = self::$coverage->cache($identifier); if (!$snippet) { throw new \Exception('Magic Method '. $name .' was not found'); } self::$coverage->cover($identifier); return clone $snippet; } /** * Retrieve a snippet from a method docblock. * * @param string $class The class name * @param string $method The method name * @param string|int $indexOrName The index of the snippet, or its name. * @return Snippet * * @experimental * @internal */ public static function snippetFromMethod($class, $method, $indexOrName = 0) { $name = $class .'::'. $method; $identifier = self::$parser->createIdentifier($name, $indexOrName); $snippet = self::$coverage->cache($identifier); if (!$snippet) { $snippet = self::$parser->methodExample($class, $method, $indexOrName); } self::$coverage->cover($identifier); return clone $snippet; } /** * Retrieve a snippet from a markdown file. * * @param string $fileName The path to the file * @param string $header The markdown header the snippet is under * @param int $index The index of the snippet * @return Snippet * * @experimental * @internal */ public static function snippetFromMarkdown(string $fileName, string $header = '', int $index = 0) { // Normalize line endings to \n to make regex handling consistent across platforms $markdown = str_replace( ["\r\n", "\r"], "\n", file_get_contents($fileName) ); // select by header if ($header) { $pattern = '/^#+\s*' . preg_quote($header, '/') . '\s*\n([\s\S]*?)(?=^#+.*$|\Z)/m'; if (!preg_match($pattern, $markdown, $matches)) { throw new \Exception('Heeader "' . $header . '" not found in markdown file ' . basename($fileName)); } $markdown = trim($matches[1]); } /** * Regex Explanation: * * (?m) : Enable multi-line mode (^ matches start of line). * ^ : Start of a line. * (\s*) : Group 1: Capture indentation. * (`{3,}|~{3,}) : Group 2: Capture the fence (3+ backticks or tildes). * [ \t]* : Consume optional spaces. * (.*?) : Group 3: Capture the language (and/or extra info) non-greedily. * \n : End of the opening line. * ([\s\S]*?) : Group 4: Content (non-greedy). * \n : Newline before closing fence. * \1 : Match exact indentation from Group 1. * \2 : Match exact fence from Group 2. * \s* : Consume any trailing whitespace/newlines on the closing line. */ $pattern = '/^(?m)(\s*)(`{3,}|~{3,})[ \t]*(.*?)\n([\s\S]*?)\1\2\s*$/m'; $snippets = []; if (!preg_match_all($pattern, $markdown, $matches, PREG_SET_ORDER)) { throw new \Exception('No snippets found in markdown file ' . basename($fileName)); } foreach ($matches as $i => $match) { // Group 3 is the language info string. Trim it to remove extra spaces. $language = isset($match[3]) ? trim($match[3]) : ''; // Fallback to 'text' if empty if ($language === '') { $language = 'text'; } // Group 4 is the actual code content $code = $match[4]; $snippets[] = new Snippet($fileName . '-' . $i, [ 'content' => $code, 'file' => $fileName, 'index' => $i, 'name' => strtolower($language), ]); } if (!isset($snippets[$index])) { throw new \Exception('No snippet found in markdown file ' . basename($fileName) . ' at index ' . $index); } return clone $snippets[$index]; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Testing/Snippet/keyfile-stub.json ================================================ { "type": "service_account", "project_id": "my-awesome-project", "private_key_id": "", "private_key": "", "client_email": "", "client_id": "", "auth_uri": "", "token_uri": "", "auth_provider_x509_cert_url": "", "client_x509_cert_url": "" } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Testing/StubTrait.php ================================================ ___getPropertyReflector($prop); $property->setAccessible(true); return $property->getValue($this); } /** * @param $prop * @param $value * * @experimental * @internal */ public function ___setProperty($prop, $value) { if (!in_array($prop, json_decode($this->___props))) { throw new \RuntimeException(sprintf('Property %s cannot be overloaded', $prop)); } $property = $this->___getPropertyReflector($prop); $property->setAccessible(true); $property->setValue($this, $value); } private function ___getPropertyReflector($property) { $trait = new \ReflectionClass($this); $ref = $trait->getParentClass() ?: $trait; // wrap this in a loop that will iterate up a class hierarchy to try // and find a private property. $keepTrying = true; do { try { $property = $ref->getProperty($property); $keepTrying = false; } catch (\ReflectionException $e) { if ($ref->getParentClass()) { $ref = $ref->getParentClass(); } else { throw new \BadMethodCallException($e->getMessage()); } } } while ($keepTrying); return $property; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Testing/System/DeletionQueue.php ================================================ acceptAllInputs = $acceptAllInputs; } /** * Add an item to be cleaned up. * * @param mixed $toDelete Unless the class was created with * `$acceptAllInputs = true`, either a callable with no arguments, or * an object with a `delete` method. * @return void * * @experimental * @internal */ public function add($toDelete) { if (!$this->acceptAllInputs) { if (!is_callable($toDelete) && !method_exists($toDelete, 'delete')) { throw new \BadMethodCallException( 'Deletion Queue requires a callable, or an object with a `delete` method.' ); } if (!is_callable($toDelete)) { $toDelete = function () use ($toDelete) { $toDelete->delete(); }; } } $this->queue[] = $toDelete; } /** * Process all items in the deletion queue. * * @return void * @throws ApiException * * @experimental * @internal */ public function process(?callable $action = null) { if ($action) { $action($this->queue); } else { $backoff = new ExponentialBackoff(8); foreach ($this->queue as $item) { $backoff->execute(function () use ($item) { try { call_user_func($item); } catch (NotFoundException $e) { } catch (ApiException $apiException) { if ($apiException->getStatus() !== 'NOT_FOUND') { throw $apiException; } } }); } } } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Testing/System/KeyManager.php ================================================ keyFile = $keyFile; $this->serviceAccountEmail = $serviceAccountEmail ?: $keyFile['client_email']; $this->projectId = $projectId ?: $keyFile['project_id']; $this->setLocation($location ?: self::DEFAULT_LOCATION); $this->requestWrapper = new RequestWrapper([ 'keyFile' => $this->keyFile, 'scopes' => ['https://www.googleapis.com/auth/cloud-platform'] ]); } /** * Set the service account email used for IAM management. * * @param string $serviceAccountEmail */ public function setServiceAccountEmail($serviceAccountEmail) { $this->serviceAccountEmail = $serviceAccountEmail; } /** * Set keyring location. * * Location name may be in upper or lower case. * * @param string $location */ public function setLocation($location) { $this->location = strtolower($location); } /** * Get the project data. * * @param string $projectId [optional] If not provided, uses ID given in * constructor or keyfile. * @return array */ public function getProject($projectId = null) { $projectId = $projectId ?: $this->projectId; $uri = 'https://cloudresourcemanager.googleapis.com/v1/projects/%s'; $res = $this->requestWrapper->send( new Request( 'GET', sprintf($uri, $projectId) ) ); return json_decode($res->getBody(), true); } /** * A helper to get KMS keys and set correct permissions. * * @param string $keyRingId * @param string[] $keyIds * @return array */ public function getKeyNames($keyRingId, array $keyIds) { $keyNames = []; $this->buildKeyRing($keyRingId); foreach ($keyIds as $keyId) { $keyNames[] = $this->getCryptoKeyName( $keyRingId, $keyId ); } return $keyNames; } /** * @param string $keyRingId */ private function buildKeyRing($keyRingId) { try { $this->requestWrapper->send( new Request( 'POST', sprintf( 'https://cloudkms.googleapis.com/v1/projects/%s/locations/%s/keyRings?keyRingId=%s', $this->projectId, $this->location, $keyRingId ) ) ); } catch (ConflictException $ex) { // If it already exists, great! } } /** * @param string $keyRingId * @param string $cryptoKeyId * @return string */ private function getCryptoKeyName( $keyRingId, $cryptoKeyId ) { $name = null; try { $uri = 'https://cloudkms.googleapis.com/v1/projects/%s/locations/%s/keyRings/%s/cryptoKeys?cryptoKeyId=%s'; $response = $this->requestWrapper->send( new Request( 'POST', sprintf( $uri, $this->projectId, $this->location, $keyRingId, $cryptoKeyId ), [], json_encode(['purpose' => 'ENCRYPT_DECRYPT']) ) ); $name = json_decode((string) $response->getBody(), true)['name']; } catch (ConflictException $ex) { $name = sprintf( 'projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s' , $this->projectId, $this->location, $keyRingId, $cryptoKeyId ); } $policy = [ 'policy' => [ 'bindings' => [ [ 'role' => 'roles/cloudkms.cryptoKeyEncrypterDecrypter', 'members' => [ "serviceAccount:" . $this->serviceAccountEmail ] ] ] ] ]; $uri = 'https://cloudkms.googleapis.com/v1/projects/%s/locations/' . '%s/keyRings/%s/cryptoKeys/%s:setIamPolicy'; $this->requestWrapper->send( new Request( 'POST', sprintf( $uri, $this->projectId, $this->location, $keyRingId, $cryptoKeyId ), [], json_encode($policy) ) ); return $name; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Testing/System/SystemTestCase.php ================================================ process(); } /** * Create a random integer ID for test entities. * * @return int * * @experimental * @internal */ public static function randId() { return rand(1, 9999999); } /** * Create a bucket and enqueue it for deletion. * * This method provides a means of creating a bucket with pre-configured * flush+delete functionality. Use in place of `StorageClient::createBucket()`. * * When inserting objects into a bucket created with this method, you do NOT need * to enqueue those objects for deletion or concern yourself with order of * operations. * * @param StorageClient $client * @param string $bucketName * @param array $options * @return Bucket * @throws GoogleException * * @experimental * @internal */ public static function createBucket(StorageClient $client, $bucketName, array $options = []) { $backoff = new ExponentialBackoff(8, function ($ex) { return !($ex instanceof BadRequestException); }); $bucket = $backoff->execute(function () use ($client, $bucketName, $options) { return $client->createBucket($bucketName, $options); }); self::$deletionQueue->add(function () use ($bucket) { foreach ($bucket->objects() as $object) { $object->delete(); } $bucket->delete(); }); return $bucket; } /** * Create a dataset and enqueue it for deletion. * * This method provides a means of creating a dataset with pre-configured * flush+delete functionality. Use in place of `BigQueryClient::createDataset()`. * * When inserting tables into a dataset created with this method, you do NOT need * to enqueue those tables for deletion or concern yourself with order of * operations. * * @param BigQueryClient $client * @param string $datasetName * @param array $options * @return Dataset * * @experimental * @internal */ public static function createDataset(BigQueryClient $client, $datasetName, array $options = []) { $dataset = $client->createDataset($datasetName, $options); self::$deletionQueue->add(function () use ($dataset) { $dataset->delete(['deleteContents' => true]); }); return $dataset; } /** * Create a topic and enqueue it for deletion. * * This method provides a means of creating a topic with pre-configured * flush+delete functionality. Use in place of `PubSubClient::createTopic()`. * * When inserting subscriptions into a topic created with this method, you do NOT need * to enqueue those subscriptions for deletion or concern yourself with order of * operations. * * @param PubSubClient $client * @param string $topicName * @param array $options * @return Topic * @throws GoogleException * * @experimental * @internal */ public static function createTopic(PubSubClient $client, $topicName, array $options = []) { $backoff = new ExponentialBackoff(8); $topic = $backoff->execute(function () use ($client, $topicName, $options) { return $client->createTopic($topicName, $options); }); self::$deletionQueue->add(function () use ($topic) { foreach ($topic->subscriptions() as $subscription) { $subscription->delete(); } $topic->delete(); }); return $topic; } /** * Set "using emulator" flag for single test case. * * Should be called in `setUpBeforeClass()` method. This will allow to * skip tests that are not supported by emulator. * * Example: * ``` * self::setUsingEmulator(getenv('FOOBAR_EMULATOR_HOST')); * ``` * * @param bool $enabled Whether emulator is detected. **Defaults to** `true`. */ public static function setUsingEmulator($enabled = true) { self::$emulatedClasses[get_called_class()] = (bool)$enabled; } /** * Set "using emulator" flag for test cases with specified fully-qualified name prefix. * * Should be called in `setUpBeforeClass()` method. This will allow to * skip tests that are not supported by emulator. * * Example: * ``` * // Set flag for called class namespace. * self::setUsingEmulatorForClassPrefix(getenv('FOOBAR_EMULATOR_HOST')); * ``` * * ``` * // Set flag for some other namespace. * self::setUsingEmulatorForClassPrefix(getenv('FOOBAR_EMULATOR_HOST'), 'Foobar\\Tests\\System\\Admin\\'); * ``` * * @param bool $enabled Whether emulator is detected. **Defaults to** `true`. * @param string|null $prefix Fully-qualified class name prefix. **Defaults to** called class namespace. */ public static function setUsingEmulatorForClassPrefix($enabled = true, $prefix = null) { if (!isset($prefix)) { $className = get_called_class(); $prefix = substr($className, 0, strrpos($className, '\\') + 1); } self::$emulatedClassPrefixes[$prefix] = (bool)$enabled; } /** * Returns `true` when "using emulator" flag is set either for called class name or its * fully-qualified name prefix or `false` otherwise. * * Example: * ``` * $transports = [['grpc']]; * if (!self::isEmulatorUsed()) { * $transports[] = ['rest']; * } * ``` * * @return bool */ public static function isEmulatorUsed() { $className = get_called_class(); if (!isset(self::$emulatedClasses[$className])) { $prefix = substr($className, 0, strrpos($className, '\\') + 1); $isEmulated = false; foreach (self::$emulatedClassPrefixes as $key => $flag) { if (strpos($prefix, $key) === 0) { $isEmulated = $flag; break; } } self::$emulatedClasses[$className] = $isEmulated; } return self::$emulatedClasses[$className]; } /** * Skips current test (when called from test method) or entire test case (when called from `setUpBeforeClass()`) * if "using emulator" flag is set either for called class name or its fully-qualified name prefix. * * Example: * ``` * // Use default reason. * self::skipIfEmulatorUsed(); * ``` * * ``` * // Use custom reason. * self::skipIfEmulatorUsed('Administration functions are not supported by emulator.'); * ``` * * @param string|null $reason Message explaining reason for skipping this test. */ public static function skipIfEmulatorUsed($reason = null) { if (self::isEmulatorUsed()) { self::markTestSkipped($reason ?: 'This test is not supported by the emulator.'); } } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Testing/TestHelpers.php ================================================ newInstanceArgs(array_values($args)); } /** * Get a trait implementation. * * @param string $trait The fully-qualified name of the trait to implement. * @return mixed * * @experimental * @internal */ public static function impl($trait, array $props = []) { $properties = []; foreach ($props as $prop) { $properties[] = 'private $' . $prop . ';'; } $tpl = 'class %s { use %s; use \Google\Cloud\Core\Testing\StubTrait; private $___props = \'%s\'; %s public function call($fn, array $args = []) { return call_user_func_array([$this, $fn], $args); } }'; $name = 'Trait' . sha1($trait . json_encode($props)); if (!class_exists($name)) { eval(sprintf($tpl, $name, $trait, json_encode($props), implode("\n", $properties))); } return new $name; } /** * Setup snippet tests support. * * @return void * @experimental * @internal */ public static function snippetBootstrap() { putenv('GOOGLE_APPLICATION_CREDENTIALS='. Fixtures::KEYFILE_STUB_FIXTURE()); $parser = new Parser; $scanner = new Scanner($parser, self::projectRoot(), [ '/vendor/', '/dev/', new RegexFileFilter('/\w{0,}\/vendor\//'), new RegexFileFilter('/\w{0,}\/V\d{1,}\w{0,}\//'), 'LongRunning/', // LongRunning doesn't match the GAPIC regex, but should still be excluded ]); $coverage = new Coverage($scanner); $coverage->buildListToCover(); Container::$coverage = $coverage; Container::$parser = $parser; } /** * Setup performance tests support. * * @return void * @experimental * @internal */ public static function perfBootstrap() { $bootstraps = glob(self::projectRoot() .'/*tests/Perf/bootstrap.php'); foreach ($bootstraps as $bootstrap) { require_once $bootstrap; } } /** * Check that the required environment variable keyfile paths are set and exist. * * @param array|string $env The environment variable(s) required. * @throws \RuntimeException * @experimental * @internal */ public static function requireKeyfile($env) { $env = is_array($env) ? $env : [$env]; foreach ($env as $var) { if (!getenv($var)) { throw new \RuntimeException(sprintf( 'Please set the \'%s\' env var to run the tests', $var )); } $path = getenv($var); if (!file_exists($path)) { throw new \RuntimeException(sprintf( 'The path \`%s\` specified in environment variable `%s` does not exist.', $path, $var )); } } } /** * Setup stuff needed for the system test runner. * * This method can only be called once per run. Subsequent calls will thrown \RuntimeException. * * @internal * @experimental */ public static function systemBootstrap() { static $started = false; if ($started) { throw new \RuntimeException('system tests cannot be bootstrapped more than once.'); } SystemTestCase::setupQueue(); // also set up the generated system tests self::generatedSystemTestBootstrap(); $bootstraps = glob(self::projectRoot() .'/*tests/System/bootstrap.php'); foreach ($bootstraps as $bootstrap) { require_once $bootstrap; } // This should always be last. self::systemTestShutdown(function () { SystemTestCase::processQueue(); }); $started = true; } /** * Setup stuff needed for the generated system tests. * @internal * @experimental */ public static function generatedSystemTestBootstrap() { // For generated system tests, we need to set GOOGLE_APPLICATION_CREDENTIALS // and PROJECT_ID to appropriate values $keyFilePath = getenv('GOOGLE_CLOUD_PHP_TESTS_KEY_PATH'); if (empty($keyFilePath)) { exit('GOOGLE_CLOUD_PHP_TESTS_KEY_PATH must be set to run system tests.'); } putenv("GOOGLE_APPLICATION_CREDENTIALS=$keyFilePath"); $keyFileData = json_decode(file_get_contents($keyFilePath), true); putenv('PROJECT_ID=' . $keyFileData['project_id']); putenv('GOOGLE_PROJECT_ID=' . $keyFileData['project_id']); } /** * Add cleanup function for system tests. * * Calls to this method enqueue a PHP shutdown function, scoped to the parent * PID. * * @param callable $shutdown The shutdown function. * @return void * @experimental * @internal */ public static function systemTestShutdown(callable $shutdown) { $pid = getmypid(); register_shutdown_function(function () use ($pid, $shutdown) { // Skip flushing deletion queue if exiting a forked process. if ($pid !== getmypid()) { return; } $shutdown(); }); } /** * Get the value of a private property. * * @param mixed $class The class * @param string $property The property name. * @return mixed */ public static function getPrivateProperty($class, $property) { $className = get_class($class); $c = \Closure::bind(function ($class) use ($property) { return $class->$property; }, null, $className); return $c($class); } /** * Determine the path of the project root based on where the composer * autoloader is located. * * @return string * @experimental * @internal */ private static function projectRoot() { static $projectRoot; if (!$projectRoot) { $ref = new \ReflectionClass(\Composer\Autoload\ClassLoader::class); $projectRoot = dirname(dirname(dirname($ref->getFileName()))); } return $projectRoot; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/TimeTrait.php ================================================ 6) { $timestamp = str_replace('.' . $subSeconds, '.' . substr($subSeconds, 0, 6), $timestamp); } $dt = new \DateTimeImmutable($timestamp); $nanos = $this->convertFractionToNanoSeconds($subSeconds); return [$dt, $nanos]; } /** * Create a DateTimeImmutable instance from a UNIX timestamp (i.e. seconds since epoch). * * @param int $seconds The unix timestamp. * @return \DateTimeImmutable */ private function createDateTimeFromSeconds($seconds) { return \DateTimeImmutable::createFromFormat( 'U', (string) $seconds, new \DateTimeZone('UTC') ); } /** * Create a Timestamp string in an API-compatible format. * * @param \DateTimeInterface $dateTime The date time object. * @param int|null $ns The number of nanoseconds. If null, subseconds from * $dateTime will be used instead. * @return string */ private function formatTimeAsString(\DateTimeInterface $dateTime, $ns) { if (!$dateTime instanceof \DateTimeImmutable) { $dateTime = clone $dateTime; } $dateTime = $dateTime->setTimeZone(new \DateTimeZone('UTC')); if ($ns === null) { return $dateTime->format(Timestamp::FORMAT); } return sprintf( $dateTime->format(Timestamp::FORMAT_INTERPOLATE), $this->convertNanoSecondsToFraction($ns) ); } /** * Format a timestamp for the API with nanosecond precision. * * @param \DateTimeInterface $dateTime The date time object. * @param int|null $ns The number of nanoseconds. If null, subseconds from * $dateTime will be used instead. * @return array */ private function formatTimeAsArray(\DateTimeInterface $dateTime, $ns = null) { if ($ns === null) { $ns = $this->convertFractionToNanoSeconds($dateTime->format('u')); } return [ 'seconds' => (int) $dateTime->format('U'), 'nanos' => (int) $ns ]; } /** * Convert subseconds, expressed as a decimal to nanoseconds. * * @param int|string $subseconds Provide value as a whole number (i.e. * provide 0.1 as 1). * @return int */ private function convertFractionToNanoSeconds($subseconds) { return (int) str_pad($subseconds, 9, '0', STR_PAD_RIGHT); } /** * Convert nanoseconds to subseconds. * * Note that result should be used as a fraction of one second, but is * given as an integer. * * @param int|string $nanos * @param bool $rpad Whether to right-pad to 6 or 9 digits. **Defaults to** * `true`. * @return string */ private function convertNanoSecondsToFraction($nanos, $rpad = true) { $nanos = (string) $nanos; $res = str_pad($nanos, 9, '0', STR_PAD_LEFT); if (substr($res, 6, 3) === '000') { $res = substr($res, 0, 6); } if (!$rpad) { $res = rtrim($res, '0'); } return $res; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Timestamp.php ================================================ value = $value; $this->nanoSeconds = $nanoSeconds !== null ? (int) $nanoSeconds : null; } /** * Get the underlying `\DateTimeInterface` implementation. * * Please note that if you provided nanoseconds when creating the timestamp, * they will not be included in this value. * * Example: * ``` * $dateTime = $timestamp->get(); * ``` * * @return DateTimeInterface */ public function get(): DateTimeInterface { return $this->value; } /** * Return the number of nanoseconds. * * Example: * ``` * $nanos = $timestamp->nanoSeconds(); * ``` * * @return int */ public function nanoSeconds(): int { return $this->nanoSeconds === null ? (int) $this->value->format('u') * 1000 : $this->nanoSeconds; } /** * Format the value as a string. * * Example: * ``` * $value = $timestamp->formatAsString(); * ``` * * @return string */ public function formatAsString(): string { return $this->formatTimeAsString( $this->value, $this->nanoSeconds ); } /** * Format the value as a string. * * @return string * @access private */ public function __toString() { return $this->formatAsString(); } /** * Format a timestamp for the API with nanosecond precision. * * @return array */ public function formatForApi(): array { return $this->formatTimeAsArray($this->value, $this->nanoSeconds()); } /** * Implement JsonSerializable by returning a ISO 8601 formatted string * * @return string * @access private */ #[\ReturnTypeWillChange] public function jsonSerialize(): string { return $this->formatAsString(); } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/TimestampTrait.php ================================================ formatForApi(); } return $args; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Upload/AbstractUploader.php ================================================ requestWrapper = $requestWrapper; $this->data = Utils::streamFor($data); $this->uri = $uri; $this->metadata = $options['metadata'] ?? []; $this->chunkSize = $options['chunkSize'] ?? null; $this->requestOptions = array_intersect_key($options, [ 'restOptions' => null, 'retries' => null, 'requestTimeout' => null, 'restRetryFunction' => null, 'restRetryListener' => null ]); $this->contentType = $options['contentType'] ?? 'application/octet-stream'; } /** * @return array */ abstract public function upload(); } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Upload/MultipartUploader.php ================================================ jsonDecode( $this->requestWrapper->send( $this->prepareRequest(), $this->requestOptions )->getBody(), true ); } /** * Triggers the upload process asynchronously. * * @return PromiseInterface * @experimental The experimental flag means that while we believe this method * or class is ready for use, it may change before release in backwards- * incompatible ways. Please use with caution, and test thoroughly when * upgrading. */ public function uploadAsync() { return $this->requestWrapper->sendAsync( $this->prepareRequest(), $this->requestOptions )->then(function (ResponseInterface $response) { return $this->jsonDecode( $response->getBody(), true ); }); } /** * Prepares a multipart upload request. * * @return RequestInterface */ private function prepareRequest() { $multipartStream = new Psr7\MultipartStream([ [ 'name' => 'metadata', 'headers' => ['Content-Type' => 'application/json; charset=UTF-8'], 'contents' => $this->jsonEncode($this->metadata) ], [ 'name' => 'data', 'headers' => ['Content-Type' => $this->contentType], 'contents' => $this->data ] ], 'boundary'); $headers = [ 'Content-Type' => 'multipart/related; boundary=boundary', ]; $size = $multipartStream->getSize(); if ($size !== null) { $headers['Content-Length'] = $size; } return new Request( 'POST', $this->uri, $headers, $multipartStream ); } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Upload/ResumableUploader.php ================================================ uploadProgressCallback = $options['uploadProgressCallback']; } elseif (isset($options['uploadProgressCallback'])) { throw new \InvalidArgumentException('$options.uploadProgressCallback must be a callable.'); } } /** * Gets the resume URI. * * @return string */ public function getResumeUri() { if (!$this->resumeUri) { return $this->createResumeUri(); } return $this->resumeUri; } /** * Resumes a download using the provided URI. * * @param string $resumeUri * @return array * @throws GoogleException */ public function resume($resumeUri) { if (!$this->data->isSeekable()) { throw new GoogleException('Cannot resume upload on a stream which cannot be seeked.'); } $this->resumeUri = $resumeUri; $response = $this->getStatusResponse(); if ($response->getBody()->getSize() > 0) { return $this->decodeResponse($response); } $this->rangeStart = $this->getRangeStart($response->getHeaderLine('Range')); return $this->upload(); } /** * Triggers the upload process. * * Errors are of form [`google.rpc.Status`](https://cloud.google.com/apis/design/errors#error_model), * and may be obtained via {@see \Google\Cloud\Core\Exception\ServiceException::getMetadata()}. * * @return array * @throws ServiceException */ public function upload() { $rangeStart = $this->rangeStart; $response = null; $resumeUri = $this->getResumeUri(); $size = $this->data->getSize() ?: '*'; do { $data = new LimitStream( $this->data, $this->chunkSize ?: - 1, $rangeStart ); $currStreamLimitSize = $data->getSize(); $rangeEnd = $rangeStart + ($currStreamLimitSize - 1); $headers = $this->headers + [ 'Content-Length' => $currStreamLimitSize, 'Content-Type' => $this->contentType, 'Content-Range' => "bytes $rangeStart-$rangeEnd/$size", ]; $request = new Request( 'PUT', $resumeUri, $headers, $data ); try { $response = $this->requestWrapper->send($request, $this->requestOptions); } catch (GoogleException $ex) { throw new ServiceException( "Upload failed. Please use this URI to resume your upload: $this->resumeUri", $ex->getCode(), null, json_decode($ex->getMessage(), true) ?: [] ); } if (is_callable($this->uploadProgressCallback)) { call_user_func($this->uploadProgressCallback, $currStreamLimitSize); } $rangeStart = $this->getRangeStart($response->getHeaderLine('Range')); } while ($response->getStatusCode() === 308); return $this->decodeResponse($response); } /** * Currently only the MultiPartUploader supports async. * * Any calls to this will throw a generic Google Exception. * * @return PromiseInterface * @throws GoogleException * @experimental The experimental flag means that while we believe this method * or class is ready for use, it may change before release in backwards- * incompatible ways. Please use with caution, and test thoroughly when * upgrading. */ public function uploadAsync() { throw new GoogleException('Currently only the MultiPartUploader supports async.'); } /** * Fetch and decode the response body * * @param ResponseInterface $response * @return array */ protected function decodeResponse(ResponseInterface $response) { return $this->jsonDecode($response->getBody(), true); } /** * Creates the resume URI. * * @return string */ protected function createResumeUri() { $headers = $this->headers + [ 'X-Upload-Content-Type' => $this->contentType, 'X-Upload-Content-Length' => $this->data->getSize(), 'Content-Type' => 'application/json' ]; $body = $this->jsonEncode($this->metadata); $request = new Request( 'POST', $this->uri, $headers, $body ); $response = $this->requestWrapper->send($request, $this->requestOptions); return $this->resumeUri = $response->getHeaderLine('Location'); } /** * Gets the status of the upload. * * @return ResponseInterface */ protected function getStatusResponse() { $request = new Request( 'PUT', $this->resumeUri, ['Content-Range' => 'bytes */' . $this->data->getSize()] ); return $this->requestWrapper->send($request, $this->requestOptions); } /** * Gets the starting range for the upload. * * @param string $rangeHeader * @return int */ protected function getRangeStart($rangeHeader) { if (!$rangeHeader) { // assume no bytes are uploaded if no range header is present return 0; } return (int) explode('-', $rangeHeader)[1] + 1; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Upload/SignedUrlUploader.php ================================================ headers['Origin'] = $options['origin']; unset($options['origin']); } parent::__construct($requestWrapper, $data, $uri, $options); } /** * Creates the resume URI. * * @return string */ protected function createResumeUri() { $headers = $this->headers + [ 'Content-Type' => $this->contentType, 'Content-Length' => 0, 'x-goog-resumable' => 'start' ]; $request = new Request( 'POST', $this->uri, $headers ); $response = $this->requestWrapper->send($request, $this->requestOptions); return $this->resumeUri = $response->getHeaderLine('Location'); } /** * Decode the response body * * @param ResponseInterface $response * @return string */ protected function decodeResponse(ResponseInterface $response) { return $response->getBody(); } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/Upload/StreamableUploader.php ================================================ getResumeUri(); if ($writeSize) { $rangeEnd = $this->rangeStart + $writeSize - 1; $data = $this->data->read($writeSize); } else { $rangeEnd = '*'; $data = $this->data->getContents(); $writeSize = strlen($data); } // do the streaming write $headers = [ 'Content-Length' => $writeSize, 'Content-Type' => $this->contentType, 'Content-Range' => "bytes {$this->rangeStart}-$rangeEnd/*" ]; $request = new Request( 'PUT', $resumeUri, $headers, $data ); try { $response = $this->requestWrapper->send($request, $this->requestOptions); } catch (ServiceException $ex) { throw new GoogleException( "Upload failed. Please use this URI to resume your upload: $resumeUri", $ex->getCode(), $ex ); } // reset the buffer with the remaining contents $this->rangeStart += $writeSize; return json_decode($response->getBody(), true); } /** * Currently only the MultiPartUploader supports async. * * Any calls to this will throw a generic Google Exception. * * @return PromiseInterface * @throws GoogleException * @experimental The experimental flag means that while we believe this method * or class is ready for use, it may change before release in backwards- * incompatible ways. Please use with caution, and test thoroughly when * upgrading. */ public function uploadAsync() { throw new GoogleException('Currently only the MultiPartUploader supports async.'); } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/UriTrait.php ================================================ expand($uri, $variables); } /** * @param string $uri * @param array $query * @return UriInterface */ public function buildUriWithQuery($uri, array $query) { $query = array_filter($query, function ($v) { return $v !== null; }); // @todo fix this hack. when using build_query booleans are converted to // 1 or 0 which the API does not accept. this casts bools to their // string representation foreach ($query as $k => &$v) { if (is_bool($v)) { $v = $v ? 'true' : 'false'; } } return Utils::uriFor($uri)->withQuery(Query::build($query)); } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/ValidateTrait.php ================================================ 0, 'nanos' => 0 ]; $dt = $this->createDateTimeFromSeconds($timestamp['seconds']); $nanos = $timestamp['nanos']; } else { list($dt, $nanos) = $this->parseTimeString($timestamp); } return new $returnType($dt, $nanos); } } ================================================ FILE: lib/Google/vendor/google/cloud-core/src/WhitelistTrait.php ================================================ setMessage('NOTE: Error may be due to Whitelist Restriction. ' . $e->getMessage()); return $e; } } ================================================ FILE: lib/Google/vendor/google/cloud-core/system-bootstrap.php ================================================ register(new MessageAwareArrayComparator()); \SebastianBergmann\Comparator\Factory::getInstance()->register(new ProtobufMessageComparator()); \SebastianBergmann\Comparator\Factory::getInstance()->register(new ProtobufGPBEmptyComparator()); // Make sure that while testing we bypass the `final` keyword for the GAPIC client. // Only run this if the individual component has the helper package installed if (class_exists(BypassFinals::class)) { BypassFinals::enable(); } ================================================ FILE: lib/Google/vendor/google/cloud-storage/.gitattributes ================================================ /*.xml.dist export-ignore /tests export-ignore /.github export-ignore ================================================ FILE: lib/Google/vendor/google/cloud-storage/CODE_OF_CONDUCT.md ================================================ # Contributor Code of Conduct As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities. We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality. Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery * Personal attacks * Trolling or insulting/derogatory comments * Public or private harassment * Publishing other's private information, such as physical or electronic addresses, without explicit permission * Other unethical or unprofessional conduct. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team. This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers. This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0, available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/) ================================================ FILE: lib/Google/vendor/google/cloud-storage/CONTRIBUTING.md ================================================ # How to Contribute We'd love to accept your patches and contributions to this project. We accept and review pull requests against the main [Google Cloud PHP](https://github.com/googleapis/google-cloud-php) repository, which contains all of our client libraries. You will also need to sign a Contributor License Agreement. For more details about how to contribute, see the [CONTRIBUTING.md](https://github.com/googleapis/google-cloud-php/blob/main/CONTRIBUTING.md) file in the main Google Cloud PHP repository. ================================================ FILE: lib/Google/vendor/google/cloud-storage/LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright {yyyy} {name of copyright owner} Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: lib/Google/vendor/google/cloud-storage/README.md ================================================ # Google Cloud Storage for PHP > Idiomatic PHP client for [Cloud Storage](https://cloud.google.com/storage/). [![Latest Stable Version](https://poser.pugx.org/google/cloud-storage/v/stable)](https://packagist.org/packages/google/cloud-storage) [![Packagist](https://img.shields.io/packagist/dm/google/cloud-storage.svg)](https://packagist.org/packages/google/cloud-storage) * [API documentation](https://cloud.google.com/php/docs/reference/cloud-storage/latest) **NOTE:** This repository is part of [Google Cloud PHP](https://github.com/googleapis/google-cloud-php). Any support requests, bug reports, or development contributions should be directed to that project. Allows world-wide storage and retrieval of any amount of data at any time. You can use Cloud Storage for a range of scenarios including serving website content, storing data for archival and disaster recovery, or distributing large data objects to users via direct download. ### Installation To begin, install the preferred dependency manager for PHP, [Composer](https://getcomposer.org/). Now install this component: ```sh $ composer require google/cloud-storage ``` ### Authentication Please see our [Authentication guide](https://github.com/googleapis/google-cloud-php/blob/main/AUTHENTICATION.md) for more information on authenticating your client. Once authenticated, you'll be ready to start making requests. ### Sample ```php require 'vendor/autoload.php'; use Google\Cloud\Storage\StorageClient; $storage = new StorageClient(); $bucket = $storage->bucket('my_bucket'); // Upload a file to the bucket. $bucket->upload( fopen('/data/file.txt', 'r') ); // Using Predefined ACLs to manage object permissions, you may // upload a file and give read access to anyone with the URL. $bucket->upload( fopen('/data/file.txt', 'r'), [ 'predefinedAcl' => 'publicRead' ] ); // Download and store an object from the bucket locally. $object = $bucket->object('file_backup.txt'); $object->downloadToFile('/data/file_backup.txt'); ``` ### Stream Wrapper ```php require 'vendor/autoload.php'; use Google\Cloud\Storage\StorageClient; $storage = new StorageClient(); $storage->registerStreamWrapper(); $contents = file_get_contents('gs://my_bucket/file_backup.txt'); ``` ### Debugging Please see our [Debugging guide](https://github.com/googleapis/google-cloud-php/blob/main/DEBUG.md) for more information about the debugging tools. ### Version This component is considered GA (generally available). As such, it will not introduce backwards-incompatible changes in any minor or patch releases. We will address issues and requests with the highest priority. ### Next Steps 1. Understand the [official documentation](https://cloud.google.com/storage/docs). 2. Take a look at [in-depth usage samples](https://github.com/GoogleCloudPlatform/php-docs-samples/tree/master/storage/). ================================================ FILE: lib/Google/vendor/google/cloud-storage/SECURITY.md ================================================ # Security Policy To report a security issue, please use [g.co/vulnz](https://g.co/vulnz). The Google Security Team will respond within 5 working days of your report on g.co/vulnz. We use g.co/vulnz for our intake, and do coordination and disclosure here using GitHub Security Advisory to privately discuss and fix the issue. ================================================ FILE: lib/Google/vendor/google/cloud-storage/VERSION ================================================ 1.49.0 ================================================ FILE: lib/Google/vendor/google/cloud-storage/composer.json ================================================ { "name": "google/cloud-storage", "description": "Cloud Storage Client for PHP", "license": "Apache-2.0", "minimum-stability": "stable", "require": { "php": "^8.1", "google/cloud-core": "^1.57", "ramsey/uuid": "^4.2.3" }, "require-dev": { "phpunit/phpunit": "^9.0", "phpspec/prophecy-phpunit": "^2.0", "squizlabs/php_codesniffer": "2.*", "phpdocumentor/reflection": "^5.3.3||^6.0", "phpdocumentor/reflection-docblock": "^5.3", "erusev/parsedown": "^1.6", "phpseclib/phpseclib": "^2.0||^3.0", "google/cloud-pubsub": "^2.0" }, "suggest": { "phpseclib/phpseclib": "May be used in place of OpenSSL for creating signed Cloud Storage URLs. Please require version ^2.", "google/cloud-pubsub": "May be used to register a topic to receive bucket notifications." }, "extra": { "component": { "id": "cloud-storage", "target": "googleapis/google-cloud-php-storage.git", "path": "Storage", "entry": "src/StorageClient.php" } }, "autoload": { "psr-4": { "Google\\Cloud\\Storage\\": "src" } }, "autoload-dev": { "psr-4": { "Google\\Cloud\\Storage\\Tests\\": "tests" } } } ================================================ FILE: lib/Google/vendor/google/cloud-storage/src/Acl.php ================================================ bucket('my-bucket'); * $acl = $bucket->acl(); * ``` */ class Acl { const ROLE_READER = 'READER'; const ROLE_WRITER = 'WRITER'; const ROLE_OWNER = 'OWNER'; /** * @var ConnectionInterface Represents a connection to Cloud Storage. * @internal */ protected $connection; /** * @var array ACL specific options. */ private $aclOptions; /** * @param ConnectionInterface $connection Represents a connection to * Cloud Storage. This object is created by StorageClient, * and should not be instantiated outside of this client. * @param string $type The type of access control this instance applies to. * @param array $identity Represents which bucket, file, or generation this * instance applies to. * @throws \InvalidArgumentException Thrown when an invalid type is passed in. */ public function __construct(ConnectionInterface $connection, $type, array $identity) { $validTypes = [ 'bucketAccessControls', 'defaultObjectAccessControls', 'objectAccessControls' ]; if (!in_array($type, $validTypes)) { throw new InvalidArgumentException('type must be one of the following: ' . implode(', ', $validTypes)); } $this->connection = $connection; $this->aclOptions = $identity + ['type' => $type]; } /** * Delete access controls. * * Delete access controls on a {@see Bucket} or * {@see StorageObject} for a specified entity. * * Example: * ``` * $acl->delete('allAuthenticatedUsers'); * ``` * * @see https://cloud.google.com/storage/docs/json_api/v1/bucketAccessControls/delete BucketAccessControls delete * API documentation. * @see https://cloud.google.com/storage/docs/json_api/v1/defaultObjectAccessControls/delete * DefaultObjectAccessControls delete API documentation. * @see https://cloud.google.com/storage/docs/json_api/v1/objectAccessControls/delete ObjectAccessControls delete * API documentation. * * @param string $entity The entity to delete. * @param array $options [optional] Configuration Options. * @return void */ public function delete($entity, array $options = []) { $aclOptions = $this->aclOptions + ['entity' => $entity]; $this->connection->deleteAcl($options + $aclOptions); } /** * Get access controls. * * Get access controls on a {@see Bucket} or * {@see StorageObject}. By default this will return all available * access controls. You may optionally specify a single entity to return * details for as well. * * Example: * ``` * $res = $acl->get(['entity' => 'allAuthenticatedUsers']); * ``` * * @see https://cloud.google.com/storage/docs/json_api/v1/bucketAccessControls/get BucketAccessControls get API * documentation. * @see https://cloud.google.com/storage/docs/json_api/v1/defaultObjectAccessControls/get * DefaultObjectAccessControls get API documentation. * @see https://cloud.google.com/storage/docs/json_api/v1/objectAccessControls/get ObjectAccessControls get API * documentation. * * @param array $options [optional] { * Configuration options. * * @type string $entity The entity to fetch. * } * @return array */ public function get(array $options = []) { if (isset($options['entity'])) { return $this->connection->getAcl($options + $this->aclOptions); } $response = $this->connection->listAcl($options + $this->aclOptions); return $response['items']; } /** * Add access controls. * * Add access controls on a {@see Bucket} or * {@see StorageObject}. * * Example: * ``` * $acl->add('allAuthenticatedUsers', 'WRITER'); * ``` * * @see https://cloud.google.com/storage/docs/json_api/v1/bucketAccessControls/insert BucketAccessControls insert * API documentation. * @see https://cloud.google.com/storage/docs/json_api/v1/defaultObjectAccessControls/insert * DefaultObjectAccessControls insert API documentation. * @see https://cloud.google.com/storage/docs/json_api/v1/objectAccessControls/insert ObjectAccessControls insert * API documentation. * * @param string $entity The entity to add access controls to. * @param string $role The permissions to add for the specified entity. May * be one of 'OWNER', 'READER', or 'WRITER'. * @param array $options [optional] Configuration Options. * @return array */ public function add($entity, $role, array $options = []) { $aclOptions = $this->aclOptions + [ 'entity' => $entity, 'role' => $role ]; return $this->connection->insertAcl($options + $aclOptions); } /** * Update access controls. * * Update access controls on a {@see Bucket} or {@see StorageObject}. * * Example: * ``` * $acl->update('allAuthenticatedUsers', 'READER'); * ``` * * @see https://cloud.google.com/storage/docs/json_api/v1/bucketAccessControls/patch BucketAccessControls patch API * documentation. * @see https://cloud.google.com/storage/docs/json_api/v1/defaultObjectAccessControls/patch * DefaultObjectAccessControls patch API documentation. * @see https://cloud.google.com/storage/docs/json_api/v1/objectAccessControls/patch ObjectAccessControls patch * API documentation. * * @param string $entity The entity to update access controls for. * @param string $role The permissions to update for the specified entity. * May be one of 'OWNER', 'READER', or 'WRITER'. * @param array $options [optional] Configuration Options. * @return array */ public function update($entity, $role, array $options = []) { $aclOptions = $this->aclOptions + [ 'entity' => $entity, 'role' => $role ]; return $this->connection->patchAcl($options + $aclOptions); } } ================================================ FILE: lib/Google/vendor/google/cloud-storage/src/Bucket.php ================================================ bucket('my-bucket'); * ``` */ class Bucket { use ArrayTrait; use EncryptionTrait; const NOTIFICATION_TEMPLATE = '//pubsub.googleapis.com/%s'; const TOPIC_TEMPLATE = 'projects/%s/topics/%s'; const TOPIC_REGEX = '/projects\/[^\/]*\/topics\/(.*)/'; /** * @var Acl ACL for the bucket. */ private $acl; /** * @var ConnectionInterface Represents a connection to Cloud Storage. * @internal */ private $connection; /** * @var Acl Default ACL for objects created within the bucket. */ private $defaultAcl; /** * @var array The bucket's identity. */ private $identity; /** * @var string The project ID. */ private $projectId; /** * @var array|null The bucket's metadata. */ private $info; /** * @var Iam|null */ private $iam; /** * @param ConnectionInterface $connection Represents a connection to Cloud * Storage. This object is created by StorageClient, * and should not be instantiated outside of this client. * @param string $name The bucket's name. * @param array $info [optional] The bucket's metadata. */ public function __construct(ConnectionInterface $connection, $name, array $info = []) { $this->connection = $connection; $this->identity = [ 'bucket' => $name, 'userProject' => $this->pluck('requesterProjectId', $info, false) ]; $this->info = $info; $this->projectId = $this->connection->projectId(); $this->acl = new Acl($this->connection, 'bucketAccessControls', $this->identity); $this->defaultAcl = new Acl($this->connection, 'defaultObjectAccessControls', $this->identity); } /** * Configure ACL for this bucket. * * Example: * ``` * $acl = $bucket->acl(); * ``` * * @see https://cloud.google.com/storage/docs/access-control More about Access Control Lists * * @return Acl An ACL instance configured to handle the bucket's access * control policies. */ public function acl() { return $this->acl; } /** * Configure default object ACL for this bucket. * * Example: * ``` * $acl = $bucket->defaultAcl(); * ``` * * @see https://cloud.google.com/storage/docs/access-control More about Access Control Lists * @return Acl An ACL instance configured to handle the bucket's default * object access control policies. */ public function defaultAcl() { return $this->defaultAcl; } /** * Check whether or not the bucket exists. * * Example: * ``` * if ($bucket->exists()) { * echo 'Bucket exists!'; * } * ``` * * @param array $options [optional] { * Configuration options. * } * @return bool */ public function exists(array $options = []) { try { $this->connection->getBucket($options + $this->identity + ['fields' => 'name']); } catch (NotFoundException $ex) { return false; } return true; } /** * Upload your data in a simple fashion. Uploads will default to being * resumable if the file size is greater than 5mb. * * Example: * ``` * $object = $bucket->upload( * fopen(__DIR__ . '/image.jpg', 'r') * ); * ``` * * ``` * // Upload an object in a resumable fashion while setting a new name for * // the object and including the content language. * $options = [ * 'resumable' => true, * 'name' => '/images/new-name.jpg', * 'metadata' => [ * 'contentLanguage' => 'en' * ] * ]; * * $object = $bucket->upload( * fopen(__DIR__ . '/image.jpg', 'r'), * $options * ); * ``` * * ``` * // Upload an object with a customer-supplied encryption key. * $key = base64_encode(openssl_random_pseudo_bytes(32)); // Make sure to remember your key. * * $object = $bucket->upload( * fopen(__DIR__ . '/image.jpg', 'r'), * ['encryptionKey' => $key] * ); * ``` * * ``` * // Upload an object utilizing an encryption key managed by the Cloud Key Management Service (KMS). * $object = $bucket->upload( * fopen(__DIR__ . '/image.jpg', 'r'), * [ * 'metadata' => [ * 'kmsKeyName' => 'projects/my-project/locations/kr-location/keyRings/my-kr/cryptoKeys/my-key' * ] * ] * ); * ``` * * @see https://cloud.google.com/storage/docs/json_api/v1/how-tos/upload#resumable Learn more about resumable * uploads. * @see https://cloud.google.com/storage/docs/json_api/v1/objects/insert Objects insert API documentation. * @see https://cloud.google.com/storage/docs/encryption#customer-supplied Customer-supplied encryption keys. * @see https://github.com/google/php-crc32 crc32c PHP extension for hardware-accelerated validation hashes. * * @param string|resource|StreamInterface|null $data The data to be uploaded. * @param array $options [optional] { * Configuration options. * * @type string $name The name of the destination. Required when data is * of type string or null. * @type bool $resumable Indicates whether or not the upload will be * performed in a resumable fashion. * @type bool|string $validate Indicates whether or not validation will * be applied using md5 or crc32c hashing functionality. If * enabled, and the calculated hash does not match that of the * upstream server, the upload will be rejected. Available options * are `true`, `false`, `md5` and `crc32`. If true, either md5 or * crc32c will be chosen based on your platform. If false, no * validation hash will be sent. Choose either `md5` or `crc32` to * force a hash method regardless of performance implications. * **Defaults to** `true`. * @type int $chunkSize If provided the upload will be done in chunks. * The size must be in multiples of 262144 bytes. With chunking * you have increased reliability at the risk of higher overhead. * It is recommended to not use chunking. * @type callable $uploadProgressCallback If provided together with * $resumable == true the given callable function/method will be * called after each successfully uploaded chunk. The callable * function/method will receive the number of uploaded bytes * after each uploaded chunk as a parameter to this callable. * It's useful if you want to create a progress bar when using * resumable upload type together with $chunkSize parameter. * If $chunkSize is not set the callable function/method will be * called only once after the successful file upload. * @type string $predefinedAcl Predefined ACL to apply to the object. * Acceptable values include, `"authenticatedRead"`, * `"bucketOwnerFullControl"`, `"bucketOwnerRead"`, `"private"`, * `"projectPrivate"`, and `"publicRead"`. * @type array $retention The full list of available options are outlined * at the [JSON API docs](https://cloud.google.com/storage/docs/json_api/v1/objects/insert#request-body). * @type string $retention.retainUntilTime The earliest time in RFC 3339 * UTC "Zulu" format that the object can be deleted or replaced. * This is the retention configuration set for this object. * @type string $retention.mode The mode of the retention configuration, * which can be either `"Unlocked"` or `"Locked"`. * @type array $metadata The full list of available options are outlined * at the [JSON API docs](https://cloud.google.com/storage/docs/json_api/v1/objects/insert#request-body). * @type array $metadata.metadata User-provided metadata, in key/value pairs. * @type string $encryptionKey A base64 encoded AES-256 customer-supplied * encryption key. If you would prefer to manage encryption * utilizing the Cloud Key Management Service (KMS) please use the * `$metadata.kmsKeyName` setting. Please note if using KMS the * key ring must use the same location as the bucket. * @type string $encryptionKeySHA256 Base64 encoded SHA256 hash of the * customer-supplied encryption key. This value will be calculated * from the `encryptionKey` on your behalf if not provided, but * for best performance it is recommended to pass in a cached * version of the already calculated SHA. * } * @return StorageObject * @throws \InvalidArgumentException */ public function upload($data, array $options = []) { if ($this->isObjectNameRequired($data) && !isset($options['name'])) { throw new \InvalidArgumentException('A name is required when data is of type string or null.'); } $encryptionKey = $options['encryptionKey'] ?? null; $encryptionKeySHA256 = $options['encryptionKeySHA256'] ?? null; $response = $this->connection->insertObject( $this->formatEncryptionHeaders($options) + $this->identity + [ 'data' => $data ] )->upload(); return new StorageObject( $this->connection, $response['name'], $this->identity['bucket'], $response['generation'], $response, $encryptionKey, $encryptionKeySHA256 ); } /** * Asynchronously uploads an object. * * Please note this method does not support resumable or streaming uploads. * * Example: * ``` * $promise = $bucket->uploadAsync('Lorem Ipsum', ['name' => 'keyToData']); * $object = $promise->wait(); * ``` * * ``` * // Upload multiple objects to a bucket asynchronously. * $promises = []; * $objects = ['key1' => 'Lorem', 'key2' => 'Ipsum', 'key3' => 'Gypsum']; * * foreach ($objects as $k => $v) { * $promises[] = $bucket->uploadAsync($v, ['name' => $k]) * ->then(function (StorageObject $object) { * echo $object->name() . PHP_EOL; * }, function(\Exception $e) { * throw new Exception('An error has occurred in the matrix.', null, $e); * }); * } * * foreach ($promises as $promise) { * $promise->wait(); * } * ``` * * @see https://cloud.google.com/storage/docs/json_api/v1/objects/insert Objects insert API documentation. * @see https://cloud.google.com/storage/docs/encryption#customer-supplied Customer-supplied encryption keys. * @see https://github.com/google/php-crc32 crc32c PHP extension for hardware-accelerated validation hashes. * @see https://github.com/guzzle/promises Learn more about Guzzle Promises * * @param string|resource|StreamInterface|null $data The data to be uploaded. * @param array $options [optional] { * Configuration options. * * @type string $name The name of the destination. Required when data is * of type string or null. * @type bool|string $validate Indicates whether or not validation will * be applied using md5 or crc32c hashing functionality. If * enabled, and the calculated hash does not match that of the * upstream server, the upload will be rejected. Available options * are `true`, `false`, `md5` and `crc32`. If true, either md5 or * crc32c will be chosen based on your platform. If false, no * validation hash will be sent. Choose either `md5` or `crc32` to * force a hash method regardless of performance implications. * **Defaults to** `true`. * @type string $predefinedAcl Predefined ACL to apply to the object. * Acceptable values include, `"authenticatedRead"`, * `"bucketOwnerFullControl"`, `"bucketOwnerRead"`, `"private"`, * `"projectPrivate"`, and `"publicRead"`. * @type array $metadata The full list of available options are outlined * at the [JSON API docs](https://cloud.google.com/storage/docs/json_api/v1/objects/insert#request-body). * @type array $metadata.metadata User-provided metadata, in key/value pairs. * @type string $encryptionKey A base64 encoded AES-256 customer-supplied * encryption key. If you would prefer to manage encryption * utilizing the Cloud Key Management Service (KMS) please use the * `$metadata.kmsKeyName` setting. Please note if using KMS the * key ring must use the same location as the bucket. * @type string $encryptionKeySHA256 Base64 encoded SHA256 hash of the * customer-supplied encryption key. This value will be calculated * from the `encryptionKey` on your behalf if not provided, but * for best performance it is recommended to pass in a cached * version of the already calculated SHA. * } * @return PromiseInterface * @throws \InvalidArgumentException * @experimental The experimental flag means that while we believe this method * or class is ready for use, it may change before release in backwards- * incompatible ways. Please use with caution, and test thoroughly when * upgrading. */ public function uploadAsync($data, array $options = []) { if ($this->isObjectNameRequired($data) && !isset($options['name'])) { throw new \InvalidArgumentException('A name is required when data is of type string or null.'); } $encryptionKey = $options['encryptionKey'] ?? null; $encryptionKeySHA256 = $options['encryptionKeySHA256'] ?? null; $promise = $this->connection->insertObject( $this->formatEncryptionHeaders($options) + $this->identity + [ 'data' => $data, 'resumable' => false ] )->uploadAsync(); return $promise->then( function (array $response) use ($encryptionKey, $encryptionKeySHA256) { return new StorageObject( $this->connection, $response['name'], $this->identity['bucket'], $response['generation'], $response, $encryptionKey, $encryptionKeySHA256 ); } ); } /** * Get a resumable uploader which can provide greater control over the * upload process. This is recommended when dealing with large files where * reliability is key. * * Example: * ``` * $uploader = $bucket->getResumableUploader( * fopen(__DIR__ . '/image.jpg', 'r') * ); * * try { * $object = $uploader->upload(); * } catch (GoogleException $ex) { * $resumeUri = $uploader->getResumeUri(); * $object = $uploader->resume($resumeUri); * } * ``` * * @see https://cloud.google.com/storage/docs/json_api/v1/how-tos/upload#resumable Learn more about resumable * uploads. * @see https://cloud.google.com/storage/docs/json_api/v1/objects/insert Objects insert API documentation. * * @param string|resource|StreamInterface|null $data The data to be uploaded. * @param array $options [optional] { * Configuration options. * * @type string $name The name of the destination. Required when data is * of type string or null. * @type bool $validate Indicates whether or not validation will be * applied using md5 hashing functionality. If true and the * calculated hash does not match that of the upstream server the * upload will be rejected. * @type string $predefinedAcl Predefined ACL to apply to the object. * Acceptable values include `"authenticatedRead`", * `"bucketOwnerFullControl`", `"bucketOwnerRead`", `"private`", * `"projectPrivate`", and `"publicRead"`. * @type array $metadata The available options for metadata are outlined * at the [JSON API docs](https://cloud.google.com/storage/docs/json_api/v1/objects/insert#request-body). * @type string $encryptionKey A base64 encoded AES-256 customer-supplied * encryption key. If you would prefer to manage encryption * utilizing the Cloud Key Management Service (KMS) please use the * $metadata['kmsKeyName'] setting. Please note if using KMS the * key ring must use the same location as the bucket. * @type string $encryptionKeySHA256 Base64 encoded SHA256 hash of the * customer-supplied encryption key. This value will be calculated * from the `encryptionKey` on your behalf if not provided, but * for best performance it is recommended to pass in a cached * version of the already calculated SHA. * @type callable $uploadProgressCallback The given callable * function/method will be called after each successfully uploaded * chunk. The callable function/method will receive the number of * uploaded bytes after each uploaded chunk as a parameter to this * callable. It's useful if you want to create a progress bar when * using resumable upload type together with $chunkSize parameter. * If $chunkSize is not set the callable function/method will be * called only once after the successful file upload. * } * @return ResumableUploader * @throws \InvalidArgumentException */ public function getResumableUploader($data, array $options = []) { if ($this->isObjectNameRequired($data) && !isset($options['name'])) { throw new \InvalidArgumentException('A name is required when data is of type string or null.'); } return $this->connection->insertObject( $this->formatEncryptionHeaders($options) + $this->identity + [ 'data' => $data, 'resumable' => true ] ); } /** * Get a streamable uploader which can provide greater control over the * upload process. This is useful for generating large files and uploading * the contents in chunks. * * Example: * ``` * $uploader = $bucket->getStreamableUploader( * 'initial contents', * ['name' => 'data.txt'] * ); * * // finish uploading the item * $uploader->upload(); * ``` * * @see https://cloud.google.com/storage/docs/json_api/v1/how-tos/upload#resumable Learn more about resumable * uploads. * @see https://cloud.google.com/storage/docs/json_api/v1/objects/insert Objects insert API documentation. * * @param string|resource|StreamInterface $data The data to be uploaded. * @param array $options [optional] { * Configuration options. * * @type string $name The name of the destination. Required when data is * of type string or null. * @type bool $validate Indicates whether or not validation will be * applied using md5 hashing functionality. If true and the * calculated hash does not match that of the upstream server the * upload will be rejected. * @type int $chunkSize If provided the upload will be done in chunks. * The size must be in multiples of 262144 bytes. With chunking * you have increased reliability at the risk of higher overhead. * It is recommended to not use chunking. * @type string $predefinedAcl Predefined ACL to apply to the object. * Acceptable values include, `"authenticatedRead"`, * `"bucketOwnerFullControl"`, `"bucketOwnerRead"`, `"private"`, * `"projectPrivate"`, and `"publicRead"`. * @type array $metadata The available options for metadata are outlined * at the [JSON API docs](https://cloud.google.com/storage/docs/json_api/v1/objects/insert#request-body). * @type string $encryptionKey A base64 encoded AES-256 customer-supplied * encryption key. If you would prefer to manage encryption * utilizing the Cloud Key Management Service (KMS) please use the * $metadata['kmsKeyName'] setting. Please note if using KMS the * key ring must use the same location as the bucket. * @type string $encryptionKeySHA256 Base64 encoded SHA256 hash of the * customer-supplied encryption key. This value will be calculated * from the `encryptionKey` on your behalf if not provided, but * for best performance it is recommended to pass in a cached * version of the already calculated SHA. * } * @return StreamableUploader * @throws \InvalidArgumentException */ public function getStreamableUploader($data, array $options = []) { if ($this->isObjectNameRequired($data) && !isset($options['name'])) { throw new \InvalidArgumentException('A name is required when data is of type string or null.'); } return $this->connection->insertObject( $this->formatEncryptionHeaders($options) + $this->identity + [ 'data' => $data, 'streamable' => true, 'validate' => false ] ); } /** * Lazily instantiates an object. There are no network requests made at this * point. * * To see the operations that can be performed on an object please * see {@see StorageObject}. * * Example: * ``` * $object = $bucket->object('file.txt'); * ``` * * @param string $name The name of the object to request. * @param array $options [optional] { * Configuration options. * * @type string $generation Request a specific revision of the object. * @type string $encryptionKey A base64 encoded AES-256 customer-supplied * encryption key. It will be neccesary to provide this when a key * was used during the object's creation. * @type string $encryptionKeySHA256 Base64 encoded SHA256 hash of the * customer-supplied encryption key. This value will be calculated * from the `encryptionKey` on your behalf if not provided, but * for best performance it is recommended to pass in a cached * version of the already calculated SHA. * @type boolean $softDeleted If true, returns the metadata of the * soft-deleted object. If true, generation must also be specified, * and alt=media cannot be specified. * } * @return StorageObject */ public function object($name, array $options = []) { $generation = $options['generation'] ?? null; $encryptionKey = $options['encryptionKey'] ?? null; $encryptionKeySHA256 = $options['encryptionKeySHA256'] ?? null; return new StorageObject( $this->connection, $name, $this->identity['bucket'], $generation, array_filter([ 'requesterProjectId' => $this->identity['userProject'] ]), $encryptionKey, $encryptionKeySHA256 ); } /** * Restores an object. * * Example: * ``` * $object = $bucket->restore('file.txt'); * ``` * * @param string $name The name of the object to restore. * @param string $generation Request a specific generation of the object. * @param array $options [optional] { * Configuration Options. * * @type string $restoreToken Must be specified when getting a soft-deleted object from * an HNS-enabled bucket that has a name and generation conflict with another object in the same bucket. * @type string $ifGenerationMatch Makes the operation conditional on whether * the object's current generation matches the given value. * @type string $ifGenerationNotMatch Makes the operation conditional on whether * the object's current generation matches the given value. * @type string $ifMetagenerationMatch If set, only restores * if its metageneration matches this value. * @type string $ifMetagenerationNotMatch If set, only restores * if its metageneration does not match this value. * } * @return StorageObject */ public function restore($name, $generation, array $options = []) { $res = $this->connection->restoreObject([ 'bucket' => $this->identity['bucket'], 'generation' => $generation, 'object' => $name, ] + $options); return new StorageObject( $this->connection, $name, $this->identity['bucket'], $res['generation'], // restored object will have a new generation $res + array_filter([ 'requesterProjectId' => $this->identity['userProject'] ]) ); } /** * Fetches all objects in the bucket. * * Example: * ``` * // Get all objects beginning with the prefix 'photo' * $objects = $bucket->objects([ * 'prefix' => 'photo', * 'fields' => 'items/name,nextPageToken' * ]); * * foreach ($objects as $object) { * echo $object->name() . PHP_EOL; * } * ``` * * @see https://cloud.google.com/storage/docs/json_api/v1/objects/list Objects list API documentation. * * @param array $options [optional] { * Configuration options. * * @type string $delimiter Returns results in a directory-like mode. * Results will contain only objects whose names, aside from the * prefix, do not contain delimiter. Objects whose names, aside * from the prefix, contain delimiter will have their name, * truncated after the delimiter, returned in prefixes. Duplicate * prefixes are omitted. * @type bool $includeFoldersAsPrefixes If true, will also include folders * and managed folders (besides objects) in the returned prefixes. * Only applicable if delimiter is set to '/'. * @type int $maxResults Maximum number of results to return per * request. **Defaults to** `1000`. * @type int $resultLimit Limit the number of results returned in total. * **Defaults to** `0` (return all results). * @type string $pageToken A previously-returned page token used to * resume the loading of results from a specific point. * @type string $prefix Filter results with this prefix. * @type string $projection Determines which properties to return. May * be either `"full"` or `"noAcl"`. * @type bool $versions If true, lists all versions of an object as * distinct results. **Defaults to** `false`. * @type string $fields Selector which will cause the response to only * return the specified fields. * @type string $matchGlob A glob pattern to filter results. The string * value must be UTF-8 encoded. See: * https://cloud.google.com/storage/docs/json_api/v1/objects/list#list-object-glob * } * @return ObjectIterator */ public function objects(array $options = []) { $resultLimit = $this->pluck('resultLimit', $options, false); return new ObjectIterator( new ObjectPageIterator( function (array $object) { return new StorageObject( $this->connection, $object['name'], $this->identity['bucket'], isset($object['generation']) ? $object['generation'] : null, $object + array_filter([ 'requesterProjectId' => $this->identity['userProject'] ]) ); }, [$this->connection, 'listObjects'], $options + $this->identity, ['resultLimit' => $resultLimit] ) ); } /** * Create a Cloud PubSub notification. * * Please note, the desired topic must be given the IAM role of * "pubsub.publisher" from the service account associated with the project * which contains the bucket you would like to receive notifications from. * Please see the example below for a programmatic example of achieving * this. * * Example: * ``` * // Update the permissions on the desired topic prior to creating the * // notification. * use Google\Cloud\Core\Iam\PolicyBuilder; * use Google\Cloud\PubSub\PubSubClient; * * $pubSub = new PubSubClient(); * $topicName = 'my-topic'; * $serviceAccountEmail = $storage->getServiceAccount(); * $topic = $pubSub->topic($topicName); * $iam = $topic->iam(); * $updatedPolicy = (new PolicyBuilder($iam->policy())) * ->addBinding('roles/pubsub.publisher', [ * "serviceAccount:$serviceAccountEmail" * ]) * ->result(); * $iam->setPolicy($updatedPolicy); * * $notification = $bucket->createNotification($topicName); * ``` * * ``` * // Use a fully qualified topic name. * $notification = $bucket->createNotification('projects/my-project/topics/my-topic'); * ``` * * ``` * // Provide a Topic object from the Cloud PubSub component. * use Google\Cloud\PubSub\PubSubClient; * * $pubSub = new PubSubClient(); * $topic = $pubSub->topic('my-topic'); * $notification = $bucket->createNotification($topic); * ``` * * ``` * // Supplying event types to trigger the notifications. * $notification = $bucket->createNotification('my-topic', [ * 'event_types' => [ * 'OBJECT_DELETE', * 'OBJECT_METADATA_UPDATE' * ] * ]); * ``` * * @codingStandardsIgnoreStart * @see https://cloud.google.com/storage/docs/pubsub-notifications Cloud PubSub Notifications. * @see https://cloud.google.com/storage/docs/json_api/v1/notifications/insert Notifications insert API documentation. * @see https://cloud.google.com/storage/docs/reporting-changes Registering Object Changes. * @codingStandardsIgnoreEnd * * @param string|Topic $topic The topic used to publish notifications. * @param array $options [optional] { * Configuration options. * * @type array $custom_attributes An optional list of additional * attributes to attach to each Cloud PubSub message published for * this notification subscription. * @type array $event_types If present, only send notifications about * listed event types. If empty, sent notifications for all event * types. Acceptablue values include `"OBJECT_FINALIZE"`, * `"OBJECT_METADATA_UPDATE"`, `"OBJECT_DELETE"` * , `"OBJECT_ARCHIVE"`. * @type string $object_name_prefix If present, only apply this * notification configuration to object names that begin with this * prefix. * @type string $payload_format The desired content of the Payload. * Acceptable values include `"JSON_API_V1"`, `"NONE"`. * **Defaults to** `"JSON_API_V1"`. * } * @return Notification * @throws \InvalidArgumentException When providing a type other than string * or {@see \Google\Cloud\PubSub\Topic} as $topic. * @throws GoogleException When a project ID has not been detected. * @experimental The experimental flag means that while we believe this * method or class is ready for use, it may change before release in * backwards-incompatible ways. Please use with caution, and test * thoroughly when upgrading. */ public function createNotification($topic, array $options = []) { $res = $this->connection->insertNotification($options + $this->identity + [ 'topic' => $this->getFormattedTopic($topic), 'payload_format' => 'JSON_API_V1' ]); return new Notification( $this->connection, $res['id'], $this->identity['bucket'], $res + [ 'requesterProjectId' => $this->identity['userProject'] ] ); } /** * Lazily instantiates a notification. There are no network requests made at * this point. * * To see the operations that can be performed on a notification * please see {@see Notification}. * * Example: * ``` * $notification = $bucket->notification('4582'); * ``` * * @see https://cloud.google.com/storage/docs/json_api/v1/notifications#resource Notifications API documentation. * * @param string $id The ID of the notification to access. * @return Notification * @experimental The experimental flag means that while we believe this * method or class is ready for use, it may change before release in * backwards-incompatible ways. Please use with caution, and test * thoroughly when upgrading. */ public function notification($id) { return new Notification( $this->connection, $id, $this->identity['bucket'], ['requesterProjectId' => $this->identity['userProject']] ); } /** * Fetches all notifications associated with this bucket. * * Example: * ``` * $notifications = $bucket->notifications(); * * foreach ($notifications as $notification) { * echo $notification->id() . PHP_EOL; * } * ``` * * @codingStandardsIgnoreStart * @see https://cloud.google.com/storage/docs/json_api/v1/notifications/list Notifications list API documentation. * @codingStandardsIgnoreEnd * * @param array $options [optional] { * Configuration options. * * @type int $resultLimit Limit the number of results returned in total. * **Defaults to** `0` (return all results). * } * @return ItemIterator * @experimental The experimental flag means that while we believe this * method or class is ready for use, it may change before release in * backwards-incompatible ways. Please use with caution, and test * thoroughly when upgrading. */ public function notifications(array $options = []) { $resultLimit = $this->pluck('resultLimit', $options, false); /** @var ItemIterator */ return new ItemIterator( new PageIterator( function (array $notification) { return new Notification( $this->connection, $notification['id'], $this->identity['bucket'], $notification + [ 'requesterProjectId' => $this->identity['userProject'] ] ); }, [$this->connection, 'listNotifications'], $options + $this->identity, ['resultLimit' => $resultLimit] ) ); } /** * Delete the bucket. * * Example: * ``` * $bucket->delete(); * ``` * * @see https://cloud.google.com/storage/docs/json_api/v1/buckets/delete Buckets delete API documentation. * * @param array $options [optional] { * Configuration options. * @type string $ifMetagenerationMatch If set, only deletes the bucket * if its metageneration matches this value. * @type string $ifMetagenerationNotMatch If set, only deletes the * bucket if its metageneration does not match this value. * } * @return void */ public function delete(array $options = []) { $this->connection->deleteBucket($options + $this->identity); } /** * Update the bucket. Upon receiving a result the local bucket's data will * be updated. * * Example: * ``` * // Enable logging on an existing bucket. * $bucket->update([ * 'logging' => [ * 'logBucket' => 'myBucket', * 'logObjectPrefix' => 'prefix' * ] * ]); * ``` * * @see https://cloud.google.com/storage/docs/json_api/v1/buckets/patch Buckets patch API documentation. * @see https://cloud.google.com/storage/docs/key-terms#bucket-labels Bucket Labels * * @codingStandardsIgnoreStart * @param array $options [optional] { * Configuration options. * * @type string $ifMetagenerationMatch Makes the return of the bucket * metadata conditional on whether the bucket's current * metageneration matches the given value. * @type string $ifMetagenerationNotMatch Makes the return of the bucket * metadata conditional on whether the bucket's current * metageneration does not match the given value. * @type string $predefinedAcl Predefined ACL to apply to the bucket. * Acceptable values include, `"authenticatedRead"`, * `"bucketOwnerFullControl"`, `"bucketOwnerRead"`, `"private"`, * `"projectPrivate"`, and `"publicRead"`. * @type string $predefinedDefaultObjectAcl Apply a predefined set of * default object access controls to this bucket. Acceptable * values include, `"authenticatedRead"`, * `"bucketOwnerFullControl"`, `"bucketOwnerRead"`, `"private"`, * `"projectPrivate"`, and `"publicRead"`. * @type string $projection Determines which properties to return. May * be either `"full"` or `"noAcl"`. * @type string $fields Selector which will cause the response to only * return the specified fields. * @type array $acl Access controls on the bucket. * @type array $cors The bucket's Cross-Origin Resource Sharing (CORS) * configuration. * @type array $defaultObjectAcl Default access controls to apply to new * objects when no ACL is provided. * @type array|Lifecycle $lifecycle The bucket's lifecycle configuration. * @type array $logging The bucket's logging configuration, which * defines the destination bucket and optional name prefix for the * current bucket's logs. * @type string $storageClass The bucket's storage class. This defines * how objects in the bucket are stored and determines the SLA and * the cost of storage. Acceptable values include the following * strings: `"STANDARD"`, `"NEARLINE"`, `"COLDLINE"` and * `"ARCHIVE"`. Legacy values including `"MULTI_REGIONAL"`, * `"REGIONAL"` and `"DURABLE_REDUCED_AVAILABILITY"` are also * available, but should be avoided for new implementations. For * more information, refer to the * [Storage Classes](https://cloud.google.com/storage/docs/storage-classes) * documentation. **Defaults to** `"STANDARD"`. * @type array $autoclass The bucket's autoclass configuration. * Buckets can have either StorageClass OLM rules or Autoclass, * but not both. When Autoclass is enabled on a bucket, adding * StorageClass OLM rules will result in failure. * For more information, refer to * [Storage Autoclass](https://cloud.google.com/storage/docs/autoclass) * @type array $versioning The bucket's versioning configuration. * @type array $website The bucket's website configuration. * @type array $billing The bucket's billing configuration. * @type bool $billing.requesterPays When `true`, requests to this bucket * and objects within it must provide a project ID to which the * request will be billed. * @type array $labels The Bucket labels. Labels are represented as an * array of keys and values. To remove an existing label, set its * value to `null`. * @type array $encryption Encryption configuration used by default for * newly inserted objects. * @type string $encryption.defaultKmsKeyName A Cloud KMS Key used to * encrypt objects uploaded into this bucket. Should be in the * format * `projects/my-project/locations/kr-location/keyRings/my-kr/cryptoKeys/my-key`. * Please note the KMS key ring must use the same location as the * bucket. * @type bool $defaultEventBasedHold When `true`, newly created objects * in this bucket will be retained indefinitely until an event * occurs, signified by the hold's release. * @type array $retentionPolicy Defines the retention policy for a * bucket. In order to lock a retention policy, please see * {@see Bucket::lockRetentionPolicy()}. * @type int $retentionPolicy.retentionPeriod Specifies the duration * that objects need to be retained, in seconds. Retention * duration must be greater than zero and less than 100 years. * @type array $iamConfiguration The bucket's IAM configuration. * @type bool $iamConfiguration.bucketPolicyOnly.enabled this is an alias * for $iamConfiguration.uniformBucketLevelAccess. * @type bool $iamConfiguration.uniformBucketLevelAccess.enabled If set and * true, access checks only use bucket-level IAM policies or * above. When enabled, requests attempting to view or manipulate * ACLs will fail with error code 400. **NOTE**: Before using * Uniform bucket-level access, please review the * [feature documentation](https://cloud.google.com/storage/docs/uniform-bucket-level-access), * as well as * [Should You Use uniform bucket-level access](https://cloud.google.com/storage/docs/uniform-bucket-level-access#should-you-use) * @type string $iamConfiguration.publicAccessPrevention The bucket's * Public Access Prevention configuration. Currently, * 'inherited' and 'enforced' are supported. **defaults to** * `inherited`. For more details, see * [Public Access Prevention](https://cloud.google.com/storage/docs/public-access-prevention). * } * @codingStandardsIgnoreEnd * @return array */ public function update(array $options = []) { if (isset($options['lifecycle']) && $options['lifecycle'] instanceof Lifecycle) { $options['lifecycle'] = $options['lifecycle']->toArray(); } return $this->info = $this->connection->patchBucket($options + $this->identity); } /** * Composes a set of objects into a single object. * * Please note that all objects to be composed must come from the same * bucket. * * Example: * ``` * $sourceObjects = ['log1.txt', 'log2.txt']; * $singleObject = $bucket->compose($sourceObjects, 'combined-logs.txt'); * ``` * * ``` * // Use an instance of StorageObject. * $sourceObjects = [ * $bucket->object('log1.txt'), * $bucket->object('log2.txt') * ]; * * $singleObject = $bucket->compose($sourceObjects, 'combined-logs.txt'); * ``` * * @see https://cloud.google.com/storage/docs/json_api/v1/objects/compose Objects compose API documentation * * @param string[]|StorageObject[] $sourceObjects The objects to compose. * @param string $name The name of the composed object. * @param array $options [optional] { * Configuration options. * * @type string $predefinedAcl Predefined ACL to apply to the composed * object. Acceptable values include, `"authenticatedRead"`, * `"bucketOwnerFullControl"`, `"bucketOwnerRead"`, `"private"`, * `"projectPrivate"`, and `"publicRead"`. * @type array $metadata Metadata to apply to the composed object. The * available options for metadata are outlined at the * [JSON API docs](https://cloud.google.com/storage/docs/json_api/v1/objects/insert#request-body). * @type string $ifGenerationMatch Makes the operation conditional on whether the object's current generation * matches the given value. * @type string $ifMetagenerationMatch Makes the operation conditional on whether the object's current * metageneration matches the given value. * } * @return StorageObject * @throws \InvalidArgumentException */ public function compose(array $sourceObjects, $name, array $options = []) { if (count($sourceObjects) < 2) { throw new \InvalidArgumentException('Must provide at least two objects to compose.'); } $options += [ 'destinationBucket' => $this->name(), 'destinationObject' => $name, 'destinationPredefinedAcl' => isset($options['predefinedAcl']) ? $options['predefinedAcl'] : null, 'destination' => isset($options['metadata']) ? $options['metadata'] : null, 'userProject' => $this->identity['userProject'], 'sourceObjects' => array_map(function ($sourceObject) { $name = null; $generation = null; if ($sourceObject instanceof StorageObject) { $name = $sourceObject->name(); $generation = $sourceObject->identity()['generation'] ?? null; } return array_filter([ 'name' => $name ?: $sourceObject, 'generation' => $generation ]); }, $sourceObjects) ]; if (!isset($options['destination']['contentType'])) { $options['destination']['contentType'] = MimeType::fromFilename($name); } if ($options['destination']['contentType'] === null) { throw new \InvalidArgumentException('A content type could not be detected and must be provided manually.'); } unset($options['metadata']); unset($options['predefinedAcl']); $response = $this->connection->composeObject(array_filter($options)); return new StorageObject( $this->connection, $response['name'], $this->identity['bucket'], $response['generation'], $response + array_filter([ 'requesterProjectId' => $this->identity['userProject'] ]) ); } /** * Retrieves the bucket's details. If no bucket data is cached a network * request will be made to retrieve it. * * Example: * ``` * $info = $bucket->info(); * echo $info['location']; * ``` * * @see https://cloud.google.com/storage/docs/json_api/v1/buckets/get Buckets get API documentation. * * @param array $options [optional] { * Configuration options. * * @type string $generation If present, selects a specific soft-deleted * version of this bucket instead of the live version. * This parameter is required if softDeleted is set to true. * @type string $ifMetagenerationMatch Makes the return of the bucket * metadata conditional on whether the bucket's current * metageneration matches the given value. * @type string $ifMetagenerationNotMatch Makes the return of the bucket * metadata conditional on whether the bucket's current * metageneration does not match the given value. * @type string $projection Determines which properties to return. May * be either `"full"` or `"noAcl"`. * @type bool $softDeleted If true, returns the soft-deleted bucket. * This parameter is required if generation is specified. * } * @return array */ public function info(array $options = []) { return $this->info ?: $this->reload($options); } /** * Triggers a network request to reload the bucket's details. * * Example: * ``` * $bucket->reload(); * $info = $bucket->info(); * echo $info['location']; * ``` * * @see https://cloud.google.com/storage/docs/json_api/v1/buckets/get Buckets get API documentation. * * @param array $options [optional] { * Configuration options. * * @type string $generation If present, selects a specific soft-deleted * version of this bucket instead of the live version. * This parameter is required if softDeleted is set to true. * @type string $ifMetagenerationMatch Makes the return of the bucket * metadata conditional on whether the bucket's current * metageneration matches the given value. * @type string $ifMetagenerationNotMatch Makes the return of the bucket * metadata conditional on whether the bucket's current * metageneration does not match the given value. * @type string $projection Determines which properties to return. May * be either `"full"` or `"noAcl"`. * @type bool $softDeleted If true, returns the soft-deleted bucket. * This parameter is required if generation is specified. * } * @return array */ public function reload(array $options = []) { return $this->info = $this->connection->getBucket($options + $this->identity); } /** * Retrieves the bucket's name. * * Example: * ``` * echo $bucket->name(); * ``` * * @return string */ public function name() { return $this->identity['bucket']; } /** * Retrieves a fresh lifecycle builder. If a lifecyle configuration already * exists on the target bucket and this builder is used, it will fully * replace the configuration with the rules provided by this builder. * * This builder is intended to be used in tandem with * {@see StorageClient::createBucket()} and * {@see Bucket::update()}. * * Example: * ``` * use Google\Cloud\Storage\Bucket; * * $lifecycle = Bucket::lifecycle() * ->addDeleteRule([ * 'age' => 50, * 'isLive' => true * ]); * $bucket->update([ * 'lifecycle' => $lifecycle * ]); * ``` * * @see https://cloud.google.com/storage/docs/lifecycle Object Lifecycle Management API Documentation * * @param array $lifecycle [optional] A lifecycle configuration. Please see * [here](https://cloud.google.com/storage/docs/json_api/v1/buckets#lifecycle) * for the expected structure. * @return Lifecycle */ public static function lifecycle(array $lifecycle = []) { return new Lifecycle($lifecycle); } /** * Retrieves a lifecycle builder preconfigured with the lifecycle rules that * already exists on the bucket. * * Use this if you want to make updates to an * existing configuration without removing existing rules, as would be the * case when using {@see Bucket::lifecycle()}. * * This builder is intended to be used in tandem with * {@see StorageClient::createBucket()} and * {@see Bucket::update()}. * * Please note, this method may trigger a network request in order to fetch * the existing lifecycle rules from the server. * * Example: * ``` * $lifecycle = $bucket->currentLifecycle() * ->addDeleteRule([ * 'age' => 50, * 'isLive' => true * ]); * $bucket->update([ * 'lifecycle' => $lifecycle * ]); * ``` * * ``` * // Iterate over existing rules. * $lifecycle = $bucket->currentLifecycle(); * * foreach ($lifecycle as $rule) { * print_r($rule); * } * ``` * * @see https://cloud.google.com/storage/docs/lifecycle Object Lifecycle Management API Documentation * * @param array $options [optional] Configuration options. * @return Lifecycle */ public function currentLifecycle(array $options = []) { return self::lifecycle( isset($this->info($options)['lifecycle']) ? $this->info['lifecycle'] : [] ); } /** * Returns whether the bucket with the given file prefix is writable. * Tries to create a temporary file as a resumable upload which will * not be completed (and cleaned up by GCS). * * @param string $file [optional] File to try to write. * @return bool * @throws ServiceException */ public function isWritable($file = null) { $file = $file ?: '__tempfile'; $uploader = $this->getResumableUploader( Utils::streamFor(''), ['name' => $file] ); try { $uploader->getResumeUri(); } catch (ServiceException $e) { // We expect a 403 access denied error if the bucket is not writable if ($e->getCode() == 403) { return false; } // If not a 403, re-raise the unexpected error throw $e; } return true; } /** * Manage the IAM policy for the current Bucket. * * To request a policy with conditions, pass an array with * '[requestedPolicyVersion => 3]' as argument to the policy() and * reload() methods. * * Example: * ``` * $iam = $bucket->iam(); * * // Returns the stored policy, or fetches the policy if none exists. * $policy = $iam->policy(['requestedPolicyVersion' => 3]); * * // Fetches a policy from the server. * $policy = $iam->reload(['requestedPolicyVersion' => 3]); * ``` * * @codingStandardsIgnoreStart * @see https://cloud.google.com/storage/docs/access-control/iam-with-json-and-xml Storage Access Control Documentation * @see https://cloud.google.com/storage/docs/json_api/v1/buckets/getIamPolicy Get Bucket IAM Policy * @see https://cloud.google.com/storage/docs/json_api/v1/buckets/setIamPolicy Set Bucket IAM Policy * @see https://cloud.google.com/storage/docs/json_api/v1/buckets/testIamPermissions Test Bucket Permissions * @see https://cloud.google.com/iam/docs/policies#versions policy versioning. * @codingStandardsIgnoreEnd * * @return Iam */ public function iam() { if (!$this->iam) { $this->iam = new Iam( new IamBucket($this->connection), $this->identity['bucket'], [ 'parent' => null, 'args' => $this->identity ] ); } return $this->iam; } /** * Locks a provided retention policy on this bucket. Upon receiving a result, * the local bucket's data will be updated. * * Please note that in order for this call to succeed, the applicable * metageneration value will need to be available. It can either be supplied * explicitly through the `ifMetagenerationMatch` option or detected for you * by ensuring a value is cached locally (by calling * {@see Bucket::reload()} or * {@see Bucket::info()}, for example). * * Example: * ``` * // Set a retention policy. * $bucket->update([ * 'retentionPolicy' => [ * 'retentionPeriod' => 604800 // One week in seconds. * ] * ]); * // Lock in the policy. * $info = $bucket->lockRetentionPolicy(); * $retentionPolicy = $info['retentionPolicy']; * * // View the time from which the policy was enforced and effective. (RFC 3339 format) * echo $retentionPolicy['effectiveTime'] . PHP_EOL; * * // View whether or not the retention policy is locked. This will be * // `true` after a successful call to `lockRetentionPolicy`. * echo $retentionPolicy['isLocked']; * ``` * * @see https://cloud.google.com/storage/docs/bucket-lock Bucket Lock Documentation * * @param array $options [optional] { * Configuration options. * * @type string $ifMetagenerationMatch Only locks the retention policy * if the bucket's metageneration matches this value. If not * provided the locally cached metageneration value will be used, * otherwise an exception will be thrown. * } * @throws \BadMethodCallException If no metageneration value is available. * @return array */ public function lockRetentionPolicy(array $options = []) { if (!isset($options['ifMetagenerationMatch'])) { if (!isset($this->info['metageneration'])) { throw new \BadMethodCallException( 'No metageneration value was detected. Please either provide ' . 'a value explicitly or ensure metadata is loaded through a ' . 'call such as Bucket::reload().' ); } $options['ifMetagenerationMatch'] = $this->info['metageneration']; } return $this->info = $this->connection->lockRetentionPolicy( $options + $this->identity ); } /** * Create a Signed URL listing objects in this bucket. * * Example: * ``` * $url = $bucket->signedUrl(time() + 3600); * ``` * * ``` * // Use V4 Signing * $url = $bucket->signedUrl(time() + 3600, [ * 'version' => 'v4' * ]); * ``` * * @see https://cloud.google.com/storage/docs/access-control/signed-urls Signed URLs * * @param Timestamp|\DateTimeInterface|int $expires Specifies when the URL * will expire. May provide an instance of {@see \Google\Cloud\Core\Timestamp}, * [http://php.net/datetimeimmutable](`\DateTimeImmutable`), or a * UNIX timestamp as an integer. * @param array $options { * Configuration Options. * * @type string $cname The CNAME for the bucket, for instance * `https://cdn.example.com`. **Defaults to** * `https://storage.googleapis.com`. * @type string $contentMd5 The MD5 digest value in base64. If you * provide this, the client must provide this HTTP header with * this same value in its request. If provided, take care to * always provide this value as a base64 encoded string. * @type string $contentType If you provide this value, the client must * provide this HTTP header set to the same value. * @type bool $forceOpenssl If true, OpenSSL will be used regardless of * whether phpseclib is available. **Defaults to** `false`. * @type array $headers If additional headers are provided, the server * will check to make sure that the client provides matching * values. Provide headers as a key/value array, where the key is * the header name, and the value is an array of header values. * Headers with multiple values may provide values as a simple * array, or a comma-separated string. For a reference of allowed * headers, see [Reference Headers](https://cloud.google.com/storage/docs/xml-api/reference-headers). * Header values will be trimmed of leading and trailing spaces, * multiple spaces within values will be collapsed to a single * space, and line breaks will be replaced by an empty string. * V2 Signed URLs may not provide `x-goog-encryption-key` or * `x-goog-encryption-key-sha256` headers. * @type FetchAuthTokenInterface $credentialsFetcher A credentials * fetcher instance. * @type array $keyFile [DEPRECATED] * This option is being deprecated because of a potential security risk. * This option does not validate the credential configuration. The security * risk occurs when a credential configuration is accepted from a source * that is not under your control and used without validation on your side. * If you know that you will be loading credential configurations of a * specific type, it is recommended to create the credentials directly and * configure them using the `credentialsFetcher` option instead. * ``` * use Google\Auth\Credentials\ServiceAccountCredentials; * $credentialsFetcher = new ServiceAccountCredentials($scopes, $json); * ``` * This will ensure that an unexpected credential type with potential for * malicious intent is not loaded unintentionally. You might still have to do * validation for certain credential types. * If you are loading your credential configuration from an untrusted source and have * not mitigated the risks (e.g. by validating the configuration yourself), make * these changes as soon as possible to prevent security risks to your environment. * Regardless of the method used, it is always your responsibility to validate * configurations received from external sources. * @see https://cloud.google.com/docs/authentication/external/externally-sourced-credentials * @type string $keyFilePath [DEPRECATED] * This option is being deprecated because of a potential security risk. * This option does not validate the credential configuration. The security * risk occurs when a credential configuration is accepted from a source * that is not under your control and used without validation on your side. * If you know that you will be loading credential configurations of a * specific type, it is recommended to create the credentials directly and * configure them using the `credentialsFetcher` option instead. * ``` * use Google\Auth\Credentials\ServiceAccountCredentials; * $credentialsFetcher = new ServiceAccountCredentials($scopes, $json); * ``` * This will ensure that an unexpected credential type with potential for * malicious intent is not loaded unintentionally. You might still have to do * validation for certain credential types. * If you are loading your credential configuration from an untrusted source and have * not mitigated the risks (e.g. by validating the configuration yourself), make * these changes as soon as possible to prevent security risks to your environment. * Regardless of the method used, it is always your responsibility to validate * configurations received from external sources. * @see https://cloud.google.com/docs/authentication/external/externally-sourced-credentials * @type array $queryParams Additional query parameters to be included * as part of the signed URL query string. For allowed values, * see [Reference Headers](https://cloud.google.com/storage/docs/xml-api/reference-headers#query). * @type string $version One of "v2" or "v4". *Defaults to** `"v2"`. * } * @return string * @throws \InvalidArgumentException If the given expiration is invalid or in the past. * @throws \InvalidArgumentException If the given `$options.method` is not valid. * @throws \InvalidArgumentException If the given `$options.keyFilePath` is not valid. * @throws \InvalidArgumentException If the given custom headers are invalid. * @throws \RuntimeException If the keyfile does not contain the required information. */ public function signedUrl($expires, array $options = []) { // May be overridden for testing. $signingHelper = $this->pluck('helper', $options, false) ?: SigningHelper::getHelper(); $resource = sprintf( '/%s', $this->identity['bucket'] ); return $signingHelper->sign( $this->connection, $expires, $resource, null, $options ); } /** * Create a signed upload policy for uploading objects. * * This method generates and signs a policy document. You can use policy * documents to allow visitors to a website to upload files to Google Cloud * Storage without giving them direct write access. * * Google Cloud PHP does not support v2 post policies. * * Example: * ``` * $policy = $bucket->generateSignedPostPolicyV4($objectName, new \DateTime('tomorrow'), [ * 'conditions' => [ * ['content-length-range', 0, 255] * ], * 'fields' => [ * 'x-goog-meta-hello' => 'world', * 'success_action_redirect' => 'https://google.com' * ] * ]); * * echo '
'; * foreach ($policy['fields'] as $name => $value) { * echo ''; * } * * echo 'Upload a file!
'; * echo ''; * echo ''; * echo '
'; * ``` * * @see https://cloud.google.com/storage/docs/xml-api/post-object#policydocument Policy Documents * * @param string $objectName The path to the file in Google Cloud Storage, * relative to the bucket. * @param Timestamp|\DateTimeInterface|int $expires Specifies when the URL * will expire. May provide an instance of {@see \Google\Cloud\Core\Timestamp}, * [http://php.net/datetimeimmutable](`\DateTimeImmutable`), or a * UNIX timestamp as an integer. * @param array $options [optional] { * Configuration options * * @type string $bucketBoundHostname The hostname for the bucket, for * instance `cdn.example.com`. May be used for Google Cloud Load * Balancers or for custom bucket CNAMEs. **Defaults to** * `storage.googleapis.com`. * @type array $conditions A list of arrays containing policy matching * conditions (e.g. `eq`, `starts-with`, `content-length-range`). * @type array $fields Additional form fields (do not include * `x-goog-signature`, `file`, `policy` or fields with an * `x-ignore` prefix), given as key/value pairs. * @type bool $forceOpenssl If true, OpenSSL will be used regardless of * whether phpseclib is available. **Defaults to** `false`. * @type FetchAuthTokenInterface $credentialsFetcher A credentials * fetcher instance. * @type array $keyFile [DEPRECATED] * This option is being deprecated because of a potential security risk. * This option does not validate the credential configuration. The security * risk occurs when a credential configuration is accepted from a source * that is not under your control and used without validation on your side. * If you know that you will be loading credential configurations of a * specific type, it is recommended to create the credentials directly and * configure them using the `credentialsFetcher` option instead. * ``` * use Google\Auth\Credentials\ServiceAccountCredentials; * $credentialsFetcher = new ServiceAccountCredentials($scopes, $json); * ``` * This will ensure that an unexpected credential type with potential for * malicious intent is not loaded unintentionally. You might still have to do * validation for certain credential types. * If you are loading your credential configuration from an untrusted source and have * not mitigated the risks (e.g. by validating the configuration yourself), make * these changes as soon as possible to prevent security risks to your environment. * Regardless of the method used, it is always your responsibility to validate * configurations received from external sources. * @see https://cloud.google.com/docs/authentication/external/externally-sourced-credentials * @type string $keyFilePath [DEPRECATED] * This option is being deprecated because of a potential security risk. * This option does not validate the credential configuration. The security * risk occurs when a credential configuration is accepted from a source * that is not under your control and used without validation on your side. * If you know that you will be loading credential configurations of a * specific type, it is recommended to create the credentials directly and * configure them using the `credentialsFetcher` option instead. * ``` * use Google\Auth\Credentials\ServiceAccountCredentials; * $credentialsFetcher = new ServiceAccountCredentials($scopes, $json); * ``` * This will ensure that an unexpected credential type with potential for * malicious intent is not loaded unintentionally. You might still have to do * validation for certain credential types. * If you are loading your credential configuration from an untrusted source and have * not mitigated the risks (e.g. by validating the configuration yourself), make * these changes as soon as possible to prevent security risks to your environment. * Regardless of the method used, it is always your responsibility to validate * configurations received from external sources. * @see https://cloud.google.com/docs/authentication/external/externally-sourced-credentials * hostname is provided via `$options.bucketBoundHostname`. If a * custom bucketBoundHostname is provided, **defaults to** `http`. * In all other cases, **defaults to** `https`. * @type string|array $scopes One or more authentication scopes to be * used with a key file. This option is ignored unless * `$options.keyFile` or `$options.keyFilePath` is set. * @type bool $virtualHostedStyle If `true`, URL will be of form * `mybucket.storage.googleapis.com`. If `false`, * `storage.googleapis.com/mybucket`. **Defaults to** `false`. * } * @return array An associative array, containing (string) `uri` and * (array) `fields` keys. */ public function generateSignedPostPolicyV4($objectName, $expires, array $options = []) { // May be overridden for testing. $signingHelper = $this->pluck('helper', $options, false) ?: SigningHelper::getHelper(); $resource = sprintf('/%s/%s', $this->identity['bucket'], $objectName); return $signingHelper->v4PostPolicy( $this->connection, $expires, $resource, $options ); } /** * Determines if an object name is required. * * @param mixed $data * @return bool */ private function isObjectNameRequired($data) { return is_string($data) || is_null($data); } /** * Return a topic name in its fully qualified format. * * @param Topic|string $topic * @return string * @throws \InvalidArgumentException * @throws GoogleException */ private function getFormattedTopic($topic) { if ($topic instanceof Topic) { return sprintf(self::NOTIFICATION_TEMPLATE, $topic->name()); } if (!is_string($topic)) { throw new \InvalidArgumentException( '$topic may only be a string or instance of Google\Cloud\PubSub\Topic' ); } if (preg_match('/projects\/[^\/]*\/topics\/(.*)/', $topic) === 1) { return sprintf(self::NOTIFICATION_TEMPLATE, $topic); } if (!$this->projectId) { throw new GoogleException( 'No project ID was provided, ' . 'and we were unable to detect a default project ID.' ); } return sprintf( self::NOTIFICATION_TEMPLATE, sprintf(self::TOPIC_TEMPLATE, $this->projectId, $topic) ); } } ================================================ FILE: lib/Google/vendor/google/cloud-storage/src/BucketIterator.php ================================================ */ public function unreachable() { return $this->unreachable->getArrayCopy(); } } ================================================ FILE: lib/Google/vendor/google/cloud-storage/src/Connection/ConnectionInterface.php ================================================ connection = $connection; } /** * @param array $args */ public function getPolicy(array $args) { if (isset($args['requestedPolicyVersion'])) { $args['optionsRequestedPolicyVersion'] = $args['requestedPolicyVersion']; unset($args['requestedPolicyVersion']); } return $this->connection->getBucketIamPolicy($args); } /** * @param array $args */ public function setPolicy(array $args) { unset($args['resource']); return $this->connection->setBucketIamPolicy($args); } /** * @param array $args */ public function testPermissions(array $args) { unset($args['resource']); return $this->connection->testBucketIamPermissions($args); } } ================================================ FILE: lib/Google/vendor/google/cloud-storage/src/Connection/Rest.php ================================================ __DIR__ . '/ServiceDefinition/storage-v1.json', 'componentVersion' => StorageClient::VERSION, 'apiEndpoint' => null, // If the user has not supplied a universe domain, use the environment variable if set. // Otherwise, use the default ("googleapis.com"). 'universeDomain' => getenv('GOOGLE_CLOUD_UNIVERSE_DOMAIN') ?: GetUniverseDomainInterface::DEFAULT_UNIVERSE_DOMAIN, // Cloud Storage needs to provide a default scope because the Storage // API does not accept JWTs with "audience" 'scopes' => StorageClient::FULL_CONTROL_SCOPE, ]; $this->apiEndpoint = $this->getApiEndpoint(null, $config, self::DEFAULT_API_ENDPOINT_TEMPLATE); $this->setRequestWrapper(new RequestWrapper($config)); $this->setRequestBuilder(new RequestBuilder( $config['serviceDefinitionPath'], $this->apiEndpoint )); $this->projectId = $this->pluck('projectId', $config, false); $this->restRetryFunction = (isset($config['restRetryFunction'])) ? $config['restRetryFunction'] : null; $this->retryStrategy = $config['retryStrategy'] ?? null; $this->restDelayFunction = $config['restDelayFunction'] ?? null; $this->restCalcDelayFunction = $config['restCalcDelayFunction'] ?? null; $this->restRetryListener = $config['restRetryListener'] ?? null; } /** * @return string */ public function projectId() { return $this->projectId; } /** * @param array $args */ public function deleteAcl(array $args = []) { return $this->send($args['type'], 'delete', $args); } /** * @param array $args */ public function getAcl(array $args = []) { return $this->send($args['type'], 'get', $args); } /** * @param array $args */ public function listAcl(array $args = []) { return $this->send($args['type'], 'list', $args); } /** * @param array $args */ public function insertAcl(array $args = []) { return $this->send($args['type'], 'insert', $args); } /** * @param array $args */ public function patchAcl(array $args = []) { return $this->send($args['type'], 'patch', $args); } /** * @param array $args */ public function deleteBucket(array $args = []) { return $this->send('buckets', 'delete', $args); } /** * @param array $args */ public function restoreBucket(array $args = []) { return $this->send('buckets', 'restore', $args); } /** * @param array $args */ public function getBucket(array $args = []) { return $this->send('buckets', 'get', $args); } /** * @param array $args */ public function listBuckets(array $args = []) { return $this->send('buckets', 'list', $args); } /** * @param array $args */ public function insertBucket(array $args = []) { return $this->send('buckets', 'insert', $args); } /** * @param array $args */ public function patchBucket(array $args = []) { return $this->send('buckets', 'patch', $args); } /** * @param array $args */ public function deleteObject(array $args = []) { return $this->send('objects', 'delete', $args); } /** * @param array $args */ public function restoreObject(array $args = []) { return $this->send('objects', 'restore', $args); } /** * @param array $args */ public function copyObject(array $args = []) { return $this->send('objects', 'copy', $args); } /** * @param array $args */ public function rewriteObject(array $args = []) { return $this->send('objects', 'rewrite', $args); } /** * @param array $args */ public function moveObject(array $args = []) { return $this->send('objects', 'move', $args); } /** * @param array $args */ public function composeObject(array $args = []) { return $this->send('objects', 'compose', $args); } /** * @param array $args */ public function getObject(array $args = []) { return $this->send('objects', 'get', $args); } /** * @param array $args */ public function listObjects(array $args = []) { return $this->send('objects', 'list', $args); } /** * @param array $args */ public function patchObject(array $args = []) { return $this->send('objects', 'patch', $args); } /** * @param array $args */ public function downloadObject(array $args = []) { // This makes sure we honour the range headers specified by the user $requestedBytes = $this->getRequestedBytes($args); $resultStream = Utils::streamFor(null); $transcodedObj = false; $args['retryStrategy'] ??= $this->retryStrategy; list($request, $requestOptions) = $this->buildDownloadObjectParams($args); $invocationId = Uuid::uuid4()->toString(); $requestOptions['retryHeaders'] = self::getRetryHeaders($invocationId, 1); $requestOptions['restRetryFunction'] = $this->getRestRetryFunction('objects', 'get', $args); // We try to deduce if the object is a transcoded object when we receive the headers. $requestOptions['restOptions']['on_headers'] = function ($response) use (&$transcodedObj) { $header = $response->getHeader(self::TRANSCODED_OBJ_HEADER_KEY); if (is_array($header) && in_array(self::TRANSCODED_OBJ_HEADER_VAL, $header)) { $transcodedObj = true; } }; $attempt = null; $requestOptions['restRetryListener'] = function ( \Exception $e, $retryAttempt, &$arguments ) use ( $resultStream, $requestedBytes, $invocationId, &$attempt, ) { // if the exception has a response for us to use if ($e instanceof RequestException && $e->hasResponse() && $e->getResponse()->getStatusCode() >= 200 && $e->getResponse()->getStatusCode() < 300 ) { $msg = (string) $e->getResponse()->getBody(); $fetchedStream = Utils::streamFor($msg); // add the partial response to our stream that we will return Utils::copyToStream($fetchedStream, $resultStream); // Start from the byte that was last fetched $startByte = intval($requestedBytes['startByte']) + $resultStream->getSize(); $endByte = $requestedBytes['endByte']; // modify the range headers to fetch the remaining data $arguments[1]['headers']['Range'] = sprintf('bytes=%s-%s', $startByte, $endByte); $arguments[0] = $this->modifyRequestForRetry($arguments[0], $retryAttempt, $invocationId); // Copy the final result to the end of the stream $attempt = $retryAttempt; } }; $fetchedStream = $this->requestWrapper->send( $request, $requestOptions )->getBody(); // If no retry attempt was made, then we can return the stream as is. // This is important in the case where downloadObject is called to open // the file but not to read from it yet. if ($attempt === null) { return $fetchedStream; } // If our object is a transcoded object, then Range headers are not honoured. // That means even if we had a partial download available, the final obj // that was fetched will contain the complete object. So, we don't need to copy // the partial stream, we can just return the stream we fetched. if ($transcodedObj) { return $fetchedStream; } Utils::copyToStream($fetchedStream, $resultStream); $resultStream->seek(0); return $resultStream; } /** * @param array $args * @experimental The experimental flag means that while we believe this method * or class is ready for use, it may change before release in backwards- * incompatible ways. Please use with caution, and test thoroughly when * upgrading. */ public function downloadObjectAsync(array $args = []) { list($request, $requestOptions) = $this->buildDownloadObjectParams($args); return $this->requestWrapper->sendAsync( $request, $requestOptions )->then(function (ResponseInterface $response) { return $response->getBody(); }); } /** * @param array $args */ public function insertObject(array $args = []) { $args = $this->resolveUploadOptions($args); $uploadType = AbstractUploader::UPLOAD_TYPE_RESUMABLE; if ($args['streamable']) { $uploaderClass = StreamableUploader::class; } elseif ($args['resumable']) { $uploaderClass = ResumableUploader::class; } else { $uploaderClass = MultipartUploader::class; $uploadType = AbstractUploader::UPLOAD_TYPE_MULTIPART; } $uriParams = [ 'bucket' => $args['bucket'], 'query' => [ 'predefinedAcl' => $args['predefinedAcl'], 'uploadType' => $uploadType, 'userProject' => $args['userProject'] ] ]; // Passing the preconditions we want to extract out of arguments // into our query params. $preconditions = self::$condIdempotentOps['objects.insert']; foreach ($preconditions as $precondition) { if (isset($args[$precondition])) { $uriParams['query'][$precondition] = $args[$precondition]; } } return new $uploaderClass( $this->requestWrapper, $args['data'], $this->expandUri($this->apiEndpoint . self::UPLOAD_PATH, $uriParams), $args['uploaderOptions'] ); } /** * @param array $args */ private function resolveUploadOptions(array $args) { $args += [ 'bucket' => null, 'name' => null, 'validate' => true, 'resumable' => null, 'streamable' => null, 'predefinedAcl' => null, 'metadata' => [], 'userProject' => null, ]; $args['retryStrategy'] ??= $this->retryStrategy; $args['data'] = Utils::streamFor($args['data']); if ($args['resumable'] === null) { $args['resumable'] = $args['data']->getSize() > AbstractUploader::RESUMABLE_LIMIT; } if (!$args['name']) { $args['name'] = basename($args['data']->getMetadata('uri')); } $validate = $this->chooseValidationMethod($args); if ($validate === 'md5') { $args['metadata']['md5Hash'] = base64_encode(Utils::hash($args['data'], 'md5', true)); } elseif ($validate === 'crc32') { $args['metadata']['crc32c'] = $this->crcFromStream($args['data']); } $args['metadata']['name'] = $args['name']; if (isset($args['retention'])) { // during object creation retention properties go into metadata // but not into request body $args['metadata']['retention'] = $args['retention']; unset($args['retention']); } unset($args['name']); $args['contentType'] = $args['metadata']['contentType'] ?? MimeType::fromFilename($args['metadata']['name']); $uploaderOptionKeys = [ 'restOptions', 'retries', 'requestTimeout', 'chunkSize', 'contentType', 'metadata', 'uploadProgressCallback', 'restDelayFunction', 'restCalcDelayFunction', ]; $args['uploaderOptions'] = array_intersect_key($args, array_flip($uploaderOptionKeys)); $args = array_diff_key($args, array_flip($uploaderOptionKeys)); // Passing on custom retry function to $args['uploaderOptions'] $retryFunc = $this->getRestRetryFunction( 'objects', 'insert', $args ); $args['uploaderOptions']['restRetryFunction'] = $retryFunc; $args['uploaderOptions'] = $this->addRetryHeaderLogic( $args['uploaderOptions'] ); return $args; } /** * @param array $args */ public function getBucketIamPolicy(array $args) { return $this->send('buckets', 'getIamPolicy', $args); } /** * @param array $args */ public function setBucketIamPolicy(array $args) { return $this->send('buckets', 'setIamPolicy', $args); } /** * @param array $args */ public function testBucketIamPermissions(array $args) { return $this->send('buckets', 'testIamPermissions', $args); } /** * @param array $args */ public function getNotification(array $args = []) { return $this->send('notifications', 'get', $args); } /** * @param array $args */ public function deleteNotification(array $args = []) { return $this->send('notifications', 'delete', $args); } /** * @param array $args */ public function insertNotification(array $args = []) { return $this->send('notifications', 'insert', $args); } /** * @param array $args */ public function listNotifications(array $args = []) { return $this->send('notifications', 'list', $args); } /** * @param array $args */ public function getServiceAccount(array $args = []) { return $this->send('projects.resources.serviceAccount', 'get', $args); } /** * @param array $args */ public function lockRetentionPolicy(array $args = []) { return $this->send('buckets', 'lockRetentionPolicy', $args); } /** * @param array $args */ public function createHmacKey(array $args = []) { return $this->send('projects.resources.hmacKeys', 'create', $args); } /** * @param array $args */ public function deleteHmacKey(array $args = []) { return $this->send('projects.resources.hmacKeys', 'delete', $args); } /** * @param array $args */ public function getHmacKey(array $args = []) { return $this->send('projects.resources.hmacKeys', 'get', $args); } /** * @param array $args */ public function updateHmacKey(array $args = []) { return $this->send('projects.resources.hmacKeys', 'update', $args); } /** * @param array $args */ public function listHmacKeys(array $args = []) { return $this->send('projects.resources.hmacKeys', 'list', $args); } /** * @param array $args * @return array */ private function buildDownloadObjectParams(array $args) { $args += [ 'bucket' => null, 'object' => null, 'generation' => null, 'userProject' => null ]; $requestOptions = array_intersect_key($args, [ 'restOptions' => null, 'retries' => null, 'restRetryFunction' => null, 'restCalcDelayFunction' => null, 'restDelayFunction' => null ]); $queryOptions = [ 'generation' => $args['generation'], 'alt' => 'media', 'userProject' => $args['userProject'], ]; if (isset($args['softDeleted'])) { // alt param cannot be specified with softDeleted param. See: // https://cloud.google.com/storage/docs/json_api/v1/objects/get unset($args['alt']); $queryOptions['softDeleted'] = $args['softDeleted']; } $uri = $this->expandUri($this->apiEndpoint . self::DOWNLOAD_PATH, [ 'bucket' => $args['bucket'], 'object' => $args['object'], 'query' => $queryOptions, ]); return [ new Request('GET', Utils::uriFor($uri)), $requestOptions ]; } /** * Choose an upload validation method based on user input and platform * requirements. * * @param array $args * @return bool|string */ private function chooseValidationMethod(array $args) { // If the user provided a hash, skip hashing. if (isset($args['metadata']['md5Hash']) || isset($args['metadata']['crc32c'])) { return false; } $validate = $args['validate']; if (in_array($validate, [false, 'crc32', 'md5'], true)) { return $validate; } // not documented, but the feature is called crc32c, so let's accept that as input anyways. if ($validate === 'crc32c') { return 'crc32'; } // is the extension loaded? if ($this->crc32cExtensionLoaded()) { return 'crc32'; } // is crc32c available in `hash()`? if ($this->supportsBuiltinCrc32c()) { return 'crc32'; } return 'md5'; } /** * Generate a CRC32c checksum from a stream. * * @param StreamInterface $data * @return string */ private function crcFromStream(StreamInterface $data) { $pos = $data->tell(); $data->rewind(); $crc32c = hash_init('crc32c'); while (!$data->eof()) { $buffer = $data->read(1048576); hash_update($crc32c, $buffer); } $data->seek($pos); $hash = hash_final($crc32c, true); return base64_encode($hash); } /** * Check if the crc32c extension is available. * * Protected access for unit testing. * * @return bool */ protected function crc32cExtensionLoaded() { return extension_loaded('crc32c'); } /** * Check if hash() supports crc32c. * * @return bool * @deprecated */ protected function supportsBuiltinCrc32c() { return extension_loaded('hash') && in_array('crc32c', hash_algos()); } /** * Add the required retry function and send the request. * * @param string $resource resource name, eg: buckets. * @param string $method method name, eg: get * @param array $options [optional] Options used to build out the request. * @param array $whitelisted [optional] */ public function send($resource, $method, array $options = [], $whitelisted = false) { $retryMap = [ 'projects.resources.serviceAccount' => 'serviceaccount', 'projects.resources.hmacKeys' => 'hmacKey', 'bucketAccessControls' => 'bucket_acl', 'defaultObjectAccessControls' => 'default_object_acl', 'objectAccessControls' => 'object_acl' ]; $retryResource = isset($retryMap[$resource]) ? $retryMap[$resource] : $resource; $options['restRetryFunction'] = $this->restRetryFunction ?? $this->getRestRetryFunction( $retryResource, $method, $options ); $options += array_filter([ 'retryStrategy' => $this->retryStrategy, 'restDelayFunction' => $this->restDelayFunction, 'restCalcDelayFunction' => $this->restCalcDelayFunction, 'restRetryListener' => $this->restRetryListener, ]); $options = $this->addRetryHeaderLogic($options); return $this->traitSend($resource, $method, $options); } /** * Adds the retry headers to $args which amends retry hash and attempt * count to the required header. * @param array $args * @return array */ private function addRetryHeaderLogic(array $args) { $invocationId = Uuid::uuid4()->toString(); $args['retryHeaders'] = self::getRetryHeaders($invocationId, 1); $userListener = $args['restRetryListener'] ?? null; // Adding callback logic to update headers while retrying $args['restRetryListener'] = function ( \Exception $e, $retryAttempt, &$arguments ) use ( $invocationId, $userListener ) { $arguments[0] = $this->modifyRequestForRetry( $arguments[0], $retryAttempt, $invocationId ); if ($userListener) { $userListener($e, $retryAttempt, $arguments); } }; return $args; } private function modifyRequestForRetry( RequestInterface $request, int $retryAttempt, string $invocationId ) { $changes = self::getRetryHeaders($invocationId, $retryAttempt + 1); $headerLine = $request->getHeaderLine(Retry::RETRY_HEADER_KEY); // An associative array to contain final header values as // $headerValueKey => $headerValue $headerElements = []; // Adding existing values $headerLineValues = explode(' ', $headerLine); foreach ($headerLineValues as $value) { $key = explode('/', $value)[0]; $headerElements[$key] = $value; } // Adding changes with replacing value if $key already present foreach ($changes as $change) { $key = explode('/', $change)[0]; $headerElements[$key] = $change; } return $request->withHeader( Retry::RETRY_HEADER_KEY, implode(' ', $headerElements) ); } /** * Util function to compute the bytes requested for a download request. * * @param array $options Request options * @return array */ private function getRequestedBytes(array $options) { $startByte = 0; $endByte = ''; if (isset($options['restOptions']) && isset($options['restOptions']['headers'])) { $headers = $options['restOptions']['headers']; if (isset($headers['Range']) || isset($headers['range'])) { $header = isset($headers['Range']) ? $headers['Range'] : $headers['range']; $range = explode('=', $header); $bytes = explode('-', $range[1]); $startByte = $bytes[0]; $endByte = $bytes[1]; } } return compact('startByte', 'endByte'); } } ================================================ FILE: lib/Google/vendor/google/cloud-storage/src/Connection/RetryTrait.php ================================================ ['ifMetagenerationMatch', 'etag'], // Currently etag is not supported, so this preCondition never available 'buckets.setIamPolicy' => ['etag'], 'buckets.update' => ['ifMetagenerationMatch', 'etag'], 'hmacKey.update' => ['etag'], 'objects.compose' => ['ifGenerationMatch'], 'objects.copy' => ['ifGenerationMatch'], 'objects.delete' => ['ifGenerationMatch'], 'objects.insert' => ['ifGenerationMatch', 'ifGenerationNotMatch'], 'objects.patch' => ['ifMetagenerationMatch', 'etag'], 'objects.rewrite' => ['ifGenerationMatch'], 'objects.update' => ['ifMetagenerationMatch'] ]; /** * Retry strategies which enforce certain behaviour like: * - Always retrying a call when an exception occurs(within the limits of 'max retries'). * - Never retrying a call when an exception occurs. * - Retrying only when the operation is considered idempotent(default). * These configurations are supplied for per api call basis. * */ /** * Header that identifies a specific request hash. The * hash needs to stay the same for multiple retries. */ private static $INVOCATION_ID_HEADER = 'gccl-invocation-id'; /** * Header that identifies the attempt count for a request. The * value will increment by 1 with every retry. */ private static $ATTEMPT_COUNT_HEADER = 'gccl-attempt-count'; /** * Return a retry decider function. * * @param string $resource resource name, eg: buckets. * @param string $method method name, eg: get * @param array $args * @return callable */ private function getRestRetryFunction($resource, $method, array $args) { if (isset($args['restRetryFunction'])) { return $args['restRetryFunction']; } $methodName = sprintf('%s.%s', $resource, $method); $isOpIdempotent = in_array($methodName, self::$idempotentOps); $preconditionNeeded = array_key_exists($methodName, self::$condIdempotentOps); $preconditionSupplied = $this->isPreConditionSupplied($methodName, $args); $retryStrategy = isset($args['retryStrategy']) ? $args['retryStrategy'] : StorageClient::RETRY_IDEMPOTENT; return function ( \Exception $exception, $currentAttempt = 0, $maxRetries = null ) use ( $isOpIdempotent, $preconditionNeeded, $preconditionSupplied, $retryStrategy ) { return $this->retryDeciderFunction( $exception, $isOpIdempotent, $preconditionNeeded, $preconditionSupplied, $retryStrategy, $currentAttempt, $maxRetries ); }; } /** * This function returns true when the user given * precondtions ($preConditions) has values that are present * in the precondition map ($this->condIdempotentMap) for that method. * eg: condIdempotentMap has entry 'objects.copy' => ['ifGenerationMatch'], * if the user has given 'ifGenerationMatch' in the 'objects.copy' operation, * it will be available in the $preConditions * as an array ['ifGenerationMatch']. This makes the array_intersect * function return a non empty result and this function returns true. * * @param string $methodName method name, eg: buckets.get. * @param array $args arguments which include preconditions provided, * eg: ['ifGenerationMatch' => 0]. * @return bool */ private function isPreConditionSupplied($methodName, array $args) { if (isset(self::$condIdempotentOps[$methodName])) { // return true if required precondition are given. return !empty(array_intersect( self::$condIdempotentOps[$methodName], array_keys($args) )); } return false; } /** * Decide whether the op needs to be retried or not. * * @param \Exception $exception The exception object received * while sending the request. * @param int $currentAttempt Current retry attempt. * @param bool $isIdempotent * @param bool $preconditionNeeded * @param bool $preconditionSupplied * @param int|null $maxRetries The maximum number of retries allowed. * Null for no limit. * @return bool */ private function retryDeciderFunction( \Exception $exception, $isIdempotent, $preconditionNeeded, $preconditionSupplied, $retryStrategy, $currentAttempt = 0, $maxRetries = null ) { // If maxRetries is specified, ensure we don't exceed it if ($maxRetries !== null && $currentAttempt >= $maxRetries) { return false; } if ($retryStrategy == StorageClient::RETRY_NEVER) { return false; } $statusCode = $exception->getCode(); // Retry if the exception status code matches // with one of the retriable status code and // the operation is either idempotent or conditionally // idempotent with preconditions supplied. if (in_array($statusCode, self::$httpRetryCodes)) { if ($retryStrategy == StorageClient::RETRY_ALWAYS) { return true; } elseif ($isIdempotent) { return true; } elseif ($preconditionNeeded) { return $preconditionSupplied; } } return false; } /** * Utility func that returns the list of headers that need to be * attached to every request and its retries. */ private static function getRetryHeaders($invocationId, $attemptCount) { return [ sprintf('%s/%s', self::$INVOCATION_ID_HEADER, $invocationId), sprintf('%s/%d', self::$ATTEMPT_COUNT_HEADER, $attemptCount) ]; } } ================================================ FILE: lib/Google/vendor/google/cloud-storage/src/Connection/ServiceDefinition/storage-v1.json ================================================ { "kind": "discovery#restDescription", "version": "v1", "id": "storage:v1", "rootUrl": "https://storage.googleapis.com/", "mtlsRootUrl": "https://storage.mtls.googleapis.com/", "baseUrl": "https://storage.googleapis.com/storage/v1/", "basePath": "/storage/v1/", "servicePath": "storage/v1/", "batchPath": "batch/storage/v1", "discoveryVersion": "v1", "name": "storage", "title": "Cloud Storage JSON API", "description": "Stores and retrieves potentially large, immutable data objects.", "ownerDomain": "google.com", "ownerName": "Google", "icons": { "x16": "https://www.google.com/images/icons/product/cloud_storage-16.png", "x32": "https://www.google.com/images/icons/product/cloud_storage-32.png" }, "documentationLink": "https://developers.google.com/storage/docs/json_api/", "labels": [ "labs" ], "endpoints": [ { "endpointUrl": "https://storage.me-central2.rep.googleapis.com/", "location": "me-central2", "description": "Regional Endpoint" } ], "protocol": "rest", "parameters": { "alt": { "type": "string", "description": "Data format for the response.", "default": "json", "enum": [ "json" ], "enumDescriptions": [ "Responses with Content-Type of application/json" ], "location": "query" }, "fields": { "type": "string", "description": "Selector specifying which fields to include in a partial response.", "location": "query" }, "key": { "type": "string", "description": "API key. Your API key identifies your project and provides you with API access, quota, and reports. Required unless you provide an OAuth 2.0 token.", "location": "query" }, "oauth_token": { "type": "string", "description": "OAuth 2.0 token for the current user.", "location": "query" }, "prettyPrint": { "type": "boolean", "description": "Returns response with indentations and line breaks.", "default": "true", "location": "query" }, "quotaUser": { "type": "string", "description": "An opaque string that represents a user for quota purposes. Must not exceed 40 characters.", "location": "query" }, "userIp": { "type": "string", "description": "Deprecated. Please use quotaUser instead.", "location": "query" }, "uploadType": { "type": "string", "description": "Upload protocol for media (e.g. \"media\", \"multipart\", \"resumable\").", "location": "query" } }, "auth": { "oauth2": { "scopes": { "https://www.googleapis.com/auth/cloud-platform": { "description": "View and manage your data across Google Cloud Platform services" }, "https://www.googleapis.com/auth/cloud-platform.read-only": { "description": "View your data across Google Cloud Platform services" }, "https://www.googleapis.com/auth/devstorage.full_control": { "description": "Manage your data and permissions in Google Cloud Storage" }, "https://www.googleapis.com/auth/devstorage.read_only": { "description": "View your data in Google Cloud Storage" }, "https://www.googleapis.com/auth/devstorage.read_write": { "description": "Manage your data in Google Cloud Storage" } } } }, "schemas": { "Bucket": { "id": "Bucket", "type": "object", "description": "A bucket.", "properties": { "acl": { "type": "array", "description": "Access controls on the bucket.", "items": { "$ref": "BucketAccessControl" }, "annotations": { "required": [ "storage.buckets.update" ] } }, "billing": { "type": "object", "description": "The bucket's billing configuration.", "properties": { "requesterPays": { "type": "boolean", "description": "When set to true, Requester Pays is enabled for this bucket." } } }, "cors": { "type": "array", "description": "The bucket's Cross-Origin Resource Sharing (CORS) configuration.", "items": { "type": "object", "properties": { "maxAgeSeconds": { "type": "integer", "description": "The value, in seconds, to return in the Access-Control-Max-Age header used in preflight responses.", "format": "int32" }, "method": { "type": "array", "description": "The list of HTTP methods on which to include CORS response headers, (GET, OPTIONS, POST, etc) Note: \"*\" is permitted in the list of methods, and means \"any method\".", "items": { "type": "string" } }, "origin": { "type": "array", "description": "The list of Origins eligible to receive CORS response headers. Note: \"*\" is permitted in the list of origins, and means \"any Origin\".", "items": { "type": "string" } }, "responseHeader": { "type": "array", "description": "The list of HTTP headers other than the simple response headers to give permission for the user-agent to share across domains.", "items": { "type": "string" } } } } }, "customPlacementConfig": { "type": "object", "description": "The bucket's custom placement configuration for Custom Dual Regions.", "properties": { "dataLocations": { "type": "array", "description": "The list of regional locations in which data is placed.", "items": { "type": "string" } } } }, "defaultEventBasedHold": { "type": "boolean", "description": "The default value for event-based hold on newly created objects in this bucket. Event-based hold is a way to retain objects indefinitely until an event occurs, signified by the hold's release. After being released, such objects will be subject to bucket-level retention (if any). One sample use case of this flag is for banks to hold loan documents for at least 3 years after loan is paid in full. Here, bucket-level retention is 3 years and the event is loan being paid in full. In this example, these objects will be held intact for any number of years until the event has occurred (event-based hold on the object is released) and then 3 more years after that. That means retention duration of the objects begins from the moment event-based hold transitioned from true to false. Objects under event-based hold cannot be deleted, overwritten or archived until the hold is removed." }, "defaultObjectAcl": { "type": "array", "description": "Default access controls to apply to new objects when no ACL is provided.", "items": { "$ref": "ObjectAccessControl" } }, "encryption": { "type": "object", "description": "Encryption configuration for a bucket.", "properties": { "defaultKmsKeyName": { "type": "string", "description": "A Cloud KMS key that will be used to encrypt objects inserted into this bucket, if no encryption method is specified." } } }, "etag": { "type": "string", "description": "HTTP 1.1 Entity tag for the bucket." }, "hierarchicalNamespace": { "type": "object", "description": "The bucket's hierarchical namespace configuration.", "properties": { "enabled": { "type": "boolean", "description": "When set to true, hierarchical namespace is enabled for this bucket." } } }, "iamConfiguration": { "type": "object", "description": "The bucket's IAM configuration.", "properties": { "bucketPolicyOnly": { "type": "object", "description": "The bucket's uniform bucket-level access configuration. The feature was formerly known as Bucket Policy Only. For backward compatibility, this field will be populated with identical information as the uniformBucketLevelAccess field. We recommend using the uniformBucketLevelAccess field to enable and disable the feature.", "properties": { "enabled": { "type": "boolean", "description": "If set, access is controlled only by bucket-level or above IAM policies." }, "lockedTime": { "type": "string", "description": "The deadline for changing iamConfiguration.bucketPolicyOnly.enabled from true to false in RFC 3339 format. iamConfiguration.bucketPolicyOnly.enabled may be changed from true to false until the locked time, after which the field is immutable.", "format": "date-time" } } }, "uniformBucketLevelAccess": { "type": "object", "description": "The bucket's uniform bucket-level access configuration.", "properties": { "enabled": { "type": "boolean", "description": "If set, access is controlled only by bucket-level or above IAM policies." }, "lockedTime": { "type": "string", "description": "The deadline for changing iamConfiguration.uniformBucketLevelAccess.enabled from true to false in RFC 3339 format. iamConfiguration.uniformBucketLevelAccess.enabled may be changed from true to false until the locked time, after which the field is immutable.", "format": "date-time" } } }, "publicAccessPrevention": { "type": "string", "description": "The bucket's Public Access Prevention configuration. Currently, 'inherited' and 'enforced' are supported." } } }, "id": { "type": "string", "description": "The ID of the bucket. For buckets, the id and name properties are the same." }, "kind": { "type": "string", "description": "The kind of item this is. For buckets, this is always storage#bucket.", "default": "storage#bucket" }, "labels": { "type": "object", "description": "User-provided labels, in key/value pairs.", "additionalProperties": { "type": "string", "description": "An individual label entry." } }, "lifecycle": { "type": "object", "description": "The bucket's lifecycle configuration. See lifecycle management for more information.", "properties": { "rule": { "type": "array", "description": "A lifecycle management rule, which is made of an action to take and the condition(s) under which the action will be taken.", "items": { "type": "object", "properties": { "action": { "type": "object", "description": "The action to take.", "properties": { "storageClass": { "type": "string", "description": "Target storage class. Required iff the type of the action is SetStorageClass." }, "type": { "type": "string", "description": "Type of the action. Currently, only Delete, SetStorageClass, and AbortIncompleteMultipartUpload are supported." } } }, "condition": { "type": "object", "description": "The condition(s) under which the action will be taken.", "properties": { "age": { "type": "integer", "description": "Age of an object (in days). This condition is satisfied when an object reaches the specified age.", "format": "int32" }, "createdBefore": { "type": "string", "description": "A date in RFC 3339 format with only the date part (for instance, \"2013-01-15\"). This condition is satisfied when an object is created before midnight of the specified date in UTC.", "format": "date" }, "customTimeBefore": { "type": "string", "description": "A date in RFC 3339 format with only the date part (for instance, \"2013-01-15\"). This condition is satisfied when the custom time on an object is before this date in UTC.", "format": "date" }, "daysSinceCustomTime": { "type": "integer", "description": "Number of days elapsed since the user-specified timestamp set on an object. The condition is satisfied if the days elapsed is at least this number. If no custom timestamp is specified on an object, the condition does not apply.", "format": "int32" }, "daysSinceNoncurrentTime": { "type": "integer", "description": "Number of days elapsed since the noncurrent timestamp of an object. The condition is satisfied if the days elapsed is at least this number. This condition is relevant only for versioned objects. The value of the field must be a nonnegative integer. If it's zero, the object version will become eligible for Lifecycle action as soon as it becomes noncurrent.", "format": "int32" }, "isLive": { "type": "boolean", "description": "Relevant only for versioned objects. If the value is true, this condition matches live objects; if the value is false, it matches archived objects." }, "matchesPattern": { "type": "string", "description": "A regular expression that satisfies the RE2 syntax. This condition is satisfied when the name of the object matches the RE2 pattern. Note: This feature is currently in the \"Early Access\" launch stage and is only available to a whitelisted set of users; that means that this feature may be changed in backward-incompatible ways and that it is not guaranteed to be released." }, "matchesPrefix": { "type": "array", "description": "List of object name prefixes. This condition will be satisfied when at least one of the prefixes exactly matches the beginning of the object name.", "items": { "type": "string" } }, "matchesSuffix": { "type": "array", "description": "List of object name suffixes. This condition will be satisfied when at least one of the suffixes exactly matches the end of the object name.", "items": { "type": "string" } }, "matchesStorageClass": { "type": "array", "description": "Objects having any of the storage classes specified by this condition will be matched. Values include MULTI_REGIONAL, REGIONAL, NEARLINE, COLDLINE, ARCHIVE, STANDARD, and DURABLE_REDUCED_AVAILABILITY.", "items": { "type": "string" } }, "noncurrentTimeBefore": { "type": "string", "description": "A date in RFC 3339 format with only the date part (for instance, \"2013-01-15\"). This condition is satisfied when the noncurrent time on an object is before this date in UTC. This condition is relevant only for versioned objects.", "format": "date" }, "numNewerVersions": { "type": "integer", "description": "Relevant only for versioned objects. If the value is N, this condition is satisfied when there are at least N versions (including the live version) newer than this version of the object.", "format": "int32" } } } } } } } }, "autoclass": { "type": "object", "description": "The bucket's Autoclass configuration.", "properties": { "enabled": { "type": "boolean", "description": "Whether or not Autoclass is enabled on this bucket" }, "toggleTime": { "type": "string", "description": "A date and time in RFC 3339 format representing the instant at which \"enabled\" was last toggled.", "format": "date-time" }, "terminalStorageClass": { "type": "string", "description": "The storage class that objects in the bucket eventually transition to if they are not read for a certain length of time. Valid values are NEARLINE and ARCHIVE." }, "terminalStorageClassUpdateTime": { "type": "string", "description": "A date and time in RFC 3339 format representing the time of the most recent update to \"terminalStorageClass\".", "format": "date-time" } } }, "location": { "type": "string", "description": "The location of the bucket. Object data for objects in the bucket resides in physical storage within this region. Defaults to US. See the developer's guide for the authoritative list." }, "locationType": { "type": "string", "description": "The type of the bucket location." }, "logging": { "type": "object", "description": "The bucket's logging configuration, which defines the destination bucket and optional name prefix for the current bucket's logs.", "properties": { "logBucket": { "type": "string", "description": "The destination bucket where the current bucket's logs should be placed." }, "logObjectPrefix": { "type": "string", "description": "A prefix for log object names." } } }, "metageneration": { "type": "string", "description": "The metadata generation of this bucket.", "format": "int64" }, "name": { "type": "string", "description": "The name of the bucket.", "annotations": { "required": [ "storage.buckets.insert" ] } }, "generation": { "type": "string", "description": "The version of the bucket.", "format": "int64" }, "owner": { "type": "object", "description": "The owner of the bucket. This is always the project team's owner group.", "properties": { "entity": { "type": "string", "description": "The entity, in the form project-owner-projectId." }, "entityId": { "type": "string", "description": "The ID for the entity." } } }, "projectNumber": { "type": "string", "description": "The project number of the project the bucket belongs to.", "format": "uint64" }, "retentionPolicy": { "type": "object", "description": "The bucket's retention policy. The retention policy enforces a minimum retention time for all objects contained in the bucket, based on their creation time. Any attempt to overwrite or delete objects younger than the retention period will result in a PERMISSION_DENIED error. An unlocked retention policy can be modified or removed from the bucket via a storage.buckets.update operation. A locked retention policy cannot be removed or shortened in duration for the lifetime of the bucket. Attempting to remove or decrease period of a locked retention policy will result in a PERMISSION_DENIED error.", "properties": { "effectiveTime": { "type": "string", "description": "Server-determined value that indicates the time from which policy was enforced and effective. This value is in RFC 3339 format.", "format": "date-time" }, "isLocked": { "type": "boolean", "description": "Once locked, an object retention policy cannot be modified." }, "retentionPeriod": { "type": "string", "description": "The duration in seconds that objects need to be retained. Retention duration must be greater than zero and less than 100 years. Note that enforcement of retention periods less than a day is not guaranteed. Such periods should only be used for testing purposes.", "format": "int64" } } }, "objectRetention": { "type": "object", "description": "The bucket's object retention config.", "properties": { "mode": { "type": "string", "description": "The bucket's object retention mode. Can be Enabled." } } }, "rpo": { "type": "string", "description": "The Recovery Point Objective (RPO) of this bucket. Set to ASYNC_TURBO to turn on Turbo Replication on a bucket." }, "selfLink": { "type": "string", "description": "The URI of this bucket." }, "softDeletePolicy": { "type": "object", "description": "The bucket's soft delete policy, which defines the period of time that soft-deleted objects will be retained, and cannot be permanently deleted.", "properties": { "retentionDurationSeconds": { "type": "string", "description": "The duration in seconds that soft-deleted objects in the bucket will be retained and cannot be permanently deleted.", "format": "int64" }, "effectiveTime": { "type": "string", "description": "Server-determined value that indicates the time from which the policy, or one with a greater retention, was effective. This value is in RFC 3339 format.", "format": "date-time" } } }, "softDeleteTime": { "type": "string", "description": "The time at which the bucket was soft-deleted.", "format": "date-time" }, "hardDeleteTime": { "type": "string", "description": "The time when a soft-deleted bucket is permanently deleted and can no longer be restored.", "format": "date-time" }, "storageClass": { "type": "string", "description": "The bucket's default storage class, used whenever no storageClass is specified for a newly-created object. This defines how objects in the bucket are stored and determines the SLA and the cost of storage. Values include MULTI_REGIONAL, REGIONAL, STANDARD, NEARLINE, COLDLINE, ARCHIVE, and DURABLE_REDUCED_AVAILABILITY. If this value is not specified when the bucket is created, it will default to STANDARD. For more information, see storage classes." }, "timeCreated": { "type": "string", "description": "The creation time of the bucket in RFC 3339 format.", "format": "date-time" }, "updated": { "type": "string", "description": "The modification time of the bucket in RFC 3339 format.", "format": "date-time" }, "versioning": { "type": "object", "description": "The bucket's versioning configuration.", "properties": { "enabled": { "type": "boolean", "description": "While set to true, versioning is fully enabled for this bucket." } } }, "website": { "type": "object", "description": "The bucket's website configuration, controlling how the service behaves when accessing bucket contents as a web site. See the Static Website Examples for more information.", "properties": { "mainPageSuffix": { "type": "string", "description": "If the requested object path is missing, the service will ensure the path has a trailing '/', append this suffix, and attempt to retrieve the resulting object. This allows the creation of index.html objects to represent directory pages." }, "notFoundPage": { "type": "string", "description": "If the requested object path is missing, and any mainPageSuffix object is missing, if applicable, the service will return the named object from this bucket as the content for a 404 Not Found result." } } }, "satisfiesPZS": { "type": "boolean", "description": "Reserved for future use." } } }, "AnywhereCache": { "id": "AnywhereCache", "type": "object", "description": "An Anywhere Cache instance.", "properties": { "kind": { "type": "string", "description": "The kind of item this is. For Anywhere Cache, this is always storage#anywhereCache.", "default": "storage#anywhereCache" }, "id": { "type": "string", "description": "The ID of the resource, including the project number, bucket name and anywhere cache ID." }, "selfLink": { "type": "string", "description": "The link to this cache instance." }, "bucket": { "type": "string", "description": "The name of the bucket containing this cache instance." }, "anywhereCacheId": { "type": "string", "description": "The ID of the Anywhere cache instance." }, "zone": { "type": "string", "description": "The zone in which the cache instance is running. For example, us-central1-a." }, "state": { "type": "string", "description": "The current state of the cache instance." }, "createTime": { "type": "string", "description": "The creation time of the cache instance in RFC 3339 format.", "format": "date-time" }, "updateTime": { "type": "string", "description": "The modification time of the cache instance metadata in RFC 3339 format.", "format": "date-time" }, "ttl": { "type": "string", "description": "The TTL of all cache entries in whole seconds. e.g., \"7200s\". ", "format": "google-duration" }, "admissionPolicy": { "type": "string", "description": "The cache-level entry admission policy." }, "pendingUpdate": { "type": "boolean", "description": "True if the cache instance has an active Update long-running operation." } } }, "AnywhereCaches": { "id": "AnywhereCaches", "type": "object", "description": "A list of Anywhere Caches.", "properties": { "kind": { "type": "string", "description": "The kind of item this is. For lists of Anywhere Caches, this is always storage#anywhereCaches.", "default": "storage#anywhereCaches" }, "nextPageToken": { "type": "string", "description": "The continuation token, used to page through large result sets. Provide this value in a subsequent request to return the next page of results." }, "items": { "type": "array", "description": "The list of items.", "items": { "$ref": "AnywhereCache" } } } }, "BucketAccessControl": { "id": "BucketAccessControl", "type": "object", "description": "An access-control entry.", "properties": { "bucket": { "type": "string", "description": "The name of the bucket." }, "domain": { "type": "string", "description": "The domain associated with the entity, if any." }, "email": { "type": "string", "description": "The email address associated with the entity, if any." }, "entity": { "type": "string", "description": "The entity holding the permission, in one of the following forms: \n- user-userId \n- user-email \n- group-groupId \n- group-email \n- domain-domain \n- project-team-projectId \n- allUsers \n- allAuthenticatedUsers Examples: \n- The user liz@example.com would be user-liz@example.com. \n- The group example@googlegroups.com would be group-example@googlegroups.com. \n- To refer to all members of the Google Apps for Business domain example.com, the entity would be domain-example.com.", "annotations": { "required": [ "storage.bucketAccessControls.insert" ] } }, "entityId": { "type": "string", "description": "The ID for the entity, if any." }, "etag": { "type": "string", "description": "HTTP 1.1 Entity tag for the access-control entry." }, "id": { "type": "string", "description": "The ID of the access-control entry." }, "kind": { "type": "string", "description": "The kind of item this is. For bucket access control entries, this is always storage#bucketAccessControl.", "default": "storage#bucketAccessControl" }, "projectTeam": { "type": "object", "description": "The project team associated with the entity, if any.", "properties": { "projectNumber": { "type": "string", "description": "The project number." }, "team": { "type": "string", "description": "The team." } } }, "role": { "type": "string", "description": "The access permission for the entity.", "annotations": { "required": [ "storage.bucketAccessControls.insert" ] } }, "selfLink": { "type": "string", "description": "The link to this access-control entry." } } }, "BucketAccessControls": { "id": "BucketAccessControls", "type": "object", "description": "An access-control list.", "properties": { "items": { "type": "array", "description": "The list of items.", "items": { "$ref": "BucketAccessControl" } }, "kind": { "type": "string", "description": "The kind of item this is. For lists of bucket access control entries, this is always storage#bucketAccessControls.", "default": "storage#bucketAccessControls" } } }, "Buckets": { "id": "Buckets", "type": "object", "description": "A list of buckets.", "properties": { "items": { "type": "array", "description": "The list of items.", "items": { "$ref": "Bucket" } }, "unreachable": { "type": "array", "description": "The list of bucket resource names that could not be reached during the listing operation.", "items": { "type": "string" } }, "kind": { "type": "string", "description": "The kind of item this is. For lists of buckets, this is always storage#buckets.", "default": "storage#buckets" }, "nextPageToken": { "type": "string", "description": "The continuation token, used to page through large result sets. Provide this value in a subsequent request to return the next page of results." } } }, "Channel": { "id": "Channel", "type": "object", "description": "An notification channel used to watch for resource changes.", "properties": { "address": { "type": "string", "description": "The address where notifications are delivered for this channel." }, "expiration": { "type": "string", "description": "Date and time of notification channel expiration, expressed as a Unix timestamp, in milliseconds. Optional.", "format": "int64" }, "id": { "type": "string", "description": "A UUID or similar unique string that identifies this channel." }, "kind": { "type": "string", "description": "Identifies this as a notification channel used to watch for changes to a resource, which is \"api#channel\".", "default": "api#channel" }, "params": { "type": "object", "description": "Additional parameters controlling delivery channel behavior. Optional.", "additionalProperties": { "type": "string", "description": "Declares a new parameter by name." } }, "payload": { "type": "boolean", "description": "A Boolean value to indicate whether payload is wanted. Optional." }, "resourceId": { "type": "string", "description": "An opaque ID that identifies the resource being watched on this channel. Stable across different API versions." }, "resourceUri": { "type": "string", "description": "A version-specific identifier for the watched resource." }, "token": { "type": "string", "description": "An arbitrary string delivered to the target address with each notification delivered over this channel. Optional." }, "type": { "type": "string", "description": "The type of delivery mechanism used for this channel." } } }, "ComposeRequest": { "id": "ComposeRequest", "type": "object", "description": "A Compose request.", "properties": { "destination": { "$ref": "Object", "description": "Properties of the resulting object." }, "kind": { "type": "string", "description": "The kind of item this is.", "default": "storage#composeRequest" }, "sourceObjects": { "type": "array", "description": "The list of source objects that will be concatenated into a single object.", "items": { "type": "object", "properties": { "generation": { "type": "string", "description": "The generation of this object to use as the source.", "format": "int64" }, "name": { "type": "string", "description": "The source object's name. All source objects must reside in the same bucket.", "annotations": { "required": [ "storage.objects.compose" ] } }, "objectPreconditions": { "type": "object", "description": "Conditions that must be met for this operation to execute.", "properties": { "ifGenerationMatch": { "type": "string", "description": "Only perform the composition if the generation of the source object that would be used matches this value. If this value and a generation are both specified, they must be the same value or the call will fail.", "format": "int64" } } } } }, "annotations": { "required": [ "storage.objects.compose" ] } } } }, "Folder": { "id": "Folder", "type": "object", "description": "A folder. Only available in buckets with hierarchical namespace enabled.", "properties": { "bucket": { "type": "string", "description": "The name of the bucket containing this folder." }, "id": { "type": "string", "description": "The ID of the folder, including the bucket name, folder name." }, "kind": { "type": "string", "description": "The kind of item this is. For folders, this is always storage#folder.", "default": "storage#folder" }, "metageneration": { "type": "string", "description": "The version of the metadata for this folder. Used for preconditions and for detecting changes in metadata.", "format": "int64" }, "name": { "type": "string", "description": "The name of the folder. Required if not specified by URL parameter." }, "selfLink": { "type": "string", "description": "The link to this folder." }, "createTime": { "type": "string", "description": "The creation time of the folder in RFC 3339 format.", "format": "date-time" }, "updateTime": { "type": "string", "description": "The modification time of the folder metadata in RFC 3339 format.", "format": "date-time" }, "pendingRenameInfo": { "type": "object", "description": "Only present if the folder is part of an ongoing rename folder operation. Contains information which can be used to query the operation status.", "properties": { "operationId": { "type": "string", "description": "The ID of the rename folder operation." } } } } }, "Folders": { "id": "Folders", "type": "object", "description": "A list of folders.", "properties": { "items": { "type": "array", "description": "The list of items.", "items": { "$ref": "Folder" } }, "kind": { "type": "string", "description": "The kind of item this is. For lists of folders, this is always storage#folders.", "default": "storage#folders" }, "nextPageToken": { "type": "string", "description": "The continuation token, used to page through large result sets. Provide this value in a subsequent request to return the next page of results." } } }, "Expr": { "id": "Expr", "type": "object", "description": "Represents an expression text. Example: title: \"User account presence\" description: \"Determines whether the request has a user account\" expression: \"size(request.user) > 0\"", "properties": { "description": { "type": "string", "description": "An optional description of the expression. This is a longer text which describes the expression, e.g. when hovered over it in a UI." }, "expression": { "type": "string", "description": "Textual representation of an expression in Common Expression Language syntax. The application context of the containing message determines which well-known feature set of CEL is supported." }, "location": { "type": "string", "description": "An optional string indicating the location of the expression for error reporting, e.g. a file name and a position in the file." }, "title": { "type": "string", "description": "An optional title for the expression, i.e. a short string describing its purpose. This can be used e.g. in UIs which allow to enter the expression." } } }, "GoogleLongrunningOperation": { "description": "This resource represents a long-running operation that is the result of a network API call.", "id": "GoogleLongrunningOperation", "properties": { "done": { "description": "If the value is \"false\", it means the operation is still in progress. If \"true\", the operation is completed, and either \"error\" or \"response\" is available.", "type": "boolean" }, "error": { "$ref": "GoogleRpcStatus", "description": "The error result of the operation in case of failure or cancellation." }, "metadata": { "additionalProperties": { "description": "Properties of the object. Contains field @type with type URL.", "type": "any" }, "description": "Service-specific metadata associated with the operation. It typically contains progress information and common metadata such as create time. Some services might not provide such metadata. Any method that returns a long-running operation should document the metadata type, if any.", "type": "object" }, "name": { "description": "The server-assigned name, which is only unique within the same service that originally returns it. If you use the default HTTP mapping, the \"name\" should be a resource name ending with \"operations/{operationId}\".", "type": "string" }, "response": { "additionalProperties": { "description": "Properties of the object. Contains field @type with type URL.", "type": "any" }, "description": "The normal response of the operation in case of success. If the original method returns no data on success, such as \"Delete\", the response is google.protobuf.Empty. If the original method is standard Get/Create/Update, the response should be the resource. For other methods, the response should have the type \"XxxResponse\", where \"Xxx\" is the original method name. For example, if the original method name is \"TakeSnapshot()\", the inferred response type is \"TakeSnapshotResponse\".", "type": "object" } }, "type": "object" }, "GoogleLongrunningListOperationsResponse": { "description": "The response message for storage.buckets.operations.list.", "id": "GoogleLongrunningListOperationsResponse", "properties": { "nextPageToken": { "type": "string", "description": "The continuation token, used to page through large result sets. Provide this value in a subsequent request to return the next page of results." }, "operations": { "description": "A list of operations that matches the specified filter in the request.", "items": { "$ref": "GoogleLongrunningOperation" }, "type": "array" } }, "type": "object" }, "GoogleRpcStatus": { "description": "The \"Status\" type defines a logical error model that is suitable for different programming environments, including REST APIs and RPC APIs. It is used by [gRPC](https://github.com/grpc). Each \"Status\" message contains three pieces of data: error code, error message, and error details. You can find out more about this error model and how to work with it in the [API Design Guide](https://cloud.google.com/apis/design/errors).", "id": "GoogleRpcStatus", "properties": { "code": { "description": "The status code, which should be an enum value of google.rpc.Code.", "format": "int32", "type": "integer" }, "details": { "description": "A list of messages that carry the error details. There is a common set of message types for APIs to use.", "items": { "additionalProperties": { "description": "Properties of the object. Contains field @type with type URL.", "type": "any" }, "type": "object" }, "type": "array" }, "message": { "description": "A developer-facing error message, which should be in English.", "type": "string" } }, "type": "object" }, "HmacKey": { "id": "HmacKey", "type": "object", "description": "JSON template to produce a JSON-style HMAC Key resource for Create responses.", "properties": { "kind": { "type": "string", "description": "The kind of item this is. For HMAC keys, this is always storage#hmacKey.", "default": "storage#hmacKey" }, "metadata": { "$ref": "HmacKeyMetadata", "description": "Key metadata." }, "secret": { "type": "string", "description": "HMAC secret key material." } } }, "HmacKeyMetadata": { "id": "HmacKeyMetadata", "type": "object", "description": "JSON template to produce a JSON-style HMAC Key metadata resource.", "properties": { "accessId": { "type": "string", "description": "The ID of the HMAC Key." }, "etag": { "type": "string", "description": "HTTP 1.1 Entity tag for the HMAC key." }, "id": { "type": "string", "description": "The ID of the HMAC key, including the Project ID and the Access ID." }, "kind": { "type": "string", "description": "The kind of item this is. For HMAC Key metadata, this is always storage#hmacKeyMetadata.", "default": "storage#hmacKeyMetadata" }, "projectId": { "type": "string", "description": "Project ID owning the service account to which the key authenticates." }, "selfLink": { "type": "string", "description": "The link to this resource." }, "serviceAccountEmail": { "type": "string", "description": "The email address of the key's associated service account." }, "state": { "type": "string", "description": "The state of the key. Can be one of ACTIVE, INACTIVE, or DELETED." }, "timeCreated": { "type": "string", "description": "The creation time of the HMAC key in RFC 3339 format.", "format": "date-time" }, "updated": { "type": "string", "description": "The last modification time of the HMAC key metadata in RFC 3339 format.", "format": "date-time" } } }, "HmacKeysMetadata": { "id": "HmacKeysMetadata", "type": "object", "description": "A list of hmacKeys.", "properties": { "items": { "type": "array", "description": "The list of items.", "items": { "$ref": "HmacKeyMetadata" } }, "kind": { "type": "string", "description": "The kind of item this is. For lists of hmacKeys, this is always storage#hmacKeysMetadata.", "default": "storage#hmacKeysMetadata" }, "nextPageToken": { "type": "string", "description": "The continuation token, used to page through large result sets. Provide this value in a subsequent request to return the next page of results." } } }, "ManagedFolder": { "id": "ManagedFolder", "type": "object", "description": "A managed folder.", "properties": { "bucket": { "type": "string", "description": "The name of the bucket containing this managed folder." }, "id": { "type": "string", "description": "The ID of the managed folder, including the bucket name and managed folder name." }, "kind": { "type": "string", "description": "The kind of item this is. For managed folders, this is always storage#managedFolder.", "default": "storage#managedFolder" }, "metageneration": { "type": "string", "description": "The version of the metadata for this managed folder. Used for preconditions and for detecting changes in metadata.", "format": "int64" }, "name": { "type": "string", "description": "The name of the managed folder. Required if not specified by URL parameter." }, "selfLink": { "type": "string", "description": "The link to this managed folder." }, "createTime": { "type": "string", "description": "The creation time of the managed folder in RFC 3339 format.", "format": "date-time" }, "updateTime": { "type": "string", "description": "The last update time of the managed folder metadata in RFC 3339 format.", "format": "date-time" } } }, "ManagedFolders": { "id": "ManagedFolders", "type": "object", "description": "A list of managed folders.", "properties": { "items": { "type": "array", "description": "The list of items.", "items": { "$ref": "ManagedFolder" } }, "kind": { "type": "string", "description": "The kind of item this is. For lists of managed folders, this is always storage#managedFolders.", "default": "storage#managedFolders" }, "nextPageToken": { "type": "string", "description": "The continuation token, used to page through large result sets. Provide this value in a subsequent request to return the next page of results." } } }, "Notification": { "id": "Notification", "type": "object", "description": "A subscription to receive Google PubSub notifications.", "properties": { "custom_attributes": { "type": "object", "description": "An optional list of additional attributes to attach to each Cloud PubSub message published for this notification subscription.", "additionalProperties": { "type": "string" } }, "etag": { "type": "string", "description": "HTTP 1.1 Entity tag for this subscription notification." }, "event_types": { "type": "array", "description": "If present, only send notifications about listed event types. If empty, sent notifications for all event types.", "items": { "type": "string" } }, "id": { "type": "string", "description": "The ID of the notification." }, "kind": { "type": "string", "description": "The kind of item this is. For notifications, this is always storage#notification.", "default": "storage#notification" }, "object_name_prefix": { "type": "string", "description": "If present, only apply this notification configuration to object names that begin with this prefix." }, "payload_format": { "type": "string", "description": "The desired content of the Payload.", "default": "JSON_API_V1", "annotations": { "required": [ "storage.notifications.insert" ] } }, "selfLink": { "type": "string", "description": "The canonical URL of this notification." }, "topic": { "type": "string", "description": "The Cloud PubSub topic to which this subscription publishes. Formatted as: '//pubsub.googleapis.com/projects/{project-identifier}/topics/{my-topic}'", "annotations": { "required": [ "storage.notifications.insert" ] } } } }, "Notifications": { "id": "Notifications", "type": "object", "description": "A list of notification subscriptions.", "properties": { "items": { "type": "array", "description": "The list of items.", "items": { "$ref": "Notification" } }, "kind": { "type": "string", "description": "The kind of item this is. For lists of notifications, this is always storage#notifications.", "default": "storage#notifications" } } }, "Object": { "id": "Object", "type": "object", "description": "An object.", "properties": { "acl": { "type": "array", "description": "Access controls on the object.", "items": { "$ref": "ObjectAccessControl" }, "annotations": { "required": [ "storage.objects.update" ] } }, "bucket": { "type": "string", "description": "The name of the bucket containing this object." }, "cacheControl": { "type": "string", "description": "Cache-Control directive for the object data. If omitted, and the object is accessible to all anonymous users, the default will be public, max-age=3600." }, "componentCount": { "type": "integer", "description": "Number of underlying components that make up this object. Components are accumulated by compose operations.", "format": "int32" }, "contentDisposition": { "type": "string", "description": "Content-Disposition of the object data." }, "contentEncoding": { "type": "string", "description": "Content-Encoding of the object data." }, "contentLanguage": { "type": "string", "description": "Content-Language of the object data." }, "contentType": { "type": "string", "description": "Content-Type of the object data. If an object is stored without a Content-Type, it is served as application/octet-stream." }, "crc32c": { "type": "string", "description": "CRC32c checksum, as described in RFC 4960, Appendix B; encoded using base64 in big-endian byte order. For more information about using the CRC32c checksum, see Hashes and ETags: Best Practices." }, "customTime": { "type": "string", "description": "A timestamp in RFC 3339 format specified by the user for an object.", "format": "date-time" }, "customerEncryption": { "type": "object", "description": "Metadata of customer-supplied encryption key, if the object is encrypted by such a key.", "properties": { "encryptionAlgorithm": { "type": "string", "description": "The encryption algorithm." }, "keySha256": { "type": "string", "description": "SHA256 hash value of the encryption key." } } }, "etag": { "type": "string", "description": "HTTP 1.1 Entity tag for the object." }, "eventBasedHold": { "type": "boolean", "description": "Whether an object is under event-based hold. Event-based hold is a way to retain objects until an event occurs, which is signified by the hold's release (i.e. this value is set to false). After being released (set to false), such objects will be subject to bucket-level retention (if any). One sample use case of this flag is for banks to hold loan documents for at least 3 years after loan is paid in full. Here, bucket-level retention is 3 years and the event is the loan being paid in full. In this example, these objects will be held intact for any number of years until the event has occurred (event-based hold on the object is released) and then 3 more years after that. That means retention duration of the objects begins from the moment event-based hold transitioned from true to false." }, "generation": { "type": "string", "description": "The content generation of this object. Used for object versioning.", "format": "int64" }, "id": { "type": "string", "description": "The ID of the object, including the bucket name, object name, and generation number." }, "kind": { "type": "string", "description": "The kind of item this is. For objects, this is always storage#object.", "default": "storage#object" }, "kmsKeyName": { "type": "string", "description": "Not currently supported. Specifying the parameter causes the request to fail with status code 400 - Bad Request." }, "md5Hash": { "type": "string", "description": "MD5 hash of the data; encoded using base64. For more information about using the MD5 hash, see Hashes and ETags: Best Practices." }, "mediaLink": { "type": "string", "description": "Media download link." }, "metadata": { "type": "object", "description": "User-provided metadata, in key/value pairs.", "additionalProperties": { "type": "string", "description": "An individual metadata entry." } }, "metageneration": { "type": "string", "description": "The version of the metadata for this object at this generation. Used for preconditions and for detecting changes in metadata. A metageneration number is only meaningful in the context of a particular generation of a particular object.", "format": "int64" }, "name": { "type": "string", "description": "The name of the object. Required if not specified by URL parameter." }, "owner": { "type": "object", "description": "The owner of the object. This will always be the uploader of the object.", "properties": { "entity": { "type": "string", "description": "The entity, in the form user-userId." }, "entityId": { "type": "string", "description": "The ID for the entity." } } }, "retentionExpirationTime": { "type": "string", "description": "A server-determined value that specifies the earliest time that the object's retention period expires. This value is in RFC 3339 format. Note 1: This field is not provided for objects with an active event-based hold, since retention expiration is unknown until the hold is removed. Note 2: This value can be provided even when temporary hold is set (so that the user can reason about policy without having to first unset the temporary hold).", "format": "date-time" }, "retention": { "type": "object", "description": "A collection of object level retention parameters.", "properties": { "retainUntilTime": { "type": "string", "description": "A time in RFC 3339 format until which object retention protects this object.", "format": "date-time" }, "mode": { "type": "string", "description": "The bucket's object retention mode, can only be Unlocked or Locked." } } }, "selfLink": { "type": "string", "description": "The link to this object." }, "size": { "type": "string", "description": "Content-Length of the data in bytes.", "format": "uint64" }, "storageClass": { "type": "string", "description": "Storage class of the object." }, "temporaryHold": { "type": "boolean", "description": "Whether an object is under temporary hold. While this flag is set to true, the object is protected against deletion and overwrites. A common use case of this flag is regulatory investigations where objects need to be retained while the investigation is ongoing. Note that unlike event-based hold, temporary hold does not impact retention expiration time of an object." }, "timeCreated": { "type": "string", "description": "The creation time of the object in RFC 3339 format.", "format": "date-time" }, "timeDeleted": { "type": "string", "description": "The time at which the object became noncurrent in RFC 3339 format. Will be returned if and only if this version of the object has been deleted.", "format": "date-time" }, "softDeleteTime": { "type": "string", "description": "The time at which the object became soft-deleted in RFC 3339 format.", "format": "date-time" }, "hardDeleteTime": { "type": "string", "description": "This is the time (in the future) when the soft-deleted object will no longer be restorable. It is equal to the soft delete time plus the current soft delete retention duration of the bucket.", "format": "date-time" }, "timeStorageClassUpdated": { "type": "string", "description": "The time at which the object's storage class was last changed. When the object is initially created, it will be set to timeCreated.", "format": "date-time" }, "updated": { "type": "string", "description": "The modification time of the object metadata in RFC 3339 format. Set initially to object creation time and then updated whenever any metadata of the object changes. This includes changes made by a requester, such as modifying custom metadata, as well as changes made by Cloud Storage on behalf of a requester, such as changing the storage class based on an Object Lifecycle Configuration.", "format": "date-time" } } }, "ObjectAccessControl": { "id": "ObjectAccessControl", "type": "object", "description": "An access-control entry.", "properties": { "bucket": { "type": "string", "description": "The name of the bucket." }, "domain": { "type": "string", "description": "The domain associated with the entity, if any." }, "email": { "type": "string", "description": "The email address associated with the entity, if any." }, "entity": { "type": "string", "description": "The entity holding the permission, in one of the following forms: \n- user-userId \n- user-email \n- group-groupId \n- group-email \n- domain-domain \n- project-team-projectId \n- allUsers \n- allAuthenticatedUsers Examples: \n- The user liz@example.com would be user-liz@example.com. \n- The group example@googlegroups.com would be group-example@googlegroups.com. \n- To refer to all members of the Google Apps for Business domain example.com, the entity would be domain-example.com.", "annotations": { "required": [ "storage.defaultObjectAccessControls.insert", "storage.objectAccessControls.insert" ] } }, "entityId": { "type": "string", "description": "The ID for the entity, if any." }, "etag": { "type": "string", "description": "HTTP 1.1 Entity tag for the access-control entry." }, "generation": { "type": "string", "description": "The content generation of the object, if applied to an object.", "format": "int64" }, "id": { "type": "string", "description": "The ID of the access-control entry." }, "kind": { "type": "string", "description": "The kind of item this is. For object access control entries, this is always storage#objectAccessControl.", "default": "storage#objectAccessControl" }, "object": { "type": "string", "description": "The name of the object, if applied to an object." }, "projectTeam": { "type": "object", "description": "The project team associated with the entity, if any.", "properties": { "projectNumber": { "type": "string", "description": "The project number." }, "team": { "type": "string", "description": "The team." } } }, "role": { "type": "string", "description": "The access permission for the entity.", "annotations": { "required": [ "storage.defaultObjectAccessControls.insert", "storage.objectAccessControls.insert" ] } }, "selfLink": { "type": "string", "description": "The link to this access-control entry." } } }, "ObjectAccessControls": { "id": "ObjectAccessControls", "type": "object", "description": "An access-control list.", "properties": { "items": { "type": "array", "description": "The list of items.", "items": { "$ref": "ObjectAccessControl" } }, "kind": { "type": "string", "description": "The kind of item this is. For lists of object access control entries, this is always storage#objectAccessControls.", "default": "storage#objectAccessControls" } } }, "Objects": { "id": "Objects", "type": "object", "description": "A list of objects.", "properties": { "items": { "type": "array", "description": "The list of items.", "items": { "$ref": "Object" } }, "kind": { "type": "string", "description": "The kind of item this is. For lists of objects, this is always storage#objects.", "default": "storage#objects" }, "nextPageToken": { "type": "string", "description": "The continuation token, used to page through large result sets. Provide this value in a subsequent request to return the next page of results." }, "prefixes": { "type": "array", "description": "The list of prefixes of objects matching-but-not-listed up to and including the requested delimiter.", "items": { "type": "string" } } } }, "Policy": { "id": "Policy", "type": "object", "description": "A bucket/object/managedFolder IAM policy.", "properties": { "bindings": { "type": "array", "description": "An association between a role, which comes with a set of permissions, and members who may assume that role.", "items": { "type": "object", "properties": { "condition": { "$ref": "Expr", "description": "The condition that is associated with this binding. NOTE: an unsatisfied condition will not allow user access via current binding. Different bindings, including their conditions, are examined independently." }, "members": { "type": "array", "description": "A collection of identifiers for members who may assume the provided role. Recognized identifiers are as follows: \n- allUsers \u2014 A special identifier that represents anyone on the internet; with or without a Google account. \n- allAuthenticatedUsers \u2014 A special identifier that represents anyone who is authenticated with a Google account or a service account. \n- user:emailid \u2014 An email address that represents a specific account. For example, user:alice@gmail.com or user:joe@example.com. \n- serviceAccount:emailid \u2014 An email address that represents a service account. For example, serviceAccount:my-other-app@appspot.gserviceaccount.com . \n- group:emailid \u2014 An email address that represents a Google group. For example, group:admins@example.com. \n- domain:domain \u2014 A Google Apps domain name that represents all the users of that domain. For example, domain:google.com or domain:example.com. \n- projectOwner:projectid \u2014 Owners of the given project. For example, projectOwner:my-example-project \n- projectEditor:projectid \u2014 Editors of the given project. For example, projectEditor:my-example-project \n- projectViewer:projectid \u2014 Viewers of the given project. For example, projectViewer:my-example-project", "items": { "type": "string" }, "annotations": { "required": [ "storage.buckets.setIamPolicy", "storage.objects.setIamPolicy", "storage.managedFolders.setIamPolicy" ] } }, "role": { "type": "string", "description": "The role to which members belong. Two types of roles are supported: new IAM roles, which grant permissions that do not map directly to those provided by ACLs, and legacy IAM roles, which do map directly to ACL permissions. All roles are of the format roles/storage.specificRole.\nThe new IAM roles are: \n- roles/storage.admin \u2014 Full control of Google Cloud Storage resources. \n- roles/storage.objectViewer \u2014 Read-Only access to Google Cloud Storage objects. \n- roles/storage.objectCreator \u2014 Access to create objects in Google Cloud Storage. \n- roles/storage.objectAdmin \u2014 Full control of Google Cloud Storage objects. The legacy IAM roles are: \n- roles/storage.legacyObjectReader \u2014 Read-only access to objects without listing. Equivalent to an ACL entry on an object with the READER role. \n- roles/storage.legacyObjectOwner \u2014 Read/write access to existing objects without listing. Equivalent to an ACL entry on an object with the OWNER role. \n- roles/storage.legacyBucketReader \u2014 Read access to buckets with object listing. Equivalent to an ACL entry on a bucket with the READER role. \n- roles/storage.legacyBucketWriter \u2014 Read access to buckets with object listing/creation/deletion. Equivalent to an ACL entry on a bucket with the WRITER role. \n- roles/storage.legacyBucketOwner \u2014 Read and write access to existing buckets with object listing/creation/deletion. Equivalent to an ACL entry on a bucket with the OWNER role.", "annotations": { "required": [ "storage.buckets.setIamPolicy", "storage.objects.setIamPolicy", "storage.managedFolders.setIamPolicy" ] } } } }, "annotations": { "required": [ "storage.buckets.setIamPolicy", "storage.objects.setIamPolicy", "storage.managedFolders.setIamPolicy" ] } }, "etag": { "type": "string", "description": "HTTP 1.1 Entity tag for the policy.", "format": "byte" }, "kind": { "type": "string", "description": "The kind of item this is. For policies, this is always storage#policy. This field is ignored on input.", "default": "storage#policy" }, "resourceId": { "type": "string", "description": "The ID of the resource to which this policy belongs. Will be of the form projects/_/buckets/bucket for buckets, projects/_/buckets/bucket/objects/object for objects, and projects/_/buckets/bucket/managedFolders/managedFolder. A specific generation may be specified by appending #generationNumber to the end of the object name, e.g. projects/_/buckets/my-bucket/objects/data.txt#17. The current generation can be denoted with #0. This field is ignored on input." }, "version": { "type": "integer", "description": "The IAM policy format version.", "format": "int32" } } }, "RewriteResponse": { "id": "RewriteResponse", "type": "object", "description": "A rewrite response.", "properties": { "done": { "type": "boolean", "description": "true if the copy is finished; otherwise, false if the copy is in progress. This property is always present in the response." }, "kind": { "type": "string", "description": "The kind of item this is.", "default": "storage#rewriteResponse" }, "objectSize": { "type": "string", "description": "The total size of the object being copied in bytes. This property is always present in the response.", "format": "int64" }, "resource": { "$ref": "Object", "description": "A resource containing the metadata for the copied-to object. This property is present in the response only when copying completes." }, "rewriteToken": { "type": "string", "description": "A token to use in subsequent requests to continue copying data. This token is present in the response only when there is more data to copy." }, "totalBytesRewritten": { "type": "string", "description": "The total bytes written so far, which can be used to provide a waiting user with a progress indicator. This property is always present in the response.", "format": "int64" } } }, "ServiceAccount": { "id": "ServiceAccount", "type": "object", "description": "A subscription to receive Google PubSub notifications.", "properties": { "email_address": { "type": "string", "description": "The ID of the notification." }, "kind": { "type": "string", "description": "The kind of item this is. For notifications, this is always storage#notification.", "default": "storage#serviceAccount" } } }, "TestIamPermissionsResponse": { "id": "TestIamPermissionsResponse", "type": "object", "description": "A storage.(buckets|objects|managedFolders).testIamPermissions response.", "properties": { "kind": { "type": "string", "description": "The kind of item this is.", "default": "storage#testIamPermissionsResponse" }, "permissions": { "type": "array", "description": "The permissions held by the caller. Permissions are always of the format storage.resource.capability, where resource is one of buckets, objects, or managedFolders. The supported permissions are as follows: \n- storage.buckets.delete \u2014 Delete bucket. \n- storage.buckets.get \u2014 Read bucket metadata. \n- storage.buckets.getIamPolicy \u2014 Read bucket IAM policy. \n- storage.buckets.create \u2014 Create bucket. \n- storage.buckets.list \u2014 List buckets. \n- storage.buckets.setIamPolicy \u2014 Update bucket IAM policy. \n- storage.buckets.update \u2014 Update bucket metadata. \n- storage.objects.delete \u2014 Delete object. \n- storage.objects.get \u2014 Read object data and metadata. \n- storage.objects.getIamPolicy \u2014 Read object IAM policy. \n- storage.objects.create \u2014 Create object. \n- storage.objects.list \u2014 List objects. \n- storage.objects.setIamPolicy \u2014 Update object IAM policy. \n- storage.objects.update \u2014 Update object metadata. \n- storage.managedFolders.delete \u2014 Delete managed folder. \n- storage.managedFolders.get \u2014 Read managed folder metadata. \n- storage.managedFolders.getIamPolicy \u2014 Read managed folder IAM policy. \n- storage.managedFolders.create \u2014 Create managed folder. \n- storage.managedFolders.list \u2014 List managed folders. \n- storage.managedFolders.setIamPolicy \u2014 Update managed folder IAM policy.", "items": { "type": "string" } } } }, "BulkRestoreObjectsRequest": { "id": "BulkRestoreObjectsRequest", "type": "object", "description": "A bulk restore objects request.", "properties": { "allowOverwrite": { "type": "boolean", "description": "If false (default), the restore will not overwrite live objects with the same name at the destination. This means some deleted objects may be skipped. If true, live objects will be overwritten resulting in a noncurrent object (if versioning is enabled). If versioning is not enabled, overwriting the object will result in a soft-deleted object. In either case, if a noncurrent object already exists with the same name, a live version can be written without issue." }, "softDeletedAfterTime": { "type": "string", "description": "Restores only the objects that were soft-deleted after this time.", "format": "date-time" }, "softDeletedBeforeTime": { "type": "string", "description": "Restores only the objects that were soft-deleted before this time.", "format": "date-time" }, "matchGlobs": { "type": "array", "description": "Restores only the objects matching any of the specified glob(s). If this parameter is not specified, all objects will be restored within the specified time range.", "items": { "type": "string" } }, "copySourceAcl": { "type": "boolean", "description": "If true, copies the source object's ACL; otherwise, uses the bucket's default object ACL. The default is false." } } } }, "resources": { "anywhereCaches": { "methods": { "insert": { "id": "storage.anywhereCaches.insert", "path": "b/{bucket}/anywhereCaches", "httpMethod": "POST", "description": "Creates an Anywhere Cache instance.", "parameters": { "bucket": { "type": "string", "description": "Name of the parent bucket.", "required": true, "location": "path" } }, "parameterOrder": [ "bucket" ], "request": { "$ref": "AnywhereCache" }, "response": { "$ref": "GoogleLongrunningOperation" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_write" ] }, "update": { "id": "storage.anywhereCaches.update", "path": "b/{bucket}/anywhereCaches/{anywhereCacheId}", "httpMethod": "PATCH", "description": "Updates the config(ttl and admissionPolicy) of an Anywhere Cache instance.", "parameters": { "bucket": { "type": "string", "description": "Name of the parent bucket.", "required": true, "location": "path" }, "anywhereCacheId": { "type": "string", "description": "The ID of requested Anywhere Cache instance.", "required": true, "location": "path" } }, "parameterOrder": [ "bucket", "anywhereCacheId" ], "request": { "$ref": "AnywhereCache" }, "response": { "$ref": "GoogleLongrunningOperation" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_write" ] }, "get": { "id": "storage.anywhereCaches.get", "path": "b/{bucket}/anywhereCaches/{anywhereCacheId}", "httpMethod": "GET", "description": "Returns the metadata of an Anywhere Cache instance.", "parameters": { "bucket": { "type": "string", "description": "Name of the parent bucket.", "required": true, "location": "path" }, "anywhereCacheId": { "type": "string", "description": "The ID of requested Anywhere Cache instance.", "required": true, "location": "path" } }, "parameterOrder": [ "bucket", "anywhereCacheId" ], "response": { "$ref": "AnywhereCache" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/cloud-platform.read-only", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_only", "https://www.googleapis.com/auth/devstorage.read_write" ] }, "list": { "id": "storage.anywhereCaches.list", "path": "b/{bucket}/anywhereCaches", "httpMethod": "GET", "description": "Returns a list of Anywhere Cache instances of the bucket matching the criteria.", "parameters": { "bucket": { "type": "string", "description": "Name of the parent bucket.", "required": true, "location": "path" }, "pageSize": { "type": "integer", "description": "Maximum number of items to return in a single page of responses. Maximum 1000.", "format": "int32", "minimum": "0", "location": "query" }, "pageToken": { "type": "string", "description": "A previously-returned page token representing part of the larger set of results to view.", "location": "query" } }, "parameterOrder": [ "bucket" ], "response": { "$ref": "AnywhereCaches" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/cloud-platform.read-only", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_only", "https://www.googleapis.com/auth/devstorage.read_write" ] }, "pause": { "id": "storage.anywhereCaches.pause", "path": "b/{bucket}/anywhereCaches/{anywhereCacheId}/pause", "httpMethod": "POST", "description": "Pauses an Anywhere Cache instance.", "parameters": { "bucket": { "type": "string", "description": "Name of the parent bucket.", "required": true, "location": "path" }, "anywhereCacheId": { "type": "string", "description": "The ID of requested Anywhere Cache instance.", "required": true, "location": "path" } }, "parameterOrder": [ "bucket", "anywhereCacheId" ], "response": { "$ref": "AnywhereCache" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_write" ] }, "resume": { "id": "storage.anywhereCaches.resume", "path": "b/{bucket}/anywhereCaches/{anywhereCacheId}/resume", "httpMethod": "POST", "description": "Resumes a paused or disabled Anywhere Cache instance.", "parameters": { "bucket": { "type": "string", "description": "Name of the parent bucket.", "required": true, "location": "path" }, "anywhereCacheId": { "type": "string", "description": "The ID of requested Anywhere Cache instance.", "required": true, "location": "path" } }, "parameterOrder": [ "bucket", "anywhereCacheId" ], "response": { "$ref": "AnywhereCache" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_write" ] }, "disable": { "id": "storage.anywhereCaches.disable", "path": "b/{bucket}/anywhereCaches/{anywhereCacheId}/disable", "httpMethod": "POST", "description": "Disables an Anywhere Cache instance.", "parameters": { "bucket": { "type": "string", "description": "Name of the parent bucket.", "required": true, "location": "path" }, "anywhereCacheId": { "type": "string", "description": "The ID of requested Anywhere Cache instance.", "required": true, "location": "path" } }, "parameterOrder": [ "bucket", "anywhereCacheId" ], "response": { "$ref": "AnywhereCache" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_write" ] } } }, "bucketAccessControls": { "methods": { "delete": { "id": "storage.bucketAccessControls.delete", "path": "b/{bucket}/acl/{entity}", "httpMethod": "DELETE", "description": "Permanently deletes the ACL entry for the specified entity on the specified bucket.", "parameters": { "bucket": { "type": "string", "description": "Name of a bucket.", "required": true, "location": "path" }, "entity": { "type": "string", "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", "required": true, "location": "path" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "bucket", "entity" ], "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control" ] }, "get": { "id": "storage.bucketAccessControls.get", "path": "b/{bucket}/acl/{entity}", "httpMethod": "GET", "description": "Returns the ACL entry for the specified entity on the specified bucket.", "parameters": { "bucket": { "type": "string", "description": "Name of a bucket.", "required": true, "location": "path" }, "entity": { "type": "string", "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", "required": true, "location": "path" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "bucket", "entity" ], "response": { "$ref": "BucketAccessControl" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control" ] }, "insert": { "id": "storage.bucketAccessControls.insert", "path": "b/{bucket}/acl", "httpMethod": "POST", "description": "Creates a new ACL entry on the specified bucket.", "parameters": { "bucket": { "type": "string", "description": "Name of a bucket.", "required": true, "location": "path" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "bucket" ], "request": { "$ref": "BucketAccessControl" }, "response": { "$ref": "BucketAccessControl" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control" ] }, "list": { "id": "storage.bucketAccessControls.list", "path": "b/{bucket}/acl", "httpMethod": "GET", "description": "Retrieves ACL entries on the specified bucket.", "parameters": { "bucket": { "type": "string", "description": "Name of a bucket.", "required": true, "location": "path" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "bucket" ], "response": { "$ref": "BucketAccessControls" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control" ] }, "patch": { "id": "storage.bucketAccessControls.patch", "path": "b/{bucket}/acl/{entity}", "httpMethod": "PATCH", "description": "Patches an ACL entry on the specified bucket.", "parameters": { "bucket": { "type": "string", "description": "Name of a bucket.", "required": true, "location": "path" }, "entity": { "type": "string", "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", "required": true, "location": "path" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "bucket", "entity" ], "request": { "$ref": "BucketAccessControl" }, "response": { "$ref": "BucketAccessControl" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control" ] }, "update": { "id": "storage.bucketAccessControls.update", "path": "b/{bucket}/acl/{entity}", "httpMethod": "PUT", "description": "Updates an ACL entry on the specified bucket.", "parameters": { "bucket": { "type": "string", "description": "Name of a bucket.", "required": true, "location": "path" }, "entity": { "type": "string", "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", "required": true, "location": "path" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "bucket", "entity" ], "request": { "$ref": "BucketAccessControl" }, "response": { "$ref": "BucketAccessControl" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control" ] } } }, "buckets": { "methods": { "delete": { "id": "storage.buckets.delete", "path": "b/{bucket}", "httpMethod": "DELETE", "description": "Permanently deletes an empty bucket.", "parameters": { "bucket": { "type": "string", "description": "Name of a bucket.", "required": true, "location": "path" }, "ifMetagenerationMatch": { "type": "string", "description": "If set, only deletes the bucket if its metageneration matches this value.", "format": "int64", "location": "query" }, "ifMetagenerationNotMatch": { "type": "string", "description": "If set, only deletes the bucket if its metageneration does not match this value.", "format": "int64", "location": "query" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "bucket" ], "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_write" ] }, "get": { "id": "storage.buckets.get", "path": "b/{bucket}", "httpMethod": "GET", "description": "Returns metadata for the specified bucket.", "parameters": { "bucket": { "type": "string", "description": "Name of a bucket.", "required": true, "location": "path" }, "generation": { "type": "string", "description": "If present, selects a specific soft-deleted version of this bucket instead of the live version. This parameter is required if softDeleted is set to true.", "format": "int64", "location": "query" }, "ifMetagenerationMatch": { "type": "string", "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration matches the given value.", "format": "int64", "location": "query" }, "ifMetagenerationNotMatch": { "type": "string", "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration does not match the given value.", "format": "int64", "location": "query" }, "projection": { "type": "string", "description": "Set of properties to return. Defaults to noAcl.", "enum": [ "full", "noAcl" ], "enumDescriptions": [ "Include all properties.", "Omit owner, acl and defaultObjectAcl properties." ], "location": "query" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" }, "softDeleted": { "type": "boolean", "description": "If true, returns the soft-deleted bucket. This parameter is required if generation is specified.", "location": "query" } }, "parameterOrder": [ "bucket" ], "response": { "$ref": "Bucket" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/cloud-platform.read-only", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_only", "https://www.googleapis.com/auth/devstorage.read_write" ] }, "getIamPolicy": { "id": "storage.buckets.getIamPolicy", "path": "b/{bucket}/iam", "httpMethod": "GET", "description": "Returns an IAM policy for the specified bucket.", "parameters": { "bucket": { "type": "string", "description": "Name of a bucket.", "required": true, "location": "path" }, "optionsRequestedPolicyVersion": { "type": "integer", "description": "The IAM policy format version to be returned. If the optionsRequestedPolicyVersion is for an older version that doesn't support part of the requested IAM policy, the request fails.", "format": "int32", "minimum": "1", "location": "query" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "bucket" ], "response": { "$ref": "Policy" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control" ] }, "insert": { "id": "storage.buckets.insert", "path": "b", "httpMethod": "POST", "description": "Creates a new bucket.", "parameters": { "predefinedAcl": { "type": "string", "description": "Apply a predefined set of access controls to this bucket.", "enum": [ "authenticatedRead", "private", "projectPrivate", "publicRead", "publicReadWrite" ], "enumDescriptions": [ "Project team owners get OWNER access, and allAuthenticatedUsers get READER access.", "Project team owners get OWNER access.", "Project team members get access according to their roles.", "Project team owners get OWNER access, and allUsers get READER access.", "Project team owners get OWNER access, and allUsers get WRITER access." ], "location": "query" }, "predefinedDefaultObjectAcl": { "type": "string", "description": "Apply a predefined set of default object access controls to this bucket.", "enum": [ "authenticatedRead", "bucketOwnerFullControl", "bucketOwnerRead", "private", "projectPrivate", "publicRead" ], "enumDescriptions": [ "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", "Object owner gets OWNER access, and project team owners get OWNER access.", "Object owner gets OWNER access, and project team owners get READER access.", "Object owner gets OWNER access.", "Object owner gets OWNER access, and project team members get access according to their roles.", "Object owner gets OWNER access, and allUsers get READER access." ], "location": "query" }, "project": { "type": "string", "description": "A valid API project identifier.", "required": true, "location": "query" }, "projection": { "type": "string", "description": "Set of properties to return. Defaults to noAcl, unless the bucket resource specifies acl or defaultObjectAcl properties, when it defaults to full.", "enum": [ "full", "noAcl" ], "enumDescriptions": [ "Include all properties.", "Omit owner, acl and defaultObjectAcl properties." ], "location": "query" }, "userProject": { "type": "string", "description": "The project to be billed for this request.", "location": "query" }, "enableObjectRetention": { "type": "boolean", "description": "When set to true, object retention is enabled for this bucket.", "default": "false", "location": "query" } }, "parameterOrder": [ "project" ], "request": { "$ref": "Bucket" }, "response": { "$ref": "Bucket" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_write" ] }, "list": { "id": "storage.buckets.list", "path": "b", "httpMethod": "GET", "description": "Retrieves a list of buckets for a given project.", "parameters": { "maxResults": { "type": "integer", "description": "Maximum number of buckets to return in a single response. The service will use this parameter or 1,000 items, whichever is smaller.", "default": "1000", "format": "uint32", "minimum": "0", "location": "query" }, "pageToken": { "type": "string", "description": "A previously-returned page token representing part of the larger set of results to view.", "location": "query" }, "prefix": { "type": "string", "description": "Filter results to buckets whose names begin with this prefix.", "location": "query" }, "project": { "type": "string", "description": "A valid API project identifier.", "required": true, "location": "query" }, "projection": { "type": "string", "description": "Set of properties to return. Defaults to noAcl.", "enum": [ "full", "noAcl" ], "enumDescriptions": [ "Include all properties.", "Omit owner, acl and defaultObjectAcl properties." ], "location": "query" }, "userProject": { "type": "string", "description": "The project to be billed for this request.", "location": "query" }, "softDeleted": { "type": "boolean", "description": "If set to true, only soft-deleted bucket versions are listed as distinct results in order of bucket name and generation number. The default value is false.", "location": "query" }, "returnPartialSuccess": { "type": "boolean", "description": "If true, returns a partial list of buckets. The `unreachable` field will contain buckets that were not reachable.", "location": "query" } }, "parameterOrder": [ "project" ], "response": { "$ref": "Buckets" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/cloud-platform.read-only", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_only", "https://www.googleapis.com/auth/devstorage.read_write" ] }, "lockRetentionPolicy": { "id": "storage.buckets.lockRetentionPolicy", "path": "b/{bucket}/lockRetentionPolicy", "httpMethod": "POST", "description": "Locks retention policy on a bucket.", "parameters": { "bucket": { "type": "string", "description": "Name of a bucket.", "required": true, "location": "path" }, "ifMetagenerationMatch": { "type": "string", "description": "Makes the operation conditional on whether bucket's current metageneration matches the given value.", "required": true, "format": "int64", "location": "query" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "bucket", "ifMetagenerationMatch" ], "response": { "$ref": "Bucket" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_write" ] }, "patch": { "id": "storage.buckets.patch", "path": "b/{bucket}", "httpMethod": "PATCH", "description": "Patches a bucket. Changes to the bucket will be readable immediately after writing, but configuration changes may take time to propagate.", "parameters": { "bucket": { "type": "string", "description": "Name of a bucket.", "required": true, "location": "path" }, "ifMetagenerationMatch": { "type": "string", "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration matches the given value.", "format": "int64", "location": "query" }, "ifMetagenerationNotMatch": { "type": "string", "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration does not match the given value.", "format": "int64", "location": "query" }, "predefinedAcl": { "type": "string", "description": "Apply a predefined set of access controls to this bucket.", "enum": [ "authenticatedRead", "private", "projectPrivate", "publicRead", "publicReadWrite" ], "enumDescriptions": [ "Project team owners get OWNER access, and allAuthenticatedUsers get READER access.", "Project team owners get OWNER access.", "Project team members get access according to their roles.", "Project team owners get OWNER access, and allUsers get READER access.", "Project team owners get OWNER access, and allUsers get WRITER access." ], "location": "query" }, "predefinedDefaultObjectAcl": { "type": "string", "description": "Apply a predefined set of default object access controls to this bucket.", "enum": [ "authenticatedRead", "bucketOwnerFullControl", "bucketOwnerRead", "private", "projectPrivate", "publicRead" ], "enumDescriptions": [ "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", "Object owner gets OWNER access, and project team owners get OWNER access.", "Object owner gets OWNER access, and project team owners get READER access.", "Object owner gets OWNER access.", "Object owner gets OWNER access, and project team members get access according to their roles.", "Object owner gets OWNER access, and allUsers get READER access." ], "location": "query" }, "projection": { "type": "string", "description": "Set of properties to return. Defaults to full.", "enum": [ "full", "noAcl" ], "enumDescriptions": [ "Include all properties.", "Omit owner, acl and defaultObjectAcl properties." ], "location": "query" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "bucket" ], "request": { "$ref": "Bucket" }, "response": { "$ref": "Bucket" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control" ] }, "setIamPolicy": { "id": "storage.buckets.setIamPolicy", "path": "b/{bucket}/iam", "httpMethod": "PUT", "description": "Updates an IAM policy for the specified bucket.", "parameters": { "bucket": { "type": "string", "description": "Name of a bucket.", "required": true, "location": "path" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "bucket" ], "request": { "$ref": "Policy" }, "response": { "$ref": "Policy" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control" ] }, "testIamPermissions": { "id": "storage.buckets.testIamPermissions", "path": "b/{bucket}/iam/testPermissions", "httpMethod": "GET", "description": "Tests a set of permissions on the given bucket to see which, if any, are held by the caller.", "parameters": { "bucket": { "type": "string", "description": "Name of a bucket.", "required": true, "location": "path" }, "permissions": { "type": "string", "description": "Permissions to test.", "required": true, "repeated": true, "location": "query" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "bucket", "permissions" ], "response": { "$ref": "TestIamPermissionsResponse" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/cloud-platform.read-only", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_only", "https://www.googleapis.com/auth/devstorage.read_write" ] }, "update": { "id": "storage.buckets.update", "path": "b/{bucket}", "httpMethod": "PUT", "description": "Updates a bucket. Changes to the bucket will be readable immediately after writing, but configuration changes may take time to propagate.", "parameters": { "bucket": { "type": "string", "description": "Name of a bucket.", "required": true, "location": "path" }, "ifMetagenerationMatch": { "type": "string", "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration matches the given value.", "format": "int64", "location": "query" }, "ifMetagenerationNotMatch": { "type": "string", "description": "Makes the return of the bucket metadata conditional on whether the bucket's current metageneration does not match the given value.", "format": "int64", "location": "query" }, "predefinedAcl": { "type": "string", "description": "Apply a predefined set of access controls to this bucket.", "enum": [ "authenticatedRead", "private", "projectPrivate", "publicRead", "publicReadWrite" ], "enumDescriptions": [ "Project team owners get OWNER access, and allAuthenticatedUsers get READER access.", "Project team owners get OWNER access.", "Project team members get access according to their roles.", "Project team owners get OWNER access, and allUsers get READER access.", "Project team owners get OWNER access, and allUsers get WRITER access." ], "location": "query" }, "predefinedDefaultObjectAcl": { "type": "string", "description": "Apply a predefined set of default object access controls to this bucket.", "enum": [ "authenticatedRead", "bucketOwnerFullControl", "bucketOwnerRead", "private", "projectPrivate", "publicRead" ], "enumDescriptions": [ "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", "Object owner gets OWNER access, and project team owners get OWNER access.", "Object owner gets OWNER access, and project team owners get READER access.", "Object owner gets OWNER access.", "Object owner gets OWNER access, and project team members get access according to their roles.", "Object owner gets OWNER access, and allUsers get READER access." ], "location": "query" }, "projection": { "type": "string", "description": "Set of properties to return. Defaults to full.", "enum": [ "full", "noAcl" ], "enumDescriptions": [ "Include all properties.", "Omit owner, acl and defaultObjectAcl properties." ], "location": "query" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "bucket" ], "request": { "$ref": "Bucket" }, "response": { "$ref": "Bucket" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control" ] }, "restore": { "id": "storage.buckets.restore", "path": "b/{bucket}/restore", "httpMethod": "POST", "description": "Restores a soft-deleted bucket.", "parameters": { "bucket": { "type": "string", "description": "Name of the bucket to be restored.", "required": true, "location": "path" }, "generation": { "type": "string", "description": "The specific version of the bucket to be restored.", "required": true, "format": "int64", "location": "query" }, "projection": { "type": "string", "description": "Set of properties to return. Defaults to full.", "enum": [ "full", "noAcl" ], "enumDescriptions": [ "Include all properties.", "Omit the owner, acl property." ], "location": "query" } }, "parameterOrder": [ "bucket", "generation" ], "response": { "$ref": "Bucket" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control" ] } } }, "operations": { "methods": { "cancel": { "description": "Starts asynchronous cancellation on a long-running operation. The server makes a best effort to cancel the operation, but success is not guaranteed.", "path": "b/{bucket}/operations/{operationId}/cancel", "httpMethod": "POST", "id": "storage.buckets.operations.cancel", "parameterOrder": [ "bucket", "operationId" ], "parameters": { "bucket": { "description": "The parent bucket of the operation resource.", "location": "path", "required": true, "type": "string" }, "operationId": { "description": "The ID of the operation resource.", "location": "path", "required": true, "type": "string" } }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_write" ] }, "get": { "description": "Gets the latest state of a long-running operation.", "path": "b/{bucket}/operations/{operationId}", "httpMethod": "GET", "id": "storage.buckets.operations.get", "parameterOrder": [ "bucket", "operationId" ], "parameters": { "bucket": { "description": "The parent bucket of the operation resource.", "location": "path", "required": true, "type": "string" }, "operationId": { "description": "The ID of the operation resource.", "location": "path", "required": true, "type": "string" } }, "response": { "$ref": "GoogleLongrunningOperation" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/cloud-platform.read-only", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_only", "https://www.googleapis.com/auth/devstorage.read_write" ] }, "list": { "description": "Lists operations that match the specified filter in the request.", "path": "b/{bucket}/operations", "httpMethod": "GET", "id": "storage.buckets.operations.list", "parameterOrder": [ "bucket" ], "parameters": { "filter": { "description": "A filter to narrow down results to a preferred subset. The filtering language is documented in more detail in [AIP-160](https://google.aip.dev/160).", "location": "query", "type": "string" }, "bucket": { "description": "Name of the bucket in which to look for operations.", "location": "path", "required": true, "type": "string" }, "pageSize": { "description": "Maximum number of items to return in a single page of responses. Fewer total results may be returned than requested. The service uses this parameter or 100 items, whichever is smaller.", "minimum": "0", "format": "int32", "location": "query", "type": "integer" }, "pageToken": { "description": "A previously-returned page token representing part of the larger set of results to view.", "location": "query", "type": "string" } }, "response": { "$ref": "GoogleLongrunningListOperationsResponse" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/cloud-platform.read-only", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_only", "https://www.googleapis.com/auth/devstorage.read_write" ] } } }, "channels": { "methods": { "stop": { "id": "storage.channels.stop", "path": "channels/stop", "httpMethod": "POST", "description": "Stop watching resources through this channel", "request": { "$ref": "Channel", "parameterName": "resource" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/cloud-platform.read-only", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_only", "https://www.googleapis.com/auth/devstorage.read_write" ] } } }, "defaultObjectAccessControls": { "methods": { "delete": { "id": "storage.defaultObjectAccessControls.delete", "path": "b/{bucket}/defaultObjectAcl/{entity}", "httpMethod": "DELETE", "description": "Permanently deletes the default object ACL entry for the specified entity on the specified bucket.", "parameters": { "bucket": { "type": "string", "description": "Name of a bucket.", "required": true, "location": "path" }, "entity": { "type": "string", "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", "required": true, "location": "path" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "bucket", "entity" ], "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control" ] }, "get": { "id": "storage.defaultObjectAccessControls.get", "path": "b/{bucket}/defaultObjectAcl/{entity}", "httpMethod": "GET", "description": "Returns the default object ACL entry for the specified entity on the specified bucket.", "parameters": { "bucket": { "type": "string", "description": "Name of a bucket.", "required": true, "location": "path" }, "entity": { "type": "string", "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", "required": true, "location": "path" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "bucket", "entity" ], "response": { "$ref": "ObjectAccessControl" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control" ] }, "insert": { "id": "storage.defaultObjectAccessControls.insert", "path": "b/{bucket}/defaultObjectAcl", "httpMethod": "POST", "description": "Creates a new default object ACL entry on the specified bucket.", "parameters": { "bucket": { "type": "string", "description": "Name of a bucket.", "required": true, "location": "path" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "bucket" ], "request": { "$ref": "ObjectAccessControl" }, "response": { "$ref": "ObjectAccessControl" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control" ] }, "list": { "id": "storage.defaultObjectAccessControls.list", "path": "b/{bucket}/defaultObjectAcl", "httpMethod": "GET", "description": "Retrieves default object ACL entries on the specified bucket.", "parameters": { "bucket": { "type": "string", "description": "Name of a bucket.", "required": true, "location": "path" }, "ifMetagenerationMatch": { "type": "string", "description": "If present, only return default ACL listing if the bucket's current metageneration matches this value.", "format": "int64", "location": "query" }, "ifMetagenerationNotMatch": { "type": "string", "description": "If present, only return default ACL listing if the bucket's current metageneration does not match the given value.", "format": "int64", "location": "query" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "bucket" ], "response": { "$ref": "ObjectAccessControls" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control" ] }, "patch": { "id": "storage.defaultObjectAccessControls.patch", "path": "b/{bucket}/defaultObjectAcl/{entity}", "httpMethod": "PATCH", "description": "Patches a default object ACL entry on the specified bucket.", "parameters": { "bucket": { "type": "string", "description": "Name of a bucket.", "required": true, "location": "path" }, "entity": { "type": "string", "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", "required": true, "location": "path" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "bucket", "entity" ], "request": { "$ref": "ObjectAccessControl" }, "response": { "$ref": "ObjectAccessControl" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control" ] }, "update": { "id": "storage.defaultObjectAccessControls.update", "path": "b/{bucket}/defaultObjectAcl/{entity}", "httpMethod": "PUT", "description": "Updates a default object ACL entry on the specified bucket.", "parameters": { "bucket": { "type": "string", "description": "Name of a bucket.", "required": true, "location": "path" }, "entity": { "type": "string", "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", "required": true, "location": "path" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "bucket", "entity" ], "request": { "$ref": "ObjectAccessControl" }, "response": { "$ref": "ObjectAccessControl" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control" ] } } }, "folders": { "methods": { "delete": { "id": "storage.folders.delete", "path": "b/{bucket}/folders/{folder}", "httpMethod": "DELETE", "description": "Permanently deletes a folder. Only applicable to buckets with hierarchical namespace enabled.", "parameters": { "bucket": { "type": "string", "description": "Name of the bucket in which the folder resides.", "required": true, "location": "path" }, "folder": { "type": "string", "description": "Name of a folder.", "required": true, "location": "path" }, "ifMetagenerationMatch": { "type": "string", "description": "If set, only deletes the folder if its metageneration matches this value.", "format": "int64", "location": "query" }, "ifMetagenerationNotMatch": { "type": "string", "description": "If set, only deletes the folder if its metageneration does not match this value.", "format": "int64", "location": "query" } }, "parameterOrder": [ "bucket", "folder" ], "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_write" ] }, "get": { "id": "storage.folders.get", "path": "b/{bucket}/folders/{folder}", "httpMethod": "GET", "description": "Returns metadata for the specified folder. Only applicable to buckets with hierarchical namespace enabled.", "parameters": { "bucket": { "type": "string", "description": "Name of the bucket in which the folder resides.", "required": true, "location": "path" }, "folder": { "type": "string", "description": "Name of a folder.", "required": true, "location": "path" }, "ifMetagenerationMatch": { "type": "string", "description": "Makes the return of the folder metadata conditional on whether the folder's current metageneration matches the given value.", "format": "int64", "location": "query" }, "ifMetagenerationNotMatch": { "type": "string", "description": "Makes the return of the folder metadata conditional on whether the folder's current metageneration does not match the given value.", "format": "int64", "location": "query" } }, "parameterOrder": [ "bucket", "folder" ], "response": { "$ref": "Folder" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/cloud-platform.read-only", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_only", "https://www.googleapis.com/auth/devstorage.read_write" ] }, "insert": { "id": "storage.folders.insert", "path": "b/{bucket}/folders", "httpMethod": "POST", "description": "Creates a new folder. Only applicable to buckets with hierarchical namespace enabled.", "parameters": { "bucket": { "type": "string", "description": "Name of the bucket in which the folder resides.", "required": true, "location": "path" }, "recursive": { "type": "boolean", "description": "If true, any parent folder which doesn\u2019t exist will be created automatically.", "location": "query" } }, "parameterOrder": [ "bucket" ], "request": { "$ref": "Folder" }, "response": { "$ref": "Folder" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_write" ] }, "list": { "id": "storage.folders.list", "path": "b/{bucket}/folders", "httpMethod": "GET", "description": "Retrieves a list of folders matching the criteria. Only applicable to buckets with hierarchical namespace enabled.", "parameters": { "bucket": { "type": "string", "description": "Name of the bucket in which to look for folders.", "required": true, "location": "path" }, "delimiter": { "type": "string", "description": "Returns results in a directory-like mode. The only supported value is '/'. If set, items will only contain folders that either exactly match the prefix, or are one level below the prefix.", "location": "query" }, "endOffset": { "type": "string", "description": "Filter results to folders whose names are lexicographically before endOffset. If startOffset is also set, the folders listed will have names between startOffset (inclusive) and endOffset (exclusive).", "location": "query" }, "pageSize": { "type": "integer", "description": "Maximum number of items to return in a single page of responses.", "format": "int32", "minimum": "0", "location": "query" }, "pageToken": { "type": "string", "description": "A previously-returned page token representing part of the larger set of results to view.", "location": "query" }, "prefix": { "type": "string", "description": "Filter results to folders whose paths begin with this prefix. If set, the value must either be an empty string or end with a '/'.", "location": "query" }, "startOffset": { "type": "string", "description": "Filter results to folders whose names are lexicographically equal to or after startOffset. If endOffset is also set, the folders listed will have names between startOffset (inclusive) and endOffset (exclusive).", "location": "query" } }, "parameterOrder": [ "bucket" ], "response": { "$ref": "Folders" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/cloud-platform.read-only", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_only", "https://www.googleapis.com/auth/devstorage.read_write" ] }, "rename": { "id": "storage.folders.rename", "path": "b/{bucket}/folders/{sourceFolder}/renameTo/folders/{destinationFolder}", "httpMethod": "POST", "description": "Renames a source folder to a destination folder. Only applicable to buckets with hierarchical namespace enabled.", "parameters": { "bucket": { "type": "string", "description": "Name of the bucket in which the folders are in.", "required": true, "location": "path" }, "destinationFolder": { "type": "string", "description": "Name of the destination folder.", "required": true, "location": "path" }, "ifSourceMetagenerationMatch": { "type": "string", "description": "Makes the operation conditional on whether the source object's current metageneration matches the given value.", "format": "int64", "location": "query" }, "ifSourceMetagenerationNotMatch": { "type": "string", "description": "Makes the operation conditional on whether the source object's current metageneration does not match the given value.", "format": "int64", "location": "query" }, "sourceFolder": { "type": "string", "description": "Name of the source folder.", "required": true, "location": "path" } }, "parameterOrder": [ "bucket", "sourceFolder", "destinationFolder" ], "response": { "$ref": "GoogleLongrunningOperation" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_write" ] } } }, "managedFolders": { "methods": { "delete": { "id": "storage.managedFolders.delete", "path": "b/{bucket}/managedFolders/{managedFolder}", "httpMethod": "DELETE", "description": "Permanently deletes a managed folder.", "parameters": { "bucket": { "type": "string", "description": "Name of the bucket containing the managed folder.", "required": true, "location": "path" }, "managedFolder": { "type": "string", "description": "The managed folder name/path.", "required": true, "location": "path" }, "ifMetagenerationMatch": { "type": "string", "description": "If set, only deletes the managed folder if its metageneration matches this value.", "format": "int64", "location": "query" }, "ifMetagenerationNotMatch": { "type": "string", "description": "If set, only deletes the managed folder if its metageneration does not match this value.", "format": "int64", "location": "query" }, "allowNonEmpty": { "type": "boolean", "description": "Allows the deletion of a managed folder even if it is not empty. A managed folder is empty if there are no objects or managed folders that it applies to. Callers must have storage.managedFolders.setIamPolicy permission.", "location": "query" } }, "parameterOrder": [ "bucket", "managedFolder" ], "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_write" ] }, "get": { "id": "storage.managedFolders.get", "path": "b/{bucket}/managedFolders/{managedFolder}", "httpMethod": "GET", "description": "Returns metadata of the specified managed folder.", "parameters": { "bucket": { "type": "string", "description": "Name of the bucket containing the managed folder.", "required": true, "location": "path" }, "managedFolder": { "type": "string", "description": "The managed folder name/path.", "required": true, "location": "path" }, "ifMetagenerationMatch": { "type": "string", "description": "Makes the return of the managed folder metadata conditional on whether the managed folder's current metageneration matches the given value.", "format": "int64", "location": "query" }, "ifMetagenerationNotMatch": { "type": "string", "description": "Makes the return of the managed folder metadata conditional on whether the managed folder's current metageneration does not match the given value.", "format": "int64", "location": "query" } }, "parameterOrder": [ "bucket", "managedFolder" ], "response": { "$ref": "ManagedFolder" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/cloud-platform.read-only", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_only", "https://www.googleapis.com/auth/devstorage.read_write" ] }, "getIamPolicy": { "id": "storage.managedFolders.getIamPolicy", "path": "b/{bucket}/managedFolders/{managedFolder}/iam", "httpMethod": "GET", "description": "Returns an IAM policy for the specified managed folder.", "parameters": { "bucket": { "type": "string", "description": "Name of the bucket containing the managed folder.", "required": true, "location": "path" }, "optionsRequestedPolicyVersion": { "type": "integer", "description": "The IAM policy format version to be returned. If the optionsRequestedPolicyVersion is for an older version that doesn't support part of the requested IAM policy, the request fails.", "format": "int32", "minimum": "1", "location": "query" }, "managedFolder": { "type": "string", "description": "The managed folder name/path.", "required": true, "location": "path" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "bucket", "managedFolder" ], "response": { "$ref": "Policy" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/cloud-platform.read-only", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_only", "https://www.googleapis.com/auth/devstorage.read_write" ] }, "insert": { "id": "storage.managedFolders.insert", "path": "b/{bucket}/managedFolders", "httpMethod": "POST", "description": "Creates a new managed folder.", "parameters": { "bucket": { "type": "string", "description": "Name of the bucket containing the managed folder.", "required": true, "location": "path" } }, "parameterOrder": [ "bucket" ], "request": { "$ref": "ManagedFolder" }, "response": { "$ref": "ManagedFolder" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_write" ] }, "list": { "id": "storage.managedFolders.list", "path": "b/{bucket}/managedFolders", "httpMethod": "GET", "description": "Lists managed folders in the given bucket.", "parameters": { "bucket": { "type": "string", "description": "Name of the bucket containing the managed folder.", "required": true, "location": "path" }, "pageSize": { "type": "integer", "description": "Maximum number of items to return in a single page of responses.", "format": "int32", "minimum": "0", "location": "query" }, "pageToken": { "type": "string", "description": "A previously-returned page token representing part of the larger set of results to view.", "location": "query" }, "prefix": { "type": "string", "description": "The managed folder name/path prefix to filter the output list of results.", "location": "query" } }, "parameterOrder": [ "bucket" ], "response": { "$ref": "ManagedFolders" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/cloud-platform.read-only", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_only", "https://www.googleapis.com/auth/devstorage.read_write" ] }, "setIamPolicy": { "id": "storage.managedFolders.setIamPolicy", "path": "b/{bucket}/managedFolders/{managedFolder}/iam", "httpMethod": "PUT", "description": "Updates an IAM policy for the specified managed folder.", "parameters": { "bucket": { "type": "string", "description": "Name of the bucket containing the managed folder.", "required": true, "location": "path" }, "managedFolder": { "type": "string", "description": "The managed folder name/path.", "required": true, "location": "path" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "bucket", "managedFolder" ], "request": { "$ref": "Policy" }, "response": { "$ref": "Policy" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control" ] }, "testIamPermissions": { "id": "storage.managedFolders.testIamPermissions", "path": "b/{bucket}/managedFolders/{managedFolder}/iam/testPermissions", "httpMethod": "GET", "description": "Tests a set of permissions on the given managed folder to see which, if any, are held by the caller.", "parameters": { "bucket": { "type": "string", "description": "Name of the bucket containing the managed folder.", "required": true, "location": "path" }, "managedFolder": { "type": "string", "description": "The managed folder name/path.", "required": true, "location": "path" }, "permissions": { "type": "string", "description": "Permissions to test.", "required": true, "repeated": true, "location": "query" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "bucket", "managedFolder", "permissions" ], "response": { "$ref": "TestIamPermissionsResponse" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/cloud-platform.read-only", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_only", "https://www.googleapis.com/auth/devstorage.read_write" ] } } }, "notifications": { "methods": { "delete": { "id": "storage.notifications.delete", "path": "b/{bucket}/notificationConfigs/{notification}", "httpMethod": "DELETE", "description": "Permanently deletes a notification subscription.", "parameters": { "bucket": { "type": "string", "description": "The parent bucket of the notification.", "required": true, "location": "path" }, "notification": { "type": "string", "description": "ID of the notification to delete.", "required": true, "location": "path" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "bucket", "notification" ], "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_write" ] }, "get": { "id": "storage.notifications.get", "path": "b/{bucket}/notificationConfigs/{notification}", "httpMethod": "GET", "description": "View a notification configuration.", "parameters": { "bucket": { "type": "string", "description": "The parent bucket of the notification.", "required": true, "location": "path" }, "notification": { "type": "string", "description": "Notification ID", "required": true, "location": "path" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "bucket", "notification" ], "response": { "$ref": "Notification" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/cloud-platform.read-only", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_only", "https://www.googleapis.com/auth/devstorage.read_write" ] }, "insert": { "id": "storage.notifications.insert", "path": "b/{bucket}/notificationConfigs", "httpMethod": "POST", "description": "Creates a notification subscription for a given bucket.", "parameters": { "bucket": { "type": "string", "description": "The parent bucket of the notification.", "required": true, "location": "path" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "bucket" ], "request": { "$ref": "Notification" }, "response": { "$ref": "Notification" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_write" ] }, "list": { "id": "storage.notifications.list", "path": "b/{bucket}/notificationConfigs", "httpMethod": "GET", "description": "Retrieves a list of notification subscriptions for a given bucket.", "parameters": { "bucket": { "type": "string", "description": "Name of a Google Cloud Storage bucket.", "required": true, "location": "path" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "bucket" ], "response": { "$ref": "Notifications" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/cloud-platform.read-only", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_only", "https://www.googleapis.com/auth/devstorage.read_write" ] } } }, "objectAccessControls": { "methods": { "delete": { "id": "storage.objectAccessControls.delete", "path": "b/{bucket}/o/{object}/acl/{entity}", "httpMethod": "DELETE", "description": "Permanently deletes the ACL entry for the specified entity on the specified object.", "parameters": { "bucket": { "type": "string", "description": "Name of a bucket.", "required": true, "location": "path" }, "entity": { "type": "string", "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", "required": true, "location": "path" }, "generation": { "type": "string", "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", "format": "int64", "location": "query" }, "object": { "type": "string", "description": "Name of the object. For information about how to URL encode object names to be path safe, see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding).", "required": true, "location": "path" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "bucket", "object", "entity" ], "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control" ] }, "get": { "id": "storage.objectAccessControls.get", "path": "b/{bucket}/o/{object}/acl/{entity}", "httpMethod": "GET", "description": "Returns the ACL entry for the specified entity on the specified object.", "parameters": { "bucket": { "type": "string", "description": "Name of a bucket.", "required": true, "location": "path" }, "entity": { "type": "string", "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", "required": true, "location": "path" }, "generation": { "type": "string", "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", "format": "int64", "location": "query" }, "object": { "type": "string", "description": "Name of the object. For information about how to URL encode object names to be path safe, see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding).", "required": true, "location": "path" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "bucket", "object", "entity" ], "response": { "$ref": "ObjectAccessControl" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control" ] }, "insert": { "id": "storage.objectAccessControls.insert", "path": "b/{bucket}/o/{object}/acl", "httpMethod": "POST", "description": "Creates a new ACL entry on the specified object.", "parameters": { "bucket": { "type": "string", "description": "Name of a bucket.", "required": true, "location": "path" }, "generation": { "type": "string", "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", "format": "int64", "location": "query" }, "object": { "type": "string", "description": "Name of the object. For information about how to URL encode object names to be path safe, see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding).", "required": true, "location": "path" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "bucket", "object" ], "request": { "$ref": "ObjectAccessControl" }, "response": { "$ref": "ObjectAccessControl" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control" ] }, "list": { "id": "storage.objectAccessControls.list", "path": "b/{bucket}/o/{object}/acl", "httpMethod": "GET", "description": "Retrieves ACL entries on the specified object.", "parameters": { "bucket": { "type": "string", "description": "Name of a bucket.", "required": true, "location": "path" }, "generation": { "type": "string", "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", "format": "int64", "location": "query" }, "object": { "type": "string", "description": "Name of the object. For information about how to URL encode object names to be path safe, see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding).", "required": true, "location": "path" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "bucket", "object" ], "response": { "$ref": "ObjectAccessControls" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control" ] }, "patch": { "id": "storage.objectAccessControls.patch", "path": "b/{bucket}/o/{object}/acl/{entity}", "httpMethod": "PATCH", "description": "Patches an ACL entry on the specified object.", "parameters": { "bucket": { "type": "string", "description": "Name of a bucket.", "required": true, "location": "path" }, "entity": { "type": "string", "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", "required": true, "location": "path" }, "generation": { "type": "string", "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", "format": "int64", "location": "query" }, "object": { "type": "string", "description": "Name of the object. For information about how to URL encode object names to be path safe, see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding).", "required": true, "location": "path" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "bucket", "object", "entity" ], "request": { "$ref": "ObjectAccessControl" }, "response": { "$ref": "ObjectAccessControl" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control" ] }, "update": { "id": "storage.objectAccessControls.update", "path": "b/{bucket}/o/{object}/acl/{entity}", "httpMethod": "PUT", "description": "Updates an ACL entry on the specified object.", "parameters": { "bucket": { "type": "string", "description": "Name of a bucket.", "required": true, "location": "path" }, "entity": { "type": "string", "description": "The entity holding the permission. Can be user-userId, user-emailAddress, group-groupId, group-emailAddress, allUsers, or allAuthenticatedUsers.", "required": true, "location": "path" }, "generation": { "type": "string", "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", "format": "int64", "location": "query" }, "object": { "type": "string", "description": "Name of the object. For information about how to URL encode object names to be path safe, see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding).", "required": true, "location": "path" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "bucket", "object", "entity" ], "request": { "$ref": "ObjectAccessControl" }, "response": { "$ref": "ObjectAccessControl" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control" ] } } }, "objects": { "methods": { "compose": { "id": "storage.objects.compose", "path": "b/{destinationBucket}/o/{destinationObject}/compose", "httpMethod": "POST", "description": "Concatenates a list of existing objects into a new object in the same bucket.", "parameters": { "destinationBucket": { "type": "string", "description": "Name of the bucket containing the source objects. The destination object is stored in this bucket.", "required": true, "location": "path" }, "destinationObject": { "type": "string", "description": "Name of the new object. For information about how to URL encode object names to be path safe, see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding).", "required": true, "location": "path" }, "destinationPredefinedAcl": { "type": "string", "description": "Apply a predefined set of access controls to the destination object.", "enum": [ "authenticatedRead", "bucketOwnerFullControl", "bucketOwnerRead", "private", "projectPrivate", "publicRead" ], "enumDescriptions": [ "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", "Object owner gets OWNER access, and project team owners get OWNER access.", "Object owner gets OWNER access, and project team owners get READER access.", "Object owner gets OWNER access.", "Object owner gets OWNER access, and project team members get access according to their roles.", "Object owner gets OWNER access, and allUsers get READER access." ], "location": "query" }, "ifGenerationMatch": { "type": "string", "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", "format": "int64", "location": "query" }, "ifMetagenerationMatch": { "type": "string", "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", "format": "int64", "location": "query" }, "kmsKeyName": { "type": "string", "description": "Resource name of the Cloud KMS key, of the form projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key, that will be used to encrypt the object. Overrides the object metadata's kms_key_name value, if any.", "location": "query" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "destinationBucket", "destinationObject" ], "request": { "$ref": "ComposeRequest" }, "response": { "$ref": "Object" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_write" ] }, "copy": { "id": "storage.objects.copy", "path": "b/{sourceBucket}/o/{sourceObject}/copyTo/b/{destinationBucket}/o/{destinationObject}", "httpMethod": "POST", "description": "Copies a source object to a destination object. Optionally overrides metadata.", "parameters": { "destinationBucket": { "type": "string", "description": "Name of the bucket in which to store the new object. Overrides the provided object metadata's bucket value, if any.For information about how to URL encode object names to be path safe, see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding).", "required": true, "location": "path" }, "destinationKmsKeyName": { "type": "string", "description": "Resource name of the Cloud KMS key, of the form projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key, that will be used to encrypt the object. Overrides the object metadata's kms_key_name value, if any.", "location": "query" }, "destinationObject": { "type": "string", "description": "Name of the new object. Required when the object metadata is not otherwise provided. Overrides the object metadata's name value, if any.", "required": true, "location": "path" }, "destinationPredefinedAcl": { "type": "string", "description": "Apply a predefined set of access controls to the destination object.", "enum": [ "authenticatedRead", "bucketOwnerFullControl", "bucketOwnerRead", "private", "projectPrivate", "publicRead" ], "enumDescriptions": [ "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", "Object owner gets OWNER access, and project team owners get OWNER access.", "Object owner gets OWNER access, and project team owners get READER access.", "Object owner gets OWNER access.", "Object owner gets OWNER access, and project team members get access according to their roles.", "Object owner gets OWNER access, and allUsers get READER access." ], "location": "query" }, "ifGenerationMatch": { "type": "string", "description": "Makes the operation conditional on whether the destination object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", "format": "int64", "location": "query" }, "ifGenerationNotMatch": { "type": "string", "description": "Makes the operation conditional on whether the destination object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", "format": "int64", "location": "query" }, "ifMetagenerationMatch": { "type": "string", "description": "Makes the operation conditional on whether the destination object's current metageneration matches the given value.", "format": "int64", "location": "query" }, "ifMetagenerationNotMatch": { "type": "string", "description": "Makes the operation conditional on whether the destination object's current metageneration does not match the given value.", "format": "int64", "location": "query" }, "ifSourceGenerationMatch": { "type": "string", "description": "Makes the operation conditional on whether the source object's current generation matches the given value.", "format": "int64", "location": "query" }, "ifSourceGenerationNotMatch": { "type": "string", "description": "Makes the operation conditional on whether the source object's current generation does not match the given value.", "format": "int64", "location": "query" }, "ifSourceMetagenerationMatch": { "type": "string", "description": "Makes the operation conditional on whether the source object's current metageneration matches the given value.", "format": "int64", "location": "query" }, "ifSourceMetagenerationNotMatch": { "type": "string", "description": "Makes the operation conditional on whether the source object's current metageneration does not match the given value.", "format": "int64", "location": "query" }, "projection": { "type": "string", "description": "Set of properties to return. Defaults to noAcl, unless the object resource specifies the acl property, when it defaults to full.", "enum": [ "full", "noAcl" ], "enumDescriptions": [ "Include all properties.", "Omit the owner, acl property." ], "location": "query" }, "sourceBucket": { "type": "string", "description": "Name of the bucket in which to find the source object.", "required": true, "location": "path" }, "sourceGeneration": { "type": "string", "description": "If present, selects a specific revision of the source object (as opposed to the latest version, the default).", "format": "int64", "location": "query" }, "sourceObject": { "type": "string", "description": "Name of the source object. For information about how to URL encode object names to be path safe, see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding).", "required": true, "location": "path" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "sourceBucket", "sourceObject", "destinationBucket", "destinationObject" ], "request": { "$ref": "Object" }, "response": { "$ref": "Object" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_write" ] }, "delete": { "id": "storage.objects.delete", "path": "b/{bucket}/o/{object}", "httpMethod": "DELETE", "description": "Deletes an object and its metadata. Deletions are permanent if versioning is not enabled for the bucket, or if the generation parameter is used.", "parameters": { "bucket": { "type": "string", "description": "Name of the bucket in which the object resides.", "required": true, "location": "path" }, "generation": { "type": "string", "description": "If present, permanently deletes a specific revision of this object (as opposed to the latest version, the default).", "format": "int64", "location": "query" }, "ifGenerationMatch": { "type": "string", "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", "format": "int64", "location": "query" }, "ifGenerationNotMatch": { "type": "string", "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", "format": "int64", "location": "query" }, "ifMetagenerationMatch": { "type": "string", "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", "format": "int64", "location": "query" }, "ifMetagenerationNotMatch": { "type": "string", "description": "Makes the operation conditional on whether the object's current metageneration does not match the given value.", "format": "int64", "location": "query" }, "object": { "type": "string", "description": "Name of the object. For information about how to URL encode object names to be path safe, see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding).", "required": true, "location": "path" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "bucket", "object" ], "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_write" ] }, "get": { "id": "storage.objects.get", "path": "b/{bucket}/o/{object}", "httpMethod": "GET", "description": "Retrieves an object or its metadata.", "parameters": { "bucket": { "type": "string", "description": "Name of the bucket in which the object resides.", "required": true, "location": "path" }, "generation": { "type": "string", "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", "format": "int64", "location": "query" }, "ifGenerationMatch": { "type": "string", "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", "format": "int64", "location": "query" }, "ifGenerationNotMatch": { "type": "string", "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", "format": "int64", "location": "query" }, "ifMetagenerationMatch": { "type": "string", "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", "format": "int64", "location": "query" }, "ifMetagenerationNotMatch": { "type": "string", "description": "Makes the operation conditional on whether the object's current metageneration does not match the given value.", "format": "int64", "location": "query" }, "object": { "type": "string", "description": "Name of the object. For information about how to URL encode object names to be path safe, see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding).", "required": true, "location": "path" }, "projection": { "type": "string", "description": "Set of properties to return. Defaults to noAcl.", "enum": [ "full", "noAcl" ], "enumDescriptions": [ "Include all properties.", "Omit the owner, acl property." ], "location": "query" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" }, "softDeleted": { "type": "boolean", "description": "If true, only soft-deleted object versions will be listed. The default is false. For more information, see Soft Delete.", "location": "query" }, "restoreToken": { "type": "string", "description": "If you have enabled hierarchical namespace on your bucket and are working with soft-deleted objects, the restoreToken, a universally unique identifier (UUID), along with the object's name and generation value, uniquely identifies the object.", "location": "query" } }, "parameterOrder": [ "bucket", "object" ], "response": { "$ref": "Object" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/cloud-platform.read-only", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_only", "https://www.googleapis.com/auth/devstorage.read_write" ], "supportsMediaDownload": true, "useMediaDownloadService": true }, "getIamPolicy": { "id": "storage.objects.getIamPolicy", "path": "b/{bucket}/o/{object}/iam", "httpMethod": "GET", "description": "Returns an IAM policy for the specified object.", "parameters": { "bucket": { "type": "string", "description": "Name of the bucket in which the object resides.", "required": true, "location": "path" }, "generation": { "type": "string", "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", "format": "int64", "location": "query" }, "object": { "type": "string", "description": "Name of the object. For information about how to URL encode object names to be path safe, see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding).", "required": true, "location": "path" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "bucket", "object" ], "response": { "$ref": "Policy" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/cloud-platform.read-only", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_only", "https://www.googleapis.com/auth/devstorage.read_write" ] }, "insert": { "id": "storage.objects.insert", "path": "b/{bucket}/o", "httpMethod": "POST", "description": "Stores a new object and metadata.", "parameters": { "bucket": { "type": "string", "description": "Name of the bucket in which to store the new object. Overrides the provided object metadata's bucket value, if any.", "required": true, "location": "path" }, "contentEncoding": { "type": "string", "description": "If set, sets the contentEncoding property of the final object to this value. Setting this parameter is equivalent to setting the contentEncoding metadata property. This can be useful when uploading an object with uploadType=media to indicate the encoding of the content being uploaded.", "location": "query" }, "ifGenerationMatch": { "type": "string", "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", "format": "int64", "location": "query" }, "ifGenerationNotMatch": { "type": "string", "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", "format": "int64", "location": "query" }, "ifMetagenerationMatch": { "type": "string", "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", "format": "int64", "location": "query" }, "ifMetagenerationNotMatch": { "type": "string", "description": "Makes the operation conditional on whether the object's current metageneration does not match the given value.", "format": "int64", "location": "query" }, "kmsKeyName": { "type": "string", "description": "Resource name of the Cloud KMS key, of the form projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key, that will be used to encrypt the object. Overrides the object metadata's kms_key_name value, if any.", "location": "query" }, "name": { "type": "string", "description": "Name of the object. Required when the object metadata is not otherwise provided. Overrides the object metadata's name value, if any. For information about how to URL encode object names to be path safe, see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding).", "location": "query" }, "predefinedAcl": { "type": "string", "description": "Apply a predefined set of access controls to this object.", "enum": [ "authenticatedRead", "bucketOwnerFullControl", "bucketOwnerRead", "private", "projectPrivate", "publicRead" ], "enumDescriptions": [ "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", "Object owner gets OWNER access, and project team owners get OWNER access.", "Object owner gets OWNER access, and project team owners get READER access.", "Object owner gets OWNER access.", "Object owner gets OWNER access, and project team members get access according to their roles.", "Object owner gets OWNER access, and allUsers get READER access." ], "location": "query" }, "projection": { "type": "string", "description": "Set of properties to return. Defaults to noAcl, unless the object resource specifies the acl property, when it defaults to full.", "enum": [ "full", "noAcl" ], "enumDescriptions": [ "Include all properties.", "Omit the owner, acl property." ], "location": "query" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "bucket" ], "request": { "$ref": "Object" }, "response": { "$ref": "Object" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_write" ], "supportsMediaUpload": true, "mediaUpload": { "accept": [ "*/*" ], "protocols": { "simple": { "multipart": true, "path": "/upload/storage/v1/b/{bucket}/o" }, "resumable": { "multipart": true, "path": "/resumable/upload/storage/v1/b/{bucket}/o" } } } }, "list": { "id": "storage.objects.list", "path": "b/{bucket}/o", "httpMethod": "GET", "description": "Retrieves a list of objects matching the criteria.", "parameters": { "bucket": { "type": "string", "description": "Name of the bucket in which to look for objects.", "required": true, "location": "path" }, "delimiter": { "type": "string", "description": "Returns results in a directory-like mode. items will contain only objects whose names, aside from the prefix, do not contain delimiter. Objects whose names, aside from the prefix, contain delimiter will have their name, truncated after the delimiter, returned in prefixes. Duplicate prefixes are omitted.", "location": "query" }, "endOffset": { "type": "string", "description": "Filter results to objects whose names are lexicographically before endOffset. If startOffset is also set, the objects listed will have names between startOffset (inclusive) and endOffset (exclusive).", "location": "query" }, "includeTrailingDelimiter": { "type": "boolean", "description": "If true, objects that end in exactly one instance of delimiter will have their metadata included in items in addition to prefixes.", "location": "query" }, "maxResults": { "type": "integer", "description": "Maximum number of items plus prefixes to return in a single page of responses. As duplicate prefixes are omitted, fewer total results may be returned than requested. The service will use this parameter or 1,000 items, whichever is smaller.", "default": "1000", "format": "uint32", "minimum": "0", "location": "query" }, "pageToken": { "type": "string", "description": "A previously-returned page token representing part of the larger set of results to view.", "location": "query" }, "prefix": { "type": "string", "description": "Filter results to objects whose names begin with this prefix.", "location": "query" }, "projection": { "type": "string", "description": "Set of properties to return. Defaults to noAcl.", "enum": [ "full", "noAcl" ], "enumDescriptions": [ "Include all properties.", "Omit the owner, acl property." ], "location": "query" }, "startOffset": { "type": "string", "description": "Filter results to objects whose names are lexicographically equal to or after startOffset. If endOffset is also set, the objects listed will have names between startOffset (inclusive) and endOffset (exclusive).", "location": "query" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" }, "versions": { "type": "boolean", "description": "If true, lists all versions of an object as distinct results. The default is false. For more information, see Object Versioning.", "location": "query" }, "matchGlob": { "type": "string", "description": "Filter results to objects and prefixes that match this glob pattern.", "location": "query" }, "softDeleted": { "type": "boolean", "description": "If true, only soft-deleted object versions will be listed. The default is false. For more information, see Soft Delete.", "location": "query" }, "includeFoldersAsPrefixes": { "type": "boolean", "description": "Only applicable if delimiter is set to '/'. If true, will also include folders and managed folders (besides objects) in the returned prefixes.", "location": "query" } }, "parameterOrder": [ "bucket" ], "response": { "$ref": "Objects" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/cloud-platform.read-only", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_only", "https://www.googleapis.com/auth/devstorage.read_write" ], "supportsSubscription": true }, "patch": { "id": "storage.objects.patch", "path": "b/{bucket}/o/{object}", "httpMethod": "PATCH", "description": "Patches an object's metadata.", "parameters": { "bucket": { "type": "string", "description": "Name of the bucket in which the object resides.", "required": true, "location": "path" }, "generation": { "type": "string", "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", "format": "int64", "location": "query" }, "ifGenerationMatch": { "type": "string", "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", "format": "int64", "location": "query" }, "ifGenerationNotMatch": { "type": "string", "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", "format": "int64", "location": "query" }, "ifMetagenerationMatch": { "type": "string", "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", "format": "int64", "location": "query" }, "ifMetagenerationNotMatch": { "type": "string", "description": "Makes the operation conditional on whether the object's current metageneration does not match the given value.", "format": "int64", "location": "query" }, "overrideUnlockedRetention": { "type": "boolean", "description": "Must be true to remove the retention configuration, reduce its unlocked retention period, or change its mode from unlocked to locked.", "location": "query" }, "object": { "type": "string", "description": "Name of the object. For information about how to URL encode object names to be path safe, see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding).", "required": true, "location": "path" }, "predefinedAcl": { "type": "string", "description": "Apply a predefined set of access controls to this object.", "enum": [ "authenticatedRead", "bucketOwnerFullControl", "bucketOwnerRead", "private", "projectPrivate", "publicRead" ], "enumDescriptions": [ "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", "Object owner gets OWNER access, and project team owners get OWNER access.", "Object owner gets OWNER access, and project team owners get READER access.", "Object owner gets OWNER access.", "Object owner gets OWNER access, and project team members get access according to their roles.", "Object owner gets OWNER access, and allUsers get READER access." ], "location": "query" }, "projection": { "type": "string", "description": "Set of properties to return. Defaults to full.", "enum": [ "full", "noAcl" ], "enumDescriptions": [ "Include all properties.", "Omit the owner, acl property." ], "location": "query" }, "userProject": { "type": "string", "description": "The project to be billed for this request, for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "bucket", "object" ], "request": { "$ref": "Object" }, "response": { "$ref": "Object" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control" ] }, "move": { "id": "storage.objects.move", "path": "b/{bucket}/o/{sourceObject}/moveTo/o/{destinationObject}", "httpMethod": "POST", "description": "Moves a source object to a destination object. Optionally overrides metadata.", "parameters": { "bucket": { "type": "string", "description": "Name of the bucket in which to find the source object.", "required": true, "location": "path" }, "sourceObject": { "type": "string", "description": "Name of the source object. For information about how to URL encode object names to be path safe, see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding).", "required": true, "location": "path" }, "destinationObject": { "type": "string", "description": "Name of the new object. Required when the object metadata is not otherwise provided. Overrides the object metadata's name value, if any. For information about how to URL encode object names to be path safe, see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding).", "required": true, "location": "path" }, "ifGenerationMatch": { "type": "string", "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", "format": "int64", "location": "query" }, "ifGenerationNotMatch": { "type": "string", "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", "format": "int64", "location": "query" }, "ifMetagenerationMatch": { "type": "string", "description": "Makes the operation conditional on whether the destination object's current metageneration matches the given value.", "format": "int64", "location": "query" }, "ifMetagenerationNotMatch": { "type": "string", "description": "Makes the operation conditional on whether the destination object's current metageneration does not match the given value.", "format": "int64", "location": "query" }, "ifSourceGenerationMatch": { "type": "string", "description": "Makes the operation conditional on whether the source object's current generation matches the given value.", "format": "int64", "location": "query" }, "ifSourceGenerationNotMatch": { "type": "string", "description": "Makes the operation conditional on whether the source object's current generation does not match the given value.", "format": "int64", "location": "query" }, "ifSourceMetagenerationMatch": { "type": "string", "description": "Makes the operation conditional on whether the source object's current metageneration matches the given value.", "format": "int64", "location": "query" }, "ifSourceMetagenerationNotMatch": { "type": "string", "description": "Makes the operation conditional on whether the source object's current metageneration does not match the given value.", "format": "int64", "location": "query" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "bucket", "sourceObject", "destinationObject" ], "request": { "$ref": "Object" }, "response": { "$ref": "Object" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_write" ] }, "rewrite": { "id": "storage.objects.rewrite", "path": "b/{sourceBucket}/o/{sourceObject}/rewriteTo/b/{destinationBucket}/o/{destinationObject}", "httpMethod": "POST", "description": "Rewrites a source object to a destination object. Optionally overrides metadata.", "parameters": { "destinationBucket": { "type": "string", "description": "Name of the bucket in which to store the new object. Overrides the provided object metadata's bucket value, if any.", "required": true, "location": "path" }, "destinationKmsKeyName": { "type": "string", "description": "Resource name of the Cloud KMS key, of the form projects/my-project/locations/global/keyRings/my-kr/cryptoKeys/my-key, that will be used to encrypt the object. Overrides the object metadata's kms_key_name value, if any.", "location": "query" }, "destinationObject": { "type": "string", "description": "Name of the new object. Required when the object metadata is not otherwise provided. Overrides the object metadata's name value, if any. For information about how to URL encode object names to be path safe, see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding).", "required": true, "location": "path" }, "destinationPredefinedAcl": { "type": "string", "description": "Apply a predefined set of access controls to the destination object.", "enum": [ "authenticatedRead", "bucketOwnerFullControl", "bucketOwnerRead", "private", "projectPrivate", "publicRead" ], "enumDescriptions": [ "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", "Object owner gets OWNER access, and project team owners get OWNER access.", "Object owner gets OWNER access, and project team owners get READER access.", "Object owner gets OWNER access.", "Object owner gets OWNER access, and project team members get access according to their roles.", "Object owner gets OWNER access, and allUsers get READER access." ], "location": "query" }, "ifGenerationMatch": { "type": "string", "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", "format": "int64", "location": "query" }, "ifGenerationNotMatch": { "type": "string", "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", "format": "int64", "location": "query" }, "ifMetagenerationMatch": { "type": "string", "description": "Makes the operation conditional on whether the destination object's current metageneration matches the given value.", "format": "int64", "location": "query" }, "ifMetagenerationNotMatch": { "type": "string", "description": "Makes the operation conditional on whether the destination object's current metageneration does not match the given value.", "format": "int64", "location": "query" }, "ifSourceGenerationMatch": { "type": "string", "description": "Makes the operation conditional on whether the source object's current generation matches the given value.", "format": "int64", "location": "query" }, "ifSourceGenerationNotMatch": { "type": "string", "description": "Makes the operation conditional on whether the source object's current generation does not match the given value.", "format": "int64", "location": "query" }, "ifSourceMetagenerationMatch": { "type": "string", "description": "Makes the operation conditional on whether the source object's current metageneration matches the given value.", "format": "int64", "location": "query" }, "ifSourceMetagenerationNotMatch": { "type": "string", "description": "Makes the operation conditional on whether the source object's current metageneration does not match the given value.", "format": "int64", "location": "query" }, "maxBytesRewrittenPerCall": { "type": "string", "description": "The maximum number of bytes that will be rewritten per rewrite request. Most callers shouldn't need to specify this parameter - it is primarily in place to support testing. If specified the value must be an integral multiple of 1 MiB (1048576). Also, this only applies to requests where the source and destination span locations and/or storage classes. Finally, this value must not change across rewrite calls else you'll get an error that the rewriteToken is invalid.", "format": "int64", "location": "query" }, "projection": { "type": "string", "description": "Set of properties to return. Defaults to noAcl, unless the object resource specifies the acl property, when it defaults to full.", "enum": [ "full", "noAcl" ], "enumDescriptions": [ "Include all properties.", "Omit the owner, acl property." ], "location": "query" }, "rewriteToken": { "type": "string", "description": "Include this field (from the previous rewrite response) on each rewrite request after the first one, until the rewrite response 'done' flag is true. Calls that provide a rewriteToken can omit all other request fields, but if included those fields must match the values provided in the first rewrite request.", "location": "query" }, "sourceBucket": { "type": "string", "description": "Name of the bucket in which to find the source object.", "required": true, "location": "path" }, "sourceGeneration": { "type": "string", "description": "If present, selects a specific revision of the source object (as opposed to the latest version, the default).", "format": "int64", "location": "query" }, "sourceObject": { "type": "string", "description": "Name of the source object. For information about how to URL encode object names to be path safe, see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding).", "required": true, "location": "path" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "sourceBucket", "sourceObject", "destinationBucket", "destinationObject" ], "request": { "$ref": "Object" }, "response": { "$ref": "RewriteResponse" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_write" ] }, "setIamPolicy": { "id": "storage.objects.setIamPolicy", "path": "b/{bucket}/o/{object}/iam", "httpMethod": "PUT", "description": "Updates an IAM policy for the specified object.", "parameters": { "bucket": { "type": "string", "description": "Name of the bucket in which the object resides.", "required": true, "location": "path" }, "generation": { "type": "string", "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", "format": "int64", "location": "query" }, "object": { "type": "string", "description": "Name of the object. For information about how to URL encode object names to be path safe, see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding).", "required": true, "location": "path" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "bucket", "object" ], "request": { "$ref": "Policy" }, "response": { "$ref": "Policy" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_write" ] }, "testIamPermissions": { "id": "storage.objects.testIamPermissions", "path": "b/{bucket}/o/{object}/iam/testPermissions", "httpMethod": "GET", "description": "Tests a set of permissions on the given object to see which, if any, are held by the caller.", "parameters": { "bucket": { "type": "string", "description": "Name of the bucket in which the object resides.", "required": true, "location": "path" }, "generation": { "type": "string", "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", "format": "int64", "location": "query" }, "object": { "type": "string", "description": "Name of the object. For information about how to URL encode object names to be path safe, see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding).", "required": true, "location": "path" }, "permissions": { "type": "string", "description": "Permissions to test.", "required": true, "repeated": true, "location": "query" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "bucket", "object", "permissions" ], "response": { "$ref": "TestIamPermissionsResponse" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/cloud-platform.read-only", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_only", "https://www.googleapis.com/auth/devstorage.read_write" ] }, "update": { "id": "storage.objects.update", "path": "b/{bucket}/o/{object}", "httpMethod": "PUT", "description": "Updates an object's metadata.", "parameters": { "bucket": { "type": "string", "description": "Name of the bucket in which the object resides.", "required": true, "location": "path" }, "generation": { "type": "string", "description": "If present, selects a specific revision of this object (as opposed to the latest version, the default).", "format": "int64", "location": "query" }, "ifGenerationMatch": { "type": "string", "description": "Makes the operation conditional on whether the object's current generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", "format": "int64", "location": "query" }, "ifGenerationNotMatch": { "type": "string", "description": "Makes the operation conditional on whether the object's current generation does not match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", "format": "int64", "location": "query" }, "ifMetagenerationMatch": { "type": "string", "description": "Makes the operation conditional on whether the object's current metageneration matches the given value.", "format": "int64", "location": "query" }, "ifMetagenerationNotMatch": { "type": "string", "description": "Makes the operation conditional on whether the object's current metageneration does not match the given value.", "format": "int64", "location": "query" }, "overrideUnlockedRetention": { "type": "boolean", "description": "Must be true to remove the retention configuration, reduce its unlocked retention period, or change its mode from unlocked to locked.", "location": "query" }, "object": { "type": "string", "description": "Name of the object. For information about how to URL encode object names to be path safe, see [Encoding URI Path Parts](https://cloud.google.com/storage/docs/request-endpoints#encoding).", "required": true, "location": "path" }, "predefinedAcl": { "type": "string", "description": "Apply a predefined set of access controls to this object.", "enum": [ "authenticatedRead", "bucketOwnerFullControl", "bucketOwnerRead", "private", "projectPrivate", "publicRead" ], "enumDescriptions": [ "Object owner gets OWNER access, and allAuthenticatedUsers get READER access.", "Object owner gets OWNER access, and project team owners get OWNER access.", "Object owner gets OWNER access, and project team owners get READER access.", "Object owner gets OWNER access.", "Object owner gets OWNER access, and project team members get access according to their roles.", "Object owner gets OWNER access, and allUsers get READER access." ], "location": "query" }, "projection": { "type": "string", "description": "Set of properties to return. Defaults to full.", "enum": [ "full", "noAcl" ], "enumDescriptions": [ "Include all properties.", "Omit the owner, acl property." ], "location": "query" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" } }, "parameterOrder": [ "bucket", "object" ], "request": { "$ref": "Object" }, "response": { "$ref": "Object" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control" ] }, "watchAll": { "id": "storage.objects.watchAll", "path": "b/{bucket}/o/watch", "httpMethod": "POST", "description": "Watch for changes on all objects in a bucket.", "parameters": { "bucket": { "type": "string", "description": "Name of the bucket in which to look for objects.", "required": true, "location": "path" }, "delimiter": { "type": "string", "description": "Returns results in a directory-like mode. items will contain only objects whose names, aside from the prefix, do not contain delimiter. Objects whose names, aside from the prefix, contain delimiter will have their name, truncated after the delimiter, returned in prefixes. Duplicate prefixes are omitted.", "location": "query" }, "endOffset": { "type": "string", "description": "Filter results to objects whose names are lexicographically before endOffset. If startOffset is also set, the objects listed will have names between startOffset (inclusive) and endOffset (exclusive).", "location": "query" }, "includeTrailingDelimiter": { "type": "boolean", "description": "If true, objects that end in exactly one instance of delimiter will have their metadata included in items in addition to prefixes.", "location": "query" }, "maxResults": { "type": "integer", "description": "Maximum number of items plus prefixes to return in a single page of responses. As duplicate prefixes are omitted, fewer total results may be returned than requested. The service will use this parameter or 1,000 items, whichever is smaller.", "default": "1000", "format": "uint32", "minimum": "0", "location": "query" }, "pageToken": { "type": "string", "description": "A previously-returned page token representing part of the larger set of results to view.", "location": "query" }, "prefix": { "type": "string", "description": "Filter results to objects whose names begin with this prefix.", "location": "query" }, "projection": { "type": "string", "description": "Set of properties to return. Defaults to noAcl.", "enum": [ "full", "noAcl" ], "enumDescriptions": [ "Include all properties.", "Omit the owner, acl property." ], "location": "query" }, "startOffset": { "type": "string", "description": "Filter results to objects whose names are lexicographically equal to or after startOffset. If endOffset is also set, the objects listed will have names between startOffset (inclusive) and endOffset (exclusive).", "location": "query" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" }, "versions": { "type": "boolean", "description": "If true, lists all versions of an object as distinct results. The default is false. For more information, see Object Versioning.", "location": "query" } }, "parameterOrder": [ "bucket" ], "request": { "$ref": "Channel", "parameterName": "resource" }, "response": { "$ref": "Channel" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/cloud-platform.read-only", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_only", "https://www.googleapis.com/auth/devstorage.read_write" ], "supportsSubscription": true }, "restore": { "id": "storage.objects.restore", "path": "b/{bucket}/o/{object}/restore", "httpMethod": "POST", "description": "Restores a soft-deleted object.", "parameters": { "bucket": { "type": "string", "description": "Name of the bucket in which the object resides.", "required": true, "location": "path" }, "generation": { "type": "string", "description": "Selects a specific revision of this object.", "required": true, "format": "int64", "location": "query" }, "object": { "type": "string", "description": "Name of the object. For information about how to URL encode object names to be path safe, see Encoding URI Path Parts.", "required": true, "location": "path" }, "ifGenerationMatch": { "type": "string", "description": "Makes the operation conditional on whether the object's one live generation matches the given value. Setting to 0 makes the operation succeed only if there are no live versions of the object.", "format": "int64", "location": "query" }, "ifGenerationNotMatch": { "type": "string", "description": "Makes the operation conditional on whether none of the object's live generations match the given value. If no live object exists, the precondition fails. Setting to 0 makes the operation succeed only if there is a live version of the object.", "format": "int64", "location": "query" }, "ifMetagenerationMatch": { "type": "string", "description": "Makes the operation conditional on whether the object's one live metageneration matches the given value.", "format": "int64", "location": "query" }, "ifMetagenerationNotMatch": { "type": "string", "description": "Makes the operation conditional on whether none of the object's live metagenerations match the given value.", "format": "int64", "location": "query" }, "copySourceAcl": { "type": "boolean", "description": "If true, copies the source object's ACL; otherwise, uses the bucket's default object ACL. The default is false.", "location": "query" }, "projection": { "type": "string", "description": "Set of properties to return. Defaults to full.", "enum": [ "full", "noAcl" ], "enumDescriptions": [ "Include all properties.", "Omit the owner, acl property." ], "location": "query" }, "userProject": { "type": "string", "description": "The project to be billed for this request. Required for Requester Pays buckets.", "location": "query" }, "restoreToken": { "type": "string", "description": "The restoreToken is required to restore a soft-deleted object only if its name and generation value do not uniquely identify it.", "location": "query" } }, "parameterOrder": [ "bucket", "object", "generation" ], "response": { "$ref": "Object" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control" ] }, "bulkRestore": { "id": "storage.objects.bulkRestore", "path": "b/{bucket}/o/bulkRestore", "httpMethod": "POST", "description": "Initiates a long-running bulk restore operation on the specified bucket.", "parameters": { "bucket": { "type": "string", "description": "Name of the bucket in which the object resides.", "required": true, "location": "path" } }, "parameterOrder": [ "bucket" ], "request": { "$ref": "BulkRestoreObjectsRequest" }, "response": { "$ref": "GoogleLongrunningOperation" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_write" ] } } }, "projects": { "resources": { "hmacKeys": { "methods": { "create": { "id": "storage.projects.hmacKeys.create", "path": "projects/{projectId}/hmacKeys", "httpMethod": "POST", "description": "Creates a new HMAC key for the specified service account.", "parameters": { "projectId": { "type": "string", "description": "Project ID owning the service account.", "required": true, "location": "path" }, "serviceAccountEmail": { "type": "string", "description": "Email address of the service account.", "required": true, "location": "query" }, "userProject": { "type": "string", "description": "The project to be billed for this request.", "location": "query" } }, "parameterOrder": [ "projectId", "serviceAccountEmail" ], "response": { "$ref": "HmacKey" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control" ] }, "delete": { "id": "storage.projects.hmacKeys.delete", "path": "projects/{projectId}/hmacKeys/{accessId}", "httpMethod": "DELETE", "description": "Deletes an HMAC key.", "parameters": { "accessId": { "type": "string", "description": "Name of the HMAC key to be deleted.", "required": true, "location": "path" }, "projectId": { "type": "string", "description": "Project ID owning the requested key", "required": true, "location": "path" }, "userProject": { "type": "string", "description": "The project to be billed for this request.", "location": "query" } }, "parameterOrder": [ "projectId", "accessId" ], "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_write" ] }, "get": { "id": "storage.projects.hmacKeys.get", "path": "projects/{projectId}/hmacKeys/{accessId}", "httpMethod": "GET", "description": "Retrieves an HMAC key's metadata", "parameters": { "accessId": { "type": "string", "description": "Name of the HMAC key.", "required": true, "location": "path" }, "projectId": { "type": "string", "description": "Project ID owning the service account of the requested key.", "required": true, "location": "path" }, "userProject": { "type": "string", "description": "The project to be billed for this request.", "location": "query" } }, "parameterOrder": [ "projectId", "accessId" ], "response": { "$ref": "HmacKeyMetadata" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/cloud-platform.read-only", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_only" ] }, "list": { "id": "storage.projects.hmacKeys.list", "path": "projects/{projectId}/hmacKeys", "httpMethod": "GET", "description": "Retrieves a list of HMAC keys matching the criteria.", "parameters": { "maxResults": { "type": "integer", "description": "Maximum number of items to return in a single page of responses. The service uses this parameter or 250 items, whichever is smaller. The max number of items per page will also be limited by the number of distinct service accounts in the response. If the number of service accounts in a single response is too high, the page will truncated and a next page token will be returned.", "default": "250", "format": "uint32", "minimum": "0", "location": "query" }, "pageToken": { "type": "string", "description": "A previously-returned page token representing part of the larger set of results to view.", "location": "query" }, "projectId": { "type": "string", "description": "Name of the project in which to look for HMAC keys.", "required": true, "location": "path" }, "serviceAccountEmail": { "type": "string", "description": "If present, only keys for the given service account are returned.", "location": "query" }, "showDeletedKeys": { "type": "boolean", "description": "Whether or not to show keys in the DELETED state.", "location": "query" }, "userProject": { "type": "string", "description": "The project to be billed for this request.", "location": "query" } }, "parameterOrder": [ "projectId" ], "response": { "$ref": "HmacKeysMetadata" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/cloud-platform.read-only", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_only" ] }, "update": { "id": "storage.projects.hmacKeys.update", "path": "projects/{projectId}/hmacKeys/{accessId}", "httpMethod": "PUT", "description": "Updates the state of an HMAC key. See the HMAC Key resource descriptor for valid states.", "parameters": { "accessId": { "type": "string", "description": "Name of the HMAC key being updated.", "required": true, "location": "path" }, "projectId": { "type": "string", "description": "Project ID owning the service account of the updated key.", "required": true, "location": "path" }, "userProject": { "type": "string", "description": "The project to be billed for this request.", "location": "query" } }, "parameterOrder": [ "projectId", "accessId" ], "request": { "$ref": "HmacKeyMetadata" }, "response": { "$ref": "HmacKeyMetadata" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/devstorage.full_control" ] } } }, "serviceAccount": { "methods": { "get": { "id": "storage.projects.serviceAccount.get", "path": "projects/{projectId}/serviceAccount", "httpMethod": "GET", "description": "Get the email address of this project's Google Cloud Storage service account.", "parameters": { "projectId": { "type": "string", "description": "Project ID", "required": true, "location": "path" }, "userProject": { "type": "string", "description": "The project to be billed for this request.", "location": "query" } }, "parameterOrder": [ "projectId" ], "response": { "$ref": "ServiceAccount" }, "scopes": [ "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/cloud-platform.read-only", "https://www.googleapis.com/auth/devstorage.full_control", "https://www.googleapis.com/auth/devstorage.read_only", "https://www.googleapis.com/auth/devstorage.read_write" ] } } } } } }, "revision": "20240501", "etag": "\"3135313638313632393935373531333737363832\"" } ================================================ FILE: lib/Google/vendor/google/cloud-storage/src/CreatedHmacKey.php ================================================ createHmacKey($serviceAccountEmail); * ``` */ class CreatedHmacKey { /** * @var HmacKey */ private $hmacKey; /** * @var string */ private $secret; /** * @param HmacKey $hmacKey The HMAC Key object. * @param string $secret The HMAC key secret. */ public function __construct(HmacKey $hmacKey, $secret) { $this->hmacKey = $hmacKey; $this->secret = $secret; } /** * Get the HMAC key object. * * Example: * ``` * $key = $response->hmacKey(); * ``` * * @return HmacKey */ public function hmacKey() { return $this->hmacKey; } /** * Get the HMAC key secret. * * This value will never be returned from the API after first creation. Make * sure to record it for later use immediately upon key creation. * * Example: * ``` * $secret = $response->secret(); * ``` * * @return string */ public function secret() { return $this->secret; } } ================================================ FILE: lib/Google/vendor/google/cloud-storage/src/EncryptionTrait.php ================================================ 'x-goog-copy-source-encryption-algorithm', 'key' => 'x-goog-copy-source-encryption-key', 'keySHA256' => 'x-goog-copy-source-encryption-key-sha256' ]; /** * @var array */ private $encryptionHeaderNames = [ 'algorithm' => 'x-goog-encryption-algorithm', 'key' => 'x-goog-encryption-key', 'keySHA256' => 'x-goog-encryption-key-sha256' ]; /** * Formats options for customer-supplied encryption headers. * * @param array $options * @return array * @access private */ public function formatEncryptionHeaders(array $options) { $encryptionHeaders = []; $useCopySourceHeaders = $options['useCopySourceHeaders'] ?? false; $key = $options['encryptionKey'] ?? null; $keySHA256 = $options['encryptionKeySHA256'] ?? null; $destinationKey = $options['destinationEncryptionKey'] ?? null; $destinationKeySHA256 = $options['destinationEncryptionKeySHA256'] ?? null; unset($options['useCopySourceHeaders']); unset($options['encryptionKey']); unset($options['encryptionKeySHA256']); unset($options['destinationEncryptionKey']); unset($options['destinationEncryptionKeySHA256']); $encryptionHeaders = $this->buildHeaders($key, $keySHA256, $useCopySourceHeaders) + $this->buildHeaders($destinationKey, $destinationKeySHA256, false); if (!empty($encryptionHeaders)) { if (isset($options['restOptions']['headers'])) { $options['restOptions']['headers'] += $encryptionHeaders; } else { $options['restOptions']['headers'] = $encryptionHeaders; } } return $options; } /** * Builds out customer-supplied encryption headers. * * @param string $key * @param string $keySHA256 * @param bool $useCopySourceHeaders * @return array */ private function buildHeaders($key, $keySHA256, $useCopySourceHeaders) { if ($key) { $headerNames = $useCopySourceHeaders ? $this->copySourceEncryptionHeaderNames : $this->encryptionHeaderNames; if (!$keySHA256) { $decodedKey = base64_decode($key); $keySHA256 = base64_encode(hash('SHA256', $decodedKey, true)); } return [ $headerNames['algorithm'] => 'AES256', $headerNames['key'] => $key, $headerNames['keySHA256'] => $keySHA256 ]; } return []; } /** * Sign a string using a given private key. * * @deprecated Please use the {@see Google\Auth\SignBlobInterface::signBlob()} * and implementations for signing strings. * This method will be removed in a future release. * * @param string $privateKey The private key to use to sign the data. * @param string $data The data to sign. * @param bool $forceOpenssl If true, OpenSSL will be used regardless of * whether phpseclib is available. **Defaults to** `false`. * @return string The signature */ protected function signString($privateKey, $data, $forceOpenssl = false) { $signature = ''; if (class_exists(RSA3::class) && !$forceOpenssl) { $rsa = RSA3::loadPrivateKey($privateKey); $rsa = $rsa->withPadding(RSA3::SIGNATURE_PKCS1) ->withHash('sha256'); $signature = $rsa->sign($data); } elseif (class_exists(RSA2::class) && !$forceOpenssl) { $rsa = new RSA2(); $rsa->loadKey($privateKey); $rsa->setSignatureMode(RSA2::SIGNATURE_PKCS1); $rsa->setHash('sha256'); $signature = $rsa->sign($data); } elseif (extension_loaded('openssl')) { openssl_sign($data, $signature, $privateKey, 'sha256WithRSAEncryption'); } else { // @codeCoverageIgnoreStart throw new \RuntimeException('OpenSSL is not installed.'); } // @codeCoverageIgnoreEnd return $signature; } } ================================================ FILE: lib/Google/vendor/google/cloud-storage/src/HmacKey.php ================================================ hmacKey($accessId); * ``` */ class HmacKey { /** * @var ConnectionInterface * @internal */ private $connection; /** * @var string */ private $projectId; /** * @var string */ private $accessId; /** * @var array|null */ private $info; /** * @param ConnectionInterface $connection A connection to Cloud Storage. * This object is created by StorageClient, * and should not be instantiated outside of this client. * @param string $projectId The current project ID. * @param string $accessId The key identifier. * @param array|null $info The key metadata. */ public function __construct( ConnectionInterface $connection, $projectId, $accessId, array $info = [] ) { $this->connection = $connection; $this->projectId = $projectId; $this->accessId = $accessId; $this->info = $info; } /** * Get the HMAC Key Access ID. * * Example: * ``` * $accessId = $hmacKey->accessId(); * ``` * * @return string */ public function accessId() { return $this->accessId; } /** * Fetch the key metadata from Cloud Storage. * * Example: * ``` * $keyMetadata = $hmacKey->reload(); * ``` * * @param array $options { * Configuration Options * * @type string $userProject If set, this is the ID of the project which * will be billed for the request. **NOTE**: This option is * currently ignored by Cloud Storage. * } * @return array */ public function reload(array $options = []) { $this->info = $this->connection->getHmacKey([ 'projectId' => $this->projectId, 'accessId' => $this->accessId ] + $options); return $this->info; } /** * Get the HMAC Key Metadata. * * If the metadata is not already available, it will be requested from Cloud * Storage. * * Example: * ``` * $keyMetadata = $hmacKey->info(); * ``` * * @param array $options { * Configuration Options * * @type string $userProject If set, this is the ID of the project which * will be billed for the request. **NOTE**: This option is * currently ignored by Cloud Storage. * } * @return array */ public function info(array $options = []) { return $this->info ?: $this->reload($options); } /** * Update the HMAC Key state. * * Example: * ``` * $hmacKey->update('INACTIVE'); * ``` * * @param string $state The key state. Either `ACTIVE` or `INACTIVE`. * @param array $options { * Configuration Options * * @type string $userProject If set, this is the ID of the project which * will be billed for the request. **NOTE**: This option is * currently ignored by Cloud Storage. * } * @return array */ public function update($state, array $options = []) { $this->info = $this->connection->updateHmacKey([ 'accessId' => $this->accessId, 'projectId' => $this->projectId, 'state' => $state ] + $options); return $this->info; } /** * Delete the HMAC Key. * * Key state must be set to `INACTIVE` prior to deletion. See * {@see HmacKey::update()} for details. * * Example: * ``` * $hmacKey->delete(); * ``` * * @param array $options { * Configuration Options * * @type string $userProject If set, this is the ID of the project which * will be billed for the request. **NOTE**: This option is * currently ignored by Cloud Storage. * } * @return void */ public function delete(array $options = []) { $this->connection->deleteHmacKey([ 'accessId' => $this->accessId, 'projectId' => $this->projectId, ] + $options); } } ================================================ FILE: lib/Google/vendor/google/cloud-storage/src/Lifecycle.php ================================================ bucket('my-bucket'); * $lifecycle = $bucket->currentLifecycle(); * ``` * * ``` * // Or get a fresh builder by using the static factory method. * use Google\Cloud\Storage\Bucket; * * $lifecycle = Bucket::lifecycle(); * ``` * * @see https://cloud.google.com/storage/docs/lifecycle Object Lifecycle Management API Documentation */ class Lifecycle implements \ArrayAccess, \IteratorAggregate { /** * @var array */ private $lifecycle; /** * @param array $lifecycle [optional] A lifecycle configuration. Please see * [here](https://cloud.google.com/storage/docs/json_api/v1/buckets#lifecycle) * for the expected structure. */ public function __construct(array $lifecycle = []) { $this->lifecycle = $lifecycle; } /** * Adds an Object Lifecycle Delete Rule. * * Example: * ``` * $lifecycle->addDeleteRule([ * 'age' => 50, * 'isLive' => true * ]); * ``` * * @param array $condition { * The condition(s) where the rule will apply. * * @type int $age Age of an object (in days). This condition is * satisfied when an object reaches the specified age. * @type \DateTimeInterface|string $createdBefore This condition is * satisfied when an object is created before midnight of the * specified date in UTC. If a string is given, it must be a date * in RFC 3339 format with only the date part (for instance, * "2013-01-15"). * @type \DateTimeInterface|string $customTimeBefore This condition is * satisfied when the custom time on an object is before this date * in UTC. If a string is given, it must be a date in RFC 3339 * format with only the date part (for instance, "2013-01-15"). * @type int $daysSinceCustomTime Number of days elapsed since the * user-specified timestamp set on an object. The condition is * satisfied if the days elapsed is at least this number. If no * custom timestamp is specified on an object, the condition does * not apply. * @type int $daysSinceNoncurrentTime Number of days elapsed since the * noncurrent timestamp of an object. The condition is satisfied * if the days elapsed is at least this number. This condition is * relevant only for versioned objects. The value of the field * must be a nonnegative integer. If it's zero, the object version * will become eligible for Lifecycle action as soon as it becomes * noncurrent. * @type bool $isLive Relevant only for versioned objects. If the value * is `true`, this condition matches live objects; if the value is * `false`, it matches archived objects. * @type string[] $matchesStorageClass Objects having any of the storage * classes specified by this condition will be matched. Values * include `"MULTI_REGIONAL"`, `"REGIONAL"`, `"NEARLINE"`, * `"ARCHIVE"`, `"COLDLINE"`, `"STANDARD"`, and * `"DURABLE_REDUCED_AVAILABILITY"`. * @type \DateTimeInterface|string $noncurrentTimeBefore This condition * is satisfied when the noncurrent time on an object is before * this timestamp. This condition is relevant only for versioned * objects. If a string is given, it must be a date in RFC 3339 * format with only the date part (for instance, "2013-01-15"). * @type int $numNewerVersions Relevant only for versioned objects. If * the value is N, this condition is satisfied when there are at * least N versions (including the live version) newer than this * version of the object. * @type string[] $matchesPrefix Objects having names which start with * values specified by this condition will be matched. * @type string[] $matchesSuffix Objects having names which end with * values specified by this condition will be matched. * } * @return Lifecycle */ public function addDeleteRule(array $condition) { $this->lifecycle['rule'][] = [ 'action' => [ 'type' => 'Delete' ], 'condition' => $this->formatCondition($condition) ]; return $this; } /** * Adds a AbortIncompleteMultipartUpload lifecycle rule to Object Lifecycle. * * Example: * ``` * $lifecycle->addAbortIncompleteMultipartUploadRule([ * 'age' => 50, * 'isLive' => true * ]); * ``` * * @param array $condition { * The condition(s) where the rule will apply. * * @type int $age Age of an object (in days). This condition is * satisfied when an object reaches the specified age. * @type \DateTimeInterface|string $createdBefore This condition is * satisfied when an object is created before midnight of the * specified date in UTC. If a string is given, it must be a date * in RFC 3339 format with only the date part (for instance, * "2013-01-15"). * @type \DateTimeInterface|string $customTimeBefore This condition is * satisfied when the custom time on an object is before this date * in UTC. If a string is given, it must be a date in RFC 3339 * format with only the date part (for instance, "2013-01-15"). * @type int $daysSinceCustomTime Number of days elapsed since the * user-specified timestamp set on an object. The condition is * satisfied if the days elapsed is at least this number. If no * custom timestamp is specified on an object, the condition does * not apply. * @type int $daysSinceNoncurrentTime Number of days elapsed since the * noncurrent timestamp of an object. The condition is satisfied * if the days elapsed is at least this number. This condition is * relevant only for versioned objects. The value of the field * must be a nonnegative integer. If it's zero, the object version * will become eligible for Lifecycle action as soon as it becomes * noncurrent. * @type bool $isLive Relevant only for versioned objects. If the value * is `true`, this condition matches live objects; if the value is * `false`, it matches archived objects. * @type string[] $matchesStorageClass Objects having any of the storage * classes specified by this condition will be matched. Values * include `"MULTI_REGIONAL"`, `"REGIONAL"`, `"NEARLINE"`, * `"ARCHIVE"`, `"COLDLINE"`, `"STANDARD"`, and * `"DURABLE_REDUCED_AVAILABILITY"`. * @type \DateTimeInterface|string $noncurrentTimeBefore This condition * is satisfied when the noncurrent time on an object is before * this timestamp. This condition is relevant only for versioned * objects. If a string is given, it must be a date in RFC 3339 * format with only the date part (for instance, "2013-01-15"). * @type int $numNewerVersions Relevant only for versioned objects. If * the value is N, this condition is satisfied when there are at * least N versions (including the live version) newer than this * version of the object. * @type string[] $matchesPrefix Objects having names which start with * values specified by this condition will be matched. * @type string[] $matchesSuffix Objects having names which end with * values specified by this condition will be matched. * } * @return Lifecycle */ public function addAbortIncompleteMultipartUploadRule(array $condition) { $this->lifecycle['rule'][] = [ 'action' => [ 'type' => 'AbortIncompleteMultipartUpload' ], 'condition' => $this->formatCondition($condition) ]; return $this; } /** * Adds an Object Lifecycle Set Storage Class Rule. * * Example: * ``` * $lifecycle->addSetStorageClassRule('COLDLINE', [ * 'age' => 50, * 'isLive' => true * ]); * ``` * * ``` * // Using customTimeBefore rule with an object's custom time setting. * $lifecycle->addSetStorageClassRule('NEARLINE', [ * 'customTimeBefore' => (new \DateTime())->add( * \DateInterval::createFromDateString('+10 days') * ) * ]); * * $bucket->update(['lifecycle' => $lifecycle]); * * $object = $bucket->object($objectName); * $object->update([ * 'metadata' => [ * 'customTime' => '2020-08-17' * ] * ]); * ``` * * @param string $storageClass The target storage class. Values include * `"MULTI_REGIONAL"`, `"REGIONAL"`, `"NEARLINE"`, `"COLDLINE"`, * `"STANDARD"`, and `"DURABLE_REDUCED_AVAILABILITY"`. * @param array $condition { * The condition(s) where the rule will apply. * * @type int $age Age of an object (in days). This condition is * satisfied when an object reaches the specified age. * @type \DateTimeInterface|string $createdBefore This condition is * satisfied when an object is created before midnight of the * specified date in UTC. If a string is given, it must be a date * in RFC 3339 format with only the date part (for instance, * "2013-01-15"). * @type \DateTimeInterface|string $customTimeBefore This condition is * satisfied when the custom time on an object is before this date * in UTC. If a string is given, it must be a date in RFC 3339 * format with only the date part (for instance, "2013-01-15"). * @type int $daysSinceCustomTime Number of days elapsed since the * user-specified timestamp set on an object. The condition is * satisfied if the days elapsed is at least this number. If no * custom timestamp is specified on an object, the condition does * not apply. * @type int $daysSinceNoncurrentTime Number of days elapsed since the * noncurrent timestamp of an object. The condition is satisfied * if the days elapsed is at least this number. This condition is * relevant only for versioned objects. The value of the field * must be a nonnegative integer. If it's zero, the object version * will become eligible for Lifecycle action as soon as it becomes * noncurrent. * @type bool $isLive Relevant only for versioned objects. If the value * is `true`, this condition matches live objects; if the value is * `false`, it matches archived objects. * @type string[] $matchesStorageClass Objects having any of the storage * classes specified by this condition will be matched. Values * include `"MULTI_REGIONAL"`, `"REGIONAL"`, `"NEARLINE"`, * `"ARCHIVE"`, `"COLDLINE"`, `"STANDARD"`, and * `"DURABLE_REDUCED_AVAILABILITY"`. * @type \DateTimeInterface|string $noncurrentTimeBefore This condition * is satisfied when the noncurrent time on an object is before * this timestamp. This condition is relevant only for versioned * objects. If a string is given, it must be a date in RFC 3339 * format with only the date part (for instance, "2013-01-15"). * @type int $numNewerVersions Relevant only for versioned objects. If * the value is N, this condition is satisfied when there are at * least N versions (including the live version) newer than this * version of the object. * @type string[] $matchesPrefix Objects having names which start with * values specified by this condition will be matched. * @type string[] $matchesSuffix Objects having names which end with * values specified by this condition will be matched. * } * @return Lifecycle */ public function addSetStorageClassRule($storageClass, array $condition) { $this->lifecycle['rule'][] = [ 'action' => [ 'type' => 'SetStorageClass', 'storageClass' => $storageClass ], 'condition' => $this->formatCondition($condition) ]; return $this; } /** * Clear all Object Lifecycle rules or rules of a certain action type. * * Example: * ``` * // Remove all rules. * $lifecycle->clearRules(); * ``` * * ``` * // Remove all "Delete" based rules. * $lifecycle->clearRules('Delete'); * ``` * * ``` * // Clear any rules which have an age equal to 50. * $lifecycle->clearRules(function (array $rule) { * return $rule['condition']['age'] === 50 * ? false * : true; * }); * ``` * * @param string|callable $action [optional] If a string is provided, it * must be the name of the type of rule to remove (`SetStorageClass` * or `Delete`). All rules of this type will then be cleared. When * providing a callable you may define a custom route for how you * would like to remove rules. The provided callable will be run * through * [array_filter](http://php.net/manual/en/function.array-filter.php). * The callable's argument will be a single lifecycle rule as an * associative array. When returning true from the callable the rule * will be preserved, and if false it will be removed. * **Defaults to** `null`, clearing all assigned rules. * @return Lifecycle * @throws \InvalidArgumentException If a type other than a string or * callabe is provided. */ public function clearRules($action = null) { if (!$action) { $this->lifecycle = []; return $this; } if (!is_string($action) && !is_callable($action)) { throw new \InvalidArgumentException( sprintf( 'Expected either a string or callable, instead got \'%s\'.', gettype($action) ) ); } if (isset($this->lifecycle['rule'])) { if (is_string($action)) { $action = function ($rule) use ($action) { return $rule['action']['type'] !== $action; }; } $this->lifecycle['rule'] = array_filter( $this->lifecycle['rule'], $action ); if (!$this->lifecycle['rule']) { $this->lifecycle = []; } } return $this; } /** * @access private * @return \Generator */ #[\ReturnTypeWillChange] public function getIterator() { if (!isset($this->lifecycle['rule'])) { return; } foreach ($this->lifecycle['rule'] as $rule) { yield $rule; } } /** * @access private * @return array */ public function toArray() { return $this->lifecycle; } /** * @access private * @param string $offset * @param mixed $value */ #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { $this->lifecycle['rule'][$offset] = $value; } /** * @access private * @param string $offset * @return bool */ #[\ReturnTypeWillChange] public function offsetExists($offset) { return isset($this->lifecycle['rule'][$offset]); } /** * @access private * @param string $offset */ #[\ReturnTypeWillChange] public function offsetUnset($offset) { unset($this->lifecycle['rule'][$offset]); } /** * @access private * @param string $offset * @return mixed */ #[\ReturnTypeWillChange] public function offsetGet($offset) { return isset($this->lifecycle['rule'][$offset]) ? $this->lifecycle['rule'][$offset] : null; } /** * Apply condition-specific formatting rules (such as date formatting) to * conditions. * * @param array $condition * @return array */ private function formatCondition(array $condition) { $rfc339DateFields = [ 'createdBefore', 'customTimeBefore', 'noncurrentTimeBefore' ]; foreach ($rfc339DateFields as $field) { if (isset($condition[$field]) && $condition[$field] instanceof \DateTimeInterface) { $condition[$field] = $condition[$field]->format('Y-m-d'); } } return $condition; } } ================================================ FILE: lib/Google/vendor/google/cloud-storage/src/Notification.php ================================================ bucket('my-bucket'); * $notification = $bucket->notification('2482'); * ``` * * @see https://cloud.google.com/storage/docs/pubsub-notifications * @experimental The experimental flag means that while we believe this method * or class is ready for use, it may change before release in backwards- * incompatible ways. Please use with caution, and test thoroughly when * upgrading. */ class Notification { use ArrayTrait; /** * @var ConnectionInterface Represents a connection to Cloud Storage. * @internal */ private $connection; /** * @var array The notification's identity. */ private $identity; /** * @var array The notification's metadata. */ private $info; /** * @param ConnectionInterface $connection Represents a connection to Cloud * Storage. This object is created by StorageClient, * and should not be instantiated outside of this client. * @param string $id The notification's ID. * @param string $bucket The name of the bucket associated with this * notification. * @param array $info [optional] The notification's metadata. */ public function __construct(ConnectionInterface $connection, $id, $bucket, array $info = []) { $this->connection = $connection; $this->identity = [ 'bucket' => $bucket, 'notification' => $id, 'userProject' => $this->pluck('requesterProjectId', $info, false) ]; $this->info = $info; } /** * Check whether or not the notification exists. * * Example: * ``` * if ($notification->exists()) { * echo 'Notification exists!'; * } * ``` * @param array $options [optional] { * Configuration options. * } * @return bool */ public function exists(array $options = []) { try { $this->connection->getNotification($options + $this->identity + ['fields' => 'id']); } catch (NotFoundException $ex) { return false; } return true; } /** * Delete the notification. * * Example: * ``` * $notification->delete(); * ``` * * @codingStandardsIgnoreStart * @see https://cloud.google.com/storage/docs/json_api/v1/notifications/delete Notifications delete API documentation. * @codingStandardsIgnoreEnd * * @param array $options [optional] * @return void */ public function delete(array $options = []) { $this->connection->deleteNotification($options + $this->identity); } /** * Retrieves the notification's details. If no notification data is cached a * network request will be made to retrieve it. * * Example: * ``` * $info = $notification->info(); * echo $info['topic']; * ``` * * @see https://cloud.google.com/storage/docs/json_api/v1/notifications/get Notifications get API documentation. * * @param array $options [optional] * @return array */ public function info(array $options = []) { return $this->info ?: $this->reload($options); } /** * Triggers a network request to reload the notification's details. * * Example: * ``` * $notification->reload(); * $info = $notification->info(); * echo $info['topic']; * ``` * * @see https://cloud.google.com/storage/docs/json_api/v1/notifications/get Notifications get API documentation. * * @param array $options [optional] * @return array */ public function reload(array $options = []) { return $this->info = $this->connection->getNotification( $options + $this->identity ); } /** * Retrieves the notification's ID. * * Example: * ``` * echo $notification->id(); * ``` * * @return string */ public function id() { return $this->identity['notification']; } /** * Retrieves the notification's identity. * * Example: * ``` * echo $notification->identity()['bucket']; * ``` * * @return array */ public function identity() { return $this->identity; } } ================================================ FILE: lib/Google/vendor/google/cloud-storage/src/ObjectIterator.php ================================================ */ class ObjectIterator implements \Iterator { use ItemIteratorTrait; /** * Gets a list of prefixes of objects matching-but-not-listed up to and * including the requested delimiter. * * @return array */ public function prefixes() { return method_exists($this->pageIterator, 'prefixes') ? $this->pageIterator->prefixes() : []; } } ================================================ FILE: lib/Google/vendor/google/cloud-storage/src/ObjectPageIterator.php ================================================ prefixes; } /** * Get the current page. * * @return array|null */ #[\ReturnTypeWillChange] public function current() { if (!$this->page) { $this->page = $this->executeCall(); } if (isset($this->page['prefixes'])) { $this->updatePrefixes(); } return $this->get($this->itemsPath, $this->page); } /** * Add new prefixes to the list. * * @return void */ private function updatePrefixes() { foreach ($this->page['prefixes'] as $prefix) { if (!in_array($prefix, $this->prefixes)) { $this->prefixes[] = $prefix; } } } } ================================================ FILE: lib/Google/vendor/google/cloud-storage/src/ReadStream.php ================================================ stream = $stream; } /** * Return the full size of the buffer. If the underlying stream does * not report it's size, try to fetch the size from the Content-Length * response header. * * @return int The size of the stream. */ public function getSize(): ?int { return $this->stream->getSize() ?: $this->getSizeFromMetadata(); } /** * Attempt to fetch the size from the Content-Length response header. * If we cannot, return 0. * * @return int The Size of the stream */ private function getSizeFromMetadata(): int { foreach ($this->stream->getMetadata('wrapper_data') as $value) { if (substr($value, 0, 15) == 'Content-Length:') { return (int) substr($value, 16); } } return 0; } /** * Read bytes from the underlying buffer, retrying until we have read * enough bytes or we cannot read any more. We do this because the * internal C code for filling a buffer does not account for when * we try to read large chunks from a user-land stream that does not * return enough bytes. * * @param int $length The number of bytes to read. * @return string Read bytes from the underlying stream. */ public function read($length): string { $data = ''; do { $moreData = $this->stream->read($length); $data .= $moreData; $readLength = strlen($moreData); $length -= $readLength; } while ($length > 0 && $readLength > 0); return $data; } } ================================================ FILE: lib/Google/vendor/google/cloud-storage/src/SigningHelper.php ================================================ getSigningCredentials($connection, $options); $expires = $this->normalizeExpiration($expires); list($resource, $bucket) = $this->normalizeResource($resource); $options = $this->normalizeOptions($options); $headers = $this->normalizeHeaders($options['headers']); if ($options['virtualHostedStyle']) { $options['bucketBoundHostname'] = sprintf( '%s.storage.googleapis.com', $bucket ); } // Make sure disallowed headers are not included. $illegalHeaders = [ 'x-goog-encryption-key', 'x-goog-encryption-key-sha256' ]; if ($illegal = array_intersect_key(array_flip($illegalHeaders), $headers)) { throw new \InvalidArgumentException(sprintf( '%s %s not allowed in Signed URL headers.', implode(' and ', array_keys($illegal)), count($illegal) === 1 ? 'is' : 'are' )); } // Sort headers by name. ksort($headers); $toSign = [ $options['method'], $options['contentMd5'], $options['contentType'], $expires, ]; $signedHeaders = []; foreach ($headers as $name => $value) { $signedHeaders[] = $name . ':' . $value; } // Push the headers onto the end of the signing string. if ($signedHeaders) { $toSign = array_merge($toSign, $signedHeaders); } $toSign[] = $resource; $stringToSign = $this->createV2CanonicalRequest($toSign); // Use exponential backOff $signature = $this->retrySignBlob(fn () => $credentials->signBlob($stringToSign, [ 'forceOpenssl' => $options['forceOpenssl'] ])); // Start with user-provided query params and add required parameters. $params = $options['queryParams']; $params['GoogleAccessId'] = $credentials->getClientName(); $params['Expires'] = $expires; $params['Signature'] = $signature; // urlencode parameter values foreach ($params as &$value) { $value = rawurlencode($value ?? ''); } $params = $this->addCommonParams($generation, $params, $options); $queryString = $this->buildQueryString($params); $resource = $this->normalizeUriPath($options['bucketBoundHostname'], $resource); return 'https://' . $options['bucketBoundHostname'] . $resource . '?' . $queryString; } /** * Sign a storage URL using Google Signed URLs v4. * * @param ConnectionInterface $connection A connection to the Cloud Storage * API. This object is created by StorageClient, * and should not be instantiated outside of this client. * @param Timestamp|\DateTimeInterface|int $expires The signed URL * expiration. * @param string $resource The URI to the storage resource, preceded by a * leading slash. * @param int|null $generation The resource generation. * @param array $options Configuration options. See * {@see StorageObject::signedUrl()} for * details. * @return string * @throws \InvalidArgumentException * @throws \RuntimeException If required data could not be gathered from * credentials. * @throws \RuntimeException If OpenSSL signing is required by user input * and OpenSSL is not available. */ public function v4Sign(ConnectionInterface $connection, $expires, $resource, $generation, array $options) { list($credentials, $options) = $this->getSigningCredentials($connection, $options); $expires = $this->normalizeExpiration($expires); list($resource, $bucket) = $this->normalizeResource($resource); $options = $this->normalizeOptions($options); $time = $options['timestamp']; $requestTimestamp = $time->format(self::V4_TIMESTAMP_FORMAT); $requestDatestamp = $time->format(self::V4_DATESTAMP_FORMAT); $timeSeconds = $time->format('U'); $expireLimit = $timeSeconds + 604800; if ($expires > $expireLimit) { throw new \InvalidArgumentException( 'V4 Signed URLs may not have an expiration greater than seven days in the future.' ); } $clientEmail = $credentials->getClientName(); $credentialScope = sprintf('%s/auto/storage/goog4_request', $requestDatestamp); $credential = sprintf('%s/%s', $clientEmail, $credentialScope); if ($options['virtualHostedStyle']) { $options['bucketBoundHostname'] = sprintf( '%s.storage.googleapis.com', $bucket ); } // Add headers and query params based on provided options. $params = $options['queryParams']; $headers = $options['headers'] + [ 'host' => $options['bucketBoundHostname'] ]; if ($options['contentType']) { $headers['content-type'] = $options['contentType']; } if ($options['contentMd5']) { $headers['content-md5'] = $options['contentMd5']; } $params = $this->addCommonParams($generation, $params, $options); $headers = $this->normalizeHeaders($headers); // sort headers by name ksort($headers, SORT_NATURAL | SORT_FLAG_CASE); // Canonical headers are a list, newline separated, of keys and values, // comma separated. // Signed headers are a list of keys, separated by a semicolon. $canonicalHeaders = []; $signedHeaders = []; foreach ($headers as $key => $val) { $canonicalHeaders[] = sprintf('%s:%s', $key, $val); $signedHeaders[] = $key; } $canonicalHeaders = implode("\n", $canonicalHeaders) . "\n"; $signedHeaders = implode(';', $signedHeaders); // Add required query parameters. $params = [ 'X-Goog-Algorithm' => self::V4_ALGO_NAME, 'X-Goog-Credential' => $credential, 'X-Goog-Date' => $requestTimestamp, 'X-Goog-Expires' => $expires - $timeSeconds, 'X-Goog-SignedHeaders' => $signedHeaders, ] + $params; $paramNames = []; foreach ($params as $key => $val) { $paramNames[] = $key; } sort($paramNames, SORT_REGULAR); $sortedParams = []; foreach ($paramNames as $name) { $sortedParams[rawurlencode($name)] = rawurlencode($params[$name]); } $canonicalQueryString = $this->buildQueryString($sortedParams); $canonicalResource = $this->normalizeCanonicalRequestResource( $resource, $options['bucketBoundHostname'], $options['virtualHostedStyle'] ); $canonicalRequest = [ $options['method'], $canonicalResource, $canonicalQueryString, $canonicalHeaders, $signedHeaders, $this->getPayloadHash($headers) ]; $requestHash = $this->createV4CanonicalRequest($canonicalRequest); // Construct the string to sign. $stringToSign = implode("\n", [ self::V4_ALGO_NAME, $requestTimestamp, $credentialScope, $requestHash ]); $signature = bin2hex(base64_decode($this->retrySignBlob( fn () => $credentials->signBlob($stringToSign, [ 'forceOpenssl' => $options['forceOpenssl'] ]) ) ?? '')); // Construct the modified resource name. If a custom hostname is provided, // this will remove the bucket name from the resource. $resource = $this->normalizeUriPath($options['bucketBoundHostname'], $resource); $scheme = $this->chooseScheme( $options['scheme'], $options['bucketBoundHostname'], $options['virtualHostedStyle'] ); return sprintf( '%s://%s%s?%s&X-Goog-Signature=%s', $scheme, $options['bucketBoundHostname'], $resource, $canonicalQueryString, $signature ); } /** * Create an HTTP POST policy using v4 signing. * * @param ConnectionInterface $connection A Connection to Google Cloud Storage. * This object is created by StorageClient, * and should not be instantiated outside of this client. * @param Timestamp|\DateTimeInterface|int $expires The signed URL * expiration. * @param string $resource The URI to the storage resource, preceded by a * leading slash. * @param array $options Configuration options. See * {@see Bucket::generateSignedPostPolicyV4()} for details. * @return array An associative array, containing (string) `uri` and * (array) `fields` keys. */ public function v4PostPolicy( ConnectionInterface $connection, $expires, $resource, array $options = [] ) { list($credentials, $options) = $this->getSigningCredentials($connection, $options); $expires = $this->normalizeExpiration($expires); list($resource, $bucket, $object) = $this->normalizeResource($resource, false); $object = trim($object, '/'); $options = $this->normalizeOptions($options) + [ 'fields' => [], 'conditions' => [], 'successActionRedirect' => null, 'successActionStatus' => null ]; $time = $options['timestamp']; $requestTimestamp = $time->format(self::V4_TIMESTAMP_FORMAT); $requestDatestamp = $time->format(self::V4_DATESTAMP_FORMAT); $expiration = \DateTimeImmutable::createFromFormat('U', (string) $expires); $expirationTimestamp = str_replace( '+00:00', 'Z', $expiration->format(\DateTime::RFC3339) ); $clientEmail = $credentials->getClientName(); $credentialScope = sprintf('%s/auto/storage/goog4_request', $requestDatestamp); $credential = sprintf('%s/%s', $clientEmail, $credentialScope); if ($options['virtualHostedStyle']) { $options['bucketBoundHostname'] = sprintf( '%s.storage.googleapis.com', $bucket ); } $fields = array_merge($options['fields'], [ 'key' => $object, 'x-goog-algorithm' => self::V4_ALGO_NAME, 'x-goog-credential' => $credential, 'x-goog-date' => $requestTimestamp ]); $conditions = $options['conditions']; foreach ($options['fields'] as $key => $value) { $conditions[] = [$key => $value]; } foreach ($conditions as $key => $value) { $key = $key; $value = $value; $conditions[$key] = $value; } $conditions = array_merge($conditions, [ ['bucket' => $bucket], ['key' => $object], ['x-goog-date' => $requestTimestamp], ['x-goog-credential' => $credential], ['x-goog-algorithm' => self::V4_ALGO_NAME], ]); $policy = [ 'conditions' => $conditions, 'expiration' => $expirationTimestamp ]; $json = str_replace('\\\u', '\\u', json_encode($policy, JSON_UNESCAPED_SLASHES)); $stringToSign = base64_encode($json); $signature = bin2hex(base64_decode($credentials->signBlob($stringToSign, [ 'forceOpenssl' => $options['forceOpenssl'] ]))); $fields['x-goog-signature'] = $signature; $fields['policy'] = $stringToSign; // Construct the modified resource name. If a custom hostname is provided, // this will remove the bucket name from the resource. $resource = $this->normalizeUriPath($options['bucketBoundHostname'], '/' . $bucket, true); $scheme = $this->chooseScheme( $options['scheme'], $options['bucketBoundHostname'], $options['virtualHostedStyle'] ); return [ 'url' => sprintf( '%s://%s%s', $scheme, $options['bucketBoundHostname'], $resource ), 'fields' => $fields ]; } /** * Creates a canonical request hash for a V4 Signed URL. * * NOTE: While in most cases `PHP_EOL` is preferable to a system-specific * character, in this case `\n` is required. * * @param array $canonicalRequest The canonical request, with each element * representing a line in the request. * @return string */ private function createV4CanonicalRequest(array $canonicalRequest) { $canonicalRequestString = implode("\n", $canonicalRequest); return bin2hex(hash('sha256', $canonicalRequestString, true)); } /** * Creates a canonical request for a V2 Signed URL. * * NOTE: While in most cases `PHP_EOL` is preferable to a system-specific * character, in this case `\n` is required. * * @param array $canonicalRequest The canonical request, with each element * representing a line in the request. * @return string */ private function createV2CanonicalRequest(array $canonicalRequest) { return implode("\n", $canonicalRequest); } /** * Choose the correct URL scheme. * * @param string $scheme The scheme provided by the user or defaults. * @param string $bucketBoundHostname The bucketBoundHostname provided by the user or defaults. * @param bool $virtualHostedStyle Whether virtual host style is enabled. * @return string */ private function chooseScheme($scheme, $bucketBoundHostname, $virtualHostedStyle = false) { // bucketBoundHostname not used -- always https. if ($bucketBoundHostname === self::DEFAULT_DOWNLOAD_HOST) { return 'https'; } // virtualHostedStyle enabled -- always https. if ($virtualHostedStyle) { return 'https'; } // not virtual hosted style, and custom hostname -- use default (http) or user choice. return $scheme; } /** * If `X-Goog-Content-SHA256` header is provided, use that as the payload. * Otherwise, `UNSIGNED-PAYLOAD`. * * @param array $headers * @return string */ private function getPayloadHash(array $headers) { if (!isset($headers['x-goog-content-sha256'])) { return 'UNSIGNED-PAYLOAD'; } return $headers['x-goog-content-sha256']; } /** * Normalizes and validates an expiration. * * @param Timestamp|\DateTimeInterface|int $expires The expiration * @return int * @throws \InvalidArgumentException If an invalid value is given. */ private function normalizeExpiration($expires) { if ($expires instanceof Timestamp) { $seconds = $expires->get()->format('U'); } elseif ($expires instanceof \DateTimeInterface) { $seconds = $expires->format('U'); } elseif (is_numeric($expires)) { $seconds = (int) $expires; } else { throw new \InvalidArgumentException('Invalid expiration.'); } return $seconds; } /** * Normalizes and encodes the resource identifier. * * @param string $resource The resource identifier. In form * `[/]$bucket/$object`. * @return array A list, where index 0 is the resource path, with pieces * encoded and prefixed with a forward slash, index 1 is the bucket * name, and index 2 is the object name, relative to the bucket. */ private function normalizeResource($resource, $urlencode = true) { $pieces = explode('/', trim($resource, '/')); if ($urlencode) { array_walk($pieces, function (&$piece) { $piece = rawurlencode($piece); }); } $bucket = $pieces[0]; $relative = $pieces; array_shift($relative); return [ '/' . implode('/', $pieces), $bucket, '/' . implode('/', $relative), ]; } /** * Fixes the user input options, filters and validates data. * * @param array $options Signed URL configuration options. * @return array * @throws \InvalidArgumentException */ private function normalizeOptions(array $options) { $options += [ 'allowPost' => false, 'cname' => null, //@deprecated 'bucketBoundHostname' => self::DEFAULT_DOWNLOAD_HOST, 'contentMd5' => null, 'contentType' => null, 'forceOpenssl' => false, 'headers' => [], 'keyFile' => null, 'keyFilePath' => null, 'credentialsFetcher' => null, 'method' => 'GET', 'queryParams' => [], 'responseDisposition' => null, 'responseType' => null, 'saveAsName' => null, // note that in almost every case this default will be overridden. 'scheme' => 'http', 'timestamp' => null, 'virtualHostedStyle' => false, ]; $allowedMethods = ['GET', 'PUT', 'POST', 'DELETE']; $options['method'] = strtoupper($options['method']); if (!in_array($options['method'], $allowedMethods)) { throw new \InvalidArgumentException('$options.method must be one of `GET`, `PUT` or `DELETE`.'); } if ($options['method'] === 'POST' && !$options['allowPost']) { throw new \InvalidArgumentException( 'Invalid method. To create an upload URI, use StorageObject::signedUploadUrl().' ); } // Rewrite deprecated `cname` to new `bucketBoundHostname`. if ($options['cname'] && $options['bucketBoundHostname'] === self::DEFAULT_DOWNLOAD_HOST) { $options['bucketBoundHostname'] = $options['cname']; } // strip protocol from hostname. $hostnameParts = explode('//', $options['bucketBoundHostname']); if (count($hostnameParts) > 1) { $options['bucketBoundHostname'] = $hostnameParts[1]; } $options['bucketBoundHostname'] = trim($options['bucketBoundHostname'], '/'); // If a timestamp is provided, use it in place of `now` for v4 URLs only.. // This option exists for testing purposes, and should not generally be provided by users. if ($options['timestamp']) { if (!($options['timestamp'] instanceof \DateTimeInterface)) { if (!is_string($options['timestamp'])) { throw new \InvalidArgumentException( 'User-provided timestamps must be a string or instance of `\DateTimeInterface`.' ); } $options['timestamp'] = \DateTimeImmutable::createFromFormat( \DateTime::RFC3339, $options['timestamp'], new \DateTimeZone('UTC') ); if (!$options['timestamp']) { throw new \InvalidArgumentException( 'Given timestamp string is in an invalid format. Provide timestamp formatted as follows: `' . \DateTime::RFC3339 . '`. Note that timestamps MUST be in UTC.' ); } } } else { $options['timestamp'] = new \DateTimeImmutable('now', new \DateTimeZone('UTC')); } unset( $options['cname'], $options['allowPost'] ); return $options; } /** * Cleans and normalizes header values. * * Arrays of values are collapsed into a comma-separated list, trailing and * leading spaces are removed, newlines are replaced by empty strings, and * multiple whitespace chars are replaced by a single space. * * @param array $headers Input headers * @return array */ private function normalizeHeaders(array $headers) { $out = []; foreach ($headers as $name => $value) { $name = strtolower(trim($name)); // collapse arrays of values into a comma-separated list. if (!is_array($value)) { $value = [$value]; } foreach ($value as &$headerValue) { // strip trailing and leading spaces. $headerValue = trim($headerValue); // replace newlines with empty strings. $headerValue = str_replace(PHP_EOL, '', $headerValue); // collapse multiple whitespace chars to a single space. $headerValue = preg_replace('/[\s]+/', ' ', $headerValue); } $out[$name] = implode(', ', $value); } return $out; } /** * Returns a resource formatted for use in a URI. * * If the bucketBoundHostname is other than the default, will omit the bucket name. * * @param string $bucketBoundHostname The bucketBoundHostname provided by the user, or the default * value. * @param string $resource The GCS resource path (i.e. /bucket/object). * @return string */ private function normalizeUriPath($bucketBoundHostname, $resource, $withTrailingSlash = false) { if ($bucketBoundHostname !== self::DEFAULT_DOWNLOAD_HOST) { $resourceParts = explode('/', trim($resource, '/')); array_shift($resourceParts); // Resource is a Bucket. if (empty($resourceParts)) { $resource = '/'; } else { $resource = '/' . implode('/', $resourceParts); } } $resource = rtrim($resource, '/'); return $withTrailingSlash ? $resource . '/' : $resource; } /** * Normalize the resource provided to the canonical request string. * * @param string $resource * @param string $bucketBoundHostname * @param boolean $virtualHostedStyle * @return string */ private function normalizeCanonicalRequestResource($resource, $bucketBoundHostname, $virtualHostedStyle = false) { if ($bucketBoundHostname === self::DEFAULT_DOWNLOAD_HOST && !$virtualHostedStyle) { return $resource; } $pieces = explode('/', trim($resource, '/')); array_shift($pieces); return '/' . implode('/', $pieces); } /** * Get the credentials for use with signing. * * @param ConnectionInterface $connection A Storage connection object. * This object is created by StorageClient, * and should not be instantiated outside of this client. * @param array $options Configuration options. * @return array A list containing a credentials object at index 0 and the * modified options at index 1. * @throws \RuntimeException If the credentials type is not valid for signing. * @throws \InvalidArgumentException If a keyfile is given and is not valid. */ private function getSigningCredentials(ConnectionInterface $connection, array $options) { $keyFilePath = $options['keyFilePath'] ?? null; if ($keyFilePath) { if (!file_exists($keyFilePath)) { throw new \InvalidArgumentException(sprintf( 'Keyfile path %s does not exist.', $keyFilePath )); } $options['keyFile'] = self::jsonDecode(file_get_contents($keyFilePath), true); } $rw = $connection->requestWrapper(); $keyFile = $options['keyFile'] ?? null; if ($keyFile) { $scopes = $options['scopes'] ?? $rw->scopes(); $credentials = CredentialsLoader::makeCredentials($scopes, $keyFile); } elseif (isset($options['credentialsFetcher'])) { $credentials = $options['credentialsFetcher']; } else { $credentials = $rw->getCredentialsFetcher(); } //@codeCoverageIgnoreStart if (!($credentials instanceof SignBlobInterface)) { throw new \RuntimeException(sprintf( 'Credentials object is of type `%s` and is not valid for signing.', get_class($credentials) )); } //@codeCoverageIgnoreEnd unset( $options['keyFilePath'], $options['keyFile'], $options['credentialsFetcher'], $options['scopes'] ); return [$credentials, $options]; } /** * Add parameters common to all signed URL versions. * * @param int|null $generation * @param array $params * @param array $options * @return array */ private function addCommonParams($generation, array $params, array $options) { if ($options['responseType']) { $params['response-content-type'] = $options['responseType']; } if ($options['responseDisposition']) { $params['response-content-disposition'] = $options['responseDisposition']; } elseif ($options['saveAsName']) { $params['response-content-disposition'] = 'attachment; filename=' . '"' . $options['saveAsName'] . '"'; } if ($generation) { $params['generation'] = $generation; } return $params; } /** * Create a query string from an array. * * Note that this method does NOT urlencode keys or values. * * @param array $input * @return string */ private function buildQueryString(array $input) { $q = []; foreach ($input as $key => $val) { $q[] = $key . '=' . $val; } return implode('&', $q); } /** * Retry logic for signBlob * * @param callable $signBlobFn A callable that perform the actual signBlob operation. * @param string $resourceName The resource name for logging or retry strategy determination. * @param array $args Arguments for the operations, include preconditions * @return string The signature genarated by signBlob. * @throws ServiceException If non-retryable error occur. * @throws \RuntimeException If retries are exhausted. */ private function retrySignBlob(callable $signBlobFn, string $resourceName = 'signBlob', array $args = []) { $attempt = 0; // Generate a retry decider function using the RetryTrait logic. $retryDecider = $this->getRestRetryFunction($resourceName, 'execute', $args); while (true) { ++$attempt; try { // Attempt the operation return $signBlobFn(); } catch (\Exception $exception) { if (!$retryDecider($exception, $attempt, self::MAX_RETRIES)) { // Non-retryable error throw $exception; } } } } } ================================================ FILE: lib/Google/vendor/google/cloud-storage/src/StorageClient.php ================================================ $creds]); * ``` * This will ensure that an unexpected credential type with potential for * malicious intent is not loaded unintentionally. You might still have to do * validation for certain credential types. * If you are loading your credential configuration from an untrusted source and have * not mitigated the risks (e.g. by validating the configuration yourself), make * these changes as soon as possible to prevent security risks to your environment. * Regardless of the method used, it is always your responsibility to validate * configurations received from external sources. * @see https://cloud.google.com/docs/authentication/external/externally-sourced-credentials * @type string $keyFilePath [DEPRECATED] * This option is being deprecated because of a potential security risk. * This option does not validate the credential configuration. The security * risk occurs when a credential configuration is accepted from a source * that is not under your control and used without validation on your side. * If you know that you will be loading credential configurations of a * specific type, it is recommended to create the credentials directly and * configure them using the `credentialsFetcher` option instead. * ``` * use Google\Auth\Credentials\ServiceAccountCredentials; * $credentialsFetcher = new ServiceAccountCredentials($scopes, $json); * $creds = new StorageClient(['credentialsFetcher' => $creds]); * ``` * This will ensure that an unexpected credential type with potential for * malicious intent is not loaded unintentionally. You might still have to do * validation for certain credential types. * If you are loading your credential configuration from an untrusted source and have * not mitigated the risks (e.g. by validating the configuration yourself), make * these changes as soon as possible to prevent security risks to your environment. * Regardless of the method used, it is always your responsibility to validate * configurations received from external sources. * @see https://cloud.google.com/docs/authentication/external/externally-sourced-credentials * @type float $requestTimeout Seconds to wait before timing out the * request. **Defaults to** `0` with REST and `60` with gRPC. * @type int $retries Number of retries for a failed request. * **Defaults to** `3`. * @type string $retryStrategy Retry strategy to signify that we never * want to retry an operation even if the error is retryable. * **Defaults to** `StorageClient::RETRY_IDEMPOTENT`. * @type callable $restDelayFunction Executes a delay, defaults to * utilizing `usleep`. Function signature should match: * `function (int $delay) : void`. * @type callable $restCalcDelayFunction Sets the conditions for * determining how long to wait between attempts to retry. Function * signature should match: `function (int $attempt) : int`. * @type callable $restRetryFunction Sets the conditions for whether or * not a request should attempt to retry. Function signature should * match: `function (\Exception $ex) : bool`. * @type callable $restRetryListener Runs after the restRetryFunction. * This might be used to simply consume the exception and * $arguments b/w retries. This returns the new $arguments thus * allowing modification on demand for $arguments. For ex: * changing the headers in b/w retries. * @type array $scopes Scopes to be used for the request. * @type string $quotaProject Specifies a user project to bill for * access charges associated with the request. * } */ public function __construct(array $config = []) { if (!isset($config['scopes'])) { $config['scopes'] = [ 'https://www.googleapis.com/auth/iam', self::FULL_CONTROL_SCOPE, ]; } $this->connection = new Rest($this->configureAuthentication($config) + [ 'projectId' => $this->projectId ]); } /** * Lazily instantiates a bucket. * * There are no network requests made at this point. To see the operations * that can be performed on a bucket please see {@see Bucket}. * * If `$userProject` is set to true, the current project ID (used to * instantiate the client) will be billed for all requests. If * `$userProject` is a project ID, given as a string, that project * will be billed for all requests. This only has an effect when the bucket * is not owned by the current or given project ID. * * Example: * ``` * $bucket = $storage->bucket('my-bucket'); * ``` * * @param string $name The name of the bucket to request. * @param string|bool $userProject If true, the current Project ID * will be used. If a string, that string will be used as the * userProject argument, and that project will be billed for the * request. **Defaults to** `false`. * @param array $options [optional] { * Configuration Options. * * @type bool $softDeleted If set to true, only soft-deleted bucket versions * are listed as distinct results in order of bucket name and generation * number. The default value is false. * @type string $generation If present, selects a specific soft-deleted version * of this bucket instead of the live version. This parameter is required if * softDeleted is set to true. * } * @return Bucket */ public function bucket($name, $userProject = false, array $options = []) { if (!$userProject) { $userProject = null; } elseif (!is_string($userProject)) { $userProject = $this->projectId; } return new Bucket($this->connection, $name, $options + [ 'requesterProjectId' => $userProject ]); } /** * Fetches all buckets in the project. * * Example: * ``` * $buckets = $storage->buckets(); * ``` * * ``` * // Get all buckets beginning with the prefix 'album'. * $buckets = $storage->buckets([ * 'prefix' => 'album' * ]); * * foreach ($buckets as $bucket) { * echo $bucket->name() . PHP_EOL; * } * ``` * * @see https://cloud.google.com/storage/docs/json_api/v1/buckets/list Buckets list API documentation. * * @param array $options [optional] { * Configuration options. * * @type int $maxResults Maximum number of results to return per * requested page. * @type int $resultLimit Limit the number of results returned in total. * **Defaults to** `0` (return all results). * @type string $pageToken A previously-returned page token used to * resume the loading of results from a specific point. * @type string $prefix Filter results with this prefix. * @type string $projection Determines which properties to return. May * be either 'full' or 'noAcl'. * @type string $fields Selector which will cause the response to only * return the specified fields. * @type string $userProject If set, this is the ID of the project which * will be billed for the request. * @type bool $softDeleted If set to true, only soft-deleted bucket versions * are listed as distinct results in order of bucket name and generation * number. The default value is false. * @type bool $bucketUserProject If true, each returned instance will * have `$userProject` set to the value of `$options.userProject`. * If false, `$options.userProject` will be used ONLY for the * listBuckets operation. If `$options.userProject` is not set, * this option has no effect. **Defaults to** `true`. * @type bool $returnPartialSuccess If true, the returned iterator will contain an * `unreachable` property with a list of buckets that were not retrieved. * **Note:** If set to false (default) and unreachable buckets are found, * the operation will throw an exception. * * } * @return BucketIterator * @throws GoogleException When a project ID has not been detected. */ public function buckets(array $options = []) { $this->requireProjectId(); $resultLimit = $this->pluck('resultLimit', $options, false); $bucketUserProject = $this->pluck('bucketUserProject', $options, null) ?? true; $userProject = $bucketUserProject ? ($options['userProject'] ?? null) : null; $unreachable = new \ArrayObject(); $apiCall = [$this->connection, 'listBuckets']; $callDelegate = function (array $args) use ($apiCall, $unreachable) { $response = call_user_func($apiCall, $args); if (isset($response['unreachable']) && is_array($response['unreachable'])) { $current = $unreachable->getArrayCopy(); $updated = array_unique(array_merge($current, $response['unreachable'])); $unreachable->exchangeArray($updated); } return $response; }; // Return the new BucketIterator with the wrapped unreachable bucket return new BucketIterator( new PageIterator( function (array $bucket) use ($userProject) { return new Bucket( $this->connection, $bucket['name'], $bucket + ['requesterProjectId' => $userProject] ); }, $callDelegate, $options + ['project' => $this->projectId], ['resultLimit' => $resultLimit] ), $unreachable ); } /** * Restores a soft-deleted bucket. * * Example: * ``` * $bucket = $storage->bucket->restore('my-bucket'); * ``` * * @param string $name The name of the bucket to restore. * @param string $generation The specific version of the bucket to be restored. * @param array $options [optional] { * Configuration Options. * * @type string $projection Determines which properties to return. May * be either `"full"` or `"noAcl"`. **Defaults to** `"noAcl"`, * unless the bucket resource specifies acl or defaultObjectAcl * properties, when it defaults to `"full"`. * } * @return Bucket */ public function restore(string $name, string $generation, array $options = []) { $res = $this->connection->restoreBucket([ 'bucket' => $name, 'generation' => $generation, ] + $options); return new Bucket( $this->connection, $name ); } /** * Create a bucket. Bucket names must be unique as Cloud Storage uses a flat * namespace. For more information please see * [bucket name requirements](https://cloud.google.com/storage/docs/naming#requirements) * * Example: * ``` * $bucket = $storage->createBucket('bucket'); * ``` * * ``` * // Create a bucket with logging enabled. * $bucket = $storage->createBucket('myBeautifulBucket', [ * 'logging' => [ * 'logBucket' => 'bucketToLogTo', * 'logObjectPrefix' => 'myPrefix' * ] * ]); * ``` * * @see https://cloud.google.com/storage/docs/json_api/v1/buckets/insert Buckets insert API documentation. * * @param string $name Name of the bucket to be created. * @codingStandardsIgnoreStart * @param array $options [optional] { * Configuration options. * * @type string $predefinedAcl Predefined ACL to apply to the bucket. * Acceptable values include, `"authenticatedRead"`, * `"bucketOwnerFullControl"`, `"bucketOwnerRead"`, `"private"`, * `"projectPrivate"`, and `"publicRead"`. * @type string $predefinedDefaultObjectAcl Apply a predefined set of * default object access controls to this bucket. * @type bool $enableObjectRetention Whether object retention should * be enabled on this bucket. For more information, refer to the * [Object Retention Lock](https://cloud.google.com/storage/docs/object-lock) * documentation. * @type string $projection Determines which properties to return. May * be either `"full"` or `"noAcl"`. **Defaults to** `"noAcl"`, * unless the bucket resource specifies acl or defaultObjectAcl * properties, when it defaults to `"full"`. * @type string $fields Selector which will cause the response to only * return the specified fields. * @type array $acl Access controls on the bucket. * @type array $cors The bucket's Cross-Origin Resource Sharing (CORS) * configuration. * @type array $defaultObjectAcl Default access controls to apply to new * objects when no ACL is provided. * @type array|Lifecycle $lifecycle The bucket's lifecycle configuration. * @type string $location The location of the bucket. If specifying * a dual-region, the `customPlacementConfig` property should be * set in conjunction. For more information, see * [Bucket Locations](https://cloud.google.com/storage/docs/locations). * **Defaults to** `"US"`. * @type array $hierarchicalNamespace The hierarchical namespace configuration * on this bucket. * @type array $customPlacementConfig The bucket's dual regions. For more * information, see * [Bucket Locations](https://cloud.google.com/storage/docs/locations). * @type array $logging The bucket's logging configuration, which * defines the destination bucket and optional name prefix for the * current bucket's logs. * @type string $storageClass The bucket's storage class. This defines * how objects in the bucket are stored and determines the SLA and * the cost of storage. Acceptable values include the following * strings: `"STANDARD"`, `"NEARLINE"`, `"COLDLINE"` and * `"ARCHIVE"`. Legacy values including `"MULTI_REGIONAL"`, * `"REGIONAL"` and `"DURABLE_REDUCED_AVAILABILITY"` are also * available, but should be avoided for new implementations. For * more information, refer to the * [Storage Classes](https://cloud.google.com/storage/docs/storage-classes) * documentation. **Defaults to** `"STANDARD"`. * @type array $autoclass The bucket's autoclass configuration. * Buckets can have either StorageClass OLM rules or Autoclass, * but not both. When Autoclass is enabled on a bucket, adding * StorageClass OLM rules will result in failure. * For more information, refer to * [Storage Autoclass](https://cloud.google.com/storage/docs/autoclass) * @type array $versioning The bucket's versioning configuration. * @type array $website The bucket's website configuration. * @type array $billing The bucket's billing configuration. * @type bool $billing.requesterPays When `true`, requests to this bucket * and objects within it must provide a project ID to which the * request will be billed. * @type array $labels The Bucket labels. Labels are represented as an * array of keys and values. To remove an existing label, set its * value to `null`. * @type string $userProject If set, this is the ID of the project which * will be billed for the request. * @type bool $bucketUserProject If true, the returned instance will * have `$userProject` set to the value of `$options.userProject`. * If false, `$options.userProject` will be used ONLY for the * createBucket operation. If `$options.userProject` is not set, * this option has no effect. **Defaults to** `true`. * @type array $encryption Encryption configuration used by default for * newly inserted objects. * @type string $encryption.defaultKmsKeyName A Cloud KMS Key used to * encrypt objects uploaded into this bucket. Should be in the * format * `projects/my-project/locations/kr-location/keyRings/my-kr/cryptoKeys/my-key`. * Please note the KMS key ring must use the same location as the * bucket. * @type bool $defaultEventBasedHold When `true`, newly created objects * in this bucket will be retained indefinitely until an event * occurs, signified by the hold's release. * @type array $retentionPolicy Defines the retention policy for a * bucket. In order to lock a retention policy, please see * {@see Bucket::lockRetentionPolicy()}. * @type int $retentionPolicy.retentionPeriod Specifies the retention * period for objects in seconds. During the retention period an * object cannot be overwritten or deleted. Retention period must * be greater than zero and less than 100 years. * @type array $iamConfiguration The bucket's IAM configuration. * @type bool $iamConfiguration.bucketPolicyOnly.enabled this is an alias * for $iamConfiguration.uniformBucketLevelAccess. * @type bool $iamConfiguration.uniformBucketLevelAccess.enabled If set and * true, access checks only use bucket-level IAM policies or * above. When enabled, requests attempting to view or manipulate * ACLs will fail with error code 400. **NOTE**: Before using * Uniform bucket-level access, please review the * [feature documentation](https://cloud.google.com/storage/docs/uniform-bucket-level-access), * as well as * [Should You Use uniform bucket-level access](https://cloud.google.com/storage/docs/uniform-bucket-level-access#should-you-use) * @type string $rpo Specifies the Turbo Replication setting for a dual-region bucket. * The possible values are DEFAULT and ASYNC_TURBO. Trying to set the rpo for a non dual-region * bucket will throw an exception. Non existence of this parameter is equivalent to it being DEFAULT. * } * @codingStandardsIgnoreEnd * @return Bucket * @throws GoogleException When a project ID has not been detected. */ public function createBucket($name, array $options = []) { $this->requireProjectId(); if (isset($options['lifecycle']) && $options['lifecycle'] instanceof Lifecycle) { $options['lifecycle'] = $options['lifecycle']->toArray(); } $bucketUserProject = $this->pluck('bucketUserProject', $options, false); $bucketUserProject = !is_null($bucketUserProject) ? $bucketUserProject : true; $userProject = (isset($options['userProject']) && $bucketUserProject) ? $options['userProject'] : null; $response = $this->connection->insertBucket($options + ['name' => $name, 'project' => $this->projectId]); return new Bucket( $this->connection, $name, $response + ['requesterProjectId' => $userProject] ); } /** * Registers this StorageClient as the handler for stream reading/writing. * * @param string $protocol The name of the protocol to use. **Defaults to** `gs`. * @throws \RuntimeException */ public function registerStreamWrapper($protocol = null) { return StreamWrapper::register($this, $protocol); } /** * Unregisters the SteamWrapper * * @param string $protocol The name of the protocol to unregister. **Defaults to** `gs`. */ public function unregisterStreamWrapper($protocol = null) { StreamWrapper::unregister($protocol); } /** * Create an uploader to handle a Signed URL. * * Example: * ``` * $uploader = $storage->signedUrlUploader($uri, fopen('/path/to/myfile.doc', 'r')); * ``` * * @param string $uri The URI to accept an upload request. * @param string|resource|StreamInterface $data The data to be uploaded * @param array $options [optional] Configuration Options. Refer to * {@see \Google\Cloud\Core\Upload\AbstractUploader::__construct()}. * @return SignedUrlUploader */ public function signedUrlUploader($uri, $data, array $options = []) { return new SignedUrlUploader($this->connection->requestWrapper(), $data, $uri, $options); } /** * Create a Timestamp object. * * Example: * ``` * $timestamp = $storage->timestamp(new \DateTime('2003-02-05 11:15:02.421827Z')); * ``` * * @param \DateTimeInterface $timestamp The timestamp value. * @param int $nanoSeconds [optional] The number of nanoseconds in the timestamp. * @return Timestamp */ public function timestamp(\DateTimeInterface $timestamp, $nanoSeconds = null) { return new Timestamp($timestamp, $nanoSeconds); } /** * Get the service account email associated with this client. * * Example: * ``` * $serviceAccount = $storage->getServiceAccount(); * ``` * * @param array $options [optional] { * Configuration options. * * @type string $userProject If set, this is the ID of the project which * will be billed for the request. * } * @return string */ public function getServiceAccount(array $options = []) { $resp = $this->connection->getServiceAccount($options + ['projectId' => $this->projectId]); return $resp['email_address']; } /** * List Service Account HMAC keys in the project. * * Example: * ``` * $hmacKeys = $storage->hmacKeys(); * ``` * * ``` * // Get the HMAC keys associated with a Service Account email * $hmacKeys = $storage->hmacKeys([ * 'serviceAccountEmail' => $serviceAccountEmail * ]); * ``` * * @param array $options { * Configuration Options * * @type string $serviceAccountEmail If present, only keys for the given * service account are returned. * @type bool $showDeletedKeys Whether or not to show keys in the * DELETED state. * @type string $userProject If set, this is the ID of the project which * will be billed for the request. * @type string $projectId The project ID to use, if different from that * with which the client was created. * } * @return ItemIterator */ public function hmacKeys(array $options = []) { $options += [ 'projectId' => $this->projectId ]; if (!$options['projectId']) { $this->requireProjectId(); } $resultLimit = $this->pluck('resultLimit', $options, false); return new ItemIterator( new PageIterator( function (array $metadata) use ($options) { return $this->hmacKey( $metadata['accessId'], $options['projectId'], $metadata ); }, [$this->connection, 'listHmacKeys'], $options, ['resultLimit' => $resultLimit] ) ); } /** * Lazily instantiate an HMAC Key instance using an Access ID. * * Example: * ``` * $hmacKey = $storage->hmacKey($accessId); * ``` * * @param string $accessId The ID of the HMAC Key. * @param string $projectId [optional] The project ID to use, if different * from that with which the client was created. * @param array $metadata [optional] HMAC key metadata. * @return HmacKey */ public function hmacKey($accessId, $projectId = null, array $metadata = []) { if (!$projectId) { $this->requireProjectId(); } return new HmacKey($this->connection, $projectId ?: $this->projectId, $accessId, $metadata); } /** * Creates a new HMAC key for the specified service account. * * Please note that the HMAC secret is only available at creation. Make sure * to note the secret after creation. * * Example: * ``` * $response = $storage->createHmacKey('account@myProject.iam.gserviceaccount.com'); * $secret = $response->secret(); * ``` * * @param string $serviceAccountEmail Email address of the service account. * @param array $options { * Configuration Options * * @type string $userProject If set, this is the ID of the project which * will be billed for the request. **NOTE**: This option is * currently ignored by Cloud Storage. * @type string $projectId The project ID to use, if different from that * with which the client was created. * } * @return CreatedHmacKey */ public function createHmacKey($serviceAccountEmail, array $options = []) { $options += [ 'projectId' => $this->projectId ]; if (!$options['projectId']) { $this->requireProjectId(); } $res = $this->connection->createHmacKey([ 'projectId' => $options['projectId'], 'serviceAccountEmail' => $serviceAccountEmail ] + $options); $key = new HmacKey( $this->connection, $options['projectId'], $res['metadata']['accessId'], $res['metadata'] ); return new CreatedHmacKey($key, $res['secret']); } /** * Throw an exception if no project ID available. * * @return void * @throws GoogleException */ private function requireProjectId() { if (!$this->projectId) { throw new GoogleException( 'No project ID was provided, ' . 'and we were unable to detect a default project ID.' ); } } } ================================================ FILE: lib/Google/vendor/google/cloud-storage/src/StorageObject.php ================================================ bucket('my-bucket'); * $object = $bucket->object('my-object'); * ``` */ class StorageObject { use ArrayTrait; use EncryptionTrait; /** * @deprecated */ const DEFAULT_DOWNLOAD_URL = SigningHelper::DEFAULT_DOWNLOAD_HOST; /** * @var Acl ACL for the object. */ private $acl; /** * @var ConnectionInterface Represents a connection to Cloud Storage. * @internal */ protected $connection; /** * @var array|null The object's encryption data. */ private $encryptionData; /** * @var array The object's identity. */ private $identity; /** * @var array|null The object's metadata. */ private $info; /** * @param ConnectionInterface $connection Represents a connection to Cloud * Storage. This object is created by StorageClient, * and should not be instantiated outside of this client. * @param string $name The object's name. * @param string $bucket The name of the bucket the object is contained in. * @param string $generation [optional] The generation of the object. * @param array $info [optional] The object's metadata. * @param string $encryptionKey [optional] An AES-256 customer-supplied * encryption key. * @param string $encryptionKeySHA256 [optional] The SHA256 hash of the * customer-supplied encryption key. */ public function __construct( ConnectionInterface $connection, $name, $bucket, $generation = null, array $info = [], $encryptionKey = null, $encryptionKeySHA256 = null ) { $this->connection = $connection; $this->info = $info; $this->encryptionData = [ 'encryptionKey' => $encryptionKey, 'encryptionKeySHA256' => $encryptionKeySHA256 ]; $this->identity = [ 'bucket' => $bucket, 'object' => $name, 'generation' => $generation, 'userProject' => $this->pluck('requesterProjectId', $info, false) ]; $this->acl = new Acl($this->connection, 'objectAccessControls', $this->identity); } /** * Configure ACL for this object. * * Example: * ``` * $acl = $object->acl(); * ``` * * @see https://cloud.google.com/storage/docs/access-control More about Access Control Lists * * @return Acl */ public function acl() { return $this->acl; } /** * Check whether or not the object exists. * * Example: * ``` * if ($object->exists()) { * echo 'Object exists!'; * } * ``` * * @param array $options [optional] Configuration options. * @return bool */ public function exists(array $options = []) { try { $this->connection->getObject($this->identity + $options + ['fields' => 'name']); } catch (NotFoundException $ex) { return false; } return true; } /** * Delete the object. * * Example: * ``` * $object->delete(); * ``` * * @see https://cloud.google.com/storage/docs/json_api/v1/objects/delete Objects delete API documentation. * * @param array $options [optional] { * Configuration options. * * @type string $ifGenerationMatch Makes the operation conditional on * whether the object's current generation matches the given * value. * @type string $ifGenerationNotMatch Makes the operation conditional on * whether the object's current generation does not match the * given value. * @type string $ifMetagenerationMatch Makes the operation conditional * on whether the object's current metageneration matches the * given value. * @type string $ifMetagenerationNotMatch Makes the operation * conditional on whether the object's current metageneration does * not match the given value. * } * @return void */ public function delete(array $options = []) { $this->connection->deleteObject($options + array_filter($this->identity)); } /** * Update the object. Upon receiving a result the local object's data will * be updated. * * Example: * ``` * // Add custom metadata to an existing object. * $object->update([ * 'metadata' => [ * 'albumType' => 'family' * ] * ]); * ``` * * @see https://cloud.google.com/storage/docs/json_api/v1/objects/patch Objects patch API documentation. * * @param array $metadata The available options for metadata are outlined * at the [JSON API docs](https://cloud.google.com/storage/docs/json_api/v1/objects#resource) * @param array $options [optional] { * Configuration options. * * @type string $ifGenerationMatch Makes the operation conditional on * whether the object's current generation matches the given * value. * @type string $ifGenerationNotMatch Makes the operation conditional on * whether the object's current generation does not match the * given value. * @type string $ifMetagenerationMatch Makes the operation conditional * on whether the object's current metageneration matches the * given value. * @type string $ifMetagenerationNotMatch Makes the operation * conditional on whether the object's current metageneration does * not match the given value. * @type string $predefinedAcl Predefined ACL to apply to the object. * Acceptable values include, `"authenticatedRead"`, * `"bucketOwnerFullControl"`, `"bucketOwnerRead"`, `"private"`, * `"projectPrivate"`, and `"publicRead"`. * @type array $retention The full list of available options are outlined * at the [JSON API docs](https://cloud.google.com/storage/docs/json_api/v1/objects/update#request-body). * @type string $retention.retainUntilTime The earliest time in RFC 3339 * UTC "Zulu" format that the object can be deleted or replaced. * This is the retention configuration set for this object. * @type string $retention.mode The mode of the retention configuration, * which can be either `"Unlocked"` or `"Locked"`. * @type bool $overrideUnlockedRetention Applicable for objects that * have an unlocked retention configuration. Required to be set to * `true` if the operation includes a retention property that * changes the mode to `Locked`, reduces the `retainUntilTime`, or * removes the retention configuration from the object. * @type string $projection Determines which properties to return. May * be either 'full' or 'noAcl'. * @type string $fields Selector which will cause the response to only * return the specified fields. * } * @return array */ public function update(array $metadata, array $options = []) { $options += $metadata; // can only set predefinedAcl or acl if (isset($options['predefinedAcl'])) { $options['acl'] = null; } return $this->info = $this->connection->patchObject($options + array_filter($this->identity)); } /** * Copy the object to a destination bucket. * * Please note that if the destination bucket is the same as the source * bucket and a new name is not provided the source object will be replaced * with the copy of itself. * * Example: * ``` * // Provide your destination bucket as a string and retain the source * // object's name. * $copiedObject = $object->copy('otherBucket'); * ``` * * ``` * // Provide your destination bucket as a bucket object and choose a new * // name for the copied object. * $otherBucket = $storage->bucket('otherBucket'); * $copiedObject = $object->copy($otherBucket, [ * 'name' => 'newFile.txt' * ]); * ``` * * @see https://cloud.google.com/storage/docs/json_api/v1/objects/copy Objects copy API documentation. * * @param Bucket|string $destination The destination bucket. * @param array $options [optional] { * Configuration options. * * @type string $name The name of the destination object. **Defaults * to** the name of the source object. * @type string $predefinedAcl Predefined ACL to apply to the object. * Acceptable values include, `"authenticatedRead"`, * `"bucketOwnerFullControl"`, `"bucketOwnerRead"`, `"private"`, * `"projectPrivate"`, and `"publicRead"`. * @type string $encryptionKey A base64 encoded AES-256 customer-supplied * encryption key. It will be neccesary to provide this when a key * was used during the object's creation. * @type string $encryptionKeySHA256 Base64 encoded SHA256 hash of the * customer-supplied encryption key. This value will be calculated * from the `encryptionKey` on your behalf if not provided, but * for best performance it is recommended to pass in a cached * version of the already calculated SHA. * @type string $ifGenerationMatch Makes the operation conditional on * whether the destination object's current generation matches the * given value. * @type string $ifGenerationNotMatch Makes the operation conditional on * whether the destination object's current generation does not * match the given value. * @type string $ifMetagenerationMatch Makes the operation conditional * on whether the destination object's current metageneration * matches the given value. * @type string $ifMetagenerationNotMatch Makes the operation * conditional on whether the destination object's current * metageneration does not match the given value. * @type string $ifSourceGenerationMatch Makes the operation conditional * on whether the source object's current generation matches the * given value. * @type string $ifSourceGenerationNotMatch Makes the operation * conditional on whether the source object's current generation * does not match the given value. * @type string $ifSourceMetagenerationMatch Makes the operation * conditional on whether the source object's current * metageneration matches the given value. * @type string $ifSourceMetagenerationNotMatch Makes the operation * conditional on whether the source object's current * metageneration does not match the given value. * } * @return StorageObject */ public function copy($destination, array $options = []) { $key = $options['encryptionKey'] ?? null; $keySHA256 = $options['encryptionKeySHA256'] ?? null; $response = $this->connection->copyObject( $this->formatDestinationRequest($destination, $options) ); return new StorageObject( $this->connection, $response['name'], $response['bucket'], $response['generation'], $response + ['requesterProjectId' => $this->identity['userProject']], $key, $keySHA256 ); } /** * Rewrite the object to a destination bucket. * * This method copies data using multiple requests so large objects can be * copied with a normal length timeout per request rather than one very long * timeout for a single request. * * Please note that if the destination bucket is the same as the source * bucket and a new name is not provided the source object will be replaced * with the copy of itself. * * Example: * ``` * // Provide your destination bucket as a string and retain the source * // object's name. * $rewrittenObject = $object->rewrite('otherBucket'); * ``` * * ``` * // Provide your destination bucket as a bucket object and choose a new * // name for the copied object. * $otherBucket = $storage->bucket('otherBucket'); * $rewrittenObject = $object->rewrite($otherBucket, [ * 'name' => 'newFile.txt' * ]); * ``` * * ``` * // Rotate customer-supplied encryption keys. * $key = file_get_contents(__DIR__ . '/key.txt'); * $destinationKey = base64_encode(openssl_random_pseudo_bytes(32)); // Make sure to remember your key. * * $rewrittenObject = $object->rewrite('otherBucket', [ * 'encryptionKey' => $key, * 'destinationEncryptionKey' => $destinationKey * ]); * ``` * * @see https://cloud.google.com/storage/docs/json_api/v1/objects/rewrite Objects rewrite API documentation. * @see https://cloud.google.com/storage/docs/encryption#customer-supplied Customer-supplied encryption keys. * * @param Bucket|string $destination The destination bucket. * @param array $options [optional] { * Configuration options. * * @type string $name The name of the destination object. **Defaults * to** the name of the source object. * @type string $predefinedAcl Predefined ACL to apply to the object. * Acceptable values include, `"authenticatedRead"`, * `"bucketOwnerFullControl"`, `"bucketOwnerRead"`, `"private"`, * `"projectPrivate"`, and `"publicRead"`. * @type string $maxBytesRewrittenPerCall The maximum number of bytes * that will be rewritten per rewrite request. Most callers * shouldn't need to specify this parameter - it is primarily in * place to support testing. If specified the value must be an * integral multiple of 1 MiB (1048576). Also, this only applies * to requests where the source and destination span locations * and/or storage classes. * @type string $encryptionKey A base64 encoded AES-256 customer-supplied * encryption key. It will be neccesary to provide this when a key * was used during the object's creation. * @type string $encryptionKeySHA256 Base64 encoded SHA256 hash of the * customer-supplied encryption key. This value will be calculated * from the `encryptionKey` on your behalf if not provided, but * for best performance it is recommended to pass in a cached * version of the already calculated SHA. * @type string $destinationEncryptionKey A base64 encoded AES-256 * customer-supplied encryption key that will be used to encrypt * the rewritten object. * @type string $destinationEncryptionKeySHA256 Base64 encoded SHA256 * hash of the customer-supplied destination encryption key. This * value will be calculated from the `destinationEncryptionKey` on * your behalf if not provided, but for best performance it is * recommended to pass in a cached version of the already * calculated SHA. * @type string $destinationKmsKeyName Name of the Cloud KMS key that * will be used to encrypt the object. Should be in the format * `projects/my-project/locations/kr-location/keyRings/my-kr/cryptoKeys/my-key`. * Please note the KMS key ring must use the same location as the * destination bucket. * @type string $ifGenerationMatch Makes the operation conditional on * whether the destination object's current generation matches the * given value. * @type string $ifGenerationNotMatch Makes the operation conditional on * whether the destination object's current generation does not * match the given value. * @type string $ifMetagenerationMatch Makes the operation conditional * on whether the destination object's current metageneration * matches the given value. * @type string $ifMetagenerationNotMatch Makes the operation * conditional on whether the destination object's current * metageneration does not match the given value. * @type string $ifSourceGenerationMatch Makes the operation conditional * on whether the source object's current generation matches the * given value. * @type string $ifSourceGenerationNotMatch Makes the operation * conditional on whether the source object's current generation * does not match the given value. * @type string $ifSourceMetagenerationMatch Makes the operation * conditional on whether the source object's current * metageneration matches the given value. * @type string $ifSourceMetagenerationNotMatch Makes the operation * conditional on whether the source object's current * metageneration does not match the given value. * } * @return StorageObject * @throws \InvalidArgumentException */ public function rewrite($destination, array $options = []) { $options['useCopySourceHeaders'] = true; $destinationKey = $options['destinationEncryptionKey'] ?? null; $destinationKeySHA256 = $options['destinationEncryptionKeySHA256'] ?? null; $options = $this->formatDestinationRequest($destination, $options); do { $response = $this->connection->rewriteObject($options); $options['rewriteToken'] = $response['rewriteToken'] ?? null; } while ($options['rewriteToken']); return new StorageObject( $this->connection, $response['resource']['name'], $response['resource']['bucket'], $response['resource']['generation'], $response['resource'] + ['requesterProjectId' => $this->identity['userProject']], $destinationKey, $destinationKeySHA256 ); } /** * Move an object within a bucket. * * This method copies data using multiple requests so large objects can be * copied with a normal length timeout per request rather than one very long * timeout for a single request. * * Example: * ``` * // Provide your destination object as a string. * $moveObject = $object->move('newObject.txt'); * ``` * * @see https://cloud.google.com/storage/docs/json_api/v1/objects/move Objects move API documentation. * * @param string $destinationObject The destination object. * @param array $options [optional] * Configuration options. * * @type string $ifGenerationMatch Makes the operation conditional on * whether the destination object's current generation matches the * given value. * @type string $ifGenerationNotMatch Makes the operation conditional on * whether the destination object's current generation does not * match the given value. * @type string $ifMetagenerationMatch Makes the operation conditional * on whether the destination object's current metageneration * matches the given value. * @type string $ifMetagenerationNotMatch Makes the operation * conditional on whether the destination object's current * metageneration does not match the given value. * @type string $ifSourceGenerationMatch Makes the operation conditional * on whether the source object's current generation matches the * given value. * @type string $ifSourceGenerationNotMatch Makes the operation * conditional on whether the source object's current generation * does not match the given value. * @type string $ifSourceMetagenerationMatch Makes the operation * conditional on whether the source object's current * metageneration matches the given value. * @type string $ifSourceMetagenerationNotMatch Makes the operation * conditional on whether the source object's current * metageneration does not match the given value. * * @return StorageObject * @throws \InvalidArgumentException */ public function move($destinationObject, array $options = []) { if (!is_string($destinationObject)) { throw new \InvalidArgumentException( '$destinationObject must be a string.' ); } $options['bucket'] = $this->identity['bucket']; $options['sourceObject'] = $this->identity['object']; $options['destinationObject'] = $destinationObject; $options['userProject'] = $this->identity['userProject']; $response = $this->connection->moveObject($options); return new StorageObject( $this->connection, $response['name'], $response['bucket'], $response['generation'], $response + ['requesterProjectId' => $this->identity['userProject']] ); } /** * Renames the object. * * Please note that there is no atomic rename provided by the Storage API. * This method is for convenience and is a set of sequential calls to copy * and delete. Upon success the source object's metadata will be cleared, * please use the returned object instead. * * Example: * ``` * $object2 = $object->rename('object2.txt'); * echo $object2->name(); * ``` * * @param string $name The new name. * @param array $options [optional] { * Configuration options. * * @type string $predefinedAcl Predefined ACL to apply to the object. * Acceptable values include, `"authenticatedRead"`, * `"bucketOwnerFullControl"`, `"bucketOwnerRead"`, `"private"`, * `"projectPrivate"`, and `"publicRead"`. * @type string $encryptionKey A base64 encoded AES-256 customer-supplied * encryption key. It will be neccesary to provide this when a key * was used during the object's creation. * @type string $encryptionKeySHA256 Base64 encoded SHA256 hash of the * customer-supplied encryption key. This value will be calculated * from the `encryptionKey` on your behalf if not provided, but * for best performance it is recommended to pass in a cached * version of the already calculated SHA. * @type string $ifGenerationMatch Makes the operation conditional on * whether the destination object's current generation matches the * given value. * @type string $ifGenerationNotMatch Makes the operation conditional on * whether the destination object's current generation does not * match the given value. * @type string $ifMetagenerationMatch Makes the operation conditional * on whether the destination object's current metageneration * matches the given value. * @type string $ifMetagenerationNotMatch Makes the operation * conditional on whether the destination object's current * metageneration does not match the given value. * @type string $ifSourceGenerationMatch Makes the operation conditional * on whether the source object's current generation matches the * given value. * @type string $ifSourceGenerationNotMatch Makes the operation * conditional on whether the source object's current generation * does not match the given value. * @type string $ifSourceMetagenerationMatch Makes the operation * conditional on whether the source object's current * metageneration matches the given value. * @type string $ifSourceMetagenerationNotMatch Makes the operation * conditional on whether the source object's current * metageneration does not match the given value. * @type string $destinationBucket Will move to this bucket if set. If * not set, will default to the same bucket. * } * @return StorageObject The renamed object. */ public function rename($name, array $options = []) { $destinationBucket = $options['destinationBucket'] ?? $this->identity['bucket']; unset($options['destinationBucket']); $copiedObject = $this->copy($destinationBucket, [ 'name' => $name ] + $options); $this->delete( array_intersect_key($options, [ 'restOptions' => null, 'retries' => null ]) ); $this->info = []; return $copiedObject; } /** * Download an object as a string. * * For an example of setting the range header to download a subrange of the * object please see {@see StorageObject::downloadAsStream()}. * * Example: * ``` * $string = $object->downloadAsString(); * echo $string; * ``` * * @see https://cloud.google.com/storage/docs/json_api/v1/objects/get Objects get API documentation. * @see https://cloud.google.com/storage/docs/json_api/v1/parameters#range Learn more about the Range header. * * @param array $options [optional] { * Configuration Options. * * @type string $encryptionKey An AES-256 customer-supplied encryption * key. It will be neccesary to provide this when a key was used * during the object's creation. If provided one must also include * an `encryptionKeySHA256`. * @type string $encryptionKeySHA256 The SHA256 hash of the * customer-supplied encryption key. It will be neccesary to * provide this when a key was used during the object's creation. * If provided one must also include an `encryptionKey`. * } * @return string */ public function downloadAsString(array $options = []) { return (string) $this->downloadAsStream($options); } /** * Download an object to a specified location. * * For an example of setting the range header to download a subrange of the * object please see {@see StorageObject::downloadAsStream()}. * * Example: * ``` * $stream = $object->downloadToFile(__DIR__ . '/my-file.txt'); * ``` * * @see https://cloud.google.com/storage/docs/json_api/v1/objects/get Objects get API documentation. * @see https://cloud.google.com/storage/docs/json_api/v1/parameters#range Learn more about the Range header. * * @param string $path Path to download the file to. * @param array $options [optional] { * Configuration Options. * * @type string $encryptionKey An AES-256 customer-supplied encryption * key. It will be neccesary to provide this when a key was used * during the object's creation. If provided one must also include * an `encryptionKeySHA256`. * @type string $encryptionKeySHA256 The SHA256 hash of the * customer-supplied encryption key. It will be neccesary to * provide this when a key was used during the object's creation. * If provided one must also include an `encryptionKey`. * } * @return StreamInterface */ public function downloadToFile($path, array $options = []) { $source = $this->downloadAsStream($options); $destination = Utils::streamFor(fopen($path, 'w')); Utils::copyToStream( $source, $destination ); $destination->seek(0); return $destination; } /** * Download an object as a stream. The library will attempt to resume the download * if a retry-able error is thrown. An attempt to fetch the remaining file will * be made only if the user has not supplied a custom retry * function of their own. * * Please note Google Cloud Storage respects the Range header as specified * by [RFC7233](https://tools.ietf.org/html/rfc7233#section-3.1). See below * for an example of this in action. * * Example: * ``` * $stream = $object->downloadAsStream(); * echo $stream->getContents(); * ``` * * ``` * // Set the Range header in order to download a subrange of the object. For more examples of * // setting the Range header, please see [RFC7233](https://tools.ietf.org/html/rfc7233#section-3.1). * $firstFiveBytes = '0-4'; // Get the first 5 bytes. * $fromFifthByteToLastByte = '4-'; // Get the bytes starting with the 5th to the last. * $lastFiveBytes = '-5'; // Get the last 5 bytes. * * $stream = $object->downloadAsStream([ * 'restOptions' => [ * 'headers' => [ * 'Range' => "bytes=$firstFiveBytes" * ] * ] * ]); * ``` * * @see https://cloud.google.com/storage/docs/json_api/v1/objects/get Objects get API documentation. * @see https://cloud.google.com/storage/docs/json_api/v1/parameters#range Learn more about the Range header. * * @param array $options [optional] { * Configuration Options. * * @type string $encryptionKey An AES-256 customer-supplied encryption * key. It will be neccesary to provide this when a key was used * during the object's creation. If provided one must also include * an `encryptionKeySHA256`. * @type string $encryptionKeySHA256 The SHA256 hash of the * customer-supplied encryption key. It will be neccesary to * provide this when a key was used during the object's creation. * If provided one must also include an `encryptionKey`. * } * @return StreamInterface */ public function downloadAsStream(array $options = []) { return $this->connection->downloadObject( $this->formatEncryptionHeaders( $options + $this->encryptionData + array_filter($this->identity) ) ); } /** * Asynchronously download an object as a stream. * * For an example of setting the range header to download a subrange of the * object please see {@see StorageObject::downloadAsStream()}. * * Example: * ``` * use Psr\Http\Message\StreamInterface; * * $promise = $object->downloadAsStreamAsync() * ->then(function (StreamInterface $data) { * echo $data->getContents(); * }); * * $promise->wait(); * ``` * * ``` * // Download all objects in a bucket asynchronously. * use GuzzleHttp\Promise\Utils; * use Psr\Http\Message\StreamInterface; * * $promises = []; * * foreach ($bucket->objects() as $object) { * $promises[] = $object->downloadAsStreamAsync() * ->then(function (StreamInterface $data) { * echo $data->getContents(); * }); * } * * Utils::unwrap($promises); * ``` * * @see https://cloud.google.com/storage/docs/json_api/v1/objects/get Objects get API documentation. * @see https://cloud.google.com/storage/docs/json_api/v1/parameters#range Learn more about the Range header. * @see https://github.com/guzzle/promises Learn more about Guzzle Promises * * @param array $options [optional] { * Configuration Options. * * @type string $encryptionKey An AES-256 customer-supplied encryption * key. It will be neccesary to provide this when a key was used * during the object's creation. If provided one must also include * an `encryptionKeySHA256`. * @type string $encryptionKeySHA256 The SHA256 hash of the * customer-supplied encryption key. It will be neccesary to * provide this when a key was used during the object's creation. * If provided one must also include an `encryptionKey`. * } * @return PromiseInterface * @experimental The experimental flag means that while we believe this method * or class is ready for use, it may change before release in backwards- * incompatible ways. Please use with caution, and test thoroughly when * upgrading. */ public function downloadAsStreamAsync(array $options = []) { return $this->connection->downloadObjectAsync( $this->formatEncryptionHeaders( $options + $this->encryptionData + array_filter($this->identity) ) ); } /** * Create a Signed URL for this object. * * Signed URLs can be complex, and it is strongly recommended you read and * understand the [documentation](https://cloud.google.com/storage/docs/access-control/signed-urls). * * In cases where a keyfile is available, signing is accomplished in the * client using your Service Account private key. In Google Compute Engine, * signing is accomplished using * [IAM signBlob](https://cloud.google.com/iam/credentials/reference/rest/v1/projects.serviceAccounts/signBlob). * Signing using IAM requires that your service account be granted the * `iam.serviceAccounts.signBlob` permission, part of the "Service Account * Token Creator" IAM role. * * Additionally, signing using IAM requires different scopes. When creating * an instance of {@see StorageClient}, provide the * `https://www.googleapis.com/auth/cloud-platform` scopein `$options.scopes`. * This scope may be used entirely in place of the scopes provided in * {@see StorageClient}. * * App Engine and Compute Engine will attempt to sign URLs using IAM. * * Example: * ``` * $url = $object->signedUrl(new \DateTime('tomorrow')); * ``` * * ``` * // Create a signed URL allowing updates to the object. * $url = $object->signedUrl(new \DateTime('tomorrow'), [ * 'method' => 'PUT' * ]); * ``` * * ``` * // Use Signed URLs v4 * $url = $object->signedUrl(new \DateTime('tomorrow'), [ * 'version' => 'v4' * ]); * ``` * * ``` * // Using Bucket-Bound hostnames * // By default, a custom bucket-bound hostname will use `http` as the schema rather than `https`. * // In order to get an https URI, we need to specify the proper scheme. * $url = $object->signedUrl(new \DateTime('tomorrow'), [ * 'version' => 'v4', * 'bucketBoundHostname' => 'cdn.example.com', * 'scheme' => 'https' * ]); * ``` * * ``` * // Using virtual hosted style URIs * // When true, returns a URL with the hostname `.storage.googleapis.com`. * $url = $object->signedUrl(new \DateTime('tomorrow'), [ * 'virtualHostedStyle' => true * ]); * ```` * * @see https://cloud.google.com/storage/docs/access-control/signed-urls Signed URLs * * @param Timestamp|\DateTimeInterface|int $expires Specifies when the URL * will expire. May provide an instance of {@see \Google\Cloud\Core\Timestamp}, * [http://php.net/datetimeimmutable](`\DateTimeImmutable`), or a * UNIX timestamp as an integer. * @param array $options { * Configuration Options. * * @type string $bucketBoundHostname The hostname for the bucket, for * instance `cdn.example.com`. May be used for Google Cloud Load * Balancers or for custom bucket CNAMEs. **Defaults to** * `storage.googleapis.com`. * @type string $contentMd5 The MD5 digest value in base64. If you * provide this, the client must provide this HTTP header with * this same value in its request. If provided, take care to * always provide this value as a base64 encoded string. * @type string $contentType If you provide this value, the client must * provide this HTTP header set to the same value. * @type bool $forceOpenssl If true, OpenSSL will be used regardless of * whether phpseclib is available. **Defaults to** `false`. * @type array $headers If additional headers are provided, the server * will check to make sure that the client provides matching * values. Provide headers as a key/value array, where the key is * the header name, and the value is an array of header values. * Headers with multiple values may provide values as a simple * array, or a comma-separated string. For a reference of allowed * headers, see [Reference Headers](https://cloud.google.com/storage/docs/xml-api/reference-headers). * Header values will be trimmed of leading and trailing spaces, * multiple spaces within values will be collapsed to a single * space, and line breaks will be replaced by an empty string. * V2 Signed URLs may not provide `x-goog-encryption-key` or * `x-goog-encryption-key-sha256` headers. * @type FetchAuthTokenInterface $credentialsFetcher A credentials * fetcher instance. * @type array $keyFile [DEPRECATED] * This option is being deprecated because of a potential security risk. * This option does not validate the credential configuration. The security * risk occurs when a credential configuration is accepted from a source * that is not under your control and used without validation on your side. * If you know that you will be loading credential configurations of a * specific type, it is recommended to create the credentials directly and * configure them using the `credentialsFetcher` option instead. * ``` * use Google\Auth\Credentials\ServiceAccountCredentials; * $credentialsFetcher = new ServiceAccountCredentials($scopes, $json); * ``` * This will ensure that an unexpected credential type with potential for * malicious intent is not loaded unintentionally. You might still have to do * validation for certain credential types. * If you are loading your credential configuration from an untrusted source and have * not mitigated the risks (e.g. by validating the configuration yourself), make * these changes as soon as possible to prevent security risks to your environment. * Regardless of the method used, it is always your responsibility to validate * configurations received from external sources. * @see https://cloud.google.com/docs/authentication/external/externally-sourced-credentials * @type string $keyFilePath [DEPRECATED] * This option is being deprecated because of a potential security risk. * This option does not validate the credential configuration. The security * risk occurs when a credential configuration is accepted from a source * that is not under your control and used without validation on your side. * If you know that you will be loading credential configurations of a * specific type, it is recommended to create the credentials directly and * configure them using the `credentialsFetcher` option instead. * ``` * use Google\Auth\Credentials\ServiceAccountCredentials; * $credentialsFetcher = new ServiceAccountCredentials($scopes, $json); * ``` * This will ensure that an unexpected credential type with potential for * malicious intent is not loaded unintentionally. You might still have to do * validation for certain credential types. * If you are loading your credential configuration from an untrusted source and have * not mitigated the risks (e.g. by validating the configuration yourself), make * these changes as soon as possible to prevent security risks to your environment. * Regardless of the method used, it is always your responsibility to validate * configurations received from external sources. * @see https://cloud.google.com/docs/authentication/external/externally-sourced-credentials * @type string $method One of `GET`, `PUT` or `DELETE`. * **Defaults to** `GET`. * @type string $responseDisposition The * [`response-content-disposition`](http://www.iana.org/assignments/cont-disp/cont-disp.xhtml) * parameter of the signed url. * @type string $responseType The `response-content-type` parameter of the * signed url. When the server contentType is `null`, this option * may be used to control the content type of the response. * @type string $saveAsName The filename to prompt the user to save the * file as when the signed url is accessed. This is ignored if * `$options.responseDisposition` is set. * @type string $scheme Either `http` or `https`. Only used if a custom * hostname is provided via `$options.bucketBoundHostname`. If a * custom bucketBoundHostname is provided, **defaults to** `http`. * In all other cases, **defaults to** `https`. * @type string|array $scopes One or more authentication scopes to be * used with a key file. This option is ignored unless * `$options.keyFile` or `$options.keyFilePath` is set. * @type array $queryParams Additional query parameters to be included * as part of the signed URL query string. For allowed values, * see [Reference Headers](https://cloud.google.com/storage/docs/xml-api/reference-headers#query). * @type string $version One of "v2" or "v4". **Defaults to** `"v2"`. * @type bool $virtualHostedStyle If `true`, URL will be of form * `mybucket.storage.googleapis.com`. If `false`, * `storage.googleapis.com/mybucket`. **Defaults to** `false`. * } * @return string * @throws \InvalidArgumentException If the given expiration is invalid or in the past. * @throws \InvalidArgumentException If the given `$options.method` is not valid. * @throws \InvalidArgumentException If the given `$options.keyFilePath` is not valid. * @throws \InvalidArgumentException If the given custom headers are invalid. * @throws \InvalidArgumentException If the keyfile does not contain the required information. * @throws \RuntimeException If the credentials provided cannot be used for signing strings. */ public function signedUrl($expires, array $options = []) { // May be overridden for testing. $signingHelper = $this->pluck('helper', $options, false) ?: SigningHelper::getHelper(); $resource = sprintf( '/%s/%s', $this->identity['bucket'], $this->identity['object'] ); return $signingHelper->sign( $this->connection, $expires, $resource, $this->identity['generation'], $options ); } /** * Create a Signed Upload URL for this object. * * This method differs from {@see StorageObject::signedUrl()} * in that it allows you to initiate a new resumable upload session. This * can be used to allow non-authenticated users to insert an object into a * bucket. * * In order to upload data, a session URI must be * obtained by sending an HTTP POST request to the URL returned from this * method. See the [Cloud Storage Documentation](https://goo.gl/b1ZiZm) for * more information. * * If you prefer to skip this initial step, you may find * {@see StorageObject::beginSignedUploadSession()} to * fit your needs. Note that `beginSignedUploadSession()` cannot be used * with Google Cloud PHP's Signed URL Uploader, and does not support a * configurable expiration date. * * Example: * ``` * $url = $object->signedUploadUrl(new \DateTime('tomorrow')); * ``` * * ``` * // Use Signed URLs v4 * $url = $object->signedUploadUrl(new \DateTime('tomorrow'), [ * 'version' => 'v4' * ]); * ``` * * @param Timestamp|\DateTimeInterface|int $expires Specifies when the URL * will expire. May provide an instance of {@see \Google\Cloud\Core\Timestamp}, * [http://php.net/datetimeimmutable](`\DateTimeImmutable`), or a * UNIX timestamp as an integer. * @param array $options { * Configuration Options. * * @type string $contentMd5 The MD5 digest value in base64. If you * provide this, the client must provide this HTTP header with * this same value in its request. If provided, take care to * always provide this value as a base64 encoded string. * @type string $contentType If you provide this value, the client must * provide this HTTP header set to the same value. * @type bool $forceOpenssl If true, OpenSSL will be used regardless of * whether phpseclib is available. **Defaults to** `false`. * @type array $headers If additional headers are provided, the server * will check to make sure that the client provides matching * values. Provide headers as a key/value array, where the key is * the header name, and the value is an array of header values. * Headers with multiple values may provide values as a simple * array, or a comma-separated string. For a reference of allowed * headers, see [Reference Headers](https://cloud.google.com/storage/docs/xml-api/reference-headers). * Header values will be trimmed of leading and trailing spaces, * multiple spaces within values will be collapsed to a single * space, and line breaks will be replaced by an empty string. * V2 Signed URLs may not provide `x-goog-encryption-key` or * `x-goog-encryption-key-sha256` headers. * @type FetchAuthTokenInterface $credentialsFetcher A credentials * fetcher instance. * @type array $keyFile [DEPRECATED] * This option is being deprecated because of a potential security risk. * This option does not validate the credential configuration. The security * risk occurs when a credential configuration is accepted from a source * that is not under your control and used without validation on your side. * If you know that you will be loading credential configurations of a * specific type, it is recommended to create the credentials directly and * configure them using the `credentialsFetcher` option instead. * ``` * use Google\Auth\Credentials\ServiceAccountCredentials; * $credentialsFetcher = new ServiceAccountCredentials($scopes, $json); * ``` * This will ensure that an unexpected credential type with potential for * malicious intent is not loaded unintentionally. You might still have to do * validation for certain credential types. * If you are loading your credential configuration from an untrusted source and have * not mitigated the risks (e.g. by validating the configuration yourself), make * these changes as soon as possible to prevent security risks to your environment. * Regardless of the method used, it is always your responsibility to validate * configurations received from external sources. * @see https://cloud.google.com/docs/authentication/external/externally-sourced-credentials * @type string $keyFilePath [DEPRECATED] * This option is being deprecated because of a potential security risk. * This option does not validate the credential configuration. The security * risk occurs when a credential configuration is accepted from a source * that is not under your control and used without validation on your side. * If you know that you will be loading credential configurations of a * specific type, it is recommended to create the credentials directly and * configure them using the `credentialsFetcher` option instead. * ``` * use Google\Auth\Credentials\ServiceAccountCredentials; * $credentialsFetcher = new ServiceAccountCredentials($scopes, $json); * ``` * This will ensure that an unexpected credential type with potential for * malicious intent is not loaded unintentionally. You might still have to do * validation for certain credential types. * If you are loading your credential configuration from an untrusted source and have * not mitigated the risks (e.g. by validating the configuration yourself), make * these changes as soon as possible to prevent security risks to your environment. * Regardless of the method used, it is always your responsibility to validate * configurations received from external sources. * @see https://cloud.google.com/docs/authentication/external/externally-sourced-credentials * @type string $responseDisposition The * [`response-content-disposition`](http://www.iana.org/assignments/cont-disp/cont-disp.xhtml) * parameter of the signed url. * @type string $responseType The `response-content-type` parameter of the * signed url. When the server contentType is `null`, this option * may be used to control the content type of the response. * @type string $saveAsName The filename to prompt the user to save the * file as when the signed url is accessed. This is ignored if * `$options.responseDisposition` is set. * @type string $scheme Either `http` or `https`. Only used if a custom * hostname is provided via `$options.bucketBoundHostname`. In all * other cases, `https` is used. When a custom bucketBoundHostname * is provided, **defaults to** `http`. * @type string|array $scopes One or more authentication scopes to be * used with a key file. This option is ignored unless * `$options.keyFile` or `$options.keyFilePath` is set. * @type array $queryParams Additional query parameters to be included * as part of the signed URL query string. For allowed values, * see [Reference Headers](https://cloud.google.com/storage/docs/xml-api/reference-headers#query). * @type string $version One of "v2" or "v4". **Defaults to** `"v2"`. * } * @return string */ public function signedUploadUrl($expires, array $options = []) { $options += [ 'headers' => [] ]; $options['headers']['x-goog-resumable'] = 'start'; unset( $options['cname'], $options['bucketBoundHostname'], $options['saveAsName'], $options['responseDisposition'], $options['responseType'], $options['virtualHostedStyle'] ); return $this->signedUrl($expires, [ 'method' => 'POST', 'allowPost' => true ] + $options); } /** * Create a signed URL upload session. * * The returned URL differs from the return value of * {@see StorageObject::signedUploadUrl()} in that it * is ready to accept upload data immediately via an HTTP PUT request. * * Because an upload session is created by the client, the expiration date * is not configurable. The URL generated by this method is valid for one * week. * * Example: * ``` * $url = $object->beginSignedUploadSession(); * ``` * * ``` * // Use Signed URLs v4 * $url = $object->beginSignedUploadSession([ * 'version' => 'v4' * ]); * ``` * * @see https://cloud.google.com/storage/docs/xml-api/resumable-upload#practices Resumable Upload Best Practices * * @param array $options { * Configuration Options. * * @type string $contentMd5 The MD5 digest value in base64. If you * provide this, the client must provide this HTTP header with * this same value in its request. If provided, take care to * always provide this value as a base64 encoded string. * @type string $contentType If you provide this value, the client must * provide this HTTP header set to the same value. * @type bool $forceOpenssl If true, OpenSSL will be used regardless of * whether phpseclib is available. **Defaults to** `false`. * @type array $headers If additional headers are provided, the server * will check to make sure that the client provides matching * values. Provide headers as a key/value array, where the key is * the header name, and the value is an array of header values. * Headers with multiple values may provide values as a simple * array, or a comma-separated string. For a reference of allowed * headers, see [Reference Headers](https://cloud.google.com/storage/docs/xml-api/reference-headers). * Header values will be trimmed of leading and trailing spaces, * multiple spaces within values will be collapsed to a single * space, and line breaks will be replaced by an empty string. * V2 Signed URLs may not provide `x-goog-encryption-key` or * `x-goog-encryption-key-sha256` headers. * @type FetchAuthTokenInterface $credentialsFetcher A credentials * fetcher instance. * @type array $keyFile [DEPRECATED] * This option is being deprecated because of a potential security risk. * This option does not validate the credential configuration. The security * risk occurs when a credential configuration is accepted from a source * that is not under your control and used without validation on your side. * If you know that you will be loading credential configurations of a * specific type, it is recommended to create the credentials directly and * configure them using the `credentialsFetcher` option instead. * ``` * use Google\Auth\Credentials\ServiceAccountCredentials; * $credentialsFetcher = new ServiceAccountCredentials($scopes, $json); * ``` * This will ensure that an unexpected credential type with potential for * malicious intent is not loaded unintentionally. You might still have to do * validation for certain credential types. * If you are loading your credential configuration from an untrusted source and have * not mitigated the risks (e.g. by validating the configuration yourself), make * these changes as soon as possible to prevent security risks to your environment. * Regardless of the method used, it is always your responsibility to validate * configurations received from external sources. * @see https://cloud.google.com/docs/authentication/external/externally-sourced-credentials * @type string $keyFilePath [DEPRECATED] * This option is being deprecated because of a potential security risk. * This option does not validate the credential configuration. The security * risk occurs when a credential configuration is accepted from a source * that is not under your control and used without validation on your side. * If you know that you will be loading credential configurations of a * specific type, it is recommended to create the credentials directly and * configure them using the `credentialsFetcher` option instead. * ``` * use Google\Auth\Credentials\ServiceAccountCredentials; * $credentialsFetcher = new ServiceAccountCredentials($scopes, $json); * ``` * This will ensure that an unexpected credential type with potential for * malicious intent is not loaded unintentionally. You might still have to do * validation for certain credential types. * If you are loading your credential configuration from an untrusted source and have * not mitigated the risks (e.g. by validating the configuration yourself), make * these changes as soon as possible to prevent security risks to your environment. * Regardless of the method used, it is always your responsibility to validate * configurations received from external sources. * @see https://cloud.google.com/docs/authentication/external/externally-sourced-credentials * "Access-Control-Allow-Origin". **Defaults to** `"*"`. * @type string|array $scopes One or more authentication scopes to be * used with a key file. This option is ignored unless * `$options.keyFile` or `$options.keyFilePath` is set. * @type array $queryParams Additional query parameters to be included * as part of the signed URL query string. For allowed values, * see [Reference Headers](https://cloud.google.com/storage/docs/xml-api/reference-headers#query). * @type string $version One of "v2" or "v4". **Defaults to** `"v2"`. * } * @return string */ public function beginSignedUploadSession(array $options = []) { $expires = new \DateTimeImmutable('+1 minute'); $startUri = $this->signedUploadUrl($expires, $options); $uploaderOptions = $this->pluckArray([ 'contentType', 'origin' ], $options); if (!isset($uploaderOptions['origin'])) { $uploaderOptions['origin'] = '*'; } $uploader = new SignedUrlUploader($this->connection->requestWrapper(), '', $startUri, $uploaderOptions); return $uploader->getResumeUri(); } /** * Retrieves the object's details. If no object data is cached a network * request will be made to retrieve it. * * Example: * ``` * $info = $object->info(); * echo $info['size']; * ``` * * @see https://cloud.google.com/storage/docs/json_api/v1/objects/get Objects get API documentation. * * @param array $options [optional] { * Configuration options. * * @type string $encryptionKey An AES-256 customer-supplied encryption * key. It will be neccesary to provide this when a key was used * during the object's creation in order to retrieve the MD5 hash * and CRC32C checksum. If provided one must also include an * `encryptionKeySHA256`. * @type string $encryptionKeySHA256 The SHA256 hash of the * customer-supplied encryption key. It will be neccesary to * provide this when a key was used during the object's creation * in order to retrieve the MD5 hash and CRC32C checksum. If * provided one must also include an `encryptionKey`. * @type string $ifGenerationMatch Makes the operation conditional on * whether the object's current generation matches the given * value. * @type string $ifGenerationNotMatch Makes the operation conditional on * whether the object's current generation does not match the * given value. * @type string $ifMetagenerationMatch Makes the operation conditional * on whether the object's current metageneration matches the * given value. * @type string $ifMetagenerationNotMatch Makes the operation * conditional on whether the object's current metageneration does * not match the given value. * @type string $projection Determines which properties to return. May * be either 'full' or 'noAcl'. * } * @return array */ public function info(array $options = []) { return $this->info ?: $this->reload($options); } /** * Triggers a network request to reload the object's details. * * Example: * ``` * $object->reload(); * $info = $object->info(); * echo $info['location']; * ``` * * @see https://cloud.google.com/storage/docs/json_api/v1/objects/get Objects get API documentation. * * @param array $options [optional] { * Configuration options. * * @type string $encryptionKey A base64 encoded AES-256 customer-supplied * encryption key. It will be neccesary to provide this when a key * was used during the object's creation. * @type string $encryptionKeySHA256 Base64 encoded SHA256 hash of the * customer-supplied encryption key. This value will be calculated * from the `encryptionKey` on your behalf if not provided, but * for best performance it is recommended to pass in a cached * version of the already calculated SHA. * @type string $ifGenerationMatch Makes the operation conditional on * whether the object's current generation matches the given * value. * @type string $ifGenerationNotMatch Makes the operation conditional on * whether the object's current generation does not match the * given value. * @type string $ifMetagenerationMatch Makes the operation conditional * on whether the object's current metageneration matches the * given value. * @type string $ifMetagenerationNotMatch Makes the operation * conditional on whether the object's current metageneration does * not match the given value. * @type string $projection Determines which properties to return. May * be either 'full' or 'noAcl'. * } * @return array */ public function reload(array $options = []) { return $this->info = $this->connection->getObject( $this->formatEncryptionHeaders( $options + $this->encryptionData + array_filter($this->identity) ) ); } /** * Retrieves the object's name. * * Example: * ``` * echo $object->name(); * ``` * * @return string */ public function name() { return $this->identity['object']; } /** * Retrieves the object's identity. * * Example: * ``` * echo $object->identity()['object']; * ``` * * @return array */ public function identity() { return $this->identity; } /** * Formats the object as a string in the following format: * `gs://{bucket-name}/{object-name}`. * * Example: * ``` * echo $object->gcsUri(); * ``` * * @return string */ public function gcsUri() { return sprintf( 'gs://%s/%s', $this->identity['bucket'], $this->identity['object'] ); } /** * Formats a destination based request, such as copy or rewrite. * * @param string|Bucket $destination The destination bucket. * @param array $options Options to configure. * @return array */ private function formatDestinationRequest($destination, array $options) { if (!is_string($destination) && !($destination instanceof Bucket)) { throw new \InvalidArgumentException( '$destination must be either a string or an instance of Bucket.' ); } $destAcl = $options['predefinedAcl'] ?? null; $destObject = $options['name'] ?? $this->identity['object']; unset($options['name']); unset($options['predefinedAcl']); return array_filter([ 'destinationBucket' => $destination instanceof Bucket ? $destination->name() : $destination, 'destinationObject' => $destObject, 'destinationPredefinedAcl' => $destAcl, 'sourceBucket' => $this->identity['bucket'], 'sourceObject' => $this->identity['object'], 'sourceGeneration' => $this->identity['generation'], 'userProject' => $this->identity['userProject'], ]) + $this->formatEncryptionHeaders($options + $this->encryptionData); } } ================================================ FILE: lib/Google/vendor/google/cloud-storage/src/StreamWrapper.php ================================================ ['option' => value]]. * Options used by StreamWrapper: * * flush (bool) `true`: fflush() will flush output buffer; `false`: fflush() will do nothing */ public $context; /** * @var \Psr\Http\Message\StreamInterface */ private $stream; /** * @var string Protocol used to open this stream */ private $protocol; /** * @var Bucket Reference to the bucket the opened file * lives in or will live in. */ private $bucket; /** * @var string Name of the file opened by this stream. */ private $file; /** * @var StorageClient[] $clients The default clients to use if using * global methods such as fopen on a stream wrapper. Keyed by protocol. */ private static $clients = []; /** * @var ObjectIterator Used for iterating through a directory */ private $directoryIterator; /** * @var StorageObject */ private $object; /** * @var array Context options passed to stream_open(), used for append mode and flushing. */ private $options = []; /** * @var bool `true`: fflush() will flush output buffer and redirect output to the "tail" object. */ private $flushing = false; /** * @var string|null Content type for composed object. Will be filled on first composing. */ private $contentType = null; /** * @var bool `true`: writing the "tail" object, next fflush() or fclose() will compose. */ private $composing = false; /** * @var bool `true`: data has been written to the stream. */ private $dirty = false; /** * Ensure we close the stream when this StreamWrapper is destroyed. */ public function __destruct() { $this->stream_close(); } /** * This is called when include/require is used on a stream. */ public function stream_set_option() { return false; } /** * This is called when touch is used on a stream. See: * https://www.php.net/manual/en/streamwrapper.stream-metadata.php */ public function stream_metadata($path, $option, $value) { if ($option == STREAM_META_TOUCH) { $this->openPath($path); return $this->touch(); } return false; } /** * Creates an empty file if it does not exist. * @return bool Returns true if file exists or has been created, false otherwise. */ private function touch() { $object = $this->bucket->object($this->file); try { if (!$object->exists()) { $this->bucket->upload('', [ 'name' => $this->file ]); } return true; } catch (NotFoundException $e) { } return false; } /** * Register a StreamWrapper for reading and writing to Google Storage * * @param StorageClient $client The StorageClient configuration to use. * @param string $protocol The name of the protocol to use. **Defaults to** * `gs`. * @throws \RuntimeException */ public static function register(StorageClient $client, $protocol = null) { $protocol = $protocol ?: self::DEFAULT_PROTOCOL; if (!in_array($protocol, stream_get_wrappers())) { if (!stream_wrapper_register($protocol, StreamWrapper::class, STREAM_IS_URL)) { throw new \RuntimeException("Failed to register '$protocol://' protocol"); } self::$clients[$protocol] = $client; return true; } return false; } /** * Unregisters the SteamWrapper * * @param string $protocol The name of the protocol to unregister. **Defaults * to** `gs`. */ public static function unregister($protocol = null) { $protocol = $protocol ?: self::DEFAULT_PROTOCOL; stream_wrapper_unregister($protocol); unset(self::$clients[$protocol]); } /** * Get the default client to use for streams. * * @param string $protocol The name of the protocol to get the client for. * **Defaults to** `gs`. * @return StorageClient */ public static function getClient($protocol = null) { $protocol = $protocol ?: self::DEFAULT_PROTOCOL; return self::$clients[$protocol]; } /** * Callback handler for when a stream is opened. For reads, we need to * download the file to see if it can be opened. * * @param string $path The path of the resource to open * @param string $mode The fopen mode. Currently supports ('r', 'rb', 'rt', 'w', 'wb', 'wt', 'a', 'ab', 'at') * @param int $flags Bitwise options STREAM_USE_PATH|STREAM_REPORT_ERRORS|STREAM_MUST_SEEK * @param string $openedPath Will be set to the path on success if STREAM_USE_PATH option is set * @return bool */ public function stream_open($path, $mode, $flags, &$openedPath) { $this->openPath($path); // strip off 'b' or 't' from the mode $mode = rtrim($mode, 'bt'); $options = []; if ($this->context) { $contextOptions = stream_context_get_options($this->context); if (array_key_exists($this->protocol, $contextOptions)) { $options = $contextOptions[$this->protocol] ?: []; } if (isset($options['flush'])) { $this->flushing = (bool) $options['flush']; unset($options['flush']); } $this->options = $options; } if ($mode == 'w') { $this->stream = new WriteStream(null, $options); $this->stream->setUploader( $this->bucket->getStreamableUploader( $this->stream, $options + ['name' => $this->file] ) ); } elseif ($mode == 'a') { try { $info = $this->bucket->object($this->file)->info(); $this->composing = ($info['size'] > 0); } catch (NotFoundException $e) { } $this->stream = new WriteStream(null, $options); $name = $this->file; if ($this->composing) { $name .= self::TAIL_NAME_SUFFIX; } $this->stream->setUploader( $this->bucket->getStreamableUploader( $this->stream, $options + ['name' => $name] ) ); } elseif ($mode == 'r') { try { // Lazy read from the source $options['restOptions']['stream'] = true; $this->stream = new ReadStream( $this->bucket->object($this->file)->downloadAsStream($options) ); // Wrap the response in a caching stream to make it seekable if (!$this->stream->isSeekable() && ($flags & STREAM_MUST_SEEK)) { $this->stream = new CachingStream($this->stream); } } catch (ServiceException $ex) { return $this->returnError($ex->getMessage(), $flags); } } else { return $this->returnError('Unknown stream_open mode.', $flags); } if ($flags & STREAM_USE_PATH) { $openedPath = $path; } return true; } /** * Callback handler for when we try to read a certain number of bytes. * * @param int $count The number of bytes to read. * * @return string */ public function stream_read($count) { return $this->stream->read($count); } /** * Callback handler for when we try to write data to the stream. * * @param string $data The data to write * * @return int The number of bytes written. */ public function stream_write($data) { $result = $this->stream->write($data); $this->dirty = $this->dirty || (bool) $result; return $result; } /** * Callback handler for getting data about the stream. * * @return array */ public function stream_stat() { $mode = $this->stream->isWritable() ? self::FILE_WRITABLE_MODE : self::FILE_READABLE_MODE; return $this->makeStatArray([ 'mode' => $mode, 'size' => $this->stream->getSize() ]); } /** * Callback handler for checking to see if the stream is at the end of file. * * @return bool */ public function stream_eof() { return $this->stream->eof(); } /** * Callback handler for trying to close the stream. */ public function stream_close() { if (isset($this->stream)) { $this->stream->close(); } if ($this->composing) { if ($this->dirty) { $this->compose(); $this->dirty = false; } try { $this->bucket->object($this->file . self::TAIL_NAME_SUFFIX)->delete(); } catch (NotFoundException $e) { } $this->composing = false; } } /** * Callback handler for trying to seek to a certain location in the stream. * * @param int $offset The stream offset to seek to * @param int $whence Flag for what the offset is relative to. See: * http://php.net/manual/en/streamwrapper.stream-seek.php * @return bool */ public function stream_seek($offset, $whence = SEEK_SET) { if ($this->stream->isSeekable()) { $this->stream->seek($offset, $whence); return true; } return false; } /** * Callhack handler for inspecting our current position in the stream * * @return int */ public function stream_tell() { return $this->stream->tell(); } /** * Callback handler for trying to close an opened directory. * * @return bool */ public function dir_closedir() { return false; } /** * Callback handler for trying to open a directory. * * @param string $path The url directory to open * @param int $options Whether or not to enforce safe_mode * @return bool */ public function dir_opendir($path, $options) { $this->openPath($path); return $this->dir_rewinddir(); } /** * Callback handler for reading an entry from a directory handle. * * @return string|bool */ public function dir_readdir() { $name = $this->directoryIterator->current(); if ($name) { $this->directoryIterator->next(); return $name; } return false; } /** * Callback handler for rewind the directory handle. * * @return bool */ public function dir_rewinddir() { try { $iterator = $this->bucket->objects([ 'prefix' => $this->file, 'fields' => 'items/name,nextPageToken' ]); // The delimiter options do not give us what we need, so instead we // list all results matching the given prefix, enumerate the // iterator, filter and transform results, and yield a fresh // generator containing only the directory listing. $this->directoryIterator = call_user_func(function () use ($iterator) { $yielded = []; $pathLen = strlen($this->makeDirectory($this->file)); foreach ($iterator as $object) { $name = substr($object->name(), $pathLen); $parts = explode('/', $name); // since the service call returns nested results and we only // want to yield results directly within the requested directory, // check if we've already yielded this value. if ($parts[0] === '' || in_array($parts[0], $yielded)) { continue; } $yielded[] = $parts[0]; yield $name => $parts[0]; } }); } catch (ServiceException $e) { return false; } return true; } /** * Callback handler for trying to create a directory. If no file path is specified, * or STREAM_MKDIR_RECURSIVE option is set, then create the bucket if it does not exist. * * @param string $path The url directory to create * @param int $mode The permissions on the directory * @param int $options Bitwise mask of options. STREAM_MKDIR_RECURSIVE * @return bool */ public function mkdir($path, $mode, $options) { $path = $this->makeDirectory($path); $client = $this->openPath($path); $predefinedAcl = $this->determineAclFromMode($mode); try { if ($options & STREAM_MKDIR_RECURSIVE || $this->file == '') { if (!$this->bucket->exists()) { $client->createBucket($this->bucket->name(), [ 'predefinedAcl' => $predefinedAcl, 'predefinedDefaultObjectAcl' => $predefinedAcl ]); } } // If the file name is empty, we were trying to create a bucket. In this case, // don't create the placeholder file. if ($this->file != '') { $bucketInfo = $this->bucket->info(); $ublEnabled = isset($bucketInfo['iamConfiguration']['uniformBucketLevelAccess']) && $bucketInfo['iamConfiguration']['uniformBucketLevelAccess']['enabled'] === true; // if bucket has uniform bucket level access enabled, don't set ACLs. $acl = []; if (!$ublEnabled) { $acl = [ 'predefinedAcl' => $predefinedAcl ]; } // Fake a directory by creating an empty placeholder file whose name ends in '/' $this->bucket->upload('', [ 'name' => $this->file, ] + $acl); } } catch (ServiceException $e) { return false; } return true; } /** * Callback handler for trying to move a file or directory. * * @param string $from The URL to the current file * @param string $to The URL of the new file location * @return bool */ public function rename($from, $to) { $this->openPath($from); $destination = (array) parse_url($to) + [ 'path' => '', 'host' => '' ]; $destinationBucket = $destination['host']; $destinationPath = substr($destination['path'], 1); // loop through to rename file and children, if given path is a directory. $objects = $this->bucket->objects([ 'prefix' => $this->file ]); foreach ($objects as $obj) { $oldName = $obj->name(); $newPath = str_replace($this->file, $destinationPath, $oldName); try { $obj->rename($newPath, [ 'destinationBucket' => $destinationBucket ]); } catch (ServiceException $e) { return false; } } return true; } /** * Callback handler for trying to remove a directory or a bucket. If the path is empty * or '/', the bucket will be deleted. * * Note that the STREAM_MKDIR_RECURSIVE flag is ignored because the option cannot * be set via the `rmdir()` function. * * @param string $path The URL directory to remove. If the path is empty or is '/', * This will attempt to destroy the bucket. * @param int $options Bitwise mask of options. * @return bool */ public function rmdir($path, $options) { $path = $this->makeDirectory($path); $this->openPath($path); try { if ($this->file == '') { $this->bucket->delete(); return true; } else { return $this->unlink($path); } } catch (ServiceException $e) { return false; } } /** * Callback handler for retrieving the underlaying resource * * @param int $castAs STREAM_CAST_FOR_SELECT|STREAM_CAST_AS_STREAM * @return resource|bool */ public function stream_cast($castAs) { return false; } /** * Callback handler for deleting a file * * @param string $path The URL of the file to delete * @return bool */ public function unlink($path) { $client = $this->openPath($path); $object = $this->bucket->object($this->file); try { $object->delete(); return true; } catch (ServiceException $e) { return false; } } /** * Callback handler for retrieving information about a file * * @param string $path The URI to the file * @param int $flags Bitwise mask of options * @return array|bool */ public function url_stat($path, $flags) { $client = $this->openPath($path); // if directory $dir = $this->getDirectoryInfo($this->file); if ($dir) { return $this->urlStatDirectory($dir); } return $this->urlStatFile(); } /** * Callback handler for fflush() function. * * @return bool */ public function stream_flush() { if (!$this->flushing) { return false; } if (!$this->dirty) { return true; } if (isset($this->stream)) { $this->stream->close(); } if ($this->composing) { $this->compose(); } $options = $this->options; $this->stream = new WriteStream(null, $options); $this->stream->setUploader( $this->bucket->getStreamableUploader( $this->stream, $options + ['name' => $this->file . self::TAIL_NAME_SUFFIX] ) ); $this->composing = true; $this->dirty = false; return true; } /** * Parse the URL and set protocol, filename and bucket. * * @param string $path URL to open * @return StorageClient */ private function openPath($path) { $url = (array) parse_url($path) + [ 'scheme' => '', 'path' => '', 'host' => '' ]; $this->protocol = $url['scheme']; $this->file = ltrim($url['path'], '/'); $client = self::getClient($this->protocol); $this->bucket = $client->bucket($url['host']); return $client; } /** * Given a path, ensure that we return a path that looks like a directory * * @param string $path * @return string */ private function makeDirectory($path) { if ($path == '' or $path == '/') { return ''; } if (substr($path, -1) == '/') { return $path; } return $path . '/'; } /** * Calculate the `url_stat` response for a directory * * @return array|bool */ private function urlStatDirectory(StorageObject $object) { $stats = []; $info = $object->info(); // equivalent to 40777 and 40444 in octal $stats['mode'] = $this->bucket->isWritable() ? self::DIRECTORY_WRITABLE_MODE : self::DIRECTORY_READABLE_MODE; $this->statsFromFileInfo($info, $stats); return $this->makeStatArray($stats); } /** * Calculate the `url_stat` response for a file * * @return array|bool */ private function urlStatFile() { try { $this->object = $this->bucket->object($this->file); $info = $this->object->info(); } catch (ServiceException $e) { // couldn't stat file return false; } // equivalent to 100666 and 100444 in octal $stats = [ 'mode' => $this->bucket->isWritable() ? self::FILE_WRITABLE_MODE : self::FILE_READABLE_MODE ]; $this->statsFromFileInfo($info, $stats); return $this->makeStatArray($stats); } /** * Given a `StorageObject` info array, extract the available fields into the * provided `$stats` array. * * @param array $info Array provided from a `StorageObject`. * @param array $stats Array to put the calculated stats into. */ private function statsFromFileInfo(array &$info, array &$stats) { $stats['size'] = (isset($info['size'])) ? (int) $info['size'] : null; $stats['mtime'] = (isset($info['updated'])) ? strtotime($info['updated']) : null; $stats['ctime'] = (isset($info['timeCreated'])) ? strtotime($info['timeCreated']) : null; } /** * Get the given path as a directory. * * In list objects calls, directories are returned with a trailing slash. By * providing the given path with a trailing slash as a list prefix, we can * check whether the given path exists as a directory. * * If the path does not exist or is not a directory, return null. * * @param string $path * @return StorageObject|null */ private function getDirectoryInfo($path) { $scan = $this->bucket->objects([ 'prefix' => $this->makeDirectory($path), 'resultLimit' => 1, 'fields' => 'items/name,items/size,items/updated,items/timeCreated,nextPageToken' ]); return $scan->current(); } /** * Returns the associative array that a `stat()` response expects using the * provided stats. Defaults the remaining fields to 0. * * @param array $stats Sparse stats entries to set. * @return array */ private function makeStatArray($stats) { return array_merge( array_fill_keys([ 'dev', 'ino', 'mode', 'nlink', 'uid', 'gid', 'rdev', 'size', 'atime', 'mtime', 'ctime', 'blksize', 'blocks' ], 0), $stats ); } /** * Helper for whether or not to trigger an error or just return false on an error. * * @param string $message The PHP error message to emit. * @param int $flags Bitwise mask of options (STREAM_REPORT_ERRORS) * @return bool Returns false */ private function returnError($message, $flags) { if ($flags & STREAM_REPORT_ERRORS) { trigger_error($message, E_USER_WARNING); } return false; } /** * Helper for determining which predefinedAcl to use given a mode. * * @param int $mode Decimal representation of the file system permissions * @return string */ private function determineAclFromMode($mode) { if ($mode & 0004) { // If any user can read, assume it should be publicRead. return 'publicRead'; } elseif ($mode & 0040) { // If any group user can read, assume it should be projectPrivate. return 'projectPrivate'; } // Otherwise, assume only the project/bucket owner can use the bucket. return 'private'; } private function compose() { if (!isset($this->contentType)) { $info = $this->bucket->object($this->file)->info(); $this->contentType = $info['contentType'] ?: 'application/octet-stream'; } $options = ['destination' => ['contentType' => $this->contentType]]; $this->bucket->compose([$this->file, $this->file . self::TAIL_NAME_SUFFIX], $this->file, $options); } } ================================================ FILE: lib/Google/vendor/google/cloud-storage/src/WriteStream.php ================================================ setUploader($uploader); } if (array_key_exists('chunkSize', $options)) { $this->chunkSize = $options['chunkSize']; } $this->stream = new BufferStream($this->chunkSize); } /** * Close the stream. Uploads any remaining data. */ public function close(): void { if ($this->uploader && $this->hasWritten) { $this->uploader->upload(); $this->uploader = null; } } /** * Write to the stream. If we pass the chunkable size, upload the available chunk. * * @param string $data Data to write * @return int The number of bytes written * @throws \RuntimeException */ public function write($data): int { if (!isset($this->uploader)) { throw new \RuntimeException('No uploader set.'); } // Ensure we have a resume uri here because we need to create the streaming // upload before we have data (size of 0). $this->uploader->getResumeUri(); $this->hasWritten = true; if (!$this->stream->write($data)) { $this->uploader->upload($this->getChunkedWriteSize()); } return strlen($data); } /** * Set the uploader for this class. You may need to set this after initialization * if the uploader depends on this stream. * * @param AbstractUploader $uploader The new uploader to use. */ public function setUploader($uploader): void { $this->uploader = $uploader; } private function getChunkedWriteSize(): int { return (int) floor($this->getSize() / $this->chunkSize) * $this->chunkSize; } } ================================================ FILE: lib/Google/vendor/google/common-protos/CHANGELOG.md ================================================ # Changelog ## [4.5.0](https://github.com/googleapis/common-protos-php/compare/v4.4.0...v4.5.0) (2023-11-29) ### Features * Add auto_populated_fields to google.api.MethodSettings ([#74](https://github.com/googleapis/common-protos-php/issues/74)) ([d739417](https://github.com/googleapis/common-protos-php/commit/d7394176eb95f0e92af4e93746dba8f515ba9bc2)) ## [4.4.0](https://github.com/googleapis/common-protos-php/compare/v4.3.0...v4.4.0) (2023-10-02) ### Features * Public google.api.FieldInfo type and extension ([#71](https://github.com/googleapis/common-protos-php/issues/71)) ([4002074](https://github.com/googleapis/common-protos-php/commit/40020744c65e7561dec08e1cd2994afcc51ec771)) ## [4.3.0](https://github.com/googleapis/common-protos-php/compare/v4.2.0...v4.3.0) (2023-08-22) ### Features * Add new FieldBehavior value IDENTIFIER ([#67](https://github.com/googleapis/common-protos-php/issues/67)) ([6c6c21f](https://github.com/googleapis/common-protos-php/commit/6c6c21fc4a2f4711aeddad11082ed17acaf4733c)) ## [4.2.0](https://github.com/googleapis/common-protos-php/compare/v4.1.0...v4.2.0) (2023-07-25) ### Features * Add a proto message to describe the `resource_type` and `resource_permission` for an API method ([#64](https://github.com/googleapis/common-protos-php/issues/64)) ([8a0ff5f](https://github.com/googleapis/common-protos-php/commit/8a0ff5f9ffcf3683fc4718e85e97f45a001a1925)) ## [4.1.0](https://github.com/googleapis/common-protos-php/compare/v4.0.0...v4.1.0) (2023-05-06) ### Features * Add ConfigServiceV2.CreateBucketAsync method for creating Log Buckets asynchronously ([b18d554](https://github.com/googleapis/common-protos-php/commit/b18d55421cbe1e55d62b5d149e56be23db8c4286)) * Add ConfigServiceV2.CreateLink method for creating linked datasets for Log Analytics Buckets ([b18d554](https://github.com/googleapis/common-protos-php/commit/b18d55421cbe1e55d62b5d149e56be23db8c4286)) * Add ConfigServiceV2.DeleteLink method for deleting linked datasets ([b18d554](https://github.com/googleapis/common-protos-php/commit/b18d55421cbe1e55d62b5d149e56be23db8c4286)) * Add ConfigServiceV2.GetLink methods for describing linked datasets ([b18d554](https://github.com/googleapis/common-protos-php/commit/b18d55421cbe1e55d62b5d149e56be23db8c4286)) * Add ConfigServiceV2.ListLinks method for listing linked datasets ([b18d554](https://github.com/googleapis/common-protos-php/commit/b18d55421cbe1e55d62b5d149e56be23db8c4286)) * Add ConfigServiceV2.UpdateBucketAsync method for creating Log Buckets asynchronously ([b18d554](https://github.com/googleapis/common-protos-php/commit/b18d55421cbe1e55d62b5d149e56be23db8c4286)) * Add LogBucket.analytics_enabled field that specifies whether Log Bucket's Analytics features are enabled ([b18d554](https://github.com/googleapis/common-protos-php/commit/b18d55421cbe1e55d62b5d149e56be23db8c4286)) * Add LogBucket.index_configs field that contains a list of Log Bucket's indexed fields and related configuration data ([b18d554](https://github.com/googleapis/common-protos-php/commit/b18d55421cbe1e55d62b5d149e56be23db8c4286)) * Log Analytics features of the Cloud Logging API ([#60](https://github.com/googleapis/common-protos-php/issues/60)) ([b18d554](https://github.com/googleapis/common-protos-php/commit/b18d55421cbe1e55d62b5d149e56be23db8c4286)) ## [4.0.0](https://github.com/googleapis/common-protos-php/compare/v3.2.0...v4.0.0) (2023-05-01) ### ⚠ BREAKING CHANGES * remove files unknown to owlbot ([#59](https://github.com/googleapis/common-protos-php/issues/59)) * add owlbot automated updates ([#54](https://github.com/googleapis/common-protos-php/issues/54)) ### Features * Add owlbot automated updates ([#54](https://github.com/googleapis/common-protos-php/issues/54)) ([6d9134d](https://github.com/googleapis/common-protos-php/commit/6d9134d2f927e9c4aa3165e823477e25ef8ff38f)) * Regenerate all common protos from new owlbot config ([#58](https://github.com/googleapis/common-protos-php/issues/58)) ([5dac653](https://github.com/googleapis/common-protos-php/commit/5dac653bdd60c4dbaec45e73e0ec487e5aeac9b1)) ### Miscellaneous Chores * Remove files unknown to owlbot ([#59](https://github.com/googleapis/common-protos-php/issues/59)) ([f541342](https://github.com/googleapis/common-protos-php/commit/f54134263a142e278c56f5e03e5a3d8c6f72aac3)) ## [3.2.0](https://github.com/googleapis/common-protos-php/compare/v3.1.0...v3.2.0) (2023-01-12) ### Features * Refresh types ([#49](https://github.com/googleapis/common-protos-php/issues/49)) ([bd71fc0](https://github.com/googleapis/common-protos-php/commit/bd71fc05cbca1ccd94b71a42c227f0d69c688f07)) ## [3.1.0](https://github.com/googleapis/common-protos-php/compare/v3.0.0...v3.1.0) (2022-10-05) ### Features * Make autoloader more efficient ([#45](https://github.com/googleapis/common-protos-php/issues/45)) ([cdff58a](https://github.com/googleapis/common-protos-php/commit/cdff58a3ff6c42e461f18f14c0bbd8e171456924)) ## [3.0.0](https://github.com/googleapis/common-protos-php/compare/2.1.0...v3.0.0) (2022-07-29) ### ⚠ BREAKING CHANGES * remove longrunning classes from common protos (#41) ### Miscellaneous Chores * remove longrunning classes from common protos ([#41](https://github.com/googleapis/common-protos-php/issues/41)) ([e88dd1d](https://github.com/googleapis/common-protos-php/commit/e88dd1d5dfef93358dc0bd7f3d62d09bbfd750b6)) ================================================ FILE: lib/Google/vendor/google/common-protos/CODE_OF_CONDUCT.md ================================================ # Contributor Code of Conduct As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities. We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality. Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery * Personal attacks * Trolling or insulting/derogatory comments * Public or private harassment * Publishing other's private information, such as physical or electronic addresses, without explicit permission * Other unethical or unprofessional conduct. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team. This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers. This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0, available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/) ================================================ FILE: lib/Google/vendor/google/common-protos/CONTRIBUTING.md ================================================ ## Contributing We are pleased that you are interested in contributing to our work. ### Generated Protocol Buffer Classes The classes in this repository are generated by the protocol buffer compiler, as known as protoc. As such, we can not accept contributions directly to these generated classes. Instead, changes should be suggested upstream in the [API Common Protos][api-common-protos] repository. ### Documentation We want for both protocol buffers and the types that we have provided here to be understandable to everyone, including to those who may be unfamiliar with the ecosystem or concepts. That means we want our documentation to be better, and welcome anyone willing to help with this. For documentation in the generated classes, please open a pull request against the [API Common Protos][api-common-protos] repository. Any improvements to READMEs or other non-generated documentation or development scripts in this repository would be greatly appreciated - please open a pull request. ## Contributor License Agreement Before we can accept your pull requests, you will need to sign a Contributor License Agreement (CLA): - **If you are an individual writing original source code** and **you own the intellectual property**, then you need to sign an [individual CLA][]. - **If you work for a company that wants to allow you to contribute your work**, then you need to sign a [corporate CLA][]. You can sign these electronically (just scroll to the bottom). After that, we'll be able to accept your pull requests. [individual CLA]: https://developers.google.com/open-source/cla/individual [corporate CLA]: https://developers.google.com/open-source/cla/corporate [api-common-protos]: https://github.com/googleapis/api-common-protos ================================================ FILE: lib/Google/vendor/google/common-protos/LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: lib/Google/vendor/google/common-protos/README.md ================================================ ## Common Protos PHP [![Latest Stable Version](https://poser.pugx.org/google/common-protos/v/stable)](https://packagist.org/packages/google/common-protos) [![Packagist](https://img.shields.io/packagist/dm/google/common-protos.svg)](https://packagist.org/packages/google/common-protos) * [API documentation](https://cloud.google.com/php/docs/reference/common-protos/latest) This repository is a home for the [protocol buffer][protobuf] types which are common dependencies throughout the Google API ecosystem, generated for PHP. The protobuf definitions for these generated PHP classes are provided by the [Common Components AIP][common-components-aip] repository. **NOTE:** This repository is part of [Google Cloud PHP](https://github.com/googleapis/google-cloud-php). Any support requests, bug reports, or development contributions should be directed to that project. ## Using these generated classes These classes are made available under an Apache license (see `LICENSE`) and you are free to depend on them within your applications. They are considered stable and will not change in backwards-incompaible ways. They are distributed as the [google/common-protos][packagist-common-protos] composer package, available on [Packagist][packagist]. In order to depend on these classes, use composer from the command line in order to add this package to your `composer.json` file in the `requires` section: ```bash composer require google/common-protos ``` ## License These classes are licensed using the Apache 2.0 software license, a permissive, copyfree license. You are free to use them in your applications provided the license terms are honored. [protobuf]: https://developers.google.com/protocol-buffers/ [common-components-aip]: https://google.aip.dev/213 [packagist-common-protos]: https://packagist.org/packages/google/common-protos/ [packagist]: https://packagist.org/ ================================================ FILE: lib/Google/vendor/google/common-protos/SECURITY.md ================================================ # Security Policy To report a security issue, please use [g.co/vulnz](https://g.co/vulnz). The Google Security Team will respond within 5 working days of your report on g.co/vulnz. We use g.co/vulnz for our intake, and do coordination and disclosure here using GitHub Security Advisory to privately discuss and fix the issue. ================================================ FILE: lib/Google/vendor/google/common-protos/VERSION ================================================ 4.12.4 ================================================ FILE: lib/Google/vendor/google/common-protos/composer.json ================================================ { "name": "google/common-protos", "type": "library", "description": "Google API Common Protos for PHP", "version": "4.12.4", "keywords": [ "google" ], "homepage": "https://github.com/googleapis/common-protos-php", "license": "Apache-2.0", "require": { "php": "^8.1", "google/protobuf": "^4.31" }, "require-dev": { "phpunit/phpunit": "^9.6" }, "autoload": { "psr-4": { "Google\\Api\\": "src/Api", "Google\\Cloud\\": "src/Cloud", "Google\\Iam\\": "src/Iam", "Google\\Rpc\\": "src/Rpc", "Google\\Type\\": "src/Type", "GPBMetadata\\Google\\Api\\": "metadata/Api", "GPBMetadata\\Google\\Cloud\\": "metadata/Cloud", "GPBMetadata\\Google\\Iam\\": "metadata/Iam", "GPBMetadata\\Google\\Logging\\": "metadata/Logging", "GPBMetadata\\Google\\Rpc\\": "metadata/Rpc", "GPBMetadata\\Google\\Type\\": "metadata/Type" } }, "extra": { "component": { "id": "common-protos", "target": "googleapis/common-protos-php.git", "path": "CommonProtos", "entry": "README.md" } } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Api/Annotations.php ================================================ internalAddGeneratedFile( '  google/api/annotations.proto google.api google/protobuf/descriptor.protoBn com.google.apiBAnnotationsProtoPZAgoogle.golang.org/genproto/googleapis/api/annotations;annotationsGAPIbproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Api/Billing.php ================================================ internalAddGeneratedFile( '  google/api/billing.proto google.api" BillingE consumer_destinations ( 2&.google.api.Billing.BillingDestinationA BillingDestination monitored_resource (  metrics ( Bn com.google.apiB BillingProtoPZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfigGAPIbproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Api/Context.php ================================================ internalAddGeneratedFile( '  google/api/context.proto google.api"1 Context& rules ( 2.google.api.ContextRule" ContextRule selector (  requested (  provided ( " allowed_request_extensions ( # allowed_response_extensions ( Bn com.google.apiB ContextProtoPZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfigGAPIbproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Api/Control.php ================================================ internalAddGeneratedFile( '  google/api/control.proto google.api"Q Control environment ( 1 method_policies ( 2.google.api.MethodPolicyBn com.google.apiB ControlProtoPZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfigGAPIbproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Api/Documentation.php ================================================ internalAddGeneratedFile( '  google/api/documentation.proto google.api" Documentation summary (  pages ( 2.google.api.Page, rules ( 2.google.api.DocumentationRule documentation_root_url (  service_root_url (  overview ( "[ DocumentationRule selector (  description (  deprecation_description ( "I Page name (  content ( " subpages ( 2.google.api.PageBt com.google.apiBDocumentationProtoPZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfigGAPIbproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Api/Endpoint.php ================================================ internalAddGeneratedFile( '  google/api/endpoint.proto google.api"M Endpoint name (  aliases (  targete (  allow_cors (Bo com.google.apiB EndpointProtoPZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfigGAPIbproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Api/Httpbody.php ================================================ internalAddGeneratedFile( '  google/api/httpbody.proto google.api"X HttpBody content_type (  data ( ( extensions ( 2.google.protobuf.AnyBe com.google.apiB HttpBodyProtoPZ;google.golang.org/genproto/googleapis/api/httpbody;httpbodyGAPIbproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Api/Log.php ================================================ internalAddGeneratedFile( '  google/api/log.proto google.api"u LogDescriptor name ( + labels ( 2.google.api.LabelDescriptor description (  display_name ( Bj com.google.apiBLogProtoPZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfigGAPIbproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Api/Logging.php ================================================ internalAddGeneratedFile( '  google/api/logging.proto google.api" LoggingE producer_destinations ( 2&.google.api.Logging.LoggingDestinationE consumer_destinations ( 2&.google.api.Logging.LoggingDestination> LoggingDestination monitored_resource (  logs ( Bn com.google.apiB LoggingProtoPZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfigGAPIbproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Api/MonitoredResource.php ================================================ internalAddGeneratedFile( '  #google/api/monitored_resource.proto google.apigoogle/api/launch_stage.protogoogle/protobuf/struct.proto" MonitoredResourceDescriptor name (  type (  display_name (  description ( + labels ( 2.google.api.LabelDescriptor- launch_stage (2.google.api.LaunchStage" MonitoredResource type ( 9 labels ( 2).google.api.MonitoredResource.LabelsEntry- LabelsEntry key (  value ( :8" MonitoredResourceMetadata. system_labels ( 2.google.protobuf.StructJ user_labels ( 25.google.api.MonitoredResourceMetadata.UserLabelsEntry1 UserLabelsEntry key (  value ( :8Bv com.google.apiBMonitoredResourceProtoPZCgoogle.golang.org/genproto/googleapis/api/monitoredres;monitoredresGAPIbproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Api/Monitoring.php ================================================ internalAddGeneratedFile( '  google/api/monitoring.proto google.api" MonitoringK producer_destinations ( 2,.google.api.Monitoring.MonitoringDestinationK consumer_destinations ( 2,.google.api.Monitoring.MonitoringDestinationD MonitoringDestination monitored_resource (  metrics ( Bq com.google.apiBMonitoringProtoPZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfigGAPIbproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Api/Policy.php ================================================ internalAddGeneratedFile( '  google/api/policy.proto google.api google/protobuf/descriptor.proto"S FieldPolicy selector (  resource_permission (  resource_type ( "S MethodPolicy selector ( 1 request_policies ( 2.google.api.FieldPolicyBm com.google.apiB PolicyProtoPZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfigGAPIbproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Api/Quota.php ================================================ internalAddGeneratedFile( '  google/api/quota.proto google.api"] Quota& limits ( 2.google.api.QuotaLimit, metric_rules ( 2.google.api.MetricRule" MetricRule selector ( = metric_costs ( 2\'.google.api.MetricRule.MetricCostsEntry2 MetricCostsEntry key (  value (:8" QuotaLimit name (  description (  default_limit ( max_limit ( free_tier ( duration (  metric (  unit ( 2 values ( 2".google.api.QuotaLimit.ValuesEntry display_name ( - ValuesEntry key (  value (:8Bl com.google.apiB QuotaProtoPZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfigGAPIbproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Api/Routing.php ================================================ internalAddGeneratedFile( '  google/api/routing.proto google.api google/protobuf/descriptor.proto"G RoutingRule8 routing_parameters ( 2.google.api.RoutingParameter"8 RoutingParameter field (  path_template ( Bj com.google.apiB RoutingProtoPZAgoogle.golang.org/genproto/googleapis/api/annotations;annotationsGAPIbproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Api/Service.php ================================================ internalAddGeneratedFile( ' google/api/service.proto google.apigoogle/api/backend.protogoogle/api/billing.protogoogle/api/client.protogoogle/api/context.protogoogle/api/control.protogoogle/api/documentation.protogoogle/api/endpoint.protogoogle/api/http.protogoogle/api/log.protogoogle/api/logging.protogoogle/api/metric.proto#google/api/monitored_resource.protogoogle/api/monitoring.protogoogle/api/quota.protogoogle/api/source_info.proto!google/api/system_parameter.protogoogle/api/usage.protogoogle/protobuf/api.protogoogle/protobuf/type.protogoogle/protobuf/wrappers.proto" Service name (  title (  producer_project_id (  id! ( " apis ( 2.google.protobuf.Api$ types ( 2.google.protobuf.Type$ enums ( 2.google.protobuf.Enum0 documentation ( 2.google.api.Documentation$ backend ( 2.google.api.Backend http ( 2.google.api.Http quota ( 2.google.api.Quota2 authentication ( 2.google.api.Authentication$ context ( 2.google.api.Context usage ( 2.google.api.Usage\' endpoints ( 2.google.api.Endpoint$ control ( 2.google.api.Control\' logs ( 2.google.api.LogDescriptor- metrics ( 2.google.api.MetricDescriptorD monitored_resources ( 2\'.google.api.MonitoredResourceDescriptor$ billing ( 2.google.api.Billing$ logging ( 2.google.api.Logging* monitoring ( 2.google.api.Monitoring7 system_parameters ( 2.google.api.SystemParameters+ source_info% ( 2.google.api.SourceInfo* publishing- ( 2.google.api.Publishing4 config_version ( 2.google.protobuf.UInt32ValueBn com.google.apiB ServiceProtoPZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfigGAPIbproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Api/SourceInfo.php ================================================ internalAddGeneratedFile( '  google/api/source_info.proto google.api"8 SourceInfo* source_files ( 2.google.protobuf.AnyBq com.google.apiBSourceInfoProtoPZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfigGAPIbproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Api/SystemParameter.php ================================================ internalAddGeneratedFile( '  !google/api/system_parameter.proto google.api"B SystemParameters. rules ( 2.google.api.SystemParameterRule"X SystemParameterRule selector ( / parameters ( 2.google.api.SystemParameter"Q SystemParameter name (  http_header (  url_query_parameter ( Bv com.google.apiBSystemParameterProtoPZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfigGAPIbproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Api/Usage.php ================================================ internalAddGeneratedFile( '  google/api/usage.proto google.api"j Usage requirements ( $ rules ( 2.google.api.UsageRule% producer_notification_channel ( "] UsageRule selector (  allow_unregistered_calls ( skip_service_control (Bl com.google.apiB UsageProtoPZEgoogle.golang.org/genproto/googleapis/api/serviceconfig;serviceconfigGAPIbproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Api/Visibility.php ================================================ internalAddGeneratedFile( '  google/api/visibility.proto google.api google/protobuf/descriptor.proto"7 Visibility) rules ( 2.google.api.VisibilityRule"7 VisibilityRule selector (  restriction ( Bk com.google.apiBVisibilityProtoPZ?google.golang.org/genproto/googleapis/api/visibility;visibilityGAPIbproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Cloud/Location/Locations.php ================================================ internalAddGeneratedFile( '  %google/cloud/location/locations.protogoogle.cloud.locationgoogle/protobuf/any.protogoogle/api/client.proto"[ ListLocationsRequest name (  filter (  page_size ( page_token ( "d ListLocationsResponse2 locations ( 2.google.cloud.location.Location next_page_token ( "" GetLocationRequest name ( " Location name (  location_id (  display_name ( ; labels ( 2+.google.cloud.location.Location.LabelsEntry& metadata ( 2.google.protobuf.Any- LabelsEntry key (  value ( :82 Locations ListLocations+.google.cloud.location.ListLocationsRequest,.google.cloud.location.ListLocationsResponse"?9/v1/{name=locations}Z!/v1/{name=projects/*}/locations GetLocation).google.cloud.location.GetLocationRequest.google.cloud.location.Location"C=/v1/{name=locations/*}Z#!/v1/{name=projects/*/locations/*}HAcloud.googleapis.comA.https://www.googleapis.com/auth/cloud-platformBo com.google.cloud.locationBLocationsProtoPZ=google.golang.org/genproto/googleapis/cloud/location;locationbproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Google/Iam/V1/IamPolicy.php ================================================ internalAddGeneratedFile( ' google/iam/v1/iam_policy.proto google.iam.v1google/api/client.protogoogle/api/field_behavior.protogoogle/api/resource.protogoogle/iam/v1/options.protogoogle/iam/v1/policy.proto google/protobuf/field_mask.proto" SetIamPolicyRequest resource ( B AA ** policy ( 2.google.iam.v1.PolicyBA/ update_mask ( 2.google.protobuf.FieldMask"d GetIamPolicyRequest resource ( B AA *0 options ( 2.google.iam.v1.GetPolicyOptions"R TestIamPermissionsRequest resource ( B AA * permissions ( BA"1 TestIamPermissionsResponse permissions ( 2 IAMPolicyt SetIamPolicy".google.iam.v1.SetIamPolicyRequest.google.iam.v1.Policy")#"/v1/{resource=**}:setIamPolicy:*t GetIamPolicy".google.iam.v1.GetIamPolicyRequest.google.iam.v1.Policy")#"/v1/{resource=**}:getIamPolicy:* TestIamPermissions(.google.iam.v1.TestIamPermissionsRequest).google.iam.v1.TestIamPermissionsResponse"/)"$/v1/{resource=**}:testIamPermissions:*Aiam-meta-api.googleapis.comB| com.google.iam.v1BIamPolicyProtoPZ)cloud.google.com/go/iam/apiv1/iampb;iampbGoogle.Cloud.Iam.V1Google\\Cloud\\Iam\\V1bproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Google/Iam/V1/Logging/AuditData.php ================================================ internalAddGeneratedFile( '  &google/iam/v1/logging/audit_data.protogoogle.iam.v1.logging"= AuditData0 policy_delta ( 2.google.iam.v1.PolicyDeltaB com.google.iam.v1.loggingBAuditDataProtoPZ9cloud.google.com/go/iam/apiv1/logging/loggingpb;loggingpbGoogle.Cloud.Iam.V1.Loggingbproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Google/Iam/V1/Options.php ================================================ internalAddGeneratedFile( '  google/iam/v1/options.proto google.iam.v1"4 GetPolicyOptions requested_policy_version (B} com.google.iam.v1B OptionsProtoPZ)cloud.google.com/go/iam/apiv1/iampb;iampbGoogle.Cloud.Iam.V1Google\\Cloud\\Iam\\V1bproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Google/Iam/V1/ResourcePolicyMember.php ================================================ internalAddGeneratedFile( '  *google/iam/v1/resource_policy_member.proto google.iam.v1"e ResourcePolicyMember& iam_policy_name_principal ( BA% iam_policy_uid_principal ( BAB com.google.iam.v1BResourcePolicyMemberProtoPZ)cloud.google.com/go/iam/apiv1/iampb;iampbGoogle.Cloud.Iam.V1Google\\Cloud\\Iam\\V1bproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Google/Logging/Type/HttpRequest.php ================================================ internalAddGeneratedFile( '  &google/logging/type/http_request.protogoogle.logging.type" HttpRequest request_method (  request_url (  request_size ( status ( response_size ( user_agent (  remote_ip (  server_ip (  referer ( * latency ( 2.google.protobuf.Duration cache_lookup ( cache_hit (* "cache_validated_with_origin_server ( cache_fill_bytes ( protocol ( B com.google.logging.typeBHttpRequestProtoPZ8google.golang.org/genproto/googleapis/logging/type;ltypeGoogle.Cloud.Logging.TypeGoogle\\Cloud\\Logging\\TypeGoogle::Cloud::Logging::Typebproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Iam/V1/IamPolicy.php ================================================ internalAddGeneratedFile( ' google/iam/v1/iam_policy.proto google.iam.v1google/api/client.protogoogle/api/field_behavior.protogoogle/api/resource.protogoogle/iam/v1/options.protogoogle/iam/v1/policy.proto google/protobuf/field_mask.proto" SetIamPolicyRequest resource ( B AA ** policy ( 2.google.iam.v1.PolicyBA/ update_mask ( 2.google.protobuf.FieldMask"d GetIamPolicyRequest resource ( B AA *0 options ( 2.google.iam.v1.GetPolicyOptions"R TestIamPermissionsRequest resource ( B AA * permissions ( BA"1 TestIamPermissionsResponse permissions ( 2 IAMPolicyt SetIamPolicy".google.iam.v1.SetIamPolicyRequest.google.iam.v1.Policy")#"/v1/{resource=**}:setIamPolicy:*t GetIamPolicy".google.iam.v1.GetIamPolicyRequest.google.iam.v1.Policy")#"/v1/{resource=**}:getIamPolicy:* TestIamPermissions(.google.iam.v1.TestIamPermissionsRequest).google.iam.v1.TestIamPermissionsResponse"/)"$/v1/{resource=**}:testIamPermissions:*Aiam-meta-api.googleapis.comB| com.google.iam.v1BIamPolicyProtoPZ)cloud.google.com/go/iam/apiv1/iampb;iampbGoogle.Cloud.Iam.V1Google\\Cloud\\Iam\\V1bproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Iam/V1/Logging/AuditData.php ================================================ internalAddGeneratedFile( '  &google/iam/v1/logging/audit_data.protogoogle.iam.v1.logging"= AuditData0 policy_delta ( 2.google.iam.v1.PolicyDeltaB com.google.iam.v1.loggingBAuditDataProtoPZ9cloud.google.com/go/iam/apiv1/logging/loggingpb;loggingpbGoogle.Cloud.Iam.V1.Loggingbproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Iam/V1/Options.php ================================================ internalAddGeneratedFile( '  google/iam/v1/options.proto google.iam.v1"4 GetPolicyOptions requested_policy_version (B} com.google.iam.v1B OptionsProtoPZ)cloud.google.com/go/iam/apiv1/iampb;iampbGoogle.Cloud.Iam.V1Google\\Cloud\\Iam\\V1bproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Iam/V1/ResourcePolicyMember.php ================================================ internalAddGeneratedFile( '  *google/iam/v1/resource_policy_member.proto google.iam.v1"e ResourcePolicyMember& iam_policy_name_principal ( BA% iam_policy_uid_principal ( BAB com.google.iam.v1BResourcePolicyMemberProtoPZ)cloud.google.com/go/iam/apiv1/iampb;iampbGoogle.Cloud.Iam.V1Google\\Cloud\\Iam\\V1bproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Logging/Type/HttpRequest.php ================================================ internalAddGeneratedFile( '  &google/logging/type/http_request.protogoogle.logging.type" HttpRequest request_method (  request_url (  request_size ( status ( response_size ( user_agent (  remote_ip (  server_ip (  referer ( * latency ( 2.google.protobuf.Duration cache_lookup ( cache_hit (* "cache_validated_with_origin_server ( cache_fill_bytes ( protocol ( B com.google.logging.typeBHttpRequestProtoPZ8google.golang.org/genproto/googleapis/logging/type;ltypeGoogle.Cloud.Logging.TypeGoogle\\Cloud\\Logging\\TypeGoogle::Cloud::Logging::Typebproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Rpc/Context/AttributeContext.php ================================================ internalAddGeneratedFile( '  *google/rpc/context/attribute_context.protogoogle.rpc.contextgoogle/protobuf/duration.protogoogle/protobuf/struct.protogoogle/protobuf/timestamp.proto" AttributeContext9 origin ( 2).google.rpc.context.AttributeContext.Peer9 source ( 2).google.rpc.context.AttributeContext.Peer> destination ( 2).google.rpc.context.AttributeContext.Peer= request ( 2,.google.rpc.context.AttributeContext.Request? response ( 2-.google.rpc.context.AttributeContext.Response? resource ( 2-.google.rpc.context.AttributeContext.Resource5 api ( 2(.google.rpc.context.AttributeContext.Api( extensions ( 2.google.protobuf.Any Peer ip (  port (E labels ( 25.google.rpc.context.AttributeContext.Peer.LabelsEntry principal (  region_code ( - LabelsEntry key (  value ( :8L Api service (  operation (  protocol (  version (  Auth principal (  audiences (  presenter ( \' claims ( 2.google.protobuf.Struct access_levels (  Request id (  method ( J headers ( 29.google.rpc.context.AttributeContext.Request.HeadersEntry path (  host (  scheme (  query ( ( time ( 2.google.protobuf.Timestamp size ( protocol (  reason ( 7 auth ( 2).google.rpc.context.AttributeContext.Auth. HeadersEntry key (  value ( :8 Response code ( size (K headers ( 2:.google.rpc.context.AttributeContext.Response.HeadersEntry( time ( 2.google.protobuf.Timestamp2 backend_latency ( 2.google.protobuf.Duration. HeadersEntry key (  value ( :8 Resource service (  name (  type ( I labels ( 29.google.rpc.context.AttributeContext.Resource.LabelsEntry uid ( S annotations ( 2>.google.rpc.context.AttributeContext.Resource.AnnotationsEntry display_name ( / create_time ( 2.google.protobuf.Timestamp/ update_time ( 2.google.protobuf.Timestamp/ delete_time ( 2.google.protobuf.Timestamp etag (  location ( - LabelsEntry key (  value ( :82 AnnotationsEntry key (  value ( :8B com.google.rpc.contextBAttributeContextProtoPZUgoogle.golang.org/genproto/googleapis/rpc/context/attribute_context;attribute_contextbproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Rpc/Context/AuditContext.php ================================================ internalAddGeneratedFile( '  &google/rpc/context/audit_context.protogoogle.rpc.context" AuditContext audit_log ( 1 scrubbed_request ( 2.google.protobuf.Struct2 scrubbed_response ( 2.google.protobuf.Struct$ scrubbed_response_item_count ( target_resource ( Bh com.google.rpc.contextBAuditContextProtoPZ9google.golang.org/genproto/googleapis/rpc/context;contextbproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Rpc/Status.php ================================================ internalAddGeneratedFile( '  google/rpc/status.proto google.rpc"N Status code ( message ( % details ( 2.google.protobuf.AnyBa com.google.rpcB StatusProtoPZ7google.golang.org/genproto/googleapis/rpc/status;statusRPCbproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Type/Color.php ================================================ internalAddGeneratedFile( '  google/type/color.proto google.type"] Color red ( green ( blue (* alpha ( 2.google.protobuf.FloatValueB` com.google.typeB ColorProtoPZ6google.golang.org/genproto/googleapis/type/color;colorGTPbproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Type/Date.php ================================================ internalAddGeneratedFile( '  google/type/date.proto google.type"0 Date year ( month ( day (B] com.google.typeB DateProtoPZ4google.golang.org/genproto/googleapis/type/date;dateGTPbproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Type/Decimal.php ================================================ internalAddGeneratedFile( '  google/type/decimal.proto google.type" Decimal value ( Bf com.google.typeB DecimalProtoPZ:google.golang.org/genproto/googleapis/type/decimal;decimalGTPbproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Type/Expr.php ================================================ internalAddGeneratedFile( '  google/type/expr.proto google.type"P Expr expression (  title (  description (  location ( BZ com.google.typeB ExprProtoPZ4google.golang.org/genproto/googleapis/type/expr;exprGTPbproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Type/Fraction.php ================================================ internalAddGeneratedFile( '  google/type/fraction.proto google.type"2 Fraction numerator ( denominator (Bf com.google.typeB FractionProtoPZinternalAddGeneratedFile( '  google/type/interval.proto google.type"h Interval. start_time ( 2.google.protobuf.Timestamp, end_time ( 2.google.protobuf.TimestampBi com.google.typeB IntervalProtoPZinternalAddGeneratedFile( '  google/type/latlng.proto google.type"- LatLng latitude ( longitude (Bc com.google.typeB LatLngProtoPZ8google.golang.org/genproto/googleapis/type/latlng;latlngGTPbproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Type/LocalizedText.php ================================================ internalAddGeneratedFile( '  google/type/localized_text.proto google.type"4 LocalizedText text (  language_code ( Bz com.google.typeBLocalizedTextProtoPZHgoogle.golang.org/genproto/googleapis/type/localized_text;localized_textGTPbproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Type/Money.php ================================================ internalAddGeneratedFile( '  google/type/money.proto google.type"< Money currency_code (  units ( nanos (B` com.google.typeB MoneyProtoPZ6google.golang.org/genproto/googleapis/type/money;moneyGTPbproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Type/PostalAddress.php ================================================ internalAddGeneratedFile( '  google/type/postal_address.proto google.type" PostalAddress revision ( region_code (  language_code (  postal_code (  sorting_code (  administrative_area (  locality (  sublocality (  address_lines (  recipients (  organization ( Bx com.google.typeBPostalAddressProtoPZFgoogle.golang.org/genproto/googleapis/type/postaladdress;postaladdressGTPbproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Type/Quaternion.php ================================================ internalAddGeneratedFile( '  google/type/quaternion.proto google.type"8 Quaternion x ( y ( z ( w (Bo com.google.typeBQuaternionProtoPZ@google.golang.org/genproto/googleapis/type/quaternion;quaternionGTPbproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/metadata/Type/Timeofday.php ================================================ internalAddGeneratedFile( '  google/type/timeofday.proto google.type"K TimeOfDay hours ( minutes ( seconds ( nanos (Bl com.google.typeBTimeOfDayProtoPZ>google.golang.org/genproto/googleapis/type/timeofday;timeofdayGTPbproto3' , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/common-protos/renovate.json ================================================ { "extends": [ "config:base", ":preserveSemverRanges", ":disableDependencyDashboard" ] } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/Advice.php ================================================ google.api.Advice */ class Advice extends \Google\Protobuf\Internal\Message { /** * Useful description for why this advice was applied and what actions should * be taken to mitigate any implied risks. * * Generated from protobuf field string description = 2; */ protected $description = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $description * Useful description for why this advice was applied and what actions should * be taken to mitigate any implied risks. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\ConfigChange::initOnce(); parent::__construct($data); } /** * Useful description for why this advice was applied and what actions should * be taken to mitigate any implied risks. * * Generated from protobuf field string description = 2; * @return string */ public function getDescription() { return $this->description; } /** * Useful description for why this advice was applied and what actions should * be taken to mitigate any implied risks. * * Generated from protobuf field string description = 2; * @param string $var * @return $this */ public function setDescription($var) { GPBUtil::checkString($var, True); $this->description = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/AuthProvider.php ================================================ google.api.AuthProvider */ class AuthProvider extends \Google\Protobuf\Internal\Message { /** * The unique identifier of the auth provider. It will be referred to by * `AuthRequirement.provider_id`. * Example: "bookstore_auth". * * Generated from protobuf field string id = 1; */ protected $id = ''; /** * Identifies the principal that issued the JWT. See * https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32#section-4.1.1 * Usually a URL or an email address. * Example: https://securetoken.google.com * Example: 1234567-compute@developer.gserviceaccount.com * * Generated from protobuf field string issuer = 2; */ protected $issuer = ''; /** * URL of the provider's public key set to validate signature of the JWT. See * [OpenID * Discovery](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata). * Optional if the key set document: * - can be retrieved from * [OpenID * Discovery](https://openid.net/specs/openid-connect-discovery-1_0.html) * of the issuer. * - can be inferred from the email domain of the issuer (e.g. a Google * service account). * Example: https://www.googleapis.com/oauth2/v1/certs * * Generated from protobuf field string jwks_uri = 3; */ protected $jwks_uri = ''; /** * The list of JWT * [audiences](https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32#section-4.1.3). * that are allowed to access. A JWT containing any of these audiences will * be accepted. When this setting is absent, JWTs with audiences: * - "https://[service.name]/[google.protobuf.Api.name]" * - "https://[service.name]/" * will be accepted. * For example, if no audiences are in the setting, LibraryService API will * accept JWTs with the following audiences: * - * https://library-example.googleapis.com/google.example.library.v1.LibraryService * - https://library-example.googleapis.com/ * Example: * audiences: bookstore_android.apps.googleusercontent.com, * bookstore_web.apps.googleusercontent.com * * Generated from protobuf field string audiences = 4; */ protected $audiences = ''; /** * Redirect URL if JWT token is required but not present or is expired. * Implement authorizationUrl of securityDefinitions in OpenAPI spec. * * Generated from protobuf field string authorization_url = 5; */ protected $authorization_url = ''; /** * Defines the locations to extract the JWT. For now it is only used by the * Cloud Endpoints to store the OpenAPI extension [x-google-jwt-locations] * (https://cloud.google.com/endpoints/docs/openapi/openapi-extensions#x-google-jwt-locations) * JWT locations can be one of HTTP headers, URL query parameters or * cookies. The rule is that the first match wins. * If not specified, default to use following 3 locations: * 1) Authorization: Bearer * 2) x-goog-iap-jwt-assertion * 3) access_token query parameter * Default locations can be specified as followings: * jwt_locations: * - header: Authorization * value_prefix: "Bearer " * - header: x-goog-iap-jwt-assertion * - query: access_token * * Generated from protobuf field repeated .google.api.JwtLocation jwt_locations = 6; */ private $jwt_locations; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $id * The unique identifier of the auth provider. It will be referred to by * `AuthRequirement.provider_id`. * Example: "bookstore_auth". * @type string $issuer * Identifies the principal that issued the JWT. See * https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32#section-4.1.1 * Usually a URL or an email address. * Example: https://securetoken.google.com * Example: 1234567-compute@developer.gserviceaccount.com * @type string $jwks_uri * URL of the provider's public key set to validate signature of the JWT. See * [OpenID * Discovery](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata). * Optional if the key set document: * - can be retrieved from * [OpenID * Discovery](https://openid.net/specs/openid-connect-discovery-1_0.html) * of the issuer. * - can be inferred from the email domain of the issuer (e.g. a Google * service account). * Example: https://www.googleapis.com/oauth2/v1/certs * @type string $audiences * The list of JWT * [audiences](https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32#section-4.1.3). * that are allowed to access. A JWT containing any of these audiences will * be accepted. When this setting is absent, JWTs with audiences: * - "https://[service.name]/[google.protobuf.Api.name]" * - "https://[service.name]/" * will be accepted. * For example, if no audiences are in the setting, LibraryService API will * accept JWTs with the following audiences: * - * https://library-example.googleapis.com/google.example.library.v1.LibraryService * - https://library-example.googleapis.com/ * Example: * audiences: bookstore_android.apps.googleusercontent.com, * bookstore_web.apps.googleusercontent.com * @type string $authorization_url * Redirect URL if JWT token is required but not present or is expired. * Implement authorizationUrl of securityDefinitions in OpenAPI spec. * @type array<\Google\Api\JwtLocation>|\Google\Protobuf\Internal\RepeatedField $jwt_locations * Defines the locations to extract the JWT. For now it is only used by the * Cloud Endpoints to store the OpenAPI extension [x-google-jwt-locations] * (https://cloud.google.com/endpoints/docs/openapi/openapi-extensions#x-google-jwt-locations) * JWT locations can be one of HTTP headers, URL query parameters or * cookies. The rule is that the first match wins. * If not specified, default to use following 3 locations: * 1) Authorization: Bearer * 2) x-goog-iap-jwt-assertion * 3) access_token query parameter * Default locations can be specified as followings: * jwt_locations: * - header: Authorization * value_prefix: "Bearer " * - header: x-goog-iap-jwt-assertion * - query: access_token * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Auth::initOnce(); parent::__construct($data); } /** * The unique identifier of the auth provider. It will be referred to by * `AuthRequirement.provider_id`. * Example: "bookstore_auth". * * Generated from protobuf field string id = 1; * @return string */ public function getId() { return $this->id; } /** * The unique identifier of the auth provider. It will be referred to by * `AuthRequirement.provider_id`. * Example: "bookstore_auth". * * Generated from protobuf field string id = 1; * @param string $var * @return $this */ public function setId($var) { GPBUtil::checkString($var, True); $this->id = $var; return $this; } /** * Identifies the principal that issued the JWT. See * https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32#section-4.1.1 * Usually a URL or an email address. * Example: https://securetoken.google.com * Example: 1234567-compute@developer.gserviceaccount.com * * Generated from protobuf field string issuer = 2; * @return string */ public function getIssuer() { return $this->issuer; } /** * Identifies the principal that issued the JWT. See * https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32#section-4.1.1 * Usually a URL or an email address. * Example: https://securetoken.google.com * Example: 1234567-compute@developer.gserviceaccount.com * * Generated from protobuf field string issuer = 2; * @param string $var * @return $this */ public function setIssuer($var) { GPBUtil::checkString($var, True); $this->issuer = $var; return $this; } /** * URL of the provider's public key set to validate signature of the JWT. See * [OpenID * Discovery](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata). * Optional if the key set document: * - can be retrieved from * [OpenID * Discovery](https://openid.net/specs/openid-connect-discovery-1_0.html) * of the issuer. * - can be inferred from the email domain of the issuer (e.g. a Google * service account). * Example: https://www.googleapis.com/oauth2/v1/certs * * Generated from protobuf field string jwks_uri = 3; * @return string */ public function getJwksUri() { return $this->jwks_uri; } /** * URL of the provider's public key set to validate signature of the JWT. See * [OpenID * Discovery](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata). * Optional if the key set document: * - can be retrieved from * [OpenID * Discovery](https://openid.net/specs/openid-connect-discovery-1_0.html) * of the issuer. * - can be inferred from the email domain of the issuer (e.g. a Google * service account). * Example: https://www.googleapis.com/oauth2/v1/certs * * Generated from protobuf field string jwks_uri = 3; * @param string $var * @return $this */ public function setJwksUri($var) { GPBUtil::checkString($var, True); $this->jwks_uri = $var; return $this; } /** * The list of JWT * [audiences](https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32#section-4.1.3). * that are allowed to access. A JWT containing any of these audiences will * be accepted. When this setting is absent, JWTs with audiences: * - "https://[service.name]/[google.protobuf.Api.name]" * - "https://[service.name]/" * will be accepted. * For example, if no audiences are in the setting, LibraryService API will * accept JWTs with the following audiences: * - * https://library-example.googleapis.com/google.example.library.v1.LibraryService * - https://library-example.googleapis.com/ * Example: * audiences: bookstore_android.apps.googleusercontent.com, * bookstore_web.apps.googleusercontent.com * * Generated from protobuf field string audiences = 4; * @return string */ public function getAudiences() { return $this->audiences; } /** * The list of JWT * [audiences](https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32#section-4.1.3). * that are allowed to access. A JWT containing any of these audiences will * be accepted. When this setting is absent, JWTs with audiences: * - "https://[service.name]/[google.protobuf.Api.name]" * - "https://[service.name]/" * will be accepted. * For example, if no audiences are in the setting, LibraryService API will * accept JWTs with the following audiences: * - * https://library-example.googleapis.com/google.example.library.v1.LibraryService * - https://library-example.googleapis.com/ * Example: * audiences: bookstore_android.apps.googleusercontent.com, * bookstore_web.apps.googleusercontent.com * * Generated from protobuf field string audiences = 4; * @param string $var * @return $this */ public function setAudiences($var) { GPBUtil::checkString($var, True); $this->audiences = $var; return $this; } /** * Redirect URL if JWT token is required but not present or is expired. * Implement authorizationUrl of securityDefinitions in OpenAPI spec. * * Generated from protobuf field string authorization_url = 5; * @return string */ public function getAuthorizationUrl() { return $this->authorization_url; } /** * Redirect URL if JWT token is required but not present or is expired. * Implement authorizationUrl of securityDefinitions in OpenAPI spec. * * Generated from protobuf field string authorization_url = 5; * @param string $var * @return $this */ public function setAuthorizationUrl($var) { GPBUtil::checkString($var, True); $this->authorization_url = $var; return $this; } /** * Defines the locations to extract the JWT. For now it is only used by the * Cloud Endpoints to store the OpenAPI extension [x-google-jwt-locations] * (https://cloud.google.com/endpoints/docs/openapi/openapi-extensions#x-google-jwt-locations) * JWT locations can be one of HTTP headers, URL query parameters or * cookies. The rule is that the first match wins. * If not specified, default to use following 3 locations: * 1) Authorization: Bearer * 2) x-goog-iap-jwt-assertion * 3) access_token query parameter * Default locations can be specified as followings: * jwt_locations: * - header: Authorization * value_prefix: "Bearer " * - header: x-goog-iap-jwt-assertion * - query: access_token * * Generated from protobuf field repeated .google.api.JwtLocation jwt_locations = 6; * @return \Google\Protobuf\Internal\RepeatedField */ public function getJwtLocations() { return $this->jwt_locations; } /** * Defines the locations to extract the JWT. For now it is only used by the * Cloud Endpoints to store the OpenAPI extension [x-google-jwt-locations] * (https://cloud.google.com/endpoints/docs/openapi/openapi-extensions#x-google-jwt-locations) * JWT locations can be one of HTTP headers, URL query parameters or * cookies. The rule is that the first match wins. * If not specified, default to use following 3 locations: * 1) Authorization: Bearer * 2) x-goog-iap-jwt-assertion * 3) access_token query parameter * Default locations can be specified as followings: * jwt_locations: * - header: Authorization * value_prefix: "Bearer " * - header: x-goog-iap-jwt-assertion * - query: access_token * * Generated from protobuf field repeated .google.api.JwtLocation jwt_locations = 6; * @param array<\Google\Api\JwtLocation>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setJwtLocations($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Api\JwtLocation::class); $this->jwt_locations = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/AuthRequirement.php ================================================ google.api.AuthRequirement */ class AuthRequirement extends \Google\Protobuf\Internal\Message { /** * [id][google.api.AuthProvider.id] from authentication provider. * Example: * provider_id: bookstore_auth * * Generated from protobuf field string provider_id = 1; */ protected $provider_id = ''; /** * NOTE: This will be deprecated soon, once AuthProvider.audiences is * implemented and accepted in all the runtime components. * The list of JWT * [audiences](https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32#section-4.1.3). * that are allowed to access. A JWT containing any of these audiences will * be accepted. When this setting is absent, only JWTs with audience * "https://[Service_name][google.api.Service.name]/[API_name][google.protobuf.Api.name]" * will be accepted. For example, if no audiences are in the setting, * LibraryService API will only accept JWTs with the following audience * "https://library-example.googleapis.com/google.example.library.v1.LibraryService". * Example: * audiences: bookstore_android.apps.googleusercontent.com, * bookstore_web.apps.googleusercontent.com * * Generated from protobuf field string audiences = 2; */ protected $audiences = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $provider_id * [id][google.api.AuthProvider.id] from authentication provider. * Example: * provider_id: bookstore_auth * @type string $audiences * NOTE: This will be deprecated soon, once AuthProvider.audiences is * implemented and accepted in all the runtime components. * The list of JWT * [audiences](https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32#section-4.1.3). * that are allowed to access. A JWT containing any of these audiences will * be accepted. When this setting is absent, only JWTs with audience * "https://[Service_name][google.api.Service.name]/[API_name][google.protobuf.Api.name]" * will be accepted. For example, if no audiences are in the setting, * LibraryService API will only accept JWTs with the following audience * "https://library-example.googleapis.com/google.example.library.v1.LibraryService". * Example: * audiences: bookstore_android.apps.googleusercontent.com, * bookstore_web.apps.googleusercontent.com * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Auth::initOnce(); parent::__construct($data); } /** * [id][google.api.AuthProvider.id] from authentication provider. * Example: * provider_id: bookstore_auth * * Generated from protobuf field string provider_id = 1; * @return string */ public function getProviderId() { return $this->provider_id; } /** * [id][google.api.AuthProvider.id] from authentication provider. * Example: * provider_id: bookstore_auth * * Generated from protobuf field string provider_id = 1; * @param string $var * @return $this */ public function setProviderId($var) { GPBUtil::checkString($var, True); $this->provider_id = $var; return $this; } /** * NOTE: This will be deprecated soon, once AuthProvider.audiences is * implemented and accepted in all the runtime components. * The list of JWT * [audiences](https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32#section-4.1.3). * that are allowed to access. A JWT containing any of these audiences will * be accepted. When this setting is absent, only JWTs with audience * "https://[Service_name][google.api.Service.name]/[API_name][google.protobuf.Api.name]" * will be accepted. For example, if no audiences are in the setting, * LibraryService API will only accept JWTs with the following audience * "https://library-example.googleapis.com/google.example.library.v1.LibraryService". * Example: * audiences: bookstore_android.apps.googleusercontent.com, * bookstore_web.apps.googleusercontent.com * * Generated from protobuf field string audiences = 2; * @return string */ public function getAudiences() { return $this->audiences; } /** * NOTE: This will be deprecated soon, once AuthProvider.audiences is * implemented and accepted in all the runtime components. * The list of JWT * [audiences](https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32#section-4.1.3). * that are allowed to access. A JWT containing any of these audiences will * be accepted. When this setting is absent, only JWTs with audience * "https://[Service_name][google.api.Service.name]/[API_name][google.protobuf.Api.name]" * will be accepted. For example, if no audiences are in the setting, * LibraryService API will only accept JWTs with the following audience * "https://library-example.googleapis.com/google.example.library.v1.LibraryService". * Example: * audiences: bookstore_android.apps.googleusercontent.com, * bookstore_web.apps.googleusercontent.com * * Generated from protobuf field string audiences = 2; * @param string $var * @return $this */ public function setAudiences($var) { GPBUtil::checkString($var, True); $this->audiences = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/Authentication.php ================================================ google.api.Authentication */ class Authentication extends \Google\Protobuf\Internal\Message { /** * A list of authentication rules that apply to individual API methods. * **NOTE:** All service configuration rules follow "last one wins" order. * * Generated from protobuf field repeated .google.api.AuthenticationRule rules = 3; */ private $rules; /** * Defines a set of authentication providers that a service supports. * * Generated from protobuf field repeated .google.api.AuthProvider providers = 4; */ private $providers; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type array<\Google\Api\AuthenticationRule>|\Google\Protobuf\Internal\RepeatedField $rules * A list of authentication rules that apply to individual API methods. * **NOTE:** All service configuration rules follow "last one wins" order. * @type array<\Google\Api\AuthProvider>|\Google\Protobuf\Internal\RepeatedField $providers * Defines a set of authentication providers that a service supports. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Auth::initOnce(); parent::__construct($data); } /** * A list of authentication rules that apply to individual API methods. * **NOTE:** All service configuration rules follow "last one wins" order. * * Generated from protobuf field repeated .google.api.AuthenticationRule rules = 3; * @return \Google\Protobuf\Internal\RepeatedField */ public function getRules() { return $this->rules; } /** * A list of authentication rules that apply to individual API methods. * **NOTE:** All service configuration rules follow "last one wins" order. * * Generated from protobuf field repeated .google.api.AuthenticationRule rules = 3; * @param array<\Google\Api\AuthenticationRule>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setRules($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Api\AuthenticationRule::class); $this->rules = $arr; return $this; } /** * Defines a set of authentication providers that a service supports. * * Generated from protobuf field repeated .google.api.AuthProvider providers = 4; * @return \Google\Protobuf\Internal\RepeatedField */ public function getProviders() { return $this->providers; } /** * Defines a set of authentication providers that a service supports. * * Generated from protobuf field repeated .google.api.AuthProvider providers = 4; * @param array<\Google\Api\AuthProvider>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setProviders($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Api\AuthProvider::class); $this->providers = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/AuthenticationRule.php ================================================ google.api.AuthenticationRule */ class AuthenticationRule extends \Google\Protobuf\Internal\Message { /** * Selects the methods to which this rule applies. * Refer to [selector][google.api.DocumentationRule.selector] for syntax * details. * * Generated from protobuf field string selector = 1; */ protected $selector = ''; /** * The requirements for OAuth credentials. * * Generated from protobuf field .google.api.OAuthRequirements oauth = 2; */ protected $oauth = null; /** * If true, the service accepts API keys without any other credential. * This flag only applies to HTTP and gRPC requests. * * Generated from protobuf field bool allow_without_credential = 5; */ protected $allow_without_credential = false; /** * Requirements for additional authentication providers. * * Generated from protobuf field repeated .google.api.AuthRequirement requirements = 7; */ private $requirements; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $selector * Selects the methods to which this rule applies. * Refer to [selector][google.api.DocumentationRule.selector] for syntax * details. * @type \Google\Api\OAuthRequirements $oauth * The requirements for OAuth credentials. * @type bool $allow_without_credential * If true, the service accepts API keys without any other credential. * This flag only applies to HTTP and gRPC requests. * @type array<\Google\Api\AuthRequirement>|\Google\Protobuf\Internal\RepeatedField $requirements * Requirements for additional authentication providers. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Auth::initOnce(); parent::__construct($data); } /** * Selects the methods to which this rule applies. * Refer to [selector][google.api.DocumentationRule.selector] for syntax * details. * * Generated from protobuf field string selector = 1; * @return string */ public function getSelector() { return $this->selector; } /** * Selects the methods to which this rule applies. * Refer to [selector][google.api.DocumentationRule.selector] for syntax * details. * * Generated from protobuf field string selector = 1; * @param string $var * @return $this */ public function setSelector($var) { GPBUtil::checkString($var, True); $this->selector = $var; return $this; } /** * The requirements for OAuth credentials. * * Generated from protobuf field .google.api.OAuthRequirements oauth = 2; * @return \Google\Api\OAuthRequirements|null */ public function getOauth() { return $this->oauth; } public function hasOauth() { return isset($this->oauth); } public function clearOauth() { unset($this->oauth); } /** * The requirements for OAuth credentials. * * Generated from protobuf field .google.api.OAuthRequirements oauth = 2; * @param \Google\Api\OAuthRequirements $var * @return $this */ public function setOauth($var) { GPBUtil::checkMessage($var, \Google\Api\OAuthRequirements::class); $this->oauth = $var; return $this; } /** * If true, the service accepts API keys without any other credential. * This flag only applies to HTTP and gRPC requests. * * Generated from protobuf field bool allow_without_credential = 5; * @return bool */ public function getAllowWithoutCredential() { return $this->allow_without_credential; } /** * If true, the service accepts API keys without any other credential. * This flag only applies to HTTP and gRPC requests. * * Generated from protobuf field bool allow_without_credential = 5; * @param bool $var * @return $this */ public function setAllowWithoutCredential($var) { GPBUtil::checkBool($var); $this->allow_without_credential = $var; return $this; } /** * Requirements for additional authentication providers. * * Generated from protobuf field repeated .google.api.AuthRequirement requirements = 7; * @return \Google\Protobuf\Internal\RepeatedField */ public function getRequirements() { return $this->requirements; } /** * Requirements for additional authentication providers. * * Generated from protobuf field repeated .google.api.AuthRequirement requirements = 7; * @param array<\Google\Api\AuthRequirement>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setRequirements($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Api\AuthRequirement::class); $this->requirements = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/Backend.php ================================================ google.api.Backend */ class Backend extends \Google\Protobuf\Internal\Message { /** * A list of API backend rules that apply to individual API methods. * **NOTE:** All service configuration rules follow "last one wins" order. * * Generated from protobuf field repeated .google.api.BackendRule rules = 1; */ private $rules; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type array<\Google\Api\BackendRule>|\Google\Protobuf\Internal\RepeatedField $rules * A list of API backend rules that apply to individual API methods. * **NOTE:** All service configuration rules follow "last one wins" order. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Backend::initOnce(); parent::__construct($data); } /** * A list of API backend rules that apply to individual API methods. * **NOTE:** All service configuration rules follow "last one wins" order. * * Generated from protobuf field repeated .google.api.BackendRule rules = 1; * @return \Google\Protobuf\Internal\RepeatedField */ public function getRules() { return $this->rules; } /** * A list of API backend rules that apply to individual API methods. * **NOTE:** All service configuration rules follow "last one wins" order. * * Generated from protobuf field repeated .google.api.BackendRule rules = 1; * @param array<\Google\Api\BackendRule>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setRules($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Api\BackendRule::class); $this->rules = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/BackendRule/PathTranslation.php ================================================ google.api.BackendRule.PathTranslation */ class PathTranslation { /** * Generated from protobuf enum PATH_TRANSLATION_UNSPECIFIED = 0; */ const PATH_TRANSLATION_UNSPECIFIED = 0; /** * Use the backend address as-is, with no modification to the path. If the * URL pattern contains variables, the variable names and values will be * appended to the query string. If a query string parameter and a URL * pattern variable have the same name, this may result in duplicate keys in * the query string. * # Examples * Given the following operation config: * Method path: /api/company/{cid}/user/{uid} * Backend address: https://example.cloudfunctions.net/getUser * Requests to the following request paths will call the backend at the * translated path: * Request path: /api/company/widgetworks/user/johndoe * Translated: * https://example.cloudfunctions.net/getUser?cid=widgetworks&uid=johndoe * Request path: /api/company/widgetworks/user/johndoe?timezone=EST * Translated: * https://example.cloudfunctions.net/getUser?timezone=EST&cid=widgetworks&uid=johndoe * * Generated from protobuf enum CONSTANT_ADDRESS = 1; */ const CONSTANT_ADDRESS = 1; /** * The request path will be appended to the backend address. * # Examples * Given the following operation config: * Method path: /api/company/{cid}/user/{uid} * Backend address: https://example.appspot.com * Requests to the following request paths will call the backend at the * translated path: * Request path: /api/company/widgetworks/user/johndoe * Translated: * https://example.appspot.com/api/company/widgetworks/user/johndoe * Request path: /api/company/widgetworks/user/johndoe?timezone=EST * Translated: * https://example.appspot.com/api/company/widgetworks/user/johndoe?timezone=EST * * Generated from protobuf enum APPEND_PATH_TO_ADDRESS = 2; */ const APPEND_PATH_TO_ADDRESS = 2; private static $valueToName = [ self::PATH_TRANSLATION_UNSPECIFIED => 'PATH_TRANSLATION_UNSPECIFIED', self::CONSTANT_ADDRESS => 'CONSTANT_ADDRESS', self::APPEND_PATH_TO_ADDRESS => 'APPEND_PATH_TO_ADDRESS', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/BackendRule.php ================================================ google.api.BackendRule */ class BackendRule extends \Google\Protobuf\Internal\Message { /** * Selects the methods to which this rule applies. * Refer to [selector][google.api.DocumentationRule.selector] for syntax * details. * * Generated from protobuf field string selector = 1; */ protected $selector = ''; /** * The address of the API backend. * The scheme is used to determine the backend protocol and security. * The following schemes are accepted: * SCHEME PROTOCOL SECURITY * http:// HTTP None * https:// HTTP TLS * grpc:// gRPC None * grpcs:// gRPC TLS * It is recommended to explicitly include a scheme. Leaving out the scheme * may cause constrasting behaviors across platforms. * If the port is unspecified, the default is: * - 80 for schemes without TLS * - 443 for schemes with TLS * For HTTP backends, use [protocol][google.api.BackendRule.protocol] * to specify the protocol version. * * Generated from protobuf field string address = 2; */ protected $address = ''; /** * The number of seconds to wait for a response from a request. The default * varies based on the request protocol and deployment environment. * * Generated from protobuf field double deadline = 3; */ protected $deadline = 0.0; /** * Deprecated, do not use. * * Generated from protobuf field double min_deadline = 4 [deprecated = true]; * @deprecated */ protected $min_deadline = 0.0; /** * The number of seconds to wait for the completion of a long running * operation. The default is no deadline. * * Generated from protobuf field double operation_deadline = 5; */ protected $operation_deadline = 0.0; /** * Generated from protobuf field .google.api.BackendRule.PathTranslation path_translation = 6; */ protected $path_translation = 0; /** * The protocol used for sending a request to the backend. * The supported values are "http/1.1" and "h2". * The default value is inferred from the scheme in the * [address][google.api.BackendRule.address] field: * SCHEME PROTOCOL * http:// http/1.1 * https:// http/1.1 * grpc:// h2 * grpcs:// h2 * For secure HTTP backends (https://) that support HTTP/2, set this field * to "h2" for improved performance. * Configuring this field to non-default values is only supported for secure * HTTP backends. This field will be ignored for all other backends. * See * https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids * for more details on the supported values. * * Generated from protobuf field string protocol = 9; */ protected $protocol = ''; /** * The map between request protocol and the backend address. * * Generated from protobuf field map overrides_by_request_protocol = 10; */ private $overrides_by_request_protocol; protected $authentication; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $selector * Selects the methods to which this rule applies. * Refer to [selector][google.api.DocumentationRule.selector] for syntax * details. * @type string $address * The address of the API backend. * The scheme is used to determine the backend protocol and security. * The following schemes are accepted: * SCHEME PROTOCOL SECURITY * http:// HTTP None * https:// HTTP TLS * grpc:// gRPC None * grpcs:// gRPC TLS * It is recommended to explicitly include a scheme. Leaving out the scheme * may cause constrasting behaviors across platforms. * If the port is unspecified, the default is: * - 80 for schemes without TLS * - 443 for schemes with TLS * For HTTP backends, use [protocol][google.api.BackendRule.protocol] * to specify the protocol version. * @type float $deadline * The number of seconds to wait for a response from a request. The default * varies based on the request protocol and deployment environment. * @type float $min_deadline * Deprecated, do not use. * @type float $operation_deadline * The number of seconds to wait for the completion of a long running * operation. The default is no deadline. * @type int $path_translation * @type string $jwt_audience * The JWT audience is used when generating a JWT ID token for the backend. * This ID token will be added in the HTTP "authorization" header, and sent * to the backend. * @type bool $disable_auth * When disable_auth is true, a JWT ID token won't be generated and the * original "Authorization" HTTP header will be preserved. If the header is * used to carry the original token and is expected by the backend, this * field must be set to true to preserve the header. * @type string $protocol * The protocol used for sending a request to the backend. * The supported values are "http/1.1" and "h2". * The default value is inferred from the scheme in the * [address][google.api.BackendRule.address] field: * SCHEME PROTOCOL * http:// http/1.1 * https:// http/1.1 * grpc:// h2 * grpcs:// h2 * For secure HTTP backends (https://) that support HTTP/2, set this field * to "h2" for improved performance. * Configuring this field to non-default values is only supported for secure * HTTP backends. This field will be ignored for all other backends. * See * https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids * for more details on the supported values. * @type array|\Google\Protobuf\Internal\MapField $overrides_by_request_protocol * The map between request protocol and the backend address. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Backend::initOnce(); parent::__construct($data); } /** * Selects the methods to which this rule applies. * Refer to [selector][google.api.DocumentationRule.selector] for syntax * details. * * Generated from protobuf field string selector = 1; * @return string */ public function getSelector() { return $this->selector; } /** * Selects the methods to which this rule applies. * Refer to [selector][google.api.DocumentationRule.selector] for syntax * details. * * Generated from protobuf field string selector = 1; * @param string $var * @return $this */ public function setSelector($var) { GPBUtil::checkString($var, True); $this->selector = $var; return $this; } /** * The address of the API backend. * The scheme is used to determine the backend protocol and security. * The following schemes are accepted: * SCHEME PROTOCOL SECURITY * http:// HTTP None * https:// HTTP TLS * grpc:// gRPC None * grpcs:// gRPC TLS * It is recommended to explicitly include a scheme. Leaving out the scheme * may cause constrasting behaviors across platforms. * If the port is unspecified, the default is: * - 80 for schemes without TLS * - 443 for schemes with TLS * For HTTP backends, use [protocol][google.api.BackendRule.protocol] * to specify the protocol version. * * Generated from protobuf field string address = 2; * @return string */ public function getAddress() { return $this->address; } /** * The address of the API backend. * The scheme is used to determine the backend protocol and security. * The following schemes are accepted: * SCHEME PROTOCOL SECURITY * http:// HTTP None * https:// HTTP TLS * grpc:// gRPC None * grpcs:// gRPC TLS * It is recommended to explicitly include a scheme. Leaving out the scheme * may cause constrasting behaviors across platforms. * If the port is unspecified, the default is: * - 80 for schemes without TLS * - 443 for schemes with TLS * For HTTP backends, use [protocol][google.api.BackendRule.protocol] * to specify the protocol version. * * Generated from protobuf field string address = 2; * @param string $var * @return $this */ public function setAddress($var) { GPBUtil::checkString($var, True); $this->address = $var; return $this; } /** * The number of seconds to wait for a response from a request. The default * varies based on the request protocol and deployment environment. * * Generated from protobuf field double deadline = 3; * @return float */ public function getDeadline() { return $this->deadline; } /** * The number of seconds to wait for a response from a request. The default * varies based on the request protocol and deployment environment. * * Generated from protobuf field double deadline = 3; * @param float $var * @return $this */ public function setDeadline($var) { GPBUtil::checkDouble($var); $this->deadline = $var; return $this; } /** * Deprecated, do not use. * * Generated from protobuf field double min_deadline = 4 [deprecated = true]; * @return float * @deprecated */ public function getMinDeadline() { if ($this->min_deadline !== 0.0) { @trigger_error('min_deadline is deprecated.', E_USER_DEPRECATED); } return $this->min_deadline; } /** * Deprecated, do not use. * * Generated from protobuf field double min_deadline = 4 [deprecated = true]; * @param float $var * @return $this * @deprecated */ public function setMinDeadline($var) { @trigger_error('min_deadline is deprecated.', E_USER_DEPRECATED); GPBUtil::checkDouble($var); $this->min_deadline = $var; return $this; } /** * The number of seconds to wait for the completion of a long running * operation. The default is no deadline. * * Generated from protobuf field double operation_deadline = 5; * @return float */ public function getOperationDeadline() { return $this->operation_deadline; } /** * The number of seconds to wait for the completion of a long running * operation. The default is no deadline. * * Generated from protobuf field double operation_deadline = 5; * @param float $var * @return $this */ public function setOperationDeadline($var) { GPBUtil::checkDouble($var); $this->operation_deadline = $var; return $this; } /** * Generated from protobuf field .google.api.BackendRule.PathTranslation path_translation = 6; * @return int */ public function getPathTranslation() { return $this->path_translation; } /** * Generated from protobuf field .google.api.BackendRule.PathTranslation path_translation = 6; * @param int $var * @return $this */ public function setPathTranslation($var) { GPBUtil::checkEnum($var, \Google\Api\BackendRule\PathTranslation::class); $this->path_translation = $var; return $this; } /** * The JWT audience is used when generating a JWT ID token for the backend. * This ID token will be added in the HTTP "authorization" header, and sent * to the backend. * * Generated from protobuf field string jwt_audience = 7; * @return string */ public function getJwtAudience() { return $this->readOneof(7); } public function hasJwtAudience() { return $this->hasOneof(7); } /** * The JWT audience is used when generating a JWT ID token for the backend. * This ID token will be added in the HTTP "authorization" header, and sent * to the backend. * * Generated from protobuf field string jwt_audience = 7; * @param string $var * @return $this */ public function setJwtAudience($var) { GPBUtil::checkString($var, True); $this->writeOneof(7, $var); return $this; } /** * When disable_auth is true, a JWT ID token won't be generated and the * original "Authorization" HTTP header will be preserved. If the header is * used to carry the original token and is expected by the backend, this * field must be set to true to preserve the header. * * Generated from protobuf field bool disable_auth = 8; * @return bool */ public function getDisableAuth() { return $this->readOneof(8); } public function hasDisableAuth() { return $this->hasOneof(8); } /** * When disable_auth is true, a JWT ID token won't be generated and the * original "Authorization" HTTP header will be preserved. If the header is * used to carry the original token and is expected by the backend, this * field must be set to true to preserve the header. * * Generated from protobuf field bool disable_auth = 8; * @param bool $var * @return $this */ public function setDisableAuth($var) { GPBUtil::checkBool($var); $this->writeOneof(8, $var); return $this; } /** * The protocol used for sending a request to the backend. * The supported values are "http/1.1" and "h2". * The default value is inferred from the scheme in the * [address][google.api.BackendRule.address] field: * SCHEME PROTOCOL * http:// http/1.1 * https:// http/1.1 * grpc:// h2 * grpcs:// h2 * For secure HTTP backends (https://) that support HTTP/2, set this field * to "h2" for improved performance. * Configuring this field to non-default values is only supported for secure * HTTP backends. This field will be ignored for all other backends. * See * https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids * for more details on the supported values. * * Generated from protobuf field string protocol = 9; * @return string */ public function getProtocol() { return $this->protocol; } /** * The protocol used for sending a request to the backend. * The supported values are "http/1.1" and "h2". * The default value is inferred from the scheme in the * [address][google.api.BackendRule.address] field: * SCHEME PROTOCOL * http:// http/1.1 * https:// http/1.1 * grpc:// h2 * grpcs:// h2 * For secure HTTP backends (https://) that support HTTP/2, set this field * to "h2" for improved performance. * Configuring this field to non-default values is only supported for secure * HTTP backends. This field will be ignored for all other backends. * See * https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids * for more details on the supported values. * * Generated from protobuf field string protocol = 9; * @param string $var * @return $this */ public function setProtocol($var) { GPBUtil::checkString($var, True); $this->protocol = $var; return $this; } /** * The map between request protocol and the backend address. * * Generated from protobuf field map overrides_by_request_protocol = 10; * @return \Google\Protobuf\Internal\MapField */ public function getOverridesByRequestProtocol() { return $this->overrides_by_request_protocol; } /** * The map between request protocol and the backend address. * * Generated from protobuf field map overrides_by_request_protocol = 10; * @param array|\Google\Protobuf\Internal\MapField $var * @return $this */ public function setOverridesByRequestProtocol($var) { $arr = GPBUtil::checkMapField($var, \Google\Protobuf\Internal\GPBType::STRING, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Api\BackendRule::class); $this->overrides_by_request_protocol = $arr; return $this; } /** * @return string */ public function getAuthentication() { return $this->whichOneof("authentication"); } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/Billing/BillingDestination.php ================================================ google.api.Billing.BillingDestination */ class BillingDestination extends \Google\Protobuf\Internal\Message { /** * The monitored resource type. The type must be defined in * [Service.monitored_resources][google.api.Service.monitored_resources] * section. * * Generated from protobuf field string monitored_resource = 1; */ protected $monitored_resource = ''; /** * Names of the metrics to report to this billing destination. * Each name must be defined in * [Service.metrics][google.api.Service.metrics] section. * * Generated from protobuf field repeated string metrics = 2; */ private $metrics; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $monitored_resource * The monitored resource type. The type must be defined in * [Service.monitored_resources][google.api.Service.monitored_resources] * section. * @type array|\Google\Protobuf\Internal\RepeatedField $metrics * Names of the metrics to report to this billing destination. * Each name must be defined in * [Service.metrics][google.api.Service.metrics] section. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Billing::initOnce(); parent::__construct($data); } /** * The monitored resource type. The type must be defined in * [Service.monitored_resources][google.api.Service.monitored_resources] * section. * * Generated from protobuf field string monitored_resource = 1; * @return string */ public function getMonitoredResource() { return $this->monitored_resource; } /** * The monitored resource type. The type must be defined in * [Service.monitored_resources][google.api.Service.monitored_resources] * section. * * Generated from protobuf field string monitored_resource = 1; * @param string $var * @return $this */ public function setMonitoredResource($var) { GPBUtil::checkString($var, True); $this->monitored_resource = $var; return $this; } /** * Names of the metrics to report to this billing destination. * Each name must be defined in * [Service.metrics][google.api.Service.metrics] section. * * Generated from protobuf field repeated string metrics = 2; * @return \Google\Protobuf\Internal\RepeatedField */ public function getMetrics() { return $this->metrics; } /** * Names of the metrics to report to this billing destination. * Each name must be defined in * [Service.metrics][google.api.Service.metrics] section. * * Generated from protobuf field repeated string metrics = 2; * @param array|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setMetrics($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->metrics = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/Billing.php ================================================ google.api.Billing */ class Billing extends \Google\Protobuf\Internal\Message { /** * Billing configurations for sending metrics to the consumer project. * There can be multiple consumer destinations per service, each one must have * a different monitored resource type. A metric can be used in at most * one consumer destination. * * Generated from protobuf field repeated .google.api.Billing.BillingDestination consumer_destinations = 8; */ private $consumer_destinations; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type array<\Google\Api\Billing\BillingDestination>|\Google\Protobuf\Internal\RepeatedField $consumer_destinations * Billing configurations for sending metrics to the consumer project. * There can be multiple consumer destinations per service, each one must have * a different monitored resource type. A metric can be used in at most * one consumer destination. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Billing::initOnce(); parent::__construct($data); } /** * Billing configurations for sending metrics to the consumer project. * There can be multiple consumer destinations per service, each one must have * a different monitored resource type. A metric can be used in at most * one consumer destination. * * Generated from protobuf field repeated .google.api.Billing.BillingDestination consumer_destinations = 8; * @return \Google\Protobuf\Internal\RepeatedField */ public function getConsumerDestinations() { return $this->consumer_destinations; } /** * Billing configurations for sending metrics to the consumer project. * There can be multiple consumer destinations per service, each one must have * a different monitored resource type. A metric can be used in at most * one consumer destination. * * Generated from protobuf field repeated .google.api.Billing.BillingDestination consumer_destinations = 8; * @param array<\Google\Api\Billing\BillingDestination>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setConsumerDestinations($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Api\Billing\BillingDestination::class); $this->consumer_destinations = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/ChangeType.php ================================================ google.api.ChangeType */ class ChangeType { /** * No value was provided. * * Generated from protobuf enum CHANGE_TYPE_UNSPECIFIED = 0; */ const CHANGE_TYPE_UNSPECIFIED = 0; /** * The changed object exists in the 'new' service configuration, but not * in the 'old' service configuration. * * Generated from protobuf enum ADDED = 1; */ const ADDED = 1; /** * The changed object exists in the 'old' service configuration, but not * in the 'new' service configuration. * * Generated from protobuf enum REMOVED = 2; */ const REMOVED = 2; /** * The changed object exists in both service configurations, but its value * is different. * * Generated from protobuf enum MODIFIED = 3; */ const MODIFIED = 3; private static $valueToName = [ self::CHANGE_TYPE_UNSPECIFIED => 'CHANGE_TYPE_UNSPECIFIED', self::ADDED => 'ADDED', self::REMOVED => 'REMOVED', self::MODIFIED => 'MODIFIED', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/ClientLibraryDestination.php ================================================ google.api.ClientLibraryDestination */ class ClientLibraryDestination { /** * Client libraries will neither be generated nor published to package * managers. * * Generated from protobuf enum CLIENT_LIBRARY_DESTINATION_UNSPECIFIED = 0; */ const CLIENT_LIBRARY_DESTINATION_UNSPECIFIED = 0; /** * Generate the client library in a repo under github.com/googleapis, * but don't publish it to package managers. * * Generated from protobuf enum GITHUB = 10; */ const GITHUB = 10; /** * Publish the library to package managers like nuget.org and npmjs.com. * * Generated from protobuf enum PACKAGE_MANAGER = 20; */ const PACKAGE_MANAGER = 20; private static $valueToName = [ self::CLIENT_LIBRARY_DESTINATION_UNSPECIFIED => 'CLIENT_LIBRARY_DESTINATION_UNSPECIFIED', self::GITHUB => 'GITHUB', self::PACKAGE_MANAGER => 'PACKAGE_MANAGER', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/ClientLibraryOrganization.php ================================================ google.api.ClientLibraryOrganization */ class ClientLibraryOrganization { /** * Not useful. * * Generated from protobuf enum CLIENT_LIBRARY_ORGANIZATION_UNSPECIFIED = 0; */ const CLIENT_LIBRARY_ORGANIZATION_UNSPECIFIED = 0; /** * Google Cloud Platform Org. * * Generated from protobuf enum CLOUD = 1; */ const CLOUD = 1; /** * Ads (Advertising) Org. * * Generated from protobuf enum ADS = 2; */ const ADS = 2; /** * Photos Org. * * Generated from protobuf enum PHOTOS = 3; */ const PHOTOS = 3; /** * Street View Org. * * Generated from protobuf enum STREET_VIEW = 4; */ const STREET_VIEW = 4; /** * Shopping Org. * * Generated from protobuf enum SHOPPING = 5; */ const SHOPPING = 5; /** * Geo Org. * * Generated from protobuf enum GEO = 6; */ const GEO = 6; /** * Generative AI - https://developers.generativeai.google * * Generated from protobuf enum GENERATIVE_AI = 7; */ const GENERATIVE_AI = 7; private static $valueToName = [ self::CLIENT_LIBRARY_ORGANIZATION_UNSPECIFIED => 'CLIENT_LIBRARY_ORGANIZATION_UNSPECIFIED', self::CLOUD => 'CLOUD', self::ADS => 'ADS', self::PHOTOS => 'PHOTOS', self::STREET_VIEW => 'STREET_VIEW', self::SHOPPING => 'SHOPPING', self::GEO => 'GEO', self::GENERATIVE_AI => 'GENERATIVE_AI', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/ClientLibrarySettings.php ================================================ google.api.ClientLibrarySettings */ class ClientLibrarySettings extends \Google\Protobuf\Internal\Message { /** * Version of the API to apply these settings to. This is the full protobuf * package for the API, ending in the version element. * Examples: "google.cloud.speech.v1" and "google.spanner.admin.database.v1". * * Generated from protobuf field string version = 1; */ protected $version = ''; /** * Launch stage of this version of the API. * * Generated from protobuf field .google.api.LaunchStage launch_stage = 2; */ protected $launch_stage = 0; /** * When using transport=rest, the client request will encode enums as * numbers rather than strings. * * Generated from protobuf field bool rest_numeric_enums = 3; */ protected $rest_numeric_enums = false; /** * Settings for legacy Java features, supported in the Service YAML. * * Generated from protobuf field .google.api.JavaSettings java_settings = 21; */ protected $java_settings = null; /** * Settings for C++ client libraries. * * Generated from protobuf field .google.api.CppSettings cpp_settings = 22; */ protected $cpp_settings = null; /** * Settings for PHP client libraries. * * Generated from protobuf field .google.api.PhpSettings php_settings = 23; */ protected $php_settings = null; /** * Settings for Python client libraries. * * Generated from protobuf field .google.api.PythonSettings python_settings = 24; */ protected $python_settings = null; /** * Settings for Node client libraries. * * Generated from protobuf field .google.api.NodeSettings node_settings = 25; */ protected $node_settings = null; /** * Settings for .NET client libraries. * * Generated from protobuf field .google.api.DotnetSettings dotnet_settings = 26; */ protected $dotnet_settings = null; /** * Settings for Ruby client libraries. * * Generated from protobuf field .google.api.RubySettings ruby_settings = 27; */ protected $ruby_settings = null; /** * Settings for Go client libraries. * * Generated from protobuf field .google.api.GoSettings go_settings = 28; */ protected $go_settings = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $version * Version of the API to apply these settings to. This is the full protobuf * package for the API, ending in the version element. * Examples: "google.cloud.speech.v1" and "google.spanner.admin.database.v1". * @type int $launch_stage * Launch stage of this version of the API. * @type bool $rest_numeric_enums * When using transport=rest, the client request will encode enums as * numbers rather than strings. * @type \Google\Api\JavaSettings $java_settings * Settings for legacy Java features, supported in the Service YAML. * @type \Google\Api\CppSettings $cpp_settings * Settings for C++ client libraries. * @type \Google\Api\PhpSettings $php_settings * Settings for PHP client libraries. * @type \Google\Api\PythonSettings $python_settings * Settings for Python client libraries. * @type \Google\Api\NodeSettings $node_settings * Settings for Node client libraries. * @type \Google\Api\DotnetSettings $dotnet_settings * Settings for .NET client libraries. * @type \Google\Api\RubySettings $ruby_settings * Settings for Ruby client libraries. * @type \Google\Api\GoSettings $go_settings * Settings for Go client libraries. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Client::initOnce(); parent::__construct($data); } /** * Version of the API to apply these settings to. This is the full protobuf * package for the API, ending in the version element. * Examples: "google.cloud.speech.v1" and "google.spanner.admin.database.v1". * * Generated from protobuf field string version = 1; * @return string */ public function getVersion() { return $this->version; } /** * Version of the API to apply these settings to. This is the full protobuf * package for the API, ending in the version element. * Examples: "google.cloud.speech.v1" and "google.spanner.admin.database.v1". * * Generated from protobuf field string version = 1; * @param string $var * @return $this */ public function setVersion($var) { GPBUtil::checkString($var, True); $this->version = $var; return $this; } /** * Launch stage of this version of the API. * * Generated from protobuf field .google.api.LaunchStage launch_stage = 2; * @return int */ public function getLaunchStage() { return $this->launch_stage; } /** * Launch stage of this version of the API. * * Generated from protobuf field .google.api.LaunchStage launch_stage = 2; * @param int $var * @return $this */ public function setLaunchStage($var) { GPBUtil::checkEnum($var, \Google\Api\LaunchStage::class); $this->launch_stage = $var; return $this; } /** * When using transport=rest, the client request will encode enums as * numbers rather than strings. * * Generated from protobuf field bool rest_numeric_enums = 3; * @return bool */ public function getRestNumericEnums() { return $this->rest_numeric_enums; } /** * When using transport=rest, the client request will encode enums as * numbers rather than strings. * * Generated from protobuf field bool rest_numeric_enums = 3; * @param bool $var * @return $this */ public function setRestNumericEnums($var) { GPBUtil::checkBool($var); $this->rest_numeric_enums = $var; return $this; } /** * Settings for legacy Java features, supported in the Service YAML. * * Generated from protobuf field .google.api.JavaSettings java_settings = 21; * @return \Google\Api\JavaSettings|null */ public function getJavaSettings() { return $this->java_settings; } public function hasJavaSettings() { return isset($this->java_settings); } public function clearJavaSettings() { unset($this->java_settings); } /** * Settings for legacy Java features, supported in the Service YAML. * * Generated from protobuf field .google.api.JavaSettings java_settings = 21; * @param \Google\Api\JavaSettings $var * @return $this */ public function setJavaSettings($var) { GPBUtil::checkMessage($var, \Google\Api\JavaSettings::class); $this->java_settings = $var; return $this; } /** * Settings for C++ client libraries. * * Generated from protobuf field .google.api.CppSettings cpp_settings = 22; * @return \Google\Api\CppSettings|null */ public function getCppSettings() { return $this->cpp_settings; } public function hasCppSettings() { return isset($this->cpp_settings); } public function clearCppSettings() { unset($this->cpp_settings); } /** * Settings for C++ client libraries. * * Generated from protobuf field .google.api.CppSettings cpp_settings = 22; * @param \Google\Api\CppSettings $var * @return $this */ public function setCppSettings($var) { GPBUtil::checkMessage($var, \Google\Api\CppSettings::class); $this->cpp_settings = $var; return $this; } /** * Settings for PHP client libraries. * * Generated from protobuf field .google.api.PhpSettings php_settings = 23; * @return \Google\Api\PhpSettings|null */ public function getPhpSettings() { return $this->php_settings; } public function hasPhpSettings() { return isset($this->php_settings); } public function clearPhpSettings() { unset($this->php_settings); } /** * Settings for PHP client libraries. * * Generated from protobuf field .google.api.PhpSettings php_settings = 23; * @param \Google\Api\PhpSettings $var * @return $this */ public function setPhpSettings($var) { GPBUtil::checkMessage($var, \Google\Api\PhpSettings::class); $this->php_settings = $var; return $this; } /** * Settings for Python client libraries. * * Generated from protobuf field .google.api.PythonSettings python_settings = 24; * @return \Google\Api\PythonSettings|null */ public function getPythonSettings() { return $this->python_settings; } public function hasPythonSettings() { return isset($this->python_settings); } public function clearPythonSettings() { unset($this->python_settings); } /** * Settings for Python client libraries. * * Generated from protobuf field .google.api.PythonSettings python_settings = 24; * @param \Google\Api\PythonSettings $var * @return $this */ public function setPythonSettings($var) { GPBUtil::checkMessage($var, \Google\Api\PythonSettings::class); $this->python_settings = $var; return $this; } /** * Settings for Node client libraries. * * Generated from protobuf field .google.api.NodeSettings node_settings = 25; * @return \Google\Api\NodeSettings|null */ public function getNodeSettings() { return $this->node_settings; } public function hasNodeSettings() { return isset($this->node_settings); } public function clearNodeSettings() { unset($this->node_settings); } /** * Settings for Node client libraries. * * Generated from protobuf field .google.api.NodeSettings node_settings = 25; * @param \Google\Api\NodeSettings $var * @return $this */ public function setNodeSettings($var) { GPBUtil::checkMessage($var, \Google\Api\NodeSettings::class); $this->node_settings = $var; return $this; } /** * Settings for .NET client libraries. * * Generated from protobuf field .google.api.DotnetSettings dotnet_settings = 26; * @return \Google\Api\DotnetSettings|null */ public function getDotnetSettings() { return $this->dotnet_settings; } public function hasDotnetSettings() { return isset($this->dotnet_settings); } public function clearDotnetSettings() { unset($this->dotnet_settings); } /** * Settings for .NET client libraries. * * Generated from protobuf field .google.api.DotnetSettings dotnet_settings = 26; * @param \Google\Api\DotnetSettings $var * @return $this */ public function setDotnetSettings($var) { GPBUtil::checkMessage($var, \Google\Api\DotnetSettings::class); $this->dotnet_settings = $var; return $this; } /** * Settings for Ruby client libraries. * * Generated from protobuf field .google.api.RubySettings ruby_settings = 27; * @return \Google\Api\RubySettings|null */ public function getRubySettings() { return $this->ruby_settings; } public function hasRubySettings() { return isset($this->ruby_settings); } public function clearRubySettings() { unset($this->ruby_settings); } /** * Settings for Ruby client libraries. * * Generated from protobuf field .google.api.RubySettings ruby_settings = 27; * @param \Google\Api\RubySettings $var * @return $this */ public function setRubySettings($var) { GPBUtil::checkMessage($var, \Google\Api\RubySettings::class); $this->ruby_settings = $var; return $this; } /** * Settings for Go client libraries. * * Generated from protobuf field .google.api.GoSettings go_settings = 28; * @return \Google\Api\GoSettings|null */ public function getGoSettings() { return $this->go_settings; } public function hasGoSettings() { return isset($this->go_settings); } public function clearGoSettings() { unset($this->go_settings); } /** * Settings for Go client libraries. * * Generated from protobuf field .google.api.GoSettings go_settings = 28; * @param \Google\Api\GoSettings $var * @return $this */ public function setGoSettings($var) { GPBUtil::checkMessage($var, \Google\Api\GoSettings::class); $this->go_settings = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/CommonLanguageSettings.php ================================================ google.api.CommonLanguageSettings */ class CommonLanguageSettings extends \Google\Protobuf\Internal\Message { /** * Link to automatically generated reference documentation. Example: * https://cloud.google.com/nodejs/docs/reference/asset/latest * * Generated from protobuf field string reference_docs_uri = 1 [deprecated = true]; * @deprecated */ protected $reference_docs_uri = ''; /** * The destination where API teams want this client library to be published. * * Generated from protobuf field repeated .google.api.ClientLibraryDestination destinations = 2; */ private $destinations; /** * Configuration for which RPCs should be generated in the GAPIC client. * * Generated from protobuf field .google.api.SelectiveGapicGeneration selective_gapic_generation = 3; */ protected $selective_gapic_generation = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $reference_docs_uri * Link to automatically generated reference documentation. Example: * https://cloud.google.com/nodejs/docs/reference/asset/latest * @type array|\Google\Protobuf\Internal\RepeatedField $destinations * The destination where API teams want this client library to be published. * @type \Google\Api\SelectiveGapicGeneration $selective_gapic_generation * Configuration for which RPCs should be generated in the GAPIC client. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Client::initOnce(); parent::__construct($data); } /** * Link to automatically generated reference documentation. Example: * https://cloud.google.com/nodejs/docs/reference/asset/latest * * Generated from protobuf field string reference_docs_uri = 1 [deprecated = true]; * @return string * @deprecated */ public function getReferenceDocsUri() { if ($this->reference_docs_uri !== '') { @trigger_error('reference_docs_uri is deprecated.', E_USER_DEPRECATED); } return $this->reference_docs_uri; } /** * Link to automatically generated reference documentation. Example: * https://cloud.google.com/nodejs/docs/reference/asset/latest * * Generated from protobuf field string reference_docs_uri = 1 [deprecated = true]; * @param string $var * @return $this * @deprecated */ public function setReferenceDocsUri($var) { @trigger_error('reference_docs_uri is deprecated.', E_USER_DEPRECATED); GPBUtil::checkString($var, True); $this->reference_docs_uri = $var; return $this; } /** * The destination where API teams want this client library to be published. * * Generated from protobuf field repeated .google.api.ClientLibraryDestination destinations = 2; * @return \Google\Protobuf\Internal\RepeatedField */ public function getDestinations() { return $this->destinations; } /** * The destination where API teams want this client library to be published. * * Generated from protobuf field repeated .google.api.ClientLibraryDestination destinations = 2; * @param array|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setDestinations($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::ENUM, \Google\Api\ClientLibraryDestination::class); $this->destinations = $arr; return $this; } /** * Configuration for which RPCs should be generated in the GAPIC client. * * Generated from protobuf field .google.api.SelectiveGapicGeneration selective_gapic_generation = 3; * @return \Google\Api\SelectiveGapicGeneration|null */ public function getSelectiveGapicGeneration() { return $this->selective_gapic_generation; } public function hasSelectiveGapicGeneration() { return isset($this->selective_gapic_generation); } public function clearSelectiveGapicGeneration() { unset($this->selective_gapic_generation); } /** * Configuration for which RPCs should be generated in the GAPIC client. * * Generated from protobuf field .google.api.SelectiveGapicGeneration selective_gapic_generation = 3; * @param \Google\Api\SelectiveGapicGeneration $var * @return $this */ public function setSelectiveGapicGeneration($var) { GPBUtil::checkMessage($var, \Google\Api\SelectiveGapicGeneration::class); $this->selective_gapic_generation = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/ConfigChange.php ================================================ google.api.ConfigChange */ class ConfigChange extends \Google\Protobuf\Internal\Message { /** * Object hierarchy path to the change, with levels separated by a '.' * character. For repeated fields, an applicable unique identifier field is * used for the index (usually selector, name, or id). For maps, the term * 'key' is used. If the field has no unique identifier, the numeric index * is used. * Examples: * - visibility.rules[selector=="google.LibraryService.ListBooks"].restriction * - quota.metric_rules[selector=="google"].metric_costs[key=="reads"].value * - logging.producer_destinations[0] * * Generated from protobuf field string element = 1; */ protected $element = ''; /** * Value of the changed object in the old Service configuration, * in JSON format. This field will not be populated if ChangeType == ADDED. * * Generated from protobuf field string old_value = 2; */ protected $old_value = ''; /** * Value of the changed object in the new Service configuration, * in JSON format. This field will not be populated if ChangeType == REMOVED. * * Generated from protobuf field string new_value = 3; */ protected $new_value = ''; /** * The type for this change, either ADDED, REMOVED, or MODIFIED. * * Generated from protobuf field .google.api.ChangeType change_type = 4; */ protected $change_type = 0; /** * Collection of advice provided for this change, useful for determining the * possible impact of this change. * * Generated from protobuf field repeated .google.api.Advice advices = 5; */ private $advices; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $element * Object hierarchy path to the change, with levels separated by a '.' * character. For repeated fields, an applicable unique identifier field is * used for the index (usually selector, name, or id). For maps, the term * 'key' is used. If the field has no unique identifier, the numeric index * is used. * Examples: * - visibility.rules[selector=="google.LibraryService.ListBooks"].restriction * - quota.metric_rules[selector=="google"].metric_costs[key=="reads"].value * - logging.producer_destinations[0] * @type string $old_value * Value of the changed object in the old Service configuration, * in JSON format. This field will not be populated if ChangeType == ADDED. * @type string $new_value * Value of the changed object in the new Service configuration, * in JSON format. This field will not be populated if ChangeType == REMOVED. * @type int $change_type * The type for this change, either ADDED, REMOVED, or MODIFIED. * @type array<\Google\Api\Advice>|\Google\Protobuf\Internal\RepeatedField $advices * Collection of advice provided for this change, useful for determining the * possible impact of this change. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\ConfigChange::initOnce(); parent::__construct($data); } /** * Object hierarchy path to the change, with levels separated by a '.' * character. For repeated fields, an applicable unique identifier field is * used for the index (usually selector, name, or id). For maps, the term * 'key' is used. If the field has no unique identifier, the numeric index * is used. * Examples: * - visibility.rules[selector=="google.LibraryService.ListBooks"].restriction * - quota.metric_rules[selector=="google"].metric_costs[key=="reads"].value * - logging.producer_destinations[0] * * Generated from protobuf field string element = 1; * @return string */ public function getElement() { return $this->element; } /** * Object hierarchy path to the change, with levels separated by a '.' * character. For repeated fields, an applicable unique identifier field is * used for the index (usually selector, name, or id). For maps, the term * 'key' is used. If the field has no unique identifier, the numeric index * is used. * Examples: * - visibility.rules[selector=="google.LibraryService.ListBooks"].restriction * - quota.metric_rules[selector=="google"].metric_costs[key=="reads"].value * - logging.producer_destinations[0] * * Generated from protobuf field string element = 1; * @param string $var * @return $this */ public function setElement($var) { GPBUtil::checkString($var, True); $this->element = $var; return $this; } /** * Value of the changed object in the old Service configuration, * in JSON format. This field will not be populated if ChangeType == ADDED. * * Generated from protobuf field string old_value = 2; * @return string */ public function getOldValue() { return $this->old_value; } /** * Value of the changed object in the old Service configuration, * in JSON format. This field will not be populated if ChangeType == ADDED. * * Generated from protobuf field string old_value = 2; * @param string $var * @return $this */ public function setOldValue($var) { GPBUtil::checkString($var, True); $this->old_value = $var; return $this; } /** * Value of the changed object in the new Service configuration, * in JSON format. This field will not be populated if ChangeType == REMOVED. * * Generated from protobuf field string new_value = 3; * @return string */ public function getNewValue() { return $this->new_value; } /** * Value of the changed object in the new Service configuration, * in JSON format. This field will not be populated if ChangeType == REMOVED. * * Generated from protobuf field string new_value = 3; * @param string $var * @return $this */ public function setNewValue($var) { GPBUtil::checkString($var, True); $this->new_value = $var; return $this; } /** * The type for this change, either ADDED, REMOVED, or MODIFIED. * * Generated from protobuf field .google.api.ChangeType change_type = 4; * @return int */ public function getChangeType() { return $this->change_type; } /** * The type for this change, either ADDED, REMOVED, or MODIFIED. * * Generated from protobuf field .google.api.ChangeType change_type = 4; * @param int $var * @return $this */ public function setChangeType($var) { GPBUtil::checkEnum($var, \Google\Api\ChangeType::class); $this->change_type = $var; return $this; } /** * Collection of advice provided for this change, useful for determining the * possible impact of this change. * * Generated from protobuf field repeated .google.api.Advice advices = 5; * @return \Google\Protobuf\Internal\RepeatedField */ public function getAdvices() { return $this->advices; } /** * Collection of advice provided for this change, useful for determining the * possible impact of this change. * * Generated from protobuf field repeated .google.api.Advice advices = 5; * @param array<\Google\Api\Advice>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setAdvices($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Api\Advice::class); $this->advices = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/Context.php ================================================ -bin” and * “x-goog-ext--jspb” format. For example, list any service * specific protobuf types that can appear in grpc metadata as follows in your * yaml file: * Example: * context: * rules: * - selector: "google.example.library.v1.LibraryService.CreateBook" * allowed_request_extensions: * - google.foo.v1.NewExtension * allowed_response_extensions: * - google.foo.v1.NewExtension * You can also specify extension ID instead of fully qualified extension name * here. * * Generated from protobuf message google.api.Context */ class Context extends \Google\Protobuf\Internal\Message { /** * A list of RPC context rules that apply to individual API methods. * **NOTE:** All service configuration rules follow "last one wins" order. * * Generated from protobuf field repeated .google.api.ContextRule rules = 1; */ private $rules; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type array<\Google\Api\ContextRule>|\Google\Protobuf\Internal\RepeatedField $rules * A list of RPC context rules that apply to individual API methods. * **NOTE:** All service configuration rules follow "last one wins" order. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Context::initOnce(); parent::__construct($data); } /** * A list of RPC context rules that apply to individual API methods. * **NOTE:** All service configuration rules follow "last one wins" order. * * Generated from protobuf field repeated .google.api.ContextRule rules = 1; * @return \Google\Protobuf\Internal\RepeatedField */ public function getRules() { return $this->rules; } /** * A list of RPC context rules that apply to individual API methods. * **NOTE:** All service configuration rules follow "last one wins" order. * * Generated from protobuf field repeated .google.api.ContextRule rules = 1; * @param array<\Google\Api\ContextRule>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setRules($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Api\ContextRule::class); $this->rules = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/ContextRule.php ================================================ google.api.ContextRule */ class ContextRule extends \Google\Protobuf\Internal\Message { /** * Selects the methods to which this rule applies. * Refer to [selector][google.api.DocumentationRule.selector] for syntax * details. * * Generated from protobuf field string selector = 1; */ protected $selector = ''; /** * A list of full type names of requested contexts, only the requested context * will be made available to the backend. * * Generated from protobuf field repeated string requested = 2; */ private $requested; /** * A list of full type names of provided contexts. It is used to support * propagating HTTP headers and ETags from the response extension. * * Generated from protobuf field repeated string provided = 3; */ private $provided; /** * A list of full type names or extension IDs of extensions allowed in grpc * side channel from client to backend. * * Generated from protobuf field repeated string allowed_request_extensions = 4; */ private $allowed_request_extensions; /** * A list of full type names or extension IDs of extensions allowed in grpc * side channel from backend to client. * * Generated from protobuf field repeated string allowed_response_extensions = 5; */ private $allowed_response_extensions; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $selector * Selects the methods to which this rule applies. * Refer to [selector][google.api.DocumentationRule.selector] for syntax * details. * @type array|\Google\Protobuf\Internal\RepeatedField $requested * A list of full type names of requested contexts, only the requested context * will be made available to the backend. * @type array|\Google\Protobuf\Internal\RepeatedField $provided * A list of full type names of provided contexts. It is used to support * propagating HTTP headers and ETags from the response extension. * @type array|\Google\Protobuf\Internal\RepeatedField $allowed_request_extensions * A list of full type names or extension IDs of extensions allowed in grpc * side channel from client to backend. * @type array|\Google\Protobuf\Internal\RepeatedField $allowed_response_extensions * A list of full type names or extension IDs of extensions allowed in grpc * side channel from backend to client. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Context::initOnce(); parent::__construct($data); } /** * Selects the methods to which this rule applies. * Refer to [selector][google.api.DocumentationRule.selector] for syntax * details. * * Generated from protobuf field string selector = 1; * @return string */ public function getSelector() { return $this->selector; } /** * Selects the methods to which this rule applies. * Refer to [selector][google.api.DocumentationRule.selector] for syntax * details. * * Generated from protobuf field string selector = 1; * @param string $var * @return $this */ public function setSelector($var) { GPBUtil::checkString($var, True); $this->selector = $var; return $this; } /** * A list of full type names of requested contexts, only the requested context * will be made available to the backend. * * Generated from protobuf field repeated string requested = 2; * @return \Google\Protobuf\Internal\RepeatedField */ public function getRequested() { return $this->requested; } /** * A list of full type names of requested contexts, only the requested context * will be made available to the backend. * * Generated from protobuf field repeated string requested = 2; * @param array|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setRequested($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->requested = $arr; return $this; } /** * A list of full type names of provided contexts. It is used to support * propagating HTTP headers and ETags from the response extension. * * Generated from protobuf field repeated string provided = 3; * @return \Google\Protobuf\Internal\RepeatedField */ public function getProvided() { return $this->provided; } /** * A list of full type names of provided contexts. It is used to support * propagating HTTP headers and ETags from the response extension. * * Generated from protobuf field repeated string provided = 3; * @param array|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setProvided($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->provided = $arr; return $this; } /** * A list of full type names or extension IDs of extensions allowed in grpc * side channel from client to backend. * * Generated from protobuf field repeated string allowed_request_extensions = 4; * @return \Google\Protobuf\Internal\RepeatedField */ public function getAllowedRequestExtensions() { return $this->allowed_request_extensions; } /** * A list of full type names or extension IDs of extensions allowed in grpc * side channel from client to backend. * * Generated from protobuf field repeated string allowed_request_extensions = 4; * @param array|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setAllowedRequestExtensions($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->allowed_request_extensions = $arr; return $this; } /** * A list of full type names or extension IDs of extensions allowed in grpc * side channel from backend to client. * * Generated from protobuf field repeated string allowed_response_extensions = 5; * @return \Google\Protobuf\Internal\RepeatedField */ public function getAllowedResponseExtensions() { return $this->allowed_response_extensions; } /** * A list of full type names or extension IDs of extensions allowed in grpc * side channel from backend to client. * * Generated from protobuf field repeated string allowed_response_extensions = 5; * @param array|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setAllowedResponseExtensions($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->allowed_response_extensions = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/Control.php ================================================ google.api.Control */ class Control extends \Google\Protobuf\Internal\Message { /** * The service controller environment to use. If empty, no control plane * feature (like quota and billing) will be enabled. The recommended value for * most services is servicecontrol.googleapis.com * * Generated from protobuf field string environment = 1; */ protected $environment = ''; /** * Defines policies applying to the API methods of the service. * * Generated from protobuf field repeated .google.api.MethodPolicy method_policies = 4; */ private $method_policies; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $environment * The service controller environment to use. If empty, no control plane * feature (like quota and billing) will be enabled. The recommended value for * most services is servicecontrol.googleapis.com * @type array<\Google\Api\MethodPolicy>|\Google\Protobuf\Internal\RepeatedField $method_policies * Defines policies applying to the API methods of the service. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Control::initOnce(); parent::__construct($data); } /** * The service controller environment to use. If empty, no control plane * feature (like quota and billing) will be enabled. The recommended value for * most services is servicecontrol.googleapis.com * * Generated from protobuf field string environment = 1; * @return string */ public function getEnvironment() { return $this->environment; } /** * The service controller environment to use. If empty, no control plane * feature (like quota and billing) will be enabled. The recommended value for * most services is servicecontrol.googleapis.com * * Generated from protobuf field string environment = 1; * @param string $var * @return $this */ public function setEnvironment($var) { GPBUtil::checkString($var, True); $this->environment = $var; return $this; } /** * Defines policies applying to the API methods of the service. * * Generated from protobuf field repeated .google.api.MethodPolicy method_policies = 4; * @return \Google\Protobuf\Internal\RepeatedField */ public function getMethodPolicies() { return $this->method_policies; } /** * Defines policies applying to the API methods of the service. * * Generated from protobuf field repeated .google.api.MethodPolicy method_policies = 4; * @param array<\Google\Api\MethodPolicy>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setMethodPolicies($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Api\MethodPolicy::class); $this->method_policies = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/CppSettings.php ================================================ google.api.CppSettings */ class CppSettings extends \Google\Protobuf\Internal\Message { /** * Some settings. * * Generated from protobuf field .google.api.CommonLanguageSettings common = 1; */ protected $common = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type \Google\Api\CommonLanguageSettings $common * Some settings. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Client::initOnce(); parent::__construct($data); } /** * Some settings. * * Generated from protobuf field .google.api.CommonLanguageSettings common = 1; * @return \Google\Api\CommonLanguageSettings|null */ public function getCommon() { return $this->common; } public function hasCommon() { return isset($this->common); } public function clearCommon() { unset($this->common); } /** * Some settings. * * Generated from protobuf field .google.api.CommonLanguageSettings common = 1; * @param \Google\Api\CommonLanguageSettings $var * @return $this */ public function setCommon($var) { GPBUtil::checkMessage($var, \Google\Api\CommonLanguageSettings::class); $this->common = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/CustomHttpPattern.php ================================================ google.api.CustomHttpPattern */ class CustomHttpPattern extends \Google\Protobuf\Internal\Message { /** * The name of this custom HTTP verb. * * Generated from protobuf field string kind = 1; */ protected $kind = ''; /** * The path matched by this custom verb. * * Generated from protobuf field string path = 2; */ protected $path = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $kind * The name of this custom HTTP verb. * @type string $path * The path matched by this custom verb. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Http::initOnce(); parent::__construct($data); } /** * The name of this custom HTTP verb. * * Generated from protobuf field string kind = 1; * @return string */ public function getKind() { return $this->kind; } /** * The name of this custom HTTP verb. * * Generated from protobuf field string kind = 1; * @param string $var * @return $this */ public function setKind($var) { GPBUtil::checkString($var, True); $this->kind = $var; return $this; } /** * The path matched by this custom verb. * * Generated from protobuf field string path = 2; * @return string */ public function getPath() { return $this->path; } /** * The path matched by this custom verb. * * Generated from protobuf field string path = 2; * @param string $var * @return $this */ public function setPath($var) { GPBUtil::checkString($var, True); $this->path = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/Distribution/BucketOptions/Explicit.php ================================================ google.api.Distribution.BucketOptions.Explicit */ class Explicit extends \Google\Protobuf\Internal\Message { /** * The values must be monotonically increasing. * * Generated from protobuf field repeated double bounds = 1; */ private $bounds; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type array|\Google\Protobuf\Internal\RepeatedField $bounds * The values must be monotonically increasing. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Distribution::initOnce(); parent::__construct($data); } /** * The values must be monotonically increasing. * * Generated from protobuf field repeated double bounds = 1; * @return \Google\Protobuf\Internal\RepeatedField */ public function getBounds() { return $this->bounds; } /** * The values must be monotonically increasing. * * Generated from protobuf field repeated double bounds = 1; * @param array|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setBounds($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::DOUBLE); $this->bounds = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/Distribution/BucketOptions/Exponential.php ================================================ google.api.Distribution.BucketOptions.Exponential */ class Exponential extends \Google\Protobuf\Internal\Message { /** * Must be greater than 0. * * Generated from protobuf field int32 num_finite_buckets = 1; */ protected $num_finite_buckets = 0; /** * Must be greater than 1. * * Generated from protobuf field double growth_factor = 2; */ protected $growth_factor = 0.0; /** * Must be greater than 0. * * Generated from protobuf field double scale = 3; */ protected $scale = 0.0; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type int $num_finite_buckets * Must be greater than 0. * @type float $growth_factor * Must be greater than 1. * @type float $scale * Must be greater than 0. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Distribution::initOnce(); parent::__construct($data); } /** * Must be greater than 0. * * Generated from protobuf field int32 num_finite_buckets = 1; * @return int */ public function getNumFiniteBuckets() { return $this->num_finite_buckets; } /** * Must be greater than 0. * * Generated from protobuf field int32 num_finite_buckets = 1; * @param int $var * @return $this */ public function setNumFiniteBuckets($var) { GPBUtil::checkInt32($var); $this->num_finite_buckets = $var; return $this; } /** * Must be greater than 1. * * Generated from protobuf field double growth_factor = 2; * @return float */ public function getGrowthFactor() { return $this->growth_factor; } /** * Must be greater than 1. * * Generated from protobuf field double growth_factor = 2; * @param float $var * @return $this */ public function setGrowthFactor($var) { GPBUtil::checkDouble($var); $this->growth_factor = $var; return $this; } /** * Must be greater than 0. * * Generated from protobuf field double scale = 3; * @return float */ public function getScale() { return $this->scale; } /** * Must be greater than 0. * * Generated from protobuf field double scale = 3; * @param float $var * @return $this */ public function setScale($var) { GPBUtil::checkDouble($var); $this->scale = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/Distribution/BucketOptions/Linear.php ================================================ google.api.Distribution.BucketOptions.Linear */ class Linear extends \Google\Protobuf\Internal\Message { /** * Must be greater than 0. * * Generated from protobuf field int32 num_finite_buckets = 1; */ protected $num_finite_buckets = 0; /** * Must be greater than 0. * * Generated from protobuf field double width = 2; */ protected $width = 0.0; /** * Lower bound of the first bucket. * * Generated from protobuf field double offset = 3; */ protected $offset = 0.0; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type int $num_finite_buckets * Must be greater than 0. * @type float $width * Must be greater than 0. * @type float $offset * Lower bound of the first bucket. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Distribution::initOnce(); parent::__construct($data); } /** * Must be greater than 0. * * Generated from protobuf field int32 num_finite_buckets = 1; * @return int */ public function getNumFiniteBuckets() { return $this->num_finite_buckets; } /** * Must be greater than 0. * * Generated from protobuf field int32 num_finite_buckets = 1; * @param int $var * @return $this */ public function setNumFiniteBuckets($var) { GPBUtil::checkInt32($var); $this->num_finite_buckets = $var; return $this; } /** * Must be greater than 0. * * Generated from protobuf field double width = 2; * @return float */ public function getWidth() { return $this->width; } /** * Must be greater than 0. * * Generated from protobuf field double width = 2; * @param float $var * @return $this */ public function setWidth($var) { GPBUtil::checkDouble($var); $this->width = $var; return $this; } /** * Lower bound of the first bucket. * * Generated from protobuf field double offset = 3; * @return float */ public function getOffset() { return $this->offset; } /** * Lower bound of the first bucket. * * Generated from protobuf field double offset = 3; * @param float $var * @return $this */ public function setOffset($var) { GPBUtil::checkDouble($var); $this->offset = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/Distribution/BucketOptions.php ================================================ 0) is the * same as the upper bound of bucket i - 1. The buckets span the whole range * of finite values: lower bound of the underflow bucket is -infinity and the * upper bound of the overflow bucket is +infinity. The finite buckets are * so-called because both bounds are finite. * * Generated from protobuf message google.api.Distribution.BucketOptions */ class BucketOptions extends \Google\Protobuf\Internal\Message { protected $options; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type \Google\Api\Distribution\BucketOptions\Linear $linear_buckets * The linear bucket. * @type \Google\Api\Distribution\BucketOptions\Exponential $exponential_buckets * The exponential buckets. * @type \Google\Api\Distribution\BucketOptions\Explicit $explicit_buckets * The explicit buckets. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Distribution::initOnce(); parent::__construct($data); } /** * The linear bucket. * * Generated from protobuf field .google.api.Distribution.BucketOptions.Linear linear_buckets = 1; * @return \Google\Api\Distribution\BucketOptions\Linear|null */ public function getLinearBuckets() { return $this->readOneof(1); } public function hasLinearBuckets() { return $this->hasOneof(1); } /** * The linear bucket. * * Generated from protobuf field .google.api.Distribution.BucketOptions.Linear linear_buckets = 1; * @param \Google\Api\Distribution\BucketOptions\Linear $var * @return $this */ public function setLinearBuckets($var) { GPBUtil::checkMessage($var, \Google\Api\Distribution\BucketOptions\Linear::class); $this->writeOneof(1, $var); return $this; } /** * The exponential buckets. * * Generated from protobuf field .google.api.Distribution.BucketOptions.Exponential exponential_buckets = 2; * @return \Google\Api\Distribution\BucketOptions\Exponential|null */ public function getExponentialBuckets() { return $this->readOneof(2); } public function hasExponentialBuckets() { return $this->hasOneof(2); } /** * The exponential buckets. * * Generated from protobuf field .google.api.Distribution.BucketOptions.Exponential exponential_buckets = 2; * @param \Google\Api\Distribution\BucketOptions\Exponential $var * @return $this */ public function setExponentialBuckets($var) { GPBUtil::checkMessage($var, \Google\Api\Distribution\BucketOptions\Exponential::class); $this->writeOneof(2, $var); return $this; } /** * The explicit buckets. * * Generated from protobuf field .google.api.Distribution.BucketOptions.Explicit explicit_buckets = 3; * @return \Google\Api\Distribution\BucketOptions\Explicit|null */ public function getExplicitBuckets() { return $this->readOneof(3); } public function hasExplicitBuckets() { return $this->hasOneof(3); } /** * The explicit buckets. * * Generated from protobuf field .google.api.Distribution.BucketOptions.Explicit explicit_buckets = 3; * @param \Google\Api\Distribution\BucketOptions\Explicit $var * @return $this */ public function setExplicitBuckets($var) { GPBUtil::checkMessage($var, \Google\Api\Distribution\BucketOptions\Explicit::class); $this->writeOneof(3, $var); return $this; } /** * @return string */ public function getOptions() { return $this->whichOneof("options"); } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/Distribution/Exemplar.php ================================================ google.api.Distribution.Exemplar */ class Exemplar extends \Google\Protobuf\Internal\Message { /** * Value of the exemplar point. This value determines to which bucket the * exemplar belongs. * * Generated from protobuf field double value = 1; */ protected $value = 0.0; /** * The observation (sampling) time of the above value. * * Generated from protobuf field .google.protobuf.Timestamp timestamp = 2; */ protected $timestamp = null; /** * Contextual information about the example value. Examples are: * Trace: type.googleapis.com/google.monitoring.v3.SpanContext * Literal string: type.googleapis.com/google.protobuf.StringValue * Labels dropped during aggregation: * type.googleapis.com/google.monitoring.v3.DroppedLabels * There may be only a single attachment of any given message type in a * single exemplar, and this is enforced by the system. * * Generated from protobuf field repeated .google.protobuf.Any attachments = 3; */ private $attachments; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type float $value * Value of the exemplar point. This value determines to which bucket the * exemplar belongs. * @type \Google\Protobuf\Timestamp $timestamp * The observation (sampling) time of the above value. * @type array<\Google\Protobuf\Any>|\Google\Protobuf\Internal\RepeatedField $attachments * Contextual information about the example value. Examples are: * Trace: type.googleapis.com/google.monitoring.v3.SpanContext * Literal string: type.googleapis.com/google.protobuf.StringValue * Labels dropped during aggregation: * type.googleapis.com/google.monitoring.v3.DroppedLabels * There may be only a single attachment of any given message type in a * single exemplar, and this is enforced by the system. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Distribution::initOnce(); parent::__construct($data); } /** * Value of the exemplar point. This value determines to which bucket the * exemplar belongs. * * Generated from protobuf field double value = 1; * @return float */ public function getValue() { return $this->value; } /** * Value of the exemplar point. This value determines to which bucket the * exemplar belongs. * * Generated from protobuf field double value = 1; * @param float $var * @return $this */ public function setValue($var) { GPBUtil::checkDouble($var); $this->value = $var; return $this; } /** * The observation (sampling) time of the above value. * * Generated from protobuf field .google.protobuf.Timestamp timestamp = 2; * @return \Google\Protobuf\Timestamp|null */ public function getTimestamp() { return $this->timestamp; } public function hasTimestamp() { return isset($this->timestamp); } public function clearTimestamp() { unset($this->timestamp); } /** * The observation (sampling) time of the above value. * * Generated from protobuf field .google.protobuf.Timestamp timestamp = 2; * @param \Google\Protobuf\Timestamp $var * @return $this */ public function setTimestamp($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Timestamp::class); $this->timestamp = $var; return $this; } /** * Contextual information about the example value. Examples are: * Trace: type.googleapis.com/google.monitoring.v3.SpanContext * Literal string: type.googleapis.com/google.protobuf.StringValue * Labels dropped during aggregation: * type.googleapis.com/google.monitoring.v3.DroppedLabels * There may be only a single attachment of any given message type in a * single exemplar, and this is enforced by the system. * * Generated from protobuf field repeated .google.protobuf.Any attachments = 3; * @return \Google\Protobuf\Internal\RepeatedField */ public function getAttachments() { return $this->attachments; } /** * Contextual information about the example value. Examples are: * Trace: type.googleapis.com/google.monitoring.v3.SpanContext * Literal string: type.googleapis.com/google.protobuf.StringValue * Labels dropped during aggregation: * type.googleapis.com/google.monitoring.v3.DroppedLabels * There may be only a single attachment of any given message type in a * single exemplar, and this is enforced by the system. * * Generated from protobuf field repeated .google.protobuf.Any attachments = 3; * @param array<\Google\Protobuf\Any>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setAttachments($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Any::class); $this->attachments = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/Distribution/Range.php ================================================ google.api.Distribution.Range */ class Range extends \Google\Protobuf\Internal\Message { /** * The minimum of the population values. * * Generated from protobuf field double min = 1; */ protected $min = 0.0; /** * The maximum of the population values. * * Generated from protobuf field double max = 2; */ protected $max = 0.0; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type float $min * The minimum of the population values. * @type float $max * The maximum of the population values. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Distribution::initOnce(); parent::__construct($data); } /** * The minimum of the population values. * * Generated from protobuf field double min = 1; * @return float */ public function getMin() { return $this->min; } /** * The minimum of the population values. * * Generated from protobuf field double min = 1; * @param float $var * @return $this */ public function setMin($var) { GPBUtil::checkDouble($var); $this->min = $var; return $this; } /** * The maximum of the population values. * * Generated from protobuf field double max = 2; * @return float */ public function getMax() { return $this->max; } /** * The maximum of the population values. * * Generated from protobuf field double max = 2; * @param float $var * @return $this */ public function setMax($var) { GPBUtil::checkDouble($var); $this->max = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/Distribution.php ================================================ google.api.Distribution */ class Distribution extends \Google\Protobuf\Internal\Message { /** * The number of values in the population. Must be non-negative. This value * must equal the sum of the values in `bucket_counts` if a histogram is * provided. * * Generated from protobuf field int64 count = 1; */ protected $count = 0; /** * The arithmetic mean of the values in the population. If `count` is zero * then this field must be zero. * * Generated from protobuf field double mean = 2; */ protected $mean = 0.0; /** * The sum of squared deviations from the mean of the values in the * population. For values x_i this is: * Sum[i=1..n]((x_i - mean)^2) * Knuth, "The Art of Computer Programming", Vol. 2, page 232, 3rd edition * describes Welford's method for accumulating this sum in one pass. * If `count` is zero then this field must be zero. * * Generated from protobuf field double sum_of_squared_deviation = 3; */ protected $sum_of_squared_deviation = 0.0; /** * If specified, contains the range of the population values. The field * must not be present if the `count` is zero. * * Generated from protobuf field .google.api.Distribution.Range range = 4; */ protected $range = null; /** * Defines the histogram bucket boundaries. If the distribution does not * contain a histogram, then omit this field. * * Generated from protobuf field .google.api.Distribution.BucketOptions bucket_options = 6; */ protected $bucket_options = null; /** * The number of values in each bucket of the histogram, as described in * `bucket_options`. If the distribution does not have a histogram, then omit * this field. If there is a histogram, then the sum of the values in * `bucket_counts` must equal the value in the `count` field of the * distribution. * If present, `bucket_counts` should contain N values, where N is the number * of buckets specified in `bucket_options`. If you supply fewer than N * values, the remaining values are assumed to be 0. * The order of the values in `bucket_counts` follows the bucket numbering * schemes described for the three bucket types. The first value must be the * count for the underflow bucket (number 0). The next N-2 values are the * counts for the finite buckets (number 1 through N-2). The N'th value in * `bucket_counts` is the count for the overflow bucket (number N-1). * * Generated from protobuf field repeated int64 bucket_counts = 7; */ private $bucket_counts; /** * Must be in increasing order of `value` field. * * Generated from protobuf field repeated .google.api.Distribution.Exemplar exemplars = 10; */ private $exemplars; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type int|string $count * The number of values in the population. Must be non-negative. This value * must equal the sum of the values in `bucket_counts` if a histogram is * provided. * @type float $mean * The arithmetic mean of the values in the population. If `count` is zero * then this field must be zero. * @type float $sum_of_squared_deviation * The sum of squared deviations from the mean of the values in the * population. For values x_i this is: * Sum[i=1..n]((x_i - mean)^2) * Knuth, "The Art of Computer Programming", Vol. 2, page 232, 3rd edition * describes Welford's method for accumulating this sum in one pass. * If `count` is zero then this field must be zero. * @type \Google\Api\Distribution\Range $range * If specified, contains the range of the population values. The field * must not be present if the `count` is zero. * @type \Google\Api\Distribution\BucketOptions $bucket_options * Defines the histogram bucket boundaries. If the distribution does not * contain a histogram, then omit this field. * @type array|array|\Google\Protobuf\Internal\RepeatedField $bucket_counts * The number of values in each bucket of the histogram, as described in * `bucket_options`. If the distribution does not have a histogram, then omit * this field. If there is a histogram, then the sum of the values in * `bucket_counts` must equal the value in the `count` field of the * distribution. * If present, `bucket_counts` should contain N values, where N is the number * of buckets specified in `bucket_options`. If you supply fewer than N * values, the remaining values are assumed to be 0. * The order of the values in `bucket_counts` follows the bucket numbering * schemes described for the three bucket types. The first value must be the * count for the underflow bucket (number 0). The next N-2 values are the * counts for the finite buckets (number 1 through N-2). The N'th value in * `bucket_counts` is the count for the overflow bucket (number N-1). * @type array<\Google\Api\Distribution\Exemplar>|\Google\Protobuf\Internal\RepeatedField $exemplars * Must be in increasing order of `value` field. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Distribution::initOnce(); parent::__construct($data); } /** * The number of values in the population. Must be non-negative. This value * must equal the sum of the values in `bucket_counts` if a histogram is * provided. * * Generated from protobuf field int64 count = 1; * @return int|string */ public function getCount() { return $this->count; } /** * The number of values in the population. Must be non-negative. This value * must equal the sum of the values in `bucket_counts` if a histogram is * provided. * * Generated from protobuf field int64 count = 1; * @param int|string $var * @return $this */ public function setCount($var) { GPBUtil::checkInt64($var); $this->count = $var; return $this; } /** * The arithmetic mean of the values in the population. If `count` is zero * then this field must be zero. * * Generated from protobuf field double mean = 2; * @return float */ public function getMean() { return $this->mean; } /** * The arithmetic mean of the values in the population. If `count` is zero * then this field must be zero. * * Generated from protobuf field double mean = 2; * @param float $var * @return $this */ public function setMean($var) { GPBUtil::checkDouble($var); $this->mean = $var; return $this; } /** * The sum of squared deviations from the mean of the values in the * population. For values x_i this is: * Sum[i=1..n]((x_i - mean)^2) * Knuth, "The Art of Computer Programming", Vol. 2, page 232, 3rd edition * describes Welford's method for accumulating this sum in one pass. * If `count` is zero then this field must be zero. * * Generated from protobuf field double sum_of_squared_deviation = 3; * @return float */ public function getSumOfSquaredDeviation() { return $this->sum_of_squared_deviation; } /** * The sum of squared deviations from the mean of the values in the * population. For values x_i this is: * Sum[i=1..n]((x_i - mean)^2) * Knuth, "The Art of Computer Programming", Vol. 2, page 232, 3rd edition * describes Welford's method for accumulating this sum in one pass. * If `count` is zero then this field must be zero. * * Generated from protobuf field double sum_of_squared_deviation = 3; * @param float $var * @return $this */ public function setSumOfSquaredDeviation($var) { GPBUtil::checkDouble($var); $this->sum_of_squared_deviation = $var; return $this; } /** * If specified, contains the range of the population values. The field * must not be present if the `count` is zero. * * Generated from protobuf field .google.api.Distribution.Range range = 4; * @return \Google\Api\Distribution\Range|null */ public function getRange() { return $this->range; } public function hasRange() { return isset($this->range); } public function clearRange() { unset($this->range); } /** * If specified, contains the range of the population values. The field * must not be present if the `count` is zero. * * Generated from protobuf field .google.api.Distribution.Range range = 4; * @param \Google\Api\Distribution\Range $var * @return $this */ public function setRange($var) { GPBUtil::checkMessage($var, \Google\Api\Distribution\Range::class); $this->range = $var; return $this; } /** * Defines the histogram bucket boundaries. If the distribution does not * contain a histogram, then omit this field. * * Generated from protobuf field .google.api.Distribution.BucketOptions bucket_options = 6; * @return \Google\Api\Distribution\BucketOptions|null */ public function getBucketOptions() { return $this->bucket_options; } public function hasBucketOptions() { return isset($this->bucket_options); } public function clearBucketOptions() { unset($this->bucket_options); } /** * Defines the histogram bucket boundaries. If the distribution does not * contain a histogram, then omit this field. * * Generated from protobuf field .google.api.Distribution.BucketOptions bucket_options = 6; * @param \Google\Api\Distribution\BucketOptions $var * @return $this */ public function setBucketOptions($var) { GPBUtil::checkMessage($var, \Google\Api\Distribution\BucketOptions::class); $this->bucket_options = $var; return $this; } /** * The number of values in each bucket of the histogram, as described in * `bucket_options`. If the distribution does not have a histogram, then omit * this field. If there is a histogram, then the sum of the values in * `bucket_counts` must equal the value in the `count` field of the * distribution. * If present, `bucket_counts` should contain N values, where N is the number * of buckets specified in `bucket_options`. If you supply fewer than N * values, the remaining values are assumed to be 0. * The order of the values in `bucket_counts` follows the bucket numbering * schemes described for the three bucket types. The first value must be the * count for the underflow bucket (number 0). The next N-2 values are the * counts for the finite buckets (number 1 through N-2). The N'th value in * `bucket_counts` is the count for the overflow bucket (number N-1). * * Generated from protobuf field repeated int64 bucket_counts = 7; * @return \Google\Protobuf\Internal\RepeatedField */ public function getBucketCounts() { return $this->bucket_counts; } /** * The number of values in each bucket of the histogram, as described in * `bucket_options`. If the distribution does not have a histogram, then omit * this field. If there is a histogram, then the sum of the values in * `bucket_counts` must equal the value in the `count` field of the * distribution. * If present, `bucket_counts` should contain N values, where N is the number * of buckets specified in `bucket_options`. If you supply fewer than N * values, the remaining values are assumed to be 0. * The order of the values in `bucket_counts` follows the bucket numbering * schemes described for the three bucket types. The first value must be the * count for the underflow bucket (number 0). The next N-2 values are the * counts for the finite buckets (number 1 through N-2). The N'th value in * `bucket_counts` is the count for the overflow bucket (number N-1). * * Generated from protobuf field repeated int64 bucket_counts = 7; * @param array|array|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setBucketCounts($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT64); $this->bucket_counts = $arr; return $this; } /** * Must be in increasing order of `value` field. * * Generated from protobuf field repeated .google.api.Distribution.Exemplar exemplars = 10; * @return \Google\Protobuf\Internal\RepeatedField */ public function getExemplars() { return $this->exemplars; } /** * Must be in increasing order of `value` field. * * Generated from protobuf field repeated .google.api.Distribution.Exemplar exemplars = 10; * @param array<\Google\Api\Distribution\Exemplar>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setExemplars($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Api\Distribution\Exemplar::class); $this->exemplars = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/Documentation.php ================================================ documentation: * summary: > * The Google Calendar API gives access * to most calendar features. * pages: * - name: Overview * content: (== include google/foo/overview.md ==) * - name: Tutorial * content: (== include google/foo/tutorial.md ==) * subpages: * - name: Java * content: (== include google/foo/tutorial_java.md ==) * rules: * - selector: google.calendar.Calendar.Get * description: > * ... * - selector: google.calendar.Calendar.Put * description: > * ... * * Documentation is provided in markdown syntax. In addition to * standard markdown features, definition lists, tables and fenced * code blocks are supported. Section headers can be provided and are * interpreted relative to the section nesting of the context where * a documentation fragment is embedded. * Documentation from the IDL is merged with documentation defined * via the config at normalization time, where documentation provided * by config rules overrides IDL provided. * A number of constructs specific to the API platform are supported * in documentation text. * In order to reference a proto element, the following * notation can be used: *
[fully.qualified.proto.name][]
* To override the display text used for the link, this can be used: *
[display text][fully.qualified.proto.name]
* Text can be excluded from doc using the following notation: *
(-- internal comment --)
* A few directives are available in documentation. Note that * directives must appear on a single line to be properly * identified. The `include` directive includes a markdown file from * an external source: *
(== include path/to/file ==)
* The `resource_for` directive marks a message to be the resource of * a collection in REST view. If it is not specified, tools attempt * to infer the resource from the operations in a collection: *
(== resource_for v1.shelves.books ==)
* The directive `suppress_warning` does not directly affect documentation * and is documented together with service config validation. * * Generated from protobuf message google.api.Documentation */ class Documentation extends \Google\Protobuf\Internal\Message { /** * A short description of what the service does. The summary must be plain * text. It becomes the overview of the service displayed in Google Cloud * Console. * NOTE: This field is equivalent to the standard field `description`. * * Generated from protobuf field string summary = 1; */ protected $summary = ''; /** * The top level pages for the documentation set. * * Generated from protobuf field repeated .google.api.Page pages = 5; */ private $pages; /** * A list of documentation rules that apply to individual API elements. * **NOTE:** All service configuration rules follow "last one wins" order. * * Generated from protobuf field repeated .google.api.DocumentationRule rules = 3; */ private $rules; /** * The URL to the root of documentation. * * Generated from protobuf field string documentation_root_url = 4; */ protected $documentation_root_url = ''; /** * Specifies the service root url if the default one (the service name * from the yaml file) is not suitable. This can be seen in any fully * specified service urls as well as sections that show a base that other * urls are relative to. * * Generated from protobuf field string service_root_url = 6; */ protected $service_root_url = ''; /** * Declares a single overview page. For example: *
documentation:
     *   summary: ...
     *   overview: (== include overview.md ==)
     * 
* This is a shortcut for the following declaration (using pages style): *
documentation:
     *   summary: ...
     *   pages:
     *   - name: Overview
     *     content: (== include overview.md ==)
     * 
* Note: you cannot specify both `overview` field and `pages` field. * * Generated from protobuf field string overview = 2; */ protected $overview = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $summary * A short description of what the service does. The summary must be plain * text. It becomes the overview of the service displayed in Google Cloud * Console. * NOTE: This field is equivalent to the standard field `description`. * @type array<\Google\Api\Page>|\Google\Protobuf\Internal\RepeatedField $pages * The top level pages for the documentation set. * @type array<\Google\Api\DocumentationRule>|\Google\Protobuf\Internal\RepeatedField $rules * A list of documentation rules that apply to individual API elements. * **NOTE:** All service configuration rules follow "last one wins" order. * @type string $documentation_root_url * The URL to the root of documentation. * @type string $service_root_url * Specifies the service root url if the default one (the service name * from the yaml file) is not suitable. This can be seen in any fully * specified service urls as well as sections that show a base that other * urls are relative to. * @type string $overview * Declares a single overview page. For example: *
documentation:
     *             summary: ...
     *             overview: (== include overview.md ==)
     *           
* This is a shortcut for the following declaration (using pages style): *
documentation:
     *             summary: ...
     *             pages:
     *             - name: Overview
     *               content: (== include overview.md ==)
     *           
* Note: you cannot specify both `overview` field and `pages` field. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Documentation::initOnce(); parent::__construct($data); } /** * A short description of what the service does. The summary must be plain * text. It becomes the overview of the service displayed in Google Cloud * Console. * NOTE: This field is equivalent to the standard field `description`. * * Generated from protobuf field string summary = 1; * @return string */ public function getSummary() { return $this->summary; } /** * A short description of what the service does. The summary must be plain * text. It becomes the overview of the service displayed in Google Cloud * Console. * NOTE: This field is equivalent to the standard field `description`. * * Generated from protobuf field string summary = 1; * @param string $var * @return $this */ public function setSummary($var) { GPBUtil::checkString($var, True); $this->summary = $var; return $this; } /** * The top level pages for the documentation set. * * Generated from protobuf field repeated .google.api.Page pages = 5; * @return \Google\Protobuf\Internal\RepeatedField */ public function getPages() { return $this->pages; } /** * The top level pages for the documentation set. * * Generated from protobuf field repeated .google.api.Page pages = 5; * @param array<\Google\Api\Page>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setPages($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Api\Page::class); $this->pages = $arr; return $this; } /** * A list of documentation rules that apply to individual API elements. * **NOTE:** All service configuration rules follow "last one wins" order. * * Generated from protobuf field repeated .google.api.DocumentationRule rules = 3; * @return \Google\Protobuf\Internal\RepeatedField */ public function getRules() { return $this->rules; } /** * A list of documentation rules that apply to individual API elements. * **NOTE:** All service configuration rules follow "last one wins" order. * * Generated from protobuf field repeated .google.api.DocumentationRule rules = 3; * @param array<\Google\Api\DocumentationRule>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setRules($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Api\DocumentationRule::class); $this->rules = $arr; return $this; } /** * The URL to the root of documentation. * * Generated from protobuf field string documentation_root_url = 4; * @return string */ public function getDocumentationRootUrl() { return $this->documentation_root_url; } /** * The URL to the root of documentation. * * Generated from protobuf field string documentation_root_url = 4; * @param string $var * @return $this */ public function setDocumentationRootUrl($var) { GPBUtil::checkString($var, True); $this->documentation_root_url = $var; return $this; } /** * Specifies the service root url if the default one (the service name * from the yaml file) is not suitable. This can be seen in any fully * specified service urls as well as sections that show a base that other * urls are relative to. * * Generated from protobuf field string service_root_url = 6; * @return string */ public function getServiceRootUrl() { return $this->service_root_url; } /** * Specifies the service root url if the default one (the service name * from the yaml file) is not suitable. This can be seen in any fully * specified service urls as well as sections that show a base that other * urls are relative to. * * Generated from protobuf field string service_root_url = 6; * @param string $var * @return $this */ public function setServiceRootUrl($var) { GPBUtil::checkString($var, True); $this->service_root_url = $var; return $this; } /** * Declares a single overview page. For example: *
documentation:
     *   summary: ...
     *   overview: (== include overview.md ==)
     * 
* This is a shortcut for the following declaration (using pages style): *
documentation:
     *   summary: ...
     *   pages:
     *   - name: Overview
     *     content: (== include overview.md ==)
     * 
* Note: you cannot specify both `overview` field and `pages` field. * * Generated from protobuf field string overview = 2; * @return string */ public function getOverview() { return $this->overview; } /** * Declares a single overview page. For example: *
documentation:
     *   summary: ...
     *   overview: (== include overview.md ==)
     * 
* This is a shortcut for the following declaration (using pages style): *
documentation:
     *   summary: ...
     *   pages:
     *   - name: Overview
     *     content: (== include overview.md ==)
     * 
* Note: you cannot specify both `overview` field and `pages` field. * * Generated from protobuf field string overview = 2; * @param string $var * @return $this */ public function setOverview($var) { GPBUtil::checkString($var, True); $this->overview = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/DocumentationRule.php ================================================ google.api.DocumentationRule */ class DocumentationRule extends \Google\Protobuf\Internal\Message { /** * The selector is a comma-separated list of patterns for any element such as * a method, a field, an enum value. Each pattern is a qualified name of the * element which may end in "*", indicating a wildcard. Wildcards are only * allowed at the end and for a whole component of the qualified name, * i.e. "foo.*" is ok, but not "foo.b*" or "foo.*.bar". A wildcard will match * one or more components. To specify a default for all applicable elements, * the whole pattern "*" is used. * * Generated from protobuf field string selector = 1; */ protected $selector = ''; /** * Description of the selected proto element (e.g. a message, a method, a * 'service' definition, or a field). Defaults to leading & trailing comments * taken from the proto source definition of the proto element. * * Generated from protobuf field string description = 2; */ protected $description = ''; /** * Deprecation description of the selected element(s). It can be provided if * an element is marked as `deprecated`. * * Generated from protobuf field string deprecation_description = 3; */ protected $deprecation_description = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $selector * The selector is a comma-separated list of patterns for any element such as * a method, a field, an enum value. Each pattern is a qualified name of the * element which may end in "*", indicating a wildcard. Wildcards are only * allowed at the end and for a whole component of the qualified name, * i.e. "foo.*" is ok, but not "foo.b*" or "foo.*.bar". A wildcard will match * one or more components. To specify a default for all applicable elements, * the whole pattern "*" is used. * @type string $description * Description of the selected proto element (e.g. a message, a method, a * 'service' definition, or a field). Defaults to leading & trailing comments * taken from the proto source definition of the proto element. * @type string $deprecation_description * Deprecation description of the selected element(s). It can be provided if * an element is marked as `deprecated`. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Documentation::initOnce(); parent::__construct($data); } /** * The selector is a comma-separated list of patterns for any element such as * a method, a field, an enum value. Each pattern is a qualified name of the * element which may end in "*", indicating a wildcard. Wildcards are only * allowed at the end and for a whole component of the qualified name, * i.e. "foo.*" is ok, but not "foo.b*" or "foo.*.bar". A wildcard will match * one or more components. To specify a default for all applicable elements, * the whole pattern "*" is used. * * Generated from protobuf field string selector = 1; * @return string */ public function getSelector() { return $this->selector; } /** * The selector is a comma-separated list of patterns for any element such as * a method, a field, an enum value. Each pattern is a qualified name of the * element which may end in "*", indicating a wildcard. Wildcards are only * allowed at the end and for a whole component of the qualified name, * i.e. "foo.*" is ok, but not "foo.b*" or "foo.*.bar". A wildcard will match * one or more components. To specify a default for all applicable elements, * the whole pattern "*" is used. * * Generated from protobuf field string selector = 1; * @param string $var * @return $this */ public function setSelector($var) { GPBUtil::checkString($var, True); $this->selector = $var; return $this; } /** * Description of the selected proto element (e.g. a message, a method, a * 'service' definition, or a field). Defaults to leading & trailing comments * taken from the proto source definition of the proto element. * * Generated from protobuf field string description = 2; * @return string */ public function getDescription() { return $this->description; } /** * Description of the selected proto element (e.g. a message, a method, a * 'service' definition, or a field). Defaults to leading & trailing comments * taken from the proto source definition of the proto element. * * Generated from protobuf field string description = 2; * @param string $var * @return $this */ public function setDescription($var) { GPBUtil::checkString($var, True); $this->description = $var; return $this; } /** * Deprecation description of the selected element(s). It can be provided if * an element is marked as `deprecated`. * * Generated from protobuf field string deprecation_description = 3; * @return string */ public function getDeprecationDescription() { return $this->deprecation_description; } /** * Deprecation description of the selected element(s). It can be provided if * an element is marked as `deprecated`. * * Generated from protobuf field string deprecation_description = 3; * @param string $var * @return $this */ public function setDeprecationDescription($var) { GPBUtil::checkString($var, True); $this->deprecation_description = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/DotnetSettings.php ================================================ google.api.DotnetSettings */ class DotnetSettings extends \Google\Protobuf\Internal\Message { /** * Some settings. * * Generated from protobuf field .google.api.CommonLanguageSettings common = 1; */ protected $common = null; /** * Map from original service names to renamed versions. * This is used when the default generated types * would cause a naming conflict. (Neither name is * fully-qualified.) * Example: Subscriber to SubscriberServiceApi. * * Generated from protobuf field map renamed_services = 2; */ private $renamed_services; /** * Map from full resource types to the effective short name * for the resource. This is used when otherwise resource * named from different services would cause naming collisions. * Example entry: * "datalabeling.googleapis.com/Dataset": "DataLabelingDataset" * * Generated from protobuf field map renamed_resources = 3; */ private $renamed_resources; /** * List of full resource types to ignore during generation. * This is typically used for API-specific Location resources, * which should be handled by the generator as if they were actually * the common Location resources. * Example entry: "documentai.googleapis.com/Location" * * Generated from protobuf field repeated string ignored_resources = 4; */ private $ignored_resources; /** * Namespaces which must be aliased in snippets due to * a known (but non-generator-predictable) naming collision * * Generated from protobuf field repeated string forced_namespace_aliases = 5; */ private $forced_namespace_aliases; /** * Method signatures (in the form "service.method(signature)") * which are provided separately, so shouldn't be generated. * Snippets *calling* these methods are still generated, however. * * Generated from protobuf field repeated string handwritten_signatures = 6; */ private $handwritten_signatures; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type \Google\Api\CommonLanguageSettings $common * Some settings. * @type array|\Google\Protobuf\Internal\MapField $renamed_services * Map from original service names to renamed versions. * This is used when the default generated types * would cause a naming conflict. (Neither name is * fully-qualified.) * Example: Subscriber to SubscriberServiceApi. * @type array|\Google\Protobuf\Internal\MapField $renamed_resources * Map from full resource types to the effective short name * for the resource. This is used when otherwise resource * named from different services would cause naming collisions. * Example entry: * "datalabeling.googleapis.com/Dataset": "DataLabelingDataset" * @type array|\Google\Protobuf\Internal\RepeatedField $ignored_resources * List of full resource types to ignore during generation. * This is typically used for API-specific Location resources, * which should be handled by the generator as if they were actually * the common Location resources. * Example entry: "documentai.googleapis.com/Location" * @type array|\Google\Protobuf\Internal\RepeatedField $forced_namespace_aliases * Namespaces which must be aliased in snippets due to * a known (but non-generator-predictable) naming collision * @type array|\Google\Protobuf\Internal\RepeatedField $handwritten_signatures * Method signatures (in the form "service.method(signature)") * which are provided separately, so shouldn't be generated. * Snippets *calling* these methods are still generated, however. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Client::initOnce(); parent::__construct($data); } /** * Some settings. * * Generated from protobuf field .google.api.CommonLanguageSettings common = 1; * @return \Google\Api\CommonLanguageSettings|null */ public function getCommon() { return $this->common; } public function hasCommon() { return isset($this->common); } public function clearCommon() { unset($this->common); } /** * Some settings. * * Generated from protobuf field .google.api.CommonLanguageSettings common = 1; * @param \Google\Api\CommonLanguageSettings $var * @return $this */ public function setCommon($var) { GPBUtil::checkMessage($var, \Google\Api\CommonLanguageSettings::class); $this->common = $var; return $this; } /** * Map from original service names to renamed versions. * This is used when the default generated types * would cause a naming conflict. (Neither name is * fully-qualified.) * Example: Subscriber to SubscriberServiceApi. * * Generated from protobuf field map renamed_services = 2; * @return \Google\Protobuf\Internal\MapField */ public function getRenamedServices() { return $this->renamed_services; } /** * Map from original service names to renamed versions. * This is used when the default generated types * would cause a naming conflict. (Neither name is * fully-qualified.) * Example: Subscriber to SubscriberServiceApi. * * Generated from protobuf field map renamed_services = 2; * @param array|\Google\Protobuf\Internal\MapField $var * @return $this */ public function setRenamedServices($var) { $arr = GPBUtil::checkMapField($var, \Google\Protobuf\Internal\GPBType::STRING, \Google\Protobuf\Internal\GPBType::STRING); $this->renamed_services = $arr; return $this; } /** * Map from full resource types to the effective short name * for the resource. This is used when otherwise resource * named from different services would cause naming collisions. * Example entry: * "datalabeling.googleapis.com/Dataset": "DataLabelingDataset" * * Generated from protobuf field map renamed_resources = 3; * @return \Google\Protobuf\Internal\MapField */ public function getRenamedResources() { return $this->renamed_resources; } /** * Map from full resource types to the effective short name * for the resource. This is used when otherwise resource * named from different services would cause naming collisions. * Example entry: * "datalabeling.googleapis.com/Dataset": "DataLabelingDataset" * * Generated from protobuf field map renamed_resources = 3; * @param array|\Google\Protobuf\Internal\MapField $var * @return $this */ public function setRenamedResources($var) { $arr = GPBUtil::checkMapField($var, \Google\Protobuf\Internal\GPBType::STRING, \Google\Protobuf\Internal\GPBType::STRING); $this->renamed_resources = $arr; return $this; } /** * List of full resource types to ignore during generation. * This is typically used for API-specific Location resources, * which should be handled by the generator as if they were actually * the common Location resources. * Example entry: "documentai.googleapis.com/Location" * * Generated from protobuf field repeated string ignored_resources = 4; * @return \Google\Protobuf\Internal\RepeatedField */ public function getIgnoredResources() { return $this->ignored_resources; } /** * List of full resource types to ignore during generation. * This is typically used for API-specific Location resources, * which should be handled by the generator as if they were actually * the common Location resources. * Example entry: "documentai.googleapis.com/Location" * * Generated from protobuf field repeated string ignored_resources = 4; * @param array|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setIgnoredResources($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->ignored_resources = $arr; return $this; } /** * Namespaces which must be aliased in snippets due to * a known (but non-generator-predictable) naming collision * * Generated from protobuf field repeated string forced_namespace_aliases = 5; * @return \Google\Protobuf\Internal\RepeatedField */ public function getForcedNamespaceAliases() { return $this->forced_namespace_aliases; } /** * Namespaces which must be aliased in snippets due to * a known (but non-generator-predictable) naming collision * * Generated from protobuf field repeated string forced_namespace_aliases = 5; * @param array|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setForcedNamespaceAliases($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->forced_namespace_aliases = $arr; return $this; } /** * Method signatures (in the form "service.method(signature)") * which are provided separately, so shouldn't be generated. * Snippets *calling* these methods are still generated, however. * * Generated from protobuf field repeated string handwritten_signatures = 6; * @return \Google\Protobuf\Internal\RepeatedField */ public function getHandwrittenSignatures() { return $this->handwritten_signatures; } /** * Method signatures (in the form "service.method(signature)") * which are provided separately, so shouldn't be generated. * Snippets *calling* these methods are still generated, however. * * Generated from protobuf field repeated string handwritten_signatures = 6; * @param array|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setHandwrittenSignatures($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->handwritten_signatures = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/Endpoint.php ================================================ google.api.Endpoint */ class Endpoint extends \Google\Protobuf\Internal\Message { /** * The canonical name of this endpoint. * * Generated from protobuf field string name = 1; */ protected $name = ''; /** * Aliases for this endpoint, these will be served by the same UrlMap as the * parent endpoint, and will be provisioned in the GCP stack for the Regional * Endpoints. * * Generated from protobuf field repeated string aliases = 2; */ private $aliases; /** * The specification of an Internet routable address of API frontend that will * handle requests to this [API * Endpoint](https://cloud.google.com/apis/design/glossary). It should be * either a valid IPv4 address or a fully-qualified domain name. For example, * "8.8.8.8" or "myservice.appspot.com". * * Generated from protobuf field string target = 101; */ protected $target = ''; /** * Allowing * [CORS](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing), aka * cross-domain traffic, would allow the backends served from this endpoint to * receive and respond to HTTP OPTIONS requests. The response will be used by * the browser to determine whether the subsequent cross-origin request is * allowed to proceed. * * Generated from protobuf field bool allow_cors = 5; */ protected $allow_cors = false; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $name * The canonical name of this endpoint. * @type array|\Google\Protobuf\Internal\RepeatedField $aliases * Aliases for this endpoint, these will be served by the same UrlMap as the * parent endpoint, and will be provisioned in the GCP stack for the Regional * Endpoints. * @type string $target * The specification of an Internet routable address of API frontend that will * handle requests to this [API * Endpoint](https://cloud.google.com/apis/design/glossary). It should be * either a valid IPv4 address or a fully-qualified domain name. For example, * "8.8.8.8" or "myservice.appspot.com". * @type bool $allow_cors * Allowing * [CORS](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing), aka * cross-domain traffic, would allow the backends served from this endpoint to * receive and respond to HTTP OPTIONS requests. The response will be used by * the browser to determine whether the subsequent cross-origin request is * allowed to proceed. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Endpoint::initOnce(); parent::__construct($data); } /** * The canonical name of this endpoint. * * Generated from protobuf field string name = 1; * @return string */ public function getName() { return $this->name; } /** * The canonical name of this endpoint. * * Generated from protobuf field string name = 1; * @param string $var * @return $this */ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; return $this; } /** * Aliases for this endpoint, these will be served by the same UrlMap as the * parent endpoint, and will be provisioned in the GCP stack for the Regional * Endpoints. * * Generated from protobuf field repeated string aliases = 2; * @return \Google\Protobuf\Internal\RepeatedField */ public function getAliases() { return $this->aliases; } /** * Aliases for this endpoint, these will be served by the same UrlMap as the * parent endpoint, and will be provisioned in the GCP stack for the Regional * Endpoints. * * Generated from protobuf field repeated string aliases = 2; * @param array|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setAliases($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->aliases = $arr; return $this; } /** * The specification of an Internet routable address of API frontend that will * handle requests to this [API * Endpoint](https://cloud.google.com/apis/design/glossary). It should be * either a valid IPv4 address or a fully-qualified domain name. For example, * "8.8.8.8" or "myservice.appspot.com". * * Generated from protobuf field string target = 101; * @return string */ public function getTarget() { return $this->target; } /** * The specification of an Internet routable address of API frontend that will * handle requests to this [API * Endpoint](https://cloud.google.com/apis/design/glossary). It should be * either a valid IPv4 address or a fully-qualified domain name. For example, * "8.8.8.8" or "myservice.appspot.com". * * Generated from protobuf field string target = 101; * @param string $var * @return $this */ public function setTarget($var) { GPBUtil::checkString($var, True); $this->target = $var; return $this; } /** * Allowing * [CORS](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing), aka * cross-domain traffic, would allow the backends served from this endpoint to * receive and respond to HTTP OPTIONS requests. The response will be used by * the browser to determine whether the subsequent cross-origin request is * allowed to proceed. * * Generated from protobuf field bool allow_cors = 5; * @return bool */ public function getAllowCors() { return $this->allow_cors; } /** * Allowing * [CORS](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing), aka * cross-domain traffic, would allow the backends served from this endpoint to * receive and respond to HTTP OPTIONS requests. The response will be used by * the browser to determine whether the subsequent cross-origin request is * allowed to proceed. * * Generated from protobuf field bool allow_cors = 5; * @param bool $var * @return $this */ public function setAllowCors($var) { GPBUtil::checkBool($var); $this->allow_cors = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/ErrorReason.php ================================================ google.api.ErrorReason */ class ErrorReason { /** * Do not use this default value. * * Generated from protobuf enum ERROR_REASON_UNSPECIFIED = 0; */ const ERROR_REASON_UNSPECIFIED = 0; /** * The request is calling a disabled service for a consumer. * Example of an ErrorInfo when the consumer "projects/123" contacting * "pubsub.googleapis.com" service which is disabled: * { "reason": "SERVICE_DISABLED", * "domain": "googleapis.com", * "metadata": { * "consumer": "projects/123", * "service": "pubsub.googleapis.com" * } * } * This response indicates the "pubsub.googleapis.com" has been disabled in * "projects/123". * * Generated from protobuf enum SERVICE_DISABLED = 1; */ const SERVICE_DISABLED = 1; /** * The request whose associated billing account is disabled. * Example of an ErrorInfo when the consumer "projects/123" fails to contact * "pubsub.googleapis.com" service because the associated billing account is * disabled: * { "reason": "BILLING_DISABLED", * "domain": "googleapis.com", * "metadata": { * "consumer": "projects/123", * "service": "pubsub.googleapis.com" * } * } * This response indicates the billing account associated has been disabled. * * Generated from protobuf enum BILLING_DISABLED = 2; */ const BILLING_DISABLED = 2; /** * The request is denied because the provided [API * key](https://cloud.google.com/docs/authentication/api-keys) is invalid. It * may be in a bad format, cannot be found, or has been expired). * Example of an ErrorInfo when the request is contacting * "storage.googleapis.com" service with an invalid API key: * { "reason": "API_KEY_INVALID", * "domain": "googleapis.com", * "metadata": { * "service": "storage.googleapis.com", * } * } * * Generated from protobuf enum API_KEY_INVALID = 3; */ const API_KEY_INVALID = 3; /** * The request is denied because it violates [API key API * restrictions](https://cloud.google.com/docs/authentication/api-keys#adding_api_restrictions). * Example of an ErrorInfo when the consumer "projects/123" fails to call the * "storage.googleapis.com" service because this service is restricted in the * API key: * { "reason": "API_KEY_SERVICE_BLOCKED", * "domain": "googleapis.com", * "metadata": { * "consumer": "projects/123", * "service": "storage.googleapis.com" * } * } * * Generated from protobuf enum API_KEY_SERVICE_BLOCKED = 4; */ const API_KEY_SERVICE_BLOCKED = 4; /** * The request is denied because it violates [API key HTTP * restrictions](https://cloud.google.com/docs/authentication/api-keys#adding_http_restrictions). * Example of an ErrorInfo when the consumer "projects/123" fails to call * "storage.googleapis.com" service because the http referrer of the request * violates API key HTTP restrictions: * { "reason": "API_KEY_HTTP_REFERRER_BLOCKED", * "domain": "googleapis.com", * "metadata": { * "consumer": "projects/123", * "service": "storage.googleapis.com", * } * } * * Generated from protobuf enum API_KEY_HTTP_REFERRER_BLOCKED = 7; */ const API_KEY_HTTP_REFERRER_BLOCKED = 7; /** * The request is denied because it violates [API key IP address * restrictions](https://cloud.google.com/docs/authentication/api-keys#adding_application_restrictions). * Example of an ErrorInfo when the consumer "projects/123" fails to call * "storage.googleapis.com" service because the caller IP of the request * violates API key IP address restrictions: * { "reason": "API_KEY_IP_ADDRESS_BLOCKED", * "domain": "googleapis.com", * "metadata": { * "consumer": "projects/123", * "service": "storage.googleapis.com", * } * } * * Generated from protobuf enum API_KEY_IP_ADDRESS_BLOCKED = 8; */ const API_KEY_IP_ADDRESS_BLOCKED = 8; /** * The request is denied because it violates [API key Android application * restrictions](https://cloud.google.com/docs/authentication/api-keys#adding_application_restrictions). * Example of an ErrorInfo when the consumer "projects/123" fails to call * "storage.googleapis.com" service because the request from the Android apps * violates the API key Android application restrictions: * { "reason": "API_KEY_ANDROID_APP_BLOCKED", * "domain": "googleapis.com", * "metadata": { * "consumer": "projects/123", * "service": "storage.googleapis.com" * } * } * * Generated from protobuf enum API_KEY_ANDROID_APP_BLOCKED = 9; */ const API_KEY_ANDROID_APP_BLOCKED = 9; /** * The request is denied because it violates [API key iOS application * restrictions](https://cloud.google.com/docs/authentication/api-keys#adding_application_restrictions). * Example of an ErrorInfo when the consumer "projects/123" fails to call * "storage.googleapis.com" service because the request from the iOS apps * violates the API key iOS application restrictions: * { "reason": "API_KEY_IOS_APP_BLOCKED", * "domain": "googleapis.com", * "metadata": { * "consumer": "projects/123", * "service": "storage.googleapis.com" * } * } * * Generated from protobuf enum API_KEY_IOS_APP_BLOCKED = 13; */ const API_KEY_IOS_APP_BLOCKED = 13; /** * The request is denied because there is not enough rate quota for the * consumer. * Example of an ErrorInfo when the consumer "projects/123" fails to contact * "pubsub.googleapis.com" service because consumer's rate quota usage has * reached the maximum value set for the quota limit * "ReadsPerMinutePerProject" on the quota metric * "pubsub.googleapis.com/read_requests": * { "reason": "RATE_LIMIT_EXCEEDED", * "domain": "googleapis.com", * "metadata": { * "consumer": "projects/123", * "service": "pubsub.googleapis.com", * "quota_metric": "pubsub.googleapis.com/read_requests", * "quota_limit": "ReadsPerMinutePerProject" * } * } * Example of an ErrorInfo when the consumer "projects/123" checks quota on * the service "dataflow.googleapis.com" and hits the organization quota * limit "DefaultRequestsPerMinutePerOrganization" on the metric * "dataflow.googleapis.com/default_requests". * { "reason": "RATE_LIMIT_EXCEEDED", * "domain": "googleapis.com", * "metadata": { * "consumer": "projects/123", * "service": "dataflow.googleapis.com", * "quota_metric": "dataflow.googleapis.com/default_requests", * "quota_limit": "DefaultRequestsPerMinutePerOrganization" * } * } * * Generated from protobuf enum RATE_LIMIT_EXCEEDED = 5; */ const RATE_LIMIT_EXCEEDED = 5; /** * The request is denied because there is not enough resource quota for the * consumer. * Example of an ErrorInfo when the consumer "projects/123" fails to contact * "compute.googleapis.com" service because consumer's resource quota usage * has reached the maximum value set for the quota limit "VMsPerProject" * on the quota metric "compute.googleapis.com/vms": * { "reason": "RESOURCE_QUOTA_EXCEEDED", * "domain": "googleapis.com", * "metadata": { * "consumer": "projects/123", * "service": "compute.googleapis.com", * "quota_metric": "compute.googleapis.com/vms", * "quota_limit": "VMsPerProject" * } * } * Example of an ErrorInfo when the consumer "projects/123" checks resource * quota on the service "dataflow.googleapis.com" and hits the organization * quota limit "jobs-per-organization" on the metric * "dataflow.googleapis.com/job_count". * { "reason": "RESOURCE_QUOTA_EXCEEDED", * "domain": "googleapis.com", * "metadata": { * "consumer": "projects/123", * "service": "dataflow.googleapis.com", * "quota_metric": "dataflow.googleapis.com/job_count", * "quota_limit": "jobs-per-organization" * } * } * * Generated from protobuf enum RESOURCE_QUOTA_EXCEEDED = 6; */ const RESOURCE_QUOTA_EXCEEDED = 6; /** * The request whose associated billing account address is in a tax restricted * location, violates the local tax restrictions when creating resources in * the restricted region. * Example of an ErrorInfo when creating the Cloud Storage Bucket in the * container "projects/123" under a tax restricted region * "locations/asia-northeast3": * { "reason": "LOCATION_TAX_POLICY_VIOLATED", * "domain": "googleapis.com", * "metadata": { * "consumer": "projects/123", * "service": "storage.googleapis.com", * "location": "locations/asia-northeast3" * } * } * This response indicates creating the Cloud Storage Bucket in * "locations/asia-northeast3" violates the location tax restriction. * * Generated from protobuf enum LOCATION_TAX_POLICY_VIOLATED = 10; */ const LOCATION_TAX_POLICY_VIOLATED = 10; /** * The request is denied because the caller does not have required permission * on the user project "projects/123" or the user project is invalid. For more * information, check the [userProject System * Parameters](https://cloud.google.com/apis/docs/system-parameters). * Example of an ErrorInfo when the caller is calling Cloud Storage service * with insufficient permissions on the user project: * { "reason": "USER_PROJECT_DENIED", * "domain": "googleapis.com", * "metadata": { * "consumer": "projects/123", * "service": "storage.googleapis.com" * } * } * * Generated from protobuf enum USER_PROJECT_DENIED = 11; */ const USER_PROJECT_DENIED = 11; /** * The request is denied because the consumer "projects/123" is suspended due * to Terms of Service(Tos) violations. Check [Project suspension * guidelines](https://cloud.google.com/resource-manager/docs/project-suspension-guidelines) * for more information. * Example of an ErrorInfo when calling Cloud Storage service with the * suspended consumer "projects/123": * { "reason": "CONSUMER_SUSPENDED", * "domain": "googleapis.com", * "metadata": { * "consumer": "projects/123", * "service": "storage.googleapis.com" * } * } * * Generated from protobuf enum CONSUMER_SUSPENDED = 12; */ const CONSUMER_SUSPENDED = 12; /** * The request is denied because the associated consumer is invalid. It may be * in a bad format, cannot be found, or have been deleted. * Example of an ErrorInfo when calling Cloud Storage service with the * invalid consumer "projects/123": * { "reason": "CONSUMER_INVALID", * "domain": "googleapis.com", * "metadata": { * "consumer": "projects/123", * "service": "storage.googleapis.com" * } * } * * Generated from protobuf enum CONSUMER_INVALID = 14; */ const CONSUMER_INVALID = 14; /** * The request is denied because it violates [VPC Service * Controls](https://cloud.google.com/vpc-service-controls/docs/overview). * The 'uid' field is a random generated identifier that customer can use it * to search the audit log for a request rejected by VPC Service Controls. For * more information, please refer [VPC Service Controls * Troubleshooting](https://cloud.google.com/vpc-service-controls/docs/troubleshooting#unique-id) * Example of an ErrorInfo when the consumer "projects/123" fails to call * Cloud Storage service because the request is prohibited by the VPC Service * Controls. * { "reason": "SECURITY_POLICY_VIOLATED", * "domain": "googleapis.com", * "metadata": { * "uid": "123456789abcde", * "consumer": "projects/123", * "service": "storage.googleapis.com" * } * } * * Generated from protobuf enum SECURITY_POLICY_VIOLATED = 15; */ const SECURITY_POLICY_VIOLATED = 15; /** * The request is denied because the provided access token has expired. * Example of an ErrorInfo when the request is calling Cloud Storage service * with an expired access token: * { "reason": "ACCESS_TOKEN_EXPIRED", * "domain": "googleapis.com", * "metadata": { * "service": "storage.googleapis.com", * "method": "google.storage.v1.Storage.GetObject" * } * } * * Generated from protobuf enum ACCESS_TOKEN_EXPIRED = 16; */ const ACCESS_TOKEN_EXPIRED = 16; /** * The request is denied because the provided access token doesn't have at * least one of the acceptable scopes required for the API. Please check * [OAuth 2.0 Scopes for Google * APIs](https://developers.google.com/identity/protocols/oauth2/scopes) for * the list of the OAuth 2.0 scopes that you might need to request to access * the API. * Example of an ErrorInfo when the request is calling Cloud Storage service * with an access token that is missing required scopes: * { "reason": "ACCESS_TOKEN_SCOPE_INSUFFICIENT", * "domain": "googleapis.com", * "metadata": { * "service": "storage.googleapis.com", * "method": "google.storage.v1.Storage.GetObject" * } * } * * Generated from protobuf enum ACCESS_TOKEN_SCOPE_INSUFFICIENT = 17; */ const ACCESS_TOKEN_SCOPE_INSUFFICIENT = 17; /** * The request is denied because the account associated with the provided * access token is in an invalid state, such as disabled or deleted. * For more information, see https://cloud.google.com/docs/authentication. * Warning: For privacy reasons, the server may not be able to disclose the * email address for some accounts. The client MUST NOT depend on the * availability of the `email` attribute. * Example of an ErrorInfo when the request is to the Cloud Storage API with * an access token that is associated with a disabled or deleted [service * account](http://cloud/iam/docs/service-accounts): * { "reason": "ACCOUNT_STATE_INVALID", * "domain": "googleapis.com", * "metadata": { * "service": "storage.googleapis.com", * "method": "google.storage.v1.Storage.GetObject", * "email": "user@123.iam.gserviceaccount.com" * } * } * * Generated from protobuf enum ACCOUNT_STATE_INVALID = 18; */ const ACCOUNT_STATE_INVALID = 18; /** * The request is denied because the type of the provided access token is not * supported by the API being called. * Example of an ErrorInfo when the request is to the Cloud Storage API with * an unsupported token type. * { "reason": "ACCESS_TOKEN_TYPE_UNSUPPORTED", * "domain": "googleapis.com", * "metadata": { * "service": "storage.googleapis.com", * "method": "google.storage.v1.Storage.GetObject" * } * } * * Generated from protobuf enum ACCESS_TOKEN_TYPE_UNSUPPORTED = 19; */ const ACCESS_TOKEN_TYPE_UNSUPPORTED = 19; /** * The request is denied because the request doesn't have any authentication * credentials. For more information regarding the supported authentication * strategies for Google Cloud APIs, see * https://cloud.google.com/docs/authentication. * Example of an ErrorInfo when the request is to the Cloud Storage API * without any authentication credentials. * { "reason": "CREDENTIALS_MISSING", * "domain": "googleapis.com", * "metadata": { * "service": "storage.googleapis.com", * "method": "google.storage.v1.Storage.GetObject" * } * } * * Generated from protobuf enum CREDENTIALS_MISSING = 20; */ const CREDENTIALS_MISSING = 20; /** * The request is denied because the provided project owning the resource * which acts as the [API * consumer](https://cloud.google.com/apis/design/glossary#api_consumer) is * invalid. It may be in a bad format or empty. * Example of an ErrorInfo when the request is to the Cloud Functions API, * but the offered resource project in the request in a bad format which can't * perform the ListFunctions method. * { "reason": "RESOURCE_PROJECT_INVALID", * "domain": "googleapis.com", * "metadata": { * "service": "cloudfunctions.googleapis.com", * "method": * "google.cloud.functions.v1.CloudFunctionsService.ListFunctions" * } * } * * Generated from protobuf enum RESOURCE_PROJECT_INVALID = 21; */ const RESOURCE_PROJECT_INVALID = 21; /** * The request is denied because the provided session cookie is missing, * invalid or failed to decode. * Example of an ErrorInfo when the request is calling Cloud Storage service * with a SID cookie which can't be decoded. * { "reason": "SESSION_COOKIE_INVALID", * "domain": "googleapis.com", * "metadata": { * "service": "storage.googleapis.com", * "method": "google.storage.v1.Storage.GetObject", * "cookie": "SID" * } * } * * Generated from protobuf enum SESSION_COOKIE_INVALID = 23; */ const SESSION_COOKIE_INVALID = 23; /** * The request is denied because the user is from a Google Workspace customer * that blocks their users from accessing a particular service. * Example scenario: https://support.google.com/a/answer/9197205?hl=en * Example of an ErrorInfo when access to Google Cloud Storage service is * blocked by the Google Workspace administrator: * { "reason": "USER_BLOCKED_BY_ADMIN", * "domain": "googleapis.com", * "metadata": { * "service": "storage.googleapis.com", * "method": "google.storage.v1.Storage.GetObject", * } * } * * Generated from protobuf enum USER_BLOCKED_BY_ADMIN = 24; */ const USER_BLOCKED_BY_ADMIN = 24; /** * The request is denied because the resource service usage is restricted * by administrators according to the organization policy constraint. * For more information see * https://cloud.google.com/resource-manager/docs/organization-policy/restricting-services. * Example of an ErrorInfo when access to Google Cloud Storage service is * restricted by Resource Usage Restriction policy: * { "reason": "RESOURCE_USAGE_RESTRICTION_VIOLATED", * "domain": "googleapis.com", * "metadata": { * "consumer": "projects/project-123", * "service": "storage.googleapis.com" * } * } * * Generated from protobuf enum RESOURCE_USAGE_RESTRICTION_VIOLATED = 25; */ const RESOURCE_USAGE_RESTRICTION_VIOLATED = 25; /** * Unimplemented. Do not use. * The request is denied because it contains unsupported system parameters in * URL query parameters or HTTP headers. For more information, * see https://cloud.google.com/apis/docs/system-parameters * Example of an ErrorInfo when access "pubsub.googleapis.com" service with * a request header of "x-goog-user-ip": * { "reason": "SYSTEM_PARAMETER_UNSUPPORTED", * "domain": "googleapis.com", * "metadata": { * "service": "pubsub.googleapis.com" * "parameter": "x-goog-user-ip" * } * } * * Generated from protobuf enum SYSTEM_PARAMETER_UNSUPPORTED = 26; */ const SYSTEM_PARAMETER_UNSUPPORTED = 26; /** * The request is denied because it violates Org Restriction: the requested * resource does not belong to allowed organizations specified in * "X-Goog-Allowed-Resources" header. * Example of an ErrorInfo when accessing a GCP resource that is restricted by * Org Restriction for "pubsub.googleapis.com" service. * { * reason: "ORG_RESTRICTION_VIOLATION" * domain: "googleapis.com" * metadata { * "consumer":"projects/123456" * "service": "pubsub.googleapis.com" * } * } * * Generated from protobuf enum ORG_RESTRICTION_VIOLATION = 27; */ const ORG_RESTRICTION_VIOLATION = 27; /** * The request is denied because "X-Goog-Allowed-Resources" header is in a bad * format. * Example of an ErrorInfo when * accessing "pubsub.googleapis.com" service with an invalid * "X-Goog-Allowed-Resources" request header. * { * reason: "ORG_RESTRICTION_HEADER_INVALID" * domain: "googleapis.com" * metadata { * "consumer":"projects/123456" * "service": "pubsub.googleapis.com" * } * } * * Generated from protobuf enum ORG_RESTRICTION_HEADER_INVALID = 28; */ const ORG_RESTRICTION_HEADER_INVALID = 28; /** * Unimplemented. Do not use. * The request is calling a service that is not visible to the consumer. * Example of an ErrorInfo when the consumer "projects/123" contacting * "pubsub.googleapis.com" service which is not visible to the consumer. * { "reason": "SERVICE_NOT_VISIBLE", * "domain": "googleapis.com", * "metadata": { * "consumer": "projects/123", * "service": "pubsub.googleapis.com" * } * } * This response indicates the "pubsub.googleapis.com" is not visible to * "projects/123" (or it may not exist). * * Generated from protobuf enum SERVICE_NOT_VISIBLE = 29; */ const SERVICE_NOT_VISIBLE = 29; /** * The request is related to a project for which GCP access is suspended. * Example of an ErrorInfo when the consumer "projects/123" fails to contact * "pubsub.googleapis.com" service because GCP access is suspended: * { "reason": "GCP_SUSPENDED", * "domain": "googleapis.com", * "metadata": { * "consumer": "projects/123", * "service": "pubsub.googleapis.com" * } * } * This response indicates the associated GCP account has been suspended. * * Generated from protobuf enum GCP_SUSPENDED = 30; */ const GCP_SUSPENDED = 30; /** * The request violates the location policies when creating resources in * the restricted region. * Example of an ErrorInfo when creating the Cloud Storage Bucket by * "projects/123" for service storage.googleapis.com: * { "reason": "LOCATION_POLICY_VIOLATED", * "domain": "googleapis.com", * "metadata": { * "consumer": "projects/123", * "service": "storage.googleapis.com", * } * } * This response indicates creating the Cloud Storage Bucket in * "locations/asia-northeast3" violates at least one location policy. * The troubleshooting guidance is provided in the Help links. * * Generated from protobuf enum LOCATION_POLICY_VIOLATED = 31; */ const LOCATION_POLICY_VIOLATED = 31; /** * The request is denied because origin request header is missing. * Example of an ErrorInfo when * accessing "pubsub.googleapis.com" service with an empty "Origin" request * header. * { * reason: "MISSING_ORIGIN" * domain: "googleapis.com" * metadata { * "consumer":"projects/123456" * "service": "pubsub.googleapis.com" * } * } * * Generated from protobuf enum MISSING_ORIGIN = 33; */ const MISSING_ORIGIN = 33; /** * The request is denied because the request contains more than one credential * type that are individually acceptable, but not together. The customer * should retry their request with only one set of credentials. * Example of an ErrorInfo when * accessing "pubsub.googleapis.com" service with overloaded credentials. * { * reason: "OVERLOADED_CREDENTIALS" * domain: "googleapis.com" * metadata { * "consumer":"projects/123456" * "service": "pubsub.googleapis.com" * } * } * * Generated from protobuf enum OVERLOADED_CREDENTIALS = 34; */ const OVERLOADED_CREDENTIALS = 34; private static $valueToName = [ self::ERROR_REASON_UNSPECIFIED => 'ERROR_REASON_UNSPECIFIED', self::SERVICE_DISABLED => 'SERVICE_DISABLED', self::BILLING_DISABLED => 'BILLING_DISABLED', self::API_KEY_INVALID => 'API_KEY_INVALID', self::API_KEY_SERVICE_BLOCKED => 'API_KEY_SERVICE_BLOCKED', self::API_KEY_HTTP_REFERRER_BLOCKED => 'API_KEY_HTTP_REFERRER_BLOCKED', self::API_KEY_IP_ADDRESS_BLOCKED => 'API_KEY_IP_ADDRESS_BLOCKED', self::API_KEY_ANDROID_APP_BLOCKED => 'API_KEY_ANDROID_APP_BLOCKED', self::API_KEY_IOS_APP_BLOCKED => 'API_KEY_IOS_APP_BLOCKED', self::RATE_LIMIT_EXCEEDED => 'RATE_LIMIT_EXCEEDED', self::RESOURCE_QUOTA_EXCEEDED => 'RESOURCE_QUOTA_EXCEEDED', self::LOCATION_TAX_POLICY_VIOLATED => 'LOCATION_TAX_POLICY_VIOLATED', self::USER_PROJECT_DENIED => 'USER_PROJECT_DENIED', self::CONSUMER_SUSPENDED => 'CONSUMER_SUSPENDED', self::CONSUMER_INVALID => 'CONSUMER_INVALID', self::SECURITY_POLICY_VIOLATED => 'SECURITY_POLICY_VIOLATED', self::ACCESS_TOKEN_EXPIRED => 'ACCESS_TOKEN_EXPIRED', self::ACCESS_TOKEN_SCOPE_INSUFFICIENT => 'ACCESS_TOKEN_SCOPE_INSUFFICIENT', self::ACCOUNT_STATE_INVALID => 'ACCOUNT_STATE_INVALID', self::ACCESS_TOKEN_TYPE_UNSUPPORTED => 'ACCESS_TOKEN_TYPE_UNSUPPORTED', self::CREDENTIALS_MISSING => 'CREDENTIALS_MISSING', self::RESOURCE_PROJECT_INVALID => 'RESOURCE_PROJECT_INVALID', self::SESSION_COOKIE_INVALID => 'SESSION_COOKIE_INVALID', self::USER_BLOCKED_BY_ADMIN => 'USER_BLOCKED_BY_ADMIN', self::RESOURCE_USAGE_RESTRICTION_VIOLATED => 'RESOURCE_USAGE_RESTRICTION_VIOLATED', self::SYSTEM_PARAMETER_UNSUPPORTED => 'SYSTEM_PARAMETER_UNSUPPORTED', self::ORG_RESTRICTION_VIOLATION => 'ORG_RESTRICTION_VIOLATION', self::ORG_RESTRICTION_HEADER_INVALID => 'ORG_RESTRICTION_HEADER_INVALID', self::SERVICE_NOT_VISIBLE => 'SERVICE_NOT_VISIBLE', self::GCP_SUSPENDED => 'GCP_SUSPENDED', self::LOCATION_POLICY_VIOLATED => 'LOCATION_POLICY_VIOLATED', self::MISSING_ORIGIN => 'MISSING_ORIGIN', self::OVERLOADED_CREDENTIALS => 'OVERLOADED_CREDENTIALS', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/FieldBehavior.php ================================================ google.api.FieldBehavior */ class FieldBehavior { /** * Conventional default for enums. Do not use this. * * Generated from protobuf enum FIELD_BEHAVIOR_UNSPECIFIED = 0; */ const FIELD_BEHAVIOR_UNSPECIFIED = 0; /** * Specifically denotes a field as optional. * While all fields in protocol buffers are optional, this may be specified * for emphasis if appropriate. * * Generated from protobuf enum OPTIONAL = 1; */ const OPTIONAL = 1; /** * Denotes a field as required. * This indicates that the field **must** be provided as part of the request, * and failure to do so will cause an error (usually `INVALID_ARGUMENT`). * * Generated from protobuf enum REQUIRED = 2; */ const REQUIRED = 2; /** * Denotes a field as output only. * This indicates that the field is provided in responses, but including the * field in a request does nothing (the server *must* ignore it and * *must not* throw an error as a result of the field's presence). * * Generated from protobuf enum OUTPUT_ONLY = 3; */ const OUTPUT_ONLY = 3; /** * Denotes a field as input only. * This indicates that the field is provided in requests, and the * corresponding field is not included in output. * * Generated from protobuf enum INPUT_ONLY = 4; */ const INPUT_ONLY = 4; /** * Denotes a field as immutable. * This indicates that the field may be set once in a request to create a * resource, but may not be changed thereafter. * * Generated from protobuf enum IMMUTABLE = 5; */ const IMMUTABLE = 5; /** * Denotes that a (repeated) field is an unordered list. * This indicates that the service may provide the elements of the list * in any arbitrary order, rather than the order the user originally * provided. Additionally, the list's order may or may not be stable. * * Generated from protobuf enum UNORDERED_LIST = 6; */ const UNORDERED_LIST = 6; /** * Denotes that this field returns a non-empty default value if not set. * This indicates that if the user provides the empty value in a request, * a non-empty value will be returned. The user will not be aware of what * non-empty value to expect. * * Generated from protobuf enum NON_EMPTY_DEFAULT = 7; */ const NON_EMPTY_DEFAULT = 7; /** * Denotes that the field in a resource (a message annotated with * google.api.resource) is used in the resource name to uniquely identify the * resource. For AIP-compliant APIs, this should only be applied to the * `name` field on the resource. * This behavior should not be applied to references to other resources within * the message. * The identifier field of resources often have different field behavior * depending on the request it is embedded in (e.g. for Create methods name * is optional and unused, while for Update methods it is required). Instead * of method-specific annotations, only `IDENTIFIER` is required. * * Generated from protobuf enum IDENTIFIER = 8; */ const IDENTIFIER = 8; private static $valueToName = [ self::FIELD_BEHAVIOR_UNSPECIFIED => 'FIELD_BEHAVIOR_UNSPECIFIED', self::OPTIONAL => 'OPTIONAL', self::REQUIRED => 'REQUIRED', self::OUTPUT_ONLY => 'OUTPUT_ONLY', self::INPUT_ONLY => 'INPUT_ONLY', self::IMMUTABLE => 'IMMUTABLE', self::UNORDERED_LIST => 'UNORDERED_LIST', self::NON_EMPTY_DEFAULT => 'NON_EMPTY_DEFAULT', self::IDENTIFIER => 'IDENTIFIER', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/FieldInfo/Format.php ================================================ google.api.FieldInfo.Format */ class Format { /** * Default, unspecified value. * * Generated from protobuf enum FORMAT_UNSPECIFIED = 0; */ const FORMAT_UNSPECIFIED = 0; /** * Universally Unique Identifier, version 4, value as defined by * https://datatracker.ietf.org/doc/html/rfc4122. The value may be * normalized to entirely lowercase letters. For example, the value * `F47AC10B-58CC-0372-8567-0E02B2C3D479` would be normalized to * `f47ac10b-58cc-0372-8567-0e02b2c3d479`. * * Generated from protobuf enum UUID4 = 1; */ const UUID4 = 1; /** * Internet Protocol v4 value as defined by [RFC * 791](https://datatracker.ietf.org/doc/html/rfc791). The value may be * condensed, with leading zeros in each octet stripped. For example, * `001.022.233.040` would be condensed to `1.22.233.40`. * * Generated from protobuf enum IPV4 = 2; */ const IPV4 = 2; /** * Internet Protocol v6 value as defined by [RFC * 2460](https://datatracker.ietf.org/doc/html/rfc2460). The value may be * normalized to entirely lowercase letters with zeros compressed, following * [RFC 5952](https://datatracker.ietf.org/doc/html/rfc5952). For example, * the value `2001:0DB8:0::0` would be normalized to `2001:db8::`. * * Generated from protobuf enum IPV6 = 3; */ const IPV6 = 3; /** * An IP address in either v4 or v6 format as described by the individual * values defined herein. See the comments on the IPV4 and IPV6 types for * allowed normalizations of each. * * Generated from protobuf enum IPV4_OR_IPV6 = 4; */ const IPV4_OR_IPV6 = 4; private static $valueToName = [ self::FORMAT_UNSPECIFIED => 'FORMAT_UNSPECIFIED', self::UUID4 => 'UUID4', self::IPV4 => 'IPV4', self::IPV6 => 'IPV6', self::IPV4_OR_IPV6 => 'IPV4_OR_IPV6', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/FieldInfo.php ================================================ google.api.FieldInfo */ class FieldInfo extends \Google\Protobuf\Internal\Message { /** * The standard format of a field value. This does not explicitly configure * any API consumer, just documents the API's format for the field it is * applied to. * * Generated from protobuf field .google.api.FieldInfo.Format format = 1; */ protected $format = 0; /** * The type(s) that the annotated, generic field may represent. * Currently, this must only be used on fields of type `google.protobuf.Any`. * Supporting other generic types may be considered in the future. * * Generated from protobuf field repeated .google.api.TypeReference referenced_types = 2; */ private $referenced_types; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type int $format * The standard format of a field value. This does not explicitly configure * any API consumer, just documents the API's format for the field it is * applied to. * @type array<\Google\Api\TypeReference>|\Google\Protobuf\Internal\RepeatedField $referenced_types * The type(s) that the annotated, generic field may represent. * Currently, this must only be used on fields of type `google.protobuf.Any`. * Supporting other generic types may be considered in the future. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\FieldInfo::initOnce(); parent::__construct($data); } /** * The standard format of a field value. This does not explicitly configure * any API consumer, just documents the API's format for the field it is * applied to. * * Generated from protobuf field .google.api.FieldInfo.Format format = 1; * @return int */ public function getFormat() { return $this->format; } /** * The standard format of a field value. This does not explicitly configure * any API consumer, just documents the API's format for the field it is * applied to. * * Generated from protobuf field .google.api.FieldInfo.Format format = 1; * @param int $var * @return $this */ public function setFormat($var) { GPBUtil::checkEnum($var, \Google\Api\FieldInfo\Format::class); $this->format = $var; return $this; } /** * The type(s) that the annotated, generic field may represent. * Currently, this must only be used on fields of type `google.protobuf.Any`. * Supporting other generic types may be considered in the future. * * Generated from protobuf field repeated .google.api.TypeReference referenced_types = 2; * @return \Google\Protobuf\Internal\RepeatedField */ public function getReferencedTypes() { return $this->referenced_types; } /** * The type(s) that the annotated, generic field may represent. * Currently, this must only be used on fields of type `google.protobuf.Any`. * Supporting other generic types may be considered in the future. * * Generated from protobuf field repeated .google.api.TypeReference referenced_types = 2; * @param array<\Google\Api\TypeReference>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setReferencedTypes($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Api\TypeReference::class); $this->referenced_types = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/FieldPolicy.php ================================================ google.api.FieldPolicy */ class FieldPolicy extends \Google\Protobuf\Internal\Message { /** * Selects one or more request or response message fields to apply this * `FieldPolicy`. * When a `FieldPolicy` is used in proto annotation, the selector must * be left as empty. The service config generator will automatically fill * the correct value. * When a `FieldPolicy` is used in service config, the selector must be a * comma-separated string with valid request or response field paths, * such as "foo.bar" or "foo.bar,foo.baz". * * Generated from protobuf field string selector = 1; */ protected $selector = ''; /** * Specifies the required permission(s) for the resource referred to by the * field. It requires the field contains a valid resource reference, and * the request must pass the permission checks to proceed. For example, * "resourcemanager.projects.get". * * Generated from protobuf field string resource_permission = 2; */ protected $resource_permission = ''; /** * Specifies the resource type for the resource referred to by the field. * * Generated from protobuf field string resource_type = 3; */ protected $resource_type = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $selector * Selects one or more request or response message fields to apply this * `FieldPolicy`. * When a `FieldPolicy` is used in proto annotation, the selector must * be left as empty. The service config generator will automatically fill * the correct value. * When a `FieldPolicy` is used in service config, the selector must be a * comma-separated string with valid request or response field paths, * such as "foo.bar" or "foo.bar,foo.baz". * @type string $resource_permission * Specifies the required permission(s) for the resource referred to by the * field. It requires the field contains a valid resource reference, and * the request must pass the permission checks to proceed. For example, * "resourcemanager.projects.get". * @type string $resource_type * Specifies the resource type for the resource referred to by the field. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Policy::initOnce(); parent::__construct($data); } /** * Selects one or more request or response message fields to apply this * `FieldPolicy`. * When a `FieldPolicy` is used in proto annotation, the selector must * be left as empty. The service config generator will automatically fill * the correct value. * When a `FieldPolicy` is used in service config, the selector must be a * comma-separated string with valid request or response field paths, * such as "foo.bar" or "foo.bar,foo.baz". * * Generated from protobuf field string selector = 1; * @return string */ public function getSelector() { return $this->selector; } /** * Selects one or more request or response message fields to apply this * `FieldPolicy`. * When a `FieldPolicy` is used in proto annotation, the selector must * be left as empty. The service config generator will automatically fill * the correct value. * When a `FieldPolicy` is used in service config, the selector must be a * comma-separated string with valid request or response field paths, * such as "foo.bar" or "foo.bar,foo.baz". * * Generated from protobuf field string selector = 1; * @param string $var * @return $this */ public function setSelector($var) { GPBUtil::checkString($var, True); $this->selector = $var; return $this; } /** * Specifies the required permission(s) for the resource referred to by the * field. It requires the field contains a valid resource reference, and * the request must pass the permission checks to proceed. For example, * "resourcemanager.projects.get". * * Generated from protobuf field string resource_permission = 2; * @return string */ public function getResourcePermission() { return $this->resource_permission; } /** * Specifies the required permission(s) for the resource referred to by the * field. It requires the field contains a valid resource reference, and * the request must pass the permission checks to proceed. For example, * "resourcemanager.projects.get". * * Generated from protobuf field string resource_permission = 2; * @param string $var * @return $this */ public function setResourcePermission($var) { GPBUtil::checkString($var, True); $this->resource_permission = $var; return $this; } /** * Specifies the resource type for the resource referred to by the field. * * Generated from protobuf field string resource_type = 3; * @return string */ public function getResourceType() { return $this->resource_type; } /** * Specifies the resource type for the resource referred to by the field. * * Generated from protobuf field string resource_type = 3; * @param string $var * @return $this */ public function setResourceType($var) { GPBUtil::checkString($var, True); $this->resource_type = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/GoSettings.php ================================================ google.api.GoSettings */ class GoSettings extends \Google\Protobuf\Internal\Message { /** * Some settings. * * Generated from protobuf field .google.api.CommonLanguageSettings common = 1; */ protected $common = null; /** * Map of service names to renamed services. Keys are the package relative * service names and values are the name to be used for the service client * and call options. * publishing: * go_settings: * renamed_services: * Publisher: TopicAdmin * * Generated from protobuf field map renamed_services = 2; */ private $renamed_services; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type \Google\Api\CommonLanguageSettings $common * Some settings. * @type array|\Google\Protobuf\Internal\MapField $renamed_services * Map of service names to renamed services. Keys are the package relative * service names and values are the name to be used for the service client * and call options. * publishing: * go_settings: * renamed_services: * Publisher: TopicAdmin * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Client::initOnce(); parent::__construct($data); } /** * Some settings. * * Generated from protobuf field .google.api.CommonLanguageSettings common = 1; * @return \Google\Api\CommonLanguageSettings|null */ public function getCommon() { return $this->common; } public function hasCommon() { return isset($this->common); } public function clearCommon() { unset($this->common); } /** * Some settings. * * Generated from protobuf field .google.api.CommonLanguageSettings common = 1; * @param \Google\Api\CommonLanguageSettings $var * @return $this */ public function setCommon($var) { GPBUtil::checkMessage($var, \Google\Api\CommonLanguageSettings::class); $this->common = $var; return $this; } /** * Map of service names to renamed services. Keys are the package relative * service names and values are the name to be used for the service client * and call options. * publishing: * go_settings: * renamed_services: * Publisher: TopicAdmin * * Generated from protobuf field map renamed_services = 2; * @return \Google\Protobuf\Internal\MapField */ public function getRenamedServices() { return $this->renamed_services; } /** * Map of service names to renamed services. Keys are the package relative * service names and values are the name to be used for the service client * and call options. * publishing: * go_settings: * renamed_services: * Publisher: TopicAdmin * * Generated from protobuf field map renamed_services = 2; * @param array|\Google\Protobuf\Internal\MapField $var * @return $this */ public function setRenamedServices($var) { $arr = GPBUtil::checkMapField($var, \Google\Protobuf\Internal\GPBType::STRING, \Google\Protobuf\Internal\GPBType::STRING); $this->renamed_services = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/Http.php ================================================ google.api.Http */ class Http extends \Google\Protobuf\Internal\Message { /** * A list of HTTP configuration rules that apply to individual API methods. * **NOTE:** All service configuration rules follow "last one wins" order. * * Generated from protobuf field repeated .google.api.HttpRule rules = 1; */ private $rules; /** * When set to true, URL path parameters will be fully URI-decoded except in * cases of single segment matches in reserved expansion, where "%2F" will be * left encoded. * The default behavior is to not decode RFC 6570 reserved characters in multi * segment matches. * * Generated from protobuf field bool fully_decode_reserved_expansion = 2; */ protected $fully_decode_reserved_expansion = false; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type array<\Google\Api\HttpRule>|\Google\Protobuf\Internal\RepeatedField $rules * A list of HTTP configuration rules that apply to individual API methods. * **NOTE:** All service configuration rules follow "last one wins" order. * @type bool $fully_decode_reserved_expansion * When set to true, URL path parameters will be fully URI-decoded except in * cases of single segment matches in reserved expansion, where "%2F" will be * left encoded. * The default behavior is to not decode RFC 6570 reserved characters in multi * segment matches. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Http::initOnce(); parent::__construct($data); } /** * A list of HTTP configuration rules that apply to individual API methods. * **NOTE:** All service configuration rules follow "last one wins" order. * * Generated from protobuf field repeated .google.api.HttpRule rules = 1; * @return \Google\Protobuf\Internal\RepeatedField */ public function getRules() { return $this->rules; } /** * A list of HTTP configuration rules that apply to individual API methods. * **NOTE:** All service configuration rules follow "last one wins" order. * * Generated from protobuf field repeated .google.api.HttpRule rules = 1; * @param array<\Google\Api\HttpRule>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setRules($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Api\HttpRule::class); $this->rules = $arr; return $this; } /** * When set to true, URL path parameters will be fully URI-decoded except in * cases of single segment matches in reserved expansion, where "%2F" will be * left encoded. * The default behavior is to not decode RFC 6570 reserved characters in multi * segment matches. * * Generated from protobuf field bool fully_decode_reserved_expansion = 2; * @return bool */ public function getFullyDecodeReservedExpansion() { return $this->fully_decode_reserved_expansion; } /** * When set to true, URL path parameters will be fully URI-decoded except in * cases of single segment matches in reserved expansion, where "%2F" will be * left encoded. * The default behavior is to not decode RFC 6570 reserved characters in multi * segment matches. * * Generated from protobuf field bool fully_decode_reserved_expansion = 2; * @param bool $var * @return $this */ public function setFullyDecodeReservedExpansion($var) { GPBUtil::checkBool($var); $this->fully_decode_reserved_expansion = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/HttpBody.php ================================================ google.api.HttpBody */ class HttpBody extends \Google\Protobuf\Internal\Message { /** * The HTTP Content-Type header value specifying the content type of the body. * * Generated from protobuf field string content_type = 1; */ protected $content_type = ''; /** * The HTTP request/response body as raw binary. * * Generated from protobuf field bytes data = 2; */ protected $data = ''; /** * Application specific response metadata. Must be set in the first response * for streaming APIs. * * Generated from protobuf field repeated .google.protobuf.Any extensions = 3; */ private $extensions; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $content_type * The HTTP Content-Type header value specifying the content type of the body. * @type string $data * The HTTP request/response body as raw binary. * @type array<\Google\Protobuf\Any>|\Google\Protobuf\Internal\RepeatedField $extensions * Application specific response metadata. Must be set in the first response * for streaming APIs. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Httpbody::initOnce(); parent::__construct($data); } /** * The HTTP Content-Type header value specifying the content type of the body. * * Generated from protobuf field string content_type = 1; * @return string */ public function getContentType() { return $this->content_type; } /** * The HTTP Content-Type header value specifying the content type of the body. * * Generated from protobuf field string content_type = 1; * @param string $var * @return $this */ public function setContentType($var) { GPBUtil::checkString($var, True); $this->content_type = $var; return $this; } /** * The HTTP request/response body as raw binary. * * Generated from protobuf field bytes data = 2; * @return string */ public function getData() { return $this->data; } /** * The HTTP request/response body as raw binary. * * Generated from protobuf field bytes data = 2; * @param string $var * @return $this */ public function setData($var) { GPBUtil::checkString($var, False); $this->data = $var; return $this; } /** * Application specific response metadata. Must be set in the first response * for streaming APIs. * * Generated from protobuf field repeated .google.protobuf.Any extensions = 3; * @return \Google\Protobuf\Internal\RepeatedField */ public function getExtensions() { return $this->extensions; } /** * Application specific response metadata. Must be set in the first response * for streaming APIs. * * Generated from protobuf field repeated .google.protobuf.Any extensions = 3; * @param array<\Google\Protobuf\Any>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setExtensions($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Any::class); $this->extensions = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/HttpRule.php ================================================ google.api.HttpRule */ class HttpRule extends \Google\Protobuf\Internal\Message { /** * Selects a method to which this rule applies. * Refer to [selector][google.api.DocumentationRule.selector] for syntax * details. * * Generated from protobuf field string selector = 1; */ protected $selector = ''; /** * The name of the request field whose value is mapped to the HTTP request * body, or `*` for mapping all request fields not captured by the path * pattern to the HTTP body, or omitted for not having any HTTP request body. * NOTE: the referred field must be present at the top-level of the request * message type. * * Generated from protobuf field string body = 7; */ protected $body = ''; /** * Optional. The name of the response field whose value is mapped to the HTTP * response body. When omitted, the entire response message will be used * as the HTTP response body. * NOTE: The referred field must be present at the top-level of the response * message type. * * Generated from protobuf field string response_body = 12; */ protected $response_body = ''; /** * Additional HTTP bindings for the selector. Nested bindings must * not contain an `additional_bindings` field themselves (that is, * the nesting may only be one level deep). * * Generated from protobuf field repeated .google.api.HttpRule additional_bindings = 11; */ private $additional_bindings; protected $pattern; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $selector * Selects a method to which this rule applies. * Refer to [selector][google.api.DocumentationRule.selector] for syntax * details. * @type string $get * Maps to HTTP GET. Used for listing and getting information about * resources. * @type string $put * Maps to HTTP PUT. Used for replacing a resource. * @type string $post * Maps to HTTP POST. Used for creating a resource or performing an action. * @type string $delete * Maps to HTTP DELETE. Used for deleting a resource. * @type string $patch * Maps to HTTP PATCH. Used for updating a resource. * @type \Google\Api\CustomHttpPattern $custom * The custom pattern is used for specifying an HTTP method that is not * included in the `pattern` field, such as HEAD, or "*" to leave the * HTTP method unspecified for this rule. The wild-card rule is useful * for services that provide content to Web (HTML) clients. * @type string $body * The name of the request field whose value is mapped to the HTTP request * body, or `*` for mapping all request fields not captured by the path * pattern to the HTTP body, or omitted for not having any HTTP request body. * NOTE: the referred field must be present at the top-level of the request * message type. * @type string $response_body * Optional. The name of the response field whose value is mapped to the HTTP * response body. When omitted, the entire response message will be used * as the HTTP response body. * NOTE: The referred field must be present at the top-level of the response * message type. * @type array<\Google\Api\HttpRule>|\Google\Protobuf\Internal\RepeatedField $additional_bindings * Additional HTTP bindings for the selector. Nested bindings must * not contain an `additional_bindings` field themselves (that is, * the nesting may only be one level deep). * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Http::initOnce(); parent::__construct($data); } /** * Selects a method to which this rule applies. * Refer to [selector][google.api.DocumentationRule.selector] for syntax * details. * * Generated from protobuf field string selector = 1; * @return string */ public function getSelector() { return $this->selector; } /** * Selects a method to which this rule applies. * Refer to [selector][google.api.DocumentationRule.selector] for syntax * details. * * Generated from protobuf field string selector = 1; * @param string $var * @return $this */ public function setSelector($var) { GPBUtil::checkString($var, True); $this->selector = $var; return $this; } /** * Maps to HTTP GET. Used for listing and getting information about * resources. * * Generated from protobuf field string get = 2; * @return string */ public function getGet() { return $this->readOneof(2); } public function hasGet() { return $this->hasOneof(2); } /** * Maps to HTTP GET. Used for listing and getting information about * resources. * * Generated from protobuf field string get = 2; * @param string $var * @return $this */ public function setGet($var) { GPBUtil::checkString($var, True); $this->writeOneof(2, $var); return $this; } /** * Maps to HTTP PUT. Used for replacing a resource. * * Generated from protobuf field string put = 3; * @return string */ public function getPut() { return $this->readOneof(3); } public function hasPut() { return $this->hasOneof(3); } /** * Maps to HTTP PUT. Used for replacing a resource. * * Generated from protobuf field string put = 3; * @param string $var * @return $this */ public function setPut($var) { GPBUtil::checkString($var, True); $this->writeOneof(3, $var); return $this; } /** * Maps to HTTP POST. Used for creating a resource or performing an action. * * Generated from protobuf field string post = 4; * @return string */ public function getPost() { return $this->readOneof(4); } public function hasPost() { return $this->hasOneof(4); } /** * Maps to HTTP POST. Used for creating a resource or performing an action. * * Generated from protobuf field string post = 4; * @param string $var * @return $this */ public function setPost($var) { GPBUtil::checkString($var, True); $this->writeOneof(4, $var); return $this; } /** * Maps to HTTP DELETE. Used for deleting a resource. * * Generated from protobuf field string delete = 5; * @return string */ public function getDelete() { return $this->readOneof(5); } public function hasDelete() { return $this->hasOneof(5); } /** * Maps to HTTP DELETE. Used for deleting a resource. * * Generated from protobuf field string delete = 5; * @param string $var * @return $this */ public function setDelete($var) { GPBUtil::checkString($var, True); $this->writeOneof(5, $var); return $this; } /** * Maps to HTTP PATCH. Used for updating a resource. * * Generated from protobuf field string patch = 6; * @return string */ public function getPatch() { return $this->readOneof(6); } public function hasPatch() { return $this->hasOneof(6); } /** * Maps to HTTP PATCH. Used for updating a resource. * * Generated from protobuf field string patch = 6; * @param string $var * @return $this */ public function setPatch($var) { GPBUtil::checkString($var, True); $this->writeOneof(6, $var); return $this; } /** * The custom pattern is used for specifying an HTTP method that is not * included in the `pattern` field, such as HEAD, or "*" to leave the * HTTP method unspecified for this rule. The wild-card rule is useful * for services that provide content to Web (HTML) clients. * * Generated from protobuf field .google.api.CustomHttpPattern custom = 8; * @return \Google\Api\CustomHttpPattern|null */ public function getCustom() { return $this->readOneof(8); } public function hasCustom() { return $this->hasOneof(8); } /** * The custom pattern is used for specifying an HTTP method that is not * included in the `pattern` field, such as HEAD, or "*" to leave the * HTTP method unspecified for this rule. The wild-card rule is useful * for services that provide content to Web (HTML) clients. * * Generated from protobuf field .google.api.CustomHttpPattern custom = 8; * @param \Google\Api\CustomHttpPattern $var * @return $this */ public function setCustom($var) { GPBUtil::checkMessage($var, \Google\Api\CustomHttpPattern::class); $this->writeOneof(8, $var); return $this; } /** * The name of the request field whose value is mapped to the HTTP request * body, or `*` for mapping all request fields not captured by the path * pattern to the HTTP body, or omitted for not having any HTTP request body. * NOTE: the referred field must be present at the top-level of the request * message type. * * Generated from protobuf field string body = 7; * @return string */ public function getBody() { return $this->body; } /** * The name of the request field whose value is mapped to the HTTP request * body, or `*` for mapping all request fields not captured by the path * pattern to the HTTP body, or omitted for not having any HTTP request body. * NOTE: the referred field must be present at the top-level of the request * message type. * * Generated from protobuf field string body = 7; * @param string $var * @return $this */ public function setBody($var) { GPBUtil::checkString($var, True); $this->body = $var; return $this; } /** * Optional. The name of the response field whose value is mapped to the HTTP * response body. When omitted, the entire response message will be used * as the HTTP response body. * NOTE: The referred field must be present at the top-level of the response * message type. * * Generated from protobuf field string response_body = 12; * @return string */ public function getResponseBody() { return $this->response_body; } /** * Optional. The name of the response field whose value is mapped to the HTTP * response body. When omitted, the entire response message will be used * as the HTTP response body. * NOTE: The referred field must be present at the top-level of the response * message type. * * Generated from protobuf field string response_body = 12; * @param string $var * @return $this */ public function setResponseBody($var) { GPBUtil::checkString($var, True); $this->response_body = $var; return $this; } /** * Additional HTTP bindings for the selector. Nested bindings must * not contain an `additional_bindings` field themselves (that is, * the nesting may only be one level deep). * * Generated from protobuf field repeated .google.api.HttpRule additional_bindings = 11; * @return \Google\Protobuf\Internal\RepeatedField */ public function getAdditionalBindings() { return $this->additional_bindings; } /** * Additional HTTP bindings for the selector. Nested bindings must * not contain an `additional_bindings` field themselves (that is, * the nesting may only be one level deep). * * Generated from protobuf field repeated .google.api.HttpRule additional_bindings = 11; * @param array<\Google\Api\HttpRule>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setAdditionalBindings($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Api\HttpRule::class); $this->additional_bindings = $arr; return $this; } /** * @return string */ public function getPattern() { return $this->whichOneof("pattern"); } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/JavaSettings.php ================================================ google.api.JavaSettings */ class JavaSettings extends \Google\Protobuf\Internal\Message { /** * The package name to use in Java. Clobbers the java_package option * set in the protobuf. This should be used **only** by APIs * who have already set the language_settings.java.package_name" field * in gapic.yaml. API teams should use the protobuf java_package option * where possible. * Example of a YAML configuration:: * publishing: * java_settings: * library_package: com.google.cloud.pubsub.v1 * * Generated from protobuf field string library_package = 1; */ protected $library_package = ''; /** * Configure the Java class name to use instead of the service's for its * corresponding generated GAPIC client. Keys are fully-qualified * service names as they appear in the protobuf (including the full * the language_settings.java.interface_names" field in gapic.yaml. API * teams should otherwise use the service name as it appears in the * protobuf. * Example of a YAML configuration:: * publishing: * java_settings: * service_class_names: * - google.pubsub.v1.Publisher: TopicAdmin * - google.pubsub.v1.Subscriber: SubscriptionAdmin * * Generated from protobuf field map service_class_names = 2; */ private $service_class_names; /** * Some settings. * * Generated from protobuf field .google.api.CommonLanguageSettings common = 3; */ protected $common = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $library_package * The package name to use in Java. Clobbers the java_package option * set in the protobuf. This should be used **only** by APIs * who have already set the language_settings.java.package_name" field * in gapic.yaml. API teams should use the protobuf java_package option * where possible. * Example of a YAML configuration:: * publishing: * java_settings: * library_package: com.google.cloud.pubsub.v1 * @type array|\Google\Protobuf\Internal\MapField $service_class_names * Configure the Java class name to use instead of the service's for its * corresponding generated GAPIC client. Keys are fully-qualified * service names as they appear in the protobuf (including the full * the language_settings.java.interface_names" field in gapic.yaml. API * teams should otherwise use the service name as it appears in the * protobuf. * Example of a YAML configuration:: * publishing: * java_settings: * service_class_names: * - google.pubsub.v1.Publisher: TopicAdmin * - google.pubsub.v1.Subscriber: SubscriptionAdmin * @type \Google\Api\CommonLanguageSettings $common * Some settings. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Client::initOnce(); parent::__construct($data); } /** * The package name to use in Java. Clobbers the java_package option * set in the protobuf. This should be used **only** by APIs * who have already set the language_settings.java.package_name" field * in gapic.yaml. API teams should use the protobuf java_package option * where possible. * Example of a YAML configuration:: * publishing: * java_settings: * library_package: com.google.cloud.pubsub.v1 * * Generated from protobuf field string library_package = 1; * @return string */ public function getLibraryPackage() { return $this->library_package; } /** * The package name to use in Java. Clobbers the java_package option * set in the protobuf. This should be used **only** by APIs * who have already set the language_settings.java.package_name" field * in gapic.yaml. API teams should use the protobuf java_package option * where possible. * Example of a YAML configuration:: * publishing: * java_settings: * library_package: com.google.cloud.pubsub.v1 * * Generated from protobuf field string library_package = 1; * @param string $var * @return $this */ public function setLibraryPackage($var) { GPBUtil::checkString($var, True); $this->library_package = $var; return $this; } /** * Configure the Java class name to use instead of the service's for its * corresponding generated GAPIC client. Keys are fully-qualified * service names as they appear in the protobuf (including the full * the language_settings.java.interface_names" field in gapic.yaml. API * teams should otherwise use the service name as it appears in the * protobuf. * Example of a YAML configuration:: * publishing: * java_settings: * service_class_names: * - google.pubsub.v1.Publisher: TopicAdmin * - google.pubsub.v1.Subscriber: SubscriptionAdmin * * Generated from protobuf field map service_class_names = 2; * @return \Google\Protobuf\Internal\MapField */ public function getServiceClassNames() { return $this->service_class_names; } /** * Configure the Java class name to use instead of the service's for its * corresponding generated GAPIC client. Keys are fully-qualified * service names as they appear in the protobuf (including the full * the language_settings.java.interface_names" field in gapic.yaml. API * teams should otherwise use the service name as it appears in the * protobuf. * Example of a YAML configuration:: * publishing: * java_settings: * service_class_names: * - google.pubsub.v1.Publisher: TopicAdmin * - google.pubsub.v1.Subscriber: SubscriptionAdmin * * Generated from protobuf field map service_class_names = 2; * @param array|\Google\Protobuf\Internal\MapField $var * @return $this */ public function setServiceClassNames($var) { $arr = GPBUtil::checkMapField($var, \Google\Protobuf\Internal\GPBType::STRING, \Google\Protobuf\Internal\GPBType::STRING); $this->service_class_names = $arr; return $this; } /** * Some settings. * * Generated from protobuf field .google.api.CommonLanguageSettings common = 3; * @return \Google\Api\CommonLanguageSettings|null */ public function getCommon() { return $this->common; } public function hasCommon() { return isset($this->common); } public function clearCommon() { unset($this->common); } /** * Some settings. * * Generated from protobuf field .google.api.CommonLanguageSettings common = 3; * @param \Google\Api\CommonLanguageSettings $var * @return $this */ public function setCommon($var) { GPBUtil::checkMessage($var, \Google\Api\CommonLanguageSettings::class); $this->common = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/JwtLocation.php ================================================ google.api.JwtLocation */ class JwtLocation extends \Google\Protobuf\Internal\Message { /** * The value prefix. The value format is "value_prefix{token}" * Only applies to "in" header type. Must be empty for "in" query type. * If not empty, the header value has to match (case sensitive) this prefix. * If not matched, JWT will not be extracted. If matched, JWT will be * extracted after the prefix is removed. * For example, for "Authorization: Bearer {JWT}", * value_prefix="Bearer " with a space at the end. * * Generated from protobuf field string value_prefix = 3; */ protected $value_prefix = ''; protected $in; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $header * Specifies HTTP header name to extract JWT token. * @type string $query * Specifies URL query parameter name to extract JWT token. * @type string $cookie * Specifies cookie name to extract JWT token. * @type string $value_prefix * The value prefix. The value format is "value_prefix{token}" * Only applies to "in" header type. Must be empty for "in" query type. * If not empty, the header value has to match (case sensitive) this prefix. * If not matched, JWT will not be extracted. If matched, JWT will be * extracted after the prefix is removed. * For example, for "Authorization: Bearer {JWT}", * value_prefix="Bearer " with a space at the end. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Auth::initOnce(); parent::__construct($data); } /** * Specifies HTTP header name to extract JWT token. * * Generated from protobuf field string header = 1; * @return string */ public function getHeader() { return $this->readOneof(1); } public function hasHeader() { return $this->hasOneof(1); } /** * Specifies HTTP header name to extract JWT token. * * Generated from protobuf field string header = 1; * @param string $var * @return $this */ public function setHeader($var) { GPBUtil::checkString($var, True); $this->writeOneof(1, $var); return $this; } /** * Specifies URL query parameter name to extract JWT token. * * Generated from protobuf field string query = 2; * @return string */ public function getQuery() { return $this->readOneof(2); } public function hasQuery() { return $this->hasOneof(2); } /** * Specifies URL query parameter name to extract JWT token. * * Generated from protobuf field string query = 2; * @param string $var * @return $this */ public function setQuery($var) { GPBUtil::checkString($var, True); $this->writeOneof(2, $var); return $this; } /** * Specifies cookie name to extract JWT token. * * Generated from protobuf field string cookie = 4; * @return string */ public function getCookie() { return $this->readOneof(4); } public function hasCookie() { return $this->hasOneof(4); } /** * Specifies cookie name to extract JWT token. * * Generated from protobuf field string cookie = 4; * @param string $var * @return $this */ public function setCookie($var) { GPBUtil::checkString($var, True); $this->writeOneof(4, $var); return $this; } /** * The value prefix. The value format is "value_prefix{token}" * Only applies to "in" header type. Must be empty for "in" query type. * If not empty, the header value has to match (case sensitive) this prefix. * If not matched, JWT will not be extracted. If matched, JWT will be * extracted after the prefix is removed. * For example, for "Authorization: Bearer {JWT}", * value_prefix="Bearer " with a space at the end. * * Generated from protobuf field string value_prefix = 3; * @return string */ public function getValuePrefix() { return $this->value_prefix; } /** * The value prefix. The value format is "value_prefix{token}" * Only applies to "in" header type. Must be empty for "in" query type. * If not empty, the header value has to match (case sensitive) this prefix. * If not matched, JWT will not be extracted. If matched, JWT will be * extracted after the prefix is removed. * For example, for "Authorization: Bearer {JWT}", * value_prefix="Bearer " with a space at the end. * * Generated from protobuf field string value_prefix = 3; * @param string $var * @return $this */ public function setValuePrefix($var) { GPBUtil::checkString($var, True); $this->value_prefix = $var; return $this; } /** * @return string */ public function getIn() { return $this->whichOneof("in"); } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/LabelDescriptor/ValueType.php ================================================ google.api.LabelDescriptor.ValueType */ class ValueType { /** * A variable-length string. This is the default. * * Generated from protobuf enum STRING = 0; */ const STRING = 0; /** * Boolean; true or false. * * Generated from protobuf enum BOOL = 1; */ const BOOL = 1; /** * A 64-bit signed integer. * * Generated from protobuf enum INT64 = 2; */ const INT64 = 2; private static $valueToName = [ self::STRING => 'STRING', self::BOOL => 'BOOL', self::INT64 => 'INT64', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/LabelDescriptor.php ================================================ google.api.LabelDescriptor */ class LabelDescriptor extends \Google\Protobuf\Internal\Message { /** * The label key. * * Generated from protobuf field string key = 1; */ protected $key = ''; /** * The type of data that can be assigned to the label. * * Generated from protobuf field .google.api.LabelDescriptor.ValueType value_type = 2; */ protected $value_type = 0; /** * A human-readable description for the label. * * Generated from protobuf field string description = 3; */ protected $description = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $key * The label key. * @type int $value_type * The type of data that can be assigned to the label. * @type string $description * A human-readable description for the label. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Label::initOnce(); parent::__construct($data); } /** * The label key. * * Generated from protobuf field string key = 1; * @return string */ public function getKey() { return $this->key; } /** * The label key. * * Generated from protobuf field string key = 1; * @param string $var * @return $this */ public function setKey($var) { GPBUtil::checkString($var, True); $this->key = $var; return $this; } /** * The type of data that can be assigned to the label. * * Generated from protobuf field .google.api.LabelDescriptor.ValueType value_type = 2; * @return int */ public function getValueType() { return $this->value_type; } /** * The type of data that can be assigned to the label. * * Generated from protobuf field .google.api.LabelDescriptor.ValueType value_type = 2; * @param int $var * @return $this */ public function setValueType($var) { GPBUtil::checkEnum($var, \Google\Api\LabelDescriptor\ValueType::class); $this->value_type = $var; return $this; } /** * A human-readable description for the label. * * Generated from protobuf field string description = 3; * @return string */ public function getDescription() { return $this->description; } /** * A human-readable description for the label. * * Generated from protobuf field string description = 3; * @param string $var * @return $this */ public function setDescription($var) { GPBUtil::checkString($var, True); $this->description = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/LaunchStage.php ================================================ google.api.LaunchStage */ class LaunchStage { /** * Do not use this default value. * * Generated from protobuf enum LAUNCH_STAGE_UNSPECIFIED = 0; */ const LAUNCH_STAGE_UNSPECIFIED = 0; /** * The feature is not yet implemented. Users can not use it. * * Generated from protobuf enum UNIMPLEMENTED = 6; */ const UNIMPLEMENTED = 6; /** * Prelaunch features are hidden from users and are only visible internally. * * Generated from protobuf enum PRELAUNCH = 7; */ const PRELAUNCH = 7; /** * Early Access features are limited to a closed group of testers. To use * these features, you must sign up in advance and sign a Trusted Tester * agreement (which includes confidentiality provisions). These features may * be unstable, changed in backward-incompatible ways, and are not * guaranteed to be released. * * Generated from protobuf enum EARLY_ACCESS = 1; */ const EARLY_ACCESS = 1; /** * Alpha is a limited availability test for releases before they are cleared * for widespread use. By Alpha, all significant design issues are resolved * and we are in the process of verifying functionality. Alpha customers * need to apply for access, agree to applicable terms, and have their * projects allowlisted. Alpha releases don't have to be feature complete, * no SLAs are provided, and there are no technical support obligations, but * they will be far enough along that customers can actually use them in * test environments or for limited-use tests -- just like they would in * normal production cases. * * Generated from protobuf enum ALPHA = 2; */ const ALPHA = 2; /** * Beta is the point at which we are ready to open a release for any * customer to use. There are no SLA or technical support obligations in a * Beta release. Products will be complete from a feature perspective, but * may have some open outstanding issues. Beta releases are suitable for * limited production use cases. * * Generated from protobuf enum BETA = 3; */ const BETA = 3; /** * GA features are open to all developers and are considered stable and * fully qualified for production use. * * Generated from protobuf enum GA = 4; */ const GA = 4; /** * Deprecated features are scheduled to be shut down and removed. For more * information, see the "Deprecation Policy" section of our [Terms of * Service](https://cloud.google.com/terms/) * and the [Google Cloud Platform Subject to the Deprecation * Policy](https://cloud.google.com/terms/deprecation) documentation. * * Generated from protobuf enum DEPRECATED = 5; */ const DEPRECATED = 5; private static $valueToName = [ self::LAUNCH_STAGE_UNSPECIFIED => 'LAUNCH_STAGE_UNSPECIFIED', self::UNIMPLEMENTED => 'UNIMPLEMENTED', self::PRELAUNCH => 'PRELAUNCH', self::EARLY_ACCESS => 'EARLY_ACCESS', self::ALPHA => 'ALPHA', self::BETA => 'BETA', self::GA => 'GA', self::DEPRECATED => 'DEPRECATED', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/LogDescriptor.php ================================================ google.api.LogDescriptor */ class LogDescriptor extends \Google\Protobuf\Internal\Message { /** * The name of the log. It must be less than 512 characters long and can * include the following characters: upper- and lower-case alphanumeric * characters [A-Za-z0-9], and punctuation characters including * slash, underscore, hyphen, period [/_-.]. * * Generated from protobuf field string name = 1; */ protected $name = ''; /** * The set of labels that are available to describe a specific log entry. * Runtime requests that contain labels not specified here are * considered invalid. * * Generated from protobuf field repeated .google.api.LabelDescriptor labels = 2; */ private $labels; /** * A human-readable description of this log. This information appears in * the documentation and can contain details. * * Generated from protobuf field string description = 3; */ protected $description = ''; /** * The human-readable name for this log. This information appears on * the user interface and should be concise. * * Generated from protobuf field string display_name = 4; */ protected $display_name = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $name * The name of the log. It must be less than 512 characters long and can * include the following characters: upper- and lower-case alphanumeric * characters [A-Za-z0-9], and punctuation characters including * slash, underscore, hyphen, period [/_-.]. * @type array<\Google\Api\LabelDescriptor>|\Google\Protobuf\Internal\RepeatedField $labels * The set of labels that are available to describe a specific log entry. * Runtime requests that contain labels not specified here are * considered invalid. * @type string $description * A human-readable description of this log. This information appears in * the documentation and can contain details. * @type string $display_name * The human-readable name for this log. This information appears on * the user interface and should be concise. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Log::initOnce(); parent::__construct($data); } /** * The name of the log. It must be less than 512 characters long and can * include the following characters: upper- and lower-case alphanumeric * characters [A-Za-z0-9], and punctuation characters including * slash, underscore, hyphen, period [/_-.]. * * Generated from protobuf field string name = 1; * @return string */ public function getName() { return $this->name; } /** * The name of the log. It must be less than 512 characters long and can * include the following characters: upper- and lower-case alphanumeric * characters [A-Za-z0-9], and punctuation characters including * slash, underscore, hyphen, period [/_-.]. * * Generated from protobuf field string name = 1; * @param string $var * @return $this */ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; return $this; } /** * The set of labels that are available to describe a specific log entry. * Runtime requests that contain labels not specified here are * considered invalid. * * Generated from protobuf field repeated .google.api.LabelDescriptor labels = 2; * @return \Google\Protobuf\Internal\RepeatedField */ public function getLabels() { return $this->labels; } /** * The set of labels that are available to describe a specific log entry. * Runtime requests that contain labels not specified here are * considered invalid. * * Generated from protobuf field repeated .google.api.LabelDescriptor labels = 2; * @param array<\Google\Api\LabelDescriptor>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setLabels($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Api\LabelDescriptor::class); $this->labels = $arr; return $this; } /** * A human-readable description of this log. This information appears in * the documentation and can contain details. * * Generated from protobuf field string description = 3; * @return string */ public function getDescription() { return $this->description; } /** * A human-readable description of this log. This information appears in * the documentation and can contain details. * * Generated from protobuf field string description = 3; * @param string $var * @return $this */ public function setDescription($var) { GPBUtil::checkString($var, True); $this->description = $var; return $this; } /** * The human-readable name for this log. This information appears on * the user interface and should be concise. * * Generated from protobuf field string display_name = 4; * @return string */ public function getDisplayName() { return $this->display_name; } /** * The human-readable name for this log. This information appears on * the user interface and should be concise. * * Generated from protobuf field string display_name = 4; * @param string $var * @return $this */ public function setDisplayName($var) { GPBUtil::checkString($var, True); $this->display_name = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/Logging/LoggingDestination.php ================================================ google.api.Logging.LoggingDestination */ class LoggingDestination extends \Google\Protobuf\Internal\Message { /** * The monitored resource type. The type must be defined in the * [Service.monitored_resources][google.api.Service.monitored_resources] * section. * * Generated from protobuf field string monitored_resource = 3; */ protected $monitored_resource = ''; /** * Names of the logs to be sent to this destination. Each name must * be defined in the [Service.logs][google.api.Service.logs] section. If the * log name is not a domain scoped name, it will be automatically prefixed * with the service name followed by "/". * * Generated from protobuf field repeated string logs = 1; */ private $logs; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $monitored_resource * The monitored resource type. The type must be defined in the * [Service.monitored_resources][google.api.Service.monitored_resources] * section. * @type array|\Google\Protobuf\Internal\RepeatedField $logs * Names of the logs to be sent to this destination. Each name must * be defined in the [Service.logs][google.api.Service.logs] section. If the * log name is not a domain scoped name, it will be automatically prefixed * with the service name followed by "/". * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Logging::initOnce(); parent::__construct($data); } /** * The monitored resource type. The type must be defined in the * [Service.monitored_resources][google.api.Service.monitored_resources] * section. * * Generated from protobuf field string monitored_resource = 3; * @return string */ public function getMonitoredResource() { return $this->monitored_resource; } /** * The monitored resource type. The type must be defined in the * [Service.monitored_resources][google.api.Service.monitored_resources] * section. * * Generated from protobuf field string monitored_resource = 3; * @param string $var * @return $this */ public function setMonitoredResource($var) { GPBUtil::checkString($var, True); $this->monitored_resource = $var; return $this; } /** * Names of the logs to be sent to this destination. Each name must * be defined in the [Service.logs][google.api.Service.logs] section. If the * log name is not a domain scoped name, it will be automatically prefixed * with the service name followed by "/". * * Generated from protobuf field repeated string logs = 1; * @return \Google\Protobuf\Internal\RepeatedField */ public function getLogs() { return $this->logs; } /** * Names of the logs to be sent to this destination. Each name must * be defined in the [Service.logs][google.api.Service.logs] section. If the * log name is not a domain scoped name, it will be automatically prefixed * with the service name followed by "/". * * Generated from protobuf field repeated string logs = 1; * @param array|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setLogs($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->logs = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/Logging.php ================================================ google.api.Logging */ class Logging extends \Google\Protobuf\Internal\Message { /** * Logging configurations for sending logs to the producer project. * There can be multiple producer destinations, each one must have a * different monitored resource type. A log can be used in at most * one producer destination. * * Generated from protobuf field repeated .google.api.Logging.LoggingDestination producer_destinations = 1; */ private $producer_destinations; /** * Logging configurations for sending logs to the consumer project. * There can be multiple consumer destinations, each one must have a * different monitored resource type. A log can be used in at most * one consumer destination. * * Generated from protobuf field repeated .google.api.Logging.LoggingDestination consumer_destinations = 2; */ private $consumer_destinations; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type array<\Google\Api\Logging\LoggingDestination>|\Google\Protobuf\Internal\RepeatedField $producer_destinations * Logging configurations for sending logs to the producer project. * There can be multiple producer destinations, each one must have a * different monitored resource type. A log can be used in at most * one producer destination. * @type array<\Google\Api\Logging\LoggingDestination>|\Google\Protobuf\Internal\RepeatedField $consumer_destinations * Logging configurations for sending logs to the consumer project. * There can be multiple consumer destinations, each one must have a * different monitored resource type. A log can be used in at most * one consumer destination. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Logging::initOnce(); parent::__construct($data); } /** * Logging configurations for sending logs to the producer project. * There can be multiple producer destinations, each one must have a * different monitored resource type. A log can be used in at most * one producer destination. * * Generated from protobuf field repeated .google.api.Logging.LoggingDestination producer_destinations = 1; * @return \Google\Protobuf\Internal\RepeatedField */ public function getProducerDestinations() { return $this->producer_destinations; } /** * Logging configurations for sending logs to the producer project. * There can be multiple producer destinations, each one must have a * different monitored resource type. A log can be used in at most * one producer destination. * * Generated from protobuf field repeated .google.api.Logging.LoggingDestination producer_destinations = 1; * @param array<\Google\Api\Logging\LoggingDestination>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setProducerDestinations($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Api\Logging\LoggingDestination::class); $this->producer_destinations = $arr; return $this; } /** * Logging configurations for sending logs to the consumer project. * There can be multiple consumer destinations, each one must have a * different monitored resource type. A log can be used in at most * one consumer destination. * * Generated from protobuf field repeated .google.api.Logging.LoggingDestination consumer_destinations = 2; * @return \Google\Protobuf\Internal\RepeatedField */ public function getConsumerDestinations() { return $this->consumer_destinations; } /** * Logging configurations for sending logs to the consumer project. * There can be multiple consumer destinations, each one must have a * different monitored resource type. A log can be used in at most * one consumer destination. * * Generated from protobuf field repeated .google.api.Logging.LoggingDestination consumer_destinations = 2; * @param array<\Google\Api\Logging\LoggingDestination>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setConsumerDestinations($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Api\Logging\LoggingDestination::class); $this->consumer_destinations = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/MethodPolicy.php ================================================ google.api.MethodPolicy */ class MethodPolicy extends \Google\Protobuf\Internal\Message { /** * Selects a method to which these policies should be enforced, for example, * "google.pubsub.v1.Subscriber.CreateSubscription". * Refer to [selector][google.api.DocumentationRule.selector] for syntax * details. * NOTE: This field must not be set in the proto annotation. It will be * automatically filled by the service config compiler . * * Generated from protobuf field string selector = 9; */ protected $selector = ''; /** * Policies that are applicable to the request message. * * Generated from protobuf field repeated .google.api.FieldPolicy request_policies = 2; */ private $request_policies; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $selector * Selects a method to which these policies should be enforced, for example, * "google.pubsub.v1.Subscriber.CreateSubscription". * Refer to [selector][google.api.DocumentationRule.selector] for syntax * details. * NOTE: This field must not be set in the proto annotation. It will be * automatically filled by the service config compiler . * @type array<\Google\Api\FieldPolicy>|\Google\Protobuf\Internal\RepeatedField $request_policies * Policies that are applicable to the request message. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Policy::initOnce(); parent::__construct($data); } /** * Selects a method to which these policies should be enforced, for example, * "google.pubsub.v1.Subscriber.CreateSubscription". * Refer to [selector][google.api.DocumentationRule.selector] for syntax * details. * NOTE: This field must not be set in the proto annotation. It will be * automatically filled by the service config compiler . * * Generated from protobuf field string selector = 9; * @return string */ public function getSelector() { return $this->selector; } /** * Selects a method to which these policies should be enforced, for example, * "google.pubsub.v1.Subscriber.CreateSubscription". * Refer to [selector][google.api.DocumentationRule.selector] for syntax * details. * NOTE: This field must not be set in the proto annotation. It will be * automatically filled by the service config compiler . * * Generated from protobuf field string selector = 9; * @param string $var * @return $this */ public function setSelector($var) { GPBUtil::checkString($var, True); $this->selector = $var; return $this; } /** * Policies that are applicable to the request message. * * Generated from protobuf field repeated .google.api.FieldPolicy request_policies = 2; * @return \Google\Protobuf\Internal\RepeatedField */ public function getRequestPolicies() { return $this->request_policies; } /** * Policies that are applicable to the request message. * * Generated from protobuf field repeated .google.api.FieldPolicy request_policies = 2; * @param array<\Google\Api\FieldPolicy>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setRequestPolicies($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Api\FieldPolicy::class); $this->request_policies = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/MethodSettings/LongRunning.php ================================================ google.api.MethodSettings.LongRunning */ class LongRunning extends \Google\Protobuf\Internal\Message { /** * Initial delay after which the first poll request will be made. * Default value: 5 seconds. * * Generated from protobuf field .google.protobuf.Duration initial_poll_delay = 1; */ protected $initial_poll_delay = null; /** * Multiplier to gradually increase delay between subsequent polls until it * reaches max_poll_delay. * Default value: 1.5. * * Generated from protobuf field float poll_delay_multiplier = 2; */ protected $poll_delay_multiplier = 0.0; /** * Maximum time between two subsequent poll requests. * Default value: 45 seconds. * * Generated from protobuf field .google.protobuf.Duration max_poll_delay = 3; */ protected $max_poll_delay = null; /** * Total polling timeout. * Default value: 5 minutes. * * Generated from protobuf field .google.protobuf.Duration total_poll_timeout = 4; */ protected $total_poll_timeout = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type \Google\Protobuf\Duration $initial_poll_delay * Initial delay after which the first poll request will be made. * Default value: 5 seconds. * @type float $poll_delay_multiplier * Multiplier to gradually increase delay between subsequent polls until it * reaches max_poll_delay. * Default value: 1.5. * @type \Google\Protobuf\Duration $max_poll_delay * Maximum time between two subsequent poll requests. * Default value: 45 seconds. * @type \Google\Protobuf\Duration $total_poll_timeout * Total polling timeout. * Default value: 5 minutes. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Client::initOnce(); parent::__construct($data); } /** * Initial delay after which the first poll request will be made. * Default value: 5 seconds. * * Generated from protobuf field .google.protobuf.Duration initial_poll_delay = 1; * @return \Google\Protobuf\Duration|null */ public function getInitialPollDelay() { return $this->initial_poll_delay; } public function hasInitialPollDelay() { return isset($this->initial_poll_delay); } public function clearInitialPollDelay() { unset($this->initial_poll_delay); } /** * Initial delay after which the first poll request will be made. * Default value: 5 seconds. * * Generated from protobuf field .google.protobuf.Duration initial_poll_delay = 1; * @param \Google\Protobuf\Duration $var * @return $this */ public function setInitialPollDelay($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Duration::class); $this->initial_poll_delay = $var; return $this; } /** * Multiplier to gradually increase delay between subsequent polls until it * reaches max_poll_delay. * Default value: 1.5. * * Generated from protobuf field float poll_delay_multiplier = 2; * @return float */ public function getPollDelayMultiplier() { return $this->poll_delay_multiplier; } /** * Multiplier to gradually increase delay between subsequent polls until it * reaches max_poll_delay. * Default value: 1.5. * * Generated from protobuf field float poll_delay_multiplier = 2; * @param float $var * @return $this */ public function setPollDelayMultiplier($var) { GPBUtil::checkFloat($var); $this->poll_delay_multiplier = $var; return $this; } /** * Maximum time between two subsequent poll requests. * Default value: 45 seconds. * * Generated from protobuf field .google.protobuf.Duration max_poll_delay = 3; * @return \Google\Protobuf\Duration|null */ public function getMaxPollDelay() { return $this->max_poll_delay; } public function hasMaxPollDelay() { return isset($this->max_poll_delay); } public function clearMaxPollDelay() { unset($this->max_poll_delay); } /** * Maximum time between two subsequent poll requests. * Default value: 45 seconds. * * Generated from protobuf field .google.protobuf.Duration max_poll_delay = 3; * @param \Google\Protobuf\Duration $var * @return $this */ public function setMaxPollDelay($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Duration::class); $this->max_poll_delay = $var; return $this; } /** * Total polling timeout. * Default value: 5 minutes. * * Generated from protobuf field .google.protobuf.Duration total_poll_timeout = 4; * @return \Google\Protobuf\Duration|null */ public function getTotalPollTimeout() { return $this->total_poll_timeout; } public function hasTotalPollTimeout() { return isset($this->total_poll_timeout); } public function clearTotalPollTimeout() { unset($this->total_poll_timeout); } /** * Total polling timeout. * Default value: 5 minutes. * * Generated from protobuf field .google.protobuf.Duration total_poll_timeout = 4; * @param \Google\Protobuf\Duration $var * @return $this */ public function setTotalPollTimeout($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Duration::class); $this->total_poll_timeout = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/MethodSettings.php ================================================ google.api.MethodSettings */ class MethodSettings extends \Google\Protobuf\Internal\Message { /** * The fully qualified name of the method, for which the options below apply. * This is used to find the method to apply the options. * Example: * publishing: * method_settings: * - selector: google.storage.control.v2.StorageControl.CreateFolder * # method settings for CreateFolder... * * Generated from protobuf field string selector = 1; */ protected $selector = ''; /** * Describes settings to use for long-running operations when generating * API methods for RPCs. Complements RPCs that use the annotations in * google/longrunning/operations.proto. * Example of a YAML configuration:: * publishing: * method_settings: * - selector: google.cloud.speech.v2.Speech.BatchRecognize * long_running: * initial_poll_delay: 60s # 1 minute * poll_delay_multiplier: 1.5 * max_poll_delay: 360s # 6 minutes * total_poll_timeout: 54000s # 90 minutes * * Generated from protobuf field .google.api.MethodSettings.LongRunning long_running = 2; */ protected $long_running = null; /** * List of top-level fields of the request message, that should be * automatically populated by the client libraries based on their * (google.api.field_info).format. Currently supported format: UUID4. * Example of a YAML configuration: * publishing: * method_settings: * - selector: google.example.v1.ExampleService.CreateExample * auto_populated_fields: * - request_id * * Generated from protobuf field repeated string auto_populated_fields = 3; */ private $auto_populated_fields; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $selector * The fully qualified name of the method, for which the options below apply. * This is used to find the method to apply the options. * Example: * publishing: * method_settings: * - selector: google.storage.control.v2.StorageControl.CreateFolder * # method settings for CreateFolder... * @type \Google\Api\MethodSettings\LongRunning $long_running * Describes settings to use for long-running operations when generating * API methods for RPCs. Complements RPCs that use the annotations in * google/longrunning/operations.proto. * Example of a YAML configuration:: * publishing: * method_settings: * - selector: google.cloud.speech.v2.Speech.BatchRecognize * long_running: * initial_poll_delay: 60s # 1 minute * poll_delay_multiplier: 1.5 * max_poll_delay: 360s # 6 minutes * total_poll_timeout: 54000s # 90 minutes * @type array|\Google\Protobuf\Internal\RepeatedField $auto_populated_fields * List of top-level fields of the request message, that should be * automatically populated by the client libraries based on their * (google.api.field_info).format. Currently supported format: UUID4. * Example of a YAML configuration: * publishing: * method_settings: * - selector: google.example.v1.ExampleService.CreateExample * auto_populated_fields: * - request_id * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Client::initOnce(); parent::__construct($data); } /** * The fully qualified name of the method, for which the options below apply. * This is used to find the method to apply the options. * Example: * publishing: * method_settings: * - selector: google.storage.control.v2.StorageControl.CreateFolder * # method settings for CreateFolder... * * Generated from protobuf field string selector = 1; * @return string */ public function getSelector() { return $this->selector; } /** * The fully qualified name of the method, for which the options below apply. * This is used to find the method to apply the options. * Example: * publishing: * method_settings: * - selector: google.storage.control.v2.StorageControl.CreateFolder * # method settings for CreateFolder... * * Generated from protobuf field string selector = 1; * @param string $var * @return $this */ public function setSelector($var) { GPBUtil::checkString($var, True); $this->selector = $var; return $this; } /** * Describes settings to use for long-running operations when generating * API methods for RPCs. Complements RPCs that use the annotations in * google/longrunning/operations.proto. * Example of a YAML configuration:: * publishing: * method_settings: * - selector: google.cloud.speech.v2.Speech.BatchRecognize * long_running: * initial_poll_delay: 60s # 1 minute * poll_delay_multiplier: 1.5 * max_poll_delay: 360s # 6 minutes * total_poll_timeout: 54000s # 90 minutes * * Generated from protobuf field .google.api.MethodSettings.LongRunning long_running = 2; * @return \Google\Api\MethodSettings\LongRunning|null */ public function getLongRunning() { return $this->long_running; } public function hasLongRunning() { return isset($this->long_running); } public function clearLongRunning() { unset($this->long_running); } /** * Describes settings to use for long-running operations when generating * API methods for RPCs. Complements RPCs that use the annotations in * google/longrunning/operations.proto. * Example of a YAML configuration:: * publishing: * method_settings: * - selector: google.cloud.speech.v2.Speech.BatchRecognize * long_running: * initial_poll_delay: 60s # 1 minute * poll_delay_multiplier: 1.5 * max_poll_delay: 360s # 6 minutes * total_poll_timeout: 54000s # 90 minutes * * Generated from protobuf field .google.api.MethodSettings.LongRunning long_running = 2; * @param \Google\Api\MethodSettings\LongRunning $var * @return $this */ public function setLongRunning($var) { GPBUtil::checkMessage($var, \Google\Api\MethodSettings\LongRunning::class); $this->long_running = $var; return $this; } /** * List of top-level fields of the request message, that should be * automatically populated by the client libraries based on their * (google.api.field_info).format. Currently supported format: UUID4. * Example of a YAML configuration: * publishing: * method_settings: * - selector: google.example.v1.ExampleService.CreateExample * auto_populated_fields: * - request_id * * Generated from protobuf field repeated string auto_populated_fields = 3; * @return \Google\Protobuf\Internal\RepeatedField */ public function getAutoPopulatedFields() { return $this->auto_populated_fields; } /** * List of top-level fields of the request message, that should be * automatically populated by the client libraries based on their * (google.api.field_info).format. Currently supported format: UUID4. * Example of a YAML configuration: * publishing: * method_settings: * - selector: google.example.v1.ExampleService.CreateExample * auto_populated_fields: * - request_id * * Generated from protobuf field repeated string auto_populated_fields = 3; * @param array|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setAutoPopulatedFields($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->auto_populated_fields = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/Metric.php ================================================ google.api.Metric */ class Metric extends \Google\Protobuf\Internal\Message { /** * An existing metric type, see * [google.api.MetricDescriptor][google.api.MetricDescriptor]. For example, * `custom.googleapis.com/invoice/paid/amount`. * * Generated from protobuf field string type = 3; */ protected $type = ''; /** * The set of label values that uniquely identify this metric. All * labels listed in the `MetricDescriptor` must be assigned values. * * Generated from protobuf field map labels = 2; */ private $labels; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $type * An existing metric type, see * [google.api.MetricDescriptor][google.api.MetricDescriptor]. For example, * `custom.googleapis.com/invoice/paid/amount`. * @type array|\Google\Protobuf\Internal\MapField $labels * The set of label values that uniquely identify this metric. All * labels listed in the `MetricDescriptor` must be assigned values. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Metric::initOnce(); parent::__construct($data); } /** * An existing metric type, see * [google.api.MetricDescriptor][google.api.MetricDescriptor]. For example, * `custom.googleapis.com/invoice/paid/amount`. * * Generated from protobuf field string type = 3; * @return string */ public function getType() { return $this->type; } /** * An existing metric type, see * [google.api.MetricDescriptor][google.api.MetricDescriptor]. For example, * `custom.googleapis.com/invoice/paid/amount`. * * Generated from protobuf field string type = 3; * @param string $var * @return $this */ public function setType($var) { GPBUtil::checkString($var, True); $this->type = $var; return $this; } /** * The set of label values that uniquely identify this metric. All * labels listed in the `MetricDescriptor` must be assigned values. * * Generated from protobuf field map labels = 2; * @return \Google\Protobuf\Internal\MapField */ public function getLabels() { return $this->labels; } /** * The set of label values that uniquely identify this metric. All * labels listed in the `MetricDescriptor` must be assigned values. * * Generated from protobuf field map labels = 2; * @param array|\Google\Protobuf\Internal\MapField $var * @return $this */ public function setLabels($var) { $arr = GPBUtil::checkMapField($var, \Google\Protobuf\Internal\GPBType::STRING, \Google\Protobuf\Internal\GPBType::STRING); $this->labels = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/MetricDescriptor/MetricDescriptorMetadata/TimeSeriesResourceHierarchyLevel.php ================================================ google.api.MetricDescriptor.MetricDescriptorMetadata.TimeSeriesResourceHierarchyLevel */ class TimeSeriesResourceHierarchyLevel { /** * Do not use this default value. * * Generated from protobuf enum TIME_SERIES_RESOURCE_HIERARCHY_LEVEL_UNSPECIFIED = 0; */ const TIME_SERIES_RESOURCE_HIERARCHY_LEVEL_UNSPECIFIED = 0; /** * Scopes a metric to a project. * * Generated from protobuf enum PROJECT = 1; */ const PROJECT = 1; /** * Scopes a metric to an organization. * * Generated from protobuf enum ORGANIZATION = 2; */ const ORGANIZATION = 2; /** * Scopes a metric to a folder. * * Generated from protobuf enum FOLDER = 3; */ const FOLDER = 3; private static $valueToName = [ self::TIME_SERIES_RESOURCE_HIERARCHY_LEVEL_UNSPECIFIED => 'TIME_SERIES_RESOURCE_HIERARCHY_LEVEL_UNSPECIFIED', self::PROJECT => 'PROJECT', self::ORGANIZATION => 'ORGANIZATION', self::FOLDER => 'FOLDER', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/MetricDescriptor/MetricDescriptorMetadata.php ================================================ google.api.MetricDescriptor.MetricDescriptorMetadata */ class MetricDescriptorMetadata extends \Google\Protobuf\Internal\Message { /** * Deprecated. Must use the * [MetricDescriptor.launch_stage][google.api.MetricDescriptor.launch_stage] * instead. * * Generated from protobuf field .google.api.LaunchStage launch_stage = 1 [deprecated = true]; * @deprecated */ protected $launch_stage = 0; /** * The sampling period of metric data points. For metrics which are written * periodically, consecutive data points are stored at this time interval, * excluding data loss due to errors. Metrics with a higher granularity have * a smaller sampling period. * * Generated from protobuf field .google.protobuf.Duration sample_period = 2; */ protected $sample_period = null; /** * The delay of data points caused by ingestion. Data points older than this * age are guaranteed to be ingested and available to be read, excluding * data loss due to errors. * * Generated from protobuf field .google.protobuf.Duration ingest_delay = 3; */ protected $ingest_delay = null; /** * The scope of the timeseries data of the metric. * * Generated from protobuf field repeated .google.api.MetricDescriptor.MetricDescriptorMetadata.TimeSeriesResourceHierarchyLevel time_series_resource_hierarchy_level = 4; */ private $time_series_resource_hierarchy_level; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type int $launch_stage * Deprecated. Must use the * [MetricDescriptor.launch_stage][google.api.MetricDescriptor.launch_stage] * instead. * @type \Google\Protobuf\Duration $sample_period * The sampling period of metric data points. For metrics which are written * periodically, consecutive data points are stored at this time interval, * excluding data loss due to errors. Metrics with a higher granularity have * a smaller sampling period. * @type \Google\Protobuf\Duration $ingest_delay * The delay of data points caused by ingestion. Data points older than this * age are guaranteed to be ingested and available to be read, excluding * data loss due to errors. * @type array|\Google\Protobuf\Internal\RepeatedField $time_series_resource_hierarchy_level * The scope of the timeseries data of the metric. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Metric::initOnce(); parent::__construct($data); } /** * Deprecated. Must use the * [MetricDescriptor.launch_stage][google.api.MetricDescriptor.launch_stage] * instead. * * Generated from protobuf field .google.api.LaunchStage launch_stage = 1 [deprecated = true]; * @return int * @deprecated */ public function getLaunchStage() { if ($this->launch_stage !== 0) { @trigger_error('launch_stage is deprecated.', E_USER_DEPRECATED); } return $this->launch_stage; } /** * Deprecated. Must use the * [MetricDescriptor.launch_stage][google.api.MetricDescriptor.launch_stage] * instead. * * Generated from protobuf field .google.api.LaunchStage launch_stage = 1 [deprecated = true]; * @param int $var * @return $this * @deprecated */ public function setLaunchStage($var) { @trigger_error('launch_stage is deprecated.', E_USER_DEPRECATED); GPBUtil::checkEnum($var, \Google\Api\LaunchStage::class); $this->launch_stage = $var; return $this; } /** * The sampling period of metric data points. For metrics which are written * periodically, consecutive data points are stored at this time interval, * excluding data loss due to errors. Metrics with a higher granularity have * a smaller sampling period. * * Generated from protobuf field .google.protobuf.Duration sample_period = 2; * @return \Google\Protobuf\Duration|null */ public function getSamplePeriod() { return $this->sample_period; } public function hasSamplePeriod() { return isset($this->sample_period); } public function clearSamplePeriod() { unset($this->sample_period); } /** * The sampling period of metric data points. For metrics which are written * periodically, consecutive data points are stored at this time interval, * excluding data loss due to errors. Metrics with a higher granularity have * a smaller sampling period. * * Generated from protobuf field .google.protobuf.Duration sample_period = 2; * @param \Google\Protobuf\Duration $var * @return $this */ public function setSamplePeriod($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Duration::class); $this->sample_period = $var; return $this; } /** * The delay of data points caused by ingestion. Data points older than this * age are guaranteed to be ingested and available to be read, excluding * data loss due to errors. * * Generated from protobuf field .google.protobuf.Duration ingest_delay = 3; * @return \Google\Protobuf\Duration|null */ public function getIngestDelay() { return $this->ingest_delay; } public function hasIngestDelay() { return isset($this->ingest_delay); } public function clearIngestDelay() { unset($this->ingest_delay); } /** * The delay of data points caused by ingestion. Data points older than this * age are guaranteed to be ingested and available to be read, excluding * data loss due to errors. * * Generated from protobuf field .google.protobuf.Duration ingest_delay = 3; * @param \Google\Protobuf\Duration $var * @return $this */ public function setIngestDelay($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Duration::class); $this->ingest_delay = $var; return $this; } /** * The scope of the timeseries data of the metric. * * Generated from protobuf field repeated .google.api.MetricDescriptor.MetricDescriptorMetadata.TimeSeriesResourceHierarchyLevel time_series_resource_hierarchy_level = 4; * @return \Google\Protobuf\Internal\RepeatedField */ public function getTimeSeriesResourceHierarchyLevel() { return $this->time_series_resource_hierarchy_level; } /** * The scope of the timeseries data of the metric. * * Generated from protobuf field repeated .google.api.MetricDescriptor.MetricDescriptorMetadata.TimeSeriesResourceHierarchyLevel time_series_resource_hierarchy_level = 4; * @param array|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setTimeSeriesResourceHierarchyLevel($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::ENUM, \Google\Api\MetricDescriptor\MetricDescriptorMetadata\TimeSeriesResourceHierarchyLevel::class); $this->time_series_resource_hierarchy_level = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/MetricDescriptor/MetricKind.php ================================================ google.api.MetricDescriptor.MetricKind */ class MetricKind { /** * Do not use this default value. * * Generated from protobuf enum METRIC_KIND_UNSPECIFIED = 0; */ const METRIC_KIND_UNSPECIFIED = 0; /** * An instantaneous measurement of a value. * * Generated from protobuf enum GAUGE = 1; */ const GAUGE = 1; /** * The change in a value during a time interval. * * Generated from protobuf enum DELTA = 2; */ const DELTA = 2; /** * A value accumulated over a time interval. Cumulative * measurements in a time series should have the same start time * and increasing end times, until an event resets the cumulative * value to zero and sets a new start time for the following * points. * * Generated from protobuf enum CUMULATIVE = 3; */ const CUMULATIVE = 3; private static $valueToName = [ self::METRIC_KIND_UNSPECIFIED => 'METRIC_KIND_UNSPECIFIED', self::GAUGE => 'GAUGE', self::DELTA => 'DELTA', self::CUMULATIVE => 'CUMULATIVE', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/MetricDescriptor/ValueType.php ================================================ google.api.MetricDescriptor.ValueType */ class ValueType { /** * Do not use this default value. * * Generated from protobuf enum VALUE_TYPE_UNSPECIFIED = 0; */ const VALUE_TYPE_UNSPECIFIED = 0; /** * The value is a boolean. * This value type can be used only if the metric kind is `GAUGE`. * * Generated from protobuf enum BOOL = 1; */ const BOOL = 1; /** * The value is a signed 64-bit integer. * * Generated from protobuf enum INT64 = 2; */ const INT64 = 2; /** * The value is a double precision floating point number. * * Generated from protobuf enum DOUBLE = 3; */ const DOUBLE = 3; /** * The value is a text string. * This value type can be used only if the metric kind is `GAUGE`. * * Generated from protobuf enum STRING = 4; */ const STRING = 4; /** * The value is a [`Distribution`][google.api.Distribution]. * * Generated from protobuf enum DISTRIBUTION = 5; */ const DISTRIBUTION = 5; /** * The value is money. * * Generated from protobuf enum MONEY = 6; */ const MONEY = 6; private static $valueToName = [ self::VALUE_TYPE_UNSPECIFIED => 'VALUE_TYPE_UNSPECIFIED', self::BOOL => 'BOOL', self::INT64 => 'INT64', self::DOUBLE => 'DOUBLE', self::STRING => 'STRING', self::DISTRIBUTION => 'DISTRIBUTION', self::MONEY => 'MONEY', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/MetricDescriptor.php ================================================ google.api.MetricDescriptor */ class MetricDescriptor extends \Google\Protobuf\Internal\Message { /** * The resource name of the metric descriptor. * * Generated from protobuf field string name = 1; */ protected $name = ''; /** * The metric type, including its DNS name prefix. The type is not * URL-encoded. All user-defined metric types have the DNS name * `custom.googleapis.com` or `external.googleapis.com`. Metric types should * use a natural hierarchical grouping. For example: * "custom.googleapis.com/invoice/paid/amount" * "external.googleapis.com/prometheus/up" * "appengine.googleapis.com/http/server/response_latencies" * * Generated from protobuf field string type = 8; */ protected $type = ''; /** * The set of labels that can be used to describe a specific * instance of this metric type. For example, the * `appengine.googleapis.com/http/server/response_latencies` metric * type has a label for the HTTP response code, `response_code`, so * you can look at latencies for successful responses or just * for responses that failed. * * Generated from protobuf field repeated .google.api.LabelDescriptor labels = 2; */ private $labels; /** * Whether the metric records instantaneous values, changes to a value, etc. * Some combinations of `metric_kind` and `value_type` might not be supported. * * Generated from protobuf field .google.api.MetricDescriptor.MetricKind metric_kind = 3; */ protected $metric_kind = 0; /** * Whether the measurement is an integer, a floating-point number, etc. * Some combinations of `metric_kind` and `value_type` might not be supported. * * Generated from protobuf field .google.api.MetricDescriptor.ValueType value_type = 4; */ protected $value_type = 0; /** * The units in which the metric value is reported. It is only applicable * if the `value_type` is `INT64`, `DOUBLE`, or `DISTRIBUTION`. The `unit` * defines the representation of the stored metric values. * Different systems might scale the values to be more easily displayed (so a * value of `0.02kBy` _might_ be displayed as `20By`, and a value of * `3523kBy` _might_ be displayed as `3.5MBy`). However, if the `unit` is * `kBy`, then the value of the metric is always in thousands of bytes, no * matter how it might be displayed. * If you want a custom metric to record the exact number of CPU-seconds used * by a job, you can create an `INT64 CUMULATIVE` metric whose `unit` is * `s{CPU}` (or equivalently `1s{CPU}` or just `s`). If the job uses 12,005 * CPU-seconds, then the value is written as `12005`. * Alternatively, if you want a custom metric to record data in a more * granular way, you can create a `DOUBLE CUMULATIVE` metric whose `unit` is * `ks{CPU}`, and then write the value `12.005` (which is `12005/1000`), * or use `Kis{CPU}` and write `11.723` (which is `12005/1024`). * The supported units are a subset of [The Unified Code for Units of * Measure](https://unitsofmeasure.org/ucum.html) standard: * **Basic units (UNIT)** * * `bit` bit * * `By` byte * * `s` second * * `min` minute * * `h` hour * * `d` day * * `1` dimensionless * **Prefixes (PREFIX)** * * `k` kilo (10^3) * * `M` mega (10^6) * * `G` giga (10^9) * * `T` tera (10^12) * * `P` peta (10^15) * * `E` exa (10^18) * * `Z` zetta (10^21) * * `Y` yotta (10^24) * * `m` milli (10^-3) * * `u` micro (10^-6) * * `n` nano (10^-9) * * `p` pico (10^-12) * * `f` femto (10^-15) * * `a` atto (10^-18) * * `z` zepto (10^-21) * * `y` yocto (10^-24) * * `Ki` kibi (2^10) * * `Mi` mebi (2^20) * * `Gi` gibi (2^30) * * `Ti` tebi (2^40) * * `Pi` pebi (2^50) * **Grammar** * The grammar also includes these connectors: * * `/` division or ratio (as an infix operator). For examples, * `kBy/{email}` or `MiBy/10ms` (although you should almost never * have `/s` in a metric `unit`; rates should always be computed at * query time from the underlying cumulative or delta value). * * `.` multiplication or composition (as an infix operator). For * examples, `GBy.d` or `k{watt}.h`. * The grammar for a unit is as follows: * Expression = Component { "." Component } { "/" Component } ; * Component = ( [ PREFIX ] UNIT | "%" ) [ Annotation ] * | Annotation * | "1" * ; * Annotation = "{" NAME "}" ; * Notes: * * `Annotation` is just a comment if it follows a `UNIT`. If the annotation * is used alone, then the unit is equivalent to `1`. For examples, * `{request}/s == 1/s`, `By{transmitted}/s == By/s`. * * `NAME` is a sequence of non-blank printable ASCII characters not * containing `{` or `}`. * * `1` represents a unitary [dimensionless * unit](https://en.wikipedia.org/wiki/Dimensionless_quantity) of 1, such * as in `1/s`. It is typically used when none of the basic units are * appropriate. For example, "new users per day" can be represented as * `1/d` or `{new-users}/d` (and a metric value `5` would mean "5 new * users). Alternatively, "thousands of page views per day" would be * represented as `1000/d` or `k1/d` or `k{page_views}/d` (and a metric * value of `5.3` would mean "5300 page views per day"). * * `%` represents dimensionless value of 1/100, and annotates values giving * a percentage (so the metric values are typically in the range of 0..100, * and a metric value `3` means "3 percent"). * * `10^2.%` indicates a metric contains a ratio, typically in the range * 0..1, that will be multiplied by 100 and displayed as a percentage * (so a metric value `0.03` means "3 percent"). * * Generated from protobuf field string unit = 5; */ protected $unit = ''; /** * A detailed description of the metric, which can be used in documentation. * * Generated from protobuf field string description = 6; */ protected $description = ''; /** * A concise name for the metric, which can be displayed in user interfaces. * Use sentence case without an ending period, for example "Request count". * This field is optional but it is recommended to be set for any metrics * associated with user-visible concepts, such as Quota. * * Generated from protobuf field string display_name = 7; */ protected $display_name = ''; /** * Optional. Metadata which can be used to guide usage of the metric. * * Generated from protobuf field .google.api.MetricDescriptor.MetricDescriptorMetadata metadata = 10; */ protected $metadata = null; /** * Optional. The launch stage of the metric definition. * * Generated from protobuf field .google.api.LaunchStage launch_stage = 12; */ protected $launch_stage = 0; /** * Read-only. If present, then a [time * series][google.monitoring.v3.TimeSeries], which is identified partially by * a metric type and a * [MonitoredResourceDescriptor][google.api.MonitoredResourceDescriptor], that * is associated with this metric type can only be associated with one of the * monitored resource types listed here. * * Generated from protobuf field repeated string monitored_resource_types = 13; */ private $monitored_resource_types; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $name * The resource name of the metric descriptor. * @type string $type * The metric type, including its DNS name prefix. The type is not * URL-encoded. All user-defined metric types have the DNS name * `custom.googleapis.com` or `external.googleapis.com`. Metric types should * use a natural hierarchical grouping. For example: * "custom.googleapis.com/invoice/paid/amount" * "external.googleapis.com/prometheus/up" * "appengine.googleapis.com/http/server/response_latencies" * @type array<\Google\Api\LabelDescriptor>|\Google\Protobuf\Internal\RepeatedField $labels * The set of labels that can be used to describe a specific * instance of this metric type. For example, the * `appengine.googleapis.com/http/server/response_latencies` metric * type has a label for the HTTP response code, `response_code`, so * you can look at latencies for successful responses or just * for responses that failed. * @type int $metric_kind * Whether the metric records instantaneous values, changes to a value, etc. * Some combinations of `metric_kind` and `value_type` might not be supported. * @type int $value_type * Whether the measurement is an integer, a floating-point number, etc. * Some combinations of `metric_kind` and `value_type` might not be supported. * @type string $unit * The units in which the metric value is reported. It is only applicable * if the `value_type` is `INT64`, `DOUBLE`, or `DISTRIBUTION`. The `unit` * defines the representation of the stored metric values. * Different systems might scale the values to be more easily displayed (so a * value of `0.02kBy` _might_ be displayed as `20By`, and a value of * `3523kBy` _might_ be displayed as `3.5MBy`). However, if the `unit` is * `kBy`, then the value of the metric is always in thousands of bytes, no * matter how it might be displayed. * If you want a custom metric to record the exact number of CPU-seconds used * by a job, you can create an `INT64 CUMULATIVE` metric whose `unit` is * `s{CPU}` (or equivalently `1s{CPU}` or just `s`). If the job uses 12,005 * CPU-seconds, then the value is written as `12005`. * Alternatively, if you want a custom metric to record data in a more * granular way, you can create a `DOUBLE CUMULATIVE` metric whose `unit` is * `ks{CPU}`, and then write the value `12.005` (which is `12005/1000`), * or use `Kis{CPU}` and write `11.723` (which is `12005/1024`). * The supported units are a subset of [The Unified Code for Units of * Measure](https://unitsofmeasure.org/ucum.html) standard: * **Basic units (UNIT)** * * `bit` bit * * `By` byte * * `s` second * * `min` minute * * `h` hour * * `d` day * * `1` dimensionless * **Prefixes (PREFIX)** * * `k` kilo (10^3) * * `M` mega (10^6) * * `G` giga (10^9) * * `T` tera (10^12) * * `P` peta (10^15) * * `E` exa (10^18) * * `Z` zetta (10^21) * * `Y` yotta (10^24) * * `m` milli (10^-3) * * `u` micro (10^-6) * * `n` nano (10^-9) * * `p` pico (10^-12) * * `f` femto (10^-15) * * `a` atto (10^-18) * * `z` zepto (10^-21) * * `y` yocto (10^-24) * * `Ki` kibi (2^10) * * `Mi` mebi (2^20) * * `Gi` gibi (2^30) * * `Ti` tebi (2^40) * * `Pi` pebi (2^50) * **Grammar** * The grammar also includes these connectors: * * `/` division or ratio (as an infix operator). For examples, * `kBy/{email}` or `MiBy/10ms` (although you should almost never * have `/s` in a metric `unit`; rates should always be computed at * query time from the underlying cumulative or delta value). * * `.` multiplication or composition (as an infix operator). For * examples, `GBy.d` or `k{watt}.h`. * The grammar for a unit is as follows: * Expression = Component { "." Component } { "/" Component } ; * Component = ( [ PREFIX ] UNIT | "%" ) [ Annotation ] * | Annotation * | "1" * ; * Annotation = "{" NAME "}" ; * Notes: * * `Annotation` is just a comment if it follows a `UNIT`. If the annotation * is used alone, then the unit is equivalent to `1`. For examples, * `{request}/s == 1/s`, `By{transmitted}/s == By/s`. * * `NAME` is a sequence of non-blank printable ASCII characters not * containing `{` or `}`. * * `1` represents a unitary [dimensionless * unit](https://en.wikipedia.org/wiki/Dimensionless_quantity) of 1, such * as in `1/s`. It is typically used when none of the basic units are * appropriate. For example, "new users per day" can be represented as * `1/d` or `{new-users}/d` (and a metric value `5` would mean "5 new * users). Alternatively, "thousands of page views per day" would be * represented as `1000/d` or `k1/d` or `k{page_views}/d` (and a metric * value of `5.3` would mean "5300 page views per day"). * * `%` represents dimensionless value of 1/100, and annotates values giving * a percentage (so the metric values are typically in the range of 0..100, * and a metric value `3` means "3 percent"). * * `10^2.%` indicates a metric contains a ratio, typically in the range * 0..1, that will be multiplied by 100 and displayed as a percentage * (so a metric value `0.03` means "3 percent"). * @type string $description * A detailed description of the metric, which can be used in documentation. * @type string $display_name * A concise name for the metric, which can be displayed in user interfaces. * Use sentence case without an ending period, for example "Request count". * This field is optional but it is recommended to be set for any metrics * associated with user-visible concepts, such as Quota. * @type \Google\Api\MetricDescriptor\MetricDescriptorMetadata $metadata * Optional. Metadata which can be used to guide usage of the metric. * @type int $launch_stage * Optional. The launch stage of the metric definition. * @type array|\Google\Protobuf\Internal\RepeatedField $monitored_resource_types * Read-only. If present, then a [time * series][google.monitoring.v3.TimeSeries], which is identified partially by * a metric type and a * [MonitoredResourceDescriptor][google.api.MonitoredResourceDescriptor], that * is associated with this metric type can only be associated with one of the * monitored resource types listed here. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Metric::initOnce(); parent::__construct($data); } /** * The resource name of the metric descriptor. * * Generated from protobuf field string name = 1; * @return string */ public function getName() { return $this->name; } /** * The resource name of the metric descriptor. * * Generated from protobuf field string name = 1; * @param string $var * @return $this */ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; return $this; } /** * The metric type, including its DNS name prefix. The type is not * URL-encoded. All user-defined metric types have the DNS name * `custom.googleapis.com` or `external.googleapis.com`. Metric types should * use a natural hierarchical grouping. For example: * "custom.googleapis.com/invoice/paid/amount" * "external.googleapis.com/prometheus/up" * "appengine.googleapis.com/http/server/response_latencies" * * Generated from protobuf field string type = 8; * @return string */ public function getType() { return $this->type; } /** * The metric type, including its DNS name prefix. The type is not * URL-encoded. All user-defined metric types have the DNS name * `custom.googleapis.com` or `external.googleapis.com`. Metric types should * use a natural hierarchical grouping. For example: * "custom.googleapis.com/invoice/paid/amount" * "external.googleapis.com/prometheus/up" * "appengine.googleapis.com/http/server/response_latencies" * * Generated from protobuf field string type = 8; * @param string $var * @return $this */ public function setType($var) { GPBUtil::checkString($var, True); $this->type = $var; return $this; } /** * The set of labels that can be used to describe a specific * instance of this metric type. For example, the * `appengine.googleapis.com/http/server/response_latencies` metric * type has a label for the HTTP response code, `response_code`, so * you can look at latencies for successful responses or just * for responses that failed. * * Generated from protobuf field repeated .google.api.LabelDescriptor labels = 2; * @return \Google\Protobuf\Internal\RepeatedField */ public function getLabels() { return $this->labels; } /** * The set of labels that can be used to describe a specific * instance of this metric type. For example, the * `appengine.googleapis.com/http/server/response_latencies` metric * type has a label for the HTTP response code, `response_code`, so * you can look at latencies for successful responses or just * for responses that failed. * * Generated from protobuf field repeated .google.api.LabelDescriptor labels = 2; * @param array<\Google\Api\LabelDescriptor>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setLabels($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Api\LabelDescriptor::class); $this->labels = $arr; return $this; } /** * Whether the metric records instantaneous values, changes to a value, etc. * Some combinations of `metric_kind` and `value_type` might not be supported. * * Generated from protobuf field .google.api.MetricDescriptor.MetricKind metric_kind = 3; * @return int */ public function getMetricKind() { return $this->metric_kind; } /** * Whether the metric records instantaneous values, changes to a value, etc. * Some combinations of `metric_kind` and `value_type` might not be supported. * * Generated from protobuf field .google.api.MetricDescriptor.MetricKind metric_kind = 3; * @param int $var * @return $this */ public function setMetricKind($var) { GPBUtil::checkEnum($var, \Google\Api\MetricDescriptor\MetricKind::class); $this->metric_kind = $var; return $this; } /** * Whether the measurement is an integer, a floating-point number, etc. * Some combinations of `metric_kind` and `value_type` might not be supported. * * Generated from protobuf field .google.api.MetricDescriptor.ValueType value_type = 4; * @return int */ public function getValueType() { return $this->value_type; } /** * Whether the measurement is an integer, a floating-point number, etc. * Some combinations of `metric_kind` and `value_type` might not be supported. * * Generated from protobuf field .google.api.MetricDescriptor.ValueType value_type = 4; * @param int $var * @return $this */ public function setValueType($var) { GPBUtil::checkEnum($var, \Google\Api\MetricDescriptor\ValueType::class); $this->value_type = $var; return $this; } /** * The units in which the metric value is reported. It is only applicable * if the `value_type` is `INT64`, `DOUBLE`, or `DISTRIBUTION`. The `unit` * defines the representation of the stored metric values. * Different systems might scale the values to be more easily displayed (so a * value of `0.02kBy` _might_ be displayed as `20By`, and a value of * `3523kBy` _might_ be displayed as `3.5MBy`). However, if the `unit` is * `kBy`, then the value of the metric is always in thousands of bytes, no * matter how it might be displayed. * If you want a custom metric to record the exact number of CPU-seconds used * by a job, you can create an `INT64 CUMULATIVE` metric whose `unit` is * `s{CPU}` (or equivalently `1s{CPU}` or just `s`). If the job uses 12,005 * CPU-seconds, then the value is written as `12005`. * Alternatively, if you want a custom metric to record data in a more * granular way, you can create a `DOUBLE CUMULATIVE` metric whose `unit` is * `ks{CPU}`, and then write the value `12.005` (which is `12005/1000`), * or use `Kis{CPU}` and write `11.723` (which is `12005/1024`). * The supported units are a subset of [The Unified Code for Units of * Measure](https://unitsofmeasure.org/ucum.html) standard: * **Basic units (UNIT)** * * `bit` bit * * `By` byte * * `s` second * * `min` minute * * `h` hour * * `d` day * * `1` dimensionless * **Prefixes (PREFIX)** * * `k` kilo (10^3) * * `M` mega (10^6) * * `G` giga (10^9) * * `T` tera (10^12) * * `P` peta (10^15) * * `E` exa (10^18) * * `Z` zetta (10^21) * * `Y` yotta (10^24) * * `m` milli (10^-3) * * `u` micro (10^-6) * * `n` nano (10^-9) * * `p` pico (10^-12) * * `f` femto (10^-15) * * `a` atto (10^-18) * * `z` zepto (10^-21) * * `y` yocto (10^-24) * * `Ki` kibi (2^10) * * `Mi` mebi (2^20) * * `Gi` gibi (2^30) * * `Ti` tebi (2^40) * * `Pi` pebi (2^50) * **Grammar** * The grammar also includes these connectors: * * `/` division or ratio (as an infix operator). For examples, * `kBy/{email}` or `MiBy/10ms` (although you should almost never * have `/s` in a metric `unit`; rates should always be computed at * query time from the underlying cumulative or delta value). * * `.` multiplication or composition (as an infix operator). For * examples, `GBy.d` or `k{watt}.h`. * The grammar for a unit is as follows: * Expression = Component { "." Component } { "/" Component } ; * Component = ( [ PREFIX ] UNIT | "%" ) [ Annotation ] * | Annotation * | "1" * ; * Annotation = "{" NAME "}" ; * Notes: * * `Annotation` is just a comment if it follows a `UNIT`. If the annotation * is used alone, then the unit is equivalent to `1`. For examples, * `{request}/s == 1/s`, `By{transmitted}/s == By/s`. * * `NAME` is a sequence of non-blank printable ASCII characters not * containing `{` or `}`. * * `1` represents a unitary [dimensionless * unit](https://en.wikipedia.org/wiki/Dimensionless_quantity) of 1, such * as in `1/s`. It is typically used when none of the basic units are * appropriate. For example, "new users per day" can be represented as * `1/d` or `{new-users}/d` (and a metric value `5` would mean "5 new * users). Alternatively, "thousands of page views per day" would be * represented as `1000/d` or `k1/d` or `k{page_views}/d` (and a metric * value of `5.3` would mean "5300 page views per day"). * * `%` represents dimensionless value of 1/100, and annotates values giving * a percentage (so the metric values are typically in the range of 0..100, * and a metric value `3` means "3 percent"). * * `10^2.%` indicates a metric contains a ratio, typically in the range * 0..1, that will be multiplied by 100 and displayed as a percentage * (so a metric value `0.03` means "3 percent"). * * Generated from protobuf field string unit = 5; * @return string */ public function getUnit() { return $this->unit; } /** * The units in which the metric value is reported. It is only applicable * if the `value_type` is `INT64`, `DOUBLE`, or `DISTRIBUTION`. The `unit` * defines the representation of the stored metric values. * Different systems might scale the values to be more easily displayed (so a * value of `0.02kBy` _might_ be displayed as `20By`, and a value of * `3523kBy` _might_ be displayed as `3.5MBy`). However, if the `unit` is * `kBy`, then the value of the metric is always in thousands of bytes, no * matter how it might be displayed. * If you want a custom metric to record the exact number of CPU-seconds used * by a job, you can create an `INT64 CUMULATIVE` metric whose `unit` is * `s{CPU}` (or equivalently `1s{CPU}` or just `s`). If the job uses 12,005 * CPU-seconds, then the value is written as `12005`. * Alternatively, if you want a custom metric to record data in a more * granular way, you can create a `DOUBLE CUMULATIVE` metric whose `unit` is * `ks{CPU}`, and then write the value `12.005` (which is `12005/1000`), * or use `Kis{CPU}` and write `11.723` (which is `12005/1024`). * The supported units are a subset of [The Unified Code for Units of * Measure](https://unitsofmeasure.org/ucum.html) standard: * **Basic units (UNIT)** * * `bit` bit * * `By` byte * * `s` second * * `min` minute * * `h` hour * * `d` day * * `1` dimensionless * **Prefixes (PREFIX)** * * `k` kilo (10^3) * * `M` mega (10^6) * * `G` giga (10^9) * * `T` tera (10^12) * * `P` peta (10^15) * * `E` exa (10^18) * * `Z` zetta (10^21) * * `Y` yotta (10^24) * * `m` milli (10^-3) * * `u` micro (10^-6) * * `n` nano (10^-9) * * `p` pico (10^-12) * * `f` femto (10^-15) * * `a` atto (10^-18) * * `z` zepto (10^-21) * * `y` yocto (10^-24) * * `Ki` kibi (2^10) * * `Mi` mebi (2^20) * * `Gi` gibi (2^30) * * `Ti` tebi (2^40) * * `Pi` pebi (2^50) * **Grammar** * The grammar also includes these connectors: * * `/` division or ratio (as an infix operator). For examples, * `kBy/{email}` or `MiBy/10ms` (although you should almost never * have `/s` in a metric `unit`; rates should always be computed at * query time from the underlying cumulative or delta value). * * `.` multiplication or composition (as an infix operator). For * examples, `GBy.d` or `k{watt}.h`. * The grammar for a unit is as follows: * Expression = Component { "." Component } { "/" Component } ; * Component = ( [ PREFIX ] UNIT | "%" ) [ Annotation ] * | Annotation * | "1" * ; * Annotation = "{" NAME "}" ; * Notes: * * `Annotation` is just a comment if it follows a `UNIT`. If the annotation * is used alone, then the unit is equivalent to `1`. For examples, * `{request}/s == 1/s`, `By{transmitted}/s == By/s`. * * `NAME` is a sequence of non-blank printable ASCII characters not * containing `{` or `}`. * * `1` represents a unitary [dimensionless * unit](https://en.wikipedia.org/wiki/Dimensionless_quantity) of 1, such * as in `1/s`. It is typically used when none of the basic units are * appropriate. For example, "new users per day" can be represented as * `1/d` or `{new-users}/d` (and a metric value `5` would mean "5 new * users). Alternatively, "thousands of page views per day" would be * represented as `1000/d` or `k1/d` or `k{page_views}/d` (and a metric * value of `5.3` would mean "5300 page views per day"). * * `%` represents dimensionless value of 1/100, and annotates values giving * a percentage (so the metric values are typically in the range of 0..100, * and a metric value `3` means "3 percent"). * * `10^2.%` indicates a metric contains a ratio, typically in the range * 0..1, that will be multiplied by 100 and displayed as a percentage * (so a metric value `0.03` means "3 percent"). * * Generated from protobuf field string unit = 5; * @param string $var * @return $this */ public function setUnit($var) { GPBUtil::checkString($var, True); $this->unit = $var; return $this; } /** * A detailed description of the metric, which can be used in documentation. * * Generated from protobuf field string description = 6; * @return string */ public function getDescription() { return $this->description; } /** * A detailed description of the metric, which can be used in documentation. * * Generated from protobuf field string description = 6; * @param string $var * @return $this */ public function setDescription($var) { GPBUtil::checkString($var, True); $this->description = $var; return $this; } /** * A concise name for the metric, which can be displayed in user interfaces. * Use sentence case without an ending period, for example "Request count". * This field is optional but it is recommended to be set for any metrics * associated with user-visible concepts, such as Quota. * * Generated from protobuf field string display_name = 7; * @return string */ public function getDisplayName() { return $this->display_name; } /** * A concise name for the metric, which can be displayed in user interfaces. * Use sentence case without an ending period, for example "Request count". * This field is optional but it is recommended to be set for any metrics * associated with user-visible concepts, such as Quota. * * Generated from protobuf field string display_name = 7; * @param string $var * @return $this */ public function setDisplayName($var) { GPBUtil::checkString($var, True); $this->display_name = $var; return $this; } /** * Optional. Metadata which can be used to guide usage of the metric. * * Generated from protobuf field .google.api.MetricDescriptor.MetricDescriptorMetadata metadata = 10; * @return \Google\Api\MetricDescriptor\MetricDescriptorMetadata|null */ public function getMetadata() { return $this->metadata; } public function hasMetadata() { return isset($this->metadata); } public function clearMetadata() { unset($this->metadata); } /** * Optional. Metadata which can be used to guide usage of the metric. * * Generated from protobuf field .google.api.MetricDescriptor.MetricDescriptorMetadata metadata = 10; * @param \Google\Api\MetricDescriptor\MetricDescriptorMetadata $var * @return $this */ public function setMetadata($var) { GPBUtil::checkMessage($var, \Google\Api\MetricDescriptor\MetricDescriptorMetadata::class); $this->metadata = $var; return $this; } /** * Optional. The launch stage of the metric definition. * * Generated from protobuf field .google.api.LaunchStage launch_stage = 12; * @return int */ public function getLaunchStage() { return $this->launch_stage; } /** * Optional. The launch stage of the metric definition. * * Generated from protobuf field .google.api.LaunchStage launch_stage = 12; * @param int $var * @return $this */ public function setLaunchStage($var) { GPBUtil::checkEnum($var, \Google\Api\LaunchStage::class); $this->launch_stage = $var; return $this; } /** * Read-only. If present, then a [time * series][google.monitoring.v3.TimeSeries], which is identified partially by * a metric type and a * [MonitoredResourceDescriptor][google.api.MonitoredResourceDescriptor], that * is associated with this metric type can only be associated with one of the * monitored resource types listed here. * * Generated from protobuf field repeated string monitored_resource_types = 13; * @return \Google\Protobuf\Internal\RepeatedField */ public function getMonitoredResourceTypes() { return $this->monitored_resource_types; } /** * Read-only. If present, then a [time * series][google.monitoring.v3.TimeSeries], which is identified partially by * a metric type and a * [MonitoredResourceDescriptor][google.api.MonitoredResourceDescriptor], that * is associated with this metric type can only be associated with one of the * monitored resource types listed here. * * Generated from protobuf field repeated string monitored_resource_types = 13; * @param array|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setMonitoredResourceTypes($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->monitored_resource_types = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/MetricRule.php ================================================ google.api.MetricRule */ class MetricRule extends \Google\Protobuf\Internal\Message { /** * Selects the methods to which this rule applies. * Refer to [selector][google.api.DocumentationRule.selector] for syntax * details. * * Generated from protobuf field string selector = 1; */ protected $selector = ''; /** * Metrics to update when the selected methods are called, and the associated * cost applied to each metric. * The key of the map is the metric name, and the values are the amount * increased for the metric against which the quota limits are defined. * The value must not be negative. * * Generated from protobuf field map metric_costs = 2; */ private $metric_costs; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $selector * Selects the methods to which this rule applies. * Refer to [selector][google.api.DocumentationRule.selector] for syntax * details. * @type array|\Google\Protobuf\Internal\MapField $metric_costs * Metrics to update when the selected methods are called, and the associated * cost applied to each metric. * The key of the map is the metric name, and the values are the amount * increased for the metric against which the quota limits are defined. * The value must not be negative. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Quota::initOnce(); parent::__construct($data); } /** * Selects the methods to which this rule applies. * Refer to [selector][google.api.DocumentationRule.selector] for syntax * details. * * Generated from protobuf field string selector = 1; * @return string */ public function getSelector() { return $this->selector; } /** * Selects the methods to which this rule applies. * Refer to [selector][google.api.DocumentationRule.selector] for syntax * details. * * Generated from protobuf field string selector = 1; * @param string $var * @return $this */ public function setSelector($var) { GPBUtil::checkString($var, True); $this->selector = $var; return $this; } /** * Metrics to update when the selected methods are called, and the associated * cost applied to each metric. * The key of the map is the metric name, and the values are the amount * increased for the metric against which the quota limits are defined. * The value must not be negative. * * Generated from protobuf field map metric_costs = 2; * @return \Google\Protobuf\Internal\MapField */ public function getMetricCosts() { return $this->metric_costs; } /** * Metrics to update when the selected methods are called, and the associated * cost applied to each metric. * The key of the map is the metric name, and the values are the amount * increased for the metric against which the quota limits are defined. * The value must not be negative. * * Generated from protobuf field map metric_costs = 2; * @param array|\Google\Protobuf\Internal\MapField $var * @return $this */ public function setMetricCosts($var) { $arr = GPBUtil::checkMapField($var, \Google\Protobuf\Internal\GPBType::STRING, \Google\Protobuf\Internal\GPBType::INT64); $this->metric_costs = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/MonitoredResource.php ================================================ google.api.MonitoredResource */ class MonitoredResource extends \Google\Protobuf\Internal\Message { /** * Required. The monitored resource type. This field must match * the `type` field of a * [MonitoredResourceDescriptor][google.api.MonitoredResourceDescriptor] * object. For example, the type of a Compute Engine VM instance is * `gce_instance`. Some descriptors include the service name in the type; for * example, the type of a Datastream stream is * `datastream.googleapis.com/Stream`. * * Generated from protobuf field string type = 1; */ protected $type = ''; /** * Required. Values for all of the labels listed in the associated monitored * resource descriptor. For example, Compute Engine VM instances use the * labels `"project_id"`, `"instance_id"`, and `"zone"`. * * Generated from protobuf field map labels = 2; */ private $labels; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $type * Required. The monitored resource type. This field must match * the `type` field of a * [MonitoredResourceDescriptor][google.api.MonitoredResourceDescriptor] * object. For example, the type of a Compute Engine VM instance is * `gce_instance`. Some descriptors include the service name in the type; for * example, the type of a Datastream stream is * `datastream.googleapis.com/Stream`. * @type array|\Google\Protobuf\Internal\MapField $labels * Required. Values for all of the labels listed in the associated monitored * resource descriptor. For example, Compute Engine VM instances use the * labels `"project_id"`, `"instance_id"`, and `"zone"`. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\MonitoredResource::initOnce(); parent::__construct($data); } /** * Required. The monitored resource type. This field must match * the `type` field of a * [MonitoredResourceDescriptor][google.api.MonitoredResourceDescriptor] * object. For example, the type of a Compute Engine VM instance is * `gce_instance`. Some descriptors include the service name in the type; for * example, the type of a Datastream stream is * `datastream.googleapis.com/Stream`. * * Generated from protobuf field string type = 1; * @return string */ public function getType() { return $this->type; } /** * Required. The monitored resource type. This field must match * the `type` field of a * [MonitoredResourceDescriptor][google.api.MonitoredResourceDescriptor] * object. For example, the type of a Compute Engine VM instance is * `gce_instance`. Some descriptors include the service name in the type; for * example, the type of a Datastream stream is * `datastream.googleapis.com/Stream`. * * Generated from protobuf field string type = 1; * @param string $var * @return $this */ public function setType($var) { GPBUtil::checkString($var, True); $this->type = $var; return $this; } /** * Required. Values for all of the labels listed in the associated monitored * resource descriptor. For example, Compute Engine VM instances use the * labels `"project_id"`, `"instance_id"`, and `"zone"`. * * Generated from protobuf field map labels = 2; * @return \Google\Protobuf\Internal\MapField */ public function getLabels() { return $this->labels; } /** * Required. Values for all of the labels listed in the associated monitored * resource descriptor. For example, Compute Engine VM instances use the * labels `"project_id"`, `"instance_id"`, and `"zone"`. * * Generated from protobuf field map labels = 2; * @param array|\Google\Protobuf\Internal\MapField $var * @return $this */ public function setLabels($var) { $arr = GPBUtil::checkMapField($var, \Google\Protobuf\Internal\GPBType::STRING, \Google\Protobuf\Internal\GPBType::STRING); $this->labels = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/MonitoredResourceDescriptor.php ================================================ google.api.MonitoredResourceDescriptor */ class MonitoredResourceDescriptor extends \Google\Protobuf\Internal\Message { /** * Optional. The resource name of the monitored resource descriptor: * `"projects/{project_id}/monitoredResourceDescriptors/{type}"` where * {type} is the value of the `type` field in this object and * {project_id} is a project ID that provides API-specific context for * accessing the type. APIs that do not use project information can use the * resource name format `"monitoredResourceDescriptors/{type}"`. * * Generated from protobuf field string name = 5; */ protected $name = ''; /** * Required. The monitored resource type. For example, the type * `"cloudsql_database"` represents databases in Google Cloud SQL. * For a list of types, see [Monitored resource * types](https://cloud.google.com/monitoring/api/resources) * and [Logging resource * types](https://cloud.google.com/logging/docs/api/v2/resource-list). * * Generated from protobuf field string type = 1; */ protected $type = ''; /** * Optional. A concise name for the monitored resource type that might be * displayed in user interfaces. It should be a Title Cased Noun Phrase, * without any article or other determiners. For example, * `"Google Cloud SQL Database"`. * * Generated from protobuf field string display_name = 2; */ protected $display_name = ''; /** * Optional. A detailed description of the monitored resource type that might * be used in documentation. * * Generated from protobuf field string description = 3; */ protected $description = ''; /** * Required. A set of labels used to describe instances of this monitored * resource type. For example, an individual Google Cloud SQL database is * identified by values for the labels `"database_id"` and `"zone"`. * * Generated from protobuf field repeated .google.api.LabelDescriptor labels = 4; */ private $labels; /** * Optional. The launch stage of the monitored resource definition. * * Generated from protobuf field .google.api.LaunchStage launch_stage = 7; */ protected $launch_stage = 0; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $name * Optional. The resource name of the monitored resource descriptor: * `"projects/{project_id}/monitoredResourceDescriptors/{type}"` where * {type} is the value of the `type` field in this object and * {project_id} is a project ID that provides API-specific context for * accessing the type. APIs that do not use project information can use the * resource name format `"monitoredResourceDescriptors/{type}"`. * @type string $type * Required. The monitored resource type. For example, the type * `"cloudsql_database"` represents databases in Google Cloud SQL. * For a list of types, see [Monitored resource * types](https://cloud.google.com/monitoring/api/resources) * and [Logging resource * types](https://cloud.google.com/logging/docs/api/v2/resource-list). * @type string $display_name * Optional. A concise name for the monitored resource type that might be * displayed in user interfaces. It should be a Title Cased Noun Phrase, * without any article or other determiners. For example, * `"Google Cloud SQL Database"`. * @type string $description * Optional. A detailed description of the monitored resource type that might * be used in documentation. * @type array<\Google\Api\LabelDescriptor>|\Google\Protobuf\Internal\RepeatedField $labels * Required. A set of labels used to describe instances of this monitored * resource type. For example, an individual Google Cloud SQL database is * identified by values for the labels `"database_id"` and `"zone"`. * @type int $launch_stage * Optional. The launch stage of the monitored resource definition. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\MonitoredResource::initOnce(); parent::__construct($data); } /** * Optional. The resource name of the monitored resource descriptor: * `"projects/{project_id}/monitoredResourceDescriptors/{type}"` where * {type} is the value of the `type` field in this object and * {project_id} is a project ID that provides API-specific context for * accessing the type. APIs that do not use project information can use the * resource name format `"monitoredResourceDescriptors/{type}"`. * * Generated from protobuf field string name = 5; * @return string */ public function getName() { return $this->name; } /** * Optional. The resource name of the monitored resource descriptor: * `"projects/{project_id}/monitoredResourceDescriptors/{type}"` where * {type} is the value of the `type` field in this object and * {project_id} is a project ID that provides API-specific context for * accessing the type. APIs that do not use project information can use the * resource name format `"monitoredResourceDescriptors/{type}"`. * * Generated from protobuf field string name = 5; * @param string $var * @return $this */ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; return $this; } /** * Required. The monitored resource type. For example, the type * `"cloudsql_database"` represents databases in Google Cloud SQL. * For a list of types, see [Monitored resource * types](https://cloud.google.com/monitoring/api/resources) * and [Logging resource * types](https://cloud.google.com/logging/docs/api/v2/resource-list). * * Generated from protobuf field string type = 1; * @return string */ public function getType() { return $this->type; } /** * Required. The monitored resource type. For example, the type * `"cloudsql_database"` represents databases in Google Cloud SQL. * For a list of types, see [Monitored resource * types](https://cloud.google.com/monitoring/api/resources) * and [Logging resource * types](https://cloud.google.com/logging/docs/api/v2/resource-list). * * Generated from protobuf field string type = 1; * @param string $var * @return $this */ public function setType($var) { GPBUtil::checkString($var, True); $this->type = $var; return $this; } /** * Optional. A concise name for the monitored resource type that might be * displayed in user interfaces. It should be a Title Cased Noun Phrase, * without any article or other determiners. For example, * `"Google Cloud SQL Database"`. * * Generated from protobuf field string display_name = 2; * @return string */ public function getDisplayName() { return $this->display_name; } /** * Optional. A concise name for the monitored resource type that might be * displayed in user interfaces. It should be a Title Cased Noun Phrase, * without any article or other determiners. For example, * `"Google Cloud SQL Database"`. * * Generated from protobuf field string display_name = 2; * @param string $var * @return $this */ public function setDisplayName($var) { GPBUtil::checkString($var, True); $this->display_name = $var; return $this; } /** * Optional. A detailed description of the monitored resource type that might * be used in documentation. * * Generated from protobuf field string description = 3; * @return string */ public function getDescription() { return $this->description; } /** * Optional. A detailed description of the monitored resource type that might * be used in documentation. * * Generated from protobuf field string description = 3; * @param string $var * @return $this */ public function setDescription($var) { GPBUtil::checkString($var, True); $this->description = $var; return $this; } /** * Required. A set of labels used to describe instances of this monitored * resource type. For example, an individual Google Cloud SQL database is * identified by values for the labels `"database_id"` and `"zone"`. * * Generated from protobuf field repeated .google.api.LabelDescriptor labels = 4; * @return \Google\Protobuf\Internal\RepeatedField */ public function getLabels() { return $this->labels; } /** * Required. A set of labels used to describe instances of this monitored * resource type. For example, an individual Google Cloud SQL database is * identified by values for the labels `"database_id"` and `"zone"`. * * Generated from protobuf field repeated .google.api.LabelDescriptor labels = 4; * @param array<\Google\Api\LabelDescriptor>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setLabels($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Api\LabelDescriptor::class); $this->labels = $arr; return $this; } /** * Optional. The launch stage of the monitored resource definition. * * Generated from protobuf field .google.api.LaunchStage launch_stage = 7; * @return int */ public function getLaunchStage() { return $this->launch_stage; } /** * Optional. The launch stage of the monitored resource definition. * * Generated from protobuf field .google.api.LaunchStage launch_stage = 7; * @param int $var * @return $this */ public function setLaunchStage($var) { GPBUtil::checkEnum($var, \Google\Api\LaunchStage::class); $this->launch_stage = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/MonitoredResourceMetadata.php ================================================ google.api.MonitoredResourceMetadata */ class MonitoredResourceMetadata extends \Google\Protobuf\Internal\Message { /** * Output only. Values for predefined system metadata labels. * System labels are a kind of metadata extracted by Google, including * "machine_image", "vpc", "subnet_id", * "security_group", "name", etc. * System label values can be only strings, Boolean values, or a list of * strings. For example: * { "name": "my-test-instance", * "security_group": ["a", "b", "c"], * "spot_instance": false } * * Generated from protobuf field .google.protobuf.Struct system_labels = 1; */ protected $system_labels = null; /** * Output only. A map of user-defined metadata labels. * * Generated from protobuf field map user_labels = 2; */ private $user_labels; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type \Google\Protobuf\Struct $system_labels * Output only. Values for predefined system metadata labels. * System labels are a kind of metadata extracted by Google, including * "machine_image", "vpc", "subnet_id", * "security_group", "name", etc. * System label values can be only strings, Boolean values, or a list of * strings. For example: * { "name": "my-test-instance", * "security_group": ["a", "b", "c"], * "spot_instance": false } * @type array|\Google\Protobuf\Internal\MapField $user_labels * Output only. A map of user-defined metadata labels. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\MonitoredResource::initOnce(); parent::__construct($data); } /** * Output only. Values for predefined system metadata labels. * System labels are a kind of metadata extracted by Google, including * "machine_image", "vpc", "subnet_id", * "security_group", "name", etc. * System label values can be only strings, Boolean values, or a list of * strings. For example: * { "name": "my-test-instance", * "security_group": ["a", "b", "c"], * "spot_instance": false } * * Generated from protobuf field .google.protobuf.Struct system_labels = 1; * @return \Google\Protobuf\Struct|null */ public function getSystemLabels() { return $this->system_labels; } public function hasSystemLabels() { return isset($this->system_labels); } public function clearSystemLabels() { unset($this->system_labels); } /** * Output only. Values for predefined system metadata labels. * System labels are a kind of metadata extracted by Google, including * "machine_image", "vpc", "subnet_id", * "security_group", "name", etc. * System label values can be only strings, Boolean values, or a list of * strings. For example: * { "name": "my-test-instance", * "security_group": ["a", "b", "c"], * "spot_instance": false } * * Generated from protobuf field .google.protobuf.Struct system_labels = 1; * @param \Google\Protobuf\Struct $var * @return $this */ public function setSystemLabels($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Struct::class); $this->system_labels = $var; return $this; } /** * Output only. A map of user-defined metadata labels. * * Generated from protobuf field map user_labels = 2; * @return \Google\Protobuf\Internal\MapField */ public function getUserLabels() { return $this->user_labels; } /** * Output only. A map of user-defined metadata labels. * * Generated from protobuf field map user_labels = 2; * @param array|\Google\Protobuf\Internal\MapField $var * @return $this */ public function setUserLabels($var) { $arr = GPBUtil::checkMapField($var, \Google\Protobuf\Internal\GPBType::STRING, \Google\Protobuf\Internal\GPBType::STRING); $this->user_labels = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/Monitoring/MonitoringDestination.php ================================================ google.api.Monitoring.MonitoringDestination */ class MonitoringDestination extends \Google\Protobuf\Internal\Message { /** * The monitored resource type. The type must be defined in * [Service.monitored_resources][google.api.Service.monitored_resources] * section. * * Generated from protobuf field string monitored_resource = 1; */ protected $monitored_resource = ''; /** * Types of the metrics to report to this monitoring destination. * Each type must be defined in * [Service.metrics][google.api.Service.metrics] section. * * Generated from protobuf field repeated string metrics = 2; */ private $metrics; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $monitored_resource * The monitored resource type. The type must be defined in * [Service.monitored_resources][google.api.Service.monitored_resources] * section. * @type array|\Google\Protobuf\Internal\RepeatedField $metrics * Types of the metrics to report to this monitoring destination. * Each type must be defined in * [Service.metrics][google.api.Service.metrics] section. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Monitoring::initOnce(); parent::__construct($data); } /** * The monitored resource type. The type must be defined in * [Service.monitored_resources][google.api.Service.monitored_resources] * section. * * Generated from protobuf field string monitored_resource = 1; * @return string */ public function getMonitoredResource() { return $this->monitored_resource; } /** * The monitored resource type. The type must be defined in * [Service.monitored_resources][google.api.Service.monitored_resources] * section. * * Generated from protobuf field string monitored_resource = 1; * @param string $var * @return $this */ public function setMonitoredResource($var) { GPBUtil::checkString($var, True); $this->monitored_resource = $var; return $this; } /** * Types of the metrics to report to this monitoring destination. * Each type must be defined in * [Service.metrics][google.api.Service.metrics] section. * * Generated from protobuf field repeated string metrics = 2; * @return \Google\Protobuf\Internal\RepeatedField */ public function getMetrics() { return $this->metrics; } /** * Types of the metrics to report to this monitoring destination. * Each type must be defined in * [Service.metrics][google.api.Service.metrics] section. * * Generated from protobuf field repeated string metrics = 2; * @param array|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setMetrics($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->metrics = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/Monitoring.php ================================================ google.api.Monitoring */ class Monitoring extends \Google\Protobuf\Internal\Message { /** * Monitoring configurations for sending metrics to the producer project. * There can be multiple producer destinations. A monitored resource type may * appear in multiple monitoring destinations if different aggregations are * needed for different sets of metrics associated with that monitored * resource type. A monitored resource and metric pair may only be used once * in the Monitoring configuration. * * Generated from protobuf field repeated .google.api.Monitoring.MonitoringDestination producer_destinations = 1; */ private $producer_destinations; /** * Monitoring configurations for sending metrics to the consumer project. * There can be multiple consumer destinations. A monitored resource type may * appear in multiple monitoring destinations if different aggregations are * needed for different sets of metrics associated with that monitored * resource type. A monitored resource and metric pair may only be used once * in the Monitoring configuration. * * Generated from protobuf field repeated .google.api.Monitoring.MonitoringDestination consumer_destinations = 2; */ private $consumer_destinations; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type array<\Google\Api\Monitoring\MonitoringDestination>|\Google\Protobuf\Internal\RepeatedField $producer_destinations * Monitoring configurations for sending metrics to the producer project. * There can be multiple producer destinations. A monitored resource type may * appear in multiple monitoring destinations if different aggregations are * needed for different sets of metrics associated with that monitored * resource type. A monitored resource and metric pair may only be used once * in the Monitoring configuration. * @type array<\Google\Api\Monitoring\MonitoringDestination>|\Google\Protobuf\Internal\RepeatedField $consumer_destinations * Monitoring configurations for sending metrics to the consumer project. * There can be multiple consumer destinations. A monitored resource type may * appear in multiple monitoring destinations if different aggregations are * needed for different sets of metrics associated with that monitored * resource type. A monitored resource and metric pair may only be used once * in the Monitoring configuration. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Monitoring::initOnce(); parent::__construct($data); } /** * Monitoring configurations for sending metrics to the producer project. * There can be multiple producer destinations. A monitored resource type may * appear in multiple monitoring destinations if different aggregations are * needed for different sets of metrics associated with that monitored * resource type. A monitored resource and metric pair may only be used once * in the Monitoring configuration. * * Generated from protobuf field repeated .google.api.Monitoring.MonitoringDestination producer_destinations = 1; * @return \Google\Protobuf\Internal\RepeatedField */ public function getProducerDestinations() { return $this->producer_destinations; } /** * Monitoring configurations for sending metrics to the producer project. * There can be multiple producer destinations. A monitored resource type may * appear in multiple monitoring destinations if different aggregations are * needed for different sets of metrics associated with that monitored * resource type. A monitored resource and metric pair may only be used once * in the Monitoring configuration. * * Generated from protobuf field repeated .google.api.Monitoring.MonitoringDestination producer_destinations = 1; * @param array<\Google\Api\Monitoring\MonitoringDestination>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setProducerDestinations($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Api\Monitoring\MonitoringDestination::class); $this->producer_destinations = $arr; return $this; } /** * Monitoring configurations for sending metrics to the consumer project. * There can be multiple consumer destinations. A monitored resource type may * appear in multiple monitoring destinations if different aggregations are * needed for different sets of metrics associated with that monitored * resource type. A monitored resource and metric pair may only be used once * in the Monitoring configuration. * * Generated from protobuf field repeated .google.api.Monitoring.MonitoringDestination consumer_destinations = 2; * @return \Google\Protobuf\Internal\RepeatedField */ public function getConsumerDestinations() { return $this->consumer_destinations; } /** * Monitoring configurations for sending metrics to the consumer project. * There can be multiple consumer destinations. A monitored resource type may * appear in multiple monitoring destinations if different aggregations are * needed for different sets of metrics associated with that monitored * resource type. A monitored resource and metric pair may only be used once * in the Monitoring configuration. * * Generated from protobuf field repeated .google.api.Monitoring.MonitoringDestination consumer_destinations = 2; * @param array<\Google\Api\Monitoring\MonitoringDestination>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setConsumerDestinations($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Api\Monitoring\MonitoringDestination::class); $this->consumer_destinations = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/NodeSettings.php ================================================ google.api.NodeSettings */ class NodeSettings extends \Google\Protobuf\Internal\Message { /** * Some settings. * * Generated from protobuf field .google.api.CommonLanguageSettings common = 1; */ protected $common = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type \Google\Api\CommonLanguageSettings $common * Some settings. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Client::initOnce(); parent::__construct($data); } /** * Some settings. * * Generated from protobuf field .google.api.CommonLanguageSettings common = 1; * @return \Google\Api\CommonLanguageSettings|null */ public function getCommon() { return $this->common; } public function hasCommon() { return isset($this->common); } public function clearCommon() { unset($this->common); } /** * Some settings. * * Generated from protobuf field .google.api.CommonLanguageSettings common = 1; * @param \Google\Api\CommonLanguageSettings $var * @return $this */ public function setCommon($var) { GPBUtil::checkMessage($var, \Google\Api\CommonLanguageSettings::class); $this->common = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/OAuthRequirements.php ================================================ google.api.OAuthRequirements */ class OAuthRequirements extends \Google\Protobuf\Internal\Message { /** * The list of publicly documented OAuth scopes that are allowed access. An * OAuth token containing any of these scopes will be accepted. * Example: * canonical_scopes: https://www.googleapis.com/auth/calendar, * https://www.googleapis.com/auth/calendar.read * * Generated from protobuf field string canonical_scopes = 1; */ protected $canonical_scopes = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $canonical_scopes * The list of publicly documented OAuth scopes that are allowed access. An * OAuth token containing any of these scopes will be accepted. * Example: * canonical_scopes: https://www.googleapis.com/auth/calendar, * https://www.googleapis.com/auth/calendar.read * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Auth::initOnce(); parent::__construct($data); } /** * The list of publicly documented OAuth scopes that are allowed access. An * OAuth token containing any of these scopes will be accepted. * Example: * canonical_scopes: https://www.googleapis.com/auth/calendar, * https://www.googleapis.com/auth/calendar.read * * Generated from protobuf field string canonical_scopes = 1; * @return string */ public function getCanonicalScopes() { return $this->canonical_scopes; } /** * The list of publicly documented OAuth scopes that are allowed access. An * OAuth token containing any of these scopes will be accepted. * Example: * canonical_scopes: https://www.googleapis.com/auth/calendar, * https://www.googleapis.com/auth/calendar.read * * Generated from protobuf field string canonical_scopes = 1; * @param string $var * @return $this */ public function setCanonicalScopes($var) { GPBUtil::checkString($var, True); $this->canonical_scopes = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/Page.php ================================================ google.api.Page */ class Page extends \Google\Protobuf\Internal\Message { /** * The name of the page. It will be used as an identity of the page to * generate URI of the page, text of the link to this page in navigation, * etc. The full page name (start from the root page name to this page * concatenated with `.`) can be used as reference to the page in your * documentation. For example: *
pages:
     * - name: Tutorial
     *   content: (== include tutorial.md ==)
     *   subpages:
     *   - name: Java
     *     content: (== include tutorial_java.md ==)
     * 
* You can reference `Java` page using Markdown reference link syntax: * `[Java][Tutorial.Java]`. * * Generated from protobuf field string name = 1; */ protected $name = ''; /** * The Markdown content of the page. You can use ```(== include {path} * ==)``` to include content from a Markdown file. The content can be used * to produce the documentation page such as HTML format page. * * Generated from protobuf field string content = 2; */ protected $content = ''; /** * Subpages of this page. The order of subpages specified here will be * honored in the generated docset. * * Generated from protobuf field repeated .google.api.Page subpages = 3; */ private $subpages; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $name * The name of the page. It will be used as an identity of the page to * generate URI of the page, text of the link to this page in navigation, * etc. The full page name (start from the root page name to this page * concatenated with `.`) can be used as reference to the page in your * documentation. For example: *
pages:
     *           - name: Tutorial
     *             content: (== include tutorial.md ==)
     *             subpages:
     *             - name: Java
     *               content: (== include tutorial_java.md ==)
     *           
* You can reference `Java` page using Markdown reference link syntax: * `[Java][Tutorial.Java]`. * @type string $content * The Markdown content of the page. You can use ```(== include {path} * ==)``` to include content from a Markdown file. The content can be used * to produce the documentation page such as HTML format page. * @type array<\Google\Api\Page>|\Google\Protobuf\Internal\RepeatedField $subpages * Subpages of this page. The order of subpages specified here will be * honored in the generated docset. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Documentation::initOnce(); parent::__construct($data); } /** * The name of the page. It will be used as an identity of the page to * generate URI of the page, text of the link to this page in navigation, * etc. The full page name (start from the root page name to this page * concatenated with `.`) can be used as reference to the page in your * documentation. For example: *
pages:
     * - name: Tutorial
     *   content: (== include tutorial.md ==)
     *   subpages:
     *   - name: Java
     *     content: (== include tutorial_java.md ==)
     * 
* You can reference `Java` page using Markdown reference link syntax: * `[Java][Tutorial.Java]`. * * Generated from protobuf field string name = 1; * @return string */ public function getName() { return $this->name; } /** * The name of the page. It will be used as an identity of the page to * generate URI of the page, text of the link to this page in navigation, * etc. The full page name (start from the root page name to this page * concatenated with `.`) can be used as reference to the page in your * documentation. For example: *
pages:
     * - name: Tutorial
     *   content: (== include tutorial.md ==)
     *   subpages:
     *   - name: Java
     *     content: (== include tutorial_java.md ==)
     * 
* You can reference `Java` page using Markdown reference link syntax: * `[Java][Tutorial.Java]`. * * Generated from protobuf field string name = 1; * @param string $var * @return $this */ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; return $this; } /** * The Markdown content of the page. You can use ```(== include {path} * ==)``` to include content from a Markdown file. The content can be used * to produce the documentation page such as HTML format page. * * Generated from protobuf field string content = 2; * @return string */ public function getContent() { return $this->content; } /** * The Markdown content of the page. You can use ```(== include {path} * ==)``` to include content from a Markdown file. The content can be used * to produce the documentation page such as HTML format page. * * Generated from protobuf field string content = 2; * @param string $var * @return $this */ public function setContent($var) { GPBUtil::checkString($var, True); $this->content = $var; return $this; } /** * Subpages of this page. The order of subpages specified here will be * honored in the generated docset. * * Generated from protobuf field repeated .google.api.Page subpages = 3; * @return \Google\Protobuf\Internal\RepeatedField */ public function getSubpages() { return $this->subpages; } /** * Subpages of this page. The order of subpages specified here will be * honored in the generated docset. * * Generated from protobuf field repeated .google.api.Page subpages = 3; * @param array<\Google\Api\Page>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setSubpages($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Api\Page::class); $this->subpages = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/PhpSettings.php ================================================ google.api.PhpSettings */ class PhpSettings extends \Google\Protobuf\Internal\Message { /** * Some settings. * * Generated from protobuf field .google.api.CommonLanguageSettings common = 1; */ protected $common = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type \Google\Api\CommonLanguageSettings $common * Some settings. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Client::initOnce(); parent::__construct($data); } /** * Some settings. * * Generated from protobuf field .google.api.CommonLanguageSettings common = 1; * @return \Google\Api\CommonLanguageSettings|null */ public function getCommon() { return $this->common; } public function hasCommon() { return isset($this->common); } public function clearCommon() { unset($this->common); } /** * Some settings. * * Generated from protobuf field .google.api.CommonLanguageSettings common = 1; * @param \Google\Api\CommonLanguageSettings $var * @return $this */ public function setCommon($var) { GPBUtil::checkMessage($var, \Google\Api\CommonLanguageSettings::class); $this->common = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/ProjectProperties.php ================================================ google.api.ProjectProperties */ class ProjectProperties extends \Google\Protobuf\Internal\Message { /** * List of per consumer project-specific properties. * * Generated from protobuf field repeated .google.api.Property properties = 1; */ private $properties; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type array<\Google\Api\Property>|\Google\Protobuf\Internal\RepeatedField $properties * List of per consumer project-specific properties. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Consumer::initOnce(); parent::__construct($data); } /** * List of per consumer project-specific properties. * * Generated from protobuf field repeated .google.api.Property properties = 1; * @return \Google\Protobuf\Internal\RepeatedField */ public function getProperties() { return $this->properties; } /** * List of per consumer project-specific properties. * * Generated from protobuf field repeated .google.api.Property properties = 1; * @param array<\Google\Api\Property>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setProperties($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Api\Property::class); $this->properties = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/Property/PropertyType.php ================================================ google.api.Property.PropertyType */ class PropertyType { /** * The type is unspecified, and will result in an error. * * Generated from protobuf enum UNSPECIFIED = 0; */ const UNSPECIFIED = 0; /** * The type is `int64`. * * Generated from protobuf enum INT64 = 1; */ const INT64 = 1; /** * The type is `bool`. * * Generated from protobuf enum BOOL = 2; */ const BOOL = 2; /** * The type is `string`. * * Generated from protobuf enum STRING = 3; */ const STRING = 3; /** * The type is 'double'. * * Generated from protobuf enum DOUBLE = 4; */ const DOUBLE = 4; private static $valueToName = [ self::UNSPECIFIED => 'UNSPECIFIED', self::INT64 => 'INT64', self::BOOL => 'BOOL', self::STRING => 'STRING', self::DOUBLE => 'DOUBLE', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/Property.php ================================================ google.api.Property */ class Property extends \Google\Protobuf\Internal\Message { /** * The name of the property (a.k.a key). * * Generated from protobuf field string name = 1; */ protected $name = ''; /** * The type of this property. * * Generated from protobuf field .google.api.Property.PropertyType type = 2; */ protected $type = 0; /** * The description of the property * * Generated from protobuf field string description = 3; */ protected $description = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $name * The name of the property (a.k.a key). * @type int $type * The type of this property. * @type string $description * The description of the property * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Consumer::initOnce(); parent::__construct($data); } /** * The name of the property (a.k.a key). * * Generated from protobuf field string name = 1; * @return string */ public function getName() { return $this->name; } /** * The name of the property (a.k.a key). * * Generated from protobuf field string name = 1; * @param string $var * @return $this */ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; return $this; } /** * The type of this property. * * Generated from protobuf field .google.api.Property.PropertyType type = 2; * @return int */ public function getType() { return $this->type; } /** * The type of this property. * * Generated from protobuf field .google.api.Property.PropertyType type = 2; * @param int $var * @return $this */ public function setType($var) { GPBUtil::checkEnum($var, \Google\Api\Property\PropertyType::class); $this->type = $var; return $this; } /** * The description of the property * * Generated from protobuf field string description = 3; * @return string */ public function getDescription() { return $this->description; } /** * The description of the property * * Generated from protobuf field string description = 3; * @param string $var * @return $this */ public function setDescription($var) { GPBUtil::checkString($var, True); $this->description = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/Publishing.php ================================================ google.api.Publishing */ class Publishing extends \Google\Protobuf\Internal\Message { /** * A list of API method settings, e.g. the behavior for methods that use the * long-running operation pattern. * * Generated from protobuf field repeated .google.api.MethodSettings method_settings = 2; */ private $method_settings; /** * Link to a *public* URI where users can report issues. Example: * https://issuetracker.google.com/issues/new?component=190865&template=1161103 * * Generated from protobuf field string new_issue_uri = 101; */ protected $new_issue_uri = ''; /** * Link to product home page. Example: * https://cloud.google.com/asset-inventory/docs/overview * * Generated from protobuf field string documentation_uri = 102; */ protected $documentation_uri = ''; /** * Used as a tracking tag when collecting data about the APIs developer * relations artifacts like docs, packages delivered to package managers, * etc. Example: "speech". * * Generated from protobuf field string api_short_name = 103; */ protected $api_short_name = ''; /** * GitHub label to apply to issues and pull requests opened for this API. * * Generated from protobuf field string github_label = 104; */ protected $github_label = ''; /** * GitHub teams to be added to CODEOWNERS in the directory in GitHub * containing source code for the client libraries for this API. * * Generated from protobuf field repeated string codeowner_github_teams = 105; */ private $codeowner_github_teams; /** * A prefix used in sample code when demarking regions to be included in * documentation. * * Generated from protobuf field string doc_tag_prefix = 106; */ protected $doc_tag_prefix = ''; /** * For whom the client library is being published. * * Generated from protobuf field .google.api.ClientLibraryOrganization organization = 107; */ protected $organization = 0; /** * Client library settings. If the same version string appears multiple * times in this list, then the last one wins. Settings from earlier * settings with the same version string are discarded. * * Generated from protobuf field repeated .google.api.ClientLibrarySettings library_settings = 109; */ private $library_settings; /** * Optional link to proto reference documentation. Example: * https://cloud.google.com/pubsub/lite/docs/reference/rpc * * Generated from protobuf field string proto_reference_documentation_uri = 110; */ protected $proto_reference_documentation_uri = ''; /** * Optional link to REST reference documentation. Example: * https://cloud.google.com/pubsub/lite/docs/reference/rest * * Generated from protobuf field string rest_reference_documentation_uri = 111; */ protected $rest_reference_documentation_uri = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type array<\Google\Api\MethodSettings>|\Google\Protobuf\Internal\RepeatedField $method_settings * A list of API method settings, e.g. the behavior for methods that use the * long-running operation pattern. * @type string $new_issue_uri * Link to a *public* URI where users can report issues. Example: * https://issuetracker.google.com/issues/new?component=190865&template=1161103 * @type string $documentation_uri * Link to product home page. Example: * https://cloud.google.com/asset-inventory/docs/overview * @type string $api_short_name * Used as a tracking tag when collecting data about the APIs developer * relations artifacts like docs, packages delivered to package managers, * etc. Example: "speech". * @type string $github_label * GitHub label to apply to issues and pull requests opened for this API. * @type array|\Google\Protobuf\Internal\RepeatedField $codeowner_github_teams * GitHub teams to be added to CODEOWNERS in the directory in GitHub * containing source code for the client libraries for this API. * @type string $doc_tag_prefix * A prefix used in sample code when demarking regions to be included in * documentation. * @type int $organization * For whom the client library is being published. * @type array<\Google\Api\ClientLibrarySettings>|\Google\Protobuf\Internal\RepeatedField $library_settings * Client library settings. If the same version string appears multiple * times in this list, then the last one wins. Settings from earlier * settings with the same version string are discarded. * @type string $proto_reference_documentation_uri * Optional link to proto reference documentation. Example: * https://cloud.google.com/pubsub/lite/docs/reference/rpc * @type string $rest_reference_documentation_uri * Optional link to REST reference documentation. Example: * https://cloud.google.com/pubsub/lite/docs/reference/rest * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Client::initOnce(); parent::__construct($data); } /** * A list of API method settings, e.g. the behavior for methods that use the * long-running operation pattern. * * Generated from protobuf field repeated .google.api.MethodSettings method_settings = 2; * @return \Google\Protobuf\Internal\RepeatedField */ public function getMethodSettings() { return $this->method_settings; } /** * A list of API method settings, e.g. the behavior for methods that use the * long-running operation pattern. * * Generated from protobuf field repeated .google.api.MethodSettings method_settings = 2; * @param array<\Google\Api\MethodSettings>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setMethodSettings($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Api\MethodSettings::class); $this->method_settings = $arr; return $this; } /** * Link to a *public* URI where users can report issues. Example: * https://issuetracker.google.com/issues/new?component=190865&template=1161103 * * Generated from protobuf field string new_issue_uri = 101; * @return string */ public function getNewIssueUri() { return $this->new_issue_uri; } /** * Link to a *public* URI where users can report issues. Example: * https://issuetracker.google.com/issues/new?component=190865&template=1161103 * * Generated from protobuf field string new_issue_uri = 101; * @param string $var * @return $this */ public function setNewIssueUri($var) { GPBUtil::checkString($var, True); $this->new_issue_uri = $var; return $this; } /** * Link to product home page. Example: * https://cloud.google.com/asset-inventory/docs/overview * * Generated from protobuf field string documentation_uri = 102; * @return string */ public function getDocumentationUri() { return $this->documentation_uri; } /** * Link to product home page. Example: * https://cloud.google.com/asset-inventory/docs/overview * * Generated from protobuf field string documentation_uri = 102; * @param string $var * @return $this */ public function setDocumentationUri($var) { GPBUtil::checkString($var, True); $this->documentation_uri = $var; return $this; } /** * Used as a tracking tag when collecting data about the APIs developer * relations artifacts like docs, packages delivered to package managers, * etc. Example: "speech". * * Generated from protobuf field string api_short_name = 103; * @return string */ public function getApiShortName() { return $this->api_short_name; } /** * Used as a tracking tag when collecting data about the APIs developer * relations artifacts like docs, packages delivered to package managers, * etc. Example: "speech". * * Generated from protobuf field string api_short_name = 103; * @param string $var * @return $this */ public function setApiShortName($var) { GPBUtil::checkString($var, True); $this->api_short_name = $var; return $this; } /** * GitHub label to apply to issues and pull requests opened for this API. * * Generated from protobuf field string github_label = 104; * @return string */ public function getGithubLabel() { return $this->github_label; } /** * GitHub label to apply to issues and pull requests opened for this API. * * Generated from protobuf field string github_label = 104; * @param string $var * @return $this */ public function setGithubLabel($var) { GPBUtil::checkString($var, True); $this->github_label = $var; return $this; } /** * GitHub teams to be added to CODEOWNERS in the directory in GitHub * containing source code for the client libraries for this API. * * Generated from protobuf field repeated string codeowner_github_teams = 105; * @return \Google\Protobuf\Internal\RepeatedField */ public function getCodeownerGithubTeams() { return $this->codeowner_github_teams; } /** * GitHub teams to be added to CODEOWNERS in the directory in GitHub * containing source code for the client libraries for this API. * * Generated from protobuf field repeated string codeowner_github_teams = 105; * @param array|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setCodeownerGithubTeams($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->codeowner_github_teams = $arr; return $this; } /** * A prefix used in sample code when demarking regions to be included in * documentation. * * Generated from protobuf field string doc_tag_prefix = 106; * @return string */ public function getDocTagPrefix() { return $this->doc_tag_prefix; } /** * A prefix used in sample code when demarking regions to be included in * documentation. * * Generated from protobuf field string doc_tag_prefix = 106; * @param string $var * @return $this */ public function setDocTagPrefix($var) { GPBUtil::checkString($var, True); $this->doc_tag_prefix = $var; return $this; } /** * For whom the client library is being published. * * Generated from protobuf field .google.api.ClientLibraryOrganization organization = 107; * @return int */ public function getOrganization() { return $this->organization; } /** * For whom the client library is being published. * * Generated from protobuf field .google.api.ClientLibraryOrganization organization = 107; * @param int $var * @return $this */ public function setOrganization($var) { GPBUtil::checkEnum($var, \Google\Api\ClientLibraryOrganization::class); $this->organization = $var; return $this; } /** * Client library settings. If the same version string appears multiple * times in this list, then the last one wins. Settings from earlier * settings with the same version string are discarded. * * Generated from protobuf field repeated .google.api.ClientLibrarySettings library_settings = 109; * @return \Google\Protobuf\Internal\RepeatedField */ public function getLibrarySettings() { return $this->library_settings; } /** * Client library settings. If the same version string appears multiple * times in this list, then the last one wins. Settings from earlier * settings with the same version string are discarded. * * Generated from protobuf field repeated .google.api.ClientLibrarySettings library_settings = 109; * @param array<\Google\Api\ClientLibrarySettings>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setLibrarySettings($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Api\ClientLibrarySettings::class); $this->library_settings = $arr; return $this; } /** * Optional link to proto reference documentation. Example: * https://cloud.google.com/pubsub/lite/docs/reference/rpc * * Generated from protobuf field string proto_reference_documentation_uri = 110; * @return string */ public function getProtoReferenceDocumentationUri() { return $this->proto_reference_documentation_uri; } /** * Optional link to proto reference documentation. Example: * https://cloud.google.com/pubsub/lite/docs/reference/rpc * * Generated from protobuf field string proto_reference_documentation_uri = 110; * @param string $var * @return $this */ public function setProtoReferenceDocumentationUri($var) { GPBUtil::checkString($var, True); $this->proto_reference_documentation_uri = $var; return $this; } /** * Optional link to REST reference documentation. Example: * https://cloud.google.com/pubsub/lite/docs/reference/rest * * Generated from protobuf field string rest_reference_documentation_uri = 111; * @return string */ public function getRestReferenceDocumentationUri() { return $this->rest_reference_documentation_uri; } /** * Optional link to REST reference documentation. Example: * https://cloud.google.com/pubsub/lite/docs/reference/rest * * Generated from protobuf field string rest_reference_documentation_uri = 111; * @param string $var * @return $this */ public function setRestReferenceDocumentationUri($var) { GPBUtil::checkString($var, True); $this->rest_reference_documentation_uri = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/PythonSettings/ExperimentalFeatures.php ================================================ google.api.PythonSettings.ExperimentalFeatures */ class ExperimentalFeatures extends \Google\Protobuf\Internal\Message { /** * Enables generation of asynchronous REST clients if `rest` transport is * enabled. By default, asynchronous REST clients will not be generated. * This feature will be enabled by default 1 month after launching the * feature in preview packages. * * Generated from protobuf field bool rest_async_io_enabled = 1; */ protected $rest_async_io_enabled = false; /** * Enables generation of protobuf code using new types that are more * Pythonic which are included in `protobuf>=5.29.x`. This feature will be * enabled by default 1 month after launching the feature in preview * packages. * * Generated from protobuf field bool protobuf_pythonic_types_enabled = 2; */ protected $protobuf_pythonic_types_enabled = false; /** * Disables generation of an unversioned Python package for this client * library. This means that the module names will need to be versioned in * import statements. For example `import google.cloud.library_v2` instead * of `import google.cloud.library`. * * Generated from protobuf field bool unversioned_package_disabled = 3; */ protected $unversioned_package_disabled = false; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type bool $rest_async_io_enabled * Enables generation of asynchronous REST clients if `rest` transport is * enabled. By default, asynchronous REST clients will not be generated. * This feature will be enabled by default 1 month after launching the * feature in preview packages. * @type bool $protobuf_pythonic_types_enabled * Enables generation of protobuf code using new types that are more * Pythonic which are included in `protobuf>=5.29.x`. This feature will be * enabled by default 1 month after launching the feature in preview * packages. * @type bool $unversioned_package_disabled * Disables generation of an unversioned Python package for this client * library. This means that the module names will need to be versioned in * import statements. For example `import google.cloud.library_v2` instead * of `import google.cloud.library`. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Client::initOnce(); parent::__construct($data); } /** * Enables generation of asynchronous REST clients if `rest` transport is * enabled. By default, asynchronous REST clients will not be generated. * This feature will be enabled by default 1 month after launching the * feature in preview packages. * * Generated from protobuf field bool rest_async_io_enabled = 1; * @return bool */ public function getRestAsyncIoEnabled() { return $this->rest_async_io_enabled; } /** * Enables generation of asynchronous REST clients if `rest` transport is * enabled. By default, asynchronous REST clients will not be generated. * This feature will be enabled by default 1 month after launching the * feature in preview packages. * * Generated from protobuf field bool rest_async_io_enabled = 1; * @param bool $var * @return $this */ public function setRestAsyncIoEnabled($var) { GPBUtil::checkBool($var); $this->rest_async_io_enabled = $var; return $this; } /** * Enables generation of protobuf code using new types that are more * Pythonic which are included in `protobuf>=5.29.x`. This feature will be * enabled by default 1 month after launching the feature in preview * packages. * * Generated from protobuf field bool protobuf_pythonic_types_enabled = 2; * @return bool */ public function getProtobufPythonicTypesEnabled() { return $this->protobuf_pythonic_types_enabled; } /** * Enables generation of protobuf code using new types that are more * Pythonic which are included in `protobuf>=5.29.x`. This feature will be * enabled by default 1 month after launching the feature in preview * packages. * * Generated from protobuf field bool protobuf_pythonic_types_enabled = 2; * @param bool $var * @return $this */ public function setProtobufPythonicTypesEnabled($var) { GPBUtil::checkBool($var); $this->protobuf_pythonic_types_enabled = $var; return $this; } /** * Disables generation of an unversioned Python package for this client * library. This means that the module names will need to be versioned in * import statements. For example `import google.cloud.library_v2` instead * of `import google.cloud.library`. * * Generated from protobuf field bool unversioned_package_disabled = 3; * @return bool */ public function getUnversionedPackageDisabled() { return $this->unversioned_package_disabled; } /** * Disables generation of an unversioned Python package for this client * library. This means that the module names will need to be versioned in * import statements. For example `import google.cloud.library_v2` instead * of `import google.cloud.library`. * * Generated from protobuf field bool unversioned_package_disabled = 3; * @param bool $var * @return $this */ public function setUnversionedPackageDisabled($var) { GPBUtil::checkBool($var); $this->unversioned_package_disabled = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/PythonSettings.php ================================================ google.api.PythonSettings */ class PythonSettings extends \Google\Protobuf\Internal\Message { /** * Some settings. * * Generated from protobuf field .google.api.CommonLanguageSettings common = 1; */ protected $common = null; /** * Experimental features to be included during client library generation. * * Generated from protobuf field .google.api.PythonSettings.ExperimentalFeatures experimental_features = 2; */ protected $experimental_features = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type \Google\Api\CommonLanguageSettings $common * Some settings. * @type \Google\Api\PythonSettings\ExperimentalFeatures $experimental_features * Experimental features to be included during client library generation. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Client::initOnce(); parent::__construct($data); } /** * Some settings. * * Generated from protobuf field .google.api.CommonLanguageSettings common = 1; * @return \Google\Api\CommonLanguageSettings|null */ public function getCommon() { return $this->common; } public function hasCommon() { return isset($this->common); } public function clearCommon() { unset($this->common); } /** * Some settings. * * Generated from protobuf field .google.api.CommonLanguageSettings common = 1; * @param \Google\Api\CommonLanguageSettings $var * @return $this */ public function setCommon($var) { GPBUtil::checkMessage($var, \Google\Api\CommonLanguageSettings::class); $this->common = $var; return $this; } /** * Experimental features to be included during client library generation. * * Generated from protobuf field .google.api.PythonSettings.ExperimentalFeatures experimental_features = 2; * @return \Google\Api\PythonSettings\ExperimentalFeatures|null */ public function getExperimentalFeatures() { return $this->experimental_features; } public function hasExperimentalFeatures() { return isset($this->experimental_features); } public function clearExperimentalFeatures() { unset($this->experimental_features); } /** * Experimental features to be included during client library generation. * * Generated from protobuf field .google.api.PythonSettings.ExperimentalFeatures experimental_features = 2; * @param \Google\Api\PythonSettings\ExperimentalFeatures $var * @return $this */ public function setExperimentalFeatures($var) { GPBUtil::checkMessage($var, \Google\Api\PythonSettings\ExperimentalFeatures::class); $this->experimental_features = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/Quota.php ================================================ google.api.Quota */ class Quota extends \Google\Protobuf\Internal\Message { /** * List of QuotaLimit definitions for the service. * * Generated from protobuf field repeated .google.api.QuotaLimit limits = 3; */ private $limits; /** * List of MetricRule definitions, each one mapping a selected method to one * or more metrics. * * Generated from protobuf field repeated .google.api.MetricRule metric_rules = 4; */ private $metric_rules; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type array<\Google\Api\QuotaLimit>|\Google\Protobuf\Internal\RepeatedField $limits * List of QuotaLimit definitions for the service. * @type array<\Google\Api\MetricRule>|\Google\Protobuf\Internal\RepeatedField $metric_rules * List of MetricRule definitions, each one mapping a selected method to one * or more metrics. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Quota::initOnce(); parent::__construct($data); } /** * List of QuotaLimit definitions for the service. * * Generated from protobuf field repeated .google.api.QuotaLimit limits = 3; * @return \Google\Protobuf\Internal\RepeatedField */ public function getLimits() { return $this->limits; } /** * List of QuotaLimit definitions for the service. * * Generated from protobuf field repeated .google.api.QuotaLimit limits = 3; * @param array<\Google\Api\QuotaLimit>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setLimits($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Api\QuotaLimit::class); $this->limits = $arr; return $this; } /** * List of MetricRule definitions, each one mapping a selected method to one * or more metrics. * * Generated from protobuf field repeated .google.api.MetricRule metric_rules = 4; * @return \Google\Protobuf\Internal\RepeatedField */ public function getMetricRules() { return $this->metric_rules; } /** * List of MetricRule definitions, each one mapping a selected method to one * or more metrics. * * Generated from protobuf field repeated .google.api.MetricRule metric_rules = 4; * @param array<\Google\Api\MetricRule>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setMetricRules($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Api\MetricRule::class); $this->metric_rules = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/QuotaLimit.php ================================================ google.api.QuotaLimit */ class QuotaLimit extends \Google\Protobuf\Internal\Message { /** * Name of the quota limit. * The name must be provided, and it must be unique within the service. The * name can only include alphanumeric characters as well as '-'. * The maximum length of the limit name is 64 characters. * * Generated from protobuf field string name = 6; */ protected $name = ''; /** * Optional. User-visible, extended description for this quota limit. * Should be used only when more context is needed to understand this limit * than provided by the limit's display name (see: `display_name`). * * Generated from protobuf field string description = 2; */ protected $description = ''; /** * Default number of tokens that can be consumed during the specified * duration. This is the number of tokens assigned when a client * application developer activates the service for his/her project. * Specifying a value of 0 will block all requests. This can be used if you * are provisioning quota to selected consumers and blocking others. * Similarly, a value of -1 will indicate an unlimited quota. No other * negative values are allowed. * Used by group-based quotas only. * * Generated from protobuf field int64 default_limit = 3; */ protected $default_limit = 0; /** * Maximum number of tokens that can be consumed during the specified * duration. Client application developers can override the default limit up * to this maximum. If specified, this value cannot be set to a value less * than the default limit. If not specified, it is set to the default limit. * To allow clients to apply overrides with no upper bound, set this to -1, * indicating unlimited maximum quota. * Used by group-based quotas only. * * Generated from protobuf field int64 max_limit = 4; */ protected $max_limit = 0; /** * Free tier value displayed in the Developers Console for this limit. * The free tier is the number of tokens that will be subtracted from the * billed amount when billing is enabled. * This field can only be set on a limit with duration "1d", in a billable * group; it is invalid on any other limit. If this field is not set, it * defaults to 0, indicating that there is no free tier for this service. * Used by group-based quotas only. * * Generated from protobuf field int64 free_tier = 7; */ protected $free_tier = 0; /** * Duration of this limit in textual notation. Must be "100s" or "1d". * Used by group-based quotas only. * * Generated from protobuf field string duration = 5; */ protected $duration = ''; /** * The name of the metric this quota limit applies to. The quota limits with * the same metric will be checked together during runtime. The metric must be * defined within the service config. * * Generated from protobuf field string metric = 8; */ protected $metric = ''; /** * Specify the unit of the quota limit. It uses the same syntax as * [MetricDescriptor.unit][google.api.MetricDescriptor.unit]. The supported * unit kinds are determined by the quota backend system. * Here are some examples: * * "1/min/{project}" for quota per minute per project. * Note: the order of unit components is insignificant. * The "1" at the beginning is required to follow the metric unit syntax. * * Generated from protobuf field string unit = 9; */ protected $unit = ''; /** * Tiered limit values. You must specify this as a key:value pair, with an * integer value that is the maximum number of requests allowed for the * specified unit. Currently only STANDARD is supported. * * Generated from protobuf field map values = 10; */ private $values; /** * User-visible display name for this limit. * Optional. If not set, the UI will provide a default display name based on * the quota configuration. This field can be used to override the default * display name generated from the configuration. * * Generated from protobuf field string display_name = 12; */ protected $display_name = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $name * Name of the quota limit. * The name must be provided, and it must be unique within the service. The * name can only include alphanumeric characters as well as '-'. * The maximum length of the limit name is 64 characters. * @type string $description * Optional. User-visible, extended description for this quota limit. * Should be used only when more context is needed to understand this limit * than provided by the limit's display name (see: `display_name`). * @type int|string $default_limit * Default number of tokens that can be consumed during the specified * duration. This is the number of tokens assigned when a client * application developer activates the service for his/her project. * Specifying a value of 0 will block all requests. This can be used if you * are provisioning quota to selected consumers and blocking others. * Similarly, a value of -1 will indicate an unlimited quota. No other * negative values are allowed. * Used by group-based quotas only. * @type int|string $max_limit * Maximum number of tokens that can be consumed during the specified * duration. Client application developers can override the default limit up * to this maximum. If specified, this value cannot be set to a value less * than the default limit. If not specified, it is set to the default limit. * To allow clients to apply overrides with no upper bound, set this to -1, * indicating unlimited maximum quota. * Used by group-based quotas only. * @type int|string $free_tier * Free tier value displayed in the Developers Console for this limit. * The free tier is the number of tokens that will be subtracted from the * billed amount when billing is enabled. * This field can only be set on a limit with duration "1d", in a billable * group; it is invalid on any other limit. If this field is not set, it * defaults to 0, indicating that there is no free tier for this service. * Used by group-based quotas only. * @type string $duration * Duration of this limit in textual notation. Must be "100s" or "1d". * Used by group-based quotas only. * @type string $metric * The name of the metric this quota limit applies to. The quota limits with * the same metric will be checked together during runtime. The metric must be * defined within the service config. * @type string $unit * Specify the unit of the quota limit. It uses the same syntax as * [MetricDescriptor.unit][google.api.MetricDescriptor.unit]. The supported * unit kinds are determined by the quota backend system. * Here are some examples: * * "1/min/{project}" for quota per minute per project. * Note: the order of unit components is insignificant. * The "1" at the beginning is required to follow the metric unit syntax. * @type array|\Google\Protobuf\Internal\MapField $values * Tiered limit values. You must specify this as a key:value pair, with an * integer value that is the maximum number of requests allowed for the * specified unit. Currently only STANDARD is supported. * @type string $display_name * User-visible display name for this limit. * Optional. If not set, the UI will provide a default display name based on * the quota configuration. This field can be used to override the default * display name generated from the configuration. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Quota::initOnce(); parent::__construct($data); } /** * Name of the quota limit. * The name must be provided, and it must be unique within the service. The * name can only include alphanumeric characters as well as '-'. * The maximum length of the limit name is 64 characters. * * Generated from protobuf field string name = 6; * @return string */ public function getName() { return $this->name; } /** * Name of the quota limit. * The name must be provided, and it must be unique within the service. The * name can only include alphanumeric characters as well as '-'. * The maximum length of the limit name is 64 characters. * * Generated from protobuf field string name = 6; * @param string $var * @return $this */ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; return $this; } /** * Optional. User-visible, extended description for this quota limit. * Should be used only when more context is needed to understand this limit * than provided by the limit's display name (see: `display_name`). * * Generated from protobuf field string description = 2; * @return string */ public function getDescription() { return $this->description; } /** * Optional. User-visible, extended description for this quota limit. * Should be used only when more context is needed to understand this limit * than provided by the limit's display name (see: `display_name`). * * Generated from protobuf field string description = 2; * @param string $var * @return $this */ public function setDescription($var) { GPBUtil::checkString($var, True); $this->description = $var; return $this; } /** * Default number of tokens that can be consumed during the specified * duration. This is the number of tokens assigned when a client * application developer activates the service for his/her project. * Specifying a value of 0 will block all requests. This can be used if you * are provisioning quota to selected consumers and blocking others. * Similarly, a value of -1 will indicate an unlimited quota. No other * negative values are allowed. * Used by group-based quotas only. * * Generated from protobuf field int64 default_limit = 3; * @return int|string */ public function getDefaultLimit() { return $this->default_limit; } /** * Default number of tokens that can be consumed during the specified * duration. This is the number of tokens assigned when a client * application developer activates the service for his/her project. * Specifying a value of 0 will block all requests. This can be used if you * are provisioning quota to selected consumers and blocking others. * Similarly, a value of -1 will indicate an unlimited quota. No other * negative values are allowed. * Used by group-based quotas only. * * Generated from protobuf field int64 default_limit = 3; * @param int|string $var * @return $this */ public function setDefaultLimit($var) { GPBUtil::checkInt64($var); $this->default_limit = $var; return $this; } /** * Maximum number of tokens that can be consumed during the specified * duration. Client application developers can override the default limit up * to this maximum. If specified, this value cannot be set to a value less * than the default limit. If not specified, it is set to the default limit. * To allow clients to apply overrides with no upper bound, set this to -1, * indicating unlimited maximum quota. * Used by group-based quotas only. * * Generated from protobuf field int64 max_limit = 4; * @return int|string */ public function getMaxLimit() { return $this->max_limit; } /** * Maximum number of tokens that can be consumed during the specified * duration. Client application developers can override the default limit up * to this maximum. If specified, this value cannot be set to a value less * than the default limit. If not specified, it is set to the default limit. * To allow clients to apply overrides with no upper bound, set this to -1, * indicating unlimited maximum quota. * Used by group-based quotas only. * * Generated from protobuf field int64 max_limit = 4; * @param int|string $var * @return $this */ public function setMaxLimit($var) { GPBUtil::checkInt64($var); $this->max_limit = $var; return $this; } /** * Free tier value displayed in the Developers Console for this limit. * The free tier is the number of tokens that will be subtracted from the * billed amount when billing is enabled. * This field can only be set on a limit with duration "1d", in a billable * group; it is invalid on any other limit. If this field is not set, it * defaults to 0, indicating that there is no free tier for this service. * Used by group-based quotas only. * * Generated from protobuf field int64 free_tier = 7; * @return int|string */ public function getFreeTier() { return $this->free_tier; } /** * Free tier value displayed in the Developers Console for this limit. * The free tier is the number of tokens that will be subtracted from the * billed amount when billing is enabled. * This field can only be set on a limit with duration "1d", in a billable * group; it is invalid on any other limit. If this field is not set, it * defaults to 0, indicating that there is no free tier for this service. * Used by group-based quotas only. * * Generated from protobuf field int64 free_tier = 7; * @param int|string $var * @return $this */ public function setFreeTier($var) { GPBUtil::checkInt64($var); $this->free_tier = $var; return $this; } /** * Duration of this limit in textual notation. Must be "100s" or "1d". * Used by group-based quotas only. * * Generated from protobuf field string duration = 5; * @return string */ public function getDuration() { return $this->duration; } /** * Duration of this limit in textual notation. Must be "100s" or "1d". * Used by group-based quotas only. * * Generated from protobuf field string duration = 5; * @param string $var * @return $this */ public function setDuration($var) { GPBUtil::checkString($var, True); $this->duration = $var; return $this; } /** * The name of the metric this quota limit applies to. The quota limits with * the same metric will be checked together during runtime. The metric must be * defined within the service config. * * Generated from protobuf field string metric = 8; * @return string */ public function getMetric() { return $this->metric; } /** * The name of the metric this quota limit applies to. The quota limits with * the same metric will be checked together during runtime. The metric must be * defined within the service config. * * Generated from protobuf field string metric = 8; * @param string $var * @return $this */ public function setMetric($var) { GPBUtil::checkString($var, True); $this->metric = $var; return $this; } /** * Specify the unit of the quota limit. It uses the same syntax as * [MetricDescriptor.unit][google.api.MetricDescriptor.unit]. The supported * unit kinds are determined by the quota backend system. * Here are some examples: * * "1/min/{project}" for quota per minute per project. * Note: the order of unit components is insignificant. * The "1" at the beginning is required to follow the metric unit syntax. * * Generated from protobuf field string unit = 9; * @return string */ public function getUnit() { return $this->unit; } /** * Specify the unit of the quota limit. It uses the same syntax as * [MetricDescriptor.unit][google.api.MetricDescriptor.unit]. The supported * unit kinds are determined by the quota backend system. * Here are some examples: * * "1/min/{project}" for quota per minute per project. * Note: the order of unit components is insignificant. * The "1" at the beginning is required to follow the metric unit syntax. * * Generated from protobuf field string unit = 9; * @param string $var * @return $this */ public function setUnit($var) { GPBUtil::checkString($var, True); $this->unit = $var; return $this; } /** * Tiered limit values. You must specify this as a key:value pair, with an * integer value that is the maximum number of requests allowed for the * specified unit. Currently only STANDARD is supported. * * Generated from protobuf field map values = 10; * @return \Google\Protobuf\Internal\MapField */ public function getValues() { return $this->values; } /** * Tiered limit values. You must specify this as a key:value pair, with an * integer value that is the maximum number of requests allowed for the * specified unit. Currently only STANDARD is supported. * * Generated from protobuf field map values = 10; * @param array|\Google\Protobuf\Internal\MapField $var * @return $this */ public function setValues($var) { $arr = GPBUtil::checkMapField($var, \Google\Protobuf\Internal\GPBType::STRING, \Google\Protobuf\Internal\GPBType::INT64); $this->values = $arr; return $this; } /** * User-visible display name for this limit. * Optional. If not set, the UI will provide a default display name based on * the quota configuration. This field can be used to override the default * display name generated from the configuration. * * Generated from protobuf field string display_name = 12; * @return string */ public function getDisplayName() { return $this->display_name; } /** * User-visible display name for this limit. * Optional. If not set, the UI will provide a default display name based on * the quota configuration. This field can be used to override the default * display name generated from the configuration. * * Generated from protobuf field string display_name = 12; * @param string $var * @return $this */ public function setDisplayName($var) { GPBUtil::checkString($var, True); $this->display_name = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/ResourceDescriptor/History.php ================================================ google.api.ResourceDescriptor.History */ class History { /** * The "unset" value. * * Generated from protobuf enum HISTORY_UNSPECIFIED = 0; */ const HISTORY_UNSPECIFIED = 0; /** * The resource originally had one pattern and launched as such, and * additional patterns were added later. * * Generated from protobuf enum ORIGINALLY_SINGLE_PATTERN = 1; */ const ORIGINALLY_SINGLE_PATTERN = 1; /** * The resource has one pattern, but the API owner expects to add more * later. (This is the inverse of ORIGINALLY_SINGLE_PATTERN, and prevents * that from being necessary once there are multiple patterns.) * * Generated from protobuf enum FUTURE_MULTI_PATTERN = 2; */ const FUTURE_MULTI_PATTERN = 2; private static $valueToName = [ self::HISTORY_UNSPECIFIED => 'HISTORY_UNSPECIFIED', self::ORIGINALLY_SINGLE_PATTERN => 'ORIGINALLY_SINGLE_PATTERN', self::FUTURE_MULTI_PATTERN => 'FUTURE_MULTI_PATTERN', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/ResourceDescriptor/Style.php ================================================ google.api.ResourceDescriptor.Style */ class Style { /** * The unspecified value. Do not use. * * Generated from protobuf enum STYLE_UNSPECIFIED = 0; */ const STYLE_UNSPECIFIED = 0; /** * This resource is intended to be "declarative-friendly". * Declarative-friendly resources must be more strictly consistent, and * setting this to true communicates to tools that this resource should * adhere to declarative-friendly expectations. * Note: This is used by the API linter (linter.aip.dev) to enable * additional checks. * * Generated from protobuf enum DECLARATIVE_FRIENDLY = 1; */ const DECLARATIVE_FRIENDLY = 1; private static $valueToName = [ self::STYLE_UNSPECIFIED => 'STYLE_UNSPECIFIED', self::DECLARATIVE_FRIENDLY => 'DECLARATIVE_FRIENDLY', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/ResourceDescriptor.php ================================================ google.api.ResourceDescriptor */ class ResourceDescriptor extends \Google\Protobuf\Internal\Message { /** * The resource type. It must be in the format of * {service_name}/{resource_type_kind}. The `resource_type_kind` must be * singular and must not include version numbers. * Example: `storage.googleapis.com/Bucket` * The value of the resource_type_kind must follow the regular expression * /[A-Za-z][a-zA-Z0-9]+/. It should start with an upper case character and * should use PascalCase (UpperCamelCase). The maximum number of * characters allowed for the `resource_type_kind` is 100. * * Generated from protobuf field string type = 1; */ protected $type = ''; /** * Optional. The relative resource name pattern associated with this resource * type. The DNS prefix of the full resource name shouldn't be specified here. * The path pattern must follow the syntax, which aligns with HTTP binding * syntax: * Template = Segment { "/" Segment } ; * Segment = LITERAL | Variable ; * Variable = "{" LITERAL "}" ; * Examples: * - "projects/{project}/topics/{topic}" * - "projects/{project}/knowledgeBases/{knowledge_base}" * The components in braces correspond to the IDs for each resource in the * hierarchy. It is expected that, if multiple patterns are provided, * the same component name (e.g. "project") refers to IDs of the same * type of resource. * * Generated from protobuf field repeated string pattern = 2; */ private $pattern; /** * Optional. The field on the resource that designates the resource name * field. If omitted, this is assumed to be "name". * * Generated from protobuf field string name_field = 3; */ protected $name_field = ''; /** * Optional. The historical or future-looking state of the resource pattern. * Example: * // The InspectTemplate message originally only supported resource * // names with organization, and project was added later. * message InspectTemplate { * option (google.api.resource) = { * type: "dlp.googleapis.com/InspectTemplate" * pattern: * "organizations/{organization}/inspectTemplates/{inspect_template}" * pattern: "projects/{project}/inspectTemplates/{inspect_template}" * history: ORIGINALLY_SINGLE_PATTERN * }; * } * * Generated from protobuf field .google.api.ResourceDescriptor.History history = 4; */ protected $history = 0; /** * The plural name used in the resource name and permission names, such as * 'projects' for the resource name of 'projects/{project}' and the permission * name of 'cloudresourcemanager.googleapis.com/projects.get'. One exception * to this is for Nested Collections that have stuttering names, as defined * in [AIP-122](https://google.aip.dev/122#nested-collections), where the * collection ID in the resource name pattern does not necessarily directly * match the `plural` value. * It is the same concept of the `plural` field in k8s CRD spec * https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/ * Note: The plural form is required even for singleton resources. See * https://aip.dev/156 * * Generated from protobuf field string plural = 5; */ protected $plural = ''; /** * The same concept of the `singular` field in k8s CRD spec * https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/ * Such as "project" for the `resourcemanager.googleapis.com/Project` type. * * Generated from protobuf field string singular = 6; */ protected $singular = ''; /** * Style flag(s) for this resource. * These indicate that a resource is expected to conform to a given * style. See the specific style flags for additional information. * * Generated from protobuf field repeated .google.api.ResourceDescriptor.Style style = 10; */ private $style; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $type * The resource type. It must be in the format of * {service_name}/{resource_type_kind}. The `resource_type_kind` must be * singular and must not include version numbers. * Example: `storage.googleapis.com/Bucket` * The value of the resource_type_kind must follow the regular expression * /[A-Za-z][a-zA-Z0-9]+/. It should start with an upper case character and * should use PascalCase (UpperCamelCase). The maximum number of * characters allowed for the `resource_type_kind` is 100. * @type array|\Google\Protobuf\Internal\RepeatedField $pattern * Optional. The relative resource name pattern associated with this resource * type. The DNS prefix of the full resource name shouldn't be specified here. * The path pattern must follow the syntax, which aligns with HTTP binding * syntax: * Template = Segment { "/" Segment } ; * Segment = LITERAL | Variable ; * Variable = "{" LITERAL "}" ; * Examples: * - "projects/{project}/topics/{topic}" * - "projects/{project}/knowledgeBases/{knowledge_base}" * The components in braces correspond to the IDs for each resource in the * hierarchy. It is expected that, if multiple patterns are provided, * the same component name (e.g. "project") refers to IDs of the same * type of resource. * @type string $name_field * Optional. The field on the resource that designates the resource name * field. If omitted, this is assumed to be "name". * @type int $history * Optional. The historical or future-looking state of the resource pattern. * Example: * // The InspectTemplate message originally only supported resource * // names with organization, and project was added later. * message InspectTemplate { * option (google.api.resource) = { * type: "dlp.googleapis.com/InspectTemplate" * pattern: * "organizations/{organization}/inspectTemplates/{inspect_template}" * pattern: "projects/{project}/inspectTemplates/{inspect_template}" * history: ORIGINALLY_SINGLE_PATTERN * }; * } * @type string $plural * The plural name used in the resource name and permission names, such as * 'projects' for the resource name of 'projects/{project}' and the permission * name of 'cloudresourcemanager.googleapis.com/projects.get'. One exception * to this is for Nested Collections that have stuttering names, as defined * in [AIP-122](https://google.aip.dev/122#nested-collections), where the * collection ID in the resource name pattern does not necessarily directly * match the `plural` value. * It is the same concept of the `plural` field in k8s CRD spec * https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/ * Note: The plural form is required even for singleton resources. See * https://aip.dev/156 * @type string $singular * The same concept of the `singular` field in k8s CRD spec * https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/ * Such as "project" for the `resourcemanager.googleapis.com/Project` type. * @type array|\Google\Protobuf\Internal\RepeatedField $style * Style flag(s) for this resource. * These indicate that a resource is expected to conform to a given * style. See the specific style flags for additional information. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Resource::initOnce(); parent::__construct($data); } /** * The resource type. It must be in the format of * {service_name}/{resource_type_kind}. The `resource_type_kind` must be * singular and must not include version numbers. * Example: `storage.googleapis.com/Bucket` * The value of the resource_type_kind must follow the regular expression * /[A-Za-z][a-zA-Z0-9]+/. It should start with an upper case character and * should use PascalCase (UpperCamelCase). The maximum number of * characters allowed for the `resource_type_kind` is 100. * * Generated from protobuf field string type = 1; * @return string */ public function getType() { return $this->type; } /** * The resource type. It must be in the format of * {service_name}/{resource_type_kind}. The `resource_type_kind` must be * singular and must not include version numbers. * Example: `storage.googleapis.com/Bucket` * The value of the resource_type_kind must follow the regular expression * /[A-Za-z][a-zA-Z0-9]+/. It should start with an upper case character and * should use PascalCase (UpperCamelCase). The maximum number of * characters allowed for the `resource_type_kind` is 100. * * Generated from protobuf field string type = 1; * @param string $var * @return $this */ public function setType($var) { GPBUtil::checkString($var, True); $this->type = $var; return $this; } /** * Optional. The relative resource name pattern associated with this resource * type. The DNS prefix of the full resource name shouldn't be specified here. * The path pattern must follow the syntax, which aligns with HTTP binding * syntax: * Template = Segment { "/" Segment } ; * Segment = LITERAL | Variable ; * Variable = "{" LITERAL "}" ; * Examples: * - "projects/{project}/topics/{topic}" * - "projects/{project}/knowledgeBases/{knowledge_base}" * The components in braces correspond to the IDs for each resource in the * hierarchy. It is expected that, if multiple patterns are provided, * the same component name (e.g. "project") refers to IDs of the same * type of resource. * * Generated from protobuf field repeated string pattern = 2; * @return \Google\Protobuf\Internal\RepeatedField */ public function getPattern() { return $this->pattern; } /** * Optional. The relative resource name pattern associated with this resource * type. The DNS prefix of the full resource name shouldn't be specified here. * The path pattern must follow the syntax, which aligns with HTTP binding * syntax: * Template = Segment { "/" Segment } ; * Segment = LITERAL | Variable ; * Variable = "{" LITERAL "}" ; * Examples: * - "projects/{project}/topics/{topic}" * - "projects/{project}/knowledgeBases/{knowledge_base}" * The components in braces correspond to the IDs for each resource in the * hierarchy. It is expected that, if multiple patterns are provided, * the same component name (e.g. "project") refers to IDs of the same * type of resource. * * Generated from protobuf field repeated string pattern = 2; * @param array|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setPattern($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->pattern = $arr; return $this; } /** * Optional. The field on the resource that designates the resource name * field. If omitted, this is assumed to be "name". * * Generated from protobuf field string name_field = 3; * @return string */ public function getNameField() { return $this->name_field; } /** * Optional. The field on the resource that designates the resource name * field. If omitted, this is assumed to be "name". * * Generated from protobuf field string name_field = 3; * @param string $var * @return $this */ public function setNameField($var) { GPBUtil::checkString($var, True); $this->name_field = $var; return $this; } /** * Optional. The historical or future-looking state of the resource pattern. * Example: * // The InspectTemplate message originally only supported resource * // names with organization, and project was added later. * message InspectTemplate { * option (google.api.resource) = { * type: "dlp.googleapis.com/InspectTemplate" * pattern: * "organizations/{organization}/inspectTemplates/{inspect_template}" * pattern: "projects/{project}/inspectTemplates/{inspect_template}" * history: ORIGINALLY_SINGLE_PATTERN * }; * } * * Generated from protobuf field .google.api.ResourceDescriptor.History history = 4; * @return int */ public function getHistory() { return $this->history; } /** * Optional. The historical or future-looking state of the resource pattern. * Example: * // The InspectTemplate message originally only supported resource * // names with organization, and project was added later. * message InspectTemplate { * option (google.api.resource) = { * type: "dlp.googleapis.com/InspectTemplate" * pattern: * "organizations/{organization}/inspectTemplates/{inspect_template}" * pattern: "projects/{project}/inspectTemplates/{inspect_template}" * history: ORIGINALLY_SINGLE_PATTERN * }; * } * * Generated from protobuf field .google.api.ResourceDescriptor.History history = 4; * @param int $var * @return $this */ public function setHistory($var) { GPBUtil::checkEnum($var, \Google\Api\ResourceDescriptor\History::class); $this->history = $var; return $this; } /** * The plural name used in the resource name and permission names, such as * 'projects' for the resource name of 'projects/{project}' and the permission * name of 'cloudresourcemanager.googleapis.com/projects.get'. One exception * to this is for Nested Collections that have stuttering names, as defined * in [AIP-122](https://google.aip.dev/122#nested-collections), where the * collection ID in the resource name pattern does not necessarily directly * match the `plural` value. * It is the same concept of the `plural` field in k8s CRD spec * https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/ * Note: The plural form is required even for singleton resources. See * https://aip.dev/156 * * Generated from protobuf field string plural = 5; * @return string */ public function getPlural() { return $this->plural; } /** * The plural name used in the resource name and permission names, such as * 'projects' for the resource name of 'projects/{project}' and the permission * name of 'cloudresourcemanager.googleapis.com/projects.get'. One exception * to this is for Nested Collections that have stuttering names, as defined * in [AIP-122](https://google.aip.dev/122#nested-collections), where the * collection ID in the resource name pattern does not necessarily directly * match the `plural` value. * It is the same concept of the `plural` field in k8s CRD spec * https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/ * Note: The plural form is required even for singleton resources. See * https://aip.dev/156 * * Generated from protobuf field string plural = 5; * @param string $var * @return $this */ public function setPlural($var) { GPBUtil::checkString($var, True); $this->plural = $var; return $this; } /** * The same concept of the `singular` field in k8s CRD spec * https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/ * Such as "project" for the `resourcemanager.googleapis.com/Project` type. * * Generated from protobuf field string singular = 6; * @return string */ public function getSingular() { return $this->singular; } /** * The same concept of the `singular` field in k8s CRD spec * https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/ * Such as "project" for the `resourcemanager.googleapis.com/Project` type. * * Generated from protobuf field string singular = 6; * @param string $var * @return $this */ public function setSingular($var) { GPBUtil::checkString($var, True); $this->singular = $var; return $this; } /** * Style flag(s) for this resource. * These indicate that a resource is expected to conform to a given * style. See the specific style flags for additional information. * * Generated from protobuf field repeated .google.api.ResourceDescriptor.Style style = 10; * @return \Google\Protobuf\Internal\RepeatedField */ public function getStyle() { return $this->style; } /** * Style flag(s) for this resource. * These indicate that a resource is expected to conform to a given * style. See the specific style flags for additional information. * * Generated from protobuf field repeated .google.api.ResourceDescriptor.Style style = 10; * @param array|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setStyle($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::ENUM, \Google\Api\ResourceDescriptor\Style::class); $this->style = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/ResourceReference.php ================================================ google.api.ResourceReference */ class ResourceReference extends \Google\Protobuf\Internal\Message { /** * The resource type that the annotated field references. * Example: * message Subscription { * string topic = 2 [(google.api.resource_reference) = { * type: "pubsub.googleapis.com/Topic" * }]; * } * Occasionally, a field may reference an arbitrary resource. In this case, * APIs use the special value * in their resource reference. * Example: * message GetIamPolicyRequest { * string resource = 2 [(google.api.resource_reference) = { * type: "*" * }]; * } * * Generated from protobuf field string type = 1; */ protected $type = ''; /** * The resource type of a child collection that the annotated field * references. This is useful for annotating the `parent` field that * doesn't have a fixed resource type. * Example: * message ListLogEntriesRequest { * string parent = 1 [(google.api.resource_reference) = { * child_type: "logging.googleapis.com/LogEntry" * }; * } * * Generated from protobuf field string child_type = 2; */ protected $child_type = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $type * The resource type that the annotated field references. * Example: * message Subscription { * string topic = 2 [(google.api.resource_reference) = { * type: "pubsub.googleapis.com/Topic" * }]; * } * Occasionally, a field may reference an arbitrary resource. In this case, * APIs use the special value * in their resource reference. * Example: * message GetIamPolicyRequest { * string resource = 2 [(google.api.resource_reference) = { * type: "*" * }]; * } * @type string $child_type * The resource type of a child collection that the annotated field * references. This is useful for annotating the `parent` field that * doesn't have a fixed resource type. * Example: * message ListLogEntriesRequest { * string parent = 1 [(google.api.resource_reference) = { * child_type: "logging.googleapis.com/LogEntry" * }; * } * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Resource::initOnce(); parent::__construct($data); } /** * The resource type that the annotated field references. * Example: * message Subscription { * string topic = 2 [(google.api.resource_reference) = { * type: "pubsub.googleapis.com/Topic" * }]; * } * Occasionally, a field may reference an arbitrary resource. In this case, * APIs use the special value * in their resource reference. * Example: * message GetIamPolicyRequest { * string resource = 2 [(google.api.resource_reference) = { * type: "*" * }]; * } * * Generated from protobuf field string type = 1; * @return string */ public function getType() { return $this->type; } /** * The resource type that the annotated field references. * Example: * message Subscription { * string topic = 2 [(google.api.resource_reference) = { * type: "pubsub.googleapis.com/Topic" * }]; * } * Occasionally, a field may reference an arbitrary resource. In this case, * APIs use the special value * in their resource reference. * Example: * message GetIamPolicyRequest { * string resource = 2 [(google.api.resource_reference) = { * type: "*" * }]; * } * * Generated from protobuf field string type = 1; * @param string $var * @return $this */ public function setType($var) { GPBUtil::checkString($var, True); $this->type = $var; return $this; } /** * The resource type of a child collection that the annotated field * references. This is useful for annotating the `parent` field that * doesn't have a fixed resource type. * Example: * message ListLogEntriesRequest { * string parent = 1 [(google.api.resource_reference) = { * child_type: "logging.googleapis.com/LogEntry" * }; * } * * Generated from protobuf field string child_type = 2; * @return string */ public function getChildType() { return $this->child_type; } /** * The resource type of a child collection that the annotated field * references. This is useful for annotating the `parent` field that * doesn't have a fixed resource type. * Example: * message ListLogEntriesRequest { * string parent = 1 [(google.api.resource_reference) = { * child_type: "logging.googleapis.com/LogEntry" * }; * } * * Generated from protobuf field string child_type = 2; * @param string $var * @return $this */ public function setChildType($var) { GPBUtil::checkString($var, True); $this->child_type = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/RoutingParameter.php ================================================ google.api.RoutingParameter */ class RoutingParameter extends \Google\Protobuf\Internal\Message { /** * A request field to extract the header key-value pair from. * * Generated from protobuf field string field = 1; */ protected $field = ''; /** * A pattern matching the key-value field. Optional. * If not specified, the whole field specified in the `field` field will be * taken as value, and its name used as key. If specified, it MUST contain * exactly one named segment (along with any number of unnamed segments) The * pattern will be matched over the field specified in the `field` field, then * if the match is successful: * - the name of the single named segment will be used as a header name, * - the match value of the segment will be used as a header value; * if the match is NOT successful, nothing will be sent. * Example: * -- This is a field in the request message * | that the header value will be extracted from. * | * | -- This is the key name in the * | | routing header. * V | * field: "table_name" v * path_template: "projects/*/{table_location=instances/*}/tables/*" * ^ ^ * | | * In the {} brackets is the pattern that -- | * specifies what to extract from the | * field as a value to be sent. | * | * The string in the field must match the whole pattern -- * before brackets, inside brackets, after brackets. * When looking at this specific example, we can see that: * - A key-value pair with the key `table_location` * and the value matching `instances/*` should be added * to the x-goog-request-params routing header. * - The value is extracted from the request message's `table_name` field * if it matches the full pattern specified: * `projects/*/instances/*/tables/*`. * **NB:** If the `path_template` field is not provided, the key name is * equal to the field name, and the whole field should be sent as a value. * This makes the pattern for the field and the value functionally equivalent * to `**`, and the configuration * { * field: "table_name" * } * is a functionally equivalent shorthand to: * { * field: "table_name" * path_template: "{table_name=**}" * } * See Example 1 for more details. * * Generated from protobuf field string path_template = 2; */ protected $path_template = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $field * A request field to extract the header key-value pair from. * @type string $path_template * A pattern matching the key-value field. Optional. * If not specified, the whole field specified in the `field` field will be * taken as value, and its name used as key. If specified, it MUST contain * exactly one named segment (along with any number of unnamed segments) The * pattern will be matched over the field specified in the `field` field, then * if the match is successful: * - the name of the single named segment will be used as a header name, * - the match value of the segment will be used as a header value; * if the match is NOT successful, nothing will be sent. * Example: * -- This is a field in the request message * | that the header value will be extracted from. * | * | -- This is the key name in the * | | routing header. * V | * field: "table_name" v * path_template: "projects/*/{table_location=instances/*}/tables/*" * ^ ^ * | | * In the {} brackets is the pattern that -- | * specifies what to extract from the | * field as a value to be sent. | * | * The string in the field must match the whole pattern -- * before brackets, inside brackets, after brackets. * When looking at this specific example, we can see that: * - A key-value pair with the key `table_location` * and the value matching `instances/*` should be added * to the x-goog-request-params routing header. * - The value is extracted from the request message's `table_name` field * if it matches the full pattern specified: * `projects/*/instances/*/tables/*`. * **NB:** If the `path_template` field is not provided, the key name is * equal to the field name, and the whole field should be sent as a value. * This makes the pattern for the field and the value functionally equivalent * to `**`, and the configuration * { * field: "table_name" * } * is a functionally equivalent shorthand to: * { * field: "table_name" * path_template: "{table_name=**}" * } * See Example 1 for more details. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Routing::initOnce(); parent::__construct($data); } /** * A request field to extract the header key-value pair from. * * Generated from protobuf field string field = 1; * @return string */ public function getField() { return $this->field; } /** * A request field to extract the header key-value pair from. * * Generated from protobuf field string field = 1; * @param string $var * @return $this */ public function setField($var) { GPBUtil::checkString($var, True); $this->field = $var; return $this; } /** * A pattern matching the key-value field. Optional. * If not specified, the whole field specified in the `field` field will be * taken as value, and its name used as key. If specified, it MUST contain * exactly one named segment (along with any number of unnamed segments) The * pattern will be matched over the field specified in the `field` field, then * if the match is successful: * - the name of the single named segment will be used as a header name, * - the match value of the segment will be used as a header value; * if the match is NOT successful, nothing will be sent. * Example: * -- This is a field in the request message * | that the header value will be extracted from. * | * | -- This is the key name in the * | | routing header. * V | * field: "table_name" v * path_template: "projects/*/{table_location=instances/*}/tables/*" * ^ ^ * | | * In the {} brackets is the pattern that -- | * specifies what to extract from the | * field as a value to be sent. | * | * The string in the field must match the whole pattern -- * before brackets, inside brackets, after brackets. * When looking at this specific example, we can see that: * - A key-value pair with the key `table_location` * and the value matching `instances/*` should be added * to the x-goog-request-params routing header. * - The value is extracted from the request message's `table_name` field * if it matches the full pattern specified: * `projects/*/instances/*/tables/*`. * **NB:** If the `path_template` field is not provided, the key name is * equal to the field name, and the whole field should be sent as a value. * This makes the pattern for the field and the value functionally equivalent * to `**`, and the configuration * { * field: "table_name" * } * is a functionally equivalent shorthand to: * { * field: "table_name" * path_template: "{table_name=**}" * } * See Example 1 for more details. * * Generated from protobuf field string path_template = 2; * @return string */ public function getPathTemplate() { return $this->path_template; } /** * A pattern matching the key-value field. Optional. * If not specified, the whole field specified in the `field` field will be * taken as value, and its name used as key. If specified, it MUST contain * exactly one named segment (along with any number of unnamed segments) The * pattern will be matched over the field specified in the `field` field, then * if the match is successful: * - the name of the single named segment will be used as a header name, * - the match value of the segment will be used as a header value; * if the match is NOT successful, nothing will be sent. * Example: * -- This is a field in the request message * | that the header value will be extracted from. * | * | -- This is the key name in the * | | routing header. * V | * field: "table_name" v * path_template: "projects/*/{table_location=instances/*}/tables/*" * ^ ^ * | | * In the {} brackets is the pattern that -- | * specifies what to extract from the | * field as a value to be sent. | * | * The string in the field must match the whole pattern -- * before brackets, inside brackets, after brackets. * When looking at this specific example, we can see that: * - A key-value pair with the key `table_location` * and the value matching `instances/*` should be added * to the x-goog-request-params routing header. * - The value is extracted from the request message's `table_name` field * if it matches the full pattern specified: * `projects/*/instances/*/tables/*`. * **NB:** If the `path_template` field is not provided, the key name is * equal to the field name, and the whole field should be sent as a value. * This makes the pattern for the field and the value functionally equivalent * to `**`, and the configuration * { * field: "table_name" * } * is a functionally equivalent shorthand to: * { * field: "table_name" * path_template: "{table_name=**}" * } * See Example 1 for more details. * * Generated from protobuf field string path_template = 2; * @param string $var * @return $this */ public function setPathTemplate($var) { GPBUtil::checkString($var, True); $this->path_template = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/RoutingRule.php ================================================ /tables/` * // - `projects//instances//tables/
` * // - `region//zones//tables/
` * string table_name = 1; * // This value specifies routing for replication. * // It can be in the following formats: * // - `profiles/` * // - a legacy `profile_id` that can be any string * string app_profile_id = 2; * } * Example message: * { * table_name: projects/proj_foo/instances/instance_bar/table/table_baz, * app_profile_id: profiles/prof_qux * } * The routing header consists of one or multiple key-value pairs. Every key * and value must be percent-encoded, and joined together in the format of * `key1=value1&key2=value2`. * The examples below skip the percent-encoding for readability. * Example 1 * Extracting a field from the request to put into the routing header * unchanged, with the key equal to the field name. * annotation: * option (google.api.routing) = { * // Take the `app_profile_id`. * routing_parameters { * field: "app_profile_id" * } * }; * result: * x-goog-request-params: app_profile_id=profiles/prof_qux * Example 2 * Extracting a field from the request to put into the routing header * unchanged, with the key different from the field name. * annotation: * option (google.api.routing) = { * // Take the `app_profile_id`, but name it `routing_id` in the header. * routing_parameters { * field: "app_profile_id" * path_template: "{routing_id=**}" * } * }; * result: * x-goog-request-params: routing_id=profiles/prof_qux * Example 3 * Extracting a field from the request to put into the routing * header, while matching a path template syntax on the field's value. * NB: it is more useful to send nothing than to send garbage for the purpose * of dynamic routing, since garbage pollutes cache. Thus the matching. * Sub-example 3a * The field matches the template. * annotation: * option (google.api.routing) = { * // Take the `table_name`, if it's well-formed (with project-based * // syntax). * routing_parameters { * field: "table_name" * path_template: "{table_name=projects/*/instances/*/**}" * } * }; * result: * x-goog-request-params: * table_name=projects/proj_foo/instances/instance_bar/table/table_baz * Sub-example 3b * The field does not match the template. * annotation: * option (google.api.routing) = { * // Take the `table_name`, if it's well-formed (with region-based * // syntax). * routing_parameters { * field: "table_name" * path_template: "{table_name=regions/*/zones/*/**}" * } * }; * result: * * Sub-example 3c * Multiple alternative conflictingly named path templates are * specified. The one that matches is used to construct the header. * annotation: * option (google.api.routing) = { * // Take the `table_name`, if it's well-formed, whether * // using the region- or projects-based syntax. * routing_parameters { * field: "table_name" * path_template: "{table_name=regions/*/zones/*/**}" * } * routing_parameters { * field: "table_name" * path_template: "{table_name=projects/*/instances/*/**}" * } * }; * result: * x-goog-request-params: * table_name=projects/proj_foo/instances/instance_bar/table/table_baz * Example 4 * Extracting a single routing header key-value pair by matching a * template syntax on (a part of) a single request field. * annotation: * option (google.api.routing) = { * // Take just the project id from the `table_name` field. * routing_parameters { * field: "table_name" * path_template: "{routing_id=projects/*}/**" * } * }; * result: * x-goog-request-params: routing_id=projects/proj_foo * Example 5 * Extracting a single routing header key-value pair by matching * several conflictingly named path templates on (parts of) a single request * field. The last template to match "wins" the conflict. * annotation: * option (google.api.routing) = { * // If the `table_name` does not have instances information, * // take just the project id for routing. * // Otherwise take project + instance. * routing_parameters { * field: "table_name" * path_template: "{routing_id=projects/*}/**" * } * routing_parameters { * field: "table_name" * path_template: "{routing_id=projects/*/instances/*}/**" * } * }; * result: * x-goog-request-params: * routing_id=projects/proj_foo/instances/instance_bar * Example 6 * Extracting multiple routing header key-value pairs by matching * several non-conflicting path templates on (parts of) a single request field. * Sub-example 6a * Make the templates strict, so that if the `table_name` does not * have an instance information, nothing is sent. * annotation: * option (google.api.routing) = { * // The routing code needs two keys instead of one composite * // but works only for the tables with the "project-instance" name * // syntax. * routing_parameters { * field: "table_name" * path_template: "{project_id=projects/*}/instances/*/**" * } * routing_parameters { * field: "table_name" * path_template: "projects/*/{instance_id=instances/*}/**" * } * }; * result: * x-goog-request-params: * project_id=projects/proj_foo&instance_id=instances/instance_bar * Sub-example 6b * Make the templates loose, so that if the `table_name` does not * have an instance information, just the project id part is sent. * annotation: * option (google.api.routing) = { * // The routing code wants two keys instead of one composite * // but will work with just the `project_id` for tables without * // an instance in the `table_name`. * routing_parameters { * field: "table_name" * path_template: "{project_id=projects/*}/**" * } * routing_parameters { * field: "table_name" * path_template: "projects/*/{instance_id=instances/*}/**" * } * }; * result (is the same as 6a for our example message because it has the instance * information): * x-goog-request-params: * project_id=projects/proj_foo&instance_id=instances/instance_bar * Example 7 * Extracting multiple routing header key-value pairs by matching * several path templates on multiple request fields. * NB: note that here there is no way to specify sending nothing if one of the * fields does not match its template. E.g. if the `table_name` is in the wrong * format, the `project_id` will not be sent, but the `routing_id` will be. * The backend routing code has to be aware of that and be prepared to not * receive a full complement of keys if it expects multiple. * annotation: * option (google.api.routing) = { * // The routing needs both `project_id` and `routing_id` * // (from the `app_profile_id` field) for routing. * routing_parameters { * field: "table_name" * path_template: "{project_id=projects/*}/**" * } * routing_parameters { * field: "app_profile_id" * path_template: "{routing_id=**}" * } * }; * result: * x-goog-request-params: * project_id=projects/proj_foo&routing_id=profiles/prof_qux * Example 8 * Extracting a single routing header key-value pair by matching * several conflictingly named path templates on several request fields. The * last template to match "wins" the conflict. * annotation: * option (google.api.routing) = { * // The `routing_id` can be a project id or a region id depending on * // the table name format, but only if the `app_profile_id` is not set. * // If `app_profile_id` is set it should be used instead. * routing_parameters { * field: "table_name" * path_template: "{routing_id=projects/*}/**" * } * routing_parameters { * field: "table_name" * path_template: "{routing_id=regions/*}/**" * } * routing_parameters { * field: "app_profile_id" * path_template: "{routing_id=**}" * } * }; * result: * x-goog-request-params: routing_id=profiles/prof_qux * Example 9 * Bringing it all together. * annotation: * option (google.api.routing) = { * // For routing both `table_location` and a `routing_id` are needed. * // * // table_location can be either an instance id or a region+zone id. * // * // For `routing_id`, take the value of `app_profile_id` * // - If it's in the format `profiles/`, send * // just the `` part. * // - If it's any other literal, send it as is. * // If the `app_profile_id` is empty, and the `table_name` starts with * // the project_id, send that instead. * routing_parameters { * field: "table_name" * path_template: "projects/*/{table_location=instances/*}/tables/*" * } * routing_parameters { * field: "table_name" * path_template: "{table_location=regions/*/zones/*}/tables/*" * } * routing_parameters { * field: "table_name" * path_template: "{routing_id=projects/*}/**" * } * routing_parameters { * field: "app_profile_id" * path_template: "{routing_id=**}" * } * routing_parameters { * field: "app_profile_id" * path_template: "profiles/{routing_id=*}" * } * }; * result: * x-goog-request-params: * table_location=instances/instance_bar&routing_id=prof_qux * * Generated from protobuf message google.api.RoutingRule */ class RoutingRule extends \Google\Protobuf\Internal\Message { /** * A collection of Routing Parameter specifications. * **NOTE:** If multiple Routing Parameters describe the same key * (via the `path_template` field or via the `field` field when * `path_template` is not provided), "last one wins" rule * determines which Parameter gets used. * See the examples for more details. * * Generated from protobuf field repeated .google.api.RoutingParameter routing_parameters = 2; */ private $routing_parameters; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type array<\Google\Api\RoutingParameter>|\Google\Protobuf\Internal\RepeatedField $routing_parameters * A collection of Routing Parameter specifications. * **NOTE:** If multiple Routing Parameters describe the same key * (via the `path_template` field or via the `field` field when * `path_template` is not provided), "last one wins" rule * determines which Parameter gets used. * See the examples for more details. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Routing::initOnce(); parent::__construct($data); } /** * A collection of Routing Parameter specifications. * **NOTE:** If multiple Routing Parameters describe the same key * (via the `path_template` field or via the `field` field when * `path_template` is not provided), "last one wins" rule * determines which Parameter gets used. * See the examples for more details. * * Generated from protobuf field repeated .google.api.RoutingParameter routing_parameters = 2; * @return \Google\Protobuf\Internal\RepeatedField */ public function getRoutingParameters() { return $this->routing_parameters; } /** * A collection of Routing Parameter specifications. * **NOTE:** If multiple Routing Parameters describe the same key * (via the `path_template` field or via the `field` field when * `path_template` is not provided), "last one wins" rule * determines which Parameter gets used. * See the examples for more details. * * Generated from protobuf field repeated .google.api.RoutingParameter routing_parameters = 2; * @param array<\Google\Api\RoutingParameter>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setRoutingParameters($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Api\RoutingParameter::class); $this->routing_parameters = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/RubySettings.php ================================================ google.api.RubySettings */ class RubySettings extends \Google\Protobuf\Internal\Message { /** * Some settings. * * Generated from protobuf field .google.api.CommonLanguageSettings common = 1; */ protected $common = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type \Google\Api\CommonLanguageSettings $common * Some settings. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Client::initOnce(); parent::__construct($data); } /** * Some settings. * * Generated from protobuf field .google.api.CommonLanguageSettings common = 1; * @return \Google\Api\CommonLanguageSettings|null */ public function getCommon() { return $this->common; } public function hasCommon() { return isset($this->common); } public function clearCommon() { unset($this->common); } /** * Some settings. * * Generated from protobuf field .google.api.CommonLanguageSettings common = 1; * @param \Google\Api\CommonLanguageSettings $var * @return $this */ public function setCommon($var) { GPBUtil::checkMessage($var, \Google\Api\CommonLanguageSettings::class); $this->common = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/SelectiveGapicGeneration.php ================================================ google.api.SelectiveGapicGeneration */ class SelectiveGapicGeneration extends \Google\Protobuf\Internal\Message { /** * An allowlist of the fully qualified names of RPCs that should be included * on public client surfaces. * * Generated from protobuf field repeated string methods = 1; */ private $methods; /** * Setting this to true indicates to the client generators that methods * that would be excluded from the generation should instead be generated * in a way that indicates these methods should not be consumed by * end users. How this is expressed is up to individual language * implementations to decide. Some examples may be: added annotations, * obfuscated identifiers, or other language idiomatic patterns. * * Generated from protobuf field bool generate_omitted_as_internal = 2; */ protected $generate_omitted_as_internal = false; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type array|\Google\Protobuf\Internal\RepeatedField $methods * An allowlist of the fully qualified names of RPCs that should be included * on public client surfaces. * @type bool $generate_omitted_as_internal * Setting this to true indicates to the client generators that methods * that would be excluded from the generation should instead be generated * in a way that indicates these methods should not be consumed by * end users. How this is expressed is up to individual language * implementations to decide. Some examples may be: added annotations, * obfuscated identifiers, or other language idiomatic patterns. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Client::initOnce(); parent::__construct($data); } /** * An allowlist of the fully qualified names of RPCs that should be included * on public client surfaces. * * Generated from protobuf field repeated string methods = 1; * @return \Google\Protobuf\Internal\RepeatedField */ public function getMethods() { return $this->methods; } /** * An allowlist of the fully qualified names of RPCs that should be included * on public client surfaces. * * Generated from protobuf field repeated string methods = 1; * @param array|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setMethods($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->methods = $arr; return $this; } /** * Setting this to true indicates to the client generators that methods * that would be excluded from the generation should instead be generated * in a way that indicates these methods should not be consumed by * end users. How this is expressed is up to individual language * implementations to decide. Some examples may be: added annotations, * obfuscated identifiers, or other language idiomatic patterns. * * Generated from protobuf field bool generate_omitted_as_internal = 2; * @return bool */ public function getGenerateOmittedAsInternal() { return $this->generate_omitted_as_internal; } /** * Setting this to true indicates to the client generators that methods * that would be excluded from the generation should instead be generated * in a way that indicates these methods should not be consumed by * end users. How this is expressed is up to individual language * implementations to decide. Some examples may be: added annotations, * obfuscated identifiers, or other language idiomatic patterns. * * Generated from protobuf field bool generate_omitted_as_internal = 2; * @param bool $var * @return $this */ public function setGenerateOmittedAsInternal($var) { GPBUtil::checkBool($var); $this->generate_omitted_as_internal = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/Service.php ================================================ google.api.Service */ class Service extends \Google\Protobuf\Internal\Message { /** * The service name, which is a DNS-like logical identifier for the * service, such as `calendar.googleapis.com`. The service name * typically goes through DNS verification to make sure the owner * of the service also owns the DNS name. * * Generated from protobuf field string name = 1; */ protected $name = ''; /** * The product title for this service, it is the name displayed in Google * Cloud Console. * * Generated from protobuf field string title = 2; */ protected $title = ''; /** * The Google project that owns this service. * * Generated from protobuf field string producer_project_id = 22; */ protected $producer_project_id = ''; /** * A unique ID for a specific instance of this message, typically assigned * by the client for tracking purpose. Must be no longer than 63 characters * and only lower case letters, digits, '.', '_' and '-' are allowed. If * empty, the server may choose to generate one instead. * * Generated from protobuf field string id = 33; */ protected $id = ''; /** * A list of API interfaces exported by this service. Only the `name` field * of the [google.protobuf.Api][google.protobuf.Api] needs to be provided by * the configuration author, as the remaining fields will be derived from the * IDL during the normalization process. It is an error to specify an API * interface here which cannot be resolved against the associated IDL files. * * Generated from protobuf field repeated .google.protobuf.Api apis = 3; */ private $apis; /** * A list of all proto message types included in this API service. * Types referenced directly or indirectly by the `apis` are automatically * included. Messages which are not referenced but shall be included, such as * types used by the `google.protobuf.Any` type, should be listed here by * name by the configuration author. Example: * types: * - name: google.protobuf.Int32 * * Generated from protobuf field repeated .google.protobuf.Type types = 4; */ private $types; /** * A list of all enum types included in this API service. Enums referenced * directly or indirectly by the `apis` are automatically included. Enums * which are not referenced but shall be included should be listed here by * name by the configuration author. Example: * enums: * - name: google.someapi.v1.SomeEnum * * Generated from protobuf field repeated .google.protobuf.Enum enums = 5; */ private $enums; /** * Additional API documentation. * * Generated from protobuf field .google.api.Documentation documentation = 6; */ protected $documentation = null; /** * API backend configuration. * * Generated from protobuf field .google.api.Backend backend = 8; */ protected $backend = null; /** * HTTP configuration. * * Generated from protobuf field .google.api.Http http = 9; */ protected $http = null; /** * Quota configuration. * * Generated from protobuf field .google.api.Quota quota = 10; */ protected $quota = null; /** * Auth configuration. * * Generated from protobuf field .google.api.Authentication authentication = 11; */ protected $authentication = null; /** * Context configuration. * * Generated from protobuf field .google.api.Context context = 12; */ protected $context = null; /** * Configuration controlling usage of this service. * * Generated from protobuf field .google.api.Usage usage = 15; */ protected $usage = null; /** * Configuration for network endpoints. If this is empty, then an endpoint * with the same name as the service is automatically generated to service all * defined APIs. * * Generated from protobuf field repeated .google.api.Endpoint endpoints = 18; */ private $endpoints; /** * Configuration for the service control plane. * * Generated from protobuf field .google.api.Control control = 21; */ protected $control = null; /** * Defines the logs used by this service. * * Generated from protobuf field repeated .google.api.LogDescriptor logs = 23; */ private $logs; /** * Defines the metrics used by this service. * * Generated from protobuf field repeated .google.api.MetricDescriptor metrics = 24; */ private $metrics; /** * Defines the monitored resources used by this service. This is required * by the [Service.monitoring][google.api.Service.monitoring] and * [Service.logging][google.api.Service.logging] configurations. * * Generated from protobuf field repeated .google.api.MonitoredResourceDescriptor monitored_resources = 25; */ private $monitored_resources; /** * Billing configuration. * * Generated from protobuf field .google.api.Billing billing = 26; */ protected $billing = null; /** * Logging configuration. * * Generated from protobuf field .google.api.Logging logging = 27; */ protected $logging = null; /** * Monitoring configuration. * * Generated from protobuf field .google.api.Monitoring monitoring = 28; */ protected $monitoring = null; /** * System parameter configuration. * * Generated from protobuf field .google.api.SystemParameters system_parameters = 29; */ protected $system_parameters = null; /** * Output only. The source information for this configuration if available. * * Generated from protobuf field .google.api.SourceInfo source_info = 37; */ protected $source_info = null; /** * Settings for [Google Cloud Client * libraries](https://cloud.google.com/apis/docs/cloud-client-libraries) * generated from APIs defined as protocol buffers. * * Generated from protobuf field .google.api.Publishing publishing = 45; */ protected $publishing = null; /** * Obsolete. Do not use. * This field has no semantic meaning. The service config compiler always * sets this field to `3`. * * Generated from protobuf field .google.protobuf.UInt32Value config_version = 20; */ protected $config_version = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $name * The service name, which is a DNS-like logical identifier for the * service, such as `calendar.googleapis.com`. The service name * typically goes through DNS verification to make sure the owner * of the service also owns the DNS name. * @type string $title * The product title for this service, it is the name displayed in Google * Cloud Console. * @type string $producer_project_id * The Google project that owns this service. * @type string $id * A unique ID for a specific instance of this message, typically assigned * by the client for tracking purpose. Must be no longer than 63 characters * and only lower case letters, digits, '.', '_' and '-' are allowed. If * empty, the server may choose to generate one instead. * @type array<\Google\Protobuf\Api>|\Google\Protobuf\Internal\RepeatedField $apis * A list of API interfaces exported by this service. Only the `name` field * of the [google.protobuf.Api][google.protobuf.Api] needs to be provided by * the configuration author, as the remaining fields will be derived from the * IDL during the normalization process. It is an error to specify an API * interface here which cannot be resolved against the associated IDL files. * @type array<\Google\Protobuf\Type>|\Google\Protobuf\Internal\RepeatedField $types * A list of all proto message types included in this API service. * Types referenced directly or indirectly by the `apis` are automatically * included. Messages which are not referenced but shall be included, such as * types used by the `google.protobuf.Any` type, should be listed here by * name by the configuration author. Example: * types: * - name: google.protobuf.Int32 * @type array<\Google\Protobuf\Enum>|\Google\Protobuf\Internal\RepeatedField $enums * A list of all enum types included in this API service. Enums referenced * directly or indirectly by the `apis` are automatically included. Enums * which are not referenced but shall be included should be listed here by * name by the configuration author. Example: * enums: * - name: google.someapi.v1.SomeEnum * @type \Google\Api\Documentation $documentation * Additional API documentation. * @type \Google\Api\Backend $backend * API backend configuration. * @type \Google\Api\Http $http * HTTP configuration. * @type \Google\Api\Quota $quota * Quota configuration. * @type \Google\Api\Authentication $authentication * Auth configuration. * @type \Google\Api\Context $context * Context configuration. * @type \Google\Api\Usage $usage * Configuration controlling usage of this service. * @type array<\Google\Api\Endpoint>|\Google\Protobuf\Internal\RepeatedField $endpoints * Configuration for network endpoints. If this is empty, then an endpoint * with the same name as the service is automatically generated to service all * defined APIs. * @type \Google\Api\Control $control * Configuration for the service control plane. * @type array<\Google\Api\LogDescriptor>|\Google\Protobuf\Internal\RepeatedField $logs * Defines the logs used by this service. * @type array<\Google\Api\MetricDescriptor>|\Google\Protobuf\Internal\RepeatedField $metrics * Defines the metrics used by this service. * @type array<\Google\Api\MonitoredResourceDescriptor>|\Google\Protobuf\Internal\RepeatedField $monitored_resources * Defines the monitored resources used by this service. This is required * by the [Service.monitoring][google.api.Service.monitoring] and * [Service.logging][google.api.Service.logging] configurations. * @type \Google\Api\Billing $billing * Billing configuration. * @type \Google\Api\Logging $logging * Logging configuration. * @type \Google\Api\Monitoring $monitoring * Monitoring configuration. * @type \Google\Api\SystemParameters $system_parameters * System parameter configuration. * @type \Google\Api\SourceInfo $source_info * Output only. The source information for this configuration if available. * @type \Google\Api\Publishing $publishing * Settings for [Google Cloud Client * libraries](https://cloud.google.com/apis/docs/cloud-client-libraries) * generated from APIs defined as protocol buffers. * @type \Google\Protobuf\UInt32Value $config_version * Obsolete. Do not use. * This field has no semantic meaning. The service config compiler always * sets this field to `3`. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Service::initOnce(); parent::__construct($data); } /** * The service name, which is a DNS-like logical identifier for the * service, such as `calendar.googleapis.com`. The service name * typically goes through DNS verification to make sure the owner * of the service also owns the DNS name. * * Generated from protobuf field string name = 1; * @return string */ public function getName() { return $this->name; } /** * The service name, which is a DNS-like logical identifier for the * service, such as `calendar.googleapis.com`. The service name * typically goes through DNS verification to make sure the owner * of the service also owns the DNS name. * * Generated from protobuf field string name = 1; * @param string $var * @return $this */ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; return $this; } /** * The product title for this service, it is the name displayed in Google * Cloud Console. * * Generated from protobuf field string title = 2; * @return string */ public function getTitle() { return $this->title; } /** * The product title for this service, it is the name displayed in Google * Cloud Console. * * Generated from protobuf field string title = 2; * @param string $var * @return $this */ public function setTitle($var) { GPBUtil::checkString($var, True); $this->title = $var; return $this; } /** * The Google project that owns this service. * * Generated from protobuf field string producer_project_id = 22; * @return string */ public function getProducerProjectId() { return $this->producer_project_id; } /** * The Google project that owns this service. * * Generated from protobuf field string producer_project_id = 22; * @param string $var * @return $this */ public function setProducerProjectId($var) { GPBUtil::checkString($var, True); $this->producer_project_id = $var; return $this; } /** * A unique ID for a specific instance of this message, typically assigned * by the client for tracking purpose. Must be no longer than 63 characters * and only lower case letters, digits, '.', '_' and '-' are allowed. If * empty, the server may choose to generate one instead. * * Generated from protobuf field string id = 33; * @return string */ public function getId() { return $this->id; } /** * A unique ID for a specific instance of this message, typically assigned * by the client for tracking purpose. Must be no longer than 63 characters * and only lower case letters, digits, '.', '_' and '-' are allowed. If * empty, the server may choose to generate one instead. * * Generated from protobuf field string id = 33; * @param string $var * @return $this */ public function setId($var) { GPBUtil::checkString($var, True); $this->id = $var; return $this; } /** * A list of API interfaces exported by this service. Only the `name` field * of the [google.protobuf.Api][google.protobuf.Api] needs to be provided by * the configuration author, as the remaining fields will be derived from the * IDL during the normalization process. It is an error to specify an API * interface here which cannot be resolved against the associated IDL files. * * Generated from protobuf field repeated .google.protobuf.Api apis = 3; * @return \Google\Protobuf\Internal\RepeatedField */ public function getApis() { return $this->apis; } /** * A list of API interfaces exported by this service. Only the `name` field * of the [google.protobuf.Api][google.protobuf.Api] needs to be provided by * the configuration author, as the remaining fields will be derived from the * IDL during the normalization process. It is an error to specify an API * interface here which cannot be resolved against the associated IDL files. * * Generated from protobuf field repeated .google.protobuf.Api apis = 3; * @param array<\Google\Protobuf\Api>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setApis($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Api::class); $this->apis = $arr; return $this; } /** * A list of all proto message types included in this API service. * Types referenced directly or indirectly by the `apis` are automatically * included. Messages which are not referenced but shall be included, such as * types used by the `google.protobuf.Any` type, should be listed here by * name by the configuration author. Example: * types: * - name: google.protobuf.Int32 * * Generated from protobuf field repeated .google.protobuf.Type types = 4; * @return \Google\Protobuf\Internal\RepeatedField */ public function getTypes() { return $this->types; } /** * A list of all proto message types included in this API service. * Types referenced directly or indirectly by the `apis` are automatically * included. Messages which are not referenced but shall be included, such as * types used by the `google.protobuf.Any` type, should be listed here by * name by the configuration author. Example: * types: * - name: google.protobuf.Int32 * * Generated from protobuf field repeated .google.protobuf.Type types = 4; * @param array<\Google\Protobuf\Type>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setTypes($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Type::class); $this->types = $arr; return $this; } /** * A list of all enum types included in this API service. Enums referenced * directly or indirectly by the `apis` are automatically included. Enums * which are not referenced but shall be included should be listed here by * name by the configuration author. Example: * enums: * - name: google.someapi.v1.SomeEnum * * Generated from protobuf field repeated .google.protobuf.Enum enums = 5; * @return \Google\Protobuf\Internal\RepeatedField */ public function getEnums() { return $this->enums; } /** * A list of all enum types included in this API service. Enums referenced * directly or indirectly by the `apis` are automatically included. Enums * which are not referenced but shall be included should be listed here by * name by the configuration author. Example: * enums: * - name: google.someapi.v1.SomeEnum * * Generated from protobuf field repeated .google.protobuf.Enum enums = 5; * @param array<\Google\Protobuf\Enum>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setEnums($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Enum::class); $this->enums = $arr; return $this; } /** * Additional API documentation. * * Generated from protobuf field .google.api.Documentation documentation = 6; * @return \Google\Api\Documentation|null */ public function getDocumentation() { return $this->documentation; } public function hasDocumentation() { return isset($this->documentation); } public function clearDocumentation() { unset($this->documentation); } /** * Additional API documentation. * * Generated from protobuf field .google.api.Documentation documentation = 6; * @param \Google\Api\Documentation $var * @return $this */ public function setDocumentation($var) { GPBUtil::checkMessage($var, \Google\Api\Documentation::class); $this->documentation = $var; return $this; } /** * API backend configuration. * * Generated from protobuf field .google.api.Backend backend = 8; * @return \Google\Api\Backend|null */ public function getBackend() { return $this->backend; } public function hasBackend() { return isset($this->backend); } public function clearBackend() { unset($this->backend); } /** * API backend configuration. * * Generated from protobuf field .google.api.Backend backend = 8; * @param \Google\Api\Backend $var * @return $this */ public function setBackend($var) { GPBUtil::checkMessage($var, \Google\Api\Backend::class); $this->backend = $var; return $this; } /** * HTTP configuration. * * Generated from protobuf field .google.api.Http http = 9; * @return \Google\Api\Http|null */ public function getHttp() { return $this->http; } public function hasHttp() { return isset($this->http); } public function clearHttp() { unset($this->http); } /** * HTTP configuration. * * Generated from protobuf field .google.api.Http http = 9; * @param \Google\Api\Http $var * @return $this */ public function setHttp($var) { GPBUtil::checkMessage($var, \Google\Api\Http::class); $this->http = $var; return $this; } /** * Quota configuration. * * Generated from protobuf field .google.api.Quota quota = 10; * @return \Google\Api\Quota|null */ public function getQuota() { return $this->quota; } public function hasQuota() { return isset($this->quota); } public function clearQuota() { unset($this->quota); } /** * Quota configuration. * * Generated from protobuf field .google.api.Quota quota = 10; * @param \Google\Api\Quota $var * @return $this */ public function setQuota($var) { GPBUtil::checkMessage($var, \Google\Api\Quota::class); $this->quota = $var; return $this; } /** * Auth configuration. * * Generated from protobuf field .google.api.Authentication authentication = 11; * @return \Google\Api\Authentication|null */ public function getAuthentication() { return $this->authentication; } public function hasAuthentication() { return isset($this->authentication); } public function clearAuthentication() { unset($this->authentication); } /** * Auth configuration. * * Generated from protobuf field .google.api.Authentication authentication = 11; * @param \Google\Api\Authentication $var * @return $this */ public function setAuthentication($var) { GPBUtil::checkMessage($var, \Google\Api\Authentication::class); $this->authentication = $var; return $this; } /** * Context configuration. * * Generated from protobuf field .google.api.Context context = 12; * @return \Google\Api\Context|null */ public function getContext() { return $this->context; } public function hasContext() { return isset($this->context); } public function clearContext() { unset($this->context); } /** * Context configuration. * * Generated from protobuf field .google.api.Context context = 12; * @param \Google\Api\Context $var * @return $this */ public function setContext($var) { GPBUtil::checkMessage($var, \Google\Api\Context::class); $this->context = $var; return $this; } /** * Configuration controlling usage of this service. * * Generated from protobuf field .google.api.Usage usage = 15; * @return \Google\Api\Usage|null */ public function getUsage() { return $this->usage; } public function hasUsage() { return isset($this->usage); } public function clearUsage() { unset($this->usage); } /** * Configuration controlling usage of this service. * * Generated from protobuf field .google.api.Usage usage = 15; * @param \Google\Api\Usage $var * @return $this */ public function setUsage($var) { GPBUtil::checkMessage($var, \Google\Api\Usage::class); $this->usage = $var; return $this; } /** * Configuration for network endpoints. If this is empty, then an endpoint * with the same name as the service is automatically generated to service all * defined APIs. * * Generated from protobuf field repeated .google.api.Endpoint endpoints = 18; * @return \Google\Protobuf\Internal\RepeatedField */ public function getEndpoints() { return $this->endpoints; } /** * Configuration for network endpoints. If this is empty, then an endpoint * with the same name as the service is automatically generated to service all * defined APIs. * * Generated from protobuf field repeated .google.api.Endpoint endpoints = 18; * @param array<\Google\Api\Endpoint>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setEndpoints($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Api\Endpoint::class); $this->endpoints = $arr; return $this; } /** * Configuration for the service control plane. * * Generated from protobuf field .google.api.Control control = 21; * @return \Google\Api\Control|null */ public function getControl() { return $this->control; } public function hasControl() { return isset($this->control); } public function clearControl() { unset($this->control); } /** * Configuration for the service control plane. * * Generated from protobuf field .google.api.Control control = 21; * @param \Google\Api\Control $var * @return $this */ public function setControl($var) { GPBUtil::checkMessage($var, \Google\Api\Control::class); $this->control = $var; return $this; } /** * Defines the logs used by this service. * * Generated from protobuf field repeated .google.api.LogDescriptor logs = 23; * @return \Google\Protobuf\Internal\RepeatedField */ public function getLogs() { return $this->logs; } /** * Defines the logs used by this service. * * Generated from protobuf field repeated .google.api.LogDescriptor logs = 23; * @param array<\Google\Api\LogDescriptor>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setLogs($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Api\LogDescriptor::class); $this->logs = $arr; return $this; } /** * Defines the metrics used by this service. * * Generated from protobuf field repeated .google.api.MetricDescriptor metrics = 24; * @return \Google\Protobuf\Internal\RepeatedField */ public function getMetrics() { return $this->metrics; } /** * Defines the metrics used by this service. * * Generated from protobuf field repeated .google.api.MetricDescriptor metrics = 24; * @param array<\Google\Api\MetricDescriptor>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setMetrics($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Api\MetricDescriptor::class); $this->metrics = $arr; return $this; } /** * Defines the monitored resources used by this service. This is required * by the [Service.monitoring][google.api.Service.monitoring] and * [Service.logging][google.api.Service.logging] configurations. * * Generated from protobuf field repeated .google.api.MonitoredResourceDescriptor monitored_resources = 25; * @return \Google\Protobuf\Internal\RepeatedField */ public function getMonitoredResources() { return $this->monitored_resources; } /** * Defines the monitored resources used by this service. This is required * by the [Service.monitoring][google.api.Service.monitoring] and * [Service.logging][google.api.Service.logging] configurations. * * Generated from protobuf field repeated .google.api.MonitoredResourceDescriptor monitored_resources = 25; * @param array<\Google\Api\MonitoredResourceDescriptor>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setMonitoredResources($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Api\MonitoredResourceDescriptor::class); $this->monitored_resources = $arr; return $this; } /** * Billing configuration. * * Generated from protobuf field .google.api.Billing billing = 26; * @return \Google\Api\Billing|null */ public function getBilling() { return $this->billing; } public function hasBilling() { return isset($this->billing); } public function clearBilling() { unset($this->billing); } /** * Billing configuration. * * Generated from protobuf field .google.api.Billing billing = 26; * @param \Google\Api\Billing $var * @return $this */ public function setBilling($var) { GPBUtil::checkMessage($var, \Google\Api\Billing::class); $this->billing = $var; return $this; } /** * Logging configuration. * * Generated from protobuf field .google.api.Logging logging = 27; * @return \Google\Api\Logging|null */ public function getLogging() { return $this->logging; } public function hasLogging() { return isset($this->logging); } public function clearLogging() { unset($this->logging); } /** * Logging configuration. * * Generated from protobuf field .google.api.Logging logging = 27; * @param \Google\Api\Logging $var * @return $this */ public function setLogging($var) { GPBUtil::checkMessage($var, \Google\Api\Logging::class); $this->logging = $var; return $this; } /** * Monitoring configuration. * * Generated from protobuf field .google.api.Monitoring monitoring = 28; * @return \Google\Api\Monitoring|null */ public function getMonitoring() { return $this->monitoring; } public function hasMonitoring() { return isset($this->monitoring); } public function clearMonitoring() { unset($this->monitoring); } /** * Monitoring configuration. * * Generated from protobuf field .google.api.Monitoring monitoring = 28; * @param \Google\Api\Monitoring $var * @return $this */ public function setMonitoring($var) { GPBUtil::checkMessage($var, \Google\Api\Monitoring::class); $this->monitoring = $var; return $this; } /** * System parameter configuration. * * Generated from protobuf field .google.api.SystemParameters system_parameters = 29; * @return \Google\Api\SystemParameters|null */ public function getSystemParameters() { return $this->system_parameters; } public function hasSystemParameters() { return isset($this->system_parameters); } public function clearSystemParameters() { unset($this->system_parameters); } /** * System parameter configuration. * * Generated from protobuf field .google.api.SystemParameters system_parameters = 29; * @param \Google\Api\SystemParameters $var * @return $this */ public function setSystemParameters($var) { GPBUtil::checkMessage($var, \Google\Api\SystemParameters::class); $this->system_parameters = $var; return $this; } /** * Output only. The source information for this configuration if available. * * Generated from protobuf field .google.api.SourceInfo source_info = 37; * @return \Google\Api\SourceInfo|null */ public function getSourceInfo() { return $this->source_info; } public function hasSourceInfo() { return isset($this->source_info); } public function clearSourceInfo() { unset($this->source_info); } /** * Output only. The source information for this configuration if available. * * Generated from protobuf field .google.api.SourceInfo source_info = 37; * @param \Google\Api\SourceInfo $var * @return $this */ public function setSourceInfo($var) { GPBUtil::checkMessage($var, \Google\Api\SourceInfo::class); $this->source_info = $var; return $this; } /** * Settings for [Google Cloud Client * libraries](https://cloud.google.com/apis/docs/cloud-client-libraries) * generated from APIs defined as protocol buffers. * * Generated from protobuf field .google.api.Publishing publishing = 45; * @return \Google\Api\Publishing|null */ public function getPublishing() { return $this->publishing; } public function hasPublishing() { return isset($this->publishing); } public function clearPublishing() { unset($this->publishing); } /** * Settings for [Google Cloud Client * libraries](https://cloud.google.com/apis/docs/cloud-client-libraries) * generated from APIs defined as protocol buffers. * * Generated from protobuf field .google.api.Publishing publishing = 45; * @param \Google\Api\Publishing $var * @return $this */ public function setPublishing($var) { GPBUtil::checkMessage($var, \Google\Api\Publishing::class); $this->publishing = $var; return $this; } /** * Obsolete. Do not use. * This field has no semantic meaning. The service config compiler always * sets this field to `3`. * * Generated from protobuf field .google.protobuf.UInt32Value config_version = 20; * @return \Google\Protobuf\UInt32Value|null */ public function getConfigVersion() { return $this->config_version; } public function hasConfigVersion() { return isset($this->config_version); } public function clearConfigVersion() { unset($this->config_version); } /** * Returns the unboxed value from getConfigVersion() * Obsolete. Do not use. * This field has no semantic meaning. The service config compiler always * sets this field to `3`. * * Generated from protobuf field .google.protobuf.UInt32Value config_version = 20; * @return int|null */ public function getConfigVersionUnwrapped() { return $this->readWrapperValue("config_version"); } /** * Obsolete. Do not use. * This field has no semantic meaning. The service config compiler always * sets this field to `3`. * * Generated from protobuf field .google.protobuf.UInt32Value config_version = 20; * @param \Google\Protobuf\UInt32Value $var * @return $this */ public function setConfigVersion($var) { GPBUtil::checkMessage($var, \Google\Protobuf\UInt32Value::class); $this->config_version = $var; return $this; } /** * Sets the field by wrapping a primitive type in a Google\Protobuf\UInt32Value object. * Obsolete. Do not use. * This field has no semantic meaning. The service config compiler always * sets this field to `3`. * * Generated from protobuf field .google.protobuf.UInt32Value config_version = 20; * @param int|null $var * @return $this */ public function setConfigVersionUnwrapped($var) { $this->writeWrapperValue("config_version", $var); return $this;} } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/SourceInfo.php ================================================ google.api.SourceInfo */ class SourceInfo extends \Google\Protobuf\Internal\Message { /** * All files used during config generation. * * Generated from protobuf field repeated .google.protobuf.Any source_files = 1; */ private $source_files; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type array<\Google\Protobuf\Any>|\Google\Protobuf\Internal\RepeatedField $source_files * All files used during config generation. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\SourceInfo::initOnce(); parent::__construct($data); } /** * All files used during config generation. * * Generated from protobuf field repeated .google.protobuf.Any source_files = 1; * @return \Google\Protobuf\Internal\RepeatedField */ public function getSourceFiles() { return $this->source_files; } /** * All files used during config generation. * * Generated from protobuf field repeated .google.protobuf.Any source_files = 1; * @param array<\Google\Protobuf\Any>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setSourceFiles($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Any::class); $this->source_files = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/SystemParameter.php ================================================ google.api.SystemParameter */ class SystemParameter extends \Google\Protobuf\Internal\Message { /** * Define the name of the parameter, such as "api_key" . It is case sensitive. * * Generated from protobuf field string name = 1; */ protected $name = ''; /** * Define the HTTP header name to use for the parameter. It is case * insensitive. * * Generated from protobuf field string http_header = 2; */ protected $http_header = ''; /** * Define the URL query parameter name to use for the parameter. It is case * sensitive. * * Generated from protobuf field string url_query_parameter = 3; */ protected $url_query_parameter = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $name * Define the name of the parameter, such as "api_key" . It is case sensitive. * @type string $http_header * Define the HTTP header name to use for the parameter. It is case * insensitive. * @type string $url_query_parameter * Define the URL query parameter name to use for the parameter. It is case * sensitive. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\SystemParameter::initOnce(); parent::__construct($data); } /** * Define the name of the parameter, such as "api_key" . It is case sensitive. * * Generated from protobuf field string name = 1; * @return string */ public function getName() { return $this->name; } /** * Define the name of the parameter, such as "api_key" . It is case sensitive. * * Generated from protobuf field string name = 1; * @param string $var * @return $this */ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; return $this; } /** * Define the HTTP header name to use for the parameter. It is case * insensitive. * * Generated from protobuf field string http_header = 2; * @return string */ public function getHttpHeader() { return $this->http_header; } /** * Define the HTTP header name to use for the parameter. It is case * insensitive. * * Generated from protobuf field string http_header = 2; * @param string $var * @return $this */ public function setHttpHeader($var) { GPBUtil::checkString($var, True); $this->http_header = $var; return $this; } /** * Define the URL query parameter name to use for the parameter. It is case * sensitive. * * Generated from protobuf field string url_query_parameter = 3; * @return string */ public function getUrlQueryParameter() { return $this->url_query_parameter; } /** * Define the URL query parameter name to use for the parameter. It is case * sensitive. * * Generated from protobuf field string url_query_parameter = 3; * @param string $var * @return $this */ public function setUrlQueryParameter($var) { GPBUtil::checkString($var, True); $this->url_query_parameter = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/SystemParameterRule.php ================================================ google.api.SystemParameterRule */ class SystemParameterRule extends \Google\Protobuf\Internal\Message { /** * Selects the methods to which this rule applies. Use '*' to indicate all * methods in all APIs. * Refer to [selector][google.api.DocumentationRule.selector] for syntax * details. * * Generated from protobuf field string selector = 1; */ protected $selector = ''; /** * Define parameters. Multiple names may be defined for a parameter. * For a given method call, only one of them should be used. If multiple * names are used the behavior is implementation-dependent. * If none of the specified names are present the behavior is * parameter-dependent. * * Generated from protobuf field repeated .google.api.SystemParameter parameters = 2; */ private $parameters; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $selector * Selects the methods to which this rule applies. Use '*' to indicate all * methods in all APIs. * Refer to [selector][google.api.DocumentationRule.selector] for syntax * details. * @type array<\Google\Api\SystemParameter>|\Google\Protobuf\Internal\RepeatedField $parameters * Define parameters. Multiple names may be defined for a parameter. * For a given method call, only one of them should be used. If multiple * names are used the behavior is implementation-dependent. * If none of the specified names are present the behavior is * parameter-dependent. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\SystemParameter::initOnce(); parent::__construct($data); } /** * Selects the methods to which this rule applies. Use '*' to indicate all * methods in all APIs. * Refer to [selector][google.api.DocumentationRule.selector] for syntax * details. * * Generated from protobuf field string selector = 1; * @return string */ public function getSelector() { return $this->selector; } /** * Selects the methods to which this rule applies. Use '*' to indicate all * methods in all APIs. * Refer to [selector][google.api.DocumentationRule.selector] for syntax * details. * * Generated from protobuf field string selector = 1; * @param string $var * @return $this */ public function setSelector($var) { GPBUtil::checkString($var, True); $this->selector = $var; return $this; } /** * Define parameters. Multiple names may be defined for a parameter. * For a given method call, only one of them should be used. If multiple * names are used the behavior is implementation-dependent. * If none of the specified names are present the behavior is * parameter-dependent. * * Generated from protobuf field repeated .google.api.SystemParameter parameters = 2; * @return \Google\Protobuf\Internal\RepeatedField */ public function getParameters() { return $this->parameters; } /** * Define parameters. Multiple names may be defined for a parameter. * For a given method call, only one of them should be used. If multiple * names are used the behavior is implementation-dependent. * If none of the specified names are present the behavior is * parameter-dependent. * * Generated from protobuf field repeated .google.api.SystemParameter parameters = 2; * @param array<\Google\Api\SystemParameter>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setParameters($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Api\SystemParameter::class); $this->parameters = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/SystemParameters.php ================================================ google.api.SystemParameters */ class SystemParameters extends \Google\Protobuf\Internal\Message { /** * Define system parameters. * The parameters defined here will override the default parameters * implemented by the system. If this field is missing from the service * config, default system parameters will be used. Default system parameters * and names is implementation-dependent. * Example: define api key for all methods * system_parameters * rules: * - selector: "*" * parameters: * - name: api_key * url_query_parameter: api_key * Example: define 2 api key names for a specific method. * system_parameters * rules: * - selector: "/ListShelves" * parameters: * - name: api_key * http_header: Api-Key1 * - name: api_key * http_header: Api-Key2 * **NOTE:** All service configuration rules follow "last one wins" order. * * Generated from protobuf field repeated .google.api.SystemParameterRule rules = 1; */ private $rules; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type array<\Google\Api\SystemParameterRule>|\Google\Protobuf\Internal\RepeatedField $rules * Define system parameters. * The parameters defined here will override the default parameters * implemented by the system. If this field is missing from the service * config, default system parameters will be used. Default system parameters * and names is implementation-dependent. * Example: define api key for all methods * system_parameters * rules: * - selector: "*" * parameters: * - name: api_key * url_query_parameter: api_key * Example: define 2 api key names for a specific method. * system_parameters * rules: * - selector: "/ListShelves" * parameters: * - name: api_key * http_header: Api-Key1 * - name: api_key * http_header: Api-Key2 * **NOTE:** All service configuration rules follow "last one wins" order. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\SystemParameter::initOnce(); parent::__construct($data); } /** * Define system parameters. * The parameters defined here will override the default parameters * implemented by the system. If this field is missing from the service * config, default system parameters will be used. Default system parameters * and names is implementation-dependent. * Example: define api key for all methods * system_parameters * rules: * - selector: "*" * parameters: * - name: api_key * url_query_parameter: api_key * Example: define 2 api key names for a specific method. * system_parameters * rules: * - selector: "/ListShelves" * parameters: * - name: api_key * http_header: Api-Key1 * - name: api_key * http_header: Api-Key2 * **NOTE:** All service configuration rules follow "last one wins" order. * * Generated from protobuf field repeated .google.api.SystemParameterRule rules = 1; * @return \Google\Protobuf\Internal\RepeatedField */ public function getRules() { return $this->rules; } /** * Define system parameters. * The parameters defined here will override the default parameters * implemented by the system. If this field is missing from the service * config, default system parameters will be used. Default system parameters * and names is implementation-dependent. * Example: define api key for all methods * system_parameters * rules: * - selector: "*" * parameters: * - name: api_key * url_query_parameter: api_key * Example: define 2 api key names for a specific method. * system_parameters * rules: * - selector: "/ListShelves" * parameters: * - name: api_key * http_header: Api-Key1 * - name: api_key * http_header: Api-Key2 * **NOTE:** All service configuration rules follow "last one wins" order. * * Generated from protobuf field repeated .google.api.SystemParameterRule rules = 1; * @param array<\Google\Api\SystemParameterRule>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setRules($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Api\SystemParameterRule::class); $this->rules = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/TypeReference.php ================================================ google.api.TypeReference */ class TypeReference extends \Google\Protobuf\Internal\Message { /** * The name of the type that the annotated, generic field may represent. * If the type is in the same protobuf package, the value can be the simple * message name e.g., `"MyMessage"`. Otherwise, the value must be the * fully-qualified message name e.g., `"google.library.v1.Book"`. * If the type(s) are unknown to the service (e.g. the field accepts generic * user input), use the wildcard `"*"` to denote this behavior. * See [AIP-202](https://google.aip.dev/202#type-references) for more details. * * Generated from protobuf field string type_name = 1; */ protected $type_name = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $type_name * The name of the type that the annotated, generic field may represent. * If the type is in the same protobuf package, the value can be the simple * message name e.g., `"MyMessage"`. Otherwise, the value must be the * fully-qualified message name e.g., `"google.library.v1.Book"`. * If the type(s) are unknown to the service (e.g. the field accepts generic * user input), use the wildcard `"*"` to denote this behavior. * See [AIP-202](https://google.aip.dev/202#type-references) for more details. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\FieldInfo::initOnce(); parent::__construct($data); } /** * The name of the type that the annotated, generic field may represent. * If the type is in the same protobuf package, the value can be the simple * message name e.g., `"MyMessage"`. Otherwise, the value must be the * fully-qualified message name e.g., `"google.library.v1.Book"`. * If the type(s) are unknown to the service (e.g. the field accepts generic * user input), use the wildcard `"*"` to denote this behavior. * See [AIP-202](https://google.aip.dev/202#type-references) for more details. * * Generated from protobuf field string type_name = 1; * @return string */ public function getTypeName() { return $this->type_name; } /** * The name of the type that the annotated, generic field may represent. * If the type is in the same protobuf package, the value can be the simple * message name e.g., `"MyMessage"`. Otherwise, the value must be the * fully-qualified message name e.g., `"google.library.v1.Book"`. * If the type(s) are unknown to the service (e.g. the field accepts generic * user input), use the wildcard `"*"` to denote this behavior. * See [AIP-202](https://google.aip.dev/202#type-references) for more details. * * Generated from protobuf field string type_name = 1; * @param string $var * @return $this */ public function setTypeName($var) { GPBUtil::checkString($var, True); $this->type_name = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/Usage.php ================================================ google.api.Usage */ class Usage extends \Google\Protobuf\Internal\Message { /** * Requirements that must be satisfied before a consumer project can use the * service. Each requirement is of the form /; * for example 'serviceusage.googleapis.com/billing-enabled'. * For Google APIs, a Terms of Service requirement must be included here. * Google Cloud APIs must include "serviceusage.googleapis.com/tos/cloud". * Other Google APIs should include * "serviceusage.googleapis.com/tos/universal". Additional ToS can be * included based on the business needs. * * Generated from protobuf field repeated string requirements = 1; */ private $requirements; /** * A list of usage rules that apply to individual API methods. * **NOTE:** All service configuration rules follow "last one wins" order. * * Generated from protobuf field repeated .google.api.UsageRule rules = 6; */ private $rules; /** * The full resource name of a channel used for sending notifications to the * service producer. * Google Service Management currently only supports * [Google Cloud Pub/Sub](https://cloud.google.com/pubsub) as a notification * channel. To use Google Cloud Pub/Sub as the channel, this must be the name * of a Cloud Pub/Sub topic that uses the Cloud Pub/Sub topic name format * documented in https://cloud.google.com/pubsub/docs/overview. * * Generated from protobuf field string producer_notification_channel = 7; */ protected $producer_notification_channel = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type array|\Google\Protobuf\Internal\RepeatedField $requirements * Requirements that must be satisfied before a consumer project can use the * service. Each requirement is of the form /; * for example 'serviceusage.googleapis.com/billing-enabled'. * For Google APIs, a Terms of Service requirement must be included here. * Google Cloud APIs must include "serviceusage.googleapis.com/tos/cloud". * Other Google APIs should include * "serviceusage.googleapis.com/tos/universal". Additional ToS can be * included based on the business needs. * @type array<\Google\Api\UsageRule>|\Google\Protobuf\Internal\RepeatedField $rules * A list of usage rules that apply to individual API methods. * **NOTE:** All service configuration rules follow "last one wins" order. * @type string $producer_notification_channel * The full resource name of a channel used for sending notifications to the * service producer. * Google Service Management currently only supports * [Google Cloud Pub/Sub](https://cloud.google.com/pubsub) as a notification * channel. To use Google Cloud Pub/Sub as the channel, this must be the name * of a Cloud Pub/Sub topic that uses the Cloud Pub/Sub topic name format * documented in https://cloud.google.com/pubsub/docs/overview. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Usage::initOnce(); parent::__construct($data); } /** * Requirements that must be satisfied before a consumer project can use the * service. Each requirement is of the form /; * for example 'serviceusage.googleapis.com/billing-enabled'. * For Google APIs, a Terms of Service requirement must be included here. * Google Cloud APIs must include "serviceusage.googleapis.com/tos/cloud". * Other Google APIs should include * "serviceusage.googleapis.com/tos/universal". Additional ToS can be * included based on the business needs. * * Generated from protobuf field repeated string requirements = 1; * @return \Google\Protobuf\Internal\RepeatedField */ public function getRequirements() { return $this->requirements; } /** * Requirements that must be satisfied before a consumer project can use the * service. Each requirement is of the form /; * for example 'serviceusage.googleapis.com/billing-enabled'. * For Google APIs, a Terms of Service requirement must be included here. * Google Cloud APIs must include "serviceusage.googleapis.com/tos/cloud". * Other Google APIs should include * "serviceusage.googleapis.com/tos/universal". Additional ToS can be * included based on the business needs. * * Generated from protobuf field repeated string requirements = 1; * @param array|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setRequirements($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->requirements = $arr; return $this; } /** * A list of usage rules that apply to individual API methods. * **NOTE:** All service configuration rules follow "last one wins" order. * * Generated from protobuf field repeated .google.api.UsageRule rules = 6; * @return \Google\Protobuf\Internal\RepeatedField */ public function getRules() { return $this->rules; } /** * A list of usage rules that apply to individual API methods. * **NOTE:** All service configuration rules follow "last one wins" order. * * Generated from protobuf field repeated .google.api.UsageRule rules = 6; * @param array<\Google\Api\UsageRule>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setRules($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Api\UsageRule::class); $this->rules = $arr; return $this; } /** * The full resource name of a channel used for sending notifications to the * service producer. * Google Service Management currently only supports * [Google Cloud Pub/Sub](https://cloud.google.com/pubsub) as a notification * channel. To use Google Cloud Pub/Sub as the channel, this must be the name * of a Cloud Pub/Sub topic that uses the Cloud Pub/Sub topic name format * documented in https://cloud.google.com/pubsub/docs/overview. * * Generated from protobuf field string producer_notification_channel = 7; * @return string */ public function getProducerNotificationChannel() { return $this->producer_notification_channel; } /** * The full resource name of a channel used for sending notifications to the * service producer. * Google Service Management currently only supports * [Google Cloud Pub/Sub](https://cloud.google.com/pubsub) as a notification * channel. To use Google Cloud Pub/Sub as the channel, this must be the name * of a Cloud Pub/Sub topic that uses the Cloud Pub/Sub topic name format * documented in https://cloud.google.com/pubsub/docs/overview. * * Generated from protobuf field string producer_notification_channel = 7; * @param string $var * @return $this */ public function setProducerNotificationChannel($var) { GPBUtil::checkString($var, True); $this->producer_notification_channel = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/UsageRule.php ================================================ google.api.UsageRule */ class UsageRule extends \Google\Protobuf\Internal\Message { /** * Selects the methods to which this rule applies. Use '*' to indicate all * methods in all APIs. * Refer to [selector][google.api.DocumentationRule.selector] for syntax * details. * * Generated from protobuf field string selector = 1; */ protected $selector = ''; /** * If true, the selected method allows unregistered calls, e.g. calls * that don't identify any user or application. * * Generated from protobuf field bool allow_unregistered_calls = 2; */ protected $allow_unregistered_calls = false; /** * If true, the selected method should skip service control and the control * plane features, such as quota and billing, will not be available. * This flag is used by Google Cloud Endpoints to bypass checks for internal * methods, such as service health check methods. * * Generated from protobuf field bool skip_service_control = 3; */ protected $skip_service_control = false; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $selector * Selects the methods to which this rule applies. Use '*' to indicate all * methods in all APIs. * Refer to [selector][google.api.DocumentationRule.selector] for syntax * details. * @type bool $allow_unregistered_calls * If true, the selected method allows unregistered calls, e.g. calls * that don't identify any user or application. * @type bool $skip_service_control * If true, the selected method should skip service control and the control * plane features, such as quota and billing, will not be available. * This flag is used by Google Cloud Endpoints to bypass checks for internal * methods, such as service health check methods. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Usage::initOnce(); parent::__construct($data); } /** * Selects the methods to which this rule applies. Use '*' to indicate all * methods in all APIs. * Refer to [selector][google.api.DocumentationRule.selector] for syntax * details. * * Generated from protobuf field string selector = 1; * @return string */ public function getSelector() { return $this->selector; } /** * Selects the methods to which this rule applies. Use '*' to indicate all * methods in all APIs. * Refer to [selector][google.api.DocumentationRule.selector] for syntax * details. * * Generated from protobuf field string selector = 1; * @param string $var * @return $this */ public function setSelector($var) { GPBUtil::checkString($var, True); $this->selector = $var; return $this; } /** * If true, the selected method allows unregistered calls, e.g. calls * that don't identify any user or application. * * Generated from protobuf field bool allow_unregistered_calls = 2; * @return bool */ public function getAllowUnregisteredCalls() { return $this->allow_unregistered_calls; } /** * If true, the selected method allows unregistered calls, e.g. calls * that don't identify any user or application. * * Generated from protobuf field bool allow_unregistered_calls = 2; * @param bool $var * @return $this */ public function setAllowUnregisteredCalls($var) { GPBUtil::checkBool($var); $this->allow_unregistered_calls = $var; return $this; } /** * If true, the selected method should skip service control and the control * plane features, such as quota and billing, will not be available. * This flag is used by Google Cloud Endpoints to bypass checks for internal * methods, such as service health check methods. * * Generated from protobuf field bool skip_service_control = 3; * @return bool */ public function getSkipServiceControl() { return $this->skip_service_control; } /** * If true, the selected method should skip service control and the control * plane features, such as quota and billing, will not be available. * This flag is used by Google Cloud Endpoints to bypass checks for internal * methods, such as service health check methods. * * Generated from protobuf field bool skip_service_control = 3; * @param bool $var * @return $this */ public function setSkipServiceControl($var) { GPBUtil::checkBool($var); $this->skip_service_control = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/Visibility.php ================================================ google.api.Visibility */ class Visibility extends \Google\Protobuf\Internal\Message { /** * A list of visibility rules that apply to individual API elements. * **NOTE:** All service configuration rules follow "last one wins" order. * * Generated from protobuf field repeated .google.api.VisibilityRule rules = 1; */ private $rules; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type array<\Google\Api\VisibilityRule>|\Google\Protobuf\Internal\RepeatedField $rules * A list of visibility rules that apply to individual API elements. * **NOTE:** All service configuration rules follow "last one wins" order. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Visibility::initOnce(); parent::__construct($data); } /** * A list of visibility rules that apply to individual API elements. * **NOTE:** All service configuration rules follow "last one wins" order. * * Generated from protobuf field repeated .google.api.VisibilityRule rules = 1; * @return \Google\Protobuf\Internal\RepeatedField */ public function getRules() { return $this->rules; } /** * A list of visibility rules that apply to individual API elements. * **NOTE:** All service configuration rules follow "last one wins" order. * * Generated from protobuf field repeated .google.api.VisibilityRule rules = 1; * @param array<\Google\Api\VisibilityRule>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setRules($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Api\VisibilityRule::class); $this->rules = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Api/VisibilityRule.php ================================================ google.api.VisibilityRule */ class VisibilityRule extends \Google\Protobuf\Internal\Message { /** * Selects methods, messages, fields, enums, etc. to which this rule applies. * Refer to [selector][google.api.DocumentationRule.selector] for syntax * details. * * Generated from protobuf field string selector = 1; */ protected $selector = ''; /** * A comma-separated list of visibility labels that apply to the `selector`. * Any of the listed labels can be used to grant the visibility. * If a rule has multiple labels, removing one of the labels but not all of * them can break clients. * Example: * visibility: * rules: * - selector: google.calendar.Calendar.EnhancedSearch * restriction: INTERNAL, PREVIEW * Removing INTERNAL from this restriction will break clients that rely on * this method and only had access to it through INTERNAL. * * Generated from protobuf field string restriction = 2; */ protected $restriction = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $selector * Selects methods, messages, fields, enums, etc. to which this rule applies. * Refer to [selector][google.api.DocumentationRule.selector] for syntax * details. * @type string $restriction * A comma-separated list of visibility labels that apply to the `selector`. * Any of the listed labels can be used to grant the visibility. * If a rule has multiple labels, removing one of the labels but not all of * them can break clients. * Example: * visibility: * rules: * - selector: google.calendar.Calendar.EnhancedSearch * restriction: INTERNAL, PREVIEW * Removing INTERNAL from this restriction will break clients that rely on * this method and only had access to it through INTERNAL. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Api\Visibility::initOnce(); parent::__construct($data); } /** * Selects methods, messages, fields, enums, etc. to which this rule applies. * Refer to [selector][google.api.DocumentationRule.selector] for syntax * details. * * Generated from protobuf field string selector = 1; * @return string */ public function getSelector() { return $this->selector; } /** * Selects methods, messages, fields, enums, etc. to which this rule applies. * Refer to [selector][google.api.DocumentationRule.selector] for syntax * details. * * Generated from protobuf field string selector = 1; * @param string $var * @return $this */ public function setSelector($var) { GPBUtil::checkString($var, True); $this->selector = $var; return $this; } /** * A comma-separated list of visibility labels that apply to the `selector`. * Any of the listed labels can be used to grant the visibility. * If a rule has multiple labels, removing one of the labels but not all of * them can break clients. * Example: * visibility: * rules: * - selector: google.calendar.Calendar.EnhancedSearch * restriction: INTERNAL, PREVIEW * Removing INTERNAL from this restriction will break clients that rely on * this method and only had access to it through INTERNAL. * * Generated from protobuf field string restriction = 2; * @return string */ public function getRestriction() { return $this->restriction; } /** * A comma-separated list of visibility labels that apply to the `selector`. * Any of the listed labels can be used to grant the visibility. * If a rule has multiple labels, removing one of the labels but not all of * them can break clients. * Example: * visibility: * rules: * - selector: google.calendar.Calendar.EnhancedSearch * restriction: INTERNAL, PREVIEW * Removing INTERNAL from this restriction will break clients that rely on * this method and only had access to it through INTERNAL. * * Generated from protobuf field string restriction = 2; * @param string $var * @return $this */ public function setRestriction($var) { GPBUtil::checkString($var, True); $this->restriction = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Cloud/Iam/V1/AuditConfig.php ================================================ google.iam.v1.AuditConfig */ class AuditConfig extends \Google\Protobuf\Internal\Message { /** * Specifies a service that will be enabled for audit logging. * For example, `storage.googleapis.com`, `cloudsql.googleapis.com`. * `allServices` is a special value that covers all services. * * Generated from protobuf field string service = 1; */ protected $service = ''; /** * The configuration for logging of each type of permission. * * Generated from protobuf field repeated .google.iam.v1.AuditLogConfig audit_log_configs = 3; */ private $audit_log_configs; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $service * Specifies a service that will be enabled for audit logging. * For example, `storage.googleapis.com`, `cloudsql.googleapis.com`. * `allServices` is a special value that covers all services. * @type array<\Google\Cloud\Iam\V1\AuditLogConfig>|\Google\Protobuf\Internal\RepeatedField $audit_log_configs * The configuration for logging of each type of permission. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Iam\V1\Policy::initOnce(); parent::__construct($data); } /** * Specifies a service that will be enabled for audit logging. * For example, `storage.googleapis.com`, `cloudsql.googleapis.com`. * `allServices` is a special value that covers all services. * * Generated from protobuf field string service = 1; * @return string */ public function getService() { return $this->service; } /** * Specifies a service that will be enabled for audit logging. * For example, `storage.googleapis.com`, `cloudsql.googleapis.com`. * `allServices` is a special value that covers all services. * * Generated from protobuf field string service = 1; * @param string $var * @return $this */ public function setService($var) { GPBUtil::checkString($var, True); $this->service = $var; return $this; } /** * The configuration for logging of each type of permission. * * Generated from protobuf field repeated .google.iam.v1.AuditLogConfig audit_log_configs = 3; * @return \Google\Protobuf\Internal\RepeatedField */ public function getAuditLogConfigs() { return $this->audit_log_configs; } /** * The configuration for logging of each type of permission. * * Generated from protobuf field repeated .google.iam.v1.AuditLogConfig audit_log_configs = 3; * @param array<\Google\Cloud\Iam\V1\AuditLogConfig>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setAuditLogConfigs($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Cloud\Iam\V1\AuditLogConfig::class); $this->audit_log_configs = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Cloud/Iam/V1/AuditConfigDelta/Action.php ================================================ google.iam.v1.AuditConfigDelta.Action */ class Action { /** * Unspecified. * * Generated from protobuf enum ACTION_UNSPECIFIED = 0; */ const ACTION_UNSPECIFIED = 0; /** * Addition of an audit configuration. * * Generated from protobuf enum ADD = 1; */ const ADD = 1; /** * Removal of an audit configuration. * * Generated from protobuf enum REMOVE = 2; */ const REMOVE = 2; private static $valueToName = [ self::ACTION_UNSPECIFIED => 'ACTION_UNSPECIFIED', self::ADD => 'ADD', self::REMOVE => 'REMOVE', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Cloud/Iam/V1/AuditConfigDelta.php ================================================ google.iam.v1.AuditConfigDelta */ class AuditConfigDelta extends \Google\Protobuf\Internal\Message { /** * The action that was performed on an audit configuration in a policy. * Required * * Generated from protobuf field .google.iam.v1.AuditConfigDelta.Action action = 1; */ protected $action = 0; /** * Specifies a service that was configured for Cloud Audit Logging. * For example, `storage.googleapis.com`, `cloudsql.googleapis.com`. * `allServices` is a special value that covers all services. * Required * * Generated from protobuf field string service = 2; */ protected $service = ''; /** * A single identity that is exempted from "data access" audit * logging for the `service` specified above. * Follows the same format of Binding.members. * * Generated from protobuf field string exempted_member = 3; */ protected $exempted_member = ''; /** * Specifies the log_type that was be enabled. ADMIN_ACTIVITY is always * enabled, and cannot be configured. * Required * * Generated from protobuf field string log_type = 4; */ protected $log_type = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type int $action * The action that was performed on an audit configuration in a policy. * Required * @type string $service * Specifies a service that was configured for Cloud Audit Logging. * For example, `storage.googleapis.com`, `cloudsql.googleapis.com`. * `allServices` is a special value that covers all services. * Required * @type string $exempted_member * A single identity that is exempted from "data access" audit * logging for the `service` specified above. * Follows the same format of Binding.members. * @type string $log_type * Specifies the log_type that was be enabled. ADMIN_ACTIVITY is always * enabled, and cannot be configured. * Required * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Iam\V1\Policy::initOnce(); parent::__construct($data); } /** * The action that was performed on an audit configuration in a policy. * Required * * Generated from protobuf field .google.iam.v1.AuditConfigDelta.Action action = 1; * @return int */ public function getAction() { return $this->action; } /** * The action that was performed on an audit configuration in a policy. * Required * * Generated from protobuf field .google.iam.v1.AuditConfigDelta.Action action = 1; * @param int $var * @return $this */ public function setAction($var) { GPBUtil::checkEnum($var, \Google\Cloud\Iam\V1\AuditConfigDelta\Action::class); $this->action = $var; return $this; } /** * Specifies a service that was configured for Cloud Audit Logging. * For example, `storage.googleapis.com`, `cloudsql.googleapis.com`. * `allServices` is a special value that covers all services. * Required * * Generated from protobuf field string service = 2; * @return string */ public function getService() { return $this->service; } /** * Specifies a service that was configured for Cloud Audit Logging. * For example, `storage.googleapis.com`, `cloudsql.googleapis.com`. * `allServices` is a special value that covers all services. * Required * * Generated from protobuf field string service = 2; * @param string $var * @return $this */ public function setService($var) { GPBUtil::checkString($var, True); $this->service = $var; return $this; } /** * A single identity that is exempted from "data access" audit * logging for the `service` specified above. * Follows the same format of Binding.members. * * Generated from protobuf field string exempted_member = 3; * @return string */ public function getExemptedMember() { return $this->exempted_member; } /** * A single identity that is exempted from "data access" audit * logging for the `service` specified above. * Follows the same format of Binding.members. * * Generated from protobuf field string exempted_member = 3; * @param string $var * @return $this */ public function setExemptedMember($var) { GPBUtil::checkString($var, True); $this->exempted_member = $var; return $this; } /** * Specifies the log_type that was be enabled. ADMIN_ACTIVITY is always * enabled, and cannot be configured. * Required * * Generated from protobuf field string log_type = 4; * @return string */ public function getLogType() { return $this->log_type; } /** * Specifies the log_type that was be enabled. ADMIN_ACTIVITY is always * enabled, and cannot be configured. * Required * * Generated from protobuf field string log_type = 4; * @param string $var * @return $this */ public function setLogType($var) { GPBUtil::checkString($var, True); $this->log_type = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Cloud/Iam/V1/AuditLogConfig/LogType.php ================================================ google.iam.v1.AuditLogConfig.LogType */ class LogType { /** * Default case. Should never be this. * * Generated from protobuf enum LOG_TYPE_UNSPECIFIED = 0; */ const LOG_TYPE_UNSPECIFIED = 0; /** * Admin reads. Example: CloudIAM getIamPolicy * * Generated from protobuf enum ADMIN_READ = 1; */ const ADMIN_READ = 1; /** * Data writes. Example: CloudSQL Users create * * Generated from protobuf enum DATA_WRITE = 2; */ const DATA_WRITE = 2; /** * Data reads. Example: CloudSQL Users list * * Generated from protobuf enum DATA_READ = 3; */ const DATA_READ = 3; private static $valueToName = [ self::LOG_TYPE_UNSPECIFIED => 'LOG_TYPE_UNSPECIFIED', self::ADMIN_READ => 'ADMIN_READ', self::DATA_WRITE => 'DATA_WRITE', self::DATA_READ => 'DATA_READ', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Cloud/Iam/V1/AuditLogConfig.php ================================================ google.iam.v1.AuditLogConfig */ class AuditLogConfig extends \Google\Protobuf\Internal\Message { /** * The log type that this config enables. * * Generated from protobuf field .google.iam.v1.AuditLogConfig.LogType log_type = 1; */ protected $log_type = 0; /** * Specifies the identities that do not cause logging for this type of * permission. * Follows the same format of * [Binding.members][google.iam.v1.Binding.members]. * * Generated from protobuf field repeated string exempted_members = 2; */ private $exempted_members; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type int $log_type * The log type that this config enables. * @type array|\Google\Protobuf\Internal\RepeatedField $exempted_members * Specifies the identities that do not cause logging for this type of * permission. * Follows the same format of * [Binding.members][google.iam.v1.Binding.members]. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Iam\V1\Policy::initOnce(); parent::__construct($data); } /** * The log type that this config enables. * * Generated from protobuf field .google.iam.v1.AuditLogConfig.LogType log_type = 1; * @return int */ public function getLogType() { return $this->log_type; } /** * The log type that this config enables. * * Generated from protobuf field .google.iam.v1.AuditLogConfig.LogType log_type = 1; * @param int $var * @return $this */ public function setLogType($var) { GPBUtil::checkEnum($var, \Google\Cloud\Iam\V1\AuditLogConfig\LogType::class); $this->log_type = $var; return $this; } /** * Specifies the identities that do not cause logging for this type of * permission. * Follows the same format of * [Binding.members][google.iam.v1.Binding.members]. * * Generated from protobuf field repeated string exempted_members = 2; * @return \Google\Protobuf\Internal\RepeatedField */ public function getExemptedMembers() { return $this->exempted_members; } /** * Specifies the identities that do not cause logging for this type of * permission. * Follows the same format of * [Binding.members][google.iam.v1.Binding.members]. * * Generated from protobuf field repeated string exempted_members = 2; * @param array|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setExemptedMembers($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->exempted_members = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Cloud/Iam/V1/Binding.php ================================================ google.iam.v1.Binding */ class Binding extends \Google\Protobuf\Internal\Message { /** * Role that is assigned to the list of `members`, or principals. * For example, `roles/viewer`, `roles/editor`, or `roles/owner`. * * Generated from protobuf field string role = 1; */ protected $role = ''; /** * Specifies the principals requesting access for a Google Cloud resource. * `members` can have the following values: * * `allUsers`: A special identifier that represents anyone who is * on the internet; with or without a Google account. * * `allAuthenticatedUsers`: A special identifier that represents anyone * who is authenticated with a Google account or a service account. * * `user:{emailid}`: An email address that represents a specific Google * account. For example, `alice@example.com` . * * `serviceAccount:{emailid}`: An email address that represents a service * account. For example, `my-other-app@appspot.gserviceaccount.com`. * * `group:{emailid}`: An email address that represents a Google group. * For example, `admins@example.com`. * * `deleted:user:{emailid}?uid={uniqueid}`: An email address (plus unique * identifier) representing a user that has been recently deleted. For * example, `alice@example.com?uid=123456789012345678901`. If the user is * recovered, this value reverts to `user:{emailid}` and the recovered user * retains the role in the binding. * * `deleted:serviceAccount:{emailid}?uid={uniqueid}`: An email address (plus * unique identifier) representing a service account that has been recently * deleted. For example, * `my-other-app@appspot.gserviceaccount.com?uid=123456789012345678901`. * If the service account is undeleted, this value reverts to * `serviceAccount:{emailid}` and the undeleted service account retains the * role in the binding. * * `deleted:group:{emailid}?uid={uniqueid}`: An email address (plus unique * identifier) representing a Google group that has been recently * deleted. For example, `admins@example.com?uid=123456789012345678901`. If * the group is recovered, this value reverts to `group:{emailid}` and the * recovered group retains the role in the binding. * * `domain:{domain}`: The G Suite domain (primary) that represents all the * users of that domain. For example, `google.com` or `example.com`. * * Generated from protobuf field repeated string members = 2; */ private $members; /** * The condition that is associated with this binding. * If the condition evaluates to `true`, then this binding applies to the * current request. * If the condition evaluates to `false`, then this binding does not apply to * the current request. However, a different role binding might grant the same * role to one or more of the principals in this binding. * To learn which resources support conditions in their IAM policies, see the * [IAM * documentation](https://cloud.google.com/iam/help/conditions/resource-policies). * * Generated from protobuf field .google.type.Expr condition = 3; */ protected $condition = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $role * Role that is assigned to the list of `members`, or principals. * For example, `roles/viewer`, `roles/editor`, or `roles/owner`. * @type array|\Google\Protobuf\Internal\RepeatedField $members * Specifies the principals requesting access for a Google Cloud resource. * `members` can have the following values: * * `allUsers`: A special identifier that represents anyone who is * on the internet; with or without a Google account. * * `allAuthenticatedUsers`: A special identifier that represents anyone * who is authenticated with a Google account or a service account. * * `user:{emailid}`: An email address that represents a specific Google * account. For example, `alice@example.com` . * * `serviceAccount:{emailid}`: An email address that represents a service * account. For example, `my-other-app@appspot.gserviceaccount.com`. * * `group:{emailid}`: An email address that represents a Google group. * For example, `admins@example.com`. * * `deleted:user:{emailid}?uid={uniqueid}`: An email address (plus unique * identifier) representing a user that has been recently deleted. For * example, `alice@example.com?uid=123456789012345678901`. If the user is * recovered, this value reverts to `user:{emailid}` and the recovered user * retains the role in the binding. * * `deleted:serviceAccount:{emailid}?uid={uniqueid}`: An email address (plus * unique identifier) representing a service account that has been recently * deleted. For example, * `my-other-app@appspot.gserviceaccount.com?uid=123456789012345678901`. * If the service account is undeleted, this value reverts to * `serviceAccount:{emailid}` and the undeleted service account retains the * role in the binding. * * `deleted:group:{emailid}?uid={uniqueid}`: An email address (plus unique * identifier) representing a Google group that has been recently * deleted. For example, `admins@example.com?uid=123456789012345678901`. If * the group is recovered, this value reverts to `group:{emailid}` and the * recovered group retains the role in the binding. * * `domain:{domain}`: The G Suite domain (primary) that represents all the * users of that domain. For example, `google.com` or `example.com`. * @type \Google\Type\Expr $condition * The condition that is associated with this binding. * If the condition evaluates to `true`, then this binding applies to the * current request. * If the condition evaluates to `false`, then this binding does not apply to * the current request. However, a different role binding might grant the same * role to one or more of the principals in this binding. * To learn which resources support conditions in their IAM policies, see the * [IAM * documentation](https://cloud.google.com/iam/help/conditions/resource-policies). * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Iam\V1\Policy::initOnce(); parent::__construct($data); } /** * Role that is assigned to the list of `members`, or principals. * For example, `roles/viewer`, `roles/editor`, or `roles/owner`. * * Generated from protobuf field string role = 1; * @return string */ public function getRole() { return $this->role; } /** * Role that is assigned to the list of `members`, or principals. * For example, `roles/viewer`, `roles/editor`, or `roles/owner`. * * Generated from protobuf field string role = 1; * @param string $var * @return $this */ public function setRole($var) { GPBUtil::checkString($var, True); $this->role = $var; return $this; } /** * Specifies the principals requesting access for a Google Cloud resource. * `members` can have the following values: * * `allUsers`: A special identifier that represents anyone who is * on the internet; with or without a Google account. * * `allAuthenticatedUsers`: A special identifier that represents anyone * who is authenticated with a Google account or a service account. * * `user:{emailid}`: An email address that represents a specific Google * account. For example, `alice@example.com` . * * `serviceAccount:{emailid}`: An email address that represents a service * account. For example, `my-other-app@appspot.gserviceaccount.com`. * * `group:{emailid}`: An email address that represents a Google group. * For example, `admins@example.com`. * * `deleted:user:{emailid}?uid={uniqueid}`: An email address (plus unique * identifier) representing a user that has been recently deleted. For * example, `alice@example.com?uid=123456789012345678901`. If the user is * recovered, this value reverts to `user:{emailid}` and the recovered user * retains the role in the binding. * * `deleted:serviceAccount:{emailid}?uid={uniqueid}`: An email address (plus * unique identifier) representing a service account that has been recently * deleted. For example, * `my-other-app@appspot.gserviceaccount.com?uid=123456789012345678901`. * If the service account is undeleted, this value reverts to * `serviceAccount:{emailid}` and the undeleted service account retains the * role in the binding. * * `deleted:group:{emailid}?uid={uniqueid}`: An email address (plus unique * identifier) representing a Google group that has been recently * deleted. For example, `admins@example.com?uid=123456789012345678901`. If * the group is recovered, this value reverts to `group:{emailid}` and the * recovered group retains the role in the binding. * * `domain:{domain}`: The G Suite domain (primary) that represents all the * users of that domain. For example, `google.com` or `example.com`. * * Generated from protobuf field repeated string members = 2; * @return \Google\Protobuf\Internal\RepeatedField */ public function getMembers() { return $this->members; } /** * Specifies the principals requesting access for a Google Cloud resource. * `members` can have the following values: * * `allUsers`: A special identifier that represents anyone who is * on the internet; with or without a Google account. * * `allAuthenticatedUsers`: A special identifier that represents anyone * who is authenticated with a Google account or a service account. * * `user:{emailid}`: An email address that represents a specific Google * account. For example, `alice@example.com` . * * `serviceAccount:{emailid}`: An email address that represents a service * account. For example, `my-other-app@appspot.gserviceaccount.com`. * * `group:{emailid}`: An email address that represents a Google group. * For example, `admins@example.com`. * * `deleted:user:{emailid}?uid={uniqueid}`: An email address (plus unique * identifier) representing a user that has been recently deleted. For * example, `alice@example.com?uid=123456789012345678901`. If the user is * recovered, this value reverts to `user:{emailid}` and the recovered user * retains the role in the binding. * * `deleted:serviceAccount:{emailid}?uid={uniqueid}`: An email address (plus * unique identifier) representing a service account that has been recently * deleted. For example, * `my-other-app@appspot.gserviceaccount.com?uid=123456789012345678901`. * If the service account is undeleted, this value reverts to * `serviceAccount:{emailid}` and the undeleted service account retains the * role in the binding. * * `deleted:group:{emailid}?uid={uniqueid}`: An email address (plus unique * identifier) representing a Google group that has been recently * deleted. For example, `admins@example.com?uid=123456789012345678901`. If * the group is recovered, this value reverts to `group:{emailid}` and the * recovered group retains the role in the binding. * * `domain:{domain}`: The G Suite domain (primary) that represents all the * users of that domain. For example, `google.com` or `example.com`. * * Generated from protobuf field repeated string members = 2; * @param array|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setMembers($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->members = $arr; return $this; } /** * The condition that is associated with this binding. * If the condition evaluates to `true`, then this binding applies to the * current request. * If the condition evaluates to `false`, then this binding does not apply to * the current request. However, a different role binding might grant the same * role to one or more of the principals in this binding. * To learn which resources support conditions in their IAM policies, see the * [IAM * documentation](https://cloud.google.com/iam/help/conditions/resource-policies). * * Generated from protobuf field .google.type.Expr condition = 3; * @return \Google\Type\Expr|null */ public function getCondition() { return $this->condition; } public function hasCondition() { return isset($this->condition); } public function clearCondition() { unset($this->condition); } /** * The condition that is associated with this binding. * If the condition evaluates to `true`, then this binding applies to the * current request. * If the condition evaluates to `false`, then this binding does not apply to * the current request. However, a different role binding might grant the same * role to one or more of the principals in this binding. * To learn which resources support conditions in their IAM policies, see the * [IAM * documentation](https://cloud.google.com/iam/help/conditions/resource-policies). * * Generated from protobuf field .google.type.Expr condition = 3; * @param \Google\Type\Expr $var * @return $this */ public function setCondition($var) { GPBUtil::checkMessage($var, \Google\Type\Expr::class); $this->condition = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Cloud/Iam/V1/BindingDelta/Action.php ================================================ google.iam.v1.BindingDelta.Action */ class Action { /** * Unspecified. * * Generated from protobuf enum ACTION_UNSPECIFIED = 0; */ const ACTION_UNSPECIFIED = 0; /** * Addition of a Binding. * * Generated from protobuf enum ADD = 1; */ const ADD = 1; /** * Removal of a Binding. * * Generated from protobuf enum REMOVE = 2; */ const REMOVE = 2; private static $valueToName = [ self::ACTION_UNSPECIFIED => 'ACTION_UNSPECIFIED', self::ADD => 'ADD', self::REMOVE => 'REMOVE', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Cloud/Iam/V1/BindingDelta.php ================================================ google.iam.v1.BindingDelta */ class BindingDelta extends \Google\Protobuf\Internal\Message { /** * The action that was performed on a Binding. * Required * * Generated from protobuf field .google.iam.v1.BindingDelta.Action action = 1; */ protected $action = 0; /** * Role that is assigned to `members`. * For example, `roles/viewer`, `roles/editor`, or `roles/owner`. * Required * * Generated from protobuf field string role = 2; */ protected $role = ''; /** * A single identity requesting access for a Google Cloud resource. * Follows the same format of Binding.members. * Required * * Generated from protobuf field string member = 3; */ protected $member = ''; /** * The condition that is associated with this binding. * * Generated from protobuf field .google.type.Expr condition = 4; */ protected $condition = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type int $action * The action that was performed on a Binding. * Required * @type string $role * Role that is assigned to `members`. * For example, `roles/viewer`, `roles/editor`, or `roles/owner`. * Required * @type string $member * A single identity requesting access for a Google Cloud resource. * Follows the same format of Binding.members. * Required * @type \Google\Type\Expr $condition * The condition that is associated with this binding. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Iam\V1\Policy::initOnce(); parent::__construct($data); } /** * The action that was performed on a Binding. * Required * * Generated from protobuf field .google.iam.v1.BindingDelta.Action action = 1; * @return int */ public function getAction() { return $this->action; } /** * The action that was performed on a Binding. * Required * * Generated from protobuf field .google.iam.v1.BindingDelta.Action action = 1; * @param int $var * @return $this */ public function setAction($var) { GPBUtil::checkEnum($var, \Google\Cloud\Iam\V1\BindingDelta\Action::class); $this->action = $var; return $this; } /** * Role that is assigned to `members`. * For example, `roles/viewer`, `roles/editor`, or `roles/owner`. * Required * * Generated from protobuf field string role = 2; * @return string */ public function getRole() { return $this->role; } /** * Role that is assigned to `members`. * For example, `roles/viewer`, `roles/editor`, or `roles/owner`. * Required * * Generated from protobuf field string role = 2; * @param string $var * @return $this */ public function setRole($var) { GPBUtil::checkString($var, True); $this->role = $var; return $this; } /** * A single identity requesting access for a Google Cloud resource. * Follows the same format of Binding.members. * Required * * Generated from protobuf field string member = 3; * @return string */ public function getMember() { return $this->member; } /** * A single identity requesting access for a Google Cloud resource. * Follows the same format of Binding.members. * Required * * Generated from protobuf field string member = 3; * @param string $var * @return $this */ public function setMember($var) { GPBUtil::checkString($var, True); $this->member = $var; return $this; } /** * The condition that is associated with this binding. * * Generated from protobuf field .google.type.Expr condition = 4; * @return \Google\Type\Expr|null */ public function getCondition() { return $this->condition; } public function hasCondition() { return isset($this->condition); } public function clearCondition() { unset($this->condition); } /** * The condition that is associated with this binding. * * Generated from protobuf field .google.type.Expr condition = 4; * @param \Google\Type\Expr $var * @return $this */ public function setCondition($var) { GPBUtil::checkMessage($var, \Google\Type\Expr::class); $this->condition = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Cloud/Iam/V1/GetIamPolicyRequest.php ================================================ google.iam.v1.GetIamPolicyRequest */ class GetIamPolicyRequest extends \Google\Protobuf\Internal\Message { /** * REQUIRED: The resource for which the policy is being requested. * See the operation documentation for the appropriate value for this field. * * Generated from protobuf field string resource = 1 [(.google.api.field_behavior) = REQUIRED, (.google.api.resource_reference) = { */ protected $resource = ''; /** * OPTIONAL: A `GetPolicyOptions` object for specifying options to * `GetIamPolicy`. * * Generated from protobuf field .google.iam.v1.GetPolicyOptions options = 2; */ protected $options = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $resource * REQUIRED: The resource for which the policy is being requested. * See the operation documentation for the appropriate value for this field. * @type \Google\Cloud\Iam\V1\GetPolicyOptions $options * OPTIONAL: A `GetPolicyOptions` object for specifying options to * `GetIamPolicy`. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Iam\V1\IamPolicy::initOnce(); parent::__construct($data); } /** * REQUIRED: The resource for which the policy is being requested. * See the operation documentation for the appropriate value for this field. * * Generated from protobuf field string resource = 1 [(.google.api.field_behavior) = REQUIRED, (.google.api.resource_reference) = { * @return string */ public function getResource() { return $this->resource; } /** * REQUIRED: The resource for which the policy is being requested. * See the operation documentation for the appropriate value for this field. * * Generated from protobuf field string resource = 1 [(.google.api.field_behavior) = REQUIRED, (.google.api.resource_reference) = { * @param string $var * @return $this */ public function setResource($var) { GPBUtil::checkString($var, True); $this->resource = $var; return $this; } /** * OPTIONAL: A `GetPolicyOptions` object for specifying options to * `GetIamPolicy`. * * Generated from protobuf field .google.iam.v1.GetPolicyOptions options = 2; * @return \Google\Cloud\Iam\V1\GetPolicyOptions|null */ public function getOptions() { return $this->options; } public function hasOptions() { return isset($this->options); } public function clearOptions() { unset($this->options); } /** * OPTIONAL: A `GetPolicyOptions` object for specifying options to * `GetIamPolicy`. * * Generated from protobuf field .google.iam.v1.GetPolicyOptions options = 2; * @param \Google\Cloud\Iam\V1\GetPolicyOptions $var * @return $this */ public function setOptions($var) { GPBUtil::checkMessage($var, \Google\Cloud\Iam\V1\GetPolicyOptions::class); $this->options = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Cloud/Iam/V1/GetPolicyOptions.php ================================================ google.iam.v1.GetPolicyOptions */ class GetPolicyOptions extends \Google\Protobuf\Internal\Message { /** * Optional. The maximum policy version that will be used to format the * policy. * Valid values are 0, 1, and 3. Requests specifying an invalid value will be * rejected. * Requests for policies with any conditional role bindings must specify * version 3. Policies with no conditional role bindings may specify any valid * value or leave the field unset. * The policy in the response might use the policy version that you specified, * or it might use a lower policy version. For example, if you specify version * 3, but the policy has no conditional role bindings, the response uses * version 1. * To learn which resources support conditions in their IAM policies, see the * [IAM * documentation](https://cloud.google.com/iam/help/conditions/resource-policies). * * Generated from protobuf field int32 requested_policy_version = 1; */ protected $requested_policy_version = 0; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type int $requested_policy_version * Optional. The maximum policy version that will be used to format the * policy. * Valid values are 0, 1, and 3. Requests specifying an invalid value will be * rejected. * Requests for policies with any conditional role bindings must specify * version 3. Policies with no conditional role bindings may specify any valid * value or leave the field unset. * The policy in the response might use the policy version that you specified, * or it might use a lower policy version. For example, if you specify version * 3, but the policy has no conditional role bindings, the response uses * version 1. * To learn which resources support conditions in their IAM policies, see the * [IAM * documentation](https://cloud.google.com/iam/help/conditions/resource-policies). * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Iam\V1\Options::initOnce(); parent::__construct($data); } /** * Optional. The maximum policy version that will be used to format the * policy. * Valid values are 0, 1, and 3. Requests specifying an invalid value will be * rejected. * Requests for policies with any conditional role bindings must specify * version 3. Policies with no conditional role bindings may specify any valid * value or leave the field unset. * The policy in the response might use the policy version that you specified, * or it might use a lower policy version. For example, if you specify version * 3, but the policy has no conditional role bindings, the response uses * version 1. * To learn which resources support conditions in their IAM policies, see the * [IAM * documentation](https://cloud.google.com/iam/help/conditions/resource-policies). * * Generated from protobuf field int32 requested_policy_version = 1; * @return int */ public function getRequestedPolicyVersion() { return $this->requested_policy_version; } /** * Optional. The maximum policy version that will be used to format the * policy. * Valid values are 0, 1, and 3. Requests specifying an invalid value will be * rejected. * Requests for policies with any conditional role bindings must specify * version 3. Policies with no conditional role bindings may specify any valid * value or leave the field unset. * The policy in the response might use the policy version that you specified, * or it might use a lower policy version. For example, if you specify version * 3, but the policy has no conditional role bindings, the response uses * version 1. * To learn which resources support conditions in their IAM policies, see the * [IAM * documentation](https://cloud.google.com/iam/help/conditions/resource-policies). * * Generated from protobuf field int32 requested_policy_version = 1; * @param int $var * @return $this */ public function setRequestedPolicyVersion($var) { GPBUtil::checkInt32($var); $this->requested_policy_version = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Cloud/Iam/V1/Policy.php ================================================ google.iam.v1.Policy */ class Policy extends \Google\Protobuf\Internal\Message { /** * Specifies the format of the policy. * Valid values are `0`, `1`, and `3`. Requests that specify an invalid value * are rejected. * Any operation that affects conditional role bindings must specify version * `3`. This requirement applies to the following operations: * * Getting a policy that includes a conditional role binding * * Adding a conditional role binding to a policy * * Changing a conditional role binding in a policy * * Removing any role binding, with or without a condition, from a policy * that includes conditions * **Important:** If you use IAM Conditions, you must include the `etag` field * whenever you call `setIamPolicy`. If you omit this field, then IAM allows * you to overwrite a version `3` policy with a version `1` policy, and all of * the conditions in the version `3` policy are lost. * If a policy does not include any conditions, operations on that policy may * specify any valid version or leave the field unset. * To learn which resources support conditions in their IAM policies, see the * [IAM * documentation](https://cloud.google.com/iam/help/conditions/resource-policies). * * Generated from protobuf field int32 version = 1; */ protected $version = 0; /** * Associates a list of `members`, or principals, with a `role`. Optionally, * may specify a `condition` that determines how and when the `bindings` are * applied. Each of the `bindings` must contain at least one principal. * The `bindings` in a `Policy` can refer to up to 1,500 principals; up to 250 * of these principals can be Google groups. Each occurrence of a principal * counts towards these limits. For example, if the `bindings` grant 50 * different roles to `user:alice@example.com`, and not to any other * principal, then you can add another 1,450 principals to the `bindings` in * the `Policy`. * * Generated from protobuf field repeated .google.iam.v1.Binding bindings = 4; */ private $bindings; /** * Specifies cloud audit logging configuration for this policy. * * Generated from protobuf field repeated .google.iam.v1.AuditConfig audit_configs = 6; */ private $audit_configs; /** * `etag` is used for optimistic concurrency control as a way to help * prevent simultaneous updates of a policy from overwriting each other. * It is strongly suggested that systems make use of the `etag` in the * read-modify-write cycle to perform policy updates in order to avoid race * conditions: An `etag` is returned in the response to `getIamPolicy`, and * systems are expected to put that etag in the request to `setIamPolicy` to * ensure that their change will be applied to the same version of the policy. * **Important:** If you use IAM Conditions, you must include the `etag` field * whenever you call `setIamPolicy`. If you omit this field, then IAM allows * you to overwrite a version `3` policy with a version `1` policy, and all of * the conditions in the version `3` policy are lost. * * Generated from protobuf field bytes etag = 3; */ protected $etag = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type int $version * Specifies the format of the policy. * Valid values are `0`, `1`, and `3`. Requests that specify an invalid value * are rejected. * Any operation that affects conditional role bindings must specify version * `3`. This requirement applies to the following operations: * * Getting a policy that includes a conditional role binding * * Adding a conditional role binding to a policy * * Changing a conditional role binding in a policy * * Removing any role binding, with or without a condition, from a policy * that includes conditions * **Important:** If you use IAM Conditions, you must include the `etag` field * whenever you call `setIamPolicy`. If you omit this field, then IAM allows * you to overwrite a version `3` policy with a version `1` policy, and all of * the conditions in the version `3` policy are lost. * If a policy does not include any conditions, operations on that policy may * specify any valid version or leave the field unset. * To learn which resources support conditions in their IAM policies, see the * [IAM * documentation](https://cloud.google.com/iam/help/conditions/resource-policies). * @type array<\Google\Cloud\Iam\V1\Binding>|\Google\Protobuf\Internal\RepeatedField $bindings * Associates a list of `members`, or principals, with a `role`. Optionally, * may specify a `condition` that determines how and when the `bindings` are * applied. Each of the `bindings` must contain at least one principal. * The `bindings` in a `Policy` can refer to up to 1,500 principals; up to 250 * of these principals can be Google groups. Each occurrence of a principal * counts towards these limits. For example, if the `bindings` grant 50 * different roles to `user:alice@example.com`, and not to any other * principal, then you can add another 1,450 principals to the `bindings` in * the `Policy`. * @type array<\Google\Cloud\Iam\V1\AuditConfig>|\Google\Protobuf\Internal\RepeatedField $audit_configs * Specifies cloud audit logging configuration for this policy. * @type string $etag * `etag` is used for optimistic concurrency control as a way to help * prevent simultaneous updates of a policy from overwriting each other. * It is strongly suggested that systems make use of the `etag` in the * read-modify-write cycle to perform policy updates in order to avoid race * conditions: An `etag` is returned in the response to `getIamPolicy`, and * systems are expected to put that etag in the request to `setIamPolicy` to * ensure that their change will be applied to the same version of the policy. * **Important:** If you use IAM Conditions, you must include the `etag` field * whenever you call `setIamPolicy`. If you omit this field, then IAM allows * you to overwrite a version `3` policy with a version `1` policy, and all of * the conditions in the version `3` policy are lost. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Iam\V1\Policy::initOnce(); parent::__construct($data); } /** * Specifies the format of the policy. * Valid values are `0`, `1`, and `3`. Requests that specify an invalid value * are rejected. * Any operation that affects conditional role bindings must specify version * `3`. This requirement applies to the following operations: * * Getting a policy that includes a conditional role binding * * Adding a conditional role binding to a policy * * Changing a conditional role binding in a policy * * Removing any role binding, with or without a condition, from a policy * that includes conditions * **Important:** If you use IAM Conditions, you must include the `etag` field * whenever you call `setIamPolicy`. If you omit this field, then IAM allows * you to overwrite a version `3` policy with a version `1` policy, and all of * the conditions in the version `3` policy are lost. * If a policy does not include any conditions, operations on that policy may * specify any valid version or leave the field unset. * To learn which resources support conditions in their IAM policies, see the * [IAM * documentation](https://cloud.google.com/iam/help/conditions/resource-policies). * * Generated from protobuf field int32 version = 1; * @return int */ public function getVersion() { return $this->version; } /** * Specifies the format of the policy. * Valid values are `0`, `1`, and `3`. Requests that specify an invalid value * are rejected. * Any operation that affects conditional role bindings must specify version * `3`. This requirement applies to the following operations: * * Getting a policy that includes a conditional role binding * * Adding a conditional role binding to a policy * * Changing a conditional role binding in a policy * * Removing any role binding, with or without a condition, from a policy * that includes conditions * **Important:** If you use IAM Conditions, you must include the `etag` field * whenever you call `setIamPolicy`. If you omit this field, then IAM allows * you to overwrite a version `3` policy with a version `1` policy, and all of * the conditions in the version `3` policy are lost. * If a policy does not include any conditions, operations on that policy may * specify any valid version or leave the field unset. * To learn which resources support conditions in their IAM policies, see the * [IAM * documentation](https://cloud.google.com/iam/help/conditions/resource-policies). * * Generated from protobuf field int32 version = 1; * @param int $var * @return $this */ public function setVersion($var) { GPBUtil::checkInt32($var); $this->version = $var; return $this; } /** * Associates a list of `members`, or principals, with a `role`. Optionally, * may specify a `condition` that determines how and when the `bindings` are * applied. Each of the `bindings` must contain at least one principal. * The `bindings` in a `Policy` can refer to up to 1,500 principals; up to 250 * of these principals can be Google groups. Each occurrence of a principal * counts towards these limits. For example, if the `bindings` grant 50 * different roles to `user:alice@example.com`, and not to any other * principal, then you can add another 1,450 principals to the `bindings` in * the `Policy`. * * Generated from protobuf field repeated .google.iam.v1.Binding bindings = 4; * @return \Google\Protobuf\Internal\RepeatedField */ public function getBindings() { return $this->bindings; } /** * Associates a list of `members`, or principals, with a `role`. Optionally, * may specify a `condition` that determines how and when the `bindings` are * applied. Each of the `bindings` must contain at least one principal. * The `bindings` in a `Policy` can refer to up to 1,500 principals; up to 250 * of these principals can be Google groups. Each occurrence of a principal * counts towards these limits. For example, if the `bindings` grant 50 * different roles to `user:alice@example.com`, and not to any other * principal, then you can add another 1,450 principals to the `bindings` in * the `Policy`. * * Generated from protobuf field repeated .google.iam.v1.Binding bindings = 4; * @param array<\Google\Cloud\Iam\V1\Binding>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setBindings($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Cloud\Iam\V1\Binding::class); $this->bindings = $arr; return $this; } /** * Specifies cloud audit logging configuration for this policy. * * Generated from protobuf field repeated .google.iam.v1.AuditConfig audit_configs = 6; * @return \Google\Protobuf\Internal\RepeatedField */ public function getAuditConfigs() { return $this->audit_configs; } /** * Specifies cloud audit logging configuration for this policy. * * Generated from protobuf field repeated .google.iam.v1.AuditConfig audit_configs = 6; * @param array<\Google\Cloud\Iam\V1\AuditConfig>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setAuditConfigs($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Cloud\Iam\V1\AuditConfig::class); $this->audit_configs = $arr; return $this; } /** * `etag` is used for optimistic concurrency control as a way to help * prevent simultaneous updates of a policy from overwriting each other. * It is strongly suggested that systems make use of the `etag` in the * read-modify-write cycle to perform policy updates in order to avoid race * conditions: An `etag` is returned in the response to `getIamPolicy`, and * systems are expected to put that etag in the request to `setIamPolicy` to * ensure that their change will be applied to the same version of the policy. * **Important:** If you use IAM Conditions, you must include the `etag` field * whenever you call `setIamPolicy`. If you omit this field, then IAM allows * you to overwrite a version `3` policy with a version `1` policy, and all of * the conditions in the version `3` policy are lost. * * Generated from protobuf field bytes etag = 3; * @return string */ public function getEtag() { return $this->etag; } /** * `etag` is used for optimistic concurrency control as a way to help * prevent simultaneous updates of a policy from overwriting each other. * It is strongly suggested that systems make use of the `etag` in the * read-modify-write cycle to perform policy updates in order to avoid race * conditions: An `etag` is returned in the response to `getIamPolicy`, and * systems are expected to put that etag in the request to `setIamPolicy` to * ensure that their change will be applied to the same version of the policy. * **Important:** If you use IAM Conditions, you must include the `etag` field * whenever you call `setIamPolicy`. If you omit this field, then IAM allows * you to overwrite a version `3` policy with a version `1` policy, and all of * the conditions in the version `3` policy are lost. * * Generated from protobuf field bytes etag = 3; * @param string $var * @return $this */ public function setEtag($var) { GPBUtil::checkString($var, False); $this->etag = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Cloud/Iam/V1/PolicyDelta.php ================================================ google.iam.v1.PolicyDelta */ class PolicyDelta extends \Google\Protobuf\Internal\Message { /** * The delta for Bindings between two policies. * * Generated from protobuf field repeated .google.iam.v1.BindingDelta binding_deltas = 1; */ private $binding_deltas; /** * The delta for AuditConfigs between two policies. * * Generated from protobuf field repeated .google.iam.v1.AuditConfigDelta audit_config_deltas = 2; */ private $audit_config_deltas; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type array<\Google\Cloud\Iam\V1\BindingDelta>|\Google\Protobuf\Internal\RepeatedField $binding_deltas * The delta for Bindings between two policies. * @type array<\Google\Cloud\Iam\V1\AuditConfigDelta>|\Google\Protobuf\Internal\RepeatedField $audit_config_deltas * The delta for AuditConfigs between two policies. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Iam\V1\Policy::initOnce(); parent::__construct($data); } /** * The delta for Bindings between two policies. * * Generated from protobuf field repeated .google.iam.v1.BindingDelta binding_deltas = 1; * @return \Google\Protobuf\Internal\RepeatedField */ public function getBindingDeltas() { return $this->binding_deltas; } /** * The delta for Bindings between two policies. * * Generated from protobuf field repeated .google.iam.v1.BindingDelta binding_deltas = 1; * @param array<\Google\Cloud\Iam\V1\BindingDelta>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setBindingDeltas($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Cloud\Iam\V1\BindingDelta::class); $this->binding_deltas = $arr; return $this; } /** * The delta for AuditConfigs between two policies. * * Generated from protobuf field repeated .google.iam.v1.AuditConfigDelta audit_config_deltas = 2; * @return \Google\Protobuf\Internal\RepeatedField */ public function getAuditConfigDeltas() { return $this->audit_config_deltas; } /** * The delta for AuditConfigs between two policies. * * Generated from protobuf field repeated .google.iam.v1.AuditConfigDelta audit_config_deltas = 2; * @param array<\Google\Cloud\Iam\V1\AuditConfigDelta>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setAuditConfigDeltas($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Cloud\Iam\V1\AuditConfigDelta::class); $this->audit_config_deltas = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Cloud/Iam/V1/ResourcePolicyMember.php ================================================ google.iam.v1.ResourcePolicyMember */ class ResourcePolicyMember extends \Google\Protobuf\Internal\Message { /** * IAM policy binding member referring to a Google Cloud resource by * user-assigned name (https://google.aip.dev/122). If a resource is deleted * and recreated with the same name, the binding will be applicable to the new * resource. * Example: * `principal://parametermanager.googleapis.com/projects/12345/name/locations/us-central1-a/parameters/my-parameter` * * Generated from protobuf field string iam_policy_name_principal = 1 [(.google.api.field_behavior) = OUTPUT_ONLY]; */ protected $iam_policy_name_principal = ''; /** * IAM policy binding member referring to a Google Cloud resource by * system-assigned unique identifier (https://google.aip.dev/148#uid). If a * resource is deleted and recreated with the same name, the binding will not * be applicable to the new resource * Example: * `principal://parametermanager.googleapis.com/projects/12345/uid/locations/us-central1-a/parameters/a918fed5` * * Generated from protobuf field string iam_policy_uid_principal = 2 [(.google.api.field_behavior) = OUTPUT_ONLY]; */ protected $iam_policy_uid_principal = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $iam_policy_name_principal * IAM policy binding member referring to a Google Cloud resource by * user-assigned name (https://google.aip.dev/122). If a resource is deleted * and recreated with the same name, the binding will be applicable to the new * resource. * Example: * `principal://parametermanager.googleapis.com/projects/12345/name/locations/us-central1-a/parameters/my-parameter` * @type string $iam_policy_uid_principal * IAM policy binding member referring to a Google Cloud resource by * system-assigned unique identifier (https://google.aip.dev/148#uid). If a * resource is deleted and recreated with the same name, the binding will not * be applicable to the new resource * Example: * `principal://parametermanager.googleapis.com/projects/12345/uid/locations/us-central1-a/parameters/a918fed5` * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Iam\V1\ResourcePolicyMember::initOnce(); parent::__construct($data); } /** * IAM policy binding member referring to a Google Cloud resource by * user-assigned name (https://google.aip.dev/122). If a resource is deleted * and recreated with the same name, the binding will be applicable to the new * resource. * Example: * `principal://parametermanager.googleapis.com/projects/12345/name/locations/us-central1-a/parameters/my-parameter` * * Generated from protobuf field string iam_policy_name_principal = 1 [(.google.api.field_behavior) = OUTPUT_ONLY]; * @return string */ public function getIamPolicyNamePrincipal() { return $this->iam_policy_name_principal; } /** * IAM policy binding member referring to a Google Cloud resource by * user-assigned name (https://google.aip.dev/122). If a resource is deleted * and recreated with the same name, the binding will be applicable to the new * resource. * Example: * `principal://parametermanager.googleapis.com/projects/12345/name/locations/us-central1-a/parameters/my-parameter` * * Generated from protobuf field string iam_policy_name_principal = 1 [(.google.api.field_behavior) = OUTPUT_ONLY]; * @param string $var * @return $this */ public function setIamPolicyNamePrincipal($var) { GPBUtil::checkString($var, True); $this->iam_policy_name_principal = $var; return $this; } /** * IAM policy binding member referring to a Google Cloud resource by * system-assigned unique identifier (https://google.aip.dev/148#uid). If a * resource is deleted and recreated with the same name, the binding will not * be applicable to the new resource * Example: * `principal://parametermanager.googleapis.com/projects/12345/uid/locations/us-central1-a/parameters/a918fed5` * * Generated from protobuf field string iam_policy_uid_principal = 2 [(.google.api.field_behavior) = OUTPUT_ONLY]; * @return string */ public function getIamPolicyUidPrincipal() { return $this->iam_policy_uid_principal; } /** * IAM policy binding member referring to a Google Cloud resource by * system-assigned unique identifier (https://google.aip.dev/148#uid). If a * resource is deleted and recreated with the same name, the binding will not * be applicable to the new resource * Example: * `principal://parametermanager.googleapis.com/projects/12345/uid/locations/us-central1-a/parameters/a918fed5` * * Generated from protobuf field string iam_policy_uid_principal = 2 [(.google.api.field_behavior) = OUTPUT_ONLY]; * @param string $var * @return $this */ public function setIamPolicyUidPrincipal($var) { GPBUtil::checkString($var, True); $this->iam_policy_uid_principal = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Cloud/Iam/V1/SetIamPolicyRequest.php ================================================ google.iam.v1.SetIamPolicyRequest */ class SetIamPolicyRequest extends \Google\Protobuf\Internal\Message { /** * REQUIRED: The resource for which the policy is being specified. * See the operation documentation for the appropriate value for this field. * * Generated from protobuf field string resource = 1 [(.google.api.field_behavior) = REQUIRED, (.google.api.resource_reference) = { */ protected $resource = ''; /** * REQUIRED: The complete policy to be applied to the `resource`. The size of * the policy is limited to a few 10s of KB. An empty policy is a * valid policy but certain Cloud Platform services (such as Projects) * might reject them. * * Generated from protobuf field .google.iam.v1.Policy policy = 2 [(.google.api.field_behavior) = REQUIRED]; */ protected $policy = null; /** * OPTIONAL: A FieldMask specifying which fields of the policy to modify. Only * the fields in the mask will be modified. If no mask is provided, the * following default mask is used: * `paths: "bindings, etag"` * * Generated from protobuf field .google.protobuf.FieldMask update_mask = 3; */ protected $update_mask = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $resource * REQUIRED: The resource for which the policy is being specified. * See the operation documentation for the appropriate value for this field. * @type \Google\Cloud\Iam\V1\Policy $policy * REQUIRED: The complete policy to be applied to the `resource`. The size of * the policy is limited to a few 10s of KB. An empty policy is a * valid policy but certain Cloud Platform services (such as Projects) * might reject them. * @type \Google\Protobuf\FieldMask $update_mask * OPTIONAL: A FieldMask specifying which fields of the policy to modify. Only * the fields in the mask will be modified. If no mask is provided, the * following default mask is used: * `paths: "bindings, etag"` * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Iam\V1\IamPolicy::initOnce(); parent::__construct($data); } /** * REQUIRED: The resource for which the policy is being specified. * See the operation documentation for the appropriate value for this field. * * Generated from protobuf field string resource = 1 [(.google.api.field_behavior) = REQUIRED, (.google.api.resource_reference) = { * @return string */ public function getResource() { return $this->resource; } /** * REQUIRED: The resource for which the policy is being specified. * See the operation documentation for the appropriate value for this field. * * Generated from protobuf field string resource = 1 [(.google.api.field_behavior) = REQUIRED, (.google.api.resource_reference) = { * @param string $var * @return $this */ public function setResource($var) { GPBUtil::checkString($var, True); $this->resource = $var; return $this; } /** * REQUIRED: The complete policy to be applied to the `resource`. The size of * the policy is limited to a few 10s of KB. An empty policy is a * valid policy but certain Cloud Platform services (such as Projects) * might reject them. * * Generated from protobuf field .google.iam.v1.Policy policy = 2 [(.google.api.field_behavior) = REQUIRED]; * @return \Google\Cloud\Iam\V1\Policy|null */ public function getPolicy() { return $this->policy; } public function hasPolicy() { return isset($this->policy); } public function clearPolicy() { unset($this->policy); } /** * REQUIRED: The complete policy to be applied to the `resource`. The size of * the policy is limited to a few 10s of KB. An empty policy is a * valid policy but certain Cloud Platform services (such as Projects) * might reject them. * * Generated from protobuf field .google.iam.v1.Policy policy = 2 [(.google.api.field_behavior) = REQUIRED]; * @param \Google\Cloud\Iam\V1\Policy $var * @return $this */ public function setPolicy($var) { GPBUtil::checkMessage($var, \Google\Cloud\Iam\V1\Policy::class); $this->policy = $var; return $this; } /** * OPTIONAL: A FieldMask specifying which fields of the policy to modify. Only * the fields in the mask will be modified. If no mask is provided, the * following default mask is used: * `paths: "bindings, etag"` * * Generated from protobuf field .google.protobuf.FieldMask update_mask = 3; * @return \Google\Protobuf\FieldMask|null */ public function getUpdateMask() { return $this->update_mask; } public function hasUpdateMask() { return isset($this->update_mask); } public function clearUpdateMask() { unset($this->update_mask); } /** * OPTIONAL: A FieldMask specifying which fields of the policy to modify. Only * the fields in the mask will be modified. If no mask is provided, the * following default mask is used: * `paths: "bindings, etag"` * * Generated from protobuf field .google.protobuf.FieldMask update_mask = 3; * @param \Google\Protobuf\FieldMask $var * @return $this */ public function setUpdateMask($var) { GPBUtil::checkMessage($var, \Google\Protobuf\FieldMask::class); $this->update_mask = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Cloud/Iam/V1/TestIamPermissionsRequest.php ================================================ google.iam.v1.TestIamPermissionsRequest */ class TestIamPermissionsRequest extends \Google\Protobuf\Internal\Message { /** * REQUIRED: The resource for which the policy detail is being requested. * See the operation documentation for the appropriate value for this field. * * Generated from protobuf field string resource = 1 [(.google.api.field_behavior) = REQUIRED, (.google.api.resource_reference) = { */ protected $resource = ''; /** * The set of permissions to check for the `resource`. Permissions with * wildcards (such as '*' or 'storage.*') are not allowed. For more * information see * [IAM Overview](https://cloud.google.com/iam/docs/overview#permissions). * * Generated from protobuf field repeated string permissions = 2 [(.google.api.field_behavior) = REQUIRED]; */ private $permissions; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $resource * REQUIRED: The resource for which the policy detail is being requested. * See the operation documentation for the appropriate value for this field. * @type array|\Google\Protobuf\Internal\RepeatedField $permissions * The set of permissions to check for the `resource`. Permissions with * wildcards (such as '*' or 'storage.*') are not allowed. For more * information see * [IAM Overview](https://cloud.google.com/iam/docs/overview#permissions). * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Iam\V1\IamPolicy::initOnce(); parent::__construct($data); } /** * REQUIRED: The resource for which the policy detail is being requested. * See the operation documentation for the appropriate value for this field. * * Generated from protobuf field string resource = 1 [(.google.api.field_behavior) = REQUIRED, (.google.api.resource_reference) = { * @return string */ public function getResource() { return $this->resource; } /** * REQUIRED: The resource for which the policy detail is being requested. * See the operation documentation for the appropriate value for this field. * * Generated from protobuf field string resource = 1 [(.google.api.field_behavior) = REQUIRED, (.google.api.resource_reference) = { * @param string $var * @return $this */ public function setResource($var) { GPBUtil::checkString($var, True); $this->resource = $var; return $this; } /** * The set of permissions to check for the `resource`. Permissions with * wildcards (such as '*' or 'storage.*') are not allowed. For more * information see * [IAM Overview](https://cloud.google.com/iam/docs/overview#permissions). * * Generated from protobuf field repeated string permissions = 2 [(.google.api.field_behavior) = REQUIRED]; * @return \Google\Protobuf\Internal\RepeatedField */ public function getPermissions() { return $this->permissions; } /** * The set of permissions to check for the `resource`. Permissions with * wildcards (such as '*' or 'storage.*') are not allowed. For more * information see * [IAM Overview](https://cloud.google.com/iam/docs/overview#permissions). * * Generated from protobuf field repeated string permissions = 2 [(.google.api.field_behavior) = REQUIRED]; * @param array|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setPermissions($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->permissions = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Cloud/Iam/V1/TestIamPermissionsResponse.php ================================================ google.iam.v1.TestIamPermissionsResponse */ class TestIamPermissionsResponse extends \Google\Protobuf\Internal\Message { /** * A subset of `TestPermissionsRequest.permissions` that the caller is * allowed. * * Generated from protobuf field repeated string permissions = 1; */ private $permissions; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type array|\Google\Protobuf\Internal\RepeatedField $permissions * A subset of `TestPermissionsRequest.permissions` that the caller is * allowed. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Iam\V1\IamPolicy::initOnce(); parent::__construct($data); } /** * A subset of `TestPermissionsRequest.permissions` that the caller is * allowed. * * Generated from protobuf field repeated string permissions = 1; * @return \Google\Protobuf\Internal\RepeatedField */ public function getPermissions() { return $this->permissions; } /** * A subset of `TestPermissionsRequest.permissions` that the caller is * allowed. * * Generated from protobuf field repeated string permissions = 1; * @param array|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setPermissions($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->permissions = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Cloud/Location/GetLocationRequest.php ================================================ google.cloud.location.GetLocationRequest */ class GetLocationRequest extends \Google\Protobuf\Internal\Message { /** * Resource name for the location. * * Generated from protobuf field string name = 1; */ protected $name = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $name * Resource name for the location. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Cloud\Location\Locations::initOnce(); parent::__construct($data); } /** * Resource name for the location. * * Generated from protobuf field string name = 1; * @return string */ public function getName() { return $this->name; } /** * Resource name for the location. * * Generated from protobuf field string name = 1; * @param string $var * @return $this */ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Cloud/Location/ListLocationsRequest.php ================================================ google.cloud.location.ListLocationsRequest */ class ListLocationsRequest extends \Google\Protobuf\Internal\Message { /** * The resource that owns the locations collection, if applicable. * * Generated from protobuf field string name = 1; */ protected $name = ''; /** * The standard list filter. * * Generated from protobuf field string filter = 2; */ protected $filter = ''; /** * The standard list page size. * * Generated from protobuf field int32 page_size = 3; */ protected $page_size = 0; /** * The standard list page token. * * Generated from protobuf field string page_token = 4; */ protected $page_token = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $name * The resource that owns the locations collection, if applicable. * @type string $filter * The standard list filter. * @type int $page_size * The standard list page size. * @type string $page_token * The standard list page token. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Cloud\Location\Locations::initOnce(); parent::__construct($data); } /** * The resource that owns the locations collection, if applicable. * * Generated from protobuf field string name = 1; * @return string */ public function getName() { return $this->name; } /** * The resource that owns the locations collection, if applicable. * * Generated from protobuf field string name = 1; * @param string $var * @return $this */ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; return $this; } /** * The standard list filter. * * Generated from protobuf field string filter = 2; * @return string */ public function getFilter() { return $this->filter; } /** * The standard list filter. * * Generated from protobuf field string filter = 2; * @param string $var * @return $this */ public function setFilter($var) { GPBUtil::checkString($var, True); $this->filter = $var; return $this; } /** * The standard list page size. * * Generated from protobuf field int32 page_size = 3; * @return int */ public function getPageSize() { return $this->page_size; } /** * The standard list page size. * * Generated from protobuf field int32 page_size = 3; * @param int $var * @return $this */ public function setPageSize($var) { GPBUtil::checkInt32($var); $this->page_size = $var; return $this; } /** * The standard list page token. * * Generated from protobuf field string page_token = 4; * @return string */ public function getPageToken() { return $this->page_token; } /** * The standard list page token. * * Generated from protobuf field string page_token = 4; * @param string $var * @return $this */ public function setPageToken($var) { GPBUtil::checkString($var, True); $this->page_token = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Cloud/Location/ListLocationsResponse.php ================================================ google.cloud.location.ListLocationsResponse */ class ListLocationsResponse extends \Google\Protobuf\Internal\Message { /** * A list of locations that matches the specified filter in the request. * * Generated from protobuf field repeated .google.cloud.location.Location locations = 1; */ private $locations; /** * The standard List next-page token. * * Generated from protobuf field string next_page_token = 2; */ protected $next_page_token = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type array<\Google\Cloud\Location\Location>|\Google\Protobuf\Internal\RepeatedField $locations * A list of locations that matches the specified filter in the request. * @type string $next_page_token * The standard List next-page token. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Cloud\Location\Locations::initOnce(); parent::__construct($data); } /** * A list of locations that matches the specified filter in the request. * * Generated from protobuf field repeated .google.cloud.location.Location locations = 1; * @return \Google\Protobuf\Internal\RepeatedField */ public function getLocations() { return $this->locations; } /** * A list of locations that matches the specified filter in the request. * * Generated from protobuf field repeated .google.cloud.location.Location locations = 1; * @param array<\Google\Cloud\Location\Location>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setLocations($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Cloud\Location\Location::class); $this->locations = $arr; return $this; } /** * The standard List next-page token. * * Generated from protobuf field string next_page_token = 2; * @return string */ public function getNextPageToken() { return $this->next_page_token; } /** * The standard List next-page token. * * Generated from protobuf field string next_page_token = 2; * @param string $var * @return $this */ public function setNextPageToken($var) { GPBUtil::checkString($var, True); $this->next_page_token = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Cloud/Location/Location.php ================================================ google.cloud.location.Location */ class Location extends \Google\Protobuf\Internal\Message { /** * Resource name for the location, which may vary between implementations. * For example: `"projects/example-project/locations/us-east1"` * * Generated from protobuf field string name = 1; */ protected $name = ''; /** * The canonical id for this location. For example: `"us-east1"`. * * Generated from protobuf field string location_id = 4; */ protected $location_id = ''; /** * The friendly name for this location, typically a nearby city name. * For example, "Tokyo". * * Generated from protobuf field string display_name = 5; */ protected $display_name = ''; /** * Cross-service attributes for the location. For example * {"cloud.googleapis.com/region": "us-east1"} * * Generated from protobuf field map labels = 2; */ private $labels; /** * Service-specific metadata. For example the available capacity at the given * location. * * Generated from protobuf field .google.protobuf.Any metadata = 3; */ protected $metadata = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $name * Resource name for the location, which may vary between implementations. * For example: `"projects/example-project/locations/us-east1"` * @type string $location_id * The canonical id for this location. For example: `"us-east1"`. * @type string $display_name * The friendly name for this location, typically a nearby city name. * For example, "Tokyo". * @type array|\Google\Protobuf\Internal\MapField $labels * Cross-service attributes for the location. For example * {"cloud.googleapis.com/region": "us-east1"} * @type \Google\Protobuf\Any $metadata * Service-specific metadata. For example the available capacity at the given * location. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Cloud\Location\Locations::initOnce(); parent::__construct($data); } /** * Resource name for the location, which may vary between implementations. * For example: `"projects/example-project/locations/us-east1"` * * Generated from protobuf field string name = 1; * @return string */ public function getName() { return $this->name; } /** * Resource name for the location, which may vary between implementations. * For example: `"projects/example-project/locations/us-east1"` * * Generated from protobuf field string name = 1; * @param string $var * @return $this */ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; return $this; } /** * The canonical id for this location. For example: `"us-east1"`. * * Generated from protobuf field string location_id = 4; * @return string */ public function getLocationId() { return $this->location_id; } /** * The canonical id for this location. For example: `"us-east1"`. * * Generated from protobuf field string location_id = 4; * @param string $var * @return $this */ public function setLocationId($var) { GPBUtil::checkString($var, True); $this->location_id = $var; return $this; } /** * The friendly name for this location, typically a nearby city name. * For example, "Tokyo". * * Generated from protobuf field string display_name = 5; * @return string */ public function getDisplayName() { return $this->display_name; } /** * The friendly name for this location, typically a nearby city name. * For example, "Tokyo". * * Generated from protobuf field string display_name = 5; * @param string $var * @return $this */ public function setDisplayName($var) { GPBUtil::checkString($var, True); $this->display_name = $var; return $this; } /** * Cross-service attributes for the location. For example * {"cloud.googleapis.com/region": "us-east1"} * * Generated from protobuf field map labels = 2; * @return \Google\Protobuf\Internal\MapField */ public function getLabels() { return $this->labels; } /** * Cross-service attributes for the location. For example * {"cloud.googleapis.com/region": "us-east1"} * * Generated from protobuf field map labels = 2; * @param array|\Google\Protobuf\Internal\MapField $var * @return $this */ public function setLabels($var) { $arr = GPBUtil::checkMapField($var, \Google\Protobuf\Internal\GPBType::STRING, \Google\Protobuf\Internal\GPBType::STRING); $this->labels = $arr; return $this; } /** * Service-specific metadata. For example the available capacity at the given * location. * * Generated from protobuf field .google.protobuf.Any metadata = 3; * @return \Google\Protobuf\Any|null */ public function getMetadata() { return $this->metadata; } public function hasMetadata() { return isset($this->metadata); } public function clearMetadata() { unset($this->metadata); } /** * Service-specific metadata. For example the available capacity at the given * location. * * Generated from protobuf field .google.protobuf.Any metadata = 3; * @param \Google\Protobuf\Any $var * @return $this */ public function setMetadata($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Any::class); $this->metadata = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Cloud/Logging/Type/HttpRequest.php ================================================ google.logging.type.HttpRequest */ class HttpRequest extends \Google\Protobuf\Internal\Message { /** * The request method. Examples: `"GET"`, `"HEAD"`, `"PUT"`, `"POST"`. * * Generated from protobuf field string request_method = 1; */ protected $request_method = ''; /** * The scheme (http, https), the host name, the path and the query * portion of the URL that was requested. * Example: `"http://example.com/some/info?color=red"`. * * Generated from protobuf field string request_url = 2; */ protected $request_url = ''; /** * The size of the HTTP request message in bytes, including the request * headers and the request body. * * Generated from protobuf field int64 request_size = 3; */ protected $request_size = 0; /** * The response code indicating the status of response. * Examples: 200, 404. * * Generated from protobuf field int32 status = 4; */ protected $status = 0; /** * The size of the HTTP response message sent back to the client, in bytes, * including the response headers and the response body. * * Generated from protobuf field int64 response_size = 5; */ protected $response_size = 0; /** * The user agent sent by the client. Example: * `"Mozilla/4.0 (compatible; MSIE 6.0; Windows 98; Q312461; .NET * CLR 1.0.3705)"`. * * Generated from protobuf field string user_agent = 6; */ protected $user_agent = ''; /** * The IP address (IPv4 or IPv6) of the client that issued the HTTP * request. This field can include port information. Examples: * `"192.168.1.1"`, `"10.0.0.1:80"`, `"FE80::0202:B3FF:FE1E:8329"`. * * Generated from protobuf field string remote_ip = 7; */ protected $remote_ip = ''; /** * The IP address (IPv4 or IPv6) of the origin server that the request was * sent to. This field can include port information. Examples: * `"192.168.1.1"`, `"10.0.0.1:80"`, `"FE80::0202:B3FF:FE1E:8329"`. * * Generated from protobuf field string server_ip = 13; */ protected $server_ip = ''; /** * The referer URL of the request, as defined in * [HTTP/1.1 Header Field * Definitions](https://datatracker.ietf.org/doc/html/rfc2616#section-14.36). * * Generated from protobuf field string referer = 8; */ protected $referer = ''; /** * The request processing latency on the server, from the time the request was * received until the response was sent. * * Generated from protobuf field .google.protobuf.Duration latency = 14; */ protected $latency = null; /** * Whether or not a cache lookup was attempted. * * Generated from protobuf field bool cache_lookup = 11; */ protected $cache_lookup = false; /** * Whether or not an entity was served from cache * (with or without validation). * * Generated from protobuf field bool cache_hit = 9; */ protected $cache_hit = false; /** * Whether or not the response was validated with the origin server before * being served from cache. This field is only meaningful if `cache_hit` is * True. * * Generated from protobuf field bool cache_validated_with_origin_server = 10; */ protected $cache_validated_with_origin_server = false; /** * The number of HTTP response bytes inserted into cache. Set only when a * cache fill was attempted. * * Generated from protobuf field int64 cache_fill_bytes = 12; */ protected $cache_fill_bytes = 0; /** * Protocol used for the request. Examples: "HTTP/1.1", "HTTP/2", "websocket" * * Generated from protobuf field string protocol = 15; */ protected $protocol = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $request_method * The request method. Examples: `"GET"`, `"HEAD"`, `"PUT"`, `"POST"`. * @type string $request_url * The scheme (http, https), the host name, the path and the query * portion of the URL that was requested. * Example: `"http://example.com/some/info?color=red"`. * @type int|string $request_size * The size of the HTTP request message in bytes, including the request * headers and the request body. * @type int $status * The response code indicating the status of response. * Examples: 200, 404. * @type int|string $response_size * The size of the HTTP response message sent back to the client, in bytes, * including the response headers and the response body. * @type string $user_agent * The user agent sent by the client. Example: * `"Mozilla/4.0 (compatible; MSIE 6.0; Windows 98; Q312461; .NET * CLR 1.0.3705)"`. * @type string $remote_ip * The IP address (IPv4 or IPv6) of the client that issued the HTTP * request. This field can include port information. Examples: * `"192.168.1.1"`, `"10.0.0.1:80"`, `"FE80::0202:B3FF:FE1E:8329"`. * @type string $server_ip * The IP address (IPv4 or IPv6) of the origin server that the request was * sent to. This field can include port information. Examples: * `"192.168.1.1"`, `"10.0.0.1:80"`, `"FE80::0202:B3FF:FE1E:8329"`. * @type string $referer * The referer URL of the request, as defined in * [HTTP/1.1 Header Field * Definitions](https://datatracker.ietf.org/doc/html/rfc2616#section-14.36). * @type \Google\Protobuf\Duration $latency * The request processing latency on the server, from the time the request was * received until the response was sent. * @type bool $cache_lookup * Whether or not a cache lookup was attempted. * @type bool $cache_hit * Whether or not an entity was served from cache * (with or without validation). * @type bool $cache_validated_with_origin_server * Whether or not the response was validated with the origin server before * being served from cache. This field is only meaningful if `cache_hit` is * True. * @type int|string $cache_fill_bytes * The number of HTTP response bytes inserted into cache. Set only when a * cache fill was attempted. * @type string $protocol * Protocol used for the request. Examples: "HTTP/1.1", "HTTP/2", "websocket" * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Logging\Type\HttpRequest::initOnce(); parent::__construct($data); } /** * The request method. Examples: `"GET"`, `"HEAD"`, `"PUT"`, `"POST"`. * * Generated from protobuf field string request_method = 1; * @return string */ public function getRequestMethod() { return $this->request_method; } /** * The request method. Examples: `"GET"`, `"HEAD"`, `"PUT"`, `"POST"`. * * Generated from protobuf field string request_method = 1; * @param string $var * @return $this */ public function setRequestMethod($var) { GPBUtil::checkString($var, True); $this->request_method = $var; return $this; } /** * The scheme (http, https), the host name, the path and the query * portion of the URL that was requested. * Example: `"http://example.com/some/info?color=red"`. * * Generated from protobuf field string request_url = 2; * @return string */ public function getRequestUrl() { return $this->request_url; } /** * The scheme (http, https), the host name, the path and the query * portion of the URL that was requested. * Example: `"http://example.com/some/info?color=red"`. * * Generated from protobuf field string request_url = 2; * @param string $var * @return $this */ public function setRequestUrl($var) { GPBUtil::checkString($var, True); $this->request_url = $var; return $this; } /** * The size of the HTTP request message in bytes, including the request * headers and the request body. * * Generated from protobuf field int64 request_size = 3; * @return int|string */ public function getRequestSize() { return $this->request_size; } /** * The size of the HTTP request message in bytes, including the request * headers and the request body. * * Generated from protobuf field int64 request_size = 3; * @param int|string $var * @return $this */ public function setRequestSize($var) { GPBUtil::checkInt64($var); $this->request_size = $var; return $this; } /** * The response code indicating the status of response. * Examples: 200, 404. * * Generated from protobuf field int32 status = 4; * @return int */ public function getStatus() { return $this->status; } /** * The response code indicating the status of response. * Examples: 200, 404. * * Generated from protobuf field int32 status = 4; * @param int $var * @return $this */ public function setStatus($var) { GPBUtil::checkInt32($var); $this->status = $var; return $this; } /** * The size of the HTTP response message sent back to the client, in bytes, * including the response headers and the response body. * * Generated from protobuf field int64 response_size = 5; * @return int|string */ public function getResponseSize() { return $this->response_size; } /** * The size of the HTTP response message sent back to the client, in bytes, * including the response headers and the response body. * * Generated from protobuf field int64 response_size = 5; * @param int|string $var * @return $this */ public function setResponseSize($var) { GPBUtil::checkInt64($var); $this->response_size = $var; return $this; } /** * The user agent sent by the client. Example: * `"Mozilla/4.0 (compatible; MSIE 6.0; Windows 98; Q312461; .NET * CLR 1.0.3705)"`. * * Generated from protobuf field string user_agent = 6; * @return string */ public function getUserAgent() { return $this->user_agent; } /** * The user agent sent by the client. Example: * `"Mozilla/4.0 (compatible; MSIE 6.0; Windows 98; Q312461; .NET * CLR 1.0.3705)"`. * * Generated from protobuf field string user_agent = 6; * @param string $var * @return $this */ public function setUserAgent($var) { GPBUtil::checkString($var, True); $this->user_agent = $var; return $this; } /** * The IP address (IPv4 or IPv6) of the client that issued the HTTP * request. This field can include port information. Examples: * `"192.168.1.1"`, `"10.0.0.1:80"`, `"FE80::0202:B3FF:FE1E:8329"`. * * Generated from protobuf field string remote_ip = 7; * @return string */ public function getRemoteIp() { return $this->remote_ip; } /** * The IP address (IPv4 or IPv6) of the client that issued the HTTP * request. This field can include port information. Examples: * `"192.168.1.1"`, `"10.0.0.1:80"`, `"FE80::0202:B3FF:FE1E:8329"`. * * Generated from protobuf field string remote_ip = 7; * @param string $var * @return $this */ public function setRemoteIp($var) { GPBUtil::checkString($var, True); $this->remote_ip = $var; return $this; } /** * The IP address (IPv4 or IPv6) of the origin server that the request was * sent to. This field can include port information. Examples: * `"192.168.1.1"`, `"10.0.0.1:80"`, `"FE80::0202:B3FF:FE1E:8329"`. * * Generated from protobuf field string server_ip = 13; * @return string */ public function getServerIp() { return $this->server_ip; } /** * The IP address (IPv4 or IPv6) of the origin server that the request was * sent to. This field can include port information. Examples: * `"192.168.1.1"`, `"10.0.0.1:80"`, `"FE80::0202:B3FF:FE1E:8329"`. * * Generated from protobuf field string server_ip = 13; * @param string $var * @return $this */ public function setServerIp($var) { GPBUtil::checkString($var, True); $this->server_ip = $var; return $this; } /** * The referer URL of the request, as defined in * [HTTP/1.1 Header Field * Definitions](https://datatracker.ietf.org/doc/html/rfc2616#section-14.36). * * Generated from protobuf field string referer = 8; * @return string */ public function getReferer() { return $this->referer; } /** * The referer URL of the request, as defined in * [HTTP/1.1 Header Field * Definitions](https://datatracker.ietf.org/doc/html/rfc2616#section-14.36). * * Generated from protobuf field string referer = 8; * @param string $var * @return $this */ public function setReferer($var) { GPBUtil::checkString($var, True); $this->referer = $var; return $this; } /** * The request processing latency on the server, from the time the request was * received until the response was sent. * * Generated from protobuf field .google.protobuf.Duration latency = 14; * @return \Google\Protobuf\Duration|null */ public function getLatency() { return $this->latency; } public function hasLatency() { return isset($this->latency); } public function clearLatency() { unset($this->latency); } /** * The request processing latency on the server, from the time the request was * received until the response was sent. * * Generated from protobuf field .google.protobuf.Duration latency = 14; * @param \Google\Protobuf\Duration $var * @return $this */ public function setLatency($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Duration::class); $this->latency = $var; return $this; } /** * Whether or not a cache lookup was attempted. * * Generated from protobuf field bool cache_lookup = 11; * @return bool */ public function getCacheLookup() { return $this->cache_lookup; } /** * Whether or not a cache lookup was attempted. * * Generated from protobuf field bool cache_lookup = 11; * @param bool $var * @return $this */ public function setCacheLookup($var) { GPBUtil::checkBool($var); $this->cache_lookup = $var; return $this; } /** * Whether or not an entity was served from cache * (with or without validation). * * Generated from protobuf field bool cache_hit = 9; * @return bool */ public function getCacheHit() { return $this->cache_hit; } /** * Whether or not an entity was served from cache * (with or without validation). * * Generated from protobuf field bool cache_hit = 9; * @param bool $var * @return $this */ public function setCacheHit($var) { GPBUtil::checkBool($var); $this->cache_hit = $var; return $this; } /** * Whether or not the response was validated with the origin server before * being served from cache. This field is only meaningful if `cache_hit` is * True. * * Generated from protobuf field bool cache_validated_with_origin_server = 10; * @return bool */ public function getCacheValidatedWithOriginServer() { return $this->cache_validated_with_origin_server; } /** * Whether or not the response was validated with the origin server before * being served from cache. This field is only meaningful if `cache_hit` is * True. * * Generated from protobuf field bool cache_validated_with_origin_server = 10; * @param bool $var * @return $this */ public function setCacheValidatedWithOriginServer($var) { GPBUtil::checkBool($var); $this->cache_validated_with_origin_server = $var; return $this; } /** * The number of HTTP response bytes inserted into cache. Set only when a * cache fill was attempted. * * Generated from protobuf field int64 cache_fill_bytes = 12; * @return int|string */ public function getCacheFillBytes() { return $this->cache_fill_bytes; } /** * The number of HTTP response bytes inserted into cache. Set only when a * cache fill was attempted. * * Generated from protobuf field int64 cache_fill_bytes = 12; * @param int|string $var * @return $this */ public function setCacheFillBytes($var) { GPBUtil::checkInt64($var); $this->cache_fill_bytes = $var; return $this; } /** * Protocol used for the request. Examples: "HTTP/1.1", "HTTP/2", "websocket" * * Generated from protobuf field string protocol = 15; * @return string */ public function getProtocol() { return $this->protocol; } /** * Protocol used for the request. Examples: "HTTP/1.1", "HTTP/2", "websocket" * * Generated from protobuf field string protocol = 15; * @param string $var * @return $this */ public function setProtocol($var) { GPBUtil::checkString($var, True); $this->protocol = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Cloud/Logging/Type/LogSeverity.php ================================================ DEBUG AND severity <= WARNING * If you are writing log entries, you should map other severity encodings to * one of these standard levels. For example, you might map all of Java's FINE, * FINER, and FINEST levels to `LogSeverity.DEBUG`. You can preserve the * original severity level in the log entry payload if you wish. * * Protobuf type google.logging.type.LogSeverity */ class LogSeverity { /** * (0) The log entry has no assigned severity level. * * Generated from protobuf enum DEFAULT = 0; */ const PBDEFAULT = 0; /** * (100) Debug or trace information. * * Generated from protobuf enum DEBUG = 100; */ const DEBUG = 100; /** * (200) Routine information, such as ongoing status or performance. * * Generated from protobuf enum INFO = 200; */ const INFO = 200; /** * (300) Normal but significant events, such as start up, shut down, or * a configuration change. * * Generated from protobuf enum NOTICE = 300; */ const NOTICE = 300; /** * (400) Warning events might cause problems. * * Generated from protobuf enum WARNING = 400; */ const WARNING = 400; /** * (500) Error events are likely to cause problems. * * Generated from protobuf enum ERROR = 500; */ const ERROR = 500; /** * (600) Critical events cause more severe problems or outages. * * Generated from protobuf enum CRITICAL = 600; */ const CRITICAL = 600; /** * (700) A person must take an action immediately. * * Generated from protobuf enum ALERT = 700; */ const ALERT = 700; /** * (800) One or more systems are unusable. * * Generated from protobuf enum EMERGENCY = 800; */ const EMERGENCY = 800; private static $valueToName = [ self::PBDEFAULT => 'DEFAULT', self::DEBUG => 'DEBUG', self::INFO => 'INFO', self::NOTICE => 'NOTICE', self::WARNING => 'WARNING', self::ERROR => 'ERROR', self::CRITICAL => 'CRITICAL', self::ALERT => 'ALERT', self::EMERGENCY => 'EMERGENCY', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { $pbconst = __CLASS__. '::PB' . strtoupper($name); if (!defined($pbconst)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($pbconst); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Cloud/OperationResponseMapping.php ================================================ google.cloud.OperationResponseMapping */ class OperationResponseMapping { /** * Do not use. * * Generated from protobuf enum UNDEFINED = 0; */ const UNDEFINED = 0; /** * A field in an API-specific (custom) Operation object which carries the same * meaning as google.longrunning.Operation.name. * * Generated from protobuf enum NAME = 1; */ const NAME = 1; /** * A field in an API-specific (custom) Operation object which carries the same * meaning as google.longrunning.Operation.done. If the annotated field is of * an enum type, `annotated_field_name == EnumType.DONE` semantics should be * equivalent to `Operation.done == true`. If the annotated field is of type * boolean, then it should follow the same semantics as Operation.done. * Otherwise, a non-empty value should be treated as `Operation.done == true`. * * Generated from protobuf enum STATUS = 2; */ const STATUS = 2; /** * A field in an API-specific (custom) Operation object which carries the same * meaning as google.longrunning.Operation.error.code. * * Generated from protobuf enum ERROR_CODE = 3; */ const ERROR_CODE = 3; /** * A field in an API-specific (custom) Operation object which carries the same * meaning as google.longrunning.Operation.error.message. * * Generated from protobuf enum ERROR_MESSAGE = 4; */ const ERROR_MESSAGE = 4; private static $valueToName = [ self::UNDEFINED => 'UNDEFINED', self::NAME => 'NAME', self::STATUS => 'STATUS', self::ERROR_CODE => 'ERROR_CODE', self::ERROR_MESSAGE => 'ERROR_MESSAGE', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Iam/V1/Logging/AuditData.php ================================================ google.iam.v1.logging.AuditData */ class AuditData extends \Google\Protobuf\Internal\Message { /** * Policy delta between the original policy and the newly set policy. * * Generated from protobuf field .google.iam.v1.PolicyDelta policy_delta = 2; */ protected $policy_delta = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type \Google\Cloud\Iam\V1\PolicyDelta $policy_delta * Policy delta between the original policy and the newly set policy. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Iam\V1\Logging\AuditData::initOnce(); parent::__construct($data); } /** * Policy delta between the original policy and the newly set policy. * * Generated from protobuf field .google.iam.v1.PolicyDelta policy_delta = 2; * @return \Google\Cloud\Iam\V1\PolicyDelta|null */ public function getPolicyDelta() { return $this->policy_delta; } public function hasPolicyDelta() { return isset($this->policy_delta); } public function clearPolicyDelta() { unset($this->policy_delta); } /** * Policy delta between the original policy and the newly set policy. * * Generated from protobuf field .google.iam.v1.PolicyDelta policy_delta = 2; * @param \Google\Cloud\Iam\V1\PolicyDelta $var * @return $this */ public function setPolicyDelta($var) { GPBUtil::checkMessage($var, \Google\Cloud\Iam\V1\PolicyDelta::class); $this->policy_delta = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Rpc/BadRequest/FieldViolation.php ================================================ google.rpc.BadRequest.FieldViolation */ class FieldViolation extends \Google\Protobuf\Internal\Message { /** * A path that leads to a field in the request body. The value will be a * sequence of dot-separated identifiers that identify a protocol buffer * field. * Consider the following: * message CreateContactRequest { * message EmailAddress { * enum Type { * TYPE_UNSPECIFIED = 0; * HOME = 1; * WORK = 2; * } * optional string email = 1; * repeated EmailType type = 2; * } * string full_name = 1; * repeated EmailAddress email_addresses = 2; * } * In this example, in proto `field` could take one of the following values: * * `full_name` for a violation in the `full_name` value * * `email_addresses[1].email` for a violation in the `email` field of the * first `email_addresses` message * * `email_addresses[3].type[2]` for a violation in the second `type` * value in the third `email_addresses` message. * In JSON, the same values are represented as: * * `fullName` for a violation in the `fullName` value * * `emailAddresses[1].email` for a violation in the `email` field of the * first `emailAddresses` message * * `emailAddresses[3].type[2]` for a violation in the second `type` * value in the third `emailAddresses` message. * * Generated from protobuf field string field = 1; */ protected $field = ''; /** * A description of why the request element is bad. * * Generated from protobuf field string description = 2; */ protected $description = ''; /** * The reason of the field-level error. This is a constant value that * identifies the proximate cause of the field-level error. It should * uniquely identify the type of the FieldViolation within the scope of the * google.rpc.ErrorInfo.domain. This should be at most 63 * characters and match a regular expression of `[A-Z][A-Z0-9_]+[A-Z0-9]`, * which represents UPPER_SNAKE_CASE. * * Generated from protobuf field string reason = 3; */ protected $reason = ''; /** * Provides a localized error message for field-level errors that is safe to * return to the API consumer. * * Generated from protobuf field .google.rpc.LocalizedMessage localized_message = 4; */ protected $localized_message = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $field * A path that leads to a field in the request body. The value will be a * sequence of dot-separated identifiers that identify a protocol buffer * field. * Consider the following: * message CreateContactRequest { * message EmailAddress { * enum Type { * TYPE_UNSPECIFIED = 0; * HOME = 1; * WORK = 2; * } * optional string email = 1; * repeated EmailType type = 2; * } * string full_name = 1; * repeated EmailAddress email_addresses = 2; * } * In this example, in proto `field` could take one of the following values: * * `full_name` for a violation in the `full_name` value * * `email_addresses[1].email` for a violation in the `email` field of the * first `email_addresses` message * * `email_addresses[3].type[2]` for a violation in the second `type` * value in the third `email_addresses` message. * In JSON, the same values are represented as: * * `fullName` for a violation in the `fullName` value * * `emailAddresses[1].email` for a violation in the `email` field of the * first `emailAddresses` message * * `emailAddresses[3].type[2]` for a violation in the second `type` * value in the third `emailAddresses` message. * @type string $description * A description of why the request element is bad. * @type string $reason * The reason of the field-level error. This is a constant value that * identifies the proximate cause of the field-level error. It should * uniquely identify the type of the FieldViolation within the scope of the * google.rpc.ErrorInfo.domain. This should be at most 63 * characters and match a regular expression of `[A-Z][A-Z0-9_]+[A-Z0-9]`, * which represents UPPER_SNAKE_CASE. * @type \Google\Rpc\LocalizedMessage $localized_message * Provides a localized error message for field-level errors that is safe to * return to the API consumer. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Rpc\ErrorDetails::initOnce(); parent::__construct($data); } /** * A path that leads to a field in the request body. The value will be a * sequence of dot-separated identifiers that identify a protocol buffer * field. * Consider the following: * message CreateContactRequest { * message EmailAddress { * enum Type { * TYPE_UNSPECIFIED = 0; * HOME = 1; * WORK = 2; * } * optional string email = 1; * repeated EmailType type = 2; * } * string full_name = 1; * repeated EmailAddress email_addresses = 2; * } * In this example, in proto `field` could take one of the following values: * * `full_name` for a violation in the `full_name` value * * `email_addresses[1].email` for a violation in the `email` field of the * first `email_addresses` message * * `email_addresses[3].type[2]` for a violation in the second `type` * value in the third `email_addresses` message. * In JSON, the same values are represented as: * * `fullName` for a violation in the `fullName` value * * `emailAddresses[1].email` for a violation in the `email` field of the * first `emailAddresses` message * * `emailAddresses[3].type[2]` for a violation in the second `type` * value in the third `emailAddresses` message. * * Generated from protobuf field string field = 1; * @return string */ public function getField() { return $this->field; } /** * A path that leads to a field in the request body. The value will be a * sequence of dot-separated identifiers that identify a protocol buffer * field. * Consider the following: * message CreateContactRequest { * message EmailAddress { * enum Type { * TYPE_UNSPECIFIED = 0; * HOME = 1; * WORK = 2; * } * optional string email = 1; * repeated EmailType type = 2; * } * string full_name = 1; * repeated EmailAddress email_addresses = 2; * } * In this example, in proto `field` could take one of the following values: * * `full_name` for a violation in the `full_name` value * * `email_addresses[1].email` for a violation in the `email` field of the * first `email_addresses` message * * `email_addresses[3].type[2]` for a violation in the second `type` * value in the third `email_addresses` message. * In JSON, the same values are represented as: * * `fullName` for a violation in the `fullName` value * * `emailAddresses[1].email` for a violation in the `email` field of the * first `emailAddresses` message * * `emailAddresses[3].type[2]` for a violation in the second `type` * value in the third `emailAddresses` message. * * Generated from protobuf field string field = 1; * @param string $var * @return $this */ public function setField($var) { GPBUtil::checkString($var, True); $this->field = $var; return $this; } /** * A description of why the request element is bad. * * Generated from protobuf field string description = 2; * @return string */ public function getDescription() { return $this->description; } /** * A description of why the request element is bad. * * Generated from protobuf field string description = 2; * @param string $var * @return $this */ public function setDescription($var) { GPBUtil::checkString($var, True); $this->description = $var; return $this; } /** * The reason of the field-level error. This is a constant value that * identifies the proximate cause of the field-level error. It should * uniquely identify the type of the FieldViolation within the scope of the * google.rpc.ErrorInfo.domain. This should be at most 63 * characters and match a regular expression of `[A-Z][A-Z0-9_]+[A-Z0-9]`, * which represents UPPER_SNAKE_CASE. * * Generated from protobuf field string reason = 3; * @return string */ public function getReason() { return $this->reason; } /** * The reason of the field-level error. This is a constant value that * identifies the proximate cause of the field-level error. It should * uniquely identify the type of the FieldViolation within the scope of the * google.rpc.ErrorInfo.domain. This should be at most 63 * characters and match a regular expression of `[A-Z][A-Z0-9_]+[A-Z0-9]`, * which represents UPPER_SNAKE_CASE. * * Generated from protobuf field string reason = 3; * @param string $var * @return $this */ public function setReason($var) { GPBUtil::checkString($var, True); $this->reason = $var; return $this; } /** * Provides a localized error message for field-level errors that is safe to * return to the API consumer. * * Generated from protobuf field .google.rpc.LocalizedMessage localized_message = 4; * @return \Google\Rpc\LocalizedMessage|null */ public function getLocalizedMessage() { return $this->localized_message; } public function hasLocalizedMessage() { return isset($this->localized_message); } public function clearLocalizedMessage() { unset($this->localized_message); } /** * Provides a localized error message for field-level errors that is safe to * return to the API consumer. * * Generated from protobuf field .google.rpc.LocalizedMessage localized_message = 4; * @param \Google\Rpc\LocalizedMessage $var * @return $this */ public function setLocalizedMessage($var) { GPBUtil::checkMessage($var, \Google\Rpc\LocalizedMessage::class); $this->localized_message = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Rpc/BadRequest.php ================================================ google.rpc.BadRequest */ class BadRequest extends \Google\Protobuf\Internal\Message { /** * Describes all violations in a client request. * * Generated from protobuf field repeated .google.rpc.BadRequest.FieldViolation field_violations = 1; */ private $field_violations; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type array<\Google\Rpc\BadRequest\FieldViolation>|\Google\Protobuf\Internal\RepeatedField $field_violations * Describes all violations in a client request. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Rpc\ErrorDetails::initOnce(); parent::__construct($data); } /** * Describes all violations in a client request. * * Generated from protobuf field repeated .google.rpc.BadRequest.FieldViolation field_violations = 1; * @return \Google\Protobuf\Internal\RepeatedField */ public function getFieldViolations() { return $this->field_violations; } /** * Describes all violations in a client request. * * Generated from protobuf field repeated .google.rpc.BadRequest.FieldViolation field_violations = 1; * @param array<\Google\Rpc\BadRequest\FieldViolation>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setFieldViolations($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Rpc\BadRequest\FieldViolation::class); $this->field_violations = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Rpc/Code.php ================================================ google.rpc.Code */ class Code { /** * Not an error; returned on success. * HTTP Mapping: 200 OK * * Generated from protobuf enum OK = 0; */ const OK = 0; /** * The operation was cancelled, typically by the caller. * HTTP Mapping: 499 Client Closed Request * * Generated from protobuf enum CANCELLED = 1; */ const CANCELLED = 1; /** * Unknown error. For example, this error may be returned when * a `Status` value received from another address space belongs to * an error space that is not known in this address space. Also * errors raised by APIs that do not return enough error information * may be converted to this error. * HTTP Mapping: 500 Internal Server Error * * Generated from protobuf enum UNKNOWN = 2; */ const UNKNOWN = 2; /** * The client specified an invalid argument. Note that this differs * from `FAILED_PRECONDITION`. `INVALID_ARGUMENT` indicates arguments * that are problematic regardless of the state of the system * (e.g., a malformed file name). * HTTP Mapping: 400 Bad Request * * Generated from protobuf enum INVALID_ARGUMENT = 3; */ const INVALID_ARGUMENT = 3; /** * The deadline expired before the operation could complete. For operations * that change the state of the system, this error may be returned * even if the operation has completed successfully. For example, a * successful response from a server could have been delayed long * enough for the deadline to expire. * HTTP Mapping: 504 Gateway Timeout * * Generated from protobuf enum DEADLINE_EXCEEDED = 4; */ const DEADLINE_EXCEEDED = 4; /** * Some requested entity (e.g., file or directory) was not found. * Note to server developers: if a request is denied for an entire class * of users, such as gradual feature rollout or undocumented allowlist, * `NOT_FOUND` may be used. If a request is denied for some users within * a class of users, such as user-based access control, `PERMISSION_DENIED` * must be used. * HTTP Mapping: 404 Not Found * * Generated from protobuf enum NOT_FOUND = 5; */ const NOT_FOUND = 5; /** * The entity that a client attempted to create (e.g., file or directory) * already exists. * HTTP Mapping: 409 Conflict * * Generated from protobuf enum ALREADY_EXISTS = 6; */ const ALREADY_EXISTS = 6; /** * The caller does not have permission to execute the specified * operation. `PERMISSION_DENIED` must not be used for rejections * caused by exhausting some resource (use `RESOURCE_EXHAUSTED` * instead for those errors). `PERMISSION_DENIED` must not be * used if the caller can not be identified (use `UNAUTHENTICATED` * instead for those errors). This error code does not imply the * request is valid or the requested entity exists or satisfies * other pre-conditions. * HTTP Mapping: 403 Forbidden * * Generated from protobuf enum PERMISSION_DENIED = 7; */ const PERMISSION_DENIED = 7; /** * The request does not have valid authentication credentials for the * operation. * HTTP Mapping: 401 Unauthorized * * Generated from protobuf enum UNAUTHENTICATED = 16; */ const UNAUTHENTICATED = 16; /** * Some resource has been exhausted, perhaps a per-user quota, or * perhaps the entire file system is out of space. * HTTP Mapping: 429 Too Many Requests * * Generated from protobuf enum RESOURCE_EXHAUSTED = 8; */ const RESOURCE_EXHAUSTED = 8; /** * The operation was rejected because the system is not in a state * required for the operation's execution. For example, the directory * to be deleted is non-empty, an rmdir operation is applied to * a non-directory, etc. * Service implementors can use the following guidelines to decide * between `FAILED_PRECONDITION`, `ABORTED`, and `UNAVAILABLE`: * (a) Use `UNAVAILABLE` if the client can retry just the failing call. * (b) Use `ABORTED` if the client should retry at a higher level. For * example, when a client-specified test-and-set fails, indicating the * client should restart a read-modify-write sequence. * (c) Use `FAILED_PRECONDITION` if the client should not retry until * the system state has been explicitly fixed. For example, if an "rmdir" * fails because the directory is non-empty, `FAILED_PRECONDITION` * should be returned since the client should not retry unless * the files are deleted from the directory. * HTTP Mapping: 400 Bad Request * * Generated from protobuf enum FAILED_PRECONDITION = 9; */ const FAILED_PRECONDITION = 9; /** * The operation was aborted, typically due to a concurrency issue such as * a sequencer check failure or transaction abort. * See the guidelines above for deciding between `FAILED_PRECONDITION`, * `ABORTED`, and `UNAVAILABLE`. * HTTP Mapping: 409 Conflict * * Generated from protobuf enum ABORTED = 10; */ const ABORTED = 10; /** * The operation was attempted past the valid range. E.g., seeking or * reading past end-of-file. * Unlike `INVALID_ARGUMENT`, this error indicates a problem that may * be fixed if the system state changes. For example, a 32-bit file * system will generate `INVALID_ARGUMENT` if asked to read at an * offset that is not in the range [0,2^32-1], but it will generate * `OUT_OF_RANGE` if asked to read from an offset past the current * file size. * There is a fair bit of overlap between `FAILED_PRECONDITION` and * `OUT_OF_RANGE`. We recommend using `OUT_OF_RANGE` (the more specific * error) when it applies so that callers who are iterating through * a space can easily look for an `OUT_OF_RANGE` error to detect when * they are done. * HTTP Mapping: 400 Bad Request * * Generated from protobuf enum OUT_OF_RANGE = 11; */ const OUT_OF_RANGE = 11; /** * The operation is not implemented or is not supported/enabled in this * service. * HTTP Mapping: 501 Not Implemented * * Generated from protobuf enum UNIMPLEMENTED = 12; */ const UNIMPLEMENTED = 12; /** * Internal errors. This means that some invariants expected by the * underlying system have been broken. This error code is reserved * for serious errors. * HTTP Mapping: 500 Internal Server Error * * Generated from protobuf enum INTERNAL = 13; */ const INTERNAL = 13; /** * The service is currently unavailable. This is most likely a * transient condition, which can be corrected by retrying with * a backoff. Note that it is not always safe to retry * non-idempotent operations. * See the guidelines above for deciding between `FAILED_PRECONDITION`, * `ABORTED`, and `UNAVAILABLE`. * HTTP Mapping: 503 Service Unavailable * * Generated from protobuf enum UNAVAILABLE = 14; */ const UNAVAILABLE = 14; /** * Unrecoverable data loss or corruption. * HTTP Mapping: 500 Internal Server Error * * Generated from protobuf enum DATA_LOSS = 15; */ const DATA_LOSS = 15; private static $valueToName = [ self::OK => 'OK', self::CANCELLED => 'CANCELLED', self::UNKNOWN => 'UNKNOWN', self::INVALID_ARGUMENT => 'INVALID_ARGUMENT', self::DEADLINE_EXCEEDED => 'DEADLINE_EXCEEDED', self::NOT_FOUND => 'NOT_FOUND', self::ALREADY_EXISTS => 'ALREADY_EXISTS', self::PERMISSION_DENIED => 'PERMISSION_DENIED', self::UNAUTHENTICATED => 'UNAUTHENTICATED', self::RESOURCE_EXHAUSTED => 'RESOURCE_EXHAUSTED', self::FAILED_PRECONDITION => 'FAILED_PRECONDITION', self::ABORTED => 'ABORTED', self::OUT_OF_RANGE => 'OUT_OF_RANGE', self::UNIMPLEMENTED => 'UNIMPLEMENTED', self::INTERNAL => 'INTERNAL', self::UNAVAILABLE => 'UNAVAILABLE', self::DATA_LOSS => 'DATA_LOSS', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Rpc/Context/AttributeContext/Api.php ================================================ google.rpc.context.AttributeContext.Api */ class Api extends \Google\Protobuf\Internal\Message { /** * The API service name. It is a logical identifier for a networked API, * such as "pubsub.googleapis.com". The naming syntax depends on the * API management system being used for handling the request. * * Generated from protobuf field string service = 1; */ protected $service = ''; /** * The API operation name. For gRPC requests, it is the fully qualified API * method name, such as "google.pubsub.v1.Publisher.Publish". For OpenAPI * requests, it is the `operationId`, such as "getPet". * * Generated from protobuf field string operation = 2; */ protected $operation = ''; /** * The API protocol used for sending the request, such as "http", "https", * "grpc", or "internal". * * Generated from protobuf field string protocol = 3; */ protected $protocol = ''; /** * The API version associated with the API operation above, such as "v1" or * "v1alpha1". * * Generated from protobuf field string version = 4; */ protected $version = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $service * The API service name. It is a logical identifier for a networked API, * such as "pubsub.googleapis.com". The naming syntax depends on the * API management system being used for handling the request. * @type string $operation * The API operation name. For gRPC requests, it is the fully qualified API * method name, such as "google.pubsub.v1.Publisher.Publish". For OpenAPI * requests, it is the `operationId`, such as "getPet". * @type string $protocol * The API protocol used for sending the request, such as "http", "https", * "grpc", or "internal". * @type string $version * The API version associated with the API operation above, such as "v1" or * "v1alpha1". * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Rpc\Context\AttributeContext::initOnce(); parent::__construct($data); } /** * The API service name. It is a logical identifier for a networked API, * such as "pubsub.googleapis.com". The naming syntax depends on the * API management system being used for handling the request. * * Generated from protobuf field string service = 1; * @return string */ public function getService() { return $this->service; } /** * The API service name. It is a logical identifier for a networked API, * such as "pubsub.googleapis.com". The naming syntax depends on the * API management system being used for handling the request. * * Generated from protobuf field string service = 1; * @param string $var * @return $this */ public function setService($var) { GPBUtil::checkString($var, True); $this->service = $var; return $this; } /** * The API operation name. For gRPC requests, it is the fully qualified API * method name, such as "google.pubsub.v1.Publisher.Publish". For OpenAPI * requests, it is the `operationId`, such as "getPet". * * Generated from protobuf field string operation = 2; * @return string */ public function getOperation() { return $this->operation; } /** * The API operation name. For gRPC requests, it is the fully qualified API * method name, such as "google.pubsub.v1.Publisher.Publish". For OpenAPI * requests, it is the `operationId`, such as "getPet". * * Generated from protobuf field string operation = 2; * @param string $var * @return $this */ public function setOperation($var) { GPBUtil::checkString($var, True); $this->operation = $var; return $this; } /** * The API protocol used for sending the request, such as "http", "https", * "grpc", or "internal". * * Generated from protobuf field string protocol = 3; * @return string */ public function getProtocol() { return $this->protocol; } /** * The API protocol used for sending the request, such as "http", "https", * "grpc", or "internal". * * Generated from protobuf field string protocol = 3; * @param string $var * @return $this */ public function setProtocol($var) { GPBUtil::checkString($var, True); $this->protocol = $var; return $this; } /** * The API version associated with the API operation above, such as "v1" or * "v1alpha1". * * Generated from protobuf field string version = 4; * @return string */ public function getVersion() { return $this->version; } /** * The API version associated with the API operation above, such as "v1" or * "v1alpha1". * * Generated from protobuf field string version = 4; * @param string $var * @return $this */ public function setVersion($var) { GPBUtil::checkString($var, True); $this->version = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Rpc/Context/AttributeContext/Auth.php ================================================ google.rpc.context.AttributeContext.Auth */ class Auth extends \Google\Protobuf\Internal\Message { /** * The authenticated principal. Reflects the issuer (`iss`) and subject * (`sub`) claims within a JWT. The issuer and subject should be `/` * delimited, with `/` percent-encoded within the subject fragment. For * Google accounts, the principal format is: * "https://accounts.google.com/{id}" * * Generated from protobuf field string principal = 1; */ protected $principal = ''; /** * The intended audience(s) for this authentication information. Reflects * the audience (`aud`) claim within a JWT. The audience * value(s) depends on the `issuer`, but typically include one or more of * the following pieces of information: * * The services intended to receive the credential. For example, * ["https://pubsub.googleapis.com/", "https://storage.googleapis.com/"]. * * A set of service-based scopes. For example, * ["https://www.googleapis.com/auth/cloud-platform"]. * * The client id of an app, such as the Firebase project id for JWTs * from Firebase Auth. * Consult the documentation for the credential issuer to determine the * information provided. * * Generated from protobuf field repeated string audiences = 2; */ private $audiences; /** * The authorized presenter of the credential. Reflects the optional * Authorized Presenter (`azp`) claim within a JWT or the * OAuth client id. For example, a Google Cloud Platform client id looks * as follows: "123456789012.apps.googleusercontent.com". * * Generated from protobuf field string presenter = 3; */ protected $presenter = ''; /** * Structured claims presented with the credential. JWTs include * `{key: value}` pairs for standard and private claims. The following * is a subset of the standard required and optional claims that would * typically be presented for a Google-based JWT: * {'iss': 'accounts.google.com', * 'sub': '113289723416554971153', * 'aud': ['123456789012', 'pubsub.googleapis.com'], * 'azp': '123456789012.apps.googleusercontent.com', * 'email': 'jsmith@example.com', * 'iat': 1353601026, * 'exp': 1353604926} * SAML assertions are similarly specified, but with an identity provider * dependent structure. * * Generated from protobuf field .google.protobuf.Struct claims = 4; */ protected $claims = null; /** * A list of access level resource names that allow resources to be * accessed by authenticated requester. It is part of Secure GCP processing * for the incoming request. An access level string has the format: * "//{api_service_name}/accessPolicies/{policy_id}/accessLevels/{short_name}" * Example: * "//accesscontextmanager.googleapis.com/accessPolicies/MY_POLICY_ID/accessLevels/MY_LEVEL" * * Generated from protobuf field repeated string access_levels = 5; */ private $access_levels; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $principal * The authenticated principal. Reflects the issuer (`iss`) and subject * (`sub`) claims within a JWT. The issuer and subject should be `/` * delimited, with `/` percent-encoded within the subject fragment. For * Google accounts, the principal format is: * "https://accounts.google.com/{id}" * @type array|\Google\Protobuf\Internal\RepeatedField $audiences * The intended audience(s) for this authentication information. Reflects * the audience (`aud`) claim within a JWT. The audience * value(s) depends on the `issuer`, but typically include one or more of * the following pieces of information: * * The services intended to receive the credential. For example, * ["https://pubsub.googleapis.com/", "https://storage.googleapis.com/"]. * * A set of service-based scopes. For example, * ["https://www.googleapis.com/auth/cloud-platform"]. * * The client id of an app, such as the Firebase project id for JWTs * from Firebase Auth. * Consult the documentation for the credential issuer to determine the * information provided. * @type string $presenter * The authorized presenter of the credential. Reflects the optional * Authorized Presenter (`azp`) claim within a JWT or the * OAuth client id. For example, a Google Cloud Platform client id looks * as follows: "123456789012.apps.googleusercontent.com". * @type \Google\Protobuf\Struct $claims * Structured claims presented with the credential. JWTs include * `{key: value}` pairs for standard and private claims. The following * is a subset of the standard required and optional claims that would * typically be presented for a Google-based JWT: * {'iss': 'accounts.google.com', * 'sub': '113289723416554971153', * 'aud': ['123456789012', 'pubsub.googleapis.com'], * 'azp': '123456789012.apps.googleusercontent.com', * 'email': 'jsmith@example.com', * 'iat': 1353601026, * 'exp': 1353604926} * SAML assertions are similarly specified, but with an identity provider * dependent structure. * @type array|\Google\Protobuf\Internal\RepeatedField $access_levels * A list of access level resource names that allow resources to be * accessed by authenticated requester. It is part of Secure GCP processing * for the incoming request. An access level string has the format: * "//{api_service_name}/accessPolicies/{policy_id}/accessLevels/{short_name}" * Example: * "//accesscontextmanager.googleapis.com/accessPolicies/MY_POLICY_ID/accessLevels/MY_LEVEL" * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Rpc\Context\AttributeContext::initOnce(); parent::__construct($data); } /** * The authenticated principal. Reflects the issuer (`iss`) and subject * (`sub`) claims within a JWT. The issuer and subject should be `/` * delimited, with `/` percent-encoded within the subject fragment. For * Google accounts, the principal format is: * "https://accounts.google.com/{id}" * * Generated from protobuf field string principal = 1; * @return string */ public function getPrincipal() { return $this->principal; } /** * The authenticated principal. Reflects the issuer (`iss`) and subject * (`sub`) claims within a JWT. The issuer and subject should be `/` * delimited, with `/` percent-encoded within the subject fragment. For * Google accounts, the principal format is: * "https://accounts.google.com/{id}" * * Generated from protobuf field string principal = 1; * @param string $var * @return $this */ public function setPrincipal($var) { GPBUtil::checkString($var, True); $this->principal = $var; return $this; } /** * The intended audience(s) for this authentication information. Reflects * the audience (`aud`) claim within a JWT. The audience * value(s) depends on the `issuer`, but typically include one or more of * the following pieces of information: * * The services intended to receive the credential. For example, * ["https://pubsub.googleapis.com/", "https://storage.googleapis.com/"]. * * A set of service-based scopes. For example, * ["https://www.googleapis.com/auth/cloud-platform"]. * * The client id of an app, such as the Firebase project id for JWTs * from Firebase Auth. * Consult the documentation for the credential issuer to determine the * information provided. * * Generated from protobuf field repeated string audiences = 2; * @return \Google\Protobuf\Internal\RepeatedField */ public function getAudiences() { return $this->audiences; } /** * The intended audience(s) for this authentication information. Reflects * the audience (`aud`) claim within a JWT. The audience * value(s) depends on the `issuer`, but typically include one or more of * the following pieces of information: * * The services intended to receive the credential. For example, * ["https://pubsub.googleapis.com/", "https://storage.googleapis.com/"]. * * A set of service-based scopes. For example, * ["https://www.googleapis.com/auth/cloud-platform"]. * * The client id of an app, such as the Firebase project id for JWTs * from Firebase Auth. * Consult the documentation for the credential issuer to determine the * information provided. * * Generated from protobuf field repeated string audiences = 2; * @param array|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setAudiences($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->audiences = $arr; return $this; } /** * The authorized presenter of the credential. Reflects the optional * Authorized Presenter (`azp`) claim within a JWT or the * OAuth client id. For example, a Google Cloud Platform client id looks * as follows: "123456789012.apps.googleusercontent.com". * * Generated from protobuf field string presenter = 3; * @return string */ public function getPresenter() { return $this->presenter; } /** * The authorized presenter of the credential. Reflects the optional * Authorized Presenter (`azp`) claim within a JWT or the * OAuth client id. For example, a Google Cloud Platform client id looks * as follows: "123456789012.apps.googleusercontent.com". * * Generated from protobuf field string presenter = 3; * @param string $var * @return $this */ public function setPresenter($var) { GPBUtil::checkString($var, True); $this->presenter = $var; return $this; } /** * Structured claims presented with the credential. JWTs include * `{key: value}` pairs for standard and private claims. The following * is a subset of the standard required and optional claims that would * typically be presented for a Google-based JWT: * {'iss': 'accounts.google.com', * 'sub': '113289723416554971153', * 'aud': ['123456789012', 'pubsub.googleapis.com'], * 'azp': '123456789012.apps.googleusercontent.com', * 'email': 'jsmith@example.com', * 'iat': 1353601026, * 'exp': 1353604926} * SAML assertions are similarly specified, but with an identity provider * dependent structure. * * Generated from protobuf field .google.protobuf.Struct claims = 4; * @return \Google\Protobuf\Struct|null */ public function getClaims() { return $this->claims; } public function hasClaims() { return isset($this->claims); } public function clearClaims() { unset($this->claims); } /** * Structured claims presented with the credential. JWTs include * `{key: value}` pairs for standard and private claims. The following * is a subset of the standard required and optional claims that would * typically be presented for a Google-based JWT: * {'iss': 'accounts.google.com', * 'sub': '113289723416554971153', * 'aud': ['123456789012', 'pubsub.googleapis.com'], * 'azp': '123456789012.apps.googleusercontent.com', * 'email': 'jsmith@example.com', * 'iat': 1353601026, * 'exp': 1353604926} * SAML assertions are similarly specified, but with an identity provider * dependent structure. * * Generated from protobuf field .google.protobuf.Struct claims = 4; * @param \Google\Protobuf\Struct $var * @return $this */ public function setClaims($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Struct::class); $this->claims = $var; return $this; } /** * A list of access level resource names that allow resources to be * accessed by authenticated requester. It is part of Secure GCP processing * for the incoming request. An access level string has the format: * "//{api_service_name}/accessPolicies/{policy_id}/accessLevels/{short_name}" * Example: * "//accesscontextmanager.googleapis.com/accessPolicies/MY_POLICY_ID/accessLevels/MY_LEVEL" * * Generated from protobuf field repeated string access_levels = 5; * @return \Google\Protobuf\Internal\RepeatedField */ public function getAccessLevels() { return $this->access_levels; } /** * A list of access level resource names that allow resources to be * accessed by authenticated requester. It is part of Secure GCP processing * for the incoming request. An access level string has the format: * "//{api_service_name}/accessPolicies/{policy_id}/accessLevels/{short_name}" * Example: * "//accesscontextmanager.googleapis.com/accessPolicies/MY_POLICY_ID/accessLevels/MY_LEVEL" * * Generated from protobuf field repeated string access_levels = 5; * @param array|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setAccessLevels($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->access_levels = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Rpc/Context/AttributeContext/Peer.php ================================================ google.rpc.context.AttributeContext.Peer */ class Peer extends \Google\Protobuf\Internal\Message { /** * The IP address of the peer. * * Generated from protobuf field string ip = 1; */ protected $ip = ''; /** * The network port of the peer. * * Generated from protobuf field int64 port = 2; */ protected $port = 0; /** * The labels associated with the peer. * * Generated from protobuf field map labels = 6; */ private $labels; /** * The identity of this peer. Similar to `Request.auth.principal`, but * relative to the peer instead of the request. For example, the * identity associated with a load balancer that forwarded the request. * * Generated from protobuf field string principal = 7; */ protected $principal = ''; /** * The CLDR country/region code associated with the above IP address. * If the IP address is private, the `region_code` should reflect the * physical location where this peer is running. * * Generated from protobuf field string region_code = 8; */ protected $region_code = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $ip * The IP address of the peer. * @type int|string $port * The network port of the peer. * @type array|\Google\Protobuf\Internal\MapField $labels * The labels associated with the peer. * @type string $principal * The identity of this peer. Similar to `Request.auth.principal`, but * relative to the peer instead of the request. For example, the * identity associated with a load balancer that forwarded the request. * @type string $region_code * The CLDR country/region code associated with the above IP address. * If the IP address is private, the `region_code` should reflect the * physical location where this peer is running. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Rpc\Context\AttributeContext::initOnce(); parent::__construct($data); } /** * The IP address of the peer. * * Generated from protobuf field string ip = 1; * @return string */ public function getIp() { return $this->ip; } /** * The IP address of the peer. * * Generated from protobuf field string ip = 1; * @param string $var * @return $this */ public function setIp($var) { GPBUtil::checkString($var, True); $this->ip = $var; return $this; } /** * The network port of the peer. * * Generated from protobuf field int64 port = 2; * @return int|string */ public function getPort() { return $this->port; } /** * The network port of the peer. * * Generated from protobuf field int64 port = 2; * @param int|string $var * @return $this */ public function setPort($var) { GPBUtil::checkInt64($var); $this->port = $var; return $this; } /** * The labels associated with the peer. * * Generated from protobuf field map labels = 6; * @return \Google\Protobuf\Internal\MapField */ public function getLabels() { return $this->labels; } /** * The labels associated with the peer. * * Generated from protobuf field map labels = 6; * @param array|\Google\Protobuf\Internal\MapField $var * @return $this */ public function setLabels($var) { $arr = GPBUtil::checkMapField($var, \Google\Protobuf\Internal\GPBType::STRING, \Google\Protobuf\Internal\GPBType::STRING); $this->labels = $arr; return $this; } /** * The identity of this peer. Similar to `Request.auth.principal`, but * relative to the peer instead of the request. For example, the * identity associated with a load balancer that forwarded the request. * * Generated from protobuf field string principal = 7; * @return string */ public function getPrincipal() { return $this->principal; } /** * The identity of this peer. Similar to `Request.auth.principal`, but * relative to the peer instead of the request. For example, the * identity associated with a load balancer that forwarded the request. * * Generated from protobuf field string principal = 7; * @param string $var * @return $this */ public function setPrincipal($var) { GPBUtil::checkString($var, True); $this->principal = $var; return $this; } /** * The CLDR country/region code associated with the above IP address. * If the IP address is private, the `region_code` should reflect the * physical location where this peer is running. * * Generated from protobuf field string region_code = 8; * @return string */ public function getRegionCode() { return $this->region_code; } /** * The CLDR country/region code associated with the above IP address. * If the IP address is private, the `region_code` should reflect the * physical location where this peer is running. * * Generated from protobuf field string region_code = 8; * @param string $var * @return $this */ public function setRegionCode($var) { GPBUtil::checkString($var, True); $this->region_code = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Rpc/Context/AttributeContext/Request.php ================================================ google.rpc.context.AttributeContext.Request */ class Request extends \Google\Protobuf\Internal\Message { /** * The unique ID for a request, which can be propagated to downstream * systems. The ID should have low probability of collision * within a single day for a specific service. * * Generated from protobuf field string id = 1; */ protected $id = ''; /** * The HTTP request method, such as `GET`, `POST`. * * Generated from protobuf field string method = 2; */ protected $method = ''; /** * The HTTP request headers. If multiple headers share the same key, they * must be merged according to the HTTP spec. All header keys must be * lowercased, because HTTP header keys are case-insensitive. * * Generated from protobuf field map headers = 3; */ private $headers; /** * The HTTP URL path, excluding the query parameters. * * Generated from protobuf field string path = 4; */ protected $path = ''; /** * The HTTP request `Host` header value. * * Generated from protobuf field string host = 5; */ protected $host = ''; /** * The HTTP URL scheme, such as `http` and `https`. * * Generated from protobuf field string scheme = 6; */ protected $scheme = ''; /** * The HTTP URL query in the format of `name1=value1&name2=value2`, as it * appears in the first line of the HTTP request. No decoding is performed. * * Generated from protobuf field string query = 7; */ protected $query = ''; /** * The timestamp when the `destination` service receives the last byte of * the request. * * Generated from protobuf field .google.protobuf.Timestamp time = 9; */ protected $time = null; /** * The HTTP request size in bytes. If unknown, it must be -1. * * Generated from protobuf field int64 size = 10; */ protected $size = 0; /** * The network protocol used with the request, such as "http/1.1", * "spdy/3", "h2", "h2c", "webrtc", "tcp", "udp", "quic". See * https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids * for details. * * Generated from protobuf field string protocol = 11; */ protected $protocol = ''; /** * A special parameter for request reason. It is used by security systems * to associate auditing information with a request. * * Generated from protobuf field string reason = 12; */ protected $reason = ''; /** * The request authentication. May be absent for unauthenticated requests. * Derived from the HTTP request `Authorization` header or equivalent. * * Generated from protobuf field .google.rpc.context.AttributeContext.Auth auth = 13; */ protected $auth = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $id * The unique ID for a request, which can be propagated to downstream * systems. The ID should have low probability of collision * within a single day for a specific service. * @type string $method * The HTTP request method, such as `GET`, `POST`. * @type array|\Google\Protobuf\Internal\MapField $headers * The HTTP request headers. If multiple headers share the same key, they * must be merged according to the HTTP spec. All header keys must be * lowercased, because HTTP header keys are case-insensitive. * @type string $path * The HTTP URL path, excluding the query parameters. * @type string $host * The HTTP request `Host` header value. * @type string $scheme * The HTTP URL scheme, such as `http` and `https`. * @type string $query * The HTTP URL query in the format of `name1=value1&name2=value2`, as it * appears in the first line of the HTTP request. No decoding is performed. * @type \Google\Protobuf\Timestamp $time * The timestamp when the `destination` service receives the last byte of * the request. * @type int|string $size * The HTTP request size in bytes. If unknown, it must be -1. * @type string $protocol * The network protocol used with the request, such as "http/1.1", * "spdy/3", "h2", "h2c", "webrtc", "tcp", "udp", "quic". See * https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids * for details. * @type string $reason * A special parameter for request reason. It is used by security systems * to associate auditing information with a request. * @type \Google\Rpc\Context\AttributeContext\Auth $auth * The request authentication. May be absent for unauthenticated requests. * Derived from the HTTP request `Authorization` header or equivalent. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Rpc\Context\AttributeContext::initOnce(); parent::__construct($data); } /** * The unique ID for a request, which can be propagated to downstream * systems. The ID should have low probability of collision * within a single day for a specific service. * * Generated from protobuf field string id = 1; * @return string */ public function getId() { return $this->id; } /** * The unique ID for a request, which can be propagated to downstream * systems. The ID should have low probability of collision * within a single day for a specific service. * * Generated from protobuf field string id = 1; * @param string $var * @return $this */ public function setId($var) { GPBUtil::checkString($var, True); $this->id = $var; return $this; } /** * The HTTP request method, such as `GET`, `POST`. * * Generated from protobuf field string method = 2; * @return string */ public function getMethod() { return $this->method; } /** * The HTTP request method, such as `GET`, `POST`. * * Generated from protobuf field string method = 2; * @param string $var * @return $this */ public function setMethod($var) { GPBUtil::checkString($var, True); $this->method = $var; return $this; } /** * The HTTP request headers. If multiple headers share the same key, they * must be merged according to the HTTP spec. All header keys must be * lowercased, because HTTP header keys are case-insensitive. * * Generated from protobuf field map headers = 3; * @return \Google\Protobuf\Internal\MapField */ public function getHeaders() { return $this->headers; } /** * The HTTP request headers. If multiple headers share the same key, they * must be merged according to the HTTP spec. All header keys must be * lowercased, because HTTP header keys are case-insensitive. * * Generated from protobuf field map headers = 3; * @param array|\Google\Protobuf\Internal\MapField $var * @return $this */ public function setHeaders($var) { $arr = GPBUtil::checkMapField($var, \Google\Protobuf\Internal\GPBType::STRING, \Google\Protobuf\Internal\GPBType::STRING); $this->headers = $arr; return $this; } /** * The HTTP URL path, excluding the query parameters. * * Generated from protobuf field string path = 4; * @return string */ public function getPath() { return $this->path; } /** * The HTTP URL path, excluding the query parameters. * * Generated from protobuf field string path = 4; * @param string $var * @return $this */ public function setPath($var) { GPBUtil::checkString($var, True); $this->path = $var; return $this; } /** * The HTTP request `Host` header value. * * Generated from protobuf field string host = 5; * @return string */ public function getHost() { return $this->host; } /** * The HTTP request `Host` header value. * * Generated from protobuf field string host = 5; * @param string $var * @return $this */ public function setHost($var) { GPBUtil::checkString($var, True); $this->host = $var; return $this; } /** * The HTTP URL scheme, such as `http` and `https`. * * Generated from protobuf field string scheme = 6; * @return string */ public function getScheme() { return $this->scheme; } /** * The HTTP URL scheme, such as `http` and `https`. * * Generated from protobuf field string scheme = 6; * @param string $var * @return $this */ public function setScheme($var) { GPBUtil::checkString($var, True); $this->scheme = $var; return $this; } /** * The HTTP URL query in the format of `name1=value1&name2=value2`, as it * appears in the first line of the HTTP request. No decoding is performed. * * Generated from protobuf field string query = 7; * @return string */ public function getQuery() { return $this->query; } /** * The HTTP URL query in the format of `name1=value1&name2=value2`, as it * appears in the first line of the HTTP request. No decoding is performed. * * Generated from protobuf field string query = 7; * @param string $var * @return $this */ public function setQuery($var) { GPBUtil::checkString($var, True); $this->query = $var; return $this; } /** * The timestamp when the `destination` service receives the last byte of * the request. * * Generated from protobuf field .google.protobuf.Timestamp time = 9; * @return \Google\Protobuf\Timestamp|null */ public function getTime() { return $this->time; } public function hasTime() { return isset($this->time); } public function clearTime() { unset($this->time); } /** * The timestamp when the `destination` service receives the last byte of * the request. * * Generated from protobuf field .google.protobuf.Timestamp time = 9; * @param \Google\Protobuf\Timestamp $var * @return $this */ public function setTime($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Timestamp::class); $this->time = $var; return $this; } /** * The HTTP request size in bytes. If unknown, it must be -1. * * Generated from protobuf field int64 size = 10; * @return int|string */ public function getSize() { return $this->size; } /** * The HTTP request size in bytes. If unknown, it must be -1. * * Generated from protobuf field int64 size = 10; * @param int|string $var * @return $this */ public function setSize($var) { GPBUtil::checkInt64($var); $this->size = $var; return $this; } /** * The network protocol used with the request, such as "http/1.1", * "spdy/3", "h2", "h2c", "webrtc", "tcp", "udp", "quic". See * https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids * for details. * * Generated from protobuf field string protocol = 11; * @return string */ public function getProtocol() { return $this->protocol; } /** * The network protocol used with the request, such as "http/1.1", * "spdy/3", "h2", "h2c", "webrtc", "tcp", "udp", "quic". See * https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids * for details. * * Generated from protobuf field string protocol = 11; * @param string $var * @return $this */ public function setProtocol($var) { GPBUtil::checkString($var, True); $this->protocol = $var; return $this; } /** * A special parameter for request reason. It is used by security systems * to associate auditing information with a request. * * Generated from protobuf field string reason = 12; * @return string */ public function getReason() { return $this->reason; } /** * A special parameter for request reason. It is used by security systems * to associate auditing information with a request. * * Generated from protobuf field string reason = 12; * @param string $var * @return $this */ public function setReason($var) { GPBUtil::checkString($var, True); $this->reason = $var; return $this; } /** * The request authentication. May be absent for unauthenticated requests. * Derived from the HTTP request `Authorization` header or equivalent. * * Generated from protobuf field .google.rpc.context.AttributeContext.Auth auth = 13; * @return \Google\Rpc\Context\AttributeContext\Auth|null */ public function getAuth() { return $this->auth; } public function hasAuth() { return isset($this->auth); } public function clearAuth() { unset($this->auth); } /** * The request authentication. May be absent for unauthenticated requests. * Derived from the HTTP request `Authorization` header or equivalent. * * Generated from protobuf field .google.rpc.context.AttributeContext.Auth auth = 13; * @param \Google\Rpc\Context\AttributeContext\Auth $var * @return $this */ public function setAuth($var) { GPBUtil::checkMessage($var, \Google\Rpc\Context\AttributeContext\Auth::class); $this->auth = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Rpc/Context/AttributeContext/Resource.php ================================================ google.rpc.context.AttributeContext.Resource */ class Resource extends \Google\Protobuf\Internal\Message { /** * The name of the service that this resource belongs to, such as * `pubsub.googleapis.com`. The service may be different from the DNS * hostname that actually serves the request. * * Generated from protobuf field string service = 1; */ protected $service = ''; /** * The stable identifier (name) of a resource on the `service`. A resource * can be logically identified as "//{resource.service}/{resource.name}". * The differences between a resource name and a URI are: * * Resource name is a logical identifier, independent of network * protocol and API version. For example, * `//pubsub.googleapis.com/projects/123/topics/news-feed`. * * URI often includes protocol and version information, so it can * be used directly by applications. For example, * `https://pubsub.googleapis.com/v1/projects/123/topics/news-feed`. * See https://cloud.google.com/apis/design/resource_names for details. * * Generated from protobuf field string name = 2; */ protected $name = ''; /** * The type of the resource. The syntax is platform-specific because * different platforms define their resources differently. * For Google APIs, the type format must be "{service}/{kind}", such as * "pubsub.googleapis.com/Topic". * * Generated from protobuf field string type = 3; */ protected $type = ''; /** * The labels or tags on the resource, such as AWS resource tags and * Kubernetes resource labels. * * Generated from protobuf field map labels = 4; */ private $labels; /** * The unique identifier of the resource. UID is unique in the time * and space for this resource within the scope of the service. It is * typically generated by the server on successful creation of a resource * and must not be changed. UID is used to uniquely identify resources * with resource name reuses. This should be a UUID4. * * Generated from protobuf field string uid = 5; */ protected $uid = ''; /** * Annotations is an unstructured key-value map stored with a resource that * may be set by external tools to store and retrieve arbitrary metadata. * They are not queryable and should be preserved when modifying objects. * More info: * https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ * * Generated from protobuf field map annotations = 6; */ private $annotations; /** * Mutable. The display name set by clients. Must be <= 63 characters. * * Generated from protobuf field string display_name = 7; */ protected $display_name = ''; /** * Output only. The timestamp when the resource was created. This may * be either the time creation was initiated or when it was completed. * * Generated from protobuf field .google.protobuf.Timestamp create_time = 8; */ protected $create_time = null; /** * Output only. The timestamp when the resource was last updated. Any * change to the resource made by users must refresh this value. * Changes to a resource made by the service should refresh this value. * * Generated from protobuf field .google.protobuf.Timestamp update_time = 9; */ protected $update_time = null; /** * Output only. The timestamp when the resource was deleted. * If the resource is not deleted, this must be empty. * * Generated from protobuf field .google.protobuf.Timestamp delete_time = 10; */ protected $delete_time = null; /** * Output only. An opaque value that uniquely identifies a version or * generation of a resource. It can be used to confirm that the client * and server agree on the ordering of a resource being written. * * Generated from protobuf field string etag = 11; */ protected $etag = ''; /** * Immutable. The location of the resource. The location encoding is * specific to the service provider, and new encoding may be introduced * as the service evolves. * For Google Cloud products, the encoding is what is used by Google Cloud * APIs, such as `us-east1`, `aws-us-east-1`, and `azure-eastus2`. The * semantics of `location` is identical to the * `cloud.googleapis.com/location` label used by some Google Cloud APIs. * * Generated from protobuf field string location = 12; */ protected $location = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $service * The name of the service that this resource belongs to, such as * `pubsub.googleapis.com`. The service may be different from the DNS * hostname that actually serves the request. * @type string $name * The stable identifier (name) of a resource on the `service`. A resource * can be logically identified as "//{resource.service}/{resource.name}". * The differences between a resource name and a URI are: * * Resource name is a logical identifier, independent of network * protocol and API version. For example, * `//pubsub.googleapis.com/projects/123/topics/news-feed`. * * URI often includes protocol and version information, so it can * be used directly by applications. For example, * `https://pubsub.googleapis.com/v1/projects/123/topics/news-feed`. * See https://cloud.google.com/apis/design/resource_names for details. * @type string $type * The type of the resource. The syntax is platform-specific because * different platforms define their resources differently. * For Google APIs, the type format must be "{service}/{kind}", such as * "pubsub.googleapis.com/Topic". * @type array|\Google\Protobuf\Internal\MapField $labels * The labels or tags on the resource, such as AWS resource tags and * Kubernetes resource labels. * @type string $uid * The unique identifier of the resource. UID is unique in the time * and space for this resource within the scope of the service. It is * typically generated by the server on successful creation of a resource * and must not be changed. UID is used to uniquely identify resources * with resource name reuses. This should be a UUID4. * @type array|\Google\Protobuf\Internal\MapField $annotations * Annotations is an unstructured key-value map stored with a resource that * may be set by external tools to store and retrieve arbitrary metadata. * They are not queryable and should be preserved when modifying objects. * More info: * https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ * @type string $display_name * Mutable. The display name set by clients. Must be <= 63 characters. * @type \Google\Protobuf\Timestamp $create_time * Output only. The timestamp when the resource was created. This may * be either the time creation was initiated or when it was completed. * @type \Google\Protobuf\Timestamp $update_time * Output only. The timestamp when the resource was last updated. Any * change to the resource made by users must refresh this value. * Changes to a resource made by the service should refresh this value. * @type \Google\Protobuf\Timestamp $delete_time * Output only. The timestamp when the resource was deleted. * If the resource is not deleted, this must be empty. * @type string $etag * Output only. An opaque value that uniquely identifies a version or * generation of a resource. It can be used to confirm that the client * and server agree on the ordering of a resource being written. * @type string $location * Immutable. The location of the resource. The location encoding is * specific to the service provider, and new encoding may be introduced * as the service evolves. * For Google Cloud products, the encoding is what is used by Google Cloud * APIs, such as `us-east1`, `aws-us-east-1`, and `azure-eastus2`. The * semantics of `location` is identical to the * `cloud.googleapis.com/location` label used by some Google Cloud APIs. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Rpc\Context\AttributeContext::initOnce(); parent::__construct($data); } /** * The name of the service that this resource belongs to, such as * `pubsub.googleapis.com`. The service may be different from the DNS * hostname that actually serves the request. * * Generated from protobuf field string service = 1; * @return string */ public function getService() { return $this->service; } /** * The name of the service that this resource belongs to, such as * `pubsub.googleapis.com`. The service may be different from the DNS * hostname that actually serves the request. * * Generated from protobuf field string service = 1; * @param string $var * @return $this */ public function setService($var) { GPBUtil::checkString($var, True); $this->service = $var; return $this; } /** * The stable identifier (name) of a resource on the `service`. A resource * can be logically identified as "//{resource.service}/{resource.name}". * The differences between a resource name and a URI are: * * Resource name is a logical identifier, independent of network * protocol and API version. For example, * `//pubsub.googleapis.com/projects/123/topics/news-feed`. * * URI often includes protocol and version information, so it can * be used directly by applications. For example, * `https://pubsub.googleapis.com/v1/projects/123/topics/news-feed`. * See https://cloud.google.com/apis/design/resource_names for details. * * Generated from protobuf field string name = 2; * @return string */ public function getName() { return $this->name; } /** * The stable identifier (name) of a resource on the `service`. A resource * can be logically identified as "//{resource.service}/{resource.name}". * The differences between a resource name and a URI are: * * Resource name is a logical identifier, independent of network * protocol and API version. For example, * `//pubsub.googleapis.com/projects/123/topics/news-feed`. * * URI often includes protocol and version information, so it can * be used directly by applications. For example, * `https://pubsub.googleapis.com/v1/projects/123/topics/news-feed`. * See https://cloud.google.com/apis/design/resource_names for details. * * Generated from protobuf field string name = 2; * @param string $var * @return $this */ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; return $this; } /** * The type of the resource. The syntax is platform-specific because * different platforms define their resources differently. * For Google APIs, the type format must be "{service}/{kind}", such as * "pubsub.googleapis.com/Topic". * * Generated from protobuf field string type = 3; * @return string */ public function getType() { return $this->type; } /** * The type of the resource. The syntax is platform-specific because * different platforms define their resources differently. * For Google APIs, the type format must be "{service}/{kind}", such as * "pubsub.googleapis.com/Topic". * * Generated from protobuf field string type = 3; * @param string $var * @return $this */ public function setType($var) { GPBUtil::checkString($var, True); $this->type = $var; return $this; } /** * The labels or tags on the resource, such as AWS resource tags and * Kubernetes resource labels. * * Generated from protobuf field map labels = 4; * @return \Google\Protobuf\Internal\MapField */ public function getLabels() { return $this->labels; } /** * The labels or tags on the resource, such as AWS resource tags and * Kubernetes resource labels. * * Generated from protobuf field map labels = 4; * @param array|\Google\Protobuf\Internal\MapField $var * @return $this */ public function setLabels($var) { $arr = GPBUtil::checkMapField($var, \Google\Protobuf\Internal\GPBType::STRING, \Google\Protobuf\Internal\GPBType::STRING); $this->labels = $arr; return $this; } /** * The unique identifier of the resource. UID is unique in the time * and space for this resource within the scope of the service. It is * typically generated by the server on successful creation of a resource * and must not be changed. UID is used to uniquely identify resources * with resource name reuses. This should be a UUID4. * * Generated from protobuf field string uid = 5; * @return string */ public function getUid() { return $this->uid; } /** * The unique identifier of the resource. UID is unique in the time * and space for this resource within the scope of the service. It is * typically generated by the server on successful creation of a resource * and must not be changed. UID is used to uniquely identify resources * with resource name reuses. This should be a UUID4. * * Generated from protobuf field string uid = 5; * @param string $var * @return $this */ public function setUid($var) { GPBUtil::checkString($var, True); $this->uid = $var; return $this; } /** * Annotations is an unstructured key-value map stored with a resource that * may be set by external tools to store and retrieve arbitrary metadata. * They are not queryable and should be preserved when modifying objects. * More info: * https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ * * Generated from protobuf field map annotations = 6; * @return \Google\Protobuf\Internal\MapField */ public function getAnnotations() { return $this->annotations; } /** * Annotations is an unstructured key-value map stored with a resource that * may be set by external tools to store and retrieve arbitrary metadata. * They are not queryable and should be preserved when modifying objects. * More info: * https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ * * Generated from protobuf field map annotations = 6; * @param array|\Google\Protobuf\Internal\MapField $var * @return $this */ public function setAnnotations($var) { $arr = GPBUtil::checkMapField($var, \Google\Protobuf\Internal\GPBType::STRING, \Google\Protobuf\Internal\GPBType::STRING); $this->annotations = $arr; return $this; } /** * Mutable. The display name set by clients. Must be <= 63 characters. * * Generated from protobuf field string display_name = 7; * @return string */ public function getDisplayName() { return $this->display_name; } /** * Mutable. The display name set by clients. Must be <= 63 characters. * * Generated from protobuf field string display_name = 7; * @param string $var * @return $this */ public function setDisplayName($var) { GPBUtil::checkString($var, True); $this->display_name = $var; return $this; } /** * Output only. The timestamp when the resource was created. This may * be either the time creation was initiated or when it was completed. * * Generated from protobuf field .google.protobuf.Timestamp create_time = 8; * @return \Google\Protobuf\Timestamp|null */ public function getCreateTime() { return $this->create_time; } public function hasCreateTime() { return isset($this->create_time); } public function clearCreateTime() { unset($this->create_time); } /** * Output only. The timestamp when the resource was created. This may * be either the time creation was initiated or when it was completed. * * Generated from protobuf field .google.protobuf.Timestamp create_time = 8; * @param \Google\Protobuf\Timestamp $var * @return $this */ public function setCreateTime($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Timestamp::class); $this->create_time = $var; return $this; } /** * Output only. The timestamp when the resource was last updated. Any * change to the resource made by users must refresh this value. * Changes to a resource made by the service should refresh this value. * * Generated from protobuf field .google.protobuf.Timestamp update_time = 9; * @return \Google\Protobuf\Timestamp|null */ public function getUpdateTime() { return $this->update_time; } public function hasUpdateTime() { return isset($this->update_time); } public function clearUpdateTime() { unset($this->update_time); } /** * Output only. The timestamp when the resource was last updated. Any * change to the resource made by users must refresh this value. * Changes to a resource made by the service should refresh this value. * * Generated from protobuf field .google.protobuf.Timestamp update_time = 9; * @param \Google\Protobuf\Timestamp $var * @return $this */ public function setUpdateTime($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Timestamp::class); $this->update_time = $var; return $this; } /** * Output only. The timestamp when the resource was deleted. * If the resource is not deleted, this must be empty. * * Generated from protobuf field .google.protobuf.Timestamp delete_time = 10; * @return \Google\Protobuf\Timestamp|null */ public function getDeleteTime() { return $this->delete_time; } public function hasDeleteTime() { return isset($this->delete_time); } public function clearDeleteTime() { unset($this->delete_time); } /** * Output only. The timestamp when the resource was deleted. * If the resource is not deleted, this must be empty. * * Generated from protobuf field .google.protobuf.Timestamp delete_time = 10; * @param \Google\Protobuf\Timestamp $var * @return $this */ public function setDeleteTime($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Timestamp::class); $this->delete_time = $var; return $this; } /** * Output only. An opaque value that uniquely identifies a version or * generation of a resource. It can be used to confirm that the client * and server agree on the ordering of a resource being written. * * Generated from protobuf field string etag = 11; * @return string */ public function getEtag() { return $this->etag; } /** * Output only. An opaque value that uniquely identifies a version or * generation of a resource. It can be used to confirm that the client * and server agree on the ordering of a resource being written. * * Generated from protobuf field string etag = 11; * @param string $var * @return $this */ public function setEtag($var) { GPBUtil::checkString($var, True); $this->etag = $var; return $this; } /** * Immutable. The location of the resource. The location encoding is * specific to the service provider, and new encoding may be introduced * as the service evolves. * For Google Cloud products, the encoding is what is used by Google Cloud * APIs, such as `us-east1`, `aws-us-east-1`, and `azure-eastus2`. The * semantics of `location` is identical to the * `cloud.googleapis.com/location` label used by some Google Cloud APIs. * * Generated from protobuf field string location = 12; * @return string */ public function getLocation() { return $this->location; } /** * Immutable. The location of the resource. The location encoding is * specific to the service provider, and new encoding may be introduced * as the service evolves. * For Google Cloud products, the encoding is what is used by Google Cloud * APIs, such as `us-east1`, `aws-us-east-1`, and `azure-eastus2`. The * semantics of `location` is identical to the * `cloud.googleapis.com/location` label used by some Google Cloud APIs. * * Generated from protobuf field string location = 12; * @param string $var * @return $this */ public function setLocation($var) { GPBUtil::checkString($var, True); $this->location = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Rpc/Context/AttributeContext/Response.php ================================================ google.rpc.context.AttributeContext.Response */ class Response extends \Google\Protobuf\Internal\Message { /** * The HTTP response status code, such as `200` and `404`. * * Generated from protobuf field int64 code = 1; */ protected $code = 0; /** * The HTTP response size in bytes. If unknown, it must be -1. * * Generated from protobuf field int64 size = 2; */ protected $size = 0; /** * The HTTP response headers. If multiple headers share the same key, they * must be merged according to HTTP spec. All header keys must be * lowercased, because HTTP header keys are case-insensitive. * * Generated from protobuf field map headers = 3; */ private $headers; /** * The timestamp when the `destination` service sends the last byte of * the response. * * Generated from protobuf field .google.protobuf.Timestamp time = 4; */ protected $time = null; /** * The amount of time it takes the backend service to fully respond to a * request. Measured from when the destination service starts to send the * request to the backend until when the destination service receives the * complete response from the backend. * * Generated from protobuf field .google.protobuf.Duration backend_latency = 5; */ protected $backend_latency = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type int|string $code * The HTTP response status code, such as `200` and `404`. * @type int|string $size * The HTTP response size in bytes. If unknown, it must be -1. * @type array|\Google\Protobuf\Internal\MapField $headers * The HTTP response headers. If multiple headers share the same key, they * must be merged according to HTTP spec. All header keys must be * lowercased, because HTTP header keys are case-insensitive. * @type \Google\Protobuf\Timestamp $time * The timestamp when the `destination` service sends the last byte of * the response. * @type \Google\Protobuf\Duration $backend_latency * The amount of time it takes the backend service to fully respond to a * request. Measured from when the destination service starts to send the * request to the backend until when the destination service receives the * complete response from the backend. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Rpc\Context\AttributeContext::initOnce(); parent::__construct($data); } /** * The HTTP response status code, such as `200` and `404`. * * Generated from protobuf field int64 code = 1; * @return int|string */ public function getCode() { return $this->code; } /** * The HTTP response status code, such as `200` and `404`. * * Generated from protobuf field int64 code = 1; * @param int|string $var * @return $this */ public function setCode($var) { GPBUtil::checkInt64($var); $this->code = $var; return $this; } /** * The HTTP response size in bytes. If unknown, it must be -1. * * Generated from protobuf field int64 size = 2; * @return int|string */ public function getSize() { return $this->size; } /** * The HTTP response size in bytes. If unknown, it must be -1. * * Generated from protobuf field int64 size = 2; * @param int|string $var * @return $this */ public function setSize($var) { GPBUtil::checkInt64($var); $this->size = $var; return $this; } /** * The HTTP response headers. If multiple headers share the same key, they * must be merged according to HTTP spec. All header keys must be * lowercased, because HTTP header keys are case-insensitive. * * Generated from protobuf field map headers = 3; * @return \Google\Protobuf\Internal\MapField */ public function getHeaders() { return $this->headers; } /** * The HTTP response headers. If multiple headers share the same key, they * must be merged according to HTTP spec. All header keys must be * lowercased, because HTTP header keys are case-insensitive. * * Generated from protobuf field map headers = 3; * @param array|\Google\Protobuf\Internal\MapField $var * @return $this */ public function setHeaders($var) { $arr = GPBUtil::checkMapField($var, \Google\Protobuf\Internal\GPBType::STRING, \Google\Protobuf\Internal\GPBType::STRING); $this->headers = $arr; return $this; } /** * The timestamp when the `destination` service sends the last byte of * the response. * * Generated from protobuf field .google.protobuf.Timestamp time = 4; * @return \Google\Protobuf\Timestamp|null */ public function getTime() { return $this->time; } public function hasTime() { return isset($this->time); } public function clearTime() { unset($this->time); } /** * The timestamp when the `destination` service sends the last byte of * the response. * * Generated from protobuf field .google.protobuf.Timestamp time = 4; * @param \Google\Protobuf\Timestamp $var * @return $this */ public function setTime($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Timestamp::class); $this->time = $var; return $this; } /** * The amount of time it takes the backend service to fully respond to a * request. Measured from when the destination service starts to send the * request to the backend until when the destination service receives the * complete response from the backend. * * Generated from protobuf field .google.protobuf.Duration backend_latency = 5; * @return \Google\Protobuf\Duration|null */ public function getBackendLatency() { return $this->backend_latency; } public function hasBackendLatency() { return isset($this->backend_latency); } public function clearBackendLatency() { unset($this->backend_latency); } /** * The amount of time it takes the backend service to fully respond to a * request. Measured from when the destination service starts to send the * request to the backend until when the destination service receives the * complete response from the backend. * * Generated from protobuf field .google.protobuf.Duration backend_latency = 5; * @param \Google\Protobuf\Duration $var * @return $this */ public function setBackendLatency($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Duration::class); $this->backend_latency = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Rpc/Context/AttributeContext.php ================================================ google.rpc.context.AttributeContext */ class AttributeContext extends \Google\Protobuf\Internal\Message { /** * The origin of a network activity. In a multi hop network activity, * the origin represents the sender of the first hop. For the first hop, * the `source` and the `origin` must have the same content. * * Generated from protobuf field .google.rpc.context.AttributeContext.Peer origin = 7; */ protected $origin = null; /** * The source of a network activity, such as starting a TCP connection. * In a multi hop network activity, the source represents the sender of the * last hop. * * Generated from protobuf field .google.rpc.context.AttributeContext.Peer source = 1; */ protected $source = null; /** * The destination of a network activity, such as accepting a TCP connection. * In a multi hop network activity, the destination represents the receiver of * the last hop. * * Generated from protobuf field .google.rpc.context.AttributeContext.Peer destination = 2; */ protected $destination = null; /** * Represents a network request, such as an HTTP request. * * Generated from protobuf field .google.rpc.context.AttributeContext.Request request = 3; */ protected $request = null; /** * Represents a network response, such as an HTTP response. * * Generated from protobuf field .google.rpc.context.AttributeContext.Response response = 4; */ protected $response = null; /** * Represents a target resource that is involved with a network activity. * If multiple resources are involved with an activity, this must be the * primary one. * * Generated from protobuf field .google.rpc.context.AttributeContext.Resource resource = 5; */ protected $resource = null; /** * Represents an API operation that is involved to a network activity. * * Generated from protobuf field .google.rpc.context.AttributeContext.Api api = 6; */ protected $api = null; /** * Supports extensions for advanced use cases, such as logs and metrics. * * Generated from protobuf field repeated .google.protobuf.Any extensions = 8; */ private $extensions; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type \Google\Rpc\Context\AttributeContext\Peer $origin * The origin of a network activity. In a multi hop network activity, * the origin represents the sender of the first hop. For the first hop, * the `source` and the `origin` must have the same content. * @type \Google\Rpc\Context\AttributeContext\Peer $source * The source of a network activity, such as starting a TCP connection. * In a multi hop network activity, the source represents the sender of the * last hop. * @type \Google\Rpc\Context\AttributeContext\Peer $destination * The destination of a network activity, such as accepting a TCP connection. * In a multi hop network activity, the destination represents the receiver of * the last hop. * @type \Google\Rpc\Context\AttributeContext\Request $request * Represents a network request, such as an HTTP request. * @type \Google\Rpc\Context\AttributeContext\Response $response * Represents a network response, such as an HTTP response. * @type \Google\Rpc\Context\AttributeContext\Resource $resource * Represents a target resource that is involved with a network activity. * If multiple resources are involved with an activity, this must be the * primary one. * @type \Google\Rpc\Context\AttributeContext\Api $api * Represents an API operation that is involved to a network activity. * @type array<\Google\Protobuf\Any>|\Google\Protobuf\Internal\RepeatedField $extensions * Supports extensions for advanced use cases, such as logs and metrics. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Rpc\Context\AttributeContext::initOnce(); parent::__construct($data); } /** * The origin of a network activity. In a multi hop network activity, * the origin represents the sender of the first hop. For the first hop, * the `source` and the `origin` must have the same content. * * Generated from protobuf field .google.rpc.context.AttributeContext.Peer origin = 7; * @return \Google\Rpc\Context\AttributeContext\Peer|null */ public function getOrigin() { return $this->origin; } public function hasOrigin() { return isset($this->origin); } public function clearOrigin() { unset($this->origin); } /** * The origin of a network activity. In a multi hop network activity, * the origin represents the sender of the first hop. For the first hop, * the `source` and the `origin` must have the same content. * * Generated from protobuf field .google.rpc.context.AttributeContext.Peer origin = 7; * @param \Google\Rpc\Context\AttributeContext\Peer $var * @return $this */ public function setOrigin($var) { GPBUtil::checkMessage($var, \Google\Rpc\Context\AttributeContext\Peer::class); $this->origin = $var; return $this; } /** * The source of a network activity, such as starting a TCP connection. * In a multi hop network activity, the source represents the sender of the * last hop. * * Generated from protobuf field .google.rpc.context.AttributeContext.Peer source = 1; * @return \Google\Rpc\Context\AttributeContext\Peer|null */ public function getSource() { return $this->source; } public function hasSource() { return isset($this->source); } public function clearSource() { unset($this->source); } /** * The source of a network activity, such as starting a TCP connection. * In a multi hop network activity, the source represents the sender of the * last hop. * * Generated from protobuf field .google.rpc.context.AttributeContext.Peer source = 1; * @param \Google\Rpc\Context\AttributeContext\Peer $var * @return $this */ public function setSource($var) { GPBUtil::checkMessage($var, \Google\Rpc\Context\AttributeContext\Peer::class); $this->source = $var; return $this; } /** * The destination of a network activity, such as accepting a TCP connection. * In a multi hop network activity, the destination represents the receiver of * the last hop. * * Generated from protobuf field .google.rpc.context.AttributeContext.Peer destination = 2; * @return \Google\Rpc\Context\AttributeContext\Peer|null */ public function getDestination() { return $this->destination; } public function hasDestination() { return isset($this->destination); } public function clearDestination() { unset($this->destination); } /** * The destination of a network activity, such as accepting a TCP connection. * In a multi hop network activity, the destination represents the receiver of * the last hop. * * Generated from protobuf field .google.rpc.context.AttributeContext.Peer destination = 2; * @param \Google\Rpc\Context\AttributeContext\Peer $var * @return $this */ public function setDestination($var) { GPBUtil::checkMessage($var, \Google\Rpc\Context\AttributeContext\Peer::class); $this->destination = $var; return $this; } /** * Represents a network request, such as an HTTP request. * * Generated from protobuf field .google.rpc.context.AttributeContext.Request request = 3; * @return \Google\Rpc\Context\AttributeContext\Request|null */ public function getRequest() { return $this->request; } public function hasRequest() { return isset($this->request); } public function clearRequest() { unset($this->request); } /** * Represents a network request, such as an HTTP request. * * Generated from protobuf field .google.rpc.context.AttributeContext.Request request = 3; * @param \Google\Rpc\Context\AttributeContext\Request $var * @return $this */ public function setRequest($var) { GPBUtil::checkMessage($var, \Google\Rpc\Context\AttributeContext\Request::class); $this->request = $var; return $this; } /** * Represents a network response, such as an HTTP response. * * Generated from protobuf field .google.rpc.context.AttributeContext.Response response = 4; * @return \Google\Rpc\Context\AttributeContext\Response|null */ public function getResponse() { return $this->response; } public function hasResponse() { return isset($this->response); } public function clearResponse() { unset($this->response); } /** * Represents a network response, such as an HTTP response. * * Generated from protobuf field .google.rpc.context.AttributeContext.Response response = 4; * @param \Google\Rpc\Context\AttributeContext\Response $var * @return $this */ public function setResponse($var) { GPBUtil::checkMessage($var, \Google\Rpc\Context\AttributeContext\Response::class); $this->response = $var; return $this; } /** * Represents a target resource that is involved with a network activity. * If multiple resources are involved with an activity, this must be the * primary one. * * Generated from protobuf field .google.rpc.context.AttributeContext.Resource resource = 5; * @return \Google\Rpc\Context\AttributeContext\Resource|null */ public function getResource() { return $this->resource; } public function hasResource() { return isset($this->resource); } public function clearResource() { unset($this->resource); } /** * Represents a target resource that is involved with a network activity. * If multiple resources are involved with an activity, this must be the * primary one. * * Generated from protobuf field .google.rpc.context.AttributeContext.Resource resource = 5; * @param \Google\Rpc\Context\AttributeContext\Resource $var * @return $this */ public function setResource($var) { GPBUtil::checkMessage($var, \Google\Rpc\Context\AttributeContext\Resource::class); $this->resource = $var; return $this; } /** * Represents an API operation that is involved to a network activity. * * Generated from protobuf field .google.rpc.context.AttributeContext.Api api = 6; * @return \Google\Rpc\Context\AttributeContext\Api|null */ public function getApi() { return $this->api; } public function hasApi() { return isset($this->api); } public function clearApi() { unset($this->api); } /** * Represents an API operation that is involved to a network activity. * * Generated from protobuf field .google.rpc.context.AttributeContext.Api api = 6; * @param \Google\Rpc\Context\AttributeContext\Api $var * @return $this */ public function setApi($var) { GPBUtil::checkMessage($var, \Google\Rpc\Context\AttributeContext\Api::class); $this->api = $var; return $this; } /** * Supports extensions for advanced use cases, such as logs and metrics. * * Generated from protobuf field repeated .google.protobuf.Any extensions = 8; * @return \Google\Protobuf\Internal\RepeatedField */ public function getExtensions() { return $this->extensions; } /** * Supports extensions for advanced use cases, such as logs and metrics. * * Generated from protobuf field repeated .google.protobuf.Any extensions = 8; * @param array<\Google\Protobuf\Any>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setExtensions($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Any::class); $this->extensions = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Rpc/Context/AuditContext.php ================================================ google.rpc.context.AuditContext */ class AuditContext extends \Google\Protobuf\Internal\Message { /** * Serialized audit log. * * Generated from protobuf field bytes audit_log = 1; */ protected $audit_log = ''; /** * An API request message that is scrubbed based on the method annotation. * This field should only be filled if audit_log field is present. * Service Control will use this to assemble a complete log for Cloud Audit * Logs and Google internal audit logs. * * Generated from protobuf field .google.protobuf.Struct scrubbed_request = 2; */ protected $scrubbed_request = null; /** * An API response message that is scrubbed based on the method annotation. * This field should only be filled if audit_log field is present. * Service Control will use this to assemble a complete log for Cloud Audit * Logs and Google internal audit logs. * * Generated from protobuf field .google.protobuf.Struct scrubbed_response = 3; */ protected $scrubbed_response = null; /** * Number of scrubbed response items. * * Generated from protobuf field int32 scrubbed_response_item_count = 4; */ protected $scrubbed_response_item_count = 0; /** * Audit resource name which is scrubbed. * * Generated from protobuf field string target_resource = 5; */ protected $target_resource = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $audit_log * Serialized audit log. * @type \Google\Protobuf\Struct $scrubbed_request * An API request message that is scrubbed based on the method annotation. * This field should only be filled if audit_log field is present. * Service Control will use this to assemble a complete log for Cloud Audit * Logs and Google internal audit logs. * @type \Google\Protobuf\Struct $scrubbed_response * An API response message that is scrubbed based on the method annotation. * This field should only be filled if audit_log field is present. * Service Control will use this to assemble a complete log for Cloud Audit * Logs and Google internal audit logs. * @type int $scrubbed_response_item_count * Number of scrubbed response items. * @type string $target_resource * Audit resource name which is scrubbed. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Rpc\Context\AuditContext::initOnce(); parent::__construct($data); } /** * Serialized audit log. * * Generated from protobuf field bytes audit_log = 1; * @return string */ public function getAuditLog() { return $this->audit_log; } /** * Serialized audit log. * * Generated from protobuf field bytes audit_log = 1; * @param string $var * @return $this */ public function setAuditLog($var) { GPBUtil::checkString($var, False); $this->audit_log = $var; return $this; } /** * An API request message that is scrubbed based on the method annotation. * This field should only be filled if audit_log field is present. * Service Control will use this to assemble a complete log for Cloud Audit * Logs and Google internal audit logs. * * Generated from protobuf field .google.protobuf.Struct scrubbed_request = 2; * @return \Google\Protobuf\Struct|null */ public function getScrubbedRequest() { return $this->scrubbed_request; } public function hasScrubbedRequest() { return isset($this->scrubbed_request); } public function clearScrubbedRequest() { unset($this->scrubbed_request); } /** * An API request message that is scrubbed based on the method annotation. * This field should only be filled if audit_log field is present. * Service Control will use this to assemble a complete log for Cloud Audit * Logs and Google internal audit logs. * * Generated from protobuf field .google.protobuf.Struct scrubbed_request = 2; * @param \Google\Protobuf\Struct $var * @return $this */ public function setScrubbedRequest($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Struct::class); $this->scrubbed_request = $var; return $this; } /** * An API response message that is scrubbed based on the method annotation. * This field should only be filled if audit_log field is present. * Service Control will use this to assemble a complete log for Cloud Audit * Logs and Google internal audit logs. * * Generated from protobuf field .google.protobuf.Struct scrubbed_response = 3; * @return \Google\Protobuf\Struct|null */ public function getScrubbedResponse() { return $this->scrubbed_response; } public function hasScrubbedResponse() { return isset($this->scrubbed_response); } public function clearScrubbedResponse() { unset($this->scrubbed_response); } /** * An API response message that is scrubbed based on the method annotation. * This field should only be filled if audit_log field is present. * Service Control will use this to assemble a complete log for Cloud Audit * Logs and Google internal audit logs. * * Generated from protobuf field .google.protobuf.Struct scrubbed_response = 3; * @param \Google\Protobuf\Struct $var * @return $this */ public function setScrubbedResponse($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Struct::class); $this->scrubbed_response = $var; return $this; } /** * Number of scrubbed response items. * * Generated from protobuf field int32 scrubbed_response_item_count = 4; * @return int */ public function getScrubbedResponseItemCount() { return $this->scrubbed_response_item_count; } /** * Number of scrubbed response items. * * Generated from protobuf field int32 scrubbed_response_item_count = 4; * @param int $var * @return $this */ public function setScrubbedResponseItemCount($var) { GPBUtil::checkInt32($var); $this->scrubbed_response_item_count = $var; return $this; } /** * Audit resource name which is scrubbed. * * Generated from protobuf field string target_resource = 5; * @return string */ public function getTargetResource() { return $this->target_resource; } /** * Audit resource name which is scrubbed. * * Generated from protobuf field string target_resource = 5; * @param string $var * @return $this */ public function setTargetResource($var) { GPBUtil::checkString($var, True); $this->target_resource = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Rpc/DebugInfo.php ================================================ google.rpc.DebugInfo */ class DebugInfo extends \Google\Protobuf\Internal\Message { /** * The stack trace entries indicating where the error occurred. * * Generated from protobuf field repeated string stack_entries = 1; */ private $stack_entries; /** * Additional debugging information provided by the server. * * Generated from protobuf field string detail = 2; */ protected $detail = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type array|\Google\Protobuf\Internal\RepeatedField $stack_entries * The stack trace entries indicating where the error occurred. * @type string $detail * Additional debugging information provided by the server. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Rpc\ErrorDetails::initOnce(); parent::__construct($data); } /** * The stack trace entries indicating where the error occurred. * * Generated from protobuf field repeated string stack_entries = 1; * @return \Google\Protobuf\Internal\RepeatedField */ public function getStackEntries() { return $this->stack_entries; } /** * The stack trace entries indicating where the error occurred. * * Generated from protobuf field repeated string stack_entries = 1; * @param array|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setStackEntries($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->stack_entries = $arr; return $this; } /** * Additional debugging information provided by the server. * * Generated from protobuf field string detail = 2; * @return string */ public function getDetail() { return $this->detail; } /** * Additional debugging information provided by the server. * * Generated from protobuf field string detail = 2; * @param string $var * @return $this */ public function setDetail($var) { GPBUtil::checkString($var, True); $this->detail = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Rpc/ErrorInfo.php ================================================ google.rpc.ErrorInfo */ class ErrorInfo extends \Google\Protobuf\Internal\Message { /** * The reason of the error. This is a constant value that identifies the * proximate cause of the error. Error reasons are unique within a particular * domain of errors. This should be at most 63 characters and match a * regular expression of `[A-Z][A-Z0-9_]+[A-Z0-9]`, which represents * UPPER_SNAKE_CASE. * * Generated from protobuf field string reason = 1; */ protected $reason = ''; /** * The logical grouping to which the "reason" belongs. The error domain * is typically the registered service name of the tool or product that * generates the error. Example: "pubsub.googleapis.com". If the error is * generated by some common infrastructure, the error domain must be a * globally unique value that identifies the infrastructure. For Google API * infrastructure, the error domain is "googleapis.com". * * Generated from protobuf field string domain = 2; */ protected $domain = ''; /** * Additional structured details about this error. * Keys must match a regular expression of `[a-z][a-zA-Z0-9-_]+` but should * ideally be lowerCamelCase. Also, they must be limited to 64 characters in * length. When identifying the current value of an exceeded limit, the units * should be contained in the key, not the value. For example, rather than * `{"instanceLimit": "100/request"}`, should be returned as, * `{"instanceLimitPerRequest": "100"}`, if the client exceeds the number of * instances that can be created in a single (batch) request. * * Generated from protobuf field map metadata = 3; */ private $metadata; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $reason * The reason of the error. This is a constant value that identifies the * proximate cause of the error. Error reasons are unique within a particular * domain of errors. This should be at most 63 characters and match a * regular expression of `[A-Z][A-Z0-9_]+[A-Z0-9]`, which represents * UPPER_SNAKE_CASE. * @type string $domain * The logical grouping to which the "reason" belongs. The error domain * is typically the registered service name of the tool or product that * generates the error. Example: "pubsub.googleapis.com". If the error is * generated by some common infrastructure, the error domain must be a * globally unique value that identifies the infrastructure. For Google API * infrastructure, the error domain is "googleapis.com". * @type array|\Google\Protobuf\Internal\MapField $metadata * Additional structured details about this error. * Keys must match a regular expression of `[a-z][a-zA-Z0-9-_]+` but should * ideally be lowerCamelCase. Also, they must be limited to 64 characters in * length. When identifying the current value of an exceeded limit, the units * should be contained in the key, not the value. For example, rather than * `{"instanceLimit": "100/request"}`, should be returned as, * `{"instanceLimitPerRequest": "100"}`, if the client exceeds the number of * instances that can be created in a single (batch) request. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Rpc\ErrorDetails::initOnce(); parent::__construct($data); } /** * The reason of the error. This is a constant value that identifies the * proximate cause of the error. Error reasons are unique within a particular * domain of errors. This should be at most 63 characters and match a * regular expression of `[A-Z][A-Z0-9_]+[A-Z0-9]`, which represents * UPPER_SNAKE_CASE. * * Generated from protobuf field string reason = 1; * @return string */ public function getReason() { return $this->reason; } /** * The reason of the error. This is a constant value that identifies the * proximate cause of the error. Error reasons are unique within a particular * domain of errors. This should be at most 63 characters and match a * regular expression of `[A-Z][A-Z0-9_]+[A-Z0-9]`, which represents * UPPER_SNAKE_CASE. * * Generated from protobuf field string reason = 1; * @param string $var * @return $this */ public function setReason($var) { GPBUtil::checkString($var, True); $this->reason = $var; return $this; } /** * The logical grouping to which the "reason" belongs. The error domain * is typically the registered service name of the tool or product that * generates the error. Example: "pubsub.googleapis.com". If the error is * generated by some common infrastructure, the error domain must be a * globally unique value that identifies the infrastructure. For Google API * infrastructure, the error domain is "googleapis.com". * * Generated from protobuf field string domain = 2; * @return string */ public function getDomain() { return $this->domain; } /** * The logical grouping to which the "reason" belongs. The error domain * is typically the registered service name of the tool or product that * generates the error. Example: "pubsub.googleapis.com". If the error is * generated by some common infrastructure, the error domain must be a * globally unique value that identifies the infrastructure. For Google API * infrastructure, the error domain is "googleapis.com". * * Generated from protobuf field string domain = 2; * @param string $var * @return $this */ public function setDomain($var) { GPBUtil::checkString($var, True); $this->domain = $var; return $this; } /** * Additional structured details about this error. * Keys must match a regular expression of `[a-z][a-zA-Z0-9-_]+` but should * ideally be lowerCamelCase. Also, they must be limited to 64 characters in * length. When identifying the current value of an exceeded limit, the units * should be contained in the key, not the value. For example, rather than * `{"instanceLimit": "100/request"}`, should be returned as, * `{"instanceLimitPerRequest": "100"}`, if the client exceeds the number of * instances that can be created in a single (batch) request. * * Generated from protobuf field map metadata = 3; * @return \Google\Protobuf\Internal\MapField */ public function getMetadata() { return $this->metadata; } /** * Additional structured details about this error. * Keys must match a regular expression of `[a-z][a-zA-Z0-9-_]+` but should * ideally be lowerCamelCase. Also, they must be limited to 64 characters in * length. When identifying the current value of an exceeded limit, the units * should be contained in the key, not the value. For example, rather than * `{"instanceLimit": "100/request"}`, should be returned as, * `{"instanceLimitPerRequest": "100"}`, if the client exceeds the number of * instances that can be created in a single (batch) request. * * Generated from protobuf field map metadata = 3; * @param array|\Google\Protobuf\Internal\MapField $var * @return $this */ public function setMetadata($var) { $arr = GPBUtil::checkMapField($var, \Google\Protobuf\Internal\GPBType::STRING, \Google\Protobuf\Internal\GPBType::STRING); $this->metadata = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Rpc/Help/Link.php ================================================ google.rpc.Help.Link */ class Link extends \Google\Protobuf\Internal\Message { /** * Describes what the link offers. * * Generated from protobuf field string description = 1; */ protected $description = ''; /** * The URL of the link. * * Generated from protobuf field string url = 2; */ protected $url = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $description * Describes what the link offers. * @type string $url * The URL of the link. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Rpc\ErrorDetails::initOnce(); parent::__construct($data); } /** * Describes what the link offers. * * Generated from protobuf field string description = 1; * @return string */ public function getDescription() { return $this->description; } /** * Describes what the link offers. * * Generated from protobuf field string description = 1; * @param string $var * @return $this */ public function setDescription($var) { GPBUtil::checkString($var, True); $this->description = $var; return $this; } /** * The URL of the link. * * Generated from protobuf field string url = 2; * @return string */ public function getUrl() { return $this->url; } /** * The URL of the link. * * Generated from protobuf field string url = 2; * @param string $var * @return $this */ public function setUrl($var) { GPBUtil::checkString($var, True); $this->url = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Rpc/Help.php ================================================ google.rpc.Help */ class Help extends \Google\Protobuf\Internal\Message { /** * URL(s) pointing to additional information on handling the current error. * * Generated from protobuf field repeated .google.rpc.Help.Link links = 1; */ private $links; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type array<\Google\Rpc\Help\Link>|\Google\Protobuf\Internal\RepeatedField $links * URL(s) pointing to additional information on handling the current error. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Rpc\ErrorDetails::initOnce(); parent::__construct($data); } /** * URL(s) pointing to additional information on handling the current error. * * Generated from protobuf field repeated .google.rpc.Help.Link links = 1; * @return \Google\Protobuf\Internal\RepeatedField */ public function getLinks() { return $this->links; } /** * URL(s) pointing to additional information on handling the current error. * * Generated from protobuf field repeated .google.rpc.Help.Link links = 1; * @param array<\Google\Rpc\Help\Link>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setLinks($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Rpc\Help\Link::class); $this->links = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Rpc/LocalizedMessage.php ================================================ google.rpc.LocalizedMessage */ class LocalizedMessage extends \Google\Protobuf\Internal\Message { /** * The locale used following the specification defined at * https://www.rfc-editor.org/rfc/bcp/bcp47.txt. * Examples are: "en-US", "fr-CH", "es-MX" * * Generated from protobuf field string locale = 1; */ protected $locale = ''; /** * The localized error message in the above locale. * * Generated from protobuf field string message = 2; */ protected $message = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $locale * The locale used following the specification defined at * https://www.rfc-editor.org/rfc/bcp/bcp47.txt. * Examples are: "en-US", "fr-CH", "es-MX" * @type string $message * The localized error message in the above locale. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Rpc\ErrorDetails::initOnce(); parent::__construct($data); } /** * The locale used following the specification defined at * https://www.rfc-editor.org/rfc/bcp/bcp47.txt. * Examples are: "en-US", "fr-CH", "es-MX" * * Generated from protobuf field string locale = 1; * @return string */ public function getLocale() { return $this->locale; } /** * The locale used following the specification defined at * https://www.rfc-editor.org/rfc/bcp/bcp47.txt. * Examples are: "en-US", "fr-CH", "es-MX" * * Generated from protobuf field string locale = 1; * @param string $var * @return $this */ public function setLocale($var) { GPBUtil::checkString($var, True); $this->locale = $var; return $this; } /** * The localized error message in the above locale. * * Generated from protobuf field string message = 2; * @return string */ public function getMessage() { return $this->message; } /** * The localized error message in the above locale. * * Generated from protobuf field string message = 2; * @param string $var * @return $this */ public function setMessage($var) { GPBUtil::checkString($var, True); $this->message = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Rpc/PreconditionFailure/Violation.php ================================================ google.rpc.PreconditionFailure.Violation */ class Violation extends \Google\Protobuf\Internal\Message { /** * The type of PreconditionFailure. We recommend using a service-specific * enum type to define the supported precondition violation subjects. For * example, "TOS" for "Terms of Service violation". * * Generated from protobuf field string type = 1; */ protected $type = ''; /** * The subject, relative to the type, that failed. * For example, "google.com/cloud" relative to the "TOS" type would indicate * which terms of service is being referenced. * * Generated from protobuf field string subject = 2; */ protected $subject = ''; /** * A description of how the precondition failed. Developers can use this * description to understand how to fix the failure. * For example: "Terms of service not accepted". * * Generated from protobuf field string description = 3; */ protected $description = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $type * The type of PreconditionFailure. We recommend using a service-specific * enum type to define the supported precondition violation subjects. For * example, "TOS" for "Terms of Service violation". * @type string $subject * The subject, relative to the type, that failed. * For example, "google.com/cloud" relative to the "TOS" type would indicate * which terms of service is being referenced. * @type string $description * A description of how the precondition failed. Developers can use this * description to understand how to fix the failure. * For example: "Terms of service not accepted". * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Rpc\ErrorDetails::initOnce(); parent::__construct($data); } /** * The type of PreconditionFailure. We recommend using a service-specific * enum type to define the supported precondition violation subjects. For * example, "TOS" for "Terms of Service violation". * * Generated from protobuf field string type = 1; * @return string */ public function getType() { return $this->type; } /** * The type of PreconditionFailure. We recommend using a service-specific * enum type to define the supported precondition violation subjects. For * example, "TOS" for "Terms of Service violation". * * Generated from protobuf field string type = 1; * @param string $var * @return $this */ public function setType($var) { GPBUtil::checkString($var, True); $this->type = $var; return $this; } /** * The subject, relative to the type, that failed. * For example, "google.com/cloud" relative to the "TOS" type would indicate * which terms of service is being referenced. * * Generated from protobuf field string subject = 2; * @return string */ public function getSubject() { return $this->subject; } /** * The subject, relative to the type, that failed. * For example, "google.com/cloud" relative to the "TOS" type would indicate * which terms of service is being referenced. * * Generated from protobuf field string subject = 2; * @param string $var * @return $this */ public function setSubject($var) { GPBUtil::checkString($var, True); $this->subject = $var; return $this; } /** * A description of how the precondition failed. Developers can use this * description to understand how to fix the failure. * For example: "Terms of service not accepted". * * Generated from protobuf field string description = 3; * @return string */ public function getDescription() { return $this->description; } /** * A description of how the precondition failed. Developers can use this * description to understand how to fix the failure. * For example: "Terms of service not accepted". * * Generated from protobuf field string description = 3; * @param string $var * @return $this */ public function setDescription($var) { GPBUtil::checkString($var, True); $this->description = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Rpc/PreconditionFailure.php ================================================ google.rpc.PreconditionFailure */ class PreconditionFailure extends \Google\Protobuf\Internal\Message { /** * Describes all precondition violations. * * Generated from protobuf field repeated .google.rpc.PreconditionFailure.Violation violations = 1; */ private $violations; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type array<\Google\Rpc\PreconditionFailure\Violation>|\Google\Protobuf\Internal\RepeatedField $violations * Describes all precondition violations. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Rpc\ErrorDetails::initOnce(); parent::__construct($data); } /** * Describes all precondition violations. * * Generated from protobuf field repeated .google.rpc.PreconditionFailure.Violation violations = 1; * @return \Google\Protobuf\Internal\RepeatedField */ public function getViolations() { return $this->violations; } /** * Describes all precondition violations. * * Generated from protobuf field repeated .google.rpc.PreconditionFailure.Violation violations = 1; * @param array<\Google\Rpc\PreconditionFailure\Violation>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setViolations($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Rpc\PreconditionFailure\Violation::class); $this->violations = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Rpc/QuotaFailure/Violation.php ================================================ google.rpc.QuotaFailure.Violation */ class Violation extends \Google\Protobuf\Internal\Message { /** * The subject on which the quota check failed. * For example, "clientip:" or "project:". * * Generated from protobuf field string subject = 1; */ protected $subject = ''; /** * A description of how the quota check failed. Clients can use this * description to find more about the quota configuration in the service's * public documentation, or find the relevant quota limit to adjust through * developer console. * For example: "Service disabled" or "Daily Limit for read operations * exceeded". * * Generated from protobuf field string description = 2; */ protected $description = ''; /** * The API Service from which the `QuotaFailure.Violation` orginates. In * some cases, Quota issues originate from an API Service other than the one * that was called. In other words, a dependency of the called API Service * could be the cause of the `QuotaFailure`, and this field would have the * dependency API service name. * For example, if the called API is Kubernetes Engine API * (container.googleapis.com), and a quota violation occurs in the * Kubernetes Engine API itself, this field would be * "container.googleapis.com". On the other hand, if the quota violation * occurs when the Kubernetes Engine API creates VMs in the Compute Engine * API (compute.googleapis.com), this field would be * "compute.googleapis.com". * * Generated from protobuf field string api_service = 3; */ protected $api_service = ''; /** * The metric of the violated quota. A quota metric is a named counter to * measure usage, such as API requests or CPUs. When an activity occurs in a * service, such as Virtual Machine allocation, one or more quota metrics * may be affected. * For example, "compute.googleapis.com/cpus_per_vm_family", * "storage.googleapis.com/internet_egress_bandwidth". * * Generated from protobuf field string quota_metric = 4; */ protected $quota_metric = ''; /** * The id of the violated quota. Also know as "limit name", this is the * unique identifier of a quota in the context of an API service. * For example, "CPUS-PER-VM-FAMILY-per-project-region". * * Generated from protobuf field string quota_id = 5; */ protected $quota_id = ''; /** * The dimensions of the violated quota. Every non-global quota is enforced * on a set of dimensions. While quota metric defines what to count, the * dimensions specify for what aspects the counter should be increased. * For example, the quota "CPUs per region per VM family" enforces a limit * on the metric "compute.googleapis.com/cpus_per_vm_family" on dimensions * "region" and "vm_family". And if the violation occurred in region * "us-central1" and for VM family "n1", the quota_dimensions would be, * { * "region": "us-central1", * "vm_family": "n1", * } * When a quota is enforced globally, the quota_dimensions would always be * empty. * * Generated from protobuf field map quota_dimensions = 6; */ private $quota_dimensions; /** * The enforced quota value at the time of the `QuotaFailure`. * For example, if the enforced quota value at the time of the * `QuotaFailure` on the number of CPUs is "10", then the value of this * field would reflect this quantity. * * Generated from protobuf field int64 quota_value = 7; */ protected $quota_value = 0; /** * The new quota value being rolled out at the time of the violation. At the * completion of the rollout, this value will be enforced in place of * quota_value. If no rollout is in progress at the time of the violation, * this field is not set. * For example, if at the time of the violation a rollout is in progress * changing the number of CPUs quota from 10 to 20, 20 would be the value of * this field. * * Generated from protobuf field optional int64 future_quota_value = 8; */ protected $future_quota_value = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $subject * The subject on which the quota check failed. * For example, "clientip:" or "project:". * @type string $description * A description of how the quota check failed. Clients can use this * description to find more about the quota configuration in the service's * public documentation, or find the relevant quota limit to adjust through * developer console. * For example: "Service disabled" or "Daily Limit for read operations * exceeded". * @type string $api_service * The API Service from which the `QuotaFailure.Violation` orginates. In * some cases, Quota issues originate from an API Service other than the one * that was called. In other words, a dependency of the called API Service * could be the cause of the `QuotaFailure`, and this field would have the * dependency API service name. * For example, if the called API is Kubernetes Engine API * (container.googleapis.com), and a quota violation occurs in the * Kubernetes Engine API itself, this field would be * "container.googleapis.com". On the other hand, if the quota violation * occurs when the Kubernetes Engine API creates VMs in the Compute Engine * API (compute.googleapis.com), this field would be * "compute.googleapis.com". * @type string $quota_metric * The metric of the violated quota. A quota metric is a named counter to * measure usage, such as API requests or CPUs. When an activity occurs in a * service, such as Virtual Machine allocation, one or more quota metrics * may be affected. * For example, "compute.googleapis.com/cpus_per_vm_family", * "storage.googleapis.com/internet_egress_bandwidth". * @type string $quota_id * The id of the violated quota. Also know as "limit name", this is the * unique identifier of a quota in the context of an API service. * For example, "CPUS-PER-VM-FAMILY-per-project-region". * @type array|\Google\Protobuf\Internal\MapField $quota_dimensions * The dimensions of the violated quota. Every non-global quota is enforced * on a set of dimensions. While quota metric defines what to count, the * dimensions specify for what aspects the counter should be increased. * For example, the quota "CPUs per region per VM family" enforces a limit * on the metric "compute.googleapis.com/cpus_per_vm_family" on dimensions * "region" and "vm_family". And if the violation occurred in region * "us-central1" and for VM family "n1", the quota_dimensions would be, * { * "region": "us-central1", * "vm_family": "n1", * } * When a quota is enforced globally, the quota_dimensions would always be * empty. * @type int|string $quota_value * The enforced quota value at the time of the `QuotaFailure`. * For example, if the enforced quota value at the time of the * `QuotaFailure` on the number of CPUs is "10", then the value of this * field would reflect this quantity. * @type int|string $future_quota_value * The new quota value being rolled out at the time of the violation. At the * completion of the rollout, this value will be enforced in place of * quota_value. If no rollout is in progress at the time of the violation, * this field is not set. * For example, if at the time of the violation a rollout is in progress * changing the number of CPUs quota from 10 to 20, 20 would be the value of * this field. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Rpc\ErrorDetails::initOnce(); parent::__construct($data); } /** * The subject on which the quota check failed. * For example, "clientip:" or "project:". * * Generated from protobuf field string subject = 1; * @return string */ public function getSubject() { return $this->subject; } /** * The subject on which the quota check failed. * For example, "clientip:" or "project:". * * Generated from protobuf field string subject = 1; * @param string $var * @return $this */ public function setSubject($var) { GPBUtil::checkString($var, True); $this->subject = $var; return $this; } /** * A description of how the quota check failed. Clients can use this * description to find more about the quota configuration in the service's * public documentation, or find the relevant quota limit to adjust through * developer console. * For example: "Service disabled" or "Daily Limit for read operations * exceeded". * * Generated from protobuf field string description = 2; * @return string */ public function getDescription() { return $this->description; } /** * A description of how the quota check failed. Clients can use this * description to find more about the quota configuration in the service's * public documentation, or find the relevant quota limit to adjust through * developer console. * For example: "Service disabled" or "Daily Limit for read operations * exceeded". * * Generated from protobuf field string description = 2; * @param string $var * @return $this */ public function setDescription($var) { GPBUtil::checkString($var, True); $this->description = $var; return $this; } /** * The API Service from which the `QuotaFailure.Violation` orginates. In * some cases, Quota issues originate from an API Service other than the one * that was called. In other words, a dependency of the called API Service * could be the cause of the `QuotaFailure`, and this field would have the * dependency API service name. * For example, if the called API is Kubernetes Engine API * (container.googleapis.com), and a quota violation occurs in the * Kubernetes Engine API itself, this field would be * "container.googleapis.com". On the other hand, if the quota violation * occurs when the Kubernetes Engine API creates VMs in the Compute Engine * API (compute.googleapis.com), this field would be * "compute.googleapis.com". * * Generated from protobuf field string api_service = 3; * @return string */ public function getApiService() { return $this->api_service; } /** * The API Service from which the `QuotaFailure.Violation` orginates. In * some cases, Quota issues originate from an API Service other than the one * that was called. In other words, a dependency of the called API Service * could be the cause of the `QuotaFailure`, and this field would have the * dependency API service name. * For example, if the called API is Kubernetes Engine API * (container.googleapis.com), and a quota violation occurs in the * Kubernetes Engine API itself, this field would be * "container.googleapis.com". On the other hand, if the quota violation * occurs when the Kubernetes Engine API creates VMs in the Compute Engine * API (compute.googleapis.com), this field would be * "compute.googleapis.com". * * Generated from protobuf field string api_service = 3; * @param string $var * @return $this */ public function setApiService($var) { GPBUtil::checkString($var, True); $this->api_service = $var; return $this; } /** * The metric of the violated quota. A quota metric is a named counter to * measure usage, such as API requests or CPUs. When an activity occurs in a * service, such as Virtual Machine allocation, one or more quota metrics * may be affected. * For example, "compute.googleapis.com/cpus_per_vm_family", * "storage.googleapis.com/internet_egress_bandwidth". * * Generated from protobuf field string quota_metric = 4; * @return string */ public function getQuotaMetric() { return $this->quota_metric; } /** * The metric of the violated quota. A quota metric is a named counter to * measure usage, such as API requests or CPUs. When an activity occurs in a * service, such as Virtual Machine allocation, one or more quota metrics * may be affected. * For example, "compute.googleapis.com/cpus_per_vm_family", * "storage.googleapis.com/internet_egress_bandwidth". * * Generated from protobuf field string quota_metric = 4; * @param string $var * @return $this */ public function setQuotaMetric($var) { GPBUtil::checkString($var, True); $this->quota_metric = $var; return $this; } /** * The id of the violated quota. Also know as "limit name", this is the * unique identifier of a quota in the context of an API service. * For example, "CPUS-PER-VM-FAMILY-per-project-region". * * Generated from protobuf field string quota_id = 5; * @return string */ public function getQuotaId() { return $this->quota_id; } /** * The id of the violated quota. Also know as "limit name", this is the * unique identifier of a quota in the context of an API service. * For example, "CPUS-PER-VM-FAMILY-per-project-region". * * Generated from protobuf field string quota_id = 5; * @param string $var * @return $this */ public function setQuotaId($var) { GPBUtil::checkString($var, True); $this->quota_id = $var; return $this; } /** * The dimensions of the violated quota. Every non-global quota is enforced * on a set of dimensions. While quota metric defines what to count, the * dimensions specify for what aspects the counter should be increased. * For example, the quota "CPUs per region per VM family" enforces a limit * on the metric "compute.googleapis.com/cpus_per_vm_family" on dimensions * "region" and "vm_family". And if the violation occurred in region * "us-central1" and for VM family "n1", the quota_dimensions would be, * { * "region": "us-central1", * "vm_family": "n1", * } * When a quota is enforced globally, the quota_dimensions would always be * empty. * * Generated from protobuf field map quota_dimensions = 6; * @return \Google\Protobuf\Internal\MapField */ public function getQuotaDimensions() { return $this->quota_dimensions; } /** * The dimensions of the violated quota. Every non-global quota is enforced * on a set of dimensions. While quota metric defines what to count, the * dimensions specify for what aspects the counter should be increased. * For example, the quota "CPUs per region per VM family" enforces a limit * on the metric "compute.googleapis.com/cpus_per_vm_family" on dimensions * "region" and "vm_family". And if the violation occurred in region * "us-central1" and for VM family "n1", the quota_dimensions would be, * { * "region": "us-central1", * "vm_family": "n1", * } * When a quota is enforced globally, the quota_dimensions would always be * empty. * * Generated from protobuf field map quota_dimensions = 6; * @param array|\Google\Protobuf\Internal\MapField $var * @return $this */ public function setQuotaDimensions($var) { $arr = GPBUtil::checkMapField($var, \Google\Protobuf\Internal\GPBType::STRING, \Google\Protobuf\Internal\GPBType::STRING); $this->quota_dimensions = $arr; return $this; } /** * The enforced quota value at the time of the `QuotaFailure`. * For example, if the enforced quota value at the time of the * `QuotaFailure` on the number of CPUs is "10", then the value of this * field would reflect this quantity. * * Generated from protobuf field int64 quota_value = 7; * @return int|string */ public function getQuotaValue() { return $this->quota_value; } /** * The enforced quota value at the time of the `QuotaFailure`. * For example, if the enforced quota value at the time of the * `QuotaFailure` on the number of CPUs is "10", then the value of this * field would reflect this quantity. * * Generated from protobuf field int64 quota_value = 7; * @param int|string $var * @return $this */ public function setQuotaValue($var) { GPBUtil::checkInt64($var); $this->quota_value = $var; return $this; } /** * The new quota value being rolled out at the time of the violation. At the * completion of the rollout, this value will be enforced in place of * quota_value. If no rollout is in progress at the time of the violation, * this field is not set. * For example, if at the time of the violation a rollout is in progress * changing the number of CPUs quota from 10 to 20, 20 would be the value of * this field. * * Generated from protobuf field optional int64 future_quota_value = 8; * @return int|string */ public function getFutureQuotaValue() { return isset($this->future_quota_value) ? $this->future_quota_value : 0; } public function hasFutureQuotaValue() { return isset($this->future_quota_value); } public function clearFutureQuotaValue() { unset($this->future_quota_value); } /** * The new quota value being rolled out at the time of the violation. At the * completion of the rollout, this value will be enforced in place of * quota_value. If no rollout is in progress at the time of the violation, * this field is not set. * For example, if at the time of the violation a rollout is in progress * changing the number of CPUs quota from 10 to 20, 20 would be the value of * this field. * * Generated from protobuf field optional int64 future_quota_value = 8; * @param int|string $var * @return $this */ public function setFutureQuotaValue($var) { GPBUtil::checkInt64($var); $this->future_quota_value = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Rpc/QuotaFailure.php ================================================ google.rpc.QuotaFailure */ class QuotaFailure extends \Google\Protobuf\Internal\Message { /** * Describes all quota violations. * * Generated from protobuf field repeated .google.rpc.QuotaFailure.Violation violations = 1; */ private $violations; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type array<\Google\Rpc\QuotaFailure\Violation>|\Google\Protobuf\Internal\RepeatedField $violations * Describes all quota violations. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Rpc\ErrorDetails::initOnce(); parent::__construct($data); } /** * Describes all quota violations. * * Generated from protobuf field repeated .google.rpc.QuotaFailure.Violation violations = 1; * @return \Google\Protobuf\Internal\RepeatedField */ public function getViolations() { return $this->violations; } /** * Describes all quota violations. * * Generated from protobuf field repeated .google.rpc.QuotaFailure.Violation violations = 1; * @param array<\Google\Rpc\QuotaFailure\Violation>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setViolations($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Rpc\QuotaFailure\Violation::class); $this->violations = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Rpc/RequestInfo.php ================================================ google.rpc.RequestInfo */ class RequestInfo extends \Google\Protobuf\Internal\Message { /** * An opaque string that should only be interpreted by the service generating * it. For example, it can be used to identify requests in the service's logs. * * Generated from protobuf field string request_id = 1; */ protected $request_id = ''; /** * Any data that was used to serve this request. For example, an encrypted * stack trace that can be sent back to the service provider for debugging. * * Generated from protobuf field string serving_data = 2; */ protected $serving_data = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $request_id * An opaque string that should only be interpreted by the service generating * it. For example, it can be used to identify requests in the service's logs. * @type string $serving_data * Any data that was used to serve this request. For example, an encrypted * stack trace that can be sent back to the service provider for debugging. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Rpc\ErrorDetails::initOnce(); parent::__construct($data); } /** * An opaque string that should only be interpreted by the service generating * it. For example, it can be used to identify requests in the service's logs. * * Generated from protobuf field string request_id = 1; * @return string */ public function getRequestId() { return $this->request_id; } /** * An opaque string that should only be interpreted by the service generating * it. For example, it can be used to identify requests in the service's logs. * * Generated from protobuf field string request_id = 1; * @param string $var * @return $this */ public function setRequestId($var) { GPBUtil::checkString($var, True); $this->request_id = $var; return $this; } /** * Any data that was used to serve this request. For example, an encrypted * stack trace that can be sent back to the service provider for debugging. * * Generated from protobuf field string serving_data = 2; * @return string */ public function getServingData() { return $this->serving_data; } /** * Any data that was used to serve this request. For example, an encrypted * stack trace that can be sent back to the service provider for debugging. * * Generated from protobuf field string serving_data = 2; * @param string $var * @return $this */ public function setServingData($var) { GPBUtil::checkString($var, True); $this->serving_data = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Rpc/ResourceInfo.php ================================================ google.rpc.ResourceInfo */ class ResourceInfo extends \Google\Protobuf\Internal\Message { /** * A name for the type of resource being accessed, e.g. "sql table", * "cloud storage bucket", "file", "Google calendar"; or the type URL * of the resource: e.g. "type.googleapis.com/google.pubsub.v1.Topic". * * Generated from protobuf field string resource_type = 1; */ protected $resource_type = ''; /** * The name of the resource being accessed. For example, a shared calendar * name: "example.com_4fghdhgsrgh@group.calendar.google.com", if the current * error is * [google.rpc.Code.PERMISSION_DENIED][google.rpc.Code.PERMISSION_DENIED]. * * Generated from protobuf field string resource_name = 2; */ protected $resource_name = ''; /** * The owner of the resource (optional). * For example, "user:" or "project:". * * Generated from protobuf field string owner = 3; */ protected $owner = ''; /** * Describes what error is encountered when accessing this resource. * For example, updating a cloud project may require the `writer` permission * on the developer console project. * * Generated from protobuf field string description = 4; */ protected $description = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $resource_type * A name for the type of resource being accessed, e.g. "sql table", * "cloud storage bucket", "file", "Google calendar"; or the type URL * of the resource: e.g. "type.googleapis.com/google.pubsub.v1.Topic". * @type string $resource_name * The name of the resource being accessed. For example, a shared calendar * name: "example.com_4fghdhgsrgh@group.calendar.google.com", if the current * error is * [google.rpc.Code.PERMISSION_DENIED][google.rpc.Code.PERMISSION_DENIED]. * @type string $owner * The owner of the resource (optional). * For example, "user:" or "project:". * @type string $description * Describes what error is encountered when accessing this resource. * For example, updating a cloud project may require the `writer` permission * on the developer console project. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Rpc\ErrorDetails::initOnce(); parent::__construct($data); } /** * A name for the type of resource being accessed, e.g. "sql table", * "cloud storage bucket", "file", "Google calendar"; or the type URL * of the resource: e.g. "type.googleapis.com/google.pubsub.v1.Topic". * * Generated from protobuf field string resource_type = 1; * @return string */ public function getResourceType() { return $this->resource_type; } /** * A name for the type of resource being accessed, e.g. "sql table", * "cloud storage bucket", "file", "Google calendar"; or the type URL * of the resource: e.g. "type.googleapis.com/google.pubsub.v1.Topic". * * Generated from protobuf field string resource_type = 1; * @param string $var * @return $this */ public function setResourceType($var) { GPBUtil::checkString($var, True); $this->resource_type = $var; return $this; } /** * The name of the resource being accessed. For example, a shared calendar * name: "example.com_4fghdhgsrgh@group.calendar.google.com", if the current * error is * [google.rpc.Code.PERMISSION_DENIED][google.rpc.Code.PERMISSION_DENIED]. * * Generated from protobuf field string resource_name = 2; * @return string */ public function getResourceName() { return $this->resource_name; } /** * The name of the resource being accessed. For example, a shared calendar * name: "example.com_4fghdhgsrgh@group.calendar.google.com", if the current * error is * [google.rpc.Code.PERMISSION_DENIED][google.rpc.Code.PERMISSION_DENIED]. * * Generated from protobuf field string resource_name = 2; * @param string $var * @return $this */ public function setResourceName($var) { GPBUtil::checkString($var, True); $this->resource_name = $var; return $this; } /** * The owner of the resource (optional). * For example, "user:" or "project:". * * Generated from protobuf field string owner = 3; * @return string */ public function getOwner() { return $this->owner; } /** * The owner of the resource (optional). * For example, "user:" or "project:". * * Generated from protobuf field string owner = 3; * @param string $var * @return $this */ public function setOwner($var) { GPBUtil::checkString($var, True); $this->owner = $var; return $this; } /** * Describes what error is encountered when accessing this resource. * For example, updating a cloud project may require the `writer` permission * on the developer console project. * * Generated from protobuf field string description = 4; * @return string */ public function getDescription() { return $this->description; } /** * Describes what error is encountered when accessing this resource. * For example, updating a cloud project may require the `writer` permission * on the developer console project. * * Generated from protobuf field string description = 4; * @param string $var * @return $this */ public function setDescription($var) { GPBUtil::checkString($var, True); $this->description = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Rpc/RetryInfo.php ================================================ google.rpc.RetryInfo */ class RetryInfo extends \Google\Protobuf\Internal\Message { /** * Clients should wait at least this long between retrying the same request. * * Generated from protobuf field .google.protobuf.Duration retry_delay = 1; */ protected $retry_delay = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type \Google\Protobuf\Duration $retry_delay * Clients should wait at least this long between retrying the same request. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Rpc\ErrorDetails::initOnce(); parent::__construct($data); } /** * Clients should wait at least this long between retrying the same request. * * Generated from protobuf field .google.protobuf.Duration retry_delay = 1; * @return \Google\Protobuf\Duration|null */ public function getRetryDelay() { return $this->retry_delay; } public function hasRetryDelay() { return isset($this->retry_delay); } public function clearRetryDelay() { unset($this->retry_delay); } /** * Clients should wait at least this long between retrying the same request. * * Generated from protobuf field .google.protobuf.Duration retry_delay = 1; * @param \Google\Protobuf\Duration $var * @return $this */ public function setRetryDelay($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Duration::class); $this->retry_delay = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Rpc/Status.php ================================================ google.rpc.Status */ class Status extends \Google\Protobuf\Internal\Message { /** * The status code, which should be an enum value of * [google.rpc.Code][google.rpc.Code]. * * Generated from protobuf field int32 code = 1; */ protected $code = 0; /** * A developer-facing error message, which should be in English. Any * user-facing error message should be localized and sent in the * [google.rpc.Status.details][google.rpc.Status.details] field, or localized * by the client. * * Generated from protobuf field string message = 2; */ protected $message = ''; /** * A list of messages that carry the error details. There is a common set of * message types for APIs to use. * * Generated from protobuf field repeated .google.protobuf.Any details = 3; */ private $details; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type int $code * The status code, which should be an enum value of * [google.rpc.Code][google.rpc.Code]. * @type string $message * A developer-facing error message, which should be in English. Any * user-facing error message should be localized and sent in the * [google.rpc.Status.details][google.rpc.Status.details] field, or localized * by the client. * @type array<\Google\Protobuf\Any>|\Google\Protobuf\Internal\RepeatedField $details * A list of messages that carry the error details. There is a common set of * message types for APIs to use. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Rpc\Status::initOnce(); parent::__construct($data); } /** * The status code, which should be an enum value of * [google.rpc.Code][google.rpc.Code]. * * Generated from protobuf field int32 code = 1; * @return int */ public function getCode() { return $this->code; } /** * The status code, which should be an enum value of * [google.rpc.Code][google.rpc.Code]. * * Generated from protobuf field int32 code = 1; * @param int $var * @return $this */ public function setCode($var) { GPBUtil::checkInt32($var); $this->code = $var; return $this; } /** * A developer-facing error message, which should be in English. Any * user-facing error message should be localized and sent in the * [google.rpc.Status.details][google.rpc.Status.details] field, or localized * by the client. * * Generated from protobuf field string message = 2; * @return string */ public function getMessage() { return $this->message; } /** * A developer-facing error message, which should be in English. Any * user-facing error message should be localized and sent in the * [google.rpc.Status.details][google.rpc.Status.details] field, or localized * by the client. * * Generated from protobuf field string message = 2; * @param string $var * @return $this */ public function setMessage($var) { GPBUtil::checkString($var, True); $this->message = $var; return $this; } /** * A list of messages that carry the error details. There is a common set of * message types for APIs to use. * * Generated from protobuf field repeated .google.protobuf.Any details = 3; * @return \Google\Protobuf\Internal\RepeatedField */ public function getDetails() { return $this->details; } /** * A list of messages that carry the error details. There is a common set of * message types for APIs to use. * * Generated from protobuf field repeated .google.protobuf.Any details = 3; * @param array<\Google\Protobuf\Any>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setDetails($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Any::class); $this->details = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Type/CalendarPeriod.php ================================================ google.type.CalendarPeriod */ class CalendarPeriod { /** * Undefined period, raises an error. * * Generated from protobuf enum CALENDAR_PERIOD_UNSPECIFIED = 0; */ const CALENDAR_PERIOD_UNSPECIFIED = 0; /** * A day. * * Generated from protobuf enum DAY = 1; */ const DAY = 1; /** * A week. Weeks begin on Monday, following * [ISO 8601](https://en.wikipedia.org/wiki/ISO_week_date). * * Generated from protobuf enum WEEK = 2; */ const WEEK = 2; /** * A fortnight. The first calendar fortnight of the year begins at the start * of week 1 according to * [ISO 8601](https://en.wikipedia.org/wiki/ISO_week_date). * * Generated from protobuf enum FORTNIGHT = 3; */ const FORTNIGHT = 3; /** * A month. * * Generated from protobuf enum MONTH = 4; */ const MONTH = 4; /** * A quarter. Quarters start on dates 1-Jan, 1-Apr, 1-Jul, and 1-Oct of each * year. * * Generated from protobuf enum QUARTER = 5; */ const QUARTER = 5; /** * A half-year. Half-years start on dates 1-Jan and 1-Jul. * * Generated from protobuf enum HALF = 6; */ const HALF = 6; /** * A year. * * Generated from protobuf enum YEAR = 7; */ const YEAR = 7; private static $valueToName = [ self::CALENDAR_PERIOD_UNSPECIFIED => 'CALENDAR_PERIOD_UNSPECIFIED', self::DAY => 'DAY', self::WEEK => 'WEEK', self::FORTNIGHT => 'FORTNIGHT', self::MONTH => 'MONTH', self::QUARTER => 'QUARTER', self::HALF => 'HALF', self::YEAR => 'YEAR', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Type/Color.php ================================================ google.type.Color */ class Color extends \Google\Protobuf\Internal\Message { /** * The amount of red in the color as a value in the interval [0, 1]. * * Generated from protobuf field float red = 1; */ protected $red = 0.0; /** * The amount of green in the color as a value in the interval [0, 1]. * * Generated from protobuf field float green = 2; */ protected $green = 0.0; /** * The amount of blue in the color as a value in the interval [0, 1]. * * Generated from protobuf field float blue = 3; */ protected $blue = 0.0; /** * The fraction of this color that should be applied to the pixel. That is, * the final pixel color is defined by the equation: * `pixel color = alpha * (this color) + (1.0 - alpha) * (background color)` * This means that a value of 1.0 corresponds to a solid color, whereas * a value of 0.0 corresponds to a completely transparent color. This * uses a wrapper message rather than a simple float scalar so that it is * possible to distinguish between a default value and the value being unset. * If omitted, this color object is rendered as a solid color * (as if the alpha value had been explicitly given a value of 1.0). * * Generated from protobuf field .google.protobuf.FloatValue alpha = 4; */ protected $alpha = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type float $red * The amount of red in the color as a value in the interval [0, 1]. * @type float $green * The amount of green in the color as a value in the interval [0, 1]. * @type float $blue * The amount of blue in the color as a value in the interval [0, 1]. * @type \Google\Protobuf\FloatValue $alpha * The fraction of this color that should be applied to the pixel. That is, * the final pixel color is defined by the equation: * `pixel color = alpha * (this color) + (1.0 - alpha) * (background color)` * This means that a value of 1.0 corresponds to a solid color, whereas * a value of 0.0 corresponds to a completely transparent color. This * uses a wrapper message rather than a simple float scalar so that it is * possible to distinguish between a default value and the value being unset. * If omitted, this color object is rendered as a solid color * (as if the alpha value had been explicitly given a value of 1.0). * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Type\Color::initOnce(); parent::__construct($data); } /** * The amount of red in the color as a value in the interval [0, 1]. * * Generated from protobuf field float red = 1; * @return float */ public function getRed() { return $this->red; } /** * The amount of red in the color as a value in the interval [0, 1]. * * Generated from protobuf field float red = 1; * @param float $var * @return $this */ public function setRed($var) { GPBUtil::checkFloat($var); $this->red = $var; return $this; } /** * The amount of green in the color as a value in the interval [0, 1]. * * Generated from protobuf field float green = 2; * @return float */ public function getGreen() { return $this->green; } /** * The amount of green in the color as a value in the interval [0, 1]. * * Generated from protobuf field float green = 2; * @param float $var * @return $this */ public function setGreen($var) { GPBUtil::checkFloat($var); $this->green = $var; return $this; } /** * The amount of blue in the color as a value in the interval [0, 1]. * * Generated from protobuf field float blue = 3; * @return float */ public function getBlue() { return $this->blue; } /** * The amount of blue in the color as a value in the interval [0, 1]. * * Generated from protobuf field float blue = 3; * @param float $var * @return $this */ public function setBlue($var) { GPBUtil::checkFloat($var); $this->blue = $var; return $this; } /** * The fraction of this color that should be applied to the pixel. That is, * the final pixel color is defined by the equation: * `pixel color = alpha * (this color) + (1.0 - alpha) * (background color)` * This means that a value of 1.0 corresponds to a solid color, whereas * a value of 0.0 corresponds to a completely transparent color. This * uses a wrapper message rather than a simple float scalar so that it is * possible to distinguish between a default value and the value being unset. * If omitted, this color object is rendered as a solid color * (as if the alpha value had been explicitly given a value of 1.0). * * Generated from protobuf field .google.protobuf.FloatValue alpha = 4; * @return \Google\Protobuf\FloatValue|null */ public function getAlpha() { return $this->alpha; } public function hasAlpha() { return isset($this->alpha); } public function clearAlpha() { unset($this->alpha); } /** * Returns the unboxed value from getAlpha() * The fraction of this color that should be applied to the pixel. That is, * the final pixel color is defined by the equation: * `pixel color = alpha * (this color) + (1.0 - alpha) * (background color)` * This means that a value of 1.0 corresponds to a solid color, whereas * a value of 0.0 corresponds to a completely transparent color. This * uses a wrapper message rather than a simple float scalar so that it is * possible to distinguish between a default value and the value being unset. * If omitted, this color object is rendered as a solid color * (as if the alpha value had been explicitly given a value of 1.0). * * Generated from protobuf field .google.protobuf.FloatValue alpha = 4; * @return float|null */ public function getAlphaUnwrapped() { return $this->readWrapperValue("alpha"); } /** * The fraction of this color that should be applied to the pixel. That is, * the final pixel color is defined by the equation: * `pixel color = alpha * (this color) + (1.0 - alpha) * (background color)` * This means that a value of 1.0 corresponds to a solid color, whereas * a value of 0.0 corresponds to a completely transparent color. This * uses a wrapper message rather than a simple float scalar so that it is * possible to distinguish between a default value and the value being unset. * If omitted, this color object is rendered as a solid color * (as if the alpha value had been explicitly given a value of 1.0). * * Generated from protobuf field .google.protobuf.FloatValue alpha = 4; * @param \Google\Protobuf\FloatValue $var * @return $this */ public function setAlpha($var) { GPBUtil::checkMessage($var, \Google\Protobuf\FloatValue::class); $this->alpha = $var; return $this; } /** * Sets the field by wrapping a primitive type in a Google\Protobuf\FloatValue object. * The fraction of this color that should be applied to the pixel. That is, * the final pixel color is defined by the equation: * `pixel color = alpha * (this color) + (1.0 - alpha) * (background color)` * This means that a value of 1.0 corresponds to a solid color, whereas * a value of 0.0 corresponds to a completely transparent color. This * uses a wrapper message rather than a simple float scalar so that it is * possible to distinguish between a default value and the value being unset. * If omitted, this color object is rendered as a solid color * (as if the alpha value had been explicitly given a value of 1.0). * * Generated from protobuf field .google.protobuf.FloatValue alpha = 4; * @param float|null $var * @return $this */ public function setAlphaUnwrapped($var) { $this->writeWrapperValue("alpha", $var); return $this;} } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Type/Date.php ================================================ google.type.Date */ class Date extends \Google\Protobuf\Internal\Message { /** * Year of the date. Must be from 1 to 9999, or 0 to specify a date without * a year. * * Generated from protobuf field int32 year = 1; */ protected $year = 0; /** * Month of a year. Must be from 1 to 12, or 0 to specify a year without a * month and day. * * Generated from protobuf field int32 month = 2; */ protected $month = 0; /** * Day of a month. Must be from 1 to 31 and valid for the year and month, or 0 * to specify a year by itself or a year and month where the day isn't * significant. * * Generated from protobuf field int32 day = 3; */ protected $day = 0; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type int $year * Year of the date. Must be from 1 to 9999, or 0 to specify a date without * a year. * @type int $month * Month of a year. Must be from 1 to 12, or 0 to specify a year without a * month and day. * @type int $day * Day of a month. Must be from 1 to 31 and valid for the year and month, or 0 * to specify a year by itself or a year and month where the day isn't * significant. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Type\Date::initOnce(); parent::__construct($data); } /** * Year of the date. Must be from 1 to 9999, or 0 to specify a date without * a year. * * Generated from protobuf field int32 year = 1; * @return int */ public function getYear() { return $this->year; } /** * Year of the date. Must be from 1 to 9999, or 0 to specify a date without * a year. * * Generated from protobuf field int32 year = 1; * @param int $var * @return $this */ public function setYear($var) { GPBUtil::checkInt32($var); $this->year = $var; return $this; } /** * Month of a year. Must be from 1 to 12, or 0 to specify a year without a * month and day. * * Generated from protobuf field int32 month = 2; * @return int */ public function getMonth() { return $this->month; } /** * Month of a year. Must be from 1 to 12, or 0 to specify a year without a * month and day. * * Generated from protobuf field int32 month = 2; * @param int $var * @return $this */ public function setMonth($var) { GPBUtil::checkInt32($var); $this->month = $var; return $this; } /** * Day of a month. Must be from 1 to 31 and valid for the year and month, or 0 * to specify a year by itself or a year and month where the day isn't * significant. * * Generated from protobuf field int32 day = 3; * @return int */ public function getDay() { return $this->day; } /** * Day of a month. Must be from 1 to 31 and valid for the year and month, or 0 * to specify a year by itself or a year and month where the day isn't * significant. * * Generated from protobuf field int32 day = 3; * @param int $var * @return $this */ public function setDay($var) { GPBUtil::checkInt32($var); $this->day = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Type/DateTime.php ================================================ google.type.DateTime */ class DateTime extends \Google\Protobuf\Internal\Message { /** * Optional. Year of date. Must be from 1 to 9999, or 0 if specifying a * datetime without a year. * * Generated from protobuf field int32 year = 1; */ protected $year = 0; /** * Required. Month of year. Must be from 1 to 12. * * Generated from protobuf field int32 month = 2; */ protected $month = 0; /** * Required. Day of month. Must be from 1 to 31 and valid for the year and * month. * * Generated from protobuf field int32 day = 3; */ protected $day = 0; /** * Required. Hours of day in 24 hour format. Should be from 0 to 23. An API * may choose to allow the value "24:00:00" for scenarios like business * closing time. * * Generated from protobuf field int32 hours = 4; */ protected $hours = 0; /** * Required. Minutes of hour of day. Must be from 0 to 59. * * Generated from protobuf field int32 minutes = 5; */ protected $minutes = 0; /** * Required. Seconds of minutes of the time. Must normally be from 0 to 59. An * API may allow the value 60 if it allows leap-seconds. * * Generated from protobuf field int32 seconds = 6; */ protected $seconds = 0; /** * Required. Fractions of seconds in nanoseconds. Must be from 0 to * 999,999,999. * * Generated from protobuf field int32 nanos = 7; */ protected $nanos = 0; protected $time_offset; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type int $year * Optional. Year of date. Must be from 1 to 9999, or 0 if specifying a * datetime without a year. * @type int $month * Required. Month of year. Must be from 1 to 12. * @type int $day * Required. Day of month. Must be from 1 to 31 and valid for the year and * month. * @type int $hours * Required. Hours of day in 24 hour format. Should be from 0 to 23. An API * may choose to allow the value "24:00:00" for scenarios like business * closing time. * @type int $minutes * Required. Minutes of hour of day. Must be from 0 to 59. * @type int $seconds * Required. Seconds of minutes of the time. Must normally be from 0 to 59. An * API may allow the value 60 if it allows leap-seconds. * @type int $nanos * Required. Fractions of seconds in nanoseconds. Must be from 0 to * 999,999,999. * @type \Google\Protobuf\Duration $utc_offset * UTC offset. Must be whole seconds, between -18 hours and +18 hours. * For example, a UTC offset of -4:00 would be represented as * { seconds: -14400 }. * @type \Google\Type\TimeZone $time_zone * Time zone. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Type\Datetime::initOnce(); parent::__construct($data); } /** * Optional. Year of date. Must be from 1 to 9999, or 0 if specifying a * datetime without a year. * * Generated from protobuf field int32 year = 1; * @return int */ public function getYear() { return $this->year; } /** * Optional. Year of date. Must be from 1 to 9999, or 0 if specifying a * datetime without a year. * * Generated from protobuf field int32 year = 1; * @param int $var * @return $this */ public function setYear($var) { GPBUtil::checkInt32($var); $this->year = $var; return $this; } /** * Required. Month of year. Must be from 1 to 12. * * Generated from protobuf field int32 month = 2; * @return int */ public function getMonth() { return $this->month; } /** * Required. Month of year. Must be from 1 to 12. * * Generated from protobuf field int32 month = 2; * @param int $var * @return $this */ public function setMonth($var) { GPBUtil::checkInt32($var); $this->month = $var; return $this; } /** * Required. Day of month. Must be from 1 to 31 and valid for the year and * month. * * Generated from protobuf field int32 day = 3; * @return int */ public function getDay() { return $this->day; } /** * Required. Day of month. Must be from 1 to 31 and valid for the year and * month. * * Generated from protobuf field int32 day = 3; * @param int $var * @return $this */ public function setDay($var) { GPBUtil::checkInt32($var); $this->day = $var; return $this; } /** * Required. Hours of day in 24 hour format. Should be from 0 to 23. An API * may choose to allow the value "24:00:00" for scenarios like business * closing time. * * Generated from protobuf field int32 hours = 4; * @return int */ public function getHours() { return $this->hours; } /** * Required. Hours of day in 24 hour format. Should be from 0 to 23. An API * may choose to allow the value "24:00:00" for scenarios like business * closing time. * * Generated from protobuf field int32 hours = 4; * @param int $var * @return $this */ public function setHours($var) { GPBUtil::checkInt32($var); $this->hours = $var; return $this; } /** * Required. Minutes of hour of day. Must be from 0 to 59. * * Generated from protobuf field int32 minutes = 5; * @return int */ public function getMinutes() { return $this->minutes; } /** * Required. Minutes of hour of day. Must be from 0 to 59. * * Generated from protobuf field int32 minutes = 5; * @param int $var * @return $this */ public function setMinutes($var) { GPBUtil::checkInt32($var); $this->minutes = $var; return $this; } /** * Required. Seconds of minutes of the time. Must normally be from 0 to 59. An * API may allow the value 60 if it allows leap-seconds. * * Generated from protobuf field int32 seconds = 6; * @return int */ public function getSeconds() { return $this->seconds; } /** * Required. Seconds of minutes of the time. Must normally be from 0 to 59. An * API may allow the value 60 if it allows leap-seconds. * * Generated from protobuf field int32 seconds = 6; * @param int $var * @return $this */ public function setSeconds($var) { GPBUtil::checkInt32($var); $this->seconds = $var; return $this; } /** * Required. Fractions of seconds in nanoseconds. Must be from 0 to * 999,999,999. * * Generated from protobuf field int32 nanos = 7; * @return int */ public function getNanos() { return $this->nanos; } /** * Required. Fractions of seconds in nanoseconds. Must be from 0 to * 999,999,999. * * Generated from protobuf field int32 nanos = 7; * @param int $var * @return $this */ public function setNanos($var) { GPBUtil::checkInt32($var); $this->nanos = $var; return $this; } /** * UTC offset. Must be whole seconds, between -18 hours and +18 hours. * For example, a UTC offset of -4:00 would be represented as * { seconds: -14400 }. * * Generated from protobuf field .google.protobuf.Duration utc_offset = 8; * @return \Google\Protobuf\Duration|null */ public function getUtcOffset() { return $this->readOneof(8); } public function hasUtcOffset() { return $this->hasOneof(8); } /** * UTC offset. Must be whole seconds, between -18 hours and +18 hours. * For example, a UTC offset of -4:00 would be represented as * { seconds: -14400 }. * * Generated from protobuf field .google.protobuf.Duration utc_offset = 8; * @param \Google\Protobuf\Duration $var * @return $this */ public function setUtcOffset($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Duration::class); $this->writeOneof(8, $var); return $this; } /** * Time zone. * * Generated from protobuf field .google.type.TimeZone time_zone = 9; * @return \Google\Type\TimeZone|null */ public function getTimeZone() { return $this->readOneof(9); } public function hasTimeZone() { return $this->hasOneof(9); } /** * Time zone. * * Generated from protobuf field .google.type.TimeZone time_zone = 9; * @param \Google\Type\TimeZone $var * @return $this */ public function setTimeZone($var) { GPBUtil::checkMessage($var, \Google\Type\TimeZone::class); $this->writeOneof(9, $var); return $this; } /** * @return string */ public function getTimeOffset() { return $this->whichOneof("time_offset"); } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Type/DayOfWeek.php ================================================ google.type.DayOfWeek */ class DayOfWeek { /** * The day of the week is unspecified. * * Generated from protobuf enum DAY_OF_WEEK_UNSPECIFIED = 0; */ const DAY_OF_WEEK_UNSPECIFIED = 0; /** * Monday * * Generated from protobuf enum MONDAY = 1; */ const MONDAY = 1; /** * Tuesday * * Generated from protobuf enum TUESDAY = 2; */ const TUESDAY = 2; /** * Wednesday * * Generated from protobuf enum WEDNESDAY = 3; */ const WEDNESDAY = 3; /** * Thursday * * Generated from protobuf enum THURSDAY = 4; */ const THURSDAY = 4; /** * Friday * * Generated from protobuf enum FRIDAY = 5; */ const FRIDAY = 5; /** * Saturday * * Generated from protobuf enum SATURDAY = 6; */ const SATURDAY = 6; /** * Sunday * * Generated from protobuf enum SUNDAY = 7; */ const SUNDAY = 7; private static $valueToName = [ self::DAY_OF_WEEK_UNSPECIFIED => 'DAY_OF_WEEK_UNSPECIFIED', self::MONDAY => 'MONDAY', self::TUESDAY => 'TUESDAY', self::WEDNESDAY => 'WEDNESDAY', self::THURSDAY => 'THURSDAY', self::FRIDAY => 'FRIDAY', self::SATURDAY => 'SATURDAY', self::SUNDAY => 'SUNDAY', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Type/Decimal.php ================================================ google.type.Decimal */ class Decimal extends \Google\Protobuf\Internal\Message { /** * The decimal value, as a string. * The string representation consists of an optional sign, `+` (`U+002B`) * or `-` (`U+002D`), followed by a sequence of zero or more decimal digits * ("the integer"), optionally followed by a fraction, optionally followed * by an exponent. * The fraction consists of a decimal point followed by zero or more decimal * digits. The string must contain at least one digit in either the integer * or the fraction. The number formed by the sign, the integer and the * fraction is referred to as the significand. * The exponent consists of the character `e` (`U+0065`) or `E` (`U+0045`) * followed by one or more decimal digits. * Services **should** normalize decimal values before storing them by: * - Removing an explicitly-provided `+` sign (`+2.5` -> `2.5`). * - Replacing a zero-length integer value with `0` (`.5` -> `0.5`). * - Coercing the exponent character to lower-case (`2.5E8` -> `2.5e8`). * - Removing an explicitly-provided zero exponent (`2.5e0` -> `2.5`). * Services **may** perform additional normalization based on its own needs * and the internal decimal implementation selected, such as shifting the * decimal point and exponent value together (example: `2.5e-1` <-> `0.25`). * Additionally, services **may** preserve trailing zeroes in the fraction * to indicate increased precision, but are not required to do so. * Note that only the `.` character is supported to divide the integer * and the fraction; `,` **should not** be supported regardless of locale. * Additionally, thousand separators **should not** be supported. If a * service does support them, values **must** be normalized. * The ENBF grammar is: * DecimalString = * [Sign] Significand [Exponent]; * Sign = '+' | '-'; * Significand = * Digits ['.'] [Digits] | [Digits] '.' Digits; * Exponent = ('e' | 'E') [Sign] Digits; * Digits = { '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' }; * Services **should** clearly document the range of supported values, the * maximum supported precision (total number of digits), and, if applicable, * the scale (number of digits after the decimal point), as well as how it * behaves when receiving out-of-bounds values. * Services **may** choose to accept values passed as input even when the * value has a higher precision or scale than the service supports, and * **should** round the value to fit the supported scale. Alternatively, the * service **may** error with `400 Bad Request` (`INVALID_ARGUMENT` in gRPC) * if precision would be lost. * Services **should** error with `400 Bad Request` (`INVALID_ARGUMENT` in * gRPC) if the service receives a value outside of the supported range. * * Generated from protobuf field string value = 1; */ protected $value = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $value * The decimal value, as a string. * The string representation consists of an optional sign, `+` (`U+002B`) * or `-` (`U+002D`), followed by a sequence of zero or more decimal digits * ("the integer"), optionally followed by a fraction, optionally followed * by an exponent. * The fraction consists of a decimal point followed by zero or more decimal * digits. The string must contain at least one digit in either the integer * or the fraction. The number formed by the sign, the integer and the * fraction is referred to as the significand. * The exponent consists of the character `e` (`U+0065`) or `E` (`U+0045`) * followed by one or more decimal digits. * Services **should** normalize decimal values before storing them by: * - Removing an explicitly-provided `+` sign (`+2.5` -> `2.5`). * - Replacing a zero-length integer value with `0` (`.5` -> `0.5`). * - Coercing the exponent character to lower-case (`2.5E8` -> `2.5e8`). * - Removing an explicitly-provided zero exponent (`2.5e0` -> `2.5`). * Services **may** perform additional normalization based on its own needs * and the internal decimal implementation selected, such as shifting the * decimal point and exponent value together (example: `2.5e-1` <-> `0.25`). * Additionally, services **may** preserve trailing zeroes in the fraction * to indicate increased precision, but are not required to do so. * Note that only the `.` character is supported to divide the integer * and the fraction; `,` **should not** be supported regardless of locale. * Additionally, thousand separators **should not** be supported. If a * service does support them, values **must** be normalized. * The ENBF grammar is: * DecimalString = * [Sign] Significand [Exponent]; * Sign = '+' | '-'; * Significand = * Digits ['.'] [Digits] | [Digits] '.' Digits; * Exponent = ('e' | 'E') [Sign] Digits; * Digits = { '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' }; * Services **should** clearly document the range of supported values, the * maximum supported precision (total number of digits), and, if applicable, * the scale (number of digits after the decimal point), as well as how it * behaves when receiving out-of-bounds values. * Services **may** choose to accept values passed as input even when the * value has a higher precision or scale than the service supports, and * **should** round the value to fit the supported scale. Alternatively, the * service **may** error with `400 Bad Request` (`INVALID_ARGUMENT` in gRPC) * if precision would be lost. * Services **should** error with `400 Bad Request` (`INVALID_ARGUMENT` in * gRPC) if the service receives a value outside of the supported range. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Type\Decimal::initOnce(); parent::__construct($data); } /** * The decimal value, as a string. * The string representation consists of an optional sign, `+` (`U+002B`) * or `-` (`U+002D`), followed by a sequence of zero or more decimal digits * ("the integer"), optionally followed by a fraction, optionally followed * by an exponent. * The fraction consists of a decimal point followed by zero or more decimal * digits. The string must contain at least one digit in either the integer * or the fraction. The number formed by the sign, the integer and the * fraction is referred to as the significand. * The exponent consists of the character `e` (`U+0065`) or `E` (`U+0045`) * followed by one or more decimal digits. * Services **should** normalize decimal values before storing them by: * - Removing an explicitly-provided `+` sign (`+2.5` -> `2.5`). * - Replacing a zero-length integer value with `0` (`.5` -> `0.5`). * - Coercing the exponent character to lower-case (`2.5E8` -> `2.5e8`). * - Removing an explicitly-provided zero exponent (`2.5e0` -> `2.5`). * Services **may** perform additional normalization based on its own needs * and the internal decimal implementation selected, such as shifting the * decimal point and exponent value together (example: `2.5e-1` <-> `0.25`). * Additionally, services **may** preserve trailing zeroes in the fraction * to indicate increased precision, but are not required to do so. * Note that only the `.` character is supported to divide the integer * and the fraction; `,` **should not** be supported regardless of locale. * Additionally, thousand separators **should not** be supported. If a * service does support them, values **must** be normalized. * The ENBF grammar is: * DecimalString = * [Sign] Significand [Exponent]; * Sign = '+' | '-'; * Significand = * Digits ['.'] [Digits] | [Digits] '.' Digits; * Exponent = ('e' | 'E') [Sign] Digits; * Digits = { '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' }; * Services **should** clearly document the range of supported values, the * maximum supported precision (total number of digits), and, if applicable, * the scale (number of digits after the decimal point), as well as how it * behaves when receiving out-of-bounds values. * Services **may** choose to accept values passed as input even when the * value has a higher precision or scale than the service supports, and * **should** round the value to fit the supported scale. Alternatively, the * service **may** error with `400 Bad Request` (`INVALID_ARGUMENT` in gRPC) * if precision would be lost. * Services **should** error with `400 Bad Request` (`INVALID_ARGUMENT` in * gRPC) if the service receives a value outside of the supported range. * * Generated from protobuf field string value = 1; * @return string */ public function getValue() { return $this->value; } /** * The decimal value, as a string. * The string representation consists of an optional sign, `+` (`U+002B`) * or `-` (`U+002D`), followed by a sequence of zero or more decimal digits * ("the integer"), optionally followed by a fraction, optionally followed * by an exponent. * The fraction consists of a decimal point followed by zero or more decimal * digits. The string must contain at least one digit in either the integer * or the fraction. The number formed by the sign, the integer and the * fraction is referred to as the significand. * The exponent consists of the character `e` (`U+0065`) or `E` (`U+0045`) * followed by one or more decimal digits. * Services **should** normalize decimal values before storing them by: * - Removing an explicitly-provided `+` sign (`+2.5` -> `2.5`). * - Replacing a zero-length integer value with `0` (`.5` -> `0.5`). * - Coercing the exponent character to lower-case (`2.5E8` -> `2.5e8`). * - Removing an explicitly-provided zero exponent (`2.5e0` -> `2.5`). * Services **may** perform additional normalization based on its own needs * and the internal decimal implementation selected, such as shifting the * decimal point and exponent value together (example: `2.5e-1` <-> `0.25`). * Additionally, services **may** preserve trailing zeroes in the fraction * to indicate increased precision, but are not required to do so. * Note that only the `.` character is supported to divide the integer * and the fraction; `,` **should not** be supported regardless of locale. * Additionally, thousand separators **should not** be supported. If a * service does support them, values **must** be normalized. * The ENBF grammar is: * DecimalString = * [Sign] Significand [Exponent]; * Sign = '+' | '-'; * Significand = * Digits ['.'] [Digits] | [Digits] '.' Digits; * Exponent = ('e' | 'E') [Sign] Digits; * Digits = { '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' }; * Services **should** clearly document the range of supported values, the * maximum supported precision (total number of digits), and, if applicable, * the scale (number of digits after the decimal point), as well as how it * behaves when receiving out-of-bounds values. * Services **may** choose to accept values passed as input even when the * value has a higher precision or scale than the service supports, and * **should** round the value to fit the supported scale. Alternatively, the * service **may** error with `400 Bad Request` (`INVALID_ARGUMENT` in gRPC) * if precision would be lost. * Services **should** error with `400 Bad Request` (`INVALID_ARGUMENT` in * gRPC) if the service receives a value outside of the supported range. * * Generated from protobuf field string value = 1; * @param string $var * @return $this */ public function setValue($var) { GPBUtil::checkString($var, True); $this->value = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Type/Expr.php ================================================ google.type.Expr */ class Expr extends \Google\Protobuf\Internal\Message { /** * Textual representation of an expression in Common Expression Language * syntax. * * Generated from protobuf field string expression = 1; */ protected $expression = ''; /** * Optional. Title for the expression, i.e. a short string describing * its purpose. This can be used e.g. in UIs which allow to enter the * expression. * * Generated from protobuf field string title = 2; */ protected $title = ''; /** * Optional. Description of the expression. This is a longer text which * describes the expression, e.g. when hovered over it in a UI. * * Generated from protobuf field string description = 3; */ protected $description = ''; /** * Optional. String indicating the location of the expression for error * reporting, e.g. a file name and a position in the file. * * Generated from protobuf field string location = 4; */ protected $location = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $expression * Textual representation of an expression in Common Expression Language * syntax. * @type string $title * Optional. Title for the expression, i.e. a short string describing * its purpose. This can be used e.g. in UIs which allow to enter the * expression. * @type string $description * Optional. Description of the expression. This is a longer text which * describes the expression, e.g. when hovered over it in a UI. * @type string $location * Optional. String indicating the location of the expression for error * reporting, e.g. a file name and a position in the file. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Type\Expr::initOnce(); parent::__construct($data); } /** * Textual representation of an expression in Common Expression Language * syntax. * * Generated from protobuf field string expression = 1; * @return string */ public function getExpression() { return $this->expression; } /** * Textual representation of an expression in Common Expression Language * syntax. * * Generated from protobuf field string expression = 1; * @param string $var * @return $this */ public function setExpression($var) { GPBUtil::checkString($var, True); $this->expression = $var; return $this; } /** * Optional. Title for the expression, i.e. a short string describing * its purpose. This can be used e.g. in UIs which allow to enter the * expression. * * Generated from protobuf field string title = 2; * @return string */ public function getTitle() { return $this->title; } /** * Optional. Title for the expression, i.e. a short string describing * its purpose. This can be used e.g. in UIs which allow to enter the * expression. * * Generated from protobuf field string title = 2; * @param string $var * @return $this */ public function setTitle($var) { GPBUtil::checkString($var, True); $this->title = $var; return $this; } /** * Optional. Description of the expression. This is a longer text which * describes the expression, e.g. when hovered over it in a UI. * * Generated from protobuf field string description = 3; * @return string */ public function getDescription() { return $this->description; } /** * Optional. Description of the expression. This is a longer text which * describes the expression, e.g. when hovered over it in a UI. * * Generated from protobuf field string description = 3; * @param string $var * @return $this */ public function setDescription($var) { GPBUtil::checkString($var, True); $this->description = $var; return $this; } /** * Optional. String indicating the location of the expression for error * reporting, e.g. a file name and a position in the file. * * Generated from protobuf field string location = 4; * @return string */ public function getLocation() { return $this->location; } /** * Optional. String indicating the location of the expression for error * reporting, e.g. a file name and a position in the file. * * Generated from protobuf field string location = 4; * @param string $var * @return $this */ public function setLocation($var) { GPBUtil::checkString($var, True); $this->location = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Type/Fraction.php ================================================ google.type.Fraction */ class Fraction extends \Google\Protobuf\Internal\Message { /** * The numerator in the fraction, e.g. 2 in 2/3. * * Generated from protobuf field int64 numerator = 1; */ protected $numerator = 0; /** * The value by which the numerator is divided, e.g. 3 in 2/3. Must be * positive. * * Generated from protobuf field int64 denominator = 2; */ protected $denominator = 0; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type int|string $numerator * The numerator in the fraction, e.g. 2 in 2/3. * @type int|string $denominator * The value by which the numerator is divided, e.g. 3 in 2/3. Must be * positive. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Type\Fraction::initOnce(); parent::__construct($data); } /** * The numerator in the fraction, e.g. 2 in 2/3. * * Generated from protobuf field int64 numerator = 1; * @return int|string */ public function getNumerator() { return $this->numerator; } /** * The numerator in the fraction, e.g. 2 in 2/3. * * Generated from protobuf field int64 numerator = 1; * @param int|string $var * @return $this */ public function setNumerator($var) { GPBUtil::checkInt64($var); $this->numerator = $var; return $this; } /** * The value by which the numerator is divided, e.g. 3 in 2/3. Must be * positive. * * Generated from protobuf field int64 denominator = 2; * @return int|string */ public function getDenominator() { return $this->denominator; } /** * The value by which the numerator is divided, e.g. 3 in 2/3. Must be * positive. * * Generated from protobuf field int64 denominator = 2; * @param int|string $var * @return $this */ public function setDenominator($var) { GPBUtil::checkInt64($var); $this->denominator = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Type/Interval.php ================================================ google.type.Interval */ class Interval extends \Google\Protobuf\Internal\Message { /** * Optional. Inclusive start of the interval. * If specified, a Timestamp matching this interval will have to be the same * or after the start. * * Generated from protobuf field .google.protobuf.Timestamp start_time = 1; */ protected $start_time = null; /** * Optional. Exclusive end of the interval. * If specified, a Timestamp matching this interval will have to be before the * end. * * Generated from protobuf field .google.protobuf.Timestamp end_time = 2; */ protected $end_time = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type \Google\Protobuf\Timestamp $start_time * Optional. Inclusive start of the interval. * If specified, a Timestamp matching this interval will have to be the same * or after the start. * @type \Google\Protobuf\Timestamp $end_time * Optional. Exclusive end of the interval. * If specified, a Timestamp matching this interval will have to be before the * end. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Type\Interval::initOnce(); parent::__construct($data); } /** * Optional. Inclusive start of the interval. * If specified, a Timestamp matching this interval will have to be the same * or after the start. * * Generated from protobuf field .google.protobuf.Timestamp start_time = 1; * @return \Google\Protobuf\Timestamp|null */ public function getStartTime() { return $this->start_time; } public function hasStartTime() { return isset($this->start_time); } public function clearStartTime() { unset($this->start_time); } /** * Optional. Inclusive start of the interval. * If specified, a Timestamp matching this interval will have to be the same * or after the start. * * Generated from protobuf field .google.protobuf.Timestamp start_time = 1; * @param \Google\Protobuf\Timestamp $var * @return $this */ public function setStartTime($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Timestamp::class); $this->start_time = $var; return $this; } /** * Optional. Exclusive end of the interval. * If specified, a Timestamp matching this interval will have to be before the * end. * * Generated from protobuf field .google.protobuf.Timestamp end_time = 2; * @return \Google\Protobuf\Timestamp|null */ public function getEndTime() { return $this->end_time; } public function hasEndTime() { return isset($this->end_time); } public function clearEndTime() { unset($this->end_time); } /** * Optional. Exclusive end of the interval. * If specified, a Timestamp matching this interval will have to be before the * end. * * Generated from protobuf field .google.protobuf.Timestamp end_time = 2; * @param \Google\Protobuf\Timestamp $var * @return $this */ public function setEndTime($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Timestamp::class); $this->end_time = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Type/LatLng.php ================================================ WGS84 * standard. Values must be within normalized ranges. * * Generated from protobuf message google.type.LatLng */ class LatLng extends \Google\Protobuf\Internal\Message { /** * The latitude in degrees. It must be in the range [-90.0, +90.0]. * * Generated from protobuf field double latitude = 1; */ protected $latitude = 0.0; /** * The longitude in degrees. It must be in the range [-180.0, +180.0]. * * Generated from protobuf field double longitude = 2; */ protected $longitude = 0.0; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type float $latitude * The latitude in degrees. It must be in the range [-90.0, +90.0]. * @type float $longitude * The longitude in degrees. It must be in the range [-180.0, +180.0]. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Type\Latlng::initOnce(); parent::__construct($data); } /** * The latitude in degrees. It must be in the range [-90.0, +90.0]. * * Generated from protobuf field double latitude = 1; * @return float */ public function getLatitude() { return $this->latitude; } /** * The latitude in degrees. It must be in the range [-90.0, +90.0]. * * Generated from protobuf field double latitude = 1; * @param float $var * @return $this */ public function setLatitude($var) { GPBUtil::checkDouble($var); $this->latitude = $var; return $this; } /** * The longitude in degrees. It must be in the range [-180.0, +180.0]. * * Generated from protobuf field double longitude = 2; * @return float */ public function getLongitude() { return $this->longitude; } /** * The longitude in degrees. It must be in the range [-180.0, +180.0]. * * Generated from protobuf field double longitude = 2; * @param float $var * @return $this */ public function setLongitude($var) { GPBUtil::checkDouble($var); $this->longitude = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Type/LocalizedText.php ================================================ google.type.LocalizedText */ class LocalizedText extends \Google\Protobuf\Internal\Message { /** * Localized string in the language corresponding to `language_code' below. * * Generated from protobuf field string text = 1; */ protected $text = ''; /** * The text's BCP-47 language code, such as "en-US" or "sr-Latn". * For more information, see * http://www.unicode.org/reports/tr35/#Unicode_locale_identifier. * * Generated from protobuf field string language_code = 2; */ protected $language_code = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $text * Localized string in the language corresponding to `language_code' below. * @type string $language_code * The text's BCP-47 language code, such as "en-US" or "sr-Latn". * For more information, see * http://www.unicode.org/reports/tr35/#Unicode_locale_identifier. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Type\LocalizedText::initOnce(); parent::__construct($data); } /** * Localized string in the language corresponding to `language_code' below. * * Generated from protobuf field string text = 1; * @return string */ public function getText() { return $this->text; } /** * Localized string in the language corresponding to `language_code' below. * * Generated from protobuf field string text = 1; * @param string $var * @return $this */ public function setText($var) { GPBUtil::checkString($var, True); $this->text = $var; return $this; } /** * The text's BCP-47 language code, such as "en-US" or "sr-Latn". * For more information, see * http://www.unicode.org/reports/tr35/#Unicode_locale_identifier. * * Generated from protobuf field string language_code = 2; * @return string */ public function getLanguageCode() { return $this->language_code; } /** * The text's BCP-47 language code, such as "en-US" or "sr-Latn". * For more information, see * http://www.unicode.org/reports/tr35/#Unicode_locale_identifier. * * Generated from protobuf field string language_code = 2; * @param string $var * @return $this */ public function setLanguageCode($var) { GPBUtil::checkString($var, True); $this->language_code = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Type/Money.php ================================================ google.type.Money */ class Money extends \Google\Protobuf\Internal\Message { /** * The three-letter currency code defined in ISO 4217. * * Generated from protobuf field string currency_code = 1; */ protected $currency_code = ''; /** * The whole units of the amount. * For example if `currencyCode` is `"USD"`, then 1 unit is one US dollar. * * Generated from protobuf field int64 units = 2; */ protected $units = 0; /** * Number of nano (10^-9) units of the amount. * The value must be between -999,999,999 and +999,999,999 inclusive. * If `units` is positive, `nanos` must be positive or zero. * If `units` is zero, `nanos` can be positive, zero, or negative. * If `units` is negative, `nanos` must be negative or zero. * For example $-1.75 is represented as `units`=-1 and `nanos`=-750,000,000. * * Generated from protobuf field int32 nanos = 3; */ protected $nanos = 0; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $currency_code * The three-letter currency code defined in ISO 4217. * @type int|string $units * The whole units of the amount. * For example if `currencyCode` is `"USD"`, then 1 unit is one US dollar. * @type int $nanos * Number of nano (10^-9) units of the amount. * The value must be between -999,999,999 and +999,999,999 inclusive. * If `units` is positive, `nanos` must be positive or zero. * If `units` is zero, `nanos` can be positive, zero, or negative. * If `units` is negative, `nanos` must be negative or zero. * For example $-1.75 is represented as `units`=-1 and `nanos`=-750,000,000. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Type\Money::initOnce(); parent::__construct($data); } /** * The three-letter currency code defined in ISO 4217. * * Generated from protobuf field string currency_code = 1; * @return string */ public function getCurrencyCode() { return $this->currency_code; } /** * The three-letter currency code defined in ISO 4217. * * Generated from protobuf field string currency_code = 1; * @param string $var * @return $this */ public function setCurrencyCode($var) { GPBUtil::checkString($var, True); $this->currency_code = $var; return $this; } /** * The whole units of the amount. * For example if `currencyCode` is `"USD"`, then 1 unit is one US dollar. * * Generated from protobuf field int64 units = 2; * @return int|string */ public function getUnits() { return $this->units; } /** * The whole units of the amount. * For example if `currencyCode` is `"USD"`, then 1 unit is one US dollar. * * Generated from protobuf field int64 units = 2; * @param int|string $var * @return $this */ public function setUnits($var) { GPBUtil::checkInt64($var); $this->units = $var; return $this; } /** * Number of nano (10^-9) units of the amount. * The value must be between -999,999,999 and +999,999,999 inclusive. * If `units` is positive, `nanos` must be positive or zero. * If `units` is zero, `nanos` can be positive, zero, or negative. * If `units` is negative, `nanos` must be negative or zero. * For example $-1.75 is represented as `units`=-1 and `nanos`=-750,000,000. * * Generated from protobuf field int32 nanos = 3; * @return int */ public function getNanos() { return $this->nanos; } /** * Number of nano (10^-9) units of the amount. * The value must be between -999,999,999 and +999,999,999 inclusive. * If `units` is positive, `nanos` must be positive or zero. * If `units` is zero, `nanos` can be positive, zero, or negative. * If `units` is negative, `nanos` must be negative or zero. * For example $-1.75 is represented as `units`=-1 and `nanos`=-750,000,000. * * Generated from protobuf field int32 nanos = 3; * @param int $var * @return $this */ public function setNanos($var) { GPBUtil::checkInt32($var); $this->nanos = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Type/Month.php ================================================ google.type.Month */ class Month { /** * The unspecified month. * * Generated from protobuf enum MONTH_UNSPECIFIED = 0; */ const MONTH_UNSPECIFIED = 0; /** * The month of January. * * Generated from protobuf enum JANUARY = 1; */ const JANUARY = 1; /** * The month of February. * * Generated from protobuf enum FEBRUARY = 2; */ const FEBRUARY = 2; /** * The month of March. * * Generated from protobuf enum MARCH = 3; */ const MARCH = 3; /** * The month of April. * * Generated from protobuf enum APRIL = 4; */ const APRIL = 4; /** * The month of May. * * Generated from protobuf enum MAY = 5; */ const MAY = 5; /** * The month of June. * * Generated from protobuf enum JUNE = 6; */ const JUNE = 6; /** * The month of July. * * Generated from protobuf enum JULY = 7; */ const JULY = 7; /** * The month of August. * * Generated from protobuf enum AUGUST = 8; */ const AUGUST = 8; /** * The month of September. * * Generated from protobuf enum SEPTEMBER = 9; */ const SEPTEMBER = 9; /** * The month of October. * * Generated from protobuf enum OCTOBER = 10; */ const OCTOBER = 10; /** * The month of November. * * Generated from protobuf enum NOVEMBER = 11; */ const NOVEMBER = 11; /** * The month of December. * * Generated from protobuf enum DECEMBER = 12; */ const DECEMBER = 12; private static $valueToName = [ self::MONTH_UNSPECIFIED => 'MONTH_UNSPECIFIED', self::JANUARY => 'JANUARY', self::FEBRUARY => 'FEBRUARY', self::MARCH => 'MARCH', self::APRIL => 'APRIL', self::MAY => 'MAY', self::JUNE => 'JUNE', self::JULY => 'JULY', self::AUGUST => 'AUGUST', self::SEPTEMBER => 'SEPTEMBER', self::OCTOBER => 'OCTOBER', self::NOVEMBER => 'NOVEMBER', self::DECEMBER => 'DECEMBER', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Type/PhoneNumber/ShortCode.php ================================================ google.type.PhoneNumber.ShortCode */ class ShortCode extends \Google\Protobuf\Internal\Message { /** * Required. The BCP-47 region code of the location where calls to this * short code can be made, such as "US" and "BB". * Reference(s): * - http://www.unicode.org/reports/tr35/#unicode_region_subtag * * Generated from protobuf field string region_code = 1; */ protected $region_code = ''; /** * Required. The short code digits, without a leading plus ('+') or country * calling code, e.g. "611". * * Generated from protobuf field string number = 2; */ protected $number = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $region_code * Required. The BCP-47 region code of the location where calls to this * short code can be made, such as "US" and "BB". * Reference(s): * - http://www.unicode.org/reports/tr35/#unicode_region_subtag * @type string $number * Required. The short code digits, without a leading plus ('+') or country * calling code, e.g. "611". * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Type\PhoneNumber::initOnce(); parent::__construct($data); } /** * Required. The BCP-47 region code of the location where calls to this * short code can be made, such as "US" and "BB". * Reference(s): * - http://www.unicode.org/reports/tr35/#unicode_region_subtag * * Generated from protobuf field string region_code = 1; * @return string */ public function getRegionCode() { return $this->region_code; } /** * Required. The BCP-47 region code of the location where calls to this * short code can be made, such as "US" and "BB". * Reference(s): * - http://www.unicode.org/reports/tr35/#unicode_region_subtag * * Generated from protobuf field string region_code = 1; * @param string $var * @return $this */ public function setRegionCode($var) { GPBUtil::checkString($var, True); $this->region_code = $var; return $this; } /** * Required. The short code digits, without a leading plus ('+') or country * calling code, e.g. "611". * * Generated from protobuf field string number = 2; * @return string */ public function getNumber() { return $this->number; } /** * Required. The short code digits, without a leading plus ('+') or country * calling code, e.g. "611". * * Generated from protobuf field string number = 2; * @param string $var * @return $this */ public function setNumber($var) { GPBUtil::checkString($var, True); $this->number = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Type/PhoneNumber.php ================================================ google.type.PhoneNumber */ class PhoneNumber extends \Google\Protobuf\Internal\Message { /** * The phone number's extension. The extension is not standardized in ITU * recommendations, except for being defined as a series of numbers with a * maximum length of 40 digits. Other than digits, some other dialing * characters such as ',' (indicating a wait) or '#' may be stored here. * Note that no regions currently use extensions with short codes, so this * field is normally only set in conjunction with an E.164 number. It is held * separately from the E.164 number to allow for short code extensions in the * future. * * Generated from protobuf field string extension = 3; */ protected $extension = ''; protected $kind; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $e164_number * The phone number, represented as a leading plus sign ('+'), followed by a * phone number that uses a relaxed ITU E.164 format consisting of the * country calling code (1 to 3 digits) and the subscriber number, with no * additional spaces or formatting, e.g.: * - correct: "+15552220123" * - incorrect: "+1 (555) 222-01234 x123". * The ITU E.164 format limits the latter to 12 digits, but in practice not * all countries respect that, so we relax that restriction here. * National-only numbers are not allowed. * References: * - https://www.itu.int/rec/T-REC-E.164-201011-I * - https://en.wikipedia.org/wiki/E.164. * - https://en.wikipedia.org/wiki/List_of_country_calling_codes * @type \Google\Type\PhoneNumber\ShortCode $short_code * A short code. * Reference(s): * - https://en.wikipedia.org/wiki/Short_code * @type string $extension * The phone number's extension. The extension is not standardized in ITU * recommendations, except for being defined as a series of numbers with a * maximum length of 40 digits. Other than digits, some other dialing * characters such as ',' (indicating a wait) or '#' may be stored here. * Note that no regions currently use extensions with short codes, so this * field is normally only set in conjunction with an E.164 number. It is held * separately from the E.164 number to allow for short code extensions in the * future. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Type\PhoneNumber::initOnce(); parent::__construct($data); } /** * The phone number, represented as a leading plus sign ('+'), followed by a * phone number that uses a relaxed ITU E.164 format consisting of the * country calling code (1 to 3 digits) and the subscriber number, with no * additional spaces or formatting, e.g.: * - correct: "+15552220123" * - incorrect: "+1 (555) 222-01234 x123". * The ITU E.164 format limits the latter to 12 digits, but in practice not * all countries respect that, so we relax that restriction here. * National-only numbers are not allowed. * References: * - https://www.itu.int/rec/T-REC-E.164-201011-I * - https://en.wikipedia.org/wiki/E.164. * - https://en.wikipedia.org/wiki/List_of_country_calling_codes * * Generated from protobuf field string e164_number = 1; * @return string */ public function getE164Number() { return $this->readOneof(1); } public function hasE164Number() { return $this->hasOneof(1); } /** * The phone number, represented as a leading plus sign ('+'), followed by a * phone number that uses a relaxed ITU E.164 format consisting of the * country calling code (1 to 3 digits) and the subscriber number, with no * additional spaces or formatting, e.g.: * - correct: "+15552220123" * - incorrect: "+1 (555) 222-01234 x123". * The ITU E.164 format limits the latter to 12 digits, but in practice not * all countries respect that, so we relax that restriction here. * National-only numbers are not allowed. * References: * - https://www.itu.int/rec/T-REC-E.164-201011-I * - https://en.wikipedia.org/wiki/E.164. * - https://en.wikipedia.org/wiki/List_of_country_calling_codes * * Generated from protobuf field string e164_number = 1; * @param string $var * @return $this */ public function setE164Number($var) { GPBUtil::checkString($var, True); $this->writeOneof(1, $var); return $this; } /** * A short code. * Reference(s): * - https://en.wikipedia.org/wiki/Short_code * * Generated from protobuf field .google.type.PhoneNumber.ShortCode short_code = 2; * @return \Google\Type\PhoneNumber\ShortCode|null */ public function getShortCode() { return $this->readOneof(2); } public function hasShortCode() { return $this->hasOneof(2); } /** * A short code. * Reference(s): * - https://en.wikipedia.org/wiki/Short_code * * Generated from protobuf field .google.type.PhoneNumber.ShortCode short_code = 2; * @param \Google\Type\PhoneNumber\ShortCode $var * @return $this */ public function setShortCode($var) { GPBUtil::checkMessage($var, \Google\Type\PhoneNumber\ShortCode::class); $this->writeOneof(2, $var); return $this; } /** * The phone number's extension. The extension is not standardized in ITU * recommendations, except for being defined as a series of numbers with a * maximum length of 40 digits. Other than digits, some other dialing * characters such as ',' (indicating a wait) or '#' may be stored here. * Note that no regions currently use extensions with short codes, so this * field is normally only set in conjunction with an E.164 number. It is held * separately from the E.164 number to allow for short code extensions in the * future. * * Generated from protobuf field string extension = 3; * @return string */ public function getExtension() { return $this->extension; } /** * The phone number's extension. The extension is not standardized in ITU * recommendations, except for being defined as a series of numbers with a * maximum length of 40 digits. Other than digits, some other dialing * characters such as ',' (indicating a wait) or '#' may be stored here. * Note that no regions currently use extensions with short codes, so this * field is normally only set in conjunction with an E.164 number. It is held * separately from the E.164 number to allow for short code extensions in the * future. * * Generated from protobuf field string extension = 3; * @param string $var * @return $this */ public function setExtension($var) { GPBUtil::checkString($var, True); $this->extension = $var; return $this; } /** * @return string */ public function getKind() { return $this->whichOneof("kind"); } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Type/PostalAddress.php ================================================ google.type.PostalAddress */ class PostalAddress extends \Google\Protobuf\Internal\Message { /** * The schema revision of the `PostalAddress`. This must be set to 0, which is * the latest revision. * All new revisions **must** be backward compatible with old revisions. * * Generated from protobuf field int32 revision = 1; */ protected $revision = 0; /** * Required. CLDR region code of the country/region of the address. This * is never inferred and it is up to the user to ensure the value is * correct. See http://cldr.unicode.org/ and * http://www.unicode.org/cldr/charts/30/supplemental/territory_information.html * for details. Example: "CH" for Switzerland. * * Generated from protobuf field string region_code = 2; */ protected $region_code = ''; /** * Optional. BCP-47 language code of the contents of this address (if * known). This is often the UI language of the input form or is expected * to match one of the languages used in the address' country/region, or their * transliterated equivalents. * This can affect formatting in certain countries, but is not critical * to the correctness of the data and will never affect any validation or * other non-formatting related operations. * If this value is not known, it should be omitted (rather than specifying a * possibly incorrect default). * Examples: "zh-Hant", "ja", "ja-Latn", "en". * * Generated from protobuf field string language_code = 3; */ protected $language_code = ''; /** * Optional. Postal code of the address. Not all countries use or require * postal codes to be present, but where they are used, they may trigger * additional validation with other parts of the address (e.g. state/zip * validation in the U.S.A.). * * Generated from protobuf field string postal_code = 4; */ protected $postal_code = ''; /** * Optional. Additional, country-specific, sorting code. This is not used * in most regions. Where it is used, the value is either a string like * "CEDEX", optionally followed by a number (e.g. "CEDEX 7"), or just a number * alone, representing the "sector code" (Jamaica), "delivery area indicator" * (Malawi) or "post office indicator" (e.g. Côte d'Ivoire). * * Generated from protobuf field string sorting_code = 5; */ protected $sorting_code = ''; /** * Optional. Highest administrative subdivision which is used for postal * addresses of a country or region. * For example, this can be a state, a province, an oblast, or a prefecture. * Specifically, for Spain this is the province and not the autonomous * community (e.g. "Barcelona" and not "Catalonia"). * Many countries don't use an administrative area in postal addresses. E.g. * in Switzerland this should be left unpopulated. * * Generated from protobuf field string administrative_area = 6; */ protected $administrative_area = ''; /** * Optional. Generally refers to the city/town portion of the address. * Examples: US city, IT comune, UK post town. * In regions of the world where localities are not well defined or do not fit * into this structure well, leave locality empty and use address_lines. * * Generated from protobuf field string locality = 7; */ protected $locality = ''; /** * Optional. Sublocality of the address. * For example, this can be neighborhoods, boroughs, districts. * * Generated from protobuf field string sublocality = 8; */ protected $sublocality = ''; /** * Unstructured address lines describing the lower levels of an address. * Because values in address_lines do not have type information and may * sometimes contain multiple values in a single field (e.g. * "Austin, TX"), it is important that the line order is clear. The order of * address lines should be "envelope order" for the country/region of the * address. In places where this can vary (e.g. Japan), address_language is * used to make it explicit (e.g. "ja" for large-to-small ordering and * "ja-Latn" or "en" for small-to-large). This way, the most specific line of * an address can be selected based on the language. * The minimum permitted structural representation of an address consists * of a region_code with all remaining information placed in the * address_lines. It would be possible to format such an address very * approximately without geocoding, but no semantic reasoning could be * made about any of the address components until it was at least * partially resolved. * Creating an address only containing a region_code and address_lines, and * then geocoding is the recommended way to handle completely unstructured * addresses (as opposed to guessing which parts of the address should be * localities or administrative areas). * * Generated from protobuf field repeated string address_lines = 9; */ private $address_lines; /** * Optional. The recipient at the address. * This field may, under certain circumstances, contain multiline information. * For example, it might contain "care of" information. * * Generated from protobuf field repeated string recipients = 10; */ private $recipients; /** * Optional. The name of the organization at the address. * * Generated from protobuf field string organization = 11; */ protected $organization = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type int $revision * The schema revision of the `PostalAddress`. This must be set to 0, which is * the latest revision. * All new revisions **must** be backward compatible with old revisions. * @type string $region_code * Required. CLDR region code of the country/region of the address. This * is never inferred and it is up to the user to ensure the value is * correct. See http://cldr.unicode.org/ and * http://www.unicode.org/cldr/charts/30/supplemental/territory_information.html * for details. Example: "CH" for Switzerland. * @type string $language_code * Optional. BCP-47 language code of the contents of this address (if * known). This is often the UI language of the input form or is expected * to match one of the languages used in the address' country/region, or their * transliterated equivalents. * This can affect formatting in certain countries, but is not critical * to the correctness of the data and will never affect any validation or * other non-formatting related operations. * If this value is not known, it should be omitted (rather than specifying a * possibly incorrect default). * Examples: "zh-Hant", "ja", "ja-Latn", "en". * @type string $postal_code * Optional. Postal code of the address. Not all countries use or require * postal codes to be present, but where they are used, they may trigger * additional validation with other parts of the address (e.g. state/zip * validation in the U.S.A.). * @type string $sorting_code * Optional. Additional, country-specific, sorting code. This is not used * in most regions. Where it is used, the value is either a string like * "CEDEX", optionally followed by a number (e.g. "CEDEX 7"), or just a number * alone, representing the "sector code" (Jamaica), "delivery area indicator" * (Malawi) or "post office indicator" (e.g. Côte d'Ivoire). * @type string $administrative_area * Optional. Highest administrative subdivision which is used for postal * addresses of a country or region. * For example, this can be a state, a province, an oblast, or a prefecture. * Specifically, for Spain this is the province and not the autonomous * community (e.g. "Barcelona" and not "Catalonia"). * Many countries don't use an administrative area in postal addresses. E.g. * in Switzerland this should be left unpopulated. * @type string $locality * Optional. Generally refers to the city/town portion of the address. * Examples: US city, IT comune, UK post town. * In regions of the world where localities are not well defined or do not fit * into this structure well, leave locality empty and use address_lines. * @type string $sublocality * Optional. Sublocality of the address. * For example, this can be neighborhoods, boroughs, districts. * @type array|\Google\Protobuf\Internal\RepeatedField $address_lines * Unstructured address lines describing the lower levels of an address. * Because values in address_lines do not have type information and may * sometimes contain multiple values in a single field (e.g. * "Austin, TX"), it is important that the line order is clear. The order of * address lines should be "envelope order" for the country/region of the * address. In places where this can vary (e.g. Japan), address_language is * used to make it explicit (e.g. "ja" for large-to-small ordering and * "ja-Latn" or "en" for small-to-large). This way, the most specific line of * an address can be selected based on the language. * The minimum permitted structural representation of an address consists * of a region_code with all remaining information placed in the * address_lines. It would be possible to format such an address very * approximately without geocoding, but no semantic reasoning could be * made about any of the address components until it was at least * partially resolved. * Creating an address only containing a region_code and address_lines, and * then geocoding is the recommended way to handle completely unstructured * addresses (as opposed to guessing which parts of the address should be * localities or administrative areas). * @type array|\Google\Protobuf\Internal\RepeatedField $recipients * Optional. The recipient at the address. * This field may, under certain circumstances, contain multiline information. * For example, it might contain "care of" information. * @type string $organization * Optional. The name of the organization at the address. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Type\PostalAddress::initOnce(); parent::__construct($data); } /** * The schema revision of the `PostalAddress`. This must be set to 0, which is * the latest revision. * All new revisions **must** be backward compatible with old revisions. * * Generated from protobuf field int32 revision = 1; * @return int */ public function getRevision() { return $this->revision; } /** * The schema revision of the `PostalAddress`. This must be set to 0, which is * the latest revision. * All new revisions **must** be backward compatible with old revisions. * * Generated from protobuf field int32 revision = 1; * @param int $var * @return $this */ public function setRevision($var) { GPBUtil::checkInt32($var); $this->revision = $var; return $this; } /** * Required. CLDR region code of the country/region of the address. This * is never inferred and it is up to the user to ensure the value is * correct. See http://cldr.unicode.org/ and * http://www.unicode.org/cldr/charts/30/supplemental/territory_information.html * for details. Example: "CH" for Switzerland. * * Generated from protobuf field string region_code = 2; * @return string */ public function getRegionCode() { return $this->region_code; } /** * Required. CLDR region code of the country/region of the address. This * is never inferred and it is up to the user to ensure the value is * correct. See http://cldr.unicode.org/ and * http://www.unicode.org/cldr/charts/30/supplemental/territory_information.html * for details. Example: "CH" for Switzerland. * * Generated from protobuf field string region_code = 2; * @param string $var * @return $this */ public function setRegionCode($var) { GPBUtil::checkString($var, True); $this->region_code = $var; return $this; } /** * Optional. BCP-47 language code of the contents of this address (if * known). This is often the UI language of the input form or is expected * to match one of the languages used in the address' country/region, or their * transliterated equivalents. * This can affect formatting in certain countries, but is not critical * to the correctness of the data and will never affect any validation or * other non-formatting related operations. * If this value is not known, it should be omitted (rather than specifying a * possibly incorrect default). * Examples: "zh-Hant", "ja", "ja-Latn", "en". * * Generated from protobuf field string language_code = 3; * @return string */ public function getLanguageCode() { return $this->language_code; } /** * Optional. BCP-47 language code of the contents of this address (if * known). This is often the UI language of the input form or is expected * to match one of the languages used in the address' country/region, or their * transliterated equivalents. * This can affect formatting in certain countries, but is not critical * to the correctness of the data and will never affect any validation or * other non-formatting related operations. * If this value is not known, it should be omitted (rather than specifying a * possibly incorrect default). * Examples: "zh-Hant", "ja", "ja-Latn", "en". * * Generated from protobuf field string language_code = 3; * @param string $var * @return $this */ public function setLanguageCode($var) { GPBUtil::checkString($var, True); $this->language_code = $var; return $this; } /** * Optional. Postal code of the address. Not all countries use or require * postal codes to be present, but where they are used, they may trigger * additional validation with other parts of the address (e.g. state/zip * validation in the U.S.A.). * * Generated from protobuf field string postal_code = 4; * @return string */ public function getPostalCode() { return $this->postal_code; } /** * Optional. Postal code of the address. Not all countries use or require * postal codes to be present, but where they are used, they may trigger * additional validation with other parts of the address (e.g. state/zip * validation in the U.S.A.). * * Generated from protobuf field string postal_code = 4; * @param string $var * @return $this */ public function setPostalCode($var) { GPBUtil::checkString($var, True); $this->postal_code = $var; return $this; } /** * Optional. Additional, country-specific, sorting code. This is not used * in most regions. Where it is used, the value is either a string like * "CEDEX", optionally followed by a number (e.g. "CEDEX 7"), or just a number * alone, representing the "sector code" (Jamaica), "delivery area indicator" * (Malawi) or "post office indicator" (e.g. Côte d'Ivoire). * * Generated from protobuf field string sorting_code = 5; * @return string */ public function getSortingCode() { return $this->sorting_code; } /** * Optional. Additional, country-specific, sorting code. This is not used * in most regions. Where it is used, the value is either a string like * "CEDEX", optionally followed by a number (e.g. "CEDEX 7"), or just a number * alone, representing the "sector code" (Jamaica), "delivery area indicator" * (Malawi) or "post office indicator" (e.g. Côte d'Ivoire). * * Generated from protobuf field string sorting_code = 5; * @param string $var * @return $this */ public function setSortingCode($var) { GPBUtil::checkString($var, True); $this->sorting_code = $var; return $this; } /** * Optional. Highest administrative subdivision which is used for postal * addresses of a country or region. * For example, this can be a state, a province, an oblast, or a prefecture. * Specifically, for Spain this is the province and not the autonomous * community (e.g. "Barcelona" and not "Catalonia"). * Many countries don't use an administrative area in postal addresses. E.g. * in Switzerland this should be left unpopulated. * * Generated from protobuf field string administrative_area = 6; * @return string */ public function getAdministrativeArea() { return $this->administrative_area; } /** * Optional. Highest administrative subdivision which is used for postal * addresses of a country or region. * For example, this can be a state, a province, an oblast, or a prefecture. * Specifically, for Spain this is the province and not the autonomous * community (e.g. "Barcelona" and not "Catalonia"). * Many countries don't use an administrative area in postal addresses. E.g. * in Switzerland this should be left unpopulated. * * Generated from protobuf field string administrative_area = 6; * @param string $var * @return $this */ public function setAdministrativeArea($var) { GPBUtil::checkString($var, True); $this->administrative_area = $var; return $this; } /** * Optional. Generally refers to the city/town portion of the address. * Examples: US city, IT comune, UK post town. * In regions of the world where localities are not well defined or do not fit * into this structure well, leave locality empty and use address_lines. * * Generated from protobuf field string locality = 7; * @return string */ public function getLocality() { return $this->locality; } /** * Optional. Generally refers to the city/town portion of the address. * Examples: US city, IT comune, UK post town. * In regions of the world where localities are not well defined or do not fit * into this structure well, leave locality empty and use address_lines. * * Generated from protobuf field string locality = 7; * @param string $var * @return $this */ public function setLocality($var) { GPBUtil::checkString($var, True); $this->locality = $var; return $this; } /** * Optional. Sublocality of the address. * For example, this can be neighborhoods, boroughs, districts. * * Generated from protobuf field string sublocality = 8; * @return string */ public function getSublocality() { return $this->sublocality; } /** * Optional. Sublocality of the address. * For example, this can be neighborhoods, boroughs, districts. * * Generated from protobuf field string sublocality = 8; * @param string $var * @return $this */ public function setSublocality($var) { GPBUtil::checkString($var, True); $this->sublocality = $var; return $this; } /** * Unstructured address lines describing the lower levels of an address. * Because values in address_lines do not have type information and may * sometimes contain multiple values in a single field (e.g. * "Austin, TX"), it is important that the line order is clear. The order of * address lines should be "envelope order" for the country/region of the * address. In places where this can vary (e.g. Japan), address_language is * used to make it explicit (e.g. "ja" for large-to-small ordering and * "ja-Latn" or "en" for small-to-large). This way, the most specific line of * an address can be selected based on the language. * The minimum permitted structural representation of an address consists * of a region_code with all remaining information placed in the * address_lines. It would be possible to format such an address very * approximately without geocoding, but no semantic reasoning could be * made about any of the address components until it was at least * partially resolved. * Creating an address only containing a region_code and address_lines, and * then geocoding is the recommended way to handle completely unstructured * addresses (as opposed to guessing which parts of the address should be * localities or administrative areas). * * Generated from protobuf field repeated string address_lines = 9; * @return \Google\Protobuf\Internal\RepeatedField */ public function getAddressLines() { return $this->address_lines; } /** * Unstructured address lines describing the lower levels of an address. * Because values in address_lines do not have type information and may * sometimes contain multiple values in a single field (e.g. * "Austin, TX"), it is important that the line order is clear. The order of * address lines should be "envelope order" for the country/region of the * address. In places where this can vary (e.g. Japan), address_language is * used to make it explicit (e.g. "ja" for large-to-small ordering and * "ja-Latn" or "en" for small-to-large). This way, the most specific line of * an address can be selected based on the language. * The minimum permitted structural representation of an address consists * of a region_code with all remaining information placed in the * address_lines. It would be possible to format such an address very * approximately without geocoding, but no semantic reasoning could be * made about any of the address components until it was at least * partially resolved. * Creating an address only containing a region_code and address_lines, and * then geocoding is the recommended way to handle completely unstructured * addresses (as opposed to guessing which parts of the address should be * localities or administrative areas). * * Generated from protobuf field repeated string address_lines = 9; * @param array|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setAddressLines($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->address_lines = $arr; return $this; } /** * Optional. The recipient at the address. * This field may, under certain circumstances, contain multiline information. * For example, it might contain "care of" information. * * Generated from protobuf field repeated string recipients = 10; * @return \Google\Protobuf\Internal\RepeatedField */ public function getRecipients() { return $this->recipients; } /** * Optional. The recipient at the address. * This field may, under certain circumstances, contain multiline information. * For example, it might contain "care of" information. * * Generated from protobuf field repeated string recipients = 10; * @param array|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setRecipients($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->recipients = $arr; return $this; } /** * Optional. The name of the organization at the address. * * Generated from protobuf field string organization = 11; * @return string */ public function getOrganization() { return $this->organization; } /** * Optional. The name of the organization at the address. * * Generated from protobuf field string organization = 11; * @param string $var * @return $this */ public function setOrganization($var) { GPBUtil::checkString($var, True); $this->organization = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Type/Quaternion.php ================================================ google.type.Quaternion */ class Quaternion extends \Google\Protobuf\Internal\Message { /** * The x component. * * Generated from protobuf field double x = 1; */ protected $x = 0.0; /** * The y component. * * Generated from protobuf field double y = 2; */ protected $y = 0.0; /** * The z component. * * Generated from protobuf field double z = 3; */ protected $z = 0.0; /** * The scalar component. * * Generated from protobuf field double w = 4; */ protected $w = 0.0; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type float $x * The x component. * @type float $y * The y component. * @type float $z * The z component. * @type float $w * The scalar component. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Type\Quaternion::initOnce(); parent::__construct($data); } /** * The x component. * * Generated from protobuf field double x = 1; * @return float */ public function getX() { return $this->x; } /** * The x component. * * Generated from protobuf field double x = 1; * @param float $var * @return $this */ public function setX($var) { GPBUtil::checkDouble($var); $this->x = $var; return $this; } /** * The y component. * * Generated from protobuf field double y = 2; * @return float */ public function getY() { return $this->y; } /** * The y component. * * Generated from protobuf field double y = 2; * @param float $var * @return $this */ public function setY($var) { GPBUtil::checkDouble($var); $this->y = $var; return $this; } /** * The z component. * * Generated from protobuf field double z = 3; * @return float */ public function getZ() { return $this->z; } /** * The z component. * * Generated from protobuf field double z = 3; * @param float $var * @return $this */ public function setZ($var) { GPBUtil::checkDouble($var); $this->z = $var; return $this; } /** * The scalar component. * * Generated from protobuf field double w = 4; * @return float */ public function getW() { return $this->w; } /** * The scalar component. * * Generated from protobuf field double w = 4; * @param float $var * @return $this */ public function setW($var) { GPBUtil::checkDouble($var); $this->w = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Type/TimeOfDay.php ================================================ google.type.TimeOfDay */ class TimeOfDay extends \Google\Protobuf\Internal\Message { /** * Hours of day in 24 hour format. Should be from 0 to 23. An API may choose * to allow the value "24:00:00" for scenarios like business closing time. * * Generated from protobuf field int32 hours = 1; */ protected $hours = 0; /** * Minutes of hour of day. Must be from 0 to 59. * * Generated from protobuf field int32 minutes = 2; */ protected $minutes = 0; /** * Seconds of minutes of the time. Must normally be from 0 to 59. An API may * allow the value 60 if it allows leap-seconds. * * Generated from protobuf field int32 seconds = 3; */ protected $seconds = 0; /** * Fractions of seconds in nanoseconds. Must be from 0 to 999,999,999. * * Generated from protobuf field int32 nanos = 4; */ protected $nanos = 0; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type int $hours * Hours of day in 24 hour format. Should be from 0 to 23. An API may choose * to allow the value "24:00:00" for scenarios like business closing time. * @type int $minutes * Minutes of hour of day. Must be from 0 to 59. * @type int $seconds * Seconds of minutes of the time. Must normally be from 0 to 59. An API may * allow the value 60 if it allows leap-seconds. * @type int $nanos * Fractions of seconds in nanoseconds. Must be from 0 to 999,999,999. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Type\Timeofday::initOnce(); parent::__construct($data); } /** * Hours of day in 24 hour format. Should be from 0 to 23. An API may choose * to allow the value "24:00:00" for scenarios like business closing time. * * Generated from protobuf field int32 hours = 1; * @return int */ public function getHours() { return $this->hours; } /** * Hours of day in 24 hour format. Should be from 0 to 23. An API may choose * to allow the value "24:00:00" for scenarios like business closing time. * * Generated from protobuf field int32 hours = 1; * @param int $var * @return $this */ public function setHours($var) { GPBUtil::checkInt32($var); $this->hours = $var; return $this; } /** * Minutes of hour of day. Must be from 0 to 59. * * Generated from protobuf field int32 minutes = 2; * @return int */ public function getMinutes() { return $this->minutes; } /** * Minutes of hour of day. Must be from 0 to 59. * * Generated from protobuf field int32 minutes = 2; * @param int $var * @return $this */ public function setMinutes($var) { GPBUtil::checkInt32($var); $this->minutes = $var; return $this; } /** * Seconds of minutes of the time. Must normally be from 0 to 59. An API may * allow the value 60 if it allows leap-seconds. * * Generated from protobuf field int32 seconds = 3; * @return int */ public function getSeconds() { return $this->seconds; } /** * Seconds of minutes of the time. Must normally be from 0 to 59. An API may * allow the value 60 if it allows leap-seconds. * * Generated from protobuf field int32 seconds = 3; * @param int $var * @return $this */ public function setSeconds($var) { GPBUtil::checkInt32($var); $this->seconds = $var; return $this; } /** * Fractions of seconds in nanoseconds. Must be from 0 to 999,999,999. * * Generated from protobuf field int32 nanos = 4; * @return int */ public function getNanos() { return $this->nanos; } /** * Fractions of seconds in nanoseconds. Must be from 0 to 999,999,999. * * Generated from protobuf field int32 nanos = 4; * @param int $var * @return $this */ public function setNanos($var) { GPBUtil::checkInt32($var); $this->nanos = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/common-protos/src/Type/TimeZone.php ================================================ google.type.TimeZone */ class TimeZone extends \Google\Protobuf\Internal\Message { /** * IANA Time Zone Database time zone, e.g. "America/New_York". * * Generated from protobuf field string id = 1; */ protected $id = ''; /** * Optional. IANA Time Zone Database version number, e.g. "2019a". * * Generated from protobuf field string version = 2; */ protected $version = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $id * IANA Time Zone Database time zone, e.g. "America/New_York". * @type string $version * Optional. IANA Time Zone Database version number, e.g. "2019a". * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Type\Datetime::initOnce(); parent::__construct($data); } /** * IANA Time Zone Database time zone, e.g. "America/New_York". * * Generated from protobuf field string id = 1; * @return string */ public function getId() { return $this->id; } /** * IANA Time Zone Database time zone, e.g. "America/New_York". * * Generated from protobuf field string id = 1; * @param string $var * @return $this */ public function setId($var) { GPBUtil::checkString($var, True); $this->id = $var; return $this; } /** * Optional. IANA Time Zone Database version number, e.g. "2019a". * * Generated from protobuf field string version = 2; * @return string */ public function getVersion() { return $this->version; } /** * Optional. IANA Time Zone Database version number, e.g. "2019a". * * Generated from protobuf field string version = 2; * @param string $var * @return $this */ public function setVersion($var) { GPBUtil::checkString($var, True); $this->version = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/gax/.repo-metadata.json ================================================ { "language": "php", "distribution_name": "google/gax", "release_level": "stable", "client_documentation": "https://cloud.google.com/php/docs/reference/gax/latest", "library_type": "CORE" } ================================================ FILE: lib/Google/vendor/google/gax/CHANGELOG.md ================================================ # Changelog ## [1.40.0](https://github.com/googleapis/gax-php/compare/v1.39.0...v1.40.0) (2025-12-04) ### Features * Add TransportCallMiddleware ([#640](https://github.com/googleapis/gax-php/issues/640)) ([a0f9d37](https://github.com/googleapis/gax-php/commit/a0f9d3740d62f6a776ac701631aa734046ceeb77)) ## [1.39.0](https://github.com/googleapis/gax-php/compare/v1.38.2...v1.39.0) (2025-12-02) ### Features * Add GapicClientTrait::prependMiddleware ([#638](https://github.com/googleapis/gax-php/issues/638)) ([d46c06d](https://github.com/googleapis/gax-php/commit/d46c06d3bb551d9f7848bceebcfd78f80ec7890f)) ## [1.38.2](https://github.com/googleapis/gax-php/compare/v1.38.1...v1.38.2) (2025-11-14) ### Bug Fixes * Don't override ApiException::__toString ([#388](https://github.com/googleapis/gax-php/issues/388)) ([db7cd2e](https://github.com/googleapis/gax-php/commit/db7cd2e55219463aa0f7d0bcc989f35d008d174b)) ## [1.38.1](https://github.com/googleapis/gax-php/compare/v1.38.0...v1.38.1) (2025-11-06) ### Bug Fixes * Add return type to `offsetGet` ([#633](https://github.com/googleapis/gax-php/issues/633)) ([b77c12d](https://github.com/googleapis/gax-php/commit/b77c12dc959e8434fcd1f7f08cedaa84cdfb00a4)) ## [1.38.0](https://github.com/googleapis/gax-php/compare/v1.37.0...v1.38.0) (2025-09-17) ### Features * Add the rpcName to the BIDI stream opening request ([#630](https://github.com/googleapis/gax-php/issues/630)) ([9c61d8f](https://github.com/googleapis/gax-php/commit/9c61d8f2bd09731d5f22c22eb81895eaf4db2031)) * Make options classes fluid ([#618](https://github.com/googleapis/gax-php/issues/618)) ([427b46e](https://github.com/googleapis/gax-php/commit/427b46e91b3881fd0da361b5b351c6dda47e640a)) ### Bug Fixes * Update protobuf RepeatedField to new namespace ([#624](https://github.com/googleapis/gax-php/issues/624)) ([3558cc4](https://github.com/googleapis/gax-php/commit/3558cc49139861fa411c77b33f457467ec8daa97)) ## [1.37.0](https://github.com/googleapis/gax-php/compare/v1.36.1...v1.37.0) (2025-09-10) ### Features * Support client options in ClientOptionsTrait::buildClientOptions ([#621](https://github.com/googleapis/gax-php/issues/621)) ([68e2336](https://github.com/googleapis/gax-php/commit/68e23369657b1740fffe480f96d9d7b04e3e38c2)) ### Bug Fixes * Ensure compute request build parameters have the operation ID last ([#625](https://github.com/googleapis/gax-php/issues/625)) ([f90ab28](https://github.com/googleapis/gax-php/commit/f90ab28cea6bbbd00f2a652a6d77babb69b2ada8)) ## [1.36.1](https://github.com/googleapis/gax-php/compare/v1.36.0...v1.36.1) (2025-05-20) ### Bug Fixes * Protobuf 4.31 deprecations ([#616](https://github.com/googleapis/gax-php/issues/616)) ([b06048b](https://github.com/googleapis/gax-php/commit/b06048be5c29a2534ba1c908642c69798e145d99)) ## [1.36.0](https://github.com/googleapis/gax-php/compare/v1.35.1...v1.36.0) (2024-12-11) ### Features * Add logging to the supported transports ([#585](https://github.com/googleapis/gax-php/issues/585)) ([819a677](https://github.com/googleapis/gax-php/commit/819a677e0d89d75662b30a1dbdd45f6a610d9f0c)) ## [1.35.1](https://github.com/googleapis/gax-php/compare/v1.35.0...v1.35.1) (2024-12-04) ### Bug Fixes * Ensure hasEmulator client option is passed to createTransport ([#594](https://github.com/googleapis/gax-php/issues/594)) ([13bbe8a](https://github.com/googleapis/gax-php/commit/13bbe8a2e6df2bfd6c5febba735113f1abcba201)) * Remove implicit null, add php 8.4 ([#599](https://github.com/googleapis/gax-php/issues/599)) ([af0a0e7](https://github.com/googleapis/gax-php/commit/af0a0e708dfbea46de627965db0f63114fcfb67f)) ## [1.35.0](https://github.com/googleapis/gax-php/compare/v1.34.1...v1.35.0) (2024-11-06) ### Features * Add `InsecureRequestBuilder` for emulator ([#582](https://github.com/googleapis/gax-php/issues/582)) ([cc1d047](https://github.com/googleapis/gax-php/commit/cc1d0472a1caf31bb3ecd98da1d6b8588f95b63a)) * **docs:** Use doctum shared workflow for reference docs ([#578](https://github.com/googleapis/gax-php/issues/578)) ([021763f](https://github.com/googleapis/gax-php/commit/021763f255acaffda6ebe34a9d1a01c2bd187326)) * Support for API Key client option ([#351](https://github.com/googleapis/gax-php/issues/351)) ([ab7f04f](https://github.com/googleapis/gax-php/commit/ab7f04fd8c9f7ed33a58155ae6b9e740f365ac2a)) ### Bug Fixes * **tests:** Skip docs tests from forks ([#591](https://github.com/googleapis/gax-php/issues/591)) ([35ae9f7](https://github.com/googleapis/gax-php/commit/35ae9f708d3ef937308d266e3a012296ce8606fc)) ## [1.34.1](https://github.com/googleapis/gax-php/compare/v1.34.0...v1.34.1) (2024-08-13) ### Bug Fixes * Disable universe domain check for MDS ([#575](https://github.com/googleapis/gax-php/issues/575)) ([a47a469](https://github.com/googleapis/gax-php/commit/a47a469d9ef76613c5d320539646323a5e7b978d)) ## [1.34.0](https://github.com/googleapis/gax-php/compare/v1.33.0...v1.34.0) (2024-05-29) ### Features * Support new surface operations clients ([#569](https://github.com/googleapis/gax-php/issues/569)) ([fa06e73](https://github.com/googleapis/gax-php/commit/fa06e738fc63a3b9f70a26e6d20f30c582ef1870)) ## [1.33.0](https://github.com/googleapis/gax-php/compare/v1.32.0...v1.33.0) (2024-05-10) ### Features * Support V2 OperationsClient in OperationResponse ([#564](https://github.com/googleapis/gax-php/issues/564)) ([7f8bb13](https://github.com/googleapis/gax-php/commit/7f8bb13f78463b1e7f2289ce5514763992806e5e)) ## [1.32.0](https://github.com/googleapis/gax-php/compare/v1.31.0...v1.32.0) (2024-04-24) ### Features * Add a custom encoder in Serializer ([#554](https://github.com/googleapis/gax-php/issues/554)) ([be28b5a](https://github.com/googleapis/gax-php/commit/be28b5a859b674a3d398bdaab7ed86b93dd7a593)) ## [1.31.0](https://github.com/googleapis/gax-php/compare/v1.30.1...v1.31.0) (2024-04-22) ### Features * Add the api header to the GapicClientTrait ([#553](https://github.com/googleapis/gax-php/issues/553)) ([cc102eb](https://github.com/googleapis/gax-php/commit/cc102ebdfd63019b1e6bcd51515be2a2cb13534d)) ### Bug Fixes * Add caching and micro optimizations in Serializer ([5a5d8a7](https://github.com/googleapis/gax-php/commit/5a5d8a763d8e2d470a6d960b788e7d2a938cd64f)) * Pass auth http handler to update metadata call ([#557](https://github.com/googleapis/gax-php/issues/557)) ([6e04a50](https://github.com/googleapis/gax-php/commit/6e04a50d013f5686ec5e66c457b9b440b9bcde9e)) ## [1.30.0](https://github.com/googleapis/gax-php/compare/v1.29.1...v1.30.0) (2024-02-28) ### Features * Auto Populate fields configured for auto population in Rpc Request Message ([#543](https://github.com/googleapis/gax-php/issues/543)) ([99d6b89](https://github.com/googleapis/gax-php/commit/99d6b899ddf55d51fab976844c1e0f8fe9918a52)) * Make the default authHttpHandler in CredentialsWrapper null ([#544](https://github.com/googleapis/gax-php/issues/544)) ([2a25eea](https://github.com/googleapis/gax-php/commit/2a25eeacadf2f783f64b4eca4f94e067ddef3eaa)) ## [1.29.1](https://github.com/googleapis/gax-php/compare/v1.29.0...v1.29.1) (2024-02-26) ### Bug Fixes * Allow InsecureCredentialsWrapper::getAuthorizationHeaderCallback to return null ([#541](https://github.com/googleapis/gax-php/issues/541)) ([676f4f7](https://github.com/googleapis/gax-php/commit/676f4f7e3d8925d8aba00285616fdf89440b45f9)) ## [1.29.0](https://github.com/googleapis/gax-php/compare/v1.28.1...v1.29.0) (2024-02-26) ### Features * Add InsecureCredentialsWrapper for Emulator connection ([#538](https://github.com/googleapis/gax-php/issues/538)) ([b5dbeaf](https://github.com/googleapis/gax-php/commit/b5dbeaf33594b300a0c678ffc6a6946b09fce7dd)) ## [1.28.1](https://github.com/googleapis/gax-php/compare/v1.28.0...v1.28.1) (2024-02-20) ### Bug Fixes * Universe domain check for grpc transport ([#534](https://github.com/googleapis/gax-php/issues/534)) ([1026d8a](https://github.com/googleapis/gax-php/commit/1026d8aec73e0aad8949a86ee7575e3edb3d56be)) ## [1.28.0](https://github.com/googleapis/gax-php/compare/v1.27.2...v1.28.0) (2024-02-15) ### Features * Allow setting of universe domain in environment variable ([#520](https://github.com/googleapis/gax-php/issues/520)) ([6e6603b](https://github.com/googleapis/gax-php/commit/6e6603b03285f3f8d1072776cd206720e3990f50)) ## [1.27.2](https://github.com/googleapis/gax-php/compare/v1.27.1...v1.27.2) (2024-02-14) ### Bug Fixes * Typo in TransportOptions option name ([#530](https://github.com/googleapis/gax-php/issues/530)) ([6914fe0](https://github.com/googleapis/gax-php/commit/6914fe04554867bd827be6596fafc751a3d7621a)) ## [1.27.1](https://github.com/googleapis/gax-php/compare/v1.27.0...v1.27.1) (2024-02-14) ### Bug Fixes * Issues in Options classes ([#528](https://github.com/googleapis/gax-php/issues/528)) ([aa9ba3a](https://github.com/googleapis/gax-php/commit/aa9ba3a6bac9324ad894d9677da0e897497ebab2)) ## [1.27.0](https://github.com/googleapis/gax-php/compare/v1.26.3...v1.27.0) (2024-02-07) ### Features * Create ClientOptionsTrait ([#527](https://github.com/googleapis/gax-php/issues/527)) ([cfe2c60](https://github.com/googleapis/gax-php/commit/cfe2c60a36233f74259c96a6799d8492ed7c45d0)) * Implement ProjectIdProviderInterface in CredentialsWrapper ([#523](https://github.com/googleapis/gax-php/issues/523)) ([b56a463](https://github.com/googleapis/gax-php/commit/b56a4635abfeeec08895202da8218e9ba915413e)) * Update ArrayTrait to be consistent with Core ([#526](https://github.com/googleapis/gax-php/issues/526)) ([8e44185](https://github.com/googleapis/gax-php/commit/8e44185dd6f8f8f9ef5b136776cba61ec7a8b8f6)) ### Bug Fixes * Correct exception type for Guzzle promise ([#521](https://github.com/googleapis/gax-php/issues/521)) ([7129373](https://github.com/googleapis/gax-php/commit/712937339c134e1d92cab5fa736cfe1bbcd7f343)) ## [1.26.3](https://github.com/googleapis/gax-php/compare/v1.26.2...v1.26.3) (2024-01-18) ### Bug Fixes * CallOptions should use transportOptions ([#513](https://github.com/googleapis/gax-php/issues/513)) ([2d45ee1](https://github.com/googleapis/gax-php/commit/2d45ee187cdc3619b30c51b653b508718baf3af4)) ## [1.26.2](https://github.com/googleapis/gax-php/compare/v1.26.1...v1.26.2) (2024-01-09) ### Bug Fixes * Ensure modifyClientOptions is called for new surface clients ([#515](https://github.com/googleapis/gax-php/issues/515)) ([68231b8](https://github.com/googleapis/gax-php/commit/68231b896dec8efb86f8986aefba3d247d2a2d1c)) ## [1.26.1](https://github.com/googleapis/gax-php/compare/v1.26.0...v1.26.1) (2024-01-04) ### Bug Fixes * Widen google/longrunning version ([#511](https://github.com/googleapis/gax-php/issues/511)) ([b93096d](https://github.com/googleapis/gax-php/commit/b93096d0e10bde14c50480ea9f0423c292fbd5a6)) ## [1.26.0](https://github.com/googleapis/gax-php/compare/v1.25.0...v1.26.0) (2024-01-03) ### Features * Add support for universe domain ([#502](https://github.com/googleapis/gax-php/issues/502)) ([5a26fac](https://github.com/googleapis/gax-php/commit/5a26facad5c2e5c30945987c422bb78a3fffb9b1)) * Interface and methods for middleware stack ([#473](https://github.com/googleapis/gax-php/issues/473)) ([766da7b](https://github.com/googleapis/gax-php/commit/766da7b369409ec1b29376b533e7f22ee7f745f4)) ### Bug Fixes * Accept throwable for retry settings ([#509](https://github.com/googleapis/gax-php/issues/509)) ([5af9c3c](https://github.com/googleapis/gax-php/commit/5af9c3c650419c8f1a590783e954cd11dc1f0d56)) ## [1.25.0](https://github.com/googleapis/gax-php/compare/v1.24.0...v1.25.0) (2023-11-02) ### Features * Add custom retries ([#489](https://github.com/googleapis/gax-php/issues/489)) ([ef0789b](https://github.com/googleapis/gax-php/commit/ef0789b73ef28d79a08c354d1361a9ccc6206088)) ## [1.24.0](https://github.com/googleapis/gax-php/compare/v1.23.0...v1.24.0) (2023-10-10) ### Features * Ensure NewClientSurface works for consoldiated v2 clients ([#493](https://github.com/googleapis/gax-php/issues/493)) ([cb8706e](https://github.com/googleapis/gax-php/commit/cb8706ef9211a1e43f733d2c8f272a330c2fa792)) ## [1.23.0](https://github.com/googleapis/gax-php/compare/v1.22.1...v1.23.0) (2023-09-14) ### Features * Typesafety for new surface client options ([#450](https://github.com/googleapis/gax-php/issues/450)) ([21550c5](https://github.com/googleapis/gax-php/commit/21550c5bf07f178f2043b0630f3ac34fcc3a05e0)) ## [1.22.1](https://github.com/googleapis/gax-php/compare/v1.22.0...v1.22.1) (2023-08-04) ### Bug Fixes * Deprecation notice while GapicClientTrait->setClientOptions ([#483](https://github.com/googleapis/gax-php/issues/483)) ([1c66d34](https://github.com/googleapis/gax-php/commit/1c66d3445dca4d43831a2f4e26e59b9bd1cb76dd)) ## [1.22.0](https://github.com/googleapis/gax-php/compare/v1.21.1...v1.22.0) (2023-07-31) ### Features * Sets api headers for "gcloud-php-new" and "gcloud-php-legacy" surface versions ([#470](https://github.com/googleapis/gax-php/issues/470)) ([2d8ccff](https://github.com/googleapis/gax-php/commit/2d8ccff419a076ee2fe9d3dc7ecd5509c74afb4c)) ## [1.21.1](https://github.com/googleapis/gax-php/compare/v1.21.0...v1.21.1) (2023-06-28) ### Bug Fixes * Revert "chore: remove unnecessary api endpoint check" ([#476](https://github.com/googleapis/gax-php/issues/476)) ([13e773f](https://github.com/googleapis/gax-php/commit/13e773f5b09f9a99b8425835815746d37e9c1da3)) ## [1.21.0](https://github.com/googleapis/gax-php/compare/v1.20.2...v1.21.0) (2023-06-09) ### Features * Support guzzle/promises:v2 ([753eae9](https://github.com/googleapis/gax-php/commit/753eae9acf638f3356f8149acf84444eb399a699)) ## [1.20.2](https://github.com/googleapis/gax-php/compare/v1.20.1...v1.20.2) (2023-05-12) ### Bug Fixes * Ensure timeout set by RetryMiddleware is int not float ([#462](https://github.com/googleapis/gax-php/issues/462)) ([9d4c7fa](https://github.com/googleapis/gax-php/commit/9d4c7fa89445c63ec0bf4745ed9d98fd185ef51f)) ## [1.20.1](https://github.com/googleapis/gax-php/compare/v1.20.0...v1.20.1) (2023-05-12) ### Bug Fixes * Default value for error message in createFromRequestException ([#463](https://github.com/googleapis/gax-php/issues/463)) ([7552d22](https://github.com/googleapis/gax-php/commit/7552d22241c2f488606e9546efdd6edea356ee9a)) ## [1.20.0](https://github.com/googleapis/gax-php/compare/v1.19.1...v1.20.0) (2023-05-01) ### Features * **deps:** Support google/common-protos 4.0 ([af1db80](https://github.com/googleapis/gax-php/commit/af1db80c22307597f0dfcb9fafa86caf466588ba)) * **deps:** Support google/grpc-gcp 0.3 ([18edc2c](https://github.com/googleapis/gax-php/commit/18edc2ce6a1a615e3ea7c00ede313c32cec4b799)) ## [1.19.1](https://github.com/googleapis/gax-php/compare/v1.19.0...v1.19.1) (2023-03-16) ### Bug Fixes * Simplify ResourceHelperTrait registration ([#447](https://github.com/googleapis/gax-php/issues/447)) ([4949dc0](https://github.com/googleapis/gax-php/commit/4949dc0c4cd5e58af7933a1d2ecab90832c0b036)) ## [1.19.0](https://github.com/googleapis/gax-php/compare/v1.18.2...v1.19.0) (2023-01-27) ### Features * Ensure cache is used in calls to ADC::onGCE ([#441](https://github.com/googleapis/gax-php/issues/441)) ([64a4184](https://github.com/googleapis/gax-php/commit/64a4184ab69d13104d269b15a55d4b8b2515b5a6)) ## [1.18.2](https://github.com/googleapis/gax-php/compare/v1.18.1...v1.18.2) (2023-01-06) ### Bug Fixes * Ensure metadata return type is loaded into descriptor pool ([#439](https://github.com/googleapis/gax-php/issues/439)) ([a40cf8d](https://github.com/googleapis/gax-php/commit/a40cf8d87ac9aa45d18239456e2e4c96653f1a6c)) * Implicit conversion from float to int warning ([#438](https://github.com/googleapis/gax-php/issues/438)) ([1cb62ad](https://github.com/googleapis/gax-php/commit/1cb62ad3d92ace0518017abc972e912b339f1b56)) ## [1.18.1](https://github.com/googleapis/gax-php/compare/v1.18.0...v1.18.1) (2022-12-06) ### Bug Fixes * Message parameters in required querystring ([#430](https://github.com/googleapis/gax-php/issues/430)) ([77bc5e1](https://github.com/googleapis/gax-php/commit/77bc5e1cb8f347601d9237bf5164cf8b8ad8aa0f)) ## [1.18.0](https://github.com/googleapis/gax-php/compare/v1.17.0...v1.18.0) (2022-12-05) ### Features * Add ResourceHelperTrait ([#428](https://github.com/googleapis/gax-php/issues/428)) ([0439efa](https://github.com/googleapis/gax-php/commit/0439efa926865be5fea25b699469b0c1f8c1c768)) ## [1.17.0](https://github.com/googleapis/gax-php/compare/v1.16.4...v1.17.0) (2022-09-08) ### Features * Add startAsyncCall support ([#418](https://github.com/googleapis/gax-php/issues/418)) ([fc90693](https://github.com/googleapis/gax-php/commit/fc9069373c329183e07f8d174084c305b2308209)) ## [1.16.4](https://github.com/googleapis/gax-php/compare/v1.16.3...v1.16.4) (2022-08-25) ### Bug Fixes * use interfaceOverride instead of param ([#419](https://github.com/googleapis/gax-php/issues/419)) ([9dd5bc9](https://github.com/googleapis/gax-php/commit/9dd5bc91c4becfd2a0832288ab2406c3d224618e)) ## [1.16.3](https://github.com/googleapis/gax-php/compare/v1.16.2...v1.16.3) (2022-08-23) ### Bug Fixes * add eager threshold ([#416](https://github.com/googleapis/gax-php/issues/416)) ([99eb172](https://github.com/googleapis/gax-php/commit/99eb172280f301b117fde9dcc92079ca03aa28bd)) ## [1.16.2](https://github.com/googleapis/gax-php/compare/v1.16.1...v1.16.2) (2022-08-16) ### Bug Fixes * use responseType for custom operations ([#413](https://github.com/googleapis/gax-php/issues/413)) ([b643adf](https://github.com/googleapis/gax-php/commit/b643adfc44dd9fe82b0919e5b34edd00c7cdbb1f)) ## [1.16.1](https://github.com/googleapis/gax-php/compare/v1.16.0...v1.16.1) (2022-08-11) ### Bug Fixes * remove typehint from extended method ([#411](https://github.com/googleapis/gax-php/issues/411)) ([fb37f73](https://github.com/googleapis/gax-php/commit/fb37f7365e888465d84fca304ca83360ddbae6c3)) ## [1.16.0](https://github.com/googleapis/gax-php/compare/v1.15.0...v1.16.0) (2022-08-10) ### Features * additional typehinting ([#403](https://github.com/googleapis/gax-php/issues/403)) ([6597a07](https://github.com/googleapis/gax-php/commit/6597a07019665d91e07ea0a016c7d99c8a099cd2)) * drop support for PHP 5.6 ([#397](https://github.com/googleapis/gax-php/issues/397)) ([b888b24](https://github.com/googleapis/gax-php/commit/b888b24e0e223784e22dbbbe27fe0284cdcdfc35)) * introduce startApiCall ([#406](https://github.com/googleapis/gax-php/issues/406)) ([1cfeb62](https://github.com/googleapis/gax-php/commit/1cfeb628070c9c6e57b2dde854b0a973a888a2bc)) ### Bug Fixes * **deps:** update dependency google/longrunning to ^0.2 ([#407](https://github.com/googleapis/gax-php/issues/407)) ([54d4f32](https://github.com/googleapis/gax-php/commit/54d4f32ba5464d1f5da33e1c99a020174cae367c)) ## [1.15.0](https://github.com/googleapis/gax-php/compare/v1.14.0...v1.15.0) (2022-08-02) ### Features * move LongRunning classes to a standalone package ([#401](https://github.com/googleapis/gax-php/issues/401)) ([1747125](https://github.com/googleapis/gax-php/commit/1747125c84dcc6d42390de7e78d2e326884e1073)) ## [1.14.0](https://github.com/googleapis/gax-php/compare/v1.13.0...v1.14.0) (2022-07-26) ### Features * support requesting numeric enum rest encoding ([#395](https://github.com/googleapis/gax-php/issues/395)) ([0d74a48](https://github.com/googleapis/gax-php/commit/0d74a4877c5198cfaf534c4e55d7e418b50bc6ab)) ================================================ FILE: lib/Google/vendor/google/gax/CODE_OF_CONDUCT.md ================================================ # Contributor Code of Conduct As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities. We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality. Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery * Personal attacks * Trolling or insulting/derogatory comments * Public or private harassment * Publishing other's private information, such as physical or electronic addresses, without explicit permission * Other unethical or unprofessional conduct. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team. This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers. This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0, available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/) ================================================ FILE: lib/Google/vendor/google/gax/LICENSE ================================================ Copyright 2016, Google Inc. 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 Google Inc. 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. ================================================ FILE: lib/Google/vendor/google/gax/README.md ================================================ # Google API Core for PHP ![Build Status](https://github.com/googleapis/gax-php/actions/workflows/tests.yml/badge.svg) - [Documentation](https://cloud.google.com/php/docs/reference/gax/latest) Google API Core for PHP (gax-php) is a set of modules which aids the development of APIs for clients based on [gRPC][] and Google API conventions. Application code will rarely need to use most of the classes within this library directly, but code generated automatically from the API definition files in [Google APIs][] can use services such as page streaming and retry to provide a more convenient and idiomatic API surface to callers. [gRPC]: http://grpc.io [Google APIs]: https://github.com/googleapis/googleapis/ ## PHP Versions gax-php currently requires PHP 8.1 or higher. ## Contributing Contributions to this library are always welcome and highly encouraged. See the [CONTRIBUTING][] documentation for more information on how to get started. [CONTRIBUTING]: https://github.com/googleapis/gax-php/blob/main/.github/CONTRIBUTING.md ## Versioning This library follows [Semantic Versioning][]. This library is considered GA (generally available). As such, it will not introduce backwards-incompatible changes in any minor or patch releases. We will address issues and requests with the highest priority. [Semantic Versioning]: http://semver.org/ ## Repository Structure All code lives under the src/ directory. Handwritten code lives in the src/ApiCore directory and is contained in the `Google\ApiCore` namespace. Generated classes for protobuf common types and LongRunning client live under the src/ directory, in the appropriate directory and namespace. Code in the metadata/ directory is provided to support generated protobuf classes, and should not be used directly. ## Development Set-Up These steps describe the dependencies to install for Linux, and equivalents can be found for Mac or Windows. 1. Install dependencies. ```sh > cd ~/ > sudo apt-get install php php-dev libcurl3-openssl-dev php-pear php-bcmath php-xml > curl -sS https://getcomposer.org/installer | php > sudo pecl install protobuf ``` 2. Set up this repo. ```sh > cd /path/to/gax-php > composer install ``` 3. Run tests. ```sh > composer test ``` 4. Updating dependencies after changing `composer.json`: ```sh > composer update ` ``` 5. Formatting source: ```sh > composer cs-lint > composer cs-fix ``` ## License BSD - See [LICENSE][] for more information. [LICENSE]: https://github.com/googleapis/gax-php/blob/main/LICENSE ================================================ FILE: lib/Google/vendor/google/gax/SECURITY.md ================================================ # Security Policy To report a security issue, please use [g.co/vulnz](https://g.co/vulnz). The Google Security Team will respond within 5 working days of your report on g.co/vulnz. We use g.co/vulnz for our intake, and do coordination and disclosure here using GitHub Security Advisory to privately discuss and fix the issue. ================================================ FILE: lib/Google/vendor/google/gax/VERSION ================================================ 1.40.0 ================================================ FILE: lib/Google/vendor/google/gax/composer.json ================================================ { "name": "google/gax", "type": "library", "description": "Google API Core for PHP", "keywords": ["google"], "homepage": "https://github.com/googleapis/gax-php", "license": "BSD-3-Clause", "require": { "php": "^8.1", "google/auth": "^1.49", "google/grpc-gcp": "^0.4", "grpc/grpc": "^1.13", "google/protobuf": "^4.31", "guzzlehttp/promises": "^2.0", "guzzlehttp/psr7": "^2.0", "google/common-protos": "^4.4", "google/longrunning": "~0.4", "ramsey/uuid": "^4.0" }, "require-dev": { "phpunit/phpunit": "^9.6", "squizlabs/php_codesniffer": "4.*", "phpspec/prophecy-phpunit": "^2.1", "phpstan/phpstan": "^2.0" }, "conflict": { "ext-protobuf": "<4.31.0" }, "autoload": { "psr-4": { "Google\\ApiCore\\": "src", "GPBMetadata\\ApiCore\\": "metadata/ApiCore" } }, "autoload-dev": { "psr-4": { "Google\\ApiCore\\Dev\\": "dev/src", "Google\\ApiCore\\Tests\\": "tests", "GPBMetadata\\Google\\": "metadata/Google" } }, "scripts": { "regenerate-test-protos": "dev/sh/regenerate-test-protos.sh", "test": "./vendor/bin/phpunit", "cs-lint": "vendor/bin/phpcs --standard=./ruleset.xml", "cs-fix": "vendor/bin/phpcbf --standard=./ruleset.xml" } } ================================================ FILE: lib/Google/vendor/google/gax/metadata/Google/ApiCore/Tests/Unit/Example.php ================================================ internalAddGeneratedFile(hex2bin( "0a85010a0d6578616d706c652e70726f746f1219676f6f676c652e617069" . "636f72652e74657374732e756e6974220b0a094d794d6573736167654244" . "ca0219476f6f676c655c417069436f72655c54657374735c556e6974e202" . "254750424d657461646174615c476f6f676c655c417069436f72655c5465" . "7374735c556e6974620670726f746f33" )); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/gax/metadata/README.md ================================================ # Google Protobuf Metadata Classes ## WARNING! These classes are not intended for direct use - they exist only to support the generated protobuf classes in src/ ================================================ FILE: lib/Google/vendor/google/gax/phpstan.neon.dist ================================================ parameters: treatPhpDocTypesAsCertain: false level: 5 paths: - src ================================================ FILE: lib/Google/vendor/google/gax/phpunit.xml.dist ================================================ src/ApiCore tests/Unit ================================================ FILE: lib/Google/vendor/google/gax/renovate.json ================================================ { "extends": [ "config:base", ":preserveSemverRanges", ":disableDependencyDashboard" ] } ================================================ FILE: lib/Google/vendor/google/gax/src/AgentHeader.php ================================================ $value) { $metricsList[] = $key . '/' . $value; } return [self::AGENT_HEADER_KEY => [implode(' ', $metricsList)]]; } /** * Reads the gapic version string from a VERSION file. In order to determine the file * location, this method follows this procedure: * - accepts a class name $callingClass * - identifies the file defining that class * - searches up the directory structure for the 'src' directory * - looks in the directory above 'src' for a file named VERSION * * @param string $callingClass * @return string the gapic version * @throws \ReflectionException */ public static function readGapicVersionFromFile(string $callingClass) { $callingClassFile = (new \ReflectionClass($callingClass))->getFileName(); $versionFile = substr( $callingClassFile, 0, strrpos($callingClassFile, DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR) ) . DIRECTORY_SEPARATOR . 'VERSION'; return Version::readVersionFile($versionFile); } } ================================================ FILE: lib/Google/vendor/google/gax/src/ApiException.php ================================================ null, 'metadata' => null, 'basicMessage' => $message, ]; parent::__construct($message, $code, $optionalArgs['previous']); $this->status = $status; $this->metadata = $optionalArgs['metadata']; $this->basicMessage = $optionalArgs['basicMessage']; if ($this->metadata) { $this->decodedMetadataErrorInfo = self::decodeMetadataErrorInfo($this->metadata); } } public function getStatus() { return $this->status; } /** * Returns null if metadata does not contain error info, or returns containsErrorInfo() array * if the metadata does contain error info. * @param array $metadata * @return array $details { * @type string|null $reason * @type string|null $domain * @type array|null $errorInfoMetadata * } */ private static function decodeMetadataErrorInfo(array $metadata) { $details = []; // ApiExceptions created from RPC status have metadata that is an array of objects. if (is_object(reset($metadata))) { $metadataRpcStatus = Serializer::decodeAnyMessages($metadata); $details = self::containsErrorInfo($metadataRpcStatus); } elseif (self::containsErrorInfo($metadata)) { $details = self::containsErrorInfo($metadata); } else { // For GRPC-based responses, the $metadata needs to be decoded. $metadataGrpc = Serializer::decodeMetadata($metadata); $details = self::containsErrorInfo($metadataGrpc); } return $details; } /** * Returns the `reason` in ErrorInfo for an exception, or null if there is no ErrorInfo. * @return string|null $reason */ public function getReason() { return ($this->decodedMetadataErrorInfo) ? $this->decodedMetadataErrorInfo['reason'] : null; } /** * Returns the `domain` in ErrorInfo for an exception, or null if there is no ErrorInfo. * @return string|null $domain */ public function getDomain() { return ($this->decodedMetadataErrorInfo) ? $this->decodedMetadataErrorInfo['domain'] : null; } /** * Returns the `metadata` in ErrorInfo for an exception, or null if there is no ErrorInfo. * @return array|null $errorInfoMetadata */ public function getErrorInfoMetadata() { return ($this->decodedMetadataErrorInfo) ? $this->decodedMetadataErrorInfo['errorInfoMetadata'] : null; } /** * @param stdClass $status * @return ApiException */ public static function createFromStdClass(stdClass $status) { $metadata = property_exists($status, 'metadata') ? $status->metadata : null; return self::create( $status->details, $status->code, $metadata, Serializer::decodeMetadata((array) $metadata) ); } /** * @param string $basicMessage * @param int $rpcCode * @param array|null $metadata * @param Exception $previous * @return ApiException */ public static function createFromApiResponse( $basicMessage, $rpcCode, ?array $metadata = null, ?Exception $previous = null ) { return self::create( $basicMessage, $rpcCode, $metadata, Serializer::decodeMetadata((array) $metadata), $previous ); } /** * For REST-based responses, the metadata does not need to be decoded. * * @param string $basicMessage * @param int $rpcCode * @param array|null $metadata * @param Exception $previous * @return ApiException */ public static function createFromRestApiResponse( $basicMessage, $rpcCode, ?array $metadata = null, ?Exception $previous = null ) { return self::create( $basicMessage, $rpcCode, $metadata, is_null($metadata) ? [] : $metadata, $previous ); } /** * Checks if decoded metadata includes errorInfo message. * If errorInfo is set, it will always contain `reason`, `domain`, and `metadata` keys. * @param array $decodedMetadata * @return array { * @type string $reason * @type string $domain * @type array $errorInfoMetadata * } */ private static function containsErrorInfo(array $decodedMetadata) { if (empty($decodedMetadata)) { return []; } foreach ($decodedMetadata as $value) { $isErrorInfoArray = isset($value['reason']) && isset($value['domain']) && isset($value['metadata']); if ($isErrorInfoArray) { return [ 'reason' => $value['reason'], 'domain' => $value['domain'], 'errorInfoMetadata' => $value['metadata'], ]; } } return []; } /** * Construct an ApiException with a useful message, including decoded metadata. * If the decoded metadata includes an errorInfo message, then the domain, reason, * and metadata fields from that message are hoisted directly into the error. * * @param string $basicMessage * @param int $rpcCode * @param iterable|null $metadata * @param array $decodedMetadata * @param Exception|null $previous * @return ApiException */ private static function create( string $basicMessage, int $rpcCode, $metadata, array $decodedMetadata, ?Exception $previous = null ) { $containsErrorInfo = self::containsErrorInfo($decodedMetadata); $rpcStatus = ApiStatus::statusFromRpcCode($rpcCode); $messageData = [ 'message' => $basicMessage, 'code' => $rpcCode, 'status' => $rpcStatus, 'details' => $decodedMetadata ]; if ($containsErrorInfo) { $messageData = array_merge($containsErrorInfo, $messageData); } $message = json_encode($messageData, JSON_PRETTY_PRINT); if ($metadata instanceof RepeatedField) { $metadata = iterator_to_array($metadata); } return new ApiException($message, $rpcCode, $rpcStatus, [ 'previous' => $previous, 'metadata' => $metadata, 'basicMessage' => $basicMessage, ]); } /** * @param Status $status * @return ApiException */ public static function createFromRpcStatus(Status $status) { return self::create( $status->getMessage(), $status->getCode(), $status->getDetails(), Serializer::decodeAnyMessages($status->getDetails()) ); } /** * Creates an ApiException from a GuzzleHttp RequestException. * * @param RequestException $ex * @param boolean $isStream * @return ApiException * @throws ValidationException */ public static function createFromRequestException(RequestException $ex, bool $isStream = false) { $res = $ex->getResponse(); $body = (string) $res->getBody(); $decoded = json_decode($body, true); // A streaming response body will return one error in an array. Parse // that first (and only) error message, if provided. if ($isStream && isset($decoded[0])) { $decoded = $decoded[0]; } if (isset($decoded['error']) && $decoded['error']) { $error = $decoded['error']; $basicMessage = $error['message'] ?? ''; $code = isset($error['status']) ? ApiStatus::rpcCodeFromStatus($error['status']) : $ex->getCode(); $metadata = $error['details'] ?? null; return static::createFromRestApiResponse($basicMessage, $code, $metadata); } // Use the RPC code instead of the HTTP Status Code. $code = ApiStatus::rpcCodeFromHttpStatusCode($res->getStatusCode()); return static::createFromApiResponse($body, $code); } /** * @return null|string */ public function getBasicMessage() { return $this->basicMessage; } /** * @return mixed[] */ public function getMetadata() { return $this->metadata; } } ================================================ FILE: lib/Google/vendor/google/gax/src/ApiKeyHeaderCredentials.php ================================================ apiKey = $apiKey; $this->quotaProject = $quotaProject; } /** * @return string|null The quota project associated with the credentials. */ public function getQuotaProject(): ?string { return $this->quotaProject; } /** * @param string|null $unusedAudience audiences are not supported for API keys. * * @return callable|null Callable function that returns the API key header. */ public function getAuthorizationHeaderCallback(?string $unusedAudience = null): ?callable { $apiKey = $this->apiKey; // NOTE: changes to this function should be treated carefully and tested thoroughly. It will // be passed into the gRPC c extension, and changes have the potential to trigger very // difficult-to-diagnose segmentation faults. return function () use ($apiKey) { return ['x-goog-api-key' => [$apiKey]]; }; } /** * Verify that the expected universe domain matches the universe domain from the credentials. * * @throws ValidationException if the universe domain does not match. */ public function checkUniverseDomain(): void { // This is a no-op, as API keys are not tied to a universe domain. As a result, the // potential for leaking API keys to the GDU is higher, and it's recommended to specify // the "universeDomain" option with the GAPIC client. } } ================================================ FILE: lib/Google/vendor/google/gax/src/ApiStatus.php ================================================ Code::OK, ApiStatus::CANCELLED => Code::CANCELLED, ApiStatus::UNKNOWN => Code::UNKNOWN, ApiStatus::INVALID_ARGUMENT => Code::INVALID_ARGUMENT, ApiStatus::DEADLINE_EXCEEDED => Code::DEADLINE_EXCEEDED, ApiStatus::NOT_FOUND => Code::NOT_FOUND, ApiStatus::ALREADY_EXISTS => Code::ALREADY_EXISTS, ApiStatus::PERMISSION_DENIED => Code::PERMISSION_DENIED, ApiStatus::RESOURCE_EXHAUSTED => Code::RESOURCE_EXHAUSTED, ApiStatus::FAILED_PRECONDITION => Code::FAILED_PRECONDITION, ApiStatus::ABORTED => Code::ABORTED, ApiStatus::OUT_OF_RANGE => Code::OUT_OF_RANGE, ApiStatus::UNIMPLEMENTED => Code::UNIMPLEMENTED, ApiStatus::INTERNAL => Code::INTERNAL, ApiStatus::UNAVAILABLE => Code::UNAVAILABLE, ApiStatus::DATA_LOSS => Code::DATA_LOSS, ApiStatus::UNAUTHENTICATED => Code::UNAUTHENTICATED, ]; private static $codeToApiStatusMap = [ Code::OK => ApiStatus::OK, Code::CANCELLED => ApiStatus::CANCELLED, Code::UNKNOWN => ApiStatus::UNKNOWN, Code::INVALID_ARGUMENT => ApiStatus::INVALID_ARGUMENT, Code::DEADLINE_EXCEEDED => ApiStatus::DEADLINE_EXCEEDED, Code::NOT_FOUND => ApiStatus::NOT_FOUND, Code::ALREADY_EXISTS => ApiStatus::ALREADY_EXISTS, Code::PERMISSION_DENIED => ApiStatus::PERMISSION_DENIED, Code::RESOURCE_EXHAUSTED => ApiStatus::RESOURCE_EXHAUSTED, Code::FAILED_PRECONDITION => ApiStatus::FAILED_PRECONDITION, Code::ABORTED => ApiStatus::ABORTED, Code::OUT_OF_RANGE => ApiStatus::OUT_OF_RANGE, Code::UNIMPLEMENTED => ApiStatus::UNIMPLEMENTED, Code::INTERNAL => ApiStatus::INTERNAL, Code::UNAVAILABLE => ApiStatus::UNAVAILABLE, Code::DATA_LOSS => ApiStatus::DATA_LOSS, Code::UNAUTHENTICATED => ApiStatus::UNAUTHENTICATED, ]; private static $httpStatusCodeToRpcCodeMap = [ 400 => Code::INVALID_ARGUMENT, 401 => Code::UNAUTHENTICATED, 403 => Code::PERMISSION_DENIED, 404 => Code::NOT_FOUND, 409 => Code::ABORTED, 416 => Code::OUT_OF_RANGE, 429 => Code::RESOURCE_EXHAUSTED, 499 => Code::CANCELLED, 501 => Code::UNIMPLEMENTED, 503 => Code::UNAVAILABLE, 504 => Code::DEADLINE_EXCEEDED, ]; /** * @param string $status * @return bool */ public static function isValidStatus(string $status) { return array_key_exists($status, self::$apiStatusToCodeMap); } /** * @param int $code * @return string */ public static function statusFromRpcCode(int $code) { if (array_key_exists($code, self::$codeToApiStatusMap)) { return self::$codeToApiStatusMap[$code]; } return ApiStatus::UNRECOGNIZED_STATUS; } /** * @param string $status * @return int */ public static function rpcCodeFromStatus(string $status) { if (array_key_exists($status, self::$apiStatusToCodeMap)) { return self::$apiStatusToCodeMap[$status]; } return ApiStatus::UNRECOGNIZED_CODE; } /** * Maps HTTP status codes to Google\Rpc\Code codes. * Some codes are left out because they map to multiple gRPC codes (e.g. 500). * * @param int $httpStatusCode * @return int */ public static function rpcCodeFromHttpStatusCode(int $httpStatusCode) { if (array_key_exists($httpStatusCode, self::$httpStatusCodeToRpcCodeMap)) { return self::$httpStatusCodeToRpcCodeMap[$httpStatusCode]; } // All 2xx if ($httpStatusCode >= 200 && $httpStatusCode < 300) { return Code::OK; } // All 4xx if ($httpStatusCode >= 400 && $httpStatusCode < 500) { return Code::FAILED_PRECONDITION; } // All 5xx if ($httpStatusCode >= 500 && $httpStatusCode < 600) { return Code::INTERNAL; } // Everything else (We cannot change this to Code::UNKNOWN because it would break BC) return ApiStatus::UNRECOGNIZED_CODE; } } ================================================ FILE: lib/Google/vendor/google/gax/src/ArrayTrait.php ================================================ pluck($key, $arr, false); } } return $values; } /** * Determine whether given array is associative. * * @param array $arr * @return bool */ private function isAssoc(array $arr) { return array_keys($arr) !== range(0, count($arr) - 1); } /** * Just like array_filter(), but preserves falsey values except null. * * @param array $arr * @return array */ private function arrayFilterRemoveNull(array $arr) { return array_filter($arr, function ($element) { if (!is_null($element)) { return true; } return false; }); } /** * Return a subset of an array, like pluckArray, without modifying the original array. * * @param array $keys * @param array $arr * @return array */ private function subsetArray(array $keys, array $arr) { return array_intersect_key( $arr, array_flip($keys) ); } /** * A method, similar to PHP's `array_merge_recursive`, with two differences. * * 1. Keys in $array2 take precedence over keys in $array1. * 2. Non-array keys found in both inputs are not transformed into an array * and appended. Rather, the value in $array2 is used. * * @param array $array1 * @param array $array2 * @return array */ private function arrayMergeRecursive(array $array1, array $array2) { foreach ($array2 as $key => $value) { if (array_key_exists($key, $array1) && is_array($array1[$key]) && is_array($value)) { $array1[$key] = ($this->isAssoc($array1[$key]) && $this->isAssoc($value)) ? $this->arrayMergeRecursive($array1[$key], $value) : array_merge($array1[$key], $value); } else { $array1[$key] = $value; } } return $array1; } } ================================================ FILE: lib/Google/vendor/google/gax/src/BidiStream.php ================================================ call = $bidiStreamingCall; if (array_key_exists('resourcesGetMethod', $streamingDescriptor)) { $this->resourcesGetMethod = $streamingDescriptor['resourcesGetMethod']; } $this->logger = $logger; } /** * Write request to the server. * * @param mixed $request The request to write * @throws ValidationException */ public function write($request) { if ($this->isComplete) { throw new ValidationException('Cannot call write() after streaming call is complete.'); } if ($this->writesClosed) { throw new ValidationException('Cannot call write() after calling closeWrite().'); } if ($this->logger && $request instanceof Message) { $logEvent = new RpcLogEvent(); $logEvent->headers = null; $logEvent->payload = $request->serializeToJsonString(); $logEvent->processId = (int) getmypid(); $logEvent->requestId = crc32((string) spl_object_id($this) . getmypid()); $this->logRequest($logEvent); } $this->call->write($request); } /** * Write all requests in $requests. * * @param iterable $requests An Iterable of request objects to write to the server * * @throws ValidationException */ public function writeAll($requests = []) { foreach ($requests as $request) { $this->write($request); } } /** * Inform the server that no more requests will be written. The write() function cannot be * called after closeWrite() is called. * @throws ValidationException */ public function closeWrite() { if ($this->isComplete) { throw new ValidationException( 'Cannot call closeWrite() after streaming call is complete.' ); } if (!$this->writesClosed) { $this->call->writesDone(); $this->writesClosed = true; } } /** * Read the next response from the server. Returns null if the streaming call completed * successfully. Throws an ApiException if the streaming call failed. * * @throws ValidationException * @throws ApiException * @return mixed */ public function read() { if ($this->isComplete) { throw new ValidationException('Cannot call read() after streaming call is complete.'); } $resourcesGetMethod = $this->resourcesGetMethod; if (!is_null($resourcesGetMethod)) { if (count($this->pendingResources) === 0) { $response = $this->call->read(); if (!is_null($response)) { $pendingResources = []; foreach ($response->$resourcesGetMethod() as $resource) { $pendingResources[] = $resource; } $this->pendingResources = array_reverse($pendingResources); } } $result = array_pop($this->pendingResources); } else { $result = $this->call->read(); } if (is_null($result)) { $status = $this->call->getStatus(); $this->isComplete = true; if (!($status->code == Code::OK)) { throw ApiException::createFromStdClass($status); } } if ($this->logger) { $responseEvent = new RpcLogEvent(); $responseEvent->headers = $this->call->getMetadata(); $responseEvent->status = $status->code ?? null; $responseEvent->processId = (int) getmypid(); $responseEvent->requestId = crc32((string) spl_object_id($this) . getmypid()); if ($result instanceof Message) { $responseEvent->payload = $result->serializeToJsonString(); } $this->logResponse($responseEvent); } return $result; } /** * Call closeWrite(), and read all responses from the server, until the streaming call is * completed. Throws an ApiException if the streaming call failed. * * @throws ValidationException * @throws ApiException * @return \Generator|mixed[] */ public function closeWriteAndReadAll() { $this->closeWrite(); $response = $this->read(); while (!is_null($response)) { yield $response; $response = $this->read(); } } /** * Return the underlying gRPC call object * * @return \Grpc\BidiStreamingCall|mixed */ public function getBidiStreamingCall() { return $this->call; } } ================================================ FILE: lib/Google/vendor/google/gax/src/Call.php ================================================ method = $method; $this->decodeType = $decodeType; $this->message = $message; $this->descriptor = $descriptor; $this->callType = $callType; } /** * @return string */ public function getMethod() { return $this->method; } /** * @return int */ public function getCallType() { return $this->callType; } /** * @return string */ public function getDecodeType() { return $this->decodeType; } /** * @return mixed|Message */ public function getMessage() { return $this->message; } /** * @return array|null */ public function getDescriptor() { return $this->descriptor; } /** * @param mixed|Message $message * @return Call */ public function withMessage($message) { // @phpstan-ignore-next-line return new static( $this->method, $this->decodeType, $message, $this->descriptor, $this->callType ); } } ================================================ FILE: lib/Google/vendor/google/gax/src/ClientOptionsTrait.php ================================================ mergeFromJsonString(file_get_contents($confPath)); $config = new Config($hostName, $apiConfig); return $config; } /** * Get default options. This function should be "overridden" by clients using late static * binding to provide default options to the client. * * @return array * @access private */ private static function getClientDefaults() { return []; } /** * Resolve client options based on the client's default * ({@see ClientOptionsTrait::getClientDefault}) and the default for all * Google APIs. * * 1. Set default client option values * 2. Set default logger (and log user-supplied configuration options) * 3. Set default transport configuration * 4. Call "modifyClientOptions" (for backwards compatibility) * 5. Use "defaultScopes" when custom endpoint is supplied * 6. Load mTLS from the environment if configured * 7. Resolve endpoint based on universe domain template when possible * 8. Load sysvshm grpc config when possible */ private function buildClientOptions(array|ClientOptions $options) { if ($options instanceof ClientOptions) { $options = $options->toArray(); } // Build $defaultOptions starting from top level // variables, then going into deeper nesting, so that // we will not encounter missing keys $defaultOptions = self::getClientDefaults(); $defaultOptions += [ 'disableRetries' => false, 'credentials' => null, 'credentialsConfig' => [], 'transport' => null, 'transportConfig' => [], 'gapicVersion' => self::getGapicVersion($options), 'libName' => null, 'libVersion' => null, 'apiEndpoint' => null, 'clientCertSource' => null, 'universeDomain' => null, 'logger' => null, ]; $supportedTransports = $this->supportedTransports(); foreach ($supportedTransports as $transportName) { if (!array_key_exists($transportName, $defaultOptions['transportConfig'])) { $defaultOptions['transportConfig'][$transportName] = []; } } if (in_array('grpc', $supportedTransports)) { $defaultOptions['transportConfig']['grpc'] = [ 'stubOpts' => ['grpc.service_config_disable_resolution' => 1] ]; } // Keep track of the API Endpoint $apiEndpoint = $options['apiEndpoint'] ?? null; // Keep track of the original user supplied options for logging the configuration $clientSuppliedOptions = $options; // Merge defaults into $options starting from top level // variables, then going into deeper nesting, so that // we will not encounter missing keys $options += $defaultOptions; // If logger is explicitly set to false, logging is disabled if (is_null($options['logger'])) { $options['logger'] = ApplicationDefaultCredentials::getDefaultLogger(); } if ( $options['logger'] !== null && $options['logger'] !== false && !$options['logger'] instanceof LoggerInterface ) { throw new ValidationException( 'The "logger" option in the options array should be PSR-3 LoggerInterface compatible' ); } // Log the user supplied configuration. $this->logConfiguration($options['logger'], $clientSuppliedOptions); if (isset($options['logger'])) { $options['credentialsConfig']['authHttpHandler'] = HttpHandlerFactory::build( logger: $options['logger'] ); } $options['credentialsConfig'] += $defaultOptions['credentialsConfig']; $options['transportConfig'] += $defaultOptions['transportConfig']; // @phpstan-ignore-line if (isset($options['transportConfig']['grpc'])) { $options['transportConfig']['grpc'] += $defaultOptions['transportConfig']['grpc']; $options['transportConfig']['grpc']['stubOpts'] += $defaultOptions['transportConfig']['grpc']['stubOpts']; $options['transportConfig']['grpc']['logger'] = $options['logger'] ?? null; } if (isset($options['transportConfig']['rest'])) { $options['transportConfig']['rest'] += $defaultOptions['transportConfig']['rest']; $options['transportConfig']['rest']['logger'] = $options['logger'] ?? null; } if (isset($options['transportConfig']['grpc-fallback'])) { $options['transportConfig']['grpc-fallback']['logger'] = $options['logger'] ?? null; } // These calls do not apply to "New Surface" clients. if ($this->isBackwardsCompatibilityMode()) { $preModifiedOptions = $options; $this->modifyClientOptions($options); // NOTE: this is required to ensure backwards compatiblity with $options['apiEndpoint'] if ($options['apiEndpoint'] !== $preModifiedOptions['apiEndpoint']) { $apiEndpoint = $options['apiEndpoint']; } // serviceAddress is now deprecated and acts as an alias for apiEndpoint if (isset($options['serviceAddress'])) { $apiEndpoint = $this->pluck('serviceAddress', $options, false); } } else { // Ads is using this method in their new surface clients, so we need to call it. // However, this method is not used anywhere else for the new surface clients // @TODO: Remove this in GAX V2 $this->modifyClientOptions($options); } // If an API endpoint is different form the default, ensure the "audience" does not conflict // with the custom endpoint by setting "user defined" scopes. if ($apiEndpoint && $apiEndpoint != $defaultOptions['apiEndpoint'] && empty($options['credentialsConfig']['scopes']) && !empty($options['credentialsConfig']['defaultScopes']) ) { $options['credentialsConfig']['scopes'] = $options['credentialsConfig']['defaultScopes']; } // mTLS: detect and load the default clientCertSource if the environment variable // "GOOGLE_API_USE_CLIENT_CERTIFICATE" is true, and the cert source is available if (empty($options['clientCertSource']) && CredentialsLoader::shouldLoadClientCertSource()) { if ($defaultCertSource = CredentialsLoader::getDefaultClientCertSource()) { $options['clientCertSource'] = function () use ($defaultCertSource) { $cert = call_user_func($defaultCertSource); // the key and the cert are returned in one string return [$cert, $cert]; }; } } // mTLS: If no apiEndpoint has been supplied by the user, and either // GOOGLE_API_USE_MTLS_ENDPOINT tells us to, or mTLS is available, use the mTLS endpoint. if (is_null($apiEndpoint) && $this->shouldUseMtlsEndpoint($options)) { $apiEndpoint = self::determineMtlsEndpoint($options['apiEndpoint']); } // If the user has not supplied a universe domain, use the environment variable if set. // Otherwise, use the default ("googleapis.com"). $options['universeDomain'] ??= getenv('GOOGLE_CLOUD_UNIVERSE_DOMAIN') ?: GetUniverseDomainInterface::DEFAULT_UNIVERSE_DOMAIN; // mTLS: It is not valid to configure mTLS outside of "googleapis.com" (yet) if (isset($options['clientCertSource']) && $options['universeDomain'] !== GetUniverseDomainInterface::DEFAULT_UNIVERSE_DOMAIN ) { throw new ValidationException( 'mTLS is not supported outside the "googleapis.com" universe' ); } if (is_null($apiEndpoint)) { if (defined('self::SERVICE_ADDRESS_TEMPLATE')) { // Derive the endpoint from the service address template and the universe domain $apiEndpoint = str_replace( 'UNIVERSE_DOMAIN', $options['universeDomain'], self::SERVICE_ADDRESS_TEMPLATE ); } else { // For older clients, the service address template does not exist. Use the default // endpoint instead. $apiEndpoint = $defaultOptions['apiEndpoint']; } } if (extension_loaded('sysvshm') && isset($options['gcpApiConfigPath']) && file_exists($options['gcpApiConfigPath']) && !empty($apiEndpoint) ) { $grpcGcpConfig = self::initGrpcGcpConfig( $apiEndpoint, $options['gcpApiConfigPath'] ); if (!array_key_exists('stubOpts', $options['transportConfig']['grpc'])) { $options['transportConfig']['grpc']['stubOpts'] = []; } $options['transportConfig']['grpc']['stubOpts'] += [ 'grpc_call_invoker' => $grpcGcpConfig->callInvoker() ]; } $options['apiEndpoint'] = $apiEndpoint; return $options; } private function shouldUseMtlsEndpoint(array $options) { $mtlsEndpointEnvVar = getenv('GOOGLE_API_USE_MTLS_ENDPOINT'); if ('always' === $mtlsEndpointEnvVar) { return true; } if ('never' === $mtlsEndpointEnvVar) { return false; } // For all other cases, assume "auto" and return true if clientCertSource exists return !empty($options['clientCertSource']); } private static function determineMtlsEndpoint(string $apiEndpoint) { $parts = explode('.', $apiEndpoint); if (count($parts) < 3) { return $apiEndpoint; // invalid endpoint! } return sprintf('%s.mtls.%s', array_shift($parts), implode('.', $parts)); } /** * @param mixed $credentials * @param array $credentialsConfig * @return CredentialsWrapper * @throws ValidationException */ private function createCredentialsWrapper($credentials, array $credentialsConfig, string $universeDomain) { if (is_null($credentials)) { // If the user has explicitly set the apiKey option, use Api Key credentials return CredentialsWrapper::build($credentialsConfig, $universeDomain); } if (is_string($credentials) || is_array($credentials)) { return CredentialsWrapper::build(['keyFile' => $credentials] + $credentialsConfig, $universeDomain); } if ($credentials instanceof FetchAuthTokenInterface) { $authHttpHandler = $credentialsConfig['authHttpHandler'] ?? null; return new CredentialsWrapper($credentials, $authHttpHandler, $universeDomain); } if ($credentials instanceof CredentialsWrapper) { return $credentials; } throw new ValidationException(sprintf( 'Unexpected value in $auth option, got: %s', print_r($credentials, true) )); } /** * This defaults to all three transports, which One-Platform supports. * Discovery clients should define this function and only return ['rest']. */ private static function supportedTransports() { return ['grpc', 'grpc-fallback', 'rest']; } // Gapic Client Extension Points // The methods below provide extension points that can be used to customize client // functionality. These extension points are currently considered // private and may change at any time. /** * Modify options passed to the client before calling setClientOptions. * * @param array $options * @access private * @internal */ protected function modifyClientOptions(array &$options) { // Do nothing - this method exists to allow option modification by partial veneers. } /** * @internal */ private function isBackwardsCompatibilityMode(): bool { return false; } /** * @param null|false|LoggerInterface $logger * @param string $options */ private function logConfiguration(null|false|LoggerInterface $logger, array $options): void { if (!$logger) { return; } $configurationLog = [ 'timestamp' => date(DATE_RFC3339), 'severity' => strtoupper(LogLevel::DEBUG), 'processId' => getmypid(), 'jsonPayload' => [ 'serviceName' => self::SERVICE_NAME, // @phpstan-ignore-line 'clientConfiguration' => $options, ] ]; $logger->debug(json_encode($configurationLog)); } } ================================================ FILE: lib/Google/vendor/google/gax/src/ClientStream.php ================================================ call = $clientStreamingCall; $this->logger = $logger; } /** * Write request to the server. * * @param mixed $request The request to write */ public function write($request) { // In some cases, $request can be a string if ($this->logger && $request instanceof Message) { $requestEvent = new RpcLogEvent(); $requestEvent->payload = $request->serializeToJsonString(); $requestEvent->processId = (int) getmypid(); $requestEvent->requestId = crc32((string) spl_object_id($this) . getmypid()); $this->logRequest($requestEvent); } $this->call->write($request); } /** * Read the response from the server, completing the streaming call. * * @throws ApiException * @return mixed The response object from the server */ public function readResponse() { list($response, $status) = $this->call->wait(); if ($status->code == Code::OK) { if ($this->logger) { $responseEvent = new RpcLogEvent(); $responseEvent->headers = $status->metadata; $responseEvent->status = $status->code; $responseEvent->processId = (int) getmypid(); $responseEvent->requestId = crc32((string) spl_object_id($this) . getmypid()); if ($response instanceof Message) { $response->serializeToJsonString(); } $this->logResponse($responseEvent); } return $response; } else { throw ApiException::createFromStdClass($status); } } /** * Write all data in $dataArray and read the response from the server, completing the streaming * call. * * @param mixed[] $requests An iterator of request objects to write to the server * @return mixed The response object from the server */ public function writeAllAndReadResponse(array $requests) { foreach ($requests as $request) { $this->write($request); } return $this->readResponse(); } /** * Return the underlying gRPC call object * * @return \Grpc\ClientStreamingCall|mixed */ public function getClientStreamingCall() { return $this->call; } } ================================================ FILE: lib/Google/vendor/google/gax/src/CredentialsWrapper.php ================================================ credentialsFetcher = $credentialsFetcher; $this->authHttpHandler = $authHttpHandler; if (empty($universeDomain)) { throw new ValidationException('The universe domain cannot be empty'); } $this->universeDomain = $universeDomain; } /** * Factory method to create a CredentialsWrapper from an array of options. * * @param array $args { * An array of optional arguments. * * @type string|array $keyFile * Credentials to be used. Accepts either a path to a credentials file, or a decoded * credentials file as a PHP array. If this is not specified, application default * credentials will be used. * @type string[] $scopes * A string array of scopes to use when acquiring credentials. * @type callable $authHttpHandler * A handler used to deliver PSR-7 requests specifically * for authentication. Should match a signature of * `function (RequestInterface $request, array $options) : ResponseInterface`. * @type bool $enableCaching * Enable caching of access tokens. Defaults to true. * @type CacheItemPoolInterface $authCache * A cache for storing access tokens. Defaults to a simple in memory implementation. * @type array $authCacheOptions * Cache configuration options. * @type string $quotaProject * Specifies a user project to bill for access charges associated with the request. * @type string[] $defaultScopes * A string array of default scopes to use when acquiring * credentials. * @type bool $useJwtAccessWithScope * Ensures service account credentials use JWT Access (also known as self-signed * JWTs), even when user-defined scopes are supplied. * } * @param string $universeDomain The expected universe of the credentials. Defaults to * "googleapis.com" * @return CredentialsWrapper * @throws ValidationException */ public static function build( array $args = [], string $universeDomain = GetUniverseDomainInterface::DEFAULT_UNIVERSE_DOMAIN ) { $args += [ 'keyFile' => null, 'scopes' => null, 'authHttpHandler' => null, 'enableCaching' => true, 'authCache' => null, 'authCacheOptions' => [], 'quotaProject' => null, 'defaultScopes' => null, 'useJwtAccessWithScope' => true, ]; $keyFile = $args['keyFile']; if (is_null($keyFile)) { $loader = self::buildApplicationDefaultCredentials( $args['scopes'], $args['authHttpHandler'], $args['authCacheOptions'], $args['authCache'], $args['quotaProject'], $args['defaultScopes'] ); if ($loader instanceof FetchAuthTokenCache) { $loader = $loader->getFetcher(); } } else { if (is_string($keyFile)) { if (!file_exists($keyFile)) { throw new ValidationException("Could not find keyfile: $keyFile"); } $keyFile = json_decode(file_get_contents($keyFile), true); } if (isset($args['quotaProject'])) { $keyFile['quota_project_id'] = $args['quotaProject']; } $loader = CredentialsLoader::makeCredentials( $args['scopes'], $keyFile, $args['defaultScopes'] ); } if ($loader instanceof ServiceAccountCredentials && $args['useJwtAccessWithScope']) { // Ensures the ServiceAccountCredentials uses JWT Access, also known // as self-signed JWTs, even when user-defined scopes are supplied. $loader->useJwtAccessWithScope(); } if ($args['enableCaching']) { $authCache = $args['authCache'] ?: new MemoryCacheItemPool(); $loader = new FetchAuthTokenCache( $loader, $args['authCacheOptions'], $authCache ); } return new CredentialsWrapper($loader, $args['authHttpHandler'], $universeDomain); } /** * @return string|null The quota project associated with the credentials. */ public function getQuotaProject(): ?string { if ($this->credentialsFetcher instanceof GetQuotaProjectInterface) { return $this->credentialsFetcher->getQuotaProject(); } return null; } public function getProjectId(?callable $httpHandler = null): ?string { // Ensure that FetchAuthTokenCache does not throw an exception if ($this->credentialsFetcher instanceof FetchAuthTokenCache && !$this->credentialsFetcher->getFetcher() instanceof ProjectIdProviderInterface) { return null; } if ($this->credentialsFetcher instanceof ProjectIdProviderInterface) { return $this->credentialsFetcher->getProjectId($httpHandler); } return null; } /** * @deprecated * @return string Bearer string containing access token. */ public function getBearerString() { $token = $this->credentialsFetcher->getLastReceivedToken(); if (self::isExpired($token)) { $this->checkUniverseDomain(); $token = $this->credentialsFetcher->fetchAuthToken($this->authHttpHandler); if (!self::isValid($token)) { return ''; } } return empty($token['access_token']) ? '' : 'Bearer ' . $token['access_token']; } /** * @param string $audience optional audience for self-signed JWTs. * @return callable Callable function that returns an authorization header. */ public function getAuthorizationHeaderCallback($audience = null): ?callable { // NOTE: changes to this function should be treated carefully and tested thoroughly. It will // be passed into the gRPC c extension, and changes have the potential to trigger very // difficult-to-diagnose segmentation faults. return function () use ($audience) { $token = $this->credentialsFetcher->getLastReceivedToken(); if (self::isExpired($token)) { $this->checkUniverseDomain(); // Call updateMetadata to take advantage of self-signed JWTs if ($this->credentialsFetcher instanceof UpdateMetadataInterface) { return $this->credentialsFetcher->updateMetadata([], $audience, $this->authHttpHandler); } // In case a custom fetcher is provided (unlikely) which doesn't // implement UpdateMetadataInterface $token = $this->credentialsFetcher->fetchAuthToken($this->authHttpHandler); if (!self::isValid($token)) { return []; } } $tokenString = $token['access_token']; if (!empty($tokenString)) { return ['authorization' => ["Bearer $tokenString"]]; } return []; }; } /** * Verify that the expected universe domain matches the universe domain from the credentials. * * @throws ValidationException if the universe domain does not match. */ public function checkUniverseDomain(): void { if (false === $this->hasCheckedUniverse && $this->shouldCheckUniverseDomain()) { $credentialsUniverse = $this->credentialsFetcher instanceof GetUniverseDomainInterface ? $this->credentialsFetcher->getUniverseDomain() : GetUniverseDomainInterface::DEFAULT_UNIVERSE_DOMAIN; if ($credentialsUniverse !== $this->universeDomain) { throw new ValidationException(sprintf( 'The configured universe domain (%s) does not match the credential universe domain (%s)', $this->universeDomain, $credentialsUniverse )); } $this->hasCheckedUniverse = true; } } /** * Skip universe domain check for Metadata server (e.g. GCE) credentials. * * @return bool */ private function shouldCheckUniverseDomain(): bool { $fetcher = $this->credentialsFetcher instanceof FetchAuthTokenCache ? $this->credentialsFetcher->getFetcher() : $this->credentialsFetcher; if ($fetcher instanceof GCECredentials) { return false; } return true; } /** * @param array $scopes * @param callable $authHttpHandler * @param array $authCacheOptions * @param CacheItemPoolInterface $authCache * @param string $quotaProject * @param array $defaultScopes * @return FetchAuthTokenInterface * @throws ValidationException */ private static function buildApplicationDefaultCredentials( ?array $scopes = null, ?callable $authHttpHandler = null, ?array $authCacheOptions = null, ?CacheItemPoolInterface $authCache = null, $quotaProject = null, ?array $defaultScopes = null ) { try { return ApplicationDefaultCredentials::getCredentials( $scopes, $authHttpHandler, $authCacheOptions, $authCache, $quotaProject, $defaultScopes ); } catch (DomainException $ex) { throw new ValidationException('Could not construct ApplicationDefaultCredentials', $ex->getCode(), $ex); } } /** * @param mixed $token */ private static function isValid($token) { return is_array($token) && array_key_exists('access_token', $token); } /** * @param mixed $token */ private static function isExpired($token) { return !(self::isValid($token) && array_key_exists('expires_at', $token) && $token['expires_at'] > time() + self::$eagerRefreshThresholdSeconds); } } ================================================ FILE: lib/Google/vendor/google/gax/src/FixedSizeCollection.php ================================================ 0. collectionSize: $collectionSize" ); } if ($collectionSize < $initialPage->getPageElementCount()) { $ipc = $initialPage->getPageElementCount(); throw new InvalidArgumentException( 'collectionSize must be greater than or equal to the number of ' . "elements in initialPage. collectionSize: $collectionSize, " . "initialPage size: $ipc" ); } $this->collectionSize = $collectionSize; $this->pageList = FixedSizeCollection::createPageArray($initialPage, $collectionSize); } /** * Returns the number of elements in the collection. This will be * equal to the collectionSize parameter used at construction * unless there are no elements remaining to be retrieved. * * @return int */ public function getCollectionSize() { $size = 0; foreach ($this->pageList as $page) { $size += $page->getPageElementCount(); } return $size; } /** * Returns true if there are more elements that can be retrieved * from the API. * * @return bool */ public function hasNextCollection() { return $this->getLastPage()->hasNextPage(); } /** * Returns a page token that can be passed into the API list * method to retrieve additional elements. * * @return string */ public function getNextPageToken() { return $this->getLastPage()->getNextPageToken(); } /** * Retrieves the next FixedSizeCollection using one or more API calls. * * @return FixedSizeCollection */ public function getNextCollection() { $lastPage = $this->getLastPage(); $nextPage = $lastPage->getNextPage($this->collectionSize); return new FixedSizeCollection($nextPage, $this->collectionSize); } /** * Returns an iterator over the elements of the collection. * * @return Generator */ #[\ReturnTypeWillChange] public function getIterator() { foreach ($this->pageList as $page) { foreach ($page as $element) { yield $element; } } } /** * Returns an iterator over FixedSizeCollections, starting with this * and making API calls as required until all of the elements have * been retrieved. * * @return Generator|FixedSizeCollection[] */ public function iterateCollections() { $currentCollection = $this; yield $this; while ($currentCollection->hasNextCollection()) { $currentCollection = $currentCollection->getNextCollection(); yield $currentCollection; } } private function getLastPage() { $pageList = $this->pageList; // Get last element in array... $lastPage = end($pageList); reset($pageList); return $lastPage; } /** * @param Page $initialPage * @param int $collectionSize * @return Page[] */ private static function createPageArray(Page $initialPage, int $collectionSize) { $pageList = [$initialPage]; $currentPage = $initialPage; $itemCount = $currentPage->getPageElementCount(); while ($itemCount < $collectionSize && $currentPage->hasNextPage()) { $remainingCount = $collectionSize - $itemCount; $currentPage = $currentPage->getNextPage($remainingCount); $rxElementCount = $currentPage->getPageElementCount(); if ($rxElementCount > $remainingCount) { throw new LengthException('API returned a number of elements ' . 'exceeding the specified page size limit. page size: ' . "$remainingCount, elements received: $rxElementCount"); } array_push($pageList, $currentPage); $itemCount += $rxElementCount; } return $pageList; } } ================================================ FILE: lib/Google/vendor/google/gax/src/GPBLabel.php ================================================ $prependMiddlewareCallables */ private array $prependMiddlewareCallables = []; /** @var array $middlewareCallables */ private array $middlewareCallables = []; private array $transportCallMethods = [ Call::UNARY_CALL => 'startUnaryCall', Call::BIDI_STREAMING_CALL => 'startBidiStreamingCall', Call::CLIENT_STREAMING_CALL => 'startClientStreamingCall', Call::SERVER_STREAMING_CALL => 'startServerStreamingCall', ]; private bool $backwardsCompatibilityMode; /** * Add a middleware to the call stack by providing a callable which will be * invoked at the start of each call, and will return an instance of * {@see MiddlewareInterface} when invoked. * * The callable must have the following method signature: * * callable(MiddlewareInterface): MiddlewareInterface * * An implementation may look something like this: * ``` * $client->addMiddleware(function (MiddlewareInterface $handler) { * return new class ($handler) implements MiddlewareInterface { * public function __construct(private MiddlewareInterface $handler) { * } * * public function __invoke(Call $call, array $options) { * // modify call and options (pre-request) * $response = ($this->handler)($call, $options); * // modify the response (post-request) * return $response; * } * }; * }); * ``` * * @param callable $middlewareCallable A callable which returns an instance * of {@see MiddlewareInterface} when invoked with a * MiddlewareInterface instance as its first argument. * @return void */ public function addMiddleware(callable $middlewareCallable): void { $this->middlewareCallables[] = $middlewareCallable; } /** * Prepend a middleware to the call stack by providing a callable which will be * invoked at the end of each call, and will return an instance of * {@see MiddlewareInterface} when invoked. * * The callable must have the following method signature: * * callable(MiddlewareInterface): MiddlewareInterface * * An implementation may look something like this: * ``` * $client->prependMiddleware(function (MiddlewareInterface $handler) { * return new class ($handler) implements MiddlewareInterface { * public function __construct(private MiddlewareInterface $handler) { * } * * public function __invoke(Call $call, array $options) { * // modify call and options (pre-request) * $response = ($this->handler)($call, $options); * // modify the response (post-request) * return $response; * } * }; * }); * ``` * * @param callable $middlewareCallable A callable which returns an instance * of {@see MiddlewareInterface} when invoked with a * MiddlewareInterface instance as its first argument. * @return void */ public function prependMiddleware(callable $middlewareCallable): void { $this->prependMiddlewareCallables[] = $middlewareCallable; } /** * Initiates an orderly shutdown in which preexisting calls continue but new * calls are immediately cancelled. * * @experimental */ public function close() { $this->transport->close(); } /** * Get the transport for the client. This method is protected to support * use by customized clients. * * @access private * @return TransportInterface */ protected function getTransport() { return $this->transport; } /** * Get the credentials for the client. This method is protected to support * use by customized clients. * * @access private * @return CredentialsWrapper */ protected function getCredentialsWrapper() { return $this->credentialsWrapper; } /** * Configures the GAPIC client based on an array of options. * * @param array $options { * An array of required and optional arguments. * * @type string $apiEndpoint * The address of the API remote host, for example "example.googleapis.com. May also * include the port, for example "example.googleapis.com:443" * @type bool $disableRetries * Determines whether or not retries defined by the client configuration should be * disabled. Defaults to `false`. * @type string|array $clientConfig * Client method configuration, including retry settings. This option can be either a * path to a JSON file, or a PHP array containing the decoded JSON data. * By default this settings points to the default client config file, which is provided * in the resources folder. * @type string|array|FetchAuthTokenInterface|CredentialsWrapper $credentials * The credentials to be used by the client to authorize API calls. This option * accepts either a path to a credentials file, or a decoded credentials file as a * PHP array. * *Advanced usage*: In addition, this option can also accept a pre-constructed * \Google\Auth\FetchAuthTokenInterface object or \Google\ApiCore\CredentialsWrapper * object. Note that when one of these objects are provided, any settings in * $authConfig will be ignored. * @type array $credentialsConfig * Options used to configure credentials, including auth token caching, for the client. * For a full list of supporting configuration options, see * \Google\ApiCore\CredentialsWrapper::build. * @type string|TransportInterface $transport * The transport used for executing network requests. May be either the string `rest`, * `grpc`, or 'grpc-fallback'. Defaults to `grpc` if gRPC support is detected on the system. * *Advanced usage*: Additionally, it is possible to pass in an already instantiated * TransportInterface object. Note that when this objects is provided, any settings in * $transportConfig, and any `$apiEndpoint` setting, will be ignored. * @type array $transportConfig * Configuration options that will be used to construct the transport. Options for * each supported transport type should be passed in a key for that transport. For * example: * $transportConfig = [ * 'grpc' => [...], * 'rest' => [...], * 'grpc-fallback' => [...], * ]; * See the GrpcTransport::build and RestTransport::build * methods for the supported options. * @type string $versionFile * The path to a file which contains the current version of the client. * @type string $descriptorsConfigPath * The path to a descriptor configuration file. * @type string $serviceName * The name of the service. * @type string $libName * The name of the client application. * @type string $libVersion * The version of the client application. * @type string $gapicVersion * The code generator version of the GAPIC library. * @type callable $clientCertSource * A callable which returns the client cert as a string. * } * @throws ValidationException */ private function setClientOptions(array $options) { // serviceAddress is now deprecated and acts as an alias for apiEndpoint if (isset($options['serviceAddress'])) { $options['apiEndpoint'] = $this->pluck('serviceAddress', $options, false); } $this->validateNotNull($options, [ 'apiEndpoint', 'serviceName', 'descriptorsConfigPath', 'clientConfig', 'disableRetries', 'credentialsConfig', 'transportConfig', ]); $this->traitValidate($options, [ 'credentials', 'transport', 'gapicVersion', 'libName', 'libVersion', ]); // "hasEmulator" is not a supported Client Option, but is used // internally to determine if the client is running in emulator mode. // Therefore, we need to remove it from the $options array before // creating the ClientOptions. $hasEmulator = $this->pluck('hasEmulator', $options, false) ?? false; if ($this->isBackwardsCompatibilityMode()) { if (is_string($options['clientConfig'])) { // perform validation for V1 surfaces which is done in the // ClientOptions class for v2 surfaces. $options['clientConfig'] = json_decode( file_get_contents($options['clientConfig']), true ); self::validateFileExists($options['descriptorsConfigPath']); } } else { // cast to ClientOptions for new surfaces only $options = new ClientOptions($options); } $this->serviceName = $options['serviceName']; $this->retrySettings = RetrySettings::load( $this->serviceName, $options['clientConfig'], $options['disableRetries'] ); $headerInfo = [ 'libName' => $options['libName'], 'libVersion' => $options['libVersion'], 'gapicVersion' => $options['gapicVersion'], ]; // Edge case: If the client has the gRPC extension installed, but is // a REST-only library, then the grpcVersion header should not be set. if ($this->transport instanceof GrpcTransport) { $headerInfo['grpcVersion'] = phpversion('grpc'); } elseif ($this->transport instanceof RestTransport || $this->transport instanceof GrpcFallbackTransport) { $headerInfo['restVersion'] = Version::getApiCoreVersion(); } $this->agentHeader = AgentHeader::buildAgentHeader($headerInfo); // Set "client_library_name" depending on client library surface being used $userAgentHeader = sprintf( 'gcloud-php-%s/%s', $this->isBackwardsCompatibilityMode() ? 'legacy' : 'new', $options['gapicVersion'] ); $this->agentHeader['User-Agent'] = [$userAgentHeader]; self::validateFileExists($options['descriptorsConfigPath']); $descriptors = require($options['descriptorsConfigPath']); $this->descriptors = $descriptors['interfaces'][$this->serviceName]; if (isset($options['apiKey'], $options['credentials'])) { throw new ValidationException( 'API Keys and Credentials are mutually exclusive authentication methods and cannot be used together.' ); } // Set the credentialsWrapper if (isset($options['apiKey'])) { $this->credentialsWrapper = new ApiKeyHeaderCredentials( $options['apiKey'], $options['credentialsConfig']['quotaProject'] ?? null ); } else { $this->credentialsWrapper = $this->createCredentialsWrapper( $options['credentials'], $options['credentialsConfig'], $options['universeDomain'] ); } $transport = $options['transport'] ?: self::defaultTransport(); $this->transport = $transport instanceof TransportInterface ? $transport : $this->createTransport( $options['apiEndpoint'], $transport, $options['transportConfig'], $options['clientCertSource'], $hasEmulator ); } /** * @param string $apiEndpoint * @param string $transport * @param TransportOptions|array $transportConfig * @param callable $clientCertSource * @param bool $hasEmulator * @return TransportInterface * @throws ValidationException */ private function createTransport( string $apiEndpoint, $transport, $transportConfig, ?callable $clientCertSource = null, bool $hasEmulator = false ) { if (!is_string($transport)) { throw new ValidationException( "'transport' must be a string, instead got:" . print_r($transport, true) ); } $supportedTransports = self::supportedTransports(); if (!in_array($transport, $supportedTransports)) { throw new ValidationException(sprintf( 'Unexpected transport option "%s". Supported transports: %s', $transport, implode(', ', $supportedTransports) )); } $configForSpecifiedTransport = $transportConfig[$transport] ?? []; if (is_array($configForSpecifiedTransport)) { $configForSpecifiedTransport['clientCertSource'] = $clientCertSource; } else { $configForSpecifiedTransport->setClientCertSource($clientCertSource); $configForSpecifiedTransport = $configForSpecifiedTransport->toArray(); } switch ($transport) { case 'grpc': // Setting the user agent for gRPC requires special handling if (isset($this->agentHeader['User-Agent'])) { if ($configForSpecifiedTransport['stubOpts']['grpc.primary_user_agent'] ??= '') { $configForSpecifiedTransport['stubOpts']['grpc.primary_user_agent'] .= ' '; } $configForSpecifiedTransport['stubOpts']['grpc.primary_user_agent'] .= $this->agentHeader['User-Agent'][0]; } return GrpcTransport::build($apiEndpoint, $configForSpecifiedTransport); case 'grpc-fallback': return GrpcFallbackTransport::build($apiEndpoint, $configForSpecifiedTransport); case 'rest': if (!isset($configForSpecifiedTransport['restClientConfigPath'])) { throw new ValidationException( "The 'restClientConfigPath' config is required for 'rest' transport." ); } $restConfigPath = $configForSpecifiedTransport['restClientConfigPath']; $configForSpecifiedTransport['hasEmulator'] = $hasEmulator; return RestTransport::build($apiEndpoint, $restConfigPath, $configForSpecifiedTransport); default: throw new ValidationException( "Unexpected 'transport' option: $transport. " . "Supported values: ['grpc', 'rest', 'grpc-fallback']" ); } } /** * @param array $options * @return OperationsClient */ private function createOperationsClient(array $options) { $this->pluckArray([ 'serviceName', 'clientConfig', 'descriptorsConfigPath', ], $options); // User-supplied operations client if ($operationsClient = $this->pluck('operationsClient', $options, false)) { return $operationsClient; } // operationsClientClass option $operationsClientClass = $this->pluck('operationsClientClass', $options, false) ?: OperationsCLient::class; return new $operationsClientClass($options); } /** * @return string */ private static function defaultTransport() { return self::getGrpcDependencyStatus() ? 'grpc' : 'rest'; } private function validateCallConfig(string $methodName) { // Ensure a method descriptor exists for the target method. if (!isset($this->descriptors[$methodName])) { throw new ValidationException("Requested method '$methodName' does not exist in descriptor configuration."); } $methodDescriptors = $this->descriptors[$methodName]; // Ensure required descriptor configuration exists. if (!isset($methodDescriptors['callType'])) { throw new ValidationException("Requested method '$methodName' does not have a callType " . 'in descriptor configuration.'); } $callType = $methodDescriptors['callType']; // Validate various callType specific configurations. if ($callType == Call::LONGRUNNING_CALL) { if (!isset($methodDescriptors['longRunning'])) { throw new ValidationException("Requested method '$methodName' does not have a longRunning config " . 'in descriptor configuration.'); } // @TODO: check if the client implements `OperationsClientInterface` instead if (!method_exists($this, 'getOperationsClient')) { throw new ValidationException('Client missing required getOperationsClient ' . "for longrunning call '$methodName'"); } } elseif ($callType == Call::PAGINATED_CALL) { if (!isset($methodDescriptors['pageStreaming'])) { throw new ValidationException("Requested method '$methodName' with callType PAGINATED_CALL does not " . 'have a pageStreaming in descriptor configuration.'); } } // LRO are either Standard LRO response type or custom, which are handled by // startOperationCall, so no need to validate responseType for those callType. if ($callType != Call::LONGRUNNING_CALL) { if (!isset($methodDescriptors['responseType'])) { throw new ValidationException("Requested method '$methodName' does not have a responseType " . 'in descriptor configuration.'); } } return $methodDescriptors; } /** * @param string $methodName * @param Message $request * @param array $optionalArgs { * Call Options * * @type array $headers [optional] key-value array containing headers * @type int $timeoutMillis [optional] the timeout in milliseconds for the call * @type array $transportOptions [optional] transport-specific call options * @type RetrySettings|array $retrySettings [optional] A retry settings override for the call. * } * * @experimental * * @return PromiseInterface */ private function startAsyncCall( string $methodName, Message $request, array $optionalArgs = [] ) { // Convert method name to the UpperCamelCase of RPC names from lowerCamelCase of GAPIC method names // in order to find the method in the descriptor config. $methodName = ucfirst($methodName); $methodDescriptors = $this->validateCallConfig($methodName); $callType = $methodDescriptors['callType']; switch ($callType) { case Call::PAGINATED_CALL: return $this->getPagedListResponseAsync( $methodName, $optionalArgs, $methodDescriptors['responseType'], $request, $methodDescriptors['interfaceOverride'] ?? $this->serviceName ); case Call::SERVER_STREAMING_CALL: case Call::CLIENT_STREAMING_CALL: case Call::BIDI_STREAMING_CALL: throw new ValidationException("Call type '$callType' of requested method " . "'$methodName' is not supported for async execution."); } return $this->startApiCall($methodName, $request, $optionalArgs); } /** * @param string $methodName * @param Message $request * @param array $optionalArgs { * Call Options * * @type array $headers [optional] key-value array containing headers * @type int $timeoutMillis [optional] the timeout in milliseconds for the call * @type array $transportOptions [optional] transport-specific call options * @type RetrySettings|array $retrySettings [optional] A retry settings * override for the call. * } * * @experimental * * @return PromiseInterface|PagedListResponse|BidiStream|ClientStream|ServerStream */ private function startApiCall( string $methodName, ?Message $request = null, array $optionalArgs = [] ) { $methodDescriptors = $this->validateCallConfig($methodName); $callType = $methodDescriptors['callType']; // Prepare request-based headers, merge with user-provided headers, // which take precedence. $headerParams = $methodDescriptors['headerParams'] ?? []; $requestHeaders = $this->buildRequestParamsHeader($headerParams, $request); $optionalArgs['headers'] = array_merge($requestHeaders, $optionalArgs['headers'] ?? []); // Default the interface name, if not set, to the client's protobuf service name. $interfaceName = $methodDescriptors['interfaceOverride'] ?? $this->serviceName; // Handle call based on call type configured in the method descriptor config. if ($callType == Call::LONGRUNNING_CALL) { return $this->startOperationsCall( $methodName, $optionalArgs, $request, $this->getOperationsClient(), $interfaceName, // Custom operations will define their own operation response type, whereas standard // LRO defaults to the same type. $methodDescriptors['responseType'] ?? null ); } // Fully-qualified name of the response message PHP class. $decodeType = $methodDescriptors['responseType']; if ($callType == Call::PAGINATED_CALL) { return $this->getPagedListResponse($methodName, $optionalArgs, $decodeType, $request, $interfaceName); } // Unary, and all Streaming types handled by startCall. return $this->startCall($methodName, $decodeType, $optionalArgs, $request, $callType, $interfaceName); } /** * @param string $methodName * @param string $decodeType * @param array $optionalArgs { * Call Options * * @type array $headers [optional] key-value array containing headers * @type int $timeoutMillis [optional] the timeout in milliseconds for the call * @type array $transportOptions [optional] transport-specific call options * @type RetrySettings|array $retrySettings [optional] A retry settings * override for the call. * } * @param Message $request * @param int $callType * @param string $interfaceName * * @return PromiseInterface|BidiStream|ClientStream|ServerStream */ private function startCall( string $methodName, string $decodeType, array $optionalArgs = [], ?Message $request = null, int $callType = Call::UNARY_CALL, ?string $interfaceName = null ) { $optionalArgs = $this->configureCallOptions($optionalArgs); $callStack = $this->createCallStack( $this->configureCallConstructionOptions($methodName, $optionalArgs) ); $descriptor = $this->descriptors[$methodName]['grpcStreaming'] ?? null; $call = new Call( $this->buildMethod($interfaceName, $methodName), $decodeType, $request, $descriptor, $callType ); switch ($callType) { case Call::UNARY_CALL: $this->modifyUnaryCallable($callStack); break; case Call::BIDI_STREAMING_CALL: case Call::CLIENT_STREAMING_CALL: case Call::SERVER_STREAMING_CALL: $this->modifyStreamingCallable($callStack); break; } return $callStack($call, $optionalArgs + array_filter([ 'audience' => self::getDefaultAudience() ])); } /** * @param array $callConstructionOptions { * Call Construction Options * * @type RetrySettings $retrySettings [optional] A retry settings override * For the call. * @type array $autoPopulationSettings Settings for * auto population of particular request fields if unset. * } * * @return callable */ private function createCallStack(array $callConstructionOptions) { $fixedHeaders = $this->agentHeader; if ($quotaProject = $this->credentialsWrapper->getQuotaProject()) { $fixedHeaders += [ 'X-Goog-User-Project' => [$quotaProject] ]; } if (isset($this->apiVersion)) { $fixedHeaders += [ 'X-Goog-Api-Version' => [$this->apiVersion] ]; } $callStack = new TransportCallMiddleware($this->transport, $this->transportCallMethods); foreach ($this->prependMiddlewareCallables as $fn) { /** @var MiddlewareInterface $callStack */ $callStack = $fn($callStack); } $callStack = new CredentialsWrapperMiddleware($callStack, $this->credentialsWrapper); $callStack = new FixedHeaderMiddleware($callStack, $fixedHeaders, true); $callStack = new RetryMiddleware($callStack, $callConstructionOptions['retrySettings']); $callStack = new RequestAutoPopulationMiddleware( $callStack, $callConstructionOptions['autoPopulationSettings'], ); $callStack = new OptionsFilterMiddleware($callStack, [ 'headers', 'timeoutMillis', 'transportOptions', 'metadataCallback', 'audience', 'metadataReturnType' ]); foreach (\array_reverse($this->middlewareCallables) as $fn) { /** @var MiddlewareInterface $callStack */ $callStack = $fn($callStack); } return $callStack; } /** * @param string $methodName * @param array $optionalArgs { * Optional arguments * * @type RetrySettings|array $retrySettings [optional] A retry settings * override for the call. * } * * @return array */ private function configureCallConstructionOptions(string $methodName, array $optionalArgs) { $retrySettings = $this->retrySettings[$methodName]; $autoPopulatedFields = $this->descriptors[$methodName]['autoPopulatedFields'] ?? []; // Allow for retry settings to be changed at call time if (isset($optionalArgs['retrySettings'])) { if ($optionalArgs['retrySettings'] instanceof RetrySettings) { $retrySettings = $optionalArgs['retrySettings']; } else { $retrySettings = $retrySettings->with( $optionalArgs['retrySettings'] ); } } return [ 'retrySettings' => $retrySettings, 'autoPopulationSettings' => $autoPopulatedFields, ]; } /** * @return array */ private function configureCallOptions(array $optionalArgs): array { if ($this->isBackwardsCompatibilityMode()) { return $optionalArgs; } // cast to CallOptions for new surfaces only return (new CallOptions($optionalArgs))->toArray(); } /** * @param string $methodName * @param array $optionalArgs { * Call Options * * @type array $headers [optional] key-value array containing headers * @type int $timeoutMillis [optional] the timeout in milliseconds for the call * @type array $transportOptions [optional] transport-specific call options * } * @param Message $request * @param OperationsClient|object $client * @param string $interfaceName * @param string $operationClass If provided, will be used instead of the default * operation response class of {@see \Google\LongRunning\Operation}. * * @return PromiseInterface */ private function startOperationsCall( string $methodName, array $optionalArgs, Message $request, $client, ?string $interfaceName = null, ?string $operationClass = null ) { $optionalArgs = $this->configureCallOptions($optionalArgs); $callStack = $this->createCallStack( $this->configureCallConstructionOptions($methodName, $optionalArgs) ); $descriptor = $this->descriptors[$methodName]['longRunning']; $metadataReturnType = null; // Call the methods supplied in "additionalArgumentMethods" on the request Message object // to build the "additionalOperationArguments" option for the operation response. if (isset($descriptor['additionalArgumentMethods'])) { $additionalArgs = []; foreach ($descriptor['additionalArgumentMethods'] as $additionalArgsMethodName) { $additionalArgs[] = $request->$additionalArgsMethodName(); } $descriptor['additionalOperationArguments'] = $additionalArgs; unset($descriptor['additionalArgumentMethods']); } if (isset($descriptor['metadataReturnType'])) { $metadataReturnType = $descriptor['metadataReturnType']; } $callStack = new OperationsMiddleware($callStack, $client, $descriptor); $call = new Call( $this->buildMethod($interfaceName, $methodName), $operationClass ?: Operation::class, $request, [], Call::UNARY_CALL ); $this->modifyUnaryCallable($callStack); return $callStack($call, $optionalArgs + array_filter([ 'metadataReturnType' => $metadataReturnType, 'audience' => self::getDefaultAudience() ])); } /** * @param string $methodName * @param array $optionalArgs * @param string $decodeType * @param Message $request * @param string $interfaceName * * @return PagedListResponse */ private function getPagedListResponse( string $methodName, array $optionalArgs, string $decodeType, Message $request, ?string $interfaceName = null ) { return $this->getPagedListResponseAsync( $methodName, $optionalArgs, $decodeType, $request, $interfaceName )->wait(); } /** * @param string $methodName * @param array $optionalArgs * @param string $decodeType * @param Message $request * @param string $interfaceName * * @return PromiseInterface */ private function getPagedListResponseAsync( string $methodName, array $optionalArgs, string $decodeType, Message $request, ?string $interfaceName = null ) { $optionalArgs = $this->configureCallOptions($optionalArgs); $callStack = $this->createCallStack( $this->configureCallConstructionOptions($methodName, $optionalArgs) ); $descriptor = new PageStreamingDescriptor( $this->descriptors[$methodName]['pageStreaming'] ); $callStack = new PagedMiddleware($callStack, $descriptor); $call = new Call( $this->buildMethod($interfaceName, $methodName), $decodeType, $request, [], Call::UNARY_CALL ); $this->modifyUnaryCallable($callStack); return $callStack($call, $optionalArgs + array_filter([ 'audience' => self::getDefaultAudience() ])); } /** * @param string $interfaceName * @param string $methodName * * @return string */ private function buildMethod(?string $interfaceName = null, ?string $methodName = null) { return sprintf( '%s/%s', $interfaceName ?: $this->serviceName, $methodName ); } /** * @param array $headerParams * @param Message|null $request * * @return array */ private function buildRequestParamsHeader(array $headerParams, ?Message $request = null) { $headers = []; // No request message means no request-based headers. if (!$request) { return $headers; } foreach ($headerParams as $headerParam) { $msg = $request; $value = null; foreach ($headerParam['fieldAccessors'] as $accessor) { $value = $msg->$accessor(); // In case the field in question is nested in another message, // skip the header param when the nested message field is unset. $msg = $value; if (is_null($msg)) { break; } } $keyName = $headerParam['keyName']; // If there are value pattern matchers configured and the target // field was set, evaluate the matchers in the order that they were // annotated in with last one matching wins. $original = $value; $matchers = isset($headerParam['matchers']) && !is_null($value) ? $headerParam['matchers'] : []; foreach ($matchers as $matcher) { $matches = []; if (preg_match($matcher, $original, $matches)) { $value = $matches[$keyName]; } } // If there are no matches or the target field was unset, skip this // header param. if (!$value) { continue; } $headers[$keyName] = $value; } $requestParams = new RequestParamsHeaderDescriptor($headers); return $requestParams->getHeader(); } /** * The SERVICE_ADDRESS constant is set by GAPIC clients */ private static function getDefaultAudience() { if (!defined('self::SERVICE_ADDRESS')) { return null; } return 'https://' . self::SERVICE_ADDRESS . '/'; // @phpstan-ignore-line } /** * Modify the unary callable. * * @param callable $callable * @access private */ protected function modifyUnaryCallable(callable &$callable) { // Do nothing - this method exists to allow callable modification by partial veneers. } /** * Modify the streaming callable. * * @param callable $callable * @access private */ protected function modifyStreamingCallable(callable &$callable) { // Do nothing - this method exists to allow callable modification by partial veneers. } /** * @internal */ private function isBackwardsCompatibilityMode(): bool { return $this->backwardsCompatibilityMode ?? $this->backwardsCompatibilityMode = substr(__CLASS__, -11) === 'GapicClient'; } } ================================================ FILE: lib/Google/vendor/google/gax/src/GrpcSupportTrait.php ================================================ baseUri, $path )); if ($queryParams) { $uri = $this->buildUriWithQuery( $uri, $queryParams ); } return $uri; } } ================================================ FILE: lib/Google/vendor/google/gax/src/Middleware/CredentialsWrapperMiddleware.php ================================================ nextHandler = $nextHandler; $this->credentialsWrapper = $credentialsWrapper; } public function __invoke(Call $call, array $options) { $next = $this->nextHandler; return $next( $call, $options + ['credentialsWrapper' => $this->credentialsWrapper] ); } } ================================================ FILE: lib/Google/vendor/google/gax/src/Middleware/FixedHeaderMiddleware.php ================================================ nextHandler = $nextHandler; $this->headers = $headers; $this->overrideUserHeaders = $overrideUserHeaders; } public function __invoke(Call $call, array $options) { $userHeaders = $options['headers'] ?? []; if ($this->overrideUserHeaders) { $options['headers'] = $this->headers + $userHeaders; } else { $options['headers'] = $userHeaders + $this->headers; } $next = $this->nextHandler; return $next( $call, $options ); } } ================================================ FILE: lib/Google/vendor/google/gax/src/Middleware/MiddlewareInterface.php ================================================ handler = $handler; * } * public function __invoke(Call $call, array $options) * { * echo "Logging info about the call: " . $call->getMethod(); * return ($this->handler)($call, $options); * } * } * ``` * * Next, add the middleware to any class implementing `GapicClientTrait` by passing in a * callable which returns the new middleware: * * ``` * $client = new ExampleGoogleApiServiceClient(); * $client->addMiddleware(function (MiddlewareInterface $handler) { * return new MyTestMiddleware($handler); * }); * ``` */ interface MiddlewareInterface { /** * Modify or observe the API call request and response. * The returned value must include the result of the next MiddlewareInterface invocation in the * chain. * * @param Call $call * @param array $options * @return PromiseInterface|ClientStream|ServerStream|BidiStream */ public function __invoke(Call $call, array $options); } ================================================ FILE: lib/Google/vendor/google/gax/src/Middleware/OperationsMiddleware.php ================================================ nextHandler = $nextHandler; $this->operationsClient = $operationsClient; $this->descriptor = $descriptor; } public function __invoke(Call $call, array $options) { $next = $this->nextHandler; return $next( $call, $options )->then(function (Message $response) { $options = $this->descriptor + [ 'lastProtoResponse' => $response ]; $operationNameMethod = $options['operationNameMethod'] ?? 'getName'; $operationName = call_user_func([$response, $operationNameMethod]); return new OperationResponse($operationName, $this->operationsClient, $options); }); } } ================================================ FILE: lib/Google/vendor/google/gax/src/Middleware/OptionsFilterMiddleware.php ================================================ nextHandler = $nextHandler; $this->permittedOptions = $permittedOptions; } public function __invoke(Call $call, array $options) { $next = $this->nextHandler; $filteredOptions = $this->pluckArray($this->permittedOptions, $options); return $next( $call, $filteredOptions ); } } ================================================ FILE: lib/Google/vendor/google/gax/src/Middleware/PagedMiddleware.php ================================================ nextHandler = $nextHandler; $this->descriptor = $descriptor; } public function __invoke(Call $call, array $options) { $next = $this->nextHandler; $descriptor = $this->descriptor; return $next($call, $options)->then( function (Message $response) use ($call, $next, $options, $descriptor) { $page = new Page( $call, $options, $next, $descriptor, $response ); return new PagedListResponse($page); } ); } } ================================================ FILE: lib/Google/vendor/google/gax/src/Middleware/RequestAutoPopulationMiddleware.php ================================================ */ private $autoPopulationSettings; public function __construct( callable $nextHandler, array $autoPopulationSettings ) { $this->nextHandler = $nextHandler; $this->autoPopulationSettings = $autoPopulationSettings; } /** * @param Call $call * @param array $options * * @return PromiseInterface */ public function __invoke(Call $call, array $options) { $next = $this->nextHandler; if (empty($this->autoPopulationSettings)) { return $next($call, $options); } $request = $call->getMessage(); foreach ($this->autoPopulationSettings as $fieldName => $valueType) { $getFieldName = 'get' . ucwords($fieldName); // We use a getter instead of a hazzer here because there's no need to // differentiate between isset and an empty default value. Even if a // field is explicitly set to an empty string, we want to autopopulate it. if (empty($request->$getFieldName())) { $setFieldName = 'set' . ucwords($fieldName); switch ($valueType) { case Format::UUID4: $request->$setFieldName(Uuid::uuid4()->toString()); break; default: throw new \UnexpectedValueException(sprintf( 'Value type %s::%s not supported for auto population of the field %s', Format::class, Format::name($valueType), $fieldName )); } } } $call = $call->withMessage($request); return $next( $call, $options ); } } ================================================ FILE: lib/Google/vendor/google/gax/src/Middleware/ResponseMetadataMiddleware.php ================================================ nextHandler = $nextHandler; } public function __invoke(Call $call, array $options) { $metadataReceiver = new Promise(); $options['metadataCallback'] = function ($metadata) use ($metadataReceiver) { $metadataReceiver->resolve($metadata); }; $next = $this->nextHandler; return $next($call, $options)->then( function ($response) use ($metadataReceiver) { if ($metadataReceiver->getState() === PromiseInterface::FULFILLED) { return [$response, $metadataReceiver->wait()]; } else { return [$response, []]; } } ); } } ================================================ FILE: lib/Google/vendor/google/gax/src/Middleware/RetryMiddleware.php ================================================ nextHandler = $nextHandler; $this->retrySettings = $retrySettings; $this->deadlineMs = $deadlineMs; $this->retryAttempts = $retryAttempts; } /** * @param Call $call * @param array $options * * @return PromiseInterface */ public function __invoke(Call $call, array $options) { $nextHandler = $this->nextHandler; if (!isset($options['timeoutMillis'])) { // default to "noRetriesRpcTimeoutMillis" when retries are disabled, otherwise use "initialRpcTimeoutMillis" if (!$this->retrySettings->retriesEnabled() && $this->retrySettings->getNoRetriesRpcTimeoutMillis() > 0) { $options['timeoutMillis'] = $this->retrySettings->getNoRetriesRpcTimeoutMillis(); } elseif ($this->retrySettings->getInitialRpcTimeoutMillis() > 0) { $options['timeoutMillis'] = $this->retrySettings->getInitialRpcTimeoutMillis(); } } // Setting the retry attempt for logging if ($this->retryAttempts > 0) { $options['retryAttempt'] = $this->retryAttempts; } // Call the handler immediately if retry settings are disabled. if (!$this->retrySettings->retriesEnabled()) { return $nextHandler($call, $options); } return $nextHandler($call, $options)->then(null, function ($e) use ($call, $options) { $retryFunction = $this->getRetryFunction(); // If the number of retries has surpassed the max allowed retries // then throw the exception as we normally would. // If the maxRetries is set to 0, then we don't check this condition. if (0 !== $this->retrySettings->getMaxRetries() && $this->retryAttempts >= $this->retrySettings->getMaxRetries() ) { throw $e; } // If the retry function returns false then throw the // exception as we normally would. if (!$retryFunction($e, $options)) { throw $e; } // Retry function returned true, so we attempt another retry return $this->retry($call, $options, $e->getStatus()); }); } /** * @param Call $call * @param array $options * @param string $status * * @return PromiseInterface * @throws ApiException */ private function retry(Call $call, array $options, string $status) { $delayMult = $this->retrySettings->getRetryDelayMultiplier(); $maxDelayMs = $this->retrySettings->getMaxRetryDelayMillis(); $timeoutMult = $this->retrySettings->getRpcTimeoutMultiplier(); $maxTimeoutMs = $this->retrySettings->getMaxRpcTimeoutMillis(); $totalTimeoutMs = $this->retrySettings->getTotalTimeoutMillis(); $delayMs = $this->retrySettings->getInitialRetryDelayMillis(); $timeoutMs = $options['timeoutMillis']; $currentTimeMs = $this->getCurrentTimeMs(); $deadlineMs = $this->deadlineMs ?: $currentTimeMs + $totalTimeoutMs; if ($currentTimeMs >= $deadlineMs) { throw new ApiException( 'Retry total timeout exceeded.', \Google\Rpc\Code::DEADLINE_EXCEEDED, ApiStatus::DEADLINE_EXCEEDED ); } $delayMs = min($delayMs * $delayMult, $maxDelayMs); $timeoutMs = (int) min( $timeoutMs * $timeoutMult, $maxTimeoutMs, $deadlineMs - $this->getCurrentTimeMs() ); $nextHandler = new RetryMiddleware( $this->nextHandler, $this->retrySettings->with([ 'initialRetryDelayMillis' => $delayMs, ]), $deadlineMs, $this->retryAttempts + 1 ); // Set the timeout for the call $options['timeoutMillis'] = $timeoutMs; return $nextHandler( $call, $options ); } protected function getCurrentTimeMs() { return microtime(true) * 1000.0; } /** * This is the default retry behaviour. */ private function getRetryFunction() { return $this->retrySettings->getRetryFunction() ?? function (\Throwable $e, array $options): bool { // This is the default retry behaviour, i.e. we don't retry an ApiException // and for other exception types, we only retry when the error code is in // the list of retryable error codes. if (!$e instanceof ApiException) { return false; } if (!in_array($e->getStatus(), $this->retrySettings->getRetryableCodes())) { return false; } return true; }; } } ================================================ FILE: lib/Google/vendor/google/gax/src/Middleware/TransportCallMiddleware.php ================================================ transportCallMethods[$call->getCallType()]; return $this->transport->$startCallMethod($call, $options); } } ================================================ FILE: lib/Google/vendor/google/gax/src/OperationResponse.php ================================================ self::DEFAULT_POLLING_INTERVAL, 'pollDelayMultiplier' => self::DEFAULT_POLLING_MULTIPLIER, 'maxPollDelayMillis' => self::DEFAULT_MAX_POLLING_INTERVAL, 'totalPollTimeoutMillis' => self::DEFAULT_MAX_POLLING_DURATION, ]; private ?object $lastProtoResponse; private bool $deleted = false; private array $additionalArgs; private string $getOperationMethod; private ?string $cancelOperationMethod; private ?string $deleteOperationMethod; private string $getOperationRequest; private ?string $cancelOperationRequest; private ?string $deleteOperationRequest; private string $operationStatusMethod; /** @var mixed */ private $operationStatusDoneValue; private ?string $operationErrorCodeMethod; private ?string $operationErrorMessageMethod; /** * OperationResponse constructor. * * @param string $operationName * @param object $operationsClient * @param array $options { * Optional. Options for configuring the operation response object. * * @type string $operationReturnType The return type of the longrunning operation. * @type string $metadataReturnType The type of the metadata returned in the operation response. * @type int $initialPollDelayMillis The initial polling interval to use, in milliseconds. * @type int $pollDelayMultiplier Multiplier applied to the polling interval on each retry. * @type int $maxPollDelayMillis The maximum polling interval to use, in milliseconds. * @type int $totalPollTimeoutMillis The maximum amount of time to continue polling. * @type object $lastProtoResponse A response already received from the server. * @type string $getOperationMethod The method on $operationsClient to get the operation. * @type string $cancelOperationMethod The method on $operationsClient to cancel the operation. * @type string $deleteOperationMethod The method on $operationsClient to delete the operation. * @type string $operationStatusMethod The method on the operation to get the status. * @type string $operationStatusDoneValue The method on the operation to determine if the status is done. * @type array $additionalOperationArguments Additional arguments to pass to $operationsClient methods. * @type string $operationErrorCodeMethod The method on the operation to get the error code * @type string $operationErrorMessageMethod The method on the operation to get the error status * } */ public function __construct(string $operationName, $operationsClient, array $options = []) { $this->operationName = $operationName; $this->operationsClient = $operationsClient; $options += [ 'operationReturnType' => null, 'metadataReturnType' => null, 'lastProtoResponse' => null, 'getOperationMethod' => 'getOperation', 'cancelOperationMethod' => 'cancelOperation', 'deleteOperationMethod' => 'deleteOperation', 'operationStatusMethod' => 'getDone', 'operationStatusDoneValue' => true, 'additionalOperationArguments' => [], 'operationErrorCodeMethod' => null, 'operationErrorMessageMethod' => null, 'getOperationRequest' => GetOperationRequest::class, 'cancelOperationRequest' => CancelOperationRequest::class, 'deleteOperationRequest' => DeleteOperationRequest::class, ]; $this->operationReturnType = $options['operationReturnType']; $this->metadataReturnType = $options['metadataReturnType']; $this->lastProtoResponse = $options['lastProtoResponse']; $this->getOperationMethod = $options['getOperationMethod']; $this->cancelOperationMethod = $options['cancelOperationMethod']; $this->deleteOperationMethod = $options['deleteOperationMethod']; $this->additionalArgs = $options['additionalOperationArguments']; $this->operationStatusMethod = $options['operationStatusMethod']; $this->operationStatusDoneValue = $options['operationStatusDoneValue']; $this->operationErrorCodeMethod = $options['operationErrorCodeMethod']; $this->operationErrorMessageMethod = $options['operationErrorMessageMethod']; $this->getOperationRequest = $options['getOperationRequest']; $this->cancelOperationRequest = $options['cancelOperationRequest']; $this->deleteOperationRequest = $options['deleteOperationRequest']; if (isset($options['initialPollDelayMillis'])) { $this->defaultPollSettings['initialPollDelayMillis'] = $options['initialPollDelayMillis']; } if (isset($options['pollDelayMultiplier'])) { $this->defaultPollSettings['pollDelayMultiplier'] = $options['pollDelayMultiplier']; } if (isset($options['maxPollDelayMillis'])) { $this->defaultPollSettings['maxPollDelayMillis'] = $options['maxPollDelayMillis']; } if (isset($options['totalPollTimeoutMillis'])) { $this->defaultPollSettings['totalPollTimeoutMillis'] = $options['totalPollTimeoutMillis']; } } /** * Check whether the operation has completed. * * @return bool */ public function isDone() { if (!$this->hasProtoResponse()) { return false; } $status = call_user_func([$this->lastProtoResponse, $this->operationStatusMethod]); if (is_null($status)) { return false; } return $status === $this->operationStatusDoneValue; } /** * Check whether the operation completed successfully. If the operation is not complete, or if the operation * failed, return false. * * @return bool */ public function operationSucceeded() { if (!$this->hasProtoResponse()) { return false; } if (!$this->canHaveResult()) { // For Operations which do not have a result, we consider a successful // operation when the operation has completed without errors. return $this->isDone() && !$this->hasErrors(); } return !is_null($this->getResult()); } /** * Check whether the operation failed. If the operation is not complete, or if the operation * succeeded, return false. * * @return bool */ public function operationFailed() { return $this->hasErrors(); } /** * Get the formatted name of the operation * * @return string The formatted name of the operation */ public function getName() { return $this->operationName; } /** * Poll the server in a loop until the operation is complete. * * Return true if the operation completed, otherwise return false. If the * $options['totalPollTimeoutMillis'] setting is not set (or set <= 0) then * pollUntilComplete will continue polling until the operation completes, * and therefore will always return true. * * @param array $options { * Options for configuring the polling behaviour. * * @type int $initialPollDelayMillis The initial polling interval to use, in milliseconds. * @type int $pollDelayMultiplier Multiplier applied to the polling interval on each retry. * @type int $maxPollDelayMillis The maximum polling interval to use, in milliseconds. * @type int $totalPollTimeoutMillis The maximum amount of time to continue polling, in milliseconds. * } * @throws ApiException If an API call fails. * @throws ValidationException * @return bool Indicates if the operation completed. */ public function pollUntilComplete(array $options = []) { if ($this->isDone()) { return true; } $pollSettings = array_merge($this->defaultPollSettings, $options); return $this->poll(function () { $this->reload(); return $this->isDone(); }, $pollSettings); } /** * Reload the status of the operation with a request to the service. * * @throws ApiException If the API call fails. * @throws ValidationException If called on a deleted operation. */ public function reload() { if ($this->deleted) { throw new ValidationException('Cannot call reload() on a deleted operation'); } $requestClass = $this->isNewSurfaceOperationsClient() ? $this->getOperationRequest : null; $this->lastProtoResponse = $this->operationsCall($this->getOperationMethod, $requestClass); } /** * Return the result of the operation. If operationSucceeded() is false, * return null. * * @return T|null */ public function getResult() { if (!$this->hasProtoResponse()) { return null; } if (!$this->canHaveResult()) { return null; } if (!$this->isDone()) { return null; } /** @var Any|null $anyResponse */ $anyResponse = $this->lastProtoResponse->getResponse(); if (is_null($anyResponse)) { return null; } if (is_null($this->operationReturnType)) { return $anyResponse; } $operationReturnType = $this->operationReturnType; /** @var Message $response */ $response = new $operationReturnType(); $response->mergeFromString($anyResponse->getValue()); return $response; } /** * If the operation failed, return the status. If operationFailed() is false, return null. * * @return Status|null The status of the operation in case of failure, or null if * operationFailed() is false. */ public function getError() { if (!$this->hasProtoResponse() || !$this->isDone()) { return null; } if ($this->operationErrorCodeMethod || $this->operationErrorMessageMethod) { $errorCode = $this->operationErrorCodeMethod ? call_user_func([$this->lastProtoResponse, $this->operationErrorCodeMethod]) : null; $errorMessage = $this->operationErrorMessageMethod ? call_user_func([$this->lastProtoResponse, $this->operationErrorMessageMethod]) : null; return (new Status()) ->setCode(ApiStatus::rpcCodeFromHttpStatusCode($errorCode)) ->setMessage($errorMessage); } if (method_exists($this->lastProtoResponse, 'getError')) { return $this->lastProtoResponse->getError(); } return null; } /** * Get an array containing the values of 'operationReturnType', 'metadataReturnType', and * the polling options `initialPollDelayMillis`, `pollDelayMultiplier`, `maxPollDelayMillis`, * and `totalPollTimeoutMillis`. The array can be passed as the $options argument to the * constructor when creating another OperationResponse object. * * @return array */ public function getDescriptorOptions() { return [ 'operationReturnType' => $this->operationReturnType, 'metadataReturnType' => $this->metadataReturnType, ] + $this->defaultPollSettings; } /** * @return Operation|mixed|null The last Operation object received from the server. */ public function getLastProtoResponse() { return $this->lastProtoResponse; } /** * @return object The OperationsClient object used to make * requests to the operations API. */ public function getOperationsClient() { return $this->operationsClient; } /** * Cancel the long-running operation. * * For operations of type Google\LongRunning\Operation, this method starts * asynchronous cancellation on a long-running operation. The server * makes a best effort to cancel the operation, but success is not * guaranteed. If the server doesn't support this method, it will throw an * ApiException with code \Google\Rpc\Code::UNIMPLEMENTED. Clients can continue * to use reload and pollUntilComplete methods to check whether the cancellation * succeeded or whether the operation completed despite cancellation. * On successful cancellation, the operation is not deleted; instead, it becomes * an operation with a getError() value with a \Google\Rpc\Status code of 1, * corresponding to \Google\Rpc\Code::CANCELLED. * * @throws ApiException If the API call fails. * @throws LogicException If the API call method has not been configured */ public function cancel() { if (is_null($this->cancelOperationMethod)) { throw new LogicException('The cancel operation is not supported by this API'); } $requestClass = $this->isNewSurfaceOperationsClient() ? $this->cancelOperationRequest : null; $this->operationsCall($this->cancelOperationMethod, $requestClass); } /** * Delete the long-running operation. * * For operations of type Google\LongRunning\Operation, this method * indicates that the client is no longer interested in the operation result. * It does not cancel the operation. If the server doesn't support this method, * it will throw an ApiException with code \Google\Rpc\Code::UNIMPLEMENTED. * * @throws ApiException If the API call fails. * @throws LogicException If the API call method has not been configured */ public function delete() { if (is_null($this->deleteOperationMethod)) { throw new LogicException('The delete operation is not supported by this API'); } $requestClass = $this->isNewSurfaceOperationsClient() ? $this->deleteOperationRequest : null; $this->operationsCall($this->deleteOperationMethod, $requestClass); $this->deleted = true; } /** * Get the metadata returned with the last proto response. If a metadata type was provided, then * the return value will be of that type - otherwise, the return value will be of type Any. If * no metadata object is available, returns null. * * @return mixed The metadata returned from the server in the last response. */ public function getMetadata() { if (!$this->hasProtoResponse()) { return null; } if (!method_exists($this->lastProtoResponse, 'getMetadata')) { // The call to getMetadata is only for OnePlatform LROs, and is not // supported by other LRO GAPIC clients (e.g. Compute) return null; } /** @var Any|null $any */ $any = $this->lastProtoResponse->getMetadata(); if (is_null($this->metadataReturnType)) { return $any; } if (is_null($any)) { return null; } // @TODO: This is probably not doing anything and can be removed in the next release. if (is_null($any->getValue())) { return null; } $metadataReturnType = $this->metadataReturnType; /** @var Message $metadata */ $metadata = new $metadataReturnType(); $metadata->mergeFromString($any->getValue()); return $metadata; } /** * Call the operations client to perform an operation. * * @param string $method The method to call on the operations client. * @param string|null $requestClass The request class to use for the call. * Will be null for legacy operations clients. */ private function operationsCall(string $method, ?string $requestClass) { // V1 GAPIC clients have an empty $requestClass if (empty($requestClass)) { if ($this->additionalArgs) { return $this->operationsClient->$method( $this->getName(), ...array_values($this->additionalArgs) ); } return $this->operationsClient->$method($this->getName()); } if (!method_exists($requestClass, 'build')) { throw new LogicException('Request class must support the static build method'); } // In V2 of Compute, the Request "build" methods contain the operation ID last instead // of first. Compute is the only API which uses $additionalArgs, so switching the order // will not break anything. $request = $requestClass::build(...array_merge( array_values($this->additionalArgs), [$this->getName()] )); return $this->operationsClient->$method($request); } private function canHaveResult() { // The call to getResponse is only for OnePlatform LROs, and is not // supported by other LRO GAPIC clients (e.g. Compute) return method_exists($this->lastProtoResponse, 'getResponse'); } private function hasErrors() { if (!$this->hasProtoResponse()) { return false; } if (method_exists($this->lastProtoResponse, 'getError')) { return !empty($this->lastProtoResponse->getError()); } if ($this->operationErrorCodeMethod) { $errorCode = call_user_func([$this->lastProtoResponse, $this->operationErrorCodeMethod]); return !empty($errorCode); } // This should never happen unless an API is misconfigured throw new LogicException('Unable to determine operation error status for this service'); } private function hasProtoResponse() { return !is_null($this->lastProtoResponse); } private function isNewSurfaceOperationsClient(): bool { return !$this->operationsClient instanceof LegacyOperationsClient && false !== strpos(get_class($this->operationsClient), self::NEW_CLIENT_NAMESPACE); } } ================================================ FILE: lib/Google/vendor/google/gax/src/Options/CallOptions.php ================================================ > $headers * Key-value array containing headers. * @type int $timeoutMillis * The timeout in milliseconds for the call. * @type array $transportOptions * Transport-specific call options. See {@see CallOptions::setTransportOptions}. * @type RetrySettings|array $retrySettings * A retry settings override for the call. If $retrySettings is an * array, the settings will be merged with the method's default * retry settings. If $retrySettings is a RetrySettings object, * that object will be used instead of the method defaults. * } */ public function __construct(array $options) { $this->fromArray($options); } /** * Sets the array of options as class properites. * * @param array $arr See the constructor for the list of supported options. */ private function fromArray(array $arr): void { $this->setHeaders($arr['headers'] ?? []); $this->setTimeoutMillis($arr['timeoutMillis'] ?? null); $this->setTransportOptions($arr['transportOptions'] ?? []); $this->setRetrySettings($arr['retrySettings'] ?? null); } /** * @param array $headers */ public function setHeaders(array $headers): self { $this->headers = $headers; return $this; } /** * @param int|null $timeoutMillis */ public function setTimeoutMillis(?int $timeoutMillis): self { $this->timeoutMillis = $timeoutMillis; return $this; } /** * @param array $transportOptions { * Transport-specific call-time options. * * @type array $grpcOptions * Key-value pairs for gRPC-specific options passed as the `$options` argument to {@see \Grpc\BaseStub} * request methods. Current options are `call_credentials_callback` and `timeout`. * **NOTE**: This library sets `call_credentials_callback` using {@see CredentialsWrapper}, and `timeout` * using the `timeoutMillis` call option, so these options are not very useful. * @type array $grpcFallbackOptions * Key-value pairs for gRPC fallback specific options passed as the `$options` argument to the * `$httpHandler` callable. By default these are passed to {@see \GuzzleHttp\Client} as request options. * See {@link https://docs.guzzlephp.org/en/stable/request-options.html}. * @type array $restOptions * Key-value pairs for REST-specific options passed as the `$options` argument to the `$httpHandler` * callable. By default these are passed to {@see \GuzzleHttp\Client} as request options. * See {@link https://docs.guzzlephp.org/en/stable/request-options.html}. * } */ public function setTransportOptions(array $transportOptions): self { $this->transportOptions = $transportOptions; return $this; } /** * @deprecated use CallOptions::setTransportOptions */ public function setTransportSpecificOptions(array $transportSpecificOptions): self { $this->setTransportOptions($transportSpecificOptions); return $this; } /** * @param RetrySettings|array|null $retrySettings * * @return $this */ public function setRetrySettings($retrySettings): self { $this->retrySettings = $retrySettings; return $this; } } ================================================ FILE: lib/Google/vendor/google/gax/src/Options/ClientOptions.php ================================================ '/path/to/my/credentials.json' * ]); * $secretManager = new SecretManagerClient($options->toArray()); * ``` * * Note: It's possible to pass an associative array to the API clients as well, * as ClientOptions will still be used internally for validation. */ class ClientOptions implements ArrayAccess, OptionsInterface { use OptionsTrait; private ?string $apiEndpoint; private bool $disableRetries; private array $clientConfig; /** @var string|array|FetchAuthTokenInterface|CredentialsWrapper|null */ private $credentials; private array $credentialsConfig; /** @var string|TransportInterface|null $transport */ private $transport; private TransportOptions $transportConfig; private ?string $versionFile; private ?string $descriptorsConfigPath; private ?string $serviceName; private ?string $libName; private ?string $libVersion; private ?string $gapicVersion; private ?Closure $clientCertSource; private ?string $universeDomain; private ?string $apiKey; private null|false|LoggerInterface $logger; /** * @param array $options { * @type string $apiEndpoint * The address of the API remote host, for example "example.googleapis.com. May also * include the port, for example "example.googleapis.com:443" * @type bool $disableRetries * Determines whether or not retries defined by the client configuration should be * disabled. Defaults to `false`. * @type string|array $clientConfig * Client method configuration, including retry settings. This option can be either a * path to a JSON file, or a PHP array containing the decoded JSON data. * By default this settings points to the default client config file, which is provided * in the resources folder. * @type FetchAuthTokenInterface|CredentialsWrapper $credentials * This option should only be used with a pre-constructed \Google\Auth\FetchAuthTokenInterface * object or \Google\ApiCore\CredentialsWrapper object. Note that when one of these objects * are provided, any settings in $authConfig will be ignored. * **Important**: If you are providing a path to a credentials file, or a decoded credentials * file as a PHP array, this usage is now DEPRECATED. Providing an unvalidated credential * configuration to Google APIs can compromise the security of your systems and data. It is now * recommended to create the credentials explicitly: * ``` * use Google\Auth\Credentials\ServiceAccountCredentials; * use Google\ApiCore\Options\ClientOptions; * $creds = new ServiceAccountCredentials($scopes, $json); * $options = new ClientOptions(['credentials' => $creds]); * ``` * For more information * {@see https://cloud.google.com/docs/authentication/external/externally-sourced-credentials} * @type array $credentialsConfig * Options used to configure credentials, including auth token caching, for the client. * For a full list of supporting configuration options, see * \Google\ApiCore\CredentialsWrapper::build. * @type string|TransportInterface|null $transport * The transport used for executing network requests. May be either the string `rest`, * `grpc`, or 'grpc-fallback'. Defaults to `grpc` if gRPC support is detected on the system. * *Advanced usage*: Additionally, it is possible to pass in an already instantiated * TransportInterface object. Note that when this objects is provided, any settings in * $transportConfig, and any `$apiEndpoint` setting, will be ignored. * @type array $transportConfig * Configuration options that will be used to construct the transport. Options for * each supported transport type should be passed in a key for that transport. For * example: * $transportConfig = [ * 'grpc' => [...], * 'rest' => [...], * 'grpc-fallback' => [...], * ]; * See the GrpcTransport::build and RestTransport::build * methods for the supported options. * @type string $versionFile * The path to a file which contains the current version of the client. * @type string $descriptorsConfigPath * The path to a descriptor configuration file. * @type string $serviceName * The name of the service. * @type string $libName * The name of the client application. * @type string $libVersion * The version of the client application. * @type string $gapicVersion * The code generator version of the GAPIC library. * @type callable $clientCertSource * A callable which returns the client cert as a string. * @type string $universeDomain * The default service domain for a given Cloud universe. * @type string $apiKey * The API key to be used for the client. * @type null|false|LoggerInterface * A PSR-3 compliant logger. * } */ public function __construct(array $options) { $this->fromArray($options); } /** * Sets the array of options as class properites. * * @param array $arr See the constructor for the list of supported options. */ private function fromArray(array $arr): void { $this->setApiEndpoint($arr['apiEndpoint'] ?? null); $this->setDisableRetries($arr['disableRetries'] ?? false); $this->setClientConfig($arr['clientConfig'] ?? []); $this->setCredentials($arr['credentials'] ?? null); $this->setCredentialsConfig($arr['credentialsConfig'] ?? []); $this->setTransport($arr['transport'] ?? null); $this->setTransportConfig(new TransportOptions($arr['transportConfig'] ?? [])); $this->setVersionFile($arr['versionFile'] ?? null); $this->setDescriptorsConfigPath($arr['descriptorsConfigPath'] ?? null); $this->setServiceName($arr['serviceName'] ?? null); $this->setLibName($arr['libName'] ?? null); $this->setLibVersion($arr['libVersion'] ?? null); $this->setGapicVersion($arr['gapicVersion'] ?? null); $this->setClientCertSource($arr['clientCertSource'] ?? null); $this->setUniverseDomain($arr['universeDomain'] ?? null); $this->setApiKey($arr['apiKey'] ?? null); $this->setLogger($arr['logger'] ?? null); } /** * @param ?string $apiEndpoint * * @return $this */ public function setApiEndpoint(?string $apiEndpoint): self { $this->apiEndpoint = $apiEndpoint; return $this; } /** * @param bool $disableRetries * * @return $this */ public function setDisableRetries(bool $disableRetries): self { $this->disableRetries = $disableRetries; return $this; } /** * @param string|array $clientConfig * * @return $this * @throws InvalidArgumentException */ public function setClientConfig($clientConfig): self { if (is_string($clientConfig)) { $this->clientConfig = json_decode(file_get_contents($clientConfig), true); } elseif (is_array($clientConfig)) { $this->clientConfig = $clientConfig; } else { throw new InvalidArgumentException('Invalid client config'); } return $this; } /** * @param string|array|FetchAuthTokenInterface|CredentialsWrapper|null $credentials * * @return $this */ public function setCredentials($credentials): self { $this->credentials = $credentials; return $this; } /** * @param array $credentialsConfig * * @return $this */ public function setCredentialsConfig(array $credentialsConfig): self { $this->credentialsConfig = $credentialsConfig; return $this; } /** * @param string|TransportInterface|null $transport * * @return $this */ public function setTransport($transport): self { $this->transport = $transport; return $this; } /** * @param TransportOptions $transportConfig * * @return $this */ public function setTransportConfig(TransportOptions $transportConfig): self { $this->transportConfig = $transportConfig; return $this; } /** * @param ?string $versionFile * * @return $this */ public function setVersionFile(?string $versionFile): self { $this->versionFile = $versionFile; return $this; } /** * @param ?string $descriptorsConfigPath * * @return $this */ private function setDescriptorsConfigPath(?string $descriptorsConfigPath): self { if (!is_null($descriptorsConfigPath)) { self::validateFileExists($descriptorsConfigPath); } $this->descriptorsConfigPath = $descriptorsConfigPath; return $this; } /** * @param ?string $serviceName * * @return $this */ public function setServiceName(?string $serviceName): self { $this->serviceName = $serviceName; return $this; } /** * @param ?string $libName * * @return $this */ public function setLibName(?string $libName): self { $this->libName = $libName; return $this; } /** * @param ?string $libVersion * * @return $this */ public function setLibVersion(?string $libVersion): self { $this->libVersion = $libVersion; return $this; } /** * @param ?string $gapicVersion * * @return $this */ public function setGapicVersion(?string $gapicVersion): self { $this->gapicVersion = $gapicVersion; return $this; } /** * @param ?callable $clientCertSource * * @return $this */ public function setClientCertSource(?callable $clientCertSource): self { if (!is_null($clientCertSource)) { $clientCertSource = Closure::fromCallable($clientCertSource); } $this->clientCertSource = $clientCertSource; return $this; } /** * @param string $universeDomain * * @return $this */ public function setUniverseDomain(?string $universeDomain): self { $this->universeDomain = $universeDomain; return $this; } /** * @param string $apiKey * * @return $this */ public function setApiKey(?string $apiKey): self { $this->apiKey = $apiKey; return $this; } /** * @param null|false|LoggerInterface $logger * * @return $this */ public function setLogger(null|false|LoggerInterface $logger): self { $this->logger = $logger; return $this; } } ================================================ FILE: lib/Google/vendor/google/gax/src/Options/OptionsInterface.php ================================================ $offset); } /** * @return mixed */ #[\ReturnTypeWillChange] public function offsetGet($offset) { return $this->$offset; } /** * @throws BadMethodCallException */ public function offsetSet($offset, $value): void { throw new BadMethodCallException('Cannot set options through array access. Use the setters instead'); } /** * @throws BadMethodCallException */ public function offsetUnset($offset): void { throw new BadMethodCallException('Cannot unset options through array access. Use the setters instead'); } public function toArray(): array { $arr = []; foreach (get_object_vars($this) as $key => $value) { $arr[$key] = $value instanceof OptionsInterface ? $value->toArray() : $value; } return $arr; } } ================================================ FILE: lib/Google/vendor/google/gax/src/Options/TransportOptions/GrpcFallbackTransportOptions.php ================================================ fromArray($options); } /** * Sets the array of options as class properites. * * @param array $arr See the constructor for the list of supported options. */ private function fromArray(array $arr): void { $this->setClientCertSource($arr['clientCertSource'] ?? null); $this->setHttpHandler($arr['httpHandler'] ?? null); $this->setLogger($arr['logger'] ?? null); } /** * @param ?callable $httpHandler * * @return $this */ public function setHttpHandler(?callable $httpHandler): self { if (!is_null($httpHandler)) { $httpHandler = Closure::fromCallable($httpHandler); } $this->httpHandler = $httpHandler; return $this; } /** * @param ?callable $clientCertSource * * @return $this */ public function setClientCertSource(?callable $clientCertSource): self { if (!is_null($clientCertSource)) { $clientCertSource = Closure::fromCallable($clientCertSource); } $this->clientCertSource = $clientCertSource; return $this; } /** * @param null|false|LoggerInterface $logger * * @return $this */ public function setLogger(null|false|LoggerInterface $logger): self { $this->logger = $logger; return $this; } } ================================================ FILE: lib/Google/vendor/google/gax/src/Options/TransportOptions/GrpcTransportOptions.php ================================================ fromArray($options); } /** * Sets the array of options as class properites. * * @param array $arr See the constructor for the list of supported options. */ private function fromArray(array $arr): void { $this->setStubOpts($arr['stubOpts'] ?? []); $this->setChannel($arr['channel'] ?? null); $this->setInterceptors($arr['interceptors'] ?? []); $this->setClientCertSource($arr['clientCertSource'] ?? null); $this->setLogger($arr['logger'] ?? null); } /** * @param array $stubOpts * * @return $this */ public function setStubOpts(array $stubOpts): self { $this->stubOpts = $stubOpts; return $this; } /** * @param ?Channel $channel * * @return $this */ public function setChannel(?Channel $channel): self { $this->channel = $channel; return $this; } /** * @param Interceptor[]|UnaryInterceptorInterface[] $interceptors * * @return $this */ public function setInterceptors(array $interceptors): self { $this->interceptors = $interceptors; return $this; } /** * @param ?callable $clientCertSource * * @return $this */ public function setClientCertSource(?callable $clientCertSource): self { if (!is_null($clientCertSource)) { $clientCertSource = Closure::fromCallable($clientCertSource); } $this->clientCertSource = $clientCertSource; return $this; } /** * @param null|false|LoggerInterface $logger * * @return $this */ public function setLogger(null|false|LoggerInterface $logger): self { $this->logger = $logger; return $this; } } ================================================ FILE: lib/Google/vendor/google/gax/src/Options/TransportOptions/RestTransportOptions.php ================================================ fromArray($options); } /** * Sets the array of options as class properites. * * @param array $arr See the constructor for the list of supported options. */ private function fromArray(array $arr): void { $this->setHttpHandler($arr['httpHandler'] ?? null); $this->setClientCertSource($arr['clientCertSource'] ?? null); $this->setRestClientConfigPath($arr['restClientConfigPath'] ?? null); $this->setLogger($arr['logger'] ?? null); } /** * @param ?callable $httpHandler * * @return $this */ public function setHttpHandler(?callable $httpHandler): self { if (!is_null($httpHandler)) { $httpHandler = Closure::fromCallable($httpHandler); } $this->httpHandler = $httpHandler; return $this; } /** * @param ?callable $clientCertSource * * @return $this */ public function setClientCertSource(?callable $clientCertSource): self { if (!is_null($clientCertSource)) { $clientCertSource = Closure::fromCallable($clientCertSource); } $this->clientCertSource = $clientCertSource; return $this; } /** * @param ?string $restClientConfigPath * * @return $this */ public function setRestClientConfigPath(?string $restClientConfigPath): self { $this->restClientConfigPath = $restClientConfigPath; return $this; } /** * @param null|false|LoggerInterface $logger * * @return $this */ public function setLogger(null|false|LoggerInterface $logger): self { $this->logger = $logger; return $this; } } ================================================ FILE: lib/Google/vendor/google/gax/src/Options/TransportOptions.php ================================================ fromArray($options); } /** * Sets the array of options as class properites. * * @param array $arr See the constructor for the list of supported options. */ private function fromArray(array $arr): void { $this->setGrpc(new GrpcTransportOptions($arr['grpc'] ?? [])); $this->setGrpcFallback(new GrpcFallbackTransportOptions($arr['grpc-fallback'] ?? [])); $this->setRest(new RestTransportOptions($arr['rest'] ?? [])); } /** * @param GrpcTransportOptions $grpc * * @return $this */ public function setGrpc(GrpcTransportOptions $grpc): self { $this->grpc = $grpc; return $this; } /** * @param GrpcFallbackTransportOptions $grpcFallback * * @return $this */ public function setGrpcFallback(GrpcFallbackTransportOptions $grpcFallback): self { $this->grpcFallback = $grpcFallback; return $this; } /** * @param RestTransportOptions $rest * * @return $this */ public function setRest(RestTransportOptions $rest): self { $this->rest = $rest; return $this; } } ================================================ FILE: lib/Google/vendor/google/gax/src/Page.php ================================================ call = $call; $this->options = $options; $this->callable = $callable; $this->pageStreamingDescriptor = $pageStreamingDescriptor; $this->response = $response; $requestPageTokenGetMethod = $this->pageStreamingDescriptor->getRequestPageTokenGetMethod(); $this->pageToken = $this->call->getMessage()->$requestPageTokenGetMethod(); } /** * Returns true if there are more pages that can be retrieved from the * API. * * @return bool */ public function hasNextPage() { return strcmp($this->getNextPageToken(), Page::FINAL_PAGE_TOKEN) != 0; } /** * Returns the next page token from the response. * * @return string */ public function getNextPageToken() { $responsePageTokenGetMethod = $this->pageStreamingDescriptor->getResponsePageTokenGetMethod(); return $this->getResponseObject()->$responsePageTokenGetMethod(); } /** * Retrieves the next Page object using the next page token. * * @param int|null $pageSize * @throws ValidationException if there are no pages remaining, or if pageSize is supplied but * is not supported by the API * @throws ApiException if the call to fetch the next page fails. * @return Page */ public function getNextPage(?int $pageSize = null) { if (!$this->hasNextPage()) { throw new ValidationException( 'Could not complete getNextPage operation: ' . 'there are no more pages to retrieve.' ); } $oldRequest = $this->getRequestObject(); $requestClass = get_class($oldRequest); $newRequest = new $requestClass(); $newRequest->mergeFrom($oldRequest); $requestPageTokenSetMethod = $this->pageStreamingDescriptor->getRequestPageTokenSetMethod(); $newRequest->$requestPageTokenSetMethod($this->getNextPageToken()); if (isset($pageSize)) { if (!$this->pageStreamingDescriptor->requestHasPageSizeField()) { throw new ValidationException( 'pageSize argument was defined, but the method does not ' . 'support a page size parameter in the optional array argument' ); } $requestPageSizeSetMethod = $this->pageStreamingDescriptor->getRequestPageSizeSetMethod(); $newRequest->$requestPageSizeSetMethod($pageSize); } $this->call = $this->call->withMessage($newRequest); $callable = $this->callable; $response = $callable( $this->call, $this->options )->wait(); return new Page( $this->call, $this->options, $this->callable, $this->pageStreamingDescriptor, $response ); } /** * Return the number of elements in the response. * * @return int */ public function getPageElementCount() { $resourcesGetMethod = $this->pageStreamingDescriptor->getResourcesGetMethod(); return count($this->getResponseObject()->$resourcesGetMethod()); } /** * Return an iterator over the elements in the response. * * @return Generator */ #[\ReturnTypeWillChange] public function getIterator() { $resourcesGetMethod = $this->pageStreamingDescriptor->getResourcesGetMethod(); $items = $this->getResponseObject()->$resourcesGetMethod(); foreach ($items as $key => $element) { if ($items instanceof MapField) { yield $key => $element; } else { yield $element; } } } /** * Return an iterator over Page objects, beginning with this object. * Additional Page objects are retrieved lazily via API calls until * all elements have been retrieved. * * @return Generator|array * @throws ValidationException * @throws ApiException */ public function iteratePages() { $currentPage = $this; yield $this; while ($currentPage->hasNextPage()) { $currentPage = $currentPage->getNextPage(); yield $currentPage; } } /** * Gets the request object used to generate the Page. * * @return mixed|Message */ public function getRequestObject() { return $this->call->getMessage(); } /** * Gets the API response object. * * @return mixed|Message */ public function getResponseObject() { return $this->response; } /** * Returns a collection of elements with a fixed size set by * the collectionSize parameter. The collection will only contain * fewer than collectionSize elements if there are no more * pages to be retrieved from the server. * * NOTE: it is an error to call this method if an optional parameter * to set the page size is not supported or has not been set in the * API call that was used to create this page. It is also an error * if the collectionSize parameter is less than the page size that * has been set. * * @param int $collectionSize * @throws ValidationException if a FixedSizeCollection of the specified size cannot be constructed * @return FixedSizeCollection */ public function expandToFixedSizeCollection($collectionSize) { if (!$this->pageStreamingDescriptor->requestHasPageSizeField()) { throw new ValidationException( 'FixedSizeCollection is not supported for this method, because ' . 'the method does not support an optional argument to set the ' . 'page size.' ); } $request = $this->getRequestObject(); $pageSizeGetMethod = $this->pageStreamingDescriptor->getRequestPageSizeGetMethod(); $pageSize = $request->$pageSizeGetMethod(); if (is_null($pageSize)) { throw new ValidationException( 'Error while expanding Page to FixedSizeCollection: No page size ' . 'parameter found. The page size parameter must be set in the API ' . 'optional arguments array, and must be less than the collectionSize ' . 'parameter, in order to create a FixedSizeCollection object.' ); } if ($pageSize > $collectionSize) { throw new ValidationException( 'Error while expanding Page to FixedSizeCollection: collectionSize ' . 'parameter is less than the page size optional argument specified in ' . "the API call. collectionSize: $collectionSize, page size: $pageSize" ); } return new FixedSizeCollection($this, $collectionSize); } } ================================================ FILE: lib/Google/vendor/google/gax/src/PageStreamingDescriptor.php ================================================ descriptor = $descriptor; } /** * @param array $fields { * Required. * * @type string $requestPageTokenField the page token field in the request object. * @type string $responsePageTokenField the page token field in the response object. * @type string $resourceField the resource field in the response object. * * Optional. * @type string $requestPageSizeField the page size field in the request object. * } * @return PageStreamingDescriptor */ public static function createFromFields(array $fields) { $requestPageToken = $fields['requestPageTokenField']; $responsePageToken = $fields['responsePageTokenField']; $resources = $fields['resourceField']; $descriptor = [ 'requestPageTokenGetMethod' => PageStreamingDescriptor::getMethod($requestPageToken), 'requestPageTokenSetMethod' => PageStreamingDescriptor::setMethod($requestPageToken), 'responsePageTokenGetMethod' => PageStreamingDescriptor::getMethod($responsePageToken), 'resourcesGetMethod' => PageStreamingDescriptor::getMethod($resources), ]; if (isset($fields['requestPageSizeField'])) { $requestPageSize = $fields['requestPageSizeField']; $descriptor['requestPageSizeGetMethod'] = PageStreamingDescriptor::getMethod($requestPageSize); $descriptor['requestPageSizeSetMethod'] = PageStreamingDescriptor::setMethod($requestPageSize); } return new PageStreamingDescriptor($descriptor); } private static function getMethod(string $field) { return 'get' . ucfirst($field); } private static function setMethod(string $field) { return 'set' . ucfirst($field); } /** * @return string The page token get method on the request object */ public function getRequestPageTokenGetMethod() { return $this->descriptor['requestPageTokenGetMethod']; } /** * @return string The page size get method on the request object */ public function getRequestPageSizeGetMethod() { return $this->descriptor['requestPageSizeGetMethod']; } /** * @return bool True if the request object has a page size field */ public function requestHasPageSizeField() { return array_key_exists('requestPageSizeGetMethod', $this->descriptor); } /** * @return string The page token get method on the response object */ public function getResponsePageTokenGetMethod() { return $this->descriptor['responsePageTokenGetMethod']; } /** * @return string The resources get method on the response object */ public function getResourcesGetMethod() { return $this->descriptor['resourcesGetMethod']; } /** * @return string The page token set method on the request object */ public function getRequestPageTokenSetMethod() { return $this->descriptor['requestPageTokenSetMethod']; } /** * @return string The page size set method on the request object */ public function getRequestPageSizeSetMethod() { return $this->descriptor['requestPageSizeSetMethod']; } private static function validate(array $descriptor) { $requiredFields = [ 'requestPageTokenGetMethod', 'requestPageTokenSetMethod', 'responsePageTokenGetMethod', 'resourcesGetMethod', ]; foreach ($requiredFields as $field) { if (empty($descriptor[$field])) { throw new InvalidArgumentException( "$field is required for PageStreamingDescriptor" ); } } } } ================================================ FILE: lib/Google/vendor/google/gax/src/PagedListResponse.php ================================================ getList(...); * foreach ($pagedListResponse as $element) { * // doSomethingWith($element); * } * ``` * * Example of iterating over each page of elements: * ``` * $pagedListResponse = $client->getList(...); * foreach ($pagedListResponse->iteratePages() as $page) { * foreach ($page as $element) { * // doSomethingWith($element); * } * } * ``` * * Example of accessing the current page, and manually iterating * over pages: * ``` * $pagedListResponse = $client->getList(...); * $page = $pagedListResponse->getPage(); * // doSomethingWith($page); * while ($page->hasNextPage()) { * $page = $page->getNextPage(); * // doSomethingWith($page); * } * ``` */ class PagedListResponse implements IteratorAggregate { private $firstPage; /** * PagedListResponse constructor. * * @param Page $firstPage A page containing response details. */ public function __construct( Page $firstPage ) { $this->firstPage = $firstPage; } /** * Returns an iterator over the full list of elements. If the * API response contains a (non-empty) next page token, then * the PagedListResponse object will make calls to the underlying * API to retrieve additional elements as required. * * NOTE: The result of this method is the same as getIterator(). * Prefer using getIterator(), or iterate directly on the * PagedListResponse object. * * @return Generator * @throws ValidationException */ public function iterateAllElements() { return $this->getIterator(); } /** * Returns an iterator over the full list of elements. If the * API response contains a (non-empty) next page token, then * the PagedListResponse object will make calls to the underlying * API to retrieve additional elements as required. * * @return Generator * @throws ValidationException */ #[\ReturnTypeWillChange] public function getIterator() { foreach ($this->iteratePages() as $page) { foreach ($page as $key => $element) { yield $key => $element; } } } /** * Return the current page of results. * * @return Page */ public function getPage() { return $this->firstPage; } /** * Returns an iterator over pages of results. The pages are * retrieved lazily from the underlying API. * * @return Page[] * @throws ValidationException */ public function iteratePages() { return $this->getPage()->iteratePages(); } /** * Returns a collection of elements with a fixed size set by * the collectionSize parameter. The collection will only contain * fewer than collectionSize elements if there are no more * pages to be retrieved from the server. * * NOTE: it is an error to call this method if an optional parameter * to set the page size is not supported or has not been set in the * original API call. It is also an error if the collectionSize parameter * is less than the page size that has been set. * * @param int $collectionSize * @throws ValidationException if a FixedSizeCollection of the specified size cannot be constructed * @return FixedSizeCollection */ public function expandToFixedSizeCollection(int $collectionSize) { return $this->getPage()->expandToFixedSizeCollection($collectionSize); } /** * Returns an iterator over fixed size collections of results. * The collections are retrieved lazily from the underlying API. * * Each collection will have collectionSize elements, with the * exception of the final collection which may contain fewer * elements. * * NOTE: it is an error to call this method if an optional parameter * to set the page size is not supported or has not been set in the * original API call. It is also an error if the collectionSize parameter * is less than the page size that has been set. * * @param int $collectionSize * @throws ValidationException if a FixedSizeCollection of the specified size cannot be constructed * @return Generator|FixedSizeCollection[] */ public function iterateFixedSizeCollections(int $collectionSize) { return $this->expandToFixedSizeCollection($collectionSize)->iterateCollections(); } } ================================================ FILE: lib/Google/vendor/google/gax/src/PathTemplate.php ================================================ resourceTemplate = new AbsoluteResourceTemplate($path); } else { $this->resourceTemplate = new RelativeResourceTemplate($path); } } /** * @return string A string representation of the path template */ public function __toString() { return $this->resourceTemplate->__toString(); } /** * Renders a path template using the provided bindings. * * @param array $bindings An array matching var names to binding strings. * @throws ValidationException if a key isn't provided or if a sub-template * can't be parsed. * @return string A rendered representation of this path template. */ public function render(array $bindings) { return $this->resourceTemplate->render($bindings); } /** * Check if $path matches a resource string. * * @param string $path A resource string. * @return bool */ public function matches(string $path) { return $this->resourceTemplate->matches($path); } /** * Matches a fully qualified path template string. * * @param string $path A fully qualified path template string. * @throws ValidationException if path can't be matched to the template. * @return array Array matching var names to binding values. */ public function match(string $path) { return $this->resourceTemplate->match($path); } } ================================================ FILE: lib/Google/vendor/google/gax/src/PollingTrait.php ================================================ 0.0; $endTime = $this->getCurrentTimeMillis() + $totalPollTimeoutMillis; while (true) { if ($hasTotalPollTimeout && $this->getCurrentTimeMillis() > $endTime) { return false; } $this->sleepMillis($currentPollDelayMillis); if ($pollCallable()) { return true; } $currentPollDelayMillis = (int) min([ $currentPollDelayMillis * $pollDelayMultiplier, $maxPollDelayMillis ]); } } /** * Protected to allow overriding for tests * * @return float Current time in milliseconds */ protected function getCurrentTimeMillis() { return microtime(true) * 1000.0; } /** * Protected to allow overriding for tests * * @param int $millis */ protected function sleepMillis(int $millis) { usleep($millis * 1000); } } ================================================ FILE: lib/Google/vendor/google/gax/src/RequestBuilder.php ================================================ baseUri = $baseUri; $this->restConfig = require($restConfigPath); } /** * @param string $path * @return bool */ public function pathExists(string $path) { list($interface, $method) = explode('/', $path); return isset($this->restConfig['interfaces'][$interface][$method]); } /** * @param string $path * @param Message $message * @param array $headers * @return RequestInterface * @throws ValidationException */ public function build(string $path, Message $message, array $headers = []) { list($interface, $method) = explode('/', $path); if (!isset($this->restConfig['interfaces'][$interface][$method])) { throw new ValidationException( "Failed to build request, as the provided path ($path) was not found in the configuration." ); } $numericEnums = isset($this->restConfig['numericEnums']) && $this->restConfig['numericEnums']; $methodConfig = $this->restConfig['interfaces'][$interface][$method] + [ 'placeholders' => [], 'body' => null, 'additionalBindings' => null, ]; $bindings = $this->buildBindings($methodConfig['placeholders'], $message); $uriTemplateConfigs = $this->getConfigsForUriTemplates($methodConfig); foreach ($uriTemplateConfigs as $config) { $pathTemplate = $this->tryRenderPathTemplate($config['uriTemplate'], $bindings); if ($pathTemplate) { // We found a valid uriTemplate - now build and return the Request list($body, $queryParams) = $this->constructBodyAndQueryParameters($message, $config); // Request enum fields will be encoded as numbers rather than strings (in the response). if ($numericEnums) { $queryParams['$alt'] = 'json;enum-encoding=int'; } $uri = $this->buildUri($pathTemplate, $queryParams); return new Request( $config['method'], $uri, ['Content-Type' => 'application/json'] + $headers, $body ); } } // No valid uriTemplate found - construct an exception $uriTemplates = []; foreach ($uriTemplateConfigs as $config) { $uriTemplates[] = $config['uriTemplate']; } throw new ValidationException("Could not map bindings for $path to any Uri template.\n" . 'Bindings: ' . print_r($bindings, true) . 'UriTemplates: ' . print_r($uriTemplates, true)); } /** * Create a list of all possible configs using the additionalBindings * * @param array $config * @return array[] An array of configs */ private function getConfigsForUriTemplates(array $config) { $configs = [$config]; if ($config['additionalBindings']) { foreach ($config['additionalBindings'] as $additionalBinding) { $configs[] = $additionalBinding + $config; } } return $configs; } /** * @param Message $message * @param array $config * @return array Tuple [$body, $queryParams] */ private function constructBodyAndQueryParameters(Message $message, array $config) { $messageDataJson = $message->serializeToJsonString(); if ($config['body'] === '*') { return [$messageDataJson, []]; } $body = null; $queryParams = []; $messageData = json_decode($messageDataJson, true); foreach ($messageData as $name => $value) { if (array_key_exists($name, $config['placeholders'])) { continue; } if (Serializer::toSnakeCase($name) === $config['body']) { if (($bodyMessage = $message->{"get$name"}()) instanceof Message) { $body = $bodyMessage->serializeToJsonString(); } else { $body = json_encode($value); } continue; } if (is_array($value) && $this->isAssoc($value)) { foreach ($value as $key => $value2) { $queryParams[$name . '.' . $key] = $value2; } } else { $queryParams[$name] = $value; } } // Ensures required query params with default values are always sent // over the wire. if (isset($config['queryParams'])) { foreach ($config['queryParams'] as $requiredQueryParam) { $requiredQueryParam = Serializer::toCamelCase($requiredQueryParam); if (!array_key_exists($requiredQueryParam, $queryParams)) { $getter = Serializer::getGetter($requiredQueryParam); $queryParamValue = $message->$getter(); if ($queryParamValue instanceof Message) { // Decode message for the query parameter. $queryParamValue = json_decode($queryParamValue->serializeToJsonString(), true); } if (is_array($queryParamValue)) { // If the message has properties, add them as nested querystring values. // NOTE: This only supports nesting at one level of depth. foreach ($queryParamValue as $key => $value) { $queryParams[$requiredQueryParam . '.' . $key] = $value; } } else { $queryParams[$requiredQueryParam] = $queryParamValue; } } } } return [$body, $queryParams]; } /** * @param array $placeholders * @param Message $message * @return array Bindings from path template fields to values from message */ private function buildBindings(array $placeholders, Message $message) { $bindings = []; foreach ($placeholders as $placeholder => $metadata) { $value = array_reduce( $metadata['getters'], function (?Message $result = null, $getter = null) { if ($result && $getter) { return $result->$getter(); } }, $message ); $bindings[$placeholder] = $value; } return $bindings; } /** * Try to render the resource name. The rendered resource name will always contain a leading '/' * * @param string $uriTemplate * @param array $bindings * @return null|string * @throws ValidationException */ private function tryRenderPathTemplate(string $uriTemplate, array $bindings) { $template = new AbsoluteResourceTemplate($uriTemplate); try { return $template->render($bindings); } catch (ValidationException $e) { return null; } } /** * @param string $path * @param array $queryParams * @return UriInterface */ protected function buildUri(string $path, array $queryParams) { $uri = Utils::uriFor( sprintf( 'https://%s%s', $this->baseUri, $path ) ); if ($queryParams) { $uri = $this->buildUriWithQuery( $uri, $queryParams ); } return $uri; } } ================================================ FILE: lib/Google/vendor/google/gax/src/RequestParamsHeaderDescriptor.php ================================================ value]. */ public function __construct(array $requestParams) { $headerKey = self::HEADER_KEY; $headerValue = ''; foreach ($requestParams as $key => $value) { if ('' !== $headerValue) { $headerValue .= '&'; } $headerValue .= $key . '=' . urlencode(strval($value)); } $this->header = [$headerKey => [$headerValue]]; } /** * Returns an associative array that contains request params header metadata. * * @return array */ public function getHeader() { return $this->header; } } ================================================ FILE: lib/Google/vendor/google/gax/src/ResourceHelperTrait.php ================================================ $template) { self::$templateMap[$name] = new PathTemplate($template); } } private static function getPathTemplate(string $key) { // TODO: Add nullable return type reference once PHP 7.1 is minimum. if (is_null(self::$templateMap)) { self::registerPathTemplates(); } return self::$templateMap[$key] ?? null; } private static function parseFormattedName(string $formattedName, ?string $template = null): array { if (is_null(self::$templateMap)) { self::registerPathTemplates(); } if ($template) { if (!isset(self::$templateMap[$template])) { throw new ValidationException("Template name $template does not exist"); } return self::$templateMap[$template]->match($formattedName); } foreach (self::$templateMap as $templateName => $pathTemplate) { try { return $pathTemplate->match($formattedName); } catch (ValidationException $ex) { // Swallow the exception to continue trying other path templates } } throw new ValidationException("Input did not match any known format. Input: $formattedName"); } } ================================================ FILE: lib/Google/vendor/google/gax/src/ResourceTemplate/AbsoluteResourceTemplate.php ================================================ "). * * Examples: * /projects * /projects/{project} * /foo/{bar=**}/fizz/*:action * * Templates use the syntax of the API platform; see * https://github.com/googleapis/api-common-protos/blob/master/google/api/http.proto * for details. A template consists of a sequence of literals, wildcards, and variable bindings, * where each binding can have a sub-path. A string representation can be parsed into an * instance of AbsoluteResourceTemplate, which can then be used to perform matching and instantiation. * * @internal */ class AbsoluteResourceTemplate implements ResourceTemplateInterface { private RelativeResourceTemplate $resourceTemplate; /** @var string|bool */ private $verb; /** * AbsoluteResourceTemplate constructor. * @param string $path * @throws ValidationException */ public function __construct(string $path) { if (empty($path)) { throw new ValidationException('Cannot construct AbsoluteResourceTemplate from empty string'); } if ($path[0] !== '/') { throw new ValidationException( "Could not construct AbsoluteResourceTemplate from '$path': must begin with '/'" ); } $verbSeparatorPos = $this->verbSeparatorPos($path); $this->resourceTemplate = new RelativeResourceTemplate(substr($path, 1, $verbSeparatorPos - 1)); $this->verb = substr($path, $verbSeparatorPos + 1); } /** * @inheritdoc */ public function __toString() { return sprintf('/%s%s', $this->resourceTemplate, $this->renderVerb()); } /** * @inheritdoc */ public function render(array $bindings) { return sprintf('/%s%s', $this->resourceTemplate->render($bindings), $this->renderVerb()); } /** * @inheritdoc */ public function matches(string $path) { try { $this->match($path); return true; } catch (ValidationException $ex) { return false; } } /** * @inheritdoc */ public function match(string $path) { if (empty($path)) { throw $this->matchException($path, 'path cannot be empty'); } if ($path[0] !== '/') { throw $this->matchException($path, "missing leading '/'"); } $verbSeparatorPos = $this->verbSeparatorPos($path); if (substr($path, $verbSeparatorPos + 1) !== $this->verb) { throw $this->matchException($path, "trailing verb did not match '{$this->verb}'"); } return $this->resourceTemplate->match(substr($path, 1, $verbSeparatorPos - 1)); } private function matchException(string $path, string $reason) { return new ValidationException("Could not match path '$path' to template '$this': $reason"); } private function renderVerb() { return $this->verb ? ':' . $this->verb : ''; } private function verbSeparatorPos(string $path) { $finalSeparatorPos = strrpos($path, '/'); $verbSeparatorPos = strrpos($path, ':', $finalSeparatorPos); if ($verbSeparatorPos === false) { $verbSeparatorPos = strlen($path); } return $verbSeparatorPos; } } ================================================ FILE: lib/Google/vendor/google/gax/src/ResourceTemplate/Parser.php ================================================ = strlen($path)) { // A trailing '/' has caused the index to exceed the bounds // of the string - provide a helpful error message. throw self::parseError($path, strlen($path) - 1, "invalid trailing '/'"); } if ($path[$index] === '{') { // Validate that the { has a matching } $closingBraceIndex = strpos($path, '}', $index); if ($closingBraceIndex === false) { throw self::parseError( $path, strlen($path), "Expected '}' to match '{' at index $index, got end of string" ); } $segmentStringLengthWithoutBraces = $closingBraceIndex - $index - 1; $segmentStringWithoutBraces = substr($path, $index + 1, $segmentStringLengthWithoutBraces); $index = $closingBraceIndex + 1; $nextLiteral = '/'; $remainingPath = substr($path, $index); if (!empty($remainingPath)) { // Find the firstnon-slash separator seen, if any. $nextSlashIndex = strpos($remainingPath, '/', 0); $nonSlashSeparators = ['-', '_', '~', '.']; foreach ($nonSlashSeparators as $nonSlashSeparator) { $nonSlashSeparatorIndex = strpos($remainingPath, $nonSlashSeparator, 0); $nextOpenBraceIndex = strpos($remainingPath, '{', 0); if ($nonSlashSeparatorIndex !== false && $nonSlashSeparatorIndex === $nextOpenBraceIndex - 1) { $index += $nonSlashSeparatorIndex; $nextLiteral = $nonSlashSeparator; break; } } } return self::parseVariableSegment($segmentStringWithoutBraces, $nextLiteral); } else { $nextSlash = strpos($path, '/', $index); if ($nextSlash === false) { $nextSlash = strlen($path); } $segmentString = substr($path, $index, $nextSlash - $index); $nextLiteral = '/'; $index = $nextSlash; return self::parse($segmentString, $path, $index); } } /** * @param string $segmentString * @param string $path * @param int $index * @return Segment * @throws ValidationException */ private static function parse(string $segmentString, string $path, int $index) { if ($segmentString === '*') { return new Segment(Segment::WILDCARD_SEGMENT); } elseif ($segmentString === '**') { return new Segment(Segment::DOUBLE_WILDCARD_SEGMENT); } else { if (!self::isValidLiteral($segmentString)) { if (empty($segmentString)) { // Create user friendly message in case of empty segment throw self::parseError($path, $index, "Unexpected empty segment (consecutive '/'s are invalid)"); } else { throw self::parseError($path, $index, "Unexpected characters in literal segment $segmentString"); } } return new Segment(Segment::LITERAL_SEGMENT, $segmentString); } } /** * @param string $segmentStringWithoutBraces * @param string $separatorLiteral * @return Segment * @throws ValidationException */ private static function parseVariableSegment(string $segmentStringWithoutBraces, string $separatorLiteral) { // Validate there are no nested braces $nestedOpenBracket = strpos($segmentStringWithoutBraces, '{'); if ($nestedOpenBracket !== false) { throw new ValidationException( "Unexpected '{' parsing segment $segmentStringWithoutBraces at index $nestedOpenBracket" ); } $equalsIndex = strpos($segmentStringWithoutBraces, '='); if ($equalsIndex === false) { // If the variable does not contain '=', we assume the pattern is '*' as per google.rpc.Http $variableKey = $segmentStringWithoutBraces; $nestedResource = new RelativeResourceTemplate('*'); } else { $variableKey = substr($segmentStringWithoutBraces, 0, $equalsIndex); $nestedResourceString = substr($segmentStringWithoutBraces, $equalsIndex + 1); $nestedResource = new RelativeResourceTemplate($nestedResourceString); } if (!self::isValidLiteral($variableKey)) { throw new ValidationException( "Unexpected characters in variable name $variableKey" ); } return new Segment(Segment::VARIABLE_SEGMENT, null, $variableKey, $nestedResource, $separatorLiteral); } /** * @param string $literal * @param string $path * @param int $index * @return string * @throws ValidationException */ private static function parseLiteralFromPath(string $literal, string $path, int &$index) { $literalLength = strlen($literal); if (strlen($path) < ($index + $literalLength)) { throw self::parseError($path, $index, "expected '$literal'"); } $consumedLiteral = substr($path, $index, $literalLength); if ($consumedLiteral !== $literal) { throw self::parseError($path, $index, "expected '$literal'"); } $index += $literalLength; return $consumedLiteral; } private static function parseError(string $path, int $index, string $reason) { return new ValidationException("Error parsing '$path' at index $index: $reason"); } /** * Check if $literal is a valid segment literal. Segment literals may only contain numbers, * letters, and any of the following: .-~_ * * @param string $literal * @return bool */ private static function isValidLiteral(string $literal) { return preg_match('/^[0-9a-zA-Z\\.\\-~_]+$/', $literal) === 1; } } ================================================ FILE: lib/Google/vendor/google/gax/src/ResourceTemplate/RelativeResourceTemplate.php ================================================ "). * * Examples: * projects * projects/{project} * foo/{bar=**}/fizz/* * * Templates use the syntax of the API platform; see * https://github.com/googleapis/api-common-protos/blob/master/google/api/http.proto * for details. A template consists of a sequence of literals, wildcards, and variable bindings, * where each binding can have a sub-path. A string representation can be parsed into an * instance of AbsoluteResourceTemplate, which can then be used to perform matching and instantiation. * * @internal */ class RelativeResourceTemplate implements ResourceTemplateInterface { /** @var Segment[] */ private array $segments; /** * RelativeResourceTemplate constructor. * * @param string $path * @throws ValidationException */ public function __construct(string $path) { if (empty($path)) { throw new ValidationException('Cannot construct RelativeResourceTemplate from empty string'); } $this->segments = Parser::parseSegments($path); $doubleWildcardCount = self::countDoubleWildcards($this->segments); if ($doubleWildcardCount > 1) { throw new ValidationException( "Cannot parse '$path': cannot contain more than one path wildcard" ); } // Check for duplicate keys $keys = []; foreach ($this->segments as $segment) { if ($segment->getSegmentType() === Segment::VARIABLE_SEGMENT) { if (isset($keys[$segment->getKey()])) { throw new ValidationException( "Duplicate key '{$segment->getKey()}' in path $path" ); } $keys[$segment->getKey()] = true; } } } /** * @inheritdoc */ public function __toString() { return self::renderSegments($this->segments); } /** * @inheritdoc */ public function render(array $bindings) { $literalSegments = []; $keySegmentTuples = self::buildKeySegmentTuples($this->segments); foreach ($keySegmentTuples as list($key, $segment)) { /** @var Segment $segment */ if ($segment->getSegmentType() === Segment::LITERAL_SEGMENT) { $literalSegments[] = $segment; continue; } if (!array_key_exists($key, $bindings)) { throw $this->renderingException($bindings, "missing required binding '$key' for segment '$segment'"); } $value = $bindings[$key]; if (!is_null($value) && $segment->matches($value)) { $literalSegments[] = new Segment( Segment::LITERAL_SEGMENT, $value, $segment->getValue(), $segment->getTemplate(), $segment->getSeparator() ); } else { $valueString = is_null($value) ? 'null' : "'$value'"; throw $this->renderingException( $bindings, "expected binding '$key' to match segment '$segment', instead got $valueString" ); } } return self::renderSegments($literalSegments); } /** * @inheritdoc */ public function matches(string $path) { try { $this->match($path); return true; } catch (ValidationException $ex) { return false; } } /** * @inheritdoc */ public function match(string $path) { // High level strategy for matching: // - Build a list of Segments from our template, where any variable segments are // flattened into a single, non-nested list // - Break $path into pieces based on '/'. // - Use the segments to further subdivide the pieces using any applicable non-slash separators. // - Match pieces of the path with Segments in the flattened list // In order to build correct bindings after we match the $path against our template, we // need to (a) calculate the correct positional keys for our wildcards, and (b) maintain // information about the variable identifier of any flattened segments. To do this, we // build a list of [string, Segment] tuples, where the string component is the appropriate // key. $keySegmentTuples = self::buildKeySegmentTuples($this->segments); $flattenedKeySegmentTuples = self::flattenKeySegmentTuples($keySegmentTuples); $flattenedKeySegmentTuplesCount = count($flattenedKeySegmentTuples); assert($flattenedKeySegmentTuplesCount > 0); $slashPathPieces = explode('/', $path); $pathPieces = []; $pathPiecesIndex = 0; $startIndex = 0; $slashPathPiecesCount = count($slashPathPieces); $doubleWildcardPieceCount = $slashPathPiecesCount - $flattenedKeySegmentTuplesCount + 1; for ($i = 0; $i < count($flattenedKeySegmentTuples); $i++) { $segmentKey = $flattenedKeySegmentTuples[$i][0]; $segment = $flattenedKeySegmentTuples[$i][1]; // In our flattened list of segments, we should never encounter a variable segment assert($segment->getSegmentType() !== Segment::VARIABLE_SEGMENT); if ($segment->getSegmentType() == Segment::DOUBLE_WILDCARD_SEGMENT) { $pathPiecesForSegment = array_slice($slashPathPieces, $pathPiecesIndex, $doubleWildcardPieceCount); $pathPiece = implode('/', $pathPiecesForSegment); $pathPiecesIndex += $doubleWildcardPieceCount; $pathPieces[] = $pathPiece; continue; } if ($segment->getSegmentType() == Segment::WILDCARD_SEGMENT) { if ($pathPiecesIndex >= $slashPathPiecesCount) { break; } } if ($segment->getSeparator() === '/') { if ($pathPiecesIndex >= $slashPathPiecesCount) { throw $this->matchException($path, 'segment and path length mismatch'); } $pathPiece = substr($slashPathPieces[$pathPiecesIndex++], $startIndex); $startIndex = 0; } else { $rawPiece = substr($slashPathPieces[$pathPiecesIndex], $startIndex); $pathPieceLength = strpos($rawPiece, $segment->getSeparator()); $pathPiece = substr($rawPiece, 0, $pathPieceLength); $startIndex += $pathPieceLength + 1; } $pathPieces[] = $pathPiece; } if ($flattenedKeySegmentTuples[$i - 1][1]->getSegmentType() !== Segment::DOUBLE_WILDCARD_SEGMENT) { // Process any remaining pieces. The binding logic will throw exceptions for any invalid paths. for (; $pathPiecesIndex < count($slashPathPieces); $pathPiecesIndex++) { $pathPieces[] = $slashPathPieces[$pathPiecesIndex]; } } $pathPiecesCount = count($pathPieces); // We would like to match pieces of our path 1:1 with the segments of our template. However, // this is confounded by the presence of double wildcards ('**') in the template, which can // match multiple segments in the path. // Because there can only be one '**' present, we can determine how many segments it must // match by examining the difference in count between the template segments and the // path pieces. if ($pathPiecesCount < $flattenedKeySegmentTuplesCount) { // Each segment in $flattenedKeyedSegments must consume at least one // segment in $pathSegments, so matching must fail. throw $this->matchException($path, 'path does not contain enough segments to be matched'); } $doubleWildcardPieceCount = $pathPiecesCount - $flattenedKeySegmentTuplesCount + 1; $bindings = []; $pathPiecesIndex = 0; /** @var Segment $segment */ foreach ($flattenedKeySegmentTuples as list($segmentKey, $segment)) { $pathPiece = $pathPieces[$pathPiecesIndex++]; if (!$segment->matches($pathPiece)) { throw $this->matchException($path, "expected path element matching '$segment', got '$pathPiece'"); } // If we have a valid key, add our $pathPiece to the $bindings array. Note that there // may be multiple copies of the same $segmentKey. This is because a flattened variable // segment can match multiple pieces from the path. We can add these to an array and // collapse them all once the bindings are complete. if (isset($segmentKey)) { $bindings += [$segmentKey => []]; $bindings[$segmentKey][] = $pathPiece; } } // It is possible that we have left over path pieces, which can occur if our template does // not have a double wildcard. In that case, the match should fail. if ($pathPiecesIndex !== $pathPiecesCount) { throw $this->matchException($path, "expected end of path, got '$pathPieces[$pathPiecesIndex]'"); } // Collapse the bindings from lists into strings $collapsedBindings = []; foreach ($bindings as $key => $boundPieces) { $collapsedBindings[$key] = implode('/', $boundPieces); } return $collapsedBindings; } private function matchException(string $path, string $reason) { return new ValidationException("Could not match path '$path' to template '$this': $reason"); } private function renderingException(array $bindings, string $reason) { $bindingsString = print_r($bindings, true); return new ValidationException( "Error rendering '$this': $reason\n" . "Provided bindings: $bindingsString" ); } /** * @param Segment[] $segments * @param string|null $separator An optional string separator * @return array[] A list of [string, Segment] tuples */ private static function buildKeySegmentTuples(array $segments, ?string $separator = null) { $keySegmentTuples = []; $positionalArgumentCounter = 0; foreach ($segments as $segment) { switch ($segment->getSegmentType()) { case Segment::WILDCARD_SEGMENT: case Segment::DOUBLE_WILDCARD_SEGMENT: $positionalKey = "\$$positionalArgumentCounter"; $positionalArgumentCounter++; $newSegment = $segment; if ($separator !== null) { $newSegment = new Segment( $segment->getSegmentType(), $segment->getValue(), $segment->getKey(), $segment->getTemplate(), $separator ); } $keySegmentTuples[] = [$positionalKey, $newSegment]; break; default: $keySegmentTuples[] = [$segment->getKey(), $segment]; } } return $keySegmentTuples; } /** * @param array[] $keySegmentTuples A list of [string, Segment] tuples * @return array[] A list of [string, Segment] tuples */ private static function flattenKeySegmentTuples(array $keySegmentTuples) { $flattenedKeySegmentTuples = []; foreach ($keySegmentTuples as list($key, $segment)) { /** @var Segment $segment */ switch ($segment->getSegmentType()) { case Segment::VARIABLE_SEGMENT: // For segment variables, replace the segment with the segments of its children $template = $segment->getTemplate(); $nestedKeySegmentTuples = self::buildKeySegmentTuples( $template->segments, $segment->getSeparator() ); foreach ($nestedKeySegmentTuples as list($nestedKey, $nestedSegment)) { /** @var Segment $nestedSegment */ // Nested variables are not allowed assert($nestedSegment->getSegmentType() !== Segment::VARIABLE_SEGMENT); // Insert the nested segment with key set to the outer key of the // parent variable segment $flattenedKeySegmentTuples[] = [$key, $nestedSegment]; } break; default: // For all other segments, don't change the key or segment $flattenedKeySegmentTuples[] = [$key, $segment]; } } return $flattenedKeySegmentTuples; } /** * @param Segment[] $segments * @return int */ private static function countDoubleWildcards(array $segments) { $doubleWildcardCount = 0; foreach ($segments as $segment) { switch ($segment->getSegmentType()) { case Segment::DOUBLE_WILDCARD_SEGMENT: $doubleWildcardCount++; break; case Segment::VARIABLE_SEGMENT: $doubleWildcardCount += self::countDoubleWildcards($segment->getTemplate()->segments); break; } } return $doubleWildcardCount; } /** * Joins segments using their separators. * @param array $segmentsToRender * @return string */ private static function renderSegments(array $segmentsToRender) { $renderResult = ''; for ($i = 0; $i < count($segmentsToRender); $i++) { $segment = $segmentsToRender[$i]; $renderResult .= $segment; if ($i < count($segmentsToRender) - 1) { $renderResult .= $segment->getSeparator(); } } return $renderResult; } } ================================================ FILE: lib/Google/vendor/google/gax/src/ResourceTemplate/ResourceTemplateInterface.php ================================================ "). (Note that a trailing verb without a * leading slash is not permitted). * * Examples: * projects * /projects * foo/{bar=**}/fizz/* * /foo/{bar=**}/fizz/*:action * * Templates use the syntax of the API platform; see * https://github.com/googleapis/api-common-protos/blob/master/google/api/http.proto * for details. A template consists of a sequence of literals, wildcards, and variable bindings, * where each binding can have a sub-path. A string representation can be parsed into an * instance of AbsoluteResourceTemplate, which can then be used to perform matching and instantiation. * * @internal */ interface ResourceTemplateInterface { /** * @return string A string representation of the resource template */ public function __toString(); /** * Renders a resource template using the provided bindings. * * @param array $bindings An array matching var names to binding strings. * @return string A rendered representation of this resource template. * @throws ValidationException If $bindings does not contain all required keys * or if a sub-template can't be parsed. */ public function render(array $bindings); /** * Check if $path matches a resource string. * * @param string $path A resource string. * @return bool */ public function matches(string $path); /** * Matches a given $path to a resource template, and returns an array of bindings between * wildcards / variables in the template and values in the path. If $path does not match the * template, then a ValidationException is thrown. * * @param string $path A resource string. * @throws ValidationException if path can't be matched to the template. * @return array Array matching var names to binding values. */ public function match(string $path); } ================================================ FILE: lib/Google/vendor/google/gax/src/ResourceTemplate/Segment.php ================================================ segmentType = $segmentType; $this->value = $value; $this->key = $key; $this->template = $template; $this->separator = $separator; switch ($this->segmentType) { case Segment::LITERAL_SEGMENT: $this->stringRepr = "{$this->value}"; break; case Segment::WILDCARD_SEGMENT: $this->stringRepr = '*'; break; case Segment::DOUBLE_WILDCARD_SEGMENT: $this->stringRepr = '**'; break; case Segment::VARIABLE_SEGMENT: $this->stringRepr = "{{$this->key}={$this->template}}"; break; default: throw new ValidationException( "Unexpected Segment type: {$this->segmentType}" ); } } /** * @return string A string representation of the segment. */ public function __toString() { return $this->stringRepr; } /** * Checks if $value matches this Segment. * * @param string $value * @return bool * @throws ValidationException */ public function matches(string $value) { switch ($this->segmentType) { case Segment::LITERAL_SEGMENT: return $this->value === $value; case Segment::WILDCARD_SEGMENT: return self::isValidBinding($value); case Segment::DOUBLE_WILDCARD_SEGMENT: return self::isValidDoubleWildcardBinding($value); case Segment::VARIABLE_SEGMENT: return $this->template->matches($value); default: throw new ValidationException( "Unexpected Segment type: {$this->segmentType}" ); } } /** * @return int */ public function getSegmentType() { return $this->segmentType; } /** * @return string|null */ public function getKey() { return $this->key; } /** * @return string|null */ public function getValue() { return $this->value; } /** * @return RelativeResourceTemplate|null */ public function getTemplate() { return $this->template; } /** * @return string */ public function getSeparator() { return $this->separator; } /** * Check if $binding is a valid segment binding. Segment bindings may contain any characters * except a forward slash ('/'), and may not be empty. * * @param string $binding * @return bool */ private static function isValidBinding(string $binding) { return preg_match('-^[^/]+$-', $binding) === 1; } /** * Check if $binding is a valid double wildcard binding. Segment bindings may contain any * characters, but may not be empty. * * @param string $binding * @return bool */ private static function isValidDoubleWildcardBinding(string $binding) { return preg_match('-^.+$-', $binding) === 1; } } ================================================ FILE: lib/Google/vendor/google/gax/src/RetrySettings.php ================================================ 100, * 'retryDelayMultiplier' => 1.3, * 'maxRetryDelayMillis' => 60000, * 'initialRpcTimeoutMillis' => 20000, * 'rpcTimeoutMultiplier' => 1.0, * 'maxRpcTimeoutMillis' => 20000, * 'totalTimeoutMillis' => 600000, * 'retryableCodes' => [ApiStatus::DEADLINE_EXCEEDED, ApiStatus::UNAVAILABLE], * ]); * ``` * * It is also possible to create a new RetrySettings object from an existing * object using the {@see \Google\ApiCore\RetrySettings::with()} method. * * Example modifying an existing RetrySettings object using `with()`: * ``` * $newRetrySettings = $retrySettings->with([ * 'totalTimeoutMillis' => 700000, * ]); * ``` * * Modifying the retry behavior of an RPC method * --------------------------------------------- * * RetrySettings objects can be used to control retries for many RPC methods in * [google-cloud-php](https://github.com/googleapis/google-cloud-php). * The examples below make use of the * [GroupServiceClient](https://cloud.google.com/php/docs/reference/cloud-monitoring/latest/V3.Client.GroupServiceClient) * from the [Monitoring V3 API](https://github.com/googleapis/google-cloud-php/tree/master/src/Monitoring/V3), * but they can be applied to other APIs in the * [google-cloud-php](https://github.com/googleapis/google-cloud-php) repository. * * It is possible to specify the retry behavior to be used by an RPC via the * `retrySettings` field in the `optionalArgs` parameter. The `retrySettings` * field can contain either a RetrySettings object, or a PHP array containing * the particular retry parameters to be updated. * * Example of disabling retries for a single call to the * [listGroups](https://cloud.google.com/php/docs/reference/cloud-monitoring/latest/V3.Client.GroupServiceClient#_Google_Cloud_Monitoring_V3_Client_GroupServiceClient__listGroups__) * method, and setting a custom timeout: * ``` * $result = $client->listGroups($name, [ * 'retrySettings' => [ * 'retriesEnabled' => false, * 'noRetriesRpcTimeoutMillis' => 5000, * ] * ]); * ``` * * Example of creating a new RetrySettings object and using it to override * the retry settings for a call to the * [listGroups](https://cloud.google.com/php/docs/reference/cloud-monitoring/latest/V3.Client.GroupServiceClient#_Google_Cloud_Monitoring_V3_Client_GroupServiceClient__listGroups__) * method: * ``` * $customRetrySettings = new RetrySettings([ * 'initialRetryDelayMillis' => 100, * 'retryDelayMultiplier' => 1.3, * 'maxRetryDelayMillis' => 60000, * 'initialRpcTimeoutMillis' => 20000, * 'rpcTimeoutMultiplier' => 1.0, * 'maxRpcTimeoutMillis' => 20000, * 'totalTimeoutMillis' => 600000, * 'retryableCodes' => [ApiStatus::DEADLINE_EXCEEDED, ApiStatus::UNAVAILABLE], * ]); * * $result = $client->listGroups($name, [ * 'retrySettings' => $customRetrySettings * ]); * ``` * * Modifying the default retry behavior for RPC methods on a Client object * ----------------------------------------------------------------------- * * It is also possible to specify the retry behavior for RPC methods when * constructing a client object using the 'retrySettingsArray'. The examples * below again make use of the * [GroupServiceClient](https://cloud.google.com/php/docs/reference/cloud-monitoring/latest/V3.Client.GroupServiceClient) * from the [Monitoring V3 API](https://github.com/googleapis/google-cloud-php/tree/main/Monitoring/src/V3), * but they can be applied to other APIs in the * [google-cloud-php](https://github.com/googleapis/google-cloud-php) repository. * * The GroupServiceClient object accepts an optional `retrySettingsArray` * parameter, which can be used to specify retry behavior for RPC methods * on the client. The `retrySettingsArray` accepts a PHP array in which keys * are the names of RPC methods on the client, and values are either a * RetrySettings object or a PHP array containing the particular retry * parameters to be updated. * * Example updating the retry settings for four methods of GroupServiceClient: * ``` * use Google\Cloud\Monitoring\V3\GroupServiceClient; * * $customRetrySettings = new RetrySettings([ * 'initialRetryDelayMillis' => 100, * 'retryDelayMultiplier' => 1.3, * 'maxRetryDelayMillis' => 60000, * 'initialRpcTimeoutMillis' => 20000, * 'rpcTimeoutMultiplier' => 1.0, * 'maxRpcTimeoutMillis' => 20000, * 'totalTimeoutMillis' => 600000, * 'retryableCodes' => [ApiStatus::DEADLINE_EXCEEDED, ApiStatus::UNAVAILABLE], * ]); * * $updatedCustomRetrySettings = $customRetrySettings->with([ * 'totalTimeoutMillis' => 700000 * ]); * * $client = new GroupServiceClient([ * 'retrySettingsArray' => [ * 'listGroups' => ['retriesEnabled' => false], * 'getGroup' => [ * 'initialRpcTimeoutMillis' => 10000, * 'maxRpcTimeoutMillis' => 30000, * 'totalTimeoutMillis' => 60000, * ], * 'deleteGroup' => $customRetrySettings, * 'updateGroup' => $updatedCustomRetrySettings * ], * ]); * ``` * * Configure the use of logical timeout * ------------------------------------ * * To configure the use of a logical timeout, where a logical timeout is the * duration a method is given to complete one or more RPC attempts, with each * attempt using only the time remaining in the logical timeout, use * {@see \Google\ApiCore\RetrySettings::logicalTimeout()} combined with * {@see \Google\ApiCore\RetrySettings::with()}. * * ``` * $timeoutSettings = RetrySettings::logicalTimeout(30000); * * $customRetrySettings = $customRetrySettings->with($timeoutSettings); * * $result = $client->listGroups($name, [ * 'retrySettings' => $customRetrySettings * ]); * ``` * * {@see \Google\ApiCore\RetrySettings::logicalTimeout()} can also be used on a * method call independent of a RetrySettings instance. * * ``` * $timeoutSettings = RetrySettings::logicalTimeout(30000); * * $result = $client->listGroups($name, [ * 'retrySettings' => $timeoutSettings * ]); * ``` */ class RetrySettings { use ValidationTrait; const DEFAULT_MAX_RETRIES = 0; private $retriesEnabled; private $retryableCodes; private $initialRetryDelayMillis; private $retryDelayMultiplier; private $maxRetryDelayMillis; private $initialRpcTimeoutMillis; private $rpcTimeoutMultiplier; private $maxRpcTimeoutMillis; private $totalTimeoutMillis; private $noRetriesRpcTimeoutMillis; /** * The number of maximum retries an operation can do. * This doesn't include the original API call. * Setting this to 0 means no limit. */ private int $maxRetries; /** * When set, this function will be used to evaluate if the retry should * take place or not. The callable will have the following signature: * function (Exception $e, array $options): bool */ private ?Closure $retryFunction; /** * Constructs an instance. * * @param array $settings { * Required. Settings for configuring the retry behavior. All parameters are required except * $retriesEnabled and $noRetriesRpcTimeoutMillis, which are optional and have defaults * determined based on the other settings provided. * * @type bool $retriesEnabled Optional. Enables retries. If not specified, the value is * determined using the $retryableCodes setting. If $retryableCodes is empty, * then $retriesEnabled is set to false; otherwise, it is set to true. * @type int $noRetriesRpcTimeoutMillis Optional. The timeout of the rpc call to be used * if $retriesEnabled is false, in milliseconds. It not specified, the value * of $initialRpcTimeoutMillis is used. * @type array $retryableCodes The Status codes that are retryable. Each status should be * either one of the string constants defined on {@see \Google\ApiCore\ApiStatus} * or an integer constant defined on {@see \Google\Rpc\Code}. * @type int $initialRetryDelayMillis The initial delay of retry in milliseconds. * @type int $retryDelayMultiplier The exponential multiplier of retry delay. * @type int $maxRetryDelayMillis The max delay of retry in milliseconds. * @type int $initialRpcTimeoutMillis The initial timeout of rpc call in milliseconds. * @type int $rpcTimeoutMultiplier The exponential multiplier of rpc timeout. * @type int $maxRpcTimeoutMillis The max timeout of rpc call in milliseconds. * @type int $totalTimeoutMillis The max accumulative timeout in total. * @type int $maxRetries The max retries allowed for an operation. * Defaults to the value of the DEFAULT_MAX_RETRIES constant. * This option is experimental. * @type callable $retryFunction This function will be used to decide if we should retry or not. * Callable signature: `function (Exception $e, array $options): bool` * This option is experimental. * } */ public function __construct(array $settings) { $this->validateNotNull($settings, [ 'initialRetryDelayMillis', 'retryDelayMultiplier', 'maxRetryDelayMillis', 'initialRpcTimeoutMillis', 'rpcTimeoutMultiplier', 'maxRpcTimeoutMillis', 'totalTimeoutMillis', 'retryableCodes' ]); $this->initialRetryDelayMillis = $settings['initialRetryDelayMillis']; $this->retryDelayMultiplier = $settings['retryDelayMultiplier']; $this->maxRetryDelayMillis = $settings['maxRetryDelayMillis']; $this->initialRpcTimeoutMillis = $settings['initialRpcTimeoutMillis']; $this->rpcTimeoutMultiplier = $settings['rpcTimeoutMultiplier']; $this->maxRpcTimeoutMillis = $settings['maxRpcTimeoutMillis']; $this->totalTimeoutMillis = $settings['totalTimeoutMillis']; $this->retryableCodes = $settings['retryableCodes']; $this->retriesEnabled = array_key_exists('retriesEnabled', $settings) ? $settings['retriesEnabled'] : (count($this->retryableCodes) > 0); $this->noRetriesRpcTimeoutMillis = array_key_exists('noRetriesRpcTimeoutMillis', $settings) ? $settings['noRetriesRpcTimeoutMillis'] : $this->initialRpcTimeoutMillis; $this->maxRetries = $settings['maxRetries'] ?? self::DEFAULT_MAX_RETRIES; $this->retryFunction = $settings['retryFunction'] ?? null; } /** * Constructs an array mapping method names to CallSettings. * * @param string $serviceName * The fully-qualified name of this service, used as a key into * the client config file. * @param array $clientConfig * An array parsed from the standard API client config file. * @param bool $disableRetries * Disable retries in all loaded RetrySettings objects. Defaults to false. * @throws ValidationException * @return RetrySettings[] $retrySettings */ public static function load( string $serviceName, array $clientConfig, bool $disableRetries = false ) { $serviceRetrySettings = []; $serviceConfig = $clientConfig['interfaces'][$serviceName]; $retryCodes = $serviceConfig['retry_codes']; $retryParams = $serviceConfig['retry_params']; foreach ($serviceConfig['methods'] as $methodName => $methodConfig) { $timeoutMillis = $methodConfig['timeout_millis']; if (empty($methodConfig['retry_codes_name']) || empty($methodConfig['retry_params_name'])) { // Construct a RetrySettings object with retries disabled $retrySettings = self::constructDefault()->with([ 'noRetriesRpcTimeoutMillis' => $timeoutMillis, ]); } else { $retryCodesName = $methodConfig['retry_codes_name']; $retryParamsName = $methodConfig['retry_params_name']; if (!array_key_exists($retryCodesName, $retryCodes)) { throw new ValidationException("Invalid retry_codes_name setting: '$retryCodesName'"); } if (!array_key_exists($retryParamsName, $retryParams)) { throw new ValidationException("Invalid retry_params_name setting: '$retryParamsName'"); } foreach ($retryCodes[$retryCodesName] as $status) { if (!ApiStatus::isValidStatus($status)) { throw new ValidationException("Invalid status code: '$status'"); } } $retryParameters = self::convertArrayFromSnakeCase($retryParams[$retryParamsName]) + [ 'retryableCodes' => $retryCodes[$retryCodesName], 'noRetriesRpcTimeoutMillis' => $timeoutMillis, ]; if ($disableRetries) { $retryParameters['retriesEnabled'] = false; } $retrySettings = new RetrySettings($retryParameters); } $serviceRetrySettings[$methodName] = $retrySettings; } return $serviceRetrySettings; } public static function constructDefault() { return new RetrySettings([ 'retriesEnabled' => false, 'noRetriesRpcTimeoutMillis' => 30000, 'initialRetryDelayMillis' => 100, 'retryDelayMultiplier' => 1.3, 'maxRetryDelayMillis' => 60000, 'initialRpcTimeoutMillis' => 20000, 'rpcTimeoutMultiplier' => 1, 'maxRpcTimeoutMillis' => 20000, 'totalTimeoutMillis' => 600000, 'retryableCodes' => [], 'maxRetries' => self::DEFAULT_MAX_RETRIES, 'retryFunction' => null]); } /** * Creates a new instance of RetrySettings that updates the settings in the existing instance * with the settings specified in the $settings parameter. * * @param array $settings { * Settings for configuring the retry behavior. Supports all of the options supported by * the constructor; see {@see \Google\ApiCore\RetrySettings::__construct()}. All parameters * are optional - all unset parameters will default to the value in the existing instance. * } * @return RetrySettings */ public function with(array $settings) { $existingSettings = [ 'initialRetryDelayMillis' => $this->getInitialRetryDelayMillis(), 'retryDelayMultiplier' => $this->getRetryDelayMultiplier(), 'maxRetryDelayMillis' => $this->getMaxRetryDelayMillis(), 'initialRpcTimeoutMillis' => $this->getInitialRpcTimeoutMillis(), 'rpcTimeoutMultiplier' => $this->getRpcTimeoutMultiplier(), 'maxRpcTimeoutMillis' => $this->getMaxRpcTimeoutMillis(), 'totalTimeoutMillis' => $this->getTotalTimeoutMillis(), 'retryableCodes' => $this->getRetryableCodes(), 'retriesEnabled' => $this->retriesEnabled(), 'noRetriesRpcTimeoutMillis' => $this->getNoRetriesRpcTimeoutMillis(), 'maxRetries' => $this->getMaxRetries(), 'retryFunction' => $this->getRetryFunction(), ]; return new RetrySettings($settings + $existingSettings); } /** * Creates an associative array of the {@see \Google\ApiCore\RetrySettings} timeout fields configured * with the given timeout specified in the $timeout parameter interpreted as a logical timeout. * * @param int $timeout The timeout in milliseconds to be used as a logical call timeout. * @return array */ public static function logicalTimeout(int $timeout) { return [ 'initialRpcTimeoutMillis' => $timeout, 'maxRpcTimeoutMillis' => $timeout, 'totalTimeoutMillis' => $timeout, 'noRetriesRpcTimeoutMillis' => $timeout, 'rpcTimeoutMultiplier' => 1.0 ]; } /** * @return bool Returns true if retries are enabled, otherwise returns false. */ public function retriesEnabled() { return $this->retriesEnabled; } /** * @return int The timeout of the rpc call to be used if $retriesEnabled is false, * in milliseconds. */ public function getNoRetriesRpcTimeoutMillis() { return $this->noRetriesRpcTimeoutMillis; } /** * @return int[] Status codes to retry */ public function getRetryableCodes() { return $this->retryableCodes; } /** * @return int The initial retry delay in milliseconds. If $this->retriesEnabled() * is false, this setting is unused. */ public function getInitialRetryDelayMillis() { return $this->initialRetryDelayMillis; } /** * @return float The retry delay multiplier. If $this->retriesEnabled() * is false, this setting is unused. */ public function getRetryDelayMultiplier() { return $this->retryDelayMultiplier; } /** * @return int The maximum retry delay in milliseconds. If $this->retriesEnabled() * is false, this setting is unused. */ public function getMaxRetryDelayMillis() { return $this->maxRetryDelayMillis; } /** * @return int The initial rpc timeout in milliseconds. If $this->retriesEnabled() * is false, this setting is unused - use noRetriesRpcTimeoutMillis to * set the timeout in that case. */ public function getInitialRpcTimeoutMillis() { return $this->initialRpcTimeoutMillis; } /** * @return float The rpc timeout multiplier. If $this->retriesEnabled() * is false, this setting is unused. */ public function getRpcTimeoutMultiplier() { return $this->rpcTimeoutMultiplier; } /** * @return int The maximum rpc timeout in milliseconds. If $this->retriesEnabled() * is false, this setting is unused - use noRetriesRpcTimeoutMillis to * set the timeout in that case. */ public function getMaxRpcTimeoutMillis() { return $this->maxRpcTimeoutMillis; } /** * @return int The total time in milliseconds to spend on the call, including all * retry attempts and delays between attempts. If $this->retriesEnabled() * is false, this setting is unused - use noRetriesRpcTimeoutMillis to * set the timeout in that case. */ public function getTotalTimeoutMillis() { return $this->totalTimeoutMillis; } /** * @experimental */ public function getMaxRetries() { return $this->maxRetries; } /** * @experimental */ public function getRetryFunction() { return $this->retryFunction; } private static function convertArrayFromSnakeCase(array $settings) { $camelCaseSettings = []; foreach ($settings as $key => $value) { $camelCaseKey = str_replace(' ', '', ucwords(str_replace('_', ' ', $key))); $camelCaseSettings[lcfirst($camelCaseKey)] = $value; } return $camelCaseSettings; } } ================================================ FILE: lib/Google/vendor/google/gax/src/Serializer.php ================================================ \Google\Rpc\RetryInfo::class, 'google.rpc.debuginfo-bin' => \Google\Rpc\DebugInfo::class, 'google.rpc.quotafailure-bin' => \Google\Rpc\QuotaFailure::class, 'google.rpc.badrequest-bin' => \Google\Rpc\BadRequest::class, 'google.rpc.requestinfo-bin' => \Google\Rpc\RequestInfo::class, 'google.rpc.resourceinfo-bin' => \Google\Rpc\ResourceInfo::class, 'google.rpc.errorinfo-bin' => \Google\Rpc\ErrorInfo::class, 'google.rpc.help-bin' => \Google\Rpc\Help::class, 'google.rpc.localizedmessage-bin' => \Google\Rpc\LocalizedMessage::class, ]; private $fieldTransformers; private $messageTypeTransformers; private $decodeFieldTransformers; private $decodeMessageTypeTransformers; // Array of key-value pairs which specify a custom encoding function. // The key is the proto class and the value is the function // which will be used to convert the proto instead of the // encodeMessage method from the Serializer class. private $customEncoders; private $descriptorMaps = []; /** * Serializer constructor. * * @param array $fieldTransformers An array mapping field names to transformation functions * @param array $messageTypeTransformers An array mapping message names to transformation functions * @param array $decodeFieldTransformers An array mapping field names to transformation functions * @param array $decodeMessageTypeTransformers An array mapping message names to transformation functions */ public function __construct( $fieldTransformers = [], $messageTypeTransformers = [], $decodeFieldTransformers = [], $decodeMessageTypeTransformers = [], $customEncoders = [], ) { $this->fieldTransformers = $fieldTransformers; $this->messageTypeTransformers = $messageTypeTransformers; $this->decodeFieldTransformers = $decodeFieldTransformers; $this->decodeMessageTypeTransformers = $decodeMessageTypeTransformers; $this->customEncoders = $customEncoders; } /** * Encode protobuf message as a PHP array * * @param mixed $message * @return array * @throws ValidationException */ public function encodeMessage($message) { $cls = get_class($message); // If we have supplied a customEncoder for this class type, // then we use that instead of the general encodeMessage definition. if (array_key_exists($cls, $this->customEncoders)) { $func = $this->customEncoders[$cls]; return call_user_func($func, $message); } // Get message descriptor $pool = DescriptorPool::getGeneratedPool(); $messageType = $pool->getDescriptorByClassName(get_class($message)); try { return $this->encodeMessageImpl($message, $messageType); } catch (\Exception $e) { throw new ValidationException( 'Error encoding message: ' . $e->getMessage(), $e->getCode(), $e ); } } /** * Decode PHP array into the specified protobuf message * * @param mixed $message * @param array $data * @return mixed * @throws ValidationException */ public function decodeMessage($message, array $data) { // Get message descriptor $pool = DescriptorPool::getGeneratedPool(); $messageType = $pool->getDescriptorByClassName(get_class($message)); try { return $this->decodeMessageImpl($message, $messageType, $data); } catch (\Exception $e) { throw new ValidationException( 'Error decoding message: ' . $e->getMessage(), $e->getCode(), $e ); } } /** * @param Message $message * @return string Json representation of $message * @throws ValidationException */ public static function serializeToJson(Message $message) { return json_encode(self::serializeToPhpArray($message), JSON_PRETTY_PRINT); } /** * @param Message $message * @return array PHP array representation of $message * @throws ValidationException */ public static function serializeToPhpArray(Message $message) { return self::getPhpArraySerializer()->encodeMessage($message); } /** * Decode metadata received from gRPC status object * * @param array $metadata * @return array */ public static function decodeMetadata(array $metadata) { if (count($metadata) == 0) { return []; } $result = []; foreach ($metadata as $key => $values) { foreach ($values as $value) { $decodedValue = [ '@type' => $key, ]; if (self::hasBinaryHeaderSuffix($key)) { if (isset(self::$metadataKnownTypes[$key])) { $class = self::$metadataKnownTypes[$key]; /** @var Message $message */ $message = new $class(); try { $message->mergeFromString($value); $decodedValue += self::serializeToPhpArray($message); } catch (\Exception $e) { // We encountered an error trying to deserialize the data $decodedValue += [ 'data' => '', ]; } } else { // The metadata contains an unexpected binary type $decodedValue += [ 'data' => '', ]; } } else { $decodedValue += [ 'data' => $value, ]; } $result[] = $decodedValue; } } return $result; } /** * Decode an array of Any messages into a printable PHP array. * * @param iterable $anyArray * @return array */ public static function decodeAnyMessages($anyArray) { $results = []; foreach ($anyArray as $any) { try { /** @var Any $any */ /** @var Message $unpacked */ $unpacked = $any->unpack(); $results[] = self::serializeToPhpArray($unpacked); } catch (\Exception $ex) { echo "$ex\n"; // failed to unpack the $any object - show as unknown binary data $results[] = [ 'typeUrl' => $any->getTypeUrl(), 'value' => '', ]; } } return $results; } /** * @param FieldDescriptor $field * @param Message|array|string $data * @return mixed * @throws \Exception */ private function encodeElement(FieldDescriptor $field, $data) { switch ($field->getType()) { case GPBType::MESSAGE: if (is_array($data)) { $result = $data; } else { $result = $this->encodeMessageImpl($data, $field->getMessageType()); } $messageType = $field->getMessageType()->getFullName(); if (isset($this->messageTypeTransformers[$messageType])) { $result = $this->messageTypeTransformers[$messageType]($result); } break; default: $result = $data; break; } if (isset($this->fieldTransformers[$field->getName()])) { $result = $this->fieldTransformers[$field->getName()]($result); } return $result; } private function getDescriptorMaps(Descriptor $descriptor) { if (!isset($this->descriptorMaps[$descriptor->getFullName()])) { $fieldsByName = []; $fieldCount = $descriptor->getFieldCount(); for ($i = 0; $i < $fieldCount; $i++) { $field = $descriptor->getField($i); $fieldsByName[$field->getName()] = $field; } $fieldToOneof = []; $oneofCount = $descriptor->getOneofDeclCount(); for ($i = 0; $i < $oneofCount; $i++) { $oneof = $descriptor->getOneofDecl($i); $oneofFieldCount = $oneof->getFieldCount(); for ($j = 0; $j < $oneofFieldCount; $j++) { $field = $oneof->getField($j); $fieldToOneof[$field->getName()] = $oneof->getName(); } } $this->descriptorMaps[$descriptor->getFullName()] = [$fieldsByName, $fieldToOneof]; } return $this->descriptorMaps[$descriptor->getFullName()]; } /** * @param Message $message * @param Descriptor $messageType * @return array * @throws \Exception */ private function encodeMessageImpl(Message $message, Descriptor $messageType) { $data = []; // Call the getDescriptorMaps outside of the loop to save processing. // Use the same set of fields to loop over, instead of using field count. list($fields, $fieldsToOneof) = $this->getDescriptorMaps($messageType); foreach ($fields as $field) { $key = $field->getName(); $getter = $this->getGetter($key); $v = $message->$getter(); if (is_null($v)) { continue; } // Check and skip unset fields inside oneofs if (isset($fieldsToOneof[$key])) { $oneofName = $fieldsToOneof[$key]; $oneofGetter = $this->getGetter($oneofName); if ($message->$oneofGetter() !== $key) { continue; } } if ($field->isMap()) { list($mapFieldsByName, $_) = $this->getDescriptorMaps($field->getMessageType()); $keyField = $mapFieldsByName[self::MAP_KEY_FIELD_NAME]; $valueField = $mapFieldsByName[self::MAP_VALUE_FIELD_NAME]; $arr = []; foreach ($v as $k => $vv) { $arr[$this->encodeElement($keyField, $k)] = $this->encodeElement($valueField, $vv); } $v = $arr; } elseif ($this->checkFieldRepeated($field)) { $arr = []; foreach ($v as $k => $vv) { $arr[$k] = $this->encodeElement($field, $vv); } $v = $arr; } else { $v = $this->encodeElement($field, $v); } $key = self::toCamelCase($key); $data[$key] = $v; } return $data; } /** * @param FieldDescriptor $field * @param mixed $data * @return mixed * @throws \Exception */ private function decodeElement(FieldDescriptor $field, $data) { if (isset($this->decodeFieldTransformers[$field->getName()])) { $data = $this->decodeFieldTransformers[$field->getName()]($data); } switch ($field->getType()) { case GPBType::MESSAGE: if ($data instanceof Message) { return $data; } $messageType = $field->getMessageType(); $messageTypeName = $messageType->getFullName(); $klass = $messageType->getClass(); $msg = new $klass(); if (isset($this->decodeMessageTypeTransformers[$messageTypeName])) { $data = $this->decodeMessageTypeTransformers[$messageTypeName]($data); } return $this->decodeMessageImpl($msg, $messageType, $data); default: return $data; } } /** * @param Message $message * @param Descriptor $messageType * @param array $data * @return mixed * @throws \Exception */ private function decodeMessageImpl(Message $message, Descriptor $messageType, array $data) { list($fieldsByName, $_) = $this->getDescriptorMaps($messageType); foreach ($data as $key => $v) { // Get the field by tag number or name $fieldName = self::toSnakeCase($key); // Unknown field found if (!isset($fieldsByName[$fieldName])) { throw new RuntimeException(sprintf( 'cannot handle unknown field %s on message %s', $fieldName, $messageType->getFullName() )); } /** @var FieldDescriptor $field */ $field = $fieldsByName[$fieldName]; if ($field->isMap()) { list($mapFieldsByName, $_) = $this->getDescriptorMaps($field->getMessageType()); $keyField = $mapFieldsByName[self::MAP_KEY_FIELD_NAME]; $valueField = $mapFieldsByName[self::MAP_VALUE_FIELD_NAME]; $arr = []; foreach ($v as $k => $vv) { $arr[$this->decodeElement($keyField, $k)] = $this->decodeElement($valueField, $vv); } $value = $arr; } elseif ($this->checkFieldRepeated($field)) { $arr = []; foreach ($v as $k => $vv) { $arr[$k] = $this->decodeElement($field, $vv); } $value = $arr; } else { $value = $this->decodeElement($field, $v); } $setter = $this->getSetter($field->getName()); $message->$setter($value); // We must unset $value here, otherwise the protobuf c extension will mix up the references // and setting one value will change all others unset($value); } return $message; } /** * @param FieldDescriptor $field * @return bool */ private function checkFieldRepeated(FieldDescriptor $field): bool { return method_exists($field, 'isRepeated') ? $field->isRepeated() : $field->getLabel() === GPBLabel::REPEATED; } /** * @param string $name * @return string Getter function */ public static function getGetter(string $name) { if (!isset(self::$getterMap[$name])) { self::$getterMap[$name] = 'get' . ucfirst(self::toCamelCase($name)); } return self::$getterMap[$name]; } /** * @param string $name * @return string Setter function */ public static function getSetter(string $name) { if (!isset(self::$setterMap[$name])) { self::$setterMap[$name] = 'set' . ucfirst(self::toCamelCase($name)); } return self::$setterMap[$name]; } /** * Convert string from camelCase to snake_case * * @param string $key * @return string */ public static function toSnakeCase(string $key) { if (!isset(self::$snakeCaseMap[$key])) { self::$snakeCaseMap[$key] = strtolower( preg_replace(['/([a-z\d])([A-Z])/', '/([^_])([A-Z][a-z])/'], '$1_$2', $key) ); } return self::$snakeCaseMap[$key]; } /** * Convert string from snake_case to camelCase * * @param string $key * @return string */ public static function toCamelCase(string $key) { if (!isset(self::$camelCaseMap[$key])) { self::$camelCaseMap[$key] = lcfirst(str_replace(' ', '', ucwords(str_replace('_', ' ', $key)))); } return self::$camelCaseMap[$key]; } private static function hasBinaryHeaderSuffix(string $key) { return substr_compare($key, '-bin', strlen($key) - 4) === 0; } private static function getPhpArraySerializer() { if (is_null(self::$phpArraySerializer)) { self::$phpArraySerializer = new Serializer(); } return self::$phpArraySerializer; } public static function loadKnownMetadataTypes() { foreach (self::$metadataKnownTypes as $key => $class) { new $class(); } } } // It is necessary to call this when this file is included. Otherwise we cannot be // guaranteed that the relevant classes will be loaded into the protobuf descriptor // pool when we try to unpack an Any object containing that class. // phpcs:disable PSR1.Files.SideEffects Serializer::loadKnownMetadataTypes(); // phpcs:enable ================================================ FILE: lib/Google/vendor/google/gax/src/ServerStream.php ================================================ call = $serverStreamingCall; if (array_key_exists('resourcesGetMethod', $streamingDescriptor)) { $this->resourcesGetMethod = $streamingDescriptor['resourcesGetMethod']; } $this->logger = $logger; } /** * A generator which yields results from the server until the streaming call * completes. Throws an ApiException if the streaming call failed. * * @throws ApiException * @return \Generator|mixed */ public function readAll() { $resourcesGetMethod = $this->resourcesGetMethod; foreach ($this->call->responses() as $response) { if ($this->logger && $response instanceof Message) { $responseEvent = new RpcLogEvent(); $responseEvent->payload = $response->serializeToJsonString(); $responseEvent->processId = (int) getmypid(); $responseEvent->requestId = crc32((string) spl_object_id($this) . getmypid()); $this->logResponse($responseEvent); } if (!is_null($resourcesGetMethod)) { foreach ($response->$resourcesGetMethod() as $resource) { yield $resource; } } else { yield $response; } } // Errors in the REST transport will be thrown from there and not reach // this handling. Successful REST server-streams will have an OK status. $status = $this->call->getStatus(); if ($this->logger) { $statusEvent = new RpcLogEvent(); $statusEvent->status = $status->code; $statusEvent->processId = (int) getmypid(); $statusEvent->requestId = crc32((string) spl_object_id($this) . getmypid()); $this->logResponse($statusEvent); } if ($status->code !== Code::OK) { throw ApiException::createFromStdClass($status); } } /** * Return the underlying call object. * * @return ServerStreamingCallInterface */ public function getServerStreamingCall() { return $this->call; } } ================================================ FILE: lib/Google/vendor/google/gax/src/ServerStreamingCallInterface.php ================================================ $metadata Metadata to send with the call, if applicable * (optional) * @param array $options An array of options, possible keys: * 'flags' => a number (optional) * @return void */ public function start($data, array $metadata = [], array $options = []); /** * @return mixed An iterator of response values. */ public function responses(); /** * Return the status of the server stream. * * @return \stdClass The API status. */ public function getStatus(); /** * @return mixed The metadata sent by the server. */ public function getMetadata(); /** * @return mixed The trailing metadata sent by the server. */ public function getTrailingMetadata(); /** * @return string The URI of the endpoint. */ public function getPeer(); /** * Cancels the call. * * @return void */ public function cancel(); /** * Set the CallCredentials for the underlying Call. * * @param mixed $call_credentials The CallCredentials object * * @return void */ public function setCallCredentials($call_credentials); } ================================================ FILE: lib/Google/vendor/google/gax/src/ServiceAddressTrait.php ================================================ assertSame($expected, $actual); return; } if (is_array($expected) || $expected instanceof RepeatedField) { if (is_array($expected) === is_array($actual)) { $this->assertEquals($expected, $actual); } $this->assertCount(count($expected), $actual); $expectedValues = $this->getValues($expected); $actualValues = $this->getValues($actual); for ($i = 0; $i < count($expectedValues); $i++) { $expectedElement = $expectedValues[$i]; $actualElement = $actualValues[$i]; $this->assertProtobufEquals($expectedElement, $actualElement); } } else { $this->assertEquals($expected, $actual); if ($expected instanceof Message) { $pool = DescriptorPool::getGeneratedPool(); $descriptor = $pool->getDescriptorByClassName(get_class($expected)); $fieldCount = $descriptor->getFieldCount(); for ($i = 0; $i < $fieldCount; $i++) { $field = $descriptor->getField($i); $getter = Serializer::getGetter($field->getName()); $expectedFieldValue = $expected->$getter(); $actualFieldValue = $actual->$getter(); $this->assertProtobufEquals($expectedFieldValue, $actualFieldValue); } } } } /** * @param iterable $field */ private function getValues($field) { return array_values( is_array($field) ? $field : iterator_to_array($field) ); } } ================================================ FILE: lib/Google/vendor/google/gax/src/Testing/MessageAwareArrayComparator.php ================================================ exporter = new MessageAwareExporter(); } } ================================================ FILE: lib/Google/vendor/google/gax/src/Testing/MessageAwareExporter.php ================================================ responses = $responses; $this->deserialize = $deserialize; if (is_null($status)) { $status = new MockStatus(Code::OK); } $this->status = $status; } /** * @return mixed|null * @throws ApiException */ public function read() { if (count($this->responses) > 0) { $resp = array_shift($this->responses); if (is_null($resp)) { // Null was added to the responses list to simulate a failed stream // To ensure that getStatus can now be called, we clear the remaining // responses and set writesDone to true $this->responses = []; $this->writesDone(); return null; } $obj = $this->deserializeMessage($resp, $this->deserialize); return $obj; } elseif ($this->writesDone) { return null; } else { throw new ApiException( 'No more responses to read, but closeWrite() not called - ' . 'this would be blocking', Grpc\STATUS_INTERNAL, null ); } } /** * @return stdClass|null * @throws ApiException */ public function getStatus() { if (count($this->responses) > 0) { throw new ApiException( 'Calls to getStatus() will block if all responses are not read', Grpc\STATUS_INTERNAL, null ); } if (!$this->writesDone) { throw new ApiException( 'Calls to getStatus() will block if closeWrite() not called', Grpc\STATUS_INTERNAL, null ); } return $this->status; } /** * Save the request object, to be retrieved via getReceivedCalls() * @param Message|mixed $request The request object * @param array $options An array of options. * @throws ApiException */ public function write($request, array $options = []) { if ($this->writesDone) { throw new ApiException( 'Cannot call write() after writesDone()', Grpc\STATUS_INTERNAL, null ); } if (is_a($request, '\Google\Protobuf\Internal\Message')) { /** @var Message $newRequest */ $newRequest = new $request(); $newRequest->mergeFromString($request->serializeToString()); $request = $newRequest; } $this->receivedWrites[] = $request; } /** * Set writesDone to true */ public function writesDone() { $this->writesDone = true; } /** * Return a list of calls made to write(), and clear $receivedFuncCalls. * * @return mixed[] An array of received requests */ public function popReceivedCalls() { $receivedFuncCallsTemp = $this->receivedWrites; $this->receivedWrites = []; return $receivedFuncCallsTemp; } } ================================================ FILE: lib/Google/vendor/google/gax/src/Testing/MockClientStreamingCall.php ================================================ mockUnaryCall = new MockUnaryCall($response, $deserialize, $status); } /** * Immediately return the preset response object and status. * @return array The response object and status. */ public function wait() { $this->waitCalled = true; return $this->mockUnaryCall->wait(); } /** * Save the request object, to be retrieved via getReceivedCalls() * @param Message|mixed $request The request object * @param array $options An array of options * @throws ApiException */ public function write($request, array $options = []) { if ($this->waitCalled) { throw new ApiException('Cannot call write() after wait()', Code::INTERNAL, ApiStatus::INTERNAL); } if (is_a($request, '\Google\Protobuf\Internal\Message')) { /** @var Message $newRequest */ $newRequest = new $request(); $newRequest->mergeFromString($request->serializeToString()); $request = $newRequest; } $this->receivedWrites[] = $request; } /** * Return a list of calls made to write(), and clear $receivedFuncCalls. * * @return mixed[] An array of received requests */ public function popReceivedCalls() { $receivedFuncCallsTemp = $this->receivedWrites; $this->receivedWrites = []; return $receivedFuncCallsTemp; } } ================================================ FILE: lib/Google/vendor/google/gax/src/Testing/MockGrpcTransport.php ================================================ mockCall = $mockCall; $opts = ['credentials' => ChannelCredentials::createSsl()]; parent::__construct('', $opts, logger: $logger); } /** * @param string $method * @param array $arguments * @param callable $deserialize */ protected function _simpleRequest( $method, $arguments, $deserialize, array $metadata = [], array $options = [] ) { $this->logCall($method, $deserialize, $metadata, $options, $arguments); return $this->mockCall; } /** * @param string $method * @param callable $deserialize */ protected function _clientStreamRequest( $method, $deserialize, array $metadata = [], array $options = [] ) { $this->logCall($method, $deserialize, $metadata, $options); return $this->mockCall; } /** * @param string $method * @param array $arguments * @param callable $deserialize */ protected function _serverStreamRequest( $method, $arguments, $deserialize, array $metadata = [], array $options = [] ) { $this->logCall($method, $deserialize, $metadata, $options, $arguments); return $this->mockCall; } /** * @param string $method * @param callable $deserialize */ protected function _bidiRequest( $method, $deserialize, array $metadata = [], array $options = [] ) { $this->logCall($method, $deserialize, $metadata, $options); return $this->mockCall; } /** * @param string $method * @param callable $deserialize * @param array $arguments */ private function logCall( $method, $deserialize, array $metadata = [], array $options = [], $arguments = null ) { $this->requestArguments = [ 'method' => $method, 'arguments' => $arguments, 'deserialize' => $deserialize, 'metadata' => $metadata, 'options' => $options, ]; } public function getRequestArguments() { return $this->requestArguments; } } ================================================ FILE: lib/Google/vendor/google/gax/src/Testing/MockRequest.php ================================================ google.apicore.testing.MockRequest * * @internal */ class MockRequest extends \Google\Protobuf\Internal\Message { /** * Generated from protobuf field string page_token = 1; */ protected $page_token = ''; /** * Generated from protobuf field uint64 page_size = 2; */ protected $page_size = 0; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $page_token * @type int|string $page_size * } */ public function __construct($data = null) { Mocks::initOnce(); parent::__construct($data); } /** * Generated from protobuf field string page_token = 1; * @return string */ public function getPageToken() { return $this->page_token; } /** * Generated from protobuf field string page_token = 1; * @param string $var * @return $this */ public function setPageToken($var) { GPBUtil::checkString($var, true); $this->page_token = $var; return $this; } /** * Generated from protobuf field uint64 page_size = 2; * @return int|string */ public function getPageSize() { return $this->page_size; } /** * Generated from protobuf field uint64 page_size = 2; * @param int|string $var * @return $this */ public function setPageSize($var) { GPBUtil::checkUint64($var); $this->page_size = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/gax/src/Testing/MockRequestBody.php ================================================ google.apicore.testing.MockRequestBody * * @internal */ class MockRequestBody extends \Google\Protobuf\Internal\Message { /** * Generated from protobuf field string name = 1; */ protected $name = ''; /** * Generated from protobuf field uint64 number = 2; */ protected $number = 0; /** * Generated from protobuf field repeated string repeated_field = 3; */ private $repeated_field; /** * Generated from protobuf field .google.apicore.testing.MockRequestBody nested_message = 4; */ protected $nested_message = null; /** * Generated from protobuf field .google.protobuf.BytesValue bytes_value = 5; */ protected $bytes_value = null; /** * Generated from protobuf field .google.protobuf.Duration duration_value = 6; */ protected $duration_value = null; /** * Generated from protobuf field .google.protobuf.FieldMask field_mask = 7; */ protected $field_mask = null; /** * Generated from protobuf field .google.protobuf.Int64Value int64_value = 8; */ protected $int64_value = null; /** * Generated from protobuf field .google.protobuf.ListValue list_value = 9; */ protected $list_value = null; /** * Generated from protobuf field .google.protobuf.StringValue string_value = 10; */ protected $string_value = null; /** * Generated from protobuf field .google.protobuf.Struct struct_value = 11; */ protected $struct_value = null; /** * Generated from protobuf field .google.protobuf.Timestamp timestamp_value = 12; */ protected $timestamp_value = null; /** * Generated from protobuf field .google.protobuf.Value value_value = 13; */ protected $value_value = null; protected $oneof_field; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $name * @type int|string $number * @type string[]|\Google\Protobuf\RepeatedField $repeated_field * @type \Google\ApiCore\Testing\MockRequestBody $nested_message * @type \Google\Protobuf\BytesValue $bytes_value * @type \Google\Protobuf\Duration $duration_value * @type \Google\Protobuf\FieldMask $field_mask * @type \Google\Protobuf\Int64Value $int64_value * @type \Google\Protobuf\ListValue $list_value * @type \Google\Protobuf\StringValue $string_value * @type \Google\Protobuf\Struct $struct_value * @type \Google\Protobuf\Timestamp $timestamp_value * @type \Google\Protobuf\Value $value_value * @type string $field_1 * @type string $field_2 * @type string $field_3 * } */ public function __construct($data = null) { \GPBMetadata\ApiCore\Testing\Mocks::initOnce(); parent::__construct($data); } /** * Generated from protobuf field string name = 1; * @return string */ public function getName() { return $this->name; } /** * Generated from protobuf field string name = 1; * @param string $var * @return $this */ public function setName($var) { GPBUtil::checkString($var, true); $this->name = $var; return $this; } /** * Generated from protobuf field uint64 number = 2; * @return int|string */ public function getNumber() { return $this->number; } /** * Generated from protobuf field uint64 number = 2; * @param int|string $var * @return $this */ public function setNumber($var) { GPBUtil::checkUint64($var); $this->number = $var; return $this; } /** * Generated from protobuf field repeated string repeated_field = 3; * @return \Google\Protobuf\RepeatedField */ public function getRepeatedField() { return $this->repeated_field; } /** * Generated from protobuf field repeated string repeated_field = 3; * @param string[]|\Google\Protobuf\RepeatedField $var * @return $this */ public function setRepeatedField($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->repeated_field = $arr; return $this; } /** * Generated from protobuf field .google.apicore.testing.MockRequestBody nested_message = 4; * @return \Google\ApiCore\Testing\MockRequestBody */ public function getNestedMessage() { return isset($this->nested_message) ? $this->nested_message : null; } public function hasNestedMessage() { return isset($this->nested_message); } public function clearNestedMessage() { unset($this->nested_message); } /** * Generated from protobuf field .google.apicore.testing.MockRequestBody nested_message = 4; * @param \Google\ApiCore\Testing\MockRequestBody $var * @return $this */ public function setNestedMessage($var) { GPBUtil::checkMessage($var, \Google\ApiCore\Testing\MockRequestBody::class); $this->nested_message = $var; return $this; } /** * Generated from protobuf field .google.protobuf.BytesValue bytes_value = 5; * @return \Google\Protobuf\BytesValue */ public function getBytesValue() { return isset($this->bytes_value) ? $this->bytes_value : null; } public function hasBytesValue() { return isset($this->bytes_value); } public function clearBytesValue() { unset($this->bytes_value); } /** * Returns the unboxed value from getBytesValue() * Generated from protobuf field .google.protobuf.BytesValue bytes_value = 5; * @return string|null */ public function getBytesValueUnwrapped() { return $this->readWrapperValue('bytes_value'); } /** * Generated from protobuf field .google.protobuf.BytesValue bytes_value = 5; * @param \Google\Protobuf\BytesValue $var * @return $this */ public function setBytesValue($var) { GPBUtil::checkMessage($var, \Google\Protobuf\BytesValue::class); $this->bytes_value = $var; return $this; } /** * Sets the field by wrapping a primitive type in a Google\Protobuf\BytesValue object. * Generated from protobuf field .google.protobuf.BytesValue bytes_value = 5; * @param string|null $var * @return $this */ public function setBytesValueUnwrapped($var) { $this->writeWrapperValue('bytes_value', $var); return $this; } /** * Generated from protobuf field .google.protobuf.Duration duration_value = 6; * @return \Google\Protobuf\Duration */ public function getDurationValue() { return isset($this->duration_value) ? $this->duration_value : null; } public function hasDurationValue() { return isset($this->duration_value); } public function clearDurationValue() { unset($this->duration_value); } /** * Generated from protobuf field .google.protobuf.Duration duration_value = 6; * @param \Google\Protobuf\Duration $var * @return $this */ public function setDurationValue($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Duration::class); $this->duration_value = $var; return $this; } /** * Generated from protobuf field .google.protobuf.FieldMask field_mask = 7; * @return \Google\Protobuf\FieldMask */ public function getFieldMask() { return isset($this->field_mask) ? $this->field_mask : null; } public function hasFieldMask() { return isset($this->field_mask); } public function clearFieldMask() { unset($this->field_mask); } /** * Generated from protobuf field .google.protobuf.FieldMask field_mask = 7; * @param \Google\Protobuf\FieldMask $var * @return $this */ public function setFieldMask($var) { GPBUtil::checkMessage($var, \Google\Protobuf\FieldMask::class); $this->field_mask = $var; return $this; } /** * Generated from protobuf field .google.protobuf.Int64Value int64_value = 8; * @return \Google\Protobuf\Int64Value */ public function getInt64Value() { return isset($this->int64_value) ? $this->int64_value : null; } public function hasInt64Value() { return isset($this->int64_value); } public function clearInt64Value() { unset($this->int64_value); } /** * Returns the unboxed value from getInt64Value() * Generated from protobuf field .google.protobuf.Int64Value int64_value = 8; * @return int|string|null */ public function getInt64ValueUnwrapped() { return $this->readWrapperValue('int64_value'); } /** * Generated from protobuf field .google.protobuf.Int64Value int64_value = 8; * @param \Google\Protobuf\Int64Value $var * @return $this */ public function setInt64Value($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Int64Value::class); $this->int64_value = $var; return $this; } /** * Sets the field by wrapping a primitive type in a Google\Protobuf\Int64Value object. * Generated from protobuf field .google.protobuf.Int64Value int64_value = 8; * @param int|string|null $var * @return $this */ public function setInt64ValueUnwrapped($var) { $this->writeWrapperValue('int64_value', $var); return $this; } /** * Generated from protobuf field .google.protobuf.ListValue list_value = 9; * @return \Google\Protobuf\ListValue */ public function getListValue() { return isset($this->list_value) ? $this->list_value : null; } public function hasListValue() { return isset($this->list_value); } public function clearListValue() { unset($this->list_value); } /** * Generated from protobuf field .google.protobuf.ListValue list_value = 9; * @param \Google\Protobuf\ListValue $var * @return $this */ public function setListValue($var) { GPBUtil::checkMessage($var, \Google\Protobuf\ListValue::class); $this->list_value = $var; return $this; } /** * Generated from protobuf field .google.protobuf.StringValue string_value = 10; * @return \Google\Protobuf\StringValue */ public function getStringValue() { return isset($this->string_value) ? $this->string_value : null; } public function hasStringValue() { return isset($this->string_value); } public function clearStringValue() { unset($this->string_value); } /** * Returns the unboxed value from getStringValue() * Generated from protobuf field .google.protobuf.StringValue string_value = 10; * @return string|null */ public function getStringValueUnwrapped() { return $this->readWrapperValue('string_value'); } /** * Generated from protobuf field .google.protobuf.StringValue string_value = 10; * @param \Google\Protobuf\StringValue $var * @return $this */ public function setStringValue($var) { GPBUtil::checkMessage($var, \Google\Protobuf\StringValue::class); $this->string_value = $var; return $this; } /** * Sets the field by wrapping a primitive type in a Google\Protobuf\StringValue object. * Generated from protobuf field .google.protobuf.StringValue string_value = 10; * @param string|null $var * @return $this */ public function setStringValueUnwrapped($var) { $this->writeWrapperValue('string_value', $var); return $this; } /** * Generated from protobuf field .google.protobuf.Struct struct_value = 11; * @return \Google\Protobuf\Struct */ public function getStructValue() { return isset($this->struct_value) ? $this->struct_value : null; } public function hasStructValue() { return isset($this->struct_value); } public function clearStructValue() { unset($this->struct_value); } /** * Generated from protobuf field .google.protobuf.Struct struct_value = 11; * @param \Google\Protobuf\Struct $var * @return $this */ public function setStructValue($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Struct::class); $this->struct_value = $var; return $this; } /** * Generated from protobuf field .google.protobuf.Timestamp timestamp_value = 12; * @return \Google\Protobuf\Timestamp */ public function getTimestampValue() { return isset($this->timestamp_value) ? $this->timestamp_value : null; } public function hasTimestampValue() { return isset($this->timestamp_value); } public function clearTimestampValue() { unset($this->timestamp_value); } /** * Generated from protobuf field .google.protobuf.Timestamp timestamp_value = 12; * @param \Google\Protobuf\Timestamp $var * @return $this */ public function setTimestampValue($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Timestamp::class); $this->timestamp_value = $var; return $this; } /** * Generated from protobuf field .google.protobuf.Value value_value = 13; * @return \Google\Protobuf\Value */ public function getValueValue() { return isset($this->value_value) ? $this->value_value : null; } public function hasValueValue() { return isset($this->value_value); } public function clearValueValue() { unset($this->value_value); } /** * Generated from protobuf field .google.protobuf.Value value_value = 13; * @param \Google\Protobuf\Value $var * @return $this */ public function setValueValue($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Value::class); $this->value_value = $var; return $this; } /** * Generated from protobuf field string field_1 = 14; * @return string */ public function getField1() { return $this->readOneof(14); } public function hasField1() { return $this->hasOneof(14); } /** * Generated from protobuf field string field_1 = 14; * @param string $var * @return $this */ public function setField1($var) { GPBUtil::checkString($var, true); $this->writeOneof(14, $var); return $this; } /** * Generated from protobuf field string field_2 = 15; * @return string */ public function getField2() { return $this->readOneof(15); } public function hasField2() { return $this->hasOneof(15); } /** * Generated from protobuf field string field_2 = 15; * @param string $var * @return $this */ public function setField2($var) { GPBUtil::checkString($var, true); $this->writeOneof(15, $var); return $this; } /** * Generated from protobuf field string field_3 = 16; * @return string */ public function getField3() { return $this->readOneof(16); } public function hasField3() { return $this->hasOneof(16); } /** * Generated from protobuf field string field_3 = 16; * @param string $var * @return $this */ public function setField3($var) { GPBUtil::checkString($var, true); $this->writeOneof(16, $var); return $this; } /** * @return string */ public function getOneofField() { return $this->whichOneof('oneof_field'); } } ================================================ FILE: lib/Google/vendor/google/gax/src/Testing/MockResponse.php ================================================ google.apicore.testing.MockResponse * * @internal */ class MockResponse extends \Google\Protobuf\Internal\Message { /** * Generated from protobuf field string name = 1; */ protected $name = ''; /** * Generated from protobuf field uint64 number = 2; */ protected $number = 0; /** * Generated from protobuf field repeated string resources_list = 3; */ private $resources_list; /** * Generated from protobuf field string next_page_token = 4; */ protected $next_page_token = ''; /** * Generated from protobuf field map resources_map = 5; */ private $resources_map; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $name * @type int|string $number * @type string[]|\Google\Protobuf\RepeatedField $resources_list * @type string $next_page_token * @type array|\Google\Protobuf\Internal\MapField $resources_map * } */ public function __construct($data = null) { \GPBMetadata\ApiCore\Testing\Mocks::initOnce(); parent::__construct($data); } /** * Generated from protobuf field string name = 1; * @return string */ public function getName() { return $this->name; } /** * Generated from protobuf field string name = 1; * @param string $var * @return $this */ public function setName($var) { GPBUtil::checkString($var, true); $this->name = $var; return $this; } /** * Generated from protobuf field uint64 number = 2; * @return int|string */ public function getNumber() { return $this->number; } /** * Generated from protobuf field uint64 number = 2; * @param int|string $var * @return $this */ public function setNumber($var) { GPBUtil::checkUint64($var); $this->number = $var; return $this; } /** * Generated from protobuf field repeated string resources_list = 3; * @return \Google\Protobuf\RepeatedField */ public function getResourcesList() { return $this->resources_list; } /** * Generated from protobuf field repeated string resources_list = 3; * @param string[]|\Google\Protobuf\RepeatedField $var * @return $this */ public function setResourcesList($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->resources_list = $arr; return $this; } /** * Generated from protobuf field string next_page_token = 4; * @return string */ public function getNextPageToken() { return $this->next_page_token; } /** * Generated from protobuf field string next_page_token = 4; * @param string $var * @return $this */ public function setNextPageToken($var) { GPBUtil::checkString($var, true); $this->next_page_token = $var; return $this; } /** * Generated from protobuf field map resources_map = 5; * @return \Google\Protobuf\Internal\MapField */ public function getResourcesMap() { return $this->resources_map; } /** * Generated from protobuf field map resources_map = 5; * @param array|\Google\Protobuf\Internal\MapField $var * @return $this */ public function setResourcesMap($var) { $arr = GPBUtil::checkMapField($var, \Google\Protobuf\Internal\GPBType::STRING, \Google\Protobuf\Internal\GPBType::STRING); $this->resources_map = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/gax/src/Testing/MockServerStreamingCall.php ================================================ responses = $responses; $this->deserialize = $deserialize; if (is_null($status)) { $status = new MockStatus(Code::OK, 'OK', []); } elseif ($status instanceof stdClass) { if (!property_exists($status, 'metadata')) { $status->metadata = []; } } $this->status = $status; } public function responses() { while (count($this->responses) > 0) { $resp = array_shift($this->responses); $obj = $this->deserializeMessage($resp, $this->deserialize); yield $obj; } } /** * @return stdClass|null * @throws ApiException */ public function getStatus() { if (count($this->responses) > 0) { throw new ApiException( 'Calls to getStatus() will block if all responses are not read', Code::INTERNAL, ApiStatus::INTERNAL ); } return $this->status; } } ================================================ FILE: lib/Google/vendor/google/gax/src/Testing/MockStatus.php ================================================ code = $code; $this->details = $details; $this->metadata = $metadata; } } ================================================ FILE: lib/Google/vendor/google/gax/src/Testing/MockStubTrait.php ================================================ deserialize = $deserialize; } /** * Overrides the _simpleRequest method in \Grpc\BaseStub * (https://github.com/grpc/grpc/blob/master/src/php/lib/Grpc/BaseStub.php) * Returns a MockUnaryCall object that will return the first item from $responses * @param string $method The API method name to be called * @param \Google\Protobuf\Internal\Message $argument The request object to the API method * @param callable $deserialize A function to deserialize the response object * @param array $metadata * @param array $options * @return MockUnaryCall */ public function _simpleRequest( $method, $argument, $deserialize, array $metadata = [], array $options = [] ) { $this->receivedFuncCalls[] = new ReceivedRequest($method, $argument, $deserialize, $metadata, $options); if (count($this->responses) < 1) { throw new UnderflowException('ran out of responses'); } list($response, $status) = array_shift($this->responses); $call = new MockUnaryCall($response, $deserialize, $status); $this->callObjects[] = $call; return $call; } /** * Overrides the _clientStreamRequest method in \Grpc\BaseStub * (https://github.com/grpc/grpc/blob/master/src/php/lib/Grpc/BaseStub.php) * Returns a MockClientStreamingCall object that will return the first item from $responses * * @param string $method The name of the method to call * @param callable $deserialize A function that deserializes the responses * @param array $metadata A metadata map to send to the server * (optional) * @param array $options An array of options (optional) * * @return MockClientStreamingCall The active call object */ public function _clientStreamRequest( $method, $deserialize, array $metadata = [], array $options = [] ) { $this->receivedFuncCalls[] = new ReceivedRequest($method, null, $deserialize, $metadata, $options); if (count($this->responses) < 1) { throw new UnderflowException('ran out of responses'); } list($response, $status) = array_shift($this->responses); $call = new MockClientStreamingCall($response, $deserialize, $status); $this->callObjects[] = $call; return $call; } /** * Overrides the _serverStreamRequest method in \Grpc\BaseStub * (https://github.com/grpc/grpc/blob/master/src/php/lib/Grpc/BaseStub.php) * Returns a MockServerStreamingCall object that will stream items from $responses, and return * a final status of $serverStreamingStatus. * * @param string $method The name of the method to call * @param \Google\Protobuf\Internal\Message $argument The argument to the method * @param callable $deserialize A function that deserializes the responses * @param array $metadata A metadata map to send to the server * (optional) * @param array $options An array of options (optional) * * @return MockServerStreamingCall The active call object */ public function _serverStreamRequest( $method, $argument, $deserialize, array $metadata = [], array $options = [] ) { if (is_a($argument, '\Google\Protobuf\Internal\Message')) { /** @var Message $newArgument */ $newArgument = new $argument(); $newArgument->mergeFromString($argument->serializeToString()); $argument = $newArgument; } $this->receivedFuncCalls[] = new ReceivedRequest($method, $argument, $deserialize, $metadata, $options); $responses = self::stripStatusFromResponses($this->responses); $this->responses = []; $call = new MockServerStreamingCall($responses, $deserialize, $this->serverStreamingStatus); $this->callObjects[] = $call; return $call; } /** * Overrides the _bidiRequest method in \Grpc\BaseStub * (https://github.com/grpc/grpc/blob/master/src/php/lib/Grpc/BaseStub.php) * Returns a MockBidiStreamingCall object that will stream items from $responses, and return * a final status of $serverStreamingStatus. * * @param string $method The name of the method to call * @param callable $deserialize A function that deserializes the responses * @param array $metadata A metadata map to send to the server * (optional) * @param array $options An array of options (optional) * * @return MockBidiStreamingCall The active call object */ public function _bidiRequest( $method, $deserialize, array $metadata = [], array $options = [] ) { $this->receivedFuncCalls[] = new ReceivedRequest($method, null, $deserialize, $metadata, $options); $responses = self::stripStatusFromResponses($this->responses); $this->responses = []; $call = new MockBidiStreamingCall($responses, $deserialize, $this->serverStreamingStatus); $this->callObjects[] = $call; return $call; } public static function stripStatusFromResponses($responses) { $strippedResponses = []; foreach ($responses as $response) { list($resp, $_) = $response; $strippedResponses[] = $resp; } return $strippedResponses; } /** * Add a response object, and an optional status, to the list of responses to be returned via * _simpleRequest. * @param \Google\Protobuf\Internal\Message $response * @param stdClass $status */ public function addResponse($response, ?stdClass $status = null) { if (!$this->deserialize && $response) { $this->deserialize = [get_class($response), 'decode']; } if (is_a($response, '\Google\Protobuf\Internal\Message')) { $response = $response->serializeToString(); } $this->responses[] = [$response, $status]; } /** * Set the status object to be used when creating streaming calls. * * @param stdClass $status */ public function setStreamingStatus(stdClass $status) { $this->serverStreamingStatus = $status; } /** * Return a list of calls made to _simpleRequest, and clear $receivedFuncCalls. * * @return ReceivedRequest[] An array of received requests */ public function popReceivedCalls() { $receivedFuncCallsTemp = $this->receivedFuncCalls; $this->receivedFuncCalls = []; return $receivedFuncCallsTemp; } /** * @return int The number of calls received. */ public function getReceivedCallCount() { return count($this->receivedFuncCalls); } /** * @return mixed[] The call objects created by calls to the stub */ public function popCallObjects() { $callObjectsTemp = $this->callObjects; $this->callObjects = []; return $callObjectsTemp; } /** * @return bool True if $receivedFuncCalls and $response are empty. */ public function isExhausted() { return count($this->receivedFuncCalls) === 0 && count($this->responses) === 0; } /** * @param mixed $responseObject * @param stdClass|null $status * @param callable $deserialize * @return static An instance of the current class type. */ public static function create($responseObject, ?stdClass $status = null, ?callable $deserialize = null) { $stub = new static($deserialize); // @phpstan-ignore-line $stub->addResponse($responseObject, $status); return $stub; } /** * Creates a sequence such that the responses are returned in order. * @param mixed[] $sequence * @param callable $deserialize * @param stdClass $finalStatus * @return static An instance of the current class type. */ public static function createWithResponseSequence(array $sequence, ?callable $deserialize = null, ?stdClass $finalStatus = null) { $stub = new static($deserialize); // @phpstan-ignore-line foreach ($sequence as $elem) { if (count($elem) == 1) { list($resp, $status) = [$elem, null]; } else { list($resp, $status) = $elem; } $stub->addResponse($resp, $status); } if ($finalStatus) { $stub->setStreamingStatus($finalStatus); } return $stub; } } ================================================ FILE: lib/Google/vendor/google/gax/src/Testing/MockTransport.php ================================================ agentHeaderDescriptor = $agentHeaderDescriptor; } public function startUnaryCall(Call $call, array $options) { $call = call_user_func([$this, $call->getMethod()], $call, $options); return $promise = new Promise( function () use ($call, &$promise) { list($response, $status) = $call->wait(); if ($status->code == Code::OK) { $promise->resolve($response); } else { throw ApiException::createFromStdClass($status); } }, [$call, 'cancel'] ); } public function startBidiStreamingCall(Call $call, array $options) { $newArgs = ['/' . $call->getMethod(), $this->deserialize, $options, $options]; $response = $this->_bidiRequest(...$newArgs); return new BidiStream($response, $call->getDescriptor()); } public function startClientStreamingCall(Call $call, array $options) { $newArgs = ['/' . $call->getMethod(), $this->deserialize, $options, $options]; $response = $this->_clientStreamRequest(...$newArgs); return new ClientStream($response, $call->getDescriptor()); } public function startServerStreamingCall(Call $call, array $options) { $newArgs = ['/' . $call->getMethod(), $call->getMessage(), $this->deserialize, $options, $options]; $response = $this->_serverStreamRequest(...$newArgs); return new ServerStream($response, $call->getDescriptor()); } public function __call(string $name, array $arguments) { $call = $arguments[0]; $options = $arguments[1]; $decode = $call->getDecodeType() ? [$call->getDecodeType(), 'decode'] : null; return $this->_simpleRequest( '/' . $call->getMethod(), $call->getMessage(), $decode, isset($options['headers']) ? $options['headers'] : [], $options ); } public function close() { // does nothing } } ================================================ FILE: lib/Google/vendor/google/gax/src/Testing/MockUnaryCall.php ================================================ response = $response; $this->deserialize = $deserialize; if (is_null($status)) { $status = new MockStatus(Code::OK); } $this->status = $status; } /** * Immediately return the preset response object and status. * @return array The response object and status. */ public function wait() { return [ $this->deserializeMessage($this->response, $this->deserialize), $this->status, ]; } } ================================================ FILE: lib/Google/vendor/google/gax/src/Testing/ProtobufGPBEmptyComparator.php ================================================ exporter = new MessageAwareExporter(); } /** * Returns whether the comparator can compare two values. * * @param mixed $expected The first value to compare * @param mixed $actual The second value to compare * @return boolean */ public function accepts($expected, $actual) { return $expected instanceof Message && $actual instanceof Message; } /** * Asserts that two values are equal. * * @param Message $expected The first value to compare * @param Message $actual The second value to compare * @param float|int $delta The allowed numerical distance between two values to * consider them equal * @param bool $canonicalize If set to TRUE, arrays are sorted before * comparison * @param bool $ignoreCase If set to TRUE, upper- and lowercasing is * ignored when comparing string values * @throws ComparisonFailure Thrown when the comparison * fails. Contains information about the * specific errors that lead to the failure. */ public function assertEquals($expected, $actual, $delta = 0, $canonicalize = false, $ignoreCase = false) { if ($expected->serializeToString() !== $actual->serializeToString()) { throw new ComparisonFailure( $expected, $actual, $this->exporter->shortenedExport($expected), $this->exporter->shortenedExport($actual), false, 'Given 2 Message objects are not the same' ); } } } ================================================ FILE: lib/Google/vendor/google/gax/src/Testing/ReceivedRequest.php ================================================ actualCall = [ 'funcCall' => $funcCall, 'request' => $requestObject, 'deserialize' => $deserialize, 'metadata' => $metadata, 'options' => $options, ]; } public function getArray() { return $this->actualCall; } public function getFuncCall() { return $this->actualCall['funcCall']; } public function getRequestObject() { return $this->actualCall['request']; } public function getMetadata() { return $this->actualCall['metadata']; } public function getOptions() { return $this->actualCall['options']; } } ================================================ FILE: lib/Google/vendor/google/gax/src/Testing/SerializationTrait.php ================================================ $deserializeFunc($message); } elseif (is_string($message)) { $obj->mergeFromString($message); } return $obj; } // Protobuf-PHP implementation return call_user_func($deserialize, $message); } } ================================================ FILE: lib/Google/vendor/google/gax/src/Testing/mocks.proto ================================================ syntax = "proto3"; package google.apicore.testing; import "google/protobuf/field_mask.proto"; import "google/protobuf/timestamp.proto"; import "google/protobuf/duration.proto"; import "google/protobuf/struct.proto"; import "google/protobuf/wrappers.proto"; option php_namespace = "Google\\ApiCore\\Testing"; option php_metadata_namespace = "GPBMetadata\\ApiCore\\Testing"; message MockRequest { string page_token = 1; uint64 page_size = 2; } message MockResponse { string name = 1; uint64 number = 2; repeated string resources_list = 3; string next_page_token = 4; map resources_map = 5; } message MockRequestBody { string name = 1; uint64 number = 2; repeated string repeated_field = 3; MockRequestBody nested_message = 4; google.protobuf.BytesValue bytes_value = 5; google.protobuf.Duration duration_value = 6; google.protobuf.FieldMask field_mask = 7; google.protobuf.Int64Value int64_value = 8; google.protobuf.ListValue list_value = 9; google.protobuf.StringValue string_value = 10; google.protobuf.Struct struct_value = 11; google.protobuf.Timestamp timestamp_value = 12; google.protobuf.Value value_value = 13; oneof oneof_field { string field_1 = 14; string field_2 = 15; string field_3 = 16; } } ================================================ FILE: lib/Google/vendor/google/gax/src/Transport/Grpc/ForwardingCall.php ================================================ innerCall = $innerCall; } /** * @return mixed The metadata sent by the server */ public function getMetadata() { return $this->innerCall->getMetadata(); } /** * @return mixed The trailing metadata sent by the server */ public function getTrailingMetadata() { return $this->innerCall->getTrailingMetadata(); } /** * @return string The URI of the endpoint */ public function getPeer() { return $this->innerCall->getPeer(); } /** * Cancels the call. */ public function cancel() { $this->innerCall->cancel(); } } ================================================ FILE: lib/Google/vendor/google/gax/src/Transport/Grpc/ForwardingServerStreamingCall.php ================================================ innerCall->responses(); } /** * Wait for the server to send the status, and return it. * * @return \stdClass The status object, with integer $code, string * $details, and array $metadata members */ public function getStatus() { return $this->innerCall->getStatus(); } } ================================================ FILE: lib/Google/vendor/google/gax/src/Transport/Grpc/ForwardingUnaryCall.php ================================================ innerCall->wait(); } } ================================================ FILE: lib/Google/vendor/google/gax/src/Transport/Grpc/ServerStreamingCallWrapper.php ================================================ stream = $stream; } /** * {@inheritdoc} */ public function start($data, array $metadata = [], array $callOptions = []) { $this->stream->start($data, $metadata, $callOptions); } /** * {@inheritdoc} */ public function responses() { foreach ($this->stream->responses() as $response) { yield $response; } } /** * {@inheritdoc} */ public function getStatus() { return $this->stream->getStatus(); } /** * {@inheritdoc} */ public function getMetadata() { return $this->stream->getMetadata(); } /** * {@inheritdoc} */ public function getTrailingMetadata() { return $this->stream->getTrailingMetadata(); } /** * {@inheritdoc} */ public function getPeer() { return $this->stream->getPeer(); } /** * {@inheritdoc} */ public function cancel() { $this->stream->cancel(); } /** * {@inheritdoc} */ public function setCallCredentials($call_credentials) { $this->stream->setCallCredentials($call_credentials); } } ================================================ FILE: lib/Google/vendor/google/gax/src/Transport/Grpc/UnaryInterceptorInterface.php ================================================ baseUri = $baseUri; $this->httpHandler = $httpHandler; $this->transportName = 'grpc-fallback'; } /** * Builds a GrpcFallbackTransport. * * @param string $apiEndpoint * The address of the API remote host, for example "example.googleapis.com". * @param array $config { * Config options used to construct the grpc-fallback transport. * * @type callable $httpHandler A handler used to deliver PSR-7 requests. * } * @return GrpcFallbackTransport * @throws ValidationException */ public static function build(string $apiEndpoint, array $config = []) { $config += [ 'httpHandler' => null, 'clientCertSource' => null, 'logger' => null, ]; list($baseUri, $port) = self::normalizeServiceAddress($apiEndpoint); $httpHandler = $config['httpHandler'] ?: self::buildHttpHandlerAsync(logger: $config['logger']); $transport = new GrpcFallbackTransport("$baseUri:$port", $httpHandler); if ($config['clientCertSource']) { $transport->configureMtlsChannel($config['clientCertSource']); } return $transport; } /** * {@inheritdoc} */ public function startUnaryCall(Call $call, array $options) { $httpHandler = $this->httpHandler; $options['requestId'] = crc32((string) spl_object_id($call) . getmypid()); return $httpHandler( $this->buildRequest($call, $options), $this->getCallOptions($options) )->then( function (ResponseInterface $response) use ($options) { if (isset($options['metadataCallback'])) { $metadataCallback = $options['metadataCallback']; $metadataCallback($response->getHeaders()); } return $response; } )->then( function (ResponseInterface $response) use ($call) { return $this->unpackResponse($call, $response); }, function (\Exception $ex) { throw $this->transformException($ex); } ); } /** * @param Call $call * @param array $options * @return RequestInterface */ private function buildRequest(Call $call, array $options) { // Build common headers and set the content type to 'application/x-protobuf' $headers = ['Content-Type' => 'application/x-protobuf'] + self::buildCommonHeaders($options); // It is necessary to supply 'grpc-web' in the 'x-goog-api-client' header // when using the grpc-fallback protocol. $headers += ['x-goog-api-client' => []]; $headers['x-goog-api-client'][] = 'grpc-web'; // Uri format: https:///$rpc/ $uri = "https://{$this->baseUri}/\$rpc/{$call->getMethod()}"; return new Request( 'POST', $uri, $headers, $call->getMessage()->serializeToString() ); } /** * @param Call $call * @param ResponseInterface $response * @return Message */ private function unpackResponse(Call $call, ResponseInterface $response) { $decodeType = $call->getDecodeType(); /** @var Message $responseMessage */ $responseMessage = new $decodeType(); $responseMessage->mergeFromString((string) $response->getBody()); return $responseMessage; } /** * @param array $options * @return array */ private function getCallOptions(array $options) { $callOptions = $options['transportOptions']['grpcFallbackOptions'] ?? []; if (isset($options['timeoutMillis'])) { $callOptions['timeout'] = $options['timeoutMillis'] / 1000; } if (isset($options['retryAttempt'])) { $callOptions['retryAttempt'] = $options['retryAttempt']; } if (isset($options['requestId'])) { $callOptions['requestId'] = $options['requestId']; } if ($this->clientCertSource) { list($cert, $key) = self::loadClientCertSource($this->clientCertSource); $callOptions['cert'] = $cert; $callOptions['key'] = $key; } return $callOptions; } /** * @param \Exception $ex * @return \Exception */ private function transformException(\Exception $ex) { if ($ex instanceof RequestException && $ex->hasResponse()) { $res = $ex->getResponse(); $body = (string) $res->getBody(); $status = new Status(); try { $status->mergeFromString($body); return ApiException::createFromRpcStatus($status); } catch (\Exception $parseException) { // We were unable to parse the response body into a $status object. Instead, // create an ApiException using the unparsed $body as message. $code = ApiStatus::rpcCodeFromHttpStatusCode($res->getStatusCode()); return ApiException::createFromApiResponse($body, $code, null, $parseException); } } else { return $ex; } } } ================================================ FILE: lib/Google/vendor/google/gax/src/Transport/GrpcTransport.php ================================================ logger = $logger; } /** * Builds a GrpcTransport. * * @param string $apiEndpoint * The address of the API remote host, for example "example.googleapis.com. May also * include the port, for example "example.googleapis.com:443" * @param array $config { * Config options used to construct the gRPC transport. * * @type array $stubOpts Options used to construct the gRPC stub (see * {@link https://grpc.github.io/grpc/core/group__grpc__arg__keys.html}). * @type Channel $channel Grpc channel to be used. * @type Interceptor[]|UnaryInterceptorInterface[] $interceptors *EXPERIMENTAL* * Interceptors used to intercept RPC invocations before a call starts. * Please note that implementations of * {@see \Google\ApiCore\Transport\Grpc\UnaryInterceptorInterface} are * considered deprecated and support will be removed in a future * release. To prepare for this, please take the time to convert * `UnaryInterceptorInterface` implementations over to a class which * extends {@see Grpc\Interceptor}. * @type callable $clientCertSource A callable which returns the client cert as a string. * } * @return GrpcTransport * @throws ValidationException */ public static function build(string $apiEndpoint, array $config = []) { self::validateGrpcSupport(); $config += [ 'stubOpts' => [], 'channel' => null, 'interceptors' => [], 'clientCertSource' => null, 'logger' => null, ]; list($addr, $port) = self::normalizeServiceAddress($apiEndpoint); $host = "$addr:$port"; $stubOpts = $config['stubOpts']; // Set the required 'credentials' key in stubOpts if it is not already set. Use // array_key_exists because null is a valid value. if (!array_key_exists('credentials', $stubOpts)) { if (isset($config['clientCertSource'])) { list($cert, $key) = self::loadClientCertSource($config['clientCertSource']); $stubOpts['credentials'] = ChannelCredentials::createSsl(null, $key, $cert); } else { $stubOpts['credentials'] = ChannelCredentials::createSsl(); } } $channel = $config['channel']; if (!is_null($channel) && !($channel instanceof Channel)) { throw new ValidationException( "Channel argument to GrpcTransport must be of type \Grpc\Channel, " . 'instead got: ' . print_r($channel, true) ); } try { if ($config['logger'] === false) { $config['logger'] = null; } return new GrpcTransport($host, $stubOpts, $channel, $config['interceptors'], $config['logger']); } catch (Exception $ex) { throw new ValidationException( 'Failed to build GrpcTransport: ' . $ex->getMessage(), $ex->getCode(), $ex ); } } /** * {@inheritdoc} */ public function startBidiStreamingCall(Call $call, array $options) { $this->verifyUniverseDomain($options); $bidiStream = new BidiStream( $this->_bidiRequest( '/' . $call->getMethod(), [$call->getDecodeType(), 'decode'], isset($options['headers']) ? $options['headers'] : [], $this->getCallOptions($options) ), $call->getDescriptor(), $this->logger ); if ($this->logger) { $requestEvent = new RpcLogEvent(); $requestEvent->headers = $options['headers'] ?? []; $requestEvent->retryAttempt = $options['retryAttempt'] ?? null; $requestEvent->serviceName = $options['serviceName'] ?? null; $requestEvent->rpcName = $call->getMethod(); $requestEvent->processId = (int) getmypid(); $requestEvent->requestId = crc32((string) spl_object_id($bidiStream) . getmypid()); $this->logRequest($requestEvent); } return $bidiStream; } /** * {@inheritdoc} */ public function startClientStreamingCall(Call $call, array $options) { $this->verifyUniverseDomain($options); return new ClientStream( $this->_clientStreamRequest( '/' . $call->getMethod(), [$call->getDecodeType(), 'decode'], isset($options['headers']) ? $options['headers'] : [], $this->getCallOptions($options) ), $call->getDescriptor(), $this->logger ); } /** * {@inheritdoc} */ public function startServerStreamingCall(Call $call, array $options) { $this->verifyUniverseDomain($options); $message = $call->getMessage(); if (!$message) { throw new \InvalidArgumentException('A message is required for ServerStreaming calls.'); } // This simultaenously creates and starts a \Grpc\ServerStreamingCall. $stream = $this->_serverStreamRequest( '/' . $call->getMethod(), $message, [$call->getDecodeType(), 'decode'], isset($options['headers']) ? $options['headers'] : [], $this->getCallOptions($options) ); $serverStream = new ServerStream( new ServerStreamingCallWrapper($stream), $call->getDescriptor(), $this->logger ); if ($this->logger) { $requestEvent = new RpcLogEvent(); $requestEvent->headers = $options['headers']; $requestEvent->payload = $call->getMessage()->serializeToJsonString(); $requestEvent->retryAttempt = $options['retryAttempt'] ?? null; $requestEvent->serviceName = $options['serviceName'] ?? null; $requestEvent->rpcName = $call->getMethod(); $requestEvent->processId = (int) getmypid(); $requestEvent->requestId = crc32((string) spl_object_id($serverStream) . getmypid()); $this->logRequest($requestEvent); } return $serverStream; } /** * {@inheritdoc} */ public function startUnaryCall(Call $call, array $options) { $this->verifyUniverseDomain($options); $headers = $options['headers'] ?? []; $requestEvent = null; $unaryCall = $this->_simpleRequest( '/' . $call->getMethod(), $call->getMessage(), [$call->getDecodeType(), 'decode'], isset($options['headers']) ? $options['headers'] : [], $this->getCallOptions($options) ); if ($this->logger) { $requestEvent = new RpcLogEvent(); $requestEvent->headers = $headers; $requestEvent->payload = $call->getMessage()->serializeToJsonString(); $requestEvent->retryAttempt = $options['retryAttempt'] ?? null; $requestEvent->serviceName = $options['serviceName'] ?? null; $requestEvent->rpcName = $call->getMethod(); $requestEvent->processId = (int) getmypid(); $requestEvent->requestId = crc32((string) spl_object_id($call) . getmypid()); $this->logRequest($requestEvent); } /** @var Promise $promise */ $promise = new Promise( function () use ($unaryCall, $options, &$promise, $requestEvent) { list($response, $status) = $unaryCall->wait(); if ($this->logger) { $responseEvent = new RpcLogEvent($requestEvent->milliseconds); $responseEvent->headers = $status->metadata; $responseEvent->payload = ($response) ? $response->serializeToJsonString() : null; $responseEvent->status = $status->code; $responseEvent->processId = $requestEvent->processId; $responseEvent->requestId = $requestEvent->requestId; $this->logResponse($responseEvent); } if ($status->code == Code::OK) { if (isset($options['metadataCallback'])) { $metadataCallback = $options['metadataCallback']; $metadataCallback($unaryCall->getMetadata()); } $promise->resolve($response); } else { throw ApiException::createFromStdClass($status); } }, [$unaryCall, 'cancel'] ); return $promise; } private function verifyUniverseDomain(array $options) { if (isset($options['credentialsWrapper'])) { $options['credentialsWrapper']->checkUniverseDomain(); } } private function getCallOptions(array $options) { $callOptions = $options['transportOptions']['grpcOptions'] ?? []; if (isset($options['credentialsWrapper'])) { $audience = $options['audience'] ?? null; $credentialsWrapper = $options['credentialsWrapper']; $callOptions['call_credentials_callback'] = $credentialsWrapper ->getAuthorizationHeaderCallback($audience); } if (isset($options['timeoutMillis'])) { $callOptions['timeout'] = $options['timeoutMillis'] * 1000; } return $callOptions; } private static function loadClientCertSource(callable $clientCertSource) { return call_user_func($clientCertSource); } } ================================================ FILE: lib/Google/vendor/google/gax/src/Transport/HttpUnaryTransportTrait.php ================================================ throwUnsupportedException(); } /** * {@inheritdoc} * @return never * @throws \BadMethodCallException */ public function startServerStreamingCall(Call $call, array $options) { $this->throwUnsupportedException(); } /** * {@inheritdoc} * @return never * @throws \BadMethodCallException */ public function startBidiStreamingCall(Call $call, array $options) { $this->throwUnsupportedException(); } /** * {@inheritdoc} */ public function close() { // Nothing to do. } /** * @param array $options * @return array */ private static function buildCommonHeaders(array $options) { $headers = $options['headers'] ?? []; if (!is_array($headers)) { throw new \InvalidArgumentException( 'The "headers" option must be an array' ); } // If not already set, add an auth header to the request if (!isset($headers['Authorization']) && isset($options['credentialsWrapper'])) { $credentialsWrapper = $options['credentialsWrapper']; $audience = $options['audience'] ?? null; $callback = $credentialsWrapper ->getAuthorizationHeaderCallback($audience); // Prevent unexpected behavior, as the authorization header callback // uses lowercase "authorization" unset($headers['authorization']); // Mitigate scenario where InsecureCredentialsWrapper returns null. $authHeaders = empty($callback) ? [] : $callback(); if (!is_array($authHeaders)) { throw new \UnexpectedValueException( 'Expected array response from authorization header callback' ); } $headers += $authHeaders; } return $headers; } /** * @return callable * @throws ValidationException */ private static function buildHttpHandlerAsync(null|false|LoggerInterface $logger = null) { try { return [HttpHandlerFactory::build(logger: $logger), 'async']; } catch (Exception $ex) { throw new ValidationException('Failed to build HttpHandler', $ex->getCode(), $ex); } } /** * Set the path to a client certificate. * * @param callable $clientCertSource */ private function configureMtlsChannel(callable $clientCertSource) { $this->clientCertSource = $clientCertSource; } /** * @return never * @throws \BadMethodCallException */ private function throwUnsupportedException() { throw new \BadMethodCallException( "Streaming calls are not supported while using the {$this->transportName} transport." ); } private static function loadClientCertSource(callable $clientCertSource) { $certFile = tempnam(sys_get_temp_dir(), 'cert'); $keyFile = tempnam(sys_get_temp_dir(), 'key'); list($cert, $key) = call_user_func($clientCertSource); file_put_contents($certFile, $cert); file_put_contents($keyFile, $key); // the key and the cert are returned in one temporary file return [$certFile, $keyFile]; } } ================================================ FILE: lib/Google/vendor/google/gax/src/Transport/Rest/JsonStreamDecoder.php ================================================ $options { * An array of optional arguments. * * @type bool $ignoreUnknown * Toggles whether or not to throw an exception when an unknown field * is encountered in a response message. The default is true. * @type int $readChunkSizeBytes * The upper size limit in bytes that can be read at a time from the * response stream. The default is 1 KB. * } * * @experimental */ public function __construct(StreamInterface $stream, string $decodeType, array $options = []) { $this->stream = $stream; $this->decodeType = $decodeType; if (isset($options['ignoreUnknown'])) { $this->ignoreUnknown = $options['ignoreUnknown']; } if (isset($options['readChunkSize'])) { $this->readChunkSize = $options['readChunkSizeBytes']; } } /** * Begins decoding the configured response stream. It is a generator which * yields messages of the given decode type from the stream until the stream * completes. Throws an Exception if the stream is closed before the closing * byte is read or if it encounters an error while decoding a message. * * @throws RuntimeException * @return \Generator */ public function decode() { try { foreach ($this->_decode() as $response) { yield $response; } } catch (RuntimeException $re) { $msg = $re->getMessage(); $streamClosedException = strpos($msg, 'Stream is detached') !== false || strpos($msg, 'Unexpected stream close') !== false; // Only throw the exception if close() was not called and it was not // a closing-related exception. if (!$this->closeCalled || !$streamClosedException) { throw $re; } } } /** * @return \Generator */ private function _decode() { $decodeType = $this->decodeType; $str = false; $prev = $chunk = ''; $start = $end = $cursor = $level = 0; while ($chunk !== '' || !$this->stream->eof()) { // Read up to $readChunkSize bytes from the stream. $chunk .= $this->stream->read($this->readChunkSize); // If the response stream has been closed and the only byte // remaining is the closing array bracket, we are done. if ($this->stream->eof() && $chunk === ']') { $level--; break; } // Parse the freshly read data available in $chunk. $chunkLength = strlen($chunk); while ($cursor < $chunkLength) { // Access the next byte for processing. $b = $chunk[$cursor]; // Track open/close double quotes of a key or value. Do not // toggle flag with the pervious byte was an escape character. if ($b === '"' && $prev !== self::ESCAPE_CHAR) { $str = !$str; } // Skip over new lines that break up items. if ($b === "\n" && $level === 1) { $start++; } // Ignore commas separating messages in the stream array. if ($b === ',' && $level === 1) { $start++; } // Track the opening of a new array or object if not in a string // value. if (($b === '{' || $b === '[') && !$str) { $level++; // Opening of the array/root object. // Do not include it in the messageBuffer. if ($level === 1) { $start++; } } // Track the closing of an object if not in a string value. if ($b === '}' && !$str) { $level--; if ($level === 1) { $end = $cursor + 1; } } // Track the closing of an array if not in a string value. if ($b === ']' && !$str) { $level--; // If we are seeing a closing square bracket at the // response message level, e.g. {"foo], there is a problem. if ($level === 1) { throw new \RuntimeException('Received closing byte mid-message'); } } // A message-closing byte was just buffered. Decode the // message with the decode type, clearing the messageBuffer, // and yield it. // // TODO(noahdietz): Support google.protobuf.*Value messages that // are encoded as primitives and separated by commas. if ($end !== 0) { $length = $end - $start; /** @var \Google\Protobuf\Internal\Message $return */ $return = new $decodeType(); $return->mergeFromJsonString( substr($chunk, $start, $length), $this->ignoreUnknown ); yield $return; // Dump the part of the chunk used for parsing the message // and use the remaining for the next message. $remaining = $chunkLength - $length; $chunk = substr($chunk, $end, $remaining); // Reset all indices and exit chunk processing. $start = 0; $end = 0; $cursor = 0; break; } $cursor++; // An escaped back slash should not escape the following character. if ($b === self::ESCAPE_CHAR && $prev === self::ESCAPE_CHAR) { $b = ''; } $prev = $b; } // If after attempting to process the chunk, no progress was made and the // stream is closed, we must break as the stream has closed prematurely. if ($cursor === $chunkLength && $this->stream->eof()) { break; } } if ($level > 0) { throw new \RuntimeException('Unexpected stream close before receiving the closing byte'); } } /** * Closes the underlying stream. If the stream is actively being decoded, an * exception will not be thrown due to the interruption. * * @return void */ public function close() { $this->closeCalled = true; $this->stream->close(); } } ================================================ FILE: lib/Google/vendor/google/gax/src/Transport/Rest/RestServerStreamingCall.php ================================================ */ private array $decoderOptions; private RequestInterface $originalRequest; private ?JsonStreamDecoder $decoder; private string $decodeType; private ?ResponseInterface $response; private stdClass $status; /** * @param callable $httpHandler * @param string $decodeType * @param array $decoderOptions */ public function __construct(callable $httpHandler, string $decodeType, array $decoderOptions) { $this->httpHandler = $httpHandler; $this->decodeType = $decodeType; $this->decoderOptions = $decoderOptions; } /** * {@inheritdoc} */ public function start($request, array $headers = [], array $callOptions = []) { $this->originalRequest = $this->appendHeaders($request, $headers); try { $handler = $this->httpHandler; $response = $handler( $this->originalRequest, $callOptions )->wait(); } catch (\Exception $ex) { if ($ex instanceof RequestException && $ex->hasResponse()) { $ex = ApiException::createFromRequestException($ex, /* isStream */ true); } throw $ex; } // Create an OK Status for a successful request just so that it // has a return value. $this->status = new stdClass(); $this->status->code = Code::OK; $this->status->message = ApiStatus::OK; $this->status->details = []; $this->response = $response; } /** * @param RequestInterface $request * @param array $headers * @return RequestInterface */ private function appendHeaders(RequestInterface $request, array $headers) { foreach ($headers as $key => $value) { $request = $request->hasHeader($key) ? $request->withAddedHeader($key, $value) : $request->withHeader($key, $value); } return $request; } /** * {@inheritdoc} */ public function responses() { if (is_null($this->response)) { throw new \Exception('Stream has not been started.'); } // Decode the stream and yield responses as they are read. $this->decoder = new JsonStreamDecoder( $this->response->getBody(), $this->decodeType, $this->decoderOptions ); foreach ($this->decoder->decode() as $message) { yield $message; } } /** * Return the status of the server stream. If the call has not been started * this will be null. * * @return stdClass The status, with integer $code, string * $details, and array $metadata members */ public function getStatus() { return $this->status; } /** * {@inheritdoc} */ public function getMetadata() { return is_null($this->response) ? null : $this->response->getHeaders(); } /** * The Rest transport does not support trailing metadata. This is a * passthrough to getMetadata(). */ public function getTrailingMetadata() { return $this->getMetadata(); } /** * {@inheritdoc} */ public function getPeer() { return $this->originalRequest->getUri(); } /** * {@inheritdoc} */ public function cancel() { if (!is_null($this->decoder)) { $this->decoder->close(); } } /** * For the REST transport this is a no-op. * {@inheritdoc} */ public function setCallCredentials($call_credentials) { // Do nothing. } } ================================================ FILE: lib/Google/vendor/google/gax/src/Transport/RestTransport.php ================================================ requestBuilder = $requestBuilder; $this->httpHandler = $httpHandler; $this->transportName = 'REST'; } /** * Builds a RestTransport. * * @param string $apiEndpoint * The address of the API remote host, for example "example.googleapis.com". * @param string $restConfigPath * Path to rest config file. * @param array $config { * Config options used to construct the gRPC transport. * * @type callable $httpHandler A handler used to deliver PSR-7 requests. * @type callable $clientCertSource A callable which returns the client cert as a string. * @type bool $hasEmulator True if the emulator is enabled. * } * @return RestTransport * @throws ValidationException */ public static function build(string $apiEndpoint, string $restConfigPath, array $config = []) { $config += [ 'httpHandler' => null, 'clientCertSource' => null, 'hasEmulator' => false, 'logger' => null, ]; list($baseUri, $port) = self::normalizeServiceAddress($apiEndpoint); $requestBuilder = $config['hasEmulator'] ? new InsecureRequestBuilder("$baseUri:$port", $restConfigPath) : new RequestBuilder("$baseUri:$port", $restConfigPath); $httpHandler = $config['httpHandler'] ?: self::buildHttpHandlerAsync($config['logger']); $transport = new RestTransport($requestBuilder, $httpHandler); if ($config['clientCertSource']) { $transport->configureMtlsChannel($config['clientCertSource']); } return $transport; } /** * {@inheritdoc} */ public function startUnaryCall(Call $call, array $options) { $headers = self::buildCommonHeaders($options); // Add the $call object ID for logging $options['requestId'] = crc32((string) spl_object_id($call) . getmypid()); // call the HTTP handler $httpHandler = $this->httpHandler; return $httpHandler( $this->requestBuilder->build( $call->getMethod(), $call->getMessage(), $headers ), $this->getCallOptions($options) )->then( function (ResponseInterface $response) use ($call, $options) { $decodeType = $call->getDecodeType(); /** @var Message $return */ $return = new $decodeType(); $body = (string) $response->getBody(); // In some rare cases LRO response metadata may not be loaded // in the descriptor pool, triggering an exception. The catch // statement handles this case and attempts to add the LRO // metadata type to the pool by directly instantiating the // metadata class. try { $return->mergeFromJsonString( $body, true ); } catch (\Exception $ex) { if (!isset($options['metadataReturnType'])) { throw $ex; } if (strpos($ex->getMessage(), 'Error occurred during parsing:') !== 0) { throw $ex; } new $options['metadataReturnType'](); $return->mergeFromJsonString( $body, true ); } if (isset($options['metadataCallback'])) { $metadataCallback = $options['metadataCallback']; $metadataCallback($response->getHeaders()); } return $return; }, function (\Throwable $ex) { if ($ex instanceof RequestException && $ex->hasResponse()) { throw ApiException::createFromRequestException($ex); } throw $ex; } ); } /** * {@inheritdoc} * @throws \BadMethodCallException for forwards compatibility with older GAPIC clients */ public function startServerStreamingCall(Call $call, array $options) { $message = $call->getMessage(); if (!$message) { throw new \InvalidArgumentException('A message is required for ServerStreaming calls.'); } // Maintain forwards compatibility with older GAPIC clients not configured for REST server streaming // @see https://github.com/googleapis/gax-php/issues/370 if (!$this->requestBuilder->pathExists($call->getMethod())) { $this->unsupportedServerStreamingCall($call, $options); } $headers = self::buildCommonHeaders($options); $callOptions = $this->getCallOptions($options); $request = $this->requestBuilder->build( $call->getMethod(), $call->getMessage() // Exclude headers here because they will be added in _serverStreamRequest(). ); $decoderOptions = []; if (isset($options['decoderOptions'])) { $decoderOptions = $options['decoderOptions']; } return new ServerStream( $this->_serverStreamRequest( $this->httpHandler, $request, $headers, $call->getDecodeType(), $callOptions, $decoderOptions ), $call->getDescriptor() ); } /** * Creates and starts a RestServerStreamingCall. * * @param callable $httpHandler The HTTP Handler to invoke the request with. * @param RequestInterface $request The request to invoke. * @param array $headers The headers to include in the request. * @param string $decodeType The response stream message type to decode. * @param array $callOptions The call options to use when making the call. * @param array $decoderOptions The options to use for the JsonStreamDecoder. * * @return RestServerStreamingCall */ private function _serverStreamRequest( $httpHandler, $request, $headers, $decodeType, $callOptions, $decoderOptions = [] ) { $call = new RestServerStreamingCall( $httpHandler, $decodeType, $decoderOptions ); $call->start($request, $headers, $callOptions); return $call; } /** * @param array $options * * @return array */ private function getCallOptions(array $options) { $callOptions = $options['transportOptions']['restOptions'] ?? []; if (isset($options['timeoutMillis'])) { $callOptions['timeout'] = $options['timeoutMillis'] / 1000; } if ($this->clientCertSource) { list($cert, $key) = self::loadClientCertSource($this->clientCertSource); $callOptions['cert'] = $cert; $callOptions['key'] = $key; } if (isset($options['retryAttempt'])) { $callOptions['retryAttempt'] = $options['retryAttempt']; } if (isset($options['requestId'])) { $callOptions['requestId'] = $options['requestId']; } return $callOptions; } } ================================================ FILE: lib/Google/vendor/google/gax/src/Transport/TransportInterface.php ================================================ $options * * @return BidiStream */ public function startBidiStreamingCall(Call $call, array $options); /** * Starts a client streaming call. * * @param Call $call * @param array $options * * @return ClientStream */ public function startClientStreamingCall(Call $call, array $options); /** * Starts a server streaming call. * * @param Call $call * @param array $options * * @return ServerStream */ public function startServerStreamingCall(Call $call, array $options); /** * Returns a promise used to execute network requests. * * @param Call $call * @param array $options * * @return PromiseInterface * @throws ValidationException */ public function startUnaryCall(Call $call, array $options); /** * Closes the connection, if one exists. * * @return void */ public function close(); } ================================================ FILE: lib/Google/vendor/google/gax/src/UriTrait.php ================================================ &$v) { if (is_bool($v)) { $v = $v ? 'true' : 'false'; } } return Utils::uriFor($uri) ->withQuery( Query::build($query) ); } } ================================================ FILE: lib/Google/vendor/google/gax/src/ValidationException.php ================================================ setRules([ '@PSR2' => true, 'concat_space' => ['spacing' => 'one'], 'no_unused_imports' => true, 'method_argument_space' => false, ]) ->setFinder( PhpCsFixer\Finder::create() ->notPath('firestore') ->in(__DIR__) ) ; ================================================ FILE: lib/Google/vendor/google/grpc-gcp/LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: lib/Google/vendor/google/grpc-gcp/README.md ================================================ # gRPC for GCP extensions Copyright 2018 [The gRPC Authors](https://github.com/grpc/grpc/blob/master/AUTHORS) ## About This Repository This repo is created to support GCP specific extensions for gRPC. To use the extension features, please refer to [src](src). This repo also contains supporting infrastructures such as end2end tests and benchmarks for accessing cloud APIs with gRPC client libraries. ## License Apache 2.0 - See [LICENSE](LICENSE) for more information. ================================================ FILE: lib/Google/vendor/google/grpc-gcp/cloudprober/cloudprober.cfg ================================================ probe { type: EXTERNAL name: "spanner" interval_msec: 1800000 timeout_msec: 30000 targets { dummy_targets {} } # No targets for external probe external_probe { mode: ONCE command: "php grpc_gpc_prober/prober.php --api=spanner" } } probe { type: EXTERNAL name: "firestore" interval_msec: 1800000 timeout_msec: 30000 targets { dummy_targets {} } # No targets for external probe external_probe { mode: ONCE command: "php grpc_gpc_prober/prober.php --api=firestore" } } surfacer { type: STACKDRIVER name: "stackdriver" stackdriver_surfacer { monitoring_url: "custom.googleapis.com/cloudprober/" } } ================================================ FILE: lib/Google/vendor/google/grpc-gcp/cloudprober/codegen.sh ================================================ #!/usr/bin/env bash cd "$(dirname "$0")" rm -rf google for p in $(find ../third_party/googleapis/google -type f -name *.proto); do protoc \ --proto_path=../third_party/googleapis \ --php_out=./ \ --grpc_out=./ \ --plugin=protoc-gen-grpc="$(which grpc_php_plugin)" \ "$p" done ================================================ FILE: lib/Google/vendor/google/grpc-gcp/cloudprober/composer.json ================================================ { "name": "grpc_gcp_prober", "description": "grpc cloudprober for PHP", "require": { "grpc/grpc": "^v1.15.0", "google/auth": "^v1.4.0", "google/cloud": "^v0.86.0" } } ================================================ FILE: lib/Google/vendor/google/grpc-gcp/cloudprober/grpc_gpc_prober/firestore_probes.php ================================================ setParent($_PARENT_RESOURCE); $time_start = microtime_float(); $client->ListDocuments($list_document_request); $lantency = (microtime_float()- $time_start) * 1000; $metrics['list_documents_latency_ms'] = $lantency; } $probFunctions = [ 'documents' => 'document' ]; return $probFunctions; ================================================ FILE: lib/Google/vendor/google/grpc-gcp/cloudprober/grpc_gpc_prober/prober.php ================================================ AuthMetadataPlugin($credentials, $request); $ssl_credentials = Grpc\ChannelCredentials::createSsl(); $composit_credentials = $grpc->composite_channel_credentials($ssl_credentials, $google_auth_credentials); return $grpc_gcp->secure_channel($target, $composit_credentials, $kwargs); } function getStubChannel($target){ $res = $auth->default([$_OAUTH_SCOPE]); $cred = $res[0]; return secureAuthorizedChannel($cred, Request(), $target); }*/ function executeProbes($api){ global $_OAUTH_SCOPE; global $_SPANNER_TARGET; global $_FIRESTORE_TARGET; global $spanner_probes; global $firestore_probes; $util = new StackdriverUtil($api); $auth = Google\Auth\ApplicationDefaultCredentials::getCredentials($_OAUTH_SCOPE); $opts = [ 'credentials' => Grpc\ChannelCredentials::createSsl(), 'update_metadata' => $auth->getUpdateMetadataFunc(), ]; if($api == 'spanner'){ $client = new SpannerGrpcClient($_SPANNER_TARGET, $opts); $probe_functions = $spanner_probes; } else if($api == 'firestore'){ $client = new FirestoreGrpcClient($_FIRESTORE_TARGET, $opts); $probe_functions = $firestore_probes; } else{ echo 'grpc not implemented for '.$api; exit(1); } $total = sizeof($probe_functions); $success = 0; $metrics = []; # Execute all probes for given api foreach ($probe_functions as $probe_name => $probe_function) { try{ $probe_function($client, $metrics); $success++; } catch(Exception $e){ $util->reportError($e); } } if($success == $total){ $util->setSuccess(True); } $util->addMetrics($metrics); $util->outputMetrics(); if($success != $total){ # TODO: exit system exit(1); } } function main(){ $args = getArgs(); executeProbes($args['api']); } main(); ================================================ FILE: lib/Google/vendor/google/grpc-gcp/cloudprober/grpc_gpc_prober/spanner_probes.php ================================================ code !== Grpc\STATUS_OK) { echo "Call did not complete successfully. Status object:\n"; var_dump($status); exit(1); } } function microtime_float() { list($usec, $sec) = explode(" ", microtime()); return ((float)$usec + (float)$sec); } /* Probes to test session related grpc call from Spanner stub. Includes tests against CreateSession, GetSession, ListSessions, and DeleteSession of Spanner stub. Args: stub: An object of SpannerStub. metrics: A list of metrics. */ function sessionManagement($client, &$metrics){ global $_DATABASE; $createSessionRequest = new Google\Cloud\Spanner\V1\CreateSessionRequest(); $createSessionRequest->setDatabase($_DATABASE); #Create Session test #Create $time_start = microtime_float(); list($session, $status) = $client->CreateSession($createSessionRequest)->wait(); hardAssertIfStatusOk($status); hardAssert($session !== null, 'Call completed with a null response'); $lantency = (microtime_float()- $time_start) * 1000; $metrics['create_session_latency_ms'] = $lantency; #Get Session $getSessionRequest = new Google\Cloud\Spanner\V1\GetSessionRequest(); $getSessionRequest->setName($session->getName()); $time_start = microtime_float(); $response = $client->GetSession($getSessionRequest); $response->wait(); $lantency = (microtime_float() - $time_start) * 1000; $metrics['get_session_latency_ms'] = $lantency; #List session $listSessionsRequest = new Google\Cloud\Spanner\V1\ListSessionsRequest(); $listSessionsRequest->setDatabase($_DATABASE); $time_start = microtime_float(); $response = $client->ListSessions($listSessionsRequest); $lantency = (microtime_float() - $time_start) * 1000; $metrics['list_sessions_latency_ms'] = $lantency; #Delete session $deleteSessionRequest = new Google\Cloud\Spanner\V1\DeleteSessionRequest(); $deleteSessionRequest->setName($session->getName()); $time_start = microtime_float(); $client->deleteSession($deleteSessionRequest); $lantency = (microtime_float() - $time_start) * 1000; $metrics['delete_session_latency_ms'] = $lantency; } /* Probes to test ExecuteSql and ExecuteStreamingSql call from Spanner stub. Args: stub: An object of SpannerStub. metrics: A list of metrics. */ function executeSql($client, &$metrics){ global $_DATABASE; $createSessionRequest = new Google\Cloud\Spanner\V1\CreateSessionRequest(); $createSessionRequest->setDatabase($_DATABASE); list($session, $status) = $client->CreateSession($createSessionRequest)->wait(); hardAssertIfStatusOk($status); hardAssert($session !== null, 'Call completed with a null response'); # Probing ExecuteSql call $time_start = microtime_float(); $executeSqlRequest = new Google\Cloud\Spanner\V1\ExecuteSqlRequest(); $executeSqlRequest->setSession($session->getName()); $executeSqlRequest->setSql('select * FROM users'); $result_set = $client->ExecuteSql($executeSqlRequest); $lantency = (microtime_float() - $time_start) * 1000; $metrics['execute_sql_latency_ms'] = $lantency; // TODO: Error check result_set # Probing ExecuteStreamingSql call $partial_result_set = $client->ExecuteStreamingSql($executeSqlRequest); $time_start = microtime_float(); $first_result = array_values($partial_result_set->getMetadata())[0]; $lantency = (microtime_float() - $time_start) * 1000; $metrics['execute_streaming_sql_latency_ms'] = $lantency; // TODO: Error Check for sreaming sql first result $deleteSessionRequest = new Google\Cloud\Spanner\V1\DeleteSessionRequest(); $deleteSessionRequest->setName($session->getName()); $client->deleteSession($deleteSessionRequest); } /* Probe to test Read and StreamingRead grpc call from Spanner stub. Args: stub: An object of SpannerStub. metrics: A list of metrics. */ function read($client, &$metrics){ global $_DATABASE; $createSessionRequest = new Google\Cloud\Spanner\V1\CreateSessionRequest(); $createSessionRequest->setDatabase($_DATABASE); list($session, $status) = $client->CreateSession($createSessionRequest)->wait(); hardAssertIfStatusOk($status); hardAssert($session !== null, 'Call completed with a null response'); # Probing Read call $time_start = microtime_float(); $readRequest = new Google\Cloud\Spanner\V1\ReadRequest(); $readRequest->setSession($session->getName()); $readRequest->setTable('users'); $readRequest->setColumns(['username', 'firstname', 'lastname']); $keyset = new Google\Cloud\Spanner\V1\KeySet(); $keyset->setAll(True); $readRequest->setKeySet($keyset); $result_set = $client->Read($readRequest); $lantency = (microtime_float() - $time_start) * 1000; $metrics['read_latency_ms'] = $lantency; // TODO: Error Check for result_set # Probing StreamingRead call $partial_result_set = $client->StreamingRead($readRequest); $time_start = microtime_float(); $first_result = array_values($partial_result_set->getMetadata())[0]; $lantency = (microtime_float() - $time_start) * 1000; $metrics['streaming_read_latency_ms'] = $lantency; //TODO: Error Check for streaming read first result $deleteSessionRequest = new Google\Cloud\Spanner\V1\DeleteSessionRequest(); $deleteSessionRequest->setName($session->getName()); $client->deleteSession($deleteSessionRequest); } /* Probe to test BeginTransaction, Commit and Rollback grpc from Spanner stub. Args: stub: An object of SpannerStub. metrics: A list of metrics. */ function transaction($client, &$metrics){ global $_DATABASE; $createSessionRequest = new Google\Cloud\Spanner\V1\CreateSessionRequest(); $createSessionRequest->setDatabase($_DATABASE); list($session, $status) = $client->CreateSession($createSessionRequest)->wait(); hardAssertIfStatusOk($status); hardAssert($session !== null, 'Call completed with a null response'); $txn_options = new Google\Cloud\Spanner\V1\TransactionOptions(); $rw = new Google\Cloud\Spanner\V1\TransactionOptions\ReadWrite(); $txn_options->setReadWrite($rw); $txn_request = new Google\Cloud\Spanner\V1\BeginTransactionRequest(); $txn_request->setSession($session->getName()); $txn_request->setOptions($txn_options); # Probing BeginTransaction call $time_start = microtime_float(); list($txn, $status) = $client->BeginTransaction($txn_request)->wait(); $lantency = (microtime_float() - $time_start) * 1000; $metrics['begin_transaction_latency_ms'] = $lantency; hardAssertIfStatusOk($status); hardAssert($txn !== null, 'Call completed with a null response'); # Probing Commit Call $commit_request = new Google\Cloud\Spanner\V1\CommitRequest(); $commit_request->setSession($session->getName()); $commit_request->setTransactionId($txn->getId()); $time_start = microtime_float(); $client->Commit($commit_request); $latency = (microtime_float() - $time_start) * 1000; $metrics['commit_latency_ms'] = $lantency; # Probing Rollback call list($txn, $status) = $client->BeginTransaction($txn_request)->wait(); $rollback_request = new Google\Cloud\Spanner\V1\RollbackRequest(); $rollback_request->setSession($session->getName()); $rollback_request->setTransactionId($txn->getId()); hardAssertIfStatusOk($status); hardAssert($txn !== null, 'Call completed with a null response'); $time_start = microtime_float(); $client->Rollback($rollback_request); $latency = (microtime_float() - $time_start) * 1000; $metrics['rollback_latency_ms'] = $latency; $deleteSessionRequest = new Google\Cloud\Spanner\V1\DeleteSessionRequest(); $deleteSessionRequest->setName($session->getName()); $client->deleteSession($deleteSessionRequest); } /* Probe to test PartitionQuery and PartitionRead grpc call from Spanner stub. Args: stub: An object of SpannerStub. metrics: A list of metrics. */ function partition($client, &$metrics){ global $_DATABASE; global $_TEST_USERNAME; $createSessionRequest = new Google\Cloud\Spanner\V1\CreateSessionRequest(); $createSessionRequest->setDatabase($_DATABASE); list($session, $status) = $client->CreateSession($createSessionRequest)->wait(); hardAssertIfStatusOk($status); hardAssert($session !== null, 'Call completed with a null response'); $txn_options = new Google\Cloud\Spanner\V1\TransactionOptions(); $ro = new Google\Cloud\Spanner\V1\TransactionOptions\PBReadOnly(); $txn_options->setReadOnly($ro); $txn_selector = new Google\Cloud\Spanner\V1\TransactionSelector(); $txn_selector->setBegin($txn_options); #Probing PartitionQuery call $ptn_query_request = new Google\Cloud\Spanner\V1\PartitionQueryRequest(); $ptn_query_request->setSession($session->getName()); $ptn_query_request->setSql('select * FROM users'); $ptn_query_request->setTransaction($txn_selector); $time_start = microtime_float(); $client->PartitionQuery($ptn_query_request); $lantency = (microtime_float() - $time_start) * 1000; $metrics['partition_query_latency_ms'] = $lantency; #Probing PartitionRead call $ptn_read_request = new Google\Cloud\Spanner\V1\PartitionReadRequest(); $ptn_read_request->setSession($session->getName()); $ptn_read_request->setTable('users'); $ptn_read_request->setTransaction($txn_selector); $keyset = new Google\Cloud\Spanner\V1\KeySet(); $keyset->setAll(True); $ptn_read_request->setKeySet($keyset); $ptn_read_request->setColumns(['username', 'firstname', 'lastname']); $time_start = microtime_float(); $client->PartitionRead($ptn_read_request); $latency = (microtime_float() - $time_start) * 1000; $metrics['partition_read_latency_ms'] = $latency; # Delete Session $deleteSessionRequest = new Google\Cloud\Spanner\V1\DeleteSessionRequest(); $deleteSessionRequest->setName($session->getName()); $client->deleteSession($deleteSessionRequest); } $PROBE_FUNCTIONS = [ 'session_management' => 'sessionManagement', 'execute_sql' => 'executeSql', 'read' => 'read', 'transaction' => 'transaction', 'partition' => 'partition' ]; return $PROBE_FUNCTIONS; ================================================ FILE: lib/Google/vendor/google/grpc-gcp/cloudprober/grpc_gpc_prober/stackdriver_util.php ================================================ api = $api; $this->metrics = []; $this->success = FALSE; $this->err_client = new ReportErrorsServiceClient(); } function addMetric($key, $value){ $this->matrics[$key] = $value; } function addMetrics($metrics){ $this->metrics = array_merge($metrics, $this->metrics); } function setSuccess($result){ $this->success = $result; } function outputMetrics(){ if ($this->success){ echo $this->api.'_success 1'."\n"; } else{ echo $this->api.'_success 0'."\n"; } foreach ($this->metrics as $key => $value) { echo $key.' '.$value."\n"; } } function reportError($err){ error_log($err); $projectId = '434076015357'; $project_name = $this->err_client->projectName($projectId); $location = (new SourceLocation()) ->setFunctionName($this->api); $context = (new ErrorContext()) ->setReportLocation($location); $error_event = new ReportedErrorEvent(); $error_event->setMessage('PHPProbeFailure: fails on '.$this->api.' API. Details: '.(string)$err."\n"); $error_event->setContext($context); $this->err_client->reportErrorEvent($project_name, $error_event); } } ================================================ FILE: lib/Google/vendor/google/grpc-gcp/composer.json ================================================ { "name": "google/grpc-gcp", "description": "gRPC GCP library for channel management", "license": "Apache-2.0", "require": { "php": "^8.0", "google/protobuf": "^v3.25.3||^4.26.1", "grpc/grpc": "^v1.13.0", "google/auth": "^1.3", "psr/cache": "^1.0.1||^2.0.0||^3.0.0" }, "require-dev": { "phpunit/phpunit": "^9.0", "google/cloud-spanner": "^1.7" }, "autoload": { "psr-4": { "Grpc\\Gcp\\": "src/" }, "classmap": [ "src/generated/" ] } } ================================================ FILE: lib/Google/vendor/google/grpc-gcp/doc/gRPC-client-user-guide.md ================================================ # Instructions for create a gRPC client for google cloud services ## Overview This instruction includes a step by step guide for creating a gRPC client to test the google cloud service from an empty linux VM, using GCE ubuntu 16.04 TLS instance. The main steps are followed as steps below: - Environment prerequisite - Install protobuf plugin and gRPC-PHP/protobuf extension - Generate client API from .proto files - Create the client and send/receive RPC. ## Environment Prerequisite **Linux** ```sh $ [sudo] apt-get install build-essential autoconf libtool pkg-config zip unzip zlib1g-dev ``` **PHP** * `php` 5.5 or above, 7.0 or above * `pecl` * `composer` ```sh $ [sudo] apt-get install php php-dev $ curl -sS https://getcomposer.org/installer | php $ [sudo] mv composer.phar /usr/local/bin/composer ``` ## Install protobuf plugin and gRPC-PHP/protobuf extension `grpc_php_plugin` is used to generate client API from `*.proto `files. Currently, The only way to install `grpc_php_plugin` is to build from the gRPC source. **Install protobuf, gRPC, which will install the plugin** ```sh $ git clone -b $(curl -L https://grpc.io/release) https://github.com/grpc/grpc $ cd grpc $ git submodule update --init # install protobuf $ cd third_party/protobuf $ ./autogen.sh && ./configure && make -j8 $ [sudo] make install $ [sudo] ldconfig # install gRPC $ cd ../.. $ make -j8 $ [sudo] make install ``` It will generate `grpc_php_plugin` under `/usr/local/bin`. **Install gRPC-PHP extension** ```sh $ [sudo] pecl install protobuf $ [sudo] pecl install grpc ``` It will generate `protobuf.so` and `grpc.so` under PHP's extension directory. Note gRPC-PHP extension installed by pecl doesn't work on RHEL6 system. ## Generate client API from .proto files The common way to generate the client API is to use `grpc_php_plugin` directly. Since the plugin won't find the dependency by itself. It works if all your service proto files and dependent proto files are inside one directory. The command looks like: ```sh $ mkdir $HOME/project $ protoc --proto_path=./ --php_out=$HOME/project \ --grpc_out=$HOME/project \ --plugin=protoc-gen-grpc=./bins/opt/grpc_php_plugin \ path/to/your/proto_dependency_directory1/*.proto \ path/to/your/proto_dependency_directory2/*.proto \ path/to/your/proto_directory/*.proto ``` Take `Firestore` service under [googleapis github repo](https://github.com/googleapis/googleapis) for example. The proto files required for generating client API are ``` google/api/annotations.proto google/api/http.proto google/api/httpbody.proto google/longrunning/operations.proto google/rpc/code.proto google/rpc/error_details.proto google/rpc/status.proto google/type/latlng.proto google/firestore/v1beta1/firestore.proto google/firestore/v1beta1/common.proto google/firestore/v1beta1/query.proto google/firestore/v1beta1/write.proto google/firestore/v1beta1/document.proto ``` Thus the command looks like: ```sh $ protoc --proto_path=googleapis --plugin=protoc-gen-grpc=`which grpc_php_plugin` \ --php_out=./ --grpc_out=./ google/api/annotations.proto google/api/http.proto \ google/api/httpbody.proto google/longrunning/operations.proto google/rpc/code.proto \ google/rpc/error_details.proto google/rpc/status.proto google/type/latlng.proto \ google/firestore/v1beta1/firestore.proto google/firestore/v1beta1/common.proto \ google/firestore/v1beta1/query.proto google/firestore/v1beta1/write.proto \ google/firestore/v1beta1/document.proto ``` Since most of cloud services already publish proto files under [googleapis github repo](https://github.com/googleapis/googleapis), you can use it's Makefile to generate the client API. The `Makefile` will help you generate the client API as well as find the dependencies. The command will simply be: ```sh $ cd $HOME $ mkdir project $ git clone https://github.com/googleapis/googleapis.git $ cd googleapis $ make LANGUAGE=php OUTPUT=$HOME/project # (It's okay if you see error like Please add 'syntax = "proto3";' # to the top of your .proto file.) ``` The client API library is generated under `$HOME/project`. Take [`Firestore`](https://github.com/googleapis/googleapis/blob/master/google/firestore/v1beta1/firestore.proto) as example, the Client API is under `project/Google/Cloud/Firestore/V1beta1/FirestoreClient.php` depends on your package name inside .proto file. An easy way to find your client is ```sh $ find ./ -name [service_name]Client.php ``` ## Create the client and send/receive RPC. Now it's time to use the client API to send and receive RPCs. ```sh $ cd $HOME/project ``` **Install gRPC-PHP composer library** ```sh $ vim composer.json ######## you need to change the path and service namespace. { "require": { "google/cloud": "^0.52.1" }, "autoload": { "psr-4": { "FireStore\\": "src/", "Google\\Cloud\\Firestore\\V1beta1\\": "Google/Cloud/Firestore/V1beta1/" } } } ######## $ composer install ``` **Set credentials file** ``` sh $ vim $HOME/key.json ## Paste you credential file downloaded from your cloud project ## which you can find in APIs&Services => credentials => create credentials ## => Service account key => your credentials $ export GOOGLE_APPLICATION_CREDENTIALS=$HOME/key.json ``` **Implement Service Client** Take a unary-unary RPC `listDocument` from `FirestoreClient` as example. Create a file name `ListDocumentClient.php`. - import library ``` require_once __DIR__ . '/vendor/autoload.php'; use Google\Cloud\Firestore\V1beta1\FirestoreClient; use Google\Cloud\Firestore\V1beta1\ListDocumentsRequest; use Google\Auth\ApplicationDefaultCredentials; ``` - Google Auth ``` $host = "firestore.googleapis.com"; $credentials = \Grpc\ChannelCredentials::createSsl(); // WARNING: the environment variable "GOOGLE_APPLICATION_CREDENTIALS" needs to be set $auth = ApplicationDefaultCredentials::getCredentials(); $opts = [ 'credentials' => $credentials, 'update_metadata' => $auth->getUpdateMetadataFunc(), ] ``` - Create Client ``` $firestoreClient = new FirestoreClient($host, $opts); ``` - Make and receive RPC call ``` $argument = new ListDocumentsRequest(); $project_id = xxxxxxx; $argument->setParent("projects/$project_id/databases/(default)/documents"); list($Response, $error) = $firestoreClient->ListDocuments($argument)->wait(); ``` - print RPC response ``` $documents = $Response->getDocuments(); $index = 0; foreach($documents as $document) { $index++; $name = $document->getName(); echo "=> Document $index: $name\n"; $fields = $document->getFields(); foreach ($fields as $name => $value) { echo "$name => ".$value->getStringValue()."\n"; } } ``` - run the script ```sh $ php -d extension=grpc.so -d extension=protobuf.so ListDocumentClient.php ``` For different kinds of RPC(unary-unary, unary-stream, stream-unary, stream-stream), please check [grpc.io PHP part](https://grpc.io/docs/tutorials/basic/php.html#calling-service-methods) for reference. ================================================ FILE: lib/Google/vendor/google/grpc-gcp/src/ChannelRef.php ================================================ target = $target; $this->channel_id = $channel_id; $this->affinity_ref = $affinity_ref; $this->active_stream_ref = $active_stream_ref; $this->opts = $opts; $this->has_deserialized = new CreatedByDeserializeCheck(); } public function getRealChannel($credentials) { // TODO(ddyihai): remove this check once the serialize handler for // \Grpc\Channel is implemented(issue https://github.com/grpc/grpc/issues/15870). if (!$this->has_deserialized->getData()) { // $real_channel exists and is not created by the deserialization. return $this->real_channel; } // If this ChannelRef is created by deserialization, $real_channel is invalid // thus needs to be recreated becasue Grpc\Channel don't have serialize and // deserialize handler. // Since [target + augments + credentials] will be the same during the recreation, // it will reuse the underline grpc channel in C extension without creating a // new connection. // 'credentials' in the array $opts will be unset during creating the channel. if (!array_key_exists('credentials', $this->opts)) { $this->opts['credentials'] = $credentials; } $real_channel = new \Grpc\Channel($this->target, $this->opts); $this->real_channel = $real_channel; // Set deserialization to false so it won't be recreated within the same script. $this->has_deserialized->setData(0); return $real_channel; } public function getAffinityRef() { return $this->affinity_ref; } public function getActiveStreamRef() { return $this->active_stream_ref; } public function affinityRefIncr() { $this->affinity_ref += 1; } public function affinityRefDecr() { $this->affinity_ref -= 1; } public function activeStreamRefIncr() { $this->active_stream_ref += 1; } public function activeStreamRefDecr() { $this->active_stream_ref -= 1; } } ================================================ FILE: lib/Google/vendor/google/grpc-gcp/src/Config.php ================================================ gcp_call_invoker = new \Grpc\DefaultCallInvoker(); return; } $gcp_channel = null; $url_host = parse_url($target, PHP_URL_HOST); $this->hostname = $url_host ? $url_host : $target; $channel_pool_key = $this->hostname . '.gcp.channel.' . getmypid(); if (!$cacheItemPool) { $affinity_conf = $this->parseConfObject($conf); $gcp_call_invoker = new GCPCallInvoker($affinity_conf); $this->gcp_call_invoker = $gcp_call_invoker; } else { $item = $cacheItemPool->getItem($channel_pool_key); if ($item->isHit()) { // Channel pool for the $hostname API has already created. $gcp_call_invoker = unserialize($item->get()); } else { $affinity_conf = $this->parseConfObject($conf); // Create GCP channel based on the information. $gcp_call_invoker = new GCPCallInvoker($affinity_conf); } $this->gcp_call_invoker = $gcp_call_invoker; register_shutdown_function(function ($gcp_call_invoker, $cacheItemPool, $item) { // Push the current gcp_channel back into the pool when the script finishes. $item->set(serialize($gcp_call_invoker)); $cacheItemPool->save($item); }, $gcp_call_invoker, $cacheItemPool, $item); } } /** * @return \Grpc\CallInvoker The call invoker to be hooked into the gRPC */ public function callInvoker() { return $this->gcp_call_invoker; } /** * @return string The URI of the endpoint */ public function getTarget() { return $this->channel->getTarget(); } private function parseConfObject($conf_object) { $config = json_decode($conf_object->serializeToJsonString(), true); if (isset($config['channelPool'])) { $affinity_conf['channelPool'] = $config['channelPool']; } $aff_by_method = array(); if (isset($config['method'])) { for ($i = 0; $i < count($config['method']); $i++) { // In proto3, if the value is default, eg 0 for int, it won't be serialized. // Thus serialized string may not have `command` if the value is default 0(BOUND). if (!array_key_exists('command', $config['method'][$i]['affinity'])) { $config['method'][$i]['affinity']['command'] = 'BOUND'; } $aff_by_method[$config['method'][$i]['name'][0]] = $config['method'][$i]['affinity']; } } $affinity_conf['affinity_by_method'] = $aff_by_method; return $affinity_conf; } } ================================================ FILE: lib/Google/vendor/google/grpc-gcp/src/CreatedByDeserializeCheck.php ================================================ data = 1; } /** * @return string */ public function serialize() { return '0'; } /** * @return string */ public function __serialize() { return $this->serialize(); } /** * @param string $data */ public function unserialize($data) { $this->data = 1; } /** * @param string $data */ public function __unserialize($data) { $this->unserialize($data); } /** * @param $data */ public function setData($data) { $this->data = $data; } /** * @return int */ public function getData() { return $this->data; } } ================================================ FILE: lib/Google/vendor/google/grpc-gcp/src/GCPBidiStreamingCall.php ================================================ _rpcPreProcess($data); $this->real_call = new \Grpc\BidiStreamingCall($channel_ref->getRealChannel( $this->gcp_channel->credentials), $this->method, $this->deserialize, $this->options); $this->real_call->start($this->metadata_rpc); return $this->real_call; } /** * Pick a channel and start the call. * * @param array $metadata Metadata to send with the call, if applicable * (optional) */ public function start(array $metadata = []) { $this->metadata_rpc = $metadata; } /** * Reads the next value from the server. * * @return mixed The next value from the server, or null if there is none */ public function read() { if (!$this->has_real_call) { $this->createRealCall(); $this->has_real_call = true; } $response = $this->real_call->read(); if ($response) { $this->response = $response; } return $response; } /** * Write a single message to the server. This cannot be called after * writesDone is called. * * @param ByteBuffer $data The data to write * @param array $options An array of options, possible keys: * 'flags' => a number (optional) */ public function write($data, array $options = []) { if (!$this->has_real_call) { $this->createRealCall($data); $this->has_real_call = true; } $this->real_call->write($data, $options); } /** * Indicate that no more writes will be sent. */ public function writesDone() { if (!$this->has_real_call) { $this->createRealCall(); $this->has_real_call = true; } $this->real_call->writesDone(); } /** * Wait for the server to send the status, and return it. * * @return \stdClass The status object, with integer $code, string * $details, and array $metadata members */ public function getStatus() { $status = $this->real_call->getStatus(); $this->_rpcPostProcess($status, $this->response); return $status; } } ================================================ FILE: lib/Google/vendor/google/grpc-gcp/src/GCPCallInvoker.php ================================================ affinity_conf = $affinity_conf; } /** * @param string $hostname * @param array $opts * @return GcpExtensionChannel */ public function createChannelFactory($hostname, $opts) { if ($this->channel) { // $call_invoker object has already created from previews PHP-FPM scripts. // Only need to update the $opts including the credentials. $this->channel->updateOpts($opts); } else { $opts['affinity_conf'] = $this->affinity_conf; $channel = new GcpExtensionChannel($hostname, $opts); $this->channel = $channel; } return $this->channel; } // _getChannel is used for testing only. public function GetChannel() { return $this->channel; } public function UnaryCall($channel, $method, $deserialize, $options) { return new GCPUnaryCall($channel, $method, $deserialize, $options); } public function ClientStreamingCall($channel, $method, $deserialize, $options) { return new GCPClientStreamCall($channel, $method, $deserialize, $options); } public function ServerStreamingCall($channel, $method, $deserialize, $options) { return new GCPServerStreamCall($channel, $method, $deserialize, $options); } public function BidiStreamingCall($channel, $method, $deserialize, $options) { return new GCPBidiStreamingCall($channel, $method, $deserialize, $options); } } ================================================ FILE: lib/Google/vendor/google/grpc-gcp/src/GCPClientStreamCall.php ================================================ _rpcPreProcess($data); $this->real_call = new \Grpc\ClientStreamingCall($channel_ref->getRealChannel( $this->gcp_channel->credentials), $this->method, $this->deserialize, $this->options); $this->real_call->start($this->metadata_rpc); return $this->real_call; } /** * Pick a channel and start the call. * * @param array $metadata Metadata to send with the call, if applicable * (optional) */ public function start(array $metadata = []) { // Postpone first rpc to write function(), where we can pick a channel // from the channel pool. $this->metadata_rpc = $metadata; } /** * Write a single message to the server. This cannot be called after * wait is called. * * @param ByteBuffer $data The data to write * @param array $options An array of options, possible keys: * 'flags' => a number (optional) */ public function write($data, array $options = []) { if (!$this->has_real_call) { $this->createRealCall($data); $this->has_real_call = true; } $this->real_call->write($data, $options); } /** * Wait for the server to respond with data and a status. * * @return array [response data, status] */ public function wait() { list($response, $status) = $this->real_call->wait(); $this->_rpcPostProcess($status, $response); return [$response, $status]; } } ================================================ FILE: lib/Google/vendor/google/grpc-gcp/src/GCPServerStreamCall.php ================================================ real_call = new \Grpc\ServerStreamingCall($channel, $this->method, $this->deserialize, $this->options); $this->has_real_call = true; return $this->real_call; } /** * Pick a channel and start the call. * * @param mixed $data The data to send * @param array $metadata Metadata to send with the call, if applicable * (optional) * @param array $options An array of options, possible keys: * 'flags' => a number (optional) */ public function start($argument, $metadata, $options) { $channel_ref = $this->_rpcPreProcess($argument); $this->createRealCall($channel_ref->getRealChannel( $this->gcp_channel->credentials)); $this->real_call->start($argument, $metadata, $options); } /** * @return mixed An iterator of response values */ public function responses() { $response = $this->real_call->responses(); // Since the last response is empty for the server streaming RPC, // the second last one is the last RPC response with payload. // Use this one for searching the affinity key. // The same as BidiStreaming. if ($response) { $this->response = $response; } return $response; } /** * Wait for the server to send the status, and return it. * * @return \stdClass The status object, with integer $code, string * $details, and array $metadata members */ public function getStatus() { $status = $this->real_call->getStatus(); $this->_rpcPostProcess($status, $this->response); return $status; } /** * @return mixed The metadata sent by the server */ public function getMetadata() { return $this->real_call->getMetadata(); } } ================================================ FILE: lib/Google/vendor/google/grpc-gcp/src/GCPUnaryCall.php ================================================ real_call = new \Grpc\UnaryCall($channel, $this->method, $this->deserialize, $this->options); $this->has_real_call = true; return $this->real_call; } /** * Pick a channel and start the call. * * @param mixed $data The data to send * @param array $metadata Metadata to send with the call, if applicable * (optional) * @param array $options An array of options, possible keys: * 'flags' => a number (optional) */ public function start($argument, $metadata, $options) { $channel_ref = $this->_rpcPreProcess($argument); $real_channel = $channel_ref->getRealChannel($this->gcp_channel->credentials); $this->createRealCall($real_channel); $this->real_call->start($argument, $metadata, $options); } /** * Wait for the server to respond with data and a status. * * @return array [response data, status] */ public function wait() { list($response, $status) = $this->real_call->wait(); $this->_rpcPostProcess($status, $response); return [$response, $status]; } /** * @return mixed The metadata sent by the server */ public function getMetadata() { return $this->real_call->getMetadata(); } } ================================================ FILE: lib/Google/vendor/google/grpc-gcp/src/GcpBaseCall.php ================================================ gcp_channel = $channel; $this->method = $method; $this->deserialize = $deserialize; $this->options = $options; $this->_affinity = null; if (isset($this->gcp_channel->affinity_conf['affinity_by_method'][$method])) { $this->_affinity = $this->gcp_channel->affinity_conf['affinity_by_method'][$method]; } } /** * Pick a ChannelRef from the channel pool based on the request and * the affinity config. * * @param mixed $argument Requests. * * @return ChannelRef */ protected function _rpcPreProcess($argument) { $this->affinity_key = null; if ($this->_affinity) { $command = $this->_affinity['command']; if ($command == self::BOUND || $command == self::UNBIND) { $this->affinity_key = $this->getAffinityKeyFromProto($argument); } } $this->channel_ref = $this->gcp_channel->getChannelRef($this->affinity_key); $this->channel_ref->activeStreamRefIncr(); return $this->channel_ref; } /** * Update ChannelRef when RPC finishes. * * @param \stdClass $status The status object, with integer $code, string * $details, and array $metadata members * @param mixed $response Response. */ protected function _rpcPostProcess($status, $response) { if ($this->_affinity) { $command = $this->_affinity['command']; if ($command == self::BIND) { if ($status->code != \Grpc\STATUS_OK) { return; } $affinity_key = $this->getAffinityKeyFromProto($response); $this->gcp_channel->bind($this->channel_ref, $affinity_key); } elseif ($command == self::UNBIND) { $this->gcp_channel->unbind($this->affinity_key); } } $this->channel_ref->activeStreamRefDecr(); } /** * Get the affinity key based on the affinity config. * * @param mixed $proto Objects may contain the affinity key. * * @return string Affinity key. */ protected function getAffinityKeyFromProto($proto) { if ($this->_affinity) { $names = $this->_affinity['affinityKey']; $names_arr = explode(".", $names); foreach ($names_arr as $name) { $getAttrMethod = 'get' . ucfirst($name); $proto = call_user_func_array(array($proto, $getAttrMethod), array()); } return $proto; } echo "Cannot find the field in the proto\n"; } /** * @return mixed The metadata sent by the server */ public function getMetadata() { if (!$this->has_real_call) { $this->createRealCall(); $this->has_real_call = true; } return $this->real_call->getMetadata(); } /** * @return mixed The trailing metadata sent by the server */ public function getTrailingMetadata() { if (!$this->has_real_call) { $this->createRealCall(); $this->has_real_call = true; } return $this->real_call->getTrailingMetadata(); } /** * @return string The URI of the endpoint */ public function getPeer() { if (!$this->has_real_call) { $this->createRealCall(); $this->has_real_call = true; } return $this->real_call->getPeer(); } /** * Cancels the call. */ public function cancel() { if (!$this->has_real_call) { $this->has_real_call = true; $this->createRealCall(); } $this->real_call->cancel(); } /** * Serialize a message to the protobuf binary format. * * @param mixed $data The Protobuf message * * @return string The protobuf binary format */ protected function _serializeMessage($data) { return $this->real_call->_serializeMessage($data); } /** * Deserialize a response value to an object. * * @param string $value The binary value to deserialize * * @return mixed The deserialized value */ protected function _deserializeResponse($value) { return $this->real_call->_deserializeResponse($value); } /** * Set the CallCredentials for the underlying Call. * * @param CallCredentials $call_credentials The CallCredentials object */ public function setCallCredentials($call_credentials) { $this->call->setCredentials($call_credentials); } } ================================================ FILE: lib/Google/vendor/google/grpc-gcp/src/GcpExtensionChannel.php ================================================ channel_refs; } /** * @param string $hostname * @param array $opts Options to create a \Grpc\Channel and affinity config */ public function __construct($hostname = null, $opts = array()) { if ($hostname == null || !is_array($opts)) { throw new \InvalidArgumentException("Expected hostname is empty"); } $this->max_size = 10; $this->max_concurrent_streams_low_watermark = 100; if (isset($opts['affinity_conf'])) { if (isset($opts['affinity_conf']['channelPool'])) { if (isset($opts['affinity_conf']['channelPool']['maxSize'])) { $this->max_size = $opts['affinity_conf']['channelPool']['maxSize']; } if (isset($opts['affinity_conf']['channelPool']['maxConcurrentStreamsLowWatermark'])) { $this->max_concurrent_streams_low_watermark = $opts['affinity_conf']['channelPool']['maxConcurrentStreamsLowWatermark']; } } $this->affinity_by_method = $opts['affinity_conf']['affinity_by_method']; $this->affinity_conf = $opts['affinity_conf']; } $this->target = $hostname; $this->affinity_key_to_channel_ref = array(); $this->channel_refs = array(); $this->updateOpts($opts); // Initiate a Grpc\Channel at the beginning in order to keep the same // behavior as the Grpc. $channel_ref = $this->getChannelRef(); $channel_ref->getRealChannel($this->credentials); } /** * @param array $opts Options to create a \Grpc\Channel */ public function updateOpts($opts) { if (isset($opts['credentials'])) { $this->credentials = $opts['credentials']; } unset($opts['affinity_conf']); unset($opts['credentials']); $this->options = $opts; $this->is_closed = false; } /** * Bind the ChannelRef with the affinity key. This is a private method. * * @param ChannelRef $channel_ref * @param string $affinity_key * * @return ChannelRef */ public function bind($channel_ref, $affinity_key) { if (!array_key_exists($affinity_key, $this->affinity_key_to_channel_ref)) { $this->affinity_key_to_channel_ref[$affinity_key] = $channel_ref; } $channel_ref->affinityRefIncr(); return $channel_ref; } /** * Unbind the affinity key. This is a private method. * * @param string $affinity_key * * @return ChannelRef */ public function unbind($affinity_key) { $channel_ref = null; if (array_key_exists($affinity_key, $this->affinity_key_to_channel_ref)) { $channel_ref = $this->affinity_key_to_channel_ref[$affinity_key]; $channel_ref->affinityRefDecr(); } unset($this->affinity_key_to_channel_ref[$affinity_key]); return $channel_ref; } public function cmp_by_active_stream_ref($a, $b) { return $a->getActiveStreamRef() - $b->getActiveStreamRef(); } /** * Pick or create a ChannelRef from the pool by affinity key. * * @param string $affinity_key * * @return ChannelRef */ public function getChannelRef($affinity_key = null) { if ($affinity_key) { if (array_key_exists($affinity_key, $this->affinity_key_to_channel_ref)) { return $this->affinity_key_to_channel_ref[$affinity_key]; } return $this->getChannelRef(); } usort($this->channel_refs, array($this, 'cmp_by_active_stream_ref')); if (count($this->channel_refs) > 0 && $this->channel_refs[0]->getActiveStreamRef() < $this->max_concurrent_streams_low_watermark) { return $this->channel_refs[0]; } $num_channel_refs = count($this->channel_refs); if ($num_channel_refs < $this->max_size) { // grpc_target_persist_bound stands for how many channels can be persisted for // the same target in the C extension. It is possible that the user use the pure // gRPC and this GCP extension at the same time, which share the same target. In this case // pure gRPC channel may occupy positions in C extension, which deletes some channels created // by this GCP extension. // If that happens, it won't cause the script failure because we saves all arguments for creating // a channel instead of a channel itself. If we watch to fetch a GCP channel already deleted, // it will create a new channel. The only cons is the latency of the first RPC will high because // it will establish the connection again. if (!isset($this->options['grpc_target_persist_bound']) || $this->options['grpc_target_persist_bound'] < $this->max_size) { $this->options['grpc_target_persist_bound'] = $this->max_size; } $cur_opts = array_merge($this->options, ['grpc_gcp_channel_id' => $num_channel_refs]); $channel_ref = new ChannelRef($this->target, $num_channel_refs, $cur_opts); array_unshift($this->channel_refs, $channel_ref); } return $this->channel_refs[0]; } /** * Get the connectivity state of the channel * * @param bool $try_to_connect try to connect on the channel * * @return int The grpc connectivity state * @throws \InvalidArgumentException */ public function getConnectivityState($try_to_connect = false) { // Since getRealChannel is creating a PHP Channel object. However in gRPC, when a Channel // object is closed, we only mark this Object to be invalid. Thus, we need a global variable // to mark whether this GCPExtensionChannel is close or not. if ($this->is_closed) { throw new \RuntimeException("Channel has already been closed"); } $ready = 0; $idle = 0; $connecting = 0; $transient_failure = 0; $shutdown = 0; foreach ($this->channel_refs as $channel_ref) { $state = $channel_ref->getRealChannel($this->credentials)->getConnectivityState($try_to_connect); switch ($state) { case \Grpc\CHANNEL_READY: $ready += 1; break 2; case \Grpc\CHANNEL_FATAL_FAILURE: $shutdown += 1; break; case \Grpc\CHANNEL_CONNECTING: $connecting += 1; break; case \Grpc\CHANNEL_TRANSIENT_FAILURE: $transient_failure += 1; break; case \Grpc\CHANNEL_IDLE: $idle += 1; break; } } if ($ready > 0) { return \Grpc\CHANNEL_READY; } elseif ($idle > 0) { return \Grpc\CHANNEL_IDLE; } elseif ($connecting > 0) { return \Grpc\CHANNEL_CONNECTING; } elseif ($transient_failure > 0) { return \Grpc\CHANNEL_TRANSIENT_FAILURE; } elseif ($shutdown > 0) { return \Grpc\CHANNEL_SHUTDOWN; } } /** * Watch the connectivity state of the channel until it changed * * @param int $last_state The previous connectivity state of the channel * @param Timeval $deadline_obj The deadline this function should wait until * * @return bool If the connectivity state changes from last_state * before deadline * @throws \InvalidArgumentException */ public function watchConnectivityState($last_state, $deadline_obj = null) { if ($deadline_obj == null || !is_a($deadline_obj, '\Grpc\Timeval')) { throw new \InvalidArgumentException(""); } // Since getRealChannel is creating a PHP Channel object. However in gRPC, when a Channel // object is closed, we only mark this Object to be invalid. Thus, we need a global variable // to mark whether this GCPExtensionChannel is close or not. if ($this->is_closed) { throw new \RuntimeException("Channel has already been closed"); } $state = 0; foreach ($this->channel_refs as $channel_ref) { $state = $channel_ref->getRealChannel($this->credentials)->watchConnectivityState($last_state, $deadline_obj); } return $state; } /** * Get the endpoint this call/stream is connected to * * @return string The URI of the endpoint */ public function getTarget() { return $this->target; } /** * Close the channel */ public function close() { foreach ($this->channel_refs as $channel_ref) { $channel_ref->getRealChannel($this->credentials)->close(); } $this->is_closed = true; } } ================================================ FILE: lib/Google/vendor/google/grpc-gcp/src/generated/GPBMetadata/GrpcGcp.php ================================================ internalAddGeneratedFile(hex2bin( "0ac9030a0e677270635f6763702e70726f746f1208677270632e67637022" . "670a09417069436f6e66696712310a0c6368616e6e656c5f706f6f6c1802" . "2001280b321b2e677270632e6763702e4368616e6e656c506f6f6c436f6e" . "66696712270a066d6574686f6418e9072003280b32162e677270632e6763" . "702e4d6574686f64436f6e66696722690a114368616e6e656c506f6f6c43" . "6f6e66696712100a086d61785f73697a6518012001280d12140a0c69646c" . "655f74696d656f7574180220012804122c0a246d61785f636f6e63757272" . "656e745f73747265616d735f6c6f775f77617465726d61726b1803200128" . "0d22490a0c4d6574686f64436f6e666967120c0a046e616d651801200328" . "09122b0a08616666696e69747918e9072001280b32182e677270632e6763" . "702e416666696e697479436f6e6669672285010a0e416666696e69747943" . "6f6e66696712310a07636f6d6d616e6418022001280e32202e677270632e" . "6763702e416666696e697479436f6e6669672e436f6d6d616e6412140a0c" . "616666696e6974795f6b6579180320012809222a0a07436f6d6d616e6412" . "090a05424f554e44100012080a0442494e441001120a0a06554e42494e44" . "1002620670726f746f33" )); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/grpc-gcp/src/generated/Grpc/Gcp/AffinityConfig.php ================================================ grpc.gcp.AffinityConfig */ class AffinityConfig extends \Google\Protobuf\Internal\Message { /** * The affinity command applies on the selected gRPC methods. * * Generated from protobuf field .grpc.gcp.AffinityConfig.Command command = 2; */ private $command = 0; /** * The field path of the affinity key in the request/response message. * For example: "f.a", "f.b.d", etc. * * Generated from protobuf field string affinity_key = 3; */ private $affinity_key = ''; public function __construct() { \GPBMetadata\GrpcGcp::initOnce(); parent::__construct(); } /** * The affinity command applies on the selected gRPC methods. * * Generated from protobuf field .grpc.gcp.AffinityConfig.Command command = 2; * @return int */ public function getCommand() { return $this->command; } /** * The affinity command applies on the selected gRPC methods. * * Generated from protobuf field .grpc.gcp.AffinityConfig.Command command = 2; * @param int $var * @return $this */ public function setCommand($var) { GPBUtil::checkEnum($var, \Grpc\Gcp\AffinityConfig_Command::class); $this->command = $var; return $this; } /** * The field path of the affinity key in the request/response message. * For example: "f.a", "f.b.d", etc. * * Generated from protobuf field string affinity_key = 3; * @return string */ public function getAffinityKey() { return $this->affinity_key; } /** * The field path of the affinity key in the request/response message. * For example: "f.a", "f.b.d", etc. * * Generated from protobuf field string affinity_key = 3; * @param string $var * @return $this */ public function setAffinityKey($var) { GPBUtil::checkString($var, true); $this->affinity_key = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/grpc-gcp/src/generated/Grpc/Gcp/AffinityConfig_Command.php ================================================ Grpc\Gcp\AffinityConfig\Command */ class AffinityConfig_Command { /** * The annotated method will be required to be bound to an existing session * to execute the RPC. The corresponding will be * used to find the affinity key from the request message. * * Generated from protobuf enum BOUND = 0; */ const BOUND = 0; /** * The annotated method will establish the channel affinity with the channel * which is used to execute the RPC. The corresponding * will be used to find the affinity key from the * response message. * * Generated from protobuf enum BIND = 1; */ const BIND = 1; /** * The annotated method will remove the channel affinity with the channel * which is used to execute the RPC. The corresponding * will be used to find the affinity key from the * request message. * * Generated from protobuf enum UNBIND = 2; */ const UNBIND = 2; } ================================================ FILE: lib/Google/vendor/google/grpc-gcp/src/generated/Grpc/Gcp/ApiConfig.php ================================================ grpc.gcp.ApiConfig */ class ApiConfig extends \Google\Protobuf\Internal\Message { /** * The channel pool configurations. * * Generated from protobuf field .grpc.gcp.ChannelPoolConfig channel_pool = 2; */ private $channel_pool = null; /** * The method configurations. * * Generated from protobuf field repeated .grpc.gcp.MethodConfig method = 1001; */ private $method; public function __construct() { \GPBMetadata\GrpcGcp::initOnce(); parent::__construct(); } /** * The channel pool configurations. * * Generated from protobuf field .grpc.gcp.ChannelPoolConfig channel_pool = 2; * @return \Grpc\Gcp\ChannelPoolConfig */ public function getChannelPool() { return $this->channel_pool; } /** * The channel pool configurations. * * Generated from protobuf field .grpc.gcp.ChannelPoolConfig channel_pool = 2; * @param \Grpc\Gcp\ChannelPoolConfig $var * @return $this */ public function setChannelPool($var) { GPBUtil::checkMessage($var, \Grpc\Gcp\ChannelPoolConfig::class); $this->channel_pool = $var; return $this; } /** * The method configurations. * * Generated from protobuf field repeated .grpc.gcp.MethodConfig method = 1001; * @return \Google\Protobuf\Internal\RepeatedField */ public function getMethod() { return $this->method; } /** * The method configurations. * * Generated from protobuf field repeated .grpc.gcp.MethodConfig method = 1001; * @param \Grpc\Gcp\MethodConfig[]|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setMethod($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Grpc\Gcp\MethodConfig::class); $this->method = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/grpc-gcp/src/generated/Grpc/Gcp/ChannelPoolConfig.php ================================================ grpc.gcp.ChannelPoolConfig */ class ChannelPoolConfig extends \Google\Protobuf\Internal\Message { /** * The max number of channels in the pool. * * Generated from protobuf field uint32 max_size = 1; */ private $max_size = 0; /** * The idle timeout (seconds) of channels without bound affinity sessions. * * Generated from protobuf field uint64 idle_timeout = 2; */ private $idle_timeout = 0; /** * The low watermark of max number of concurrent streams in a channel. * New channel will be created once it get hit, until we reach the max size * of the channel pool. * * Generated from protobuf field uint32 max_concurrent_streams_low_watermark = 3; */ private $max_concurrent_streams_low_watermark = 0; public function __construct() { \GPBMetadata\GrpcGcp::initOnce(); parent::__construct(); } /** * The max number of channels in the pool. * * Generated from protobuf field uint32 max_size = 1; * @return int */ public function getMaxSize() { return $this->max_size; } /** * The max number of channels in the pool. * * Generated from protobuf field uint32 max_size = 1; * @param int $var * @return $this */ public function setMaxSize($var) { GPBUtil::checkUint32($var); $this->max_size = $var; return $this; } /** * The idle timeout (seconds) of channels without bound affinity sessions. * * Generated from protobuf field uint64 idle_timeout = 2; * @return int|string */ public function getIdleTimeout() { return $this->idle_timeout; } /** * The idle timeout (seconds) of channels without bound affinity sessions. * * Generated from protobuf field uint64 idle_timeout = 2; * @param int|string $var * @return $this */ public function setIdleTimeout($var) { GPBUtil::checkUint64($var); $this->idle_timeout = $var; return $this; } /** * The low watermark of max number of concurrent streams in a channel. * New channel will be created once it get hit, until we reach the max size * of the channel pool. * * Generated from protobuf field uint32 max_concurrent_streams_low_watermark = 3; * @return int */ public function getMaxConcurrentStreamsLowWatermark() { return $this->max_concurrent_streams_low_watermark; } /** * The low watermark of max number of concurrent streams in a channel. * New channel will be created once it get hit, until we reach the max size * of the channel pool. * * Generated from protobuf field uint32 max_concurrent_streams_low_watermark = 3; * @param int $var * @return $this */ public function setMaxConcurrentStreamsLowWatermark($var) { GPBUtil::checkUint32($var); $this->max_concurrent_streams_low_watermark = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/grpc-gcp/src/generated/Grpc/Gcp/MethodConfig.php ================================================ grpc.gcp.MethodConfig */ class MethodConfig extends \Google\Protobuf\Internal\Message { /** * A fully qualified name of a gRPC method, or a wildcard pattern ending * with .*, such as foo.bar.A, foo.bar.*. Method configs are evaluated * sequentially, and the first one takes precedence. * * Generated from protobuf field repeated string name = 1; */ private $name; /** * The channel affinity configurations. * * Generated from protobuf field .grpc.gcp.AffinityConfig affinity = 1001; */ private $affinity = null; public function __construct() { \GPBMetadata\GrpcGcp::initOnce(); parent::__construct(); } /** * A fully qualified name of a gRPC method, or a wildcard pattern ending * with .*, such as foo.bar.A, foo.bar.*. Method configs are evaluated * sequentially, and the first one takes precedence. * * Generated from protobuf field repeated string name = 1; * @return \Google\Protobuf\Internal\RepeatedField */ public function getName() { return $this->name; } /** * A fully qualified name of a gRPC method, or a wildcard pattern ending * with .*, such as foo.bar.A, foo.bar.*. Method configs are evaluated * sequentially, and the first one takes precedence. * * Generated from protobuf field repeated string name = 1; * @param string[]|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setName($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->name = $arr; return $this; } /** * The channel affinity configurations. * * Generated from protobuf field .grpc.gcp.AffinityConfig affinity = 1001; * @return \Grpc\Gcp\AffinityConfig */ public function getAffinity() { return $this->affinity; } /** * The channel affinity configurations. * * Generated from protobuf field .grpc.gcp.AffinityConfig affinity = 1001; * @param \Grpc\Gcp\AffinityConfig $var * @return $this */ public function setAffinity($var) { GPBUtil::checkMessage($var, \Grpc\Gcp\AffinityConfig::class); $this->affinity = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/grpc-gcp/src/grpc_gcp.proto ================================================ // Copyright 2018 gRPC authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. syntax = "proto3"; package grpc.gcp; message ApiConfig { // The channel pool configurations. ChannelPoolConfig channel_pool = 2; // The method configurations. repeated MethodConfig method = 1001; } message ChannelPoolConfig { // The max number of channels in the pool. uint32 max_size = 1; // The idle timeout (seconds) of channels without bound affinity sessions. uint64 idle_timeout = 2; // The low watermark of max number of concurrent streams in a channel. // New channel will be created once it get hit, until we reach the max size // of the channel pool. uint32 max_concurrent_streams_low_watermark = 3; } message MethodConfig { // A fully qualified name of a gRPC method, or a wildcard pattern ending // with .*, such as foo.bar.A, foo.bar.*. Method configs are evaluated // sequentially, and the first one takes precedence. repeated string name = 1; // The channel affinity configurations. AffinityConfig affinity = 1001; } message AffinityConfig { enum Command { // The annotated method will be required to be bound to an existing session // to execute the RPC. The corresponding will be // used to find the affinity key from the request message. BOUND = 0; // The annotated method will establish the channel affinity with the channel // which is used to execute the RPC. The corresponding // will be used to find the affinity key from the // response message. BIND = 1; // The annotated method will remove the channel affinity with the channel // which is used to execute the RPC. The corresponding // will be used to find the affinity key from the // request message. UNBIND = 2; } // The affinity command applies on the selected gRPC methods. Command command = 2; // The field path of the affinity key in the request/response message. // For example: "f.a", "f.b.d", etc. string affinity_key = 3; } ================================================ FILE: lib/Google/vendor/google/longrunning/.gitattributes ================================================ /*.xml.dist export-ignore /tests export-ignore /.github export-ignore /.OwlBot.yaml export-ignore /owlbot.py export-ignore /src/**/gapic_metadata.json export-ignore ================================================ FILE: lib/Google/vendor/google/longrunning/CODE_OF_CONDUCT.md ================================================ # Contributor Code of Conduct As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities. We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality. Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery * Personal attacks * Trolling or insulting/derogatory comments * Public or private harassment * Publishing other's private information, such as physical or electronic addresses, without explicit permission * Other unethical or unprofessional conduct. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team. This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers. This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0, available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/) ================================================ FILE: lib/Google/vendor/google/longrunning/CONTRIBUTING.md ================================================ # How to Contribute We'd love to accept your patches and contributions to this project. We accept and review pull requests against the main [Google Cloud PHP](https://github.com/googleapis/google-cloud-php) repository, which contains all of our client libraries. You will also need to sign a Contributor License Agreement. For more details about how to contribute, see the [CONTRIBUTING.md](https://github.com/googleapis/google-cloud-php/blob/main/CONTRIBUTING.md) file in the main Google Cloud PHP repository. ================================================ FILE: lib/Google/vendor/google/longrunning/LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: lib/Google/vendor/google/longrunning/README.md ================================================ # Google LongRunning API for PHP > Idiomatic PHP client for [Google LongRunning API](https://cloud.google.com/service-infrastructure/docs/service-management/reference/rpc/google.longrunning). [![Latest Stable Version](https://poser.pugx.org/google/longrunning/v/stable)](https://packagist.org/packages/google/longrunning) [![Packagist](https://img.shields.io/packagist/dm/google/longrunning.svg)](https://packagist.org/packages/google/longrunning) * [API documentation](https://cloud.google.com/service-infrastructure/docs/service-management/reference/rpc/google.longrunning) **NOTE:** This repository is part of [Google Cloud PHP](https://github.com/googleapis/google-cloud-php). Any support requests, bug reports, or development contributions should be directed to that project. ### Installation To begin, install the preferred dependency manager for PHP, [Composer](https://getcomposer.org/). Now to install just this component: ```sh $ composer require google/longrunning ``` This component supports both REST over HTTP/1.1 and gRPC. In order to take advantage of the benefits offered by gRPC (such as streaming methods) please see our [gRPC installation guide](https://cloud.google.com/php/grpc). ### Authentication Please see our [Authentication guide](https://github.com/googleapis/google-cloud-php/blob/main/AUTHENTICATION.md) for more information on authenticating your client. Once authenticated, you'll be ready to start making requests. ### Debugging Please see our [Debugging guide](https://github.com/googleapis/google-cloud-php/blob/main/DEBUG.md) for more information about the debugging tools. ### Version This component is considered beta. As such, it should be expected to be mostly stable and we're working towards a release candidate. We will address issues and requests with a higher priority. ### Next Steps 1. Understand the [official documentation](https://cloud.google.com/service-infrastructure/docs/service-management/reference/rpc/google.longrunning/docs). ================================================ FILE: lib/Google/vendor/google/longrunning/SECURITY.md ================================================ # Security Policy To report a security issue, please use [g.co/vulnz](https://g.co/vulnz). The Google Security Team will respond within 5 working days of your report on g.co/vulnz. We use g.co/vulnz for our intake, and do coordination and disclosure here using GitHub Security Advisory to privately discuss and fix the issue. ================================================ FILE: lib/Google/vendor/google/longrunning/VERSION ================================================ 0.6.0 ================================================ FILE: lib/Google/vendor/google/longrunning/composer.json ================================================ { "name": "google/longrunning", "description": "Google LongRunning Client for PHP", "license": "Apache-2.0", "minimum-stability": "stable", "version": "0.6.0", "autoload": { "psr-4": { "Google\\ApiCore\\LongRunning\\": "src/ApiCore/LongRunning", "Google\\LongRunning\\": "src/LongRunning", "GPBMetadata\\Google\\Longrunning\\": "metadata/Longrunning" } }, "extra": { "component": { "id": "longrunning", "path": "LongRunning", "entry": null, "target": "googleapis/php-longrunning" } }, "require-dev": { "google/gax": "^1.38.0", "phpunit/phpunit": "^9.0" } } ================================================ FILE: lib/Google/vendor/google/longrunning/metadata/README.md ================================================ # Google Protobuf Metadata Classes ## WARNING! These classes are not intended for direct use - they exist only to support the generated protobuf classes in src/ ================================================ FILE: lib/Google/vendor/google/longrunning/src/ApiCore/LongRunning/Gapic/OperationsGapicClient.php ================================================ google.longrunning.CancelOperationRequest */ class CancelOperationRequest extends \Google\Protobuf\Internal\Message { /** * The name of the operation resource to be cancelled. * * Generated from protobuf field string name = 1; */ private $name = ''; /** * @param string $name The name of the operation resource to be cancelled. * * @return \Google\LongRunning\CancelOperationRequest * * @experimental */ public static function build(string $name): self { return (new self()) ->setName($name); } /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $name * The name of the operation resource to be cancelled. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Longrunning\Operations::initOnce(); parent::__construct($data); } /** * The name of the operation resource to be cancelled. * * Generated from protobuf field string name = 1; * @return string */ public function getName() { return $this->name; } /** * The name of the operation resource to be cancelled. * * Generated from protobuf field string name = 1; * @param string $var * @return $this */ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/longrunning/src/LongRunning/Client/OperationsClient.php ================================================ cancelOperationAsync(CancelOperationRequest $request, array $optionalArgs = []) * @method PromiseInterface deleteOperationAsync(DeleteOperationRequest $request, array $optionalArgs = []) * @method PromiseInterface getOperationAsync(GetOperationRequest $request, array $optionalArgs = []) * @method PromiseInterface listOperationsAsync(ListOperationsRequest $request, array $optionalArgs = []) * @method PromiseInterface waitOperationAsync(WaitOperationRequest $request, array $optionalArgs = []) */ class OperationsClient { use GapicClientTrait; /** The name of the service. */ private const SERVICE_NAME = 'google.longrunning.Operations'; /** * The default address of the service. * * @deprecated SERVICE_ADDRESS_TEMPLATE should be used instead. */ private const SERVICE_ADDRESS = 'longrunning.googleapis.com'; /** The address template of the service. */ private const SERVICE_ADDRESS_TEMPLATE = 'longrunning.UNIVERSE_DOMAIN'; /** The default port of the service. */ private const DEFAULT_SERVICE_PORT = 443; /** The name of the code generator, to be included in the agent header. */ private const CODEGEN_NAME = 'gapic'; /** The default scopes required by the service. */ public static $serviceScopes = []; private static function getClientDefaults() { return [ 'serviceName' => self::SERVICE_NAME, 'apiEndpoint' => self::SERVICE_ADDRESS . ':' . self::DEFAULT_SERVICE_PORT, 'clientConfig' => __DIR__ . '/../resources/operations_client_config.json', 'descriptorsConfigPath' => __DIR__ . '/../resources/operations_descriptor_config.php', 'gcpApiConfigPath' => __DIR__ . '/../resources/operations_grpc_config.json', 'credentialsConfig' => [ 'defaultScopes' => self::$serviceScopes, ], 'transportConfig' => [ 'rest' => [ 'restClientConfigPath' => __DIR__ . '/../resources/operations_rest_client_config.php', ], ], ]; } /** * Constructor. * * @param array|ClientOptions $options { * Optional. Options for configuring the service API wrapper. * * @type string $apiEndpoint * The address of the API remote host. May optionally include the port, formatted * as ":". Default 'longrunning.googleapis.com:443'. * @type FetchAuthTokenInterface|CredentialsWrapper $credentials * This option should only be used with a pre-constructed * {@see FetchAuthTokenInterface} or {@see CredentialsWrapper} object. Note that * when one of these objects are provided, any settings in $credentialsConfig will * be ignored. * **Important**: If you are providing a path to a credentials file, or a decoded * credentials file as a PHP array, this usage is now DEPRECATED. Providing an * unvalidated credential configuration to Google APIs can compromise the security * of your systems and data. It is recommended to create the credentials explicitly * ``` * use Google\Auth\Credentials\ServiceAccountCredentials; * use Google\LongRunning\OperationsClient; * $creds = new ServiceAccountCredentials($scopes, $json); * $options = new OperationsClient(['credentials' => $creds]); * ``` * {@see * https://cloud.google.com/docs/authentication/external/externally-sourced-credentials} * @type array $credentialsConfig * Options used to configure credentials, including auth token caching, for the * client. For a full list of supporting configuration options, see * {@see \Google\ApiCore\CredentialsWrapper::build()} . * @type bool $disableRetries * Determines whether or not retries defined by the client configuration should be * disabled. Defaults to `false`. * @type string|array $clientConfig * Client method configuration, including retry settings. This option can be either * a path to a JSON file, or a PHP array containing the decoded JSON data. By * default this settings points to the default client config file, which is * provided in the resources folder. * @type string|TransportInterface $transport * The transport used for executing network requests. May be either the string * `rest` or `grpc`. Defaults to `grpc` if gRPC support is detected on the system. * *Advanced usage*: Additionally, it is possible to pass in an already * instantiated {@see \Google\ApiCore\Transport\TransportInterface} object. Note * that when this object is provided, any settings in $transportConfig, and any * $apiEndpoint setting, will be ignored. * @type array $transportConfig * Configuration options that will be used to construct the transport. Options for * each supported transport type should be passed in a key for that transport. For * example: * $transportConfig = [ * 'grpc' => [...], * 'rest' => [...], * ]; * See the {@see \Google\ApiCore\Transport\GrpcTransport::build()} and * {@see \Google\ApiCore\Transport\RestTransport::build()} methods for the * supported options. * @type callable $clientCertSource * A callable which returns the client cert as a string. This can be used to * provide a certificate and private key to the transport layer for mTLS. * @type false|LoggerInterface $logger * A PSR-3 compliant logger. If set to false, logging is disabled, ignoring the * 'GOOGLE_SDK_PHP_LOGGING' environment flag * @type string $universeDomain * The service domain for the client. Defaults to 'googleapis.com'. * } * * @throws ValidationException */ public function __construct(array|ClientOptions $options = []) { $clientOptions = $this->buildClientOptions($options); $this->setClientOptions($clientOptions); } /** Handles execution of the async variants for each documented method. */ public function __call($method, $args) { if (substr($method, -5) !== 'Async') { trigger_error('Call to undefined method ' . __CLASS__ . "::$method()", E_USER_ERROR); } array_unshift($args, substr($method, 0, -5)); return call_user_func_array([$this, 'startAsyncCall'], $args); } /** * Starts asynchronous cancellation on a long-running operation. The server * makes a best effort to cancel the operation, but success is not * guaranteed. If the server doesn't support this method, it returns * `google.rpc.Code.UNIMPLEMENTED`. Clients can use * [Operations.GetOperation][google.longrunning.Operations.GetOperation] or * other methods to check whether the cancellation succeeded or whether the * operation completed despite cancellation. On successful cancellation, * the operation is not deleted; instead, it becomes an operation with * an [Operation.error][google.longrunning.Operation.error] value with a * [google.rpc.Status.code][google.rpc.Status.code] of `1`, corresponding to * `Code.CANCELLED`. * * The async variant is {@see OperationsClient::cancelOperationAsync()} . * * @example samples/OperationsClient/cancel_operation.php * * @param CancelOperationRequest $request A request to house fields associated with the call. * @param array $callOptions { * Optional. * * @type RetrySettings|array $retrySettings * Retry settings to use for this call. Can be a {@see RetrySettings} object, or an * associative array of retry settings parameters. See the documentation on * {@see RetrySettings} for example usage. * } * * @throws ApiException Thrown if the API call fails. */ public function cancelOperation(CancelOperationRequest $request, array $callOptions = []): void { $this->startApiCall('CancelOperation', $request, $callOptions)->wait(); } /** * Deletes a long-running operation. This method indicates that the client is * no longer interested in the operation result. It does not cancel the * operation. If the server doesn't support this method, it returns * `google.rpc.Code.UNIMPLEMENTED`. * * The async variant is {@see OperationsClient::deleteOperationAsync()} . * * @example samples/OperationsClient/delete_operation.php * * @param DeleteOperationRequest $request A request to house fields associated with the call. * @param array $callOptions { * Optional. * * @type RetrySettings|array $retrySettings * Retry settings to use for this call. Can be a {@see RetrySettings} object, or an * associative array of retry settings parameters. See the documentation on * {@see RetrySettings} for example usage. * } * * @throws ApiException Thrown if the API call fails. */ public function deleteOperation(DeleteOperationRequest $request, array $callOptions = []): void { $this->startApiCall('DeleteOperation', $request, $callOptions)->wait(); } /** * Gets the latest state of a long-running operation. Clients can use this * method to poll the operation result at intervals as recommended by the API * service. * * The async variant is {@see OperationsClient::getOperationAsync()} . * * @example samples/OperationsClient/get_operation.php * * @param GetOperationRequest $request A request to house fields associated with the call. * @param array $callOptions { * Optional. * * @type RetrySettings|array $retrySettings * Retry settings to use for this call. Can be a {@see RetrySettings} object, or an * associative array of retry settings parameters. See the documentation on * {@see RetrySettings} for example usage. * } * * @return Operation * * @throws ApiException Thrown if the API call fails. */ public function getOperation(GetOperationRequest $request, array $callOptions = []): Operation { return $this->startApiCall('GetOperation', $request, $callOptions)->wait(); } /** * Lists operations that match the specified filter in the request. If the * server doesn't support this method, it returns `UNIMPLEMENTED`. * * The async variant is {@see OperationsClient::listOperationsAsync()} . * * @example samples/OperationsClient/list_operations.php * * @param ListOperationsRequest $request A request to house fields associated with the call. * @param array $callOptions { * Optional. * * @type RetrySettings|array $retrySettings * Retry settings to use for this call. Can be a {@see RetrySettings} object, or an * associative array of retry settings parameters. See the documentation on * {@see RetrySettings} for example usage. * } * * @return PagedListResponse * * @throws ApiException Thrown if the API call fails. */ public function listOperations(ListOperationsRequest $request, array $callOptions = []): PagedListResponse { return $this->startApiCall('ListOperations', $request, $callOptions); } /** * Waits until the specified long-running operation is done or reaches at most * a specified timeout, returning the latest state. If the operation is * already done, the latest state is immediately returned. If the timeout * specified is greater than the default HTTP/RPC timeout, the HTTP/RPC * timeout is used. If the server does not support this method, it returns * `google.rpc.Code.UNIMPLEMENTED`. * Note that this method is on a best-effort basis. It may return the latest * state before the specified timeout (including immediately), meaning even an * immediate response is no guarantee that the operation is done. * * The async variant is {@see OperationsClient::waitOperationAsync()} . * * @example samples/OperationsClient/wait_operation.php * * @param WaitOperationRequest $request A request to house fields associated with the call. * @param array $callOptions { * Optional. * * @type RetrySettings|array $retrySettings * Retry settings to use for this call. Can be a {@see RetrySettings} object, or an * associative array of retry settings parameters. See the documentation on * {@see RetrySettings} for example usage. * } * * @return Operation * * @throws ApiException Thrown if the API call fails. */ public function waitOperation(WaitOperationRequest $request, array $callOptions = []): Operation { return $this->startApiCall('WaitOperation', $request, $callOptions)->wait(); } } ================================================ FILE: lib/Google/vendor/google/longrunning/src/LongRunning/DeleteOperationRequest.php ================================================ google.longrunning.DeleteOperationRequest */ class DeleteOperationRequest extends \Google\Protobuf\Internal\Message { /** * The name of the operation resource to be deleted. * * Generated from protobuf field string name = 1; */ private $name = ''; /** * @param string $name The name of the operation resource to be deleted. * * @return \Google\LongRunning\DeleteOperationRequest * * @experimental */ public static function build(string $name): self { return (new self()) ->setName($name); } /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $name * The name of the operation resource to be deleted. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Longrunning\Operations::initOnce(); parent::__construct($data); } /** * The name of the operation resource to be deleted. * * Generated from protobuf field string name = 1; * @return string */ public function getName() { return $this->name; } /** * The name of the operation resource to be deleted. * * Generated from protobuf field string name = 1; * @param string $var * @return $this */ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/longrunning/src/LongRunning/Gapic/OperationsGapicClient.php ================================================ cancelOperation($name); * } finally { * $operationsClient->close(); * } * ``` * * @deprecated Please use the new service client {@see \Google\LongRunning\Client\OperationsClient}. */ class OperationsGapicClient { use GapicClientTrait; /** The name of the service. */ const SERVICE_NAME = 'google.longrunning.Operations'; /** * The default address of the service. * * @deprecated SERVICE_ADDRESS_TEMPLATE should be used instead. */ const SERVICE_ADDRESS = 'longrunning.googleapis.com'; /** The address template of the service. */ private const SERVICE_ADDRESS_TEMPLATE = 'longrunning.UNIVERSE_DOMAIN'; /** The default port of the service. */ const DEFAULT_SERVICE_PORT = 443; /** The name of the code generator, to be included in the agent header. */ const CODEGEN_NAME = 'gapic'; /** The default scopes required by the service. */ public static $serviceScopes = []; private static function getClientDefaults() { return [ 'serviceName' => self::SERVICE_NAME, 'apiEndpoint' => self::SERVICE_ADDRESS . ':' . self::DEFAULT_SERVICE_PORT, 'clientConfig' => __DIR__ . '/../resources/operations_client_config.json', 'descriptorsConfigPath' => __DIR__ . '/../resources/operations_descriptor_config.php', 'gcpApiConfigPath' => __DIR__ . '/../resources/operations_grpc_config.json', 'credentialsConfig' => [ 'defaultScopes' => self::$serviceScopes, ], 'transportConfig' => [ 'rest' => [ 'restClientConfigPath' => __DIR__ . '/../resources/operations_rest_client_config.php', ], ], ]; } /** * Constructor. * * @param array $options { * Optional. Options for configuring the service API wrapper. * * @type string $apiEndpoint * The address of the API remote host. May optionally include the port, formatted * as ":". Default 'longrunning.googleapis.com:443'. * @type string|array|FetchAuthTokenInterface|CredentialsWrapper $credentials * The credentials to be used by the client to authorize API calls. This option * accepts either a path to a credentials file, or a decoded credentials file as a * PHP array. * *Advanced usage*: In addition, this option can also accept a pre-constructed * {@see \Google\Auth\FetchAuthTokenInterface} object or * {@see \Google\ApiCore\CredentialsWrapper} object. Note that when one of these * objects are provided, any settings in $credentialsConfig will be ignored. * @type array $credentialsConfig * Options used to configure credentials, including auth token caching, for the * client. For a full list of supporting configuration options, see * {@see \Google\ApiCore\CredentialsWrapper::build()} . * @type bool $disableRetries * Determines whether or not retries defined by the client configuration should be * disabled. Defaults to `false`. * @type string|array $clientConfig * Client method configuration, including retry settings. This option can be either * a path to a JSON file, or a PHP array containing the decoded JSON data. By * default this settings points to the default client config file, which is * provided in the resources folder. * @type string|TransportInterface $transport * The transport used for executing network requests. May be either the string * `rest` or `grpc`. Defaults to `grpc` if gRPC support is detected on the system. * *Advanced usage*: Additionally, it is possible to pass in an already * instantiated {@see \Google\ApiCore\Transport\TransportInterface} object. Note * that when this object is provided, any settings in $transportConfig, and any * $apiEndpoint setting, will be ignored. * @type array $transportConfig * Configuration options that will be used to construct the transport. Options for * each supported transport type should be passed in a key for that transport. For * example: * $transportConfig = [ * 'grpc' => [...], * 'rest' => [...], * ]; * See the {@see \Google\ApiCore\Transport\GrpcTransport::build()} and * {@see \Google\ApiCore\Transport\RestTransport::build()} methods for the * supported options. * @type callable $clientCertSource * A callable which returns the client cert as a string. This can be used to * provide a certificate and private key to the transport layer for mTLS. * } * * @throws ValidationException */ public function __construct(array $options = []) { $clientOptions = $this->buildClientOptions($options); $this->setClientOptions($clientOptions); } /** * Starts asynchronous cancellation on a long-running operation. The server * makes a best effort to cancel the operation, but success is not * guaranteed. If the server doesn't support this method, it returns * `google.rpc.Code.UNIMPLEMENTED`. Clients can use * [Operations.GetOperation][google.longrunning.Operations.GetOperation] or * other methods to check whether the cancellation succeeded or whether the * operation completed despite cancellation. On successful cancellation, * the operation is not deleted; instead, it becomes an operation with * an [Operation.error][google.longrunning.Operation.error] value with a * [google.rpc.Status.code][google.rpc.Status.code] of `1`, corresponding to * `Code.CANCELLED`. * * Sample code: * ``` * $operationsClient = new OperationsClient(); * try { * $name = 'name'; * $operationsClient->cancelOperation($name); * } finally { * $operationsClient->close(); * } * ``` * * @param string $name The name of the operation resource to be cancelled. * @param array $optionalArgs { * Optional. * * @type RetrySettings|array $retrySettings * Retry settings to use for this call. Can be a {@see RetrySettings} object, or an * associative array of retry settings parameters. See the documentation on * {@see RetrySettings} for example usage. * } * * @throws ApiException if the remote call fails */ public function cancelOperation($name, array $optionalArgs = []) { $request = new CancelOperationRequest(); $requestParamHeaders = []; $request->setName($name); $requestParamHeaders['name'] = $name; $requestParams = new RequestParamsHeaderDescriptor( $requestParamHeaders ); $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader(); return $this->startCall( 'CancelOperation', GPBEmpty::class, $optionalArgs, $request )->wait(); } /** * Deletes a long-running operation. This method indicates that the client is * no longer interested in the operation result. It does not cancel the * operation. If the server doesn't support this method, it returns * `google.rpc.Code.UNIMPLEMENTED`. * * Sample code: * ``` * $operationsClient = new OperationsClient(); * try { * $name = 'name'; * $operationsClient->deleteOperation($name); * } finally { * $operationsClient->close(); * } * ``` * * @param string $name The name of the operation resource to be deleted. * @param array $optionalArgs { * Optional. * * @type RetrySettings|array $retrySettings * Retry settings to use for this call. Can be a {@see RetrySettings} object, or an * associative array of retry settings parameters. See the documentation on * {@see RetrySettings} for example usage. * } * * @throws ApiException if the remote call fails */ public function deleteOperation($name, array $optionalArgs = []) { $request = new DeleteOperationRequest(); $requestParamHeaders = []; $request->setName($name); $requestParamHeaders['name'] = $name; $requestParams = new RequestParamsHeaderDescriptor( $requestParamHeaders ); $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader(); return $this->startCall( 'DeleteOperation', GPBEmpty::class, $optionalArgs, $request )->wait(); } /** * Gets the latest state of a long-running operation. Clients can use this * method to poll the operation result at intervals as recommended by the API * service. * * Sample code: * ``` * $operationsClient = new OperationsClient(); * try { * $name = 'name'; * $response = $operationsClient->getOperation($name); * } finally { * $operationsClient->close(); * } * ``` * * @param string $name The name of the operation resource. * @param array $optionalArgs { * Optional. * * @type RetrySettings|array $retrySettings * Retry settings to use for this call. Can be a {@see RetrySettings} object, or an * associative array of retry settings parameters. See the documentation on * {@see RetrySettings} for example usage. * } * * @return \Google\LongRunning\Operation * * @throws ApiException if the remote call fails */ public function getOperation($name, array $optionalArgs = []) { $request = new GetOperationRequest(); $requestParamHeaders = []; $request->setName($name); $requestParamHeaders['name'] = $name; $requestParams = new RequestParamsHeaderDescriptor( $requestParamHeaders ); $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader(); return $this->startCall( 'GetOperation', Operation::class, $optionalArgs, $request )->wait(); } /** * Lists operations that match the specified filter in the request. If the * server doesn't support this method, it returns `UNIMPLEMENTED`. * * Sample code: * ``` * $operationsClient = new OperationsClient(); * try { * $name = 'name'; * $filter = 'filter'; * // Iterate over pages of elements * $pagedResponse = $operationsClient->listOperations($name, $filter); * foreach ($pagedResponse->iteratePages() as $page) { * foreach ($page as $element) { * // doSomethingWith($element); * } * } * // Alternatively: * // Iterate through all elements * $pagedResponse = $operationsClient->listOperations($name, $filter); * foreach ($pagedResponse->iterateAllElements() as $element) { * // doSomethingWith($element); * } * } finally { * $operationsClient->close(); * } * ``` * * @param string $name The name of the operation's parent resource. * @param string $filter The standard list filter. * @param array $optionalArgs { * Optional. * * @type int $pageSize * The maximum number of resources contained in the underlying API * response. The API may return fewer values in a page, even if * there are additional values to be retrieved. * @type string $pageToken * A page token is used to specify a page of values to be returned. * If no page token is specified (the default), the first page * of values will be returned. Any page token used here must have * been generated by a previous call to the API. * @type bool $returnPartialSuccess * When set to `true`, operations that are reachable are returned as normal, * and those that are unreachable are returned in the * [ListOperationsResponse.unreachable] field. * * This can only be `true` when reading across collections e.g. when `parent` * is set to `"projects/example/locations/-"`. * * This field is not by default supported and will result in an * `UNIMPLEMENTED` error if set unless explicitly documented otherwise in * service or product specific documentation. * @type RetrySettings|array $retrySettings * Retry settings to use for this call. Can be a {@see RetrySettings} object, or an * associative array of retry settings parameters. See the documentation on * {@see RetrySettings} for example usage. * } * * @return \Google\ApiCore\PagedListResponse * * @throws ApiException if the remote call fails */ public function listOperations($name, $filter, array $optionalArgs = []) { $request = new ListOperationsRequest(); $requestParamHeaders = []; $request->setName($name); $request->setFilter($filter); $requestParamHeaders['name'] = $name; if (isset($optionalArgs['pageSize'])) { $request->setPageSize($optionalArgs['pageSize']); } if (isset($optionalArgs['pageToken'])) { $request->setPageToken($optionalArgs['pageToken']); } if (isset($optionalArgs['returnPartialSuccess'])) { $request->setReturnPartialSuccess( $optionalArgs['returnPartialSuccess'] ); } $requestParams = new RequestParamsHeaderDescriptor( $requestParamHeaders ); $optionalArgs['headers'] = isset($optionalArgs['headers']) ? array_merge($requestParams->getHeader(), $optionalArgs['headers']) : $requestParams->getHeader(); return $this->getPagedListResponse( 'ListOperations', $optionalArgs, ListOperationsResponse::class, $request ); } /** * Waits until the specified long-running operation is done or reaches at most * a specified timeout, returning the latest state. If the operation is * already done, the latest state is immediately returned. If the timeout * specified is greater than the default HTTP/RPC timeout, the HTTP/RPC * timeout is used. If the server does not support this method, it returns * `google.rpc.Code.UNIMPLEMENTED`. * Note that this method is on a best-effort basis. It may return the latest * state before the specified timeout (including immediately), meaning even an * immediate response is no guarantee that the operation is done. * * Sample code: * ``` * $operationsClient = new OperationsClient(); * try { * $response = $operationsClient->waitOperation(); * } finally { * $operationsClient->close(); * } * ``` * * @param array $optionalArgs { * Optional. * * @type string $name * The name of the operation resource to wait on. * @type Duration $timeout * The maximum duration to wait before timing out. If left blank, the wait * will be at most the time permitted by the underlying HTTP/RPC protocol. * If RPC context deadline is also specified, the shorter one will be used. * @type RetrySettings|array $retrySettings * Retry settings to use for this call. Can be a {@see RetrySettings} object, or an * associative array of retry settings parameters. See the documentation on * {@see RetrySettings} for example usage. * } * * @return \Google\LongRunning\Operation * * @throws ApiException if the remote call fails */ public function waitOperation(array $optionalArgs = []) { $request = new WaitOperationRequest(); if (isset($optionalArgs['name'])) { $request->setName($optionalArgs['name']); } if (isset($optionalArgs['timeout'])) { $request->setTimeout($optionalArgs['timeout']); } return $this->startCall( 'WaitOperation', Operation::class, $optionalArgs, $request )->wait(); } } ================================================ FILE: lib/Google/vendor/google/longrunning/src/LongRunning/GetOperationRequest.php ================================================ google.longrunning.GetOperationRequest */ class GetOperationRequest extends \Google\Protobuf\Internal\Message { /** * The name of the operation resource. * * Generated from protobuf field string name = 1; */ private $name = ''; /** * @param string $name The name of the operation resource. * * @return \Google\LongRunning\GetOperationRequest * * @experimental */ public static function build(string $name): self { return (new self()) ->setName($name); } /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $name * The name of the operation resource. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Longrunning\Operations::initOnce(); parent::__construct($data); } /** * The name of the operation resource. * * Generated from protobuf field string name = 1; * @return string */ public function getName() { return $this->name; } /** * The name of the operation resource. * * Generated from protobuf field string name = 1; * @param string $var * @return $this */ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/longrunning/src/LongRunning/ListOperationsRequest.php ================================================ google.longrunning.ListOperationsRequest */ class ListOperationsRequest extends \Google\Protobuf\Internal\Message { /** * The name of the operation's parent resource. * * Generated from protobuf field string name = 4; */ private $name = ''; /** * The standard list filter. * * Generated from protobuf field string filter = 1; */ private $filter = ''; /** * The standard list page size. * * Generated from protobuf field int32 page_size = 2; */ private $page_size = 0; /** * The standard list page token. * * Generated from protobuf field string page_token = 3; */ private $page_token = ''; /** * When set to `true`, operations that are reachable are returned as normal, * and those that are unreachable are returned in the * [ListOperationsResponse.unreachable] field. * This can only be `true` when reading across collections e.g. when `parent` * is set to `"projects/example/locations/-"`. * This field is not by default supported and will result in an * `UNIMPLEMENTED` error if set unless explicitly documented otherwise in * service or product specific documentation. * * Generated from protobuf field bool return_partial_success = 5; */ private $return_partial_success = false; /** * @param string $name The name of the operation's parent resource. * @param string $filter The standard list filter. * * @return \Google\LongRunning\ListOperationsRequest * * @experimental */ public static function build(string $name, string $filter): self { return (new self()) ->setName($name) ->setFilter($filter); } /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $name * The name of the operation's parent resource. * @type string $filter * The standard list filter. * @type int $page_size * The standard list page size. * @type string $page_token * The standard list page token. * @type bool $return_partial_success * When set to `true`, operations that are reachable are returned as normal, * and those that are unreachable are returned in the * [ListOperationsResponse.unreachable] field. * This can only be `true` when reading across collections e.g. when `parent` * is set to `"projects/example/locations/-"`. * This field is not by default supported and will result in an * `UNIMPLEMENTED` error if set unless explicitly documented otherwise in * service or product specific documentation. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Longrunning\Operations::initOnce(); parent::__construct($data); } /** * The name of the operation's parent resource. * * Generated from protobuf field string name = 4; * @return string */ public function getName() { return $this->name; } /** * The name of the operation's parent resource. * * Generated from protobuf field string name = 4; * @param string $var * @return $this */ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; return $this; } /** * The standard list filter. * * Generated from protobuf field string filter = 1; * @return string */ public function getFilter() { return $this->filter; } /** * The standard list filter. * * Generated from protobuf field string filter = 1; * @param string $var * @return $this */ public function setFilter($var) { GPBUtil::checkString($var, True); $this->filter = $var; return $this; } /** * The standard list page size. * * Generated from protobuf field int32 page_size = 2; * @return int */ public function getPageSize() { return $this->page_size; } /** * The standard list page size. * * Generated from protobuf field int32 page_size = 2; * @param int $var * @return $this */ public function setPageSize($var) { GPBUtil::checkInt32($var); $this->page_size = $var; return $this; } /** * The standard list page token. * * Generated from protobuf field string page_token = 3; * @return string */ public function getPageToken() { return $this->page_token; } /** * The standard list page token. * * Generated from protobuf field string page_token = 3; * @param string $var * @return $this */ public function setPageToken($var) { GPBUtil::checkString($var, True); $this->page_token = $var; return $this; } /** * When set to `true`, operations that are reachable are returned as normal, * and those that are unreachable are returned in the * [ListOperationsResponse.unreachable] field. * This can only be `true` when reading across collections e.g. when `parent` * is set to `"projects/example/locations/-"`. * This field is not by default supported and will result in an * `UNIMPLEMENTED` error if set unless explicitly documented otherwise in * service or product specific documentation. * * Generated from protobuf field bool return_partial_success = 5; * @return bool */ public function getReturnPartialSuccess() { return $this->return_partial_success; } /** * When set to `true`, operations that are reachable are returned as normal, * and those that are unreachable are returned in the * [ListOperationsResponse.unreachable] field. * This can only be `true` when reading across collections e.g. when `parent` * is set to `"projects/example/locations/-"`. * This field is not by default supported and will result in an * `UNIMPLEMENTED` error if set unless explicitly documented otherwise in * service or product specific documentation. * * Generated from protobuf field bool return_partial_success = 5; * @param bool $var * @return $this */ public function setReturnPartialSuccess($var) { GPBUtil::checkBool($var); $this->return_partial_success = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/longrunning/src/LongRunning/ListOperationsResponse.php ================================================ google.longrunning.ListOperationsResponse */ class ListOperationsResponse extends \Google\Protobuf\Internal\Message { /** * A list of operations that matches the specified filter in the request. * * Generated from protobuf field repeated .google.longrunning.Operation operations = 1; */ private $operations; /** * The standard List next-page token. * * Generated from protobuf field string next_page_token = 2; */ private $next_page_token = ''; /** * Unordered list. Unreachable resources. Populated when the request sets * `ListOperationsRequest.return_partial_success` and reads across * collections e.g. when attempting to list all resources across all supported * locations. * * Generated from protobuf field repeated string unreachable = 3 [(.google.api.field_behavior) = UNORDERED_LIST]; */ private $unreachable; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type array<\Google\LongRunning\Operation>|\Google\Protobuf\Internal\RepeatedField $operations * A list of operations that matches the specified filter in the request. * @type string $next_page_token * The standard List next-page token. * @type array|\Google\Protobuf\Internal\RepeatedField $unreachable * Unordered list. Unreachable resources. Populated when the request sets * `ListOperationsRequest.return_partial_success` and reads across * collections e.g. when attempting to list all resources across all supported * locations. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Longrunning\Operations::initOnce(); parent::__construct($data); } /** * A list of operations that matches the specified filter in the request. * * Generated from protobuf field repeated .google.longrunning.Operation operations = 1; * @return \Google\Protobuf\Internal\RepeatedField */ public function getOperations() { return $this->operations; } /** * A list of operations that matches the specified filter in the request. * * Generated from protobuf field repeated .google.longrunning.Operation operations = 1; * @param array<\Google\LongRunning\Operation>|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setOperations($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\LongRunning\Operation::class); $this->operations = $arr; return $this; } /** * The standard List next-page token. * * Generated from protobuf field string next_page_token = 2; * @return string */ public function getNextPageToken() { return $this->next_page_token; } /** * The standard List next-page token. * * Generated from protobuf field string next_page_token = 2; * @param string $var * @return $this */ public function setNextPageToken($var) { GPBUtil::checkString($var, True); $this->next_page_token = $var; return $this; } /** * Unordered list. Unreachable resources. Populated when the request sets * `ListOperationsRequest.return_partial_success` and reads across * collections e.g. when attempting to list all resources across all supported * locations. * * Generated from protobuf field repeated string unreachable = 3 [(.google.api.field_behavior) = UNORDERED_LIST]; * @return \Google\Protobuf\Internal\RepeatedField */ public function getUnreachable() { return $this->unreachable; } /** * Unordered list. Unreachable resources. Populated when the request sets * `ListOperationsRequest.return_partial_success` and reads across * collections e.g. when attempting to list all resources across all supported * locations. * * Generated from protobuf field repeated string unreachable = 3 [(.google.api.field_behavior) = UNORDERED_LIST]; * @param array|\Google\Protobuf\Internal\RepeatedField $var * @return $this */ public function setUnreachable($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->unreachable = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/longrunning/src/LongRunning/Operation.php ================================================ google.longrunning.Operation */ class Operation extends \Google\Protobuf\Internal\Message { /** * The server-assigned name, which is only unique within the same service that * originally returns it. If you use the default HTTP mapping, the * `name` should be a resource name ending with `operations/{unique_id}`. * * Generated from protobuf field string name = 1; */ private $name = ''; /** * Service-specific metadata associated with the operation. It typically * contains progress information and common metadata such as create time. * Some services might not provide such metadata. Any method that returns a * long-running operation should document the metadata type, if any. * * Generated from protobuf field .google.protobuf.Any metadata = 2; */ private $metadata = null; /** * If the value is `false`, it means the operation is still in progress. * If `true`, the operation is completed, and either `error` or `response` is * available. * * Generated from protobuf field bool done = 3; */ private $done = false; protected $result; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $name * The server-assigned name, which is only unique within the same service that * originally returns it. If you use the default HTTP mapping, the * `name` should be a resource name ending with `operations/{unique_id}`. * @type \Google\Protobuf\Any $metadata * Service-specific metadata associated with the operation. It typically * contains progress information and common metadata such as create time. * Some services might not provide such metadata. Any method that returns a * long-running operation should document the metadata type, if any. * @type bool $done * If the value is `false`, it means the operation is still in progress. * If `true`, the operation is completed, and either `error` or `response` is * available. * @type \Google\Rpc\Status $error * The error result of the operation in case of failure or cancellation. * @type \Google\Protobuf\Any $response * The normal, successful response of the operation. If the original * method returns no data on success, such as `Delete`, the response is * `google.protobuf.Empty`. If the original method is standard * `Get`/`Create`/`Update`, the response should be the resource. For other * methods, the response should have the type `XxxResponse`, where `Xxx` * is the original method name. For example, if the original method name * is `TakeSnapshot()`, the inferred response type is * `TakeSnapshotResponse`. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Longrunning\Operations::initOnce(); parent::__construct($data); } /** * The server-assigned name, which is only unique within the same service that * originally returns it. If you use the default HTTP mapping, the * `name` should be a resource name ending with `operations/{unique_id}`. * * Generated from protobuf field string name = 1; * @return string */ public function getName() { return $this->name; } /** * The server-assigned name, which is only unique within the same service that * originally returns it. If you use the default HTTP mapping, the * `name` should be a resource name ending with `operations/{unique_id}`. * * Generated from protobuf field string name = 1; * @param string $var * @return $this */ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; return $this; } /** * Service-specific metadata associated with the operation. It typically * contains progress information and common metadata such as create time. * Some services might not provide such metadata. Any method that returns a * long-running operation should document the metadata type, if any. * * Generated from protobuf field .google.protobuf.Any metadata = 2; * @return \Google\Protobuf\Any|null */ public function getMetadata() { return $this->metadata; } public function hasMetadata() { return isset($this->metadata); } public function clearMetadata() { unset($this->metadata); } /** * Service-specific metadata associated with the operation. It typically * contains progress information and common metadata such as create time. * Some services might not provide such metadata. Any method that returns a * long-running operation should document the metadata type, if any. * * Generated from protobuf field .google.protobuf.Any metadata = 2; * @param \Google\Protobuf\Any $var * @return $this */ public function setMetadata($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Any::class); $this->metadata = $var; return $this; } /** * If the value is `false`, it means the operation is still in progress. * If `true`, the operation is completed, and either `error` or `response` is * available. * * Generated from protobuf field bool done = 3; * @return bool */ public function getDone() { return $this->done; } /** * If the value is `false`, it means the operation is still in progress. * If `true`, the operation is completed, and either `error` or `response` is * available. * * Generated from protobuf field bool done = 3; * @param bool $var * @return $this */ public function setDone($var) { GPBUtil::checkBool($var); $this->done = $var; return $this; } /** * The error result of the operation in case of failure or cancellation. * * Generated from protobuf field .google.rpc.Status error = 4; * @return \Google\Rpc\Status|null */ public function getError() { return $this->readOneof(4); } public function hasError() { return $this->hasOneof(4); } /** * The error result of the operation in case of failure or cancellation. * * Generated from protobuf field .google.rpc.Status error = 4; * @param \Google\Rpc\Status $var * @return $this */ public function setError($var) { GPBUtil::checkMessage($var, \Google\Rpc\Status::class); $this->writeOneof(4, $var); return $this; } /** * The normal, successful response of the operation. If the original * method returns no data on success, such as `Delete`, the response is * `google.protobuf.Empty`. If the original method is standard * `Get`/`Create`/`Update`, the response should be the resource. For other * methods, the response should have the type `XxxResponse`, where `Xxx` * is the original method name. For example, if the original method name * is `TakeSnapshot()`, the inferred response type is * `TakeSnapshotResponse`. * * Generated from protobuf field .google.protobuf.Any response = 5; * @return \Google\Protobuf\Any|null */ public function getResponse() { return $this->readOneof(5); } public function hasResponse() { return $this->hasOneof(5); } /** * The normal, successful response of the operation. If the original * method returns no data on success, such as `Delete`, the response is * `google.protobuf.Empty`. If the original method is standard * `Get`/`Create`/`Update`, the response should be the resource. For other * methods, the response should have the type `XxxResponse`, where `Xxx` * is the original method name. For example, if the original method name * is `TakeSnapshot()`, the inferred response type is * `TakeSnapshotResponse`. * * Generated from protobuf field .google.protobuf.Any response = 5; * @param \Google\Protobuf\Any $var * @return $this */ public function setResponse($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Any::class); $this->writeOneof(5, $var); return $this; } /** * @return string */ public function getResult() { return $this->whichOneof("result"); } } ================================================ FILE: lib/Google/vendor/google/longrunning/src/LongRunning/OperationInfo.php ================================================ google.longrunning.OperationInfo */ class OperationInfo extends \Google\Protobuf\Internal\Message { /** * Required. The message name of the primary return type for this * long-running operation. * This type will be used to deserialize the LRO's response. * If the response is in a different package from the rpc, a fully-qualified * message name must be used (e.g. `google.protobuf.Struct`). * Note: Altering this value constitutes a breaking change. * * Generated from protobuf field string response_type = 1; */ private $response_type = ''; /** * Required. The message name of the metadata type for this long-running * operation. * If the response is in a different package from the rpc, a fully-qualified * message name must be used (e.g. `google.protobuf.Struct`). * Note: Altering this value constitutes a breaking change. * * Generated from protobuf field string metadata_type = 2; */ private $metadata_type = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $response_type * Required. The message name of the primary return type for this * long-running operation. * This type will be used to deserialize the LRO's response. * If the response is in a different package from the rpc, a fully-qualified * message name must be used (e.g. `google.protobuf.Struct`). * Note: Altering this value constitutes a breaking change. * @type string $metadata_type * Required. The message name of the metadata type for this long-running * operation. * If the response is in a different package from the rpc, a fully-qualified * message name must be used (e.g. `google.protobuf.Struct`). * Note: Altering this value constitutes a breaking change. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Longrunning\Operations::initOnce(); parent::__construct($data); } /** * Required. The message name of the primary return type for this * long-running operation. * This type will be used to deserialize the LRO's response. * If the response is in a different package from the rpc, a fully-qualified * message name must be used (e.g. `google.protobuf.Struct`). * Note: Altering this value constitutes a breaking change. * * Generated from protobuf field string response_type = 1; * @return string */ public function getResponseType() { return $this->response_type; } /** * Required. The message name of the primary return type for this * long-running operation. * This type will be used to deserialize the LRO's response. * If the response is in a different package from the rpc, a fully-qualified * message name must be used (e.g. `google.protobuf.Struct`). * Note: Altering this value constitutes a breaking change. * * Generated from protobuf field string response_type = 1; * @param string $var * @return $this */ public function setResponseType($var) { GPBUtil::checkString($var, True); $this->response_type = $var; return $this; } /** * Required. The message name of the metadata type for this long-running * operation. * If the response is in a different package from the rpc, a fully-qualified * message name must be used (e.g. `google.protobuf.Struct`). * Note: Altering this value constitutes a breaking change. * * Generated from protobuf field string metadata_type = 2; * @return string */ public function getMetadataType() { return $this->metadata_type; } /** * Required. The message name of the metadata type for this long-running * operation. * If the response is in a different package from the rpc, a fully-qualified * message name must be used (e.g. `google.protobuf.Struct`). * Note: Altering this value constitutes a breaking change. * * Generated from protobuf field string metadata_type = 2; * @param string $var * @return $this */ public function setMetadataType($var) { GPBUtil::checkString($var, True); $this->metadata_type = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/longrunning/src/LongRunning/OperationsClient.php ================================================ _simpleRequest('/google.longrunning.Operations/ListOperations', $argument, ['\Google\LongRunning\ListOperationsResponse', 'decode'], $metadata, $options); } /** * Gets the latest state of a long-running operation. Clients can use this * method to poll the operation result at intervals as recommended by the API * service. * @param \Google\LongRunning\GetOperationRequest $argument input argument * @param array $metadata metadata * @param array $options call options * @return \Grpc\UnaryCall */ public function GetOperation(\Google\LongRunning\GetOperationRequest $argument, $metadata = [], $options = []) { return $this->_simpleRequest('/google.longrunning.Operations/GetOperation', $argument, ['\Google\LongRunning\Operation', 'decode'], $metadata, $options); } /** * Deletes a long-running operation. This method indicates that the client is * no longer interested in the operation result. It does not cancel the * operation. If the server doesn't support this method, it returns * `google.rpc.Code.UNIMPLEMENTED`. * @param \Google\LongRunning\DeleteOperationRequest $argument input argument * @param array $metadata metadata * @param array $options call options * @return \Grpc\UnaryCall */ public function DeleteOperation(\Google\LongRunning\DeleteOperationRequest $argument, $metadata = [], $options = []) { return $this->_simpleRequest('/google.longrunning.Operations/DeleteOperation', $argument, ['\Google\Protobuf\GPBEmpty', 'decode'], $metadata, $options); } /** * Starts asynchronous cancellation on a long-running operation. The server * makes a best effort to cancel the operation, but success is not * guaranteed. If the server doesn't support this method, it returns * `google.rpc.Code.UNIMPLEMENTED`. Clients can use * [Operations.GetOperation][google.longrunning.Operations.GetOperation] or * other methods to check whether the cancellation succeeded or whether the * operation completed despite cancellation. On successful cancellation, * the operation is not deleted; instead, it becomes an operation with * an [Operation.error][google.longrunning.Operation.error] value with a [google.rpc.Status.code][google.rpc.Status.code] of 1, * corresponding to `Code.CANCELLED`. * @param \Google\LongRunning\CancelOperationRequest $argument input argument * @param array $metadata metadata * @param array $options call options * @return \Grpc\UnaryCall */ public function CancelOperation(\Google\LongRunning\CancelOperationRequest $argument, $metadata = [], $options = []) { return $this->_simpleRequest('/google.longrunning.Operations/CancelOperation', $argument, ['\Google\Protobuf\GPBEmpty', 'decode'], $metadata, $options); } /** * Waits until the specified long-running operation is done or reaches at most * a specified timeout, returning the latest state. If the operation is * already done, the latest state is immediately returned. If the timeout * specified is greater than the default HTTP/RPC timeout, the HTTP/RPC * timeout is used. If the server does not support this method, it returns * `google.rpc.Code.UNIMPLEMENTED`. * Note that this method is on a best-effort basis. It may return the latest * state before the specified timeout (including immediately), meaning even an * immediate response is no guarantee that the operation is done. * @param \Google\LongRunning\WaitOperationRequest $argument input argument * @param array $metadata metadata * @param array $options call options * @return \Grpc\UnaryCall */ public function WaitOperation(\Google\LongRunning\WaitOperationRequest $argument, $metadata = [], $options = []) { return $this->_simpleRequest('/google.longrunning.Operations/WaitOperation', $argument, ['\Google\LongRunning\Operation', 'decode'], $metadata, $options); } } ================================================ FILE: lib/Google/vendor/google/longrunning/src/LongRunning/WaitOperationRequest.php ================================================ google.longrunning.WaitOperationRequest */ class WaitOperationRequest extends \Google\Protobuf\Internal\Message { /** * The name of the operation resource to wait on. * * Generated from protobuf field string name = 1; */ private $name = ''; /** * The maximum duration to wait before timing out. If left blank, the wait * will be at most the time permitted by the underlying HTTP/RPC protocol. * If RPC context deadline is also specified, the shorter one will be used. * * Generated from protobuf field .google.protobuf.Duration timeout = 2; */ private $timeout = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $name * The name of the operation resource to wait on. * @type \Google\Protobuf\Duration $timeout * The maximum duration to wait before timing out. If left blank, the wait * will be at most the time permitted by the underlying HTTP/RPC protocol. * If RPC context deadline is also specified, the shorter one will be used. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Longrunning\Operations::initOnce(); parent::__construct($data); } /** * The name of the operation resource to wait on. * * Generated from protobuf field string name = 1; * @return string */ public function getName() { return $this->name; } /** * The name of the operation resource to wait on. * * Generated from protobuf field string name = 1; * @param string $var * @return $this */ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; return $this; } /** * The maximum duration to wait before timing out. If left blank, the wait * will be at most the time permitted by the underlying HTTP/RPC protocol. * If RPC context deadline is also specified, the shorter one will be used. * * Generated from protobuf field .google.protobuf.Duration timeout = 2; * @return \Google\Protobuf\Duration|null */ public function getTimeout() { return $this->timeout; } public function hasTimeout() { return isset($this->timeout); } public function clearTimeout() { unset($this->timeout); } /** * The maximum duration to wait before timing out. If left blank, the wait * will be at most the time permitted by the underlying HTTP/RPC protocol. * If RPC context deadline is also specified, the shorter one will be used. * * Generated from protobuf field .google.protobuf.Duration timeout = 2; * @param \Google\Protobuf\Duration $var * @return $this */ public function setTimeout($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Duration::class); $this->timeout = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/longrunning/src/LongRunning/resources/operations_client_config.json ================================================ { "interfaces": { "google.longrunning.Operations": { "retry_codes": { "no_retry_codes": [], "retry_policy_1_codes": [ "UNAVAILABLE" ] }, "retry_params": { "no_retry_params": { "initial_retry_delay_millis": 0, "retry_delay_multiplier": 0.0, "max_retry_delay_millis": 0, "initial_rpc_timeout_millis": 0, "rpc_timeout_multiplier": 1.0, "max_rpc_timeout_millis": 0, "total_timeout_millis": 0 }, "retry_policy_1_params": { "initial_retry_delay_millis": 500, "retry_delay_multiplier": 2.0, "max_retry_delay_millis": 10000, "initial_rpc_timeout_millis": 10000, "rpc_timeout_multiplier": 1.0, "max_rpc_timeout_millis": 10000, "total_timeout_millis": 10000 } }, "methods": { "CancelOperation": { "timeout_millis": 10000, "retry_codes_name": "retry_policy_1_codes", "retry_params_name": "retry_policy_1_params" }, "DeleteOperation": { "timeout_millis": 10000, "retry_codes_name": "retry_policy_1_codes", "retry_params_name": "retry_policy_1_params" }, "GetOperation": { "timeout_millis": 10000, "retry_codes_name": "retry_policy_1_codes", "retry_params_name": "retry_policy_1_params" }, "ListOperations": { "timeout_millis": 10000, "retry_codes_name": "retry_policy_1_codes", "retry_params_name": "retry_policy_1_params" }, "WaitOperation": { "timeout_millis": 60000, "retry_codes_name": "no_retry_codes", "retry_params_name": "no_retry_params" } } } } } ================================================ FILE: lib/Google/vendor/google/longrunning/src/LongRunning/resources/operations_descriptor_config.php ================================================ [ 'google.longrunning.Operations' => [ 'CancelOperation' => [ 'callType' => \Google\ApiCore\Call::UNARY_CALL, 'responseType' => 'Google\Protobuf\GPBEmpty', 'headerParams' => [ [ 'keyName' => 'name', 'fieldAccessors' => [ 'getName', ], ], ], ], 'DeleteOperation' => [ 'callType' => \Google\ApiCore\Call::UNARY_CALL, 'responseType' => 'Google\Protobuf\GPBEmpty', 'headerParams' => [ [ 'keyName' => 'name', 'fieldAccessors' => [ 'getName', ], ], ], ], 'GetOperation' => [ 'callType' => \Google\ApiCore\Call::UNARY_CALL, 'responseType' => 'Google\LongRunning\Operation', 'headerParams' => [ [ 'keyName' => 'name', 'fieldAccessors' => [ 'getName', ], ], ], ], 'ListOperations' => [ 'pageStreaming' => [ 'requestPageTokenGetMethod' => 'getPageToken', 'requestPageTokenSetMethod' => 'setPageToken', 'requestPageSizeGetMethod' => 'getPageSize', 'requestPageSizeSetMethod' => 'setPageSize', 'responsePageTokenGetMethod' => 'getNextPageToken', 'resourcesGetMethod' => 'getOperations', ], 'callType' => \Google\ApiCore\Call::PAGINATED_CALL, 'responseType' => 'Google\LongRunning\ListOperationsResponse', 'headerParams' => [ [ 'keyName' => 'name', 'fieldAccessors' => [ 'getName', ], ], ], ], 'WaitOperation' => [ 'callType' => \Google\ApiCore\Call::UNARY_CALL, 'responseType' => 'Google\LongRunning\Operation', ], ], ], ]; ================================================ FILE: lib/Google/vendor/google/longrunning/src/LongRunning/resources/operations_rest_client_config.php ================================================ [ 'google.longrunning.Operations' => [ 'CancelOperation' => [ 'method' => 'post', 'uriTemplate' => '/v1/{name=operations/**}:cancel', 'body' => '*', 'placeholders' => [ 'name' => [ 'getters' => [ 'getName', ], ], ], ], 'DeleteOperation' => [ 'method' => 'delete', 'uriTemplate' => '/v1/{name=operations/**}', 'placeholders' => [ 'name' => [ 'getters' => [ 'getName', ], ], ], ], 'GetOperation' => [ 'method' => 'get', 'uriTemplate' => '/v1/{name=operations/**}', 'placeholders' => [ 'name' => [ 'getters' => [ 'getName', ], ], ], ], 'ListOperations' => [ 'method' => 'get', 'uriTemplate' => '/v1/{name=operations}', 'placeholders' => [ 'name' => [ 'getters' => [ 'getName', ], ], ], 'queryParams' => [ 'filter', ], ], ], ], ]; ================================================ FILE: lib/Google/vendor/google/protobuf/LICENSE ================================================ BSD 3-Clause License Copyright (c) 2019, Protocol Buffers 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 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. ================================================ FILE: lib/Google/vendor/google/protobuf/README.md ================================================ # protobuf-php This repository contains only PHP files to support Composer installation. This repository is a mirror of [protobuf](https://github.com/protocolbuffers/protobuf). Any support requests, bug reports, or development contributions should be directed to that project. To install protobuf for PHP, please see https://github.com/protocolbuffers/protobuf/tree/master/php ================================================ FILE: lib/Google/vendor/google/protobuf/composer.json ================================================ { "name": "google/protobuf", "type": "library", "description": "proto library for PHP", "keywords": ["proto"], "homepage": "https://developers.google.com/protocol-buffers/", "license": "BSD-3-Clause", "require": { "php": ">=8.1.0" }, "require-dev": { "phpunit/phpunit": ">=5.0.0 <8.5.27" }, "suggest": { "ext-bcmath": "Need to support JSON deserialization" }, "autoload": { "psr-4": { "Google\\Protobuf\\": "src/Google/Protobuf", "GPBMetadata\\Google\\Protobuf\\": "src/GPBMetadata/Google/Protobuf" } } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/GPBMetadata/Google/Protobuf/Any.php ================================================ internalAddGeneratedFile( "\x0A\xD4\x01\x0A\x19google/protobuf/any.proto\x12\x0Fgoogle.protobuf\"&\x0A\x03Any\x12\x10\x0A\x08type_url\x18\x01 \x01(\x09\x12\x0D\x0A\x05value\x18\x02 \x01(\x0CBv\x0A\x13com.google.protobufB\x08AnyProtoP\x01Z,google.golang.org/protobuf/types/known/anypb\xA2\x02\x03GPB\xAA\x02\x1EGoogle.Protobuf.WellKnownTypesb\x06proto3" , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/GPBMetadata/Google/Protobuf/Api.php ================================================ internalAddGeneratedFile( "\x0A\xF3\x05\x0A\x19google/protobuf/api.proto\x12\x0Fgoogle.protobuf\x1A\x1Agoogle/protobuf/type.proto\"\x92\x02\x0A\x03Api\x12\x0C\x0A\x04name\x18\x01 \x01(\x09\x12(\x0A\x07methods\x18\x02 \x03(\x0B2\x17.google.protobuf.Method\x12(\x0A\x07options\x18\x03 \x03(\x0B2\x17.google.protobuf.Option\x12\x0F\x0A\x07version\x18\x04 \x01(\x09\x126\x0A\x0Esource_context\x18\x05 \x01(\x0B2\x1E.google.protobuf.SourceContext\x12&\x0A\x06mixins\x18\x06 \x03(\x0B2\x16.google.protobuf.Mixin\x12'\x0A\x06syntax\x18\x07 \x01(\x0E2\x17.google.protobuf.Syntax\x12\x0F\x0A\x07edition\x18\x08 \x01(\x09\"\xEE\x01\x0A\x06Method\x12\x0C\x0A\x04name\x18\x01 \x01(\x09\x12\x18\x0A\x10request_type_url\x18\x02 \x01(\x09\x12\x19\x0A\x11request_streaming\x18\x03 \x01(\x08\x12\x19\x0A\x11response_type_url\x18\x04 \x01(\x09\x12\x1A\x0A\x12response_streaming\x18\x05 \x01(\x08\x12(\x0A\x07options\x18\x06 \x03(\x0B2\x17.google.protobuf.Option\x12+\x0A\x06syntax\x18\x07 \x01(\x0E2\x17.google.protobuf.SyntaxB\x02\x18\x01\x12\x13\x0A\x07edition\x18\x08 \x01(\x09B\x02\x18\x01\"#\x0A\x05Mixin\x12\x0C\x0A\x04name\x18\x01 \x01(\x09\x12\x0C\x0A\x04root\x18\x02 \x01(\x09Bv\x0A\x13com.google.protobufB\x08ApiProtoP\x01Z,google.golang.org/protobuf/types/known/apipb\xA2\x02\x03GPB\xAA\x02\x1EGoogle.Protobuf.WellKnownTypesb\x06proto3" , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/GPBMetadata/Google/Protobuf/Duration.php ================================================ internalAddGeneratedFile( "\x0A\xEB\x01\x0A\x1Egoogle/protobuf/duration.proto\x12\x0Fgoogle.protobuf\"*\x0A\x08Duration\x12\x0F\x0A\x07seconds\x18\x01 \x01(\x03\x12\x0D\x0A\x05nanos\x18\x02 \x01(\x05B\x83\x01\x0A\x13com.google.protobufB\x0DDurationProtoP\x01Z1google.golang.org/protobuf/types/known/durationpb\xF8\x01\x01\xA2\x02\x03GPB\xAA\x02\x1EGoogle.Protobuf.WellKnownTypesb\x06proto3" , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/GPBMetadata/Google/Protobuf/FieldMask.php ================================================ internalAddGeneratedFile( "\x0A\xDF\x01\x0A google/protobuf/field_mask.proto\x12\x0Fgoogle.protobuf\"\x1A\x0A\x09FieldMask\x12\x0D\x0A\x05paths\x18\x01 \x03(\x09B\x85\x01\x0A\x13com.google.protobufB\x0EFieldMaskProtoP\x01Z2google.golang.org/protobuf/types/known/fieldmaskpb\xF8\x01\x01\xA2\x02\x03GPB\xAA\x02\x1EGoogle.Protobuf.WellKnownTypesb\x06proto3" , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/GPBMetadata/Google/Protobuf/GPBEmpty.php ================================================ internalAddGeneratedFile( "\x0A\xBE\x01\x0A\x1Bgoogle/protobuf/empty.proto\x12\x0Fgoogle.protobuf\"\x07\x0A\x05EmptyB}\x0A\x13com.google.protobufB\x0AEmptyProtoP\x01Z.google.golang.org/protobuf/types/known/emptypb\xF8\x01\x01\xA2\x02\x03GPB\xAA\x02\x1EGoogle.Protobuf.WellKnownTypesb\x06proto3" , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/GPBMetadata/Google/Protobuf/Internal/Descriptor.php ================================================ addMessage('google.protobuf.internal.FileDescriptorSet', \Google\Protobuf\Internal\FileDescriptorSet::class) ->repeated('file', \Google\Protobuf\Internal\GPBType::MESSAGE, 1, 'google.protobuf.internal.FileDescriptorProto') ->finalizeToPool(); $pool->addMessage('google.protobuf.internal.FileDescriptorProto', \Google\Protobuf\Internal\FileDescriptorProto::class) ->optional('name', \Google\Protobuf\Internal\GPBType::STRING, 1) ->optional('package', \Google\Protobuf\Internal\GPBType::STRING, 2) ->repeated('dependency', \Google\Protobuf\Internal\GPBType::STRING, 3) ->repeated('public_dependency', \Google\Protobuf\Internal\GPBType::INT32, 10) ->repeated('weak_dependency', \Google\Protobuf\Internal\GPBType::INT32, 11) ->repeated('option_dependency', \Google\Protobuf\Internal\GPBType::STRING, 15) ->repeated('message_type', \Google\Protobuf\Internal\GPBType::MESSAGE, 4, 'google.protobuf.internal.DescriptorProto') ->repeated('enum_type', \Google\Protobuf\Internal\GPBType::MESSAGE, 5, 'google.protobuf.internal.EnumDescriptorProto') ->repeated('service', \Google\Protobuf\Internal\GPBType::MESSAGE, 6, 'google.protobuf.internal.ServiceDescriptorProto') ->repeated('extension', \Google\Protobuf\Internal\GPBType::MESSAGE, 7, 'google.protobuf.internal.FieldDescriptorProto') ->optional('options', \Google\Protobuf\Internal\GPBType::MESSAGE, 8, 'google.protobuf.internal.FileOptions') ->optional('source_code_info', \Google\Protobuf\Internal\GPBType::MESSAGE, 9, 'google.protobuf.internal.SourceCodeInfo') ->optional('syntax', \Google\Protobuf\Internal\GPBType::STRING, 12) ->optional('edition', \Google\Protobuf\Internal\GPBType::ENUM, 14, 'google.protobuf.internal.Edition') ->finalizeToPool(); $pool->addMessage('google.protobuf.internal.DescriptorProto', \Google\Protobuf\Internal\DescriptorProto::class) ->optional('name', \Google\Protobuf\Internal\GPBType::STRING, 1) ->repeated('field', \Google\Protobuf\Internal\GPBType::MESSAGE, 2, 'google.protobuf.internal.FieldDescriptorProto') ->repeated('extension', \Google\Protobuf\Internal\GPBType::MESSAGE, 6, 'google.protobuf.internal.FieldDescriptorProto') ->repeated('nested_type', \Google\Protobuf\Internal\GPBType::MESSAGE, 3, 'google.protobuf.internal.DescriptorProto') ->repeated('enum_type', \Google\Protobuf\Internal\GPBType::MESSAGE, 4, 'google.protobuf.internal.EnumDescriptorProto') ->repeated('extension_range', \Google\Protobuf\Internal\GPBType::MESSAGE, 5, 'google.protobuf.internal.DescriptorProto.ExtensionRange') ->repeated('oneof_decl', \Google\Protobuf\Internal\GPBType::MESSAGE, 8, 'google.protobuf.internal.OneofDescriptorProto') ->optional('options', \Google\Protobuf\Internal\GPBType::MESSAGE, 7, 'google.protobuf.internal.MessageOptions') ->repeated('reserved_range', \Google\Protobuf\Internal\GPBType::MESSAGE, 9, 'google.protobuf.internal.DescriptorProto.ReservedRange') ->repeated('reserved_name', \Google\Protobuf\Internal\GPBType::STRING, 10) ->optional('visibility', \Google\Protobuf\Internal\GPBType::ENUM, 11, 'google.protobuf.internal.SymbolVisibility') ->finalizeToPool(); $pool->addMessage('google.protobuf.internal.DescriptorProto.ExtensionRange', \Google\Protobuf\Internal\DescriptorProto\ExtensionRange::class) ->optional('start', \Google\Protobuf\Internal\GPBType::INT32, 1) ->optional('end', \Google\Protobuf\Internal\GPBType::INT32, 2) ->optional('options', \Google\Protobuf\Internal\GPBType::MESSAGE, 3, 'google.protobuf.internal.ExtensionRangeOptions') ->finalizeToPool(); $pool->addMessage('google.protobuf.internal.DescriptorProto.ReservedRange', \Google\Protobuf\Internal\DescriptorProto\ReservedRange::class) ->optional('start', \Google\Protobuf\Internal\GPBType::INT32, 1) ->optional('end', \Google\Protobuf\Internal\GPBType::INT32, 2) ->finalizeToPool(); $pool->addMessage('google.protobuf.internal.ExtensionRangeOptions', \Google\Protobuf\Internal\ExtensionRangeOptions::class) ->repeated('uninterpreted_option', \Google\Protobuf\Internal\GPBType::MESSAGE, 999, 'google.protobuf.internal.UninterpretedOption') ->repeated('declaration', \Google\Protobuf\Internal\GPBType::MESSAGE, 2, 'google.protobuf.internal.ExtensionRangeOptions.Declaration') ->optional('features', \Google\Protobuf\Internal\GPBType::MESSAGE, 50, 'google.protobuf.internal.FeatureSet') ->optional('verification', \Google\Protobuf\Internal\GPBType::ENUM, 3, 'google.protobuf.internal.ExtensionRangeOptions.VerificationState') ->finalizeToPool(); $pool->addMessage('google.protobuf.internal.ExtensionRangeOptions.Declaration', \Google\Protobuf\Internal\ExtensionRangeOptions\Declaration::class) ->optional('number', \Google\Protobuf\Internal\GPBType::INT32, 1) ->optional('full_name', \Google\Protobuf\Internal\GPBType::STRING, 2) ->optional('type', \Google\Protobuf\Internal\GPBType::STRING, 3) ->optional('reserved', \Google\Protobuf\Internal\GPBType::BOOL, 5) ->optional('repeated', \Google\Protobuf\Internal\GPBType::BOOL, 6) ->finalizeToPool(); $pool->addEnum('google.protobuf.internal.ExtensionRangeOptions.VerificationState', \Google\Protobuf\Internal\VerificationState::class) ->value("DECLARATION", 0) ->value("UNVERIFIED", 1) ->finalizeToPool(); $pool->addMessage('google.protobuf.internal.FieldDescriptorProto', \Google\Protobuf\Internal\FieldDescriptorProto::class) ->optional('name', \Google\Protobuf\Internal\GPBType::STRING, 1) ->optional('number', \Google\Protobuf\Internal\GPBType::INT32, 3) ->optional('label', \Google\Protobuf\Internal\GPBType::ENUM, 4, 'google.protobuf.internal.FieldDescriptorProto.Label') ->optional('type', \Google\Protobuf\Internal\GPBType::ENUM, 5, 'google.protobuf.internal.FieldDescriptorProto.Type') ->optional('type_name', \Google\Protobuf\Internal\GPBType::STRING, 6) ->optional('extendee', \Google\Protobuf\Internal\GPBType::STRING, 2) ->optional('default_value', \Google\Protobuf\Internal\GPBType::STRING, 7) ->optional('oneof_index', \Google\Protobuf\Internal\GPBType::INT32, 9) ->optional('json_name', \Google\Protobuf\Internal\GPBType::STRING, 10) ->optional('options', \Google\Protobuf\Internal\GPBType::MESSAGE, 8, 'google.protobuf.internal.FieldOptions') ->optional('proto3_optional', \Google\Protobuf\Internal\GPBType::BOOL, 17) ->finalizeToPool(); $pool->addEnum('google.protobuf.internal.FieldDescriptorProto.Type', \Google\Protobuf\Internal\Type::class) ->value("TYPE_DOUBLE", 1) ->value("TYPE_FLOAT", 2) ->value("TYPE_INT64", 3) ->value("TYPE_UINT64", 4) ->value("TYPE_INT32", 5) ->value("TYPE_FIXED64", 6) ->value("TYPE_FIXED32", 7) ->value("TYPE_BOOL", 8) ->value("TYPE_STRING", 9) ->value("TYPE_GROUP", 10) ->value("TYPE_MESSAGE", 11) ->value("TYPE_BYTES", 12) ->value("TYPE_UINT32", 13) ->value("TYPE_ENUM", 14) ->value("TYPE_SFIXED32", 15) ->value("TYPE_SFIXED64", 16) ->value("TYPE_SINT32", 17) ->value("TYPE_SINT64", 18) ->finalizeToPool(); $pool->addEnum('google.protobuf.internal.FieldDescriptorProto.Label', \Google\Protobuf\Internal\Label::class) ->value("LABEL_OPTIONAL", 1) ->value("LABEL_REPEATED", 3) ->value("LABEL_REQUIRED", 2) ->finalizeToPool(); $pool->addMessage('google.protobuf.internal.OneofDescriptorProto', \Google\Protobuf\Internal\OneofDescriptorProto::class) ->optional('name', \Google\Protobuf\Internal\GPBType::STRING, 1) ->optional('options', \Google\Protobuf\Internal\GPBType::MESSAGE, 2, 'google.protobuf.internal.OneofOptions') ->finalizeToPool(); $pool->addMessage('google.protobuf.internal.EnumDescriptorProto', \Google\Protobuf\Internal\EnumDescriptorProto::class) ->optional('name', \Google\Protobuf\Internal\GPBType::STRING, 1) ->repeated('value', \Google\Protobuf\Internal\GPBType::MESSAGE, 2, 'google.protobuf.internal.EnumValueDescriptorProto') ->optional('options', \Google\Protobuf\Internal\GPBType::MESSAGE, 3, 'google.protobuf.internal.EnumOptions') ->repeated('reserved_range', \Google\Protobuf\Internal\GPBType::MESSAGE, 4, 'google.protobuf.internal.EnumDescriptorProto.EnumReservedRange') ->repeated('reserved_name', \Google\Protobuf\Internal\GPBType::STRING, 5) ->optional('visibility', \Google\Protobuf\Internal\GPBType::ENUM, 6, 'google.protobuf.internal.SymbolVisibility') ->finalizeToPool(); $pool->addMessage('google.protobuf.internal.EnumDescriptorProto.EnumReservedRange', \Google\Protobuf\Internal\EnumDescriptorProto\EnumReservedRange::class) ->optional('start', \Google\Protobuf\Internal\GPBType::INT32, 1) ->optional('end', \Google\Protobuf\Internal\GPBType::INT32, 2) ->finalizeToPool(); $pool->addMessage('google.protobuf.internal.EnumValueDescriptorProto', \Google\Protobuf\Internal\EnumValueDescriptorProto::class) ->optional('name', \Google\Protobuf\Internal\GPBType::STRING, 1) ->optional('number', \Google\Protobuf\Internal\GPBType::INT32, 2) ->optional('options', \Google\Protobuf\Internal\GPBType::MESSAGE, 3, 'google.protobuf.internal.EnumValueOptions') ->finalizeToPool(); $pool->addMessage('google.protobuf.internal.ServiceDescriptorProto', \Google\Protobuf\Internal\ServiceDescriptorProto::class) ->optional('name', \Google\Protobuf\Internal\GPBType::STRING, 1) ->repeated('method', \Google\Protobuf\Internal\GPBType::MESSAGE, 2, 'google.protobuf.internal.MethodDescriptorProto') ->optional('options', \Google\Protobuf\Internal\GPBType::MESSAGE, 3, 'google.protobuf.internal.ServiceOptions') ->finalizeToPool(); $pool->addMessage('google.protobuf.internal.MethodDescriptorProto', \Google\Protobuf\Internal\MethodDescriptorProto::class) ->optional('name', \Google\Protobuf\Internal\GPBType::STRING, 1) ->optional('input_type', \Google\Protobuf\Internal\GPBType::STRING, 2) ->optional('output_type', \Google\Protobuf\Internal\GPBType::STRING, 3) ->optional('options', \Google\Protobuf\Internal\GPBType::MESSAGE, 4, 'google.protobuf.internal.MethodOptions') ->optional('client_streaming', \Google\Protobuf\Internal\GPBType::BOOL, 5) ->optional('server_streaming', \Google\Protobuf\Internal\GPBType::BOOL, 6) ->finalizeToPool(); $pool->addMessage('google.protobuf.internal.FileOptions', \Google\Protobuf\Internal\FileOptions::class) ->optional('java_package', \Google\Protobuf\Internal\GPBType::STRING, 1) ->optional('java_outer_classname', \Google\Protobuf\Internal\GPBType::STRING, 8) ->optional('java_multiple_files', \Google\Protobuf\Internal\GPBType::BOOL, 10) ->optional('java_generate_equals_and_hash', \Google\Protobuf\Internal\GPBType::BOOL, 20) ->optional('java_string_check_utf8', \Google\Protobuf\Internal\GPBType::BOOL, 27) ->optional('optimize_for', \Google\Protobuf\Internal\GPBType::ENUM, 9, 'google.protobuf.internal.FileOptions.OptimizeMode') ->optional('go_package', \Google\Protobuf\Internal\GPBType::STRING, 11) ->optional('cc_generic_services', \Google\Protobuf\Internal\GPBType::BOOL, 16) ->optional('java_generic_services', \Google\Protobuf\Internal\GPBType::BOOL, 17) ->optional('py_generic_services', \Google\Protobuf\Internal\GPBType::BOOL, 18) ->optional('deprecated', \Google\Protobuf\Internal\GPBType::BOOL, 23) ->optional('cc_enable_arenas', \Google\Protobuf\Internal\GPBType::BOOL, 31) ->optional('objc_class_prefix', \Google\Protobuf\Internal\GPBType::STRING, 36) ->optional('csharp_namespace', \Google\Protobuf\Internal\GPBType::STRING, 37) ->optional('swift_prefix', \Google\Protobuf\Internal\GPBType::STRING, 39) ->optional('php_class_prefix', \Google\Protobuf\Internal\GPBType::STRING, 40) ->optional('php_namespace', \Google\Protobuf\Internal\GPBType::STRING, 41) ->optional('php_metadata_namespace', \Google\Protobuf\Internal\GPBType::STRING, 44) ->optional('ruby_package', \Google\Protobuf\Internal\GPBType::STRING, 45) ->optional('features', \Google\Protobuf\Internal\GPBType::MESSAGE, 50, 'google.protobuf.internal.FeatureSet') ->repeated('uninterpreted_option', \Google\Protobuf\Internal\GPBType::MESSAGE, 999, 'google.protobuf.internal.UninterpretedOption') ->finalizeToPool(); $pool->addEnum('google.protobuf.internal.FileOptions.OptimizeMode', \Google\Protobuf\Internal\OptimizeMode::class) ->value("SPEED", 1) ->value("CODE_SIZE", 2) ->value("LITE_RUNTIME", 3) ->finalizeToPool(); $pool->addMessage('google.protobuf.internal.MessageOptions', \Google\Protobuf\Internal\MessageOptions::class) ->optional('message_set_wire_format', \Google\Protobuf\Internal\GPBType::BOOL, 1) ->optional('no_standard_descriptor_accessor', \Google\Protobuf\Internal\GPBType::BOOL, 2) ->optional('deprecated', \Google\Protobuf\Internal\GPBType::BOOL, 3) ->optional('map_entry', \Google\Protobuf\Internal\GPBType::BOOL, 7) ->optional('deprecated_legacy_json_field_conflicts', \Google\Protobuf\Internal\GPBType::BOOL, 11) ->optional('features', \Google\Protobuf\Internal\GPBType::MESSAGE, 12, 'google.protobuf.internal.FeatureSet') ->repeated('uninterpreted_option', \Google\Protobuf\Internal\GPBType::MESSAGE, 999, 'google.protobuf.internal.UninterpretedOption') ->finalizeToPool(); $pool->addMessage('google.protobuf.internal.FieldOptions', \Google\Protobuf\Internal\FieldOptions::class) ->optional('ctype', \Google\Protobuf\Internal\GPBType::ENUM, 1, 'google.protobuf.internal.FieldOptions.CType') ->optional('packed', \Google\Protobuf\Internal\GPBType::BOOL, 2) ->optional('jstype', \Google\Protobuf\Internal\GPBType::ENUM, 6, 'google.protobuf.internal.FieldOptions.JSType') ->optional('lazy', \Google\Protobuf\Internal\GPBType::BOOL, 5) ->optional('unverified_lazy', \Google\Protobuf\Internal\GPBType::BOOL, 15) ->optional('deprecated', \Google\Protobuf\Internal\GPBType::BOOL, 3) ->optional('weak', \Google\Protobuf\Internal\GPBType::BOOL, 10) ->optional('debug_redact', \Google\Protobuf\Internal\GPBType::BOOL, 16) ->optional('retention', \Google\Protobuf\Internal\GPBType::ENUM, 17, 'google.protobuf.internal.FieldOptions.OptionRetention') ->repeated('targets', \Google\Protobuf\Internal\GPBType::ENUM, 19, 'google.protobuf.internal.FieldOptions.OptionTargetType') ->repeated('edition_defaults', \Google\Protobuf\Internal\GPBType::MESSAGE, 20, 'google.protobuf.internal.FieldOptions.EditionDefault') ->optional('features', \Google\Protobuf\Internal\GPBType::MESSAGE, 21, 'google.protobuf.internal.FeatureSet') ->optional('feature_support', \Google\Protobuf\Internal\GPBType::MESSAGE, 22, 'google.protobuf.internal.FieldOptions.FeatureSupport') ->repeated('uninterpreted_option', \Google\Protobuf\Internal\GPBType::MESSAGE, 999, 'google.protobuf.internal.UninterpretedOption') ->finalizeToPool(); $pool->addMessage('google.protobuf.internal.FieldOptions.EditionDefault', \Google\Protobuf\Internal\FieldOptions\EditionDefault::class) ->optional('edition', \Google\Protobuf\Internal\GPBType::ENUM, 3, 'google.protobuf.internal.Edition') ->optional('value', \Google\Protobuf\Internal\GPBType::STRING, 2) ->finalizeToPool(); $pool->addMessage('google.protobuf.internal.FieldOptions.FeatureSupport', \Google\Protobuf\Internal\FieldOptions\FeatureSupport::class) ->optional('edition_introduced', \Google\Protobuf\Internal\GPBType::ENUM, 1, 'google.protobuf.internal.Edition') ->optional('edition_deprecated', \Google\Protobuf\Internal\GPBType::ENUM, 2, 'google.protobuf.internal.Edition') ->optional('deprecation_warning', \Google\Protobuf\Internal\GPBType::STRING, 3) ->optional('edition_removed', \Google\Protobuf\Internal\GPBType::ENUM, 4, 'google.protobuf.internal.Edition') ->finalizeToPool(); $pool->addEnum('google.protobuf.internal.FieldOptions.CType', \Google\Protobuf\Internal\CType::class) ->value("STRING", 0) ->value("CORD", 1) ->value("STRING_PIECE", 2) ->finalizeToPool(); $pool->addEnum('google.protobuf.internal.FieldOptions.JSType', \Google\Protobuf\Internal\JSType::class) ->value("JS_NORMAL", 0) ->value("JS_STRING", 1) ->value("JS_NUMBER", 2) ->finalizeToPool(); $pool->addEnum('google.protobuf.internal.FieldOptions.OptionRetention', \Google\Protobuf\Internal\OptionRetention::class) ->value("RETENTION_UNKNOWN", 0) ->value("RETENTION_RUNTIME", 1) ->value("RETENTION_SOURCE", 2) ->finalizeToPool(); $pool->addEnum('google.protobuf.internal.FieldOptions.OptionTargetType', \Google\Protobuf\Internal\OptionTargetType::class) ->value("TARGET_TYPE_UNKNOWN", 0) ->value("TARGET_TYPE_FILE", 1) ->value("TARGET_TYPE_EXTENSION_RANGE", 2) ->value("TARGET_TYPE_MESSAGE", 3) ->value("TARGET_TYPE_FIELD", 4) ->value("TARGET_TYPE_ONEOF", 5) ->value("TARGET_TYPE_ENUM", 6) ->value("TARGET_TYPE_ENUM_ENTRY", 7) ->value("TARGET_TYPE_SERVICE", 8) ->value("TARGET_TYPE_METHOD", 9) ->finalizeToPool(); $pool->addMessage('google.protobuf.internal.OneofOptions', \Google\Protobuf\Internal\OneofOptions::class) ->optional('features', \Google\Protobuf\Internal\GPBType::MESSAGE, 1, 'google.protobuf.internal.FeatureSet') ->repeated('uninterpreted_option', \Google\Protobuf\Internal\GPBType::MESSAGE, 999, 'google.protobuf.internal.UninterpretedOption') ->finalizeToPool(); $pool->addMessage('google.protobuf.internal.EnumOptions', \Google\Protobuf\Internal\EnumOptions::class) ->optional('allow_alias', \Google\Protobuf\Internal\GPBType::BOOL, 2) ->optional('deprecated', \Google\Protobuf\Internal\GPBType::BOOL, 3) ->optional('deprecated_legacy_json_field_conflicts', \Google\Protobuf\Internal\GPBType::BOOL, 6) ->optional('features', \Google\Protobuf\Internal\GPBType::MESSAGE, 7, 'google.protobuf.internal.FeatureSet') ->repeated('uninterpreted_option', \Google\Protobuf\Internal\GPBType::MESSAGE, 999, 'google.protobuf.internal.UninterpretedOption') ->finalizeToPool(); $pool->addMessage('google.protobuf.internal.EnumValueOptions', \Google\Protobuf\Internal\EnumValueOptions::class) ->optional('deprecated', \Google\Protobuf\Internal\GPBType::BOOL, 1) ->optional('features', \Google\Protobuf\Internal\GPBType::MESSAGE, 2, 'google.protobuf.internal.FeatureSet') ->optional('debug_redact', \Google\Protobuf\Internal\GPBType::BOOL, 3) ->optional('feature_support', \Google\Protobuf\Internal\GPBType::MESSAGE, 4, 'google.protobuf.internal.FieldOptions.FeatureSupport') ->repeated('uninterpreted_option', \Google\Protobuf\Internal\GPBType::MESSAGE, 999, 'google.protobuf.internal.UninterpretedOption') ->finalizeToPool(); $pool->addMessage('google.protobuf.internal.ServiceOptions', \Google\Protobuf\Internal\ServiceOptions::class) ->optional('features', \Google\Protobuf\Internal\GPBType::MESSAGE, 34, 'google.protobuf.internal.FeatureSet') ->optional('deprecated', \Google\Protobuf\Internal\GPBType::BOOL, 33) ->repeated('uninterpreted_option', \Google\Protobuf\Internal\GPBType::MESSAGE, 999, 'google.protobuf.internal.UninterpretedOption') ->finalizeToPool(); $pool->addMessage('google.protobuf.internal.MethodOptions', \Google\Protobuf\Internal\MethodOptions::class) ->optional('deprecated', \Google\Protobuf\Internal\GPBType::BOOL, 33) ->optional('idempotency_level', \Google\Protobuf\Internal\GPBType::ENUM, 34, 'google.protobuf.internal.MethodOptions.IdempotencyLevel') ->optional('features', \Google\Protobuf\Internal\GPBType::MESSAGE, 35, 'google.protobuf.internal.FeatureSet') ->repeated('uninterpreted_option', \Google\Protobuf\Internal\GPBType::MESSAGE, 999, 'google.protobuf.internal.UninterpretedOption') ->finalizeToPool(); $pool->addEnum('google.protobuf.internal.MethodOptions.IdempotencyLevel', \Google\Protobuf\Internal\IdempotencyLevel::class) ->value("IDEMPOTENCY_UNKNOWN", 0) ->value("NO_SIDE_EFFECTS", 1) ->value("IDEMPOTENT", 2) ->finalizeToPool(); $pool->addMessage('google.protobuf.internal.UninterpretedOption', \Google\Protobuf\Internal\UninterpretedOption::class) ->repeated('name', \Google\Protobuf\Internal\GPBType::MESSAGE, 2, 'google.protobuf.internal.UninterpretedOption.NamePart') ->optional('identifier_value', \Google\Protobuf\Internal\GPBType::STRING, 3) ->optional('positive_int_value', \Google\Protobuf\Internal\GPBType::UINT64, 4) ->optional('negative_int_value', \Google\Protobuf\Internal\GPBType::INT64, 5) ->optional('double_value', \Google\Protobuf\Internal\GPBType::DOUBLE, 6) ->optional('string_value', \Google\Protobuf\Internal\GPBType::BYTES, 7) ->optional('aggregate_value', \Google\Protobuf\Internal\GPBType::STRING, 8) ->finalizeToPool(); $pool->addMessage('google.protobuf.internal.UninterpretedOption.NamePart', \Google\Protobuf\Internal\UninterpretedOption\NamePart::class) ->required('name_part', \Google\Protobuf\Internal\GPBType::STRING, 1) ->required('is_extension', \Google\Protobuf\Internal\GPBType::BOOL, 2) ->finalizeToPool(); $pool->addMessage('google.protobuf.internal.FeatureSet', \Google\Protobuf\Internal\FeatureSet::class) ->optional('field_presence', \Google\Protobuf\Internal\GPBType::ENUM, 1, 'google.protobuf.internal.FeatureSet.FieldPresence') ->optional('enum_type', \Google\Protobuf\Internal\GPBType::ENUM, 2, 'google.protobuf.internal.FeatureSet.EnumType') ->optional('repeated_field_encoding', \Google\Protobuf\Internal\GPBType::ENUM, 3, 'google.protobuf.internal.FeatureSet.RepeatedFieldEncoding') ->optional('utf8_validation', \Google\Protobuf\Internal\GPBType::ENUM, 4, 'google.protobuf.internal.FeatureSet.Utf8Validation') ->optional('message_encoding', \Google\Protobuf\Internal\GPBType::ENUM, 5, 'google.protobuf.internal.FeatureSet.MessageEncoding') ->optional('json_format', \Google\Protobuf\Internal\GPBType::ENUM, 6, 'google.protobuf.internal.FeatureSet.JsonFormat') ->optional('enforce_naming_style', \Google\Protobuf\Internal\GPBType::ENUM, 7, 'google.protobuf.internal.FeatureSet.EnforceNamingStyle') ->optional('default_symbol_visibility', \Google\Protobuf\Internal\GPBType::ENUM, 8, 'google.protobuf.internal.FeatureSet.VisibilityFeature.DefaultSymbolVisibility') ->finalizeToPool(); $pool->addMessage('google.protobuf.internal.FeatureSet.VisibilityFeature', \Google\Protobuf\Internal\FeatureSet\VisibilityFeature::class) ->finalizeToPool(); $pool->addEnum('google.protobuf.internal.FeatureSet.VisibilityFeature.DefaultSymbolVisibility', \Google\Protobuf\Internal\DefaultSymbolVisibility::class) ->value("DEFAULT_SYMBOL_VISIBILITY_UNKNOWN", 0) ->value("EXPORT_ALL", 1) ->value("EXPORT_TOP_LEVEL", 2) ->value("LOCAL_ALL", 3) ->value("STRICT", 4) ->finalizeToPool(); $pool->addEnum('google.protobuf.internal.FeatureSet.FieldPresence', \Google\Protobuf\Internal\FieldPresence::class) ->value("FIELD_PRESENCE_UNKNOWN", 0) ->value("EXPLICIT", 1) ->value("IMPLICIT", 2) ->value("LEGACY_REQUIRED", 3) ->finalizeToPool(); $pool->addEnum('google.protobuf.internal.FeatureSet.EnumType', \Google\Protobuf\Internal\EnumType::class) ->value("ENUM_TYPE_UNKNOWN", 0) ->value("OPEN", 1) ->value("CLOSED", 2) ->finalizeToPool(); $pool->addEnum('google.protobuf.internal.FeatureSet.RepeatedFieldEncoding', \Google\Protobuf\Internal\RepeatedFieldEncoding::class) ->value("REPEATED_FIELD_ENCODING_UNKNOWN", 0) ->value("PACKED", 1) ->value("EXPANDED", 2) ->finalizeToPool(); $pool->addEnum('google.protobuf.internal.FeatureSet.Utf8Validation', \Google\Protobuf\Internal\Utf8Validation::class) ->value("UTF8_VALIDATION_UNKNOWN", 0) ->value("VERIFY", 2) ->value("NONE", 3) ->finalizeToPool(); $pool->addEnum('google.protobuf.internal.FeatureSet.MessageEncoding', \Google\Protobuf\Internal\MessageEncoding::class) ->value("MESSAGE_ENCODING_UNKNOWN", 0) ->value("LENGTH_PREFIXED", 1) ->value("DELIMITED", 2) ->finalizeToPool(); $pool->addEnum('google.protobuf.internal.FeatureSet.JsonFormat', \Google\Protobuf\Internal\JsonFormat::class) ->value("JSON_FORMAT_UNKNOWN", 0) ->value("ALLOW", 1) ->value("LEGACY_BEST_EFFORT", 2) ->finalizeToPool(); $pool->addEnum('google.protobuf.internal.FeatureSet.EnforceNamingStyle', \Google\Protobuf\Internal\EnforceNamingStyle::class) ->value("ENFORCE_NAMING_STYLE_UNKNOWN", 0) ->value("STYLE2024", 1) ->value("STYLE_LEGACY", 2) ->finalizeToPool(); $pool->addMessage('google.protobuf.internal.FeatureSetDefaults', \Google\Protobuf\Internal\FeatureSetDefaults::class) ->repeated('defaults', \Google\Protobuf\Internal\GPBType::MESSAGE, 1, 'google.protobuf.internal.FeatureSetDefaults.FeatureSetEditionDefault') ->optional('minimum_edition', \Google\Protobuf\Internal\GPBType::ENUM, 4, 'google.protobuf.internal.Edition') ->optional('maximum_edition', \Google\Protobuf\Internal\GPBType::ENUM, 5, 'google.protobuf.internal.Edition') ->finalizeToPool(); $pool->addMessage('google.protobuf.internal.FeatureSetDefaults.FeatureSetEditionDefault', \Google\Protobuf\Internal\FeatureSetDefaults\FeatureSetEditionDefault::class) ->optional('edition', \Google\Protobuf\Internal\GPBType::ENUM, 3, 'google.protobuf.internal.Edition') ->optional('overridable_features', \Google\Protobuf\Internal\GPBType::MESSAGE, 4, 'google.protobuf.internal.FeatureSet') ->optional('fixed_features', \Google\Protobuf\Internal\GPBType::MESSAGE, 5, 'google.protobuf.internal.FeatureSet') ->finalizeToPool(); $pool->addMessage('google.protobuf.internal.SourceCodeInfo', \Google\Protobuf\Internal\SourceCodeInfo::class) ->repeated('location', \Google\Protobuf\Internal\GPBType::MESSAGE, 1, 'google.protobuf.internal.SourceCodeInfo.Location') ->finalizeToPool(); $pool->addMessage('google.protobuf.internal.SourceCodeInfo.Location', \Google\Protobuf\Internal\SourceCodeInfo\Location::class) ->repeated('path', \Google\Protobuf\Internal\GPBType::INT32, 1) ->repeated('span', \Google\Protobuf\Internal\GPBType::INT32, 2) ->optional('leading_comments', \Google\Protobuf\Internal\GPBType::STRING, 3) ->optional('trailing_comments', \Google\Protobuf\Internal\GPBType::STRING, 4) ->repeated('leading_detached_comments', \Google\Protobuf\Internal\GPBType::STRING, 6) ->finalizeToPool(); $pool->addMessage('google.protobuf.internal.GeneratedCodeInfo', \Google\Protobuf\Internal\GeneratedCodeInfo::class) ->repeated('annotation', \Google\Protobuf\Internal\GPBType::MESSAGE, 1, 'google.protobuf.internal.GeneratedCodeInfo.Annotation') ->finalizeToPool(); $pool->addMessage('google.protobuf.internal.GeneratedCodeInfo.Annotation', \Google\Protobuf\Internal\GeneratedCodeInfo\Annotation::class) ->repeated('path', \Google\Protobuf\Internal\GPBType::INT32, 1) ->optional('source_file', \Google\Protobuf\Internal\GPBType::STRING, 2) ->optional('begin', \Google\Protobuf\Internal\GPBType::INT32, 3) ->optional('end', \Google\Protobuf\Internal\GPBType::INT32, 4) ->optional('semantic', \Google\Protobuf\Internal\GPBType::ENUM, 5, 'google.protobuf.internal.GeneratedCodeInfo.Annotation.Semantic') ->finalizeToPool(); $pool->addEnum('google.protobuf.internal.GeneratedCodeInfo.Annotation.Semantic', \Google\Protobuf\Internal\Semantic::class) ->value("NONE", 0) ->value("SET", 1) ->value("ALIAS", 2) ->finalizeToPool(); $pool->addEnum('google.protobuf.internal.Edition', \Google\Protobuf\Internal\Edition::class) ->value("EDITION_UNKNOWN", 0) ->value("EDITION_LEGACY", 900) ->value("EDITION_PROTO2", 998) ->value("EDITION_PROTO3", 999) ->value("EDITION_2023", 1000) ->value("EDITION_2024", 1001) ->value("EDITION_UNSTABLE", 9999) ->value("EDITION_1_TEST_ONLY", 1) ->value("EDITION_2_TEST_ONLY", 2) ->value("EDITION_99997_TEST_ONLY", 99997) ->value("EDITION_99998_TEST_ONLY", 99998) ->value("EDITION_99999_TEST_ONLY", 99999) ->value("EDITION_MAX", 2147483647) ->finalizeToPool(); $pool->addEnum('google.protobuf.internal.SymbolVisibility', \Google\Protobuf\Internal\SymbolVisibility::class) ->value("VISIBILITY_UNSET", 0) ->value("VISIBILITY_LOCAL", 1) ->value("VISIBILITY_EXPORT", 2) ->finalizeToPool(); $pool->finish(); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/GPBMetadata/Google/Protobuf/SourceContext.php ================================================ internalAddGeneratedFile( "\x0A\xF0\x01\x0A\$google/protobuf/source_context.proto\x12\x0Fgoogle.protobuf\"\"\x0A\x0DSourceContext\x12\x11\x0A\x09file_name\x18\x01 \x01(\x09B\x8A\x01\x0A\x13com.google.protobufB\x12SourceContextProtoP\x01Z6google.golang.org/protobuf/types/known/sourcecontextpb\xA2\x02\x03GPB\xAA\x02\x1EGoogle.Protobuf.WellKnownTypesb\x06proto3" , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/GPBMetadata/Google/Protobuf/Struct.php ================================================ internalAddGeneratedFile( "\x0A\xFE\x04\x0A\x1Cgoogle/protobuf/struct.proto\x12\x0Fgoogle.protobuf\"\x84\x01\x0A\x06Struct\x123\x0A\x06fields\x18\x01 \x03(\x0B2#.google.protobuf.Struct.FieldsEntry\x1AE\x0A\x0BFieldsEntry\x12\x0B\x0A\x03key\x18\x01 \x01(\x09\x12%\x0A\x05value\x18\x02 \x01(\x0B2\x16.google.protobuf.Value:\x028\x01\"\xEA\x01\x0A\x05Value\x120\x0A\x0Anull_value\x18\x01 \x01(\x0E2\x1A.google.protobuf.NullValueH\x00\x12\x16\x0A\x0Cnumber_value\x18\x02 \x01(\x01H\x00\x12\x16\x0A\x0Cstring_value\x18\x03 \x01(\x09H\x00\x12\x14\x0A\x0Abool_value\x18\x04 \x01(\x08H\x00\x12/\x0A\x0Cstruct_value\x18\x05 \x01(\x0B2\x17.google.protobuf.StructH\x00\x120\x0A\x0Alist_value\x18\x06 \x01(\x0B2\x1A.google.protobuf.ListValueH\x00B\x06\x0A\x04kind\"3\x0A\x09ListValue\x12&\x0A\x06values\x18\x01 \x03(\x0B2\x16.google.protobuf.Value*\x1B\x0A\x09NullValue\x12\x0E\x0A\x0ANULL_VALUE\x10\x00B\x7F\x0A\x13com.google.protobufB\x0BStructProtoP\x01Z/google.golang.org/protobuf/types/known/structpb\xF8\x01\x01\xA2\x02\x03GPB\xAA\x02\x1EGoogle.Protobuf.WellKnownTypesb\x06proto3" , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/GPBMetadata/Google/Protobuf/Timestamp.php ================================================ internalAddGeneratedFile( "\x0A\xEF\x01\x0A\x1Fgoogle/protobuf/timestamp.proto\x12\x0Fgoogle.protobuf\"+\x0A\x09Timestamp\x12\x0F\x0A\x07seconds\x18\x01 \x01(\x03\x12\x0D\x0A\x05nanos\x18\x02 \x01(\x05B\x85\x01\x0A\x13com.google.protobufB\x0ETimestampProtoP\x01Z2google.golang.org/protobuf/types/known/timestamppb\xF8\x01\x01\xA2\x02\x03GPB\xAA\x02\x1EGoogle.Protobuf.WellKnownTypesb\x06proto3" , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/GPBMetadata/Google/Protobuf/Type.php ================================================ internalAddGeneratedFile( "\x0A\xD4\x0C\x0A\x1Agoogle/protobuf/type.proto\x12\x0Fgoogle.protobuf\x1A\$google/protobuf/source_context.proto\"\xE8\x01\x0A\x04Type\x12\x0C\x0A\x04name\x18\x01 \x01(\x09\x12&\x0A\x06fields\x18\x02 \x03(\x0B2\x16.google.protobuf.Field\x12\x0E\x0A\x06oneofs\x18\x03 \x03(\x09\x12(\x0A\x07options\x18\x04 \x03(\x0B2\x17.google.protobuf.Option\x126\x0A\x0Esource_context\x18\x05 \x01(\x0B2\x1E.google.protobuf.SourceContext\x12'\x0A\x06syntax\x18\x06 \x01(\x0E2\x17.google.protobuf.Syntax\x12\x0F\x0A\x07edition\x18\x07 \x01(\x09\"\xD5\x05\x0A\x05Field\x12)\x0A\x04kind\x18\x01 \x01(\x0E2\x1B.google.protobuf.Field.Kind\x127\x0A\x0Bcardinality\x18\x02 \x01(\x0E2\".google.protobuf.Field.Cardinality\x12\x0E\x0A\x06number\x18\x03 \x01(\x05\x12\x0C\x0A\x04name\x18\x04 \x01(\x09\x12\x10\x0A\x08type_url\x18\x06 \x01(\x09\x12\x13\x0A\x0Boneof_index\x18\x07 \x01(\x05\x12\x0E\x0A\x06packed\x18\x08 \x01(\x08\x12(\x0A\x07options\x18\x09 \x03(\x0B2\x17.google.protobuf.Option\x12\x11\x0A\x09json_name\x18\x0A \x01(\x09\x12\x15\x0A\x0Ddefault_value\x18\x0B \x01(\x09\"\xC8\x02\x0A\x04Kind\x12\x10\x0A\x0CTYPE_UNKNOWN\x10\x00\x12\x0F\x0A\x0BTYPE_DOUBLE\x10\x01\x12\x0E\x0A\x0ATYPE_FLOAT\x10\x02\x12\x0E\x0A\x0ATYPE_INT64\x10\x03\x12\x0F\x0A\x0BTYPE_UINT64\x10\x04\x12\x0E\x0A\x0ATYPE_INT32\x10\x05\x12\x10\x0A\x0CTYPE_FIXED64\x10\x06\x12\x10\x0A\x0CTYPE_FIXED32\x10\x07\x12\x0D\x0A\x09TYPE_BOOL\x10\x08\x12\x0F\x0A\x0BTYPE_STRING\x10\x09\x12\x0E\x0A\x0ATYPE_GROUP\x10\x0A\x12\x10\x0A\x0CTYPE_MESSAGE\x10\x0B\x12\x0E\x0A\x0ATYPE_BYTES\x10\x0C\x12\x0F\x0A\x0BTYPE_UINT32\x10\x0D\x12\x0D\x0A\x09TYPE_ENUM\x10\x0E\x12\x11\x0A\x0DTYPE_SFIXED32\x10\x0F\x12\x11\x0A\x0DTYPE_SFIXED64\x10\x10\x12\x0F\x0A\x0BTYPE_SINT32\x10\x11\x12\x0F\x0A\x0BTYPE_SINT64\x10\x12\"t\x0A\x0BCardinality\x12\x17\x0A\x13CARDINALITY_UNKNOWN\x10\x00\x12\x18\x0A\x14CARDINALITY_OPTIONAL\x10\x01\x12\x18\x0A\x14CARDINALITY_REQUIRED\x10\x02\x12\x18\x0A\x14CARDINALITY_REPEATED\x10\x03\"\xDF\x01\x0A\x04Enum\x12\x0C\x0A\x04name\x18\x01 \x01(\x09\x12-\x0A\x09enumvalue\x18\x02 \x03(\x0B2\x1A.google.protobuf.EnumValue\x12(\x0A\x07options\x18\x03 \x03(\x0B2\x17.google.protobuf.Option\x126\x0A\x0Esource_context\x18\x04 \x01(\x0B2\x1E.google.protobuf.SourceContext\x12'\x0A\x06syntax\x18\x05 \x01(\x0E2\x17.google.protobuf.Syntax\x12\x0F\x0A\x07edition\x18\x06 \x01(\x09\"S\x0A\x09EnumValue\x12\x0C\x0A\x04name\x18\x01 \x01(\x09\x12\x0E\x0A\x06number\x18\x02 \x01(\x05\x12(\x0A\x07options\x18\x03 \x03(\x0B2\x17.google.protobuf.Option\";\x0A\x06Option\x12\x0C\x0A\x04name\x18\x01 \x01(\x09\x12#\x0A\x05value\x18\x02 \x01(\x0B2\x14.google.protobuf.Any*C\x0A\x06Syntax\x12\x11\x0A\x0DSYNTAX_PROTO2\x10\x00\x12\x11\x0A\x0DSYNTAX_PROTO3\x10\x01\x12\x13\x0A\x0FSYNTAX_EDITIONS\x10\x02B{\x0A\x13com.google.protobufB\x09TypeProtoP\x01Z-google.golang.org/protobuf/types/known/typepb\xF8\x01\x01\xA2\x02\x03GPB\xAA\x02\x1EGoogle.Protobuf.WellKnownTypesb\x06proto3" , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/GPBMetadata/Google/Protobuf/Wrappers.php ================================================ internalAddGeneratedFile( "\x0A\xC7\x03\x0A\x1Egoogle/protobuf/wrappers.proto\x12\x0Fgoogle.protobuf\"\x1C\x0A\x0BDoubleValue\x12\x0D\x0A\x05value\x18\x01 \x01(\x01\"\x1B\x0A\x0AFloatValue\x12\x0D\x0A\x05value\x18\x01 \x01(\x02\"\x1B\x0A\x0AInt64Value\x12\x0D\x0A\x05value\x18\x01 \x01(\x03\"\x1C\x0A\x0BUInt64Value\x12\x0D\x0A\x05value\x18\x01 \x01(\x04\"\x1B\x0A\x0AInt32Value\x12\x0D\x0A\x05value\x18\x01 \x01(\x05\"\x1C\x0A\x0BUInt32Value\x12\x0D\x0A\x05value\x18\x01 \x01(\x0D\"\x1A\x0A\x09BoolValue\x12\x0D\x0A\x05value\x18\x01 \x01(\x08\"\x1C\x0A\x0BStringValue\x12\x0D\x0A\x05value\x18\x01 \x01(\x09\"\x1B\x0A\x0ABytesValue\x12\x0D\x0A\x05value\x18\x01 \x01(\x0CB\x83\x01\x0A\x13com.google.protobufB\x0DWrappersProtoP\x01Z1google.golang.org/protobuf/types/known/wrapperspb\xF8\x01\x01\xA2\x02\x03GPB\xAA\x02\x1EGoogle.Protobuf.WellKnownTypesb\x06proto3" , true); static::$is_initialized = true; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Any.php ================================================ , * "lastName": * } * If the embedded message type is well-known and has a custom JSON * representation, that representation will be embedded adding a field * `value` which holds the custom JSON in addition to the `\@type` * field. Example (for message [google.protobuf.Duration][]): * { * "\@type": "type.googleapis.com/google.protobuf.Duration", * "value": "1.212s" * } * * Generated from protobuf message google.protobuf.Any */ class Any extends \Google\Protobuf\Internal\AnyBase { /** * A URL/resource name that uniquely identifies the type of the serialized * protocol buffer message. This string must contain at least * one "/" character. The last segment of the URL's path must represent * the fully qualified name of the type (as in * `path/google.protobuf.Duration`). The name should be in a canonical form * (e.g., leading "." is not accepted). * In practice, teams usually precompile into the binary all types that they * expect it to use in the context of Any. However, for URLs which use the * scheme `http`, `https`, or no scheme, one can optionally set up a type * server that maps type URLs to message definitions as follows: * * If no scheme is provided, `https` is assumed. * * An HTTP GET on the URL must yield a [google.protobuf.Type][] * value in binary format, or produce an error. * * Applications are allowed to cache lookup results based on the * URL, or have them precompiled into a binary to avoid any * lookup. Therefore, binary compatibility needs to be preserved * on changes to types. (Use versioned type names to manage * breaking changes.) * Note: this functionality is not currently available in the official * protobuf release, and it is not used for type URLs beginning with * type.googleapis.com. As of May 2023, there are no widely used type server * implementations and no plans to implement one. * Schemes other than `http`, `https` (or the empty scheme) might be * used with implementation specific semantics. * * Generated from protobuf field string type_url = 1; */ protected $type_url = ''; /** * Must be a valid serialized protocol buffer of the above specified type. * * Generated from protobuf field bytes value = 2; */ protected $value = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $type_url * A URL/resource name that uniquely identifies the type of the serialized * protocol buffer message. This string must contain at least * one "/" character. The last segment of the URL's path must represent * the fully qualified name of the type (as in * `path/google.protobuf.Duration`). The name should be in a canonical form * (e.g., leading "." is not accepted). * In practice, teams usually precompile into the binary all types that they * expect it to use in the context of Any. However, for URLs which use the * scheme `http`, `https`, or no scheme, one can optionally set up a type * server that maps type URLs to message definitions as follows: * * If no scheme is provided, `https` is assumed. * * An HTTP GET on the URL must yield a [google.protobuf.Type][] * value in binary format, or produce an error. * * Applications are allowed to cache lookup results based on the * URL, or have them precompiled into a binary to avoid any * lookup. Therefore, binary compatibility needs to be preserved * on changes to types. (Use versioned type names to manage * breaking changes.) * Note: this functionality is not currently available in the official * protobuf release, and it is not used for type URLs beginning with * type.googleapis.com. As of May 2023, there are no widely used type server * implementations and no plans to implement one. * Schemes other than `http`, `https` (or the empty scheme) might be * used with implementation specific semantics. * @type string $value * Must be a valid serialized protocol buffer of the above specified type. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Any::initOnce(); parent::__construct($data); } /** * A URL/resource name that uniquely identifies the type of the serialized * protocol buffer message. This string must contain at least * one "/" character. The last segment of the URL's path must represent * the fully qualified name of the type (as in * `path/google.protobuf.Duration`). The name should be in a canonical form * (e.g., leading "." is not accepted). * In practice, teams usually precompile into the binary all types that they * expect it to use in the context of Any. However, for URLs which use the * scheme `http`, `https`, or no scheme, one can optionally set up a type * server that maps type URLs to message definitions as follows: * * If no scheme is provided, `https` is assumed. * * An HTTP GET on the URL must yield a [google.protobuf.Type][] * value in binary format, or produce an error. * * Applications are allowed to cache lookup results based on the * URL, or have them precompiled into a binary to avoid any * lookup. Therefore, binary compatibility needs to be preserved * on changes to types. (Use versioned type names to manage * breaking changes.) * Note: this functionality is not currently available in the official * protobuf release, and it is not used for type URLs beginning with * type.googleapis.com. As of May 2023, there are no widely used type server * implementations and no plans to implement one. * Schemes other than `http`, `https` (or the empty scheme) might be * used with implementation specific semantics. * * Generated from protobuf field string type_url = 1; * @return string */ public function getTypeUrl() { return $this->type_url; } /** * A URL/resource name that uniquely identifies the type of the serialized * protocol buffer message. This string must contain at least * one "/" character. The last segment of the URL's path must represent * the fully qualified name of the type (as in * `path/google.protobuf.Duration`). The name should be in a canonical form * (e.g., leading "." is not accepted). * In practice, teams usually precompile into the binary all types that they * expect it to use in the context of Any. However, for URLs which use the * scheme `http`, `https`, or no scheme, one can optionally set up a type * server that maps type URLs to message definitions as follows: * * If no scheme is provided, `https` is assumed. * * An HTTP GET on the URL must yield a [google.protobuf.Type][] * value in binary format, or produce an error. * * Applications are allowed to cache lookup results based on the * URL, or have them precompiled into a binary to avoid any * lookup. Therefore, binary compatibility needs to be preserved * on changes to types. (Use versioned type names to manage * breaking changes.) * Note: this functionality is not currently available in the official * protobuf release, and it is not used for type URLs beginning with * type.googleapis.com. As of May 2023, there are no widely used type server * implementations and no plans to implement one. * Schemes other than `http`, `https` (or the empty scheme) might be * used with implementation specific semantics. * * Generated from protobuf field string type_url = 1; * @param string $var * @return $this */ public function setTypeUrl($var) { GPBUtil::checkString($var, True); $this->type_url = $var; return $this; } /** * Must be a valid serialized protocol buffer of the above specified type. * * Generated from protobuf field bytes value = 2; * @return string */ public function getValue() { return $this->value; } /** * Must be a valid serialized protocol buffer of the above specified type. * * Generated from protobuf field bytes value = 2; * @param string $var * @return $this */ public function setValue($var) { GPBUtil::checkString($var, False); $this->value = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Api.php ================================================ google.protobuf.Api */ class Api extends \Google\Protobuf\Internal\Message { /** * The fully qualified name of this interface, including package name * followed by the interface's simple name. * * Generated from protobuf field string name = 1; */ protected $name = ''; /** * The methods of this interface, in unspecified order. * * Generated from protobuf field repeated .google.protobuf.Method methods = 2; */ private $methods; /** * Any metadata attached to the interface. * * Generated from protobuf field repeated .google.protobuf.Option options = 3; */ private $options; /** * A version string for this interface. If specified, must have the form * `major-version.minor-version`, as in `1.10`. If the minor version is * omitted, it defaults to zero. If the entire version field is empty, the * major version is derived from the package name, as outlined below. If the * field is not empty, the version in the package name will be verified to be * consistent with what is provided here. * The versioning schema uses [semantic * versioning](http://semver.org) where the major version number * indicates a breaking change and the minor version an additive, * non-breaking change. Both version numbers are signals to users * what to expect from different versions, and should be carefully * chosen based on the product plan. * The major version is also reflected in the package name of the * interface, which must end in `v`, as in * `google.feature.v1`. For major versions 0 and 1, the suffix can * be omitted. Zero major versions must only be used for * experimental, non-GA interfaces. * * Generated from protobuf field string version = 4; */ protected $version = ''; /** * Source context for the protocol buffer service represented by this * message. * * Generated from protobuf field .google.protobuf.SourceContext source_context = 5; */ protected $source_context = null; /** * Included interfaces. See [Mixin][]. * * Generated from protobuf field repeated .google.protobuf.Mixin mixins = 6; */ private $mixins; /** * The source syntax of the service. * * Generated from protobuf field .google.protobuf.Syntax syntax = 7; */ protected $syntax = 0; /** * The source edition string, only valid when syntax is SYNTAX_EDITIONS. * * Generated from protobuf field string edition = 8; */ protected $edition = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $name * The fully qualified name of this interface, including package name * followed by the interface's simple name. * @type \Google\Protobuf\Method[] $methods * The methods of this interface, in unspecified order. * @type \Google\Protobuf\Option[] $options * Any metadata attached to the interface. * @type string $version * A version string for this interface. If specified, must have the form * `major-version.minor-version`, as in `1.10`. If the minor version is * omitted, it defaults to zero. If the entire version field is empty, the * major version is derived from the package name, as outlined below. If the * field is not empty, the version in the package name will be verified to be * consistent with what is provided here. * The versioning schema uses [semantic * versioning](http://semver.org) where the major version number * indicates a breaking change and the minor version an additive, * non-breaking change. Both version numbers are signals to users * what to expect from different versions, and should be carefully * chosen based on the product plan. * The major version is also reflected in the package name of the * interface, which must end in `v`, as in * `google.feature.v1`. For major versions 0 and 1, the suffix can * be omitted. Zero major versions must only be used for * experimental, non-GA interfaces. * @type \Google\Protobuf\SourceContext $source_context * Source context for the protocol buffer service represented by this * message. * @type \Google\Protobuf\Mixin[] $mixins * Included interfaces. See [Mixin][]. * @type int $syntax * The source syntax of the service. * @type string $edition * The source edition string, only valid when syntax is SYNTAX_EDITIONS. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Api::initOnce(); parent::__construct($data); } /** * The fully qualified name of this interface, including package name * followed by the interface's simple name. * * Generated from protobuf field string name = 1; * @return string */ public function getName() { return $this->name; } /** * The fully qualified name of this interface, including package name * followed by the interface's simple name. * * Generated from protobuf field string name = 1; * @param string $var * @return $this */ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; return $this; } /** * The methods of this interface, in unspecified order. * * Generated from protobuf field repeated .google.protobuf.Method methods = 2; * @return RepeatedField<\Google\Protobuf\Method> */ public function getMethods() { return $this->methods; } /** * The methods of this interface, in unspecified order. * * Generated from protobuf field repeated .google.protobuf.Method methods = 2; * @param \Google\Protobuf\Method[] $var * @return $this */ public function setMethods($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Method::class); $this->methods = $arr; return $this; } /** * Any metadata attached to the interface. * * Generated from protobuf field repeated .google.protobuf.Option options = 3; * @return RepeatedField<\Google\Protobuf\Option> */ public function getOptions() { return $this->options; } /** * Any metadata attached to the interface. * * Generated from protobuf field repeated .google.protobuf.Option options = 3; * @param \Google\Protobuf\Option[] $var * @return $this */ public function setOptions($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Option::class); $this->options = $arr; return $this; } /** * A version string for this interface. If specified, must have the form * `major-version.minor-version`, as in `1.10`. If the minor version is * omitted, it defaults to zero. If the entire version field is empty, the * major version is derived from the package name, as outlined below. If the * field is not empty, the version in the package name will be verified to be * consistent with what is provided here. * The versioning schema uses [semantic * versioning](http://semver.org) where the major version number * indicates a breaking change and the minor version an additive, * non-breaking change. Both version numbers are signals to users * what to expect from different versions, and should be carefully * chosen based on the product plan. * The major version is also reflected in the package name of the * interface, which must end in `v`, as in * `google.feature.v1`. For major versions 0 and 1, the suffix can * be omitted. Zero major versions must only be used for * experimental, non-GA interfaces. * * Generated from protobuf field string version = 4; * @return string */ public function getVersion() { return $this->version; } /** * A version string for this interface. If specified, must have the form * `major-version.minor-version`, as in `1.10`. If the minor version is * omitted, it defaults to zero. If the entire version field is empty, the * major version is derived from the package name, as outlined below. If the * field is not empty, the version in the package name will be verified to be * consistent with what is provided here. * The versioning schema uses [semantic * versioning](http://semver.org) where the major version number * indicates a breaking change and the minor version an additive, * non-breaking change. Both version numbers are signals to users * what to expect from different versions, and should be carefully * chosen based on the product plan. * The major version is also reflected in the package name of the * interface, which must end in `v`, as in * `google.feature.v1`. For major versions 0 and 1, the suffix can * be omitted. Zero major versions must only be used for * experimental, non-GA interfaces. * * Generated from protobuf field string version = 4; * @param string $var * @return $this */ public function setVersion($var) { GPBUtil::checkString($var, True); $this->version = $var; return $this; } /** * Source context for the protocol buffer service represented by this * message. * * Generated from protobuf field .google.protobuf.SourceContext source_context = 5; * @return \Google\Protobuf\SourceContext|null */ public function getSourceContext() { return $this->source_context; } public function hasSourceContext() { return isset($this->source_context); } public function clearSourceContext() { unset($this->source_context); } /** * Source context for the protocol buffer service represented by this * message. * * Generated from protobuf field .google.protobuf.SourceContext source_context = 5; * @param \Google\Protobuf\SourceContext $var * @return $this */ public function setSourceContext($var) { GPBUtil::checkMessage($var, \Google\Protobuf\SourceContext::class); $this->source_context = $var; return $this; } /** * Included interfaces. See [Mixin][]. * * Generated from protobuf field repeated .google.protobuf.Mixin mixins = 6; * @return RepeatedField<\Google\Protobuf\Mixin> */ public function getMixins() { return $this->mixins; } /** * Included interfaces. See [Mixin][]. * * Generated from protobuf field repeated .google.protobuf.Mixin mixins = 6; * @param \Google\Protobuf\Mixin[] $var * @return $this */ public function setMixins($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Mixin::class); $this->mixins = $arr; return $this; } /** * The source syntax of the service. * * Generated from protobuf field .google.protobuf.Syntax syntax = 7; * @return int */ public function getSyntax() { return $this->syntax; } /** * The source syntax of the service. * * Generated from protobuf field .google.protobuf.Syntax syntax = 7; * @param int $var * @return $this */ public function setSyntax($var) { GPBUtil::checkEnum($var, \Google\Protobuf\Syntax::class); $this->syntax = $var; return $this; } /** * The source edition string, only valid when syntax is SYNTAX_EDITIONS. * * Generated from protobuf field string edition = 8; * @return string */ public function getEdition() { return $this->edition; } /** * The source edition string, only valid when syntax is SYNTAX_EDITIONS. * * Generated from protobuf field string edition = 8; * @param string $var * @return $this */ public function setEdition($var) { GPBUtil::checkString($var, True); $this->edition = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/BoolValue.php ================================================ google.protobuf.BoolValue */ class BoolValue extends \Google\Protobuf\Internal\Message { /** * The bool value. * * Generated from protobuf field bool value = 1; */ protected $value = false; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type bool $value * The bool value. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Wrappers::initOnce(); parent::__construct($data); } /** * The bool value. * * Generated from protobuf field bool value = 1; * @return bool */ public function getValue() { return $this->value; } /** * The bool value. * * Generated from protobuf field bool value = 1; * @param bool $var * @return $this */ public function setValue($var) { GPBUtil::checkBool($var); $this->value = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/BytesValue.php ================================================ google.protobuf.BytesValue */ class BytesValue extends \Google\Protobuf\Internal\Message { /** * The bytes value. * * Generated from protobuf field bytes value = 1; */ protected $value = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $value * The bytes value. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Wrappers::initOnce(); parent::__construct($data); } /** * The bytes value. * * Generated from protobuf field bytes value = 1; * @return string */ public function getValue() { return $this->value; } /** * The bytes value. * * Generated from protobuf field bytes value = 1; * @param string $var * @return $this */ public function setValue($var) { GPBUtil::checkString($var, False); $this->value = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Descriptor.php ================================================ internal_desc = $internal_desc; } /** * @return string Full protobuf message name */ public function getFullName() { return trim($this->internal_desc->getFullName(), "."); } /** * @return string PHP class name */ public function getClass() { return $this->internal_desc->getClass(); } /** * @param int $index Must be >= 0 and < getFieldCount() * @return FieldDescriptor */ public function getField($index) { return $this->getPublicDescriptor($this->internal_desc->getFieldByIndex($index)); } /** * @return int Number of fields in message */ public function getFieldCount() { return count($this->internal_desc->getField()); } /** * @param int $index Must be >= 0 and < getOneofDeclCount() * @return OneofDescriptor */ public function getOneofDecl($index) { return $this->getPublicDescriptor($this->internal_desc->getOneofDecl()[$index]); } /** * @return int Number of oneofs in message */ public function getOneofDeclCount() { return count($this->internal_desc->getOneofDecl()); } /** * @return int Number of real oneofs in message */ public function getRealOneofDeclCount() { return $this->internal_desc->getRealOneofDeclCount(); } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/DescriptorPool.php ================================================ internal_pool = $internal_pool; } /** * @param string $className A fully qualified protobuf class name * @return Descriptor */ public function getDescriptorByClassName($className) { $desc = $this->internal_pool->getDescriptorByClassName($className); return is_null($desc) ? null : $desc->getPublicDescriptor(); } /** * @param string $className A fully qualified protobuf class name * @return EnumDescriptor */ public function getEnumDescriptorByClassName($className) { $desc = $this->internal_pool->getEnumDescriptorByClassName($className); return is_null($desc) ? null : $desc->getPublicDescriptor(); } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/DoubleValue.php ================================================ google.protobuf.DoubleValue */ class DoubleValue extends \Google\Protobuf\Internal\Message { /** * The double value. * * Generated from protobuf field double value = 1; */ protected $value = 0.0; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type float $value * The double value. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Wrappers::initOnce(); parent::__construct($data); } /** * The double value. * * Generated from protobuf field double value = 1; * @return float */ public function getValue() { return $this->value; } /** * The double value. * * Generated from protobuf field double value = 1; * @param float $var * @return $this */ public function setValue($var) { GPBUtil::checkDouble($var); $this->value = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Duration.php ================================================ 0) { * duration.seconds += 1; * duration.nanos -= 1000000000; * } else if (duration.seconds > 0 && duration.nanos < 0) { * duration.seconds -= 1; * duration.nanos += 1000000000; * } * Example 2: Compute Timestamp from Timestamp + Duration in pseudo code. * Timestamp start = ...; * Duration duration = ...; * Timestamp end = ...; * end.seconds = start.seconds + duration.seconds; * end.nanos = start.nanos + duration.nanos; * if (end.nanos < 0) { * end.seconds -= 1; * end.nanos += 1000000000; * } else if (end.nanos >= 1000000000) { * end.seconds += 1; * end.nanos -= 1000000000; * } * Example 3: Compute Duration from datetime.timedelta in Python. * td = datetime.timedelta(days=3, minutes=10) * duration = Duration() * duration.FromTimedelta(td) * # JSON Mapping * In JSON format, the Duration type is encoded as a string rather than an * object, where the string ends in the suffix "s" (indicating seconds) and * is preceded by the number of seconds, with nanoseconds expressed as * fractional seconds. For example, 3 seconds with 0 nanoseconds should be * encoded in JSON format as "3s", while 3 seconds and 1 nanosecond should * be expressed in JSON format as "3.000000001s", and 3 seconds and 1 * microsecond should be expressed in JSON format as "3.000001s". * * Generated from protobuf message google.protobuf.Duration */ class Duration extends \Google\Protobuf\Internal\Message { /** * Signed seconds of the span of time. Must be from -315,576,000,000 * to +315,576,000,000 inclusive. Note: these bounds are computed from: * 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years * * Generated from protobuf field int64 seconds = 1; */ protected $seconds = 0; /** * Signed fractions of a second at nanosecond resolution of the span * of time. Durations less than one second are represented with a 0 * `seconds` field and a positive or negative `nanos` field. For durations * of one second or more, a non-zero value for the `nanos` field must be * of the same sign as the `seconds` field. Must be from -999,999,999 * to +999,999,999 inclusive. * * Generated from protobuf field int32 nanos = 2; */ protected $nanos = 0; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type int|string $seconds * Signed seconds of the span of time. Must be from -315,576,000,000 * to +315,576,000,000 inclusive. Note: these bounds are computed from: * 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years * @type int $nanos * Signed fractions of a second at nanosecond resolution of the span * of time. Durations less than one second are represented with a 0 * `seconds` field and a positive or negative `nanos` field. For durations * of one second or more, a non-zero value for the `nanos` field must be * of the same sign as the `seconds` field. Must be from -999,999,999 * to +999,999,999 inclusive. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Duration::initOnce(); parent::__construct($data); } /** * Signed seconds of the span of time. Must be from -315,576,000,000 * to +315,576,000,000 inclusive. Note: these bounds are computed from: * 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years * * Generated from protobuf field int64 seconds = 1; * @return int|string */ public function getSeconds() { return $this->seconds; } /** * Signed seconds of the span of time. Must be from -315,576,000,000 * to +315,576,000,000 inclusive. Note: these bounds are computed from: * 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years * * Generated from protobuf field int64 seconds = 1; * @param int|string $var * @return $this */ public function setSeconds($var) { GPBUtil::checkInt64($var); $this->seconds = $var; return $this; } /** * Signed fractions of a second at nanosecond resolution of the span * of time. Durations less than one second are represented with a 0 * `seconds` field and a positive or negative `nanos` field. For durations * of one second or more, a non-zero value for the `nanos` field must be * of the same sign as the `seconds` field. Must be from -999,999,999 * to +999,999,999 inclusive. * * Generated from protobuf field int32 nanos = 2; * @return int */ public function getNanos() { return $this->nanos; } /** * Signed fractions of a second at nanosecond resolution of the span * of time. Durations less than one second are represented with a 0 * `seconds` field and a positive or negative `nanos` field. For durations * of one second or more, a non-zero value for the `nanos` field must be * of the same sign as the `seconds` field. Must be from -999,999,999 * to +999,999,999 inclusive. * * Generated from protobuf field int32 nanos = 2; * @param int $var * @return $this */ public function setNanos($var) { GPBUtil::checkInt32($var); $this->nanos = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Enum.php ================================================ google.protobuf.Enum */ class Enum extends \Google\Protobuf\Internal\Message { /** * Enum type name. * * Generated from protobuf field string name = 1; */ protected $name = ''; /** * Enum value definitions. * * Generated from protobuf field repeated .google.protobuf.EnumValue enumvalue = 2; */ private $enumvalue; /** * Protocol buffer options. * * Generated from protobuf field repeated .google.protobuf.Option options = 3; */ private $options; /** * The source context. * * Generated from protobuf field .google.protobuf.SourceContext source_context = 4; */ protected $source_context = null; /** * The source syntax. * * Generated from protobuf field .google.protobuf.Syntax syntax = 5; */ protected $syntax = 0; /** * The source edition string, only valid when syntax is SYNTAX_EDITIONS. * * Generated from protobuf field string edition = 6; */ protected $edition = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $name * Enum type name. * @type \Google\Protobuf\EnumValue[] $enumvalue * Enum value definitions. * @type \Google\Protobuf\Option[] $options * Protocol buffer options. * @type \Google\Protobuf\SourceContext $source_context * The source context. * @type int $syntax * The source syntax. * @type string $edition * The source edition string, only valid when syntax is SYNTAX_EDITIONS. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Type::initOnce(); parent::__construct($data); } /** * Enum type name. * * Generated from protobuf field string name = 1; * @return string */ public function getName() { return $this->name; } /** * Enum type name. * * Generated from protobuf field string name = 1; * @param string $var * @return $this */ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; return $this; } /** * Enum value definitions. * * Generated from protobuf field repeated .google.protobuf.EnumValue enumvalue = 2; * @return RepeatedField<\Google\Protobuf\EnumValue> */ public function getEnumvalue() { return $this->enumvalue; } /** * Enum value definitions. * * Generated from protobuf field repeated .google.protobuf.EnumValue enumvalue = 2; * @param \Google\Protobuf\EnumValue[] $var * @return $this */ public function setEnumvalue($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\EnumValue::class); $this->enumvalue = $arr; return $this; } /** * Protocol buffer options. * * Generated from protobuf field repeated .google.protobuf.Option options = 3; * @return RepeatedField<\Google\Protobuf\Option> */ public function getOptions() { return $this->options; } /** * Protocol buffer options. * * Generated from protobuf field repeated .google.protobuf.Option options = 3; * @param \Google\Protobuf\Option[] $var * @return $this */ public function setOptions($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Option::class); $this->options = $arr; return $this; } /** * The source context. * * Generated from protobuf field .google.protobuf.SourceContext source_context = 4; * @return \Google\Protobuf\SourceContext|null */ public function getSourceContext() { return $this->source_context; } public function hasSourceContext() { return isset($this->source_context); } public function clearSourceContext() { unset($this->source_context); } /** * The source context. * * Generated from protobuf field .google.protobuf.SourceContext source_context = 4; * @param \Google\Protobuf\SourceContext $var * @return $this */ public function setSourceContext($var) { GPBUtil::checkMessage($var, \Google\Protobuf\SourceContext::class); $this->source_context = $var; return $this; } /** * The source syntax. * * Generated from protobuf field .google.protobuf.Syntax syntax = 5; * @return int */ public function getSyntax() { return $this->syntax; } /** * The source syntax. * * Generated from protobuf field .google.protobuf.Syntax syntax = 5; * @param int $var * @return $this */ public function setSyntax($var) { GPBUtil::checkEnum($var, \Google\Protobuf\Syntax::class); $this->syntax = $var; return $this; } /** * The source edition string, only valid when syntax is SYNTAX_EDITIONS. * * Generated from protobuf field string edition = 6; * @return string */ public function getEdition() { return $this->edition; } /** * The source edition string, only valid when syntax is SYNTAX_EDITIONS. * * Generated from protobuf field string edition = 6; * @param string $var * @return $this */ public function setEdition($var) { GPBUtil::checkString($var, True); $this->edition = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/EnumDescriptor.php ================================================ internal_desc = $internal_desc; } /** * @return string Full protobuf message name */ public function getFullName() { return $this->internal_desc->getFullName(); } /** * @return string PHP class name */ public function getClass() { return $this->internal_desc->getClass(); } /** * @param int $index Must be >= 0 and < getValueCount() * @return EnumValueDescriptor */ public function getValue($index) { return $this->internal_desc->getValueDescriptorByIndex($index); } /** * @return int Number of values in enum */ public function getValueCount() { return $this->internal_desc->getValueCount(); } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/EnumValue.php ================================================ google.protobuf.EnumValue */ class EnumValue extends \Google\Protobuf\Internal\Message { /** * Enum value name. * * Generated from protobuf field string name = 1; */ protected $name = ''; /** * Enum value number. * * Generated from protobuf field int32 number = 2; */ protected $number = 0; /** * Protocol buffer options. * * Generated from protobuf field repeated .google.protobuf.Option options = 3; */ private $options; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $name * Enum value name. * @type int $number * Enum value number. * @type \Google\Protobuf\Option[] $options * Protocol buffer options. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Type::initOnce(); parent::__construct($data); } /** * Enum value name. * * Generated from protobuf field string name = 1; * @return string */ public function getName() { return $this->name; } /** * Enum value name. * * Generated from protobuf field string name = 1; * @param string $var * @return $this */ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; return $this; } /** * Enum value number. * * Generated from protobuf field int32 number = 2; * @return int */ public function getNumber() { return $this->number; } /** * Enum value number. * * Generated from protobuf field int32 number = 2; * @param int $var * @return $this */ public function setNumber($var) { GPBUtil::checkInt32($var); $this->number = $var; return $this; } /** * Protocol buffer options. * * Generated from protobuf field repeated .google.protobuf.Option options = 3; * @return RepeatedField<\Google\Protobuf\Option> */ public function getOptions() { return $this->options; } /** * Protocol buffer options. * * Generated from protobuf field repeated .google.protobuf.Option options = 3; * @param \Google\Protobuf\Option[] $var * @return $this */ public function setOptions($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Option::class); $this->options = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/EnumValueDescriptor.php ================================================ name = $name; $this->number = $number; } /** * @return string */ public function getName() { return $this->name; } /** * @return int */ public function getNumber() { return $this->number; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Field/Cardinality.php ================================================ google.protobuf.Field.Cardinality */ class Cardinality { /** * For fields with unknown cardinality. * * Generated from protobuf enum CARDINALITY_UNKNOWN = 0; */ const CARDINALITY_UNKNOWN = 0; /** * For optional fields. * * Generated from protobuf enum CARDINALITY_OPTIONAL = 1; */ const CARDINALITY_OPTIONAL = 1; /** * For required fields. Proto2 syntax only. * * Generated from protobuf enum CARDINALITY_REQUIRED = 2; */ const CARDINALITY_REQUIRED = 2; /** * For repeated fields. * * Generated from protobuf enum CARDINALITY_REPEATED = 3; */ const CARDINALITY_REPEATED = 3; private static $valueToName = [ self::CARDINALITY_UNKNOWN => 'CARDINALITY_UNKNOWN', self::CARDINALITY_OPTIONAL => 'CARDINALITY_OPTIONAL', self::CARDINALITY_REQUIRED => 'CARDINALITY_REQUIRED', self::CARDINALITY_REPEATED => 'CARDINALITY_REPEATED', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Field/Kind.php ================================================ google.protobuf.Field.Kind */ class Kind { /** * Field type unknown. * * Generated from protobuf enum TYPE_UNKNOWN = 0; */ const TYPE_UNKNOWN = 0; /** * Field type double. * * Generated from protobuf enum TYPE_DOUBLE = 1; */ const TYPE_DOUBLE = 1; /** * Field type float. * * Generated from protobuf enum TYPE_FLOAT = 2; */ const TYPE_FLOAT = 2; /** * Field type int64. * * Generated from protobuf enum TYPE_INT64 = 3; */ const TYPE_INT64 = 3; /** * Field type uint64. * * Generated from protobuf enum TYPE_UINT64 = 4; */ const TYPE_UINT64 = 4; /** * Field type int32. * * Generated from protobuf enum TYPE_INT32 = 5; */ const TYPE_INT32 = 5; /** * Field type fixed64. * * Generated from protobuf enum TYPE_FIXED64 = 6; */ const TYPE_FIXED64 = 6; /** * Field type fixed32. * * Generated from protobuf enum TYPE_FIXED32 = 7; */ const TYPE_FIXED32 = 7; /** * Field type bool. * * Generated from protobuf enum TYPE_BOOL = 8; */ const TYPE_BOOL = 8; /** * Field type string. * * Generated from protobuf enum TYPE_STRING = 9; */ const TYPE_STRING = 9; /** * Field type group. Proto2 syntax only, and deprecated. * * Generated from protobuf enum TYPE_GROUP = 10; */ const TYPE_GROUP = 10; /** * Field type message. * * Generated from protobuf enum TYPE_MESSAGE = 11; */ const TYPE_MESSAGE = 11; /** * Field type bytes. * * Generated from protobuf enum TYPE_BYTES = 12; */ const TYPE_BYTES = 12; /** * Field type uint32. * * Generated from protobuf enum TYPE_UINT32 = 13; */ const TYPE_UINT32 = 13; /** * Field type enum. * * Generated from protobuf enum TYPE_ENUM = 14; */ const TYPE_ENUM = 14; /** * Field type sfixed32. * * Generated from protobuf enum TYPE_SFIXED32 = 15; */ const TYPE_SFIXED32 = 15; /** * Field type sfixed64. * * Generated from protobuf enum TYPE_SFIXED64 = 16; */ const TYPE_SFIXED64 = 16; /** * Field type sint32. * * Generated from protobuf enum TYPE_SINT32 = 17; */ const TYPE_SINT32 = 17; /** * Field type sint64. * * Generated from protobuf enum TYPE_SINT64 = 18; */ const TYPE_SINT64 = 18; private static $valueToName = [ self::TYPE_UNKNOWN => 'TYPE_UNKNOWN', self::TYPE_DOUBLE => 'TYPE_DOUBLE', self::TYPE_FLOAT => 'TYPE_FLOAT', self::TYPE_INT64 => 'TYPE_INT64', self::TYPE_UINT64 => 'TYPE_UINT64', self::TYPE_INT32 => 'TYPE_INT32', self::TYPE_FIXED64 => 'TYPE_FIXED64', self::TYPE_FIXED32 => 'TYPE_FIXED32', self::TYPE_BOOL => 'TYPE_BOOL', self::TYPE_STRING => 'TYPE_STRING', self::TYPE_GROUP => 'TYPE_GROUP', self::TYPE_MESSAGE => 'TYPE_MESSAGE', self::TYPE_BYTES => 'TYPE_BYTES', self::TYPE_UINT32 => 'TYPE_UINT32', self::TYPE_ENUM => 'TYPE_ENUM', self::TYPE_SFIXED32 => 'TYPE_SFIXED32', self::TYPE_SFIXED64 => 'TYPE_SFIXED64', self::TYPE_SINT32 => 'TYPE_SINT32', self::TYPE_SINT64 => 'TYPE_SINT64', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Field.php ================================================ google.protobuf.Field */ class Field extends \Google\Protobuf\Internal\Message { /** * The field type. * * Generated from protobuf field .google.protobuf.Field.Kind kind = 1; */ protected $kind = 0; /** * The field cardinality. * * Generated from protobuf field .google.protobuf.Field.Cardinality cardinality = 2; */ protected $cardinality = 0; /** * The field number. * * Generated from protobuf field int32 number = 3; */ protected $number = 0; /** * The field name. * * Generated from protobuf field string name = 4; */ protected $name = ''; /** * The field type URL, without the scheme, for message or enumeration * types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`. * * Generated from protobuf field string type_url = 6; */ protected $type_url = ''; /** * The index of the field type in `Type.oneofs`, for message or enumeration * types. The first type has index 1; zero means the type is not in the list. * * Generated from protobuf field int32 oneof_index = 7; */ protected $oneof_index = 0; /** * Whether to use alternative packed wire representation. * * Generated from protobuf field bool packed = 8; */ protected $packed = false; /** * The protocol buffer options. * * Generated from protobuf field repeated .google.protobuf.Option options = 9; */ private $options; /** * The field JSON name. * * Generated from protobuf field string json_name = 10; */ protected $json_name = ''; /** * The string value of the default value of this field. Proto2 syntax only. * * Generated from protobuf field string default_value = 11; */ protected $default_value = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type int $kind * The field type. * @type int $cardinality * The field cardinality. * @type int $number * The field number. * @type string $name * The field name. * @type string $type_url * The field type URL, without the scheme, for message or enumeration * types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`. * @type int $oneof_index * The index of the field type in `Type.oneofs`, for message or enumeration * types. The first type has index 1; zero means the type is not in the list. * @type bool $packed * Whether to use alternative packed wire representation. * @type \Google\Protobuf\Option[] $options * The protocol buffer options. * @type string $json_name * The field JSON name. * @type string $default_value * The string value of the default value of this field. Proto2 syntax only. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Type::initOnce(); parent::__construct($data); } /** * The field type. * * Generated from protobuf field .google.protobuf.Field.Kind kind = 1; * @return int */ public function getKind() { return $this->kind; } /** * The field type. * * Generated from protobuf field .google.protobuf.Field.Kind kind = 1; * @param int $var * @return $this */ public function setKind($var) { GPBUtil::checkEnum($var, \Google\Protobuf\Field\Kind::class); $this->kind = $var; return $this; } /** * The field cardinality. * * Generated from protobuf field .google.protobuf.Field.Cardinality cardinality = 2; * @return int */ public function getCardinality() { return $this->cardinality; } /** * The field cardinality. * * Generated from protobuf field .google.protobuf.Field.Cardinality cardinality = 2; * @param int $var * @return $this */ public function setCardinality($var) { GPBUtil::checkEnum($var, \Google\Protobuf\Field\Cardinality::class); $this->cardinality = $var; return $this; } /** * The field number. * * Generated from protobuf field int32 number = 3; * @return int */ public function getNumber() { return $this->number; } /** * The field number. * * Generated from protobuf field int32 number = 3; * @param int $var * @return $this */ public function setNumber($var) { GPBUtil::checkInt32($var); $this->number = $var; return $this; } /** * The field name. * * Generated from protobuf field string name = 4; * @return string */ public function getName() { return $this->name; } /** * The field name. * * Generated from protobuf field string name = 4; * @param string $var * @return $this */ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; return $this; } /** * The field type URL, without the scheme, for message or enumeration * types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`. * * Generated from protobuf field string type_url = 6; * @return string */ public function getTypeUrl() { return $this->type_url; } /** * The field type URL, without the scheme, for message or enumeration * types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`. * * Generated from protobuf field string type_url = 6; * @param string $var * @return $this */ public function setTypeUrl($var) { GPBUtil::checkString($var, True); $this->type_url = $var; return $this; } /** * The index of the field type in `Type.oneofs`, for message or enumeration * types. The first type has index 1; zero means the type is not in the list. * * Generated from protobuf field int32 oneof_index = 7; * @return int */ public function getOneofIndex() { return $this->oneof_index; } /** * The index of the field type in `Type.oneofs`, for message or enumeration * types. The first type has index 1; zero means the type is not in the list. * * Generated from protobuf field int32 oneof_index = 7; * @param int $var * @return $this */ public function setOneofIndex($var) { GPBUtil::checkInt32($var); $this->oneof_index = $var; return $this; } /** * Whether to use alternative packed wire representation. * * Generated from protobuf field bool packed = 8; * @return bool */ public function getPacked() { return $this->packed; } /** * Whether to use alternative packed wire representation. * * Generated from protobuf field bool packed = 8; * @param bool $var * @return $this */ public function setPacked($var) { GPBUtil::checkBool($var); $this->packed = $var; return $this; } /** * The protocol buffer options. * * Generated from protobuf field repeated .google.protobuf.Option options = 9; * @return RepeatedField<\Google\Protobuf\Option> */ public function getOptions() { return $this->options; } /** * The protocol buffer options. * * Generated from protobuf field repeated .google.protobuf.Option options = 9; * @param \Google\Protobuf\Option[] $var * @return $this */ public function setOptions($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Option::class); $this->options = $arr; return $this; } /** * The field JSON name. * * Generated from protobuf field string json_name = 10; * @return string */ public function getJsonName() { return $this->json_name; } /** * The field JSON name. * * Generated from protobuf field string json_name = 10; * @param string $var * @return $this */ public function setJsonName($var) { GPBUtil::checkString($var, True); $this->json_name = $var; return $this; } /** * The string value of the default value of this field. Proto2 syntax only. * * Generated from protobuf field string default_value = 11; * @return string */ public function getDefaultValue() { return $this->default_value; } /** * The string value of the default value of this field. Proto2 syntax only. * * Generated from protobuf field string default_value = 11; * @param string $var * @return $this */ public function setDefaultValue($var) { GPBUtil::checkString($var, True); $this->default_value = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/FieldDescriptor.php ================================================ internal_desc = $internal_desc; } /** * @return string Field name */ public function getName() { return $this->internal_desc->getName(); } /** * @return int Protobuf field number */ public function getNumber() { return $this->internal_desc->getNumber(); } /** * @deprecated Use isRepeated() or isRequired() instead. * * @return int */ public function getLabel() { return $this->internal_desc->getLabel(); } /** * @return boolean */ public function isRequired() { return $this->internal_desc->isRequired(); } /** * @return boolean */ public function isRepeated() { return $this->internal_desc->isRepeated(); } /** * @return int */ public function getType() { return $this->internal_desc->getType(); } /** * @return OneofDescriptor */ public function getContainingOneof() { return $this->getPublicDescriptor($this->internal_desc->getContainingOneof()); } /** * Gets the field's containing oneof, only if non-synthetic. * * @return null|OneofDescriptor */ public function getRealContainingOneof() { return $this->getPublicDescriptor($this->internal_desc->getRealContainingOneof()); } /** * @return boolean */ public function hasOptionalKeyword() { return $this->internal_desc->hasOptionalKeyword(); } /** * @return Descriptor Returns a descriptor for the field type if the field type is a message, otherwise throws \Exception * @throws \Exception */ public function getMessageType() { if ($this->getType() == GPBType::MESSAGE) { return $this->getPublicDescriptor($this->internal_desc->getMessageType()); } else { throw new \Exception("Cannot get message type for non-message field '" . $this->getName() . "'"); } } /** * @return EnumDescriptor Returns an enum descriptor if the field type is an enum, otherwise throws \Exception * @throws \Exception */ public function getEnumType() { if ($this->getType() == GPBType::ENUM) { return $this->getPublicDescriptor($this->internal_desc->getEnumType()); } else { throw new \Exception("Cannot get enum type for non-enum field '" . $this->getName() . "'"); } } /** * @return boolean */ public function isMap() { return $this->internal_desc->isMap(); } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/FieldMask.php ================================================ google.protobuf.FieldMask */ class FieldMask extends \Google\Protobuf\Internal\Message { /** * The set of field mask paths. * * Generated from protobuf field repeated string paths = 1; */ private $paths; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string[] $paths * The set of field mask paths. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\FieldMask::initOnce(); parent::__construct($data); } /** * The set of field mask paths. * * Generated from protobuf field repeated string paths = 1; * @return RepeatedField */ public function getPaths() { return $this->paths; } /** * The set of field mask paths. * * Generated from protobuf field repeated string paths = 1; * @param string[] $var * @return $this */ public function setPaths($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->paths = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Field_Cardinality.php ================================================ google.protobuf.FloatValue */ class FloatValue extends \Google\Protobuf\Internal\Message { /** * The float value. * * Generated from protobuf field float value = 1; */ protected $value = 0.0; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type float $value * The float value. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Wrappers::initOnce(); parent::__construct($data); } /** * The float value. * * Generated from protobuf field float value = 1; * @return float */ public function getValue() { return $this->value; } /** * The float value. * * Generated from protobuf field float value = 1; * @param float $var * @return $this */ public function setValue($var) { GPBUtil::checkFloat($var); $this->value = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/GPBEmpty.php ================================================ google.protobuf.Empty */ class GPBEmpty extends \Google\Protobuf\Internal\Message { /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\GPBEmpty::initOnce(); parent::__construct($data); } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Int32Value.php ================================================ google.protobuf.Int32Value */ class Int32Value extends \Google\Protobuf\Internal\Message { /** * The int32 value. * * Generated from protobuf field int32 value = 1; */ protected $value = 0; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type int $value * The int32 value. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Wrappers::initOnce(); parent::__construct($data); } /** * The int32 value. * * Generated from protobuf field int32 value = 1; * @return int */ public function getValue() { return $this->value; } /** * The int32 value. * * Generated from protobuf field int32 value = 1; * @param int $var * @return $this */ public function setValue($var) { GPBUtil::checkInt32($var); $this->value = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Int64Value.php ================================================ google.protobuf.Int64Value */ class Int64Value extends \Google\Protobuf\Internal\Message { /** * The int64 value. * * Generated from protobuf field int64 value = 1; */ protected $value = 0; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type int|string $value * The int64 value. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Wrappers::initOnce(); parent::__construct($data); } /** * The int64 value. * * Generated from protobuf field int64 value = 1; * @return int|string */ public function getValue() { return $this->value; } /** * The int64 value. * * Generated from protobuf field int64 value = 1; * @param int|string $var * @return $this */ public function setValue($var) { GPBUtil::checkInt64($var); $this->value = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/AnyBase.php ================================================ type_url, 0, $url_prifix_len) != GPBUtil::TYPE_URL_PREFIX) { throw new \Exception( "Type url needs to be type.googleapis.com/fully-qulified"); } $fully_qualified_name = substr($this->type_url, $url_prifix_len); // Create message according to fully qualified name. $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool(); $desc = $pool->getDescriptorByProtoName($fully_qualified_name); if (is_null($desc)) { throw new \Exception("Class ".$fully_qualified_name ." hasn't been added to descriptor pool"); } $klass = $desc->getClass(); $msg = new $klass(); // Merge data into message. $msg->mergeFromString($this->value); return $msg; } /** * The type_url will be created according to the given message’s type and * the value is encoded data from the given message.. * @param Message $msg A proto message. */ public function pack($msg) { if (!$msg instanceof Message) { trigger_error("Given parameter is not a message instance.", E_USER_ERROR); return; } // Set value using serialized message. $this->value = $msg->serializeToString(); // Set type url. $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool(); $desc = $pool->getDescriptorByClassName(get_class($msg)); $fully_qualified_name = $desc->getFullName(); $this->type_url = GPBUtil::TYPE_URL_PREFIX . $fully_qualified_name; } /** * This method returns whether the type_url in any_message is corresponded * to the given class. * @param string $klass The fully qualified PHP class name of a proto message type. */ public function is($klass) { $pool = \Google\Protobuf\Internal\DescriptorPool::getGeneratedPool(); $desc = $pool->getDescriptorByClassName($klass); $fully_qualified_name = $desc->getFullName(); $type_url = GPBUtil::TYPE_URL_PREFIX . $fully_qualified_name; return $this->type_url === $type_url; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/CodedInputStream.php ================================================ buffer = $buffer; $this->buffer_size_after_limit = 0; $this->buffer_end = $end; $this->current = $start; $this->current_limit = $end; $this->legitimate_message_end = false; $this->recursion_budget = self::DEFAULT_RECURSION_LIMIT; $this->recursion_limit = self::DEFAULT_RECURSION_LIMIT; $this->total_bytes_limit = self::DEFAULT_TOTAL_BYTES_LIMIT; $this->total_bytes_read = $end - $start; } private function advance($amount) { $this->current += $amount; } public function bufferSize() { return $this->buffer_end - $this->current; } public function current() { return $this->total_bytes_read - ($this->buffer_end - $this->current + $this->buffer_size_after_limit); } public function substr($start, $end) { return substr($this->buffer, $start, $end - $start); } private function recomputeBufferLimits() { $this->buffer_end += $this->buffer_size_after_limit; $closest_limit = min($this->current_limit, $this->total_bytes_limit); if ($closest_limit < $this->total_bytes_read) { // The limit position is in the current buffer. We must adjust the // buffer size accordingly. $this->buffer_size_after_limit = $this->total_bytes_read - $closest_limit; $this->buffer_end -= $this->buffer_size_after_limit; } else { $this->buffer_size_after_limit = 0; } } private function consumedEntireMessage() { return $this->legitimate_message_end; } /** * Read uint32 into $var. Advance buffer with consumed bytes. If the * contained varint is larger than 32 bits, discard the high order bits. * @param $var */ public function readVarint32(&$var) { if (!$this->readVarint64($var)) { return false; } if (PHP_INT_SIZE == 4) { $var = bcmod($var, 4294967296); } else { $var &= 0xFFFFFFFF; } // Convert large uint32 to int32. if ($var > 0x7FFFFFFF) { if (PHP_INT_SIZE === 8) { $var = $var | (0xFFFFFFFF << 32); } else { $var = bcsub($var, 4294967296); } } $var = intval($var); return true; } /** * Read Uint64 into $var. Advance buffer with consumed bytes. * @param $var */ public function readVarint64(&$var) { $count = 0; if (PHP_INT_SIZE == 4) { $high = 0; $low = 0; $b = 0; do { if ($this->current === $this->buffer_end) { return false; } if ($count === self::MAX_VARINT_BYTES) { return false; } $b = ord($this->buffer[$this->current]); $bits = 7 * $count; if ($bits >= 32) { $high |= (($b & 0x7F) << ($bits - 32)); } else if ($bits > 25){ // $bits is 28 in this case. $low |= (($b & 0x7F) << 28); $high = ($b & 0x7F) >> 4; } else { $low |= (($b & 0x7F) << $bits); } $this->advance(1); $count += 1; } while ($b & 0x80); $var = GPBUtil::combineInt32ToInt64($high, $low); if (bccomp($var, 0) < 0) { $var = bcadd($var, "18446744073709551616"); } } else { $result = 0; $shift = 0; do { if ($this->current === $this->buffer_end) { return false; } if ($count === self::MAX_VARINT_BYTES) { return false; } $byte = ord($this->buffer[$this->current]); $result |= ($byte & 0x7f) << $shift; $shift += 7; $this->advance(1); $count += 1; } while ($byte > 0x7f); $var = $result; } return true; } /** * Read int into $var. If the result is larger than the largest integer, $var * will be -1. Advance buffer with consumed bytes. * @param $var */ public function readVarintSizeAsInt(&$var) { if (!$this->readVarint64($var)) { return false; } $var = (int)$var; return true; } /** * Read 32-bit unsigned integer to $var. If the buffer has less than 4 bytes, * return false. Advance buffer with consumed bytes. * @param $var */ public function readLittleEndian32(&$var) { $data = null; if (!$this->readRaw(4, $data)) { return false; } $var = unpack('V', $data); $var = $var[1]; return true; } /** * Read 64-bit unsigned integer to $var. If the buffer has less than 8 bytes, * return false. Advance buffer with consumed bytes. * @param $var */ public function readLittleEndian64(&$var) { $data = null; if (!$this->readRaw(4, $data)) { return false; } $low = unpack('V', $data)[1]; if (!$this->readRaw(4, $data)) { return false; } $high = unpack('V', $data)[1]; if (PHP_INT_SIZE == 4) { $var = GPBUtil::combineInt32ToInt64($high, $low); } else { $var = ($high << 32) | $low; } return true; } /** * Read tag into $var. Advance buffer with consumed bytes. */ public function readTag() { if ($this->current === $this->buffer_end) { // Make sure that it failed due to EOF, not because we hit // total_bytes_limit, which, unlike normal limits, is not a valid // place to end a message. $current_position = $this->total_bytes_read - $this->buffer_size_after_limit; if ($current_position >= $this->total_bytes_limit) { // Hit total_bytes_limit_. But if we also hit the normal limit, // we're still OK. $this->legitimate_message_end = ($this->current_limit === $this->total_bytes_limit); } else { $this->legitimate_message_end = true; } return 0; } $result = 0; // The largest tag is 2^29 - 1, which can be represented by int32. $success = $this->readVarint32($result); if ($success) { return $result; } else { return 0; } } public function readRaw($size, &$buffer) { $current_buffer_size = 0; if ($this->bufferSize() < $size) { return false; } if ($size === 0) { $buffer = ""; } else { $buffer = substr($this->buffer, $this->current, $size); $this->advance($size); } return true; } /* Places a limit on the number of bytes that the stream may read, starting * from the current position. Once the stream hits this limit, it will act * like the end of the input has been reached until popLimit() is called. * * As the names imply, the stream conceptually has a stack of limits. The * shortest limit on the stack is always enforced, even if it is not the top * limit. * * The value returned by pushLimit() is opaque to the caller, and must be * passed unchanged to the corresponding call to popLimit(). * * @param integer $byte_limit * @throws \Exception Fail to push limit. */ public function pushLimit($byte_limit) { // Current position relative to the beginning of the stream. $current_position = $this->current(); $old_limit = $this->current_limit; // security: byte_limit is possibly evil, so check for negative values // and overflow. if ($byte_limit >= 0 && $byte_limit <= PHP_INT_MAX - $current_position && $byte_limit <= $this->current_limit - $current_position) { $this->current_limit = $current_position + $byte_limit; $this->recomputeBufferLimits(); } else { throw new GPBDecodeException("Fail to push limit."); } return $old_limit; } /* The limit passed in is actually the *old* limit, which we returned from * PushLimit(). * * @param integer $byte_limit */ public function popLimit($byte_limit) { $this->current_limit = $byte_limit; $this->recomputeBufferLimits(); // We may no longer be at a legitimate message end. ReadTag() needs to // be called again to find out. $this->legitimate_message_end = false; } public function incrementRecursionDepthAndPushLimit( $byte_limit, &$old_limit, &$recursion_budget) { $old_limit = $this->pushLimit($byte_limit); $recursion_limit = --$this->recursion_limit; } public function decrementRecursionDepthAndPopLimit($byte_limit) { $result = $this->consumedEntireMessage(); $this->popLimit($byte_limit); ++$this->recursion_budget; return $result; } public function bytesUntilLimit() { if ($this->current_limit === PHP_INT_MAX) { return -1; } return $this->current_limit - $this->current; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/CodedOutputStream.php ================================================ current = 0; $this->buffer_size = $size; $this->buffer = str_repeat(chr(0), $this->buffer_size); $this->options = $options; } public function getData() { return $this->buffer; } public function getOptions() { return $this->options; } public function writeVarint32($value, $trim) { $bytes = str_repeat(chr(0), self::MAX_VARINT64_BYTES); $size = self::writeVarintToArray($value, $bytes, $trim); return $this->writeRaw($bytes, $size); } public function writeVarint64($value) { $bytes = str_repeat(chr(0), self::MAX_VARINT64_BYTES); $size = self::writeVarintToArray($value, $bytes); return $this->writeRaw($bytes, $size); } public function writeLittleEndian32($value) { $bytes = str_repeat(chr(0), 4); $size = self::writeLittleEndian32ToArray($value, $bytes); return $this->writeRaw($bytes, $size); } public function writeLittleEndian64($value) { $bytes = str_repeat(chr(0), 8); $size = self::writeLittleEndian64ToArray($value, $bytes); return $this->writeRaw($bytes, $size); } public function writeTag($tag) { return $this->writeVarint32($tag, true); } public function writeRaw($data, $size) { if ($this->buffer_size < $size) { trigger_error("Output stream doesn't have enough buffer."); return false; } for ($i = 0; $i < $size; $i++) { $this->buffer[$this->current] = $data[$i]; $this->current++; $this->buffer_size--; } return true; } public static function writeVarintToArray($value, &$buffer, $trim = false) { $current = 0; $high = 0; $low = 0; if (PHP_INT_SIZE == 4) { GPBUtil::divideInt64ToInt32($value, $high, $low, $trim); } else { $low = $value; } while (($low >= 0x80 || $low < 0) || $high != 0) { $buffer[$current] = chr($low | 0x80); $value = ($value >> 7) & ~(0x7F << ((PHP_INT_SIZE << 3) - 7)); $carry = ($high & 0x7F) << ((PHP_INT_SIZE << 3) - 7); $high = ($high >> 7) & ~(0x7F << ((PHP_INT_SIZE << 3) - 7)); $low = (($low >> 7) & ~(0x7F << ((PHP_INT_SIZE << 3) - 7)) | $carry); $current++; } $buffer[$current] = chr($low); return $current + 1; } private static function writeLittleEndian32ToArray($value, &$buffer) { $buffer[0] = chr($value & 0x000000FF); $buffer[1] = chr(($value >> 8) & 0x000000FF); $buffer[2] = chr(($value >> 16) & 0x000000FF); $buffer[3] = chr(($value >> 24) & 0x000000FF); return 4; } private static function writeLittleEndian64ToArray($value, &$buffer) { $high = 0; $low = 0; if (PHP_INT_SIZE == 4) { GPBUtil::divideInt64ToInt32($value, $high, $low); } else { $low = $value & 0xFFFFFFFF; $high = ($value >> 32) & 0xFFFFFFFF; } $buffer[0] = chr($low & 0x000000FF); $buffer[1] = chr(($low >> 8) & 0x000000FF); $buffer[2] = chr(($low >> 16) & 0x000000FF); $buffer[3] = chr(($low >> 24) & 0x000000FF); $buffer[4] = chr($high & 0x000000FF); $buffer[5] = chr(($high >> 8) & 0x000000FF); $buffer[6] = chr(($high >> 16) & 0x000000FF); $buffer[7] = chr(($high >> 24) & 0x000000FF); return 8; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/Descriptor.php ================================================ public_desc = new \Google\Protobuf\Descriptor($this); } public function addOneofDecl($oneof) { $this->oneof_decl[] = $oneof; } public function getOneofDecl() { return $this->oneof_decl; } public function setFullName($full_name) { $this->full_name = $full_name; } public function getFullName() { return $this->full_name; } public function addField($field) { $this->field[$field->getNumber()] = $field; $this->json_to_field[$field->getJsonName()] = $field; $this->name_to_field[$field->getName()] = $field; $this->index_to_field[] = $field; } public function getField() { return $this->field; } public function addNestedType($desc) { $this->nested_type[] = $desc; } public function getNestedType() { return $this->nested_type; } public function addEnumType($desc) { $this->enum_type[] = $desc; } public function getEnumType() { return $this->enum_type; } public function getFieldByNumber($number) { if (!isset($this->field[$number])) { return NULL; } else { return $this->field[$number]; } } public function getFieldByJsonName($json_name) { if (!isset($this->json_to_field[$json_name])) { return NULL; } else { return $this->json_to_field[$json_name]; } } public function getFieldByName($name) { if (!isset($this->name_to_field[$name])) { return NULL; } else { return $this->name_to_field[$name]; } } public function getFieldByIndex($index) { if (count($this->index_to_field) <= $index) { return NULL; } else { return $this->index_to_field[$index]; } } public function setClass($klass) { $this->klass = $klass; } public function getClass() { return $this->klass; } public function setLegacyClass($klass) { $this->legacy_klass = $klass; } public function getLegacyClass() { return $this->legacy_klass; } public function setPreviouslyUnreservedClass($klass) { $this->previous_klass = $klass; } public function getPreviouslyUnreservedClass() { return $this->previous_klass; } public function setOptions($options) { $this->options = $options; } public function getOptions() { return $this->options; } public static function buildFromProto($proto, $file_proto, $containing) { $desc = new Descriptor(); $message_name_without_package = ""; $classname = ""; $legacy_classname = ""; $previous_classname = ""; $fullname = ""; GPBUtil::getFullClassName( $proto, $containing, $file_proto, $message_name_without_package, $classname, $legacy_classname, $fullname, $previous_classname); $desc->setFullName($fullname); $desc->setClass($classname); $desc->setLegacyClass($legacy_classname); $desc->setPreviouslyUnreservedClass($previous_classname); $desc->setOptions($proto->getOptions()); foreach ($proto->getField() as $field_proto) { $desc->addField(FieldDescriptor::buildFromProto($field_proto)); } // Handle nested types. foreach ($proto->getNestedType() as $nested_proto) { $desc->addNestedType(Descriptor::buildFromProto( $nested_proto, $file_proto, $message_name_without_package)); } // Handle nested enum. foreach ($proto->getEnumType() as $enum_proto) { $desc->addEnumType(EnumDescriptor::buildFromProto( $enum_proto, $file_proto, $message_name_without_package)); } // Handle oneof fields. $index = 0; foreach ($proto->getOneofDecl() as $oneof_proto) { $desc->addOneofDecl( OneofDescriptor::buildFromProto($oneof_proto, $desc, $index)); $index++; } return $desc; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/DescriptorPool.php ================================================ mergeFromString($data); foreach($files->getFile() as $file_proto) { $file = FileDescriptor::buildFromProto($file_proto); foreach ($file->getMessageType() as $desc) { $this->addDescriptor($desc); } unset($desc); foreach ($file->getEnumType() as $desc) { $this->addEnumDescriptor($desc); } unset($desc); foreach ($file->getMessageType() as $desc) { $this->crossLink($desc); } unset($desc); } } public function addMessage($name, $klass) { return new MessageBuilderContext($name, $klass, $this); } public function addEnum($name, $klass) { return new EnumBuilderContext($name, $klass, $this); } public function addDescriptor($descriptor) { $this->proto_to_class[$descriptor->getFullName()] = $descriptor->getClass(); $this->unique_descs[$descriptor->getFullName()] = $descriptor; $this->class_to_desc[$descriptor->getClass()] = $descriptor; $this->class_to_desc[$descriptor->getLegacyClass()] = $descriptor; $this->class_to_desc[$descriptor->getPreviouslyUnreservedClass()] = $descriptor; foreach ($descriptor->getNestedType() as $nested_type) { $this->addDescriptor($nested_type); } foreach ($descriptor->getEnumType() as $enum_type) { $this->addEnumDescriptor($enum_type); } } public function addEnumDescriptor($descriptor) { $this->proto_to_class[$descriptor->getFullName()] = $descriptor->getClass(); $this->class_to_enum_desc[$descriptor->getClass()] = $descriptor; $this->class_to_enum_desc[$descriptor->getLegacyClass()] = $descriptor; } public function getDescriptorByClassName($klass) { if (isset($this->class_to_desc[$klass])) { return $this->class_to_desc[$klass]; } else { return null; } } public function getEnumDescriptorByClassName($klass) { if (isset($this->class_to_enum_desc[$klass])) { return $this->class_to_enum_desc[$klass]; } else { return null; } } public function getDescriptorByProtoName($proto) { if (isset($this->proto_to_class[$proto])) { $klass = $this->proto_to_class[$proto]; return $this->class_to_desc[$klass]; } else { return null; } } public function getEnumDescriptorByProtoName($proto) { $klass = $this->proto_to_class[$proto]; return $this->class_to_enum_desc[$klass]; } private function crossLink(Descriptor $desc) { foreach ($desc->getField() as $field) { switch ($field->getType()) { case GPBType::MESSAGE: $proto = $field->getMessageType(); if ($proto[0] == '.') { $proto = substr($proto, 1); } $subdesc = $this->getDescriptorByProtoName($proto); if (is_null($subdesc)) { trigger_error( 'proto not added: ' . $proto . " for " . $desc->getFullName(), E_USER_ERROR); } $field->setMessageType($subdesc); break; case GPBType::ENUM: $proto = $field->getEnumType(); if ($proto[0] == '.') { $proto = substr($proto, 1); } $field->setEnumType( $this->getEnumDescriptorByProtoName($proto)); break; default: break; } } unset($field); foreach ($desc->getNestedType() as $nested_type) { $this->crossLink($nested_type); } unset($nested_type); } public function finish() { foreach ($this->unique_descs as $klass => $desc) { $this->crossLink($desc); } unset($desc); } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/DescriptorProto/ExtensionRange.php ================================================ google.protobuf.DescriptorProto.ExtensionRange */ class ExtensionRange extends \Google\Protobuf\Internal\Message { /** * Inclusive. * * Generated from protobuf field optional int32 start = 1; */ protected $start = null; /** * Exclusive. * * Generated from protobuf field optional int32 end = 2; */ protected $end = null; /** * Generated from protobuf field optional .google.protobuf.ExtensionRangeOptions options = 3; */ protected $options = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type int $start * Inclusive. * @type int $end * Exclusive. * @type \Google\Protobuf\Internal\ExtensionRangeOptions $options * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); parent::__construct($data); } /** * Inclusive. * * Generated from protobuf field optional int32 start = 1; * @return int */ public function getStart() { return isset($this->start) ? $this->start : 0; } public function hasStart() { return isset($this->start); } public function clearStart() { unset($this->start); } /** * Inclusive. * * Generated from protobuf field optional int32 start = 1; * @param int $var * @return $this */ public function setStart($var) { GPBUtil::checkInt32($var); $this->start = $var; return $this; } /** * Exclusive. * * Generated from protobuf field optional int32 end = 2; * @return int */ public function getEnd() { return isset($this->end) ? $this->end : 0; } public function hasEnd() { return isset($this->end); } public function clearEnd() { unset($this->end); } /** * Exclusive. * * Generated from protobuf field optional int32 end = 2; * @param int $var * @return $this */ public function setEnd($var) { GPBUtil::checkInt32($var); $this->end = $var; return $this; } /** * Generated from protobuf field optional .google.protobuf.ExtensionRangeOptions options = 3; * @return \Google\Protobuf\Internal\ExtensionRangeOptions|null */ public function getOptions() { return $this->options; } public function hasOptions() { return isset($this->options); } public function clearOptions() { unset($this->options); } /** * Generated from protobuf field optional .google.protobuf.ExtensionRangeOptions options = 3; * @param \Google\Protobuf\Internal\ExtensionRangeOptions $var * @return $this */ public function setOptions($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\ExtensionRangeOptions::class); $this->options = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/DescriptorProto/ReservedRange.php ================================================ google.protobuf.DescriptorProto.ReservedRange */ class ReservedRange extends \Google\Protobuf\Internal\Message { /** * Inclusive. * * Generated from protobuf field optional int32 start = 1; */ protected $start = null; /** * Exclusive. * * Generated from protobuf field optional int32 end = 2; */ protected $end = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type int $start * Inclusive. * @type int $end * Exclusive. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); parent::__construct($data); } /** * Inclusive. * * Generated from protobuf field optional int32 start = 1; * @return int */ public function getStart() { return isset($this->start) ? $this->start : 0; } public function hasStart() { return isset($this->start); } public function clearStart() { unset($this->start); } /** * Inclusive. * * Generated from protobuf field optional int32 start = 1; * @param int $var * @return $this */ public function setStart($var) { GPBUtil::checkInt32($var); $this->start = $var; return $this; } /** * Exclusive. * * Generated from protobuf field optional int32 end = 2; * @return int */ public function getEnd() { return isset($this->end) ? $this->end : 0; } public function hasEnd() { return isset($this->end); } public function clearEnd() { unset($this->end); } /** * Exclusive. * * Generated from protobuf field optional int32 end = 2; * @param int $var * @return $this */ public function setEnd($var) { GPBUtil::checkInt32($var); $this->end = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/DescriptorProto.php ================================================ google.protobuf.DescriptorProto */ class DescriptorProto extends \Google\Protobuf\Internal\Message { /** * Generated from protobuf field optional string name = 1; */ protected $name = null; /** * Generated from protobuf field repeated .google.protobuf.FieldDescriptorProto field = 2; */ private $field; /** * Generated from protobuf field repeated .google.protobuf.FieldDescriptorProto extension = 6; */ private $extension; /** * Generated from protobuf field repeated .google.protobuf.DescriptorProto nested_type = 3; */ private $nested_type; /** * Generated from protobuf field repeated .google.protobuf.EnumDescriptorProto enum_type = 4; */ private $enum_type; /** * Generated from protobuf field repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; */ private $extension_range; /** * Generated from protobuf field repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8; */ private $oneof_decl; /** * Generated from protobuf field optional .google.protobuf.MessageOptions options = 7; */ protected $options = null; /** * Generated from protobuf field repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9; */ private $reserved_range; /** * Reserved field names, which may not be used by fields in the same message. * A given name may only be reserved once. * * Generated from protobuf field repeated string reserved_name = 10; */ private $reserved_name; /** * Support for `export` and `local` keywords on enums. * * Generated from protobuf field optional .google.protobuf.SymbolVisibility visibility = 11; */ protected $visibility = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $name * @type \Google\Protobuf\Internal\FieldDescriptorProto[] $field * @type \Google\Protobuf\Internal\FieldDescriptorProto[] $extension * @type \Google\Protobuf\Internal\DescriptorProto[] $nested_type * @type \Google\Protobuf\Internal\EnumDescriptorProto[] $enum_type * @type \Google\Protobuf\Internal\DescriptorProto\ExtensionRange[] $extension_range * @type \Google\Protobuf\Internal\OneofDescriptorProto[] $oneof_decl * @type \Google\Protobuf\Internal\MessageOptions $options * @type \Google\Protobuf\Internal\DescriptorProto\ReservedRange[] $reserved_range * @type string[] $reserved_name * Reserved field names, which may not be used by fields in the same message. * A given name may only be reserved once. * @type int $visibility * Support for `export` and `local` keywords on enums. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); parent::__construct($data); } /** * Generated from protobuf field optional string name = 1; * @return string */ public function getName() { return isset($this->name) ? $this->name : ''; } public function hasName() { return isset($this->name); } public function clearName() { unset($this->name); } /** * Generated from protobuf field optional string name = 1; * @param string $var * @return $this */ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; return $this; } /** * Generated from protobuf field repeated .google.protobuf.FieldDescriptorProto field = 2; * @return RepeatedField<\Google\Protobuf\Internal\FieldDescriptorProto> */ public function getField() { return $this->field; } /** * Generated from protobuf field repeated .google.protobuf.FieldDescriptorProto field = 2; * @param \Google\Protobuf\Internal\FieldDescriptorProto[] $var * @return $this */ public function setField($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\FieldDescriptorProto::class); $this->field = $arr; return $this; } /** * Generated from protobuf field repeated .google.protobuf.FieldDescriptorProto extension = 6; * @return RepeatedField<\Google\Protobuf\Internal\FieldDescriptorProto> */ public function getExtension() { return $this->extension; } /** * Generated from protobuf field repeated .google.protobuf.FieldDescriptorProto extension = 6; * @param \Google\Protobuf\Internal\FieldDescriptorProto[] $var * @return $this */ public function setExtension($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\FieldDescriptorProto::class); $this->extension = $arr; return $this; } /** * Generated from protobuf field repeated .google.protobuf.DescriptorProto nested_type = 3; * @return RepeatedField<\Google\Protobuf\Internal\DescriptorProto> */ public function getNestedType() { return $this->nested_type; } /** * Generated from protobuf field repeated .google.protobuf.DescriptorProto nested_type = 3; * @param \Google\Protobuf\Internal\DescriptorProto[] $var * @return $this */ public function setNestedType($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\DescriptorProto::class); $this->nested_type = $arr; return $this; } /** * Generated from protobuf field repeated .google.protobuf.EnumDescriptorProto enum_type = 4; * @return RepeatedField<\Google\Protobuf\Internal\EnumDescriptorProto> */ public function getEnumType() { return $this->enum_type; } /** * Generated from protobuf field repeated .google.protobuf.EnumDescriptorProto enum_type = 4; * @param \Google\Protobuf\Internal\EnumDescriptorProto[] $var * @return $this */ public function setEnumType($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\EnumDescriptorProto::class); $this->enum_type = $arr; return $this; } /** * Generated from protobuf field repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; * @return RepeatedField<\Google\Protobuf\Internal\DescriptorProto\ExtensionRange> */ public function getExtensionRange() { return $this->extension_range; } /** * Generated from protobuf field repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; * @param \Google\Protobuf\Internal\DescriptorProto\ExtensionRange[] $var * @return $this */ public function setExtensionRange($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\DescriptorProto\ExtensionRange::class); $this->extension_range = $arr; return $this; } /** * Generated from protobuf field repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8; * @return RepeatedField<\Google\Protobuf\Internal\OneofDescriptorProto> */ public function getOneofDecl() { return $this->oneof_decl; } /** * Generated from protobuf field repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8; * @param \Google\Protobuf\Internal\OneofDescriptorProto[] $var * @return $this */ public function setOneofDecl($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\OneofDescriptorProto::class); $this->oneof_decl = $arr; return $this; } /** * Generated from protobuf field optional .google.protobuf.MessageOptions options = 7; * @return \Google\Protobuf\Internal\MessageOptions|null */ public function getOptions() { return $this->options; } public function hasOptions() { return isset($this->options); } public function clearOptions() { unset($this->options); } /** * Generated from protobuf field optional .google.protobuf.MessageOptions options = 7; * @param \Google\Protobuf\Internal\MessageOptions $var * @return $this */ public function setOptions($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\MessageOptions::class); $this->options = $var; return $this; } /** * Generated from protobuf field repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9; * @return RepeatedField<\Google\Protobuf\Internal\DescriptorProto\ReservedRange> */ public function getReservedRange() { return $this->reserved_range; } /** * Generated from protobuf field repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9; * @param \Google\Protobuf\Internal\DescriptorProto\ReservedRange[] $var * @return $this */ public function setReservedRange($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\DescriptorProto\ReservedRange::class); $this->reserved_range = $arr; return $this; } /** * Reserved field names, which may not be used by fields in the same message. * A given name may only be reserved once. * * Generated from protobuf field repeated string reserved_name = 10; * @return RepeatedField */ public function getReservedName() { return $this->reserved_name; } /** * Reserved field names, which may not be used by fields in the same message. * A given name may only be reserved once. * * Generated from protobuf field repeated string reserved_name = 10; * @param string[] $var * @return $this */ public function setReservedName($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->reserved_name = $arr; return $this; } /** * Support for `export` and `local` keywords on enums. * * Generated from protobuf field optional .google.protobuf.SymbolVisibility visibility = 11; * @return int */ public function getVisibility() { return isset($this->visibility) ? $this->visibility : 0; } public function hasVisibility() { return isset($this->visibility); } public function clearVisibility() { unset($this->visibility); } /** * Support for `export` and `local` keywords on enums. * * Generated from protobuf field optional .google.protobuf.SymbolVisibility visibility = 11; * @param int $var * @return $this */ public function setVisibility($var) { GPBUtil::checkEnum($var, \Google\Protobuf\Internal\SymbolVisibility::class); $this->visibility = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/Edition.php ================================================ google.protobuf.Edition */ class Edition { /** * A placeholder for an unknown edition value. * * Generated from protobuf enum EDITION_UNKNOWN = 0; */ const EDITION_UNKNOWN = 0; /** * A placeholder edition for specifying default behaviors *before* a feature * was first introduced. This is effectively an "infinite past". * * Generated from protobuf enum EDITION_LEGACY = 900; */ const EDITION_LEGACY = 900; /** * Legacy syntax "editions". These pre-date editions, but behave much like * distinct editions. These can't be used to specify the edition of proto * files, but feature definitions must supply proto2/proto3 defaults for * backwards compatibility. * * Generated from protobuf enum EDITION_PROTO2 = 998; */ const EDITION_PROTO2 = 998; /** * Generated from protobuf enum EDITION_PROTO3 = 999; */ const EDITION_PROTO3 = 999; /** * Editions that have been released. The specific values are arbitrary and * should not be depended on, but they will always be time-ordered for easy * comparison. * * Generated from protobuf enum EDITION_2023 = 1000; */ const EDITION_2023 = 1000; /** * Generated from protobuf enum EDITION_2024 = 1001; */ const EDITION_2024 = 1001; /** * A placeholder edition for developing and testing unscheduled features. * * Generated from protobuf enum EDITION_UNSTABLE = 9999; */ const EDITION_UNSTABLE = 9999; /** * Placeholder editions for testing feature resolution. These should not be * used or relied on outside of tests. * * Generated from protobuf enum EDITION_1_TEST_ONLY = 1; */ const EDITION_1_TEST_ONLY = 1; /** * Generated from protobuf enum EDITION_2_TEST_ONLY = 2; */ const EDITION_2_TEST_ONLY = 2; /** * Generated from protobuf enum EDITION_99997_TEST_ONLY = 99997; */ const EDITION_99997_TEST_ONLY = 99997; /** * Generated from protobuf enum EDITION_99998_TEST_ONLY = 99998; */ const EDITION_99998_TEST_ONLY = 99998; /** * Generated from protobuf enum EDITION_99999_TEST_ONLY = 99999; */ const EDITION_99999_TEST_ONLY = 99999; /** * Placeholder for specifying unbounded edition support. This should only * ever be used by plugins that can expect to never require any changes to * support a new edition. * * Generated from protobuf enum EDITION_MAX = 2147483647; */ const EDITION_MAX = 2147483647; private static $valueToName = [ self::EDITION_UNKNOWN => 'EDITION_UNKNOWN', self::EDITION_LEGACY => 'EDITION_LEGACY', self::EDITION_PROTO2 => 'EDITION_PROTO2', self::EDITION_PROTO3 => 'EDITION_PROTO3', self::EDITION_2023 => 'EDITION_2023', self::EDITION_2024 => 'EDITION_2024', self::EDITION_UNSTABLE => 'EDITION_UNSTABLE', self::EDITION_1_TEST_ONLY => 'EDITION_1_TEST_ONLY', self::EDITION_2_TEST_ONLY => 'EDITION_2_TEST_ONLY', self::EDITION_99997_TEST_ONLY => 'EDITION_99997_TEST_ONLY', self::EDITION_99998_TEST_ONLY => 'EDITION_99998_TEST_ONLY', self::EDITION_99999_TEST_ONLY => 'EDITION_99999_TEST_ONLY', self::EDITION_MAX => 'EDITION_MAX', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/EnumBuilderContext.php ================================================ descriptor = new EnumDescriptor(); $this->descriptor->setFullName($full_name); $this->descriptor->setClass($klass); $this->pool = $pool; } public function value($name, $number) { $value = new EnumValueDescriptor($name, $number); $this->descriptor->addValue($number, $value); return $this; } public function finalizeToPool() { $this->pool->addEnumDescriptor($this->descriptor); } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/EnumDescriptor.php ================================================ public_desc = new \Google\Protobuf\EnumDescriptor($this); } public function setFullName($full_name) { $this->full_name = $full_name; } public function getFullName() { return $this->full_name; } public function addValue($number, $value) { $this->value[$number] = $value; $this->name_to_value[$value->getName()] = $value; $this->value_descriptor[] = new EnumValueDescriptor($value->getName(), $number); } public function getValueByNumber($number) { if (isset($this->value[$number])) { return $this->value[$number]; } return null; } public function getValueByName($name) { if (isset($this->name_to_value[$name])) { return $this->name_to_value[$name]; } return null; } public function getValueDescriptorByIndex($index) { if (isset($this->value_descriptor[$index])) { return $this->value_descriptor[$index]; } return null; } public function getValueCount() { return count($this->value); } public function setClass($klass) { $this->klass = $klass; } public function getClass() { return $this->klass; } public function setLegacyClass($klass) { $this->legacy_klass = $klass; } public function getLegacyClass() { return $this->legacy_klass; } public static function buildFromProto($proto, $file_proto, $containing) { $desc = new EnumDescriptor(); $enum_name_without_package = ""; $classname = ""; $legacy_classname = ""; $fullname = ""; GPBUtil::getFullClassName( $proto, $containing, $file_proto, $enum_name_without_package, $classname, $legacy_classname, $fullname, $unused_previous_classname); $desc->setFullName($fullname); $desc->setClass($classname); $desc->setLegacyClass($legacy_classname); $values = $proto->getValue(); foreach ($values as $value) { $desc->addValue($value->getNumber(), $value); } return $desc; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/EnumDescriptorProto/EnumReservedRange.php ================================================ google.protobuf.EnumDescriptorProto.EnumReservedRange */ class EnumReservedRange extends \Google\Protobuf\Internal\Message { /** * Inclusive. * * Generated from protobuf field optional int32 start = 1; */ protected $start = null; /** * Inclusive. * * Generated from protobuf field optional int32 end = 2; */ protected $end = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type int $start * Inclusive. * @type int $end * Inclusive. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); parent::__construct($data); } /** * Inclusive. * * Generated from protobuf field optional int32 start = 1; * @return int */ public function getStart() { return isset($this->start) ? $this->start : 0; } public function hasStart() { return isset($this->start); } public function clearStart() { unset($this->start); } /** * Inclusive. * * Generated from protobuf field optional int32 start = 1; * @param int $var * @return $this */ public function setStart($var) { GPBUtil::checkInt32($var); $this->start = $var; return $this; } /** * Inclusive. * * Generated from protobuf field optional int32 end = 2; * @return int */ public function getEnd() { return isset($this->end) ? $this->end : 0; } public function hasEnd() { return isset($this->end); } public function clearEnd() { unset($this->end); } /** * Inclusive. * * Generated from protobuf field optional int32 end = 2; * @param int $var * @return $this */ public function setEnd($var) { GPBUtil::checkInt32($var); $this->end = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/EnumDescriptorProto.php ================================================ google.protobuf.EnumDescriptorProto */ class EnumDescriptorProto extends \Google\Protobuf\Internal\Message { /** * Generated from protobuf field optional string name = 1; */ protected $name = null; /** * Generated from protobuf field repeated .google.protobuf.EnumValueDescriptorProto value = 2; */ private $value; /** * Generated from protobuf field optional .google.protobuf.EnumOptions options = 3; */ protected $options = null; /** * Range of reserved numeric values. Reserved numeric values may not be used * by enum values in the same enum declaration. Reserved ranges may not * overlap. * * Generated from protobuf field repeated .google.protobuf.EnumDescriptorProto.EnumReservedRange reserved_range = 4; */ private $reserved_range; /** * Reserved enum value names, which may not be reused. A given name may only * be reserved once. * * Generated from protobuf field repeated string reserved_name = 5; */ private $reserved_name; /** * Support for `export` and `local` keywords on enums. * * Generated from protobuf field optional .google.protobuf.SymbolVisibility visibility = 6; */ protected $visibility = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $name * @type \Google\Protobuf\Internal\EnumValueDescriptorProto[] $value * @type \Google\Protobuf\Internal\EnumOptions $options * @type \Google\Protobuf\Internal\EnumDescriptorProto\EnumReservedRange[] $reserved_range * Range of reserved numeric values. Reserved numeric values may not be used * by enum values in the same enum declaration. Reserved ranges may not * overlap. * @type string[] $reserved_name * Reserved enum value names, which may not be reused. A given name may only * be reserved once. * @type int $visibility * Support for `export` and `local` keywords on enums. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); parent::__construct($data); } /** * Generated from protobuf field optional string name = 1; * @return string */ public function getName() { return isset($this->name) ? $this->name : ''; } public function hasName() { return isset($this->name); } public function clearName() { unset($this->name); } /** * Generated from protobuf field optional string name = 1; * @param string $var * @return $this */ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; return $this; } /** * Generated from protobuf field repeated .google.protobuf.EnumValueDescriptorProto value = 2; * @return RepeatedField<\Google\Protobuf\Internal\EnumValueDescriptorProto> */ public function getValue() { return $this->value; } /** * Generated from protobuf field repeated .google.protobuf.EnumValueDescriptorProto value = 2; * @param \Google\Protobuf\Internal\EnumValueDescriptorProto[] $var * @return $this */ public function setValue($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\EnumValueDescriptorProto::class); $this->value = $arr; return $this; } /** * Generated from protobuf field optional .google.protobuf.EnumOptions options = 3; * @return \Google\Protobuf\Internal\EnumOptions|null */ public function getOptions() { return $this->options; } public function hasOptions() { return isset($this->options); } public function clearOptions() { unset($this->options); } /** * Generated from protobuf field optional .google.protobuf.EnumOptions options = 3; * @param \Google\Protobuf\Internal\EnumOptions $var * @return $this */ public function setOptions($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\EnumOptions::class); $this->options = $var; return $this; } /** * Range of reserved numeric values. Reserved numeric values may not be used * by enum values in the same enum declaration. Reserved ranges may not * overlap. * * Generated from protobuf field repeated .google.protobuf.EnumDescriptorProto.EnumReservedRange reserved_range = 4; * @return RepeatedField<\Google\Protobuf\Internal\EnumDescriptorProto\EnumReservedRange> */ public function getReservedRange() { return $this->reserved_range; } /** * Range of reserved numeric values. Reserved numeric values may not be used * by enum values in the same enum declaration. Reserved ranges may not * overlap. * * Generated from protobuf field repeated .google.protobuf.EnumDescriptorProto.EnumReservedRange reserved_range = 4; * @param \Google\Protobuf\Internal\EnumDescriptorProto\EnumReservedRange[] $var * @return $this */ public function setReservedRange($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\EnumDescriptorProto\EnumReservedRange::class); $this->reserved_range = $arr; return $this; } /** * Reserved enum value names, which may not be reused. A given name may only * be reserved once. * * Generated from protobuf field repeated string reserved_name = 5; * @return RepeatedField */ public function getReservedName() { return $this->reserved_name; } /** * Reserved enum value names, which may not be reused. A given name may only * be reserved once. * * Generated from protobuf field repeated string reserved_name = 5; * @param string[] $var * @return $this */ public function setReservedName($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->reserved_name = $arr; return $this; } /** * Support for `export` and `local` keywords on enums. * * Generated from protobuf field optional .google.protobuf.SymbolVisibility visibility = 6; * @return int */ public function getVisibility() { return isset($this->visibility) ? $this->visibility : 0; } public function hasVisibility() { return isset($this->visibility); } public function clearVisibility() { unset($this->visibility); } /** * Support for `export` and `local` keywords on enums. * * Generated from protobuf field optional .google.protobuf.SymbolVisibility visibility = 6; * @param int $var * @return $this */ public function setVisibility($var) { GPBUtil::checkEnum($var, \Google\Protobuf\Internal\SymbolVisibility::class); $this->visibility = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/EnumOptions.php ================================================ google.protobuf.EnumOptions */ class EnumOptions extends \Google\Protobuf\Internal\Message { /** * Set this option to true to allow mapping different tag names to the same * value. * * Generated from protobuf field optional bool allow_alias = 2; */ protected $allow_alias = null; /** * Is this enum deprecated? * Depending on the target platform, this can emit Deprecated annotations * for the enum, or it will be completely ignored; in the very least, this * is a formalization for deprecating enums. * * Generated from protobuf field optional bool deprecated = 3 [default = false]; */ protected $deprecated = null; /** * Enable the legacy handling of JSON field name conflicts. This lowercases * and strips underscored from the fields before comparison in proto3 only. * The new behavior takes `json_name` into account and applies to proto2 as * well. * TODO Remove this legacy behavior once downstream teams have * had time to migrate. * * Generated from protobuf field optional bool deprecated_legacy_json_field_conflicts = 6 [deprecated = true]; * @deprecated */ protected $deprecated_legacy_json_field_conflicts = null; /** * Any features defined in the specific edition. * WARNING: This field should only be used by protobuf plugins or special * cases like the proto compiler. Other uses are discouraged and * developers should rely on the protoreflect APIs for their client language. * * Generated from protobuf field optional .google.protobuf.FeatureSet features = 7; */ protected $features = null; /** * The parser stores options it doesn't recognize here. See above. * * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; */ private $uninterpreted_option; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type bool $allow_alias * Set this option to true to allow mapping different tag names to the same * value. * @type bool $deprecated * Is this enum deprecated? * Depending on the target platform, this can emit Deprecated annotations * for the enum, or it will be completely ignored; in the very least, this * is a formalization for deprecating enums. * @type bool $deprecated_legacy_json_field_conflicts * Enable the legacy handling of JSON field name conflicts. This lowercases * and strips underscored from the fields before comparison in proto3 only. * The new behavior takes `json_name` into account and applies to proto2 as * well. * TODO Remove this legacy behavior once downstream teams have * had time to migrate. * @type \Google\Protobuf\Internal\FeatureSet $features * Any features defined in the specific edition. * WARNING: This field should only be used by protobuf plugins or special * cases like the proto compiler. Other uses are discouraged and * developers should rely on the protoreflect APIs for their client language. * @type \Google\Protobuf\Internal\UninterpretedOption[] $uninterpreted_option * The parser stores options it doesn't recognize here. See above. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); parent::__construct($data); } /** * Set this option to true to allow mapping different tag names to the same * value. * * Generated from protobuf field optional bool allow_alias = 2; * @return bool */ public function getAllowAlias() { return isset($this->allow_alias) ? $this->allow_alias : false; } public function hasAllowAlias() { return isset($this->allow_alias); } public function clearAllowAlias() { unset($this->allow_alias); } /** * Set this option to true to allow mapping different tag names to the same * value. * * Generated from protobuf field optional bool allow_alias = 2; * @param bool $var * @return $this */ public function setAllowAlias($var) { GPBUtil::checkBool($var); $this->allow_alias = $var; return $this; } /** * Is this enum deprecated? * Depending on the target platform, this can emit Deprecated annotations * for the enum, or it will be completely ignored; in the very least, this * is a formalization for deprecating enums. * * Generated from protobuf field optional bool deprecated = 3 [default = false]; * @return bool */ public function getDeprecated() { return isset($this->deprecated) ? $this->deprecated : false; } public function hasDeprecated() { return isset($this->deprecated); } public function clearDeprecated() { unset($this->deprecated); } /** * Is this enum deprecated? * Depending on the target platform, this can emit Deprecated annotations * for the enum, or it will be completely ignored; in the very least, this * is a formalization for deprecating enums. * * Generated from protobuf field optional bool deprecated = 3 [default = false]; * @param bool $var * @return $this */ public function setDeprecated($var) { GPBUtil::checkBool($var); $this->deprecated = $var; return $this; } /** * Enable the legacy handling of JSON field name conflicts. This lowercases * and strips underscored from the fields before comparison in proto3 only. * The new behavior takes `json_name` into account and applies to proto2 as * well. * TODO Remove this legacy behavior once downstream teams have * had time to migrate. * * Generated from protobuf field optional bool deprecated_legacy_json_field_conflicts = 6 [deprecated = true]; * @return bool * @deprecated */ public function getDeprecatedLegacyJsonFieldConflicts() { if (isset($this->deprecated_legacy_json_field_conflicts)) { @trigger_error('deprecated_legacy_json_field_conflicts is deprecated.', E_USER_DEPRECATED); } return isset($this->deprecated_legacy_json_field_conflicts) ? $this->deprecated_legacy_json_field_conflicts : false; } public function hasDeprecatedLegacyJsonFieldConflicts() { if (isset($this->deprecated_legacy_json_field_conflicts)) { @trigger_error('deprecated_legacy_json_field_conflicts is deprecated.', E_USER_DEPRECATED); } return isset($this->deprecated_legacy_json_field_conflicts); } public function clearDeprecatedLegacyJsonFieldConflicts() { @trigger_error('deprecated_legacy_json_field_conflicts is deprecated.', E_USER_DEPRECATED); unset($this->deprecated_legacy_json_field_conflicts); } /** * Enable the legacy handling of JSON field name conflicts. This lowercases * and strips underscored from the fields before comparison in proto3 only. * The new behavior takes `json_name` into account and applies to proto2 as * well. * TODO Remove this legacy behavior once downstream teams have * had time to migrate. * * Generated from protobuf field optional bool deprecated_legacy_json_field_conflicts = 6 [deprecated = true]; * @param bool $var * @return $this * @deprecated */ public function setDeprecatedLegacyJsonFieldConflicts($var) { @trigger_error('deprecated_legacy_json_field_conflicts is deprecated.', E_USER_DEPRECATED); GPBUtil::checkBool($var); $this->deprecated_legacy_json_field_conflicts = $var; return $this; } /** * Any features defined in the specific edition. * WARNING: This field should only be used by protobuf plugins or special * cases like the proto compiler. Other uses are discouraged and * developers should rely on the protoreflect APIs for their client language. * * Generated from protobuf field optional .google.protobuf.FeatureSet features = 7; * @return \Google\Protobuf\Internal\FeatureSet|null */ public function getFeatures() { return $this->features; } public function hasFeatures() { return isset($this->features); } public function clearFeatures() { unset($this->features); } /** * Any features defined in the specific edition. * WARNING: This field should only be used by protobuf plugins or special * cases like the proto compiler. Other uses are discouraged and * developers should rely on the protoreflect APIs for their client language. * * Generated from protobuf field optional .google.protobuf.FeatureSet features = 7; * @param \Google\Protobuf\Internal\FeatureSet $var * @return $this */ public function setFeatures($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\FeatureSet::class); $this->features = $var; return $this; } /** * The parser stores options it doesn't recognize here. See above. * * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; * @return RepeatedField<\Google\Protobuf\Internal\UninterpretedOption> */ public function getUninterpretedOption() { return $this->uninterpreted_option; } /** * The parser stores options it doesn't recognize here. See above. * * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; * @param \Google\Protobuf\Internal\UninterpretedOption[] $var * @return $this */ public function setUninterpretedOption($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); $this->uninterpreted_option = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/EnumValueDescriptorProto.php ================================================ google.protobuf.EnumValueDescriptorProto */ class EnumValueDescriptorProto extends \Google\Protobuf\Internal\Message { /** * Generated from protobuf field optional string name = 1; */ protected $name = null; /** * Generated from protobuf field optional int32 number = 2; */ protected $number = null; /** * Generated from protobuf field optional .google.protobuf.EnumValueOptions options = 3; */ protected $options = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $name * @type int $number * @type \Google\Protobuf\Internal\EnumValueOptions $options * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); parent::__construct($data); } /** * Generated from protobuf field optional string name = 1; * @return string */ public function getName() { return isset($this->name) ? $this->name : ''; } public function hasName() { return isset($this->name); } public function clearName() { unset($this->name); } /** * Generated from protobuf field optional string name = 1; * @param string $var * @return $this */ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; return $this; } /** * Generated from protobuf field optional int32 number = 2; * @return int */ public function getNumber() { return isset($this->number) ? $this->number : 0; } public function hasNumber() { return isset($this->number); } public function clearNumber() { unset($this->number); } /** * Generated from protobuf field optional int32 number = 2; * @param int $var * @return $this */ public function setNumber($var) { GPBUtil::checkInt32($var); $this->number = $var; return $this; } /** * Generated from protobuf field optional .google.protobuf.EnumValueOptions options = 3; * @return \Google\Protobuf\Internal\EnumValueOptions|null */ public function getOptions() { return $this->options; } public function hasOptions() { return isset($this->options); } public function clearOptions() { unset($this->options); } /** * Generated from protobuf field optional .google.protobuf.EnumValueOptions options = 3; * @param \Google\Protobuf\Internal\EnumValueOptions $var * @return $this */ public function setOptions($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\EnumValueOptions::class); $this->options = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/EnumValueOptions.php ================================================ google.protobuf.EnumValueOptions */ class EnumValueOptions extends \Google\Protobuf\Internal\Message { /** * Is this enum value deprecated? * Depending on the target platform, this can emit Deprecated annotations * for the enum value, or it will be completely ignored; in the very least, * this is a formalization for deprecating enum values. * * Generated from protobuf field optional bool deprecated = 1 [default = false]; */ protected $deprecated = null; /** * Any features defined in the specific edition. * WARNING: This field should only be used by protobuf plugins or special * cases like the proto compiler. Other uses are discouraged and * developers should rely on the protoreflect APIs for their client language. * * Generated from protobuf field optional .google.protobuf.FeatureSet features = 2; */ protected $features = null; /** * Indicate that fields annotated with this enum value should not be printed * out when using debug formats, e.g. when the field contains sensitive * credentials. * * Generated from protobuf field optional bool debug_redact = 3 [default = false]; */ protected $debug_redact = null; /** * Information about the support window of a feature value. * * Generated from protobuf field optional .google.protobuf.FieldOptions.FeatureSupport feature_support = 4; */ protected $feature_support = null; /** * The parser stores options it doesn't recognize here. See above. * * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; */ private $uninterpreted_option; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type bool $deprecated * Is this enum value deprecated? * Depending on the target platform, this can emit Deprecated annotations * for the enum value, or it will be completely ignored; in the very least, * this is a formalization for deprecating enum values. * @type \Google\Protobuf\Internal\FeatureSet $features * Any features defined in the specific edition. * WARNING: This field should only be used by protobuf plugins or special * cases like the proto compiler. Other uses are discouraged and * developers should rely on the protoreflect APIs for their client language. * @type bool $debug_redact * Indicate that fields annotated with this enum value should not be printed * out when using debug formats, e.g. when the field contains sensitive * credentials. * @type \Google\Protobuf\Internal\FieldOptions\FeatureSupport $feature_support * Information about the support window of a feature value. * @type \Google\Protobuf\Internal\UninterpretedOption[] $uninterpreted_option * The parser stores options it doesn't recognize here. See above. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); parent::__construct($data); } /** * Is this enum value deprecated? * Depending on the target platform, this can emit Deprecated annotations * for the enum value, or it will be completely ignored; in the very least, * this is a formalization for deprecating enum values. * * Generated from protobuf field optional bool deprecated = 1 [default = false]; * @return bool */ public function getDeprecated() { return isset($this->deprecated) ? $this->deprecated : false; } public function hasDeprecated() { return isset($this->deprecated); } public function clearDeprecated() { unset($this->deprecated); } /** * Is this enum value deprecated? * Depending on the target platform, this can emit Deprecated annotations * for the enum value, or it will be completely ignored; in the very least, * this is a formalization for deprecating enum values. * * Generated from protobuf field optional bool deprecated = 1 [default = false]; * @param bool $var * @return $this */ public function setDeprecated($var) { GPBUtil::checkBool($var); $this->deprecated = $var; return $this; } /** * Any features defined in the specific edition. * WARNING: This field should only be used by protobuf plugins or special * cases like the proto compiler. Other uses are discouraged and * developers should rely on the protoreflect APIs for their client language. * * Generated from protobuf field optional .google.protobuf.FeatureSet features = 2; * @return \Google\Protobuf\Internal\FeatureSet|null */ public function getFeatures() { return $this->features; } public function hasFeatures() { return isset($this->features); } public function clearFeatures() { unset($this->features); } /** * Any features defined in the specific edition. * WARNING: This field should only be used by protobuf plugins or special * cases like the proto compiler. Other uses are discouraged and * developers should rely on the protoreflect APIs for their client language. * * Generated from protobuf field optional .google.protobuf.FeatureSet features = 2; * @param \Google\Protobuf\Internal\FeatureSet $var * @return $this */ public function setFeatures($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\FeatureSet::class); $this->features = $var; return $this; } /** * Indicate that fields annotated with this enum value should not be printed * out when using debug formats, e.g. when the field contains sensitive * credentials. * * Generated from protobuf field optional bool debug_redact = 3 [default = false]; * @return bool */ public function getDebugRedact() { return isset($this->debug_redact) ? $this->debug_redact : false; } public function hasDebugRedact() { return isset($this->debug_redact); } public function clearDebugRedact() { unset($this->debug_redact); } /** * Indicate that fields annotated with this enum value should not be printed * out when using debug formats, e.g. when the field contains sensitive * credentials. * * Generated from protobuf field optional bool debug_redact = 3 [default = false]; * @param bool $var * @return $this */ public function setDebugRedact($var) { GPBUtil::checkBool($var); $this->debug_redact = $var; return $this; } /** * Information about the support window of a feature value. * * Generated from protobuf field optional .google.protobuf.FieldOptions.FeatureSupport feature_support = 4; * @return \Google\Protobuf\Internal\FieldOptions\FeatureSupport|null */ public function getFeatureSupport() { return $this->feature_support; } public function hasFeatureSupport() { return isset($this->feature_support); } public function clearFeatureSupport() { unset($this->feature_support); } /** * Information about the support window of a feature value. * * Generated from protobuf field optional .google.protobuf.FieldOptions.FeatureSupport feature_support = 4; * @param \Google\Protobuf\Internal\FieldOptions\FeatureSupport $var * @return $this */ public function setFeatureSupport($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\FieldOptions\FeatureSupport::class); $this->feature_support = $var; return $this; } /** * The parser stores options it doesn't recognize here. See above. * * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; * @return RepeatedField<\Google\Protobuf\Internal\UninterpretedOption> */ public function getUninterpretedOption() { return $this->uninterpreted_option; } /** * The parser stores options it doesn't recognize here. See above. * * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; * @param \Google\Protobuf\Internal\UninterpretedOption[] $var * @return $this */ public function setUninterpretedOption($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); $this->uninterpreted_option = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/ExtensionRangeOptions/Declaration.php ================================================ google.protobuf.ExtensionRangeOptions.Declaration */ class Declaration extends \Google\Protobuf\Internal\Message { /** * The extension number declared within the extension range. * * Generated from protobuf field optional int32 number = 1; */ protected $number = null; /** * The fully-qualified name of the extension field. There must be a leading * dot in front of the full name. * * Generated from protobuf field optional string full_name = 2; */ protected $full_name = null; /** * The fully-qualified type name of the extension field. Unlike * Metadata.type, Declaration.type must have a leading dot for messages * and enums. * * Generated from protobuf field optional string type = 3; */ protected $type = null; /** * If true, indicates that the number is reserved in the extension range, * and any extension field with the number will fail to compile. Set this * when a declared extension field is deleted. * * Generated from protobuf field optional bool reserved = 5; */ protected $reserved = null; /** * If true, indicates that the extension must be defined as repeated. * Otherwise the extension must be defined as optional. * * Generated from protobuf field optional bool repeated = 6; */ protected $repeated = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type int $number * The extension number declared within the extension range. * @type string $full_name * The fully-qualified name of the extension field. There must be a leading * dot in front of the full name. * @type string $type * The fully-qualified type name of the extension field. Unlike * Metadata.type, Declaration.type must have a leading dot for messages * and enums. * @type bool $reserved * If true, indicates that the number is reserved in the extension range, * and any extension field with the number will fail to compile. Set this * when a declared extension field is deleted. * @type bool $repeated * If true, indicates that the extension must be defined as repeated. * Otherwise the extension must be defined as optional. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); parent::__construct($data); } /** * The extension number declared within the extension range. * * Generated from protobuf field optional int32 number = 1; * @return int */ public function getNumber() { return isset($this->number) ? $this->number : 0; } public function hasNumber() { return isset($this->number); } public function clearNumber() { unset($this->number); } /** * The extension number declared within the extension range. * * Generated from protobuf field optional int32 number = 1; * @param int $var * @return $this */ public function setNumber($var) { GPBUtil::checkInt32($var); $this->number = $var; return $this; } /** * The fully-qualified name of the extension field. There must be a leading * dot in front of the full name. * * Generated from protobuf field optional string full_name = 2; * @return string */ public function getFullName() { return isset($this->full_name) ? $this->full_name : ''; } public function hasFullName() { return isset($this->full_name); } public function clearFullName() { unset($this->full_name); } /** * The fully-qualified name of the extension field. There must be a leading * dot in front of the full name. * * Generated from protobuf field optional string full_name = 2; * @param string $var * @return $this */ public function setFullName($var) { GPBUtil::checkString($var, True); $this->full_name = $var; return $this; } /** * The fully-qualified type name of the extension field. Unlike * Metadata.type, Declaration.type must have a leading dot for messages * and enums. * * Generated from protobuf field optional string type = 3; * @return string */ public function getType() { return isset($this->type) ? $this->type : ''; } public function hasType() { return isset($this->type); } public function clearType() { unset($this->type); } /** * The fully-qualified type name of the extension field. Unlike * Metadata.type, Declaration.type must have a leading dot for messages * and enums. * * Generated from protobuf field optional string type = 3; * @param string $var * @return $this */ public function setType($var) { GPBUtil::checkString($var, True); $this->type = $var; return $this; } /** * If true, indicates that the number is reserved in the extension range, * and any extension field with the number will fail to compile. Set this * when a declared extension field is deleted. * * Generated from protobuf field optional bool reserved = 5; * @return bool */ public function getReserved() { return isset($this->reserved) ? $this->reserved : false; } public function hasReserved() { return isset($this->reserved); } public function clearReserved() { unset($this->reserved); } /** * If true, indicates that the number is reserved in the extension range, * and any extension field with the number will fail to compile. Set this * when a declared extension field is deleted. * * Generated from protobuf field optional bool reserved = 5; * @param bool $var * @return $this */ public function setReserved($var) { GPBUtil::checkBool($var); $this->reserved = $var; return $this; } /** * If true, indicates that the extension must be defined as repeated. * Otherwise the extension must be defined as optional. * * Generated from protobuf field optional bool repeated = 6; * @return bool */ public function getRepeated() { return isset($this->repeated) ? $this->repeated : false; } public function hasRepeated() { return isset($this->repeated); } public function clearRepeated() { unset($this->repeated); } /** * If true, indicates that the extension must be defined as repeated. * Otherwise the extension must be defined as optional. * * Generated from protobuf field optional bool repeated = 6; * @param bool $var * @return $this */ public function setRepeated($var) { GPBUtil::checkBool($var); $this->repeated = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/ExtensionRangeOptions/VerificationState.php ================================================ google.protobuf.ExtensionRangeOptions.VerificationState */ class VerificationState { /** * All the extensions of the range must be declared. * * Generated from protobuf enum DECLARATION = 0; */ const DECLARATION = 0; /** * Generated from protobuf enum UNVERIFIED = 1; */ const UNVERIFIED = 1; private static $valueToName = [ self::DECLARATION => 'DECLARATION', self::UNVERIFIED => 'UNVERIFIED', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/ExtensionRangeOptions.php ================================================ google.protobuf.ExtensionRangeOptions */ class ExtensionRangeOptions extends \Google\Protobuf\Internal\Message { /** * The parser stores options it doesn't recognize here. See above. * * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; */ private $uninterpreted_option; /** * For external users: DO NOT USE. We are in the process of open sourcing * extension declaration and executing internal cleanups before it can be * used externally. * * Generated from protobuf field repeated .google.protobuf.ExtensionRangeOptions.Declaration declaration = 2 [retention = RETENTION_SOURCE]; */ private $declaration; /** * Any features defined in the specific edition. * * Generated from protobuf field optional .google.protobuf.FeatureSet features = 50; */ protected $features = null; /** * The verification state of the range. * TODO: flip the default to DECLARATION once all empty ranges * are marked as UNVERIFIED. * * Generated from protobuf field optional .google.protobuf.ExtensionRangeOptions.VerificationState verification = 3 [default = UNVERIFIED, retention = RETENTION_SOURCE]; */ protected $verification = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type \Google\Protobuf\Internal\UninterpretedOption[] $uninterpreted_option * The parser stores options it doesn't recognize here. See above. * @type \Google\Protobuf\Internal\ExtensionRangeOptions\Declaration[] $declaration * For external users: DO NOT USE. We are in the process of open sourcing * extension declaration and executing internal cleanups before it can be * used externally. * @type \Google\Protobuf\Internal\FeatureSet $features * Any features defined in the specific edition. * @type int $verification * The verification state of the range. * TODO: flip the default to DECLARATION once all empty ranges * are marked as UNVERIFIED. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); parent::__construct($data); } /** * The parser stores options it doesn't recognize here. See above. * * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; * @return RepeatedField<\Google\Protobuf\Internal\UninterpretedOption> */ public function getUninterpretedOption() { return $this->uninterpreted_option; } /** * The parser stores options it doesn't recognize here. See above. * * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; * @param \Google\Protobuf\Internal\UninterpretedOption[] $var * @return $this */ public function setUninterpretedOption($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); $this->uninterpreted_option = $arr; return $this; } /** * For external users: DO NOT USE. We are in the process of open sourcing * extension declaration and executing internal cleanups before it can be * used externally. * * Generated from protobuf field repeated .google.protobuf.ExtensionRangeOptions.Declaration declaration = 2 [retention = RETENTION_SOURCE]; * @return RepeatedField<\Google\Protobuf\Internal\ExtensionRangeOptions\Declaration> */ public function getDeclaration() { return $this->declaration; } /** * For external users: DO NOT USE. We are in the process of open sourcing * extension declaration and executing internal cleanups before it can be * used externally. * * Generated from protobuf field repeated .google.protobuf.ExtensionRangeOptions.Declaration declaration = 2 [retention = RETENTION_SOURCE]; * @param \Google\Protobuf\Internal\ExtensionRangeOptions\Declaration[] $var * @return $this */ public function setDeclaration($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\ExtensionRangeOptions\Declaration::class); $this->declaration = $arr; return $this; } /** * Any features defined in the specific edition. * * Generated from protobuf field optional .google.protobuf.FeatureSet features = 50; * @return \Google\Protobuf\Internal\FeatureSet|null */ public function getFeatures() { return $this->features; } public function hasFeatures() { return isset($this->features); } public function clearFeatures() { unset($this->features); } /** * Any features defined in the specific edition. * * Generated from protobuf field optional .google.protobuf.FeatureSet features = 50; * @param \Google\Protobuf\Internal\FeatureSet $var * @return $this */ public function setFeatures($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\FeatureSet::class); $this->features = $var; return $this; } /** * The verification state of the range. * TODO: flip the default to DECLARATION once all empty ranges * are marked as UNVERIFIED. * * Generated from protobuf field optional .google.protobuf.ExtensionRangeOptions.VerificationState verification = 3 [default = UNVERIFIED, retention = RETENTION_SOURCE]; * @return int */ public function getVerification() { return isset($this->verification) ? $this->verification : 0; } public function hasVerification() { return isset($this->verification); } public function clearVerification() { unset($this->verification); } /** * The verification state of the range. * TODO: flip the default to DECLARATION once all empty ranges * are marked as UNVERIFIED. * * Generated from protobuf field optional .google.protobuf.ExtensionRangeOptions.VerificationState verification = 3 [default = UNVERIFIED, retention = RETENTION_SOURCE]; * @param int $var * @return $this */ public function setVerification($var) { GPBUtil::checkEnum($var, \Google\Protobuf\Internal\ExtensionRangeOptions\VerificationState::class); $this->verification = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/FeatureSet/EnforceNamingStyle.php ================================================ google.protobuf.FeatureSet.EnforceNamingStyle */ class EnforceNamingStyle { /** * Generated from protobuf enum ENFORCE_NAMING_STYLE_UNKNOWN = 0; */ const ENFORCE_NAMING_STYLE_UNKNOWN = 0; /** * Generated from protobuf enum STYLE2024 = 1; */ const STYLE2024 = 1; /** * Generated from protobuf enum STYLE_LEGACY = 2; */ const STYLE_LEGACY = 2; private static $valueToName = [ self::ENFORCE_NAMING_STYLE_UNKNOWN => 'ENFORCE_NAMING_STYLE_UNKNOWN', self::STYLE2024 => 'STYLE2024', self::STYLE_LEGACY => 'STYLE_LEGACY', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/FeatureSet/EnumType.php ================================================ google.protobuf.FeatureSet.EnumType */ class EnumType { /** * Generated from protobuf enum ENUM_TYPE_UNKNOWN = 0; */ const ENUM_TYPE_UNKNOWN = 0; /** * Generated from protobuf enum OPEN = 1; */ const OPEN = 1; /** * Generated from protobuf enum CLOSED = 2; */ const CLOSED = 2; private static $valueToName = [ self::ENUM_TYPE_UNKNOWN => 'ENUM_TYPE_UNKNOWN', self::OPEN => 'OPEN', self::CLOSED => 'CLOSED', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/FeatureSet/FieldPresence.php ================================================ google.protobuf.FeatureSet.FieldPresence */ class FieldPresence { /** * Generated from protobuf enum FIELD_PRESENCE_UNKNOWN = 0; */ const FIELD_PRESENCE_UNKNOWN = 0; /** * Generated from protobuf enum EXPLICIT = 1; */ const EXPLICIT = 1; /** * Generated from protobuf enum IMPLICIT = 2; */ const IMPLICIT = 2; /** * Generated from protobuf enum LEGACY_REQUIRED = 3; */ const LEGACY_REQUIRED = 3; private static $valueToName = [ self::FIELD_PRESENCE_UNKNOWN => 'FIELD_PRESENCE_UNKNOWN', self::EXPLICIT => 'EXPLICIT', self::IMPLICIT => 'IMPLICIT', self::LEGACY_REQUIRED => 'LEGACY_REQUIRED', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/FeatureSet/JsonFormat.php ================================================ google.protobuf.FeatureSet.JsonFormat */ class JsonFormat { /** * Generated from protobuf enum JSON_FORMAT_UNKNOWN = 0; */ const JSON_FORMAT_UNKNOWN = 0; /** * Generated from protobuf enum ALLOW = 1; */ const ALLOW = 1; /** * Generated from protobuf enum LEGACY_BEST_EFFORT = 2; */ const LEGACY_BEST_EFFORT = 2; private static $valueToName = [ self::JSON_FORMAT_UNKNOWN => 'JSON_FORMAT_UNKNOWN', self::ALLOW => 'ALLOW', self::LEGACY_BEST_EFFORT => 'LEGACY_BEST_EFFORT', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/FeatureSet/MessageEncoding.php ================================================ google.protobuf.FeatureSet.MessageEncoding */ class MessageEncoding { /** * Generated from protobuf enum MESSAGE_ENCODING_UNKNOWN = 0; */ const MESSAGE_ENCODING_UNKNOWN = 0; /** * Generated from protobuf enum LENGTH_PREFIXED = 1; */ const LENGTH_PREFIXED = 1; /** * Generated from protobuf enum DELIMITED = 2; */ const DELIMITED = 2; private static $valueToName = [ self::MESSAGE_ENCODING_UNKNOWN => 'MESSAGE_ENCODING_UNKNOWN', self::LENGTH_PREFIXED => 'LENGTH_PREFIXED', self::DELIMITED => 'DELIMITED', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/FeatureSet/RepeatedFieldEncoding.php ================================================ google.protobuf.FeatureSet.RepeatedFieldEncoding */ class RepeatedFieldEncoding { /** * Generated from protobuf enum REPEATED_FIELD_ENCODING_UNKNOWN = 0; */ const REPEATED_FIELD_ENCODING_UNKNOWN = 0; /** * Generated from protobuf enum PACKED = 1; */ const PACKED = 1; /** * Generated from protobuf enum EXPANDED = 2; */ const EXPANDED = 2; private static $valueToName = [ self::REPEATED_FIELD_ENCODING_UNKNOWN => 'REPEATED_FIELD_ENCODING_UNKNOWN', self::PACKED => 'PACKED', self::EXPANDED => 'EXPANDED', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/FeatureSet/Utf8Validation.php ================================================ google.protobuf.FeatureSet.Utf8Validation */ class Utf8Validation { /** * Generated from protobuf enum UTF8_VALIDATION_UNKNOWN = 0; */ const UTF8_VALIDATION_UNKNOWN = 0; /** * Generated from protobuf enum VERIFY = 2; */ const VERIFY = 2; /** * Generated from protobuf enum NONE = 3; */ const NONE = 3; private static $valueToName = [ self::UTF8_VALIDATION_UNKNOWN => 'UTF8_VALIDATION_UNKNOWN', self::VERIFY => 'VERIFY', self::NONE => 'NONE', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/FeatureSet/VisibilityFeature/DefaultSymbolVisibility.php ================================================ google.protobuf.FeatureSet.VisibilityFeature.DefaultSymbolVisibility */ class DefaultSymbolVisibility { /** * Generated from protobuf enum DEFAULT_SYMBOL_VISIBILITY_UNKNOWN = 0; */ const DEFAULT_SYMBOL_VISIBILITY_UNKNOWN = 0; /** * Default pre-EDITION_2024, all UNSET visibility are export. * * Generated from protobuf enum EXPORT_ALL = 1; */ const EXPORT_ALL = 1; /** * All top-level symbols default to export, nested default to local. * * Generated from protobuf enum EXPORT_TOP_LEVEL = 2; */ const EXPORT_TOP_LEVEL = 2; /** * All symbols default to local. * * Generated from protobuf enum LOCAL_ALL = 3; */ const LOCAL_ALL = 3; /** * All symbols local by default. Nested types cannot be exported. * With special case caveat for message { enum {} reserved 1 to max; } * This is the recommended setting for new protos. * * Generated from protobuf enum STRICT = 4; */ const STRICT = 4; private static $valueToName = [ self::DEFAULT_SYMBOL_VISIBILITY_UNKNOWN => 'DEFAULT_SYMBOL_VISIBILITY_UNKNOWN', self::EXPORT_ALL => 'EXPORT_ALL', self::EXPORT_TOP_LEVEL => 'EXPORT_TOP_LEVEL', self::LOCAL_ALL => 'LOCAL_ALL', self::STRICT => 'STRICT', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/FeatureSet/VisibilityFeature.php ================================================ google.protobuf.FeatureSet.VisibilityFeature */ class VisibilityFeature extends \Google\Protobuf\Internal\Message { /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); parent::__construct($data); } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/FeatureSet.php ================================================ google.protobuf.FeatureSet */ class FeatureSet extends \Google\Protobuf\Internal\Message { /** * Generated from protobuf field optional .google.protobuf.FeatureSet.FieldPresence field_presence = 1 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { */ protected $field_presence = null; /** * Generated from protobuf field optional .google.protobuf.FeatureSet.EnumType enum_type = 2 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_ENUM, targets = TARGET_TYPE_FILE, edition_defaults = { */ protected $enum_type = null; /** * Generated from protobuf field optional .google.protobuf.FeatureSet.RepeatedFieldEncoding repeated_field_encoding = 3 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { */ protected $repeated_field_encoding = null; /** * Generated from protobuf field optional .google.protobuf.FeatureSet.Utf8Validation utf8_validation = 4 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { */ protected $utf8_validation = null; /** * Generated from protobuf field optional .google.protobuf.FeatureSet.MessageEncoding message_encoding = 5 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { */ protected $message_encoding = null; /** * Generated from protobuf field optional .google.protobuf.FeatureSet.JsonFormat json_format = 6 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_MESSAGE, targets = TARGET_TYPE_ENUM, targets = TARGET_TYPE_FILE, edition_defaults = { */ protected $json_format = null; /** * Generated from protobuf field optional .google.protobuf.FeatureSet.EnforceNamingStyle enforce_naming_style = 7 [retention = RETENTION_SOURCE, targets = TARGET_TYPE_FILE, targets = TARGET_TYPE_EXTENSION_RANGE, targets = TARGET_TYPE_MESSAGE, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_ONEOF, targets = TARGET_TYPE_ENUM, targets = TARGET_TYPE_ENUM_ENTRY, targets = TARGET_TYPE_SERVICE, targets = TARGET_TYPE_METHOD, edition_defaults = { */ protected $enforce_naming_style = null; /** * Generated from protobuf field optional .google.protobuf.FeatureSet.VisibilityFeature.DefaultSymbolVisibility default_symbol_visibility = 8 [retention = RETENTION_SOURCE, targets = TARGET_TYPE_FILE, edition_defaults = { */ protected $default_symbol_visibility = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type int $field_presence * @type int $enum_type * @type int $repeated_field_encoding * @type int $utf8_validation * @type int $message_encoding * @type int $json_format * @type int $enforce_naming_style * @type int $default_symbol_visibility * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); parent::__construct($data); } /** * Generated from protobuf field optional .google.protobuf.FeatureSet.FieldPresence field_presence = 1 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { * @return int */ public function getFieldPresence() { return isset($this->field_presence) ? $this->field_presence : 0; } public function hasFieldPresence() { return isset($this->field_presence); } public function clearFieldPresence() { unset($this->field_presence); } /** * Generated from protobuf field optional .google.protobuf.FeatureSet.FieldPresence field_presence = 1 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { * @param int $var * @return $this */ public function setFieldPresence($var) { GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FeatureSet\FieldPresence::class); $this->field_presence = $var; return $this; } /** * Generated from protobuf field optional .google.protobuf.FeatureSet.EnumType enum_type = 2 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_ENUM, targets = TARGET_TYPE_FILE, edition_defaults = { * @return int */ public function getEnumType() { return isset($this->enum_type) ? $this->enum_type : 0; } public function hasEnumType() { return isset($this->enum_type); } public function clearEnumType() { unset($this->enum_type); } /** * Generated from protobuf field optional .google.protobuf.FeatureSet.EnumType enum_type = 2 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_ENUM, targets = TARGET_TYPE_FILE, edition_defaults = { * @param int $var * @return $this */ public function setEnumType($var) { GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FeatureSet\EnumType::class); $this->enum_type = $var; return $this; } /** * Generated from protobuf field optional .google.protobuf.FeatureSet.RepeatedFieldEncoding repeated_field_encoding = 3 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { * @return int */ public function getRepeatedFieldEncoding() { return isset($this->repeated_field_encoding) ? $this->repeated_field_encoding : 0; } public function hasRepeatedFieldEncoding() { return isset($this->repeated_field_encoding); } public function clearRepeatedFieldEncoding() { unset($this->repeated_field_encoding); } /** * Generated from protobuf field optional .google.protobuf.FeatureSet.RepeatedFieldEncoding repeated_field_encoding = 3 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { * @param int $var * @return $this */ public function setRepeatedFieldEncoding($var) { GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FeatureSet\RepeatedFieldEncoding::class); $this->repeated_field_encoding = $var; return $this; } /** * Generated from protobuf field optional .google.protobuf.FeatureSet.Utf8Validation utf8_validation = 4 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { * @return int */ public function getUtf8Validation() { return isset($this->utf8_validation) ? $this->utf8_validation : 0; } public function hasUtf8Validation() { return isset($this->utf8_validation); } public function clearUtf8Validation() { unset($this->utf8_validation); } /** * Generated from protobuf field optional .google.protobuf.FeatureSet.Utf8Validation utf8_validation = 4 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { * @param int $var * @return $this */ public function setUtf8Validation($var) { GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FeatureSet\Utf8Validation::class); $this->utf8_validation = $var; return $this; } /** * Generated from protobuf field optional .google.protobuf.FeatureSet.MessageEncoding message_encoding = 5 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { * @return int */ public function getMessageEncoding() { return isset($this->message_encoding) ? $this->message_encoding : 0; } public function hasMessageEncoding() { return isset($this->message_encoding); } public function clearMessageEncoding() { unset($this->message_encoding); } /** * Generated from protobuf field optional .google.protobuf.FeatureSet.MessageEncoding message_encoding = 5 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_FILE, edition_defaults = { * @param int $var * @return $this */ public function setMessageEncoding($var) { GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FeatureSet\MessageEncoding::class); $this->message_encoding = $var; return $this; } /** * Generated from protobuf field optional .google.protobuf.FeatureSet.JsonFormat json_format = 6 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_MESSAGE, targets = TARGET_TYPE_ENUM, targets = TARGET_TYPE_FILE, edition_defaults = { * @return int */ public function getJsonFormat() { return isset($this->json_format) ? $this->json_format : 0; } public function hasJsonFormat() { return isset($this->json_format); } public function clearJsonFormat() { unset($this->json_format); } /** * Generated from protobuf field optional .google.protobuf.FeatureSet.JsonFormat json_format = 6 [retention = RETENTION_RUNTIME, targets = TARGET_TYPE_MESSAGE, targets = TARGET_TYPE_ENUM, targets = TARGET_TYPE_FILE, edition_defaults = { * @param int $var * @return $this */ public function setJsonFormat($var) { GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FeatureSet\JsonFormat::class); $this->json_format = $var; return $this; } /** * Generated from protobuf field optional .google.protobuf.FeatureSet.EnforceNamingStyle enforce_naming_style = 7 [retention = RETENTION_SOURCE, targets = TARGET_TYPE_FILE, targets = TARGET_TYPE_EXTENSION_RANGE, targets = TARGET_TYPE_MESSAGE, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_ONEOF, targets = TARGET_TYPE_ENUM, targets = TARGET_TYPE_ENUM_ENTRY, targets = TARGET_TYPE_SERVICE, targets = TARGET_TYPE_METHOD, edition_defaults = { * @return int */ public function getEnforceNamingStyle() { return isset($this->enforce_naming_style) ? $this->enforce_naming_style : 0; } public function hasEnforceNamingStyle() { return isset($this->enforce_naming_style); } public function clearEnforceNamingStyle() { unset($this->enforce_naming_style); } /** * Generated from protobuf field optional .google.protobuf.FeatureSet.EnforceNamingStyle enforce_naming_style = 7 [retention = RETENTION_SOURCE, targets = TARGET_TYPE_FILE, targets = TARGET_TYPE_EXTENSION_RANGE, targets = TARGET_TYPE_MESSAGE, targets = TARGET_TYPE_FIELD, targets = TARGET_TYPE_ONEOF, targets = TARGET_TYPE_ENUM, targets = TARGET_TYPE_ENUM_ENTRY, targets = TARGET_TYPE_SERVICE, targets = TARGET_TYPE_METHOD, edition_defaults = { * @param int $var * @return $this */ public function setEnforceNamingStyle($var) { GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FeatureSet\EnforceNamingStyle::class); $this->enforce_naming_style = $var; return $this; } /** * Generated from protobuf field optional .google.protobuf.FeatureSet.VisibilityFeature.DefaultSymbolVisibility default_symbol_visibility = 8 [retention = RETENTION_SOURCE, targets = TARGET_TYPE_FILE, edition_defaults = { * @return int */ public function getDefaultSymbolVisibility() { return isset($this->default_symbol_visibility) ? $this->default_symbol_visibility : 0; } public function hasDefaultSymbolVisibility() { return isset($this->default_symbol_visibility); } public function clearDefaultSymbolVisibility() { unset($this->default_symbol_visibility); } /** * Generated from protobuf field optional .google.protobuf.FeatureSet.VisibilityFeature.DefaultSymbolVisibility default_symbol_visibility = 8 [retention = RETENTION_SOURCE, targets = TARGET_TYPE_FILE, edition_defaults = { * @param int $var * @return $this */ public function setDefaultSymbolVisibility($var) { GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FeatureSet\VisibilityFeature\DefaultSymbolVisibility::class); $this->default_symbol_visibility = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/FeatureSetDefaults/FeatureSetEditionDefault.php ================================================ google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault */ class FeatureSetEditionDefault extends \Google\Protobuf\Internal\Message { /** * Generated from protobuf field optional .google.protobuf.Edition edition = 3; */ protected $edition = null; /** * Defaults of features that can be overridden in this edition. * * Generated from protobuf field optional .google.protobuf.FeatureSet overridable_features = 4; */ protected $overridable_features = null; /** * Defaults of features that can't be overridden in this edition. * * Generated from protobuf field optional .google.protobuf.FeatureSet fixed_features = 5; */ protected $fixed_features = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type int $edition * @type \Google\Protobuf\Internal\FeatureSet $overridable_features * Defaults of features that can be overridden in this edition. * @type \Google\Protobuf\Internal\FeatureSet $fixed_features * Defaults of features that can't be overridden in this edition. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); parent::__construct($data); } /** * Generated from protobuf field optional .google.protobuf.Edition edition = 3; * @return int */ public function getEdition() { return isset($this->edition) ? $this->edition : 0; } public function hasEdition() { return isset($this->edition); } public function clearEdition() { unset($this->edition); } /** * Generated from protobuf field optional .google.protobuf.Edition edition = 3; * @param int $var * @return $this */ public function setEdition($var) { GPBUtil::checkEnum($var, \Google\Protobuf\Internal\Edition::class); $this->edition = $var; return $this; } /** * Defaults of features that can be overridden in this edition. * * Generated from protobuf field optional .google.protobuf.FeatureSet overridable_features = 4; * @return \Google\Protobuf\Internal\FeatureSet|null */ public function getOverridableFeatures() { return $this->overridable_features; } public function hasOverridableFeatures() { return isset($this->overridable_features); } public function clearOverridableFeatures() { unset($this->overridable_features); } /** * Defaults of features that can be overridden in this edition. * * Generated from protobuf field optional .google.protobuf.FeatureSet overridable_features = 4; * @param \Google\Protobuf\Internal\FeatureSet $var * @return $this */ public function setOverridableFeatures($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\FeatureSet::class); $this->overridable_features = $var; return $this; } /** * Defaults of features that can't be overridden in this edition. * * Generated from protobuf field optional .google.protobuf.FeatureSet fixed_features = 5; * @return \Google\Protobuf\Internal\FeatureSet|null */ public function getFixedFeatures() { return $this->fixed_features; } public function hasFixedFeatures() { return isset($this->fixed_features); } public function clearFixedFeatures() { unset($this->fixed_features); } /** * Defaults of features that can't be overridden in this edition. * * Generated from protobuf field optional .google.protobuf.FeatureSet fixed_features = 5; * @param \Google\Protobuf\Internal\FeatureSet $var * @return $this */ public function setFixedFeatures($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\FeatureSet::class); $this->fixed_features = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/FeatureSetDefaults.php ================================================ google.protobuf.FeatureSetDefaults */ class FeatureSetDefaults extends \Google\Protobuf\Internal\Message { /** * Generated from protobuf field repeated .google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault defaults = 1; */ private $defaults; /** * The minimum supported edition (inclusive) when this was constructed. * Editions before this will not have defaults. * * Generated from protobuf field optional .google.protobuf.Edition minimum_edition = 4; */ protected $minimum_edition = null; /** * The maximum known edition (inclusive) when this was constructed. Editions * after this will not have reliable defaults. * * Generated from protobuf field optional .google.protobuf.Edition maximum_edition = 5; */ protected $maximum_edition = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type \Google\Protobuf\Internal\FeatureSetDefaults\FeatureSetEditionDefault[] $defaults * @type int $minimum_edition * The minimum supported edition (inclusive) when this was constructed. * Editions before this will not have defaults. * @type int $maximum_edition * The maximum known edition (inclusive) when this was constructed. Editions * after this will not have reliable defaults. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); parent::__construct($data); } /** * Generated from protobuf field repeated .google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault defaults = 1; * @return RepeatedField<\Google\Protobuf\Internal\FeatureSetDefaults\FeatureSetEditionDefault> */ public function getDefaults() { return $this->defaults; } /** * Generated from protobuf field repeated .google.protobuf.FeatureSetDefaults.FeatureSetEditionDefault defaults = 1; * @param \Google\Protobuf\Internal\FeatureSetDefaults\FeatureSetEditionDefault[] $var * @return $this */ public function setDefaults($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\FeatureSetDefaults\FeatureSetEditionDefault::class); $this->defaults = $arr; return $this; } /** * The minimum supported edition (inclusive) when this was constructed. * Editions before this will not have defaults. * * Generated from protobuf field optional .google.protobuf.Edition minimum_edition = 4; * @return int */ public function getMinimumEdition() { return isset($this->minimum_edition) ? $this->minimum_edition : 0; } public function hasMinimumEdition() { return isset($this->minimum_edition); } public function clearMinimumEdition() { unset($this->minimum_edition); } /** * The minimum supported edition (inclusive) when this was constructed. * Editions before this will not have defaults. * * Generated from protobuf field optional .google.protobuf.Edition minimum_edition = 4; * @param int $var * @return $this */ public function setMinimumEdition($var) { GPBUtil::checkEnum($var, \Google\Protobuf\Internal\Edition::class); $this->minimum_edition = $var; return $this; } /** * The maximum known edition (inclusive) when this was constructed. Editions * after this will not have reliable defaults. * * Generated from protobuf field optional .google.protobuf.Edition maximum_edition = 5; * @return int */ public function getMaximumEdition() { return isset($this->maximum_edition) ? $this->maximum_edition : 0; } public function hasMaximumEdition() { return isset($this->maximum_edition); } public function clearMaximumEdition() { unset($this->maximum_edition); } /** * The maximum known edition (inclusive) when this was constructed. Editions * after this will not have reliable defaults. * * Generated from protobuf field optional .google.protobuf.Edition maximum_edition = 5; * @param int $var * @return $this */ public function setMaximumEdition($var) { GPBUtil::checkEnum($var, \Google\Protobuf\Internal\Edition::class); $this->maximum_edition = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/FieldDescriptor.php ================================================ public_desc = new \Google\Protobuf\FieldDescriptor($this); } public function setOneofIndex($index) { $this->oneof_index = $index; } public function getOneofIndex() { return $this->oneof_index; } public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } public function setJsonName($json_name) { $this->json_name = $json_name; } public function getJsonName() { return $this->json_name; } public function setSetter($setter) { $this->setter = $setter; } public function getSetter() { return $this->setter; } public function setGetter($getter) { $this->getter = $getter; } public function getGetter() { return $this->getter; } public function setNumber($number) { $this->number = $number; } public function getNumber() { return $this->number; } public function setLabel($label) { $this->label = $label; } public function getLabel() { return $this->label; } public function isRequired() { return $this->label === GPBLabel::REQUIRED; } public function isRepeated() { return $this->label === GPBLabel::REPEATED; } public function setType($type) { $this->type = $type; } public function getType() { return $this->type; } public function setMessageType($message_type) { $this->message_type = $message_type; } public function getMessageType() { return $this->message_type; } public function setEnumType($enum_type) { $this->enum_type = $enum_type; } public function getEnumType() { return $this->enum_type; } public function setPacked($packed) { $this->packed = $packed; } public function getPacked() { return $this->packed; } public function getProto3Optional() { return $this->proto3_optional; } public function setProto3Optional($proto3_optional) { $this->proto3_optional = $proto3_optional; } public function getContainingOneof() { return $this->containing_oneof; } public function setContainingOneof($containing_oneof) { $this->containing_oneof = $containing_oneof; } public function getRealContainingOneof() { return !is_null($this->containing_oneof) && !$this->containing_oneof->isSynthetic() ? $this->containing_oneof : null; } public function isPackable() { return $this->isRepeated() && self::isTypePackable($this->type); } public function isMap() { return $this->getType() == GPBType::MESSAGE && !is_null($this->getMessageType()->getOptions()) && $this->getMessageType()->getOptions()->getMapEntry(); } public function isTimestamp() { return $this->getType() == GPBType::MESSAGE && $this->getMessageType()->getClass() === "Google\Protobuf\Timestamp"; } public function isWrapperType() { if ($this->getType() == GPBType::MESSAGE) { $class = $this->getMessageType()->getClass(); return in_array($class, [ "Google\Protobuf\DoubleValue", "Google\Protobuf\FloatValue", "Google\Protobuf\Int64Value", "Google\Protobuf\UInt64Value", "Google\Protobuf\Int32Value", "Google\Protobuf\UInt32Value", "Google\Protobuf\BoolValue", "Google\Protobuf\StringValue", "Google\Protobuf\BytesValue", ]); } return false; } private static function isTypePackable($field_type) { return ($field_type !== GPBType::STRING && $field_type !== GPBType::GROUP && $field_type !== GPBType::MESSAGE && $field_type !== GPBType::BYTES); } /** * @param FieldDescriptorProto $proto * @return FieldDescriptor */ public static function getFieldDescriptor($proto) { $type_name = null; $type = $proto->getType(); switch ($type) { case GPBType::MESSAGE: case GPBType::GROUP: case GPBType::ENUM: $type_name = $proto->getTypeName(); break; default: break; } $oneof_index = $proto->hasOneofIndex() ? $proto->getOneofIndex() : -1; // TODO: once proto2 is supported, this default should be false // for proto2. if ($proto->getLabel() === GPBLabel::REPEATED && $proto->getType() !== GPBType::MESSAGE && $proto->getType() !== GPBType::GROUP && $proto->getType() !== GPBType::STRING && $proto->getType() !== GPBType::BYTES) { $packed = true; } else { $packed = false; } $options = $proto->getOptions(); if ($options !== null) { $packed = $options->getPacked(); } $field = new FieldDescriptor(); $field->setName($proto->getName()); if ($proto->hasJsonName()) { $json_name = $proto->getJsonName(); } else { $proto_name = $proto->getName(); $json_name = implode('', array_map('ucwords', explode('_', $proto_name))); if ($proto_name[0] !== "_" && !ctype_upper($proto_name[0])) { $json_name = lcfirst($json_name); } } $field->setJsonName($json_name); $camel_name = implode('', array_map('ucwords', explode('_', $proto->getName()))); $field->setGetter('get' . $camel_name); $field->setSetter('set' . $camel_name); $field->setType($proto->getType()); $field->setNumber($proto->getNumber()); $field->setLabel($proto->getLabel()); $field->setPacked($packed); $field->setOneofIndex($oneof_index); $field->setProto3Optional($proto->getProto3Optional()); // At this time, the message/enum type may have not been added to pool. // So we use the type name as place holder and will replace it with the // actual descriptor in cross building. switch ($type) { case GPBType::MESSAGE: $field->setMessageType($type_name); break; case GPBType::ENUM: $field->setEnumType($type_name); break; default: break; } return $field; } public static function buildFromProto($proto) { return FieldDescriptor::getFieldDescriptor($proto); } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/FieldDescriptorProto/Label.php ================================================ google.protobuf.FieldDescriptorProto.Label */ class Label { /** * 0 is reserved for errors * * Generated from protobuf enum LABEL_OPTIONAL = 1; */ const LABEL_OPTIONAL = 1; /** * Generated from protobuf enum LABEL_REPEATED = 3; */ const LABEL_REPEATED = 3; /** * The required label is only allowed in google.protobuf. In proto3 and Editions * it's explicitly prohibited. In Editions, the `field_presence` feature * can be used to get this behavior. * * Generated from protobuf enum LABEL_REQUIRED = 2; */ const LABEL_REQUIRED = 2; private static $valueToName = [ self::LABEL_OPTIONAL => 'LABEL_OPTIONAL', self::LABEL_REPEATED => 'LABEL_REPEATED', self::LABEL_REQUIRED => 'LABEL_REQUIRED', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/FieldDescriptorProto/Type.php ================================================ google.protobuf.FieldDescriptorProto.Type */ class Type { /** * 0 is reserved for errors. * Order is weird for historical reasons. * * Generated from protobuf enum TYPE_DOUBLE = 1; */ const TYPE_DOUBLE = 1; /** * Generated from protobuf enum TYPE_FLOAT = 2; */ const TYPE_FLOAT = 2; /** * Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if * negative values are likely. * * Generated from protobuf enum TYPE_INT64 = 3; */ const TYPE_INT64 = 3; /** * Generated from protobuf enum TYPE_UINT64 = 4; */ const TYPE_UINT64 = 4; /** * Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if * negative values are likely. * * Generated from protobuf enum TYPE_INT32 = 5; */ const TYPE_INT32 = 5; /** * Generated from protobuf enum TYPE_FIXED64 = 6; */ const TYPE_FIXED64 = 6; /** * Generated from protobuf enum TYPE_FIXED32 = 7; */ const TYPE_FIXED32 = 7; /** * Generated from protobuf enum TYPE_BOOL = 8; */ const TYPE_BOOL = 8; /** * Generated from protobuf enum TYPE_STRING = 9; */ const TYPE_STRING = 9; /** * Tag-delimited aggregate. * Group type is deprecated and not supported after google.protobuf. However, Proto3 * implementations should still be able to parse the group wire format and * treat group fields as unknown fields. In Editions, the group wire format * can be enabled via the `message_encoding` feature. * * Generated from protobuf enum TYPE_GROUP = 10; */ const TYPE_GROUP = 10; /** * Length-delimited aggregate. * * Generated from protobuf enum TYPE_MESSAGE = 11; */ const TYPE_MESSAGE = 11; /** * New in version 2. * * Generated from protobuf enum TYPE_BYTES = 12; */ const TYPE_BYTES = 12; /** * Generated from protobuf enum TYPE_UINT32 = 13; */ const TYPE_UINT32 = 13; /** * Generated from protobuf enum TYPE_ENUM = 14; */ const TYPE_ENUM = 14; /** * Generated from protobuf enum TYPE_SFIXED32 = 15; */ const TYPE_SFIXED32 = 15; /** * Generated from protobuf enum TYPE_SFIXED64 = 16; */ const TYPE_SFIXED64 = 16; /** * Uses ZigZag encoding. * * Generated from protobuf enum TYPE_SINT32 = 17; */ const TYPE_SINT32 = 17; /** * Uses ZigZag encoding. * * Generated from protobuf enum TYPE_SINT64 = 18; */ const TYPE_SINT64 = 18; private static $valueToName = [ self::TYPE_DOUBLE => 'TYPE_DOUBLE', self::TYPE_FLOAT => 'TYPE_FLOAT', self::TYPE_INT64 => 'TYPE_INT64', self::TYPE_UINT64 => 'TYPE_UINT64', self::TYPE_INT32 => 'TYPE_INT32', self::TYPE_FIXED64 => 'TYPE_FIXED64', self::TYPE_FIXED32 => 'TYPE_FIXED32', self::TYPE_BOOL => 'TYPE_BOOL', self::TYPE_STRING => 'TYPE_STRING', self::TYPE_GROUP => 'TYPE_GROUP', self::TYPE_MESSAGE => 'TYPE_MESSAGE', self::TYPE_BYTES => 'TYPE_BYTES', self::TYPE_UINT32 => 'TYPE_UINT32', self::TYPE_ENUM => 'TYPE_ENUM', self::TYPE_SFIXED32 => 'TYPE_SFIXED32', self::TYPE_SFIXED64 => 'TYPE_SFIXED64', self::TYPE_SINT32 => 'TYPE_SINT32', self::TYPE_SINT64 => 'TYPE_SINT64', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/FieldDescriptorProto.php ================================================ google.protobuf.FieldDescriptorProto */ class FieldDescriptorProto extends \Google\Protobuf\Internal\Message { /** * Generated from protobuf field optional string name = 1; */ protected $name = null; /** * Generated from protobuf field optional int32 number = 3; */ protected $number = null; /** * Generated from protobuf field optional .google.protobuf.FieldDescriptorProto.Label label = 4; */ protected $label = null; /** * If type_name is set, this need not be set. If both this and type_name * are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP. * * Generated from protobuf field optional .google.protobuf.FieldDescriptorProto.Type type = 5; */ protected $type = null; /** * For message and enum types, this is the name of the type. If the name * starts with a '.', it is fully-qualified. Otherwise, C++-like scoping * rules are used to find the type (i.e. first the nested types within this * message are searched, then within the parent, on up to the root * namespace). * * Generated from protobuf field optional string type_name = 6; */ protected $type_name = null; /** * For extensions, this is the name of the type being extended. It is * resolved in the same manner as type_name. * * Generated from protobuf field optional string extendee = 2; */ protected $extendee = null; /** * For numeric types, contains the original text representation of the value. * For booleans, "true" or "false". * For strings, contains the default text contents (not escaped in any way). * For bytes, contains the C escaped value. All bytes >= 128 are escaped. * * Generated from protobuf field optional string default_value = 7; */ protected $default_value = null; /** * If set, gives the index of a oneof in the containing type's oneof_decl * list. This field is a member of that oneof. * * Generated from protobuf field optional int32 oneof_index = 9; */ protected $oneof_index = null; /** * JSON name of this field. The value is set by protocol compiler. If the * user has set a "json_name" option on this field, that option's value * will be used. Otherwise, it's deduced from the field's name by converting * it to camelCase. * * Generated from protobuf field optional string json_name = 10; */ protected $json_name = null; /** * Generated from protobuf field optional .google.protobuf.FieldOptions options = 8; */ protected $options = null; /** * If true, this is a proto3 "optional". When a proto3 field is optional, it * tracks presence regardless of field type. * When proto3_optional is true, this field must belong to a oneof to signal * to old proto3 clients that presence is tracked for this field. This oneof * is known as a "synthetic" oneof, and this field must be its sole member * (each proto3 optional field gets its own synthetic oneof). Synthetic oneofs * exist in the descriptor only, and do not generate any API. Synthetic oneofs * must be ordered after all "real" oneofs. * For message fields, proto3_optional doesn't create any semantic change, * since non-repeated message fields always track presence. However it still * indicates the semantic detail of whether the user wrote "optional" or not. * This can be useful for round-tripping the .proto file. For consistency we * give message fields a synthetic oneof also, even though it is not required * to track presence. This is especially important because the parser can't * tell if a field is a message or an enum, so it must always create a * synthetic oneof. * Proto2 optional fields do not set this flag, because they already indicate * optional with `LABEL_OPTIONAL`. * * Generated from protobuf field optional bool proto3_optional = 17; */ protected $proto3_optional = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $name * @type int $number * @type int $label * @type int $type * If type_name is set, this need not be set. If both this and type_name * are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP. * @type string $type_name * For message and enum types, this is the name of the type. If the name * starts with a '.', it is fully-qualified. Otherwise, C++-like scoping * rules are used to find the type (i.e. first the nested types within this * message are searched, then within the parent, on up to the root * namespace). * @type string $extendee * For extensions, this is the name of the type being extended. It is * resolved in the same manner as type_name. * @type string $default_value * For numeric types, contains the original text representation of the value. * For booleans, "true" or "false". * For strings, contains the default text contents (not escaped in any way). * For bytes, contains the C escaped value. All bytes >= 128 are escaped. * @type int $oneof_index * If set, gives the index of a oneof in the containing type's oneof_decl * list. This field is a member of that oneof. * @type string $json_name * JSON name of this field. The value is set by protocol compiler. If the * user has set a "json_name" option on this field, that option's value * will be used. Otherwise, it's deduced from the field's name by converting * it to camelCase. * @type \Google\Protobuf\Internal\FieldOptions $options * @type bool $proto3_optional * If true, this is a proto3 "optional". When a proto3 field is optional, it * tracks presence regardless of field type. * When proto3_optional is true, this field must belong to a oneof to signal * to old proto3 clients that presence is tracked for this field. This oneof * is known as a "synthetic" oneof, and this field must be its sole member * (each proto3 optional field gets its own synthetic oneof). Synthetic oneofs * exist in the descriptor only, and do not generate any API. Synthetic oneofs * must be ordered after all "real" oneofs. * For message fields, proto3_optional doesn't create any semantic change, * since non-repeated message fields always track presence. However it still * indicates the semantic detail of whether the user wrote "optional" or not. * This can be useful for round-tripping the .proto file. For consistency we * give message fields a synthetic oneof also, even though it is not required * to track presence. This is especially important because the parser can't * tell if a field is a message or an enum, so it must always create a * synthetic oneof. * Proto2 optional fields do not set this flag, because they already indicate * optional with `LABEL_OPTIONAL`. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); parent::__construct($data); } /** * Generated from protobuf field optional string name = 1; * @return string */ public function getName() { return isset($this->name) ? $this->name : ''; } public function hasName() { return isset($this->name); } public function clearName() { unset($this->name); } /** * Generated from protobuf field optional string name = 1; * @param string $var * @return $this */ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; return $this; } /** * Generated from protobuf field optional int32 number = 3; * @return int */ public function getNumber() { return isset($this->number) ? $this->number : 0; } public function hasNumber() { return isset($this->number); } public function clearNumber() { unset($this->number); } /** * Generated from protobuf field optional int32 number = 3; * @param int $var * @return $this */ public function setNumber($var) { GPBUtil::checkInt32($var); $this->number = $var; return $this; } /** * Generated from protobuf field optional .google.protobuf.FieldDescriptorProto.Label label = 4; * @return int */ public function getLabel() { return isset($this->label) ? $this->label : 0; } public function hasLabel() { return isset($this->label); } public function clearLabel() { unset($this->label); } /** * Generated from protobuf field optional .google.protobuf.FieldDescriptorProto.Label label = 4; * @param int $var * @return $this */ public function setLabel($var) { GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FieldDescriptorProto\Label::class); $this->label = $var; return $this; } /** * If type_name is set, this need not be set. If both this and type_name * are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP. * * Generated from protobuf field optional .google.protobuf.FieldDescriptorProto.Type type = 5; * @return int */ public function getType() { return isset($this->type) ? $this->type : 0; } public function hasType() { return isset($this->type); } public function clearType() { unset($this->type); } /** * If type_name is set, this need not be set. If both this and type_name * are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP. * * Generated from protobuf field optional .google.protobuf.FieldDescriptorProto.Type type = 5; * @param int $var * @return $this */ public function setType($var) { GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FieldDescriptorProto\Type::class); $this->type = $var; return $this; } /** * For message and enum types, this is the name of the type. If the name * starts with a '.', it is fully-qualified. Otherwise, C++-like scoping * rules are used to find the type (i.e. first the nested types within this * message are searched, then within the parent, on up to the root * namespace). * * Generated from protobuf field optional string type_name = 6; * @return string */ public function getTypeName() { return isset($this->type_name) ? $this->type_name : ''; } public function hasTypeName() { return isset($this->type_name); } public function clearTypeName() { unset($this->type_name); } /** * For message and enum types, this is the name of the type. If the name * starts with a '.', it is fully-qualified. Otherwise, C++-like scoping * rules are used to find the type (i.e. first the nested types within this * message are searched, then within the parent, on up to the root * namespace). * * Generated from protobuf field optional string type_name = 6; * @param string $var * @return $this */ public function setTypeName($var) { GPBUtil::checkString($var, True); $this->type_name = $var; return $this; } /** * For extensions, this is the name of the type being extended. It is * resolved in the same manner as type_name. * * Generated from protobuf field optional string extendee = 2; * @return string */ public function getExtendee() { return isset($this->extendee) ? $this->extendee : ''; } public function hasExtendee() { return isset($this->extendee); } public function clearExtendee() { unset($this->extendee); } /** * For extensions, this is the name of the type being extended. It is * resolved in the same manner as type_name. * * Generated from protobuf field optional string extendee = 2; * @param string $var * @return $this */ public function setExtendee($var) { GPBUtil::checkString($var, True); $this->extendee = $var; return $this; } /** * For numeric types, contains the original text representation of the value. * For booleans, "true" or "false". * For strings, contains the default text contents (not escaped in any way). * For bytes, contains the C escaped value. All bytes >= 128 are escaped. * * Generated from protobuf field optional string default_value = 7; * @return string */ public function getDefaultValue() { return isset($this->default_value) ? $this->default_value : ''; } public function hasDefaultValue() { return isset($this->default_value); } public function clearDefaultValue() { unset($this->default_value); } /** * For numeric types, contains the original text representation of the value. * For booleans, "true" or "false". * For strings, contains the default text contents (not escaped in any way). * For bytes, contains the C escaped value. All bytes >= 128 are escaped. * * Generated from protobuf field optional string default_value = 7; * @param string $var * @return $this */ public function setDefaultValue($var) { GPBUtil::checkString($var, True); $this->default_value = $var; return $this; } /** * If set, gives the index of a oneof in the containing type's oneof_decl * list. This field is a member of that oneof. * * Generated from protobuf field optional int32 oneof_index = 9; * @return int */ public function getOneofIndex() { return isset($this->oneof_index) ? $this->oneof_index : 0; } public function hasOneofIndex() { return isset($this->oneof_index); } public function clearOneofIndex() { unset($this->oneof_index); } /** * If set, gives the index of a oneof in the containing type's oneof_decl * list. This field is a member of that oneof. * * Generated from protobuf field optional int32 oneof_index = 9; * @param int $var * @return $this */ public function setOneofIndex($var) { GPBUtil::checkInt32($var); $this->oneof_index = $var; return $this; } /** * JSON name of this field. The value is set by protocol compiler. If the * user has set a "json_name" option on this field, that option's value * will be used. Otherwise, it's deduced from the field's name by converting * it to camelCase. * * Generated from protobuf field optional string json_name = 10; * @return string */ public function getJsonName() { return isset($this->json_name) ? $this->json_name : ''; } public function hasJsonName() { return isset($this->json_name); } public function clearJsonName() { unset($this->json_name); } /** * JSON name of this field. The value is set by protocol compiler. If the * user has set a "json_name" option on this field, that option's value * will be used. Otherwise, it's deduced from the field's name by converting * it to camelCase. * * Generated from protobuf field optional string json_name = 10; * @param string $var * @return $this */ public function setJsonName($var) { GPBUtil::checkString($var, True); $this->json_name = $var; return $this; } /** * Generated from protobuf field optional .google.protobuf.FieldOptions options = 8; * @return \Google\Protobuf\Internal\FieldOptions|null */ public function getOptions() { return $this->options; } public function hasOptions() { return isset($this->options); } public function clearOptions() { unset($this->options); } /** * Generated from protobuf field optional .google.protobuf.FieldOptions options = 8; * @param \Google\Protobuf\Internal\FieldOptions $var * @return $this */ public function setOptions($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\FieldOptions::class); $this->options = $var; return $this; } /** * If true, this is a proto3 "optional". When a proto3 field is optional, it * tracks presence regardless of field type. * When proto3_optional is true, this field must belong to a oneof to signal * to old proto3 clients that presence is tracked for this field. This oneof * is known as a "synthetic" oneof, and this field must be its sole member * (each proto3 optional field gets its own synthetic oneof). Synthetic oneofs * exist in the descriptor only, and do not generate any API. Synthetic oneofs * must be ordered after all "real" oneofs. * For message fields, proto3_optional doesn't create any semantic change, * since non-repeated message fields always track presence. However it still * indicates the semantic detail of whether the user wrote "optional" or not. * This can be useful for round-tripping the .proto file. For consistency we * give message fields a synthetic oneof also, even though it is not required * to track presence. This is especially important because the parser can't * tell if a field is a message or an enum, so it must always create a * synthetic oneof. * Proto2 optional fields do not set this flag, because they already indicate * optional with `LABEL_OPTIONAL`. * * Generated from protobuf field optional bool proto3_optional = 17; * @return bool */ public function getProto3Optional() { return isset($this->proto3_optional) ? $this->proto3_optional : false; } public function hasProto3Optional() { return isset($this->proto3_optional); } public function clearProto3Optional() { unset($this->proto3_optional); } /** * If true, this is a proto3 "optional". When a proto3 field is optional, it * tracks presence regardless of field type. * When proto3_optional is true, this field must belong to a oneof to signal * to old proto3 clients that presence is tracked for this field. This oneof * is known as a "synthetic" oneof, and this field must be its sole member * (each proto3 optional field gets its own synthetic oneof). Synthetic oneofs * exist in the descriptor only, and do not generate any API. Synthetic oneofs * must be ordered after all "real" oneofs. * For message fields, proto3_optional doesn't create any semantic change, * since non-repeated message fields always track presence. However it still * indicates the semantic detail of whether the user wrote "optional" or not. * This can be useful for round-tripping the .proto file. For consistency we * give message fields a synthetic oneof also, even though it is not required * to track presence. This is especially important because the parser can't * tell if a field is a message or an enum, so it must always create a * synthetic oneof. * Proto2 optional fields do not set this flag, because they already indicate * optional with `LABEL_OPTIONAL`. * * Generated from protobuf field optional bool proto3_optional = 17; * @param bool $var * @return $this */ public function setProto3Optional($var) { GPBUtil::checkBool($var); $this->proto3_optional = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/FieldOptions/CType.php ================================================ google.protobuf.FieldOptions.CType */ class CType { /** * Default mode. * * Generated from protobuf enum STRING = 0; */ const STRING = 0; /** * The option [ctype=CORD] may be applied to a non-repeated field of type * "bytes". It indicates that in C++, the data should be stored in a Cord * instead of a string. For very large strings, this may reduce memory * fragmentation. It may also allow better performance when parsing from a * Cord, or when parsing with aliasing enabled, as the parsed Cord may then * alias the original buffer. * * Generated from protobuf enum CORD = 1; */ const CORD = 1; /** * Generated from protobuf enum STRING_PIECE = 2; */ const STRING_PIECE = 2; private static $valueToName = [ self::STRING => 'STRING', self::CORD => 'CORD', self::STRING_PIECE => 'STRING_PIECE', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/FieldOptions/EditionDefault.php ================================================ google.protobuf.FieldOptions.EditionDefault */ class EditionDefault extends \Google\Protobuf\Internal\Message { /** * Generated from protobuf field optional .google.protobuf.Edition edition = 3; */ protected $edition = null; /** * Textproto value. * * Generated from protobuf field optional string value = 2; */ protected $value = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type int $edition * @type string $value * Textproto value. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); parent::__construct($data); } /** * Generated from protobuf field optional .google.protobuf.Edition edition = 3; * @return int */ public function getEdition() { return isset($this->edition) ? $this->edition : 0; } public function hasEdition() { return isset($this->edition); } public function clearEdition() { unset($this->edition); } /** * Generated from protobuf field optional .google.protobuf.Edition edition = 3; * @param int $var * @return $this */ public function setEdition($var) { GPBUtil::checkEnum($var, \Google\Protobuf\Internal\Edition::class); $this->edition = $var; return $this; } /** * Textproto value. * * Generated from protobuf field optional string value = 2; * @return string */ public function getValue() { return isset($this->value) ? $this->value : ''; } public function hasValue() { return isset($this->value); } public function clearValue() { unset($this->value); } /** * Textproto value. * * Generated from protobuf field optional string value = 2; * @param string $var * @return $this */ public function setValue($var) { GPBUtil::checkString($var, True); $this->value = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/FieldOptions/FeatureSupport.php ================================================ google.protobuf.FieldOptions.FeatureSupport */ class FeatureSupport extends \Google\Protobuf\Internal\Message { /** * The edition that this feature was first available in. In editions * earlier than this one, the default assigned to EDITION_LEGACY will be * used, and proto files will not be able to override it. * * Generated from protobuf field optional .google.protobuf.Edition edition_introduced = 1; */ protected $edition_introduced = null; /** * The edition this feature becomes deprecated in. Using this after this * edition may trigger warnings. * * Generated from protobuf field optional .google.protobuf.Edition edition_deprecated = 2; */ protected $edition_deprecated = null; /** * The deprecation warning text if this feature is used after the edition it * was marked deprecated in. * * Generated from protobuf field optional string deprecation_warning = 3; */ protected $deprecation_warning = null; /** * The edition this feature is no longer available in. In editions after * this one, the last default assigned will be used, and proto files will * not be able to override it. * * Generated from protobuf field optional .google.protobuf.Edition edition_removed = 4; */ protected $edition_removed = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type int $edition_introduced * The edition that this feature was first available in. In editions * earlier than this one, the default assigned to EDITION_LEGACY will be * used, and proto files will not be able to override it. * @type int $edition_deprecated * The edition this feature becomes deprecated in. Using this after this * edition may trigger warnings. * @type string $deprecation_warning * The deprecation warning text if this feature is used after the edition it * was marked deprecated in. * @type int $edition_removed * The edition this feature is no longer available in. In editions after * this one, the last default assigned will be used, and proto files will * not be able to override it. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); parent::__construct($data); } /** * The edition that this feature was first available in. In editions * earlier than this one, the default assigned to EDITION_LEGACY will be * used, and proto files will not be able to override it. * * Generated from protobuf field optional .google.protobuf.Edition edition_introduced = 1; * @return int */ public function getEditionIntroduced() { return isset($this->edition_introduced) ? $this->edition_introduced : 0; } public function hasEditionIntroduced() { return isset($this->edition_introduced); } public function clearEditionIntroduced() { unset($this->edition_introduced); } /** * The edition that this feature was first available in. In editions * earlier than this one, the default assigned to EDITION_LEGACY will be * used, and proto files will not be able to override it. * * Generated from protobuf field optional .google.protobuf.Edition edition_introduced = 1; * @param int $var * @return $this */ public function setEditionIntroduced($var) { GPBUtil::checkEnum($var, \Google\Protobuf\Internal\Edition::class); $this->edition_introduced = $var; return $this; } /** * The edition this feature becomes deprecated in. Using this after this * edition may trigger warnings. * * Generated from protobuf field optional .google.protobuf.Edition edition_deprecated = 2; * @return int */ public function getEditionDeprecated() { return isset($this->edition_deprecated) ? $this->edition_deprecated : 0; } public function hasEditionDeprecated() { return isset($this->edition_deprecated); } public function clearEditionDeprecated() { unset($this->edition_deprecated); } /** * The edition this feature becomes deprecated in. Using this after this * edition may trigger warnings. * * Generated from protobuf field optional .google.protobuf.Edition edition_deprecated = 2; * @param int $var * @return $this */ public function setEditionDeprecated($var) { GPBUtil::checkEnum($var, \Google\Protobuf\Internal\Edition::class); $this->edition_deprecated = $var; return $this; } /** * The deprecation warning text if this feature is used after the edition it * was marked deprecated in. * * Generated from protobuf field optional string deprecation_warning = 3; * @return string */ public function getDeprecationWarning() { return isset($this->deprecation_warning) ? $this->deprecation_warning : ''; } public function hasDeprecationWarning() { return isset($this->deprecation_warning); } public function clearDeprecationWarning() { unset($this->deprecation_warning); } /** * The deprecation warning text if this feature is used after the edition it * was marked deprecated in. * * Generated from protobuf field optional string deprecation_warning = 3; * @param string $var * @return $this */ public function setDeprecationWarning($var) { GPBUtil::checkString($var, True); $this->deprecation_warning = $var; return $this; } /** * The edition this feature is no longer available in. In editions after * this one, the last default assigned will be used, and proto files will * not be able to override it. * * Generated from protobuf field optional .google.protobuf.Edition edition_removed = 4; * @return int */ public function getEditionRemoved() { return isset($this->edition_removed) ? $this->edition_removed : 0; } public function hasEditionRemoved() { return isset($this->edition_removed); } public function clearEditionRemoved() { unset($this->edition_removed); } /** * The edition this feature is no longer available in. In editions after * this one, the last default assigned will be used, and proto files will * not be able to override it. * * Generated from protobuf field optional .google.protobuf.Edition edition_removed = 4; * @param int $var * @return $this */ public function setEditionRemoved($var) { GPBUtil::checkEnum($var, \Google\Protobuf\Internal\Edition::class); $this->edition_removed = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/FieldOptions/JSType.php ================================================ google.protobuf.FieldOptions.JSType */ class JSType { /** * Use the default type. * * Generated from protobuf enum JS_NORMAL = 0; */ const JS_NORMAL = 0; /** * Use JavaScript strings. * * Generated from protobuf enum JS_STRING = 1; */ const JS_STRING = 1; /** * Use JavaScript numbers. * * Generated from protobuf enum JS_NUMBER = 2; */ const JS_NUMBER = 2; private static $valueToName = [ self::JS_NORMAL => 'JS_NORMAL', self::JS_STRING => 'JS_STRING', self::JS_NUMBER => 'JS_NUMBER', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/FieldOptions/OptionRetention.php ================================================ google.protobuf.FieldOptions.OptionRetention */ class OptionRetention { /** * Generated from protobuf enum RETENTION_UNKNOWN = 0; */ const RETENTION_UNKNOWN = 0; /** * Generated from protobuf enum RETENTION_RUNTIME = 1; */ const RETENTION_RUNTIME = 1; /** * Generated from protobuf enum RETENTION_SOURCE = 2; */ const RETENTION_SOURCE = 2; private static $valueToName = [ self::RETENTION_UNKNOWN => 'RETENTION_UNKNOWN', self::RETENTION_RUNTIME => 'RETENTION_RUNTIME', self::RETENTION_SOURCE => 'RETENTION_SOURCE', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/FieldOptions/OptionTargetType.php ================================================ google.protobuf.FieldOptions.OptionTargetType */ class OptionTargetType { /** * Generated from protobuf enum TARGET_TYPE_UNKNOWN = 0; */ const TARGET_TYPE_UNKNOWN = 0; /** * Generated from protobuf enum TARGET_TYPE_FILE = 1; */ const TARGET_TYPE_FILE = 1; /** * Generated from protobuf enum TARGET_TYPE_EXTENSION_RANGE = 2; */ const TARGET_TYPE_EXTENSION_RANGE = 2; /** * Generated from protobuf enum TARGET_TYPE_MESSAGE = 3; */ const TARGET_TYPE_MESSAGE = 3; /** * Generated from protobuf enum TARGET_TYPE_FIELD = 4; */ const TARGET_TYPE_FIELD = 4; /** * Generated from protobuf enum TARGET_TYPE_ONEOF = 5; */ const TARGET_TYPE_ONEOF = 5; /** * Generated from protobuf enum TARGET_TYPE_ENUM = 6; */ const TARGET_TYPE_ENUM = 6; /** * Generated from protobuf enum TARGET_TYPE_ENUM_ENTRY = 7; */ const TARGET_TYPE_ENUM_ENTRY = 7; /** * Generated from protobuf enum TARGET_TYPE_SERVICE = 8; */ const TARGET_TYPE_SERVICE = 8; /** * Generated from protobuf enum TARGET_TYPE_METHOD = 9; */ const TARGET_TYPE_METHOD = 9; private static $valueToName = [ self::TARGET_TYPE_UNKNOWN => 'TARGET_TYPE_UNKNOWN', self::TARGET_TYPE_FILE => 'TARGET_TYPE_FILE', self::TARGET_TYPE_EXTENSION_RANGE => 'TARGET_TYPE_EXTENSION_RANGE', self::TARGET_TYPE_MESSAGE => 'TARGET_TYPE_MESSAGE', self::TARGET_TYPE_FIELD => 'TARGET_TYPE_FIELD', self::TARGET_TYPE_ONEOF => 'TARGET_TYPE_ONEOF', self::TARGET_TYPE_ENUM => 'TARGET_TYPE_ENUM', self::TARGET_TYPE_ENUM_ENTRY => 'TARGET_TYPE_ENUM_ENTRY', self::TARGET_TYPE_SERVICE => 'TARGET_TYPE_SERVICE', self::TARGET_TYPE_METHOD => 'TARGET_TYPE_METHOD', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/FieldOptions.php ================================================ google.protobuf.FieldOptions */ class FieldOptions extends \Google\Protobuf\Internal\Message { /** * NOTE: ctype is deprecated. Use `features.(pb.cpp).string_type` instead. * The ctype option instructs the C++ code generator to use a different * representation of the field than it normally would. See the specific * options below. This option is only implemented to support use of * [ctype=CORD] and [ctype=STRING] (the default) on non-repeated fields of * type "bytes" in the open source release. * TODO: make ctype actually deprecated. * * Generated from protobuf field optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING]; */ protected $ctype = null; /** * The packed option can be enabled for repeated primitive fields to enable * a more efficient representation on the wire. Rather than repeatedly * writing the tag and type for each element, the entire array is encoded as * a single length-delimited blob. In proto3, only explicit setting it to * false will avoid using packed encoding. This option is prohibited in * Editions, but the `repeated_field_encoding` feature can be used to control * the behavior. * * Generated from protobuf field optional bool packed = 2; */ protected $packed = null; /** * The jstype option determines the JavaScript type used for values of the * field. The option is permitted only for 64 bit integral and fixed types * (int64, uint64, sint64, fixed64, sfixed64). A field with jstype JS_STRING * is represented as JavaScript string, which avoids loss of precision that * can happen when a large value is converted to a floating point JavaScript. * Specifying JS_NUMBER for the jstype causes the generated JavaScript code to * use the JavaScript "number" type. The behavior of the default option * JS_NORMAL is implementation dependent. * This option is an enum to permit additional types to be added, e.g. * goog.math.Integer. * * Generated from protobuf field optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL]; */ protected $jstype = null; /** * Should this field be parsed lazily? Lazy applies only to message-type * fields. It means that when the outer message is initially parsed, the * inner message's contents will not be parsed but instead stored in encoded * form. The inner message will actually be parsed when it is first accessed. * This is only a hint. Implementations are free to choose whether to use * eager or lazy parsing regardless of the value of this option. However, * setting this option true suggests that the protocol author believes that * using lazy parsing on this field is worth the additional bookkeeping * overhead typically needed to implement it. * This option does not affect the public interface of any generated code; * all method signatures remain the same. Furthermore, thread-safety of the * interface is not affected by this option; const methods remain safe to * call from multiple threads concurrently, while non-const methods continue * to require exclusive access. * Note that lazy message fields are still eagerly verified to check * ill-formed wireformat or missing required fields. Calling IsInitialized() * on the outer message would fail if the inner message has missing required * fields. Failed verification would result in parsing failure (except when * uninitialized messages are acceptable). * * Generated from protobuf field optional bool lazy = 5 [default = false]; */ protected $lazy = null; /** * unverified_lazy does no correctness checks on the byte stream. This should * only be used where lazy with verification is prohibitive for performance * reasons. * * Generated from protobuf field optional bool unverified_lazy = 15 [default = false]; */ protected $unverified_lazy = null; /** * Is this field deprecated? * Depending on the target platform, this can emit Deprecated annotations * for accessors, or it will be completely ignored; in the very least, this * is a formalization for deprecating fields. * * Generated from protobuf field optional bool deprecated = 3 [default = false]; */ protected $deprecated = null; /** * DEPRECATED. DO NOT USE! * For Google-internal migration only. Do not use. * * Generated from protobuf field optional bool weak = 10 [default = false, deprecated = true]; * @deprecated */ protected $weak = null; /** * Indicate that the field value should not be printed out when using debug * formats, e.g. when the field contains sensitive credentials. * * Generated from protobuf field optional bool debug_redact = 16 [default = false]; */ protected $debug_redact = null; /** * Generated from protobuf field optional .google.protobuf.FieldOptions.OptionRetention retention = 17; */ protected $retention = null; /** * Generated from protobuf field repeated .google.protobuf.FieldOptions.OptionTargetType targets = 19; */ private $targets; /** * Generated from protobuf field repeated .google.protobuf.FieldOptions.EditionDefault edition_defaults = 20; */ private $edition_defaults; /** * Any features defined in the specific edition. * WARNING: This field should only be used by protobuf plugins or special * cases like the proto compiler. Other uses are discouraged and * developers should rely on the protoreflect APIs for their client language. * * Generated from protobuf field optional .google.protobuf.FeatureSet features = 21; */ protected $features = null; /** * Generated from protobuf field optional .google.protobuf.FieldOptions.FeatureSupport feature_support = 22; */ protected $feature_support = null; /** * The parser stores options it doesn't recognize here. See above. * * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; */ private $uninterpreted_option; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type int $ctype * NOTE: ctype is deprecated. Use `features.(pb.cpp).string_type` instead. * The ctype option instructs the C++ code generator to use a different * representation of the field than it normally would. See the specific * options below. This option is only implemented to support use of * [ctype=CORD] and [ctype=STRING] (the default) on non-repeated fields of * type "bytes" in the open source release. * TODO: make ctype actually deprecated. * @type bool $packed * The packed option can be enabled for repeated primitive fields to enable * a more efficient representation on the wire. Rather than repeatedly * writing the tag and type for each element, the entire array is encoded as * a single length-delimited blob. In proto3, only explicit setting it to * false will avoid using packed encoding. This option is prohibited in * Editions, but the `repeated_field_encoding` feature can be used to control * the behavior. * @type int $jstype * The jstype option determines the JavaScript type used for values of the * field. The option is permitted only for 64 bit integral and fixed types * (int64, uint64, sint64, fixed64, sfixed64). A field with jstype JS_STRING * is represented as JavaScript string, which avoids loss of precision that * can happen when a large value is converted to a floating point JavaScript. * Specifying JS_NUMBER for the jstype causes the generated JavaScript code to * use the JavaScript "number" type. The behavior of the default option * JS_NORMAL is implementation dependent. * This option is an enum to permit additional types to be added, e.g. * goog.math.Integer. * @type bool $lazy * Should this field be parsed lazily? Lazy applies only to message-type * fields. It means that when the outer message is initially parsed, the * inner message's contents will not be parsed but instead stored in encoded * form. The inner message will actually be parsed when it is first accessed. * This is only a hint. Implementations are free to choose whether to use * eager or lazy parsing regardless of the value of this option. However, * setting this option true suggests that the protocol author believes that * using lazy parsing on this field is worth the additional bookkeeping * overhead typically needed to implement it. * This option does not affect the public interface of any generated code; * all method signatures remain the same. Furthermore, thread-safety of the * interface is not affected by this option; const methods remain safe to * call from multiple threads concurrently, while non-const methods continue * to require exclusive access. * Note that lazy message fields are still eagerly verified to check * ill-formed wireformat or missing required fields. Calling IsInitialized() * on the outer message would fail if the inner message has missing required * fields. Failed verification would result in parsing failure (except when * uninitialized messages are acceptable). * @type bool $unverified_lazy * unverified_lazy does no correctness checks on the byte stream. This should * only be used where lazy with verification is prohibitive for performance * reasons. * @type bool $deprecated * Is this field deprecated? * Depending on the target platform, this can emit Deprecated annotations * for accessors, or it will be completely ignored; in the very least, this * is a formalization for deprecating fields. * @type bool $weak * DEPRECATED. DO NOT USE! * For Google-internal migration only. Do not use. * @type bool $debug_redact * Indicate that the field value should not be printed out when using debug * formats, e.g. when the field contains sensitive credentials. * @type int $retention * @type int[] $targets * @type \Google\Protobuf\Internal\FieldOptions\EditionDefault[] $edition_defaults * @type \Google\Protobuf\Internal\FeatureSet $features * Any features defined in the specific edition. * WARNING: This field should only be used by protobuf plugins or special * cases like the proto compiler. Other uses are discouraged and * developers should rely on the protoreflect APIs for their client language. * @type \Google\Protobuf\Internal\FieldOptions\FeatureSupport $feature_support * @type \Google\Protobuf\Internal\UninterpretedOption[] $uninterpreted_option * The parser stores options it doesn't recognize here. See above. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); parent::__construct($data); } /** * NOTE: ctype is deprecated. Use `features.(pb.cpp).string_type` instead. * The ctype option instructs the C++ code generator to use a different * representation of the field than it normally would. See the specific * options below. This option is only implemented to support use of * [ctype=CORD] and [ctype=STRING] (the default) on non-repeated fields of * type "bytes" in the open source release. * TODO: make ctype actually deprecated. * * Generated from protobuf field optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING]; * @return int */ public function getCtype() { return isset($this->ctype) ? $this->ctype : 0; } public function hasCtype() { return isset($this->ctype); } public function clearCtype() { unset($this->ctype); } /** * NOTE: ctype is deprecated. Use `features.(pb.cpp).string_type` instead. * The ctype option instructs the C++ code generator to use a different * representation of the field than it normally would. See the specific * options below. This option is only implemented to support use of * [ctype=CORD] and [ctype=STRING] (the default) on non-repeated fields of * type "bytes" in the open source release. * TODO: make ctype actually deprecated. * * Generated from protobuf field optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING]; * @param int $var * @return $this */ public function setCtype($var) { GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FieldOptions\CType::class); $this->ctype = $var; return $this; } /** * The packed option can be enabled for repeated primitive fields to enable * a more efficient representation on the wire. Rather than repeatedly * writing the tag and type for each element, the entire array is encoded as * a single length-delimited blob. In proto3, only explicit setting it to * false will avoid using packed encoding. This option is prohibited in * Editions, but the `repeated_field_encoding` feature can be used to control * the behavior. * * Generated from protobuf field optional bool packed = 2; * @return bool */ public function getPacked() { return isset($this->packed) ? $this->packed : false; } public function hasPacked() { return isset($this->packed); } public function clearPacked() { unset($this->packed); } /** * The packed option can be enabled for repeated primitive fields to enable * a more efficient representation on the wire. Rather than repeatedly * writing the tag and type for each element, the entire array is encoded as * a single length-delimited blob. In proto3, only explicit setting it to * false will avoid using packed encoding. This option is prohibited in * Editions, but the `repeated_field_encoding` feature can be used to control * the behavior. * * Generated from protobuf field optional bool packed = 2; * @param bool $var * @return $this */ public function setPacked($var) { GPBUtil::checkBool($var); $this->packed = $var; return $this; } /** * The jstype option determines the JavaScript type used for values of the * field. The option is permitted only for 64 bit integral and fixed types * (int64, uint64, sint64, fixed64, sfixed64). A field with jstype JS_STRING * is represented as JavaScript string, which avoids loss of precision that * can happen when a large value is converted to a floating point JavaScript. * Specifying JS_NUMBER for the jstype causes the generated JavaScript code to * use the JavaScript "number" type. The behavior of the default option * JS_NORMAL is implementation dependent. * This option is an enum to permit additional types to be added, e.g. * goog.math.Integer. * * Generated from protobuf field optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL]; * @return int */ public function getJstype() { return isset($this->jstype) ? $this->jstype : 0; } public function hasJstype() { return isset($this->jstype); } public function clearJstype() { unset($this->jstype); } /** * The jstype option determines the JavaScript type used for values of the * field. The option is permitted only for 64 bit integral and fixed types * (int64, uint64, sint64, fixed64, sfixed64). A field with jstype JS_STRING * is represented as JavaScript string, which avoids loss of precision that * can happen when a large value is converted to a floating point JavaScript. * Specifying JS_NUMBER for the jstype causes the generated JavaScript code to * use the JavaScript "number" type. The behavior of the default option * JS_NORMAL is implementation dependent. * This option is an enum to permit additional types to be added, e.g. * goog.math.Integer. * * Generated from protobuf field optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL]; * @param int $var * @return $this */ public function setJstype($var) { GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FieldOptions\JSType::class); $this->jstype = $var; return $this; } /** * Should this field be parsed lazily? Lazy applies only to message-type * fields. It means that when the outer message is initially parsed, the * inner message's contents will not be parsed but instead stored in encoded * form. The inner message will actually be parsed when it is first accessed. * This is only a hint. Implementations are free to choose whether to use * eager or lazy parsing regardless of the value of this option. However, * setting this option true suggests that the protocol author believes that * using lazy parsing on this field is worth the additional bookkeeping * overhead typically needed to implement it. * This option does not affect the public interface of any generated code; * all method signatures remain the same. Furthermore, thread-safety of the * interface is not affected by this option; const methods remain safe to * call from multiple threads concurrently, while non-const methods continue * to require exclusive access. * Note that lazy message fields are still eagerly verified to check * ill-formed wireformat or missing required fields. Calling IsInitialized() * on the outer message would fail if the inner message has missing required * fields. Failed verification would result in parsing failure (except when * uninitialized messages are acceptable). * * Generated from protobuf field optional bool lazy = 5 [default = false]; * @return bool */ public function getLazy() { return isset($this->lazy) ? $this->lazy : false; } public function hasLazy() { return isset($this->lazy); } public function clearLazy() { unset($this->lazy); } /** * Should this field be parsed lazily? Lazy applies only to message-type * fields. It means that when the outer message is initially parsed, the * inner message's contents will not be parsed but instead stored in encoded * form. The inner message will actually be parsed when it is first accessed. * This is only a hint. Implementations are free to choose whether to use * eager or lazy parsing regardless of the value of this option. However, * setting this option true suggests that the protocol author believes that * using lazy parsing on this field is worth the additional bookkeeping * overhead typically needed to implement it. * This option does not affect the public interface of any generated code; * all method signatures remain the same. Furthermore, thread-safety of the * interface is not affected by this option; const methods remain safe to * call from multiple threads concurrently, while non-const methods continue * to require exclusive access. * Note that lazy message fields are still eagerly verified to check * ill-formed wireformat or missing required fields. Calling IsInitialized() * on the outer message would fail if the inner message has missing required * fields. Failed verification would result in parsing failure (except when * uninitialized messages are acceptable). * * Generated from protobuf field optional bool lazy = 5 [default = false]; * @param bool $var * @return $this */ public function setLazy($var) { GPBUtil::checkBool($var); $this->lazy = $var; return $this; } /** * unverified_lazy does no correctness checks on the byte stream. This should * only be used where lazy with verification is prohibitive for performance * reasons. * * Generated from protobuf field optional bool unverified_lazy = 15 [default = false]; * @return bool */ public function getUnverifiedLazy() { return isset($this->unverified_lazy) ? $this->unverified_lazy : false; } public function hasUnverifiedLazy() { return isset($this->unverified_lazy); } public function clearUnverifiedLazy() { unset($this->unverified_lazy); } /** * unverified_lazy does no correctness checks on the byte stream. This should * only be used where lazy with verification is prohibitive for performance * reasons. * * Generated from protobuf field optional bool unverified_lazy = 15 [default = false]; * @param bool $var * @return $this */ public function setUnverifiedLazy($var) { GPBUtil::checkBool($var); $this->unverified_lazy = $var; return $this; } /** * Is this field deprecated? * Depending on the target platform, this can emit Deprecated annotations * for accessors, or it will be completely ignored; in the very least, this * is a formalization for deprecating fields. * * Generated from protobuf field optional bool deprecated = 3 [default = false]; * @return bool */ public function getDeprecated() { return isset($this->deprecated) ? $this->deprecated : false; } public function hasDeprecated() { return isset($this->deprecated); } public function clearDeprecated() { unset($this->deprecated); } /** * Is this field deprecated? * Depending on the target platform, this can emit Deprecated annotations * for accessors, or it will be completely ignored; in the very least, this * is a formalization for deprecating fields. * * Generated from protobuf field optional bool deprecated = 3 [default = false]; * @param bool $var * @return $this */ public function setDeprecated($var) { GPBUtil::checkBool($var); $this->deprecated = $var; return $this; } /** * DEPRECATED. DO NOT USE! * For Google-internal migration only. Do not use. * * Generated from protobuf field optional bool weak = 10 [default = false, deprecated = true]; * @return bool * @deprecated */ public function getWeak() { if (isset($this->weak)) { @trigger_error('weak is deprecated.', E_USER_DEPRECATED); } return isset($this->weak) ? $this->weak : false; } public function hasWeak() { if (isset($this->weak)) { @trigger_error('weak is deprecated.', E_USER_DEPRECATED); } return isset($this->weak); } public function clearWeak() { @trigger_error('weak is deprecated.', E_USER_DEPRECATED); unset($this->weak); } /** * DEPRECATED. DO NOT USE! * For Google-internal migration only. Do not use. * * Generated from protobuf field optional bool weak = 10 [default = false, deprecated = true]; * @param bool $var * @return $this * @deprecated */ public function setWeak($var) { @trigger_error('weak is deprecated.', E_USER_DEPRECATED); GPBUtil::checkBool($var); $this->weak = $var; return $this; } /** * Indicate that the field value should not be printed out when using debug * formats, e.g. when the field contains sensitive credentials. * * Generated from protobuf field optional bool debug_redact = 16 [default = false]; * @return bool */ public function getDebugRedact() { return isset($this->debug_redact) ? $this->debug_redact : false; } public function hasDebugRedact() { return isset($this->debug_redact); } public function clearDebugRedact() { unset($this->debug_redact); } /** * Indicate that the field value should not be printed out when using debug * formats, e.g. when the field contains sensitive credentials. * * Generated from protobuf field optional bool debug_redact = 16 [default = false]; * @param bool $var * @return $this */ public function setDebugRedact($var) { GPBUtil::checkBool($var); $this->debug_redact = $var; return $this; } /** * Generated from protobuf field optional .google.protobuf.FieldOptions.OptionRetention retention = 17; * @return int */ public function getRetention() { return isset($this->retention) ? $this->retention : 0; } public function hasRetention() { return isset($this->retention); } public function clearRetention() { unset($this->retention); } /** * Generated from protobuf field optional .google.protobuf.FieldOptions.OptionRetention retention = 17; * @param int $var * @return $this */ public function setRetention($var) { GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FieldOptions\OptionRetention::class); $this->retention = $var; return $this; } /** * Generated from protobuf field repeated .google.protobuf.FieldOptions.OptionTargetType targets = 19; * @return RepeatedField */ public function getTargets() { return $this->targets; } /** * Generated from protobuf field repeated .google.protobuf.FieldOptions.OptionTargetType targets = 19; * @param int[] $var * @return $this */ public function setTargets($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::ENUM, \Google\Protobuf\Internal\FieldOptions\OptionTargetType::class); $this->targets = $arr; return $this; } /** * Generated from protobuf field repeated .google.protobuf.FieldOptions.EditionDefault edition_defaults = 20; * @return RepeatedField<\Google\Protobuf\Internal\FieldOptions\EditionDefault> */ public function getEditionDefaults() { return $this->edition_defaults; } /** * Generated from protobuf field repeated .google.protobuf.FieldOptions.EditionDefault edition_defaults = 20; * @param \Google\Protobuf\Internal\FieldOptions\EditionDefault[] $var * @return $this */ public function setEditionDefaults($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\FieldOptions\EditionDefault::class); $this->edition_defaults = $arr; return $this; } /** * Any features defined in the specific edition. * WARNING: This field should only be used by protobuf plugins or special * cases like the proto compiler. Other uses are discouraged and * developers should rely on the protoreflect APIs for their client language. * * Generated from protobuf field optional .google.protobuf.FeatureSet features = 21; * @return \Google\Protobuf\Internal\FeatureSet|null */ public function getFeatures() { return $this->features; } public function hasFeatures() { return isset($this->features); } public function clearFeatures() { unset($this->features); } /** * Any features defined in the specific edition. * WARNING: This field should only be used by protobuf plugins or special * cases like the proto compiler. Other uses are discouraged and * developers should rely on the protoreflect APIs for their client language. * * Generated from protobuf field optional .google.protobuf.FeatureSet features = 21; * @param \Google\Protobuf\Internal\FeatureSet $var * @return $this */ public function setFeatures($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\FeatureSet::class); $this->features = $var; return $this; } /** * Generated from protobuf field optional .google.protobuf.FieldOptions.FeatureSupport feature_support = 22; * @return \Google\Protobuf\Internal\FieldOptions\FeatureSupport|null */ public function getFeatureSupport() { return $this->feature_support; } public function hasFeatureSupport() { return isset($this->feature_support); } public function clearFeatureSupport() { unset($this->feature_support); } /** * Generated from protobuf field optional .google.protobuf.FieldOptions.FeatureSupport feature_support = 22; * @param \Google\Protobuf\Internal\FieldOptions\FeatureSupport $var * @return $this */ public function setFeatureSupport($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\FieldOptions\FeatureSupport::class); $this->feature_support = $var; return $this; } /** * The parser stores options it doesn't recognize here. See above. * * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; * @return RepeatedField<\Google\Protobuf\Internal\UninterpretedOption> */ public function getUninterpretedOption() { return $this->uninterpreted_option; } /** * The parser stores options it doesn't recognize here. See above. * * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; * @param \Google\Protobuf\Internal\UninterpretedOption[] $var * @return $this */ public function setUninterpretedOption($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); $this->uninterpreted_option = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/FileDescriptor.php ================================================ package = $package; } public function getPackage() { return $this->package; } public function getMessageType() { return $this->message_type; } public function addMessageType($desc) { $this->message_type[] = $desc; } public function getEnumType() { return $this->enum_type; } public function addEnumType($desc) { $this->enum_type[]= $desc; } public static function buildFromProto($proto) { $file = new FileDescriptor(); $file->setPackage($proto->getPackage()); foreach ($proto->getMessageType() as $message_proto) { $file->addMessageType(Descriptor::buildFromProto( $message_proto, $proto, "")); } foreach ($proto->getEnumType() as $enum_proto) { $file->addEnumType( EnumDescriptor::buildFromProto( $enum_proto, $proto, "")); } return $file; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/FileDescriptorProto.php ================================================ google.protobuf.FileDescriptorProto */ class FileDescriptorProto extends \Google\Protobuf\Internal\Message { /** * file name, relative to root of source tree * * Generated from protobuf field optional string name = 1; */ protected $name = null; /** * e.g. "foo", "foo.bar", etc. * * Generated from protobuf field optional string package = 2; */ protected $package = null; /** * Names of files imported by this file. * * Generated from protobuf field repeated string dependency = 3; */ private $dependency; /** * Indexes of the public imported files in the dependency list above. * * Generated from protobuf field repeated int32 public_dependency = 10; */ private $public_dependency; /** * Indexes of the weak imported files in the dependency list. * For Google-internal migration only. Do not use. * * Generated from protobuf field repeated int32 weak_dependency = 11; */ private $weak_dependency; /** * Names of files imported by this file purely for the purpose of providing * option extensions. These are excluded from the dependency list above. * * Generated from protobuf field repeated string option_dependency = 15; */ private $option_dependency; /** * All top-level definitions in this file. * * Generated from protobuf field repeated .google.protobuf.DescriptorProto message_type = 4; */ private $message_type; /** * Generated from protobuf field repeated .google.protobuf.EnumDescriptorProto enum_type = 5; */ private $enum_type; /** * Generated from protobuf field repeated .google.protobuf.ServiceDescriptorProto service = 6; */ private $service; /** * Generated from protobuf field repeated .google.protobuf.FieldDescriptorProto extension = 7; */ private $extension; /** * Generated from protobuf field optional .google.protobuf.FileOptions options = 8; */ protected $options = null; /** * This field contains optional information about the original source code. * You may safely remove this entire field without harming runtime * functionality of the descriptors -- the information is needed only by * development tools. * * Generated from protobuf field optional .google.protobuf.SourceCodeInfo source_code_info = 9; */ protected $source_code_info = null; /** * The syntax of the proto file. * The supported values are "proto2", "proto3", and "editions". * If `edition` is present, this value must be "editions". * WARNING: This field should only be used by protobuf plugins or special * cases like the proto compiler. Other uses are discouraged and * developers should rely on the protoreflect APIs for their client language. * * Generated from protobuf field optional string syntax = 12; */ protected $syntax = null; /** * The edition of the proto file. * WARNING: This field should only be used by protobuf plugins or special * cases like the proto compiler. Other uses are discouraged and * developers should rely on the protoreflect APIs for their client language. * * Generated from protobuf field optional .google.protobuf.Edition edition = 14; */ protected $edition = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $name * file name, relative to root of source tree * @type string $package * e.g. "foo", "foo.bar", etc. * @type string[] $dependency * Names of files imported by this file. * @type int[] $public_dependency * Indexes of the public imported files in the dependency list above. * @type int[] $weak_dependency * Indexes of the weak imported files in the dependency list. * For Google-internal migration only. Do not use. * @type string[] $option_dependency * Names of files imported by this file purely for the purpose of providing * option extensions. These are excluded from the dependency list above. * @type \Google\Protobuf\Internal\DescriptorProto[] $message_type * All top-level definitions in this file. * @type \Google\Protobuf\Internal\EnumDescriptorProto[] $enum_type * @type \Google\Protobuf\Internal\ServiceDescriptorProto[] $service * @type \Google\Protobuf\Internal\FieldDescriptorProto[] $extension * @type \Google\Protobuf\Internal\FileOptions $options * @type \Google\Protobuf\Internal\SourceCodeInfo $source_code_info * This field contains optional information about the original source code. * You may safely remove this entire field without harming runtime * functionality of the descriptors -- the information is needed only by * development tools. * @type string $syntax * The syntax of the proto file. * The supported values are "proto2", "proto3", and "editions". * If `edition` is present, this value must be "editions". * WARNING: This field should only be used by protobuf plugins or special * cases like the proto compiler. Other uses are discouraged and * developers should rely on the protoreflect APIs for their client language. * @type int $edition * The edition of the proto file. * WARNING: This field should only be used by protobuf plugins or special * cases like the proto compiler. Other uses are discouraged and * developers should rely on the protoreflect APIs for their client language. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); parent::__construct($data); } /** * file name, relative to root of source tree * * Generated from protobuf field optional string name = 1; * @return string */ public function getName() { return isset($this->name) ? $this->name : ''; } public function hasName() { return isset($this->name); } public function clearName() { unset($this->name); } /** * file name, relative to root of source tree * * Generated from protobuf field optional string name = 1; * @param string $var * @return $this */ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; return $this; } /** * e.g. "foo", "foo.bar", etc. * * Generated from protobuf field optional string package = 2; * @return string */ public function getPackage() { return isset($this->package) ? $this->package : ''; } public function hasPackage() { return isset($this->package); } public function clearPackage() { unset($this->package); } /** * e.g. "foo", "foo.bar", etc. * * Generated from protobuf field optional string package = 2; * @param string $var * @return $this */ public function setPackage($var) { GPBUtil::checkString($var, True); $this->package = $var; return $this; } /** * Names of files imported by this file. * * Generated from protobuf field repeated string dependency = 3; * @return RepeatedField */ public function getDependency() { return $this->dependency; } /** * Names of files imported by this file. * * Generated from protobuf field repeated string dependency = 3; * @param string[] $var * @return $this */ public function setDependency($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->dependency = $arr; return $this; } /** * Indexes of the public imported files in the dependency list above. * * Generated from protobuf field repeated int32 public_dependency = 10; * @return RepeatedField */ public function getPublicDependency() { return $this->public_dependency; } /** * Indexes of the public imported files in the dependency list above. * * Generated from protobuf field repeated int32 public_dependency = 10; * @param int[] $var * @return $this */ public function setPublicDependency($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32); $this->public_dependency = $arr; return $this; } /** * Indexes of the weak imported files in the dependency list. * For Google-internal migration only. Do not use. * * Generated from protobuf field repeated int32 weak_dependency = 11; * @return RepeatedField */ public function getWeakDependency() { return $this->weak_dependency; } /** * Indexes of the weak imported files in the dependency list. * For Google-internal migration only. Do not use. * * Generated from protobuf field repeated int32 weak_dependency = 11; * @param int[] $var * @return $this */ public function setWeakDependency($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32); $this->weak_dependency = $arr; return $this; } /** * Names of files imported by this file purely for the purpose of providing * option extensions. These are excluded from the dependency list above. * * Generated from protobuf field repeated string option_dependency = 15; * @return RepeatedField */ public function getOptionDependency() { return $this->option_dependency; } /** * Names of files imported by this file purely for the purpose of providing * option extensions. These are excluded from the dependency list above. * * Generated from protobuf field repeated string option_dependency = 15; * @param string[] $var * @return $this */ public function setOptionDependency($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->option_dependency = $arr; return $this; } /** * All top-level definitions in this file. * * Generated from protobuf field repeated .google.protobuf.DescriptorProto message_type = 4; * @return RepeatedField<\Google\Protobuf\Internal\DescriptorProto> */ public function getMessageType() { return $this->message_type; } /** * All top-level definitions in this file. * * Generated from protobuf field repeated .google.protobuf.DescriptorProto message_type = 4; * @param \Google\Protobuf\Internal\DescriptorProto[] $var * @return $this */ public function setMessageType($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\DescriptorProto::class); $this->message_type = $arr; return $this; } /** * Generated from protobuf field repeated .google.protobuf.EnumDescriptorProto enum_type = 5; * @return RepeatedField<\Google\Protobuf\Internal\EnumDescriptorProto> */ public function getEnumType() { return $this->enum_type; } /** * Generated from protobuf field repeated .google.protobuf.EnumDescriptorProto enum_type = 5; * @param \Google\Protobuf\Internal\EnumDescriptorProto[] $var * @return $this */ public function setEnumType($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\EnumDescriptorProto::class); $this->enum_type = $arr; return $this; } /** * Generated from protobuf field repeated .google.protobuf.ServiceDescriptorProto service = 6; * @return RepeatedField<\Google\Protobuf\Internal\ServiceDescriptorProto> */ public function getService() { return $this->service; } /** * Generated from protobuf field repeated .google.protobuf.ServiceDescriptorProto service = 6; * @param \Google\Protobuf\Internal\ServiceDescriptorProto[] $var * @return $this */ public function setService($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\ServiceDescriptorProto::class); $this->service = $arr; return $this; } /** * Generated from protobuf field repeated .google.protobuf.FieldDescriptorProto extension = 7; * @return RepeatedField<\Google\Protobuf\Internal\FieldDescriptorProto> */ public function getExtension() { return $this->extension; } /** * Generated from protobuf field repeated .google.protobuf.FieldDescriptorProto extension = 7; * @param \Google\Protobuf\Internal\FieldDescriptorProto[] $var * @return $this */ public function setExtension($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\FieldDescriptorProto::class); $this->extension = $arr; return $this; } /** * Generated from protobuf field optional .google.protobuf.FileOptions options = 8; * @return \Google\Protobuf\Internal\FileOptions|null */ public function getOptions() { return $this->options; } public function hasOptions() { return isset($this->options); } public function clearOptions() { unset($this->options); } /** * Generated from protobuf field optional .google.protobuf.FileOptions options = 8; * @param \Google\Protobuf\Internal\FileOptions $var * @return $this */ public function setOptions($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\FileOptions::class); $this->options = $var; return $this; } /** * This field contains optional information about the original source code. * You may safely remove this entire field without harming runtime * functionality of the descriptors -- the information is needed only by * development tools. * * Generated from protobuf field optional .google.protobuf.SourceCodeInfo source_code_info = 9; * @return \Google\Protobuf\Internal\SourceCodeInfo|null */ public function getSourceCodeInfo() { return $this->source_code_info; } public function hasSourceCodeInfo() { return isset($this->source_code_info); } public function clearSourceCodeInfo() { unset($this->source_code_info); } /** * This field contains optional information about the original source code. * You may safely remove this entire field without harming runtime * functionality of the descriptors -- the information is needed only by * development tools. * * Generated from protobuf field optional .google.protobuf.SourceCodeInfo source_code_info = 9; * @param \Google\Protobuf\Internal\SourceCodeInfo $var * @return $this */ public function setSourceCodeInfo($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\SourceCodeInfo::class); $this->source_code_info = $var; return $this; } /** * The syntax of the proto file. * The supported values are "proto2", "proto3", and "editions". * If `edition` is present, this value must be "editions". * WARNING: This field should only be used by protobuf plugins or special * cases like the proto compiler. Other uses are discouraged and * developers should rely on the protoreflect APIs for their client language. * * Generated from protobuf field optional string syntax = 12; * @return string */ public function getSyntax() { return isset($this->syntax) ? $this->syntax : ''; } public function hasSyntax() { return isset($this->syntax); } public function clearSyntax() { unset($this->syntax); } /** * The syntax of the proto file. * The supported values are "proto2", "proto3", and "editions". * If `edition` is present, this value must be "editions". * WARNING: This field should only be used by protobuf plugins or special * cases like the proto compiler. Other uses are discouraged and * developers should rely on the protoreflect APIs for their client language. * * Generated from protobuf field optional string syntax = 12; * @param string $var * @return $this */ public function setSyntax($var) { GPBUtil::checkString($var, True); $this->syntax = $var; return $this; } /** * The edition of the proto file. * WARNING: This field should only be used by protobuf plugins or special * cases like the proto compiler. Other uses are discouraged and * developers should rely on the protoreflect APIs for their client language. * * Generated from protobuf field optional .google.protobuf.Edition edition = 14; * @return int */ public function getEdition() { return isset($this->edition) ? $this->edition : 0; } public function hasEdition() { return isset($this->edition); } public function clearEdition() { unset($this->edition); } /** * The edition of the proto file. * WARNING: This field should only be used by protobuf plugins or special * cases like the proto compiler. Other uses are discouraged and * developers should rely on the protoreflect APIs for their client language. * * Generated from protobuf field optional .google.protobuf.Edition edition = 14; * @param int $var * @return $this */ public function setEdition($var) { GPBUtil::checkEnum($var, \Google\Protobuf\Internal\Edition::class); $this->edition = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/FileDescriptorSet.php ================================================ google.protobuf.FileDescriptorSet */ class FileDescriptorSet extends \Google\Protobuf\Internal\Message { /** * Generated from protobuf field repeated .google.protobuf.FileDescriptorProto file = 1; */ private $file; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type \Google\Protobuf\Internal\FileDescriptorProto[] $file * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); parent::__construct($data); } /** * Generated from protobuf field repeated .google.protobuf.FileDescriptorProto file = 1; * @return RepeatedField<\Google\Protobuf\Internal\FileDescriptorProto> */ public function getFile() { return $this->file; } /** * Generated from protobuf field repeated .google.protobuf.FileDescriptorProto file = 1; * @param \Google\Protobuf\Internal\FileDescriptorProto[] $var * @return $this */ public function setFile($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\FileDescriptorProto::class); $this->file = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/FileOptions/OptimizeMode.php ================================================ google.protobuf.FileOptions.OptimizeMode */ class OptimizeMode { /** * Generate complete code for parsing, serialization, * * Generated from protobuf enum SPEED = 1; */ const SPEED = 1; /** * etc. * * Generated from protobuf enum CODE_SIZE = 2; */ const CODE_SIZE = 2; /** * Generate code using MessageLite and the lite runtime. * * Generated from protobuf enum LITE_RUNTIME = 3; */ const LITE_RUNTIME = 3; private static $valueToName = [ self::SPEED => 'SPEED', self::CODE_SIZE => 'CODE_SIZE', self::LITE_RUNTIME => 'LITE_RUNTIME', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/FileOptions.php ================================================ google.protobuf.FileOptions */ class FileOptions extends \Google\Protobuf\Internal\Message { /** * Sets the Java package where classes generated from this .proto will be * placed. By default, the proto package is used, but this is often * inappropriate because proto packages do not normally start with backwards * domain names. * * Generated from protobuf field optional string java_package = 1; */ protected $java_package = null; /** * Controls the name of the wrapper Java class generated for the .proto file. * That class will always contain the .proto file's getDescriptor() method as * well as any top-level extensions defined in the .proto file. * If java_multiple_files is disabled, then all the other classes from the * .proto file will be nested inside the single wrapper outer class. * * Generated from protobuf field optional string java_outer_classname = 8; */ protected $java_outer_classname = null; /** * If enabled, then the Java code generator will generate a separate .java * file for each top-level message, enum, and service defined in the .proto * file. Thus, these types will *not* be nested inside the wrapper class * named by java_outer_classname. However, the wrapper class will still be * generated to contain the file's getDescriptor() method as well as any * top-level extensions defined in the file. * * Generated from protobuf field optional bool java_multiple_files = 10 [default = false]; */ protected $java_multiple_files = null; /** * This option does nothing. * * Generated from protobuf field optional bool java_generate_equals_and_hash = 20 [deprecated = true]; * @deprecated */ protected $java_generate_equals_and_hash = null; /** * A proto2 file can set this to true to opt in to UTF-8 checking for Java, * which will throw an exception if invalid UTF-8 is parsed from the wire or * assigned to a string field. * TODO: clarify exactly what kinds of field types this option * applies to, and update these docs accordingly. * Proto3 files already perform these checks. Setting the option explicitly to * false has no effect: it cannot be used to opt proto3 files out of UTF-8 * checks. * * Generated from protobuf field optional bool java_string_check_utf8 = 27 [default = false]; */ protected $java_string_check_utf8 = null; /** * Generated from protobuf field optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; */ protected $optimize_for = null; /** * Sets the Go package where structs generated from this .proto will be * placed. If omitted, the Go package will be derived from the following: * - The basename of the package import path, if provided. * - Otherwise, the package statement in the .proto file, if present. * - Otherwise, the basename of the .proto file, without extension. * * Generated from protobuf field optional string go_package = 11; */ protected $go_package = null; /** * Should generic services be generated in each language? "Generic" services * are not specific to any particular RPC system. They are generated by the * main code generators in each language (without additional plugins). * Generic services were the only kind of service generation supported by * early versions of google.protobuf. * Generic services are now considered deprecated in favor of using plugins * that generate code specific to your particular RPC system. Therefore, * these default to false. Old code which depends on generic services should * explicitly set them to true. * * Generated from protobuf field optional bool cc_generic_services = 16 [default = false]; */ protected $cc_generic_services = null; /** * Generated from protobuf field optional bool java_generic_services = 17 [default = false]; */ protected $java_generic_services = null; /** * Generated from protobuf field optional bool py_generic_services = 18 [default = false]; */ protected $py_generic_services = null; /** * Is this file deprecated? * Depending on the target platform, this can emit Deprecated annotations * for everything in the file, or it will be completely ignored; in the very * least, this is a formalization for deprecating files. * * Generated from protobuf field optional bool deprecated = 23 [default = false]; */ protected $deprecated = null; /** * Enables the use of arenas for the proto messages in this file. This applies * only to generated classes for C++. * * Generated from protobuf field optional bool cc_enable_arenas = 31 [default = true]; */ protected $cc_enable_arenas = null; /** * Sets the objective c class prefix which is prepended to all objective c * generated classes from this .proto. There is no default. * * Generated from protobuf field optional string objc_class_prefix = 36; */ protected $objc_class_prefix = null; /** * Namespace for generated classes; defaults to the package. * * Generated from protobuf field optional string csharp_namespace = 37; */ protected $csharp_namespace = null; /** * By default Swift generators will take the proto package and CamelCase it * replacing '.' with underscore and use that to prefix the types/symbols * defined. When this options is provided, they will use this value instead * to prefix the types/symbols defined. * * Generated from protobuf field optional string swift_prefix = 39; */ protected $swift_prefix = null; /** * Sets the php class prefix which is prepended to all php generated classes * from this .proto. Default is empty. * * Generated from protobuf field optional string php_class_prefix = 40; */ protected $php_class_prefix = null; /** * Use this option to change the namespace of php generated classes. Default * is empty. When this option is empty, the package name will be used for * determining the namespace. * * Generated from protobuf field optional string php_namespace = 41; */ protected $php_namespace = null; /** * Use this option to change the namespace of php generated metadata classes. * Default is empty. When this option is empty, the proto file name will be * used for determining the namespace. * * Generated from protobuf field optional string php_metadata_namespace = 44; */ protected $php_metadata_namespace = null; /** * Use this option to change the package of ruby generated classes. Default * is empty. When this option is not set, the package name will be used for * determining the ruby package. * * Generated from protobuf field optional string ruby_package = 45; */ protected $ruby_package = null; /** * Any features defined in the specific edition. * WARNING: This field should only be used by protobuf plugins or special * cases like the proto compiler. Other uses are discouraged and * developers should rely on the protoreflect APIs for their client language. * * Generated from protobuf field optional .google.protobuf.FeatureSet features = 50; */ protected $features = null; /** * The parser stores options it doesn't recognize here. * See the documentation for the "Options" section above. * * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; */ private $uninterpreted_option; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $java_package * Sets the Java package where classes generated from this .proto will be * placed. By default, the proto package is used, but this is often * inappropriate because proto packages do not normally start with backwards * domain names. * @type string $java_outer_classname * Controls the name of the wrapper Java class generated for the .proto file. * That class will always contain the .proto file's getDescriptor() method as * well as any top-level extensions defined in the .proto file. * If java_multiple_files is disabled, then all the other classes from the * .proto file will be nested inside the single wrapper outer class. * @type bool $java_multiple_files * If enabled, then the Java code generator will generate a separate .java * file for each top-level message, enum, and service defined in the .proto * file. Thus, these types will *not* be nested inside the wrapper class * named by java_outer_classname. However, the wrapper class will still be * generated to contain the file's getDescriptor() method as well as any * top-level extensions defined in the file. * @type bool $java_generate_equals_and_hash * This option does nothing. * @type bool $java_string_check_utf8 * A proto2 file can set this to true to opt in to UTF-8 checking for Java, * which will throw an exception if invalid UTF-8 is parsed from the wire or * assigned to a string field. * TODO: clarify exactly what kinds of field types this option * applies to, and update these docs accordingly. * Proto3 files already perform these checks. Setting the option explicitly to * false has no effect: it cannot be used to opt proto3 files out of UTF-8 * checks. * @type int $optimize_for * @type string $go_package * Sets the Go package where structs generated from this .proto will be * placed. If omitted, the Go package will be derived from the following: * - The basename of the package import path, if provided. * - Otherwise, the package statement in the .proto file, if present. * - Otherwise, the basename of the .proto file, without extension. * @type bool $cc_generic_services * Should generic services be generated in each language? "Generic" services * are not specific to any particular RPC system. They are generated by the * main code generators in each language (without additional plugins). * Generic services were the only kind of service generation supported by * early versions of google.protobuf. * Generic services are now considered deprecated in favor of using plugins * that generate code specific to your particular RPC system. Therefore, * these default to false. Old code which depends on generic services should * explicitly set them to true. * @type bool $java_generic_services * @type bool $py_generic_services * @type bool $deprecated * Is this file deprecated? * Depending on the target platform, this can emit Deprecated annotations * for everything in the file, or it will be completely ignored; in the very * least, this is a formalization for deprecating files. * @type bool $cc_enable_arenas * Enables the use of arenas for the proto messages in this file. This applies * only to generated classes for C++. * @type string $objc_class_prefix * Sets the objective c class prefix which is prepended to all objective c * generated classes from this .proto. There is no default. * @type string $csharp_namespace * Namespace for generated classes; defaults to the package. * @type string $swift_prefix * By default Swift generators will take the proto package and CamelCase it * replacing '.' with underscore and use that to prefix the types/symbols * defined. When this options is provided, they will use this value instead * to prefix the types/symbols defined. * @type string $php_class_prefix * Sets the php class prefix which is prepended to all php generated classes * from this .proto. Default is empty. * @type string $php_namespace * Use this option to change the namespace of php generated classes. Default * is empty. When this option is empty, the package name will be used for * determining the namespace. * @type string $php_metadata_namespace * Use this option to change the namespace of php generated metadata classes. * Default is empty. When this option is empty, the proto file name will be * used for determining the namespace. * @type string $ruby_package * Use this option to change the package of ruby generated classes. Default * is empty. When this option is not set, the package name will be used for * determining the ruby package. * @type \Google\Protobuf\Internal\FeatureSet $features * Any features defined in the specific edition. * WARNING: This field should only be used by protobuf plugins or special * cases like the proto compiler. Other uses are discouraged and * developers should rely on the protoreflect APIs for their client language. * @type \Google\Protobuf\Internal\UninterpretedOption[] $uninterpreted_option * The parser stores options it doesn't recognize here. * See the documentation for the "Options" section above. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); parent::__construct($data); } /** * Sets the Java package where classes generated from this .proto will be * placed. By default, the proto package is used, but this is often * inappropriate because proto packages do not normally start with backwards * domain names. * * Generated from protobuf field optional string java_package = 1; * @return string */ public function getJavaPackage() { return isset($this->java_package) ? $this->java_package : ''; } public function hasJavaPackage() { return isset($this->java_package); } public function clearJavaPackage() { unset($this->java_package); } /** * Sets the Java package where classes generated from this .proto will be * placed. By default, the proto package is used, but this is often * inappropriate because proto packages do not normally start with backwards * domain names. * * Generated from protobuf field optional string java_package = 1; * @param string $var * @return $this */ public function setJavaPackage($var) { GPBUtil::checkString($var, True); $this->java_package = $var; return $this; } /** * Controls the name of the wrapper Java class generated for the .proto file. * That class will always contain the .proto file's getDescriptor() method as * well as any top-level extensions defined in the .proto file. * If java_multiple_files is disabled, then all the other classes from the * .proto file will be nested inside the single wrapper outer class. * * Generated from protobuf field optional string java_outer_classname = 8; * @return string */ public function getJavaOuterClassname() { return isset($this->java_outer_classname) ? $this->java_outer_classname : ''; } public function hasJavaOuterClassname() { return isset($this->java_outer_classname); } public function clearJavaOuterClassname() { unset($this->java_outer_classname); } /** * Controls the name of the wrapper Java class generated for the .proto file. * That class will always contain the .proto file's getDescriptor() method as * well as any top-level extensions defined in the .proto file. * If java_multiple_files is disabled, then all the other classes from the * .proto file will be nested inside the single wrapper outer class. * * Generated from protobuf field optional string java_outer_classname = 8; * @param string $var * @return $this */ public function setJavaOuterClassname($var) { GPBUtil::checkString($var, True); $this->java_outer_classname = $var; return $this; } /** * If enabled, then the Java code generator will generate a separate .java * file for each top-level message, enum, and service defined in the .proto * file. Thus, these types will *not* be nested inside the wrapper class * named by java_outer_classname. However, the wrapper class will still be * generated to contain the file's getDescriptor() method as well as any * top-level extensions defined in the file. * * Generated from protobuf field optional bool java_multiple_files = 10 [default = false]; * @return bool */ public function getJavaMultipleFiles() { return isset($this->java_multiple_files) ? $this->java_multiple_files : false; } public function hasJavaMultipleFiles() { return isset($this->java_multiple_files); } public function clearJavaMultipleFiles() { unset($this->java_multiple_files); } /** * If enabled, then the Java code generator will generate a separate .java * file for each top-level message, enum, and service defined in the .proto * file. Thus, these types will *not* be nested inside the wrapper class * named by java_outer_classname. However, the wrapper class will still be * generated to contain the file's getDescriptor() method as well as any * top-level extensions defined in the file. * * Generated from protobuf field optional bool java_multiple_files = 10 [default = false]; * @param bool $var * @return $this */ public function setJavaMultipleFiles($var) { GPBUtil::checkBool($var); $this->java_multiple_files = $var; return $this; } /** * This option does nothing. * * Generated from protobuf field optional bool java_generate_equals_and_hash = 20 [deprecated = true]; * @return bool * @deprecated */ public function getJavaGenerateEqualsAndHash() { if (isset($this->java_generate_equals_and_hash)) { @trigger_error('java_generate_equals_and_hash is deprecated.', E_USER_DEPRECATED); } return isset($this->java_generate_equals_and_hash) ? $this->java_generate_equals_and_hash : false; } public function hasJavaGenerateEqualsAndHash() { if (isset($this->java_generate_equals_and_hash)) { @trigger_error('java_generate_equals_and_hash is deprecated.', E_USER_DEPRECATED); } return isset($this->java_generate_equals_and_hash); } public function clearJavaGenerateEqualsAndHash() { @trigger_error('java_generate_equals_and_hash is deprecated.', E_USER_DEPRECATED); unset($this->java_generate_equals_and_hash); } /** * This option does nothing. * * Generated from protobuf field optional bool java_generate_equals_and_hash = 20 [deprecated = true]; * @param bool $var * @return $this * @deprecated */ public function setJavaGenerateEqualsAndHash($var) { @trigger_error('java_generate_equals_and_hash is deprecated.', E_USER_DEPRECATED); GPBUtil::checkBool($var); $this->java_generate_equals_and_hash = $var; return $this; } /** * A proto2 file can set this to true to opt in to UTF-8 checking for Java, * which will throw an exception if invalid UTF-8 is parsed from the wire or * assigned to a string field. * TODO: clarify exactly what kinds of field types this option * applies to, and update these docs accordingly. * Proto3 files already perform these checks. Setting the option explicitly to * false has no effect: it cannot be used to opt proto3 files out of UTF-8 * checks. * * Generated from protobuf field optional bool java_string_check_utf8 = 27 [default = false]; * @return bool */ public function getJavaStringCheckUtf8() { return isset($this->java_string_check_utf8) ? $this->java_string_check_utf8 : false; } public function hasJavaStringCheckUtf8() { return isset($this->java_string_check_utf8); } public function clearJavaStringCheckUtf8() { unset($this->java_string_check_utf8); } /** * A proto2 file can set this to true to opt in to UTF-8 checking for Java, * which will throw an exception if invalid UTF-8 is parsed from the wire or * assigned to a string field. * TODO: clarify exactly what kinds of field types this option * applies to, and update these docs accordingly. * Proto3 files already perform these checks. Setting the option explicitly to * false has no effect: it cannot be used to opt proto3 files out of UTF-8 * checks. * * Generated from protobuf field optional bool java_string_check_utf8 = 27 [default = false]; * @param bool $var * @return $this */ public function setJavaStringCheckUtf8($var) { GPBUtil::checkBool($var); $this->java_string_check_utf8 = $var; return $this; } /** * Generated from protobuf field optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; * @return int */ public function getOptimizeFor() { return isset($this->optimize_for) ? $this->optimize_for : 0; } public function hasOptimizeFor() { return isset($this->optimize_for); } public function clearOptimizeFor() { unset($this->optimize_for); } /** * Generated from protobuf field optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; * @param int $var * @return $this */ public function setOptimizeFor($var) { GPBUtil::checkEnum($var, \Google\Protobuf\Internal\FileOptions\OptimizeMode::class); $this->optimize_for = $var; return $this; } /** * Sets the Go package where structs generated from this .proto will be * placed. If omitted, the Go package will be derived from the following: * - The basename of the package import path, if provided. * - Otherwise, the package statement in the .proto file, if present. * - Otherwise, the basename of the .proto file, without extension. * * Generated from protobuf field optional string go_package = 11; * @return string */ public function getGoPackage() { return isset($this->go_package) ? $this->go_package : ''; } public function hasGoPackage() { return isset($this->go_package); } public function clearGoPackage() { unset($this->go_package); } /** * Sets the Go package where structs generated from this .proto will be * placed. If omitted, the Go package will be derived from the following: * - The basename of the package import path, if provided. * - Otherwise, the package statement in the .proto file, if present. * - Otherwise, the basename of the .proto file, without extension. * * Generated from protobuf field optional string go_package = 11; * @param string $var * @return $this */ public function setGoPackage($var) { GPBUtil::checkString($var, True); $this->go_package = $var; return $this; } /** * Should generic services be generated in each language? "Generic" services * are not specific to any particular RPC system. They are generated by the * main code generators in each language (without additional plugins). * Generic services were the only kind of service generation supported by * early versions of google.protobuf. * Generic services are now considered deprecated in favor of using plugins * that generate code specific to your particular RPC system. Therefore, * these default to false. Old code which depends on generic services should * explicitly set them to true. * * Generated from protobuf field optional bool cc_generic_services = 16 [default = false]; * @return bool */ public function getCcGenericServices() { return isset($this->cc_generic_services) ? $this->cc_generic_services : false; } public function hasCcGenericServices() { return isset($this->cc_generic_services); } public function clearCcGenericServices() { unset($this->cc_generic_services); } /** * Should generic services be generated in each language? "Generic" services * are not specific to any particular RPC system. They are generated by the * main code generators in each language (without additional plugins). * Generic services were the only kind of service generation supported by * early versions of google.protobuf. * Generic services are now considered deprecated in favor of using plugins * that generate code specific to your particular RPC system. Therefore, * these default to false. Old code which depends on generic services should * explicitly set them to true. * * Generated from protobuf field optional bool cc_generic_services = 16 [default = false]; * @param bool $var * @return $this */ public function setCcGenericServices($var) { GPBUtil::checkBool($var); $this->cc_generic_services = $var; return $this; } /** * Generated from protobuf field optional bool java_generic_services = 17 [default = false]; * @return bool */ public function getJavaGenericServices() { return isset($this->java_generic_services) ? $this->java_generic_services : false; } public function hasJavaGenericServices() { return isset($this->java_generic_services); } public function clearJavaGenericServices() { unset($this->java_generic_services); } /** * Generated from protobuf field optional bool java_generic_services = 17 [default = false]; * @param bool $var * @return $this */ public function setJavaGenericServices($var) { GPBUtil::checkBool($var); $this->java_generic_services = $var; return $this; } /** * Generated from protobuf field optional bool py_generic_services = 18 [default = false]; * @return bool */ public function getPyGenericServices() { return isset($this->py_generic_services) ? $this->py_generic_services : false; } public function hasPyGenericServices() { return isset($this->py_generic_services); } public function clearPyGenericServices() { unset($this->py_generic_services); } /** * Generated from protobuf field optional bool py_generic_services = 18 [default = false]; * @param bool $var * @return $this */ public function setPyGenericServices($var) { GPBUtil::checkBool($var); $this->py_generic_services = $var; return $this; } /** * Is this file deprecated? * Depending on the target platform, this can emit Deprecated annotations * for everything in the file, or it will be completely ignored; in the very * least, this is a formalization for deprecating files. * * Generated from protobuf field optional bool deprecated = 23 [default = false]; * @return bool */ public function getDeprecated() { return isset($this->deprecated) ? $this->deprecated : false; } public function hasDeprecated() { return isset($this->deprecated); } public function clearDeprecated() { unset($this->deprecated); } /** * Is this file deprecated? * Depending on the target platform, this can emit Deprecated annotations * for everything in the file, or it will be completely ignored; in the very * least, this is a formalization for deprecating files. * * Generated from protobuf field optional bool deprecated = 23 [default = false]; * @param bool $var * @return $this */ public function setDeprecated($var) { GPBUtil::checkBool($var); $this->deprecated = $var; return $this; } /** * Enables the use of arenas for the proto messages in this file. This applies * only to generated classes for C++. * * Generated from protobuf field optional bool cc_enable_arenas = 31 [default = true]; * @return bool */ public function getCcEnableArenas() { return isset($this->cc_enable_arenas) ? $this->cc_enable_arenas : false; } public function hasCcEnableArenas() { return isset($this->cc_enable_arenas); } public function clearCcEnableArenas() { unset($this->cc_enable_arenas); } /** * Enables the use of arenas for the proto messages in this file. This applies * only to generated classes for C++. * * Generated from protobuf field optional bool cc_enable_arenas = 31 [default = true]; * @param bool $var * @return $this */ public function setCcEnableArenas($var) { GPBUtil::checkBool($var); $this->cc_enable_arenas = $var; return $this; } /** * Sets the objective c class prefix which is prepended to all objective c * generated classes from this .proto. There is no default. * * Generated from protobuf field optional string objc_class_prefix = 36; * @return string */ public function getObjcClassPrefix() { return isset($this->objc_class_prefix) ? $this->objc_class_prefix : ''; } public function hasObjcClassPrefix() { return isset($this->objc_class_prefix); } public function clearObjcClassPrefix() { unset($this->objc_class_prefix); } /** * Sets the objective c class prefix which is prepended to all objective c * generated classes from this .proto. There is no default. * * Generated from protobuf field optional string objc_class_prefix = 36; * @param string $var * @return $this */ public function setObjcClassPrefix($var) { GPBUtil::checkString($var, True); $this->objc_class_prefix = $var; return $this; } /** * Namespace for generated classes; defaults to the package. * * Generated from protobuf field optional string csharp_namespace = 37; * @return string */ public function getCsharpNamespace() { return isset($this->csharp_namespace) ? $this->csharp_namespace : ''; } public function hasCsharpNamespace() { return isset($this->csharp_namespace); } public function clearCsharpNamespace() { unset($this->csharp_namespace); } /** * Namespace for generated classes; defaults to the package. * * Generated from protobuf field optional string csharp_namespace = 37; * @param string $var * @return $this */ public function setCsharpNamespace($var) { GPBUtil::checkString($var, True); $this->csharp_namespace = $var; return $this; } /** * By default Swift generators will take the proto package and CamelCase it * replacing '.' with underscore and use that to prefix the types/symbols * defined. When this options is provided, they will use this value instead * to prefix the types/symbols defined. * * Generated from protobuf field optional string swift_prefix = 39; * @return string */ public function getSwiftPrefix() { return isset($this->swift_prefix) ? $this->swift_prefix : ''; } public function hasSwiftPrefix() { return isset($this->swift_prefix); } public function clearSwiftPrefix() { unset($this->swift_prefix); } /** * By default Swift generators will take the proto package and CamelCase it * replacing '.' with underscore and use that to prefix the types/symbols * defined. When this options is provided, they will use this value instead * to prefix the types/symbols defined. * * Generated from protobuf field optional string swift_prefix = 39; * @param string $var * @return $this */ public function setSwiftPrefix($var) { GPBUtil::checkString($var, True); $this->swift_prefix = $var; return $this; } /** * Sets the php class prefix which is prepended to all php generated classes * from this .proto. Default is empty. * * Generated from protobuf field optional string php_class_prefix = 40; * @return string */ public function getPhpClassPrefix() { return isset($this->php_class_prefix) ? $this->php_class_prefix : ''; } public function hasPhpClassPrefix() { return isset($this->php_class_prefix); } public function clearPhpClassPrefix() { unset($this->php_class_prefix); } /** * Sets the php class prefix which is prepended to all php generated classes * from this .proto. Default is empty. * * Generated from protobuf field optional string php_class_prefix = 40; * @param string $var * @return $this */ public function setPhpClassPrefix($var) { GPBUtil::checkString($var, True); $this->php_class_prefix = $var; return $this; } /** * Use this option to change the namespace of php generated classes. Default * is empty. When this option is empty, the package name will be used for * determining the namespace. * * Generated from protobuf field optional string php_namespace = 41; * @return string */ public function getPhpNamespace() { return isset($this->php_namespace) ? $this->php_namespace : ''; } public function hasPhpNamespace() { return isset($this->php_namespace); } public function clearPhpNamespace() { unset($this->php_namespace); } /** * Use this option to change the namespace of php generated classes. Default * is empty. When this option is empty, the package name will be used for * determining the namespace. * * Generated from protobuf field optional string php_namespace = 41; * @param string $var * @return $this */ public function setPhpNamespace($var) { GPBUtil::checkString($var, True); $this->php_namespace = $var; return $this; } /** * Use this option to change the namespace of php generated metadata classes. * Default is empty. When this option is empty, the proto file name will be * used for determining the namespace. * * Generated from protobuf field optional string php_metadata_namespace = 44; * @return string */ public function getPhpMetadataNamespace() { return isset($this->php_metadata_namespace) ? $this->php_metadata_namespace : ''; } public function hasPhpMetadataNamespace() { return isset($this->php_metadata_namespace); } public function clearPhpMetadataNamespace() { unset($this->php_metadata_namespace); } /** * Use this option to change the namespace of php generated metadata classes. * Default is empty. When this option is empty, the proto file name will be * used for determining the namespace. * * Generated from protobuf field optional string php_metadata_namespace = 44; * @param string $var * @return $this */ public function setPhpMetadataNamespace($var) { GPBUtil::checkString($var, True); $this->php_metadata_namespace = $var; return $this; } /** * Use this option to change the package of ruby generated classes. Default * is empty. When this option is not set, the package name will be used for * determining the ruby package. * * Generated from protobuf field optional string ruby_package = 45; * @return string */ public function getRubyPackage() { return isset($this->ruby_package) ? $this->ruby_package : ''; } public function hasRubyPackage() { return isset($this->ruby_package); } public function clearRubyPackage() { unset($this->ruby_package); } /** * Use this option to change the package of ruby generated classes. Default * is empty. When this option is not set, the package name will be used for * determining the ruby package. * * Generated from protobuf field optional string ruby_package = 45; * @param string $var * @return $this */ public function setRubyPackage($var) { GPBUtil::checkString($var, True); $this->ruby_package = $var; return $this; } /** * Any features defined in the specific edition. * WARNING: This field should only be used by protobuf plugins or special * cases like the proto compiler. Other uses are discouraged and * developers should rely on the protoreflect APIs for their client language. * * Generated from protobuf field optional .google.protobuf.FeatureSet features = 50; * @return \Google\Protobuf\Internal\FeatureSet|null */ public function getFeatures() { return $this->features; } public function hasFeatures() { return isset($this->features); } public function clearFeatures() { unset($this->features); } /** * Any features defined in the specific edition. * WARNING: This field should only be used by protobuf plugins or special * cases like the proto compiler. Other uses are discouraged and * developers should rely on the protoreflect APIs for their client language. * * Generated from protobuf field optional .google.protobuf.FeatureSet features = 50; * @param \Google\Protobuf\Internal\FeatureSet $var * @return $this */ public function setFeatures($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\FeatureSet::class); $this->features = $var; return $this; } /** * The parser stores options it doesn't recognize here. * See the documentation for the "Options" section above. * * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; * @return RepeatedField<\Google\Protobuf\Internal\UninterpretedOption> */ public function getUninterpretedOption() { return $this->uninterpreted_option; } /** * The parser stores options it doesn't recognize here. * See the documentation for the "Options" section above. * * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; * @param \Google\Protobuf\Internal\UninterpretedOption[] $var * @return $this */ public function setUninterpretedOption($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); $this->uninterpreted_option = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/GPBDecodeException.php ================================================ writeRaw("\"", 1); $field_name = GPBJsonWire::formatFieldName($field, $output->getOptions()); $output->writeRaw($field_name, strlen($field_name)); $output->writeRaw("\":", 2); } return static::serializeFieldValueToStream( $value, $field, $output, !$has_field_name); } public static function serializeFieldValueToStream( $values, $field, &$output, $is_well_known = false) { if ($field->isMap()) { $output->writeRaw("{", 1); $first = true; $map_entry = $field->getMessageType(); $key_field = $map_entry->getFieldByNumber(1); $value_field = $map_entry->getFieldByNumber(2); switch ($key_field->getType()) { case GPBType::STRING: case GPBType::SFIXED64: case GPBType::INT64: case GPBType::SINT64: case GPBType::FIXED64: case GPBType::UINT64: $additional_quote = false; break; default: $additional_quote = true; } foreach ($values as $key => $value) { if ($first) { $first = false; } else { $output->writeRaw(",", 1); } if ($additional_quote) { $output->writeRaw("\"", 1); } if (!static::serializeSingularFieldValueToStream( $key, $key_field, $output, $is_well_known)) { return false; } if ($additional_quote) { $output->writeRaw("\"", 1); } $output->writeRaw(":", 1); if (!static::serializeSingularFieldValueToStream( $value, $value_field, $output, $is_well_known)) { return false; } } $output->writeRaw("}", 1); return true; } elseif ($field->isRepeated()) { $output->writeRaw("[", 1); $first = true; foreach ($values as $value) { if ($first) { $first = false; } else { $output->writeRaw(",", 1); } if (!static::serializeSingularFieldValueToStream( $value, $field, $output, $is_well_known)) { return false; } } $output->writeRaw("]", 1); return true; } else { return static::serializeSingularFieldValueToStream( $values, $field, $output, $is_well_known); } } private static function serializeSingularFieldValueToStream( $value, $field, &$output, $is_well_known = false) { switch ($field->getType()) { case GPBType::SFIXED32: case GPBType::SINT32: case GPBType::INT32: $str_value = strval($value); $output->writeRaw($str_value, strlen($str_value)); break; case GPBType::FIXED32: case GPBType::UINT32: if ($value < 0) { $value = bcadd($value, "4294967296"); } $str_value = strval($value); $output->writeRaw($str_value, strlen($str_value)); break; case GPBType::FIXED64: case GPBType::UINT64: if ($value < 0) { $value = bcadd($value, "18446744073709551616"); } // Intentional fall through. case GPBType::SFIXED64: case GPBType::INT64: case GPBType::SINT64: $output->writeRaw("\"", 1); $str_value = strval($value); $output->writeRaw($str_value, strlen($str_value)); $output->writeRaw("\"", 1); break; case GPBType::FLOAT: if (is_nan($value)) { $str_value = "\"NaN\""; } elseif ($value === INF) { $str_value = "\"Infinity\""; } elseif ($value === -INF) { $str_value = "\"-Infinity\""; } else { $str_value = sprintf("%.8g", $value); } $output->writeRaw($str_value, strlen($str_value)); break; case GPBType::DOUBLE: if (is_nan($value)) { $str_value = "\"NaN\""; } elseif ($value === INF) { $str_value = "\"Infinity\""; } elseif ($value === -INF) { $str_value = "\"-Infinity\""; } else { $str_value = sprintf("%.17g", $value); } $output->writeRaw($str_value, strlen($str_value)); break; case GPBType::ENUM: $enum_desc = $field->getEnumType(); if ($enum_desc->getClass() === "Google\Protobuf\NullValue") { $output->writeRaw("null", 4); break; } if ($output->getOptions() & PrintOptions::ALWAYS_PRINT_ENUMS_AS_INTS) { $str_value = strval($value); $output->writeRaw($str_value, strlen($str_value)); break; } $enum_value_desc = $enum_desc->getValueByNumber($value); if (!is_null($enum_value_desc)) { $str_value = $enum_value_desc->getName(); $output->writeRaw("\"", 1); $output->writeRaw($str_value, strlen($str_value)); $output->writeRaw("\"", 1); } else { $str_value = strval($value); $output->writeRaw($str_value, strlen($str_value)); } break; case GPBType::BOOL: if ($value) { $output->writeRaw("true", 4); } else { $output->writeRaw("false", 5); } break; case GPBType::BYTES: $bytes_value = base64_encode($value); $output->writeRaw("\"", 1); $output->writeRaw($bytes_value, strlen($bytes_value)); $output->writeRaw("\"", 1); break; case GPBType::STRING: $value = json_encode($value, JSON_UNESCAPED_UNICODE); $output->writeRaw($value, strlen($value)); break; // case GPBType::GROUP: // echo "GROUP\xA"; // trigger_error("Not implemented.", E_ERROR); // break; case GPBType::MESSAGE: $value->serializeToJsonStream($output); break; default: user_error("Unsupported type."); return false; } return true; } private static function formatFieldName($field, $options) { if ($options & PrintOptions::PRESERVE_PROTO_FIELD_NAMES) { return $field->getName(); } return $field->getJsonName(); } // Used for escaping control chars in strings. private static $k_control_char_limit = 0x20; private static function jsonNiceEscape($c) { switch ($c) { case '"': return "\\\""; case '\\': return "\\\\"; case '/': return "\\/"; case '\b': return "\\b"; case '\f': return "\\f"; case '\n': return "\\n"; case '\r': return "\\r"; case '\t': return "\\t"; default: return NULL; } } private static function isJsonEscaped($c) { // See RFC 4627. return $c < chr($k_control_char_limit) || $c === "\"" || $c === "\\"; } public static function escapedJson($value) { $escaped_value = ""; $unescaped_run = ""; for ($i = 0; $i < strlen($value); $i++) { $c = $value[$i]; // Handle escaping. if (static::isJsonEscaped($c)) { // Use a "nice" escape, like \n, if one exists for this // character. $escape = static::jsonNiceEscape($c); if (is_null($escape)) { $escape = "\\u00" . bin2hex($c); } if ($unescaped_run !== "") { $escaped_value .= $unescaped_run; $unescaped_run = ""; } $escaped_value .= $escape; } else { if ($unescaped_run === "") { $unescaped_run .= $c; } } } $escaped_value .= $unescaped_run; return $escaped_value; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/GPBLabel.php ================================================ 0) { $high = (int) bcsub($high, 4294967296); } else { $high = (int) $high; } if (bccomp($low, 2147483647) > 0) { $low = (int) bcsub($low, 4294967296); } else { $low = (int) $low; } if ($isNeg) { $high = ~$high; $low = ~$low; $low++; if (!$low) { $high = (int)($high + 1); } } if ($trim) { $high = 0; } } public static function checkString(&$var, $check_utf8) { if (is_array($var) || is_object($var)) { throw new \InvalidArgumentException("Expect string."); } if (!is_string($var)) { $var = strval($var); } if ($check_utf8 && !preg_match('//u', $var)) { throw new \Exception("Expect utf-8 encoding."); } } public static function checkEnum(&$var) { static::checkInt32($var); } public static function checkInt32(&$var) { if (is_numeric($var)) { $var = intval($var); } else { throw new \Exception("Expect integer."); } } public static function checkUint32(&$var) { if (is_numeric($var)) { if (PHP_INT_SIZE === 8) { $var = intval($var); $var |= ((-(($var >> 31) & 0x1)) & ~0xFFFFFFFF); } else { if (bccomp($var, 0x7FFFFFFF) > 0) { $var = bcsub($var, "4294967296"); } $var = (int) $var; } } else { throw new \Exception("Expect integer."); } } public static function checkInt64(&$var) { if (is_numeric($var)) { if (PHP_INT_SIZE == 8) { $var = intval($var); } else { if (is_float($var) || is_integer($var) || (is_string($var) && bccomp($var, "9223372036854774784") < 0)) { $var = number_format($var, 0, ".", ""); } } } else { throw new \Exception("Expect integer."); } } public static function checkUint64(&$var) { if (is_numeric($var)) { if (PHP_INT_SIZE == 8) { $var = intval($var); } else { $var = number_format($var, 0, ".", ""); } } else { throw new \Exception("Expect integer."); } } public static function checkFloat(&$var) { if (is_float($var) || is_numeric($var)) { $var = unpack("f", pack("f", $var))[1]; } else { throw new \Exception("Expect float."); } } public static function checkDouble(&$var) { if (is_float($var) || is_numeric($var)) { $var = floatval($var); } else { throw new \Exception("Expect float."); } } public static function checkBool(&$var) { if (is_array($var) || is_object($var)) { throw new \Exception("Expect boolean."); } $var = boolval($var); } public static function checkMessage(&$var, $klass, $newClass = null) { if (!$var instanceof $klass && !is_null($var)) { throw new \Exception("Expect $klass."); } } public static function checkRepeatedField(&$var, $type, $klass = null) { if (!$var instanceof RepeatedField && !is_array($var)) { throw new \Exception("Expect array."); } if (is_array($var)) { $tmp = new RepeatedField($type, $klass); foreach ($var as $value) { $tmp[] = $value; } return $tmp; } else { if ($var->getType() != $type) { throw new \Exception( "Expect repeated field of different type."); } if ($var->getType() === GPBType::MESSAGE && $var->getClass() !== $klass && $var->getLegacyClass() !== $klass) { throw new \Exception( "Expect repeated field of " . $klass . "."); } return $var; } } public static function checkMapField(&$var, $key_type, $value_type, $klass = null) { if (!$var instanceof MapField && !is_array($var)) { throw new \Exception("Expect dict."); } if (is_array($var)) { $tmp = new MapField($key_type, $value_type, $klass); foreach ($var as $key => $value) { $tmp[$key] = $value; } return $tmp; } else { if ($var->getKeyType() != $key_type) { throw new \Exception("Expect map field of key type."); } if ($var->getValueType() != $value_type) { throw new \Exception("Expect map field of value type."); } if ($var->getValueType() === GPBType::MESSAGE && $var->getValueClass() !== $klass && $var->getLegacyValueClass() !== $klass) { throw new \Exception( "Expect map field of " . $klass . "."); } return $var; } } public static function Int64($value) { return new Int64($value); } public static function Uint64($value) { return new Uint64($value); } public static function getClassNamePrefix( $classname, $file_proto) { $option = $file_proto->getOptions(); $prefix = is_null($option) ? "" : $option->getPhpClassPrefix(); if ($prefix !== "") { return $prefix; } $reserved_words = array( "abstract"=>0, "and"=>0, "array"=>0, "as"=>0, "break"=>0, "callable"=>0, "case"=>0, "catch"=>0, "class"=>0, "clone"=>0, "const"=>0, "continue"=>0, "declare"=>0, "default"=>0, "die"=>0, "do"=>0, "echo"=>0, "else"=>0, "elseif"=>0, "empty"=>0, "enddeclare"=>0, "endfor"=>0, "endforeach"=>0, "endif"=>0, "endswitch"=>0, "endwhile"=>0, "eval"=>0, "exit"=>0, "extends"=>0, "final"=>0, "finally"=>0, "fn"=>0, "for"=>0, "foreach"=>0, "function"=>0, "global"=>0, "goto"=>0, "if"=>0, "implements"=>0, "include"=>0, "include_once"=>0, "instanceof"=>0, "insteadof"=>0, "interface"=>0, "isset"=>0, "list"=>0, "match"=>0, "namespace"=>0, "new"=>0, "or"=>0, "parent"=>0, "print"=>0, "private"=>0, "protected"=>0,"public"=>0, "readonly" => 0,"require"=>0, "require_once"=>0,"return"=>0, "self"=>0, "static"=>0, "switch"=>0, "throw"=>0,"trait"=>0, "try"=>0,"unset"=>0, "use"=>0, "var"=>0, "while"=>0,"xor"=>0, "yield"=>0, "int"=>0, "float"=>0, "bool"=>0, "string"=>0,"true"=>0, "false"=>0, "null"=>0, "void"=>0, "iterable"=>0 ); if (array_key_exists(strtolower($classname), $reserved_words)) { if ($file_proto->getPackage() === "google.protobuf") { return "GPB"; } else { return "PB"; } } return ""; } private static function getPreviouslyUnreservedClassNamePrefix( $classname, $file_proto) { $previously_unreserved_words = array( "readonly"=>0 ); if (array_key_exists(strtolower($classname), $previously_unreserved_words)) { $option = $file_proto->getOptions(); $prefix = is_null($option) ? "" : $option->getPhpClassPrefix(); if ($prefix !== "") { return $prefix; } return ""; } return self::getClassNamePrefix($classname, $file_proto); } public static function getLegacyClassNameWithoutPackage( $name, $file_proto) { $classname = implode('_', explode('.', $name)); return static::getClassNamePrefix($classname, $file_proto) . $classname; } public static function getClassNameWithoutPackage( $name, $file_proto) { $parts = explode('.', $name); foreach ($parts as $i => $part) { $parts[$i] = static::getClassNamePrefix($parts[$i], $file_proto) . $parts[$i]; } return implode('\\', $parts); } private static function getPreviouslyUnreservedClassNameWithoutPackage( $name, $file_proto) { $parts = explode('.', $name); foreach ($parts as $i => $part) { $parts[$i] = static::getPreviouslyUnreservedClassNamePrefix($parts[$i], $file_proto) . $parts[$i]; } return implode('\\', $parts); } public static function getFullClassName( $proto, $containing, $file_proto, &$message_name_without_package, &$classname, &$legacy_classname, &$fullname, &$previous_classname) { // Full name needs to start with '.'. $message_name_without_package = $proto->getName(); if ($containing !== "") { $message_name_without_package = $containing . "." . $message_name_without_package; } $package = $file_proto->getPackage(); if ($package === "") { $fullname = $message_name_without_package; } else { $fullname = $package . "." . $message_name_without_package; } $class_name_without_package = static::getClassNameWithoutPackage($message_name_without_package, $file_proto); $legacy_class_name_without_package = static::getLegacyClassNameWithoutPackage( $message_name_without_package, $file_proto); $previous_class_name_without_package = static::getPreviouslyUnreservedClassNameWithoutPackage( $message_name_without_package, $file_proto); $option = $file_proto->getOptions(); if (!is_null($option) && $option->hasPhpNamespace()) { $namespace = $option->getPhpNamespace(); if ($namespace !== "") { $classname = $namespace . "\\" . $class_name_without_package; $legacy_classname = $namespace . "\\" . $legacy_class_name_without_package; $previous_classname = $namespace . "\\" . $previous_class_name_without_package; return; } else { $classname = $class_name_without_package; $legacy_classname = $legacy_class_name_without_package; $previous_classname = $previous_class_name_without_package; return; } } if ($package === "") { $classname = $class_name_without_package; $legacy_classname = $legacy_class_name_without_package; $previous_classname = $previous_class_name_without_package; } else { $parts = array_map('ucwords', explode('.', $package)); foreach ($parts as $i => $part) { $parts[$i] = self::getClassNamePrefix($part, $file_proto).$part; } $classname = implode('\\', $parts) . "\\".self::getClassNamePrefix($class_name_without_package,$file_proto). $class_name_without_package; $legacy_classname = implode('\\', array_map('ucwords', explode('.', $package))). "\\".$legacy_class_name_without_package; $previous_classname = implode('\\', array_map('ucwords', explode('.', $package))). "\\".self::getPreviouslyUnreservedClassNamePrefix( $previous_class_name_without_package, $file_proto). $previous_class_name_without_package; } } public static function combineInt32ToInt64($high, $low) { $isNeg = $high < 0; if ($isNeg) { $high = ~$high; $low = ~$low; $low++; if (!$low) { $high = (int) ($high + 1); } } $result = bcadd(bcmul($high, 4294967296), $low); if ($low < 0) { $result = bcadd($result, 4294967296); } if ($isNeg) { $result = bcsub(0, $result); } return $result; } public static function parseTimestamp($timestamp) { // prevent parsing timestamps containing with the non-existent year "0000" // DateTime::createFromFormat parses without failing but as a nonsensical date if (substr($timestamp, 0, 4) === "0000") { throw new \Exception("Year cannot be zero."); } // prevent parsing timestamps ending with a lowercase z if (substr($timestamp, -1, 1) === "z") { throw new \Exception("Timezone cannot be a lowercase z."); } $nanoseconds = 0; $periodIndex = strpos($timestamp, "."); if ($periodIndex !== false) { $nanosecondsLength = 0; // find the next non-numeric character in the timestamp to calculate // the length of the nanoseconds text for ($i = $periodIndex + 1, $length = strlen($timestamp); $i < $length; $i++) { if (!is_numeric($timestamp[$i])) { $nanosecondsLength = $i - ($periodIndex + 1); break; } } if ($nanosecondsLength % 3 !== 0) { throw new \Exception("Nanoseconds must be disible by 3."); } if ($nanosecondsLength > 9) { throw new \Exception("Nanoseconds must be in the range of 0 to 999,999,999 nanoseconds."); } if ($nanosecondsLength > 0) { $nanoseconds = substr($timestamp, $periodIndex + 1, $nanosecondsLength); $nanoseconds = intval($nanoseconds); if ($nanosecondsLength < 9) { $nanoseconds = $nanoseconds * pow(10, 9 - $nanosecondsLength); } // remove the nanoseconds and preceding period from the timestamp $date = substr($timestamp, 0, $periodIndex); $timezone = substr($timestamp, $periodIndex + $nanosecondsLength + 1); $timestamp = $date.$timezone; } } $date = \DateTime::createFromFormat(\DateTime::RFC3339, $timestamp, new \DateTimeZone("UTC")); if ($date === false) { throw new \Exception("Invalid RFC 3339 timestamp."); } $value = new \Google\Protobuf\Timestamp(); $seconds = $date->format("U"); $value->setSeconds($seconds); $value->setNanos($nanoseconds); return $value; } public static function formatTimestamp($value) { if (bccomp($value->getSeconds(), "253402300800") != -1) { throw new GPBDecodeException("Duration number too large."); } if (bccomp($value->getSeconds(), "-62135596801") != 1) { throw new GPBDecodeException("Duration number too small."); } $nanoseconds = static::getNanosecondsForTimestamp($value->getNanos()); if (!empty($nanoseconds)) { $nanoseconds = ".".$nanoseconds; } $date = new \DateTime('@'.$value->getSeconds(), new \DateTimeZone("UTC")); return $date->format("Y-m-d\TH:i:s".$nanoseconds."\Z"); } public static function parseDuration($value) { if (strlen($value) < 2 || substr($value, -1) !== "s") { throw new GPBDecodeException("Missing s after duration string"); } $number = substr($value, 0, -1); if (bccomp($number, "315576000001") != -1) { throw new GPBDecodeException("Duration number too large."); } if (bccomp($number, "-315576000001") != 1) { throw new GPBDecodeException("Duration number too small."); } $pos = strrpos($number, "."); if ($pos !== false) { $seconds = substr($number, 0, $pos); if (bccomp($seconds, 0) < 0) { $nanos = bcmul("0" . substr($number, $pos), -1000000000); } else { $nanos = bcmul("0" . substr($number, $pos), 1000000000); } } else { $seconds = $number; $nanos = 0; } $duration = new Duration(); $duration->setSeconds($seconds); $duration->setNanos($nanos); return $duration; } public static function formatDuration($value) { if (bccomp($value->getSeconds(), '315576000001') != -1) { throw new GPBDecodeException('Duration number too large.'); } if (bccomp($value->getSeconds(), '-315576000001') != 1) { throw new GPBDecodeException('Duration number too small.'); } $nanos = $value->getNanos(); if ($nanos === 0) { return (string) $value->getSeconds(); } if ($nanos % 1000000 === 0) { $digits = 3; } elseif ($nanos % 1000 === 0) { $digits = 6; } else { $digits = 9; } $nanos = bcdiv($nanos, '1000000000', $digits); return bcadd($value->getSeconds(), $nanos, $digits); } public static function parseFieldMask($paths_string) { $field_mask = new FieldMask(); if (strlen($paths_string) === 0) { return $field_mask; } $path_strings = explode(",", $paths_string); $paths = $field_mask->getPaths(); foreach($path_strings as &$path_string) { $field_strings = explode(".", $path_string); foreach($field_strings as &$field_string) { $field_string = camel2underscore($field_string); } $path_string = implode(".", $field_strings); $paths[] = $path_string; } return $field_mask; } public static function formatFieldMask($field_mask) { $converted_paths = []; foreach($field_mask->getPaths() as $path) { $fields = explode('.', $path); $converted_path = []; foreach ($fields as $field) { $segments = explode('_', $field); $start = true; $converted_segments = ""; foreach($segments as $segment) { if (!$start) { $converted = ucfirst($segment); } else { $converted = $segment; $start = false; } $converted_segments .= $converted; } $converted_path []= $converted_segments; } $converted_path = implode(".", $converted_path); $converted_paths []= $converted_path; } return implode(",", $converted_paths); } public static function getNanosecondsForTimestamp($nanoseconds) { if ($nanoseconds == 0) { return ''; } if ($nanoseconds % static::NANOS_PER_MILLISECOND == 0) { return sprintf('%03d', $nanoseconds / static::NANOS_PER_MILLISECOND); } if ($nanoseconds % static::NANOS_PER_MICROSECOND == 0) { return sprintf('%06d', $nanoseconds / static::NANOS_PER_MICROSECOND); } return sprintf('%09d', $nanoseconds); } public static function hasSpecialJsonMapping($msg) { return is_a($msg, 'Google\Protobuf\Any') || is_a($msg, "Google\Protobuf\ListValue") || is_a($msg, "Google\Protobuf\Struct") || is_a($msg, "Google\Protobuf\Value") || is_a($msg, "Google\Protobuf\Duration") || is_a($msg, "Google\Protobuf\Timestamp") || is_a($msg, "Google\Protobuf\FieldMask") || static::hasJsonValue($msg); } public static function hasJsonValue($msg) { return is_a($msg, "Google\Protobuf\DoubleValue") || is_a($msg, "Google\Protobuf\FloatValue") || is_a($msg, "Google\Protobuf\Int64Value") || is_a($msg, "Google\Protobuf\UInt64Value") || is_a($msg, "Google\Protobuf\Int32Value") || is_a($msg, "Google\Protobuf\UInt32Value") || is_a($msg, "Google\Protobuf\BoolValue") || is_a($msg, "Google\Protobuf\StringValue") || is_a($msg, "Google\Protobuf\BytesValue"); } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/GPBWire.php ================================================ > self::TAG_TYPE_BITS) & 0x1fffffff; } public static function getTagWireType($tag) { return $tag & 0x7; } public static function getWireType($type) { switch ($type) { case GPBType::FLOAT: case GPBType::FIXED32: case GPBType::SFIXED32: return self::WIRETYPE_FIXED32; case GPBType::DOUBLE: case GPBType::FIXED64: case GPBType::SFIXED64: return self::WIRETYPE_FIXED64; case GPBType::UINT32: case GPBType::UINT64: case GPBType::INT32: case GPBType::INT64: case GPBType::SINT32: case GPBType::SINT64: case GPBType::ENUM: case GPBType::BOOL: return self::WIRETYPE_VARINT; case GPBType::STRING: case GPBType::BYTES: case GPBType::MESSAGE: return self::WIRETYPE_LENGTH_DELIMITED; case GPBType::GROUP: user_error("Unsupported type."); return 0; default: user_error("Unsupported type."); return 0; } } // ZigZag Transform: Encodes signed integers so that they can be effectively // used with varint encoding. // // varint operates on unsigned integers, encoding smaller numbers into fewer // bytes. If you try to use it on a signed integer, it will treat this // number as a very large unsigned integer, which means that even small // signed numbers like -1 will take the maximum number of bytes (10) to // encode. zigZagEncode() maps signed integers to unsigned in such a way // that those with a small absolute value will have smaller encoded values, // making them appropriate for encoding using varint. // // int32 -> uint32 // ------------------------- // 0 -> 0 // -1 -> 1 // 1 -> 2 // -2 -> 3 // ... -> ... // 2147483647 -> 4294967294 // -2147483648 -> 4294967295 // // >> encode >> // << decode << public static function zigZagEncode32($int32) { if (PHP_INT_SIZE == 8) { $trim_int32 = $int32 & 0xFFFFFFFF; return (($trim_int32 << 1) ^ ($int32 << 32 >> 63)) & 0xFFFFFFFF; } else { return ($int32 << 1) ^ ($int32 >> 31); } } public static function zigZagDecode32($uint32) { // Fill high 32 bits. if (PHP_INT_SIZE === 8) { $uint32 |= ($uint32 & 0xFFFFFFFF); } $int32 = (($uint32 >> 1) & 0x7FFFFFFF) ^ (-($uint32 & 1)); return $int32; } public static function zigZagEncode64($int64) { if (PHP_INT_SIZE == 4) { if (bccomp($int64, 0) >= 0) { return bcmul($int64, 2); } else { return bcsub(bcmul(bcsub(0, $int64), 2), 1); } } else { return ((int)$int64 << 1) ^ ((int)$int64 >> 63); } } public static function zigZagDecode64($uint64) { if (PHP_INT_SIZE == 4) { if (bcmod($uint64, 2) == 0) { return bcdiv($uint64, 2, 0); } else { return bcsub(0, bcdiv(bcadd($uint64, 1), 2, 0)); } } else { return (($uint64 >> 1) & 0x7FFFFFFFFFFFFFFF) ^ (-($uint64 & 1)); } } public static function readInt32(&$input, &$value) { return $input->readVarint32($value); } public static function readInt64(&$input, &$value) { $success = $input->readVarint64($value); if (PHP_INT_SIZE == 4 && bccomp($value, "9223372036854775807") > 0) { $value = bcsub($value, "18446744073709551616"); } return $success; } public static function readUint32(&$input, &$value) { return self::readInt32($input, $value); } public static function readUint64(&$input, &$value) { return self::readInt64($input, $value); } public static function readSint32(&$input, &$value) { if (!$input->readVarint32($value)) { return false; } $value = GPBWire::zigZagDecode32($value); return true; } public static function readSint64(&$input, &$value) { if (!$input->readVarint64($value)) { return false; } $value = GPBWire::zigZagDecode64($value); return true; } public static function readFixed32(&$input, &$value) { return $input->readLittleEndian32($value); } public static function readFixed64(&$input, &$value) { return $input->readLittleEndian64($value); } public static function readSfixed32(&$input, &$value) { if (!self::readFixed32($input, $value)) { return false; } if (PHP_INT_SIZE === 8) { $value |= (-($value >> 31) << 32); } return true; } public static function readSfixed64(&$input, &$value) { $success = $input->readLittleEndian64($value); if (PHP_INT_SIZE == 4 && bccomp($value, "9223372036854775807") > 0) { $value = bcsub($value, "18446744073709551616"); } return $success; } public static function readFloat(&$input, &$value) { $data = null; if (!$input->readRaw(4, $data)) { return false; } $value = unpack('g', $data)[1]; return true; } public static function readDouble(&$input, &$value) { $data = null; if (!$input->readRaw(8, $data)) { return false; } $value = unpack('e', $data)[1]; return true; } public static function readBool(&$input, &$value) { if (!$input->readVarint64($value)) { return false; } if ($value == 0) { $value = false; } else { $value = true; } return true; } public static function readString(&$input, &$value) { $length = 0; return $input->readVarintSizeAsInt($length) && $input->readRaw($length, $value); } public static function readMessage(&$input, &$message) { $length = 0; if (!$input->readVarintSizeAsInt($length)) { return false; } $old_limit = 0; $recursion_limit = 0; $input->incrementRecursionDepthAndPushLimit( $length, $old_limit, $recursion_limit); if ($recursion_limit < 0 || !$message->parseFromStream($input)) { return false; } return $input->decrementRecursionDepthAndPopLimit($old_limit); } public static function writeTag(&$output, $tag) { return $output->writeTag($tag); } public static function writeInt32(&$output, $value) { return $output->writeVarint32($value, false); } public static function writeInt64(&$output, $value) { return $output->writeVarint64($value); } public static function writeUint32(&$output, $value) { return $output->writeVarint32($value, true); } public static function writeUint64(&$output, $value) { return $output->writeVarint64($value); } public static function writeSint32(&$output, $value) { $value = GPBWire::zigZagEncode32($value); return $output->writeVarint32($value, true); } public static function writeSint64(&$output, $value) { $value = GPBWire::zigZagEncode64($value); return $output->writeVarint64($value); } public static function writeFixed32(&$output, $value) { return $output->writeLittleEndian32($value); } public static function writeFixed64(&$output, $value) { return $output->writeLittleEndian64($value); } public static function writeSfixed32(&$output, $value) { return $output->writeLittleEndian32($value); } public static function writeSfixed64(&$output, $value) { return $output->writeLittleEndian64($value); } public static function writeBool(&$output, $value) { if ($value) { return $output->writeVarint32(1, true); } else { return $output->writeVarint32(0, true); } } public static function writeFloat(&$output, $value) { $data = pack("g", $value); return $output->writeRaw($data, 4); } public static function writeDouble(&$output, $value) { $data = pack("e", $value); return $output->writeRaw($data, 8); } public static function writeString(&$output, $value) { return self::writeBytes($output, $value); } public static function writeBytes(&$output, $value) { $size = strlen($value); if (!$output->writeVarint32($size, true)) { return false; } return $output->writeRaw($value, $size); } public static function writeMessage(&$output, $value) { $size = $value->byteSize(); if (!$output->writeVarint32($size, true)) { return false; } return $value->serializeToStream($output); } public static function makeTag($number, $type) { return ($number << 3) | self::getWireType($type); } public static function tagSize($field) { $tag = self::makeTag($field->getNumber(), $field->getType()); return self::varint32Size($tag); } public static function varint32Size($value, $sign_extended = false) { if ($value < 0) { if ($sign_extended) { return 10; } else { return 5; } } if ($value < (1 << 7)) { return 1; } if ($value < (1 << 14)) { return 2; } if ($value < (1 << 21)) { return 3; } if ($value < (1 << 28)) { return 4; } return 5; } public static function sint32Size($value) { $value = self::zigZagEncode32($value); return self::varint32Size($value); } public static function sint64Size($value) { $value = self::zigZagEncode64($value); return self::varint64Size($value); } public static function varint64Size($value) { if (PHP_INT_SIZE == 4) { if (bccomp($value, 0) < 0 || bccomp($value, "9223372036854775807") > 0) { return 10; } if (bccomp($value, 1 << 7) < 0) { return 1; } if (bccomp($value, 1 << 14) < 0) { return 2; } if (bccomp($value, 1 << 21) < 0) { return 3; } if (bccomp($value, 1 << 28) < 0) { return 4; } if (bccomp($value, '34359738368') < 0) { return 5; } if (bccomp($value, '4398046511104') < 0) { return 6; } if (bccomp($value, '562949953421312') < 0) { return 7; } if (bccomp($value, '72057594037927936') < 0) { return 8; } return 9; } else { if ($value < 0) { return 10; } if ($value < (1 << 7)) { return 1; } if ($value < (1 << 14)) { return 2; } if ($value < (1 << 21)) { return 3; } if ($value < (1 << 28)) { return 4; } if ($value < (1 << 35)) { return 5; } if ($value < (1 << 42)) { return 6; } if ($value < (1 << 49)) { return 7; } if ($value < (1 << 56)) { return 8; } return 9; } } public static function serializeFieldToStream( $value, $field, $need_tag, &$output) { if ($need_tag) { if (!GPBWire::writeTag( $output, self::makeTag( $field->getNumber(), $field->getType()))) { return false; } } switch ($field->getType()) { case GPBType::DOUBLE: if (!GPBWire::writeDouble($output, $value)) { return false; } break; case GPBType::FLOAT: if (!GPBWire::writeFloat($output, $value)) { return false; } break; case GPBType::INT64: if (!GPBWire::writeInt64($output, $value)) { return false; } break; case GPBType::UINT64: if (!GPBWire::writeUint64($output, $value)) { return false; } break; case GPBType::INT32: if (!GPBWire::writeInt32($output, $value)) { return false; } break; case GPBType::FIXED32: if (!GPBWire::writeFixed32($output, $value)) { return false; } break; case GPBType::FIXED64: if (!GPBWire::writeFixed64($output, $value)) { return false; } break; case GPBType::BOOL: if (!GPBWire::writeBool($output, $value)) { return false; } break; case GPBType::STRING: if (!GPBWire::writeString($output, $value)) { return false; } break; // case GPBType::GROUP: // echo "GROUP\xA"; // trigger_error("Not implemented.", E_ERROR); // break; case GPBType::MESSAGE: if (!GPBWire::writeMessage($output, $value)) { return false; } break; case GPBType::BYTES: if (!GPBWire::writeBytes($output, $value)) { return false; } break; case GPBType::UINT32: if (PHP_INT_SIZE === 8 && $value < 0) { $value += 4294967296; } if (!GPBWire::writeUint32($output, $value)) { return false; } break; case GPBType::ENUM: if (!GPBWire::writeInt32($output, $value)) { return false; } break; case GPBType::SFIXED32: if (!GPBWire::writeSfixed32($output, $value)) { return false; } break; case GPBType::SFIXED64: if (!GPBWire::writeSfixed64($output, $value)) { return false; } break; case GPBType::SINT32: if (!GPBWire::writeSint32($output, $value)) { return false; } break; case GPBType::SINT64: if (!GPBWire::writeSint64($output, $value)) { return false; } break; default: user_error("Unsupported type."); return false; } return true; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/GPBWireType.php ================================================ google.protobuf.GeneratedCodeInfo.Annotation.Semantic */ class Semantic { /** * There is no effect or the effect is indescribable. * * Generated from protobuf enum NONE = 0; */ const NONE = 0; /** * The element is set or otherwise mutated. * * Generated from protobuf enum SET = 1; */ const SET = 1; /** * An alias to the element is returned. * * Generated from protobuf enum ALIAS = 2; */ const ALIAS = 2; private static $valueToName = [ self::NONE => 'NONE', self::SET => 'SET', self::ALIAS => 'ALIAS', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/GeneratedCodeInfo/Annotation.php ================================================ google.protobuf.GeneratedCodeInfo.Annotation */ class Annotation extends \Google\Protobuf\Internal\Message { /** * Identifies the element in the original source .proto file. This field * is formatted the same as SourceCodeInfo.Location.path. * * Generated from protobuf field repeated int32 path = 1 [packed = true]; */ private $path; /** * Identifies the filesystem path to the original source .proto. * * Generated from protobuf field optional string source_file = 2; */ protected $source_file = null; /** * Identifies the starting offset in bytes in the generated code * that relates to the identified object. * * Generated from protobuf field optional int32 begin = 3; */ protected $begin = null; /** * Identifies the ending offset in bytes in the generated code that * relates to the identified object. The end offset should be one past * the last relevant byte (so the length of the text = end - begin). * * Generated from protobuf field optional int32 end = 4; */ protected $end = null; /** * Generated from protobuf field optional .google.protobuf.GeneratedCodeInfo.Annotation.Semantic semantic = 5; */ protected $semantic = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type int[] $path * Identifies the element in the original source .proto file. This field * is formatted the same as SourceCodeInfo.Location.path. * @type string $source_file * Identifies the filesystem path to the original source .proto. * @type int $begin * Identifies the starting offset in bytes in the generated code * that relates to the identified object. * @type int $end * Identifies the ending offset in bytes in the generated code that * relates to the identified object. The end offset should be one past * the last relevant byte (so the length of the text = end - begin). * @type int $semantic * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); parent::__construct($data); } /** * Identifies the element in the original source .proto file. This field * is formatted the same as SourceCodeInfo.Location.path. * * Generated from protobuf field repeated int32 path = 1 [packed = true]; * @return RepeatedField */ public function getPath() { return $this->path; } /** * Identifies the element in the original source .proto file. This field * is formatted the same as SourceCodeInfo.Location.path. * * Generated from protobuf field repeated int32 path = 1 [packed = true]; * @param int[] $var * @return $this */ public function setPath($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32); $this->path = $arr; return $this; } /** * Identifies the filesystem path to the original source .proto. * * Generated from protobuf field optional string source_file = 2; * @return string */ public function getSourceFile() { return isset($this->source_file) ? $this->source_file : ''; } public function hasSourceFile() { return isset($this->source_file); } public function clearSourceFile() { unset($this->source_file); } /** * Identifies the filesystem path to the original source .proto. * * Generated from protobuf field optional string source_file = 2; * @param string $var * @return $this */ public function setSourceFile($var) { GPBUtil::checkString($var, True); $this->source_file = $var; return $this; } /** * Identifies the starting offset in bytes in the generated code * that relates to the identified object. * * Generated from protobuf field optional int32 begin = 3; * @return int */ public function getBegin() { return isset($this->begin) ? $this->begin : 0; } public function hasBegin() { return isset($this->begin); } public function clearBegin() { unset($this->begin); } /** * Identifies the starting offset in bytes in the generated code * that relates to the identified object. * * Generated from protobuf field optional int32 begin = 3; * @param int $var * @return $this */ public function setBegin($var) { GPBUtil::checkInt32($var); $this->begin = $var; return $this; } /** * Identifies the ending offset in bytes in the generated code that * relates to the identified object. The end offset should be one past * the last relevant byte (so the length of the text = end - begin). * * Generated from protobuf field optional int32 end = 4; * @return int */ public function getEnd() { return isset($this->end) ? $this->end : 0; } public function hasEnd() { return isset($this->end); } public function clearEnd() { unset($this->end); } /** * Identifies the ending offset in bytes in the generated code that * relates to the identified object. The end offset should be one past * the last relevant byte (so the length of the text = end - begin). * * Generated from protobuf field optional int32 end = 4; * @param int $var * @return $this */ public function setEnd($var) { GPBUtil::checkInt32($var); $this->end = $var; return $this; } /** * Generated from protobuf field optional .google.protobuf.GeneratedCodeInfo.Annotation.Semantic semantic = 5; * @return int */ public function getSemantic() { return isset($this->semantic) ? $this->semantic : 0; } public function hasSemantic() { return isset($this->semantic); } public function clearSemantic() { unset($this->semantic); } /** * Generated from protobuf field optional .google.protobuf.GeneratedCodeInfo.Annotation.Semantic semantic = 5; * @param int $var * @return $this */ public function setSemantic($var) { GPBUtil::checkEnum($var, \Google\Protobuf\Internal\GeneratedCodeInfo\Annotation\Semantic::class); $this->semantic = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/GeneratedCodeInfo.php ================================================ google.protobuf.GeneratedCodeInfo */ class GeneratedCodeInfo extends \Google\Protobuf\Internal\Message { /** * An Annotation connects some span of text in generated code to an element * of its generating .proto file. * * Generated from protobuf field repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1; */ private $annotation; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type \Google\Protobuf\Internal\GeneratedCodeInfo\Annotation[] $annotation * An Annotation connects some span of text in generated code to an element * of its generating .proto file. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); parent::__construct($data); } /** * An Annotation connects some span of text in generated code to an element * of its generating .proto file. * * Generated from protobuf field repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1; * @return RepeatedField<\Google\Protobuf\Internal\GeneratedCodeInfo\Annotation> */ public function getAnnotation() { return $this->annotation; } /** * An Annotation connects some span of text in generated code to an element * of its generating .proto file. * * Generated from protobuf field repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1; * @param \Google\Protobuf\Internal\GeneratedCodeInfo\Annotation[] $var * @return $this */ public function setAnnotation($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\GeneratedCodeInfo\Annotation::class); $this->annotation = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/GetPublicDescriptorTrait.php ================================================ getPublicDescriptor(); } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/HasPublicDescriptorTrait.php ================================================ public_desc; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/MapEntry.php ================================================ getFieldByNumber(2); if ($value_field->getType() == GPBType::MESSAGE) { $klass = $value_field->getMessageType()->getClass(); $value = new $klass; $this->setValue($value); } } public function setKey($key) { $this->key = $key; } public function getKey() { return $this->key; } public function setValue($value) { $this->value = $value; } public function getValue() { return $this->value; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/MapField.php ================================================ container = []; $this->key_type = $key_type; $this->value_type = $value_type; $this->klass = $klass; if ($this->value_type == GPBType::MESSAGE) { $pool = DescriptorPool::getGeneratedPool(); $desc = $pool->getDescriptorByClassName($klass); if ($desc == NULL) { new $klass; // No msg class instance has been created before. $desc = $pool->getDescriptorByClassName($klass); } $this->klass = $desc->getClass(); $this->legacy_klass = $desc->getLegacyClass(); } } /** * @ignore */ public function getKeyType() { return $this->key_type; } /** * @ignore */ public function getValueType() { return $this->value_type; } /** * @ignore */ public function getValueClass() { return $this->klass; } /** * @ignore */ public function getLegacyValueClass() { return $this->legacy_klass; } /** * Return the element at the given key. * * This will also be called for: $ele = $arr[$key] * * @param int|string $key The key of the element to be fetched. * @return object The stored element at given key. * @throws \ErrorException Invalid type for index. * @throws \ErrorException Non-existing index. * @todo need to add return type mixed (require update php version to 8.0) */ #[\ReturnTypeWillChange] public function offsetGet($key) { return $this->container[$key]; } /** * Assign the element at the given key. * * This will also be called for: $arr[$key] = $value * * @param int|string $key The key of the element to be fetched. * @param object $value The element to be assigned. * @return void * @throws \ErrorException Invalid type for key. * @throws \ErrorException Invalid type for value. * @throws \ErrorException Non-existing key. * @todo need to add return type void (require update php version to 7.1) */ #[\ReturnTypeWillChange] public function offsetSet($key, $value) { $this->checkKey($this->key_type, $key); switch ($this->value_type) { case GPBType::SFIXED32: case GPBType::SINT32: case GPBType::INT32: case GPBType::ENUM: GPBUtil::checkInt32($value); break; case GPBType::FIXED32: case GPBType::UINT32: GPBUtil::checkUint32($value); break; case GPBType::SFIXED64: case GPBType::SINT64: case GPBType::INT64: GPBUtil::checkInt64($value); break; case GPBType::FIXED64: case GPBType::UINT64: GPBUtil::checkUint64($value); break; case GPBType::FLOAT: GPBUtil::checkFloat($value); break; case GPBType::DOUBLE: GPBUtil::checkDouble($value); break; case GPBType::BOOL: GPBUtil::checkBool($value); break; case GPBType::STRING: GPBUtil::checkString($value, true); break; case GPBType::MESSAGE: if (is_null($value)) { trigger_error("Map element cannot be null.", E_USER_ERROR); } GPBUtil::checkMessage($value, $this->klass); break; default: break; } $this->container[$key] = $value; } /** * Remove the element at the given key. * * This will also be called for: unset($arr) * * @param int|string $key The key of the element to be removed. * @return void * @throws \ErrorException Invalid type for key. * @todo need to add return type void (require update php version to 7.1) */ #[\ReturnTypeWillChange] public function offsetUnset($key) { $this->checkKey($this->key_type, $key); unset($this->container[$key]); } /** * Check the existence of the element at the given key. * * This will also be called for: isset($arr) * * @param int|string $key The key of the element to be removed. * @return bool True if the element at the given key exists. * @throws \ErrorException Invalid type for key. */ public function offsetExists($key): bool { $this->checkKey($this->key_type, $key); return isset($this->container[$key]); } /** * @ignore */ public function getIterator(): Traversable { return new MapFieldIter($this->container, $this->key_type); } /** * Return the number of stored elements. * * This will also be called for: count($arr) * * @return integer The number of stored elements. */ public function count(): int { return count($this->container); } /** * @ignore */ private function checkKey($key_type, &$key) { switch ($key_type) { case GPBType::SFIXED32: case GPBType::SINT32: case GPBType::INT32: GPBUtil::checkInt32($key); break; case GPBType::FIXED32: case GPBType::UINT32: GPBUtil::checkUint32($key); break; case GPBType::SFIXED64: case GPBType::SINT64: case GPBType::INT64: GPBUtil::checkInt64($key); break; case GPBType::FIXED64: case GPBType::UINT64: GPBUtil::checkUint64($key); break; case GPBType::BOOL: GPBUtil::checkBool($key); break; case GPBType::STRING: GPBUtil::checkString($key, true); break; default: trigger_error( "Given type cannot be map key.", E_USER_ERROR); break; } } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/MapFieldIter.php ================================================ container = $container; $this->key_type = $key_type; } /** * Reset the status of the iterator * * @return void * @todo need to add return type void (require update php version to 7.1) */ #[\ReturnTypeWillChange] public function rewind() { reset($this->container); } /** * Return the element at the current position. * * @return object The element at the current position. * @todo need to add return type mixed (require update php version to 8.0) */ #[\ReturnTypeWillChange] public function current() { return current($this->container); } /** * Return the current key. * * @return object The current key. * @todo need to add return type mixed (require update php version to 8.0) */ #[\ReturnTypeWillChange] public function key() { $key = key($this->container); switch ($this->key_type) { case GPBType::INT64: case GPBType::UINT64: case GPBType::FIXED64: case GPBType::SFIXED64: case GPBType::SINT64: if (PHP_INT_SIZE === 8) { return $key; } // Intentionally fall through case GPBType::STRING: // PHP associative array stores int string as int for key. return strval($key); case GPBType::BOOL: // PHP associative array stores bool as integer for key. return boolval($key); default: return $key; } } /** * Move to the next position. * * @return void * @todo need to add return type void (require update php version to 7.1) */ #[\ReturnTypeWillChange] public function next() { next($this->container); } /** * Check whether there are more elements to iterate. * * @return bool True if there are more elements to iterate. */ public function valid(): bool { return key($this->container) !== null; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/Message.php ================================================ initWithDescriptor($data); } else { $this->initWithGeneratedPool(); if (is_array($data)) { $this->mergeFromArray($data); } else if (!empty($data)) { throw new \InvalidArgumentException( 'Message constructor must be an array or null.' ); } } } /** * @ignore */ private function initWithGeneratedPool() { $pool = DescriptorPool::getGeneratedPool(); $this->desc = $pool->getDescriptorByClassName(get_class($this)); if (is_null($this->desc)) { throw new \InvalidArgumentException( get_class($this) ." is not found in descriptor pool. " . 'Only generated classes may derive from Message.'); } foreach ($this->desc->getField() as $field) { $setter = $field->getSetter(); if ($field->isMap()) { $message_type = $field->getMessageType(); $key_field = $message_type->getFieldByNumber(1); $value_field = $message_type->getFieldByNumber(2); switch ($value_field->getType()) { case GPBType::MESSAGE: case GPBType::GROUP: $map_field = new MapField( $key_field->getType(), $value_field->getType(), $value_field->getMessageType()->getClass()); $this->$setter($map_field); break; case GPBType::ENUM: $map_field = new MapField( $key_field->getType(), $value_field->getType(), $value_field->getEnumType()->getClass()); $this->$setter($map_field); break; default: $map_field = new MapField( $key_field->getType(), $value_field->getType()); $this->$setter($map_field); break; } } else if ($field->isRepeated()) { switch ($field->getType()) { case GPBType::MESSAGE: case GPBType::GROUP: $repeated_field = new RepeatedField( $field->getType(), $field->getMessageType()->getClass()); $this->$setter($repeated_field); break; case GPBType::ENUM: $repeated_field = new RepeatedField( $field->getType(), $field->getEnumType()->getClass()); $this->$setter($repeated_field); break; default: $repeated_field = new RepeatedField($field->getType()); $this->$setter($repeated_field); break; } } else if ($field->getOneofIndex() !== -1) { $oneof = $this->desc->getOneofDecl()[$field->getOneofIndex()]; $oneof_name = $oneof->getName(); $this->$oneof_name = new OneofField($oneof); } else if (!$field->isRequired() && !$field->isRepeated() && PHP_INT_SIZE == 4) { switch ($field->getType()) { case GPBType::INT64: case GPBType::UINT64: case GPBType::FIXED64: case GPBType::SFIXED64: case GPBType::SINT64: $this->$setter("0"); } } } } /** * @ignore */ private function initWithDescriptor(Descriptor $desc) { $this->desc = $desc; foreach ($desc->getField() as $field) { $setter = $field->getSetter(); $defaultValue = $this->defaultValue($field); $this->$setter($defaultValue); } } protected function readWrapperValue($member) { $field = $this->desc->getFieldByName($member); $oneof_index = $field->getOneofIndex(); if ($oneof_index === -1) { $wrapper = $this->$member; } else { $wrapper = $this->readOneof($field->getNumber()); } if (is_null($wrapper)) { return NULL; } else { return $wrapper->getValue(); } } protected function writeWrapperValue($member, $value) { $field = $this->desc->getFieldByName($member); $wrapped_value = $value; if (!is_null($value)) { $desc = $field->getMessageType(); $klass = $desc->getClass(); $wrapped_value = new $klass; $wrapped_value->setValue($value); } $oneof_index = $field->getOneofIndex(); if ($oneof_index === -1) { $this->$member = $wrapped_value; } else { $this->writeOneof($field->getNumber(), $wrapped_value); } } protected function readOneof($number) { $field = $this->desc->getFieldByNumber($number); $oneof = $this->desc->getOneofDecl()[$field->getOneofIndex()]; $oneof_name = $oneof->getName(); $oneof_field = $this->$oneof_name; if ($number === $oneof_field->getNumber()) { return $oneof_field->getValue(); } else { return $this->defaultValue($field); } } protected function hasOneof($number) { $field = $this->desc->getFieldByNumber($number); $oneof = $this->desc->getOneofDecl()[$field->getOneofIndex()]; $oneof_name = $oneof->getName(); $oneof_field = $this->$oneof_name; return $number === $oneof_field->getNumber(); } protected function writeOneof($number, $value) { $field = $this->desc->getFieldByNumber($number); $oneof = $this->desc->getOneofDecl()[$field->getOneofIndex()]; $oneof_name = $oneof->getName(); if ($value === null) { $this->$oneof_name = new OneofField($oneof); } else { $oneof_field = $this->$oneof_name; $oneof_field->setValue($value); $oneof_field->setFieldName($field->getName()); $oneof_field->setNumber($number); } } protected function whichOneof($oneof_name) { $oneof_field = $this->$oneof_name; $number = $oneof_field->getNumber(); if ($number == 0) { return ""; } $field = $this->desc->getFieldByNumber($number); return $field->getName(); } /** * @ignore */ private function defaultValue($field) { $value = null; switch ($field->getType()) { case GPBType::DOUBLE: case GPBType::FLOAT: return 0.0; case GPBType::UINT32: case GPBType::INT32: case GPBType::FIXED32: case GPBType::SFIXED32: case GPBType::SINT32: case GPBType::ENUM: return 0; case GPBType::INT64: case GPBType::UINT64: case GPBType::FIXED64: case GPBType::SFIXED64: case GPBType::SINT64: if (PHP_INT_SIZE === 4) { return '0'; } else { return 0; } case GPBType::BOOL: return false; case GPBType::STRING: case GPBType::BYTES: return ""; case GPBType::GROUP: case GPBType::MESSAGE: return null; default: user_error("Unsupported type."); return false; } } /** * @ignore */ private function skipField($input, $tag) { $number = GPBWire::getTagFieldNumber($tag); if ($number === 0) { throw new GPBDecodeException("Illegal field number zero."); } $start = $input->current(); switch (GPBWire::getTagWireType($tag)) { case GPBWireType::VARINT: $uint64 = 0; if (!$input->readVarint64($uint64)) { throw new GPBDecodeException( "Unexpected EOF inside varint."); } break; case GPBWireType::FIXED64: $uint64 = 0; if (!$input->readLittleEndian64($uint64)) { throw new GPBDecodeException( "Unexpected EOF inside fixed64."); } break; case GPBWireType::FIXED32: $uint32 = 0; if (!$input->readLittleEndian32($uint32)) { throw new GPBDecodeException( "Unexpected EOF inside fixed32."); } break; case GPBWireType::LENGTH_DELIMITED: $length = 0; if (!$input->readVarint32($length)) { throw new GPBDecodeException( "Unexpected EOF inside length."); } $data = NULL; if (!$input->readRaw($length, $data)) { throw new GPBDecodeException( "Unexpected EOF inside length delimited data."); } break; case GPBWireType::START_GROUP: case GPBWireType::END_GROUP: throw new GPBDecodeException("Unexpected wire type."); default: throw new GPBDecodeException("Unexpected wire type."); } $end = $input->current(); $bytes = str_repeat(chr(0), CodedOutputStream::MAX_VARINT64_BYTES); $size = CodedOutputStream::writeVarintToArray($tag, $bytes, true); $this->unknown .= substr($bytes, 0, $size) . $input->substr($start, $end); } /** * @ignore */ private static function parseFieldFromStreamNoTag($input, $field, &$value) { switch ($field->getType()) { case GPBType::DOUBLE: if (!GPBWire::readDouble($input, $value)) { throw new GPBDecodeException( "Unexpected EOF inside double field."); } break; case GPBType::FLOAT: if (!GPBWire::readFloat($input, $value)) { throw new GPBDecodeException( "Unexpected EOF inside float field."); } break; case GPBType::INT64: if (!GPBWire::readInt64($input, $value)) { throw new GPBDecodeException( "Unexpected EOF inside int64 field."); } break; case GPBType::UINT64: if (!GPBWire::readUint64($input, $value)) { throw new GPBDecodeException( "Unexpected EOF inside uint64 field."); } break; case GPBType::INT32: if (!GPBWire::readInt32($input, $value)) { throw new GPBDecodeException( "Unexpected EOF inside int32 field."); } break; case GPBType::FIXED64: if (!GPBWire::readFixed64($input, $value)) { throw new GPBDecodeException( "Unexpected EOF inside fixed64 field."); } break; case GPBType::FIXED32: if (!GPBWire::readFixed32($input, $value)) { throw new GPBDecodeException( "Unexpected EOF inside fixed32 field."); } break; case GPBType::BOOL: if (!GPBWire::readBool($input, $value)) { throw new GPBDecodeException( "Unexpected EOF inside bool field."); } break; case GPBType::STRING: // We don't check UTF-8 here; that will be validated by the // setter later. if (!GPBWire::readString($input, $value)) { throw new GPBDecodeException( "Unexpected EOF inside string field."); } break; case GPBType::GROUP: trigger_error("Not implemented.", E_USER_ERROR); break; case GPBType::MESSAGE: if ($field->isMap()) { $value = new MapEntry($field->getMessageType()); } else { $klass = $field->getMessageType()->getClass(); $value = new $klass; } if (!GPBWire::readMessage($input, $value)) { throw new GPBDecodeException( "Unexpected EOF inside message."); } break; case GPBType::BYTES: if (!GPBWire::readString($input, $value)) { throw new GPBDecodeException( "Unexpected EOF inside bytes field."); } break; case GPBType::UINT32: if (!GPBWire::readUint32($input, $value)) { throw new GPBDecodeException( "Unexpected EOF inside uint32 field."); } break; case GPBType::ENUM: // TODO: Check unknown enum value. if (!GPBWire::readInt32($input, $value)) { throw new GPBDecodeException( "Unexpected EOF inside enum field."); } break; case GPBType::SFIXED32: if (!GPBWire::readSfixed32($input, $value)) { throw new GPBDecodeException( "Unexpected EOF inside sfixed32 field."); } break; case GPBType::SFIXED64: if (!GPBWire::readSfixed64($input, $value)) { throw new GPBDecodeException( "Unexpected EOF inside sfixed64 field."); } break; case GPBType::SINT32: if (!GPBWire::readSint32($input, $value)) { throw new GPBDecodeException( "Unexpected EOF inside sint32 field."); } break; case GPBType::SINT64: if (!GPBWire::readSint64($input, $value)) { throw new GPBDecodeException( "Unexpected EOF inside sint64 field."); } break; default: user_error("Unsupported type."); return false; } return true; } /** * @ignore */ private function parseFieldFromStream($tag, $input, $field) { $value = null; if (is_null($field)) { $value_format = GPBWire::UNKNOWN; } elseif (GPBWire::getTagWireType($tag) === GPBWire::getWireType($field->getType())) { $value_format = GPBWire::NORMAL_FORMAT; } elseif ($field->isPackable() && GPBWire::getTagWireType($tag) === GPBWire::WIRETYPE_LENGTH_DELIMITED) { $value_format = GPBWire::PACKED_FORMAT; } else { // the wire type doesn't match. Put it in our unknown field set. $value_format = GPBWire::UNKNOWN; } if ($value_format === GPBWire::UNKNOWN) { $this->skipField($input, $tag); return; } elseif ($value_format === GPBWire::NORMAL_FORMAT) { self::parseFieldFromStreamNoTag($input, $field, $value); } elseif ($value_format === GPBWire::PACKED_FORMAT) { $length = 0; if (!GPBWire::readInt32($input, $length)) { throw new GPBDecodeException( "Unexpected EOF inside packed length."); } $limit = $input->pushLimit($length); $getter = $field->getGetter(); while ($input->bytesUntilLimit() > 0) { self::parseFieldFromStreamNoTag($input, $field, $value); $this->appendHelper($field, $value); } $input->popLimit($limit); return; } else { return; } if ($field->isMap()) { $this->kvUpdateHelper($field, $value->getKey(), $value->getValue()); } else if ($field->isRepeated()) { $this->appendHelper($field, $value); } else { $setter = $field->getSetter(); $this->$setter($value); } } /** * Clear all containing fields. * @return null */ public function clear() { $this->unknown = ""; foreach ($this->desc->getField() as $field) { $setter = $field->getSetter(); if ($field->isMap()) { $message_type = $field->getMessageType(); $key_field = $message_type->getFieldByNumber(1); $value_field = $message_type->getFieldByNumber(2); switch ($value_field->getType()) { case GPBType::MESSAGE: case GPBType::GROUP: $map_field = new MapField( $key_field->getType(), $value_field->getType(), $value_field->getMessageType()->getClass()); $this->$setter($map_field); break; case GPBType::ENUM: $map_field = new MapField( $key_field->getType(), $value_field->getType(), $value_field->getEnumType()->getClass()); $this->$setter($map_field); break; default: $map_field = new MapField( $key_field->getType(), $value_field->getType()); $this->$setter($map_field); break; } } else if ($field->isRepeated()) { switch ($field->getType()) { case GPBType::MESSAGE: case GPBType::GROUP: $repeated_field = new RepeatedField( $field->getType(), $field->getMessageType()->getClass()); $this->$setter($repeated_field); break; case GPBType::ENUM: $repeated_field = new RepeatedField( $field->getType(), $field->getEnumType()->getClass()); $this->$setter($repeated_field); break; default: $repeated_field = new RepeatedField($field->getType()); $this->$setter($repeated_field); break; } } else if ($field->getOneofIndex() !== -1) { $oneof = $this->desc->getOneofDecl()[$field->getOneofIndex()]; $oneof_name = $oneof->getName(); $this->$oneof_name = new OneofField($oneof); } else if (!$field->isRequired() && !$field->isRepeated()) { switch ($field->getType()) { case GPBType::DOUBLE : case GPBType::FLOAT : $this->$setter(0.0); break; case GPBType::INT32 : case GPBType::FIXED32 : case GPBType::UINT32 : case GPBType::SFIXED32 : case GPBType::SINT32 : case GPBType::ENUM : $this->$setter(0); break; case GPBType::BOOL : $this->$setter(false); break; case GPBType::STRING : case GPBType::BYTES : $this->$setter(""); break; case GPBType::GROUP : case GPBType::MESSAGE : $null = null; $this->$setter($null); break; } if (PHP_INT_SIZE == 4) { switch ($field->getType()) { case GPBType::INT64: case GPBType::UINT64: case GPBType::FIXED64: case GPBType::SFIXED64: case GPBType::SINT64: $this->$setter("0"); } } else { switch ($field->getType()) { case GPBType::INT64: case GPBType::UINT64: case GPBType::FIXED64: case GPBType::SFIXED64: case GPBType::SINT64: $this->$setter(0); } } } } } /** * Clear all unknown fields previously parsed. * @return null */ public function discardUnknownFields() { $this->unknown = ""; foreach ($this->desc->getField() as $field) { if ($field->getType() != GPBType::MESSAGE) { continue; } if ($field->isMap()) { $value_field = $field->getMessageType()->getFieldByNumber(2); if ($value_field->getType() != GPBType::MESSAGE) { continue; } $getter = $field->getGetter(); $map = $this->$getter(); foreach ($map as $key => $value) { $value->discardUnknownFields(); } } else if ($field->isRepeated()) { $getter = $field->getGetter(); $arr = $this->$getter(); foreach ($arr as $sub) { $sub->discardUnknownFields(); } } else if (!$field->isRequired() && !$field->isRepeated()) { $getter = $field->getGetter(); $sub = $this->$getter(); if (!is_null($sub)) { $sub->discardUnknownFields(); } } } } /** * Merges the contents of the specified message into current message. * * This method merges the contents of the specified message into the * current message. Singular fields that are set in the specified message * overwrite the corresponding fields in the current message. Repeated * fields are appended. Map fields key-value pairs are overwritten. * Singular/Oneof sub-messages are recursively merged. All overwritten * sub-messages are deep-copied. * * @param object $msg Protobuf message to be merged from. * @return null */ public function mergeFrom($msg) { if (get_class($this) !== get_class($msg)) { user_error("Cannot merge messages with different class."); return; } foreach ($this->desc->getField() as $field) { $setter = $field->getSetter(); $getter = $field->getGetter(); if ($field->isMap()) { if (count($msg->$getter()) != 0) { $value_field = $field->getMessageType()->getFieldByNumber(2); foreach ($msg->$getter() as $key => $value) { if ($value_field->getType() == GPBType::MESSAGE) { $klass = $value_field->getMessageType()->getClass(); $copy = new $klass; $copy->mergeFrom($value); $this->kvUpdateHelper($field, $key, $copy); } else { $this->kvUpdateHelper($field, $key, $value); } } } } else if ($field->isRepeated()) { if (count($msg->$getter()) != 0) { foreach ($msg->$getter() as $tmp) { if ($field->getType() == GPBType::MESSAGE) { $klass = $field->getMessageType()->getClass(); $copy = new $klass; $copy->mergeFrom($tmp); $this->appendHelper($field, $copy); } else { $this->appendHelper($field, $tmp); } } } } else if (!$field->isRequired() && !$field->isRepeated()) { if($msg->$getter() !== $this->defaultValue($field)) { $tmp = $msg->$getter(); if ($field->getType() == GPBType::MESSAGE) { if (is_null($this->$getter())) { $klass = $field->getMessageType()->getClass(); $new_msg = new $klass; $this->$setter($new_msg); } $this->$getter()->mergeFrom($tmp); } else { $this->$setter($tmp); } } } } } /** * Parses a protocol buffer contained in a string. * * This function takes a string in the (non-human-readable) binary wire * format, matching the encoding output by serializeToString(). * See mergeFrom() for merging behavior, if the field is already set in the * specified message. * * @param string $data Binary protobuf data. * @return null * @throws \Exception Invalid data. */ public function mergeFromString($data) { $input = new CodedInputStream($data); $this->parseFromStream($input); } /** * Parses a json string to protobuf message. * * This function takes a string in the json wire format, matching the * encoding output by serializeToJsonString(). * See mergeFrom() for merging behavior, if the field is already set in the * specified message. * * @param string $data Json protobuf data. * @param bool $ignore_unknown * @return null * @throws \Exception Invalid data. */ public function mergeFromJsonString($data, $ignore_unknown = false) { $input = new RawInputStream($data); $this->parseFromJsonStream($input, $ignore_unknown); } /** * @ignore */ public function parseFromStream($input) { while (true) { $tag = $input->readTag(); // End of input. This is a valid place to end, so return true. if ($tag === 0) { return true; } $number = GPBWire::getTagFieldNumber($tag); $field = $this->desc->getFieldByNumber($number); $this->parseFieldFromStream($tag, $input, $field); } } private function convertJsonValueToProtoValue( $value, $field, $ignore_unknown, $is_map_key = false) { switch ($field->getType()) { case GPBType::MESSAGE: $klass = $field->getMessageType()->getClass(); $submsg = new $klass; if (is_a($submsg, "Google\Protobuf\Duration")) { if (is_null($value)) { return $this->defaultValue($field); } else if (!is_string($value)) { throw new GPBDecodeException("Expect string."); } return GPBUtil::parseDuration($value); } else if ($field->isTimestamp()) { if (is_null($value)) { return $this->defaultValue($field); } else if (!is_string($value)) { throw new GPBDecodeException("Expect string."); } try { $timestamp = GPBUtil::parseTimestamp($value); } catch (\Exception $e) { throw new GPBDecodeException( "Invalid RFC 3339 timestamp: ".$e->getMessage()); } $submsg->setSeconds($timestamp->getSeconds()); $submsg->setNanos($timestamp->getNanos()); } else if (is_a($submsg, "Google\Protobuf\FieldMask")) { if (is_null($value)) { return $this->defaultValue($field); } try { return GPBUtil::parseFieldMask($value); } catch (\Exception $e) { throw new GPBDecodeException( "Invalid FieldMask: ".$e->getMessage()); } } else { if (is_null($value) && !is_a($submsg, "Google\Protobuf\Value")) { return $this->defaultValue($field); } if (GPBUtil::hasSpecialJsonMapping($submsg)) { } elseif (!is_object($value) && !is_array($value)) { throw new GPBDecodeException("Expect message."); } $submsg->mergeFromJsonArray($value, $ignore_unknown); } return $submsg; case GPBType::ENUM: if (is_null($value)) { return $this->defaultValue($field); } if (is_integer($value)) { return $value; } $enum_value = $field->getEnumType()->getValueByName($value); if (!is_null($enum_value)) { return $enum_value->getNumber(); } else if ($ignore_unknown) { return $this->defaultValue($field); } else { throw new GPBDecodeException( "Enum field only accepts integer or enum value name"); } case GPBType::STRING: if (is_null($value)) { return $this->defaultValue($field); } if (is_numeric($value)) { return strval($value); } if (!is_string($value)) { throw new GPBDecodeException( "String field only accepts string value"); } return $value; case GPBType::BYTES: if (is_null($value)) { return $this->defaultValue($field); } if (!is_string($value)) { throw new GPBDecodeException( "Byte field only accepts string value"); } $proto_value = base64_decode($value, true); if ($proto_value === false) { throw new GPBDecodeException("Invalid base64 characters"); } return $proto_value; case GPBType::BOOL: if (is_null($value)) { return $this->defaultValue($field); } if ($is_map_key) { if ($value === "true") { return true; } if ($value === "false") { return false; } throw new GPBDecodeException( "Bool field only accepts bool value"); } if (!is_bool($value)) { throw new GPBDecodeException( "Bool field only accepts bool value"); } return $value; case GPBType::FLOAT: case GPBType::DOUBLE: if (is_null($value)) { return $this->defaultValue($field); } if ($value === "Infinity") { return INF; } if ($value === "-Infinity") { return -INF; } if ($value === "NaN") { return NAN; } return $value; case GPBType::INT32: case GPBType::SINT32: case GPBType::SFIXED32: if (is_null($value)) { return $this->defaultValue($field); } if (!is_numeric($value)) { throw new GPBDecodeException( "Invalid data type for int32 field"); } if (is_string($value) && trim($value) !== $value) { throw new GPBDecodeException( "Invalid data type for int32 field"); } if (bccomp($value, "2147483647") > 0) { throw new GPBDecodeException( "Int32 too large"); } if (bccomp($value, "-2147483648") < 0) { throw new GPBDecodeException( "Int32 too small"); } return $value; case GPBType::UINT32: case GPBType::FIXED32: if (is_null($value)) { return $this->defaultValue($field); } if (!is_numeric($value)) { throw new GPBDecodeException( "Invalid data type for uint32 field"); } if (is_string($value) && trim($value) !== $value) { throw new GPBDecodeException( "Invalid data type for int32 field"); } if (bccomp($value, 4294967295) > 0) { throw new GPBDecodeException( "Uint32 too large"); } return $value; case GPBType::INT64: case GPBType::SINT64: case GPBType::SFIXED64: if (is_null($value)) { return $this->defaultValue($field); } if (!is_numeric($value)) { throw new GPBDecodeException( "Invalid data type for int64 field"); } if (is_string($value) && trim($value) !== $value) { throw new GPBDecodeException( "Invalid data type for int64 field"); } if (bccomp($value, "9223372036854775807") > 0) { throw new GPBDecodeException( "Int64 too large"); } if (bccomp($value, "-9223372036854775808") < 0) { throw new GPBDecodeException( "Int64 too small"); } return $value; case GPBType::UINT64: case GPBType::FIXED64: if (is_null($value)) { return $this->defaultValue($field); } if (!is_numeric($value)) { throw new GPBDecodeException( "Invalid data type for int64 field"); } if (is_string($value) && trim($value) !== $value) { throw new GPBDecodeException( "Invalid data type for int64 field"); } if (bccomp($value, "18446744073709551615") > 0) { throw new GPBDecodeException( "Uint64 too large"); } if (bccomp($value, "9223372036854775807") > 0) { $value = bcsub($value, "18446744073709551616"); } return $value; default: return $value; } } /** * Populates the message from a user-supplied PHP array. Array keys * correspond to Message properties and nested message properties. * * Example: * ``` * $message->mergeFromArray([ * 'name' => 'This is a message name', * 'interval' => [ * 'startTime' => time() - 60, * 'endTime' => time(), * ] * ]); * ``` * * This method will trigger an error if it is passed data that cannot * be converted to the correct type. For example, a StringValue field * must receive data that is either a string or a StringValue object. * * @param array $array An array containing message properties and values. * @return null */ protected function mergeFromArray(array $array) { // Just call the setters for the field names foreach ($array as $key => $value) { $field = $this->desc->getFieldByName($key); if (is_null($field)) { throw new \UnexpectedValueException( 'Invalid message property: ' . $key); } $setter = $field->getSetter(); if ($field->isMap()) { $valueField = $field->getMessageType()->getFieldByName('value'); if (!is_null($valueField) && $valueField->isWrapperType()) { self::normalizeArrayElementsToMessageType($value, $valueField->getMessageType()->getClass()); } } elseif ($field->isWrapperType()) { $class = $field->getMessageType()->getClass(); if ($field->isRepeated()) { self::normalizeArrayElementsToMessageType($value, $class); } else { self::normalizeToMessageType($value, $class); } } $this->$setter($value); } } /** * Tries to normalize the elements in $value into a provided protobuf * wrapper type $class. If $value is any type other than array, we do * not do any conversion, and instead rely on the existing protobuf * type checking. If $value is an array, we process each element and * try to convert it to an instance of $class. * * @param mixed $value The array of values to normalize. * @param string $class The expected wrapper class name */ private static function normalizeArrayElementsToMessageType(&$value, $class) { if (!is_array($value)) { // In the case that $value is not an array, we do not want to // attempt any conversion. Note that this includes the cases // when $value is a RepeatedField of MapField. In those cases, // we do not need to convert the elements, as they should // already be the correct types. return; } else { // Normalize each element in the array. foreach ($value as $key => &$elementValue) { self::normalizeToMessageType($elementValue, $class); } } } /** * Tries to normalize $value into a provided protobuf wrapper type $class. * If $value is any type other than an object, we attempt to construct an * instance of $class and assign $value to it using the setValue method * shared by all wrapper types. * * This method will raise an error if it receives a type that cannot be * assigned to the wrapper type via setValue. * * @param mixed $value The value to normalize. * @param string $class The expected wrapper class name */ private static function normalizeToMessageType(&$value, $class) { if (is_null($value) || is_object($value)) { // This handles the case that $value is an instance of $class. We // choose not to do any more strict checking here, relying on the // existing type checking done by GPBUtil. return; } else { // Try to instantiate $class and set the value try { $msg = new $class; $msg->setValue($value); $value = $msg; return; } catch (\Exception $exception) { trigger_error( "Error normalizing value to type '$class': " . $exception->getMessage(), E_USER_ERROR ); } } } protected function mergeFromJsonArray($array, $ignore_unknown) { if (is_a($this, "Google\Protobuf\Any")) { $this->clear(); $this->setTypeUrl($array["@type"]); $msg = $this->unpack(); if (GPBUtil::hasSpecialJsonMapping($msg)) { $msg->mergeFromJsonArray($array["value"], $ignore_unknown); } else { unset($array["@type"]); $msg->mergeFromJsonArray($array, $ignore_unknown); } $this->setValue($msg->serializeToString()); return; } if (is_a($this, "Google\Protobuf\DoubleValue") || is_a($this, "Google\Protobuf\FloatValue") || is_a($this, "Google\Protobuf\Int64Value") || is_a($this, "Google\Protobuf\UInt64Value") || is_a($this, "Google\Protobuf\Int32Value") || is_a($this, "Google\Protobuf\UInt32Value") || is_a($this, "Google\Protobuf\BoolValue") || is_a($this, "Google\Protobuf\StringValue")) { $this->setValue($array); return; } if (is_a($this, "Google\Protobuf\BytesValue")) { $this->setValue(base64_decode($array)); return; } if (is_a($this, "Google\Protobuf\Duration")) { $this->mergeFrom(GPBUtil::parseDuration($array)); return; } if (is_a($this, "Google\Protobuf\FieldMask")) { $this->mergeFrom(GPBUtil::parseFieldMask($array)); return; } if (is_a($this, "Google\Protobuf\Timestamp")) { $this->mergeFrom(GPBUtil::parseTimestamp($array)); return; } if (is_a($this, "Google\Protobuf\Struct")) { $fields = $this->getFields(); foreach($array as $key => $value) { $v = new Value(); $v->mergeFromJsonArray($value, $ignore_unknown); $fields[$key] = $v; } return; } if (is_a($this, "Google\Protobuf\Value")) { if (is_bool($array)) { $this->setBoolValue($array); } elseif (is_string($array)) { $this->setStringValue($array); } elseif (is_null($array)) { $this->setNullValue(0); } elseif (is_double($array) || is_integer($array)) { $this->setNumberValue($array); } elseif (is_array($array)) { if (array_values($array) !== $array) { // Associative array $struct_value = $this->getStructValue(); if (is_null($struct_value)) { $struct_value = new Struct(); $this->setStructValue($struct_value); } foreach ($array as $key => $v) { $value = new Value(); $value->mergeFromJsonArray($v, $ignore_unknown); $values = $struct_value->getFields(); $values[$key]= $value; } } else { // Array $list_value = $this->getListValue(); if (is_null($list_value)) { $list_value = new ListValue(); $this->setListValue($list_value); } foreach ($array as $v) { $value = new Value(); $value->mergeFromJsonArray($v, $ignore_unknown); $values = $list_value->getValues(); $values[]= $value; } } } else { throw new GPBDecodeException("Invalid type for Value."); } return; } $this->mergeFromArrayJsonImpl($array, $ignore_unknown); } private function mergeFromArrayJsonImpl($array, $ignore_unknown) { foreach ($array as $key => $value) { $field = $this->desc->getFieldByJsonName($key); if (is_null($field)) { $field = $this->desc->getFieldByName($key); if (is_null($field)) { if ($ignore_unknown) { continue; } else { throw new GPBDecodeException( $key . ' is unknown.' ); } } } if ($field->isMap()) { if (is_null($value)) { continue; } $key_field = $field->getMessageType()->getFieldByNumber(1); $value_field = $field->getMessageType()->getFieldByNumber(2); foreach ($value as $tmp_key => $tmp_value) { if (is_null($tmp_value)) { throw new \Exception( "Map value field element cannot be null."); } $proto_key = $this->convertJsonValueToProtoValue( $tmp_key, $key_field, $ignore_unknown, true); $proto_value = $this->convertJsonValueToProtoValue( $tmp_value, $value_field, $ignore_unknown); // Mapped unknown enum string values should be silently // ignored if ignore_unknown is set. if ($value_field->getType() == GPBType::ENUM && is_string($tmp_value) && is_null( $value_field->getEnumType()->getValueByName($tmp_value) ) && $ignore_unknown) { continue; } self::kvUpdateHelper($field, $proto_key, $proto_value); } } else if ($field->isRepeated()) { if (is_null($value)) { continue; } foreach ($value as $tmp) { if (is_null($tmp)) { throw new \Exception( "Repeated field elements cannot be null."); } $proto_value = $this->convertJsonValueToProtoValue( $tmp, $field, $ignore_unknown); // Repeated unknown enum string values should be silently // ignored if ignore_unknown is set. if ($field->getType() == GPBType::ENUM && is_string($tmp) && is_null($field->getEnumType()->getValueByName($tmp)) && $ignore_unknown) { continue; } self::appendHelper($field, $proto_value); } } else { $setter = $field->getSetter(); $proto_value = $this->convertJsonValueToProtoValue( $value, $field, $ignore_unknown); if ($field->getType() === GPBType::MESSAGE) { if (is_null($proto_value)) { continue; } $getter = $field->getGetter(); $submsg = $this->$getter(); if (!is_null($submsg)) { $submsg->mergeFrom($proto_value); continue; } } $this->$setter($proto_value); } } } /** * @ignore */ public function parseFromJsonStream($input, $ignore_unknown) { $array = json_decode($input->getData(), true, 512, JSON_BIGINT_AS_STRING); if ($this instanceof \Google\Protobuf\ListValue) { $array = ["values"=>$array]; } if (is_null($array)) { if ($this instanceof \Google\Protobuf\Value) { $this->setNullValue(\Google\Protobuf\NullValue::NULL_VALUE); return; } else { throw new GPBDecodeException( "Cannot decode json string: " . $input->getData()); } } try { $this->mergeFromJsonArray($array, $ignore_unknown); } catch (\Exception $e) { throw new GPBDecodeException($e->getMessage(), $e->getCode(), $e); } } /** * @ignore */ private function serializeSingularFieldToStream($field, &$output) { if (!$this->existField($field)) { return true; } $getter = $field->getGetter(); $value = $this->$getter(); if (!GPBWire::serializeFieldToStream($value, $field, true, $output)) { return false; } return true; } /** * @ignore */ private function serializeRepeatedFieldToStream($field, &$output) { $getter = $field->getGetter(); $values = $this->$getter(); $count = count($values); if ($count === 0) { return true; } $packed = $field->getPacked(); if ($packed) { if (!GPBWire::writeTag( $output, GPBWire::makeTag($field->getNumber(), GPBType::STRING))) { return false; } $size = 0; foreach ($values as $value) { $size += $this->fieldDataOnlyByteSize($field, $value); } if (!$output->writeVarint32($size, true)) { return false; } } foreach ($values as $value) { if (!GPBWire::serializeFieldToStream( $value, $field, !$packed, $output)) { return false; } } return true; } /** * @ignore */ private function serializeMapFieldToStream($field, $output) { $getter = $field->getGetter(); $values = $this->$getter(); $count = count($values); if ($count === 0) { return true; } foreach ($values as $key => $value) { $map_entry = new MapEntry($field->getMessageType()); $map_entry->setKey($key); $map_entry->setValue($value); if (!GPBWire::serializeFieldToStream( $map_entry, $field, true, $output)) { return false; } } return true; } /** * @ignore */ private function serializeFieldToStream(&$output, $field) { if ($field->isMap()) { return $this->serializeMapFieldToStream($field, $output); } elseif ($field->isRepeated()) { return $this->serializeRepeatedFieldToStream($field, $output); } else { return $this->serializeSingularFieldToStream($field, $output); } } /** * @ignore */ private function serializeFieldToJsonStream(&$output, $field) { $getter = $field->getGetter(); $values = $this->$getter(); return GPBJsonWire::serializeFieldToStream( $values, $field, $output, !GPBUtil::hasSpecialJsonMapping($this)); } /** * @ignore */ public function serializeToStream(&$output) { $fields = $this->desc->getField(); foreach ($fields as $field) { if (!$this->serializeFieldToStream($output, $field)) { return false; } } $output->writeRaw($this->unknown, strlen($this->unknown)); return true; } /** * @ignore */ public function serializeToJsonStream(&$output) { if (is_a($this, 'Google\Protobuf\Any')) { $output->writeRaw("{", 1); $type_field = $this->desc->getFieldByNumber(1); $value_msg = $this->unpack(); // Serialize type url. $output->writeRaw("\"@type\":", 8); $output->writeRaw("\"", 1); $output->writeRaw($this->getTypeUrl(), strlen($this->getTypeUrl())); $output->writeRaw("\"", 1); // Serialize value if (GPBUtil::hasSpecialJsonMapping($value_msg)) { $output->writeRaw(",\"value\":", 9); $value_msg->serializeToJsonStream($output); } else { $value_fields = $value_msg->desc->getField(); foreach ($value_fields as $field) { if ($value_msg->existField($field)) { $output->writeRaw(",", 1); if (!$value_msg->serializeFieldToJsonStream($output, $field)) { return false; } } } } $output->writeRaw("}", 1); } elseif (is_a($this, 'Google\Protobuf\FieldMask')) { $field_mask = GPBUtil::formatFieldMask($this); $output->writeRaw("\"", 1); $output->writeRaw($field_mask, strlen($field_mask)); $output->writeRaw("\"", 1); } elseif (is_a($this, 'Google\Protobuf\Duration')) { $duration = GPBUtil::formatDuration($this) . "s"; $output->writeRaw("\"", 1); $output->writeRaw($duration, strlen($duration)); $output->writeRaw("\"", 1); } elseif (get_class($this) === 'Google\Protobuf\Timestamp') { $timestamp = GPBUtil::formatTimestamp($this); $timestamp = json_encode($timestamp); $output->writeRaw($timestamp, strlen($timestamp)); } elseif (get_class($this) === 'Google\Protobuf\ListValue') { $field = $this->desc->getField()[1]; if (!$this->existField($field)) { $output->writeRaw("[]", 2); } else { if (!$this->serializeFieldToJsonStream($output, $field)) { return false; } } } elseif (get_class($this) === 'Google\Protobuf\Struct') { $field = $this->desc->getField()[1]; if (!$this->existField($field)) { $output->writeRaw("{}", 2); } else { if (!$this->serializeFieldToJsonStream($output, $field)) { return false; } } } else { if (!GPBUtil::hasSpecialJsonMapping($this)) { $output->writeRaw("{", 1); } $fields = $this->desc->getField(); $first = true; foreach ($fields as $field) { if ($this->existField($field) || GPBUtil::hasJsonValue($this)) { if ($first) { $first = false; } else { $output->writeRaw(",", 1); } if (!$this->serializeFieldToJsonStream($output, $field)) { return false; } } } if (!GPBUtil::hasSpecialJsonMapping($this)) { $output->writeRaw("}", 1); } } return true; } /** * Serialize the message to string. * @return string Serialized binary protobuf data. */ public function serializeToString() { $output = new CodedOutputStream($this->byteSize()); $this->serializeToStream($output); return $output->getData(); } /** * Serialize the message to json string. * @return string Serialized json protobuf data. */ public function serializeToJsonString($options = 0) { $output = new CodedOutputStream($this->jsonByteSize($options), $options); $this->serializeToJsonStream($output); return $output->getData(); } /** * @ignore */ private function existField($field) { $getter = $field->getGetter(); $hazzer = "has" . substr($getter, 3); if (method_exists($this, $hazzer)) { return $this->$hazzer(); } else if ($field->getOneofIndex() !== -1) { // For old generated code, which does not have hazzers for oneof // fields. $oneof = $this->desc->getOneofDecl()[$field->getOneofIndex()]; $oneof_name = $oneof->getName(); return $this->$oneof_name->getNumber() === $field->getNumber(); } $values = $this->$getter(); if ($field->isMap()) { return count($values) !== 0; } elseif ($field->isRepeated()) { return count($values) !== 0; } else { return $values !== $this->defaultValue($field); } } /** * @ignore */ private function repeatedFieldDataOnlyByteSize($field) { $size = 0; $getter = $field->getGetter(); $values = $this->$getter(); $count = count($values); if ($count !== 0) { $size += $count * GPBWire::tagSize($field); foreach ($values as $value) { $size += $this->singularFieldDataOnlyByteSize($field); } } } /** * @ignore */ private function fieldDataOnlyByteSize($field, $value) { $size = 0; switch ($field->getType()) { case GPBType::BOOL: $size += 1; break; case GPBType::FLOAT: case GPBType::FIXED32: case GPBType::SFIXED32: $size += 4; break; case GPBType::DOUBLE: case GPBType::FIXED64: case GPBType::SFIXED64: $size += 8; break; case GPBType::INT32: case GPBType::ENUM: $size += GPBWire::varint32Size($value, true); break; case GPBType::UINT32: $size += GPBWire::varint32Size($value); break; case GPBType::UINT64: case GPBType::INT64: $size += GPBWire::varint64Size($value); break; case GPBType::SINT32: $size += GPBWire::sint32Size($value); break; case GPBType::SINT64: $size += GPBWire::sint64Size($value); break; case GPBType::STRING: case GPBType::BYTES: $size += strlen($value); $size += GPBWire::varint32Size($size); break; case GPBType::MESSAGE: $size += $value->byteSize(); $size += GPBWire::varint32Size($size); break; case GPBType::GROUP: // TODO: Add support. user_error("Unsupported type."); break; default: user_error("Unsupported type."); return 0; } return $size; } /** * @ignore */ private function fieldDataOnlyJsonByteSize($field, $value, $options = 0) { $size = 0; switch ($field->getType()) { case GPBType::SFIXED32: case GPBType::SINT32: case GPBType::INT32: $size += strlen(strval($value)); break; case GPBType::FIXED32: case GPBType::UINT32: if ($value < 0) { $value = bcadd($value, "4294967296"); } $size += strlen(strval($value)); break; case GPBType::FIXED64: case GPBType::UINT64: if ($value < 0) { $value = bcadd($value, "18446744073709551616"); } // Intentional fall through. case GPBType::SFIXED64: case GPBType::INT64: case GPBType::SINT64: $size += 2; // size for "" $size += strlen(strval($value)); break; case GPBType::FLOAT: if (is_nan($value)) { $size += strlen("NaN") + 2; } elseif ($value === INF) { $size += strlen("Infinity") + 2; } elseif ($value === -INF) { $size += strlen("-Infinity") + 2; } else { $size += strlen(sprintf("%.8g", $value)); } break; case GPBType::DOUBLE: if (is_nan($value)) { $size += strlen("NaN") + 2; } elseif ($value === INF) { $size += strlen("Infinity") + 2; } elseif ($value === -INF) { $size += strlen("-Infinity") + 2; } else { $size += strlen(sprintf("%.17g", $value)); } break; case GPBType::ENUM: $enum_desc = $field->getEnumType(); if ($enum_desc->getClass() === "Google\Protobuf\NullValue") { $size += 4; break; } if ($options & PrintOptions::ALWAYS_PRINT_ENUMS_AS_INTS) { $size += strlen(strval($value)); // size for integer length } else { $enum_value_desc = $enum_desc->getValueByNumber($value); if (!is_null($enum_value_desc)) { $size += 2; // size for "" $size += strlen($enum_value_desc->getName()); } else { $str_value = strval($value); $size += strlen($str_value); } } break; case GPBType::BOOL: if ($value) { $size += 4; } else { $size += 5; } break; case GPBType::STRING: $value = json_encode($value, JSON_UNESCAPED_UNICODE); $size += strlen($value); break; case GPBType::BYTES: # if (is_a($this, "Google\Protobuf\BytesValue")) { # $size += strlen(json_encode($value)); # } else { # $size += strlen(base64_encode($value)); # $size += 2; // size for \"\" # } $size += strlen(base64_encode($value)); $size += 2; // size for \"\" break; case GPBType::MESSAGE: $size += $value->jsonByteSize($options); break; # case GPBType::GROUP: # // TODO: Add support. # user_error("Unsupported type."); # break; default: user_error("Unsupported type " . $field->getType()); return 0; } return $size; } /** * @ignore */ private function fieldByteSize($field) { $size = 0; if ($field->isMap()) { $getter = $field->getGetter(); $values = $this->$getter(); $count = count($values); if ($count !== 0) { $size += $count * GPBWire::tagSize($field); $message_type = $field->getMessageType(); $key_field = $message_type->getFieldByNumber(1); $value_field = $message_type->getFieldByNumber(2); foreach ($values as $key => $value) { $data_size = 0; if ($key != $this->defaultValue($key_field)) { $data_size += $this->fieldDataOnlyByteSize( $key_field, $key); $data_size += GPBWire::tagSize($key_field); } if ($value != $this->defaultValue($value_field)) { $data_size += $this->fieldDataOnlyByteSize( $value_field, $value); $data_size += GPBWire::tagSize($value_field); } $size += GPBWire::varint32Size($data_size) + $data_size; } } } elseif ($field->isRepeated()) { $getter = $field->getGetter(); $values = $this->$getter(); $count = count($values); if ($count !== 0) { if ($field->getPacked()) { $data_size = 0; foreach ($values as $value) { $data_size += $this->fieldDataOnlyByteSize($field, $value); } $size += GPBWire::tagSize($field); $size += GPBWire::varint32Size($data_size); $size += $data_size; } else { $size += $count * GPBWire::tagSize($field); foreach ($values as $value) { $size += $this->fieldDataOnlyByteSize($field, $value); } } } } elseif ($this->existField($field)) { $size += GPBWire::tagSize($field); $getter = $field->getGetter(); $value = $this->$getter(); $size += $this->fieldDataOnlyByteSize($field, $value); } return $size; } /** * @ignore */ private function fieldJsonByteSize($field, $options = 0) { $size = 0; if ($field->isMap()) { $getter = $field->getGetter(); $values = $this->$getter(); $count = count($values); if ($count !== 0) { if (!GPBUtil::hasSpecialJsonMapping($this)) { $size += 3; // size for "\"\":". if ($options & PrintOptions::PRESERVE_PROTO_FIELD_NAMES) { $size += strlen($field->getName()); } else { $size += strlen($field->getJsonName()); } // size for field name } $size += 2; // size for "{}". $size += $count - 1; // size for commas $getter = $field->getGetter(); $map_entry = $field->getMessageType(); $key_field = $map_entry->getFieldByNumber(1); $value_field = $map_entry->getFieldByNumber(2); switch ($key_field->getType()) { case GPBType::STRING: case GPBType::SFIXED64: case GPBType::INT64: case GPBType::SINT64: case GPBType::FIXED64: case GPBType::UINT64: $additional_quote = false; break; default: $additional_quote = true; } foreach ($values as $key => $value) { if ($additional_quote) { $size += 2; // size for "" } $size += $this->fieldDataOnlyJsonByteSize($key_field, $key, $options); $size += $this->fieldDataOnlyJsonByteSize($value_field, $value, $options); $size += 1; // size for : } } } elseif ($field->isRepeated()) { $getter = $field->getGetter(); $values = $this->$getter(); $count = count($values); if ($count !== 0) { if (!GPBUtil::hasSpecialJsonMapping($this)) { $size += 3; // size for "\"\":". if ($options & PrintOptions::PRESERVE_PROTO_FIELD_NAMES) { $size += strlen($field->getName()); } else { $size += strlen($field->getJsonName()); } // size for field name } $size += 2; // size for "[]". $size += $count - 1; // size for commas $getter = $field->getGetter(); foreach ($values as $value) { $size += $this->fieldDataOnlyJsonByteSize($field, $value, $options); } } } elseif ($this->existField($field) || GPBUtil::hasJsonValue($this)) { if (!GPBUtil::hasSpecialJsonMapping($this)) { $size += 3; // size for "\"\":". if ($options & PrintOptions::PRESERVE_PROTO_FIELD_NAMES) { $size += strlen($field->getName()); } else { $size += strlen($field->getJsonName()); } // size for field name } $getter = $field->getGetter(); $value = $this->$getter(); $size += $this->fieldDataOnlyJsonByteSize($field, $value, $options); } return $size; } /** * @ignore */ public function byteSize() { $size = 0; $fields = $this->desc->getField(); foreach ($fields as $field) { $size += $this->fieldByteSize($field); } $size += strlen($this->unknown); return $size; } private function appendHelper($field, $append_value) { $getter = $field->getGetter(); $setter = $field->getSetter(); $field_arr_value = $this->$getter(); $field_arr_value[] = $append_value; if (!is_object($field_arr_value)) { $this->$setter($field_arr_value); } } private function kvUpdateHelper($field, $update_key, $update_value) { $getter = $field->getGetter(); $setter = $field->getSetter(); $field_arr_value = $this->$getter(); $field_arr_value[$update_key] = $update_value; if (!is_object($field_arr_value)) { $this->$setter($field_arr_value); } } /** * @ignore */ public function jsonByteSize($options = 0) { $size = 0; if (is_a($this, 'Google\Protobuf\Any')) { // Size for "{}". $size += 2; // Size for "\"@type\":". $size += 8; // Size for url. +2 for "" /. $size += strlen($this->getTypeUrl()) + 2; $value_msg = $this->unpack(); if (GPBUtil::hasSpecialJsonMapping($value_msg)) { // Size for "\",value\":". $size += 9; $size += $value_msg->jsonByteSize($options); } else { $value_size = $value_msg->jsonByteSize($options); // size === 2 it's empty message {} which is not serialized inside any if ($value_size !== 2) { // Size for value. +1 for comma, -2 for "{}". $size += $value_size -1; } } } elseif (get_class($this) === 'Google\Protobuf\FieldMask') { $field_mask = GPBUtil::formatFieldMask($this); $size += strlen($field_mask) + 2; // 2 for "" } elseif (get_class($this) === 'Google\Protobuf\Duration') { $duration = GPBUtil::formatDuration($this) . "s"; $size += strlen($duration) + 2; // 2 for "" } elseif (get_class($this) === 'Google\Protobuf\Timestamp') { $timestamp = GPBUtil::formatTimestamp($this); $timestamp = json_encode($timestamp); $size += strlen($timestamp); } elseif (get_class($this) === 'Google\Protobuf\ListValue') { $field = $this->desc->getField()[1]; if ($this->existField($field)) { $field_size = $this->fieldJsonByteSize($field, $options); $size += $field_size; } else { // Size for "[]". $size += 2; } } elseif (get_class($this) === 'Google\Protobuf\Struct') { $field = $this->desc->getField()[1]; if ($this->existField($field)) { $field_size = $this->fieldJsonByteSize($field, $options); $size += $field_size; } else { // Size for "{}". $size += 2; } } else { if (!GPBUtil::hasSpecialJsonMapping($this)) { // Size for "{}". $size += 2; } $fields = $this->desc->getField(); $count = 0; foreach ($fields as $field) { $field_size = $this->fieldJsonByteSize($field, $options); $size += $field_size; if ($field_size != 0) { $count++; } } // size for comma $size += $count > 0 ? ($count - 1) : 0; } return $size; } public function __debugInfo() { if (is_a($this, 'Google\Protobuf\FieldMask')) { return ['paths' => $this->getPaths()->__debugInfo()]; } if (is_a($this, 'Google\Protobuf\Value')) { switch ($this->getKind()) { case 'null_value': return ['nullValue' => $this->getNullValue()]; case 'number_value': return ['numberValue' => $this->getNumberValue()]; case 'string_value': return ['stringValue' => $this->getStringValue()]; case 'bool_value': return ['boolValue' => $this->getBoolValue()]; case 'struct_value': return ['structValue' => $this->getStructValue()->__debugInfo()]; case 'list_value': return ['listValue' => $this->getListValue()->__debugInfo()]; } return []; } if (is_a($this, 'Google\Protobuf\BoolValue') || is_a($this, 'Google\Protobuf\BytesValue') || is_a($this, 'Google\Protobuf\DoubleValue') || is_a($this, 'Google\Protobuf\FloatValue') || is_a($this, 'Google\Protobuf\StringValue') || is_a($this, 'Google\Protobuf\Int32Value') || is_a($this, 'Google\Protobuf\Int64Value') || is_a($this, 'Google\Protobuf\UInt32Value') || is_a($this, 'Google\Protobuf\UInt64Value') ) { return [ 'value' => json_decode($this->serializeToJsonString(), true), ]; } if ( is_a($this, 'Google\Protobuf\Duration') || is_a($this, 'Google\Protobuf\Timestamp') ) { return [ 'seconds' => $this->getSeconds(), 'nanos' => $this->getNanos(), ]; } return json_decode($this->serializeToJsonString(), true); } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/MessageBuilderContext.php ================================================ descriptor = new Descriptor(); $this->descriptor->setFullName($full_name); $this->descriptor->setClass($klass); $this->pool = $pool; } private function getFieldDescriptor($name, $label, $type, $number, $type_name = null) { $field = new FieldDescriptor(); $field->setName($name); $camel_name = implode('', array_map('ucwords', explode('_', $name))); $field->setGetter('get' . $camel_name); $field->setSetter('set' . $camel_name); $field->setType($type); $field->setNumber($number); $field->setLabel($label); // At this time, the message/enum type may have not been added to pool. // So we use the type name as place holder and will replace it with the // actual descriptor in cross building. switch ($type) { case GPBType::MESSAGE: $field->setMessageType($type_name); break; case GPBType::ENUM: $field->setEnumType($type_name); break; default: break; } return $field; } public function optional($name, $type, $number, $type_name = null) { $this->descriptor->addField($this->getFieldDescriptor( $name, GPBLabel::OPTIONAL, $type, $number, $type_name)); return $this; } public function repeated($name, $type, $number, $type_name = null) { $this->descriptor->addField($this->getFieldDescriptor( $name, GPBLabel::REPEATED, $type, $number, $type_name)); return $this; } public function required($name, $type, $number, $type_name = null) { $this->descriptor->addField($this->getFieldDescriptor( $name, GPBLabel::REQUIRED, $type, $number, $type_name)); return $this; } public function finalizeToPool() { $this->pool->addDescriptor($this->descriptor); } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/MessageOptions.php ================================================ google.protobuf.MessageOptions */ class MessageOptions extends \Google\Protobuf\Internal\Message { /** * Set true to use the old proto1 MessageSet wire format for extensions. * This is provided for backwards-compatibility with the MessageSet wire * format. You should not use this for any other reason: It's less * efficient, has fewer features, and is more complicated. * The message must be defined exactly as follows: * message Foo { * option message_set_wire_format = true; * extensions 4 to max; * } * Note that the message cannot have any defined fields; MessageSets only * have extensions. * All extensions of your type must be singular messages; e.g. they cannot * be int32s, enums, or repeated messages. * Because this is an option, the above two restrictions are not enforced by * the protocol compiler. * * Generated from protobuf field optional bool message_set_wire_format = 1 [default = false]; */ protected $message_set_wire_format = null; /** * Disables the generation of the standard "descriptor()" accessor, which can * conflict with a field of the same name. This is meant to make migration * from proto1 easier; new code should avoid fields named "descriptor". * * Generated from protobuf field optional bool no_standard_descriptor_accessor = 2 [default = false]; */ protected $no_standard_descriptor_accessor = null; /** * Is this message deprecated? * Depending on the target platform, this can emit Deprecated annotations * for the message, or it will be completely ignored; in the very least, * this is a formalization for deprecating messages. * * Generated from protobuf field optional bool deprecated = 3 [default = false]; */ protected $deprecated = null; /** * Whether the message is an automatically generated map entry type for the * maps field. * For maps fields: * map map_field = 1; * The parsed descriptor looks like: * message MapFieldEntry { * option map_entry = true; * optional KeyType key = 1; * optional ValueType value = 2; * } * repeated MapFieldEntry map_field = 1; * Implementations may choose not to generate the map_entry=true message, but * use a native map in the target language to hold the keys and values. * The reflection APIs in such implementations still need to work as * if the field is a repeated message field. * NOTE: Do not set the option in .proto files. Always use the maps syntax * instead. The option should only be implicitly set by the proto compiler * parser. * * Generated from protobuf field optional bool map_entry = 7; */ protected $map_entry = null; /** * Enable the legacy handling of JSON field name conflicts. This lowercases * and strips underscored from the fields before comparison in proto3 only. * The new behavior takes `json_name` into account and applies to proto2 as * well. * This should only be used as a temporary measure against broken builds due * to the change in behavior for JSON field name conflicts. * TODO This is legacy behavior we plan to remove once downstream * teams have had time to migrate. * * Generated from protobuf field optional bool deprecated_legacy_json_field_conflicts = 11 [deprecated = true]; * @deprecated */ protected $deprecated_legacy_json_field_conflicts = null; /** * Any features defined in the specific edition. * WARNING: This field should only be used by protobuf plugins or special * cases like the proto compiler. Other uses are discouraged and * developers should rely on the protoreflect APIs for their client language. * * Generated from protobuf field optional .google.protobuf.FeatureSet features = 12; */ protected $features = null; /** * The parser stores options it doesn't recognize here. See above. * * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; */ private $uninterpreted_option; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type bool $message_set_wire_format * Set true to use the old proto1 MessageSet wire format for extensions. * This is provided for backwards-compatibility with the MessageSet wire * format. You should not use this for any other reason: It's less * efficient, has fewer features, and is more complicated. * The message must be defined exactly as follows: * message Foo { * option message_set_wire_format = true; * extensions 4 to max; * } * Note that the message cannot have any defined fields; MessageSets only * have extensions. * All extensions of your type must be singular messages; e.g. they cannot * be int32s, enums, or repeated messages. * Because this is an option, the above two restrictions are not enforced by * the protocol compiler. * @type bool $no_standard_descriptor_accessor * Disables the generation of the standard "descriptor()" accessor, which can * conflict with a field of the same name. This is meant to make migration * from proto1 easier; new code should avoid fields named "descriptor". * @type bool $deprecated * Is this message deprecated? * Depending on the target platform, this can emit Deprecated annotations * for the message, or it will be completely ignored; in the very least, * this is a formalization for deprecating messages. * @type bool $map_entry * Whether the message is an automatically generated map entry type for the * maps field. * For maps fields: * map map_field = 1; * The parsed descriptor looks like: * message MapFieldEntry { * option map_entry = true; * optional KeyType key = 1; * optional ValueType value = 2; * } * repeated MapFieldEntry map_field = 1; * Implementations may choose not to generate the map_entry=true message, but * use a native map in the target language to hold the keys and values. * The reflection APIs in such implementations still need to work as * if the field is a repeated message field. * NOTE: Do not set the option in .proto files. Always use the maps syntax * instead. The option should only be implicitly set by the proto compiler * parser. * @type bool $deprecated_legacy_json_field_conflicts * Enable the legacy handling of JSON field name conflicts. This lowercases * and strips underscored from the fields before comparison in proto3 only. * The new behavior takes `json_name` into account and applies to proto2 as * well. * This should only be used as a temporary measure against broken builds due * to the change in behavior for JSON field name conflicts. * TODO This is legacy behavior we plan to remove once downstream * teams have had time to migrate. * @type \Google\Protobuf\Internal\FeatureSet $features * Any features defined in the specific edition. * WARNING: This field should only be used by protobuf plugins or special * cases like the proto compiler. Other uses are discouraged and * developers should rely on the protoreflect APIs for their client language. * @type \Google\Protobuf\Internal\UninterpretedOption[] $uninterpreted_option * The parser stores options it doesn't recognize here. See above. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); parent::__construct($data); } /** * Set true to use the old proto1 MessageSet wire format for extensions. * This is provided for backwards-compatibility with the MessageSet wire * format. You should not use this for any other reason: It's less * efficient, has fewer features, and is more complicated. * The message must be defined exactly as follows: * message Foo { * option message_set_wire_format = true; * extensions 4 to max; * } * Note that the message cannot have any defined fields; MessageSets only * have extensions. * All extensions of your type must be singular messages; e.g. they cannot * be int32s, enums, or repeated messages. * Because this is an option, the above two restrictions are not enforced by * the protocol compiler. * * Generated from protobuf field optional bool message_set_wire_format = 1 [default = false]; * @return bool */ public function getMessageSetWireFormat() { return isset($this->message_set_wire_format) ? $this->message_set_wire_format : false; } public function hasMessageSetWireFormat() { return isset($this->message_set_wire_format); } public function clearMessageSetWireFormat() { unset($this->message_set_wire_format); } /** * Set true to use the old proto1 MessageSet wire format for extensions. * This is provided for backwards-compatibility with the MessageSet wire * format. You should not use this for any other reason: It's less * efficient, has fewer features, and is more complicated. * The message must be defined exactly as follows: * message Foo { * option message_set_wire_format = true; * extensions 4 to max; * } * Note that the message cannot have any defined fields; MessageSets only * have extensions. * All extensions of your type must be singular messages; e.g. they cannot * be int32s, enums, or repeated messages. * Because this is an option, the above two restrictions are not enforced by * the protocol compiler. * * Generated from protobuf field optional bool message_set_wire_format = 1 [default = false]; * @param bool $var * @return $this */ public function setMessageSetWireFormat($var) { GPBUtil::checkBool($var); $this->message_set_wire_format = $var; return $this; } /** * Disables the generation of the standard "descriptor()" accessor, which can * conflict with a field of the same name. This is meant to make migration * from proto1 easier; new code should avoid fields named "descriptor". * * Generated from protobuf field optional bool no_standard_descriptor_accessor = 2 [default = false]; * @return bool */ public function getNoStandardDescriptorAccessor() { return isset($this->no_standard_descriptor_accessor) ? $this->no_standard_descriptor_accessor : false; } public function hasNoStandardDescriptorAccessor() { return isset($this->no_standard_descriptor_accessor); } public function clearNoStandardDescriptorAccessor() { unset($this->no_standard_descriptor_accessor); } /** * Disables the generation of the standard "descriptor()" accessor, which can * conflict with a field of the same name. This is meant to make migration * from proto1 easier; new code should avoid fields named "descriptor". * * Generated from protobuf field optional bool no_standard_descriptor_accessor = 2 [default = false]; * @param bool $var * @return $this */ public function setNoStandardDescriptorAccessor($var) { GPBUtil::checkBool($var); $this->no_standard_descriptor_accessor = $var; return $this; } /** * Is this message deprecated? * Depending on the target platform, this can emit Deprecated annotations * for the message, or it will be completely ignored; in the very least, * this is a formalization for deprecating messages. * * Generated from protobuf field optional bool deprecated = 3 [default = false]; * @return bool */ public function getDeprecated() { return isset($this->deprecated) ? $this->deprecated : false; } public function hasDeprecated() { return isset($this->deprecated); } public function clearDeprecated() { unset($this->deprecated); } /** * Is this message deprecated? * Depending on the target platform, this can emit Deprecated annotations * for the message, or it will be completely ignored; in the very least, * this is a formalization for deprecating messages. * * Generated from protobuf field optional bool deprecated = 3 [default = false]; * @param bool $var * @return $this */ public function setDeprecated($var) { GPBUtil::checkBool($var); $this->deprecated = $var; return $this; } /** * Whether the message is an automatically generated map entry type for the * maps field. * For maps fields: * map map_field = 1; * The parsed descriptor looks like: * message MapFieldEntry { * option map_entry = true; * optional KeyType key = 1; * optional ValueType value = 2; * } * repeated MapFieldEntry map_field = 1; * Implementations may choose not to generate the map_entry=true message, but * use a native map in the target language to hold the keys and values. * The reflection APIs in such implementations still need to work as * if the field is a repeated message field. * NOTE: Do not set the option in .proto files. Always use the maps syntax * instead. The option should only be implicitly set by the proto compiler * parser. * * Generated from protobuf field optional bool map_entry = 7; * @return bool */ public function getMapEntry() { return isset($this->map_entry) ? $this->map_entry : false; } public function hasMapEntry() { return isset($this->map_entry); } public function clearMapEntry() { unset($this->map_entry); } /** * Whether the message is an automatically generated map entry type for the * maps field. * For maps fields: * map map_field = 1; * The parsed descriptor looks like: * message MapFieldEntry { * option map_entry = true; * optional KeyType key = 1; * optional ValueType value = 2; * } * repeated MapFieldEntry map_field = 1; * Implementations may choose not to generate the map_entry=true message, but * use a native map in the target language to hold the keys and values. * The reflection APIs in such implementations still need to work as * if the field is a repeated message field. * NOTE: Do not set the option in .proto files. Always use the maps syntax * instead. The option should only be implicitly set by the proto compiler * parser. * * Generated from protobuf field optional bool map_entry = 7; * @param bool $var * @return $this */ public function setMapEntry($var) { GPBUtil::checkBool($var); $this->map_entry = $var; return $this; } /** * Enable the legacy handling of JSON field name conflicts. This lowercases * and strips underscored from the fields before comparison in proto3 only. * The new behavior takes `json_name` into account and applies to proto2 as * well. * This should only be used as a temporary measure against broken builds due * to the change in behavior for JSON field name conflicts. * TODO This is legacy behavior we plan to remove once downstream * teams have had time to migrate. * * Generated from protobuf field optional bool deprecated_legacy_json_field_conflicts = 11 [deprecated = true]; * @return bool * @deprecated */ public function getDeprecatedLegacyJsonFieldConflicts() { if (isset($this->deprecated_legacy_json_field_conflicts)) { @trigger_error('deprecated_legacy_json_field_conflicts is deprecated.', E_USER_DEPRECATED); } return isset($this->deprecated_legacy_json_field_conflicts) ? $this->deprecated_legacy_json_field_conflicts : false; } public function hasDeprecatedLegacyJsonFieldConflicts() { if (isset($this->deprecated_legacy_json_field_conflicts)) { @trigger_error('deprecated_legacy_json_field_conflicts is deprecated.', E_USER_DEPRECATED); } return isset($this->deprecated_legacy_json_field_conflicts); } public function clearDeprecatedLegacyJsonFieldConflicts() { @trigger_error('deprecated_legacy_json_field_conflicts is deprecated.', E_USER_DEPRECATED); unset($this->deprecated_legacy_json_field_conflicts); } /** * Enable the legacy handling of JSON field name conflicts. This lowercases * and strips underscored from the fields before comparison in proto3 only. * The new behavior takes `json_name` into account and applies to proto2 as * well. * This should only be used as a temporary measure against broken builds due * to the change in behavior for JSON field name conflicts. * TODO This is legacy behavior we plan to remove once downstream * teams have had time to migrate. * * Generated from protobuf field optional bool deprecated_legacy_json_field_conflicts = 11 [deprecated = true]; * @param bool $var * @return $this * @deprecated */ public function setDeprecatedLegacyJsonFieldConflicts($var) { @trigger_error('deprecated_legacy_json_field_conflicts is deprecated.', E_USER_DEPRECATED); GPBUtil::checkBool($var); $this->deprecated_legacy_json_field_conflicts = $var; return $this; } /** * Any features defined in the specific edition. * WARNING: This field should only be used by protobuf plugins or special * cases like the proto compiler. Other uses are discouraged and * developers should rely on the protoreflect APIs for their client language. * * Generated from protobuf field optional .google.protobuf.FeatureSet features = 12; * @return \Google\Protobuf\Internal\FeatureSet|null */ public function getFeatures() { return $this->features; } public function hasFeatures() { return isset($this->features); } public function clearFeatures() { unset($this->features); } /** * Any features defined in the specific edition. * WARNING: This field should only be used by protobuf plugins or special * cases like the proto compiler. Other uses are discouraged and * developers should rely on the protoreflect APIs for their client language. * * Generated from protobuf field optional .google.protobuf.FeatureSet features = 12; * @param \Google\Protobuf\Internal\FeatureSet $var * @return $this */ public function setFeatures($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\FeatureSet::class); $this->features = $var; return $this; } /** * The parser stores options it doesn't recognize here. See above. * * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; * @return RepeatedField<\Google\Protobuf\Internal\UninterpretedOption> */ public function getUninterpretedOption() { return $this->uninterpreted_option; } /** * The parser stores options it doesn't recognize here. See above. * * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; * @param \Google\Protobuf\Internal\UninterpretedOption[] $var * @return $this */ public function setUninterpretedOption($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); $this->uninterpreted_option = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/MethodDescriptorProto.php ================================================ google.protobuf.MethodDescriptorProto */ class MethodDescriptorProto extends \Google\Protobuf\Internal\Message { /** * Generated from protobuf field optional string name = 1; */ protected $name = null; /** * Input and output type names. These are resolved in the same way as * FieldDescriptorProto.type_name, but must refer to a message type. * * Generated from protobuf field optional string input_type = 2; */ protected $input_type = null; /** * Generated from protobuf field optional string output_type = 3; */ protected $output_type = null; /** * Generated from protobuf field optional .google.protobuf.MethodOptions options = 4; */ protected $options = null; /** * Identifies if client streams multiple client messages * * Generated from protobuf field optional bool client_streaming = 5 [default = false]; */ protected $client_streaming = null; /** * Identifies if server streams multiple server messages * * Generated from protobuf field optional bool server_streaming = 6 [default = false]; */ protected $server_streaming = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $name * @type string $input_type * Input and output type names. These are resolved in the same way as * FieldDescriptorProto.type_name, but must refer to a message type. * @type string $output_type * @type \Google\Protobuf\Internal\MethodOptions $options * @type bool $client_streaming * Identifies if client streams multiple client messages * @type bool $server_streaming * Identifies if server streams multiple server messages * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); parent::__construct($data); } /** * Generated from protobuf field optional string name = 1; * @return string */ public function getName() { return isset($this->name) ? $this->name : ''; } public function hasName() { return isset($this->name); } public function clearName() { unset($this->name); } /** * Generated from protobuf field optional string name = 1; * @param string $var * @return $this */ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; return $this; } /** * Input and output type names. These are resolved in the same way as * FieldDescriptorProto.type_name, but must refer to a message type. * * Generated from protobuf field optional string input_type = 2; * @return string */ public function getInputType() { return isset($this->input_type) ? $this->input_type : ''; } public function hasInputType() { return isset($this->input_type); } public function clearInputType() { unset($this->input_type); } /** * Input and output type names. These are resolved in the same way as * FieldDescriptorProto.type_name, but must refer to a message type. * * Generated from protobuf field optional string input_type = 2; * @param string $var * @return $this */ public function setInputType($var) { GPBUtil::checkString($var, True); $this->input_type = $var; return $this; } /** * Generated from protobuf field optional string output_type = 3; * @return string */ public function getOutputType() { return isset($this->output_type) ? $this->output_type : ''; } public function hasOutputType() { return isset($this->output_type); } public function clearOutputType() { unset($this->output_type); } /** * Generated from protobuf field optional string output_type = 3; * @param string $var * @return $this */ public function setOutputType($var) { GPBUtil::checkString($var, True); $this->output_type = $var; return $this; } /** * Generated from protobuf field optional .google.protobuf.MethodOptions options = 4; * @return \Google\Protobuf\Internal\MethodOptions|null */ public function getOptions() { return $this->options; } public function hasOptions() { return isset($this->options); } public function clearOptions() { unset($this->options); } /** * Generated from protobuf field optional .google.protobuf.MethodOptions options = 4; * @param \Google\Protobuf\Internal\MethodOptions $var * @return $this */ public function setOptions($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\MethodOptions::class); $this->options = $var; return $this; } /** * Identifies if client streams multiple client messages * * Generated from protobuf field optional bool client_streaming = 5 [default = false]; * @return bool */ public function getClientStreaming() { return isset($this->client_streaming) ? $this->client_streaming : false; } public function hasClientStreaming() { return isset($this->client_streaming); } public function clearClientStreaming() { unset($this->client_streaming); } /** * Identifies if client streams multiple client messages * * Generated from protobuf field optional bool client_streaming = 5 [default = false]; * @param bool $var * @return $this */ public function setClientStreaming($var) { GPBUtil::checkBool($var); $this->client_streaming = $var; return $this; } /** * Identifies if server streams multiple server messages * * Generated from protobuf field optional bool server_streaming = 6 [default = false]; * @return bool */ public function getServerStreaming() { return isset($this->server_streaming) ? $this->server_streaming : false; } public function hasServerStreaming() { return isset($this->server_streaming); } public function clearServerStreaming() { unset($this->server_streaming); } /** * Identifies if server streams multiple server messages * * Generated from protobuf field optional bool server_streaming = 6 [default = false]; * @param bool $var * @return $this */ public function setServerStreaming($var) { GPBUtil::checkBool($var); $this->server_streaming = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/MethodOptions/IdempotencyLevel.php ================================================ google.protobuf.MethodOptions.IdempotencyLevel */ class IdempotencyLevel { /** * Generated from protobuf enum IDEMPOTENCY_UNKNOWN = 0; */ const IDEMPOTENCY_UNKNOWN = 0; /** * implies idempotent * * Generated from protobuf enum NO_SIDE_EFFECTS = 1; */ const NO_SIDE_EFFECTS = 1; /** * idempotent, but may have side effects * * Generated from protobuf enum IDEMPOTENT = 2; */ const IDEMPOTENT = 2; private static $valueToName = [ self::IDEMPOTENCY_UNKNOWN => 'IDEMPOTENCY_UNKNOWN', self::NO_SIDE_EFFECTS => 'NO_SIDE_EFFECTS', self::IDEMPOTENT => 'IDEMPOTENT', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/MethodOptions.php ================================================ google.protobuf.MethodOptions */ class MethodOptions extends \Google\Protobuf\Internal\Message { /** * Is this method deprecated? * Depending on the target platform, this can emit Deprecated annotations * for the method, or it will be completely ignored; in the very least, * this is a formalization for deprecating methods. * * Generated from protobuf field optional bool deprecated = 33 [default = false]; */ protected $deprecated = null; /** * Generated from protobuf field optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN]; */ protected $idempotency_level = null; /** * Any features defined in the specific edition. * WARNING: This field should only be used by protobuf plugins or special * cases like the proto compiler. Other uses are discouraged and * developers should rely on the protoreflect APIs for their client language. * * Generated from protobuf field optional .google.protobuf.FeatureSet features = 35; */ protected $features = null; /** * The parser stores options it doesn't recognize here. See above. * * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; */ private $uninterpreted_option; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type bool $deprecated * Is this method deprecated? * Depending on the target platform, this can emit Deprecated annotations * for the method, or it will be completely ignored; in the very least, * this is a formalization for deprecating methods. * @type int $idempotency_level * @type \Google\Protobuf\Internal\FeatureSet $features * Any features defined in the specific edition. * WARNING: This field should only be used by protobuf plugins or special * cases like the proto compiler. Other uses are discouraged and * developers should rely on the protoreflect APIs for their client language. * @type \Google\Protobuf\Internal\UninterpretedOption[] $uninterpreted_option * The parser stores options it doesn't recognize here. See above. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); parent::__construct($data); } /** * Is this method deprecated? * Depending on the target platform, this can emit Deprecated annotations * for the method, or it will be completely ignored; in the very least, * this is a formalization for deprecating methods. * * Generated from protobuf field optional bool deprecated = 33 [default = false]; * @return bool */ public function getDeprecated() { return isset($this->deprecated) ? $this->deprecated : false; } public function hasDeprecated() { return isset($this->deprecated); } public function clearDeprecated() { unset($this->deprecated); } /** * Is this method deprecated? * Depending on the target platform, this can emit Deprecated annotations * for the method, or it will be completely ignored; in the very least, * this is a formalization for deprecating methods. * * Generated from protobuf field optional bool deprecated = 33 [default = false]; * @param bool $var * @return $this */ public function setDeprecated($var) { GPBUtil::checkBool($var); $this->deprecated = $var; return $this; } /** * Generated from protobuf field optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN]; * @return int */ public function getIdempotencyLevel() { return isset($this->idempotency_level) ? $this->idempotency_level : 0; } public function hasIdempotencyLevel() { return isset($this->idempotency_level); } public function clearIdempotencyLevel() { unset($this->idempotency_level); } /** * Generated from protobuf field optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN]; * @param int $var * @return $this */ public function setIdempotencyLevel($var) { GPBUtil::checkEnum($var, \Google\Protobuf\Internal\MethodOptions\IdempotencyLevel::class); $this->idempotency_level = $var; return $this; } /** * Any features defined in the specific edition. * WARNING: This field should only be used by protobuf plugins or special * cases like the proto compiler. Other uses are discouraged and * developers should rely on the protoreflect APIs for their client language. * * Generated from protobuf field optional .google.protobuf.FeatureSet features = 35; * @return \Google\Protobuf\Internal\FeatureSet|null */ public function getFeatures() { return $this->features; } public function hasFeatures() { return isset($this->features); } public function clearFeatures() { unset($this->features); } /** * Any features defined in the specific edition. * WARNING: This field should only be used by protobuf plugins or special * cases like the proto compiler. Other uses are discouraged and * developers should rely on the protoreflect APIs for their client language. * * Generated from protobuf field optional .google.protobuf.FeatureSet features = 35; * @param \Google\Protobuf\Internal\FeatureSet $var * @return $this */ public function setFeatures($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\FeatureSet::class); $this->features = $var; return $this; } /** * The parser stores options it doesn't recognize here. See above. * * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; * @return RepeatedField<\Google\Protobuf\Internal\UninterpretedOption> */ public function getUninterpretedOption() { return $this->uninterpreted_option; } /** * The parser stores options it doesn't recognize here. See above. * * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; * @param \Google\Protobuf\Internal\UninterpretedOption[] $var * @return $this */ public function setUninterpretedOption($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); $this->uninterpreted_option = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/OneofDescriptor.php ================================================ public_desc = new \Google\Protobuf\OneofDescriptor($this); } public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } public function addField(FieldDescriptor $field) { $this->fields[] = $field; } public function getFields() { return $this->fields; } public function isSynthetic() { return !is_null($this->fields) && count($this->fields) === 1 && $this->fields[0]->getProto3Optional(); } public static function buildFromProto($oneof_proto, $desc, $index) { $oneof = new OneofDescriptor(); $oneof->setName($oneof_proto->getName()); foreach ($desc->getField() as $field) { /** @var FieldDescriptor $field */ if ($field->getOneofIndex() == $index) { $oneof->addField($field); $field->setContainingOneof($oneof); } } return $oneof; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/OneofDescriptorProto.php ================================================ google.protobuf.OneofDescriptorProto */ class OneofDescriptorProto extends \Google\Protobuf\Internal\Message { /** * Generated from protobuf field optional string name = 1; */ protected $name = null; /** * Generated from protobuf field optional .google.protobuf.OneofOptions options = 2; */ protected $options = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $name * @type \Google\Protobuf\Internal\OneofOptions $options * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); parent::__construct($data); } /** * Generated from protobuf field optional string name = 1; * @return string */ public function getName() { return isset($this->name) ? $this->name : ''; } public function hasName() { return isset($this->name); } public function clearName() { unset($this->name); } /** * Generated from protobuf field optional string name = 1; * @param string $var * @return $this */ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; return $this; } /** * Generated from protobuf field optional .google.protobuf.OneofOptions options = 2; * @return \Google\Protobuf\Internal\OneofOptions|null */ public function getOptions() { return $this->options; } public function hasOptions() { return isset($this->options); } public function clearOptions() { unset($this->options); } /** * Generated from protobuf field optional .google.protobuf.OneofOptions options = 2; * @param \Google\Protobuf\Internal\OneofOptions $var * @return $this */ public function setOptions($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\OneofOptions::class); $this->options = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/OneofField.php ================================================ desc = $desc; } public function setValue($value) { $this->value = $value; } public function getValue() { return $this->value; } public function setFieldName($field_name) { $this->field_name = $field_name; } public function getFieldName() { return $this->field_name; } public function setNumber($number) { $this->number = $number; } public function getNumber() { return $this->number; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/OneofOptions.php ================================================ google.protobuf.OneofOptions */ class OneofOptions extends \Google\Protobuf\Internal\Message { /** * Any features defined in the specific edition. * WARNING: This field should only be used by protobuf plugins or special * cases like the proto compiler. Other uses are discouraged and * developers should rely on the protoreflect APIs for their client language. * * Generated from protobuf field optional .google.protobuf.FeatureSet features = 1; */ protected $features = null; /** * The parser stores options it doesn't recognize here. See above. * * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; */ private $uninterpreted_option; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type \Google\Protobuf\Internal\FeatureSet $features * Any features defined in the specific edition. * WARNING: This field should only be used by protobuf plugins or special * cases like the proto compiler. Other uses are discouraged and * developers should rely on the protoreflect APIs for their client language. * @type \Google\Protobuf\Internal\UninterpretedOption[] $uninterpreted_option * The parser stores options it doesn't recognize here. See above. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); parent::__construct($data); } /** * Any features defined in the specific edition. * WARNING: This field should only be used by protobuf plugins or special * cases like the proto compiler. Other uses are discouraged and * developers should rely on the protoreflect APIs for their client language. * * Generated from protobuf field optional .google.protobuf.FeatureSet features = 1; * @return \Google\Protobuf\Internal\FeatureSet|null */ public function getFeatures() { return $this->features; } public function hasFeatures() { return isset($this->features); } public function clearFeatures() { unset($this->features); } /** * Any features defined in the specific edition. * WARNING: This field should only be used by protobuf plugins or special * cases like the proto compiler. Other uses are discouraged and * developers should rely on the protoreflect APIs for their client language. * * Generated from protobuf field optional .google.protobuf.FeatureSet features = 1; * @param \Google\Protobuf\Internal\FeatureSet $var * @return $this */ public function setFeatures($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\FeatureSet::class); $this->features = $var; return $this; } /** * The parser stores options it doesn't recognize here. See above. * * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; * @return RepeatedField<\Google\Protobuf\Internal\UninterpretedOption> */ public function getUninterpretedOption() { return $this->uninterpreted_option; } /** * The parser stores options it doesn't recognize here. See above. * * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; * @param \Google\Protobuf\Internal\UninterpretedOption[] $var * @return $this */ public function setUninterpretedOption($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); $this->uninterpreted_option = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/RawInputStream.php ================================================ buffer = $buffer; } public function getData() { return $this->buffer; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/RepeatedField.php ================================================ position = 0; $this->container = $container; } /** * Reset the status of the iterator * * @return void * @todo need to add return type void (require update php version to 7.1) */ #[\ReturnTypeWillChange] public function rewind() { $this->position = 0; } /** * Return the element at the current position. * * @return object The element at the current position. * @todo need to add return type mixed (require update php version to 8.0) */ #[\ReturnTypeWillChange] public function current() { return $this->container[$this->position]; } /** * Return the current position. * * @return integer The current position. * @todo need to add return type mixed (require update php version to 8.0) */ #[\ReturnTypeWillChange] public function key() { return $this->position; } /** * Move to the next position. * * @return void * @todo need to add return type void (require update php version to 7.1) */ #[\ReturnTypeWillChange] public function next() { ++$this->position; } /** * Check whether there are more elements to iterate. * * @return bool True if there are more elements to iterate. */ public function valid(): bool { return isset($this->container[$this->position]); } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/ServiceDescriptorProto.php ================================================ google.protobuf.ServiceDescriptorProto */ class ServiceDescriptorProto extends \Google\Protobuf\Internal\Message { /** * Generated from protobuf field optional string name = 1; */ protected $name = null; /** * Generated from protobuf field repeated .google.protobuf.MethodDescriptorProto method = 2; */ private $method; /** * Generated from protobuf field optional .google.protobuf.ServiceOptions options = 3; */ protected $options = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $name * @type \Google\Protobuf\Internal\MethodDescriptorProto[] $method * @type \Google\Protobuf\Internal\ServiceOptions $options * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); parent::__construct($data); } /** * Generated from protobuf field optional string name = 1; * @return string */ public function getName() { return isset($this->name) ? $this->name : ''; } public function hasName() { return isset($this->name); } public function clearName() { unset($this->name); } /** * Generated from protobuf field optional string name = 1; * @param string $var * @return $this */ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; return $this; } /** * Generated from protobuf field repeated .google.protobuf.MethodDescriptorProto method = 2; * @return RepeatedField<\Google\Protobuf\Internal\MethodDescriptorProto> */ public function getMethod() { return $this->method; } /** * Generated from protobuf field repeated .google.protobuf.MethodDescriptorProto method = 2; * @param \Google\Protobuf\Internal\MethodDescriptorProto[] $var * @return $this */ public function setMethod($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\MethodDescriptorProto::class); $this->method = $arr; return $this; } /** * Generated from protobuf field optional .google.protobuf.ServiceOptions options = 3; * @return \Google\Protobuf\Internal\ServiceOptions|null */ public function getOptions() { return $this->options; } public function hasOptions() { return isset($this->options); } public function clearOptions() { unset($this->options); } /** * Generated from protobuf field optional .google.protobuf.ServiceOptions options = 3; * @param \Google\Protobuf\Internal\ServiceOptions $var * @return $this */ public function setOptions($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\ServiceOptions::class); $this->options = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/ServiceOptions.php ================================================ google.protobuf.ServiceOptions */ class ServiceOptions extends \Google\Protobuf\Internal\Message { /** * Any features defined in the specific edition. * WARNING: This field should only be used by protobuf plugins or special * cases like the proto compiler. Other uses are discouraged and * developers should rely on the protoreflect APIs for their client language. * * Generated from protobuf field optional .google.protobuf.FeatureSet features = 34; */ protected $features = null; /** * Is this service deprecated? * Depending on the target platform, this can emit Deprecated annotations * for the service, or it will be completely ignored; in the very least, * this is a formalization for deprecating services. * * Generated from protobuf field optional bool deprecated = 33 [default = false]; */ protected $deprecated = null; /** * The parser stores options it doesn't recognize here. See above. * * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; */ private $uninterpreted_option; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type \Google\Protobuf\Internal\FeatureSet $features * Any features defined in the specific edition. * WARNING: This field should only be used by protobuf plugins or special * cases like the proto compiler. Other uses are discouraged and * developers should rely on the protoreflect APIs for their client language. * @type bool $deprecated * Is this service deprecated? * Depending on the target platform, this can emit Deprecated annotations * for the service, or it will be completely ignored; in the very least, * this is a formalization for deprecating services. * @type \Google\Protobuf\Internal\UninterpretedOption[] $uninterpreted_option * The parser stores options it doesn't recognize here. See above. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); parent::__construct($data); } /** * Any features defined in the specific edition. * WARNING: This field should only be used by protobuf plugins or special * cases like the proto compiler. Other uses are discouraged and * developers should rely on the protoreflect APIs for their client language. * * Generated from protobuf field optional .google.protobuf.FeatureSet features = 34; * @return \Google\Protobuf\Internal\FeatureSet|null */ public function getFeatures() { return $this->features; } public function hasFeatures() { return isset($this->features); } public function clearFeatures() { unset($this->features); } /** * Any features defined in the specific edition. * WARNING: This field should only be used by protobuf plugins or special * cases like the proto compiler. Other uses are discouraged and * developers should rely on the protoreflect APIs for their client language. * * Generated from protobuf field optional .google.protobuf.FeatureSet features = 34; * @param \Google\Protobuf\Internal\FeatureSet $var * @return $this */ public function setFeatures($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Internal\FeatureSet::class); $this->features = $var; return $this; } /** * Is this service deprecated? * Depending on the target platform, this can emit Deprecated annotations * for the service, or it will be completely ignored; in the very least, * this is a formalization for deprecating services. * * Generated from protobuf field optional bool deprecated = 33 [default = false]; * @return bool */ public function getDeprecated() { return isset($this->deprecated) ? $this->deprecated : false; } public function hasDeprecated() { return isset($this->deprecated); } public function clearDeprecated() { unset($this->deprecated); } /** * Is this service deprecated? * Depending on the target platform, this can emit Deprecated annotations * for the service, or it will be completely ignored; in the very least, * this is a formalization for deprecating services. * * Generated from protobuf field optional bool deprecated = 33 [default = false]; * @param bool $var * @return $this */ public function setDeprecated($var) { GPBUtil::checkBool($var); $this->deprecated = $var; return $this; } /** * The parser stores options it doesn't recognize here. See above. * * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; * @return RepeatedField<\Google\Protobuf\Internal\UninterpretedOption> */ public function getUninterpretedOption() { return $this->uninterpreted_option; } /** * The parser stores options it doesn't recognize here. See above. * * Generated from protobuf field repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; * @param \Google\Protobuf\Internal\UninterpretedOption[] $var * @return $this */ public function setUninterpretedOption($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption::class); $this->uninterpreted_option = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/SourceCodeInfo/Location.php ================================================ google.protobuf.SourceCodeInfo.Location */ class Location extends \Google\Protobuf\Internal\Message { /** * Identifies which part of the FileDescriptorProto was defined at this * location. * Each element is a field number or an index. They form a path from * the root FileDescriptorProto to the place where the definition appears. * For example, this path: * [ 4, 3, 2, 7, 1 ] * refers to: * file.message_type(3) // 4, 3 * .field(7) // 2, 7 * .name() // 1 * This is because FileDescriptorProto.message_type has field number 4: * repeated DescriptorProto message_type = 4; * and DescriptorProto.field has field number 2: * repeated FieldDescriptorProto field = 2; * and FieldDescriptorProto.name has field number 1: * optional string name = 1; * Thus, the above path gives the location of a field name. If we removed * the last element: * [ 4, 3, 2, 7 ] * this path refers to the whole field declaration (from the beginning * of the label to the terminating semicolon). * * Generated from protobuf field repeated int32 path = 1 [packed = true]; */ private $path; /** * Always has exactly three or four elements: start line, start column, * end line (optional, otherwise assumed same as start line), end column. * These are packed into a single field for efficiency. Note that line * and column numbers are zero-based -- typically you will want to add * 1 to each before displaying to a user. * * Generated from protobuf field repeated int32 span = 2 [packed = true]; */ private $span; /** * If this SourceCodeInfo represents a complete declaration, these are any * comments appearing before and after the declaration which appear to be * attached to the declaration. * A series of line comments appearing on consecutive lines, with no other * tokens appearing on those lines, will be treated as a single comment. * leading_detached_comments will keep paragraphs of comments that appear * before (but not connected to) the current element. Each paragraph, * separated by empty lines, will be one comment element in the repeated * field. * Only the comment content is provided; comment markers (e.g. //) are * stripped out. For block comments, leading whitespace and an asterisk * will be stripped from the beginning of each line other than the first. * Newlines are included in the output. * Examples: * optional int32 foo = 1; // Comment attached to foo. * // Comment attached to bar. * optional int32 bar = 2; * optional string baz = 3; * // Comment attached to baz. * // Another line attached to baz. * // Comment attached to moo. * // * // Another line attached to moo. * optional double moo = 4; * // Detached comment for corge. This is not leading or trailing comments * // to moo or corge because there are blank lines separating it from * // both. * // Detached comment for corge paragraph 2. * optional string corge = 5; * /* Block comment attached * * to corge. Leading asterisks * * will be removed. {@*} * /* Block comment attached to * * grault. {@*} * optional int32 grault = 6; * // ignored detached comments. * * Generated from protobuf field optional string leading_comments = 3; */ protected $leading_comments = null; /** * Generated from protobuf field optional string trailing_comments = 4; */ protected $trailing_comments = null; /** * Generated from protobuf field repeated string leading_detached_comments = 6; */ private $leading_detached_comments; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type int[] $path * Identifies which part of the FileDescriptorProto was defined at this * location. * Each element is a field number or an index. They form a path from * the root FileDescriptorProto to the place where the definition appears. * For example, this path: * [ 4, 3, 2, 7, 1 ] * refers to: * file.message_type(3) // 4, 3 * .field(7) // 2, 7 * .name() // 1 * This is because FileDescriptorProto.message_type has field number 4: * repeated DescriptorProto message_type = 4; * and DescriptorProto.field has field number 2: * repeated FieldDescriptorProto field = 2; * and FieldDescriptorProto.name has field number 1: * optional string name = 1; * Thus, the above path gives the location of a field name. If we removed * the last element: * [ 4, 3, 2, 7 ] * this path refers to the whole field declaration (from the beginning * of the label to the terminating semicolon). * @type int[] $span * Always has exactly three or four elements: start line, start column, * end line (optional, otherwise assumed same as start line), end column. * These are packed into a single field for efficiency. Note that line * and column numbers are zero-based -- typically you will want to add * 1 to each before displaying to a user. * @type string $leading_comments * If this SourceCodeInfo represents a complete declaration, these are any * comments appearing before and after the declaration which appear to be * attached to the declaration. * A series of line comments appearing on consecutive lines, with no other * tokens appearing on those lines, will be treated as a single comment. * leading_detached_comments will keep paragraphs of comments that appear * before (but not connected to) the current element. Each paragraph, * separated by empty lines, will be one comment element in the repeated * field. * Only the comment content is provided; comment markers (e.g. //) are * stripped out. For block comments, leading whitespace and an asterisk * will be stripped from the beginning of each line other than the first. * Newlines are included in the output. * Examples: * optional int32 foo = 1; // Comment attached to foo. * // Comment attached to bar. * optional int32 bar = 2; * optional string baz = 3; * // Comment attached to baz. * // Another line attached to baz. * // Comment attached to moo. * // * // Another line attached to moo. * optional double moo = 4; * // Detached comment for corge. This is not leading or trailing comments * // to moo or corge because there are blank lines separating it from * // both. * // Detached comment for corge paragraph 2. * optional string corge = 5; * /* Block comment attached * * to corge. Leading asterisks * * will be removed. {@*} * /* Block comment attached to * * grault. {@*} * optional int32 grault = 6; * // ignored detached comments. * @type string $trailing_comments * @type string[] $leading_detached_comments * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); parent::__construct($data); } /** * Identifies which part of the FileDescriptorProto was defined at this * location. * Each element is a field number or an index. They form a path from * the root FileDescriptorProto to the place where the definition appears. * For example, this path: * [ 4, 3, 2, 7, 1 ] * refers to: * file.message_type(3) // 4, 3 * .field(7) // 2, 7 * .name() // 1 * This is because FileDescriptorProto.message_type has field number 4: * repeated DescriptorProto message_type = 4; * and DescriptorProto.field has field number 2: * repeated FieldDescriptorProto field = 2; * and FieldDescriptorProto.name has field number 1: * optional string name = 1; * Thus, the above path gives the location of a field name. If we removed * the last element: * [ 4, 3, 2, 7 ] * this path refers to the whole field declaration (from the beginning * of the label to the terminating semicolon). * * Generated from protobuf field repeated int32 path = 1 [packed = true]; * @return RepeatedField */ public function getPath() { return $this->path; } /** * Identifies which part of the FileDescriptorProto was defined at this * location. * Each element is a field number or an index. They form a path from * the root FileDescriptorProto to the place where the definition appears. * For example, this path: * [ 4, 3, 2, 7, 1 ] * refers to: * file.message_type(3) // 4, 3 * .field(7) // 2, 7 * .name() // 1 * This is because FileDescriptorProto.message_type has field number 4: * repeated DescriptorProto message_type = 4; * and DescriptorProto.field has field number 2: * repeated FieldDescriptorProto field = 2; * and FieldDescriptorProto.name has field number 1: * optional string name = 1; * Thus, the above path gives the location of a field name. If we removed * the last element: * [ 4, 3, 2, 7 ] * this path refers to the whole field declaration (from the beginning * of the label to the terminating semicolon). * * Generated from protobuf field repeated int32 path = 1 [packed = true]; * @param int[] $var * @return $this */ public function setPath($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32); $this->path = $arr; return $this; } /** * Always has exactly three or four elements: start line, start column, * end line (optional, otherwise assumed same as start line), end column. * These are packed into a single field for efficiency. Note that line * and column numbers are zero-based -- typically you will want to add * 1 to each before displaying to a user. * * Generated from protobuf field repeated int32 span = 2 [packed = true]; * @return RepeatedField */ public function getSpan() { return $this->span; } /** * Always has exactly three or four elements: start line, start column, * end line (optional, otherwise assumed same as start line), end column. * These are packed into a single field for efficiency. Note that line * and column numbers are zero-based -- typically you will want to add * 1 to each before displaying to a user. * * Generated from protobuf field repeated int32 span = 2 [packed = true]; * @param int[] $var * @return $this */ public function setSpan($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::INT32); $this->span = $arr; return $this; } /** * If this SourceCodeInfo represents a complete declaration, these are any * comments appearing before and after the declaration which appear to be * attached to the declaration. * A series of line comments appearing on consecutive lines, with no other * tokens appearing on those lines, will be treated as a single comment. * leading_detached_comments will keep paragraphs of comments that appear * before (but not connected to) the current element. Each paragraph, * separated by empty lines, will be one comment element in the repeated * field. * Only the comment content is provided; comment markers (e.g. //) are * stripped out. For block comments, leading whitespace and an asterisk * will be stripped from the beginning of each line other than the first. * Newlines are included in the output. * Examples: * optional int32 foo = 1; // Comment attached to foo. * // Comment attached to bar. * optional int32 bar = 2; * optional string baz = 3; * // Comment attached to baz. * // Another line attached to baz. * // Comment attached to moo. * // * // Another line attached to moo. * optional double moo = 4; * // Detached comment for corge. This is not leading or trailing comments * // to moo or corge because there are blank lines separating it from * // both. * // Detached comment for corge paragraph 2. * optional string corge = 5; * /* Block comment attached * * to corge. Leading asterisks * * will be removed. {@*} * /* Block comment attached to * * grault. {@*} * optional int32 grault = 6; * // ignored detached comments. * * Generated from protobuf field optional string leading_comments = 3; * @return string */ public function getLeadingComments() { return isset($this->leading_comments) ? $this->leading_comments : ''; } public function hasLeadingComments() { return isset($this->leading_comments); } public function clearLeadingComments() { unset($this->leading_comments); } /** * If this SourceCodeInfo represents a complete declaration, these are any * comments appearing before and after the declaration which appear to be * attached to the declaration. * A series of line comments appearing on consecutive lines, with no other * tokens appearing on those lines, will be treated as a single comment. * leading_detached_comments will keep paragraphs of comments that appear * before (but not connected to) the current element. Each paragraph, * separated by empty lines, will be one comment element in the repeated * field. * Only the comment content is provided; comment markers (e.g. //) are * stripped out. For block comments, leading whitespace and an asterisk * will be stripped from the beginning of each line other than the first. * Newlines are included in the output. * Examples: * optional int32 foo = 1; // Comment attached to foo. * // Comment attached to bar. * optional int32 bar = 2; * optional string baz = 3; * // Comment attached to baz. * // Another line attached to baz. * // Comment attached to moo. * // * // Another line attached to moo. * optional double moo = 4; * // Detached comment for corge. This is not leading or trailing comments * // to moo or corge because there are blank lines separating it from * // both. * // Detached comment for corge paragraph 2. * optional string corge = 5; * /* Block comment attached * * to corge. Leading asterisks * * will be removed. {@*} * /* Block comment attached to * * grault. {@*} * optional int32 grault = 6; * // ignored detached comments. * * Generated from protobuf field optional string leading_comments = 3; * @param string $var * @return $this */ public function setLeadingComments($var) { GPBUtil::checkString($var, True); $this->leading_comments = $var; return $this; } /** * Generated from protobuf field optional string trailing_comments = 4; * @return string */ public function getTrailingComments() { return isset($this->trailing_comments) ? $this->trailing_comments : ''; } public function hasTrailingComments() { return isset($this->trailing_comments); } public function clearTrailingComments() { unset($this->trailing_comments); } /** * Generated from protobuf field optional string trailing_comments = 4; * @param string $var * @return $this */ public function setTrailingComments($var) { GPBUtil::checkString($var, True); $this->trailing_comments = $var; return $this; } /** * Generated from protobuf field repeated string leading_detached_comments = 6; * @return RepeatedField */ public function getLeadingDetachedComments() { return $this->leading_detached_comments; } /** * Generated from protobuf field repeated string leading_detached_comments = 6; * @param string[] $var * @return $this */ public function setLeadingDetachedComments($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->leading_detached_comments = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/SourceCodeInfo.php ================================================ google.protobuf.SourceCodeInfo */ class SourceCodeInfo extends \Google\Protobuf\Internal\Message { /** * A Location identifies a piece of source code in a .proto file which * corresponds to a particular definition. This information is intended * to be useful to IDEs, code indexers, documentation generators, and similar * tools. * For example, say we have a file like: * message Foo { * optional string foo = 1; * } * Let's look at just the field definition: * optional string foo = 1; * ^ ^^ ^^ ^ ^^^ * a bc de f ghi * We have the following locations: * span path represents * [a,i) [ 4, 0, 2, 0 ] The whole field definition. * [a,b) [ 4, 0, 2, 0, 4 ] The label (optional). * [c,d) [ 4, 0, 2, 0, 5 ] The type (string). * [e,f) [ 4, 0, 2, 0, 1 ] The name (foo). * [g,h) [ 4, 0, 2, 0, 3 ] The number (1). * Notes: * - A location may refer to a repeated field itself (i.e. not to any * particular index within it). This is used whenever a set of elements are * logically enclosed in a single code segment. For example, an entire * extend block (possibly containing multiple extension definitions) will * have an outer location whose path refers to the "extensions" repeated * field without an index. * - Multiple locations may have the same path. This happens when a single * logical declaration is spread out across multiple places. The most * obvious example is the "extend" block again -- there may be multiple * extend blocks in the same scope, each of which will have the same path. * - A location's span is not always a subset of its parent's span. For * example, the "extendee" of an extension declaration appears at the * beginning of the "extend" block and is shared by all extensions within * the block. * - Just because a location's span is a subset of some other location's span * does not mean that it is a descendant. For example, a "group" defines * both a type and a field in a single declaration. Thus, the locations * corresponding to the type and field and their components will overlap. * - Code which tries to interpret locations should probably be designed to * ignore those that it doesn't understand, as more types of locations could * be recorded in the future. * * Generated from protobuf field repeated .google.protobuf.SourceCodeInfo.Location location = 1; */ private $location; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type \Google\Protobuf\Internal\SourceCodeInfo\Location[] $location * A Location identifies a piece of source code in a .proto file which * corresponds to a particular definition. This information is intended * to be useful to IDEs, code indexers, documentation generators, and similar * tools. * For example, say we have a file like: * message Foo { * optional string foo = 1; * } * Let's look at just the field definition: * optional string foo = 1; * ^ ^^ ^^ ^ ^^^ * a bc de f ghi * We have the following locations: * span path represents * [a,i) [ 4, 0, 2, 0 ] The whole field definition. * [a,b) [ 4, 0, 2, 0, 4 ] The label (optional). * [c,d) [ 4, 0, 2, 0, 5 ] The type (string). * [e,f) [ 4, 0, 2, 0, 1 ] The name (foo). * [g,h) [ 4, 0, 2, 0, 3 ] The number (1). * Notes: * - A location may refer to a repeated field itself (i.e. not to any * particular index within it). This is used whenever a set of elements are * logically enclosed in a single code segment. For example, an entire * extend block (possibly containing multiple extension definitions) will * have an outer location whose path refers to the "extensions" repeated * field without an index. * - Multiple locations may have the same path. This happens when a single * logical declaration is spread out across multiple places. The most * obvious example is the "extend" block again -- there may be multiple * extend blocks in the same scope, each of which will have the same path. * - A location's span is not always a subset of its parent's span. For * example, the "extendee" of an extension declaration appears at the * beginning of the "extend" block and is shared by all extensions within * the block. * - Just because a location's span is a subset of some other location's span * does not mean that it is a descendant. For example, a "group" defines * both a type and a field in a single declaration. Thus, the locations * corresponding to the type and field and their components will overlap. * - Code which tries to interpret locations should probably be designed to * ignore those that it doesn't understand, as more types of locations could * be recorded in the future. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); parent::__construct($data); } /** * A Location identifies a piece of source code in a .proto file which * corresponds to a particular definition. This information is intended * to be useful to IDEs, code indexers, documentation generators, and similar * tools. * For example, say we have a file like: * message Foo { * optional string foo = 1; * } * Let's look at just the field definition: * optional string foo = 1; * ^ ^^ ^^ ^ ^^^ * a bc de f ghi * We have the following locations: * span path represents * [a,i) [ 4, 0, 2, 0 ] The whole field definition. * [a,b) [ 4, 0, 2, 0, 4 ] The label (optional). * [c,d) [ 4, 0, 2, 0, 5 ] The type (string). * [e,f) [ 4, 0, 2, 0, 1 ] The name (foo). * [g,h) [ 4, 0, 2, 0, 3 ] The number (1). * Notes: * - A location may refer to a repeated field itself (i.e. not to any * particular index within it). This is used whenever a set of elements are * logically enclosed in a single code segment. For example, an entire * extend block (possibly containing multiple extension definitions) will * have an outer location whose path refers to the "extensions" repeated * field without an index. * - Multiple locations may have the same path. This happens when a single * logical declaration is spread out across multiple places. The most * obvious example is the "extend" block again -- there may be multiple * extend blocks in the same scope, each of which will have the same path. * - A location's span is not always a subset of its parent's span. For * example, the "extendee" of an extension declaration appears at the * beginning of the "extend" block and is shared by all extensions within * the block. * - Just because a location's span is a subset of some other location's span * does not mean that it is a descendant. For example, a "group" defines * both a type and a field in a single declaration. Thus, the locations * corresponding to the type and field and their components will overlap. * - Code which tries to interpret locations should probably be designed to * ignore those that it doesn't understand, as more types of locations could * be recorded in the future. * * Generated from protobuf field repeated .google.protobuf.SourceCodeInfo.Location location = 1; * @return RepeatedField<\Google\Protobuf\Internal\SourceCodeInfo\Location> */ public function getLocation() { return $this->location; } /** * A Location identifies a piece of source code in a .proto file which * corresponds to a particular definition. This information is intended * to be useful to IDEs, code indexers, documentation generators, and similar * tools. * For example, say we have a file like: * message Foo { * optional string foo = 1; * } * Let's look at just the field definition: * optional string foo = 1; * ^ ^^ ^^ ^ ^^^ * a bc de f ghi * We have the following locations: * span path represents * [a,i) [ 4, 0, 2, 0 ] The whole field definition. * [a,b) [ 4, 0, 2, 0, 4 ] The label (optional). * [c,d) [ 4, 0, 2, 0, 5 ] The type (string). * [e,f) [ 4, 0, 2, 0, 1 ] The name (foo). * [g,h) [ 4, 0, 2, 0, 3 ] The number (1). * Notes: * - A location may refer to a repeated field itself (i.e. not to any * particular index within it). This is used whenever a set of elements are * logically enclosed in a single code segment. For example, an entire * extend block (possibly containing multiple extension definitions) will * have an outer location whose path refers to the "extensions" repeated * field without an index. * - Multiple locations may have the same path. This happens when a single * logical declaration is spread out across multiple places. The most * obvious example is the "extend" block again -- there may be multiple * extend blocks in the same scope, each of which will have the same path. * - A location's span is not always a subset of its parent's span. For * example, the "extendee" of an extension declaration appears at the * beginning of the "extend" block and is shared by all extensions within * the block. * - Just because a location's span is a subset of some other location's span * does not mean that it is a descendant. For example, a "group" defines * both a type and a field in a single declaration. Thus, the locations * corresponding to the type and field and their components will overlap. * - Code which tries to interpret locations should probably be designed to * ignore those that it doesn't understand, as more types of locations could * be recorded in the future. * * Generated from protobuf field repeated .google.protobuf.SourceCodeInfo.Location location = 1; * @param \Google\Protobuf\Internal\SourceCodeInfo\Location[] $var * @return $this */ public function setLocation($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\SourceCodeInfo\Location::class); $this->location = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/SymbolVisibility.php ================================================ google.protobuf.SymbolVisibility */ class SymbolVisibility { /** * Generated from protobuf enum VISIBILITY_UNSET = 0; */ const VISIBILITY_UNSET = 0; /** * Generated from protobuf enum VISIBILITY_LOCAL = 1; */ const VISIBILITY_LOCAL = 1; /** * Generated from protobuf enum VISIBILITY_EXPORT = 2; */ const VISIBILITY_EXPORT = 2; private static $valueToName = [ self::VISIBILITY_UNSET => 'VISIBILITY_UNSET', self::VISIBILITY_LOCAL => 'VISIBILITY_LOCAL', self::VISIBILITY_EXPORT => 'VISIBILITY_EXPORT', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/TimestampBase.php ================================================ seconds = $datetime->getTimestamp(); $this->nanos = 1000 * $datetime->format('u'); } /** * Converts Timestamp to PHP DateTime. * * @return \DateTime $datetime */ public function toDateTime() { $time = sprintf('%s.%06d', $this->seconds, $this->nanos / 1000); return \DateTime::createFromFormat('U.u', $time); } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/UninterpretedOption/NamePart.php ================================================ google.protobuf.UninterpretedOption.NamePart */ class NamePart extends \Google\Protobuf\Internal\Message { /** * Generated from protobuf field required string name_part = 1; */ protected $name_part = null; /** * Generated from protobuf field required bool is_extension = 2; */ protected $is_extension = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $name_part * @type bool $is_extension * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); parent::__construct($data); } /** * Generated from protobuf field required string name_part = 1; * @return string */ public function getNamePart() { return isset($this->name_part) ? $this->name_part : ''; } public function hasNamePart() { return isset($this->name_part); } public function clearNamePart() { unset($this->name_part); } /** * Generated from protobuf field required string name_part = 1; * @param string $var * @return $this */ public function setNamePart($var) { GPBUtil::checkString($var, True); $this->name_part = $var; return $this; } /** * Generated from protobuf field required bool is_extension = 2; * @return bool */ public function getIsExtension() { return isset($this->is_extension) ? $this->is_extension : false; } public function hasIsExtension() { return isset($this->is_extension); } public function clearIsExtension() { unset($this->is_extension); } /** * Generated from protobuf field required bool is_extension = 2; * @param bool $var * @return $this */ public function setIsExtension($var) { GPBUtil::checkBool($var); $this->is_extension = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Internal/UninterpretedOption.php ================================================ google.protobuf.UninterpretedOption */ class UninterpretedOption extends \Google\Protobuf\Internal\Message { /** * Generated from protobuf field repeated .google.protobuf.UninterpretedOption.NamePart name = 2; */ private $name; /** * The value of the uninterpreted option, in whatever type the tokenizer * identified it as during parsing. Exactly one of these should be set. * * Generated from protobuf field optional string identifier_value = 3; */ protected $identifier_value = null; /** * Generated from protobuf field optional uint64 positive_int_value = 4; */ protected $positive_int_value = null; /** * Generated from protobuf field optional int64 negative_int_value = 5; */ protected $negative_int_value = null; /** * Generated from protobuf field optional double double_value = 6; */ protected $double_value = null; /** * Generated from protobuf field optional bytes string_value = 7; */ protected $string_value = null; /** * Generated from protobuf field optional string aggregate_value = 8; */ protected $aggregate_value = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type \Google\Protobuf\Internal\UninterpretedOption\NamePart[] $name * @type string $identifier_value * The value of the uninterpreted option, in whatever type the tokenizer * identified it as during parsing. Exactly one of these should be set. * @type int|string $positive_int_value * @type int|string $negative_int_value * @type float $double_value * @type string $string_value * @type string $aggregate_value * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Internal\Descriptor::initOnce(); parent::__construct($data); } /** * Generated from protobuf field repeated .google.protobuf.UninterpretedOption.NamePart name = 2; * @return RepeatedField<\Google\Protobuf\Internal\UninterpretedOption\NamePart> */ public function getName() { return $this->name; } /** * Generated from protobuf field repeated .google.protobuf.UninterpretedOption.NamePart name = 2; * @param \Google\Protobuf\Internal\UninterpretedOption\NamePart[] $var * @return $this */ public function setName($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Internal\UninterpretedOption\NamePart::class); $this->name = $arr; return $this; } /** * The value of the uninterpreted option, in whatever type the tokenizer * identified it as during parsing. Exactly one of these should be set. * * Generated from protobuf field optional string identifier_value = 3; * @return string */ public function getIdentifierValue() { return isset($this->identifier_value) ? $this->identifier_value : ''; } public function hasIdentifierValue() { return isset($this->identifier_value); } public function clearIdentifierValue() { unset($this->identifier_value); } /** * The value of the uninterpreted option, in whatever type the tokenizer * identified it as during parsing. Exactly one of these should be set. * * Generated from protobuf field optional string identifier_value = 3; * @param string $var * @return $this */ public function setIdentifierValue($var) { GPBUtil::checkString($var, True); $this->identifier_value = $var; return $this; } /** * Generated from protobuf field optional uint64 positive_int_value = 4; * @return int|string */ public function getPositiveIntValue() { return isset($this->positive_int_value) ? $this->positive_int_value : 0; } public function hasPositiveIntValue() { return isset($this->positive_int_value); } public function clearPositiveIntValue() { unset($this->positive_int_value); } /** * Generated from protobuf field optional uint64 positive_int_value = 4; * @param int|string $var * @return $this */ public function setPositiveIntValue($var) { GPBUtil::checkUint64($var); $this->positive_int_value = $var; return $this; } /** * Generated from protobuf field optional int64 negative_int_value = 5; * @return int|string */ public function getNegativeIntValue() { return isset($this->negative_int_value) ? $this->negative_int_value : 0; } public function hasNegativeIntValue() { return isset($this->negative_int_value); } public function clearNegativeIntValue() { unset($this->negative_int_value); } /** * Generated from protobuf field optional int64 negative_int_value = 5; * @param int|string $var * @return $this */ public function setNegativeIntValue($var) { GPBUtil::checkInt64($var); $this->negative_int_value = $var; return $this; } /** * Generated from protobuf field optional double double_value = 6; * @return float */ public function getDoubleValue() { return isset($this->double_value) ? $this->double_value : 0.0; } public function hasDoubleValue() { return isset($this->double_value); } public function clearDoubleValue() { unset($this->double_value); } /** * Generated from protobuf field optional double double_value = 6; * @param float $var * @return $this */ public function setDoubleValue($var) { GPBUtil::checkDouble($var); $this->double_value = $var; return $this; } /** * Generated from protobuf field optional bytes string_value = 7; * @return string */ public function getStringValue() { return isset($this->string_value) ? $this->string_value : ''; } public function hasStringValue() { return isset($this->string_value); } public function clearStringValue() { unset($this->string_value); } /** * Generated from protobuf field optional bytes string_value = 7; * @param string $var * @return $this */ public function setStringValue($var) { GPBUtil::checkString($var, False); $this->string_value = $var; return $this; } /** * Generated from protobuf field optional string aggregate_value = 8; * @return string */ public function getAggregateValue() { return isset($this->aggregate_value) ? $this->aggregate_value : ''; } public function hasAggregateValue() { return isset($this->aggregate_value); } public function clearAggregateValue() { unset($this->aggregate_value); } /** * Generated from protobuf field optional string aggregate_value = 8; * @param string $var * @return $this */ public function setAggregateValue($var) { GPBUtil::checkString($var, True); $this->aggregate_value = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/ListValue.php ================================================ google.protobuf.ListValue */ class ListValue extends \Google\Protobuf\Internal\Message { /** * Repeated field of dynamically typed values. * * Generated from protobuf field repeated .google.protobuf.Value values = 1; */ private $values; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type \Google\Protobuf\Value[] $values * Repeated field of dynamically typed values. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Struct::initOnce(); parent::__construct($data); } /** * Repeated field of dynamically typed values. * * Generated from protobuf field repeated .google.protobuf.Value values = 1; * @return RepeatedField<\Google\Protobuf\Value> */ public function getValues() { return $this->values; } /** * Repeated field of dynamically typed values. * * Generated from protobuf field repeated .google.protobuf.Value values = 1; * @param \Google\Protobuf\Value[] $var * @return $this */ public function setValues($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Value::class); $this->values = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Method.php ================================================ google.protobuf.Method */ class Method extends \Google\Protobuf\Internal\Message { /** * The simple name of this method. * * Generated from protobuf field string name = 1; */ protected $name = ''; /** * A URL of the input message type. * * Generated from protobuf field string request_type_url = 2; */ protected $request_type_url = ''; /** * If true, the request is streamed. * * Generated from protobuf field bool request_streaming = 3; */ protected $request_streaming = false; /** * The URL of the output message type. * * Generated from protobuf field string response_type_url = 4; */ protected $response_type_url = ''; /** * If true, the response is streamed. * * Generated from protobuf field bool response_streaming = 5; */ protected $response_streaming = false; /** * Any metadata attached to the method. * * Generated from protobuf field repeated .google.protobuf.Option options = 6; */ private $options; /** * The source syntax of this method. * This field should be ignored, instead the syntax should be inherited from * Api. This is similar to Field and EnumValue. * * Generated from protobuf field .google.protobuf.Syntax syntax = 7 [deprecated = true]; * @deprecated */ protected $syntax = 0; /** * The source edition string, only valid when syntax is SYNTAX_EDITIONS. * This field should be ignored, instead the edition should be inherited from * Api. This is similar to Field and EnumValue. * * Generated from protobuf field string edition = 8 [deprecated = true]; * @deprecated */ protected $edition = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $name * The simple name of this method. * @type string $request_type_url * A URL of the input message type. * @type bool $request_streaming * If true, the request is streamed. * @type string $response_type_url * The URL of the output message type. * @type bool $response_streaming * If true, the response is streamed. * @type \Google\Protobuf\Option[] $options * Any metadata attached to the method. * @type int $syntax * The source syntax of this method. * This field should be ignored, instead the syntax should be inherited from * Api. This is similar to Field and EnumValue. * @type string $edition * The source edition string, only valid when syntax is SYNTAX_EDITIONS. * This field should be ignored, instead the edition should be inherited from * Api. This is similar to Field and EnumValue. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Api::initOnce(); parent::__construct($data); } /** * The simple name of this method. * * Generated from protobuf field string name = 1; * @return string */ public function getName() { return $this->name; } /** * The simple name of this method. * * Generated from protobuf field string name = 1; * @param string $var * @return $this */ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; return $this; } /** * A URL of the input message type. * * Generated from protobuf field string request_type_url = 2; * @return string */ public function getRequestTypeUrl() { return $this->request_type_url; } /** * A URL of the input message type. * * Generated from protobuf field string request_type_url = 2; * @param string $var * @return $this */ public function setRequestTypeUrl($var) { GPBUtil::checkString($var, True); $this->request_type_url = $var; return $this; } /** * If true, the request is streamed. * * Generated from protobuf field bool request_streaming = 3; * @return bool */ public function getRequestStreaming() { return $this->request_streaming; } /** * If true, the request is streamed. * * Generated from protobuf field bool request_streaming = 3; * @param bool $var * @return $this */ public function setRequestStreaming($var) { GPBUtil::checkBool($var); $this->request_streaming = $var; return $this; } /** * The URL of the output message type. * * Generated from protobuf field string response_type_url = 4; * @return string */ public function getResponseTypeUrl() { return $this->response_type_url; } /** * The URL of the output message type. * * Generated from protobuf field string response_type_url = 4; * @param string $var * @return $this */ public function setResponseTypeUrl($var) { GPBUtil::checkString($var, True); $this->response_type_url = $var; return $this; } /** * If true, the response is streamed. * * Generated from protobuf field bool response_streaming = 5; * @return bool */ public function getResponseStreaming() { return $this->response_streaming; } /** * If true, the response is streamed. * * Generated from protobuf field bool response_streaming = 5; * @param bool $var * @return $this */ public function setResponseStreaming($var) { GPBUtil::checkBool($var); $this->response_streaming = $var; return $this; } /** * Any metadata attached to the method. * * Generated from protobuf field repeated .google.protobuf.Option options = 6; * @return RepeatedField<\Google\Protobuf\Option> */ public function getOptions() { return $this->options; } /** * Any metadata attached to the method. * * Generated from protobuf field repeated .google.protobuf.Option options = 6; * @param \Google\Protobuf\Option[] $var * @return $this */ public function setOptions($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Option::class); $this->options = $arr; return $this; } /** * The source syntax of this method. * This field should be ignored, instead the syntax should be inherited from * Api. This is similar to Field and EnumValue. * * Generated from protobuf field .google.protobuf.Syntax syntax = 7 [deprecated = true]; * @return int * @deprecated */ public function getSyntax() { if ($this->syntax !== 0) { @trigger_error('syntax is deprecated.', E_USER_DEPRECATED); } return $this->syntax; } /** * The source syntax of this method. * This field should be ignored, instead the syntax should be inherited from * Api. This is similar to Field and EnumValue. * * Generated from protobuf field .google.protobuf.Syntax syntax = 7 [deprecated = true]; * @param int $var * @return $this * @deprecated */ public function setSyntax($var) { @trigger_error('syntax is deprecated.', E_USER_DEPRECATED); GPBUtil::checkEnum($var, \Google\Protobuf\Syntax::class); $this->syntax = $var; return $this; } /** * The source edition string, only valid when syntax is SYNTAX_EDITIONS. * This field should be ignored, instead the edition should be inherited from * Api. This is similar to Field and EnumValue. * * Generated from protobuf field string edition = 8 [deprecated = true]; * @return string * @deprecated */ public function getEdition() { if ($this->edition !== '') { @trigger_error('edition is deprecated.', E_USER_DEPRECATED); } return $this->edition; } /** * The source edition string, only valid when syntax is SYNTAX_EDITIONS. * This field should be ignored, instead the edition should be inherited from * Api. This is similar to Field and EnumValue. * * Generated from protobuf field string edition = 8 [deprecated = true]; * @param string $var * @return $this * @deprecated */ public function setEdition($var) { @trigger_error('edition is deprecated.', E_USER_DEPRECATED); GPBUtil::checkString($var, True); $this->edition = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Mixin.php ================================================ google.protobuf.Mixin */ class Mixin extends \Google\Protobuf\Internal\Message { /** * The fully qualified name of the interface which is included. * * Generated from protobuf field string name = 1; */ protected $name = ''; /** * If non-empty specifies a path under which inherited HTTP paths * are rooted. * * Generated from protobuf field string root = 2; */ protected $root = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $name * The fully qualified name of the interface which is included. * @type string $root * If non-empty specifies a path under which inherited HTTP paths * are rooted. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Api::initOnce(); parent::__construct($data); } /** * The fully qualified name of the interface which is included. * * Generated from protobuf field string name = 1; * @return string */ public function getName() { return $this->name; } /** * The fully qualified name of the interface which is included. * * Generated from protobuf field string name = 1; * @param string $var * @return $this */ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; return $this; } /** * If non-empty specifies a path under which inherited HTTP paths * are rooted. * * Generated from protobuf field string root = 2; * @return string */ public function getRoot() { return $this->root; } /** * If non-empty specifies a path under which inherited HTTP paths * are rooted. * * Generated from protobuf field string root = 2; * @param string $var * @return $this */ public function setRoot($var) { GPBUtil::checkString($var, True); $this->root = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/NullValue.php ================================================ google.protobuf.NullValue */ class NullValue { /** * Null value. * * Generated from protobuf enum NULL_VALUE = 0; */ const NULL_VALUE = 0; private static $valueToName = [ self::NULL_VALUE => 'NULL_VALUE', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/OneofDescriptor.php ================================================ internal_desc = $internal_desc; } /** * @return string The name of the oneof */ public function getName() { return $this->internal_desc->getName(); } /** * @param int $index Must be >= 0 and < getFieldCount() * @return FieldDescriptor */ public function getField($index) { if ( is_null($this->internal_desc->getFields()) || !isset($this->internal_desc->getFields()[$index]) ) { return null; } return $this->getPublicDescriptor($this->internal_desc->getFields()[$index]); } /** * @return int Number of fields in the oneof */ public function getFieldCount() { return count($this->internal_desc->getFields()); } public function isSynthetic() { return $this->internal_desc->isSynthetic(); } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Option.php ================================================ google.protobuf.Option */ class Option extends \Google\Protobuf\Internal\Message { /** * The option's name. For protobuf built-in options (options defined in * descriptor.proto), this is the short name. For example, `"map_entry"`. * For custom options, it should be the fully-qualified name. For example, * `"google.api.http"`. * * Generated from protobuf field string name = 1; */ protected $name = ''; /** * The option's value packed in an Any message. If the value is a primitive, * the corresponding wrapper type defined in google/protobuf/wrappers.proto * should be used. If the value is an enum, it should be stored as an int32 * value using the google.protobuf.Int32Value type. * * Generated from protobuf field .google.protobuf.Any value = 2; */ protected $value = null; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $name * The option's name. For protobuf built-in options (options defined in * descriptor.proto), this is the short name. For example, `"map_entry"`. * For custom options, it should be the fully-qualified name. For example, * `"google.api.http"`. * @type \Google\Protobuf\Any $value * The option's value packed in an Any message. If the value is a primitive, * the corresponding wrapper type defined in google/protobuf/wrappers.proto * should be used. If the value is an enum, it should be stored as an int32 * value using the google.protobuf.Int32Value type. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Type::initOnce(); parent::__construct($data); } /** * The option's name. For protobuf built-in options (options defined in * descriptor.proto), this is the short name. For example, `"map_entry"`. * For custom options, it should be the fully-qualified name. For example, * `"google.api.http"`. * * Generated from protobuf field string name = 1; * @return string */ public function getName() { return $this->name; } /** * The option's name. For protobuf built-in options (options defined in * descriptor.proto), this is the short name. For example, `"map_entry"`. * For custom options, it should be the fully-qualified name. For example, * `"google.api.http"`. * * Generated from protobuf field string name = 1; * @param string $var * @return $this */ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; return $this; } /** * The option's value packed in an Any message. If the value is a primitive, * the corresponding wrapper type defined in google/protobuf/wrappers.proto * should be used. If the value is an enum, it should be stored as an int32 * value using the google.protobuf.Int32Value type. * * Generated from protobuf field .google.protobuf.Any value = 2; * @return \Google\Protobuf\Any|null */ public function getValue() { return $this->value; } public function hasValue() { return isset($this->value); } public function clearValue() { unset($this->value); } /** * The option's value packed in an Any message. If the value is a primitive, * the corresponding wrapper type defined in google/protobuf/wrappers.proto * should be used. If the value is an enum, it should be stored as an int32 * value using the google.protobuf.Int32Value type. * * Generated from protobuf field .google.protobuf.Any value = 2; * @param \Google\Protobuf\Any $var * @return $this */ public function setValue($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Any::class); $this->value = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/PrintOptions.php ================================================ * @implements \IteratorAggregate */ class RepeatedField implements \ArrayAccess, \IteratorAggregate, \Countable { /** * @ignore */ private $container; /** * @ignore */ private $type; /** * @ignore * @var string|class-string */ private $klass; /** * Constructs an instance of RepeatedField. * * @param integer $type Type of the stored element. * @param string|class-string $klass Message/Enum class name (message/enum fields only). * @ignore */ public function __construct($type, $klass = null) { $this->container = []; $this->type = $type; if ($this->type == GPBType::MESSAGE) { $pool = DescriptorPool::getGeneratedPool(); $desc = $pool->getDescriptorByClassName($klass); if ($desc == NULL) { new $klass; // No msg class instance has been created before. $desc = $pool->getDescriptorByClassName($klass); } $this->klass = $desc->getClass(); } } /** * @ignore */ public function getType() { return $this->type; } /** * @ignore * @return string|class-string */ public function getClass() { return $this->klass; } /** * Return the element at the given index. * * This will also be called for: $ele = $arr[0] * * @param integer $offset The index of the element to be fetched. * @return T The stored element at given index. * @throws \ErrorException Invalid type for index. * @throws \ErrorException Non-existing index. * @todo need to add return type mixed (require update php version to 8.0) */ #[\ReturnTypeWillChange] public function offsetGet($offset) { return $this->container[$offset]; } /** * Assign the element at the given index. * * This will also be called for: $arr []= $ele and $arr[0] = ele * * @param int|null $offset The index of the element to be assigned. * @param T $value The element to be assigned. * @return void * @throws \ErrorException Invalid type for index. * @throws \ErrorException Non-existing index. * @throws \ErrorException Incorrect type of the element. * @todo need to add return type void (require update php version to 7.1) */ #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { switch ($this->type) { case GPBType::SFIXED32: case GPBType::SINT32: case GPBType::INT32: case GPBType::ENUM: GPBUtil::checkInt32($value); break; case GPBType::FIXED32: case GPBType::UINT32: GPBUtil::checkUint32($value); break; case GPBType::SFIXED64: case GPBType::SINT64: case GPBType::INT64: GPBUtil::checkInt64($value); break; case GPBType::FIXED64: case GPBType::UINT64: GPBUtil::checkUint64($value); break; case GPBType::FLOAT: GPBUtil::checkFloat($value); break; case GPBType::DOUBLE: GPBUtil::checkDouble($value); break; case GPBType::BOOL: GPBUtil::checkBool($value); break; case GPBType::BYTES: GPBUtil::checkString($value, false); break; case GPBType::STRING: GPBUtil::checkString($value, true); break; case GPBType::MESSAGE: if (is_null($value)) { throw new \TypeError("RepeatedField element cannot be null."); } GPBUtil::checkMessage($value, $this->klass); break; default: break; } if (is_null($offset)) { $this->container[] = $value; } else { $count = count($this->container); if (!is_numeric($offset) || $offset < 0 || $offset >= $count) { trigger_error( "Cannot modify element at the given index", E_USER_ERROR); return; } $this->container[$offset] = $value; } } /** * Remove the element at the given index. * * This will also be called for: unset($arr) * * @param integer $offset The index of the element to be removed. * @return void * @throws \ErrorException Invalid type for index. * @throws \ErrorException The element to be removed is not at the end of the * RepeatedField. * @todo need to add return type void (require update php version to 7.1) */ #[\ReturnTypeWillChange] public function offsetUnset($offset) { $count = count($this->container); if (!is_numeric($offset) || $count === 0 || $offset < 0 || $offset >= $count) { trigger_error( "Cannot remove element at the given index", E_USER_ERROR); return; } array_splice($this->container, $offset, 1); } /** * Check the existence of the element at the given index. * * This will also be called for: isset($arr) * * @param integer $offset The index of the element to be removed. * @return bool True if the element at the given offset exists. * @throws \ErrorException Invalid type for index. */ public function offsetExists($offset): bool { return isset($this->container[$offset]); } /** * @ignore */ public function getIterator(): Traversable { return new RepeatedFieldIter($this->container); } /** * Return the number of stored elements. * * This will also be called for: count($arr) * * @return integer The number of stored elements. */ public function count(): int { return count($this->container); } public function __debugInfo() { return array_map( function ($item) { if ($item instanceof Message || $item instanceof RepeatedField) { return $item->__debugInfo(); } return $item; }, iterator_to_array($this) ); } } class_alias(RepeatedField::class, Internal\RepeatedField::class); ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/SourceContext.php ================================================ google.protobuf.SourceContext */ class SourceContext extends \Google\Protobuf\Internal\Message { /** * The path-qualified name of the .proto file that contained the associated * protobuf element. For example: `"google/protobuf/source_context.proto"`. * * Generated from protobuf field string file_name = 1; */ protected $file_name = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $file_name * The path-qualified name of the .proto file that contained the associated * protobuf element. For example: `"google/protobuf/source_context.proto"`. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\SourceContext::initOnce(); parent::__construct($data); } /** * The path-qualified name of the .proto file that contained the associated * protobuf element. For example: `"google/protobuf/source_context.proto"`. * * Generated from protobuf field string file_name = 1; * @return string */ public function getFileName() { return $this->file_name; } /** * The path-qualified name of the .proto file that contained the associated * protobuf element. For example: `"google/protobuf/source_context.proto"`. * * Generated from protobuf field string file_name = 1; * @param string $var * @return $this */ public function setFileName($var) { GPBUtil::checkString($var, True); $this->file_name = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/StringValue.php ================================================ google.protobuf.StringValue */ class StringValue extends \Google\Protobuf\Internal\Message { /** * The string value. * * Generated from protobuf field string value = 1; */ protected $value = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $value * The string value. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Wrappers::initOnce(); parent::__construct($data); } /** * The string value. * * Generated from protobuf field string value = 1; * @return string */ public function getValue() { return $this->value; } /** * The string value. * * Generated from protobuf field string value = 1; * @param string $var * @return $this */ public function setValue($var) { GPBUtil::checkString($var, True); $this->value = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Struct.php ================================================ google.protobuf.Struct */ class Struct extends \Google\Protobuf\Internal\Message { /** * Unordered map of dynamically typed values. * * Generated from protobuf field map fields = 1; */ private $fields; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type array|\Google\Protobuf\Internal\MapField $fields * Unordered map of dynamically typed values. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Struct::initOnce(); parent::__construct($data); } /** * Unordered map of dynamically typed values. * * Generated from protobuf field map fields = 1; * @return \Google\Protobuf\Internal\MapField */ public function getFields() { return $this->fields; } /** * Unordered map of dynamically typed values. * * Generated from protobuf field map fields = 1; * @param array|\Google\Protobuf\Internal\MapField $var * @return $this */ public function setFields($var) { $arr = GPBUtil::checkMapField($var, \Google\Protobuf\Internal\GPBType::STRING, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Value::class); $this->fields = $arr; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Syntax.php ================================================ google.protobuf.Syntax */ class Syntax { /** * Syntax `proto2`. * * Generated from protobuf enum SYNTAX_PROTO2 = 0; */ const SYNTAX_PROTO2 = 0; /** * Syntax `proto3`. * * Generated from protobuf enum SYNTAX_PROTO3 = 1; */ const SYNTAX_PROTO3 = 1; /** * Syntax `editions`. * * Generated from protobuf enum SYNTAX_EDITIONS = 2; */ const SYNTAX_EDITIONS = 2; private static $valueToName = [ self::SYNTAX_PROTO2 => 'SYNTAX_PROTO2', self::SYNTAX_PROTO3 => 'SYNTAX_PROTO3', self::SYNTAX_EDITIONS => 'SYNTAX_EDITIONS', ]; public static function name($value) { if (!isset(self::$valueToName[$value])) { throw new UnexpectedValueException(sprintf( 'Enum %s has no name defined for value %s', __CLASS__, $value)); } return self::$valueToName[$value]; } public static function value($name) { $const = __CLASS__ . '::' . strtoupper($name); if (!defined($const)) { throw new UnexpectedValueException(sprintf( 'Enum %s has no value defined for name %s', __CLASS__, $name)); } return constant($const); } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Timestamp.php ================================================ google.protobuf.Timestamp */ class Timestamp extends \Google\Protobuf\Internal\TimestampBase { /** * Represents seconds of UTC time since Unix epoch 1970-01-01T00:00:00Z. Must * be between -315576000000 and 315576000000 inclusive (which corresponds to * 0001-01-01T00:00:00Z to 9999-12-31T23:59:59Z). * * Generated from protobuf field int64 seconds = 1; */ protected $seconds = 0; /** * Non-negative fractions of a second at nanosecond resolution. This field is * the nanosecond portion of the duration, not an alternative to seconds. * Negative second values with fractions must still have non-negative nanos * values that count forward in time. Must be between 0 and 999,999,999 * inclusive. * * Generated from protobuf field int32 nanos = 2; */ protected $nanos = 0; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type int|string $seconds * Represents seconds of UTC time since Unix epoch 1970-01-01T00:00:00Z. Must * be between -315576000000 and 315576000000 inclusive (which corresponds to * 0001-01-01T00:00:00Z to 9999-12-31T23:59:59Z). * @type int $nanos * Non-negative fractions of a second at nanosecond resolution. This field is * the nanosecond portion of the duration, not an alternative to seconds. * Negative second values with fractions must still have non-negative nanos * values that count forward in time. Must be between 0 and 999,999,999 * inclusive. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Timestamp::initOnce(); parent::__construct($data); } /** * Represents seconds of UTC time since Unix epoch 1970-01-01T00:00:00Z. Must * be between -315576000000 and 315576000000 inclusive (which corresponds to * 0001-01-01T00:00:00Z to 9999-12-31T23:59:59Z). * * Generated from protobuf field int64 seconds = 1; * @return int|string */ public function getSeconds() { return $this->seconds; } /** * Represents seconds of UTC time since Unix epoch 1970-01-01T00:00:00Z. Must * be between -315576000000 and 315576000000 inclusive (which corresponds to * 0001-01-01T00:00:00Z to 9999-12-31T23:59:59Z). * * Generated from protobuf field int64 seconds = 1; * @param int|string $var * @return $this */ public function setSeconds($var) { GPBUtil::checkInt64($var); $this->seconds = $var; return $this; } /** * Non-negative fractions of a second at nanosecond resolution. This field is * the nanosecond portion of the duration, not an alternative to seconds. * Negative second values with fractions must still have non-negative nanos * values that count forward in time. Must be between 0 and 999,999,999 * inclusive. * * Generated from protobuf field int32 nanos = 2; * @return int */ public function getNanos() { return $this->nanos; } /** * Non-negative fractions of a second at nanosecond resolution. This field is * the nanosecond portion of the duration, not an alternative to seconds. * Negative second values with fractions must still have non-negative nanos * values that count forward in time. Must be between 0 and 999,999,999 * inclusive. * * Generated from protobuf field int32 nanos = 2; * @param int $var * @return $this */ public function setNanos($var) { GPBUtil::checkInt32($var); $this->nanos = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Type.php ================================================ google.protobuf.Type */ class Type extends \Google\Protobuf\Internal\Message { /** * The fully qualified message name. * * Generated from protobuf field string name = 1; */ protected $name = ''; /** * The list of fields. * * Generated from protobuf field repeated .google.protobuf.Field fields = 2; */ private $fields; /** * The list of types appearing in `oneof` definitions in this type. * * Generated from protobuf field repeated string oneofs = 3; */ private $oneofs; /** * The protocol buffer options. * * Generated from protobuf field repeated .google.protobuf.Option options = 4; */ private $options; /** * The source context. * * Generated from protobuf field .google.protobuf.SourceContext source_context = 5; */ protected $source_context = null; /** * The source syntax. * * Generated from protobuf field .google.protobuf.Syntax syntax = 6; */ protected $syntax = 0; /** * The source edition string, only valid when syntax is SYNTAX_EDITIONS. * * Generated from protobuf field string edition = 7; */ protected $edition = ''; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type string $name * The fully qualified message name. * @type \Google\Protobuf\Field[] $fields * The list of fields. * @type string[] $oneofs * The list of types appearing in `oneof` definitions in this type. * @type \Google\Protobuf\Option[] $options * The protocol buffer options. * @type \Google\Protobuf\SourceContext $source_context * The source context. * @type int $syntax * The source syntax. * @type string $edition * The source edition string, only valid when syntax is SYNTAX_EDITIONS. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Type::initOnce(); parent::__construct($data); } /** * The fully qualified message name. * * Generated from protobuf field string name = 1; * @return string */ public function getName() { return $this->name; } /** * The fully qualified message name. * * Generated from protobuf field string name = 1; * @param string $var * @return $this */ public function setName($var) { GPBUtil::checkString($var, True); $this->name = $var; return $this; } /** * The list of fields. * * Generated from protobuf field repeated .google.protobuf.Field fields = 2; * @return RepeatedField<\Google\Protobuf\Field> */ public function getFields() { return $this->fields; } /** * The list of fields. * * Generated from protobuf field repeated .google.protobuf.Field fields = 2; * @param \Google\Protobuf\Field[] $var * @return $this */ public function setFields($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Field::class); $this->fields = $arr; return $this; } /** * The list of types appearing in `oneof` definitions in this type. * * Generated from protobuf field repeated string oneofs = 3; * @return RepeatedField */ public function getOneofs() { return $this->oneofs; } /** * The list of types appearing in `oneof` definitions in this type. * * Generated from protobuf field repeated string oneofs = 3; * @param string[] $var * @return $this */ public function setOneofs($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING); $this->oneofs = $arr; return $this; } /** * The protocol buffer options. * * Generated from protobuf field repeated .google.protobuf.Option options = 4; * @return RepeatedField<\Google\Protobuf\Option> */ public function getOptions() { return $this->options; } /** * The protocol buffer options. * * Generated from protobuf field repeated .google.protobuf.Option options = 4; * @param \Google\Protobuf\Option[] $var * @return $this */ public function setOptions($var) { $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Protobuf\Option::class); $this->options = $arr; return $this; } /** * The source context. * * Generated from protobuf field .google.protobuf.SourceContext source_context = 5; * @return \Google\Protobuf\SourceContext|null */ public function getSourceContext() { return $this->source_context; } public function hasSourceContext() { return isset($this->source_context); } public function clearSourceContext() { unset($this->source_context); } /** * The source context. * * Generated from protobuf field .google.protobuf.SourceContext source_context = 5; * @param \Google\Protobuf\SourceContext $var * @return $this */ public function setSourceContext($var) { GPBUtil::checkMessage($var, \Google\Protobuf\SourceContext::class); $this->source_context = $var; return $this; } /** * The source syntax. * * Generated from protobuf field .google.protobuf.Syntax syntax = 6; * @return int */ public function getSyntax() { return $this->syntax; } /** * The source syntax. * * Generated from protobuf field .google.protobuf.Syntax syntax = 6; * @param int $var * @return $this */ public function setSyntax($var) { GPBUtil::checkEnum($var, \Google\Protobuf\Syntax::class); $this->syntax = $var; return $this; } /** * The source edition string, only valid when syntax is SYNTAX_EDITIONS. * * Generated from protobuf field string edition = 7; * @return string */ public function getEdition() { return $this->edition; } /** * The source edition string, only valid when syntax is SYNTAX_EDITIONS. * * Generated from protobuf field string edition = 7; * @param string $var * @return $this */ public function setEdition($var) { GPBUtil::checkString($var, True); $this->edition = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/UInt32Value.php ================================================ google.protobuf.UInt32Value */ class UInt32Value extends \Google\Protobuf\Internal\Message { /** * The uint32 value. * * Generated from protobuf field uint32 value = 1; */ protected $value = 0; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type int $value * The uint32 value. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Wrappers::initOnce(); parent::__construct($data); } /** * The uint32 value. * * Generated from protobuf field uint32 value = 1; * @return int */ public function getValue() { return $this->value; } /** * The uint32 value. * * Generated from protobuf field uint32 value = 1; * @param int $var * @return $this */ public function setValue($var) { GPBUtil::checkUint32($var); $this->value = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/UInt64Value.php ================================================ google.protobuf.UInt64Value */ class UInt64Value extends \Google\Protobuf\Internal\Message { /** * The uint64 value. * * Generated from protobuf field uint64 value = 1; */ protected $value = 0; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type int|string $value * The uint64 value. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Wrappers::initOnce(); parent::__construct($data); } /** * The uint64 value. * * Generated from protobuf field uint64 value = 1; * @return int|string */ public function getValue() { return $this->value; } /** * The uint64 value. * * Generated from protobuf field uint64 value = 1; * @param int|string $var * @return $this */ public function setValue($var) { GPBUtil::checkUint64($var); $this->value = $var; return $this; } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/Google/Protobuf/Value.php ================================================ google.protobuf.Value */ class Value extends \Google\Protobuf\Internal\Message { protected $kind; /** * Constructor. * * @param array $data { * Optional. Data for populating the Message object. * * @type int $null_value * Represents a null value. * @type float $number_value * Represents a double value. * @type string $string_value * Represents a string value. * @type bool $bool_value * Represents a boolean value. * @type \Google\Protobuf\Struct $struct_value * Represents a structured value. * @type \Google\Protobuf\ListValue $list_value * Represents a repeated `Value`. * } */ public function __construct($data = NULL) { \GPBMetadata\Google\Protobuf\Struct::initOnce(); parent::__construct($data); } /** * Represents a null value. * * Generated from protobuf field .google.protobuf.NullValue null_value = 1; * @return int */ public function getNullValue() { return $this->readOneof(1); } public function hasNullValue() { return $this->hasOneof(1); } /** * Represents a null value. * * Generated from protobuf field .google.protobuf.NullValue null_value = 1; * @param int $var * @return $this */ public function setNullValue($var) { GPBUtil::checkEnum($var, \Google\Protobuf\NullValue::class); $this->writeOneof(1, $var); return $this; } /** * Represents a double value. * * Generated from protobuf field double number_value = 2; * @return float */ public function getNumberValue() { return $this->readOneof(2); } public function hasNumberValue() { return $this->hasOneof(2); } /** * Represents a double value. * * Generated from protobuf field double number_value = 2; * @param float $var * @return $this */ public function setNumberValue($var) { GPBUtil::checkDouble($var); $this->writeOneof(2, $var); return $this; } /** * Represents a string value. * * Generated from protobuf field string string_value = 3; * @return string */ public function getStringValue() { return $this->readOneof(3); } public function hasStringValue() { return $this->hasOneof(3); } /** * Represents a string value. * * Generated from protobuf field string string_value = 3; * @param string $var * @return $this */ public function setStringValue($var) { GPBUtil::checkString($var, True); $this->writeOneof(3, $var); return $this; } /** * Represents a boolean value. * * Generated from protobuf field bool bool_value = 4; * @return bool */ public function getBoolValue() { return $this->readOneof(4); } public function hasBoolValue() { return $this->hasOneof(4); } /** * Represents a boolean value. * * Generated from protobuf field bool bool_value = 4; * @param bool $var * @return $this */ public function setBoolValue($var) { GPBUtil::checkBool($var); $this->writeOneof(4, $var); return $this; } /** * Represents a structured value. * * Generated from protobuf field .google.protobuf.Struct struct_value = 5; * @return \Google\Protobuf\Struct|null */ public function getStructValue() { return $this->readOneof(5); } public function hasStructValue() { return $this->hasOneof(5); } /** * Represents a structured value. * * Generated from protobuf field .google.protobuf.Struct struct_value = 5; * @param \Google\Protobuf\Struct $var * @return $this */ public function setStructValue($var) { GPBUtil::checkMessage($var, \Google\Protobuf\Struct::class); $this->writeOneof(5, $var); return $this; } /** * Represents a repeated `Value`. * * Generated from protobuf field .google.protobuf.ListValue list_value = 6; * @return \Google\Protobuf\ListValue|null */ public function getListValue() { return $this->readOneof(6); } public function hasListValue() { return $this->hasOneof(6); } /** * Represents a repeated `Value`. * * Generated from protobuf field .google.protobuf.ListValue list_value = 6; * @param \Google\Protobuf\ListValue $var * @return $this */ public function setListValue($var) { GPBUtil::checkMessage($var, \Google\Protobuf\ListValue::class); $this->writeOneof(6, $var); return $this; } /** * @return string */ public function getKind() { return $this->whichOneof("kind"); } } ================================================ FILE: lib/Google/vendor/google/protobuf/src/phpdoc.dist.xml ================================================ doc doc Google/Protobuf/Internal/MapField.php Google/Protobuf/Internal/Message.php Google/Protobuf/Internal/RepeatedField.php ================================================ FILE: lib/Google/vendor/grpc/grpc/LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright {yyyy} {name of copyright owner} Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: lib/Google/vendor/grpc/grpc/MAINTAINERS.md ================================================ This page lists all active maintainers of this repository. If you were a maintainer and would like to add your name to the Emeritus list, please send us a PR. See [GOVERNANCE.md](https://github.com/grpc/grpc-community/blob/master/governance.md) for governance guidelines and how to become a maintainer. See [CONTRIBUTING.md](https://github.com/grpc/grpc-community/blob/master/CONTRIBUTING.md) for general contribution guidelines. ## Maintainers (in alphabetical order) - [stanley-cheung](https://github.com/stanley-cheung), Google Inc. - [wenbozhu](https://github.com/wenbozhu), Google Inc. - [zhouyihaiding](https://github.com/zhouyihaiding), Google Inc. ## Emeritus Maintainers (in alphabetical order) - [murgatroid99](https://github.com/murgatroid99), Google Inc. ================================================ FILE: lib/Google/vendor/grpc/grpc/README.md ================================================ # gRPC PHP Client Library This repository contains only PHP files to support Composer installation. This repository is a mirror of [gRPC](https://github.com/grpc/grpc). Any support requests, bug reports, or development contributions should be directed to that project. To install gRPC for PHP, please see https://github.com/grpc/grpc/tree/master/src/php ================================================ FILE: lib/Google/vendor/grpc/grpc/composer.json ================================================ { "name": "grpc/grpc", "type": "library", "description": "gRPC library for PHP", "keywords": ["rpc"], "homepage": "https://grpc.io", "license": "Apache-2.0", "version": "1.74.0", "require": { "php": ">=7.0.0" }, "require-dev": { "google/auth": "^v1.3.0" }, "suggest": { "ext-protobuf": "For better performance, install the protobuf C extension.", "google/protobuf": "To get started using grpc quickly, install the native protobuf library." }, "autoload": { "psr-4": { "Grpc\\": "src/lib/" } } } ================================================ FILE: lib/Google/vendor/grpc/grpc/etc/roots.pem ================================================ # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # Issuer: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA # Subject: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA # Label: "GlobalSign Root CA" # Serial: 4835703278459707669005204 # MD5 Fingerprint: 3e:45:52:15:09:51:92:e1:b7:5d:37:9f:b1:87:29:8a # SHA1 Fingerprint: b1:bc:96:8b:d4:f4:9d:62:2a:a8:9a:81:f2:15:01:52:a4:1d:82:9c # SHA256 Fingerprint: eb:d4:10:40:e4:bb:3e:c7:42:c9:e3:81:d3:1e:f2:a4:1a:48:b6:68:5c:96:e7:ce:f3:c1:df:6c:d4:33:1c:99 -----BEGIN CERTIFICATE----- MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp 1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8 9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE 38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== -----END CERTIFICATE----- # Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2 # Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2 # Label: "GlobalSign Root CA - R2" # Serial: 4835703278459682885658125 # MD5 Fingerprint: 94:14:77:7e:3e:5e:fd:8f:30:bd:41:b0:cf:e7:d0:30 # SHA1 Fingerprint: 75:e0:ab:b6:13:85:12:27:1c:04:f8:5f:dd:de:38:e4:b7:24:2e:fe # SHA256 Fingerprint: ca:42:dd:41:74:5f:d0:b8:1e:b9:02:36:2c:f9:d8:bf:71:9d:a1:bd:1b:1e:fc:94:6f:5b:4c:99:f4:2c:1b:9e -----BEGIN CERTIFICATE----- MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1 MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8 eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG 3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO 291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== -----END CERTIFICATE----- # Issuer: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited # Subject: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited # Label: "Entrust.net Premium 2048 Secure Server CA" # Serial: 946069240 # MD5 Fingerprint: ee:29:31:bc:32:7e:9a:e6:e8:b5:f7:51:b4:34:71:90 # SHA1 Fingerprint: 50:30:06:09:1d:97:d4:f5:ae:39:f7:cb:e7:92:7d:7d:65:2d:34:31 # SHA256 Fingerprint: 6d:c4:71:72:e0:1c:bc:b0:bf:62:58:0d:89:5f:e2:b8:ac:9a:d4:f8:73:80:1e:0c:10:b9:c8:37:d2:1e:b1:77 -----BEGIN CERTIFICATE----- MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5 IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0yOTA3 MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3 LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/ HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH 4QIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV HQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJKoZIhvcNAQEFBQADggEBADub j1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPyT/4xmf3IDExo U8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b u/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+ bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er fF6adulZkMV8gzURZVE= -----END CERTIFICATE----- # Issuer: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust # Subject: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust # Label: "Baltimore CyberTrust Root" # Serial: 33554617 # MD5 Fingerprint: ac:b6:94:a5:9c:17:e0:d7:91:52:9b:b1:97:06:a6:e4 # SHA1 Fingerprint: d4:de:20:d0:5e:66:fc:53:fe:1a:50:88:2c:78:db:28:52:ca:e4:74 # SHA256 Fingerprint: 16:af:57:a9:f6:76:b0:ab:12:60:95:aa:5e:ba:de:f2:2a:b3:11:19:d6:44:ac:95:cd:4b:93:db:f3:f2:6a:eb -----BEGIN CERTIFICATE----- MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1 BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3 DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92 9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0 Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp -----END CERTIFICATE----- # Issuer: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc. # Subject: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc. # Label: "Entrust Root Certification Authority" # Serial: 1164660820 # MD5 Fingerprint: d6:a5:c3:ed:5d:dd:3e:00:c1:3d:87:92:1f:1d:3f:e4 # SHA1 Fingerprint: b3:1e:b1:b7:40:e3:6c:84:02:da:dc:37:d4:4d:f5:d4:67:49:52:f9 # SHA256 Fingerprint: 73:c1:76:43:4f:1b:c6:d5:ad:f4:5b:0e:76:e7:27:28:7c:8d:e5:76:16:c1:e6:e6:14:1a:2b:2c:bc:7d:8e:4c -----BEGIN CERTIFICATE----- MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0 Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4 4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9 KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi 94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP 9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/ eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m 0vdXcDazv/wor3ElhVsT/h5/WrQ8 -----END CERTIFICATE----- # Issuer: CN=AAA Certificate Services O=Comodo CA Limited # Subject: CN=AAA Certificate Services O=Comodo CA Limited # Label: "Comodo AAA Services root" # Serial: 1 # MD5 Fingerprint: 49:79:04:b0:eb:87:19:ac:47:b0:bc:11:51:9b:74:d0 # SHA1 Fingerprint: d1:eb:23:a4:6d:17:d6:8f:d9:25:64:c2:f1:f1:60:17:64:d8:e3:49 # SHA256 Fingerprint: d7:a7:a0:fb:5d:7e:27:31:d7:71:e9:48:4e:bc:de:f7:1d:5f:0c:3e:0a:29:48:78:2b:c8:3e:e0:ea:69:9e:f4 -----BEGIN CERTIFICATE----- MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe 3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4 YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2 G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3 smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== -----END CERTIFICATE----- # Issuer: CN=QuoVadis Root CA 2 O=QuoVadis Limited # Subject: CN=QuoVadis Root CA 2 O=QuoVadis Limited # Label: "QuoVadis Root CA 2" # Serial: 1289 # MD5 Fingerprint: 5e:39:7b:dd:f8:ba:ec:82:e9:ac:62:ba:0c:54:00:2b # SHA1 Fingerprint: ca:3a:fb:cf:12:40:36:4b:44:b2:16:20:88:80:48:39:19:93:7c:f7 # SHA256 Fingerprint: 85:a0:dd:7d:d7:20:ad:b7:ff:05:f8:3d:54:2b:20:9d:c7:ff:45:28:f7:d6:77:b1:83:89:fe:a5:e5:c4:9e:86 -----BEGIN CERTIFICATE----- MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv b3QgQ0EgMjAeFw0wNjExMjQxODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNV BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W YWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCa GMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6XJxg Fyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55J WpzmM+Yklvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bB rrcCaoF6qUWD4gXmuVbBlDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp +ARz8un+XJiM9XOva7R+zdRcAitMOeGylZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1 ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt66/3FsvbzSUr5R/7mp/i Ucw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1JdxnwQ5hYIiz PtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og /zOhD7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UH oycR7hYQe7xFSkyyBNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuI yV77zGHcizN300QyNQliBJIWENieJ0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1Ud EwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBQahGK8SEwzJQTU7tD2 A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGUa6FJpEcwRTEL MAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2f BluornFdLwUvZ+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzn g/iN/Ae42l9NLmeyhP3ZRPx3UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2Bl fF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodmVjB3pjd4M1IQWK4/YY7yarHvGH5K WWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK+JDSV6IZUaUtl0Ha B0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrWIozc hLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPR TUIZ3Ph1WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWD mbA4CD/pXvk1B+TJYm5Xf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0Z ohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y 4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8VCLAAVBpQ570su9t+Oza 8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u -----END CERTIFICATE----- # Issuer: CN=QuoVadis Root CA 3 O=QuoVadis Limited # Subject: CN=QuoVadis Root CA 3 O=QuoVadis Limited # Label: "QuoVadis Root CA 3" # Serial: 1478 # MD5 Fingerprint: 31:85:3c:62:94:97:63:b9:aa:fd:89:4e:af:6f:e0:cf # SHA1 Fingerprint: 1f:49:14:f7:d8:74:95:1d:dd:ae:02:c0:be:fd:3a:2d:82:75:51:85 # SHA256 Fingerprint: 18:f1:fc:7f:20:5d:f8:ad:dd:eb:7f:e0:07:dd:57:e3:af:37:5a:9c:4d:8d:73:54:6b:f4:f1:fe:d1:e1:8d:35 -----BEGIN CERTIFICATE----- MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv b3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W YWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM V0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNggDhoB 4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUr H556VOijKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd 8lyyBTNvijbO0BNO/79KDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9Cabwv vWhDFlaJKjdhkf2mrk7AyxRllDdLkgbvBNDInIjbC3uBr7E9KsRlOni27tyAsdLT mZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwpp5ijJUMv7/FfJuGITfhe btfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8nT8KKdjc T5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDt WAEXMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZ c6tsgLjoC2SToJyMGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A 4iLItLRkT9a6fUg+qGkM17uGcclzuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYD VR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHTBgkrBgEEAb5YAAMwgcUwgZMG CCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0 aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0 aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu dC4wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2Nw czALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4G A1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4ywLQoUmkRzBFMQswCQYDVQQGEwJC TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UEAxMSUXVvVmFkaXMg Um9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZVqyM0 7ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSem d1o417+shvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd +LJ2w/w4E6oM3kJpK27zPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B 4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadN t54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp8kokUvd0/bpO5qgdAm6x DYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBCbjPsMZ57 k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6s zHXug/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0j Wy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK 4SVhM7JZG+Ju1zdXtg2pEto= -----END CERTIFICATE----- # Issuer: O=SECOM Trust.net OU=Security Communication RootCA1 # Subject: O=SECOM Trust.net OU=Security Communication RootCA1 # Label: "Security Communication Root CA" # Serial: 0 # MD5 Fingerprint: f1:bc:63:6a:54:e0:b5:27:f5:cd:e7:1a:e3:4d:6e:4a # SHA1 Fingerprint: 36:b1:2b:49:f9:81:9e:d7:4c:9e:bc:38:0f:c6:56:8f:5d:ac:b2:f7 # SHA256 Fingerprint: e7:5e:72:ed:9f:56:0e:ec:6e:b4:80:00:73:a4:3f:c3:ad:19:19:5a:39:22:82:01:78:95:97:4a:99:02:6b:6c -----BEGIN CERTIFICATE----- MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEY MBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21t dW5pY2F0aW9uIFJvb3RDQTEwHhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5 WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYD VQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEwggEiMA0GCSqGSIb3 DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw8yl8 9f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJ DKaVv0uMDPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9 Ms+k2Y7CI9eNqPPYJayX5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/N QV3Is00qVUarH9oe4kA92819uZKAnDfdDJZkndwi92SL32HeFZRSFaB9UslLqCHJ xrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2JChzAgMBAAGjPzA9MB0G A1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYwDwYDVR0T AQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vG kl3g0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfr Uj94nK9NrvjVT8+amCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5 Bw+SUEmK3TGXX8npN6o7WWWXlDLJs58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJU JRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfcioU+tHXot RSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAiFL39vmwLAw== -----END CERTIFICATE----- # Issuer: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com # Subject: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com # Label: "XRamp Global CA Root" # Serial: 107108908803651509692980124233745014957 # MD5 Fingerprint: a1:0b:44:b3:ca:10:d8:00:6e:9d:0f:d8:0f:92:0a:d1 # SHA1 Fingerprint: b8:01:86:d1:eb:9c:86:a5:41:04:cf:30:54:f3:4c:52:b7:e5:58:c6 # SHA256 Fingerprint: ce:cd:dc:90:50:99:d8:da:df:c5:b1:d2:09:b7:37:cb:e2:c1:8c:fb:2c:10:c0:ff:0b:cf:0d:32:86:fc:1a:a2 -----BEGIN CERTIFICATE----- MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3 dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6 38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4 qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0 eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ O+7ETPTsJ3xCwnR8gooJybQDJbw= -----END CERTIFICATE----- # Issuer: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority # Subject: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority # Label: "Go Daddy Class 2 CA" # Serial: 0 # MD5 Fingerprint: 91:de:06:25:ab:da:fd:32:17:0c:bb:25:17:2a:84:67 # SHA1 Fingerprint: 27:96:ba:e6:3f:18:01:e2:77:26:1b:a0:d7:77:70:02:8f:20:ee:e4 # SHA256 Fingerprint: c3:84:6b:f2:4b:9e:93:ca:64:27:4c:0e:c6:7c:1e:cc:5e:02:4f:fc:ac:d2:d7:40:19:35:0e:81:fe:54:6a:e4 -----BEGIN CERTIFICATE----- MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3 MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+ YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h /t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5 IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf ReYNnyicsbkqWletNw+vHX/bvZ8= -----END CERTIFICATE----- # Issuer: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority # Subject: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority # Label: "Starfield Class 2 CA" # Serial: 0 # MD5 Fingerprint: 32:4a:4b:bb:c8:63:69:9b:be:74:9a:c6:dd:1d:46:24 # SHA1 Fingerprint: ad:7e:1c:28:b0:64:ef:8f:60:03:40:20:14:c3:d0:e3:37:0e:b5:8a # SHA256 Fingerprint: 14:65:fa:20:53:97:b8:76:fa:a6:f0:a9:95:8e:55:90:e4:0f:cc:7f:aa:4f:b7:c2:c8:67:75:21:fb:5f:b6:58 -----BEGIN CERTIFICATE----- MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3 DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf 8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN +lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0 X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA 1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0 YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3 L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q= -----END CERTIFICATE----- # Issuer: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com # Subject: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com # Label: "DigiCert Assured ID Root CA" # Serial: 17154717934120587862167794914071425081 # MD5 Fingerprint: 87:ce:0b:7b:2a:0e:49:00:e1:58:71:9b:37:a8:93:72 # SHA1 Fingerprint: 05:63:b8:63:0d:62:d7:5a:bb:c8:ab:1e:4b:df:b5:a8:99:b2:4d:43 # SHA256 Fingerprint: 3e:90:99:b5:01:5e:8f:48:6c:00:bc:ea:9d:11:1e:e7:21:fa:ba:35:5a:89:bc:f1:df:69:56:1e:3d:c6:32:5c -----BEGIN CERTIFICATE----- MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+ wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4 VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/ AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe +o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== -----END CERTIFICATE----- # Issuer: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com # Subject: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com # Label: "DigiCert Global Root CA" # Serial: 10944719598952040374951832963794454346 # MD5 Fingerprint: 79:e4:a9:84:0d:7d:3a:96:d7:c0:4f:e2:43:4c:89:2e # SHA1 Fingerprint: a8:98:5d:3a:65:e5:e5:c4:b2:d7:d6:6d:40:c6:dd:2f:b1:9c:54:36 # SHA256 Fingerprint: 43:48:a0:e9:44:4c:78:cb:26:5e:05:8d:5e:89:44:b4:d8:4f:96:62:bd:26:db:25:7f:89:34:a4:43:c7:01:61 -----BEGIN CERTIFICATE----- MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG 9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt 43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg 06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= -----END CERTIFICATE----- # Issuer: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com # Subject: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com # Label: "DigiCert High Assurance EV Root CA" # Serial: 3553400076410547919724730734378100087 # MD5 Fingerprint: d4:74:de:57:5c:39:b2:d3:9c:85:83:c5:c0:65:49:8a # SHA1 Fingerprint: 5f:b7:ee:06:33:e2:59:db:ad:0c:4c:9a:e6:d3:8f:1a:61:c7:dc:25 # SHA256 Fingerprint: 74:31:e5:f4:c3:c1:ce:46:90:77:4f:0b:61:e0:54:40:88:3b:a9:a0:1e:d0:0b:a6:ab:d7:80:6e:d3:b1:18:cf -----BEGIN CERTIFICATE----- MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm +9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3 hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2 Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep +OkuE6N36B9K -----END CERTIFICATE----- # Issuer: CN=SwissSign Gold CA - G2 O=SwissSign AG # Subject: CN=SwissSign Gold CA - G2 O=SwissSign AG # Label: "SwissSign Gold CA - G2" # Serial: 13492815561806991280 # MD5 Fingerprint: 24:77:d9:a8:91:d1:3b:fa:88:2d:c2:ff:f8:cd:33:93 # SHA1 Fingerprint: d8:c5:38:8a:b7:30:1b:1b:6e:d4:7a:e6:45:25:3a:6f:9f:1a:27:61 # SHA256 Fingerprint: 62:dd:0b:e9:b9:f5:0a:16:3e:a0:f8:e7:5c:05:3b:1e:ca:57:ea:55:c8:68:8f:64:7c:68:81:f2:c8:35:7b:95 -----BEGIN CERTIFICATE----- MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2ln biBHb2xkIENBIC0gRzIwHhcNMDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBF MQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMR8wHQYDVQQDExZT d2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC CgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUqt2/8 76LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+ bbqBHH5CjCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c 6bM8K8vzARO/Ws/BtQpgvd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqE emA8atufK+ze3gE/bk3lUIbLtK/tREDFylqM2tIrfKjuvqblCqoOpd8FUrdVxyJd MmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvRAiTysybUa9oEVeXBCsdt MDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuendjIj3o02y MszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69y FGkOpeUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPi aG59je883WX0XaxR7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxM gI93e2CaHt+28kgeDrpOVG2Y4OGiGqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCB qTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUWyV7 lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64OfPAeGZe6Drn 8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe6 45R88a7A3hfm5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczO UYrHUDFu4Up+GC9pWbY9ZIEr44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5 O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOfMke6UiI0HTJ6CVanfCU2qT1L2sCC bwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6mGu6uLftIdxf+u+yv GPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxpmo/a 77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCC hdiDyyJkvC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid3 92qgQmwLOM7XdVAyksLfKzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEpp Ld6leNcG2mqeSz53OiATIgHQv2ieY2BrNU0LbbqhPcCT4H8js1WtciVORvnSFu+w ZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6LqjviOvrv1vA+ACOzB2+htt Qc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ -----END CERTIFICATE----- # Issuer: CN=SwissSign Silver CA - G2 O=SwissSign AG # Subject: CN=SwissSign Silver CA - G2 O=SwissSign AG # Label: "SwissSign Silver CA - G2" # Serial: 5700383053117599563 # MD5 Fingerprint: e0:06:a1:c9:7d:cf:c9:fc:0d:c0:56:75:96:d8:62:13 # SHA1 Fingerprint: 9b:aa:e5:9f:56:ee:21:cb:43:5a:be:25:93:df:a7:f0:40:d1:1d:cb # SHA256 Fingerprint: be:6c:4d:a2:bb:b9:ba:59:b6:f3:93:97:68:37:42:46:c3:c0:05:99:3f:a9:8f:02:0d:1d:ed:be:d4:8a:81:d5 -----BEGIN CERTIFICATE----- MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UE BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWdu IFNpbHZlciBDQSAtIEcyMB4XDTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0Nlow RzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMY U3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A MIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644N0Mv Fz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7br YT7QbNHm+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieF nbAVlDLaYQ1HTWBCrpJH6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH 6ATK72oxh9TAtvmUcXtnZLi2kUpCe2UuMGoM9ZDulebyzYLs2aFK7PayS+VFheZt eJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5hqAaEuSh6XzjZG6k4sIN/ c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5FZGkECwJ MoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRH HTBsROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTf jNFusB3hB48IHpmccelM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb6 5i/4z3GcRm25xBWNOHkDRUjvxF3XCO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOB rDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU F6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRBtjpbO8tFnb0c wpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0 cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIB AHPGgeAn0i0P4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShp WJHckRE1qTodvBqlYJ7YH39FkWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9 xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L3XWgwF15kIwb4FDm3jH+mHtwX6WQ 2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx/uNncqCxv1yL5PqZ IseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFaDGi8 aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2X em1ZqSqPe97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQR dAtq/gsD/KNVV4n+SsuuWxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/ OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJDIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+ hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ubDgEj8Z+7fNzcbBGXJbLy tGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u -----END CERTIFICATE----- # Issuer: CN=SecureTrust CA O=SecureTrust Corporation # Subject: CN=SecureTrust CA O=SecureTrust Corporation # Label: "SecureTrust CA" # Serial: 17199774589125277788362757014266862032 # MD5 Fingerprint: dc:32:c3:a7:6d:25:57:c7:68:09:9d:ea:2d:a9:a2:d1 # SHA1 Fingerprint: 87:82:c6:c3:04:35:3b:cf:d2:96:92:d2:59:3e:7d:44:d9:34:ff:11 # SHA256 Fingerprint: f1:c1:b5:0a:e5:a2:0d:d8:03:0e:c9:f6:bc:24:82:3d:d3:67:b5:25:57:59:b4:e7:1b:61:fc:e9:f7:37:5d:73 -----BEGIN CERTIFICATE----- MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO 0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj 7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS 8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB /zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3 6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/ 3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR 3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= -----END CERTIFICATE----- # Issuer: CN=Secure Global CA O=SecureTrust Corporation # Subject: CN=Secure Global CA O=SecureTrust Corporation # Label: "Secure Global CA" # Serial: 9751836167731051554232119481456978597 # MD5 Fingerprint: cf:f4:27:0d:d4:ed:dc:65:16:49:6d:3d:da:bf:6e:de # SHA1 Fingerprint: 3a:44:73:5a:e5:81:90:1f:24:86:61:46:1e:3b:9c:c4:5f:f5:3a:1b # SHA256 Fingerprint: 42:00:f5:04:3a:c8:59:0e:bb:52:7d:20:9e:d1:50:30:29:fb:cb:d4:1c:a1:b5:06:ec:27:f1:5a:de:7d:ac:69 -----BEGIN CERTIFICATE----- MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa /FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7 sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW -----END CERTIFICATE----- # Issuer: CN=COMODO Certification Authority O=COMODO CA Limited # Subject: CN=COMODO Certification Authority O=COMODO CA Limited # Label: "COMODO Certification Authority" # Serial: 104350513648249232941998508985834464573 # MD5 Fingerprint: 5c:48:dc:f7:42:72:ec:56:94:6d:1c:cc:71:35:80:75 # SHA1 Fingerprint: 66:31:bf:9e:f7:4f:9e:b6:c9:d5:a6:0c:ba:6a:be:d1:f7:bd:ef:7b # SHA256 Fingerprint: 0c:2c:d6:3d:f7:80:6f:a3:99:ed:e8:09:11:6b:57:5b:f8:79:89:f0:65:18:f9:80:8c:86:05:03:17:8b:af:66 -----BEGIN CERTIFICATE----- MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0 aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3 UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI 2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8 Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp +2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+ DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW /zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4 zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB ZQ== -----END CERTIFICATE----- # Issuer: CN=Network Solutions Certificate Authority O=Network Solutions L.L.C. # Subject: CN=Network Solutions Certificate Authority O=Network Solutions L.L.C. # Label: "Network Solutions Certificate Authority" # Serial: 116697915152937497490437556386812487904 # MD5 Fingerprint: d3:f3:a6:16:c0:fa:6b:1d:59:b1:2d:96:4d:0e:11:2e # SHA1 Fingerprint: 74:f8:a3:c3:ef:e7:b3:90:06:4b:83:90:3c:21:64:60:20:e5:df:ce # SHA256 Fingerprint: 15:f0:ba:00:a3:ac:7a:f3:ac:88:4c:07:2b:10:11:a0:77:bd:77:c0:97:f4:01:64:b2:f8:59:8a:bd:83:86:0c -----BEGIN CERTIFICATE----- MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBi MQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3Jp dHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMxMjM1OTU5WjBiMQswCQYDVQQGEwJV UzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydO ZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwz c7MEL7xxjOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPP OCwGJgl6cvf6UDL4wpPTaaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rl mGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXTcrA/vGp97Eh/jcOrqnErU2lBUzS1sLnF BgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc/Qzpf14Dl847ABSHJ3A4 qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMBAAGjgZcw gZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIB BjAPBgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwu bmV0c29sc3NsLmNvbS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3Jp dHkuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc8 6fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q4LqILPxFzBiwmZVRDuwduIj/ h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/GGUsyfJj4akH /nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHN pGxlaKFJdlxDydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey -----END CERTIFICATE----- # Issuer: CN=COMODO ECC Certification Authority O=COMODO CA Limited # Subject: CN=COMODO ECC Certification Authority O=COMODO CA Limited # Label: "COMODO ECC Certification Authority" # Serial: 41578283867086692638256921589707938090 # MD5 Fingerprint: 7c:62:ff:74:9d:31:53:5e:68:4a:d5:78:aa:1e:bf:23 # SHA1 Fingerprint: 9f:74:4e:9f:2b:4d:ba:ec:0f:31:2c:50:b6:56:3b:8e:2d:93:c3:11 # SHA256 Fingerprint: 17:93:92:7a:06:14:54:97:89:ad:ce:2f:8f:34:f7:f0:b6:6d:0f:3a:e3:a3:b8:4d:21:ec:15:db:ba:4f:ad:c7 -----BEGIN CERTIFICATE----- MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= -----END CERTIFICATE----- # Issuer: CN=Certigna O=Dhimyotis # Subject: CN=Certigna O=Dhimyotis # Label: "Certigna" # Serial: 18364802974209362175 # MD5 Fingerprint: ab:57:a6:5b:7d:42:82:19:b5:d8:58:26:28:5e:fd:ff # SHA1 Fingerprint: b1:2e:13:63:45:86:a4:6f:1a:b2:60:68:37:58:2d:c4:ac:fd:94:97 # SHA256 Fingerprint: e3:b6:a2:db:2e:d7:ce:48:84:2f:7a:c5:32:41:c7:b7:1d:54:14:4b:fb:40:c1:1f:3f:1d:0b:42:f5:ee:a1:2d -----BEGIN CERTIFICATE----- MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV BAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4X DTA3MDYyOTE1MTMwNVoXDTI3MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQ BgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwIQ2VydGlnbmEwggEiMA0GCSqGSIb3 DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7qXOEm7RFHYeGifBZ4 QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyHGxny gQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbw zBfsV1/pogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q 130yGLMLLGq/jj8UEYkgDncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2 JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKfIrjxwo1p3Po6WAbfAgMBAAGjgbwwgbkw DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQtCRZvgHyUtVF9lo53BEw ZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJBgNVBAYT AkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzj AQ/JSP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG 9w0BAQUFAAOCAQEAhQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8h bV6lUmPOEvjvKtpv6zf+EwLHyzs+ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFnc fca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1kluPBS1xp81HlDQwY9qcEQCYsuu HWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY1gkIl2PlwS6w t0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== -----END CERTIFICATE----- # Issuer: CN=Cybertrust Global Root O=Cybertrust, Inc # Subject: CN=Cybertrust Global Root O=Cybertrust, Inc # Label: "Cybertrust Global Root" # Serial: 4835703278459682877484360 # MD5 Fingerprint: 72:e4:4a:87:e3:69:40:80:77:ea:bc:e3:f4:ff:f0:e1 # SHA1 Fingerprint: 5f:43:e5:b1:bf:f8:78:8c:ac:1c:c7:ca:4a:9a:c6:22:2b:cc:34:c6 # SHA256 Fingerprint: 96:0a:df:00:63:e9:63:56:75:0c:29:65:dd:0a:08:67:da:0b:9c:bd:6e:77:71:4a:ea:fb:23:49:ab:39:3d:a3 -----BEGIN CERTIFICATE----- MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYG A1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2Jh bCBSb290MB4XDTA2MTIxNTA4MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UE ChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBS b290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+Mi8vRRQZhP/8NN5 7CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW0ozS J8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2y HLtgwEZLAfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iP t3sMpTjr3kfb1V05/Iin89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNz FtApD0mpSPCzqrdsxacwOUBdrsTiXSZT8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAY XSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/ MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2MDSgMqAw hi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3Js MB8GA1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUA A4IBAQBW7wojoFROlZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMj Wqd8BfP9IjsO0QbE2zZMcwSO5bAi5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUx XOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2hO0j9n0Hq0V+09+zv+mKts2o omcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+TX3EJIrduPuoc A06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW WL1WMRJOEcgh4LMRkWXbtKaIOM5V -----END CERTIFICATE----- # Issuer: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority # Subject: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority # Label: "ePKI Root Certification Authority" # Serial: 28956088682735189655030529057352760477 # MD5 Fingerprint: 1b:2e:00:ca:26:06:90:3d:ad:fe:6f:15:68:d3:6b:b3 # SHA1 Fingerprint: 67:65:0d:f1:7e:8e:7e:5b:82:40:a4:f4:56:4b:cf:e2:3d:69:c6:f0 # SHA256 Fingerprint: c0:a6:f4:dc:63:a2:4b:fd:cf:54:ef:2a:6a:08:2a:0a:72:de:35:80:3e:2f:f5:ff:52:7a:e5:d8:72:06:df:d5 -----BEGIN CERTIFICATE----- MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBe MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0 ZC4xKjAoBgNVBAsMIWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe Fw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMxMjdaMF4xCzAJBgNVBAYTAlRXMSMw IQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEqMCgGA1UECwwhZVBL SSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEF AAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAH SyZbCUNsIZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAh ijHyl3SJCRImHJ7K2RKilTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3X DZoTM1PRYfl61dd4s5oz9wCGzh1NlDivqOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1 TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX12ruOzjjK9SXDrkb5wdJ fzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0OWQqraffA sgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uU WH1+ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLS nT0IFaUQAS2zMnaolQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pH dmX2Os+PYhcZewoozRrSgx4hxyy/vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJip NiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXiZo1jDiVN1Rmy5nk3pyKdVDEC AwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/QkqiMAwGA1UdEwQF MAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGB uvl2ICO1J2B01GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6Yl PwZpVnPDimZI+ymBV3QGypzqKOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkP JXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdVxrsStZf0X4OFunHB2WyBEXYKCrC/ gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEPNXubrjlpC2JgQCA2 j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+rGNm6 5ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUB o2M3IUxExJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS /jQ6fbjpKdx2qcgw+BRxgMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2z Gp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTE W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D hNQ+IIX3Sj0rnP0qCglN6oH4EZw= -----END CERTIFICATE----- # Issuer: O=certSIGN OU=certSIGN ROOT CA # Subject: O=certSIGN OU=certSIGN ROOT CA # Label: "certSIGN ROOT CA" # Serial: 35210227249154 # MD5 Fingerprint: 18:98:c0:d6:e9:3a:fc:f9:b0:f5:0c:f7:4b:01:44:17 # SHA1 Fingerprint: fa:b7:ee:36:97:26:62:fb:2d:b0:2a:f6:bf:03:fd:e8:7c:4b:2f:9b # SHA256 Fingerprint: ea:a9:62:c4:fa:4a:6b:af:eb:e4:15:19:6d:35:1c:cd:88:8d:4f:53:f3:fa:8a:e6:d7:c4:66:a9:4e:60:42:bb -----BEGIN CERTIFICATE----- MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYT AlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBD QTAeFw0wNjA3MDQxNzIwMDRaFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJP MREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTCC ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7IJUqOtdu0KBuqV5Do 0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHHrfAQ UySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5d RdY4zTW2ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQ OA7+j0xbm0bqQfWwCHTD0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwv JoIQ4uNllAoEwF73XVv4EOLQunpL+943AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08C AwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAcYwHQYDVR0O BBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IBAQA+0hyJ LjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecY MnQ8SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ 44gx+FkagQnIl6Z0x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6I Jd1hJyMctTEHBDa0GpC9oHRxUIltvBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNw i/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN 9u6wWk5JRFRYX0KD -----END CERTIFICATE----- # Issuer: CN=NetLock Arany (Class Gold) Főtanúsítvány O=NetLock Kft. OU=Tanúsítványkiadók (Certification Services) # Subject: CN=NetLock Arany (Class Gold) Főtanúsítvány O=NetLock Kft. OU=Tanúsítványkiadók (Certification Services) # Label: "NetLock Arany (Class Gold) Főtanúsítvány" # Serial: 80544274841616 # MD5 Fingerprint: c5:a1:b7:ff:73:dd:d6:d7:34:32:18:df:fc:3c:ad:88 # SHA1 Fingerprint: 06:08:3f:59:3f:15:a1:04:a0:69:a4:6b:a9:03:d0:06:b7:97:09:91 # SHA256 Fingerprint: 6c:61:da:c3:a2:de:f0:31:50:6b:e0:36:d2:a6:fe:40:19:94:fb:d1:3d:f9:c8:d4:66:59:92:74:c4:46:ec:98 -----BEGIN CERTIFICATE----- MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3 MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl cnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBBcmFueSAoQ2xhc3MgR29sZCkgRsWR dGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgxMjA2MTUwODIxWjCB pzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxOZXRM b2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlm aWNhdGlvbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNz IEdvbGQpIEbFkXRhbsO6c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A MIIBCgKCAQEAxCRec75LbRTDofTjl5Bu0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrT lF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw/HpYzY6b7cNGbIRwXdrz AZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAkH3B5r9s5 VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRG ILdwfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2 BJtr+UBdADTHLpl1neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAG AQH/AgEEMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2M U9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwWqZw8UQCgwBEIBaeZ5m8BiFRh bvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C +C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2 XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= -----END CERTIFICATE----- # Issuer: CN=Hongkong Post Root CA 1 O=Hongkong Post # Subject: CN=Hongkong Post Root CA 1 O=Hongkong Post # Label: "Hongkong Post Root CA 1" # Serial: 1000 # MD5 Fingerprint: a8:0d:6f:39:78:b9:43:6d:77:42:6d:98:5a:cc:23:ca # SHA1 Fingerprint: d6:da:a8:20:8d:09:d2:15:4d:24:b5:2f:cb:34:6e:b2:58:b2:8a:58 # SHA256 Fingerprint: f9:e6:7d:33:6c:51:00:2a:c0:54:c6:32:02:2d:66:dd:a2:e7:e3:ff:f1:0a:d0:61:ed:31:d8:bb:b4:10:cf:b2 -----BEGIN CERTIFICATE----- MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsx FjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3Qg Um9vdCBDQSAxMB4XDTAzMDUxNTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkG A1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdr b25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC AQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1ApzQ jVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEn PzlTCeqrauh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjh ZY4bXSNmO7ilMlHIhqqhqZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9 nnV0ttgCXjqQesBCNnLsak3c78QA3xMYV18meMjWCnl3v/evt3a5pQuEF10Q6m/h q5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNVHRMBAf8ECDAGAQH/AgED MA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7ih9legYsC mEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI3 7piol7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clB oiMBdDhViw+5LmeiIAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJs EhTkYY2sEJCehFC78JZvRZ+K88psT/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpO fMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilTc4afU9hDDl3WY4JxHYB0yvbi AmvZWg== -----END CERTIFICATE----- # Issuer: CN=SecureSign RootCA11 O=Japan Certification Services, Inc. # Subject: CN=SecureSign RootCA11 O=Japan Certification Services, Inc. # Label: "SecureSign RootCA11" # Serial: 1 # MD5 Fingerprint: b7:52:74:e2:92:b4:80:93:f2:75:e4:cc:d7:f2:ea:26 # SHA1 Fingerprint: 3b:c4:9f:48:f8:f3:73:a0:9c:1e:bd:f8:5b:b1:c3:65:c7:d8:11:b3 # SHA256 Fingerprint: bf:0f:ee:fb:9e:3a:58:1a:d5:f9:e9:db:75:89:98:57:43:d2:61:08:5c:4d:31:4f:6f:5d:72:59:aa:42:16:12 -----BEGIN CERTIFICATE----- MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDEr MCkGA1UEChMiSmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoG A1UEAxMTU2VjdXJlU2lnbiBSb290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0 MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSswKQYDVQQKEyJKYXBhbiBDZXJ0aWZp Y2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1cmVTaWduIFJvb3RD QTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvLTJsz i1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8 h9uuywGOwvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOV MdrAG/LuYpmGYz+/3ZMqg6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9 UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rPO7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni 8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitAbpSACW22s293bzUIUPsC h8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZXt94wDgYD VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEB AKChOBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xm KbabfSVSSUOrTC4rbnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQ X5Ucv+2rIrVls4W6ng+4reV6G4pQOh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWr QbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01y8hSyn+B/tlr0/cR7SXf+Of5 pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061lgeLKBObjBmN QSdJQO7e5iNEOdyhIta6A/I= -----END CERTIFICATE----- # Issuer: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd. # Subject: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd. # Label: "Microsec e-Szigno Root CA 2009" # Serial: 14014712776195784473 # MD5 Fingerprint: f8:49:f4:03:bc:44:2d:83:be:48:69:7d:29:64:fc:b1 # SHA1 Fingerprint: 89:df:74:fe:5c:f4:0f:4a:80:f9:e3:37:7d:54:da:91:e1:01:31:8e # SHA256 Fingerprint: 3c:5f:81:fe:a5:fa:b8:2c:64:bf:a2:ea:ec:af:cd:e8:e0:77:fc:86:20:a7:ca:e5:37:16:3d:f3:6e:db:f3:78 -----BEGIN CERTIFICATE----- MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0 ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0G CSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTAeFw0wOTA2MTYxMTMwMThaFw0y OTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3Qx FjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3pp Z25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o dTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvP kd6mJviZpWNwrZuuyjNAfW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tc cbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG0IMZfcChEhyVbUr02MelTTMuhTlAdX4U fIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKApxn1ntxVUwOXewdI/5n7 N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm1HxdrtbC xkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1 +rUCAwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G A1UdDgQWBBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPM Pcu1SCOhGnqmKrs0aDAbBgNVHREEFDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqG SIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0olZMEyL/azXm4Q5DwpL7v8u8h mLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfXI/OMn74dseGk ddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c 2Pm2G2JwCz02yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5t HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW -----END CERTIFICATE----- # Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 # Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 # Label: "GlobalSign Root CA - R3" # Serial: 4835703278459759426209954 # MD5 Fingerprint: c5:df:b8:49:ca:05:13:55:ee:2d:ba:1a:c3:3e:b0:28 # SHA1 Fingerprint: d6:9b:56:11:48:f0:1c:77:c5:45:78:c1:09:26:df:5b:85:69:76:ad # SHA256 Fingerprint: cb:b5:22:d7:b7:f1:27:ad:6a:01:13:86:5b:df:1c:d4:10:2e:7d:07:59:af:63:5a:7c:f4:72:0d:c9:63:c5:3b -----BEGIN CERTIFICATE----- MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4 MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8 RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK 6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH WD9f -----END CERTIFICATE----- # Issuer: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 # Subject: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 # Label: "Autoridad de Certificacion Firmaprofesional CIF A62634068" # Serial: 6047274297262753887 # MD5 Fingerprint: 73:3a:74:7a:ec:bb:a3:96:a6:c2:e4:e2:c8:9b:c0:c3 # SHA1 Fingerprint: ae:c5:fb:3f:c8:e1:bf:c4:e5:4f:03:07:5a:9a:e8:00:b7:f7:b6:fa # SHA256 Fingerprint: 04:04:80:28:bf:1f:28:64:d4:8f:9a:d4:d8:32:94:36:6a:82:88:56:55:3f:3b:14:30:3f:90:14:7f:5d:40:ef -----BEGIN CERTIFICATE----- MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UE BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEy MzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9 thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF 6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYD VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNHDhpkLzCBpgYD VR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBv ACAAZABlACAAbABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBl AGwAbwBuAGEAIAAwADgAMAAxADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF 661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx51tkljYyGOylMnfX40S2wBEqgLk9 am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qkR71kMrv2JYSiJ0L1 ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaPT481 PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS 3a/DTg4fJl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5k SeTy36LssUzAKh3ntLFlosS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF 3dvd6qJ2gHN99ZwExEWN57kci57q13XRcrHedUTnQn3iV2t93Jm8PYMo6oCTjcVM ZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoRsaS8I8nkvof/uZS2+F0g StRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTDKCOM/icz Q0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQB jLMi6Et8Vcad+qMUu2WFbm5PEn4KPJ2V -----END CERTIFICATE----- # Issuer: CN=Izenpe.com O=IZENPE S.A. # Subject: CN=Izenpe.com O=IZENPE S.A. # Label: "Izenpe.com" # Serial: 917563065490389241595536686991402621 # MD5 Fingerprint: a6:b0:cd:85:80:da:5c:50:34:a3:39:90:2f:55:67:73 # SHA1 Fingerprint: 2f:78:3d:25:52:18:a7:4a:65:39:71:b5:2c:a2:9c:45:15:6f:e9:19 # SHA256 Fingerprint: 25:30:cc:8e:98:32:15:02:ba:d9:6f:9b:1f:ba:1b:09:9e:2d:29:9e:0f:45:48:bb:91:4f:36:3b:c0:d4:53:1f -----BEGIN CERTIFICATE----- MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4 MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6 ZW5wZS5jb20wHhcNMDcxMjEzMTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYD VQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5j b20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ03rKDx6sp4boFmVq scIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAKClaO xdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6H LmYRY2xU+zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFX uaOKmMPsOzTFlUFpfnXCPCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQD yCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxTOTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+ JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbKF7jJeodWLBoBHmy+E60Q rLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK0GqfvEyN BjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8L hij+0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIB QFqNeb+Lz0vPqhbBleStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+ HMh3/1uaD7euBUbl8agW7EekFwIDAQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2lu Zm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+SVpFTlBFIFMuQS4gLSBDSUYg QTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBGNjIgUzgxQzBB BgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC AQYwHQYDVR0OBBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUA A4ICAQB4pgwWSp9MiDrAyw6lFn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWb laQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbgakEyrkgPH7UIBzg/YsfqikuFgba56 awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8qhT/AQKM6WfxZSzwo JNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Csg1lw LDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCT VyvehQP5aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGk LhObNA5me0mrZJfQRsN5nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJb UjWumDqtujWTI6cfSN01RpiyEGjkpTHCClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/ QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZoQ0iy2+tzJOeRf1SktoA+ naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1ZWrOZyGls QyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw== -----END CERTIFICATE----- # Issuer: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc. # Subject: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc. # Label: "Go Daddy Root Certificate Authority - G2" # Serial: 0 # MD5 Fingerprint: 80:3a:bc:22:c1:e6:fb:8d:9b:3b:27:4a:32:1b:9a:01 # SHA1 Fingerprint: 47:be:ab:c9:22:ea:e8:0e:78:78:34:62:a7:9f:45:c2:54:fd:e6:8b # SHA256 Fingerprint: 45:14:0b:32:47:eb:9c:c8:c5:b4:f0:d7:b5:30:91:f7:32:92:08:9e:6e:5a:63:e2:74:9d:d3:ac:a9:19:8e:da -----BEGIN CERTIFICATE----- MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH /PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu 9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo 2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI 4uJEvlz36hz1 -----END CERTIFICATE----- # Issuer: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc. # Subject: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc. # Label: "Starfield Root Certificate Authority - G2" # Serial: 0 # MD5 Fingerprint: d6:39:81:c6:52:7e:96:69:fc:fc:ca:66:ed:05:f2:96 # SHA1 Fingerprint: b5:1c:06:7c:ee:2b:0c:3d:f8:55:ab:2d:92:f4:fe:39:d4:e7:0f:0e # SHA256 Fingerprint: 2c:e1:cb:0b:f9:d2:f9:e1:02:99:3f:be:21:51:52:c3:b2:dd:0c:ab:de:1c:68:e5:31:9b:83:91:54:db:b7:f5 -----BEGIN CERTIFICATE----- MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1 HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0 HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3 4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg 8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1 mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 -----END CERTIFICATE----- # Issuer: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc. # Subject: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc. # Label: "Starfield Services Root Certificate Authority - G2" # Serial: 0 # MD5 Fingerprint: 17:35:74:af:7b:61:1c:eb:f4:f9:3c:e2:ee:40:f9:a2 # SHA1 Fingerprint: 92:5a:8f:8d:2c:6d:04:e0:66:5f:59:6a:ff:22:d8:63:e8:25:6f:3f # SHA256 Fingerprint: 56:8d:69:05:a2:c8:87:08:a4:b3:02:51:90:ed:cf:ed:b1:97:4a:60:6a:13:c6:e5:29:0f:cb:2a:e6:3e:da:b5 -----BEGIN CERTIFICATE----- MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2 8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk 6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn 0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN sSi6 -----END CERTIFICATE----- # Issuer: CN=AffirmTrust Commercial O=AffirmTrust # Subject: CN=AffirmTrust Commercial O=AffirmTrust # Label: "AffirmTrust Commercial" # Serial: 8608355977964138876 # MD5 Fingerprint: 82:92:ba:5b:ef:cd:8a:6f:a6:3d:55:f9:84:f6:d6:b7 # SHA1 Fingerprint: f9:b5:b6:32:45:5f:9c:be:ec:57:5f:80:dc:e9:6e:2c:c7:b2:78:b7 # SHA256 Fingerprint: 03:76:ab:1d:54:c5:f9:80:3c:e4:b2:e2:01:a0:ee:7e:ef:7b:57:b6:36:e8:a9:3c:9b:8d:48:60:c9:6f:5f:a7 -----BEGIN CERTIFICATE----- MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz dCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp cm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC AQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP Hx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr ba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL MeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1 yHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr VwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/ nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ KoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG XUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj vbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= -----END CERTIFICATE----- # Issuer: CN=AffirmTrust Networking O=AffirmTrust # Subject: CN=AffirmTrust Networking O=AffirmTrust # Label: "AffirmTrust Networking" # Serial: 8957382827206547757 # MD5 Fingerprint: 42:65:ca:be:01:9a:9a:4c:a9:8c:41:49:cd:c0:d5:7f # SHA1 Fingerprint: 29:36:21:02:8b:20:ed:02:f5:66:c5:32:d1:d6:ed:90:9f:45:00:2f # SHA256 Fingerprint: 0a:81:ec:5a:92:97:77:f1:45:90:4a:f3:8d:5d:50:9f:66:b5:e2:c5:8f:cd:b5:31:05:8b:0e:17:f3:f0:b4:1b -----BEGIN CERTIFICATE----- MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz dCBOZXR3b3JraW5nMB4XDTEwMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDEL MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp cm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC AQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SEHi3y YJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbua kCNrmreIdIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRL QESxG9fhwoXA3hA/Pe24/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp 6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gbh+0t+nvujArjqWaJGctB+d1ENmHP4ndG yH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNVHQ4EFgQUBx/S55zawm6i QLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ KoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfO tDIuUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzu QY0x2+c06lkh1QF612S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZ Lgo/bNjR9eUJtGxUAArgFU2HdW23WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4u olu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48 x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= -----END CERTIFICATE----- # Issuer: CN=AffirmTrust Premium O=AffirmTrust # Subject: CN=AffirmTrust Premium O=AffirmTrust # Label: "AffirmTrust Premium" # Serial: 7893706540734352110 # MD5 Fingerprint: c4:5d:0e:48:b6:ac:28:30:4e:0a:bc:f9:38:16:87:57 # SHA1 Fingerprint: d8:a6:33:2c:e0:03:6f:b1:85:f6:63:4f:7d:6a:06:65:26:32:28:27 # SHA256 Fingerprint: 70:a7:3f:7f:37:6b:60:07:42:48:90:45:34:b1:14:82:d5:bf:0e:69:8e:cc:49:8d:f5:25:77:eb:f2:e9:3b:9a -----BEGIN CERTIFICATE----- MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz dCBQcmVtaXVtMB4XDTEwMDEyOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkG A1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1U cnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxBLf qV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtnBKAQ JG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ +jjeRFcV5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrS s8PhaJyJ+HoAVt70VZVs+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5 HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmdGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d7 70O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5Rp9EixAqnOEhss/n/fauG V+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NIS+LI+H+S qHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S 5u046uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4Ia C1nEWTJ3s7xgaVY5/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TX OwF0lkLgAOIua+rF7nKsu7/+6qqo+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYE FJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByvMiPIs0laUZx2 KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B 8OWycvpEgjNC6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQ MKSOyARiqcTtNd56l+0OOF6SL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc 0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK+4w1IX2COPKpVJEZNZOUbWo6xbLQ u4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmVBtWVyuEklut89pMF u+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFgIxpH YoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8 GKa1qF60g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaO RtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e KeC2uAloGRwYQw== -----END CERTIFICATE----- # Issuer: CN=AffirmTrust Premium ECC O=AffirmTrust # Subject: CN=AffirmTrust Premium ECC O=AffirmTrust # Label: "AffirmTrust Premium ECC" # Serial: 8401224907861490260 # MD5 Fingerprint: 64:b0:09:55:cf:b1:d5:99:e2:be:13:ab:a6:5d:ea:4d # SHA1 Fingerprint: b8:23:6b:00:2f:1d:16:86:53:01:55:6c:11:a4:37:ca:eb:ff:c3:bb # SHA256 Fingerprint: bd:71:fd:f6:da:97:e4:cf:62:d1:64:7a:dd:25:81:b0:7d:79:ad:f8:39:7e:b4:ec:ba:9c:5e:84:88:82:14:23 -----BEGIN CERTIFICATE----- MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D 0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9 ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ== -----END CERTIFICATE----- # Issuer: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority # Subject: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority # Label: "Certum Trusted Network CA" # Serial: 279744 # MD5 Fingerprint: d5:e9:81:40:c5:18:69:fc:46:2c:89:75:62:0f:aa:78 # SHA1 Fingerprint: 07:e0:32:e0:20:b7:2c:3f:19:2f:06:28:a2:59:3a:19:a7:0f:06:9e # SHA256 Fingerprint: 5c:58:46:8d:55:f5:8e:49:7e:74:39:82:d2:b5:00:10:b6:d1:65:37:4a:cf:83:a7:d4:a3:2d:b7:68:c4:40:8e -----BEGIN CERTIFICATE----- MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3 WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8 J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI 03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= -----END CERTIFICATE----- # Issuer: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA # Subject: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA # Label: "TWCA Root Certification Authority" # Serial: 1 # MD5 Fingerprint: aa:08:8f:f6:f9:7b:b7:f2:b1:a7:1e:9b:ea:ea:bd:79 # SHA1 Fingerprint: cf:9e:87:6d:d3:eb:fc:42:26:97:a3:b5:a3:7a:a0:76:a9:06:23:48 # SHA256 Fingerprint: bf:d8:8f:e1:10:1c:41:ae:3e:80:1b:f8:be:56:35:0e:e9:ba:d1:a6:b9:bd:51:5e:dc:5c:6d:5b:87:11:ac:44 -----BEGIN CERTIFICATE----- MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES MBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU V0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz WhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO LUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm aWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB AQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE AcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH K3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX RfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z rX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx 3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq hkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC MErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls XebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D lhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn aspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ YiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== -----END CERTIFICATE----- # Issuer: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2 # Subject: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2 # Label: "Security Communication RootCA2" # Serial: 0 # MD5 Fingerprint: 6c:39:7d:a4:0e:55:59:b2:3f:d6:41:b1:12:50:de:43 # SHA1 Fingerprint: 5f:3b:8c:f2:f8:10:b3:7d:78:b4:ce:ec:19:19:c3:73:34:b9:c7:74 # SHA256 Fingerprint: 51:3b:2c:ec:b8:10:d4:cd:e5:dd:85:39:1a:df:c6:c2:dd:60:d8:7b:b7:36:d2:b5:21:48:4a:a4:7a:0e:be:f6 -----BEGIN CERTIFICATE----- MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoX DTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRy dXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmlj YXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAV OVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGr zbl+dp+++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVM VAX3NuRFg3sUZdbcDE3R3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQ hNBqyjoGADdH5H5XTz+L62e4iKrFvlNVspHEfbmwhRkGeC7bYRr6hfVKkaHnFtWO ojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1KEOtOghY6rCcMU/Gt1SSw awNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8QIH4D5cs OPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3 DQEBCwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpF coJxDjrSzG+ntKEju/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXc okgfGT+Ok+vx+hfuzU7jBBJV1uXk3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8 t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy 1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/ SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 -----END CERTIFICATE----- # Issuer: CN=EC-ACC O=Agencia Catalana de Certificacio (NIF Q-0801176-I) OU=Serveis Publics de Certificacio/Vegeu https://www.catcert.net/verarrel (c)03/Jerarquia Entitats de Certificacio Catalanes # Subject: CN=EC-ACC O=Agencia Catalana de Certificacio (NIF Q-0801176-I) OU=Serveis Publics de Certificacio/Vegeu https://www.catcert.net/verarrel (c)03/Jerarquia Entitats de Certificacio Catalanes # Label: "EC-ACC" # Serial: -23701579247955709139626555126524820479 # MD5 Fingerprint: eb:f5:9d:29:0d:61:f9:42:1f:7c:c2:ba:6d:e3:15:09 # SHA1 Fingerprint: 28:90:3a:63:5b:52:80:fa:e6:77:4c:0b:6d:a7:d6:ba:a6:4a:f2:e8 # SHA256 Fingerprint: 88:49:7f:01:60:2f:31:54:24:6a:e2:8c:4d:5a:ef:10:f1:d8:7e:bb:76:62:6f:4a:e0:b7:f9:5b:a7:96:87:99 -----BEGIN CERTIFICATE----- MIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB 8zELMAkGA1UEBhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2Vy dGlmaWNhY2lvIChOSUYgUS0wODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1 YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYDVQQLEyxWZWdldSBodHRwczovL3d3 dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UECxMsSmVyYXJxdWlh IEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMTBkVD LUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQG EwJFUzE7MDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8g KE5JRiBRLTA4MDExNzYtSSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBD ZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZlZ2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQu bmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJhcnF1aWEgRW50aXRhdHMg ZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUNDMIIBIjAN BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R 85iKw5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm 4CgPukLjbo73FCeTae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaV HMf5NLWUhdWZXqBIoH7nF2W4onW4HvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNd QlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0aE9jD2z3Il3rucO2n5nzbcc8t lGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw0JDnJwIDAQAB o4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4 opvpXY0wfwYDVR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBo dHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidW ZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAwDQYJKoZIhvcN AQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJlF7W2u++AVtd0x7Y /X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNaAl6k SBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhy Rp/7SNVel+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOS Agu+TGbrIP65y7WZf+a2E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xl nJ2lYJU6Un/10asIbvPuW/mIPX64b24D5EI= -----END CERTIFICATE----- # Issuer: CN=Hellenic Academic and Research Institutions RootCA 2011 O=Hellenic Academic and Research Institutions Cert. Authority # Subject: CN=Hellenic Academic and Research Institutions RootCA 2011 O=Hellenic Academic and Research Institutions Cert. Authority # Label: "Hellenic Academic and Research Institutions RootCA 2011" # Serial: 0 # MD5 Fingerprint: 73:9f:4c:4b:73:5b:79:e9:fa:ba:1c:ef:6e:cb:d5:c9 # SHA1 Fingerprint: fe:45:65:9b:79:03:5b:98:a1:61:b5:51:2e:ac:da:58:09:48:22:4d # SHA256 Fingerprint: bc:10:4f:15:a4:8b:e7:09:dc:a5:42:a7:e1:d4:b9:df:6f:05:45:27:e8:02:ea:a9:2d:59:54:44:25:8a:fe:71 -----BEGIN CERTIFICATE----- MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1Ix RDBCBgNVBAoTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1p YyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIFJvb3RDQSAyMDExMB4XDTExMTIw NjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYTAkdSMUQwQgYDVQQK EztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIENl cnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl c2VhcmNoIEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEB BQADggEPADCCAQoCggEBAKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPz dYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJ fel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa71HFK9+WXesyHgLacEns bgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u8yBRQlqD 75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSP FEDH3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNV HRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp 5dgTBCPuQSUwRwYDVR0eBEAwPqA8MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQu b3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQub3JnMA0GCSqGSIb3DQEBBQUA A4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVtXdMiKahsog2p 6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8 TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7 dIsXRSZMFpGD/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8Acys Nnq/onN694/BtZqhFLKPM58N7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXI l7WdmplNsDz4SgCbZN2fOUvRJ9e4 -----END CERTIFICATE----- # Issuer: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967 # Subject: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967 # Label: "Actalis Authentication Root CA" # Serial: 6271844772424770508 # MD5 Fingerprint: 69:c1:0d:4f:07:a3:1b:c3:fe:56:3d:04:bc:11:f6:a6 # SHA1 Fingerprint: f3:73:b3:87:06:5a:28:84:8a:f2:f3:4a:ce:19:2b:dd:c7:8e:9c:ac # SHA256 Fingerprint: 55:92:60:84:ec:96:3a:64:b9:6e:2a:be:01:ce:0b:a8:6a:64:fb:fe:bc:c7:aa:b5:af:c1:55:b3:7f:d7:60:66 -----BEGIN CERTIFICATE----- MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDkyMjExMjIwMlowazELMAkGA1UEBhMC SVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1 ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENB MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNv UTufClrJwkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX 4ay8IMKx4INRimlNAJZaby/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9 KK3giq0itFZljoZUj5NDKd45RnijMCO6zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/ gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1fYVEiVRvjRuPjPdA1Yprb rxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2oxgkg4YQ 51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2F be8lEfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxe KF+w6D9Fz8+vm2/7hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4F v6MGn8i1zeQf1xcGDXqVdFUNaBr8EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbn fpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5jF66CyCU3nuDuP/jVo23Eek7 jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLYiDrIn3hm7Ynz ezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAL e3KHwGCmSUyIWOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70 jsNjLiNmsGe+b7bAEzlgqqI0JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDz WochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKxK3JCaKygvU5a2hi/a5iB0P2avl4V SM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+Xlff1ANATIGk0k9j pwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC4yyX X04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+Ok fcvHlXHo2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7R K4X9p2jIugErsWx0Hbhzlefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btU ZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXemOR/qnuOf0GZvBeyqdn6/axag67XH/JJU LysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT LnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== -----END CERTIFICATE----- # Issuer: CN=Buypass Class 2 Root CA O=Buypass AS-983163327 # Subject: CN=Buypass Class 2 Root CA O=Buypass AS-983163327 # Label: "Buypass Class 2 Root CA" # Serial: 2 # MD5 Fingerprint: 46:a7:d2:fe:45:fb:64:5a:a8:59:90:9b:78:44:9b:29 # SHA1 Fingerprint: 49:0a:75:74:de:87:0a:47:fe:58:ee:f6:c7:6b:eb:c6:0b:12:40:99 # SHA256 Fingerprint: 9a:11:40:25:19:7c:5b:b9:5d:94:e6:3d:55:cd:43:79:08:47:b6:46:b2:3c:df:11:ad:a4:a0:0e:ff:15:fb:48 -----BEGIN CERTIFICATE----- MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg Q2xhc3MgMiBSb290IENBMB4XDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1ow TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw HgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB BQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1g1Lr 6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPV L4O2fuPn9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC91 1K2GScuVr1QGbNgGE41b/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHx MlAQTn/0hpPshNOOvEu/XAFOBz3cFIqUCqTqc/sLUegTBxj6DvEr0VQVfTzh97QZ QmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeffawrbD02TTqigzXsu8lkB arcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgIzRFo1clr Us3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLi FRhnBkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRS P/TizPJhk9H9Z2vXUq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN 9SG9dKpN6nIDSdvHXx1iY8f93ZHsM+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxP AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMmAd+BikoL1Rpzz uvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAU18h 9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3t OluwlN5E40EIosHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo +fsicdl9sz1Gv7SEr5AcD48Saq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7 KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYdDnkM/crqJIByw5c/8nerQyIKx+u2 DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWDLfJ6v9r9jv6ly0Us H8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0oyLQ I+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7 5t98biGCwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h 3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz Y11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA= -----END CERTIFICATE----- # Issuer: CN=Buypass Class 3 Root CA O=Buypass AS-983163327 # Subject: CN=Buypass Class 3 Root CA O=Buypass AS-983163327 # Label: "Buypass Class 3 Root CA" # Serial: 2 # MD5 Fingerprint: 3d:3b:18:9e:2c:64:5a:e8:d5:88:ce:0e:f9:37:c2:ec # SHA1 Fingerprint: da:fa:f7:fa:66:84:ec:06:8f:14:50:bd:c7:c2:81:a5:bc:a9:64:57 # SHA256 Fingerprint: ed:f7:eb:bc:a2:7a:2a:38:4d:38:7b:7d:40:10:c6:66:e2:ed:b4:84:3e:4c:29:b4:ae:1d:5b:93:32:e6:b2:4d -----BEGIN CERTIFICATE----- MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg Q2xhc3MgMyBSb290IENBMB4XDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFow TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw HgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB BQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRHsJ8Y ZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3E N3coTRiR5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9 tznDDgFHmV0ST9tD+leh7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX 0DJq1l1sDPGzbjniazEuOQAnFN44wOwZZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c /3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH2xc519woe2v1n/MuwU8X KhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV/afmiSTY zIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvS O1UQRwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D 34xFMFbG02SrZvPAXpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgP K9Dx2hzLabjKSWJtyNBjYt1gD1iqj6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3 AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEe4zf/lb+74suwv Tg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAACAj QTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXS IGrs/CIBKM+GuIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2 HJLw5QY33KbmkJs4j1xrG0aGQ0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsa O5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8ZORK15FTAaggiG6cX0S5y2CBNOxv 033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2KSb12tjE8nVhz36u dmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz6MkE kbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41 3OEMXbugUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvD u79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq 4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc= -----END CERTIFICATE----- # Issuer: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center # Subject: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center # Label: "T-TeleSec GlobalRoot Class 3" # Serial: 1 # MD5 Fingerprint: ca:fb:40:a8:4e:39:92:8a:1d:fe:8e:2f:c4:27:ea:ef # SHA1 Fingerprint: 55:a6:72:3e:cb:f2:ec:cd:c3:23:74:70:19:9d:2a:be:11:e3:81:d1 # SHA256 Fingerprint: fd:73:da:d3:1c:64:4f:f1:b4:3b:ef:0c:cd:da:96:71:0b:9c:d9:87:5e:ca:7e:31:70:7a:f3:e9:6d:52:2b:bd -----BEGIN CERTIFICATE----- MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1 OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN 8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/ RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4 hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5 ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1 A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ 1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30 6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT 91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p TpPDpFQUWw== -----END CERTIFICATE----- # Issuer: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH # Subject: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH # Label: "D-TRUST Root Class 3 CA 2 2009" # Serial: 623603 # MD5 Fingerprint: cd:e0:25:69:8d:47:ac:9c:89:35:90:f7:fd:51:3d:2f # SHA1 Fingerprint: 58:e8:ab:b0:36:15:33:fb:80:f7:9b:1b:6d:29:d3:ff:8d:5f:00:f0 # SHA256 Fingerprint: 49:e7:a4:42:ac:f0:ea:62:87:05:00:54:b5:25:64:b6:50:e4:f4:9e:42:e3:48:d6:aa:38:e0:39:e9:57:b1:c1 -----BEGIN CERTIFICATE----- MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03 UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42 tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp /hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0 o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8 PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y Johw1+qRzT65ysCQblrGXnRl11z+o+I= -----END CERTIFICATE----- # Issuer: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH # Subject: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH # Label: "D-TRUST Root Class 3 CA 2 EV 2009" # Serial: 623604 # MD5 Fingerprint: aa:c6:43:2c:5e:2d:cd:c4:34:c0:50:4f:11:02:4f:b6 # SHA1 Fingerprint: 96:c9:1b:0b:95:b4:10:98:42:fa:d0:d8:22:79:fe:60:fa:b9:16:83 # SHA256 Fingerprint: ee:c5:49:6b:98:8c:e9:86:25:b9:34:09:2e:ec:29:08:be:d0:b0:f3:16:c2:d4:73:0c:84:ea:f1:f3:d3:48:81 -----BEGIN CERTIFICATE----- MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRF MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBD bGFzcyAzIENBIDIgRVYgMjAwOTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUw NDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNV BAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOTCCASIwDQYJKoZI hvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfSegpn ljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM0 3TP1YtHhzRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6Z qQTMFexgaDbtCHu39b+T7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lR p75mpoo6Kr3HGrHhFPC+Oh25z1uxav60sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8 HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure3511H3a6UCAwEAAaOCASQw ggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyvcop9Ntea HNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFw Oi8vZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xh c3MlMjAzJTIwQ0ElMjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1E RT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0MEagRKBChkBodHRwOi8vd3d3LmQt dHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xhc3NfM19jYV8yX2V2XzIwMDku Y3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+PPoeUSbrh/Yp 3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05 nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNF CSuGdXzfX2lXANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7na xpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX KVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1 -----END CERTIFICATE----- # Issuer: CN=CA Disig Root R2 O=Disig a.s. # Subject: CN=CA Disig Root R2 O=Disig a.s. # Label: "CA Disig Root R2" # Serial: 10572350602393338211 # MD5 Fingerprint: 26:01:fb:d8:27:a7:17:9a:45:54:38:1a:43:01:3b:03 # SHA1 Fingerprint: b5:61:eb:ea:a4:de:e4:25:4b:69:1a:98:a5:57:47:c2:34:c7:d9:71 # SHA256 Fingerprint: e2:3d:4a:03:6d:7b:70:e9:f5:95:b1:42:20:79:d2:b9:1e:df:bb:1f:b6:51:a0:63:3e:aa:8a:9d:c5:f8:07:03 -----BEGIN CERTIFICATE----- MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQy MDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjIw ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbCw3Oe NcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNH PWSb6WiaxswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3I x2ymrdMxp7zo5eFm1tL7A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbe QTg06ov80egEFGEtQX6sx3dOy1FU+16SGBsEWmjGycT6txOgmLcRK7fWV8x8nhfR yyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqVg8NTEQxzHQuyRpDRQjrO QG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa5Beny912 H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJ QfYEkoopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUD i/ZnWejBBhG93c+AAk9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORs nLMOPReisjQS1n6yqEm70XooQL6iFh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1 rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud DwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5uQu0wDQYJKoZI hvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqf GopTpti72TVVsRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkb lvdhuDvEK7Z4bLQjb/D907JedR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka +elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W81k/BfDxujRNt+3vrMNDcTa/F1bal TFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjxmHHEt38OFdAlab0i nSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01utI3 gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18Dr G5gPcFw0sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3Os zMOl6W8KjptlwlCFtaOgUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8x L4ysEr3vQCj8KWefshNPZiTEUxnpHikV7+ZtsH8tZ/3zbBt1RqPlShfppNcL -----END CERTIFICATE----- # Issuer: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV # Subject: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV # Label: "ACCVRAIZ1" # Serial: 6828503384748696800 # MD5 Fingerprint: d0:a0:5a:ee:05:b6:09:94:21:a1:7d:f1:b2:29:82:02 # SHA1 Fingerprint: 93:05:7a:88:15:c6:4f:ce:88:2f:fa:91:16:52:28:78:bc:53:64:17 # SHA256 Fingerprint: 9a:6e:c0:12:e1:a7:da:9d:be:34:19:4d:47:8a:d7:c0:db:18:22:fb:07:1d:f1:29:81:49:6e:d1:04:38:41:13 -----BEGIN CERTIFICATE----- MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UE AwwJQUNDVlJBSVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQsw CQYDVQQGEwJFUzAeFw0xMTA1MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQ BgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwHUEtJQUNDVjENMAsGA1UECgwEQUND VjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCb qau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gMjmoY HtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWo G2ioPej0RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpA lHPrzg5XPAOBOp0KoVdDaaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhr IA8wKFSVf+DuzgpmndFALW4ir50awQUZ0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/ 0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDGWuzndN9wrqODJerWx5eH k6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs78yM2x/47 4KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMO m3WR5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpa cXpkatcnYGMN285J9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPl uUsXQA+xtrn13k/c4LOsOxFwYIRKQ26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYI KwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRwOi8vd3d3LmFjY3YuZXMvZmls ZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEuY3J0MB8GCCsG AQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2 VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeT VfZW6oHlNsyMHj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIG CCsGAQUFBwICMIIBFB6CARAAQQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUA cgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBhAO0AegAgAGQAZQAgAGwAYQAgAEEA QwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUAYwBuAG8AbABvAGcA 7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBjAHQA cgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAA QwBQAFMAIABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUA czAwBggrBgEFBQcCARYkaHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2Mu aHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRt aW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2MV9kZXIuY3JsMA4GA1Ud DwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZIhvcNAQEF BQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdp D70ER9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gU JyCpZET/LtZ1qmxNYEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+m AM/EKXMRNt6GGT6d7hmKG9Ww7Y49nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepD vV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJTS+xJlsndQAJxGJ3KQhfnlms tn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3sCPdK6jT2iWH 7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szA h1xA2syVP1XgNce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xF d3+YJ5oyXSrjhO7FmGYvliAd3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2H pPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3pEfbRD0tVNEYqi4Y7 -----END CERTIFICATE----- # Issuer: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA # Subject: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA # Label: "TWCA Global Root CA" # Serial: 3262 # MD5 Fingerprint: f9:03:7e:cf:e6:9e:3c:73:7a:2a:90:07:69:ff:2b:96 # SHA1 Fingerprint: 9c:bb:48:53:f6:a4:f6:d3:52:a4:e8:32:52:55:60:13:f5:ad:af:65 # SHA256 Fingerprint: 59:76:90:07:f7:68:5d:0f:cd:50:87:2f:9f:95:d5:75:5a:5b:2b:45:7d:81:f3:69:2b:61:0a:98:67:2f:0e:1b -----BEGIN CERTIFICATE----- MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5 NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT B1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG SIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF 10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz 0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh MBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH zIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc 46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2 yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi laLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP oA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA BDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE qYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm 4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB /zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL 1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF H6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo RI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+ nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh 15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW 6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy KwbQBM0= -----END CERTIFICATE----- # Issuer: CN=TeliaSonera Root CA v1 O=TeliaSonera # Subject: CN=TeliaSonera Root CA v1 O=TeliaSonera # Label: "TeliaSonera Root CA v1" # Serial: 199041966741090107964904287217786801558 # MD5 Fingerprint: 37:41:49:1b:18:56:9a:26:f5:ad:c2:66:fb:40:a5:4c # SHA1 Fingerprint: 43:13:bb:96:f1:d5:86:9b:c1:4e:6a:92:f6:cf:f6:34:69:87:82:37 # SHA256 Fingerprint: dd:69:36:fe:21:f8:f0:77:c1:23:a1:a5:21:c1:22:24:f7:22:55:b7:3e:03:a7:26:06:93:e8:a2:4b:0f:a3:89 -----BEGIN CERTIFICATE----- MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAw NzEUMBIGA1UECgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJv b3QgQ0EgdjEwHhcNMDcxMDE4MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYD VQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwWVGVsaWFTb25lcmEgUm9vdCBDQSB2 MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+6yfwIaPzaSZVfp3F VRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA3GV1 7CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+X Z75Ljo1kB1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+ /jXh7VB7qTCNGdMJjmhnXb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs 81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxHoLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkm dtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3F0fUTPHSiXk+TT2YqGHe Oh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJoWjiUIMu sDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4 pgd7gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fs slESl1MpWtTwEhDcTwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQ arMCpgKIv7NHfirZ1fpoeDVNAgMBAAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYD VR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qWDNXr+nuqF+gTEjANBgkqhkiG 9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNmzqjMDfz1mgbl dxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx 0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1Tj TQpgcmLNkQfWpb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBed Y2gea+zDTYa4EzAvXUYNR0PVG6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7 Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpcc41teyWRyu5FrgZLAMzTsVlQ2jqI OylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOTJsjrDNYmiLbAJM+7 vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2qReW t88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcn HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= -----END CERTIFICATE----- # Issuer: CN=E-Tugra Certification Authority O=E-Tuğra EBG Bilişim Teknolojileri ve Hizmetleri A.Ş. OU=E-Tugra Sertifikasyon Merkezi # Subject: CN=E-Tugra Certification Authority O=E-Tuğra EBG Bilişim Teknolojileri ve Hizmetleri A.Ş. OU=E-Tugra Sertifikasyon Merkezi # Label: "E-Tugra Certification Authority" # Serial: 7667447206703254355 # MD5 Fingerprint: b8:a1:03:63:b0:bd:21:71:70:8a:6f:13:3a:bb:79:49 # SHA1 Fingerprint: 51:c6:e7:08:49:06:6e:f3:92:d4:5c:a0:0d:6d:a3:62:8f:c3:52:39 # SHA256 Fingerprint: b0:bf:d5:2b:b0:d7:d9:bd:92:bf:5d:4d:c1:3d:a2:55:c0:2c:54:2f:37:83:65:ea:89:39:11:f5:5e:55:f2:3c -----BEGIN CERTIFICATE----- MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNV BAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBC aWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNV BAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQDDB9FLVR1 Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMwNTEyMDk0OFoXDTIz MDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+ BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhp em1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4vU/kwVRHoViVF56C/UY B4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vdhQd2h8y/L5VMzH2nPbxH D5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5KCKpbknSF Q9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEo q1+gElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3D k14opz8n8Y4e0ypQBaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcH fC425lAcP9tDJMW/hkd5s3kc91r0E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsut dEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gzrt48Ue7LE3wBf4QOXVGUnhMM ti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAqjqFGOjGY5RH8 zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUX U8u3Zg5mTPj5dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6 Jyr+zE7S6E5UMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5 XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAF Nzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAKkEh47U6YA5n+KGCR HTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jOXKqY GwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c 77NCR807VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3 +GbHeJAAFS6LrVE1Uweoa2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WK vJUawSg5TB9D0pH0clmKuVb8P7Sd2nCcdlqMQ1DujjByTd//SffGqWfZbawCEeI6 FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEVKV0jq9BgoRJP3vQXzTLl yb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gTDx4JnW2P AJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpD y4Q08ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8d NL/+I5c30jn6PQ0GC7TbO6Orb1wdtn7os4I07QZcJA== -----END CERTIFICATE----- # Issuer: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center # Subject: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center # Label: "T-TeleSec GlobalRoot Class 2" # Serial: 1 # MD5 Fingerprint: 2b:9b:9e:e4:7b:6c:1f:00:72:1a:cc:c1:77:79:df:6a # SHA1 Fingerprint: 59:0d:2d:7d:88:4f:40:2e:61:7e:a5:62:32:17:65:cf:17:d8:94:e9 # SHA256 Fingerprint: 91:e2:f5:78:8d:58:10:eb:a7:ba:58:73:7d:e1:54:8a:8e:ca:cd:01:45:98:bc:0b:14:3e:04:1b:17:05:25:52 -----BEGIN CERTIFICATE----- MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1 OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi 1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/ WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6 g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN 9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP BSeOE6Fuwg== -----END CERTIFICATE----- # Issuer: CN=Atos TrustedRoot 2011 O=Atos # Subject: CN=Atos TrustedRoot 2011 O=Atos # Label: "Atos TrustedRoot 2011" # Serial: 6643877497813316402 # MD5 Fingerprint: ae:b9:c4:32:4b:ac:7f:5d:66:cc:77:94:bb:2a:77:56 # SHA1 Fingerprint: 2b:b1:f5:3e:55:0c:1d:c5:f1:d4:e6:b7:6a:46:4b:55:06:02:ac:21 # SHA256 Fingerprint: f3:56:be:a2:44:b7:a9:1e:b3:5d:53:ca:9a:d7:86:4a:ce:01:8e:2d:35:d5:f8:f9:6d:df:68:a6:f4:1a:a4:74 -----BEGIN CERTIFICATE----- MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UE AwwVQXRvcyBUcnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQG EwJERTAeFw0xMTA3MDcxNDU4MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMM FUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsGA1UECgwEQXRvczELMAkGA1UEBhMC REUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCVhTuXbyo7LjvPpvMp Nb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr54rM VD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+ SZFhyBH+DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ 4J7sVaE3IqKHBAUsR320HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0L cp2AMBYHlT8oDv3FdU9T1nSatCQujgKRz3bFmx5VdJx4IbHwLfELn8LVlhgf8FQi eowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7Rl+lwrrw7GWzbITAPBgNV HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZbNshMBgG A1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3 DQEBCwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8j vZfza1zv7v1Apt+hk6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kP DpFrdRbhIfzYJsdHt6bPWHJxfrrhTZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pc maHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a961qn8FYiqTxlVMYVqL2Gns2D lmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G3mB/ufNPRJLv KrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed -----END CERTIFICATE----- # Issuer: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited # Subject: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited # Label: "QuoVadis Root CA 1 G3" # Serial: 687049649626669250736271037606554624078720034195 # MD5 Fingerprint: a4:bc:5b:3f:fe:37:9a:fa:64:f0:e2:fa:05:3d:0b:ab # SHA1 Fingerprint: 1b:8e:ea:57:96:29:1a:c9:39:ea:b8:0a:81:1a:73:73:c0:93:79:67 # SHA256 Fingerprint: 8a:86:6f:d1:b2:76:b5:7e:57:8e:92:1c:65:82:8a:2b:ed:58:e9:f2:f2:88:05:41:34:b7:f1:f4:bf:c9:cc:74 -----BEGIN CERTIFICATE----- MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQEL BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00 MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEgRzMwggIiMA0GCSqG SIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakEPBtV wedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWe rNrwU8lmPNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF341 68Xfuw6cwI2H44g4hWf6Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh 4Pw5qlPafX7PGglTvF0FBM+hSo+LdoINofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXp UhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/lg6AnhF4EwfWQvTA9xO+o abw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV7qJZjqlc 3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/G KubX9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSt hfbZxbGL0eUQMk1fiyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KO Tk0k+17kBL5yG6YnLUlamXrXXAkgt3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOt zCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB BjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZIhvcNAQELBQAD ggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2 cDMT/uFPpiN3GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUN qXsCHKnQO18LwIE6PWThv6ctTr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5 YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP+V04ikkwj+3x6xn0dxoxGE1nVGwv b2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh3jRJjehZrJ3ydlo2 8hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fawx/k NSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNj ZgKAvQU6O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhp q1467HxpvMc7hU6eFbm0FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFt nh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOVhMJKzRwuJIczYOXD -----END CERTIFICATE----- # Issuer: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited # Subject: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited # Label: "QuoVadis Root CA 2 G3" # Serial: 390156079458959257446133169266079962026824725800 # MD5 Fingerprint: af:0c:86:6e:bf:40:2d:7f:0b:3e:12:50:ba:12:3d:06 # SHA1 Fingerprint: 09:3c:61:f3:8b:8b:dc:7d:55:df:75:38:02:05:00:e1:25:f5:c8:36 # SHA256 Fingerprint: 8f:e4:fb:0a:f9:3a:4d:0d:67:db:0b:eb:b2:3e:37:c7:1b:f3:25:dc:bc:dd:24:0e:a0:4d:af:58:b4:7e:18:40 -----BEGIN CERTIFICATE----- MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00 MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIgRzMwggIiMA0GCSqG SIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFhZiFf qq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMW n4rjyduYNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ym c5GQYaYDFCDy54ejiK2toIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+ O7q414AB+6XrW7PFXmAqMaCvN+ggOp+oMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1 o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+lV0POKa2Mq1W/xPtbAd0j IaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZoL1NesNKq IcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz 8eQQsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43eh vNURG3YBZwjgQQvD6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l 7ZizlWNof/k19N+IxWA1ksB8aRxhlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALG cC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB BjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZIhvcNAQELBQAD ggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66 AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RC roijQ1h5fq7KpVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0Ga W/ZZGYjeVYg3UQt4XAoeo0L9x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4n lv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgzdWqTHBLmYF5vHX/JHyPLhGGfHoJE +V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6XU/IyAgkwo1jwDQHV csaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+NwmNtd dbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg KCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM HVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4 WSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M -----END CERTIFICATE----- # Issuer: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited # Subject: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited # Label: "QuoVadis Root CA 3 G3" # Serial: 268090761170461462463995952157327242137089239581 # MD5 Fingerprint: df:7d:b9:ad:54:6f:68:a1:df:89:57:03:97:43:b0:d7 # SHA1 Fingerprint: 48:12:bd:92:3c:a8:c4:39:06:e7:30:6d:27:96:e6:a4:cf:22:2e:7d # SHA256 Fingerprint: 88:ef:81:de:20:2e:b0:18:45:2e:43:f8:64:72:5c:ea:5f:bd:1f:c2:d9:d2:05:73:07:09:c5:d8:b8:69:0f:46 -----BEGIN CERTIFICATE----- MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00 MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMgRzMwggIiMA0GCSqG SIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286IxSR /xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNu FoM7pmRLMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXR U7Ox7sWTaYI+FrUoRqHe6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+c ra1AdHkrAj80//ogaX3T7mH1urPnMNA3I4ZyYUUpSFlob3emLoG+B01vr87ERROR FHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3UVDmrJqMz6nWB2i3ND0/k A9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f75li59wzw eyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634Ryl sSqiMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBp VzgeAVuNVejH38DMdyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0Q A4XN8f+MFrXBsj6IbGB/kE+V9/YtrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB BjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZIhvcNAQELBQAD ggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnI FUBhynLWcKzSt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5Wvv oxXqA/4Ti2Tk08HS6IT7SdEQTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFg u/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP 0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGibIh6BJpsQBJFxwAYf 3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmDhPbl 8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+ DhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN PlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ ywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0 -----END CERTIFICATE----- # Issuer: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com # Subject: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com # Label: "DigiCert Assured ID Root G2" # Serial: 15385348160840213938643033620894905419 # MD5 Fingerprint: 92:38:b9:f8:63:24:82:65:2c:57:33:e6:fe:81:8f:9d # SHA1 Fingerprint: a1:4b:48:d9:43:ee:0a:0e:40:90:4f:3c:e0:a4:c0:91:93:51:5d:3f # SHA256 Fingerprint: 7d:05:eb:b6:82:33:9f:8c:94:51:ee:09:4e:eb:fe:fa:79:53:a1:14:ed:b2:f4:49:49:45:2f:ab:7d:2f:c1:85 -----BEGIN CERTIFICATE----- MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I 0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9 B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo IhNzbM8m9Yop5w== -----END CERTIFICATE----- # Issuer: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com # Subject: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com # Label: "DigiCert Assured ID Root G3" # Serial: 15459312981008553731928384953135426796 # MD5 Fingerprint: 7c:7f:65:31:0c:81:df:8d:ba:3e:99:e2:5c:ad:6e:fb # SHA1 Fingerprint: f5:17:a2:4f:9a:48:c6:c9:f8:a2:00:26:9f:dc:0f:48:2c:ab:30:89 # SHA256 Fingerprint: 7e:37:cb:8b:4c:47:09:0c:ab:36:55:1b:a6:f4:5d:b8:40:68:0f:ba:16:6a:95:2d:b1:00:71:7f:43:05:3f:c2 -----BEGIN CERTIFICATE----- MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv 6pZjamVFkpUBtA== -----END CERTIFICATE----- # Issuer: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com # Subject: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com # Label: "DigiCert Global Root G2" # Serial: 4293743540046975378534879503202253541 # MD5 Fingerprint: e4:a6:8a:c8:54:ac:52:42:46:0a:fd:72:48:1b:2a:44 # SHA1 Fingerprint: df:3c:24:f9:bf:d6:66:76:1b:26:80:73:fe:06:d1:cc:8d:4f:82:a4 # SHA256 Fingerprint: cb:3c:cb:b7:60:31:e5:e0:13:8f:8d:d3:9a:23:f9:de:47:ff:c3:5e:43:c1:14:4c:ea:27:d4:6a:5a:b1:cb:5f -----BEGIN CERTIFICATE----- MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG 9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI 2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx 1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV 5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY 1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl MrY= -----END CERTIFICATE----- # Issuer: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com # Subject: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com # Label: "DigiCert Global Root G3" # Serial: 7089244469030293291760083333884364146 # MD5 Fingerprint: f5:5d:a4:50:a5:fb:28:7e:1e:0f:0d:cc:96:57:56:ca # SHA1 Fingerprint: 7e:04:de:89:6a:3e:66:6d:00:e6:87:d3:3f:fa:d9:3b:e8:3d:34:9e # SHA256 Fingerprint: 31:ad:66:48:f8:10:41:38:c7:38:f3:9e:a4:32:01:33:39:3e:3a:18:cc:02:29:6e:f9:7c:2a:c9:ef:67:31:d0 -----BEGIN CERTIFICATE----- MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/ oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8 sycX -----END CERTIFICATE----- # Issuer: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com # Subject: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com # Label: "DigiCert Trusted Root G4" # Serial: 7451500558977370777930084869016614236 # MD5 Fingerprint: 78:f2:fc:aa:60:1f:2f:b4:eb:c9:37:ba:53:2e:75:49 # SHA1 Fingerprint: dd:fb:16:cd:49:31:c9:73:a2:03:7d:3f:c8:3a:4d:7d:77:5d:05:e4 # SHA256 Fingerprint: 55:2f:7b:dc:f1:a7:af:9e:6c:e6:72:01:7f:4f:12:ab:f7:72:40:c7:8e:76:1a:c2:03:d1:d9:d2:0a:c8:99:88 -----BEGIN CERTIFICATE----- MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/ CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t 9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2 SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd +SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N 0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie 4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1 /YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+ -----END CERTIFICATE----- # Issuer: CN=COMODO RSA Certification Authority O=COMODO CA Limited # Subject: CN=COMODO RSA Certification Authority O=COMODO CA Limited # Label: "COMODO RSA Certification Authority" # Serial: 101909084537582093308941363524873193117 # MD5 Fingerprint: 1b:31:b0:71:40:36:cc:14:36:91:ad:c4:3e:fd:ec:18 # SHA1 Fingerprint: af:e5:d2:44:a8:d1:19:42:30:ff:47:9f:e2:f8:97:bb:cd:7a:8c:b4 # SHA256 Fingerprint: 52:f0:e1:c4:e5:8e:c6:29:29:1b:60:31:7f:07:46:71:b8:5d:7e:a8:0d:5b:07:27:34:63:53:4b:32:b4:02:34 -----BEGIN CERTIFICATE----- MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5 MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR 6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC 9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV /erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z +pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB /wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM 4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV 2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl 0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB NVOFBkpdn627G190 -----END CERTIFICATE----- # Issuer: CN=USERTrust RSA Certification Authority O=The USERTRUST Network # Subject: CN=USERTrust RSA Certification Authority O=The USERTRUST Network # Label: "USERTrust RSA Certification Authority" # Serial: 2645093764781058787591871645665788717 # MD5 Fingerprint: 1b:fe:69:d1:91:b7:19:33:a3:72:a8:0f:e1:55:e5:b5 # SHA1 Fingerprint: 2b:8f:1b:57:33:0d:bb:a2:d0:7a:6c:51:f7:0e:e9:0d:da:b9:ad:8e # SHA256 Fingerprint: e7:93:c9:b0:2f:d8:aa:13:e2:1c:31:22:8a:cc:b0:81:19:64:3b:74:9c:89:89:64:b1:74:6d:46:c3:d4:cb:d2 -----BEGIN CERTIFICATE----- MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B 3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/ Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2 VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT 79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6 c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3 ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs 8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/ qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG jjxDah2nGN59PRbxYvnKkKj9 -----END CERTIFICATE----- # Issuer: CN=USERTrust ECC Certification Authority O=The USERTRUST Network # Subject: CN=USERTrust ECC Certification Authority O=The USERTRUST Network # Label: "USERTrust ECC Certification Authority" # Serial: 123013823720199481456569720443997572134 # MD5 Fingerprint: fa:68:bc:d9:b5:7f:ad:fd:c9:1d:06:83:28:cc:24:c1 # SHA1 Fingerprint: d1:cb:ca:5d:b2:d5:2a:7f:69:3b:67:4d:e5:f0:5a:1d:0c:95:7d:f0 # SHA256 Fingerprint: 4f:f4:60:d5:4b:9c:86:da:bf:bc:fc:57:12:e0:40:0d:2b:ed:3f:bc:4d:4f:bd:aa:86:e0:6a:dc:d2:a9:ad:7a -----BEGIN CERTIFICATE----- MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg VVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm aWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo I+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng o4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= -----END CERTIFICATE----- # Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4 # Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4 # Label: "GlobalSign ECC Root CA - R4" # Serial: 14367148294922964480859022125800977897474 # MD5 Fingerprint: 20:f0:27:68:d1:7e:a0:9d:0e:e6:2a:ca:df:5c:89:8e # SHA1 Fingerprint: 69:69:56:2e:40:80:f4:24:a1:e7:19:9f:14:ba:f3:ee:58:ab:6a:bb # SHA256 Fingerprint: be:c9:49:11:c2:95:56:76:db:6c:0a:55:09:86:d7:6e:3b:a0:05:66:7c:44:2c:97:62:b4:fb:b7:73:de:22:8c -----BEGIN CERTIFICATE----- MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD QSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprlOQcJ FspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAw DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61F uOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX kPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs ewv4n4Q= -----END CERTIFICATE----- # Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5 # Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5 # Label: "GlobalSign ECC Root CA - R5" # Serial: 32785792099990507226680698011560947931244 # MD5 Fingerprint: 9f:ad:3b:1c:02:1e:8a:ba:17:74:38:81:0c:a2:bc:08 # SHA1 Fingerprint: 1f:24:c6:30:cd:a4:18:ef:20:69:ff:ad:4f:dd:5f:46:3a:1b:69:aa # SHA256 Fingerprint: 17:9f:bc:14:8a:3d:d0:0f:d2:4e:a1:34:58:cc:43:bf:a7:f5:9c:81:82:d7:83:a5:13:f6:eb:ec:10:0c:89:24 -----BEGIN CERTIFICATE----- MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD QSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6SFkc 8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8ke hOvRnkmSh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg 515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO xwy8p2Fp8fc74SrL+SvzZpA3 -----END CERTIFICATE----- # Issuer: CN=Staat der Nederlanden EV Root CA O=Staat der Nederlanden # Subject: CN=Staat der Nederlanden EV Root CA O=Staat der Nederlanden # Label: "Staat der Nederlanden EV Root CA" # Serial: 10000013 # MD5 Fingerprint: fc:06:af:7b:e8:1a:f1:9a:b4:e8:d2:70:1f:c0:f5:ba # SHA1 Fingerprint: 76:e2:7e:c1:4f:db:82:c1:c0:a6:75:b5:05:be:3d:29:b4:ed:db:bb # SHA256 Fingerprint: 4d:24:91:41:4c:fe:95:67:46:ec:4c:ef:a6:cf:6f:72:e2:8a:13:29:43:2f:9d:8a:90:7a:c4:cb:5d:ad:c1:5a -----BEGIN CERTIFICATE----- MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJO TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFh dCBkZXIgTmVkZXJsYW5kZW4gRVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0y MjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIg TmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRlcmxhbmRlbiBFViBS b290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkkSzrS M4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nC UiY4iKTWO0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3d Z//BYY1jTw+bbRcwJu+r0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46p rfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13l pJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gVXJrm0w912fxBmJc+qiXb j5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr08C+eKxC KFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS /ZbV0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0X cgOPvZuM5l5Tnrmd74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH 1vI4gnPah1vlPNOePqc7nvQDs/nxfRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrP px9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB /zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwaivsnuL8wbqg7 MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u 2dfOWBfoqSmuc0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHS v4ilf0X8rLiltTMMgsT7B/Zq5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTC wPTxGfARKbalGAKb12NMcIxHowNDXLldRqANb/9Zjr7dn3LDWyvfjFvO5QxGbJKy CqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tNf1zuacpzEPuKqf2e vTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi5Dp6 Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIa Gl6I6lD4WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeL eG9QgkRQP2YGiqtDhFZKDyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8 FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGyeUN51q1veieQA6TqJIc/2b3Z6fJfUEkc 7uzXLg== -----END CERTIFICATE----- # Issuer: CN=IdenTrust Commercial Root CA 1 O=IdenTrust # Subject: CN=IdenTrust Commercial Root CA 1 O=IdenTrust # Label: "IdenTrust Commercial Root CA 1" # Serial: 13298821034946342390520003877796839426 # MD5 Fingerprint: b3:3e:77:73:75:ee:a0:d3:e3:7e:49:63:49:59:bb:c7 # SHA1 Fingerprint: df:71:7e:aa:4a:d9:4e:c9:55:84:99:60:2d:48:de:5f:bc:f0:3a:25 # SHA256 Fingerprint: 5d:56:49:9b:e4:d2:e0:8b:cf:ca:d0:8a:3e:38:72:3d:50:50:3b:de:70:69:48:e4:2f:55:60:30:19:e5:28:ae -----BEGIN CERTIFICATE----- MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBK MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVu VHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQw MTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScw JQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwggIiMA0GCSqG SIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ldhNlT 3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU +ehcCuz/mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gp S0l4PJNgiCL8mdo2yMKi1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1 bVoE/c40yiTcdCMbXTMTEl3EASX2MN0CXZ/g1Ue9tOsbobtJSdifWwLziuQkkORi T0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl3ZBWzvurpWCdxJ35UrCL vYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzyNeVJSQjK Vsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZK dHzVWYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHT c+XvvqDtMwt0viAgxGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hv l7yTmvmcEpB4eoCHFddydJxVdHixuuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5N iGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB /zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZIhvcNAQELBQAD ggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH 6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwt LRvM7Kqas6pgghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93 nAbowacYXVKV7cndJZ5t+qntozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3 +wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmVYjzlVYA211QC//G5Xc7UI2/YRYRK W2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUXfeu+h1sXIFRRk0pT AwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/rokTLq l1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG 4iZZRHUe2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZ mUlO+KWA2yUPHGNiiskzZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A 7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7RcGzM7vRX+Bi6hG6H -----END CERTIFICATE----- # Issuer: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust # Subject: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust # Label: "IdenTrust Public Sector Root CA 1" # Serial: 13298821034946342390521976156843933698 # MD5 Fingerprint: 37:06:a5:b0:fc:89:9d:ba:f4:6b:8c:1a:64:cd:d5:ba # SHA1 Fingerprint: ba:29:41:60:77:98:3f:f4:f3:ef:f2:31:05:3b:2e:ea:6d:4d:45:fd # SHA256 Fingerprint: 30:d0:89:5a:9a:44:8a:26:20:91:63:55:22:d1:f5:20:10:b5:86:7a:ca:e1:2c:78:ef:95:8f:d4:f4:38:9f:2f -----BEGIN CERTIFICATE----- MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBN MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVu VHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcN MzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0 MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwggIi MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTyP4o7 ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGy RBb06tD6Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlS bdsHyo+1W/CD80/HLaXIrcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF /YTLNiCBWS2ab21ISGHKTN9T0a9SvESfqy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R 3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoSmJxZZoY+rfGwyj4GD3vw EUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFnol57plzy 9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9V GxyhLrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ 2fjXctscvG29ZV/viDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsV WaFHVCkugyhfHMKiq3IXAAaOReyL4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gD W/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMwDQYJKoZIhvcN AQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHV DRDtfULAj+7AmgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9 TaDKQGXSc3z1i9kKlT/YPyNtGtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8G lwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFtm6/n6J91eEyrRjuazr8FGF1NFTwW mhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMxNRF4eKLg6TCMf4Df WN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4Mhn5 +bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJ tshquDDIajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhA GaQdp/lLQzfcaFpPz+vCZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv 8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ3Wl9af0AVqW3rLatt8o+Ae+c -----END CERTIFICATE----- # Issuer: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only # Subject: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only # Label: "Entrust Root Certification Authority - G2" # Serial: 1246989352 # MD5 Fingerprint: 4b:e2:c9:91:96:65:0c:f4:0e:5a:93:92:a0:0a:fe:b2 # SHA1 Fingerprint: 8c:f4:27:fd:79:0c:3a:d1:66:06:8d:e8:1e:57:ef:bb:93:22:72:d4 # SHA256 Fingerprint: 43:df:57:74:b0:3e:7f:ef:5f:e4:0d:93:1a:7b:ed:f1:bb:2e:6b:42:73:8c:4e:6d:38:41:10:3d:3a:a7:f3:39 -----BEGIN CERTIFICATE----- MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50 cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0 aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1 U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0 jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/ jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v 1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g== -----END CERTIFICATE----- # Issuer: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only # Subject: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only # Label: "Entrust Root Certification Authority - EC1" # Serial: 51543124481930649114116133369 # MD5 Fingerprint: b6:7e:1d:f0:58:c5:49:6c:24:3b:3d:ed:98:18:ed:bc # SHA1 Fingerprint: 20:d8:06:40:df:9b:25:f5:12:25:3a:11:ea:f7:59:8a:eb:14:b5:47 # SHA256 Fingerprint: 02:ed:0e:b2:8c:14:da:45:16:5c:56:67:91:70:0d:64:51:d7:fb:56:f0:b2:ab:1d:3b:8e:b0:70:e5:6e:df:f5 -----BEGIN CERTIFICATE----- MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3 d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0 L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G -----END CERTIFICATE----- # Issuer: CN=CFCA EV ROOT O=China Financial Certification Authority # Subject: CN=CFCA EV ROOT O=China Financial Certification Authority # Label: "CFCA EV ROOT" # Serial: 407555286 # MD5 Fingerprint: 74:e1:b6:ed:26:7a:7a:44:30:33:94:ab:7b:27:81:30 # SHA1 Fingerprint: e2:b8:29:4b:55:84:ab:6b:58:c2:90:46:6c:ac:3f:b8:39:8f:84:83 # SHA256 Fingerprint: 5c:c3:d7:8e:4e:1d:5e:45:54:7a:04:e6:87:3e:64:f9:0c:f9:53:6d:1c:cc:2e:f8:00:f3:55:c4:c5:fd:70:fd -----BEGIN CERTIFICATE----- MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJD TjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y aXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkx MjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5j aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJP T1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnVBU03 sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpL TIpTUnrD7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5 /ZOkVIBMUtRSqy5J35DNuF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp 7hZZLDRJGqgG16iI0gNyejLi6mhNbiyWZXvKWfry4t3uMCz7zEasxGPrb382KzRz EpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7xzbh72fROdOXW3NiGUgt hxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9fpy25IGvP a931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqot aK8KgWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNg TnYGmE69g60dWIolhdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfV PKPtl8MeNPo4+QgO48BdK4PRVmrJtqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hv cWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAfBgNVHSMEGDAWgBTj/i39KNAL tbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAd BgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObT ej/tUxPQ4i9qecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdL jOztUmCypAbqTuv0axn96/Ua4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBS ESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sGE5uPhnEFtC+NiWYzKXZUmhH4J/qy P5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfXBDrDMlI1Dlb4pd19 xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjnaH9d Ci77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN 5mydLIhyPDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe /v5WOaHIz16eGWRGENoXkbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+Z AAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3CekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ 5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su -----END CERTIFICATE----- # Issuer: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed # Subject: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed # Label: "OISTE WISeKey Global Root GB CA" # Serial: 157768595616588414422159278966750757568 # MD5 Fingerprint: a4:eb:b9:61:28:2e:b7:2f:98:b0:35:26:90:99:51:1d # SHA1 Fingerprint: 0f:f9:40:76:18:d3:d7:6a:4b:98:f0:a8:35:9e:0c:fd:27:ac:cc:ed # SHA256 Fingerprint: 6b:9c:08:e8:6e:b0:f7:67:cf:ad:65:cd:98:b6:21:49:e5:49:4a:67:f5:84:5e:7b:d1:ed:01:9f:27:b8:6b:d6 -----BEGIN CERTIFICATE----- MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBt MQswCQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUg Rm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9i YWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAwMzJaFw0zOTEyMDExNTEwMzFaMG0x CzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBG b3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh bCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3 HEokKtaXscriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGx WuR51jIjK+FTzJlFXHtPrby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX 1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNk u7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4oQnc/nSMbsrY9gBQHTC5P 99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvgGUpuuy9r M2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw AwEB/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUB BAMCAQAwDQYJKoZIhvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrgh cViXfa43FK8+5/ea4n32cZiZBKpDdHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5 gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0VQreUGdNZtGn//3ZwLWoo4rO ZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEuiHZeeevJuQHHf aPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM= -----END CERTIFICATE----- # Issuer: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A. # Subject: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A. # Label: "SZAFIR ROOT CA2" # Serial: 357043034767186914217277344587386743377558296292 # MD5 Fingerprint: 11:64:c1:89:b0:24:b1:8c:b1:07:7e:89:9e:51:9e:99 # SHA1 Fingerprint: e2:52:fa:95:3f:ed:db:24:60:bd:6e:28:f3:9c:cc:cf:5e:b3:3f:de # SHA256 Fingerprint: a1:33:9d:33:28:1a:0b:56:e5:57:d3:d3:2b:1c:e7:f9:36:7e:b0:94:bd:5f:a7:2a:7e:50:04:c8:de:d7:ca:fe -----BEGIN CERTIFICATE----- MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQEL BQAwUTELMAkGA1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6 ZW5pb3dhIFMuQS4xGDAWBgNVBAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkw NzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9L cmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYDVQQDDA9TWkFGSVIg Uk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5QqEvN QLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT 3PSQ1hNKDJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw 3gAeqDRHu5rr/gsUvTaE2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr6 3fE9biCloBK0TXC5ztdyO4mTp4CEHCdJckm1/zuVnsHMyAHs6A6KCpbns6aH5db5 BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwiieDhZNRnvDF5YTy7ykHN XGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD AgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsF AAOCAQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw 8PRBEew/R40/cof5O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOG nXkZ7/e7DDWQw4rtTw/1zBLZpD67oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCP oky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul4+vJhaAlIDf7js4MNIThPIGy d05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6+/NNIxuZMzSg LvWpCz/UXeHPhJ/iGcJfitYgHuNztw== -----END CERTIFICATE----- # Issuer: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority # Subject: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority # Label: "Certum Trusted Network CA 2" # Serial: 44979900017204383099463764357512596969 # MD5 Fingerprint: 6d:46:9e:d9:25:6d:08:23:5b:5e:74:7d:1e:27:db:f2 # SHA1 Fingerprint: d3:dd:48:3e:2b:bf:4c:05:e8:af:10:f5:fa:76:26:cf:d3:dc:30:92 # SHA256 Fingerprint: b6:76:f2:ed:da:e8:77:5c:d3:6c:b0:f6:3c:d1:d4:60:39:61:f4:9e:62:65:ba:01:3a:2f:03:07:b6:d0:b8:04 -----BEGIN CERTIFICATE----- MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCB gDELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIG A1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQSAyMCIYDzIwMTExMDA2MDgz OTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQTDEiMCAGA1UEChMZ VW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRp ZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3 b3JrIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWA DGSdhhuWZGc/IjoedQF97/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn 0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+oCgCXhVqqndwpyeI1B+twTUrWwbNWuKFB OJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40bRr5HMNUuctHFY9rnY3lE fktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2puTRZCr+E Sv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1m o130GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02i sx7QBlrd9pPPV3WZ9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOW OZV7bIBaTxNyxtd9KXpEulKkKtVBRgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgez Tv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pyehizKV/Ma5ciSixqClnrDvFAS adgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vMBhBgu4M1t15n 3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMC AQYwDQYJKoZIhvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQ F/xlhMcQSZDe28cmk4gmb3DWAl45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTf CVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuAL55MYIR4PSFk1vtBHxgP58l1cb29 XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMoclm2q8KMZiYcdywm djWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tMpkT/ WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jb AoJnwTnbw3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksq P/ujmv5zMnHCnsZy4YpoJ/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Ko b7a6bINDd82Kkhehnlt4Fj1F4jNy3eFmypnTycUm/Q1oBEauttmbjL4ZvrHG8hnj XALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLXis7VmFxWlgPF7ncGNf/P 5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7zAYspsbi DrW5viSP -----END CERTIFICATE----- # Issuer: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority # Subject: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority # Label: "Hellenic Academic and Research Institutions RootCA 2015" # Serial: 0 # MD5 Fingerprint: ca:ff:e2:db:03:d9:cb:4b:e9:0f:ad:84:fd:7b:18:ce # SHA1 Fingerprint: 01:0c:06:95:a6:98:19:14:ff:bf:5f:c6:b0:b6:95:ea:29:e9:12:a6 # SHA256 Fingerprint: a0:40:92:9a:02:ce:53:b4:ac:f4:f2:ff:c6:98:1c:e4:49:6f:75:5e:6d:45:fe:0b:2a:69:2b:cd:52:52:3f:36 -----BEGIN CERTIFICATE----- MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1Ix DzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5k IFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMT N0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9v dENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAxMTIxWjCBpjELMAkG A1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNh ZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkx QDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 dGlvbnMgUm9vdENBIDIwMTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC AQDC+Kk/G4n8PDwEXT2QNrCROnk8ZlrvbTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA 4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+ehiGsxr/CL0BgzuNtFajT0 AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+6PAQZe10 4S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06C ojXdFPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV 9Cz82XBST3i4vTwri5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrD gfgXy5I2XdGj2HUb4Ysn6npIQf1FGQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6 Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2fu/Z8VFRfS0myGlZYeCsargq NhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9muiNX6hME6wGko LfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNV HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVd ctA4GGqd83EkVAswDQYJKoZIhvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0I XtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+D1hYc2Ryx+hFjtyp8iY/xnmMsVMI M4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrMd/K4kPFox/la/vot 9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+yd+2V Z5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/ea j8GsGsVn82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnh X9izjFk0WaSrT2y7HxjbdavYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQ l033DlZdwJVqwjbDG2jJ9SrcR5q+ss7FJej6A7na+RZukYT1HCjI/CbM1xyQVqdf bzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVtJ94Cj8rDtSvK6evIIVM4 pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGaJI7ZjnHK e7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0 vm9qp/UsQu0yrbYhnr68 -----END CERTIFICATE----- # Issuer: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority # Subject: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority # Label: "Hellenic Academic and Research Institutions ECC RootCA 2015" # Serial: 0 # MD5 Fingerprint: 81:e5:b4:17:eb:c2:f5:e1:4b:0d:41:7b:49:92:fe:ef # SHA1 Fingerprint: 9f:f1:71:8d:92:d5:9a:f3:7d:74:97:b4:bc:6f:84:68:0b:ba:b6:66 # SHA256 Fingerprint: 44:b5:45:aa:8a:25:e6:5a:73:ca:15:dc:27:fc:36:d2:4c:1c:b9:95:3a:06:65:39:b1:15:82:dc:48:7b:48:33 -----BEGIN CERTIFICATE----- MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzAN BgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl c2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hl bGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgRUNDIFJv b3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEwMzcxMlowgaoxCzAJ BgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmljIEFj YWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5 MUQwQgYDVQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0 dXRpb25zIEVDQyBSb290Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKg QehLgoRc4vgxEZmGZE4JJS+dQS8KrjVPdJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJa jq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoKVlp8aQuqgAkkbH7BRqNC MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFLQi C4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaep lSTAGiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7Sof TUwJCA3sS61kFyjndc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR -----END CERTIFICATE----- # Issuer: CN=ISRG Root X1 O=Internet Security Research Group # Subject: CN=ISRG Root X1 O=Internet Security Research Group # Label: "ISRG Root X1" # Serial: 172886928669790476064670243504169061120 # MD5 Fingerprint: 0c:d2:f9:e0:da:17:73:e9:ed:86:4d:a5:e3:70:e7:4e # SHA1 Fingerprint: ca:bd:2a:79:a1:07:6a:31:f2:1d:25:36:35:cb:03:9d:43:29:a5:e8 # SHA256 Fingerprint: 96:bc:ec:06:26:49:76:f3:74:60:77:9a:cf:28:c5:a7:cf:e8:a3:c0:aa:e1:1a:8f:fc:ee:05:c0:bd:df:08:c6 -----BEGIN CERTIFICATE----- MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ 0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ 3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq 4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= -----END CERTIFICATE----- # Issuer: O=FNMT-RCM OU=AC RAIZ FNMT-RCM # Subject: O=FNMT-RCM OU=AC RAIZ FNMT-RCM # Label: "AC RAIZ FNMT-RCM" # Serial: 485876308206448804701554682760554759 # MD5 Fingerprint: e2:09:04:b4:d3:bd:d1:a0:14:fd:1a:d2:47:c4:57:1d # SHA1 Fingerprint: ec:50:35:07:b2:15:c4:95:62:19:e2:a8:9a:5b:42:99:2c:4c:2c:20 # SHA256 Fingerprint: eb:c5:57:0c:29:01:8c:4d:67:b1:aa:12:7b:af:12:f7:03:b4:61:1e:bc:17:b7:da:b5:57:38:94:17:9b:93:fa -----BEGIN CERTIFICATE----- MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsx CzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJ WiBGTk1ULVJDTTAeFw0wODEwMjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJ BgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBG Tk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALpxgHpMhm5/ yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcfqQgf BBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAz WHFctPVrbtQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxF tBDXaEAUwED653cXeuYLj2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z 374jNUUeAlz+taibmSXaXvMiwzn15Cou08YfxGyqxRxqAQVKL9LFwag0Jl1mpdIC IfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mwWsXmo8RZZUc1g16p6DUL mbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnTtOmlcYF7 wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peS MKGJ47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2 ZSysV4999AeU14ECll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMet UqIJ5G+GR4of6ygnXYMgrwTJbFaai0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUw AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFPd9xf3E6Jobd2Sn9R2gzL+H YJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1odHRwOi8vd3d3 LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1 RXxlDPiyN8+sD8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYM LVN0V2Ue1bLdI4E7pWYjJ2cJj+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf 77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrTQfv6MooqtyuGC2mDOL7Nii4LcK2N JpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW+YJF1DngoABd15jm fZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7Ixjp 6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp 1txyM/1d8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B 9kiABdcPUXmsEKvU7ANm5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wok RqEIr9baRRmW1FMdW4R58MD3R++Lj8UGrp1MYp3/RgT408m2ECVAdf4WqslKYIYv uu8wd+RU4riEmViAqhOLUTpPSPaLtrM= -----END CERTIFICATE----- # Issuer: CN=Amazon Root CA 1 O=Amazon # Subject: CN=Amazon Root CA 1 O=Amazon # Label: "Amazon Root CA 1" # Serial: 143266978916655856878034712317230054538369994 # MD5 Fingerprint: 43:c6:bf:ae:ec:fe:ad:2f:18:c6:88:68:30:fc:c8:e6 # SHA1 Fingerprint: 8d:a7:f9:65:ec:5e:fc:37:91:0f:1c:6e:59:fd:c1:cc:6a:6e:de:16 # SHA256 Fingerprint: 8e:cd:e6:88:4f:3d:87:b1:12:5b:a3:1a:c3:fc:b1:3d:70:16:de:7f:57:cc:90:4f:e1:cb:97:c6:ae:98:19:6e -----BEGIN CERTIFICATE----- MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM 9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6 VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L 93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU 5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy rqXRfboQnoZsG4q5WTP468SQvvG5 -----END CERTIFICATE----- # Issuer: CN=Amazon Root CA 2 O=Amazon # Subject: CN=Amazon Root CA 2 O=Amazon # Label: "Amazon Root CA 2" # Serial: 143266982885963551818349160658925006970653239 # MD5 Fingerprint: c8:e5:8d:ce:a8:42:e2:7a:c0:2a:5c:7c:9e:26:bf:66 # SHA1 Fingerprint: 5a:8c:ef:45:d7:a6:98:59:76:7a:8c:8b:44:96:b5:78:cf:47:4b:1a # SHA256 Fingerprint: 1b:a5:b2:aa:8c:65:40:1a:82:96:01:18:f8:0b:ec:4f:62:30:4d:83:ce:c4:71:3a:19:c3:9c:01:1e:a4:6d:b4 -----BEGIN CERTIFICATE----- MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 b24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv b3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2Wny2cSkxK gXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4kHbZ W0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg 1dKmSYXpN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K 8nu+NQWpEjTj82R0Yiw9AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r 2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvdfLC6HM783k81ds8P+HgfajZRRidhW+me z/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAExkv8LV/SasrlX6avvDXbR 8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSSbtqDT6Zj mUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz 7Mt0Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6 +XUyo05f7O0oYtlNc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI 0u1ufm8/0i2BWSlmy5A5lREedCf+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB Af8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSwDPBMMPQFWAJI/TPlUq9LhONm UjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oAA7CXDpO8Wqj2 LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY +gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kS k5Nrp+gvU5LEYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl 7uxMMne0nxrpS10gxdr9HIcWxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygm btmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQgj9sAq+uEjonljYE1x2igGOpm/Hl urR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbWaQbLU8uz/mtBzUF+ fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoVYh63 n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE 76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H 9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT 4PsJYGw= -----END CERTIFICATE----- # Issuer: CN=Amazon Root CA 3 O=Amazon # Subject: CN=Amazon Root CA 3 O=Amazon # Label: "Amazon Root CA 3" # Serial: 143266986699090766294700635381230934788665930 # MD5 Fingerprint: a0:d4:ef:0b:f7:b5:d8:49:95:2a:ec:f5:c4:fc:81:87 # SHA1 Fingerprint: 0d:44:dd:8c:3c:8c:1a:1a:58:75:64:81:e9:0f:2e:2a:ff:b3:d2:6e # SHA256 Fingerprint: 18:ce:6c:fe:7b:f1:4e:60:b2:e3:47:b8:df:e8:68:cb:31:d0:2e:bb:3a:da:27:15:69:f5:03:43:b4:6d:b3:a4 -----BEGIN CERTIFICATE----- MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5 MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM YyRIHN8wfdVoOw== -----END CERTIFICATE----- # Issuer: CN=Amazon Root CA 4 O=Amazon # Subject: CN=Amazon Root CA 4 O=Amazon # Label: "Amazon Root CA 4" # Serial: 143266989758080763974105200630763877849284878 # MD5 Fingerprint: 89:bc:27:d5:eb:17:8d:06:6a:69:d5:fd:89:47:b4:cd # SHA1 Fingerprint: f6:10:84:07:d6:f8:bb:67:98:0c:c2:e2:44:c2:eb:ae:1c:ef:63:be # SHA256 Fingerprint: e3:5d:28:41:9e:d0:20:25:cf:a6:90:38:cd:62:39:62:45:8d:a5:c6:95:fb:de:a3:c2:2b:0b:fb:25:89:70:92 -----BEGIN CERTIFICATE----- MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5 MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g Um9vdCBDQSA0MB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg Q0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN/sGKe0uoe0ZLY7Bi 9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri83Bk M6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB /zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WB MAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW 1KyLa2tJElMzrdfkviT8tQp21KW8EA== -----END CERTIFICATE----- # Issuer: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM # Subject: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM # Label: "TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1" # Serial: 1 # MD5 Fingerprint: dc:00:81:dc:69:2f:3e:2f:b0:3b:f6:3d:5a:91:8e:49 # SHA1 Fingerprint: 31:43:64:9b:ec:ce:27:ec:ed:3a:3f:0b:8f:0d:e4:e8:91:dd:ee:ca # SHA256 Fingerprint: 46:ed:c3:68:90:46:d5:3a:45:3f:b3:10:4a:b8:0d:ca:ec:65:8b:26:60:ea:16:29:dd:7e:86:79:90:64:87:16 -----BEGIN CERTIFICATE----- MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIx GDAWBgNVBAcTD0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxp bXNlbCB2ZSBUZWtub2xvamlrIEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0w KwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24gTWVya2V6aSAtIEthbXUgU00xNjA0 BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRpZmlrYXNpIC0gU3Vy dW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYDVQQG EwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXll IEJpbGltc2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklU QUsxLTArBgNVBAsTJEthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBT TTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11IFNNIFNTTCBLb2sgU2VydGlmaWthc2kg LSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr3UwM6q7 a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y86Ij5iySr LqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INr N3wcwv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2X YacQuFWQfw4tJzh03+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/ iSIzL+aFCr2lqBs23tPcLG07xxO9WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4f AJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQUZT/HiobGPN08VFw1+DrtUgxH V8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL BQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh AHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPf IPP54+M638yclNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4 lzwDGrpDxpa5RXI4s6ehlj2Re37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c 8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0jq5Rm+K37DwhuJi1/FwcJsoz7UMCf lo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM= -----END CERTIFICATE----- # Issuer: CN=GDCA TrustAUTH R5 ROOT O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD. # Subject: CN=GDCA TrustAUTH R5 ROOT O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD. # Label: "GDCA TrustAUTH R5 ROOT" # Serial: 9009899650740120186 # MD5 Fingerprint: 63:cc:d9:3d:34:35:5c:6f:53:a3:e2:08:70:48:1f:b4 # SHA1 Fingerprint: 0f:36:38:5b:81:1a:25:c3:9b:31:4e:83:ca:e9:34:66:70:cc:74:b4 # SHA256 Fingerprint: bf:ff:8f:d0:44:33:48:7d:6a:8a:a6:0c:1a:29:76:7a:9f:c2:bb:b0:5e:42:0f:71:3a:13:b9:92:89:1d:38:93 -----BEGIN CERTIFICATE----- MIIFiDCCA3CgAwIBAgIIfQmX/vBH6nowDQYJKoZIhvcNAQELBQAwYjELMAkGA1UE BhMCQ04xMjAwBgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZ IENPLixMVEQuMR8wHQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMB4XDTE0 MTEyNjA1MTMxNVoXDTQwMTIzMTE1NTk1OVowYjELMAkGA1UEBhMCQ04xMjAwBgNV BAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZIENPLixMVEQuMR8w HQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMIICIjANBgkqhkiG9w0BAQEF AAOCAg8AMIICCgKCAgEA2aMW8Mh0dHeb7zMNOwZ+Vfy1YI92hhJCfVZmPoiC7XJj Dp6L3TQsAlFRwxn9WVSEyfFrs0yw6ehGXTjGoqcuEVe6ghWinI9tsJlKCvLriXBj TnnEt1u9ol2x8kECK62pOqPseQrsXzrj/e+APK00mxqriCZ7VqKChh/rNYmDf1+u KU49tm7srsHwJ5uu4/Ts765/94Y9cnrrpftZTqfrlYwiOXnhLQiPzLyRuEH3FMEj qcOtmkVEs7LXLM3GKeJQEK5cy4KOFxg2fZfmiJqwTTQJ9Cy5WmYqsBebnh52nUpm MUHfP/vFBu8btn4aRjb3ZGM74zkYI+dndRTVdVeSN72+ahsmUPI2JgaQxXABZG12 ZuGR224HwGGALrIuL4xwp9E7PLOR5G62xDtw8mySlwnNR30YwPO7ng/Wi64HtloP zgsMR6flPri9fcebNaBhlzpBdRfMK5Z3KpIhHtmVdiBnaM8Nvd/WHwlqmuLMc3Gk L30SgLdTMEZeS1SZD2fJpcjyIMGC7J0R38IC+xo70e0gmu9lZJIQDSri3nDxGGeC jGHeuLzRL5z7D9Ar7Rt2ueQ5Vfj4oR24qoAATILnsn8JuLwwoC8N9VKejveSswoA HQBUlwbgsQfZxw9cZX08bVlX5O2ljelAU58VS6Bx9hoh49pwBiFYFIeFd3mqgnkC AwEAAaNCMEAwHQYDVR0OBBYEFOLJQJ9NzuiaoXzPDj9lxSmIahlRMA8GA1UdEwEB /wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQDRSVfg p8xoWLoBDysZzY2wYUWsEe1jUGn4H3++Fo/9nesLqjJHdtJnJO29fDMylyrHBYZm DRd9FBUb1Ov9H5r2XpdptxolpAqzkT9fNqyL7FeoPueBihhXOYV0GkLH6VsTX4/5 COmSdI31R9KrO9b7eGZONn356ZLpBN79SWP8bfsUcZNnL0dKt7n/HipzcEYwv1ry L3ml4Y0M2fmyYzeMN2WFcGpcWwlyua1jPLHd+PwyvzeG5LuOmCd+uh8W4XAR8gPf JWIyJyYYMoSf/wA6E7qaTfRPuBRwIrHKK5DOKcFw9C+df/KQHtZa37dG/OaG+svg IHZ6uqbL9XzeYqWxi+7egmaKTjowHz+Ay60nugxe19CxVsp3cbK1daFQqUBDF8Io 2c9Si1vIY9RCPqAzekYu9wogRlR+ak8x8YF+QnQ4ZXMn7sZ8uI7XpTrXmKGcjBBV 09tL7ECQ8s1uV9JiDnxXk7Gnbc2dg7sq5+W2O3FYrf3RRbxake5TFW/TRQl1brqQ XR4EzzffHqhmsYzmIGrv/EhOdJhCrylvLmrH+33RZjEizIYAfmaDDEL0vTSSwxrq T8p+ck0LcIymSLumoRT2+1hEmRSuqguTaaApJUqlyyvdimYHFngVV3Eb7PVHhPOe MTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g== -----END CERTIFICATE----- # Issuer: CN=TrustCor RootCert CA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority # Subject: CN=TrustCor RootCert CA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority # Label: "TrustCor RootCert CA-1" # Serial: 15752444095811006489 # MD5 Fingerprint: 6e:85:f1:dc:1a:00:d3:22:d5:b2:b2:ac:6b:37:05:45 # SHA1 Fingerprint: ff:bd:cd:e7:82:c8:43:5e:3c:6f:26:86:5c:ca:a8:3a:45:5b:c3:0a # SHA256 Fingerprint: d4:0e:9c:86:cd:8f:e4:68:c1:77:69:59:f4:9e:a7:74:fa:54:86:84:b6:c4:06:f3:90:92:61:f4:dc:e2:57:5c -----BEGIN CERTIFICATE----- MIIEMDCCAxigAwIBAgIJANqb7HHzA7AZMA0GCSqGSIb3DQEBCwUAMIGkMQswCQYD VQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEk MCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRydXN0Q29y IFJvb3RDZXJ0IENBLTEwHhcNMTYwMjA0MTIzMjE2WhcNMjkxMjMxMTcyMzE2WjCB pDELMAkGA1UEBhMCUEExDzANBgNVBAgMBlBhbmFtYTEUMBIGA1UEBwwLUGFuYW1h IENpdHkxJDAiBgNVBAoMG1RydXN0Q29yIFN5c3RlbXMgUy4gZGUgUi5MLjEnMCUG A1UECwweVHJ1c3RDb3IgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MR8wHQYDVQQDDBZU cnVzdENvciBSb290Q2VydCBDQS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB CgKCAQEAv463leLCJhJrMxnHQFgKq1mqjQCj/IDHUHuO1CAmujIS2CNUSSUQIpid RtLByZ5OGy4sDjjzGiVoHKZaBeYei0i/mJZ0PmnK6bV4pQa81QBeCQryJ3pS/C3V seq0iWEk8xoT26nPUu0MJLq5nux+AHT6k61sKZKuUbS701e/s/OojZz0JEsq1pme 9J7+wH5COucLlVPat2gOkEz7cD+PSiyU8ybdY2mplNgQTsVHCJCZGxdNuWxu72CV EY4hgLW9oHPY0LJ3xEXqWib7ZnZ2+AYfYW0PVcWDtxBWcgYHpfOxGgMFZA6dWorW hnAbJN7+KIor0Gqw/Hqi3LJ5DotlDwIDAQABo2MwYTAdBgNVHQ4EFgQU7mtJPHo/ DeOxCbeKyKsZn3MzUOcwHwYDVR0jBBgwFoAU7mtJPHo/DeOxCbeKyKsZn3MzUOcw DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQAD ggEBACUY1JGPE+6PHh0RU9otRCkZoB5rMZ5NDp6tPVxBb5UrJKF5mDo4Nvu7Zp5I /5CQ7z3UuJu0h3U/IJvOcs+hVcFNZKIZBqEHMwwLKeXx6quj7LUKdJDHfXLy11yf ke+Ri7fc7Waiz45mO7yfOgLgJ90WmMCV1Aqk5IGadZQ1nJBfiDcGrVmVCrDRZ9MZ yonnMlo2HD6CqFqTvsbQZJG2z9m2GM/bftJlo6bEjhcxwft+dtvTheNYsnd6djts L1Ac59v2Z3kf9YKVmgenFK+P3CghZwnS1k1aHBkcjndcw5QkPTJrS37UeJSDvjdN zl/HHk484IkzlQsPpTLWPFp5LBk= -----END CERTIFICATE----- # Issuer: CN=TrustCor RootCert CA-2 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority # Subject: CN=TrustCor RootCert CA-2 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority # Label: "TrustCor RootCert CA-2" # Serial: 2711694510199101698 # MD5 Fingerprint: a2:e1:f8:18:0b:ba:45:d5:c7:41:2a:bb:37:52:45:64 # SHA1 Fingerprint: b8:be:6d:cb:56:f1:55:b9:63:d4:12:ca:4e:06:34:c7:94:b2:1c:c0 # SHA256 Fingerprint: 07:53:e9:40:37:8c:1b:d5:e3:83:6e:39:5d:ae:a5:cb:83:9e:50:46:f1:bd:0e:ae:19:51:cf:10:fe:c7:c9:65 -----BEGIN CERTIFICATE----- MIIGLzCCBBegAwIBAgIIJaHfyjPLWQIwDQYJKoZIhvcNAQELBQAwgaQxCzAJBgNV BAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQw IgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRy dXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0eTEfMB0GA1UEAwwWVHJ1c3RDb3Ig Um9vdENlcnQgQ0EtMjAeFw0xNjAyMDQxMjMyMjNaFw0zNDEyMzExNzI2MzlaMIGk MQswCQYDVQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEg Q2l0eTEkMCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYD VQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRy dXN0Q29yIFJvb3RDZXJ0IENBLTIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK AoICAQCnIG7CKqJiJJWQdsg4foDSq8GbZQWU9MEKENUCrO2fk8eHyLAnK0IMPQo+ QVqedd2NyuCb7GgypGmSaIwLgQ5WoD4a3SwlFIIvl9NkRvRUqdw6VC0xK5mC8tkq 1+9xALgxpL56JAfDQiDyitSSBBtlVkxs1Pu2YVpHI7TYabS3OtB0PAx1oYxOdqHp 2yqlO/rOsP9+aij9JxzIsekp8VduZLTQwRVtDr4uDkbIXvRR/u8OYzo7cbrPb1nK DOObXUm4TOJXsZiKQlecdu/vvdFoqNL0Cbt3Nb4lggjEFixEIFapRBF37120Hape az6LMvYHL1cEksr1/p3C6eizjkxLAjHZ5DxIgif3GIJ2SDpxsROhOdUuxTTCHWKF 3wP+TfSvPd9cW436cOGlfifHhi5qjxLGhF5DUVCcGZt45vz27Ud+ez1m7xMTiF88 oWP7+ayHNZ/zgp6kPwqcMWmLmaSISo5uZk3vFsQPeSghYA2FFn3XVDjxklb9tTNM g9zXEJ9L/cb4Qr26fHMC4P99zVvh1Kxhe1fVSntb1IVYJ12/+CtgrKAmrhQhJ8Z3 mjOAPF5GP/fDsaOGM8boXg25NSyqRsGFAnWAoOsk+xWq5Gd/bnc/9ASKL3x74xdh 8N0JqSDIvgmk0H5Ew7IwSjiqqewYmgeCK9u4nBit2uBGF6zPXQIDAQABo2MwYTAd BgNVHQ4EFgQU2f4hQG6UnrybPZx9mCAZ5YwwYrIwHwYDVR0jBBgwFoAU2f4hQG6U nrybPZx9mCAZ5YwwYrIwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYw DQYJKoZIhvcNAQELBQADggIBAJ5Fngw7tu/hOsh80QA9z+LqBrWyOrsGS2h60COX dKcs8AjYeVrXWoSK2BKaG9l9XE1wxaX5q+WjiYndAfrs3fnpkpfbsEZC89NiqpX+ MWcUaViQCqoL7jcjx1BRtPV+nuN79+TMQjItSQzL/0kMmx40/W5ulop5A7Zv2wnL /V9lFDfhOPXzYRZY5LVtDQsEGz9QLX+zx3oaFoBg+Iof6Rsqxvm6ARppv9JYx1RX CI/hOWB3S6xZhBqI8d3LT3jX5+EzLfzuQfogsL7L9ziUwOHQhQ+77Sxzq+3+knYa ZH9bDTMJBzN7Bj8RpFxwPIXAz+OQqIN3+tvmxYxoZxBnpVIt8MSZj3+/0WvitUfW 2dCFmU2Umw9Lje4AWkcdEQOsQRivh7dvDDqPys/cA8GiCcjl/YBeyGBCARsaU1q7 N6a3vLqE6R5sGtRk2tRD/pOLS/IseRYQ1JMLiI+h2IYURpFHmygk71dSTlxCnKr3 Sewn6EAes6aJInKc9Q0ztFijMDvd1GpUk74aTfOTlPf8hAs/hCBcNANExdqtvArB As8e5ZTZ845b2EzwnexhF7sUMlQMAimTHpKG9n/v55IFDlndmQguLvqcAFLTxWYp 5KeXRKQOKIETNcX2b2TmQcTVL8w0RSXPQQCWPUouwpaYT05KnJe32x+SMsj/D1Fu 1uwJ -----END CERTIFICATE----- # Issuer: CN=TrustCor ECA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority # Subject: CN=TrustCor ECA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority # Label: "TrustCor ECA-1" # Serial: 9548242946988625984 # MD5 Fingerprint: 27:92:23:1d:0a:f5:40:7c:e9:e6:6b:9d:d8:f5:e7:6c # SHA1 Fingerprint: 58:d1:df:95:95:67:6b:63:c0:f0:5b:1c:17:4d:8b:84:0b:c8:78:bd # SHA256 Fingerprint: 5a:88:5d:b1:9c:01:d9:12:c5:75:93:88:93:8c:af:bb:df:03:1a:b2:d4:8e:91:ee:15:58:9b:42:97:1d:03:9c -----BEGIN CERTIFICATE----- MIIEIDCCAwigAwIBAgIJAISCLF8cYtBAMA0GCSqGSIb3DQEBCwUAMIGcMQswCQYD VQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEk MCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxFzAVBgNVBAMMDlRydXN0Q29y IEVDQS0xMB4XDTE2MDIwNDEyMzIzM1oXDTI5MTIzMTE3MjgwN1owgZwxCzAJBgNV BAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQw IgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRy dXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0eTEXMBUGA1UEAwwOVHJ1c3RDb3Ig RUNBLTEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPj+ARtZ+odnbb 3w9U73NjKYKtR8aja+3+XzP4Q1HpGjORMRegdMTUpwHmspI+ap3tDvl0mEDTPwOA BoJA6LHip1GnHYMma6ve+heRK9jGrB6xnhkB1Zem6g23xFUfJ3zSCNV2HykVh0A5 3ThFEXXQmqc04L/NyFIduUd+Dbi7xgz2c1cWWn5DkR9VOsZtRASqnKmcp0yJF4Ou owReUoCLHhIlERnXDH19MURB6tuvsBzvgdAsxZohmz3tQjtQJvLsznFhBmIhVE5/ wZ0+fyCMgMsq2JdiyIMzkX2woloPV+g7zPIlstR8L+xNxqE6FXrntl019fZISjZF ZtS6mFjBAgMBAAGjYzBhMB0GA1UdDgQWBBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAf BgNVHSMEGDAWgBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAPBgNVHRMBAf8EBTADAQH/ MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAQEABT41XBVwm8nHc2Fv civUwo/yQ10CzsSUuZQRg2dd4mdsdXa/uwyqNsatR5Nj3B5+1t4u/ukZMjgDfxT2 AHMsWbEhBuH7rBiVDKP/mZb3Kyeb1STMHd3BOuCYRLDE5D53sXOpZCz2HAF8P11F hcCF5yWPldwX8zyfGm6wyuMdKulMY/okYWLW2n62HGz1Ah3UKt1VkOsqEUc8Ll50 soIipX1TH0XsJ5F95yIW6MBoNtjG8U+ARDL54dHRHareqKucBK+tIA5kmE2la8BI WJZpTdwHjFGTot+fDz2LYLSCjaoITmJF4PkL0uDgPFveXHEnJcLmA4GLEFPjx1Wi tJ/X5g== -----END CERTIFICATE----- # Issuer: CN=SSL.com Root Certification Authority RSA O=SSL Corporation # Subject: CN=SSL.com Root Certification Authority RSA O=SSL Corporation # Label: "SSL.com Root Certification Authority RSA" # Serial: 8875640296558310041 # MD5 Fingerprint: 86:69:12:c0:70:f1:ec:ac:ac:c2:d5:bc:a5:5b:a1:29 # SHA1 Fingerprint: b7:ab:33:08:d1:ea:44:77:ba:14:80:12:5a:6f:bd:a9:36:49:0c:bb # SHA256 Fingerprint: 85:66:6a:56:2e:e0:be:5c:e9:25:c1:d8:89:0a:6f:76:a8:7e:c1:6d:4d:7d:5f:29:ea:74:19:cf:20:12:3b:69 -----BEGIN CERTIFICATE----- MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE BhMCVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQK DA9TU0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZp Y2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYwMjEyMTczOTM5WhcNNDEwMjEyMTcz OTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcN AQEBBQADggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2R xFdHaxh3a3by/ZPkPQ/CFp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aX qhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcC C52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/geoeOy3ZExqysdBP+lSgQ3 6YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkpk8zruFvh /l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrF YD3ZfBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93E JNyAKoFBbZQ+yODJgUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVc US4cK38acijnALXRdMbX5J+tB5O2UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8 ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi81xtZPCvM8hnIk2snYxnP/Okm +Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4sbE6x/c+cCbqi M+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4G A1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGV cpNxJK1ok1iOMq8bs3AD/CUrdIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBc Hadm47GUBwwyOabqG7B52B2ccETjit3E+ZUfijhDPwGFpUenPUayvOUiaPd7nNgs PgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAslu1OJD7OAUN5F7kR/ q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjqerQ0 cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jr a6x+3uxjMxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90I H37hVZkLId6Tngr75qNJvTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/Y K9f1JmzJBjSWFupwWRoyeXkLtoh/D1JIPb9s2KJELtFOt3JY04kTlf5Eq/jXixtu nLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406ywKBjYZC6VWg3dGq2ktuf oYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NIWuuA8ShY Ic2wBlX7Jz9TkHCpBB5XJ7k= -----END CERTIFICATE----- # Issuer: CN=SSL.com Root Certification Authority ECC O=SSL Corporation # Subject: CN=SSL.com Root Certification Authority ECC O=SSL Corporation # Label: "SSL.com Root Certification Authority ECC" # Serial: 8495723813297216424 # MD5 Fingerprint: 2e:da:e4:39:7f:9c:8f:37:d1:70:9f:26:17:51:3a:8e # SHA1 Fingerprint: c3:19:7c:39:24:e6:54:af:1b:c4:ab:20:95:7a:e2:c3:0e:13:02:6a # SHA256 Fingerprint: 34:17:bb:06:cc:60:07:da:1b:96:1c:92:0b:8a:b4:ce:3f:ad:82:0e:4a:a3:0b:9a:cb:c4:a7:4e:bd:ce:bc:65 -----BEGIN CERTIFICATE----- MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMC VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T U0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0 aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNDAzWhcNNDEwMjEyMTgxNDAz WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0 b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNvbSBS b290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB BAAiA2IABEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI 7Z4INcgn64mMU1jrYor+8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPg CemB+vNH06NjMGEwHQYDVR0OBBYEFILRhXMw5zUE044CkvvlpNHEIejNMA8GA1Ud EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTTjgKS++Wk0cQh6M0wDgYD VR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCWe+0F+S8T kdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+ gA0z5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl -----END CERTIFICATE----- # Issuer: CN=SSL.com EV Root Certification Authority RSA R2 O=SSL Corporation # Subject: CN=SSL.com EV Root Certification Authority RSA R2 O=SSL Corporation # Label: "SSL.com EV Root Certification Authority RSA R2" # Serial: 6248227494352943350 # MD5 Fingerprint: e1:1e:31:58:1a:ae:54:53:02:f6:17:6a:11:7b:4d:95 # SHA1 Fingerprint: 74:3a:f0:52:9b:d0:32:a0:f4:4a:83:cd:d4:ba:a9:7b:7c:2e:c4:9a # SHA256 Fingerprint: 2e:7b:f1:6c:c2:24:85:a7:bb:e2:aa:86:96:75:07:61:b0:ae:39:be:3b:2f:e9:d0:cc:6d:4e:f7:34:91:42:5c -----BEGIN CERTIFICATE----- MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNV BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UE CgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2Vy dGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMB4XDTE3MDUzMTE4MTQzN1oXDTQy MDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4G A1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQD DC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvq M0fNTPl9fb69LT3w23jhhqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssuf OePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7wcXHswxzpY6IXFJ3vG2fThVUCAtZJycxa 4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTOZw+oz12WGQvE43LrrdF9 HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+B6KjBSYR aZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcA b9ZhCBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQ Gp8hLH94t2S42Oim9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQV PWKchjgGAGYS5Fl2WlPAApiiECtoRHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMO pgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+SlmJuwgUHfbSguPvuUCYHBBXtSu UDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48+qvWBkofZ6aY MBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV HSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa4 9QaAJadz20ZpqJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBW s47LCp1Jjr+kxJG7ZhcFUZh1++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5 Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nxY/hoLVUE0fKNsKTPvDxeH3jnpaAg cLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2GguDKBAdRUNf/ktUM 79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDzOFSz /bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXt ll9ldDz7CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEm Kf7GUmG6sXP/wwyc5WxqlD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKK QbNmC1r7fSOl8hqw/96bg5Qu0T/fkreRrwU7ZcegbLHNYhLDkBvjJc40vG93drEQ w/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1hlMYegouCRw2n5H9gooi S9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX9hwJ1C07 mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w== -----END CERTIFICATE----- # Issuer: CN=SSL.com EV Root Certification Authority ECC O=SSL Corporation # Subject: CN=SSL.com EV Root Certification Authority ECC O=SSL Corporation # Label: "SSL.com EV Root Certification Authority ECC" # Serial: 3182246526754555285 # MD5 Fingerprint: 59:53:22:65:83:42:01:54:c0:ce:42:b9:5a:7c:f2:90 # SHA1 Fingerprint: 4c:dd:51:a3:d1:f5:20:32:14:b0:c6:c5:32:23:03:91:c7:46:42:6d # SHA256 Fingerprint: 22:a2:c1:f7:bd:ed:70:4c:c1:e7:01:b5:f4:08:c3:10:88:0f:e9:56:b5:de:2a:4a:44:f9:9c:87:3a:25:a7:c8 -----BEGIN CERTIFICATE----- MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMC VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T U0wgQ29ycG9yYXRpb24xNDAyBgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZp Y2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNTIzWhcNNDEwMjEyMTgx NTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NMLmNv bSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49 AgEGBSuBBAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMA VIbc/R/fALhBYlzccBYy3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1Kthku WnBaBu2+8KGwytAJKaNjMGEwHQYDVR0OBBYEFFvKXuXe0oGqzagtZFG22XKbl+ZP MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe5d7SgarNqC1kUbbZcpuX 5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJN+vp1RPZ ytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZg h5Mmm7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg== -----END CERTIFICATE----- # Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R6 # Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R6 # Label: "GlobalSign Root CA - R6" # Serial: 1417766617973444989252670301619537 # MD5 Fingerprint: 4f:dd:07:e4:d4:22:64:39:1e:0c:37:42:ea:d1:c6:ae # SHA1 Fingerprint: 80:94:64:0e:b5:a7:a1:ca:11:9c:1f:dd:d5:9f:81:02:63:a7:fb:d1 # SHA256 Fingerprint: 2c:ab:ea:fe:37:d0:6c:a2:2a:ba:73:91:c0:03:3d:25:98:29:52:c4:53:64:73:49:76:3a:3a:b5:ad:6c:cf:69 -----BEGIN CERTIFICATE----- MIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEg MB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2Jh bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTQxMjEwMDAwMDAwWhcNMzQx MjEwMDAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSNjET MBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCAiIwDQYJ KoZIhvcNAQEBBQADggIPADCCAgoCggIBAJUH6HPKZvnsFMp7PPcNCPG0RQssgrRI xutbPK6DuEGSMxSkb3/pKszGsIhrxbaJ0cay/xTOURQh7ErdG1rG1ofuTToVBu1k ZguSgMpE3nOUTvOniX9PeGMIyBJQbUJmL025eShNUhqKGoC3GYEOfsSKvGRMIRxD aNc9PIrFsmbVkJq3MQbFvuJtMgamHvm566qjuL++gmNQ0PAYid/kD3n16qIfKtJw LnvnvJO7bVPiSHyMEAc4/2ayd2F+4OqMPKq0pPbzlUoSB239jLKJz9CgYXfIWHSw 1CM69106yqLbnQneXUQtkPGBzVeS+n68UARjNN9rkxi+azayOeSsJDa38O+2HBNX k7besvjihbdzorg1qkXy4J02oW9UivFyVm4uiMVRQkQVlO6jxTiWm05OWgtH8wY2 SXcwvHE35absIQh1/OZhFj931dmRl4QKbNQCTXTAFO39OfuD8l4UoQSwC+n+7o/h bguyCLNhZglqsQY6ZZZZwPA1/cnaKI0aEYdwgQqomnUdnjqGBQCe24DWJfncBZ4n WUx2OVvq+aWh2IMP0f/fMBH5hc8zSPXKbWQULHpYT9NLCEnFlWQaYw55PfWzjMpY rZxCRXluDocZXFSxZba/jJvcE+kNb7gu3GduyYsRtYQUigAZcIN5kZeR1Bonvzce MgfYFGM8KEyvAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTAD AQH/MB0GA1UdDgQWBBSubAWjkxPioufi1xzWx/B/yGdToDAfBgNVHSMEGDAWgBSu bAWjkxPioufi1xzWx/B/yGdToDANBgkqhkiG9w0BAQwFAAOCAgEAgyXt6NH9lVLN nsAEoJFp5lzQhN7craJP6Ed41mWYqVuoPId8AorRbrcWc+ZfwFSY1XS+wc3iEZGt Ixg93eFyRJa0lV7Ae46ZeBZDE1ZXs6KzO7V33EByrKPrmzU+sQghoefEQzd5Mr61 55wsTLxDKZmOMNOsIeDjHfrYBzN2VAAiKrlNIC5waNrlU/yDXNOd8v9EDERm8tLj vUYAGm0CuiVdjaExUd1URhxN25mW7xocBFymFe944Hn+Xds+qkxV/ZoVqW/hpvvf cDDpw+5CRu3CkwWJ+n1jez/QcYF8AOiYrg54NMMl+68KnyBr3TsTjxKM4kEaSHpz oHdpx7Zcf4LIHv5YGygrqGytXm3ABdJ7t+uA/iU3/gKbaKxCXcPu9czc8FB10jZp nOZ7BN9uBmm23goJSFmH63sUYHpkqmlD75HHTOwY3WzvUy2MmeFe8nI+z1TIvWfs pA9MRf/TuTAjB0yPEL+GltmZWrSZVxykzLsViVO6LAUP5MSeGbEYNNVMnbrt9x+v JJUEeKgDu+6B5dpffItKoZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R 8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+tJDfLRVpOoERIyNiwmcUVhAn21klJwGW4 5hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA= -----END CERTIFICATE----- # Issuer: CN=OISTE WISeKey Global Root GC CA O=WISeKey OU=OISTE Foundation Endorsed # Subject: CN=OISTE WISeKey Global Root GC CA O=WISeKey OU=OISTE Foundation Endorsed # Label: "OISTE WISeKey Global Root GC CA" # Serial: 44084345621038548146064804565436152554 # MD5 Fingerprint: a9:d6:b9:2d:2f:93:64:f8:a5:69:ca:91:e9:68:07:23 # SHA1 Fingerprint: e0:11:84:5e:34:de:be:88:81:b9:9c:f6:16:26:d1:96:1f:c3:b9:31 # SHA256 Fingerprint: 85:60:f9:1c:36:24:da:ba:95:70:b5:fe:a0:db:e3:6f:f1:1a:83:23:be:94:86:85:4f:b3:f3:4a:55:71:19:8d -----BEGIN CERTIFICATE----- MIICaTCCAe+gAwIBAgIQISpWDK7aDKtARb8roi066jAKBggqhkjOPQQDAzBtMQsw CQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91 bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwg Um9vdCBHQyBDQTAeFw0xNzA1MDkwOTQ4MzRaFw00MjA1MDkwOTU4MzNaMG0xCzAJ BgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBGb3Vu ZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2JhbCBS b290IEdDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAETOlQwMYPchi82PG6s4ni eUqjFqdrVCTbUf/q9Akkwwsin8tqJ4KBDdLArzHkdIJuyiXZjHWd8dvQmqJLIX4W p2OQ0jnUsYd4XxiWD1AbNTcPasbc2RNNpI6QN+a9WzGRo1QwUjAOBgNVHQ8BAf8E BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUSIcUrOPDnpBgOtfKie7T rYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0EAwMDaAAwZQIwJsdpW9zV 57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtkAjEA2zQg Mgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9 -----END CERTIFICATE----- # Issuer: CN=GTS Root R1 O=Google Trust Services LLC # Subject: CN=GTS Root R1 O=Google Trust Services LLC # Label: "GTS Root R1" # Serial: 146587175971765017618439757810265552097 # MD5 Fingerprint: 82:1a:ef:d4:d2:4a:f2:9f:e2:3d:97:06:14:70:72:85 # SHA1 Fingerprint: e1:c9:50:e6:ef:22:f8:4c:56:45:72:8b:92:20:60:d7:d5:a7:a3:e8 # SHA256 Fingerprint: 2a:57:54:71:e3:13:40:bc:21:58:1c:bd:2c:f1:3e:15:84:63:20:3e:ce:94:bc:f9:d3:cc:19:6b:f0:9a:54:72 -----BEGIN CERTIFICATE----- MIIFWjCCA0KgAwIBAgIQbkepxUtHDA3sM9CJuRz04TANBgkqhkiG9w0BAQwFADBH MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEB AQUAA4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaM f/vo27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vX mX7wCl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7 zUjwTcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0P fyblqAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtc vfaHszVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4 Zor8Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUsp zBmkMiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOO Rc92wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYW k70paDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+ DVrNVjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgF lQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV HQ4EFgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBADiW Cu49tJYeX++dnAsznyvgyv3SjgofQXSlfKqE1OXyHuY3UjKcC9FhHb8owbZEKTV1 d5iyfNm9dKyKaOOpMQkpAWBz40d8U6iQSifvS9efk+eCNs6aaAyC58/UEBZvXw6Z XPYfcX3v73svfuo21pdwCxXu11xWajOl40k4DLh9+42FpLFZXvRq4d2h9mREruZR gyFmxhE+885H7pwoHyXa/6xmld01D1zvICxi/ZG6qcz8WpyTgYMpl0p8WnK0OdC3 d8t5/Wk6kjftbjhlRn7pYL15iJdfOBL07q9bgsiG1eGZbYwE8na6SfZu6W0eX6Dv J4J2QPim01hcDyxC2kLGe4g0x8HYRZvBPsVhHdljUEn2NIVq4BjFbkerQUIpm/Zg DdIx02OYI5NaAIFItO/Nis3Jz5nu2Z6qNuFoS3FJFDYoOj0dzpqPJeaAcWErtXvM +SUWgeExX6GjfhaknBZqlxi9dnKlC54dNuYvoS++cJEPqOba+MSSQGwlfnuzCdyy F62ARPBopY+Udf90WuioAnwMCeKpSwughQtiue+hMZL77/ZRBIls6Kl0obsXs7X9 SQ98POyDGCBDTtWTurQ0sR8WNh8M5mQ5Fkzc4P4dyKliPUDqysU0ArSuiYgzNdws E3PYJ/HQcu51OyLemGhmW/HGY0dVHLqlCFF1pkgl -----END CERTIFICATE----- # Issuer: CN=GTS Root R2 O=Google Trust Services LLC # Subject: CN=GTS Root R2 O=Google Trust Services LLC # Label: "GTS Root R2" # Serial: 146587176055767053814479386953112547951 # MD5 Fingerprint: 44:ed:9a:0e:a4:09:3b:00:f2:ae:4c:a3:c6:61:b0:8b # SHA1 Fingerprint: d2:73:96:2a:2a:5e:39:9f:73:3f:e1:c7:1e:64:3f:03:38:34:fc:4d # SHA256 Fingerprint: c4:5d:7b:b0:8e:6d:67:e6:2e:42:35:11:0b:56:4e:5f:78:fd:92:ef:05:8c:84:0a:ea:4e:64:55:d7:58:5c:60 -----BEGIN CERTIFICATE----- MIIFWjCCA0KgAwIBAgIQbkepxlqz5yDFMJo/aFLybzANBgkqhkiG9w0BAQwFADBH MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEB AQUAA4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3Lv CvptnfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3Kg GjSY6Dlo7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9Bu XvAuMC6C/Pq8tBcKSOWIm8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOd re7kRXuJVfeKH2JShBKzwkCX44ofR5GmdFrS+LFjKBC4swm4VndAoiaYecb+3yXu PuWgf9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7MkogwTZq9TwtImoS1 mKPV+3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJGr61K 8YzodDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqj x5RWIr9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsR nTKaG73VululycslaVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0 kzCqgc7dGtxRcw1PcOnlthYhGXmy5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9Ok twIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV HQ4EFgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQADggIBALZp 8KZ3/p7uC4Gt4cCpx/k1HUCCq+YEtN/L9x0Pg/B+E02NjO7jMyLDOfxA325BS0JT vhaI8dI4XsRomRyYUpOM52jtG2pzegVATX9lO9ZY8c6DR2Dj/5epnGB3GFW1fgiT z9D2PGcDFWEJ+YF59exTpJ/JjwGLc8R3dtyDovUMSRqodt6Sm2T4syzFJ9MHwAiA pJiS4wGWAqoC7o87xdFtCjMwc3i5T1QWvwsHoaRc5svJXISPD+AVdyx+Jn7axEvb pxZ3B7DNdehyQtaVhJ2Gg/LkkM0JR9SLA3DaWsYDQvTtN6LwG1BUSw7YhN4ZKJmB R64JGz9I0cNv4rBgF/XuIwKl2gBbbZCr7qLpGzvpx0QnRY5rn/WkhLx3+WuXrD5R RaIRpsyF7gpo8j5QOHokYh4XIDdtak23CZvJ/KRY9bb7nE4Yu5UC56GtmwfuNmsk 0jmGwZODUNKBRqhfYlcsu2xkiAhu7xNUX90txGdj08+JN7+dIPT7eoOboB6BAFDC 5AwiWVIQ7UNWhwD4FFKnHYuTjKJNRn8nxnGbJN7k2oaLDX5rIMHAnuFl2GqjpuiF izoHCBy69Y9Vmhh1fuXsgWbRIXOhNUQLgD1bnF5vKheW0YMjiGZt5obicDIvUiLn yOd/xCxgXS/Dr55FBcOEArf9LAhST4Ldo/DUhgkC -----END CERTIFICATE----- # Issuer: CN=GTS Root R3 O=Google Trust Services LLC # Subject: CN=GTS Root R3 O=Google Trust Services LLC # Label: "GTS Root R3" # Serial: 146587176140553309517047991083707763997 # MD5 Fingerprint: 1a:79:5b:6b:04:52:9c:5d:c7:74:33:1b:25:9a:f9:25 # SHA1 Fingerprint: 30:d4:24:6f:07:ff:db:91:89:8a:0b:e9:49:66:11:eb:8c:5e:46:e5 # SHA256 Fingerprint: 15:d5:b8:77:46:19:ea:7d:54:ce:1c:a6:d0:b0:c4:03:e0:37:a9:17:f1:31:e8:a0:4e:1e:6b:7a:71:ba:bc:e5 -----BEGIN CERTIFICATE----- MIICDDCCAZGgAwIBAgIQbkepx2ypcyRAiQ8DVd2NHTAKBggqhkjOPQQDAzBHMQsw CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU MBIGA1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQA IgNiAAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout 736GjOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2A DDL24CejQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud DgQWBBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEAgFuk fCPAlaUs3L6JbyO5o91lAFJekazInXJ0glMLfalAvWhgxeG4VDvBNhcl2MG9AjEA njWSdIUlUfUk7GRSJFClH9voy8l27OyCbvWFGFPouOOaKaqW04MjyaR7YbPMAuhd -----END CERTIFICATE----- # Issuer: CN=GTS Root R4 O=Google Trust Services LLC # Subject: CN=GTS Root R4 O=Google Trust Services LLC # Label: "GTS Root R4" # Serial: 146587176229350439916519468929765261721 # MD5 Fingerprint: 5d:b6:6a:c4:60:17:24:6a:1a:99:a8:4b:ee:5e:b4:26 # SHA1 Fingerprint: 2a:1d:60:27:d9:4a:b1:0a:1c:4d:91:5c:cd:33:a0:cb:3e:2d:54:cb # SHA256 Fingerprint: 71:cc:a5:39:1f:9e:79:4b:04:80:25:30:b3:63:e1:21:da:8a:30:43:bb:26:66:2f:ea:4d:ca:7f:c9:51:a4:bd -----BEGIN CERTIFICATE----- MIICCjCCAZGgAwIBAgIQbkepyIuUtui7OyrYorLBmTAKBggqhkjOPQQDAzBHMQsw CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU MBIGA1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQA IgNiAATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzu hXyiQHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/l xKvRHYqjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud DgQWBBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNnADBkAjBqUFJ0 CMRw3J5QdCHojXohw0+WbhXRIjVhLfoIN+4Zba3bssx9BzT1YBkstTTZbyACMANx sbqjYAuG7ZoIapVon+Kz4ZNkfF6Tpt95LY2F45TPI11xzPKwTdb+mciUqXWi4w== -----END CERTIFICATE----- # Issuer: CN=UCA Global G2 Root O=UniTrust # Subject: CN=UCA Global G2 Root O=UniTrust # Label: "UCA Global G2 Root" # Serial: 124779693093741543919145257850076631279 # MD5 Fingerprint: 80:fe:f0:c4:4a:f0:5c:62:32:9f:1c:ba:78:a9:50:f8 # SHA1 Fingerprint: 28:f9:78:16:19:7a:ff:18:25:18:aa:44:fe:c1:a0:ce:5c:b6:4c:8a # SHA256 Fingerprint: 9b:ea:11:c9:76:fe:01:47:64:c1:be:56:a6:f9:14:b5:a5:60:31:7a:bd:99:88:39:33:82:e5:16:1a:a0:49:3c -----BEGIN CERTIFICATE----- MIIFRjCCAy6gAwIBAgIQXd+x2lqj7V2+WmUgZQOQ7zANBgkqhkiG9w0BAQsFADA9 MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxGzAZBgNVBAMMElVDQSBH bG9iYWwgRzIgUm9vdDAeFw0xNjAzMTEwMDAwMDBaFw00MDEyMzEwMDAwMDBaMD0x CzAJBgNVBAYTAkNOMREwDwYDVQQKDAhVbmlUcnVzdDEbMBkGA1UEAwwSVUNBIEds b2JhbCBHMiBSb290MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxeYr b3zvJgUno4Ek2m/LAfmZmqkywiKHYUGRO8vDaBsGxUypK8FnFyIdK+35KYmToni9 kmugow2ifsqTs6bRjDXVdfkX9s9FxeV67HeToI8jrg4aA3++1NDtLnurRiNb/yzm VHqUwCoV8MmNsHo7JOHXaOIxPAYzRrZUEaalLyJUKlgNAQLx+hVRZ2zA+te2G3/R VogvGjqNO7uCEeBHANBSh6v7hn4PJGtAnTRnvI3HLYZveT6OqTwXS3+wmeOwcWDc C/Vkw85DvG1xudLeJ1uK6NjGruFZfc8oLTW4lVYa8bJYS7cSN8h8s+1LgOGN+jIj tm+3SJUIsUROhYw6AlQgL9+/V087OpAh18EmNVQg7Mc/R+zvWr9LesGtOxdQXGLY D0tK3Cv6brxzks3sx1DoQZbXqX5t2Okdj4q1uViSukqSKwxW/YDrCPBeKW4bHAyv j5OJrdu9o54hyokZ7N+1wxrrFv54NkzWbtA+FxyQF2smuvt6L78RHBgOLXMDj6Dl NaBa4kx1HXHhOThTeEDMg5PXCp6dW4+K5OXgSORIskfNTip1KnvyIvbJvgmRlld6 iIis7nCs+dwp4wwcOxJORNanTrAmyPPZGpeRaOrvjUYG0lZFWJo8DA+DuAUlwznP O6Q0ibd5Ei9Hxeepl2n8pndntd978XplFeRhVmUCAwEAAaNCMEAwDgYDVR0PAQH/ BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFIHEjMz15DD/pQwIX4wV ZyF0Ad/fMA0GCSqGSIb3DQEBCwUAA4ICAQATZSL1jiutROTL/7lo5sOASD0Ee/oj L3rtNtqyzm325p7lX1iPyzcyochltq44PTUbPrw7tgTQvPlJ9Zv3hcU2tsu8+Mg5 1eRfB70VVJd0ysrtT7q6ZHafgbiERUlMjW+i67HM0cOU2kTC5uLqGOiiHycFutfl 1qnN3e92mI0ADs0b+gO3joBYDic/UvuUospeZcnWhNq5NXHzJsBPd+aBJ9J3O5oU b3n09tDh05S60FdRvScFDcH9yBIw7m+NESsIndTUv4BFFJqIRNow6rSn4+7vW4LV PtateJLbXDzz2K36uGt/xDYotgIVilQsnLAXc47QN6MUPJiVAAwpBVueSUmxX8fj y88nZY41F7dXyDDZQVu5FLbowg+UMaeUmMxq67XhJ/UQqAHojhJi6IjMtX9Gl8Cb EGY4GjZGXyJoPd/JxhMnq1MGrKI8hgZlb7F+sSlEmqO6SWkoaY/X5V+tBIZkbxqg DMUIYs6Ao9Dz7GjevjPHF1t/gMRMTLGmhIrDO7gJzRSBuhjjVFc2/tsvfEehOjPI +Vg7RE+xygKJBJYoaMVLuCaJu9YzL1DV/pqJuhgyklTGW+Cd+V7lDSKb9triyCGy YiGqhkCyLmTTX8jjfhFnRR8F/uOi77Oos/N9j/gMHyIfLXC0uAE0djAA5SN4p1bX UB+K+wb1whnw0A== -----END CERTIFICATE----- # Issuer: CN=UCA Extended Validation Root O=UniTrust # Subject: CN=UCA Extended Validation Root O=UniTrust # Label: "UCA Extended Validation Root" # Serial: 106100277556486529736699587978573607008 # MD5 Fingerprint: a1:f3:5f:43:c6:34:9b:da:bf:8c:7e:05:53:ad:96:e2 # SHA1 Fingerprint: a3:a1:b0:6f:24:61:23:4a:e3:36:a5:c2:37:fc:a6:ff:dd:f0:d7:3a # SHA256 Fingerprint: d4:3a:f9:b3:54:73:75:5c:96:84:fc:06:d7:d8:cb:70:ee:5c:28:e7:73:fb:29:4e:b4:1e:e7:17:22:92:4d:24 -----BEGIN CERTIFICATE----- MIIFWjCCA0KgAwIBAgIQT9Irj/VkyDOeTzRYZiNwYDANBgkqhkiG9w0BAQsFADBH MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBF eHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwHhcNMTUwMzEzMDAwMDAwWhcNMzgxMjMx MDAwMDAwWjBHMQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNV BAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwggIiMA0GCSqGSIb3DQEB AQUAA4ICDwAwggIKAoICAQCpCQcoEwKwmeBkqh5DFnpzsZGgdT6o+uM4AHrsiWog D4vFsJszA1qGxliG1cGFu0/GnEBNyr7uaZa4rYEwmnySBesFK5pI0Lh2PpbIILvS sPGP2KxFRv+qZ2C0d35qHzwaUnoEPQc8hQ2E0B92CvdqFN9y4zR8V05WAT558aop O2z6+I9tTcg1367r3CTueUWnhbYFiN6IXSV8l2RnCdm/WhUFhvMJHuxYMjMR83dk sHYf5BA1FxvyDrFspCqjc/wJHx4yGVMR59mzLC52LqGj3n5qiAno8geK+LLNEOfi c0CTuwjRP+H8C5SzJe98ptfRr5//lpr1kXuYC3fUfugH0mK1lTnj8/FtDw5lhIpj VMWAtuCeS31HJqcBCF3RiJ7XwzJE+oJKCmhUfzhTA8ykADNkUVkLo4KRel7sFsLz KuZi2irbWWIQJUoqgQtHB0MGcIfS+pMRKXpITeuUx3BNr2fVUbGAIAEBtHoIppB/ TuDvB0GHr2qlXov7z1CymlSvw4m6WC31MJixNnI5fkkE/SmnTHnkBVfblLkWU41G sx2VYVdWf6/wFlthWG82UBEL2KwrlRYaDh8IzTY0ZRBiZtWAXxQgXy0MoHgKaNYs 1+lvK9JKBZP8nm9rZ/+I8U6laUpSNwXqxhaN0sSZ0YIrO7o1dfdRUVjzyAfd5LQD fwIDAQABo0IwQDAdBgNVHQ4EFgQU2XQ65DA9DfcS3H5aBZ8eNJr34RQwDwYDVR0T AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBADaN l8xCFWQpN5smLNb7rhVpLGsaGvdftvkHTFnq88nIua7Mui563MD1sC3AO6+fcAUR ap8lTwEpcOPlDOHqWnzcSbvBHiqB9RZLcpHIojG5qtr8nR/zXUACE/xOHAbKsxSQ VBcZEhrxH9cMaVr2cXj0lH2RC47skFSOvG+hTKv8dGT9cZr4QQehzZHkPJrgmzI5 c6sq1WnIeJEmMX3ixzDx/BR4dxIOE/TdFpS/S2d7cFOFyrC78zhNLJA5wA3CXWvp 4uXViI3WLL+rG761KIcSF3Ru/H38j9CHJrAb+7lsq+KePRXBOy5nAliRn+/4Qh8s t2j1da3Ptfb/EX3C8CSlrdP6oDyp+l3cpaDvRKS+1ujl5BOWF3sGPjLtx7dCvHaj 2GU4Kzg1USEODm8uNBNA4StnDG1KQTAYI1oyVZnJF+A83vbsea0rWBmirSwiGpWO vpaQXUJXxPkUAzUrHC1RVwinOt4/5Mi0A3PCwSaAuwtCH60NryZy2sy+s6ODWA2C xR9GUeOcGMyNm43sSet1UNWMKFnKdDTajAshqx7qG+XH/RU+wBeq+yNuJkbL+vmx cmtpzyKEC2IPrNkZAJSidjzULZrtBJ4tBmIQN1IchXIbJ+XMxjHsN+xjWZsLHXbM fjKaiJUINlK73nZfdklJrX+9ZSCyycErdhh2n1ax -----END CERTIFICATE----- # Issuer: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036 # Subject: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036 # Label: "Certigna Root CA" # Serial: 269714418870597844693661054334862075617 # MD5 Fingerprint: 0e:5c:30:62:27:eb:5b:bc:d7:ae:62:ba:e9:d5:df:77 # SHA1 Fingerprint: 2d:0d:52:14:ff:9e:ad:99:24:01:74:20:47:6e:6c:85:27:27:f5:43 # SHA256 Fingerprint: d4:8d:3d:23:ee:db:50:a4:59:e5:51:97:60:1c:27:77:4b:9d:7b:18:c9:4d:5a:05:95:11:a1:02:50:b9:31:68 -----BEGIN CERTIFICATE----- MIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAw WjELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAw MiA0ODE0NjMwODEwMDAzNjEZMBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0x MzEwMDEwODMyMjdaFw0zMzEwMDEwODMyMjdaMFoxCzAJBgNVBAYTAkZSMRIwEAYD VQQKDAlEaGlteW90aXMxHDAaBgNVBAsMEzAwMDIgNDgxNDYzMDgxMDAwMzYxGTAX BgNVBAMMEENlcnRpZ25hIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw ggIKAoICAQDNGDllGlmx6mQWDoyUJJV8g9PFOSbcDO8WV43X2KyjQn+Cyu3NW9sO ty3tRQgXstmzy9YXUnIo245Onoq2C/mehJpNdt4iKVzSs9IGPjA5qXSjklYcoW9M CiBtnyN6tMbaLOQdLNyzKNAT8kxOAkmhVECe5uUFoC2EyP+YbNDrihqECB63aCPu I9Vwzm1RaRDuoXrC0SIxwoKF0vJVdlB8JXrJhFwLrN1CTivngqIkicuQstDuI7pm TLtipPlTWmR7fJj6o0ieD5Wupxj0auwuA0Wv8HT4Ks16XdG+RCYyKfHx9WzMfgIh C59vpD++nVPiz32pLHxYGpfhPTc3GGYo0kDFUYqMwy3OU4gkWGQwFsWq4NYKpkDf ePb1BHxpE4S80dGnBs8B92jAqFe7OmGtBIyT46388NtEbVncSVmurJqZNjBBe3Yz IoejwpKGbvlw7q6Hh5UbxHq9MfPU0uWZ/75I7HX1eBYdpnDBfzwboZL7z8g81sWT Co/1VTp2lc5ZmIoJlXcymoO6LAQ6l73UL77XbJuiyn1tJslV1c/DeVIICZkHJC1k JWumIWmbat10TWuXekG9qxf5kBdIjzb5LdXF2+6qhUVB+s06RbFo5jZMm5BX7CO5 hwjCxAnxl4YqKE3idMDaxIzb3+KhF1nOJFl0Mdp//TBt2dzhauH8XwIDAQABo4IB GjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE FBiHVuBud+4kNTxOc5of1uHieX4rMB8GA1UdIwQYMBaAFBiHVuBud+4kNTxOc5of 1uHieX4rMEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwczov L3d3d3cuY2VydGlnbmEuZnIvYXV0b3JpdGVzLzBtBgNVHR8EZjBkMC+gLaArhilo dHRwOi8vY3JsLmNlcnRpZ25hLmZyL2NlcnRpZ25hcm9vdGNhLmNybDAxoC+gLYYr aHR0cDovL2NybC5kaGlteW90aXMuY29tL2NlcnRpZ25hcm9vdGNhLmNybDANBgkq hkiG9w0BAQsFAAOCAgEAlLieT/DjlQgi581oQfccVdV8AOItOoldaDgvUSILSo3L 6btdPrtcPbEo/uRTVRPPoZAbAh1fZkYJMyjhDSSXcNMQH+pkV5a7XdrnxIxPTGRG HVyH41neQtGbqH6mid2PHMkwgu07nM3A6RngatgCdTer9zQoKJHyBApPNeNgJgH6 0BGM+RFq7q89w1DTj18zeTyGqHNFkIwgtnJzFyO+B2XleJINugHA64wcZr+shncB lA2c5uk5jR+mUYyZDDl34bSb+hxnV29qao6pK0xXeXpXIs/NX2NGjVxZOob4Mkdi o2cNGJHc+6Zr9UhhcyNZjgKnvETq9Emd8VRY+WCv2hikLyhF3HqgiIZd8zvn/yk1 gPxkQ5Tm4xxvvq0OKmOZK8l+hfZx6AYDlf7ej0gcWtSS6Cvu5zHbugRqh5jnxV/v faci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaYtlu3zM63 Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayh jWZSaX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw 3kAP+HwV96LOPNdeE4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0= -----END CERTIFICATE----- # Issuer: CN=emSign Root CA - G1 O=eMudhra Technologies Limited OU=emSign PKI # Subject: CN=emSign Root CA - G1 O=eMudhra Technologies Limited OU=emSign PKI # Label: "emSign Root CA - G1" # Serial: 235931866688319308814040 # MD5 Fingerprint: 9c:42:84:57:dd:cb:0b:a7:2e:95:ad:b6:f3:da:bc:ac # SHA1 Fingerprint: 8a:c7:ad:8f:73:ac:4e:c1:b5:75:4d:a5:40:f4:fc:cf:7c:b5:8e:8c # SHA256 Fingerprint: 40:f6:af:03:46:a9:9a:a1:cd:1d:55:5a:4e:9c:ce:62:c7:f9:63:46:03:ee:40:66:15:83:3d:c8:c8:d0:03:67 -----BEGIN CERTIFICATE----- MIIDlDCCAnygAwIBAgIKMfXkYgxsWO3W2DANBgkqhkiG9w0BAQsFADBnMQswCQYD VQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBU ZWNobm9sb2dpZXMgTGltaXRlZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBH MTAeFw0xODAyMTgxODMwMDBaFw00MzAyMTgxODMwMDBaMGcxCzAJBgNVBAYTAklO MRMwEQYDVQQLEwplbVNpZ24gUEtJMSUwIwYDVQQKExxlTXVkaHJhIFRlY2hub2xv Z2llcyBMaW1pdGVkMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEcxMIIBIjAN BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk0u76WaK7p1b1TST0Bsew+eeuGQz f2N4aLTNLnF115sgxk0pvLZoYIr3IZpWNVrzdr3YzZr/k1ZLpVkGoZM0Kd0WNHVO 8oG0x5ZOrRkVUkr+PHB1cM2vK6sVmjM8qrOLqs1D/fXqcP/tzxE7lM5OMhbTI0Aq d7OvPAEsbO2ZLIvZTmmYsvePQbAyeGHWDV/D+qJAkh1cF+ZwPjXnorfCYuKrpDhM tTk1b+oDafo6VGiFbdbyL0NVHpENDtjVaqSW0RM8LHhQ6DqS0hdW5TUaQBw+jSzt Od9C4INBdN+jzcKGYEho42kLVACL5HZpIQ15TjQIXhTCzLG3rdd8cIrHhQIDAQAB o0IwQDAdBgNVHQ4EFgQU++8Nhp6w492pufEhF38+/PB3KxowDgYDVR0PAQH/BAQD AgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFn/8oz1h31x PaOfG1vR2vjTnGs2vZupYeveFix0PZ7mddrXuqe8QhfnPZHr5X3dPpzxz5KsbEjM wiI/aTvFthUvozXGaCocV685743QNcMYDHsAVhzNixl03r4PEuDQqqE/AjSxcM6d GNYIAwlG7mDgfrbESQRRfXBgvKqy/3lyeqYdPV8q+Mri/Tm3R7nrft8EI6/6nAYH 6ftjk4BAtcZsCjEozgyfz7MjNYBBjWzEN3uBL4ChQEKF6dk4jeihU80Bv2noWgby RQuQ+q7hv53yrlc8pa6yVvSLZUDp/TGBLPQ5Cdjua6e0ph0VpZj3AYHYhX3zUVxx iN66zB+Afko= -----END CERTIFICATE----- # Issuer: CN=emSign ECC Root CA - G3 O=eMudhra Technologies Limited OU=emSign PKI # Subject: CN=emSign ECC Root CA - G3 O=eMudhra Technologies Limited OU=emSign PKI # Label: "emSign ECC Root CA - G3" # Serial: 287880440101571086945156 # MD5 Fingerprint: ce:0b:72:d1:9f:88:8e:d0:50:03:e8:e3:b8:8b:67:40 # SHA1 Fingerprint: 30:43:fa:4f:f2:57:dc:a0:c3:80:ee:2e:58:ea:78:b2:3f:e6:bb:c1 # SHA256 Fingerprint: 86:a1:ec:ba:08:9c:4a:8d:3b:be:27:34:c6:12:ba:34:1d:81:3e:04:3c:f9:e8:a8:62:cd:5c:57:a3:6b:be:6b -----BEGIN CERTIFICATE----- MIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQG EwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNo bm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0g RzMwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4MTgzMDAwWjBrMQswCQYDVQQGEwJJ TjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9s b2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMw djAQBgcqhkjOPQIBBgUrgQQAIgNiAAQjpQy4LRL1KPOxst3iAhKAnjlfSU2fySU0 WXTsuwYc58Byr+iuL+FBVIcUqEqy6HyC5ltqtdyzdc6LBtCGI79G1Y4PPwT01xyS fvalY8L1X44uT6EYGQIrMgqCZH0Wk9GjQjBAMB0GA1UdDgQWBBR8XQKEE9TMipuB zhccLikenEhjQjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggq hkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+DCBeQyh+KTOgNG3qxrdWB CUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7jHvrZQnD +JbNR6iC8hZVdyR+EhCVBCyj -----END CERTIFICATE----- # Issuer: CN=emSign Root CA - C1 O=eMudhra Inc OU=emSign PKI # Subject: CN=emSign Root CA - C1 O=eMudhra Inc OU=emSign PKI # Label: "emSign Root CA - C1" # Serial: 825510296613316004955058 # MD5 Fingerprint: d8:e3:5d:01:21:fa:78:5a:b0:df:ba:d2:ee:2a:5f:68 # SHA1 Fingerprint: e7:2e:f1:df:fc:b2:09:28:cf:5d:d4:d5:67:37:b1:51:cb:86:4f:01 # SHA256 Fingerprint: 12:56:09:aa:30:1d:a0:a2:49:b9:7a:82:39:cb:6a:34:21:6f:44:dc:ac:9f:39:54:b1:42:92:f2:e8:c8:60:8f -----BEGIN CERTIFICATE----- MIIDczCCAlugAwIBAgILAK7PALrEzzL4Q7IwDQYJKoZIhvcNAQELBQAwVjELMAkG A1UEBhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEg SW5jMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEMxMB4XDTE4MDIxODE4MzAw MFoXDTQzMDIxODE4MzAwMFowVjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMRwwGgYDVQQDExNlbVNpZ24gUm9v dCBDQSAtIEMxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz+upufGZ BczYKCFK83M0UYRWEPWgTywS4/oTmifQz/l5GnRfHXk5/Fv4cI7gklL35CX5VIPZ HdPIWoU/Xse2B+4+wM6ar6xWQio5JXDWv7V7Nq2s9nPczdcdioOl+yuQFTdrHCZH 3DspVpNqs8FqOp099cGXOFgFixwR4+S0uF2FHYP+eF8LRWgYSKVGczQ7/g/IdrvH GPMF0Ybzhe3nudkyrVWIzqa2kbBPrH4VI5b2P/AgNBbeCsbEBEV5f6f9vtKppa+c xSMq9zwhbL2vj07FOrLzNBL834AaSaTUqZX3noleoomslMuoaJuvimUnzYnu3Yy1 aylwQ6BpC+S5DwIDAQABo0IwQDAdBgNVHQ4EFgQU/qHgcB4qAzlSWkK+XJGFehiq TbUwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL BQADggEBAMJKVvoVIXsoounlHfv4LcQ5lkFMOycsxGwYFYDGrK9HWS8mC+M2sO87 /kOXSTKZEhVb3xEp/6tT+LvBeA+snFOvV71ojD1pM/CjoCNjO2RnIkSt1XHLVip4 kqNPEjE2NuLe/gDEo2APJ62gsIq1NnpSob0n9CAnYuhNlCQT5AoE6TyrLshDCUrG YQTlSTR+08TI9Q/Aqum6VF7zYytPT1DU/rl7mYw9wC68AivTxEDkigcxHpvOJpkT +xHqmiIMERnHXhuBUDDIlhJu58tBf5E7oke3VIAb3ADMmpDqw8NQBmIMMMAVSKeo WXzhriKi4gp6D/piq1JM4fHfyr6DDUI= -----END CERTIFICATE----- # Issuer: CN=emSign ECC Root CA - C3 O=eMudhra Inc OU=emSign PKI # Subject: CN=emSign ECC Root CA - C3 O=eMudhra Inc OU=emSign PKI # Label: "emSign ECC Root CA - C3" # Serial: 582948710642506000014504 # MD5 Fingerprint: 3e:53:b3:a3:81:ee:d7:10:f8:d3:b0:1d:17:92:f5:d5 # SHA1 Fingerprint: b6:af:43:c2:9b:81:53:7d:f6:ef:6b:c3:1f:1f:60:15:0c:ee:48:66 # SHA256 Fingerprint: bc:4d:80:9b:15:18:9d:78:db:3e:1d:8c:f4:f9:72:6a:79:5d:a1:64:3c:a5:f1:35:8e:1d:db:0e:dc:0d:7e:b3 -----BEGIN CERTIFICATE----- MIICKzCCAbGgAwIBAgIKe3G2gla4EnycqDAKBggqhkjOPQQDAzBaMQswCQYDVQQG EwJVUzETMBEGA1UECxMKZW1TaWduIFBLSTEUMBIGA1UEChMLZU11ZGhyYSBJbmMx IDAeBgNVBAMTF2VtU2lnbiBFQ0MgUm9vdCBDQSAtIEMzMB4XDTE4MDIxODE4MzAw MFoXDTQzMDIxODE4MzAwMFowWjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln biBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMSAwHgYDVQQDExdlbVNpZ24gRUND IFJvb3QgQ0EgLSBDMzB2MBAGByqGSM49AgEGBSuBBAAiA2IABP2lYa57JhAd6bci MK4G9IGzsUJxlTm801Ljr6/58pc1kjZGDoeVjbk5Wum739D+yAdBPLtVb4Ojavti sIGJAnB9SMVK4+kiVCJNk7tCDK93nCOmfddhEc5lx/h//vXyqaNCMEAwHQYDVR0O BBYEFPtaSNCAIEDyqOkAB2kZd6fmw/TPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB Af8EBTADAQH/MAoGCCqGSM49BAMDA2gAMGUCMQC02C8Cif22TGK6Q04ThHK1rt0c 3ta13FaPWEBaLd4gTCKDypOofu4SQMfWh0/434UCMBwUZOR8loMRnLDRWmFLpg9J 0wD8ofzkpf9/rdcw0Md3f76BB1UwUCAU9Vc4CqgxUQ== -----END CERTIFICATE----- # Issuer: CN=Hongkong Post Root CA 3 O=Hongkong Post # Subject: CN=Hongkong Post Root CA 3 O=Hongkong Post # Label: "Hongkong Post Root CA 3" # Serial: 46170865288971385588281144162979347873371282084 # MD5 Fingerprint: 11:fc:9f:bd:73:30:02:8a:fd:3f:f3:58:b9:cb:20:f0 # SHA1 Fingerprint: 58:a2:d0:ec:20:52:81:5b:c1:f3:f8:64:02:24:4e:c2:8e:02:4b:02 # SHA256 Fingerprint: 5a:2f:c0:3f:0c:83:b0:90:bb:fa:40:60:4b:09:88:44:6c:76:36:18:3d:f9:84:6e:17:10:1a:44:7f:b8:ef:d6 -----BEGIN CERTIFICATE----- MIIFzzCCA7egAwIBAgIUCBZfikyl7ADJk0DfxMauI7gcWqQwDQYJKoZIhvcNAQEL BQAwbzELMAkGA1UEBhMCSEsxEjAQBgNVBAgTCUhvbmcgS29uZzESMBAGA1UEBxMJ SG9uZyBLb25nMRYwFAYDVQQKEw1Ib25na29uZyBQb3N0MSAwHgYDVQQDExdIb25n a29uZyBQb3N0IFJvb3QgQ0EgMzAeFw0xNzA2MDMwMjI5NDZaFw00MjA2MDMwMjI5 NDZaMG8xCzAJBgNVBAYTAkhLMRIwEAYDVQQIEwlIb25nIEtvbmcxEjAQBgNVBAcT CUhvbmcgS29uZzEWMBQGA1UEChMNSG9uZ2tvbmcgUG9zdDEgMB4GA1UEAxMXSG9u Z2tvbmcgUG9zdCBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK AoICAQCziNfqzg8gTr7m1gNt7ln8wlffKWihgw4+aMdoWJwcYEuJQwy51BWy7sFO dem1p+/l6TWZ5Mwc50tfjTMwIDNT2aa71T4Tjukfh0mtUC1Qyhi+AViiE3CWu4mI VoBc+L0sPOFMV4i707mV78vH9toxdCim5lSJ9UExyuUmGs2C4HDaOym71QP1mbpV 9WTRYA6ziUm4ii8F0oRFKHyPaFASePwLtVPLwpgchKOesL4jpNrcyCse2m5FHomY 2vkALgbpDDtw1VAliJnLzXNg99X/NWfFobxeq81KuEXryGgeDQ0URhLj0mRiikKY vLTGCAj4/ahMZJx2Ab0vqWwzD9g/KLg8aQFChn5pwckGyuV6RmXpwtZQQS4/t+Tt bNe/JgERohYpSms0BpDsE9K2+2p20jzt8NYt3eEV7KObLyzJPivkaTv/ciWxNoZb x39ri1UbSsUgYT2uy1DhCDq+sI9jQVMwCFk8mB13umOResoQUGC/8Ne8lYePl8X+ l2oBlKN8W4UdKjk60FSh0Tlxnf0h+bV78OLgAo9uliQlLKAeLKjEiafv7ZkGL7YK TE/bosw3Gq9HhS2KX8Q0NEwA/RiTZxPRN+ZItIsGxVd7GYYKecsAyVKvQv83j+Gj Hno9UKtjBucVtT+2RTeUN7F+8kjDf8V1/peNRY8apxpyKBpADwIDAQABo2MwYTAP BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBQXnc0e i9Y5K3DTXNSguB+wAPzFYTAdBgNVHQ4EFgQUF53NHovWOStw01zUoLgfsAD8xWEw DQYJKoZIhvcNAQELBQADggIBAFbVe27mIgHSQpsY1Q7XZiNc4/6gx5LS6ZStS6LG 7BJ8dNVI0lkUmcDrudHr9EgwW62nV3OZqdPlt9EuWSRY3GguLmLYauRwCy0gUCCk MpXRAJi70/33MvJJrsZ64Ee+bs7Lo3I6LWldy8joRTnU+kLBEUx3XZL7av9YROXr gZ6voJmtvqkBZss4HTzfQx/0TW60uhdG/H39h4F5ag0zD/ov+BS5gLNdTaqX4fnk GMX41TiMJjz98iji7lpJiCzfeT2OnpA8vUFKOt1b9pq0zj8lMH8yfaIDlNDceqFS 3m6TjRgm/VWsvY+b0s+v54Ysyx8Jb6NvqYTUc79NoXQbTiNg8swOqn+knEwlqLJm Ozj/2ZQw9nKEvmhVEA/GcywWaZMH/rFF7buiVWqw2rVKAiUnhde3t4ZEFolsgCs+ l6mc1X5VTMbeRRAc6uk7nwNT7u56AQIWeNTowr5GdogTPyK7SBIdUgC0An4hGh6c JfTzPV4e0hz5sy229zdcxsshTrD3mUcYhcErulWuBurQB7Lcq9CClnXO0lD+mefP L5/ndtFhKvshuzHQqp9HpLIiyhY6UFfEW0NnxWViA0kB60PZ2Pierc+xYw5F9KBa LJstxabArahH9CdMOA0uG0k7UvToiIMrVCjU8jVStDKDYmlkDJGcn5fqdBb9HxEG mpv0 -----END CERTIFICATE----- # Issuer: CN=Entrust Root Certification Authority - G4 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2015 Entrust, Inc. - for authorized use only # Subject: CN=Entrust Root Certification Authority - G4 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2015 Entrust, Inc. - for authorized use only # Label: "Entrust Root Certification Authority - G4" # Serial: 289383649854506086828220374796556676440 # MD5 Fingerprint: 89:53:f1:83:23:b7:7c:8e:05:f1:8c:71:38:4e:1f:88 # SHA1 Fingerprint: 14:88:4e:86:26:37:b0:26:af:59:62:5c:40:77:ec:35:29:ba:96:01 # SHA256 Fingerprint: db:35:17:d1:f6:73:2a:2d:5a:b9:7c:53:3e:c7:07:79:ee:32:70:a6:2f:b4:ac:42:38:37:24:60:e6:f0:1e:88 -----BEGIN CERTIFICATE----- MIIGSzCCBDOgAwIBAgIRANm1Q3+vqTkPAAAAAFVlrVgwDQYJKoZIhvcNAQELBQAw gb4xCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQL Ex9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykg MjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAw BgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0 MB4XDTE1MDUyNzExMTExNloXDTM3MTIyNzExNDExNlowgb4xCzAJBgNVBAYTAlVT MRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1 c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJ bmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3Qg Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0MIICIjANBgkqhkiG9w0B AQEFAAOCAg8AMIICCgKCAgEAsewsQu7i0TD/pZJH4i3DumSXbcr3DbVZwbPLqGgZ 2K+EbTBwXX7zLtJTmeH+H17ZSK9dE43b/2MzTdMAArzE+NEGCJR5WIoV3imz/f3E T+iq4qA7ec2/a0My3dl0ELn39GjUu9CH1apLiipvKgS1sqbHoHrmSKvS0VnM1n4j 5pds8ELl3FFLFUHtSUrJ3hCX1nbB76W1NhSXNdh4IjVS70O92yfbYVaCNNzLiGAM C1rlLAHGVK/XqsEQe9IFWrhAnoanw5CGAlZSCXqc0ieCU0plUmr1POeo8pyvi73T DtTUXm6Hnmo9RR3RXRv06QqsYJn7ibT/mCzPfB3pAqoEmh643IhuJbNsZvc8kPNX wbMv9W3y+8qh+CmdRouzavbmZwe+LGcKKh9asj5XxNMhIWNlUpEbsZmOeX7m640A 2Vqq6nPopIICR5b+W45UYaPrL0swsIsjdXJ8ITzI9vF01Bx7owVV7rtNOzK+mndm nqxpkCIHH2E6lr7lmk/MBTwoWdPBDFSoWWG9yHJM6Nyfh3+9nEg2XpWjDrk4JFX8 dWbrAuMINClKxuMrLzOg2qOGpRKX/YAr2hRC45K9PvJdXmd0LhyIRyk0X+IyqJwl N4y6mACXi0mWHv0liqzc2thddG5msP9E36EYxr5ILzeUePiVSj9/E15dWf10hkNj c0kCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD VR0OBBYEFJ84xFYjwznooHFs6FRM5Og6sb9nMA0GCSqGSIb3DQEBCwUAA4ICAQAS 5UKme4sPDORGpbZgQIeMJX6tuGguW8ZAdjwD+MlZ9POrYs4QjbRaZIxowLByQzTS Gwv2LFPSypBLhmb8qoMi9IsabyZIrHZ3CL/FmFz0Jomee8O5ZDIBf9PD3Vht7LGr hFV0d4QEJ1JrhkzO3bll/9bGXp+aEJlLdWr+aumXIOTkdnrG0CSqkM0gkLpHZPt/ B7NTeLUKYvJzQ85BK4FqLoUWlFPUa19yIqtRLULVAJyZv967lDtX/Zr1hstWO1uI AeV8KEsD+UmDfLJ/fOPtjqF/YFOOVZ1QNBIPt5d7bIdKROf1beyAN/BYGW5KaHbw H5Lk6rWS02FREAutp9lfx1/cH6NcjKF+m7ee01ZvZl4HliDtC3T7Zk6LERXpgUl+ b7DUUH8i119lAg2m9IUe2K4GS0qn0jFmwvjO5QimpAKWRGhXxNUzzxkvFMSUHHuk 2fCfDrGA4tGeEWSpiBE6doLlYsKA2KSD7ZPvfC+QsDJMlhVoSFLUmQjAJOgc47Ol IQ6SwJAfzyBfyjs4x7dtOvPmRLgOMWuIjnDrnBdSqEGULoe256YSxXXfW8AKbnuk 5F6G+TaU33fD6Q3AOfF5u0aOq0NZJ7cguyPpVkAh7DE9ZapD8j3fcEThuk0mEDuY n/PIjhs4ViFqUZPTkcpG2om3PVODLAgfi49T3f+sHw== -----END CERTIFICATE----- # Issuer: CN=Microsoft ECC Root Certificate Authority 2017 O=Microsoft Corporation # Subject: CN=Microsoft ECC Root Certificate Authority 2017 O=Microsoft Corporation # Label: "Microsoft ECC Root Certificate Authority 2017" # Serial: 136839042543790627607696632466672567020 # MD5 Fingerprint: dd:a1:03:e6:4a:93:10:d1:bf:f0:19:42:cb:fe:ed:67 # SHA1 Fingerprint: 99:9a:64:c3:7f:f4:7d:9f:ab:95:f1:47:69:89:14:60:ee:c4:c3:c5 # SHA256 Fingerprint: 35:8d:f3:9d:76:4a:f9:e1:b7:66:e9:c9:72:df:35:2e:e1:5c:fa:c2:27:af:6a:d1:d7:0e:8e:4a:6e:dc:ba:02 -----BEGIN CERTIFICATE----- MIICWTCCAd+gAwIBAgIQZvI9r4fei7FK6gxXMQHC7DAKBggqhkjOPQQDAzBlMQsw CQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYD VQQDEy1NaWNyb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIw MTcwHhcNMTkxMjE4MjMwNjQ1WhcNNDIwNzE4MjMxNjA0WjBlMQswCQYDVQQGEwJV UzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNy b3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwdjAQBgcq hkjOPQIBBgUrgQQAIgNiAATUvD0CQnVBEyPNgASGAlEvaqiBYgtlzPbKnR5vSmZR ogPZnZH6thaxjG7efM3beaYvzrvOcS/lpaso7GMEZpn4+vKTEAXhgShC48Zo9OYb hGBKia/teQ87zvH2RPUBeMCjVDBSMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8E BTADAQH/MB0GA1UdDgQWBBTIy5lycFIM+Oa+sgRXKSrPQhDtNTAQBgkrBgEEAYI3 FQEEAwIBADAKBggqhkjOPQQDAwNoADBlAjBY8k3qDPlfXu5gKcs68tvWMoQZP3zV L8KxzJOuULsJMsbG7X7JNpQS5GiFBqIb0C8CMQCZ6Ra0DvpWSNSkMBaReNtUjGUB iudQZsIxtzm6uBoiB078a1QWIP8rtedMDE2mT3M= -----END CERTIFICATE----- # Issuer: CN=Microsoft RSA Root Certificate Authority 2017 O=Microsoft Corporation # Subject: CN=Microsoft RSA Root Certificate Authority 2017 O=Microsoft Corporation # Label: "Microsoft RSA Root Certificate Authority 2017" # Serial: 40975477897264996090493496164228220339 # MD5 Fingerprint: 10:ff:00:ff:cf:c9:f8:c7:7a:c0:ee:35:8e:c9:0f:47 # SHA1 Fingerprint: 73:a5:e6:4a:3b:ff:83:16:ff:0e:dc:cc:61:8a:90:6e:4e:ae:4d:74 # SHA256 Fingerprint: c7:41:f7:0f:4b:2a:8d:88:bf:2e:71:c1:41:22:ef:53:ef:10:eb:a0:cf:a5:e6:4c:fa:20:f4:18:85:30:73:e0 -----BEGIN CERTIFICATE----- MIIFqDCCA5CgAwIBAgIQHtOXCV/YtLNHcB6qvn9FszANBgkqhkiG9w0BAQwFADBl MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYw NAYDVQQDEy1NaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 IDIwMTcwHhcNMTkxMjE4MjI1MTIyWhcNNDIwNzE4MjMwMDIzWjBlMQswCQYDVQQG EwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1N aWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwggIi MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKW76UM4wplZEWCpW9R2LBifOZ Nt9GkMml7Xhqb0eRaPgnZ1AzHaGm++DlQ6OEAlcBXZxIQIJTELy/xztokLaCLeX0 ZdDMbRnMlfl7rEqUrQ7eS0MdhweSE5CAg2Q1OQT85elss7YfUJQ4ZVBcF0a5toW1 HLUX6NZFndiyJrDKxHBKrmCk3bPZ7Pw71VdyvD/IybLeS2v4I2wDwAW9lcfNcztm gGTjGqwu+UcF8ga2m3P1eDNbx6H7JyqhtJqRjJHTOoI+dkC0zVJhUXAoP8XFWvLJ jEm7FFtNyP9nTUwSlq31/niol4fX/V4ggNyhSyL71Imtus5Hl0dVe49FyGcohJUc aDDv70ngNXtk55iwlNpNhTs+VcQor1fznhPbRiefHqJeRIOkpcrVE7NLP8TjwuaG YaRSMLl6IE9vDzhTyzMMEyuP1pq9KsgtsRx9S1HKR9FIJ3Jdh+vVReZIZZ2vUpC6 W6IYZVcSn2i51BVrlMRpIpj0M+Dt+VGOQVDJNE92kKz8OMHY4Xu54+OU4UZpyw4K UGsTuqwPN1q3ErWQgR5WrlcihtnJ0tHXUeOrO8ZV/R4O03QK0dqq6mm4lyiPSMQH +FJDOvTKVTUssKZqwJz58oHhEmrARdlns87/I6KJClTUFLkqqNfs+avNJVgyeY+Q W5g5xAgGwax/Dj0ApQIDAQABo1QwUjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/ BAUwAwEB/zAdBgNVHQ4EFgQUCctZf4aycI8awznjwNnpv7tNsiMwEAYJKwYBBAGC NxUBBAMCAQAwDQYJKoZIhvcNAQEMBQADggIBAKyvPl3CEZaJjqPnktaXFbgToqZC LgLNFgVZJ8og6Lq46BrsTaiXVq5lQ7GPAJtSzVXNUzltYkyLDVt8LkS/gxCP81OC gMNPOsduET/m4xaRhPtthH80dK2Jp86519efhGSSvpWhrQlTM93uCupKUY5vVau6 tZRGrox/2KJQJWVggEbbMwSubLWYdFQl3JPk+ONVFT24bcMKpBLBaYVu32TxU5nh SnUgnZUP5NbcA/FZGOhHibJXWpS2qdgXKxdJ5XbLwVaZOjex/2kskZGT4d9Mozd2 TaGf+G0eHdP67Pv0RR0Tbc/3WeUiJ3IrhvNXuzDtJE3cfVa7o7P4NHmJweDyAmH3 pvwPuxwXC65B2Xy9J6P9LjrRk5Sxcx0ki69bIImtt2dmefU6xqaWM/5TkshGsRGR xpl/j8nWZjEgQRCHLQzWwa80mMpkg/sTV9HB8Dx6jKXB/ZUhoHHBk2dxEuqPiApp GWSZI1b7rCoucL5mxAyE7+WL85MB+GqQk2dLsmijtWKP6T+MejteD+eMuMZ87zf9 dOLITzNy4ZQ5bb0Sr74MTnB8G2+NszKTc0QWbej09+CVgI+WXTik9KveCjCHk9hN AHFiRSdLOkKEW39lt2c0Ui2cFmuqqNh7o0JMcccMyj6D5KbvtwEwXlGjefVwaaZB RA+GsCyRxj3qrg+E -----END CERTIFICATE----- # Issuer: CN=e-Szigno Root CA 2017 O=Microsec Ltd. # Subject: CN=e-Szigno Root CA 2017 O=Microsec Ltd. # Label: "e-Szigno Root CA 2017" # Serial: 411379200276854331539784714 # MD5 Fingerprint: de:1f:f6:9e:84:ae:a7:b4:21:ce:1e:58:7d:d1:84:98 # SHA1 Fingerprint: 89:d4:83:03:4f:9e:9a:48:80:5f:72:37:d4:a9:a6:ef:cb:7c:1f:d1 # SHA256 Fingerprint: be:b0:0b:30:83:9b:9b:c3:2c:32:e4:44:79:05:95:06:41:f2:64:21:b1:5e:d0:89:19:8b:51:8a:e2:ea:1b:99 -----BEGIN CERTIFICATE----- MIICQDCCAeWgAwIBAgIMAVRI7yH9l1kN9QQKMAoGCCqGSM49BAMCMHExCzAJBgNV BAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMgTHRk LjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25vIFJv b3QgQ0EgMjAxNzAeFw0xNzA4MjIxMjA3MDZaFw00MjA4MjIxMjA3MDZaMHExCzAJ BgNVBAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMg THRkLjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25v IFJvb3QgQ0EgMjAxNzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJbcPYrYsHtv xie+RJCxs1YVe45DJH0ahFnuY2iyxl6H0BVIHqiQrb1TotreOpCmYF9oMrWGQd+H Wyx7xf58etqjYzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G A1UdDgQWBBSHERUI0arBeAyxr87GyZDvvzAEwDAfBgNVHSMEGDAWgBSHERUI0arB eAyxr87GyZDvvzAEwDAKBggqhkjOPQQDAgNJADBGAiEAtVfd14pVCzbhhkT61Nlo jbjcI4qKDdQvfepz7L9NbKgCIQDLpbQS+ue16M9+k/zzNY9vTlp8tLxOsvxyqltZ +efcMQ== -----END CERTIFICATE----- # Issuer: O=CERTSIGN SA OU=certSIGN ROOT CA G2 # Subject: O=CERTSIGN SA OU=certSIGN ROOT CA G2 # Label: "certSIGN Root CA G2" # Serial: 313609486401300475190 # MD5 Fingerprint: 8c:f1:75:8a:c6:19:cf:94:b7:f7:65:20:87:c3:97:c7 # SHA1 Fingerprint: 26:f9:93:b4:ed:3d:28:27:b0:b9:4b:a7:e9:15:1d:a3:8d:92:e5:32 # SHA256 Fingerprint: 65:7c:fe:2f:a7:3f:aa:38:46:25:71:f3:32:a2:36:3a:46:fc:e7:02:09:51:71:07:02:cd:fb:b6:ee:da:33:05 -----BEGIN CERTIFICATE----- MIIFRzCCAy+gAwIBAgIJEQA0tk7GNi02MA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV BAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJR04g Uk9PVCBDQSBHMjAeFw0xNzAyMDYwOTI3MzVaFw00MjAyMDYwOTI3MzVaMEExCzAJ BgNVBAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJ R04gUk9PVCBDQSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDF dRmRfUR0dIf+DjuW3NgBFszuY5HnC2/OOwppGnzC46+CjobXXo9X69MhWf05N0Iw vlDqtg+piNguLWkh59E3GE59kdUWX2tbAMI5Qw02hVK5U2UPHULlj88F0+7cDBrZ uIt4ImfkabBoxTzkbFpG583H+u/E7Eu9aqSs/cwoUe+StCmrqzWaTOTECMYmzPhp n+Sc8CnTXPnGFiWeI8MgwT0PPzhAsP6CRDiqWhqKa2NYOLQV07YRaXseVO6MGiKs cpc/I1mbySKEwQdPzH/iV8oScLumZfNpdWO9lfsbl83kqK/20U6o2YpxJM02PbyW xPFsqa7lzw1uKA2wDrXKUXt4FMMgL3/7FFXhEZn91QqhngLjYl/rNUssuHLoPj1P rCy7Lobio3aP5ZMqz6WryFyNSwb/EkaseMsUBzXgqd+L6a8VTxaJW732jcZZroiF DsGJ6x9nxUWO/203Nit4ZoORUSs9/1F3dmKh7Gc+PoGD4FapUB8fepmrY7+EF3fx DTvf95xhszWYijqy7DwaNz9+j5LP2RIUZNoQAhVB/0/E6xyjyfqZ90bp4RjZsbgy LcsUDFDYg2WD7rlcz8sFWkz6GZdr1l0T08JcVLwyc6B49fFtHsufpaafItzRUZ6C eWRgKRM+o/1Pcmqr4tTluCRVLERLiohEnMqE0yo7AgMBAAGjQjBAMA8GA1UdEwEB /wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSCIS1mxteg4BXrzkwJ d8RgnlRuAzANBgkqhkiG9w0BAQsFAAOCAgEAYN4auOfyYILVAzOBywaK8SJJ6ejq kX/GM15oGQOGO0MBzwdw5AgeZYWR5hEit/UCI46uuR59H35s5r0l1ZUa8gWmr4UC b6741jH/JclKyMeKqdmfS0mbEVeZkkMR3rYzpMzXjWR91M08KCy0mpbqTfXERMQl qiCA2ClV9+BB/AYm/7k29UMUA2Z44RGx2iBfRgB4ACGlHgAoYXhvqAEBj500mv/0 OJD7uNGzcgbJceaBxXntC6Z58hMLnPddDnskk7RI24Zf3lCGeOdA5jGokHZwYa+c NywRtYK3qq4kNFtyDGkNzVmf9nGvnAvRCjj5BiKDUyUM/FHE5r7iOZULJK2v0ZXk ltd0ZGtxTgI8qoXzIKNDOXZbbFD+mpwUHmUUihW9o4JFWklWatKcsWMy5WHgUyIO pwpJ6st+H6jiYoD2EEVSmAYY3qXNL3+q1Ok+CHLsIwMCPKaq2LxndD0UF/tUSxfj 03k9bWtJySgOLnRQvwzZRjoQhsmnP+mg7H/rpXdYaXHmgwo38oZJar55CJD2AhZk PuXaTH4MNMn5X7azKFGnpyuqSfqNZSlO42sTp5SjLVFteAxEy9/eCG/Oo2Sr05WE 1LlSVHJ7liXMvGnjSG4N0MedJ5qq+BOS3R7fY581qRY27Iy4g/Q9iY/NtBde17MX QRBdJ3NghVdJIgc= -----END CERTIFICATE----- # Issuer: CN=Trustwave Global Certification Authority O=Trustwave Holdings, Inc. # Subject: CN=Trustwave Global Certification Authority O=Trustwave Holdings, Inc. # Label: "Trustwave Global Certification Authority" # Serial: 1846098327275375458322922162 # MD5 Fingerprint: f8:1c:18:2d:2f:ba:5f:6d:a1:6c:bc:c7:ab:91:c7:0e # SHA1 Fingerprint: 2f:8f:36:4f:e1:58:97:44:21:59:87:a5:2a:9a:d0:69:95:26:7f:b5 # SHA256 Fingerprint: 97:55:20:15:f5:dd:fc:3c:87:88:c0:06:94:45:55:40:88:94:45:00:84:f1:00:86:70:86:bc:1a:2b:b5:8d:c8 -----BEGIN CERTIFICATE----- MIIF2jCCA8KgAwIBAgIMBfcOhtpJ80Y1LrqyMA0GCSqGSIb3DQEBCwUAMIGIMQsw CQYDVQQGEwJVUzERMA8GA1UECAwISWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28x ITAfBgNVBAoMGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1 c3R3YXZlIEdsb2JhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xNzA4MjMx OTM0MTJaFw00MjA4MjMxOTM0MTJaMIGIMQswCQYDVQQGEwJVUzERMA8GA1UECAwI SWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28xITAfBgNVBAoMGFRydXN0d2F2ZSBI b2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1c3R3YXZlIEdsb2JhbCBDZXJ0aWZp Y2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB ALldUShLPDeS0YLOvR29zd24q88KPuFd5dyqCblXAj7mY2Hf8g+CY66j96xz0Xzn swuvCAAJWX/NKSqIk4cXGIDtiLK0thAfLdZfVaITXdHG6wZWiYj+rDKd/VzDBcdu 7oaJuogDnXIhhpCujwOl3J+IKMujkkkP7NAP4m1ET4BqstTnoApTAbqOl5F2brz8 1Ws25kCI1nsvXwXoLG0R8+eyvpJETNKXpP7ScoFDB5zpET71ixpZfR9oWN0EACyW 80OzfpgZdNmcc9kYvkHHNHnZ9GLCQ7mzJ7Aiy/k9UscwR7PJPrhq4ufogXBeQotP JqX+OsIgbrv4Fo7NDKm0G2x2EOFYeUY+VM6AqFcJNykbmROPDMjWLBz7BegIlT1l RtzuzWniTY+HKE40Cz7PFNm73bZQmq131BnW2hqIyE4bJ3XYsgjxroMwuREOzYfw hI0Vcnyh78zyiGG69Gm7DIwLdVcEuE4qFC49DxweMqZiNu5m4iK4BUBjECLzMx10 coos9TkpoNPnG4CELcU9402x/RpvumUHO1jsQkUm+9jaJXLE9gCxInm943xZYkqc BW89zubWR2OZxiRvchLIrH+QtAuRcOi35hYQcRfO3gZPSEF9NUqjifLJS3tBEW1n twiYTOURGa5CgNz7kAXU+FDKvuStx8KU1xad5hePrzb7AgMBAAGjQjBAMA8GA1Ud EwEB/wQFMAMBAf8wHQYDVR0OBBYEFJngGWcNYtt2s9o9uFvo/ULSMQ6HMA4GA1Ud DwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAmHNw4rDT7TnsTGDZqRKGFx6W 0OhUKDtkLSGm+J1WE2pIPU/HPinbbViDVD2HfSMF1OQc3Og4ZYbFdada2zUFvXfe uyk3QAUHw5RSn8pk3fEbK9xGChACMf1KaA0HZJDmHvUqoai7PF35owgLEQzxPy0Q lG/+4jSHg9bP5Rs1bdID4bANqKCqRieCNqcVtgimQlRXtpla4gt5kNdXElE1GYhB aCXUNxeEFfsBctyV3lImIJgm4nb1J2/6ADtKYdkNy1GTKv0WBpanI5ojSP5RvbbE sLFUzt5sQa0WZ37b/TjNuThOssFgy50X31ieemKyJo90lZvkWx3SD92YHJtZuSPT MaCm/zjdzyBP6VhWOmfD0faZmZ26NraAL4hHT4a/RDqA5Dccprrql5gR0IRiR2Qe qu5AvzSxnI9O4fKSTx+O856X3vOmeWqJcU9LJxdI/uz0UA9PSX3MReO9ekDFQdxh VicGaeVyQYHTtgGJoC86cnn+OjC/QezHYj6RS8fZMXZC+fc8Y+wmjHMMfRod6qh8 h6jCJ3zhM0EPz8/8AKAigJ5Kp28AsEFFtyLKaEjFQqKu3R3y4G5OBVixwJAWKqQ9 EEC+j2Jjg6mcgn0tAumDMHzLJ8n9HmYAsC7TIS+OMxZsmO0QqAfWzJPP29FpHOTK yeC2nOnOcXHebD8WpHk= -----END CERTIFICATE----- # Issuer: CN=Trustwave Global ECC P256 Certification Authority O=Trustwave Holdings, Inc. # Subject: CN=Trustwave Global ECC P256 Certification Authority O=Trustwave Holdings, Inc. # Label: "Trustwave Global ECC P256 Certification Authority" # Serial: 4151900041497450638097112925 # MD5 Fingerprint: 5b:44:e3:8d:5d:36:86:26:e8:0d:05:d2:59:a7:83:54 # SHA1 Fingerprint: b4:90:82:dd:45:0c:be:8b:5b:b1:66:d3:e2:a4:08:26:cd:ed:42:cf # SHA256 Fingerprint: 94:5b:bc:82:5e:a5:54:f4:89:d1:fd:51:a7:3d:df:2e:a6:24:ac:70:19:a0:52:05:22:5c:22:a7:8c:cf:a8:b4 -----BEGIN CERTIFICATE----- MIICYDCCAgegAwIBAgIMDWpfCD8oXD5Rld9dMAoGCCqGSM49BAMCMIGRMQswCQYD VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf BgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3 YXZlIEdsb2JhbCBFQ0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x NzA4MjMxOTM1MTBaFw00MjA4MjMxOTM1MTBaMIGRMQswCQYDVQQGEwJVUzERMA8G A1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0 d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF Q0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTBZMBMGByqGSM49AgEGCCqG SM49AwEHA0IABH77bOYj43MyCMpg5lOcunSNGLB4kFKA3TjASh3RqMyTpJcGOMoN FWLGjgEqZZ2q3zSRLoHB5DOSMcT9CTqmP62jQzBBMA8GA1UdEwEB/wQFMAMBAf8w DwYDVR0PAQH/BAUDAwcGADAdBgNVHQ4EFgQUo0EGrJBt0UrrdaVKEJmzsaGLSvcw CgYIKoZIzj0EAwIDRwAwRAIgB+ZU2g6gWrKuEZ+Hxbb/ad4lvvigtwjzRM4q3wgh DDcCIC0mA6AFvWvR9lz4ZcyGbbOcNEhjhAnFjXca4syc4XR7 -----END CERTIFICATE----- # Issuer: CN=Trustwave Global ECC P384 Certification Authority O=Trustwave Holdings, Inc. # Subject: CN=Trustwave Global ECC P384 Certification Authority O=Trustwave Holdings, Inc. # Label: "Trustwave Global ECC P384 Certification Authority" # Serial: 2704997926503831671788816187 # MD5 Fingerprint: ea:cf:60:c4:3b:b9:15:29:40:a1:97:ed:78:27:93:d6 # SHA1 Fingerprint: e7:f3:a3:c8:cf:6f:c3:04:2e:6d:0e:67:32:c5:9e:68:95:0d:5e:d2 # SHA256 Fingerprint: 55:90:38:59:c8:c0:c3:eb:b8:75:9e:ce:4e:25:57:22:5f:f5:75:8b:bd:38:eb:d4:82:76:60:1e:1b:d5:80:97 -----BEGIN CERTIFICATE----- MIICnTCCAiSgAwIBAgIMCL2Fl2yZJ6SAaEc7MAoGCCqGSM49BAMDMIGRMQswCQYD VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf BgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3 YXZlIEdsb2JhbCBFQ0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x NzA4MjMxOTM2NDNaFw00MjA4MjMxOTM2NDNaMIGRMQswCQYDVQQGEwJVUzERMA8G A1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0 d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF Q0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTB2MBAGByqGSM49AgEGBSuB BAAiA2IABGvaDXU1CDFHBa5FmVXxERMuSvgQMSOjfoPTfygIOiYaOs+Xgh+AtycJ j9GOMMQKmw6sWASr9zZ9lCOkmwqKi6vr/TklZvFe/oyujUF5nQlgziip04pt89ZF 1PKYhDhloKNDMEEwDwYDVR0TAQH/BAUwAwEB/zAPBgNVHQ8BAf8EBQMDBwYAMB0G A1UdDgQWBBRVqYSJ0sEyvRjLbKYHTsjnnb6CkDAKBggqhkjOPQQDAwNnADBkAjA3 AZKXRRJ+oPM+rRk6ct30UJMDEr5E0k9BpIycnR+j9sKS50gU/k6bpZFXrsY3crsC MGclCrEMXu6pY5Jv5ZAL/mYiykf9ijH3g/56vxC+GCsej/YpHpRZ744hN8tRmKVu Sw== -----END CERTIFICATE----- # Issuer: CN=NAVER Global Root Certification Authority O=NAVER BUSINESS PLATFORM Corp. # Subject: CN=NAVER Global Root Certification Authority O=NAVER BUSINESS PLATFORM Corp. # Label: "NAVER Global Root Certification Authority" # Serial: 9013692873798656336226253319739695165984492813 # MD5 Fingerprint: c8:7e:41:f6:25:3b:f5:09:b3:17:e8:46:3d:bf:d0:9b # SHA1 Fingerprint: 8f:6b:f2:a9:27:4a:da:14:a0:c4:f4:8e:61:27:f9:c0:1e:78:5d:d1 # SHA256 Fingerprint: 88:f4:38:dc:f8:ff:d1:fa:8f:42:91:15:ff:e5:f8:2a:e1:e0:6e:0c:70:c3:75:fa:ad:71:7b:34:a4:9e:72:65 -----BEGIN CERTIFICATE----- MIIFojCCA4qgAwIBAgIUAZQwHqIL3fXFMyqxQ0Rx+NZQTQ0wDQYJKoZIhvcNAQEM BQAwaTELMAkGA1UEBhMCS1IxJjAkBgNVBAoMHU5BVkVSIEJVU0lORVNTIFBMQVRG T1JNIENvcnAuMTIwMAYDVQQDDClOQVZFUiBHbG9iYWwgUm9vdCBDZXJ0aWZpY2F0 aW9uIEF1dGhvcml0eTAeFw0xNzA4MTgwODU4NDJaFw0zNzA4MTgyMzU5NTlaMGkx CzAJBgNVBAYTAktSMSYwJAYDVQQKDB1OQVZFUiBCVVNJTkVTUyBQTEFURk9STSBD b3JwLjEyMDAGA1UEAwwpTkFWRVIgR2xvYmFsIFJvb3QgQ2VydGlmaWNhdGlvbiBB dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC21PGTXLVA iQqrDZBbUGOukJR0F0Vy1ntlWilLp1agS7gvQnXp2XskWjFlqxcX0TM62RHcQDaH 38dq6SZeWYp34+hInDEW+j6RscrJo+KfziFTowI2MMtSAuXaMl3Dxeb57hHHi8lE HoSTGEq0n+USZGnQJoViAbbJAh2+g1G7XNr4rRVqmfeSVPc0W+m/6imBEtRTkZaz kVrd/pBzKPswRrXKCAfHcXLJZtM0l/aM9BhK4dA9WkW2aacp+yPOiNgSnABIqKYP szuSjXEOdMWLyEz59JuOuDxp7W87UC9Y7cSw0BwbagzivESq2M0UXZR4Yb8Obtoq vC8MC3GmsxY/nOb5zJ9TNeIDoKAYv7vxvvTWjIcNQvcGufFt7QSUqP620wbGQGHf nZ3zVHbOUzoBppJB7ASjjw2i1QnK1sua8e9DXcCrpUHPXFNwcMmIpi3Ua2FzUCaG YQ5fG8Ir4ozVu53BA0K6lNpfqbDKzE0K70dpAy8i+/Eozr9dUGWokG2zdLAIx6yo 0es+nPxdGoMuK8u180SdOqcXYZaicdNwlhVNt0xz7hlcxVs+Qf6sdWA7G2POAN3a CJBitOUt7kinaxeZVL6HSuOpXgRM6xBtVNbv8ejyYhbLgGvtPe31HzClrkvJE+2K AQHJuFFYwGY6sWZLxNUxAmLpdIQM201GLQIDAQABo0IwQDAdBgNVHQ4EFgQU0p+I 36HNLL3s9TsBAZMzJ7LrYEswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB Af8wDQYJKoZIhvcNAQEMBQADggIBADLKgLOdPVQG3dLSLvCkASELZ0jKbY7gyKoN qo0hV4/GPnrK21HUUrPUloSlWGB/5QuOH/XcChWB5Tu2tyIvCZwTFrFsDDUIbatj cu3cvuzHV+YwIHHW1xDBE1UBjCpD5EHxzzp6U5LOogMFDTjfArsQLtk70pt6wKGm +LUx5vR1yblTmXVHIloUFcd4G7ad6Qz4G3bxhYTeodoS76TiEJd6eN4MUZeoIUCL hr0N8F5OSza7OyAfikJW4Qsav3vQIkMsRIz75Sq0bBwcupTgE34h5prCy8VCZLQe lHsIJchxzIdFV4XTnyliIoNRlwAYl3dqmJLJfGBs32x9SuRwTMKeuB330DTHD8z7 p/8Dvq1wkNoL3chtl1+afwkyQf3NosxabUzyqkn+Zvjp2DXrDige7kgvOtB5CTh8 piKCk5XQA76+AqAF3SAi428diDRgxuYKuQl1C/AH6GmWNcf7I4GOODm4RStDeKLR LBT/DShycpWbXgnbiUSYqqFJu3FS8r/2/yehNq+4tneI3TqkbZs0kNwUXTC/t+sX 5Ie3cdCh13cV1ELX8vMxmV2b3RZtP+oGI/hGoiLtk/bdmuYqh7GYVPEi92tF4+KO dh2ajcQGjTa3FPOdVGm3jjzVpG2Tgbet9r1ke8LJaDmgkpzNNIaRkPpkUZ3+/uul 9XXeifdy -----END CERTIFICATE----- # Issuer: CN=AC RAIZ FNMT-RCM SERVIDORES SEGUROS O=FNMT-RCM OU=Ceres # Subject: CN=AC RAIZ FNMT-RCM SERVIDORES SEGUROS O=FNMT-RCM OU=Ceres # Label: "AC RAIZ FNMT-RCM SERVIDORES SEGUROS" # Serial: 131542671362353147877283741781055151509 # MD5 Fingerprint: 19:36:9c:52:03:2f:d2:d1:bb:23:cc:dd:1e:12:55:bb # SHA1 Fingerprint: 62:ff:d9:9e:c0:65:0d:03:ce:75:93:d2:ed:3f:2d:32:c9:e3:e5:4a # SHA256 Fingerprint: 55:41:53:b1:3d:2c:f9:dd:b7:53:bf:be:1a:4e:0a:e0:8d:0a:a4:18:70:58:fe:60:a2:b8:62:b2:e4:b8:7b:cb -----BEGIN CERTIFICATE----- MIICbjCCAfOgAwIBAgIQYvYybOXE42hcG2LdnC6dlTAKBggqhkjOPQQDAzB4MQsw CQYDVQQGEwJFUzERMA8GA1UECgwIRk5NVC1SQ00xDjAMBgNVBAsMBUNlcmVzMRgw FgYDVQRhDA9WQVRFUy1RMjgyNjAwNEoxLDAqBgNVBAMMI0FDIFJBSVogRk5NVC1S Q00gU0VSVklET1JFUyBTRUdVUk9TMB4XDTE4MTIyMDA5MzczM1oXDTQzMTIyMDA5 MzczM1oweDELMAkGA1UEBhMCRVMxETAPBgNVBAoMCEZOTVQtUkNNMQ4wDAYDVQQL DAVDZXJlczEYMBYGA1UEYQwPVkFURVMtUTI4MjYwMDRKMSwwKgYDVQQDDCNBQyBS QUlaIEZOTVQtUkNNIFNFUlZJRE9SRVMgU0VHVVJPUzB2MBAGByqGSM49AgEGBSuB BAAiA2IABPa6V1PIyqvfNkpSIeSX0oNnnvBlUdBeh8dHsVnyV0ebAAKTRBdp20LH sbI6GA60XYyzZl2hNPk2LEnb80b8s0RpRBNm/dfF/a82Tc4DTQdxz69qBdKiQ1oK Um8BA06Oi6NCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD VR0OBBYEFAG5L++/EYZg8k/QQW6rcx/n0m5JMAoGCCqGSM49BAMDA2kAMGYCMQCu SuMrQMN0EfKVrRYj3k4MGuZdpSRea0R7/DjiT8ucRRcRTBQnJlU5dUoDzBOQn5IC MQD6SmxgiHPz7riYYqnOK8LZiqZwMR2vsJRM60/G49HzYqc8/5MuB1xJAWdpEgJy v+c= -----END CERTIFICATE----- # Issuer: CN=GlobalSign Root R46 O=GlobalSign nv-sa # Subject: CN=GlobalSign Root R46 O=GlobalSign nv-sa # Label: "GlobalSign Root R46" # Serial: 1552617688466950547958867513931858518042577 # MD5 Fingerprint: c4:14:30:e4:fa:66:43:94:2a:6a:1b:24:5f:19:d0:ef # SHA1 Fingerprint: 53:a2:b0:4b:ca:6b:d6:45:e6:39:8a:8e:c4:0d:d2:bf:77:c3:a2:90 # SHA256 Fingerprint: 4f:a3:12:6d:8d:3a:11:d1:c4:85:5a:4f:80:7c:ba:d6:cf:91:9d:3a:5a:88:b0:3b:ea:2c:63:72:d9:3c:40:c9 -----BEGIN CERTIFICATE----- MIIFWjCCA0KgAwIBAgISEdK7udcjGJ5AXwqdLdDfJWfRMA0GCSqGSIb3DQEBDAUA MEYxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYD VQQDExNHbG9iYWxTaWduIFJvb3QgUjQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMy MDAwMDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYt c2ExHDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEB AQUAA4ICDwAwggIKAoICAQCsrHQy6LNl5brtQyYdpokNRbopiLKkHWPd08EsCVeJ OaFV6Wc0dwxu5FUdUiXSE2te4R2pt32JMl8Nnp8semNgQB+msLZ4j5lUlghYruQG vGIFAha/r6gjA7aUD7xubMLL1aa7DOn2wQL7Id5m3RerdELv8HQvJfTqa1VbkNud 316HCkD7rRlr+/fKYIje2sGP1q7Vf9Q8g+7XFkyDRTNrJ9CG0Bwta/OrffGFqfUo 0q3v84RLHIf8E6M6cqJaESvWJ3En7YEtbWaBkoe0G1h6zD8K+kZPTXhc+CtI4wSE y132tGqzZfxCnlEmIyDLPRT5ge1lFgBPGmSXZgjPjHvjK8Cd+RTyG/FWaha/LIWF zXg4mutCagI0GIMXTpRW+LaCtfOW3T3zvn8gdz57GSNrLNRyc0NXfeD412lPFzYE +cCQYDdF3uYM2HSNrpyibXRdQr4G9dlkbgIQrImwTDsHTUB+JMWKmIJ5jqSngiCN I/onccnfxkF0oE32kRbcRoxfKWMxWXEM2G/CtjJ9++ZdU6Z+Ffy7dXxd7Pj2Fxzs x2sZy/N78CsHpdlseVR2bJ0cpm4O6XkMqCNqo98bMDGfsVR7/mrLZqrcZdCinkqa ByFrgY/bxFn63iLABJzjqls2k+g9vXqhnQt2sQvHnf3PmKgGwvgqo6GDoLclcqUC 4wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV HQ4EFgQUA1yrc4GHqMywptWU4jaWSf8FmSwwDQYJKoZIhvcNAQEMBQADggIBAHx4 7PYCLLtbfpIrXTncvtgdokIzTfnvpCo7RGkerNlFo048p9gkUbJUHJNOxO97k4Vg JuoJSOD1u8fpaNK7ajFxzHmuEajwmf3lH7wvqMxX63bEIaZHU1VNaL8FpO7XJqti 2kM3S+LGteWygxk6x9PbTZ4IevPuzz5i+6zoYMzRx6Fcg0XERczzF2sUyQQCPtIk pnnpHs6i58FZFZ8d4kuaPp92CC1r2LpXFNqD6v6MVenQTqnMdzGxRBF6XLE+0xRF FRhiJBPSy03OXIPBNvIQtQ6IbbjhVp+J3pZmOUdkLG5NrmJ7v2B0GbhWrJKsFjLt rWhV/pi60zTe9Mlhww6G9kuEYO4Ne7UyWHmRVSyBQ7N0H3qqJZ4d16GLuc1CLgSk ZoNNiTW2bKg2SnkheCLQQrzRQDGQob4Ez8pn7fXwgNNgyYMqIgXQBztSvwyeqiv5 u+YfjyW6hY0XHgL+XVAEV8/+LbzvXMAaq7afJMbfc2hIkCwU9D9SGuTSyxTDYWnP 4vkYxboznxSjBF25cfe1lNj2M8FawTSLfJvdkzrnE6JwYZ+vj+vYxXX4M2bUdGc6 N3ec592kD3ZDZopD8p/7DEJ4Y9HiD2971KE9dJeFt0g5QdYg/NA6s/rob8SKunE3 vouXsXgxT7PntgMTzlSdriVZzH81Xwj3QEUxeCp6 -----END CERTIFICATE----- # Issuer: CN=GlobalSign Root E46 O=GlobalSign nv-sa # Subject: CN=GlobalSign Root E46 O=GlobalSign nv-sa # Label: "GlobalSign Root E46" # Serial: 1552617690338932563915843282459653771421763 # MD5 Fingerprint: b5:b8:66:ed:de:08:83:e3:c9:e2:01:34:06:ac:51:6f # SHA1 Fingerprint: 39:b4:6c:d5:fe:80:06:eb:e2:2f:4a:bb:08:33:a0:af:db:b9:dd:84 # SHA256 Fingerprint: cb:b9:c4:4d:84:b8:04:3e:10:50:ea:31:a6:9f:51:49:55:d7:bf:d2:e2:c6:b4:93:01:01:9a:d6:1d:9f:50:58 -----BEGIN CERTIFICATE----- MIICCzCCAZGgAwIBAgISEdK7ujNu1LzmJGjFDYQdmOhDMAoGCCqGSM49BAMDMEYx CzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYDVQQD ExNHbG9iYWxTaWduIFJvb3QgRTQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMyMDAw MDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2Ex HDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA IgNiAAScDrHPt+ieUnd1NPqlRqetMhkytAepJ8qUuwzSChDH2omwlwxwEwkBjtjq R+q+soArzfwoDdusvKSGN+1wCAB16pMLey5SnCNoIwZD7JIvU4Tb+0cUB+hflGdd yXqBPCCjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud DgQWBBQxCpCPtsad0kRLgLWi5h+xEk8blTAKBggqhkjOPQQDAwNoADBlAjEA31SQ 7Zvvi5QCkxeCmb6zniz2C5GMn0oUsfZkvLtoURMMA/cVi4RguYv/Uo7njLwcAjA8 +RHUjE7AwWHCFUyqqx0LMV87HOIAl0Qx5v5zli/altP+CAezNIm8BZ/3Hobui3A= -----END CERTIFICATE----- # Issuer: CN=GLOBALTRUST 2020 O=e-commerce monitoring GmbH # Subject: CN=GLOBALTRUST 2020 O=e-commerce monitoring GmbH # Label: "GLOBALTRUST 2020" # Serial: 109160994242082918454945253 # MD5 Fingerprint: 8a:c7:6f:cb:6d:e3:cc:a2:f1:7c:83:fa:0e:78:d7:e8 # SHA1 Fingerprint: d0:67:c1:13:51:01:0c:aa:d0:c7:6a:65:37:31:16:26:4f:53:71:a2 # SHA256 Fingerprint: 9a:29:6a:51:82:d1:d4:51:a2:e3:7f:43:9b:74:da:af:a2:67:52:33:29:f9:0f:9a:0d:20:07:c3:34:e2:3c:9a -----BEGIN CERTIFICATE----- MIIFgjCCA2qgAwIBAgILWku9WvtPilv6ZeUwDQYJKoZIhvcNAQELBQAwTTELMAkG A1UEBhMCQVQxIzAhBgNVBAoTGmUtY29tbWVyY2UgbW9uaXRvcmluZyBHbWJIMRkw FwYDVQQDExBHTE9CQUxUUlVTVCAyMDIwMB4XDTIwMDIxMDAwMDAwMFoXDTQwMDYx MDAwMDAwMFowTTELMAkGA1UEBhMCQVQxIzAhBgNVBAoTGmUtY29tbWVyY2UgbW9u aXRvcmluZyBHbWJIMRkwFwYDVQQDExBHTE9CQUxUUlVTVCAyMDIwMIICIjANBgkq hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAri5WrRsc7/aVj6B3GyvTY4+ETUWiD59b RatZe1E0+eyLinjF3WuvvcTfk0Uev5E4C64OFudBc/jbu9G4UeDLgztzOG53ig9Z YybNpyrOVPu44sB8R85gfD+yc/LAGbaKkoc1DZAoouQVBGM+uq/ufF7MpotQsjj3 QWPKzv9pj2gOlTblzLmMCcpL3TGQlsjMH/1WljTbjhzqLL6FLmPdqqmV0/0plRPw yJiT2S0WR5ARg6I6IqIoV6Lr/sCMKKCmfecqQjuCgGOlYx8ZzHyyZqjC0203b+J+ BlHZRYQfEs4kUmSFC0iAToexIiIwquuuvuAC4EDosEKAA1GqtH6qRNdDYfOiaxaJ SaSjpCuKAsR49GiKweR6NrFvG5Ybd0mN1MkGco/PU+PcF4UgStyYJ9ORJitHHmkH r96i5OTUawuzXnzUJIBHKWk7buis/UDr2O1xcSvy6Fgd60GXIsUf1DnQJ4+H4xj0 4KlGDfV0OoIu0G4skaMxXDtG6nsEEFZegB31pWXogvziB4xiRfUg3kZwhqG8k9Me dKZssCz3AwyIDMvUclOGvGBG85hqwvG/Q/lwIHfKN0F5VVJjjVsSn8VoxIidrPIw q7ejMZdnrY8XD2zHc+0klGvIg5rQmjdJBKuxFshsSUktq6HQjJLyQUp5ISXbY9e2 nKd+Qmn7OmMCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC AQYwHQYDVR0OBBYEFNwuH9FhN3nkq9XVsxJxaD1qaJwiMB8GA1UdIwQYMBaAFNwu H9FhN3nkq9XVsxJxaD1qaJwiMA0GCSqGSIb3DQEBCwUAA4ICAQCR8EICaEDuw2jA VC/f7GLDw56KoDEoqoOOpFaWEhCGVrqXctJUMHytGdUdaG/7FELYjQ7ztdGl4wJC XtzoRlgHNQIw4Lx0SsFDKv/bGtCwr2zD/cuz9X9tAy5ZVp0tLTWMstZDFyySCstd 6IwPS3BD0IL/qMy/pJTAvoe9iuOTe8aPmxadJ2W8esVCgmxcB9CpwYhgROmYhRZf +I/KARDOJcP5YBugxZfD0yyIMaK9MOzQ0MAS8cE54+X1+NZK3TTN+2/BT+MAi1bi kvcoskJ3ciNnxz8RFbLEAwW+uxF7Cr+obuf/WEPPm2eggAe2HcqtbepBEX4tdJP7 wry+UUTF72glJ4DjyKDUEuzZpTcdN3y0kcra1LGWge9oXHYQSa9+pTeAsRxSvTOB TI/53WXZFM2KJVj04sWDpQmQ1GwUY7VA3+vA/MRYfg0UFodUJ25W5HCEuGwyEn6C MUO+1918oa2u1qsgEu8KwxCMSZY13At1XrFP1U80DhEgB3VDRemjEdqso5nCtnkn 4rnvyOL2NSl6dPrFf4IFYqYK6miyeUcGbvJXqBUzxvd4Sj1Ce2t+/vdG6tHrju+I aFvowdlxfv1k7/9nR4hYJS8+hge9+6jlgqispdNpQ80xiEmEU5LAsTkbOYMBMMTy qfrQA71yN2BWHzZ8vTmR9W0Nv3vXkg== -----END CERTIFICATE----- # Issuer: CN=ANF Secure Server Root CA O=ANF Autoridad de Certificacion OU=ANF CA Raiz # Subject: CN=ANF Secure Server Root CA O=ANF Autoridad de Certificacion OU=ANF CA Raiz # Label: "ANF Secure Server Root CA" # Serial: 996390341000653745 # MD5 Fingerprint: 26:a6:44:5a:d9:af:4e:2f:b2:1d:b6:65:b0:4e:e8:96 # SHA1 Fingerprint: 5b:6e:68:d0:cc:15:b6:a0:5f:1e:c1:5f:ae:02:fc:6b:2f:5d:6f:74 # SHA256 Fingerprint: fb:8f:ec:75:91:69:b9:10:6b:1e:51:16:44:c6:18:c5:13:04:37:3f:6c:06:43:08:8d:8b:ef:fd:1b:99:75:99 -----BEGIN CERTIFICATE----- MIIF7zCCA9egAwIBAgIIDdPjvGz5a7EwDQYJKoZIhvcNAQELBQAwgYQxEjAQBgNV BAUTCUc2MzI4NzUxMDELMAkGA1UEBhMCRVMxJzAlBgNVBAoTHkFORiBBdXRvcmlk YWQgZGUgQ2VydGlmaWNhY2lvbjEUMBIGA1UECxMLQU5GIENBIFJhaXoxIjAgBgNV BAMTGUFORiBTZWN1cmUgU2VydmVyIFJvb3QgQ0EwHhcNMTkwOTA0MTAwMDM4WhcN MzkwODMwMTAwMDM4WjCBhDESMBAGA1UEBRMJRzYzMjg3NTEwMQswCQYDVQQGEwJF UzEnMCUGA1UEChMeQU5GIEF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uMRQwEgYD VQQLEwtBTkYgQ0EgUmFpejEiMCAGA1UEAxMZQU5GIFNlY3VyZSBTZXJ2ZXIgUm9v dCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANvrayvmZFSVgpCj cqQZAZ2cC4Ffc0m6p6zzBE57lgvsEeBbphzOG9INgxwruJ4dfkUyYA8H6XdYfp9q yGFOtibBTI3/TO80sh9l2Ll49a2pcbnvT1gdpd50IJeh7WhM3pIXS7yr/2WanvtH 2Vdy8wmhrnZEE26cLUQ5vPnHO6RYPUG9tMJJo8gN0pcvB2VSAKduyK9o7PQUlrZX H1bDOZ8rbeTzPvY1ZNoMHKGESy9LS+IsJJ1tk0DrtSOOMspvRdOoiXsezx76W0OL zc2oD2rKDF65nkeP8Nm2CgtYZRczuSPkdxl9y0oukntPLxB3sY0vaJxizOBQ+OyR p1RMVwnVdmPF6GUe7m1qzwmd+nxPrWAI/VaZDxUse6mAq4xhj0oHdkLePfTdsiQz W7i1o0TJrH93PB0j7IKppuLIBkwC/qxcmZkLLxCKpvR/1Yd0DVlJRfbwcVw5Kda/ SiOL9V8BY9KHcyi1Swr1+KuCLH5zJTIdC2MKF4EA/7Z2Xue0sUDKIbvVgFHlSFJn LNJhiQcND85Cd8BEc5xEUKDbEAotlRyBr+Qc5RQe8TZBAQIvfXOn3kLMTOmJDVb3 n5HUA8ZsyY/b2BzgQJhdZpmYgG4t/wHFzstGH6wCxkPmrqKEPMVOHj1tyRRM4y5B u8o5vzY8KhmqQYdOpc5LMnndkEl/AgMBAAGjYzBhMB8GA1UdIwQYMBaAFJxf0Gxj o1+TypOYCK2Mh6UsXME3MB0GA1UdDgQWBBScX9BsY6Nfk8qTmAitjIelLFzBNzAO BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC AgEATh65isagmD9uw2nAalxJUqzLK114OMHVVISfk/CHGT0sZonrDUL8zPB1hT+L 9IBdeeUXZ701guLyPI59WzbLWoAAKfLOKyzxj6ptBZNscsdW699QIyjlRRA96Gej rw5VD5AJYu9LWaL2U/HANeQvwSS9eS9OICI7/RogsKQOLHDtdD+4E5UGUcjohybK pFtqFiGS3XNgnhAY3jyB6ugYw3yJ8otQPr0R4hUDqDZ9MwFsSBXXiJCZBMXM5gf0 vPSQ7RPi6ovDj6MzD8EpTBNO2hVWcXNyglD2mjN8orGoGjR0ZVzO0eurU+AagNjq OknkJjCb5RyKqKkVMoaZkgoQI1YS4PbOTOK7vtuNknMBZi9iPrJyJ0U27U1W45eZ /zo1PqVUSlJZS2Db7v54EX9K3BR5YLZrZAPbFYPhor72I5dQ8AkzNqdxliXzuUJ9 2zg/LFis6ELhDtjTO0wugumDLmsx2d1Hhk9tl5EuT+IocTUW0fJz/iUrB0ckYyfI +PbZa/wSMVYIwFNCr5zQM378BvAxRAMU8Vjq8moNqRGyg77FGr8H6lnco4g175x2 MjxNBiLOFeXdntiP2t7SxDnlF4HPOEfrf4htWRvfn0IUrn7PqLBmZdo3r5+qPeoo tt7VMVgWglvquxl1AnMaykgaIZOQCo6ThKd9OyMYkomgjaw= -----END CERTIFICATE----- # Issuer: CN=Certum EC-384 CA O=Asseco Data Systems S.A. OU=Certum Certification Authority # Subject: CN=Certum EC-384 CA O=Asseco Data Systems S.A. OU=Certum Certification Authority # Label: "Certum EC-384 CA" # Serial: 160250656287871593594747141429395092468 # MD5 Fingerprint: b6:65:b3:96:60:97:12:a1:ec:4e:e1:3d:a3:c6:c9:f1 # SHA1 Fingerprint: f3:3e:78:3c:ac:df:f4:a2:cc:ac:67:55:69:56:d7:e5:16:3c:e1:ed # SHA256 Fingerprint: 6b:32:80:85:62:53:18:aa:50:d1:73:c9:8d:8b:da:09:d5:7e:27:41:3d:11:4c:f7:87:a0:f5:d0:6c:03:0c:f6 -----BEGIN CERTIFICATE----- MIICZTCCAeugAwIBAgIQeI8nXIESUiClBNAt3bpz9DAKBggqhkjOPQQDAzB0MQsw CQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEuMScw JQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGTAXBgNVBAMT EENlcnR1bSBFQy0zODQgQ0EwHhcNMTgwMzI2MDcyNDU0WhcNNDMwMzI2MDcyNDU0 WjB0MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBT LkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGTAX BgNVBAMTEENlcnR1bSBFQy0zODQgQ0EwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATE KI6rGFtqvm5kN2PkzeyrOvfMobgOgknXhimfoZTy42B4mIF4Bk3y7JoOV2CDn7Tm Fy8as10CW4kjPMIRBSqniBMY81CE1700LCeJVf/OTOffph8oxPBUw7l8t1Ot68Kj QjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI0GZnQkdjrzife81r1HfS+8 EF9LMA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNoADBlAjADVS2m5hjEfO/J UG7BJw+ch69u1RsIGL2SKcHvlJF40jocVYli5RsJHrpka/F2tNQCMQC0QoSZ/6vn nvuRlydd3LBbMHHOXjgaatkl5+r3YZJW+OraNsKHZZYuciUvf9/DE8k= -----END CERTIFICATE----- # Issuer: CN=Certum Trusted Root CA O=Asseco Data Systems S.A. OU=Certum Certification Authority # Subject: CN=Certum Trusted Root CA O=Asseco Data Systems S.A. OU=Certum Certification Authority # Label: "Certum Trusted Root CA" # Serial: 40870380103424195783807378461123655149 # MD5 Fingerprint: 51:e1:c2:e7:fe:4c:84:af:59:0e:2f:f4:54:6f:ea:29 # SHA1 Fingerprint: c8:83:44:c0:18:ae:9f:cc:f1:87:b7:8f:22:d1:c5:d7:45:84:ba:e5 # SHA256 Fingerprint: fe:76:96:57:38:55:77:3e:37:a9:5e:7a:d4:d9:cc:96:c3:01:57:c1:5d:31:76:5b:a9:b1:57:04:e1:ae:78:fd -----BEGIN CERTIFICATE----- MIIFwDCCA6igAwIBAgIQHr9ZULjJgDdMBvfrVU+17TANBgkqhkiG9w0BAQ0FADB6 MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEu MScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxHzAdBgNV BAMTFkNlcnR1bSBUcnVzdGVkIFJvb3QgQ0EwHhcNMTgwMzE2MTIxMDEzWhcNNDMw MzE2MTIxMDEzWjB6MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEg U3lzdGVtcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRo b3JpdHkxHzAdBgNVBAMTFkNlcnR1bSBUcnVzdGVkIFJvb3QgQ0EwggIiMA0GCSqG SIb3DQEBAQUAA4ICDwAwggIKAoICAQDRLY67tzbqbTeRn06TpwXkKQMlzhyC93yZ n0EGze2jusDbCSzBfN8pfktlL5On1AFrAygYo9idBcEq2EXxkd7fO9CAAozPOA/q p1x4EaTByIVcJdPTsuclzxFUl6s1wB52HO8AU5853BSlLCIls3Jy/I2z5T4IHhQq NwuIPMqw9MjCoa68wb4pZ1Xi/K1ZXP69VyywkI3C7Te2fJmItdUDmj0VDT06qKhF 8JVOJVkdzZhpu9PMMsmN74H+rX2Ju7pgE8pllWeg8xn2A1bUatMn4qGtg/BKEiJ3 HAVz4hlxQsDsdUaakFjgao4rpUYwBI4Zshfjvqm6f1bxJAPXsiEodg42MEx51UGa mqi4NboMOvJEGyCI98Ul1z3G4z5D3Yf+xOr1Uz5MZf87Sst4WmsXXw3Hw09Omiqi 7VdNIuJGmj8PkTQkfVXjjJU30xrwCSss0smNtA0Aq2cpKNgB9RkEth2+dv5yXMSF ytKAQd8FqKPVhJBPC/PgP5sZ0jeJP/J7UhyM9uH3PAeXjA6iWYEMspA90+NZRu0P qafegGtaqge2Gcu8V/OXIXoMsSt0Puvap2ctTMSYnjYJdmZm/Bo/6khUHL4wvYBQ v3y1zgD2DGHZ5yQD4OMBgQ692IU0iL2yNqh7XAjlRICMb/gv1SHKHRzQ+8S1h9E6 Tsd2tTVItQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSM+xx1 vALTn04uSNn5YFSqxLNP+jAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQENBQAD ggIBAEii1QALLtA/vBzVtVRJHlpr9OTy4EA34MwUe7nJ+jW1dReTagVphZzNTxl4 WxmB82M+w85bj/UvXgF2Ez8sALnNllI5SW0ETsXpD4YN4fqzX4IS8TrOZgYkNCvo zMrnadyHncI013nR03e4qllY/p0m+jiGPp2Kh2RX5Rc64vmNueMzeMGQ2Ljdt4NR 5MTMI9UGfOZR0800McD2RrsLrfw9EAUqO0qRJe6M1ISHgCq8CYyqOhNf6DR5UMEQ GfnTKB7U0VEwKbOukGfWHwpjscWpxkIxYxeU72nLL/qMFH3EQxiJ2fAyQOaA4kZf 5ePBAFmo+eggvIksDkc0C+pXwlM2/KfUrzHN/gLldfq5Jwn58/U7yn2fqSLLiMmq 0Uc9NneoWWRrJ8/vJ8HjJLWG965+Mk2weWjROeiQWMODvA8s1pfrzgzhIMfatz7D P78v3DSk+yshzWePS/Tj6tQ/50+6uaWTRRxmHyH6ZF5v4HaUMst19W7l9o/HuKTM qJZ9ZPskWkoDbGs4xugDQ5r3V7mzKWmTOPQD8rv7gmsHINFSH5pkAnuYZttcTVoP 0ISVoDwUQwbKytu4QTbaakRnh6+v40URFWkIsr4WOZckbxJF0WddCajJFdr60qZf E2Efv4WstK2tBZQIgx51F9NxO5NQI1mg7TyRVJ12AMXDuDjb -----END CERTIFICATE----- # Issuer: CN=TunTrust Root CA O=Agence Nationale de Certification Electronique # Subject: CN=TunTrust Root CA O=Agence Nationale de Certification Electronique # Label: "TunTrust Root CA" # Serial: 108534058042236574382096126452369648152337120275 # MD5 Fingerprint: 85:13:b9:90:5b:36:5c:b6:5e:b8:5a:f8:e0:31:57:b4 # SHA1 Fingerprint: cf:e9:70:84:0f:e0:73:0f:9d:f6:0c:7f:2c:4b:ee:20:46:34:9c:bb # SHA256 Fingerprint: 2e:44:10:2a:b5:8c:b8:54:19:45:1c:8e:19:d9:ac:f3:66:2c:af:bc:61:4b:6a:53:96:0a:30:f7:d0:e2:eb:41 -----BEGIN CERTIFICATE----- MIIFszCCA5ugAwIBAgIUEwLV4kBMkkaGFmddtLu7sms+/BMwDQYJKoZIhvcNAQEL BQAwYTELMAkGA1UEBhMCVE4xNzA1BgNVBAoMLkFnZW5jZSBOYXRpb25hbGUgZGUg Q2VydGlmaWNhdGlvbiBFbGVjdHJvbmlxdWUxGTAXBgNVBAMMEFR1blRydXN0IFJv b3QgQ0EwHhcNMTkwNDI2MDg1NzU2WhcNNDQwNDI2MDg1NzU2WjBhMQswCQYDVQQG EwJUTjE3MDUGA1UECgwuQWdlbmNlIE5hdGlvbmFsZSBkZSBDZXJ0aWZpY2F0aW9u IEVsZWN0cm9uaXF1ZTEZMBcGA1UEAwwQVHVuVHJ1c3QgUm9vdCBDQTCCAiIwDQYJ KoZIhvcNAQEBBQADggIPADCCAgoCggIBAMPN0/y9BFPdDCA61YguBUtB9YOCfvdZ n56eY+hz2vYGqU8ftPkLHzmMmiDQfgbU7DTZhrx1W4eI8NLZ1KMKsmwb60ksPqxd 2JQDoOw05TDENX37Jk0bbjBU2PWARZw5rZzJJQRNmpA+TkBuimvNKWfGzC3gdOgF VwpIUPp6Q9p+7FuaDmJ2/uqdHYVy7BG7NegfJ7/Boce7SBbdVtfMTqDhuazb1YMZ GoXRlJfXyqNlC/M4+QKu3fZnz8k/9YosRxqZbwUN/dAdgjH8KcwAWJeRTIAAHDOF li/LQcKLEITDCSSJH7UP2dl3RxiSlGBcx5kDPP73lad9UKGAwqmDrViWVSHbhlnU r8a83YFuB9tgYv7sEG7aaAH0gxupPqJbI9dkxt/con3YS7qC0lH4Zr8GRuR5KiY2 eY8fTpkdso8MDhz/yV3A/ZAQprE38806JG60hZC/gLkMjNWb1sjxVj8agIl6qeIb MlEsPvLfe/ZdeikZjuXIvTZxi11Mwh0/rViizz1wTaZQmCXcI/m4WEEIcb9PuISg jwBUFfyRbVinljvrS5YnzWuioYasDXxU5mZMZl+QviGaAkYt5IPCgLnPSz7ofzwB 7I9ezX/SKEIBlYrilz0QIX32nRzFNKHsLA4KUiwSVXAkPcvCFDVDXSdOvsC9qnyW 5/yeYa1E0wCXAgMBAAGjYzBhMB0GA1UdDgQWBBQGmpsfU33x9aTI04Y+oXNZtPdE ITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFAaamx9TffH1pMjThj6hc1m0 90QhMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAqgVutt0Vyb+z xiD2BkewhpMl0425yAA/l/VSJ4hxyXT968pk21vvHl26v9Hr7lxpuhbI87mP0zYu QEkHDVneixCwSQXi/5E/S7fdAo74gShczNxtr18UnH1YeA32gAm56Q6XKRm4t+v4 FstVEuTGfbvE7Pi1HE4+Z7/FXxttbUcoqgRYYdZ2vyJ/0Adqp2RT8JeNnYA/u8EH 22Wv5psymsNUk8QcCMNE+3tjEUPRahphanltkE8pjkcFwRJpadbGNjHh/PqAulxP xOu3Mqz4dWEX1xAZufHSCe96Qp1bWgvUxpVOKs7/B9dPfhgGiPEZtdmYu65xxBzn dFlY7wyJz4sfdZMaBBSSSFCp61cpABbjNhzI+L/wM9VBD8TMPN3pM0MBkRArHtG5 Xc0yGYuPjCB31yLEQtyEFpslbei0VXF/sHyz03FJuc9SpAQ/3D2gu68zngowYI7b nV2UqL1g52KAdoGDDIzMMEZJ4gzSqK/rYXHv5yJiqfdcZGyfFoxnNidF9Ql7v/YQ CvGwjVRDjAS6oz/v4jXH+XTgbzRB0L9zZVcg+ZtnemZoJE6AZb0QmQZZ8mWvuMZH u/2QeItBcy6vVR/cO5JyboTT0GFMDcx2V+IthSIVNg3rAZ3r2OvEhJn7wAzMMujj d9qDRIueVSjAi1jTkD5OGwDxFa2DK5o= -----END CERTIFICATE----- # Issuer: CN=HARICA TLS RSA Root CA 2021 O=Hellenic Academic and Research Institutions CA # Subject: CN=HARICA TLS RSA Root CA 2021 O=Hellenic Academic and Research Institutions CA # Label: "HARICA TLS RSA Root CA 2021" # Serial: 76817823531813593706434026085292783742 # MD5 Fingerprint: 65:47:9b:58:86:dd:2c:f0:fc:a2:84:1f:1e:96:c4:91 # SHA1 Fingerprint: 02:2d:05:82:fa:88:ce:14:0c:06:79:de:7f:14:10:e9:45:d7:a5:6d # SHA256 Fingerprint: d9:5d:0e:8e:da:79:52:5b:f9:be:b1:1b:14:d2:10:0d:32:94:98:5f:0c:62:d9:fa:bd:9c:d9:99:ec:cb:7b:1d -----BEGIN CERTIFICATE----- MIIFpDCCA4ygAwIBAgIQOcqTHO9D88aOk8f0ZIk4fjANBgkqhkiG9w0BAQsFADBs MQswCQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl c2VhcmNoIEluc3RpdHV0aW9ucyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBSU0Eg Um9vdCBDQSAyMDIxMB4XDTIxMDIxOTEwNTUzOFoXDTQ1MDIxMzEwNTUzN1owbDEL MAkGA1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNl YXJjaCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgUlNBIFJv b3QgQ0EgMjAyMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAIvC569l mwVnlskNJLnQDmT8zuIkGCyEf3dRywQRNrhe7Wlxp57kJQmXZ8FHws+RFjZiPTgE 4VGC/6zStGndLuwRo0Xua2s7TL+MjaQenRG56Tj5eg4MmOIjHdFOY9TnuEFE+2uv a9of08WRiFukiZLRgeaMOVig1mlDqa2YUlhu2wr7a89o+uOkXjpFc5gH6l8Cct4M pbOfrqkdtx2z/IpZ525yZa31MJQjB/OCFks1mJxTuy/K5FrZx40d/JiZ+yykgmvw Kh+OC19xXFyuQnspiYHLA6OZyoieC0AJQTPb5lh6/a6ZcMBaD9YThnEvdmn8kN3b LW7R8pv1GmuebxWMevBLKKAiOIAkbDakO/IwkfN4E8/BPzWr8R0RI7VDIp4BkrcY AuUR0YLbFQDMYTfBKnya4dC6s1BG7oKsnTH4+yPiAwBIcKMJJnkVU2DzOFytOOqB AGMUuTNe3QvboEUHGjMJ+E20pwKmafTCWQWIZYVWrkvL4N48fS0ayOn7H6NhStYq E613TBoYm5EPWNgGVMWX+Ko/IIqmhaZ39qb8HOLubpQzKoNQhArlT4b4UEV4AIHr W2jjJo3Me1xR9BQsQL4aYB16cmEdH2MtiKrOokWQCPxrvrNQKlr9qEgYRtaQQJKQ CoReaDH46+0N0x3GfZkYVVYnZS6NRcUk7M7jAgMBAAGjQjBAMA8GA1UdEwEB/wQF MAMBAf8wHQYDVR0OBBYEFApII6ZgpJIKM+qTW8VX6iVNvRLuMA4GA1UdDwEB/wQE AwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAPpBIqm5iFSVmewzVjIuJndftTgfvnNAU X15QvWiWkKQUEapobQk1OUAJ2vQJLDSle1mESSmXdMgHHkdt8s4cUCbjnj1AUz/3 f5Z2EMVGpdAgS1D0NTsY9FVqQRtHBmg8uwkIYtlfVUKqrFOFrJVWNlar5AWMxaja H6NpvVMPxP/cyuN+8kyIhkdGGvMA9YCRotxDQpSbIPDRzbLrLFPCU3hKTwSUQZqP JzLB5UkZv/HywouoCjkxKLR9YjYsTewfM7Z+d21+UPCfDtcRj88YxeMn/ibvBZ3P zzfF0HvaO7AWhAw6k9a+F9sPPg4ZeAnHqQJyIkv3N3a6dcSFA1pj1bF1BcK5vZSt jBWZp5N99sXzqnTPBIWUmAD04vnKJGW/4GKvyMX6ssmeVkjaef2WdhW+o45WxLM0 /L5H9MG0qPzVMIho7suuyWPEdr6sOBjhXlzPrjoiUevRi7PzKzMHVIf6tLITe7pT BGIBnfHAT+7hOtSLIBD6Alfm78ELt5BGnBkpjNxvoEppaZS3JGWg/6w/zgH7IS79 aPib8qXPMThcFarmlwDB31qlpzmq6YR/PFGoOtmUW4y/Twhx5duoXNTSpv4Ao8YW xw/ogM4cKGR0GQjTQuPOAF1/sdwTsOEFy9EgqoZ0njnnkf3/W9b3raYvAwtt41dU 63ZTGI0RmLo= -----END CERTIFICATE----- # Issuer: CN=HARICA TLS ECC Root CA 2021 O=Hellenic Academic and Research Institutions CA # Subject: CN=HARICA TLS ECC Root CA 2021 O=Hellenic Academic and Research Institutions CA # Label: "HARICA TLS ECC Root CA 2021" # Serial: 137515985548005187474074462014555733966 # MD5 Fingerprint: ae:f7:4c:e5:66:35:d1:b7:9b:8c:22:93:74:d3:4b:b0 # SHA1 Fingerprint: bc:b0:c1:9d:e9:98:92:70:19:38:57:e9:8d:a7:b4:5d:6e:ee:01:48 # SHA256 Fingerprint: 3f:99:cc:47:4a:cf:ce:4d:fe:d5:87:94:66:5e:47:8d:15:47:73:9f:2e:78:0f:1b:b4:ca:9b:13:30:97:d4:01 -----BEGIN CERTIFICATE----- MIICVDCCAdugAwIBAgIQZ3SdjXfYO2rbIvT/WeK/zjAKBggqhkjOPQQDAzBsMQsw CQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2Vh cmNoIEluc3RpdHV0aW9ucyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBFQ0MgUm9v dCBDQSAyMDIxMB4XDTIxMDIxOTExMDExMFoXDTQ1MDIxMzExMDEwOVowbDELMAkG A1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJj aCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgRUNDIFJvb3Qg Q0EgMjAyMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABDgI/rGgltJ6rK9JOtDA4MM7 KKrxcm1lAEeIhPyaJmuqS7psBAqIXhfyVYf8MLA04jRYVxqEU+kw2anylnTDUR9Y STHMmE5gEYd103KUkE+bECUqqHgtvpBBWJAVcqeht6NCMEAwDwYDVR0TAQH/BAUw AwEB/zAdBgNVHQ4EFgQUyRtTgRL+BNUW0aq8mm+3oJUZbsowDgYDVR0PAQH/BAQD AgGGMAoGCCqGSM49BAMDA2cAMGQCMBHervjcToiwqfAircJRQO9gcS3ujwLEXQNw SaSS6sUUiHCm0w2wqsosQJz76YJumgIwK0eaB8bRwoF8yguWGEEbo/QwCZ61IygN nxS2PFOiTAZpffpskcYqSUXm7LcT4Tps -----END CERTIFICATE----- ================================================ FILE: lib/Google/vendor/grpc/grpc/src/lib/AbstractCall.php ================================================ add($delta); } else { $deadline = Timeval::infFuture(); } $this->call = new Call($channel, $method, $deadline); $this->deserialize = $deserialize; $this->metadata = null; $this->trailing_metadata = null; if (array_key_exists('call_credentials_callback', $options) && is_callable($call_credentials_callback = $options['call_credentials_callback']) ) { $call_credentials = CallCredentials::createFromPlugin( $call_credentials_callback ); $this->call->setCredentials($call_credentials); } } /** * @return mixed The metadata sent by the server */ public function getMetadata() { return $this->metadata; } /** * @return mixed The trailing metadata sent by the server */ public function getTrailingMetadata() { return $this->trailing_metadata; } /** * @return string The URI of the endpoint */ public function getPeer() { return $this->call->getPeer(); } /** * Cancels the call. */ public function cancel() { $this->call->cancel(); } /** * Serialize a message to the protobuf binary format. * * @param mixed $data The Protobuf message * * @return string The protobuf binary format */ protected function _serializeMessage($data) { // Proto3 implementation return $data->serializeToString(); } /** * Deserialize a response value to an object. * * @param string $value The binary value to deserialize * * @return mixed The deserialized value */ protected function _deserializeResponse($value) { if ($value === null) { return; } list($className, $deserializeFunc) = $this->deserialize; $obj = new $className(); $obj->mergeFromString($value); return $obj; } /** * Set the CallCredentials for the underlying Call. * * @param CallCredentials $call_credentials The CallCredentials object */ public function setCallCredentials($call_credentials) { $this->call->setCredentials($call_credentials); } } ================================================ FILE: lib/Google/vendor/grpc/grpc/src/lib/BaseStub.php ================================================ hostname = $hostname; $this->update_metadata = null; if (isset($opts['update_metadata'])) { if (is_callable($opts['update_metadata'])) { $this->update_metadata = $opts['update_metadata']; } unset($opts['update_metadata']); } if (!empty($opts['grpc.ssl_target_name_override'])) { $this->hostname_override = $opts['grpc.ssl_target_name_override']; } if (isset($opts['grpc_call_invoker'])) { $this->call_invoker = $opts['grpc_call_invoker']; unset($opts['grpc_call_invoker']); $channel_opts = $this->updateOpts($opts); // If the grpc_call_invoker is defined, use the channel created by the call invoker. $this->channel = $this->call_invoker->createChannelFactory($hostname, $channel_opts); return; } $this->call_invoker = new DefaultCallInvoker(); if ($channel) { if (!is_a($channel, 'Grpc\Channel') && !is_a($channel, 'Grpc\Internal\InterceptorChannel')) { throw new \Exception('The channel argument is not a Channel object '. 'or an InterceptorChannel object created by '. 'Interceptor::intercept($channel, Interceptor|Interceptor[] $interceptors)'); } $this->channel = $channel; return; } $this->channel = static::getDefaultChannel($hostname, $opts); } private static function updateOpts($opts) { if (!empty($opts['grpc.primary_user_agent'])) { $opts['grpc.primary_user_agent'] .= ' '; } else { $opts['grpc.primary_user_agent'] = ''; } if (defined('\Grpc\VERSION')) { $version_str = \Grpc\VERSION; } else { if (!file_exists($composerFile = __DIR__.'/../../composer.json')) { // for grpc/grpc-php subpackage $composerFile = __DIR__.'/../composer.json'; } $package_config = json_decode(file_get_contents($composerFile), true); $version_str = $package_config['version']; } $opts['grpc.primary_user_agent'] .= 'grpc-php/'.$version_str; if (!array_key_exists('credentials', $opts)) { throw new \Exception("The opts['credentials'] key is now ". 'required. Please see one of the '. 'ChannelCredentials::create methods'); } return $opts; } /** * Creates and returns the default Channel * * @param array $opts Channel constructor options * * @return Channel The channel */ public static function getDefaultChannel($hostname, array $opts) { $channel_opts = self::updateOpts($opts); return new Channel($hostname, $channel_opts); } /** * @return string The URI of the endpoint */ public function getTarget() { return $this->channel->getTarget(); } /** * @param bool $try_to_connect (optional) * * @return int The grpc connectivity state */ public function getConnectivityState($try_to_connect = false) { return $this->channel->getConnectivityState($try_to_connect); } /** * @param int $timeout in microseconds * * @return bool true if channel is ready * @throws Exception if channel is in FATAL_ERROR state */ public function waitForReady($timeout) { $new_state = $this->getConnectivityState(true); if ($this->_checkConnectivityState($new_state)) { return true; } $now = Timeval::now(); $delta = new Timeval($timeout); $deadline = $now->add($delta); while ($this->channel->watchConnectivityState($new_state, $deadline)) { // state has changed before deadline $new_state = $this->getConnectivityState(); if ($this->_checkConnectivityState($new_state)) { return true; } } // deadline has passed $new_state = $this->getConnectivityState(); return $this->_checkConnectivityState($new_state); } /** * Close the communication channel associated with this stub. */ public function close() { $this->channel->close(); } /** * @param $new_state Connect state * * @return bool true if state is CHANNEL_READY * @throws Exception if state is CHANNEL_FATAL_FAILURE */ private function _checkConnectivityState($new_state) { if ($new_state == \Grpc\CHANNEL_READY) { return true; } if ($new_state == \Grpc\CHANNEL_FATAL_FAILURE) { throw new \Exception('Failed to connect to server'); } return false; } /** * constructs the auth uri for the jwt. * * @param string $method The method string * * @return string The URL string */ private function _get_jwt_aud_uri($method) { // TODO(jtattermusch): This is not the correct implementation // of extracting JWT "aud" claim. We should rely on // grpc_metadata_credentials_plugin which // also provides the correct value of "aud" claim // in the grpc_auth_metadata_context.service_url field. // Trying to do the construction of "aud" field ourselves // is bad. $last_slash_idx = strrpos($method, '/'); if ($last_slash_idx === false) { throw new \InvalidArgumentException( 'service name must have a slash' ); } $service_name = substr($method, 0, $last_slash_idx); if ($this->hostname_override) { $hostname = $this->hostname_override; } else { $hostname = $this->hostname; } // Remove the port if it is 443 // See https://github.com/grpc/grpc/blob/07c9f7a36b2a0d34fcffebc85649cf3b8c339b5d/src/core/filter/auth/client_auth_filter.cc#L205 if ((strlen($hostname) > 4) && (substr($hostname, -4) === ":443")) { $hostname = substr($hostname, 0, -4); } return 'https://'.$hostname.$service_name; } /** * validate and normalize the metadata array. * * @param array $metadata The metadata map * * @return array $metadata Validated and key-normalized metadata map * @throws InvalidArgumentException if key contains invalid characters */ private function _validate_and_normalize_metadata($metadata) { $metadata_copy = []; foreach ($metadata as $key => $value) { if (!preg_match('/^[.A-Za-z\d_-]+$/', $key)) { throw new \InvalidArgumentException( 'Metadata keys must be nonempty strings containing only '. 'alphanumeric characters, hyphens, underscores and dots' ); } $metadata_copy[strtolower($key)] = $value; } return $metadata_copy; } /** * Create a function which can be used to create UnaryCall * * @param Channel|InterceptorChannel $channel * @param callable $deserialize A function that deserializes the response * * @return \Closure */ private function _GrpcUnaryUnary($channel) { return function ($method, $argument, $deserialize, array $metadata = [], array $options = []) use ($channel) { $call = $this->call_invoker->UnaryCall( $channel, $method, $deserialize, $options ); $jwt_aud_uri = $this->_get_jwt_aud_uri($method); if (is_callable($this->update_metadata)) { $metadata = call_user_func( $this->update_metadata, $metadata, $jwt_aud_uri ); } $metadata = $this->_validate_and_normalize_metadata( $metadata ); $call->start($argument, $metadata, $options); return $call; }; } /** * Create a function which can be used to create ServerStreamingCall * * @param Channel|InterceptorChannel $channel * @param callable $deserialize A function that deserializes the response * * @return \Closure */ private function _GrpcStreamUnary($channel) { return function ($method, $deserialize, array $metadata = [], array $options = []) use ($channel) { $call = $this->call_invoker->ClientStreamingCall( $channel, $method, $deserialize, $options ); $jwt_aud_uri = $this->_get_jwt_aud_uri($method); if (is_callable($this->update_metadata)) { $metadata = call_user_func( $this->update_metadata, $metadata, $jwt_aud_uri ); } $metadata = $this->_validate_and_normalize_metadata( $metadata ); $call->start($metadata); return $call; }; } /** * Create a function which can be used to create ClientStreamingCall * * @param Channel|InterceptorChannel $channel * @param callable $deserialize A function that deserializes the response * * @return \Closure */ private function _GrpcUnaryStream($channel) { return function ($method, $argument, $deserialize, array $metadata = [], array $options = []) use ($channel) { $call = $this->call_invoker->ServerStreamingCall( $channel, $method, $deserialize, $options ); $jwt_aud_uri = $this->_get_jwt_aud_uri($method); if (is_callable($this->update_metadata)) { $metadata = call_user_func( $this->update_metadata, $metadata, $jwt_aud_uri ); } $metadata = $this->_validate_and_normalize_metadata( $metadata ); $call->start($argument, $metadata, $options); return $call; }; } /** * Create a function which can be used to create BidiStreamingCall * * @param Channel|InterceptorChannel $channel * @param callable $deserialize A function that deserializes the response * * @return \Closure */ private function _GrpcStreamStream($channel) { return function ($method, $deserialize, array $metadata = [], array $options = []) use ($channel) { $call = $this->call_invoker->BidiStreamingCall( $channel, $method, $deserialize, $options ); $jwt_aud_uri = $this->_get_jwt_aud_uri($method); if (is_callable($this->update_metadata)) { $metadata = call_user_func( $this->update_metadata, $metadata, $jwt_aud_uri ); } $metadata = $this->_validate_and_normalize_metadata( $metadata ); $call->start($metadata); return $call; }; } /** * Create a function which can be used to create UnaryCall * * @param Channel|InterceptorChannel $channel * @param callable $deserialize A function that deserializes the response * * @return \Closure */ private function _UnaryUnaryCallFactory($channel) { if (is_a($channel, 'Grpc\Internal\InterceptorChannel')) { return function ($method, $argument, $deserialize, array $metadata = [], array $options = []) use ($channel) { return $channel->getInterceptor()->interceptUnaryUnary( $method, $argument, $deserialize, $this->_UnaryUnaryCallFactory($channel->getNext()), $metadata, $options ); }; } return $this->_GrpcUnaryUnary($channel); } /** * Create a function which can be used to create ServerStreamingCall * * @param Channel|InterceptorChannel $channel * @param callable $deserialize A function that deserializes the response * * @return \Closure */ private function _UnaryStreamCallFactory($channel) { if (is_a($channel, 'Grpc\Internal\InterceptorChannel')) { return function ($method, $argument, $deserialize, array $metadata = [], array $options = []) use ($channel) { return $channel->getInterceptor()->interceptUnaryStream( $method, $argument, $deserialize, $this->_UnaryStreamCallFactory($channel->getNext()), $metadata, $options ); }; } return $this->_GrpcUnaryStream($channel); } /** * Create a function which can be used to create ClientStreamingCall * * @param Channel|InterceptorChannel $channel * @param callable $deserialize A function that deserializes the response * * @return \Closure */ private function _StreamUnaryCallFactory($channel) { if (is_a($channel, 'Grpc\Internal\InterceptorChannel')) { return function ($method, $deserialize, array $metadata = [], array $options = []) use ($channel) { return $channel->getInterceptor()->interceptStreamUnary( $method, $deserialize, $this->_StreamUnaryCallFactory($channel->getNext()), $metadata, $options ); }; } return $this->_GrpcStreamUnary($channel); } /** * Create a function which can be used to create BidiStreamingCall * * @param Channel|InterceptorChannel $channel * @param callable $deserialize A function that deserializes the response * * @return \Closure */ private function _StreamStreamCallFactory($channel) { if (is_a($channel, 'Grpc\Internal\InterceptorChannel')) { return function ($method, $deserialize, array $metadata = [], array $options = []) use ($channel) { return $channel->getInterceptor()->interceptStreamStream( $method, $deserialize, $this->_StreamStreamCallFactory($channel->getNext()), $metadata, $options ); }; } return $this->_GrpcStreamStream($channel); } /* This class is intended to be subclassed by generated code, so * all functions begin with "_" to avoid name collisions. */ /** * Call a remote method that takes a single argument and has a * single output. * * @param string $method The name of the method to call * @param mixed $argument The argument to the method * @param callable $deserialize A function that deserializes the response * @param array $metadata A metadata map to send to the server * (optional) * @param array $options An array of options (optional) * * @return UnaryCall The active call object */ protected function _simpleRequest( $method, $argument, $deserialize, array $metadata = [], array $options = [] ) { $call_factory = $this->_UnaryUnaryCallFactory($this->channel); $call = $call_factory($method, $argument, $deserialize, $metadata, $options); return $call; } /** * Call a remote method that takes a stream of arguments and has a single * output. * * @param string $method The name of the method to call * @param callable $deserialize A function that deserializes the response * @param array $metadata A metadata map to send to the server * (optional) * @param array $options An array of options (optional) * * @return ClientStreamingCall The active call object */ protected function _clientStreamRequest( $method, $deserialize, array $metadata = [], array $options = [] ) { $call_factory = $this->_StreamUnaryCallFactory($this->channel); $call = $call_factory($method, $deserialize, $metadata, $options); return $call; } /** * Call a remote method that takes a single argument and returns a stream * of responses. * * @param string $method The name of the method to call * @param mixed $argument The argument to the method * @param callable $deserialize A function that deserializes the responses * @param array $metadata A metadata map to send to the server * (optional) * @param array $options An array of options (optional) * * @return ServerStreamingCall The active call object */ protected function _serverStreamRequest( $method, $argument, $deserialize, array $metadata = [], array $options = [] ) { $call_factory = $this->_UnaryStreamCallFactory($this->channel); $call = $call_factory($method, $argument, $deserialize, $metadata, $options); return $call; } /** * Call a remote method with messages streaming in both directions. * * @param string $method The name of the method to call * @param callable $deserialize A function that deserializes the responses * @param array $metadata A metadata map to send to the server * (optional) * @param array $options An array of options (optional) * * @return BidiStreamingCall The active call object */ protected function _bidiRequest( $method, $deserialize, array $metadata = [], array $options = [] ) { $call_factory = $this->_StreamStreamCallFactory($this->channel); $call = $call_factory($method, $deserialize, $metadata, $options); return $call; } } ================================================ FILE: lib/Google/vendor/grpc/grpc/src/lib/BidiStreamingCall.php ================================================ call->startBatch([ OP_SEND_INITIAL_METADATA => $metadata, ]); } /** * Reads the next value from the server. * * @return mixed The next value from the server, or null if there is none */ public function read() { $batch = [OP_RECV_MESSAGE => true]; if ($this->metadata === null) { $batch[OP_RECV_INITIAL_METADATA] = true; } $read_event = $this->call->startBatch($batch); if ($this->metadata === null) { $this->metadata = $read_event->metadata; } return $this->_deserializeResponse($read_event->message); } /** * Write a single message to the server. This cannot be called after * writesDone is called. * * @param ByteBuffer $data The data to write * @param array $options An array of options, possible keys: * 'flags' => a number (optional) */ public function write($data, array $options = []) { $message_array = ['message' => $this->_serializeMessage($data)]; if (array_key_exists('flags', $options)) { $message_array['flags'] = $options['flags']; } $this->call->startBatch([ OP_SEND_MESSAGE => $message_array, ]); } /** * Indicate that no more writes will be sent. */ public function writesDone() { $this->call->startBatch([ OP_SEND_CLOSE_FROM_CLIENT => true, ]); } /** * Wait for the server to send the status, and return it. * * @return \stdClass The status object, with integer $code, string * $details, and array $metadata members */ public function getStatus() { $status_event = $this->call->startBatch([ OP_RECV_STATUS_ON_CLIENT => true, ]); $this->trailing_metadata = $status_event->status->metadata; return $status_event->status; } } ================================================ FILE: lib/Google/vendor/grpc/grpc/src/lib/CallInvoker.php ================================================ call->startBatch([ OP_SEND_INITIAL_METADATA => $metadata, ]); } /** * Write a single message to the server. This cannot be called after * wait is called. * * @param ByteBuffer $data The data to write * @param array $options An array of options, possible keys: * 'flags' => a number (optional) */ public function write($data, array $options = []) { $message_array = ['message' => $this->_serializeMessage($data)]; if (array_key_exists('flags', $options)) { $message_array['flags'] = $options['flags']; } $this->call->startBatch([ OP_SEND_MESSAGE => $message_array, ]); } /** * Wait for the server to respond with data and a status. * * @return array [response data, status] */ public function wait() { $event = $this->call->startBatch([ OP_SEND_CLOSE_FROM_CLIENT => true, OP_RECV_INITIAL_METADATA => true, OP_RECV_MESSAGE => true, OP_RECV_STATUS_ON_CLIENT => true, ]); $this->metadata = $event->metadata; $status = $event->status; $this->trailing_metadata = $status->metadata; return [$this->_deserializeResponse($event->message), $status]; } } ================================================ FILE: lib/Google/vendor/grpc/grpc/src/lib/DefaultCallInvoker.php ================================================ = 0; $i--) { $channel = new Internal\InterceptorChannel($channel, $interceptors[$i]); } } else { $channel = new Internal\InterceptorChannel($channel, $interceptors); } return $channel; } } ================================================ FILE: lib/Google/vendor/grpc/grpc/src/lib/Internal/InterceptorChannel.php ================================================ interceptor = $interceptor; $this->next = $channel; } public function getNext() { return $this->next; } public function getInterceptor() { return $this->interceptor; } public function getTarget() { return $this->getNext()->getTarget(); } public function watchConnectivityState($new_state, $deadline) { return $this->getNext()->watchConnectivityState($new_state, $deadline); } public function getConnectivityState($try_to_connect = false) { return $this->getNext()->getConnectivityState($try_to_connect); } public function close() { return $this->getNext()->close(); } } ================================================ FILE: lib/Google/vendor/grpc/grpc/src/lib/MethodDescriptor.php ================================================ service = $service; $this->method_name = $method_name; $this->request_type = $request_type; $this->call_type = $call_type; } public const UNARY_CALL = 0; public const SERVER_STREAMING_CALL = 1; public const CLIENT_STREAMING_CALL = 2; public const BIDI_STREAMING_CALL = 3; public $service; public $method_name; public $request_type; public $call_type; } ================================================ FILE: lib/Google/vendor/grpc/grpc/src/lib/RpcServer.php ================================================ => MethodDescriptor ] private $paths_map = []; private function waitForNextEvent() { return $this->requestCall(); } /** * Add a service to this server * * @param Object $service The service to be added */ public function handle($service) { $methodDescriptors = $service->getMethodDescriptors(); $exist_methods = array_intersect_key($this->paths_map, $methodDescriptors); if (!empty($exist_methods)) { fwrite(STDERR, "WARNING: " . 'override already registered methods: ' . implode(', ', array_keys($exist_methods)) . PHP_EOL); } $this->paths_map = array_merge($this->paths_map, $methodDescriptors); return $this->paths_map; } public function run() { $this->start(); while (true) try { // This blocks until the server receives a request $event = $this->waitForNextEvent(); $full_path = $event->method; $context = new ServerContext($event); $server_writer = new ServerCallWriter($event->call, $context); if (!array_key_exists($full_path, $this->paths_map)) { $context->setStatus(Status::unimplemented()); $server_writer->finish(); continue; }; $method_desc = $this->paths_map[$full_path]; $server_reader = new ServerCallReader( $event->call, $method_desc->request_type ); try { $this->processCall( $method_desc, $server_reader, $server_writer, $context ); } catch (\Exception $e) { $context->setStatus(Status::status( STATUS_INTERNAL, $e->getMessage() )); $server_writer->finish(); } } catch (\Exception $e) { fwrite(STDERR, "ERROR: " . $e->getMessage() . PHP_EOL); exit(1); } } private function processCall( MethodDescriptor $method_desc, ServerCallReader $server_reader, ServerCallWriter $server_writer, ServerContext $context ) { // Dispatch to actual server logic switch ($method_desc->call_type) { case MethodDescriptor::UNARY_CALL: $request = $server_reader->read(); $response = call_user_func( array($method_desc->service, $method_desc->method_name), $request ?? new $method_desc->request_type, $context ); $server_writer->finish($response); break; case MethodDescriptor::SERVER_STREAMING_CALL: $request = $server_reader->read(); call_user_func( array($method_desc->service, $method_desc->method_name), $request ?? new $method_desc->request_type, $server_writer, $context ); break; case MethodDescriptor::CLIENT_STREAMING_CALL: $response = call_user_func( array($method_desc->service, $method_desc->method_name), $server_reader, $context ); $server_writer->finish($response); break; case MethodDescriptor::BIDI_STREAMING_CALL: call_user_func( array($method_desc->service, $method_desc->method_name), $server_reader, $server_writer, $context ); break; default: throw new \Exception(); } } } ================================================ FILE: lib/Google/vendor/grpc/grpc/src/lib/ServerCallReader.php ================================================ call_ = $call; $this->request_type_ = $request_type; } public function read() { $event = $this->call_->startBatch([ OP_RECV_MESSAGE => true, ]); if ($event->message === null) { return null; } $data = new $this->request_type_; $data->mergeFromString($event->message); return $data; } private $call_; private $request_type_; } ================================================ FILE: lib/Google/vendor/grpc/grpc/src/lib/ServerCallWriter.php ================================================ call_ = $call; $this->serverContext_ = $serverContext; } public function start( $data = null, array $options = [] ) { $batch = []; $this->addSendInitialMetadataOpIfNotSent( $batch, $this->serverContext_->initialMetadata() ); $this->addSendMessageOpIfHasData($batch, $data, $options); $this->call_->startBatch($batch); } public function write( $data, array $options = [] ) { $batch = []; $this->addSendInitialMetadataOpIfNotSent( $batch, $this->serverContext_->initialMetadata() ); $this->addSendMessageOpIfHasData($batch, $data, $options); $this->call_->startBatch($batch); } public function finish( $data = null, array $options = [] ) { $batch = [ OP_SEND_STATUS_FROM_SERVER => $this->serverContext_->status() ?? Status::ok(), OP_RECV_CLOSE_ON_SERVER => true, ]; $this->addSendInitialMetadataOpIfNotSent( $batch, $this->serverContext_->initialMetadata() ); $this->addSendMessageOpIfHasData($batch, $data, $options); $this->call_->startBatch($batch); } //////////////////////////// private function addSendInitialMetadataOpIfNotSent( array &$batch, ?array $initialMetadata = null ) { if (!$this->initialMetadataSent_) { $batch[OP_SEND_INITIAL_METADATA] = $initialMetadata ?? []; $this->initialMetadataSent_ = true; } } private function addSendMessageOpIfHasData( array &$batch, $data = null, array $options = [] ) { if ($data) { $message_array = ['message' => $data->serializeToString()]; if (array_key_exists('flags', $options)) { $message_array['flags'] = $options['flags']; } $batch[OP_SEND_MESSAGE] = $message_array; } } private $call_; private $initialMetadataSent_ = false; private $serverContext_; } ================================================ FILE: lib/Google/vendor/grpc/grpc/src/lib/ServerContext.php ================================================ event = $event; } public function clientMetadata() { return $this->event->metadata; } public function deadline() { return $this->event->absolute_deadline; } public function host() { return $this->event->host; } public function method() { return $this->event->method; } public function setInitialMetadata($initialMetadata) { $this->initialMetadata_ = $initialMetadata; } public function initialMetadata() { return $this->initialMetadata_; } public function setStatus($status) { $this->status_ = $status; } public function status() { return $this->status_; } private $event; private $initialMetadata_; private $status_; } ================================================ FILE: lib/Google/vendor/grpc/grpc/src/lib/ServerStreamingCall.php ================================================ a number (optional) */ public function start($data, array $metadata = [], array $options = []) { $message_array = ['message' => $this->_serializeMessage($data)]; if (array_key_exists('flags', $options)) { $message_array['flags'] = $options['flags']; } $this->call->startBatch([ OP_SEND_INITIAL_METADATA => $metadata, OP_SEND_MESSAGE => $message_array, OP_SEND_CLOSE_FROM_CLIENT => true, ]); } /** * @return mixed An iterator of response values */ public function responses() { $batch = [OP_RECV_MESSAGE => true]; if ($this->metadata === null) { $batch[OP_RECV_INITIAL_METADATA] = true; } $read_event = $this->call->startBatch($batch); if ($this->metadata === null) { $this->metadata = $read_event->metadata; } $response = $read_event->message; while ($response !== null) { yield $this->_deserializeResponse($response); $response = $this->call->startBatch([ OP_RECV_MESSAGE => true, ])->message; } } /** * Wait for the server to send the status, and return it. * * @return \stdClass The status object, with integer $code, string * $details, and array $metadata members */ public function getStatus() { $status_event = $this->call->startBatch([ OP_RECV_STATUS_ON_CLIENT => true, ]); $this->trailing_metadata = $status_event->status->metadata; return $status_event->status; } /** * @return mixed The metadata sent by the server */ public function getMetadata() { if ($this->metadata === null) { $event = $this->call->startBatch([OP_RECV_INITIAL_METADATA => true]); $this->metadata = $event->metadata; } return $this->metadata; } } ================================================ FILE: lib/Google/vendor/grpc/grpc/src/lib/Status.php ================================================ $code, 'details' => $details, ]; if ($metadata) { $status['metadata'] = $metadata; } return $status; } public static function ok(?array $metadata = null): array { return Status::status(STATUS_OK, 'OK', $metadata); } public static function unimplemented(): array { return Status::status(STATUS_UNIMPLEMENTED, 'UNIMPLEMENTED'); } } ================================================ FILE: lib/Google/vendor/grpc/grpc/src/lib/UnaryCall.php ================================================ a number (optional) */ public function start($data, array $metadata = [], array $options = []) { $message_array = ['message' => $this->_serializeMessage($data)]; if (isset($options['flags'])) { $message_array['flags'] = $options['flags']; } $this->call->startBatch([ OP_SEND_INITIAL_METADATA => $metadata, OP_SEND_MESSAGE => $message_array, OP_SEND_CLOSE_FROM_CLIENT => true, ]); } /** * Wait for the server to respond with data and a status. * * @return array{0: T|null, 1: \stdClass} [response data, status] */ public function wait() { $batch = [ OP_RECV_MESSAGE => true, OP_RECV_STATUS_ON_CLIENT => true, ]; if ($this->metadata === null) { $batch[OP_RECV_INITIAL_METADATA] = true; } $event = $this->call->startBatch($batch); if ($this->metadata === null) { $this->metadata = $event->metadata; } $status = $event->status; $this->trailing_metadata = $status->metadata; return [$this->_deserializeResponse($event->message), $status]; } /** * @return mixed The metadata sent by the server */ public function getMetadata() { if ($this->metadata === null) { $event = $this->call->startBatch([OP_RECV_INITIAL_METADATA => true]); $this->metadata = $event->metadata; } return $this->metadata; } } ================================================ FILE: lib/Google/vendor/guzzlehttp/guzzle/CHANGELOG.md ================================================ # Change Log Please refer to [UPGRADING](UPGRADING.md) guide for upgrading to a major version. ## 7.10.0 - 2025-08-23 ### Added - Support for PHP 8.5 ### Changed - Adjusted `guzzlehttp/promises` version constraint to `^2.3` - Adjusted `guzzlehttp/psr7` version constraint to `^2.8` ## 7.9.3 - 2025-03-27 ### Changed - Remove explicit content-length header for GET requests - Improve compatibility with bad servers for boolean cookie values ## 7.9.2 - 2024-07-24 ### Fixed - Adjusted handler selection to use cURL if its version is 7.21.2 or higher, rather than 7.34.0 ## 7.9.1 - 2024-07-19 ### Fixed - Fix TLS 1.3 check for HTTP/2 requests ## 7.9.0 - 2024-07-18 ### Changed - Improve protocol version checks to provide feedback around unsupported protocols - Only select the cURL handler by default if 7.34.0 or higher is linked - Improved `CurlMultiHandler` to avoid busy wait if possible - Dropped support for EOL `guzzlehttp/psr7` v1 - Improved URI user info redaction in errors ## 7.8.2 - 2024-07-18 ### Added - Support for PHP 8.4 ## 7.8.1 - 2023-12-03 ### Changed - Updated links in docs to their canonical versions - Replaced `call_user_func*` with native calls ## 7.8.0 - 2023-08-27 ### Added - Support for PHP 8.3 - Added automatic closing of handles on `CurlFactory` object destruction ## 7.7.1 - 2023-08-27 ### Changed - Remove the need for `AllowDynamicProperties` in `CurlMultiHandler` ## 7.7.0 - 2023-05-21 ### Added - Support `guzzlehttp/promises` v2 ## 7.6.1 - 2023-05-15 ### Fixed - Fix `SetCookie::fromString` MaxAge deprecation warning and skip invalid MaxAge values ## 7.6.0 - 2023-05-14 ### Added - Support for setting the minimum TLS version in a unified way - Apply on request the version set in options parameters ## 7.5.2 - 2023-05-14 ### Fixed - Fixed set cookie constructor validation - Fixed handling of files with `'0'` body ### Changed - Corrected docs and default connect timeout value to 300 seconds ## 7.5.1 - 2023-04-17 ### Fixed - Fixed `NO_PROXY` settings so that setting the `proxy` option to `no` overrides the env variable ### Changed - Adjusted `guzzlehttp/psr7` version constraint to `^1.9.1 || ^2.4.5` ## 7.5.0 - 2022-08-28 ### Added - Support PHP 8.2 - Add request to delay closure params ## 7.4.5 - 2022-06-20 ### Fixed * Fix change in port should be considered a change in origin * Fix `CURLOPT_HTTPAUTH` option not cleared on change of origin ## 7.4.4 - 2022-06-09 ### Fixed * Fix failure to strip Authorization header on HTTP downgrade * Fix failure to strip the Cookie header on change in host or HTTP downgrade ## 7.4.3 - 2022-05-25 ### Fixed * Fix cross-domain cookie leakage ## 7.4.2 - 2022-03-20 ### Fixed - Remove curl auth on cross-domain redirects to align with the Authorization HTTP header - Reject non-HTTP schemes in StreamHandler - Set a default ssl.peer_name context in StreamHandler to allow `force_ip_resolve` ## 7.4.1 - 2021-12-06 ### Changed - Replaced implicit URI to string coercion [#2946](https://github.com/guzzle/guzzle/pull/2946) - Allow `symfony/deprecation-contracts` version 3 [#2961](https://github.com/guzzle/guzzle/pull/2961) ### Fixed - Only close curl handle if it's done [#2950](https://github.com/guzzle/guzzle/pull/2950) ## 7.4.0 - 2021-10-18 ### Added - Support PHP 8.1 [#2929](https://github.com/guzzle/guzzle/pull/2929), [#2939](https://github.com/guzzle/guzzle/pull/2939) - Support `psr/log` version 2 and 3 [#2943](https://github.com/guzzle/guzzle/pull/2943) ### Fixed - Make sure we always call `restore_error_handler()` [#2915](https://github.com/guzzle/guzzle/pull/2915) - Fix progress parameter type compatibility between the cURL and stream handlers [#2936](https://github.com/guzzle/guzzle/pull/2936) - Throw `InvalidArgumentException` when an incorrect `headers` array is provided [#2916](https://github.com/guzzle/guzzle/pull/2916), [#2942](https://github.com/guzzle/guzzle/pull/2942) ### Changed - Be more strict with types [#2914](https://github.com/guzzle/guzzle/pull/2914), [#2917](https://github.com/guzzle/guzzle/pull/2917), [#2919](https://github.com/guzzle/guzzle/pull/2919), [#2945](https://github.com/guzzle/guzzle/pull/2945) ## 7.3.0 - 2021-03-23 ### Added - Support for DER and P12 certificates [#2413](https://github.com/guzzle/guzzle/pull/2413) - Support the cURL (http://) scheme for StreamHandler proxies [#2850](https://github.com/guzzle/guzzle/pull/2850) - Support for `guzzlehttp/psr7:^2.0` [#2878](https://github.com/guzzle/guzzle/pull/2878) ### Fixed - Handle exceptions on invalid header consistently between PHP versions and handlers [#2872](https://github.com/guzzle/guzzle/pull/2872) ## 7.2.0 - 2020-10-10 ### Added - Support for PHP 8 [#2712](https://github.com/guzzle/guzzle/pull/2712), [#2715](https://github.com/guzzle/guzzle/pull/2715), [#2789](https://github.com/guzzle/guzzle/pull/2789) - Support passing a body summarizer to the http errors middleware [#2795](https://github.com/guzzle/guzzle/pull/2795) ### Fixed - Handle exceptions during response creation [#2591](https://github.com/guzzle/guzzle/pull/2591) - Fix CURLOPT_ENCODING not to be overwritten [#2595](https://github.com/guzzle/guzzle/pull/2595) - Make sure the Request always has a body object [#2804](https://github.com/guzzle/guzzle/pull/2804) ### Changed - The `TooManyRedirectsException` has a response [#2660](https://github.com/guzzle/guzzle/pull/2660) - Avoid "functions" from dependencies [#2712](https://github.com/guzzle/guzzle/pull/2712) ### Deprecated - Using environment variable GUZZLE_CURL_SELECT_TIMEOUT [#2786](https://github.com/guzzle/guzzle/pull/2786) ## 7.1.1 - 2020-09-30 ### Fixed - Incorrect EOF detection for response body streams on Windows. ### Changed - We dont connect curl `sink` on HEAD requests. - Removed some PHP 5 workarounds ## 7.1.0 - 2020-09-22 ### Added - `GuzzleHttp\MessageFormatterInterface` ### Fixed - Fixed issue that caused cookies with no value not to be stored. - On redirects, we allow all safe methods like GET, HEAD and OPTIONS. - Fixed logging on empty responses. - Make sure MessageFormatter::format returns string ### Deprecated - All functions in `GuzzleHttp` has been deprecated. Use static methods on `Utils` instead. - `ClientInterface::getConfig()` - `Client::getConfig()` - `Client::__call()` - `Utils::defaultCaBundle()` - `CurlFactory::LOW_CURL_VERSION_NUMBER` ## 7.0.1 - 2020-06-27 * Fix multiply defined functions fatal error [#2699](https://github.com/guzzle/guzzle/pull/2699) ## 7.0.0 - 2020-06-27 No changes since 7.0.0-rc1. ## 7.0.0-rc1 - 2020-06-15 ### Changed * Use error level for logging errors in Middleware [#2629](https://github.com/guzzle/guzzle/pull/2629) * Disabled IDN support by default and require ext-intl to use it [#2675](https://github.com/guzzle/guzzle/pull/2675) ## 7.0.0-beta2 - 2020-05-25 ### Added * Using `Utils` class instead of functions in the `GuzzleHttp` namespace. [#2546](https://github.com/guzzle/guzzle/pull/2546) * `ClientInterface::MAJOR_VERSION` [#2583](https://github.com/guzzle/guzzle/pull/2583) ### Changed * Avoid the `getenv` function when unsafe [#2531](https://github.com/guzzle/guzzle/pull/2531) * Added real client methods [#2529](https://github.com/guzzle/guzzle/pull/2529) * Avoid functions due to global install conflicts [#2546](https://github.com/guzzle/guzzle/pull/2546) * Use Symfony intl-idn polyfill [#2550](https://github.com/guzzle/guzzle/pull/2550) * Adding methods for HTTP verbs like `Client::get()`, `Client::head()`, `Client::patch()` etc [#2529](https://github.com/guzzle/guzzle/pull/2529) * `ConnectException` extends `TransferException` [#2541](https://github.com/guzzle/guzzle/pull/2541) * Updated the default User Agent to "GuzzleHttp/7" [#2654](https://github.com/guzzle/guzzle/pull/2654) ### Fixed * Various intl icu issues [#2626](https://github.com/guzzle/guzzle/pull/2626) ### Removed * Pool option `pool_size` [#2528](https://github.com/guzzle/guzzle/pull/2528) ## 7.0.0-beta1 - 2019-12-30 The diff might look very big but 95% of Guzzle users will be able to upgrade without modification. Please see [the upgrade document](UPGRADING.md) that describes all BC breaking changes. ### Added * Implement PSR-18 and dropped PHP 5 support [#2421](https://github.com/guzzle/guzzle/pull/2421) [#2474](https://github.com/guzzle/guzzle/pull/2474) * PHP 7 types [#2442](https://github.com/guzzle/guzzle/pull/2442) [#2449](https://github.com/guzzle/guzzle/pull/2449) [#2466](https://github.com/guzzle/guzzle/pull/2466) [#2497](https://github.com/guzzle/guzzle/pull/2497) [#2499](https://github.com/guzzle/guzzle/pull/2499) * IDN support for redirects [2424](https://github.com/guzzle/guzzle/pull/2424) ### Changed * Dont allow passing null as third argument to `BadResponseException::__construct()` [#2427](https://github.com/guzzle/guzzle/pull/2427) * Use SAPI constant instead of method call [#2450](https://github.com/guzzle/guzzle/pull/2450) * Use native function invocation [#2444](https://github.com/guzzle/guzzle/pull/2444) * Better defaults for PHP installations with old ICU lib [2454](https://github.com/guzzle/guzzle/pull/2454) * Added visibility to all constants [#2462](https://github.com/guzzle/guzzle/pull/2462) * Dont allow passing `null` as URI to `Client::request()` and `Client::requestAsync()` [#2461](https://github.com/guzzle/guzzle/pull/2461) * Widen the exception argument to throwable [#2495](https://github.com/guzzle/guzzle/pull/2495) ### Fixed * Logging when Promise rejected with a string [#2311](https://github.com/guzzle/guzzle/pull/2311) ### Removed * Class `SeekException` [#2162](https://github.com/guzzle/guzzle/pull/2162) * `RequestException::getResponseBodySummary()` [#2425](https://github.com/guzzle/guzzle/pull/2425) * `CookieJar::getCookieValue()` [#2433](https://github.com/guzzle/guzzle/pull/2433) * `uri_template()` and `UriTemplate` [#2440](https://github.com/guzzle/guzzle/pull/2440) * Request options `save_to` and `exceptions` [#2464](https://github.com/guzzle/guzzle/pull/2464) ## 6.5.2 - 2019-12-23 * idn_to_ascii() fix for old PHP versions [#2489](https://github.com/guzzle/guzzle/pull/2489) ## 6.5.1 - 2019-12-21 * Better defaults for PHP installations with old ICU lib [#2454](https://github.com/guzzle/guzzle/pull/2454) * IDN support for redirects [#2424](https://github.com/guzzle/guzzle/pull/2424) ## 6.5.0 - 2019-12-07 * Improvement: Added support for reset internal queue in MockHandler. [#2143](https://github.com/guzzle/guzzle/pull/2143) * Improvement: Added support to pass arbitrary options to `curl_multi_init`. [#2287](https://github.com/guzzle/guzzle/pull/2287) * Fix: Gracefully handle passing `null` to the `header` option. [#2132](https://github.com/guzzle/guzzle/pull/2132) * Fix: `RetryMiddleware` did not do exponential delay between retires due unit mismatch. [#2132](https://github.com/guzzle/guzzle/pull/2132) * Fix: Prevent undefined offset when using array for ssl_key options. [#2348](https://github.com/guzzle/guzzle/pull/2348) * Deprecated `ClientInterface::VERSION` ## 6.4.1 - 2019-10-23 * No `guzzle.phar` was created in 6.4.0 due expired API token. This release will fix that * Added `parent::__construct()` to `FileCookieJar` and `SessionCookieJar` ## 6.4.0 - 2019-10-23 * Improvement: Improved error messages when using curl < 7.21.2 [#2108](https://github.com/guzzle/guzzle/pull/2108) * Fix: Test if response is readable before returning a summary in `RequestException::getResponseBodySummary()` [#2081](https://github.com/guzzle/guzzle/pull/2081) * Fix: Add support for GUZZLE_CURL_SELECT_TIMEOUT environment variable [#2161](https://github.com/guzzle/guzzle/pull/2161) * Improvement: Added `GuzzleHttp\Exception\InvalidArgumentException` [#2163](https://github.com/guzzle/guzzle/pull/2163) * Improvement: Added `GuzzleHttp\_current_time()` to use `hrtime()` if that function exists. [#2242](https://github.com/guzzle/guzzle/pull/2242) * Improvement: Added curl's `appconnect_time` in `TransferStats` [#2284](https://github.com/guzzle/guzzle/pull/2284) * Improvement: Make GuzzleException extend Throwable wherever it's available [#2273](https://github.com/guzzle/guzzle/pull/2273) * Fix: Prevent concurrent writes to file when saving `CookieJar` [#2335](https://github.com/guzzle/guzzle/pull/2335) * Improvement: Update `MockHandler` so we can test transfer time [#2362](https://github.com/guzzle/guzzle/pull/2362) ## 6.3.3 - 2018-04-22 * Fix: Default headers when decode_content is specified ## 6.3.2 - 2018-03-26 * Fix: Release process ## 6.3.1 - 2018-03-26 * Bug fix: Parsing 0 epoch expiry times in cookies [#2014](https://github.com/guzzle/guzzle/pull/2014) * Improvement: Better ConnectException detection [#2012](https://github.com/guzzle/guzzle/pull/2012) * Bug fix: Malformed domain that contains a "/" [#1999](https://github.com/guzzle/guzzle/pull/1999) * Bug fix: Undefined offset when a cookie has no first key-value pair [#1998](https://github.com/guzzle/guzzle/pull/1998) * Improvement: Support PHPUnit 6 [#1953](https://github.com/guzzle/guzzle/pull/1953) * Bug fix: Support empty headers [#1915](https://github.com/guzzle/guzzle/pull/1915) * Bug fix: Ignore case during header modifications [#1916](https://github.com/guzzle/guzzle/pull/1916) + Minor code cleanups, documentation fixes and clarifications. ## 6.3.0 - 2017-06-22 * Feature: force IP resolution (ipv4 or ipv6) [#1608](https://github.com/guzzle/guzzle/pull/1608), [#1659](https://github.com/guzzle/guzzle/pull/1659) * Improvement: Don't include summary in exception message when body is empty [#1621](https://github.com/guzzle/guzzle/pull/1621) * Improvement: Handle `on_headers` option in MockHandler [#1580](https://github.com/guzzle/guzzle/pull/1580) * Improvement: Added SUSE Linux CA path [#1609](https://github.com/guzzle/guzzle/issues/1609) * Improvement: Use class reference for getting the name of the class instead of using hardcoded strings [#1641](https://github.com/guzzle/guzzle/pull/1641) * Feature: Added `read_timeout` option [#1611](https://github.com/guzzle/guzzle/pull/1611) * Bug fix: PHP 7.x fixes [#1685](https://github.com/guzzle/guzzle/pull/1685), [#1686](https://github.com/guzzle/guzzle/pull/1686), [#1811](https://github.com/guzzle/guzzle/pull/1811) * Deprecation: BadResponseException instantiation without a response [#1642](https://github.com/guzzle/guzzle/pull/1642) * Feature: Added NTLM auth [#1569](https://github.com/guzzle/guzzle/pull/1569) * Feature: Track redirect HTTP status codes [#1711](https://github.com/guzzle/guzzle/pull/1711) * Improvement: Check handler type during construction [#1745](https://github.com/guzzle/guzzle/pull/1745) * Improvement: Always include the Content-Length if there's a body [#1721](https://github.com/guzzle/guzzle/pull/1721) * Feature: Added convenience method to access a cookie by name [#1318](https://github.com/guzzle/guzzle/pull/1318) * Bug fix: Fill `CURLOPT_CAPATH` and `CURLOPT_CAINFO` properly [#1684](https://github.com/guzzle/guzzle/pull/1684) * Improvement: Use `\GuzzleHttp\Promise\rejection_for` function instead of object init [#1827](https://github.com/guzzle/guzzle/pull/1827) + Minor code cleanups, documentation fixes and clarifications. ## 6.2.3 - 2017-02-28 * Fix deprecations with guzzle/psr7 version 1.4 ## 6.2.2 - 2016-10-08 * Allow to pass nullable Response to delay callable * Only add scheme when host is present * Fix drain case where content-length is the literal string zero * Obfuscate in-URL credentials in exceptions ## 6.2.1 - 2016-07-18 * Address HTTP_PROXY security vulnerability, CVE-2016-5385: https://httpoxy.org/ * Fixing timeout bug with StreamHandler: https://github.com/guzzle/guzzle/pull/1488 * Only read up to `Content-Length` in PHP StreamHandler to avoid timeouts when a server does not honor `Connection: close`. * Ignore URI fragment when sending requests. ## 6.2.0 - 2016-03-21 * Feature: added `GuzzleHttp\json_encode` and `GuzzleHttp\json_decode`. https://github.com/guzzle/guzzle/pull/1389 * Bug fix: Fix sleep calculation when waiting for delayed requests. https://github.com/guzzle/guzzle/pull/1324 * Feature: More flexible history containers. https://github.com/guzzle/guzzle/pull/1373 * Bug fix: defer sink stream opening in StreamHandler. https://github.com/guzzle/guzzle/pull/1377 * Bug fix: do not attempt to escape cookie values. https://github.com/guzzle/guzzle/pull/1406 * Feature: report original content encoding and length on decoded responses. https://github.com/guzzle/guzzle/pull/1409 * Bug fix: rewind seekable request bodies before dispatching to cURL. https://github.com/guzzle/guzzle/pull/1422 * Bug fix: provide an empty string to `http_build_query` for HHVM workaround. https://github.com/guzzle/guzzle/pull/1367 ## 6.1.1 - 2015-11-22 * Bug fix: Proxy::wrapSync() now correctly proxies to the appropriate handler https://github.com/guzzle/guzzle/commit/911bcbc8b434adce64e223a6d1d14e9a8f63e4e4 * Feature: HandlerStack is now more generic. https://github.com/guzzle/guzzle/commit/f2102941331cda544745eedd97fc8fd46e1ee33e * Bug fix: setting verify to false in the StreamHandler now disables peer verification. https://github.com/guzzle/guzzle/issues/1256 * Feature: Middleware now uses an exception factory, including more error context. https://github.com/guzzle/guzzle/pull/1282 * Feature: better support for disabled functions. https://github.com/guzzle/guzzle/pull/1287 * Bug fix: fixed regression where MockHandler was not using `sink`. https://github.com/guzzle/guzzle/pull/1292 ## 6.1.0 - 2015-09-08 * Feature: Added the `on_stats` request option to provide access to transfer statistics for requests. https://github.com/guzzle/guzzle/pull/1202 * Feature: Added the ability to persist session cookies in CookieJars. https://github.com/guzzle/guzzle/pull/1195 * Feature: Some compatibility updates for Google APP Engine https://github.com/guzzle/guzzle/pull/1216 * Feature: Added support for NO_PROXY to prevent the use of a proxy based on a simple set of rules. https://github.com/guzzle/guzzle/pull/1197 * Feature: Cookies can now contain square brackets. https://github.com/guzzle/guzzle/pull/1237 * Bug fix: Now correctly parsing `=` inside of quotes in Cookies. https://github.com/guzzle/guzzle/pull/1232 * Bug fix: Cusotm cURL options now correctly override curl options of the same name. https://github.com/guzzle/guzzle/pull/1221 * Bug fix: Content-Type header is now added when using an explicitly provided multipart body. https://github.com/guzzle/guzzle/pull/1218 * Bug fix: Now ignoring Set-Cookie headers that have no name. * Bug fix: Reason phrase is no longer cast to an int in some cases in the cURL handler. https://github.com/guzzle/guzzle/pull/1187 * Bug fix: Remove the Authorization header when redirecting if the Host header changes. https://github.com/guzzle/guzzle/pull/1207 * Bug fix: Cookie path matching fixes https://github.com/guzzle/guzzle/issues/1129 * Bug fix: Fixing the cURL `body_as_string` setting https://github.com/guzzle/guzzle/pull/1201 * Bug fix: quotes are no longer stripped when parsing cookies. https://github.com/guzzle/guzzle/issues/1172 * Bug fix: `form_params` and `query` now always uses the `&` separator. https://github.com/guzzle/guzzle/pull/1163 * Bug fix: Adding a Content-Length to PHP stream wrapper requests if not set. https://github.com/guzzle/guzzle/pull/1189 ## 6.0.2 - 2015-07-04 * Fixed a memory leak in the curl handlers in which references to callbacks were not being removed by `curl_reset`. * Cookies are now extracted properly before redirects. * Cookies now allow more character ranges. * Decoded Content-Encoding responses are now modified to correctly reflect their state if the encoding was automatically removed by a handler. This means that the `Content-Encoding` header may be removed an the `Content-Length` modified to reflect the message size after removing the encoding. * Added a more explicit error message when trying to use `form_params` and `multipart` in the same request. * Several fixes for HHVM support. * Functions are now conditionally required using an additional level of indirection to help with global Composer installations. ## 6.0.1 - 2015-05-27 * Fixed a bug with serializing the `query` request option where the `&` separator was missing. * Added a better error message for when `body` is provided as an array. Please use `form_params` or `multipart` instead. * Various doc fixes. ## 6.0.0 - 2015-05-26 * See the UPGRADING.md document for more information. * Added `multipart` and `form_params` request options. * Added `synchronous` request option. * Added the `on_headers` request option. * Fixed `expect` handling. * No longer adding default middlewares in the client ctor. These need to be present on the provided handler in order to work. * Requests are no longer initiated when sending async requests with the CurlMultiHandler. This prevents unexpected recursion from requests completing while ticking the cURL loop. * Removed the semantics of setting `default` to `true`. This is no longer required now that the cURL loop is not ticked for async requests. * Added request and response logging middleware. * No longer allowing self signed certificates when using the StreamHandler. * Ensuring that `sink` is valid if saving to a file. * Request exceptions now include a "handler context" which provides handler specific contextual information. * Added `GuzzleHttp\RequestOptions` to allow request options to be applied using constants. * `$maxHandles` has been removed from CurlMultiHandler. * `MultipartPostBody` is now part of the `guzzlehttp/psr7` package. ## 5.3.0 - 2015-05-19 * Mock now supports `save_to` * Marked `AbstractRequestEvent::getTransaction()` as public. * Fixed a bug in which multiple headers using different casing would overwrite previous headers in the associative array. * Added `Utils::getDefaultHandler()` * Marked `GuzzleHttp\Client::getDefaultUserAgent` as deprecated. * URL scheme is now always lowercased. ## 6.0.0-beta.1 * Requires PHP >= 5.5 * Updated to use PSR-7 * Requires immutable messages, which basically means an event based system owned by a request instance is no longer possible. * Utilizing the [Guzzle PSR-7 package](https://github.com/guzzle/psr7). * Removed the dependency on `guzzlehttp/streams`. These stream abstractions are available in the `guzzlehttp/psr7` package under the `GuzzleHttp\Psr7` namespace. * Added middleware and handler system * Replaced the Guzzle event and subscriber system with a middleware system. * No longer depends on RingPHP, but rather places the HTTP handlers directly in Guzzle, operating on PSR-7 messages. * Retry logic is now encapsulated in `GuzzleHttp\Middleware::retry`, which means the `guzzlehttp/retry-subscriber` is now obsolete. * Mocking responses is now handled using `GuzzleHttp\Handler\MockHandler`. * Asynchronous responses * No longer supports the `future` request option to send an async request. Instead, use one of the `*Async` methods of a client (e.g., `requestAsync`, `getAsync`, etc.). * Utilizing `GuzzleHttp\Promise` instead of React's promise library to avoid recursion required by chaining and forwarding react promises. See https://github.com/guzzle/promises * Added `requestAsync` and `sendAsync` to send request asynchronously. * Added magic methods for `getAsync()`, `postAsync()`, etc. to send requests asynchronously. * Request options * POST and form updates * Added the `form_fields` and `form_files` request options. * Removed the `GuzzleHttp\Post` namespace. * The `body` request option no longer accepts an array for POST requests. * The `exceptions` request option has been deprecated in favor of the `http_errors` request options. * The `save_to` request option has been deprecated in favor of `sink` request option. * Clients no longer accept an array of URI template string and variables for URI variables. You will need to expand URI templates before passing them into a client constructor or request method. * Client methods `get()`, `post()`, `put()`, `patch()`, `options()`, etc. are now magic methods that will send synchronous requests. * Replaced `Utils.php` with plain functions in `functions.php`. * Removed `GuzzleHttp\Collection`. * Removed `GuzzleHttp\BatchResults`. Batched pool results are now returned as an array. * Removed `GuzzleHttp\Query`. Query string handling is now handled using an associative array passed into the `query` request option. The query string is serialized using PHP's `http_build_query`. If you need more control, you can pass the query string in as a string. * `GuzzleHttp\QueryParser` has been replaced with the `GuzzleHttp\Psr7\parse_query`. ## 5.2.0 - 2015-01-27 * Added `AppliesHeadersInterface` to make applying headers to a request based on the body more generic and not specific to `PostBodyInterface`. * Reduced the number of stack frames needed to send requests. * Nested futures are now resolved in the client rather than the RequestFsm * Finishing state transitions is now handled in the RequestFsm rather than the RingBridge. * Added a guard in the Pool class to not use recursion for request retries. ## 5.1.0 - 2014-12-19 * Pool class no longer uses recursion when a request is intercepted. * The size of a Pool can now be dynamically adjusted using a callback. See https://github.com/guzzle/guzzle/pull/943. * Setting a request option to `null` when creating a request with a client will ensure that the option is not set. This allows you to overwrite default request options on a per-request basis. See https://github.com/guzzle/guzzle/pull/937. * Added the ability to limit which protocols are allowed for redirects by specifying a `protocols` array in the `allow_redirects` request option. * Nested futures due to retries are now resolved when waiting for synchronous responses. See https://github.com/guzzle/guzzle/pull/947. * `"0"` is now an allowed URI path. See https://github.com/guzzle/guzzle/pull/935. * `Query` no longer typehints on the `$query` argument in the constructor, allowing for strings and arrays. * Exceptions thrown in the `end` event are now correctly wrapped with Guzzle specific exceptions if necessary. ## 5.0.3 - 2014-11-03 This change updates query strings so that they are treated as un-encoded values by default where the value represents an un-encoded value to send over the wire. A Query object then encodes the value before sending over the wire. This means that even value query string values (e.g., ":") are url encoded. This makes the Query class match PHP's http_build_query function. However, if you want to send requests over the wire using valid query string characters that do not need to be encoded, then you can provide a string to Url::setQuery() and pass true as the second argument to specify that the query string is a raw string that should not be parsed or encoded (unless a call to getQuery() is subsequently made, forcing the query-string to be converted into a Query object). ## 5.0.2 - 2014-10-30 * Added a trailing `\r\n` to multipart/form-data payloads. See https://github.com/guzzle/guzzle/pull/871 * Added a `GuzzleHttp\Pool::send()` convenience method to match the docs. * Status codes are now returned as integers. See https://github.com/guzzle/guzzle/issues/881 * No longer overwriting an existing `application/x-www-form-urlencoded` header when sending POST requests, allowing for customized headers. See https://github.com/guzzle/guzzle/issues/877 * Improved path URL serialization. * No longer double percent-encoding characters in the path or query string if they are already encoded. * Now properly encoding the supplied path to a URL object, instead of only encoding ' ' and '?'. * Note: This has been changed in 5.0.3 to now encode query string values by default unless the `rawString` argument is provided when setting the query string on a URL: Now allowing many more characters to be present in the query string without being percent encoded. See https://datatracker.ietf.org/doc/html/rfc3986#appendix-A ## 5.0.1 - 2014-10-16 Bugfix release. * Fixed an issue where connection errors still returned response object in error and end events event though the response is unusable. This has been corrected so that a response is not returned in the `getResponse` method of these events if the response did not complete. https://github.com/guzzle/guzzle/issues/867 * Fixed an issue where transfer statistics were not being populated in the RingBridge. https://github.com/guzzle/guzzle/issues/866 ## 5.0.0 - 2014-10-12 Adding support for non-blocking responses and some minor API cleanup. ### New Features * Added support for non-blocking responses based on `guzzlehttp/guzzle-ring`. * Added a public API for creating a default HTTP adapter. * Updated the redirect plugin to be non-blocking so that redirects are sent concurrently. Other plugins like this can now be updated to be non-blocking. * Added a "progress" event so that you can get upload and download progress events. * Added `GuzzleHttp\Pool` which implements FutureInterface and transfers requests concurrently using a capped pool size as efficiently as possible. * Added `hasListeners()` to EmitterInterface. * Removed `GuzzleHttp\ClientInterface::sendAll` and marked `GuzzleHttp\Client::sendAll` as deprecated (it's still there, just not the recommended way). ### Breaking changes The breaking changes in this release are relatively minor. The biggest thing to look out for is that request and response objects no longer implement fluent interfaces. * Removed the fluent interfaces (i.e., `return $this`) from requests, responses, `GuzzleHttp\Collection`, `GuzzleHttp\Url`, `GuzzleHttp\Query`, `GuzzleHttp\Post\PostBody`, and `GuzzleHttp\Cookie\SetCookie`. This blog post provides a good outline of why I did this: https://ocramius.github.io/blog/fluent-interfaces-are-evil/. This also makes the Guzzle message interfaces compatible with the current PSR-7 message proposal. * Removed "functions.php", so that Guzzle is truly PSR-4 compliant. Except for the HTTP request functions from function.php, these functions are now implemented in `GuzzleHttp\Utils` using camelCase. `GuzzleHttp\json_decode` moved to `GuzzleHttp\Utils::jsonDecode`. `GuzzleHttp\get_path` moved to `GuzzleHttp\Utils::getPath`. `GuzzleHttp\set_path` moved to `GuzzleHttp\Utils::setPath`. `GuzzleHttp\batch` should now be `GuzzleHttp\Pool::batch`, which returns an `objectStorage`. Using functions.php caused problems for many users: they aren't PSR-4 compliant, require an explicit include, and needed an if-guard to ensure that the functions are not declared multiple times. * Rewrote adapter layer. * Removing all classes from `GuzzleHttp\Adapter`, these are now implemented as callables that are stored in `GuzzleHttp\Ring\Client`. * Removed the concept of "parallel adapters". Sending requests serially or concurrently is now handled using a single adapter. * Moved `GuzzleHttp\Adapter\Transaction` to `GuzzleHttp\Transaction`. The Transaction object now exposes the request, response, and client as public properties. The getters and setters have been removed. * Removed the "headers" event. This event was only useful for changing the body a response once the headers of the response were known. You can implement a similar behavior in a number of ways. One example might be to use a FnStream that has access to the transaction being sent. For example, when the first byte is written, you could check if the response headers match your expectations, and if so, change the actual stream body that is being written to. * Removed the `asArray` parameter from `GuzzleHttp\Message\MessageInterface::getHeader`. If you want to get a header value as an array, then use the newly added `getHeaderAsArray()` method of `MessageInterface`. This change makes the Guzzle interfaces compatible with the PSR-7 interfaces. * `GuzzleHttp\Message\MessageFactory` no longer allows subclasses to add custom request options using double-dispatch (this was an implementation detail). Instead, you should now provide an associative array to the constructor which is a mapping of the request option name mapping to a function that applies the option value to a request. * Removed the concept of "throwImmediately" from exceptions and error events. This control mechanism was used to stop a transfer of concurrent requests from completing. This can now be handled by throwing the exception or by cancelling a pool of requests or each outstanding future request individually. * Updated to "GuzzleHttp\Streams" 3.0. * `GuzzleHttp\Stream\StreamInterface::getContents()` no longer accepts a `maxLen` parameter. This update makes the Guzzle streams project compatible with the current PSR-7 proposal. * `GuzzleHttp\Stream\Stream::__construct`, `GuzzleHttp\Stream\Stream::factory`, and `GuzzleHttp\Stream\Utils::create` no longer accept a size in the second argument. They now accept an associative array of options, including the "size" key and "metadata" key which can be used to provide custom metadata. ## 4.2.2 - 2014-09-08 * Fixed a memory leak in the CurlAdapter when reusing cURL handles. * No longer using `request_fulluri` in stream adapter proxies. * Relative redirects are now based on the last response, not the first response. ## 4.2.1 - 2014-08-19 * Ensuring that the StreamAdapter does not always add a Content-Type header * Adding automated github releases with a phar and zip ## 4.2.0 - 2014-08-17 * Now merging in default options using a case-insensitive comparison. Closes https://github.com/guzzle/guzzle/issues/767 * Added the ability to automatically decode `Content-Encoding` response bodies using the `decode_content` request option. This is set to `true` by default to decode the response body if it comes over the wire with a `Content-Encoding`. Set this value to `false` to disable decoding the response content, and pass a string to provide a request `Accept-Encoding` header and turn on automatic response decoding. This feature now allows you to pass an `Accept-Encoding` header in the headers of a request but still disable automatic response decoding. Closes https://github.com/guzzle/guzzle/issues/764 * Added the ability to throw an exception immediately when transferring requests in parallel. Closes https://github.com/guzzle/guzzle/issues/760 * Updating guzzlehttp/streams dependency to ~2.1 * No longer utilizing the now deprecated namespaced methods from the stream package. ## 4.1.8 - 2014-08-14 * Fixed an issue in the CurlFactory that caused setting the `stream=false` request option to throw an exception. See: https://github.com/guzzle/guzzle/issues/769 * TransactionIterator now calls rewind on the inner iterator. See: https://github.com/guzzle/guzzle/pull/765 * You can now set the `Content-Type` header to `multipart/form-data` when creating POST requests to force multipart bodies. See https://github.com/guzzle/guzzle/issues/768 ## 4.1.7 - 2014-08-07 * Fixed an error in the HistoryPlugin that caused the same request and response to be logged multiple times when an HTTP protocol error occurs. * Ensuring that cURL does not add a default Content-Type when no Content-Type has been supplied by the user. This prevents the adapter layer from modifying the request that is sent over the wire after any listeners may have already put the request in a desired state (e.g., signed the request). * Throwing an exception when you attempt to send requests that have the "stream" set to true in parallel using the MultiAdapter. * Only calling curl_multi_select when there are active cURL handles. This was previously changed and caused performance problems on some systems due to PHP always selecting until the maximum select timeout. * Fixed a bug where multipart/form-data POST fields were not correctly aggregated (e.g., values with "&"). ## 4.1.6 - 2014-08-03 * Added helper methods to make it easier to represent messages as strings, including getting the start line and getting headers as a string. ## 4.1.5 - 2014-08-02 * Automatically retrying cURL "Connection died, retrying a fresh connect" errors when possible. * cURL implementation cleanup * Allowing multiple event subscriber listeners to be registered per event by passing an array of arrays of listener configuration. ## 4.1.4 - 2014-07-22 * Fixed a bug that caused multi-part POST requests with more than one field to serialize incorrectly. * Paths can now be set to "0" * `ResponseInterface::xml` now accepts a `libxml_options` option and added a missing default argument that was required when parsing XML response bodies. * A `save_to` stream is now created lazily, which means that files are not created on disk unless a request succeeds. ## 4.1.3 - 2014-07-15 * Various fixes to multipart/form-data POST uploads * Wrapping function.php in an if-statement to ensure Guzzle can be used globally and in a Composer install * Fixed an issue with generating and merging in events to an event array * POST headers are only applied before sending a request to allow you to change the query aggregator used before uploading * Added much more robust query string parsing * Fixed various parsing and normalization issues with URLs * Fixing an issue where multi-valued headers were not being utilized correctly in the StreamAdapter ## 4.1.2 - 2014-06-18 * Added support for sending payloads with GET requests ## 4.1.1 - 2014-06-08 * Fixed an issue related to using custom message factory options in subclasses * Fixed an issue with nested form fields in a multi-part POST * Fixed an issue with using the `json` request option for POST requests * Added `ToArrayInterface` to `GuzzleHttp\Cookie\CookieJar` ## 4.1.0 - 2014-05-27 * Added a `json` request option to easily serialize JSON payloads. * Added a `GuzzleHttp\json_decode()` wrapper to safely parse JSON. * Added `setPort()` and `getPort()` to `GuzzleHttp\Message\RequestInterface`. * Added the ability to provide an emitter to a client in the client constructor. * Added the ability to persist a cookie session using $_SESSION. * Added a trait that can be used to add event listeners to an iterator. * Removed request method constants from RequestInterface. * Fixed warning when invalid request start-lines are received. * Updated MessageFactory to work with custom request option methods. * Updated cacert bundle to latest build. 4.0.2 (2014-04-16) ------------------ * Proxy requests using the StreamAdapter now properly use request_fulluri (#632) * Added the ability to set scalars as POST fields (#628) ## 4.0.1 - 2014-04-04 * The HTTP status code of a response is now set as the exception code of RequestException objects. * 303 redirects will now correctly switch from POST to GET requests. * The default parallel adapter of a client now correctly uses the MultiAdapter. * HasDataTrait now initializes the internal data array as an empty array so that the toArray() method always returns an array. ## 4.0.0 - 2014-03-29 * For information on changes and upgrading, see: https://github.com/guzzle/guzzle/blob/master/UPGRADING.md#3x-to-40 * Added `GuzzleHttp\batch()` as a convenience function for sending requests in parallel without needing to write asynchronous code. * Restructured how events are added to `GuzzleHttp\ClientInterface::sendAll()`. You can now pass a callable or an array of associative arrays where each associative array contains the "fn", "priority", and "once" keys. ## 4.0.0.rc-2 - 2014-03-25 * Removed `getConfig()` and `setConfig()` from clients to avoid confusion around whether things like base_url, message_factory, etc. should be able to be retrieved or modified. * Added `getDefaultOption()` and `setDefaultOption()` to ClientInterface * functions.php functions were renamed using snake_case to match PHP idioms * Added support for `HTTP_PROXY`, `HTTPS_PROXY`, and `GUZZLE_CURL_SELECT_TIMEOUT` environment variables * Added the ability to specify custom `sendAll()` event priorities * Added the ability to specify custom stream context options to the stream adapter. * Added a functions.php function for `get_path()` and `set_path()` * CurlAdapter and MultiAdapter now use a callable to generate curl resources * MockAdapter now properly reads a body and emits a `headers` event * Updated Url class to check if a scheme and host are set before adding ":" and "//". This allows empty Url (e.g., "") to be serialized as "". * Parsing invalid XML no longer emits warnings * Curl classes now properly throw AdapterExceptions * Various performance optimizations * Streams are created with the faster `Stream\create()` function * Marked deprecation_proxy() as internal * Test server is now a collection of static methods on a class ## 4.0.0-rc.1 - 2014-03-15 * See https://github.com/guzzle/guzzle/blob/master/UPGRADING.md#3x-to-40 ## 3.8.1 - 2014-01-28 * Bug: Always using GET requests when redirecting from a 303 response * Bug: CURLOPT_SSL_VERIFYHOST is now correctly set to false when setting `$certificateAuthority` to false in `Guzzle\Http\ClientInterface::setSslVerification()` * Bug: RedirectPlugin now uses strict RFC 3986 compliance when combining a base URL with a relative URL * Bug: The body of a request can now be set to `"0"` * Sending PHP stream requests no longer forces `HTTP/1.0` * Adding more information to ExceptionCollection exceptions so that users have more context, including a stack trace of each sub-exception * Updated the `$ref` attribute in service descriptions to merge over any existing parameters of a schema (rather than clobbering everything). * Merging URLs will now use the query string object from the relative URL (thus allowing custom query aggregators) * Query strings are now parsed in a way that they do no convert empty keys with no value to have a dangling `=`. For example `foo&bar=baz` is now correctly parsed and recognized as `foo&bar=baz` rather than `foo=&bar=baz`. * Now properly escaping the regular expression delimiter when matching Cookie domains. * Network access is now disabled when loading XML documents ## 3.8.0 - 2013-12-05 * Added the ability to define a POST name for a file * JSON response parsing now properly walks additionalProperties * cURL error code 18 is now retried automatically in the BackoffPlugin * Fixed a cURL error when URLs contain fragments * Fixed an issue in the BackoffPlugin retry event where it was trying to access all exceptions as if they were CurlExceptions * CURLOPT_PROGRESS function fix for PHP 5.5 (69fcc1e) * Added the ability for Guzzle to work with older versions of cURL that do not support `CURLOPT_TIMEOUT_MS` * Fixed a bug that was encountered when parsing empty header parameters * UriTemplate now has a `setRegex()` method to match the docs * The `debug` request parameter now checks if it is truthy rather than if it exists * Setting the `debug` request parameter to true shows verbose cURL output instead of using the LogPlugin * Added the ability to combine URLs using strict RFC 3986 compliance * Command objects can now return the validation errors encountered by the command * Various fixes to cache revalidation (#437 and 29797e5) * Various fixes to the AsyncPlugin * Cleaned up build scripts ## 3.7.4 - 2013-10-02 * Bug fix: 0 is now an allowed value in a description parameter that has a default value (#430) * Bug fix: SchemaFormatter now returns an integer when formatting to a Unix timestamp (see https://github.com/aws/aws-sdk-php/issues/147) * Bug fix: Cleaned up and fixed URL dot segment removal to properly resolve internal dots * Minimum PHP version is now properly specified as 5.3.3 (up from 5.3.2) (#420) * Updated the bundled cacert.pem (#419) * OauthPlugin now supports adding authentication to headers or query string (#425) ## 3.7.3 - 2013-09-08 * Added the ability to get the exception associated with a request/command when using `MultiTransferException` and `CommandTransferException`. * Setting `additionalParameters` of a response to false is now honored when parsing responses with a service description * Schemas are only injected into response models when explicitly configured. * No longer guessing Content-Type based on the path of a request. Content-Type is now only guessed based on the path of an EntityBody. * Bug fix: ChunkedIterator can now properly chunk a \Traversable as well as an \Iterator. * Bug fix: FilterIterator now relies on `\Iterator` instead of `\Traversable`. * Bug fix: Gracefully handling malformed responses in RequestMediator::writeResponseBody() * Bug fix: Replaced call to canCache with canCacheRequest in the CallbackCanCacheStrategy of the CachePlugin * Bug fix: Visiting XML attributes first before visiting XML children when serializing requests * Bug fix: Properly parsing headers that contain commas contained in quotes * Bug fix: mimetype guessing based on a filename is now case-insensitive ## 3.7.2 - 2013-08-02 * Bug fix: Properly URL encoding paths when using the PHP-only version of the UriTemplate expander See https://github.com/guzzle/guzzle/issues/371 * Bug fix: Cookie domains are now matched correctly according to RFC 6265 See https://github.com/guzzle/guzzle/issues/377 * Bug fix: GET parameters are now used when calculating an OAuth signature * Bug fix: Fixed an issue with cache revalidation where the If-None-Match header was being double quoted * `Guzzle\Common\AbstractHasDispatcher::dispatch()` now returns the event that was dispatched * `Guzzle\Http\QueryString::factory()` now guesses the most appropriate query aggregator to used based on the input. See https://github.com/guzzle/guzzle/issues/379 * Added a way to add custom domain objects to service description parsing using the `operation.parse_class` event. See https://github.com/guzzle/guzzle/pull/380 * cURL multi cleanup and optimizations ## 3.7.1 - 2013-07-05 * Bug fix: Setting default options on a client now works * Bug fix: Setting options on HEAD requests now works. See #352 * Bug fix: Moving stream factory before send event to before building the stream. See #353 * Bug fix: Cookies no longer match on IP addresses per RFC 6265 * Bug fix: Correctly parsing header parameters that are in `<>` and quotes * Added `cert` and `ssl_key` as request options * `Host` header can now diverge from the host part of a URL if the header is set manually * `Guzzle\Service\Command\LocationVisitor\Request\XmlVisitor` was rewritten to change from using SimpleXML to XMLWriter * OAuth parameters are only added via the plugin if they aren't already set * Exceptions are now thrown when a URL cannot be parsed * Returning `false` if `Guzzle\Http\EntityBody::getContentMd5()` fails * Not setting a `Content-MD5` on a command if calculating the Content-MD5 fails via the CommandContentMd5Plugin ## 3.7.0 - 2013-06-10 * See UPGRADING.md for more information on how to upgrade. * Requests now support the ability to specify an array of $options when creating a request to more easily modify a request. You can pass a 'request.options' configuration setting to a client to apply default request options to every request created by a client (e.g. default query string variables, headers, curl options, etc.). * Added a static facade class that allows you to use Guzzle with static methods and mount the class to `\Guzzle`. See `Guzzle\Http\StaticClient::mount`. * Added `command.request_options` to `Guzzle\Service\Command\AbstractCommand` to pass request options to requests created by a command (e.g. custom headers, query string variables, timeout settings, etc.). * Stream size in `Guzzle\Stream\PhpStreamRequestFactory` will now be set if Content-Length is returned in the headers of a response * Added `Guzzle\Common\Collection::setPath($path, $value)` to set a value into an array using a nested key (e.g. `$collection->setPath('foo/baz/bar', 'test'); echo $collection['foo']['bar']['bar'];`) * ServiceBuilders now support storing and retrieving arbitrary data * CachePlugin can now purge all resources for a given URI * CachePlugin can automatically purge matching cached items when a non-idempotent request is sent to a resource * CachePlugin now uses the Vary header to determine if a resource is a cache hit * `Guzzle\Http\Message\Response` now implements `\Serializable` * Added `Guzzle\Cache\CacheAdapterFactory::fromCache()` to more easily create cache adapters * `Guzzle\Service\ClientInterface::execute()` now accepts an array, single command, or Traversable * Fixed a bug in `Guzzle\Http\Message\Header\Link::addLink()` * Better handling of calculating the size of a stream in `Guzzle\Stream\Stream` using fstat() and caching the size * `Guzzle\Common\Exception\ExceptionCollection` now creates a more readable exception message * Fixing BC break: Added back the MonologLogAdapter implementation rather than extending from PsrLog so that older Symfony users can still use the old version of Monolog. * Fixing BC break: Added the implementation back in for `Guzzle\Http\Message\AbstractMessage::getTokenizedHeader()`. Now triggering an E_USER_DEPRECATED warning when used. Use `$message->getHeader()->parseParams()`. * Several performance improvements to `Guzzle\Common\Collection` * Added an `$options` argument to the end of the following methods of `Guzzle\Http\ClientInterface`: createRequest, head, delete, put, patch, post, options, prepareRequest * Added an `$options` argument to the end of `Guzzle\Http\Message\Request\RequestFactoryInterface::createRequest()` * Added an `applyOptions()` method to `Guzzle\Http\Message\Request\RequestFactoryInterface` * Changed `Guzzle\Http\ClientInterface::get($uri = null, $headers = null, $body = null)` to `Guzzle\Http\ClientInterface::get($uri = null, $headers = null, $options = array())`. You can still pass in a resource, string, or EntityBody into the $options parameter to specify the download location of the response. * Changed `Guzzle\Common\Collection::__construct($data)` to no longer accepts a null value for `$data` but a default `array()` * Added `Guzzle\Stream\StreamInterface::isRepeatable` * Removed `Guzzle\Http\ClientInterface::setDefaultHeaders(). Use $client->getConfig()->setPath('request.options/headers/{header_name}', 'value')`. or $client->getConfig()->setPath('request.options/headers', array('header_name' => 'value'))`. * Removed `Guzzle\Http\ClientInterface::getDefaultHeaders(). Use $client->getConfig()->getPath('request.options/headers')`. * Removed `Guzzle\Http\ClientInterface::expandTemplate()` * Removed `Guzzle\Http\ClientInterface::setRequestFactory()` * Removed `Guzzle\Http\ClientInterface::getCurlMulti()` * Removed `Guzzle\Http\Message\RequestInterface::canCache` * Removed `Guzzle\Http\Message\RequestInterface::setIsRedirect` * Removed `Guzzle\Http\Message\RequestInterface::isRedirect` * Made `Guzzle\Http\Client::expandTemplate` and `getUriTemplate` protected methods. * You can now enable E_USER_DEPRECATED warnings to see if you are using a deprecated method by setting `Guzzle\Common\Version::$emitWarnings` to true. * Marked `Guzzle\Http\Message\Request::isResponseBodyRepeatable()` as deprecated. Use `$request->getResponseBody()->isRepeatable()` instead. * Marked `Guzzle\Http\Message\Request::canCache()` as deprecated. Use `Guzzle\Plugin\Cache\DefaultCanCacheStrategy->canCacheRequest()` instead. * Marked `Guzzle\Http\Message\Request::canCache()` as deprecated. Use `Guzzle\Plugin\Cache\DefaultCanCacheStrategy->canCacheRequest()` instead. * Marked `Guzzle\Http\Message\Request::setIsRedirect()` as deprecated. Use the HistoryPlugin instead. * Marked `Guzzle\Http\Message\Request::isRedirect()` as deprecated. Use the HistoryPlugin instead. * Marked `Guzzle\Cache\CacheAdapterFactory::factory()` as deprecated * Marked 'command.headers', 'command.response_body' and 'command.on_complete' as deprecated for AbstractCommand. These will work through Guzzle 4.0 * Marked 'request.params' for `Guzzle\Http\Client` as deprecated. Use [request.options][params]. * Marked `Guzzle\Service\Client::enableMagicMethods()` as deprecated. Magic methods can no longer be disabled on a Guzzle\Service\Client. * Marked `Guzzle\Service\Client::getDefaultHeaders()` as deprecated. Use $client->getConfig()->getPath('request.options/headers')`. * Marked `Guzzle\Service\Client::setDefaultHeaders()` as deprecated. Use $client->getConfig()->setPath('request.options/headers/{header_name}', 'value')`. * Marked `Guzzle\Parser\Url\UrlParser` as deprecated. Just use PHP's `parse_url()` and percent encode your UTF-8. * Marked `Guzzle\Common\Collection::inject()` as deprecated. * Marked `Guzzle\Plugin\CurlAuth\CurlAuthPlugin` as deprecated. Use `$client->getConfig()->setPath('request.options/auth', array('user', 'pass', 'Basic|Digest');` * CacheKeyProviderInterface and DefaultCacheKeyProvider are no longer used. All of this logic is handled in a CacheStorageInterface. These two objects and interface will be removed in a future version. * Always setting X-cache headers on cached responses * Default cache TTLs are now handled by the CacheStorageInterface of a CachePlugin * `CacheStorageInterface::cache($key, Response $response, $ttl = null)` has changed to `cache(RequestInterface $request, Response $response);` * `CacheStorageInterface::fetch($key)` has changed to `fetch(RequestInterface $request);` * `CacheStorageInterface::delete($key)` has changed to `delete(RequestInterface $request);` * Added `CacheStorageInterface::purge($url)` * `DefaultRevalidation::__construct(CacheKeyProviderInterface $cacheKey, CacheStorageInterface $cache, CachePlugin $plugin)` has changed to `DefaultRevalidation::__construct(CacheStorageInterface $cache, CanCacheStrategyInterface $canCache = null)` * Added `RevalidationInterface::shouldRevalidate(RequestInterface $request, Response $response)` ## 3.6.0 - 2013-05-29 * ServiceDescription now implements ToArrayInterface * Added command.hidden_params to blacklist certain headers from being treated as additionalParameters * Guzzle can now correctly parse incomplete URLs * Mixed casing of headers are now forced to be a single consistent casing across all values for that header. * Messages internally use a HeaderCollection object to delegate handling case-insensitive header resolution * Removed the whole changedHeader() function system of messages because all header changes now go through addHeader(). * Specific header implementations can be created for complex headers. When a message creates a header, it uses a HeaderFactory which can map specific headers to specific header classes. There is now a Link header and CacheControl header implementation. * Removed from interface: Guzzle\Http\ClientInterface::setUriTemplate * Removed from interface: Guzzle\Http\ClientInterface::setCurlMulti() * Removed Guzzle\Http\Message\Request::receivedRequestHeader() and implemented this functionality in Guzzle\Http\Curl\RequestMediator * Removed the optional $asString parameter from MessageInterface::getHeader(). Just cast the header to a string. * Removed the optional $tryChunkedTransfer option from Guzzle\Http\Message\EntityEnclosingRequestInterface * Removed the $asObjects argument from Guzzle\Http\Message\MessageInterface::getHeaders() * Removed Guzzle\Parser\ParserRegister::get(). Use getParser() * Removed Guzzle\Parser\ParserRegister::set(). Use registerParser(). * All response header helper functions return a string rather than mixing Header objects and strings inconsistently * Removed cURL blacklist support. This is no longer necessary now that Expect, Accept, etc. are managed by Guzzle directly via interfaces * Removed the injecting of a request object onto a response object. The methods to get and set a request still exist but are a no-op until removed. * Most classes that used to require a `Guzzle\Service\Command\CommandInterface` typehint now request a `Guzzle\Service\Command\ArrayCommandInterface`. * Added `Guzzle\Http\Message\RequestInterface::startResponse()` to the RequestInterface to handle injecting a response on a request while the request is still being transferred * The ability to case-insensitively search for header values * Guzzle\Http\Message\Header::hasExactHeader * Guzzle\Http\Message\Header::raw. Use getAll() * Deprecated cache control specific methods on Guzzle\Http\Message\AbstractMessage. Use the CacheControl header object instead. * `Guzzle\Service\Command\CommandInterface` now extends from ToArrayInterface and ArrayAccess * Added the ability to cast Model objects to a string to view debug information. ## 3.5.0 - 2013-05-13 * Bug: Fixed a regression so that request responses are parsed only once per oncomplete event rather than multiple times * Bug: Better cleanup of one-time events across the board (when an event is meant to fire once, it will now remove itself from the EventDispatcher) * Bug: `Guzzle\Log\MessageFormatter` now properly writes "total_time" and "connect_time" values * Bug: Cloning an EntityEnclosingRequest now clones the EntityBody too * Bug: Fixed an undefined index error when parsing nested JSON responses with a sentAs parameter that reference a non-existent key * Bug: All __call() method arguments are now required (helps with mocking frameworks) * Deprecating Response::getRequest() and now using a shallow clone of a request object to remove a circular reference to help with refcount based garbage collection of resources created by sending a request * Deprecating ZF1 cache and log adapters. These will be removed in the next major version. * Deprecating `Response::getPreviousResponse()` (method signature still exists, but it's deprecated). Use the HistoryPlugin for a history. * Added a `responseBody` alias for the `response_body` location * Refactored internals to no longer rely on Response::getRequest() * HistoryPlugin can now be cast to a string * HistoryPlugin now logs transactions rather than requests and responses to more accurately keep track of the requests and responses that are sent over the wire * Added `getEffectiveUrl()` and `getRedirectCount()` to Response objects ## 3.4.3 - 2013-04-30 * Bug fix: Fixing bug introduced in 3.4.2 where redirect responses are duplicated on the final redirected response * Added a check to re-extract the temp cacert bundle from the phar before sending each request ## 3.4.2 - 2013-04-29 * Bug fix: Stream objects now work correctly with "a" and "a+" modes * Bug fix: Removing `Transfer-Encoding: chunked` header when a Content-Length is present * Bug fix: AsyncPlugin no longer forces HEAD requests * Bug fix: DateTime timezones are now properly handled when using the service description schema formatter * Bug fix: CachePlugin now properly handles stale-if-error directives when a request to the origin server fails * Setting a response on a request will write to the custom request body from the response body if one is specified * LogPlugin now writes to php://output when STDERR is undefined * Added the ability to set multiple POST files for the same key in a single call * application/x-www-form-urlencoded POSTs now use the utf-8 charset by default * Added the ability to queue CurlExceptions to the MockPlugin * Cleaned up how manual responses are queued on requests (removed "queued_response" and now using request.before_send) * Configuration loading now allows remote files ## 3.4.1 - 2013-04-16 * Large refactoring to how CurlMulti handles work. There is now a proxy that sits in front of a pool of CurlMulti handles. This greatly simplifies the implementation, fixes a couple bugs, and provides a small performance boost. * Exceptions are now properly grouped when sending requests in parallel * Redirects are now properly aggregated when a multi transaction fails * Redirects now set the response on the original object even in the event of a failure * Bug fix: Model names are now properly set even when using $refs * Added support for PHP 5.5's CurlFile to prevent warnings with the deprecated @ syntax * Added support for oauth_callback in OAuth signatures * Added support for oauth_verifier in OAuth signatures * Added support to attempt to retrieve a command first literally, then ucfirst, the with inflection ## 3.4.0 - 2013-04-11 * Bug fix: URLs are now resolved correctly based on https://datatracker.ietf.org/doc/html/rfc3986#section-5.2. #289 * Bug fix: Absolute URLs with a path in a service description will now properly override the base URL. #289 * Bug fix: Parsing a query string with a single PHP array value will now result in an array. #263 * Bug fix: Better normalization of the User-Agent header to prevent duplicate headers. #264. * Bug fix: Added `number` type to service descriptions. * Bug fix: empty parameters are removed from an OAuth signature * Bug fix: Revalidating a cache entry prefers the Last-Modified over the Date header * Bug fix: Fixed "array to string" error when validating a union of types in a service description * Bug fix: Removed code that attempted to determine the size of a stream when data is written to the stream * Bug fix: Not including an `oauth_token` if the value is null in the OauthPlugin. * Bug fix: Now correctly aggregating successful requests and failed requests in CurlMulti when a redirect occurs. * The new default CURLOPT_TIMEOUT setting has been increased to 150 seconds so that Guzzle works on poor connections. * Added a feature to EntityEnclosingRequest::setBody() that will automatically set the Content-Type of the request if the Content-Type can be determined based on the entity body or the path of the request. * Added the ability to overwrite configuration settings in a client when grabbing a throwaway client from a builder. * Added support for a PSR-3 LogAdapter. * Added a `command.after_prepare` event * Added `oauth_callback` parameter to the OauthPlugin * Added the ability to create a custom stream class when using a stream factory * Added a CachingEntityBody decorator * Added support for `additionalParameters` in service descriptions to define how custom parameters are serialized. * The bundled SSL certificate is now provided in the phar file and extracted when running Guzzle from a phar. * You can now send any EntityEnclosingRequest with POST fields or POST files and cURL will handle creating bodies * POST requests using a custom entity body are now treated exactly like PUT requests but with a custom cURL method. This means that the redirect behavior of POST requests with custom bodies will not be the same as POST requests that use POST fields or files (the latter is only used when emulating a form POST in the browser). * Lots of cleanup to CurlHandle::factory and RequestFactory::createRequest ## 3.3.1 - 2013-03-10 * Added the ability to create PHP streaming responses from HTTP requests * Bug fix: Running any filters when parsing response headers with service descriptions * Bug fix: OauthPlugin fixes to allow for multi-dimensional array signing, and sorting parameters before signing * Bug fix: Removed the adding of default empty arrays and false Booleans to responses in order to be consistent across response location visitors. * Bug fix: Removed the possibility of creating configuration files with circular dependencies * RequestFactory::create() now uses the key of a POST file when setting the POST file name * Added xmlAllowEmpty to serialize an XML body even if no XML specific parameters are set ## 3.3.0 - 2013-03-03 * A large number of performance optimizations have been made * Bug fix: Added 'wb' as a valid write mode for streams * Bug fix: `Guzzle\Http\Message\Response::json()` now allows scalar values to be returned * Bug fix: Fixed bug in `Guzzle\Http\Message\Response` where wrapping quotes were stripped from `getEtag()` * BC: Removed `Guzzle\Http\Utils` class * BC: Setting a service description on a client will no longer modify the client's command factories. * BC: Emitting IO events from a RequestMediator is now a parameter that must be set in a request's curl options using the 'emit_io' key. This was previously set under a request's parameters using 'curl.emit_io' * BC: `Guzzle\Stream\Stream::getWrapper()` and `Guzzle\Stream\Stream::getSteamType()` are no longer converted to lowercase * Operation parameter objects are now lazy loaded internally * Added ErrorResponsePlugin that can throw errors for responses defined in service description operations' errorResponses * Added support for instantiating responseType=class responseClass classes. Classes must implement `Guzzle\Service\Command\ResponseClassInterface` * Added support for additionalProperties for top-level parameters in responseType=model responseClasses. These additional properties also support locations and can be used to parse JSON responses where the outermost part of the JSON is an array * Added support for nested renaming of JSON models (rename sentAs to name) * CachePlugin * Added support for stale-if-error so that the CachePlugin can now serve stale content from the cache on error * Debug headers can now added to cached response in the CachePlugin ## 3.2.0 - 2013-02-14 * CurlMulti is no longer reused globally. A new multi object is created per-client. This helps to isolate clients. * URLs with no path no longer contain a "/" by default * Guzzle\Http\QueryString does no longer manages the leading "?". This is now handled in Guzzle\Http\Url. * BadResponseException no longer includes the full request and response message * Adding setData() to Guzzle\Service\Description\ServiceDescriptionInterface * Adding getResponseBody() to Guzzle\Http\Message\RequestInterface * Various updates to classes to use ServiceDescriptionInterface type hints rather than ServiceDescription * Header values can now be normalized into distinct values when multiple headers are combined with a comma separated list * xmlEncoding can now be customized for the XML declaration of a XML service description operation * Guzzle\Http\QueryString now uses Guzzle\Http\QueryAggregator\QueryAggregatorInterface objects to add custom value aggregation and no longer uses callbacks * The URL encoding implementation of Guzzle\Http\QueryString can now be customized * Bug fix: Filters were not always invoked for array service description parameters * Bug fix: Redirects now use a target response body rather than a temporary response body * Bug fix: The default exponential backoff BackoffPlugin was not giving when the request threshold was exceeded * Bug fix: Guzzle now takes the first found value when grabbing Cache-Control directives ## 3.1.2 - 2013-01-27 * Refactored how operation responses are parsed. Visitors now include a before() method responsible for parsing the response body. For example, the XmlVisitor now parses the XML response into an array in the before() method. * Fixed an issue where cURL would not automatically decompress responses when the Accept-Encoding header was sent * CURLOPT_SSL_VERIFYHOST is never set to 1 because it is deprecated (see 5e0ff2ef20f839e19d1eeb298f90ba3598784444) * Fixed a bug where redirect responses were not chained correctly using getPreviousResponse() * Setting default headers on a client after setting the user-agent will not erase the user-agent setting ## 3.1.1 - 2013-01-20 * Adding wildcard support to Guzzle\Common\Collection::getPath() * Adding alias support to ServiceBuilder configs * Adding Guzzle\Service\Resource\CompositeResourceIteratorFactory and cleaning up factory interface ## 3.1.0 - 2013-01-12 * BC: CurlException now extends from RequestException rather than BadResponseException * BC: Renamed Guzzle\Plugin\Cache\CanCacheStrategyInterface::canCache() to canCacheRequest() and added CanCacheResponse() * Added getData to ServiceDescriptionInterface * Added context array to RequestInterface::setState() * Bug: Removing hard dependency on the BackoffPlugin from Guzzle\Http * Bug: Adding required content-type when JSON request visitor adds JSON to a command * Bug: Fixing the serialization of a service description with custom data * Made it easier to deal with exceptions thrown when transferring commands or requests in parallel by providing an array of successful and failed responses * Moved getPath from Guzzle\Service\Resource\Model to Guzzle\Common\Collection * Added Guzzle\Http\IoEmittingEntityBody * Moved command filtration from validators to location visitors * Added `extends` attributes to service description parameters * Added getModels to ServiceDescriptionInterface ## 3.0.7 - 2012-12-19 * Fixing phar detection when forcing a cacert to system if null or true * Allowing filename to be passed to `Guzzle\Http\Message\Request::setResponseBody()` * Cleaning up `Guzzle\Common\Collection::inject` method * Adding a response_body location to service descriptions ## 3.0.6 - 2012-12-09 * CurlMulti performance improvements * Adding setErrorResponses() to Operation * composer.json tweaks ## 3.0.5 - 2012-11-18 * Bug: Fixing an infinite recursion bug caused from revalidating with the CachePlugin * Bug: Response body can now be a string containing "0" * Bug: Using Guzzle inside of a phar uses system by default but now allows for a custom cacert * Bug: QueryString::fromString now properly parses query string parameters that contain equal signs * Added support for XML attributes in service description responses * DefaultRequestSerializer now supports array URI parameter values for URI template expansion * Added better mimetype guessing to requests and post files ## 3.0.4 - 2012-11-11 * Bug: Fixed a bug when adding multiple cookies to a request to use the correct glue value * Bug: Cookies can now be added that have a name, domain, or value set to "0" * Bug: Using the system cacert bundle when using the Phar * Added json and xml methods to Response to make it easier to parse JSON and XML response data into data structures * Enhanced cookie jar de-duplication * Added the ability to enable strict cookie jars that throw exceptions when invalid cookies are added * Added setStream to StreamInterface to actually make it possible to implement custom rewind behavior for entity bodies * Added the ability to create any sort of hash for a stream rather than just an MD5 hash ## 3.0.3 - 2012-11-04 * Implementing redirects in PHP rather than cURL * Added PECL URI template extension and using as default parser if available * Bug: Fixed Content-Length parsing of Response factory * Adding rewind() method to entity bodies and streams. Allows for custom rewinding of non-repeatable streams. * Adding ToArrayInterface throughout library * Fixing OauthPlugin to create unique nonce values per request ## 3.0.2 - 2012-10-25 * Magic methods are enabled by default on clients * Magic methods return the result of a command * Service clients no longer require a base_url option in the factory * Bug: Fixed an issue with URI templates where null template variables were being expanded ## 3.0.1 - 2012-10-22 * Models can now be used like regular collection objects by calling filter, map, etc. * Models no longer require a Parameter structure or initial data in the constructor * Added a custom AppendIterator to get around a PHP bug with the `\AppendIterator` ## 3.0.0 - 2012-10-15 * Rewrote service description format to be based on Swagger * Now based on JSON schema * Added nested input structures and nested response models * Support for JSON and XML input and output models * Renamed `commands` to `operations` * Removed dot class notation * Removed custom types * Broke the project into smaller top-level namespaces to be more component friendly * Removed support for XML configs and descriptions. Use arrays or JSON files. * Removed the Validation component and Inspector * Moved all cookie code to Guzzle\Plugin\Cookie * Magic methods on a Guzzle\Service\Client now return the command un-executed. * Calling getResult() or getResponse() on a command will lazily execute the command if needed. * Now shipping with cURL's CA certs and using it by default * Added previousResponse() method to response objects * No longer sending Accept and Accept-Encoding headers on every request * Only sending an Expect header by default when a payload is greater than 1MB * Added/moved client options: * curl.blacklist to curl.option.blacklist * Added ssl.certificate_authority * Added a Guzzle\Iterator component * Moved plugins from Guzzle\Http\Plugin to Guzzle\Plugin * Added a more robust backoff retry strategy (replaced the ExponentialBackoffPlugin) * Added a more robust caching plugin * Added setBody to response objects * Updating LogPlugin to use a more flexible MessageFormatter * Added a completely revamped build process * Cleaning up Collection class and removing default values from the get method * Fixed ZF2 cache adapters ## 2.8.8 - 2012-10-15 * Bug: Fixed a cookie issue that caused dot prefixed domains to not match where popular browsers did ## 2.8.7 - 2012-09-30 * Bug: Fixed config file aliases for JSON includes * Bug: Fixed cookie bug on a request object by using CookieParser to parse cookies on requests * Bug: Removing the path to a file when sending a Content-Disposition header on a POST upload * Bug: Hardening request and response parsing to account for missing parts * Bug: Fixed PEAR packaging * Bug: Fixed Request::getInfo * Bug: Fixed cases where CURLM_CALL_MULTI_PERFORM return codes were causing curl transactions to fail * Adding the ability for the namespace Iterator factory to look in multiple directories * Added more getters/setters/removers from service descriptions * Added the ability to remove POST fields from OAuth signatures * OAuth plugin now supports 2-legged OAuth ## 2.8.6 - 2012-09-05 * Added the ability to modify and build service descriptions * Added the use of visitors to apply parameters to locations in service descriptions using the dynamic command * Added a `json` parameter location * Now allowing dot notation for classes in the CacheAdapterFactory * Using the union of two arrays rather than an array_merge when extending service builder services and service params * Ensuring that a service is a string before doing strpos() checks on it when substituting services for references in service builder config files. * Services defined in two different config files that include one another will by default replace the previously defined service, but you can now create services that extend themselves and merge their settings over the previous * The JsonLoader now supports aliasing filenames with different filenames. This allows you to alias something like '_default' with a default JSON configuration file. ## 2.8.5 - 2012-08-29 * Bug: Suppressed empty arrays from URI templates * Bug: Added the missing $options argument from ServiceDescription::factory to enable caching * Added support for HTTP responses that do not contain a reason phrase in the start-line * AbstractCommand commands are now invokable * Added a way to get the data used when signing an Oauth request before a request is sent ## 2.8.4 - 2012-08-15 * Bug: Custom delay time calculations are no longer ignored in the ExponentialBackoffPlugin * Added the ability to transfer entity bodies as a string rather than streamed. This gets around curl error 65. Set `body_as_string` in a request's curl options to enable. * Added a StreamInterface, EntityBodyInterface, and added ftell() to Guzzle\Common\Stream * Added an AbstractEntityBodyDecorator and a ReadLimitEntityBody decorator to transfer only a subset of a decorated stream * Stream and EntityBody objects will now return the file position to the previous position after a read required operation (e.g. getContentMd5()) * Added additional response status codes * Removed SSL information from the default User-Agent header * DELETE requests can now send an entity body * Added an EventDispatcher to the ExponentialBackoffPlugin and added an ExponentialBackoffLogger to log backoff retries * Added the ability of the MockPlugin to consume mocked request bodies * LogPlugin now exposes request and response objects in the extras array ## 2.8.3 - 2012-07-30 * Bug: Fixed a case where empty POST requests were sent as GET requests * Bug: Fixed a bug in ExponentialBackoffPlugin that caused fatal errors when retrying an EntityEnclosingRequest that does not have a body * Bug: Setting the response body of a request to null after completing a request, not when setting the state of a request to new * Added multiple inheritance to service description commands * Added an ApiCommandInterface and added `getParamNames()` and `hasParam()` * Removed the default 2mb size cutoff from the Md5ValidatorPlugin so that it now defaults to validating everything * Changed CurlMulti::perform to pass a smaller timeout to CurlMulti::executeHandles ## 2.8.2 - 2012-07-24 * Bug: Query string values set to 0 are no longer dropped from the query string * Bug: A Collection object is no longer created each time a call is made to `Guzzle\Service\Command\AbstractCommand::getRequestHeaders()` * Bug: `+` is now treated as an encoded space when parsing query strings * QueryString and Collection performance improvements * Allowing dot notation for class paths in filters attribute of a service descriptions ## 2.8.1 - 2012-07-16 * Loosening Event Dispatcher dependency * POST redirects can now be customized using CURLOPT_POSTREDIR ## 2.8.0 - 2012-07-15 * BC: Guzzle\Http\Query * Query strings with empty variables will always show an equal sign unless the variable is set to QueryString::BLANK (e.g. ?acl= vs ?acl) * Changed isEncodingValues() and isEncodingFields() to isUrlEncoding() * Changed setEncodeValues(bool) and setEncodeFields(bool) to useUrlEncoding(bool) * Changed the aggregation functions of QueryString to be static methods * Can now use fromString() with querystrings that have a leading ? * cURL configuration values can be specified in service descriptions using `curl.` prefixed parameters * Content-Length is set to 0 before emitting the request.before_send event when sending an empty request body * Cookies are no longer URL decoded by default * Bug: URI template variables set to null are no longer expanded ## 2.7.2 - 2012-07-02 * BC: Moving things to get ready for subtree splits. Moving Inflection into Common. Moving Guzzle\Http\Parser to Guzzle\Parser. * BC: Removing Guzzle\Common\Batch\Batch::count() and replacing it with isEmpty() * CachePlugin now allows for a custom request parameter function to check if a request can be cached * Bug fix: CachePlugin now only caches GET and HEAD requests by default * Bug fix: Using header glue when transferring headers over the wire * Allowing deeply nested arrays for composite variables in URI templates * Batch divisors can now return iterators or arrays ## 2.7.1 - 2012-06-26 * Minor patch to update version number in UA string * Updating build process ## 2.7.0 - 2012-06-25 * BC: Inflection classes moved to Guzzle\Inflection. No longer static methods. Can now inject custom inflectors into classes. * BC: Removed magic setX methods from commands * BC: Magic methods mapped to service description commands are now inflected in the command factory rather than the client __call() method * Verbose cURL options are no longer enabled by default. Set curl.debug to true on a client to enable. * Bug: Now allowing colons in a response start-line (e.g. HTTP/1.1 503 Service Unavailable: Back-end server is at capacity) * Guzzle\Service\Resource\ResourceIteratorApplyBatched now internally uses the Guzzle\Common\Batch namespace * Added Guzzle\Service\Plugin namespace and a PluginCollectionPlugin * Added the ability to set POST fields and files in a service description * Guzzle\Http\EntityBody::factory() now accepts objects with a __toString() method * Adding a command.before_prepare event to clients * Added BatchClosureTransfer and BatchClosureDivisor * BatchTransferException now includes references to the batch divisor and transfer strategies * Fixed some tests so that they pass more reliably * Added Guzzle\Common\Log\ArrayLogAdapter ## 2.6.6 - 2012-06-10 * BC: Removing Guzzle\Http\Plugin\BatchQueuePlugin * BC: Removing Guzzle\Service\Command\CommandSet * Adding generic batching system (replaces the batch queue plugin and command set) * Updating ZF cache and log adapters and now using ZF's composer repository * Bug: Setting the name of each ApiParam when creating through an ApiCommand * Adding result_type, result_doc, deprecated, and doc_url to service descriptions * Bug: Changed the default cookie header casing back to 'Cookie' ## 2.6.5 - 2012-06-03 * BC: Renaming Guzzle\Http\Message\RequestInterface::getResourceUri() to getResource() * BC: Removing unused AUTH_BASIC and AUTH_DIGEST constants from * BC: Guzzle\Http\Cookie is now used to manage Set-Cookie data, not Cookie data * BC: Renaming methods in the CookieJarInterface * Moving almost all cookie logic out of the CookiePlugin and into the Cookie or CookieJar implementations * Making the default glue for HTTP headers ';' instead of ',' * Adding a removeValue to Guzzle\Http\Message\Header * Adding getCookies() to request interface. * Making it easier to add event subscribers to HasDispatcherInterface classes. Can now directly call addSubscriber() ## 2.6.4 - 2012-05-30 * BC: Cleaning up how POST files are stored in EntityEnclosingRequest objects. Adding PostFile class. * BC: Moving ApiCommand specific functionality from the Inspector and on to the ApiCommand * Bug: Fixing magic method command calls on clients * Bug: Email constraint only validates strings * Bug: Aggregate POST fields when POST files are present in curl handle * Bug: Fixing default User-Agent header * Bug: Only appending or prepending parameters in commands if they are specified * Bug: Not requiring response reason phrases or status codes to match a predefined list of codes * Allowing the use of dot notation for class namespaces when using instance_of constraint * Added any_match validation constraint * Added an AsyncPlugin * Passing request object to the calculateWait method of the ExponentialBackoffPlugin * Allowing the result of a command object to be changed * Parsing location and type sub values when instantiating a service description rather than over and over at runtime ## 2.6.3 - 2012-05-23 * [BC] Guzzle\Common\FromConfigInterface no longer requires any config options. * [BC] Refactoring how POST files are stored on an EntityEnclosingRequest. They are now separate from POST fields. * You can now use an array of data when creating PUT request bodies in the request factory. * Removing the requirement that HTTPS requests needed a Cache-Control: public directive to be cacheable. * [Http] Adding support for Content-Type in multipart POST uploads per upload * [Http] Added support for uploading multiple files using the same name (foo[0], foo[1]) * Adding more POST data operations for easier manipulation of POST data. * You can now set empty POST fields. * The body of a request is only shown on EntityEnclosingRequest objects that do not use POST files. * Split the Guzzle\Service\Inspector::validateConfig method into two methods. One to initialize when a command is created, and one to validate. * CS updates ## 2.6.2 - 2012-05-19 * [Http] Better handling of nested scope requests in CurlMulti. Requests are now always prepares in the send() method rather than the addRequest() method. ## 2.6.1 - 2012-05-19 * [BC] Removing 'path' support in service descriptions. Use 'uri'. * [BC] Guzzle\Service\Inspector::parseDocBlock is now protected. Adding getApiParamsForClass() with cache. * [BC] Removing Guzzle\Common\NullObject. Use https://github.com/mtdowling/NullObject if you need it. * [BC] Removing Guzzle\Common\XmlElement. * All commands, both dynamic and concrete, have ApiCommand objects. * Adding a fix for CurlMulti so that if all of the connections encounter some sort of curl error, then the loop exits. * Adding checks to EntityEnclosingRequest so that empty POST files and fields are ignored. * Making the method signature of Guzzle\Service\Builder\ServiceBuilder::factory more flexible. ## 2.6.0 - 2012-05-15 * [BC] Moving Guzzle\Service\Builder to Guzzle\Service\Builder\ServiceBuilder * [BC] Executing a Command returns the result of the command rather than the command * [BC] Moving all HTTP parsing logic to Guzzle\Http\Parsers. Allows for faster C implementations if needed. * [BC] Changing the Guzzle\Http\Message\Response::setProtocol() method to accept a protocol and version in separate args. * [BC] Moving ResourceIterator* to Guzzle\Service\Resource * [BC] Completely refactored ResourceIterators to iterate over a cloned command object * [BC] Moved Guzzle\Http\UriTemplate to Guzzle\Http\Parser\UriTemplate\UriTemplate * [BC] Guzzle\Guzzle is now deprecated * Moving Guzzle\Common\Guzzle::inject to Guzzle\Common\Collection::inject * Adding Guzzle\Version class to give version information about Guzzle * Adding Guzzle\Http\Utils class to provide getDefaultUserAgent() and getHttpDate() * Adding Guzzle\Curl\CurlVersion to manage caching curl_version() data * ServiceDescription and ServiceBuilder are now cacheable using similar configs * Changing the format of XML and JSON service builder configs. Backwards compatible. * Cleaned up Cookie parsing * Trimming the default Guzzle User-Agent header * Adding a setOnComplete() method to Commands that is called when a command completes * Keeping track of requests that were mocked in the MockPlugin * Fixed a caching bug in the CacheAdapterFactory * Inspector objects can be injected into a Command object * Refactoring a lot of code and tests to be case insensitive when dealing with headers * Adding Guzzle\Http\Message\HeaderComparison for easy comparison of HTTP headers using a DSL * Adding the ability to set global option overrides to service builder configs * Adding the ability to include other service builder config files from within XML and JSON files * Moving the parseQuery method out of Url and on to QueryString::fromString() as a static factory method. ## 2.5.0 - 2012-05-08 * Major performance improvements * [BC] Simplifying Guzzle\Common\Collection. Please check to see if you are using features that are now deprecated. * [BC] Using a custom validation system that allows a flyweight implementation for much faster validation. No longer using Symfony2 Validation component. * [BC] No longer supporting "{{ }}" for injecting into command or UriTemplates. Use "{}" * Added the ability to passed parameters to all requests created by a client * Added callback functionality to the ExponentialBackoffPlugin * Using microtime in ExponentialBackoffPlugin to allow more granular backoff strategies. * Rewinding request stream bodies when retrying requests * Exception is thrown when JSON response body cannot be decoded * Added configurable magic method calls to clients and commands. This is off by default. * Fixed a defect that added a hash to every parsed URL part * Fixed duplicate none generation for OauthPlugin. * Emitting an event each time a client is generated by a ServiceBuilder * Using an ApiParams object instead of a Collection for parameters of an ApiCommand * cache.* request parameters should be renamed to params.cache.* * Added the ability to set arbitrary curl options on requests (disable_wire, progress, etc.). See CurlHandle. * Added the ability to disable type validation of service descriptions * ServiceDescriptions and ServiceBuilders are now Serializable ================================================ FILE: lib/Google/vendor/guzzlehttp/guzzle/LICENSE ================================================ The MIT License (MIT) Copyright (c) 2011 Michael Dowling Copyright (c) 2012 Jeremy Lindblom Copyright (c) 2014 Graham Campbell Copyright (c) 2015 Márk Sági-Kazár Copyright (c) 2015 Tobias Schultze Copyright (c) 2016 Tobias Nyholm Copyright (c) 2016 George Mponos 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. ================================================ FILE: lib/Google/vendor/guzzlehttp/guzzle/README.md ================================================ ![Guzzle](.github/logo.png?raw=true) # Guzzle, PHP HTTP client [![Latest Version](https://img.shields.io/github/release/guzzle/guzzle.svg?style=flat-square)](https://github.com/guzzle/guzzle/releases) [![Build Status](https://img.shields.io/github/actions/workflow/status/guzzle/guzzle/ci.yml?label=ci%20build&style=flat-square)](https://github.com/guzzle/guzzle/actions?query=workflow%3ACI) [![Total Downloads](https://img.shields.io/packagist/dt/guzzlehttp/guzzle.svg?style=flat-square)](https://packagist.org/packages/guzzlehttp/guzzle) Guzzle is a PHP HTTP client that makes it easy to send HTTP requests and trivial to integrate with web services. - Simple interface for building query strings, POST requests, streaming large uploads, streaming large downloads, using HTTP cookies, uploading JSON data, etc... - Can send both synchronous and asynchronous requests using the same interface. - Uses PSR-7 interfaces for requests, responses, and streams. This allows you to utilize other PSR-7 compatible libraries with Guzzle. - Supports PSR-18 allowing interoperability between other PSR-18 HTTP Clients. - Abstracts away the underlying HTTP transport, allowing you to write environment and transport agnostic code; i.e., no hard dependency on cURL, PHP streams, sockets, or non-blocking event loops. - Middleware system allows you to augment and compose client behavior. ```php $client = new \GuzzleHttp\Client(); $response = $client->request('GET', 'https://api.github.com/repos/guzzle/guzzle'); echo $response->getStatusCode(); // 200 echo $response->getHeaderLine('content-type'); // 'application/json; charset=utf8' echo $response->getBody(); // '{"id": 1420053, "name": "guzzle", ...}' // Send an asynchronous request. $request = new \GuzzleHttp\Psr7\Request('GET', 'http://httpbin.org'); $promise = $client->sendAsync($request)->then(function ($response) { echo 'I completed! ' . $response->getBody(); }); $promise->wait(); ``` ## Help and docs We use GitHub issues only to discuss bugs and new features. For support please refer to: - [Documentation](https://docs.guzzlephp.org) - [Stack Overflow](https://stackoverflow.com/questions/tagged/guzzle) - [#guzzle](https://app.slack.com/client/T0D2S9JCT/CE6UAAKL4) channel on [PHP-HTTP Slack](https://slack.httplug.io/) - [Gitter](https://gitter.im/guzzle/guzzle) ## Installing Guzzle The recommended way to install Guzzle is through [Composer](https://getcomposer.org/). ```bash composer require guzzlehttp/guzzle ``` ## Version Guidance | Version | Status | Packagist | Namespace | Repo | Docs | PSR-7 | PHP Version | |---------|---------------------|---------------------|--------------|---------------------|---------------------|-------|--------------| | 3.x | EOL (2016-10-31) | `guzzle/guzzle` | `Guzzle` | [v3][guzzle-3-repo] | [v3][guzzle-3-docs] | No | >=5.3.3,<7.0 | | 4.x | EOL (2016-10-31) | `guzzlehttp/guzzle` | `GuzzleHttp` | [v4][guzzle-4-repo] | N/A | No | >=5.4,<7.0 | | 5.x | EOL (2019-10-31) | `guzzlehttp/guzzle` | `GuzzleHttp` | [v5][guzzle-5-repo] | [v5][guzzle-5-docs] | No | >=5.4,<7.4 | | 6.x | EOL (2023-10-31) | `guzzlehttp/guzzle` | `GuzzleHttp` | [v6][guzzle-6-repo] | [v6][guzzle-6-docs] | Yes | >=5.5,<8.0 | | 7.x | Latest | `guzzlehttp/guzzle` | `GuzzleHttp` | [v7][guzzle-7-repo] | [v7][guzzle-7-docs] | Yes | >=7.2.5,<8.5 | [guzzle-3-repo]: https://github.com/guzzle/guzzle3 [guzzle-4-repo]: https://github.com/guzzle/guzzle/tree/4.x [guzzle-5-repo]: https://github.com/guzzle/guzzle/tree/5.3 [guzzle-6-repo]: https://github.com/guzzle/guzzle/tree/6.5 [guzzle-7-repo]: https://github.com/guzzle/guzzle [guzzle-3-docs]: https://guzzle3.readthedocs.io/ [guzzle-5-docs]: https://docs.guzzlephp.org/en/5.3/ [guzzle-6-docs]: https://docs.guzzlephp.org/en/6.5/ [guzzle-7-docs]: https://docs.guzzlephp.org/en/latest/ ## Security If you discover a security vulnerability within this package, please send an email to security@tidelift.com. All security vulnerabilities will be promptly addressed. Please do not disclose security-related issues publicly until a fix has been announced. Please see [Security Policy](https://github.com/guzzle/guzzle/security/policy) for more information. ## License Guzzle is made available under the MIT License (MIT). Please see [License File](LICENSE) for more information. ## For Enterprise Available as part of the Tidelift Subscription The maintainers of Guzzle and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/packagist-guzzlehttp-guzzle?utm_source=packagist-guzzlehttp-guzzle&utm_medium=referral&utm_campaign=enterprise&utm_term=repo) ================================================ FILE: lib/Google/vendor/guzzlehttp/guzzle/UPGRADING.md ================================================ Guzzle Upgrade Guide ==================== 6.0 to 7.0 ---------- In order to take advantage of the new features of PHP, Guzzle dropped the support of PHP 5. The minimum supported PHP version is now PHP 7.2. Type hints and return types for functions and methods have been added wherever possible. Please make sure: - You are calling a function or a method with the correct type. - If you extend a class of Guzzle; update all signatures on methods you override. #### Other backwards compatibility breaking changes - Class `GuzzleHttp\UriTemplate` is removed. - Class `GuzzleHttp\Exception\SeekException` is removed. - Classes `GuzzleHttp\Exception\BadResponseException`, `GuzzleHttp\Exception\ClientException`, `GuzzleHttp\Exception\ServerException` can no longer be initialized with an empty Response as argument. - Class `GuzzleHttp\Exception\ConnectException` now extends `GuzzleHttp\Exception\TransferException` instead of `GuzzleHttp\Exception\RequestException`. - Function `GuzzleHttp\Exception\ConnectException::getResponse()` is removed. - Function `GuzzleHttp\Exception\ConnectException::hasResponse()` is removed. - Constant `GuzzleHttp\ClientInterface::VERSION` is removed. Added `GuzzleHttp\ClientInterface::MAJOR_VERSION` instead. - Function `GuzzleHttp\Exception\RequestException::getResponseBodySummary` is removed. Use `\GuzzleHttp\Psr7\get_message_body_summary` as an alternative. - Function `GuzzleHttp\Cookie\CookieJar::getCookieValue` is removed. - Request option `exceptions` is removed. Please use `http_errors`. - Request option `save_to` is removed. Please use `sink`. - Pool option `pool_size` is removed. Please use `concurrency`. - We now look for environment variables in the `$_SERVER` super global, due to thread safety issues with `getenv`. We continue to fallback to `getenv` in CLI environments, for maximum compatibility. - The `get`, `head`, `put`, `post`, `patch`, `delete`, `getAsync`, `headAsync`, `putAsync`, `postAsync`, `patchAsync`, and `deleteAsync` methods are now implemented as genuine methods on `GuzzleHttp\Client`, with strong typing. The original `__call` implementation remains unchanged for now, for maximum backwards compatibility, but won't be invoked under normal operation. - The `log` middleware will log the errors with level `error` instead of `notice` - Support for international domain names (IDN) is now disabled by default, and enabling it requires installing ext-intl, linked against a modern version of the C library (ICU 4.6 or higher). #### Native functions calls All internal native functions calls of Guzzle are now prefixed with a slash. This change makes it impossible for method overloading by other libraries or applications. Example: ```php // Before: curl_version(); // After: \curl_version(); ``` For the full diff you can check [here](https://github.com/guzzle/guzzle/compare/6.5.4..master). 5.0 to 6.0 ---------- Guzzle now uses [PSR-7](https://www.php-fig.org/psr/psr-7/) for HTTP messages. Due to the fact that these messages are immutable, this prompted a refactoring of Guzzle to use a middleware based system rather than an event system. Any HTTP message interaction (e.g., `GuzzleHttp\Message\Request`) need to be updated to work with the new immutable PSR-7 request and response objects. Any event listeners or subscribers need to be updated to become middleware functions that wrap handlers (or are injected into a `GuzzleHttp\HandlerStack`). - Removed `GuzzleHttp\BatchResults` - Removed `GuzzleHttp\Collection` - Removed `GuzzleHttp\HasDataTrait` - Removed `GuzzleHttp\ToArrayInterface` - The `guzzlehttp/streams` dependency has been removed. Stream functionality is now present in the `GuzzleHttp\Psr7` namespace provided by the `guzzlehttp/psr7` package. - Guzzle no longer uses ReactPHP promises and now uses the `guzzlehttp/promises` library. We use a custom promise library for three significant reasons: 1. React promises (at the time of writing this) are recursive. Promise chaining and promise resolution will eventually blow the stack. Guzzle promises are not recursive as they use a sort of trampolining technique. Note: there has been movement in the React project to modify promises to no longer utilize recursion. 2. Guzzle needs to have the ability to synchronously block on a promise to wait for a result. Guzzle promises allows this functionality (and does not require the use of recursion). 3. Because we need to be able to wait on a result, doing so using React promises requires wrapping react promises with RingPHP futures. This overhead is no longer needed, reducing stack sizes, reducing complexity, and improving performance. - `GuzzleHttp\Mimetypes` has been moved to a function in `GuzzleHttp\Psr7\mimetype_from_extension` and `GuzzleHttp\Psr7\mimetype_from_filename`. - `GuzzleHttp\Query` and `GuzzleHttp\QueryParser` have been removed. Query strings must now be passed into request objects as strings, or provided to the `query` request option when creating requests with clients. The `query` option uses PHP's `http_build_query` to convert an array to a string. If you need a different serialization technique, you will need to pass the query string in as a string. There are a couple helper functions that will make working with query strings easier: `GuzzleHttp\Psr7\parse_query` and `GuzzleHttp\Psr7\build_query`. - Guzzle no longer has a dependency on RingPHP. Due to the use of a middleware system based on PSR-7, using RingPHP and it's middleware system as well adds more complexity than the benefits it provides. All HTTP handlers that were present in RingPHP have been modified to work directly with PSR-7 messages and placed in the `GuzzleHttp\Handler` namespace. This significantly reduces complexity in Guzzle, removes a dependency, and improves performance. RingPHP will be maintained for Guzzle 5 support, but will no longer be a part of Guzzle 6. - As Guzzle now uses a middleware based systems the event system and RingPHP integration has been removed. Note: while the event system has been removed, it is possible to add your own type of event system that is powered by the middleware system. - Removed the `Event` namespace. - Removed the `Subscriber` namespace. - Removed `Transaction` class - Removed `RequestFsm` - Removed `RingBridge` - `GuzzleHttp\Subscriber\Cookie` is now provided by `GuzzleHttp\Middleware::cookies` - `GuzzleHttp\Subscriber\HttpError` is now provided by `GuzzleHttp\Middleware::httpError` - `GuzzleHttp\Subscriber\History` is now provided by `GuzzleHttp\Middleware::history` - `GuzzleHttp\Subscriber\Mock` is now provided by `GuzzleHttp\Handler\MockHandler` - `GuzzleHttp\Subscriber\Prepare` is now provided by `GuzzleHttp\PrepareBodyMiddleware` - `GuzzleHttp\Subscriber\Redirect` is now provided by `GuzzleHttp\RedirectMiddleware` - Guzzle now uses `Psr\Http\Message\UriInterface` (implements in `GuzzleHttp\Psr7\Uri`) for URI support. `GuzzleHttp\Url` is now gone. - Static functions in `GuzzleHttp\Utils` have been moved to namespaced functions under the `GuzzleHttp` namespace. This requires either a Composer based autoloader or you to include functions.php. - `GuzzleHttp\ClientInterface::getDefaultOption` has been renamed to `GuzzleHttp\ClientInterface::getConfig`. - `GuzzleHttp\ClientInterface::setDefaultOption` has been removed. - The `json` and `xml` methods of response objects has been removed. With the migration to strictly adhering to PSR-7 as the interface for Guzzle messages, adding methods to message interfaces would actually require Guzzle messages to extend from PSR-7 messages rather then work with them directly. ## Migrating to middleware The change to PSR-7 unfortunately required significant refactoring to Guzzle due to the fact that PSR-7 messages are immutable. Guzzle 5 relied on an event system from plugins. The event system relied on mutability of HTTP messages and side effects in order to work. With immutable messages, you have to change your workflow to become more about either returning a value (e.g., functional middlewares) or setting a value on an object. Guzzle v6 has chosen the functional middleware approach. Instead of using the event system to listen for things like the `before` event, you now create a stack based middleware function that intercepts a request on the way in and the promise of the response on the way out. This is a much simpler and more predictable approach than the event system and works nicely with PSR-7 middleware. Due to the use of promises, the middleware system is also asynchronous. v5: ```php use GuzzleHttp\Event\BeforeEvent; $client = new GuzzleHttp\Client(); // Get the emitter and listen to the before event. $client->getEmitter()->on('before', function (BeforeEvent $e) { // Guzzle v5 events relied on mutation $e->getRequest()->setHeader('X-Foo', 'Bar'); }); ``` v6: In v6, you can modify the request before it is sent using the `mapRequest` middleware. The idiomatic way in v6 to modify the request/response lifecycle is to setup a handler middleware stack up front and inject the handler into a client. ```php use GuzzleHttp\Middleware; // Create a handler stack that has all of the default middlewares attached $handler = GuzzleHttp\HandlerStack::create(); // Push the handler onto the handler stack $handler->push(Middleware::mapRequest(function (RequestInterface $request) { // Notice that we have to return a request object return $request->withHeader('X-Foo', 'Bar'); })); // Inject the handler into the client $client = new GuzzleHttp\Client(['handler' => $handler]); ``` ## POST Requests This version added the [`form_params`](https://docs.guzzlephp.org/en/latest/request-options.html#form_params) and `multipart` request options. `form_params` is an associative array of strings or array of strings and is used to serialize an `application/x-www-form-urlencoded` POST request. The [`multipart`](https://docs.guzzlephp.org/en/latest/request-options.html#multipart) option is now used to send a multipart/form-data POST request. `GuzzleHttp\Post\PostFile` has been removed. Use the `multipart` option to add POST files to a multipart/form-data request. The `body` option no longer accepts an array to send POST requests. Please use `multipart` or `form_params` instead. The `base_url` option has been renamed to `base_uri`. 4.x to 5.0 ---------- ## Rewritten Adapter Layer Guzzle now uses [RingPHP](https://ringphp.readthedocs.org/en/latest) to send HTTP requests. The `adapter` option in a `GuzzleHttp\Client` constructor is still supported, but it has now been renamed to `handler`. Instead of passing a `GuzzleHttp\Adapter\AdapterInterface`, you must now pass a PHP `callable` that follows the RingPHP specification. ## Removed Fluent Interfaces [Fluent interfaces were removed](https://ocramius.github.io/blog/fluent-interfaces-are-evil/) from the following classes: - `GuzzleHttp\Collection` - `GuzzleHttp\Url` - `GuzzleHttp\Query` - `GuzzleHttp\Post\PostBody` - `GuzzleHttp\Cookie\SetCookie` ## Removed functions.php Removed "functions.php", so that Guzzle is truly PSR-4 compliant. The following functions can be used as replacements. - `GuzzleHttp\json_decode` -> `GuzzleHttp\Utils::jsonDecode` - `GuzzleHttp\get_path` -> `GuzzleHttp\Utils::getPath` - `GuzzleHttp\Utils::setPath` -> `GuzzleHttp\set_path` - `GuzzleHttp\Pool::batch` -> `GuzzleHttp\batch`. This function is, however, deprecated in favor of using `GuzzleHttp\Pool::batch()`. The "procedural" global client has been removed with no replacement (e.g., `GuzzleHttp\get()`, `GuzzleHttp\post()`, etc.). Use a `GuzzleHttp\Client` object as a replacement. ## `throwImmediately` has been removed The concept of "throwImmediately" has been removed from exceptions and error events. This control mechanism was used to stop a transfer of concurrent requests from completing. This can now be handled by throwing the exception or by cancelling a pool of requests or each outstanding future request individually. ## headers event has been removed Removed the "headers" event. This event was only useful for changing the body a response once the headers of the response were known. You can implement a similar behavior in a number of ways. One example might be to use a FnStream that has access to the transaction being sent. For example, when the first byte is written, you could check if the response headers match your expectations, and if so, change the actual stream body that is being written to. ## Updates to HTTP Messages Removed the `asArray` parameter from `GuzzleHttp\Message\MessageInterface::getHeader`. If you want to get a header value as an array, then use the newly added `getHeaderAsArray()` method of `MessageInterface`. This change makes the Guzzle interfaces compatible with the PSR-7 interfaces. 3.x to 4.0 ---------- ## Overarching changes: - Now requires PHP 5.4 or greater. - No longer requires cURL to send requests. - Guzzle no longer wraps every exception it throws. Only exceptions that are recoverable are now wrapped by Guzzle. - Various namespaces have been removed or renamed. - No longer requiring the Symfony EventDispatcher. A custom event dispatcher based on the Symfony EventDispatcher is now utilized in `GuzzleHttp\Event\EmitterInterface` (resulting in significant speed and functionality improvements). Changes per Guzzle 3.x namespace are described below. ## Batch The `Guzzle\Batch` namespace has been removed. This is best left to third-parties to implement on top of Guzzle's core HTTP library. ## Cache The `Guzzle\Cache` namespace has been removed. (Todo: No suitable replacement has been implemented yet, but hoping to utilize a PSR cache interface). ## Common - Removed all of the wrapped exceptions. It's better to use the standard PHP library for unrecoverable exceptions. - `FromConfigInterface` has been removed. - `Guzzle\Common\Version` has been removed. The VERSION constant can be found at `GuzzleHttp\ClientInterface::VERSION`. ### Collection - `getAll` has been removed. Use `toArray` to convert a collection to an array. - `inject` has been removed. - `keySearch` has been removed. - `getPath` no longer supports wildcard expressions. Use something better like JMESPath for this. - `setPath` now supports appending to an existing array via the `[]` notation. ### Events Guzzle no longer requires Symfony's EventDispatcher component. Guzzle now uses `GuzzleHttp\Event\Emitter`. - `Symfony\Component\EventDispatcher\EventDispatcherInterface` is replaced by `GuzzleHttp\Event\EmitterInterface`. - `Symfony\Component\EventDispatcher\EventDispatcher` is replaced by `GuzzleHttp\Event\Emitter`. - `Symfony\Component\EventDispatcher\Event` is replaced by `GuzzleHttp\Event\Event`, and Guzzle now has an EventInterface in `GuzzleHttp\Event\EventInterface`. - `AbstractHasDispatcher` has moved to a trait, `HasEmitterTrait`, and `HasDispatcherInterface` has moved to `HasEmitterInterface`. Retrieving the event emitter of a request, client, etc. now uses the `getEmitter` method rather than the `getDispatcher` method. #### Emitter - Use the `once()` method to add a listener that automatically removes itself the first time it is invoked. - Use the `listeners()` method to retrieve a list of event listeners rather than the `getListeners()` method. - Use `emit()` instead of `dispatch()` to emit an event from an emitter. - Use `attach()` instead of `addSubscriber()` and `detach()` instead of `removeSubscriber()`. ```php $mock = new Mock(); // 3.x $request->getEventDispatcher()->addSubscriber($mock); $request->getEventDispatcher()->removeSubscriber($mock); // 4.x $request->getEmitter()->attach($mock); $request->getEmitter()->detach($mock); ``` Use the `on()` method to add a listener rather than the `addListener()` method. ```php // 3.x $request->getEventDispatcher()->addListener('foo', function (Event $event) { /* ... */ } ); // 4.x $request->getEmitter()->on('foo', function (Event $event, $name) { /* ... */ } ); ``` ## Http ### General changes - The cacert.pem certificate has been moved to `src/cacert.pem`. - Added the concept of adapters that are used to transfer requests over the wire. - Simplified the event system. - Sending requests in parallel is still possible, but batching is no longer a concept of the HTTP layer. Instead, you must use the `complete` and `error` events to asynchronously manage parallel request transfers. - `Guzzle\Http\Url` has moved to `GuzzleHttp\Url`. - `Guzzle\Http\QueryString` has moved to `GuzzleHttp\Query`. - QueryAggregators have been rewritten so that they are simply callable functions. - `GuzzleHttp\StaticClient` has been removed. Use the functions provided in `functions.php` for an easy to use static client instance. - Exceptions in `GuzzleHttp\Exception` have been updated to all extend from `GuzzleHttp\Exception\TransferException`. ### Client Calling methods like `get()`, `post()`, `head()`, etc. no longer create and return a request, but rather creates a request, sends the request, and returns the response. ```php // 3.0 $request = $client->get('/'); $response = $request->send(); // 4.0 $response = $client->get('/'); // or, to mirror the previous behavior $request = $client->createRequest('GET', '/'); $response = $client->send($request); ``` `GuzzleHttp\ClientInterface` has changed. - The `send` method no longer accepts more than one request. Use `sendAll` to send multiple requests in parallel. - `setUserAgent()` has been removed. Use a default request option instead. You could, for example, do something like: `$client->setConfig('defaults/headers/User-Agent', 'Foo/Bar ' . $client::getDefaultUserAgent())`. - `setSslVerification()` has been removed. Use default request options instead, like `$client->setConfig('defaults/verify', true)`. `GuzzleHttp\Client` has changed. - The constructor now accepts only an associative array. You can include a `base_url` string or array to use a URI template as the base URL of a client. You can also specify a `defaults` key that is an associative array of default request options. You can pass an `adapter` to use a custom adapter, `batch_adapter` to use a custom adapter for sending requests in parallel, or a `message_factory` to change the factory used to create HTTP requests and responses. - The client no longer emits a `client.create_request` event. - Creating requests with a client no longer automatically utilize a URI template. You must pass an array into a creational method (e.g., `createRequest`, `get`, `put`, etc.) in order to expand a URI template. ### Messages Messages no longer have references to their counterparts (i.e., a request no longer has a reference to it's response, and a response no loger has a reference to its request). This association is now managed through a `GuzzleHttp\Adapter\TransactionInterface` object. You can get references to these transaction objects using request events that are emitted over the lifecycle of a request. #### Requests with a body - `GuzzleHttp\Message\EntityEnclosingRequest` and `GuzzleHttp\Message\EntityEnclosingRequestInterface` have been removed. The separation between requests that contain a body and requests that do not contain a body has been removed, and now `GuzzleHttp\Message\RequestInterface` handles both use cases. - Any method that previously accepts a `GuzzleHttp\Response` object now accept a `GuzzleHttp\Message\ResponseInterface`. - `GuzzleHttp\Message\RequestFactoryInterface` has been renamed to `GuzzleHttp\Message\MessageFactoryInterface`. This interface is used to create both requests and responses and is implemented in `GuzzleHttp\Message\MessageFactory`. - POST field and file methods have been removed from the request object. You must now use the methods made available to `GuzzleHttp\Post\PostBodyInterface` to control the format of a POST body. Requests that are created using a standard `GuzzleHttp\Message\MessageFactoryInterface` will automatically use a `GuzzleHttp\Post\PostBody` body if the body was passed as an array or if the method is POST and no body is provided. ```php $request = $client->createRequest('POST', '/'); $request->getBody()->setField('foo', 'bar'); $request->getBody()->addFile(new PostFile('file_key', fopen('/path/to/content', 'r'))); ``` #### Headers - `GuzzleHttp\Message\Header` has been removed. Header values are now simply represented by an array of values or as a string. Header values are returned as a string by default when retrieving a header value from a message. You can pass an optional argument of `true` to retrieve a header value as an array of strings instead of a single concatenated string. - `GuzzleHttp\PostFile` and `GuzzleHttp\PostFileInterface` have been moved to `GuzzleHttp\Post`. This interface has been simplified and now allows the addition of arbitrary headers. - Custom headers like `GuzzleHttp\Message\Header\Link` have been removed. Most of the custom headers are now handled separately in specific subscribers/plugins, and `GuzzleHttp\Message\HeaderValues::parseParams()` has been updated to properly handle headers that contain parameters (like the `Link` header). #### Responses - `GuzzleHttp\Message\Response::getInfo()` and `GuzzleHttp\Message\Response::setInfo()` have been removed. Use the event system to retrieve this type of information. - `GuzzleHttp\Message\Response::getRawHeaders()` has been removed. - `GuzzleHttp\Message\Response::getMessage()` has been removed. - `GuzzleHttp\Message\Response::calculateAge()` and other cache specific methods have moved to the CacheSubscriber. - Header specific helper functions like `getContentMd5()` have been removed. Just use `getHeader('Content-MD5')` instead. - `GuzzleHttp\Message\Response::setRequest()` and `GuzzleHttp\Message\Response::getRequest()` have been removed. Use the event system to work with request and response objects as a transaction. - `GuzzleHttp\Message\Response::getRedirectCount()` has been removed. Use the Redirect subscriber instead. - `GuzzleHttp\Message\Response::isSuccessful()` and other related methods have been removed. Use `getStatusCode()` instead. #### Streaming responses Streaming requests can now be created by a client directly, returning a `GuzzleHttp\Message\ResponseInterface` object that contains a body stream referencing an open PHP HTTP stream. ```php // 3.0 use Guzzle\Stream\PhpStreamRequestFactory; $request = $client->get('/'); $factory = new PhpStreamRequestFactory(); $stream = $factory->fromRequest($request); $data = $stream->read(1024); // 4.0 $response = $client->get('/', ['stream' => true]); // Read some data off of the stream in the response body $data = $response->getBody()->read(1024); ``` #### Redirects The `configureRedirects()` method has been removed in favor of a `allow_redirects` request option. ```php // Standard redirects with a default of a max of 5 redirects $request = $client->createRequest('GET', '/', ['allow_redirects' => true]); // Strict redirects with a custom number of redirects $request = $client->createRequest('GET', '/', [ 'allow_redirects' => ['max' => 5, 'strict' => true] ]); ``` #### EntityBody EntityBody interfaces and classes have been removed or moved to `GuzzleHttp\Stream`. All classes and interfaces that once required `GuzzleHttp\EntityBodyInterface` now require `GuzzleHttp\Stream\StreamInterface`. Creating a new body for a request no longer uses `GuzzleHttp\EntityBody::factory` but now uses `GuzzleHttp\Stream\Stream::factory` or even better: `GuzzleHttp\Stream\create()`. - `Guzzle\Http\EntityBodyInterface` is now `GuzzleHttp\Stream\StreamInterface` - `Guzzle\Http\EntityBody` is now `GuzzleHttp\Stream\Stream` - `Guzzle\Http\CachingEntityBody` is now `GuzzleHttp\Stream\CachingStream` - `Guzzle\Http\ReadLimitEntityBody` is now `GuzzleHttp\Stream\LimitStream` - `Guzzle\Http\IoEmittyinEntityBody` has been removed. #### Request lifecycle events Requests previously submitted a large number of requests. The number of events emitted over the lifecycle of a request has been significantly reduced to make it easier to understand how to extend the behavior of a request. All events emitted during the lifecycle of a request now emit a custom `GuzzleHttp\Event\EventInterface` object that contains context providing methods and a way in which to modify the transaction at that specific point in time (e.g., intercept the request and set a response on the transaction). - `request.before_send` has been renamed to `before` and now emits a `GuzzleHttp\Event\BeforeEvent` - `request.complete` has been renamed to `complete` and now emits a `GuzzleHttp\Event\CompleteEvent`. - `request.sent` has been removed. Use `complete`. - `request.success` has been removed. Use `complete`. - `error` is now an event that emits a `GuzzleHttp\Event\ErrorEvent`. - `request.exception` has been removed. Use `error`. - `request.receive.status_line` has been removed. - `curl.callback.progress` has been removed. Use a custom `StreamInterface` to maintain a status update. - `curl.callback.write` has been removed. Use a custom `StreamInterface` to intercept writes. - `curl.callback.read` has been removed. Use a custom `StreamInterface` to intercept reads. `headers` is a new event that is emitted after the response headers of a request have been received before the body of the response is downloaded. This event emits a `GuzzleHttp\Event\HeadersEvent`. You can intercept a request and inject a response using the `intercept()` event of a `GuzzleHttp\Event\BeforeEvent`, `GuzzleHttp\Event\CompleteEvent`, and `GuzzleHttp\Event\ErrorEvent` event. See: https://docs.guzzlephp.org/en/latest/events.html ## Inflection The `Guzzle\Inflection` namespace has been removed. This is not a core concern of Guzzle. ## Iterator The `Guzzle\Iterator` namespace has been removed. - `Guzzle\Iterator\AppendIterator`, `Guzzle\Iterator\ChunkedIterator`, and `Guzzle\Iterator\MethodProxyIterator` are nice, but not a core requirement of Guzzle itself. - `Guzzle\Iterator\FilterIterator` is no longer needed because an equivalent class is shipped with PHP 5.4. - `Guzzle\Iterator\MapIterator` is not really needed when using PHP 5.5 because it's easier to just wrap an iterator in a generator that maps values. For a replacement of these iterators, see https://github.com/nikic/iter ## Log The LogPlugin has moved to https://github.com/guzzle/log-subscriber. The `Guzzle\Log` namespace has been removed. Guzzle now relies on `Psr\Log\LoggerInterface` for all logging. The MessageFormatter class has been moved to `GuzzleHttp\Subscriber\Log\Formatter`. ## Parser The `Guzzle\Parser` namespace has been removed. This was previously used to make it possible to plug in custom parsers for cookies, messages, URI templates, and URLs; however, this level of complexity is not needed in Guzzle so it has been removed. - Cookie: Cookie parsing logic has been moved to `GuzzleHttp\Cookie\SetCookie::fromString`. - Message: Message parsing logic for both requests and responses has been moved to `GuzzleHttp\Message\MessageFactory::fromMessage`. Message parsing is only used in debugging or deserializing messages, so it doesn't make sense for Guzzle as a library to add this level of complexity to parsing messages. - UriTemplate: URI template parsing has been moved to `GuzzleHttp\UriTemplate`. The Guzzle library will automatically use the PECL URI template library if it is installed. - Url: URL parsing is now performed in `GuzzleHttp\Url::fromString` (previously it was `Guzzle\Http\Url::factory()`). If custom URL parsing is necessary, then developers are free to subclass `GuzzleHttp\Url`. ## Plugin The `Guzzle\Plugin` namespace has been renamed to `GuzzleHttp\Subscriber`. Several plugins are shipping with the core Guzzle library under this namespace. - `GuzzleHttp\Subscriber\Cookie`: Replaces the old CookiePlugin. Cookie jar code has moved to `GuzzleHttp\Cookie`. - `GuzzleHttp\Subscriber\History`: Replaces the old HistoryPlugin. - `GuzzleHttp\Subscriber\HttpError`: Throws errors when a bad HTTP response is received. - `GuzzleHttp\Subscriber\Mock`: Replaces the old MockPlugin. - `GuzzleHttp\Subscriber\Prepare`: Prepares the body of a request just before sending. This subscriber is attached to all requests by default. - `GuzzleHttp\Subscriber\Redirect`: Replaces the RedirectPlugin. The following plugins have been removed (third-parties are free to re-implement these if needed): - `GuzzleHttp\Plugin\Async` has been removed. - `GuzzleHttp\Plugin\CurlAuth` has been removed. - `GuzzleHttp\Plugin\ErrorResponse\ErrorResponsePlugin` has been removed. This functionality should instead be implemented with event listeners that occur after normal response parsing occurs in the guzzle/command package. The following plugins are not part of the core Guzzle package, but are provided in separate repositories: - `Guzzle\Http\Plugin\BackoffPlugin` has been rewritten to be much simpler to build custom retry policies using simple functions rather than various chained classes. See: https://github.com/guzzle/retry-subscriber - `Guzzle\Http\Plugin\Cache\CachePlugin` has moved to https://github.com/guzzle/cache-subscriber - `Guzzle\Http\Plugin\Log\LogPlugin` has moved to https://github.com/guzzle/log-subscriber - `Guzzle\Http\Plugin\Md5\Md5Plugin` has moved to https://github.com/guzzle/message-integrity-subscriber - `Guzzle\Http\Plugin\Mock\MockPlugin` has moved to `GuzzleHttp\Subscriber\MockSubscriber`. - `Guzzle\Http\Plugin\Oauth\OauthPlugin` has moved to https://github.com/guzzle/oauth-subscriber ## Service The service description layer of Guzzle has moved into two separate packages: - https://github.com/guzzle/command Provides a high level abstraction over web services by representing web service operations using commands. - https://github.com/guzzle/guzzle-services Provides an implementation of guzzle/command that provides request serialization and response parsing using Guzzle service descriptions. ## Stream Stream have moved to a separate package available at https://github.com/guzzle/streams. `Guzzle\Stream\StreamInterface` has been given a large update to cleanly take on the responsibilities of `Guzzle\Http\EntityBody` and `Guzzle\Http\EntityBodyInterface` now that they have been removed. The number of methods implemented by the `StreamInterface` has been drastically reduced to allow developers to more easily extend and decorate stream behavior. ## Removed methods from StreamInterface - `getStream` and `setStream` have been removed to better encapsulate streams. - `getMetadata` and `setMetadata` have been removed in favor of `GuzzleHttp\Stream\MetadataStreamInterface`. - `getWrapper`, `getWrapperData`, `getStreamType`, and `getUri` have all been removed. This data is accessible when using streams that implement `GuzzleHttp\Stream\MetadataStreamInterface`. - `rewind` has been removed. Use `seek(0)` for a similar behavior. ## Renamed methods - `detachStream` has been renamed to `detach`. - `feof` has been renamed to `eof`. - `ftell` has been renamed to `tell`. - `readLine` has moved from an instance method to a static class method of `GuzzleHttp\Stream\Stream`. ## Metadata streams `GuzzleHttp\Stream\MetadataStreamInterface` has been added to denote streams that contain additional metadata accessible via `getMetadata()`. `GuzzleHttp\Stream\StreamInterface::getMetadata` and `GuzzleHttp\Stream\StreamInterface::setMetadata` have been removed. ## StreamRequestFactory The entire concept of the StreamRequestFactory has been removed. The way this was used in Guzzle 3 broke the actual interface of sending streaming requests (instead of getting back a Response, you got a StreamInterface). Streaming PHP requests are now implemented through the `GuzzleHttp\Adapter\StreamAdapter`. 3.6 to 3.7 ---------- ### Deprecations - You can now enable E_USER_DEPRECATED warnings to see if you are using any deprecated methods.: ```php \Guzzle\Common\Version::$emitWarnings = true; ``` The following APIs and options have been marked as deprecated: - Marked `Guzzle\Http\Message\Request::isResponseBodyRepeatable()` as deprecated. Use `$request->getResponseBody()->isRepeatable()` instead. - Marked `Guzzle\Http\Message\Request::canCache()` as deprecated. Use `Guzzle\Plugin\Cache\DefaultCanCacheStrategy->canCacheRequest()` instead. - Marked `Guzzle\Http\Message\Request::canCache()` as deprecated. Use `Guzzle\Plugin\Cache\DefaultCanCacheStrategy->canCacheRequest()` instead. - Marked `Guzzle\Http\Message\Request::setIsRedirect()` as deprecated. Use the HistoryPlugin instead. - Marked `Guzzle\Http\Message\Request::isRedirect()` as deprecated. Use the HistoryPlugin instead. - Marked `Guzzle\Cache\CacheAdapterFactory::factory()` as deprecated - Marked `Guzzle\Service\Client::enableMagicMethods()` as deprecated. Magic methods can no longer be disabled on a Guzzle\Service\Client. - Marked `Guzzle\Parser\Url\UrlParser` as deprecated. Just use PHP's `parse_url()` and percent encode your UTF-8. - Marked `Guzzle\Common\Collection::inject()` as deprecated. - Marked `Guzzle\Plugin\CurlAuth\CurlAuthPlugin` as deprecated. Use `$client->getConfig()->setPath('request.options/auth', array('user', 'pass', 'Basic|Digest|NTLM|Any'));` or `$client->setDefaultOption('auth', array('user', 'pass', 'Basic|Digest|NTLM|Any'));` 3.7 introduces `request.options` as a parameter for a client configuration and as an optional argument to all creational request methods. When paired with a client's configuration settings, these options allow you to specify default settings for various aspects of a request. Because these options make other previous configuration options redundant, several configuration options and methods of a client and AbstractCommand have been deprecated. - Marked `Guzzle\Service\Client::getDefaultHeaders()` as deprecated. Use `$client->getDefaultOption('headers')`. - Marked `Guzzle\Service\Client::setDefaultHeaders()` as deprecated. Use `$client->setDefaultOption('headers/{header_name}', 'value')`. - Marked 'request.params' for `Guzzle\Http\Client` as deprecated. Use `$client->setDefaultOption('params/{param_name}', 'value')` - Marked 'command.headers', 'command.response_body' and 'command.on_complete' as deprecated for AbstractCommand. These will work through Guzzle 4.0 $command = $client->getCommand('foo', array( 'command.headers' => array('Test' => '123'), 'command.response_body' => '/path/to/file' )); // Should be changed to: $command = $client->getCommand('foo', array( 'command.request_options' => array( 'headers' => array('Test' => '123'), 'save_as' => '/path/to/file' ) )); ### Interface changes Additions and changes (you will need to update any implementations or subclasses you may have created): - Added an `$options` argument to the end of the following methods of `Guzzle\Http\ClientInterface`: createRequest, head, delete, put, patch, post, options, prepareRequest - Added an `$options` argument to the end of `Guzzle\Http\Message\Request\RequestFactoryInterface::createRequest()` - Added an `applyOptions()` method to `Guzzle\Http\Message\Request\RequestFactoryInterface` - Changed `Guzzle\Http\ClientInterface::get($uri = null, $headers = null, $body = null)` to `Guzzle\Http\ClientInterface::get($uri = null, $headers = null, $options = array())`. You can still pass in a resource, string, or EntityBody into the $options parameter to specify the download location of the response. - Changed `Guzzle\Common\Collection::__construct($data)` to no longer accepts a null value for `$data` but a default `array()` - Added `Guzzle\Stream\StreamInterface::isRepeatable` - Made `Guzzle\Http\Client::expandTemplate` and `getUriTemplate` protected methods. The following methods were removed from interfaces. All of these methods are still available in the concrete classes that implement them, but you should update your code to use alternative methods: - Removed `Guzzle\Http\ClientInterface::setDefaultHeaders(). Use `$client->getConfig()->setPath('request.options/headers/{header_name}', 'value')`. or `$client->getConfig()->setPath('request.options/headers', array('header_name' => 'value'))` or `$client->setDefaultOption('headers/{header_name}', 'value')`. or `$client->setDefaultOption('headers', array('header_name' => 'value'))`. - Removed `Guzzle\Http\ClientInterface::getDefaultHeaders(). Use `$client->getConfig()->getPath('request.options/headers')`. - Removed `Guzzle\Http\ClientInterface::expandTemplate()`. This is an implementation detail. - Removed `Guzzle\Http\ClientInterface::setRequestFactory()`. This is an implementation detail. - Removed `Guzzle\Http\ClientInterface::getCurlMulti()`. This is a very specific implementation detail. - Removed `Guzzle\Http\Message\RequestInterface::canCache`. Use the CachePlugin. - Removed `Guzzle\Http\Message\RequestInterface::setIsRedirect`. Use the HistoryPlugin. - Removed `Guzzle\Http\Message\RequestInterface::isRedirect`. Use the HistoryPlugin. ### Cache plugin breaking changes - CacheKeyProviderInterface and DefaultCacheKeyProvider are no longer used. All of this logic is handled in a CacheStorageInterface. These two objects and interface will be removed in a future version. - Always setting X-cache headers on cached responses - Default cache TTLs are now handled by the CacheStorageInterface of a CachePlugin - `CacheStorageInterface::cache($key, Response $response, $ttl = null)` has changed to `cache(RequestInterface $request, Response $response);` - `CacheStorageInterface::fetch($key)` has changed to `fetch(RequestInterface $request);` - `CacheStorageInterface::delete($key)` has changed to `delete(RequestInterface $request);` - Added `CacheStorageInterface::purge($url)` - `DefaultRevalidation::__construct(CacheKeyProviderInterface $cacheKey, CacheStorageInterface $cache, CachePlugin $plugin)` has changed to `DefaultRevalidation::__construct(CacheStorageInterface $cache, CanCacheStrategyInterface $canCache = null)` - Added `RevalidationInterface::shouldRevalidate(RequestInterface $request, Response $response)` 3.5 to 3.6 ---------- * Mixed casing of headers are now forced to be a single consistent casing across all values for that header. * Messages internally use a HeaderCollection object to delegate handling case-insensitive header resolution * Removed the whole changedHeader() function system of messages because all header changes now go through addHeader(). For example, setHeader() first removes the header using unset on a HeaderCollection and then calls addHeader(). Keeping the Host header and URL host in sync is now handled by overriding the addHeader method in Request. * Specific header implementations can be created for complex headers. When a message creates a header, it uses a HeaderFactory which can map specific headers to specific header classes. There is now a Link header and CacheControl header implementation. * Moved getLinks() from Response to just be used on a Link header object. If you previously relied on Guzzle\Http\Message\Header::raw(), then you will need to update your code to use the HeaderInterface (e.g. toArray(), getAll(), etc.). ### Interface changes * Removed from interface: Guzzle\Http\ClientInterface::setUriTemplate * Removed from interface: Guzzle\Http\ClientInterface::setCurlMulti() * Removed Guzzle\Http\Message\Request::receivedRequestHeader() and implemented this functionality in Guzzle\Http\Curl\RequestMediator * Removed the optional $asString parameter from MessageInterface::getHeader(). Just cast the header to a string. * Removed the optional $tryChunkedTransfer option from Guzzle\Http\Message\EntityEnclosingRequestInterface * Removed the $asObjects argument from Guzzle\Http\Message\MessageInterface::getHeaders() ### Removed deprecated functions * Removed Guzzle\Parser\ParserRegister::get(). Use getParser() * Removed Guzzle\Parser\ParserRegister::set(). Use registerParser(). ### Deprecations * The ability to case-insensitively search for header values * Guzzle\Http\Message\Header::hasExactHeader * Guzzle\Http\Message\Header::raw. Use getAll() * Deprecated cache control specific methods on Guzzle\Http\Message\AbstractMessage. Use the CacheControl header object instead. ### Other changes * All response header helper functions return a string rather than mixing Header objects and strings inconsistently * Removed cURL blacklist support. This is no longer necessary now that Expect, Accept, etc. are managed by Guzzle directly via interfaces * Removed the injecting of a request object onto a response object. The methods to get and set a request still exist but are a no-op until removed. * Most classes that used to require a `Guzzle\Service\Command\CommandInterface` typehint now request a `Guzzle\Service\Command\ArrayCommandInterface`. * Added `Guzzle\Http\Message\RequestInterface::startResponse()` to the RequestInterface to handle injecting a response on a request while the request is still being transferred * `Guzzle\Service\Command\CommandInterface` now extends from ToArrayInterface and ArrayAccess 3.3 to 3.4 ---------- Base URLs of a client now follow the rules of https://datatracker.ietf.org/doc/html/rfc3986#section-5.2.2 when merging URLs. 3.2 to 3.3 ---------- ### Response::getEtag() quote stripping removed `Guzzle\Http\Message\Response::getEtag()` no longer strips quotes around the ETag response header ### Removed `Guzzle\Http\Utils` The `Guzzle\Http\Utils` class was removed. This class was only used for testing. ### Stream wrapper and type `Guzzle\Stream\Stream::getWrapper()` and `Guzzle\Stream\Stream::getStreamType()` are no longer converted to lowercase. ### curl.emit_io became emit_io Emitting IO events from a RequestMediator is now a parameter that must be set in a request's curl options using the 'emit_io' key. This was previously set under a request's parameters using 'curl.emit_io' 3.1 to 3.2 ---------- ### CurlMulti is no longer reused globally Before 3.2, the same CurlMulti object was reused globally for each client. This can cause issue where plugins added to a single client can pollute requests dispatched from other clients. If you still wish to reuse the same CurlMulti object with each client, then you can add a listener to the ServiceBuilder's `service_builder.create_client` event to inject a custom CurlMulti object into each client as it is created. ```php $multi = new Guzzle\Http\Curl\CurlMulti(); $builder = Guzzle\Service\Builder\ServiceBuilder::factory('/path/to/config.json'); $builder->addListener('service_builder.create_client', function ($event) use ($multi) { $event['client']->setCurlMulti($multi); } }); ``` ### No default path URLs no longer have a default path value of '/' if no path was specified. Before: ```php $request = $client->get('http://www.foo.com'); echo $request->getUrl(); // >> http://www.foo.com/ ``` After: ```php $request = $client->get('http://www.foo.com'); echo $request->getUrl(); // >> http://www.foo.com ``` ### Less verbose BadResponseException The exception message for `Guzzle\Http\Exception\BadResponseException` no longer contains the full HTTP request and response information. You can, however, get access to the request and response object by calling `getRequest()` or `getResponse()` on the exception object. ### Query parameter aggregation Multi-valued query parameters are no longer aggregated using a callback function. `Guzzle\Http\Query` now has a setAggregator() method that accepts a `Guzzle\Http\QueryAggregator\QueryAggregatorInterface` object. This object is responsible for handling the aggregation of multi-valued query string variables into a flattened hash. 2.8 to 3.x ---------- ### Guzzle\Service\Inspector Change `\Guzzle\Service\Inspector::fromConfig` to `\Guzzle\Common\Collection::fromConfig` **Before** ```php use Guzzle\Service\Inspector; class YourClient extends \Guzzle\Service\Client { public static function factory($config = array()) { $default = array(); $required = array('base_url', 'username', 'api_key'); $config = Inspector::fromConfig($config, $default, $required); $client = new self( $config->get('base_url'), $config->get('username'), $config->get('api_key') ); $client->setConfig($config); $client->setDescription(ServiceDescription::factory(__DIR__ . DIRECTORY_SEPARATOR . 'client.json')); return $client; } ``` **After** ```php use Guzzle\Common\Collection; class YourClient extends \Guzzle\Service\Client { public static function factory($config = array()) { $default = array(); $required = array('base_url', 'username', 'api_key'); $config = Collection::fromConfig($config, $default, $required); $client = new self( $config->get('base_url'), $config->get('username'), $config->get('api_key') ); $client->setConfig($config); $client->setDescription(ServiceDescription::factory(__DIR__ . DIRECTORY_SEPARATOR . 'client.json')); return $client; } ``` ### Convert XML Service Descriptions to JSON **Before** ```xml Get a list of groups Uses a search query to get a list of groups Create a group Delete a group by ID Update a group ``` **After** ```json { "name": "Zendesk REST API v2", "apiVersion": "2012-12-31", "description":"Provides access to Zendesk views, groups, tickets, ticket fields, and users", "operations": { "list_groups": { "httpMethod":"GET", "uri": "groups.json", "summary": "Get a list of groups" }, "search_groups":{ "httpMethod":"GET", "uri": "search.json?query=\"{query} type:group\"", "summary": "Uses a search query to get a list of groups", "parameters":{ "query":{ "location": "uri", "description":"Zendesk Search Query", "type": "string", "required": true } } }, "create_group": { "httpMethod":"POST", "uri": "groups.json", "summary": "Create a group", "parameters":{ "data": { "type": "array", "location": "body", "description":"Group JSON", "filters": "json_encode", "required": true }, "Content-Type":{ "type": "string", "location":"header", "static": "application/json" } } }, "delete_group": { "httpMethod":"DELETE", "uri": "groups/{id}.json", "summary": "Delete a group", "parameters":{ "id":{ "location": "uri", "description":"Group to delete by ID", "type": "integer", "required": true } } }, "get_group": { "httpMethod":"GET", "uri": "groups/{id}.json", "summary": "Get a ticket", "parameters":{ "id":{ "location": "uri", "description":"Group to get by ID", "type": "integer", "required": true } } }, "update_group": { "httpMethod":"PUT", "uri": "groups/{id}.json", "summary": "Update a group", "parameters":{ "id": { "location": "uri", "description":"Group to update by ID", "type": "integer", "required": true }, "data": { "type": "array", "location": "body", "description":"Group JSON", "filters": "json_encode", "required": true }, "Content-Type":{ "type": "string", "location":"header", "static": "application/json" } } } } ``` ### Guzzle\Service\Description\ServiceDescription Commands are now called Operations **Before** ```php use Guzzle\Service\Description\ServiceDescription; $sd = new ServiceDescription(); $sd->getCommands(); // @returns ApiCommandInterface[] $sd->hasCommand($name); $sd->getCommand($name); // @returns ApiCommandInterface|null $sd->addCommand($command); // @param ApiCommandInterface $command ``` **After** ```php use Guzzle\Service\Description\ServiceDescription; $sd = new ServiceDescription(); $sd->getOperations(); // @returns OperationInterface[] $sd->hasOperation($name); $sd->getOperation($name); // @returns OperationInterface|null $sd->addOperation($operation); // @param OperationInterface $operation ``` ### Guzzle\Common\Inflection\Inflector Namespace is now `Guzzle\Inflection\Inflector` ### Guzzle\Http\Plugin Namespace is now `Guzzle\Plugin`. Many other changes occur within this namespace and are detailed in their own sections below. ### Guzzle\Http\Plugin\LogPlugin and Guzzle\Common\Log Now `Guzzle\Plugin\Log\LogPlugin` and `Guzzle\Log` respectively. **Before** ```php use Guzzle\Common\Log\ClosureLogAdapter; use Guzzle\Http\Plugin\LogPlugin; /** @var \Guzzle\Http\Client */ $client; // $verbosity is an integer indicating desired message verbosity level $client->addSubscriber(new LogPlugin(new ClosureLogAdapter(function($m) { echo $m; }, $verbosity = LogPlugin::LOG_VERBOSE); ``` **After** ```php use Guzzle\Log\ClosureLogAdapter; use Guzzle\Log\MessageFormatter; use Guzzle\Plugin\Log\LogPlugin; /** @var \Guzzle\Http\Client */ $client; // $format is a string indicating desired message format -- @see MessageFormatter $client->addSubscriber(new LogPlugin(new ClosureLogAdapter(function($m) { echo $m; }, $format = MessageFormatter::DEBUG_FORMAT); ``` ### Guzzle\Http\Plugin\CurlAuthPlugin Now `Guzzle\Plugin\CurlAuth\CurlAuthPlugin`. ### Guzzle\Http\Plugin\ExponentialBackoffPlugin Now `Guzzle\Plugin\Backoff\BackoffPlugin`, and other changes. **Before** ```php use Guzzle\Http\Plugin\ExponentialBackoffPlugin; $backoffPlugin = new ExponentialBackoffPlugin($maxRetries, array_merge( ExponentialBackoffPlugin::getDefaultFailureCodes(), array(429) )); $client->addSubscriber($backoffPlugin); ``` **After** ```php use Guzzle\Plugin\Backoff\BackoffPlugin; use Guzzle\Plugin\Backoff\HttpBackoffStrategy; // Use convenient factory method instead -- see implementation for ideas of what // you can do with chaining backoff strategies $backoffPlugin = BackoffPlugin::getExponentialBackoff($maxRetries, array_merge( HttpBackoffStrategy::getDefaultFailureCodes(), array(429) )); $client->addSubscriber($backoffPlugin); ``` ### Known Issues #### [BUG] Accept-Encoding header behavior changed unintentionally. (See #217) (Fixed in 09daeb8c666fb44499a0646d655a8ae36456575e) In version 2.8 setting the `Accept-Encoding` header would set the CURLOPT_ENCODING option, which permitted cURL to properly handle gzip/deflate compressed responses from the server. In versions affected by this bug this does not happen. See issue #217 for a workaround, or use a version containing the fix. ================================================ FILE: lib/Google/vendor/guzzlehttp/guzzle/composer.json ================================================ { "name": "guzzlehttp/guzzle", "description": "Guzzle is a PHP HTTP client library", "keywords": [ "framework", "http", "rest", "web service", "curl", "client", "HTTP client", "PSR-7", "PSR-18" ], "license": "MIT", "authors": [ { "name": "Graham Campbell", "email": "hello@gjcampbell.co.uk", "homepage": "https://github.com/GrahamCampbell" }, { "name": "Michael Dowling", "email": "mtdowling@gmail.com", "homepage": "https://github.com/mtdowling" }, { "name": "Jeremy Lindblom", "email": "jeremeamia@gmail.com", "homepage": "https://github.com/jeremeamia" }, { "name": "George Mponos", "email": "gmponos@gmail.com", "homepage": "https://github.com/gmponos" }, { "name": "Tobias Nyholm", "email": "tobias.nyholm@gmail.com", "homepage": "https://github.com/Nyholm" }, { "name": "Márk Sági-Kazár", "email": "mark.sagikazar@gmail.com", "homepage": "https://github.com/sagikazarmark" }, { "name": "Tobias Schultze", "email": "webmaster@tubo-world.de", "homepage": "https://github.com/Tobion" } ], "repositories": [ { "type": "package", "package": { "name": "guzzle/client-integration-tests", "version": "v3.0.2", "dist": { "url": "https://codeload.github.com/guzzle/client-integration-tests/zip/2c025848417c1135031fdf9c728ee53d0a7ceaee", "type": "zip" }, "require": { "php": "^7.2.5 || ^8.0", "phpunit/phpunit": "^7.5.20 || ^8.5.8 || ^9.3.11", "php-http/message": "^1.0 || ^2.0", "guzzlehttp/psr7": "^1.7 || ^2.0", "th3n3rd/cartesian-product": "^0.3" }, "autoload": { "psr-4": { "Http\\Client\\Tests\\": "src/" } }, "bin": [ "bin/http_test_server" ] } } ], "require": { "php": "^7.2.5 || ^8.0", "ext-json": "*", "guzzlehttp/promises": "^2.3", "guzzlehttp/psr7": "^2.8", "psr/http-client": "^1.0", "symfony/deprecation-contracts": "^2.2 || ^3.0" }, "provide": { "psr/http-client-implementation": "1.0" }, "require-dev": { "ext-curl": "*", "bamarni/composer-bin-plugin": "^1.8.2", "guzzle/client-integration-tests": "3.0.2", "php-http/message-factory": "^1.1", "phpunit/phpunit": "^8.5.39 || ^9.6.20", "psr/log": "^1.1 || ^2.0 || ^3.0" }, "suggest": { "ext-curl": "Required for CURL handler support", "ext-intl": "Required for Internationalized Domain Name (IDN) support", "psr/log": "Required for using the Log middleware" }, "config": { "allow-plugins": { "bamarni/composer-bin-plugin": true }, "preferred-install": "dist", "sort-packages": true }, "extra": { "bamarni-bin": { "bin-links": true, "forward-command": false } }, "autoload": { "psr-4": { "GuzzleHttp\\": "src/" }, "files": [ "src/functions_include.php" ] }, "autoload-dev": { "psr-4": { "GuzzleHttp\\Tests\\": "tests/" } } } ================================================ FILE: lib/Google/vendor/guzzlehttp/guzzle/src/BodySummarizer.php ================================================ truncateAt = $truncateAt; } /** * Returns a summarized message body. */ public function summarize(MessageInterface $message): ?string { return $this->truncateAt === null ? Psr7\Message::bodySummary($message) : Psr7\Message::bodySummary($message, $this->truncateAt); } } ================================================ FILE: lib/Google/vendor/guzzlehttp/guzzle/src/BodySummarizerInterface.php ================================================ 'http://www.foo.com/1.0/', * 'timeout' => 0, * 'allow_redirects' => false, * 'proxy' => '192.168.16.1:10' * ]); * * Client configuration settings include the following options: * * - handler: (callable) Function that transfers HTTP requests over the * wire. The function is called with a Psr7\Http\Message\RequestInterface * and array of transfer options, and must return a * GuzzleHttp\Promise\PromiseInterface that is fulfilled with a * Psr7\Http\Message\ResponseInterface on success. * If no handler is provided, a default handler will be created * that enables all of the request options below by attaching all of the * default middleware to the handler. * - base_uri: (string|UriInterface) Base URI of the client that is merged * into relative URIs. Can be a string or instance of UriInterface. * - **: any request option * * @param array $config Client configuration settings. * * @see RequestOptions for a list of available request options. */ public function __construct(array $config = []) { if (!isset($config['handler'])) { $config['handler'] = HandlerStack::create(); } elseif (!\is_callable($config['handler'])) { throw new InvalidArgumentException('handler must be a callable'); } // Convert the base_uri to a UriInterface if (isset($config['base_uri'])) { $config['base_uri'] = Psr7\Utils::uriFor($config['base_uri']); } $this->configureDefaults($config); } /** * @param string $method * @param array $args * * @return PromiseInterface|ResponseInterface * * @deprecated Client::__call will be removed in guzzlehttp/guzzle:8.0. */ public function __call($method, $args) { if (\count($args) < 1) { throw new InvalidArgumentException('Magic request methods require a URI and optional options array'); } $uri = $args[0]; $opts = $args[1] ?? []; return \substr($method, -5) === 'Async' ? $this->requestAsync(\substr($method, 0, -5), $uri, $opts) : $this->request($method, $uri, $opts); } /** * Asynchronously send an HTTP request. * * @param array $options Request options to apply to the given * request and to the transfer. See \GuzzleHttp\RequestOptions. */ public function sendAsync(RequestInterface $request, array $options = []): PromiseInterface { // Merge the base URI into the request URI if needed. $options = $this->prepareDefaults($options); return $this->transfer( $request->withUri($this->buildUri($request->getUri(), $options), $request->hasHeader('Host')), $options ); } /** * Send an HTTP request. * * @param array $options Request options to apply to the given * request and to the transfer. See \GuzzleHttp\RequestOptions. * * @throws GuzzleException */ public function send(RequestInterface $request, array $options = []): ResponseInterface { $options[RequestOptions::SYNCHRONOUS] = true; return $this->sendAsync($request, $options)->wait(); } /** * The HttpClient PSR (PSR-18) specify this method. * * {@inheritDoc} */ public function sendRequest(RequestInterface $request): ResponseInterface { $options[RequestOptions::SYNCHRONOUS] = true; $options[RequestOptions::ALLOW_REDIRECTS] = false; $options[RequestOptions::HTTP_ERRORS] = false; return $this->sendAsync($request, $options)->wait(); } /** * Create and send an asynchronous HTTP request. * * Use an absolute path to override the base path of the client, or a * relative path to append to the base path of the client. The URL can * contain the query string as well. Use an array to provide a URL * template and additional variables to use in the URL template expansion. * * @param string $method HTTP method * @param string|UriInterface $uri URI object or string. * @param array $options Request options to apply. See \GuzzleHttp\RequestOptions. */ public function requestAsync(string $method, $uri = '', array $options = []): PromiseInterface { $options = $this->prepareDefaults($options); // Remove request modifying parameter because it can be done up-front. $headers = $options['headers'] ?? []; $body = $options['body'] ?? null; $version = $options['version'] ?? '1.1'; // Merge the URI into the base URI. $uri = $this->buildUri(Psr7\Utils::uriFor($uri), $options); if (\is_array($body)) { throw $this->invalidBody(); } $request = new Psr7\Request($method, $uri, $headers, $body, $version); // Remove the option so that they are not doubly-applied. unset($options['headers'], $options['body'], $options['version']); return $this->transfer($request, $options); } /** * Create and send an HTTP request. * * Use an absolute path to override the base path of the client, or a * relative path to append to the base path of the client. The URL can * contain the query string as well. * * @param string $method HTTP method. * @param string|UriInterface $uri URI object or string. * @param array $options Request options to apply. See \GuzzleHttp\RequestOptions. * * @throws GuzzleException */ public function request(string $method, $uri = '', array $options = []): ResponseInterface { $options[RequestOptions::SYNCHRONOUS] = true; return $this->requestAsync($method, $uri, $options)->wait(); } /** * Get a client configuration option. * * These options include default request options of the client, a "handler" * (if utilized by the concrete client), and a "base_uri" if utilized by * the concrete client. * * @param string|null $option The config option to retrieve. * * @return mixed * * @deprecated Client::getConfig will be removed in guzzlehttp/guzzle:8.0. */ public function getConfig(?string $option = null) { return $option === null ? $this->config : ($this->config[$option] ?? null); } private function buildUri(UriInterface $uri, array $config): UriInterface { if (isset($config['base_uri'])) { $uri = Psr7\UriResolver::resolve(Psr7\Utils::uriFor($config['base_uri']), $uri); } if (isset($config['idn_conversion']) && ($config['idn_conversion'] !== false)) { $idnOptions = ($config['idn_conversion'] === true) ? \IDNA_DEFAULT : $config['idn_conversion']; $uri = Utils::idnUriConvert($uri, $idnOptions); } return $uri->getScheme() === '' && $uri->getHost() !== '' ? $uri->withScheme('http') : $uri; } /** * Configures the default options for a client. */ private function configureDefaults(array $config): void { $defaults = [ 'allow_redirects' => RedirectMiddleware::$defaultSettings, 'http_errors' => true, 'decode_content' => true, 'verify' => true, 'cookies' => false, 'idn_conversion' => false, ]; // Use the standard Linux HTTP_PROXY and HTTPS_PROXY if set. // We can only trust the HTTP_PROXY environment variable in a CLI // process due to the fact that PHP has no reliable mechanism to // get environment variables that start with "HTTP_". if (\PHP_SAPI === 'cli' && ($proxy = Utils::getenv('HTTP_PROXY'))) { $defaults['proxy']['http'] = $proxy; } if ($proxy = Utils::getenv('HTTPS_PROXY')) { $defaults['proxy']['https'] = $proxy; } if ($noProxy = Utils::getenv('NO_PROXY')) { $cleanedNoProxy = \str_replace(' ', '', $noProxy); $defaults['proxy']['no'] = \explode(',', $cleanedNoProxy); } $this->config = $config + $defaults; if (!empty($config['cookies']) && $config['cookies'] === true) { $this->config['cookies'] = new CookieJar(); } // Add the default user-agent header. if (!isset($this->config['headers'])) { $this->config['headers'] = ['User-Agent' => Utils::defaultUserAgent()]; } else { // Add the User-Agent header if one was not already set. foreach (\array_keys($this->config['headers']) as $name) { if (\strtolower($name) === 'user-agent') { return; } } $this->config['headers']['User-Agent'] = Utils::defaultUserAgent(); } } /** * Merges default options into the array. * * @param array $options Options to modify by reference */ private function prepareDefaults(array $options): array { $defaults = $this->config; if (!empty($defaults['headers'])) { // Default headers are only added if they are not present. $defaults['_conditional'] = $defaults['headers']; unset($defaults['headers']); } // Special handling for headers is required as they are added as // conditional headers and as headers passed to a request ctor. if (\array_key_exists('headers', $options)) { // Allows default headers to be unset. if ($options['headers'] === null) { $defaults['_conditional'] = []; unset($options['headers']); } elseif (!\is_array($options['headers'])) { throw new InvalidArgumentException('headers must be an array'); } } // Shallow merge defaults underneath options. $result = $options + $defaults; // Remove null values. foreach ($result as $k => $v) { if ($v === null) { unset($result[$k]); } } return $result; } /** * Transfers the given request and applies request options. * * The URI of the request is not modified and the request options are used * as-is without merging in default options. * * @param array $options See \GuzzleHttp\RequestOptions. */ private function transfer(RequestInterface $request, array $options): PromiseInterface { $request = $this->applyOptions($request, $options); /** @var HandlerStack $handler */ $handler = $options['handler']; try { return P\Create::promiseFor($handler($request, $options)); } catch (\Exception $e) { return P\Create::rejectionFor($e); } } /** * Applies the array of request options to a request. */ private function applyOptions(RequestInterface $request, array &$options): RequestInterface { $modify = [ 'set_headers' => [], ]; if (isset($options['headers'])) { if (array_keys($options['headers']) === range(0, count($options['headers']) - 1)) { throw new InvalidArgumentException('The headers array must have header name as keys.'); } $modify['set_headers'] = $options['headers']; unset($options['headers']); } if (isset($options['form_params'])) { if (isset($options['multipart'])) { throw new InvalidArgumentException('You cannot use ' .'form_params and multipart at the same time. Use the ' .'form_params option if you want to send application/' .'x-www-form-urlencoded requests, and the multipart ' .'option to send multipart/form-data requests.'); } $options['body'] = \http_build_query($options['form_params'], '', '&'); unset($options['form_params']); // Ensure that we don't have the header in different case and set the new value. $options['_conditional'] = Psr7\Utils::caselessRemove(['Content-Type'], $options['_conditional']); $options['_conditional']['Content-Type'] = 'application/x-www-form-urlencoded'; } if (isset($options['multipart'])) { $options['body'] = new Psr7\MultipartStream($options['multipart']); unset($options['multipart']); } if (isset($options['json'])) { $options['body'] = Utils::jsonEncode($options['json']); unset($options['json']); // Ensure that we don't have the header in different case and set the new value. $options['_conditional'] = Psr7\Utils::caselessRemove(['Content-Type'], $options['_conditional']); $options['_conditional']['Content-Type'] = 'application/json'; } if (!empty($options['decode_content']) && $options['decode_content'] !== true ) { // Ensure that we don't have the header in different case and set the new value. $options['_conditional'] = Psr7\Utils::caselessRemove(['Accept-Encoding'], $options['_conditional']); $modify['set_headers']['Accept-Encoding'] = $options['decode_content']; } if (isset($options['body'])) { if (\is_array($options['body'])) { throw $this->invalidBody(); } $modify['body'] = Psr7\Utils::streamFor($options['body']); unset($options['body']); } if (!empty($options['auth']) && \is_array($options['auth'])) { $value = $options['auth']; $type = isset($value[2]) ? \strtolower($value[2]) : 'basic'; switch ($type) { case 'basic': // Ensure that we don't have the header in different case and set the new value. $modify['set_headers'] = Psr7\Utils::caselessRemove(['Authorization'], $modify['set_headers']); $modify['set_headers']['Authorization'] = 'Basic ' .\base64_encode("$value[0]:$value[1]"); break; case 'digest': // @todo: Do not rely on curl $options['curl'][\CURLOPT_HTTPAUTH] = \CURLAUTH_DIGEST; $options['curl'][\CURLOPT_USERPWD] = "$value[0]:$value[1]"; break; case 'ntlm': $options['curl'][\CURLOPT_HTTPAUTH] = \CURLAUTH_NTLM; $options['curl'][\CURLOPT_USERPWD] = "$value[0]:$value[1]"; break; } } if (isset($options['query'])) { $value = $options['query']; if (\is_array($value)) { $value = \http_build_query($value, '', '&', \PHP_QUERY_RFC3986); } if (!\is_string($value)) { throw new InvalidArgumentException('query must be a string or array'); } $modify['query'] = $value; unset($options['query']); } // Ensure that sink is not an invalid value. if (isset($options['sink'])) { // TODO: Add more sink validation? if (\is_bool($options['sink'])) { throw new InvalidArgumentException('sink must not be a boolean'); } } if (isset($options['version'])) { $modify['version'] = $options['version']; } $request = Psr7\Utils::modifyRequest($request, $modify); if ($request->getBody() instanceof Psr7\MultipartStream) { // Use a multipart/form-data POST if a Content-Type is not set. // Ensure that we don't have the header in different case and set the new value. $options['_conditional'] = Psr7\Utils::caselessRemove(['Content-Type'], $options['_conditional']); $options['_conditional']['Content-Type'] = 'multipart/form-data; boundary=' .$request->getBody()->getBoundary(); } // Merge in conditional headers if they are not present. if (isset($options['_conditional'])) { // Build up the changes so it's in a single clone of the message. $modify = []; foreach ($options['_conditional'] as $k => $v) { if (!$request->hasHeader($k)) { $modify['set_headers'][$k] = $v; } } $request = Psr7\Utils::modifyRequest($request, $modify); // Don't pass this internal value along to middleware/handlers. unset($options['_conditional']); } return $request; } /** * Return an InvalidArgumentException with pre-set message. */ private function invalidBody(): InvalidArgumentException { return new InvalidArgumentException('Passing in the "body" request ' .'option as an array to send a request is not supported. ' .'Please use the "form_params" request option to send a ' .'application/x-www-form-urlencoded request, or the "multipart" ' .'request option to send a multipart/form-data request.'); } } ================================================ FILE: lib/Google/vendor/guzzlehttp/guzzle/src/ClientInterface.php ================================================ request('GET', $uri, $options); } /** * Create and send an HTTP HEAD request. * * Use an absolute path to override the base path of the client, or a * relative path to append to the base path of the client. The URL can * contain the query string as well. * * @param string|UriInterface $uri URI object or string. * @param array $options Request options to apply. * * @throws GuzzleException */ public function head($uri, array $options = []): ResponseInterface { return $this->request('HEAD', $uri, $options); } /** * Create and send an HTTP PUT request. * * Use an absolute path to override the base path of the client, or a * relative path to append to the base path of the client. The URL can * contain the query string as well. * * @param string|UriInterface $uri URI object or string. * @param array $options Request options to apply. * * @throws GuzzleException */ public function put($uri, array $options = []): ResponseInterface { return $this->request('PUT', $uri, $options); } /** * Create and send an HTTP POST request. * * Use an absolute path to override the base path of the client, or a * relative path to append to the base path of the client. The URL can * contain the query string as well. * * @param string|UriInterface $uri URI object or string. * @param array $options Request options to apply. * * @throws GuzzleException */ public function post($uri, array $options = []): ResponseInterface { return $this->request('POST', $uri, $options); } /** * Create and send an HTTP PATCH request. * * Use an absolute path to override the base path of the client, or a * relative path to append to the base path of the client. The URL can * contain the query string as well. * * @param string|UriInterface $uri URI object or string. * @param array $options Request options to apply. * * @throws GuzzleException */ public function patch($uri, array $options = []): ResponseInterface { return $this->request('PATCH', $uri, $options); } /** * Create and send an HTTP DELETE request. * * Use an absolute path to override the base path of the client, or a * relative path to append to the base path of the client. The URL can * contain the query string as well. * * @param string|UriInterface $uri URI object or string. * @param array $options Request options to apply. * * @throws GuzzleException */ public function delete($uri, array $options = []): ResponseInterface { return $this->request('DELETE', $uri, $options); } /** * Create and send an asynchronous HTTP request. * * Use an absolute path to override the base path of the client, or a * relative path to append to the base path of the client. The URL can * contain the query string as well. Use an array to provide a URL * template and additional variables to use in the URL template expansion. * * @param string $method HTTP method * @param string|UriInterface $uri URI object or string. * @param array $options Request options to apply. */ abstract public function requestAsync(string $method, $uri, array $options = []): PromiseInterface; /** * Create and send an asynchronous HTTP GET request. * * Use an absolute path to override the base path of the client, or a * relative path to append to the base path of the client. The URL can * contain the query string as well. Use an array to provide a URL * template and additional variables to use in the URL template expansion. * * @param string|UriInterface $uri URI object or string. * @param array $options Request options to apply. */ public function getAsync($uri, array $options = []): PromiseInterface { return $this->requestAsync('GET', $uri, $options); } /** * Create and send an asynchronous HTTP HEAD request. * * Use an absolute path to override the base path of the client, or a * relative path to append to the base path of the client. The URL can * contain the query string as well. Use an array to provide a URL * template and additional variables to use in the URL template expansion. * * @param string|UriInterface $uri URI object or string. * @param array $options Request options to apply. */ public function headAsync($uri, array $options = []): PromiseInterface { return $this->requestAsync('HEAD', $uri, $options); } /** * Create and send an asynchronous HTTP PUT request. * * Use an absolute path to override the base path of the client, or a * relative path to append to the base path of the client. The URL can * contain the query string as well. Use an array to provide a URL * template and additional variables to use in the URL template expansion. * * @param string|UriInterface $uri URI object or string. * @param array $options Request options to apply. */ public function putAsync($uri, array $options = []): PromiseInterface { return $this->requestAsync('PUT', $uri, $options); } /** * Create and send an asynchronous HTTP POST request. * * Use an absolute path to override the base path of the client, or a * relative path to append to the base path of the client. The URL can * contain the query string as well. Use an array to provide a URL * template and additional variables to use in the URL template expansion. * * @param string|UriInterface $uri URI object or string. * @param array $options Request options to apply. */ public function postAsync($uri, array $options = []): PromiseInterface { return $this->requestAsync('POST', $uri, $options); } /** * Create and send an asynchronous HTTP PATCH request. * * Use an absolute path to override the base path of the client, or a * relative path to append to the base path of the client. The URL can * contain the query string as well. Use an array to provide a URL * template and additional variables to use in the URL template expansion. * * @param string|UriInterface $uri URI object or string. * @param array $options Request options to apply. */ public function patchAsync($uri, array $options = []): PromiseInterface { return $this->requestAsync('PATCH', $uri, $options); } /** * Create and send an asynchronous HTTP DELETE request. * * Use an absolute path to override the base path of the client, or a * relative path to append to the base path of the client. The URL can * contain the query string as well. Use an array to provide a URL * template and additional variables to use in the URL template expansion. * * @param string|UriInterface $uri URI object or string. * @param array $options Request options to apply. */ public function deleteAsync($uri, array $options = []): PromiseInterface { return $this->requestAsync('DELETE', $uri, $options); } } ================================================ FILE: lib/Google/vendor/guzzlehttp/guzzle/src/Cookie/CookieJar.php ================================================ strictMode = $strictMode; foreach ($cookieArray as $cookie) { if (!($cookie instanceof SetCookie)) { $cookie = new SetCookie($cookie); } $this->setCookie($cookie); } } /** * Create a new Cookie jar from an associative array and domain. * * @param array $cookies Cookies to create the jar from * @param string $domain Domain to set the cookies to */ public static function fromArray(array $cookies, string $domain): self { $cookieJar = new self(); foreach ($cookies as $name => $value) { $cookieJar->setCookie(new SetCookie([ 'Domain' => $domain, 'Name' => $name, 'Value' => $value, 'Discard' => true, ])); } return $cookieJar; } /** * Evaluate if this cookie should be persisted to storage * that survives between requests. * * @param SetCookie $cookie Being evaluated. * @param bool $allowSessionCookies If we should persist session cookies */ public static function shouldPersist(SetCookie $cookie, bool $allowSessionCookies = false): bool { if ($cookie->getExpires() || $allowSessionCookies) { if (!$cookie->getDiscard()) { return true; } } return false; } /** * Finds and returns the cookie based on the name * * @param string $name cookie name to search for * * @return SetCookie|null cookie that was found or null if not found */ public function getCookieByName(string $name): ?SetCookie { foreach ($this->cookies as $cookie) { if ($cookie->getName() !== null && \strcasecmp($cookie->getName(), $name) === 0) { return $cookie; } } return null; } public function toArray(): array { return \array_map(static function (SetCookie $cookie): array { return $cookie->toArray(); }, $this->getIterator()->getArrayCopy()); } public function clear(?string $domain = null, ?string $path = null, ?string $name = null): void { if (!$domain) { $this->cookies = []; return; } elseif (!$path) { $this->cookies = \array_filter( $this->cookies, static function (SetCookie $cookie) use ($domain): bool { return !$cookie->matchesDomain($domain); } ); } elseif (!$name) { $this->cookies = \array_filter( $this->cookies, static function (SetCookie $cookie) use ($path, $domain): bool { return !($cookie->matchesPath($path) && $cookie->matchesDomain($domain)); } ); } else { $this->cookies = \array_filter( $this->cookies, static function (SetCookie $cookie) use ($path, $domain, $name) { return !($cookie->getName() == $name && $cookie->matchesPath($path) && $cookie->matchesDomain($domain)); } ); } } public function clearSessionCookies(): void { $this->cookies = \array_filter( $this->cookies, static function (SetCookie $cookie): bool { return !$cookie->getDiscard() && $cookie->getExpires(); } ); } public function setCookie(SetCookie $cookie): bool { // If the name string is empty (but not 0), ignore the set-cookie // string entirely. $name = $cookie->getName(); if (!$name && $name !== '0') { return false; } // Only allow cookies with set and valid domain, name, value $result = $cookie->validate(); if ($result !== true) { if ($this->strictMode) { throw new \RuntimeException('Invalid cookie: '.$result); } $this->removeCookieIfEmpty($cookie); return false; } // Resolve conflicts with previously set cookies foreach ($this->cookies as $i => $c) { // Two cookies are identical, when their path, and domain are // identical. if ($c->getPath() != $cookie->getPath() || $c->getDomain() != $cookie->getDomain() || $c->getName() != $cookie->getName() ) { continue; } // The previously set cookie is a discard cookie and this one is // not so allow the new cookie to be set if (!$cookie->getDiscard() && $c->getDiscard()) { unset($this->cookies[$i]); continue; } // If the new cookie's expiration is further into the future, then // replace the old cookie if ($cookie->getExpires() > $c->getExpires()) { unset($this->cookies[$i]); continue; } // If the value has changed, we better change it if ($cookie->getValue() !== $c->getValue()) { unset($this->cookies[$i]); continue; } // The cookie exists, so no need to continue return false; } $this->cookies[] = $cookie; return true; } public function count(): int { return \count($this->cookies); } /** * @return \ArrayIterator */ public function getIterator(): \ArrayIterator { return new \ArrayIterator(\array_values($this->cookies)); } public function extractCookies(RequestInterface $request, ResponseInterface $response): void { if ($cookieHeader = $response->getHeader('Set-Cookie')) { foreach ($cookieHeader as $cookie) { $sc = SetCookie::fromString($cookie); if (!$sc->getDomain()) { $sc->setDomain($request->getUri()->getHost()); } if (0 !== \strpos($sc->getPath(), '/')) { $sc->setPath($this->getCookiePathFromRequest($request)); } if (!$sc->matchesDomain($request->getUri()->getHost())) { continue; } // Note: At this point `$sc->getDomain()` being a public suffix should // be rejected, but we don't want to pull in the full PSL dependency. $this->setCookie($sc); } } } /** * Computes cookie path following RFC 6265 section 5.1.4 * * @see https://datatracker.ietf.org/doc/html/rfc6265#section-5.1.4 */ private function getCookiePathFromRequest(RequestInterface $request): string { $uriPath = $request->getUri()->getPath(); if ('' === $uriPath) { return '/'; } if (0 !== \strpos($uriPath, '/')) { return '/'; } if ('/' === $uriPath) { return '/'; } $lastSlashPos = \strrpos($uriPath, '/'); if (0 === $lastSlashPos || false === $lastSlashPos) { return '/'; } return \substr($uriPath, 0, $lastSlashPos); } public function withCookieHeader(RequestInterface $request): RequestInterface { $values = []; $uri = $request->getUri(); $scheme = $uri->getScheme(); $host = $uri->getHost(); $path = $uri->getPath() ?: '/'; foreach ($this->cookies as $cookie) { if ($cookie->matchesPath($path) && $cookie->matchesDomain($host) && !$cookie->isExpired() && (!$cookie->getSecure() || $scheme === 'https') ) { $values[] = $cookie->getName().'=' .$cookie->getValue(); } } return $values ? $request->withHeader('Cookie', \implode('; ', $values)) : $request; } /** * If a cookie already exists and the server asks to set it again with a * null value, the cookie must be deleted. */ private function removeCookieIfEmpty(SetCookie $cookie): void { $cookieValue = $cookie->getValue(); if ($cookieValue === null || $cookieValue === '') { $this->clear( $cookie->getDomain(), $cookie->getPath(), $cookie->getName() ); } } } ================================================ FILE: lib/Google/vendor/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php ================================================ */ interface CookieJarInterface extends \Countable, \IteratorAggregate { /** * Create a request with added cookie headers. * * If no matching cookies are found in the cookie jar, then no Cookie * header is added to the request and the same request is returned. * * @param RequestInterface $request Request object to modify. * * @return RequestInterface returns the modified request. */ public function withCookieHeader(RequestInterface $request): RequestInterface; /** * Extract cookies from an HTTP response and store them in the CookieJar. * * @param RequestInterface $request Request that was sent * @param ResponseInterface $response Response that was received */ public function extractCookies(RequestInterface $request, ResponseInterface $response): void; /** * Sets a cookie in the cookie jar. * * @param SetCookie $cookie Cookie to set. * * @return bool Returns true on success or false on failure */ public function setCookie(SetCookie $cookie): bool; /** * Remove cookies currently held in the cookie jar. * * Invoking this method without arguments will empty the whole cookie jar. * If given a $domain argument only cookies belonging to that domain will * be removed. If given a $domain and $path argument, cookies belonging to * the specified path within that domain are removed. If given all three * arguments, then the cookie with the specified name, path and domain is * removed. * * @param string|null $domain Clears cookies matching a domain * @param string|null $path Clears cookies matching a domain and path * @param string|null $name Clears cookies matching a domain, path, and name */ public function clear(?string $domain = null, ?string $path = null, ?string $name = null): void; /** * Discard all sessions cookies. * * Removes cookies that don't have an expire field or a have a discard * field set to true. To be called when the user agent shuts down according * to RFC 2965. */ public function clearSessionCookies(): void; /** * Converts the cookie jar to an array. */ public function toArray(): array; } ================================================ FILE: lib/Google/vendor/guzzlehttp/guzzle/src/Cookie/FileCookieJar.php ================================================ filename = $cookieFile; $this->storeSessionCookies = $storeSessionCookies; if (\file_exists($cookieFile)) { $this->load($cookieFile); } } /** * Saves the file when shutting down */ public function __destruct() { $this->save($this->filename); } /** * Saves the cookies to a file. * * @param string $filename File to save * * @throws \RuntimeException if the file cannot be found or created */ public function save(string $filename): void { $json = []; /** @var SetCookie $cookie */ foreach ($this as $cookie) { if (CookieJar::shouldPersist($cookie, $this->storeSessionCookies)) { $json[] = $cookie->toArray(); } } $jsonStr = Utils::jsonEncode($json); if (false === \file_put_contents($filename, $jsonStr, \LOCK_EX)) { throw new \RuntimeException("Unable to save file {$filename}"); } } /** * Load cookies from a JSON formatted file. * * Old cookies are kept unless overwritten by newly loaded ones. * * @param string $filename Cookie file to load. * * @throws \RuntimeException if the file cannot be loaded. */ public function load(string $filename): void { $json = \file_get_contents($filename); if (false === $json) { throw new \RuntimeException("Unable to load file {$filename}"); } if ($json === '') { return; } $data = Utils::jsonDecode($json, true); if (\is_array($data)) { foreach ($data as $cookie) { $this->setCookie(new SetCookie($cookie)); } } elseif (\is_scalar($data) && !empty($data)) { throw new \RuntimeException("Invalid cookie file: {$filename}"); } } } ================================================ FILE: lib/Google/vendor/guzzlehttp/guzzle/src/Cookie/SessionCookieJar.php ================================================ sessionKey = $sessionKey; $this->storeSessionCookies = $storeSessionCookies; $this->load(); } /** * Saves cookies to session when shutting down */ public function __destruct() { $this->save(); } /** * Save cookies to the client session */ public function save(): void { $json = []; /** @var SetCookie $cookie */ foreach ($this as $cookie) { if (CookieJar::shouldPersist($cookie, $this->storeSessionCookies)) { $json[] = $cookie->toArray(); } } $_SESSION[$this->sessionKey] = \json_encode($json); } /** * Load the contents of the client session into the data array */ protected function load(): void { if (!isset($_SESSION[$this->sessionKey])) { return; } $data = \json_decode($_SESSION[$this->sessionKey], true); if (\is_array($data)) { foreach ($data as $cookie) { $this->setCookie(new SetCookie($cookie)); } } elseif (\strlen($data)) { throw new \RuntimeException('Invalid cookie data'); } } } ================================================ FILE: lib/Google/vendor/guzzlehttp/guzzle/src/Cookie/SetCookie.php ================================================ null, 'Value' => null, 'Domain' => null, 'Path' => '/', 'Max-Age' => null, 'Expires' => null, 'Secure' => false, 'Discard' => false, 'HttpOnly' => false, ]; /** * @var array Cookie data */ private $data; /** * Create a new SetCookie object from a string. * * @param string $cookie Set-Cookie header string */ public static function fromString(string $cookie): self { // Create the default return array $data = self::$defaults; // Explode the cookie string using a series of semicolons $pieces = \array_filter(\array_map('trim', \explode(';', $cookie))); // The name of the cookie (first kvp) must exist and include an equal sign. if (!isset($pieces[0]) || \strpos($pieces[0], '=') === false) { return new self($data); } // Add the cookie pieces into the parsed data array foreach ($pieces as $part) { $cookieParts = \explode('=', $part, 2); $key = \trim($cookieParts[0]); $value = isset($cookieParts[1]) ? \trim($cookieParts[1], " \n\r\t\0\x0B") : true; // Only check for non-cookies when cookies have been found if (!isset($data['Name'])) { $data['Name'] = $key; $data['Value'] = $value; } else { foreach (\array_keys(self::$defaults) as $search) { if (!\strcasecmp($search, $key)) { if ($search === 'Max-Age') { if (is_numeric($value)) { $data[$search] = (int) $value; } } elseif ($search === 'Secure' || $search === 'Discard' || $search === 'HttpOnly') { if ($value) { $data[$search] = true; } } else { $data[$search] = $value; } continue 2; } } $data[$key] = $value; } } return new self($data); } /** * @param array $data Array of cookie data provided by a Cookie parser */ public function __construct(array $data = []) { $this->data = self::$defaults; if (isset($data['Name'])) { $this->setName($data['Name']); } if (isset($data['Value'])) { $this->setValue($data['Value']); } if (isset($data['Domain'])) { $this->setDomain($data['Domain']); } if (isset($data['Path'])) { $this->setPath($data['Path']); } if (isset($data['Max-Age'])) { $this->setMaxAge($data['Max-Age']); } if (isset($data['Expires'])) { $this->setExpires($data['Expires']); } if (isset($data['Secure'])) { $this->setSecure($data['Secure']); } if (isset($data['Discard'])) { $this->setDiscard($data['Discard']); } if (isset($data['HttpOnly'])) { $this->setHttpOnly($data['HttpOnly']); } // Set the remaining values that don't have extra validation logic foreach (array_diff(array_keys($data), array_keys(self::$defaults)) as $key) { $this->data[$key] = $data[$key]; } // Extract the Expires value and turn it into a UNIX timestamp if needed if (!$this->getExpires() && $this->getMaxAge()) { // Calculate the Expires date $this->setExpires(\time() + $this->getMaxAge()); } elseif (null !== ($expires = $this->getExpires()) && !\is_numeric($expires)) { $this->setExpires($expires); } } public function __toString() { $str = $this->data['Name'].'='.($this->data['Value'] ?? '').'; '; foreach ($this->data as $k => $v) { if ($k !== 'Name' && $k !== 'Value' && $v !== null && $v !== false) { if ($k === 'Expires') { $str .= 'Expires='.\gmdate('D, d M Y H:i:s \G\M\T', $v).'; '; } else { $str .= ($v === true ? $k : "{$k}={$v}").'; '; } } } return \rtrim($str, '; '); } public function toArray(): array { return $this->data; } /** * Get the cookie name. * * @return string */ public function getName() { return $this->data['Name']; } /** * Set the cookie name. * * @param string $name Cookie name */ public function setName($name): void { if (!is_string($name)) { trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a string to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__); } $this->data['Name'] = (string) $name; } /** * Get the cookie value. * * @return string|null */ public function getValue() { return $this->data['Value']; } /** * Set the cookie value. * * @param string $value Cookie value */ public function setValue($value): void { if (!is_string($value)) { trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a string to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__); } $this->data['Value'] = (string) $value; } /** * Get the domain. * * @return string|null */ public function getDomain() { return $this->data['Domain']; } /** * Set the domain of the cookie. * * @param string|null $domain */ public function setDomain($domain): void { if (!is_string($domain) && null !== $domain) { trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a string or null to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__); } $this->data['Domain'] = null === $domain ? null : (string) $domain; } /** * Get the path. * * @return string */ public function getPath() { return $this->data['Path']; } /** * Set the path of the cookie. * * @param string $path Path of the cookie */ public function setPath($path): void { if (!is_string($path)) { trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a string to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__); } $this->data['Path'] = (string) $path; } /** * Maximum lifetime of the cookie in seconds. * * @return int|null */ public function getMaxAge() { return null === $this->data['Max-Age'] ? null : (int) $this->data['Max-Age']; } /** * Set the max-age of the cookie. * * @param int|null $maxAge Max age of the cookie in seconds */ public function setMaxAge($maxAge): void { if (!is_int($maxAge) && null !== $maxAge) { trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing an int or null to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__); } $this->data['Max-Age'] = $maxAge === null ? null : (int) $maxAge; } /** * The UNIX timestamp when the cookie Expires. * * @return string|int|null */ public function getExpires() { return $this->data['Expires']; } /** * Set the unix timestamp for which the cookie will expire. * * @param int|string|null $timestamp Unix timestamp or any English textual datetime description. */ public function setExpires($timestamp): void { if (!is_int($timestamp) && !is_string($timestamp) && null !== $timestamp) { trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing an int, string or null to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__); } $this->data['Expires'] = null === $timestamp ? null : (\is_numeric($timestamp) ? (int) $timestamp : \strtotime((string) $timestamp)); } /** * Get whether or not this is a secure cookie. * * @return bool */ public function getSecure() { return $this->data['Secure']; } /** * Set whether or not the cookie is secure. * * @param bool $secure Set to true or false if secure */ public function setSecure($secure): void { if (!is_bool($secure)) { trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a bool to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__); } $this->data['Secure'] = (bool) $secure; } /** * Get whether or not this is a session cookie. * * @return bool|null */ public function getDiscard() { return $this->data['Discard']; } /** * Set whether or not this is a session cookie. * * @param bool $discard Set to true or false if this is a session cookie */ public function setDiscard($discard): void { if (!is_bool($discard)) { trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a bool to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__); } $this->data['Discard'] = (bool) $discard; } /** * Get whether or not this is an HTTP only cookie. * * @return bool */ public function getHttpOnly() { return $this->data['HttpOnly']; } /** * Set whether or not this is an HTTP only cookie. * * @param bool $httpOnly Set to true or false if this is HTTP only */ public function setHttpOnly($httpOnly): void { if (!is_bool($httpOnly)) { trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a bool to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__); } $this->data['HttpOnly'] = (bool) $httpOnly; } /** * Check if the cookie matches a path value. * * A request-path path-matches a given cookie-path if at least one of * the following conditions holds: * * - The cookie-path and the request-path are identical. * - The cookie-path is a prefix of the request-path, and the last * character of the cookie-path is %x2F ("/"). * - The cookie-path is a prefix of the request-path, and the first * character of the request-path that is not included in the cookie- * path is a %x2F ("/") character. * * @param string $requestPath Path to check against */ public function matchesPath(string $requestPath): bool { $cookiePath = $this->getPath(); // Match on exact matches or when path is the default empty "/" if ($cookiePath === '/' || $cookiePath == $requestPath) { return true; } // Ensure that the cookie-path is a prefix of the request path. if (0 !== \strpos($requestPath, $cookiePath)) { return false; } // Match if the last character of the cookie-path is "/" if (\substr($cookiePath, -1, 1) === '/') { return true; } // Match if the first character not included in cookie path is "/" return \substr($requestPath, \strlen($cookiePath), 1) === '/'; } /** * Check if the cookie matches a domain value. * * @param string $domain Domain to check against */ public function matchesDomain(string $domain): bool { $cookieDomain = $this->getDomain(); if (null === $cookieDomain) { return true; } // Remove the leading '.' as per spec in RFC 6265. // https://datatracker.ietf.org/doc/html/rfc6265#section-5.2.3 $cookieDomain = \ltrim(\strtolower($cookieDomain), '.'); $domain = \strtolower($domain); // Domain not set or exact match. if ('' === $cookieDomain || $domain === $cookieDomain) { return true; } // Matching the subdomain according to RFC 6265. // https://datatracker.ietf.org/doc/html/rfc6265#section-5.1.3 if (\filter_var($domain, \FILTER_VALIDATE_IP)) { return false; } return (bool) \preg_match('/\.'.\preg_quote($cookieDomain, '/').'$/', $domain); } /** * Check if the cookie is expired. */ public function isExpired(): bool { return $this->getExpires() !== null && \time() > $this->getExpires(); } /** * Check if the cookie is valid according to RFC 6265. * * @return bool|string Returns true if valid or an error message if invalid */ public function validate() { $name = $this->getName(); if ($name === '') { return 'The cookie name must not be empty'; } // Check if any of the invalid characters are present in the cookie name if (\preg_match( '/[\x00-\x20\x22\x28-\x29\x2c\x2f\x3a-\x40\x5c\x7b\x7d\x7f]/', $name )) { return 'Cookie name must not contain invalid characters: ASCII ' .'Control characters (0-31;127), space, tab and the ' .'following characters: ()<>@,;:\"/?={}'; } // Value must not be null. 0 and empty string are valid. Empty strings // are technically against RFC 6265, but known to happen in the wild. $value = $this->getValue(); if ($value === null) { return 'The cookie value must not be empty'; } // Domains must not be empty, but can be 0. "0" is not a valid internet // domain, but may be used as server name in a private network. $domain = $this->getDomain(); if ($domain === null || $domain === '') { return 'The cookie domain must not be empty'; } return true; } } ================================================ FILE: lib/Google/vendor/guzzlehttp/guzzle/src/Exception/BadResponseException.php ================================================ request = $request; $this->handlerContext = $handlerContext; } /** * Get the request that caused the exception */ public function getRequest(): RequestInterface { return $this->request; } /** * Get contextual information about the error from the underlying handler. * * The contents of this array will vary depending on which handler you are * using. It may also be just an empty array. Relying on this data will * couple you to a specific handler, but can give more debug information * when needed. */ public function getHandlerContext(): array { return $this->handlerContext; } } ================================================ FILE: lib/Google/vendor/guzzlehttp/guzzle/src/Exception/GuzzleException.php ================================================ getStatusCode() : 0; parent::__construct($message, $code, $previous); $this->request = $request; $this->response = $response; $this->handlerContext = $handlerContext; } /** * Wrap non-RequestExceptions with a RequestException */ public static function wrapException(RequestInterface $request, \Throwable $e): RequestException { return $e instanceof RequestException ? $e : new RequestException($e->getMessage(), $request, null, $e); } /** * Factory method to create a new exception with a normalized error message * * @param RequestInterface $request Request sent * @param ResponseInterface $response Response received * @param \Throwable|null $previous Previous exception * @param array $handlerContext Optional handler context * @param BodySummarizerInterface|null $bodySummarizer Optional body summarizer */ public static function create( RequestInterface $request, ?ResponseInterface $response = null, ?\Throwable $previous = null, array $handlerContext = [], ?BodySummarizerInterface $bodySummarizer = null ): self { if (!$response) { return new self( 'Error completing request', $request, null, $previous, $handlerContext ); } $level = (int) \floor($response->getStatusCode() / 100); if ($level === 4) { $label = 'Client error'; $className = ClientException::class; } elseif ($level === 5) { $label = 'Server error'; $className = ServerException::class; } else { $label = 'Unsuccessful request'; $className = __CLASS__; } $uri = \GuzzleHttp\Psr7\Utils::redactUserInfo($request->getUri()); // Client Error: `GET /` resulted in a `404 Not Found` response: // ... (truncated) $message = \sprintf( '%s: `%s %s` resulted in a `%s %s` response', $label, $request->getMethod(), $uri->__toString(), $response->getStatusCode(), $response->getReasonPhrase() ); $summary = ($bodySummarizer ?? new BodySummarizer())->summarize($response); if ($summary !== null) { $message .= ":\n{$summary}\n"; } return new $className($message, $request, $response, $previous, $handlerContext); } /** * Get the request that caused the exception */ public function getRequest(): RequestInterface { return $this->request; } /** * Get the associated response */ public function getResponse(): ?ResponseInterface { return $this->response; } /** * Check if a response was received */ public function hasResponse(): bool { return $this->response !== null; } /** * Get contextual information about the error from the underlying handler. * * The contents of this array will vary depending on which handler you are * using. It may also be just an empty array. Relying on this data will * couple you to a specific handler, but can give more debug information * when needed. */ public function getHandlerContext(): array { return $this->handlerContext; } } ================================================ FILE: lib/Google/vendor/guzzlehttp/guzzle/src/Exception/ServerException.php ================================================ maxHandles = $maxHandles; } public function create(RequestInterface $request, array $options): EasyHandle { $protocolVersion = $request->getProtocolVersion(); if ('2' === $protocolVersion || '2.0' === $protocolVersion) { if (!self::supportsHttp2()) { throw new ConnectException('HTTP/2 is supported by the cURL handler, however libcurl is built without HTTP/2 support.', $request); } } elseif ('1.0' !== $protocolVersion && '1.1' !== $protocolVersion) { throw new ConnectException(sprintf('HTTP/%s is not supported by the cURL handler.', $protocolVersion), $request); } if (isset($options['curl']['body_as_string'])) { $options['_body_as_string'] = $options['curl']['body_as_string']; unset($options['curl']['body_as_string']); } $easy = new EasyHandle(); $easy->request = $request; $easy->options = $options; $conf = $this->getDefaultConf($easy); $this->applyMethod($easy, $conf); $this->applyHandlerOptions($easy, $conf); $this->applyHeaders($easy, $conf); unset($conf['_headers']); // Add handler options from the request configuration options if (isset($options['curl'])) { $conf = \array_replace($conf, $options['curl']); } $conf[\CURLOPT_HEADERFUNCTION] = $this->createHeaderFn($easy); $easy->handle = $this->handles ? \array_pop($this->handles) : \curl_init(); curl_setopt_array($easy->handle, $conf); return $easy; } private static function supportsHttp2(): bool { static $supportsHttp2 = null; if (null === $supportsHttp2) { $supportsHttp2 = self::supportsTls12() && defined('CURL_VERSION_HTTP2') && (\CURL_VERSION_HTTP2 & \curl_version()['features']); } return $supportsHttp2; } private static function supportsTls12(): bool { static $supportsTls12 = null; if (null === $supportsTls12) { $supportsTls12 = \CURL_SSLVERSION_TLSv1_2 & \curl_version()['features']; } return $supportsTls12; } private static function supportsTls13(): bool { static $supportsTls13 = null; if (null === $supportsTls13) { $supportsTls13 = defined('CURL_SSLVERSION_TLSv1_3') && (\CURL_SSLVERSION_TLSv1_3 & \curl_version()['features']); } return $supportsTls13; } public function release(EasyHandle $easy): void { $resource = $easy->handle; unset($easy->handle); if (\count($this->handles) >= $this->maxHandles) { if (PHP_VERSION_ID < 80000) { \curl_close($resource); } } else { // Remove all callback functions as they can hold onto references // and are not cleaned up by curl_reset. Using curl_setopt_array // does not work for some reason, so removing each one // individually. \curl_setopt($resource, \CURLOPT_HEADERFUNCTION, null); \curl_setopt($resource, \CURLOPT_READFUNCTION, null); \curl_setopt($resource, \CURLOPT_WRITEFUNCTION, null); \curl_setopt($resource, \CURLOPT_PROGRESSFUNCTION, null); \curl_reset($resource); $this->handles[] = $resource; } } /** * Completes a cURL transaction, either returning a response promise or a * rejected promise. * * @param callable(RequestInterface, array): PromiseInterface $handler * @param CurlFactoryInterface $factory Dictates how the handle is released */ public static function finish(callable $handler, EasyHandle $easy, CurlFactoryInterface $factory): PromiseInterface { if (isset($easy->options['on_stats'])) { self::invokeStats($easy); } if (!$easy->response || $easy->errno) { return self::finishError($handler, $easy, $factory); } // Return the response if it is present and there is no error. $factory->release($easy); // Rewind the body of the response if possible. $body = $easy->response->getBody(); if ($body->isSeekable()) { $body->rewind(); } return new FulfilledPromise($easy->response); } private static function invokeStats(EasyHandle $easy): void { $curlStats = \curl_getinfo($easy->handle); $curlStats['appconnect_time'] = \curl_getinfo($easy->handle, \CURLINFO_APPCONNECT_TIME); $stats = new TransferStats( $easy->request, $easy->response, $curlStats['total_time'], $easy->errno, $curlStats ); ($easy->options['on_stats'])($stats); } /** * @param callable(RequestInterface, array): PromiseInterface $handler */ private static function finishError(callable $handler, EasyHandle $easy, CurlFactoryInterface $factory): PromiseInterface { // Get error information and release the handle to the factory. $ctx = [ 'errno' => $easy->errno, 'error' => \curl_error($easy->handle), 'appconnect_time' => \curl_getinfo($easy->handle, \CURLINFO_APPCONNECT_TIME), ] + \curl_getinfo($easy->handle); $ctx[self::CURL_VERSION_STR] = self::getCurlVersion(); $factory->release($easy); // Retry when nothing is present or when curl failed to rewind. if (empty($easy->options['_err_message']) && (!$easy->errno || $easy->errno == 65)) { return self::retryFailedRewind($handler, $easy, $ctx); } return self::createRejection($easy, $ctx); } private static function getCurlVersion(): string { static $curlVersion = null; if (null === $curlVersion) { $curlVersion = \curl_version()['version']; } return $curlVersion; } private static function createRejection(EasyHandle $easy, array $ctx): PromiseInterface { static $connectionErrors = [ \CURLE_OPERATION_TIMEOUTED => true, \CURLE_COULDNT_RESOLVE_HOST => true, \CURLE_COULDNT_CONNECT => true, \CURLE_SSL_CONNECT_ERROR => true, \CURLE_GOT_NOTHING => true, ]; if ($easy->createResponseException) { return P\Create::rejectionFor( new RequestException( 'An error was encountered while creating the response', $easy->request, $easy->response, $easy->createResponseException, $ctx ) ); } // If an exception was encountered during the onHeaders event, then // return a rejected promise that wraps that exception. if ($easy->onHeadersException) { return P\Create::rejectionFor( new RequestException( 'An error was encountered during the on_headers event', $easy->request, $easy->response, $easy->onHeadersException, $ctx ) ); } $uri = $easy->request->getUri(); $sanitizedError = self::sanitizeCurlError($ctx['error'] ?? '', $uri); $message = \sprintf( 'cURL error %s: %s (%s)', $ctx['errno'], $sanitizedError, 'see https://curl.haxx.se/libcurl/c/libcurl-errors.html' ); if ('' !== $sanitizedError) { $redactedUriString = \GuzzleHttp\Psr7\Utils::redactUserInfo($uri)->__toString(); if ($redactedUriString !== '' && false === \strpos($sanitizedError, $redactedUriString)) { $message .= \sprintf(' for %s', $redactedUriString); } } // Create a connection exception if it was a specific error code. $error = isset($connectionErrors[$easy->errno]) ? new ConnectException($message, $easy->request, null, $ctx) : new RequestException($message, $easy->request, $easy->response, null, $ctx); return P\Create::rejectionFor($error); } private static function sanitizeCurlError(string $error, UriInterface $uri): string { if ('' === $error) { return $error; } $baseUri = $uri->withQuery('')->withFragment(''); $baseUriString = $baseUri->__toString(); if ('' === $baseUriString) { return $error; } $redactedUriString = \GuzzleHttp\Psr7\Utils::redactUserInfo($baseUri)->__toString(); return str_replace($baseUriString, $redactedUriString, $error); } /** * @return array */ private function getDefaultConf(EasyHandle $easy): array { $conf = [ '_headers' => $easy->request->getHeaders(), \CURLOPT_CUSTOMREQUEST => $easy->request->getMethod(), \CURLOPT_URL => (string) $easy->request->getUri()->withFragment(''), \CURLOPT_RETURNTRANSFER => false, \CURLOPT_HEADER => false, \CURLOPT_CONNECTTIMEOUT => 300, ]; if (\defined('CURLOPT_PROTOCOLS')) { $conf[\CURLOPT_PROTOCOLS] = \CURLPROTO_HTTP | \CURLPROTO_HTTPS; } $version = $easy->request->getProtocolVersion(); if ('2' === $version || '2.0' === $version) { $conf[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_2_0; } elseif ('1.1' === $version) { $conf[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_1_1; } else { $conf[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_1_0; } return $conf; } private function applyMethod(EasyHandle $easy, array &$conf): void { $body = $easy->request->getBody(); $size = $body->getSize(); if ($size === null || $size > 0) { $this->applyBody($easy->request, $easy->options, $conf); return; } $method = $easy->request->getMethod(); if ($method === 'PUT' || $method === 'POST') { // See https://datatracker.ietf.org/doc/html/rfc7230#section-3.3.2 if (!$easy->request->hasHeader('Content-Length')) { $conf[\CURLOPT_HTTPHEADER][] = 'Content-Length: 0'; } } elseif ($method === 'HEAD') { $conf[\CURLOPT_NOBODY] = true; unset( $conf[\CURLOPT_WRITEFUNCTION], $conf[\CURLOPT_READFUNCTION], $conf[\CURLOPT_FILE], $conf[\CURLOPT_INFILE] ); } } private function applyBody(RequestInterface $request, array $options, array &$conf): void { $size = $request->hasHeader('Content-Length') ? (int) $request->getHeaderLine('Content-Length') : null; // Send the body as a string if the size is less than 1MB OR if the // [curl][body_as_string] request value is set. if (($size !== null && $size < 1000000) || !empty($options['_body_as_string'])) { $conf[\CURLOPT_POSTFIELDS] = (string) $request->getBody(); // Don't duplicate the Content-Length header $this->removeHeader('Content-Length', $conf); $this->removeHeader('Transfer-Encoding', $conf); } else { $conf[\CURLOPT_UPLOAD] = true; if ($size !== null) { $conf[\CURLOPT_INFILESIZE] = $size; $this->removeHeader('Content-Length', $conf); } $body = $request->getBody(); if ($body->isSeekable()) { $body->rewind(); } $conf[\CURLOPT_READFUNCTION] = static function ($ch, $fd, $length) use ($body) { return $body->read($length); }; } // If the Expect header is not present, prevent curl from adding it if (!$request->hasHeader('Expect')) { $conf[\CURLOPT_HTTPHEADER][] = 'Expect:'; } // cURL sometimes adds a content-type by default. Prevent this. if (!$request->hasHeader('Content-Type')) { $conf[\CURLOPT_HTTPHEADER][] = 'Content-Type:'; } } private function applyHeaders(EasyHandle $easy, array &$conf): void { foreach ($conf['_headers'] as $name => $values) { foreach ($values as $value) { $value = (string) $value; if ($value === '') { // cURL requires a special format for empty headers. // See https://github.com/guzzle/guzzle/issues/1882 for more details. $conf[\CURLOPT_HTTPHEADER][] = "$name;"; } else { $conf[\CURLOPT_HTTPHEADER][] = "$name: $value"; } } } // Remove the Accept header if one was not set if (!$easy->request->hasHeader('Accept')) { $conf[\CURLOPT_HTTPHEADER][] = 'Accept:'; } } /** * Remove a header from the options array. * * @param string $name Case-insensitive header to remove * @param array $options Array of options to modify */ private function removeHeader(string $name, array &$options): void { foreach (\array_keys($options['_headers']) as $key) { if (!\strcasecmp($key, $name)) { unset($options['_headers'][$key]); return; } } } private function applyHandlerOptions(EasyHandle $easy, array &$conf): void { $options = $easy->options; if (isset($options['verify'])) { if ($options['verify'] === false) { unset($conf[\CURLOPT_CAINFO]); $conf[\CURLOPT_SSL_VERIFYHOST] = 0; $conf[\CURLOPT_SSL_VERIFYPEER] = false; } else { $conf[\CURLOPT_SSL_VERIFYHOST] = 2; $conf[\CURLOPT_SSL_VERIFYPEER] = true; if (\is_string($options['verify'])) { // Throw an error if the file/folder/link path is not valid or doesn't exist. if (!\file_exists($options['verify'])) { throw new \InvalidArgumentException("SSL CA bundle not found: {$options['verify']}"); } // If it's a directory or a link to a directory use CURLOPT_CAPATH. // If not, it's probably a file, or a link to a file, so use CURLOPT_CAINFO. if ( \is_dir($options['verify']) || ( \is_link($options['verify']) === true && ($verifyLink = \readlink($options['verify'])) !== false && \is_dir($verifyLink) ) ) { $conf[\CURLOPT_CAPATH] = $options['verify']; } else { $conf[\CURLOPT_CAINFO] = $options['verify']; } } } } if (!isset($options['curl'][\CURLOPT_ENCODING]) && !empty($options['decode_content'])) { $accept = $easy->request->getHeaderLine('Accept-Encoding'); if ($accept) { $conf[\CURLOPT_ENCODING] = $accept; } else { // The empty string enables all available decoders and implicitly // sets a matching 'Accept-Encoding' header. $conf[\CURLOPT_ENCODING] = ''; // But as the user did not specify any encoding preference, // let's leave it up to server by preventing curl from sending // the header, which will be interpreted as 'Accept-Encoding: *'. // https://www.rfc-editor.org/rfc/rfc9110#field.accept-encoding $conf[\CURLOPT_HTTPHEADER][] = 'Accept-Encoding:'; } } if (!isset($options['sink'])) { // Use a default temp stream if no sink was set. $options['sink'] = \GuzzleHttp\Psr7\Utils::tryFopen('php://temp', 'w+'); } $sink = $options['sink']; if (!\is_string($sink)) { $sink = \GuzzleHttp\Psr7\Utils::streamFor($sink); } elseif (!\is_dir(\dirname($sink))) { // Ensure that the directory exists before failing in curl. throw new \RuntimeException(\sprintf('Directory %s does not exist for sink value of %s', \dirname($sink), $sink)); } else { $sink = new LazyOpenStream($sink, 'w+'); } $easy->sink = $sink; $conf[\CURLOPT_WRITEFUNCTION] = static function ($ch, $write) use ($sink): int { return $sink->write($write); }; $timeoutRequiresNoSignal = false; if (isset($options['timeout'])) { $timeoutRequiresNoSignal |= $options['timeout'] < 1; $conf[\CURLOPT_TIMEOUT_MS] = $options['timeout'] * 1000; } // CURL default value is CURL_IPRESOLVE_WHATEVER if (isset($options['force_ip_resolve'])) { if ('v4' === $options['force_ip_resolve']) { $conf[\CURLOPT_IPRESOLVE] = \CURL_IPRESOLVE_V4; } elseif ('v6' === $options['force_ip_resolve']) { $conf[\CURLOPT_IPRESOLVE] = \CURL_IPRESOLVE_V6; } } if (isset($options['connect_timeout'])) { $timeoutRequiresNoSignal |= $options['connect_timeout'] < 1; $conf[\CURLOPT_CONNECTTIMEOUT_MS] = $options['connect_timeout'] * 1000; } if ($timeoutRequiresNoSignal && \strtoupper(\substr(\PHP_OS, 0, 3)) !== 'WIN') { $conf[\CURLOPT_NOSIGNAL] = true; } if (isset($options['proxy'])) { if (!\is_array($options['proxy'])) { $conf[\CURLOPT_PROXY] = $options['proxy']; } else { $scheme = $easy->request->getUri()->getScheme(); if (isset($options['proxy'][$scheme])) { $host = $easy->request->getUri()->getHost(); if (isset($options['proxy']['no']) && Utils::isHostInNoProxy($host, $options['proxy']['no'])) { unset($conf[\CURLOPT_PROXY]); } else { $conf[\CURLOPT_PROXY] = $options['proxy'][$scheme]; } } } } if (isset($options['crypto_method'])) { $protocolVersion = $easy->request->getProtocolVersion(); // If HTTP/2, upgrade TLS 1.0 and 1.1 to 1.2 if ('2' === $protocolVersion || '2.0' === $protocolVersion) { if ( \STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT === $options['crypto_method'] || \STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT === $options['crypto_method'] || \STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT === $options['crypto_method'] ) { $conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_2; } elseif (defined('STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT') && \STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT === $options['crypto_method']) { if (!self::supportsTls13()) { throw new \InvalidArgumentException('Invalid crypto_method request option: TLS 1.3 not supported by your version of cURL'); } $conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_3; } else { throw new \InvalidArgumentException('Invalid crypto_method request option: unknown version provided'); } } elseif (\STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT === $options['crypto_method']) { $conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_0; } elseif (\STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT === $options['crypto_method']) { $conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_1; } elseif (\STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT === $options['crypto_method']) { if (!self::supportsTls12()) { throw new \InvalidArgumentException('Invalid crypto_method request option: TLS 1.2 not supported by your version of cURL'); } $conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_2; } elseif (defined('STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT') && \STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT === $options['crypto_method']) { if (!self::supportsTls13()) { throw new \InvalidArgumentException('Invalid crypto_method request option: TLS 1.3 not supported by your version of cURL'); } $conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_3; } else { throw new \InvalidArgumentException('Invalid crypto_method request option: unknown version provided'); } } if (isset($options['cert'])) { $cert = $options['cert']; if (\is_array($cert)) { $conf[\CURLOPT_SSLCERTPASSWD] = $cert[1]; $cert = $cert[0]; } if (!\file_exists($cert)) { throw new \InvalidArgumentException("SSL certificate not found: {$cert}"); } // OpenSSL (versions 0.9.3 and later) also support "P12" for PKCS#12-encoded files. // see https://curl.se/libcurl/c/CURLOPT_SSLCERTTYPE.html $ext = pathinfo($cert, \PATHINFO_EXTENSION); if (preg_match('#^(der|p12)$#i', $ext)) { $conf[\CURLOPT_SSLCERTTYPE] = strtoupper($ext); } $conf[\CURLOPT_SSLCERT] = $cert; } if (isset($options['ssl_key'])) { if (\is_array($options['ssl_key'])) { if (\count($options['ssl_key']) === 2) { [$sslKey, $conf[\CURLOPT_SSLKEYPASSWD]] = $options['ssl_key']; } else { [$sslKey] = $options['ssl_key']; } } $sslKey = $sslKey ?? $options['ssl_key']; if (!\file_exists($sslKey)) { throw new \InvalidArgumentException("SSL private key not found: {$sslKey}"); } $conf[\CURLOPT_SSLKEY] = $sslKey; } if (isset($options['progress'])) { $progress = $options['progress']; if (!\is_callable($progress)) { throw new \InvalidArgumentException('progress client option must be callable'); } $conf[\CURLOPT_NOPROGRESS] = false; $conf[\CURLOPT_PROGRESSFUNCTION] = static function ($resource, int $downloadSize, int $downloaded, int $uploadSize, int $uploaded) use ($progress) { $progress($downloadSize, $downloaded, $uploadSize, $uploaded); }; } if (!empty($options['debug'])) { $conf[\CURLOPT_STDERR] = Utils::debugResource($options['debug']); $conf[\CURLOPT_VERBOSE] = true; } } /** * This function ensures that a response was set on a transaction. If one * was not set, then the request is retried if possible. This error * typically means you are sending a payload, curl encountered a * "Connection died, retrying a fresh connect" error, tried to rewind the * stream, and then encountered a "necessary data rewind wasn't possible" * error, causing the request to be sent through curl_multi_info_read() * without an error status. * * @param callable(RequestInterface, array): PromiseInterface $handler */ private static function retryFailedRewind(callable $handler, EasyHandle $easy, array $ctx): PromiseInterface { try { // Only rewind if the body has been read from. $body = $easy->request->getBody(); if ($body->tell() > 0) { $body->rewind(); } } catch (\RuntimeException $e) { $ctx['error'] = 'The connection unexpectedly failed without ' .'providing an error. The request would have been retried, ' .'but attempting to rewind the request body failed. ' .'Exception: '.$e; return self::createRejection($easy, $ctx); } // Retry no more than 3 times before giving up. if (!isset($easy->options['_curl_retries'])) { $easy->options['_curl_retries'] = 1; } elseif ($easy->options['_curl_retries'] == 2) { $ctx['error'] = 'The cURL request was retried 3 times ' .'and did not succeed. The most likely reason for the failure ' .'is that cURL was unable to rewind the body of the request ' .'and subsequent retries resulted in the same error. Turn on ' .'the debug option to see what went wrong. See ' .'https://bugs.php.net/bug.php?id=47204 for more information.'; return self::createRejection($easy, $ctx); } else { ++$easy->options['_curl_retries']; } return $handler($easy->request, $easy->options); } private function createHeaderFn(EasyHandle $easy): callable { if (isset($easy->options['on_headers'])) { $onHeaders = $easy->options['on_headers']; if (!\is_callable($onHeaders)) { throw new \InvalidArgumentException('on_headers must be callable'); } } else { $onHeaders = null; } return static function ($ch, $h) use ( $onHeaders, $easy, &$startingResponse ) { $value = \trim($h); if ($value === '') { $startingResponse = true; try { $easy->createResponse(); } catch (\Exception $e) { $easy->createResponseException = $e; return -1; } if ($onHeaders !== null) { try { $onHeaders($easy->response); } catch (\Exception $e) { // Associate the exception with the handle and trigger // a curl header write error by returning 0. $easy->onHeadersException = $e; return -1; } } } elseif ($startingResponse) { $startingResponse = false; $easy->headers = [$value]; } else { $easy->headers[] = $value; } return \strlen($h); }; } public function __destruct() { foreach ($this->handles as $id => $handle) { if (PHP_VERSION_ID < 80000) { \curl_close($handle); } unset($this->handles[$id]); } } } ================================================ FILE: lib/Google/vendor/guzzlehttp/guzzle/src/Handler/CurlFactoryInterface.php ================================================ factory = $options['handle_factory'] ?? new CurlFactory(3); } public function __invoke(RequestInterface $request, array $options): PromiseInterface { if (isset($options['delay'])) { \usleep($options['delay'] * 1000); } $easy = $this->factory->create($request, $options); \curl_exec($easy->handle); $easy->errno = \curl_errno($easy->handle); return CurlFactory::finish($this, $easy, $this->factory); } } ================================================ FILE: lib/Google/vendor/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php ================================================ An array of delay times, indexed by handle id in `addRequest`. * * @see CurlMultiHandler::addRequest */ private $delays = []; /** * @var array An associative array of CURLMOPT_* options and corresponding values for curl_multi_setopt() */ private $options = []; /** @var resource|\CurlMultiHandle */ private $_mh; /** * This handler accepts the following options: * * - handle_factory: An optional factory used to create curl handles * - select_timeout: Optional timeout (in seconds) to block before timing * out while selecting curl handles. Defaults to 1 second. * - options: An associative array of CURLMOPT_* options and * corresponding values for curl_multi_setopt() */ public function __construct(array $options = []) { $this->factory = $options['handle_factory'] ?? new CurlFactory(50); if (isset($options['select_timeout'])) { $this->selectTimeout = $options['select_timeout']; } elseif ($selectTimeout = Utils::getenv('GUZZLE_CURL_SELECT_TIMEOUT')) { @trigger_error('Since guzzlehttp/guzzle 7.2.0: Using environment variable GUZZLE_CURL_SELECT_TIMEOUT is deprecated. Use option "select_timeout" instead.', \E_USER_DEPRECATED); $this->selectTimeout = (int) $selectTimeout; } else { $this->selectTimeout = 1; } $this->options = $options['options'] ?? []; // unsetting the property forces the first access to go through // __get(). unset($this->_mh); } /** * @param string $name * * @return resource|\CurlMultiHandle * * @throws \BadMethodCallException when another field as `_mh` will be gotten * @throws \RuntimeException when curl can not initialize a multi handle */ public function __get($name) { if ($name !== '_mh') { throw new \BadMethodCallException("Can not get other property as '_mh'."); } $multiHandle = \curl_multi_init(); if (false === $multiHandle) { throw new \RuntimeException('Can not initialize curl multi handle.'); } $this->_mh = $multiHandle; foreach ($this->options as $option => $value) { // A warning is raised in case of a wrong option. curl_multi_setopt($this->_mh, $option, $value); } return $this->_mh; } public function __destruct() { if (isset($this->_mh)) { \curl_multi_close($this->_mh); unset($this->_mh); } } public function __invoke(RequestInterface $request, array $options): PromiseInterface { $easy = $this->factory->create($request, $options); $id = (int) $easy->handle; $promise = new Promise( [$this, 'execute'], function () use ($id) { return $this->cancel($id); } ); $this->addRequest(['easy' => $easy, 'deferred' => $promise]); return $promise; } /** * Ticks the curl event loop. */ public function tick(): void { // Add any delayed handles if needed. if ($this->delays) { $currentTime = Utils::currentTime(); foreach ($this->delays as $id => $delay) { if ($currentTime >= $delay) { unset($this->delays[$id]); \curl_multi_add_handle( $this->_mh, $this->handles[$id]['easy']->handle ); } } } // Run curl_multi_exec in the queue to enable other async tasks to run P\Utils::queue()->add(Closure::fromCallable([$this, 'tickInQueue'])); // Step through the task queue which may add additional requests. P\Utils::queue()->run(); if ($this->active && \curl_multi_select($this->_mh, $this->selectTimeout) === -1) { // Perform a usleep if a select returns -1. // See: https://bugs.php.net/bug.php?id=61141 \usleep(250); } while (\curl_multi_exec($this->_mh, $this->active) === \CURLM_CALL_MULTI_PERFORM) { // Prevent busy looping for slow HTTP requests. \curl_multi_select($this->_mh, $this->selectTimeout); } $this->processMessages(); } /** * Runs \curl_multi_exec() inside the event loop, to prevent busy looping */ private function tickInQueue(): void { if (\curl_multi_exec($this->_mh, $this->active) === \CURLM_CALL_MULTI_PERFORM) { \curl_multi_select($this->_mh, 0); P\Utils::queue()->add(Closure::fromCallable([$this, 'tickInQueue'])); } } /** * Runs until all outstanding connections have completed. */ public function execute(): void { $queue = P\Utils::queue(); while ($this->handles || !$queue->isEmpty()) { // If there are no transfers, then sleep for the next delay if (!$this->active && $this->delays) { \usleep($this->timeToNext()); } $this->tick(); } } private function addRequest(array $entry): void { $easy = $entry['easy']; $id = (int) $easy->handle; $this->handles[$id] = $entry; if (empty($easy->options['delay'])) { \curl_multi_add_handle($this->_mh, $easy->handle); } else { $this->delays[$id] = Utils::currentTime() + ($easy->options['delay'] / 1000); } } /** * Cancels a handle from sending and removes references to it. * * @param int $id Handle ID to cancel and remove. * * @return bool True on success, false on failure. */ private function cancel($id): bool { if (!is_int($id)) { trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing an integer to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__); } // Cannot cancel if it has been processed. if (!isset($this->handles[$id])) { return false; } $handle = $this->handles[$id]['easy']->handle; unset($this->delays[$id], $this->handles[$id]); \curl_multi_remove_handle($this->_mh, $handle); if (PHP_VERSION_ID < 80000) { \curl_close($handle); } return true; } private function processMessages(): void { while ($done = \curl_multi_info_read($this->_mh)) { if ($done['msg'] !== \CURLMSG_DONE) { // if it's not done, then it would be premature to remove the handle. ref https://github.com/guzzle/guzzle/pull/2892#issuecomment-945150216 continue; } $id = (int) $done['handle']; \curl_multi_remove_handle($this->_mh, $done['handle']); if (!isset($this->handles[$id])) { // Probably was cancelled. continue; } $entry = $this->handles[$id]; unset($this->handles[$id], $this->delays[$id]); $entry['easy']->errno = $done['result']; $entry['deferred']->resolve( CurlFactory::finish($this, $entry['easy'], $this->factory) ); } } private function timeToNext(): int { $currentTime = Utils::currentTime(); $nextTime = \PHP_INT_MAX; foreach ($this->delays as $time) { if ($time < $nextTime) { $nextTime = $time; } } return ((int) \max(0, $nextTime - $currentTime)) * 1000000; } } ================================================ FILE: lib/Google/vendor/guzzlehttp/guzzle/src/Handler/EasyHandle.php ================================================ headers); $normalizedKeys = Utils::normalizeHeaderKeys($headers); if (!empty($this->options['decode_content']) && isset($normalizedKeys['content-encoding'])) { $headers['x-encoded-content-encoding'] = $headers[$normalizedKeys['content-encoding']]; unset($headers[$normalizedKeys['content-encoding']]); if (isset($normalizedKeys['content-length'])) { $headers['x-encoded-content-length'] = $headers[$normalizedKeys['content-length']]; $bodyLength = (int) $this->sink->getSize(); if ($bodyLength) { $headers[$normalizedKeys['content-length']] = $bodyLength; } else { unset($headers[$normalizedKeys['content-length']]); } } } // Attach a response to the easy handle with the parsed headers. $this->response = new Response( $status, $headers, $this->sink, $ver, $reason ); } /** * @param string $name * * @return void * * @throws \BadMethodCallException */ public function __get($name) { $msg = $name === 'handle' ? 'The EasyHandle has been released' : 'Invalid property: '.$name; throw new \BadMethodCallException($msg); } } ================================================ FILE: lib/Google/vendor/guzzlehttp/guzzle/src/Handler/HeaderProcessor.php ================================================ |null $queue The parameters to be passed to the append function, as an indexed array. * @param callable|null $onFulfilled Callback to invoke when the return value is fulfilled. * @param callable|null $onRejected Callback to invoke when the return value is rejected. */ public function __construct(?array $queue = null, ?callable $onFulfilled = null, ?callable $onRejected = null) { $this->onFulfilled = $onFulfilled; $this->onRejected = $onRejected; if ($queue) { // array_values included for BC $this->append(...array_values($queue)); } } public function __invoke(RequestInterface $request, array $options): PromiseInterface { if (!$this->queue) { throw new \OutOfBoundsException('Mock queue is empty'); } if (isset($options['delay']) && \is_numeric($options['delay'])) { \usleep((int) $options['delay'] * 1000); } $this->lastRequest = $request; $this->lastOptions = $options; $response = \array_shift($this->queue); if (isset($options['on_headers'])) { if (!\is_callable($options['on_headers'])) { throw new \InvalidArgumentException('on_headers must be callable'); } try { $options['on_headers']($response); } catch (\Exception $e) { $msg = 'An error was encountered during the on_headers event'; $response = new RequestException($msg, $request, $response, $e); } } if (\is_callable($response)) { $response = $response($request, $options); } $response = $response instanceof \Throwable ? P\Create::rejectionFor($response) : P\Create::promiseFor($response); return $response->then( function (?ResponseInterface $value) use ($request, $options) { $this->invokeStats($request, $options, $value); if ($this->onFulfilled) { ($this->onFulfilled)($value); } if ($value !== null && isset($options['sink'])) { $contents = (string) $value->getBody(); $sink = $options['sink']; if (\is_resource($sink)) { \fwrite($sink, $contents); } elseif (\is_string($sink)) { \file_put_contents($sink, $contents); } elseif ($sink instanceof StreamInterface) { $sink->write($contents); } } return $value; }, function ($reason) use ($request, $options) { $this->invokeStats($request, $options, null, $reason); if ($this->onRejected) { ($this->onRejected)($reason); } return P\Create::rejectionFor($reason); } ); } /** * Adds one or more variadic requests, exceptions, callables, or promises * to the queue. * * @param mixed ...$values */ public function append(...$values): void { foreach ($values as $value) { if ($value instanceof ResponseInterface || $value instanceof \Throwable || $value instanceof PromiseInterface || \is_callable($value) ) { $this->queue[] = $value; } else { throw new \TypeError('Expected a Response, Promise, Throwable or callable. Found '.Utils::describeType($value)); } } } /** * Get the last received request. */ public function getLastRequest(): ?RequestInterface { return $this->lastRequest; } /** * Get the last received request options. */ public function getLastOptions(): array { return $this->lastOptions; } /** * Returns the number of remaining items in the queue. */ public function count(): int { return \count($this->queue); } public function reset(): void { $this->queue = []; } /** * @param mixed $reason Promise or reason. */ private function invokeStats( RequestInterface $request, array $options, ?ResponseInterface $response = null, $reason = null ): void { if (isset($options['on_stats'])) { $transferTime = $options['transfer_time'] ?? 0; $stats = new TransferStats($request, $response, $transferTime, $reason); ($options['on_stats'])($stats); } } } ================================================ FILE: lib/Google/vendor/guzzlehttp/guzzle/src/Handler/Proxy.php ================================================ getProtocolVersion(); if ('1.0' !== $protocolVersion && '1.1' !== $protocolVersion) { throw new ConnectException(sprintf('HTTP/%s is not supported by the stream handler.', $protocolVersion), $request); } $startTime = isset($options['on_stats']) ? Utils::currentTime() : null; try { // Does not support the expect header. $request = $request->withoutHeader('Expect'); // Append a content-length header if body size is zero to match // the behavior of `CurlHandler` if ( ( 0 === \strcasecmp('PUT', $request->getMethod()) || 0 === \strcasecmp('POST', $request->getMethod()) ) && 0 === $request->getBody()->getSize() ) { $request = $request->withHeader('Content-Length', '0'); } return $this->createResponse( $request, $options, $this->createStream($request, $options), $startTime ); } catch (\InvalidArgumentException $e) { throw $e; } catch (\Exception $e) { // Determine if the error was a networking error. $message = $e->getMessage(); // This list can probably get more comprehensive. if (false !== \strpos($message, 'getaddrinfo') // DNS lookup failed || false !== \strpos($message, 'Connection refused') || false !== \strpos($message, "couldn't connect to host") // error on HHVM || false !== \strpos($message, 'connection attempt failed') ) { $e = new ConnectException($e->getMessage(), $request, $e); } else { $e = RequestException::wrapException($request, $e); } $this->invokeStats($options, $request, $startTime, null, $e); return P\Create::rejectionFor($e); } } private function invokeStats( array $options, RequestInterface $request, ?float $startTime, ?ResponseInterface $response = null, ?\Throwable $error = null ): void { if (isset($options['on_stats'])) { $stats = new TransferStats($request, $response, Utils::currentTime() - $startTime, $error, []); ($options['on_stats'])($stats); } } /** * @param resource $stream */ private function createResponse(RequestInterface $request, array $options, $stream, ?float $startTime): PromiseInterface { $hdrs = $this->lastHeaders; $this->lastHeaders = []; try { [$ver, $status, $reason, $headers] = HeaderProcessor::parseHeaders($hdrs); } catch (\Exception $e) { return P\Create::rejectionFor( new RequestException('An error was encountered while creating the response', $request, null, $e) ); } [$stream, $headers] = $this->checkDecode($options, $headers, $stream); $stream = Psr7\Utils::streamFor($stream); $sink = $stream; if (\strcasecmp('HEAD', $request->getMethod())) { $sink = $this->createSink($stream, $options); } try { $response = new Psr7\Response($status, $headers, $sink, $ver, $reason); } catch (\Exception $e) { return P\Create::rejectionFor( new RequestException('An error was encountered while creating the response', $request, null, $e) ); } if (isset($options['on_headers'])) { try { $options['on_headers']($response); } catch (\Exception $e) { return P\Create::rejectionFor( new RequestException('An error was encountered during the on_headers event', $request, $response, $e) ); } } // Do not drain when the request is a HEAD request because they have // no body. if ($sink !== $stream) { $this->drain($stream, $sink, $response->getHeaderLine('Content-Length')); } $this->invokeStats($options, $request, $startTime, $response, null); return new FulfilledPromise($response); } private function createSink(StreamInterface $stream, array $options): StreamInterface { if (!empty($options['stream'])) { return $stream; } $sink = $options['sink'] ?? Psr7\Utils::tryFopen('php://temp', 'r+'); return \is_string($sink) ? new Psr7\LazyOpenStream($sink, 'w+') : Psr7\Utils::streamFor($sink); } /** * @param resource $stream */ private function checkDecode(array $options, array $headers, $stream): array { // Automatically decode responses when instructed. if (!empty($options['decode_content'])) { $normalizedKeys = Utils::normalizeHeaderKeys($headers); if (isset($normalizedKeys['content-encoding'])) { $encoding = $headers[$normalizedKeys['content-encoding']]; if ($encoding[0] === 'gzip' || $encoding[0] === 'deflate') { $stream = new Psr7\InflateStream(Psr7\Utils::streamFor($stream)); $headers['x-encoded-content-encoding'] = $headers[$normalizedKeys['content-encoding']]; // Remove content-encoding header unset($headers[$normalizedKeys['content-encoding']]); // Fix content-length header if (isset($normalizedKeys['content-length'])) { $headers['x-encoded-content-length'] = $headers[$normalizedKeys['content-length']]; $length = (int) $stream->getSize(); if ($length === 0) { unset($headers[$normalizedKeys['content-length']]); } else { $headers[$normalizedKeys['content-length']] = [$length]; } } } } } return [$stream, $headers]; } /** * Drains the source stream into the "sink" client option. * * @param string $contentLength Header specifying the amount of * data to read. * * @throws \RuntimeException when the sink option is invalid. */ private function drain(StreamInterface $source, StreamInterface $sink, string $contentLength): StreamInterface { // If a content-length header is provided, then stop reading once // that number of bytes has been read. This can prevent infinitely // reading from a stream when dealing with servers that do not honor // Connection: Close headers. Psr7\Utils::copyToStream( $source, $sink, (\strlen($contentLength) > 0 && (int) $contentLength > 0) ? (int) $contentLength : -1 ); $sink->seek(0); $source->close(); return $sink; } /** * Create a resource and check to ensure it was created successfully * * @param callable $callback Callable that returns stream resource * * @return resource * * @throws \RuntimeException on error */ private function createResource(callable $callback) { $errors = []; \set_error_handler(static function ($_, $msg, $file, $line) use (&$errors): bool { $errors[] = [ 'message' => $msg, 'file' => $file, 'line' => $line, ]; return true; }); try { $resource = $callback(); } finally { \restore_error_handler(); } if (!$resource) { $message = 'Error creating resource: '; foreach ($errors as $err) { foreach ($err as $key => $value) { $message .= "[$key] $value".\PHP_EOL; } } throw new \RuntimeException(\trim($message)); } return $resource; } /** * @return resource */ private function createStream(RequestInterface $request, array $options) { static $methods; if (!$methods) { $methods = \array_flip(\get_class_methods(__CLASS__)); } if (!\in_array($request->getUri()->getScheme(), ['http', 'https'])) { throw new RequestException(\sprintf("The scheme '%s' is not supported.", $request->getUri()->getScheme()), $request); } // HTTP/1.1 streams using the PHP stream wrapper require a // Connection: close header if ($request->getProtocolVersion() === '1.1' && !$request->hasHeader('Connection') ) { $request = $request->withHeader('Connection', 'close'); } // Ensure SSL is verified by default if (!isset($options['verify'])) { $options['verify'] = true; } $params = []; $context = $this->getDefaultContext($request); if (isset($options['on_headers']) && !\is_callable($options['on_headers'])) { throw new \InvalidArgumentException('on_headers must be callable'); } if (!empty($options)) { foreach ($options as $key => $value) { $method = "add_{$key}"; if (isset($methods[$method])) { $this->{$method}($request, $context, $value, $params); } } } if (isset($options['stream_context'])) { if (!\is_array($options['stream_context'])) { throw new \InvalidArgumentException('stream_context must be an array'); } $context = \array_replace_recursive($context, $options['stream_context']); } // Microsoft NTLM authentication only supported with curl handler if (isset($options['auth'][2]) && 'ntlm' === $options['auth'][2]) { throw new \InvalidArgumentException('Microsoft NTLM authentication only supported with curl handler'); } $uri = $this->resolveHost($request, $options); $contextResource = $this->createResource( static function () use ($context, $params) { return \stream_context_create($context, $params); } ); return $this->createResource( function () use ($uri, $contextResource, $context, $options, $request) { $resource = @\fopen((string) $uri, 'r', false, $contextResource); // See https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_the_http_response_header_predefined_variable if (function_exists('http_get_last_response_headers')) { /** @var array|null */ $http_response_header = \http_get_last_response_headers(); } $this->lastHeaders = $http_response_header ?? []; if (false === $resource) { throw new ConnectException(sprintf('Connection refused for URI %s', $uri), $request, null, $context); } if (isset($options['read_timeout'])) { $readTimeout = $options['read_timeout']; $sec = (int) $readTimeout; $usec = ($readTimeout - $sec) * 100000; \stream_set_timeout($resource, $sec, $usec); } return $resource; } ); } private function resolveHost(RequestInterface $request, array $options): UriInterface { $uri = $request->getUri(); if (isset($options['force_ip_resolve']) && !\filter_var($uri->getHost(), \FILTER_VALIDATE_IP)) { if ('v4' === $options['force_ip_resolve']) { $records = \dns_get_record($uri->getHost(), \DNS_A); if (false === $records || !isset($records[0]['ip'])) { throw new ConnectException(\sprintf("Could not resolve IPv4 address for host '%s'", $uri->getHost()), $request); } return $uri->withHost($records[0]['ip']); } if ('v6' === $options['force_ip_resolve']) { $records = \dns_get_record($uri->getHost(), \DNS_AAAA); if (false === $records || !isset($records[0]['ipv6'])) { throw new ConnectException(\sprintf("Could not resolve IPv6 address for host '%s'", $uri->getHost()), $request); } return $uri->withHost('['.$records[0]['ipv6'].']'); } } return $uri; } private function getDefaultContext(RequestInterface $request): array { $headers = ''; foreach ($request->getHeaders() as $name => $value) { foreach ($value as $val) { $headers .= "$name: $val\r\n"; } } $context = [ 'http' => [ 'method' => $request->getMethod(), 'header' => $headers, 'protocol_version' => $request->getProtocolVersion(), 'ignore_errors' => true, 'follow_location' => 0, ], 'ssl' => [ 'peer_name' => $request->getUri()->getHost(), ], ]; $body = (string) $request->getBody(); if ('' !== $body) { $context['http']['content'] = $body; // Prevent the HTTP handler from adding a Content-Type header. if (!$request->hasHeader('Content-Type')) { $context['http']['header'] .= "Content-Type:\r\n"; } } $context['http']['header'] = \rtrim($context['http']['header']); return $context; } /** * @param mixed $value as passed via Request transfer options. */ private function add_proxy(RequestInterface $request, array &$options, $value, array &$params): void { $uri = null; if (!\is_array($value)) { $uri = $value; } else { $scheme = $request->getUri()->getScheme(); if (isset($value[$scheme])) { if (!isset($value['no']) || !Utils::isHostInNoProxy($request->getUri()->getHost(), $value['no'])) { $uri = $value[$scheme]; } } } if (!$uri) { return; } $parsed = $this->parse_proxy($uri); $options['http']['proxy'] = $parsed['proxy']; if ($parsed['auth']) { if (!isset($options['http']['header'])) { $options['http']['header'] = []; } $options['http']['header'] .= "\r\nProxy-Authorization: {$parsed['auth']}"; } } /** * Parses the given proxy URL to make it compatible with the format PHP's stream context expects. */ private function parse_proxy(string $url): array { $parsed = \parse_url($url); if ($parsed !== false && isset($parsed['scheme']) && $parsed['scheme'] === 'http') { if (isset($parsed['host']) && isset($parsed['port'])) { $auth = null; if (isset($parsed['user']) && isset($parsed['pass'])) { $auth = \base64_encode("{$parsed['user']}:{$parsed['pass']}"); } return [ 'proxy' => "tcp://{$parsed['host']}:{$parsed['port']}", 'auth' => $auth ? "Basic {$auth}" : null, ]; } } // Return proxy as-is. return [ 'proxy' => $url, 'auth' => null, ]; } /** * @param mixed $value as passed via Request transfer options. */ private function add_timeout(RequestInterface $request, array &$options, $value, array &$params): void { if ($value > 0) { $options['http']['timeout'] = $value; } } /** * @param mixed $value as passed via Request transfer options. */ private function add_crypto_method(RequestInterface $request, array &$options, $value, array &$params): void { if ( $value === \STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT || $value === \STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT || $value === \STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT || (defined('STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT') && $value === \STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT) ) { $options['http']['crypto_method'] = $value; return; } throw new \InvalidArgumentException('Invalid crypto_method request option: unknown version provided'); } /** * @param mixed $value as passed via Request transfer options. */ private function add_verify(RequestInterface $request, array &$options, $value, array &$params): void { if ($value === false) { $options['ssl']['verify_peer'] = false; $options['ssl']['verify_peer_name'] = false; return; } if (\is_string($value)) { $options['ssl']['cafile'] = $value; if (!\file_exists($value)) { throw new \RuntimeException("SSL CA bundle not found: $value"); } } elseif ($value !== true) { throw new \InvalidArgumentException('Invalid verify request option'); } $options['ssl']['verify_peer'] = true; $options['ssl']['verify_peer_name'] = true; $options['ssl']['allow_self_signed'] = false; } /** * @param mixed $value as passed via Request transfer options. */ private function add_cert(RequestInterface $request, array &$options, $value, array &$params): void { if (\is_array($value)) { $options['ssl']['passphrase'] = $value[1]; $value = $value[0]; } if (!\file_exists($value)) { throw new \RuntimeException("SSL certificate not found: {$value}"); } $options['ssl']['local_cert'] = $value; } /** * @param mixed $value as passed via Request transfer options. */ private function add_progress(RequestInterface $request, array &$options, $value, array &$params): void { self::addNotification( $params, static function ($code, $a, $b, $c, $transferred, $total) use ($value) { if ($code == \STREAM_NOTIFY_PROGRESS) { // The upload progress cannot be determined. Use 0 for cURL compatibility: // https://curl.se/libcurl/c/CURLOPT_PROGRESSFUNCTION.html $value($total, $transferred, 0, 0); } } ); } /** * @param mixed $value as passed via Request transfer options. */ private function add_debug(RequestInterface $request, array &$options, $value, array &$params): void { if ($value === false) { return; } static $map = [ \STREAM_NOTIFY_CONNECT => 'CONNECT', \STREAM_NOTIFY_AUTH_REQUIRED => 'AUTH_REQUIRED', \STREAM_NOTIFY_AUTH_RESULT => 'AUTH_RESULT', \STREAM_NOTIFY_MIME_TYPE_IS => 'MIME_TYPE_IS', \STREAM_NOTIFY_FILE_SIZE_IS => 'FILE_SIZE_IS', \STREAM_NOTIFY_REDIRECTED => 'REDIRECTED', \STREAM_NOTIFY_PROGRESS => 'PROGRESS', \STREAM_NOTIFY_FAILURE => 'FAILURE', \STREAM_NOTIFY_COMPLETED => 'COMPLETED', \STREAM_NOTIFY_RESOLVE => 'RESOLVE', ]; static $args = ['severity', 'message', 'message_code', 'bytes_transferred', 'bytes_max']; $value = Utils::debugResource($value); $ident = $request->getMethod().' '.$request->getUri()->withFragment(''); self::addNotification( $params, static function (int $code, ...$passed) use ($ident, $value, $map, $args): void { \fprintf($value, '<%s> [%s] ', $ident, $map[$code]); foreach (\array_filter($passed) as $i => $v) { \fwrite($value, $args[$i].': "'.$v.'" '); } \fwrite($value, "\n"); } ); } private static function addNotification(array &$params, callable $notify): void { // Wrap the existing function if needed. if (!isset($params['notification'])) { $params['notification'] = $notify; } else { $params['notification'] = self::callArray([ $params['notification'], $notify, ]); } } private static function callArray(array $functions): callable { return static function (...$args) use ($functions) { foreach ($functions as $fn) { $fn(...$args); } }; } } ================================================ FILE: lib/Google/vendor/guzzlehttp/guzzle/src/HandlerStack.php ================================================ push(Middleware::httpErrors(), 'http_errors'); $stack->push(Middleware::redirect(), 'allow_redirects'); $stack->push(Middleware::cookies(), 'cookies'); $stack->push(Middleware::prepareBody(), 'prepare_body'); return $stack; } /** * @param (callable(RequestInterface, array): PromiseInterface)|null $handler Underlying HTTP handler. */ public function __construct(?callable $handler = null) { $this->handler = $handler; } /** * Invokes the handler stack as a composed handler * * @return ResponseInterface|PromiseInterface */ public function __invoke(RequestInterface $request, array $options) { $handler = $this->resolve(); return $handler($request, $options); } /** * Dumps a string representation of the stack. * * @return string */ public function __toString() { $depth = 0; $stack = []; if ($this->handler !== null) { $stack[] = '0) Handler: '.$this->debugCallable($this->handler); } $result = ''; foreach (\array_reverse($this->stack) as $tuple) { ++$depth; $str = "{$depth}) Name: '{$tuple[1]}', "; $str .= 'Function: '.$this->debugCallable($tuple[0]); $result = "> {$str}\n{$result}"; $stack[] = $str; } foreach (\array_keys($stack) as $k) { $result .= "< {$stack[$k]}\n"; } return $result; } /** * Set the HTTP handler that actually returns a promise. * * @param callable(RequestInterface, array): PromiseInterface $handler Accepts a request and array of options and * returns a Promise. */ public function setHandler(callable $handler): void { $this->handler = $handler; $this->cached = null; } /** * Returns true if the builder has a handler. */ public function hasHandler(): bool { return $this->handler !== null; } /** * Unshift a middleware to the bottom of the stack. * * @param callable(callable): callable $middleware Middleware function * @param string $name Name to register for this middleware. */ public function unshift(callable $middleware, ?string $name = null): void { \array_unshift($this->stack, [$middleware, $name]); $this->cached = null; } /** * Push a middleware to the top of the stack. * * @param callable(callable): callable $middleware Middleware function * @param string $name Name to register for this middleware. */ public function push(callable $middleware, string $name = ''): void { $this->stack[] = [$middleware, $name]; $this->cached = null; } /** * Add a middleware before another middleware by name. * * @param string $findName Middleware to find * @param callable(callable): callable $middleware Middleware function * @param string $withName Name to register for this middleware. */ public function before(string $findName, callable $middleware, string $withName = ''): void { $this->splice($findName, $withName, $middleware, true); } /** * Add a middleware after another middleware by name. * * @param string $findName Middleware to find * @param callable(callable): callable $middleware Middleware function * @param string $withName Name to register for this middleware. */ public function after(string $findName, callable $middleware, string $withName = ''): void { $this->splice($findName, $withName, $middleware, false); } /** * Remove a middleware by instance or name from the stack. * * @param callable|string $remove Middleware to remove by instance or name. */ public function remove($remove): void { if (!is_string($remove) && !is_callable($remove)) { trigger_deprecation('guzzlehttp/guzzle', '7.4', 'Not passing a callable or string to %s::%s() is deprecated and will cause an error in 8.0.', __CLASS__, __FUNCTION__); } $this->cached = null; $idx = \is_callable($remove) ? 0 : 1; $this->stack = \array_values(\array_filter( $this->stack, static function ($tuple) use ($idx, $remove) { return $tuple[$idx] !== $remove; } )); } /** * Compose the middleware and handler into a single callable function. * * @return callable(RequestInterface, array): PromiseInterface */ public function resolve(): callable { if ($this->cached === null) { if (($prev = $this->handler) === null) { throw new \LogicException('No handler has been specified'); } foreach (\array_reverse($this->stack) as $fn) { /** @var callable(RequestInterface, array): PromiseInterface $prev */ $prev = $fn[0]($prev); } $this->cached = $prev; } return $this->cached; } private function findByName(string $name): int { foreach ($this->stack as $k => $v) { if ($v[1] === $name) { return $k; } } throw new \InvalidArgumentException("Middleware not found: $name"); } /** * Splices a function into the middleware list at a specific position. */ private function splice(string $findName, string $withName, callable $middleware, bool $before): void { $this->cached = null; $idx = $this->findByName($findName); $tuple = [$middleware, $withName]; if ($before) { if ($idx === 0) { \array_unshift($this->stack, $tuple); } else { $replacement = [$tuple, $this->stack[$idx]]; \array_splice($this->stack, $idx, 1, $replacement); } } elseif ($idx === \count($this->stack) - 1) { $this->stack[] = $tuple; } else { $replacement = [$this->stack[$idx], $tuple]; \array_splice($this->stack, $idx, 1, $replacement); } } /** * Provides a debug string for a given callable. * * @param callable|string $fn Function to write as a string. */ private function debugCallable($fn): string { if (\is_string($fn)) { return "callable({$fn})"; } if (\is_array($fn)) { return \is_string($fn[0]) ? "callable({$fn[0]}::{$fn[1]})" : "callable(['".\get_class($fn[0])."', '{$fn[1]}'])"; } /** @var object $fn */ return 'callable('.\spl_object_hash($fn).')'; } } ================================================ FILE: lib/Google/vendor/guzzlehttp/guzzle/src/MessageFormatter.php ================================================ >>>>>>>\n{request}\n<<<<<<<<\n{response}\n--------\n{error}"; public const SHORT = '[{ts}] "{method} {target} HTTP/{version}" {code}'; /** * @var string Template used to format log messages */ private $template; /** * @param string $template Log message template */ public function __construct(?string $template = self::CLF) { $this->template = $template ?: self::CLF; } /** * Returns a formatted message string. * * @param RequestInterface $request Request that was sent * @param ResponseInterface|null $response Response that was received * @param \Throwable|null $error Exception that was received */ public function format(RequestInterface $request, ?ResponseInterface $response = null, ?\Throwable $error = null): string { $cache = []; /** @var string */ return \preg_replace_callback( '/{\s*([A-Za-z_\-\.0-9]+)\s*}/', function (array $matches) use ($request, $response, $error, &$cache) { if (isset($cache[$matches[1]])) { return $cache[$matches[1]]; } $result = ''; switch ($matches[1]) { case 'request': $result = Psr7\Message::toString($request); break; case 'response': $result = $response ? Psr7\Message::toString($response) : ''; break; case 'req_headers': $result = \trim($request->getMethod() .' '.$request->getRequestTarget()) .' HTTP/'.$request->getProtocolVersion()."\r\n" .$this->headers($request); break; case 'res_headers': $result = $response ? \sprintf( 'HTTP/%s %d %s', $response->getProtocolVersion(), $response->getStatusCode(), $response->getReasonPhrase() )."\r\n".$this->headers($response) : 'NULL'; break; case 'req_body': $result = $request->getBody()->__toString(); break; case 'res_body': if (!$response instanceof ResponseInterface) { $result = 'NULL'; break; } $body = $response->getBody(); if (!$body->isSeekable()) { $result = 'RESPONSE_NOT_LOGGEABLE'; break; } $result = $response->getBody()->__toString(); break; case 'ts': case 'date_iso_8601': $result = \gmdate('c'); break; case 'date_common_log': $result = \date('d/M/Y:H:i:s O'); break; case 'method': $result = $request->getMethod(); break; case 'version': $result = $request->getProtocolVersion(); break; case 'uri': case 'url': $result = $request->getUri()->__toString(); break; case 'target': $result = $request->getRequestTarget(); break; case 'req_version': $result = $request->getProtocolVersion(); break; case 'res_version': $result = $response ? $response->getProtocolVersion() : 'NULL'; break; case 'host': $result = $request->getHeaderLine('Host'); break; case 'hostname': $result = \gethostname(); break; case 'code': $result = $response ? $response->getStatusCode() : 'NULL'; break; case 'phrase': $result = $response ? $response->getReasonPhrase() : 'NULL'; break; case 'error': $result = $error ? $error->getMessage() : 'NULL'; break; default: // handle prefixed dynamic headers if (\strpos($matches[1], 'req_header_') === 0) { $result = $request->getHeaderLine(\substr($matches[1], 11)); } elseif (\strpos($matches[1], 'res_header_') === 0) { $result = $response ? $response->getHeaderLine(\substr($matches[1], 11)) : 'NULL'; } } $cache[$matches[1]] = $result; return $result; }, $this->template ); } /** * Get headers from message as string */ private function headers(MessageInterface $message): string { $result = ''; foreach ($message->getHeaders() as $name => $values) { $result .= $name.': '.\implode(', ', $values)."\r\n"; } return \trim($result); } } ================================================ FILE: lib/Google/vendor/guzzlehttp/guzzle/src/MessageFormatterInterface.php ================================================ withCookieHeader($request); return $handler($request, $options) ->then( static function (ResponseInterface $response) use ($cookieJar, $request): ResponseInterface { $cookieJar->extractCookies($request, $response); return $response; } ); }; }; } /** * Middleware that throws exceptions for 4xx or 5xx responses when the * "http_errors" request option is set to true. * * @param BodySummarizerInterface|null $bodySummarizer The body summarizer to use in exception messages. * * @return callable(callable): callable Returns a function that accepts the next handler. */ public static function httpErrors(?BodySummarizerInterface $bodySummarizer = null): callable { return static function (callable $handler) use ($bodySummarizer): callable { return static function ($request, array $options) use ($handler, $bodySummarizer) { if (empty($options['http_errors'])) { return $handler($request, $options); } return $handler($request, $options)->then( static function (ResponseInterface $response) use ($request, $bodySummarizer) { $code = $response->getStatusCode(); if ($code < 400) { return $response; } throw RequestException::create($request, $response, null, [], $bodySummarizer); } ); }; }; } /** * Middleware that pushes history data to an ArrayAccess container. * * @param array|\ArrayAccess $container Container to hold the history (by reference). * * @return callable(callable): callable Returns a function that accepts the next handler. * * @throws \InvalidArgumentException if container is not an array or ArrayAccess. */ public static function history(&$container): callable { if (!\is_array($container) && !$container instanceof \ArrayAccess) { throw new \InvalidArgumentException('history container must be an array or object implementing ArrayAccess'); } return static function (callable $handler) use (&$container): callable { return static function (RequestInterface $request, array $options) use ($handler, &$container) { return $handler($request, $options)->then( static function ($value) use ($request, &$container, $options) { $container[] = [ 'request' => $request, 'response' => $value, 'error' => null, 'options' => $options, ]; return $value; }, static function ($reason) use ($request, &$container, $options) { $container[] = [ 'request' => $request, 'response' => null, 'error' => $reason, 'options' => $options, ]; return P\Create::rejectionFor($reason); } ); }; }; } /** * Middleware that invokes a callback before and after sending a request. * * The provided listener cannot modify or alter the response. It simply * "taps" into the chain to be notified before returning the promise. The * before listener accepts a request and options array, and the after * listener accepts a request, options array, and response promise. * * @param callable $before Function to invoke before forwarding the request. * @param callable $after Function invoked after forwarding. * * @return callable Returns a function that accepts the next handler. */ public static function tap(?callable $before = null, ?callable $after = null): callable { return static function (callable $handler) use ($before, $after): callable { return static function (RequestInterface $request, array $options) use ($handler, $before, $after) { if ($before) { $before($request, $options); } $response = $handler($request, $options); if ($after) { $after($request, $options, $response); } return $response; }; }; } /** * Middleware that handles request redirects. * * @return callable Returns a function that accepts the next handler. */ public static function redirect(): callable { return static function (callable $handler): RedirectMiddleware { return new RedirectMiddleware($handler); }; } /** * Middleware that retries requests based on the boolean result of * invoking the provided "decider" function. * * If no delay function is provided, a simple implementation of exponential * backoff will be utilized. * * @param callable $decider Function that accepts the number of retries, * a request, [response], and [exception] and * returns true if the request is to be retried. * @param callable $delay Function that accepts the number of retries and * returns the number of milliseconds to delay. * * @return callable Returns a function that accepts the next handler. */ public static function retry(callable $decider, ?callable $delay = null): callable { return static function (callable $handler) use ($decider, $delay): RetryMiddleware { return new RetryMiddleware($decider, $handler, $delay); }; } /** * Middleware that logs requests, responses, and errors using a message * formatter. * * @param LoggerInterface $logger Logs messages. * @param MessageFormatterInterface|MessageFormatter $formatter Formatter used to create message strings. * @param string $logLevel Level at which to log requests. * * @phpstan-param \Psr\Log\LogLevel::* $logLevel Level at which to log requests. * * @return callable Returns a function that accepts the next handler. */ public static function log(LoggerInterface $logger, $formatter, string $logLevel = 'info'): callable { // To be compatible with Guzzle 7.1.x we need to allow users to pass a MessageFormatter if (!$formatter instanceof MessageFormatter && !$formatter instanceof MessageFormatterInterface) { throw new \LogicException(sprintf('Argument 2 to %s::log() must be of type %s', self::class, MessageFormatterInterface::class)); } return static function (callable $handler) use ($logger, $formatter, $logLevel): callable { return static function (RequestInterface $request, array $options = []) use ($handler, $logger, $formatter, $logLevel) { return $handler($request, $options)->then( static function ($response) use ($logger, $request, $formatter, $logLevel): ResponseInterface { $message = $formatter->format($request, $response); $logger->log($logLevel, $message); return $response; }, static function ($reason) use ($logger, $request, $formatter): PromiseInterface { $response = $reason instanceof RequestException ? $reason->getResponse() : null; $message = $formatter->format($request, $response, P\Create::exceptionFor($reason)); $logger->error($message); return P\Create::rejectionFor($reason); } ); }; }; } /** * This middleware adds a default content-type if possible, a default * content-length or transfer-encoding header, and the expect header. */ public static function prepareBody(): callable { return static function (callable $handler): PrepareBodyMiddleware { return new PrepareBodyMiddleware($handler); }; } /** * Middleware that applies a map function to the request before passing to * the next handler. * * @param callable $fn Function that accepts a RequestInterface and returns * a RequestInterface. */ public static function mapRequest(callable $fn): callable { return static function (callable $handler) use ($fn): callable { return static function (RequestInterface $request, array $options) use ($handler, $fn) { return $handler($fn($request), $options); }; }; } /** * Middleware that applies a map function to the resolved promise's * response. * * @param callable $fn Function that accepts a ResponseInterface and * returns a ResponseInterface. */ public static function mapResponse(callable $fn): callable { return static function (callable $handler) use ($fn): callable { return static function (RequestInterface $request, array $options) use ($handler, $fn) { return $handler($request, $options)->then($fn); }; }; } } ================================================ FILE: lib/Google/vendor/guzzlehttp/guzzle/src/Pool.php ================================================ $rfn) { if ($rfn instanceof RequestInterface) { yield $key => $client->sendAsync($rfn, $opts); } elseif (\is_callable($rfn)) { yield $key => $rfn($opts); } else { throw new \InvalidArgumentException('Each value yielded by the iterator must be a Psr7\Http\Message\RequestInterface or a callable that returns a promise that fulfills with a Psr7\Message\Http\ResponseInterface object.'); } } }; $this->each = new EachPromise($requests(), $config); } /** * Get promise */ public function promise(): PromiseInterface { return $this->each->promise(); } /** * Sends multiple requests concurrently and returns an array of responses * and exceptions that uses the same ordering as the provided requests. * * IMPORTANT: This method keeps every request and response in memory, and * as such, is NOT recommended when sending a large number or an * indeterminate number of requests concurrently. * * @param ClientInterface $client Client used to send the requests * @param array|\Iterator $requests Requests to send concurrently. * @param array $options Passes through the options available in * {@see Pool::__construct} * * @return array Returns an array containing the response or an exception * in the same order that the requests were sent. * * @throws \InvalidArgumentException if the event format is incorrect. */ public static function batch(ClientInterface $client, $requests, array $options = []): array { $res = []; self::cmpCallback($options, 'fulfilled', $res); self::cmpCallback($options, 'rejected', $res); $pool = new static($client, $requests, $options); $pool->promise()->wait(); \ksort($res); return $res; } /** * Execute callback(s) */ private static function cmpCallback(array &$options, string $name, array &$results): void { if (!isset($options[$name])) { $options[$name] = static function ($v, $k) use (&$results) { $results[$k] = $v; }; } else { $currentFn = $options[$name]; $options[$name] = static function ($v, $k) use (&$results, $currentFn) { $currentFn($v, $k); $results[$k] = $v; }; } } } ================================================ FILE: lib/Google/vendor/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php ================================================ nextHandler = $nextHandler; } public function __invoke(RequestInterface $request, array $options): PromiseInterface { $fn = $this->nextHandler; // Don't do anything if the request has no body. if ($request->getBody()->getSize() === 0) { return $fn($request, $options); } $modify = []; // Add a default content-type if possible. if (!$request->hasHeader('Content-Type')) { if ($uri = $request->getBody()->getMetadata('uri')) { if (is_string($uri) && $type = Psr7\MimeType::fromFilename($uri)) { $modify['set_headers']['Content-Type'] = $type; } } } // Add a default content-length or transfer-encoding header. if (!$request->hasHeader('Content-Length') && !$request->hasHeader('Transfer-Encoding') ) { $size = $request->getBody()->getSize(); if ($size !== null) { $modify['set_headers']['Content-Length'] = $size; } else { $modify['set_headers']['Transfer-Encoding'] = 'chunked'; } } // Add the expect header if needed. $this->addExpectHeader($request, $options, $modify); return $fn(Psr7\Utils::modifyRequest($request, $modify), $options); } /** * Add expect header */ private function addExpectHeader(RequestInterface $request, array $options, array &$modify): void { // Determine if the Expect header should be used if ($request->hasHeader('Expect')) { return; } $expect = $options['expect'] ?? null; // Return if disabled or using HTTP/1.0 if ($expect === false || $request->getProtocolVersion() === '1.0') { return; } // The expect header is unconditionally enabled if ($expect === true) { $modify['set_headers']['Expect'] = '100-Continue'; return; } // By default, send the expect header when the payload is > 1mb if ($expect === null) { $expect = 1048576; } // Always add if the body cannot be rewound, the size cannot be // determined, or the size is greater than the cutoff threshold $body = $request->getBody(); $size = $body->getSize(); if ($size === null || $size >= (int) $expect || !$body->isSeekable()) { $modify['set_headers']['Expect'] = '100-Continue'; } } } ================================================ FILE: lib/Google/vendor/guzzlehttp/guzzle/src/RedirectMiddleware.php ================================================ 5, 'protocols' => ['http', 'https'], 'strict' => false, 'referer' => false, 'track_redirects' => false, ]; /** * @var callable(RequestInterface, array): PromiseInterface */ private $nextHandler; /** * @param callable(RequestInterface, array): PromiseInterface $nextHandler Next handler to invoke. */ public function __construct(callable $nextHandler) { $this->nextHandler = $nextHandler; } public function __invoke(RequestInterface $request, array $options): PromiseInterface { $fn = $this->nextHandler; if (empty($options['allow_redirects'])) { return $fn($request, $options); } if ($options['allow_redirects'] === true) { $options['allow_redirects'] = self::$defaultSettings; } elseif (!\is_array($options['allow_redirects'])) { throw new \InvalidArgumentException('allow_redirects must be true, false, or array'); } else { // Merge the default settings with the provided settings $options['allow_redirects'] += self::$defaultSettings; } if (empty($options['allow_redirects']['max'])) { return $fn($request, $options); } return $fn($request, $options) ->then(function (ResponseInterface $response) use ($request, $options) { return $this->checkRedirect($request, $options, $response); }); } /** * @return ResponseInterface|PromiseInterface */ public function checkRedirect(RequestInterface $request, array $options, ResponseInterface $response) { if (\strpos((string) $response->getStatusCode(), '3') !== 0 || !$response->hasHeader('Location') ) { return $response; } $this->guardMax($request, $response, $options); $nextRequest = $this->modifyRequest($request, $options, $response); // If authorization is handled by curl, unset it if URI is cross-origin. if (Psr7\UriComparator::isCrossOrigin($request->getUri(), $nextRequest->getUri()) && defined('\CURLOPT_HTTPAUTH')) { unset( $options['curl'][\CURLOPT_HTTPAUTH], $options['curl'][\CURLOPT_USERPWD] ); } if (isset($options['allow_redirects']['on_redirect'])) { ($options['allow_redirects']['on_redirect'])( $request, $response, $nextRequest->getUri() ); } $promise = $this($nextRequest, $options); // Add headers to be able to track history of redirects. if (!empty($options['allow_redirects']['track_redirects'])) { return $this->withTracking( $promise, (string) $nextRequest->getUri(), $response->getStatusCode() ); } return $promise; } /** * Enable tracking on promise. */ private function withTracking(PromiseInterface $promise, string $uri, int $statusCode): PromiseInterface { return $promise->then( static function (ResponseInterface $response) use ($uri, $statusCode) { // Note that we are pushing to the front of the list as this // would be an earlier response than what is currently present // in the history header. $historyHeader = $response->getHeader(self::HISTORY_HEADER); $statusHeader = $response->getHeader(self::STATUS_HISTORY_HEADER); \array_unshift($historyHeader, $uri); \array_unshift($statusHeader, (string) $statusCode); return $response->withHeader(self::HISTORY_HEADER, $historyHeader) ->withHeader(self::STATUS_HISTORY_HEADER, $statusHeader); } ); } /** * Check for too many redirects. * * @throws TooManyRedirectsException Too many redirects. */ private function guardMax(RequestInterface $request, ResponseInterface $response, array &$options): void { $current = $options['__redirect_count'] ?? 0; $options['__redirect_count'] = $current + 1; $max = $options['allow_redirects']['max']; if ($options['__redirect_count'] > $max) { throw new TooManyRedirectsException("Will not follow more than {$max} redirects", $request, $response); } } public function modifyRequest(RequestInterface $request, array $options, ResponseInterface $response): RequestInterface { // Request modifications to apply. $modify = []; $protocols = $options['allow_redirects']['protocols']; // Use a GET request if this is an entity enclosing request and we are // not forcing RFC compliance, but rather emulating what all browsers // would do. $statusCode = $response->getStatusCode(); if ($statusCode == 303 || ($statusCode <= 302 && !$options['allow_redirects']['strict']) ) { $safeMethods = ['GET', 'HEAD', 'OPTIONS']; $requestMethod = $request->getMethod(); $modify['method'] = in_array($requestMethod, $safeMethods) ? $requestMethod : 'GET'; $modify['body'] = ''; } $uri = self::redirectUri($request, $response, $protocols); if (isset($options['idn_conversion']) && ($options['idn_conversion'] !== false)) { $idnOptions = ($options['idn_conversion'] === true) ? \IDNA_DEFAULT : $options['idn_conversion']; $uri = Utils::idnUriConvert($uri, $idnOptions); } $modify['uri'] = $uri; Psr7\Message::rewindBody($request); // Add the Referer header if it is told to do so and only // add the header if we are not redirecting from https to http. if ($options['allow_redirects']['referer'] && $modify['uri']->getScheme() === $request->getUri()->getScheme() ) { $uri = $request->getUri()->withUserInfo(''); $modify['set_headers']['Referer'] = (string) $uri; } else { $modify['remove_headers'][] = 'Referer'; } // Remove Authorization and Cookie headers if URI is cross-origin. if (Psr7\UriComparator::isCrossOrigin($request->getUri(), $modify['uri'])) { $modify['remove_headers'][] = 'Authorization'; $modify['remove_headers'][] = 'Cookie'; } return Psr7\Utils::modifyRequest($request, $modify); } /** * Set the appropriate URL on the request based on the location header. */ private static function redirectUri( RequestInterface $request, ResponseInterface $response, array $protocols ): UriInterface { $location = Psr7\UriResolver::resolve( $request->getUri(), new Psr7\Uri($response->getHeaderLine('Location')) ); // Ensure that the redirect URI is allowed based on the protocols. if (!\in_array($location->getScheme(), $protocols)) { throw new BadResponseException(\sprintf('Redirect URI, %s, does not use one of the allowed redirect protocols: %s', $location, \implode(', ', $protocols)), $request, $response); } return $location; } } ================================================ FILE: lib/Google/vendor/guzzlehttp/guzzle/src/RequestOptions.php ================================================ decider = $decider; $this->nextHandler = $nextHandler; $this->delay = $delay ?: __CLASS__.'::exponentialDelay'; } /** * Default exponential backoff delay function. * * @return int milliseconds. */ public static function exponentialDelay(int $retries): int { return (int) 2 ** ($retries - 1) * 1000; } public function __invoke(RequestInterface $request, array $options): PromiseInterface { if (!isset($options['retries'])) { $options['retries'] = 0; } $fn = $this->nextHandler; return $fn($request, $options) ->then( $this->onFulfilled($request, $options), $this->onRejected($request, $options) ); } /** * Execute fulfilled closure */ private function onFulfilled(RequestInterface $request, array $options): callable { return function ($value) use ($request, $options) { if (!($this->decider)( $options['retries'], $request, $value, null )) { return $value; } return $this->doRetry($request, $options, $value); }; } /** * Execute rejected closure */ private function onRejected(RequestInterface $req, array $options): callable { return function ($reason) use ($req, $options) { if (!($this->decider)( $options['retries'], $req, null, $reason )) { return P\Create::rejectionFor($reason); } return $this->doRetry($req, $options); }; } private function doRetry(RequestInterface $request, array $options, ?ResponseInterface $response = null): PromiseInterface { $options['delay'] = ($this->delay)(++$options['retries'], $response, $request); return $this($request, $options); } } ================================================ FILE: lib/Google/vendor/guzzlehttp/guzzle/src/TransferStats.php ================================================ request = $request; $this->response = $response; $this->transferTime = $transferTime; $this->handlerErrorData = $handlerErrorData; $this->handlerStats = $handlerStats; } public function getRequest(): RequestInterface { return $this->request; } /** * Returns the response that was received (if any). */ public function getResponse(): ?ResponseInterface { return $this->response; } /** * Returns true if a response was received. */ public function hasResponse(): bool { return $this->response !== null; } /** * Gets handler specific error data. * * This might be an exception, a integer representing an error code, or * anything else. Relying on this value assumes that you know what handler * you are using. * * @return mixed */ public function getHandlerErrorData() { return $this->handlerErrorData; } /** * Get the effective URI the request was sent to. */ public function getEffectiveUri(): UriInterface { return $this->request->getUri(); } /** * Get the estimated time the request was being transferred by the handler. * * @return float|null Time in seconds. */ public function getTransferTime(): ?float { return $this->transferTime; } /** * Gets an array of all of the handler specific transfer data. */ public function getHandlerStats(): array { return $this->handlerStats; } /** * Get a specific handler statistic from the handler by name. * * @param string $stat Handler specific transfer stat to retrieve. * * @return mixed|null */ public function getHandlerStat(string $stat) { return $this->handlerStats[$stat] ?? null; } } ================================================ FILE: lib/Google/vendor/guzzlehttp/guzzle/src/Utils.php ================================================ = 0) { if (\function_exists('curl_multi_exec') && \function_exists('curl_exec')) { $handler = Proxy::wrapSync(new CurlMultiHandler(), new CurlHandler()); } elseif (\function_exists('curl_exec')) { $handler = new CurlHandler(); } elseif (\function_exists('curl_multi_exec')) { $handler = new CurlMultiHandler(); } } if (\ini_get('allow_url_fopen')) { $handler = $handler ? Proxy::wrapStreaming($handler, new StreamHandler()) : new StreamHandler(); } elseif (!$handler) { throw new \RuntimeException('GuzzleHttp requires cURL, the allow_url_fopen ini setting, or a custom HTTP handler.'); } return $handler; } /** * Get the default User-Agent string to use with Guzzle. */ public static function defaultUserAgent(): string { return sprintf('GuzzleHttp/%d', ClientInterface::MAJOR_VERSION); } /** * Returns the default cacert bundle for the current system. * * First, the openssl.cafile and curl.cainfo php.ini settings are checked. * If those settings are not configured, then the common locations for * bundles found on Red Hat, CentOS, Fedora, Ubuntu, Debian, FreeBSD, OS X * and Windows are checked. If any of these file locations are found on * disk, they will be utilized. * * Note: the result of this function is cached for subsequent calls. * * @throws \RuntimeException if no bundle can be found. * * @deprecated Utils::defaultCaBundle will be removed in guzzlehttp/guzzle:8.0. This method is not needed in PHP 5.6+. */ public static function defaultCaBundle(): string { static $cached = null; static $cafiles = [ // Red Hat, CentOS, Fedora (provided by the ca-certificates package) '/etc/pki/tls/certs/ca-bundle.crt', // Ubuntu, Debian (provided by the ca-certificates package) '/etc/ssl/certs/ca-certificates.crt', // FreeBSD (provided by the ca_root_nss package) '/usr/local/share/certs/ca-root-nss.crt', // SLES 12 (provided by the ca-certificates package) '/var/lib/ca-certificates/ca-bundle.pem', // OS X provided by homebrew (using the default path) '/usr/local/etc/openssl/cert.pem', // Google app engine '/etc/ca-certificates.crt', // Windows? 'C:\\windows\\system32\\curl-ca-bundle.crt', 'C:\\windows\\curl-ca-bundle.crt', ]; if ($cached) { return $cached; } if ($ca = \ini_get('openssl.cafile')) { return $cached = $ca; } if ($ca = \ini_get('curl.cainfo')) { return $cached = $ca; } foreach ($cafiles as $filename) { if (\file_exists($filename)) { return $cached = $filename; } } throw new \RuntimeException( <<< EOT No system CA bundle could be found in any of the the common system locations. PHP versions earlier than 5.6 are not properly configured to use the system's CA bundle by default. In order to verify peer certificates, you will need to supply the path on disk to a certificate bundle to the 'verify' request option: https://docs.guzzlephp.org/en/latest/request-options.html#verify. If you do not need a specific certificate bundle, then Mozilla provides a commonly used CA bundle which can be downloaded here (provided by the maintainer of cURL): https://curl.haxx.se/ca/cacert.pem. Once you have a CA bundle available on disk, you can set the 'openssl.cafile' PHP ini setting to point to the path to the file, allowing you to omit the 'verify' request option. See https://curl.haxx.se/docs/sslcerts.html for more information. EOT ); } /** * Creates an associative array of lowercase header names to the actual * header casing. */ public static function normalizeHeaderKeys(array $headers): array { $result = []; foreach (\array_keys($headers) as $key) { $result[\strtolower($key)] = $key; } return $result; } /** * Returns true if the provided host matches any of the no proxy areas. * * This method will strip a port from the host if it is present. Each pattern * can be matched with an exact match (e.g., "foo.com" == "foo.com") or a * partial match: (e.g., "foo.com" == "baz.foo.com" and ".foo.com" == * "baz.foo.com", but ".foo.com" != "foo.com"). * * Areas are matched in the following cases: * 1. "*" (without quotes) always matches any hosts. * 2. An exact match. * 3. The area starts with "." and the area is the last part of the host. e.g. * '.mit.edu' will match any host that ends with '.mit.edu'. * * @param string $host Host to check against the patterns. * @param string[] $noProxyArray An array of host patterns. * * @throws InvalidArgumentException */ public static function isHostInNoProxy(string $host, array $noProxyArray): bool { if (\strlen($host) === 0) { throw new InvalidArgumentException('Empty host provided'); } // Strip port if present. [$host] = \explode(':', $host, 2); foreach ($noProxyArray as $area) { // Always match on wildcards. if ($area === '*') { return true; } if (empty($area)) { // Don't match on empty values. continue; } if ($area === $host) { // Exact matches. return true; } // Special match if the area when prefixed with ".". Remove any // existing leading "." and add a new leading ".". $area = '.'.\ltrim($area, '.'); if (\substr($host, -\strlen($area)) === $area) { return true; } } return false; } /** * Wrapper for json_decode that throws when an error occurs. * * @param string $json JSON data to parse * @param bool $assoc When true, returned objects will be converted * into associative arrays. * @param int $depth User specified recursion depth. * @param int $options Bitmask of JSON decode options. * * @return object|array|string|int|float|bool|null * * @throws InvalidArgumentException if the JSON cannot be decoded. * * @see https://www.php.net/manual/en/function.json-decode.php */ public static function jsonDecode(string $json, bool $assoc = false, int $depth = 512, int $options = 0) { $data = \json_decode($json, $assoc, $depth, $options); if (\JSON_ERROR_NONE !== \json_last_error()) { throw new InvalidArgumentException('json_decode error: '.\json_last_error_msg()); } return $data; } /** * Wrapper for JSON encoding that throws when an error occurs. * * @param mixed $value The value being encoded * @param int $options JSON encode option bitmask * @param int $depth Set the maximum depth. Must be greater than zero. * * @throws InvalidArgumentException if the JSON cannot be encoded. * * @see https://www.php.net/manual/en/function.json-encode.php */ public static function jsonEncode($value, int $options = 0, int $depth = 512): string { $json = \json_encode($value, $options, $depth); if (\JSON_ERROR_NONE !== \json_last_error()) { throw new InvalidArgumentException('json_encode error: '.\json_last_error_msg()); } /** @var string */ return $json; } /** * Wrapper for the hrtime() or microtime() functions * (depending on the PHP version, one of the two is used) * * @return float UNIX timestamp * * @internal */ public static function currentTime(): float { return (float) \function_exists('hrtime') ? \hrtime(true) / 1e9 : \microtime(true); } /** * @throws InvalidArgumentException * * @internal */ public static function idnUriConvert(UriInterface $uri, int $options = 0): UriInterface { if ($uri->getHost()) { $asciiHost = self::idnToAsci($uri->getHost(), $options, $info); if ($asciiHost === false) { $errorBitSet = $info['errors'] ?? 0; $errorConstants = array_filter(array_keys(get_defined_constants()), static function (string $name): bool { return substr($name, 0, 11) === 'IDNA_ERROR_'; }); $errors = []; foreach ($errorConstants as $errorConstant) { if ($errorBitSet & constant($errorConstant)) { $errors[] = $errorConstant; } } $errorMessage = 'IDN conversion failed'; if ($errors) { $errorMessage .= ' (errors: '.implode(', ', $errors).')'; } throw new InvalidArgumentException($errorMessage); } if ($uri->getHost() !== $asciiHost) { // Replace URI only if the ASCII version is different $uri = $uri->withHost($asciiHost); } } return $uri; } /** * @internal */ public static function getenv(string $name): ?string { if (isset($_SERVER[$name])) { return (string) $_SERVER[$name]; } if (\PHP_SAPI === 'cli' && ($value = \getenv($name)) !== false && $value !== null) { return (string) $value; } return null; } /** * @return string|false */ private static function idnToAsci(string $domain, int $options, ?array &$info = []) { if (\function_exists('idn_to_ascii') && \defined('INTL_IDNA_VARIANT_UTS46')) { return \idn_to_ascii($domain, $options, \INTL_IDNA_VARIANT_UTS46, $info); } throw new \Error('ext-idn or symfony/polyfill-intl-idn not loaded or too old'); } } ================================================ FILE: lib/Google/vendor/guzzlehttp/guzzle/src/functions.php ================================================ Copyright (c) 2015 Graham Campbell Copyright (c) 2017 Tobias Schultze Copyright (c) 2020 Tobias Nyholm 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. ================================================ FILE: lib/Google/vendor/guzzlehttp/promises/README.md ================================================ # Guzzle Promises [Promises/A+](https://promisesaplus.com/) implementation that handles promise chaining and resolution iteratively, allowing for "infinite" promise chaining while keeping the stack size constant. Read [this blog post](https://blog.domenic.me/youre-missing-the-point-of-promises/) for a general introduction to promises. - [Features](#features) - [Quick start](#quick-start) - [Synchronous wait](#synchronous-wait) - [Cancellation](#cancellation) - [API](#api) - [Promise](#promise) - [FulfilledPromise](#fulfilledpromise) - [RejectedPromise](#rejectedpromise) - [Promise interop](#promise-interop) - [Implementation notes](#implementation-notes) ## Features - [Promises/A+](https://promisesaplus.com/) implementation. - Promise resolution and chaining is handled iteratively, allowing for "infinite" promise chaining. - Promises have a synchronous `wait` method. - Promises can be cancelled. - Works with any object that has a `then` function. - C# style async/await coroutine promises using `GuzzleHttp\Promise\Coroutine::of()`. ## Installation ```shell composer require guzzlehttp/promises ``` ## Version Guidance | Version | Status | PHP Version | |---------|---------------------|--------------| | 1.x | Security fixes only | >=5.5,<8.3 | | 2.x | Latest | >=7.2.5,<8.6 | ## Quick Start A *promise* represents the eventual result of an asynchronous operation. The primary way of interacting with a promise is through its `then` method, which registers callbacks to receive either a promise's eventual value or the reason why the promise cannot be fulfilled. ### Callbacks Callbacks are registered with the `then` method by providing an optional `$onFulfilled` followed by an optional `$onRejected` function. ```php use GuzzleHttp\Promise\Promise; $promise = new Promise(); $promise->then( // $onFulfilled function ($value) { echo 'The promise was fulfilled.'; }, // $onRejected function ($reason) { echo 'The promise was rejected.'; } ); ``` *Resolving* a promise means that you either fulfill a promise with a *value* or reject a promise with a *reason*. Resolving a promise triggers callbacks registered with the promise's `then` method. These callbacks are triggered only once and in the order in which they were added. ### Resolving a Promise Promises are fulfilled using the `resolve($value)` method. Resolving a promise with any value other than a `GuzzleHttp\Promise\RejectedPromise` will trigger all of the onFulfilled callbacks (resolving a promise with a rejected promise will reject the promise and trigger the `$onRejected` callbacks). ```php use GuzzleHttp\Promise\Promise; $promise = new Promise(); $promise ->then(function ($value) { // Return a value and don't break the chain return "Hello, " . $value; }) // This then is executed after the first then and receives the value // returned from the first then. ->then(function ($value) { echo $value; }); // Resolving the promise triggers the $onFulfilled callbacks and outputs // "Hello, reader." $promise->resolve('reader.'); ``` ### Promise Forwarding Promises can be chained one after the other. Each then in the chain is a new promise. The return value of a promise is what's forwarded to the next promise in the chain. Returning a promise in a `then` callback will cause the subsequent promises in the chain to only be fulfilled when the returned promise has been fulfilled. The next promise in the chain will be invoked with the resolved value of the promise. ```php use GuzzleHttp\Promise\Promise; $promise = new Promise(); $nextPromise = new Promise(); $promise ->then(function ($value) use ($nextPromise) { echo $value; return $nextPromise; }) ->then(function ($value) { echo $value; }); // Triggers the first callback and outputs "A" $promise->resolve('A'); // Triggers the second callback and outputs "B" $nextPromise->resolve('B'); ``` ### Promise Rejection When a promise is rejected, the `$onRejected` callbacks are invoked with the rejection reason. ```php use GuzzleHttp\Promise\Promise; $promise = new Promise(); $promise->then(null, function ($reason) { echo $reason; }); $promise->reject('Error!'); // Outputs "Error!" ``` ### Rejection Forwarding If an exception is thrown in an `$onRejected` callback, subsequent `$onRejected` callbacks are invoked with the thrown exception as the reason. ```php use GuzzleHttp\Promise\Promise; $promise = new Promise(); $promise->then(null, function ($reason) { throw new Exception($reason); })->then(null, function ($reason) { assert($reason->getMessage() === 'Error!'); }); $promise->reject('Error!'); ``` You can also forward a rejection down the promise chain by returning a `GuzzleHttp\Promise\RejectedPromise` in either an `$onFulfilled` or `$onRejected` callback. ```php use GuzzleHttp\Promise\Promise; use GuzzleHttp\Promise\RejectedPromise; $promise = new Promise(); $promise->then(null, function ($reason) { return new RejectedPromise($reason); })->then(null, function ($reason) { assert($reason === 'Error!'); }); $promise->reject('Error!'); ``` If an exception is not thrown in a `$onRejected` callback and the callback does not return a rejected promise, downstream `$onFulfilled` callbacks are invoked using the value returned from the `$onRejected` callback. ```php use GuzzleHttp\Promise\Promise; $promise = new Promise(); $promise ->then(null, function ($reason) { return "It's ok"; }) ->then(function ($value) { assert($value === "It's ok"); }); $promise->reject('Error!'); ``` ## Synchronous Wait You can synchronously force promises to complete using a promise's `wait` method. When creating a promise, you can provide a wait function that is used to synchronously force a promise to complete. When a wait function is invoked it is expected to deliver a value to the promise or reject the promise. If the wait function does not deliver a value, then an exception is thrown. The wait function provided to a promise constructor is invoked when the `wait` function of the promise is called. ```php $promise = new Promise(function () use (&$promise) { $promise->resolve('foo'); }); // Calling wait will return the value of the promise. echo $promise->wait(); // outputs "foo" ``` If an exception is encountered while invoking the wait function of a promise, the promise is rejected with the exception and the exception is thrown. ```php $promise = new Promise(function () use (&$promise) { throw new Exception('foo'); }); $promise->wait(); // throws the exception. ``` Calling `wait` on a promise that has been fulfilled will not trigger the wait function. It will simply return the previously resolved value. ```php $promise = new Promise(function () { die('this is not called!'); }); $promise->resolve('foo'); echo $promise->wait(); // outputs "foo" ``` Calling `wait` on a promise that has been rejected will throw an exception. If the rejection reason is an instance of `\Exception` the reason is thrown. Otherwise, a `GuzzleHttp\Promise\RejectionException` is thrown and the reason can be obtained by calling the `getReason` method of the exception. ```php $promise = new Promise(); $promise->reject('foo'); $promise->wait(); ``` > PHP Fatal error: Uncaught exception 'GuzzleHttp\Promise\RejectionException' with message 'The promise was rejected with value: foo' ### Unwrapping a Promise When synchronously waiting on a promise, you are joining the state of the promise into the current state of execution (i.e., return the value of the promise if it was fulfilled or throw an exception if it was rejected). This is called "unwrapping" the promise. Waiting on a promise will by default unwrap the promise state. You can force a promise to resolve and *not* unwrap the state of the promise by passing `false` to the first argument of the `wait` function: ```php $promise = new Promise(); $promise->reject('foo'); // This will not throw an exception. It simply ensures the promise has // been resolved. $promise->wait(false); ``` When unwrapping a promise, the resolved value of the promise will be waited upon until the unwrapped value is not a promise. This means that if you resolve promise A with a promise B and unwrap promise A, the value returned by the wait function will be the value delivered to promise B. **Note**: when you do not unwrap the promise, no value is returned. ## Cancellation You can cancel a promise that has not yet been fulfilled using the `cancel()` method of a promise. When creating a promise you can provide an optional cancel function that when invoked cancels the action of computing a resolution of the promise. ## API ### Promise When creating a promise object, you can provide an optional `$waitFn` and `$cancelFn`. `$waitFn` is a function that is invoked with no arguments and is expected to resolve the promise. `$cancelFn` is a function with no arguments that is expected to cancel the computation of a promise. It is invoked when the `cancel()` method of a promise is called. ```php use GuzzleHttp\Promise\Promise; $promise = new Promise( function () use (&$promise) { $promise->resolve('waited'); }, function () { // do something that will cancel the promise computation (e.g., close // a socket, cancel a database query, etc...) } ); assert('waited' === $promise->wait()); ``` A promise has the following methods: - `then(callable $onFulfilled, callable $onRejected) : PromiseInterface` Appends fulfillment and rejection handlers to the promise, and returns a new promise resolving to the return value of the called handler. - `otherwise(callable $onRejected) : PromiseInterface` Appends a rejection handler callback to the promise, and returns a new promise resolving to the return value of the callback if it is called, or to its original fulfillment value if the promise is instead fulfilled. - `wait($unwrap = true) : mixed` Synchronously waits on the promise to complete. `$unwrap` controls whether or not the value of the promise is returned for a fulfilled promise or if an exception is thrown if the promise is rejected. This is set to `true` by default. - `cancel()` Attempts to cancel the promise if possible. The promise being cancelled and the parent most ancestor that has not yet been resolved will also be cancelled. Any promises waiting on the cancelled promise to resolve will also be cancelled. - `getState() : string` Returns the state of the promise. One of `pending`, `fulfilled`, or `rejected`. - `resolve($value)` Fulfills the promise with the given `$value`. - `reject($reason)` Rejects the promise with the given `$reason`. ### FulfilledPromise A fulfilled promise can be created to represent a promise that has been fulfilled. ```php use GuzzleHttp\Promise\FulfilledPromise; $promise = new FulfilledPromise('value'); // Fulfilled callbacks are immediately invoked. $promise->then(function ($value) { echo $value; }); ``` ### RejectedPromise A rejected promise can be created to represent a promise that has been rejected. ```php use GuzzleHttp\Promise\RejectedPromise; $promise = new RejectedPromise('Error'); // Rejected callbacks are immediately invoked. $promise->then(null, function ($reason) { echo $reason; }); ``` ## Promise Interoperability This library works with foreign promises that have a `then` method. This means you can use Guzzle promises with [React promises](https://github.com/reactphp/promise) for example. When a foreign promise is returned inside of a then method callback, promise resolution will occur recursively. ```php // Create a React promise $deferred = new React\Promise\Deferred(); $reactPromise = $deferred->promise(); // Create a Guzzle promise that is fulfilled with a React promise. $guzzlePromise = new GuzzleHttp\Promise\Promise(); $guzzlePromise->then(function ($value) use ($reactPromise) { // Do something something with the value... // Return the React promise return $reactPromise; }); ``` Please note that wait and cancel chaining is no longer possible when forwarding a foreign promise. You will need to wrap a third-party promise with a Guzzle promise in order to utilize wait and cancel functions with foreign promises. ### Event Loop Integration In order to keep the stack size constant, Guzzle promises are resolved asynchronously using a task queue. When waiting on promises synchronously, the task queue will be automatically run to ensure that the blocking promise and any forwarded promises are resolved. When using promises asynchronously in an event loop, you will need to run the task queue on each tick of the loop. If you do not run the task queue, then promises will not be resolved. You can run the task queue using the `run()` method of the global task queue instance. ```php // Get the global task queue $queue = GuzzleHttp\Promise\Utils::queue(); $queue->run(); ``` For example, you could use Guzzle promises with React using a periodic timer: ```php $loop = React\EventLoop\Factory::create(); $loop->addPeriodicTimer(0, [$queue, 'run']); ``` ## Implementation Notes ### Promise Resolution and Chaining is Handled Iteratively By shuffling pending handlers from one owner to another, promises are resolved iteratively, allowing for "infinite" then chaining. ```php then(function ($v) { // The stack size remains constant (a good thing) echo xdebug_get_stack_depth() . ', '; return $v + 1; }); } $parent->resolve(0); var_dump($p->wait()); // int(1000) ``` When a promise is fulfilled or rejected with a non-promise value, the promise then takes ownership of the handlers of each child promise and delivers values down the chain without using recursion. When a promise is resolved with another promise, the original promise transfers all of its pending handlers to the new promise. When the new promise is eventually resolved, all of the pending handlers are delivered the forwarded value. ### A Promise is the Deferred Some promise libraries implement promises using a deferred object to represent a computation and a promise object to represent the delivery of the result of the computation. This is a nice separation of computation and delivery because consumers of the promise cannot modify the value that will be eventually delivered. One side effect of being able to implement promise resolution and chaining iteratively is that you need to be able for one promise to reach into the state of another promise to shuffle around ownership of handlers. In order to achieve this without making the handlers of a promise publicly mutable, a promise is also the deferred value, allowing promises of the same parent class to reach into and modify the private properties of promises of the same type. While this does allow consumers of the value to modify the resolution or rejection of the deferred, it is a small price to pay for keeping the stack size constant. ```php $promise = new Promise(); $promise->then(function ($value) { echo $value; }); // The promise is the deferred value, so you can deliver a value to it. $promise->resolve('foo'); // prints "foo" ``` ## Upgrading from Function API A static API was first introduced in 1.4.0, in order to mitigate problems with functions conflicting between global and local copies of the package. The function API was removed in 2.0.0. A migration table has been provided here for your convenience: | Original Function | Replacement Method | |----------------|----------------| | `queue` | `Utils::queue` | | `task` | `Utils::task` | | `promise_for` | `Create::promiseFor` | | `rejection_for` | `Create::rejectionFor` | | `exception_for` | `Create::exceptionFor` | | `iter_for` | `Create::iterFor` | | `inspect` | `Utils::inspect` | | `inspect_all` | `Utils::inspectAll` | | `unwrap` | `Utils::unwrap` | | `all` | `Utils::all` | | `some` | `Utils::some` | | `any` | `Utils::any` | | `settle` | `Utils::settle` | | `each` | `Each::of` | | `each_limit` | `Each::ofLimit` | | `each_limit_all` | `Each::ofLimitAll` | | `!is_fulfilled` | `Is::pending` | | `is_fulfilled` | `Is::fulfilled` | | `is_rejected` | `Is::rejected` | | `is_settled` | `Is::settled` | | `coroutine` | `Coroutine::of` | ## Security If you discover a security vulnerability within this package, please send an email to security@tidelift.com. All security vulnerabilities will be promptly addressed. Please do not disclose security-related issues publicly until a fix has been announced. Please see [Security Policy](https://github.com/guzzle/promises/security/policy) for more information. ## License Guzzle is made available under the MIT License (MIT). Please see [License File](LICENSE) for more information. ## For Enterprise Available as part of the Tidelift Subscription The maintainers of Guzzle and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/packagist-guzzlehttp-promises?utm_source=packagist-guzzlehttp-promises&utm_medium=referral&utm_campaign=enterprise&utm_term=repo) ================================================ FILE: lib/Google/vendor/guzzlehttp/promises/composer.json ================================================ { "name": "guzzlehttp/promises", "description": "Guzzle promises library", "keywords": ["promise"], "license": "MIT", "authors": [ { "name": "Graham Campbell", "email": "hello@gjcampbell.co.uk", "homepage": "https://github.com/GrahamCampbell" }, { "name": "Michael Dowling", "email": "mtdowling@gmail.com", "homepage": "https://github.com/mtdowling" }, { "name": "Tobias Nyholm", "email": "tobias.nyholm@gmail.com", "homepage": "https://github.com/Nyholm" }, { "name": "Tobias Schultze", "email": "webmaster@tubo-world.de", "homepage": "https://github.com/Tobion" } ], "require": { "php": "^7.2.5 || ^8.0" }, "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", "phpunit/phpunit": "^8.5.44 || ^9.6.25" }, "autoload": { "psr-4": { "GuzzleHttp\\Promise\\": "src/" } }, "autoload-dev": { "psr-4": { "GuzzleHttp\\Promise\\Tests\\": "tests/" } }, "extra": { "bamarni-bin": { "bin-links": true, "forward-command": false } }, "config": { "allow-plugins": { "bamarni/composer-bin-plugin": true }, "preferred-install": "dist", "sort-packages": true } } ================================================ FILE: lib/Google/vendor/guzzlehttp/promises/src/AggregateException.php ================================================ then(function ($v) { echo $v; }); * * @param callable $generatorFn Generator function to wrap into a promise. * * @return Promise * * @see https://github.com/petkaantonov/bluebird/blob/master/API.md#generators inspiration */ final class Coroutine implements PromiseInterface { /** * @var PromiseInterface|null */ private $currentPromise; /** * @var Generator */ private $generator; /** * @var Promise */ private $result; public function __construct(callable $generatorFn) { $this->generator = $generatorFn(); $this->result = new Promise(function (): void { while (isset($this->currentPromise)) { $this->currentPromise->wait(); } }); try { $this->nextCoroutine($this->generator->current()); } catch (Throwable $throwable) { $this->result->reject($throwable); } } /** * Create a new coroutine. */ public static function of(callable $generatorFn): self { return new self($generatorFn); } public function then( ?callable $onFulfilled = null, ?callable $onRejected = null ): PromiseInterface { return $this->result->then($onFulfilled, $onRejected); } public function otherwise(callable $onRejected): PromiseInterface { return $this->result->otherwise($onRejected); } public function wait(bool $unwrap = true) { return $this->result->wait($unwrap); } public function getState(): string { return $this->result->getState(); } public function resolve($value): void { $this->result->resolve($value); } public function reject($reason): void { $this->result->reject($reason); } public function cancel(): void { $this->currentPromise->cancel(); $this->result->cancel(); } private function nextCoroutine($yielded): void { $this->currentPromise = Create::promiseFor($yielded) ->then([$this, '_handleSuccess'], [$this, '_handleFailure']); } /** * @internal */ public function _handleSuccess($value): void { unset($this->currentPromise); try { $next = $this->generator->send($value); if ($this->generator->valid()) { $this->nextCoroutine($next); } else { $this->result->resolve($value); } } catch (Throwable $throwable) { $this->result->reject($throwable); } } /** * @internal */ public function _handleFailure($reason): void { unset($this->currentPromise); try { $nextYield = $this->generator->throw(Create::exceptionFor($reason)); // The throw was caught, so keep iterating on the coroutine $this->nextCoroutine($nextYield); } catch (Throwable $throwable) { $this->result->reject($throwable); } } } ================================================ FILE: lib/Google/vendor/guzzlehttp/promises/src/Create.php ================================================ then([$promise, 'resolve'], [$promise, 'reject']); return $promise; } return new FulfilledPromise($value); } /** * Creates a rejected promise for a reason if the reason is not a promise. * If the provided reason is a promise, then it is returned as-is. * * @param mixed $reason Promise or reason. */ public static function rejectionFor($reason): PromiseInterface { if ($reason instanceof PromiseInterface) { return $reason; } return new RejectedPromise($reason); } /** * Create an exception for a rejected promise value. * * @param mixed $reason */ public static function exceptionFor($reason): \Throwable { if ($reason instanceof \Throwable) { return $reason; } return new RejectionException($reason); } /** * Returns an iterator for the given value. * * @param mixed $value */ public static function iterFor($value): \Iterator { if ($value instanceof \Iterator) { return $value; } if (is_array($value)) { return new \ArrayIterator($value); } return new \ArrayIterator([$value]); } } ================================================ FILE: lib/Google/vendor/guzzlehttp/promises/src/Each.php ================================================ $onFulfilled, 'rejected' => $onRejected, ]))->promise(); } /** * Like of, but only allows a certain number of outstanding promises at any * given time. * * $concurrency may be an integer or a function that accepts the number of * pending promises and returns a numeric concurrency limit value to allow * for dynamic a concurrency size. * * @param mixed $iterable * @param int|callable $concurrency */ public static function ofLimit( $iterable, $concurrency, ?callable $onFulfilled = null, ?callable $onRejected = null ): PromiseInterface { return (new EachPromise($iterable, [ 'fulfilled' => $onFulfilled, 'rejected' => $onRejected, 'concurrency' => $concurrency, ]))->promise(); } /** * Like limit, but ensures that no promise in the given $iterable argument * is rejected. If any promise is rejected, then the aggregate promise is * rejected with the encountered rejection. * * @param mixed $iterable * @param int|callable $concurrency */ public static function ofLimitAll( $iterable, $concurrency, ?callable $onFulfilled = null ): PromiseInterface { return self::ofLimit( $iterable, $concurrency, $onFulfilled, function ($reason, $idx, PromiseInterface $aggregate): void { $aggregate->reject($reason); } ); } } ================================================ FILE: lib/Google/vendor/guzzlehttp/promises/src/EachPromise.php ================================================ iterable = Create::iterFor($iterable); if (isset($config['concurrency'])) { $this->concurrency = $config['concurrency']; } if (isset($config['fulfilled'])) { $this->onFulfilled = $config['fulfilled']; } if (isset($config['rejected'])) { $this->onRejected = $config['rejected']; } } /** @psalm-suppress InvalidNullableReturnType */ public function promise(): PromiseInterface { if ($this->aggregate) { return $this->aggregate; } try { $this->createPromise(); /** @psalm-assert Promise $this->aggregate */ $this->iterable->rewind(); $this->refillPending(); } catch (\Throwable $e) { $this->aggregate->reject($e); } /** * @psalm-suppress NullableReturnStatement */ return $this->aggregate; } private function createPromise(): void { $this->mutex = false; $this->aggregate = new Promise(function (): void { if ($this->checkIfFinished()) { return; } reset($this->pending); // Consume a potentially fluctuating list of promises while // ensuring that indexes are maintained (precluding array_shift). while ($promise = current($this->pending)) { next($this->pending); $promise->wait(); if (Is::settled($this->aggregate)) { return; } } }); // Clear the references when the promise is resolved. $clearFn = function (): void { $this->iterable = $this->concurrency = $this->pending = null; $this->onFulfilled = $this->onRejected = null; $this->nextPendingIndex = 0; }; $this->aggregate->then($clearFn, $clearFn); } private function refillPending(): void { if (!$this->concurrency) { // Add all pending promises. while ($this->addPending() && $this->advanceIterator()) { } return; } // Add only up to N pending promises. $concurrency = is_callable($this->concurrency) ? ($this->concurrency)(count($this->pending)) : $this->concurrency; $concurrency = max($concurrency - count($this->pending), 0); // Concurrency may be set to 0 to disallow new promises. if (!$concurrency) { return; } // Add the first pending promise. $this->addPending(); // Note this is special handling for concurrency=1 so that we do // not advance the iterator after adding the first promise. This // helps work around issues with generators that might not have the // next value to yield until promise callbacks are called. while (--$concurrency && $this->advanceIterator() && $this->addPending()) { } } private function addPending(): bool { if (!$this->iterable || !$this->iterable->valid()) { return false; } $promise = Create::promiseFor($this->iterable->current()); $key = $this->iterable->key(); // Iterable keys may not be unique, so we use a counter to // guarantee uniqueness $idx = $this->nextPendingIndex++; $this->pending[$idx] = $promise->then( function ($value) use ($idx, $key): void { if ($this->onFulfilled) { ($this->onFulfilled)( $value, $key, $this->aggregate ); } $this->step($idx); }, function ($reason) use ($idx, $key): void { if ($this->onRejected) { ($this->onRejected)( $reason, $key, $this->aggregate ); } $this->step($idx); } ); return true; } private function advanceIterator(): bool { // Place a lock on the iterator so that we ensure to not recurse, // preventing fatal generator errors. if ($this->mutex) { return false; } $this->mutex = true; try { $this->iterable->next(); $this->mutex = false; return true; } catch (\Throwable $e) { $this->aggregate->reject($e); $this->mutex = false; return false; } } private function step(int $idx): void { // If the promise was already resolved, then ignore this step. if (Is::settled($this->aggregate)) { return; } unset($this->pending[$idx]); // Only refill pending promises if we are not locked, preventing the // EachPromise to recursively invoke the provided iterator, which // cause a fatal error: "Cannot resume an already running generator" if ($this->advanceIterator() && !$this->checkIfFinished()) { // Add more pending promises if possible. $this->refillPending(); } } private function checkIfFinished(): bool { if (!$this->pending && !$this->iterable->valid()) { // Resolve the promise if there's nothing left to do. $this->aggregate->resolve(null); return true; } return false; } } ================================================ FILE: lib/Google/vendor/guzzlehttp/promises/src/FulfilledPromise.php ================================================ value = $value; } public function then( ?callable $onFulfilled = null, ?callable $onRejected = null ): PromiseInterface { // Return itself if there is no onFulfilled function. if (!$onFulfilled) { return $this; } $queue = Utils::queue(); $p = new Promise([$queue, 'run']); $value = $this->value; $queue->add(static function () use ($p, $value, $onFulfilled): void { if (Is::pending($p)) { try { $p->resolve($onFulfilled($value)); } catch (\Throwable $e) { $p->reject($e); } } }); return $p; } public function otherwise(callable $onRejected): PromiseInterface { return $this->then(null, $onRejected); } public function wait(bool $unwrap = true) { return $unwrap ? $this->value : null; } public function getState(): string { return self::FULFILLED; } public function resolve($value): void { if ($value !== $this->value) { throw new \LogicException('Cannot resolve a fulfilled promise'); } } public function reject($reason): void { throw new \LogicException('Cannot reject a fulfilled promise'); } public function cancel(): void { // pass } } ================================================ FILE: lib/Google/vendor/guzzlehttp/promises/src/Is.php ================================================ getState() === PromiseInterface::PENDING; } /** * Returns true if a promise is fulfilled or rejected. */ public static function settled(PromiseInterface $promise): bool { return $promise->getState() !== PromiseInterface::PENDING; } /** * Returns true if a promise is fulfilled. */ public static function fulfilled(PromiseInterface $promise): bool { return $promise->getState() === PromiseInterface::FULFILLED; } /** * Returns true if a promise is rejected. */ public static function rejected(PromiseInterface $promise): bool { return $promise->getState() === PromiseInterface::REJECTED; } } ================================================ FILE: lib/Google/vendor/guzzlehttp/promises/src/Promise.php ================================================ waitFn = $waitFn; $this->cancelFn = $cancelFn; } public function then( ?callable $onFulfilled = null, ?callable $onRejected = null ): PromiseInterface { if ($this->state === self::PENDING) { $p = new Promise(null, [$this, 'cancel']); $this->handlers[] = [$p, $onFulfilled, $onRejected]; $p->waitList = $this->waitList; $p->waitList[] = $this; return $p; } // Return a fulfilled promise and immediately invoke any callbacks. if ($this->state === self::FULFILLED) { $promise = Create::promiseFor($this->result); return $onFulfilled ? $promise->then($onFulfilled) : $promise; } // It's either cancelled or rejected, so return a rejected promise // and immediately invoke any callbacks. $rejection = Create::rejectionFor($this->result); return $onRejected ? $rejection->then(null, $onRejected) : $rejection; } public function otherwise(callable $onRejected): PromiseInterface { return $this->then(null, $onRejected); } public function wait(bool $unwrap = true) { $this->waitIfPending(); if ($this->result instanceof PromiseInterface) { return $this->result->wait($unwrap); } if ($unwrap) { if ($this->state === self::FULFILLED) { return $this->result; } // It's rejected so "unwrap" and throw an exception. throw Create::exceptionFor($this->result); } } public function getState(): string { return $this->state; } public function cancel(): void { if ($this->state !== self::PENDING) { return; } $this->waitFn = $this->waitList = null; if ($this->cancelFn) { $fn = $this->cancelFn; $this->cancelFn = null; try { $fn(); } catch (\Throwable $e) { $this->reject($e); } } // Reject the promise only if it wasn't rejected in a then callback. /** @psalm-suppress RedundantCondition */ if ($this->state === self::PENDING) { $this->reject(new CancellationException('Promise has been cancelled')); } } public function resolve($value): void { $this->settle(self::FULFILLED, $value); } public function reject($reason): void { $this->settle(self::REJECTED, $reason); } private function settle(string $state, $value): void { if ($this->state !== self::PENDING) { // Ignore calls with the same resolution. if ($state === $this->state && $value === $this->result) { return; } throw $this->state === $state ? new \LogicException("The promise is already {$state}.") : new \LogicException("Cannot change a {$this->state} promise to {$state}"); } if ($value === $this) { throw new \LogicException('Cannot fulfill or reject a promise with itself'); } // Clear out the state of the promise but stash the handlers. $this->state = $state; $this->result = $value; $handlers = $this->handlers; $this->handlers = null; $this->waitList = $this->waitFn = null; $this->cancelFn = null; if (!$handlers) { return; } // If the value was not a settled promise or a thenable, then resolve // it in the task queue using the correct ID. if (!is_object($value) || !method_exists($value, 'then')) { $id = $state === self::FULFILLED ? 1 : 2; // It's a success, so resolve the handlers in the queue. Utils::queue()->add(static function () use ($id, $value, $handlers): void { foreach ($handlers as $handler) { self::callHandler($id, $value, $handler); } }); } elseif ($value instanceof Promise && Is::pending($value)) { // We can just merge our handlers onto the next promise. $value->handlers = array_merge($value->handlers, $handlers); } else { // Resolve the handlers when the forwarded promise is resolved. $value->then( static function ($value) use ($handlers): void { foreach ($handlers as $handler) { self::callHandler(1, $value, $handler); } }, static function ($reason) use ($handlers): void { foreach ($handlers as $handler) { self::callHandler(2, $reason, $handler); } } ); } } /** * Call a stack of handlers using a specific callback index and value. * * @param int $index 1 (resolve) or 2 (reject). * @param mixed $value Value to pass to the callback. * @param array $handler Array of handler data (promise and callbacks). */ private static function callHandler(int $index, $value, array $handler): void { /** @var PromiseInterface $promise */ $promise = $handler[0]; // The promise may have been cancelled or resolved before placing // this thunk in the queue. if (Is::settled($promise)) { return; } try { if (isset($handler[$index])) { /* * If $f throws an exception, then $handler will be in the exception * stack trace. Since $handler contains a reference to the callable * itself we get a circular reference. We clear the $handler * here to avoid that memory leak. */ $f = $handler[$index]; unset($handler); $promise->resolve($f($value)); } elseif ($index === 1) { // Forward resolution values as-is. $promise->resolve($value); } else { // Forward rejections down the chain. $promise->reject($value); } } catch (\Throwable $reason) { $promise->reject($reason); } } private function waitIfPending(): void { if ($this->state !== self::PENDING) { return; } elseif ($this->waitFn) { $this->invokeWaitFn(); } elseif ($this->waitList) { $this->invokeWaitList(); } else { // If there's no wait function, then reject the promise. $this->reject('Cannot wait on a promise that has ' .'no internal wait function. You must provide a wait ' .'function when constructing the promise to be able to ' .'wait on a promise.'); } Utils::queue()->run(); /** @psalm-suppress RedundantCondition */ if ($this->state === self::PENDING) { $this->reject('Invoking the wait callback did not resolve the promise'); } } private function invokeWaitFn(): void { try { $wfn = $this->waitFn; $this->waitFn = null; $wfn(true); } catch (\Throwable $reason) { if ($this->state === self::PENDING) { // The promise has not been resolved yet, so reject the promise // with the exception. $this->reject($reason); } else { // The promise was already resolved, so there's a problem in // the application. throw $reason; } } } private function invokeWaitList(): void { $waitList = $this->waitList; $this->waitList = null; foreach ($waitList as $result) { do { $result->waitIfPending(); $result = $result->result; } while ($result instanceof Promise); if ($result instanceof PromiseInterface) { $result->wait(false); } } } } ================================================ FILE: lib/Google/vendor/guzzlehttp/promises/src/PromiseInterface.php ================================================ reason = $reason; } public function then( ?callable $onFulfilled = null, ?callable $onRejected = null ): PromiseInterface { // If there's no onRejected callback then just return self. if (!$onRejected) { return $this; } $queue = Utils::queue(); $reason = $this->reason; $p = new Promise([$queue, 'run']); $queue->add(static function () use ($p, $reason, $onRejected): void { if (Is::pending($p)) { try { // Return a resolved promise if onRejected does not throw. $p->resolve($onRejected($reason)); } catch (\Throwable $e) { // onRejected threw, so return a rejected promise. $p->reject($e); } } }); return $p; } public function otherwise(callable $onRejected): PromiseInterface { return $this->then(null, $onRejected); } public function wait(bool $unwrap = true) { if ($unwrap) { throw Create::exceptionFor($this->reason); } return null; } public function getState(): string { return self::REJECTED; } public function resolve($value): void { throw new \LogicException('Cannot resolve a rejected promise'); } public function reject($reason): void { if ($reason !== $this->reason) { throw new \LogicException('Cannot reject a rejected promise'); } } public function cancel(): void { // pass } } ================================================ FILE: lib/Google/vendor/guzzlehttp/promises/src/RejectionException.php ================================================ reason = $reason; $message = 'The promise was rejected'; if ($description) { $message .= ' with reason: '.$description; } elseif (is_string($reason) || (is_object($reason) && method_exists($reason, '__toString')) ) { $message .= ' with reason: '.$this->reason; } elseif ($reason instanceof \JsonSerializable) { $message .= ' with reason: '.json_encode($this->reason, JSON_PRETTY_PRINT); } parent::__construct($message); } /** * Returns the rejection reason. * * @return mixed */ public function getReason() { return $this->reason; } } ================================================ FILE: lib/Google/vendor/guzzlehttp/promises/src/TaskQueue.php ================================================ run(); * * @final */ class TaskQueue implements TaskQueueInterface { private $enableShutdown = true; private $queue = []; public function __construct(bool $withShutdown = true) { if ($withShutdown) { register_shutdown_function(function (): void { if ($this->enableShutdown) { // Only run the tasks if an E_ERROR didn't occur. $err = error_get_last(); if (!$err || ($err['type'] ^ E_ERROR)) { $this->run(); } } }); } } public function isEmpty(): bool { return !$this->queue; } public function add(callable $task): void { $this->queue[] = $task; } public function run(): void { while ($task = array_shift($this->queue)) { /** @var callable $task */ $task(); } } /** * The task queue will be run and exhausted by default when the process * exits IFF the exit is not the result of a PHP E_ERROR error. * * You can disable running the automatic shutdown of the queue by calling * this function. If you disable the task queue shutdown process, then you * MUST either run the task queue (as a result of running your event loop * or manually using the run() method) or wait on each outstanding promise. * * Note: This shutdown will occur before any destructors are triggered. */ public function disableShutdown(): void { $this->enableShutdown = false; } } ================================================ FILE: lib/Google/vendor/guzzlehttp/promises/src/TaskQueueInterface.php ================================================ * while ($eventLoop->isRunning()) { * GuzzleHttp\Promise\Utils::queue()->run(); * } * * * @param TaskQueueInterface|null $assign Optionally specify a new queue instance. */ public static function queue(?TaskQueueInterface $assign = null): TaskQueueInterface { static $queue; if ($assign) { $queue = $assign; } elseif (!$queue) { $queue = new TaskQueue(); } return $queue; } /** * Adds a function to run in the task queue when it is next `run()` and * returns a promise that is fulfilled or rejected with the result. * * @param callable $task Task function to run. */ public static function task(callable $task): PromiseInterface { $queue = self::queue(); $promise = new Promise([$queue, 'run']); $queue->add(function () use ($task, $promise): void { try { if (Is::pending($promise)) { $promise->resolve($task()); } } catch (\Throwable $e) { $promise->reject($e); } }); return $promise; } /** * Synchronously waits on a promise to resolve and returns an inspection * state array. * * Returns a state associative array containing a "state" key mapping to a * valid promise state. If the state of the promise is "fulfilled", the * array will contain a "value" key mapping to the fulfilled value of the * promise. If the promise is rejected, the array will contain a "reason" * key mapping to the rejection reason of the promise. * * @param PromiseInterface $promise Promise or value. */ public static function inspect(PromiseInterface $promise): array { try { return [ 'state' => PromiseInterface::FULFILLED, 'value' => $promise->wait(), ]; } catch (RejectionException $e) { return ['state' => PromiseInterface::REJECTED, 'reason' => $e->getReason()]; } catch (\Throwable $e) { return ['state' => PromiseInterface::REJECTED, 'reason' => $e]; } } /** * Waits on all of the provided promises, but does not unwrap rejected * promises as thrown exception. * * Returns an array of inspection state arrays. * * @see inspect for the inspection state array format. * * @param PromiseInterface[] $promises Traversable of promises to wait upon. */ public static function inspectAll($promises): array { $results = []; foreach ($promises as $key => $promise) { $results[$key] = self::inspect($promise); } return $results; } /** * Waits on all of the provided promises and returns the fulfilled values. * * Returns an array that contains the value of each promise (in the same * order the promises were provided). An exception is thrown if any of the * promises are rejected. * * @param iterable $promises Iterable of PromiseInterface objects to wait on. * * @throws \Throwable on error */ public static function unwrap($promises): array { $results = []; foreach ($promises as $key => $promise) { $results[$key] = $promise->wait(); } return $results; } /** * Given an array of promises, return a promise that is fulfilled when all * the items in the array are fulfilled. * * The promise's fulfillment value is an array with fulfillment values at * respective positions to the original array. If any promise in the array * rejects, the returned promise is rejected with the rejection reason. * * @param mixed $promises Promises or values. * @param bool $recursive If true, resolves new promises that might have been added to the stack during its own resolution. */ public static function all($promises, bool $recursive = false): PromiseInterface { $results = []; $promise = Each::of( $promises, function ($value, $idx) use (&$results): void { $results[$idx] = $value; }, function ($reason, $idx, Promise $aggregate): void { if (Is::pending($aggregate)) { $aggregate->reject($reason); } } )->then(function () use (&$results) { ksort($results); return $results; }); if (true === $recursive) { $promise = $promise->then(function ($results) use ($recursive, &$promises) { foreach ($promises as $promise) { if (Is::pending($promise)) { return self::all($promises, $recursive); } } return $results; }); } return $promise; } /** * Initiate a competitive race between multiple promises or values (values * will become immediately fulfilled promises). * * When count amount of promises have been fulfilled, the returned promise * is fulfilled with an array that contains the fulfillment values of the * winners in order of resolution. * * This promise is rejected with a {@see AggregateException} if the number * of fulfilled promises is less than the desired $count. * * @param int $count Total number of promises. * @param mixed $promises Promises or values. */ public static function some(int $count, $promises): PromiseInterface { $results = []; $rejections = []; return Each::of( $promises, function ($value, $idx, PromiseInterface $p) use (&$results, $count): void { if (Is::settled($p)) { return; } $results[$idx] = $value; if (count($results) >= $count) { $p->resolve(null); } }, function ($reason) use (&$rejections): void { $rejections[] = $reason; } )->then( function () use (&$results, &$rejections, $count) { if (count($results) !== $count) { throw new AggregateException( 'Not enough promises to fulfill count', $rejections ); } ksort($results); return array_values($results); } ); } /** * Like some(), with 1 as count. However, if the promise fulfills, the * fulfillment value is not an array of 1 but the value directly. * * @param mixed $promises Promises or values. */ public static function any($promises): PromiseInterface { return self::some(1, $promises)->then(function ($values) { return $values[0]; }); } /** * Returns a promise that is fulfilled when all of the provided promises have * been fulfilled or rejected. * * The returned promise is fulfilled with an array of inspection state arrays. * * @see inspect for the inspection state array format. * * @param mixed $promises Promises or values. */ public static function settle($promises): PromiseInterface { $results = []; return Each::of( $promises, function ($value, $idx) use (&$results): void { $results[$idx] = ['state' => PromiseInterface::FULFILLED, 'value' => $value]; }, function ($reason, $idx) use (&$results): void { $results[$idx] = ['state' => PromiseInterface::REJECTED, 'reason' => $reason]; } )->then(function () use (&$results) { ksort($results); return $results; }); } } ================================================ FILE: lib/Google/vendor/guzzlehttp/psr7/CHANGELOG.md ================================================ # Change Log All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## 2.8.0 - 2025-08-23 ### Added - Allow empty lists as header values ### Changed - PHP 8.5 support ## 2.7.1 - 2025-03-27 ### Fixed - Fixed uppercase IPv6 addresses in URI ### Changed - Improve uploaded file error message ## 2.7.0 - 2024-07-18 ### Added - Add `Utils::redactUserInfo()` method - Add ability to encode bools as ints in `Query::build` ## 2.6.3 - 2024-07-18 ### Fixed - Make `StreamWrapper::stream_stat()` return `false` if inner stream's size is `null` ### Changed - PHP 8.4 support ## 2.6.2 - 2023-12-03 ### Fixed - Fixed another issue with the fact that PHP transforms numeric strings in array keys to ints ### Changed - Updated links in docs to their canonical versions - Replaced `call_user_func*` with native calls ## 2.6.1 - 2023-08-27 ### Fixed - Properly handle the fact that PHP transforms numeric strings in array keys to ints ## 2.6.0 - 2023-08-03 ### Changed - Updated the mime type map to add some new entries, fix a couple of invalid entries, and remove an invalid entry - Fallback to `application/octet-stream` if we are unable to guess the content type for a multipart file upload ## 2.5.1 - 2023-08-03 ### Fixed - Corrected mime type for `.acc` files to `audio/aac` ### Changed - PHP 8.3 support ## 2.5.0 - 2023-04-17 ### Changed - Adjusted `psr/http-message` version constraint to `^1.1 || ^2.0` ## 2.4.5 - 2023-04-17 ### Fixed - Prevent possible warnings on unset variables in `ServerRequest::normalizeNestedFileSpec` - Fixed `Message::bodySummary` when `preg_match` fails - Fixed header validation issue ## 2.4.4 - 2023-03-09 ### Changed - Removed the need for `AllowDynamicProperties` in `LazyOpenStream` ## 2.4.3 - 2022-10-26 ### Changed - Replaced `sha1(uniqid())` by `bin2hex(random_bytes(20))` ## 2.4.2 - 2022-10-25 ### Fixed - Fixed erroneous behaviour when combining host and relative path ## 2.4.1 - 2022-08-28 ### Fixed - Rewind body before reading in `Message::bodySummary` ## 2.4.0 - 2022-06-20 ### Added - Added provisional PHP 8.2 support - Added `UriComparator::isCrossOrigin` method ## 2.3.0 - 2022-06-09 ### Fixed - Added `Header::splitList` method - Added `Utils::tryGetContents` method - Improved `Stream::getContents` method - Updated mimetype mappings ## 2.2.2 - 2022-06-08 ### Fixed - Fix `Message::parseRequestUri` for numeric headers - Re-wrap exceptions thrown in `fread` into runtime exceptions - Throw an exception when multipart options is misformatted ## 2.2.1 - 2022-03-20 ### Fixed - Correct header value validation ## 2.2.0 - 2022-03-20 ### Added - A more compressive list of mime types - Add JsonSerializable to Uri - Missing return types ### Fixed - Bug MultipartStream no `uri` metadata - Bug MultipartStream with filename for `data://` streams - Fixed new line handling in MultipartStream - Reduced RAM usage when copying streams - Updated parsing in `Header::normalize()` ## 2.1.1 - 2022-03-20 ### Fixed - Validate header values properly ## 2.1.0 - 2021-10-06 ### Changed - Attempting to create a `Uri` object from a malformed URI will no longer throw a generic `InvalidArgumentException`, but rather a `MalformedUriException`, which inherits from the former for backwards compatibility. Callers relying on the exception being thrown to detect invalid URIs should catch the new exception. ### Fixed - Return `null` in caching stream size if remote size is `null` ## 2.0.0 - 2021-06-30 Identical to the RC release. ## 2.0.0@RC-1 - 2021-04-29 ### Fixed - Handle possibly unset `url` in `stream_get_meta_data` ## 2.0.0@beta-1 - 2021-03-21 ### Added - PSR-17 factories - Made classes final - PHP7 type hints ### Changed - When building a query string, booleans are represented as 1 and 0. ### Removed - PHP < 7.2 support - All functions in the `GuzzleHttp\Psr7` namespace ## 1.8.1 - 2021-03-21 ### Fixed - Issue parsing IPv6 URLs - Issue modifying ServerRequest lost all its attributes ## 1.8.0 - 2021-03-21 ### Added - Locale independent URL parsing - Most classes got a `@final` annotation to prepare for 2.0 ### Fixed - Issue when creating stream from `php://input` and curl-ext is not installed - Broken `Utils::tryFopen()` on PHP 8 ## 1.7.0 - 2020-09-30 ### Added - Replaced functions by static methods ### Fixed - Converting a non-seekable stream to a string - Handle multiple Set-Cookie correctly - Ignore array keys in header values when merging - Allow multibyte characters to be parsed in `Message:bodySummary()` ### Changed - Restored partial HHVM 3 support ## [1.6.1] - 2019-07-02 ### Fixed - Accept null and bool header values again ## [1.6.0] - 2019-06-30 ### Added - Allowed version `^3.0` of `ralouphie/getallheaders` dependency (#244) - Added MIME type for WEBP image format (#246) - Added more validation of values according to PSR-7 and RFC standards, e.g. status code range (#250, #272) ### Changed - Tests don't pass with HHVM 4.0, so HHVM support got dropped. Other libraries like composer have done the same. (#262) - Accept port number 0 to be valid (#270) ### Fixed - Fixed subsequent reads from `php://input` in ServerRequest (#247) - Fixed readable/writable detection for certain stream modes (#248) - Fixed encoding of special characters in the `userInfo` component of an URI (#253) ## [1.5.2] - 2018-12-04 ### Fixed - Check body size when getting the message summary ## [1.5.1] - 2018-12-04 ### Fixed - Get the summary of a body only if it is readable ## [1.5.0] - 2018-12-03 ### Added - Response first-line to response string exception (fixes #145) - A test for #129 behavior - `get_message_body_summary` function in order to get the message summary - `3gp` and `mkv` mime types ### Changed - Clarify exception message when stream is detached ### Deprecated - Deprecated parsing folded header lines as per RFC 7230 ### Fixed - Fix `AppendStream::detach` to not close streams - `InflateStream` preserves `isSeekable` attribute of the underlying stream - `ServerRequest::getUriFromGlobals` to support URLs in query parameters Several other fixes and improvements. ## [1.4.2] - 2017-03-20 ### Fixed - Reverted BC break to `Uri::resolve` and `Uri::removeDotSegments` by removing calls to `trigger_error` when deprecated methods are invoked. ## [1.4.1] - 2017-02-27 ### Added - Rriggering of silenced deprecation warnings. ### Fixed - Reverted BC break by reintroducing behavior to automagically fix a URI with a relative path and an authority by adding a leading slash to the path. It's only deprecated now. ## [1.4.0] - 2017-02-21 ### Added - Added common URI utility methods based on RFC 3986 (see documentation in the readme): - `Uri::isDefaultPort` - `Uri::isAbsolute` - `Uri::isNetworkPathReference` - `Uri::isAbsolutePathReference` - `Uri::isRelativePathReference` - `Uri::isSameDocumentReference` - `Uri::composeComponents` - `UriNormalizer::normalize` - `UriNormalizer::isEquivalent` - `UriResolver::relativize` ### Changed - Ensure `ServerRequest::getUriFromGlobals` returns a URI in absolute form. - Allow `parse_response` to parse a response without delimiting space and reason. - Ensure each URI modification results in a valid URI according to PSR-7 discussions. Invalid modifications will throw an exception instead of returning a wrong URI or doing some magic. - `(new Uri)->withPath('foo')->withHost('example.com')` will throw an exception because the path of a URI with an authority must start with a slash "/" or be empty - `(new Uri())->withScheme('http')` will return `'http://localhost'` ### Deprecated - `Uri::resolve` in favor of `UriResolver::resolve` - `Uri::removeDotSegments` in favor of `UriResolver::removeDotSegments` ### Fixed - `Stream::read` when length parameter <= 0. - `copy_to_stream` reads bytes in chunks instead of `maxLen` into memory. - `ServerRequest::getUriFromGlobals` when `Host` header contains port. - Compatibility of URIs with `file` scheme and empty host. ## [1.3.1] - 2016-06-25 ### Fixed - `Uri::__toString` for network path references, e.g. `//example.org`. - Missing lowercase normalization for host. - Handling of URI components in case they are `'0'` in a lot of places, e.g. as a user info password. - `Uri::withAddedHeader` to correctly merge headers with different case. - Trimming of header values in `Uri::withAddedHeader`. Header values may be surrounded by whitespace which should be ignored according to RFC 7230 Section 3.2.4. This does not apply to header names. - `Uri::withAddedHeader` with an array of header values. - `Uri::resolve` when base path has no slash and handling of fragment. - Handling of encoding in `Uri::with(out)QueryValue` so one can pass the key/value both in encoded as well as decoded form to those methods. This is consistent with withPath, withQuery etc. - `ServerRequest::withoutAttribute` when attribute value is null. ## [1.3.0] - 2016-04-13 ### Added - Remaining interfaces needed for full PSR7 compatibility (ServerRequestInterface, UploadedFileInterface, etc.). - Support for stream_for from scalars. ### Changed - Can now extend Uri. ### Fixed - A bug in validating request methods by making it more permissive. ## [1.2.3] - 2016-02-18 ### Fixed - Support in `GuzzleHttp\Psr7\CachingStream` for seeking forward on remote streams, which can sometimes return fewer bytes than requested with `fread`. - Handling of gzipped responses with FNAME headers. ## [1.2.2] - 2016-01-22 ### Added - Support for URIs without any authority. - Support for HTTP 451 'Unavailable For Legal Reasons.' - Support for using '0' as a filename. - Support for including non-standard ports in Host headers. ## [1.2.1] - 2015-11-02 ### Changes - Now supporting negative offsets when seeking to SEEK_END. ## [1.2.0] - 2015-08-15 ### Changed - Body as `"0"` is now properly added to a response. - Now allowing forward seeking in CachingStream. - Now properly parsing HTTP requests that contain proxy targets in `parse_request`. - functions.php is now conditionally required. - user-info is no longer dropped when resolving URIs. ## [1.1.0] - 2015-06-24 ### Changed - URIs can now be relative. - `multipart/form-data` headers are now overridden case-insensitively. - URI paths no longer encode the following characters because they are allowed in URIs: "(", ")", "*", "!", "'" - A port is no longer added to a URI when the scheme is missing and no port is present. ## 1.0.0 - 2015-05-19 Initial release. Currently unsupported: - `Psr\Http\Message\ServerRequestInterface` - `Psr\Http\Message\UploadedFileInterface` [1.6.0]: https://github.com/guzzle/psr7/compare/1.5.2...1.6.0 [1.5.2]: https://github.com/guzzle/psr7/compare/1.5.1...1.5.2 [1.5.1]: https://github.com/guzzle/psr7/compare/1.5.0...1.5.1 [1.5.0]: https://github.com/guzzle/psr7/compare/1.4.2...1.5.0 [1.4.2]: https://github.com/guzzle/psr7/compare/1.4.1...1.4.2 [1.4.1]: https://github.com/guzzle/psr7/compare/1.4.0...1.4.1 [1.4.0]: https://github.com/guzzle/psr7/compare/1.3.1...1.4.0 [1.3.1]: https://github.com/guzzle/psr7/compare/1.3.0...1.3.1 [1.3.0]: https://github.com/guzzle/psr7/compare/1.2.3...1.3.0 [1.2.3]: https://github.com/guzzle/psr7/compare/1.2.2...1.2.3 [1.2.2]: https://github.com/guzzle/psr7/compare/1.2.1...1.2.2 [1.2.1]: https://github.com/guzzle/psr7/compare/1.2.0...1.2.1 [1.2.0]: https://github.com/guzzle/psr7/compare/1.1.0...1.2.0 [1.1.0]: https://github.com/guzzle/psr7/compare/1.0.0...1.1.0 ================================================ FILE: lib/Google/vendor/guzzlehttp/psr7/LICENSE ================================================ The MIT License (MIT) Copyright (c) 2015 Michael Dowling Copyright (c) 2015 Márk Sági-Kazár Copyright (c) 2015 Graham Campbell Copyright (c) 2016 Tobias Schultze Copyright (c) 2016 George Mponos Copyright (c) 2018 Tobias Nyholm 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. ================================================ FILE: lib/Google/vendor/guzzlehttp/psr7/README.md ================================================ # PSR-7 Message Implementation This repository contains a full [PSR-7](https://www.php-fig.org/psr/psr-7/) message implementation, several stream decorators, and some helpful functionality like query string parsing. ![CI](https://github.com/guzzle/psr7/workflows/CI/badge.svg) ![Static analysis](https://github.com/guzzle/psr7/workflows/Static%20analysis/badge.svg) ## Features This package comes with a number of stream implementations and stream decorators. ## Installation ```shell composer require guzzlehttp/psr7 ``` ## Version Guidance | Version | Status | PHP Version | |---------|---------------------|--------------| | 1.x | EOL (2024-06-30) | >=5.4,<8.2 | | 2.x | Latest | >=7.2.5,<8.6 | ## AppendStream `GuzzleHttp\Psr7\AppendStream` Reads from multiple streams, one after the other. ```php use GuzzleHttp\Psr7; $a = Psr7\Utils::streamFor('abc, '); $b = Psr7\Utils::streamFor('123.'); $composed = new Psr7\AppendStream([$a, $b]); $composed->addStream(Psr7\Utils::streamFor(' Above all listen to me')); echo $composed; // abc, 123. Above all listen to me. ``` ## BufferStream `GuzzleHttp\Psr7\BufferStream` Provides a buffer stream that can be written to fill a buffer, and read from to remove bytes from the buffer. This stream returns a "hwm" metadata value that tells upstream consumers what the configured high water mark of the stream is, or the maximum preferred size of the buffer. ```php use GuzzleHttp\Psr7; // When more than 1024 bytes are in the buffer, it will begin returning // false to writes. This is an indication that writers should slow down. $buffer = new Psr7\BufferStream(1024); ``` ## CachingStream The CachingStream is used to allow seeking over previously read bytes on non-seekable streams. This can be useful when transferring a non-seekable entity body fails due to needing to rewind the stream (for example, resulting from a redirect). Data that is read from the remote stream will be buffered in a PHP temp stream so that previously read bytes are cached first in memory, then on disk. ```php use GuzzleHttp\Psr7; $original = Psr7\Utils::streamFor(fopen('http://www.google.com', 'r')); $stream = new Psr7\CachingStream($original); $stream->read(1024); echo $stream->tell(); // 1024 $stream->seek(0); echo $stream->tell(); // 0 ``` ## DroppingStream `GuzzleHttp\Psr7\DroppingStream` Stream decorator that begins dropping data once the size of the underlying stream becomes too full. ```php use GuzzleHttp\Psr7; // Create an empty stream $stream = Psr7\Utils::streamFor(); // Start dropping data when the stream has more than 10 bytes $dropping = new Psr7\DroppingStream($stream, 10); $dropping->write('01234567890123456789'); echo $stream; // 0123456789 ``` ## FnStream `GuzzleHttp\Psr7\FnStream` Compose stream implementations based on a hash of functions. Allows for easy testing and extension of a provided stream without needing to create a concrete class for a simple extension point. ```php use GuzzleHttp\Psr7; $stream = Psr7\Utils::streamFor('hi'); $fnStream = Psr7\FnStream::decorate($stream, [ 'rewind' => function () use ($stream) { echo 'About to rewind - '; $stream->rewind(); echo 'rewound!'; } ]); $fnStream->rewind(); // Outputs: About to rewind - rewound! ``` ## InflateStream `GuzzleHttp\Psr7\InflateStream` Uses PHP's zlib.inflate filter to inflate zlib (HTTP deflate, RFC1950) or gzipped (RFC1952) content. This stream decorator converts the provided stream to a PHP stream resource, then appends the zlib.inflate filter. The stream is then converted back to a Guzzle stream resource to be used as a Guzzle stream. ## LazyOpenStream `GuzzleHttp\Psr7\LazyOpenStream` Lazily reads or writes to a file that is opened only after an IO operation take place on the stream. ```php use GuzzleHttp\Psr7; $stream = new Psr7\LazyOpenStream('/path/to/file', 'r'); // The file has not yet been opened... echo $stream->read(10); // The file is opened and read from only when needed. ``` ## LimitStream `GuzzleHttp\Psr7\LimitStream` LimitStream can be used to read a subset or slice of an existing stream object. This can be useful for breaking a large file into smaller pieces to be sent in chunks (e.g. Amazon S3's multipart upload API). ```php use GuzzleHttp\Psr7; $original = Psr7\Utils::streamFor(fopen('/tmp/test.txt', 'r+')); echo $original->getSize(); // >>> 1048576 // Limit the size of the body to 1024 bytes and start reading from byte 2048 $stream = new Psr7\LimitStream($original, 1024, 2048); echo $stream->getSize(); // >>> 1024 echo $stream->tell(); // >>> 0 ``` ## MultipartStream `GuzzleHttp\Psr7\MultipartStream` Stream that when read returns bytes for a streaming multipart or multipart/form-data stream. ## NoSeekStream `GuzzleHttp\Psr7\NoSeekStream` NoSeekStream wraps a stream and does not allow seeking. ```php use GuzzleHttp\Psr7; $original = Psr7\Utils::streamFor('foo'); $noSeek = new Psr7\NoSeekStream($original); echo $noSeek->read(3); // foo var_export($noSeek->isSeekable()); // false $noSeek->seek(0); var_export($noSeek->read(3)); // NULL ``` ## PumpStream `GuzzleHttp\Psr7\PumpStream` Provides a read only stream that pumps data from a PHP callable. When invoking the provided callable, the PumpStream will pass the amount of data requested to read to the callable. The callable can choose to ignore this value and return fewer or more bytes than requested. Any extra data returned by the provided callable is buffered internally until drained using the read() function of the PumpStream. The provided callable MUST return false when there is no more data to read. ## Implementing stream decorators Creating a stream decorator is very easy thanks to the `GuzzleHttp\Psr7\StreamDecoratorTrait`. This trait provides methods that implement `Psr\Http\Message\StreamInterface` by proxying to an underlying stream. Just `use` the `StreamDecoratorTrait` and implement your custom methods. For example, let's say we wanted to call a specific function each time the last byte is read from a stream. This could be implemented by overriding the `read()` method. ```php use Psr\Http\Message\StreamInterface; use GuzzleHttp\Psr7\StreamDecoratorTrait; class EofCallbackStream implements StreamInterface { use StreamDecoratorTrait; private $callback; private $stream; public function __construct(StreamInterface $stream, callable $cb) { $this->stream = $stream; $this->callback = $cb; } public function read($length) { $result = $this->stream->read($length); // Invoke the callback when EOF is hit. if ($this->eof()) { ($this->callback)(); } return $result; } } ``` This decorator could be added to any existing stream and used like so: ```php use GuzzleHttp\Psr7; $original = Psr7\Utils::streamFor('foo'); $eofStream = new EofCallbackStream($original, function () { echo 'EOF!'; }); $eofStream->read(2); $eofStream->read(1); // echoes "EOF!" $eofStream->seek(0); $eofStream->read(3); // echoes "EOF!" ``` ## PHP StreamWrapper You can use the `GuzzleHttp\Psr7\StreamWrapper` class if you need to use a PSR-7 stream as a PHP stream resource. Use the `GuzzleHttp\Psr7\StreamWrapper::getResource()` method to create a PHP stream from a PSR-7 stream. ```php use GuzzleHttp\Psr7\StreamWrapper; $stream = GuzzleHttp\Psr7\Utils::streamFor('hello!'); $resource = StreamWrapper::getResource($stream); echo fread($resource, 6); // outputs hello! ``` # Static API There are various static methods available under the `GuzzleHttp\Psr7` namespace. ## `GuzzleHttp\Psr7\Message::toString` `public static function toString(MessageInterface $message): string` Returns the string representation of an HTTP message. ```php $request = new GuzzleHttp\Psr7\Request('GET', 'http://example.com'); echo GuzzleHttp\Psr7\Message::toString($request); ``` ## `GuzzleHttp\Psr7\Message::bodySummary` `public static function bodySummary(MessageInterface $message, int $truncateAt = 120): string|null` Get a short summary of the message body. Will return `null` if the response is not printable. ## `GuzzleHttp\Psr7\Message::rewindBody` `public static function rewindBody(MessageInterface $message): void` Attempts to rewind a message body and throws an exception on failure. The body of the message will only be rewound if a call to `tell()` returns a value other than `0`. ## `GuzzleHttp\Psr7\Message::parseMessage` `public static function parseMessage(string $message): array` Parses an HTTP message into an associative array. The array contains the "start-line" key containing the start line of the message, "headers" key containing an associative array of header array values, and a "body" key containing the body of the message. ## `GuzzleHttp\Psr7\Message::parseRequestUri` `public static function parseRequestUri(string $path, array $headers): string` Constructs a URI for an HTTP request message. ## `GuzzleHttp\Psr7\Message::parseRequest` `public static function parseRequest(string $message): Request` Parses a request message string into a request object. ## `GuzzleHttp\Psr7\Message::parseResponse` `public static function parseResponse(string $message): Response` Parses a response message string into a response object. ## `GuzzleHttp\Psr7\Header::parse` `public static function parse(string|array $header): array` Parse an array of header values containing ";" separated data into an array of associative arrays representing the header key value pair data of the header. When a parameter does not contain a value, but just contains a key, this function will inject a key with a '' string value. ## `GuzzleHttp\Psr7\Header::splitList` `public static function splitList(string|string[] $header): string[]` Splits a HTTP header defined to contain a comma-separated list into each individual value: ``` $knownEtags = Header::splitList($request->getHeader('if-none-match')); ``` Example headers include `accept`, `cache-control` and `if-none-match`. ## `GuzzleHttp\Psr7\Header::normalize` (deprecated) `public static function normalize(string|array $header): array` `Header::normalize()` is deprecated in favor of [`Header::splitList()`](README.md#guzzlehttppsr7headersplitlist) which performs the same operation with a cleaned up API and improved documentation. Converts an array of header values that may contain comma separated headers into an array of headers with no comma separated values. ## `GuzzleHttp\Psr7\Query::parse` `public static function parse(string $str, int|bool $urlEncoding = true): array` Parse a query string into an associative array. If multiple values are found for the same key, the value of that key value pair will become an array. This function does not parse nested PHP style arrays into an associative array (e.g., `foo[a]=1&foo[b]=2` will be parsed into `['foo[a]' => '1', 'foo[b]' => '2'])`. ## `GuzzleHttp\Psr7\Query::build` `public static function build(array $params, int|false $encoding = PHP_QUERY_RFC3986, bool $treatBoolsAsInts = true): string` Build a query string from an array of key value pairs. This function can use the return value of `parse()` to build a query string. This function does not modify the provided keys when an array is encountered (like `http_build_query()` would). ## `GuzzleHttp\Psr7\Utils::caselessRemove` `public static function caselessRemove(iterable $keys, $keys, array $data): array` Remove the items given by the keys, case insensitively from the data. ## `GuzzleHttp\Psr7\Utils::copyToStream` `public static function copyToStream(StreamInterface $source, StreamInterface $dest, int $maxLen = -1): void` Copy the contents of a stream into another stream until the given number of bytes have been read. ## `GuzzleHttp\Psr7\Utils::copyToString` `public static function copyToString(StreamInterface $stream, int $maxLen = -1): string` Copy the contents of a stream into a string until the given number of bytes have been read. ## `GuzzleHttp\Psr7\Utils::hash` `public static function hash(StreamInterface $stream, string $algo, bool $rawOutput = false): string` Calculate a hash of a stream. This method reads the entire stream to calculate a rolling hash, based on PHP's `hash_init` functions. ## `GuzzleHttp\Psr7\Utils::modifyRequest` `public static function modifyRequest(RequestInterface $request, array $changes): RequestInterface` Clone and modify a request with the given changes. This method is useful for reducing the number of clones needed to mutate a message. - method: (string) Changes the HTTP method. - set_headers: (array) Sets the given headers. - remove_headers: (array) Remove the given headers. - body: (mixed) Sets the given body. - uri: (UriInterface) Set the URI. - query: (string) Set the query string value of the URI. - version: (string) Set the protocol version. ## `GuzzleHttp\Psr7\Utils::readLine` `public static function readLine(StreamInterface $stream, ?int $maxLength = null): string` Read a line from the stream up to the maximum allowed buffer length. ## `GuzzleHttp\Psr7\Utils::redactUserInfo` `public static function redactUserInfo(UriInterface $uri): UriInterface` Redact the password in the user info part of a URI. ## `GuzzleHttp\Psr7\Utils::streamFor` `public static function streamFor(resource|string|null|int|float|bool|StreamInterface|callable|\Iterator $resource = '', array $options = []): StreamInterface` Create a new stream based on the input type. Options is an associative array that can contain the following keys: - metadata: Array of custom metadata. - size: Size of the stream. This method accepts the following `$resource` types: - `Psr\Http\Message\StreamInterface`: Returns the value as-is. - `string`: Creates a stream object that uses the given string as the contents. - `resource`: Creates a stream object that wraps the given PHP stream resource. - `Iterator`: If the provided value implements `Iterator`, then a read-only stream object will be created that wraps the given iterable. Each time the stream is read from, data from the iterator will fill a buffer and will be continuously called until the buffer is equal to the requested read size. Subsequent read calls will first read from the buffer and then call `next` on the underlying iterator until it is exhausted. - `object` with `__toString()`: If the object has the `__toString()` method, the object will be cast to a string and then a stream will be returned that uses the string value. - `NULL`: When `null` is passed, an empty stream object is returned. - `callable` When a callable is passed, a read-only stream object will be created that invokes the given callable. The callable is invoked with the number of suggested bytes to read. The callable can return any number of bytes, but MUST return `false` when there is no more data to return. The stream object that wraps the callable will invoke the callable until the number of requested bytes are available. Any additional bytes will be buffered and used in subsequent reads. ```php $stream = GuzzleHttp\Psr7\Utils::streamFor('foo'); $stream = GuzzleHttp\Psr7\Utils::streamFor(fopen('/path/to/file', 'r')); $generator = function ($bytes) { for ($i = 0; $i < $bytes; $i++) { yield ' '; } } $stream = GuzzleHttp\Psr7\Utils::streamFor($generator(100)); ``` ## `GuzzleHttp\Psr7\Utils::tryFopen` `public static function tryFopen(string $filename, string $mode): resource` Safely opens a PHP stream resource using a filename. When fopen fails, PHP normally raises a warning. This function adds an error handler that checks for errors and throws an exception instead. ## `GuzzleHttp\Psr7\Utils::tryGetContents` `public static function tryGetContents(resource $stream): string` Safely gets the contents of a given stream. When stream_get_contents fails, PHP normally raises a warning. This function adds an error handler that checks for errors and throws an exception instead. ## `GuzzleHttp\Psr7\Utils::uriFor` `public static function uriFor(string|UriInterface $uri): UriInterface` Returns a UriInterface for the given value. This function accepts a string or UriInterface and returns a UriInterface for the given value. If the value is already a UriInterface, it is returned as-is. ## `GuzzleHttp\Psr7\MimeType::fromFilename` `public static function fromFilename(string $filename): string|null` Determines the mimetype of a file by looking at its extension. ## `GuzzleHttp\Psr7\MimeType::fromExtension` `public static function fromExtension(string $extension): string|null` Maps a file extensions to a mimetype. ## Upgrading from Function API The static API was first introduced in 1.7.0, in order to mitigate problems with functions conflicting between global and local copies of the package. The function API was removed in 2.0.0. A migration table has been provided here for your convenience: | Original Function | Replacement Method | |----------------|----------------| | `str` | `Message::toString` | | `uri_for` | `Utils::uriFor` | | `stream_for` | `Utils::streamFor` | | `parse_header` | `Header::parse` | | `normalize_header` | `Header::normalize` | | `modify_request` | `Utils::modifyRequest` | | `rewind_body` | `Message::rewindBody` | | `try_fopen` | `Utils::tryFopen` | | `copy_to_string` | `Utils::copyToString` | | `copy_to_stream` | `Utils::copyToStream` | | `hash` | `Utils::hash` | | `readline` | `Utils::readLine` | | `parse_request` | `Message::parseRequest` | | `parse_response` | `Message::parseResponse` | | `parse_query` | `Query::parse` | | `build_query` | `Query::build` | | `mimetype_from_filename` | `MimeType::fromFilename` | | `mimetype_from_extension` | `MimeType::fromExtension` | | `_parse_message` | `Message::parseMessage` | | `_parse_request_uri` | `Message::parseRequestUri` | | `get_message_body_summary` | `Message::bodySummary` | | `_caseless_remove` | `Utils::caselessRemove` | # Additional URI Methods Aside from the standard `Psr\Http\Message\UriInterface` implementation in form of the `GuzzleHttp\Psr7\Uri` class, this library also provides additional functionality when working with URIs as static methods. ## URI Types An instance of `Psr\Http\Message\UriInterface` can either be an absolute URI or a relative reference. An absolute URI has a scheme. A relative reference is used to express a URI relative to another URI, the base URI. Relative references can be divided into several forms according to [RFC 3986 Section 4.2](https://datatracker.ietf.org/doc/html/rfc3986#section-4.2): - network-path references, e.g. `//example.com/path` - absolute-path references, e.g. `/path` - relative-path references, e.g. `subpath` The following methods can be used to identify the type of the URI. ### `GuzzleHttp\Psr7\Uri::isAbsolute` `public static function isAbsolute(UriInterface $uri): bool` Whether the URI is absolute, i.e. it has a scheme. ### `GuzzleHttp\Psr7\Uri::isNetworkPathReference` `public static function isNetworkPathReference(UriInterface $uri): bool` Whether the URI is a network-path reference. A relative reference that begins with two slash characters is termed an network-path reference. ### `GuzzleHttp\Psr7\Uri::isAbsolutePathReference` `public static function isAbsolutePathReference(UriInterface $uri): bool` Whether the URI is a absolute-path reference. A relative reference that begins with a single slash character is termed an absolute-path reference. ### `GuzzleHttp\Psr7\Uri::isRelativePathReference` `public static function isRelativePathReference(UriInterface $uri): bool` Whether the URI is a relative-path reference. A relative reference that does not begin with a slash character is termed a relative-path reference. ### `GuzzleHttp\Psr7\Uri::isSameDocumentReference` `public static function isSameDocumentReference(UriInterface $uri, ?UriInterface $base = null): bool` Whether the URI is a same-document reference. A same-document reference refers to a URI that is, aside from its fragment component, identical to the base URI. When no base URI is given, only an empty URI reference (apart from its fragment) is considered a same-document reference. ## URI Components Additional methods to work with URI components. ### `GuzzleHttp\Psr7\Uri::isDefaultPort` `public static function isDefaultPort(UriInterface $uri): bool` Whether the URI has the default port of the current scheme. `Psr\Http\Message\UriInterface::getPort` may return null or the standard port. This method can be used independently of the implementation. ### `GuzzleHttp\Psr7\Uri::composeComponents` `public static function composeComponents($scheme, $authority, $path, $query, $fragment): string` Composes a URI reference string from its various components according to [RFC 3986 Section 5.3](https://datatracker.ietf.org/doc/html/rfc3986#section-5.3). Usually this method does not need to be called manually but instead is used indirectly via `Psr\Http\Message\UriInterface::__toString`. ### `GuzzleHttp\Psr7\Uri::fromParts` `public static function fromParts(array $parts): UriInterface` Creates a URI from a hash of [`parse_url`](https://www.php.net/manual/en/function.parse-url.php) components. ### `GuzzleHttp\Psr7\Uri::withQueryValue` `public static function withQueryValue(UriInterface $uri, $key, $value): UriInterface` Creates a new URI with a specific query string value. Any existing query string values that exactly match the provided key are removed and replaced with the given key value pair. A value of null will set the query string key without a value, e.g. "key" instead of "key=value". ### `GuzzleHttp\Psr7\Uri::withQueryValues` `public static function withQueryValues(UriInterface $uri, array $keyValueArray): UriInterface` Creates a new URI with multiple query string values. It has the same behavior as `withQueryValue()` but for an associative array of key => value. ### `GuzzleHttp\Psr7\Uri::withoutQueryValue` `public static function withoutQueryValue(UriInterface $uri, $key): UriInterface` Creates a new URI with a specific query string value removed. Any existing query string values that exactly match the provided key are removed. ## Cross-Origin Detection `GuzzleHttp\Psr7\UriComparator` provides methods to determine if a modified URL should be considered cross-origin. ### `GuzzleHttp\Psr7\UriComparator::isCrossOrigin` `public static function isCrossOrigin(UriInterface $original, UriInterface $modified): bool` Determines if a modified URL should be considered cross-origin with respect to an original URL. ## Reference Resolution `GuzzleHttp\Psr7\UriResolver` provides methods to resolve a URI reference in the context of a base URI according to [RFC 3986 Section 5](https://datatracker.ietf.org/doc/html/rfc3986#section-5). This is for example also what web browsers do when resolving a link in a website based on the current request URI. ### `GuzzleHttp\Psr7\UriResolver::resolve` `public static function resolve(UriInterface $base, UriInterface $rel): UriInterface` Converts the relative URI into a new URI that is resolved against the base URI. ### `GuzzleHttp\Psr7\UriResolver::removeDotSegments` `public static function removeDotSegments(string $path): string` Removes dot segments from a path and returns the new path according to [RFC 3986 Section 5.2.4](https://datatracker.ietf.org/doc/html/rfc3986#section-5.2.4). ### `GuzzleHttp\Psr7\UriResolver::relativize` `public static function relativize(UriInterface $base, UriInterface $target): UriInterface` Returns the target URI as a relative reference from the base URI. This method is the counterpart to resolve(): ```php (string) $target === (string) UriResolver::resolve($base, UriResolver::relativize($base, $target)) ``` One use-case is to use the current request URI as base URI and then generate relative links in your documents to reduce the document size or offer self-contained downloadable document archives. ```php $base = new Uri('http://example.com/a/b/'); echo UriResolver::relativize($base, new Uri('http://example.com/a/b/c')); // prints 'c'. echo UriResolver::relativize($base, new Uri('http://example.com/a/x/y')); // prints '../x/y'. echo UriResolver::relativize($base, new Uri('http://example.com/a/b/?q')); // prints '?q'. echo UriResolver::relativize($base, new Uri('http://example.org/a/b/')); // prints '//example.org/a/b/'. ``` ## Normalization and Comparison `GuzzleHttp\Psr7\UriNormalizer` provides methods to normalize and compare URIs according to [RFC 3986 Section 6](https://datatracker.ietf.org/doc/html/rfc3986#section-6). ### `GuzzleHttp\Psr7\UriNormalizer::normalize` `public static function normalize(UriInterface $uri, $flags = self::PRESERVING_NORMALIZATIONS): UriInterface` Returns a normalized URI. The scheme and host component are already normalized to lowercase per PSR-7 UriInterface. This methods adds additional normalizations that can be configured with the `$flags` parameter which is a bitmask of normalizations to apply. The following normalizations are available: - `UriNormalizer::PRESERVING_NORMALIZATIONS` Default normalizations which only include the ones that preserve semantics. - `UriNormalizer::CAPITALIZE_PERCENT_ENCODING` All letters within a percent-encoding triplet (e.g., "%3A") are case-insensitive, and should be capitalized. Example: `http://example.org/a%c2%b1b` → `http://example.org/a%C2%B1b` - `UriNormalizer::DECODE_UNRESERVED_CHARACTERS` Decodes percent-encoded octets of unreserved characters. For consistency, percent-encoded octets in the ranges of ALPHA (%41–%5A and %61–%7A), DIGIT (%30–%39), hyphen (%2D), period (%2E), underscore (%5F), or tilde (%7E) should not be created by URI producers and, when found in a URI, should be decoded to their corresponding unreserved characters by URI normalizers. Example: `http://example.org/%7Eusern%61me/` → `http://example.org/~username/` - `UriNormalizer::CONVERT_EMPTY_PATH` Converts the empty path to "/" for http and https URIs. Example: `http://example.org` → `http://example.org/` - `UriNormalizer::REMOVE_DEFAULT_HOST` Removes the default host of the given URI scheme from the URI. Only the "file" scheme defines the default host "localhost". All of `file:/myfile`, `file:///myfile`, and `file://localhost/myfile` are equivalent according to RFC 3986. Example: `file://localhost/myfile` → `file:///myfile` - `UriNormalizer::REMOVE_DEFAULT_PORT` Removes the default port of the given URI scheme from the URI. Example: `http://example.org:80/` → `http://example.org/` - `UriNormalizer::REMOVE_DOT_SEGMENTS` Removes unnecessary dot-segments. Dot-segments in relative-path references are not removed as it would change the semantics of the URI reference. Example: `http://example.org/../a/b/../c/./d.html` → `http://example.org/a/c/d.html` - `UriNormalizer::REMOVE_DUPLICATE_SLASHES` Paths which include two or more adjacent slashes are converted to one. Webservers usually ignore duplicate slashes and treat those URIs equivalent. But in theory those URIs do not need to be equivalent. So this normalization may change the semantics. Encoded slashes (%2F) are not removed. Example: `http://example.org//foo///bar.html` → `http://example.org/foo/bar.html` - `UriNormalizer::SORT_QUERY_PARAMETERS` Sort query parameters with their values in alphabetical order. However, the order of parameters in a URI may be significant (this is not defined by the standard). So this normalization is not safe and may change the semantics of the URI. Example: `?lang=en&article=fred` → `?article=fred&lang=en` ### `GuzzleHttp\Psr7\UriNormalizer::isEquivalent` `public static function isEquivalent(UriInterface $uri1, UriInterface $uri2, $normalizations = self::PRESERVING_NORMALIZATIONS): bool` Whether two URIs can be considered equivalent. Both URIs are normalized automatically before comparison with the given `$normalizations` bitmask. The method also accepts relative URI references and returns true when they are equivalent. This of course assumes they will be resolved against the same base URI. If this is not the case, determination of equivalence or difference of relative references does not mean anything. ## Security If you discover a security vulnerability within this package, please send an email to security@tidelift.com. All security vulnerabilities will be promptly addressed. Please do not disclose security-related issues publicly until a fix has been announced. Please see [Security Policy](https://github.com/guzzle/psr7/security/policy) for more information. ## License Guzzle is made available under the MIT License (MIT). Please see [License File](LICENSE) for more information. ## For Enterprise Available as part of the Tidelift Subscription The maintainers of Guzzle and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/packagist-guzzlehttp-psr7?utm_source=packagist-guzzlehttp-psr7&utm_medium=referral&utm_campaign=enterprise&utm_term=repo) ================================================ FILE: lib/Google/vendor/guzzlehttp/psr7/composer.json ================================================ { "name": "guzzlehttp/psr7", "description": "PSR-7 message implementation that also provides common utility methods", "keywords": [ "request", "response", "message", "stream", "http", "uri", "url", "psr-7" ], "license": "MIT", "authors": [ { "name": "Graham Campbell", "email": "hello@gjcampbell.co.uk", "homepage": "https://github.com/GrahamCampbell" }, { "name": "Michael Dowling", "email": "mtdowling@gmail.com", "homepage": "https://github.com/mtdowling" }, { "name": "George Mponos", "email": "gmponos@gmail.com", "homepage": "https://github.com/gmponos" }, { "name": "Tobias Nyholm", "email": "tobias.nyholm@gmail.com", "homepage": "https://github.com/Nyholm" }, { "name": "Márk Sági-Kazár", "email": "mark.sagikazar@gmail.com", "homepage": "https://github.com/sagikazarmark" }, { "name": "Tobias Schultze", "email": "webmaster@tubo-world.de", "homepage": "https://github.com/Tobion" }, { "name": "Márk Sági-Kazár", "email": "mark.sagikazar@gmail.com", "homepage": "https://sagikazarmark.hu" } ], "require": { "php": "^7.2.5 || ^8.0", "psr/http-factory": "^1.0", "psr/http-message": "^1.1 || ^2.0", "ralouphie/getallheaders": "^3.0" }, "provide": { "psr/http-factory-implementation": "1.0", "psr/http-message-implementation": "1.0" }, "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", "http-interop/http-factory-tests": "0.9.0", "phpunit/phpunit": "^8.5.44 || ^9.6.25" }, "suggest": { "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" }, "autoload": { "psr-4": { "GuzzleHttp\\Psr7\\": "src/" } }, "autoload-dev": { "psr-4": { "GuzzleHttp\\Tests\\Psr7\\": "tests/" } }, "extra": { "bamarni-bin": { "bin-links": true, "forward-command": false } }, "config": { "allow-plugins": { "bamarni/composer-bin-plugin": true }, "preferred-install": "dist", "sort-packages": true } } ================================================ FILE: lib/Google/vendor/guzzlehttp/psr7/src/AppendStream.php ================================================ addStream($stream); } } public function __toString(): string { try { $this->rewind(); return $this->getContents(); } catch (\Throwable $e) { if (\PHP_VERSION_ID >= 70400) { throw $e; } trigger_error(sprintf('%s::__toString exception: %s', self::class, (string) $e), E_USER_ERROR); return ''; } } /** * Add a stream to the AppendStream * * @param StreamInterface $stream Stream to append. Must be readable. * * @throws \InvalidArgumentException if the stream is not readable */ public function addStream(StreamInterface $stream): void { if (!$stream->isReadable()) { throw new \InvalidArgumentException('Each stream must be readable'); } // The stream is only seekable if all streams are seekable if (!$stream->isSeekable()) { $this->seekable = false; } $this->streams[] = $stream; } public function getContents(): string { return Utils::copyToString($this); } /** * Closes each attached stream. */ public function close(): void { $this->pos = $this->current = 0; $this->seekable = true; foreach ($this->streams as $stream) { $stream->close(); } $this->streams = []; } /** * Detaches each attached stream. * * Returns null as it's not clear which underlying stream resource to return. */ public function detach() { $this->pos = $this->current = 0; $this->seekable = true; foreach ($this->streams as $stream) { $stream->detach(); } $this->streams = []; return null; } public function tell(): int { return $this->pos; } /** * Tries to calculate the size by adding the size of each stream. * * If any of the streams do not return a valid number, then the size of the * append stream cannot be determined and null is returned. */ public function getSize(): ?int { $size = 0; foreach ($this->streams as $stream) { $s = $stream->getSize(); if ($s === null) { return null; } $size += $s; } return $size; } public function eof(): bool { return !$this->streams || ($this->current >= count($this->streams) - 1 && $this->streams[$this->current]->eof()); } public function rewind(): void { $this->seek(0); } /** * Attempts to seek to the given position. Only supports SEEK_SET. */ public function seek($offset, $whence = SEEK_SET): void { if (!$this->seekable) { throw new \RuntimeException('This AppendStream is not seekable'); } elseif ($whence !== SEEK_SET) { throw new \RuntimeException('The AppendStream can only seek with SEEK_SET'); } $this->pos = $this->current = 0; // Rewind each stream foreach ($this->streams as $i => $stream) { try { $stream->rewind(); } catch (\Exception $e) { throw new \RuntimeException('Unable to seek stream ' .$i.' of the AppendStream', 0, $e); } } // Seek to the actual position by reading from each stream while ($this->pos < $offset && !$this->eof()) { $result = $this->read(min(8096, $offset - $this->pos)); if ($result === '') { break; } } } /** * Reads from all of the appended streams until the length is met or EOF. */ public function read($length): string { $buffer = ''; $total = count($this->streams) - 1; $remaining = $length; $progressToNext = false; while ($remaining > 0) { // Progress to the next stream if needed. if ($progressToNext || $this->streams[$this->current]->eof()) { $progressToNext = false; if ($this->current === $total) { break; } ++$this->current; } $result = $this->streams[$this->current]->read($remaining); if ($result === '') { $progressToNext = true; continue; } $buffer .= $result; $remaining = $length - strlen($buffer); } $this->pos += strlen($buffer); return $buffer; } public function isReadable(): bool { return true; } public function isWritable(): bool { return false; } public function isSeekable(): bool { return $this->seekable; } public function write($string): int { throw new \RuntimeException('Cannot write to an AppendStream'); } /** * @return mixed */ public function getMetadata($key = null) { return $key ? null : []; } } ================================================ FILE: lib/Google/vendor/guzzlehttp/psr7/src/BufferStream.php ================================================ hwm = $hwm; } public function __toString(): string { return $this->getContents(); } public function getContents(): string { $buffer = $this->buffer; $this->buffer = ''; return $buffer; } public function close(): void { $this->buffer = ''; } public function detach() { $this->close(); return null; } public function getSize(): ?int { return strlen($this->buffer); } public function isReadable(): bool { return true; } public function isWritable(): bool { return true; } public function isSeekable(): bool { return false; } public function rewind(): void { $this->seek(0); } public function seek($offset, $whence = SEEK_SET): void { throw new \RuntimeException('Cannot seek a BufferStream'); } public function eof(): bool { return strlen($this->buffer) === 0; } public function tell(): int { throw new \RuntimeException('Cannot determine the position of a BufferStream'); } /** * Reads data from the buffer. */ public function read($length): string { $currentLength = strlen($this->buffer); if ($length >= $currentLength) { // No need to slice the buffer because we don't have enough data. $result = $this->buffer; $this->buffer = ''; } else { // Slice up the result to provide a subset of the buffer. $result = substr($this->buffer, 0, $length); $this->buffer = substr($this->buffer, $length); } return $result; } /** * Writes data to the buffer. */ public function write($string): int { $this->buffer .= $string; if (strlen($this->buffer) >= $this->hwm) { return 0; } return strlen($string); } /** * @return mixed */ public function getMetadata($key = null) { if ($key === 'hwm') { return $this->hwm; } return $key ? null : []; } } ================================================ FILE: lib/Google/vendor/guzzlehttp/psr7/src/CachingStream.php ================================================ remoteStream = $stream; $this->stream = $target ?: new Stream(Utils::tryFopen('php://temp', 'r+')); } public function getSize(): ?int { $remoteSize = $this->remoteStream->getSize(); if (null === $remoteSize) { return null; } return max($this->stream->getSize(), $remoteSize); } public function rewind(): void { $this->seek(0); } public function seek($offset, $whence = SEEK_SET): void { if ($whence === SEEK_SET) { $byte = $offset; } elseif ($whence === SEEK_CUR) { $byte = $offset + $this->tell(); } elseif ($whence === SEEK_END) { $size = $this->remoteStream->getSize(); if ($size === null) { $size = $this->cacheEntireStream(); } $byte = $size + $offset; } else { throw new \InvalidArgumentException('Invalid whence'); } $diff = $byte - $this->stream->getSize(); if ($diff > 0) { // Read the remoteStream until we have read in at least the amount // of bytes requested, or we reach the end of the file. while ($diff > 0 && !$this->remoteStream->eof()) { $this->read($diff); $diff = $byte - $this->stream->getSize(); } } else { // We can just do a normal seek since we've already seen this byte. $this->stream->seek($byte); } } public function read($length): string { // Perform a regular read on any previously read data from the buffer $data = $this->stream->read($length); $remaining = $length - strlen($data); // More data was requested so read from the remote stream if ($remaining) { // If data was written to the buffer in a position that would have // been filled from the remote stream, then we must skip bytes on // the remote stream to emulate overwriting bytes from that // position. This mimics the behavior of other PHP stream wrappers. $remoteData = $this->remoteStream->read( $remaining + $this->skipReadBytes ); if ($this->skipReadBytes) { $len = strlen($remoteData); $remoteData = substr($remoteData, $this->skipReadBytes); $this->skipReadBytes = max(0, $this->skipReadBytes - $len); } $data .= $remoteData; $this->stream->write($remoteData); } return $data; } public function write($string): int { // When appending to the end of the currently read stream, you'll want // to skip bytes from being read from the remote stream to emulate // other stream wrappers. Basically replacing bytes of data of a fixed // length. $overflow = (strlen($string) + $this->tell()) - $this->remoteStream->tell(); if ($overflow > 0) { $this->skipReadBytes += $overflow; } return $this->stream->write($string); } public function eof(): bool { return $this->stream->eof() && $this->remoteStream->eof(); } /** * Close both the remote stream and buffer stream */ public function close(): void { $this->remoteStream->close(); $this->stream->close(); } private function cacheEntireStream(): int { $target = new FnStream(['write' => 'strlen']); Utils::copyToStream($this, $target); return $this->tell(); } } ================================================ FILE: lib/Google/vendor/guzzlehttp/psr7/src/DroppingStream.php ================================================ stream = $stream; $this->maxLength = $maxLength; } public function write($string): int { $diff = $this->maxLength - $this->stream->getSize(); // Begin returning 0 when the underlying stream is too large. if ($diff <= 0) { return 0; } // Write the stream or a subset of the stream if needed. if (strlen($string) < $diff) { return $this->stream->write($string); } return $this->stream->write(substr($string, 0, $diff)); } } ================================================ FILE: lib/Google/vendor/guzzlehttp/psr7/src/Exception/MalformedUriException.php ================================================ */ private $methods; /** * @param array $methods Hash of method name to a callable. */ public function __construct(array $methods) { $this->methods = $methods; // Create the functions on the class foreach ($methods as $name => $fn) { $this->{'_fn_'.$name} = $fn; } } /** * Lazily determine which methods are not implemented. * * @throws \BadMethodCallException */ public function __get(string $name): void { throw new \BadMethodCallException(str_replace('_fn_', '', $name) .'() is not implemented in the FnStream'); } /** * The close method is called on the underlying stream only if possible. */ public function __destruct() { if (isset($this->_fn_close)) { ($this->_fn_close)(); } } /** * An unserialize would allow the __destruct to run when the unserialized value goes out of scope. * * @throws \LogicException */ public function __wakeup(): void { throw new \LogicException('FnStream should never be unserialized'); } /** * Adds custom functionality to an underlying stream by intercepting * specific method calls. * * @param StreamInterface $stream Stream to decorate * @param array $methods Hash of method name to a closure * * @return FnStream */ public static function decorate(StreamInterface $stream, array $methods) { // If any of the required methods were not provided, then simply // proxy to the decorated stream. foreach (array_diff(self::SLOTS, array_keys($methods)) as $diff) { /** @var callable $callable */ $callable = [$stream, $diff]; $methods[$diff] = $callable; } return new self($methods); } public function __toString(): string { try { /** @var string */ return ($this->_fn___toString)(); } catch (\Throwable $e) { if (\PHP_VERSION_ID >= 70400) { throw $e; } trigger_error(sprintf('%s::__toString exception: %s', self::class, (string) $e), E_USER_ERROR); return ''; } } public function close(): void { ($this->_fn_close)(); } public function detach() { return ($this->_fn_detach)(); } public function getSize(): ?int { return ($this->_fn_getSize)(); } public function tell(): int { return ($this->_fn_tell)(); } public function eof(): bool { return ($this->_fn_eof)(); } public function isSeekable(): bool { return ($this->_fn_isSeekable)(); } public function rewind(): void { ($this->_fn_rewind)(); } public function seek($offset, $whence = SEEK_SET): void { ($this->_fn_seek)($offset, $whence); } public function isWritable(): bool { return ($this->_fn_isWritable)(); } public function write($string): int { return ($this->_fn_write)($string); } public function isReadable(): bool { return ($this->_fn_isReadable)(); } public function read($length): string { return ($this->_fn_read)($length); } public function getContents(): string { return ($this->_fn_getContents)(); } /** * @return mixed */ public function getMetadata($key = null) { return ($this->_fn_getMetadata)($key); } } ================================================ FILE: lib/Google/vendor/guzzlehttp/psr7/src/Header.php ================================================ ]+>|[^=]+/', $kvp, $matches)) { $m = $matches[0]; if (isset($m[1])) { $part[trim($m[0], $trimmed)] = trim($m[1], $trimmed); } else { $part[] = trim($m[0], $trimmed); } } } if ($part) { $params[] = $part; } } } return $params; } /** * Converts an array of header values that may contain comma separated * headers into an array of headers with no comma separated values. * * @param string|array $header Header to normalize. * * @deprecated Use self::splitList() instead. */ public static function normalize($header): array { $result = []; foreach ((array) $header as $value) { foreach (self::splitList($value) as $parsed) { $result[] = $parsed; } } return $result; } /** * Splits a HTTP header defined to contain a comma-separated list into * each individual value. Empty values will be removed. * * Example headers include 'accept', 'cache-control' and 'if-none-match'. * * This method must not be used to parse headers that are not defined as * a list, such as 'user-agent' or 'set-cookie'. * * @param string|string[] $values Header value as returned by MessageInterface::getHeader() * * @return string[] */ public static function splitList($values): array { if (!\is_array($values)) { $values = [$values]; } $result = []; foreach ($values as $value) { if (!\is_string($value)) { throw new \TypeError('$header must either be a string or an array containing strings.'); } $v = ''; $isQuoted = false; $isEscaped = false; for ($i = 0, $max = \strlen($value); $i < $max; ++$i) { if ($isEscaped) { $v .= $value[$i]; $isEscaped = false; continue; } if (!$isQuoted && $value[$i] === ',') { $v = \trim($v); if ($v !== '') { $result[] = $v; } $v = ''; continue; } if ($isQuoted && $value[$i] === '\\') { $isEscaped = true; $v .= $value[$i]; continue; } if ($value[$i] === '"') { $isQuoted = !$isQuoted; $v .= $value[$i]; continue; } $v .= $value[$i]; } $v = \trim($v); if ($v !== '') { $result[] = $v; } } return $result; } } ================================================ FILE: lib/Google/vendor/guzzlehttp/psr7/src/HttpFactory.php ================================================ getSize(); } return new UploadedFile($stream, $size, $error, $clientFilename, $clientMediaType); } public function createStream(string $content = ''): StreamInterface { return Utils::streamFor($content); } public function createStreamFromFile(string $file, string $mode = 'r'): StreamInterface { try { $resource = Utils::tryFopen($file, $mode); } catch (\RuntimeException $e) { if ('' === $mode || false === \in_array($mode[0], ['r', 'w', 'a', 'x', 'c'], true)) { throw new \InvalidArgumentException(sprintf('Invalid file opening mode "%s"', $mode), 0, $e); } throw $e; } return Utils::streamFor($resource); } public function createStreamFromResource($resource): StreamInterface { return Utils::streamFor($resource); } public function createServerRequest(string $method, $uri, array $serverParams = []): ServerRequestInterface { if (empty($method)) { if (!empty($serverParams['REQUEST_METHOD'])) { $method = $serverParams['REQUEST_METHOD']; } else { throw new \InvalidArgumentException('Cannot determine HTTP method'); } } return new ServerRequest($method, $uri, [], null, '1.1', $serverParams); } public function createResponse(int $code = 200, string $reasonPhrase = ''): ResponseInterface { return new Response($code, [], null, '1.1', $reasonPhrase); } public function createRequest(string $method, $uri): RequestInterface { return new Request($method, $uri); } public function createUri(string $uri = ''): UriInterface { return new Uri($uri); } } ================================================ FILE: lib/Google/vendor/guzzlehttp/psr7/src/InflateStream.php ================================================ 15 + 32]); $this->stream = $stream->isSeekable() ? new Stream($resource) : new NoSeekStream(new Stream($resource)); } } ================================================ FILE: lib/Google/vendor/guzzlehttp/psr7/src/LazyOpenStream.php ================================================ filename = $filename; $this->mode = $mode; // unsetting the property forces the first access to go through // __get(). unset($this->stream); } /** * Creates the underlying stream lazily when required. */ protected function createStream(): StreamInterface { return Utils::streamFor(Utils::tryFopen($this->filename, $this->mode)); } } ================================================ FILE: lib/Google/vendor/guzzlehttp/psr7/src/LimitStream.php ================================================ stream = $stream; $this->setLimit($limit); $this->setOffset($offset); } public function eof(): bool { // Always return true if the underlying stream is EOF if ($this->stream->eof()) { return true; } // No limit and the underlying stream is not at EOF if ($this->limit === -1) { return false; } return $this->stream->tell() >= $this->offset + $this->limit; } /** * Returns the size of the limited subset of data */ public function getSize(): ?int { if (null === ($length = $this->stream->getSize())) { return null; } elseif ($this->limit === -1) { return $length - $this->offset; } else { return min($this->limit, $length - $this->offset); } } /** * Allow for a bounded seek on the read limited stream */ public function seek($offset, $whence = SEEK_SET): void { if ($whence !== SEEK_SET || $offset < 0) { throw new \RuntimeException(sprintf( 'Cannot seek to offset %s with whence %s', $offset, $whence )); } $offset += $this->offset; if ($this->limit !== -1) { if ($offset > $this->offset + $this->limit) { $offset = $this->offset + $this->limit; } } $this->stream->seek($offset); } /** * Give a relative tell() */ public function tell(): int { return $this->stream->tell() - $this->offset; } /** * Set the offset to start limiting from * * @param int $offset Offset to seek to and begin byte limiting from * * @throws \RuntimeException if the stream cannot be seeked. */ public function setOffset(int $offset): void { $current = $this->stream->tell(); if ($current !== $offset) { // If the stream cannot seek to the offset position, then read to it if ($this->stream->isSeekable()) { $this->stream->seek($offset); } elseif ($current > $offset) { throw new \RuntimeException("Could not seek to stream offset $offset"); } else { $this->stream->read($offset - $current); } } $this->offset = $offset; } /** * Set the limit of bytes that the decorator allows to be read from the * stream. * * @param int $limit Number of bytes to allow to be read from the stream. * Use -1 for no limit. */ public function setLimit(int $limit): void { $this->limit = $limit; } public function read($length): string { if ($this->limit === -1) { return $this->stream->read($length); } // Check if the current position is less than the total allowed // bytes + original offset $remaining = ($this->offset + $this->limit) - $this->stream->tell(); if ($remaining > 0) { // Only return the amount of requested data, ensuring that the byte // limit is not exceeded return $this->stream->read(min($remaining, $length)); } return ''; } } ================================================ FILE: lib/Google/vendor/guzzlehttp/psr7/src/Message.php ================================================ getMethod().' ' .$message->getRequestTarget()) .' HTTP/'.$message->getProtocolVersion(); if (!$message->hasHeader('host')) { $msg .= "\r\nHost: ".$message->getUri()->getHost(); } } elseif ($message instanceof ResponseInterface) { $msg = 'HTTP/'.$message->getProtocolVersion().' ' .$message->getStatusCode().' ' .$message->getReasonPhrase(); } else { throw new \InvalidArgumentException('Unknown message type'); } foreach ($message->getHeaders() as $name => $values) { if (is_string($name) && strtolower($name) === 'set-cookie') { foreach ($values as $value) { $msg .= "\r\n{$name}: ".$value; } } else { $msg .= "\r\n{$name}: ".implode(', ', $values); } } return "{$msg}\r\n\r\n".$message->getBody(); } /** * Get a short summary of the message body. * * Will return `null` if the response is not printable. * * @param MessageInterface $message The message to get the body summary * @param int $truncateAt The maximum allowed size of the summary */ public static function bodySummary(MessageInterface $message, int $truncateAt = 120): ?string { $body = $message->getBody(); if (!$body->isSeekable() || !$body->isReadable()) { return null; } $size = $body->getSize(); if ($size === 0) { return null; } $body->rewind(); $summary = $body->read($truncateAt); $body->rewind(); if ($size > $truncateAt) { $summary .= ' (truncated...)'; } // Matches any printable character, including unicode characters: // letters, marks, numbers, punctuation, spacing, and separators. if (preg_match('/[^\pL\pM\pN\pP\pS\pZ\n\r\t]/u', $summary) !== 0) { return null; } return $summary; } /** * Attempts to rewind a message body and throws an exception on failure. * * The body of the message will only be rewound if a call to `tell()` * returns a value other than `0`. * * @param MessageInterface $message Message to rewind * * @throws \RuntimeException */ public static function rewindBody(MessageInterface $message): void { $body = $message->getBody(); if ($body->tell()) { $body->rewind(); } } /** * Parses an HTTP message into an associative array. * * The array contains the "start-line" key containing the start line of * the message, "headers" key containing an associative array of header * array values, and a "body" key containing the body of the message. * * @param string $message HTTP request or response to parse. */ public static function parseMessage(string $message): array { if (!$message) { throw new \InvalidArgumentException('Invalid message'); } $message = ltrim($message, "\r\n"); $messageParts = preg_split("/\r?\n\r?\n/", $message, 2); if ($messageParts === false || count($messageParts) !== 2) { throw new \InvalidArgumentException('Invalid message: Missing header delimiter'); } [$rawHeaders, $body] = $messageParts; $rawHeaders .= "\r\n"; // Put back the delimiter we split previously $headerParts = preg_split("/\r?\n/", $rawHeaders, 2); if ($headerParts === false || count($headerParts) !== 2) { throw new \InvalidArgumentException('Invalid message: Missing status line'); } [$startLine, $rawHeaders] = $headerParts; if (preg_match("/(?:^HTTP\/|^[A-Z]+ \S+ HTTP\/)(\d+(?:\.\d+)?)/i", $startLine, $matches) && $matches[1] === '1.0') { // Header folding is deprecated for HTTP/1.1, but allowed in HTTP/1.0 $rawHeaders = preg_replace(Rfc7230::HEADER_FOLD_REGEX, ' ', $rawHeaders); } /** @var array[] $headerLines */ $count = preg_match_all(Rfc7230::HEADER_REGEX, $rawHeaders, $headerLines, PREG_SET_ORDER); // If these aren't the same, then one line didn't match and there's an invalid header. if ($count !== substr_count($rawHeaders, "\n")) { // Folding is deprecated, see https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.4 if (preg_match(Rfc7230::HEADER_FOLD_REGEX, $rawHeaders)) { throw new \InvalidArgumentException('Invalid header syntax: Obsolete line folding'); } throw new \InvalidArgumentException('Invalid header syntax'); } $headers = []; foreach ($headerLines as $headerLine) { $headers[$headerLine[1]][] = $headerLine[2]; } return [ 'start-line' => $startLine, 'headers' => $headers, 'body' => $body, ]; } /** * Constructs a URI for an HTTP request message. * * @param string $path Path from the start-line * @param array $headers Array of headers (each value an array). */ public static function parseRequestUri(string $path, array $headers): string { $hostKey = array_filter(array_keys($headers), function ($k) { // Numeric array keys are converted to int by PHP. $k = (string) $k; return strtolower($k) === 'host'; }); // If no host is found, then a full URI cannot be constructed. if (!$hostKey) { return $path; } $host = $headers[reset($hostKey)][0]; $scheme = substr($host, -4) === ':443' ? 'https' : 'http'; return $scheme.'://'.$host.'/'.ltrim($path, '/'); } /** * Parses a request message string into a request object. * * @param string $message Request message string. */ public static function parseRequest(string $message): RequestInterface { $data = self::parseMessage($message); $matches = []; if (!preg_match('/^[\S]+\s+([a-zA-Z]+:\/\/|\/).*/', $data['start-line'], $matches)) { throw new \InvalidArgumentException('Invalid request string'); } $parts = explode(' ', $data['start-line'], 3); $version = isset($parts[2]) ? explode('/', $parts[2])[1] : '1.1'; $request = new Request( $parts[0], $matches[1] === '/' ? self::parseRequestUri($parts[1], $data['headers']) : $parts[1], $data['headers'], $data['body'], $version ); return $matches[1] === '/' ? $request : $request->withRequestTarget($parts[1]); } /** * Parses a response message string into a response object. * * @param string $message Response message string. */ public static function parseResponse(string $message): ResponseInterface { $data = self::parseMessage($message); // According to https://datatracker.ietf.org/doc/html/rfc7230#section-3.1.2 // the space between status-code and reason-phrase is required. But // browsers accept responses without space and reason as well. if (!preg_match('/^HTTP\/.* [0-9]{3}( .*|$)/', $data['start-line'])) { throw new \InvalidArgumentException('Invalid response string: '.$data['start-line']); } $parts = explode(' ', $data['start-line'], 3); return new Response( (int) $parts[1], $data['headers'], $data['body'], explode('/', $parts[0])[1], $parts[2] ?? null ); } } ================================================ FILE: lib/Google/vendor/guzzlehttp/psr7/src/MessageTrait.php ================================================ array of values */ private $headers = []; /** @var string[] Map of lowercase header name => original name at registration */ private $headerNames = []; /** @var string */ private $protocol = '1.1'; /** @var StreamInterface|null */ private $stream; public function getProtocolVersion(): string { return $this->protocol; } public function withProtocolVersion($version): MessageInterface { if ($this->protocol === $version) { return $this; } $new = clone $this; $new->protocol = $version; return $new; } public function getHeaders(): array { return $this->headers; } public function hasHeader($header): bool { return isset($this->headerNames[strtolower($header)]); } public function getHeader($header): array { $header = strtolower($header); if (!isset($this->headerNames[$header])) { return []; } $header = $this->headerNames[$header]; return $this->headers[$header]; } public function getHeaderLine($header): string { return implode(', ', $this->getHeader($header)); } public function withHeader($header, $value): MessageInterface { $this->assertHeader($header); $value = $this->normalizeHeaderValue($value); $normalized = strtolower($header); $new = clone $this; if (isset($new->headerNames[$normalized])) { unset($new->headers[$new->headerNames[$normalized]]); } $new->headerNames[$normalized] = $header; $new->headers[$header] = $value; return $new; } public function withAddedHeader($header, $value): MessageInterface { $this->assertHeader($header); $value = $this->normalizeHeaderValue($value); $normalized = strtolower($header); $new = clone $this; if (isset($new->headerNames[$normalized])) { $header = $this->headerNames[$normalized]; $new->headers[$header] = array_merge($this->headers[$header], $value); } else { $new->headerNames[$normalized] = $header; $new->headers[$header] = $value; } return $new; } public function withoutHeader($header): MessageInterface { $normalized = strtolower($header); if (!isset($this->headerNames[$normalized])) { return $this; } $header = $this->headerNames[$normalized]; $new = clone $this; unset($new->headers[$header], $new->headerNames[$normalized]); return $new; } public function getBody(): StreamInterface { if (!$this->stream) { $this->stream = Utils::streamFor(''); } return $this->stream; } public function withBody(StreamInterface $body): MessageInterface { if ($body === $this->stream) { return $this; } $new = clone $this; $new->stream = $body; return $new; } /** * @param (string|string[])[] $headers */ private function setHeaders(array $headers): void { $this->headerNames = $this->headers = []; foreach ($headers as $header => $value) { // Numeric array keys are converted to int by PHP. $header = (string) $header; $this->assertHeader($header); $value = $this->normalizeHeaderValue($value); $normalized = strtolower($header); if (isset($this->headerNames[$normalized])) { $header = $this->headerNames[$normalized]; $this->headers[$header] = array_merge($this->headers[$header], $value); } else { $this->headerNames[$normalized] = $header; $this->headers[$header] = $value; } } } /** * @param mixed $value * * @return string[] */ private function normalizeHeaderValue($value): array { if (!is_array($value)) { return $this->trimAndValidateHeaderValues([$value]); } return $this->trimAndValidateHeaderValues($value); } /** * Trims whitespace from the header values. * * Spaces and tabs ought to be excluded by parsers when extracting the field value from a header field. * * header-field = field-name ":" OWS field-value OWS * OWS = *( SP / HTAB ) * * @param mixed[] $values Header values * * @return string[] Trimmed header values * * @see https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.4 */ private function trimAndValidateHeaderValues(array $values): array { return array_map(function ($value) { if (!is_scalar($value) && null !== $value) { throw new \InvalidArgumentException(sprintf( 'Header value must be scalar or null but %s provided.', is_object($value) ? get_class($value) : gettype($value) )); } $trimmed = trim((string) $value, " \t"); $this->assertValue($trimmed); return $trimmed; }, array_values($values)); } /** * @see https://datatracker.ietf.org/doc/html/rfc7230#section-3.2 * * @param mixed $header */ private function assertHeader($header): void { if (!is_string($header)) { throw new \InvalidArgumentException(sprintf( 'Header name must be a string but %s provided.', is_object($header) ? get_class($header) : gettype($header) )); } if (!preg_match('/^[a-zA-Z0-9\'`#$%&*+.^_|~!-]+$/D', $header)) { throw new \InvalidArgumentException( sprintf('"%s" is not valid header name.', $header) ); } } /** * @see https://datatracker.ietf.org/doc/html/rfc7230#section-3.2 * * field-value = *( field-content / obs-fold ) * field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ] * field-vchar = VCHAR / obs-text * VCHAR = %x21-7E * obs-text = %x80-FF * obs-fold = CRLF 1*( SP / HTAB ) */ private function assertValue(string $value): void { // The regular expression intentionally does not support the obs-fold production, because as // per RFC 7230#3.2.4: // // A sender MUST NOT generate a message that includes // line folding (i.e., that has any field-value that contains a match to // the obs-fold rule) unless the message is intended for packaging // within the message/http media type. // // Clients must not send a request with line folding and a server sending folded headers is // likely very rare. Line folding is a fairly obscure feature of HTTP/1.1 and thus not accepting // folding is not likely to break any legitimate use case. if (!preg_match('/^[\x20\x09\x21-\x7E\x80-\xFF]*$/D', $value)) { throw new \InvalidArgumentException( sprintf('"%s" is not valid header value.', $value) ); } } } ================================================ FILE: lib/Google/vendor/guzzlehttp/psr7/src/MimeType.php ================================================ 'application/vnd.1000minds.decision-model+xml', '3dml' => 'text/vnd.in3d.3dml', '3ds' => 'image/x-3ds', '3g2' => 'video/3gpp2', '3gp' => 'video/3gp', '3gpp' => 'video/3gpp', '3mf' => 'model/3mf', '7z' => 'application/x-7z-compressed', '7zip' => 'application/x-7z-compressed', '123' => 'application/vnd.lotus-1-2-3', 'aab' => 'application/x-authorware-bin', 'aac' => 'audio/aac', 'aam' => 'application/x-authorware-map', 'aas' => 'application/x-authorware-seg', 'abw' => 'application/x-abiword', 'ac' => 'application/vnd.nokia.n-gage.ac+xml', 'ac3' => 'audio/ac3', 'acc' => 'application/vnd.americandynamics.acc', 'ace' => 'application/x-ace-compressed', 'acu' => 'application/vnd.acucobol', 'acutc' => 'application/vnd.acucorp', 'adp' => 'audio/adpcm', 'adts' => 'audio/aac', 'aep' => 'application/vnd.audiograph', 'afm' => 'application/x-font-type1', 'afp' => 'application/vnd.ibm.modcap', 'age' => 'application/vnd.age', 'ahead' => 'application/vnd.ahead.space', 'ai' => 'application/pdf', 'aif' => 'audio/x-aiff', 'aifc' => 'audio/x-aiff', 'aiff' => 'audio/x-aiff', 'air' => 'application/vnd.adobe.air-application-installer-package+zip', 'ait' => 'application/vnd.dvb.ait', 'ami' => 'application/vnd.amiga.ami', 'aml' => 'application/automationml-aml+xml', 'amlx' => 'application/automationml-amlx+zip', 'amr' => 'audio/amr', 'apk' => 'application/vnd.android.package-archive', 'apng' => 'image/apng', 'appcache' => 'text/cache-manifest', 'appinstaller' => 'application/appinstaller', 'application' => 'application/x-ms-application', 'appx' => 'application/appx', 'appxbundle' => 'application/appxbundle', 'apr' => 'application/vnd.lotus-approach', 'arc' => 'application/x-freearc', 'arj' => 'application/x-arj', 'asc' => 'application/pgp-signature', 'asf' => 'video/x-ms-asf', 'asm' => 'text/x-asm', 'aso' => 'application/vnd.accpac.simply.aso', 'asx' => 'video/x-ms-asf', 'atc' => 'application/vnd.acucorp', 'atom' => 'application/atom+xml', 'atomcat' => 'application/atomcat+xml', 'atomdeleted' => 'application/atomdeleted+xml', 'atomsvc' => 'application/atomsvc+xml', 'atx' => 'application/vnd.antix.game-component', 'au' => 'audio/x-au', 'avci' => 'image/avci', 'avcs' => 'image/avcs', 'avi' => 'video/x-msvideo', 'avif' => 'image/avif', 'aw' => 'application/applixware', 'azf' => 'application/vnd.airzip.filesecure.azf', 'azs' => 'application/vnd.airzip.filesecure.azs', 'azv' => 'image/vnd.airzip.accelerator.azv', 'azw' => 'application/vnd.amazon.ebook', 'b16' => 'image/vnd.pco.b16', 'bat' => 'application/x-msdownload', 'bcpio' => 'application/x-bcpio', 'bdf' => 'application/x-font-bdf', 'bdm' => 'application/vnd.syncml.dm+wbxml', 'bdoc' => 'application/x-bdoc', 'bed' => 'application/vnd.realvnc.bed', 'bh2' => 'application/vnd.fujitsu.oasysprs', 'bin' => 'application/octet-stream', 'blb' => 'application/x-blorb', 'blorb' => 'application/x-blorb', 'bmi' => 'application/vnd.bmi', 'bmml' => 'application/vnd.balsamiq.bmml+xml', 'bmp' => 'image/bmp', 'book' => 'application/vnd.framemaker', 'box' => 'application/vnd.previewsystems.box', 'boz' => 'application/x-bzip2', 'bpk' => 'application/octet-stream', 'bpmn' => 'application/octet-stream', 'bsp' => 'model/vnd.valve.source.compiled-map', 'btf' => 'image/prs.btif', 'btif' => 'image/prs.btif', 'buffer' => 'application/octet-stream', 'bz' => 'application/x-bzip', 'bz2' => 'application/x-bzip2', 'c' => 'text/x-c', 'c4d' => 'application/vnd.clonk.c4group', 'c4f' => 'application/vnd.clonk.c4group', 'c4g' => 'application/vnd.clonk.c4group', 'c4p' => 'application/vnd.clonk.c4group', 'c4u' => 'application/vnd.clonk.c4group', 'c11amc' => 'application/vnd.cluetrust.cartomobile-config', 'c11amz' => 'application/vnd.cluetrust.cartomobile-config-pkg', 'cab' => 'application/vnd.ms-cab-compressed', 'caf' => 'audio/x-caf', 'cap' => 'application/vnd.tcpdump.pcap', 'car' => 'application/vnd.curl.car', 'cat' => 'application/vnd.ms-pki.seccat', 'cb7' => 'application/x-cbr', 'cba' => 'application/x-cbr', 'cbr' => 'application/x-cbr', 'cbt' => 'application/x-cbr', 'cbz' => 'application/x-cbr', 'cc' => 'text/x-c', 'cco' => 'application/x-cocoa', 'cct' => 'application/x-director', 'ccxml' => 'application/ccxml+xml', 'cdbcmsg' => 'application/vnd.contact.cmsg', 'cdf' => 'application/x-netcdf', 'cdfx' => 'application/cdfx+xml', 'cdkey' => 'application/vnd.mediastation.cdkey', 'cdmia' => 'application/cdmi-capability', 'cdmic' => 'application/cdmi-container', 'cdmid' => 'application/cdmi-domain', 'cdmio' => 'application/cdmi-object', 'cdmiq' => 'application/cdmi-queue', 'cdr' => 'application/cdr', 'cdx' => 'chemical/x-cdx', 'cdxml' => 'application/vnd.chemdraw+xml', 'cdy' => 'application/vnd.cinderella', 'cer' => 'application/pkix-cert', 'cfs' => 'application/x-cfs-compressed', 'cgm' => 'image/cgm', 'chat' => 'application/x-chat', 'chm' => 'application/vnd.ms-htmlhelp', 'chrt' => 'application/vnd.kde.kchart', 'cif' => 'chemical/x-cif', 'cii' => 'application/vnd.anser-web-certificate-issue-initiation', 'cil' => 'application/vnd.ms-artgalry', 'cjs' => 'application/node', 'cla' => 'application/vnd.claymore', 'class' => 'application/octet-stream', 'cld' => 'model/vnd.cld', 'clkk' => 'application/vnd.crick.clicker.keyboard', 'clkp' => 'application/vnd.crick.clicker.palette', 'clkt' => 'application/vnd.crick.clicker.template', 'clkw' => 'application/vnd.crick.clicker.wordbank', 'clkx' => 'application/vnd.crick.clicker', 'clp' => 'application/x-msclip', 'cmc' => 'application/vnd.cosmocaller', 'cmdf' => 'chemical/x-cmdf', 'cml' => 'chemical/x-cml', 'cmp' => 'application/vnd.yellowriver-custom-menu', 'cmx' => 'image/x-cmx', 'cod' => 'application/vnd.rim.cod', 'coffee' => 'text/coffeescript', 'com' => 'application/x-msdownload', 'conf' => 'text/plain', 'cpio' => 'application/x-cpio', 'cpl' => 'application/cpl+xml', 'cpp' => 'text/x-c', 'cpt' => 'application/mac-compactpro', 'crd' => 'application/x-mscardfile', 'crl' => 'application/pkix-crl', 'crt' => 'application/x-x509-ca-cert', 'crx' => 'application/x-chrome-extension', 'cryptonote' => 'application/vnd.rig.cryptonote', 'csh' => 'application/x-csh', 'csl' => 'application/vnd.citationstyles.style+xml', 'csml' => 'chemical/x-csml', 'csp' => 'application/vnd.commonspace', 'csr' => 'application/octet-stream', 'css' => 'text/css', 'cst' => 'application/x-director', 'csv' => 'text/csv', 'cu' => 'application/cu-seeme', 'curl' => 'text/vnd.curl', 'cwl' => 'application/cwl', 'cww' => 'application/prs.cww', 'cxt' => 'application/x-director', 'cxx' => 'text/x-c', 'dae' => 'model/vnd.collada+xml', 'daf' => 'application/vnd.mobius.daf', 'dart' => 'application/vnd.dart', 'dataless' => 'application/vnd.fdsn.seed', 'davmount' => 'application/davmount+xml', 'dbf' => 'application/vnd.dbf', 'dbk' => 'application/docbook+xml', 'dcr' => 'application/x-director', 'dcurl' => 'text/vnd.curl.dcurl', 'dd2' => 'application/vnd.oma.dd2+xml', 'ddd' => 'application/vnd.fujixerox.ddd', 'ddf' => 'application/vnd.syncml.dmddf+xml', 'dds' => 'image/vnd.ms-dds', 'deb' => 'application/x-debian-package', 'def' => 'text/plain', 'deploy' => 'application/octet-stream', 'der' => 'application/x-x509-ca-cert', 'dfac' => 'application/vnd.dreamfactory', 'dgc' => 'application/x-dgc-compressed', 'dib' => 'image/bmp', 'dic' => 'text/x-c', 'dir' => 'application/x-director', 'dis' => 'application/vnd.mobius.dis', 'disposition-notification' => 'message/disposition-notification', 'dist' => 'application/octet-stream', 'distz' => 'application/octet-stream', 'djv' => 'image/vnd.djvu', 'djvu' => 'image/vnd.djvu', 'dll' => 'application/octet-stream', 'dmg' => 'application/x-apple-diskimage', 'dmn' => 'application/octet-stream', 'dmp' => 'application/vnd.tcpdump.pcap', 'dms' => 'application/octet-stream', 'dna' => 'application/vnd.dna', 'doc' => 'application/msword', 'docm' => 'application/vnd.ms-word.template.macroEnabled.12', 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'dot' => 'application/msword', 'dotm' => 'application/vnd.ms-word.template.macroEnabled.12', 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', 'dp' => 'application/vnd.osgi.dp', 'dpg' => 'application/vnd.dpgraph', 'dpx' => 'image/dpx', 'dra' => 'audio/vnd.dra', 'drle' => 'image/dicom-rle', 'dsc' => 'text/prs.lines.tag', 'dssc' => 'application/dssc+der', 'dtb' => 'application/x-dtbook+xml', 'dtd' => 'application/xml-dtd', 'dts' => 'audio/vnd.dts', 'dtshd' => 'audio/vnd.dts.hd', 'dump' => 'application/octet-stream', 'dvb' => 'video/vnd.dvb.file', 'dvi' => 'application/x-dvi', 'dwd' => 'application/atsc-dwd+xml', 'dwf' => 'model/vnd.dwf', 'dwg' => 'image/vnd.dwg', 'dxf' => 'image/vnd.dxf', 'dxp' => 'application/vnd.spotfire.dxp', 'dxr' => 'application/x-director', 'ear' => 'application/java-archive', 'ecelp4800' => 'audio/vnd.nuera.ecelp4800', 'ecelp7470' => 'audio/vnd.nuera.ecelp7470', 'ecelp9600' => 'audio/vnd.nuera.ecelp9600', 'ecma' => 'application/ecmascript', 'edm' => 'application/vnd.novadigm.edm', 'edx' => 'application/vnd.novadigm.edx', 'efif' => 'application/vnd.picsel', 'ei6' => 'application/vnd.pg.osasli', 'elc' => 'application/octet-stream', 'emf' => 'image/emf', 'eml' => 'message/rfc822', 'emma' => 'application/emma+xml', 'emotionml' => 'application/emotionml+xml', 'emz' => 'application/x-msmetafile', 'eol' => 'audio/vnd.digital-winds', 'eot' => 'application/vnd.ms-fontobject', 'eps' => 'application/postscript', 'epub' => 'application/epub+zip', 'es3' => 'application/vnd.eszigno3+xml', 'esa' => 'application/vnd.osgi.subsystem', 'esf' => 'application/vnd.epson.esf', 'et3' => 'application/vnd.eszigno3+xml', 'etx' => 'text/x-setext', 'eva' => 'application/x-eva', 'evy' => 'application/x-envoy', 'exe' => 'application/octet-stream', 'exi' => 'application/exi', 'exp' => 'application/express', 'exr' => 'image/aces', 'ext' => 'application/vnd.novadigm.ext', 'ez' => 'application/andrew-inset', 'ez2' => 'application/vnd.ezpix-album', 'ez3' => 'application/vnd.ezpix-package', 'f' => 'text/x-fortran', 'f4v' => 'video/mp4', 'f77' => 'text/x-fortran', 'f90' => 'text/x-fortran', 'fbs' => 'image/vnd.fastbidsheet', 'fcdt' => 'application/vnd.adobe.formscentral.fcdt', 'fcs' => 'application/vnd.isac.fcs', 'fdf' => 'application/vnd.fdf', 'fdt' => 'application/fdt+xml', 'fe_launch' => 'application/vnd.denovo.fcselayout-link', 'fg5' => 'application/vnd.fujitsu.oasysgp', 'fgd' => 'application/x-director', 'fh' => 'image/x-freehand', 'fh4' => 'image/x-freehand', 'fh5' => 'image/x-freehand', 'fh7' => 'image/x-freehand', 'fhc' => 'image/x-freehand', 'fig' => 'application/x-xfig', 'fits' => 'image/fits', 'flac' => 'audio/x-flac', 'fli' => 'video/x-fli', 'flo' => 'application/vnd.micrografx.flo', 'flv' => 'video/x-flv', 'flw' => 'application/vnd.kde.kivio', 'flx' => 'text/vnd.fmi.flexstor', 'fly' => 'text/vnd.fly', 'fm' => 'application/vnd.framemaker', 'fnc' => 'application/vnd.frogans.fnc', 'fo' => 'application/vnd.software602.filler.form+xml', 'for' => 'text/x-fortran', 'fpx' => 'image/vnd.fpx', 'frame' => 'application/vnd.framemaker', 'fsc' => 'application/vnd.fsc.weblaunch', 'fst' => 'image/vnd.fst', 'ftc' => 'application/vnd.fluxtime.clip', 'fti' => 'application/vnd.anser-web-funds-transfer-initiation', 'fvt' => 'video/vnd.fvt', 'fxp' => 'application/vnd.adobe.fxp', 'fxpl' => 'application/vnd.adobe.fxp', 'fzs' => 'application/vnd.fuzzysheet', 'g2w' => 'application/vnd.geoplan', 'g3' => 'image/g3fax', 'g3w' => 'application/vnd.geospace', 'gac' => 'application/vnd.groove-account', 'gam' => 'application/x-tads', 'gbr' => 'application/rpki-ghostbusters', 'gca' => 'application/x-gca-compressed', 'gdl' => 'model/vnd.gdl', 'gdoc' => 'application/vnd.google-apps.document', 'ged' => 'text/vnd.familysearch.gedcom', 'geo' => 'application/vnd.dynageo', 'geojson' => 'application/geo+json', 'gex' => 'application/vnd.geometry-explorer', 'ggb' => 'application/vnd.geogebra.file', 'ggt' => 'application/vnd.geogebra.tool', 'ghf' => 'application/vnd.groove-help', 'gif' => 'image/gif', 'gim' => 'application/vnd.groove-identity-message', 'glb' => 'model/gltf-binary', 'gltf' => 'model/gltf+json', 'gml' => 'application/gml+xml', 'gmx' => 'application/vnd.gmx', 'gnumeric' => 'application/x-gnumeric', 'gpg' => 'application/gpg-keys', 'gph' => 'application/vnd.flographit', 'gpx' => 'application/gpx+xml', 'gqf' => 'application/vnd.grafeq', 'gqs' => 'application/vnd.grafeq', 'gram' => 'application/srgs', 'gramps' => 'application/x-gramps-xml', 'gre' => 'application/vnd.geometry-explorer', 'grv' => 'application/vnd.groove-injector', 'grxml' => 'application/srgs+xml', 'gsf' => 'application/x-font-ghostscript', 'gsheet' => 'application/vnd.google-apps.spreadsheet', 'gslides' => 'application/vnd.google-apps.presentation', 'gtar' => 'application/x-gtar', 'gtm' => 'application/vnd.groove-tool-message', 'gtw' => 'model/vnd.gtw', 'gv' => 'text/vnd.graphviz', 'gxf' => 'application/gxf', 'gxt' => 'application/vnd.geonext', 'gz' => 'application/gzip', 'gzip' => 'application/gzip', 'h' => 'text/x-c', 'h261' => 'video/h261', 'h263' => 'video/h263', 'h264' => 'video/h264', 'hal' => 'application/vnd.hal+xml', 'hbci' => 'application/vnd.hbci', 'hbs' => 'text/x-handlebars-template', 'hdd' => 'application/x-virtualbox-hdd', 'hdf' => 'application/x-hdf', 'heic' => 'image/heic', 'heics' => 'image/heic-sequence', 'heif' => 'image/heif', 'heifs' => 'image/heif-sequence', 'hej2' => 'image/hej2k', 'held' => 'application/atsc-held+xml', 'hh' => 'text/x-c', 'hjson' => 'application/hjson', 'hlp' => 'application/winhlp', 'hpgl' => 'application/vnd.hp-hpgl', 'hpid' => 'application/vnd.hp-hpid', 'hps' => 'application/vnd.hp-hps', 'hqx' => 'application/mac-binhex40', 'hsj2' => 'image/hsj2', 'htc' => 'text/x-component', 'htke' => 'application/vnd.kenameaapp', 'htm' => 'text/html', 'html' => 'text/html', 'hvd' => 'application/vnd.yamaha.hv-dic', 'hvp' => 'application/vnd.yamaha.hv-voice', 'hvs' => 'application/vnd.yamaha.hv-script', 'i2g' => 'application/vnd.intergeo', 'icc' => 'application/vnd.iccprofile', 'ice' => 'x-conference/x-cooltalk', 'icm' => 'application/vnd.iccprofile', 'ico' => 'image/x-icon', 'ics' => 'text/calendar', 'ief' => 'image/ief', 'ifb' => 'text/calendar', 'ifm' => 'application/vnd.shana.informed.formdata', 'iges' => 'model/iges', 'igl' => 'application/vnd.igloader', 'igm' => 'application/vnd.insors.igm', 'igs' => 'model/iges', 'igx' => 'application/vnd.micrografx.igx', 'iif' => 'application/vnd.shana.informed.interchange', 'img' => 'application/octet-stream', 'imp' => 'application/vnd.accpac.simply.imp', 'ims' => 'application/vnd.ms-ims', 'in' => 'text/plain', 'ini' => 'text/plain', 'ink' => 'application/inkml+xml', 'inkml' => 'application/inkml+xml', 'install' => 'application/x-install-instructions', 'iota' => 'application/vnd.astraea-software.iota', 'ipfix' => 'application/ipfix', 'ipk' => 'application/vnd.shana.informed.package', 'irm' => 'application/vnd.ibm.rights-management', 'irp' => 'application/vnd.irepository.package+xml', 'iso' => 'application/x-iso9660-image', 'itp' => 'application/vnd.shana.informed.formtemplate', 'its' => 'application/its+xml', 'ivp' => 'application/vnd.immervision-ivp', 'ivu' => 'application/vnd.immervision-ivu', 'jad' => 'text/vnd.sun.j2me.app-descriptor', 'jade' => 'text/jade', 'jam' => 'application/vnd.jam', 'jar' => 'application/java-archive', 'jardiff' => 'application/x-java-archive-diff', 'java' => 'text/x-java-source', 'jhc' => 'image/jphc', 'jisp' => 'application/vnd.jisp', 'jls' => 'image/jls', 'jlt' => 'application/vnd.hp-jlyt', 'jng' => 'image/x-jng', 'jnlp' => 'application/x-java-jnlp-file', 'joda' => 'application/vnd.joost.joda-archive', 'jp2' => 'image/jp2', 'jpe' => 'image/jpeg', 'jpeg' => 'image/jpeg', 'jpf' => 'image/jpx', 'jpg' => 'image/jpeg', 'jpg2' => 'image/jp2', 'jpgm' => 'video/jpm', 'jpgv' => 'video/jpeg', 'jph' => 'image/jph', 'jpm' => 'video/jpm', 'jpx' => 'image/jpx', 'js' => 'application/javascript', 'json' => 'application/json', 'json5' => 'application/json5', 'jsonld' => 'application/ld+json', 'jsonml' => 'application/jsonml+json', 'jsx' => 'text/jsx', 'jt' => 'model/jt', 'jxr' => 'image/jxr', 'jxra' => 'image/jxra', 'jxrs' => 'image/jxrs', 'jxs' => 'image/jxs', 'jxsc' => 'image/jxsc', 'jxsi' => 'image/jxsi', 'jxss' => 'image/jxss', 'kar' => 'audio/midi', 'karbon' => 'application/vnd.kde.karbon', 'kdb' => 'application/octet-stream', 'kdbx' => 'application/x-keepass2', 'key' => 'application/x-iwork-keynote-sffkey', 'kfo' => 'application/vnd.kde.kformula', 'kia' => 'application/vnd.kidspiration', 'kml' => 'application/vnd.google-earth.kml+xml', 'kmz' => 'application/vnd.google-earth.kmz', 'kne' => 'application/vnd.kinar', 'knp' => 'application/vnd.kinar', 'kon' => 'application/vnd.kde.kontour', 'kpr' => 'application/vnd.kde.kpresenter', 'kpt' => 'application/vnd.kde.kpresenter', 'kpxx' => 'application/vnd.ds-keypoint', 'ksp' => 'application/vnd.kde.kspread', 'ktr' => 'application/vnd.kahootz', 'ktx' => 'image/ktx', 'ktx2' => 'image/ktx2', 'ktz' => 'application/vnd.kahootz', 'kwd' => 'application/vnd.kde.kword', 'kwt' => 'application/vnd.kde.kword', 'lasxml' => 'application/vnd.las.las+xml', 'latex' => 'application/x-latex', 'lbd' => 'application/vnd.llamagraphics.life-balance.desktop', 'lbe' => 'application/vnd.llamagraphics.life-balance.exchange+xml', 'les' => 'application/vnd.hhe.lesson-player', 'less' => 'text/less', 'lgr' => 'application/lgr+xml', 'lha' => 'application/octet-stream', 'link66' => 'application/vnd.route66.link66+xml', 'list' => 'text/plain', 'list3820' => 'application/vnd.ibm.modcap', 'listafp' => 'application/vnd.ibm.modcap', 'litcoffee' => 'text/coffeescript', 'lnk' => 'application/x-ms-shortcut', 'log' => 'text/plain', 'lostxml' => 'application/lost+xml', 'lrf' => 'application/octet-stream', 'lrm' => 'application/vnd.ms-lrm', 'ltf' => 'application/vnd.frogans.ltf', 'lua' => 'text/x-lua', 'luac' => 'application/x-lua-bytecode', 'lvp' => 'audio/vnd.lucent.voice', 'lwp' => 'application/vnd.lotus-wordpro', 'lzh' => 'application/octet-stream', 'm1v' => 'video/mpeg', 'm2a' => 'audio/mpeg', 'm2v' => 'video/mpeg', 'm3a' => 'audio/mpeg', 'm3u' => 'text/plain', 'm3u8' => 'application/vnd.apple.mpegurl', 'm4a' => 'audio/x-m4a', 'm4p' => 'application/mp4', 'm4s' => 'video/iso.segment', 'm4u' => 'application/vnd.mpegurl', 'm4v' => 'video/x-m4v', 'm13' => 'application/x-msmediaview', 'm14' => 'application/x-msmediaview', 'm21' => 'application/mp21', 'ma' => 'application/mathematica', 'mads' => 'application/mads+xml', 'maei' => 'application/mmt-aei+xml', 'mag' => 'application/vnd.ecowin.chart', 'maker' => 'application/vnd.framemaker', 'man' => 'text/troff', 'manifest' => 'text/cache-manifest', 'map' => 'application/json', 'mar' => 'application/octet-stream', 'markdown' => 'text/markdown', 'mathml' => 'application/mathml+xml', 'mb' => 'application/mathematica', 'mbk' => 'application/vnd.mobius.mbk', 'mbox' => 'application/mbox', 'mc1' => 'application/vnd.medcalcdata', 'mcd' => 'application/vnd.mcd', 'mcurl' => 'text/vnd.curl.mcurl', 'md' => 'text/markdown', 'mdb' => 'application/x-msaccess', 'mdi' => 'image/vnd.ms-modi', 'mdx' => 'text/mdx', 'me' => 'text/troff', 'mesh' => 'model/mesh', 'meta4' => 'application/metalink4+xml', 'metalink' => 'application/metalink+xml', 'mets' => 'application/mets+xml', 'mfm' => 'application/vnd.mfmp', 'mft' => 'application/rpki-manifest', 'mgp' => 'application/vnd.osgeo.mapguide.package', 'mgz' => 'application/vnd.proteus.magazine', 'mid' => 'audio/midi', 'midi' => 'audio/midi', 'mie' => 'application/x-mie', 'mif' => 'application/vnd.mif', 'mime' => 'message/rfc822', 'mj2' => 'video/mj2', 'mjp2' => 'video/mj2', 'mjs' => 'text/javascript', 'mk3d' => 'video/x-matroska', 'mka' => 'audio/x-matroska', 'mkd' => 'text/x-markdown', 'mks' => 'video/x-matroska', 'mkv' => 'video/x-matroska', 'mlp' => 'application/vnd.dolby.mlp', 'mmd' => 'application/vnd.chipnuts.karaoke-mmd', 'mmf' => 'application/vnd.smaf', 'mml' => 'text/mathml', 'mmr' => 'image/vnd.fujixerox.edmics-mmr', 'mng' => 'video/x-mng', 'mny' => 'application/x-msmoney', 'mobi' => 'application/x-mobipocket-ebook', 'mods' => 'application/mods+xml', 'mov' => 'video/quicktime', 'movie' => 'video/x-sgi-movie', 'mp2' => 'audio/mpeg', 'mp2a' => 'audio/mpeg', 'mp3' => 'audio/mpeg', 'mp4' => 'video/mp4', 'mp4a' => 'audio/mp4', 'mp4s' => 'application/mp4', 'mp4v' => 'video/mp4', 'mp21' => 'application/mp21', 'mpc' => 'application/vnd.mophun.certificate', 'mpd' => 'application/dash+xml', 'mpe' => 'video/mpeg', 'mpeg' => 'video/mpeg', 'mpf' => 'application/media-policy-dataset+xml', 'mpg' => 'video/mpeg', 'mpg4' => 'video/mp4', 'mpga' => 'audio/mpeg', 'mpkg' => 'application/vnd.apple.installer+xml', 'mpm' => 'application/vnd.blueice.multipass', 'mpn' => 'application/vnd.mophun.application', 'mpp' => 'application/vnd.ms-project', 'mpt' => 'application/vnd.ms-project', 'mpy' => 'application/vnd.ibm.minipay', 'mqy' => 'application/vnd.mobius.mqy', 'mrc' => 'application/marc', 'mrcx' => 'application/marcxml+xml', 'ms' => 'text/troff', 'mscml' => 'application/mediaservercontrol+xml', 'mseed' => 'application/vnd.fdsn.mseed', 'mseq' => 'application/vnd.mseq', 'msf' => 'application/vnd.epson.msf', 'msg' => 'application/vnd.ms-outlook', 'msh' => 'model/mesh', 'msi' => 'application/x-msdownload', 'msix' => 'application/msix', 'msixbundle' => 'application/msixbundle', 'msl' => 'application/vnd.mobius.msl', 'msm' => 'application/octet-stream', 'msp' => 'application/octet-stream', 'msty' => 'application/vnd.muvee.style', 'mtl' => 'model/mtl', 'mts' => 'model/vnd.mts', 'mus' => 'application/vnd.musician', 'musd' => 'application/mmt-usd+xml', 'musicxml' => 'application/vnd.recordare.musicxml+xml', 'mvb' => 'application/x-msmediaview', 'mvt' => 'application/vnd.mapbox-vector-tile', 'mwf' => 'application/vnd.mfer', 'mxf' => 'application/mxf', 'mxl' => 'application/vnd.recordare.musicxml', 'mxmf' => 'audio/mobile-xmf', 'mxml' => 'application/xv+xml', 'mxs' => 'application/vnd.triscape.mxs', 'mxu' => 'video/vnd.mpegurl', 'n-gage' => 'application/vnd.nokia.n-gage.symbian.install', 'n3' => 'text/n3', 'nb' => 'application/mathematica', 'nbp' => 'application/vnd.wolfram.player', 'nc' => 'application/x-netcdf', 'ncx' => 'application/x-dtbncx+xml', 'nfo' => 'text/x-nfo', 'ngdat' => 'application/vnd.nokia.n-gage.data', 'nitf' => 'application/vnd.nitf', 'nlu' => 'application/vnd.neurolanguage.nlu', 'nml' => 'application/vnd.enliven', 'nnd' => 'application/vnd.noblenet-directory', 'nns' => 'application/vnd.noblenet-sealer', 'nnw' => 'application/vnd.noblenet-web', 'npx' => 'image/vnd.net-fpx', 'nq' => 'application/n-quads', 'nsc' => 'application/x-conference', 'nsf' => 'application/vnd.lotus-notes', 'nt' => 'application/n-triples', 'ntf' => 'application/vnd.nitf', 'numbers' => 'application/x-iwork-numbers-sffnumbers', 'nzb' => 'application/x-nzb', 'oa2' => 'application/vnd.fujitsu.oasys2', 'oa3' => 'application/vnd.fujitsu.oasys3', 'oas' => 'application/vnd.fujitsu.oasys', 'obd' => 'application/x-msbinder', 'obgx' => 'application/vnd.openblox.game+xml', 'obj' => 'model/obj', 'oda' => 'application/oda', 'odb' => 'application/vnd.oasis.opendocument.database', 'odc' => 'application/vnd.oasis.opendocument.chart', 'odf' => 'application/vnd.oasis.opendocument.formula', 'odft' => 'application/vnd.oasis.opendocument.formula-template', 'odg' => 'application/vnd.oasis.opendocument.graphics', 'odi' => 'application/vnd.oasis.opendocument.image', 'odm' => 'application/vnd.oasis.opendocument.text-master', 'odp' => 'application/vnd.oasis.opendocument.presentation', 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', 'odt' => 'application/vnd.oasis.opendocument.text', 'oga' => 'audio/ogg', 'ogex' => 'model/vnd.opengex', 'ogg' => 'audio/ogg', 'ogv' => 'video/ogg', 'ogx' => 'application/ogg', 'omdoc' => 'application/omdoc+xml', 'onepkg' => 'application/onenote', 'onetmp' => 'application/onenote', 'onetoc' => 'application/onenote', 'onetoc2' => 'application/onenote', 'opf' => 'application/oebps-package+xml', 'opml' => 'text/x-opml', 'oprc' => 'application/vnd.palm', 'opus' => 'audio/ogg', 'org' => 'text/x-org', 'osf' => 'application/vnd.yamaha.openscoreformat', 'osfpvg' => 'application/vnd.yamaha.openscoreformat.osfpvg+xml', 'osm' => 'application/vnd.openstreetmap.data+xml', 'otc' => 'application/vnd.oasis.opendocument.chart-template', 'otf' => 'font/otf', 'otg' => 'application/vnd.oasis.opendocument.graphics-template', 'oth' => 'application/vnd.oasis.opendocument.text-web', 'oti' => 'application/vnd.oasis.opendocument.image-template', 'otp' => 'application/vnd.oasis.opendocument.presentation-template', 'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template', 'ott' => 'application/vnd.oasis.opendocument.text-template', 'ova' => 'application/x-virtualbox-ova', 'ovf' => 'application/x-virtualbox-ovf', 'owl' => 'application/rdf+xml', 'oxps' => 'application/oxps', 'oxt' => 'application/vnd.openofficeorg.extension', 'p' => 'text/x-pascal', 'p7a' => 'application/x-pkcs7-signature', 'p7b' => 'application/x-pkcs7-certificates', 'p7c' => 'application/pkcs7-mime', 'p7m' => 'application/pkcs7-mime', 'p7r' => 'application/x-pkcs7-certreqresp', 'p7s' => 'application/pkcs7-signature', 'p8' => 'application/pkcs8', 'p10' => 'application/x-pkcs10', 'p12' => 'application/x-pkcs12', 'pac' => 'application/x-ns-proxy-autoconfig', 'pages' => 'application/x-iwork-pages-sffpages', 'pas' => 'text/x-pascal', 'paw' => 'application/vnd.pawaafile', 'pbd' => 'application/vnd.powerbuilder6', 'pbm' => 'image/x-portable-bitmap', 'pcap' => 'application/vnd.tcpdump.pcap', 'pcf' => 'application/x-font-pcf', 'pcl' => 'application/vnd.hp-pcl', 'pclxl' => 'application/vnd.hp-pclxl', 'pct' => 'image/x-pict', 'pcurl' => 'application/vnd.curl.pcurl', 'pcx' => 'image/x-pcx', 'pdb' => 'application/x-pilot', 'pde' => 'text/x-processing', 'pdf' => 'application/pdf', 'pem' => 'application/x-x509-user-cert', 'pfa' => 'application/x-font-type1', 'pfb' => 'application/x-font-type1', 'pfm' => 'application/x-font-type1', 'pfr' => 'application/font-tdpfr', 'pfx' => 'application/x-pkcs12', 'pgm' => 'image/x-portable-graymap', 'pgn' => 'application/x-chess-pgn', 'pgp' => 'application/pgp', 'phar' => 'application/octet-stream', 'php' => 'application/x-httpd-php', 'php3' => 'application/x-httpd-php', 'php4' => 'application/x-httpd-php', 'phps' => 'application/x-httpd-php-source', 'phtml' => 'application/x-httpd-php', 'pic' => 'image/x-pict', 'pkg' => 'application/octet-stream', 'pki' => 'application/pkixcmp', 'pkipath' => 'application/pkix-pkipath', 'pkpass' => 'application/vnd.apple.pkpass', 'pl' => 'application/x-perl', 'plb' => 'application/vnd.3gpp.pic-bw-large', 'plc' => 'application/vnd.mobius.plc', 'plf' => 'application/vnd.pocketlearn', 'pls' => 'application/pls+xml', 'pm' => 'application/x-perl', 'pml' => 'application/vnd.ctc-posml', 'png' => 'image/png', 'pnm' => 'image/x-portable-anymap', 'portpkg' => 'application/vnd.macports.portpkg', 'pot' => 'application/vnd.ms-powerpoint', 'potm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12', 'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template', 'ppa' => 'application/vnd.ms-powerpoint', 'ppam' => 'application/vnd.ms-powerpoint.addin.macroEnabled.12', 'ppd' => 'application/vnd.cups-ppd', 'ppm' => 'image/x-portable-pixmap', 'pps' => 'application/vnd.ms-powerpoint', 'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12', 'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', 'ppt' => 'application/powerpoint', 'pptm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12', 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'pqa' => 'application/vnd.palm', 'prc' => 'model/prc', 'pre' => 'application/vnd.lotus-freelance', 'prf' => 'application/pics-rules', 'provx' => 'application/provenance+xml', 'ps' => 'application/postscript', 'psb' => 'application/vnd.3gpp.pic-bw-small', 'psd' => 'application/x-photoshop', 'psf' => 'application/x-font-linux-psf', 'pskcxml' => 'application/pskc+xml', 'pti' => 'image/prs.pti', 'ptid' => 'application/vnd.pvi.ptid1', 'pub' => 'application/x-mspublisher', 'pvb' => 'application/vnd.3gpp.pic-bw-var', 'pwn' => 'application/vnd.3m.post-it-notes', 'pya' => 'audio/vnd.ms-playready.media.pya', 'pyo' => 'model/vnd.pytha.pyox', 'pyox' => 'model/vnd.pytha.pyox', 'pyv' => 'video/vnd.ms-playready.media.pyv', 'qam' => 'application/vnd.epson.quickanime', 'qbo' => 'application/vnd.intu.qbo', 'qfx' => 'application/vnd.intu.qfx', 'qps' => 'application/vnd.publishare-delta-tree', 'qt' => 'video/quicktime', 'qwd' => 'application/vnd.quark.quarkxpress', 'qwt' => 'application/vnd.quark.quarkxpress', 'qxb' => 'application/vnd.quark.quarkxpress', 'qxd' => 'application/vnd.quark.quarkxpress', 'qxl' => 'application/vnd.quark.quarkxpress', 'qxt' => 'application/vnd.quark.quarkxpress', 'ra' => 'audio/x-realaudio', 'ram' => 'audio/x-pn-realaudio', 'raml' => 'application/raml+yaml', 'rapd' => 'application/route-apd+xml', 'rar' => 'application/x-rar', 'ras' => 'image/x-cmu-raster', 'rcprofile' => 'application/vnd.ipunplugged.rcprofile', 'rdf' => 'application/rdf+xml', 'rdz' => 'application/vnd.data-vision.rdz', 'relo' => 'application/p2p-overlay+xml', 'rep' => 'application/vnd.businessobjects', 'res' => 'application/x-dtbresource+xml', 'rgb' => 'image/x-rgb', 'rif' => 'application/reginfo+xml', 'rip' => 'audio/vnd.rip', 'ris' => 'application/x-research-info-systems', 'rl' => 'application/resource-lists+xml', 'rlc' => 'image/vnd.fujixerox.edmics-rlc', 'rld' => 'application/resource-lists-diff+xml', 'rm' => 'audio/x-pn-realaudio', 'rmi' => 'audio/midi', 'rmp' => 'audio/x-pn-realaudio-plugin', 'rms' => 'application/vnd.jcp.javame.midlet-rms', 'rmvb' => 'application/vnd.rn-realmedia-vbr', 'rnc' => 'application/relax-ng-compact-syntax', 'rng' => 'application/xml', 'roa' => 'application/rpki-roa', 'roff' => 'text/troff', 'rp9' => 'application/vnd.cloanto.rp9', 'rpm' => 'audio/x-pn-realaudio-plugin', 'rpss' => 'application/vnd.nokia.radio-presets', 'rpst' => 'application/vnd.nokia.radio-preset', 'rq' => 'application/sparql-query', 'rs' => 'application/rls-services+xml', 'rsa' => 'application/x-pkcs7', 'rsat' => 'application/atsc-rsat+xml', 'rsd' => 'application/rsd+xml', 'rsheet' => 'application/urc-ressheet+xml', 'rss' => 'application/rss+xml', 'rtf' => 'text/rtf', 'rtx' => 'text/richtext', 'run' => 'application/x-makeself', 'rusd' => 'application/route-usd+xml', 'rv' => 'video/vnd.rn-realvideo', 's' => 'text/x-asm', 's3m' => 'audio/s3m', 'saf' => 'application/vnd.yamaha.smaf-audio', 'sass' => 'text/x-sass', 'sbml' => 'application/sbml+xml', 'sc' => 'application/vnd.ibm.secure-container', 'scd' => 'application/x-msschedule', 'scm' => 'application/vnd.lotus-screencam', 'scq' => 'application/scvp-cv-request', 'scs' => 'application/scvp-cv-response', 'scss' => 'text/x-scss', 'scurl' => 'text/vnd.curl.scurl', 'sda' => 'application/vnd.stardivision.draw', 'sdc' => 'application/vnd.stardivision.calc', 'sdd' => 'application/vnd.stardivision.impress', 'sdkd' => 'application/vnd.solent.sdkm+xml', 'sdkm' => 'application/vnd.solent.sdkm+xml', 'sdp' => 'application/sdp', 'sdw' => 'application/vnd.stardivision.writer', 'sea' => 'application/octet-stream', 'see' => 'application/vnd.seemail', 'seed' => 'application/vnd.fdsn.seed', 'sema' => 'application/vnd.sema', 'semd' => 'application/vnd.semd', 'semf' => 'application/vnd.semf', 'senmlx' => 'application/senml+xml', 'sensmlx' => 'application/sensml+xml', 'ser' => 'application/java-serialized-object', 'setpay' => 'application/set-payment-initiation', 'setreg' => 'application/set-registration-initiation', 'sfd-hdstx' => 'application/vnd.hydrostatix.sof-data', 'sfs' => 'application/vnd.spotfire.sfs', 'sfv' => 'text/x-sfv', 'sgi' => 'image/sgi', 'sgl' => 'application/vnd.stardivision.writer-global', 'sgm' => 'text/sgml', 'sgml' => 'text/sgml', 'sh' => 'application/x-sh', 'shar' => 'application/x-shar', 'shex' => 'text/shex', 'shf' => 'application/shf+xml', 'shtml' => 'text/html', 'sid' => 'image/x-mrsid-image', 'sieve' => 'application/sieve', 'sig' => 'application/pgp-signature', 'sil' => 'audio/silk', 'silo' => 'model/mesh', 'sis' => 'application/vnd.symbian.install', 'sisx' => 'application/vnd.symbian.install', 'sit' => 'application/x-stuffit', 'sitx' => 'application/x-stuffitx', 'siv' => 'application/sieve', 'skd' => 'application/vnd.koan', 'skm' => 'application/vnd.koan', 'skp' => 'application/vnd.koan', 'skt' => 'application/vnd.koan', 'sldm' => 'application/vnd.ms-powerpoint.slide.macroenabled.12', 'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide', 'slim' => 'text/slim', 'slm' => 'text/slim', 'sls' => 'application/route-s-tsid+xml', 'slt' => 'application/vnd.epson.salt', 'sm' => 'application/vnd.stepmania.stepchart', 'smf' => 'application/vnd.stardivision.math', 'smi' => 'application/smil', 'smil' => 'application/smil', 'smv' => 'video/x-smv', 'smzip' => 'application/vnd.stepmania.package', 'snd' => 'audio/basic', 'snf' => 'application/x-font-snf', 'so' => 'application/octet-stream', 'spc' => 'application/x-pkcs7-certificates', 'spdx' => 'text/spdx', 'spf' => 'application/vnd.yamaha.smaf-phrase', 'spl' => 'application/x-futuresplash', 'spot' => 'text/vnd.in3d.spot', 'spp' => 'application/scvp-vp-response', 'spq' => 'application/scvp-vp-request', 'spx' => 'audio/ogg', 'sql' => 'application/x-sql', 'src' => 'application/x-wais-source', 'srt' => 'application/x-subrip', 'sru' => 'application/sru+xml', 'srx' => 'application/sparql-results+xml', 'ssdl' => 'application/ssdl+xml', 'sse' => 'application/vnd.kodak-descriptor', 'ssf' => 'application/vnd.epson.ssf', 'ssml' => 'application/ssml+xml', 'sst' => 'application/octet-stream', 'st' => 'application/vnd.sailingtracker.track', 'stc' => 'application/vnd.sun.xml.calc.template', 'std' => 'application/vnd.sun.xml.draw.template', 'step' => 'application/STEP', 'stf' => 'application/vnd.wt.stf', 'sti' => 'application/vnd.sun.xml.impress.template', 'stk' => 'application/hyperstudio', 'stl' => 'model/stl', 'stp' => 'application/STEP', 'stpx' => 'model/step+xml', 'stpxz' => 'model/step-xml+zip', 'stpz' => 'model/step+zip', 'str' => 'application/vnd.pg.format', 'stw' => 'application/vnd.sun.xml.writer.template', 'styl' => 'text/stylus', 'stylus' => 'text/stylus', 'sub' => 'text/vnd.dvb.subtitle', 'sus' => 'application/vnd.sus-calendar', 'susp' => 'application/vnd.sus-calendar', 'sv4cpio' => 'application/x-sv4cpio', 'sv4crc' => 'application/x-sv4crc', 'svc' => 'application/vnd.dvb.service', 'svd' => 'application/vnd.svd', 'svg' => 'image/svg+xml', 'svgz' => 'image/svg+xml', 'swa' => 'application/x-director', 'swf' => 'application/x-shockwave-flash', 'swi' => 'application/vnd.aristanetworks.swi', 'swidtag' => 'application/swid+xml', 'sxc' => 'application/vnd.sun.xml.calc', 'sxd' => 'application/vnd.sun.xml.draw', 'sxg' => 'application/vnd.sun.xml.writer.global', 'sxi' => 'application/vnd.sun.xml.impress', 'sxm' => 'application/vnd.sun.xml.math', 'sxw' => 'application/vnd.sun.xml.writer', 't' => 'text/troff', 't3' => 'application/x-t3vm-image', 't38' => 'image/t38', 'taglet' => 'application/vnd.mynfc', 'tao' => 'application/vnd.tao.intent-module-archive', 'tap' => 'image/vnd.tencent.tap', 'tar' => 'application/x-tar', 'tcap' => 'application/vnd.3gpp2.tcap', 'tcl' => 'application/x-tcl', 'td' => 'application/urc-targetdesc+xml', 'teacher' => 'application/vnd.smart.teacher', 'tei' => 'application/tei+xml', 'teicorpus' => 'application/tei+xml', 'tex' => 'application/x-tex', 'texi' => 'application/x-texinfo', 'texinfo' => 'application/x-texinfo', 'text' => 'text/plain', 'tfi' => 'application/thraud+xml', 'tfm' => 'application/x-tex-tfm', 'tfx' => 'image/tiff-fx', 'tga' => 'image/x-tga', 'tgz' => 'application/x-tar', 'thmx' => 'application/vnd.ms-officetheme', 'tif' => 'image/tiff', 'tiff' => 'image/tiff', 'tk' => 'application/x-tcl', 'tmo' => 'application/vnd.tmobile-livetv', 'toml' => 'application/toml', 'torrent' => 'application/x-bittorrent', 'tpl' => 'application/vnd.groove-tool-template', 'tpt' => 'application/vnd.trid.tpt', 'tr' => 'text/troff', 'tra' => 'application/vnd.trueapp', 'trig' => 'application/trig', 'trm' => 'application/x-msterminal', 'ts' => 'video/mp2t', 'tsd' => 'application/timestamped-data', 'tsv' => 'text/tab-separated-values', 'ttc' => 'font/collection', 'ttf' => 'font/ttf', 'ttl' => 'text/turtle', 'ttml' => 'application/ttml+xml', 'twd' => 'application/vnd.simtech-mindmapper', 'twds' => 'application/vnd.simtech-mindmapper', 'txd' => 'application/vnd.genomatix.tuxedo', 'txf' => 'application/vnd.mobius.txf', 'txt' => 'text/plain', 'u3d' => 'model/u3d', 'u8dsn' => 'message/global-delivery-status', 'u8hdr' => 'message/global-headers', 'u8mdn' => 'message/global-disposition-notification', 'u8msg' => 'message/global', 'u32' => 'application/x-authorware-bin', 'ubj' => 'application/ubjson', 'udeb' => 'application/x-debian-package', 'ufd' => 'application/vnd.ufdl', 'ufdl' => 'application/vnd.ufdl', 'ulx' => 'application/x-glulx', 'umj' => 'application/vnd.umajin', 'unityweb' => 'application/vnd.unity', 'uo' => 'application/vnd.uoml+xml', 'uoml' => 'application/vnd.uoml+xml', 'uri' => 'text/uri-list', 'uris' => 'text/uri-list', 'urls' => 'text/uri-list', 'usda' => 'model/vnd.usda', 'usdz' => 'model/vnd.usdz+zip', 'ustar' => 'application/x-ustar', 'utz' => 'application/vnd.uiq.theme', 'uu' => 'text/x-uuencode', 'uva' => 'audio/vnd.dece.audio', 'uvd' => 'application/vnd.dece.data', 'uvf' => 'application/vnd.dece.data', 'uvg' => 'image/vnd.dece.graphic', 'uvh' => 'video/vnd.dece.hd', 'uvi' => 'image/vnd.dece.graphic', 'uvm' => 'video/vnd.dece.mobile', 'uvp' => 'video/vnd.dece.pd', 'uvs' => 'video/vnd.dece.sd', 'uvt' => 'application/vnd.dece.ttml+xml', 'uvu' => 'video/vnd.uvvu.mp4', 'uvv' => 'video/vnd.dece.video', 'uvva' => 'audio/vnd.dece.audio', 'uvvd' => 'application/vnd.dece.data', 'uvvf' => 'application/vnd.dece.data', 'uvvg' => 'image/vnd.dece.graphic', 'uvvh' => 'video/vnd.dece.hd', 'uvvi' => 'image/vnd.dece.graphic', 'uvvm' => 'video/vnd.dece.mobile', 'uvvp' => 'video/vnd.dece.pd', 'uvvs' => 'video/vnd.dece.sd', 'uvvt' => 'application/vnd.dece.ttml+xml', 'uvvu' => 'video/vnd.uvvu.mp4', 'uvvv' => 'video/vnd.dece.video', 'uvvx' => 'application/vnd.dece.unspecified', 'uvvz' => 'application/vnd.dece.zip', 'uvx' => 'application/vnd.dece.unspecified', 'uvz' => 'application/vnd.dece.zip', 'vbox' => 'application/x-virtualbox-vbox', 'vbox-extpack' => 'application/x-virtualbox-vbox-extpack', 'vcard' => 'text/vcard', 'vcd' => 'application/x-cdlink', 'vcf' => 'text/x-vcard', 'vcg' => 'application/vnd.groove-vcard', 'vcs' => 'text/x-vcalendar', 'vcx' => 'application/vnd.vcx', 'vdi' => 'application/x-virtualbox-vdi', 'vds' => 'model/vnd.sap.vds', 'vhd' => 'application/x-virtualbox-vhd', 'vis' => 'application/vnd.visionary', 'viv' => 'video/vnd.vivo', 'vlc' => 'application/videolan', 'vmdk' => 'application/x-virtualbox-vmdk', 'vob' => 'video/x-ms-vob', 'vor' => 'application/vnd.stardivision.writer', 'vox' => 'application/x-authorware-bin', 'vrml' => 'model/vrml', 'vsd' => 'application/vnd.visio', 'vsf' => 'application/vnd.vsf', 'vss' => 'application/vnd.visio', 'vst' => 'application/vnd.visio', 'vsw' => 'application/vnd.visio', 'vtf' => 'image/vnd.valve.source.texture', 'vtt' => 'text/vtt', 'vtu' => 'model/vnd.vtu', 'vxml' => 'application/voicexml+xml', 'w3d' => 'application/x-director', 'wad' => 'application/x-doom', 'wadl' => 'application/vnd.sun.wadl+xml', 'war' => 'application/java-archive', 'wasm' => 'application/wasm', 'wav' => 'audio/x-wav', 'wax' => 'audio/x-ms-wax', 'wbmp' => 'image/vnd.wap.wbmp', 'wbs' => 'application/vnd.criticaltools.wbs+xml', 'wbxml' => 'application/wbxml', 'wcm' => 'application/vnd.ms-works', 'wdb' => 'application/vnd.ms-works', 'wdp' => 'image/vnd.ms-photo', 'weba' => 'audio/webm', 'webapp' => 'application/x-web-app-manifest+json', 'webm' => 'video/webm', 'webmanifest' => 'application/manifest+json', 'webp' => 'image/webp', 'wg' => 'application/vnd.pmi.widget', 'wgsl' => 'text/wgsl', 'wgt' => 'application/widget', 'wif' => 'application/watcherinfo+xml', 'wks' => 'application/vnd.ms-works', 'wm' => 'video/x-ms-wm', 'wma' => 'audio/x-ms-wma', 'wmd' => 'application/x-ms-wmd', 'wmf' => 'image/wmf', 'wml' => 'text/vnd.wap.wml', 'wmlc' => 'application/wmlc', 'wmls' => 'text/vnd.wap.wmlscript', 'wmlsc' => 'application/vnd.wap.wmlscriptc', 'wmv' => 'video/x-ms-wmv', 'wmx' => 'video/x-ms-wmx', 'wmz' => 'application/x-msmetafile', 'woff' => 'font/woff', 'woff2' => 'font/woff2', 'word' => 'application/msword', 'wpd' => 'application/vnd.wordperfect', 'wpl' => 'application/vnd.ms-wpl', 'wps' => 'application/vnd.ms-works', 'wqd' => 'application/vnd.wqd', 'wri' => 'application/x-mswrite', 'wrl' => 'model/vrml', 'wsc' => 'message/vnd.wfa.wsc', 'wsdl' => 'application/wsdl+xml', 'wspolicy' => 'application/wspolicy+xml', 'wtb' => 'application/vnd.webturbo', 'wvx' => 'video/x-ms-wvx', 'x3d' => 'model/x3d+xml', 'x3db' => 'model/x3d+fastinfoset', 'x3dbz' => 'model/x3d+binary', 'x3dv' => 'model/x3d-vrml', 'x3dvz' => 'model/x3d+vrml', 'x3dz' => 'model/x3d+xml', 'x32' => 'application/x-authorware-bin', 'x_b' => 'model/vnd.parasolid.transmit.binary', 'x_t' => 'model/vnd.parasolid.transmit.text', 'xaml' => 'application/xaml+xml', 'xap' => 'application/x-silverlight-app', 'xar' => 'application/vnd.xara', 'xav' => 'application/xcap-att+xml', 'xbap' => 'application/x-ms-xbap', 'xbd' => 'application/vnd.fujixerox.docuworks.binder', 'xbm' => 'image/x-xbitmap', 'xca' => 'application/xcap-caps+xml', 'xcs' => 'application/calendar+xml', 'xdf' => 'application/xcap-diff+xml', 'xdm' => 'application/vnd.syncml.dm+xml', 'xdp' => 'application/vnd.adobe.xdp+xml', 'xdssc' => 'application/dssc+xml', 'xdw' => 'application/vnd.fujixerox.docuworks', 'xel' => 'application/xcap-el+xml', 'xenc' => 'application/xenc+xml', 'xer' => 'application/patch-ops-error+xml', 'xfdf' => 'application/xfdf', 'xfdl' => 'application/vnd.xfdl', 'xht' => 'application/xhtml+xml', 'xhtm' => 'application/vnd.pwg-xhtml-print+xml', 'xhtml' => 'application/xhtml+xml', 'xhvml' => 'application/xv+xml', 'xif' => 'image/vnd.xiff', 'xl' => 'application/excel', 'xla' => 'application/vnd.ms-excel', 'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12', 'xlc' => 'application/vnd.ms-excel', 'xlf' => 'application/xliff+xml', 'xlm' => 'application/vnd.ms-excel', 'xls' => 'application/vnd.ms-excel', 'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12', 'xlsm' => 'application/vnd.ms-excel.sheet.macroEnabled.12', 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'xlt' => 'application/vnd.ms-excel', 'xltm' => 'application/vnd.ms-excel.template.macroEnabled.12', 'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template', 'xlw' => 'application/vnd.ms-excel', 'xm' => 'audio/xm', 'xml' => 'application/xml', 'xns' => 'application/xcap-ns+xml', 'xo' => 'application/vnd.olpc-sugar', 'xop' => 'application/xop+xml', 'xpi' => 'application/x-xpinstall', 'xpl' => 'application/xproc+xml', 'xpm' => 'image/x-xpixmap', 'xpr' => 'application/vnd.is-xpr', 'xps' => 'application/vnd.ms-xpsdocument', 'xpw' => 'application/vnd.intercon.formnet', 'xpx' => 'application/vnd.intercon.formnet', 'xsd' => 'application/xml', 'xsf' => 'application/prs.xsf+xml', 'xsl' => 'application/xml', 'xslt' => 'application/xslt+xml', 'xsm' => 'application/vnd.syncml+xml', 'xspf' => 'application/xspf+xml', 'xul' => 'application/vnd.mozilla.xul+xml', 'xvm' => 'application/xv+xml', 'xvml' => 'application/xv+xml', 'xwd' => 'image/x-xwindowdump', 'xyz' => 'chemical/x-xyz', 'xz' => 'application/x-xz', 'yaml' => 'text/yaml', 'yang' => 'application/yang', 'yin' => 'application/yin+xml', 'yml' => 'text/yaml', 'ymp' => 'text/x-suse-ymp', 'z' => 'application/x-compress', 'z1' => 'application/x-zmachine', 'z2' => 'application/x-zmachine', 'z3' => 'application/x-zmachine', 'z4' => 'application/x-zmachine', 'z5' => 'application/x-zmachine', 'z6' => 'application/x-zmachine', 'z7' => 'application/x-zmachine', 'z8' => 'application/x-zmachine', 'zaz' => 'application/vnd.zzazz.deck+xml', 'zip' => 'application/zip', 'zir' => 'application/vnd.zul', 'zirz' => 'application/vnd.zul', 'zmm' => 'application/vnd.handheld-entertainment+xml', 'zsh' => 'text/x-scriptzsh', ]; /** * Determines the mimetype of a file by looking at its extension. * * @see https://raw.githubusercontent.com/jshttp/mime-db/master/db.json */ public static function fromFilename(string $filename): ?string { return self::fromExtension(pathinfo($filename, PATHINFO_EXTENSION)); } /** * Maps a file extensions to a mimetype. * * @see https://raw.githubusercontent.com/jshttp/mime-db/master/db.json */ public static function fromExtension(string $extension): ?string { return self::MIME_TYPES[strtolower($extension)] ?? null; } } ================================================ FILE: lib/Google/vendor/guzzlehttp/psr7/src/MultipartStream.php ================================================ boundary = $boundary ?: bin2hex(random_bytes(20)); $this->stream = $this->createStream($elements); } public function getBoundary(): string { return $this->boundary; } public function isWritable(): bool { return false; } /** * Get the headers needed before transferring the content of a POST file * * @param string[] $headers */ private function getHeaders(array $headers): string { $str = ''; foreach ($headers as $key => $value) { $str .= "{$key}: {$value}\r\n"; } return "--{$this->boundary}\r\n".trim($str)."\r\n\r\n"; } /** * Create the aggregate stream that will be used to upload the POST data */ protected function createStream(array $elements = []): StreamInterface { $stream = new AppendStream(); foreach ($elements as $element) { if (!is_array($element)) { throw new \UnexpectedValueException('An array is expected'); } $this->addElement($stream, $element); } // Add the trailing boundary with CRLF $stream->addStream(Utils::streamFor("--{$this->boundary}--\r\n")); return $stream; } private function addElement(AppendStream $stream, array $element): void { foreach (['contents', 'name'] as $key) { if (!array_key_exists($key, $element)) { throw new \InvalidArgumentException("A '{$key}' key is required"); } } $element['contents'] = Utils::streamFor($element['contents']); if (empty($element['filename'])) { $uri = $element['contents']->getMetadata('uri'); if ($uri && \is_string($uri) && \substr($uri, 0, 6) !== 'php://' && \substr($uri, 0, 7) !== 'data://') { $element['filename'] = $uri; } } [$body, $headers] = $this->createElement( $element['name'], $element['contents'], $element['filename'] ?? null, $element['headers'] ?? [] ); $stream->addStream(Utils::streamFor($this->getHeaders($headers))); $stream->addStream($body); $stream->addStream(Utils::streamFor("\r\n")); } /** * @param string[] $headers * * @return array{0: StreamInterface, 1: string[]} */ private function createElement(string $name, StreamInterface $stream, ?string $filename, array $headers): array { // Set a default content-disposition header if one was no provided $disposition = self::getHeader($headers, 'content-disposition'); if (!$disposition) { $headers['Content-Disposition'] = ($filename === '0' || $filename) ? sprintf( 'form-data; name="%s"; filename="%s"', $name, basename($filename) ) : "form-data; name=\"{$name}\""; } // Set a default content-length header if one was no provided $length = self::getHeader($headers, 'content-length'); if (!$length) { if ($length = $stream->getSize()) { $headers['Content-Length'] = (string) $length; } } // Set a default Content-Type if one was not supplied $type = self::getHeader($headers, 'content-type'); if (!$type && ($filename === '0' || $filename)) { $headers['Content-Type'] = MimeType::fromFilename($filename) ?? 'application/octet-stream'; } return [$stream, $headers]; } /** * @param string[] $headers */ private static function getHeader(array $headers, string $key): ?string { $lowercaseHeader = strtolower($key); foreach ($headers as $k => $v) { if (strtolower((string) $k) === $lowercaseHeader) { return $v; } } return null; } } ================================================ FILE: lib/Google/vendor/guzzlehttp/psr7/src/NoSeekStream.php ================================================ source = $source; $this->size = $options['size'] ?? null; $this->metadata = $options['metadata'] ?? []; $this->buffer = new BufferStream(); } public function __toString(): string { try { return Utils::copyToString($this); } catch (\Throwable $e) { if (\PHP_VERSION_ID >= 70400) { throw $e; } trigger_error(sprintf('%s::__toString exception: %s', self::class, (string) $e), E_USER_ERROR); return ''; } } public function close(): void { $this->detach(); } public function detach() { $this->tellPos = 0; $this->source = null; return null; } public function getSize(): ?int { return $this->size; } public function tell(): int { return $this->tellPos; } public function eof(): bool { return $this->source === null; } public function isSeekable(): bool { return false; } public function rewind(): void { $this->seek(0); } public function seek($offset, $whence = SEEK_SET): void { throw new \RuntimeException('Cannot seek a PumpStream'); } public function isWritable(): bool { return false; } public function write($string): int { throw new \RuntimeException('Cannot write to a PumpStream'); } public function isReadable(): bool { return true; } public function read($length): string { $data = $this->buffer->read($length); $readLen = strlen($data); $this->tellPos += $readLen; $remaining = $length - $readLen; if ($remaining) { $this->pump($remaining); $data .= $this->buffer->read($remaining); $this->tellPos += strlen($data) - $readLen; } return $data; } public function getContents(): string { $result = ''; while (!$this->eof()) { $result .= $this->read(1000000); } return $result; } /** * @return mixed */ public function getMetadata($key = null) { if (!$key) { return $this->metadata; } return $this->metadata[$key] ?? null; } private function pump(int $length): void { if ($this->source !== null) { do { $data = ($this->source)($length); if ($data === false || $data === null) { $this->source = null; return; } $this->buffer->write($data); $length -= strlen($data); } while ($length > 0); } } } ================================================ FILE: lib/Google/vendor/guzzlehttp/psr7/src/Query.php ================================================ '1', 'foo[b]' => '2'])`. * * @param string $str Query string to parse * @param int|bool $urlEncoding How the query string is encoded */ public static function parse(string $str, $urlEncoding = true): array { $result = []; if ($str === '') { return $result; } if ($urlEncoding === true) { $decoder = function ($value) { return rawurldecode(str_replace('+', ' ', (string) $value)); }; } elseif ($urlEncoding === PHP_QUERY_RFC3986) { $decoder = 'rawurldecode'; } elseif ($urlEncoding === PHP_QUERY_RFC1738) { $decoder = 'urldecode'; } else { $decoder = function ($str) { return $str; }; } foreach (explode('&', $str) as $kvp) { $parts = explode('=', $kvp, 2); $key = $decoder($parts[0]); $value = isset($parts[1]) ? $decoder($parts[1]) : null; if (!array_key_exists($key, $result)) { $result[$key] = $value; } else { if (!is_array($result[$key])) { $result[$key] = [$result[$key]]; } $result[$key][] = $value; } } return $result; } /** * Build a query string from an array of key value pairs. * * This function can use the return value of `parse()` to build a query * string. This function does not modify the provided keys when an array is * encountered (like `http_build_query()` would). * * @param array $params Query string parameters. * @param int|false $encoding Set to false to not encode, * PHP_QUERY_RFC3986 to encode using * RFC3986, or PHP_QUERY_RFC1738 to * encode using RFC1738. * @param bool $treatBoolsAsInts Set to true to encode as 0/1, and * false as false/true. */ public static function build(array $params, $encoding = PHP_QUERY_RFC3986, bool $treatBoolsAsInts = true): string { if (!$params) { return ''; } if ($encoding === false) { $encoder = function (string $str): string { return $str; }; } elseif ($encoding === PHP_QUERY_RFC3986) { $encoder = 'rawurlencode'; } elseif ($encoding === PHP_QUERY_RFC1738) { $encoder = 'urlencode'; } else { throw new \InvalidArgumentException('Invalid type'); } $castBool = $treatBoolsAsInts ? static function ($v) { return (int) $v; } : static function ($v) { return $v ? 'true' : 'false'; }; $qs = ''; foreach ($params as $k => $v) { $k = $encoder((string) $k); if (!is_array($v)) { $qs .= $k; $v = is_bool($v) ? $castBool($v) : $v; if ($v !== null) { $qs .= '='.$encoder((string) $v); } $qs .= '&'; } else { foreach ($v as $vv) { $qs .= $k; $vv = is_bool($vv) ? $castBool($vv) : $vv; if ($vv !== null) { $qs .= '='.$encoder((string) $vv); } $qs .= '&'; } } } return $qs ? (string) substr($qs, 0, -1) : ''; } } ================================================ FILE: lib/Google/vendor/guzzlehttp/psr7/src/Request.php ================================================ assertMethod($method); if (!($uri instanceof UriInterface)) { $uri = new Uri($uri); } $this->method = strtoupper($method); $this->uri = $uri; $this->setHeaders($headers); $this->protocol = $version; if (!isset($this->headerNames['host'])) { $this->updateHostFromUri(); } if ($body !== '' && $body !== null) { $this->stream = Utils::streamFor($body); } } public function getRequestTarget(): string { if ($this->requestTarget !== null) { return $this->requestTarget; } $target = $this->uri->getPath(); if ($target === '') { $target = '/'; } if ($this->uri->getQuery() != '') { $target .= '?'.$this->uri->getQuery(); } return $target; } public function withRequestTarget($requestTarget): RequestInterface { if (preg_match('#\s#', $requestTarget)) { throw new InvalidArgumentException( 'Invalid request target provided; cannot contain whitespace' ); } $new = clone $this; $new->requestTarget = $requestTarget; return $new; } public function getMethod(): string { return $this->method; } public function withMethod($method): RequestInterface { $this->assertMethod($method); $new = clone $this; $new->method = strtoupper($method); return $new; } public function getUri(): UriInterface { return $this->uri; } public function withUri(UriInterface $uri, $preserveHost = false): RequestInterface { if ($uri === $this->uri) { return $this; } $new = clone $this; $new->uri = $uri; if (!$preserveHost || !isset($this->headerNames['host'])) { $new->updateHostFromUri(); } return $new; } private function updateHostFromUri(): void { $host = $this->uri->getHost(); if ($host == '') { return; } if (($port = $this->uri->getPort()) !== null) { $host .= ':'.$port; } if (isset($this->headerNames['host'])) { $header = $this->headerNames['host']; } else { $header = 'Host'; $this->headerNames['host'] = 'Host'; } // Ensure Host is the first header. // See: https://datatracker.ietf.org/doc/html/rfc7230#section-5.4 $this->headers = [$header => [$host]] + $this->headers; } /** * @param mixed $method */ private function assertMethod($method): void { if (!is_string($method) || $method === '') { throw new InvalidArgumentException('Method must be a non-empty string.'); } } } ================================================ FILE: lib/Google/vendor/guzzlehttp/psr7/src/Response.php ================================================ 'Continue', 101 => 'Switching Protocols', 102 => 'Processing', 200 => 'OK', 201 => 'Created', 202 => 'Accepted', 203 => 'Non-Authoritative Information', 204 => 'No Content', 205 => 'Reset Content', 206 => 'Partial Content', 207 => 'Multi-status', 208 => 'Already Reported', 300 => 'Multiple Choices', 301 => 'Moved Permanently', 302 => 'Found', 303 => 'See Other', 304 => 'Not Modified', 305 => 'Use Proxy', 306 => 'Switch Proxy', 307 => 'Temporary Redirect', 308 => 'Permanent Redirect', 400 => 'Bad Request', 401 => 'Unauthorized', 402 => 'Payment Required', 403 => 'Forbidden', 404 => 'Not Found', 405 => 'Method Not Allowed', 406 => 'Not Acceptable', 407 => 'Proxy Authentication Required', 408 => 'Request Time-out', 409 => 'Conflict', 410 => 'Gone', 411 => 'Length Required', 412 => 'Precondition Failed', 413 => 'Request Entity Too Large', 414 => 'Request-URI Too Large', 415 => 'Unsupported Media Type', 416 => 'Requested range not satisfiable', 417 => 'Expectation Failed', 418 => 'I\'m a teapot', 422 => 'Unprocessable Entity', 423 => 'Locked', 424 => 'Failed Dependency', 425 => 'Unordered Collection', 426 => 'Upgrade Required', 428 => 'Precondition Required', 429 => 'Too Many Requests', 431 => 'Request Header Fields Too Large', 451 => 'Unavailable For Legal Reasons', 500 => 'Internal Server Error', 501 => 'Not Implemented', 502 => 'Bad Gateway', 503 => 'Service Unavailable', 504 => 'Gateway Time-out', 505 => 'HTTP Version not supported', 506 => 'Variant Also Negotiates', 507 => 'Insufficient Storage', 508 => 'Loop Detected', 510 => 'Not Extended', 511 => 'Network Authentication Required', ]; /** @var string */ private $reasonPhrase; /** @var int */ private $statusCode; /** * @param int $status Status code * @param (string|string[])[] $headers Response headers * @param string|resource|StreamInterface|null $body Response body * @param string $version Protocol version * @param string|null $reason Reason phrase (when empty a default will be used based on the status code) */ public function __construct( int $status = 200, array $headers = [], $body = null, string $version = '1.1', ?string $reason = null ) { $this->assertStatusCodeRange($status); $this->statusCode = $status; if ($body !== '' && $body !== null) { $this->stream = Utils::streamFor($body); } $this->setHeaders($headers); if ($reason == '' && isset(self::PHRASES[$this->statusCode])) { $this->reasonPhrase = self::PHRASES[$this->statusCode]; } else { $this->reasonPhrase = (string) $reason; } $this->protocol = $version; } public function getStatusCode(): int { return $this->statusCode; } public function getReasonPhrase(): string { return $this->reasonPhrase; } public function withStatus($code, $reasonPhrase = ''): ResponseInterface { $this->assertStatusCodeIsInteger($code); $code = (int) $code; $this->assertStatusCodeRange($code); $new = clone $this; $new->statusCode = $code; if ($reasonPhrase == '' && isset(self::PHRASES[$new->statusCode])) { $reasonPhrase = self::PHRASES[$new->statusCode]; } $new->reasonPhrase = (string) $reasonPhrase; return $new; } /** * @param mixed $statusCode */ private function assertStatusCodeIsInteger($statusCode): void { if (filter_var($statusCode, FILTER_VALIDATE_INT) === false) { throw new \InvalidArgumentException('Status code must be an integer value.'); } } private function assertStatusCodeRange(int $statusCode): void { if ($statusCode < 100 || $statusCode >= 600) { throw new \InvalidArgumentException('Status code must be an integer value between 1xx and 5xx.'); } } } ================================================ FILE: lib/Google/vendor/guzzlehttp/psr7/src/Rfc7230.php ================================================ @,;:\\\"/[\]?={}\x01-\x20\x7F]++):[ \t]*+((?:[ \t]*+[\x21-\x7E\x80-\xFF]++)*+)[ \t]*+\r?\n)m"; public const HEADER_FOLD_REGEX = "(\r?\n[ \t]++)"; } ================================================ FILE: lib/Google/vendor/guzzlehttp/psr7/src/ServerRequest.php ================================================ serverParams = $serverParams; parent::__construct($method, $uri, $headers, $body, $version); } /** * Return an UploadedFile instance array. * * @param array $files An array which respect $_FILES structure * * @throws InvalidArgumentException for unrecognized values */ public static function normalizeFiles(array $files): array { $normalized = []; foreach ($files as $key => $value) { if ($value instanceof UploadedFileInterface) { $normalized[$key] = $value; } elseif (is_array($value) && isset($value['tmp_name'])) { $normalized[$key] = self::createUploadedFileFromSpec($value); } elseif (is_array($value)) { $normalized[$key] = self::normalizeFiles($value); continue; } else { throw new InvalidArgumentException('Invalid value in files specification'); } } return $normalized; } /** * Create and return an UploadedFile instance from a $_FILES specification. * * If the specification represents an array of values, this method will * delegate to normalizeNestedFileSpec() and return that return value. * * @param array $value $_FILES struct * * @return UploadedFileInterface|UploadedFileInterface[] */ private static function createUploadedFileFromSpec(array $value) { if (is_array($value['tmp_name'])) { return self::normalizeNestedFileSpec($value); } return new UploadedFile( $value['tmp_name'], (int) $value['size'], (int) $value['error'], $value['name'], $value['type'] ); } /** * Normalize an array of file specifications. * * Loops through all nested files and returns a normalized array of * UploadedFileInterface instances. * * @return UploadedFileInterface[] */ private static function normalizeNestedFileSpec(array $files = []): array { $normalizedFiles = []; foreach (array_keys($files['tmp_name']) as $key) { $spec = [ 'tmp_name' => $files['tmp_name'][$key], 'size' => $files['size'][$key] ?? null, 'error' => $files['error'][$key] ?? null, 'name' => $files['name'][$key] ?? null, 'type' => $files['type'][$key] ?? null, ]; $normalizedFiles[$key] = self::createUploadedFileFromSpec($spec); } return $normalizedFiles; } /** * Return a ServerRequest populated with superglobals: * $_GET * $_POST * $_COOKIE * $_FILES * $_SERVER */ public static function fromGlobals(): ServerRequestInterface { $method = $_SERVER['REQUEST_METHOD'] ?? 'GET'; $headers = getallheaders(); $uri = self::getUriFromGlobals(); $body = new CachingStream(new LazyOpenStream('php://input', 'r+')); $protocol = isset($_SERVER['SERVER_PROTOCOL']) ? str_replace('HTTP/', '', $_SERVER['SERVER_PROTOCOL']) : '1.1'; $serverRequest = new ServerRequest($method, $uri, $headers, $body, $protocol, $_SERVER); return $serverRequest ->withCookieParams($_COOKIE) ->withQueryParams($_GET) ->withParsedBody($_POST) ->withUploadedFiles(self::normalizeFiles($_FILES)); } private static function extractHostAndPortFromAuthority(string $authority): array { $uri = 'http://'.$authority; $parts = parse_url($uri); if (false === $parts) { return [null, null]; } $host = $parts['host'] ?? null; $port = $parts['port'] ?? null; return [$host, $port]; } /** * Get a Uri populated with values from $_SERVER. */ public static function getUriFromGlobals(): UriInterface { $uri = new Uri(''); $uri = $uri->withScheme(!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' ? 'https' : 'http'); $hasPort = false; if (isset($_SERVER['HTTP_HOST'])) { [$host, $port] = self::extractHostAndPortFromAuthority($_SERVER['HTTP_HOST']); if ($host !== null) { $uri = $uri->withHost($host); } if ($port !== null) { $hasPort = true; $uri = $uri->withPort($port); } } elseif (isset($_SERVER['SERVER_NAME'])) { $uri = $uri->withHost($_SERVER['SERVER_NAME']); } elseif (isset($_SERVER['SERVER_ADDR'])) { $uri = $uri->withHost($_SERVER['SERVER_ADDR']); } if (!$hasPort && isset($_SERVER['SERVER_PORT'])) { $uri = $uri->withPort($_SERVER['SERVER_PORT']); } $hasQuery = false; if (isset($_SERVER['REQUEST_URI'])) { $requestUriParts = explode('?', $_SERVER['REQUEST_URI'], 2); $uri = $uri->withPath($requestUriParts[0]); if (isset($requestUriParts[1])) { $hasQuery = true; $uri = $uri->withQuery($requestUriParts[1]); } } if (!$hasQuery && isset($_SERVER['QUERY_STRING'])) { $uri = $uri->withQuery($_SERVER['QUERY_STRING']); } return $uri; } public function getServerParams(): array { return $this->serverParams; } public function getUploadedFiles(): array { return $this->uploadedFiles; } public function withUploadedFiles(array $uploadedFiles): ServerRequestInterface { $new = clone $this; $new->uploadedFiles = $uploadedFiles; return $new; } public function getCookieParams(): array { return $this->cookieParams; } public function withCookieParams(array $cookies): ServerRequestInterface { $new = clone $this; $new->cookieParams = $cookies; return $new; } public function getQueryParams(): array { return $this->queryParams; } public function withQueryParams(array $query): ServerRequestInterface { $new = clone $this; $new->queryParams = $query; return $new; } /** * @return array|object|null */ public function getParsedBody() { return $this->parsedBody; } public function withParsedBody($data): ServerRequestInterface { $new = clone $this; $new->parsedBody = $data; return $new; } public function getAttributes(): array { return $this->attributes; } /** * @return mixed */ public function getAttribute($attribute, $default = null) { if (false === array_key_exists($attribute, $this->attributes)) { return $default; } return $this->attributes[$attribute]; } public function withAttribute($attribute, $value): ServerRequestInterface { $new = clone $this; $new->attributes[$attribute] = $value; return $new; } public function withoutAttribute($attribute): ServerRequestInterface { if (false === array_key_exists($attribute, $this->attributes)) { return $this; } $new = clone $this; unset($new->attributes[$attribute]); return $new; } } ================================================ FILE: lib/Google/vendor/guzzlehttp/psr7/src/Stream.php ================================================ size = $options['size']; } $this->customMetadata = $options['metadata'] ?? []; $this->stream = $stream; $meta = stream_get_meta_data($this->stream); $this->seekable = $meta['seekable']; $this->readable = (bool) preg_match(self::READABLE_MODES, $meta['mode']); $this->writable = (bool) preg_match(self::WRITABLE_MODES, $meta['mode']); $this->uri = $this->getMetadata('uri'); } /** * Closes the stream when the destructed */ public function __destruct() { $this->close(); } public function __toString(): string { try { if ($this->isSeekable()) { $this->seek(0); } return $this->getContents(); } catch (\Throwable $e) { if (\PHP_VERSION_ID >= 70400) { throw $e; } trigger_error(sprintf('%s::__toString exception: %s', self::class, (string) $e), E_USER_ERROR); return ''; } } public function getContents(): string { if (!isset($this->stream)) { throw new \RuntimeException('Stream is detached'); } if (!$this->readable) { throw new \RuntimeException('Cannot read from non-readable stream'); } return Utils::tryGetContents($this->stream); } public function close(): void { if (isset($this->stream)) { if (is_resource($this->stream)) { fclose($this->stream); } $this->detach(); } } public function detach() { if (!isset($this->stream)) { return null; } $result = $this->stream; unset($this->stream); $this->size = $this->uri = null; $this->readable = $this->writable = $this->seekable = false; return $result; } public function getSize(): ?int { if ($this->size !== null) { return $this->size; } if (!isset($this->stream)) { return null; } // Clear the stat cache if the stream has a URI if ($this->uri) { clearstatcache(true, $this->uri); } $stats = fstat($this->stream); if (is_array($stats) && isset($stats['size'])) { $this->size = $stats['size']; return $this->size; } return null; } public function isReadable(): bool { return $this->readable; } public function isWritable(): bool { return $this->writable; } public function isSeekable(): bool { return $this->seekable; } public function eof(): bool { if (!isset($this->stream)) { throw new \RuntimeException('Stream is detached'); } return feof($this->stream); } public function tell(): int { if (!isset($this->stream)) { throw new \RuntimeException('Stream is detached'); } $result = ftell($this->stream); if ($result === false) { throw new \RuntimeException('Unable to determine stream position'); } return $result; } public function rewind(): void { $this->seek(0); } public function seek($offset, $whence = SEEK_SET): void { $whence = (int) $whence; if (!isset($this->stream)) { throw new \RuntimeException('Stream is detached'); } if (!$this->seekable) { throw new \RuntimeException('Stream is not seekable'); } if (fseek($this->stream, $offset, $whence) === -1) { throw new \RuntimeException('Unable to seek to stream position ' .$offset.' with whence '.var_export($whence, true)); } } public function read($length): string { if (!isset($this->stream)) { throw new \RuntimeException('Stream is detached'); } if (!$this->readable) { throw new \RuntimeException('Cannot read from non-readable stream'); } if ($length < 0) { throw new \RuntimeException('Length parameter cannot be negative'); } if (0 === $length) { return ''; } try { $string = fread($this->stream, $length); } catch (\Exception $e) { throw new \RuntimeException('Unable to read from stream', 0, $e); } if (false === $string) { throw new \RuntimeException('Unable to read from stream'); } return $string; } public function write($string): int { if (!isset($this->stream)) { throw new \RuntimeException('Stream is detached'); } if (!$this->writable) { throw new \RuntimeException('Cannot write to a non-writable stream'); } // We can't know the size after writing anything $this->size = null; $result = fwrite($this->stream, $string); if ($result === false) { throw new \RuntimeException('Unable to write to stream'); } return $result; } /** * @return mixed */ public function getMetadata($key = null) { if (!isset($this->stream)) { return $key ? null : []; } elseif (!$key) { return $this->customMetadata + stream_get_meta_data($this->stream); } elseif (isset($this->customMetadata[$key])) { return $this->customMetadata[$key]; } $meta = stream_get_meta_data($this->stream); return $meta[$key] ?? null; } } ================================================ FILE: lib/Google/vendor/guzzlehttp/psr7/src/StreamDecoratorTrait.php ================================================ stream = $stream; } /** * Magic method used to create a new stream if streams are not added in * the constructor of a decorator (e.g., LazyOpenStream). * * @return StreamInterface */ public function __get(string $name) { if ($name === 'stream') { $this->stream = $this->createStream(); return $this->stream; } throw new \UnexpectedValueException("$name not found on class"); } public function __toString(): string { try { if ($this->isSeekable()) { $this->seek(0); } return $this->getContents(); } catch (\Throwable $e) { if (\PHP_VERSION_ID >= 70400) { throw $e; } trigger_error(sprintf('%s::__toString exception: %s', self::class, (string) $e), E_USER_ERROR); return ''; } } public function getContents(): string { return Utils::copyToString($this); } /** * Allow decorators to implement custom methods * * @return mixed */ public function __call(string $method, array $args) { /** @var callable $callable */ $callable = [$this->stream, $method]; $result = ($callable)(...$args); // Always return the wrapped object if the result is a return $this return $result === $this->stream ? $this : $result; } public function close(): void { $this->stream->close(); } /** * @return mixed */ public function getMetadata($key = null) { return $this->stream->getMetadata($key); } public function detach() { return $this->stream->detach(); } public function getSize(): ?int { return $this->stream->getSize(); } public function eof(): bool { return $this->stream->eof(); } public function tell(): int { return $this->stream->tell(); } public function isReadable(): bool { return $this->stream->isReadable(); } public function isWritable(): bool { return $this->stream->isWritable(); } public function isSeekable(): bool { return $this->stream->isSeekable(); } public function rewind(): void { $this->seek(0); } public function seek($offset, $whence = SEEK_SET): void { $this->stream->seek($offset, $whence); } public function read($length): string { return $this->stream->read($length); } public function write($string): int { return $this->stream->write($string); } /** * Implement in subclasses to dynamically create streams when requested. * * @throws \BadMethodCallException */ protected function createStream(): StreamInterface { throw new \BadMethodCallException('Not implemented'); } } ================================================ FILE: lib/Google/vendor/guzzlehttp/psr7/src/StreamWrapper.php ================================================ isReadable()) { $mode = $stream->isWritable() ? 'r+' : 'r'; } elseif ($stream->isWritable()) { $mode = 'w'; } else { throw new \InvalidArgumentException('The stream must be readable, ' .'writable, or both.'); } return fopen('guzzle://stream', $mode, false, self::createStreamContext($stream)); } /** * Creates a stream context that can be used to open a stream as a php stream resource. * * @return resource */ public static function createStreamContext(StreamInterface $stream) { return stream_context_create([ 'guzzle' => ['stream' => $stream], ]); } /** * Registers the stream wrapper if needed */ public static function register(): void { if (!in_array('guzzle', stream_get_wrappers())) { stream_wrapper_register('guzzle', __CLASS__); } } public function stream_open(string $path, string $mode, int $options, ?string &$opened_path = null): bool { $options = stream_context_get_options($this->context); if (!isset($options['guzzle']['stream'])) { return false; } $this->mode = $mode; $this->stream = $options['guzzle']['stream']; return true; } public function stream_read(int $count): string { return $this->stream->read($count); } public function stream_write(string $data): int { return $this->stream->write($data); } public function stream_tell(): int { return $this->stream->tell(); } public function stream_eof(): bool { return $this->stream->eof(); } public function stream_seek(int $offset, int $whence): bool { $this->stream->seek($offset, $whence); return true; } /** * @return resource|false */ public function stream_cast(int $cast_as) { $stream = clone $this->stream; $resource = $stream->detach(); return $resource ?? false; } /** * @return array{ * dev: int, * ino: int, * mode: int, * nlink: int, * uid: int, * gid: int, * rdev: int, * size: int, * atime: int, * mtime: int, * ctime: int, * blksize: int, * blocks: int * }|false */ public function stream_stat() { if ($this->stream->getSize() === null) { return false; } static $modeMap = [ 'r' => 33060, 'rb' => 33060, 'r+' => 33206, 'w' => 33188, 'wb' => 33188, ]; return [ 'dev' => 0, 'ino' => 0, 'mode' => $modeMap[$this->mode], 'nlink' => 0, 'uid' => 0, 'gid' => 0, 'rdev' => 0, 'size' => $this->stream->getSize() ?: 0, 'atime' => 0, 'mtime' => 0, 'ctime' => 0, 'blksize' => 0, 'blocks' => 0, ]; } /** * @return array{ * dev: int, * ino: int, * mode: int, * nlink: int, * uid: int, * gid: int, * rdev: int, * size: int, * atime: int, * mtime: int, * ctime: int, * blksize: int, * blocks: int * } */ public function url_stat(string $path, int $flags): array { return [ 'dev' => 0, 'ino' => 0, 'mode' => 0, 'nlink' => 0, 'uid' => 0, 'gid' => 0, 'rdev' => 0, 'size' => 0, 'atime' => 0, 'mtime' => 0, 'ctime' => 0, 'blksize' => 0, 'blocks' => 0, ]; } } ================================================ FILE: lib/Google/vendor/guzzlehttp/psr7/src/UploadedFile.php ================================================ 'UPLOAD_ERR_OK', UPLOAD_ERR_INI_SIZE => 'UPLOAD_ERR_INI_SIZE', UPLOAD_ERR_FORM_SIZE => 'UPLOAD_ERR_FORM_SIZE', UPLOAD_ERR_PARTIAL => 'UPLOAD_ERR_PARTIAL', UPLOAD_ERR_NO_FILE => 'UPLOAD_ERR_NO_FILE', UPLOAD_ERR_NO_TMP_DIR => 'UPLOAD_ERR_NO_TMP_DIR', UPLOAD_ERR_CANT_WRITE => 'UPLOAD_ERR_CANT_WRITE', UPLOAD_ERR_EXTENSION => 'UPLOAD_ERR_EXTENSION', ]; /** * @var string|null */ private $clientFilename; /** * @var string|null */ private $clientMediaType; /** * @var int */ private $error; /** * @var string|null */ private $file; /** * @var bool */ private $moved = false; /** * @var int|null */ private $size; /** * @var StreamInterface|null */ private $stream; /** * @param StreamInterface|string|resource $streamOrFile */ public function __construct( $streamOrFile, ?int $size, int $errorStatus, ?string $clientFilename = null, ?string $clientMediaType = null ) { $this->setError($errorStatus); $this->size = $size; $this->clientFilename = $clientFilename; $this->clientMediaType = $clientMediaType; if ($this->isOk()) { $this->setStreamOrFile($streamOrFile); } } /** * Depending on the value set file or stream variable * * @param StreamInterface|string|resource $streamOrFile * * @throws InvalidArgumentException */ private function setStreamOrFile($streamOrFile): void { if (is_string($streamOrFile)) { $this->file = $streamOrFile; } elseif (is_resource($streamOrFile)) { $this->stream = new Stream($streamOrFile); } elseif ($streamOrFile instanceof StreamInterface) { $this->stream = $streamOrFile; } else { throw new InvalidArgumentException( 'Invalid stream or file provided for UploadedFile' ); } } /** * @throws InvalidArgumentException */ private function setError(int $error): void { if (!isset(UploadedFile::ERROR_MAP[$error])) { throw new InvalidArgumentException( 'Invalid error status for UploadedFile' ); } $this->error = $error; } private static function isStringNotEmpty($param): bool { return is_string($param) && false === empty($param); } /** * Return true if there is no upload error */ private function isOk(): bool { return $this->error === UPLOAD_ERR_OK; } public function isMoved(): bool { return $this->moved; } /** * @throws RuntimeException if is moved or not ok */ private function validateActive(): void { if (false === $this->isOk()) { throw new RuntimeException(\sprintf('Cannot retrieve stream due to upload error (%s)', self::ERROR_MAP[$this->error])); } if ($this->isMoved()) { throw new RuntimeException('Cannot retrieve stream after it has already been moved'); } } public function getStream(): StreamInterface { $this->validateActive(); if ($this->stream instanceof StreamInterface) { return $this->stream; } /** @var string $file */ $file = $this->file; return new LazyOpenStream($file, 'r+'); } public function moveTo($targetPath): void { $this->validateActive(); if (false === self::isStringNotEmpty($targetPath)) { throw new InvalidArgumentException( 'Invalid path provided for move operation; must be a non-empty string' ); } if ($this->file) { $this->moved = PHP_SAPI === 'cli' ? rename($this->file, $targetPath) : move_uploaded_file($this->file, $targetPath); } else { Utils::copyToStream( $this->getStream(), new LazyOpenStream($targetPath, 'w') ); $this->moved = true; } if (false === $this->moved) { throw new RuntimeException( sprintf('Uploaded file could not be moved to %s', $targetPath) ); } } public function getSize(): ?int { return $this->size; } public function getError(): int { return $this->error; } public function getClientFilename(): ?string { return $this->clientFilename; } public function getClientMediaType(): ?string { return $this->clientMediaType; } } ================================================ FILE: lib/Google/vendor/guzzlehttp/psr7/src/Uri.php ================================================ 80, 'https' => 443, 'ftp' => 21, 'gopher' => 70, 'nntp' => 119, 'news' => 119, 'telnet' => 23, 'tn3270' => 23, 'imap' => 143, 'pop' => 110, 'ldap' => 389, ]; /** * Unreserved characters for use in a regex. * * @see https://datatracker.ietf.org/doc/html/rfc3986#section-2.3 */ private const CHAR_UNRESERVED = 'a-zA-Z0-9_\-\.~'; /** * Sub-delims for use in a regex. * * @see https://datatracker.ietf.org/doc/html/rfc3986#section-2.2 */ private const CHAR_SUB_DELIMS = '!\$&\'\(\)\*\+,;='; private const QUERY_SEPARATORS_REPLACEMENT = ['=' => '%3D', '&' => '%26']; /** @var string Uri scheme. */ private $scheme = ''; /** @var string Uri user info. */ private $userInfo = ''; /** @var string Uri host. */ private $host = ''; /** @var int|null Uri port. */ private $port; /** @var string Uri path. */ private $path = ''; /** @var string Uri query string. */ private $query = ''; /** @var string Uri fragment. */ private $fragment = ''; /** @var string|null String representation */ private $composedComponents; public function __construct(string $uri = '') { if ($uri !== '') { $parts = self::parse($uri); if ($parts === false) { throw new MalformedUriException("Unable to parse URI: $uri"); } $this->applyParts($parts); } } /** * UTF-8 aware \parse_url() replacement. * * The internal function produces broken output for non ASCII domain names * (IDN) when used with locales other than "C". * * On the other hand, cURL understands IDN correctly only when UTF-8 locale * is configured ("C.UTF-8", "en_US.UTF-8", etc.). * * @see https://bugs.php.net/bug.php?id=52923 * @see https://www.php.net/manual/en/function.parse-url.php#114817 * @see https://curl.haxx.se/libcurl/c/CURLOPT_URL.html#ENCODING * * @return array|false */ private static function parse(string $url) { // If IPv6 $prefix = ''; if (preg_match('%^(.*://\[[0-9:a-fA-F]+\])(.*?)$%', $url, $matches)) { /** @var array{0:string, 1:string, 2:string} $matches */ $prefix = $matches[1]; $url = $matches[2]; } /** @var string */ $encodedUrl = preg_replace_callback( '%[^:/@?&=#]+%usD', static function ($matches) { return urlencode($matches[0]); }, $url ); $result = parse_url($prefix.$encodedUrl); if ($result === false) { return false; } return array_map('urldecode', $result); } public function __toString(): string { if ($this->composedComponents === null) { $this->composedComponents = self::composeComponents( $this->scheme, $this->getAuthority(), $this->path, $this->query, $this->fragment ); } return $this->composedComponents; } /** * Composes a URI reference string from its various components. * * Usually this method does not need to be called manually but instead is used indirectly via * `Psr\Http\Message\UriInterface::__toString`. * * PSR-7 UriInterface treats an empty component the same as a missing component as * getQuery(), getFragment() etc. always return a string. This explains the slight * difference to RFC 3986 Section 5.3. * * Another adjustment is that the authority separator is added even when the authority is missing/empty * for the "file" scheme. This is because PHP stream functions like `file_get_contents` only work with * `file:///myfile` but not with `file:/myfile` although they are equivalent according to RFC 3986. But * `file:///` is the more common syntax for the file scheme anyway (Chrome for example redirects to * that format). * * @see https://datatracker.ietf.org/doc/html/rfc3986#section-5.3 */ public static function composeComponents(?string $scheme, ?string $authority, string $path, ?string $query, ?string $fragment): string { $uri = ''; // weak type checks to also accept null until we can add scalar type hints if ($scheme != '') { $uri .= $scheme.':'; } if ($authority != '' || $scheme === 'file') { $uri .= '//'.$authority; } if ($authority != '' && $path != '' && $path[0] != '/') { $path = '/'.$path; } $uri .= $path; if ($query != '') { $uri .= '?'.$query; } if ($fragment != '') { $uri .= '#'.$fragment; } return $uri; } /** * Whether the URI has the default port of the current scheme. * * `Psr\Http\Message\UriInterface::getPort` may return null or the standard port. This method can be used * independently of the implementation. */ public static function isDefaultPort(UriInterface $uri): bool { return $uri->getPort() === null || (isset(self::DEFAULT_PORTS[$uri->getScheme()]) && $uri->getPort() === self::DEFAULT_PORTS[$uri->getScheme()]); } /** * Whether the URI is absolute, i.e. it has a scheme. * * An instance of UriInterface can either be an absolute URI or a relative reference. This method returns true * if it is the former. An absolute URI has a scheme. A relative reference is used to express a URI relative * to another URI, the base URI. Relative references can be divided into several forms: * - network-path references, e.g. '//example.com/path' * - absolute-path references, e.g. '/path' * - relative-path references, e.g. 'subpath' * * @see Uri::isNetworkPathReference * @see Uri::isAbsolutePathReference * @see Uri::isRelativePathReference * @see https://datatracker.ietf.org/doc/html/rfc3986#section-4 */ public static function isAbsolute(UriInterface $uri): bool { return $uri->getScheme() !== ''; } /** * Whether the URI is a network-path reference. * * A relative reference that begins with two slash characters is termed an network-path reference. * * @see https://datatracker.ietf.org/doc/html/rfc3986#section-4.2 */ public static function isNetworkPathReference(UriInterface $uri): bool { return $uri->getScheme() === '' && $uri->getAuthority() !== ''; } /** * Whether the URI is a absolute-path reference. * * A relative reference that begins with a single slash character is termed an absolute-path reference. * * @see https://datatracker.ietf.org/doc/html/rfc3986#section-4.2 */ public static function isAbsolutePathReference(UriInterface $uri): bool { return $uri->getScheme() === '' && $uri->getAuthority() === '' && isset($uri->getPath()[0]) && $uri->getPath()[0] === '/'; } /** * Whether the URI is a relative-path reference. * * A relative reference that does not begin with a slash character is termed a relative-path reference. * * @see https://datatracker.ietf.org/doc/html/rfc3986#section-4.2 */ public static function isRelativePathReference(UriInterface $uri): bool { return $uri->getScheme() === '' && $uri->getAuthority() === '' && (!isset($uri->getPath()[0]) || $uri->getPath()[0] !== '/'); } /** * Whether the URI is a same-document reference. * * A same-document reference refers to a URI that is, aside from its fragment * component, identical to the base URI. When no base URI is given, only an empty * URI reference (apart from its fragment) is considered a same-document reference. * * @param UriInterface $uri The URI to check * @param UriInterface|null $base An optional base URI to compare against * * @see https://datatracker.ietf.org/doc/html/rfc3986#section-4.4 */ public static function isSameDocumentReference(UriInterface $uri, ?UriInterface $base = null): bool { if ($base !== null) { $uri = UriResolver::resolve($base, $uri); return ($uri->getScheme() === $base->getScheme()) && ($uri->getAuthority() === $base->getAuthority()) && ($uri->getPath() === $base->getPath()) && ($uri->getQuery() === $base->getQuery()); } return $uri->getScheme() === '' && $uri->getAuthority() === '' && $uri->getPath() === '' && $uri->getQuery() === ''; } /** * Creates a new URI with a specific query string value removed. * * Any existing query string values that exactly match the provided key are * removed. * * @param UriInterface $uri URI to use as a base. * @param string $key Query string key to remove. */ public static function withoutQueryValue(UriInterface $uri, string $key): UriInterface { $result = self::getFilteredQueryString($uri, [$key]); return $uri->withQuery(implode('&', $result)); } /** * Creates a new URI with a specific query string value. * * Any existing query string values that exactly match the provided key are * removed and replaced with the given key value pair. * * A value of null will set the query string key without a value, e.g. "key" * instead of "key=value". * * @param UriInterface $uri URI to use as a base. * @param string $key Key to set. * @param string|null $value Value to set */ public static function withQueryValue(UriInterface $uri, string $key, ?string $value): UriInterface { $result = self::getFilteredQueryString($uri, [$key]); $result[] = self::generateQueryString($key, $value); return $uri->withQuery(implode('&', $result)); } /** * Creates a new URI with multiple specific query string values. * * It has the same behavior as withQueryValue() but for an associative array of key => value. * * @param UriInterface $uri URI to use as a base. * @param (string|null)[] $keyValueArray Associative array of key and values */ public static function withQueryValues(UriInterface $uri, array $keyValueArray): UriInterface { $result = self::getFilteredQueryString($uri, array_keys($keyValueArray)); foreach ($keyValueArray as $key => $value) { $result[] = self::generateQueryString((string) $key, $value !== null ? (string) $value : null); } return $uri->withQuery(implode('&', $result)); } /** * Creates a URI from a hash of `parse_url` components. * * @see https://www.php.net/manual/en/function.parse-url.php * * @throws MalformedUriException If the components do not form a valid URI. */ public static function fromParts(array $parts): UriInterface { $uri = new self(); $uri->applyParts($parts); $uri->validateState(); return $uri; } public function getScheme(): string { return $this->scheme; } public function getAuthority(): string { $authority = $this->host; if ($this->userInfo !== '') { $authority = $this->userInfo.'@'.$authority; } if ($this->port !== null) { $authority .= ':'.$this->port; } return $authority; } public function getUserInfo(): string { return $this->userInfo; } public function getHost(): string { return $this->host; } public function getPort(): ?int { return $this->port; } public function getPath(): string { return $this->path; } public function getQuery(): string { return $this->query; } public function getFragment(): string { return $this->fragment; } public function withScheme($scheme): UriInterface { $scheme = $this->filterScheme($scheme); if ($this->scheme === $scheme) { return $this; } $new = clone $this; $new->scheme = $scheme; $new->composedComponents = null; $new->removeDefaultPort(); $new->validateState(); return $new; } public function withUserInfo($user, $password = null): UriInterface { $info = $this->filterUserInfoComponent($user); if ($password !== null) { $info .= ':'.$this->filterUserInfoComponent($password); } if ($this->userInfo === $info) { return $this; } $new = clone $this; $new->userInfo = $info; $new->composedComponents = null; $new->validateState(); return $new; } public function withHost($host): UriInterface { $host = $this->filterHost($host); if ($this->host === $host) { return $this; } $new = clone $this; $new->host = $host; $new->composedComponents = null; $new->validateState(); return $new; } public function withPort($port): UriInterface { $port = $this->filterPort($port); if ($this->port === $port) { return $this; } $new = clone $this; $new->port = $port; $new->composedComponents = null; $new->removeDefaultPort(); $new->validateState(); return $new; } public function withPath($path): UriInterface { $path = $this->filterPath($path); if ($this->path === $path) { return $this; } $new = clone $this; $new->path = $path; $new->composedComponents = null; $new->validateState(); return $new; } public function withQuery($query): UriInterface { $query = $this->filterQueryAndFragment($query); if ($this->query === $query) { return $this; } $new = clone $this; $new->query = $query; $new->composedComponents = null; return $new; } public function withFragment($fragment): UriInterface { $fragment = $this->filterQueryAndFragment($fragment); if ($this->fragment === $fragment) { return $this; } $new = clone $this; $new->fragment = $fragment; $new->composedComponents = null; return $new; } public function jsonSerialize(): string { return $this->__toString(); } /** * Apply parse_url parts to a URI. * * @param array $parts Array of parse_url parts to apply. */ private function applyParts(array $parts): void { $this->scheme = isset($parts['scheme']) ? $this->filterScheme($parts['scheme']) : ''; $this->userInfo = isset($parts['user']) ? $this->filterUserInfoComponent($parts['user']) : ''; $this->host = isset($parts['host']) ? $this->filterHost($parts['host']) : ''; $this->port = isset($parts['port']) ? $this->filterPort($parts['port']) : null; $this->path = isset($parts['path']) ? $this->filterPath($parts['path']) : ''; $this->query = isset($parts['query']) ? $this->filterQueryAndFragment($parts['query']) : ''; $this->fragment = isset($parts['fragment']) ? $this->filterQueryAndFragment($parts['fragment']) : ''; if (isset($parts['pass'])) { $this->userInfo .= ':'.$this->filterUserInfoComponent($parts['pass']); } $this->removeDefaultPort(); } /** * @param mixed $scheme * * @throws \InvalidArgumentException If the scheme is invalid. */ private function filterScheme($scheme): string { if (!is_string($scheme)) { throw new \InvalidArgumentException('Scheme must be a string'); } return \strtr($scheme, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'); } /** * @param mixed $component * * @throws \InvalidArgumentException If the user info is invalid. */ private function filterUserInfoComponent($component): string { if (!is_string($component)) { throw new \InvalidArgumentException('User info must be a string'); } return preg_replace_callback( '/(?:[^%'.self::CHAR_UNRESERVED.self::CHAR_SUB_DELIMS.']+|%(?![A-Fa-f0-9]{2}))/', [$this, 'rawurlencodeMatchZero'], $component ); } /** * @param mixed $host * * @throws \InvalidArgumentException If the host is invalid. */ private function filterHost($host): string { if (!is_string($host)) { throw new \InvalidArgumentException('Host must be a string'); } return \strtr($host, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'); } /** * @param mixed $port * * @throws \InvalidArgumentException If the port is invalid. */ private function filterPort($port): ?int { if ($port === null) { return null; } $port = (int) $port; if (0 > $port || 0xFFFF < $port) { throw new \InvalidArgumentException( sprintf('Invalid port: %d. Must be between 0 and 65535', $port) ); } return $port; } /** * @param (string|int)[] $keys * * @return string[] */ private static function getFilteredQueryString(UriInterface $uri, array $keys): array { $current = $uri->getQuery(); if ($current === '') { return []; } $decodedKeys = array_map(function ($k): string { return rawurldecode((string) $k); }, $keys); return array_filter(explode('&', $current), function ($part) use ($decodedKeys) { return !in_array(rawurldecode(explode('=', $part)[0]), $decodedKeys, true); }); } private static function generateQueryString(string $key, ?string $value): string { // Query string separators ("=", "&") within the key or value need to be encoded // (while preventing double-encoding) before setting the query string. All other // chars that need percent-encoding will be encoded by withQuery(). $queryString = strtr($key, self::QUERY_SEPARATORS_REPLACEMENT); if ($value !== null) { $queryString .= '='.strtr($value, self::QUERY_SEPARATORS_REPLACEMENT); } return $queryString; } private function removeDefaultPort(): void { if ($this->port !== null && self::isDefaultPort($this)) { $this->port = null; } } /** * Filters the path of a URI * * @param mixed $path * * @throws \InvalidArgumentException If the path is invalid. */ private function filterPath($path): string { if (!is_string($path)) { throw new \InvalidArgumentException('Path must be a string'); } return preg_replace_callback( '/(?:[^'.self::CHAR_UNRESERVED.self::CHAR_SUB_DELIMS.'%:@\/]++|%(?![A-Fa-f0-9]{2}))/', [$this, 'rawurlencodeMatchZero'], $path ); } /** * Filters the query string or fragment of a URI. * * @param mixed $str * * @throws \InvalidArgumentException If the query or fragment is invalid. */ private function filterQueryAndFragment($str): string { if (!is_string($str)) { throw new \InvalidArgumentException('Query and fragment must be a string'); } return preg_replace_callback( '/(?:[^'.self::CHAR_UNRESERVED.self::CHAR_SUB_DELIMS.'%:@\/\?]++|%(?![A-Fa-f0-9]{2}))/', [$this, 'rawurlencodeMatchZero'], $str ); } private function rawurlencodeMatchZero(array $match): string { return rawurlencode($match[0]); } private function validateState(): void { if ($this->host === '' && ($this->scheme === 'http' || $this->scheme === 'https')) { $this->host = self::HTTP_DEFAULT_HOST; } if ($this->getAuthority() === '') { if (0 === strpos($this->path, '//')) { throw new MalformedUriException('The path of a URI without an authority must not start with two slashes "//"'); } if ($this->scheme === '' && false !== strpos(explode('/', $this->path, 2)[0], ':')) { throw new MalformedUriException('A relative URI must not have a path beginning with a segment containing a colon'); } } } } ================================================ FILE: lib/Google/vendor/guzzlehttp/psr7/src/UriComparator.php ================================================ getHost(), $modified->getHost()) !== 0) { return true; } if ($original->getScheme() !== $modified->getScheme()) { return true; } if (self::computePort($original) !== self::computePort($modified)) { return true; } return false; } private static function computePort(UriInterface $uri): int { $port = $uri->getPort(); if (null !== $port) { return $port; } return 'https' === $uri->getScheme() ? 443 : 80; } private function __construct() { // cannot be instantiated } } ================================================ FILE: lib/Google/vendor/guzzlehttp/psr7/src/UriNormalizer.php ================================================ getPath() === '' && ($uri->getScheme() === 'http' || $uri->getScheme() === 'https') ) { $uri = $uri->withPath('/'); } if ($flags & self::REMOVE_DEFAULT_HOST && $uri->getScheme() === 'file' && $uri->getHost() === 'localhost') { $uri = $uri->withHost(''); } if ($flags & self::REMOVE_DEFAULT_PORT && $uri->getPort() !== null && Uri::isDefaultPort($uri)) { $uri = $uri->withPort(null); } if ($flags & self::REMOVE_DOT_SEGMENTS && !Uri::isRelativePathReference($uri)) { $uri = $uri->withPath(UriResolver::removeDotSegments($uri->getPath())); } if ($flags & self::REMOVE_DUPLICATE_SLASHES) { $uri = $uri->withPath(preg_replace('#//++#', '/', $uri->getPath())); } if ($flags & self::SORT_QUERY_PARAMETERS && $uri->getQuery() !== '') { $queryKeyValues = explode('&', $uri->getQuery()); sort($queryKeyValues); $uri = $uri->withQuery(implode('&', $queryKeyValues)); } return $uri; } /** * Whether two URIs can be considered equivalent. * * Both URIs are normalized automatically before comparison with the given $normalizations bitmask. The method also * accepts relative URI references and returns true when they are equivalent. This of course assumes they will be * resolved against the same base URI. If this is not the case, determination of equivalence or difference of * relative references does not mean anything. * * @param UriInterface $uri1 An URI to compare * @param UriInterface $uri2 An URI to compare * @param int $normalizations A bitmask of normalizations to apply, see constants * * @see https://datatracker.ietf.org/doc/html/rfc3986#section-6.1 */ public static function isEquivalent(UriInterface $uri1, UriInterface $uri2, int $normalizations = self::PRESERVING_NORMALIZATIONS): bool { return (string) self::normalize($uri1, $normalizations) === (string) self::normalize($uri2, $normalizations); } private static function capitalizePercentEncoding(UriInterface $uri): UriInterface { $regex = '/(?:%[A-Fa-f0-9]{2})++/'; $callback = function (array $match): string { return strtoupper($match[0]); }; return $uri->withPath( preg_replace_callback($regex, $callback, $uri->getPath()) )->withQuery( preg_replace_callback($regex, $callback, $uri->getQuery()) ); } private static function decodeUnreservedCharacters(UriInterface $uri): UriInterface { $regex = '/%(?:2D|2E|5F|7E|3[0-9]|[46][1-9A-F]|[57][0-9A])/i'; $callback = function (array $match): string { return rawurldecode($match[0]); }; return $uri->withPath( preg_replace_callback($regex, $callback, $uri->getPath()) )->withQuery( preg_replace_callback($regex, $callback, $uri->getQuery()) ); } private function __construct() { // cannot be instantiated } } ================================================ FILE: lib/Google/vendor/guzzlehttp/psr7/src/UriResolver.php ================================================ getScheme() != '') { return $rel->withPath(self::removeDotSegments($rel->getPath())); } if ($rel->getAuthority() != '') { $targetAuthority = $rel->getAuthority(); $targetPath = self::removeDotSegments($rel->getPath()); $targetQuery = $rel->getQuery(); } else { $targetAuthority = $base->getAuthority(); if ($rel->getPath() === '') { $targetPath = $base->getPath(); $targetQuery = $rel->getQuery() != '' ? $rel->getQuery() : $base->getQuery(); } else { if ($rel->getPath()[0] === '/') { $targetPath = $rel->getPath(); } else { if ($targetAuthority != '' && $base->getPath() === '') { $targetPath = '/'.$rel->getPath(); } else { $lastSlashPos = strrpos($base->getPath(), '/'); if ($lastSlashPos === false) { $targetPath = $rel->getPath(); } else { $targetPath = substr($base->getPath(), 0, $lastSlashPos + 1).$rel->getPath(); } } } $targetPath = self::removeDotSegments($targetPath); $targetQuery = $rel->getQuery(); } } return new Uri(Uri::composeComponents( $base->getScheme(), $targetAuthority, $targetPath, $targetQuery, $rel->getFragment() )); } /** * Returns the target URI as a relative reference from the base URI. * * This method is the counterpart to resolve(): * * (string) $target === (string) UriResolver::resolve($base, UriResolver::relativize($base, $target)) * * One use-case is to use the current request URI as base URI and then generate relative links in your documents * to reduce the document size or offer self-contained downloadable document archives. * * $base = new Uri('http://example.com/a/b/'); * echo UriResolver::relativize($base, new Uri('http://example.com/a/b/c')); // prints 'c'. * echo UriResolver::relativize($base, new Uri('http://example.com/a/x/y')); // prints '../x/y'. * echo UriResolver::relativize($base, new Uri('http://example.com/a/b/?q')); // prints '?q'. * echo UriResolver::relativize($base, new Uri('http://example.org/a/b/')); // prints '//example.org/a/b/'. * * This method also accepts a target that is already relative and will try to relativize it further. Only a * relative-path reference will be returned as-is. * * echo UriResolver::relativize($base, new Uri('/a/b/c')); // prints 'c' as well */ public static function relativize(UriInterface $base, UriInterface $target): UriInterface { if ($target->getScheme() !== '' && ($base->getScheme() !== $target->getScheme() || $target->getAuthority() === '' && $base->getAuthority() !== '') ) { return $target; } if (Uri::isRelativePathReference($target)) { // As the target is already highly relative we return it as-is. It would be possible to resolve // the target with `$target = self::resolve($base, $target);` and then try make it more relative // by removing a duplicate query. But let's not do that automatically. return $target; } if ($target->getAuthority() !== '' && $base->getAuthority() !== $target->getAuthority()) { return $target->withScheme(''); } // We must remove the path before removing the authority because if the path starts with two slashes, the URI // would turn invalid. And we also cannot set a relative path before removing the authority, as that is also // invalid. $emptyPathUri = $target->withScheme('')->withPath('')->withUserInfo('')->withPort(null)->withHost(''); if ($base->getPath() !== $target->getPath()) { return $emptyPathUri->withPath(self::getRelativePath($base, $target)); } if ($base->getQuery() === $target->getQuery()) { // Only the target fragment is left. And it must be returned even if base and target fragment are the same. return $emptyPathUri->withQuery(''); } // If the base URI has a query but the target has none, we cannot return an empty path reference as it would // inherit the base query component when resolving. if ($target->getQuery() === '') { $segments = explode('/', $target->getPath()); /** @var string $lastSegment */ $lastSegment = end($segments); return $emptyPathUri->withPath($lastSegment === '' ? './' : $lastSegment); } return $emptyPathUri; } private static function getRelativePath(UriInterface $base, UriInterface $target): string { $sourceSegments = explode('/', $base->getPath()); $targetSegments = explode('/', $target->getPath()); array_pop($sourceSegments); $targetLastSegment = array_pop($targetSegments); foreach ($sourceSegments as $i => $segment) { if (isset($targetSegments[$i]) && $segment === $targetSegments[$i]) { unset($sourceSegments[$i], $targetSegments[$i]); } else { break; } } $targetSegments[] = $targetLastSegment; $relativePath = str_repeat('../', count($sourceSegments)).implode('/', $targetSegments); // A reference to am empty last segment or an empty first sub-segment must be prefixed with "./". // This also applies to a segment with a colon character (e.g., "file:colon") that cannot be used // as the first segment of a relative-path reference, as it would be mistaken for a scheme name. if ('' === $relativePath || false !== strpos(explode('/', $relativePath, 2)[0], ':')) { $relativePath = "./$relativePath"; } elseif ('/' === $relativePath[0]) { if ($base->getAuthority() != '' && $base->getPath() === '') { // In this case an extra slash is added by resolve() automatically. So we must not add one here. $relativePath = ".$relativePath"; } else { $relativePath = "./$relativePath"; } } return $relativePath; } private function __construct() { // cannot be instantiated } } ================================================ FILE: lib/Google/vendor/guzzlehttp/psr7/src/Utils.php ================================================ $v) { if (!in_array(strtolower((string) $k), $keys)) { $result[$k] = $v; } } return $result; } /** * Copy the contents of a stream into another stream until the given number * of bytes have been read. * * @param StreamInterface $source Stream to read from * @param StreamInterface $dest Stream to write to * @param int $maxLen Maximum number of bytes to read. Pass -1 * to read the entire stream. * * @throws \RuntimeException on error. */ public static function copyToStream(StreamInterface $source, StreamInterface $dest, int $maxLen = -1): void { $bufferSize = 8192; if ($maxLen === -1) { while (!$source->eof()) { if (!$dest->write($source->read($bufferSize))) { break; } } } else { $remaining = $maxLen; while ($remaining > 0 && !$source->eof()) { $buf = $source->read(min($bufferSize, $remaining)); $len = strlen($buf); if (!$len) { break; } $remaining -= $len; $dest->write($buf); } } } /** * Copy the contents of a stream into a string until the given number of * bytes have been read. * * @param StreamInterface $stream Stream to read * @param int $maxLen Maximum number of bytes to read. Pass -1 * to read the entire stream. * * @throws \RuntimeException on error. */ public static function copyToString(StreamInterface $stream, int $maxLen = -1): string { $buffer = ''; if ($maxLen === -1) { while (!$stream->eof()) { $buf = $stream->read(1048576); if ($buf === '') { break; } $buffer .= $buf; } return $buffer; } $len = 0; while (!$stream->eof() && $len < $maxLen) { $buf = $stream->read($maxLen - $len); if ($buf === '') { break; } $buffer .= $buf; $len = strlen($buffer); } return $buffer; } /** * Calculate a hash of a stream. * * This method reads the entire stream to calculate a rolling hash, based * on PHP's `hash_init` functions. * * @param StreamInterface $stream Stream to calculate the hash for * @param string $algo Hash algorithm (e.g. md5, crc32, etc) * @param bool $rawOutput Whether or not to use raw output * * @throws \RuntimeException on error. */ public static function hash(StreamInterface $stream, string $algo, bool $rawOutput = false): string { $pos = $stream->tell(); if ($pos > 0) { $stream->rewind(); } $ctx = hash_init($algo); while (!$stream->eof()) { hash_update($ctx, $stream->read(1048576)); } $out = hash_final($ctx, $rawOutput); $stream->seek($pos); return $out; } /** * Clone and modify a request with the given changes. * * This method is useful for reducing the number of clones needed to mutate * a message. * * The changes can be one of: * - method: (string) Changes the HTTP method. * - set_headers: (array) Sets the given headers. * - remove_headers: (array) Remove the given headers. * - body: (mixed) Sets the given body. * - uri: (UriInterface) Set the URI. * - query: (string) Set the query string value of the URI. * - version: (string) Set the protocol version. * * @param RequestInterface $request Request to clone and modify. * @param array $changes Changes to apply. */ public static function modifyRequest(RequestInterface $request, array $changes): RequestInterface { if (!$changes) { return $request; } $headers = $request->getHeaders(); if (!isset($changes['uri'])) { $uri = $request->getUri(); } else { // Remove the host header if one is on the URI if ($host = $changes['uri']->getHost()) { $changes['set_headers']['Host'] = $host; if ($port = $changes['uri']->getPort()) { $standardPorts = ['http' => 80, 'https' => 443]; $scheme = $changes['uri']->getScheme(); if (isset($standardPorts[$scheme]) && $port != $standardPorts[$scheme]) { $changes['set_headers']['Host'] .= ':'.$port; } } } $uri = $changes['uri']; } if (!empty($changes['remove_headers'])) { $headers = self::caselessRemove($changes['remove_headers'], $headers); } if (!empty($changes['set_headers'])) { $headers = self::caselessRemove(array_keys($changes['set_headers']), $headers); $headers = $changes['set_headers'] + $headers; } if (isset($changes['query'])) { $uri = $uri->withQuery($changes['query']); } if ($request instanceof ServerRequestInterface) { $new = (new ServerRequest( $changes['method'] ?? $request->getMethod(), $uri, $headers, $changes['body'] ?? $request->getBody(), $changes['version'] ?? $request->getProtocolVersion(), $request->getServerParams() )) ->withParsedBody($request->getParsedBody()) ->withQueryParams($request->getQueryParams()) ->withCookieParams($request->getCookieParams()) ->withUploadedFiles($request->getUploadedFiles()); foreach ($request->getAttributes() as $key => $value) { $new = $new->withAttribute($key, $value); } return $new; } return new Request( $changes['method'] ?? $request->getMethod(), $uri, $headers, $changes['body'] ?? $request->getBody(), $changes['version'] ?? $request->getProtocolVersion() ); } /** * Read a line from the stream up to the maximum allowed buffer length. * * @param StreamInterface $stream Stream to read from * @param int|null $maxLength Maximum buffer length */ public static function readLine(StreamInterface $stream, ?int $maxLength = null): string { $buffer = ''; $size = 0; while (!$stream->eof()) { if ('' === ($byte = $stream->read(1))) { return $buffer; } $buffer .= $byte; // Break when a new line is found or the max length - 1 is reached if ($byte === "\n" || ++$size === $maxLength - 1) { break; } } return $buffer; } /** * Redact the password in the user info part of a URI. */ public static function redactUserInfo(UriInterface $uri): UriInterface { $userInfo = $uri->getUserInfo(); if (false !== ($pos = \strpos($userInfo, ':'))) { return $uri->withUserInfo(\substr($userInfo, 0, $pos), '***'); } return $uri; } /** * Create a new stream based on the input type. * * Options is an associative array that can contain the following keys: * - metadata: Array of custom metadata. * - size: Size of the stream. * * This method accepts the following `$resource` types: * - `Psr\Http\Message\StreamInterface`: Returns the value as-is. * - `string`: Creates a stream object that uses the given string as the contents. * - `resource`: Creates a stream object that wraps the given PHP stream resource. * - `Iterator`: If the provided value implements `Iterator`, then a read-only * stream object will be created that wraps the given iterable. Each time the * stream is read from, data from the iterator will fill a buffer and will be * continuously called until the buffer is equal to the requested read size. * Subsequent read calls will first read from the buffer and then call `next` * on the underlying iterator until it is exhausted. * - `object` with `__toString()`: If the object has the `__toString()` method, * the object will be cast to a string and then a stream will be returned that * uses the string value. * - `NULL`: When `null` is passed, an empty stream object is returned. * - `callable` When a callable is passed, a read-only stream object will be * created that invokes the given callable. The callable is invoked with the * number of suggested bytes to read. The callable can return any number of * bytes, but MUST return `false` when there is no more data to return. The * stream object that wraps the callable will invoke the callable until the * number of requested bytes are available. Any additional bytes will be * buffered and used in subsequent reads. * * @param resource|string|int|float|bool|StreamInterface|callable|\Iterator|null $resource Entity body data * @param array{size?: int, metadata?: array} $options Additional options * * @throws \InvalidArgumentException if the $resource arg is not valid. */ public static function streamFor($resource = '', array $options = []): StreamInterface { if (is_scalar($resource)) { $stream = self::tryFopen('php://temp', 'r+'); if ($resource !== '') { fwrite($stream, (string) $resource); fseek($stream, 0); } return new Stream($stream, $options); } switch (gettype($resource)) { case 'resource': /* * The 'php://input' is a special stream with quirks and inconsistencies. * We avoid using that stream by reading it into php://temp */ /** @var resource $resource */ if ((\stream_get_meta_data($resource)['uri'] ?? '') === 'php://input') { $stream = self::tryFopen('php://temp', 'w+'); stream_copy_to_stream($resource, $stream); fseek($stream, 0); $resource = $stream; } return new Stream($resource, $options); case 'object': /** @var object $resource */ if ($resource instanceof StreamInterface) { return $resource; } elseif ($resource instanceof \Iterator) { return new PumpStream(function () use ($resource) { if (!$resource->valid()) { return false; } $result = $resource->current(); $resource->next(); return $result; }, $options); } elseif (method_exists($resource, '__toString')) { return self::streamFor((string) $resource, $options); } break; case 'NULL': return new Stream(self::tryFopen('php://temp', 'r+'), $options); } if (is_callable($resource)) { return new PumpStream($resource, $options); } throw new \InvalidArgumentException('Invalid resource type: '.gettype($resource)); } /** * Safely opens a PHP stream resource using a filename. * * When fopen fails, PHP normally raises a warning. This function adds an * error handler that checks for errors and throws an exception instead. * * @param string $filename File to open * @param string $mode Mode used to open the file * * @return resource * * @throws \RuntimeException if the file cannot be opened */ public static function tryFopen(string $filename, string $mode) { $ex = null; set_error_handler(static function (int $errno, string $errstr) use ($filename, $mode, &$ex): bool { $ex = new \RuntimeException(sprintf( 'Unable to open "%s" using mode "%s": %s', $filename, $mode, $errstr )); return true; }); try { /** @var resource $handle */ $handle = fopen($filename, $mode); } catch (\Throwable $e) { $ex = new \RuntimeException(sprintf( 'Unable to open "%s" using mode "%s": %s', $filename, $mode, $e->getMessage() ), 0, $e); } restore_error_handler(); if ($ex) { /** @var \RuntimeException $ex */ throw $ex; } return $handle; } /** * Safely gets the contents of a given stream. * * When stream_get_contents fails, PHP normally raises a warning. This * function adds an error handler that checks for errors and throws an * exception instead. * * @param resource $stream * * @throws \RuntimeException if the stream cannot be read */ public static function tryGetContents($stream): string { $ex = null; set_error_handler(static function (int $errno, string $errstr) use (&$ex): bool { $ex = new \RuntimeException(sprintf( 'Unable to read stream contents: %s', $errstr )); return true; }); try { /** @var string|false $contents */ $contents = stream_get_contents($stream); if ($contents === false) { $ex = new \RuntimeException('Unable to read stream contents'); } } catch (\Throwable $e) { $ex = new \RuntimeException(sprintf( 'Unable to read stream contents: %s', $e->getMessage() ), 0, $e); } restore_error_handler(); if ($ex) { /** @var \RuntimeException $ex */ throw $ex; } return $contents; } /** * Returns a UriInterface for the given value. * * This function accepts a string or UriInterface and returns a * UriInterface for the given value. If the value is already a * UriInterface, it is returned as-is. * * @param string|UriInterface $uri * * @throws \InvalidArgumentException */ public static function uriFor($uri): UriInterface { if ($uri instanceof UriInterface) { return $uri; } if (is_string($uri)) { return new Uri($uri); } throw new \InvalidArgumentException('URI must be a string or UriInterface'); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/CHANGELOG.md ================================================ ### 3.10.0 (2026-01-02) * Added automatic directory cleanup in RotatingFileHandler (#2000) * Added timezone-aware file rotation to RotatingFileHandler (#1982) * Added support for mongodb/mongodb 2.0+ (#1998) * Added NoDiscard attribute to TestHandler methods to ensure the result is used (#2013) * Fixed JsonFormatter crashing if __toString throws while normalizing data (#1968) * Fixed PHP 8.5 deprecation warnings (#1997, #2009) * Fixed DeduplicatingHandler collecting duplicate logs if the file cannot be locked (2e97231) * Fixed GelfMessageFormatter to use integers instead of bool for gelf 1.1 support (#1973) * Fixed empty stack traces being output anyway (#1979) * Fixed StreamHandler not reopening the file if the inode changed (#1963) * Fixed TelegramBotHandler sending empty messages (#1992) * Fixed file paths in stack traces containing backslashes on windows, always using / now to unify logs (#1980) * Fixed RotatingFileHandler unlink errors not being suppressed correctly (#1999) ### 3.9.0 (2025-03-24) * BC Warning: Fixed SendGridHandler to use the V3 API as V2 is now shut down, but this requires a new API key (#1952) * Deprecated Monolog\Test\TestCase in favor of Monolog\Test\MonologTestCase (#1953) * Added extension point for NativeMailerHandler::mail (#1948) * Added setHandler method to BufferHandler to modify the nested handler at runtime (#1946) * Fixed date format in ElasticsearchFormatter to use +00:00 vs +0000 tz identifiers (#1942) * Fixed GelfMessageFormatter handling numeric context/extra keys (#1932) ### 3.8.1 (2024-12-05) * Deprecated Monolog\DateTimeImmutable in favor of Monolog\JsonSerializableDateTimeImmutable (#1928) * Fixed gelf keys not being valid when context/extra data keys have spaces in them (#1927) * Fixed empty lines appearing in the stack traces when a custom formatter returned null (#1925) ### 3.8.0 (2024-11-12) * Added `$fileOpenMode` param to `StreamHandler` to define a custom fopen mode to open the log file (#1913) * Fixed PHP 8.4 deprecation notices (#1903) * Added ability to extend/override `IntrospectionProcessor` (#1899) * Added `$timeout` param to `ProcessHandler` to configure the stream_select() timeout to avoid blocking too long (default is 1.0 sec) (#1916) * Fixed JsonFormatter batch handling to normalize records individually to make sure they look the same as if they were handled one by one (#1906) * Fixed `StreamHandler` handling of write failures so that it now closes/reopens the stream and retries the write once before failing (#1882) * Fixed `StreamHandler` error handler causing issues if a stream handler triggers an error (#1866) * Fixed `StreamHandler::reset` not closing the stream, so that it would fail to write in some cases with long running processes (#1862) * Fixed `RotatingFileHandler` issue where rotation does not happen in some long running processes (#1905) * Fixed `JsonFormatter` handling of incomplete classes (#1834) * Fixed `RotatingFileHandler` bug where rotation could sometimes not happen correctly (#1905) ### 3.7.0 (2024-06-28) * Added `NormalizerFormatter->setBasePath(...)` (and `JsonFormatter` by extension) that allows removing the project's path from the stack trace output (47e301d3e) * Fixed JsonFormatter handling of incomplete classes (#1834) * Fixed private error handlers causing problems with custom StreamHandler implementations (#1866) ### 3.6.0 (2024-04-12) * Added `LineFormatter->setBasePath(...)` that allows removing the project's path from the stack trace output (#1873) * Added `$includeExtra` option in `PsrHandler` to also use extra data to replace placeholder values in the message (#1852) * Added ability to customize what is a duplicated message by extending the `DeduplicationHandler` (#1879) * Added handling for using `GelfMessageFormatter` together with the `AmqpHandler` (#1869) * Added ability to extend `GoogleCloudLoggingFormatter` (#1859) * Fixed `__toString` failures in context data crashing the normalization process (#1868) * Fixed PHP 8.4 deprecation warnings (#1874) ### 3.5.0 (2023-10-27) * Added ability to indent stack traces in LineFormatter via e.g. `indentStacktraces(' ')` (#1835) * Added ability to configure a max level name length in LineFormatter via e.g. `setMaxLevelNameLength(3)` (#1850) * Added support for indexed arrays (i.e. `[]` and not `{}` arrays once json serialized) containing inline linebreaks in LineFormatter (#1818) * Added `WithMonologChannel` attribute for integrators to use to configure autowiring (#1847) * Fixed log record `extra` data leaking between handlers that have handler-specific processors set (#1819) * Fixed LogglyHandler issue with record level filtering (#1841) * Fixed display_errors parsing in ErrorHandler which did not support string values (#1804) * Fixed bug where the previous error handler would not be restored in some cases where StreamHandler fails (#1815) * Fixed normalization error when normalizing incomplete classes (#1833) ### 3.4.0 (2023-06-21) * Added `LoadAverageProcessor` to track one of the 1, 5 or 15min load averages (#1803) * Added support for priority to the `AsMonologProcessor` attribute (#1797) * Added `TelegramBotHandler` `topic`/`message_thread_id` support (#1802) * Fixed `FingersCrossedHandler` passthruLevel checking (#1801) * Fixed support of yearly and monthly rotation log file to rotate only once a month/year (#1805) * Fixed `TestHandler` method docs (#1794) * Fixed handling of falsey `display_errors` string values (#1804) ### 3.3.1 (2023-02-06) * Fixed Logger not being serializable anymore (#1792) ### 3.3.0 (2023-02-06) * Deprecated FlowdockHandler & Formatter as the flowdock service was shutdown (#1748) * Added `ClosureContextProcessor` to allow delaying the creation of context data by setting a Closure in context which is called when the log record is used (#1745) * Added an ElasticsearchHandler option to set the `op_type` to `create` instead of the default `index` (#1766) * Added support for enum context values in PsrLogMessageProcessor (#1773) * Added graylog2/gelf-php 2.x support (#1747) * Improved `BrowserConsoleHandler` logging to use more appropriate methods than just console.log in the browser (#1739) * Fixed GitProcessor not filtering correctly based on Level (#1749) * Fixed `WhatFailureGroupHandler` not catching errors happening inside `close()` (#1791) * Fixed datetime field in `GoogleCloudLoggingFormatter` (#1758) * Fixed infinite loop detection within Fibers (#1753) * Fixed `AmqpHandler->setExtraAttributes` not working with buffering handler wrappers (#1781) ### 3.2.0 (2022-07-24) * Deprecated `CubeHandler` and `PHPConsoleHandler` as both projects are abandoned and those should not be used anymore (#1734) * Marked `Logger` `@final` as it should not be extended, prefer composition or talk to us if you are missing something * Added RFC 5424 level (`7` to `0`) support to `Logger::log` and `Logger::addRecord` to increase interoperability (#1723) * Added `SyslogFormatter` to output syslog-like files which can be consumed by tools like [lnav](https://lnav.org/) (#1689) * Added support for `__toString` for objects which are not json serializable in `JsonFormatter` (#1733) * Added `GoogleCloudLoggingFormatter` (#1719) * Added support for Predis 2.x (#1732) * Added `AmqpHandler->setExtraAttributes` to allow configuring attributes when using an AMQPExchange (#1724) * Fixed serialization/unserialization of handlers to make sure private properties are included (#1727) * Fixed allowInlineLineBreaks in LineFormatter causing issues with windows paths containing `\n` or `\r` sequences (#1720) * Fixed max normalization depth not being taken into account when formatting exceptions with a deep chain of previous exceptions (#1726) * Fixed PHP 8.2 deprecation warnings (#1722) * Fixed rare race condition or filesystem issue where StreamHandler is unable to create the directory the log should go into yet it exists already (#1678) ### 3.1.0 (2022-06-09) * Added `$datetime` parameter to `Logger::addRecord` as low level API to allow logging into the past or future (#1682) * Added `Logger::useLoggingLoopDetection` to allow disabling cyclic logging detection in concurrent frameworks (#1681) * Fixed handling of fatal errors if callPrevious is disabled in ErrorHandler (#1670) * Fixed interop issue by removing the need for a return type in ProcessorInterface (#1680) * Marked the reusable `Monolog\Test\TestCase` class as `@internal` to make sure PHPStorm does not show it above PHPUnit, you may still use it to test your own handlers/etc though (#1677) * Fixed RotatingFileHandler issue when the date format contained slashes (#1671) ### 3.0.0 (2022-05-10) Changes from RC1 - The `Monolog\LevelName` enum does not exist anymore, use `Monolog\Level->getName()` instead. ### 3.0.0-RC1 (2022-05-08) This is mostly a cleanup release offering stronger type guarantees for integrators with the array->object/enum changes, but there is no big new feature for end users. See [UPGRADE notes](UPGRADE.md#300) for details on all breaking changes especially if you are extending/implementing Monolog classes/interfaces. Noteworthy BC Breaks: - The minimum supported PHP version is now `8.1.0`. - Log records have been converted from an array to a [`Monolog\LogRecord` object](src/Monolog/LogRecord.php) with public (and mostly readonly) properties. e.g. instead of doing `$record['context']` use `$record->context`. In formatters or handlers if you rather need an array to work with you can use `$record->toArray()` to get back a Monolog 1/2 style record array. This will contain the enum values instead of enum cases in the `level` and `level_name` keys to be more backwards compatible and use simpler data types. - `FormatterInterface`, `HandlerInterface`, `ProcessorInterface`, etc. changed to contain `LogRecord $record` instead of `array $record` parameter types. If you want to support multiple Monolog versions this should be possible by type-hinting nothing, or `array|LogRecord` if you support PHP 8.0+. You can then code against the $record using Monolog 2 style as LogRecord implements ArrayAccess for BC. The interfaces do not require a `LogRecord` return type even where it would be applicable, but if you only support Monolog 3 in integration code I would recommend you use `LogRecord` return types wherever fitting to ensure forward compatibility as it may be added in Monolog 4. - Log levels are now enums [`Monolog\Level`](src/Monolog/Level.php) and [`Monolog\LevelName`](src/Monolog/LevelName.php) - Removed deprecated SwiftMailerHandler, migrate to SymfonyMailerHandler instead. - `ResettableInterface::reset()` now requires a void return type. - All properties have had types added, which may require you to do so as well if you extended a Monolog class and declared the same property. New deprecations: - `Logger::DEBUG`, `Logger::ERROR`, etc. are now deprecated in favor of the `Monolog\Level` enum. e.g. instead of `Logger::WARNING` use `Level::Warning` if you need to pass the enum case to Monolog or one of its handlers, or `Level::Warning->value` if you need the integer value equal to what `Logger::WARNING` was giving you. - `Logger::getLevelName()` is now deprecated. ### 2.10.0 (2024-11-12) * Added `$fileOpenMode` to `StreamHandler` to define a custom fopen mode to open the log file (#1913) * Fixed `StreamHandler` handling of write failures so that it now closes/reopens the stream and retries the write once before failing (#1882) * Fixed `StreamHandler` error handler causing issues if a stream handler triggers an error (#1866) * Fixed `JsonFormatter` handling of incomplete classes (#1834) * Fixed `RotatingFileHandler` bug where rotation could sometimes not happen correctly (#1905) ### 2.9.3 (2024-04-12) * Fixed PHP 8.4 deprecation warnings (#1874) ### 2.9.2 (2023-10-27) * Fixed display_errors parsing in ErrorHandler which did not support string values (#1804) * Fixed bug where the previous error handler would not be restored in some cases where StreamHandler fails (#1815) * Fixed normalization error when normalizing incomplete classes (#1833) ### 2.9.1 (2023-02-06) * Fixed Logger not being serializable anymore (#1792) ### 2.9.0 (2023-02-05) * Deprecated FlowdockHandler & Formatter as the flowdock service was shutdown (#1748) * Added support for enum context values in PsrLogMessageProcessor (#1773) * Added graylog2/gelf-php 2.x support (#1747) * Improved `BrowserConsoleHandler` logging to use more appropriate methods than just console.log in the browser (#1739) * Fixed `WhatFailureGroupHandler` not catching errors happening inside `close()` (#1791) * Fixed datetime field in `GoogleCloudLoggingFormatter` (#1758) * Fixed infinite loop detection within Fibers (#1753) * Fixed `AmqpHandler->setExtraAttributes` not working with buffering handler wrappers (#1781) ### 2.8.0 (2022-07-24) * Deprecated `CubeHandler` and `PHPConsoleHandler` as both projects are abandoned and those should not be used anymore (#1734) * Added RFC 5424 level (`7` to `0`) support to `Logger::log` and `Logger::addRecord` to increase interoperability (#1723) * Added support for `__toString` for objects which are not json serializable in `JsonFormatter` (#1733) * Added `GoogleCloudLoggingFormatter` (#1719) * Added support for Predis 2.x (#1732) * Added `AmqpHandler->setExtraAttributes` to allow configuring attributes when using an AMQPExchange (#1724) * Fixed serialization/unserialization of handlers to make sure private properties are included (#1727) * Fixed allowInlineLineBreaks in LineFormatter causing issues with windows paths containing `\n` or `\r` sequences (#1720) * Fixed max normalization depth not being taken into account when formatting exceptions with a deep chain of previous exceptions (#1726) * Fixed PHP 8.2 deprecation warnings (#1722) * Fixed rare race condition or filesystem issue where StreamHandler is unable to create the directory the log should go into yet it exists already (#1678) ### 2.7.0 (2022-06-09) * Added `$datetime` parameter to `Logger::addRecord` as low level API to allow logging into the past or future (#1682) * Added `Logger::useLoggingLoopDetection` to allow disabling cyclic logging detection in concurrent frameworks (#1681) * Fixed handling of fatal errors if callPrevious is disabled in ErrorHandler (#1670) * Marked the reusable `Monolog\Test\TestCase` class as `@internal` to make sure PHPStorm does not show it above PHPUnit, you may still use it to test your own handlers/etc though (#1677) * Fixed RotatingFileHandler issue when the date format contained slashes (#1671) ### 2.6.0 (2022-05-10) * Deprecated `SwiftMailerHandler`, use `SymfonyMailerHandler` instead * Added `SymfonyMailerHandler` (#1663) * Added ElasticSearch 8.x support to the ElasticsearchHandler (#1662) * Added a way to filter/modify stack traces in LineFormatter (#1665) * Fixed UdpSocket not being able to reopen/reconnect after close() * Fixed infinite loops if a Handler is triggering logging while handling log records ### 2.5.0 (2022-04-08) * Added `callType` to IntrospectionProcessor (#1612) * Fixed AsMonologProcessor syntax to be compatible with PHP 7.2 (#1651) ### 2.4.0 (2022-03-14) * Added [`Monolog\LogRecord`](src/Monolog/LogRecord.php) interface that can be used to type-hint records like `array|\Monolog\LogRecord $record` to be forward compatible with the upcoming Monolog 3 changes * Added `includeStacktraces` constructor params to LineFormatter & JsonFormatter (#1603) * Added `persistent`, `timeout`, `writingTimeout`, `connectionTimeout`, `chunkSize` constructor params to SocketHandler and derivatives (#1600) * Added `AsMonologProcessor` PHP attribute which can help autowiring / autoconfiguration of processors if frameworks / integrations decide to make use of it. This is useless when used purely with Monolog (#1637) * Added support for keeping native BSON types as is in MongoDBFormatter (#1620) * Added support for a `user_agent` key in WebProcessor, disabled by default but you can use it by configuring the $extraFields you want (#1613) * Added support for username/userIcon in SlackWebhookHandler (#1617) * Added extension points to BrowserConsoleHandler (#1593) * Added record message/context/extra info to exceptions thrown when a StreamHandler cannot open its stream to avoid completely losing the data logged (#1630) * Fixed error handler signature to accept a null $context which happens with internal PHP errors (#1614) * Fixed a few setter methods not returning `self` (#1609) * Fixed handling of records going over the max Telegram message length (#1616) ### 2.3.5 (2021-10-01) * Fixed regression in StreamHandler since 2.3.3 on systems with the memory_limit set to >=20GB (#1592) ### 2.3.4 (2021-09-15) * Fixed support for psr/log 3.x (#1589) ### 2.3.3 (2021-09-14) * Fixed memory usage when using StreamHandler and calling stream_get_contents on the resource you passed to it (#1578, #1577) * Fixed support for psr/log 2.x (#1587) * Fixed some type annotations ### 2.3.2 (2021-07-23) * Fixed compatibility with PHP 7.2 - 7.4 when experiencing PCRE errors (#1568) ### 2.3.1 (2021-07-14) * Fixed Utils::getClass handling of anonymous classes not being fully compatible with PHP 8 (#1563) * Fixed some `@inheritDoc` annotations having the wrong case ### 2.3.0 (2021-07-05) * Added a ton of PHPStan type annotations as well as type aliases on Monolog\Logger for Record, Level and LevelName that you can import (#1557) * Added ability to customize date format when using JsonFormatter (#1561) * Fixed FilterHandler not calling reset on its internal handler when reset() is called on it (#1531) * Fixed SyslogUdpHandler not setting the timezone correctly on DateTimeImmutable instances (#1540) * Fixed StreamHandler thread safety - chunk size set to 2GB now to avoid interlacing when doing concurrent writes (#1553) ### 2.2.0 (2020-12-14) * Added JSON_PARTIAL_OUTPUT_ON_ERROR to default json encoding flags, to avoid dropping entire context data or even records due to an invalid subset of it somewhere * Added setDateFormat to NormalizerFormatter (and Line/Json formatters by extension) to allow changing this after object creation * Added RedisPubSubHandler to log records to a Redis channel using PUBLISH * Added support for Elastica 7, and deprecated the $type argument of ElasticaFormatter which is not in use anymore as of Elastica 7 * Added support for millisecond write timeouts in SocketHandler, you can now pass floats to setWritingTimeout, e.g. 0.2 is 200ms * Added support for unix sockets in SyslogUdpHandler (set $port to 0 to make the $host a unix socket) * Added handleBatch support for TelegramBotHandler * Added RFC5424e extended date format including milliseconds to SyslogUdpHandler * Added support for configuring handlers with numeric level values in strings (coming from e.g. env vars) * Fixed Wildfire/FirePHP/ChromePHP handling of unicode characters * Fixed PHP 8 issues in SyslogUdpHandler * Fixed internal type error when mbstring is missing ### 2.1.1 (2020-07-23) * Fixed removing of json encoding options * Fixed type hint of $level not accepting strings in SendGridHandler and OverflowHandler * Fixed SwiftMailerHandler not accepting email templates with an empty subject * Fixed array access on null in RavenHandler * Fixed unique_id in WebProcessor not being disableable ### 2.1.0 (2020-05-22) * Added `JSON_INVALID_UTF8_SUBSTITUTE` to default json flags, so that invalid UTF8 characters now get converted to [�](https://en.wikipedia.org/wiki/Specials_(Unicode_block)#Replacement_character) instead of being converted from ISO-8859-15 to UTF8 as it was before, which was hardly a comprehensive solution * Added `$ignoreEmptyContextAndExtra` option to JsonFormatter to skip empty context/extra entirely from the output * Added `$parseMode`, `$disableWebPagePreview` and `$disableNotification` options to TelegramBotHandler * Added tentative support for PHP 8 * NormalizerFormatter::addJsonEncodeOption and removeJsonEncodeOption are now public to allow modifying default json flags * Fixed GitProcessor type error when there is no git repo present * Fixed normalization of SoapFault objects containing deeply nested objects as "detail" * Fixed support for relative paths in RotatingFileHandler ### 2.0.2 (2019-12-20) * Fixed ElasticsearchHandler swallowing exceptions details when failing to index log records * Fixed normalization of SoapFault objects containing non-strings as "detail" in LineFormatter * Fixed formatting of resources in JsonFormatter * Fixed RedisHandler failing to use MULTI properly when passed a proxied Redis instance (e.g. in Symfony with lazy services) * Fixed FilterHandler triggering a notice when handleBatch was filtering all records passed to it * Fixed Turkish locale messing up the conversion of level names to their constant values ### 2.0.1 (2019-11-13) * Fixed normalization of Traversables to avoid traversing them as not all of them are rewindable * Fixed setFormatter/getFormatter to forward to the nested handler in FilterHandler, FingersCrossedHandler, BufferHandler, OverflowHandler and SamplingHandler * Fixed BrowserConsoleHandler formatting when using multiple styles * Fixed normalization of exception codes to be always integers even for PDOException which have them as numeric strings * Fixed normalization of SoapFault objects containing non-strings as "detail" * Fixed json encoding across all handlers to always attempt recovery of non-UTF-8 strings instead of failing the whole encoding * Fixed ChromePHPHandler to avoid sending more data than latest Chrome versions allow in headers (4KB down from 256KB). * Fixed type error in BrowserConsoleHandler when the context array of log records was not associative. ### 2.0.0 (2019-08-30) * BC Break: This is a major release, see [UPGRADE.md](UPGRADE.md) for details if you are coming from a 1.x release * BC Break: Logger methods log/debug/info/notice/warning/error/critical/alert/emergency now have explicit void return types * Added FallbackGroupHandler which works like the WhatFailureGroupHandler but stops dispatching log records as soon as one handler accepted it * Fixed support for UTF-8 when cutting strings to avoid cutting a multibyte-character in half * Fixed normalizers handling of exception backtraces to avoid serializing arguments in some cases * Fixed date timezone handling in SyslogUdpHandler ### 2.0.0-beta2 (2019-07-06) * BC Break: This is a major release, see [UPGRADE.md](UPGRADE.md) for details if you are coming from a 1.x release * BC Break: PHP 7.2 is now the minimum required PHP version. * BC Break: Removed SlackbotHandler, RavenHandler and HipChatHandler, see [UPGRADE.md](UPGRADE.md) for details * Added OverflowHandler which will only flush log records to its nested handler when reaching a certain amount of logs (i.e. only pass through when things go really bad) * Added TelegramBotHandler to log records to a [Telegram](https://core.telegram.org/bots/api) bot account * Added support for JsonSerializable when normalizing exceptions * Added support for RFC3164 (outdated BSD syslog protocol) to SyslogUdpHandler * Added SoapFault details to formatted exceptions * Fixed DeduplicationHandler silently failing to start when file could not be opened * Fixed issue in GroupHandler and WhatFailureGroupHandler where setting multiple processors would duplicate records * Fixed GelfFormatter losing some data when one attachment was too long * Fixed issue in SignalHandler restarting syscalls functionality * Improved performance of LogglyHandler when sending multiple logs in a single request ### 2.0.0-beta1 (2018-12-08) * BC Break: This is a major release, see [UPGRADE.md](UPGRADE.md) for details if you are coming from a 1.x release * BC Break: PHP 7.1 is now the minimum required PHP version. * BC Break: Quite a few interface changes, only relevant if you implemented your own handlers/processors/formatters * BC Break: Removed non-PSR-3 methods to add records, all the `add*` (e.g. `addWarning`) methods as well as `emerg`, `crit`, `err` and `warn` * BC Break: The record timezone is now set per Logger instance and not statically anymore * BC Break: There is no more default handler configured on empty Logger instances * BC Break: ElasticSearchHandler renamed to ElasticaHandler * BC Break: Various handler-specific breaks, see [UPGRADE.md](UPGRADE.md) for details * Added scalar type hints and return hints in all the places it was possible. Switched strict_types on for more reliability. * Added DateTimeImmutable support, all record datetime are now immutable, and will toString/json serialize with the correct date format, including microseconds (unless disabled) * Added timezone and microseconds to the default date format * Added SendGridHandler to use the SendGrid API to send emails * Added LogmaticHandler to use the Logmatic.io API to store log records * Added SqsHandler to send log records to an AWS SQS queue * Added ElasticsearchHandler to send records via the official ES library. Elastica users should now use ElasticaHandler instead of ElasticSearchHandler * Added NoopHandler which is similar to the NullHandle but does not prevent the bubbling of log records to handlers further down the configuration, useful for temporarily disabling a handler in configuration files * Added ProcessHandler to write log output to the STDIN of a given process * Added HostnameProcessor that adds the machine's hostname to log records * Added a `$dateFormat` option to the PsrLogMessageProcessor which lets you format DateTime instances nicely * Added support for the PHP 7.x `mongodb` extension in the MongoDBHandler * Fixed many minor issues in various handlers, and probably added a few regressions too ### 1.26.1 (2021-05-28) * Fixed PHP 8.1 deprecation warning ### 1.26.0 (2020-12-14) * Added $dateFormat and $removeUsedContextFields arguments to PsrLogMessageProcessor (backport from 2.x) ### 1.25.5 (2020-07-23) * Fixed array access on null in RavenHandler * Fixed unique_id in WebProcessor not being disableable ### 1.25.4 (2020-05-22) * Fixed GitProcessor type error when there is no git repo present * Fixed normalization of SoapFault objects containing deeply nested objects as "detail" * Fixed support for relative paths in RotatingFileHandler ### 1.25.3 (2019-12-20) * Fixed formatting of resources in JsonFormatter * Fixed RedisHandler failing to use MULTI properly when passed a proxied Redis instance (e.g. in Symfony with lazy services) * Fixed FilterHandler triggering a notice when handleBatch was filtering all records passed to it * Fixed Turkish locale messing up the conversion of level names to their constant values ### 1.25.2 (2019-11-13) * Fixed normalization of Traversables to avoid traversing them as not all of them are rewindable * Fixed setFormatter/getFormatter to forward to the nested handler in FilterHandler, FingersCrossedHandler, BufferHandler and SamplingHandler * Fixed BrowserConsoleHandler formatting when using multiple styles * Fixed normalization of exception codes to be always integers even for PDOException which have them as numeric strings * Fixed normalization of SoapFault objects containing non-strings as "detail" * Fixed json encoding across all handlers to always attempt recovery of non-UTF-8 strings instead of failing the whole encoding ### 1.25.1 (2019-09-06) * Fixed forward-compatible interfaces to be compatible with Monolog 1.x too. ### 1.25.0 (2019-09-06) * Deprecated SlackbotHandler, use SlackWebhookHandler or SlackHandler instead * Deprecated RavenHandler, use sentry/sentry 2.x and their Sentry\Monolog\Handler instead * Deprecated HipChatHandler, migrate to Slack and use SlackWebhookHandler or SlackHandler instead * Added forward-compatible interfaces and traits FormattableHandlerInterface, FormattableHandlerTrait, ProcessableHandlerInterface, ProcessableHandlerTrait. If you use modern PHP and want to make code compatible with Monolog 1 and 2 this can help. You will have to require at least Monolog 1.25 though. * Added support for RFC3164 (outdated BSD syslog protocol) to SyslogUdpHandler * Fixed issue in GroupHandler and WhatFailureGroupHandler where setting multiple processors would duplicate records * Fixed issue in SignalHandler restarting syscalls functionality * Fixed normalizers handling of exception backtraces to avoid serializing arguments in some cases * Fixed ZendMonitorHandler to work with the latest Zend Server versions * Fixed ChromePHPHandler to avoid sending more data than latest Chrome versions allow in headers (4KB down from 256KB). ### 1.24.0 (2018-11-05) * BC Notice: If you are extending any of the Monolog's Formatters' `normalize` method, make sure you add the new `$depth = 0` argument to your function signature to avoid strict PHP warnings. * Added a `ResettableInterface` in order to reset/reset/clear/flush handlers and processors * Added a `ProcessorInterface` as an optional way to label a class as being a processor (mostly useful for autowiring dependency containers) * Added a way to log signals being received using Monolog\SignalHandler * Added ability to customize error handling at the Logger level using Logger::setExceptionHandler * Added InsightOpsHandler to migrate users of the LogEntriesHandler * Added protection to NormalizerFormatter against circular and very deep structures, it now stops normalizing at a depth of 9 * Added capture of stack traces to ErrorHandler when logging PHP errors * Added RavenHandler support for a `contexts` context or extra key to forward that to Sentry's contexts * Added forwarding of context info to FluentdFormatter * Added SocketHandler::setChunkSize to override the default chunk size in case you must send large log lines to rsyslog for example * Added ability to extend/override BrowserConsoleHandler * Added SlackWebhookHandler::getWebhookUrl and SlackHandler::getToken to enable class extensibility * Added SwiftMailerHandler::getSubjectFormatter to enable class extensibility * Dropped official support for HHVM in test builds * Fixed normalization of exception traces when call_user_func is used to avoid serializing objects and the data they contain * Fixed naming of fields in Slack handler, all field names are now capitalized in all cases * Fixed HipChatHandler bug where slack dropped messages randomly * Fixed normalization of objects in Slack handlers * Fixed support for PHP7's Throwable in NewRelicHandler * Fixed race bug when StreamHandler sometimes incorrectly reported it failed to create a directory * Fixed table row styling issues in HtmlFormatter * Fixed RavenHandler dropping the message when logging exception * Fixed WhatFailureGroupHandler skipping processors when using handleBatch and implement it where possible * Fixed display of anonymous class names ### 1.23.0 (2017-06-19) * Improved SyslogUdpHandler's support for RFC5424 and added optional `$ident` argument * Fixed GelfHandler truncation to be per field and not per message * Fixed compatibility issue with PHP <5.3.6 * Fixed support for headless Chrome in ChromePHPHandler * Fixed support for latest Aws SDK in DynamoDbHandler * Fixed support for SwiftMailer 6.0+ in SwiftMailerHandler ### 1.22.1 (2017-03-13) * Fixed lots of minor issues in the new Slack integrations * Fixed support for allowInlineLineBreaks in LineFormatter when formatting exception backtraces ### 1.22.0 (2016-11-26) * Added SlackbotHandler and SlackWebhookHandler to set up Slack integration more easily * Added MercurialProcessor to add mercurial revision and branch names to log records * Added support for AWS SDK v3 in DynamoDbHandler * Fixed fatal errors occurring when normalizing generators that have been fully consumed * Fixed RollbarHandler to include a level (rollbar level), monolog_level (original name), channel and datetime (unix) * Fixed RollbarHandler not flushing records automatically, calling close() explicitly is not necessary anymore * Fixed SyslogUdpHandler to avoid sending empty frames * Fixed a few PHP 7.0 and 7.1 compatibility issues ### 1.21.0 (2016-07-29) * Break: Reverted the addition of $context when the ErrorHandler handles regular php errors from 1.20.0 as it was causing issues * Added support for more formats in RotatingFileHandler::setFilenameFormat as long as they have Y, m and d in order * Added ability to format the main line of text the SlackHandler sends by explicitly setting a formatter on the handler * Added information about SoapFault instances in NormalizerFormatter * Added $handleOnlyReportedErrors option on ErrorHandler::registerErrorHandler (default true) to allow logging of all errors no matter the error_reporting level ### 1.20.0 (2016-07-02) * Added FingersCrossedHandler::activate() to manually trigger the handler regardless of the activation policy * Added StreamHandler::getUrl to retrieve the stream's URL * Added ability to override addRow/addTitle in HtmlFormatter * Added the $context to context information when the ErrorHandler handles a regular php error * Deprecated RotatingFileHandler::setFilenameFormat to only support 3 formats: Y, Y-m and Y-m-d * Fixed WhatFailureGroupHandler to work with PHP7 throwables * Fixed a few minor bugs ### 1.19.0 (2016-04-12) * Break: StreamHandler will not close streams automatically that it does not own. If you pass in a stream (not a path/url), then it will not close it for you. You can retrieve those using getStream() if needed * Added DeduplicationHandler to remove duplicate records from notifications across multiple requests, useful for email or other notifications on errors * Added ability to use `%message%` and other LineFormatter replacements in the subject line of emails sent with NativeMailHandler and SwiftMailerHandler * Fixed HipChatHandler handling of long messages ### 1.18.2 (2016-04-02) * Fixed ElasticaFormatter to use more precise dates * Fixed GelfMessageFormatter sending too long messages ### 1.18.1 (2016-03-13) * Fixed SlackHandler bug where slack dropped messages randomly * Fixed RedisHandler issue when using with the PHPRedis extension * Fixed AmqpHandler content-type being incorrectly set when using with the AMQP extension * Fixed BrowserConsoleHandler regression ### 1.18.0 (2016-03-01) * Added optional reduction of timestamp precision via `Logger->useMicrosecondTimestamps(false)`, disabling it gets you a bit of performance boost but reduces the precision to the second instead of microsecond * Added possibility to skip some extra stack frames in IntrospectionProcessor if you have some library wrapping Monolog that is always adding frames * Added `Logger->withName` to clone a logger (keeping all handlers) with a new name * Added FluentdFormatter for the Fluentd unix socket protocol * Added HandlerWrapper base class to ease the creation of handler wrappers, just extend it and override as needed * Added support for replacing context sub-keys using `%context.*%` in LineFormatter * Added support for `payload` context value in RollbarHandler * Added setRelease to RavenHandler to describe the application version, sent with every log * Added support for `fingerprint` context value in RavenHandler * Fixed JSON encoding errors that would gobble up the whole log record, we now handle those more gracefully by dropping chars as needed * Fixed write timeouts in SocketHandler and derivatives, set to 10sec by default, lower it with `setWritingTimeout()` * Fixed PHP7 compatibility with regard to Exception/Throwable handling in a few places ### 1.17.2 (2015-10-14) * Fixed ErrorHandler compatibility with non-Monolog PSR-3 loggers * Fixed SlackHandler handling to use slack functionalities better * Fixed SwiftMailerHandler bug when sending multiple emails they all had the same id * Fixed 5.3 compatibility regression ### 1.17.1 (2015-08-31) * Fixed RollbarHandler triggering PHP notices ### 1.17.0 (2015-08-30) * Added support for `checksum` and `release` context/extra values in RavenHandler * Added better support for exceptions in RollbarHandler * Added UidProcessor::getUid * Added support for showing the resource type in NormalizedFormatter * Fixed IntrospectionProcessor triggering PHP notices ### 1.16.0 (2015-08-09) * Added IFTTTHandler to notify ifttt.com triggers * Added Logger::setHandlers() to allow setting/replacing all handlers * Added $capSize in RedisHandler to cap the log size * Fixed StreamHandler creation of directory to only trigger when the first log write happens * Fixed bug in the handling of curl failures * Fixed duplicate logging of fatal errors when both error and fatal error handlers are registered in monolog's ErrorHandler * Fixed missing fatal errors records with handlers that need to be closed to flush log records * Fixed TagProcessor::addTags support for associative arrays ### 1.15.0 (2015-07-12) * Added addTags and setTags methods to change a TagProcessor * Added automatic creation of directories if they are missing for a StreamHandler to open a log file * Added retry functionality to Loggly, Cube and Mandrill handlers so they retry up to 5 times in case of network failure * Fixed process exit code being incorrectly reset to 0 if ErrorHandler::registerExceptionHandler was used * Fixed HTML/JS escaping in BrowserConsoleHandler * Fixed JSON encoding errors being silently suppressed (PHP 5.5+ only) ### 1.14.0 (2015-06-19) * Added PHPConsoleHandler to send record to Chrome's PHP Console extension and library * Added support for objects implementing __toString in the NormalizerFormatter * Added support for HipChat's v2 API in HipChatHandler * Added Logger::setTimezone() to initialize the timezone monolog should use in case date.timezone isn't correct for your app * Added an option to send formatted message instead of the raw record on PushoverHandler via ->useFormattedMessage(true) * Fixed curl errors being silently suppressed ### 1.13.1 (2015-03-09) * Fixed regression in HipChat requiring a new token to be created ### 1.13.0 (2015-03-05) * Added Registry::hasLogger to check for the presence of a logger instance * Added context.user support to RavenHandler * Added HipChat API v2 support in the HipChatHandler * Added NativeMailerHandler::addParameter to pass params to the mail() process * Added context data to SlackHandler when $includeContextAndExtra is true * Added ability to customize the Swift_Message per-email in SwiftMailerHandler * Fixed SwiftMailerHandler to lazily create message instances if a callback is provided * Fixed serialization of INF and NaN values in Normalizer and LineFormatter ### 1.12.0 (2014-12-29) * Break: HandlerInterface::isHandling now receives a partial record containing only a level key. This was always the intent and does not break any Monolog handler but is strictly speaking a BC break and you should check if you relied on any other field in your own handlers. * Added PsrHandler to forward records to another PSR-3 logger * Added SamplingHandler to wrap around a handler and include only every Nth record * Added MongoDBFormatter to support better storage with MongoDBHandler (it must be enabled manually for now) * Added exception codes in the output of most formatters * Added LineFormatter::includeStacktraces to enable exception stack traces in logs (uses more than one line) * Added $useShortAttachment to SlackHandler to minify attachment size and $includeExtra to append extra data * Added $host to HipChatHandler for users of private instances * Added $transactionName to NewRelicHandler and support for a transaction_name context value * Fixed MandrillHandler to avoid outputting API call responses * Fixed some non-standard behaviors in SyslogUdpHandler ### 1.11.0 (2014-09-30) * Break: The NewRelicHandler extra and context data are now prefixed with extra_ and context_ to avoid clashes. Watch out if you have scripts reading those from the API and rely on names * Added WhatFailureGroupHandler to suppress any exception coming from the wrapped handlers and avoid chain failures if a logging service fails * Added MandrillHandler to send emails via the Mandrillapp.com API * Added SlackHandler to log records to a Slack.com account * Added FleepHookHandler to log records to a Fleep.io account * Added LogglyHandler::addTag to allow adding tags to an existing handler * Added $ignoreEmptyContextAndExtra to LineFormatter to avoid empty [] at the end * Added $useLocking to StreamHandler and RotatingFileHandler to enable flock() while writing * Added support for PhpAmqpLib in the AmqpHandler * Added FingersCrossedHandler::clear and BufferHandler::clear to reset them between batches in long running jobs * Added support for adding extra fields from $_SERVER in the WebProcessor * Fixed support for non-string values in PrsLogMessageProcessor * Fixed SwiftMailer messages being sent with the wrong date in long running scripts * Fixed minor PHP 5.6 compatibility issues * Fixed BufferHandler::close being called twice ### 1.10.0 (2014-06-04) * Added Logger::getHandlers() and Logger::getProcessors() methods * Added $passthruLevel argument to FingersCrossedHandler to let it always pass some records through even if the trigger level is not reached * Added support for extra data in NewRelicHandler * Added $expandNewlines flag to the ErrorLogHandler to create multiple log entries when a message has multiple lines ### 1.9.1 (2014-04-24) * Fixed regression in RotatingFileHandler file permissions * Fixed initialization of the BufferHandler to make sure it gets flushed after receiving records * Fixed ChromePHPHandler and FirePHPHandler's activation strategies to be more conservative ### 1.9.0 (2014-04-20) * Added LogEntriesHandler to send logs to a LogEntries account * Added $filePermissions to tweak file mode on StreamHandler and RotatingFileHandler * Added $useFormatting flag to MemoryProcessor to make it send raw data in bytes * Added support for table formatting in FirePHPHandler via the table context key * Added a TagProcessor to add tags to records, and support for tags in RavenHandler * Added $appendNewline flag to the JsonFormatter to enable using it when logging to files * Added sound support to the PushoverHandler * Fixed multi-threading support in StreamHandler * Fixed empty headers issue when ChromePHPHandler received no records * Fixed default format of the ErrorLogHandler ### 1.8.0 (2014-03-23) * Break: the LineFormatter now strips newlines by default because this was a bug, set $allowInlineLineBreaks to true if you need them * Added BrowserConsoleHandler to send logs to any browser's console via console.log() injection in the output * Added FilterHandler to filter records and only allow those of a given list of levels through to the wrapped handler * Added FlowdockHandler to send logs to a Flowdock account * Added RollbarHandler to send logs to a Rollbar account * Added HtmlFormatter to send prettier log emails with colors for each log level * Added GitProcessor to add the current branch/commit to extra record data * Added a Monolog\Registry class to allow easier global access to pre-configured loggers * Added support for the new official graylog2/gelf-php lib for GelfHandler, upgrade if you can by replacing the mlehner/gelf-php requirement * Added support for HHVM * Added support for Loggly batch uploads * Added support for tweaking the content type and encoding in NativeMailerHandler * Added $skipClassesPartials to tweak the ignored classes in the IntrospectionProcessor * Fixed batch request support in GelfHandler ### 1.7.0 (2013-11-14) * Added ElasticSearchHandler to send logs to an Elastic Search server * Added DynamoDbHandler and ScalarFormatter to send logs to Amazon's Dynamo DB * Added SyslogUdpHandler to send logs to a remote syslogd server * Added LogglyHandler to send logs to a Loggly account * Added $level to IntrospectionProcessor so it only adds backtraces when needed * Added $version to LogstashFormatter to allow using the new v1 Logstash format * Added $appName to NewRelicHandler * Added configuration of Pushover notification retries/expiry * Added $maxColumnWidth to NativeMailerHandler to change the 70 chars default * Added chainability to most setters for all handlers * Fixed RavenHandler batch processing so it takes the message from the record with highest priority * Fixed HipChatHandler batch processing so it sends all messages at once * Fixed issues with eAccelerator * Fixed and improved many small things ### 1.6.0 (2013-07-29) * Added HipChatHandler to send logs to a HipChat chat room * Added ErrorLogHandler to send logs to PHP's error_log function * Added NewRelicHandler to send logs to NewRelic's service * Added Monolog\ErrorHandler helper class to register a Logger as exception/error/fatal handler * Added ChannelLevelActivationStrategy for the FingersCrossedHandler to customize levels by channel * Added stack traces output when normalizing exceptions (json output & co) * Added Monolog\Logger::API constant (currently 1) * Added support for ChromePHP's v4.0 extension * Added support for message priorities in PushoverHandler, see $highPriorityLevel and $emergencyLevel * Added support for sending messages to multiple users at once with the PushoverHandler * Fixed RavenHandler's support for batch sending of messages (when behind a Buffer or FingersCrossedHandler) * Fixed normalization of Traversables with very large data sets, only the first 1000 items are shown now * Fixed issue in RotatingFileHandler when an open_basedir restriction is active * Fixed minor issues in RavenHandler and bumped the API to Raven 0.5.0 * Fixed SyslogHandler issue when many were used concurrently with different facilities ### 1.5.0 (2013-04-23) * Added ProcessIdProcessor to inject the PID in log records * Added UidProcessor to inject a unique identifier to all log records of one request/run * Added support for previous exceptions in the LineFormatter exception serialization * Added Monolog\Logger::getLevels() to get all available levels * Fixed ChromePHPHandler so it avoids sending headers larger than Chrome can handle ### 1.4.1 (2013-04-01) * Fixed exception formatting in the LineFormatter to be more minimalistic * Fixed RavenHandler's handling of context/extra data, requires Raven client >0.1.0 * Fixed log rotation in RotatingFileHandler to work with long running scripts spanning multiple days * Fixed WebProcessor array access so it checks for data presence * Fixed Buffer, Group and FingersCrossed handlers to make use of their processors ### 1.4.0 (2013-02-13) * Added RedisHandler to log to Redis via the Predis library or the phpredis extension * Added ZendMonitorHandler to log to the Zend Server monitor * Added the possibility to pass arrays of handlers and processors directly in the Logger constructor * Added `$useSSL` option to the PushoverHandler which is enabled by default * Fixed ChromePHPHandler and FirePHPHandler issue when multiple instances are used simultaneously * Fixed header injection capability in the NativeMailHandler ### 1.3.1 (2013-01-11) * Fixed LogstashFormatter to be usable with stream handlers * Fixed GelfMessageFormatter levels on Windows ### 1.3.0 (2013-01-08) * Added PSR-3 compliance, the `Monolog\Logger` class is now an instance of `Psr\Log\LoggerInterface` * Added PsrLogMessageProcessor that you can selectively enable for full PSR-3 compliance * Added LogstashFormatter (combine with SocketHandler or StreamHandler to send logs to Logstash) * Added PushoverHandler to send mobile notifications * Added CouchDBHandler and DoctrineCouchDBHandler * Added RavenHandler to send data to Sentry servers * Added support for the new MongoClient class in MongoDBHandler * Added microsecond precision to log records' timestamps * Added `$flushOnOverflow` param to BufferHandler to flush by batches instead of losing the oldest entries * Fixed normalization of objects with cyclic references ### 1.2.1 (2012-08-29) * Added new $logopts arg to SyslogHandler to provide custom openlog options * Fixed fatal error in SyslogHandler ### 1.2.0 (2012-08-18) * Added AmqpHandler (for use with AMQP servers) * Added CubeHandler * Added NativeMailerHandler::addHeader() to send custom headers in mails * Added the possibility to specify more than one recipient in NativeMailerHandler * Added the possibility to specify float timeouts in SocketHandler * Added NOTICE and EMERGENCY levels to conform with RFC 5424 * Fixed the log records to use the php default timezone instead of UTC * Fixed BufferHandler not being flushed properly on PHP fatal errors * Fixed normalization of exotic resource types * Fixed the default format of the SyslogHandler to avoid duplicating datetimes in syslog ### 1.1.0 (2012-04-23) * Added Monolog\Logger::isHandling() to check if a handler will handle the given log level * Added ChromePHPHandler * Added MongoDBHandler * Added GelfHandler (for use with Graylog2 servers) * Added SocketHandler (for use with syslog-ng for example) * Added NormalizerFormatter * Added the possibility to change the activation strategy of the FingersCrossedHandler * Added possibility to show microseconds in logs * Added `server` and `referer` to WebProcessor output ### 1.0.2 (2011-10-24) * Fixed bug in IE with large response headers and FirePHPHandler ### 1.0.1 (2011-08-25) * Added MemoryPeakUsageProcessor and MemoryUsageProcessor * Added Monolog\Logger::getName() to get a logger's channel name ### 1.0.0 (2011-07-06) * Added IntrospectionProcessor to get info from where the logger was called * Fixed WebProcessor in CLI ### 1.0.0-RC1 (2011-07-01) * Initial release ================================================ FILE: lib/Google/vendor/monolog/monolog/LICENSE ================================================ Copyright (c) 2011-2020 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. ================================================ FILE: lib/Google/vendor/monolog/monolog/README.md ================================================

Monolog

# Monolog - Logging for PHP [![Continuous Integration](https://github.com/Seldaek/monolog/workflows/Continuous%20Integration/badge.svg?branch=main)](https://github.com/Seldaek/monolog/actions) [![Total Downloads](https://img.shields.io/packagist/dt/monolog/monolog.svg)](https://packagist.org/packages/monolog/monolog) [![Latest Stable Version](https://img.shields.io/packagist/v/monolog/monolog.svg)](https://packagist.org/packages/monolog/monolog) >**Note** This is the **documentation for Monolog 3.x**, if you are using older releases >see the documentation for [Monolog 2.x](https://github.com/Seldaek/monolog/blob/2.x/README.md) or [Monolog 1.x](https://github.com/Seldaek/monolog/blob/1.x/README.md) Monolog sends your logs to files, sockets, inboxes, databases and various web services. See the complete list of handlers below. Special handlers allow you to build advanced logging strategies. This library implements the [PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md) interface that you can type-hint against in your own libraries to keep a maximum of interoperability. You can also use it in your applications to make sure you can always use another compatible logger at a later time. As of 1.11.0 Monolog public APIs will also accept PSR-3 log levels. Internally Monolog still uses its own level scheme since it predates PSR-3. ## Installation Install the latest version with ```bash composer require monolog/monolog ``` ## Basic Usage ```php pushHandler(new StreamHandler('path/to/your.log', Level::Warning)); // add records to the log $log->warning('Foo'); $log->error('Bar'); ``` ## Documentation - [Usage Instructions](doc/01-usage.md) - [Handlers, Formatters and Processors](doc/02-handlers-formatters-processors.md) - [Utility Classes](doc/03-utilities.md) - [Extending Monolog](doc/04-extending.md) - [Log Record Structure](doc/message-structure.md) ## Support Monolog Financially Get supported Monolog and help fund the project with the [Tidelift Subscription](https://tidelift.com/subscription/pkg/packagist-monolog-monolog?utm_source=packagist-monolog-monolog&utm_medium=referral&utm_campaign=enterprise) or via [GitHub sponsorship](https://github.com/sponsors/Seldaek). Tidelift delivers commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. ## Third Party Packages Third party handlers, formatters and processors are [listed in the wiki](https://github.com/Seldaek/monolog/wiki/Third-Party-Packages). You can also add your own there if you publish one. ## About ### Requirements - Monolog `^3.0` works with PHP 8.1 or above. - Monolog `^2.5` works with PHP 7.2 or above. - Monolog `^1.25` works with PHP 5.3 up to 8.1, but is not very maintained anymore and will not receive PHP support fixes anymore. ### Support Monolog 1.x support is somewhat limited at this point and only important fixes will be done. You should migrate to Monolog 2 or 3 where possible to benefit from all the latest features and fixes. ### Submitting bugs and feature requests Bugs and feature request are tracked on [GitHub](https://github.com/Seldaek/monolog/issues) ### Framework Integrations - Frameworks and libraries using [PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md) can be used very easily with Monolog since it implements the interface. - [Symfony](http://symfony.com) comes out of the box with Monolog. - [Laravel](http://laravel.com/) comes out of the box with Monolog. - [Lumen](http://lumen.laravel.com/) comes out of the box with Monolog. - [PPI](https://github.com/ppi/framework) comes out of the box with Monolog. - [CakePHP](http://cakephp.org/) is usable with Monolog via the [cakephp-monolog](https://github.com/jadb/cakephp-monolog) plugin. - [XOOPS 2.6](http://xoops.org/) comes out of the box with Monolog. - [Aura.Web_Project](https://github.com/auraphp/Aura.Web_Project) comes out of the box with Monolog. - [Nette Framework](http://nette.org/en/) is usable with Monolog via the [contributte/monolog](https://github.com/contributte/monolog) or [orisai/nette-monolog](https://github.com/orisai/nette-monolog) extensions. - [Proton Micro Framework](https://github.com/alexbilbie/Proton) comes out of the box with Monolog. - [FuelPHP](http://fuelphp.com/) comes out of the box with Monolog. - [Equip Framework](https://github.com/equip/framework) comes out of the box with Monolog. - [Yii 2](http://www.yiiframework.com/) is usable with Monolog via the [yii2-monolog](https://github.com/merorafael/yii2-monolog) or [yii2-psr-log-target](https://github.com/samdark/yii2-psr-log-target) plugins. - [Hawkbit Micro Framework](https://github.com/HawkBitPhp/hawkbit) comes out of the box with Monolog. - [SilverStripe 4](https://www.silverstripe.org/) comes out of the box with Monolog. - [Drupal](https://www.drupal.org/) is usable with Monolog via the [monolog](https://www.drupal.org/project/monolog) module. - [Aimeos ecommerce framework](https://aimeos.org/) is usable with Monolog via the [ai-monolog](https://github.com/aimeos/ai-monolog) extension. - [Magento](https://magento.com/) comes out of the box with Monolog. - [Spiral Framework](https://spiral.dev) comes out of the box with Monolog bridge. - [WebFramework](https://web-framework.com/) comes out of the box with Monolog. ### Author Jordi Boggiano - -
See also the list of [contributors](https://github.com/Seldaek/monolog/contributors) who participated in this project. ### License Monolog is licensed under the MIT License - see the [LICENSE](LICENSE) file for details ### Acknowledgements This library is heavily inspired by Python's [Logbook](https://logbook.readthedocs.io/en/stable/) library, although most concepts have been adjusted to fit to the PHP world. ================================================ FILE: lib/Google/vendor/monolog/monolog/composer.json ================================================ { "name": "monolog/monolog", "description": "Sends your logs to files, sockets, inboxes, databases and various web services", "keywords": ["log", "logging", "psr-3"], "homepage": "https://github.com/Seldaek/monolog", "type": "library", "license": "MIT", "authors": [ { "name": "Jordi Boggiano", "email": "j.boggiano@seld.be", "homepage": "https://seld.be" } ], "require": { "php": ">=8.1", "psr/log": "^2.0 || ^3.0" }, "require-dev": { "ext-json": "*", "aws/aws-sdk-php": "^3.0", "doctrine/couchdb": "~1.0@dev", "elasticsearch/elasticsearch": "^7 || ^8", "graylog2/gelf-php": "^1.4.2 || ^2.0", "guzzlehttp/guzzle": "^7.4.5", "guzzlehttp/psr7": "^2.2", "mongodb/mongodb": "^1.8 || ^2.0", "php-amqplib/php-amqplib": "~2.4 || ^3", "php-console/php-console": "^3.1.8", "phpstan/phpstan": "^2", "phpstan/phpstan-deprecation-rules": "^2", "phpstan/phpstan-strict-rules": "^2", "phpunit/phpunit": "^10.5.17 || ^11.0.7", "predis/predis": "^1.1 || ^2", "rollbar/rollbar": "^4.0", "ruflin/elastica": "^7 || ^8", "symfony/mailer": "^5.4 || ^6", "symfony/mime": "^5.4 || ^6" }, "suggest": { "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", "doctrine/couchdb": "Allow sending log messages to a CouchDB server", "ruflin/elastica": "Allow sending log messages to an Elastic Search server", "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client", "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)", "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)", "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", "rollbar/rollbar": "Allow sending log messages to Rollbar", "ext-mbstring": "Allow to work properly with unicode symbols", "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)", "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler", "ext-openssl": "Required to send log messages using SSL" }, "autoload": { "psr-4": {"Monolog\\": "src/Monolog"} }, "autoload-dev": { "psr-4": {"Monolog\\": "tests/Monolog"} }, "provide": { "psr/log-implementation": "3.0.0" }, "extra": { "branch-alias": { "dev-main": "3.x-dev" } }, "scripts": { "test": "@php vendor/bin/phpunit", "phpstan": "@php vendor/bin/phpstan analyse" }, "config": { "lock": false, "sort-packages": true, "platform-check": false, "allow-plugins": { "php-http/discovery": false } } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Attribute/AsMonologProcessor.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Attribute; /** * A reusable attribute to help configure a class or a method as a processor. * * Using it offers no guarantee: it needs to be leveraged by a Monolog third-party consumer. * * Using it with the Monolog library only has no effect at all: processors should still be turned into a callable if * needed and manually pushed to the loggers and to the processable handlers. */ #[\Attribute(\Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)] class AsMonologProcessor { /** * @param string|null $channel The logging channel the processor should be pushed to. * @param string|null $handler The handler the processor should be pushed to. * @param string|null $method The method that processes the records (if the attribute is used at the class level). * @param int|null $priority The priority of the processor so the order can be determined. */ public function __construct( public readonly ?string $channel = null, public readonly ?string $handler = null, public readonly ?string $method = null, public readonly ?int $priority = null ) { } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Attribute/WithMonologChannel.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Attribute; /** * A reusable attribute to help configure a class as expecting a given logger channel. * * Using it offers no guarantee: it needs to be leveraged by a Monolog third-party consumer. * * Using it with the Monolog library only has no effect at all: wiring the logger instance into * other classes is not managed by Monolog. */ #[\Attribute(\Attribute::TARGET_CLASS)] final class WithMonologChannel { public function __construct( public readonly string $channel ) { } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/DateTimeImmutable.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog; class_alias(JsonSerializableDateTimeImmutable::class, 'Monolog\DateTimeImmutable'); // @phpstan-ignore-next-line if (false) { /** * @deprecated Use \Monolog\JsonSerializableDateTimeImmutable instead. */ class DateTimeImmutable extends JsonSerializableDateTimeImmutable { } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/ErrorHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog; use Closure; use Psr\Log\LoggerInterface; use Psr\Log\LogLevel; /** * Monolog error handler * * A facility to enable logging of runtime errors, exceptions and fatal errors. * * Quick setup: ErrorHandler::register($logger); * * @author Jordi Boggiano */ class ErrorHandler { private Closure|null $previousExceptionHandler = null; /** @var array an array of class name to LogLevel::* constant mapping */ private array $uncaughtExceptionLevelMap = []; /** @var Closure|true|null */ private Closure|bool|null $previousErrorHandler = null; /** @var array an array of E_* constant to LogLevel::* constant mapping */ private array $errorLevelMap = []; private bool $handleOnlyReportedErrors = true; private bool $hasFatalErrorHandler = false; private string $fatalLevel = LogLevel::ALERT; private string|null $reservedMemory = null; /** @var ?array{type: int, message: string, file: string, line: int, trace: mixed} */ private array|null $lastFatalData = null; private const FATAL_ERRORS = [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR]; public function __construct( private LoggerInterface $logger ) { } /** * Registers a new ErrorHandler for a given Logger * * By default it will handle errors, exceptions and fatal errors * * @param array|false $errorLevelMap an array of E_* constant to LogLevel::* constant mapping, or false to disable error handling * @param array|false $exceptionLevelMap an array of class name to LogLevel::* constant mapping, or false to disable exception handling * @param LogLevel::*|null|false $fatalLevel a LogLevel::* constant, null to use the default LogLevel::ALERT or false to disable fatal error handling * @return static */ public static function register(LoggerInterface $logger, $errorLevelMap = [], $exceptionLevelMap = [], $fatalLevel = null): self { /** @phpstan-ignore-next-line */ $handler = new static($logger); if ($errorLevelMap !== false) { $handler->registerErrorHandler($errorLevelMap); } if ($exceptionLevelMap !== false) { $handler->registerExceptionHandler($exceptionLevelMap); } if ($fatalLevel !== false) { $handler->registerFatalHandler($fatalLevel); } return $handler; } /** * @param array $levelMap an array of class name to LogLevel::* constant mapping * @return $this */ public function registerExceptionHandler(array $levelMap = [], bool $callPrevious = true): self { $prev = set_exception_handler(function (\Throwable $e): void { $this->handleException($e); }); $this->uncaughtExceptionLevelMap = $levelMap; foreach ($this->defaultExceptionLevelMap() as $class => $level) { if (!isset($this->uncaughtExceptionLevelMap[$class])) { $this->uncaughtExceptionLevelMap[$class] = $level; } } if ($callPrevious && null !== $prev) { $this->previousExceptionHandler = $prev(...); } return $this; } /** * @param array $levelMap an array of E_* constant to LogLevel::* constant mapping * @return $this */ public function registerErrorHandler(array $levelMap = [], bool $callPrevious = true, int $errorTypes = -1, bool $handleOnlyReportedErrors = true): self { $prev = set_error_handler($this->handleError(...), $errorTypes); $this->errorLevelMap = array_replace($this->defaultErrorLevelMap(), $levelMap); if ($callPrevious) { $this->previousErrorHandler = $prev !== null ? $prev(...) : true; } else { $this->previousErrorHandler = null; } $this->handleOnlyReportedErrors = $handleOnlyReportedErrors; return $this; } /** * @param LogLevel::*|null $level a LogLevel::* constant, null to use the default LogLevel::ALERT * @param int $reservedMemorySize Amount of KBs to reserve in memory so that it can be freed when handling fatal errors giving Monolog some room in memory to get its job done * @return $this */ public function registerFatalHandler($level = null, int $reservedMemorySize = 20): self { register_shutdown_function($this->handleFatalError(...)); $this->reservedMemory = str_repeat(' ', 1024 * $reservedMemorySize); $this->fatalLevel = null === $level ? LogLevel::ALERT : $level; $this->hasFatalErrorHandler = true; return $this; } /** * @return array */ protected function defaultExceptionLevelMap(): array { return [ 'ParseError' => LogLevel::CRITICAL, 'Throwable' => LogLevel::ERROR, ]; } /** * @return array */ protected function defaultErrorLevelMap(): array { return [ E_ERROR => LogLevel::CRITICAL, E_WARNING => LogLevel::WARNING, E_PARSE => LogLevel::ALERT, E_NOTICE => LogLevel::NOTICE, E_CORE_ERROR => LogLevel::CRITICAL, E_CORE_WARNING => LogLevel::WARNING, E_COMPILE_ERROR => LogLevel::ALERT, E_COMPILE_WARNING => LogLevel::WARNING, E_USER_ERROR => LogLevel::ERROR, E_USER_WARNING => LogLevel::WARNING, E_USER_NOTICE => LogLevel::NOTICE, 2048 => LogLevel::NOTICE, // E_STRICT E_RECOVERABLE_ERROR => LogLevel::ERROR, E_DEPRECATED => LogLevel::NOTICE, E_USER_DEPRECATED => LogLevel::NOTICE, ]; } private function handleException(\Throwable $e): never { $level = LogLevel::ERROR; foreach ($this->uncaughtExceptionLevelMap as $class => $candidate) { if ($e instanceof $class) { $level = $candidate; break; } } $this->logger->log( $level, sprintf('Uncaught Exception %s: "%s" at %s line %s', Utils::getClass($e), $e->getMessage(), $e->getFile(), $e->getLine()), ['exception' => $e] ); if (null !== $this->previousExceptionHandler) { ($this->previousExceptionHandler)($e); } if (!headers_sent() && \in_array(strtolower((string) \ini_get('display_errors')), ['0', '', 'false', 'off', 'none', 'no'], true)) { http_response_code(500); } exit(255); } private function handleError(int $code, string $message, string $file = '', int $line = 0): bool { if ($this->handleOnlyReportedErrors && 0 === (error_reporting() & $code)) { return false; } // fatal error codes are ignored if a fatal error handler is present as well to avoid duplicate log entries if (!$this->hasFatalErrorHandler || !\in_array($code, self::FATAL_ERRORS, true)) { $level = $this->errorLevelMap[$code] ?? LogLevel::CRITICAL; $this->logger->log($level, self::codeToString($code).': '.$message, ['code' => $code, 'message' => $message, 'file' => $file, 'line' => $line]); } else { $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); array_shift($trace); // Exclude handleError from trace $this->lastFatalData = ['type' => $code, 'message' => $message, 'file' => $file, 'line' => $line, 'trace' => $trace]; } if ($this->previousErrorHandler === true) { return false; } if ($this->previousErrorHandler instanceof Closure) { return (bool) ($this->previousErrorHandler)($code, $message, $file, $line); } return true; } /** * @private */ public function handleFatalError(): void { $this->reservedMemory = ''; if (\is_array($this->lastFatalData)) { $lastError = $this->lastFatalData; } else { $lastError = error_get_last(); } if (\is_array($lastError) && \in_array($lastError['type'], self::FATAL_ERRORS, true)) { $trace = $lastError['trace'] ?? null; $this->logger->log( $this->fatalLevel, 'Fatal Error ('.self::codeToString($lastError['type']).'): '.$lastError['message'], ['code' => $lastError['type'], 'message' => $lastError['message'], 'file' => $lastError['file'], 'line' => $lastError['line'], 'trace' => $trace] ); if ($this->logger instanceof Logger) { foreach ($this->logger->getHandlers() as $handler) { $handler->close(); } } } } private static function codeToString(int $code): string { return match ($code) { E_ERROR => 'E_ERROR', E_WARNING => 'E_WARNING', E_PARSE => 'E_PARSE', E_NOTICE => 'E_NOTICE', E_CORE_ERROR => 'E_CORE_ERROR', E_CORE_WARNING => 'E_CORE_WARNING', E_COMPILE_ERROR => 'E_COMPILE_ERROR', E_COMPILE_WARNING => 'E_COMPILE_WARNING', E_USER_ERROR => 'E_USER_ERROR', E_USER_WARNING => 'E_USER_WARNING', E_USER_NOTICE => 'E_USER_NOTICE', 2048 => 'E_STRICT', E_RECOVERABLE_ERROR => 'E_RECOVERABLE_ERROR', E_DEPRECATED => 'E_DEPRECATED', E_USER_DEPRECATED => 'E_USER_DEPRECATED', default => 'Unknown PHP error', }; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Formatter/ChromePHPFormatter.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Formatter; use Monolog\Level; use Monolog\LogRecord; /** * Formats a log message according to the ChromePHP array format * * @author Christophe Coevoet */ class ChromePHPFormatter implements FormatterInterface { /** * Translates Monolog log levels to Wildfire levels. * * @return 'log'|'info'|'warn'|'error' */ private function toWildfireLevel(Level $level): string { return match ($level) { Level::Debug => 'log', Level::Info => 'info', Level::Notice => 'info', Level::Warning => 'warn', Level::Error => 'error', Level::Critical => 'error', Level::Alert => 'error', Level::Emergency => 'error', }; } /** * @inheritDoc */ public function format(LogRecord $record) { // Retrieve the line and file if set and remove them from the formatted extra $backtrace = 'unknown'; if (isset($record->extra['file'], $record->extra['line'])) { $backtrace = $record->extra['file'].' : '.$record->extra['line']; unset($record->extra['file'], $record->extra['line']); } $message = ['message' => $record->message]; if (\count($record->context) > 0) { $message['context'] = $record->context; } if (\count($record->extra) > 0) { $message['extra'] = $record->extra; } if (\count($message) === 1) { $message = reset($message); } return [ $record->channel, $message, $backtrace, $this->toWildfireLevel($record->level), ]; } /** * @inheritDoc */ public function formatBatch(array $records) { $formatted = []; foreach ($records as $record) { $formatted[] = $this->format($record); } return $formatted; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Formatter/ElasticaFormatter.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Formatter; use Elastica\Document; use Monolog\LogRecord; /** * Format a log message into an Elastica Document * * @author Jelle Vink */ class ElasticaFormatter extends NormalizerFormatter { /** * @var string Elastic search index name */ protected string $index; /** * @var string|null Elastic search document type */ protected string|null $type; /** * @param string $index Elastic Search index name * @param ?string $type Elastic Search document type, deprecated as of Elastica 7 */ public function __construct(string $index, ?string $type) { // elasticsearch requires a ISO 8601 format date with optional millisecond precision. parent::__construct('Y-m-d\TH:i:s.uP'); $this->index = $index; $this->type = $type; } /** * @inheritDoc */ public function format(LogRecord $record) { $record = parent::format($record); return $this->getDocument($record); } public function getIndex(): string { return $this->index; } /** * @deprecated since Elastica 7 type has no effect */ public function getType(): string { /** @phpstan-ignore-next-line */ return $this->type; } /** * Convert a log message into an Elastica Document * * @param mixed[] $record */ protected function getDocument(array $record): Document { $document = new Document(); $document->setData($record); $document->setIndex($this->index); return $document; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Formatter/ElasticsearchFormatter.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Formatter; use DateTimeInterface; use Monolog\LogRecord; /** * Format a log message into an Elasticsearch record * * @author Avtandil Kikabidze */ class ElasticsearchFormatter extends NormalizerFormatter { /** * @var string Elasticsearch index name */ protected string $index; /** * @var string Elasticsearch record type */ protected string $type; /** * @param string $index Elasticsearch index name * @param string $type Elasticsearch record type */ public function __construct(string $index, string $type) { // Elasticsearch requires an ISO 8601 format date with optional millisecond precision. parent::__construct(DateTimeInterface::ATOM); $this->index = $index; $this->type = $type; } /** * @inheritDoc */ public function format(LogRecord $record) { $record = parent::format($record); return $this->getDocument($record); } /** * Getter index */ public function getIndex(): string { return $this->index; } /** * Getter type */ public function getType(): string { return $this->type; } /** * Convert a log message into an Elasticsearch record * * @param mixed[] $record Log message * @return mixed[] */ protected function getDocument(array $record): array { $record['_index'] = $this->index; $record['_type'] = $this->type; return $record; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Formatter/FlowdockFormatter.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Formatter; use Monolog\LogRecord; /** * formats the record to be used in the FlowdockHandler * * @author Dominik Liebler * @deprecated Since 2.9.0 and 3.3.0, Flowdock was shutdown we will thus drop this handler in Monolog 4 */ class FlowdockFormatter implements FormatterInterface { private string $source; private string $sourceEmail; public function __construct(string $source, string $sourceEmail) { $this->source = $source; $this->sourceEmail = $sourceEmail; } /** * @inheritDoc * * @return mixed[] */ public function format(LogRecord $record): array { $tags = [ '#logs', '#' . $record->level->toPsrLogLevel(), '#' . $record->channel, ]; foreach ($record->extra as $value) { $tags[] = '#' . $value; } $subject = sprintf( 'in %s: %s - %s', $this->source, $record->level->getName(), $this->getShortMessage($record->message) ); return [ 'source' => $this->source, 'from_address' => $this->sourceEmail, 'subject' => $subject, 'content' => $record->message, 'tags' => $tags, 'project' => $this->source, ]; } /** * @inheritDoc * * @return mixed[][] */ public function formatBatch(array $records): array { $formatted = []; foreach ($records as $record) { $formatted[] = $this->format($record); } return $formatted; } public function getShortMessage(string $message): string { static $hasMbString; if (null === $hasMbString) { $hasMbString = \function_exists('mb_strlen'); } $maxLength = 45; if ($hasMbString) { if (mb_strlen($message, 'UTF-8') > $maxLength) { $message = mb_substr($message, 0, $maxLength - 4, 'UTF-8') . ' ...'; } } else { if (\strlen($message) > $maxLength) { $message = substr($message, 0, $maxLength - 4) . ' ...'; } } return $message; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Formatter/FluentdFormatter.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Formatter; use Monolog\Utils; use Monolog\LogRecord; /** * Class FluentdFormatter * * Serializes a log message to Fluentd unix socket protocol * * Fluentd config: * * * type unix * path /var/run/td-agent/td-agent.sock * * * Monolog setup: * * $logger = new Monolog\Logger('fluent.tag'); * $fluentHandler = new Monolog\Handler\SocketHandler('unix:///var/run/td-agent/td-agent.sock'); * $fluentHandler->setFormatter(new Monolog\Formatter\FluentdFormatter()); * $logger->pushHandler($fluentHandler); * * @author Andrius Putna */ class FluentdFormatter implements FormatterInterface { /** * @var bool $levelTag should message level be a part of the fluentd tag */ protected bool $levelTag = false; public function __construct(bool $levelTag = false) { $this->levelTag = $levelTag; } public function isUsingLevelsInTag(): bool { return $this->levelTag; } public function format(LogRecord $record): string { $tag = $record->channel; if ($this->levelTag) { $tag .= '.' . $record->level->toPsrLogLevel(); } $message = [ 'message' => $record->message, 'context' => $record->context, 'extra' => $record->extra, ]; if (!$this->levelTag) { $message['level'] = $record->level->value; $message['level_name'] = $record->level->getName(); } return Utils::jsonEncode([$tag, $record->datetime->getTimestamp(), $message]); } public function formatBatch(array $records): string { $message = ''; foreach ($records as $record) { $message .= $this->format($record); } return $message; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Formatter/FormatterInterface.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Formatter; use Monolog\LogRecord; /** * Interface for formatters * * @author Jordi Boggiano */ interface FormatterInterface { /** * Formats a log record. * * @param LogRecord $record A record to format * @return mixed The formatted record */ public function format(LogRecord $record); /** * Formats a set of log records. * * @param array $records A set of records to format * @return mixed The formatted set of records */ public function formatBatch(array $records); } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Formatter/GelfMessageFormatter.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Formatter; use Monolog\Level; use Gelf\Message; use Monolog\Utils; use Monolog\LogRecord; /** * Serializes a log message to GELF * @see http://docs.graylog.org/en/latest/pages/gelf.html * * @author Matt Lehner */ class GelfMessageFormatter extends NormalizerFormatter { protected const DEFAULT_MAX_LENGTH = 32766; /** * @var string the name of the system for the Gelf log message */ protected string $systemName; /** * @var string a prefix for 'extra' fields from the Monolog record (optional) */ protected string $extraPrefix; /** * @var string a prefix for 'context' fields from the Monolog record (optional) */ protected string $contextPrefix; /** * @var int max length per field */ protected int $maxLength; /** * Translates Monolog log levels to Graylog2 log priorities. */ private function getGraylog2Priority(Level $level): int { return match ($level) { Level::Debug => 7, Level::Info => 6, Level::Notice => 5, Level::Warning => 4, Level::Error => 3, Level::Critical => 2, Level::Alert => 1, Level::Emergency => 0, }; } /** * @throws \RuntimeException */ public function __construct(?string $systemName = null, ?string $extraPrefix = null, string $contextPrefix = 'ctxt_', ?int $maxLength = null) { if (!class_exists(Message::class)) { throw new \RuntimeException('Composer package graylog2/gelf-php is required to use Monolog\'s GelfMessageFormatter'); } parent::__construct('U.u'); $this->systemName = (null === $systemName || $systemName === '') ? (string) gethostname() : $systemName; $this->extraPrefix = null === $extraPrefix ? '' : $extraPrefix; $this->contextPrefix = $contextPrefix; $this->maxLength = null === $maxLength ? self::DEFAULT_MAX_LENGTH : $maxLength; } /** * @inheritDoc */ public function format(LogRecord $record): Message { $context = $extra = []; if (isset($record->context)) { /** @var array|bool|float|int|string|null> $context */ $context = parent::normalize($record->context); } if (isset($record->extra)) { /** @var array|bool|float|int|string|null> $extra */ $extra = parent::normalize($record->extra); } $message = new Message(); $message ->setTimestamp($record->datetime) ->setShortMessage($record->message) ->setHost($this->systemName) ->setLevel($this->getGraylog2Priority($record->level)); // message length + system name length + 200 for padding / metadata $len = 200 + \strlen($record->message) + \strlen($this->systemName); if ($len > $this->maxLength) { $message->setShortMessage(Utils::substr($record->message, 0, $this->maxLength)); } if (isset($record->channel)) { $message->setAdditional('facility', $record->channel); } foreach ($extra as $key => $val) { $key = (string) preg_replace('#[^\w.-]#', '-', (string) $key); $val = \is_bool($val) ? ($val ? 1 : 0) : $val; $val = \is_scalar($val) || null === $val ? $val : $this->toJson($val); $len = \strlen($this->extraPrefix . $key . $val); if ($len > $this->maxLength) { $message->setAdditional($this->extraPrefix . $key, Utils::substr((string) $val, 0, $this->maxLength)); continue; } $message->setAdditional($this->extraPrefix . $key, $val); } foreach ($context as $key => $val) { $key = (string) preg_replace('#[^\w.-]#', '-', (string) $key); $val = \is_bool($val) ? ($val ? 1 : 0) : $val; $val = \is_scalar($val) || null === $val ? $val : $this->toJson($val); $len = \strlen($this->contextPrefix . $key . $val); if ($len > $this->maxLength) { $message->setAdditional($this->contextPrefix . $key, Utils::substr((string) $val, 0, $this->maxLength)); continue; } $message->setAdditional($this->contextPrefix . $key, $val); } if (!$message->hasAdditional('file') && isset($context['exception']['file'])) { if (1 === preg_match("/^(.+):([0-9]+)$/", $context['exception']['file'], $matches)) { $message->setAdditional('file', $matches[1]); $message->setAdditional('line', $matches[2]); } } return $message; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Formatter/GoogleCloudLoggingFormatter.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Formatter; use DateTimeInterface; use Monolog\LogRecord; /** * Encodes message information into JSON in a format compatible with Cloud logging. * * @see https://cloud.google.com/logging/docs/structured-logging * @see https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry * * @author Luís Cobucci */ class GoogleCloudLoggingFormatter extends JsonFormatter { protected function normalizeRecord(LogRecord $record): array { $normalized = parent::normalizeRecord($record); // Re-key level for GCP logging $normalized['severity'] = $normalized['level_name']; $normalized['time'] = $record->datetime->format(DateTimeInterface::RFC3339_EXTENDED); // Remove keys that are not used by GCP unset($normalized['level'], $normalized['level_name'], $normalized['datetime']); return $normalized; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Formatter/HtmlFormatter.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Formatter; use Monolog\Level; use Monolog\Utils; use Monolog\LogRecord; /** * Formats incoming records into an HTML table * * This is especially useful for html email logging * * @author Tiago Brito */ class HtmlFormatter extends NormalizerFormatter { /** * Translates Monolog log levels to html color priorities. */ protected function getLevelColor(Level $level): string { return match ($level) { Level::Debug => '#CCCCCC', Level::Info => '#28A745', Level::Notice => '#17A2B8', Level::Warning => '#FFC107', Level::Error => '#FD7E14', Level::Critical => '#DC3545', Level::Alert => '#821722', Level::Emergency => '#000000', }; } /** * @param string|null $dateFormat The format of the timestamp: one supported by DateTime::format */ public function __construct(?string $dateFormat = null) { parent::__construct($dateFormat); } /** * Creates an HTML table row * * @param string $th Row header content * @param string $td Row standard cell content * @param bool $escapeTd false if td content must not be html escaped */ protected function addRow(string $th, string $td = ' ', bool $escapeTd = true): string { $th = htmlspecialchars($th, ENT_NOQUOTES, 'UTF-8'); if ($escapeTd) { $td = '
'.htmlspecialchars($td, ENT_NOQUOTES, 'UTF-8').'
'; } return "
\n\n\n"; } /** * Create a HTML h1 tag * * @param string $title Text to be in the h1 */ protected function addTitle(string $title, Level $level): string { $title = htmlspecialchars($title, ENT_NOQUOTES, 'UTF-8'); return '

'.$title.'

'; } /** * Formats a log record. * * @return string The formatted record */ public function format(LogRecord $record): string { $output = $this->addTitle($record->level->getName(), $record->level); $output .= '
$th:".$td."
'; $output .= $this->addRow('Message', $record->message); $output .= $this->addRow('Time', $this->formatDate($record->datetime)); $output .= $this->addRow('Channel', $record->channel); if (\count($record->context) > 0) { $embeddedTable = '
'; foreach ($record->context as $key => $value) { $embeddedTable .= $this->addRow((string) $key, $this->convertToString($value)); } $embeddedTable .= '
'; $output .= $this->addRow('Context', $embeddedTable, false); } if (\count($record->extra) > 0) { $embeddedTable = ''; foreach ($record->extra as $key => $value) { $embeddedTable .= $this->addRow((string) $key, $this->convertToString($value)); } $embeddedTable .= '
'; $output .= $this->addRow('Extra', $embeddedTable, false); } return $output.''; } /** * Formats a set of log records. * * @return string The formatted set of records */ public function formatBatch(array $records): string { $message = ''; foreach ($records as $record) { $message .= $this->format($record); } return $message; } /** * @param mixed $data */ protected function convertToString($data): string { if (null === $data || \is_scalar($data)) { return (string) $data; } $data = $this->normalize($data); return Utils::jsonEncode($data, JSON_PRETTY_PRINT | Utils::DEFAULT_JSON_FLAGS, true); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Formatter/JsonFormatter.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Formatter; use Stringable; use Throwable; use Monolog\LogRecord; /** * Encodes whatever record data is passed to it as json * * This can be useful to log to databases or remote APIs * * @author Jordi Boggiano */ class JsonFormatter extends NormalizerFormatter { public const BATCH_MODE_JSON = 1; public const BATCH_MODE_NEWLINES = 2; /** @var self::BATCH_MODE_* */ protected int $batchMode; protected bool $appendNewline; protected bool $ignoreEmptyContextAndExtra; protected bool $includeStacktraces = false; /** * @param self::BATCH_MODE_* $batchMode */ public function __construct(int $batchMode = self::BATCH_MODE_JSON, bool $appendNewline = true, bool $ignoreEmptyContextAndExtra = false, bool $includeStacktraces = false) { $this->batchMode = $batchMode; $this->appendNewline = $appendNewline; $this->ignoreEmptyContextAndExtra = $ignoreEmptyContextAndExtra; $this->includeStacktraces = $includeStacktraces; parent::__construct(); } /** * The batch mode option configures the formatting style for * multiple records. By default, multiple records will be * formatted as a JSON-encoded array. However, for * compatibility with some API endpoints, alternative styles * are available. */ public function getBatchMode(): int { return $this->batchMode; } /** * True if newlines are appended to every formatted record */ public function isAppendingNewlines(): bool { return $this->appendNewline; } /** * @inheritDoc */ public function format(LogRecord $record): string { $normalized = $this->normalizeRecord($record); return $this->toJson($normalized, true) . ($this->appendNewline ? "\n" : ''); } /** * @inheritDoc */ public function formatBatch(array $records): string { return match ($this->batchMode) { static::BATCH_MODE_NEWLINES => $this->formatBatchNewlines($records), default => $this->formatBatchJson($records), }; } /** * @return $this */ public function includeStacktraces(bool $include = true): self { $this->includeStacktraces = $include; return $this; } /** * @return array|bool|float|int|\stdClass|string|null> */ protected function normalizeRecord(LogRecord $record): array { $normalized = parent::normalizeRecord($record); if (isset($normalized['context']) && $normalized['context'] === []) { if ($this->ignoreEmptyContextAndExtra) { unset($normalized['context']); } else { $normalized['context'] = new \stdClass; } } if (isset($normalized['extra']) && $normalized['extra'] === []) { if ($this->ignoreEmptyContextAndExtra) { unset($normalized['extra']); } else { $normalized['extra'] = new \stdClass; } } return $normalized; } /** * Return a JSON-encoded array of records. * * @phpstan-param LogRecord[] $records */ protected function formatBatchJson(array $records): string { $formatted = array_map(fn (LogRecord $record) => $this->normalizeRecord($record), $records); return $this->toJson($formatted, true); } /** * Use new lines to separate records instead of a * JSON-encoded array. * * @phpstan-param LogRecord[] $records */ protected function formatBatchNewlines(array $records): string { $oldNewline = $this->appendNewline; $this->appendNewline = false; $formatted = array_map(fn (LogRecord $record) => $this->format($record), $records); $this->appendNewline = $oldNewline; return implode("\n", $formatted); } /** * Normalizes given $data. * * @return null|scalar|array|object */ protected function normalize(mixed $data, int $depth = 0): mixed { if ($depth > $this->maxNormalizeDepth) { return 'Over '.$this->maxNormalizeDepth.' levels deep, aborting normalization'; } if (\is_array($data)) { $normalized = []; $count = 1; foreach ($data as $key => $value) { if ($count++ > $this->maxNormalizeItemCount) { $normalized['...'] = 'Over '.$this->maxNormalizeItemCount.' items ('.\count($data).' total), aborting normalization'; break; } $normalized[$key] = $this->normalize($value, $depth + 1); } return $normalized; } if (\is_object($data)) { if ($data instanceof \DateTimeInterface) { return $this->formatDate($data); } if ($data instanceof Throwable) { return $this->normalizeException($data, $depth); } // if the object has specific json serializability we want to make sure we skip the __toString treatment below if ($data instanceof \JsonSerializable) { return $data; } if ($data instanceof Stringable) { try { return $data->__toString(); } catch (Throwable) { return $data::class; } } if (\get_class($data) === '__PHP_Incomplete_Class') { return new \ArrayObject($data); } return $data; } if (\is_resource($data)) { return parent::normalize($data); } return $data; } /** * Normalizes given exception with or without its own stack trace based on * `includeStacktraces` property. * * @return array>> */ protected function normalizeException(Throwable $e, int $depth = 0): array { $data = parent::normalizeException($e, $depth); if (!$this->includeStacktraces) { unset($data['trace']); } return $data; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Formatter/LineFormatter.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Formatter; use Closure; use Monolog\Utils; use Monolog\LogRecord; /** * Formats incoming records into a one-line string * * This is especially useful for logging to files * * @author Jordi Boggiano * @author Christophe Coevoet */ class LineFormatter extends NormalizerFormatter { public const SIMPLE_FORMAT = "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n"; protected string $format; protected bool $allowInlineLineBreaks; protected bool $ignoreEmptyContextAndExtra; protected bool $includeStacktraces; protected ?int $maxLevelNameLength = null; protected string $indentStacktraces = ''; protected Closure|null $stacktracesParser = null; protected string $basePath = ''; /** * @param string|null $format The format of the message * @param string|null $dateFormat The format of the timestamp: one supported by DateTime::format * @param bool $allowInlineLineBreaks Whether to allow inline line breaks in log entries */ public function __construct(?string $format = null, ?string $dateFormat = null, bool $allowInlineLineBreaks = false, bool $ignoreEmptyContextAndExtra = false, bool $includeStacktraces = false) { $this->format = $format === null ? static::SIMPLE_FORMAT : $format; $this->allowInlineLineBreaks = $allowInlineLineBreaks; $this->ignoreEmptyContextAndExtra = $ignoreEmptyContextAndExtra; $this->includeStacktraces($includeStacktraces); parent::__construct($dateFormat); } /** * Setting a base path will hide the base path from exception and stack trace file names to shorten them * @return $this */ public function setBasePath(string $path = ''): self { if ($path !== '') { $path = rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; } $this->basePath = $path; return $this; } /** * @return $this */ public function includeStacktraces(bool $include = true, ?Closure $parser = null): self { $this->includeStacktraces = $include; if ($this->includeStacktraces) { $this->allowInlineLineBreaks = true; $this->stacktracesParser = $parser; } return $this; } /** * Indent stack traces to separate them a bit from the main log record messages * * @param string $indent The string used to indent, for example " " * @return $this */ public function indentStacktraces(string $indent): self { $this->indentStacktraces = $indent; return $this; } /** * @return $this */ public function allowInlineLineBreaks(bool $allow = true): self { $this->allowInlineLineBreaks = $allow; return $this; } /** * @return $this */ public function ignoreEmptyContextAndExtra(bool $ignore = true): self { $this->ignoreEmptyContextAndExtra = $ignore; return $this; } /** * Allows cutting the level name to get fixed-length levels like INF for INFO, ERR for ERROR if you set this to 3 for example * * @param int|null $maxLevelNameLength Maximum characters for the level name. Set null for infinite length (default) * @return $this */ public function setMaxLevelNameLength(?int $maxLevelNameLength = null): self { $this->maxLevelNameLength = $maxLevelNameLength; return $this; } /** * @inheritDoc */ public function format(LogRecord $record): string { $vars = parent::format($record); if ($this->maxLevelNameLength !== null) { $vars['level_name'] = substr($vars['level_name'], 0, $this->maxLevelNameLength); } $output = $this->format; foreach ($vars['extra'] as $var => $val) { if (false !== strpos($output, '%extra.'.$var.'%')) { $output = str_replace('%extra.'.$var.'%', $this->stringify($val), $output); unset($vars['extra'][$var]); } } foreach ($vars['context'] as $var => $val) { if (false !== strpos($output, '%context.'.$var.'%')) { $output = str_replace('%context.'.$var.'%', $this->stringify($val), $output); unset($vars['context'][$var]); } } if ($this->ignoreEmptyContextAndExtra) { if (\count($vars['context']) === 0) { unset($vars['context']); $output = str_replace('%context%', '', $output); } if (\count($vars['extra']) === 0) { unset($vars['extra']); $output = str_replace('%extra%', '', $output); } } foreach ($vars as $var => $val) { if (false !== strpos($output, '%'.$var.'%')) { $output = str_replace('%'.$var.'%', $this->stringify($val), $output); } } // remove leftover %extra.xxx% and %context.xxx% if any if (false !== strpos($output, '%')) { $output = preg_replace('/%(?:extra|context)\..+?%/', '', $output); if (null === $output) { $pcreErrorCode = preg_last_error(); throw new \RuntimeException('Failed to run preg_replace: ' . $pcreErrorCode . ' / ' . preg_last_error_msg()); } } return $output; } public function formatBatch(array $records): string { $message = ''; foreach ($records as $record) { $message .= $this->format($record); } return $message; } /** * @param mixed $value */ public function stringify($value): string { return $this->replaceNewlines($this->convertToString($value)); } protected function normalizeException(\Throwable $e, int $depth = 0): string { $str = $this->formatException($e); $previous = $e->getPrevious(); while ($previous instanceof \Throwable) { $depth++; if ($depth > $this->maxNormalizeDepth) { $str .= "\n[previous exception] Over " . $this->maxNormalizeDepth . ' levels deep, aborting normalization'; break; } $str .= "\n[previous exception] " . $this->formatException($previous); $previous = $previous->getPrevious(); } return $str; } /** * @param mixed $data */ protected function convertToString($data): string { if (null === $data || \is_bool($data)) { return var_export($data, true); } if (\is_scalar($data)) { return (string) $data; } return $this->toJson($data, true); } protected function replaceNewlines(string $str): string { if ($this->allowInlineLineBreaks) { if (0 === strpos($str, '{') || 0 === strpos($str, '[')) { $str = preg_replace('/(?getCode(); if ($e instanceof \SoapFault) { if (isset($e->faultcode)) { $str .= ' faultcode: ' . $e->faultcode; } if (isset($e->faultactor)) { $str .= ' faultactor: ' . $e->faultactor; } if (isset($e->detail)) { if (\is_string($e->detail)) { $str .= ' detail: ' . $e->detail; } elseif (\is_object($e->detail) || \is_array($e->detail)) { $str .= ' detail: ' . $this->toJson($e->detail, true); } } } $file = $e->getFile(); if ($this->basePath !== '') { $file = preg_replace('{^'.preg_quote($this->basePath).'}', '', $file); } $str .= '): ' . $e->getMessage() . ' at ' . strtr((string) $file, DIRECTORY_SEPARATOR, '/') . ':' . $e->getLine() . ')'; if ($this->includeStacktraces) { $str .= $this->stacktracesParser($e); } return $str; } private function stacktracesParser(\Throwable $e): string { $trace = $e->getTraceAsString(); if ($this->basePath !== '') { $trace = preg_replace('{^(#\d+ )' . preg_quote($this->basePath) . '}m', '$1', $trace) ?? $trace; } if ($this->stacktracesParser !== null) { $trace = $this->stacktracesParserCustom($trace); } if ($this->indentStacktraces !== '') { $trace = str_replace("\n", "\n{$this->indentStacktraces}", $trace); } if (trim($trace) === '') { return ''; } return "\n{$this->indentStacktraces}[stacktrace]\n{$this->indentStacktraces}" . strtr($trace, DIRECTORY_SEPARATOR, '/') . "\n"; } private function stacktracesParserCustom(string $trace): string { return implode("\n", array_filter(array_map($this->stacktracesParser, explode("\n", $trace)), fn ($line) => is_string($line) && trim($line) !== '')); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Formatter/LogglyFormatter.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Formatter; use Monolog\LogRecord; /** * Encodes message information into JSON in a format compatible with Loggly. * * @author Adam Pancutt */ class LogglyFormatter extends JsonFormatter { /** * Overrides the default batch mode to new lines for compatibility with the * Loggly bulk API. */ public function __construct(int $batchMode = self::BATCH_MODE_NEWLINES, bool $appendNewline = false) { parent::__construct($batchMode, $appendNewline); } /** * Appends the 'timestamp' parameter for indexing by Loggly. * * @see https://www.loggly.com/docs/automated-parsing/#json * @see \Monolog\Formatter\JsonFormatter::format() */ protected function normalizeRecord(LogRecord $record): array { $recordData = parent::normalizeRecord($record); $recordData["timestamp"] = $record->datetime->format("Y-m-d\TH:i:s.uO"); unset($recordData["datetime"]); return $recordData; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Formatter/LogmaticFormatter.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Formatter; use Monolog\LogRecord; /** * Encodes message information into JSON in a format compatible with Logmatic. * * @author Julien Breux */ class LogmaticFormatter extends JsonFormatter { protected const MARKERS = ["sourcecode", "php"]; protected string $hostname = ''; protected string $appName = ''; /** * @return $this */ public function setHostname(string $hostname): self { $this->hostname = $hostname; return $this; } /** * @return $this */ public function setAppName(string $appName): self { $this->appName = $appName; return $this; } /** * Appends the 'hostname' and 'appname' parameter for indexing by Logmatic. * * @see http://doc.logmatic.io/docs/basics-to-send-data * @see \Monolog\Formatter\JsonFormatter::format() */ public function normalizeRecord(LogRecord $record): array { $record = parent::normalizeRecord($record); if ($this->hostname !== '') { $record["hostname"] = $this->hostname; } if ($this->appName !== '') { $record["appname"] = $this->appName; } $record["@marker"] = static::MARKERS; return $record; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Formatter/LogstashFormatter.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Formatter; use Monolog\LogRecord; /** * Serializes a log message to Logstash Event Format * * @see https://www.elastic.co/products/logstash * @see https://github.com/elastic/logstash/blob/master/logstash-core/src/main/java/org/logstash/Event.java * * @author Tim Mower */ class LogstashFormatter extends NormalizerFormatter { /** * @var string the name of the system for the Logstash log message, used to fill the @source field */ protected string $systemName; /** * @var string an application name for the Logstash log message, used to fill the @type field */ protected string $applicationName; /** * @var string the key for 'extra' fields from the Monolog record */ protected string $extraKey; /** * @var string the key for 'context' fields from the Monolog record */ protected string $contextKey; /** * @param string $applicationName The application that sends the data, used as the "type" field of logstash * @param string|null $systemName The system/machine name, used as the "source" field of logstash, defaults to the hostname of the machine * @param string $extraKey The key for extra keys inside logstash "fields", defaults to extra * @param string $contextKey The key for context keys inside logstash "fields", defaults to context */ public function __construct(string $applicationName, ?string $systemName = null, string $extraKey = 'extra', string $contextKey = 'context') { // logstash requires a ISO 8601 format date with optional millisecond precision. parent::__construct('Y-m-d\TH:i:s.uP'); $this->systemName = $systemName === null ? (string) gethostname() : $systemName; $this->applicationName = $applicationName; $this->extraKey = $extraKey; $this->contextKey = $contextKey; } /** * @inheritDoc */ public function format(LogRecord $record): string { $recordData = parent::format($record); $message = [ '@timestamp' => $recordData['datetime'], '@version' => 1, 'host' => $this->systemName, ]; if (isset($recordData['message'])) { $message['message'] = $recordData['message']; } if (isset($recordData['channel'])) { $message['type'] = $recordData['channel']; $message['channel'] = $recordData['channel']; } if (isset($recordData['level_name'])) { $message['level'] = $recordData['level_name']; } if (isset($recordData['level'])) { $message['monolog_level'] = $recordData['level']; } if ('' !== $this->applicationName) { $message['type'] = $this->applicationName; } if (\count($recordData['extra']) > 0) { $message[$this->extraKey] = $recordData['extra']; } if (\count($recordData['context']) > 0) { $message[$this->contextKey] = $recordData['context']; } return $this->toJson($message) . "\n"; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Formatter/MongoDBFormatter.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Formatter; use MongoDB\BSON\Type; use MongoDB\BSON\UTCDateTime; use Monolog\Utils; use Monolog\LogRecord; /** * Formats a record for use with the MongoDBHandler. * * @author Florian Plattner */ class MongoDBFormatter implements FormatterInterface { private bool $exceptionTraceAsString; private int $maxNestingLevel; /** * @param int $maxNestingLevel 0 means infinite nesting, the $record itself is level 1, $record->context is 2 * @param bool $exceptionTraceAsString set to false to log exception traces as a sub documents instead of strings */ public function __construct(int $maxNestingLevel = 3, bool $exceptionTraceAsString = true) { $this->maxNestingLevel = max($maxNestingLevel, 0); $this->exceptionTraceAsString = $exceptionTraceAsString; } /** * @inheritDoc * * @return mixed[] */ public function format(LogRecord $record): array { /** @var mixed[] $res */ $res = $this->formatArray($record->toArray()); return $res; } /** * @inheritDoc * * @return array */ public function formatBatch(array $records): array { $formatted = []; foreach ($records as $key => $record) { $formatted[$key] = $this->format($record); } return $formatted; } /** * @param mixed[] $array * @return mixed[]|string Array except when max nesting level is reached then a string "[...]" */ protected function formatArray(array $array, int $nestingLevel = 0) { if ($this->maxNestingLevel > 0 && $nestingLevel > $this->maxNestingLevel) { return '[...]'; } foreach ($array as $name => $value) { if ($value instanceof \DateTimeInterface) { $array[$name] = $this->formatDate($value, $nestingLevel + 1); } elseif ($value instanceof \Throwable) { $array[$name] = $this->formatException($value, $nestingLevel + 1); } elseif (\is_array($value)) { $array[$name] = $this->formatArray($value, $nestingLevel + 1); } elseif (\is_object($value) && !$value instanceof Type) { $array[$name] = $this->formatObject($value, $nestingLevel + 1); } } return $array; } /** * @param mixed $value * @return mixed[]|string */ protected function formatObject($value, int $nestingLevel) { $objectVars = get_object_vars($value); $objectVars['class'] = Utils::getClass($value); return $this->formatArray($objectVars, $nestingLevel); } /** * @return mixed[]|string */ protected function formatException(\Throwable $exception, int $nestingLevel) { $formattedException = [ 'class' => Utils::getClass($exception), 'message' => $exception->getMessage(), 'code' => (int) $exception->getCode(), 'file' => $exception->getFile() . ':' . $exception->getLine(), ]; if ($this->exceptionTraceAsString === true) { $formattedException['trace'] = $exception->getTraceAsString(); } else { $formattedException['trace'] = $exception->getTrace(); } return $this->formatArray($formattedException, $nestingLevel); } protected function formatDate(\DateTimeInterface $value, int $nestingLevel): UTCDateTime { return new UTCDateTime((int) floor(((float) $value->format('U.u')) * 1000)); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Formatter/NormalizerFormatter.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Formatter; use Monolog\JsonSerializableDateTimeImmutable; use Monolog\Utils; use Throwable; use Monolog\LogRecord; /** * Normalizes incoming records to remove objects/resources so it's easier to dump to various targets * * @author Jordi Boggiano */ class NormalizerFormatter implements FormatterInterface { public const SIMPLE_DATE = "Y-m-d\TH:i:sP"; protected string $dateFormat; protected int $maxNormalizeDepth = 9; protected int $maxNormalizeItemCount = 1000; private int $jsonEncodeOptions = Utils::DEFAULT_JSON_FLAGS; protected string $basePath = ''; /** * @param string|null $dateFormat The format of the timestamp: one supported by DateTime::format */ public function __construct(?string $dateFormat = null) { $this->dateFormat = null === $dateFormat ? static::SIMPLE_DATE : $dateFormat; } /** * @inheritDoc */ public function format(LogRecord $record) { return $this->normalizeRecord($record); } /** * Normalize an arbitrary value to a scalar|array|null * * @return null|scalar|array */ public function normalizeValue(mixed $data): mixed { return $this->normalize($data); } /** * @inheritDoc */ public function formatBatch(array $records) { foreach ($records as $key => $record) { $records[$key] = $this->format($record); } return $records; } public function getDateFormat(): string { return $this->dateFormat; } /** * @return $this */ public function setDateFormat(string $dateFormat): self { $this->dateFormat = $dateFormat; return $this; } /** * The maximum number of normalization levels to go through */ public function getMaxNormalizeDepth(): int { return $this->maxNormalizeDepth; } /** * @return $this */ public function setMaxNormalizeDepth(int $maxNormalizeDepth): self { $this->maxNormalizeDepth = $maxNormalizeDepth; return $this; } /** * The maximum number of items to normalize per level */ public function getMaxNormalizeItemCount(): int { return $this->maxNormalizeItemCount; } /** * @return $this */ public function setMaxNormalizeItemCount(int $maxNormalizeItemCount): self { $this->maxNormalizeItemCount = $maxNormalizeItemCount; return $this; } /** * Enables `json_encode` pretty print. * * @return $this */ public function setJsonPrettyPrint(bool $enable): self { if ($enable) { $this->jsonEncodeOptions |= JSON_PRETTY_PRINT; } else { $this->jsonEncodeOptions &= ~JSON_PRETTY_PRINT; } return $this; } /** * Setting a base path will hide the base path from exception and stack trace file names to shorten them * @return $this */ public function setBasePath(string $path = ''): self { if ($path !== '') { $path = rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; } $this->basePath = $path; return $this; } /** * Provided as extension point * * Because normalize is called with sub-values of context data etc, normalizeRecord can be * extended when data needs to be appended on the record array but not to other normalized data. * * @return array */ protected function normalizeRecord(LogRecord $record): array { /** @var array $normalized */ $normalized = $this->normalize($record->toArray()); return $normalized; } /** * @return null|scalar|array */ protected function normalize(mixed $data, int $depth = 0): mixed { if ($depth > $this->maxNormalizeDepth) { return 'Over ' . $this->maxNormalizeDepth . ' levels deep, aborting normalization'; } if (null === $data || \is_scalar($data)) { if (\is_float($data)) { if (is_infinite($data)) { return ($data > 0 ? '' : '-') . 'INF'; } if (is_nan($data)) { return 'NaN'; } } return $data; } if (\is_array($data)) { $normalized = []; $count = 1; foreach ($data as $key => $value) { if ($count++ > $this->maxNormalizeItemCount) { $normalized['...'] = 'Over ' . $this->maxNormalizeItemCount . ' items ('.\count($data).' total), aborting normalization'; break; } $normalized[$key] = $this->normalize($value, $depth + 1); } return $normalized; } if ($data instanceof \DateTimeInterface) { return $this->formatDate($data); } if (\is_object($data)) { if ($data instanceof Throwable) { return $this->normalizeException($data, $depth); } if ($data instanceof \JsonSerializable) { /** @var null|scalar|array $value */ $value = $data->jsonSerialize(); } elseif (\get_class($data) === '__PHP_Incomplete_Class') { $accessor = new \ArrayObject($data); $value = (string) $accessor['__PHP_Incomplete_Class_Name']; } elseif (method_exists($data, '__toString')) { try { /** @var string $value */ $value = $data->__toString(); } catch (\Throwable) { // if the toString method is failing, use the default behavior /** @var null|scalar|array $value */ $value = json_decode($this->toJson($data, true), true); } } else { // the rest is normalized by json encoding and decoding it /** @var null|scalar|array $value */ $value = json_decode($this->toJson($data, true), true); } return [Utils::getClass($data) => $value]; } if (\is_resource($data)) { return sprintf('[resource(%s)]', get_resource_type($data)); } return '[unknown('.\gettype($data).')]'; } /** * @return array>> */ protected function normalizeException(Throwable $e, int $depth = 0) { if ($depth > $this->maxNormalizeDepth) { return ['Over ' . $this->maxNormalizeDepth . ' levels deep, aborting normalization']; } if ($e instanceof \JsonSerializable) { return (array) $e->jsonSerialize(); } $file = $e->getFile(); if ($this->basePath !== '') { $file = preg_replace('{^'.preg_quote($this->basePath).'}', '', $file); } $data = [ 'class' => Utils::getClass($e), 'message' => $e->getMessage(), 'code' => (int) $e->getCode(), 'file' => $file.':'.$e->getLine(), ]; if ($e instanceof \SoapFault) { if (isset($e->faultcode)) { $data['faultcode'] = $e->faultcode; } if (isset($e->faultactor)) { $data['faultactor'] = $e->faultactor; } if (isset($e->detail)) { if (\is_string($e->detail)) { $data['detail'] = $e->detail; } elseif (\is_object($e->detail) || \is_array($e->detail)) { $data['detail'] = $this->toJson($e->detail, true); } } } $trace = $e->getTrace(); foreach ($trace as $frame) { if (isset($frame['file'], $frame['line'])) { $file = $frame['file']; if ($this->basePath !== '') { $file = preg_replace('{^'.preg_quote($this->basePath).'}', '', $file); } $data['trace'][] = $file.':'.$frame['line']; } } if (($previous = $e->getPrevious()) instanceof \Throwable) { $data['previous'] = $this->normalizeException($previous, $depth + 1); } return $data; } /** * Return the JSON representation of a value * * @param mixed $data * @throws \RuntimeException if encoding fails and errors are not ignored * @return string if encoding fails and ignoreErrors is true 'null' is returned */ protected function toJson($data, bool $ignoreErrors = false): string { return Utils::jsonEncode($data, $this->jsonEncodeOptions, $ignoreErrors); } protected function formatDate(\DateTimeInterface $date): string { // in case the date format isn't custom then we defer to the custom JsonSerializableDateTimeImmutable // formatting logic, which will pick the right format based on whether useMicroseconds is on if ($this->dateFormat === self::SIMPLE_DATE && $date instanceof JsonSerializableDateTimeImmutable) { return (string) $date; } return $date->format($this->dateFormat); } /** * @return $this */ public function addJsonEncodeOption(int $option): self { $this->jsonEncodeOptions |= $option; return $this; } /** * @return $this */ public function removeJsonEncodeOption(int $option): self { $this->jsonEncodeOptions &= ~$option; return $this; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Formatter/ScalarFormatter.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Formatter; use Monolog\LogRecord; /** * Formats data into an associative array of scalar (+ null) values. * Objects and arrays will be JSON encoded. * * @author Andrew Lawson */ class ScalarFormatter extends NormalizerFormatter { /** * @inheritDoc * * @phpstan-return array $record */ public function format(LogRecord $record): array { $result = []; foreach ($record->toArray() as $key => $value) { $result[$key] = $this->toScalar($value); } return $result; } protected function toScalar(mixed $value): string|int|float|bool|null { $normalized = $this->normalize($value); if (\is_array($normalized)) { return $this->toJson($normalized, true); } return $normalized; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Formatter/SyslogFormatter.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Formatter; use Monolog\Level; use Monolog\LogRecord; /** * Serializes a log message according to RFC 5424 * * @author Dalibor Karlović * @author Renat Gabdullin */ class SyslogFormatter extends LineFormatter { private const SYSLOG_FACILITY_USER = 1; private const FORMAT = "<%extra.priority%>1 %datetime% %extra.hostname% %extra.app-name% %extra.procid% %channel% %extra.structured-data% %level_name%: %message% %context% %extra%\n"; private const NILVALUE = '-'; private string $hostname; private int $procid; public function __construct(private string $applicationName = self::NILVALUE) { parent::__construct(self::FORMAT, 'Y-m-d\TH:i:s.uP', true, true); $this->hostname = (string) gethostname(); $this->procid = (int) getmypid(); } public function format(LogRecord $record): string { $record->extra = $this->formatExtra($record); return parent::format($record); } /** * @return array */ private function formatExtra(LogRecord $record): array { $extra = $record->extra; $extra['app-name'] = $this->applicationName; $extra['hostname'] = $this->hostname; $extra['procid'] = $this->procid; $extra['priority'] = self::calculatePriority($record->level); $extra['structured-data'] = self::NILVALUE; return $extra; } private static function calculatePriority(Level $level): int { return (self::SYSLOG_FACILITY_USER * 8) + $level->toRFC5424Level(); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Formatter/WildfireFormatter.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Formatter; use Monolog\Level; use Monolog\LogRecord; /** * Serializes a log message according to Wildfire's header requirements * * @author Eric Clemmons (@ericclemmons) * @author Christophe Coevoet * @author Kirill chEbba Chebunin */ class WildfireFormatter extends NormalizerFormatter { /** * @param string|null $dateFormat The format of the timestamp: one supported by DateTime::format */ public function __construct(?string $dateFormat = null) { parent::__construct($dateFormat); // http headers do not like non-ISO-8559-1 characters $this->removeJsonEncodeOption(JSON_UNESCAPED_UNICODE); } /** * Translates Monolog log levels to Wildfire levels. * * @return 'LOG'|'INFO'|'WARN'|'ERROR' */ private function toWildfireLevel(Level $level): string { return match ($level) { Level::Debug => 'LOG', Level::Info => 'INFO', Level::Notice => 'INFO', Level::Warning => 'WARN', Level::Error => 'ERROR', Level::Critical => 'ERROR', Level::Alert => 'ERROR', Level::Emergency => 'ERROR', }; } /** * @inheritDoc */ public function format(LogRecord $record): string { // Retrieve the line and file if set and remove them from the formatted extra $file = $line = ''; if (isset($record->extra['file'])) { $file = $record->extra['file']; unset($record->extra['file']); } if (isset($record->extra['line'])) { $line = $record->extra['line']; unset($record->extra['line']); } $message = ['message' => $record->message]; $handleError = false; if (\count($record->context) > 0) { $message['context'] = $this->normalize($record->context); $handleError = true; } if (\count($record->extra) > 0) { $message['extra'] = $this->normalize($record->extra); $handleError = true; } if (\count($message) === 1) { $message = reset($message); } if (is_array($message) && isset($message['context']) && \is_array($message['context']) && isset($message['context']['table'])) { $type = 'TABLE'; $label = $record->channel .': '. $record->message; $message = $message['context']['table']; } else { $type = $this->toWildfireLevel($record->level); $label = $record->channel; } // Create JSON object describing the appearance of the message in the console $json = $this->toJson([ [ 'Type' => $type, 'File' => $file, 'Line' => $line, 'Label' => $label, ], $message, ], $handleError); // The message itself is a serialization of the above JSON object + it's length return sprintf( '%d|%s|', \strlen($json), $json ); } /** * @inheritDoc * * @phpstan-return never */ public function formatBatch(array $records) { throw new \BadMethodCallException('Batch formatting does not make sense for the WildfireFormatter'); } /** * @inheritDoc * * @return null|scalar|array|object */ protected function normalize(mixed $data, int $depth = 0): mixed { if (\is_object($data) && !$data instanceof \DateTimeInterface) { return $data; } return parent::normalize($data, $depth); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/AbstractHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Level; use Monolog\Logger; use Monolog\ResettableInterface; use Psr\Log\LogLevel; use Monolog\LogRecord; /** * Base Handler class providing basic level/bubble support * * @author Jordi Boggiano */ abstract class AbstractHandler extends Handler implements ResettableInterface { protected Level $level = Level::Debug; protected bool $bubble = true; /** * @param int|string|Level|LogLevel::* $level The minimum logging level at which this handler will be triggered * @param bool $bubble Whether the messages that are handled can bubble up the stack or not * * @phpstan-param value-of|value-of|Level|LogLevel::* $level */ public function __construct(int|string|Level $level = Level::Debug, bool $bubble = true) { $this->setLevel($level); $this->bubble = $bubble; } /** * @inheritDoc */ public function isHandling(LogRecord $record): bool { return $record->level->value >= $this->level->value; } /** * Sets minimum logging level at which this handler will be triggered. * * @param Level|LogLevel::* $level Level or level name * @return $this * * @phpstan-param value-of|value-of|Level|LogLevel::* $level */ public function setLevel(int|string|Level $level): self { $this->level = Logger::toMonologLevel($level); return $this; } /** * Gets minimum logging level at which this handler will be triggered. */ public function getLevel(): Level { return $this->level; } /** * Sets the bubbling behavior. * * @param bool $bubble true means that this handler allows bubbling. * false means that bubbling is not permitted. * @return $this */ public function setBubble(bool $bubble): self { $this->bubble = $bubble; return $this; } /** * Gets the bubbling behavior. * * @return bool true means that this handler allows bubbling. * false means that bubbling is not permitted. */ public function getBubble(): bool { return $this->bubble; } /** * @inheritDoc */ public function reset(): void { } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\LogRecord; /** * Base Handler class providing the Handler structure, including processors and formatters * * Classes extending it should (in most cases) only implement write($record) * * @author Jordi Boggiano * @author Christophe Coevoet */ abstract class AbstractProcessingHandler extends AbstractHandler implements ProcessableHandlerInterface, FormattableHandlerInterface { use ProcessableHandlerTrait; use FormattableHandlerTrait; /** * @inheritDoc */ public function handle(LogRecord $record): bool { if (!$this->isHandling($record)) { return false; } if (\count($this->processors) > 0) { $record = $this->processRecord($record); } $record->formatted = $this->getFormatter()->format($record); $this->write($record); return false === $this->bubble; } /** * Writes the (already formatted) record down to the log of the implementing handler */ abstract protected function write(LogRecord $record): void; public function reset(): void { parent::reset(); $this->resetProcessors(); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/AbstractSyslogHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Level; use Monolog\Formatter\FormatterInterface; use Monolog\Formatter\LineFormatter; /** * Common syslog functionality */ abstract class AbstractSyslogHandler extends AbstractProcessingHandler { protected int $facility; /** * List of valid log facility names. * @var array */ protected array $facilities = [ 'auth' => \LOG_AUTH, 'authpriv' => \LOG_AUTHPRIV, 'cron' => \LOG_CRON, 'daemon' => \LOG_DAEMON, 'kern' => \LOG_KERN, 'lpr' => \LOG_LPR, 'mail' => \LOG_MAIL, 'news' => \LOG_NEWS, 'syslog' => \LOG_SYSLOG, 'user' => \LOG_USER, 'uucp' => \LOG_UUCP, ]; /** * Translates Monolog log levels to syslog log priorities. */ protected function toSyslogPriority(Level $level): int { return $level->toRFC5424Level(); } /** * @param string|int $facility Either one of the names of the keys in $this->facilities, or a LOG_* facility constant */ public function __construct(string|int $facility = \LOG_USER, int|string|Level $level = Level::Debug, bool $bubble = true) { parent::__construct($level, $bubble); if (!\defined('PHP_WINDOWS_VERSION_BUILD')) { $this->facilities['local0'] = \LOG_LOCAL0; $this->facilities['local1'] = \LOG_LOCAL1; $this->facilities['local2'] = \LOG_LOCAL2; $this->facilities['local3'] = \LOG_LOCAL3; $this->facilities['local4'] = \LOG_LOCAL4; $this->facilities['local5'] = \LOG_LOCAL5; $this->facilities['local6'] = \LOG_LOCAL6; $this->facilities['local7'] = \LOG_LOCAL7; } else { $this->facilities['local0'] = 128; // LOG_LOCAL0 $this->facilities['local1'] = 136; // LOG_LOCAL1 $this->facilities['local2'] = 144; // LOG_LOCAL2 $this->facilities['local3'] = 152; // LOG_LOCAL3 $this->facilities['local4'] = 160; // LOG_LOCAL4 $this->facilities['local5'] = 168; // LOG_LOCAL5 $this->facilities['local6'] = 176; // LOG_LOCAL6 $this->facilities['local7'] = 184; // LOG_LOCAL7 } // convert textual description of facility to syslog constant if (\is_string($facility) && \array_key_exists(strtolower($facility), $this->facilities)) { $facility = $this->facilities[strtolower($facility)]; } elseif (!\in_array($facility, array_values($this->facilities), true)) { throw new \UnexpectedValueException('Unknown facility value "'.$facility.'" given'); } $this->facility = $facility; } /** * @inheritDoc */ protected function getDefaultFormatter(): FormatterInterface { return new LineFormatter('%channel%.%level_name%: %message% %context% %extra%'); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/AmqpHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Gelf\Message as GelfMessage; use Monolog\Level; use Monolog\Formatter\FormatterInterface; use Monolog\Formatter\JsonFormatter; use PhpAmqpLib\Message\AMQPMessage; use PhpAmqpLib\Channel\AMQPChannel; use AMQPExchange; use Monolog\LogRecord; class AmqpHandler extends AbstractProcessingHandler { protected AMQPExchange|AMQPChannel $exchange; /** @var array */ private array $extraAttributes = []; protected string $exchangeName; /** * @param AMQPExchange|AMQPChannel $exchange AMQPExchange (php AMQP ext) or PHP AMQP lib channel, ready for use * @param string|null $exchangeName Optional exchange name, for AMQPChannel (PhpAmqpLib) only */ public function __construct(AMQPExchange|AMQPChannel $exchange, ?string $exchangeName = null, int|string|Level $level = Level::Debug, bool $bubble = true) { if ($exchange instanceof AMQPChannel) { $this->exchangeName = (string) $exchangeName; } elseif ($exchangeName !== null) { @trigger_error('The $exchangeName parameter can only be passed when using PhpAmqpLib, if using an AMQPExchange instance configure it beforehand', E_USER_DEPRECATED); } $this->exchange = $exchange; parent::__construct($level, $bubble); } /** * @return array */ public function getExtraAttributes(): array { return $this->extraAttributes; } /** * Configure extra attributes to pass to the AMQPExchange (if you are using the amqp extension) * * @param array $extraAttributes One of content_type, content_encoding, * message_id, user_id, app_id, delivery_mode, * priority, timestamp, expiration, type * or reply_to, headers. * @return $this */ public function setExtraAttributes(array $extraAttributes): self { $this->extraAttributes = $extraAttributes; return $this; } /** * @inheritDoc */ protected function write(LogRecord $record): void { $data = $record->formatted; $routingKey = $this->getRoutingKey($record); if($data instanceof GelfMessage) { $data = json_encode($data->toArray()); } if ($this->exchange instanceof AMQPExchange) { $attributes = [ 'delivery_mode' => 2, 'content_type' => 'application/json', ]; if (\count($this->extraAttributes) > 0) { $attributes = array_merge($attributes, $this->extraAttributes); } $this->exchange->publish( $data, $routingKey, 0, $attributes ); } else { $this->exchange->basic_publish( $this->createAmqpMessage($data), $this->exchangeName, $routingKey ); } } /** * @inheritDoc */ public function handleBatch(array $records): void { if ($this->exchange instanceof AMQPExchange) { parent::handleBatch($records); return; } foreach ($records as $record) { if (!$this->isHandling($record)) { continue; } $record = $this->processRecord($record); $data = $this->getFormatter()->format($record); if($data instanceof GelfMessage) { $data = json_encode($data->toArray()); } $this->exchange->batch_basic_publish( $this->createAmqpMessage($data), $this->exchangeName, $this->getRoutingKey($record) ); } $this->exchange->publish_batch(); } /** * Gets the routing key for the AMQP exchange */ protected function getRoutingKey(LogRecord $record): string { $routingKey = sprintf('%s.%s', $record->level->name, $record->channel); return strtolower($routingKey); } private function createAmqpMessage(string $data): AMQPMessage { $attributes = [ 'delivery_mode' => 2, 'content_type' => 'application/json', ]; if (\count($this->extraAttributes) > 0) { $attributes = array_merge($attributes, $this->extraAttributes); } return new AMQPMessage($data, $attributes); } /** * @inheritDoc */ protected function getDefaultFormatter(): FormatterInterface { return new JsonFormatter(JsonFormatter::BATCH_MODE_JSON, false); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/BrowserConsoleHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Formatter\FormatterInterface; use Monolog\Formatter\LineFormatter; use Monolog\Utils; use Monolog\LogRecord; use Monolog\Level; use function headers_list; use function stripos; /** * Handler sending logs to browser's javascript console with no browser extension required * * @author Olivier Poitrey */ class BrowserConsoleHandler extends AbstractProcessingHandler { protected static bool $initialized = false; /** @var LogRecord[] */ protected static array $records = []; protected const FORMAT_HTML = 'html'; protected const FORMAT_JS = 'js'; protected const FORMAT_UNKNOWN = 'unknown'; /** * @inheritDoc * * Formatted output may contain some formatting markers to be transferred to `console.log` using the %c format. * * Example of formatted string: * * You can do [[blue text]]{color: blue} or [[green background]]{background-color: green; color: white} */ protected function getDefaultFormatter(): FormatterInterface { return new LineFormatter('[[%channel%]]{macro: autolabel} [[%level_name%]]{font-weight: bold} %message%'); } /** * @inheritDoc */ protected function write(LogRecord $record): void { // Accumulate records static::$records[] = $record; // Register shutdown handler if not already done if (!static::$initialized) { static::$initialized = true; $this->registerShutdownFunction(); } } /** * Convert records to javascript console commands and send it to the browser. * This method is automatically called on PHP shutdown if output is HTML or Javascript. */ public static function send(): void { $format = static::getResponseFormat(); if ($format === self::FORMAT_UNKNOWN) { return; } if (\count(static::$records) > 0) { if ($format === self::FORMAT_HTML) { static::writeOutput(''); } else { // js format static::writeOutput(self::generateScript()); } static::resetStatic(); } } public function close(): void { self::resetStatic(); } public function reset(): void { parent::reset(); self::resetStatic(); } /** * Forget all logged records */ public static function resetStatic(): void { static::$records = []; } /** * Wrapper for register_shutdown_function to allow overriding */ protected function registerShutdownFunction(): void { if (PHP_SAPI !== 'cli') { register_shutdown_function(['Monolog\Handler\BrowserConsoleHandler', 'send']); } } /** * Wrapper for echo to allow overriding */ protected static function writeOutput(string $str): void { echo $str; } /** * Checks the format of the response * * If Content-Type is set to application/javascript or text/javascript -> js * If Content-Type is set to text/html, or is unset -> html * If Content-Type is anything else -> unknown * * @return string One of 'js', 'html' or 'unknown' * @phpstan-return self::FORMAT_* */ protected static function getResponseFormat(): string { // Check content type foreach (headers_list() as $header) { if (stripos($header, 'content-type:') === 0) { return static::getResponseFormatFromContentType($header); } } return self::FORMAT_HTML; } /** * @return string One of 'js', 'html' or 'unknown' * @phpstan-return self::FORMAT_* */ protected static function getResponseFormatFromContentType(string $contentType): string { // This handler only works with HTML and javascript outputs // text/javascript is obsolete in favour of application/javascript, but still used if (stripos($contentType, 'application/javascript') !== false || stripos($contentType, 'text/javascript') !== false) { return self::FORMAT_JS; } if (stripos($contentType, 'text/html') !== false) { return self::FORMAT_HTML; } return self::FORMAT_UNKNOWN; } private static function generateScript(): string { $script = []; foreach (static::$records as $record) { $context = self::dump('Context', $record->context); $extra = self::dump('Extra', $record->extra); if (\count($context) === 0 && \count($extra) === 0) { $script[] = self::call_array(self::getConsoleMethodForLevel($record->level), self::handleStyles($record->formatted)); } else { $script = array_merge( $script, [self::call_array('groupCollapsed', self::handleStyles($record->formatted))], $context, $extra, [self::call('groupEnd')] ); } } return "(function (c) {if (c && c.groupCollapsed) {\n" . implode("\n", $script) . "\n}})(console);"; } private static function getConsoleMethodForLevel(Level $level): string { return match ($level) { Level::Debug => 'debug', Level::Info, Level::Notice => 'info', Level::Warning => 'warn', Level::Error, Level::Critical, Level::Alert, Level::Emergency => 'error', }; } /** * @return string[] */ private static function handleStyles(string $formatted): array { $args = []; $format = '%c' . $formatted; preg_match_all('/\[\[(.*?)\]\]\{([^}]*)\}/s', $format, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER); foreach (array_reverse($matches) as $match) { $args[] = '"font-weight: normal"'; $args[] = self::quote(self::handleCustomStyles($match[2][0], $match[1][0])); $pos = $match[0][1]; $format = Utils::substr($format, 0, $pos) . '%c' . $match[1][0] . '%c' . Utils::substr($format, $pos + \strlen($match[0][0])); } $args[] = self::quote('font-weight: normal'); $args[] = self::quote($format); return array_reverse($args); } private static function handleCustomStyles(string $style, string $string): string { static $colors = ['blue', 'green', 'red', 'magenta', 'orange', 'black', 'grey']; static $labels = []; $style = preg_replace_callback('/macro\s*:(.*?)(?:;|$)/', function (array $m) use ($string, &$colors, &$labels) { if (trim($m[1]) === 'autolabel') { // Format the string as a label with consistent auto assigned background color if (!isset($labels[$string])) { $labels[$string] = $colors[\count($labels) % \count($colors)]; } $color = $labels[$string]; return "background-color: $color; color: white; border-radius: 3px; padding: 0 2px 0 2px"; } return $m[1]; }, $style); if (null === $style) { $pcreErrorCode = preg_last_error(); throw new \RuntimeException('Failed to run preg_replace_callback: ' . $pcreErrorCode . ' / ' . preg_last_error_msg()); } return $style; } /** * @param mixed[] $dict * @return mixed[] */ private static function dump(string $title, array $dict): array { $script = []; $dict = array_filter($dict, fn ($value) => $value !== null); if (\count($dict) === 0) { return $script; } $script[] = self::call('log', self::quote('%c%s'), self::quote('font-weight: bold'), self::quote($title)); foreach ($dict as $key => $value) { $value = json_encode($value); if (false === $value) { $value = self::quote(''); } $script[] = self::call('log', self::quote('%s: %o'), self::quote((string) $key), $value); } return $script; } private static function quote(string $arg): string { return '"' . addcslashes($arg, "\"\n\\") . '"'; } /** * @param mixed $args */ private static function call(...$args): string { $method = array_shift($args); if (!\is_string($method)) { throw new \UnexpectedValueException('Expected the first arg to be a string, got: '.var_export($method, true)); } return self::call_array($method, $args); } /** * @param mixed[] $args */ private static function call_array(string $method, array $args): string { return 'c.' . $method . '(' . implode(', ', $args) . ');'; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/BufferHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Level; use Monolog\ResettableInterface; use Monolog\Formatter\FormatterInterface; use Monolog\LogRecord; /** * Buffers all records until closing the handler and then pass them as batch. * * This is useful for a MailHandler to send only one mail per request instead of * sending one per log message. * * @author Christophe Coevoet */ class BufferHandler extends AbstractHandler implements ProcessableHandlerInterface, FormattableHandlerInterface { use ProcessableHandlerTrait; protected HandlerInterface $handler; protected int $bufferSize = 0; protected int $bufferLimit; protected bool $flushOnOverflow; /** @var LogRecord[] */ protected array $buffer = []; protected bool $initialized = false; /** * @param HandlerInterface $handler Handler. * @param int $bufferLimit How many entries should be buffered at most, beyond that the oldest items are removed from the buffer. * @param bool $flushOnOverflow If true, the buffer is flushed when the max size has been reached, by default oldest entries are discarded */ public function __construct(HandlerInterface $handler, int $bufferLimit = 0, int|string|Level $level = Level::Debug, bool $bubble = true, bool $flushOnOverflow = false) { parent::__construct($level, $bubble); $this->handler = $handler; $this->bufferLimit = $bufferLimit; $this->flushOnOverflow = $flushOnOverflow; } /** * @inheritDoc */ public function handle(LogRecord $record): bool { if ($record->level->isLowerThan($this->level)) { return false; } if (!$this->initialized) { // __destructor() doesn't get called on Fatal errors register_shutdown_function([$this, 'close']); $this->initialized = true; } if ($this->bufferLimit > 0 && $this->bufferSize === $this->bufferLimit) { if ($this->flushOnOverflow) { $this->flush(); } else { array_shift($this->buffer); $this->bufferSize--; } } if (\count($this->processors) > 0) { $record = $this->processRecord($record); } $this->buffer[] = $record; $this->bufferSize++; return false === $this->bubble; } public function flush(): void { if ($this->bufferSize === 0) { return; } $this->handler->handleBatch($this->buffer); $this->clear(); } public function __destruct() { // suppress the parent behavior since we already have register_shutdown_function() // to call close(), and the reference contained there will prevent this from being // GC'd until the end of the request } /** * @inheritDoc */ public function close(): void { $this->flush(); $this->handler->close(); } /** * Clears the buffer without flushing any messages down to the wrapped handler. */ public function clear(): void { $this->bufferSize = 0; $this->buffer = []; } public function reset(): void { $this->flush(); parent::reset(); $this->resetProcessors(); if ($this->handler instanceof ResettableInterface) { $this->handler->reset(); } } /** * @inheritDoc */ public function setFormatter(FormatterInterface $formatter): HandlerInterface { if ($this->handler instanceof FormattableHandlerInterface) { $this->handler->setFormatter($formatter); return $this; } throw new \UnexpectedValueException('The nested handler of type '.\get_class($this->handler).' does not support formatters.'); } /** * @inheritDoc */ public function getFormatter(): FormatterInterface { if ($this->handler instanceof FormattableHandlerInterface) { return $this->handler->getFormatter(); } throw new \UnexpectedValueException('The nested handler of type '.\get_class($this->handler).' does not support formatters.'); } public function setHandler(HandlerInterface $handler): void { $this->handler = $handler; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/ChromePHPHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Formatter\ChromePHPFormatter; use Monolog\Formatter\FormatterInterface; use Monolog\Level; use Monolog\Utils; use Monolog\LogRecord; use Monolog\JsonSerializableDateTimeImmutable; /** * Handler sending logs to the ChromePHP extension (http://www.chromephp.com/) * * This also works out of the box with Firefox 43+ * * @author Christophe Coevoet */ class ChromePHPHandler extends AbstractProcessingHandler { use WebRequestRecognizerTrait; /** * Version of the extension */ protected const VERSION = '4.0'; /** * Header name */ protected const HEADER_NAME = 'X-ChromeLogger-Data'; /** * Regular expression to detect supported browsers (matches any Chrome, or Firefox 43+) */ protected const USER_AGENT_REGEX = '{\b(?:Chrome/\d+(?:\.\d+)*|HeadlessChrome|Firefox/(?:4[3-9]|[5-9]\d|\d{3,})(?:\.\d)*)\b}'; protected static bool $initialized = false; /** * Tracks whether we sent too much data * * Chrome limits the headers to 4KB, so when we sent 3KB we stop sending */ protected static bool $overflowed = false; /** @var mixed[] */ protected static array $json = [ 'version' => self::VERSION, 'columns' => ['label', 'log', 'backtrace', 'type'], 'rows' => [], ]; protected static bool $sendHeaders = true; public function __construct(int|string|Level $level = Level::Debug, bool $bubble = true) { parent::__construct($level, $bubble); } /** * @inheritDoc */ public function handleBatch(array $records): void { if (!$this->isWebRequest()) { return; } $messages = []; foreach ($records as $record) { if ($record->level < $this->level) { continue; } $message = $this->processRecord($record); $messages[] = $message; } if (\count($messages) > 0) { $messages = $this->getFormatter()->formatBatch($messages); self::$json['rows'] = array_merge(self::$json['rows'], $messages); $this->send(); } } /** * @inheritDoc */ protected function getDefaultFormatter(): FormatterInterface { return new ChromePHPFormatter(); } /** * Creates & sends header for a record * * @see sendHeader() * @see send() */ protected function write(LogRecord $record): void { if (!$this->isWebRequest()) { return; } self::$json['rows'][] = $record->formatted; $this->send(); } /** * Sends the log header * * @see sendHeader() */ protected function send(): void { if (self::$overflowed || !self::$sendHeaders) { return; } if (!self::$initialized) { self::$initialized = true; self::$sendHeaders = $this->headersAccepted(); if (!self::$sendHeaders) { return; } self::$json['request_uri'] = $_SERVER['REQUEST_URI'] ?? ''; } $json = Utils::jsonEncode(self::$json, Utils::DEFAULT_JSON_FLAGS & ~JSON_UNESCAPED_UNICODE, true); $data = base64_encode($json); if (\strlen($data) > 3 * 1024) { self::$overflowed = true; $record = new LogRecord( message: 'Incomplete logs, chrome header size limit reached', level: Level::Warning, channel: 'monolog', datetime: new JsonSerializableDateTimeImmutable(true), ); self::$json['rows'][\count(self::$json['rows']) - 1] = $this->getFormatter()->format($record); $json = Utils::jsonEncode(self::$json, Utils::DEFAULT_JSON_FLAGS & ~JSON_UNESCAPED_UNICODE, true); $data = base64_encode($json); } if (trim($data) !== '') { $this->sendHeader(static::HEADER_NAME, $data); } } /** * Send header string to the client */ protected function sendHeader(string $header, string $content): void { if (!headers_sent() && self::$sendHeaders) { header(sprintf('%s: %s', $header, $content)); } } /** * Verifies if the headers are accepted by the current user agent */ protected function headersAccepted(): bool { if (!isset($_SERVER['HTTP_USER_AGENT'])) { return false; } return preg_match(static::USER_AGENT_REGEX, $_SERVER['HTTP_USER_AGENT']) === 1; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/CouchDBHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Formatter\FormatterInterface; use Monolog\Formatter\JsonFormatter; use Monolog\Level; use Monolog\LogRecord; /** * CouchDB handler * * @author Markus Bachmann * @phpstan-type Options array{ * host: string, * port: int, * dbname: string, * username: string|null, * password: string|null * } * @phpstan-type InputOptions array{ * host?: string, * port?: int, * dbname?: string, * username?: string|null, * password?: string|null * } */ class CouchDBHandler extends AbstractProcessingHandler { /** * @var mixed[] * @phpstan-var Options */ private array $options; /** * @param mixed[] $options * * @phpstan-param InputOptions $options */ public function __construct(array $options = [], int|string|Level $level = Level::Debug, bool $bubble = true) { $this->options = array_merge([ 'host' => 'localhost', 'port' => 5984, 'dbname' => 'logger', 'username' => null, 'password' => null, ], $options); parent::__construct($level, $bubble); } /** * @inheritDoc */ protected function write(LogRecord $record): void { $basicAuth = null; if (null !== $this->options['username'] && null !== $this->options['password']) { $basicAuth = sprintf('%s:%s@', $this->options['username'], $this->options['password']); } $url = 'http://'.$basicAuth.$this->options['host'].':'.$this->options['port'].'/'.$this->options['dbname']; $context = stream_context_create([ 'http' => [ 'method' => 'POST', 'content' => $record->formatted, 'ignore_errors' => true, 'max_redirects' => 0, 'header' => 'Content-type: application/json', ], ]); if (false === @file_get_contents($url, false, $context)) { throw new \RuntimeException(sprintf('Could not connect to %s', $url)); } } /** * @inheritDoc */ protected function getDefaultFormatter(): FormatterInterface { return new JsonFormatter(JsonFormatter::BATCH_MODE_JSON, false); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/CubeHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Level; use Monolog\Utils; use Monolog\LogRecord; /** * Logs to Cube. * * @link https://github.com/square/cube/wiki * @author Wan Chen * @deprecated Since 2.8.0 and 3.2.0, Cube appears abandoned and thus we will drop this handler in Monolog 4 */ class CubeHandler extends AbstractProcessingHandler { private ?\Socket $udpConnection = null; private ?\CurlHandle $httpConnection = null; private string $scheme; private string $host; private int $port; /** @var string[] */ private array $acceptedSchemes = ['http', 'udp']; /** * Create a Cube handler * * @throws \UnexpectedValueException when given url is not a valid url. * A valid url must consist of three parts : protocol://host:port * Only valid protocols used by Cube are http and udp */ public function __construct(string $url, int|string|Level $level = Level::Debug, bool $bubble = true) { $urlInfo = parse_url($url); if ($urlInfo === false || !isset($urlInfo['scheme'], $urlInfo['host'], $urlInfo['port'])) { throw new \UnexpectedValueException('URL "'.$url.'" is not valid'); } if (!\in_array($urlInfo['scheme'], $this->acceptedSchemes, true)) { throw new \UnexpectedValueException( 'Invalid protocol (' . $urlInfo['scheme'] . ').' . ' Valid options are ' . implode(', ', $this->acceptedSchemes) ); } $this->scheme = $urlInfo['scheme']; $this->host = $urlInfo['host']; $this->port = $urlInfo['port']; parent::__construct($level, $bubble); } /** * Establish a connection to an UDP socket * * @throws \LogicException when unable to connect to the socket * @throws MissingExtensionException when there is no socket extension */ protected function connectUdp(): void { if (!\extension_loaded('sockets')) { throw new MissingExtensionException('The sockets extension is required to use udp URLs with the CubeHandler'); } $udpConnection = socket_create(AF_INET, SOCK_DGRAM, 0); if (false === $udpConnection) { throw new \LogicException('Unable to create a socket'); } $this->udpConnection = $udpConnection; if (!socket_connect($this->udpConnection, $this->host, $this->port)) { throw new \LogicException('Unable to connect to the socket at ' . $this->host . ':' . $this->port); } } /** * Establish a connection to an http server * * @throws \LogicException when unable to connect to the socket * @throws MissingExtensionException when no curl extension */ protected function connectHttp(): void { if (!\extension_loaded('curl')) { throw new MissingExtensionException('The curl extension is required to use http URLs with the CubeHandler'); } $httpConnection = curl_init('http://'.$this->host.':'.$this->port.'/1.0/event/put'); if (false === $httpConnection) { throw new \LogicException('Unable to connect to ' . $this->host . ':' . $this->port); } $this->httpConnection = $httpConnection; curl_setopt($this->httpConnection, CURLOPT_CUSTOMREQUEST, "POST"); curl_setopt($this->httpConnection, CURLOPT_RETURNTRANSFER, true); } /** * @inheritDoc */ protected function write(LogRecord $record): void { $date = $record->datetime; $data = ['time' => $date->format('Y-m-d\TH:i:s.uO')]; $context = $record->context; if (isset($context['type'])) { $data['type'] = $context['type']; unset($context['type']); } else { $data['type'] = $record->channel; } $data['data'] = $context; $data['data']['level'] = $record->level; if ($this->scheme === 'http') { $this->writeHttp(Utils::jsonEncode($data)); } else { $this->writeUdp(Utils::jsonEncode($data)); } } private function writeUdp(string $data): void { if (null === $this->udpConnection) { $this->connectUdp(); } if (null === $this->udpConnection) { throw new \LogicException('No UDP socket could be opened'); } socket_send($this->udpConnection, $data, \strlen($data), 0); } private function writeHttp(string $data): void { if (null === $this->httpConnection) { $this->connectHttp(); } if (null === $this->httpConnection) { throw new \LogicException('No connection could be established'); } curl_setopt($this->httpConnection, CURLOPT_POSTFIELDS, '['.$data.']'); curl_setopt($this->httpConnection, CURLOPT_HTTPHEADER, [ 'Content-Type: application/json', 'Content-Length: ' . \strlen('['.$data.']'), ]); Curl\Util::execute($this->httpConnection, 5); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/Curl/Util.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler\Curl; use CurlHandle; /** * This class is marked as internal and it is not under the BC promise of the package. * * @internal */ final class Util { /** @var array */ private static array $retriableErrorCodes = [ CURLE_COULDNT_RESOLVE_HOST, CURLE_COULDNT_CONNECT, CURLE_HTTP_NOT_FOUND, CURLE_READ_ERROR, CURLE_OPERATION_TIMEOUTED, CURLE_HTTP_POST_ERROR, CURLE_SSL_CONNECT_ERROR, ]; /** * Executes a CURL request with optional retries and exception on failure * * @param CurlHandle $ch curl handler * @return bool|string @see curl_exec */ public static function execute(CurlHandle $ch, int $retries = 5): bool|string { while ($retries > 0) { $retries--; $curlResponse = curl_exec($ch); if ($curlResponse === false) { $curlErrno = curl_errno($ch); if (false === \in_array($curlErrno, self::$retriableErrorCodes, true) || $retries === 0) { $curlError = curl_error($ch); throw new \RuntimeException(sprintf('Curl error (code %d): %s', $curlErrno, $curlError)); } continue; } return $curlResponse; } return false; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/DeduplicationHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Level; use Monolog\Logger; use Psr\Log\LogLevel; use Monolog\LogRecord; /** * Simple handler wrapper that deduplicates log records across multiple requests * * It also includes the BufferHandler functionality and will buffer * all messages until the end of the request or flush() is called. * * This works by storing all log records' messages above $deduplicationLevel * to the file specified by $deduplicationStore. When further logs come in at the end of the * request (or when flush() is called), all those above $deduplicationLevel are checked * against the existing stored logs. If they match and the timestamps in the stored log is * not older than $time seconds, the new log record is discarded. If no log record is new, the * whole data set is discarded. * * This is mainly useful in combination with Mail handlers or things like Slack or HipChat handlers * that send messages to people, to avoid spamming with the same message over and over in case of * a major component failure like a database server being down which makes all requests fail in the * same way. * * @author Jordi Boggiano */ class DeduplicationHandler extends BufferHandler { protected string $deduplicationStore; protected Level $deduplicationLevel; protected int $time; protected bool $gc = false; /** * @param HandlerInterface $handler Handler. * @param string|null $deduplicationStore The file/path where the deduplication log should be kept * @param int|string|Level|LogLevel::* $deduplicationLevel The minimum logging level for log records to be looked at for deduplication purposes * @param int $time The period (in seconds) during which duplicate entries should be suppressed after a given log is sent through * @param bool $bubble Whether the messages that are handled can bubble up the stack or not * * @phpstan-param value-of|value-of|Level|LogLevel::* $deduplicationLevel */ public function __construct(HandlerInterface $handler, ?string $deduplicationStore = null, int|string|Level $deduplicationLevel = Level::Error, int $time = 60, bool $bubble = true) { parent::__construct($handler, 0, Level::Debug, $bubble, false); $this->deduplicationStore = $deduplicationStore === null ? sys_get_temp_dir() . '/monolog-dedup-' . substr(md5(__FILE__), 0, 20) .'.log' : $deduplicationStore; $this->deduplicationLevel = Logger::toMonologLevel($deduplicationLevel); $this->time = $time; } public function flush(): void { if ($this->bufferSize === 0) { return; } $store = null; if (file_exists($this->deduplicationStore)) { $store = file($this->deduplicationStore, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); } $passthru = null; foreach ($this->buffer as $record) { if ($record->level->value >= $this->deduplicationLevel->value) { $passthru = $passthru === true || !\is_array($store) || !$this->isDuplicate($store, $record); if ($passthru) { $line = $this->buildDeduplicationStoreEntry($record); file_put_contents($this->deduplicationStore, $line . "\n", FILE_APPEND); if (!\is_array($store)) { $store = []; } $store[] = $line; } } } // default of null is valid as well as if no record matches duplicationLevel we just pass through if ($passthru === true || $passthru === null) { $this->handler->handleBatch($this->buffer); } $this->clear(); if ($this->gc) { $this->collectLogs(); } } /** * If there is a store entry older than e.g. a day, this method should set `$this->gc` to `true` to trigger garbage collection. * @param string[] $store The deduplication store */ protected function isDuplicate(array $store, LogRecord $record): bool { $timestampValidity = $record->datetime->getTimestamp() - $this->time; $expectedMessage = preg_replace('{[\r\n].*}', '', $record->message); $yesterday = time() - 86400; for ($i = \count($store) - 1; $i >= 0; $i--) { list($timestamp, $level, $message) = explode(':', $store[$i], 3); if ($level === $record->level->getName() && $message === $expectedMessage && $timestamp > $timestampValidity) { return true; } if ($timestamp < $yesterday) { $this->gc = true; } } return false; } /** * @return string The given record serialized as a single line of text */ protected function buildDeduplicationStoreEntry(LogRecord $record): string { return $record->datetime->getTimestamp() . ':' . $record->level->getName() . ':' . preg_replace('{[\r\n].*}', '', $record->message); } private function collectLogs(): void { if (!file_exists($this->deduplicationStore)) { return; } $handle = fopen($this->deduplicationStore, 'rw+'); if (false === $handle) { throw new \RuntimeException('Failed to open file for reading and writing: ' . $this->deduplicationStore); } if (false === flock($handle, LOCK_EX)) { return; } $validLogs = []; $timestampValidity = time() - $this->time; while (!feof($handle)) { $log = fgets($handle); if (\is_string($log) && '' !== $log && substr($log, 0, 10) >= $timestampValidity) { $validLogs[] = $log; } } ftruncate($handle, 0); rewind($handle); foreach ($validLogs as $log) { fwrite($handle, $log); } flock($handle, LOCK_UN); fclose($handle); $this->gc = false; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/DoctrineCouchDBHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Level; use Monolog\Formatter\NormalizerFormatter; use Monolog\Formatter\FormatterInterface; use Doctrine\CouchDB\CouchDBClient; use Monolog\LogRecord; /** * CouchDB handler for Doctrine CouchDB ODM * * @author Markus Bachmann */ class DoctrineCouchDBHandler extends AbstractProcessingHandler { private CouchDBClient $client; public function __construct(CouchDBClient $client, int|string|Level $level = Level::Debug, bool $bubble = true) { $this->client = $client; parent::__construct($level, $bubble); } /** * @inheritDoc */ protected function write(LogRecord $record): void { $this->client->postDocument($record->formatted); } protected function getDefaultFormatter(): FormatterInterface { return new NormalizerFormatter; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/DynamoDbHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Aws\Sdk; use Aws\DynamoDb\DynamoDbClient; use Monolog\Formatter\FormatterInterface; use Aws\DynamoDb\Marshaler; use Monolog\Formatter\ScalarFormatter; use Monolog\Level; use Monolog\LogRecord; /** * Amazon DynamoDB handler (http://aws.amazon.com/dynamodb/) * * @link https://github.com/aws/aws-sdk-php/ * @author Andrew Lawson */ class DynamoDbHandler extends AbstractProcessingHandler { public const DATE_FORMAT = 'Y-m-d\TH:i:s.uO'; protected DynamoDbClient $client; protected string $table; protected Marshaler $marshaler; public function __construct(DynamoDbClient $client, string $table, int|string|Level $level = Level::Debug, bool $bubble = true) { $this->marshaler = new Marshaler; $this->client = $client; $this->table = $table; parent::__construct($level, $bubble); } /** * @inheritDoc */ protected function write(LogRecord $record): void { $filtered = $this->filterEmptyFields($record->formatted); $formatted = $this->marshaler->marshalItem($filtered); $this->client->putItem([ 'TableName' => $this->table, 'Item' => $formatted, ]); } /** * @param mixed[] $record * @return mixed[] */ protected function filterEmptyFields(array $record): array { return array_filter($record, function ($value) { return [] !== $value; }); } /** * @inheritDoc */ protected function getDefaultFormatter(): FormatterInterface { return new ScalarFormatter(self::DATE_FORMAT); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/ElasticaHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Elastic\Transport\Exception\TransportException; use Elastica\Document; use Monolog\Formatter\FormatterInterface; use Monolog\Formatter\ElasticaFormatter; use Monolog\Level; use Elastica\Client; use Elastica\Exception\ExceptionInterface; use Monolog\LogRecord; /** * Elastic Search handler * * Usage example: * * $client = new \Elastica\Client(); * $options = array( * 'index' => 'elastic_index_name', * 'type' => 'elastic_doc_type', Types have been removed in Elastica 7 * ); * $handler = new ElasticaHandler($client, $options); * $log = new Logger('application'); * $log->pushHandler($handler); * * @author Jelle Vink * @phpstan-type Options array{ * index: string, * type: string, * ignore_error: bool * } * @phpstan-type InputOptions array{ * index?: string, * type?: string, * ignore_error?: bool * } */ class ElasticaHandler extends AbstractProcessingHandler { protected Client $client; /** * @var mixed[] Handler config options * @phpstan-var Options */ protected array $options; /** * @param Client $client Elastica Client object * @param mixed[] $options Handler configuration * * @phpstan-param InputOptions $options */ public function __construct(Client $client, array $options = [], int|string|Level $level = Level::Debug, bool $bubble = true) { parent::__construct($level, $bubble); $this->client = $client; $this->options = array_merge( [ 'index' => 'monolog', // Elastic index name 'type' => 'record', // Elastic document type 'ignore_error' => false, // Suppress Elastica exceptions ], $options ); } /** * @inheritDoc */ protected function write(LogRecord $record): void { $this->bulkSend([$record->formatted]); } /** * @inheritDoc */ public function setFormatter(FormatterInterface $formatter): HandlerInterface { if ($formatter instanceof ElasticaFormatter) { return parent::setFormatter($formatter); } throw new \InvalidArgumentException('ElasticaHandler is only compatible with ElasticaFormatter'); } /** * @return mixed[] * * @phpstan-return Options */ public function getOptions(): array { return $this->options; } /** * @inheritDoc */ protected function getDefaultFormatter(): FormatterInterface { return new ElasticaFormatter($this->options['index'], $this->options['type']); } /** * @inheritDoc */ public function handleBatch(array $records): void { $documents = $this->getFormatter()->formatBatch($records); $this->bulkSend($documents); } /** * Use Elasticsearch bulk API to send list of documents * * @param Document[] $documents * * @throws \RuntimeException */ protected function bulkSend(array $documents): void { try { $this->client->addDocuments($documents); } catch (ExceptionInterface | TransportException $e) { if (!$this->options['ignore_error']) { throw new \RuntimeException("Error sending messages to Elasticsearch", 0, $e); } } } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/ElasticsearchHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Elastic\Elasticsearch\Response\Elasticsearch; use Throwable; use RuntimeException; use Monolog\Level; use Monolog\Formatter\FormatterInterface; use Monolog\Formatter\ElasticsearchFormatter; use InvalidArgumentException; use Elasticsearch\Common\Exceptions\RuntimeException as ElasticsearchRuntimeException; use Elasticsearch\Client; use Monolog\LogRecord; use Elastic\Elasticsearch\Exception\InvalidArgumentException as ElasticInvalidArgumentException; use Elastic\Elasticsearch\Client as Client8; /** * Elasticsearch handler * * @link https://www.elastic.co/guide/en/elasticsearch/client/php-api/current/index.html * * Simple usage example: * * $client = \Elasticsearch\ClientBuilder::create() * ->setHosts($hosts) * ->build(); * * $options = array( * 'index' => 'elastic_index_name', * 'type' => 'elastic_doc_type', * ); * $handler = new ElasticsearchHandler($client, $options); * $log = new Logger('application'); * $log->pushHandler($handler); * * @author Avtandil Kikabidze * @phpstan-type Options array{ * index: string, * type: string, * ignore_error: bool, * op_type: 'index'|'create' * } * @phpstan-type InputOptions array{ * index?: string, * type?: string, * ignore_error?: bool, * op_type?: 'index'|'create' * } */ class ElasticsearchHandler extends AbstractProcessingHandler { protected Client|Client8 $client; /** * @var mixed[] Handler config options * @phpstan-var Options */ protected array $options; /** * @var bool */ private $needsType; /** * @param Client|Client8 $client Elasticsearch Client object * @param mixed[] $options Handler configuration * * @phpstan-param InputOptions $options */ public function __construct(Client|Client8 $client, array $options = [], int|string|Level $level = Level::Debug, bool $bubble = true) { parent::__construct($level, $bubble); $this->client = $client; $this->options = array_merge( [ 'index' => 'monolog', // Elastic index name 'type' => '_doc', // Elastic document type 'ignore_error' => false, // Suppress Elasticsearch exceptions 'op_type' => 'index', // Elastic op_type (index or create) (https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-index_.html#docs-index-api-op_type) ], $options ); if ($client instanceof Client8 || $client::VERSION[0] === '7') { $this->needsType = false; // force the type to _doc for ES8/ES7 $this->options['type'] = '_doc'; } else { $this->needsType = true; } } /** * @inheritDoc */ protected function write(LogRecord $record): void { $this->bulkSend([$record->formatted]); } /** * @inheritDoc */ public function setFormatter(FormatterInterface $formatter): HandlerInterface { if ($formatter instanceof ElasticsearchFormatter) { return parent::setFormatter($formatter); } throw new InvalidArgumentException('ElasticsearchHandler is only compatible with ElasticsearchFormatter'); } /** * Getter options * * @return mixed[] * * @phpstan-return Options */ public function getOptions(): array { return $this->options; } /** * @inheritDoc */ protected function getDefaultFormatter(): FormatterInterface { return new ElasticsearchFormatter($this->options['index'], $this->options['type']); } /** * @inheritDoc */ public function handleBatch(array $records): void { $documents = $this->getFormatter()->formatBatch($records); $this->bulkSend($documents); } /** * Use Elasticsearch bulk API to send list of documents * * @param array> $records Records + _index/_type keys * @throws \RuntimeException */ protected function bulkSend(array $records): void { try { $params = [ 'body' => [], ]; foreach ($records as $record) { $params['body'][] = [ $this->options['op_type'] => $this->needsType ? [ '_index' => $record['_index'], '_type' => $record['_type'], ] : [ '_index' => $record['_index'], ], ]; unset($record['_index'], $record['_type']); $params['body'][] = $record; } /** @var Elasticsearch */ $responses = $this->client->bulk($params); if ($responses['errors'] === true) { throw $this->createExceptionFromResponses($responses); } } catch (Throwable $e) { if (! $this->options['ignore_error']) { throw new RuntimeException('Error sending messages to Elasticsearch', 0, $e); } } } /** * Creates elasticsearch exception from responses array * * Only the first error is converted into an exception. * * @param mixed[]|Elasticsearch $responses returned by $this->client->bulk() */ protected function createExceptionFromResponses($responses): Throwable { foreach ($responses['items'] ?? [] as $item) { if (isset($item['index']['error'])) { return $this->createExceptionFromError($item['index']['error']); } } if (class_exists(ElasticInvalidArgumentException::class)) { return new ElasticInvalidArgumentException('Elasticsearch failed to index one or more records.'); } if (class_exists(ElasticsearchRuntimeException::class)) { return new ElasticsearchRuntimeException('Elasticsearch failed to index one or more records.'); } throw new \LogicException('Unsupported elastic search client version'); } /** * Creates elasticsearch exception from error array * * @param mixed[] $error */ protected function createExceptionFromError(array $error): Throwable { $previous = isset($error['caused_by']) ? $this->createExceptionFromError($error['caused_by']) : null; if (class_exists(ElasticInvalidArgumentException::class)) { return new ElasticInvalidArgumentException($error['type'] . ': ' . $error['reason'], 0, $previous); } if (class_exists(ElasticsearchRuntimeException::class)) { return new ElasticsearchRuntimeException($error['type'].': '.$error['reason'], 0, $previous); } throw new \LogicException('Unsupported elastic search client version'); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/ErrorLogHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Formatter\LineFormatter; use Monolog\Formatter\FormatterInterface; use Monolog\Level; use Monolog\Utils; use Monolog\LogRecord; /** * Stores to PHP error_log() handler. * * @author Elan Ruusamäe */ class ErrorLogHandler extends AbstractProcessingHandler { public const OPERATING_SYSTEM = 0; public const SAPI = 4; /** @var 0|4 */ protected int $messageType; protected bool $expandNewlines; /** * @param 0|4 $messageType Says where the error should go. * @param bool $expandNewlines If set to true, newlines in the message will be expanded to be take multiple log entries * * @throws \InvalidArgumentException If an unsupported message type is set */ public function __construct(int $messageType = self::OPERATING_SYSTEM, int|string|Level $level = Level::Debug, bool $bubble = true, bool $expandNewlines = false) { parent::__construct($level, $bubble); if (false === \in_array($messageType, self::getAvailableTypes(), true)) { $message = sprintf('The given message type "%s" is not supported', print_r($messageType, true)); throw new \InvalidArgumentException($message); } $this->messageType = $messageType; $this->expandNewlines = $expandNewlines; } /** * @return int[] With all available types */ public static function getAvailableTypes(): array { return [ self::OPERATING_SYSTEM, self::SAPI, ]; } /** * @inheritDoc */ protected function getDefaultFormatter(): FormatterInterface { return new LineFormatter('[%datetime%] %channel%.%level_name%: %message% %context% %extra%'); } /** * @inheritDoc */ protected function write(LogRecord $record): void { if (!$this->expandNewlines) { error_log((string) $record->formatted, $this->messageType); return; } $lines = preg_split('{[\r\n]+}', (string) $record->formatted); if ($lines === false) { $pcreErrorCode = preg_last_error(); throw new \RuntimeException('Failed to preg_split formatted string: ' . $pcreErrorCode . ' / '. preg_last_error_msg()); } foreach ($lines as $line) { error_log($line, $this->messageType); } } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/FallbackGroupHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Throwable; use Monolog\LogRecord; /** * Forwards records to at most one handler * * If a handler fails, the exception is suppressed and the record is forwarded to the next handler. * * As soon as one handler handles a record successfully, the handling stops there. */ class FallbackGroupHandler extends GroupHandler { /** * @inheritDoc */ public function handle(LogRecord $record): bool { if (\count($this->processors) > 0) { $record = $this->processRecord($record); } foreach ($this->handlers as $handler) { try { $handler->handle(clone $record); break; } catch (Throwable $e) { // What throwable? } } return false === $this->bubble; } /** * @inheritDoc */ public function handleBatch(array $records): void { if (\count($this->processors) > 0) { $processed = []; foreach ($records as $record) { $processed[] = $this->processRecord($record); } $records = $processed; } foreach ($this->handlers as $handler) { try { $handler->handleBatch(array_map(fn ($record) => clone $record, $records)); break; } catch (Throwable $e) { // What throwable? } } } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/FilterHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Closure; use Monolog\Level; use Monolog\Logger; use Monolog\ResettableInterface; use Monolog\Formatter\FormatterInterface; use Psr\Log\LogLevel; use Monolog\LogRecord; /** * Simple handler wrapper that filters records based on a list of levels * * It can be configured with an exact list of levels to allow, or a min/max level. * * @author Hennadiy Verkh * @author Jordi Boggiano */ class FilterHandler extends Handler implements ProcessableHandlerInterface, ResettableInterface, FormattableHandlerInterface { use ProcessableHandlerTrait; /** * Handler or factory Closure($record, $this) * * @phpstan-var (Closure(LogRecord|null, HandlerInterface): HandlerInterface)|HandlerInterface */ protected Closure|HandlerInterface $handler; /** * Minimum level for logs that are passed to handler * * @var bool[] Map of Level value => true * @phpstan-var array, true> */ protected array $acceptedLevels; /** * Whether the messages that are handled can bubble up the stack or not */ protected bool $bubble; /** * @phpstan-param (Closure(LogRecord|null, HandlerInterface): HandlerInterface)|HandlerInterface $handler * * @param Closure|HandlerInterface $handler Handler or factory Closure($record|null, $filterHandler). * @param int|string|Level|array $minLevelOrList A list of levels to accept or a minimum level if maxLevel is provided * @param int|string|Level|LogLevel::* $maxLevel Maximum level to accept, only used if $minLevelOrList is not an array * @param bool $bubble Whether the messages that are handled can bubble up the stack or not * * @phpstan-param value-of|value-of|Level|LogLevel::*|array|value-of|Level|LogLevel::*> $minLevelOrList * @phpstan-param value-of|value-of|Level|LogLevel::* $maxLevel */ public function __construct(Closure|HandlerInterface $handler, int|string|Level|array $minLevelOrList = Level::Debug, int|string|Level $maxLevel = Level::Emergency, bool $bubble = true) { $this->handler = $handler; $this->bubble = $bubble; $this->setAcceptedLevels($minLevelOrList, $maxLevel); } /** * @phpstan-return list List of levels */ public function getAcceptedLevels(): array { return array_map(fn (int $level) => Level::from($level), array_keys($this->acceptedLevels)); } /** * @param int|string|Level|LogLevel::*|array $minLevelOrList A list of levels to accept or a minimum level or level name if maxLevel is provided * @param int|string|Level|LogLevel::* $maxLevel Maximum level or level name to accept, only used if $minLevelOrList is not an array * @return $this * * @phpstan-param value-of|value-of|Level|LogLevel::*|array|value-of|Level|LogLevel::*> $minLevelOrList * @phpstan-param value-of|value-of|Level|LogLevel::* $maxLevel */ public function setAcceptedLevels(int|string|Level|array $minLevelOrList = Level::Debug, int|string|Level $maxLevel = Level::Emergency): self { if (\is_array($minLevelOrList)) { $acceptedLevels = array_map(Logger::toMonologLevel(...), $minLevelOrList); } else { $minLevelOrList = Logger::toMonologLevel($minLevelOrList); $maxLevel = Logger::toMonologLevel($maxLevel); $acceptedLevels = array_values(array_filter(Level::cases(), fn (Level $level) => $level->value >= $minLevelOrList->value && $level->value <= $maxLevel->value)); } $this->acceptedLevels = []; foreach ($acceptedLevels as $level) { $this->acceptedLevels[$level->value] = true; } return $this; } /** * @inheritDoc */ public function isHandling(LogRecord $record): bool { return isset($this->acceptedLevels[$record->level->value]); } /** * @inheritDoc */ public function handle(LogRecord $record): bool { if (!$this->isHandling($record)) { return false; } if (\count($this->processors) > 0) { $record = $this->processRecord($record); } $this->getHandler($record)->handle($record); return false === $this->bubble; } /** * @inheritDoc */ public function handleBatch(array $records): void { $filtered = []; foreach ($records as $record) { if ($this->isHandling($record)) { $filtered[] = $record; } } if (\count($filtered) > 0) { $this->getHandler($filtered[\count($filtered) - 1])->handleBatch($filtered); } } /** * Return the nested handler * * If the handler was provided as a factory, this will trigger the handler's instantiation. */ public function getHandler(LogRecord|null $record = null): HandlerInterface { if (!$this->handler instanceof HandlerInterface) { $handler = ($this->handler)($record, $this); if (!$handler instanceof HandlerInterface) { throw new \RuntimeException("The factory Closure should return a HandlerInterface"); } $this->handler = $handler; } return $this->handler; } /** * @inheritDoc */ public function setFormatter(FormatterInterface $formatter): HandlerInterface { $handler = $this->getHandler(); if ($handler instanceof FormattableHandlerInterface) { $handler->setFormatter($formatter); return $this; } throw new \UnexpectedValueException('The nested handler of type '.\get_class($handler).' does not support formatters.'); } /** * @inheritDoc */ public function getFormatter(): FormatterInterface { $handler = $this->getHandler(); if ($handler instanceof FormattableHandlerInterface) { return $handler->getFormatter(); } throw new \UnexpectedValueException('The nested handler of type '.\get_class($handler).' does not support formatters.'); } public function reset(): void { $this->resetProcessors(); if ($this->getHandler() instanceof ResettableInterface) { $this->getHandler()->reset(); } } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ActivationStrategyInterface.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler\FingersCrossed; use Monolog\LogRecord; /** * Interface for activation strategies for the FingersCrossedHandler. * * @author Johannes M. Schmitt */ interface ActivationStrategyInterface { /** * Returns whether the given record activates the handler. */ public function isHandlerActivated(LogRecord $record): bool; } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ChannelLevelActivationStrategy.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler\FingersCrossed; use Monolog\Level; use Monolog\Logger; use Psr\Log\LogLevel; use Monolog\LogRecord; /** * Channel and Error level based monolog activation strategy. Allows to trigger activation * based on level per channel. e.g. trigger activation on level 'ERROR' by default, except * for records of the 'sql' channel; those should trigger activation on level 'WARN'. * * Example: * * * $activationStrategy = new ChannelLevelActivationStrategy( * Level::Critical, * array( * 'request' => Level::Alert, * 'sensitive' => Level::Error, * ) * ); * $handler = new FingersCrossedHandler(new StreamHandler('php://stderr'), $activationStrategy); * * * @author Mike Meessen */ class ChannelLevelActivationStrategy implements ActivationStrategyInterface { private Level $defaultActionLevel; /** * @var array */ private array $channelToActionLevel; /** * @param int|string|Level|LogLevel::* $defaultActionLevel The default action level to be used if the record's category doesn't match any * @param array $channelToActionLevel An array that maps channel names to action levels. * * @phpstan-param value-of|value-of|Level|LogLevel::* $defaultActionLevel * @phpstan-param array|value-of|Level|LogLevel::*> $channelToActionLevel */ public function __construct(int|string|Level $defaultActionLevel, array $channelToActionLevel = []) { $this->defaultActionLevel = Logger::toMonologLevel($defaultActionLevel); $this->channelToActionLevel = array_map(Logger::toMonologLevel(...), $channelToActionLevel); } public function isHandlerActivated(LogRecord $record): bool { if (isset($this->channelToActionLevel[$record->channel])) { return $record->level->value >= $this->channelToActionLevel[$record->channel]->value; } return $record->level->value >= $this->defaultActionLevel->value; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ErrorLevelActivationStrategy.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler\FingersCrossed; use Monolog\Level; use Monolog\LogRecord; use Monolog\Logger; use Psr\Log\LogLevel; /** * Error level based activation strategy. * * @author Johannes M. Schmitt */ class ErrorLevelActivationStrategy implements ActivationStrategyInterface { private Level $actionLevel; /** * @param int|string|Level $actionLevel Level or name or value * * @phpstan-param value-of|value-of|Level|LogLevel::* $actionLevel */ public function __construct(int|string|Level $actionLevel) { $this->actionLevel = Logger::toMonologLevel($actionLevel); } public function isHandlerActivated(LogRecord $record): bool { return $record->level->value >= $this->actionLevel->value; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossedHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Closure; use Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy; use Monolog\Handler\FingersCrossed\ActivationStrategyInterface; use Monolog\Level; use Monolog\Logger; use Monolog\ResettableInterface; use Monolog\Formatter\FormatterInterface; use Psr\Log\LogLevel; use Monolog\LogRecord; /** * Buffers all records until a certain level is reached * * The advantage of this approach is that you don't get any clutter in your log files. * Only requests which actually trigger an error (or whatever your actionLevel is) will be * in the logs, but they will contain all records, not only those above the level threshold. * * You can then have a passthruLevel as well which means that at the end of the request, * even if it did not get activated, it will still send through log records of e.g. at least a * warning level. * * You can find the various activation strategies in the * Monolog\Handler\FingersCrossed\ namespace. * * @author Jordi Boggiano */ class FingersCrossedHandler extends Handler implements ProcessableHandlerInterface, ResettableInterface, FormattableHandlerInterface { use ProcessableHandlerTrait; /** * Handler or factory Closure($record, $this) * * @phpstan-var (Closure(LogRecord|null, HandlerInterface): HandlerInterface)|HandlerInterface */ protected Closure|HandlerInterface $handler; protected ActivationStrategyInterface $activationStrategy; protected bool $buffering = true; protected int $bufferSize; /** @var LogRecord[] */ protected array $buffer = []; protected bool $stopBuffering; protected Level|null $passthruLevel = null; protected bool $bubble; /** * @phpstan-param (Closure(LogRecord|null, HandlerInterface): HandlerInterface)|HandlerInterface $handler * * @param Closure|HandlerInterface $handler Handler or factory Closure($record|null, $fingersCrossedHandler). * @param int|string|Level|LogLevel::*|null $activationStrategy Strategy which determines when this handler takes action, or a level name/value at which the handler is activated * @param int $bufferSize How many entries should be buffered at most, beyond that the oldest items are removed from the buffer. * @param bool $bubble Whether the messages that are handled can bubble up the stack or not * @param bool $stopBuffering Whether the handler should stop buffering after being triggered (default true) * @param int|string|Level|LogLevel::*|null $passthruLevel Minimum level to always flush to handler on close, even if strategy not triggered * * @phpstan-param value-of|value-of|Level|LogLevel::*|ActivationStrategyInterface|null $activationStrategy * @phpstan-param value-of|value-of|Level|LogLevel::*|null $passthruLevel */ public function __construct(Closure|HandlerInterface $handler, int|string|Level|ActivationStrategyInterface|null $activationStrategy = null, int $bufferSize = 0, bool $bubble = true, bool $stopBuffering = true, int|string|Level|null $passthruLevel = null) { if (null === $activationStrategy) { $activationStrategy = new ErrorLevelActivationStrategy(Level::Warning); } // convert simple int activationStrategy to an object if (!$activationStrategy instanceof ActivationStrategyInterface) { $activationStrategy = new ErrorLevelActivationStrategy($activationStrategy); } $this->handler = $handler; $this->activationStrategy = $activationStrategy; $this->bufferSize = $bufferSize; $this->bubble = $bubble; $this->stopBuffering = $stopBuffering; if ($passthruLevel !== null) { $this->passthruLevel = Logger::toMonologLevel($passthruLevel); } } /** * @inheritDoc */ public function isHandling(LogRecord $record): bool { return true; } /** * Manually activate this logger regardless of the activation strategy */ public function activate(): void { if ($this->stopBuffering) { $this->buffering = false; } $this->getHandler(end($this->buffer) ?: null)->handleBatch($this->buffer); $this->buffer = []; } /** * @inheritDoc */ public function handle(LogRecord $record): bool { if (\count($this->processors) > 0) { $record = $this->processRecord($record); } if ($this->buffering) { $this->buffer[] = $record; if ($this->bufferSize > 0 && \count($this->buffer) > $this->bufferSize) { array_shift($this->buffer); } if ($this->activationStrategy->isHandlerActivated($record)) { $this->activate(); } } else { $this->getHandler($record)->handle($record); } return false === $this->bubble; } /** * @inheritDoc */ public function close(): void { $this->flushBuffer(); $this->getHandler()->close(); } public function reset(): void { $this->flushBuffer(); $this->resetProcessors(); if ($this->getHandler() instanceof ResettableInterface) { $this->getHandler()->reset(); } } /** * Clears the buffer without flushing any messages down to the wrapped handler. * * It also resets the handler to its initial buffering state. */ public function clear(): void { $this->buffer = []; $this->reset(); } /** * Resets the state of the handler. Stops forwarding records to the wrapped handler. */ private function flushBuffer(): void { if (null !== $this->passthruLevel) { $passthruLevel = $this->passthruLevel; $this->buffer = array_filter($this->buffer, static function ($record) use ($passthruLevel) { return $passthruLevel->includes($record->level); }); if (\count($this->buffer) > 0) { $this->getHandler(end($this->buffer))->handleBatch($this->buffer); } } $this->buffer = []; $this->buffering = true; } /** * Return the nested handler * * If the handler was provided as a factory, this will trigger the handler's instantiation. */ public function getHandler(LogRecord|null $record = null): HandlerInterface { if (!$this->handler instanceof HandlerInterface) { $handler = ($this->handler)($record, $this); if (!$handler instanceof HandlerInterface) { throw new \RuntimeException("The factory Closure should return a HandlerInterface"); } $this->handler = $handler; } return $this->handler; } /** * @inheritDoc */ public function setFormatter(FormatterInterface $formatter): HandlerInterface { $handler = $this->getHandler(); if ($handler instanceof FormattableHandlerInterface) { $handler->setFormatter($formatter); return $this; } throw new \UnexpectedValueException('The nested handler of type '.\get_class($handler).' does not support formatters.'); } /** * @inheritDoc */ public function getFormatter(): FormatterInterface { $handler = $this->getHandler(); if ($handler instanceof FormattableHandlerInterface) { return $handler->getFormatter(); } throw new \UnexpectedValueException('The nested handler of type '.\get_class($handler).' does not support formatters.'); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/FirePHPHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Formatter\WildfireFormatter; use Monolog\Formatter\FormatterInterface; use Monolog\LogRecord; /** * Simple FirePHP Handler (http://www.firephp.org/), which uses the Wildfire protocol. * * @author Eric Clemmons (@ericclemmons) */ class FirePHPHandler extends AbstractProcessingHandler { use WebRequestRecognizerTrait; /** * WildFire JSON header message format */ protected const PROTOCOL_URI = 'http://meta.wildfirehq.org/Protocol/JsonStream/0.2'; /** * FirePHP structure for parsing messages & their presentation */ protected const STRUCTURE_URI = 'http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1'; /** * Must reference a "known" plugin, otherwise headers won't display in FirePHP */ protected const PLUGIN_URI = 'http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/0.3'; /** * Header prefix for Wildfire to recognize & parse headers */ protected const HEADER_PREFIX = 'X-Wf'; /** * Whether or not Wildfire vendor-specific headers have been generated & sent yet */ protected static bool $initialized = false; /** * Shared static message index between potentially multiple handlers */ protected static int $messageIndex = 1; protected static bool $sendHeaders = true; /** * Base header creation function used by init headers & record headers * * @param array $meta Wildfire Plugin, Protocol & Structure Indexes * @param string $message Log message * * @return array Complete header string ready for the client as key and message as value * * @phpstan-return non-empty-array */ protected function createHeader(array $meta, string $message): array { $header = sprintf('%s-%s', static::HEADER_PREFIX, join('-', $meta)); return [$header => $message]; } /** * Creates message header from record * * @return array * * @phpstan-return non-empty-array * * @see createHeader() */ protected function createRecordHeader(LogRecord $record): array { // Wildfire is extensible to support multiple protocols & plugins in a single request, // but we're not taking advantage of that (yet), so we're using "1" for simplicity's sake. return $this->createHeader( [1, 1, 1, self::$messageIndex++], $record->formatted ); } /** * @inheritDoc */ protected function getDefaultFormatter(): FormatterInterface { return new WildfireFormatter(); } /** * Wildfire initialization headers to enable message parsing * * @see createHeader() * @see sendHeader() * * @return array */ protected function getInitHeaders(): array { // Initial payload consists of required headers for Wildfire return array_merge( $this->createHeader(['Protocol', 1], static::PROTOCOL_URI), $this->createHeader([1, 'Structure', 1], static::STRUCTURE_URI), $this->createHeader([1, 'Plugin', 1], static::PLUGIN_URI) ); } /** * Send header string to the client */ protected function sendHeader(string $header, string $content): void { if (!headers_sent() && self::$sendHeaders) { header(sprintf('%s: %s', $header, $content)); } } /** * Creates & sends header for a record, ensuring init headers have been sent prior * * @see sendHeader() * @see sendInitHeaders() */ protected function write(LogRecord $record): void { if (!self::$sendHeaders || !$this->isWebRequest()) { return; } // WildFire-specific headers must be sent prior to any messages if (!self::$initialized) { self::$initialized = true; self::$sendHeaders = $this->headersAccepted(); if (!self::$sendHeaders) { return; } foreach ($this->getInitHeaders() as $header => $content) { $this->sendHeader($header, $content); } } $header = $this->createRecordHeader($record); if (trim(current($header)) !== '') { $this->sendHeader(key($header), current($header)); } } /** * Verifies if the headers are accepted by the current user agent */ protected function headersAccepted(): bool { if (isset($_SERVER['HTTP_USER_AGENT']) && 1 === preg_match('{\bFirePHP/\d+\.\d+\b}', $_SERVER['HTTP_USER_AGENT'])) { return true; } return isset($_SERVER['HTTP_X_FIREPHP_VERSION']); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/FleepHookHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Formatter\FormatterInterface; use Monolog\Formatter\LineFormatter; use Monolog\Level; use Monolog\LogRecord; /** * Sends logs to Fleep.io using Webhook integrations * * You'll need a Fleep.io account to use this handler. * * @see https://fleep.io/integrations/webhooks/ Fleep Webhooks Documentation * @author Ando Roots */ class FleepHookHandler extends SocketHandler { protected const FLEEP_HOST = 'fleep.io'; protected const FLEEP_HOOK_URI = '/hook/'; /** * @var string Webhook token (specifies the conversation where logs are sent) */ protected string $token; /** * Construct a new Fleep.io Handler. * * For instructions on how to create a new web hook in your conversations * see https://fleep.io/integrations/webhooks/ * * @param string $token Webhook token * @throws MissingExtensionException if OpenSSL is missing */ public function __construct( string $token, $level = Level::Debug, bool $bubble = true, bool $persistent = false, float $timeout = 0.0, float $writingTimeout = 10.0, ?float $connectionTimeout = null, ?int $chunkSize = null ) { if (!\extension_loaded('openssl')) { throw new MissingExtensionException('The OpenSSL PHP extension is required to use the FleepHookHandler'); } $this->token = $token; $connectionString = 'ssl://' . static::FLEEP_HOST . ':443'; parent::__construct( $connectionString, $level, $bubble, $persistent, $timeout, $writingTimeout, $connectionTimeout, $chunkSize ); } /** * Returns the default formatter to use with this handler * * Overloaded to remove empty context and extra arrays from the end of the log message. * * @return LineFormatter */ protected function getDefaultFormatter(): FormatterInterface { return new LineFormatter(null, null, true, true); } /** * Handles a log record */ public function write(LogRecord $record): void { parent::write($record); $this->closeSocket(); } /** * @inheritDoc */ protected function generateDataStream(LogRecord $record): string { $content = $this->buildContent($record); return $this->buildHeader($content) . $content; } /** * Builds the header of the API Call */ private function buildHeader(string $content): string { $header = "POST " . static::FLEEP_HOOK_URI . $this->token . " HTTP/1.1\r\n"; $header .= "Host: " . static::FLEEP_HOST . "\r\n"; $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; $header .= "Content-Length: " . \strlen($content) . "\r\n"; $header .= "\r\n"; return $header; } /** * Builds the body of API call */ private function buildContent(LogRecord $record): string { $dataArray = [ 'message' => $record->formatted, ]; return http_build_query($dataArray); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/FlowdockHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Level; use Monolog\Utils; use Monolog\Formatter\FlowdockFormatter; use Monolog\Formatter\FormatterInterface; use Monolog\LogRecord; /** * Sends notifications through the Flowdock push API * * This must be configured with a FlowdockFormatter instance via setFormatter() * * Notes: * API token - Flowdock API token * * @author Dominik Liebler * @see https://www.flowdock.com/api/push * @deprecated Since 2.9.0 and 3.3.0, Flowdock was shutdown we will thus drop this handler in Monolog 4 */ class FlowdockHandler extends SocketHandler { protected string $apiToken; /** * @throws MissingExtensionException if OpenSSL is missing */ public function __construct( string $apiToken, $level = Level::Debug, bool $bubble = true, bool $persistent = false, float $timeout = 0.0, float $writingTimeout = 10.0, ?float $connectionTimeout = null, ?int $chunkSize = null ) { if (!\extension_loaded('openssl')) { throw new MissingExtensionException('The OpenSSL PHP extension is required to use the FlowdockHandler'); } parent::__construct( 'ssl://api.flowdock.com:443', $level, $bubble, $persistent, $timeout, $writingTimeout, $connectionTimeout, $chunkSize ); $this->apiToken = $apiToken; } /** * @inheritDoc */ public function setFormatter(FormatterInterface $formatter): HandlerInterface { if (!$formatter instanceof FlowdockFormatter) { throw new \InvalidArgumentException('The FlowdockHandler requires an instance of Monolog\Formatter\FlowdockFormatter to function correctly'); } return parent::setFormatter($formatter); } /** * Gets the default formatter. */ protected function getDefaultFormatter(): FormatterInterface { throw new \InvalidArgumentException('The FlowdockHandler must be configured (via setFormatter) with an instance of Monolog\Formatter\FlowdockFormatter to function correctly'); } /** * @inheritDoc */ protected function write(LogRecord $record): void { parent::write($record); $this->closeSocket(); } /** * @inheritDoc */ protected function generateDataStream(LogRecord $record): string { $content = $this->buildContent($record); return $this->buildHeader($content) . $content; } /** * Builds the body of API call */ private function buildContent(LogRecord $record): string { return Utils::jsonEncode($record->formatted); } /** * Builds the header of the API Call */ private function buildHeader(string $content): string { $header = "POST /v1/messages/team_inbox/" . $this->apiToken . " HTTP/1.1\r\n"; $header .= "Host: api.flowdock.com\r\n"; $header .= "Content-Type: application/json\r\n"; $header .= "Content-Length: " . \strlen($content) . "\r\n"; $header .= "\r\n"; return $header; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/FormattableHandlerInterface.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Formatter\FormatterInterface; /** * Interface to describe loggers that have a formatter * * @author Jordi Boggiano */ interface FormattableHandlerInterface { /** * Sets the formatter. * * @return HandlerInterface self */ public function setFormatter(FormatterInterface $formatter): HandlerInterface; /** * Gets the formatter. */ public function getFormatter(): FormatterInterface; } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/FormattableHandlerTrait.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Formatter\FormatterInterface; use Monolog\Formatter\LineFormatter; /** * Helper trait for implementing FormattableInterface * * @author Jordi Boggiano */ trait FormattableHandlerTrait { protected FormatterInterface|null $formatter = null; /** * @inheritDoc */ public function setFormatter(FormatterInterface $formatter): HandlerInterface { $this->formatter = $formatter; return $this; } /** * @inheritDoc */ public function getFormatter(): FormatterInterface { if (null === $this->formatter) { $this->formatter = $this->getDefaultFormatter(); } return $this->formatter; } /** * Gets the default formatter. * * Overwrite this if the LineFormatter is not a good default for your handler. */ protected function getDefaultFormatter(): FormatterInterface { return new LineFormatter(); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/GelfHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Gelf\PublisherInterface; use Monolog\Level; use Monolog\Formatter\GelfMessageFormatter; use Monolog\Formatter\FormatterInterface; use Monolog\LogRecord; /** * Handler to send messages to a Graylog2 (http://www.graylog2.org) server * * @author Matt Lehner * @author Benjamin Zikarsky */ class GelfHandler extends AbstractProcessingHandler { /** * @var PublisherInterface the publisher object that sends the message to the server */ protected PublisherInterface $publisher; /** * @param PublisherInterface $publisher a gelf publisher object */ public function __construct(PublisherInterface $publisher, int|string|Level $level = Level::Debug, bool $bubble = true) { parent::__construct($level, $bubble); $this->publisher = $publisher; } /** * @inheritDoc */ protected function write(LogRecord $record): void { $this->publisher->publish($record->formatted); } /** * @inheritDoc */ protected function getDefaultFormatter(): FormatterInterface { return new GelfMessageFormatter(); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/GroupHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Formatter\FormatterInterface; use Monolog\ResettableInterface; use Monolog\LogRecord; /** * Forwards records to multiple handlers * * @author Lenar Lõhmus */ class GroupHandler extends Handler implements ProcessableHandlerInterface, ResettableInterface { use ProcessableHandlerTrait; /** @var HandlerInterface[] */ protected array $handlers; protected bool $bubble; /** * @param HandlerInterface[] $handlers Array of Handlers. * @param bool $bubble Whether the messages that are handled can bubble up the stack or not * * @throws \InvalidArgumentException if an unsupported handler is set */ public function __construct(array $handlers, bool $bubble = true) { foreach ($handlers as $handler) { if (!$handler instanceof HandlerInterface) { throw new \InvalidArgumentException('The first argument of the GroupHandler must be an array of HandlerInterface instances.'); } } $this->handlers = $handlers; $this->bubble = $bubble; } /** * @inheritDoc */ public function isHandling(LogRecord $record): bool { foreach ($this->handlers as $handler) { if ($handler->isHandling($record)) { return true; } } return false; } /** * @inheritDoc */ public function handle(LogRecord $record): bool { if (\count($this->processors) > 0) { $record = $this->processRecord($record); } foreach ($this->handlers as $handler) { $handler->handle(clone $record); } return false === $this->bubble; } /** * @inheritDoc */ public function handleBatch(array $records): void { if (\count($this->processors) > 0) { $processed = []; foreach ($records as $record) { $processed[] = $this->processRecord($record); } $records = $processed; } foreach ($this->handlers as $handler) { $handler->handleBatch(array_map(fn ($record) => clone $record, $records)); } } public function reset(): void { $this->resetProcessors(); foreach ($this->handlers as $handler) { if ($handler instanceof ResettableInterface) { $handler->reset(); } } } public function close(): void { parent::close(); foreach ($this->handlers as $handler) { $handler->close(); } } /** * @inheritDoc */ public function setFormatter(FormatterInterface $formatter): HandlerInterface { foreach ($this->handlers as $handler) { if ($handler instanceof FormattableHandlerInterface) { $handler->setFormatter($formatter); } } return $this; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/Handler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; /** * Base Handler class providing basic close() support as well as handleBatch * * @author Jordi Boggiano */ abstract class Handler implements HandlerInterface { /** * @inheritDoc */ public function handleBatch(array $records): void { foreach ($records as $record) { $this->handle($record); } } /** * @inheritDoc */ public function close(): void { } public function __destruct() { try { $this->close(); } catch (\Throwable $e) { // do nothing } } public function __serialize(): array { $this->close(); return (array) $this; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/HandlerInterface.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\LogRecord; /** * Interface that all Monolog Handlers must implement * * @author Jordi Boggiano */ interface HandlerInterface { /** * Checks whether the given record will be handled by this handler. * * This is mostly done for performance reasons, to avoid calling processors for nothing. * * Handlers should still check the record levels within handle(), returning false in isHandling() * is no guarantee that handle() will not be called, and isHandling() might not be called * for a given record. * * @param LogRecord $record Partial log record having only a level initialized */ public function isHandling(LogRecord $record): bool; /** * Handles a record. * * All records may be passed to this method, and the handler should discard * those that it does not want to handle. * * The return value of this function controls the bubbling process of the handler stack. * Unless the bubbling is interrupted (by returning true), the Logger class will keep on * calling further handlers in the stack with a given log record. * * @param LogRecord $record The record to handle * @return bool true means that this handler handled the record, and that bubbling is not permitted. * false means the record was either not processed or that this handler allows bubbling. */ public function handle(LogRecord $record): bool; /** * Handles a set of records at once. * * @param array $records The records to handle */ public function handleBatch(array $records): void; /** * Closes the handler. * * Ends a log cycle and frees all resources used by the handler. * * Closing a Handler means flushing all buffers and freeing any open resources/handles. * * Implementations have to be idempotent (i.e. it should be possible to call close several times without breakage) * and ideally handlers should be able to reopen themselves on handle() after they have been closed. * * This is useful at the end of a request and will be called automatically when the object * is destroyed if you extend Monolog\Handler\Handler. * * If you are thinking of calling this method yourself, most likely you should be * calling ResettableInterface::reset instead. Have a look. */ public function close(): void; } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/HandlerWrapper.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\ResettableInterface; use Monolog\Formatter\FormatterInterface; use Monolog\LogRecord; /** * This simple wrapper class can be used to extend handlers functionality. * * Example: A custom filtering that can be applied to any handler. * * Inherit from this class and override handle() like this: * * public function handle(LogRecord $record) * { * if ($record meets certain conditions) { * return false; * } * return $this->handler->handle($record); * } * * @author Alexey Karapetov */ class HandlerWrapper implements HandlerInterface, ProcessableHandlerInterface, FormattableHandlerInterface, ResettableInterface { protected HandlerInterface $handler; public function __construct(HandlerInterface $handler) { $this->handler = $handler; } /** * @inheritDoc */ public function isHandling(LogRecord $record): bool { return $this->handler->isHandling($record); } /** * @inheritDoc */ public function handle(LogRecord $record): bool { return $this->handler->handle($record); } /** * @inheritDoc */ public function handleBatch(array $records): void { $this->handler->handleBatch($records); } /** * @inheritDoc */ public function close(): void { $this->handler->close(); } /** * @inheritDoc */ public function pushProcessor(callable $callback): HandlerInterface { if ($this->handler instanceof ProcessableHandlerInterface) { $this->handler->pushProcessor($callback); return $this; } throw new \LogicException('The wrapped handler does not implement ' . ProcessableHandlerInterface::class); } /** * @inheritDoc */ public function popProcessor(): callable { if ($this->handler instanceof ProcessableHandlerInterface) { return $this->handler->popProcessor(); } throw new \LogicException('The wrapped handler does not implement ' . ProcessableHandlerInterface::class); } /** * @inheritDoc */ public function setFormatter(FormatterInterface $formatter): HandlerInterface { if ($this->handler instanceof FormattableHandlerInterface) { $this->handler->setFormatter($formatter); return $this; } throw new \LogicException('The wrapped handler does not implement ' . FormattableHandlerInterface::class); } /** * @inheritDoc */ public function getFormatter(): FormatterInterface { if ($this->handler instanceof FormattableHandlerInterface) { return $this->handler->getFormatter(); } throw new \LogicException('The wrapped handler does not implement ' . FormattableHandlerInterface::class); } public function reset(): void { if ($this->handler instanceof ResettableInterface) { $this->handler->reset(); } } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/IFTTTHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Level; use Monolog\Utils; use Monolog\LogRecord; /** * IFTTTHandler uses cURL to trigger IFTTT Maker actions * * Register a secret key and trigger/event name at https://ifttt.com/maker * * value1 will be the channel from monolog's Logger constructor, * value2 will be the level name (ERROR, WARNING, ..) * value3 will be the log record's message * * @author Nehal Patel */ class IFTTTHandler extends AbstractProcessingHandler { private string $eventName; private string $secretKey; /** * @param string $eventName The name of the IFTTT Maker event that should be triggered * @param string $secretKey A valid IFTTT secret key * * @throws MissingExtensionException If the curl extension is missing */ public function __construct(string $eventName, string $secretKey, int|string|Level $level = Level::Error, bool $bubble = true) { if (!\extension_loaded('curl')) { throw new MissingExtensionException('The curl extension is needed to use the IFTTTHandler'); } $this->eventName = $eventName; $this->secretKey = $secretKey; parent::__construct($level, $bubble); } /** * @inheritDoc */ public function write(LogRecord $record): void { $postData = [ "value1" => $record->channel, "value2" => $record["level_name"], "value3" => $record->message, ]; $postString = Utils::jsonEncode($postData); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "https://maker.ifttt.com/trigger/" . $this->eventName . "/with/key/" . $this->secretKey); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $postString); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "Content-Type: application/json", ]); Curl\Util::execute($ch); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/InsightOpsHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Level; use Monolog\LogRecord; /** * Inspired on LogEntriesHandler. * * @author Robert Kaufmann III * @author Gabriel Machado */ class InsightOpsHandler extends SocketHandler { protected string $logToken; /** * @param string $token Log token supplied by InsightOps * @param string $region Region where InsightOps account is hosted. Could be 'us' or 'eu'. * @param bool $useSSL Whether or not SSL encryption should be used * * @throws MissingExtensionException If SSL encryption is set to true and OpenSSL is missing */ public function __construct( string $token, string $region = 'us', bool $useSSL = true, $level = Level::Debug, bool $bubble = true, bool $persistent = false, float $timeout = 0.0, float $writingTimeout = 10.0, ?float $connectionTimeout = null, ?int $chunkSize = null ) { if ($useSSL && !\extension_loaded('openssl')) { throw new MissingExtensionException('The OpenSSL PHP plugin is required to use SSL encrypted connection for InsightOpsHandler'); } $endpoint = $useSSL ? 'ssl://' . $region . '.data.logs.insight.rapid7.com:443' : $region . '.data.logs.insight.rapid7.com:80'; parent::__construct( $endpoint, $level, $bubble, $persistent, $timeout, $writingTimeout, $connectionTimeout, $chunkSize ); $this->logToken = $token; } /** * @inheritDoc */ protected function generateDataStream(LogRecord $record): string { return $this->logToken . ' ' . $record->formatted; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/LogEntriesHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Level; use Monolog\LogRecord; /** * @author Robert Kaufmann III */ class LogEntriesHandler extends SocketHandler { protected string $logToken; /** * @param string $token Log token supplied by LogEntries * @param bool $useSSL Whether or not SSL encryption should be used. * @param string $host Custom hostname to send the data to if needed * * @throws MissingExtensionException If SSL encryption is set to true and OpenSSL is missing */ public function __construct( string $token, bool $useSSL = true, $level = Level::Debug, bool $bubble = true, string $host = 'data.logentries.com', bool $persistent = false, float $timeout = 0.0, float $writingTimeout = 10.0, ?float $connectionTimeout = null, ?int $chunkSize = null ) { if ($useSSL && !\extension_loaded('openssl')) { throw new MissingExtensionException('The OpenSSL PHP plugin is required to use SSL encrypted connection for LogEntriesHandler'); } $endpoint = $useSSL ? 'ssl://' . $host . ':443' : $host . ':80'; parent::__construct( $endpoint, $level, $bubble, $persistent, $timeout, $writingTimeout, $connectionTimeout, $chunkSize ); $this->logToken = $token; } /** * @inheritDoc */ protected function generateDataStream(LogRecord $record): string { return $this->logToken . ' ' . $record->formatted; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/LogglyHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Level; use Monolog\Formatter\FormatterInterface; use Monolog\Formatter\LogglyFormatter; use CurlHandle; use Monolog\LogRecord; /** * Sends errors to Loggly. * * @author Przemek Sobstel * @author Adam Pancutt * @author Gregory Barchard */ class LogglyHandler extends AbstractProcessingHandler { protected const HOST = 'logs-01.loggly.com'; protected const ENDPOINT_SINGLE = 'inputs'; protected const ENDPOINT_BATCH = 'bulk'; /** * Caches the curl handlers for every given endpoint. * * @var CurlHandle[] */ protected array $curlHandlers = []; protected string $token; /** @var string[] */ protected array $tag = []; /** * @param string $token API token supplied by Loggly * * @throws MissingExtensionException If the curl extension is missing */ public function __construct(string $token, int|string|Level $level = Level::Debug, bool $bubble = true) { if (!\extension_loaded('curl')) { throw new MissingExtensionException('The curl extension is needed to use the LogglyHandler'); } $this->token = $token; parent::__construct($level, $bubble); } /** * Loads and returns the shared curl handler for the given endpoint. */ protected function getCurlHandler(string $endpoint): CurlHandle { if (!\array_key_exists($endpoint, $this->curlHandlers)) { $this->curlHandlers[$endpoint] = $this->loadCurlHandle($endpoint); } return $this->curlHandlers[$endpoint]; } /** * Starts a fresh curl session for the given endpoint and returns its handler. */ private function loadCurlHandle(string $endpoint): CurlHandle { $url = sprintf("https://%s/%s/%s/", static::HOST, $endpoint, $this->token); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); return $ch; } /** * @param string[]|string $tag * @return $this */ public function setTag(string|array $tag): self { if ('' === $tag || [] === $tag) { $this->tag = []; } else { $this->tag = \is_array($tag) ? $tag : [$tag]; } return $this; } /** * @param string[]|string $tag * @return $this */ public function addTag(string|array $tag): self { if ('' !== $tag) { $tag = \is_array($tag) ? $tag : [$tag]; $this->tag = array_unique(array_merge($this->tag, $tag)); } return $this; } protected function write(LogRecord $record): void { $this->send($record->formatted, static::ENDPOINT_SINGLE); } public function handleBatch(array $records): void { $level = $this->level; $records = array_filter($records, function ($record) use ($level) { return ($record->level->value >= $level->value); }); if (\count($records) > 0) { $this->send($this->getFormatter()->formatBatch($records), static::ENDPOINT_BATCH); } } protected function send(string $data, string $endpoint): void { $ch = $this->getCurlHandler($endpoint); $headers = ['Content-Type: application/json']; if (\count($this->tag) > 0) { $headers[] = 'X-LOGGLY-TAG: '.implode(',', $this->tag); } curl_setopt($ch, CURLOPT_POSTFIELDS, $data); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); Curl\Util::execute($ch, 5); } protected function getDefaultFormatter(): FormatterInterface { return new LogglyFormatter(); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/LogmaticHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Level; use Monolog\Formatter\FormatterInterface; use Monolog\Formatter\LogmaticFormatter; use Monolog\LogRecord; /** * @author Julien Breux */ class LogmaticHandler extends SocketHandler { private string $logToken; private string $hostname; private string $appName; /** * @param string $token Log token supplied by Logmatic. * @param string $hostname Host name supplied by Logmatic. * @param string $appName Application name supplied by Logmatic. * @param bool $useSSL Whether or not SSL encryption should be used. * * @throws MissingExtensionException If SSL encryption is set to true and OpenSSL is missing */ public function __construct( string $token, string $hostname = '', string $appName = '', bool $useSSL = true, $level = Level::Debug, bool $bubble = true, bool $persistent = false, float $timeout = 0.0, float $writingTimeout = 10.0, ?float $connectionTimeout = null, ?int $chunkSize = null ) { if ($useSSL && !\extension_loaded('openssl')) { throw new MissingExtensionException('The OpenSSL PHP extension is required to use SSL encrypted connection for LogmaticHandler'); } $endpoint = $useSSL ? 'ssl://api.logmatic.io:10515' : 'api.logmatic.io:10514'; $endpoint .= '/v1/'; parent::__construct( $endpoint, $level, $bubble, $persistent, $timeout, $writingTimeout, $connectionTimeout, $chunkSize ); $this->logToken = $token; $this->hostname = $hostname; $this->appName = $appName; } /** * @inheritDoc */ protected function generateDataStream(LogRecord $record): string { return $this->logToken . ' ' . $record->formatted; } /** * @inheritDoc */ protected function getDefaultFormatter(): FormatterInterface { $formatter = new LogmaticFormatter(); if ($this->hostname !== '') { $formatter->setHostname($this->hostname); } if ($this->appName !== '') { $formatter->setAppName($this->appName); } return $formatter; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/MailHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Formatter\FormatterInterface; use Monolog\Formatter\HtmlFormatter; use Monolog\LogRecord; /** * Base class for all mail handlers * * @author Gyula Sallai */ abstract class MailHandler extends AbstractProcessingHandler { /** * @inheritDoc */ public function handleBatch(array $records): void { $messages = []; foreach ($records as $record) { if ($record->level->isLowerThan($this->level)) { continue; } $message = $this->processRecord($record); $messages[] = $message; } if (\count($messages) > 0) { $this->send((string) $this->getFormatter()->formatBatch($messages), $messages); } } /** * Send a mail with the given content * * @param string $content formatted email body to be sent * @param array $records the array of log records that formed this content * * @phpstan-param non-empty-array $records */ abstract protected function send(string $content, array $records): void; /** * @inheritDoc */ protected function write(LogRecord $record): void { $this->send((string) $record->formatted, [$record]); } /** * @phpstan-param non-empty-array $records */ protected function getHighestRecord(array $records): LogRecord { $highestRecord = null; foreach ($records as $record) { if ($highestRecord === null || $record->level->isHigherThan($highestRecord->level)) { $highestRecord = $record; } } return $highestRecord; } protected function isHtmlBody(string $body): bool { return ($body[0] ?? null) === '<'; } /** * Gets the default formatter. */ protected function getDefaultFormatter(): FormatterInterface { return new HtmlFormatter(); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/MandrillHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Level; use Swift; use Swift_Message; /** * MandrillHandler uses cURL to send the emails to the Mandrill API * * @author Adam Nicholson */ class MandrillHandler extends MailHandler { protected Swift_Message $message; protected string $apiKey; /** * @phpstan-param (Swift_Message|callable(): Swift_Message) $message * * @param string $apiKey A valid Mandrill API key * @param callable|Swift_Message $message An example message for real messages, only the body will be replaced * * @throws \InvalidArgumentException if not a Swift Message is set */ public function __construct(string $apiKey, callable|Swift_Message $message, int|string|Level $level = Level::Error, bool $bubble = true) { parent::__construct($level, $bubble); if (!$message instanceof Swift_Message) { $message = $message(); } if (!$message instanceof Swift_Message) { throw new \InvalidArgumentException('You must provide either a Swift_Message instance or a callable returning it'); } $this->message = $message; $this->apiKey = $apiKey; } /** * @inheritDoc */ protected function send(string $content, array $records): void { $mime = 'text/plain'; if ($this->isHtmlBody($content)) { $mime = 'text/html'; } $message = clone $this->message; $message->setBody($content, $mime); /** @phpstan-ignore-next-line */ if (version_compare(Swift::VERSION, '6.0.0', '>=')) { $message->setDate(new \DateTimeImmutable()); } else { /** @phpstan-ignore-next-line */ $message->setDate(time()); } $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://mandrillapp.com/api/1.0/messages/send-raw.json'); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([ 'key' => $this->apiKey, 'raw_message' => (string) $message, 'async' => false, ])); Curl\Util::execute($ch); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/MissingExtensionException.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; /** * Exception can be thrown if an extension for a handler is missing * * @author Christian Bergau */ class MissingExtensionException extends \Exception { } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/MongoDBHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use MongoDB\Client; use MongoDB\Collection; use MongoDB\Driver\BulkWrite; use MongoDB\Driver\Manager; use Monolog\Level; use Monolog\Formatter\FormatterInterface; use Monolog\Formatter\MongoDBFormatter; use Monolog\LogRecord; /** * Logs to a MongoDB database. * * Usage example: * * $log = new \Monolog\Logger('application'); * $client = new \MongoDB\Client('mongodb://localhost:27017'); * $mongodb = new \Monolog\Handler\MongoDBHandler($client, 'logs', 'prod'); * $log->pushHandler($mongodb); * * The above examples uses the MongoDB PHP library's client class; however, the * MongoDB\Driver\Manager class from ext-mongodb is also supported. */ class MongoDBHandler extends AbstractProcessingHandler { private Collection $collection; private Client|Manager $manager; private string|null $namespace = null; /** * Constructor. * * @param Client|Manager $mongodb MongoDB library or driver client * @param string $database Database name * @param string $collection Collection name */ public function __construct(Client|Manager $mongodb, string $database, string $collection, int|string|Level $level = Level::Debug, bool $bubble = true) { if ($mongodb instanceof Client) { $this->collection = method_exists($mongodb, 'getCollection') ? $mongodb->getCollection($database, $collection) : $mongodb->selectCollection($database, $collection); } else { $this->manager = $mongodb; $this->namespace = $database . '.' . $collection; } parent::__construct($level, $bubble); } protected function write(LogRecord $record): void { if (isset($this->collection)) { $this->collection->insertOne($record->formatted); } if (isset($this->manager, $this->namespace)) { $bulk = new BulkWrite; $bulk->insert($record->formatted); $this->manager->executeBulkWrite($this->namespace, $bulk); } } /** * @inheritDoc */ protected function getDefaultFormatter(): FormatterInterface { return new MongoDBFormatter; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/NativeMailerHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Level; use Monolog\Formatter\LineFormatter; /** * NativeMailerHandler uses the mail() function to send the emails * * @author Christophe Coevoet * @author Mark Garrett */ class NativeMailerHandler extends MailHandler { /** * The email addresses to which the message will be sent * @var string[] */ protected array $to; /** * The subject of the email */ protected string $subject; /** * Optional headers for the message * @var string[] */ protected array $headers = []; /** * Optional parameters for the message * @var string[] */ protected array $parameters = []; /** * The wordwrap length for the message */ protected int $maxColumnWidth; /** * The Content-type for the message */ protected string|null $contentType = null; /** * The encoding for the message */ protected string $encoding = 'utf-8'; /** * @param string|string[] $to The receiver of the mail * @param string $subject The subject of the mail * @param string $from The sender of the mail * @param int $maxColumnWidth The maximum column width that the message lines will have */ public function __construct(string|array $to, string $subject, string $from, int|string|Level $level = Level::Error, bool $bubble = true, int $maxColumnWidth = 70) { parent::__construct($level, $bubble); $this->to = (array) $to; $this->subject = $subject; $this->addHeader(sprintf('From: %s', $from)); $this->maxColumnWidth = $maxColumnWidth; } /** * Add headers to the message * * @param string|string[] $headers Custom added headers * @return $this */ public function addHeader($headers): self { foreach ((array) $headers as $header) { if (strpos($header, "\n") !== false || strpos($header, "\r") !== false) { throw new \InvalidArgumentException('Headers can not contain newline characters for security reasons'); } $this->headers[] = $header; } return $this; } /** * Add parameters to the message * * @param string|string[] $parameters Custom added parameters * @return $this */ public function addParameter($parameters): self { $this->parameters = array_merge($this->parameters, (array) $parameters); return $this; } /** * @inheritDoc */ protected function send(string $content, array $records): void { $contentType = $this->getContentType() ?? ($this->isHtmlBody($content) ? 'text/html' : 'text/plain'); if ($contentType !== 'text/html') { $content = wordwrap($content, $this->maxColumnWidth); } $headers = ltrim(implode("\r\n", $this->headers) . "\r\n", "\r\n"); $headers .= 'Content-type: ' . $contentType . '; charset=' . $this->getEncoding() . "\r\n"; if ($contentType === 'text/html' && false === strpos($headers, 'MIME-Version:')) { $headers .= 'MIME-Version: 1.0' . "\r\n"; } $subjectFormatter = new LineFormatter($this->subject); $subject = $subjectFormatter->format($this->getHighestRecord($records)); $parameters = implode(' ', $this->parameters); foreach ($this->to as $to) { $this->mail($to, $subject, $content, $headers, $parameters); } } public function getContentType(): ?string { return $this->contentType; } public function getEncoding(): string { return $this->encoding; } /** * @param string $contentType The content type of the email - Defaults to text/plain. Use text/html for HTML messages. * @return $this */ public function setContentType(string $contentType): self { if (strpos($contentType, "\n") !== false || strpos($contentType, "\r") !== false) { throw new \InvalidArgumentException('The content type can not contain newline characters to prevent email header injection'); } $this->contentType = $contentType; return $this; } /** * @return $this */ public function setEncoding(string $encoding): self { if (strpos($encoding, "\n") !== false || strpos($encoding, "\r") !== false) { throw new \InvalidArgumentException('The encoding can not contain newline characters to prevent email header injection'); } $this->encoding = $encoding; return $this; } protected function mail(string $to, string $subject, string $content, string $headers, string $parameters): void { mail($to, $subject, $content, $headers, $parameters); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/NewRelicHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Level; use Monolog\Utils; use Monolog\Formatter\NormalizerFormatter; use Monolog\Formatter\FormatterInterface; use Monolog\LogRecord; /** * Class to record a log on a NewRelic application. * Enabling New Relic High Security mode may prevent capture of useful information. * * This handler requires a NormalizerFormatter to function and expects an array in $record->formatted * * @see https://docs.newrelic.com/docs/agents/php-agent * @see https://docs.newrelic.com/docs/accounts-partnerships/accounts/security/high-security */ class NewRelicHandler extends AbstractProcessingHandler { /** * @inheritDoc */ public function __construct( int|string|Level $level = Level::Error, bool $bubble = true, /** * Name of the New Relic application that will receive logs from this handler. */ protected string|null $appName = null, /** * Some context and extra data is passed into the handler as arrays of values. Do we send them as is * (useful if we are using the API), or explode them for display on the NewRelic RPM website? */ protected bool $explodeArrays = false, /** * Name of the current transaction */ protected string|null $transactionName = null ) { parent::__construct($level, $bubble); } /** * @inheritDoc */ protected function write(LogRecord $record): void { if (!$this->isNewRelicEnabled()) { throw new MissingExtensionException('The newrelic PHP extension is required to use the NewRelicHandler'); } if (null !== ($appName = $this->getAppName($record->context))) { $this->setNewRelicAppName($appName); } if (null !== ($transactionName = $this->getTransactionName($record->context))) { $this->setNewRelicTransactionName($transactionName); unset($record->formatted['context']['transaction_name']); } if (isset($record->context['exception']) && $record->context['exception'] instanceof \Throwable) { newrelic_notice_error($record->message, $record->context['exception']); unset($record->formatted['context']['exception']); } else { newrelic_notice_error($record->message); } if (isset($record->formatted['context']) && \is_array($record->formatted['context'])) { foreach ($record->formatted['context'] as $key => $parameter) { if (\is_array($parameter) && $this->explodeArrays) { foreach ($parameter as $paramKey => $paramValue) { $this->setNewRelicParameter('context_' . $key . '_' . $paramKey, $paramValue); } } else { $this->setNewRelicParameter('context_' . $key, $parameter); } } } if (isset($record->formatted['extra']) && \is_array($record->formatted['extra'])) { foreach ($record->formatted['extra'] as $key => $parameter) { if (\is_array($parameter) && $this->explodeArrays) { foreach ($parameter as $paramKey => $paramValue) { $this->setNewRelicParameter('extra_' . $key . '_' . $paramKey, $paramValue); } } else { $this->setNewRelicParameter('extra_' . $key, $parameter); } } } } /** * Checks whether the NewRelic extension is enabled in the system. */ protected function isNewRelicEnabled(): bool { return \extension_loaded('newrelic'); } /** * Returns the appname where this log should be sent. Each log can override the default appname, set in this * handler's constructor, by providing the appname in it's context. * * @param mixed[] $context */ protected function getAppName(array $context): ?string { if (isset($context['appname'])) { return $context['appname']; } return $this->appName; } /** * Returns the name of the current transaction. Each log can override the default transaction name, set in this * handler's constructor, by providing the transaction_name in it's context * * @param mixed[] $context */ protected function getTransactionName(array $context): ?string { if (isset($context['transaction_name'])) { return $context['transaction_name']; } return $this->transactionName; } /** * Sets the NewRelic application that should receive this log. */ protected function setNewRelicAppName(string $appName): void { newrelic_set_appname($appName); } /** * Overwrites the name of the current transaction */ protected function setNewRelicTransactionName(string $transactionName): void { newrelic_name_transaction($transactionName); } /** * @param mixed $value */ protected function setNewRelicParameter(string $key, $value): void { if (null === $value || \is_scalar($value)) { newrelic_add_custom_parameter($key, $value); } else { newrelic_add_custom_parameter($key, Utils::jsonEncode($value, null, true)); } } /** * @inheritDoc */ protected function getDefaultFormatter(): FormatterInterface { return new NormalizerFormatter(); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/NoopHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\LogRecord; /** * No-op * * This handler handles anything, but does nothing, and does not stop bubbling to the rest of the stack. * This can be used for testing, or to disable a handler when overriding a configuration without * influencing the rest of the stack. * * @author Roel Harbers */ class NoopHandler extends Handler { /** * @inheritDoc */ public function isHandling(LogRecord $record): bool { return true; } /** * @inheritDoc */ public function handle(LogRecord $record): bool { return false; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/NullHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Level; use Psr\Log\LogLevel; use Monolog\Logger; use Monolog\LogRecord; /** * Blackhole * * Any record it can handle will be thrown away. This can be used * to put on top of an existing stack to override it temporarily. * * @author Jordi Boggiano */ class NullHandler extends Handler { private Level $level; /** * @param string|int|Level $level The minimum logging level at which this handler will be triggered * * @phpstan-param value-of|value-of|Level|LogLevel::* $level */ public function __construct(string|int|Level $level = Level::Debug) { $this->level = Logger::toMonologLevel($level); } /** * @inheritDoc */ public function isHandling(LogRecord $record): bool { return $record->level->value >= $this->level->value; } /** * @inheritDoc */ public function handle(LogRecord $record): bool { return $record->level->value >= $this->level->value; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/OverflowHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Level; use Monolog\Formatter\FormatterInterface; use Monolog\LogRecord; /** * Handler to only pass log messages when a certain threshold of number of messages is reached. * * This can be useful in cases of processing a batch of data, but you're for example only interested * in case it fails catastrophically instead of a warning for 1 or 2 events. Worse things can happen, right? * * Usage example: * * ``` * $log = new Logger('application'); * $handler = new SomeHandler(...) * * // Pass all warnings to the handler when more than 10 & all error messages when more then 5 * $overflow = new OverflowHandler($handler, [Level::Warning->value => 10, Level::Error->value => 5]); * * $log->pushHandler($overflow); *``` * * @author Kris Buist */ class OverflowHandler extends AbstractHandler implements FormattableHandlerInterface { private HandlerInterface $handler; /** @var array */ private array $thresholdMap = []; /** * Buffer of all messages passed to the handler before the threshold was reached * * @var mixed[][] */ private array $buffer = []; /** * @param array $thresholdMap Dictionary of log level value => threshold */ public function __construct( HandlerInterface $handler, array $thresholdMap = [], $level = Level::Debug, bool $bubble = true ) { $this->handler = $handler; foreach ($thresholdMap as $thresholdLevel => $threshold) { $this->thresholdMap[$thresholdLevel] = $threshold; } parent::__construct($level, $bubble); } /** * Handles a record. * * All records may be passed to this method, and the handler should discard * those that it does not want to handle. * * The return value of this function controls the bubbling process of the handler stack. * Unless the bubbling is interrupted (by returning true), the Logger class will keep on * calling further handlers in the stack with a given log record. * * @inheritDoc */ public function handle(LogRecord $record): bool { if ($record->level->isLowerThan($this->level)) { return false; } $level = $record->level->value; if (!isset($this->thresholdMap[$level])) { $this->thresholdMap[$level] = 0; } if ($this->thresholdMap[$level] > 0) { // The overflow threshold is not yet reached, so we're buffering the record and lowering the threshold by 1 $this->thresholdMap[$level]--; $this->buffer[$level][] = $record; return false === $this->bubble; } if ($this->thresholdMap[$level] === 0) { // This current message is breaking the threshold. Flush the buffer and continue handling the current record foreach ($this->buffer[$level] ?? [] as $buffered) { $this->handler->handle($buffered); } $this->thresholdMap[$level]--; unset($this->buffer[$level]); } $this->handler->handle($record); return false === $this->bubble; } /** * @inheritDoc */ public function setFormatter(FormatterInterface $formatter): HandlerInterface { if ($this->handler instanceof FormattableHandlerInterface) { $this->handler->setFormatter($formatter); return $this; } throw new \UnexpectedValueException('The nested handler of type '.\get_class($this->handler).' does not support formatters.'); } /** * @inheritDoc */ public function getFormatter(): FormatterInterface { if ($this->handler instanceof FormattableHandlerInterface) { return $this->handler->getFormatter(); } throw new \UnexpectedValueException('The nested handler of type '.\get_class($this->handler).' does not support formatters.'); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/PHPConsoleHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Formatter\LineFormatter; use Monolog\Formatter\FormatterInterface; use Monolog\Level; use Monolog\Utils; use PhpConsole\Connector; use PhpConsole\Handler as VendorPhpConsoleHandler; use PhpConsole\Helper; use Monolog\LogRecord; use PhpConsole\Storage; /** * Monolog handler for Google Chrome extension "PHP Console" * * Display PHP error/debug log messages in Google Chrome console and notification popups, executes PHP code remotely * * Usage: * 1. Install Google Chrome extension [now dead and removed from the chrome store] * 2. See overview https://github.com/barbushin/php-console#overview * 3. Install PHP Console library https://github.com/barbushin/php-console#installation * 4. Example (result will looks like http://i.hizliresim.com/vg3Pz4.png) * * $logger = new \Monolog\Logger('all', array(new \Monolog\Handler\PHPConsoleHandler())); * \Monolog\ErrorHandler::register($logger); * echo $undefinedVar; * $logger->debug('SELECT * FROM users', array('db', 'time' => 0.012)); * PC::debug($_SERVER); // PHP Console debugger for any type of vars * * @author Sergey Barbushin https://www.linkedin.com/in/barbushin * @phpstan-type Options array{ * enabled: bool, * classesPartialsTraceIgnore: string[], * debugTagsKeysInContext: array, * useOwnErrorsHandler: bool, * useOwnExceptionsHandler: bool, * sourcesBasePath: string|null, * registerHelper: bool, * serverEncoding: string|null, * headersLimit: int|null, * password: string|null, * enableSslOnlyMode: bool, * ipMasks: string[], * enableEvalListener: bool, * dumperDetectCallbacks: bool, * dumperLevelLimit: int, * dumperItemsCountLimit: int, * dumperItemSizeLimit: int, * dumperDumpSizeLimit: int, * detectDumpTraceAndSource: bool, * dataStorage: Storage|null * } * @phpstan-type InputOptions array{ * enabled?: bool, * classesPartialsTraceIgnore?: string[], * debugTagsKeysInContext?: array, * useOwnErrorsHandler?: bool, * useOwnExceptionsHandler?: bool, * sourcesBasePath?: string|null, * registerHelper?: bool, * serverEncoding?: string|null, * headersLimit?: int|null, * password?: string|null, * enableSslOnlyMode?: bool, * ipMasks?: string[], * enableEvalListener?: bool, * dumperDetectCallbacks?: bool, * dumperLevelLimit?: int, * dumperItemsCountLimit?: int, * dumperItemSizeLimit?: int, * dumperDumpSizeLimit?: int, * detectDumpTraceAndSource?: bool, * dataStorage?: Storage|null * } * * @deprecated Since 2.8.0 and 3.2.0, PHPConsole is abandoned and thus we will drop this handler in Monolog 4 */ class PHPConsoleHandler extends AbstractProcessingHandler { /** * @phpstan-var Options */ private array $options = [ 'enabled' => true, // bool Is PHP Console server enabled 'classesPartialsTraceIgnore' => ['Monolog\\'], // array Hide calls of classes started with... 'debugTagsKeysInContext' => [0, 'tag'], // bool Is PHP Console server enabled 'useOwnErrorsHandler' => false, // bool Enable errors handling 'useOwnExceptionsHandler' => false, // bool Enable exceptions handling 'sourcesBasePath' => null, // string Base path of all project sources to strip in errors source paths 'registerHelper' => true, // bool Register PhpConsole\Helper that allows short debug calls like PC::debug($var, 'ta.g.s') 'serverEncoding' => null, // string|null Server internal encoding 'headersLimit' => null, // int|null Set headers size limit for your web-server 'password' => null, // string|null Protect PHP Console connection by password 'enableSslOnlyMode' => false, // bool Force connection by SSL for clients with PHP Console installed 'ipMasks' => [], // array Set IP masks of clients that will be allowed to connect to PHP Console: array('192.168.*.*', '127.0.0.1') 'enableEvalListener' => false, // bool Enable eval request to be handled by eval dispatcher(if enabled, 'password' option is also required) 'dumperDetectCallbacks' => false, // bool Convert callback items in dumper vars to (callback SomeClass::someMethod) strings 'dumperLevelLimit' => 5, // int Maximum dumped vars array or object nested dump level 'dumperItemsCountLimit' => 100, // int Maximum dumped var same level array items or object properties number 'dumperItemSizeLimit' => 5000, // int Maximum length of any string or dumped array item 'dumperDumpSizeLimit' => 500000, // int Maximum approximate size of dumped vars result formatted in JSON 'detectDumpTraceAndSource' => false, // bool Autodetect and append trace data to debug 'dataStorage' => null, // \PhpConsole\Storage|null Fixes problem with custom $_SESSION handler (see https://github.com/barbushin/php-console#troubleshooting-with-_session-handler-overridden-in-some-frameworks) ]; private Connector $connector; /** * @param array $options See \Monolog\Handler\PHPConsoleHandler::$options for more details * @param Connector|null $connector Instance of \PhpConsole\Connector class (optional) * @throws \RuntimeException * @phpstan-param InputOptions $options */ public function __construct(array $options = [], ?Connector $connector = null, int|string|Level $level = Level::Debug, bool $bubble = true) { if (!class_exists('PhpConsole\Connector')) { throw new \RuntimeException('PHP Console library not found. See https://github.com/barbushin/php-console#installation'); } parent::__construct($level, $bubble); $this->options = $this->initOptions($options); $this->connector = $this->initConnector($connector); } /** * @param array $options * @return array * * @phpstan-param InputOptions $options * @phpstan-return Options */ private function initOptions(array $options): array { $wrongOptions = array_diff(array_keys($options), array_keys($this->options)); if (\count($wrongOptions) > 0) { throw new \RuntimeException('Unknown options: ' . implode(', ', $wrongOptions)); } return array_replace($this->options, $options); } private function initConnector(?Connector $connector = null): Connector { if (null === $connector) { if ($this->options['dataStorage'] instanceof Storage) { Connector::setPostponeStorage($this->options['dataStorage']); } $connector = Connector::getInstance(); } if ($this->options['registerHelper'] && !Helper::isRegistered()) { Helper::register(); } if ($this->options['enabled'] && $connector->isActiveClient()) { if ($this->options['useOwnErrorsHandler'] || $this->options['useOwnExceptionsHandler']) { $handler = VendorPhpConsoleHandler::getInstance(); $handler->setHandleErrors($this->options['useOwnErrorsHandler']); $handler->setHandleExceptions($this->options['useOwnExceptionsHandler']); $handler->start(); } if (null !== $this->options['sourcesBasePath']) { $connector->setSourcesBasePath($this->options['sourcesBasePath']); } if (null !== $this->options['serverEncoding']) { $connector->setServerEncoding($this->options['serverEncoding']); } if (null !== $this->options['password']) { $connector->setPassword($this->options['password']); } if ($this->options['enableSslOnlyMode']) { $connector->enableSslOnlyMode(); } if (\count($this->options['ipMasks']) > 0) { $connector->setAllowedIpMasks($this->options['ipMasks']); } if (null !== $this->options['headersLimit'] && $this->options['headersLimit'] > 0) { $connector->setHeadersLimit($this->options['headersLimit']); } if ($this->options['detectDumpTraceAndSource']) { $connector->getDebugDispatcher()->detectTraceAndSource = true; } $dumper = $connector->getDumper(); $dumper->levelLimit = $this->options['dumperLevelLimit']; $dumper->itemsCountLimit = $this->options['dumperItemsCountLimit']; $dumper->itemSizeLimit = $this->options['dumperItemSizeLimit']; $dumper->dumpSizeLimit = $this->options['dumperDumpSizeLimit']; $dumper->detectCallbacks = $this->options['dumperDetectCallbacks']; if ($this->options['enableEvalListener']) { $connector->startEvalRequestsListener(); } } return $connector; } public function getConnector(): Connector { return $this->connector; } /** * @return array */ public function getOptions(): array { return $this->options; } public function handle(LogRecord $record): bool { if ($this->options['enabled'] && $this->connector->isActiveClient()) { return parent::handle($record); } return !$this->bubble; } /** * Writes the record down to the log of the implementing handler */ protected function write(LogRecord $record): void { if ($record->level->isLowerThan(Level::Notice)) { $this->handleDebugRecord($record); } elseif (isset($record->context['exception']) && $record->context['exception'] instanceof \Throwable) { $this->handleExceptionRecord($record); } else { $this->handleErrorRecord($record); } } private function handleDebugRecord(LogRecord $record): void { [$tags, $filteredContext] = $this->getRecordTags($record); $message = $record->message; if (\count($filteredContext) > 0) { $message .= ' ' . Utils::jsonEncode($this->connector->getDumper()->dump(array_filter($filteredContext)), null, true); } $this->connector->getDebugDispatcher()->dispatchDebug($message, $tags, $this->options['classesPartialsTraceIgnore']); } private function handleExceptionRecord(LogRecord $record): void { $this->connector->getErrorsDispatcher()->dispatchException($record->context['exception']); } private function handleErrorRecord(LogRecord $record): void { $context = $record->context; $this->connector->getErrorsDispatcher()->dispatchError( $context['code'] ?? null, $context['message'] ?? $record->message, $context['file'] ?? null, $context['line'] ?? null, $this->options['classesPartialsTraceIgnore'] ); } /** * @return array{string, mixed[]} */ private function getRecordTags(LogRecord $record): array { $tags = null; $filteredContext = []; if ($record->context !== []) { $filteredContext = $record->context; foreach ($this->options['debugTagsKeysInContext'] as $key) { if (isset($filteredContext[$key])) { $tags = $filteredContext[$key]; if ($key === 0) { array_shift($filteredContext); } else { unset($filteredContext[$key]); } break; } } } return [$tags ?? $record->level->toPsrLogLevel(), $filteredContext]; } /** * @inheritDoc */ protected function getDefaultFormatter(): FormatterInterface { return new LineFormatter('%message%'); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/ProcessHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Level; use Monolog\LogRecord; /** * Stores to STDIN of any process, specified by a command. * * Usage example: *
 * $log = new Logger('myLogger');
 * $log->pushHandler(new ProcessHandler('/usr/bin/php /var/www/monolog/someScript.php'));
 * 
* * @author Kolja Zuelsdorf */ class ProcessHandler extends AbstractProcessingHandler { /** * Holds the process to receive data on its STDIN. * * @var resource|bool|null */ private $process; private string $command; private ?string $cwd; /** * @var resource[] */ private array $pipes = []; private float $timeout; /** * @var array> */ protected const DESCRIPTOR_SPEC = [ 0 => ['pipe', 'r'], // STDIN is a pipe that the child will read from 1 => ['pipe', 'w'], // STDOUT is a pipe that the child will write to 2 => ['pipe', 'w'], // STDERR is a pipe to catch the any errors ]; /** * @param string $command Command for the process to start. Absolute paths are recommended, * especially if you do not use the $cwd parameter. * @param string|null $cwd "Current working directory" (CWD) for the process to be executed in. * @param float $timeout The maximum timeout (in seconds) for the stream_select() function. * @throws \InvalidArgumentException */ public function __construct(string $command, int|string|Level $level = Level::Debug, bool $bubble = true, ?string $cwd = null, float $timeout = 1.0) { if ($command === '') { throw new \InvalidArgumentException('The command argument must be a non-empty string.'); } if ($cwd === '') { throw new \InvalidArgumentException('The optional CWD argument must be a non-empty string or null.'); } parent::__construct($level, $bubble); $this->command = $command; $this->cwd = $cwd; $this->timeout = $timeout; } /** * Writes the record down to the log of the implementing handler * * @throws \UnexpectedValueException */ protected function write(LogRecord $record): void { $this->ensureProcessIsStarted(); $this->writeProcessInput($record->formatted); $errors = $this->readProcessErrors(); if ($errors !== '') { throw new \UnexpectedValueException(sprintf('Errors while writing to process: %s', $errors)); } } /** * Makes sure that the process is actually started, and if not, starts it, * assigns the stream pipes, and handles startup errors, if any. */ private function ensureProcessIsStarted(): void { if (\is_resource($this->process) === false) { $this->startProcess(); $this->handleStartupErrors(); } } /** * Starts the actual process and sets all streams to non-blocking. */ private function startProcess(): void { $this->process = proc_open($this->command, static::DESCRIPTOR_SPEC, $this->pipes, $this->cwd); foreach ($this->pipes as $pipe) { stream_set_blocking($pipe, false); } } /** * Selects the STDERR stream, handles upcoming startup errors, and throws an exception, if any. * * @throws \UnexpectedValueException */ private function handleStartupErrors(): void { $selected = $this->selectErrorStream(); if (false === $selected) { throw new \UnexpectedValueException('Something went wrong while selecting a stream.'); } $errors = $this->readProcessErrors(); if (\is_resource($this->process) === false || $errors !== '') { throw new \UnexpectedValueException( sprintf('The process "%s" could not be opened: ' . $errors, $this->command) ); } } /** * Selects the STDERR stream. * * @return int|bool */ protected function selectErrorStream() { $empty = []; $errorPipes = [$this->pipes[2]]; $seconds = (int) $this->timeout; return stream_select($errorPipes, $empty, $empty, $seconds, (int) (($this->timeout - $seconds) * 1000000)); } /** * Reads the errors of the process, if there are any. * * @codeCoverageIgnore * @return string Empty string if there are no errors. */ protected function readProcessErrors(): string { return (string) stream_get_contents($this->pipes[2]); } /** * Writes to the input stream of the opened process. * * @codeCoverageIgnore */ protected function writeProcessInput(string $string): void { fwrite($this->pipes[0], $string); } /** * @inheritDoc */ public function close(): void { if (\is_resource($this->process)) { foreach ($this->pipes as $pipe) { fclose($pipe); } proc_close($this->process); $this->process = null; } } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/ProcessableHandlerInterface.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Processor\ProcessorInterface; use Monolog\LogRecord; /** * Interface to describe loggers that have processors * * @author Jordi Boggiano */ interface ProcessableHandlerInterface { /** * Adds a processor in the stack. * * @phpstan-param ProcessorInterface|(callable(LogRecord): LogRecord) $callback * * @param ProcessorInterface|callable $callback * @return HandlerInterface self */ public function pushProcessor(callable $callback): HandlerInterface; /** * Removes the processor on top of the stack and returns it. * * @phpstan-return ProcessorInterface|(callable(LogRecord): LogRecord) $callback * * @throws \LogicException In case the processor stack is empty * @return callable|ProcessorInterface */ public function popProcessor(): callable; } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/ProcessableHandlerTrait.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\ResettableInterface; use Monolog\Processor\ProcessorInterface; use Monolog\LogRecord; /** * Helper trait for implementing ProcessableInterface * * @author Jordi Boggiano */ trait ProcessableHandlerTrait { /** * @var callable[] * @phpstan-var array<(callable(LogRecord): LogRecord)|ProcessorInterface> */ protected array $processors = []; /** * @inheritDoc */ public function pushProcessor(callable $callback): HandlerInterface { array_unshift($this->processors, $callback); return $this; } /** * @inheritDoc */ public function popProcessor(): callable { if (\count($this->processors) === 0) { throw new \LogicException('You tried to pop from an empty processor stack.'); } return array_shift($this->processors); } protected function processRecord(LogRecord $record): LogRecord { foreach ($this->processors as $processor) { $record = $processor($record); } return $record; } protected function resetProcessors(): void { foreach ($this->processors as $processor) { if ($processor instanceof ResettableInterface) { $processor->reset(); } } } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/PsrHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Level; use Psr\Log\LoggerInterface; use Monolog\Formatter\FormatterInterface; use Monolog\LogRecord; /** * Proxies log messages to an existing PSR-3 compliant logger. * * If a formatter is configured, the formatter's output MUST be a string and the * formatted message will be fed to the wrapped PSR logger instead of the original * log record's message. * * @author Michael Moussa */ class PsrHandler extends AbstractHandler implements FormattableHandlerInterface { /** * PSR-3 compliant logger */ protected LoggerInterface $logger; protected FormatterInterface|null $formatter = null; private bool $includeExtra; /** * @param LoggerInterface $logger The underlying PSR-3 compliant logger to which messages will be proxied */ public function __construct(LoggerInterface $logger, int|string|Level $level = Level::Debug, bool $bubble = true, bool $includeExtra = false) { parent::__construct($level, $bubble); $this->logger = $logger; $this->includeExtra = $includeExtra; } /** * @inheritDoc */ public function handle(LogRecord $record): bool { if (!$this->isHandling($record)) { return false; } $message = $this->formatter !== null ? (string) $this->formatter->format($record) : $record->message; $context = $this->includeExtra ? [...$record->extra, ...$record->context] : $record->context; $this->logger->log($record->level->toPsrLogLevel(), $message, $context); return false === $this->bubble; } /** * Sets the formatter. */ public function setFormatter(FormatterInterface $formatter): HandlerInterface { $this->formatter = $formatter; return $this; } /** * Gets the formatter. */ public function getFormatter(): FormatterInterface { if ($this->formatter === null) { throw new \LogicException('No formatter has been set and this handler does not have a default formatter'); } return $this->formatter; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/PushoverHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Level; use Monolog\Logger; use Monolog\Utils; use Psr\Log\LogLevel; use Monolog\LogRecord; /** * Sends notifications through the pushover api to mobile phones * * @author Sebastian Göttschkes * @see https://www.pushover.net/api */ class PushoverHandler extends SocketHandler { private string $token; /** @var array */ private array $users; private string $title; private string|int|null $user = null; private int $retry; private int $expire; private Level $highPriorityLevel; private Level $emergencyLevel; private bool $useFormattedMessage = false; /** * All parameters that can be sent to Pushover * @see https://pushover.net/api * @var array */ private array $parameterNames = [ 'token' => true, 'user' => true, 'message' => true, 'device' => true, 'title' => true, 'url' => true, 'url_title' => true, 'priority' => true, 'timestamp' => true, 'sound' => true, 'retry' => true, 'expire' => true, 'callback' => true, ]; /** * Sounds the api supports by default * @see https://pushover.net/api#sounds * @var string[] */ private array $sounds = [ 'pushover', 'bike', 'bugle', 'cashregister', 'classical', 'cosmic', 'falling', 'gamelan', 'incoming', 'intermission', 'magic', 'mechanical', 'pianobar', 'siren', 'spacealarm', 'tugboat', 'alien', 'climb', 'persistent', 'echo', 'updown', 'none', ]; /** * @param string $token Pushover api token * @param string|array $users Pushover user id or array of ids the message will be sent to * @param string|null $title Title sent to the Pushover API * @param bool $useSSL Whether to connect via SSL. Required when pushing messages to users that are not * the pushover.net app owner. OpenSSL is required for this option. * @param int $retry The retry parameter specifies how often (in seconds) the Pushover servers will * send the same notification to the user. * @param int $expire The expire parameter specifies how many seconds your notification will continue * to be retried for (every retry seconds). * * @param int|string|Level|LogLevel::* $highPriorityLevel The minimum logging level at which this handler will start * sending "high priority" requests to the Pushover API * @param int|string|Level|LogLevel::* $emergencyLevel The minimum logging level at which this handler will start * sending "emergency" requests to the Pushover API * * * @phpstan-param string|array $users * @phpstan-param value-of|value-of|Level|LogLevel::* $highPriorityLevel * @phpstan-param value-of|value-of|Level|LogLevel::* $emergencyLevel */ public function __construct( string $token, $users, ?string $title = null, int|string|Level $level = Level::Critical, bool $bubble = true, bool $useSSL = true, int|string|Level $highPriorityLevel = Level::Critical, int|string|Level $emergencyLevel = Level::Emergency, int $retry = 30, int $expire = 25200, bool $persistent = false, float $timeout = 0.0, float $writingTimeout = 10.0, ?float $connectionTimeout = null, ?int $chunkSize = null ) { $connectionString = $useSSL ? 'ssl://api.pushover.net:443' : 'api.pushover.net:80'; parent::__construct( $connectionString, $level, $bubble, $persistent, $timeout, $writingTimeout, $connectionTimeout, $chunkSize ); $this->token = $token; $this->users = (array) $users; $this->title = $title ?? (string) gethostname(); $this->highPriorityLevel = Logger::toMonologLevel($highPriorityLevel); $this->emergencyLevel = Logger::toMonologLevel($emergencyLevel); $this->retry = $retry; $this->expire = $expire; } protected function generateDataStream(LogRecord $record): string { $content = $this->buildContent($record); return $this->buildHeader($content) . $content; } private function buildContent(LogRecord $record): string { // Pushover has a limit of 512 characters on title and message combined. $maxMessageLength = 512 - \strlen($this->title); $message = ($this->useFormattedMessage) ? $record->formatted : $record->message; $message = Utils::substr($message, 0, $maxMessageLength); $timestamp = $record->datetime->getTimestamp(); $dataArray = [ 'token' => $this->token, 'user' => $this->user, 'message' => $message, 'title' => $this->title, 'timestamp' => $timestamp, ]; if ($record->level->value >= $this->emergencyLevel->value) { $dataArray['priority'] = 2; $dataArray['retry'] = $this->retry; $dataArray['expire'] = $this->expire; } elseif ($record->level->value >= $this->highPriorityLevel->value) { $dataArray['priority'] = 1; } // First determine the available parameters $context = array_intersect_key($record->context, $this->parameterNames); $extra = array_intersect_key($record->extra, $this->parameterNames); // Least important info should be merged with subsequent info $dataArray = array_merge($extra, $context, $dataArray); // Only pass sounds that are supported by the API if (isset($dataArray['sound']) && !\in_array($dataArray['sound'], $this->sounds, true)) { unset($dataArray['sound']); } return http_build_query($dataArray); } private function buildHeader(string $content): string { $header = "POST /1/messages.json HTTP/1.1\r\n"; $header .= "Host: api.pushover.net\r\n"; $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; $header .= "Content-Length: " . \strlen($content) . "\r\n"; $header .= "\r\n"; return $header; } protected function write(LogRecord $record): void { foreach ($this->users as $user) { $this->user = $user; parent::write($record); $this->closeSocket(); } $this->user = null; } /** * @param int|string|Level|LogLevel::* $level * @return $this * * @phpstan-param value-of|value-of|Level|LogLevel::* $level */ public function setHighPriorityLevel(int|string|Level $level): self { $this->highPriorityLevel = Logger::toMonologLevel($level); return $this; } /** * @param int|string|Level|LogLevel::* $level * @return $this * * @phpstan-param value-of|value-of|Level|LogLevel::* $level */ public function setEmergencyLevel(int|string|Level $level): self { $this->emergencyLevel = Logger::toMonologLevel($level); return $this; } /** * Use the formatted message? * * @return $this */ public function useFormattedMessage(bool $useFormattedMessage): self { $this->useFormattedMessage = $useFormattedMessage; return $this; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/RedisHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Formatter\LineFormatter; use Monolog\Formatter\FormatterInterface; use Monolog\Level; use Monolog\LogRecord; use Predis\Client as Predis; use Redis; /** * Logs to a Redis key using rpush * * usage example: * * $log = new Logger('application'); * $redis = new RedisHandler(new Predis\Client("tcp://localhost:6379"), "logs"); * $log->pushHandler($redis); * * @author Thomas Tourlourat */ class RedisHandler extends AbstractProcessingHandler { /** @var Predis|Redis */ private Predis|Redis $redisClient; private string $redisKey; protected int $capSize; /** * @param Predis|Redis $redis The redis instance * @param string $key The key name to push records to * @param int $capSize Number of entries to limit list size to, 0 = unlimited */ public function __construct(Predis|Redis $redis, string $key, int|string|Level $level = Level::Debug, bool $bubble = true, int $capSize = 0) { $this->redisClient = $redis; $this->redisKey = $key; $this->capSize = $capSize; parent::__construct($level, $bubble); } /** * @inheritDoc */ protected function write(LogRecord $record): void { if ($this->capSize > 0) { $this->writeCapped($record); } else { $this->redisClient->rpush($this->redisKey, $record->formatted); } } /** * Write and cap the collection * Writes the record to the redis list and caps its */ protected function writeCapped(LogRecord $record): void { if ($this->redisClient instanceof Redis) { $mode = \defined('Redis::MULTI') ? Redis::MULTI : 1; $this->redisClient->multi($mode) ->rPush($this->redisKey, $record->formatted) ->ltrim($this->redisKey, -$this->capSize, -1) ->exec(); } else { $redisKey = $this->redisKey; $capSize = $this->capSize; $this->redisClient->transaction(function ($tx) use ($record, $redisKey, $capSize) { $tx->rpush($redisKey, $record->formatted); $tx->ltrim($redisKey, -$capSize, -1); }); } } /** * @inheritDoc */ protected function getDefaultFormatter(): FormatterInterface { return new LineFormatter(); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/RedisPubSubHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Formatter\LineFormatter; use Monolog\Formatter\FormatterInterface; use Monolog\Level; use Monolog\LogRecord; use Predis\Client as Predis; use Redis; /** * Sends the message to a Redis Pub/Sub channel using PUBLISH * * usage example: * * $log = new Logger('application'); * $redis = new RedisPubSubHandler(new Predis\Client("tcp://localhost:6379"), "logs", Level::Warning); * $log->pushHandler($redis); * * @author Gaëtan Faugère */ class RedisPubSubHandler extends AbstractProcessingHandler { /** @var Predis|Redis */ private Predis|Redis $redisClient; private string $channelKey; /** * @param Predis|Redis $redis The redis instance * @param string $key The channel key to publish records to */ public function __construct(Predis|Redis $redis, string $key, int|string|Level $level = Level::Debug, bool $bubble = true) { $this->redisClient = $redis; $this->channelKey = $key; parent::__construct($level, $bubble); } /** * @inheritDoc */ protected function write(LogRecord $record): void { $this->redisClient->publish($this->channelKey, $record->formatted); } /** * @inheritDoc */ protected function getDefaultFormatter(): FormatterInterface { return new LineFormatter(); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/RollbarHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Level; use Rollbar\RollbarLogger; use Throwable; use Monolog\LogRecord; /** * Sends errors to Rollbar * * If the context data contains a `payload` key, that is used as an array * of payload options to RollbarLogger's log method. * * Rollbar's context info will contain the context + extra keys from the log record * merged, and then on top of that a few keys: * * - level (rollbar level name) * - monolog_level (monolog level name, raw level, as rollbar only has 5 but monolog 8) * - channel * - datetime (unix timestamp) * * @author Paul Statezny */ class RollbarHandler extends AbstractProcessingHandler { protected RollbarLogger $rollbarLogger; /** * Records whether any log records have been added since the last flush of the rollbar notifier */ private bool $hasRecords = false; protected bool $initialized = false; /** * @param RollbarLogger $rollbarLogger RollbarLogger object constructed with valid token */ public function __construct(RollbarLogger $rollbarLogger, int|string|Level $level = Level::Error, bool $bubble = true) { $this->rollbarLogger = $rollbarLogger; parent::__construct($level, $bubble); } /** * Translates Monolog log levels to Rollbar levels. * * @return 'debug'|'info'|'warning'|'error'|'critical' */ protected function toRollbarLevel(Level $level): string { return match ($level) { Level::Debug => 'debug', Level::Info => 'info', Level::Notice => 'info', Level::Warning => 'warning', Level::Error => 'error', Level::Critical => 'critical', Level::Alert => 'critical', Level::Emergency => 'critical', }; } /** * @inheritDoc */ protected function write(LogRecord $record): void { if (!$this->initialized) { // __destructor() doesn't get called on Fatal errors register_shutdown_function([$this, 'close']); $this->initialized = true; } $context = $record->context; $context = array_merge($context, $record->extra, [ 'level' => $this->toRollbarLevel($record->level), 'monolog_level' => $record->level->getName(), 'channel' => $record->channel, 'datetime' => $record->datetime->format('U'), ]); if (isset($context['exception']) && $context['exception'] instanceof Throwable) { $exception = $context['exception']; unset($context['exception']); $toLog = $exception; } else { $toLog = $record->message; } $this->rollbarLogger->log($context['level'], $toLog, $context); $this->hasRecords = true; } public function flush(): void { if ($this->hasRecords) { $this->rollbarLogger->flush(); $this->hasRecords = false; } } /** * @inheritDoc */ public function close(): void { $this->flush(); } /** * @inheritDoc */ public function reset(): void { $this->flush(); parent::reset(); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/RotatingFileHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use DateTimeZone; use InvalidArgumentException; use Monolog\Level; use Monolog\Utils; use Monolog\LogRecord; /** * Stores logs to files that are rotated every day and a limited number of files are kept. * * This rotation is only intended to be used as a workaround. Using logrotate to * handle the rotation is strongly encouraged when you can use it. * * @author Christophe Coevoet * @author Jordi Boggiano */ class RotatingFileHandler extends StreamHandler { public const FILE_PER_DAY = 'Y-m-d'; public const FILE_PER_MONTH = 'Y-m'; public const FILE_PER_YEAR = 'Y'; protected string $filename; protected int $maxFiles; protected bool|null $mustRotate = null; protected \DateTimeImmutable $nextRotation; protected string $filenameFormat; protected string $dateFormat; protected DateTimeZone|null $timezone = null; /** * @param int $maxFiles The maximal amount of files to keep (0 means unlimited) * @param int|null $filePermission Optional file permissions (default (0644) are only for owner read/write) * @param bool $useLocking Try to lock log file before doing any writes */ public function __construct(string $filename, int $maxFiles = 0, int|string|Level $level = Level::Debug, bool $bubble = true, ?int $filePermission = null, bool $useLocking = false, string $dateFormat = self::FILE_PER_DAY, string $filenameFormat = '{filename}-{date}', DateTimeZone|null $timezone = null) { $this->filename = Utils::canonicalizePath($filename); $this->maxFiles = $maxFiles; $this->setFilenameFormat($filenameFormat, $dateFormat); $this->nextRotation = $this->getNextRotation(); $this->timezone = $timezone; parent::__construct($this->getTimedFilename(), $level, $bubble, $filePermission, $useLocking); } /** * @inheritDoc */ public function close(): void { parent::close(); if (true === $this->mustRotate) { $this->rotate(); } } /** * @inheritDoc */ public function reset(): void { parent::reset(); } /** * @return $this */ public function setFilenameFormat(string $filenameFormat, string $dateFormat): self { $this->setDateFormat($dateFormat); if (substr_count($filenameFormat, '{date}') === 0) { throw new InvalidArgumentException( 'Invalid filename format - format must contain at least `{date}`, because otherwise rotating is impossible.' ); } $this->filenameFormat = $filenameFormat; $this->url = $this->getTimedFilename(); $this->close(); return $this; } /** * @inheritDoc */ protected function write(LogRecord $record): void { // on the first record written, if the log is new, we rotate (once per day) after the log has been written so that the new file exists if (null === $this->mustRotate) { $this->mustRotate = null === $this->url || !file_exists($this->url); } // if the next rotation is expired, then we rotate immediately if ($this->nextRotation <= $record->datetime) { $this->mustRotate = true; $this->close(); // triggers rotation } parent::write($record); if (true === $this->mustRotate) { $this->close(); // triggers rotation } } /** * Rotates the files. */ protected function rotate(): void { // update filename $this->url = $this->getTimedFilename(); $this->nextRotation = $this->getNextRotation(); $this->mustRotate = false; // skip GC of old logs if files are unlimited if (0 === $this->maxFiles) { return; } $logFiles = glob($this->getGlobPattern()); if (false === $logFiles) { // failed to glob return; } if ($this->maxFiles >= \count($logFiles)) { // no files to remove return; } // Sorting the files by name to remove the older ones usort($logFiles, function ($a, $b) { return strcmp($b, $a); }); $basePath = dirname($this->filename); foreach (\array_slice($logFiles, $this->maxFiles) as $file) { if (is_writable($file)) { // suppress errors here as unlink() might fail if two processes // are cleaning up/rotating at the same time set_error_handler(function (int $errno, string $errstr, string $errfile, int $errline): bool { return true; }); unlink($file); $dir = dirname($file); while ($dir !== $basePath) { $entries = scandir($dir); if ($entries === false || \count(array_diff($entries, ['.', '..'])) > 0) { break; } rmdir($dir); $dir = dirname($dir); } restore_error_handler(); } } } protected function getTimedFilename(): string { $fileInfo = pathinfo($this->filename); $timedFilename = str_replace( ['{filename}', '{date}'], [$fileInfo['filename'], (new \DateTimeImmutable(timezone: $this->timezone))->format($this->dateFormat)], ($fileInfo['dirname'] ?? '') . '/' . $this->filenameFormat ); if (isset($fileInfo['extension'])) { $timedFilename .= '.'.$fileInfo['extension']; } return $timedFilename; } protected function getGlobPattern(): string { $fileInfo = pathinfo($this->filename); $glob = str_replace( ['{filename}', '{date}'], [$fileInfo['filename'], str_replace( ['Y', 'y', 'm', 'd'], ['[0-9][0-9][0-9][0-9]', '[0-9][0-9]', '[0-9][0-9]', '[0-9][0-9]'], $this->dateFormat )], ($fileInfo['dirname'] ?? '') . '/' . $this->filenameFormat ); if (isset($fileInfo['extension'])) { $glob .= '.'.$fileInfo['extension']; } return $glob; } protected function setDateFormat(string $dateFormat): void { if (0 === preg_match('{^[Yy](([/_.-]?m)([/_.-]?d)?)?$}', $dateFormat)) { throw new InvalidArgumentException( 'Invalid date format - format must be one of '. 'RotatingFileHandler::FILE_PER_DAY ("Y-m-d"), RotatingFileHandler::FILE_PER_MONTH ("Y-m") '. 'or RotatingFileHandler::FILE_PER_YEAR ("Y"), or you can set one of the '. 'date formats using slashes, underscores and/or dots instead of dashes.' ); } $this->dateFormat = $dateFormat; } protected function getNextRotation(): \DateTimeImmutable { return match (str_replace(['/','_','.'], '-', $this->dateFormat)) { self::FILE_PER_MONTH => (new \DateTimeImmutable('first day of next month'))->setTime(0, 0, 0), self::FILE_PER_YEAR => (new \DateTimeImmutable('first day of January next year'))->setTime(0, 0, 0), default => (new \DateTimeImmutable('tomorrow'))->setTime(0, 0, 0), }; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/SamplingHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Closure; use Monolog\Formatter\FormatterInterface; use Monolog\LogRecord; /** * Sampling handler * * A sampled event stream can be useful for logging high frequency events in * a production environment where you only need an idea of what is happening * and are not concerned with capturing every occurrence. Since the decision to * handle or not handle a particular event is determined randomly, the * resulting sampled log is not guaranteed to contain 1/N of the events that * occurred in the application, but based on the Law of large numbers, it will * tend to be close to this ratio with a large number of attempts. * * @author Bryan Davis * @author Kunal Mehta */ class SamplingHandler extends AbstractHandler implements ProcessableHandlerInterface, FormattableHandlerInterface { use ProcessableHandlerTrait; /** * Handler or factory Closure($record, $this) * * @phpstan-var (Closure(LogRecord|null, HandlerInterface): HandlerInterface)|HandlerInterface */ protected Closure|HandlerInterface $handler; protected int $factor; /** * @phpstan-param (Closure(LogRecord|null, HandlerInterface): HandlerInterface)|HandlerInterface $handler * * @param Closure|HandlerInterface $handler Handler or factory Closure($record|null, $samplingHandler). * @param int $factor Sample factor (e.g. 10 means every ~10th record is sampled) */ public function __construct(Closure|HandlerInterface $handler, int $factor) { parent::__construct(); $this->handler = $handler; $this->factor = $factor; } public function isHandling(LogRecord $record): bool { return $this->getHandler($record)->isHandling($record); } public function handle(LogRecord $record): bool { if ($this->isHandling($record) && mt_rand(1, $this->factor) === 1) { if (\count($this->processors) > 0) { $record = $this->processRecord($record); } $this->getHandler($record)->handle($record); } return false === $this->bubble; } /** * Return the nested handler * * If the handler was provided as a factory, this will trigger the handler's instantiation. */ public function getHandler(LogRecord|null $record = null): HandlerInterface { if (!$this->handler instanceof HandlerInterface) { $handler = ($this->handler)($record, $this); if (!$handler instanceof HandlerInterface) { throw new \RuntimeException("The factory Closure should return a HandlerInterface"); } $this->handler = $handler; } return $this->handler; } /** * @inheritDoc */ public function setFormatter(FormatterInterface $formatter): HandlerInterface { $handler = $this->getHandler(); if ($handler instanceof FormattableHandlerInterface) { $handler->setFormatter($formatter); return $this; } throw new \UnexpectedValueException('The nested handler of type '.\get_class($handler).' does not support formatters.'); } /** * @inheritDoc */ public function getFormatter(): FormatterInterface { $handler = $this->getHandler(); if ($handler instanceof FormattableHandlerInterface) { return $handler->getFormatter(); } throw new \UnexpectedValueException('The nested handler of type '.\get_class($handler).' does not support formatters.'); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/SendGridHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Level; use Monolog\Utils; /** * SendGridHandler uses the SendGrid API v3 function to send Log emails, more information in https://www.twilio.com/docs/sendgrid/for-developers/sending-email/api-getting-started * * @author Ricardo Fontanelli */ class SendGridHandler extends MailHandler { /** * The SendGrid API User * @deprecated this is not used anymore as of SendGrid API v3 */ protected string $apiUser; /** * The email addresses to which the message will be sent * @var string[] */ protected array $to; /** * @param string|null $apiUser Unused user as of SendGrid API v3, you can pass null or any string * @param list|string $to * @param non-empty-string $apiHost Allows you to use another endpoint (e.g. api.eu.sendgrid.com) * @throws MissingExtensionException If the curl extension is missing */ public function __construct( string|null $apiUser, protected string $apiKey, protected string $from, array|string $to, protected string $subject, int|string|Level $level = Level::Error, bool $bubble = true, /** @var non-empty-string */ private readonly string $apiHost = 'api.sendgrid.com', ) { if (!\extension_loaded('curl')) { throw new MissingExtensionException('The curl extension is needed to use the SendGridHandler'); } $this->to = (array) $to; // @phpstan-ignore property.deprecated $this->apiUser = $apiUser ?? ''; parent::__construct($level, $bubble); } protected function send(string $content, array $records): void { $body = []; $body['personalizations'] = []; $body['from']['email'] = $this->from; foreach ($this->to as $recipient) { $body['personalizations'][]['to'][]['email'] = $recipient; } $body['subject'] = $this->subject; if ($this->isHtmlBody($content)) { $body['content'][] = [ 'type' => 'text/html', 'value' => $content, ]; } else { $body['content'][] = [ 'type' => 'text/plain', 'value' => $content, ]; } $ch = curl_init(); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Content-Type: application/json', 'Authorization: Bearer '.$this->apiKey, ]); curl_setopt($ch, CURLOPT_URL, 'https://'.$this->apiHost.'/v3/mail/send'); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POSTFIELDS, Utils::jsonEncode($body)); Curl\Util::execute($ch, 2); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/Slack/SlackRecord.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler\Slack; use Monolog\Level; use Monolog\Utils; use Monolog\Formatter\NormalizerFormatter; use Monolog\Formatter\FormatterInterface; use Monolog\LogRecord; /** * Slack record utility helping to log to Slack webhooks or API. * * @author Greg Kedzierski * @author Haralan Dobrev * @see https://api.slack.com/incoming-webhooks * @see https://api.slack.com/docs/message-attachments */ class SlackRecord { public const COLOR_DANGER = 'danger'; public const COLOR_WARNING = 'warning'; public const COLOR_GOOD = 'good'; public const COLOR_DEFAULT = '#e3e4e6'; /** * Slack channel (encoded ID or name) */ private string|null $channel; /** * Name of a bot */ private string|null $username; /** * User icon e.g. 'ghost', 'http://example.com/user.png' */ private string|null $userIcon; /** * Whether the message should be added to Slack as attachment (plain text otherwise) */ private bool $useAttachment; /** * Whether the the context/extra messages added to Slack as attachments are in a short style */ private bool $useShortAttachment; /** * Whether the attachment should include context and extra data */ private bool $includeContextAndExtra; /** * Dot separated list of fields to exclude from slack message. E.g. ['context.field1', 'extra.field2'] * @var string[] */ private array $excludeFields; private FormatterInterface|null $formatter; private NormalizerFormatter $normalizerFormatter; /** * @param string[] $excludeFields */ public function __construct( ?string $channel = null, ?string $username = null, bool $useAttachment = true, ?string $userIcon = null, bool $useShortAttachment = false, bool $includeContextAndExtra = false, array $excludeFields = [], FormatterInterface|null $formatter = null ) { $this ->setChannel($channel) ->setUsername($username) ->useAttachment($useAttachment) ->setUserIcon($userIcon) ->useShortAttachment($useShortAttachment) ->includeContextAndExtra($includeContextAndExtra) ->excludeFields($excludeFields) ->setFormatter($formatter); if ($this->includeContextAndExtra) { $this->normalizerFormatter = new NormalizerFormatter(); } } /** * Returns required data in format that Slack * is expecting. * * @phpstan-return mixed[] */ public function getSlackData(LogRecord $record): array { $dataArray = []; if ($this->username !== null) { $dataArray['username'] = $this->username; } if ($this->channel !== null) { $dataArray['channel'] = $this->channel; } if ($this->formatter !== null && !$this->useAttachment) { $message = $this->formatter->format($record); } else { $message = $record->message; } $recordData = $this->removeExcludedFields($record); if ($this->useAttachment) { $attachment = [ 'fallback' => $message, 'text' => $message, 'color' => $this->getAttachmentColor($record->level), 'fields' => [], 'mrkdwn_in' => ['fields'], 'ts' => $recordData['datetime']->getTimestamp(), 'footer' => $this->username, 'footer_icon' => $this->userIcon, ]; if ($this->useShortAttachment) { $attachment['title'] = $recordData['level_name']; } else { $attachment['title'] = 'Message'; $attachment['fields'][] = $this->generateAttachmentField('Level', $recordData['level_name']); } if ($this->includeContextAndExtra) { foreach (['extra', 'context'] as $key) { if (!isset($recordData[$key]) || \count($recordData[$key]) === 0) { continue; } if ($this->useShortAttachment) { $attachment['fields'][] = $this->generateAttachmentField( $key, $recordData[$key] ); } else { // Add all extra fields as individual fields in attachment $attachment['fields'] = array_merge( $attachment['fields'], $this->generateAttachmentFields($recordData[$key]) ); } } } $dataArray['attachments'] = [$attachment]; } else { $dataArray['text'] = $message; } if ($this->userIcon !== null) { if (false !== ($iconUrl = filter_var($this->userIcon, FILTER_VALIDATE_URL))) { $dataArray['icon_url'] = $iconUrl; } else { $dataArray['icon_emoji'] = ":{$this->userIcon}:"; } } return $dataArray; } /** * Returns a Slack message attachment color associated with * provided level. */ public function getAttachmentColor(Level $level): string { return match ($level) { Level::Error, Level::Critical, Level::Alert, Level::Emergency => static::COLOR_DANGER, Level::Warning => static::COLOR_WARNING, Level::Info, Level::Notice => static::COLOR_GOOD, Level::Debug => static::COLOR_DEFAULT }; } /** * Stringifies an array of key/value pairs to be used in attachment fields * * @param mixed[] $fields */ public function stringify(array $fields): string { /** @var array|bool|float|int|string|null> $normalized */ $normalized = $this->normalizerFormatter->normalizeValue($fields); $hasSecondDimension = \count(array_filter($normalized, 'is_array')) > 0; $hasOnlyNonNumericKeys = \count(array_filter(array_keys($normalized), 'is_numeric')) === 0; return $hasSecondDimension || $hasOnlyNonNumericKeys ? Utils::jsonEncode($normalized, JSON_PRETTY_PRINT|Utils::DEFAULT_JSON_FLAGS) : Utils::jsonEncode($normalized, Utils::DEFAULT_JSON_FLAGS); } /** * Channel used by the bot when posting * * @param ?string $channel * @return $this */ public function setChannel(?string $channel = null): self { $this->channel = $channel; return $this; } /** * Username used by the bot when posting * * @param ?string $username * @return $this */ public function setUsername(?string $username = null): self { $this->username = $username; return $this; } /** * @return $this */ public function useAttachment(bool $useAttachment = true): self { $this->useAttachment = $useAttachment; return $this; } /** * @return $this */ public function setUserIcon(?string $userIcon = null): self { $this->userIcon = $userIcon; if (\is_string($userIcon)) { $this->userIcon = trim($userIcon, ':'); } return $this; } /** * @return $this */ public function useShortAttachment(bool $useShortAttachment = false): self { $this->useShortAttachment = $useShortAttachment; return $this; } /** * @return $this */ public function includeContextAndExtra(bool $includeContextAndExtra = false): self { $this->includeContextAndExtra = $includeContextAndExtra; if ($this->includeContextAndExtra) { $this->normalizerFormatter = new NormalizerFormatter(); } return $this; } /** * @param string[] $excludeFields * @return $this */ public function excludeFields(array $excludeFields = []): self { $this->excludeFields = $excludeFields; return $this; } /** * @return $this */ public function setFormatter(?FormatterInterface $formatter = null): self { $this->formatter = $formatter; return $this; } /** * Generates attachment field * * @param string|mixed[] $value * * @return array{title: string, value: string, short: false} */ private function generateAttachmentField(string $title, $value): array { $value = \is_array($value) ? sprintf('```%s```', substr($this->stringify($value), 0, 1990)) : $value; return [ 'title' => ucfirst($title), 'value' => $value, 'short' => false, ]; } /** * Generates a collection of attachment fields from array * * @param mixed[] $data * * @return array */ private function generateAttachmentFields(array $data): array { /** @var array|string> $normalized */ $normalized = $this->normalizerFormatter->normalizeValue($data); $fields = []; foreach ($normalized as $key => $value) { $fields[] = $this->generateAttachmentField((string) $key, $value); } return $fields; } /** * Get a copy of record with fields excluded according to $this->excludeFields * * @return mixed[] */ private function removeExcludedFields(LogRecord $record): array { $recordData = $record->toArray(); foreach ($this->excludeFields as $field) { $keys = explode('.', $field); $node = &$recordData; $lastKey = end($keys); foreach ($keys as $key) { if (!isset($node[$key])) { break; } if ($lastKey === $key) { unset($node[$key]); break; } $node = &$node[$key]; } } return $recordData; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/SlackHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Formatter\FormatterInterface; use Monolog\Level; use Monolog\Utils; use Monolog\Handler\Slack\SlackRecord; use Monolog\LogRecord; /** * Sends notifications through Slack API * * @author Greg Kedzierski * @see https://api.slack.com/ */ class SlackHandler extends SocketHandler { /** * Slack API token */ private string $token; /** * Instance of the SlackRecord util class preparing data for Slack API. */ private SlackRecord $slackRecord; /** * @param string $token Slack API token * @param string $channel Slack channel (encoded ID or name) * @param string|null $username Name of a bot * @param bool $useAttachment Whether the message should be added to Slack as attachment (plain text otherwise) * @param string|null $iconEmoji The emoji name to use (or null) * @param bool $useShortAttachment Whether the context/extra messages added to Slack as attachments are in a short style * @param bool $includeContextAndExtra Whether the attachment should include context and extra data * @param string[] $excludeFields Dot separated list of fields to exclude from slack message. E.g. ['context.field1', 'extra.field2'] * @throws MissingExtensionException If no OpenSSL PHP extension configured */ public function __construct( string $token, string $channel, ?string $username = null, bool $useAttachment = true, ?string $iconEmoji = null, $level = Level::Critical, bool $bubble = true, bool $useShortAttachment = false, bool $includeContextAndExtra = false, array $excludeFields = [], bool $persistent = false, float $timeout = 0.0, float $writingTimeout = 10.0, ?float $connectionTimeout = null, ?int $chunkSize = null ) { if (!\extension_loaded('openssl')) { throw new MissingExtensionException('The OpenSSL PHP extension is required to use the SlackHandler'); } parent::__construct( 'ssl://slack.com:443', $level, $bubble, $persistent, $timeout, $writingTimeout, $connectionTimeout, $chunkSize ); $this->slackRecord = new SlackRecord( $channel, $username, $useAttachment, $iconEmoji, $useShortAttachment, $includeContextAndExtra, $excludeFields ); $this->token = $token; } public function getSlackRecord(): SlackRecord { return $this->slackRecord; } public function getToken(): string { return $this->token; } /** * @inheritDoc */ protected function generateDataStream(LogRecord $record): string { $content = $this->buildContent($record); return $this->buildHeader($content) . $content; } /** * Builds the body of API call */ private function buildContent(LogRecord $record): string { $dataArray = $this->prepareContentData($record); return http_build_query($dataArray); } /** * @return string[] */ protected function prepareContentData(LogRecord $record): array { $dataArray = $this->slackRecord->getSlackData($record); $dataArray['token'] = $this->token; if (isset($dataArray['attachments']) && \is_array($dataArray['attachments']) && \count($dataArray['attachments']) > 0) { $dataArray['attachments'] = Utils::jsonEncode($dataArray['attachments']); } return $dataArray; } /** * Builds the header of the API Call */ private function buildHeader(string $content): string { $header = "POST /api/chat.postMessage HTTP/1.1\r\n"; $header .= "Host: slack.com\r\n"; $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; $header .= "Content-Length: " . \strlen($content) . "\r\n"; $header .= "\r\n"; return $header; } /** * @inheritDoc */ protected function write(LogRecord $record): void { parent::write($record); $this->finalizeWrite(); } /** * Finalizes the request by reading some bytes and then closing the socket * * If we do not read some but close the socket too early, slack sometimes * drops the request entirely. */ protected function finalizeWrite(): void { $res = $this->getResource(); if (\is_resource($res)) { @fread($res, 2048); } $this->closeSocket(); } public function setFormatter(FormatterInterface $formatter): HandlerInterface { parent::setFormatter($formatter); $this->slackRecord->setFormatter($formatter); return $this; } public function getFormatter(): FormatterInterface { $formatter = parent::getFormatter(); $this->slackRecord->setFormatter($formatter); return $formatter; } /** * Channel used by the bot when posting * * @return $this */ public function setChannel(string $channel): self { $this->slackRecord->setChannel($channel); return $this; } /** * Username used by the bot when posting * * @return $this */ public function setUsername(string $username): self { $this->slackRecord->setUsername($username); return $this; } /** * @return $this */ public function useAttachment(bool $useAttachment): self { $this->slackRecord->useAttachment($useAttachment); return $this; } /** * @return $this */ public function setIconEmoji(string $iconEmoji): self { $this->slackRecord->setUserIcon($iconEmoji); return $this; } /** * @return $this */ public function useShortAttachment(bool $useShortAttachment): self { $this->slackRecord->useShortAttachment($useShortAttachment); return $this; } /** * @return $this */ public function includeContextAndExtra(bool $includeContextAndExtra): self { $this->slackRecord->includeContextAndExtra($includeContextAndExtra); return $this; } /** * @param string[] $excludeFields * @return $this */ public function excludeFields(array $excludeFields): self { $this->slackRecord->excludeFields($excludeFields); return $this; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/SlackWebhookHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Formatter\FormatterInterface; use Monolog\Level; use Monolog\Utils; use Monolog\Handler\Slack\SlackRecord; use Monolog\LogRecord; /** * Sends notifications through Slack Webhooks * * @author Haralan Dobrev * @see https://api.slack.com/incoming-webhooks */ class SlackWebhookHandler extends AbstractProcessingHandler { /** * Slack Webhook token * * @var non-empty-string */ private string $webhookUrl; /** * Instance of the SlackRecord util class preparing data for Slack API. */ private SlackRecord $slackRecord; /** * @param non-empty-string $webhookUrl Slack Webhook URL * @param string|null $channel Slack channel (encoded ID or name) * @param string|null $username Name of a bot * @param bool $useAttachment Whether the message should be added to Slack as attachment (plain text otherwise) * @param string|null $iconEmoji The emoji name to use (or null) * @param bool $useShortAttachment Whether the the context/extra messages added to Slack as attachments are in a short style * @param bool $includeContextAndExtra Whether the attachment should include context and extra data * @param string[] $excludeFields Dot separated list of fields to exclude from slack message. E.g. ['context.field1', 'extra.field2'] * * @throws MissingExtensionException If the curl extension is missing */ public function __construct( string $webhookUrl, ?string $channel = null, ?string $username = null, bool $useAttachment = true, ?string $iconEmoji = null, bool $useShortAttachment = false, bool $includeContextAndExtra = false, $level = Level::Critical, bool $bubble = true, array $excludeFields = [] ) { if (!\extension_loaded('curl')) { throw new MissingExtensionException('The curl extension is needed to use the SlackWebhookHandler'); } parent::__construct($level, $bubble); $this->webhookUrl = $webhookUrl; $this->slackRecord = new SlackRecord( $channel, $username, $useAttachment, $iconEmoji, $useShortAttachment, $includeContextAndExtra, $excludeFields ); } public function getSlackRecord(): SlackRecord { return $this->slackRecord; } public function getWebhookUrl(): string { return $this->webhookUrl; } /** * @inheritDoc */ protected function write(LogRecord $record): void { $postData = $this->slackRecord->getSlackData($record); $postString = Utils::jsonEncode($postData); $ch = curl_init(); $options = [ CURLOPT_URL => $this->webhookUrl, CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ['Content-type: application/json'], CURLOPT_POSTFIELDS => $postString, ]; curl_setopt_array($ch, $options); Curl\Util::execute($ch); } public function setFormatter(FormatterInterface $formatter): HandlerInterface { parent::setFormatter($formatter); $this->slackRecord->setFormatter($formatter); return $this; } public function getFormatter(): FormatterInterface { $formatter = parent::getFormatter(); $this->slackRecord->setFormatter($formatter); return $formatter; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/SocketHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Level; use Monolog\LogRecord; /** * Stores to any socket - uses fsockopen() or pfsockopen(). * * @author Pablo de Leon Belloc * @see http://php.net/manual/en/function.fsockopen.php */ class SocketHandler extends AbstractProcessingHandler { private string $connectionString; private float $connectionTimeout; /** @var resource|null */ private $resource; private float $timeout; private float $writingTimeout; private int|null $lastSentBytes = null; private int|null $chunkSize; private bool $persistent; private int|null $errno = null; private string|null $errstr = null; private float|null $lastWritingAt = null; /** * @param string $connectionString Socket connection string * @param bool $persistent Flag to enable/disable persistent connections * @param float $timeout Socket timeout to wait until the request is being aborted * @param float $writingTimeout Socket timeout to wait until the request should've been sent/written * @param float|null $connectionTimeout Socket connect timeout to wait until the connection should've been * established * @param int|null $chunkSize Sets the chunk size. Only has effect during connection in the writing cycle * * @throws \InvalidArgumentException If an invalid timeout value (less than 0) is passed. */ public function __construct( string $connectionString, $level = Level::Debug, bool $bubble = true, bool $persistent = false, float $timeout = 0.0, float $writingTimeout = 10.0, ?float $connectionTimeout = null, ?int $chunkSize = null ) { parent::__construct($level, $bubble); $this->connectionString = $connectionString; if ($connectionTimeout !== null) { $this->validateTimeout($connectionTimeout); } $this->connectionTimeout = $connectionTimeout ?? (float) \ini_get('default_socket_timeout'); $this->persistent = $persistent; $this->validateTimeout($timeout); $this->timeout = $timeout; $this->validateTimeout($writingTimeout); $this->writingTimeout = $writingTimeout; $this->chunkSize = $chunkSize; } /** * Connect (if necessary) and write to the socket * * @inheritDoc * * @throws \UnexpectedValueException * @throws \RuntimeException */ protected function write(LogRecord $record): void { $this->connectIfNotConnected(); $data = $this->generateDataStream($record); $this->writeToSocket($data); } /** * We will not close a PersistentSocket instance so it can be reused in other requests. */ public function close(): void { if (!$this->isPersistent()) { $this->closeSocket(); } } /** * Close socket, if open */ public function closeSocket(): void { if (\is_resource($this->resource)) { fclose($this->resource); $this->resource = null; } } /** * Set socket connection to be persistent. It only has effect before the connection is initiated. * * @return $this */ public function setPersistent(bool $persistent): self { $this->persistent = $persistent; return $this; } /** * Set connection timeout. Only has effect before we connect. * * @see http://php.net/manual/en/function.fsockopen.php * @return $this */ public function setConnectionTimeout(float $seconds): self { $this->validateTimeout($seconds); $this->connectionTimeout = $seconds; return $this; } /** * Set write timeout. Only has effect before we connect. * * @see http://php.net/manual/en/function.stream-set-timeout.php * @return $this */ public function setTimeout(float $seconds): self { $this->validateTimeout($seconds); $this->timeout = $seconds; return $this; } /** * Set writing timeout. Only has effect during connection in the writing cycle. * * @param float $seconds 0 for no timeout * @return $this */ public function setWritingTimeout(float $seconds): self { $this->validateTimeout($seconds); $this->writingTimeout = $seconds; return $this; } /** * Set chunk size. Only has effect during connection in the writing cycle. * * @return $this */ public function setChunkSize(int $bytes): self { $this->chunkSize = $bytes; return $this; } /** * Get current connection string */ public function getConnectionString(): string { return $this->connectionString; } /** * Get persistent setting */ public function isPersistent(): bool { return $this->persistent; } /** * Get current connection timeout setting */ public function getConnectionTimeout(): float { return $this->connectionTimeout; } /** * Get current in-transfer timeout */ public function getTimeout(): float { return $this->timeout; } /** * Get current local writing timeout */ public function getWritingTimeout(): float { return $this->writingTimeout; } /** * Get current chunk size */ public function getChunkSize(): ?int { return $this->chunkSize; } /** * Check to see if the socket is currently available. * * UDP might appear to be connected but might fail when writing. See http://php.net/fsockopen for details. */ public function isConnected(): bool { return \is_resource($this->resource) && !feof($this->resource); // on TCP - other party can close connection. } /** * Wrapper to allow mocking * * @return resource|false */ protected function pfsockopen() { return @pfsockopen($this->connectionString, -1, $this->errno, $this->errstr, $this->connectionTimeout); } /** * Wrapper to allow mocking * * @return resource|false */ protected function fsockopen() { return @fsockopen($this->connectionString, -1, $this->errno, $this->errstr, $this->connectionTimeout); } /** * Wrapper to allow mocking * * @see http://php.net/manual/en/function.stream-set-timeout.php */ protected function streamSetTimeout(): bool { $seconds = floor($this->timeout); $microseconds = round(($this->timeout - $seconds) * 1e6); if (!\is_resource($this->resource)) { throw new \LogicException('streamSetTimeout called but $this->resource is not a resource'); } return stream_set_timeout($this->resource, (int) $seconds, (int) $microseconds); } /** * Wrapper to allow mocking * * @see http://php.net/manual/en/function.stream-set-chunk-size.php * * @return int|false */ protected function streamSetChunkSize(): int|bool { if (!\is_resource($this->resource)) { throw new \LogicException('streamSetChunkSize called but $this->resource is not a resource'); } if (null === $this->chunkSize) { throw new \LogicException('streamSetChunkSize called but $this->chunkSize is not set'); } return stream_set_chunk_size($this->resource, $this->chunkSize); } /** * Wrapper to allow mocking * * @return int|false */ protected function fwrite(string $data): int|bool { if (!\is_resource($this->resource)) { throw new \LogicException('fwrite called but $this->resource is not a resource'); } return @fwrite($this->resource, $data); } /** * Wrapper to allow mocking * * @return mixed[]|bool */ protected function streamGetMetadata(): array|bool { if (!\is_resource($this->resource)) { throw new \LogicException('streamGetMetadata called but $this->resource is not a resource'); } return stream_get_meta_data($this->resource); } private function validateTimeout(float $value): void { if ($value < 0) { throw new \InvalidArgumentException("Timeout must be 0 or a positive float (got $value)"); } } private function connectIfNotConnected(): void { if ($this->isConnected()) { return; } $this->connect(); } protected function generateDataStream(LogRecord $record): string { return (string) $record->formatted; } /** * @return resource|null */ protected function getResource() { return $this->resource; } private function connect(): void { $this->createSocketResource(); $this->setSocketTimeout(); $this->setStreamChunkSize(); } private function createSocketResource(): void { if ($this->isPersistent()) { $resource = $this->pfsockopen(); } else { $resource = $this->fsockopen(); } if (\is_bool($resource)) { throw new \UnexpectedValueException("Failed connecting to $this->connectionString ($this->errno: $this->errstr)"); } $this->resource = $resource; } private function setSocketTimeout(): void { if (!$this->streamSetTimeout()) { throw new \UnexpectedValueException("Failed setting timeout with stream_set_timeout()"); } } private function setStreamChunkSize(): void { if (null !== $this->chunkSize && false === $this->streamSetChunkSize()) { throw new \UnexpectedValueException("Failed setting chunk size with stream_set_chunk_size()"); } } private function writeToSocket(string $data): void { $length = \strlen($data); $sent = 0; $this->lastSentBytes = $sent; while ($this->isConnected() && $sent < $length) { if (0 === $sent) { $chunk = $this->fwrite($data); } else { $chunk = $this->fwrite(substr($data, $sent)); } if ($chunk === false) { throw new \RuntimeException("Could not write to socket"); } $sent += $chunk; $socketInfo = $this->streamGetMetadata(); if (\is_array($socketInfo) && (bool) $socketInfo['timed_out']) { throw new \RuntimeException("Write timed-out"); } if ($this->writingIsTimedOut($sent)) { throw new \RuntimeException("Write timed-out, no data sent for `{$this->writingTimeout}` seconds, probably we got disconnected (sent $sent of $length)"); } } if (!$this->isConnected() && $sent < $length) { throw new \RuntimeException("End-of-file reached, probably we got disconnected (sent $sent of $length)"); } } private function writingIsTimedOut(int $sent): bool { // convert to ms if (0.0 === $this->writingTimeout) { return false; } if ($sent !== $this->lastSentBytes) { $this->lastWritingAt = microtime(true); $this->lastSentBytes = $sent; return false; } else { usleep(100); } if ((microtime(true) - (float) $this->lastWritingAt) >= $this->writingTimeout) { $this->closeSocket(); return true; } return false; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/SqsHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Aws\Sqs\SqsClient; use Monolog\Level; use Monolog\Utils; use Monolog\LogRecord; /** * Writes to any sqs queue. * * @author Martijn van Calker */ class SqsHandler extends AbstractProcessingHandler { /** 256 KB in bytes - maximum message size in SQS */ protected const MAX_MESSAGE_SIZE = 262144; /** 100 KB in bytes - head message size for new error log */ protected const HEAD_MESSAGE_SIZE = 102400; private SqsClient $client; private string $queueUrl; public function __construct(SqsClient $sqsClient, string $queueUrl, int|string|Level $level = Level::Debug, bool $bubble = true) { parent::__construct($level, $bubble); $this->client = $sqsClient; $this->queueUrl = $queueUrl; } /** * @inheritDoc */ protected function write(LogRecord $record): void { if (!isset($record->formatted) || 'string' !== \gettype($record->formatted)) { throw new \InvalidArgumentException('SqsHandler accepts only formatted records as a string' . Utils::getRecordMessageForException($record)); } $messageBody = $record->formatted; if (\strlen($messageBody) >= static::MAX_MESSAGE_SIZE) { $messageBody = Utils::substr($messageBody, 0, static::HEAD_MESSAGE_SIZE); } $this->client->sendMessage([ 'QueueUrl' => $this->queueUrl, 'MessageBody' => $messageBody, ]); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Level; use Monolog\Utils; use Monolog\LogRecord; /** * Stores to any stream resource * * Can be used to store into php://stderr, remote and local files, etc. * * @author Jordi Boggiano */ class StreamHandler extends AbstractProcessingHandler { protected const MAX_CHUNK_SIZE = 2147483647; /** 10MB */ protected const DEFAULT_CHUNK_SIZE = 10 * 1024 * 1024; protected int $streamChunkSize; /** @var resource|null */ protected $stream; protected string|null $url = null; private string|null $errorMessage = null; protected int|null $filePermission; protected bool $useLocking; protected string $fileOpenMode; /** @var true|null */ private bool|null $dirCreated = null; private bool $retrying = false; private int|null $inodeUrl = null; /** * @param resource|string $stream If a missing path can't be created, an UnexpectedValueException will be thrown on first write * @param int|null $filePermission Optional file permissions (default (0644) are only for owner read/write) * @param bool $useLocking Try to lock log file before doing any writes * @param string $fileOpenMode The fopen() mode used when opening a file, if $stream is a file path * * @throws \InvalidArgumentException If stream is not a resource or string */ public function __construct($stream, int|string|Level $level = Level::Debug, bool $bubble = true, ?int $filePermission = null, bool $useLocking = false, string $fileOpenMode = 'a') { parent::__construct($level, $bubble); if (($phpMemoryLimit = Utils::expandIniShorthandBytes(\ini_get('memory_limit'))) !== false) { if ($phpMemoryLimit > 0) { // use max 10% of allowed memory for the chunk size, and at least 100KB $this->streamChunkSize = min(static::MAX_CHUNK_SIZE, max((int) ($phpMemoryLimit / 10), 100 * 1024)); } else { // memory is unlimited, set to the default 10MB $this->streamChunkSize = static::DEFAULT_CHUNK_SIZE; } } else { // no memory limit information, set to the default 10MB $this->streamChunkSize = static::DEFAULT_CHUNK_SIZE; } if (\is_resource($stream)) { $this->stream = $stream; stream_set_chunk_size($this->stream, $this->streamChunkSize); } elseif (\is_string($stream)) { $this->url = Utils::canonicalizePath($stream); } else { throw new \InvalidArgumentException('A stream must either be a resource or a string.'); } $this->fileOpenMode = $fileOpenMode; $this->filePermission = $filePermission; $this->useLocking = $useLocking; } /** * @inheritDoc */ public function reset(): void { parent::reset(); // auto-close on reset to make sure we periodically close the file in long running processes // as long as they correctly call reset() between jobs if ($this->url !== null && $this->url !== 'php://memory') { $this->close(); } } /** * @inheritDoc */ public function close(): void { if (null !== $this->url && \is_resource($this->stream)) { fclose($this->stream); } $this->stream = null; $this->dirCreated = null; } /** * Return the currently active stream if it is open * * @return resource|null */ public function getStream() { return $this->stream; } /** * Return the stream URL if it was configured with a URL and not an active resource */ public function getUrl(): ?string { return $this->url; } public function getStreamChunkSize(): int { return $this->streamChunkSize; } /** * @inheritDoc */ protected function write(LogRecord $record): void { if ($this->hasUrlInodeWasChanged()) { $this->close(); $this->write($record); return; } if (!\is_resource($this->stream)) { $url = $this->url; if (null === $url || '' === $url) { throw new \LogicException('Missing stream url, the stream can not be opened. This may be caused by a premature call to close().' . Utils::getRecordMessageForException($record)); } $this->createDir($url); $this->errorMessage = null; set_error_handler($this->customErrorHandler(...)); try { $stream = fopen($url, $this->fileOpenMode); if ($this->filePermission !== null) { @chmod($url, $this->filePermission); } } finally { restore_error_handler(); } if (!\is_resource($stream)) { $this->stream = null; throw new \UnexpectedValueException(sprintf('The stream or file "%s" could not be opened in append mode: '.$this->errorMessage, $url) . Utils::getRecordMessageForException($record)); } stream_set_chunk_size($stream, $this->streamChunkSize); $this->stream = $stream; $this->inodeUrl = $this->getInodeFromUrl(); } $stream = $this->stream; if ($this->useLocking) { // ignoring errors here, there's not much we can do about them flock($stream, LOCK_EX); } $this->errorMessage = null; set_error_handler($this->customErrorHandler(...)); try { $this->streamWrite($stream, $record); } finally { restore_error_handler(); } if ($this->errorMessage !== null) { $error = $this->errorMessage; // close the resource if possible to reopen it, and retry the failed write if (!$this->retrying && $this->url !== null && $this->url !== 'php://memory') { $this->retrying = true; $this->close(); $this->write($record); return; } throw new \UnexpectedValueException('Writing to the log file failed: '.$error . Utils::getRecordMessageForException($record)); } $this->retrying = false; if ($this->useLocking) { flock($stream, LOCK_UN); } } /** * Write to stream * @param resource $stream */ protected function streamWrite($stream, LogRecord $record): void { fwrite($stream, (string) $record->formatted); } /** * @return true */ private function customErrorHandler(int $code, string $msg): bool { $this->errorMessage = preg_replace('{^(fopen|mkdir|fwrite)\(.*?\): }', '', $msg); return true; } private function getDirFromStream(string $stream): ?string { $pos = strpos($stream, '://'); if ($pos === false) { return \dirname($stream); } if ('file://' === substr($stream, 0, 7)) { return \dirname(substr($stream, 7)); } return null; } private function createDir(string $url): void { // Do not try to create dir if it has already been tried. if (true === $this->dirCreated) { return; } $dir = $this->getDirFromStream($url); if (null !== $dir && !is_dir($dir)) { $this->errorMessage = null; set_error_handler(function (...$args) { return $this->customErrorHandler(...$args); }); $status = mkdir($dir, 0777, true); restore_error_handler(); if (false === $status && !is_dir($dir) && strpos((string) $this->errorMessage, 'File exists') === false) { throw new \UnexpectedValueException(sprintf('There is no existing directory at "%s" and it could not be created: '.$this->errorMessage, $dir)); } } $this->dirCreated = true; } private function getInodeFromUrl(): ?int { if ($this->url === null || str_starts_with($this->url, 'php://')) { return null; } $inode = @fileinode($this->url); return $inode === false ? null : $inode; } private function hasUrlInodeWasChanged(): bool { if ($this->inodeUrl === null || $this->retrying || $this->inodeUrl === $this->getInodeFromUrl()) { return false; } $this->retrying = true; return true; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/SymfonyMailerHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Closure; use Monolog\Level; use Monolog\LogRecord; use Monolog\Utils; use Monolog\Formatter\FormatterInterface; use Monolog\Formatter\LineFormatter; use Symfony\Component\Mailer\MailerInterface; use Symfony\Component\Mailer\Transport\TransportInterface; use Symfony\Component\Mime\Email; /** * SymfonyMailerHandler uses Symfony's Mailer component to send the emails * * @author Jordi Boggiano */ class SymfonyMailerHandler extends MailHandler { protected MailerInterface|TransportInterface $mailer; /** @var Email|Closure(string, LogRecord[]): Email */ private Email|Closure $emailTemplate; /** * @phpstan-param Email|Closure(string, LogRecord[]): Email $email * * @param MailerInterface|TransportInterface $mailer The mailer to use * @param Closure|Email $email An email template, the subject/body will be replaced */ public function __construct($mailer, Email|Closure $email, int|string|Level $level = Level::Error, bool $bubble = true) { parent::__construct($level, $bubble); $this->mailer = $mailer; $this->emailTemplate = $email; } /** * {@inheritDoc} */ protected function send(string $content, array $records): void { $this->mailer->send($this->buildMessage($content, $records)); } /** * Gets the formatter for the Swift_Message subject. * * @param string|null $format The format of the subject */ protected function getSubjectFormatter(?string $format): FormatterInterface { return new LineFormatter($format); } /** * Creates instance of Email to be sent * * @param string $content formatted email body to be sent * @param LogRecord[] $records Log records that formed the content */ protected function buildMessage(string $content, array $records): Email { $message = null; if ($this->emailTemplate instanceof Email) { $message = clone $this->emailTemplate; } elseif (\is_callable($this->emailTemplate)) { $message = ($this->emailTemplate)($content, $records); } if (!$message instanceof Email) { $record = reset($records); throw new \InvalidArgumentException('Could not resolve message as instance of Email or a callable returning it' . ($record instanceof LogRecord ? Utils::getRecordMessageForException($record) : '')); } if (\count($records) > 0) { $subjectFormatter = $this->getSubjectFormatter($message->getSubject()); $message->subject($subjectFormatter->format($this->getHighestRecord($records))); } if ($this->isHtmlBody($content)) { if (null !== ($charset = $message->getHtmlCharset())) { $message->html($content, $charset); } else { $message->html($content); } } else { if (null !== ($charset = $message->getTextCharset())) { $message->text($content, $charset); } else { $message->text($content); } } return $message->date(new \DateTimeImmutable()); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/SyslogHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Level; use Monolog\LogRecord; /** * Logs to syslog service. * * usage example: * * $log = new Logger('application'); * $syslog = new SyslogHandler('myfacility', 'local6'); * $formatter = new LineFormatter("%channel%.%level_name%: %message% %extra%"); * $syslog->setFormatter($formatter); * $log->pushHandler($syslog); * * @author Sven Paulus */ class SyslogHandler extends AbstractSyslogHandler { protected string $ident; protected int $logopts; /** * @param string|int $facility Either one of the names of the keys in $this->facilities, or a LOG_* facility constant * @param int $logopts Option flags for the openlog() call, defaults to LOG_PID */ public function __construct(string $ident, string|int $facility = LOG_USER, int|string|Level $level = Level::Debug, bool $bubble = true, int $logopts = LOG_PID) { parent::__construct($facility, $level, $bubble); $this->ident = $ident; $this->logopts = $logopts; } /** * @inheritDoc */ public function close(): void { closelog(); } /** * @inheritDoc */ protected function write(LogRecord $record): void { openlog($this->ident, $this->logopts, $this->facility); syslog($this->toSyslogPriority($record->level), (string) $record->formatted); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/SyslogUdp/UdpSocket.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler\SyslogUdp; use Monolog\Utils; use Socket; class UdpSocket { protected const DATAGRAM_MAX_LENGTH = 65023; protected string $ip; protected int $port; protected ?Socket $socket = null; public function __construct(string $ip, int $port = 514) { $this->ip = $ip; $this->port = $port; } public function write(string $line, string $header = ""): void { $this->send($this->assembleMessage($line, $header)); } public function close(): void { if ($this->socket instanceof Socket) { socket_close($this->socket); $this->socket = null; } } protected function getSocket(): Socket { if (null !== $this->socket) { return $this->socket; } $domain = AF_INET; $protocol = SOL_UDP; // Check if we are using unix sockets. if ($this->port === 0) { $domain = AF_UNIX; $protocol = IPPROTO_IP; } $socket = socket_create($domain, SOCK_DGRAM, $protocol); if ($socket instanceof Socket) { return $this->socket = $socket; } throw new \RuntimeException('The UdpSocket to '.$this->ip.':'.$this->port.' could not be opened via socket_create'); } protected function send(string $chunk): void { socket_sendto($this->getSocket(), $chunk, \strlen($chunk), $flags = 0, $this->ip, $this->port); } protected function assembleMessage(string $line, string $header): string { $chunkSize = static::DATAGRAM_MAX_LENGTH - \strlen($header); return $header . Utils::substr($line, 0, $chunkSize); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/SyslogUdpHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use DateTimeInterface; use Monolog\Handler\SyslogUdp\UdpSocket; use Monolog\Level; use Monolog\LogRecord; use Monolog\Utils; /** * A Handler for logging to a remote syslogd server. * * @author Jesper Skovgaard Nielsen * @author Dominik Kukacka */ class SyslogUdpHandler extends AbstractSyslogHandler { const RFC3164 = 0; const RFC5424 = 1; const RFC5424e = 2; /** @var array */ private array $dateFormats = [ self::RFC3164 => 'M d H:i:s', self::RFC5424 => \DateTime::RFC3339, self::RFC5424e => \DateTime::RFC3339_EXTENDED, ]; protected UdpSocket $socket; protected string $ident; /** @var self::RFC* */ protected int $rfc; /** * @param string $host Either IP/hostname or a path to a unix socket (port must be 0 then) * @param int $port Port number, or 0 if $host is a unix socket * @param string|int $facility Either one of the names of the keys in $this->facilities, or a LOG_* facility constant * @param bool $bubble Whether the messages that are handled can bubble up the stack or not * @param string $ident Program name or tag for each log message. * @param int $rfc RFC to format the message for. * @throws MissingExtensionException when there is no socket extension * * @phpstan-param self::RFC* $rfc */ public function __construct(string $host, int $port = 514, string|int $facility = LOG_USER, int|string|Level $level = Level::Debug, bool $bubble = true, string $ident = 'php', int $rfc = self::RFC5424) { if (!\extension_loaded('sockets')) { throw new MissingExtensionException('The sockets extension is required to use the SyslogUdpHandler'); } parent::__construct($facility, $level, $bubble); $this->ident = $ident; $this->rfc = $rfc; $this->socket = new UdpSocket($host, $port); } protected function write(LogRecord $record): void { $lines = $this->splitMessageIntoLines($record->formatted); $header = $this->makeCommonSyslogHeader($this->toSyslogPriority($record->level), $record->datetime); foreach ($lines as $line) { $this->socket->write($line, $header); } } public function close(): void { $this->socket->close(); } /** * @param string|string[] $message * @return string[] */ private function splitMessageIntoLines($message): array { if (\is_array($message)) { $message = implode("\n", $message); } $lines = preg_split('/$\R?^/m', (string) $message, -1, PREG_SPLIT_NO_EMPTY); if (false === $lines) { $pcreErrorCode = preg_last_error(); throw new \RuntimeException('Could not preg_split: ' . $pcreErrorCode . ' / ' . preg_last_error_msg()); } return $lines; } /** * Make common syslog header (see rfc5424 or rfc3164) */ protected function makeCommonSyslogHeader(int $severity, DateTimeInterface $datetime): string { $priority = $severity + $this->facility; $pid = getmypid(); if (false === $pid) { $pid = '-'; } $hostname = gethostname(); if (false === $hostname) { $hostname = '-'; } if ($this->rfc === self::RFC3164) { // see https://github.com/phpstan/phpstan/issues/5348 // @phpstan-ignore-next-line $dateNew = $datetime->setTimezone(new \DateTimeZone('UTC')); $date = $dateNew->format($this->dateFormats[$this->rfc]); return "<$priority>" . $date . " " . $hostname . " " . $this->ident . "[" . $pid . "]: "; } $date = $datetime->format($this->dateFormats[$this->rfc]); return "<$priority>1 " . $date . " " . $hostname . " " . $this->ident . " " . $pid . " - - "; } /** * Inject your own socket, mainly used for testing * * @return $this */ public function setSocket(UdpSocket $socket): self { $this->socket = $socket; return $this; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/TelegramBotHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use RuntimeException; use Monolog\Level; use Monolog\Utils; use Monolog\LogRecord; /** * Handler sends logs to Telegram using Telegram Bot API. * * How to use: * 1) Create a Telegram bot with https://telegram.me/BotFather; * 2) Create a Telegram channel or a group where logs will be recorded; * 3) Add the created bot from step 1 to the created channel/group from step 2. * * In order to create an instance of TelegramBotHandler use * 1. The Telegram bot API key from step 1 * 2. The channel name with the `@` prefix if you created a public channel (e.g. `@my_public_channel`), * or the channel ID with the `-100` prefix if you created a private channel (e.g. `-1001234567890`), * or the group ID from step 2 (e.g. `-1234567890`). * * @link https://core.telegram.org/bots/api * * @author Mazur Alexandr */ class TelegramBotHandler extends AbstractProcessingHandler { private const BOT_API = 'https://api.telegram.org/bot'; /** * The available values of parseMode according to the Telegram api documentation */ private const AVAILABLE_PARSE_MODES = [ 'HTML', 'MarkdownV2', 'Markdown', // legacy mode without underline and strikethrough, use MarkdownV2 instead ]; /** * The maximum number of characters allowed in a message according to the Telegram api documentation */ private const MAX_MESSAGE_LENGTH = 4096; /** * Telegram bot access token provided by BotFather. * Create telegram bot with https://telegram.me/BotFather and use access token from it. */ private string $apiKey; /** * Telegram channel name. * Since to start with '@' symbol as prefix. */ private string $channel; /** * The kind of formatting that is used for the message. * See available options at https://core.telegram.org/bots/api#formatting-options * or in AVAILABLE_PARSE_MODES */ private string|null $parseMode; /** * Disables link previews for links in the message. */ private bool|null $disableWebPagePreview; /** * Sends the message silently. Users will receive a notification with no sound. */ private bool|null $disableNotification; /** * True - split a message longer than MAX_MESSAGE_LENGTH into parts and send in multiple messages. * False - truncates a message that is too long. */ private bool $splitLongMessages; /** * Adds 1-second delay between sending a split message (according to Telegram API to avoid 429 Too Many Requests). */ private bool $delayBetweenMessages; /** * Telegram message thread id, unique identifier for the target message thread (topic) of the forum; for forum supergroups only * See how to get the `message_thread_id` https://stackoverflow.com/a/75178418 */ private int|null $topic; /** * @param string $apiKey Telegram bot access token provided by BotFather * @param string $channel Telegram channel name * @param bool $splitLongMessages Split a message longer than MAX_MESSAGE_LENGTH into parts and send in multiple messages * @param bool $delayBetweenMessages Adds delay between sending a split message according to Telegram API * @param int $topic Telegram message thread id, unique identifier for the target message thread (topic) of the forum * @throws MissingExtensionException If the curl extension is missing */ public function __construct( string $apiKey, string $channel, $level = Level::Debug, bool $bubble = true, ?string $parseMode = null, ?bool $disableWebPagePreview = null, ?bool $disableNotification = null, bool $splitLongMessages = false, bool $delayBetweenMessages = false, ?int $topic = null ) { if (!\extension_loaded('curl')) { throw new MissingExtensionException('The curl extension is needed to use the TelegramBotHandler'); } parent::__construct($level, $bubble); $this->apiKey = $apiKey; $this->channel = $channel; $this->setParseMode($parseMode); $this->disableWebPagePreview($disableWebPagePreview); $this->disableNotification($disableNotification); $this->splitLongMessages($splitLongMessages); $this->delayBetweenMessages($delayBetweenMessages); $this->setTopic($topic); } /** * @return $this */ public function setParseMode(string|null $parseMode = null): self { if ($parseMode !== null && !\in_array($parseMode, self::AVAILABLE_PARSE_MODES, true)) { throw new \InvalidArgumentException('Unknown parseMode, use one of these: ' . implode(', ', self::AVAILABLE_PARSE_MODES) . '.'); } $this->parseMode = $parseMode; return $this; } /** * @return $this */ public function disableWebPagePreview(bool|null $disableWebPagePreview = null): self { $this->disableWebPagePreview = $disableWebPagePreview; return $this; } /** * @return $this */ public function disableNotification(bool|null $disableNotification = null): self { $this->disableNotification = $disableNotification; return $this; } /** * True - split a message longer than MAX_MESSAGE_LENGTH into parts and send in multiple messages. * False - truncates a message that is too long. * * @return $this */ public function splitLongMessages(bool $splitLongMessages = false): self { $this->splitLongMessages = $splitLongMessages; return $this; } /** * Adds 1-second delay between sending a split message (according to Telegram API to avoid 429 Too Many Requests). * * @return $this */ public function delayBetweenMessages(bool $delayBetweenMessages = false): self { $this->delayBetweenMessages = $delayBetweenMessages; return $this; } /** * @return $this */ public function setTopic(?int $topic = null): self { $this->topic = $topic; return $this; } /** * @inheritDoc */ public function handleBatch(array $records): void { $messages = []; foreach ($records as $record) { if (!$this->isHandling($record)) { continue; } if (\count($this->processors) > 0) { $record = $this->processRecord($record); } $messages[] = $record; } if (\count($messages) > 0) { $this->send((string) $this->getFormatter()->formatBatch($messages)); } } /** * @inheritDoc */ protected function write(LogRecord $record): void { $this->send($record->formatted); } /** * Send request to @link https://api.telegram.org/bot on SendMessage action. */ protected function send(string $message): void { $messages = $this->handleMessageLength($message); foreach ($messages as $key => $msg) { if ($this->delayBetweenMessages && $key > 0) { sleep(1); } $this->sendCurl($msg); } } protected function sendCurl(string $message): void { if ('' === trim($message)) { return; } $ch = curl_init(); $url = self::BOT_API . $this->apiKey . '/SendMessage'; curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); $params = [ 'text' => $message, 'chat_id' => $this->channel, 'parse_mode' => $this->parseMode, 'disable_web_page_preview' => $this->disableWebPagePreview, 'disable_notification' => $this->disableNotification, ]; if ($this->topic !== null) { $params['message_thread_id'] = $this->topic; } curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params)); $result = Curl\Util::execute($ch); if (!\is_string($result)) { throw new RuntimeException('Telegram API error. Description: No response'); } $result = json_decode($result, true); if ($result['ok'] === false) { throw new RuntimeException('Telegram API error. Description: ' . $result['description']); } } /** * Handle a message that is too long: truncates or splits into several * @return string[] */ private function handleMessageLength(string $message): array { $truncatedMarker = ' (…truncated)'; if (!$this->splitLongMessages && \strlen($message) > self::MAX_MESSAGE_LENGTH) { return [Utils::substr($message, 0, self::MAX_MESSAGE_LENGTH - \strlen($truncatedMarker)) . $truncatedMarker]; } return str_split($message, self::MAX_MESSAGE_LENGTH); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/TestHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Level; use Monolog\Logger; use Psr\Log\LogLevel; use Monolog\LogRecord; use NoDiscard; /** * Used for testing purposes. * * It records all records and gives you access to them for verification. * * @author Jordi Boggiano * * @method bool hasEmergency(array{message: string, context?: mixed[]}|string $recordAssertions) * @method bool hasAlert(array{message: string, context?: mixed[]}|string $recordAssertions) * @method bool hasCritical(array{message: string, context?: mixed[]}|string $recordAssertions) * @method bool hasError(array{message: string, context?: mixed[]}|string $recordAssertions) * @method bool hasWarning(array{message: string, context?: mixed[]}|string $recordAssertions) * @method bool hasNotice(array{message: string, context?: mixed[]}|string $recordAssertions) * @method bool hasInfo(array{message: string, context?: mixed[]}|string $recordAssertions) * @method bool hasDebug(array{message: string, context?: mixed[]}|string $recordAssertions) * * @method bool hasEmergencyRecords() * @method bool hasAlertRecords() * @method bool hasCriticalRecords() * @method bool hasErrorRecords() * @method bool hasWarningRecords() * @method bool hasNoticeRecords() * @method bool hasInfoRecords() * @method bool hasDebugRecords() * * @method bool hasEmergencyThatContains(string $message) * @method bool hasAlertThatContains(string $message) * @method bool hasCriticalThatContains(string $message) * @method bool hasErrorThatContains(string $message) * @method bool hasWarningThatContains(string $message) * @method bool hasNoticeThatContains(string $message) * @method bool hasInfoThatContains(string $message) * @method bool hasDebugThatContains(string $message) * * @method bool hasEmergencyThatMatches(string $regex) * @method bool hasAlertThatMatches(string $regex) * @method bool hasCriticalThatMatches(string $regex) * @method bool hasErrorThatMatches(string $regex) * @method bool hasWarningThatMatches(string $regex) * @method bool hasNoticeThatMatches(string $regex) * @method bool hasInfoThatMatches(string $regex) * @method bool hasDebugThatMatches(string $regex) * * @method bool hasEmergencyThatPasses(callable $predicate) * @method bool hasAlertThatPasses(callable $predicate) * @method bool hasCriticalThatPasses(callable $predicate) * @method bool hasErrorThatPasses(callable $predicate) * @method bool hasWarningThatPasses(callable $predicate) * @method bool hasNoticeThatPasses(callable $predicate) * @method bool hasInfoThatPasses(callable $predicate) * @method bool hasDebugThatPasses(callable $predicate) */ class TestHandler extends AbstractProcessingHandler { /** @var LogRecord[] */ protected array $records = []; /** @phpstan-var array, LogRecord[]> */ protected array $recordsByLevel = []; private bool $skipReset = false; /** * @return array */ #[NoDiscard] public function getRecords(): array { return $this->records; } public function clear(): void { $this->records = []; $this->recordsByLevel = []; } public function reset(): void { if (!$this->skipReset) { $this->clear(); } } public function setSkipReset(bool $skipReset): void { $this->skipReset = $skipReset; } /** * @param int|string|Level|LogLevel::* $level Logging level value or name * * @phpstan-param value-of|value-of|Level|LogLevel::* $level */ #[NoDiscard] public function hasRecords(int|string|Level $level): bool { return isset($this->recordsByLevel[Logger::toMonologLevel($level)->value]); } /** * @param string|array $recordAssertions Either a message string or an array containing message and optionally context keys that will be checked against all records * * @phpstan-param array{message: string, context?: mixed[]}|string $recordAssertions */ #[NoDiscard] public function hasRecord(string|array $recordAssertions, Level $level): bool { if (\is_string($recordAssertions)) { $recordAssertions = ['message' => $recordAssertions]; } return $this->hasRecordThatPasses(function (LogRecord $rec) use ($recordAssertions) { if ($rec->message !== $recordAssertions['message']) { return false; } if (isset($recordAssertions['context']) && $rec->context !== $recordAssertions['context']) { return false; } return true; }, $level); } #[NoDiscard] public function hasRecordThatContains(string $message, Level $level): bool { return $this->hasRecordThatPasses(fn (LogRecord $rec) => str_contains($rec->message, $message), $level); } #[NoDiscard] public function hasRecordThatMatches(string $regex, Level $level): bool { return $this->hasRecordThatPasses(fn (LogRecord $rec) => preg_match($regex, $rec->message) > 0, $level); } /** * @phpstan-param callable(LogRecord, int): mixed $predicate */ #[NoDiscard] public function hasRecordThatPasses(callable $predicate, Level $level): bool { $level = Logger::toMonologLevel($level); if (!isset($this->recordsByLevel[$level->value])) { return false; } foreach ($this->recordsByLevel[$level->value] as $i => $rec) { if ((bool) $predicate($rec, $i)) { return true; } } return false; } /** * @inheritDoc */ protected function write(LogRecord $record): void { $this->recordsByLevel[$record->level->value][] = $record; $this->records[] = $record; } /** * @param mixed[] $args */ #[NoDiscard] public function __call(string $method, array $args): bool { if ((bool) preg_match('/(.*)(Debug|Info|Notice|Warning|Error|Critical|Alert|Emergency)(.*)/', $method, $matches)) { $genericMethod = $matches[1] . ('Records' !== $matches[3] ? 'Record' : '') . $matches[3]; $level = \constant(Level::class.'::' . $matches[2]); $callback = [$this, $genericMethod]; if (\is_callable($callback)) { $args[] = $level; return \call_user_func_array($callback, $args); } } throw new \BadMethodCallException('Call to undefined method ' . \get_class($this) . '::' . $method . '()'); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/WebRequestRecognizerTrait.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; trait WebRequestRecognizerTrait { /** * Checks if PHP's serving a web request */ protected function isWebRequest(): bool { return 'cli' !== \PHP_SAPI && 'phpdbg' !== \PHP_SAPI; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/WhatFailureGroupHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\LogRecord; use Throwable; /** * Forwards records to multiple handlers suppressing failures of each handler * and continuing through to give every handler a chance to succeed. * * @author Craig D'Amelio */ class WhatFailureGroupHandler extends GroupHandler { /** * @inheritDoc */ public function handle(LogRecord $record): bool { if (\count($this->processors) > 0) { $record = $this->processRecord($record); } foreach ($this->handlers as $handler) { try { $handler->handle(clone $record); } catch (Throwable) { // What failure? } } return false === $this->bubble; } /** * @inheritDoc */ public function handleBatch(array $records): void { if (\count($this->processors) > 0) { $processed = []; foreach ($records as $record) { $processed[] = $this->processRecord($record); } $records = $processed; } foreach ($this->handlers as $handler) { try { $handler->handleBatch(array_map(fn ($record) => clone $record, $records)); } catch (Throwable) { // What failure? } } } /** * {@inheritDoc} */ public function close(): void { foreach ($this->handlers as $handler) { try { $handler->close(); } catch (\Throwable $e) { // What failure? } } } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Handler/ZendMonitorHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Formatter\FormatterInterface; use Monolog\Formatter\NormalizerFormatter; use Monolog\Level; use Monolog\LogRecord; /** * Handler sending logs to Zend Monitor * * @author Christian Bergau * @author Jason Davis */ class ZendMonitorHandler extends AbstractProcessingHandler { /** * @throws MissingExtensionException */ public function __construct(int|string|Level $level = Level::Debug, bool $bubble = true) { if (!\function_exists('zend_monitor_custom_event')) { throw new MissingExtensionException( 'You must have Zend Server installed with Zend Monitor enabled in order to use this handler' ); } parent::__construct($level, $bubble); } /** * Translates Monolog log levels to ZendMonitor levels. */ protected function toZendMonitorLevel(Level $level): int { return match ($level) { Level::Debug => \ZEND_MONITOR_EVENT_SEVERITY_INFO, Level::Info => \ZEND_MONITOR_EVENT_SEVERITY_INFO, Level::Notice => \ZEND_MONITOR_EVENT_SEVERITY_INFO, Level::Warning => \ZEND_MONITOR_EVENT_SEVERITY_WARNING, Level::Error => \ZEND_MONITOR_EVENT_SEVERITY_ERROR, Level::Critical => \ZEND_MONITOR_EVENT_SEVERITY_ERROR, Level::Alert => \ZEND_MONITOR_EVENT_SEVERITY_ERROR, Level::Emergency => \ZEND_MONITOR_EVENT_SEVERITY_ERROR, }; } /** * @inheritDoc */ protected function write(LogRecord $record): void { $this->writeZendMonitorCustomEvent( $record->level->getName(), $record->message, $record->formatted, $this->toZendMonitorLevel($record->level) ); } /** * Write to Zend Monitor Events * @param string $type Text displayed in "Class Name (custom)" field * @param string $message Text displayed in "Error String" * @param array $formatted Displayed in Custom Variables tab * @param int $severity Set the event severity level (-1,0,1) */ protected function writeZendMonitorCustomEvent(string $type, string $message, array $formatted, int $severity): void { zend_monitor_custom_event($type, $message, $formatted, $severity); } /** * @inheritDoc */ public function getDefaultFormatter(): FormatterInterface { return new NormalizerFormatter(); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/JsonSerializableDateTimeImmutable.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog; use DateTimeZone; /** * Overrides default json encoding of date time objects * * @author Menno Holtkamp * @author Jordi Boggiano */ class JsonSerializableDateTimeImmutable extends \DateTimeImmutable implements \JsonSerializable { private bool $useMicroseconds; public function __construct(bool $useMicroseconds, ?DateTimeZone $timezone = null) { $this->useMicroseconds = $useMicroseconds; // if you like to use a custom time to pass to Logger::addRecord directly, // call modify() or setTimestamp() on this instance to change the date after creating it parent::__construct('now', $timezone); } public function jsonSerialize(): string { if ($this->useMicroseconds) { return $this->format('Y-m-d\TH:i:s.uP'); } return $this->format('Y-m-d\TH:i:sP'); } public function __toString(): string { return $this->jsonSerialize(); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Level.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog; use Psr\Log\LogLevel; /** * Represents the log levels * * Monolog supports the logging levels described by RFC 5424 {@see https://datatracker.ietf.org/doc/html/rfc5424} * but due to BC the severity values used internally are not 0-7. * * To get the level name/value out of a Level there are several options: * * - Use ->getName() to get the standard Monolog name which is full uppercased (e.g. "DEBUG") * - Use ->toPsrLogLevel() to get the standard PSR-3 name which is full lowercased (e.g. "debug") * - Use ->toRFC5424Level() to get the standard RFC 5424 value (e.g. 7 for debug, 0 for emergency) * - Use ->name to get the enum case's name which is capitalized (e.g. "Debug") * * To get the internal value for filtering, if the includes/isLowerThan/isHigherThan methods are * not enough, you can use ->value to get the enum case's integer value. */ enum Level: int { /** * Detailed debug information */ case Debug = 100; /** * Interesting events * * Examples: User logs in, SQL logs. */ case Info = 200; /** * Uncommon events */ case Notice = 250; /** * Exceptional occurrences that are not errors * * Examples: Use of deprecated APIs, poor use of an API, * undesirable things that are not necessarily wrong. */ case Warning = 300; /** * Runtime errors */ case Error = 400; /** * Critical conditions * * Example: Application component unavailable, unexpected exception. */ case Critical = 500; /** * Action must be taken immediately * * Example: Entire website down, database unavailable, etc. * This should trigger the SMS alerts and wake you up. */ case Alert = 550; /** * Urgent alert. */ case Emergency = 600; /** * @param value-of|LogLevel::*|'Debug'|'Info'|'Notice'|'Warning'|'Error'|'Critical'|'Alert'|'Emergency' $name * @return static */ public static function fromName(string $name): self { return match (strtolower($name)) { 'debug' => self::Debug, 'info' => self::Info, 'notice' => self::Notice, 'warning' => self::Warning, 'error' => self::Error, 'critical' => self::Critical, 'alert' => self::Alert, 'emergency' => self::Emergency, }; } /** * @param value-of $value * @return static */ public static function fromValue(int $value): self { return self::from($value); } /** * Returns true if the passed $level is higher or equal to $this */ public function includes(Level $level): bool { return $this->value <= $level->value; } public function isHigherThan(Level $level): bool { return $this->value > $level->value; } public function isLowerThan(Level $level): bool { return $this->value < $level->value; } /** * Returns the monolog standardized all-capitals name of the level * * Use this instead of $level->name which returns the enum case name (e.g. Debug vs DEBUG if you use getName()) * * @return value-of */ public function getName(): string { return match ($this) { self::Debug => 'DEBUG', self::Info => 'INFO', self::Notice => 'NOTICE', self::Warning => 'WARNING', self::Error => 'ERROR', self::Critical => 'CRITICAL', self::Alert => 'ALERT', self::Emergency => 'EMERGENCY', }; } /** * Returns the PSR-3 level matching this instance * * @phpstan-return \Psr\Log\LogLevel::* */ public function toPsrLogLevel(): string { return match ($this) { self::Debug => LogLevel::DEBUG, self::Info => LogLevel::INFO, self::Notice => LogLevel::NOTICE, self::Warning => LogLevel::WARNING, self::Error => LogLevel::ERROR, self::Critical => LogLevel::CRITICAL, self::Alert => LogLevel::ALERT, self::Emergency => LogLevel::EMERGENCY, }; } /** * Returns the RFC 5424 level matching this instance * * @phpstan-return int<0, 7> */ public function toRFC5424Level(): int { return match ($this) { self::Debug => 7, self::Info => 6, self::Notice => 5, self::Warning => 4, self::Error => 3, self::Critical => 2, self::Alert => 1, self::Emergency => 0, }; } public const VALUES = [ 100, 200, 250, 300, 400, 500, 550, 600, ]; public const NAMES = [ 'DEBUG', 'INFO', 'NOTICE', 'WARNING', 'ERROR', 'CRITICAL', 'ALERT', 'EMERGENCY', ]; } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/LogRecord.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog; use ArrayAccess; /** * Monolog log record * * @author Jordi Boggiano * @template-implements ArrayAccess<'message'|'level'|'context'|'level_name'|'channel'|'datetime'|'extra'|'formatted', int|string|\DateTimeImmutable|array> */ class LogRecord implements ArrayAccess { private const MODIFIABLE_FIELDS = [ 'extra' => true, 'formatted' => true, ]; public function __construct( public readonly \DateTimeImmutable $datetime, public readonly string $channel, public readonly Level $level, public readonly string $message, /** @var array */ public readonly array $context = [], /** @var array */ public array $extra = [], public mixed $formatted = null, ) { } public function offsetSet(mixed $offset, mixed $value): void { if ($offset === 'extra') { if (!\is_array($value)) { throw new \InvalidArgumentException('extra must be an array'); } $this->extra = $value; return; } if ($offset === 'formatted') { $this->formatted = $value; return; } throw new \LogicException('Unsupported operation: setting '.$offset); } public function offsetExists(mixed $offset): bool { if ($offset === 'level_name') { return true; } return isset($this->{$offset}); } public function offsetUnset(mixed $offset): void { throw new \LogicException('Unsupported operation'); } public function &offsetGet(mixed $offset): mixed { // handle special cases for the level enum if ($offset === 'level_name') { // avoid returning readonly props by ref as this is illegal $copy = $this->level->getName(); return $copy; } if ($offset === 'level') { // avoid returning readonly props by ref as this is illegal $copy = $this->level->value; return $copy; } if (isset(self::MODIFIABLE_FIELDS[$offset])) { return $this->{$offset}; } // avoid returning readonly props by ref as this is illegal $copy = $this->{$offset}; return $copy; } /** * @phpstan-return array{message: string, context: mixed[], level: value-of, level_name: value-of, channel: string, datetime: \DateTimeImmutable, extra: mixed[]} */ public function toArray(): array { return [ 'message' => $this->message, 'context' => $this->context, 'level' => $this->level->value, 'level_name' => $this->level->getName(), 'channel' => $this->channel, 'datetime' => $this->datetime, 'extra' => $this->extra, ]; } public function with(mixed ...$args): self { foreach (['message', 'context', 'level', 'channel', 'datetime', 'extra'] as $prop) { $args[$prop] ??= $this->{$prop}; } return new self(...$args); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Logger.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog; use Closure; use DateTimeZone; use Fiber; use Monolog\Handler\HandlerInterface; use Monolog\Processor\ProcessorInterface; use Psr\Log\LoggerInterface; use Psr\Log\InvalidArgumentException; use Psr\Log\LogLevel; use Throwable; use Stringable; use WeakMap; /** * Monolog log channel * * It contains a stack of Handlers and a stack of Processors, * and uses them to store records that are added to it. * * @author Jordi Boggiano * @final */ class Logger implements LoggerInterface, ResettableInterface { /** * Detailed debug information * * @deprecated Use \Monolog\Level::Debug */ public const DEBUG = 100; /** * Interesting events * * Examples: User logs in, SQL logs. * * @deprecated Use \Monolog\Level::Info */ public const INFO = 200; /** * Uncommon events * * @deprecated Use \Monolog\Level::Notice */ public const NOTICE = 250; /** * Exceptional occurrences that are not errors * * Examples: Use of deprecated APIs, poor use of an API, * undesirable things that are not necessarily wrong. * * @deprecated Use \Monolog\Level::Warning */ public const WARNING = 300; /** * Runtime errors * * @deprecated Use \Monolog\Level::Error */ public const ERROR = 400; /** * Critical conditions * * Example: Application component unavailable, unexpected exception. * * @deprecated Use \Monolog\Level::Critical */ public const CRITICAL = 500; /** * Action must be taken immediately * * Example: Entire website down, database unavailable, etc. * This should trigger the SMS alerts and wake you up. * * @deprecated Use \Monolog\Level::Alert */ public const ALERT = 550; /** * Urgent alert. * * @deprecated Use \Monolog\Level::Emergency */ public const EMERGENCY = 600; /** * Monolog API version * * This is only bumped when API breaks are done and should * follow the major version of the library */ public const API = 3; /** * Mapping between levels numbers defined in RFC 5424 and Monolog ones * * @phpstan-var array $rfc_5424_levels */ private const RFC_5424_LEVELS = [ 7 => Level::Debug, 6 => Level::Info, 5 => Level::Notice, 4 => Level::Warning, 3 => Level::Error, 2 => Level::Critical, 1 => Level::Alert, 0 => Level::Emergency, ]; protected string $name; /** * The handler stack * * @var list */ protected array $handlers; /** * Processors that will process all log records * * To process records of a single handler instead, add the processor on that specific handler * * @var array<(callable(LogRecord): LogRecord)|ProcessorInterface> */ protected array $processors; protected bool $microsecondTimestamps = true; protected DateTimeZone $timezone; protected Closure|null $exceptionHandler = null; /** * Keeps track of depth to prevent infinite logging loops */ private int $logDepth = 0; /** * @var WeakMap, int> Keeps track of depth inside fibers to prevent infinite logging loops */ private WeakMap $fiberLogDepth; /** * Whether to detect infinite logging loops * This can be disabled via {@see useLoggingLoopDetection} if you have async handlers that do not play well with this */ private bool $detectCycles = true; /** * @param string $name The logging channel, a simple descriptive name that is attached to all log records * @param list $handlers Optional stack of handlers, the first one in the array is called first, etc. * @param callable[] $processors Optional array of processors * @param DateTimeZone|null $timezone Optional timezone, if not provided date_default_timezone_get() will be used * * @phpstan-param array<(callable(LogRecord): LogRecord)|ProcessorInterface> $processors */ public function __construct(string $name, array $handlers = [], array $processors = [], DateTimeZone|null $timezone = null) { $this->name = $name; $this->setHandlers($handlers); $this->processors = $processors; $this->timezone = $timezone ?? new DateTimeZone(date_default_timezone_get()); $this->fiberLogDepth = new \WeakMap(); } public function getName(): string { return $this->name; } /** * Return a new cloned instance with the name changed * * @return static */ public function withName(string $name): self { $new = clone $this; $new->name = $name; return $new; } /** * Pushes a handler on to the stack. * * @return $this */ public function pushHandler(HandlerInterface $handler): self { array_unshift($this->handlers, $handler); return $this; } /** * Pops a handler from the stack * * @throws \LogicException If empty handler stack */ public function popHandler(): HandlerInterface { if (0 === \count($this->handlers)) { throw new \LogicException('You tried to pop from an empty handler stack.'); } return array_shift($this->handlers); } /** * Set handlers, replacing all existing ones. * * If a map is passed, keys will be ignored. * * @param list $handlers * @return $this */ public function setHandlers(array $handlers): self { $this->handlers = []; foreach (array_reverse($handlers) as $handler) { $this->pushHandler($handler); } return $this; } /** * @return list */ public function getHandlers(): array { return $this->handlers; } /** * Adds a processor on to the stack. * * @phpstan-param ProcessorInterface|(callable(LogRecord): LogRecord) $callback * @return $this */ public function pushProcessor(ProcessorInterface|callable $callback): self { array_unshift($this->processors, $callback); return $this; } /** * Removes the processor on top of the stack and returns it. * * @phpstan-return ProcessorInterface|(callable(LogRecord): LogRecord) * @throws \LogicException If empty processor stack */ public function popProcessor(): callable { if (0 === \count($this->processors)) { throw new \LogicException('You tried to pop from an empty processor stack.'); } return array_shift($this->processors); } /** * @return callable[] * @phpstan-return array */ public function getProcessors(): array { return $this->processors; } /** * Control the use of microsecond resolution timestamps in the 'datetime' * member of new records. * * As of PHP7.1 microseconds are always included by the engine, so * there is no performance penalty and Monolog 2 enabled microseconds * by default. This function lets you disable them though in case you want * to suppress microseconds from the output. * * @param bool $micro True to use microtime() to create timestamps * @return $this */ public function useMicrosecondTimestamps(bool $micro): self { $this->microsecondTimestamps = $micro; return $this; } /** * @return $this */ public function useLoggingLoopDetection(bool $detectCycles): self { $this->detectCycles = $detectCycles; return $this; } /** * Adds a log record. * * @param int $level The logging level (a Monolog or RFC 5424 level) * @param string $message The log message * @param mixed[] $context The log context * @param JsonSerializableDateTimeImmutable|null $datetime Optional log date to log into the past or future * * @return bool Whether the record has been processed * * @phpstan-param value-of|Level $level */ public function addRecord(int|Level $level, string $message, array $context = [], JsonSerializableDateTimeImmutable|null $datetime = null): bool { if (\is_int($level) && isset(self::RFC_5424_LEVELS[$level])) { $level = self::RFC_5424_LEVELS[$level]; } if ($this->detectCycles) { if (null !== ($fiber = Fiber::getCurrent())) { $logDepth = $this->fiberLogDepth[$fiber] = ($this->fiberLogDepth[$fiber] ?? 0) + 1; } else { $logDepth = ++$this->logDepth; } } else { $logDepth = 0; } if ($logDepth === 3) { $this->warning('A possible infinite logging loop was detected and aborted. It appears some of your handler code is triggering logging, see the previous log record for a hint as to what may be the cause.'); return false; } elseif ($logDepth >= 5) { // log depth 4 is let through, so we can log the warning above return false; } try { $recordInitialized = \count($this->processors) === 0; $record = new LogRecord( datetime: $datetime ?? new JsonSerializableDateTimeImmutable($this->microsecondTimestamps, $this->timezone), channel: $this->name, level: self::toMonologLevel($level), message: $message, context: $context, extra: [], ); $handled = false; foreach ($this->handlers as $handler) { if (false === $recordInitialized) { // skip initializing the record as long as no handler is going to handle it if (!$handler->isHandling($record)) { continue; } try { foreach ($this->processors as $processor) { $record = $processor($record); } $recordInitialized = true; } catch (Throwable $e) { $this->handleException($e, $record); return true; } } // once the record is initialized, send it to all handlers as long as the bubbling chain is not interrupted try { $handled = true; if (true === $handler->handle(clone $record)) { break; } } catch (Throwable $e) { $this->handleException($e, $record); return true; } } return $handled; } finally { if ($this->detectCycles) { if (isset($fiber)) { $this->fiberLogDepth[$fiber]--; } else { $this->logDepth--; } } } } /** * Ends a log cycle and frees all resources used by handlers. * * Closing a Handler means flushing all buffers and freeing any open resources/handles. * Handlers that have been closed should be able to accept log records again and re-open * themselves on demand, but this may not always be possible depending on implementation. * * This is useful at the end of a request and will be called automatically on every handler * when they get destructed. */ public function close(): void { foreach ($this->handlers as $handler) { $handler->close(); } } /** * Ends a log cycle and resets all handlers and processors to their initial state. * * Resetting a Handler or a Processor means flushing/cleaning all buffers, resetting internal * state, and getting it back to a state in which it can receive log records again. * * This is useful in case you want to avoid logs leaking between two requests or jobs when you * have a long running process like a worker or an application server serving multiple requests * in one process. */ public function reset(): void { foreach ($this->handlers as $handler) { if ($handler instanceof ResettableInterface) { $handler->reset(); } } foreach ($this->processors as $processor) { if ($processor instanceof ResettableInterface) { $processor->reset(); } } } /** * Gets the name of the logging level as a string. * * This still returns a string instead of a Level for BC, but new code should not rely on this method. * * @throws \Psr\Log\InvalidArgumentException If level is not defined * * @phpstan-param value-of|Level $level * @phpstan-return value-of * * @deprecated Since 3.0, use {@see toMonologLevel} or {@see \Monolog\Level->getName()} instead */ public static function getLevelName(int|Level $level): string { return self::toMonologLevel($level)->getName(); } /** * Converts PSR-3 levels to Monolog ones if necessary * * @param int|string|Level|LogLevel::* $level Level number (monolog) or name (PSR-3) * @throws \Psr\Log\InvalidArgumentException If level is not defined * * @phpstan-param value-of|value-of|Level|LogLevel::* $level */ public static function toMonologLevel(string|int|Level $level): Level { if ($level instanceof Level) { return $level; } if (\is_string($level)) { if (is_numeric($level)) { $levelEnum = Level::tryFrom((int) $level); if ($levelEnum === null) { throw new InvalidArgumentException('Level "'.$level.'" is not defined, use one of: '.implode(', ', Level::NAMES + Level::VALUES)); } return $levelEnum; } // Contains first char of all log levels and avoids using strtoupper() which may have // strange results depending on locale (for example, "i" will become "İ" in Turkish locale) $upper = strtr(substr($level, 0, 1), 'dinweca', 'DINWECA') . strtolower(substr($level, 1)); if (\defined(Level::class.'::'.$upper)) { return \constant(Level::class . '::' . $upper); } throw new InvalidArgumentException('Level "'.$level.'" is not defined, use one of: '.implode(', ', Level::NAMES + Level::VALUES)); } $levelEnum = Level::tryFrom($level); if ($levelEnum === null) { throw new InvalidArgumentException('Level "'.var_export($level, true).'" is not defined, use one of: '.implode(', ', Level::NAMES + Level::VALUES)); } return $levelEnum; } /** * Checks whether the Logger has a handler that listens on the given level * * @phpstan-param value-of|value-of|Level|LogLevel::* $level */ public function isHandling(int|string|Level $level): bool { $record = new LogRecord( datetime: new JsonSerializableDateTimeImmutable($this->microsecondTimestamps, $this->timezone), channel: $this->name, message: '', level: self::toMonologLevel($level), ); foreach ($this->handlers as $handler) { if ($handler->isHandling($record)) { return true; } } return false; } /** * Set a custom exception handler that will be called if adding a new record fails * * The Closure will receive an exception object and the record that failed to be logged * * @return $this */ public function setExceptionHandler(Closure|null $callback): self { $this->exceptionHandler = $callback; return $this; } public function getExceptionHandler(): Closure|null { return $this->exceptionHandler; } /** * Adds a log record at an arbitrary level. * * This method allows for compatibility with common interfaces. * * @param mixed $level The log level (a Monolog, PSR-3 or RFC 5424 level) * @param string|Stringable $message The log message * @param mixed[] $context The log context * * @phpstan-param Level|LogLevel::* $level */ public function log($level, string|\Stringable $message, array $context = []): void { if (!$level instanceof Level) { if (!\is_string($level) && !\is_int($level)) { throw new \InvalidArgumentException('$level is expected to be a string, int or '.Level::class.' instance'); } if (isset(self::RFC_5424_LEVELS[$level])) { $level = self::RFC_5424_LEVELS[$level]; } $level = static::toMonologLevel($level); } $this->addRecord($level, (string) $message, $context); } /** * Adds a log record at the DEBUG level. * * This method allows for compatibility with common interfaces. * * @param string|Stringable $message The log message * @param mixed[] $context The log context */ public function debug(string|\Stringable $message, array $context = []): void { $this->addRecord(Level::Debug, (string) $message, $context); } /** * Adds a log record at the INFO level. * * This method allows for compatibility with common interfaces. * * @param string|Stringable $message The log message * @param mixed[] $context The log context */ public function info(string|\Stringable $message, array $context = []): void { $this->addRecord(Level::Info, (string) $message, $context); } /** * Adds a log record at the NOTICE level. * * This method allows for compatibility with common interfaces. * * @param string|Stringable $message The log message * @param mixed[] $context The log context */ public function notice(string|\Stringable $message, array $context = []): void { $this->addRecord(Level::Notice, (string) $message, $context); } /** * Adds a log record at the WARNING level. * * This method allows for compatibility with common interfaces. * * @param string|Stringable $message The log message * @param mixed[] $context The log context */ public function warning(string|\Stringable $message, array $context = []): void { $this->addRecord(Level::Warning, (string) $message, $context); } /** * Adds a log record at the ERROR level. * * This method allows for compatibility with common interfaces. * * @param string|Stringable $message The log message * @param mixed[] $context The log context */ public function error(string|\Stringable $message, array $context = []): void { $this->addRecord(Level::Error, (string) $message, $context); } /** * Adds a log record at the CRITICAL level. * * This method allows for compatibility with common interfaces. * * @param string|Stringable $message The log message * @param mixed[] $context The log context */ public function critical(string|\Stringable $message, array $context = []): void { $this->addRecord(Level::Critical, (string) $message, $context); } /** * Adds a log record at the ALERT level. * * This method allows for compatibility with common interfaces. * * @param string|Stringable $message The log message * @param mixed[] $context The log context */ public function alert(string|\Stringable $message, array $context = []): void { $this->addRecord(Level::Alert, (string) $message, $context); } /** * Adds a log record at the EMERGENCY level. * * This method allows for compatibility with common interfaces. * * @param string|Stringable $message The log message * @param mixed[] $context The log context */ public function emergency(string|\Stringable $message, array $context = []): void { $this->addRecord(Level::Emergency, (string) $message, $context); } /** * Sets the timezone to be used for the timestamp of log records. * * @return $this */ public function setTimezone(DateTimeZone $tz): self { $this->timezone = $tz; return $this; } /** * Returns the timezone to be used for the timestamp of log records. */ public function getTimezone(): DateTimeZone { return $this->timezone; } /** * Delegates exception management to the custom exception handler, * or throws the exception if no custom handler is set. */ protected function handleException(Throwable $e, LogRecord $record): void { if (null === $this->exceptionHandler) { throw $e; } ($this->exceptionHandler)($e, $record); } /** * @return array */ public function __serialize(): array { return [ 'name' => $this->name, 'handlers' => $this->handlers, 'processors' => $this->processors, 'microsecondTimestamps' => $this->microsecondTimestamps, 'timezone' => $this->timezone, 'exceptionHandler' => $this->exceptionHandler, 'logDepth' => $this->logDepth, 'detectCycles' => $this->detectCycles, ]; } /** * @param array $data */ public function __unserialize(array $data): void { foreach (['name', 'handlers', 'processors', 'microsecondTimestamps', 'timezone', 'exceptionHandler', 'logDepth', 'detectCycles'] as $property) { if (isset($data[$property])) { $this->$property = $data[$property]; } } $this->fiberLogDepth = new \WeakMap(); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Processor/ClosureContextProcessor.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Processor; use Monolog\LogRecord; /** * Generates a context from a Closure if the Closure is the only value * in the context * * It helps reduce the performance impact of debug logs if they do * need to create lots of context information. If this processor is added * on the correct handler the context data will only be generated * when the logs are actually logged to that handler, which is useful when * using FingersCrossedHandler or other filtering handlers to conditionally * log records. */ class ClosureContextProcessor implements ProcessorInterface { public function __invoke(LogRecord $record): LogRecord { $context = $record->context; if (isset($context[0]) && 1 === \count($context) && $context[0] instanceof \Closure) { try { $context = $context[0](); } catch (\Throwable $e) { $context = [ 'error_on_context_generation' => $e->getMessage(), 'exception' => $e, ]; } if (!\is_array($context)) { $context = [$context]; } $record = $record->with(context: $context); } return $record; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Processor/GitProcessor.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Processor; use Monolog\Level; use Monolog\Logger; use Psr\Log\LogLevel; use Monolog\LogRecord; /** * Injects Git branch and Git commit SHA in all records * * @author Nick Otter * @author Jordi Boggiano */ class GitProcessor implements ProcessorInterface { private Level $level; /** @var array{branch: string, commit: string}|array|null */ private static $cache = null; /** * @param int|string|Level|LogLevel::* $level The minimum logging level at which this Processor will be triggered * * @phpstan-param value-of|value-of|Level|LogLevel::* $level */ public function __construct(int|string|Level $level = Level::Debug) { $this->level = Logger::toMonologLevel($level); } /** * @inheritDoc */ public function __invoke(LogRecord $record): LogRecord { // return if the level is not high enough if ($record->level->isLowerThan($this->level)) { return $record; } $record->extra['git'] = self::getGitInfo(); return $record; } /** * @return array{branch: string, commit: string}|array */ private static function getGitInfo(): array { if (self::$cache !== null) { return self::$cache; } $branches = shell_exec('git branch -v --no-abbrev'); if (\is_string($branches) && 1 === preg_match('{^\* (.+?)\s+([a-f0-9]{40})(?:\s|$)}m', $branches, $matches)) { return self::$cache = [ 'branch' => $matches[1], 'commit' => $matches[2], ]; } return self::$cache = []; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Processor/HostnameProcessor.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Processor; use Monolog\LogRecord; /** * Injects value of gethostname in all records */ class HostnameProcessor implements ProcessorInterface { private static string $host; public function __construct() { self::$host = (string) gethostname(); } /** * @inheritDoc */ public function __invoke(LogRecord $record): LogRecord { $record->extra['hostname'] = self::$host; return $record; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Processor/IntrospectionProcessor.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Processor; use Monolog\Level; use Monolog\Logger; use Psr\Log\LogLevel; use Monolog\LogRecord; /** * Injects line/file:class/function where the log message came from * * Warning: This only works if the handler processes the logs directly. * If you put the processor on a handler that is behind a FingersCrossedHandler * for example, the processor will only be called once the trigger level is reached, * and all the log records will have the same file/line/.. data from the call that * triggered the FingersCrossedHandler. * * @author Jordi Boggiano */ class IntrospectionProcessor implements ProcessorInterface { protected Level $level; /** @var string[] */ protected array $skipClassesPartials; protected int $skipStackFramesCount; protected const SKIP_FUNCTIONS = [ 'call_user_func', 'call_user_func_array', ]; protected const SKIP_CLASSES = [ 'Monolog\\', ]; /** * @param string|int|Level $level The minimum logging level at which this Processor will be triggered * @param string[] $skipClassesPartials * * @phpstan-param value-of|value-of|Level|LogLevel::* $level */ public function __construct(int|string|Level $level = Level::Debug, array $skipClassesPartials = [], int $skipStackFramesCount = 0) { $this->level = Logger::toMonologLevel($level); $this->skipClassesPartials = array_merge(static::SKIP_CLASSES, $skipClassesPartials); $this->skipStackFramesCount = $skipStackFramesCount; } /** * @inheritDoc */ public function __invoke(LogRecord $record): LogRecord { // return if the level is not high enough if ($record->level->isLowerThan($this->level)) { return $record; } $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); // skip first since it's always the current method array_shift($trace); // the call_user_func call is also skipped array_shift($trace); $i = 0; while ($this->isTraceClassOrSkippedFunction($trace, $i)) { if (isset($trace[$i]['class'])) { foreach ($this->skipClassesPartials as $part) { if (strpos($trace[$i]['class'], $part) !== false) { $i++; continue 2; } } } elseif (\in_array($trace[$i]['function'], self::SKIP_FUNCTIONS, true)) { $i++; continue; } break; } $i += $this->skipStackFramesCount; // we should have the call source now $record->extra = array_merge( $record->extra, [ 'file' => $trace[$i - 1]['file'] ?? null, 'line' => $trace[$i - 1]['line'] ?? null, 'class' => $trace[$i]['class'] ?? null, 'callType' => $trace[$i]['type'] ?? null, 'function' => $trace[$i]['function'] ?? null, ] ); return $record; } /** * @param array $trace */ private function isTraceClassOrSkippedFunction(array $trace, int $index): bool { if (!isset($trace[$index])) { return false; } return isset($trace[$index]['class']) || \in_array($trace[$index]['function'], self::SKIP_FUNCTIONS, true); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Processor/LoadAverageProcessor.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Processor; use Monolog\LogRecord; /** * Injects sys_getloadavg in all records @see https://www.php.net/manual/en/function.sys-getloadavg.php * * @author Johan Vlaar */ class LoadAverageProcessor implements ProcessorInterface { public const LOAD_1_MINUTE = 0; public const LOAD_5_MINUTE = 1; public const LOAD_15_MINUTE = 2; private const AVAILABLE_LOAD = [ self::LOAD_1_MINUTE, self::LOAD_5_MINUTE, self::LOAD_15_MINUTE, ]; /** * @var int */ protected $avgSystemLoad; /** * @param self::LOAD_* $avgSystemLoad */ public function __construct(int $avgSystemLoad = self::LOAD_1_MINUTE) { if (!\in_array($avgSystemLoad, self::AVAILABLE_LOAD, true)) { throw new \InvalidArgumentException(sprintf('Invalid average system load: `%s`', $avgSystemLoad)); } $this->avgSystemLoad = $avgSystemLoad; } /** * {@inheritDoc} */ public function __invoke(LogRecord $record): LogRecord { if (!\function_exists('sys_getloadavg')) { return $record; } $usage = sys_getloadavg(); if (false === $usage) { return $record; } $record->extra['load_average'] = $usage[$this->avgSystemLoad]; return $record; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Processor/MemoryPeakUsageProcessor.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Processor; use Monolog\LogRecord; /** * Injects memory_get_peak_usage in all records * * @see Monolog\Processor\MemoryProcessor::__construct() for options * @author Rob Jensen */ class MemoryPeakUsageProcessor extends MemoryProcessor { /** * @inheritDoc */ public function __invoke(LogRecord $record): LogRecord { $usage = memory_get_peak_usage($this->realUsage); if ($this->useFormatting) { $usage = $this->formatBytes($usage); } $record->extra['memory_peak_usage'] = $usage; return $record; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Processor/MemoryProcessor.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Processor; /** * Some methods that are common for all memory processors * * @author Rob Jensen */ abstract class MemoryProcessor implements ProcessorInterface { /** * @var bool If true, get the real size of memory allocated from system. Else, only the memory used by emalloc() is reported. */ protected bool $realUsage; /** * @var bool If true, then format memory size to human readable string (MB, KB, B depending on size) */ protected bool $useFormatting; /** * @param bool $realUsage Set this to true to get the real size of memory allocated from system. * @param bool $useFormatting If true, then format memory size to human readable string (MB, KB, B depending on size) */ public function __construct(bool $realUsage = true, bool $useFormatting = true) { $this->realUsage = $realUsage; $this->useFormatting = $useFormatting; } /** * Formats bytes into a human readable string if $this->useFormatting is true, otherwise return $bytes as is * * @return string|int Formatted string if $this->useFormatting is true, otherwise return $bytes as int */ protected function formatBytes(int $bytes) { if (!$this->useFormatting) { return $bytes; } if ($bytes > 1024 * 1024) { return round($bytes / 1024 / 1024, 2).' MB'; } elseif ($bytes > 1024) { return round($bytes / 1024, 2).' KB'; } return $bytes . ' B'; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Processor/MemoryUsageProcessor.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Processor; use Monolog\LogRecord; /** * Injects memory_get_usage in all records * * @see Monolog\Processor\MemoryProcessor::__construct() for options * @author Rob Jensen */ class MemoryUsageProcessor extends MemoryProcessor { /** * @inheritDoc */ public function __invoke(LogRecord $record): LogRecord { $usage = memory_get_usage($this->realUsage); if ($this->useFormatting) { $usage = $this->formatBytes($usage); } $record->extra['memory_usage'] = $usage; return $record; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Processor/MercurialProcessor.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Processor; use Monolog\Level; use Monolog\Logger; use Psr\Log\LogLevel; use Monolog\LogRecord; /** * Injects Hg branch and Hg revision number in all records * * @author Jonathan A. Schweder */ class MercurialProcessor implements ProcessorInterface { private Level $level; /** @var array{branch: string, revision: string}|array|null */ private static $cache = null; /** * @param int|string|Level $level The minimum logging level at which this Processor will be triggered * * @phpstan-param value-of|value-of|Level|LogLevel::* $level */ public function __construct(int|string|Level $level = Level::Debug) { $this->level = Logger::toMonologLevel($level); } /** * @inheritDoc */ public function __invoke(LogRecord $record): LogRecord { // return if the level is not high enough if ($record->level->isLowerThan($this->level)) { return $record; } $record->extra['hg'] = self::getMercurialInfo(); return $record; } /** * @return array{branch: string, revision: string}|array */ private static function getMercurialInfo(): array { if (self::$cache !== null) { return self::$cache; } $result = explode(' ', trim((string) shell_exec('hg id -nb'))); if (\count($result) >= 3) { return self::$cache = [ 'branch' => $result[1], 'revision' => $result[2], ]; } if (\count($result) === 2) { return self::$cache = [ 'branch' => $result[1], 'revision' => $result[0], ]; } return self::$cache = []; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Processor/ProcessIdProcessor.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Processor; use Monolog\LogRecord; /** * Adds value of getmypid into records * * @author Andreas Hörnicke */ class ProcessIdProcessor implements ProcessorInterface { /** * @inheritDoc */ public function __invoke(LogRecord $record): LogRecord { $record->extra['process_id'] = getmypid(); return $record; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Processor/ProcessorInterface.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Processor; use Monolog\LogRecord; /** * An optional interface to allow labelling Monolog processors. * * @author Nicolas Grekas */ interface ProcessorInterface { /** * @return LogRecord The processed record */ public function __invoke(LogRecord $record); } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Processor/PsrLogMessageProcessor.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Processor; use Monolog\Utils; use Monolog\LogRecord; /** * Processes a record's message according to PSR-3 rules * * It replaces {foo} with the value from $context['foo'] * * @author Jordi Boggiano */ class PsrLogMessageProcessor implements ProcessorInterface { public const SIMPLE_DATE = "Y-m-d\TH:i:s.uP"; private ?string $dateFormat; private bool $removeUsedContextFields; /** * @param string|null $dateFormat The format of the timestamp: one supported by DateTime::format * @param bool $removeUsedContextFields If set to true the fields interpolated into message gets unset */ public function __construct(?string $dateFormat = null, bool $removeUsedContextFields = false) { $this->dateFormat = $dateFormat; $this->removeUsedContextFields = $removeUsedContextFields; } /** * @inheritDoc */ public function __invoke(LogRecord $record): LogRecord { if (false === strpos($record->message, '{')) { return $record; } $replacements = []; $context = $record->context; foreach ($context as $key => $val) { $placeholder = '{' . $key . '}'; if (strpos($record->message, $placeholder) === false) { continue; } if (null === $val || \is_scalar($val) || (\is_object($val) && method_exists($val, "__toString"))) { $replacements[$placeholder] = $val; } elseif ($val instanceof \DateTimeInterface) { if (null === $this->dateFormat && $val instanceof \Monolog\JsonSerializableDateTimeImmutable) { // handle monolog dates using __toString if no specific dateFormat was asked for // so that it follows the useMicroseconds flag $replacements[$placeholder] = (string) $val; } else { $replacements[$placeholder] = $val->format($this->dateFormat ?? static::SIMPLE_DATE); } } elseif ($val instanceof \UnitEnum) { $replacements[$placeholder] = $val instanceof \BackedEnum ? $val->value : $val->name; } elseif (\is_object($val)) { $replacements[$placeholder] = '[object '.Utils::getClass($val).']'; } elseif (\is_array($val)) { $replacements[$placeholder] = 'array'.Utils::jsonEncode($val, null, true); } else { $replacements[$placeholder] = '['.\gettype($val).']'; } if ($this->removeUsedContextFields) { unset($context[$key]); } } return $record->with(message: strtr($record->message, $replacements), context: $context); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Processor/TagProcessor.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Processor; use Monolog\LogRecord; /** * Adds a tags array into record * * @author Martijn Riemers */ class TagProcessor implements ProcessorInterface { /** @var string[] */ private array $tags; /** * @param string[] $tags */ public function __construct(array $tags = []) { $this->setTags($tags); } /** * @param string[] $tags * @return $this */ public function addTags(array $tags = []): self { $this->tags = array_merge($this->tags, $tags); return $this; } /** * @param string[] $tags * @return $this */ public function setTags(array $tags = []): self { $this->tags = $tags; return $this; } /** * @inheritDoc */ public function __invoke(LogRecord $record): LogRecord { $record->extra['tags'] = $this->tags; return $record; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Processor/UidProcessor.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Processor; use Monolog\ResettableInterface; use Monolog\LogRecord; /** * Adds a unique identifier into records * * @author Simon Mönch */ class UidProcessor implements ProcessorInterface, ResettableInterface { /** @var non-empty-string */ private string $uid; /** * @param int<1, 32> $length */ public function __construct(int $length = 7) { if ($length > 32 || $length < 1) { throw new \InvalidArgumentException('The uid length must be an integer between 1 and 32'); } $this->uid = $this->generateUid($length); } /** * @inheritDoc */ public function __invoke(LogRecord $record): LogRecord { $record->extra['uid'] = $this->uid; return $record; } public function getUid(): string { return $this->uid; } public function reset(): void { $this->uid = $this->generateUid(\strlen($this->uid)); } /** * @param positive-int $length * @return non-empty-string */ private function generateUid(int $length): string { return substr(bin2hex(random_bytes((int) ceil($length / 2))), 0, $length); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Processor/WebProcessor.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Processor; use ArrayAccess; use Monolog\LogRecord; /** * Injects url/method and remote IP of the current web request in all records * * @author Jordi Boggiano */ class WebProcessor implements ProcessorInterface { /** * @var array|ArrayAccess */ protected array|ArrayAccess $serverData; /** * Default fields * * Array is structured as [key in record.extra => key in $serverData] * * @var array */ protected array $extraFields = [ 'url' => 'REQUEST_URI', 'ip' => 'REMOTE_ADDR', 'http_method' => 'REQUEST_METHOD', 'server' => 'SERVER_NAME', 'referrer' => 'HTTP_REFERER', 'user_agent' => 'HTTP_USER_AGENT', ]; /** * @param array|ArrayAccess|null $serverData Array or object w/ ArrayAccess that provides access to the $_SERVER data * @param array|array|null $extraFields Field names and the related key inside $serverData to be added (or just a list of field names to use the default configured $serverData mapping). If not provided it defaults to: [url, ip, http_method, server, referrer] + unique_id if present in server data */ public function __construct(array|ArrayAccess|null $serverData = null, array|null $extraFields = null) { if (null === $serverData) { $this->serverData = &$_SERVER; } else { $this->serverData = $serverData; } $defaultEnabled = ['url', 'ip', 'http_method', 'server', 'referrer']; if (isset($this->serverData['UNIQUE_ID'])) { $this->extraFields['unique_id'] = 'UNIQUE_ID'; $defaultEnabled[] = 'unique_id'; } if (null === $extraFields) { $extraFields = $defaultEnabled; } if (isset($extraFields[0])) { foreach (array_keys($this->extraFields) as $fieldName) { if (!\in_array($fieldName, $extraFields, true)) { unset($this->extraFields[$fieldName]); } } } else { $this->extraFields = $extraFields; } } /** * @inheritDoc */ public function __invoke(LogRecord $record): LogRecord { // skip processing if for some reason request data // is not present (CLI or wonky SAPIs) if (!isset($this->serverData['REQUEST_URI'])) { return $record; } $record->extra = $this->appendExtraFields($record->extra); return $record; } /** * @return $this */ public function addExtraField(string $extraName, string $serverName): self { $this->extraFields[$extraName] = $serverName; return $this; } /** * @param mixed[] $extra * @return mixed[] */ private function appendExtraFields(array $extra): array { foreach ($this->extraFields as $extraName => $serverName) { $extra[$extraName] = $this->serverData[$serverName] ?? null; } return $extra; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Registry.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog; use InvalidArgumentException; /** * Monolog log registry * * Allows to get `Logger` instances in the global scope * via static method calls on this class. * * * $application = new Monolog\Logger('application'); * $api = new Monolog\Logger('api'); * * Monolog\Registry::addLogger($application); * Monolog\Registry::addLogger($api); * * function testLogger() * { * Monolog\Registry::api()->error('Sent to $api Logger instance'); * Monolog\Registry::application()->error('Sent to $application Logger instance'); * } * * * @author Tomas Tatarko */ class Registry { /** * List of all loggers in the registry (by named indexes) * * @var Logger[] */ private static array $loggers = []; /** * Adds new logging channel to the registry * * @param Logger $logger Instance of the logging channel * @param string|null $name Name of the logging channel ($logger->getName() by default) * @param bool $overwrite Overwrite instance in the registry if the given name already exists? * @throws \InvalidArgumentException If $overwrite set to false and named Logger instance already exists */ public static function addLogger(Logger $logger, ?string $name = null, bool $overwrite = false): void { $name = $name ?? $logger->getName(); if (isset(self::$loggers[$name]) && !$overwrite) { throw new InvalidArgumentException('Logger with the given name already exists'); } self::$loggers[$name] = $logger; } /** * Checks if such logging channel exists by name or instance * * @param string|Logger $logger Name or logger instance */ public static function hasLogger($logger): bool { if ($logger instanceof Logger) { $index = array_search($logger, self::$loggers, true); return false !== $index; } return isset(self::$loggers[$logger]); } /** * Removes instance from registry by name or instance * * @param string|Logger $logger Name or logger instance */ public static function removeLogger($logger): void { if ($logger instanceof Logger) { if (false !== ($idx = array_search($logger, self::$loggers, true))) { unset(self::$loggers[$idx]); } } else { unset(self::$loggers[$logger]); } } /** * Clears the registry */ public static function clear(): void { self::$loggers = []; } /** * Gets Logger instance from the registry * * @param string $name Name of the requested Logger instance * @throws \InvalidArgumentException If named Logger instance is not in the registry */ public static function getInstance(string $name): Logger { if (!isset(self::$loggers[$name])) { throw new InvalidArgumentException(sprintf('Requested "%s" logger instance is not in the registry', $name)); } return self::$loggers[$name]; } /** * Gets Logger instance from the registry via static method call * * @param string $name Name of the requested Logger instance * @param mixed[] $arguments Arguments passed to static method call * @throws \InvalidArgumentException If named Logger instance is not in the registry * @return Logger Requested instance of Logger */ public static function __callStatic(string $name, array $arguments): Logger { return self::getInstance($name); } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/ResettableInterface.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog; /** * Handler or Processor implementing this interface will be reset when Logger::reset() is called. * * Resetting ends a log cycle gets them back to their initial state. * * Resetting a Handler or a Processor means flushing/cleaning all buffers, resetting internal * state, and getting it back to a state in which it can receive log records again. * * This is useful in case you want to avoid logs leaking between two requests or jobs when you * have a long running process like a worker or an application server serving multiple requests * in one process. * * @author Grégoire Pineau */ interface ResettableInterface { public function reset(): void; } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/SignalHandler.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog; use Psr\Log\LoggerInterface; use Psr\Log\LogLevel; use ReflectionExtension; /** * Monolog POSIX signal handler * * @author Robert Gust-Bardon */ class SignalHandler { private LoggerInterface $logger; /** @var array SIG_DFL, SIG_IGN or previous callable */ private array $previousSignalHandler = []; /** @var array */ private array $signalLevelMap = []; /** @var array */ private array $signalRestartSyscalls = []; public function __construct(LoggerInterface $logger) { $this->logger = $logger; } /** * @param int|string|Level $level Level or level name * @return $this * * @phpstan-param value-of|value-of|Level|LogLevel::* $level */ public function registerSignalHandler(int $signo, int|string|Level $level = LogLevel::CRITICAL, bool $callPrevious = true, bool $restartSyscalls = true, ?bool $async = true): self { if (!\extension_loaded('pcntl') || !\function_exists('pcntl_signal')) { return $this; } $level = Logger::toMonologLevel($level)->toPsrLogLevel(); if ($callPrevious) { $handler = pcntl_signal_get_handler($signo); $this->previousSignalHandler[$signo] = $handler; } else { unset($this->previousSignalHandler[$signo]); } $this->signalLevelMap[$signo] = $level; $this->signalRestartSyscalls[$signo] = $restartSyscalls; if ($async !== null) { pcntl_async_signals($async); } pcntl_signal($signo, [$this, 'handleSignal'], $restartSyscalls); return $this; } /** * @param mixed $siginfo */ public function handleSignal(int $signo, $siginfo = null): void { /** @var array $signals */ static $signals = []; if (\count($signals) === 0 && \extension_loaded('pcntl')) { $pcntl = new ReflectionExtension('pcntl'); foreach ($pcntl->getConstants() as $name => $value) { if (substr($name, 0, 3) === 'SIG' && $name[3] !== '_' && \is_int($value)) { $signals[$value] = $name; } } } $level = $this->signalLevelMap[$signo] ?? LogLevel::CRITICAL; $signal = $signals[$signo] ?? $signo; $context = $siginfo ?? []; $this->logger->log($level, sprintf('Program received signal %s', $signal), $context); if (!isset($this->previousSignalHandler[$signo])) { return; } if ($this->previousSignalHandler[$signo] === SIG_DFL) { if (\extension_loaded('pcntl') && \function_exists('pcntl_signal') && \function_exists('pcntl_sigprocmask') && \function_exists('pcntl_signal_dispatch') && \extension_loaded('posix') && \function_exists('posix_getpid') && \function_exists('posix_kill') ) { $restartSyscalls = $this->signalRestartSyscalls[$signo] ?? true; pcntl_signal($signo, SIG_DFL, $restartSyscalls); pcntl_sigprocmask(SIG_UNBLOCK, [$signo], $oldset); posix_kill(posix_getpid(), $signo); pcntl_signal_dispatch(); pcntl_sigprocmask(SIG_SETMASK, $oldset); pcntl_signal($signo, [$this, 'handleSignal'], $restartSyscalls); } } elseif (\is_callable($this->previousSignalHandler[$signo])) { $this->previousSignalHandler[$signo]($signo, $siginfo); } } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Test/MonologTestCase.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Test; use Monolog\Level; use Monolog\Logger; use Monolog\LogRecord; use Monolog\JsonSerializableDateTimeImmutable; use Monolog\Formatter\FormatterInterface; use Psr\Log\LogLevel; /** * Lets you easily generate log records and a dummy formatter for testing purposes * * @author Jordi Boggiano */ class MonologTestCase extends \PHPUnit\Framework\TestCase { /** * @param array $context * @param array $extra * * @phpstan-param value-of|value-of|Level|LogLevel::* $level */ protected function getRecord(int|string|Level $level = Level::Warning, string|\Stringable $message = 'test', array $context = [], string $channel = 'test', \DateTimeImmutable $datetime = new JsonSerializableDateTimeImmutable(true), array $extra = []): LogRecord { return new LogRecord( message: (string) $message, context: $context, level: Logger::toMonologLevel($level), channel: $channel, datetime: $datetime, extra: $extra, ); } /** * @phpstan-return list */ protected function getMultipleRecords(): array { return [ $this->getRecord(Level::Debug, 'debug message 1'), $this->getRecord(Level::Debug, 'debug message 2'), $this->getRecord(Level::Info, 'information'), $this->getRecord(Level::Warning, 'warning'), $this->getRecord(Level::Error, 'error'), ]; } protected function getIdentityFormatter(): FormatterInterface { $formatter = $this->createMock(FormatterInterface::class); $formatter->expects(self::any()) ->method('format') ->willReturnCallback(function ($record) { return $record->message; }); return $formatter; } } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Test/TestCase.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Test; /** * Lets you easily generate log records and a dummy formatter for testing purposes * * @author Jordi Boggiano * * @deprecated use MonologTestCase instead. */ class TestCase extends MonologTestCase { } ================================================ FILE: lib/Google/vendor/monolog/monolog/src/Monolog/Utils.php ================================================ * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog; final class Utils { const DEFAULT_JSON_FLAGS = JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRESERVE_ZERO_FRACTION | JSON_INVALID_UTF8_SUBSTITUTE | JSON_PARTIAL_OUTPUT_ON_ERROR; public static function getClass(object $object): string { $class = \get_class($object); if (false === ($pos = strpos($class, "@anonymous\0"))) { return $class; } if (false === ($parent = get_parent_class($class))) { return substr($class, 0, $pos + 10); } return $parent . '@anonymous'; } public static function substr(string $string, int $start, ?int $length = null): string { if (\extension_loaded('mbstring')) { return mb_strcut($string, $start, $length); } return substr($string, $start, (null === $length) ? \strlen($string) : $length); } /** * Makes sure if a relative path is passed in it is turned into an absolute path * * @param string $streamUrl stream URL or path without protocol */ public static function canonicalizePath(string $streamUrl): string { $prefix = ''; if ('file://' === substr($streamUrl, 0, 7)) { $streamUrl = substr($streamUrl, 7); $prefix = 'file://'; } // other type of stream, not supported if (false !== strpos($streamUrl, '://')) { return $streamUrl; } // already absolute if (substr($streamUrl, 0, 1) === '/' || substr($streamUrl, 1, 1) === ':' || substr($streamUrl, 0, 2) === '\\\\') { return $prefix.$streamUrl; } $streamUrl = getcwd() . '/' . $streamUrl; return $prefix.$streamUrl; } /** * Return the JSON representation of a value * * @param mixed $data * @param int $encodeFlags flags to pass to json encode, defaults to DEFAULT_JSON_FLAGS * @param bool $ignoreErrors whether to ignore encoding errors or to throw on error, when ignored and the encoding fails, "null" is returned which is valid json for null * @throws \RuntimeException if encoding fails and errors are not ignored * @return string when errors are ignored and the encoding fails, "null" is returned which is valid json for null */ public static function jsonEncode($data, ?int $encodeFlags = null, bool $ignoreErrors = false): string { if (null === $encodeFlags) { $encodeFlags = self::DEFAULT_JSON_FLAGS; } if ($ignoreErrors) { $json = @json_encode($data, $encodeFlags); if (false === $json) { return 'null'; } return $json; } $json = json_encode($data, $encodeFlags); if (false === $json) { $json = self::handleJsonError(json_last_error(), $data); } return $json; } /** * Handle a json_encode failure. * * If the failure is due to invalid string encoding, try to clean the * input and encode again. If the second encoding attempt fails, the * initial error is not encoding related or the input can't be cleaned then * raise a descriptive exception. * * @param int $code return code of json_last_error function * @param mixed $data data that was meant to be encoded * @param int $encodeFlags flags to pass to json encode, defaults to JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRESERVE_ZERO_FRACTION * @throws \RuntimeException if failure can't be corrected * @return string JSON encoded data after error correction */ public static function handleJsonError(int $code, $data, ?int $encodeFlags = null): string { if ($code !== JSON_ERROR_UTF8) { self::throwEncodeError($code, $data); } if (\is_string($data)) { self::detectAndCleanUtf8($data); } elseif (\is_array($data)) { array_walk_recursive($data, ['Monolog\Utils', 'detectAndCleanUtf8']); } else { self::throwEncodeError($code, $data); } if (null === $encodeFlags) { $encodeFlags = self::DEFAULT_JSON_FLAGS; } $json = json_encode($data, $encodeFlags); if ($json === false) { self::throwEncodeError(json_last_error(), $data); } return $json; } /** * Throws an exception according to a given code with a customized message * * @param int $code return code of json_last_error function * @param mixed $data data that was meant to be encoded * @throws \RuntimeException */ private static function throwEncodeError(int $code, $data): never { $msg = match ($code) { JSON_ERROR_DEPTH => 'Maximum stack depth exceeded', JSON_ERROR_STATE_MISMATCH => 'Underflow or the modes mismatch', JSON_ERROR_CTRL_CHAR => 'Unexpected control character found', JSON_ERROR_UTF8 => 'Malformed UTF-8 characters, possibly incorrectly encoded', default => 'Unknown error', }; throw new \RuntimeException('JSON encoding failed: '.$msg.'. Encoding: '.var_export($data, true)); } /** * Detect invalid UTF-8 string characters and convert to valid UTF-8. * * Valid UTF-8 input will be left unmodified, but strings containing * invalid UTF-8 codepoints will be reencoded as UTF-8 with an assumed * original encoding of ISO-8859-15. This conversion may result in * incorrect output if the actual encoding was not ISO-8859-15, but it * will be clean UTF-8 output and will not rely on expensive and fragile * detection algorithms. * * Function converts the input in place in the passed variable so that it * can be used as a callback for array_walk_recursive. * * @param mixed $data Input to check and convert if needed, passed by ref */ private static function detectAndCleanUtf8(&$data): void { if (\is_string($data) && preg_match('//u', $data) !== 1) { $data = preg_replace_callback( '/[\x80-\xFF]+/', function (array $m): string { return \function_exists('mb_convert_encoding') ? mb_convert_encoding($m[0], 'UTF-8', 'ISO-8859-1') : (\function_exists('utf8_encode') ? utf8_encode($m[0]) : ''); }, $data ); if (!\is_string($data)) { $pcreErrorCode = preg_last_error(); throw new \RuntimeException('Failed to preg_replace_callback: ' . $pcreErrorCode . ' / ' . preg_last_error_msg()); } $data = str_replace( ['¤', '¦', '¨', '´', '¸', '¼', '½', '¾'], ['€', 'Š', 'š', 'Ž', 'ž', 'Œ', 'œ', 'Ÿ'], $data ); } } /** * Converts a string with a valid 'memory_limit' format, to bytes. * * @param string|false $val * @return int|false Returns an integer representing bytes. Returns FALSE in case of error. */ public static function expandIniShorthandBytes($val) { if (!\is_string($val)) { return false; } // support -1 if ((int) $val < 0) { return (int) $val; } if (!(bool) preg_match('/^\s*(?\d+)(?:\.\d+)?\s*(?[gmk]?)\s*$/i', $val, $match)) { return false; } $val = (int) $match['val']; switch (strtolower($match['unit'])) { case 'g': $val *= 1024; // no break case 'm': $val *= 1024; // no break case 'k': $val *= 1024; } return $val; } public static function getRecordMessageForException(LogRecord $record): string { $context = ''; $extra = ''; try { if (\count($record->context) > 0) { $context = "\nContext: " . json_encode($record->context, JSON_THROW_ON_ERROR); } if (\count($record->extra) > 0) { $extra = "\nExtra: " . json_encode($record->extra, JSON_THROW_ON_ERROR); } } catch (\Throwable $e) { // noop } return "\nThe exception occurred while attempting to log: " . $record->message . $context . $extra; } } ================================================ FILE: lib/Google/vendor/paragonie/constant_time_encoding/LICENSE.txt ================================================ The MIT License (MIT) Copyright (c) 2016 - 2022 Paragon Initiative Enterprises 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. ------------------------------------------------------------------------------ This library was based on the work of Steve "Sc00bz" Thomas. ------------------------------------------------------------------------------ The MIT License (MIT) Copyright (c) 2014 Steve Thomas 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. ================================================ FILE: lib/Google/vendor/paragonie/constant_time_encoding/README.md ================================================ # Constant-Time Encoding [![Build Status](https://github.com/paragonie/constant_time_encoding/actions/workflows/ci.yml/badge.svg)](https://github.com/paragonie/constant_time_encoding/actions) [![Static Analysis](https://github.com/paragonie/constant_time_encoding/actions/workflows/psalm.yml/badge.svg)](https://github.com/paragonie/constant_time_encoding/actions) [![Latest Stable Version](https://poser.pugx.org/paragonie/constant_time_encoding/v/stable)](https://packagist.org/packages/paragonie/constant_time_encoding) [![Latest Unstable Version](https://poser.pugx.org/paragonie/constant_time_encoding/v/unstable)](https://packagist.org/packages/paragonie/constant_time_encoding) [![License](https://poser.pugx.org/paragonie/constant_time_encoding/license)](https://packagist.org/packages/paragonie/constant_time_encoding) [![Downloads](https://img.shields.io/packagist/dt/paragonie/constant_time_encoding.svg)](https://packagist.org/packages/paragonie/constant_time_encoding) Based on the [constant-time base64 implementation made by Steve "Sc00bz" Thomas](https://github.com/Sc00bz/ConstTimeEncoding), this library aims to offer character encoding functions that do not leak information about what you are encoding/decoding via processor cache misses. Further reading on [cache-timing attacks](http://blog.ircmaxell.com/2014/11/its-all-about-time.html). Our fork offers the following enhancements: * `mbstring.func_overload` resistance * Unit tests * Composer- and Packagist-ready * Base16 encoding * Base32 encoding * Uses `pack()` and `unpack()` instead of `chr()` and `ord()` ## PHP Version Requirements Version 3 of this library should work on **PHP 8** or newer. Version 2 of this library should work on **PHP 7** or newer. See [the v2.x branch](https://github.com/paragonie/constant_time_encoding/tree/v2.x). For PHP 5 support, see [the v1.x branch](https://github.com/paragonie/constant_time_encoding/tree/v1.x). If you are adding this as a dependency to a project intended to work on PHP 5 through 8.4, please set the required version to `^1|^2|^3`. ## How to Install ```sh composer require paragonie/constant_time_encoding ``` ## How to Use ```php use ParagonIE\ConstantTime\Encoding; // possibly (if applicable): // require 'vendor/autoload.php'; $data = random_bytes(32); echo Encoding::base64Encode($data), "\n"; echo Encoding::base32EncodeUpper($data), "\n"; echo Encoding::base32Encode($data), "\n"; echo Encoding::hexEncode($data), "\n"; echo Encoding::hexEncodeUpper($data), "\n"; ``` Example output: ``` 1VilPkeVqirlPifk5scbzcTTbMT2clp+Zkyv9VFFasE= 2VMKKPSHSWVCVZJ6E7SONRY3ZXCNG3GE6ZZFU7TGJSX7KUKFNLAQ==== 2vmkkpshswvcvzj6e7sonry3zxcng3ge6zzfu7tgjsx7kukfnlaq==== d558a53e4795aa2ae53e27e4e6c71bcdc4d36cc4f6725a7e664caff551456ac1 D558A53E4795AA2AE53E27E4E6C71BDCC4D36CC4F6725A7E664CAFF551456AC1 ``` If you only need a particular variant, you can just reference the required class like so: ```php use ParagonIE\ConstantTime\Base64; use ParagonIE\ConstantTime\Base32; $data = random_bytes(32); echo Base64::encode($data), "\n"; echo Base32::encode($data), "\n"; ``` Example output: ``` 1VilPkeVqirlPifk5scbzcTTbMT2clp+Zkyv9VFFasE= 2vmkkpshswvcvzj6e7sonry3zxcng3ge6zzfu7tgjsx7kukfnlaq==== ``` ## Support Contracts If your company uses this library in their products or services, you may be interested in [purchasing a support contract from Paragon Initiative Enterprises](https://paragonie.com/enterprise). ================================================ FILE: lib/Google/vendor/paragonie/constant_time_encoding/composer.json ================================================ { "name": "paragonie/constant_time_encoding", "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)", "keywords": [ "base64", "encoding", "rfc4648", "base32", "base16", "hex", "bin2hex", "hex2bin", "base64_encode", "base64_decode", "base32_encode", "base32_decode" ], "license": "MIT", "type": "library", "authors": [ { "name": "Paragon Initiative Enterprises", "email": "security@paragonie.com", "homepage": "https://paragonie.com", "role": "Maintainer" }, { "name": "Steve 'Sc00bz' Thomas", "email": "steve@tobtu.com", "homepage": "https://www.tobtu.com", "role": "Original Developer" } ], "support": { "issues": "https://github.com/paragonie/constant_time_encoding/issues", "email": "info@paragonie.com", "source": "https://github.com/paragonie/constant_time_encoding" }, "require": { "php": "^8" }, "require-dev": { "infection/infection": "^0", "nikic/php-fuzzer": "^0", "phpunit/phpunit": "^9|^10|^11", "vimeo/psalm": "^4|^5|^6" }, "autoload": { "psr-4": { "ParagonIE\\ConstantTime\\": "src/" } }, "autoload-dev": { "psr-4": { "ParagonIE\\ConstantTime\\Tests\\": "tests/" } }, "scripts": { "mutation-test": "infection" }, "config": { "process-timeout": 0, "allow-plugins": { "infection/extension-installer": true } } } ================================================ FILE: lib/Google/vendor/paragonie/constant_time_encoding/src/Base32.php ================================================ 96 && $src < 123) $ret += $src - 97 + 1; // -64 $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 96); // if ($src > 0x31 && $src < 0x38) $ret += $src - 24 + 1; // -23 $ret += (((0x31 - $src) & ($src - 0x38)) >> 8) & ($src - 23); return $ret; } /** * Uses bitwise operators instead of table-lookups to turn 5-bit integers * into 8-bit integers. * * Uppercase variant. * * @param int $src * @return int * @api */ protected static function decode5BitsUpper(int $src): int { $ret = -1; // if ($src > 64 && $src < 91) $ret += $src - 65 + 1; // -64 $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 64); // if ($src > 0x31 && $src < 0x38) $ret += $src - 24 + 1; // -23 $ret += (((0x31 - $src) & ($src - 0x38)) >> 8) & ($src - 23); return $ret; } /** * Uses bitwise operators instead of table-lookups to turn 8-bit integers * into 5-bit integers. * * @param int $src * @return string * @api */ protected static function encode5Bits(int $src): string { $diff = 0x61; // if ($src > 25) $ret -= 72; $diff -= ((25 - $src) >> 8) & 73; return pack('C', $src + $diff); } /** * Uses bitwise operators instead of table-lookups to turn 8-bit integers * into 5-bit integers. * * Uppercase variant. * * @param int $src * @return string * @api */ protected static function encode5BitsUpper(int $src): string { $diff = 0x41; // if ($src > 25) $ret -= 40; $diff -= ((25 - $src) >> 8) & 41; return pack('C', $src + $diff); } /** * @param string $encodedString * @param bool $upper * @return string * @api */ public static function decodeNoPadding( #[SensitiveParameter] string $encodedString, bool $upper = false ): string { $srcLen = strlen($encodedString); if ($srcLen === 0) { return ''; } if (($srcLen & 7) === 0) { for ($j = 0; $j < 7 && $j < $srcLen; ++$j) { if ($encodedString[$srcLen - $j - 1] === '=') { throw new InvalidArgumentException( "decodeNoPadding() doesn't tolerate padding" ); } } } return static::doDecode( $encodedString, $upper, true ); } /** * Base32 decoding * * @param string $src * @param bool $upper * @param bool $strictPadding * @return string * * @throws TypeError */ protected static function doDecode( #[SensitiveParameter] string $src, bool $upper = false, bool $strictPadding = false ): string { // We do this to reduce code duplication: $method = $upper ? 'decode5BitsUpper' : 'decode5Bits'; // Remove padding $srcLen = strlen($src); if ($srcLen === 0) { return ''; } if ($strictPadding) { if (($srcLen & 7) === 0) { for ($j = 0; $j < 7; ++$j) { if ($src[$srcLen - 1] === '=') { $srcLen--; } else { break; } } } if (($srcLen & 7) === 1) { throw new RangeException( 'Incorrect padding' ); } } else { $src = rtrim($src, '='); $srcLen = strlen($src); } $err = 0; $dest = ''; // Main loop (no padding): for ($i = 0; $i + 8 <= $srcLen; $i += 8) { /** @var array $chunk */ $chunk = unpack('C*', substr($src, $i, 8)); /** @var int $c0 */ $c0 = static::$method($chunk[1]); /** @var int $c1 */ $c1 = static::$method($chunk[2]); /** @var int $c2 */ $c2 = static::$method($chunk[3]); /** @var int $c3 */ $c3 = static::$method($chunk[4]); /** @var int $c4 */ $c4 = static::$method($chunk[5]); /** @var int $c5 */ $c5 = static::$method($chunk[6]); /** @var int $c6 */ $c6 = static::$method($chunk[7]); /** @var int $c7 */ $c7 = static::$method($chunk[8]); $dest .= pack( 'CCCCC', (($c0 << 3) | ($c1 >> 2) ) & 0xff, (($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff, (($c3 << 4) | ($c4 >> 1) ) & 0xff, (($c4 << 7) | ($c5 << 2) | ($c6 >> 3)) & 0xff, (($c6 << 5) | ($c7 ) ) & 0xff ); $err |= ($c0 | $c1 | $c2 | $c3 | $c4 | $c5 | $c6 | $c7) >> 8; } // The last chunk, which may have padding: if ($i < $srcLen) { /** @var array $chunk */ $chunk = unpack('C*', substr($src, $i, $srcLen - $i)); /** @var int $c0 */ $c0 = static::$method($chunk[1]); if ($i + 6 < $srcLen) { /** @var int $c1 */ $c1 = static::$method($chunk[2]); /** @var int $c2 */ $c2 = static::$method($chunk[3]); /** @var int $c3 */ $c3 = static::$method($chunk[4]); /** @var int $c4 */ $c4 = static::$method($chunk[5]); /** @var int $c5 */ $c5 = static::$method($chunk[6]); /** @var int $c6 */ $c6 = static::$method($chunk[7]); $dest .= pack( 'CCCC', (($c0 << 3) | ($c1 >> 2) ) & 0xff, (($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff, (($c3 << 4) | ($c4 >> 1) ) & 0xff, (($c4 << 7) | ($c5 << 2) | ($c6 >> 3)) & 0xff ); $err |= ($c0 | $c1 | $c2 | $c3 | $c4 | $c5 | $c6) >> 8; if ($strictPadding) { $err |= ($c6 << 5) & 0xff; } } elseif ($i + 5 < $srcLen) { /** @var int $c1 */ $c1 = static::$method($chunk[2]); /** @var int $c2 */ $c2 = static::$method($chunk[3]); /** @var int $c3 */ $c3 = static::$method($chunk[4]); /** @var int $c4 */ $c4 = static::$method($chunk[5]); /** @var int $c5 */ $c5 = static::$method($chunk[6]); $dest .= pack( 'CCCC', (($c0 << 3) | ($c1 >> 2) ) & 0xff, (($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff, (($c3 << 4) | ($c4 >> 1) ) & 0xff, (($c4 << 7) | ($c5 << 2) ) & 0xff ); $err |= ($c0 | $c1 | $c2 | $c3 | $c4 | $c5) >> 8; } elseif ($i + 4 < $srcLen) { /** @var int $c1 */ $c1 = static::$method($chunk[2]); /** @var int $c2 */ $c2 = static::$method($chunk[3]); /** @var int $c3 */ $c3 = static::$method($chunk[4]); /** @var int $c4 */ $c4 = static::$method($chunk[5]); $dest .= pack( 'CCC', (($c0 << 3) | ($c1 >> 2) ) & 0xff, (($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff, (($c3 << 4) | ($c4 >> 1) ) & 0xff ); $err |= ($c0 | $c1 | $c2 | $c3 | $c4) >> 8; if ($strictPadding) { $err |= ($c4 << 7) & 0xff; } } elseif ($i + 3 < $srcLen) { /** @var int $c1 */ $c1 = static::$method($chunk[2]); /** @var int $c2 */ $c2 = static::$method($chunk[3]); /** @var int $c3 */ $c3 = static::$method($chunk[4]); $dest .= pack( 'CC', (($c0 << 3) | ($c1 >> 2) ) & 0xff, (($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff ); $err |= ($c0 | $c1 | $c2 | $c3) >> 8; if ($strictPadding) { $err |= ($c3 << 4) & 0xff; } } elseif ($i + 2 < $srcLen) { /** @var int $c1 */ $c1 = static::$method($chunk[2]); /** @var int $c2 */ $c2 = static::$method($chunk[3]); $dest .= pack( 'CC', (($c0 << 3) | ($c1 >> 2) ) & 0xff, (($c1 << 6) | ($c2 << 1) ) & 0xff ); $err |= ($c0 | $c1 | $c2) >> 8; if ($strictPadding) { $err |= ($c2 << 6) & 0xff; } } elseif ($i + 1 < $srcLen) { /** @var int $c1 */ $c1 = static::$method($chunk[2]); $dest .= pack( 'C', (($c0 << 3) | ($c1 >> 2) ) & 0xff ); $err |= ($c0 | $c1) >> 8; if ($strictPadding) { $err |= ($c1 << 6) & 0xff; } } else { $dest .= pack( 'C', (($c0 << 3) ) & 0xff ); $err |= ($c0) >> 8; } } $check = ($err === 0); if (!$check) { throw new RangeException( 'Base32::doDecode() only expects characters in the correct base32 alphabet' ); } return $dest; } /** * Base32 Encoding * * @param string $src * @param bool $upper * @param bool $pad * @return string * @throws TypeError */ protected static function doEncode( #[SensitiveParameter] string $src, bool $upper = false, bool $pad = true ): string { // We do this to reduce code duplication: $method = $upper ? 'encode5BitsUpper' : 'encode5Bits'; $dest = ''; $srcLen = strlen($src); // Main loop (no padding): for ($i = 0; $i + 5 <= $srcLen; $i += 5) { /** @var array $chunk */ $chunk = unpack('C*', substr($src, $i, 5)); $b0 = $chunk[1]; $b1 = $chunk[2]; $b2 = $chunk[3]; $b3 = $chunk[4]; $b4 = $chunk[5]; $dest .= static::$method( ($b0 >> 3) & 31) . static::$method((($b0 << 2) | ($b1 >> 6)) & 31) . static::$method((($b1 >> 1) ) & 31) . static::$method((($b1 << 4) | ($b2 >> 4)) & 31) . static::$method((($b2 << 1) | ($b3 >> 7)) & 31) . static::$method((($b3 >> 2) ) & 31) . static::$method((($b3 << 3) | ($b4 >> 5)) & 31) . static::$method( $b4 & 31); } // The last chunk, which may have padding: if ($i < $srcLen) { /** @var array $chunk */ $chunk = unpack('C*', substr($src, $i, $srcLen - $i)); $b0 = $chunk[1]; if ($i + 3 < $srcLen) { $b1 = $chunk[2]; $b2 = $chunk[3]; $b3 = $chunk[4]; $dest .= static::$method( ($b0 >> 3) & 31) . static::$method((($b0 << 2) | ($b1 >> 6)) & 31) . static::$method((($b1 >> 1) ) & 31) . static::$method((($b1 << 4) | ($b2 >> 4)) & 31) . static::$method((($b2 << 1) | ($b3 >> 7)) & 31) . static::$method((($b3 >> 2) ) & 31) . static::$method((($b3 << 3) ) & 31); if ($pad) { $dest .= '='; } } elseif ($i + 2 < $srcLen) { $b1 = $chunk[2]; $b2 = $chunk[3]; $dest .= static::$method( ($b0 >> 3) & 31) . static::$method((($b0 << 2) | ($b1 >> 6)) & 31) . static::$method((($b1 >> 1) ) & 31) . static::$method((($b1 << 4) | ($b2 >> 4)) & 31) . static::$method((($b2 << 1) ) & 31); if ($pad) { $dest .= '==='; } } elseif ($i + 1 < $srcLen) { $b1 = $chunk[2]; $dest .= static::$method( ($b0 >> 3) & 31) . static::$method((($b0 << 2) | ($b1 >> 6)) & 31) . static::$method((($b1 >> 1) ) & 31) . static::$method((($b1 << 4) ) & 31); if ($pad) { $dest .= '===='; } } else { $dest .= static::$method( ($b0 >> 3) & 31) . static::$method( ($b0 << 2) & 31); if ($pad) { $dest .= '======'; } } } return $dest; } } ================================================ FILE: lib/Google/vendor/paragonie/constant_time_encoding/src/Base32Hex.php ================================================ 0x30 && $src < 0x3a) ret += $src - 0x2e + 1; // -47 $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src - 47); // if ($src > 0x60 && $src < 0x77) ret += $src - 0x61 + 10 + 1; // -86 $ret += (((0x60 - $src) & ($src - 0x77)) >> 8) & ($src - 86); return $ret; } /** * Uses bitwise operators instead of table-lookups to turn 5-bit integers * into 8-bit integers. * * @param int $src * @return int */ #[Override] protected static function decode5BitsUpper(int $src): int { $ret = -1; // if ($src > 0x30 && $src < 0x3a) ret += $src - 0x2e + 1; // -47 $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src - 47); // if ($src > 0x40 && $src < 0x57) ret += $src - 0x41 + 10 + 1; // -54 $ret += (((0x40 - $src) & ($src - 0x57)) >> 8) & ($src - 54); return $ret; } /** * Uses bitwise operators instead of table-lookups to turn 8-bit integers * into 5-bit integers. * * @param int $src * @return string */ #[Override] protected static function encode5Bits(int $src): string { $src += 0x30; // if ($src > 0x39) $src += 0x61 - 0x3a; // 39 $src += ((0x39 - $src) >> 8) & 39; return pack('C', $src); } /** * Uses bitwise operators instead of table-lookups to turn 8-bit integers * into 5-bit integers. * * Uppercase variant. * * @param int $src * @return string */ #[Override] protected static function encode5BitsUpper(int $src): string { $src += 0x30; // if ($src > 0x39) $src += 0x41 - 0x3a; // 7 $src += ((0x39 - $src) >> 8) & 7; return pack('C', $src); } } ================================================ FILE: lib/Google/vendor/paragonie/constant_time_encoding/src/Base64.php ================================================ SODIUM_BASE64_VARIANT_ORIGINAL, Base64UrlSafe::class => SODIUM_BASE64_VARIANT_URLSAFE, default => 0, }; if ($variant > 0) { try { return sodium_bin2base64($binString, $variant); } catch (SodiumException $ex) { throw new RangeException($ex->getMessage(), $ex->getCode(), $ex); } } } return static::doEncode($binString, true); } /** * Encode into Base64, no = padding * * Base64 character set "[A-Z][a-z][0-9]+/" * * @param string $src * @return string * * @throws TypeError * @api */ public static function encodeUnpadded( #[SensitiveParameter] string $src ): string { if (extension_loaded('sodium')) { $variant = match(static::class) { Base64::class => SODIUM_BASE64_VARIANT_ORIGINAL_NO_PADDING, Base64UrlSafe::class => SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING, default => 0, }; if ($variant > 0) { try { return sodium_bin2base64($src, $variant); } catch (SodiumException $ex) { throw new RangeException($ex->getMessage(), $ex->getCode(), $ex); } } } return static::doEncode($src, false); } /** * @param string $src * @param bool $pad Include = padding? * @return string * * @throws TypeError */ protected static function doEncode( #[SensitiveParameter] string $src, bool $pad = true ): string { $dest = ''; $srcLen = strlen($src); // Main loop (no padding): for ($i = 0; $i + 3 <= $srcLen; $i += 3) { /** @var array $chunk */ $chunk = unpack('C*', substr($src, $i, 3)); $b0 = $chunk[1]; $b1 = $chunk[2]; $b2 = $chunk[3]; $dest .= static::encode6Bits( $b0 >> 2 ) . static::encode6Bits((($b0 << 4) | ($b1 >> 4)) & 63) . static::encode6Bits((($b1 << 2) | ($b2 >> 6)) & 63) . static::encode6Bits( $b2 & 63); } // The last chunk, which may have padding: if ($i < $srcLen) { /** @var array $chunk */ $chunk = unpack('C*', substr($src, $i, $srcLen - $i)); $b0 = $chunk[1]; if ($i + 1 < $srcLen) { $b1 = $chunk[2]; $dest .= static::encode6Bits($b0 >> 2) . static::encode6Bits((($b0 << 4) | ($b1 >> 4)) & 63) . static::encode6Bits(($b1 << 2) & 63); if ($pad) { $dest .= '='; } } else { $dest .= static::encode6Bits( $b0 >> 2) . static::encode6Bits(($b0 << 4) & 63); if ($pad) { $dest .= '=='; } } } return $dest; } /** * decode from base64 into binary * * Base64 character set "./[A-Z][a-z][0-9]" * * @param string $encodedString * @param bool $strictPadding * @return string * * @throws RangeException * @throws TypeError */ #[Override] public static function decode( #[SensitiveParameter] string $encodedString, bool $strictPadding = false ): string { // Remove padding $srcLen = strlen($encodedString); if ($srcLen === 0) { return ''; } if ($strictPadding) { if (($srcLen & 3) === 0) { if ($encodedString[$srcLen - 1] === '=') { $srcLen--; if ($encodedString[$srcLen - 1] === '=') { $srcLen--; } } } if (($srcLen & 3) === 1) { throw new RangeException( 'Incorrect padding' ); } if ($encodedString[$srcLen - 1] === '=') { throw new RangeException( 'Incorrect padding' ); } if (extension_loaded('sodium')) { $variant = match(static::class) { Base64::class => SODIUM_BASE64_VARIANT_ORIGINAL_NO_PADDING, Base64UrlSafe::class => SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING, default => 0, }; if ($variant > 0) { try { return sodium_base642bin(substr($encodedString, 0, $srcLen), $variant); } catch (SodiumException $ex) { throw new RangeException($ex->getMessage(), $ex->getCode(), $ex); } } } } else { // Just remove all padding. $encodedString = rtrim($encodedString, '='); $srcLen = strlen($encodedString); } $err = 0; $dest = ''; // Main loop (no padding): for ($i = 0; $i + 4 <= $srcLen; $i += 4) { /** @var array $chunk */ $chunk = unpack('C*', substr($encodedString, $i, 4)); $c0 = static::decode6Bits($chunk[1]); $c1 = static::decode6Bits($chunk[2]); $c2 = static::decode6Bits($chunk[3]); $c3 = static::decode6Bits($chunk[4]); $dest .= pack( 'CCC', ((($c0 << 2) | ($c1 >> 4)) & 0xff), ((($c1 << 4) | ($c2 >> 2)) & 0xff), ((($c2 << 6) | $c3 ) & 0xff) ); $err |= ($c0 | $c1 | $c2 | $c3) >> 8; } // The last chunk, which may have padding: if ($i < $srcLen) { /** @var array $chunk */ $chunk = unpack('C*', substr($encodedString, $i, $srcLen - $i)); $c0 = static::decode6Bits($chunk[1]); if ($i + 2 < $srcLen) { $c1 = static::decode6Bits($chunk[2]); $c2 = static::decode6Bits($chunk[3]); $dest .= pack( 'CC', ((($c0 << 2) | ($c1 >> 4)) & 0xff), ((($c1 << 4) | ($c2 >> 2)) & 0xff) ); $err |= ($c0 | $c1 | $c2) >> 8; if ($strictPadding) { $err |= ($c2 << 6) & 0xff; } } elseif ($i + 1 < $srcLen) { $c1 = static::decode6Bits($chunk[2]); $dest .= pack( 'C', ((($c0 << 2) | ($c1 >> 4)) & 0xff) ); $err |= ($c0 | $c1) >> 8; if ($strictPadding) { $err |= ($c1 << 4) & 0xff; } } elseif ($strictPadding) { $err |= 1; } } $check = ($err === 0); if (!$check) { throw new RangeException( 'Base64::decode() only expects characters in the correct base64 alphabet' ); } return $dest; } /** * @param string $encodedString * @return string * @api */ public static function decodeNoPadding( #[SensitiveParameter] string $encodedString ): string { $srcLen = strlen($encodedString); if ($srcLen === 0) { return ''; } if (($srcLen & 3) === 0) { // If $strLen is not zero, and it is divisible by 4, then it's at least 4. if ($encodedString[$srcLen - 1] === '=' || $encodedString[$srcLen - 2] === '=') { throw new InvalidArgumentException( "decodeNoPadding() doesn't tolerate padding" ); } } return static::decode( $encodedString, true ); } /** * Uses bitwise operators instead of table-lookups to turn 6-bit integers * into 8-bit integers. * * Base64 character set: * [A-Z] [a-z] [0-9] + / * 0x41-0x5a, 0x61-0x7a, 0x30-0x39, 0x2b, 0x2f * * @param int $src * @return int */ protected static function decode6Bits(int $src): int { $ret = -1; // if ($src > 0x40 && $src < 0x5b) $ret += $src - 0x41 + 1; // -64 $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 64); // if ($src > 0x60 && $src < 0x7b) $ret += $src - 0x61 + 26 + 1; // -70 $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 70); // if ($src > 0x2f && $src < 0x3a) $ret += $src - 0x30 + 52 + 1; // 5 $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src + 5); // if ($src == 0x2b) $ret += 62 + 1; $ret += (((0x2a - $src) & ($src - 0x2c)) >> 8) & 63; // if ($src == 0x2f) ret += 63 + 1; $ret += (((0x2e - $src) & ($src - 0x30)) >> 8) & 64; return $ret; } /** * Uses bitwise operators instead of table-lookups to turn 8-bit integers * into 6-bit integers. * * @param int $src * @return string */ protected static function encode6Bits(int $src): string { $diff = 0x41; // if ($src > 25) $diff += 0x61 - 0x41 - 26; // 6 $diff += ((25 - $src) >> 8) & 6; // if ($src > 51) $diff += 0x30 - 0x61 - 26; // -75 $diff -= ((51 - $src) >> 8) & 75; // if ($src > 61) $diff += 0x2b - 0x30 - 10; // -15 $diff -= ((61 - $src) >> 8) & 15; // if ($src > 62) $diff += 0x2f - 0x2b - 1; // 3 $diff += ((62 - $src) >> 8) & 3; return pack('C', $src + $diff); } } ================================================ FILE: lib/Google/vendor/paragonie/constant_time_encoding/src/Base64DotSlash.php ================================================ 0x2d && $src < 0x30) ret += $src - 0x2e + 1; // -45 $ret += (((0x2d - $src) & ($src - 0x30)) >> 8) & ($src - 45); // if ($src > 0x40 && $src < 0x5b) ret += $src - 0x41 + 2 + 1; // -62 $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 62); // if ($src > 0x60 && $src < 0x7b) ret += $src - 0x61 + 28 + 1; // -68 $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 68); // if ($src > 0x2f && $src < 0x3a) ret += $src - 0x30 + 54 + 1; // 7 $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src + 7); return $ret; } /** * Uses bitwise operators instead of table-lookups to turn 8-bit integers * into 6-bit integers. * * @param int $src * @return string */ #[Override] protected static function encode6Bits(int $src): string { $src += 0x2e; // if ($src > 0x2f) $src += 0x41 - 0x30; // 17 $src += ((0x2f - $src) >> 8) & 17; // if ($src > 0x5a) $src += 0x61 - 0x5b; // 6 $src += ((0x5a - $src) >> 8) & 6; // if ($src > 0x7a) $src += 0x30 - 0x7b; // -75 $src -= ((0x7a - $src) >> 8) & 75; return \pack('C', $src); } } ================================================ FILE: lib/Google/vendor/paragonie/constant_time_encoding/src/Base64DotSlashOrdered.php ================================================ 0x2d && $src < 0x3a) ret += $src - 0x2e + 1; // -45 $ret += (((0x2d - $src) & ($src - 0x3a)) >> 8) & ($src - 45); // if ($src > 0x40 && $src < 0x5b) ret += $src - 0x41 + 12 + 1; // -52 $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 52); // if ($src > 0x60 && $src < 0x7b) ret += $src - 0x61 + 38 + 1; // -58 $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 58); return $ret; } /** * Uses bitwise operators instead of table-lookups to turn 8-bit integers * into 6-bit integers. * * @param int $src * @return string */ #[Override] protected static function encode6Bits(int $src): string { $src += 0x2e; // if ($src > 0x39) $src += 0x41 - 0x3a; // 7 $src += ((0x39 - $src) >> 8) & 7; // if ($src > 0x5a) $src += 0x61 - 0x5b; // 6 $src += ((0x5a - $src) >> 8) & 6; return \pack('C', $src); } } ================================================ FILE: lib/Google/vendor/paragonie/constant_time_encoding/src/Base64UrlSafe.php ================================================ 0x40 && $src < 0x5b) $ret += $src - 0x41 + 1; // -64 $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 64); // if ($src > 0x60 && $src < 0x7b) $ret += $src - 0x61 + 26 + 1; // -70 $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 70); // if ($src > 0x2f && $src < 0x3a) $ret += $src - 0x30 + 52 + 1; // 5 $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src + 5); // if ($src == 0x2c) $ret += 62 + 1; $ret += (((0x2c - $src) & ($src - 0x2e)) >> 8) & 63; // if ($src == 0x5f) ret += 63 + 1; $ret += (((0x5e - $src) & ($src - 0x60)) >> 8) & 64; return $ret; } /** * Uses bitwise operators instead of table-lookups to turn 8-bit integers * into 6-bit integers. * * @param int $src * @return string */ #[Override] protected static function encode6Bits(int $src): string { $diff = 0x41; // if ($src > 25) $diff += 0x61 - 0x41 - 26; // 6 $diff += ((25 - $src) >> 8) & 6; // if ($src > 51) $diff += 0x30 - 0x61 - 26; // -75 $diff -= ((51 - $src) >> 8) & 75; // if ($src > 61) $diff += 0x2d - 0x30 - 10; // -13 $diff -= ((61 - $src) >> 8) & 13; // if ($src > 62) $diff += 0x5f - 0x2b - 1; // 3 $diff += ((62 - $src) >> 8) & 49; return \pack('C', $src + $diff); } } ================================================ FILE: lib/Google/vendor/paragonie/constant_time_encoding/src/Binary.php ================================================ getMessage(), $ex->getCode(), $ex); } } $hex = ''; $len = strlen($binString); for ($i = 0; $i < $len; ++$i) { /** @var array $chunk */ $chunk = unpack('C', $binString[$i]); $c = $chunk[1] & 0xf; $b = $chunk[1] >> 4; $hex .= pack( 'CC', (87 + $b + ((($b - 10) >> 8) & ~38)), (87 + $c + ((($c - 10) >> 8) & ~38)) ); } return $hex; } /** * Convert a binary string into a hexadecimal string without cache-timing * leaks, returning uppercase letters (as per RFC 4648) * * @param string $binString (raw binary) * @return string * @throws TypeError */ public static function encodeUpper( #[SensitiveParameter] string $binString ): string { $hex = ''; $len = strlen($binString); for ($i = 0; $i < $len; ++$i) { /** @var array $chunk */ $chunk = unpack('C', $binString[$i]); $c = $chunk[1] & 0xf; $b = $chunk[1] >> 4; $hex .= pack( 'CC', (55 + $b + ((($b - 10) >> 8) & ~6)), (55 + $c + ((($c - 10) >> 8) & ~6)) ); } return $hex; } /** * Convert a hexadecimal string into a binary string without cache-timing * leaks * * @param string $encodedString * @param bool $strictPadding * @return string (raw binary) * @throws RangeException */ #[Override] public static function decode( #[SensitiveParameter] string $encodedString, bool $strictPadding = false ): string { if (extension_loaded('sodium') && $strictPadding) { try { return sodium_hex2bin($encodedString); } catch (SodiumException $ex) { throw new RangeException($ex->getMessage(), $ex->getCode(), $ex); } } $hex_pos = 0; $bin = ''; $c_acc = 0; $hex_len = strlen($encodedString); $state = 0; if (($hex_len & 1) !== 0) { if ($strictPadding) { throw new RangeException( 'Expected an even number of hexadecimal characters' ); } else { $encodedString = '0' . $encodedString; ++$hex_len; } } /** @var array $chunk */ $chunk = unpack('C*', $encodedString); while ($hex_pos < $hex_len) { ++$hex_pos; $c = $chunk[$hex_pos]; $c_num = $c ^ 48; $c_num0 = ($c_num - 10) >> 8; $c_alpha = ($c & ~32) - 55; $c_alpha0 = (($c_alpha - 10) ^ ($c_alpha - 16)) >> 8; if (($c_num0 | $c_alpha0) === 0) { throw new RangeException( 'Expected hexadecimal character' ); } $c_val = ($c_num0 & $c_num) | ($c_alpha & $c_alpha0); if ($state === 0) { $c_acc = $c_val * 16; } else { $bin .= pack('C', $c_acc | $c_val); } $state ^= 1; } return $bin; } } ================================================ FILE: lib/Google/vendor/paragonie/constant_time_encoding/src/RFC4648.php ================================================ "Zm9v" * * @param string $str * @return string * * @throws TypeError */ public static function base64Encode( #[SensitiveParameter] string $str ): string { return Base64::encode($str); } /** * RFC 4648 Base64 decoding * * "Zm9v" -> "foo" * * @param string $str * @return string * * @throws TypeError */ public static function base64Decode( #[SensitiveParameter] string $str ): string { return Base64::decode($str, true); } /** * RFC 4648 Base64 (URL Safe) encoding * * "foo" -> "Zm9v" * * @param string $str * @return string * * @throws TypeError */ public static function base64UrlSafeEncode( #[SensitiveParameter] string $str ): string { return Base64UrlSafe::encode($str); } /** * RFC 4648 Base64 (URL Safe) decoding * * "Zm9v" -> "foo" * * @param string $str * @return string * * @throws TypeError */ public static function base64UrlSafeDecode( #[SensitiveParameter] string $str ): string { return Base64UrlSafe::decode($str, true); } /** * RFC 4648 Base32 encoding * * "foo" -> "MZXW6===" * * @param string $str * @return string * * @throws TypeError */ public static function base32Encode( #[SensitiveParameter] string $str ): string { return Base32::encodeUpper($str); } /** * RFC 4648 Base32 encoding * * "MZXW6===" -> "foo" * * @param string $str * @return string * * @throws TypeError */ public static function base32Decode( #[SensitiveParameter] string $str ): string { return Base32::decodeUpper($str, true); } /** * RFC 4648 Base32-Hex encoding * * "foo" -> "CPNMU===" * * @param string $str * @return string * * @throws TypeError */ public static function base32HexEncode( #[SensitiveParameter] string $str ): string { return Base32::encodeUpper($str); } /** * RFC 4648 Base32-Hex decoding * * "CPNMU===" -> "foo" * * @param string $str * @return string * * @throws TypeError */ public static function base32HexDecode( #[SensitiveParameter] string $str ): string { return Base32::decodeUpper($str, true); } /** * RFC 4648 Base16 decoding * * "foo" -> "666F6F" * * @param string $str * @return string * * @throws TypeError */ public static function base16Encode( #[SensitiveParameter] string $str ): string { return Hex::encodeUpper($str); } /** * RFC 4648 Base16 decoding * * "666F6F" -> "foo" * * @param string $str * @return string */ public static function base16Decode( #[SensitiveParameter] string $str ): string { return Hex::decode($str, true); } } ================================================ FILE: lib/Google/vendor/paragonie/random_compat/LICENSE ================================================ The MIT License (MIT) Copyright (c) 2015 Paragon Initiative Enterprises 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. ================================================ FILE: lib/Google/vendor/paragonie/random_compat/build-phar.sh ================================================ #!/usr/bin/env bash basedir=$( dirname $( readlink -f ${BASH_SOURCE[0]} ) ) php -dphar.readonly=0 "$basedir/other/build_phar.php" $* ================================================ FILE: lib/Google/vendor/paragonie/random_compat/composer.json ================================================ { "name": "paragonie/random_compat", "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", "keywords": [ "csprng", "random", "polyfill", "pseudorandom" ], "license": "MIT", "type": "library", "authors": [ { "name": "Paragon Initiative Enterprises", "email": "security@paragonie.com", "homepage": "https://paragonie.com" } ], "support": { "issues": "https://github.com/paragonie/random_compat/issues", "email": "info@paragonie.com", "source": "https://github.com/paragonie/random_compat" }, "require": { "php": ">= 7" }, "require-dev": { "vimeo/psalm": "^1", "phpunit/phpunit": "4.*|5.*" }, "suggest": { "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." } } ================================================ FILE: lib/Google/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey ================================================ -----BEGIN PUBLIC KEY----- MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEEd+wCqJDrx5B4OldM0dQE0ZMX+lx1ZWm pui0SUqD4G29L3NGsz9UhJ/0HjBdbnkhIK5xviT0X5vtjacF6ajgcCArbTB+ds+p +h7Q084NuSuIpNb6YPfoUFgC/CL9kAoc -----END PUBLIC KEY----- ================================================ FILE: lib/Google/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey.asc ================================================ -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (MingW32) iQEcBAABAgAGBQJWtW1hAAoJEGuXocKCZATaJf0H+wbZGgskK1dcRTsuVJl9IWip QwGw/qIKI280SD6/ckoUMxKDCJiFuPR14zmqnS36k7N5UNPnpdTJTS8T11jttSpg 1LCmgpbEIpgaTah+cELDqFCav99fS+bEiAL5lWDAHBTE/XPjGVCqeehyPYref4IW NDBIEsvnHPHPLsn6X5jq4+Yj5oUixgxaMPiR+bcO4Sh+RzOVB6i2D0upWfRXBFXA NNnsg9/zjvoC7ZW73y9uSH+dPJTt/Vgfeiv52/v41XliyzbUyLalf02GNPY+9goV JHG1ulEEBJOCiUD9cE1PUIJwHA/HqyhHIvV350YoEFiHl8iSwm7SiZu5kPjaq74= =B6+8 -----END PGP SIGNATURE----- ================================================ FILE: lib/Google/vendor/paragonie/random_compat/lib/random.php ================================================ buildFromDirectory(dirname(__DIR__).'/lib'); rename( dirname(__DIR__).'/lib/index.php', dirname(__DIR__).'/lib/random.php' ); /** * If we pass an (optional) path to a private key as a second argument, we will * sign the Phar with OpenSSL. * * If you leave this out, it will produce an unsigned .phar! */ if ($argc > 1) { if (!@is_readable($argv[1])) { echo 'Could not read the private key file:', $argv[1], "\n"; exit(255); } $pkeyFile = file_get_contents($argv[1]); $private = openssl_get_privatekey($pkeyFile); if ($private !== false) { $pkey = ''; openssl_pkey_export($private, $pkey); $phar->setSignatureAlgorithm(Phar::OPENSSL, $pkey); /** * Save the corresponding public key to the file */ if (!@is_readable($dist.'/random_compat.phar.pubkey')) { $details = openssl_pkey_get_details($private); file_put_contents( $dist.'/random_compat.phar.pubkey', $details['key'] ); } } else { echo 'An error occurred reading the private key from OpenSSL.', "\n"; exit(255); } } ================================================ FILE: lib/Google/vendor/paragonie/random_compat/psalm-autoload.php ================================================ ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/AUTHORS ================================================ phpseclib Lead Developer: TerraFrost (Jim Wigginton) phpseclib Developers: monnerat (Patrick Monnerat) bantu (Andreas Fischer) petrich (Hans-Jürgen Petrich) GrahamCampbell (Graham Campbell) hc-jworman ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/BACKERS.md ================================================ # Backers phpseclib ongoing development is made possible by [Tidelift](https://tidelift.com/subscription/pkg/packagist-phpseclib-phpseclib?utm_source=packagist-phpseclib-phpseclib&utm_medium=referral&utm_campaign=readme) and by contributions by users like you. Thank you. ## Backers - Allan Simon - [ChargeOver](https://chargeover.com/) - Raghu Veer Dendukuri - Zane Hooper - [Setasign](https://www.setasign.com/) - [Charles Severance](https://github.com/csev) - [Rachel Fish](https://github.com/itsrachelfish) - Tharyrok - [cjhaas](https://github.com/cjhaas) - [istiak-tridip](https://github.com/istiak-tridip) - [Anna Filina](https://github.com/afilina) - [blakemckeeby](https://github.com/blakemckeeby) - [ssddanbrown](https://github.com/ssddanbrown) - Stefan Beck ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/LICENSE ================================================ Copyright (c) 2011-2019 TerraFrost and other contributors 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. ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/README.md ================================================ # phpseclib - PHP Secure Communications Library [![CI Status](https://github.com/phpseclib/phpseclib/actions/workflows/ci.yml/badge.svg?branch=3.0&event=push "CI Status")](https://github.com/phpseclib/phpseclib) ## Supporting phpseclib - [Become a backer or sponsor on Patreon](https://www.patreon.com/phpseclib) - [One-time donation via PayPal or crypto-currencies](http://sourceforge.net/donate/index.php?group_id=198487) - [Subscribe to Tidelift](https://tidelift.com/subscription/pkg/packagist-phpseclib-phpseclib?utm_source=packagist-phpseclib-phpseclib&utm_medium=referral&utm_campaign=readme) ## Introduction MIT-licensed pure-PHP implementations of the following: SSH-2, SFTP, X.509, an arbitrary-precision integer arithmetic library, Ed25519 / Ed449 / Curve25519 / Curve449, ECDSA / ECDH (with support for 66 curves), RSA (PKCS#1 v2.2 compliant), DSA / DH, DES / 3DES / RC4 / Rijndael / AES / Blowfish / Twofish / Salsa20 / ChaCha20, GCM / Poly1305 * [Browse Git](https://github.com/phpseclib/phpseclib) ## Documentation * [Documentation / Manual](https://phpseclib.com/) * [API Documentation](https://api.phpseclib.com/3.0/) (generated by Doctum) ## Branches ### master * Development Branch * Unstable API * Do not use in production ### 3.0 * Long term support (LTS) release * Major expansion of cryptographic primitives * Minimum PHP version: 5.6.1 * PSR-4 autoloading with namespace rooted at `\phpseclib3` * Install via Composer: `composer require phpseclib/phpseclib:~3.0` ### 2.0 * Long term support (LTS) release * Modernized version of 1.0 * Minimum PHP version: 5.3.3 * PSR-4 autoloading with namespace rooted at `\phpseclib` * Install via Composer: `composer require phpseclib/phpseclib:~2.0` ### 1.0 * Long term support (LTS) release * PHP4 compatible * Composer compatible (PSR-0 autoloading) * Install using Composer: `composer require phpseclib/phpseclib:~1.0` * [Download 1.0.25 as ZIP](http://sourceforge.net/projects/phpseclib/files/phpseclib1.0.25.zip/download) ## Security contact information To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure. ## Support Need Support? * [Checkout Questions and Answers on Stack Overflow](http://stackoverflow.com/questions/tagged/phpseclib) * [Create a Support Ticket on GitHub](https://github.com/phpseclib/phpseclib/issues/new) ## Special Thanks

Sovereign Tech Agency

## Additional Thanks - Allan Simon - [Anna Filina](https://afilina.com/) - delovelady - [ChargeOver](https://chargeover.com/) - ## Contributing 1. Fork the Project 2. Ensure you have Composer installed (see [Composer Download Instructions](https://getcomposer.org/download/)) 3. Install Development Dependencies ```sh composer install ``` 4. Create a Feature Branch 5. Run continuous integration checks: ```sh composer global require php:^8.1 squizlabs/php_codesniffer friendsofphp/php-cs-fixer vimeo/psalm phpcs --standard=build/php_codesniffer.xml php-cs-fixer fix --config=build/php-cs-fixer.php --diff --dry-run --using-cache=no psalm --config=build/psalm.xml --no-cache --long-progress --report-show-info=false --output-format=text vendor/bin/phpunit --verbose --configuration tests/phpunit.xml ``` 6. Send us a Pull Request ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/SECURITY.md ================================================ # Security Policy ## Supported Versions | Version | Supported | | ------- | ------------------ | | 1.0.x | :white_check_mark: | | 2.0.x | :white_check_mark: | | 3.0.x | :white_check_mark: | ## Reporting a Vulnerability To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure. ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/composer.json ================================================ { "name": "phpseclib/phpseclib", "type": "library", "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", "keywords": [ "security", "crypto", "cryptography", "encryption", "signature", "signing", "rsa", "aes", "blowfish", "twofish", "ssh", "sftp", "x509", "x.509", "asn1", "asn.1", "BigInteger" ], "homepage": "http://phpseclib.sourceforge.net", "license": "MIT", "authors": [ { "name": "Jim Wigginton", "email": "terrafrost@php.net", "role": "Lead Developer" }, { "name": "Patrick Monnerat", "email": "pm@datasphere.ch", "role": "Developer" }, { "name": "Andreas Fischer", "email": "bantu@phpbb.com", "role": "Developer" }, { "name": "Hans-Jürgen Petrich", "email": "petrich@tronic-media.com", "role": "Developer" }, { "name": "Graham Campbell", "email": "graham@alt-three.com", "role": "Developer" } ], "require": { "php": ">=5.6.1", "paragonie/constant_time_encoding": "^1|^2|^3", "paragonie/random_compat": "^1.4|^2.0|^9.99.99" }, "require-dev": { "phpunit/phpunit": "*" }, "suggest": { "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations.", "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", "ext-dom": "Install the DOM extension to load XML formatted public keys." }, "autoload": { "files": [ "phpseclib/bootstrap.php" ], "psr-4": { "phpseclib3\\": "phpseclib/" } }, "autoload-dev": { "psr-4": { "phpseclib3\\Tests\\": "tests/" } }, "config": { "sort-packages": true } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Common/Functions/Strings.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Common\Functions; use ParagonIE\ConstantTime\Base64; use ParagonIE\ConstantTime\Base64UrlSafe; use ParagonIE\ConstantTime\Hex; use phpseclib3\Math\BigInteger; use phpseclib3\Math\Common\FiniteField; /** * Common String Functions * * @author Jim Wigginton */ abstract class Strings { /** * String Shift * * Inspired by array_shift * * @param string $string * @param int $index * @return string */ public static function shift(&$string, $index = 1) { $substr = substr($string, 0, $index); $string = substr($string, $index); return $substr; } /** * String Pop * * Inspired by array_pop * * @param string $string * @param int $index * @return string */ public static function pop(&$string, $index = 1) { $substr = substr($string, -$index); $string = substr($string, 0, -$index); return $substr; } /** * Parse SSH2-style string * * Returns either an array or a boolean if $data is malformed. * * Valid characters for $format are as follows: * * C = byte * b = boolean (true/false) * N = uint32 * Q = uint64 * s = string * i = mpint * L = name-list * * uint64 is not supported. * * @param string $format * @param string $data * @return mixed */ public static function unpackSSH2($format, &$data) { $format = self::formatPack($format); $result = []; for ($i = 0; $i < strlen($format); $i++) { switch ($format[$i]) { case 'C': case 'b': if (!strlen($data)) { throw new \LengthException('At least one byte needs to be present for successful C / b decodes'); } break; case 'N': case 'i': case 's': case 'L': if (strlen($data) < 4) { throw new \LengthException('At least four byte needs to be present for successful N / i / s / L decodes'); } break; case 'Q': if (strlen($data) < 8) { throw new \LengthException('At least eight byte needs to be present for successful N / i / s / L decodes'); } break; default: throw new \InvalidArgumentException('$format contains an invalid character'); } switch ($format[$i]) { case 'C': $result[] = ord(self::shift($data)); continue 2; case 'b': $result[] = ord(self::shift($data)) != 0; continue 2; case 'N': list(, $temp) = unpack('N', self::shift($data, 4)); $result[] = $temp; continue 2; case 'Q': // pack() added support for Q in PHP 5.6.3 and PHP 5.6 is phpseclib 3's minimum version // so in theory we could support this BUT, "64-bit format codes are not available for // 32-bit versions" and phpseclib works on 32-bit installs. on 32-bit installs // 64-bit floats can be used to get larger numbers then 32-bit signed ints would allow // for. sure, you're not gonna get the full precision of 64-bit numbers but just because // you need > 32-bit precision doesn't mean you need the full 64-bit precision $unpacked = unpack('Nupper/Nlower', self::shift($data, 8)); $upper = $unpacked['upper']; $lower = $unpacked['lower']; $temp = $upper ? 4294967296 * $upper : 0; $temp += $lower < 0 ? ($lower & 0x7FFFFFFFF) + 0x80000000 : $lower; // $temp = hexdec(bin2hex(self::shift($data, 8))); $result[] = $temp; continue 2; } list(, $length) = unpack('N', self::shift($data, 4)); if (strlen($data) < $length) { throw new \LengthException("$length bytes needed; " . strlen($data) . ' bytes available'); } $temp = self::shift($data, $length); switch ($format[$i]) { case 'i': $result[] = new BigInteger($temp, -256); break; case 's': $result[] = $temp; break; case 'L': $result[] = explode(',', $temp); } } return $result; } /** * Create SSH2-style string * * @param string $format * @param string|int|float|array|bool ...$elements * @return string */ public static function packSSH2($format, ...$elements) { $format = self::formatPack($format); if (strlen($format) != count($elements)) { throw new \InvalidArgumentException('There must be as many arguments as there are characters in the $format string'); } $result = ''; for ($i = 0; $i < strlen($format); $i++) { $element = $elements[$i]; switch ($format[$i]) { case 'C': if (!is_int($element)) { throw new \InvalidArgumentException('Bytes must be represented as an integer between 0 and 255, inclusive.'); } $result .= pack('C', $element); break; case 'b': if (!is_bool($element)) { throw new \InvalidArgumentException('A boolean parameter was expected.'); } $result .= $element ? "\1" : "\0"; break; case 'Q': if (!is_int($element) && !is_float($element)) { throw new \InvalidArgumentException('An integer was expected.'); } // 4294967296 == 1 << 32 $result .= pack('NN', $element / 4294967296, $element); break; case 'N': if (is_float($element)) { $element = (int) $element; } if (!is_int($element)) { throw new \InvalidArgumentException('An integer was expected.'); } $result .= pack('N', $element); break; case 's': if (!self::is_stringable($element)) { throw new \InvalidArgumentException('A string was expected.'); } $result .= pack('Na*', strlen($element), $element); break; case 'i': if (!$element instanceof BigInteger && !$element instanceof FiniteField\Integer) { throw new \InvalidArgumentException('A phpseclib3\Math\BigInteger or phpseclib3\Math\Common\FiniteField\Integer object was expected.'); } $element = $element->toBytes(true); $result .= pack('Na*', strlen($element), $element); break; case 'L': if (!is_array($element)) { throw new \InvalidArgumentException('An array was expected.'); } $element = implode(',', $element); $result .= pack('Na*', strlen($element), $element); break; default: throw new \InvalidArgumentException('$format contains an invalid character'); } } return $result; } /** * Expand a pack string * * Converts C5 to CCCCC, for example. * * @param string $format * @return string */ private static function formatPack($format) { $parts = preg_split('#(\d+)#', $format, -1, PREG_SPLIT_DELIM_CAPTURE); $format = ''; for ($i = 1; $i < count($parts); $i += 2) { $format .= substr($parts[$i - 1], 0, -1) . str_repeat(substr($parts[$i - 1], -1), $parts[$i]); } $format .= $parts[$i - 1]; return $format; } /** * Convert binary data into bits * * bin2hex / hex2bin refer to base-256 encoded data as binary, whilst * decbin / bindec refer to base-2 encoded data as binary. For the purposes * of this function, bin refers to base-256 encoded data whilst bits refers * to base-2 encoded data * * @param string $x * @return string */ public static function bits2bin($x) { /* // the pure-PHP approach is faster than the GMP approach if (function_exists('gmp_export')) { return strlen($x) ? gmp_export(gmp_init($x, 2)) : gmp_init(0); } */ if (preg_match('#[^01]#', $x)) { throw new \RuntimeException('The only valid characters are 0 and 1'); } if (!defined('PHP_INT_MIN')) { define('PHP_INT_MIN', ~PHP_INT_MAX); } $length = strlen($x); if (!$length) { return ''; } $block_size = PHP_INT_SIZE << 3; $pad = $block_size - ($length % $block_size); if ($pad != $block_size) { $x = str_repeat('0', $pad) . $x; } $parts = str_split($x, $block_size); $str = ''; foreach ($parts as $part) { $xor = $part[0] == '1' ? PHP_INT_MIN : 0; $part[0] = '0'; $str .= pack( PHP_INT_SIZE == 4 ? 'N' : 'J', $xor ^ eval('return 0b' . $part . ';') ); } return ltrim($str, "\0"); } /** * Convert bits to binary data * * @param string $x * @return string */ public static function bin2bits($x, $trim = true) { /* // the pure-PHP approach is slower than the GMP approach BUT // i want to the pure-PHP version to be easily unit tested as well if (function_exists('gmp_import')) { return gmp_strval(gmp_import($x), 2); } */ $len = strlen($x); $mod = $len % PHP_INT_SIZE; if ($mod) { $x = str_pad($x, $len + PHP_INT_SIZE - $mod, "\0", STR_PAD_LEFT); } $bits = ''; if (PHP_INT_SIZE == 4) { $digits = unpack('N*', $x); foreach ($digits as $digit) { $bits .= sprintf('%032b', $digit); } } else { $digits = unpack('J*', $x); foreach ($digits as $digit) { $bits .= sprintf('%064b', $digit); } } return $trim ? ltrim($bits, '0') : $bits; } /** * Switch Endianness Bit Order * * @param string $x * @return string */ public static function switchEndianness($x) { $r = ''; for ($i = strlen($x) - 1; $i >= 0; $i--) { $b = ord($x[$i]); if (PHP_INT_SIZE === 8) { // 3 operations // from http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith64BitsDiv $r .= chr((($b * 0x0202020202) & 0x010884422010) % 1023); } else { // 7 operations // from http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith32Bits $p1 = ($b * 0x0802) & 0x22110; $p2 = ($b * 0x8020) & 0x88440; $r .= chr( (($p1 | $p2) * 0x10101) >> 16 ); } } return $r; } /** * Increment the current string * * @param string $var * @return string */ public static function increment_str(&$var) { if (function_exists('sodium_increment')) { $var = strrev($var); sodium_increment($var); $var = strrev($var); return $var; } for ($i = 4; $i <= strlen($var); $i += 4) { $temp = substr($var, -$i, 4); switch ($temp) { case "\xFF\xFF\xFF\xFF": $var = substr_replace($var, "\x00\x00\x00\x00", -$i, 4); break; case "\x7F\xFF\xFF\xFF": $var = substr_replace($var, "\x80\x00\x00\x00", -$i, 4); return $var; default: $temp = unpack('Nnum', $temp); $var = substr_replace($var, pack('N', $temp['num'] + 1), -$i, 4); return $var; } } $remainder = strlen($var) % 4; if ($remainder == 0) { return $var; } $temp = unpack('Nnum', str_pad(substr($var, 0, $remainder), 4, "\0", STR_PAD_LEFT)); $temp = substr(pack('N', $temp['num'] + 1), -$remainder); $var = substr_replace($var, $temp, 0, $remainder); return $var; } /** * Find whether the type of a variable is string (or could be converted to one) * * @param mixed $var * @return bool * @psalm-assert-if-true string|\Stringable $var */ public static function is_stringable($var) { return is_string($var) || (is_object($var) && method_exists($var, '__toString')); } /** * Constant Time Base64-decoding * * ParagoneIE\ConstantTime doesn't use libsodium if it's available so we'll do so * ourselves. see https://github.com/paragonie/constant_time_encoding/issues/39 * * @param string $data * @return string */ public static function base64_decode($data) { return function_exists('sodium_base642bin') ? sodium_base642bin($data, SODIUM_BASE64_VARIANT_ORIGINAL_NO_PADDING, '=') : Base64::decode($data); } /** * Constant Time Base64-decoding (URL safe) * * @param string $data * @return string */ public static function base64url_decode($data) { // return self::base64_decode(str_replace(['-', '_'], ['+', '/'], $data)); return function_exists('sodium_base642bin') ? sodium_base642bin($data, SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING, '=') : Base64UrlSafe::decode($data); } /** * Constant Time Base64-encoding * * @param string $data * @return string */ public static function base64_encode($data) { return function_exists('sodium_bin2base64') ? sodium_bin2base64($data, SODIUM_BASE64_VARIANT_ORIGINAL) : Base64::encode($data); } /** * Constant Time Base64-encoding (URL safe) * * @param string $data * @return string */ public static function base64url_encode($data) { // return str_replace(['+', '/'], ['-', '_'], self::base64_encode($data)); return function_exists('sodium_bin2base64') ? sodium_bin2base64($data, SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING) : Base64UrlSafe::encode($data); } /** * Constant Time Hex Decoder * * @param string $data * @return string */ public static function hex2bin($data) { return function_exists('sodium_hex2bin') ? sodium_hex2bin($data) : Hex::decode($data); } /** * Constant Time Hex Encoder * * @param string $data * @return string */ public static function bin2hex($data) { return function_exists('sodium_bin2hex') ? sodium_bin2hex($data) : Hex::encode($data); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php ================================================ * setKey('abcdefghijklmnop'); * * $size = 10 * 1024; * $plaintext = ''; * for ($i = 0; $i < $size; $i++) { * $plaintext.= 'a'; * } * * echo $aes->decrypt($aes->encrypt($plaintext)); * ?> * * * @author Jim Wigginton * @copyright 2008 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt; /** * Pure-PHP implementation of AES. * * @author Jim Wigginton */ class AES extends Rijndael { /** * Dummy function * * Since \phpseclib3\Crypt\AES extends \phpseclib3\Crypt\Rijndael, this function is, technically, available, but it doesn't do anything. * * @see \phpseclib3\Crypt\Rijndael::setBlockLength() * @param int $length * @throws \BadMethodCallException anytime it's called */ public function setBlockLength($length) { throw new \BadMethodCallException('The block length cannot be set for AES.'); } /** * Sets the key length * * Valid key lengths are 128, 192, and 256. Set the link to bool(false) to disable a fixed key length * * @see \phpseclib3\Crypt\Rijndael:setKeyLength() * @param int $length * @throws \LengthException if the key length isn't supported */ public function setKeyLength($length) { switch ($length) { case 128: case 192: case 256: break; default: throw new \LengthException('Key of size ' . $length . ' not supported by this algorithm. Only keys of sizes 128, 192 or 256 supported'); } parent::setKeyLength($length); } /** * Sets the key. * * Rijndael supports five different key lengths, AES only supports three. * * @see \phpseclib3\Crypt\Rijndael:setKey() * @see setKeyLength() * @param string $key * @throws \LengthException if the key length isn't supported */ public function setKey($key) { switch (strlen($key)) { case 16: case 24: case 32: break; default: throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported'); } parent::setKey($key); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php ================================================ unpack('N*', $x), $blocks); it jumps up by an additional * ~90MB, yielding a 106x increase in memory usage. Consequently, it bcrypt calls a different * _encryptBlock() then the regular Blowfish does. That said, the Blowfish _encryptBlock() is * basically just a thin wrapper around the bcrypt _encryptBlock(), so there's that. * * This explains 3 of the 4 _encryptBlock() implementations. the last _encryptBlock() * implementation can best be understood by doing Ctrl + F and searching for where * self::$use_reg_intval is defined. * * # phpseclib's three different _setupKey() implementations * * Every bcrypt round is the equivalent of encrypting 512KB of data. Since OpenSSH uses 16 * rounds by default that's ~8MB of data that's essentially being encrypted whenever * you use bcrypt. That's a lot of data, however, bcrypt operates within tighter constraints * than regular Blowfish, so we can use that to our advantage. In particular, whereas Blowfish * supports variable length keys, in bcrypt, the initial "key" is the sha512 hash of the * password. sha512 hashes are 512 bits or 64 bytes long and thus the bcrypt keys are of a * fixed length whereas Blowfish keys are not of a fixed length. * * bcrypt actually has two different key expansion steps. The first one (expandstate) is * constantly XOR'ing every _encryptBlock() parameter against the salt prior _encryptBlock()'s * being called. The second one (expand0state) is more similar to Blowfish's _setupKey() * but it can still use the fixed length key optimization discussed above and can do away with * the pack() / unpack() calls. * * I suppose _setupKey() could be made to be a thin wrapper around expandstate() but idk it's * just a lot of work for very marginal benefits as _setupKey() is only called once for * regular Blowfish vs the 128 times it's called --per round-- with bcrypt. * * # blowfish + bcrypt in the same class * * Altho there's a lot of Blowfish code that bcrypt doesn't re-use, bcrypt does re-use the * initial S-boxes, the initial P-array and the int-only _encryptBlock() implementation. * * # Credit * * phpseclib's bcrypt implementation is based losely off of OpenSSH's implementation: * * https://github.com/openssh/openssh-portable/blob/master/openbsd-compat/bcrypt_pbkdf.c * * Here's a short example of how to use this library: * * setKey('12345678901234567890123456789012'); * * $plaintext = str_repeat('a', 1024); * * echo $blowfish->decrypt($blowfish->encrypt($plaintext)); * ?> * * * @author Jim Wigginton * @author Hans-Juergen Petrich * @copyright 2007 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt; use phpseclib3\Crypt\Common\BlockCipher; /** * Pure-PHP implementation of Blowfish. * * @author Jim Wigginton * @author Hans-Juergen Petrich */ class Blowfish extends BlockCipher { /** * Block Length of the cipher * * @see Common\SymmetricKey::block_size * @var int */ protected $block_size = 8; /** * The mcrypt specific name of the cipher * * @see Common\SymmetricKey::cipher_name_mcrypt * @var string */ protected $cipher_name_mcrypt = 'blowfish'; /** * Optimizing value while CFB-encrypting * * @see Common\SymmetricKey::cfb_init_len * @var int */ protected $cfb_init_len = 500; /** * The fixed subkeys boxes * * S-Box * * @var array */ private static $sbox = [ 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a, 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7, 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0, 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 ]; /** * P-Array consists of 18 32-bit subkeys * * @var array */ private static $parray = [ 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b ]; /** * The BCTX-working Array * * Holds the expanded key [p] and the key-depended s-boxes [sb] * * @var array */ private $bctx; /** * Holds the last used key * * @var array */ private $kl; /** * The Key Length (in bytes) * {@internal The max value is 256 / 8 = 32, the min value is 128 / 8 = 16. Exists in conjunction with $Nk * because the encryption / decryption / key schedule creation requires this number and not $key_length. We could * derive this from $key_length or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu * of that, we'll just precompute it once.} * * @see Common\SymmetricKey::setKeyLength() * @var int */ protected $key_length = 16; /** * Default Constructor. * * @param string $mode * @throws \InvalidArgumentException if an invalid / unsupported mode is provided */ public function __construct($mode) { parent::__construct($mode); if ($this->mode == self::MODE_STREAM) { throw new \InvalidArgumentException('Block ciphers cannot be ran in stream mode'); } } /** * Sets the key length. * * Key lengths can be between 32 and 448 bits. * * @param int $length */ public function setKeyLength($length) { if ($length < 32 || $length > 448) { throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes between 32 and 448 bits are supported'); } $this->key_length = $length >> 3; parent::setKeyLength($length); } /** * Test for engine validity * * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() * * @see Common\SymmetricKey::isValidEngine() * @param int $engine * @return bool */ protected function isValidEngineHelper($engine) { if ($engine == self::ENGINE_OPENSSL) { if ($this->key_length < 16) { return false; } // quoting https://www.openssl.org/news/openssl-3.0-notes.html, OpenSSL 3.0.1 // "Moved all variations of the EVP ciphers CAST5, BF, IDEA, SEED, RC2, RC4, RC5, and DES to the legacy provider" // in theory openssl_get_cipher_methods() should catch this but, on GitHub Actions, at least, it does not if (defined('OPENSSL_VERSION_TEXT') && version_compare(preg_replace('#OpenSSL (\d+\.\d+\.\d+) .*#', '$1', OPENSSL_VERSION_TEXT), '3.0.1', '>=')) { return false; } $this->cipher_name_openssl_ecb = 'bf-ecb'; $this->cipher_name_openssl = 'bf-' . $this->openssl_translate_mode(); } return parent::isValidEngineHelper($engine); } /** * Setup the key (expansion) * * @see Common\SymmetricKey::_setupKey() */ protected function setupKey() { if (isset($this->kl['key']) && $this->key === $this->kl['key']) { // already expanded return; } $this->kl = ['key' => $this->key]; /* key-expanding p[] and S-Box building sb[] */ $this->bctx = [ 'p' => [], 'sb' => self::$sbox ]; // unpack binary string in unsigned chars $key = array_values(unpack('C*', $this->key)); $keyl = count($key); // with bcrypt $keyl will always be 16 (because the key is the sha512 of the key you provide) for ($j = 0, $i = 0; $i < 18; ++$i) { // xor P1 with the first 32-bits of the key, xor P2 with the second 32-bits ... for ($data = 0, $k = 0; $k < 4; ++$k) { $data = ($data << 8) | $key[$j]; if (++$j >= $keyl) { $j = 0; } } $this->bctx['p'][] = self::$parray[$i] ^ intval($data); } // encrypt the zero-string, replace P1 and P2 with the encrypted data, // encrypt P3 and P4 with the new P1 and P2, do it with all P-array and subkeys $data = "\0\0\0\0\0\0\0\0"; for ($i = 0; $i < 18; $i += 2) { list($l, $r) = array_values(unpack('N*', $data = $this->encryptBlock($data))); $this->bctx['p'][$i ] = $l; $this->bctx['p'][$i + 1] = $r; } for ($i = 0; $i < 0x400; $i += 0x100) { for ($j = 0; $j < 256; $j += 2) { list($l, $r) = array_values(unpack('N*', $data = $this->encryptBlock($data))); $this->bctx['sb'][$i | $j] = $l; $this->bctx['sb'][$i | ($j + 1)] = $r; } } } /** * Initialize Static Variables */ protected static function initialize_static_variables() { if (is_float(self::$sbox[0x200])) { self::$sbox = array_map('intval', self::$sbox); self::$parray = array_map('intval', self::$parray); } parent::initialize_static_variables(); } /** * bcrypt * * @param string $sha2pass * @param string $sha2salt * @access private * @return string */ private static function bcrypt_hash($sha2pass, $sha2salt) { $p = self::$parray; $sbox = self::$sbox; $cdata = array_values(unpack('N*', 'OxychromaticBlowfishSwatDynamite')); $sha2pass = array_values(unpack('N*', $sha2pass)); $sha2salt = array_values(unpack('N*', $sha2salt)); self::expandstate($sha2salt, $sha2pass, $sbox, $p); for ($i = 0; $i < 64; $i++) { self::expand0state($sha2salt, $sbox, $p); self::expand0state($sha2pass, $sbox, $p); } for ($i = 0; $i < 64; $i++) { for ($j = 0; $j < 8; $j += 2) { // count($cdata) == 8 list($cdata[$j], $cdata[$j + 1]) = self::encryptBlockHelperFast($cdata[$j], $cdata[$j + 1], $sbox, $p); } } return pack('V*', ...$cdata); } /** * Performs OpenSSH-style bcrypt * * @param string $pass * @param string $salt * @param int $keylen * @param int $rounds * @access public * @return string */ public static function bcrypt_pbkdf($pass, $salt, $keylen, $rounds) { self::initialize_static_variables(); if (PHP_INT_SIZE == 4) { throw new \RuntimeException('bcrypt is far too slow to be practical on 32-bit versions of PHP'); } $sha2pass = hash('sha512', $pass, true); $results = []; $count = 1; while (32 * count($results) < $keylen) { $countsalt = $salt . pack('N', $count++); $sha2salt = hash('sha512', $countsalt, true); $out = $tmpout = self::bcrypt_hash($sha2pass, $sha2salt); for ($i = 1; $i < $rounds; $i++) { $sha2salt = hash('sha512', $tmpout, true); $tmpout = self::bcrypt_hash($sha2pass, $sha2salt); $out ^= $tmpout; } $results[] = $out; } $output = ''; for ($i = 0; $i < 32; $i++) { foreach ($results as $result) { $output .= $result[$i]; } } return substr($output, 0, $keylen); } /** * Key expansion without salt * * @access private * @param int[] $key * @param int[] $sbox * @param int[] $p * @see self::_bcrypt_hash() */ private static function expand0state(array $key, array &$sbox, array &$p) { // expand0state is basically the same thing as this: //return self::expandstate(array_fill(0, 16, 0), $key); // but this separate function eliminates a bunch of XORs and array lookups $p = [ $p[0] ^ $key[0], $p[1] ^ $key[1], $p[2] ^ $key[2], $p[3] ^ $key[3], $p[4] ^ $key[4], $p[5] ^ $key[5], $p[6] ^ $key[6], $p[7] ^ $key[7], $p[8] ^ $key[8], $p[9] ^ $key[9], $p[10] ^ $key[10], $p[11] ^ $key[11], $p[12] ^ $key[12], $p[13] ^ $key[13], $p[14] ^ $key[14], $p[15] ^ $key[15], $p[16] ^ $key[0], $p[17] ^ $key[1] ]; // @codingStandardsIgnoreStart list( $p[0], $p[1]) = self::encryptBlockHelperFast( 0, 0, $sbox, $p); list( $p[2], $p[3]) = self::encryptBlockHelperFast($p[ 0], $p[ 1], $sbox, $p); list( $p[4], $p[5]) = self::encryptBlockHelperFast($p[ 2], $p[ 3], $sbox, $p); list( $p[6], $p[7]) = self::encryptBlockHelperFast($p[ 4], $p[ 5], $sbox, $p); list( $p[8], $p[9]) = self::encryptBlockHelperFast($p[ 6], $p[ 7], $sbox, $p); list($p[10], $p[11]) = self::encryptBlockHelperFast($p[ 8], $p[ 9], $sbox, $p); list($p[12], $p[13]) = self::encryptBlockHelperFast($p[10], $p[11], $sbox, $p); list($p[14], $p[15]) = self::encryptBlockHelperFast($p[12], $p[13], $sbox, $p); list($p[16], $p[17]) = self::encryptBlockHelperFast($p[14], $p[15], $sbox, $p); // @codingStandardsIgnoreEnd list($sbox[0], $sbox[1]) = self::encryptBlockHelperFast($p[16], $p[17], $sbox, $p); for ($i = 2; $i < 1024; $i += 2) { list($sbox[$i], $sbox[$i + 1]) = self::encryptBlockHelperFast($sbox[$i - 2], $sbox[$i - 1], $sbox, $p); } } /** * Key expansion with salt * * @access private * @param int[] $data * @param int[] $key * @param int[] $sbox * @param int[] $p * @see self::_bcrypt_hash() */ private static function expandstate(array $data, array $key, array &$sbox, array &$p) { $p = [ $p[0] ^ $key[0], $p[1] ^ $key[1], $p[2] ^ $key[2], $p[3] ^ $key[3], $p[4] ^ $key[4], $p[5] ^ $key[5], $p[6] ^ $key[6], $p[7] ^ $key[7], $p[8] ^ $key[8], $p[9] ^ $key[9], $p[10] ^ $key[10], $p[11] ^ $key[11], $p[12] ^ $key[12], $p[13] ^ $key[13], $p[14] ^ $key[14], $p[15] ^ $key[15], $p[16] ^ $key[0], $p[17] ^ $key[1] ]; // @codingStandardsIgnoreStart list( $p[0], $p[1]) = self::encryptBlockHelperFast($data[ 0] , $data[ 1] , $sbox, $p); list( $p[2], $p[3]) = self::encryptBlockHelperFast($data[ 2] ^ $p[ 0], $data[ 3] ^ $p[ 1], $sbox, $p); list( $p[4], $p[5]) = self::encryptBlockHelperFast($data[ 4] ^ $p[ 2], $data[ 5] ^ $p[ 3], $sbox, $p); list( $p[6], $p[7]) = self::encryptBlockHelperFast($data[ 6] ^ $p[ 4], $data[ 7] ^ $p[ 5], $sbox, $p); list( $p[8], $p[9]) = self::encryptBlockHelperFast($data[ 8] ^ $p[ 6], $data[ 9] ^ $p[ 7], $sbox, $p); list($p[10], $p[11]) = self::encryptBlockHelperFast($data[10] ^ $p[ 8], $data[11] ^ $p[ 9], $sbox, $p); list($p[12], $p[13]) = self::encryptBlockHelperFast($data[12] ^ $p[10], $data[13] ^ $p[11], $sbox, $p); list($p[14], $p[15]) = self::encryptBlockHelperFast($data[14] ^ $p[12], $data[15] ^ $p[13], $sbox, $p); list($p[16], $p[17]) = self::encryptBlockHelperFast($data[ 0] ^ $p[14], $data[ 1] ^ $p[15], $sbox, $p); // @codingStandardsIgnoreEnd list($sbox[0], $sbox[1]) = self::encryptBlockHelperFast($data[2] ^ $p[16], $data[3] ^ $p[17], $sbox, $p); for ($i = 2, $j = 4; $i < 1024; $i += 2, $j = ($j + 2) % 16) { // instead of 16 maybe count($data) would be better? list($sbox[$i], $sbox[$i + 1]) = self::encryptBlockHelperFast($data[$j] ^ $sbox[$i - 2], $data[$j + 1] ^ $sbox[$i - 1], $sbox, $p); } } /** * Encrypts a block * * @param string $in * @return string */ protected function encryptBlock($in) { $p = $this->bctx['p']; // extract($this->bctx['sb'], EXTR_PREFIX_ALL, 'sb'); // slower $sb = $this->bctx['sb']; $in = unpack('N*', $in); $l = $in[1]; $r = $in[2]; list($r, $l) = PHP_INT_SIZE == 4 ? self::encryptBlockHelperSlow($l, $r, $sb, $p) : self::encryptBlockHelperFast($l, $r, $sb, $p); return pack("N*", $r, $l); } /** * Fast helper function for block encryption * * @access private * @param int $x0 * @param int $x1 * @param int[] $sbox * @param int[] $p * @return int[] */ private static function encryptBlockHelperFast($x0, $x1, array $sbox, array $p) { $x0 ^= $p[0]; $x1 ^= ((($sbox[($x0 & 0xFF000000) >> 24] + $sbox[0x100 | (($x0 & 0xFF0000) >> 16)]) ^ $sbox[0x200 | (($x0 & 0xFF00) >> 8)]) + $sbox[0x300 | ($x0 & 0xFF)]) ^ $p[1]; $x0 ^= ((($sbox[($x1 & 0xFF000000) >> 24] + $sbox[0x100 | (($x1 & 0xFF0000) >> 16)]) ^ $sbox[0x200 | (($x1 & 0xFF00) >> 8)]) + $sbox[0x300 | ($x1 & 0xFF)]) ^ $p[2]; $x1 ^= ((($sbox[($x0 & 0xFF000000) >> 24] + $sbox[0x100 | (($x0 & 0xFF0000) >> 16)]) ^ $sbox[0x200 | (($x0 & 0xFF00) >> 8)]) + $sbox[0x300 | ($x0 & 0xFF)]) ^ $p[3]; $x0 ^= ((($sbox[($x1 & 0xFF000000) >> 24] + $sbox[0x100 | (($x1 & 0xFF0000) >> 16)]) ^ $sbox[0x200 | (($x1 & 0xFF00) >> 8)]) + $sbox[0x300 | ($x1 & 0xFF)]) ^ $p[4]; $x1 ^= ((($sbox[($x0 & 0xFF000000) >> 24] + $sbox[0x100 | (($x0 & 0xFF0000) >> 16)]) ^ $sbox[0x200 | (($x0 & 0xFF00) >> 8)]) + $sbox[0x300 | ($x0 & 0xFF)]) ^ $p[5]; $x0 ^= ((($sbox[($x1 & 0xFF000000) >> 24] + $sbox[0x100 | (($x1 & 0xFF0000) >> 16)]) ^ $sbox[0x200 | (($x1 & 0xFF00) >> 8)]) + $sbox[0x300 | ($x1 & 0xFF)]) ^ $p[6]; $x1 ^= ((($sbox[($x0 & 0xFF000000) >> 24] + $sbox[0x100 | (($x0 & 0xFF0000) >> 16)]) ^ $sbox[0x200 | (($x0 & 0xFF00) >> 8)]) + $sbox[0x300 | ($x0 & 0xFF)]) ^ $p[7]; $x0 ^= ((($sbox[($x1 & 0xFF000000) >> 24] + $sbox[0x100 | (($x1 & 0xFF0000) >> 16)]) ^ $sbox[0x200 | (($x1 & 0xFF00) >> 8)]) + $sbox[0x300 | ($x1 & 0xFF)]) ^ $p[8]; $x1 ^= ((($sbox[($x0 & 0xFF000000) >> 24] + $sbox[0x100 | (($x0 & 0xFF0000) >> 16)]) ^ $sbox[0x200 | (($x0 & 0xFF00) >> 8)]) + $sbox[0x300 | ($x0 & 0xFF)]) ^ $p[9]; $x0 ^= ((($sbox[($x1 & 0xFF000000) >> 24] + $sbox[0x100 | (($x1 & 0xFF0000) >> 16)]) ^ $sbox[0x200 | (($x1 & 0xFF00) >> 8)]) + $sbox[0x300 | ($x1 & 0xFF)]) ^ $p[10]; $x1 ^= ((($sbox[($x0 & 0xFF000000) >> 24] + $sbox[0x100 | (($x0 & 0xFF0000) >> 16)]) ^ $sbox[0x200 | (($x0 & 0xFF00) >> 8)]) + $sbox[0x300 | ($x0 & 0xFF)]) ^ $p[11]; $x0 ^= ((($sbox[($x1 & 0xFF000000) >> 24] + $sbox[0x100 | (($x1 & 0xFF0000) >> 16)]) ^ $sbox[0x200 | (($x1 & 0xFF00) >> 8)]) + $sbox[0x300 | ($x1 & 0xFF)]) ^ $p[12]; $x1 ^= ((($sbox[($x0 & 0xFF000000) >> 24] + $sbox[0x100 | (($x0 & 0xFF0000) >> 16)]) ^ $sbox[0x200 | (($x0 & 0xFF00) >> 8)]) + $sbox[0x300 | ($x0 & 0xFF)]) ^ $p[13]; $x0 ^= ((($sbox[($x1 & 0xFF000000) >> 24] + $sbox[0x100 | (($x1 & 0xFF0000) >> 16)]) ^ $sbox[0x200 | (($x1 & 0xFF00) >> 8)]) + $sbox[0x300 | ($x1 & 0xFF)]) ^ $p[14]; $x1 ^= ((($sbox[($x0 & 0xFF000000) >> 24] + $sbox[0x100 | (($x0 & 0xFF0000) >> 16)]) ^ $sbox[0x200 | (($x0 & 0xFF00) >> 8)]) + $sbox[0x300 | ($x0 & 0xFF)]) ^ $p[15]; $x0 ^= ((($sbox[($x1 & 0xFF000000) >> 24] + $sbox[0x100 | (($x1 & 0xFF0000) >> 16)]) ^ $sbox[0x200 | (($x1 & 0xFF00) >> 8)]) + $sbox[0x300 | ($x1 & 0xFF)]) ^ $p[16]; return [$x1 & 0xFFFFFFFF ^ $p[17], $x0 & 0xFFFFFFFF]; } /** * Slow helper function for block encryption * * @access private * @param int $x0 * @param int $x1 * @param int[] $sbox * @param int[] $p * @return int[] */ private static function encryptBlockHelperSlow($x0, $x1, array $sbox, array $p) { // -16777216 == intval(0xFF000000) on 32-bit PHP installs $x0 ^= $p[0]; $x1 ^= self::safe_intval((self::safe_intval($sbox[(($x0 & -16777216) >> 24) & 0xFF] + $sbox[0x100 | (($x0 & 0xFF0000) >> 16)]) ^ $sbox[0x200 | (($x0 & 0xFF00) >> 8)]) + $sbox[0x300 | ($x0 & 0xFF)]) ^ $p[1]; $x0 ^= self::safe_intval((self::safe_intval($sbox[(($x1 & -16777216) >> 24) & 0xFF] + $sbox[0x100 | (($x1 & 0xFF0000) >> 16)]) ^ $sbox[0x200 | (($x1 & 0xFF00) >> 8)]) + $sbox[0x300 | ($x1 & 0xFF)]) ^ $p[2]; $x1 ^= self::safe_intval((self::safe_intval($sbox[(($x0 & -16777216) >> 24) & 0xFF] + $sbox[0x100 | (($x0 & 0xFF0000) >> 16)]) ^ $sbox[0x200 | (($x0 & 0xFF00) >> 8)]) + $sbox[0x300 | ($x0 & 0xFF)]) ^ $p[3]; $x0 ^= self::safe_intval((self::safe_intval($sbox[(($x1 & -16777216) >> 24) & 0xFF] + $sbox[0x100 | (($x1 & 0xFF0000) >> 16)]) ^ $sbox[0x200 | (($x1 & 0xFF00) >> 8)]) + $sbox[0x300 | ($x1 & 0xFF)]) ^ $p[4]; $x1 ^= self::safe_intval((self::safe_intval($sbox[(($x0 & -16777216) >> 24) & 0xFF] + $sbox[0x100 | (($x0 & 0xFF0000) >> 16)]) ^ $sbox[0x200 | (($x0 & 0xFF00) >> 8)]) + $sbox[0x300 | ($x0 & 0xFF)]) ^ $p[5]; $x0 ^= self::safe_intval((self::safe_intval($sbox[(($x1 & -16777216) >> 24) & 0xFF] + $sbox[0x100 | (($x1 & 0xFF0000) >> 16)]) ^ $sbox[0x200 | (($x1 & 0xFF00) >> 8)]) + $sbox[0x300 | ($x1 & 0xFF)]) ^ $p[6]; $x1 ^= self::safe_intval((self::safe_intval($sbox[(($x0 & -16777216) >> 24) & 0xFF] + $sbox[0x100 | (($x0 & 0xFF0000) >> 16)]) ^ $sbox[0x200 | (($x0 & 0xFF00) >> 8)]) + $sbox[0x300 | ($x0 & 0xFF)]) ^ $p[7]; $x0 ^= self::safe_intval((self::safe_intval($sbox[(($x1 & -16777216) >> 24) & 0xFF] + $sbox[0x100 | (($x1 & 0xFF0000) >> 16)]) ^ $sbox[0x200 | (($x1 & 0xFF00) >> 8)]) + $sbox[0x300 | ($x1 & 0xFF)]) ^ $p[8]; $x1 ^= self::safe_intval((self::safe_intval($sbox[(($x0 & -16777216) >> 24) & 0xFF] + $sbox[0x100 | (($x0 & 0xFF0000) >> 16)]) ^ $sbox[0x200 | (($x0 & 0xFF00) >> 8)]) + $sbox[0x300 | ($x0 & 0xFF)]) ^ $p[9]; $x0 ^= self::safe_intval((self::safe_intval($sbox[(($x1 & -16777216) >> 24) & 0xFF] + $sbox[0x100 | (($x1 & 0xFF0000) >> 16)]) ^ $sbox[0x200 | (($x1 & 0xFF00) >> 8)]) + $sbox[0x300 | ($x1 & 0xFF)]) ^ $p[10]; $x1 ^= self::safe_intval((self::safe_intval($sbox[(($x0 & -16777216) >> 24) & 0xFF] + $sbox[0x100 | (($x0 & 0xFF0000) >> 16)]) ^ $sbox[0x200 | (($x0 & 0xFF00) >> 8)]) + $sbox[0x300 | ($x0 & 0xFF)]) ^ $p[11]; $x0 ^= self::safe_intval((self::safe_intval($sbox[(($x1 & -16777216) >> 24) & 0xFF] + $sbox[0x100 | (($x1 & 0xFF0000) >> 16)]) ^ $sbox[0x200 | (($x1 & 0xFF00) >> 8)]) + $sbox[0x300 | ($x1 & 0xFF)]) ^ $p[12]; $x1 ^= self::safe_intval((self::safe_intval($sbox[(($x0 & -16777216) >> 24) & 0xFF] + $sbox[0x100 | (($x0 & 0xFF0000) >> 16)]) ^ $sbox[0x200 | (($x0 & 0xFF00) >> 8)]) + $sbox[0x300 | ($x0 & 0xFF)]) ^ $p[13]; $x0 ^= self::safe_intval((self::safe_intval($sbox[(($x1 & -16777216) >> 24) & 0xFF] + $sbox[0x100 | (($x1 & 0xFF0000) >> 16)]) ^ $sbox[0x200 | (($x1 & 0xFF00) >> 8)]) + $sbox[0x300 | ($x1 & 0xFF)]) ^ $p[14]; $x1 ^= self::safe_intval((self::safe_intval($sbox[(($x0 & -16777216) >> 24) & 0xFF] + $sbox[0x100 | (($x0 & 0xFF0000) >> 16)]) ^ $sbox[0x200 | (($x0 & 0xFF00) >> 8)]) + $sbox[0x300 | ($x0 & 0xFF)]) ^ $p[15]; $x0 ^= self::safe_intval((self::safe_intval($sbox[(($x1 & -16777216) >> 24) & 0xFF] + $sbox[0x100 | (($x1 & 0xFF0000) >> 16)]) ^ $sbox[0x200 | (($x1 & 0xFF00) >> 8)]) + $sbox[0x300 | ($x1 & 0xFF)]) ^ $p[16]; return [$x1 ^ $p[17], $x0]; } /** * Decrypts a block * * @param string $in * @return string */ protected function decryptBlock($in) { $p = $this->bctx['p']; $sb = $this->bctx['sb']; $in = unpack('N*', $in); $l = $in[1]; $r = $in[2]; for ($i = 17; $i > 2; $i -= 2) { $l ^= $p[$i]; $r ^= self::safe_intval((self::safe_intval($sb[$l >> 24 & 0xff] + $sb[0x100 + ($l >> 16 & 0xff)]) ^ $sb[0x200 + ($l >> 8 & 0xff)]) + $sb[0x300 + ($l & 0xff)]); $r ^= $p[$i - 1]; $l ^= self::safe_intval((self::safe_intval($sb[$r >> 24 & 0xff] + $sb[0x100 + ($r >> 16 & 0xff)]) ^ $sb[0x200 + ($r >> 8 & 0xff)]) + $sb[0x300 + ($r & 0xff)]); } return pack('N*', $r ^ $p[0], $l ^ $p[1]); } /** * Setup the performance-optimized function for de/encrypt() * * @see Common\SymmetricKey::_setupInlineCrypt() */ protected function setupInlineCrypt() { $p = $this->bctx['p']; $init_crypt = ' static $sb; if (!$sb) { $sb = $this->bctx["sb"]; } '; $safeint = self::safe_intval_inline(); // Generating encrypt code: $encrypt_block = ' $in = unpack("N*", $in); $l = $in[1]; $r = $in[2]; '; for ($i = 0; $i < 16; $i += 2) { $encrypt_block .= ' $l^= ' . $p[$i] . '; $r^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb[$l >> 24 & 0xff] + $sb[0x100 + ($l >> 16 & 0xff)]') . ' ^ $sb[0x200 + ($l >> 8 & 0xff)]) + $sb[0x300 + ($l & 0xff)]') . '; $r^= ' . $p[$i + 1] . '; $l^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb[$r >> 24 & 0xff] + $sb[0x100 + ($r >> 16 & 0xff)]') . ' ^ $sb[0x200 + ($r >> 8 & 0xff)]) + $sb[0x300 + ($r & 0xff)]') . '; '; } $encrypt_block .= ' $in = pack("N*", $r ^ ' . $p[17] . ', $l ^ ' . $p[16] . ' ); '; // Generating decrypt code: $decrypt_block = ' $in = unpack("N*", $in); $l = $in[1]; $r = $in[2]; '; for ($i = 17; $i > 2; $i -= 2) { $decrypt_block .= ' $l^= ' . $p[$i] . '; $r^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb[$l >> 24 & 0xff] + $sb[0x100 + ($l >> 16 & 0xff)]') . ' ^ $sb[0x200 + ($l >> 8 & 0xff)]) + $sb[0x300 + ($l & 0xff)]') . '; $r^= ' . $p[$i - 1] . '; $l^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb[$r >> 24 & 0xff] + $sb[0x100 + ($r >> 16 & 0xff)]') . ' ^ $sb[0x200 + ($r >> 8 & 0xff)]) + $sb[0x300 + ($r & 0xff)]') . '; '; } $decrypt_block .= ' $in = pack("N*", $r ^ ' . $p[0] . ', $l ^ ' . $p[1] . ' ); '; $this->inline_crypt = $this->createInlineCryptFunction( [ 'init_crypt' => $init_crypt, 'init_encrypt' => '', 'init_decrypt' => '', 'encrypt_block' => $encrypt_block, 'decrypt_block' => $decrypt_block ] ); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/ChaCha20.php ================================================ * @copyright 2019 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt; use phpseclib3\Exception\BadDecryptionException; use phpseclib3\Exception\InsufficientSetupException; /** * Pure-PHP implementation of ChaCha20. * * @author Jim Wigginton */ class ChaCha20 extends Salsa20 { /** * The OpenSSL specific name of the cipher * * @var string */ protected $cipher_name_openssl = 'chacha20'; /** * Test for engine validity * * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() * * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() * @param int $engine * @return bool */ protected function isValidEngineHelper($engine) { switch ($engine) { case self::ENGINE_LIBSODIUM: // PHP 7.2.0 (30 Nov 2017) added support for libsodium // we could probably make it so that if $this->counter == 0 then the first block would be done with either OpenSSL // or PHP and then subsequent blocks would then be done with libsodium but idk - it's not a high priority atm // we could also make it so that if $this->counter == 0 and $this->continuousBuffer then do the first string // with libsodium and subsequent strings with openssl or pure-PHP but again not a high priority return function_exists('sodium_crypto_aead_chacha20poly1305_ietf_encrypt') && $this->key_length == 32 && (($this->usePoly1305 && !isset($this->poly1305Key) && $this->counter == 0) || $this->counter == 1) && !$this->continuousBuffer; case self::ENGINE_OPENSSL: // OpenSSL 1.1.0 (released 25 Aug 2016) added support for chacha20. // PHP didn't support OpenSSL 1.1.0 until 7.0.19 (11 May 2017) // if you attempt to provide openssl with a 128 bit key (as opposed to a 256 bit key) openssl will null // pad the key to 256 bits and still use the expansion constant for 256-bit keys. the fact that // openssl treats the IV as both the counter and nonce, however, let's us use openssl in continuous mode // whereas libsodium does not if ($this->key_length != 32) { return false; } } return parent::isValidEngineHelper($engine); } /** * Encrypts a message. * * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() * @see self::crypt() * @param string $plaintext * @return string $ciphertext */ public function encrypt($plaintext) { $this->setup(); if ($this->engine == self::ENGINE_LIBSODIUM) { return $this->encrypt_with_libsodium($plaintext); } return parent::encrypt($plaintext); } /** * Decrypts a message. * * $this->decrypt($this->encrypt($plaintext)) == $this->encrypt($this->encrypt($plaintext)). * At least if the continuous buffer is disabled. * * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() * @see self::crypt() * @param string $ciphertext * @return string $plaintext */ public function decrypt($ciphertext) { $this->setup(); if ($this->engine == self::ENGINE_LIBSODIUM) { return $this->decrypt_with_libsodium($ciphertext); } return parent::decrypt($ciphertext); } /** * Encrypts a message with libsodium * * @see self::encrypt() * @param string $plaintext * @return string $text */ private function encrypt_with_libsodium($plaintext) { $params = [$plaintext, $this->aad, $this->nonce, $this->key]; $ciphertext = strlen($this->nonce) == 8 ? sodium_crypto_aead_chacha20poly1305_encrypt(...$params) : sodium_crypto_aead_chacha20poly1305_ietf_encrypt(...$params); if (!$this->usePoly1305) { return substr($ciphertext, 0, strlen($plaintext)); } $newciphertext = substr($ciphertext, 0, strlen($plaintext)); $this->newtag = $this->usingGeneratedPoly1305Key && strlen($this->nonce) == 12 ? substr($ciphertext, strlen($plaintext)) : $this->poly1305($newciphertext); return $newciphertext; } /** * Decrypts a message with libsodium * * @see self::decrypt() * @param string $ciphertext * @return string $text */ private function decrypt_with_libsodium($ciphertext) { $params = [$ciphertext, $this->aad, $this->nonce, $this->key]; if (isset($this->poly1305Key)) { if ($this->oldtag === false) { throw new InsufficientSetupException('Authentication Tag has not been set'); } if ($this->usingGeneratedPoly1305Key && strlen($this->nonce) == 12) { $plaintext = sodium_crypto_aead_chacha20poly1305_ietf_decrypt(...$params); $this->oldtag = false; if ($plaintext === false) { throw new BadDecryptionException('Derived authentication tag and supplied authentication tag do not match'); } return $plaintext; } $newtag = $this->poly1305($ciphertext); if ($this->oldtag != substr($newtag, 0, strlen($this->oldtag))) { $this->oldtag = false; throw new BadDecryptionException('Derived authentication tag and supplied authentication tag do not match'); } $this->oldtag = false; } $plaintext = strlen($this->nonce) == 8 ? sodium_crypto_aead_chacha20poly1305_encrypt(...$params) : sodium_crypto_aead_chacha20poly1305_ietf_encrypt(...$params); return substr($plaintext, 0, strlen($ciphertext)); } /** * Sets the nonce. * * @param string $nonce */ public function setNonce($nonce) { if (!is_string($nonce)) { throw new \UnexpectedValueException('The nonce should be a string'); } /* from https://tools.ietf.org/html/rfc7539#page-7 "Note also that the original ChaCha had a 64-bit nonce and 64-bit block count. We have modified this here to be more consistent with recommendations in Section 3.2 of [RFC5116]." */ switch (strlen($nonce)) { case 8: // 64 bits case 12: // 96 bits break; default: throw new \LengthException('Nonce of size ' . strlen($nonce) . ' not supported by this algorithm. Only 64-bit nonces or 96-bit nonces are supported'); } $this->nonce = $nonce; $this->changed = true; $this->setEngine(); } /** * Setup the self::ENGINE_INTERNAL $engine * * (re)init, if necessary, the internal cipher $engine * * _setup() will be called each time if $changed === true * typically this happens when using one or more of following public methods: * * - setKey() * * - setNonce() * * - First run of encrypt() / decrypt() with no init-settings * * @see self::setKey() * @see self::setNonce() * @see self::disableContinuousBuffer() */ protected function setup() { if (!$this->changed) { return; } $this->enbuffer = $this->debuffer = ['ciphertext' => '', 'counter' => $this->counter]; $this->changed = $this->nonIVChanged = false; if ($this->nonce === false) { throw new InsufficientSetupException('No nonce has been defined'); } if ($this->key === false) { throw new InsufficientSetupException('No key has been defined'); } if ($this->usePoly1305 && !isset($this->poly1305Key)) { $this->usingGeneratedPoly1305Key = true; if ($this->engine == self::ENGINE_LIBSODIUM) { return; } $this->createPoly1305Key(); } $key = $this->key; if (strlen($key) == 16) { $constant = 'expand 16-byte k'; $key .= $key; } else { $constant = 'expand 32-byte k'; } $this->p1 = $constant . $key; $this->p2 = $this->nonce; if (strlen($this->nonce) == 8) { $this->p2 = "\0\0\0\0" . $this->p2; } } /** * The quarterround function * * @param int $a * @param int $b * @param int $c * @param int $d */ protected static function quarterRound(&$a, &$b, &$c, &$d) { // in https://datatracker.ietf.org/doc/html/rfc7539#section-2.1 the addition, // xor'ing and rotation are all on the same line so i'm keeping it on the same // line here as well // @codingStandardsIgnoreStart $a+= $b; $d = self::leftRotate(intval($d) ^ intval($a), 16); $c+= $d; $b = self::leftRotate(intval($b) ^ intval($c), 12); $a+= $b; $d = self::leftRotate(intval($d) ^ intval($a), 8); $c+= $d; $b = self::leftRotate(intval($b) ^ intval($c), 7); // @codingStandardsIgnoreEnd } /** * The doubleround function * * @param int $x0 (by reference) * @param int $x1 (by reference) * @param int $x2 (by reference) * @param int $x3 (by reference) * @param int $x4 (by reference) * @param int $x5 (by reference) * @param int $x6 (by reference) * @param int $x7 (by reference) * @param int $x8 (by reference) * @param int $x9 (by reference) * @param int $x10 (by reference) * @param int $x11 (by reference) * @param int $x12 (by reference) * @param int $x13 (by reference) * @param int $x14 (by reference) * @param int $x15 (by reference) */ protected static function doubleRound(&$x0, &$x1, &$x2, &$x3, &$x4, &$x5, &$x6, &$x7, &$x8, &$x9, &$x10, &$x11, &$x12, &$x13, &$x14, &$x15) { // columnRound static::quarterRound($x0, $x4, $x8, $x12); static::quarterRound($x1, $x5, $x9, $x13); static::quarterRound($x2, $x6, $x10, $x14); static::quarterRound($x3, $x7, $x11, $x15); // rowRound static::quarterRound($x0, $x5, $x10, $x15); static::quarterRound($x1, $x6, $x11, $x12); static::quarterRound($x2, $x7, $x8, $x13); static::quarterRound($x3, $x4, $x9, $x14); } /** * The Salsa20 hash function function * * On my laptop this loop unrolled / function dereferenced version of parent::salsa20 encrypts 1mb of text in * 0.65s vs the 0.85s that it takes with the parent method. * * If we were free to assume that the host OS would always be 64-bits then the if condition in leftRotate could * be eliminated and we could knock this done to 0.60s. * * For comparison purposes, RC4 takes 0.16s and AES in CTR mode with the Eval engine takes 0.48s. * AES in CTR mode with the PHP engine takes 1.19s. Salsa20 / ChaCha20 do not benefit as much from the Eval * approach due to the fact that there are a lot less variables to de-reference, fewer loops to unroll, etc * * @param string $x */ protected static function salsa20($x) { list(, $x0, $x1, $x2, $x3, $x4, $x5, $x6, $x7, $x8, $x9, $x10, $x11, $x12, $x13, $x14, $x15) = unpack('V*', $x); $z0 = $x0; $z1 = $x1; $z2 = $x2; $z3 = $x3; $z4 = $x4; $z5 = $x5; $z6 = $x6; $z7 = $x7; $z8 = $x8; $z9 = $x9; $z10 = $x10; $z11 = $x11; $z12 = $x12; $z13 = $x13; $z14 = $x14; $z15 = $x15; // @codingStandardsIgnoreStart // columnRound $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16); $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12); $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8); $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7); $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16); $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12); $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8); $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7); $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16); $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12); $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8); $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7); $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16); $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12); $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8); $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7); // rowRound $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16); $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12); $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8); $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7); $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16); $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12); $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8); $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7); $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16); $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12); $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8); $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7); $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16); $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12); $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8); $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7); // columnRound $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16); $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12); $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8); $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7); $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16); $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12); $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8); $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7); $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16); $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12); $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8); $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7); $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16); $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12); $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8); $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7); // rowRound $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16); $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12); $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8); $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7); $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16); $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12); $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8); $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7); $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16); $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12); $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8); $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7); $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16); $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12); $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8); $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7); // columnRound $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16); $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12); $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8); $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7); $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16); $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12); $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8); $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7); $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16); $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12); $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8); $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7); $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16); $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12); $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8); $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7); // rowRound $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16); $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12); $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8); $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7); $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16); $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12); $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8); $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7); $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16); $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12); $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8); $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7); $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16); $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12); $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8); $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7); // columnRound $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16); $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12); $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8); $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7); $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16); $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12); $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8); $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7); $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16); $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12); $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8); $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7); $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16); $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12); $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8); $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7); // rowRound $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16); $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12); $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8); $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7); $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16); $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12); $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8); $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7); $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16); $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12); $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8); $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7); $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16); $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12); $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8); $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7); // columnRound $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16); $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12); $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8); $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7); $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16); $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12); $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8); $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7); $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16); $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12); $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8); $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7); $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16); $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12); $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8); $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7); // rowRound $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16); $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12); $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8); $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7); $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16); $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12); $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8); $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7); $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16); $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12); $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8); $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7); $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16); $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12); $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8); $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7); // columnRound $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16); $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12); $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8); $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7); $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16); $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12); $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8); $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7); $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16); $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12); $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8); $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7); $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16); $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12); $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8); $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7); // rowRound $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16); $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12); $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8); $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7); $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16); $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12); $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8); $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7); $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16); $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12); $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8); $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7); $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16); $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12); $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8); $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7); // columnRound $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16); $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12); $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8); $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7); $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16); $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12); $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8); $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7); $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16); $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12); $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8); $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7); $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16); $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12); $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8); $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7); // rowRound $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16); $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12); $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8); $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7); $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16); $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12); $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8); $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7); $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16); $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12); $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8); $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7); $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16); $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12); $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8); $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7); // columnRound $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16); $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12); $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8); $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7); $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16); $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12); $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8); $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7); $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16); $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12); $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8); $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7); $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16); $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12); $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8); $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7); // rowRound $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16); $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12); $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8); $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7); $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16); $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12); $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8); $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7); $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16); $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12); $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8); $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7); $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16); $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12); $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8); $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7); // columnRound $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16); $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12); $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8); $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7); $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16); $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12); $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8); $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7); $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16); $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12); $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8); $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7); $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16); $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12); $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8); $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7); // rowRound $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16); $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12); $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8); $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7); $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16); $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12); $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8); $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7); $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16); $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12); $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8); $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7); $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16); $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12); $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8); $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7); // columnRound $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16); $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12); $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8); $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7); $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16); $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12); $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8); $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7); $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16); $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12); $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8); $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7); $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16); $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12); $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8); $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7); // rowRound $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16); $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12); $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8); $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7); $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16); $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12); $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8); $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7); $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16); $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12); $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8); $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7); $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16); $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12); $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8); $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7); // @codingStandardsIgnoreEnd $x0 += $z0; $x1 += $z1; $x2 += $z2; $x3 += $z3; $x4 += $z4; $x5 += $z5; $x6 += $z6; $x7 += $z7; $x8 += $z8; $x9 += $z9; $x10 += $z10; $x11 += $z11; $x12 += $z12; $x13 += $z13; $x14 += $z14; $x15 += $z15; return pack('V*', $x0, $x1, $x2, $x3, $x4, $x5, $x6, $x7, $x8, $x9, $x10, $x11, $x12, $x13, $x14, $x15); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\Common; use phpseclib3\Crypt\DSA; use phpseclib3\Crypt\Hash; use phpseclib3\Crypt\RSA; use phpseclib3\Exception\NoKeyLoadedException; use phpseclib3\Exception\UnsupportedFormatException; use phpseclib3\Math\BigInteger; /** * Base Class for all asymmetric cipher classes * * @author Jim Wigginton */ abstract class AsymmetricKey { /** * Precomputed Zero * * @var BigInteger */ protected static $zero; /** * Precomputed One * * @var BigInteger */ protected static $one; /** * Format of the loaded key * * @var string */ protected $format; /** * Hash function * * @var Hash */ protected $hash; /** * HMAC function * * @var Hash */ private $hmac; /** * Supported plugins (lower case) * * @see self::initialize_static_variables() * @var array */ private static $plugins = []; /** * Invisible plugins * * @see self::initialize_static_variables() * @var array */ private static $invisiblePlugins = []; /** * Available Engines * * @var boolean[] */ protected static $engines = []; /** * Key Comment * * @var null|string */ private $comment; /** * @param string $type * @return array|string */ abstract public function toString($type, array $options = []); /** * The constructor */ protected function __construct() { self::initialize_static_variables(); $this->hash = new Hash('sha256'); $this->hmac = new Hash('sha256'); } /** * Initialize static variables */ protected static function initialize_static_variables() { if (!isset(self::$zero)) { self::$zero = new BigInteger(0); self::$one = new BigInteger(1); } self::loadPlugins('Keys'); if (static::ALGORITHM != 'RSA' && static::ALGORITHM != 'DH') { self::loadPlugins('Signature'); } } /** * Load the key * * @param string $key * @param string $password optional * @return PublicKey|PrivateKey */ public static function load($key, $password = false) { self::initialize_static_variables(); $class = new \ReflectionClass(static::class); if ($class->isFinal()) { throw new \RuntimeException('load() should not be called from final classes (' . static::class . ')'); } $components = false; foreach (self::$plugins[static::ALGORITHM]['Keys'] as $format) { if (isset(self::$invisiblePlugins[static::ALGORITHM]) && in_array($format, self::$invisiblePlugins[static::ALGORITHM])) { continue; } try { $components = $format::load($key, $password); } catch (\Exception $e) { $components = false; } if ($components !== false) { break; } } if ($components === false) { throw new NoKeyLoadedException('Unable to read key'); } $components['format'] = $format; $components['secret'] = isset($components['secret']) ? $components['secret'] : ''; $comment = isset($components['comment']) ? $components['comment'] : null; $new = static::onLoad($components); $new->format = $format; $new->comment = $comment; return $new instanceof PrivateKey ? $new->withPassword($password) : $new; } /** * Loads a private key * * @return PrivateKey * @param string|array $key * @param string $password optional */ public static function loadPrivateKey($key, $password = '') { $key = self::load($key, $password); if (!$key instanceof PrivateKey) { throw new NoKeyLoadedException('The key that was loaded was not a private key'); } return $key; } /** * Loads a public key * * @return PublicKey * @param string|array $key */ public static function loadPublicKey($key) { $key = self::load($key); if (!$key instanceof PublicKey) { throw new NoKeyLoadedException('The key that was loaded was not a public key'); } return $key; } /** * Loads parameters * * @return AsymmetricKey * @param string|array $key */ public static function loadParameters($key) { $key = self::load($key); if (!$key instanceof PrivateKey && !$key instanceof PublicKey) { throw new NoKeyLoadedException('The key that was loaded was not a parameter'); } return $key; } /** * Load the key, assuming a specific format * * @param string $type * @param string $key * @param string $password optional * @return static */ public static function loadFormat($type, $key, $password = false) { self::initialize_static_variables(); $components = false; $format = strtolower($type); if (isset(self::$plugins[static::ALGORITHM]['Keys'][$format])) { $format = self::$plugins[static::ALGORITHM]['Keys'][$format]; $components = $format::load($key, $password); } if ($components === false) { throw new NoKeyLoadedException('Unable to read key'); } $components['format'] = $format; $components['secret'] = isset($components['secret']) ? $components['secret'] : ''; $new = static::onLoad($components); $new->format = $format; return $new instanceof PrivateKey ? $new->withPassword($password) : $new; } /** * Loads a private key * * @return PrivateKey * @param string $type * @param string $key * @param string $password optional */ public static function loadPrivateKeyFormat($type, $key, $password = false) { $key = self::loadFormat($type, $key, $password); if (!$key instanceof PrivateKey) { throw new NoKeyLoadedException('The key that was loaded was not a private key'); } return $key; } /** * Loads a public key * * @return PublicKey * @param string $type * @param string $key */ public static function loadPublicKeyFormat($type, $key) { $key = self::loadFormat($type, $key); if (!$key instanceof PublicKey) { throw new NoKeyLoadedException('The key that was loaded was not a public key'); } return $key; } /** * Loads parameters * * @return AsymmetricKey * @param string $type * @param string|array $key */ public static function loadParametersFormat($type, $key) { $key = self::loadFormat($type, $key); if (!$key instanceof PrivateKey && !$key instanceof PublicKey) { throw new NoKeyLoadedException('The key that was loaded was not a parameter'); } return $key; } /** * Validate Plugin * * @param string $format * @param string $type * @param string $method optional * @return mixed */ protected static function validatePlugin($format, $type, $method = null) { $type = strtolower($type); if (!isset(self::$plugins[static::ALGORITHM][$format][$type])) { throw new UnsupportedFormatException("$type is not a supported format"); } $type = self::$plugins[static::ALGORITHM][$format][$type]; if (isset($method) && !method_exists($type, $method)) { throw new UnsupportedFormatException("$type does not implement $method"); } return $type; } /** * Load Plugins * * @param string $format */ private static function loadPlugins($format) { if (!isset(self::$plugins[static::ALGORITHM][$format])) { self::$plugins[static::ALGORITHM][$format] = []; foreach (new \DirectoryIterator(__DIR__ . '/../' . static::ALGORITHM . '/Formats/' . $format . '/') as $file) { if ($file->getExtension() != 'php') { continue; } $name = $file->getBasename('.php'); if ($name[0] == '.') { continue; } $type = 'phpseclib3\Crypt\\' . static::ALGORITHM . '\\Formats\\' . $format . '\\' . $name; $reflect = new \ReflectionClass($type); if ($reflect->isTrait()) { continue; } self::$plugins[static::ALGORITHM][$format][strtolower($name)] = $type; if ($reflect->hasConstant('IS_INVISIBLE')) { self::$invisiblePlugins[static::ALGORITHM][] = $type; } } } } /** * Returns a list of supported formats. * * @return array */ public static function getSupportedKeyFormats() { self::initialize_static_variables(); return self::$plugins[static::ALGORITHM]['Keys']; } /** * Add a fileformat plugin * * The plugin needs to either already be loaded or be auto-loadable. * Loading a plugin whose shortname overwrite an existing shortname will overwrite the old plugin. * * @see self::load() * @param string $fullname * @return bool */ public static function addFileFormat($fullname) { self::initialize_static_variables(); if (class_exists($fullname)) { $meta = new \ReflectionClass($fullname); $shortname = $meta->getShortName(); self::$plugins[static::ALGORITHM]['Keys'][strtolower($shortname)] = $fullname; if ($meta->hasConstant('IS_INVISIBLE')) { self::$invisiblePlugins[static::ALGORITHM][] = strtolower($shortname); } } } /** * Returns the format of the loaded key. * * If the key that was loaded wasn't in a valid or if the key was auto-generated * with RSA::createKey() then this will throw an exception. * * @see self::load() * @return mixed */ public function getLoadedFormat() { if (empty($this->format)) { throw new NoKeyLoadedException('This key was created with createKey - it was not loaded with load. Therefore there is no "loaded format"'); } $meta = new \ReflectionClass($this->format); return $meta->getShortName(); } /** * Returns the key's comment * * Not all key formats support comments. If you want to set a comment use toString() * * @return null|string */ public function getComment() { return $this->comment; } /** * Tests engine validity * */ public static function useBestEngine() { static::$engines = [ 'PHP' => true, 'OpenSSL' => extension_loaded('openssl'), // this test can be satisfied by either of the following: // http://php.net/manual/en/book.sodium.php // https://github.com/paragonie/sodium_compat 'libsodium' => function_exists('sodium_crypto_sign_keypair') ]; return static::$engines; } /** * Flag to use internal engine only (useful for unit testing) * */ public static function useInternalEngine() { static::$engines = [ 'PHP' => true, 'OpenSSL' => false, 'libsodium' => false ]; } /** * __toString() magic method * * @return string */ public function __toString() { return $this->toString('PKCS8'); } /** * Determines which hashing function should be used * * @param string $hash */ public function withHash($hash) { $new = clone $this; $new->hash = new Hash($hash); $new->hmac = new Hash($hash); return $new; } /** * Returns the hash algorithm currently being used * */ public function getHash() { return clone $this->hash; } /** * Compute the pseudorandom k for signature generation, * using the process specified for deterministic DSA. * * @param string $h1 * @return string */ protected function computek($h1) { $v = str_repeat("\1", strlen($h1)); $k = str_repeat("\0", strlen($h1)); $x = $this->int2octets($this->x); $h1 = $this->bits2octets($h1); $this->hmac->setKey($k); $k = $this->hmac->hash($v . "\0" . $x . $h1); $this->hmac->setKey($k); $v = $this->hmac->hash($v); $k = $this->hmac->hash($v . "\1" . $x . $h1); $this->hmac->setKey($k); $v = $this->hmac->hash($v); $qlen = $this->q->getLengthInBytes(); while (true) { $t = ''; while (strlen($t) < $qlen) { $v = $this->hmac->hash($v); $t = $t . $v; } $k = $this->bits2int($t); if (!$k->equals(self::$zero) && $k->compare($this->q) < 0) { break; } $k = $this->hmac->hash($v . "\0"); $this->hmac->setKey($k); $v = $this->hmac->hash($v); } return $k; } /** * Integer to Octet String * * @param BigInteger $v * @return string */ private function int2octets($v) { $out = $v->toBytes(); $rolen = $this->q->getLengthInBytes(); if (strlen($out) < $rolen) { return str_pad($out, $rolen, "\0", STR_PAD_LEFT); } elseif (strlen($out) > $rolen) { return substr($out, -$rolen); } else { return $out; } } /** * Bit String to Integer * * @param string $in * @return BigInteger */ protected function bits2int($in) { $v = new BigInteger($in, 256); $vlen = strlen($in) << 3; $qlen = $this->q->getLength(); if ($vlen > $qlen) { return $v->bitwise_rightShift($vlen - $qlen); } return $v; } /** * Bit String to Octet String * * @param string $in * @return string */ private function bits2octets($in) { $z1 = $this->bits2int($in); $z2 = $z1->subtract($this->q); return $z2->compare(self::$zero) < 0 ? $this->int2octets($z1) : $this->int2octets($z2); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/BlockCipher.php ================================================ * @author Hans-Juergen Petrich * @copyright 2007 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\Common; /** * Base Class for all block cipher classes * * @author Jim Wigginton */ abstract class BlockCipher extends SymmetricKey { } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/JWK.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\Common\Formats\Keys; use phpseclib3\Common\Functions\Strings; /** * JSON Web Key Formatted Key Handler * * @author Jim Wigginton */ abstract class JWK { /** * Break a public or private key down into its constituent components * * @param string $key * @param string $password * @return array */ public static function load($key, $password = '') { if (!Strings::is_stringable($key)) { throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); } $key = preg_replace('#\s#', '', $key); // remove whitespace if (PHP_VERSION_ID >= 73000) { $key = json_decode($key, null, 512, JSON_THROW_ON_ERROR); } else { $key = json_decode($key); if (!$key) { throw new \RuntimeException('Unable to decode JSON'); } } if (isset($key->kty)) { return $key; } if (!is_object($key)) { throw new \RuntimeException('invalid JWK: not an object'); } if (!isset($key->keys)) { throw new \RuntimeException('invalid JWK: object has no property "keys"'); } if (count($key->keys) != 1) { throw new \RuntimeException('Although the JWK key format supports multiple keys phpseclib does not'); } return $key->keys[0]; } /** * Wrap a key appropriately * * @return string */ protected static function wrapKey(array $key, array $options) { return json_encode(['keys' => [$key + $options]]); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/OpenSSH.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\Common\Formats\Keys; use phpseclib3\Common\Functions\Strings; use phpseclib3\Crypt\AES; use phpseclib3\Crypt\Random; use phpseclib3\Exception\BadDecryptionException; /** * OpenSSH Formatted RSA Key Handler * * @author Jim Wigginton */ abstract class OpenSSH { /** * Default comment * * @var string */ protected static $comment = 'phpseclib-generated-key'; /** * Binary key flag * * @var bool */ protected static $binary = false; /** * Sets the default comment * * @param string $comment */ public static function setComment($comment) { self::$comment = str_replace(["\r", "\n"], '', $comment); } /** * Break a public or private key down into its constituent components * * $type can be either ssh-dss or ssh-rsa * * @param string $key * @param string $password * @return array */ public static function load($key, $password = '') { if (!Strings::is_stringable($key)) { throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); } // key format is described here: // https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.key?annotate=HEAD if (strpos($key, 'BEGIN OPENSSH PRIVATE KEY') !== false) { $key = preg_replace('#(?:^-.*?-[\r\n]*$)|\s#ms', '', $key); $key = Strings::base64_decode($key); $magic = Strings::shift($key, 15); if ($magic != "openssh-key-v1\0") { throw new \RuntimeException('Expected openssh-key-v1'); } list($ciphername, $kdfname, $kdfoptions, $numKeys) = Strings::unpackSSH2('sssN', $key); if ($numKeys != 1) { // if we wanted to support multiple keys we could update PublicKeyLoader to preview what the # of keys // would be; it'd then call Common\Keys\OpenSSH.php::load() and get the paddedKey. it'd then pass // that to the appropriate key loading parser $numKey times or something throw new \RuntimeException('Although the OpenSSH private key format supports multiple keys phpseclib does not'); } switch ($ciphername) { case 'none': break; case 'aes256-ctr': if ($kdfname != 'bcrypt') { throw new \RuntimeException('Only the bcrypt kdf is supported (' . $kdfname . ' encountered)'); } list($salt, $rounds) = Strings::unpackSSH2('sN', $kdfoptions); $crypto = new AES('ctr'); //$crypto->setKeyLength(256); //$crypto->disablePadding(); $crypto->setPassword($password, 'bcrypt', $salt, $rounds, 32); break; default: throw new \RuntimeException('The only supported ciphers are: none, aes256-ctr (' . $ciphername . ' is being used)'); } list($publicKey, $paddedKey) = Strings::unpackSSH2('ss', $key); list($type) = Strings::unpackSSH2('s', $publicKey); if (isset($crypto)) { $paddedKey = $crypto->decrypt($paddedKey); } list($checkint1, $checkint2) = Strings::unpackSSH2('NN', $paddedKey); // any leftover bytes in $paddedKey are for padding? but they should be sequential bytes. eg. 1, 2, 3, etc. if ($checkint1 != $checkint2) { if (isset($crypto)) { throw new BadDecryptionException('Unable to decrypt key - please verify the password you are using'); } throw new \RuntimeException("The two checkints do not match ($checkint1 vs. $checkint2)"); } self::checkType($type); return compact('type', 'publicKey', 'paddedKey'); } $parts = explode(' ', $key, 3); if (!isset($parts[1])) { $key = base64_decode($parts[0]); $comment = false; } else { $asciiType = $parts[0]; self::checkType($parts[0]); $key = base64_decode($parts[1]); $comment = isset($parts[2]) ? $parts[2] : false; } if ($key === false) { throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); } list($type) = Strings::unpackSSH2('s', $key); self::checkType($type); if (isset($asciiType) && $asciiType != $type) { throw new \RuntimeException('Two different types of keys are claimed: ' . $asciiType . ' and ' . $type); } if (strlen($key) <= 4) { throw new \UnexpectedValueException('Key appears to be malformed'); } $publicKey = $key; return compact('type', 'publicKey', 'comment'); } /** * Toggle between binary and printable keys * * Printable keys are what are generated by default. These are the ones that go in * $HOME/.ssh/authorized_key. * * @param bool $enabled */ public static function setBinaryOutput($enabled) { self::$binary = $enabled; } /** * Checks to see if the type is valid * * @param string $candidate */ private static function checkType($candidate) { if (!in_array($candidate, static::$types)) { throw new \RuntimeException("The key type ($candidate) is not equal to: " . implode(',', static::$types)); } } /** * Wrap a private key appropriately * * @param string $publicKey * @param string $privateKey * @param string $password * @param array $options * @return string */ protected static function wrapPrivateKey($publicKey, $privateKey, $password, $options) { list(, $checkint) = unpack('N', Random::string(4)); $comment = isset($options['comment']) ? $options['comment'] : self::$comment; $paddedKey = Strings::packSSH2('NN', $checkint, $checkint) . $privateKey . Strings::packSSH2('s', $comment); $usesEncryption = !empty($password) && is_string($password); /* from http://tools.ietf.org/html/rfc4253#section-6 : Note that the length of the concatenation of 'packet_length', 'padding_length', 'payload', and 'random padding' MUST be a multiple of the cipher block size or 8, whichever is larger. */ $blockSize = $usesEncryption ? 16 : 8; $paddingLength = (($blockSize - 1) * strlen($paddedKey)) % $blockSize; for ($i = 1; $i <= $paddingLength; $i++) { $paddedKey .= chr($i); } if (!$usesEncryption) { $key = Strings::packSSH2('sssNss', 'none', 'none', '', 1, $publicKey, $paddedKey); } else { $rounds = isset($options['rounds']) ? $options['rounds'] : 16; $salt = Random::string(16); $kdfoptions = Strings::packSSH2('sN', $salt, $rounds); $crypto = new AES('ctr'); $crypto->setPassword($password, 'bcrypt', $salt, $rounds, 32); $paddedKey = $crypto->encrypt($paddedKey); $key = Strings::packSSH2('sssNss', 'aes256-ctr', 'bcrypt', $kdfoptions, 1, $publicKey, $paddedKey); } $key = "openssh-key-v1\0$key"; return "-----BEGIN OPENSSH PRIVATE KEY-----\n" . chunk_split(Strings::base64_encode($key), 70, "\n") . "-----END OPENSSH PRIVATE KEY-----\n"; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\Common\Formats\Keys; /** * PKCS1 Formatted Key Handler * * @author Jim Wigginton */ abstract class PKCS { /** * Auto-detect the format */ const MODE_ANY = 0; /** * Require base64-encoded PEM's be supplied */ const MODE_PEM = 1; /** * Require raw DER's be supplied */ const MODE_DER = 2; /**#@-*/ /** * Is the key a base-64 encoded PEM, DER or should it be auto-detected? * * @var int */ protected static $format = self::MODE_ANY; /** * Require base64-encoded PEM's be supplied * */ public static function requirePEM() { self::$format = self::MODE_PEM; } /** * Require raw DER's be supplied * */ public static function requireDER() { self::$format = self::MODE_DER; } /** * Accept any format and auto detect the format * * This is the default setting * */ public static function requireAny() { self::$format = self::MODE_ANY; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS1.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\Common\Formats\Keys; use phpseclib3\Common\Functions\Strings; use phpseclib3\Crypt\AES; use phpseclib3\Crypt\DES; use phpseclib3\Crypt\Random; use phpseclib3\Crypt\TripleDES; use phpseclib3\Exception\UnsupportedAlgorithmException; use phpseclib3\File\ASN1; /** * PKCS1 Formatted Key Handler * * @author Jim Wigginton */ abstract class PKCS1 extends PKCS { /** * Default encryption algorithm * * @var string */ private static $defaultEncryptionAlgorithm = 'AES-128-CBC'; /** * Sets the default encryption algorithm * * @param string $algo */ public static function setEncryptionAlgorithm($algo) { self::$defaultEncryptionAlgorithm = $algo; } /** * Returns the mode constant corresponding to the mode string * * @param string $mode * @return int * @throws \UnexpectedValueException if the block cipher mode is unsupported */ private static function getEncryptionMode($mode) { switch ($mode) { case 'CBC': case 'ECB': case 'CFB': case 'OFB': case 'CTR': return $mode; } throw new \UnexpectedValueException('Unsupported block cipher mode of operation'); } /** * Returns a cipher object corresponding to a string * * @param string $algo * @return string * @throws \UnexpectedValueException if the encryption algorithm is unsupported */ private static function getEncryptionObject($algo) { $modes = '(CBC|ECB|CFB|OFB|CTR)'; switch (true) { case preg_match("#^AES-(128|192|256)-$modes$#", $algo, $matches): $cipher = new AES(self::getEncryptionMode($matches[2])); $cipher->setKeyLength($matches[1]); return $cipher; case preg_match("#^DES-EDE3-$modes$#", $algo, $matches): return new TripleDES(self::getEncryptionMode($matches[1])); case preg_match("#^DES-$modes$#", $algo, $matches): return new DES(self::getEncryptionMode($matches[1])); default: throw new UnsupportedAlgorithmException($algo . ' is not a supported algorithm'); } } /** * Generate a symmetric key for PKCS#1 keys * * @param string $password * @param string $iv * @param int $length * @return string */ private static function generateSymmetricKey($password, $iv, $length) { $symkey = ''; $iv = substr($iv, 0, 8); while (strlen($symkey) < $length) { $symkey .= md5($symkey . $password . $iv, true); } return substr($symkey, 0, $length); } /** * Break a public or private key down into its constituent components * * @param string $key * @param string $password optional * @return array */ protected static function load($key, $password) { if (!Strings::is_stringable($key)) { throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); } /* Although PKCS#1 proposes a format that public and private keys can use, encrypting them is "outside the scope" of PKCS#1. PKCS#1 then refers you to PKCS#12 and PKCS#15 if you're wanting to protect private keys, however, that's not what OpenSSL* does. OpenSSL protects private keys by adding two new "fields" to the key - DEK-Info and Proc-Type. These fields are discussed here: http://tools.ietf.org/html/rfc1421#section-4.6.1.1 http://tools.ietf.org/html/rfc1421#section-4.6.1.3 DES-EDE3-CBC as an algorithm, however, is not discussed anywhere, near as I can tell. DES-CBC and DES-EDE are discussed in RFC1423, however, DES-EDE3-CBC isn't, nor is its key derivation function. As is, the definitive authority on this encoding scheme isn't the IETF but rather OpenSSL's own implementation. ie. the implementation *is* the standard and any bugs that may exist in that implementation are part of the standard, as well. * OpenSSL is the de facto standard. It's utilized by OpenSSH and other projects */ if (preg_match('#DEK-Info: (.+),(.+)#', $key, $matches)) { $iv = Strings::hex2bin(trim($matches[2])); // remove the Proc-Type / DEK-Info sections as they're no longer needed $key = preg_replace('#^(?:Proc-Type|DEK-Info): .*#m', '', $key); $ciphertext = ASN1::extractBER($key); if ($ciphertext === false) { $ciphertext = $key; } $crypto = self::getEncryptionObject($matches[1]); $crypto->setKey(self::generateSymmetricKey($password, $iv, $crypto->getKeyLength() >> 3)); $crypto->setIV($iv); $key = $crypto->decrypt($ciphertext); } else { if (self::$format != self::MODE_DER) { $decoded = ASN1::extractBER($key); if ($decoded !== false) { $key = $decoded; } elseif (self::$format == self::MODE_PEM) { throw new \UnexpectedValueException('Expected base64-encoded PEM format but was unable to decode base64 text'); } } } return $key; } /** * Wrap a private key appropriately * * @param string $key * @param string $type * @param string $password * @param array $options optional * @return string */ protected static function wrapPrivateKey($key, $type, $password, array $options = []) { if (empty($password) || !is_string($password)) { return "-----BEGIN $type PRIVATE KEY-----\r\n" . chunk_split(Strings::base64_encode($key), 64) . "-----END $type PRIVATE KEY-----"; } $encryptionAlgorithm = isset($options['encryptionAlgorithm']) ? $options['encryptionAlgorithm'] : self::$defaultEncryptionAlgorithm; $cipher = self::getEncryptionObject($encryptionAlgorithm); $iv = Random::string($cipher->getBlockLength() >> 3); $cipher->setKey(self::generateSymmetricKey($password, $iv, $cipher->getKeyLength() >> 3)); $cipher->setIV($iv); $iv = strtoupper(Strings::bin2hex($iv)); return "-----BEGIN $type PRIVATE KEY-----\r\n" . "Proc-Type: 4,ENCRYPTED\r\n" . "DEK-Info: " . $encryptionAlgorithm . ",$iv\r\n" . "\r\n" . chunk_split(Strings::base64_encode($cipher->encrypt($key)), 64) . "-----END $type PRIVATE KEY-----"; } /** * Wrap a public key appropriately * * @param string $key * @param string $type * @return string */ protected static function wrapPublicKey($key, $type) { return "-----BEGIN $type PUBLIC KEY-----\r\n" . chunk_split(Strings::base64_encode($key), 64) . "-----END $type PUBLIC KEY-----"; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\Common\Formats\Keys; use phpseclib3\Common\Functions\Strings; use phpseclib3\Crypt\AES; use phpseclib3\Crypt\DES; use phpseclib3\Crypt\Random; use phpseclib3\Crypt\RC2; use phpseclib3\Crypt\RC4; use phpseclib3\Crypt\TripleDES; use phpseclib3\Exception\InsufficientSetupException; use phpseclib3\Exception\UnsupportedAlgorithmException; use phpseclib3\File\ASN1; use phpseclib3\File\ASN1\Maps; /** * PKCS#8 Formatted Key Handler * * @author Jim Wigginton */ abstract class PKCS8 extends PKCS { /** * Default encryption algorithm * * @var string */ private static $defaultEncryptionAlgorithm = 'id-PBES2'; /** * Default encryption scheme * * Only used when defaultEncryptionAlgorithm is id-PBES2 * * @var string */ private static $defaultEncryptionScheme = 'aes128-CBC-PAD'; /** * Default PRF * * Only used when defaultEncryptionAlgorithm is id-PBES2 * * @var string */ private static $defaultPRF = 'id-hmacWithSHA256'; /** * Default Iteration Count * * @var int */ private static $defaultIterationCount = 2048; /** * OIDs loaded * * @var bool */ private static $oidsLoaded = false; /** * Binary key flag * * @var bool */ private static $binary = false; /** * Sets the default encryption algorithm * * @param string $algo */ public static function setEncryptionAlgorithm($algo) { self::$defaultEncryptionAlgorithm = $algo; } /** * Sets the default encryption algorithm for PBES2 * * @param string $algo */ public static function setEncryptionScheme($algo) { self::$defaultEncryptionScheme = $algo; } /** * Sets the iteration count * * @param int $count */ public static function setIterationCount($count) { self::$defaultIterationCount = $count; } /** * Sets the PRF for PBES2 * * @param string $algo */ public static function setPRF($algo) { self::$defaultPRF = $algo; } /** * Returns a SymmetricKey object based on a PBES1 $algo * * @return \phpseclib3\Crypt\Common\SymmetricKey * @param string $algo */ private static function getPBES1EncryptionObject($algo) { $algo = preg_match('#^pbeWith(?:MD2|MD5|SHA1|SHA)And(.*?)-CBC$#', $algo, $matches) ? $matches[1] : substr($algo, 13); // strlen('pbeWithSHAAnd') == 13 switch ($algo) { case 'DES': $cipher = new DES('cbc'); break; case 'RC2': $cipher = new RC2('cbc'); $cipher->setKeyLength(64); break; case '3-KeyTripleDES': $cipher = new TripleDES('cbc'); break; case '2-KeyTripleDES': $cipher = new TripleDES('cbc'); $cipher->setKeyLength(128); break; case '128BitRC2': $cipher = new RC2('cbc'); $cipher->setKeyLength(128); break; case '40BitRC2': $cipher = new RC2('cbc'); $cipher->setKeyLength(40); break; case '128BitRC4': $cipher = new RC4(); $cipher->setKeyLength(128); break; case '40BitRC4': $cipher = new RC4(); $cipher->setKeyLength(40); break; default: throw new UnsupportedAlgorithmException("$algo is not a supported algorithm"); } return $cipher; } /** * Returns a hash based on a PBES1 $algo * * @return string * @param string $algo */ private static function getPBES1Hash($algo) { if (preg_match('#^pbeWith(MD2|MD5|SHA1|SHA)And.*?-CBC$#', $algo, $matches)) { return $matches[1] == 'SHA' ? 'sha1' : $matches[1]; } return 'sha1'; } /** * Returns a KDF baesd on a PBES1 $algo * * @return string * @param string $algo */ private static function getPBES1KDF($algo) { switch ($algo) { case 'pbeWithMD2AndDES-CBC': case 'pbeWithMD2AndRC2-CBC': case 'pbeWithMD5AndDES-CBC': case 'pbeWithMD5AndRC2-CBC': case 'pbeWithSHA1AndDES-CBC': case 'pbeWithSHA1AndRC2-CBC': return 'pbkdf1'; } return 'pkcs12'; } /** * Returns a SymmetricKey object baesd on a PBES2 $algo * * @return SymmetricKey * @param string $algo */ private static function getPBES2EncryptionObject($algo) { switch ($algo) { case 'desCBC': $cipher = new DES('cbc'); break; case 'des-EDE3-CBC': $cipher = new TripleDES('cbc'); break; case 'rc2CBC': $cipher = new RC2('cbc'); // in theory this can be changed $cipher->setKeyLength(128); break; case 'rc5-CBC-PAD': throw new UnsupportedAlgorithmException('rc5-CBC-PAD is not supported for PBES2 PKCS#8 keys'); case 'aes128-CBC-PAD': case 'aes192-CBC-PAD': case 'aes256-CBC-PAD': $cipher = new AES('cbc'); $cipher->setKeyLength(substr($algo, 3, 3)); break; default: throw new UnsupportedAlgorithmException("$algo is not supported"); } return $cipher; } /** * Initialize static variables * */ private static function initialize_static_variables() { if (!isset(static::$childOIDsLoaded)) { throw new InsufficientSetupException('This class should not be called directly'); } if (!static::$childOIDsLoaded) { ASN1::loadOIDs(is_array(static::OID_NAME) ? array_combine(static::OID_NAME, static::OID_VALUE) : [static::OID_NAME => static::OID_VALUE]); static::$childOIDsLoaded = true; } if (!self::$oidsLoaded) { // from https://tools.ietf.org/html/rfc2898 ASN1::loadOIDs([ // PBES1 encryption schemes 'pbeWithMD2AndDES-CBC' => '1.2.840.113549.1.5.1', 'pbeWithMD2AndRC2-CBC' => '1.2.840.113549.1.5.4', 'pbeWithMD5AndDES-CBC' => '1.2.840.113549.1.5.3', 'pbeWithMD5AndRC2-CBC' => '1.2.840.113549.1.5.6', 'pbeWithSHA1AndDES-CBC' => '1.2.840.113549.1.5.10', 'pbeWithSHA1AndRC2-CBC' => '1.2.840.113549.1.5.11', // from PKCS#12: // https://tools.ietf.org/html/rfc7292 'pbeWithSHAAnd128BitRC4' => '1.2.840.113549.1.12.1.1', 'pbeWithSHAAnd40BitRC4' => '1.2.840.113549.1.12.1.2', 'pbeWithSHAAnd3-KeyTripleDES-CBC' => '1.2.840.113549.1.12.1.3', 'pbeWithSHAAnd2-KeyTripleDES-CBC' => '1.2.840.113549.1.12.1.4', 'pbeWithSHAAnd128BitRC2-CBC' => '1.2.840.113549.1.12.1.5', 'pbeWithSHAAnd40BitRC2-CBC' => '1.2.840.113549.1.12.1.6', 'id-PBKDF2' => '1.2.840.113549.1.5.12', 'id-PBES2' => '1.2.840.113549.1.5.13', 'id-PBMAC1' => '1.2.840.113549.1.5.14', // from PKCS#5 v2.1: // http://www.rsa.com/rsalabs/pkcs/files/h11302-wp-pkcs5v2-1-password-based-cryptography-standard.pdf 'id-hmacWithSHA1' => '1.2.840.113549.2.7', 'id-hmacWithSHA224' => '1.2.840.113549.2.8', 'id-hmacWithSHA256' => '1.2.840.113549.2.9', 'id-hmacWithSHA384' => '1.2.840.113549.2.10', 'id-hmacWithSHA512' => '1.2.840.113549.2.11', 'id-hmacWithSHA512-224' => '1.2.840.113549.2.12', 'id-hmacWithSHA512-256' => '1.2.840.113549.2.13', 'desCBC' => '1.3.14.3.2.7', 'des-EDE3-CBC' => '1.2.840.113549.3.7', 'rc2CBC' => '1.2.840.113549.3.2', 'rc5-CBC-PAD' => '1.2.840.113549.3.9', 'aes128-CBC-PAD' => '2.16.840.1.101.3.4.1.2', 'aes192-CBC-PAD' => '2.16.840.1.101.3.4.1.22', 'aes256-CBC-PAD' => '2.16.840.1.101.3.4.1.42' ]); self::$oidsLoaded = true; } } /** * Break a public or private key down into its constituent components * * @param string $key * @param string $password optional * @return array */ protected static function load($key, $password = '') { if (!Strings::is_stringable($key)) { throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); } $isPublic = strpos($key, 'PUBLIC') !== false; $isPrivate = strpos($key, 'PRIVATE') !== false; $decoded = self::preParse($key); $meta = []; $decrypted = ASN1::asn1map($decoded[0], Maps\EncryptedPrivateKeyInfo::MAP); if (strlen($password) && is_array($decrypted)) { $algorithm = $decrypted['encryptionAlgorithm']['algorithm']; switch ($algorithm) { // PBES1 case 'pbeWithMD2AndDES-CBC': case 'pbeWithMD2AndRC2-CBC': case 'pbeWithMD5AndDES-CBC': case 'pbeWithMD5AndRC2-CBC': case 'pbeWithSHA1AndDES-CBC': case 'pbeWithSHA1AndRC2-CBC': case 'pbeWithSHAAnd3-KeyTripleDES-CBC': case 'pbeWithSHAAnd2-KeyTripleDES-CBC': case 'pbeWithSHAAnd128BitRC2-CBC': case 'pbeWithSHAAnd40BitRC2-CBC': case 'pbeWithSHAAnd128BitRC4': case 'pbeWithSHAAnd40BitRC4': $cipher = self::getPBES1EncryptionObject($algorithm); $hash = self::getPBES1Hash($algorithm); $kdf = self::getPBES1KDF($algorithm); $meta['meta']['algorithm'] = $algorithm; $temp = ASN1::decodeBER($decrypted['encryptionAlgorithm']['parameters']); if (!$temp) { throw new \RuntimeException('Unable to decode BER'); } $map = ASN1::asn1map($temp[0], Maps\PBEParameter::MAP); $salt = $map['salt']; $iterationCount = $map['iterationCount']; $iterationCount = (int) $iterationCount->toString(); $cipher->setPassword($password, $kdf, $hash, $salt, $iterationCount); $key = $cipher->decrypt($decrypted['encryptedData']); $decoded = ASN1::decodeBER($key); if (!$decoded) { throw new \RuntimeException('Unable to decode BER 2'); } break; case 'id-PBES2': $meta['meta']['algorithm'] = $algorithm; $temp = ASN1::decodeBER($decrypted['encryptionAlgorithm']['parameters']); if (!$temp) { throw new \RuntimeException('Unable to decode BER'); } $temp = ASN1::asn1map($temp[0], Maps\PBES2params::MAP); $keyDerivationFunc = $temp['keyDerivationFunc']; $encryptionScheme = $temp['encryptionScheme']; $cipher = self::getPBES2EncryptionObject($encryptionScheme['algorithm']); $meta['meta']['cipher'] = $encryptionScheme['algorithm']; $temp = ASN1::decodeBER($decrypted['encryptionAlgorithm']['parameters']); if (!$temp) { throw new \RuntimeException('Unable to decode BER'); } $temp = ASN1::asn1map($temp[0], Maps\PBES2params::MAP); $keyDerivationFunc = $temp['keyDerivationFunc']; $encryptionScheme = $temp['encryptionScheme']; if (!$cipher instanceof RC2) { $cipher->setIV($encryptionScheme['parameters']['octetString']); } else { $temp = ASN1::decodeBER($encryptionScheme['parameters']); if (!$temp) { throw new \RuntimeException('Unable to decode BER'); } $map = ASN1::asn1map($temp[0], Maps\RC2CBCParameter::MAP); $rc2ParametersVersion = $map['rc2ParametersVersion']; $iv = $map['iv']; $effectiveKeyLength = (int) $rc2ParametersVersion->toString(); switch ($effectiveKeyLength) { case 160: $effectiveKeyLength = 40; break; case 120: $effectiveKeyLength = 64; break; case 58: $effectiveKeyLength = 128; break; //default: // should be >= 256 } $cipher->setIV($iv); $cipher->setKeyLength($effectiveKeyLength); } $meta['meta']['keyDerivationFunc'] = $keyDerivationFunc['algorithm']; switch ($keyDerivationFunc['algorithm']) { case 'id-PBKDF2': $temp = ASN1::decodeBER($keyDerivationFunc['parameters']); if (!$temp) { throw new \RuntimeException('Unable to decode BER'); } $params = ASN1::asn1map($temp[0], Maps\PBKDF2params::MAP); if (empty($params['prf'])) { $params['prf'] = ['algorithm' => 'id-hmacWithSHA1']; } $salt = $params['salt']; $iterationCount = $params['iterationCount']; $prf = $params['prf']; $meta['meta']['prf'] = $prf['algorithm']; $hash = str_replace('-', '/', substr($prf['algorithm'], 11)); $params = [ $password, 'pbkdf2', $hash, $salt, (int) $iterationCount->toString() ]; if (isset($keyLength)) { $params[] = (int) $keyLength->toString(); } $cipher->setPassword(...$params); $key = $cipher->decrypt($decrypted['encryptedData']); $decoded = ASN1::decodeBER($key); if (!$decoded) { throw new \RuntimeException('Unable to decode BER 3'); } break; default: throw new UnsupportedAlgorithmException('Only PBKDF2 is supported for PBES2 PKCS#8 keys'); } break; case 'id-PBMAC1': //$temp = ASN1::decodeBER($decrypted['encryptionAlgorithm']['parameters']); //$value = ASN1::asn1map($temp[0], Maps\PBMAC1params::MAP); // since i can't find any implementation that does PBMAC1 it is unsupported throw new UnsupportedAlgorithmException('Only PBES1 and PBES2 PKCS#8 keys are supported.'); // at this point we'll assume that the key conforms to PublicKeyInfo } } $private = ASN1::asn1map($decoded[0], Maps\OneAsymmetricKey::MAP); if (is_array($private)) { if ($isPublic) { throw new \UnexpectedValueException('Human readable string claims public key but DER encoded string claims private key'); } if (isset($private['privateKeyAlgorithm']['parameters']) && !$private['privateKeyAlgorithm']['parameters'] instanceof ASN1\Element && isset($decoded[0]['content'][1]['content'][1])) { $temp = $decoded[0]['content'][1]['content'][1]; $private['privateKeyAlgorithm']['parameters'] = new ASN1\Element(substr($key, $temp['start'], $temp['length'])); } if (is_array(static::OID_NAME)) { if (!in_array($private['privateKeyAlgorithm']['algorithm'], static::OID_NAME)) { throw new UnsupportedAlgorithmException($private['privateKeyAlgorithm']['algorithm'] . ' is not a supported key type'); } } else { if ($private['privateKeyAlgorithm']['algorithm'] != static::OID_NAME) { throw new UnsupportedAlgorithmException('Only ' . static::OID_NAME . ' keys are supported; this is a ' . $private['privateKeyAlgorithm']['algorithm'] . ' key'); } } if (isset($private['publicKey'])) { if ($private['publicKey'][0] != "\0") { throw new \UnexpectedValueException('The first byte of the public key should be null - not ' . bin2hex($private['publicKey'][0])); } $private['publicKey'] = substr($private['publicKey'], 1); } return $private + $meta; } // EncryptedPrivateKeyInfo and PublicKeyInfo have largely identical "signatures". the only difference // is that the former has an octet string and the later has a bit string. the first byte of a bit // string represents the number of bits in the last byte that are to be ignored but, currently, // bit strings wanting a non-zero amount of bits trimmed are not supported $public = ASN1::asn1map($decoded[0], Maps\PublicKeyInfo::MAP); if (is_array($public)) { if ($isPrivate) { throw new \UnexpectedValueException('Human readable string claims private key but DER encoded string claims public key'); } if ($public['publicKey'][0] != "\0") { throw new \UnexpectedValueException('The first byte of the public key should be null - not ' . bin2hex($public['publicKey'][0])); } if (is_array(static::OID_NAME)) { if (!in_array($public['publicKeyAlgorithm']['algorithm'], static::OID_NAME)) { throw new UnsupportedAlgorithmException($public['publicKeyAlgorithm']['algorithm'] . ' is not a supported key type'); } } else { if ($public['publicKeyAlgorithm']['algorithm'] != static::OID_NAME) { throw new UnsupportedAlgorithmException('Only ' . static::OID_NAME . ' keys are supported; this is a ' . $public['publicKeyAlgorithm']['algorithm'] . ' key'); } } if (isset($public['publicKeyAlgorithm']['parameters']) && !$public['publicKeyAlgorithm']['parameters'] instanceof ASN1\Element && isset($decoded[0]['content'][0]['content'][1])) { $temp = $decoded[0]['content'][0]['content'][1]; $public['publicKeyAlgorithm']['parameters'] = new ASN1\Element(substr($key, $temp['start'], $temp['length'])); } $public['publicKey'] = substr($public['publicKey'], 1); return $public; } throw new \RuntimeException('Unable to parse using either OneAsymmetricKey or PublicKeyInfo ASN1 maps'); } /** * Toggle between binary (DER) and printable (PEM) keys * * Printable keys are what are generated by default. * * @param bool $enabled */ public static function setBinaryOutput($enabled) { self::$binary = $enabled; } /** * Wrap a private key appropriately * * @param string $key * @param string $attr * @param mixed $params * @param string $password * @param string $oid optional * @param string $publicKey optional * @param array $options optional * @return string */ protected static function wrapPrivateKey($key, $attr, $params, $password, $oid = null, $publicKey = '', array $options = []) { self::initialize_static_variables(); $key = [ 'version' => 'v1', 'privateKeyAlgorithm' => [ 'algorithm' => is_string(static::OID_NAME) ? static::OID_NAME : $oid ], 'privateKey' => $key ]; if ($oid != 'id-Ed25519' && $oid != 'id-Ed448') { $key['privateKeyAlgorithm']['parameters'] = $params; } if (!empty($attr)) { $key['attributes'] = $attr; } if (!empty($publicKey)) { $key['version'] = 'v2'; $key['publicKey'] = $publicKey; } $key = ASN1::encodeDER($key, Maps\OneAsymmetricKey::MAP); if (!empty($password) && is_string($password)) { $salt = Random::string(8); $iterationCount = isset($options['iterationCount']) ? $options['iterationCount'] : self::$defaultIterationCount; $encryptionAlgorithm = isset($options['encryptionAlgorithm']) ? $options['encryptionAlgorithm'] : self::$defaultEncryptionAlgorithm; $encryptionScheme = isset($options['encryptionScheme']) ? $options['encryptionScheme'] : self::$defaultEncryptionScheme; $prf = isset($options['PRF']) ? $options['PRF'] : self::$defaultPRF; if ($encryptionAlgorithm == 'id-PBES2') { $crypto = self::getPBES2EncryptionObject($encryptionScheme); $hash = str_replace('-', '/', substr($prf, 11)); $kdf = 'pbkdf2'; $iv = Random::string($crypto->getBlockLength() >> 3); $PBKDF2params = [ 'salt' => $salt, 'iterationCount' => $iterationCount, 'prf' => ['algorithm' => $prf, 'parameters' => null] ]; $PBKDF2params = ASN1::encodeDER($PBKDF2params, Maps\PBKDF2params::MAP); if (!$crypto instanceof RC2) { $params = ['octetString' => $iv]; } else { $params = [ 'rc2ParametersVersion' => 58, 'iv' => $iv ]; $params = ASN1::encodeDER($params, Maps\RC2CBCParameter::MAP); $params = new ASN1\Element($params); } $params = [ 'keyDerivationFunc' => [ 'algorithm' => 'id-PBKDF2', 'parameters' => new ASN1\Element($PBKDF2params) ], 'encryptionScheme' => [ 'algorithm' => $encryptionScheme, 'parameters' => $params ] ]; $params = ASN1::encodeDER($params, Maps\PBES2params::MAP); $crypto->setIV($iv); } else { $crypto = self::getPBES1EncryptionObject($encryptionAlgorithm); $hash = self::getPBES1Hash($encryptionAlgorithm); $kdf = self::getPBES1KDF($encryptionAlgorithm); $params = [ 'salt' => $salt, 'iterationCount' => $iterationCount ]; $params = ASN1::encodeDER($params, Maps\PBEParameter::MAP); } $crypto->setPassword($password, $kdf, $hash, $salt, $iterationCount); $key = $crypto->encrypt($key); $key = [ 'encryptionAlgorithm' => [ 'algorithm' => $encryptionAlgorithm, 'parameters' => new ASN1\Element($params) ], 'encryptedData' => $key ]; $key = ASN1::encodeDER($key, Maps\EncryptedPrivateKeyInfo::MAP); if (isset($options['binary']) ? $options['binary'] : self::$binary) { return $key; } return "-----BEGIN ENCRYPTED PRIVATE KEY-----\r\n" . chunk_split(Strings::base64_encode($key), 64) . "-----END ENCRYPTED PRIVATE KEY-----"; } if (isset($options['binary']) ? $options['binary'] : self::$binary) { return $key; } return "-----BEGIN PRIVATE KEY-----\r\n" . chunk_split(Strings::base64_encode($key), 64) . "-----END PRIVATE KEY-----"; } /** * Wrap a public key appropriately * * @param string $key * @param mixed $params * @param string $oid * @return string */ protected static function wrapPublicKey($key, $params, $oid = null, array $options = []) { self::initialize_static_variables(); $key = [ 'publicKeyAlgorithm' => [ 'algorithm' => is_string(static::OID_NAME) ? static::OID_NAME : $oid ], 'publicKey' => "\0" . $key ]; if ($oid != 'id-Ed25519' && $oid != 'id-Ed448') { $key['publicKeyAlgorithm']['parameters'] = $params; } $key = ASN1::encodeDER($key, Maps\PublicKeyInfo::MAP); if (isset($options['binary']) ? $options['binary'] : self::$binary) { return $key; } return "-----BEGIN PUBLIC KEY-----\r\n" . chunk_split(Strings::base64_encode($key), 64) . "-----END PUBLIC KEY-----"; } /** * Perform some preliminary parsing of the key * * @param string $key * @return array */ private static function preParse(&$key) { self::initialize_static_variables(); if (self::$format != self::MODE_DER) { $decoded = ASN1::extractBER($key); if ($decoded !== false) { $key = $decoded; } elseif (self::$format == self::MODE_PEM) { throw new \UnexpectedValueException('Expected base64-encoded PEM format but was unable to decode base64 text'); } } $decoded = ASN1::decodeBER($key); if (!$decoded) { throw new \RuntimeException('Unable to decode BER'); } return $decoded; } /** * Returns the encryption parameters used by the key * * @param string $key * @return array */ public static function extractEncryptionAlgorithm($key) { if (!Strings::is_stringable($key)) { throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); } $decoded = self::preParse($key); $r = ASN1::asn1map($decoded[0], Maps\EncryptedPrivateKeyInfo::MAP); if (!is_array($r)) { throw new \RuntimeException('Unable to parse using EncryptedPrivateKeyInfo map'); } if ($r['encryptionAlgorithm']['algorithm'] == 'id-PBES2') { $decoded = ASN1::decodeBER($r['encryptionAlgorithm']['parameters']->element); if (!$decoded) { throw new \RuntimeException('Unable to decode BER'); } $r['encryptionAlgorithm']['parameters'] = ASN1::asn1map($decoded[0], Maps\PBES2params::MAP); $kdf = &$r['encryptionAlgorithm']['parameters']['keyDerivationFunc']; switch ($kdf['algorithm']) { case 'id-PBKDF2': $decoded = ASN1::decodeBER($kdf['parameters']->element); if (!$decoded) { throw new \RuntimeException('Unable to decode BER'); } $kdf['parameters'] = ASN1::asn1map($decoded[0], Maps\PBKDF2params::MAP); } } return $r['encryptionAlgorithm']; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PuTTY.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\Common\Formats\Keys; use phpseclib3\Common\Functions\Strings; use phpseclib3\Crypt\AES; use phpseclib3\Crypt\Hash; use phpseclib3\Crypt\Random; use phpseclib3\Exception\UnsupportedAlgorithmException; /** * PuTTY Formatted Key Handler * * @author Jim Wigginton */ abstract class PuTTY { /** * Default comment * * @var string */ private static $comment = 'phpseclib-generated-key'; /** * Default version * * @var int */ private static $version = 2; /** * Sets the default comment * * @param string $comment */ public static function setComment($comment) { self::$comment = str_replace(["\r", "\n"], '', $comment); } /** * Sets the default version * * @param int $version */ public static function setVersion($version) { if ($version != 2 && $version != 3) { throw new \RuntimeException('Only supported versions are 2 and 3'); } self::$version = $version; } /** * Generate a symmetric key for PuTTY v2 keys * * @param string $password * @param int $length * @return string */ private static function generateV2Key($password, $length) { $symkey = ''; $sequence = 0; while (strlen($symkey) < $length) { $temp = pack('Na*', $sequence++, $password); $symkey .= Strings::hex2bin(sha1($temp)); } return substr($symkey, 0, $length); } /** * Generate a symmetric key for PuTTY v3 keys * * @param string $password * @param string $flavour * @param int $memory * @param int $passes * @param string $salt * @return array */ private static function generateV3Key($password, $flavour, $memory, $passes, $salt) { if (!function_exists('sodium_crypto_pwhash')) { throw new \RuntimeException('sodium_crypto_pwhash needs to exist for Argon2 password hasing'); } switch ($flavour) { case 'Argon2i': $flavour = SODIUM_CRYPTO_PWHASH_ALG_ARGON2I13; break; case 'Argon2id': $flavour = SODIUM_CRYPTO_PWHASH_ALG_ARGON2ID13; break; default: throw new UnsupportedAlgorithmException('Only Argon2i and Argon2id are supported'); } $length = 80; // keylen + ivlen + mac_keylen $temp = sodium_crypto_pwhash($length, $password, $salt, $passes, $memory << 10, $flavour); $symkey = substr($temp, 0, 32); $symiv = substr($temp, 32, 16); $hashkey = substr($temp, -32); return compact('symkey', 'symiv', 'hashkey'); } /** * Break a public or private key down into its constituent components * * @param string $key * @param string $password * @return array */ public static function load($key, $password) { if (!Strings::is_stringable($key)) { throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); } if (strpos($key, 'BEGIN SSH2 PUBLIC KEY') !== false) { $lines = preg_split('#[\r\n]+#', $key); switch (true) { case $lines[0] != '---- BEGIN SSH2 PUBLIC KEY ----': throw new \UnexpectedValueException('Key doesn\'t start with ---- BEGIN SSH2 PUBLIC KEY ----'); case $lines[count($lines) - 1] != '---- END SSH2 PUBLIC KEY ----': throw new \UnexpectedValueException('Key doesn\'t end with ---- END SSH2 PUBLIC KEY ----'); } $lines = array_splice($lines, 1, -1); $lines = array_map(function ($line) { return rtrim($line, "\r\n"); }, $lines); $data = $current = ''; $values = []; $in_value = false; foreach ($lines as $line) { switch (true) { case preg_match('#^(.*?): (.*)#', $line, $match): $in_value = $line[strlen($line) - 1] == '\\'; $current = strtolower($match[1]); $values[$current] = $in_value ? substr($match[2], 0, -1) : $match[2]; break; case $in_value: $in_value = $line[strlen($line) - 1] == '\\'; $values[$current] .= $in_value ? substr($line, 0, -1) : $line; break; default: $data .= $line; } } $components = call_user_func([static::PUBLIC_HANDLER, 'load'], $data); if ($components === false) { throw new \UnexpectedValueException('Unable to decode public key'); } $components += $values; $components['comment'] = str_replace(['\\\\', '\"'], ['\\', '"'], $values['comment']); return $components; } $components = []; $key = preg_split('#\r\n|\r|\n#', trim($key)); if (Strings::shift($key[0], strlen('PuTTY-User-Key-File-')) != 'PuTTY-User-Key-File-') { return false; } $version = (int) Strings::shift($key[0], 3); // should be either "2: " or "3: 0" prior to int casting if ($version != 2 && $version != 3) { throw new \RuntimeException('Only v2 and v3 PuTTY private keys are supported'); } $components['type'] = $type = rtrim($key[0]); if (!in_array($type, static::$types)) { $error = count(static::$types) == 1 ? 'Only ' . static::$types[0] . ' keys are supported. ' : ''; throw new UnsupportedAlgorithmException($error . 'This is an unsupported ' . $type . ' key'); } $encryption = trim(preg_replace('#Encryption: (.+)#', '$1', $key[1])); $components['comment'] = trim(preg_replace('#Comment: (.+)#', '$1', $key[2])); $publicLength = trim(preg_replace('#Public-Lines: (\d+)#', '$1', $key[3])); $public = Strings::base64_decode(implode('', array_map('trim', array_slice($key, 4, $publicLength)))); $source = Strings::packSSH2('ssss', $type, $encryption, $components['comment'], $public); $length = unpack('Nlength', Strings::shift($public, 4))['length']; $newtype = Strings::shift($public, $length); if ($newtype != $type) { throw new \RuntimeException('The binary type does not match the human readable type field'); } $components['public'] = $public; switch ($version) { case 3: $hashkey = ''; break; case 2: $hashkey = 'putty-private-key-file-mac-key'; } $offset = $publicLength + 4; switch ($encryption) { case 'aes256-cbc': $crypto = new AES('cbc'); switch ($version) { case 3: $flavour = trim(preg_replace('#Key-Derivation: (.*)#', '$1', $key[$offset++])); $memory = trim(preg_replace('#Argon2-Memory: (\d+)#', '$1', $key[$offset++])); $passes = trim(preg_replace('#Argon2-Passes: (\d+)#', '$1', $key[$offset++])); $parallelism = trim(preg_replace('#Argon2-Parallelism: (\d+)#', '$1', $key[$offset++])); $salt = Strings::hex2bin(trim(preg_replace('#Argon2-Salt: ([0-9a-f]+)#', '$1', $key[$offset++]))); $v3key = self::generateV3Key($password, $flavour, $memory, $passes, $salt); $symkey = $v3key['symkey']; $symiv = $v3key['symiv']; $hashkey = $v3key['hashkey']; break; case 2: $symkey = self::generateV2Key($password, 32); $symiv = str_repeat("\0", $crypto->getBlockLength() >> 3); $hashkey .= $password; } } switch ($version) { case 3: $hash = new Hash('sha256'); $hash->setKey($hashkey); break; case 2: $hash = new Hash('sha1'); $hash->setKey(sha1($hashkey, true)); } $privateLength = trim(preg_replace('#Private-Lines: (\d+)#', '$1', $key[$offset++])); $private = Strings::base64_decode(implode('', array_map('trim', array_slice($key, $offset, $privateLength)))); if ($encryption != 'none') { $crypto->setKey($symkey); $crypto->setIV($symiv); $crypto->disablePadding(); $private = $crypto->decrypt($private); } $source .= Strings::packSSH2('s', $private); $hmac = trim(preg_replace('#Private-MAC: (.+)#', '$1', $key[$offset + $privateLength])); $hmac = Strings::hex2bin($hmac); if (!hash_equals($hash->hash($source), $hmac)) { throw new \UnexpectedValueException('MAC validation error'); } $components['private'] = $private; return $components; } /** * Wrap a private key appropriately * * @param string $public * @param string $private * @param string $type * @param string $password * @param array $options optional * @return string */ protected static function wrapPrivateKey($public, $private, $type, $password, array $options = []) { $encryption = (!empty($password) || is_string($password)) ? 'aes256-cbc' : 'none'; $comment = isset($options['comment']) ? $options['comment'] : self::$comment; $version = isset($options['version']) ? $options['version'] : self::$version; $key = "PuTTY-User-Key-File-$version: $type\r\n"; $key .= "Encryption: $encryption\r\n"; $key .= "Comment: $comment\r\n"; $public = Strings::packSSH2('s', $type) . $public; $source = Strings::packSSH2('ssss', $type, $encryption, $comment, $public); $public = Strings::base64_encode($public); $key .= "Public-Lines: " . ((strlen($public) + 63) >> 6) . "\r\n"; $key .= chunk_split($public, 64); if (empty($password) && !is_string($password)) { $source .= Strings::packSSH2('s', $private); switch ($version) { case 3: $hash = new Hash('sha256'); $hash->setKey(''); break; case 2: $hash = new Hash('sha1'); $hash->setKey(sha1('putty-private-key-file-mac-key', true)); } } else { $private .= Random::string(16 - (strlen($private) & 15)); $source .= Strings::packSSH2('s', $private); $crypto = new AES('cbc'); switch ($version) { case 3: $salt = Random::string(16); $key .= "Key-Derivation: Argon2id\r\n"; $key .= "Argon2-Memory: 8192\r\n"; $key .= "Argon2-Passes: 13\r\n"; $key .= "Argon2-Parallelism: 1\r\n"; $key .= "Argon2-Salt: " . Strings::bin2hex($salt) . "\r\n"; $v3key = self::generateV3Key($password, 'Argon2id', 8192, 13, $salt); $symkey = $v3key['symkey']; $symiv = $v3key['symiv']; $hashkey = $v3key['hashkey']; $hash = new Hash('sha256'); $hash->setKey($hashkey); break; case 2: $symkey = self::generateV2Key($password, 32); $symiv = str_repeat("\0", $crypto->getBlockLength() >> 3); $hashkey = 'putty-private-key-file-mac-key' . $password; $hash = new Hash('sha1'); $hash->setKey(sha1($hashkey, true)); } $crypto->setKey($symkey); $crypto->setIV($symiv); $crypto->disablePadding(); $private = $crypto->encrypt($private); $mac = $hash->hash($source); } $private = Strings::base64_encode($private); $key .= 'Private-Lines: ' . ((strlen($private) + 63) >> 6) . "\r\n"; $key .= chunk_split($private, 64); $key .= 'Private-MAC: ' . Strings::bin2hex($hash->hash($source)) . "\r\n"; return $key; } /** * Wrap a public key appropriately * * This is basically the format described in RFC 4716 (https://tools.ietf.org/html/rfc4716) * * @param string $key * @param string $type * @return string */ protected static function wrapPublicKey($key, $type) { $key = pack('Na*a*', strlen($type), $type, $key); $key = "---- BEGIN SSH2 PUBLIC KEY ----\r\n" . 'Comment: "' . str_replace(['\\', '"'], ['\\\\', '\"'], self::$comment) . "\"\r\n" . chunk_split(Strings::base64_encode($key), 64) . '---- END SSH2 PUBLIC KEY ----'; return $key; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Signature/Raw.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\Common\Formats\Signature; use phpseclib3\Math\BigInteger; /** * Raw Signature Handler * * @author Jim Wigginton */ abstract class Raw { /** * Loads a signature * * @param array $sig * @return array|bool */ public static function load($sig) { switch (true) { case !is_array($sig): case !isset($sig['r']) || !isset($sig['s']): case !$sig['r'] instanceof BigInteger: case !$sig['s'] instanceof BigInteger: return false; } return [ 'r' => $sig['r'], 's' => $sig['s'] ]; } /** * Returns a signature in the appropriate format * * @param BigInteger $r * @param BigInteger $s * @return string */ public static function save(BigInteger $r, BigInteger $s) { return compact('r', 's'); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/PrivateKey.php ================================================ * @copyright 2009 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\Common; /** * PrivateKey interface * * @author Jim Wigginton */ interface PrivateKey { public function sign($message); //public function decrypt($ciphertext); public function getPublicKey(); public function toString($type, array $options = []); /** * @param string|false $password * @return mixed */ public function withPassword($password = false); } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/PublicKey.php ================================================ * @copyright 2009 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\Common; /** * PublicKey interface * * @author Jim Wigginton */ interface PublicKey { public function verify($message, $signature); //public function encrypt($plaintext); public function toString($type, array $options = []); public function getFingerprint($algorithm); } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/StreamCipher.php ================================================ * @author Hans-Juergen Petrich * @copyright 2007 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\Common; /** * Base Class for all stream cipher classes * * @author Jim Wigginton */ abstract class StreamCipher extends SymmetricKey { /** * Block Length of the cipher * * Stream ciphers do not have a block size * * @see SymmetricKey::block_size * @var int */ protected $block_size = 0; /** * Default Constructor. * * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() * @return StreamCipher */ public function __construct() { parent::__construct('stream'); } /** * Stream ciphers not use an IV * * @return bool */ public function usesIV() { return false; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/SymmetricKey.php ================================================ * @author Hans-Juergen Petrich * @copyright 2007 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\Common; use phpseclib3\Common\Functions\Strings; use phpseclib3\Crypt\Blowfish; use phpseclib3\Crypt\Hash; use phpseclib3\Exception\BadDecryptionException; use phpseclib3\Exception\BadModeException; use phpseclib3\Exception\InconsistentSetupException; use phpseclib3\Exception\InsufficientSetupException; use phpseclib3\Exception\UnsupportedAlgorithmException; use phpseclib3\Math\BigInteger; use phpseclib3\Math\BinaryField; use phpseclib3\Math\PrimeField; /** * Base Class for all \phpseclib3\Crypt\* cipher classes * * @author Jim Wigginton * @author Hans-Juergen Petrich */ abstract class SymmetricKey { /** * Encrypt / decrypt using the Counter mode. * * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode. * * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29 * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() */ const MODE_CTR = -1; /** * Encrypt / decrypt using the Electronic Code Book mode. * * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29 * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() */ const MODE_ECB = 1; /** * Encrypt / decrypt using the Code Book Chaining mode. * * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29 * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() */ const MODE_CBC = 2; /** * Encrypt / decrypt using the Cipher Feedback mode. * * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29 * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() */ const MODE_CFB = 3; /** * Encrypt / decrypt using the Cipher Feedback mode (8bit) * * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() */ const MODE_CFB8 = 7; /** * Encrypt / decrypt using the Output Feedback mode (8bit) * * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() */ const MODE_OFB8 = 8; /** * Encrypt / decrypt using the Output Feedback mode. * * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29 * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() */ const MODE_OFB = 4; /** * Encrypt / decrypt using Galois/Counter mode. * * @link https://en.wikipedia.org/wiki/Galois/Counter_Mode * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() */ const MODE_GCM = 5; /** * Encrypt / decrypt using streaming mode. * * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() */ const MODE_STREAM = 6; /** * Mode Map * * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() */ const MODE_MAP = [ 'ctr' => self::MODE_CTR, 'ecb' => self::MODE_ECB, 'cbc' => self::MODE_CBC, 'cfb' => self::MODE_CFB, 'cfb8' => self::MODE_CFB8, 'ofb' => self::MODE_OFB, 'ofb8' => self::MODE_OFB8, 'gcm' => self::MODE_GCM, 'stream' => self::MODE_STREAM ]; /** * Base value for the internal implementation $engine switch * * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() */ const ENGINE_INTERNAL = 1; /** * Base value for the eval() implementation $engine switch * * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() */ const ENGINE_EVAL = 2; /** * Base value for the mcrypt implementation $engine switch * * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() */ const ENGINE_MCRYPT = 3; /** * Base value for the openssl implementation $engine switch * * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() */ const ENGINE_OPENSSL = 4; /** * Base value for the libsodium implementation $engine switch * * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() */ const ENGINE_LIBSODIUM = 5; /** * Base value for the openssl / gcm implementation $engine switch * * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() */ const ENGINE_OPENSSL_GCM = 6; /** * Engine Reverse Map * * @see \phpseclib3\Crypt\Common\SymmetricKey::getEngine() */ const ENGINE_MAP = [ self::ENGINE_INTERNAL => 'PHP', self::ENGINE_EVAL => 'Eval', self::ENGINE_MCRYPT => 'mcrypt', self::ENGINE_OPENSSL => 'OpenSSL', self::ENGINE_LIBSODIUM => 'libsodium', self::ENGINE_OPENSSL_GCM => 'OpenSSL (GCM)' ]; /** * The Encryption Mode * * @see self::__construct() * @var int */ protected $mode; /** * The Block Length of the block cipher * * @var int */ protected $block_size = 16; /** * The Key * * @see self::setKey() * @var string */ protected $key = false; /** * HMAC Key * * @see self::setupGCM() * @var ?string */ protected $hKey = false; /** * The Initialization Vector * * @see self::setIV() * @var string */ protected $iv = false; /** * A "sliding" Initialization Vector * * @see self::enableContinuousBuffer() * @see self::clearBuffers() * @var string */ protected $encryptIV; /** * A "sliding" Initialization Vector * * @see self::enableContinuousBuffer() * @see self::clearBuffers() * @var string */ protected $decryptIV; /** * Continuous Buffer status * * @see self::enableContinuousBuffer() * @var bool */ protected $continuousBuffer = false; /** * Encryption buffer for CTR, OFB and CFB modes * * @see self::encrypt() * @see self::clearBuffers() * @var array */ protected $enbuffer; /** * Decryption buffer for CTR, OFB and CFB modes * * @see self::decrypt() * @see self::clearBuffers() * @var array */ protected $debuffer; /** * mcrypt resource for encryption * * The mcrypt resource can be recreated every time something needs to be created or it can be created just once. * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode. * * @see self::encrypt() * @var resource */ private $enmcrypt; /** * mcrypt resource for decryption * * The mcrypt resource can be recreated every time something needs to be created or it can be created just once. * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode. * * @see self::decrypt() * @var resource */ private $demcrypt; /** * Does the enmcrypt resource need to be (re)initialized? * * @see \phpseclib3\Crypt\Twofish::setKey() * @see \phpseclib3\Crypt\Twofish::setIV() * @var bool */ private $enchanged = true; /** * Does the demcrypt resource need to be (re)initialized? * * @see \phpseclib3\Crypt\Twofish::setKey() * @see \phpseclib3\Crypt\Twofish::setIV() * @var bool */ private $dechanged = true; /** * mcrypt resource for CFB mode * * mcrypt's CFB mode, in (and only in) buffered context, * is broken, so phpseclib implements the CFB mode by it self, * even when the mcrypt php extension is available. * * In order to do the CFB-mode work (fast) phpseclib * use a separate ECB-mode mcrypt resource. * * @link http://phpseclib.sourceforge.net/cfb-demo.phps * @see self::encrypt() * @see self::decrypt() * @see self::setupMcrypt() * @var resource */ private $ecb; /** * Optimizing value while CFB-encrypting * * Only relevant if $continuousBuffer enabled * and $engine == self::ENGINE_MCRYPT * * It's faster to re-init $enmcrypt if * $buffer bytes > $cfb_init_len than * using the $ecb resource furthermore. * * This value depends of the chosen cipher * and the time it would be needed for it's * initialization [by mcrypt_generic_init()] * which, typically, depends on the complexity * on its internaly Key-expanding algorithm. * * @see self::encrypt() * @var int */ protected $cfb_init_len = 600; /** * Does internal cipher state need to be (re)initialized? * * @see self::setKey() * @see self::setIV() * @see self::disableContinuousBuffer() * @var bool */ protected $changed = true; /** * Does Eval engie need to be (re)initialized? * * @see self::setup() * @var bool */ protected $nonIVChanged = true; /** * Padding status * * @see self::enablePadding() * @var bool */ private $padding = true; /** * Is the mode one that is paddable? * * @see self::__construct() * @var bool */ private $paddable = false; /** * Holds which crypt engine internaly should be use, * which will be determined automatically on __construct() * * Currently available $engines are: * - self::ENGINE_LIBSODIUM (very fast, php-extension: libsodium, extension_loaded('libsodium') required) * - self::ENGINE_OPENSSL_GCM (very fast, php-extension: openssl, extension_loaded('openssl') required) * - self::ENGINE_OPENSSL (very fast, php-extension: openssl, extension_loaded('openssl') required) * - self::ENGINE_MCRYPT (fast, php-extension: mcrypt, extension_loaded('mcrypt') required) * - self::ENGINE_EVAL (medium, pure php-engine, no php-extension required) * - self::ENGINE_INTERNAL (slower, pure php-engine, no php-extension required) * * @see self::setEngine() * @see self::encrypt() * @see self::decrypt() * @var int */ protected $engine; /** * Holds the preferred crypt engine * * @see self::setEngine() * @see self::setPreferredEngine() * @var int */ private $preferredEngine; /** * The mcrypt specific name of the cipher * * Only used if $engine == self::ENGINE_MCRYPT * * @link http://www.php.net/mcrypt_module_open * @link http://www.php.net/mcrypt_list_algorithms * @see self::setupMcrypt() * @var string */ protected $cipher_name_mcrypt; /** * The openssl specific name of the cipher * * Only used if $engine == self::ENGINE_OPENSSL * * @link http://www.php.net/openssl-get-cipher-methods * @var string */ protected $cipher_name_openssl; /** * The openssl specific name of the cipher in ECB mode * * If OpenSSL does not support the mode we're trying to use (CTR) * it can still be emulated with ECB mode. * * @link http://www.php.net/openssl-get-cipher-methods * @var string */ protected $cipher_name_openssl_ecb; /** * The default salt used by setPassword() * * @see self::setPassword() * @var string */ private $password_default_salt = 'phpseclib/salt'; /** * The name of the performance-optimized callback function * * Used by encrypt() / decrypt() * only if $engine == self::ENGINE_INTERNAL * * @see self::encrypt() * @see self::decrypt() * @see self::setupInlineCrypt() * @var Callback */ protected $inline_crypt; /** * If OpenSSL can be used in ECB but not in CTR we can emulate CTR * * @see self::openssl_ctr_process() * @var bool */ private $openssl_emulate_ctr = false; /** * Don't truncate / null pad key * * @see self::clearBuffers() * @var bool */ private $skip_key_adjustment = false; /** * Has the key length explicitly been set or should it be derived from the key, itself? * * @see self::setKeyLength() * @var bool */ protected $explicit_key_length = false; /** * Hash subkey for GHASH * * @see self::setupGCM() * @see self::ghash() * @var BinaryField\Integer */ private $h; /** * Additional authenticated data * * @var string */ protected $aad = ''; /** * Authentication Tag produced after a round of encryption * * @var string */ protected $newtag = false; /** * Authentication Tag to be verified during decryption * * @var string */ protected $oldtag = false; /** * GCM Binary Field * * @see self::__construct() * @see self::ghash() * @var BinaryField */ private static $gcmField; /** * Poly1305 Prime Field * * @see self::enablePoly1305() * @see self::poly1305() * @var PrimeField */ private static $poly1305Field; /** * Flag for using regular vs "safe" intval * * @see self::initialize_static_variables() * @var boolean */ protected static $use_reg_intval; /** * Poly1305 Key * * @see self::setPoly1305Key() * @see self::poly1305() * @var string */ protected $poly1305Key; /** * Poly1305 Flag * * @see self::setPoly1305Key() * @see self::enablePoly1305() * @var boolean */ protected $usePoly1305 = false; /** * The Original Initialization Vector * * GCM uses the nonce to build the IV but we want to be able to distinguish between nonce-derived * IV's and user-set IV's * * @see self::setIV() * @var string */ private $origIV = false; /** * Nonce * * Only used with GCM. We could re-use setIV() but nonce's can be of a different length and * toggling between GCM and other modes could be more complicated if we re-used setIV() * * @see self::setNonce() * @var string */ protected $nonce = false; /** * Default Constructor. * * $mode could be: * * - ecb * * - cbc * * - ctr * * - cfb * * - cfb8 * * - ofb * * - ofb8 * * - gcm * * @param string $mode * @throws BadModeException if an invalid / unsupported mode is provided */ public function __construct($mode) { $mode = strtolower($mode); // necessary because of 5.6 compatibility; we can't do isset(self::MODE_MAP[$mode]) in 5.6 $map = self::MODE_MAP; if (!isset($map[$mode])) { throw new BadModeException('No valid mode has been specified'); } $mode = self::MODE_MAP[$mode]; // $mode dependent settings switch ($mode) { case self::MODE_ECB: case self::MODE_CBC: $this->paddable = true; break; case self::MODE_CTR: case self::MODE_CFB: case self::MODE_CFB8: case self::MODE_OFB: case self::MODE_OFB8: case self::MODE_STREAM: $this->paddable = false; break; case self::MODE_GCM: if ($this->block_size != 16) { throw new BadModeException('GCM is only valid for block ciphers with a block size of 128 bits'); } if (!isset(self::$gcmField)) { self::$gcmField = new BinaryField(128, 7, 2, 1, 0); } $this->paddable = false; break; default: throw new BadModeException('No valid mode has been specified'); } $this->mode = $mode; static::initialize_static_variables(); } /** * Initialize static variables */ protected static function initialize_static_variables() { if (!isset(self::$use_reg_intval)) { switch (true) { // PHP_OS & "\xDF\xDF\xDF" == strtoupper(substr(PHP_OS, 0, 3)), but a lot faster case (PHP_OS & "\xDF\xDF\xDF") === 'WIN': case !function_exists('php_uname'): case !is_string(php_uname('m')): case (php_uname('m') & "\xDF\xDF\xDF") != 'ARM': case defined('PHP_INT_SIZE') && PHP_INT_SIZE == 8: self::$use_reg_intval = true; break; case (php_uname('m') & "\xDF\xDF\xDF") == 'ARM': switch (true) { /* PHP 7.0.0 introduced a bug that affected 32-bit ARM processors: https://github.com/php/php-src/commit/716da71446ebbd40fa6cf2cea8a4b70f504cc3cd altho the changelogs make no mention of it, this bug was fixed with this commit: https://github.com/php/php-src/commit/c1729272b17a1fe893d1a54e423d3b71470f3ee8 affected versions of PHP are: 7.0.x, 7.1.0 - 7.1.23 and 7.2.0 - 7.2.11 */ case PHP_VERSION_ID >= 70000 && PHP_VERSION_ID <= 70123: case PHP_VERSION_ID >= 70200 && PHP_VERSION_ID <= 70211: self::$use_reg_intval = false; break; default: self::$use_reg_intval = true; } } } } /** * Sets the initialization vector. * * setIV() is not required when ecb or gcm modes are being used. * * {@internal Can be overwritten by a sub class, but does not have to be} * * @param string $iv * @throws \LengthException if the IV length isn't equal to the block size * @throws \BadMethodCallException if an IV is provided when one shouldn't be */ public function setIV($iv) { if ($this->mode == self::MODE_ECB) { throw new \BadMethodCallException('This mode does not require an IV.'); } if ($this->mode == self::MODE_GCM) { throw new \BadMethodCallException('Use setNonce instead'); } if (!$this->usesIV()) { throw new \BadMethodCallException('This algorithm does not use an IV.'); } if (strlen($iv) != $this->block_size) { throw new \LengthException('Received initialization vector of size ' . strlen($iv) . ', but size ' . $this->block_size . ' is required'); } $this->iv = $this->origIV = $iv; $this->changed = true; } /** * Enables Poly1305 mode. * * Once enabled Poly1305 cannot be disabled. * * @throws \BadMethodCallException if Poly1305 is enabled whilst in GCM mode */ public function enablePoly1305() { if ($this->mode == self::MODE_GCM) { throw new \BadMethodCallException('Poly1305 cannot be used in GCM mode'); } $this->usePoly1305 = true; } /** * Enables Poly1305 mode. * * Once enabled Poly1305 cannot be disabled. If $key is not passed then an attempt to call createPoly1305Key * will be made. * * @param string $key optional * @throws \LengthException if the key isn't long enough * @throws \BadMethodCallException if Poly1305 is enabled whilst in GCM mode */ public function setPoly1305Key($key = null) { if ($this->mode == self::MODE_GCM) { throw new \BadMethodCallException('Poly1305 cannot be used in GCM mode'); } if (!is_string($key) || strlen($key) != 32) { throw new \LengthException('The Poly1305 key must be 32 bytes long (256 bits)'); } if (!isset(self::$poly1305Field)) { // 2^130-5 self::$poly1305Field = new PrimeField(new BigInteger('3fffffffffffffffffffffffffffffffb', 16)); } $this->poly1305Key = $key; $this->usePoly1305 = true; } /** * Sets the nonce. * * setNonce() is only required when gcm is used * * @param string $nonce * @throws \BadMethodCallException if an nonce is provided when one shouldn't be */ public function setNonce($nonce) { if ($this->mode != self::MODE_GCM) { throw new \BadMethodCallException('Nonces are only used in GCM mode.'); } $this->nonce = $nonce; $this->setEngine(); } /** * Sets additional authenticated data * * setAAD() is only used by gcm or in poly1305 mode * * @param string $aad * @throws \BadMethodCallException if mode isn't GCM or if poly1305 isn't being utilized */ public function setAAD($aad) { if ($this->mode != self::MODE_GCM && !$this->usePoly1305) { throw new \BadMethodCallException('Additional authenticated data is only utilized in GCM mode or with Poly1305'); } $this->aad = $aad; } /** * Returns whether or not the algorithm uses an IV * * @return bool */ public function usesIV() { return $this->mode != self::MODE_GCM && $this->mode != self::MODE_ECB; } /** * Returns whether or not the algorithm uses a nonce * * @return bool */ public function usesNonce() { return $this->mode == self::MODE_GCM; } /** * Returns the current key length in bits * * @return int */ public function getKeyLength() { return $this->key_length << 3; } /** * Returns the current block length in bits * * @return int */ public function getBlockLength() { return $this->block_size << 3; } /** * Returns the current block length in bytes * * @return int */ public function getBlockLengthInBytes() { return $this->block_size; } /** * Sets the key length. * * Keys with explicitly set lengths need to be treated accordingly * * @param int $length */ public function setKeyLength($length) { $this->explicit_key_length = $length >> 3; if (is_string($this->key) && strlen($this->key) != $this->explicit_key_length) { $this->key = false; throw new InconsistentSetupException('Key has already been set and is not ' . $this->explicit_key_length . ' bytes long'); } } /** * Sets the key. * * The min/max length(s) of the key depends on the cipher which is used. * If the key not fits the length(s) of the cipher it will paded with null bytes * up to the closest valid key length. If the key is more than max length, * we trim the excess bits. * * If the key is not explicitly set, it'll be assumed to be all null bytes. * * {@internal Could, but not must, extend by the child Crypt_* class} * * @param string $key */ public function setKey($key) { if ($this->explicit_key_length !== false && strlen($key) != $this->explicit_key_length) { throw new InconsistentSetupException('Key length has already been set to ' . $this->explicit_key_length . ' bytes and this key is ' . strlen($key) . ' bytes'); } $this->key = $key; $this->key_length = strlen($key); $this->setEngine(); } /** * Sets the password. * * Depending on what $method is set to, setPassword()'s (optional) parameters are as follows: * {@link http://en.wikipedia.org/wiki/PBKDF2 pbkdf2} or pbkdf1: * $hash, $salt, $count, $dkLen * * Where $hash (default = sha1) currently supports the following hashes: see: Crypt/Hash.php * {@link https://en.wikipedia.org/wiki/Bcrypt bcypt}: * $salt, $rounds, $keylen * * This is a modified version of bcrypt used by OpenSSH. * * {@internal Could, but not must, extend by the child Crypt_* class} * * @see Crypt/Hash.php * @param string $password * @param string $method * @param int|string ...$func_args * @throws \LengthException if pbkdf1 is being used and the derived key length exceeds the hash length * @throws \RuntimeException if bcrypt is being used and a salt isn't provided * @return bool */ public function setPassword($password, $method = 'pbkdf2', ...$func_args) { $key = ''; $method = strtolower($method); switch ($method) { case 'bcrypt': if (!isset($func_args[2])) { throw new \RuntimeException('A salt must be provided for bcrypt to work'); } $salt = $func_args[0]; $rounds = isset($func_args[1]) ? $func_args[1] : 16; $keylen = isset($func_args[2]) ? $func_args[2] : $this->key_length; $key = Blowfish::bcrypt_pbkdf($password, $salt, $keylen + $this->block_size, $rounds); $this->setKey(substr($key, 0, $keylen)); $this->setIV(substr($key, $keylen)); return true; case 'pkcs12': // from https://tools.ietf.org/html/rfc7292#appendix-B.2 case 'pbkdf1': case 'pbkdf2': // Hash function $hash = isset($func_args[0]) ? strtolower($func_args[0]) : 'sha1'; $hashObj = new Hash(); $hashObj->setHash($hash); // WPA and WPA2 use the SSID as the salt $salt = isset($func_args[1]) ? $func_args[1] : $this->password_default_salt; // RFC2898#section-4.2 uses 1,000 iterations by default // WPA and WPA2 use 4,096. $count = isset($func_args[2]) ? $func_args[2] : 1000; // Keylength if (isset($func_args[3])) { if ($func_args[3] <= 0) { throw new \LengthException('Derived key length cannot be longer 0 or less'); } $dkLen = $func_args[3]; } else { $key_length = $this->explicit_key_length !== false ? $this->explicit_key_length : $this->key_length; $dkLen = $method == 'pbkdf1' ? 2 * $key_length : $key_length; } switch (true) { case $method == 'pkcs12': /* In this specification, however, all passwords are created from BMPStrings with a NULL terminator. This means that each character in the original BMPString is encoded in 2 bytes in big-endian format (most-significant byte first). There are no Unicode byte order marks. The 2 bytes produced from the last character in the BMPString are followed by 2 additional bytes with the value 0x00. -- https://tools.ietf.org/html/rfc7292#appendix-B.1 */ $password = "\0" . chunk_split($password, 1, "\0") . "\0"; /* This standard specifies 3 different values for the ID byte mentioned above: 1. If ID=1, then the pseudorandom bits being produced are to be used as key material for performing encryption or decryption. 2. If ID=2, then the pseudorandom bits being produced are to be used as an IV (Initial Value) for encryption or decryption. 3. If ID=3, then the pseudorandom bits being produced are to be used as an integrity key for MACing. */ // Construct a string, D (the "diversifier"), by concatenating v/8 // copies of ID. $blockLength = $hashObj->getBlockLengthInBytes(); $d1 = str_repeat(chr(1), $blockLength); $d2 = str_repeat(chr(2), $blockLength); $s = ''; if (strlen($salt)) { while (strlen($s) < $blockLength) { $s .= $salt; } } $s = substr($s, 0, $blockLength); $p = ''; if (strlen($password)) { while (strlen($p) < $blockLength) { $p .= $password; } } $p = substr($p, 0, $blockLength); $i = $s . $p; $this->setKey(self::pkcs12helper($dkLen, $hashObj, $i, $d1, $count)); if ($this->usesIV()) { $this->setIV(self::pkcs12helper($this->block_size, $hashObj, $i, $d2, $count)); } return true; case $method == 'pbkdf1': if ($dkLen > $hashObj->getLengthInBytes()) { throw new \LengthException('Derived key length cannot be longer than the hash length'); } $t = $password . $salt; for ($i = 0; $i < $count; ++$i) { $t = $hashObj->hash($t); } $key = substr($t, 0, $dkLen); $this->setKey(substr($key, 0, $dkLen >> 1)); if ($this->usesIV()) { $this->setIV(substr($key, $dkLen >> 1)); } return true; case !in_array($hash, hash_algos()): $i = 1; $hashObj->setKey($password); while (strlen($key) < $dkLen) { $f = $u = $hashObj->hash($salt . pack('N', $i++)); for ($j = 2; $j <= $count; ++$j) { $u = $hashObj->hash($u); $f ^= $u; } $key .= $f; } $key = substr($key, 0, $dkLen); break; default: $key = hash_pbkdf2($hash, $password, $salt, $count, $dkLen, true); } break; default: throw new UnsupportedAlgorithmException($method . ' is not a supported password hashing method'); } $this->setKey($key); return true; } /** * PKCS#12 KDF Helper Function * * As discussed here: * * {@link https://tools.ietf.org/html/rfc7292#appendix-B} * * @see self::setPassword() * @param int $n * @param Hash $hashObj * @param string $i * @param string $d * @param int $count * @return string $a */ private static function pkcs12helper($n, $hashObj, $i, $d, $count) { static $one; if (!isset($one)) { $one = new BigInteger(1); } $blockLength = $hashObj->getBlockLength() >> 3; $c = ceil($n / $hashObj->getLengthInBytes()); $a = ''; for ($j = 1; $j <= $c; $j++) { $ai = $d . $i; for ($k = 0; $k < $count; $k++) { $ai = $hashObj->hash($ai); } $b = ''; while (strlen($b) < $blockLength) { $b .= $ai; } $b = substr($b, 0, $blockLength); $b = new BigInteger($b, 256); $newi = ''; for ($k = 0; $k < strlen($i); $k += $blockLength) { $temp = substr($i, $k, $blockLength); $temp = new BigInteger($temp, 256); $temp->setPrecision($blockLength << 3); $temp = $temp->add($b); $temp = $temp->add($one); $newi .= $temp->toBytes(false); } $i = $newi; $a .= $ai; } return substr($a, 0, $n); } /** * Encrypts a message. * * $plaintext will be padded with additional bytes such that it's length is a multiple of the block size. Other cipher * implementations may or may not pad in the same manner. Other common approaches to padding and the reasons why it's * necessary are discussed in the following * URL: * * {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html} * * An alternative to padding is to, separately, send the length of the file. This is what SSH, in fact, does. * strlen($plaintext) will still need to be a multiple of the block size, however, arbitrary values can be added to make it that * length. * * {@internal Could, but not must, extend by the child Crypt_* class} * * @see self::decrypt() * @param string $plaintext * @return string $ciphertext */ public function encrypt($plaintext) { if ($this->paddable) { $plaintext = $this->pad($plaintext); } $this->setup(); if ($this->mode == self::MODE_GCM) { $oldIV = $this->iv; Strings::increment_str($this->iv); $cipher = new static('ctr'); $cipher->setKey($this->key); $cipher->setIV($this->iv); $ciphertext = $cipher->encrypt($plaintext); $s = $this->ghash( self::nullPad128($this->aad) . self::nullPad128($ciphertext) . self::len64($this->aad) . self::len64($ciphertext) ); $cipher->encryptIV = $this->iv = $this->encryptIV = $this->decryptIV = $oldIV; $this->newtag = $cipher->encrypt($s); return $ciphertext; } if (isset($this->poly1305Key)) { $cipher = clone $this; unset($cipher->poly1305Key); $this->usePoly1305 = false; $ciphertext = $cipher->encrypt($plaintext); $this->newtag = $this->poly1305($ciphertext); return $ciphertext; } if ($this->engine === self::ENGINE_OPENSSL) { switch ($this->mode) { case self::MODE_STREAM: return openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); case self::MODE_ECB: return openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); case self::MODE_CBC: $result = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $this->encryptIV); if ($this->continuousBuffer) { $this->encryptIV = substr($result, -$this->block_size); } return $result; case self::MODE_CTR: return $this->openssl_ctr_process($plaintext, $this->encryptIV, $this->enbuffer); case self::MODE_CFB: // cfb loosely routines inspired by openssl's: // {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1} $ciphertext = ''; if ($this->continuousBuffer) { $iv = &$this->encryptIV; $pos = &$this->enbuffer['pos']; } else { $iv = $this->encryptIV; $pos = 0; } $len = strlen($plaintext); $i = 0; if ($pos) { $orig_pos = $pos; $max = $this->block_size - $pos; if ($len >= $max) { $i = $max; $len -= $max; $pos = 0; } else { $i = $len; $pos += $len; $len = 0; } // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize $ciphertext = substr($iv, $orig_pos) ^ $plaintext; $iv = substr_replace($iv, $ciphertext, $orig_pos, $i); $plaintext = substr($plaintext, $i); } $overflow = $len % $this->block_size; if ($overflow) { $ciphertext .= openssl_encrypt(substr($plaintext, 0, -$overflow) . str_repeat("\0", $this->block_size), $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); $iv = Strings::pop($ciphertext, $this->block_size); $size = $len - $overflow; $block = $iv ^ substr($plaintext, -$overflow); $iv = substr_replace($iv, $block, 0, $overflow); $ciphertext .= $block; $pos = $overflow; } elseif ($len) { $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); $iv = substr($ciphertext, -$this->block_size); } return $ciphertext; case self::MODE_CFB8: $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $this->encryptIV); if ($this->continuousBuffer) { if (($len = strlen($ciphertext)) >= $this->block_size) { $this->encryptIV = substr($ciphertext, -$this->block_size); } else { $this->encryptIV = substr($this->encryptIV, $len - $this->block_size) . substr($ciphertext, -$len); } } return $ciphertext; case self::MODE_OFB8: $ciphertext = ''; $len = strlen($plaintext); $iv = $this->encryptIV; for ($i = 0; $i < $len; ++$i) { $xor = openssl_encrypt($iv, $this->cipher_name_openssl_ecb, $this->key, $this->openssl_options, $this->decryptIV); $ciphertext .= $plaintext[$i] ^ $xor; $iv = substr($iv, 1) . $xor[0]; } if ($this->continuousBuffer) { $this->encryptIV = $iv; } break; case self::MODE_OFB: return $this->openssl_ofb_process($plaintext, $this->encryptIV, $this->enbuffer); } } if ($this->engine === self::ENGINE_MCRYPT) { set_error_handler(function () { }); if ($this->enchanged) { mcrypt_generic_init($this->enmcrypt, $this->key, $this->getIV($this->encryptIV)); $this->enchanged = false; } // re: {@link http://phpseclib.sourceforge.net/cfb-demo.phps} // using mcrypt's default handing of CFB the above would output two different things. using phpseclib's // rewritten CFB implementation the above outputs the same thing twice. if ($this->mode == self::MODE_CFB && $this->continuousBuffer) { $block_size = $this->block_size; $iv = &$this->encryptIV; $pos = &$this->enbuffer['pos']; $len = strlen($plaintext); $ciphertext = ''; $i = 0; if ($pos) { $orig_pos = $pos; $max = $block_size - $pos; if ($len >= $max) { $i = $max; $len -= $max; $pos = 0; } else { $i = $len; $pos += $len; $len = 0; } $ciphertext = substr($iv, $orig_pos) ^ $plaintext; $iv = substr_replace($iv, $ciphertext, $orig_pos, $i); $this->enbuffer['enmcrypt_init'] = true; } if ($len >= $block_size) { if ($this->enbuffer['enmcrypt_init'] === false || $len > $this->cfb_init_len) { if ($this->enbuffer['enmcrypt_init'] === true) { mcrypt_generic_init($this->enmcrypt, $this->key, $iv); $this->enbuffer['enmcrypt_init'] = false; } $ciphertext .= mcrypt_generic($this->enmcrypt, substr($plaintext, $i, $len - $len % $block_size)); $iv = substr($ciphertext, -$block_size); $len %= $block_size; } else { while ($len >= $block_size) { $iv = mcrypt_generic($this->ecb, $iv) ^ substr($plaintext, $i, $block_size); $ciphertext .= $iv; $len -= $block_size; $i += $block_size; } } } if ($len) { $iv = mcrypt_generic($this->ecb, $iv); $block = $iv ^ substr($plaintext, -$len); $iv = substr_replace($iv, $block, 0, $len); $ciphertext .= $block; $pos = $len; } restore_error_handler(); return $ciphertext; } $ciphertext = mcrypt_generic($this->enmcrypt, $plaintext); if (!$this->continuousBuffer) { mcrypt_generic_init($this->enmcrypt, $this->key, $this->getIV($this->encryptIV)); } restore_error_handler(); return $ciphertext; } if ($this->engine === self::ENGINE_EVAL) { $inline = $this->inline_crypt; return $inline('encrypt', $plaintext); } $buffer = &$this->enbuffer; $block_size = $this->block_size; $ciphertext = ''; switch ($this->mode) { case self::MODE_ECB: for ($i = 0; $i < strlen($plaintext); $i += $block_size) { $ciphertext .= $this->encryptBlock(substr($plaintext, $i, $block_size)); } break; case self::MODE_CBC: $xor = $this->encryptIV; for ($i = 0; $i < strlen($plaintext); $i += $block_size) { $block = substr($plaintext, $i, $block_size); $block = $this->encryptBlock($block ^ $xor); $xor = $block; $ciphertext .= $block; } if ($this->continuousBuffer) { $this->encryptIV = $xor; } break; case self::MODE_CTR: $xor = $this->encryptIV; if (strlen($buffer['ciphertext'])) { for ($i = 0; $i < strlen($plaintext); $i += $block_size) { $block = substr($plaintext, $i, $block_size); if (strlen($block) > strlen($buffer['ciphertext'])) { $buffer['ciphertext'] .= $this->encryptBlock($xor); Strings::increment_str($xor); } $key = Strings::shift($buffer['ciphertext'], $block_size); $ciphertext .= $block ^ $key; } } else { for ($i = 0; $i < strlen($plaintext); $i += $block_size) { $block = substr($plaintext, $i, $block_size); $key = $this->encryptBlock($xor); Strings::increment_str($xor); $ciphertext .= $block ^ $key; } } if ($this->continuousBuffer) { $this->encryptIV = $xor; if ($start = strlen($plaintext) % $block_size) { $buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext']; } } break; case self::MODE_CFB: // cfb loosely routines inspired by openssl's: // {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1} if ($this->continuousBuffer) { $iv = &$this->encryptIV; $pos = &$buffer['pos']; } else { $iv = $this->encryptIV; $pos = 0; } $len = strlen($plaintext); $i = 0; if ($pos) { $orig_pos = $pos; $max = $block_size - $pos; if ($len >= $max) { $i = $max; $len -= $max; $pos = 0; } else { $i = $len; $pos += $len; $len = 0; } // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize $ciphertext = substr($iv, $orig_pos) ^ $plaintext; $iv = substr_replace($iv, $ciphertext, $orig_pos, $i); } while ($len >= $block_size) { $iv = $this->encryptBlock($iv) ^ substr($plaintext, $i, $block_size); $ciphertext .= $iv; $len -= $block_size; $i += $block_size; } if ($len) { $iv = $this->encryptBlock($iv); $block = $iv ^ substr($plaintext, $i); $iv = substr_replace($iv, $block, 0, $len); $ciphertext .= $block; $pos = $len; } break; case self::MODE_CFB8: $ciphertext = ''; $len = strlen($plaintext); $iv = $this->encryptIV; for ($i = 0; $i < $len; ++$i) { $ciphertext .= ($c = $plaintext[$i] ^ $this->encryptBlock($iv)); $iv = substr($iv, 1) . $c; } if ($this->continuousBuffer) { if ($len >= $block_size) { $this->encryptIV = substr($ciphertext, -$block_size); } else { $this->encryptIV = substr($this->encryptIV, $len - $block_size) . substr($ciphertext, -$len); } } break; case self::MODE_OFB8: $ciphertext = ''; $len = strlen($plaintext); $iv = $this->encryptIV; for ($i = 0; $i < $len; ++$i) { $xor = $this->encryptBlock($iv); $ciphertext .= $plaintext[$i] ^ $xor; $iv = substr($iv, 1) . $xor[0]; } if ($this->continuousBuffer) { $this->encryptIV = $iv; } break; case self::MODE_OFB: $xor = $this->encryptIV; if (strlen($buffer['xor'])) { for ($i = 0; $i < strlen($plaintext); $i += $block_size) { $block = substr($plaintext, $i, $block_size); if (strlen($block) > strlen($buffer['xor'])) { $xor = $this->encryptBlock($xor); $buffer['xor'] .= $xor; } $key = Strings::shift($buffer['xor'], $block_size); $ciphertext .= $block ^ $key; } } else { for ($i = 0; $i < strlen($plaintext); $i += $block_size) { $xor = $this->encryptBlock($xor); $ciphertext .= substr($plaintext, $i, $block_size) ^ $xor; } $key = $xor; } if ($this->continuousBuffer) { $this->encryptIV = $xor; if ($start = strlen($plaintext) % $block_size) { $buffer['xor'] = substr($key, $start) . $buffer['xor']; } } break; case self::MODE_STREAM: $ciphertext = $this->encryptBlock($plaintext); break; } return $ciphertext; } /** * Decrypts a message. * * If strlen($ciphertext) is not a multiple of the block size, null bytes will be added to the end of the string until * it is. * * {@internal Could, but not must, extend by the child Crypt_* class} * * @see self::encrypt() * @param string $ciphertext * @return string $plaintext * @throws \LengthException if we're inside a block cipher and the ciphertext length is not a multiple of the block size */ public function decrypt($ciphertext) { if ($this->paddable && strlen($ciphertext) % $this->block_size) { throw new \LengthException('The ciphertext length (' . strlen($ciphertext) . ') needs to be a multiple of the block size (' . $this->block_size . ')'); } $this->setup(); if ($this->mode == self::MODE_GCM || isset($this->poly1305Key)) { if ($this->oldtag === false) { throw new InsufficientSetupException('Authentication Tag has not been set'); } if (isset($this->poly1305Key)) { $newtag = $this->poly1305($ciphertext); } else { $oldIV = $this->iv; Strings::increment_str($this->iv); $cipher = new static('ctr'); $cipher->setKey($this->key); $cipher->setIV($this->iv); $plaintext = $cipher->decrypt($ciphertext); $s = $this->ghash( self::nullPad128($this->aad) . self::nullPad128($ciphertext) . self::len64($this->aad) . self::len64($ciphertext) ); $cipher->encryptIV = $this->iv = $this->encryptIV = $this->decryptIV = $oldIV; $newtag = $cipher->encrypt($s); } if ($this->oldtag != substr($newtag, 0, strlen($newtag))) { $cipher = clone $this; unset($cipher->poly1305Key); $this->usePoly1305 = false; $plaintext = $cipher->decrypt($ciphertext); $this->oldtag = false; throw new BadDecryptionException('Derived authentication tag and supplied authentication tag do not match'); } $this->oldtag = false; return $plaintext; } if ($this->engine === self::ENGINE_OPENSSL) { switch ($this->mode) { case self::MODE_STREAM: $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); break; case self::MODE_ECB: $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); break; case self::MODE_CBC: $offset = $this->block_size; $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $this->decryptIV); if ($this->continuousBuffer) { $this->decryptIV = substr($ciphertext, -$offset, $this->block_size); } break; case self::MODE_CTR: $plaintext = $this->openssl_ctr_process($ciphertext, $this->decryptIV, $this->debuffer); break; case self::MODE_CFB: // cfb loosely routines inspired by openssl's: // {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1} $plaintext = ''; if ($this->continuousBuffer) { $iv = &$this->decryptIV; $pos = &$this->debuffer['pos']; } else { $iv = $this->decryptIV; $pos = 0; } $len = strlen($ciphertext); $i = 0; if ($pos) { $orig_pos = $pos; $max = $this->block_size - $pos; if ($len >= $max) { $i = $max; $len -= $max; $pos = 0; } else { $i = $len; $pos += $len; $len = 0; } // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $this->blocksize $plaintext = substr($iv, $orig_pos) ^ $ciphertext; $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i); $ciphertext = substr($ciphertext, $i); } $overflow = $len % $this->block_size; if ($overflow) { $plaintext .= openssl_decrypt(substr($ciphertext, 0, -$overflow), $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); if ($len - $overflow) { $iv = substr($ciphertext, -$overflow - $this->block_size, -$overflow); } $iv = openssl_encrypt(str_repeat("\0", $this->block_size), $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); $plaintext .= $iv ^ substr($ciphertext, -$overflow); $iv = substr_replace($iv, substr($ciphertext, -$overflow), 0, $overflow); $pos = $overflow; } elseif ($len) { $plaintext .= openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); $iv = substr($ciphertext, -$this->block_size); } break; case self::MODE_CFB8: $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $this->decryptIV); if ($this->continuousBuffer) { if (($len = strlen($ciphertext)) >= $this->block_size) { $this->decryptIV = substr($ciphertext, -$this->block_size); } else { $this->decryptIV = substr($this->decryptIV, $len - $this->block_size) . substr($ciphertext, -$len); } } break; case self::MODE_OFB8: $plaintext = ''; $len = strlen($ciphertext); $iv = $this->decryptIV; for ($i = 0; $i < $len; ++$i) { $xor = openssl_encrypt($iv, $this->cipher_name_openssl_ecb, $this->key, $this->openssl_options, $this->decryptIV); $plaintext .= $ciphertext[$i] ^ $xor; $iv = substr($iv, 1) . $xor[0]; } if ($this->continuousBuffer) { $this->decryptIV = $iv; } break; case self::MODE_OFB: $plaintext = $this->openssl_ofb_process($ciphertext, $this->decryptIV, $this->debuffer); } return $this->paddable ? $this->unpad($plaintext) : $plaintext; } if ($this->engine === self::ENGINE_MCRYPT) { set_error_handler(function () { }); $block_size = $this->block_size; if ($this->dechanged) { mcrypt_generic_init($this->demcrypt, $this->key, $this->getIV($this->decryptIV)); $this->dechanged = false; } if ($this->mode == self::MODE_CFB && $this->continuousBuffer) { $iv = &$this->decryptIV; $pos = &$this->debuffer['pos']; $len = strlen($ciphertext); $plaintext = ''; $i = 0; if ($pos) { $orig_pos = $pos; $max = $block_size - $pos; if ($len >= $max) { $i = $max; $len -= $max; $pos = 0; } else { $i = $len; $pos += $len; $len = 0; } // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize $plaintext = substr($iv, $orig_pos) ^ $ciphertext; $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i); } if ($len >= $block_size) { $cb = substr($ciphertext, $i, $len - $len % $block_size); $plaintext .= mcrypt_generic($this->ecb, $iv . $cb) ^ $cb; $iv = substr($cb, -$block_size); $len %= $block_size; } if ($len) { $iv = mcrypt_generic($this->ecb, $iv); $plaintext .= $iv ^ substr($ciphertext, -$len); $iv = substr_replace($iv, substr($ciphertext, -$len), 0, $len); $pos = $len; } restore_error_handler(); return $plaintext; } $plaintext = mdecrypt_generic($this->demcrypt, $ciphertext); if (!$this->continuousBuffer) { mcrypt_generic_init($this->demcrypt, $this->key, $this->getIV($this->decryptIV)); } restore_error_handler(); return $this->paddable ? $this->unpad($plaintext) : $plaintext; } if ($this->engine === self::ENGINE_EVAL) { $inline = $this->inline_crypt; return $inline('decrypt', $ciphertext); } $block_size = $this->block_size; $buffer = &$this->debuffer; $plaintext = ''; switch ($this->mode) { case self::MODE_ECB: for ($i = 0; $i < strlen($ciphertext); $i += $block_size) { $plaintext .= $this->decryptBlock(substr($ciphertext, $i, $block_size)); } break; case self::MODE_CBC: $xor = $this->decryptIV; for ($i = 0; $i < strlen($ciphertext); $i += $block_size) { $block = substr($ciphertext, $i, $block_size); $plaintext .= $this->decryptBlock($block) ^ $xor; $xor = $block; } if ($this->continuousBuffer) { $this->decryptIV = $xor; } break; case self::MODE_CTR: $xor = $this->decryptIV; if (strlen($buffer['ciphertext'])) { for ($i = 0; $i < strlen($ciphertext); $i += $block_size) { $block = substr($ciphertext, $i, $block_size); if (strlen($block) > strlen($buffer['ciphertext'])) { $buffer['ciphertext'] .= $this->encryptBlock($xor); Strings::increment_str($xor); } $key = Strings::shift($buffer['ciphertext'], $block_size); $plaintext .= $block ^ $key; } } else { for ($i = 0; $i < strlen($ciphertext); $i += $block_size) { $block = substr($ciphertext, $i, $block_size); $key = $this->encryptBlock($xor); Strings::increment_str($xor); $plaintext .= $block ^ $key; } } if ($this->continuousBuffer) { $this->decryptIV = $xor; if ($start = strlen($ciphertext) % $block_size) { $buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext']; } } break; case self::MODE_CFB: if ($this->continuousBuffer) { $iv = &$this->decryptIV; $pos = &$buffer['pos']; } else { $iv = $this->decryptIV; $pos = 0; } $len = strlen($ciphertext); $i = 0; if ($pos) { $orig_pos = $pos; $max = $block_size - $pos; if ($len >= $max) { $i = $max; $len -= $max; $pos = 0; } else { $i = $len; $pos += $len; $len = 0; } // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize $plaintext = substr($iv, $orig_pos) ^ $ciphertext; $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i); } while ($len >= $block_size) { $iv = $this->encryptBlock($iv); $cb = substr($ciphertext, $i, $block_size); $plaintext .= $iv ^ $cb; $iv = $cb; $len -= $block_size; $i += $block_size; } if ($len) { $iv = $this->encryptBlock($iv); $plaintext .= $iv ^ substr($ciphertext, $i); $iv = substr_replace($iv, substr($ciphertext, $i), 0, $len); $pos = $len; } break; case self::MODE_CFB8: $plaintext = ''; $len = strlen($ciphertext); $iv = $this->decryptIV; for ($i = 0; $i < $len; ++$i) { $plaintext .= $ciphertext[$i] ^ $this->encryptBlock($iv); $iv = substr($iv, 1) . $ciphertext[$i]; } if ($this->continuousBuffer) { if ($len >= $block_size) { $this->decryptIV = substr($ciphertext, -$block_size); } else { $this->decryptIV = substr($this->decryptIV, $len - $block_size) . substr($ciphertext, -$len); } } break; case self::MODE_OFB8: $plaintext = ''; $len = strlen($ciphertext); $iv = $this->decryptIV; for ($i = 0; $i < $len; ++$i) { $xor = $this->encryptBlock($iv); $plaintext .= $ciphertext[$i] ^ $xor; $iv = substr($iv, 1) . $xor[0]; } if ($this->continuousBuffer) { $this->decryptIV = $iv; } break; case self::MODE_OFB: $xor = $this->decryptIV; if (strlen($buffer['xor'])) { for ($i = 0; $i < strlen($ciphertext); $i += $block_size) { $block = substr($ciphertext, $i, $block_size); if (strlen($block) > strlen($buffer['xor'])) { $xor = $this->encryptBlock($xor); $buffer['xor'] .= $xor; } $key = Strings::shift($buffer['xor'], $block_size); $plaintext .= $block ^ $key; } } else { for ($i = 0; $i < strlen($ciphertext); $i += $block_size) { $xor = $this->encryptBlock($xor); $plaintext .= substr($ciphertext, $i, $block_size) ^ $xor; } $key = $xor; } if ($this->continuousBuffer) { $this->decryptIV = $xor; if ($start = strlen($ciphertext) % $block_size) { $buffer['xor'] = substr($key, $start) . $buffer['xor']; } } break; case self::MODE_STREAM: $plaintext = $this->decryptBlock($ciphertext); break; } return $this->paddable ? $this->unpad($plaintext) : $plaintext; } /** * Get the authentication tag * * Only used in GCM or Poly1305 mode * * @see self::encrypt() * @param int $length optional * @return string * @throws \LengthException if $length isn't of a sufficient length * @throws \RuntimeException if GCM mode isn't being used */ public function getTag($length = 16) { if ($this->mode != self::MODE_GCM && !$this->usePoly1305) { throw new \BadMethodCallException('Authentication tags are only utilized in GCM mode or with Poly1305'); } if ($this->newtag === false) { throw new \BadMethodCallException('A tag can only be returned after a round of encryption has been performed'); } // the tag is 128-bits. it can't be greater than 16 bytes because that's bigger than the tag is. if it // were 0 you might as well be doing CTR and less than 4 provides minimal security that could be trivially // easily brute forced. // see https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf#page=36 // for more info if ($length < 4 || $length > 16) { throw new \LengthException('The authentication tag must be between 4 and 16 bytes long'); } return $length == 16 ? $this->newtag : substr($this->newtag, 0, $length); } /** * Sets the authentication tag * * Only used in GCM mode * * @see self::decrypt() * @param string $tag * @throws \LengthException if $length isn't of a sufficient length * @throws \RuntimeException if GCM mode isn't being used */ public function setTag($tag) { if ($this->usePoly1305 && !isset($this->poly1305Key) && method_exists($this, 'createPoly1305Key')) { $this->createPoly1305Key(); } if ($this->mode != self::MODE_GCM && !$this->usePoly1305) { throw new \BadMethodCallException('Authentication tags are only utilized in GCM mode or with Poly1305'); } $length = strlen($tag); if ($length < 4 || $length > 16) { throw new \LengthException('The authentication tag must be between 4 and 16 bytes long'); } $this->oldtag = $tag; } /** * Get the IV * * mcrypt requires an IV even if ECB is used * * @see self::encrypt() * @see self::decrypt() * @param string $iv * @return string */ protected function getIV($iv) { return $this->mode == self::MODE_ECB ? str_repeat("\0", $this->block_size) : $iv; } /** * OpenSSL CTR Processor * * PHP's OpenSSL bindings do not operate in continuous mode so we'll wrap around it. Since the keystream * for CTR is the same for both encrypting and decrypting this function is re-used by both SymmetricKey::encrypt() * and SymmetricKey::decrypt(). Also, OpenSSL doesn't implement CTR for all of it's symmetric ciphers so this * function will emulate CTR with ECB when necessary. * * @see self::encrypt() * @see self::decrypt() * @param string $plaintext * @param string $encryptIV * @param array $buffer * @return string */ private function openssl_ctr_process($plaintext, &$encryptIV, &$buffer) { $ciphertext = ''; $block_size = $this->block_size; $key = $this->key; if ($this->openssl_emulate_ctr) { $xor = $encryptIV; if (strlen($buffer['ciphertext'])) { for ($i = 0; $i < strlen($plaintext); $i += $block_size) { $block = substr($plaintext, $i, $block_size); if (strlen($block) > strlen($buffer['ciphertext'])) { $buffer['ciphertext'] .= openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); } Strings::increment_str($xor); $otp = Strings::shift($buffer['ciphertext'], $block_size); $ciphertext .= $block ^ $otp; } } else { for ($i = 0; $i < strlen($plaintext); $i += $block_size) { $block = substr($plaintext, $i, $block_size); $otp = openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); Strings::increment_str($xor); $ciphertext .= $block ^ $otp; } } if ($this->continuousBuffer) { $encryptIV = $xor; if ($start = strlen($plaintext) % $block_size) { $buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext']; } } return $ciphertext; } if (strlen($buffer['ciphertext'])) { $ciphertext = $plaintext ^ Strings::shift($buffer['ciphertext'], strlen($plaintext)); $plaintext = substr($plaintext, strlen($ciphertext)); if (!strlen($plaintext)) { return $ciphertext; } } $overflow = strlen($plaintext) % $block_size; if ($overflow) { $plaintext2 = Strings::pop($plaintext, $overflow); // ie. trim $plaintext to a multiple of $block_size and put rest of $plaintext in $plaintext2 $encrypted = openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $encryptIV); $temp = Strings::pop($encrypted, $block_size); $ciphertext .= $encrypted . ($plaintext2 ^ $temp); if ($this->continuousBuffer) { $buffer['ciphertext'] = substr($temp, $overflow); $encryptIV = $temp; } } elseif (!strlen($buffer['ciphertext'])) { $ciphertext .= openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $encryptIV); $temp = Strings::pop($ciphertext, $block_size); if ($this->continuousBuffer) { $encryptIV = $temp; } } if ($this->continuousBuffer) { $encryptIV = openssl_decrypt($encryptIV, $this->cipher_name_openssl_ecb, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); if ($overflow) { Strings::increment_str($encryptIV); } } return $ciphertext; } /** * OpenSSL OFB Processor * * PHP's OpenSSL bindings do not operate in continuous mode so we'll wrap around it. Since the keystream * for OFB is the same for both encrypting and decrypting this function is re-used by both SymmetricKey::encrypt() * and SymmetricKey::decrypt(). * * @see self::encrypt() * @see self::decrypt() * @param string $plaintext * @param string $encryptIV * @param array $buffer * @return string */ private function openssl_ofb_process($plaintext, &$encryptIV, &$buffer) { if (strlen($buffer['xor'])) { $ciphertext = $plaintext ^ $buffer['xor']; $buffer['xor'] = substr($buffer['xor'], strlen($ciphertext)); $plaintext = substr($plaintext, strlen($ciphertext)); } else { $ciphertext = ''; } $block_size = $this->block_size; $len = strlen($plaintext); $key = $this->key; $overflow = $len % $block_size; if (strlen($plaintext)) { if ($overflow) { $ciphertext .= openssl_encrypt(substr($plaintext, 0, -$overflow) . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $encryptIV); $xor = Strings::pop($ciphertext, $block_size); if ($this->continuousBuffer) { $encryptIV = $xor; } $ciphertext .= Strings::shift($xor, $overflow) ^ substr($plaintext, -$overflow); if ($this->continuousBuffer) { $buffer['xor'] = $xor; } } else { $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $encryptIV); if ($this->continuousBuffer) { $encryptIV = substr($ciphertext, -$block_size) ^ substr($plaintext, -$block_size); } } } return $ciphertext; } /** * phpseclib <-> OpenSSL Mode Mapper * * May need to be overwritten by classes extending this one in some cases * * @return string */ protected function openssl_translate_mode() { switch ($this->mode) { case self::MODE_ECB: return 'ecb'; case self::MODE_CBC: return 'cbc'; case self::MODE_CTR: case self::MODE_GCM: return 'ctr'; case self::MODE_CFB: return 'cfb'; case self::MODE_CFB8: return 'cfb8'; case self::MODE_OFB: return 'ofb'; } } /** * Pad "packets". * * Block ciphers working by encrypting between their specified [$this->]block_size at a time * If you ever need to encrypt or decrypt something that isn't of the proper length, it becomes necessary to * pad the input so that it is of the proper length. * * Padding is enabled by default. Sometimes, however, it is undesirable to pad strings. Such is the case in SSH, * where "packets" are padded with random bytes before being encrypted. Unpad these packets and you risk stripping * away characters that shouldn't be stripped away. (SSH knows how many bytes are added because the length is * transmitted separately) * * @see self::disablePadding() */ public function enablePadding() { $this->padding = true; } /** * Do not pad packets. * * @see self::enablePadding() */ public function disablePadding() { $this->padding = false; } /** * Treat consecutive "packets" as if they are a continuous buffer. * * Say you have a 32-byte plaintext $plaintext. Using the default behavior, the two following code snippets * will yield different outputs: * * * echo $rijndael->encrypt(substr($plaintext, 0, 16)); * echo $rijndael->encrypt(substr($plaintext, 16, 16)); * * * echo $rijndael->encrypt($plaintext); * * * The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates * another, as demonstrated with the following: * * * $rijndael->encrypt(substr($plaintext, 0, 16)); * echo $rijndael->decrypt($rijndael->encrypt(substr($plaintext, 16, 16))); * * * echo $rijndael->decrypt($rijndael->encrypt(substr($plaintext, 16, 16))); * * * With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different * outputs. The reason is due to the fact that the initialization vector's change after every encryption / * decryption round when the continuous buffer is enabled. When it's disabled, they remain constant. * * Put another way, when the continuous buffer is enabled, the state of the \phpseclib3\Crypt\*() object changes after each * encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that * continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them), * however, they are also less intuitive and more likely to cause you problems. * * {@internal Could, but not must, extend by the child Crypt_* class} * * @see self::disableContinuousBuffer() */ public function enableContinuousBuffer() { if ($this->mode == self::MODE_ECB) { return; } if ($this->mode == self::MODE_GCM) { throw new \BadMethodCallException('This mode does not run in continuous mode'); } $this->continuousBuffer = true; $this->setEngine(); } /** * Treat consecutive packets as if they are a discontinuous buffer. * * The default behavior. * * {@internal Could, but not must, extend by the child Crypt_* class} * * @see self::enableContinuousBuffer() */ public function disableContinuousBuffer() { if ($this->mode == self::MODE_ECB) { return; } if (!$this->continuousBuffer) { return; } $this->continuousBuffer = false; $this->setEngine(); } /** * Test for engine validity * * @see self::__construct() * @param int $engine * @return bool */ protected function isValidEngineHelper($engine) { switch ($engine) { case self::ENGINE_OPENSSL: $this->openssl_emulate_ctr = false; $result = $this->cipher_name_openssl && extension_loaded('openssl'); if (!$result) { return false; } $methods = openssl_get_cipher_methods(); if (in_array($this->cipher_name_openssl, $methods)) { return true; } // not all of openssl's symmetric cipher's support ctr. for those // that don't we'll emulate it switch ($this->mode) { case self::MODE_CTR: if (in_array($this->cipher_name_openssl_ecb, $methods)) { $this->openssl_emulate_ctr = true; return true; } } return false; case self::ENGINE_MCRYPT: set_error_handler(function () { }); $result = $this->cipher_name_mcrypt && extension_loaded('mcrypt') && in_array($this->cipher_name_mcrypt, mcrypt_list_algorithms()); restore_error_handler(); return $result; case self::ENGINE_EVAL: return method_exists($this, 'setupInlineCrypt'); case self::ENGINE_INTERNAL: return true; } return false; } /** * Test for engine validity * * @see self::__construct() * @param string $engine * @return bool */ public function isValidEngine($engine) { static $reverseMap; if (!isset($reverseMap)) { $reverseMap = array_map('strtolower', self::ENGINE_MAP); $reverseMap = array_flip($reverseMap); } $engine = strtolower($engine); if (!isset($reverseMap[$engine])) { return false; } return $this->isValidEngineHelper($reverseMap[$engine]); } /** * Sets the preferred crypt engine * * Currently, $engine could be: * * - libsodium[very fast] * * - OpenSSL [very fast] * * - mcrypt [fast] * * - Eval [slow] * * - PHP [slowest] * * If the preferred crypt engine is not available the fastest available one will be used * * @see self::__construct() * @param string $engine */ public function setPreferredEngine($engine) { static $reverseMap; if (!isset($reverseMap)) { $reverseMap = array_map('strtolower', self::ENGINE_MAP); $reverseMap = array_flip($reverseMap); } $engine = is_string($engine) ? strtolower($engine) : ''; $this->preferredEngine = isset($reverseMap[$engine]) ? $reverseMap[$engine] : self::ENGINE_LIBSODIUM; $this->setEngine(); } /** * Returns the engine currently being utilized * * @see self::setEngine() */ public function getEngine() { return self::ENGINE_MAP[$this->engine]; } /** * Sets the engine as appropriate * * @see self::__construct() */ protected function setEngine() { $this->engine = null; $candidateEngines = [ self::ENGINE_LIBSODIUM, self::ENGINE_OPENSSL_GCM, self::ENGINE_OPENSSL, self::ENGINE_MCRYPT, self::ENGINE_EVAL ]; if (isset($this->preferredEngine)) { $temp = [$this->preferredEngine]; $candidateEngines = array_merge( $temp, array_diff($candidateEngines, $temp) ); } foreach ($candidateEngines as $engine) { if ($this->isValidEngineHelper($engine)) { $this->engine = $engine; break; } } if (!$this->engine) { $this->engine = self::ENGINE_INTERNAL; } if ($this->engine != self::ENGINE_MCRYPT && $this->enmcrypt) { set_error_handler(function () { }); // Closing the current mcrypt resource(s). _mcryptSetup() will, if needed, // (re)open them with the module named in $this->cipher_name_mcrypt mcrypt_module_close($this->enmcrypt); mcrypt_module_close($this->demcrypt); $this->enmcrypt = null; $this->demcrypt = null; if ($this->ecb) { mcrypt_module_close($this->ecb); $this->ecb = null; } restore_error_handler(); } $this->changed = $this->nonIVChanged = true; } /** * Encrypts a block * * Note: Must be extended by the child \phpseclib3\Crypt\* class * * @param string $in * @return string */ abstract protected function encryptBlock($in); /** * Decrypts a block * * Note: Must be extended by the child \phpseclib3\Crypt\* class * * @param string $in * @return string */ abstract protected function decryptBlock($in); /** * Setup the key (expansion) * * Only used if $engine == self::ENGINE_INTERNAL * * Note: Must extend by the child \phpseclib3\Crypt\* class * * @see self::setup() */ abstract protected function setupKey(); /** * Setup the self::ENGINE_INTERNAL $engine * * (re)init, if necessary, the internal cipher $engine and flush all $buffers * Used (only) if $engine == self::ENGINE_INTERNAL * * _setup() will be called each time if $changed === true * typically this happens when using one or more of following public methods: * * - setKey() * * - setIV() * * - disableContinuousBuffer() * * - First run of encrypt() / decrypt() with no init-settings * * {@internal setup() is always called before en/decryption.} * * {@internal Could, but not must, extend by the child Crypt_* class} * * @see self::setKey() * @see self::setIV() * @see self::disableContinuousBuffer() */ protected function setup() { if (!$this->changed) { return; } $this->changed = false; if ($this->usePoly1305 && !isset($this->poly1305Key) && method_exists($this, 'createPoly1305Key')) { $this->createPoly1305Key(); } $this->enbuffer = $this->debuffer = ['ciphertext' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true]; //$this->newtag = $this->oldtag = false; if ($this->usesNonce()) { if ($this->nonce === false) { throw new InsufficientSetupException('No nonce has been defined'); } if ($this->mode == self::MODE_GCM && !in_array($this->engine, [self::ENGINE_LIBSODIUM, self::ENGINE_OPENSSL_GCM])) { $this->setupGCM(); } } else { $this->iv = $this->origIV; } if ($this->iv === false && !in_array($this->mode, [self::MODE_STREAM, self::MODE_ECB])) { if ($this->mode != self::MODE_GCM || !in_array($this->engine, [self::ENGINE_LIBSODIUM, self::ENGINE_OPENSSL_GCM])) { throw new InsufficientSetupException('No IV has been defined'); } } if ($this->key === false) { throw new InsufficientSetupException('No key has been defined'); } $this->encryptIV = $this->decryptIV = $this->iv; switch ($this->engine) { case self::ENGINE_MCRYPT: $this->enchanged = $this->dechanged = true; set_error_handler(function () { }); if (!isset($this->enmcrypt)) { static $mcrypt_modes = [ self::MODE_CTR => 'ctr', self::MODE_ECB => MCRYPT_MODE_ECB, self::MODE_CBC => MCRYPT_MODE_CBC, self::MODE_CFB => 'ncfb', self::MODE_CFB8 => MCRYPT_MODE_CFB, self::MODE_OFB => MCRYPT_MODE_NOFB, self::MODE_OFB8 => MCRYPT_MODE_OFB, self::MODE_STREAM => MCRYPT_MODE_STREAM, ]; $this->demcrypt = mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], ''); $this->enmcrypt = mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], ''); // we need the $ecb mcrypt resource (only) in MODE_CFB with enableContinuousBuffer() // to workaround mcrypt's broken ncfb implementation in buffered mode // see: {@link http://phpseclib.sourceforge.net/cfb-demo.phps} if ($this->mode == self::MODE_CFB) { $this->ecb = mcrypt_module_open($this->cipher_name_mcrypt, '', MCRYPT_MODE_ECB, ''); } } // else should mcrypt_generic_deinit be called? if ($this->mode == self::MODE_CFB) { mcrypt_generic_init($this->ecb, $this->key, str_repeat("\0", $this->block_size)); } restore_error_handler(); break; case self::ENGINE_INTERNAL: $this->setupKey(); break; case self::ENGINE_EVAL: if ($this->nonIVChanged) { $this->setupKey(); $this->setupInlineCrypt(); } } $this->nonIVChanged = false; } /** * Pads a string * * Pads a string using the RSA PKCS padding standards so that its length is a multiple of the blocksize. * $this->block_size - (strlen($text) % $this->block_size) bytes are added, each of which is equal to * chr($this->block_size - (strlen($text) % $this->block_size) * * If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless * and padding will, hence forth, be enabled. * * @see self::unpad() * @param string $text * @throws \LengthException if padding is disabled and the plaintext's length is not a multiple of the block size * @return string */ protected function pad($text) { $length = strlen($text); if (!$this->padding) { if ($length % $this->block_size == 0) { return $text; } else { throw new \LengthException("The plaintext's length ($length) is not a multiple of the block size ({$this->block_size}). Try enabling padding."); } } $pad = $this->block_size - ($length % $this->block_size); return str_pad($text, $length + $pad, chr($pad)); } /** * Unpads a string. * * If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong * and false will be returned. * * @see self::pad() * @param string $text * @throws \LengthException if the ciphertext's length is not a multiple of the block size * @return string */ protected function unpad($text) { if (!$this->padding) { return $text; } $length = ord($text[strlen($text) - 1]); if (!$length || $length > $this->block_size) { throw new BadDecryptionException("The ciphertext has an invalid padding length ($length) compared to the block size ({$this->block_size})"); } return substr($text, 0, -$length); } /** * Setup the performance-optimized function for de/encrypt() * * Stores the created (or existing) callback function-name * in $this->inline_crypt * * Internally for phpseclib developers: * * _setupInlineCrypt() would be called only if: * * - $this->engine === self::ENGINE_EVAL * * - each time on _setup(), after(!) _setupKey() * * * This ensures that _setupInlineCrypt() has always a * full ready2go initializated internal cipher $engine state * where, for example, the keys already expanded, * keys/block_size calculated and such. * * It is, each time if called, the responsibility of _setupInlineCrypt(): * * - to set $this->inline_crypt to a valid and fully working callback function * as a (faster) replacement for encrypt() / decrypt() * * - NOT to create unlimited callback functions (for memory reasons!) * no matter how often _setupInlineCrypt() would be called. At some * point of amount they must be generic re-useable. * * - the code of _setupInlineCrypt() it self, * and the generated callback code, * must be, in following order: * - 100% safe * - 100% compatible to encrypt()/decrypt() * - using only php5+ features/lang-constructs/php-extensions if * compatibility (down to php4) or fallback is provided * - readable/maintainable/understandable/commented and... not-cryptic-styled-code :-) * - >= 10% faster than encrypt()/decrypt() [which is, by the way, * the reason for the existence of _setupInlineCrypt() :-)] * - memory-nice * - short (as good as possible) * * Note: - _setupInlineCrypt() is using _createInlineCryptFunction() to create the full callback function code. * - In case of using inline crypting, _setupInlineCrypt() must extend by the child \phpseclib3\Crypt\* class. * - The following variable names are reserved: * - $_* (all variable names prefixed with an underscore) * - $self (object reference to it self. Do not use $this, but $self instead) * - $in (the content of $in has to en/decrypt by the generated code) * - The callback function should not use the 'return' statement, but en/decrypt'ing the content of $in only * * {@internal If a Crypt_* class providing inline crypting it must extend _setupInlineCrypt()} * * @see self::setup() * @see self::createInlineCryptFunction() * @see self::encrypt() * @see self::decrypt() */ //protected function setupInlineCrypt(); /** * Creates the performance-optimized function for en/decrypt() * * Internally for phpseclib developers: * * _createInlineCryptFunction(): * * - merge the $cipher_code [setup'ed by _setupInlineCrypt()] * with the current [$this->]mode of operation code * * - create the $inline function, which called by encrypt() / decrypt() * as its replacement to speed up the en/decryption operations. * * - return the name of the created $inline callback function * * - used to speed up en/decryption * * * * The main reason why can speed up things [up to 50%] this way are: * * - using variables more effective then regular. * (ie no use of expensive arrays but integers $k_0, $k_1 ... * or even, for example, the pure $key[] values hardcoded) * * - avoiding 1000's of function calls of ie _encryptBlock() * but inlining the crypt operations. * in the mode of operation for() loop. * * - full loop unroll the (sometimes key-dependent) rounds * avoiding this way ++$i counters and runtime-if's etc... * * The basic code architectur of the generated $inline en/decrypt() * lambda function, in pseudo php, is: * * * +----------------------------------------------------------------------------------------------+ * | callback $inline = create_function: | * | lambda_function_0001_crypt_ECB($action, $text) | * | { | * | INSERT PHP CODE OF: | * | $cipher_code['init_crypt']; // general init code. | * | // ie: $sbox'es declarations used for | * | // encrypt and decrypt'ing. | * | | * | switch ($action) { | * | case 'encrypt': | * | INSERT PHP CODE OF: | * | $cipher_code['init_encrypt']; // encrypt sepcific init code. | * | ie: specified $key or $box | * | declarations for encrypt'ing. | * | | * | foreach ($ciphertext) { | * | $in = $block_size of $ciphertext; | * | | * | INSERT PHP CODE OF: | * | $cipher_code['encrypt_block']; // encrypt's (string) $in, which is always: | * | // strlen($in) == $this->block_size | * | // here comes the cipher algorithm in action | * | // for encryption. | * | // $cipher_code['encrypt_block'] has to | * | // encrypt the content of the $in variable | * | | * | $plaintext .= $in; | * | } | * | return $plaintext; | * | | * | case 'decrypt': | * | INSERT PHP CODE OF: | * | $cipher_code['init_decrypt']; // decrypt sepcific init code | * | ie: specified $key or $box | * | declarations for decrypt'ing. | * | foreach ($plaintext) { | * | $in = $block_size of $plaintext; | * | | * | INSERT PHP CODE OF: | * | $cipher_code['decrypt_block']; // decrypt's (string) $in, which is always | * | // strlen($in) == $this->block_size | * | // here comes the cipher algorithm in action | * | // for decryption. | * | // $cipher_code['decrypt_block'] has to | * | // decrypt the content of the $in variable | * | $ciphertext .= $in; | * | } | * | return $ciphertext; | * | } | * | } | * +----------------------------------------------------------------------------------------------+ * * * See also the \phpseclib3\Crypt\*::_setupInlineCrypt()'s for * productive inline $cipher_code's how they works. * * Structure of: * * $cipher_code = [ * 'init_crypt' => (string) '', // optional * 'init_encrypt' => (string) '', // optional * 'init_decrypt' => (string) '', // optional * 'encrypt_block' => (string) '', // required * 'decrypt_block' => (string) '' // required * ]; * * * @see self::setupInlineCrypt() * @see self::encrypt() * @see self::decrypt() * @param array $cipher_code * @return string (the name of the created callback function) */ protected function createInlineCryptFunction($cipher_code) { $block_size = $this->block_size; // optional $init_crypt = isset($cipher_code['init_crypt']) ? $cipher_code['init_crypt'] : ''; $init_encrypt = isset($cipher_code['init_encrypt']) ? $cipher_code['init_encrypt'] : ''; $init_decrypt = isset($cipher_code['init_decrypt']) ? $cipher_code['init_decrypt'] : ''; // required $encrypt_block = $cipher_code['encrypt_block']; $decrypt_block = $cipher_code['decrypt_block']; // Generating mode of operation inline code, // merged with the $cipher_code algorithm // for encrypt- and decryption. switch ($this->mode) { case self::MODE_ECB: $encrypt = $init_encrypt . ' $_ciphertext = ""; $_plaintext_len = strlen($_text); for ($_i = 0; $_i < $_plaintext_len; $_i+= ' . $block_size . ') { $in = substr($_text, $_i, ' . $block_size . '); ' . $encrypt_block . ' $_ciphertext.= $in; } return $_ciphertext; '; $decrypt = $init_decrypt . ' $_plaintext = ""; $_text = str_pad($_text, strlen($_text) + (' . $block_size . ' - strlen($_text) % ' . $block_size . ') % ' . $block_size . ', chr(0)); $_ciphertext_len = strlen($_text); for ($_i = 0; $_i < $_ciphertext_len; $_i+= ' . $block_size . ') { $in = substr($_text, $_i, ' . $block_size . '); ' . $decrypt_block . ' $_plaintext.= $in; } return $this->unpad($_plaintext); '; break; case self::MODE_CTR: $encrypt = $init_encrypt . ' $_ciphertext = ""; $_plaintext_len = strlen($_text); $_xor = $this->encryptIV; $_buffer = &$this->enbuffer; if (strlen($_buffer["ciphertext"])) { for ($_i = 0; $_i < $_plaintext_len; $_i+= ' . $block_size . ') { $_block = substr($_text, $_i, ' . $block_size . '); if (strlen($_block) > strlen($_buffer["ciphertext"])) { $in = $_xor; ' . $encrypt_block . ' \phpseclib3\Common\Functions\Strings::increment_str($_xor); $_buffer["ciphertext"].= $in; } $_key = \phpseclib3\Common\Functions\Strings::shift($_buffer["ciphertext"], ' . $block_size . '); $_ciphertext.= $_block ^ $_key; } } else { for ($_i = 0; $_i < $_plaintext_len; $_i+= ' . $block_size . ') { $_block = substr($_text, $_i, ' . $block_size . '); $in = $_xor; ' . $encrypt_block . ' \phpseclib3\Common\Functions\Strings::increment_str($_xor); $_key = $in; $_ciphertext.= $_block ^ $_key; } } if ($this->continuousBuffer) { $this->encryptIV = $_xor; if ($_start = $_plaintext_len % ' . $block_size . ') { $_buffer["ciphertext"] = substr($_key, $_start) . $_buffer["ciphertext"]; } } return $_ciphertext; '; $decrypt = $init_encrypt . ' $_plaintext = ""; $_ciphertext_len = strlen($_text); $_xor = $this->decryptIV; $_buffer = &$this->debuffer; if (strlen($_buffer["ciphertext"])) { for ($_i = 0; $_i < $_ciphertext_len; $_i+= ' . $block_size . ') { $_block = substr($_text, $_i, ' . $block_size . '); if (strlen($_block) > strlen($_buffer["ciphertext"])) { $in = $_xor; ' . $encrypt_block . ' \phpseclib3\Common\Functions\Strings::increment_str($_xor); $_buffer["ciphertext"].= $in; } $_key = \phpseclib3\Common\Functions\Strings::shift($_buffer["ciphertext"], ' . $block_size . '); $_plaintext.= $_block ^ $_key; } } else { for ($_i = 0; $_i < $_ciphertext_len; $_i+= ' . $block_size . ') { $_block = substr($_text, $_i, ' . $block_size . '); $in = $_xor; ' . $encrypt_block . ' \phpseclib3\Common\Functions\Strings::increment_str($_xor); $_key = $in; $_plaintext.= $_block ^ $_key; } } if ($this->continuousBuffer) { $this->decryptIV = $_xor; if ($_start = $_ciphertext_len % ' . $block_size . ') { $_buffer["ciphertext"] = substr($_key, $_start) . $_buffer["ciphertext"]; } } return $_plaintext; '; break; case self::MODE_CFB: $encrypt = $init_encrypt . ' $_ciphertext = ""; $_buffer = &$this->enbuffer; if ($this->continuousBuffer) { $_iv = &$this->encryptIV; $_pos = &$_buffer["pos"]; } else { $_iv = $this->encryptIV; $_pos = 0; } $_len = strlen($_text); $_i = 0; if ($_pos) { $_orig_pos = $_pos; $_max = ' . $block_size . ' - $_pos; if ($_len >= $_max) { $_i = $_max; $_len-= $_max; $_pos = 0; } else { $_i = $_len; $_pos+= $_len; $_len = 0; } $_ciphertext = substr($_iv, $_orig_pos) ^ $_text; $_iv = substr_replace($_iv, $_ciphertext, $_orig_pos, $_i); } while ($_len >= ' . $block_size . ') { $in = $_iv; ' . $encrypt_block . '; $_iv = $in ^ substr($_text, $_i, ' . $block_size . '); $_ciphertext.= $_iv; $_len-= ' . $block_size . '; $_i+= ' . $block_size . '; } if ($_len) { $in = $_iv; ' . $encrypt_block . ' $_iv = $in; $_block = $_iv ^ substr($_text, $_i); $_iv = substr_replace($_iv, $_block, 0, $_len); $_ciphertext.= $_block; $_pos = $_len; } return $_ciphertext; '; $decrypt = $init_encrypt . ' $_plaintext = ""; $_buffer = &$this->debuffer; if ($this->continuousBuffer) { $_iv = &$this->decryptIV; $_pos = &$_buffer["pos"]; } else { $_iv = $this->decryptIV; $_pos = 0; } $_len = strlen($_text); $_i = 0; if ($_pos) { $_orig_pos = $_pos; $_max = ' . $block_size . ' - $_pos; if ($_len >= $_max) { $_i = $_max; $_len-= $_max; $_pos = 0; } else { $_i = $_len; $_pos+= $_len; $_len = 0; } $_plaintext = substr($_iv, $_orig_pos) ^ $_text; $_iv = substr_replace($_iv, substr($_text, 0, $_i), $_orig_pos, $_i); } while ($_len >= ' . $block_size . ') { $in = $_iv; ' . $encrypt_block . ' $_iv = $in; $cb = substr($_text, $_i, ' . $block_size . '); $_plaintext.= $_iv ^ $cb; $_iv = $cb; $_len-= ' . $block_size . '; $_i+= ' . $block_size . '; } if ($_len) { $in = $_iv; ' . $encrypt_block . ' $_iv = $in; $_plaintext.= $_iv ^ substr($_text, $_i); $_iv = substr_replace($_iv, substr($_text, $_i), 0, $_len); $_pos = $_len; } return $_plaintext; '; break; case self::MODE_CFB8: $encrypt = $init_encrypt . ' $_ciphertext = ""; $_len = strlen($_text); $_iv = $this->encryptIV; for ($_i = 0; $_i < $_len; ++$_i) { $in = $_iv; ' . $encrypt_block . ' $_ciphertext .= ($_c = $_text[$_i] ^ $in); $_iv = substr($_iv, 1) . $_c; } if ($this->continuousBuffer) { if ($_len >= ' . $block_size . ') { $this->encryptIV = substr($_ciphertext, -' . $block_size . '); } else { $this->encryptIV = substr($this->encryptIV, $_len - ' . $block_size . ') . substr($_ciphertext, -$_len); } } return $_ciphertext; '; $decrypt = $init_encrypt . ' $_plaintext = ""; $_len = strlen($_text); $_iv = $this->decryptIV; for ($_i = 0; $_i < $_len; ++$_i) { $in = $_iv; ' . $encrypt_block . ' $_plaintext .= $_text[$_i] ^ $in; $_iv = substr($_iv, 1) . $_text[$_i]; } if ($this->continuousBuffer) { if ($_len >= ' . $block_size . ') { $this->decryptIV = substr($_text, -' . $block_size . '); } else { $this->decryptIV = substr($this->decryptIV, $_len - ' . $block_size . ') . substr($_text, -$_len); } } return $_plaintext; '; break; case self::MODE_OFB8: $encrypt = $init_encrypt . ' $_ciphertext = ""; $_len = strlen($_text); $_iv = $this->encryptIV; for ($_i = 0; $_i < $_len; ++$_i) { $in = $_iv; ' . $encrypt_block . ' $_ciphertext.= $_text[$_i] ^ $in; $_iv = substr($_iv, 1) . $in[0]; } if ($this->continuousBuffer) { $this->encryptIV = $_iv; } return $_ciphertext; '; $decrypt = $init_encrypt . ' $_plaintext = ""; $_len = strlen($_text); $_iv = $this->decryptIV; for ($_i = 0; $_i < $_len; ++$_i) { $in = $_iv; ' . $encrypt_block . ' $_plaintext.= $_text[$_i] ^ $in; $_iv = substr($_iv, 1) . $in[0]; } if ($this->continuousBuffer) { $this->decryptIV = $_iv; } return $_plaintext; '; break; case self::MODE_OFB: $encrypt = $init_encrypt . ' $_ciphertext = ""; $_plaintext_len = strlen($_text); $_xor = $this->encryptIV; $_buffer = &$this->enbuffer; if (strlen($_buffer["xor"])) { for ($_i = 0; $_i < $_plaintext_len; $_i+= ' . $block_size . ') { $_block = substr($_text, $_i, ' . $block_size . '); if (strlen($_block) > strlen($_buffer["xor"])) { $in = $_xor; ' . $encrypt_block . ' $_xor = $in; $_buffer["xor"].= $_xor; } $_key = \phpseclib3\Common\Functions\Strings::shift($_buffer["xor"], ' . $block_size . '); $_ciphertext.= $_block ^ $_key; } } else { for ($_i = 0; $_i < $_plaintext_len; $_i+= ' . $block_size . ') { $in = $_xor; ' . $encrypt_block . ' $_xor = $in; $_ciphertext.= substr($_text, $_i, ' . $block_size . ') ^ $_xor; } $_key = $_xor; } if ($this->continuousBuffer) { $this->encryptIV = $_xor; if ($_start = $_plaintext_len % ' . $block_size . ') { $_buffer["xor"] = substr($_key, $_start) . $_buffer["xor"]; } } return $_ciphertext; '; $decrypt = $init_encrypt . ' $_plaintext = ""; $_ciphertext_len = strlen($_text); $_xor = $this->decryptIV; $_buffer = &$this->debuffer; if (strlen($_buffer["xor"])) { for ($_i = 0; $_i < $_ciphertext_len; $_i+= ' . $block_size . ') { $_block = substr($_text, $_i, ' . $block_size . '); if (strlen($_block) > strlen($_buffer["xor"])) { $in = $_xor; ' . $encrypt_block . ' $_xor = $in; $_buffer["xor"].= $_xor; } $_key = \phpseclib3\Common\Functions\Strings::shift($_buffer["xor"], ' . $block_size . '); $_plaintext.= $_block ^ $_key; } } else { for ($_i = 0; $_i < $_ciphertext_len; $_i+= ' . $block_size . ') { $in = $_xor; ' . $encrypt_block . ' $_xor = $in; $_plaintext.= substr($_text, $_i, ' . $block_size . ') ^ $_xor; } $_key = $_xor; } if ($this->continuousBuffer) { $this->decryptIV = $_xor; if ($_start = $_ciphertext_len % ' . $block_size . ') { $_buffer["xor"] = substr($_key, $_start) . $_buffer["xor"]; } } return $_plaintext; '; break; case self::MODE_STREAM: $encrypt = $init_encrypt . ' $_ciphertext = ""; ' . $encrypt_block . ' return $_ciphertext; '; $decrypt = $init_decrypt . ' $_plaintext = ""; ' . $decrypt_block . ' return $_plaintext; '; break; // case self::MODE_CBC: default: $encrypt = $init_encrypt . ' $_ciphertext = ""; $_plaintext_len = strlen($_text); $in = $this->encryptIV; for ($_i = 0; $_i < $_plaintext_len; $_i+= ' . $block_size . ') { $in = substr($_text, $_i, ' . $block_size . ') ^ $in; ' . $encrypt_block . ' $_ciphertext.= $in; } if ($this->continuousBuffer) { $this->encryptIV = $in; } return $_ciphertext; '; $decrypt = $init_decrypt . ' $_plaintext = ""; $_text = str_pad($_text, strlen($_text) + (' . $block_size . ' - strlen($_text) % ' . $block_size . ') % ' . $block_size . ', chr(0)); $_ciphertext_len = strlen($_text); $_iv = $this->decryptIV; for ($_i = 0; $_i < $_ciphertext_len; $_i+= ' . $block_size . ') { $in = $_block = substr($_text, $_i, ' . $block_size . '); ' . $decrypt_block . ' $_plaintext.= $in ^ $_iv; $_iv = $_block; } if ($this->continuousBuffer) { $this->decryptIV = $_iv; } return $this->unpad($_plaintext); '; break; } // Before discrediting this, please read the following: // @see https://github.com/phpseclib/phpseclib/issues/1293 // @see https://github.com/phpseclib/phpseclib/pull/1143 eval('$func = function ($_action, $_text) { ' . $init_crypt . 'if ($_action == "encrypt") { ' . $encrypt . ' } else { ' . $decrypt . ' }};'); return \Closure::bind($func, $this, static::class); } /** * Convert float to int * * On ARM CPUs converting floats to ints doesn't always work * * @param string $x * @return int */ protected static function safe_intval($x) { if (is_int($x)) { return $x; } if (self::$use_reg_intval) { return PHP_INT_SIZE == 4 && PHP_VERSION_ID >= 80100 ? intval($x) : $x; } return (fmod($x, 0x80000000) & 0x7FFFFFFF) | ((fmod(floor($x / 0x80000000), 2) & 1) << 31); } /** * eval()'able string for in-line float to int * * @return string */ protected static function safe_intval_inline() { if (self::$use_reg_intval) { return PHP_INT_SIZE == 4 && PHP_VERSION_ID >= 80100 ? 'intval(%s)' : '%s'; } $safeint = '(is_int($temp = %s) ? $temp : (fmod($temp, 0x80000000) & 0x7FFFFFFF) | '; return $safeint . '((fmod(floor($temp / 0x80000000), 2) & 1) << 31))'; } /** * Sets up GCM parameters * * See steps 1-2 of https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf#page=23 * for more info * */ private function setupGCM() { // don't keep on re-calculating $this->h if (!$this->h || $this->hKey != $this->key) { $cipher = new static('ecb'); $cipher->setKey($this->key); $cipher->disablePadding(); $this->h = self::$gcmField->newInteger( Strings::switchEndianness($cipher->encrypt("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0")) ); $this->hKey = $this->key; } if (strlen($this->nonce) == 12) { $this->iv = $this->nonce . "\0\0\0\1"; } else { $this->iv = $this->ghash( self::nullPad128($this->nonce) . str_repeat("\0", 8) . self::len64($this->nonce) ); } } /** * Performs GHASH operation * * See https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf#page=20 * for more info * * @see self::decrypt() * @see self::encrypt() * @param string $x * @return string */ private function ghash($x) { $h = $this->h; $y = ["\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"]; $x = str_split($x, 16); $n = 0; // the switchEndianness calls are necessary because the multiplication algorithm in BinaryField/Integer // interprets strings as polynomials in big endian order whereas in GCM they're interpreted in little // endian order per https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf#page=19. // big endian order is what binary field elliptic curves use per http://www.secg.org/sec1-v2.pdf#page=18. // we could switchEndianness here instead of in the while loop but doing so in the while loop seems like it // might be slightly more performant //$x = Strings::switchEndianness($x); foreach ($x as $xn) { $xn = Strings::switchEndianness($xn); $t = $y[$n] ^ $xn; $temp = self::$gcmField->newInteger($t); $y[++$n] = $temp->multiply($h)->toBytes(); $y[$n] = substr($y[$n], 1); } $y[$n] = Strings::switchEndianness($y[$n]); return $y[$n]; } /** * Returns the bit length of a string in a packed format * * @see self::decrypt() * @see self::encrypt() * @see self::setupGCM() * @param string $str * @return string */ private static function len64($str) { return "\0\0\0\0" . pack('N', 8 * strlen($str)); } /** * NULL pads a string to be a multiple of 128 * * @see self::decrypt() * @see self::encrypt() * @see self::setupGCM() * @param string $str * @return string */ protected static function nullPad128($str) { $len = strlen($str); return $str . str_repeat("\0", 16 * ceil($len / 16) - $len); } /** * Calculates Poly1305 MAC * * On my system ChaCha20, with libsodium, takes 0.5s. With this custom Poly1305 implementation * it takes 1.2s. * * @see self::decrypt() * @see self::encrypt() * @param string $text * @return string */ protected function poly1305($text) { $s = $this->poly1305Key; // strlen($this->poly1305Key) == 32 $r = Strings::shift($s, 16); $r = strrev($r); $r &= "\x0f\xff\xff\xfc\x0f\xff\xff\xfc\x0f\xff\xff\xfc\x0f\xff\xff\xff"; $s = strrev($s); $r = self::$poly1305Field->newInteger(new BigInteger($r, 256)); $s = self::$poly1305Field->newInteger(new BigInteger($s, 256)); $a = self::$poly1305Field->newInteger(new BigInteger()); $blocks = str_split($text, 16); foreach ($blocks as $block) { $n = strrev($block . chr(1)); $n = self::$poly1305Field->newInteger(new BigInteger($n, 256)); $a = $a->add($n); $a = $a->multiply($r); } $r = $a->toBigInteger()->add($s->toBigInteger()); $mask = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"; return strrev($r->toBytes()) & $mask; } /** * Return the mode * * You can do $obj instanceof AES or whatever to get the cipher but you can't do that to get the mode * * @return string */ public function getMode() { return array_flip(self::MODE_MAP)[$this->mode]; } /** * Is the continuous buffer enabled? * * @return boolean */ public function continuousBufferEnabled() { return $this->continuousBuffer; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/Fingerprint.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\Common\Traits; use phpseclib3\Crypt\Hash; /** * Fingerprint Trait for Private Keys * * @author Jim Wigginton */ trait Fingerprint { /** * Returns the public key's fingerprint * * The public key's fingerprint is returned, which is equivalent to running `ssh-keygen -lf rsa.pub`. If there is * no public key currently loaded, false is returned. * Example output (md5): "c1:b1:30:29:d7:b8:de:6c:97:77:10:d7:46:41:63:87" (as specified by RFC 4716) * * @param string $algorithm The hashing algorithm to be used. Valid options are 'md5' and 'sha256'. False is returned * for invalid values. * @return mixed */ public function getFingerprint($algorithm = 'md5') { $type = self::validatePlugin('Keys', 'OpenSSH', 'savePublicKey'); if ($type === false) { return false; } $key = $this->toString('OpenSSH', ['binary' => true]); if ($key === false) { return false; } switch ($algorithm) { case 'sha256': $hash = new Hash('sha256'); $base = base64_encode($hash->hash($key)); return substr($base, 0, strlen($base) - 1); case 'md5': return substr(chunk_split(md5($key), 2, ':'), 0, -1); default: return false; } } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/PasswordProtected.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\Common\Traits; /** * Password Protected Trait for Private Keys * * @author Jim Wigginton */ trait PasswordProtected { /** * Password * * @var string|bool */ private $password = false; /** * Sets the password * * Private keys can be encrypted with a password. To unset the password, pass in the empty string or false. * Or rather, pass in $password such that empty($password) && !is_string($password) is true. * * @see self::createKey() * @see self::load() * @param string|bool $password */ public function withPassword($password = false) { $new = clone $this; $new->password = $password; return $new; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php ================================================ * setKey('abcdefgh'); * * $size = 10 * 1024; * $plaintext = ''; * for ($i = 0; $i < $size; $i++) { * $plaintext.= 'a'; * } * * echo $des->decrypt($des->encrypt($plaintext)); * ?> * * * @author Jim Wigginton * @copyright 2007 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt; use phpseclib3\Crypt\Common\BlockCipher; use phpseclib3\Exception\BadModeException; /** * Pure-PHP implementation of DES. * * @author Jim Wigginton */ class DES extends BlockCipher { /** * Contains $keys[self::ENCRYPT] * * @see \phpseclib3\Crypt\DES::setupKey() * @see \phpseclib3\Crypt\DES::processBlock() */ const ENCRYPT = 0; /** * Contains $keys[self::DECRYPT] * * @see \phpseclib3\Crypt\DES::setupKey() * @see \phpseclib3\Crypt\DES::processBlock() */ const DECRYPT = 1; /** * Block Length of the cipher * * @see Common\SymmetricKey::block_size * @var int */ protected $block_size = 8; /** * Key Length (in bytes) * * @see Common\SymmetricKey::setKeyLength() * @var int */ protected $key_length = 8; /** * The mcrypt specific name of the cipher * * @see Common\SymmetricKey::cipher_name_mcrypt * @var string */ protected $cipher_name_mcrypt = 'des'; /** * The OpenSSL names of the cipher / modes * * @see Common\SymmetricKey::openssl_mode_names * @var array */ protected $openssl_mode_names = [ self::MODE_ECB => 'des-ecb', self::MODE_CBC => 'des-cbc', self::MODE_CFB => 'des-cfb', self::MODE_OFB => 'des-ofb' // self::MODE_CTR is undefined for DES ]; /** * Optimizing value while CFB-encrypting * * @see Common\SymmetricKey::cfb_init_len * @var int */ protected $cfb_init_len = 500; /** * Switch for DES/3DES encryption * * Used only if $engine == self::ENGINE_INTERNAL * * @see self::setupKey() * @see self::processBlock() * @var int */ protected $des_rounds = 1; /** * max possible size of $key * * @see self::setKey() * @var string */ protected $key_length_max = 8; /** * The Key Schedule * * @see self::setupKey() * @var array */ private $keys; /** * Key Cache "key" * * @see self::setupKey() * @var array */ private $kl; /** * Shuffle table. * * For each byte value index, the entry holds an 8-byte string * with each byte containing all bits in the same state as the * corresponding bit in the index value. * * @see self::processBlock() * @see self::setupKey() * @var array */ protected static $shuffle = [ "\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\xFF", "\x00\x00\x00\x00\x00\x00\xFF\x00", "\x00\x00\x00\x00\x00\x00\xFF\xFF", "\x00\x00\x00\x00\x00\xFF\x00\x00", "\x00\x00\x00\x00\x00\xFF\x00\xFF", "\x00\x00\x00\x00\x00\xFF\xFF\x00", "\x00\x00\x00\x00\x00\xFF\xFF\xFF", "\x00\x00\x00\x00\xFF\x00\x00\x00", "\x00\x00\x00\x00\xFF\x00\x00\xFF", "\x00\x00\x00\x00\xFF\x00\xFF\x00", "\x00\x00\x00\x00\xFF\x00\xFF\xFF", "\x00\x00\x00\x00\xFF\xFF\x00\x00", "\x00\x00\x00\x00\xFF\xFF\x00\xFF", "\x00\x00\x00\x00\xFF\xFF\xFF\x00", "\x00\x00\x00\x00\xFF\xFF\xFF\xFF", "\x00\x00\x00\xFF\x00\x00\x00\x00", "\x00\x00\x00\xFF\x00\x00\x00\xFF", "\x00\x00\x00\xFF\x00\x00\xFF\x00", "\x00\x00\x00\xFF\x00\x00\xFF\xFF", "\x00\x00\x00\xFF\x00\xFF\x00\x00", "\x00\x00\x00\xFF\x00\xFF\x00\xFF", "\x00\x00\x00\xFF\x00\xFF\xFF\x00", "\x00\x00\x00\xFF\x00\xFF\xFF\xFF", "\x00\x00\x00\xFF\xFF\x00\x00\x00", "\x00\x00\x00\xFF\xFF\x00\x00\xFF", "\x00\x00\x00\xFF\xFF\x00\xFF\x00", "\x00\x00\x00\xFF\xFF\x00\xFF\xFF", "\x00\x00\x00\xFF\xFF\xFF\x00\x00", "\x00\x00\x00\xFF\xFF\xFF\x00\xFF", "\x00\x00\x00\xFF\xFF\xFF\xFF\x00", "\x00\x00\x00\xFF\xFF\xFF\xFF\xFF", "\x00\x00\xFF\x00\x00\x00\x00\x00", "\x00\x00\xFF\x00\x00\x00\x00\xFF", "\x00\x00\xFF\x00\x00\x00\xFF\x00", "\x00\x00\xFF\x00\x00\x00\xFF\xFF", "\x00\x00\xFF\x00\x00\xFF\x00\x00", "\x00\x00\xFF\x00\x00\xFF\x00\xFF", "\x00\x00\xFF\x00\x00\xFF\xFF\x00", "\x00\x00\xFF\x00\x00\xFF\xFF\xFF", "\x00\x00\xFF\x00\xFF\x00\x00\x00", "\x00\x00\xFF\x00\xFF\x00\x00\xFF", "\x00\x00\xFF\x00\xFF\x00\xFF\x00", "\x00\x00\xFF\x00\xFF\x00\xFF\xFF", "\x00\x00\xFF\x00\xFF\xFF\x00\x00", "\x00\x00\xFF\x00\xFF\xFF\x00\xFF", "\x00\x00\xFF\x00\xFF\xFF\xFF\x00", "\x00\x00\xFF\x00\xFF\xFF\xFF\xFF", "\x00\x00\xFF\xFF\x00\x00\x00\x00", "\x00\x00\xFF\xFF\x00\x00\x00\xFF", "\x00\x00\xFF\xFF\x00\x00\xFF\x00", "\x00\x00\xFF\xFF\x00\x00\xFF\xFF", "\x00\x00\xFF\xFF\x00\xFF\x00\x00", "\x00\x00\xFF\xFF\x00\xFF\x00\xFF", "\x00\x00\xFF\xFF\x00\xFF\xFF\x00", "\x00\x00\xFF\xFF\x00\xFF\xFF\xFF", "\x00\x00\xFF\xFF\xFF\x00\x00\x00", "\x00\x00\xFF\xFF\xFF\x00\x00\xFF", "\x00\x00\xFF\xFF\xFF\x00\xFF\x00", "\x00\x00\xFF\xFF\xFF\x00\xFF\xFF", "\x00\x00\xFF\xFF\xFF\xFF\x00\x00", "\x00\x00\xFF\xFF\xFF\xFF\x00\xFF", "\x00\x00\xFF\xFF\xFF\xFF\xFF\x00", "\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF", "\x00\xFF\x00\x00\x00\x00\x00\x00", "\x00\xFF\x00\x00\x00\x00\x00\xFF", "\x00\xFF\x00\x00\x00\x00\xFF\x00", "\x00\xFF\x00\x00\x00\x00\xFF\xFF", "\x00\xFF\x00\x00\x00\xFF\x00\x00", "\x00\xFF\x00\x00\x00\xFF\x00\xFF", "\x00\xFF\x00\x00\x00\xFF\xFF\x00", "\x00\xFF\x00\x00\x00\xFF\xFF\xFF", "\x00\xFF\x00\x00\xFF\x00\x00\x00", "\x00\xFF\x00\x00\xFF\x00\x00\xFF", "\x00\xFF\x00\x00\xFF\x00\xFF\x00", "\x00\xFF\x00\x00\xFF\x00\xFF\xFF", "\x00\xFF\x00\x00\xFF\xFF\x00\x00", "\x00\xFF\x00\x00\xFF\xFF\x00\xFF", "\x00\xFF\x00\x00\xFF\xFF\xFF\x00", "\x00\xFF\x00\x00\xFF\xFF\xFF\xFF", "\x00\xFF\x00\xFF\x00\x00\x00\x00", "\x00\xFF\x00\xFF\x00\x00\x00\xFF", "\x00\xFF\x00\xFF\x00\x00\xFF\x00", "\x00\xFF\x00\xFF\x00\x00\xFF\xFF", "\x00\xFF\x00\xFF\x00\xFF\x00\x00", "\x00\xFF\x00\xFF\x00\xFF\x00\xFF", "\x00\xFF\x00\xFF\x00\xFF\xFF\x00", "\x00\xFF\x00\xFF\x00\xFF\xFF\xFF", "\x00\xFF\x00\xFF\xFF\x00\x00\x00", "\x00\xFF\x00\xFF\xFF\x00\x00\xFF", "\x00\xFF\x00\xFF\xFF\x00\xFF\x00", "\x00\xFF\x00\xFF\xFF\x00\xFF\xFF", "\x00\xFF\x00\xFF\xFF\xFF\x00\x00", "\x00\xFF\x00\xFF\xFF\xFF\x00\xFF", "\x00\xFF\x00\xFF\xFF\xFF\xFF\x00", "\x00\xFF\x00\xFF\xFF\xFF\xFF\xFF", "\x00\xFF\xFF\x00\x00\x00\x00\x00", "\x00\xFF\xFF\x00\x00\x00\x00\xFF", "\x00\xFF\xFF\x00\x00\x00\xFF\x00", "\x00\xFF\xFF\x00\x00\x00\xFF\xFF", "\x00\xFF\xFF\x00\x00\xFF\x00\x00", "\x00\xFF\xFF\x00\x00\xFF\x00\xFF", "\x00\xFF\xFF\x00\x00\xFF\xFF\x00", "\x00\xFF\xFF\x00\x00\xFF\xFF\xFF", "\x00\xFF\xFF\x00\xFF\x00\x00\x00", "\x00\xFF\xFF\x00\xFF\x00\x00\xFF", "\x00\xFF\xFF\x00\xFF\x00\xFF\x00", "\x00\xFF\xFF\x00\xFF\x00\xFF\xFF", "\x00\xFF\xFF\x00\xFF\xFF\x00\x00", "\x00\xFF\xFF\x00\xFF\xFF\x00\xFF", "\x00\xFF\xFF\x00\xFF\xFF\xFF\x00", "\x00\xFF\xFF\x00\xFF\xFF\xFF\xFF", "\x00\xFF\xFF\xFF\x00\x00\x00\x00", "\x00\xFF\xFF\xFF\x00\x00\x00\xFF", "\x00\xFF\xFF\xFF\x00\x00\xFF\x00", "\x00\xFF\xFF\xFF\x00\x00\xFF\xFF", "\x00\xFF\xFF\xFF\x00\xFF\x00\x00", "\x00\xFF\xFF\xFF\x00\xFF\x00\xFF", "\x00\xFF\xFF\xFF\x00\xFF\xFF\x00", "\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF", "\x00\xFF\xFF\xFF\xFF\x00\x00\x00", "\x00\xFF\xFF\xFF\xFF\x00\x00\xFF", "\x00\xFF\xFF\xFF\xFF\x00\xFF\x00", "\x00\xFF\xFF\xFF\xFF\x00\xFF\xFF", "\x00\xFF\xFF\xFF\xFF\xFF\x00\x00", "\x00\xFF\xFF\xFF\xFF\xFF\x00\xFF", "\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00", "\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF", "\xFF\x00\x00\x00\x00\x00\x00\x00", "\xFF\x00\x00\x00\x00\x00\x00\xFF", "\xFF\x00\x00\x00\x00\x00\xFF\x00", "\xFF\x00\x00\x00\x00\x00\xFF\xFF", "\xFF\x00\x00\x00\x00\xFF\x00\x00", "\xFF\x00\x00\x00\x00\xFF\x00\xFF", "\xFF\x00\x00\x00\x00\xFF\xFF\x00", "\xFF\x00\x00\x00\x00\xFF\xFF\xFF", "\xFF\x00\x00\x00\xFF\x00\x00\x00", "\xFF\x00\x00\x00\xFF\x00\x00\xFF", "\xFF\x00\x00\x00\xFF\x00\xFF\x00", "\xFF\x00\x00\x00\xFF\x00\xFF\xFF", "\xFF\x00\x00\x00\xFF\xFF\x00\x00", "\xFF\x00\x00\x00\xFF\xFF\x00\xFF", "\xFF\x00\x00\x00\xFF\xFF\xFF\x00", "\xFF\x00\x00\x00\xFF\xFF\xFF\xFF", "\xFF\x00\x00\xFF\x00\x00\x00\x00", "\xFF\x00\x00\xFF\x00\x00\x00\xFF", "\xFF\x00\x00\xFF\x00\x00\xFF\x00", "\xFF\x00\x00\xFF\x00\x00\xFF\xFF", "\xFF\x00\x00\xFF\x00\xFF\x00\x00", "\xFF\x00\x00\xFF\x00\xFF\x00\xFF", "\xFF\x00\x00\xFF\x00\xFF\xFF\x00", "\xFF\x00\x00\xFF\x00\xFF\xFF\xFF", "\xFF\x00\x00\xFF\xFF\x00\x00\x00", "\xFF\x00\x00\xFF\xFF\x00\x00\xFF", "\xFF\x00\x00\xFF\xFF\x00\xFF\x00", "\xFF\x00\x00\xFF\xFF\x00\xFF\xFF", "\xFF\x00\x00\xFF\xFF\xFF\x00\x00", "\xFF\x00\x00\xFF\xFF\xFF\x00\xFF", "\xFF\x00\x00\xFF\xFF\xFF\xFF\x00", "\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF", "\xFF\x00\xFF\x00\x00\x00\x00\x00", "\xFF\x00\xFF\x00\x00\x00\x00\xFF", "\xFF\x00\xFF\x00\x00\x00\xFF\x00", "\xFF\x00\xFF\x00\x00\x00\xFF\xFF", "\xFF\x00\xFF\x00\x00\xFF\x00\x00", "\xFF\x00\xFF\x00\x00\xFF\x00\xFF", "\xFF\x00\xFF\x00\x00\xFF\xFF\x00", "\xFF\x00\xFF\x00\x00\xFF\xFF\xFF", "\xFF\x00\xFF\x00\xFF\x00\x00\x00", "\xFF\x00\xFF\x00\xFF\x00\x00\xFF", "\xFF\x00\xFF\x00\xFF\x00\xFF\x00", "\xFF\x00\xFF\x00\xFF\x00\xFF\xFF", "\xFF\x00\xFF\x00\xFF\xFF\x00\x00", "\xFF\x00\xFF\x00\xFF\xFF\x00\xFF", "\xFF\x00\xFF\x00\xFF\xFF\xFF\x00", "\xFF\x00\xFF\x00\xFF\xFF\xFF\xFF", "\xFF\x00\xFF\xFF\x00\x00\x00\x00", "\xFF\x00\xFF\xFF\x00\x00\x00\xFF", "\xFF\x00\xFF\xFF\x00\x00\xFF\x00", "\xFF\x00\xFF\xFF\x00\x00\xFF\xFF", "\xFF\x00\xFF\xFF\x00\xFF\x00\x00", "\xFF\x00\xFF\xFF\x00\xFF\x00\xFF", "\xFF\x00\xFF\xFF\x00\xFF\xFF\x00", "\xFF\x00\xFF\xFF\x00\xFF\xFF\xFF", "\xFF\x00\xFF\xFF\xFF\x00\x00\x00", "\xFF\x00\xFF\xFF\xFF\x00\x00\xFF", "\xFF\x00\xFF\xFF\xFF\x00\xFF\x00", "\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF", "\xFF\x00\xFF\xFF\xFF\xFF\x00\x00", "\xFF\x00\xFF\xFF\xFF\xFF\x00\xFF", "\xFF\x00\xFF\xFF\xFF\xFF\xFF\x00", "\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF", "\xFF\xFF\x00\x00\x00\x00\x00\x00", "\xFF\xFF\x00\x00\x00\x00\x00\xFF", "\xFF\xFF\x00\x00\x00\x00\xFF\x00", "\xFF\xFF\x00\x00\x00\x00\xFF\xFF", "\xFF\xFF\x00\x00\x00\xFF\x00\x00", "\xFF\xFF\x00\x00\x00\xFF\x00\xFF", "\xFF\xFF\x00\x00\x00\xFF\xFF\x00", "\xFF\xFF\x00\x00\x00\xFF\xFF\xFF", "\xFF\xFF\x00\x00\xFF\x00\x00\x00", "\xFF\xFF\x00\x00\xFF\x00\x00\xFF", "\xFF\xFF\x00\x00\xFF\x00\xFF\x00", "\xFF\xFF\x00\x00\xFF\x00\xFF\xFF", "\xFF\xFF\x00\x00\xFF\xFF\x00\x00", "\xFF\xFF\x00\x00\xFF\xFF\x00\xFF", "\xFF\xFF\x00\x00\xFF\xFF\xFF\x00", "\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF", "\xFF\xFF\x00\xFF\x00\x00\x00\x00", "\xFF\xFF\x00\xFF\x00\x00\x00\xFF", "\xFF\xFF\x00\xFF\x00\x00\xFF\x00", "\xFF\xFF\x00\xFF\x00\x00\xFF\xFF", "\xFF\xFF\x00\xFF\x00\xFF\x00\x00", "\xFF\xFF\x00\xFF\x00\xFF\x00\xFF", "\xFF\xFF\x00\xFF\x00\xFF\xFF\x00", "\xFF\xFF\x00\xFF\x00\xFF\xFF\xFF", "\xFF\xFF\x00\xFF\xFF\x00\x00\x00", "\xFF\xFF\x00\xFF\xFF\x00\x00\xFF", "\xFF\xFF\x00\xFF\xFF\x00\xFF\x00", "\xFF\xFF\x00\xFF\xFF\x00\xFF\xFF", "\xFF\xFF\x00\xFF\xFF\xFF\x00\x00", "\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF", "\xFF\xFF\x00\xFF\xFF\xFF\xFF\x00", "\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF", "\xFF\xFF\xFF\x00\x00\x00\x00\x00", "\xFF\xFF\xFF\x00\x00\x00\x00\xFF", "\xFF\xFF\xFF\x00\x00\x00\xFF\x00", "\xFF\xFF\xFF\x00\x00\x00\xFF\xFF", "\xFF\xFF\xFF\x00\x00\xFF\x00\x00", "\xFF\xFF\xFF\x00\x00\xFF\x00\xFF", "\xFF\xFF\xFF\x00\x00\xFF\xFF\x00", "\xFF\xFF\xFF\x00\x00\xFF\xFF\xFF", "\xFF\xFF\xFF\x00\xFF\x00\x00\x00", "\xFF\xFF\xFF\x00\xFF\x00\x00\xFF", "\xFF\xFF\xFF\x00\xFF\x00\xFF\x00", "\xFF\xFF\xFF\x00\xFF\x00\xFF\xFF", "\xFF\xFF\xFF\x00\xFF\xFF\x00\x00", "\xFF\xFF\xFF\x00\xFF\xFF\x00\xFF", "\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00", "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF", "\xFF\xFF\xFF\xFF\x00\x00\x00\x00", "\xFF\xFF\xFF\xFF\x00\x00\x00\xFF", "\xFF\xFF\xFF\xFF\x00\x00\xFF\x00", "\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF", "\xFF\xFF\xFF\xFF\x00\xFF\x00\x00", "\xFF\xFF\xFF\xFF\x00\xFF\x00\xFF", "\xFF\xFF\xFF\xFF\x00\xFF\xFF\x00", "\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF", "\xFF\xFF\xFF\xFF\xFF\x00\x00\x00", "\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF", "\xFF\xFF\xFF\xFF\xFF\x00\xFF\x00", "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF", "\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00", "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF", "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00", "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" ]; /** * IP mapping helper table. * * Indexing this table with each source byte performs the initial bit permutation. * * @var array */ protected static $ipmap = [ 0x00, 0x10, 0x01, 0x11, 0x20, 0x30, 0x21, 0x31, 0x02, 0x12, 0x03, 0x13, 0x22, 0x32, 0x23, 0x33, 0x40, 0x50, 0x41, 0x51, 0x60, 0x70, 0x61, 0x71, 0x42, 0x52, 0x43, 0x53, 0x62, 0x72, 0x63, 0x73, 0x04, 0x14, 0x05, 0x15, 0x24, 0x34, 0x25, 0x35, 0x06, 0x16, 0x07, 0x17, 0x26, 0x36, 0x27, 0x37, 0x44, 0x54, 0x45, 0x55, 0x64, 0x74, 0x65, 0x75, 0x46, 0x56, 0x47, 0x57, 0x66, 0x76, 0x67, 0x77, 0x80, 0x90, 0x81, 0x91, 0xA0, 0xB0, 0xA1, 0xB1, 0x82, 0x92, 0x83, 0x93, 0xA2, 0xB2, 0xA3, 0xB3, 0xC0, 0xD0, 0xC1, 0xD1, 0xE0, 0xF0, 0xE1, 0xF1, 0xC2, 0xD2, 0xC3, 0xD3, 0xE2, 0xF2, 0xE3, 0xF3, 0x84, 0x94, 0x85, 0x95, 0xA4, 0xB4, 0xA5, 0xB5, 0x86, 0x96, 0x87, 0x97, 0xA6, 0xB6, 0xA7, 0xB7, 0xC4, 0xD4, 0xC5, 0xD5, 0xE4, 0xF4, 0xE5, 0xF5, 0xC6, 0xD6, 0xC7, 0xD7, 0xE6, 0xF6, 0xE7, 0xF7, 0x08, 0x18, 0x09, 0x19, 0x28, 0x38, 0x29, 0x39, 0x0A, 0x1A, 0x0B, 0x1B, 0x2A, 0x3A, 0x2B, 0x3B, 0x48, 0x58, 0x49, 0x59, 0x68, 0x78, 0x69, 0x79, 0x4A, 0x5A, 0x4B, 0x5B, 0x6A, 0x7A, 0x6B, 0x7B, 0x0C, 0x1C, 0x0D, 0x1D, 0x2C, 0x3C, 0x2D, 0x3D, 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, 0x4C, 0x5C, 0x4D, 0x5D, 0x6C, 0x7C, 0x6D, 0x7D, 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, 0x88, 0x98, 0x89, 0x99, 0xA8, 0xB8, 0xA9, 0xB9, 0x8A, 0x9A, 0x8B, 0x9B, 0xAA, 0xBA, 0xAB, 0xBB, 0xC8, 0xD8, 0xC9, 0xD9, 0xE8, 0xF8, 0xE9, 0xF9, 0xCA, 0xDA, 0xCB, 0xDB, 0xEA, 0xFA, 0xEB, 0xFB, 0x8C, 0x9C, 0x8D, 0x9D, 0xAC, 0xBC, 0xAD, 0xBD, 0x8E, 0x9E, 0x8F, 0x9F, 0xAE, 0xBE, 0xAF, 0xBF, 0xCC, 0xDC, 0xCD, 0xDD, 0xEC, 0xFC, 0xED, 0xFD, 0xCE, 0xDE, 0xCF, 0xDF, 0xEE, 0xFE, 0xEF, 0xFF ]; /** * Inverse IP mapping helper table. * Indexing this table with a byte value reverses the bit order. * * @var array */ protected static $invipmap = [ 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4, 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC, 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA, 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6, 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1, 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9, 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD, 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3, 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB, 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF ]; /** * Pre-permuted S-box1 * * Each box ($sbox1-$sbox8) has been vectorized, then each value pre-permuted using the * P table: concatenation can then be replaced by exclusive ORs. * * @var array */ protected static $sbox1 = [ 0x00808200, 0x00000000, 0x00008000, 0x00808202, 0x00808002, 0x00008202, 0x00000002, 0x00008000, 0x00000200, 0x00808200, 0x00808202, 0x00000200, 0x00800202, 0x00808002, 0x00800000, 0x00000002, 0x00000202, 0x00800200, 0x00800200, 0x00008200, 0x00008200, 0x00808000, 0x00808000, 0x00800202, 0x00008002, 0x00800002, 0x00800002, 0x00008002, 0x00000000, 0x00000202, 0x00008202, 0x00800000, 0x00008000, 0x00808202, 0x00000002, 0x00808000, 0x00808200, 0x00800000, 0x00800000, 0x00000200, 0x00808002, 0x00008000, 0x00008200, 0x00800002, 0x00000200, 0x00000002, 0x00800202, 0x00008202, 0x00808202, 0x00008002, 0x00808000, 0x00800202, 0x00800002, 0x00000202, 0x00008202, 0x00808200, 0x00000202, 0x00800200, 0x00800200, 0x00000000, 0x00008002, 0x00008200, 0x00000000, 0x00808002 ]; /** * Pre-permuted S-box2 * * @var array */ protected static $sbox2 = [ 0x40084010, 0x40004000, 0x00004000, 0x00084010, 0x00080000, 0x00000010, 0x40080010, 0x40004010, 0x40000010, 0x40084010, 0x40084000, 0x40000000, 0x40004000, 0x00080000, 0x00000010, 0x40080010, 0x00084000, 0x00080010, 0x40004010, 0x00000000, 0x40000000, 0x00004000, 0x00084010, 0x40080000, 0x00080010, 0x40000010, 0x00000000, 0x00084000, 0x00004010, 0x40084000, 0x40080000, 0x00004010, 0x00000000, 0x00084010, 0x40080010, 0x00080000, 0x40004010, 0x40080000, 0x40084000, 0x00004000, 0x40080000, 0x40004000, 0x00000010, 0x40084010, 0x00084010, 0x00000010, 0x00004000, 0x40000000, 0x00004010, 0x40084000, 0x00080000, 0x40000010, 0x00080010, 0x40004010, 0x40000010, 0x00080010, 0x00084000, 0x00000000, 0x40004000, 0x00004010, 0x40000000, 0x40080010, 0x40084010, 0x00084000 ]; /** * Pre-permuted S-box3 * * @var array */ protected static $sbox3 = [ 0x00000104, 0x04010100, 0x00000000, 0x04010004, 0x04000100, 0x00000000, 0x00010104, 0x04000100, 0x00010004, 0x04000004, 0x04000004, 0x00010000, 0x04010104, 0x00010004, 0x04010000, 0x00000104, 0x04000000, 0x00000004, 0x04010100, 0x00000100, 0x00010100, 0x04010000, 0x04010004, 0x00010104, 0x04000104, 0x00010100, 0x00010000, 0x04000104, 0x00000004, 0x04010104, 0x00000100, 0x04000000, 0x04010100, 0x04000000, 0x00010004, 0x00000104, 0x00010000, 0x04010100, 0x04000100, 0x00000000, 0x00000100, 0x00010004, 0x04010104, 0x04000100, 0x04000004, 0x00000100, 0x00000000, 0x04010004, 0x04000104, 0x00010000, 0x04000000, 0x04010104, 0x00000004, 0x00010104, 0x00010100, 0x04000004, 0x04010000, 0x04000104, 0x00000104, 0x04010000, 0x00010104, 0x00000004, 0x04010004, 0x00010100 ]; /** * Pre-permuted S-box4 * * @var array */ protected static $sbox4 = [ 0x80401000, 0x80001040, 0x80001040, 0x00000040, 0x00401040, 0x80400040, 0x80400000, 0x80001000, 0x00000000, 0x00401000, 0x00401000, 0x80401040, 0x80000040, 0x00000000, 0x00400040, 0x80400000, 0x80000000, 0x00001000, 0x00400000, 0x80401000, 0x00000040, 0x00400000, 0x80001000, 0x00001040, 0x80400040, 0x80000000, 0x00001040, 0x00400040, 0x00001000, 0x00401040, 0x80401040, 0x80000040, 0x00400040, 0x80400000, 0x00401000, 0x80401040, 0x80000040, 0x00000000, 0x00000000, 0x00401000, 0x00001040, 0x00400040, 0x80400040, 0x80000000, 0x80401000, 0x80001040, 0x80001040, 0x00000040, 0x80401040, 0x80000040, 0x80000000, 0x00001000, 0x80400000, 0x80001000, 0x00401040, 0x80400040, 0x80001000, 0x00001040, 0x00400000, 0x80401000, 0x00000040, 0x00400000, 0x00001000, 0x00401040 ]; /** * Pre-permuted S-box5 * * @var array */ protected static $sbox5 = [ 0x00000080, 0x01040080, 0x01040000, 0x21000080, 0x00040000, 0x00000080, 0x20000000, 0x01040000, 0x20040080, 0x00040000, 0x01000080, 0x20040080, 0x21000080, 0x21040000, 0x00040080, 0x20000000, 0x01000000, 0x20040000, 0x20040000, 0x00000000, 0x20000080, 0x21040080, 0x21040080, 0x01000080, 0x21040000, 0x20000080, 0x00000000, 0x21000000, 0x01040080, 0x01000000, 0x21000000, 0x00040080, 0x00040000, 0x21000080, 0x00000080, 0x01000000, 0x20000000, 0x01040000, 0x21000080, 0x20040080, 0x01000080, 0x20000000, 0x21040000, 0x01040080, 0x20040080, 0x00000080, 0x01000000, 0x21040000, 0x21040080, 0x00040080, 0x21000000, 0x21040080, 0x01040000, 0x00000000, 0x20040000, 0x21000000, 0x00040080, 0x01000080, 0x20000080, 0x00040000, 0x00000000, 0x20040000, 0x01040080, 0x20000080 ]; /** * Pre-permuted S-box6 * * @var array */ protected static $sbox6 = [ 0x10000008, 0x10200000, 0x00002000, 0x10202008, 0x10200000, 0x00000008, 0x10202008, 0x00200000, 0x10002000, 0x00202008, 0x00200000, 0x10000008, 0x00200008, 0x10002000, 0x10000000, 0x00002008, 0x00000000, 0x00200008, 0x10002008, 0x00002000, 0x00202000, 0x10002008, 0x00000008, 0x10200008, 0x10200008, 0x00000000, 0x00202008, 0x10202000, 0x00002008, 0x00202000, 0x10202000, 0x10000000, 0x10002000, 0x00000008, 0x10200008, 0x00202000, 0x10202008, 0x00200000, 0x00002008, 0x10000008, 0x00200000, 0x10002000, 0x10000000, 0x00002008, 0x10000008, 0x10202008, 0x00202000, 0x10200000, 0x00202008, 0x10202000, 0x00000000, 0x10200008, 0x00000008, 0x00002000, 0x10200000, 0x00202008, 0x00002000, 0x00200008, 0x10002008, 0x00000000, 0x10202000, 0x10000000, 0x00200008, 0x10002008 ]; /** * Pre-permuted S-box7 * * @var array */ protected static $sbox7 = [ 0x00100000, 0x02100001, 0x02000401, 0x00000000, 0x00000400, 0x02000401, 0x00100401, 0x02100400, 0x02100401, 0x00100000, 0x00000000, 0x02000001, 0x00000001, 0x02000000, 0x02100001, 0x00000401, 0x02000400, 0x00100401, 0x00100001, 0x02000400, 0x02000001, 0x02100000, 0x02100400, 0x00100001, 0x02100000, 0x00000400, 0x00000401, 0x02100401, 0x00100400, 0x00000001, 0x02000000, 0x00100400, 0x02000000, 0x00100400, 0x00100000, 0x02000401, 0x02000401, 0x02100001, 0x02100001, 0x00000001, 0x00100001, 0x02000000, 0x02000400, 0x00100000, 0x02100400, 0x00000401, 0x00100401, 0x02100400, 0x00000401, 0x02000001, 0x02100401, 0x02100000, 0x00100400, 0x00000000, 0x00000001, 0x02100401, 0x00000000, 0x00100401, 0x02100000, 0x00000400, 0x02000001, 0x02000400, 0x00000400, 0x00100001 ]; /** * Pre-permuted S-box8 * * @var array */ protected static $sbox8 = [ 0x08000820, 0x00000800, 0x00020000, 0x08020820, 0x08000000, 0x08000820, 0x00000020, 0x08000000, 0x00020020, 0x08020000, 0x08020820, 0x00020800, 0x08020800, 0x00020820, 0x00000800, 0x00000020, 0x08020000, 0x08000020, 0x08000800, 0x00000820, 0x00020800, 0x00020020, 0x08020020, 0x08020800, 0x00000820, 0x00000000, 0x00000000, 0x08020020, 0x08000020, 0x08000800, 0x00020820, 0x00020000, 0x00020820, 0x00020000, 0x08020800, 0x00000800, 0x00000020, 0x08020020, 0x00000800, 0x00020820, 0x08000800, 0x00000020, 0x08000020, 0x08020000, 0x08020020, 0x08000000, 0x00020000, 0x08000820, 0x00000000, 0x08020820, 0x00020020, 0x08000020, 0x08020000, 0x08000800, 0x08000820, 0x00000000, 0x08020820, 0x00020800, 0x00020800, 0x00000820, 0x00000820, 0x00020020, 0x08000000, 0x08020800 ]; /** * Default Constructor. * * @param string $mode * @throws BadModeException if an invalid / unsupported mode is provided */ public function __construct($mode) { parent::__construct($mode); if ($this->mode == self::MODE_STREAM) { throw new BadModeException('Block ciphers cannot be ran in stream mode'); } } /** * Test for engine validity * * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() * * @see Common\SymmetricKey::isValidEngine() * @param int $engine * @return bool */ protected function isValidEngineHelper($engine) { if ($this->key_length_max == 8) { if ($engine == self::ENGINE_OPENSSL) { // quoting https://www.openssl.org/news/openssl-3.0-notes.html, OpenSSL 3.0.1 // "Moved all variations of the EVP ciphers CAST5, BF, IDEA, SEED, RC2, RC4, RC5, and DES to the legacy provider" // in theory openssl_get_cipher_methods() should catch this but, on GitHub Actions, at least, it does not if (defined('OPENSSL_VERSION_TEXT') && version_compare(preg_replace('#OpenSSL (\d+\.\d+\.\d+) .*#', '$1', OPENSSL_VERSION_TEXT), '3.0.1', '>=')) { return false; } $this->cipher_name_openssl_ecb = 'des-ecb'; $this->cipher_name_openssl = 'des-' . $this->openssl_translate_mode(); } } return parent::isValidEngineHelper($engine); } /** * Sets the key. * * Keys must be 64-bits long or 8 bytes long. * * DES also requires that every eighth bit be a parity bit, however, we'll ignore that. * * @see Common\SymmetricKey::setKey() * @param string $key */ public function setKey($key) { if (!($this instanceof TripleDES) && strlen($key) != 8) { throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of size 8 are supported'); } // Sets the key parent::setKey($key); } /** * Encrypts a block * * @see Common\SymmetricKey::encryptBlock() * @see Common\SymmetricKey::encrypt() * @see self::encrypt() * @param string $in * @return string */ protected function encryptBlock($in) { return $this->processBlock($in, self::ENCRYPT); } /** * Decrypts a block * * @see Common\SymmetricKey::decryptBlock() * @see Common\SymmetricKey::decrypt() * @see self::decrypt() * @param string $in * @return string */ protected function decryptBlock($in) { return $this->processBlock($in, self::DECRYPT); } /** * Encrypts or decrypts a 64-bit block * * $mode should be either self::ENCRYPT or self::DECRYPT. See * {@link http://en.wikipedia.org/wiki/Image:Feistel.png Feistel.png} to get a general * idea of what this function does. * * @see self::encryptBlock() * @see self::decryptBlock() * @param string $block * @param int $mode * @return string */ private function processBlock($block, $mode) { static $sbox1, $sbox2, $sbox3, $sbox4, $sbox5, $sbox6, $sbox7, $sbox8, $shuffleip, $shuffleinvip; if (!$sbox1) { $sbox1 = array_map('intval', self::$sbox1); $sbox2 = array_map('intval', self::$sbox2); $sbox3 = array_map('intval', self::$sbox3); $sbox4 = array_map('intval', self::$sbox4); $sbox5 = array_map('intval', self::$sbox5); $sbox6 = array_map('intval', self::$sbox6); $sbox7 = array_map('intval', self::$sbox7); $sbox8 = array_map('intval', self::$sbox8); /* Merge $shuffle with $[inv]ipmap */ for ($i = 0; $i < 256; ++$i) { $shuffleip[] = self::$shuffle[self::$ipmap[$i]]; $shuffleinvip[] = self::$shuffle[self::$invipmap[$i]]; } } $keys = $this->keys[$mode]; $ki = -1; // Do the initial IP permutation. $t = unpack('Nl/Nr', $block); list($l, $r) = [$t['l'], $t['r']]; $block = ($shuffleip[ $r & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") | ($shuffleip[($r >> 8) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") | ($shuffleip[($r >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") | ($shuffleip[($r >> 24) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") | ($shuffleip[ $l & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") | ($shuffleip[($l >> 8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") | ($shuffleip[($l >> 16) & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") | ($shuffleip[($l >> 24) & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01"); // Extract L0 and R0. $t = unpack('Nl/Nr', $block); list($l, $r) = [$t['l'], $t['r']]; for ($des_round = 0; $des_round < $this->des_rounds; ++$des_round) { // Perform the 16 steps. for ($i = 0; $i < 16; $i++) { // start of "the Feistel (F) function" - see the following URL: // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png // Merge key schedule. $b1 = (($r >> 3) & 0x1FFFFFFF) ^ ($r << 29) ^ $keys[++$ki]; $b2 = (($r >> 31) & 0x00000001) ^ ($r << 1) ^ $keys[++$ki]; // S-box indexing. $t = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^ $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^ $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^ $sbox7[ $b1 & 0x3F] ^ $sbox8[ $b2 & 0x3F] ^ $l; // end of "the Feistel (F) function" $l = $r; $r = $t; } // Last step should not permute L & R. $t = $l; $l = $r; $r = $t; } // Perform the inverse IP permutation. return ($shuffleinvip[($r >> 24) & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") | ($shuffleinvip[($l >> 24) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") | ($shuffleinvip[($r >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") | ($shuffleinvip[($l >> 16) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") | ($shuffleinvip[($r >> 8) & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") | ($shuffleinvip[($l >> 8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") | ($shuffleinvip[ $r & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") | ($shuffleinvip[ $l & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01"); } /** * Creates the key schedule * * @see Common\SymmetricKey::setupKey() */ protected function setupKey() { if (isset($this->kl['key']) && $this->key === $this->kl['key'] && $this->des_rounds === $this->kl['des_rounds']) { // already expanded return; } $this->kl = ['key' => $this->key, 'des_rounds' => $this->des_rounds]; static $shifts = [ // number of key bits shifted per round 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 ]; static $pc1map = [ 0x00, 0x00, 0x08, 0x08, 0x04, 0x04, 0x0C, 0x0C, 0x02, 0x02, 0x0A, 0x0A, 0x06, 0x06, 0x0E, 0x0E, 0x10, 0x10, 0x18, 0x18, 0x14, 0x14, 0x1C, 0x1C, 0x12, 0x12, 0x1A, 0x1A, 0x16, 0x16, 0x1E, 0x1E, 0x20, 0x20, 0x28, 0x28, 0x24, 0x24, 0x2C, 0x2C, 0x22, 0x22, 0x2A, 0x2A, 0x26, 0x26, 0x2E, 0x2E, 0x30, 0x30, 0x38, 0x38, 0x34, 0x34, 0x3C, 0x3C, 0x32, 0x32, 0x3A, 0x3A, 0x36, 0x36, 0x3E, 0x3E, 0x40, 0x40, 0x48, 0x48, 0x44, 0x44, 0x4C, 0x4C, 0x42, 0x42, 0x4A, 0x4A, 0x46, 0x46, 0x4E, 0x4E, 0x50, 0x50, 0x58, 0x58, 0x54, 0x54, 0x5C, 0x5C, 0x52, 0x52, 0x5A, 0x5A, 0x56, 0x56, 0x5E, 0x5E, 0x60, 0x60, 0x68, 0x68, 0x64, 0x64, 0x6C, 0x6C, 0x62, 0x62, 0x6A, 0x6A, 0x66, 0x66, 0x6E, 0x6E, 0x70, 0x70, 0x78, 0x78, 0x74, 0x74, 0x7C, 0x7C, 0x72, 0x72, 0x7A, 0x7A, 0x76, 0x76, 0x7E, 0x7E, 0x80, 0x80, 0x88, 0x88, 0x84, 0x84, 0x8C, 0x8C, 0x82, 0x82, 0x8A, 0x8A, 0x86, 0x86, 0x8E, 0x8E, 0x90, 0x90, 0x98, 0x98, 0x94, 0x94, 0x9C, 0x9C, 0x92, 0x92, 0x9A, 0x9A, 0x96, 0x96, 0x9E, 0x9E, 0xA0, 0xA0, 0xA8, 0xA8, 0xA4, 0xA4, 0xAC, 0xAC, 0xA2, 0xA2, 0xAA, 0xAA, 0xA6, 0xA6, 0xAE, 0xAE, 0xB0, 0xB0, 0xB8, 0xB8, 0xB4, 0xB4, 0xBC, 0xBC, 0xB2, 0xB2, 0xBA, 0xBA, 0xB6, 0xB6, 0xBE, 0xBE, 0xC0, 0xC0, 0xC8, 0xC8, 0xC4, 0xC4, 0xCC, 0xCC, 0xC2, 0xC2, 0xCA, 0xCA, 0xC6, 0xC6, 0xCE, 0xCE, 0xD0, 0xD0, 0xD8, 0xD8, 0xD4, 0xD4, 0xDC, 0xDC, 0xD2, 0xD2, 0xDA, 0xDA, 0xD6, 0xD6, 0xDE, 0xDE, 0xE0, 0xE0, 0xE8, 0xE8, 0xE4, 0xE4, 0xEC, 0xEC, 0xE2, 0xE2, 0xEA, 0xEA, 0xE6, 0xE6, 0xEE, 0xEE, 0xF0, 0xF0, 0xF8, 0xF8, 0xF4, 0xF4, 0xFC, 0xFC, 0xF2, 0xF2, 0xFA, 0xFA, 0xF6, 0xF6, 0xFE, 0xFE ]; // Mapping tables for the PC-2 transformation. static $pc2mapc1 = [ 0x00000000, 0x00000400, 0x00200000, 0x00200400, 0x00000001, 0x00000401, 0x00200001, 0x00200401, 0x02000000, 0x02000400, 0x02200000, 0x02200400, 0x02000001, 0x02000401, 0x02200001, 0x02200401 ]; static $pc2mapc2 = [ 0x00000000, 0x00000800, 0x08000000, 0x08000800, 0x00010000, 0x00010800, 0x08010000, 0x08010800, 0x00000000, 0x00000800, 0x08000000, 0x08000800, 0x00010000, 0x00010800, 0x08010000, 0x08010800, 0x00000100, 0x00000900, 0x08000100, 0x08000900, 0x00010100, 0x00010900, 0x08010100, 0x08010900, 0x00000100, 0x00000900, 0x08000100, 0x08000900, 0x00010100, 0x00010900, 0x08010100, 0x08010900, 0x00000010, 0x00000810, 0x08000010, 0x08000810, 0x00010010, 0x00010810, 0x08010010, 0x08010810, 0x00000010, 0x00000810, 0x08000010, 0x08000810, 0x00010010, 0x00010810, 0x08010010, 0x08010810, 0x00000110, 0x00000910, 0x08000110, 0x08000910, 0x00010110, 0x00010910, 0x08010110, 0x08010910, 0x00000110, 0x00000910, 0x08000110, 0x08000910, 0x00010110, 0x00010910, 0x08010110, 0x08010910, 0x00040000, 0x00040800, 0x08040000, 0x08040800, 0x00050000, 0x00050800, 0x08050000, 0x08050800, 0x00040000, 0x00040800, 0x08040000, 0x08040800, 0x00050000, 0x00050800, 0x08050000, 0x08050800, 0x00040100, 0x00040900, 0x08040100, 0x08040900, 0x00050100, 0x00050900, 0x08050100, 0x08050900, 0x00040100, 0x00040900, 0x08040100, 0x08040900, 0x00050100, 0x00050900, 0x08050100, 0x08050900, 0x00040010, 0x00040810, 0x08040010, 0x08040810, 0x00050010, 0x00050810, 0x08050010, 0x08050810, 0x00040010, 0x00040810, 0x08040010, 0x08040810, 0x00050010, 0x00050810, 0x08050010, 0x08050810, 0x00040110, 0x00040910, 0x08040110, 0x08040910, 0x00050110, 0x00050910, 0x08050110, 0x08050910, 0x00040110, 0x00040910, 0x08040110, 0x08040910, 0x00050110, 0x00050910, 0x08050110, 0x08050910, 0x01000000, 0x01000800, 0x09000000, 0x09000800, 0x01010000, 0x01010800, 0x09010000, 0x09010800, 0x01000000, 0x01000800, 0x09000000, 0x09000800, 0x01010000, 0x01010800, 0x09010000, 0x09010800, 0x01000100, 0x01000900, 0x09000100, 0x09000900, 0x01010100, 0x01010900, 0x09010100, 0x09010900, 0x01000100, 0x01000900, 0x09000100, 0x09000900, 0x01010100, 0x01010900, 0x09010100, 0x09010900, 0x01000010, 0x01000810, 0x09000010, 0x09000810, 0x01010010, 0x01010810, 0x09010010, 0x09010810, 0x01000010, 0x01000810, 0x09000010, 0x09000810, 0x01010010, 0x01010810, 0x09010010, 0x09010810, 0x01000110, 0x01000910, 0x09000110, 0x09000910, 0x01010110, 0x01010910, 0x09010110, 0x09010910, 0x01000110, 0x01000910, 0x09000110, 0x09000910, 0x01010110, 0x01010910, 0x09010110, 0x09010910, 0x01040000, 0x01040800, 0x09040000, 0x09040800, 0x01050000, 0x01050800, 0x09050000, 0x09050800, 0x01040000, 0x01040800, 0x09040000, 0x09040800, 0x01050000, 0x01050800, 0x09050000, 0x09050800, 0x01040100, 0x01040900, 0x09040100, 0x09040900, 0x01050100, 0x01050900, 0x09050100, 0x09050900, 0x01040100, 0x01040900, 0x09040100, 0x09040900, 0x01050100, 0x01050900, 0x09050100, 0x09050900, 0x01040010, 0x01040810, 0x09040010, 0x09040810, 0x01050010, 0x01050810, 0x09050010, 0x09050810, 0x01040010, 0x01040810, 0x09040010, 0x09040810, 0x01050010, 0x01050810, 0x09050010, 0x09050810, 0x01040110, 0x01040910, 0x09040110, 0x09040910, 0x01050110, 0x01050910, 0x09050110, 0x09050910, 0x01040110, 0x01040910, 0x09040110, 0x09040910, 0x01050110, 0x01050910, 0x09050110, 0x09050910 ]; static $pc2mapc3 = [ 0x00000000, 0x00000004, 0x00001000, 0x00001004, 0x00000000, 0x00000004, 0x00001000, 0x00001004, 0x10000000, 0x10000004, 0x10001000, 0x10001004, 0x10000000, 0x10000004, 0x10001000, 0x10001004, 0x00000020, 0x00000024, 0x00001020, 0x00001024, 0x00000020, 0x00000024, 0x00001020, 0x00001024, 0x10000020, 0x10000024, 0x10001020, 0x10001024, 0x10000020, 0x10000024, 0x10001020, 0x10001024, 0x00080000, 0x00080004, 0x00081000, 0x00081004, 0x00080000, 0x00080004, 0x00081000, 0x00081004, 0x10080000, 0x10080004, 0x10081000, 0x10081004, 0x10080000, 0x10080004, 0x10081000, 0x10081004, 0x00080020, 0x00080024, 0x00081020, 0x00081024, 0x00080020, 0x00080024, 0x00081020, 0x00081024, 0x10080020, 0x10080024, 0x10081020, 0x10081024, 0x10080020, 0x10080024, 0x10081020, 0x10081024, 0x20000000, 0x20000004, 0x20001000, 0x20001004, 0x20000000, 0x20000004, 0x20001000, 0x20001004, 0x30000000, 0x30000004, 0x30001000, 0x30001004, 0x30000000, 0x30000004, 0x30001000, 0x30001004, 0x20000020, 0x20000024, 0x20001020, 0x20001024, 0x20000020, 0x20000024, 0x20001020, 0x20001024, 0x30000020, 0x30000024, 0x30001020, 0x30001024, 0x30000020, 0x30000024, 0x30001020, 0x30001024, 0x20080000, 0x20080004, 0x20081000, 0x20081004, 0x20080000, 0x20080004, 0x20081000, 0x20081004, 0x30080000, 0x30080004, 0x30081000, 0x30081004, 0x30080000, 0x30080004, 0x30081000, 0x30081004, 0x20080020, 0x20080024, 0x20081020, 0x20081024, 0x20080020, 0x20080024, 0x20081020, 0x20081024, 0x30080020, 0x30080024, 0x30081020, 0x30081024, 0x30080020, 0x30080024, 0x30081020, 0x30081024, 0x00000002, 0x00000006, 0x00001002, 0x00001006, 0x00000002, 0x00000006, 0x00001002, 0x00001006, 0x10000002, 0x10000006, 0x10001002, 0x10001006, 0x10000002, 0x10000006, 0x10001002, 0x10001006, 0x00000022, 0x00000026, 0x00001022, 0x00001026, 0x00000022, 0x00000026, 0x00001022, 0x00001026, 0x10000022, 0x10000026, 0x10001022, 0x10001026, 0x10000022, 0x10000026, 0x10001022, 0x10001026, 0x00080002, 0x00080006, 0x00081002, 0x00081006, 0x00080002, 0x00080006, 0x00081002, 0x00081006, 0x10080002, 0x10080006, 0x10081002, 0x10081006, 0x10080002, 0x10080006, 0x10081002, 0x10081006, 0x00080022, 0x00080026, 0x00081022, 0x00081026, 0x00080022, 0x00080026, 0x00081022, 0x00081026, 0x10080022, 0x10080026, 0x10081022, 0x10081026, 0x10080022, 0x10080026, 0x10081022, 0x10081026, 0x20000002, 0x20000006, 0x20001002, 0x20001006, 0x20000002, 0x20000006, 0x20001002, 0x20001006, 0x30000002, 0x30000006, 0x30001002, 0x30001006, 0x30000002, 0x30000006, 0x30001002, 0x30001006, 0x20000022, 0x20000026, 0x20001022, 0x20001026, 0x20000022, 0x20000026, 0x20001022, 0x20001026, 0x30000022, 0x30000026, 0x30001022, 0x30001026, 0x30000022, 0x30000026, 0x30001022, 0x30001026, 0x20080002, 0x20080006, 0x20081002, 0x20081006, 0x20080002, 0x20080006, 0x20081002, 0x20081006, 0x30080002, 0x30080006, 0x30081002, 0x30081006, 0x30080002, 0x30080006, 0x30081002, 0x30081006, 0x20080022, 0x20080026, 0x20081022, 0x20081026, 0x20080022, 0x20080026, 0x20081022, 0x20081026, 0x30080022, 0x30080026, 0x30081022, 0x30081026, 0x30080022, 0x30080026, 0x30081022, 0x30081026 ]; static $pc2mapc4 = [ 0x00000000, 0x00100000, 0x00000008, 0x00100008, 0x00000200, 0x00100200, 0x00000208, 0x00100208, 0x00000000, 0x00100000, 0x00000008, 0x00100008, 0x00000200, 0x00100200, 0x00000208, 0x00100208, 0x04000000, 0x04100000, 0x04000008, 0x04100008, 0x04000200, 0x04100200, 0x04000208, 0x04100208, 0x04000000, 0x04100000, 0x04000008, 0x04100008, 0x04000200, 0x04100200, 0x04000208, 0x04100208, 0x00002000, 0x00102000, 0x00002008, 0x00102008, 0x00002200, 0x00102200, 0x00002208, 0x00102208, 0x00002000, 0x00102000, 0x00002008, 0x00102008, 0x00002200, 0x00102200, 0x00002208, 0x00102208, 0x04002000, 0x04102000, 0x04002008, 0x04102008, 0x04002200, 0x04102200, 0x04002208, 0x04102208, 0x04002000, 0x04102000, 0x04002008, 0x04102008, 0x04002200, 0x04102200, 0x04002208, 0x04102208, 0x00000000, 0x00100000, 0x00000008, 0x00100008, 0x00000200, 0x00100200, 0x00000208, 0x00100208, 0x00000000, 0x00100000, 0x00000008, 0x00100008, 0x00000200, 0x00100200, 0x00000208, 0x00100208, 0x04000000, 0x04100000, 0x04000008, 0x04100008, 0x04000200, 0x04100200, 0x04000208, 0x04100208, 0x04000000, 0x04100000, 0x04000008, 0x04100008, 0x04000200, 0x04100200, 0x04000208, 0x04100208, 0x00002000, 0x00102000, 0x00002008, 0x00102008, 0x00002200, 0x00102200, 0x00002208, 0x00102208, 0x00002000, 0x00102000, 0x00002008, 0x00102008, 0x00002200, 0x00102200, 0x00002208, 0x00102208, 0x04002000, 0x04102000, 0x04002008, 0x04102008, 0x04002200, 0x04102200, 0x04002208, 0x04102208, 0x04002000, 0x04102000, 0x04002008, 0x04102008, 0x04002200, 0x04102200, 0x04002208, 0x04102208, 0x00020000, 0x00120000, 0x00020008, 0x00120008, 0x00020200, 0x00120200, 0x00020208, 0x00120208, 0x00020000, 0x00120000, 0x00020008, 0x00120008, 0x00020200, 0x00120200, 0x00020208, 0x00120208, 0x04020000, 0x04120000, 0x04020008, 0x04120008, 0x04020200, 0x04120200, 0x04020208, 0x04120208, 0x04020000, 0x04120000, 0x04020008, 0x04120008, 0x04020200, 0x04120200, 0x04020208, 0x04120208, 0x00022000, 0x00122000, 0x00022008, 0x00122008, 0x00022200, 0x00122200, 0x00022208, 0x00122208, 0x00022000, 0x00122000, 0x00022008, 0x00122008, 0x00022200, 0x00122200, 0x00022208, 0x00122208, 0x04022000, 0x04122000, 0x04022008, 0x04122008, 0x04022200, 0x04122200, 0x04022208, 0x04122208, 0x04022000, 0x04122000, 0x04022008, 0x04122008, 0x04022200, 0x04122200, 0x04022208, 0x04122208, 0x00020000, 0x00120000, 0x00020008, 0x00120008, 0x00020200, 0x00120200, 0x00020208, 0x00120208, 0x00020000, 0x00120000, 0x00020008, 0x00120008, 0x00020200, 0x00120200, 0x00020208, 0x00120208, 0x04020000, 0x04120000, 0x04020008, 0x04120008, 0x04020200, 0x04120200, 0x04020208, 0x04120208, 0x04020000, 0x04120000, 0x04020008, 0x04120008, 0x04020200, 0x04120200, 0x04020208, 0x04120208, 0x00022000, 0x00122000, 0x00022008, 0x00122008, 0x00022200, 0x00122200, 0x00022208, 0x00122208, 0x00022000, 0x00122000, 0x00022008, 0x00122008, 0x00022200, 0x00122200, 0x00022208, 0x00122208, 0x04022000, 0x04122000, 0x04022008, 0x04122008, 0x04022200, 0x04122200, 0x04022208, 0x04122208, 0x04022000, 0x04122000, 0x04022008, 0x04122008, 0x04022200, 0x04122200, 0x04022208, 0x04122208 ]; static $pc2mapd1 = [ 0x00000000, 0x00000001, 0x08000000, 0x08000001, 0x00200000, 0x00200001, 0x08200000, 0x08200001, 0x00000002, 0x00000003, 0x08000002, 0x08000003, 0x00200002, 0x00200003, 0x08200002, 0x08200003 ]; static $pc2mapd2 = [ 0x00000000, 0x00100000, 0x00000800, 0x00100800, 0x00000000, 0x00100000, 0x00000800, 0x00100800, 0x04000000, 0x04100000, 0x04000800, 0x04100800, 0x04000000, 0x04100000, 0x04000800, 0x04100800, 0x00000004, 0x00100004, 0x00000804, 0x00100804, 0x00000004, 0x00100004, 0x00000804, 0x00100804, 0x04000004, 0x04100004, 0x04000804, 0x04100804, 0x04000004, 0x04100004, 0x04000804, 0x04100804, 0x00000000, 0x00100000, 0x00000800, 0x00100800, 0x00000000, 0x00100000, 0x00000800, 0x00100800, 0x04000000, 0x04100000, 0x04000800, 0x04100800, 0x04000000, 0x04100000, 0x04000800, 0x04100800, 0x00000004, 0x00100004, 0x00000804, 0x00100804, 0x00000004, 0x00100004, 0x00000804, 0x00100804, 0x04000004, 0x04100004, 0x04000804, 0x04100804, 0x04000004, 0x04100004, 0x04000804, 0x04100804, 0x00000200, 0x00100200, 0x00000A00, 0x00100A00, 0x00000200, 0x00100200, 0x00000A00, 0x00100A00, 0x04000200, 0x04100200, 0x04000A00, 0x04100A00, 0x04000200, 0x04100200, 0x04000A00, 0x04100A00, 0x00000204, 0x00100204, 0x00000A04, 0x00100A04, 0x00000204, 0x00100204, 0x00000A04, 0x00100A04, 0x04000204, 0x04100204, 0x04000A04, 0x04100A04, 0x04000204, 0x04100204, 0x04000A04, 0x04100A04, 0x00000200, 0x00100200, 0x00000A00, 0x00100A00, 0x00000200, 0x00100200, 0x00000A00, 0x00100A00, 0x04000200, 0x04100200, 0x04000A00, 0x04100A00, 0x04000200, 0x04100200, 0x04000A00, 0x04100A00, 0x00000204, 0x00100204, 0x00000A04, 0x00100A04, 0x00000204, 0x00100204, 0x00000A04, 0x00100A04, 0x04000204, 0x04100204, 0x04000A04, 0x04100A04, 0x04000204, 0x04100204, 0x04000A04, 0x04100A04, 0x00020000, 0x00120000, 0x00020800, 0x00120800, 0x00020000, 0x00120000, 0x00020800, 0x00120800, 0x04020000, 0x04120000, 0x04020800, 0x04120800, 0x04020000, 0x04120000, 0x04020800, 0x04120800, 0x00020004, 0x00120004, 0x00020804, 0x00120804, 0x00020004, 0x00120004, 0x00020804, 0x00120804, 0x04020004, 0x04120004, 0x04020804, 0x04120804, 0x04020004, 0x04120004, 0x04020804, 0x04120804, 0x00020000, 0x00120000, 0x00020800, 0x00120800, 0x00020000, 0x00120000, 0x00020800, 0x00120800, 0x04020000, 0x04120000, 0x04020800, 0x04120800, 0x04020000, 0x04120000, 0x04020800, 0x04120800, 0x00020004, 0x00120004, 0x00020804, 0x00120804, 0x00020004, 0x00120004, 0x00020804, 0x00120804, 0x04020004, 0x04120004, 0x04020804, 0x04120804, 0x04020004, 0x04120004, 0x04020804, 0x04120804, 0x00020200, 0x00120200, 0x00020A00, 0x00120A00, 0x00020200, 0x00120200, 0x00020A00, 0x00120A00, 0x04020200, 0x04120200, 0x04020A00, 0x04120A00, 0x04020200, 0x04120200, 0x04020A00, 0x04120A00, 0x00020204, 0x00120204, 0x00020A04, 0x00120A04, 0x00020204, 0x00120204, 0x00020A04, 0x00120A04, 0x04020204, 0x04120204, 0x04020A04, 0x04120A04, 0x04020204, 0x04120204, 0x04020A04, 0x04120A04, 0x00020200, 0x00120200, 0x00020A00, 0x00120A00, 0x00020200, 0x00120200, 0x00020A00, 0x00120A00, 0x04020200, 0x04120200, 0x04020A00, 0x04120A00, 0x04020200, 0x04120200, 0x04020A00, 0x04120A00, 0x00020204, 0x00120204, 0x00020A04, 0x00120A04, 0x00020204, 0x00120204, 0x00020A04, 0x00120A04, 0x04020204, 0x04120204, 0x04020A04, 0x04120A04, 0x04020204, 0x04120204, 0x04020A04, 0x04120A04 ]; static $pc2mapd3 = [ 0x00000000, 0x00010000, 0x02000000, 0x02010000, 0x00000020, 0x00010020, 0x02000020, 0x02010020, 0x00040000, 0x00050000, 0x02040000, 0x02050000, 0x00040020, 0x00050020, 0x02040020, 0x02050020, 0x00002000, 0x00012000, 0x02002000, 0x02012000, 0x00002020, 0x00012020, 0x02002020, 0x02012020, 0x00042000, 0x00052000, 0x02042000, 0x02052000, 0x00042020, 0x00052020, 0x02042020, 0x02052020, 0x00000000, 0x00010000, 0x02000000, 0x02010000, 0x00000020, 0x00010020, 0x02000020, 0x02010020, 0x00040000, 0x00050000, 0x02040000, 0x02050000, 0x00040020, 0x00050020, 0x02040020, 0x02050020, 0x00002000, 0x00012000, 0x02002000, 0x02012000, 0x00002020, 0x00012020, 0x02002020, 0x02012020, 0x00042000, 0x00052000, 0x02042000, 0x02052000, 0x00042020, 0x00052020, 0x02042020, 0x02052020, 0x00000010, 0x00010010, 0x02000010, 0x02010010, 0x00000030, 0x00010030, 0x02000030, 0x02010030, 0x00040010, 0x00050010, 0x02040010, 0x02050010, 0x00040030, 0x00050030, 0x02040030, 0x02050030, 0x00002010, 0x00012010, 0x02002010, 0x02012010, 0x00002030, 0x00012030, 0x02002030, 0x02012030, 0x00042010, 0x00052010, 0x02042010, 0x02052010, 0x00042030, 0x00052030, 0x02042030, 0x02052030, 0x00000010, 0x00010010, 0x02000010, 0x02010010, 0x00000030, 0x00010030, 0x02000030, 0x02010030, 0x00040010, 0x00050010, 0x02040010, 0x02050010, 0x00040030, 0x00050030, 0x02040030, 0x02050030, 0x00002010, 0x00012010, 0x02002010, 0x02012010, 0x00002030, 0x00012030, 0x02002030, 0x02012030, 0x00042010, 0x00052010, 0x02042010, 0x02052010, 0x00042030, 0x00052030, 0x02042030, 0x02052030, 0x20000000, 0x20010000, 0x22000000, 0x22010000, 0x20000020, 0x20010020, 0x22000020, 0x22010020, 0x20040000, 0x20050000, 0x22040000, 0x22050000, 0x20040020, 0x20050020, 0x22040020, 0x22050020, 0x20002000, 0x20012000, 0x22002000, 0x22012000, 0x20002020, 0x20012020, 0x22002020, 0x22012020, 0x20042000, 0x20052000, 0x22042000, 0x22052000, 0x20042020, 0x20052020, 0x22042020, 0x22052020, 0x20000000, 0x20010000, 0x22000000, 0x22010000, 0x20000020, 0x20010020, 0x22000020, 0x22010020, 0x20040000, 0x20050000, 0x22040000, 0x22050000, 0x20040020, 0x20050020, 0x22040020, 0x22050020, 0x20002000, 0x20012000, 0x22002000, 0x22012000, 0x20002020, 0x20012020, 0x22002020, 0x22012020, 0x20042000, 0x20052000, 0x22042000, 0x22052000, 0x20042020, 0x20052020, 0x22042020, 0x22052020, 0x20000010, 0x20010010, 0x22000010, 0x22010010, 0x20000030, 0x20010030, 0x22000030, 0x22010030, 0x20040010, 0x20050010, 0x22040010, 0x22050010, 0x20040030, 0x20050030, 0x22040030, 0x22050030, 0x20002010, 0x20012010, 0x22002010, 0x22012010, 0x20002030, 0x20012030, 0x22002030, 0x22012030, 0x20042010, 0x20052010, 0x22042010, 0x22052010, 0x20042030, 0x20052030, 0x22042030, 0x22052030, 0x20000010, 0x20010010, 0x22000010, 0x22010010, 0x20000030, 0x20010030, 0x22000030, 0x22010030, 0x20040010, 0x20050010, 0x22040010, 0x22050010, 0x20040030, 0x20050030, 0x22040030, 0x22050030, 0x20002010, 0x20012010, 0x22002010, 0x22012010, 0x20002030, 0x20012030, 0x22002030, 0x22012030, 0x20042010, 0x20052010, 0x22042010, 0x22052010, 0x20042030, 0x20052030, 0x22042030, 0x22052030 ]; static $pc2mapd4 = [ 0x00000000, 0x00000400, 0x01000000, 0x01000400, 0x00000000, 0x00000400, 0x01000000, 0x01000400, 0x00000100, 0x00000500, 0x01000100, 0x01000500, 0x00000100, 0x00000500, 0x01000100, 0x01000500, 0x10000000, 0x10000400, 0x11000000, 0x11000400, 0x10000000, 0x10000400, 0x11000000, 0x11000400, 0x10000100, 0x10000500, 0x11000100, 0x11000500, 0x10000100, 0x10000500, 0x11000100, 0x11000500, 0x00080000, 0x00080400, 0x01080000, 0x01080400, 0x00080000, 0x00080400, 0x01080000, 0x01080400, 0x00080100, 0x00080500, 0x01080100, 0x01080500, 0x00080100, 0x00080500, 0x01080100, 0x01080500, 0x10080000, 0x10080400, 0x11080000, 0x11080400, 0x10080000, 0x10080400, 0x11080000, 0x11080400, 0x10080100, 0x10080500, 0x11080100, 0x11080500, 0x10080100, 0x10080500, 0x11080100, 0x11080500, 0x00000008, 0x00000408, 0x01000008, 0x01000408, 0x00000008, 0x00000408, 0x01000008, 0x01000408, 0x00000108, 0x00000508, 0x01000108, 0x01000508, 0x00000108, 0x00000508, 0x01000108, 0x01000508, 0x10000008, 0x10000408, 0x11000008, 0x11000408, 0x10000008, 0x10000408, 0x11000008, 0x11000408, 0x10000108, 0x10000508, 0x11000108, 0x11000508, 0x10000108, 0x10000508, 0x11000108, 0x11000508, 0x00080008, 0x00080408, 0x01080008, 0x01080408, 0x00080008, 0x00080408, 0x01080008, 0x01080408, 0x00080108, 0x00080508, 0x01080108, 0x01080508, 0x00080108, 0x00080508, 0x01080108, 0x01080508, 0x10080008, 0x10080408, 0x11080008, 0x11080408, 0x10080008, 0x10080408, 0x11080008, 0x11080408, 0x10080108, 0x10080508, 0x11080108, 0x11080508, 0x10080108, 0x10080508, 0x11080108, 0x11080508, 0x00001000, 0x00001400, 0x01001000, 0x01001400, 0x00001000, 0x00001400, 0x01001000, 0x01001400, 0x00001100, 0x00001500, 0x01001100, 0x01001500, 0x00001100, 0x00001500, 0x01001100, 0x01001500, 0x10001000, 0x10001400, 0x11001000, 0x11001400, 0x10001000, 0x10001400, 0x11001000, 0x11001400, 0x10001100, 0x10001500, 0x11001100, 0x11001500, 0x10001100, 0x10001500, 0x11001100, 0x11001500, 0x00081000, 0x00081400, 0x01081000, 0x01081400, 0x00081000, 0x00081400, 0x01081000, 0x01081400, 0x00081100, 0x00081500, 0x01081100, 0x01081500, 0x00081100, 0x00081500, 0x01081100, 0x01081500, 0x10081000, 0x10081400, 0x11081000, 0x11081400, 0x10081000, 0x10081400, 0x11081000, 0x11081400, 0x10081100, 0x10081500, 0x11081100, 0x11081500, 0x10081100, 0x10081500, 0x11081100, 0x11081500, 0x00001008, 0x00001408, 0x01001008, 0x01001408, 0x00001008, 0x00001408, 0x01001008, 0x01001408, 0x00001108, 0x00001508, 0x01001108, 0x01001508, 0x00001108, 0x00001508, 0x01001108, 0x01001508, 0x10001008, 0x10001408, 0x11001008, 0x11001408, 0x10001008, 0x10001408, 0x11001008, 0x11001408, 0x10001108, 0x10001508, 0x11001108, 0x11001508, 0x10001108, 0x10001508, 0x11001108, 0x11001508, 0x00081008, 0x00081408, 0x01081008, 0x01081408, 0x00081008, 0x00081408, 0x01081008, 0x01081408, 0x00081108, 0x00081508, 0x01081108, 0x01081508, 0x00081108, 0x00081508, 0x01081108, 0x01081508, 0x10081008, 0x10081408, 0x11081008, 0x11081408, 0x10081008, 0x10081408, 0x11081008, 0x11081408, 0x10081108, 0x10081508, 0x11081108, 0x11081508, 0x10081108, 0x10081508, 0x11081108, 0x11081508 ]; $keys = []; for ($des_round = 0; $des_round < $this->des_rounds; ++$des_round) { // pad the key and remove extra characters as appropriate. $key = str_pad(substr($this->key, $des_round * 8, 8), 8, "\0"); // Perform the PC/1 transformation and compute C and D. $t = unpack('Nl/Nr', $key); list($l, $r) = [$t['l'], $t['r']]; $key = (self::$shuffle[$pc1map[ $r & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x00") | (self::$shuffle[$pc1map[($r >> 8) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x00") | (self::$shuffle[$pc1map[($r >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x00") | (self::$shuffle[$pc1map[($r >> 24) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x00") | (self::$shuffle[$pc1map[ $l & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x00") | (self::$shuffle[$pc1map[($l >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x00") | (self::$shuffle[$pc1map[($l >> 16) & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x00") | (self::$shuffle[$pc1map[($l >> 24) & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x00"); $key = unpack('Nc/Nd', $key); $c = ( $key['c'] >> 4) & 0x0FFFFFFF; $d = (($key['d'] >> 4) & 0x0FFFFFF0) | ($key['c'] & 0x0F); $keys[$des_round] = [ self::ENCRYPT => [], self::DECRYPT => array_fill(0, 32, 0) ]; for ($i = 0, $ki = 31; $i < 16; ++$i, $ki -= 2) { $c <<= $shifts[$i]; $c = ($c | ($c >> 28)) & 0x0FFFFFFF; $d <<= $shifts[$i]; $d = ($d | ($d >> 28)) & 0x0FFFFFFF; // Perform the PC-2 transformation. $cp = $pc2mapc1[ $c >> 24 ] | $pc2mapc2[($c >> 16) & 0xFF] | $pc2mapc3[($c >> 8) & 0xFF] | $pc2mapc4[ $c & 0xFF]; $dp = $pc2mapd1[ $d >> 24 ] | $pc2mapd2[($d >> 16) & 0xFF] | $pc2mapd3[($d >> 8) & 0xFF] | $pc2mapd4[ $d & 0xFF]; // Reorder: odd bytes/even bytes. Push the result in key schedule. $val1 = ( $cp & intval(0xFF000000)) | (($cp << 8) & 0x00FF0000) | (($dp >> 16) & 0x0000FF00) | (($dp >> 8) & 0x000000FF); $val2 = (($cp << 8) & intval(0xFF000000)) | (($cp << 16) & 0x00FF0000) | (($dp >> 8) & 0x0000FF00) | ( $dp & 0x000000FF); $keys[$des_round][self::ENCRYPT][ ] = $val1; $keys[$des_round][self::DECRYPT][$ki - 1] = $val1; $keys[$des_round][self::ENCRYPT][ ] = $val2; $keys[$des_round][self::DECRYPT][$ki ] = $val2; } } switch ($this->des_rounds) { case 3: // 3DES keys $this->keys = [ self::ENCRYPT => array_merge( $keys[0][self::ENCRYPT], $keys[1][self::DECRYPT], $keys[2][self::ENCRYPT] ), self::DECRYPT => array_merge( $keys[2][self::DECRYPT], $keys[1][self::ENCRYPT], $keys[0][self::DECRYPT] ) ]; break; // case 1: // DES keys default: $this->keys = [ self::ENCRYPT => $keys[0][self::ENCRYPT], self::DECRYPT => $keys[0][self::DECRYPT] ]; } } /** * Setup the performance-optimized function for de/encrypt() * * @see Common\SymmetricKey::setupInlineCrypt() */ protected function setupInlineCrypt() { // Engine configuration for: // - DES ($des_rounds == 1) or // - 3DES ($des_rounds == 3) $des_rounds = $this->des_rounds; $init_crypt = 'static $sbox1, $sbox2, $sbox3, $sbox4, $sbox5, $sbox6, $sbox7, $sbox8, $shuffleip, $shuffleinvip; if (!$sbox1) { $sbox1 = array_map("intval", self::$sbox1); $sbox2 = array_map("intval", self::$sbox2); $sbox3 = array_map("intval", self::$sbox3); $sbox4 = array_map("intval", self::$sbox4); $sbox5 = array_map("intval", self::$sbox5); $sbox6 = array_map("intval", self::$sbox6); $sbox7 = array_map("intval", self::$sbox7); $sbox8 = array_map("intval", self::$sbox8);' /* Merge $shuffle with $[inv]ipmap */ . ' for ($i = 0; $i < 256; ++$i) { $shuffleip[] = self::$shuffle[self::$ipmap[$i]]; $shuffleinvip[] = self::$shuffle[self::$invipmap[$i]]; } } '; $k = [ self::ENCRYPT => $this->keys[self::ENCRYPT], self::DECRYPT => $this->keys[self::DECRYPT] ]; $init_encrypt = ''; $init_decrypt = ''; // Creating code for en- and decryption. $crypt_block = []; foreach ([self::ENCRYPT, self::DECRYPT] as $c) { /* Do the initial IP permutation. */ $crypt_block[$c] = ' $in = unpack("N*", $in); $l = $in[1]; $r = $in[2]; $in = unpack("N*", ($shuffleip[ $r & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") | ($shuffleip[($r >> 8) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") | ($shuffleip[($r >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") | ($shuffleip[($r >> 24) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") | ($shuffleip[ $l & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") | ($shuffleip[($l >> 8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") | ($shuffleip[($l >> 16) & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") | ($shuffleip[($l >> 24) & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01") ); ' . /* Extract L0 and R0 */ ' $l = $in[1]; $r = $in[2]; '; $l = '$l'; $r = '$r'; // Perform DES or 3DES. for ($ki = -1, $des_round = 0; $des_round < $des_rounds; ++$des_round) { // Perform the 16 steps. for ($i = 0; $i < 16; ++$i) { // start of "the Feistel (F) function" - see the following URL: // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png // Merge key schedule. $crypt_block[$c] .= ' $b1 = ((' . $r . ' >> 3) & 0x1FFFFFFF) ^ (' . $r . ' << 29) ^ ' . $k[$c][++$ki] . '; $b2 = ((' . $r . ' >> 31) & 0x00000001) ^ (' . $r . ' << 1) ^ ' . $k[$c][++$ki] . ';' . /* S-box indexing. */ $l . ' = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^ $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^ $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^ $sbox7[ $b1 & 0x3F] ^ $sbox8[ $b2 & 0x3F] ^ ' . $l . '; '; // end of "the Feistel (F) function" // swap L & R list($l, $r) = [$r, $l]; } list($l, $r) = [$r, $l]; } // Perform the inverse IP permutation. $crypt_block[$c] .= '$in = ($shuffleinvip[($l >> 24) & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") | ($shuffleinvip[($r >> 24) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") | ($shuffleinvip[($l >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") | ($shuffleinvip[($r >> 16) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") | ($shuffleinvip[($l >> 8) & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") | ($shuffleinvip[($r >> 8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") | ($shuffleinvip[ $l & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") | ($shuffleinvip[ $r & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01"); '; } // Creates the inline-crypt function $this->inline_crypt = $this->createInlineCryptFunction( [ 'init_crypt' => $init_crypt, 'init_encrypt' => $init_encrypt, 'init_decrypt' => $init_decrypt, 'encrypt_block' => $crypt_block[self::ENCRYPT], 'decrypt_block' => $crypt_block[self::DECRYPT] ] ); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS1.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\DH\Formats\Keys; use phpseclib3\Crypt\Common\Formats\Keys\PKCS1 as Progenitor; use phpseclib3\File\ASN1; use phpseclib3\File\ASN1\Maps; use phpseclib3\Math\BigInteger; /** * "PKCS1" Formatted DH Key Handler * * @author Jim Wigginton */ abstract class PKCS1 extends Progenitor { /** * Break a public or private key down into its constituent components * * @param string $key * @param string $password optional * @return array */ public static function load($key, $password = '') { $key = parent::load($key, $password); $decoded = ASN1::decodeBER($key); if (!$decoded) { throw new \RuntimeException('Unable to decode BER'); } $components = ASN1::asn1map($decoded[0], Maps\DHParameter::MAP); if (!is_array($components)) { throw new \RuntimeException('Unable to perform ASN1 mapping on parameters'); } return $components; } /** * Convert EC parameters to the appropriate format * * @return string */ public static function saveParameters(BigInteger $prime, BigInteger $base, array $options = []) { $params = [ 'prime' => $prime, 'base' => $base ]; $params = ASN1::encodeDER($params, Maps\DHParameter::MAP); return "-----BEGIN DH PARAMETERS-----\r\n" . chunk_split(base64_encode($params), 64) . "-----END DH PARAMETERS-----\r\n"; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS8.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\DH\Formats\Keys; use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; use phpseclib3\File\ASN1; use phpseclib3\File\ASN1\Maps; use phpseclib3\Math\BigInteger; /** * PKCS#8 Formatted DH Key Handler * * @author Jim Wigginton */ abstract class PKCS8 extends Progenitor { /** * OID Name * * @var string */ const OID_NAME = 'dhKeyAgreement'; /** * OID Value * * @var string */ const OID_VALUE = '1.2.840.113549.1.3.1'; /** * Child OIDs loaded * * @var bool */ protected static $childOIDsLoaded = false; /** * Break a public or private key down into its constituent components * * @param string $key * @param string $password optional * @return array */ public static function load($key, $password = '') { $key = parent::load($key, $password); $type = isset($key['privateKey']) ? 'privateKey' : 'publicKey'; $decoded = ASN1::decodeBER($key[$type . 'Algorithm']['parameters']->element); if (empty($decoded)) { throw new \RuntimeException('Unable to decode BER of parameters'); } $components = ASN1::asn1map($decoded[0], Maps\DHParameter::MAP); if (!is_array($components)) { throw new \RuntimeException('Unable to perform ASN1 mapping on parameters'); } $decoded = ASN1::decodeBER($key[$type]); switch (true) { case !isset($decoded): case !isset($decoded[0]['content']): case !$decoded[0]['content'] instanceof BigInteger: throw new \RuntimeException('Unable to decode BER of parameters'); } $components[$type] = $decoded[0]['content']; return $components; } /** * Convert a private key to the appropriate format. * * @param BigInteger $prime * @param BigInteger $base * @param BigInteger $privateKey * @param BigInteger $publicKey * @param string $password optional * @param array $options optional * @return string */ public static function savePrivateKey(BigInteger $prime, BigInteger $base, BigInteger $privateKey, BigInteger $publicKey, $password = '', array $options = []) { $params = [ 'prime' => $prime, 'base' => $base ]; $params = ASN1::encodeDER($params, Maps\DHParameter::MAP); $params = new ASN1\Element($params); $key = ASN1::encodeDER($privateKey, ['type' => ASN1::TYPE_INTEGER]); return self::wrapPrivateKey($key, [], $params, $password, null, '', $options); } /** * Convert a public key to the appropriate format * * @param BigInteger $prime * @param BigInteger $base * @param BigInteger $publicKey * @param array $options optional * @return string */ public static function savePublicKey(BigInteger $prime, BigInteger $base, BigInteger $publicKey, array $options = []) { $params = [ 'prime' => $prime, 'base' => $base ]; $params = ASN1::encodeDER($params, Maps\DHParameter::MAP); $params = new ASN1\Element($params); $key = ASN1::encodeDER($publicKey, ['type' => ASN1::TYPE_INTEGER]); return self::wrapPublicKey($key, $params, null, $options); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Parameters.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\DH; use phpseclib3\Crypt\DH; /** * DH Parameters * * @author Jim Wigginton */ final class Parameters extends DH { /** * Returns the parameters * * @param string $type * @param array $options optional * @return string */ public function toString($type = 'PKCS1', array $options = []) { $type = self::validatePlugin('Keys', 'PKCS1', 'saveParameters'); return $type::saveParameters($this->prime, $this->base, $options); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PrivateKey.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\DH; use phpseclib3\Crypt\Common; use phpseclib3\Crypt\DH; /** * DH Private Key * * @author Jim Wigginton */ final class PrivateKey extends DH { use Common\Traits\PasswordProtected; /** * Private Key * * @var \phpseclib3\Math\BigInteger */ protected $privateKey; /** * Public Key * * @var \phpseclib3\Math\BigInteger */ protected $publicKey; /** * Returns the public key * * @return PublicKey */ public function getPublicKey() { $type = self::validatePlugin('Keys', 'PKCS8', 'savePublicKey'); if (!isset($this->publicKey)) { $this->publicKey = $this->base->powMod($this->privateKey, $this->prime); } $key = $type::savePublicKey($this->prime, $this->base, $this->publicKey); return DH::loadFormat('PKCS8', $key); } /** * Returns the private key * * @param string $type * @param array $options optional * @return string */ public function toString($type, array $options = []) { $type = self::validatePlugin('Keys', $type, 'savePrivateKey'); if (!isset($this->publicKey)) { $this->publicKey = $this->base->powMod($this->privateKey, $this->prime); } return $type::savePrivateKey($this->prime, $this->base, $this->privateKey, $this->publicKey, $this->password, $options); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PublicKey.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\DH; use phpseclib3\Crypt\Common; use phpseclib3\Crypt\DH; /** * DH Public Key * * @author Jim Wigginton */ final class PublicKey extends DH { use Common\Traits\Fingerprint; /** * Returns the public key * * @param string $type * @param array $options optional * @return string */ public function toString($type, array $options = []) { $type = self::validatePlugin('Keys', $type, 'savePublicKey'); return $type::savePublicKey($this->prime, $this->base, $this->publicKey, $options); } /** * Returns the public key as a BigInteger * * @return \phpseclib3\Math\BigInteger */ public function toBigInteger() { return $this->publicKey; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH.php ================================================ * * * * @author Jim Wigginton * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt; use phpseclib3\Crypt\Common\AsymmetricKey; use phpseclib3\Crypt\DH\Parameters; use phpseclib3\Crypt\DH\PrivateKey; use phpseclib3\Crypt\DH\PublicKey; use phpseclib3\Exception\NoKeyLoadedException; use phpseclib3\Exception\UnsupportedOperationException; use phpseclib3\Math\BigInteger; /** * Pure-PHP (EC)DH implementation * * @author Jim Wigginton */ abstract class DH extends AsymmetricKey { /** * Algorithm Name * * @var string */ const ALGORITHM = 'DH'; /** * DH prime * * @var BigInteger */ protected $prime; /** * DH Base * * Prime divisor of p-1 * * @var BigInteger */ protected $base; /** * Public Key * * @var BigInteger */ protected $publicKey; /** * Create DH parameters * * This method is a bit polymorphic. It can take any of the following: * - two BigInteger's (prime and base) * - an integer representing the size of the prime in bits (the base is assumed to be 2) * - a string (eg. diffie-hellman-group14-sha1) * * @return Parameters */ public static function createParameters(...$args) { $class = new \ReflectionClass(static::class); if ($class->isFinal()) { throw new \RuntimeException('createParameters() should not be called from final classes (' . static::class . ')'); } $params = new Parameters(); if (count($args) == 2 && $args[0] instanceof BigInteger && $args[1] instanceof BigInteger) { //if (!$args[0]->isPrime()) { // throw new \InvalidArgumentException('The first parameter should be a prime number'); //} $params->prime = $args[0]; $params->base = $args[1]; return $params; } elseif (count($args) == 1 && is_numeric($args[0])) { $params->prime = BigInteger::randomPrime($args[0]); $params->base = new BigInteger(2); return $params; } elseif (count($args) != 1 || !is_string($args[0])) { throw new \InvalidArgumentException('Valid parameters are either: two BigInteger\'s (prime and base), a single integer (the length of the prime; base is assumed to be 2) or a string'); } switch ($args[0]) { // see http://tools.ietf.org/html/rfc2409#section-6.2 and // http://tools.ietf.org/html/rfc2412, appendex E case 'diffie-hellman-group1-sha1': $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF'; break; // see http://tools.ietf.org/html/rfc3526#section-3 case 'diffie-hellman-group14-sha1': // 2048-bit MODP Group case 'diffie-hellman-group14-sha256': $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' . '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' . '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' . 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' . '3995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF'; break; // see https://tools.ietf.org/html/rfc3526#section-4 case 'diffie-hellman-group15-sha512': // 3072-bit MODP Group $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' . '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' . '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' . 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' . '3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33' . 'A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7' . 'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864' . 'D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E2' . '08E24FA074E5AB3143DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF'; break; // see https://tools.ietf.org/html/rfc3526#section-5 case 'diffie-hellman-group16-sha512': // 4096-bit MODP Group $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' . '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' . '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' . 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' . '3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33' . 'A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7' . 'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864' . 'D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E2' . '08E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7' . '88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8' . 'DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2' . '233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9' . '93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199FFFFFFFFFFFFFFFF'; break; // see https://tools.ietf.org/html/rfc3526#section-6 case 'diffie-hellman-group17-sha512': // 6144-bit MODP Group $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' . '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' . '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' . 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' . '3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33' . 'A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7' . 'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864' . 'D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E2' . '08E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7' . '88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8' . 'DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2' . '233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9' . '93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C93402849236C3FAB4D27C7026' . 'C1D4DCB2602646DEC9751E763DBA37BDF8FF9406AD9E530EE5DB382F413001AE' . 'B06A53ED9027D831179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B' . 'DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF5983CA01C64B92EC' . 'F032EA15D1721D03F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E' . '59E7C97FBEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA' . 'CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58BB7C5DA76' . 'F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632387FE8D76E3C0468' . '043E8F663F4860EE12BF2D5B0B7474D6E694F91E6DCC4024FFFFFFFFFFFFFFFF'; break; // see https://tools.ietf.org/html/rfc3526#section-7 case 'diffie-hellman-group18-sha512': // 8192-bit MODP Group $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' . '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' . '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' . 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' . '3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33' . 'A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7' . 'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864' . 'D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E2' . '08E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7' . '88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8' . 'DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2' . '233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9' . '93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C93402849236C3FAB4D27C7026' . 'C1D4DCB2602646DEC9751E763DBA37BDF8FF9406AD9E530EE5DB382F413001AE' . 'B06A53ED9027D831179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B' . 'DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF5983CA01C64B92EC' . 'F032EA15D1721D03F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E' . '59E7C97FBEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA' . 'CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58BB7C5DA76' . 'F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632387FE8D76E3C0468' . '043E8F663F4860EE12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E4' . '38777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300741FA7BF8AFC47ED' . '2576F6936BA424663AAB639C5AE4F5683423B4742BF1C978238F16CBE39D652D' . 'E3FDB8BEFC848AD922222E04A4037C0713EB57A81A23F0C73473FC646CEA306B' . '4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A062B3CF5B3A278A6' . '6D2A13F83F44F82DDF310EE074AB6A364597E899A0255DC164F31CC50846851D' . 'F9AB48195DED7EA1B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F92' . '4009438B481C6CD7889A002ED5EE382BC9190DA6FC026E479558E4475677E9AA' . '9E3050E2765694DFC81F56E880B96E7160C980DD98EDD3DFFFFFFFFFFFFFFFFF'; break; default: throw new \InvalidArgumentException('Invalid named prime provided'); } $params->prime = new BigInteger($prime, 16); $params->base = new BigInteger(2); return $params; } /** * Create public / private key pair. * * The rationale for the second parameter is described in http://tools.ietf.org/html/rfc4419#section-6.2 : * * "To increase the speed of the key exchange, both client and server may * reduce the size of their private exponents. It should be at least * twice as long as the key material that is generated from the shared * secret. For more details, see the paper by van Oorschot and Wiener * [VAN-OORSCHOT]." * * $length is in bits * * @param Parameters $params * @param int $length optional * @return PrivateKey */ public static function createKey(Parameters $params, $length = 0) { $class = new \ReflectionClass(static::class); if ($class->isFinal()) { throw new \RuntimeException('createKey() should not be called from final classes (' . static::class . ')'); } $one = new BigInteger(1); if ($length) { $max = $one->bitwise_leftShift($length); $max = $max->subtract($one); } else { $max = $params->prime->subtract($one); } $key = new PrivateKey(); $key->prime = $params->prime; $key->base = $params->base; $key->privateKey = BigInteger::randomRange($one, $max); $key->publicKey = $key->base->powMod($key->privateKey, $key->prime); return $key; } /** * Compute Shared Secret * * @param PrivateKey|EC $private * @param PublicKey|BigInteger|string $public * @return mixed */ public static function computeSecret($private, $public) { if ($private instanceof PrivateKey) { // DH\PrivateKey switch (true) { case $public instanceof PublicKey: if (!$private->prime->equals($public->prime) || !$private->base->equals($public->base)) { throw new \InvalidArgumentException('The public and private key do not share the same prime and / or base numbers'); } return $public->publicKey->powMod($private->privateKey, $private->prime)->toBytes(true); case is_string($public): $public = new BigInteger($public, -256); // fall-through case $public instanceof BigInteger: return $public->powMod($private->privateKey, $private->prime)->toBytes(true); default: throw new \InvalidArgumentException('$public needs to be an instance of DH\PublicKey, a BigInteger or a string'); } } if ($private instanceof EC\PrivateKey) { switch (true) { case $public instanceof EC\PublicKey: $public = $public->getEncodedCoordinates(); // fall-through case is_string($public): $point = $private->multiply($public); switch ($private->getCurve()) { case 'Curve25519': case 'Curve448': $secret = $point; break; default: // according to https://www.secg.org/sec1-v2.pdf#page=33 only X is returned $secret = substr($point, 1, (strlen($point) - 1) >> 1); } /* if (($secret[0] & "\x80") === "\x80") { $secret = "\0$secret"; } */ return $secret; default: throw new \InvalidArgumentException('$public needs to be an instance of EC\PublicKey or a string (an encoded coordinate)'); } } } /** * Load the key * * @param string $key * @param string $password optional * @return AsymmetricKey */ public static function load($key, $password = false) { try { return EC::load($key, $password); } catch (NoKeyLoadedException $e) { } return parent::load($key, $password); } /** * OnLoad Handler * * @return bool */ protected static function onLoad(array $components) { if (!isset($components['privateKey']) && !isset($components['publicKey'])) { $new = new Parameters(); } else { $new = isset($components['privateKey']) ? new PrivateKey() : new PublicKey(); } $new->prime = $components['prime']; $new->base = $components['base']; if (isset($components['privateKey'])) { $new->privateKey = $components['privateKey']; } if (isset($components['publicKey'])) { $new->publicKey = $components['publicKey']; } return $new; } /** * Determines which hashing function should be used * * @param string $hash */ public function withHash($hash) { throw new UnsupportedOperationException('DH does not use a hash algorithm'); } /** * Returns the hash algorithm currently being used * */ public function getHash() { throw new UnsupportedOperationException('DH does not use a hash algorithm'); } /** * Returns the parameters * * A public / private key is only returned if the currently loaded "key" contains an x or y * value. * * @see self::getPublicKey() * @return mixed */ public function getParameters() { $type = DH::validatePlugin('Keys', 'PKCS1', 'saveParameters'); $key = $type::saveParameters($this->prime, $this->base); return DH::load($key, 'PKCS1'); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/OpenSSH.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\DSA\Formats\Keys; use phpseclib3\Common\Functions\Strings; use phpseclib3\Crypt\Common\Formats\Keys\OpenSSH as Progenitor; use phpseclib3\Math\BigInteger; /** * OpenSSH Formatted DSA Key Handler * * @author Jim Wigginton */ abstract class OpenSSH extends Progenitor { /** * Supported Key Types * * @var array */ protected static $types = ['ssh-dss']; /** * Break a public or private key down into its constituent components * * @param string $key * @param string $password optional * @return array */ public static function load($key, $password = '') { $parsed = parent::load($key, $password); if (isset($parsed['paddedKey'])) { list($type) = Strings::unpackSSH2('s', $parsed['paddedKey']); if ($type != $parsed['type']) { throw new \RuntimeException("The public and private keys are not of the same type ($type vs $parsed[type])"); } list($p, $q, $g, $y, $x, $comment) = Strings::unpackSSH2('i5s', $parsed['paddedKey']); return compact('p', 'q', 'g', 'y', 'x', 'comment'); } list($p, $q, $g, $y) = Strings::unpackSSH2('iiii', $parsed['publicKey']); $comment = $parsed['comment']; return compact('p', 'q', 'g', 'y', 'comment'); } /** * Convert a public key to the appropriate format * * @param BigInteger $p * @param BigInteger $q * @param BigInteger $g * @param BigInteger $y * @param array $options optional * @return string */ public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, array $options = []) { if ($q->getLength() != 160) { throw new \InvalidArgumentException('SSH only supports keys with an N (length of Group Order q) of 160'); } // from : // string "ssh-dss" // mpint p // mpint q // mpint g // mpint y $DSAPublicKey = Strings::packSSH2('siiii', 'ssh-dss', $p, $q, $g, $y); if (isset($options['binary']) ? $options['binary'] : self::$binary) { return $DSAPublicKey; } $comment = isset($options['comment']) ? $options['comment'] : self::$comment; $DSAPublicKey = 'ssh-dss ' . base64_encode($DSAPublicKey) . ' ' . $comment; return $DSAPublicKey; } /** * Convert a private key to the appropriate format. * * @param BigInteger $p * @param BigInteger $q * @param BigInteger $g * @param BigInteger $y * @param BigInteger $x * @param string $password optional * @param array $options optional * @return string */ public static function savePrivateKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, BigInteger $x, $password = '', array $options = []) { $publicKey = self::savePublicKey($p, $q, $g, $y, ['binary' => true]); $privateKey = Strings::packSSH2('si5', 'ssh-dss', $p, $q, $g, $y, $x); return self::wrapPrivateKey($publicKey, $privateKey, $password, $options); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS1.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\DSA\Formats\Keys; use phpseclib3\Common\Functions\Strings; use phpseclib3\Crypt\Common\Formats\Keys\PKCS1 as Progenitor; use phpseclib3\File\ASN1; use phpseclib3\File\ASN1\Maps; use phpseclib3\Math\BigInteger; /** * PKCS#1 Formatted DSA Key Handler * * @author Jim Wigginton */ abstract class PKCS1 extends Progenitor { /** * Break a public or private key down into its constituent components * * @param string $key * @param string $password optional * @return array */ public static function load($key, $password = '') { $key = parent::load($key, $password); $decoded = ASN1::decodeBER($key); if (!$decoded) { throw new \RuntimeException('Unable to decode BER'); } $key = ASN1::asn1map($decoded[0], Maps\DSAParams::MAP); if (is_array($key)) { return $key; } $key = ASN1::asn1map($decoded[0], Maps\DSAPrivateKey::MAP); if (is_array($key)) { return $key; } $key = ASN1::asn1map($decoded[0], Maps\DSAPublicKey::MAP); if (is_array($key)) { return $key; } throw new \RuntimeException('Unable to perform ASN1 mapping'); } /** * Convert DSA parameters to the appropriate format * * @param BigInteger $p * @param BigInteger $q * @param BigInteger $g * @return string */ public static function saveParameters(BigInteger $p, BigInteger $q, BigInteger $g) { $key = [ 'p' => $p, 'q' => $q, 'g' => $g ]; $key = ASN1::encodeDER($key, Maps\DSAParams::MAP); return "-----BEGIN DSA PARAMETERS-----\r\n" . chunk_split(Strings::base64_encode($key), 64) . "-----END DSA PARAMETERS-----\r\n"; } /** * Convert a private key to the appropriate format. * * @param BigInteger $p * @param BigInteger $q * @param BigInteger $g * @param BigInteger $y * @param BigInteger $x * @param string $password optional * @param array $options optional * @return string */ public static function savePrivateKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, BigInteger $x, $password = '', array $options = []) { $key = [ 'version' => 0, 'p' => $p, 'q' => $q, 'g' => $g, 'y' => $y, 'x' => $x ]; $key = ASN1::encodeDER($key, Maps\DSAPrivateKey::MAP); return self::wrapPrivateKey($key, 'DSA', $password, $options); } /** * Convert a public key to the appropriate format * * @param BigInteger $p * @param BigInteger $q * @param BigInteger $g * @param BigInteger $y * @return string */ public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y) { $key = ASN1::encodeDER($y, Maps\DSAPublicKey::MAP); return self::wrapPublicKey($key, 'DSA'); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS8.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\DSA\Formats\Keys; use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; use phpseclib3\File\ASN1; use phpseclib3\File\ASN1\Maps; use phpseclib3\Math\BigInteger; /** * PKCS#8 Formatted DSA Key Handler * * @author Jim Wigginton */ abstract class PKCS8 extends Progenitor { /** * OID Name * * @var string */ const OID_NAME = 'id-dsa'; /** * OID Value * * @var string */ const OID_VALUE = '1.2.840.10040.4.1'; /** * Child OIDs loaded * * @var bool */ protected static $childOIDsLoaded = false; /** * Break a public or private key down into its constituent components * * @param string $key * @param string $password optional * @return array */ public static function load($key, $password = '') { $key = parent::load($key, $password); $type = isset($key['privateKey']) ? 'privateKey' : 'publicKey'; $decoded = ASN1::decodeBER($key[$type . 'Algorithm']['parameters']->element); if (!$decoded) { throw new \RuntimeException('Unable to decode BER of parameters'); } $components = ASN1::asn1map($decoded[0], Maps\DSAParams::MAP); if (!is_array($components)) { throw new \RuntimeException('Unable to perform ASN1 mapping on parameters'); } $decoded = ASN1::decodeBER($key[$type]); if (empty($decoded)) { throw new \RuntimeException('Unable to decode BER'); } $var = $type == 'privateKey' ? 'x' : 'y'; $components[$var] = ASN1::asn1map($decoded[0], Maps\DSAPublicKey::MAP); if (!$components[$var] instanceof BigInteger) { throw new \RuntimeException('Unable to perform ASN1 mapping'); } if (isset($key['meta'])) { $components['meta'] = $key['meta']; } return $components; } /** * Convert a private key to the appropriate format. * * @param BigInteger $p * @param BigInteger $q * @param BigInteger $g * @param BigInteger $y * @param BigInteger $x * @param string $password optional * @param array $options optional * @return string */ public static function savePrivateKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, BigInteger $x, $password = '', array $options = []) { $params = [ 'p' => $p, 'q' => $q, 'g' => $g ]; $params = ASN1::encodeDER($params, Maps\DSAParams::MAP); $params = new ASN1\Element($params); $key = ASN1::encodeDER($x, Maps\DSAPublicKey::MAP); return self::wrapPrivateKey($key, [], $params, $password, null, '', $options); } /** * Convert a public key to the appropriate format * * @param BigInteger $p * @param BigInteger $q * @param BigInteger $g * @param BigInteger $y * @param array $options optional * @return string */ public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, array $options = []) { $params = [ 'p' => $p, 'q' => $q, 'g' => $g ]; $params = ASN1::encodeDER($params, Maps\DSAParams::MAP); $params = new ASN1\Element($params); $key = ASN1::encodeDER($y, Maps\DSAPublicKey::MAP); return self::wrapPublicKey($key, $params, null, $options); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PuTTY.php ================================================ 160 kinda useless, hence this handlers not supporting such keys. * * PHP version 5 * * @author Jim Wigginton * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\DSA\Formats\Keys; use phpseclib3\Common\Functions\Strings; use phpseclib3\Crypt\Common\Formats\Keys\PuTTY as Progenitor; use phpseclib3\Math\BigInteger; /** * PuTTY Formatted DSA Key Handler * * @author Jim Wigginton */ abstract class PuTTY extends Progenitor { /** * Public Handler * * @var string */ const PUBLIC_HANDLER = 'phpseclib3\Crypt\DSA\Formats\Keys\OpenSSH'; /** * Algorithm Identifier * * @var array */ protected static $types = ['ssh-dss']; /** * Break a public or private key down into its constituent components * * @param string $key * @param string $password optional * @return array */ public static function load($key, $password = '') { $components = parent::load($key, $password); if (!isset($components['private'])) { return $components; } $type = $components['type']; $comment = $components['comment']; $public = $components['public']; $private = $components['private']; unset($components['public'], $components['private']); list($p, $q, $g, $y) = Strings::unpackSSH2('iiii', $public); list($x) = Strings::unpackSSH2('i', $private); return compact('p', 'q', 'g', 'y', 'x', 'comment'); } /** * Convert a private key to the appropriate format. * * @param BigInteger $p * @param BigInteger $q * @param BigInteger $g * @param BigInteger $y * @param BigInteger $x * @param string $password optional * @param array $options optional * @return string */ public static function savePrivateKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, BigInteger $x, $password = false, array $options = []) { if ($q->getLength() != 160) { throw new \InvalidArgumentException('SSH only supports keys with an N (length of Group Order q) of 160'); } $public = Strings::packSSH2('iiii', $p, $q, $g, $y); $private = Strings::packSSH2('i', $x); return self::wrapPrivateKey($public, $private, 'ssh-dss', $password, $options); } /** * Convert a public key to the appropriate format * * @param BigInteger $p * @param BigInteger $q * @param BigInteger $g * @param BigInteger $y * @return string */ public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y) { if ($q->getLength() != 160) { throw new \InvalidArgumentException('SSH only supports keys with an N (length of Group Order q) of 160'); } return self::wrapPublicKey(Strings::packSSH2('iiii', $p, $q, $g, $y), 'ssh-dss'); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/Raw.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\DSA\Formats\Keys; use phpseclib3\Math\BigInteger; /** * Raw DSA Key Handler * * @author Jim Wigginton */ abstract class Raw { /** * Break a public or private key down into its constituent components * * @param array $key * @param string $password optional * @return array */ public static function load($key, $password = '') { if (!is_array($key)) { throw new \UnexpectedValueException('Key should be a array - not a ' . gettype($key)); } switch (true) { case !isset($key['p']) || !isset($key['q']) || !isset($key['g']): case !$key['p'] instanceof BigInteger: case !$key['q'] instanceof BigInteger: case !$key['g'] instanceof BigInteger: case !isset($key['x']) && !isset($key['y']): case isset($key['x']) && !$key['x'] instanceof BigInteger: case isset($key['y']) && !$key['y'] instanceof BigInteger: throw new \UnexpectedValueException('Key appears to be malformed'); } $options = ['p' => 1, 'q' => 1, 'g' => 1, 'x' => 1, 'y' => 1]; return array_intersect_key($key, $options); } /** * Convert a private key to the appropriate format. * * @param BigInteger $p * @param BigInteger $q * @param BigInteger $g * @param BigInteger $y * @param BigInteger $x * @param string $password optional * @return string */ public static function savePrivateKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, BigInteger $x, $password = '') { return compact('p', 'q', 'g', 'y', 'x'); } /** * Convert a public key to the appropriate format * * @param BigInteger $p * @param BigInteger $q * @param BigInteger $g * @param BigInteger $y * @return string */ public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y) { return compact('p', 'q', 'g', 'y'); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/XML.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\DSA\Formats\Keys; use phpseclib3\Common\Functions\Strings; use phpseclib3\Exception\BadConfigurationException; use phpseclib3\Math\BigInteger; /** * XML Formatted DSA Key Handler * * @author Jim Wigginton */ abstract class XML { /** * Break a public or private key down into its constituent components * * @param string $key * @param string $password optional * @return array */ public static function load($key, $password = '') { if (!Strings::is_stringable($key)) { throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); } if (!class_exists('DOMDocument')) { throw new BadConfigurationException('The dom extension is not setup correctly on this system'); } $use_errors = libxml_use_internal_errors(true); $dom = new \DOMDocument(); if (substr($key, 0, 5) != '' . $key . ''; } if (!$dom->loadXML($key)) { libxml_use_internal_errors($use_errors); throw new \UnexpectedValueException('Key does not appear to contain XML'); } $xpath = new \DOMXPath($dom); $keys = ['p', 'q', 'g', 'y', 'j', 'seed', 'pgencounter']; foreach ($keys as $key) { // $dom->getElementsByTagName($key) is case-sensitive $temp = $xpath->query("//*[translate(local-name(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='$key']"); if (!$temp->length) { continue; } $value = new BigInteger(Strings::base64_decode($temp->item(0)->nodeValue), 256); switch ($key) { case 'p': // a prime modulus meeting the [DSS] requirements // Parameters P, Q, and G can be public and common to a group of users. They might be known // from application context. As such, they are optional but P and Q must either both appear // or both be absent $components['p'] = $value; break; case 'q': // an integer in the range 2**159 < Q < 2**160 which is a prime divisor of P-1 $components['q'] = $value; break; case 'g': // an integer with certain properties with respect to P and Q $components['g'] = $value; break; case 'y': // G**X mod P (where X is part of the private key and not made public) $components['y'] = $value; // the remaining options do not do anything case 'j': // (P - 1) / Q // Parameter J is available for inclusion solely for efficiency as it is calculatable from // P and Q case 'seed': // a DSA prime generation seed // Parameters seed and pgenCounter are used in the DSA prime number generation algorithm // specified in [DSS]. As such, they are optional but must either both be present or both // be absent case 'pgencounter': // a DSA prime generation counter } } libxml_use_internal_errors($use_errors); if (!isset($components['y'])) { throw new \UnexpectedValueException('Key is missing y component'); } switch (true) { case !isset($components['p']): case !isset($components['q']): case !isset($components['g']): return ['y' => $components['y']]; } return $components; } /** * Convert a public key to the appropriate format * * See https://www.w3.org/TR/xmldsig-core/#sec-DSAKeyValue * * @param BigInteger $p * @param BigInteger $q * @param BigInteger $g * @param BigInteger $y * @return string */ public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y) { return "\r\n" . '

' . Strings::base64_encode($p->toBytes()) . "

\r\n" . ' ' . Strings::base64_encode($q->toBytes()) . "\r\n" . ' ' . Strings::base64_encode($g->toBytes()) . "\r\n" . ' ' . Strings::base64_encode($y->toBytes()) . "\r\n" . '
'; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/ASN1.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\DSA\Formats\Signature; use phpseclib3\File\ASN1 as Encoder; use phpseclib3\File\ASN1\Maps; use phpseclib3\Math\BigInteger; /** * ASN1 Signature Handler * * @author Jim Wigginton */ abstract class ASN1 { /** * Loads a signature * * @param string $sig * @return array|bool */ public static function load($sig) { if (!is_string($sig)) { return false; } $decoded = Encoder::decodeBER($sig); if (empty($decoded)) { return false; } $components = Encoder::asn1map($decoded[0], Maps\DssSigValue::MAP); return $components; } /** * Returns a signature in the appropriate format * * @param BigInteger $r * @param BigInteger $s * @return string */ public static function save(BigInteger $r, BigInteger $s) { return Encoder::encodeDER(compact('r', 's'), Maps\DssSigValue::MAP); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/Raw.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\DSA\Formats\Signature; use phpseclib3\Crypt\Common\Formats\Signature\Raw as Progenitor; /** * Raw DSA Signature Handler * * @author Jim Wigginton */ abstract class Raw extends Progenitor { } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/SSH2.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\DSA\Formats\Signature; use phpseclib3\Common\Functions\Strings; use phpseclib3\Math\BigInteger; /** * SSH2 Signature Handler * * @author Jim Wigginton */ abstract class SSH2 { /** * Loads a signature * * @param string $sig * @return mixed */ public static function load($sig) { if (!is_string($sig)) { return false; } $result = Strings::unpackSSH2('ss', $sig); if ($result === false) { return false; } list($type, $blob) = $result; if ($type != 'ssh-dss' || strlen($blob) != 40) { return false; } return [ 'r' => new BigInteger(substr($blob, 0, 20), 256), 's' => new BigInteger(substr($blob, 20), 256) ]; } /** * Returns a signature in the appropriate format * * @param BigInteger $r * @param BigInteger $s * @return string */ public static function save(BigInteger $r, BigInteger $s) { if ($r->getLength() > 160 || $s->getLength() > 160) { return false; } return Strings::packSSH2( 'ss', 'ssh-dss', str_pad($r->toBytes(), 20, "\0", STR_PAD_LEFT) . str_pad($s->toBytes(), 20, "\0", STR_PAD_LEFT) ); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Parameters.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\DSA; use phpseclib3\Crypt\DSA; /** * DSA Parameters * * @author Jim Wigginton */ final class Parameters extends DSA { /** * Returns the parameters * * @param string $type * @param array $options optional * @return string */ public function toString($type = 'PKCS1', array $options = []) { $type = self::validatePlugin('Keys', 'PKCS1', 'saveParameters'); return $type::saveParameters($this->p, $this->q, $this->g, $options); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PrivateKey.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\DSA; use phpseclib3\Crypt\Common; use phpseclib3\Crypt\DSA; use phpseclib3\Crypt\DSA\Formats\Signature\ASN1 as ASN1Signature; use phpseclib3\Math\BigInteger; /** * DSA Private Key * * @author Jim Wigginton */ final class PrivateKey extends DSA implements Common\PrivateKey { use Common\Traits\PasswordProtected; /** * DSA secret exponent x * * @var BigInteger */ protected $x; /** * Returns the public key * * If you do "openssl rsa -in private.rsa -pubout -outform PEM" you get a PKCS8 formatted key * that contains a publicKeyAlgorithm AlgorithmIdentifier and a publicKey BIT STRING. * An AlgorithmIdentifier contains an OID and a parameters field. With RSA public keys this * parameters field is NULL. With DSA PKCS8 public keys it is not - it contains the p, q and g * variables. The publicKey BIT STRING contains, simply, the y variable. This can be verified * by getting a DSA PKCS8 public key: * * "openssl dsa -in private.dsa -pubout -outform PEM" * * ie. just swap out rsa with dsa in the rsa command above. * * A PKCS1 public key corresponds to the publicKey portion of the PKCS8 key. In the case of RSA * the publicKey portion /is/ the key. In the case of DSA it is not. You cannot verify a signature * without the parameters and the PKCS1 DSA public key format does not include the parameters. * * @see self::getPrivateKey() * @return mixed */ public function getPublicKey() { $type = self::validatePlugin('Keys', 'PKCS8', 'savePublicKey'); if (!isset($this->y)) { $this->y = $this->g->powMod($this->x, $this->p); } $key = $type::savePublicKey($this->p, $this->q, $this->g, $this->y); return DSA::loadFormat('PKCS8', $key) ->withHash($this->hash->getHash()) ->withSignatureFormat($this->shortFormat); } /** * Create a signature * * @see self::verify() * @param string $message * @return mixed */ public function sign($message) { $format = $this->sigFormat; if (self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods())) { $signature = ''; $result = openssl_sign($message, $signature, $this->toString('PKCS8'), $this->hash->getHash()); if ($result) { if ($this->shortFormat == 'ASN1') { return $signature; } $loaded = ASN1Signature::load($signature); $r = $loaded['r']; $s = $loaded['s']; return $format::save($r, $s); } } $h = $this->hash->hash($message); $h = $this->bits2int($h); while (true) { $k = BigInteger::randomRange(self::$one, $this->q->subtract(self::$one)); $r = $this->g->powMod($k, $this->p); list(, $r) = $r->divide($this->q); if ($r->equals(self::$zero)) { continue; } $kinv = $k->modInverse($this->q); $temp = $h->add($this->x->multiply($r)); $temp = $kinv->multiply($temp); list(, $s) = $temp->divide($this->q); if (!$s->equals(self::$zero)) { break; } } // the following is an RFC6979 compliant implementation of deterministic DSA // it's unused because it's mainly intended for use when a good CSPRNG isn't // available. if phpseclib's CSPRNG isn't good then even key generation is // suspect /* $h1 = $this->hash->hash($message); $k = $this->computek($h1); $r = $this->g->powMod($k, $this->p); list(, $r) = $r->divide($this->q); $kinv = $k->modInverse($this->q); $h1 = $this->bits2int($h1); $temp = $h1->add($this->x->multiply($r)); $temp = $kinv->multiply($temp); list(, $s) = $temp->divide($this->q); */ return $format::save($r, $s); } /** * Returns the private key * * @param string $type * @param array $options optional * @return string */ public function toString($type, array $options = []) { $type = self::validatePlugin('Keys', $type, 'savePrivateKey'); if (!isset($this->y)) { $this->y = $this->g->powMod($this->x, $this->p); } return $type::savePrivateKey($this->p, $this->q, $this->g, $this->y, $this->x, $this->password, $options); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PublicKey.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\DSA; use phpseclib3\Crypt\Common; use phpseclib3\Crypt\DSA; use phpseclib3\Crypt\DSA\Formats\Signature\ASN1 as ASN1Signature; /** * DSA Public Key * * @author Jim Wigginton */ final class PublicKey extends DSA implements Common\PublicKey { use Common\Traits\Fingerprint; /** * Verify a signature * * @see self::verify() * @param string $message * @param string $signature * @return mixed */ public function verify($message, $signature) { $format = $this->sigFormat; $params = $format::load($signature); if ($params === false || count($params) != 2) { return false; } $r = $params['r']; $s = $params['s']; if (self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods())) { $sig = $format != 'ASN1' ? ASN1Signature::save($r, $s) : $signature; $result = openssl_verify($message, $sig, $this->toString('PKCS8'), $this->hash->getHash()); if ($result != -1) { return (bool) $result; } } $q_1 = $this->q->subtract(self::$one); if (!$r->between(self::$one, $q_1) || !$s->between(self::$one, $q_1)) { return false; } $w = $s->modInverse($this->q); $h = $this->hash->hash($message); $h = $this->bits2int($h); list(, $u1) = $h->multiply($w)->divide($this->q); list(, $u2) = $r->multiply($w)->divide($this->q); $v1 = $this->g->powMod($u1, $this->p); $v2 = $this->y->powMod($u2, $this->p); list(, $v) = $v1->multiply($v2)->divide($this->p); list(, $v) = $v->divide($this->q); return $v->equals($r); } /** * Returns the public key * * @param string $type * @param array $options optional * @return string */ public function toString($type, array $options = []) { $type = self::validatePlugin('Keys', $type, 'savePublicKey'); return $type::savePublicKey($this->p, $this->q, $this->g, $this->y, $options); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA.php ================================================ * getPublicKey(); * * $plaintext = 'terrafrost'; * * $signature = $private->sign($plaintext); * * echo $public->verify($plaintext, $signature) ? 'verified' : 'unverified'; * ?> * * * @author Jim Wigginton * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt; use phpseclib3\Crypt\Common\AsymmetricKey; use phpseclib3\Crypt\DSA\Parameters; use phpseclib3\Crypt\DSA\PrivateKey; use phpseclib3\Crypt\DSA\PublicKey; use phpseclib3\Exception\InsufficientSetupException; use phpseclib3\Math\BigInteger; /** * Pure-PHP FIPS 186-4 compliant implementation of DSA. * * @author Jim Wigginton */ abstract class DSA extends AsymmetricKey { /** * Algorithm Name * * @var string */ const ALGORITHM = 'DSA'; /** * DSA Prime P * * @var BigInteger */ protected $p; /** * DSA Group Order q * * Prime divisor of p-1 * * @var BigInteger */ protected $q; /** * DSA Group Generator G * * @var BigInteger */ protected $g; /** * DSA public key value y * * @var BigInteger */ protected $y; /** * Signature Format * * @var string */ protected $sigFormat; /** * Signature Format (Short) * * @var string */ protected $shortFormat; /** * Create DSA parameters * * @param int $L * @param int $N * @return DSA|bool */ public static function createParameters($L = 2048, $N = 224) { self::initialize_static_variables(); $class = new \ReflectionClass(static::class); if ($class->isFinal()) { throw new \RuntimeException('createParameters() should not be called from final classes (' . static::class . ')'); } if (!isset(self::$engines['PHP'])) { self::useBestEngine(); } switch (true) { case $N == 160: /* in FIPS 186-1 and 186-2 N was fixed at 160 whereas K had an upper bound of 1024. RFC 4253 (SSH Transport Layer Protocol) references FIPS 186-2 and as such most SSH DSA implementations only support keys with an N of 160. puttygen let's you set the size of L (but not the size of N) and uses 2048 as the default L value. that's not really compliant with any of the FIPS standards, however, for the purposes of maintaining compatibility with puttygen, we'll support it */ //case ($L >= 512 || $L <= 1024) && (($L & 0x3F) == 0) && $N == 160: // FIPS 186-3 changed this as follows: //case $L == 1024 && $N == 160: case $L == 2048 && $N == 224: case $L == 2048 && $N == 256: case $L == 3072 && $N == 256: break; default: throw new \InvalidArgumentException('Invalid values for N and L'); } $two = new BigInteger(2); $q = BigInteger::randomPrime($N); $divisor = $q->multiply($two); do { $x = BigInteger::random($L); list(, $c) = $x->divide($divisor); $p = $x->subtract($c->subtract(self::$one)); } while ($p->getLength() != $L || !$p->isPrime()); $p_1 = $p->subtract(self::$one); list($e) = $p_1->divide($q); // quoting http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf#page=50 , // "h could be obtained from a random number generator or from a counter that // changes after each use". PuTTY (sshdssg.c) starts h off at 1 and increments // it on each loop. wikipedia says "commonly h = 2 is used" so we'll just do that $h = clone $two; while (true) { $g = $h->powMod($e, $p); if (!$g->equals(self::$one)) { break; } $h = $h->add(self::$one); } $dsa = new Parameters(); $dsa->p = $p; $dsa->q = $q; $dsa->g = $g; return $dsa; } /** * Create public / private key pair. * * This method is a bit polymorphic. It can take a DSA/Parameters object, L / N as two distinct parameters or * no parameters (at which point L and N will be generated with this method) * * Returns the private key, from which the publickey can be extracted * * @param int[] ...$args * @return PrivateKey */ public static function createKey(...$args) { self::initialize_static_variables(); $class = new \ReflectionClass(static::class); if ($class->isFinal()) { throw new \RuntimeException('createKey() should not be called from final classes (' . static::class . ')'); } if (!isset(self::$engines['PHP'])) { self::useBestEngine(); } if (count($args) == 2 && is_int($args[0]) && is_int($args[1])) { $params = self::createParameters($args[0], $args[1]); } elseif (count($args) == 1 && $args[0] instanceof Parameters) { $params = $args[0]; } elseif (!count($args)) { $params = self::createParameters(); } else { throw new InsufficientSetupException('Valid parameters are either two integers (L and N), a single DSA object or no parameters at all.'); } $private = new PrivateKey(); $private->p = $params->p; $private->q = $params->q; $private->g = $params->g; $private->x = BigInteger::randomRange(self::$one, $private->q->subtract(self::$one)); $private->y = $private->g->powMod($private->x, $private->p); //$public = clone $private; //unset($public->x); return $private ->withHash($params->hash->getHash()) ->withSignatureFormat($params->shortFormat); } /** * OnLoad Handler * * @return bool */ protected static function onLoad(array $components) { if (!isset(self::$engines['PHP'])) { self::useBestEngine(); } if (!isset($components['x']) && !isset($components['y'])) { $new = new Parameters(); } elseif (isset($components['x'])) { $new = new PrivateKey(); $new->x = $components['x']; } else { $new = new PublicKey(); } $new->p = $components['p']; $new->q = $components['q']; $new->g = $components['g']; if (isset($components['y'])) { $new->y = $components['y']; } return $new; } /** * Constructor * * PublicKey and PrivateKey objects can only be created from abstract RSA class */ protected function __construct() { $this->sigFormat = self::validatePlugin('Signature', 'ASN1'); $this->shortFormat = 'ASN1'; parent::__construct(); } /** * Returns the key size * * More specifically, this L (the length of DSA Prime P) and N (the length of DSA Group Order q) * * @return array */ public function getLength() { return ['L' => $this->p->getLength(), 'N' => $this->q->getLength()]; } /** * Returns the current engine being used * * @see self::useInternalEngine() * @see self::useBestEngine() * @return string */ public function getEngine() { if (!isset(self::$engines['PHP'])) { self::useBestEngine(); } return self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods()) ? 'OpenSSL' : 'PHP'; } /** * Returns the parameters * * A public / private key is only returned if the currently loaded "key" contains an x or y * value. * * @see self::getPublicKey() * @return mixed */ public function getParameters() { $type = self::validatePlugin('Keys', 'PKCS1', 'saveParameters'); $key = $type::saveParameters($this->p, $this->q, $this->g); return DSA::load($key, 'PKCS1') ->withHash($this->hash->getHash()) ->withSignatureFormat($this->shortFormat); } /** * Determines the signature padding mode * * Valid values are: ASN1, SSH2, Raw * * @param string $format */ public function withSignatureFormat($format) { $new = clone $this; $new->shortFormat = $format; $new->sigFormat = self::validatePlugin('Signature', $format); return $new; } /** * Returns the signature format currently being used * */ public function getSignatureFormat() { return $this->shortFormat; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Base.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\BaseCurves; use phpseclib3\Math\BigInteger; /** * Base * * @author Jim Wigginton */ abstract class Base { /** * The Order * * @var BigInteger */ protected $order; /** * Finite Field Integer factory * * @var FiniteField\Integer */ protected $factory; /** * Returns a random integer * * @return object */ public function randomInteger() { return $this->factory->randomInteger(); } /** * Converts a BigInteger to a FiniteField\Integer integer * * @return object */ public function convertInteger(BigInteger $x) { return $this->factory->newInteger($x); } /** * Returns the length, in bytes, of the modulo * * @return integer */ public function getLengthInBytes() { return $this->factory->getLengthInBytes(); } /** * Returns the length, in bits, of the modulo * * @return integer */ public function getLength() { return $this->factory->getLength(); } /** * Multiply a point on the curve by a scalar * * Uses the montgomery ladder technique as described here: * * https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication#Montgomery_ladder * https://github.com/phpecc/phpecc/issues/16#issuecomment-59176772 * * @return array */ public function multiplyPoint(array $p, BigInteger $d) { $alreadyInternal = isset($p[2]); $r = $alreadyInternal ? [[], $p] : [[], $this->convertToInternal($p)]; $d = $d->toBits(); for ($i = 0; $i < strlen($d); $i++) { $d_i = (int) $d[$i]; $r[1 - $d_i] = $this->addPoint($r[0], $r[1]); $r[$d_i] = $this->doublePoint($r[$d_i]); } return $alreadyInternal ? $r[0] : $this->convertToAffine($r[0]); } /** * Creates a random scalar multiplier * * @return BigInteger */ public function createRandomMultiplier() { static $one; if (!isset($one)) { $one = new BigInteger(1); } return BigInteger::randomRange($one, $this->order->subtract($one)); } /** * Performs range check */ public function rangeCheck(BigInteger $x) { static $zero; if (!isset($zero)) { $zero = new BigInteger(); } if (!isset($this->order)) { throw new \RuntimeException('setOrder needs to be called before this method'); } if ($x->compare($this->order) > 0 || $x->compare($zero) <= 0) { throw new \RangeException('x must be between 1 and the order of the curve'); } } /** * Sets the Order */ public function setOrder(BigInteger $order) { $this->order = $order; } /** * Returns the Order * * @return BigInteger */ public function getOrder() { return $this->order; } /** * Use a custom defined modular reduction function * * @return object */ public function setReduction(callable $func) { $this->factory->setReduction($func); } /** * Returns the affine point * * @return object[] */ public function convertToAffine(array $p) { return $p; } /** * Converts an affine point to a jacobian coordinate * * @return object[] */ public function convertToInternal(array $p) { return $p; } /** * Negates a point * * @return object[] */ public function negatePoint(array $p) { $temp = [ $p[0], $p[1]->negate() ]; if (isset($p[2])) { $temp[] = $p[2]; } return $temp; } /** * Multiply and Add Points * * @return int[] */ public function multiplyAddPoints(array $points, array $scalars) { $p1 = $this->convertToInternal($points[0]); $p2 = $this->convertToInternal($points[1]); $p1 = $this->multiplyPoint($p1, $scalars[0]); $p2 = $this->multiplyPoint($p2, $scalars[1]); $r = $this->addPoint($p1, $p2); return $this->convertToAffine($r); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Binary.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\BaseCurves; use phpseclib3\Math\BigInteger; use phpseclib3\Math\BinaryField; use phpseclib3\Math\BinaryField\Integer as BinaryInteger; /** * Curves over y^2 + x*y = x^3 + a*x^2 + b * * @author Jim Wigginton */ class Binary extends Base { /** * Binary Field Integer factory * * @var BinaryField */ protected $factory; /** * Cofficient for x^1 * * @var object */ protected $a; /** * Cofficient for x^0 * * @var object */ protected $b; /** * Base Point * * @var object */ protected $p; /** * The number one over the specified finite field * * @var object */ protected $one; /** * The modulo * * @var BigInteger */ protected $modulo; /** * The Order * * @var BigInteger */ protected $order; /** * Sets the modulo */ public function setModulo(...$modulo) { $this->modulo = $modulo; $this->factory = new BinaryField(...$modulo); $this->one = $this->factory->newInteger("\1"); } /** * Set coefficients a and b * * @param string $a * @param string $b */ public function setCoefficients($a, $b) { if (!isset($this->factory)) { throw new \RuntimeException('setModulo needs to be called before this method'); } $this->a = $this->factory->newInteger(pack('H*', $a)); $this->b = $this->factory->newInteger(pack('H*', $b)); } /** * Set x and y coordinates for the base point * * @param string|BinaryInteger $x * @param string|BinaryInteger $y */ public function setBasePoint($x, $y) { switch (true) { case !is_string($x) && !$x instanceof BinaryInteger: throw new \UnexpectedValueException('Argument 1 passed to Binary::setBasePoint() must be a string or an instance of BinaryField\Integer'); case !is_string($y) && !$y instanceof BinaryInteger: throw new \UnexpectedValueException('Argument 2 passed to Binary::setBasePoint() must be a string or an instance of BinaryField\Integer'); } if (!isset($this->factory)) { throw new \RuntimeException('setModulo needs to be called before this method'); } $this->p = [ is_string($x) ? $this->factory->newInteger(pack('H*', $x)) : $x, is_string($y) ? $this->factory->newInteger(pack('H*', $y)) : $y ]; } /** * Retrieve the base point as an array * * @return array */ public function getBasePoint() { if (!isset($this->factory)) { throw new \RuntimeException('setModulo needs to be called before this method'); } /* if (!isset($this->p)) { throw new \RuntimeException('setBasePoint needs to be called before this method'); } */ return $this->p; } /** * Adds two points on the curve * * @return FiniteField[] */ public function addPoint(array $p, array $q) { if (!isset($this->factory)) { throw new \RuntimeException('setModulo needs to be called before this method'); } if (!count($p) || !count($q)) { if (count($q)) { return $q; } if (count($p)) { return $p; } return []; } if (!isset($p[2]) || !isset($q[2])) { throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); } if ($p[0]->equals($q[0])) { return !$p[1]->equals($q[1]) ? [] : $this->doublePoint($p); } // formulas from http://hyperelliptic.org/EFD/g12o/auto-shortw-jacobian.html list($x1, $y1, $z1) = $p; list($x2, $y2, $z2) = $q; $o1 = $z1->multiply($z1); $b = $x2->multiply($o1); if ($z2->equals($this->one)) { $d = $y2->multiply($o1)->multiply($z1); $e = $x1->add($b); $f = $y1->add($d); $z3 = $e->multiply($z1); $h = $f->multiply($x2)->add($z3->multiply($y2)); $i = $f->add($z3); $g = $z3->multiply($z3); $p1 = $this->a->multiply($g); $p2 = $f->multiply($i); $p3 = $e->multiply($e)->multiply($e); $x3 = $p1->add($p2)->add($p3); $y3 = $i->multiply($x3)->add($g->multiply($h)); return [$x3, $y3, $z3]; } $o2 = $z2->multiply($z2); $a = $x1->multiply($o2); $c = $y1->multiply($o2)->multiply($z2); $d = $y2->multiply($o1)->multiply($z1); $e = $a->add($b); $f = $c->add($d); $g = $e->multiply($z1); $h = $f->multiply($x2)->add($g->multiply($y2)); $z3 = $g->multiply($z2); $i = $f->add($z3); $p1 = $this->a->multiply($z3->multiply($z3)); $p2 = $f->multiply($i); $p3 = $e->multiply($e)->multiply($e); $x3 = $p1->add($p2)->add($p3); $y3 = $i->multiply($x3)->add($g->multiply($g)->multiply($h)); return [$x3, $y3, $z3]; } /** * Doubles a point on a curve * * @return FiniteField[] */ public function doublePoint(array $p) { if (!isset($this->factory)) { throw new \RuntimeException('setModulo needs to be called before this method'); } if (!count($p)) { return []; } if (!isset($p[2])) { throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); } // formulas from http://hyperelliptic.org/EFD/g12o/auto-shortw-jacobian.html list($x1, $y1, $z1) = $p; $a = $x1->multiply($x1); $b = $a->multiply($a); if ($z1->equals($this->one)) { $x3 = $b->add($this->b); $z3 = clone $x1; $p1 = $a->add($y1)->add($z3)->multiply($this->b); $p2 = $a->add($y1)->multiply($b); $y3 = $p1->add($p2); return [$x3, $y3, $z3]; } $c = $z1->multiply($z1); $d = $c->multiply($c); $x3 = $b->add($this->b->multiply($d->multiply($d))); $z3 = $x1->multiply($c); $p1 = $b->multiply($z3); $p2 = $a->add($y1->multiply($z1))->add($z3)->multiply($x3); $y3 = $p1->add($p2); return [$x3, $y3, $z3]; } /** * Returns the X coordinate and the derived Y coordinate * * Not supported because it is covered by patents. * Quoting https://www.openssl.org/docs/man1.1.0/apps/ecparam.html , * * "Due to patent issues the compressed option is disabled by default for binary curves * and can be enabled by defining the preprocessor macro OPENSSL_EC_BIN_PT_COMP at * compile time." * * @return array */ public function derivePoint($m) { throw new \RuntimeException('Point compression on binary finite field elliptic curves is not supported'); } /** * Tests whether or not the x / y values satisfy the equation * * @return boolean */ public function verifyPoint(array $p) { list($x, $y) = $p; $lhs = $y->multiply($y); $lhs = $lhs->add($x->multiply($y)); $x2 = $x->multiply($x); $x3 = $x2->multiply($x); $rhs = $x3->add($this->a->multiply($x2))->add($this->b); return $lhs->equals($rhs); } /** * Returns the modulo * * @return BigInteger */ public function getModulo() { return $this->modulo; } /** * Returns the a coefficient * * @return \phpseclib3\Math\PrimeField\Integer */ public function getA() { return $this->a; } /** * Returns the a coefficient * * @return \phpseclib3\Math\PrimeField\Integer */ public function getB() { return $this->b; } /** * Returns the affine point * * A Jacobian Coordinate is of the form (x, y, z). * To convert a Jacobian Coordinate to an Affine Point * you do (x / z^2, y / z^3) * * @return \phpseclib3\Math\PrimeField\Integer[] */ public function convertToAffine(array $p) { if (!isset($p[2])) { return $p; } list($x, $y, $z) = $p; $z = $this->one->divide($z); $z2 = $z->multiply($z); return [ $x->multiply($z2), $y->multiply($z2)->multiply($z) ]; } /** * Converts an affine point to a jacobian coordinate * * @return \phpseclib3\Math\PrimeField\Integer[] */ public function convertToInternal(array $p) { if (isset($p[2])) { return $p; } $p[2] = clone $this->one; $p['fresh'] = true; return $p; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/KoblitzPrime.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\BaseCurves; use phpseclib3\Math\BigInteger; use phpseclib3\Math\PrimeField; /** * Curves over y^2 = x^3 + b * * @author Jim Wigginton */ class KoblitzPrime extends Prime { /** * Basis * * @var list */ protected $basis; /** * Beta * * @var PrimeField\Integer */ protected $beta; // don't overwrite setCoefficients() with one that only accepts one parameter so that // one might be able to switch between KoblitzPrime and Prime more easily (for benchmarking // purposes). /** * Multiply and Add Points * * Uses a efficiently computable endomorphism to achieve a slight speedup * * Adapted from: * https://github.com/indutny/elliptic/blob/725bd91/lib/elliptic/curve/short.js#L219 * * @return int[] */ public function multiplyAddPoints(array $points, array $scalars) { static $zero, $one, $two; if (!isset($two)) { $two = new BigInteger(2); $one = new BigInteger(1); } if (!isset($this->beta)) { // get roots $inv = $this->one->divide($this->two)->negate(); $s = $this->three->negate()->squareRoot()->multiply($inv); $betas = [ $inv->add($s), $inv->subtract($s) ]; $this->beta = $betas[0]->compare($betas[1]) < 0 ? $betas[0] : $betas[1]; //echo strtoupper($this->beta->toHex(true)) . "\n"; exit; } if (!isset($this->basis)) { $factory = new PrimeField($this->order); $tempOne = $factory->newInteger($one); $tempTwo = $factory->newInteger($two); $tempThree = $factory->newInteger(new BigInteger(3)); $inv = $tempOne->divide($tempTwo)->negate(); $s = $tempThree->negate()->squareRoot()->multiply($inv); $lambdas = [ $inv->add($s), $inv->subtract($s) ]; $lhs = $this->multiplyPoint($this->p, $lambdas[0])[0]; $rhs = $this->p[0]->multiply($this->beta); $lambda = $lhs->equals($rhs) ? $lambdas[0] : $lambdas[1]; $this->basis = static::extendedGCD($lambda->toBigInteger(), $this->order); ///* foreach ($this->basis as $basis) { echo strtoupper($basis['a']->toHex(true)) . "\n"; echo strtoupper($basis['b']->toHex(true)) . "\n\n"; } exit; //*/ } $npoints = $nscalars = []; for ($i = 0; $i < count($points); $i++) { $p = $points[$i]; $k = $scalars[$i]->toBigInteger(); // begin split list($v1, $v2) = $this->basis; $c1 = $v2['b']->multiply($k); list($c1, $r) = $c1->divide($this->order); if ($this->order->compare($r->multiply($two)) <= 0) { $c1 = $c1->add($one); } $c2 = $v1['b']->negate()->multiply($k); list($c2, $r) = $c2->divide($this->order); if ($this->order->compare($r->multiply($two)) <= 0) { $c2 = $c2->add($one); } $p1 = $c1->multiply($v1['a']); $p2 = $c2->multiply($v2['a']); $q1 = $c1->multiply($v1['b']); $q2 = $c2->multiply($v2['b']); $k1 = $k->subtract($p1)->subtract($p2); $k2 = $q1->add($q2)->negate(); // end split $beta = [ $p[0]->multiply($this->beta), $p[1], clone $this->one ]; if (isset($p['naf'])) { $beta['naf'] = array_map(function ($p) { return [ $p[0]->multiply($this->beta), $p[1], clone $this->one ]; }, $p['naf']); $beta['nafwidth'] = $p['nafwidth']; } if ($k1->isNegative()) { $k1 = $k1->negate(); $p = $this->negatePoint($p); } if ($k2->isNegative()) { $k2 = $k2->negate(); $beta = $this->negatePoint($beta); } $pos = 2 * $i; $npoints[$pos] = $p; $nscalars[$pos] = $this->factory->newInteger($k1); $pos++; $npoints[$pos] = $beta; $nscalars[$pos] = $this->factory->newInteger($k2); } return parent::multiplyAddPoints($npoints, $nscalars); } /** * Returns the numerator and denominator of the slope * * @return FiniteField[] */ protected function doublePointHelper(array $p) { $numerator = $this->three->multiply($p[0])->multiply($p[0]); $denominator = $this->two->multiply($p[1]); return [$numerator, $denominator]; } /** * Doubles a jacobian coordinate on the curve * * See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l * * @return FiniteField[] */ protected function jacobianDoublePoint(array $p) { list($x1, $y1, $z1) = $p; $a = $x1->multiply($x1); $b = $y1->multiply($y1); $c = $b->multiply($b); $d = $x1->add($b); $d = $d->multiply($d)->subtract($a)->subtract($c)->multiply($this->two); $e = $this->three->multiply($a); $f = $e->multiply($e); $x3 = $f->subtract($this->two->multiply($d)); $y3 = $e->multiply($d->subtract($x3))->subtract( $this->eight->multiply($c) ); $z3 = $this->two->multiply($y1)->multiply($z1); return [$x3, $y3, $z3]; } /** * Doubles a "fresh" jacobian coordinate on the curve * * See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl * * @return FiniteField[] */ protected function jacobianDoublePointMixed(array $p) { list($x1, $y1) = $p; $xx = $x1->multiply($x1); $yy = $y1->multiply($y1); $yyyy = $yy->multiply($yy); $s = $x1->add($yy); $s = $s->multiply($s)->subtract($xx)->subtract($yyyy)->multiply($this->two); $m = $this->three->multiply($xx); $t = $m->multiply($m)->subtract($this->two->multiply($s)); $x3 = $t; $y3 = $s->subtract($t); $y3 = $m->multiply($y3)->subtract($this->eight->multiply($yyyy)); $z3 = $this->two->multiply($y1); return [$x3, $y3, $z3]; } /** * Tests whether or not the x / y values satisfy the equation * * @return boolean */ public function verifyPoint(array $p) { list($x, $y) = $p; $lhs = $y->multiply($y); $temp = $x->multiply($x)->multiply($x); $rhs = $temp->add($this->b); return $lhs->equals($rhs); } /** * Calculates the parameters needed from the Euclidean algorithm as discussed at * http://diamond.boisestate.edu/~liljanab/MATH308/GuideToECC.pdf#page=148 * * @param BigInteger $u * @param BigInteger $v * @return BigInteger[] */ protected static function extendedGCD(BigInteger $u, BigInteger $v) { $one = new BigInteger(1); $zero = new BigInteger(); $a = clone $one; $b = clone $zero; $c = clone $zero; $d = clone $one; $stop = $v->bitwise_rightShift($v->getLength() >> 1); $a1 = clone $zero; $b1 = clone $zero; $a2 = clone $zero; $b2 = clone $zero; $postGreatestIndex = 0; while (!$v->equals($zero)) { list($q) = $u->divide($v); $temp = $u; $u = $v; $v = $temp->subtract($v->multiply($q)); $temp = $a; $a = $c; $c = $temp->subtract($a->multiply($q)); $temp = $b; $b = $d; $d = $temp->subtract($b->multiply($q)); if ($v->compare($stop) > 0) { $a0 = $v; $b0 = $c; } else { $postGreatestIndex++; } if ($postGreatestIndex == 1) { $a1 = $v; $b1 = $c->negate(); } if ($postGreatestIndex == 2) { $rhs = $a0->multiply($a0)->add($b0->multiply($b0)); $lhs = $v->multiply($v)->add($b->multiply($b)); if ($lhs->compare($rhs) <= 0) { $a2 = $a0; $b2 = $b0->negate(); } else { $a2 = $v; $b2 = $c->negate(); } break; } } return [ ['a' => $a1, 'b' => $b1], ['a' => $a2, 'b' => $b2] ]; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Montgomery.php ================================================ * @copyright 2019 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\BaseCurves; use phpseclib3\Crypt\EC\Curves\Curve25519; use phpseclib3\Math\BigInteger; use phpseclib3\Math\PrimeField; use phpseclib3\Math\PrimeField\Integer as PrimeInteger; /** * Curves over y^2 = x^3 + a*x + x * * @author Jim Wigginton */ class Montgomery extends Base { /** * Prime Field Integer factory * * @var PrimeField */ protected $factory; /** * Cofficient for x * * @var object */ protected $a; /** * Constant used for point doubling * * @var object */ protected $a24; /** * The Number Zero * * @var object */ protected $zero; /** * The Number One * * @var object */ protected $one; /** * Base Point * * @var object */ protected $p; /** * The modulo * * @var BigInteger */ protected $modulo; /** * The Order * * @var BigInteger */ protected $order; /** * Sets the modulo */ public function setModulo(BigInteger $modulo) { $this->modulo = $modulo; $this->factory = new PrimeField($modulo); $this->zero = $this->factory->newInteger(new BigInteger()); $this->one = $this->factory->newInteger(new BigInteger(1)); } /** * Set coefficients a */ public function setCoefficients(BigInteger $a) { if (!isset($this->factory)) { throw new \RuntimeException('setModulo needs to be called before this method'); } $this->a = $this->factory->newInteger($a); $two = $this->factory->newInteger(new BigInteger(2)); $four = $this->factory->newInteger(new BigInteger(4)); $this->a24 = $this->a->subtract($two)->divide($four); } /** * Set x and y coordinates for the base point * * @param BigInteger|PrimeInteger $x * @param BigInteger|PrimeInteger $y * @return PrimeInteger[] */ public function setBasePoint($x, $y) { switch (true) { case !$x instanceof BigInteger && !$x instanceof PrimeInteger: throw new \UnexpectedValueException('Argument 1 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); case !$y instanceof BigInteger && !$y instanceof PrimeInteger: throw new \UnexpectedValueException('Argument 2 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); } if (!isset($this->factory)) { throw new \RuntimeException('setModulo needs to be called before this method'); } $this->p = [ $x instanceof BigInteger ? $this->factory->newInteger($x) : $x, $y instanceof BigInteger ? $this->factory->newInteger($y) : $y ]; } /** * Retrieve the base point as an array * * @return array */ public function getBasePoint() { if (!isset($this->factory)) { throw new \RuntimeException('setModulo needs to be called before this method'); } /* if (!isset($this->p)) { throw new \RuntimeException('setBasePoint needs to be called before this method'); } */ return $this->p; } /** * Doubles and adds a point on a curve * * See https://tools.ietf.org/html/draft-ietf-tls-curve25519-01#appendix-A.1.3 * * @return FiniteField[][] */ private function doubleAndAddPoint(array $p, array $q, PrimeInteger $x1) { if (!isset($this->factory)) { throw new \RuntimeException('setModulo needs to be called before this method'); } if (!count($p) || !count($q)) { return []; } if (!isset($p[1])) { throw new \RuntimeException('Affine coordinates need to be manually converted to XZ coordinates'); } list($x2, $z2) = $p; list($x3, $z3) = $q; $a = $x2->add($z2); $aa = $a->multiply($a); $b = $x2->subtract($z2); $bb = $b->multiply($b); $e = $aa->subtract($bb); $c = $x3->add($z3); $d = $x3->subtract($z3); $da = $d->multiply($a); $cb = $c->multiply($b); $temp = $da->add($cb); $x5 = $temp->multiply($temp); $temp = $da->subtract($cb); $z5 = $x1->multiply($temp->multiply($temp)); $x4 = $aa->multiply($bb); $temp = static::class == Curve25519::class ? $bb : $aa; $z4 = $e->multiply($temp->add($this->a24->multiply($e))); return [ [$x4, $z4], [$x5, $z5] ]; } /** * Multiply a point on the curve by a scalar * * Uses the montgomery ladder technique as described here: * * https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication#Montgomery_ladder * https://github.com/phpecc/phpecc/issues/16#issuecomment-59176772 * * @return array */ public function multiplyPoint(array $p, BigInteger $d) { $p1 = [$this->one, $this->zero]; $alreadyInternal = isset($p[1]); $p2 = $this->convertToInternal($p); $x = $p[0]; $b = $d->toBits(); $b = str_pad($b, 256, '0', STR_PAD_LEFT); for ($i = 0; $i < strlen($b); $i++) { $b_i = (int) $b[$i]; if ($b_i) { list($p2, $p1) = $this->doubleAndAddPoint($p2, $p1, $x); } else { list($p1, $p2) = $this->doubleAndAddPoint($p1, $p2, $x); } } return $alreadyInternal ? $p1 : $this->convertToAffine($p1); } /** * Converts an affine point to an XZ coordinate * * From https://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html * * XZ coordinates represent x y as X Z satsfying the following equations: * * x=X/Z * * @return PrimeInteger[] */ public function convertToInternal(array $p) { if (empty($p)) { return [clone $this->zero, clone $this->one]; } if (isset($p[1])) { return $p; } $p[1] = clone $this->one; return $p; } /** * Returns the affine point * * @return PrimeInteger[] */ public function convertToAffine(array $p) { if (!isset($p[1])) { return $p; } list($x, $z) = $p; return [$x->divide($z)]; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Prime.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\BaseCurves; use phpseclib3\Common\Functions\Strings; use phpseclib3\Math\BigInteger; use phpseclib3\Math\Common\FiniteField\Integer; use phpseclib3\Math\PrimeField; use phpseclib3\Math\PrimeField\Integer as PrimeInteger; /** * Curves over y^2 = x^3 + a*x + b * * @author Jim Wigginton */ class Prime extends Base { /** * Prime Field Integer factory * * @var \phpseclib3\Math\PrimeFields */ protected $factory; /** * Cofficient for x^1 * * @var object */ protected $a; /** * Cofficient for x^0 * * @var object */ protected $b; /** * Base Point * * @var object */ protected $p; /** * The number one over the specified finite field * * @var object */ protected $one; /** * The number two over the specified finite field * * @var object */ protected $two; /** * The number three over the specified finite field * * @var object */ protected $three; /** * The number four over the specified finite field * * @var object */ protected $four; /** * The number eight over the specified finite field * * @var object */ protected $eight; /** * The modulo * * @var BigInteger */ protected $modulo; /** * The Order * * @var BigInteger */ protected $order; /** * Sets the modulo */ public function setModulo(BigInteger $modulo) { $this->modulo = $modulo; $this->factory = new PrimeField($modulo); $this->two = $this->factory->newInteger(new BigInteger(2)); $this->three = $this->factory->newInteger(new BigInteger(3)); // used by jacobian coordinates $this->one = $this->factory->newInteger(new BigInteger(1)); $this->four = $this->factory->newInteger(new BigInteger(4)); $this->eight = $this->factory->newInteger(new BigInteger(8)); } /** * Set coefficients a and b */ public function setCoefficients(BigInteger $a, BigInteger $b) { if (!isset($this->factory)) { throw new \RuntimeException('setModulo needs to be called before this method'); } $this->a = $this->factory->newInteger($a); $this->b = $this->factory->newInteger($b); } /** * Set x and y coordinates for the base point * * @param BigInteger|PrimeInteger $x * @param BigInteger|PrimeInteger $y * @return PrimeInteger[] */ public function setBasePoint($x, $y) { switch (true) { case !$x instanceof BigInteger && !$x instanceof PrimeInteger: throw new \UnexpectedValueException('Argument 1 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); case !$y instanceof BigInteger && !$y instanceof PrimeInteger: throw new \UnexpectedValueException('Argument 2 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); } if (!isset($this->factory)) { throw new \RuntimeException('setModulo needs to be called before this method'); } $this->p = [ $x instanceof BigInteger ? $this->factory->newInteger($x) : $x, $y instanceof BigInteger ? $this->factory->newInteger($y) : $y ]; } /** * Retrieve the base point as an array * * @return array */ public function getBasePoint() { if (!isset($this->factory)) { throw new \RuntimeException('setModulo needs to be called before this method'); } /* if (!isset($this->p)) { throw new \RuntimeException('setBasePoint needs to be called before this method'); } */ return $this->p; } /** * Adds two "fresh" jacobian form on the curve * * @return FiniteField[] */ protected function jacobianAddPointMixedXY(array $p, array $q) { list($u1, $s1) = $p; list($u2, $s2) = $q; if ($u1->equals($u2)) { if (!$s1->equals($s2)) { return []; } else { return $this->doublePoint($p); } } $h = $u2->subtract($u1); $r = $s2->subtract($s1); $h2 = $h->multiply($h); $h3 = $h2->multiply($h); $v = $u1->multiply($h2); $x3 = $r->multiply($r)->subtract($h3)->subtract($v->multiply($this->two)); $y3 = $r->multiply( $v->subtract($x3) )->subtract( $s1->multiply($h3) ); return [$x3, $y3, $h]; } /** * Adds one "fresh" jacobian form on the curve * * The second parameter should be the "fresh" one * * @return FiniteField[] */ protected function jacobianAddPointMixedX(array $p, array $q) { list($u1, $s1, $z1) = $p; list($x2, $y2) = $q; $z12 = $z1->multiply($z1); $u2 = $x2->multiply($z12); $s2 = $y2->multiply($z12->multiply($z1)); if ($u1->equals($u2)) { if (!$s1->equals($s2)) { return []; } else { return $this->doublePoint($p); } } $h = $u2->subtract($u1); $r = $s2->subtract($s1); $h2 = $h->multiply($h); $h3 = $h2->multiply($h); $v = $u1->multiply($h2); $x3 = $r->multiply($r)->subtract($h3)->subtract($v->multiply($this->two)); $y3 = $r->multiply( $v->subtract($x3) )->subtract( $s1->multiply($h3) ); $z3 = $h->multiply($z1); return [$x3, $y3, $z3]; } /** * Adds two jacobian coordinates on the curve * * @return FiniteField[] */ protected function jacobianAddPoint(array $p, array $q) { list($x1, $y1, $z1) = $p; list($x2, $y2, $z2) = $q; $z12 = $z1->multiply($z1); $z22 = $z2->multiply($z2); $u1 = $x1->multiply($z22); $u2 = $x2->multiply($z12); $s1 = $y1->multiply($z22->multiply($z2)); $s2 = $y2->multiply($z12->multiply($z1)); if ($u1->equals($u2)) { if (!$s1->equals($s2)) { return []; } else { return $this->doublePoint($p); } } $h = $u2->subtract($u1); $r = $s2->subtract($s1); $h2 = $h->multiply($h); $h3 = $h2->multiply($h); $v = $u1->multiply($h2); $x3 = $r->multiply($r)->subtract($h3)->subtract($v->multiply($this->two)); $y3 = $r->multiply( $v->subtract($x3) )->subtract( $s1->multiply($h3) ); $z3 = $h->multiply($z1)->multiply($z2); return [$x3, $y3, $z3]; } /** * Adds two points on the curve * * @return FiniteField[] */ public function addPoint(array $p, array $q) { if (!isset($this->factory)) { throw new \RuntimeException('setModulo needs to be called before this method'); } if (!count($p) || !count($q)) { if (count($q)) { return $q; } if (count($p)) { return $p; } return []; } // use jacobian coordinates if (isset($p[2]) && isset($q[2])) { if (isset($p['fresh']) && isset($q['fresh'])) { return $this->jacobianAddPointMixedXY($p, $q); } if (isset($p['fresh'])) { return $this->jacobianAddPointMixedX($q, $p); } if (isset($q['fresh'])) { return $this->jacobianAddPointMixedX($p, $q); } return $this->jacobianAddPoint($p, $q); } if (isset($p[2]) || isset($q[2])) { throw new \RuntimeException('Affine coordinates need to be manually converted to Jacobi coordinates or vice versa'); } if ($p[0]->equals($q[0])) { if (!$p[1]->equals($q[1])) { return []; } else { // eg. doublePoint list($numerator, $denominator) = $this->doublePointHelper($p); } } else { $numerator = $q[1]->subtract($p[1]); $denominator = $q[0]->subtract($p[0]); } $slope = $numerator->divide($denominator); $x = $slope->multiply($slope)->subtract($p[0])->subtract($q[0]); $y = $slope->multiply($p[0]->subtract($x))->subtract($p[1]); return [$x, $y]; } /** * Returns the numerator and denominator of the slope * * @return FiniteField[] */ protected function doublePointHelper(array $p) { $numerator = $this->three->multiply($p[0])->multiply($p[0])->add($this->a); $denominator = $this->two->multiply($p[1]); return [$numerator, $denominator]; } /** * Doubles a jacobian coordinate on the curve * * @return FiniteField[] */ protected function jacobianDoublePoint(array $p) { list($x, $y, $z) = $p; $x2 = $x->multiply($x); $y2 = $y->multiply($y); $z2 = $z->multiply($z); $s = $this->four->multiply($x)->multiply($y2); $m1 = $this->three->multiply($x2); $m2 = $this->a->multiply($z2->multiply($z2)); $m = $m1->add($m2); $x1 = $m->multiply($m)->subtract($this->two->multiply($s)); $y1 = $m->multiply($s->subtract($x1))->subtract( $this->eight->multiply($y2->multiply($y2)) ); $z1 = $this->two->multiply($y)->multiply($z); return [$x1, $y1, $z1]; } /** * Doubles a "fresh" jacobian coordinate on the curve * * @return FiniteField[] */ protected function jacobianDoublePointMixed(array $p) { list($x, $y) = $p; $x2 = $x->multiply($x); $y2 = $y->multiply($y); $s = $this->four->multiply($x)->multiply($y2); $m1 = $this->three->multiply($x2); $m = $m1->add($this->a); $x1 = $m->multiply($m)->subtract($this->two->multiply($s)); $y1 = $m->multiply($s->subtract($x1))->subtract( $this->eight->multiply($y2->multiply($y2)) ); $z1 = $this->two->multiply($y); return [$x1, $y1, $z1]; } /** * Doubles a point on a curve * * @return FiniteField[] */ public function doublePoint(array $p) { if (!isset($this->factory)) { throw new \RuntimeException('setModulo needs to be called before this method'); } if (!count($p)) { return []; } // use jacobian coordinates if (isset($p[2])) { if (isset($p['fresh'])) { return $this->jacobianDoublePointMixed($p); } return $this->jacobianDoublePoint($p); } list($numerator, $denominator) = $this->doublePointHelper($p); $slope = $numerator->divide($denominator); $x = $slope->multiply($slope)->subtract($p[0])->subtract($p[0]); $y = $slope->multiply($p[0]->subtract($x))->subtract($p[1]); return [$x, $y]; } /** * Returns the X coordinate and the derived Y coordinate * * @return array */ public function derivePoint($m) { $y = ord(Strings::shift($m)); $x = new BigInteger($m, 256); $xp = $this->convertInteger($x); switch ($y) { case 2: $ypn = false; break; case 3: $ypn = true; break; default: throw new \RuntimeException('Coordinate not in recognized format'); } $temp = $xp->multiply($this->a); $temp = $xp->multiply($xp)->multiply($xp)->add($temp); $temp = $temp->add($this->b); $b = $temp->squareRoot(); if (!$b) { throw new \RuntimeException('Unable to derive Y coordinate'); } $bn = $b->isOdd(); $yp = $ypn == $bn ? $b : $b->negate(); return [$xp, $yp]; } /** * Tests whether or not the x / y values satisfy the equation * * @return boolean */ public function verifyPoint(array $p) { list($x, $y) = $p; $lhs = $y->multiply($y); $temp = $x->multiply($this->a); $temp = $x->multiply($x)->multiply($x)->add($temp); $rhs = $temp->add($this->b); return $lhs->equals($rhs); } /** * Returns the modulo * * @return BigInteger */ public function getModulo() { return $this->modulo; } /** * Returns the a coefficient * * @return PrimeInteger */ public function getA() { return $this->a; } /** * Returns the a coefficient * * @return PrimeInteger */ public function getB() { return $this->b; } /** * Multiply and Add Points * * Adapted from: * https://github.com/indutny/elliptic/blob/725bd91/lib/elliptic/curve/base.js#L125 * * @return int[] */ public function multiplyAddPoints(array $points, array $scalars) { $length = count($points); foreach ($points as &$point) { $point = $this->convertToInternal($point); } $wnd = [$this->getNAFPoints($points[0], 7)]; $wndWidth = [isset($points[0]['nafwidth']) ? $points[0]['nafwidth'] : 7]; for ($i = 1; $i < $length; $i++) { $wnd[] = $this->getNAFPoints($points[$i], 1); $wndWidth[] = isset($points[$i]['nafwidth']) ? $points[$i]['nafwidth'] : 1; } $naf = []; // comb all window NAFs $max = 0; for ($i = $length - 1; $i >= 1; $i -= 2) { $a = $i - 1; $b = $i; if ($wndWidth[$a] != 1 || $wndWidth[$b] != 1) { $naf[$a] = $scalars[$a]->getNAF($wndWidth[$a]); $naf[$b] = $scalars[$b]->getNAF($wndWidth[$b]); $max = max(count($naf[$a]), count($naf[$b]), $max); continue; } $comb = [ $points[$a], // 1 null, // 3 null, // 5 $points[$b] // 7 ]; $comb[1] = $this->addPoint($points[$a], $points[$b]); $comb[2] = $this->addPoint($points[$a], $this->negatePoint($points[$b])); $index = [ -3, /* -1 -1 */ -1, /* -1 0 */ -5, /* -1 1 */ -7, /* 0 -1 */ 0, /* 0 -1 */ 7, /* 0 1 */ 5, /* 1 -1 */ 1, /* 1 0 */ 3 /* 1 1 */ ]; $jsf = self::getJSFPoints($scalars[$a], $scalars[$b]); $max = max(count($jsf[0]), $max); if ($max > 0) { $naf[$a] = array_fill(0, $max, 0); $naf[$b] = array_fill(0, $max, 0); } else { $naf[$a] = []; $naf[$b] = []; } for ($j = 0; $j < $max; $j++) { $ja = isset($jsf[0][$j]) ? $jsf[0][$j] : 0; $jb = isset($jsf[1][$j]) ? $jsf[1][$j] : 0; $naf[$a][$j] = $index[3 * ($ja + 1) + $jb + 1]; $naf[$b][$j] = 0; $wnd[$a] = $comb; } } $acc = []; $temp = [0, 0, 0, 0]; for ($i = $max; $i >= 0; $i--) { $k = 0; while ($i >= 0) { $zero = true; for ($j = 0; $j < $length; $j++) { $temp[$j] = isset($naf[$j][$i]) ? $naf[$j][$i] : 0; if ($temp[$j] != 0) { $zero = false; } } if (!$zero) { break; } $k++; $i--; } if ($i >= 0) { $k++; } while ($k--) { $acc = $this->doublePoint($acc); } if ($i < 0) { break; } for ($j = 0; $j < $length; $j++) { $z = $temp[$j]; $p = null; if ($z == 0) { continue; } $p = $z > 0 ? $wnd[$j][($z - 1) >> 1] : $this->negatePoint($wnd[$j][(-$z - 1) >> 1]); $acc = $this->addPoint($acc, $p); } } return $this->convertToAffine($acc); } /** * Precomputes NAF points * * Adapted from: * https://github.com/indutny/elliptic/blob/725bd91/lib/elliptic/curve/base.js#L351 * * @return int[] */ private function getNAFPoints(array $point, $wnd) { if (isset($point['naf'])) { return $point['naf']; } $res = [$point]; $max = (1 << $wnd) - 1; $dbl = $max == 1 ? null : $this->doublePoint($point); for ($i = 1; $i < $max; $i++) { $res[] = $this->addPoint($res[$i - 1], $dbl); } $point['naf'] = $res; /* $str = ''; foreach ($res as $re) { $re[0] = bin2hex($re[0]->toBytes()); $re[1] = bin2hex($re[1]->toBytes()); $str.= " ['$re[0]', '$re[1]'],\r\n"; } file_put_contents('temp.txt', $str); exit; */ return $res; } /** * Precomputes points in Joint Sparse Form * * Adapted from: * https://github.com/indutny/elliptic/blob/725bd91/lib/elliptic/utils.js#L96 * * @return int[] */ private static function getJSFPoints(Integer $k1, Integer $k2) { static $three; if (!isset($three)) { $three = new BigInteger(3); } $jsf = [[], []]; $k1 = $k1->toBigInteger(); $k2 = $k2->toBigInteger(); $d1 = 0; $d2 = 0; while ($k1->compare(new BigInteger(-$d1)) > 0 || $k2->compare(new BigInteger(-$d2)) > 0) { // first phase $m14 = $k1->testBit(0) + 2 * $k1->testBit(1); $m14 += $d1; $m14 &= 3; $m24 = $k2->testBit(0) + 2 * $k2->testBit(1); $m24 += $d2; $m24 &= 3; if ($m14 == 3) { $m14 = -1; } if ($m24 == 3) { $m24 = -1; } $u1 = 0; if ($m14 & 1) { // if $m14 is odd $m8 = $k1->testBit(0) + 2 * $k1->testBit(1) + 4 * $k1->testBit(2); $m8 += $d1; $m8 &= 7; $u1 = ($m8 == 3 || $m8 == 5) && $m24 == 2 ? -$m14 : $m14; } $jsf[0][] = $u1; $u2 = 0; if ($m24 & 1) { // if $m24 is odd $m8 = $k2->testBit(0) + 2 * $k2->testBit(1) + 4 * $k2->testBit(2); $m8 += $d2; $m8 &= 7; $u2 = ($m8 == 3 || $m8 == 5) && $m14 == 2 ? -$m24 : $m24; } $jsf[1][] = $u2; // second phase if (2 * $d1 == $u1 + 1) { $d1 = 1 - $d1; } if (2 * $d2 == $u2 + 1) { $d2 = 1 - $d2; } $k1 = $k1->bitwise_rightShift(1); $k2 = $k2->bitwise_rightShift(1); } return $jsf; } /** * Returns the affine point * * A Jacobian Coordinate is of the form (x, y, z). * To convert a Jacobian Coordinate to an Affine Point * you do (x / z^2, y / z^3) * * @return PrimeInteger[] */ public function convertToAffine(array $p) { if (!isset($p[2])) { return $p; } list($x, $y, $z) = $p; $z = $this->one->divide($z); $z2 = $z->multiply($z); return [ $x->multiply($z2), $y->multiply($z2)->multiply($z) ]; } /** * Converts an affine point to a jacobian coordinate * * @return PrimeInteger[] */ public function convertToInternal(array $p) { if (isset($p[2])) { return $p; } $p[2] = clone $this->one; $p['fresh'] = true; return $p; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/TwistedEdwards.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\BaseCurves; use phpseclib3\Math\BigInteger; use phpseclib3\Math\PrimeField; use phpseclib3\Math\PrimeField\Integer as PrimeInteger; /** * Curves over a*x^2 + y^2 = 1 + d*x^2*y^2 * * @author Jim Wigginton */ class TwistedEdwards extends Base { /** * The modulo * * @var BigInteger */ protected $modulo; /** * Cofficient for x^2 * * @var object */ protected $a; /** * Cofficient for x^2*y^2 * * @var object */ protected $d; /** * Base Point * * @var object[] */ protected $p; /** * The number zero over the specified finite field * * @var object */ protected $zero; /** * The number one over the specified finite field * * @var object */ protected $one; /** * The number two over the specified finite field * * @var object */ protected $two; /** * Sets the modulo */ public function setModulo(BigInteger $modulo) { $this->modulo = $modulo; $this->factory = new PrimeField($modulo); $this->zero = $this->factory->newInteger(new BigInteger(0)); $this->one = $this->factory->newInteger(new BigInteger(1)); $this->two = $this->factory->newInteger(new BigInteger(2)); } /** * Set coefficients a and b */ public function setCoefficients(BigInteger $a, BigInteger $d) { if (!isset($this->factory)) { throw new \RuntimeException('setModulo needs to be called before this method'); } $this->a = $this->factory->newInteger($a); $this->d = $this->factory->newInteger($d); } /** * Set x and y coordinates for the base point */ public function setBasePoint($x, $y) { switch (true) { case !$x instanceof BigInteger && !$x instanceof PrimeInteger: throw new \UnexpectedValueException('Argument 1 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); case !$y instanceof BigInteger && !$y instanceof PrimeInteger: throw new \UnexpectedValueException('Argument 2 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); } if (!isset($this->factory)) { throw new \RuntimeException('setModulo needs to be called before this method'); } $this->p = [ $x instanceof BigInteger ? $this->factory->newInteger($x) : $x, $y instanceof BigInteger ? $this->factory->newInteger($y) : $y ]; } /** * Returns the a coefficient * * @return PrimeInteger */ public function getA() { return $this->a; } /** * Returns the a coefficient * * @return PrimeInteger */ public function getD() { return $this->d; } /** * Retrieve the base point as an array * * @return array */ public function getBasePoint() { if (!isset($this->factory)) { throw new \RuntimeException('setModulo needs to be called before this method'); } /* if (!isset($this->p)) { throw new \RuntimeException('setBasePoint needs to be called before this method'); } */ return $this->p; } /** * Returns the affine point * * @return PrimeInteger[] */ public function convertToAffine(array $p) { if (!isset($p[2])) { return $p; } list($x, $y, $z) = $p; $z = $this->one->divide($z); return [ $x->multiply($z), $y->multiply($z) ]; } /** * Returns the modulo * * @return BigInteger */ public function getModulo() { return $this->modulo; } /** * Tests whether or not the x / y values satisfy the equation * * @return boolean */ public function verifyPoint(array $p) { list($x, $y) = $p; $x2 = $x->multiply($x); $y2 = $y->multiply($y); $lhs = $this->a->multiply($x2)->add($y2); $rhs = $this->d->multiply($x2)->multiply($y2)->add($this->one); return $lhs->equals($rhs); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve25519.php ================================================ * @copyright 2019 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Montgomery; use phpseclib3\Math\BigInteger; class Curve25519 extends Montgomery { public function __construct() { // 2^255 - 19 $this->setModulo(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED', 16)); $this->a24 = $this->factory->newInteger(new BigInteger('121666')); $this->p = [$this->factory->newInteger(new BigInteger(9))]; // 2^252 + 0x14def9dea2f79cd65812631a5cf5d3ed $this->setOrder(new BigInteger('1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED', 16)); /* $this->setCoefficients( new BigInteger('486662'), // a ); $this->setBasePoint( new BigInteger(9), new BigInteger('14781619447589544791020593568409986887264606134616475288964881837755586237401') ); */ } /** * Multiply a point on the curve by a scalar * * Modifies the scalar as described at https://tools.ietf.org/html/rfc7748#page-8 * * @return array */ public function multiplyPoint(array $p, BigInteger $d) { //$r = strrev(sodium_crypto_scalarmult($d->toBytes(), strrev($p[0]->toBytes()))); //return [$this->factory->newInteger(new BigInteger($r, 256))]; $d = $d->toBytes(); $d &= "\xF8" . str_repeat("\xFF", 30) . "\x7F"; $d = strrev($d); $d |= "\x40"; $d = new BigInteger($d, -256); return parent::multiplyPoint($p, $d); } /** * Creates a random scalar multiplier * * @return BigInteger */ public function createRandomMultiplier() { return BigInteger::random(256); } /** * Performs range check */ public function rangeCheck(BigInteger $x) { if ($x->getLength() > 256 || $x->isNegative()) { throw new \RangeException('x must be a positive integer less than 256 bytes in length'); } } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve448.php ================================================ * @copyright 2019 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Montgomery; use phpseclib3\Math\BigInteger; class Curve448 extends Montgomery { public function __construct() { // 2^448 - 2^224 - 1 $this->setModulo(new BigInteger( 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE' . 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', 16 )); $this->a24 = $this->factory->newInteger(new BigInteger('39081')); $this->p = [$this->factory->newInteger(new BigInteger(5))]; // 2^446 - 0x8335dc163bb124b65129c96fde933d8d723a70aadc873d6d54a7bb0d $this->setOrder(new BigInteger( '3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . '7CCA23E9C44EDB49AED63690216CC2728DC58F552378C292AB5844F3', 16 )); /* $this->setCoefficients( new BigInteger('156326'), // a ); $this->setBasePoint( new BigInteger(5), new BigInteger( '355293926785568175264127502063783334808976399387714271831880898' . '435169088786967410002932673765864550910142774147268105838985595290' . '606362') ); */ } /** * Multiply a point on the curve by a scalar * * Modifies the scalar as described at https://tools.ietf.org/html/rfc7748#page-8 * * @return array */ public function multiplyPoint(array $p, BigInteger $d) { //$r = strrev(sodium_crypto_scalarmult($d->toBytes(), strrev($p[0]->toBytes()))); //return [$this->factory->newInteger(new BigInteger($r, 256))]; $d = $d->toBytes(); $d[0] = $d[0] & "\xFC"; $d = strrev($d); $d |= "\x80"; $d = new BigInteger($d, 256); return parent::multiplyPoint($p, $d); } /** * Creates a random scalar multiplier * * @return BigInteger */ public function createRandomMultiplier() { return BigInteger::random(446); } /** * Performs range check */ public function rangeCheck(BigInteger $x) { if ($x->getLength() > 448 || $x->isNegative()) { throw new \RangeException('x must be a positive integer less than 446 bytes in length'); } } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed25519.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards; use phpseclib3\Crypt\Hash; use phpseclib3\Crypt\Random; use phpseclib3\Math\BigInteger; class Ed25519 extends TwistedEdwards { const HASH = 'sha512'; /* Per https://tools.ietf.org/html/rfc8032#page-6 EdDSA has several parameters, one of which is b: 2. An integer b with 2^(b-1) > p. EdDSA public keys have exactly b bits, and EdDSA signatures have exactly 2*b bits. b is recommended to be a multiple of 8, so public key and signature lengths are an integral number of octets. SIZE corresponds to b */ const SIZE = 32; public function __construct() { // 2^255 - 19 $this->setModulo(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED', 16)); $this->setCoefficients( // -1 new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC', 16), // a // -121665/121666 new BigInteger('52036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978A3', 16) // d ); $this->setBasePoint( new BigInteger('216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A', 16), new BigInteger('6666666666666666666666666666666666666666666666666666666666666658', 16) ); $this->setOrder(new BigInteger('1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED', 16)); // algorithm 14.47 from http://cacr.uwaterloo.ca/hac/about/chap14.pdf#page=16 /* $this->setReduction(function($x) { $parts = $x->bitwise_split(255); $className = $this->className; if (count($parts) > 2) { list(, $r) = $x->divide($className::$modulo); return $r; } $zero = new BigInteger(); $c = new BigInteger(19); switch (count($parts)) { case 2: list($qi, $ri) = $parts; break; case 1: $qi = $zero; list($ri) = $parts; break; case 0: return $zero; } $r = $ri; while ($qi->compare($zero) > 0) { $temp = $qi->multiply($c)->bitwise_split(255); if (count($temp) == 2) { list($qi, $ri) = $temp; } else { $qi = $zero; list($ri) = $temp; } $r = $r->add($ri); } while ($r->compare($className::$modulo) > 0) { $r = $r->subtract($className::$modulo); } return $r; }); */ } /** * Recover X from Y * * Implements steps 2-4 at https://tools.ietf.org/html/rfc8032#section-5.1.3 * * Used by EC\Keys\Common.php * * @param BigInteger $y * @param boolean $sign * @return object[] */ public function recoverX(BigInteger $y, $sign) { $y = $this->factory->newInteger($y); $y2 = $y->multiply($y); $u = $y2->subtract($this->one); $v = $this->d->multiply($y2)->add($this->one); $x2 = $u->divide($v); if ($x2->equals($this->zero)) { if ($sign) { throw new \RuntimeException('Unable to recover X coordinate (x2 = 0)'); } return clone $this->zero; } // find the square root /* we don't do $x2->squareRoot() because, quoting from https://tools.ietf.org/html/rfc8032#section-5.1.1: "For point decoding or "decompression", square roots modulo p are needed. They can be computed using the Tonelli-Shanks algorithm or the special case for p = 5 (mod 8). To find a square root of a, first compute the candidate root x = a^((p+3)/8) (mod p)." */ $exp = $this->getModulo()->add(new BigInteger(3)); $exp = $exp->bitwise_rightShift(3); $x = $x2->pow($exp); // If v x^2 = -u (mod p), set x <-- x * 2^((p-1)/4), which is a square root. if (!$x->multiply($x)->subtract($x2)->equals($this->zero)) { $temp = $this->getModulo()->subtract(new BigInteger(1)); $temp = $temp->bitwise_rightShift(2); $temp = $this->two->pow($temp); $x = $x->multiply($temp); if (!$x->multiply($x)->subtract($x2)->equals($this->zero)) { throw new \RuntimeException('Unable to recover X coordinate'); } } if ($x->isOdd() != $sign) { $x = $x->negate(); } return [$x, $y]; } /** * Extract Secret Scalar * * Implements steps 1-3 at https://tools.ietf.org/html/rfc8032#section-5.1.5 * * Used by the various key handlers * * @param string $str * @return array */ public function extractSecret($str) { if (strlen($str) != 32) { throw new \LengthException('Private Key should be 32-bytes long'); } // 1. Hash the 32-byte private key using SHA-512, storing the digest in // a 64-octet large buffer, denoted h. Only the lower 32 bytes are // used for generating the public key. $hash = new Hash('sha512'); $h = $hash->hash($str); $h = substr($h, 0, 32); // 2. Prune the buffer: The lowest three bits of the first octet are // cleared, the highest bit of the last octet is cleared, and the // second highest bit of the last octet is set. $h[0] = $h[0] & chr(0xF8); $h = strrev($h); $h[0] = ($h[0] & chr(0x3F)) | chr(0x40); // 3. Interpret the buffer as the little-endian integer, forming a // secret scalar s. $dA = new BigInteger($h, 256); return [ 'dA' => $dA, 'secret' => $str ]; } /** * Encode a point as a string * * @param array $point * @return string */ public function encodePoint($point) { list($x, $y) = $point; $y = $y->toBytes(); $y[0] = $y[0] & chr(0x7F); if ($x->isOdd()) { $y[0] = $y[0] | chr(0x80); } $y = strrev($y); return $y; } /** * Creates a random scalar multiplier * * @return \phpseclib3\Math\PrimeField\Integer */ public function createRandomMultiplier() { return $this->extractSecret(Random::string(32))['dA']; } /** * Converts an affine point to an extended homogeneous coordinate * * From https://tools.ietf.org/html/rfc8032#section-5.1.4 : * * A point (x,y) is represented in extended homogeneous coordinates (X, Y, Z, T), * with x = X/Z, y = Y/Z, x * y = T/Z. * * @return \phpseclib3\Math\PrimeField\Integer[] */ public function convertToInternal(array $p) { if (empty($p)) { return [clone $this->zero, clone $this->one, clone $this->one, clone $this->zero]; } if (isset($p[2])) { return $p; } $p[2] = clone $this->one; $p[3] = $p[0]->multiply($p[1]); return $p; } /** * Doubles a point on a curve * * @return FiniteField[] */ public function doublePoint(array $p) { if (!isset($this->factory)) { throw new \RuntimeException('setModulo needs to be called before this method'); } if (!count($p)) { return []; } if (!isset($p[2])) { throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); } // from https://tools.ietf.org/html/rfc8032#page-12 list($x1, $y1, $z1, $t1) = $p; $a = $x1->multiply($x1); $b = $y1->multiply($y1); $c = $this->two->multiply($z1)->multiply($z1); $h = $a->add($b); $temp = $x1->add($y1); $e = $h->subtract($temp->multiply($temp)); $g = $a->subtract($b); $f = $c->add($g); $x3 = $e->multiply($f); $y3 = $g->multiply($h); $t3 = $e->multiply($h); $z3 = $f->multiply($g); return [$x3, $y3, $z3, $t3]; } /** * Adds two points on the curve * * @return FiniteField[] */ public function addPoint(array $p, array $q) { if (!isset($this->factory)) { throw new \RuntimeException('setModulo needs to be called before this method'); } if (!count($p) || !count($q)) { if (count($q)) { return $q; } if (count($p)) { return $p; } return []; } if (!isset($p[2]) || !isset($q[2])) { throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); } if ($p[0]->equals($q[0])) { return !$p[1]->equals($q[1]) ? [] : $this->doublePoint($p); } // from https://tools.ietf.org/html/rfc8032#page-12 list($x1, $y1, $z1, $t1) = $p; list($x2, $y2, $z2, $t2) = $q; $a = $y1->subtract($x1)->multiply($y2->subtract($x2)); $b = $y1->add($x1)->multiply($y2->add($x2)); $c = $t1->multiply($this->two)->multiply($this->d)->multiply($t2); $d = $z1->multiply($this->two)->multiply($z2); $e = $b->subtract($a); $f = $d->subtract($c); $g = $d->add($c); $h = $b->add($a); $x3 = $e->multiply($f); $y3 = $g->multiply($h); $t3 = $e->multiply($h); $z3 = $f->multiply($g); return [$x3, $y3, $z3, $t3]; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed448.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards; use phpseclib3\Crypt\Hash; use phpseclib3\Crypt\Random; use phpseclib3\Math\BigInteger; class Ed448 extends TwistedEdwards { const HASH = 'shake256-912'; const SIZE = 57; public function __construct() { // 2^448 - 2^224 - 1 $this->setModulo(new BigInteger( 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE' . 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', 16 )); $this->setCoefficients( new BigInteger(1), // -39081 new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE' . 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6756', 16) ); $this->setBasePoint( new BigInteger('4F1970C66BED0DED221D15A622BF36DA9E146570470F1767EA6DE324' . 'A3D3A46412AE1AF72AB66511433B80E18B00938E2626A82BC70CC05E', 16), new BigInteger('693F46716EB6BC248876203756C9C7624BEA73736CA3984087789C1E' . '05A0C2D73AD3FF1CE67C39C4FDBD132C4ED7C8AD9808795BF230FA14', 16) ); $this->setOrder(new BigInteger( '3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . '7CCA23E9C44EDB49AED63690216CC2728DC58F552378C292AB5844F3', 16 )); } /** * Recover X from Y * * Implements steps 2-4 at https://tools.ietf.org/html/rfc8032#section-5.2.3 * * Used by EC\Keys\Common.php * * @param BigInteger $y * @param boolean $sign * @return object[] */ public function recoverX(BigInteger $y, $sign) { $y = $this->factory->newInteger($y); $y2 = $y->multiply($y); $u = $y2->subtract($this->one); $v = $this->d->multiply($y2)->subtract($this->one); $x2 = $u->divide($v); if ($x2->equals($this->zero)) { if ($sign) { throw new \RuntimeException('Unable to recover X coordinate (x2 = 0)'); } return clone $this->zero; } // find the square root $exp = $this->getModulo()->add(new BigInteger(1)); $exp = $exp->bitwise_rightShift(2); $x = $x2->pow($exp); if (!$x->multiply($x)->subtract($x2)->equals($this->zero)) { throw new \RuntimeException('Unable to recover X coordinate'); } if ($x->isOdd() != $sign) { $x = $x->negate(); } return [$x, $y]; } /** * Extract Secret Scalar * * Implements steps 1-3 at https://tools.ietf.org/html/rfc8032#section-5.2.5 * * Used by the various key handlers * * @param string $str * @return array */ public function extractSecret($str) { if (strlen($str) != 57) { throw new \LengthException('Private Key should be 57-bytes long'); } // 1. Hash the 57-byte private key using SHAKE256(x, 114), storing the // digest in a 114-octet large buffer, denoted h. Only the lower 57 // bytes are used for generating the public key. $hash = new Hash('shake256-912'); $h = $hash->hash($str); $h = substr($h, 0, 57); // 2. Prune the buffer: The two least significant bits of the first // octet are cleared, all eight bits the last octet are cleared, and // the highest bit of the second to last octet is set. $h[0] = $h[0] & chr(0xFC); $h = strrev($h); $h[0] = "\0"; $h[1] = $h[1] | chr(0x80); // 3. Interpret the buffer as the little-endian integer, forming a // secret scalar s. $dA = new BigInteger($h, 256); return [ 'dA' => $dA, 'secret' => $str ]; $dA->secret = $str; return $dA; } /** * Encode a point as a string * * @param array $point * @return string */ public function encodePoint($point) { list($x, $y) = $point; $y = "\0" . $y->toBytes(); if ($x->isOdd()) { $y[0] = $y[0] | chr(0x80); } $y = strrev($y); return $y; } /** * Creates a random scalar multiplier * * @return \phpseclib3\Math\PrimeField\Integer */ public function createRandomMultiplier() { return $this->extractSecret(Random::string(57))['dA']; } /** * Converts an affine point to an extended homogeneous coordinate * * From https://tools.ietf.org/html/rfc8032#section-5.2.4 : * * A point (x,y) is represented in extended homogeneous coordinates (X, Y, Z, T), * with x = X/Z, y = Y/Z, x * y = T/Z. * * @return \phpseclib3\Math\PrimeField\Integer[] */ public function convertToInternal(array $p) { if (empty($p)) { return [clone $this->zero, clone $this->one, clone $this->one]; } if (isset($p[2])) { return $p; } $p[2] = clone $this->one; return $p; } /** * Doubles a point on a curve * * @return FiniteField[] */ public function doublePoint(array $p) { if (!isset($this->factory)) { throw new \RuntimeException('setModulo needs to be called before this method'); } if (!count($p)) { return []; } if (!isset($p[2])) { throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); } // from https://tools.ietf.org/html/rfc8032#page-18 list($x1, $y1, $z1) = $p; $b = $x1->add($y1); $b = $b->multiply($b); $c = $x1->multiply($x1); $d = $y1->multiply($y1); $e = $c->add($d); $h = $z1->multiply($z1); $j = $e->subtract($this->two->multiply($h)); $x3 = $b->subtract($e)->multiply($j); $y3 = $c->subtract($d)->multiply($e); $z3 = $e->multiply($j); return [$x3, $y3, $z3]; } /** * Adds two points on the curve * * @return FiniteField[] */ public function addPoint(array $p, array $q) { if (!isset($this->factory)) { throw new \RuntimeException('setModulo needs to be called before this method'); } if (!count($p) || !count($q)) { if (count($q)) { return $q; } if (count($p)) { return $p; } return []; } if (!isset($p[2]) || !isset($q[2])) { throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); } if ($p[0]->equals($q[0])) { return !$p[1]->equals($q[1]) ? [] : $this->doublePoint($p); } // from https://tools.ietf.org/html/rfc8032#page-17 list($x1, $y1, $z1) = $p; list($x2, $y2, $z2) = $q; $a = $z1->multiply($z2); $b = $a->multiply($a); $c = $x1->multiply($x2); $d = $y1->multiply($y2); $e = $this->d->multiply($c)->multiply($d); $f = $b->subtract($e); $g = $b->add($e); $h = $x1->add($y1)->multiply($x2->add($y2)); $x3 = $a->multiply($f)->multiply($h->subtract($c)->subtract($d)); $y3 = $a->multiply($g)->multiply($d->subtract($c)); $z3 = $f->multiply($g); return [$x3, $y3, $z3]; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160r1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Prime; use phpseclib3\Math\BigInteger; class brainpoolP160r1 extends Prime { public function __construct() { $this->setModulo(new BigInteger('E95E4A5F737059DC60DFC7AD95B3D8139515620F', 16)); $this->setCoefficients( new BigInteger('340E7BE2A280EB74E2BE61BADA745D97E8F7C300', 16), new BigInteger('1E589A8595423412134FAA2DBDEC95C8D8675E58', 16) ); $this->setBasePoint( new BigInteger('BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3', 16), new BigInteger('1667CB477A1A8EC338F94741669C976316DA6321', 16) ); $this->setOrder(new BigInteger('E95E4A5F737059DC60DF5991D45029409E60FC09', 16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160t1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Prime; use phpseclib3\Math\BigInteger; class brainpoolP160t1 extends Prime { public function __construct() { $this->setModulo(new BigInteger('E95E4A5F737059DC60DFC7AD95B3D8139515620F', 16)); $this->setCoefficients( new BigInteger('E95E4A5F737059DC60DFC7AD95B3D8139515620C', 16), // eg. -3 new BigInteger('7A556B6DAE535B7B51ED2C4D7DAA7A0B5C55F380', 16) ); $this->setBasePoint( new BigInteger('B199B13B9B34EFC1397E64BAEB05ACC265FF2378', 16), new BigInteger('ADD6718B7C7C1961F0991B842443772152C9E0AD', 16) ); $this->setOrder(new BigInteger('E95E4A5F737059DC60DF5991D45029409E60FC09', 16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192r1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Prime; use phpseclib3\Math\BigInteger; class brainpoolP192r1 extends Prime { public function __construct() { $this->setModulo(new BigInteger('C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297', 16)); $this->setCoefficients( new BigInteger('6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF', 16), new BigInteger('469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9', 16) ); $this->setBasePoint( new BigInteger('C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6', 16), new BigInteger('14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F', 16) ); $this->setOrder(new BigInteger('C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1', 16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192t1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Prime; use phpseclib3\Math\BigInteger; class brainpoolP192t1 extends Prime { public function __construct() { $this->setModulo(new BigInteger('C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297', 16)); $this->setCoefficients( new BigInteger('C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86294', 16), // eg. -3 new BigInteger('13D56FFAEC78681E68F9DEB43B35BEC2FB68542E27897B79', 16) ); $this->setBasePoint( new BigInteger('3AE9E58C82F63C30282E1FE7BBF43FA72C446AF6F4618129', 16), new BigInteger('097E2C5667C2223A902AB5CA449D0084B7E5B3DE7CCC01C9', 16) ); $this->setOrder(new BigInteger('C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1', 16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224r1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Prime; use phpseclib3\Math\BigInteger; class brainpoolP224r1 extends Prime { public function __construct() { $this->setModulo(new BigInteger('D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF', 16)); $this->setCoefficients( new BigInteger('68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43', 16), new BigInteger('2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B', 16) ); $this->setBasePoint( new BigInteger('0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D', 16), new BigInteger('58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD', 16) ); $this->setOrder(new BigInteger('D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F', 16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224t1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Prime; use phpseclib3\Math\BigInteger; class brainpoolP224t1 extends Prime { public function __construct() { $this->setModulo(new BigInteger('D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF', 16)); $this->setCoefficients( new BigInteger('D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FC', 16), // eg. -3 new BigInteger('4B337D934104CD7BEF271BF60CED1ED20DA14C08B3BB64F18A60888D', 16) ); $this->setBasePoint( new BigInteger('6AB1E344CE25FF3896424E7FFE14762ECB49F8928AC0C76029B4D580', 16), new BigInteger('0374E9F5143E568CD23F3F4D7C0D4B1E41C8CC0D1C6ABD5F1A46DB4C', 16) ); $this->setOrder(new BigInteger('D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F', 16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256r1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Prime; use phpseclib3\Math\BigInteger; class brainpoolP256r1 extends Prime { public function __construct() { $this->setModulo(new BigInteger('A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377', 16)); $this->setCoefficients( new BigInteger('7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9', 16), new BigInteger('26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6', 16) ); $this->setBasePoint( new BigInteger('8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262', 16), new BigInteger('547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997', 16) ); $this->setOrder(new BigInteger('A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7', 16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256t1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Prime; use phpseclib3\Math\BigInteger; class brainpoolP256t1 extends Prime { public function __construct() { $this->setModulo(new BigInteger('A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377', 16)); $this->setCoefficients( new BigInteger('A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5374', 16), // eg. -3 new BigInteger('662C61C430D84EA4FE66A7733D0B76B7BF93EBC4AF2F49256AE58101FEE92B04', 16) ); $this->setBasePoint( new BigInteger('A3E8EB3CC1CFE7B7732213B23A656149AFA142C47AAFBC2B79A191562E1305F4', 16), new BigInteger('2D996C823439C56D7F7B22E14644417E69BCB6DE39D027001DABE8F35B25C9BE', 16) ); $this->setOrder(new BigInteger('A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7', 16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320r1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Prime; use phpseclib3\Math\BigInteger; class brainpoolP320r1 extends Prime { public function __construct() { $this->setModulo(new BigInteger('D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F9' . '2B9EC7893EC28FCD412B1F1B32E27', 16)); $this->setCoefficients( new BigInteger('3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F4' . '92F375A97D860EB4', 16), new BigInteger('520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD88453981' . '6F5EB4AC8FB1F1A6', 16) ); $this->setBasePoint( new BigInteger('43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C7' . '10AF8D0D39E20611', 16), new BigInteger('14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7' . 'D35245D1692E8EE1', 16) ); $this->setOrder(new BigInteger('D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D4' . '82EC7EE8658E98691555B44C59311', 16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320t1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Prime; use phpseclib3\Math\BigInteger; class brainpoolP320t1 extends Prime { public function __construct() { $this->setModulo(new BigInteger('D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F9' . '2B9EC7893EC28FCD412B1F1B32E27', 16)); $this->setCoefficients( new BigInteger('D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28' . 'FCD412B1F1B32E24', 16), // eg. -3 new BigInteger('A7F561E038EB1ED560B3D147DB782013064C19F27ED27C6780AAF77FB8A547CE' . 'B5B4FEF422340353', 16) ); $this->setBasePoint( new BigInteger('925BE9FB01AFC6FB4D3E7D4990010F813408AB106C4F09CB7EE07868CC136FFF' . '3357F624A21BED52', 16), new BigInteger('63BA3A7A27483EBF6671DBEF7ABB30EBEE084E58A0B077AD42A5A0989D1EE71B' . '1B9BC0455FB0D2C3', 16) ); $this->setOrder(new BigInteger('D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D4' . '82EC7EE8658E98691555B44C59311', 16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384r1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Prime; use phpseclib3\Math\BigInteger; class brainpoolP384r1 extends Prime { public function __construct() { $this->setModulo(new BigInteger( '8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A7' . '1874700133107EC53', 16 )); $this->setCoefficients( new BigInteger( '7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503' . 'AD4EB04A8C7DD22CE2826', 16 ), new BigInteger( '4A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DB' . 'C9943AB78696FA504C11', 16 ) ); $this->setBasePoint( new BigInteger( '1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D' . '646AAEF87B2E247D4AF1E', 16 ), new BigInteger( '8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E464621779' . '1811142820341263C5315', 16 ) ); $this->setOrder(new BigInteger( '8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC31' . '03B883202E9046565', 16 )); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384t1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Prime; use phpseclib3\Math\BigInteger; class brainpoolP384t1 extends Prime { public function __construct() { $this->setModulo(new BigInteger( '8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A7' . '1874700133107EC53', 16 )); $this->setCoefficients( new BigInteger( '8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901' . 'D1A71874700133107EC50', 16 ), // eg. -3 new BigInteger( '7F519EADA7BDA81BD826DBA647910F8C4B9346ED8CCDC64E4B1ABD11756DCE1D2074AA263B8' . '8805CED70355A33B471EE', 16 ) ); $this->setBasePoint( new BigInteger( '18DE98B02DB9A306F2AFCD7235F72A819B80AB12EBD653172476FECD462AABFFC4FF191B946' . 'A5F54D8D0AA2F418808CC', 16 ), new BigInteger( '25AB056962D30651A114AFD2755AD336747F93475B7A1FCA3B88F2B6A208CCFE469408584DC' . '2B2912675BF5B9E582928', 16 ) ); $this->setOrder(new BigInteger( '8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC31' . '03B883202E9046565', 16 )); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512r1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Prime; use phpseclib3\Math\BigInteger; class brainpoolP512r1 extends Prime { public function __construct() { $this->setModulo(new BigInteger( 'AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC' . '66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3', 16 )); $this->setCoefficients( new BigInteger( '7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA82' . '53AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA', 16 ), new BigInteger( '3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C' . '1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723', 16 ) ); $this->setBasePoint( new BigInteger( '81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D' . '0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822', 16 ), new BigInteger( '7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5' . 'F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892', 16 ) ); $this->setOrder(new BigInteger( 'AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA' . '92619418661197FAC10471DB1D381085DDADDB58796829CA90069', 16 )); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512t1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Prime; use phpseclib3\Math\BigInteger; class brainpoolP512t1 extends Prime { public function __construct() { $this->setModulo(new BigInteger( 'AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC' . '66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3', 16 )); $this->setCoefficients( new BigInteger( 'AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC' . '66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F0', 16 ), // eg. -3 new BigInteger( '7CBBBCF9441CFAB76E1890E46884EAE321F70C0BCB4981527897504BEC3E36A62BCDFA23049' . '76540F6450085F2DAE145C22553B465763689180EA2571867423E', 16 ) ); $this->setBasePoint( new BigInteger( '640ECE5C12788717B9C1BA06CBC2A6FEBA85842458C56DDE9DB1758D39C0313D82BA51735CD' . 'B3EA499AA77A7D6943A64F7A3F25FE26F06B51BAA2696FA9035DA', 16 ), new BigInteger( '5B534BD595F5AF0FA2C892376C84ACE1BB4E3019B71634C01131159CAE03CEE9D9932184BEE' . 'F216BD71DF2DADF86A627306ECFF96DBB8BACE198B61E00F8B332', 16 ) ); $this->setOrder(new BigInteger( 'AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA' . '92619418661197FAC10471DB1D381085DDADDB58796829CA90069', 16 )); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb233.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; final class nistb233 extends sect233r1 { } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb409.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; final class nistb409 extends sect409r1 { } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk163.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; final class nistk163 extends sect163k1 { } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk233.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; final class nistk233 extends sect233k1 { } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk283.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; final class nistk283 extends sect283k1 { } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk409.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; final class nistk409 extends sect409k1 { } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp192.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; final class nistp192 extends secp192r1 { } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp224.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; final class nistp224 extends secp224r1 { } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp256.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; final class nistp256 extends secp256r1 { } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp384.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; final class nistp384 extends secp384r1 { } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp521.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; final class nistp521 extends secp521r1 { } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistt571.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; final class nistt571 extends sect571k1 { } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; final class prime192v1 extends secp192r1 { } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v2.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Prime; use phpseclib3\Math\BigInteger; class prime192v2 extends Prime { public function __construct() { $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF', 16)); $this->setCoefficients( new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC', 16), new BigInteger('CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953', 16) ); $this->setBasePoint( new BigInteger('EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A', 16), new BigInteger('6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15', 16) ); $this->setOrder(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31', 16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v3.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Prime; use phpseclib3\Math\BigInteger; class prime192v3 extends Prime { public function __construct() { $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF', 16)); $this->setCoefficients( new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC', 16), new BigInteger('22123DC2395A05CAA7423DAECCC94760A7D462256BD56916', 16) ); $this->setBasePoint( new BigInteger('7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896', 16), new BigInteger('38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0', 16) ); $this->setOrder(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13', 16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Prime; use phpseclib3\Math\BigInteger; class prime239v1 extends Prime { public function __construct() { $this->setModulo(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF', 16)); $this->setCoefficients( new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC', 16), new BigInteger('6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A', 16) ); $this->setBasePoint( new BigInteger('0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF', 16), new BigInteger('7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE', 16) ); $this->setOrder(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B', 16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v2.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Prime; use phpseclib3\Math\BigInteger; class prime239v2 extends Prime { public function __construct() { $this->setModulo(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF', 16)); $this->setCoefficients( new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC', 16), new BigInteger('617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C', 16) ); $this->setBasePoint( new BigInteger('38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7', 16), new BigInteger('5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA', 16) ); $this->setOrder(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063', 16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v3.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Prime; use phpseclib3\Math\BigInteger; class prime239v3 extends Prime { public function __construct() { $this->setModulo(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF', 16)); $this->setCoefficients( new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC', 16), new BigInteger('255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E', 16) ); $this->setBasePoint( new BigInteger('6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A', 16), new BigInteger('1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3', 16) ); $this->setOrder(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551', 16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime256v1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; final class prime256v1 extends secp256r1 { } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Prime; use phpseclib3\Math\BigInteger; class secp112r1 extends Prime { public function __construct() { $this->setModulo(new BigInteger('DB7C2ABF62E35E668076BEAD208B', 16)); $this->setCoefficients( new BigInteger('DB7C2ABF62E35E668076BEAD2088', 16), new BigInteger('659EF8BA043916EEDE8911702B22', 16) ); $this->setBasePoint( new BigInteger('09487239995A5EE76B55F9C2F098', 16), new BigInteger('A89CE5AF8724C0A23E0E0FF77500', 16) ); $this->setOrder(new BigInteger('DB7C2ABF62E35E7628DFAC6561C5', 16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r2.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Prime; use phpseclib3\Math\BigInteger; class secp112r2 extends Prime { public function __construct() { // same modulo as secp112r1 $this->setModulo(new BigInteger('DB7C2ABF62E35E668076BEAD208B', 16)); $this->setCoefficients( new BigInteger('6127C24C05F38A0AAAF65C0EF02C', 16), new BigInteger('51DEF1815DB5ED74FCC34C85D709', 16) ); $this->setBasePoint( new BigInteger('4BA30AB5E892B4E1649DD0928643', 16), new BigInteger('ADCD46F5882E3747DEF36E956E97', 16) ); $this->setOrder(new BigInteger('36DF0AAFD8B8D7597CA10520D04B', 16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Prime; use phpseclib3\Math\BigInteger; class secp128r1 extends Prime { public function __construct() { $this->setModulo(new BigInteger('FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF', 16)); $this->setCoefficients( new BigInteger('FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC', 16), new BigInteger('E87579C11079F43DD824993C2CEE5ED3', 16) ); $this->setBasePoint( new BigInteger('161FF7528B899B2D0C28607CA52C5B86', 16), new BigInteger('CF5AC8395BAFEB13C02DA292DDED7A83', 16) ); $this->setOrder(new BigInteger('FFFFFFFE0000000075A30D1B9038A115', 16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r2.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Prime; use phpseclib3\Math\BigInteger; class secp128r2 extends Prime { public function __construct() { // same as secp128r1 $this->setModulo(new BigInteger('FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF', 16)); $this->setCoefficients( new BigInteger('D6031998D1B3BBFEBF59CC9BBFF9AEE1', 16), new BigInteger('5EEEFCA380D02919DC2C6558BB6D8A5D', 16) ); $this->setBasePoint( new BigInteger('7B6AA5D85E572983E6FB32A7CDEBC140', 16), new BigInteger('27B6916A894D3AEE7106FE805FC34B44', 16) ); $this->setOrder(new BigInteger('3FFFFFFF7FFFFFFFBE0024720613B5A3', 16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160k1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\KoblitzPrime; use phpseclib3\Math\BigInteger; class secp160k1 extends KoblitzPrime { public function __construct() { // same as secp160r2 $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73', 16)); $this->setCoefficients( new BigInteger('0000000000000000000000000000000000000000', 16), new BigInteger('0000000000000000000000000000000000000007', 16) ); $this->setBasePoint( new BigInteger('3B4C382CE37AA192A4019E763036F4F5DD4D7EBB', 16), new BigInteger('938CF935318FDCED6BC28286531733C3F03C4FEE', 16) ); $this->setOrder(new BigInteger('0100000000000000000001B8FA16DFAB9ACA16B6B3', 16)); $this->basis = []; $this->basis[] = [ 'a' => new BigInteger('0096341F1138933BC2F505', -16), 'b' => new BigInteger('FF6E9D0418C67BB8D5F562', -16) ]; $this->basis[] = [ 'a' => new BigInteger('01BDCB3A09AAAABEAFF4A8', -16), 'b' => new BigInteger('04D12329FF0EF498EA67', -16) ]; $this->beta = $this->factory->newInteger(new BigInteger('645B7345A143464942CC46D7CF4D5D1E1E6CBB68', -16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Prime; use phpseclib3\Math\BigInteger; class secp160r1 extends Prime { public function __construct() { $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF', 16)); $this->setCoefficients( new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC', 16), new BigInteger('1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45', 16) ); $this->setBasePoint( new BigInteger('4A96B5688EF573284664698968C38BB913CBFC82', 16), new BigInteger('23A628553168947D59DCC912042351377AC5FB32', 16) ); $this->setOrder(new BigInteger('0100000000000000000001F4C8F927AED3CA752257', 16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r2.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Prime; use phpseclib3\Math\BigInteger; class secp160r2 extends Prime { public function __construct() { // same as secp160k1 $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73', 16)); $this->setCoefficients( new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70', 16), new BigInteger('B4E134D3FB59EB8BAB57274904664D5AF50388BA', 16) ); $this->setBasePoint( new BigInteger('52DCB034293A117E1F4FF11B30F7199D3144CE6D', 16), new BigInteger('FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E', 16) ); $this->setOrder(new BigInteger('0100000000000000000000351EE786A818F3A1A16B', 16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192k1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\KoblitzPrime; use phpseclib3\Math\BigInteger; class secp192k1 extends KoblitzPrime { public function __construct() { $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37', 16)); $this->setCoefficients( new BigInteger('000000000000000000000000000000000000000000000000', 16), new BigInteger('000000000000000000000000000000000000000000000003', 16) ); $this->setBasePoint( new BigInteger('DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D', 16), new BigInteger('9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D', 16) ); $this->setOrder(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D', 16)); $this->basis = []; $this->basis[] = [ 'a' => new BigInteger('00B3FB3400DEC5C4ADCEB8655C', -16), 'b' => new BigInteger('8EE96418CCF4CFC7124FDA0F', -16) ]; $this->basis[] = [ 'a' => new BigInteger('01D90D03E8F096B9948B20F0A9', -16), 'b' => new BigInteger('42E49819ABBA9474E1083F6B', -16) ]; $this->beta = $this->factory->newInteger(new BigInteger('447A96E6C647963E2F7809FEAAB46947F34B0AA3CA0BBA74', -16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192r1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Prime; use phpseclib3\Math\BigInteger; class secp192r1 extends Prime { public function __construct() { $modulo = new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF', 16); $this->setModulo($modulo); // algorithm 2.27 from http://diamond.boisestate.edu/~liljanab/MATH308/GuideToECC.pdf#page=66 /* in theory this should be faster than regular modular reductions save for one small issue. to convert to / from base-2**8 with BCMath you have to call bcmul() and bcdiv() a lot. to convert to / from base-2**8 with PHP64 you have to call base256_rshift() a lot. in short, converting to / from base-2**8 is pretty expensive and that expense is enough to offset whatever else might be gained by a simplified reduction algorithm. now, if PHP supported unsigned integers things might be different. no bit-shifting would be required for the PHP engine and it'd be a lot faster. but as is, BigInteger uses base-2**31 or base-2**26 depending on whether or not the system is has a 32-bit or a 64-bit OS. */ /* $m_length = $this->getLengthInBytes(); $this->setReduction(function($c) use ($m_length) { $cBytes = $c->toBytes(); $className = $this->className; if (strlen($cBytes) > 2 * $m_length) { list(, $r) = $c->divide($className::$modulo); return $r; } $c = str_pad($cBytes, 48, "\0", STR_PAD_LEFT); $c = array_reverse(str_split($c, 8)); $null = "\0\0\0\0\0\0\0\0"; $s1 = new BigInteger($c[2] . $c[1] . $c[0], 256); $s2 = new BigInteger($null . $c[3] . $c[3], 256); $s3 = new BigInteger($c[4] . $c[4] . $null, 256); $s4 = new BigInteger($c[5] . $c[5] . $c[5], 256); $r = $s1->add($s2)->add($s3)->add($s4); while ($r->compare($className::$modulo) >= 0) { $r = $r->subtract($className::$modulo); } return $r; }); */ $this->setCoefficients( new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC', 16), new BigInteger('64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1', 16) ); $this->setBasePoint( new BigInteger('188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012', 16), new BigInteger('07192B95FFC8DA78631011ED6B24CDD573F977A11E794811', 16) ); $this->setOrder(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831', 16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224k1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\KoblitzPrime; use phpseclib3\Math\BigInteger; class secp224k1 extends KoblitzPrime { public function __construct() { $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D', 16)); $this->setCoefficients( new BigInteger('00000000000000000000000000000000000000000000000000000000', 16), new BigInteger('00000000000000000000000000000000000000000000000000000005', 16) ); $this->setBasePoint( new BigInteger('A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C', 16), new BigInteger('7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5', 16) ); $this->setOrder(new BigInteger('010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7', 16)); $this->basis = []; $this->basis[] = [ 'a' => new BigInteger('00B8ADF1378A6EB73409FA6C9C637D', -16), 'b' => new BigInteger('94730F82B358A3776A826298FA6F', -16) ]; $this->basis[] = [ 'a' => new BigInteger('01DCE8D2EC6184CAF0A972769FCC8B', -16), 'b' => new BigInteger('4D2100BA3DC75AAB747CCF355DEC', -16) ]; $this->beta = $this->factory->newInteger(new BigInteger('01F178FFA4B17C89E6F73AECE2AAD57AF4C0A748B63C830947B27E04', -16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224r1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Prime; use phpseclib3\Math\BigInteger; class secp224r1 extends Prime { public function __construct() { $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001', 16)); $this->setCoefficients( new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE', 16), new BigInteger('B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4', 16) ); $this->setBasePoint( new BigInteger('B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21', 16), new BigInteger('BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34', 16) ); $this->setOrder(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D', 16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256k1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; //use phpseclib3\Crypt\EC\BaseCurves\Prime; use phpseclib3\Crypt\EC\BaseCurves\KoblitzPrime; use phpseclib3\Math\BigInteger; //class secp256k1 extends Prime class secp256k1 extends KoblitzPrime { public function __construct() { $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F', 16)); $this->setCoefficients( new BigInteger('0000000000000000000000000000000000000000000000000000000000000000', 16), new BigInteger('0000000000000000000000000000000000000000000000000000000000000007', 16) ); $this->setOrder(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141', 16)); $this->setBasePoint( new BigInteger('79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798', 16), new BigInteger('483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8', 16) ); $this->basis = []; $this->basis[] = [ 'a' => new BigInteger('3086D221A7D46BCDE86C90E49284EB15', -16), 'b' => new BigInteger('FF1BBC8129FEF177D790AB8056F5401B3D', -16) ]; $this->basis[] = [ 'a' => new BigInteger('114CA50F7A8E2F3F657C1108D9D44CFD8', -16), 'b' => new BigInteger('3086D221A7D46BCDE86C90E49284EB15', -16) ]; $this->beta = $this->factory->newInteger(new BigInteger('7AE96A2B657C07106E64479EAC3434E99CF0497512F58995C1396C28719501EE', -16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256r1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Prime; use phpseclib3\Math\BigInteger; class secp256r1 extends Prime { public function __construct() { $this->setModulo(new BigInteger('FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF', 16)); $this->setCoefficients( new BigInteger('FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC', 16), new BigInteger('5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B', 16) ); $this->setBasePoint( new BigInteger('6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296', 16), new BigInteger('4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5', 16) ); $this->setOrder(new BigInteger('FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551', 16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp384r1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Prime; use phpseclib3\Math\BigInteger; class secp384r1 extends Prime { public function __construct() { $this->setModulo(new BigInteger( 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF', 16 )); $this->setCoefficients( new BigInteger( 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC', 16 ), new BigInteger( 'B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF', 16 ) ); $this->setBasePoint( new BigInteger( 'AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7', 16 ), new BigInteger( '3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F', 16 ) ); $this->setOrder(new BigInteger( 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973', 16 )); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp521r1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Prime; use phpseclib3\Math\BigInteger; class secp521r1 extends Prime { public function __construct() { $this->setModulo(new BigInteger('01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . 'FFFF', 16)); $this->setCoefficients( new BigInteger('01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . 'FFFC', 16), new BigInteger('0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF1' . '09E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B50' . '3F00', 16) ); $this->setBasePoint( new BigInteger('00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D' . '3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5' . 'BD66', 16), new BigInteger('011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E' . '662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD1' . '6650', 16) ); $this->setOrder(new BigInteger('01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . 'FFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E9138' . '6409', 16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Binary; use phpseclib3\Math\BigInteger; class sect113r1 extends Binary { public function __construct() { $this->setModulo(113, 9, 0); $this->setCoefficients( '003088250CA6E7C7FE649CE85820F7', '00E8BEE4D3E2260744188BE0E9C723' ); $this->setBasePoint( '009D73616F35F4AB1407D73562C10F', '00A52830277958EE84D1315ED31886' ); $this->setOrder(new BigInteger('0100000000000000D9CCEC8A39E56F', 16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r2.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Binary; use phpseclib3\Math\BigInteger; class sect113r2 extends Binary { public function __construct() { $this->setModulo(113, 9, 0); $this->setCoefficients( '00689918DBEC7E5A0DD6DFC0AA55C7', '0095E9A9EC9B297BD4BF36E059184F' ); $this->setBasePoint( '01A57A6A7B26CA5EF52FCDB8164797', '00B3ADC94ED1FE674C06E695BABA1D' ); $this->setOrder(new BigInteger('010000000000000108789B2496AF93', 16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Binary; use phpseclib3\Math\BigInteger; class sect131r1 extends Binary { public function __construct() { $this->setModulo(131, 8, 3, 2, 0); $this->setCoefficients( '07A11B09A76B562144418FF3FF8C2570B8', '0217C05610884B63B9C6C7291678F9D341' ); $this->setBasePoint( '0081BAF91FDF9833C40F9C181343638399', '078C6E7EA38C001F73C8134B1B4EF9E150' ); $this->setOrder(new BigInteger('0400000000000000023123953A9464B54D', 16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r2.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Binary; use phpseclib3\Math\BigInteger; class sect131r2 extends Binary { public function __construct() { $this->setModulo(131, 8, 3, 2, 0); $this->setCoefficients( '03E5A88919D7CAFCBF415F07C2176573B2', '04B8266A46C55657AC734CE38F018F2192' ); $this->setBasePoint( '0356DCD8F2F95031AD652D23951BB366A8', '0648F06D867940A5366D9E265DE9EB240F' ); $this->setOrder(new BigInteger('0400000000000000016954A233049BA98F', 16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163k1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Binary; use phpseclib3\Math\BigInteger; class sect163k1 extends Binary { public function __construct() { $this->setModulo(163, 7, 6, 3, 0); $this->setCoefficients( '000000000000000000000000000000000000000001', '000000000000000000000000000000000000000001' ); $this->setBasePoint( '02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8', '0289070FB05D38FF58321F2E800536D538CCDAA3D9' ); $this->setOrder(new BigInteger('04000000000000000000020108A2E0CC0D99F8A5EF', 16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Binary; use phpseclib3\Math\BigInteger; class sect163r1 extends Binary { public function __construct() { $this->setModulo(163, 7, 6, 3, 0); $this->setCoefficients( '07B6882CAAEFA84F9554FF8428BD88E246D2782AE2', '0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9' ); $this->setBasePoint( '0369979697AB43897789566789567F787A7876A654', '00435EDB42EFAFB2989D51FEFCE3C80988F41FF883' ); $this->setOrder(new BigInteger('03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B', 16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r2.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Binary; use phpseclib3\Math\BigInteger; class sect163r2 extends Binary { public function __construct() { $this->setModulo(163, 7, 6, 3, 0); $this->setCoefficients( '000000000000000000000000000000000000000001', '020A601907B8C953CA1481EB10512F78744A3205FD' ); $this->setBasePoint( '03F0EBA16286A2D57EA0991168D4994637E8343E36', '00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1' ); $this->setOrder(new BigInteger('040000000000000000000292FE77E70C12A4234C33', 16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Binary; use phpseclib3\Math\BigInteger; class sect193r1 extends Binary { public function __construct() { $this->setModulo(193, 15, 0); $this->setCoefficients( '0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01', '00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814' ); $this->setBasePoint( '01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1', '0025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05' ); $this->setOrder(new BigInteger('01000000000000000000000000C7F34A778F443ACC920EBA49', 16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r2.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Binary; use phpseclib3\Math\BigInteger; class sect193r2 extends Binary { public function __construct() { $this->setModulo(193, 15, 0); $this->setCoefficients( '0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B', '00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE' ); $this->setBasePoint( '00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F', '01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C' ); $this->setOrder(new BigInteger('010000000000000000000000015AAB561B005413CCD4EE99D5', 16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233k1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Binary; use phpseclib3\Math\BigInteger; class sect233k1 extends Binary { public function __construct() { $this->setModulo(233, 74, 0); $this->setCoefficients( '000000000000000000000000000000000000000000000000000000000000', '000000000000000000000000000000000000000000000000000000000001' ); $this->setBasePoint( '017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126', '01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3' ); $this->setOrder(new BigInteger('8000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF', 16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233r1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Binary; use phpseclib3\Math\BigInteger; class sect233r1 extends Binary { public function __construct() { $this->setModulo(233, 74, 0); $this->setCoefficients( '000000000000000000000000000000000000000000000000000000000001', '0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD' ); $this->setBasePoint( '00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B', '01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052' ); $this->setOrder(new BigInteger('01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7', 16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect239k1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Binary; use phpseclib3\Math\BigInteger; class sect239k1 extends Binary { public function __construct() { $this->setModulo(239, 158, 0); $this->setCoefficients( '000000000000000000000000000000000000000000000000000000000000', '000000000000000000000000000000000000000000000000000000000001' ); $this->setBasePoint( '29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC', '76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA' ); $this->setOrder(new BigInteger('2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5', 16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283k1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Binary; use phpseclib3\Math\BigInteger; class sect283k1 extends Binary { public function __construct() { $this->setModulo(283, 12, 7, 5, 0); $this->setCoefficients( '000000000000000000000000000000000000000000000000000000000000000000000000', '000000000000000000000000000000000000000000000000000000000000000000000001' ); $this->setBasePoint( '0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836', '01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259' ); $this->setOrder(new BigInteger('01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61', 16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283r1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Binary; use phpseclib3\Math\BigInteger; class sect283r1 extends Binary { public function __construct() { $this->setModulo(283, 12, 7, 5, 0); $this->setCoefficients( '000000000000000000000000000000000000000000000000000000000000000000000001', '027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5' ); $this->setBasePoint( '05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053', '03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4' ); $this->setOrder(new BigInteger('03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307', 16)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409k1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Binary; use phpseclib3\Math\BigInteger; class sect409k1 extends Binary { public function __construct() { $this->setModulo(409, 87, 0); $this->setCoefficients( '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001' ); $this->setBasePoint( '0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746', '01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B' ); $this->setOrder(new BigInteger( '7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F' . '83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF', 16 )); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409r1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Binary; use phpseclib3\Math\BigInteger; class sect409r1 extends Binary { public function __construct() { $this->setModulo(409, 87, 0); $this->setCoefficients( '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001', '0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F' ); $this->setBasePoint( '015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7', '0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706' ); $this->setOrder(new BigInteger( '010000000000000000000000000000000000000000000000000001E2' . 'AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173', 16 )); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571k1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Binary; use phpseclib3\Math\BigInteger; class sect571k1 extends Binary { public function __construct() { $this->setModulo(571, 10, 5, 2, 0); $this->setCoefficients( '000000000000000000000000000000000000000000000000000000000000000000000000' . '000000000000000000000000000000000000000000000000000000000000000000000000', '000000000000000000000000000000000000000000000000000000000000000000000000' . '000000000000000000000000000000000000000000000000000000000000000000000001' ); $this->setBasePoint( '026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA443709584' . '93B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972', '0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0' . 'AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3' ); $this->setOrder(new BigInteger( '020000000000000000000000000000000000000000000000000000000000000000000000' . '131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001', 16 )); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571r1.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Crypt\EC\Curves; use phpseclib3\Crypt\EC\BaseCurves\Binary; use phpseclib3\Math\BigInteger; class sect571r1 extends Binary { public function __construct() { $this->setModulo(571, 10, 5, 2, 0); $this->setCoefficients( '000000000000000000000000000000000000000000000000000000000000000000000000' . '000000000000000000000000000000000000000000000000000000000000000000000001', '02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD' . '8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A' ); $this->setBasePoint( '0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950' . 'F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19', '037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43' . 'BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B' ); $this->setOrder(new BigInteger( '03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . 'E661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47', 16 )); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/Common.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\EC\Formats\Keys; use phpseclib3\Common\Functions\Strings; use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; use phpseclib3\Crypt\EC\BaseCurves\Binary as BinaryCurve; use phpseclib3\Crypt\EC\BaseCurves\Prime as PrimeCurve; use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; use phpseclib3\Exception\UnsupportedCurveException; use phpseclib3\File\ASN1; use phpseclib3\File\ASN1\Maps; use phpseclib3\Math\BigInteger; /** * Generic EC Key Parsing Helper functions * * @author Jim Wigginton */ trait Common { /** * Curve OIDs * * @var array */ private static $curveOIDs = []; /** * Child OIDs loaded * * @var bool */ protected static $childOIDsLoaded = false; /** * Use Named Curves * * @var bool */ private static $useNamedCurves = true; /** * Initialize static variables */ private static function initialize_static_variables() { if (empty(self::$curveOIDs)) { // the sec* curves are from the standards for efficient cryptography group // sect* curves are curves over binary finite fields // secp* curves are curves over prime finite fields // sec*r* curves are regular curves; sec*k* curves are koblitz curves // brainpool*r* curves are regular prime finite field curves // brainpool*t* curves are twisted versions of the brainpool*r* curves self::$curveOIDs = [ 'prime192v1' => '1.2.840.10045.3.1.1', // J.5.1, example 1 (aka secp192r1) 'prime192v2' => '1.2.840.10045.3.1.2', // J.5.1, example 2 'prime192v3' => '1.2.840.10045.3.1.3', // J.5.1, example 3 'prime239v1' => '1.2.840.10045.3.1.4', // J.5.2, example 1 'prime239v2' => '1.2.840.10045.3.1.5', // J.5.2, example 2 'prime239v3' => '1.2.840.10045.3.1.6', // J.5.2, example 3 'prime256v1' => '1.2.840.10045.3.1.7', // J.5.3, example 1 (aka secp256r1) // https://tools.ietf.org/html/rfc5656#section-10 'nistp256' => '1.2.840.10045.3.1.7', // aka secp256r1 'nistp384' => '1.3.132.0.34', // aka secp384r1 'nistp521' => '1.3.132.0.35', // aka secp521r1 'nistk163' => '1.3.132.0.1', // aka sect163k1 'nistp192' => '1.2.840.10045.3.1.1', // aka secp192r1 'nistp224' => '1.3.132.0.33', // aka secp224r1 'nistk233' => '1.3.132.0.26', // aka sect233k1 'nistb233' => '1.3.132.0.27', // aka sect233r1 'nistk283' => '1.3.132.0.16', // aka sect283k1 'nistk409' => '1.3.132.0.36', // aka sect409k1 'nistb409' => '1.3.132.0.37', // aka sect409r1 'nistt571' => '1.3.132.0.38', // aka sect571k1 // from https://tools.ietf.org/html/rfc5915 'secp192r1' => '1.2.840.10045.3.1.1', // aka prime192v1 'sect163k1' => '1.3.132.0.1', 'sect163r2' => '1.3.132.0.15', 'secp224r1' => '1.3.132.0.33', 'sect233k1' => '1.3.132.0.26', 'sect233r1' => '1.3.132.0.27', 'secp256r1' => '1.2.840.10045.3.1.7', // aka prime256v1 'sect283k1' => '1.3.132.0.16', 'sect283r1' => '1.3.132.0.17', 'secp384r1' => '1.3.132.0.34', 'sect409k1' => '1.3.132.0.36', 'sect409r1' => '1.3.132.0.37', 'secp521r1' => '1.3.132.0.35', 'sect571k1' => '1.3.132.0.38', 'sect571r1' => '1.3.132.0.39', // from http://www.secg.org/SEC2-Ver-1.0.pdf 'secp112r1' => '1.3.132.0.6', 'secp112r2' => '1.3.132.0.7', 'secp128r1' => '1.3.132.0.28', 'secp128r2' => '1.3.132.0.29', 'secp160k1' => '1.3.132.0.9', 'secp160r1' => '1.3.132.0.8', 'secp160r2' => '1.3.132.0.30', 'secp192k1' => '1.3.132.0.31', 'secp224k1' => '1.3.132.0.32', 'secp256k1' => '1.3.132.0.10', 'sect113r1' => '1.3.132.0.4', 'sect113r2' => '1.3.132.0.5', 'sect131r1' => '1.3.132.0.22', 'sect131r2' => '1.3.132.0.23', 'sect163r1' => '1.3.132.0.2', 'sect193r1' => '1.3.132.0.24', 'sect193r2' => '1.3.132.0.25', 'sect239k1' => '1.3.132.0.3', // from http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.202.2977&rep=rep1&type=pdf#page=36 /* 'c2pnb163v1' => '1.2.840.10045.3.0.1', // J.4.1, example 1 'c2pnb163v2' => '1.2.840.10045.3.0.2', // J.4.1, example 2 'c2pnb163v3' => '1.2.840.10045.3.0.3', // J.4.1, example 3 'c2pnb172w1' => '1.2.840.10045.3.0.4', // J.4.2, example 1 'c2tnb191v1' => '1.2.840.10045.3.0.5', // J.4.3, example 1 'c2tnb191v2' => '1.2.840.10045.3.0.6', // J.4.3, example 2 'c2tnb191v3' => '1.2.840.10045.3.0.7', // J.4.3, example 3 'c2onb191v4' => '1.2.840.10045.3.0.8', // J.4.3, example 4 'c2onb191v5' => '1.2.840.10045.3.0.9', // J.4.3, example 5 'c2pnb208w1' => '1.2.840.10045.3.0.10', // J.4.4, example 1 'c2tnb239v1' => '1.2.840.10045.3.0.11', // J.4.5, example 1 'c2tnb239v2' => '1.2.840.10045.3.0.12', // J.4.5, example 2 'c2tnb239v3' => '1.2.840.10045.3.0.13', // J.4.5, example 3 'c2onb239v4' => '1.2.840.10045.3.0.14', // J.4.5, example 4 'c2onb239v5' => '1.2.840.10045.3.0.15', // J.4.5, example 5 'c2pnb272w1' => '1.2.840.10045.3.0.16', // J.4.6, example 1 'c2pnb304w1' => '1.2.840.10045.3.0.17', // J.4.7, example 1 'c2tnb359v1' => '1.2.840.10045.3.0.18', // J.4.8, example 1 'c2pnb368w1' => '1.2.840.10045.3.0.19', // J.4.9, example 1 'c2tnb431r1' => '1.2.840.10045.3.0.20', // J.4.10, example 1 */ // http://www.ecc-brainpool.org/download/Domain-parameters.pdf // https://tools.ietf.org/html/rfc5639 'brainpoolP160r1' => '1.3.36.3.3.2.8.1.1.1', 'brainpoolP160t1' => '1.3.36.3.3.2.8.1.1.2', 'brainpoolP192r1' => '1.3.36.3.3.2.8.1.1.3', 'brainpoolP192t1' => '1.3.36.3.3.2.8.1.1.4', 'brainpoolP224r1' => '1.3.36.3.3.2.8.1.1.5', 'brainpoolP224t1' => '1.3.36.3.3.2.8.1.1.6', 'brainpoolP256r1' => '1.3.36.3.3.2.8.1.1.7', 'brainpoolP256t1' => '1.3.36.3.3.2.8.1.1.8', 'brainpoolP320r1' => '1.3.36.3.3.2.8.1.1.9', 'brainpoolP320t1' => '1.3.36.3.3.2.8.1.1.10', 'brainpoolP384r1' => '1.3.36.3.3.2.8.1.1.11', 'brainpoolP384t1' => '1.3.36.3.3.2.8.1.1.12', 'brainpoolP512r1' => '1.3.36.3.3.2.8.1.1.13', 'brainpoolP512t1' => '1.3.36.3.3.2.8.1.1.14' ]; ASN1::loadOIDs([ 'prime-field' => '1.2.840.10045.1.1', 'characteristic-two-field' => '1.2.840.10045.1.2', 'characteristic-two-basis' => '1.2.840.10045.1.2.3', // per http://www.secg.org/SEC1-Ver-1.0.pdf#page=84, gnBasis "not used here" 'gnBasis' => '1.2.840.10045.1.2.3.1', // NULL 'tpBasis' => '1.2.840.10045.1.2.3.2', // Trinomial 'ppBasis' => '1.2.840.10045.1.2.3.3' // Pentanomial ] + self::$curveOIDs); } } /** * Explicitly set the curve * * If the key contains an implicit curve phpseclib needs the curve * to be explicitly provided * * @param BaseCurve $curve */ public static function setImplicitCurve(BaseCurve $curve) { self::$implicitCurve = $curve; } /** * Returns an instance of \phpseclib3\Crypt\EC\BaseCurves\Base based * on the curve parameters * * @param array $params * @return BaseCurve|false */ protected static function loadCurveByParam(array $params) { if (count($params) > 1) { throw new \RuntimeException('No parameters are present'); } if (isset($params['namedCurve'])) { $curve = '\phpseclib3\Crypt\EC\Curves\\' . $params['namedCurve']; if (!class_exists($curve)) { throw new UnsupportedCurveException('Named Curve of ' . $params['namedCurve'] . ' is not supported'); } return new $curve(); } if (isset($params['implicitCurve'])) { if (!isset(self::$implicitCurve)) { throw new \RuntimeException('Implicit curves can be provided by calling setImplicitCurve'); } return self::$implicitCurve; } if (isset($params['specifiedCurve'])) { $data = $params['specifiedCurve']; switch ($data['fieldID']['fieldType']) { case 'prime-field': $curve = new PrimeCurve(); $curve->setModulo($data['fieldID']['parameters']); $curve->setCoefficients( new BigInteger($data['curve']['a'], 256), new BigInteger($data['curve']['b'], 256) ); $point = self::extractPoint("\0" . $data['base'], $curve); $curve->setBasePoint(...$point); $curve->setOrder($data['order']); return $curve; case 'characteristic-two-field': $curve = new BinaryCurve(); $params = ASN1::decodeBER($data['fieldID']['parameters']); $params = ASN1::asn1map($params[0], Maps\Characteristic_two::MAP); $modulo = [(int) $params['m']->toString()]; switch ($params['basis']) { case 'tpBasis': $modulo[] = (int) $params['parameters']->toString(); break; case 'ppBasis': $temp = ASN1::decodeBER($params['parameters']); $temp = ASN1::asn1map($temp[0], Maps\Pentanomial::MAP); $modulo[] = (int) $temp['k3']->toString(); $modulo[] = (int) $temp['k2']->toString(); $modulo[] = (int) $temp['k1']->toString(); } $modulo[] = 0; $curve->setModulo(...$modulo); $len = ceil($modulo[0] / 8); $curve->setCoefficients( Strings::bin2hex($data['curve']['a']), Strings::bin2hex($data['curve']['b']) ); $point = self::extractPoint("\0" . $data['base'], $curve); $curve->setBasePoint(...$point); $curve->setOrder($data['order']); return $curve; default: throw new UnsupportedCurveException('Field Type of ' . $data['fieldID']['fieldType'] . ' is not supported'); } } throw new \RuntimeException('No valid parameters are present'); } /** * Extract points from a string * * Supports both compressed and uncompressed points * * @param string $str * @param BaseCurve $curve * @return object[] */ public static function extractPoint($str, BaseCurve $curve) { if ($curve instanceof TwistedEdwardsCurve) { // first step of point deciding as discussed at the following URL's: // https://tools.ietf.org/html/rfc8032#section-5.1.3 // https://tools.ietf.org/html/rfc8032#section-5.2.3 $y = $str; $y = strrev($y); $sign = (bool) (ord($y[0]) & 0x80); $y[0] = $y[0] & chr(0x7F); $y = new BigInteger($y, 256); if ($y->compare($curve->getModulo()) >= 0) { throw new \RuntimeException('The Y coordinate should not be >= the modulo'); } $point = $curve->recoverX($y, $sign); if (!$curve->verifyPoint($point)) { throw new \RuntimeException('Unable to verify that point exists on curve'); } return $point; } // the first byte of a bit string represents the number of bits in the last byte that are to be ignored but, // currently, bit strings wanting a non-zero amount of bits trimmed are not supported if (($val = Strings::shift($str)) != "\0") { throw new \UnexpectedValueException('extractPoint expects the first byte to be null - not ' . Strings::bin2hex($val)); } if ($str == "\0") { return []; } $keylen = strlen($str); $order = $curve->getLengthInBytes(); // point compression is being used if ($keylen == $order + 1) { return $curve->derivePoint($str); } // point compression is not being used if ($keylen == 2 * $order + 1) { preg_match("#(.)(.{{$order}})(.{{$order}})#s", $str, $matches); list(, $w, $x, $y) = $matches; if ($w != "\4") { throw new \UnexpectedValueException('The first byte of an uncompressed point should be 04 - not ' . Strings::bin2hex($val)); } $point = [ $curve->convertInteger(new BigInteger($x, 256)), $curve->convertInteger(new BigInteger($y, 256)) ]; if (!$curve->verifyPoint($point)) { throw new \RuntimeException('Unable to verify that point exists on curve'); } return $point; } throw new \UnexpectedValueException('The string representation of the points is not of an appropriate length'); } /** * Encode Parameters * * @todo Maybe at some point this could be moved to __toString() for each of the curves? * @param BaseCurve $curve * @param bool $returnArray optional * @param array $options optional * @return string|false */ private static function encodeParameters(BaseCurve $curve, $returnArray = false, array $options = []) { $useNamedCurves = isset($options['namedCurve']) ? $options['namedCurve'] : self::$useNamedCurves; $reflect = new \ReflectionClass($curve); $name = $reflect->getShortName(); if ($useNamedCurves) { if (isset(self::$curveOIDs[$name])) { if ($reflect->isFinal()) { $reflect = $reflect->getParentClass(); $name = $reflect->getShortName(); } return $returnArray ? ['namedCurve' => $name] : ASN1::encodeDER(['namedCurve' => $name], Maps\ECParameters::MAP); } foreach (new \DirectoryIterator(__DIR__ . '/../../Curves/') as $file) { if ($file->getExtension() != 'php') { continue; } $testName = $file->getBasename('.php'); $class = 'phpseclib3\Crypt\EC\Curves\\' . $testName; $reflect = new \ReflectionClass($class); if ($reflect->isFinal()) { continue; } $candidate = new $class(); switch ($name) { case 'Prime': if (!$candidate instanceof PrimeCurve) { break; } if (!$candidate->getModulo()->equals($curve->getModulo())) { break; } if ($candidate->getA()->toBytes() != $curve->getA()->toBytes()) { break; } if ($candidate->getB()->toBytes() != $curve->getB()->toBytes()) { break; } list($candidateX, $candidateY) = $candidate->getBasePoint(); list($curveX, $curveY) = $curve->getBasePoint(); if ($candidateX->toBytes() != $curveX->toBytes()) { break; } if ($candidateY->toBytes() != $curveY->toBytes()) { break; } return $returnArray ? ['namedCurve' => $testName] : ASN1::encodeDER(['namedCurve' => $testName], Maps\ECParameters::MAP); case 'Binary': if (!$candidate instanceof BinaryCurve) { break; } if ($candidate->getModulo() != $curve->getModulo()) { break; } if ($candidate->getA()->toBytes() != $curve->getA()->toBytes()) { break; } if ($candidate->getB()->toBytes() != $curve->getB()->toBytes()) { break; } list($candidateX, $candidateY) = $candidate->getBasePoint(); list($curveX, $curveY) = $curve->getBasePoint(); if ($candidateX->toBytes() != $curveX->toBytes()) { break; } if ($candidateY->toBytes() != $curveY->toBytes()) { break; } return $returnArray ? ['namedCurve' => $testName] : ASN1::encodeDER(['namedCurve' => $testName], Maps\ECParameters::MAP); } } } $order = $curve->getOrder(); // we could try to calculate the order thusly: // https://crypto.stackexchange.com/a/27914/4520 // https://en.wikipedia.org/wiki/Schoof%E2%80%93Elkies%E2%80%93Atkin_algorithm if (!$order) { throw new \RuntimeException('Specified Curves need the order to be specified'); } $point = $curve->getBasePoint(); $x = $point[0]->toBytes(); $y = $point[1]->toBytes(); if ($curve instanceof PrimeCurve) { /* * valid versions are: * * ecdpVer1: * - neither the curve or the base point are generated verifiably randomly. * ecdpVer2: * - curve and base point are generated verifiably at random and curve.seed is present * ecdpVer3: * - base point is generated verifiably at random but curve is not. curve.seed is present */ // other (optional) parameters can be calculated using the methods discused at // https://crypto.stackexchange.com/q/28947/4520 $data = [ 'version' => 'ecdpVer1', 'fieldID' => [ 'fieldType' => 'prime-field', 'parameters' => $curve->getModulo() ], 'curve' => [ 'a' => $curve->getA()->toBytes(), 'b' => $curve->getB()->toBytes() ], 'base' => "\4" . $x . $y, 'order' => $order ]; return $returnArray ? ['specifiedCurve' => $data] : ASN1::encodeDER(['specifiedCurve' => $data], Maps\ECParameters::MAP); } if ($curve instanceof BinaryCurve) { $modulo = $curve->getModulo(); $basis = count($modulo); $m = array_shift($modulo); array_pop($modulo); // the last parameter should always be 0 //rsort($modulo); switch ($basis) { case 3: $basis = 'tpBasis'; $modulo = new BigInteger($modulo[0]); break; case 5: $basis = 'ppBasis'; // these should be in strictly ascending order (hence the commented out rsort above) $modulo = [ 'k1' => new BigInteger($modulo[2]), 'k2' => new BigInteger($modulo[1]), 'k3' => new BigInteger($modulo[0]) ]; $modulo = ASN1::encodeDER($modulo, Maps\Pentanomial::MAP); $modulo = new ASN1\Element($modulo); } $params = ASN1::encodeDER([ 'm' => new BigInteger($m), 'basis' => $basis, 'parameters' => $modulo ], Maps\Characteristic_two::MAP); $params = new ASN1\Element($params); $a = ltrim($curve->getA()->toBytes(), "\0"); if (!strlen($a)) { $a = "\0"; } $b = ltrim($curve->getB()->toBytes(), "\0"); if (!strlen($b)) { $b = "\0"; } $data = [ 'version' => 'ecdpVer1', 'fieldID' => [ 'fieldType' => 'characteristic-two-field', 'parameters' => $params ], 'curve' => [ 'a' => $a, 'b' => $b ], 'base' => "\4" . $x . $y, 'order' => $order ]; return $returnArray ? ['specifiedCurve' => $data] : ASN1::encodeDER(['specifiedCurve' => $data], Maps\ECParameters::MAP); } throw new UnsupportedCurveException('Curve cannot be serialized'); } /** * Use Specified Curve * * A specified curve has all the coefficients, the base points, etc, explicitely included. * A specified curve is a more verbose way of representing a curve */ public static function useSpecifiedCurve() { self::$useNamedCurves = false; } /** * Use Named Curve * * A named curve does not include any parameters. It is up to the EC parameters to * know what the coefficients, the base points, etc, are from the name of the curve. * A named curve is a more concise way of representing a curve */ public static function useNamedCurve() { self::$useNamedCurves = true; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/JWK.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\EC\Formats\Keys; use phpseclib3\Common\Functions\Strings; use phpseclib3\Crypt\Common\Formats\Keys\JWK as Progenitor; use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; use phpseclib3\Crypt\EC\Curves\Ed25519; use phpseclib3\Crypt\EC\Curves\secp256k1; use phpseclib3\Crypt\EC\Curves\secp256r1; use phpseclib3\Crypt\EC\Curves\secp384r1; use phpseclib3\Crypt\EC\Curves\secp521r1; use phpseclib3\Exception\UnsupportedCurveException; use phpseclib3\Math\BigInteger; /** * JWK Formatted EC Handler * * @author Jim Wigginton */ abstract class JWK extends Progenitor { use Common; /** * Break a public or private key down into its constituent components * * @param string $key * @param string $password optional * @return array */ public static function load($key, $password = '') { $key = parent::load($key, $password); switch ($key->kty) { case 'EC': switch ($key->crv) { case 'P-256': case 'P-384': case 'P-521': case 'secp256k1': break; default: throw new UnsupportedCurveException('Only P-256, P-384, P-521 and secp256k1 curves are accepted (' . $key->crv . ' provided)'); } break; case 'OKP': switch ($key->crv) { case 'Ed25519': case 'Ed448': break; default: throw new UnsupportedCurveException('Only Ed25519 and Ed448 curves are accepted (' . $key->crv . ' provided)'); } break; default: throw new \Exception('Only EC and OKP JWK keys are supported'); } $curve = '\phpseclib3\Crypt\EC\Curves\\' . str_replace('P-', 'nistp', $key->crv); $curve = new $curve(); if ($curve instanceof TwistedEdwardsCurve) { $QA = self::extractPoint(Strings::base64url_decode($key->x), $curve); if (!isset($key->d)) { return compact('curve', 'QA'); } $arr = $curve->extractSecret(Strings::base64url_decode($key->d)); return compact('curve', 'QA') + $arr; } $QA = [ $curve->convertInteger(new BigInteger(Strings::base64url_decode($key->x), 256)), $curve->convertInteger(new BigInteger(Strings::base64url_decode($key->y), 256)) ]; if (!$curve->verifyPoint($QA)) { throw new \RuntimeException('Unable to verify that point exists on curve'); } if (!isset($key->d)) { return compact('curve', 'QA'); } $dA = new BigInteger(Strings::base64url_decode($key->d), 256); $curve->rangeCheck($dA); return compact('curve', 'dA', 'QA'); } /** * Returns the alias that corresponds to a curve * * @return string */ private static function getAlias(BaseCurve $curve) { switch (true) { case $curve instanceof secp256r1: return 'P-256'; case $curve instanceof secp384r1: return 'P-384'; case $curve instanceof secp521r1: return 'P-521'; case $curve instanceof secp256k1: return 'secp256k1'; } $reflect = new \ReflectionClass($curve); $curveName = $reflect->isFinal() ? $reflect->getParentClass()->getShortName() : $reflect->getShortName(); throw new UnsupportedCurveException("$curveName is not a supported curve"); } /** * Return the array superstructure for an EC public key * * @param BaseCurve $curve * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey * @return array */ private static function savePublicKeyHelper(BaseCurve $curve, array $publicKey) { if ($curve instanceof TwistedEdwardsCurve) { return [ 'kty' => 'OKP', 'crv' => $curve instanceof Ed25519 ? 'Ed25519' : 'Ed448', 'x' => Strings::base64url_encode($curve->encodePoint($publicKey)) ]; } return [ 'kty' => 'EC', 'crv' => self::getAlias($curve), 'x' => Strings::base64url_encode($publicKey[0]->toBytes()), 'y' => Strings::base64url_encode($publicKey[1]->toBytes()) ]; } /** * Convert an EC public key to the appropriate format * * @param BaseCurve $curve * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey * @param array $options optional * @return string */ public static function savePublicKey(BaseCurve $curve, array $publicKey, array $options = []) { $key = self::savePublicKeyHelper($curve, $publicKey); return self::wrapKey($key, $options); } /** * Convert a private key to the appropriate format. * * @param BigInteger $privateKey * @param Ed25519 $curve * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey * @param string $secret optional * @param string $password optional * @param array $options optional * @return string */ public static function savePrivateKey(BigInteger $privateKey, BaseCurve $curve, array $publicKey, $secret = null, $password = '', array $options = []) { $key = self::savePublicKeyHelper($curve, $publicKey); $key['d'] = $curve instanceof TwistedEdwardsCurve ? $secret : $privateKey->toBytes(); $key['d'] = Strings::base64url_encode($key['d']); return self::wrapKey($key, $options); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPrivate.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\EC\Formats\Keys; use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; use phpseclib3\Crypt\EC\Curves\Curve25519; use phpseclib3\Crypt\EC\Curves\Curve448; use phpseclib3\Exception\UnsupportedFormatException; use phpseclib3\Math\BigInteger; /** * Montgomery Curve Private Key Handler * * @author Jim Wigginton */ abstract class MontgomeryPrivate { /** * Is invisible flag * */ const IS_INVISIBLE = true; /** * Break a public or private key down into its constituent components * * @param string $key * @param string $password optional * @return array */ public static function load($key, $password = '') { switch (strlen($key)) { case 32: $curve = new Curve25519(); break; case 56: $curve = new Curve448(); break; default: throw new \LengthException('The only supported lengths are 32 and 56'); } $components = ['curve' => $curve]; $components['dA'] = new BigInteger($key, 256); $curve->rangeCheck($components['dA']); // note that EC::getEncodedCoordinates does some additional "magic" (it does strrev on the result) $components['QA'] = $components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA']); return $components; } /** * Convert an EC public key to the appropriate format * * @param MontgomeryCurve $curve * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey * @return string */ public static function savePublicKey(MontgomeryCurve $curve, array $publicKey) { return strrev($publicKey[0]->toBytes()); } /** * Convert a private key to the appropriate format. * * @param BigInteger $privateKey * @param MontgomeryCurve $curve * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey * @param string $secret optional * @param string $password optional * @return string */ public static function savePrivateKey(BigInteger $privateKey, MontgomeryCurve $curve, array $publicKey, $secret = null, $password = '') { if (!empty($password) && is_string($password)) { throw new UnsupportedFormatException('MontgomeryPrivate private keys do not support encryption'); } return $privateKey->toBytes(); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPublic.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\EC\Formats\Keys; use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; use phpseclib3\Crypt\EC\Curves\Curve25519; use phpseclib3\Crypt\EC\Curves\Curve448; use phpseclib3\Math\BigInteger; /** * Montgomery Public Key Handler * * @author Jim Wigginton */ abstract class MontgomeryPublic { /** * Is invisible flag * */ const IS_INVISIBLE = true; /** * Break a public or private key down into its constituent components * * @param string $key * @param string $password optional * @return array */ public static function load($key, $password = '') { switch (strlen($key)) { case 32: $curve = new Curve25519(); break; case 56: $curve = new Curve448(); break; default: throw new \LengthException('The only supported lengths are 32 and 56'); } $components = ['curve' => $curve]; $components['QA'] = [$components['curve']->convertInteger(new BigInteger(strrev($key), 256))]; return $components; } /** * Convert an EC public key to the appropriate format * * @param MontgomeryCurve $curve * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey * @return string */ public static function savePublicKey(MontgomeryCurve $curve, array $publicKey) { return strrev($publicKey[0]->toBytes()); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/OpenSSH.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\EC\Formats\Keys; use phpseclib3\Common\Functions\Strings; use phpseclib3\Crypt\Common\Formats\Keys\OpenSSH as Progenitor; use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; use phpseclib3\Crypt\EC\Curves\Ed25519; use phpseclib3\Exception\UnsupportedCurveException; use phpseclib3\Math\BigInteger; /** * OpenSSH Formatted EC Key Handler * * @author Jim Wigginton */ abstract class OpenSSH extends Progenitor { use Common; /** * Supported Key Types * * @var array */ protected static $types = [ 'ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp384', 'ecdsa-sha2-nistp521', 'ssh-ed25519' ]; /** * Break a public or private key down into its constituent components * * @param string $key * @param string $password optional * @return array */ public static function load($key, $password = '') { $parsed = parent::load($key, $password); if (isset($parsed['paddedKey'])) { $paddedKey = $parsed['paddedKey']; list($type) = Strings::unpackSSH2('s', $paddedKey); if ($type != $parsed['type']) { throw new \RuntimeException("The public and private keys are not of the same type ($type vs $parsed[type])"); } if ($type == 'ssh-ed25519') { list(, $key, $comment) = Strings::unpackSSH2('sss', $paddedKey); $key = libsodium::load($key); $key['comment'] = $comment; return $key; } list($curveName, $publicKey, $privateKey, $comment) = Strings::unpackSSH2('ssis', $paddedKey); $curve = self::loadCurveByParam(['namedCurve' => $curveName]); $curve->rangeCheck($privateKey); return [ 'curve' => $curve, 'dA' => $privateKey, 'QA' => self::extractPoint("\0$publicKey", $curve), 'comment' => $comment ]; } if ($parsed['type'] == 'ssh-ed25519') { if (Strings::shift($parsed['publicKey'], 4) != "\0\0\0\x20") { throw new \RuntimeException('Length of ssh-ed25519 key should be 32'); } $curve = new Ed25519(); $qa = self::extractPoint($parsed['publicKey'], $curve); } else { list($curveName, $publicKey) = Strings::unpackSSH2('ss', $parsed['publicKey']); $curveName = '\phpseclib3\Crypt\EC\Curves\\' . $curveName; $curve = new $curveName(); $qa = self::extractPoint("\0" . $publicKey, $curve); } return [ 'curve' => $curve, 'QA' => $qa, 'comment' => $parsed['comment'] ]; } /** * Returns the alias that corresponds to a curve * * @return string */ private static function getAlias(BaseCurve $curve) { self::initialize_static_variables(); $reflect = new \ReflectionClass($curve); $name = $reflect->getShortName(); $oid = self::$curveOIDs[$name]; $aliases = array_filter(self::$curveOIDs, function ($v) use ($oid) { return $v == $oid; }); $aliases = array_keys($aliases); for ($i = 0; $i < count($aliases); $i++) { if (in_array('ecdsa-sha2-' . $aliases[$i], self::$types)) { $alias = $aliases[$i]; break; } } if (!isset($alias)) { throw new UnsupportedCurveException($name . ' is not a curve that the OpenSSH plugin supports'); } return $alias; } /** * Convert an EC public key to the appropriate format * * @param BaseCurve $curve * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey * @param array $options optional * @return string */ public static function savePublicKey(BaseCurve $curve, array $publicKey, array $options = []) { $comment = isset($options['comment']) ? $options['comment'] : self::$comment; if ($curve instanceof Ed25519) { $key = Strings::packSSH2('ss', 'ssh-ed25519', $curve->encodePoint($publicKey)); if (isset($options['binary']) ? $options['binary'] : self::$binary) { return $key; } $key = 'ssh-ed25519 ' . base64_encode($key) . ' ' . $comment; return $key; } $alias = self::getAlias($curve); $points = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); $key = Strings::packSSH2('sss', 'ecdsa-sha2-' . $alias, $alias, $points); if (isset($options['binary']) ? $options['binary'] : self::$binary) { return $key; } $key = 'ecdsa-sha2-' . $alias . ' ' . base64_encode($key) . ' ' . $comment; return $key; } /** * Convert a private key to the appropriate format. * * @param BigInteger $privateKey * @param Ed25519 $curve * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey * @param string $secret optional * @param string $password optional * @param array $options optional * @return string */ public static function savePrivateKey(BigInteger $privateKey, BaseCurve $curve, array $publicKey, $secret = null, $password = '', array $options = []) { if ($curve instanceof Ed25519) { if (!isset($secret)) { throw new \RuntimeException('Private Key does not have a secret set'); } if (strlen($secret) != 32) { throw new \RuntimeException('Private Key secret is not of the correct length'); } $pubKey = $curve->encodePoint($publicKey); $publicKey = Strings::packSSH2('ss', 'ssh-ed25519', $pubKey); $privateKey = Strings::packSSH2('sss', 'ssh-ed25519', $pubKey, $secret . $pubKey); return self::wrapPrivateKey($publicKey, $privateKey, $password, $options); } $alias = self::getAlias($curve); $points = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); $publicKey = self::savePublicKey($curve, $publicKey, ['binary' => true]); $privateKey = Strings::packSSH2('sssi', 'ecdsa-sha2-' . $alias, $alias, $points, $privateKey); return self::wrapPrivateKey($publicKey, $privateKey, $password, $options); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS1.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\EC\Formats\Keys; use phpseclib3\Common\Functions\Strings; use phpseclib3\Crypt\Common\Formats\Keys\PKCS1 as Progenitor; use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; use phpseclib3\Exception\UnsupportedCurveException; use phpseclib3\File\ASN1; use phpseclib3\File\ASN1\Maps; use phpseclib3\Math\BigInteger; /** * "PKCS1" (RFC5915) Formatted EC Key Handler * * @author Jim Wigginton */ abstract class PKCS1 extends Progenitor { use Common; /** * Break a public or private key down into its constituent components * * @param string $key * @param string $password optional * @return array */ public static function load($key, $password = '') { self::initialize_static_variables(); if (!Strings::is_stringable($key)) { throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); } if (strpos($key, 'BEGIN EC PARAMETERS') && strpos($key, 'BEGIN EC PRIVATE KEY')) { $components = []; preg_match('#-*BEGIN EC PRIVATE KEY-*[^-]*-*END EC PRIVATE KEY-*#s', $key, $matches); $decoded = parent::load($matches[0], $password); $decoded = ASN1::decodeBER($decoded); if (!$decoded) { throw new \RuntimeException('Unable to decode BER'); } $ecPrivate = ASN1::asn1map($decoded[0], Maps\ECPrivateKey::MAP); if (!is_array($ecPrivate)) { throw new \RuntimeException('Unable to perform ASN1 mapping'); } if (isset($ecPrivate['parameters'])) { $components['curve'] = self::loadCurveByParam($ecPrivate['parameters']); } preg_match('#-*BEGIN EC PARAMETERS-*[^-]*-*END EC PARAMETERS-*#s', $key, $matches); $decoded = parent::load($matches[0], ''); $decoded = ASN1::decodeBER($decoded); if (!$decoded) { throw new \RuntimeException('Unable to decode BER'); } $ecParams = ASN1::asn1map($decoded[0], Maps\ECParameters::MAP); if (!is_array($ecParams)) { throw new \RuntimeException('Unable to perform ASN1 mapping'); } $ecParams = self::loadCurveByParam($ecParams); // comparing $ecParams and $components['curve'] directly won't work because they'll have different Math\Common\FiniteField classes // even if the modulo is the same if (isset($components['curve']) && self::encodeParameters($ecParams, false, []) != self::encodeParameters($components['curve'], false, [])) { throw new \RuntimeException('EC PARAMETERS does not correspond to EC PRIVATE KEY'); } if (!isset($components['curve'])) { $components['curve'] = $ecParams; } $components['dA'] = new BigInteger($ecPrivate['privateKey'], 256); $components['curve']->rangeCheck($components['dA']); $components['QA'] = isset($ecPrivate['publicKey']) ? self::extractPoint($ecPrivate['publicKey'], $components['curve']) : $components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA']); return $components; } $key = parent::load($key, $password); $decoded = ASN1::decodeBER($key); if (!$decoded) { throw new \RuntimeException('Unable to decode BER'); } $key = ASN1::asn1map($decoded[0], Maps\ECParameters::MAP); if (is_array($key)) { return ['curve' => self::loadCurveByParam($key)]; } $key = ASN1::asn1map($decoded[0], Maps\ECPrivateKey::MAP); if (!is_array($key)) { throw new \RuntimeException('Unable to perform ASN1 mapping'); } if (!isset($key['parameters'])) { throw new \RuntimeException('Key cannot be loaded without parameters'); } $components = []; $components['curve'] = self::loadCurveByParam($key['parameters']); $components['dA'] = new BigInteger($key['privateKey'], 256); $components['QA'] = isset($ecPrivate['publicKey']) ? self::extractPoint($ecPrivate['publicKey'], $components['curve']) : $components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA']); return $components; } /** * Convert EC parameters to the appropriate format * * @return string */ public static function saveParameters(BaseCurve $curve, array $options = []) { self::initialize_static_variables(); if ($curve instanceof TwistedEdwardsCurve || $curve instanceof MontgomeryCurve) { throw new UnsupportedCurveException('TwistedEdwards and Montgomery Curves are not supported'); } $key = self::encodeParameters($curve, false, $options); return "-----BEGIN EC PARAMETERS-----\r\n" . chunk_split(Strings::base64_encode($key), 64) . "-----END EC PARAMETERS-----\r\n"; } /** * Convert a private key to the appropriate format. * * @param BigInteger $privateKey * @param BaseCurve $curve * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey * @param string $secret optional * @param string $password optional * @param array $options optional * @return string */ public static function savePrivateKey(BigInteger $privateKey, BaseCurve $curve, array $publicKey, $secret = null, $password = '', array $options = []) { self::initialize_static_variables(); if ($curve instanceof TwistedEdwardsCurve || $curve instanceof MontgomeryCurve) { throw new UnsupportedCurveException('TwistedEdwards Curves are not supported'); } $publicKey = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); $key = [ 'version' => 'ecPrivkeyVer1', 'privateKey' => $privateKey->toBytes(), 'parameters' => new ASN1\Element(self::encodeParameters($curve)), 'publicKey' => "\0" . $publicKey ]; $key = ASN1::encodeDER($key, Maps\ECPrivateKey::MAP); return self::wrapPrivateKey($key, 'EC', $password, $options); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\EC\Formats\Keys; use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; use phpseclib3\Crypt\EC\Curves\Ed25519; use phpseclib3\Crypt\EC\Curves\Ed448; use phpseclib3\Exception\UnsupportedCurveException; use phpseclib3\File\ASN1; use phpseclib3\File\ASN1\Maps; use phpseclib3\Math\BigInteger; /** * PKCS#8 Formatted EC Key Handler * * @author Jim Wigginton */ abstract class PKCS8 extends Progenitor { use Common; /** * OID Name * * @var array */ const OID_NAME = ['id-ecPublicKey', 'id-Ed25519', 'id-Ed448']; /** * OID Value * * @var string */ const OID_VALUE = ['1.2.840.10045.2.1', '1.3.101.112', '1.3.101.113']; /** * Break a public or private key down into its constituent components * * @param string $key * @param string $password optional * @return array */ public static function load($key, $password = '') { // initialize_static_variables() is defined in both the trait and the parent class // when it's defined in two places it's the traits one that's called // the parent one is needed, as well, but the parent one is called by other methods // in the parent class as needed and in the context of the parent it's the parent // one that's called self::initialize_static_variables(); $key = parent::load($key, $password); $type = isset($key['privateKey']) ? 'privateKey' : 'publicKey'; switch ($key[$type . 'Algorithm']['algorithm']) { case 'id-Ed25519': case 'id-Ed448': return self::loadEdDSA($key); } $decoded = ASN1::decodeBER($key[$type . 'Algorithm']['parameters']->element); if (!$decoded) { throw new \RuntimeException('Unable to decode BER'); } $params = ASN1::asn1map($decoded[0], Maps\ECParameters::MAP); if (!$params) { throw new \RuntimeException('Unable to decode the parameters using Maps\ECParameters'); } $components = []; $components['curve'] = self::loadCurveByParam($params); if ($type == 'publicKey') { $components['QA'] = self::extractPoint("\0" . $key['publicKey'], $components['curve']); return $components; } $decoded = ASN1::decodeBER($key['privateKey']); if (!$decoded) { throw new \RuntimeException('Unable to decode BER'); } $key = ASN1::asn1map($decoded[0], Maps\ECPrivateKey::MAP); if (isset($key['parameters']) && $params != $key['parameters']) { throw new \RuntimeException('The PKCS8 parameter field does not match the private key parameter field'); } $components['dA'] = new BigInteger($key['privateKey'], 256); $components['curve']->rangeCheck($components['dA']); $components['QA'] = isset($key['publicKey']) ? self::extractPoint($key['publicKey'], $components['curve']) : $components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA']); return $components; } /** * Break a public or private EdDSA key down into its constituent components * * @return array */ private static function loadEdDSA(array $key) { $components = []; if (isset($key['privateKey'])) { $components['curve'] = $key['privateKeyAlgorithm']['algorithm'] == 'id-Ed25519' ? new Ed25519() : new Ed448(); $expected = chr(ASN1::TYPE_OCTET_STRING) . ASN1::encodeLength($components['curve']::SIZE); if (substr($key['privateKey'], 0, 2) != $expected) { throw new \RuntimeException( 'The first two bytes of the ' . $key['privateKeyAlgorithm']['algorithm'] . ' private key field should be 0x' . bin2hex($expected) ); } $arr = $components['curve']->extractSecret(substr($key['privateKey'], 2)); $components['dA'] = $arr['dA']; $components['secret'] = $arr['secret']; } if (isset($key['publicKey'])) { if (!isset($components['curve'])) { $components['curve'] = $key['publicKeyAlgorithm']['algorithm'] == 'id-Ed25519' ? new Ed25519() : new Ed448(); } $components['QA'] = self::extractPoint($key['publicKey'], $components['curve']); } if (isset($key['privateKey']) && !isset($components['QA'])) { $components['QA'] = $components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA']); } return $components; } /** * Convert an EC public key to the appropriate format * * @param BaseCurve $curve * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey * @param array $options optional * @return string */ public static function savePublicKey(BaseCurve $curve, array $publicKey, array $options = []) { self::initialize_static_variables(); if ($curve instanceof MontgomeryCurve) { throw new UnsupportedCurveException('Montgomery Curves are not supported'); } if ($curve instanceof TwistedEdwardsCurve) { return self::wrapPublicKey( $curve->encodePoint($publicKey), null, $curve instanceof Ed25519 ? 'id-Ed25519' : 'id-Ed448', $options ); } $params = new ASN1\Element(self::encodeParameters($curve, false, $options)); $key = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); return self::wrapPublicKey($key, $params, 'id-ecPublicKey', $options); } /** * Convert a private key to the appropriate format. * * @param BigInteger $privateKey * @param BaseCurve $curve * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey * @param string $secret optional * @param string $password optional * @param array $options optional * @return string */ public static function savePrivateKey(BigInteger $privateKey, BaseCurve $curve, array $publicKey, $secret = null, $password = '', array $options = []) { self::initialize_static_variables(); if ($curve instanceof MontgomeryCurve) { throw new UnsupportedCurveException('Montgomery Curves are not supported'); } if ($curve instanceof TwistedEdwardsCurve) { return self::wrapPrivateKey( chr(ASN1::TYPE_OCTET_STRING) . ASN1::encodeLength($curve::SIZE) . $secret, [], null, $password, $curve instanceof Ed25519 ? 'id-Ed25519' : 'id-Ed448' ); } $publicKey = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); $params = new ASN1\Element(self::encodeParameters($curve, false, $options)); $key = [ 'version' => 'ecPrivkeyVer1', 'privateKey' => $privateKey->toBytes(), //'parameters' => $params, 'publicKey' => "\0" . $publicKey ]; $key = ASN1::encodeDER($key, Maps\ECPrivateKey::MAP); return self::wrapPrivateKey($key, [], $params, $password, 'id-ecPublicKey', '', $options); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PuTTY.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\EC\Formats\Keys; use phpseclib3\Common\Functions\Strings; use phpseclib3\Crypt\Common\Formats\Keys\PuTTY as Progenitor; use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; use phpseclib3\Math\BigInteger; /** * PuTTY Formatted EC Key Handler * * @author Jim Wigginton */ abstract class PuTTY extends Progenitor { use Common; /** * Public Handler * * @var string */ const PUBLIC_HANDLER = 'phpseclib3\Crypt\EC\Formats\Keys\OpenSSH'; /** * Supported Key Types * * @var array */ protected static $types = [ 'ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp384', 'ecdsa-sha2-nistp521', 'ssh-ed25519' ]; /** * Break a public or private key down into its constituent components * * @param string $key * @param string $password optional * @return array */ public static function load($key, $password = '') { $components = parent::load($key, $password); if (!isset($components['private'])) { return $components; } $private = $components['private']; $temp = Strings::base64_encode(Strings::packSSH2('s', $components['type']) . $components['public']); $components = OpenSSH::load($components['type'] . ' ' . $temp . ' ' . $components['comment']); if ($components['curve'] instanceof TwistedEdwardsCurve) { if (Strings::shift($private, 4) != "\0\0\0\x20") { throw new \RuntimeException('Length of ssh-ed25519 key should be 32'); } $arr = $components['curve']->extractSecret($private); $components['dA'] = $arr['dA']; $components['secret'] = $arr['secret']; } else { list($components['dA']) = Strings::unpackSSH2('i', $private); $components['curve']->rangeCheck($components['dA']); } return $components; } /** * Convert a private key to the appropriate format. * * @param BigInteger $privateKey * @param BaseCurve $curve * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey * @param string $secret optional * @param string $password optional * @param array $options optional * @return string */ public static function savePrivateKey(BigInteger $privateKey, BaseCurve $curve, array $publicKey, $secret = null, $password = false, array $options = []) { self::initialize_static_variables(); $public = explode(' ', OpenSSH::savePublicKey($curve, $publicKey)); $name = $public[0]; $public = Strings::base64_decode($public[1]); list(, $length) = unpack('N', Strings::shift($public, 4)); Strings::shift($public, $length); // PuTTY pads private keys with a null byte per the following: // https://github.com/github/putty/blob/a3d14d77f566a41fc61dfdc5c2e0e384c9e6ae8b/sshecc.c#L1926 if (!$curve instanceof TwistedEdwardsCurve) { $private = $privateKey->toBytes(); if (!(strlen($privateKey->toBits()) & 7)) { $private = "\0$private"; } } $private = $curve instanceof TwistedEdwardsCurve ? Strings::packSSH2('s', $secret) : Strings::packSSH2('s', $private); return self::wrapPrivateKey($public, $private, $name, $password, $options); } /** * Convert an EC public key to the appropriate format * * @param BaseCurve $curve * @param \phpseclib3\Math\Common\FiniteField[] $publicKey * @return string */ public static function savePublicKey(BaseCurve $curve, array $publicKey) { $public = explode(' ', OpenSSH::savePublicKey($curve, $publicKey)); $type = $public[0]; $public = Strings::base64_decode($public[1]); list(, $length) = unpack('N', Strings::shift($public, 4)); Strings::shift($public, $length); return self::wrapPublicKey($public, $type); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/XML.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\EC\Formats\Keys; use phpseclib3\Common\Functions\Strings; use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; use phpseclib3\Crypt\EC\BaseCurves\Prime as PrimeCurve; use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; use phpseclib3\Exception\BadConfigurationException; use phpseclib3\Exception\UnsupportedCurveException; use phpseclib3\Math\BigInteger; /** * XML Formatted EC Key Handler * * @author Jim Wigginton */ abstract class XML { use Common; /** * Default namespace * * @var string */ private static $namespace; /** * Flag for using RFC4050 syntax * * @var bool */ private static $rfc4050 = false; /** * Break a public or private key down into its constituent components * * @param string $key * @param string $password optional * @return array */ public static function load($key, $password = '') { self::initialize_static_variables(); if (!Strings::is_stringable($key)) { throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); } if (!class_exists('DOMDocument')) { throw new BadConfigurationException('The dom extension is not setup correctly on this system'); } $use_errors = libxml_use_internal_errors(true); if (substr($key, 0, 5) != '' . $key . ''; } $temp = self::isolateNamespace($key, 'http://www.w3.org/2009/xmldsig11#'); if ($temp) { $key = $temp; } $temp = self::isolateNamespace($key, 'http://www.w3.org/2001/04/xmldsig-more#'); if ($temp) { $key = $temp; } $dom = new \DOMDocument(); if (!$dom->loadXML($key)) { libxml_use_internal_errors($use_errors); throw new \UnexpectedValueException('Key does not appear to contain XML'); } $xpath = new \DOMXPath($dom); libxml_use_internal_errors($use_errors); $curve = self::loadCurveByParam($xpath); $pubkey = self::query($xpath, 'publickey', 'Public Key is not present'); $QA = self::query($xpath, 'ecdsakeyvalue')->length ? self::extractPointRFC4050($xpath, $curve) : self::extractPoint("\0" . $pubkey, $curve); libxml_use_internal_errors($use_errors); return compact('curve', 'QA'); } /** * Case-insensitive xpath query * * @param \DOMXPath $xpath * @param string $name * @param string $error optional * @param bool $decode optional * @return \DOMNodeList */ private static function query(\DOMXPath $xpath, $name, $error = null, $decode = true) { $query = '/'; $names = explode('/', $name); foreach ($names as $name) { $query .= "/*[translate(local-name(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='$name']"; } $result = $xpath->query($query); if (!isset($error)) { return $result; } if (!$result->length) { throw new \RuntimeException($error); } return $decode ? self::decodeValue($result->item(0)->textContent) : $result->item(0)->textContent; } /** * Finds the first element in the relevant namespace, strips the namespacing and returns the XML for that element. * * @param string $xml * @param string $ns */ private static function isolateNamespace($xml, $ns) { $dom = new \DOMDocument(); if (!$dom->loadXML($xml)) { return false; } $xpath = new \DOMXPath($dom); $nodes = $xpath->query("//*[namespace::*[.='$ns'] and not(../namespace::*[.='$ns'])]"); if (!$nodes->length) { return false; } $node = $nodes->item(0); $ns_name = $node->lookupPrefix($ns); if ($ns_name) { $node->removeAttributeNS($ns, $ns_name); } return $dom->saveXML($node); } /** * Decodes the value * * @param string $value */ private static function decodeValue($value) { return Strings::base64_decode(str_replace(["\r", "\n", ' ', "\t"], '', $value)); } /** * Extract points from an XML document * * @param \DOMXPath $xpath * @param BaseCurve $curve * @return object[] */ private static function extractPointRFC4050(\DOMXPath $xpath, BaseCurve $curve) { $x = self::query($xpath, 'publickey/x'); $y = self::query($xpath, 'publickey/y'); if (!$x->length || !$x->item(0)->hasAttribute('Value')) { throw new \RuntimeException('Public Key / X coordinate not found'); } if (!$y->length || !$y->item(0)->hasAttribute('Value')) { throw new \RuntimeException('Public Key / Y coordinate not found'); } $point = [ $curve->convertInteger(new BigInteger($x->item(0)->getAttribute('Value'))), $curve->convertInteger(new BigInteger($y->item(0)->getAttribute('Value'))) ]; if (!$curve->verifyPoint($point)) { throw new \RuntimeException('Unable to verify that point exists on curve'); } return $point; } /** * Returns an instance of \phpseclib3\Crypt\EC\BaseCurves\Base based * on the curve parameters * * @param \DomXPath $xpath * @return BaseCurve|false */ private static function loadCurveByParam(\DOMXPath $xpath) { $namedCurve = self::query($xpath, 'namedcurve'); if ($namedCurve->length == 1) { $oid = $namedCurve->item(0)->getAttribute('URN'); $oid = preg_replace('#[^\d.]#', '', $oid); $name = array_search($oid, self::$curveOIDs); if ($name === false) { throw new UnsupportedCurveException('Curve with OID of ' . $oid . ' is not supported'); } $curve = '\phpseclib3\Crypt\EC\Curves\\' . $name; if (!class_exists($curve)) { throw new UnsupportedCurveException('Named Curve of ' . $name . ' is not supported'); } return new $curve(); } $params = self::query($xpath, 'explicitparams'); if ($params->length) { return self::loadCurveByParamRFC4050($xpath); } $params = self::query($xpath, 'ecparameters'); if (!$params->length) { throw new \RuntimeException('No parameters are present'); } $fieldTypes = [ 'prime-field' => ['fieldid/prime/p'], 'gnb' => ['fieldid/gnb/m'], 'tnb' => ['fieldid/tnb/k'], 'pnb' => ['fieldid/pnb/k1', 'fieldid/pnb/k2', 'fieldid/pnb/k3'], 'unknown' => [] ]; foreach ($fieldTypes as $type => $queries) { foreach ($queries as $query) { $result = self::query($xpath, $query); if (!$result->length) { continue 2; } $param = preg_replace('#.*/#', '', $query); $$param = self::decodeValue($result->item(0)->textContent); } break; } $a = self::query($xpath, 'curve/a', 'A coefficient is not present'); $b = self::query($xpath, 'curve/b', 'B coefficient is not present'); $base = self::query($xpath, 'base', 'Base point is not present'); $order = self::query($xpath, 'order', 'Order is not present'); switch ($type) { case 'prime-field': $curve = new PrimeCurve(); $curve->setModulo(new BigInteger($p, 256)); $curve->setCoefficients( new BigInteger($a, 256), new BigInteger($b, 256) ); $point = self::extractPoint("\0" . $base, $curve); $curve->setBasePoint(...$point); $curve->setOrder(new BigInteger($order, 256)); return $curve; case 'gnb': case 'tnb': case 'pnb': default: throw new UnsupportedCurveException('Field Type of ' . $type . ' is not supported'); } } /** * Returns an instance of \phpseclib3\Crypt\EC\BaseCurves\Base based * on the curve parameters * * @param \DomXPath $xpath * @return BaseCurve|false */ private static function loadCurveByParamRFC4050(\DOMXPath $xpath) { $fieldTypes = [ 'prime-field' => ['primefieldparamstype/p'], 'unknown' => [] ]; foreach ($fieldTypes as $type => $queries) { foreach ($queries as $query) { $result = self::query($xpath, $query); if (!$result->length) { continue 2; } $param = preg_replace('#.*/#', '', $query); $$param = $result->item(0)->textContent; } break; } $a = self::query($xpath, 'curveparamstype/a', 'A coefficient is not present', false); $b = self::query($xpath, 'curveparamstype/b', 'B coefficient is not present', false); $x = self::query($xpath, 'basepointparams/basepoint/ecpointtype/x', 'Base Point X is not present', false); $y = self::query($xpath, 'basepointparams/basepoint/ecpointtype/y', 'Base Point Y is not present', false); $order = self::query($xpath, 'order', 'Order is not present', false); switch ($type) { case 'prime-field': $curve = new PrimeCurve(); $p = str_replace(["\r", "\n", ' ', "\t"], '', $p); $curve->setModulo(new BigInteger($p)); $a = str_replace(["\r", "\n", ' ', "\t"], '', $a); $b = str_replace(["\r", "\n", ' ', "\t"], '', $b); $curve->setCoefficients( new BigInteger($a), new BigInteger($b) ); $x = str_replace(["\r", "\n", ' ', "\t"], '', $x); $y = str_replace(["\r", "\n", ' ', "\t"], '', $y); $curve->setBasePoint( new BigInteger($x), new BigInteger($y) ); $order = str_replace(["\r", "\n", ' ', "\t"], '', $order); $curve->setOrder(new BigInteger($order)); return $curve; default: throw new UnsupportedCurveException('Field Type of ' . $type . ' is not supported'); } } /** * Sets the namespace. dsig11 is the most common one. * * Set to null to unset. Used only for creating public keys. * * @param string $namespace */ public static function setNamespace($namespace) { self::$namespace = $namespace; } /** * Uses the XML syntax specified in https://tools.ietf.org/html/rfc4050 */ public static function enableRFC4050Syntax() { self::$rfc4050 = true; } /** * Uses the XML syntax specified in https://www.w3.org/TR/xmldsig-core/#sec-ECParameters */ public static function disableRFC4050Syntax() { self::$rfc4050 = false; } /** * Convert a public key to the appropriate format * * @param BaseCurve $curve * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey * @param array $options optional * @return string */ public static function savePublicKey(BaseCurve $curve, array $publicKey, array $options = []) { self::initialize_static_variables(); if ($curve instanceof TwistedEdwardsCurve || $curve instanceof MontgomeryCurve) { throw new UnsupportedCurveException('TwistedEdwards and Montgomery Curves are not supported'); } if (empty(static::$namespace)) { $pre = $post = ''; } else { $pre = static::$namespace . ':'; $post = ':' . static::$namespace; } if (self::$rfc4050) { return '<' . $pre . 'ECDSAKeyValue xmlns' . $post . '="http://www.w3.org/2001/04/xmldsig-more#">' . "\r\n" . self::encodeXMLParameters($curve, $pre, $options) . "\r\n" . '<' . $pre . 'PublicKey>' . "\r\n" . '<' . $pre . 'X Value="' . $publicKey[0] . '" />' . "\r\n" . '<' . $pre . 'Y Value="' . $publicKey[1] . '" />' . "\r\n" . '' . "\r\n" . ''; } $publicKey = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); return '<' . $pre . 'ECDSAKeyValue xmlns' . $post . '="http://www.w3.org/2009/xmldsig11#">' . "\r\n" . self::encodeXMLParameters($curve, $pre, $options) . "\r\n" . '<' . $pre . 'PublicKey>' . Strings::base64_encode($publicKey) . '' . "\r\n" . ''; } /** * Encode Parameters * * @param BaseCurve $curve * @param string $pre * @param array $options optional * @return string|false */ private static function encodeXMLParameters(BaseCurve $curve, $pre, array $options = []) { $result = self::encodeParameters($curve, true, $options); if (isset($result['namedCurve'])) { $namedCurve = '<' . $pre . 'NamedCurve URI="urn:oid:' . self::$curveOIDs[$result['namedCurve']] . '" />'; return self::$rfc4050 ? '' . str_replace('URI', 'URN', $namedCurve) . '' : $namedCurve; } if (self::$rfc4050) { $xml = '<' . $pre . 'ExplicitParams>' . "\r\n" . '<' . $pre . 'FieldParams>' . "\r\n"; $temp = $result['specifiedCurve']; switch ($temp['fieldID']['fieldType']) { case 'prime-field': $xml .= '<' . $pre . 'PrimeFieldParamsType>' . "\r\n" . '<' . $pre . 'P>' . $temp['fieldID']['parameters'] . '' . "\r\n" . '' . "\r\n"; $a = $curve->getA(); $b = $curve->getB(); list($x, $y) = $curve->getBasePoint(); break; default: throw new UnsupportedCurveException('Field Type of ' . $temp['fieldID']['fieldType'] . ' is not supported'); } $xml .= '' . "\r\n" . '<' . $pre . 'CurveParamsType>' . "\r\n" . '<' . $pre . 'A>' . $a . '' . "\r\n" . '<' . $pre . 'B>' . $b . '' . "\r\n" . '' . "\r\n" . '<' . $pre . 'BasePointParams>' . "\r\n" . '<' . $pre . 'BasePoint>' . "\r\n" . '<' . $pre . 'ECPointType>' . "\r\n" . '<' . $pre . 'X>' . $x . '' . "\r\n" . '<' . $pre . 'Y>' . $y . '' . "\r\n" . '' . "\r\n" . '' . "\r\n" . '<' . $pre . 'Order>' . $curve->getOrder() . '' . "\r\n" . '' . "\r\n" . '' . "\r\n"; return $xml; } if (isset($result['specifiedCurve'])) { $xml = '<' . $pre . 'ECParameters>' . "\r\n" . '<' . $pre . 'FieldID>' . "\r\n"; $temp = $result['specifiedCurve']; switch ($temp['fieldID']['fieldType']) { case 'prime-field': $xml .= '<' . $pre . 'Prime>' . "\r\n" . '<' . $pre . 'P>' . Strings::base64_encode($temp['fieldID']['parameters']->toBytes()) . '' . "\r\n" . '' . "\r\n" ; break; default: throw new UnsupportedCurveException('Field Type of ' . $temp['fieldID']['fieldType'] . ' is not supported'); } $xml .= '' . "\r\n" . '<' . $pre . 'Curve>' . "\r\n" . '<' . $pre . 'A>' . Strings::base64_encode($temp['curve']['a']) . '' . "\r\n" . '<' . $pre . 'B>' . Strings::base64_encode($temp['curve']['b']) . '' . "\r\n" . '' . "\r\n" . '<' . $pre . 'Base>' . Strings::base64_encode($temp['base']) . '' . "\r\n" . '<' . $pre . 'Order>' . Strings::base64_encode($temp['order']) . '' . "\r\n" . ''; return $xml; } } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/libsodium.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\EC\Formats\Keys; use phpseclib3\Crypt\EC\Curves\Ed25519; use phpseclib3\Exception\UnsupportedFormatException; use phpseclib3\Math\BigInteger; /** * libsodium Key Handler * * @author Jim Wigginton */ abstract class libsodium { use Common; /** * Is invisible flag * */ const IS_INVISIBLE = true; /** * Break a public or private key down into its constituent components * * @param string $key * @param string $password optional * @return array */ public static function load($key, $password = '') { switch (strlen($key)) { case 32: $public = $key; break; case 64: $private = substr($key, 0, 32); $public = substr($key, -32); break; case 96: $public = substr($key, -32); if (substr($key, 32, 32) != $public) { throw new \RuntimeException('Keys with 96 bytes should have the 2nd and 3rd set of 32 bytes match'); } $private = substr($key, 0, 32); break; default: throw new \RuntimeException('libsodium keys need to either be 32 bytes long, 64 bytes long or 96 bytes long'); } $curve = new Ed25519(); $components = ['curve' => $curve]; if (isset($private)) { $arr = $curve->extractSecret($private); $components['dA'] = $arr['dA']; $components['secret'] = $arr['secret']; } $components['QA'] = isset($public) ? self::extractPoint($public, $curve) : $curve->multiplyPoint($curve->getBasePoint(), $components['dA']); return $components; } /** * Convert an EC public key to the appropriate format * * @param Ed25519 $curve * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey * @return string */ public static function savePublicKey(Ed25519 $curve, array $publicKey) { return $curve->encodePoint($publicKey); } /** * Convert a private key to the appropriate format. * * @param BigInteger $privateKey * @param Ed25519 $curve * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey * @param string $secret optional * @param string $password optional * @return string */ public static function savePrivateKey(BigInteger $privateKey, Ed25519 $curve, array $publicKey, $secret = null, $password = '') { if (!isset($secret)) { throw new \RuntimeException('Private Key does not have a secret set'); } if (strlen($secret) != 32) { throw new \RuntimeException('Private Key secret is not of the correct length'); } if (!empty($password) && is_string($password)) { throw new UnsupportedFormatException('libsodium private keys do not support encryption'); } return $secret . $curve->encodePoint($publicKey); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/ASN1.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\EC\Formats\Signature; use phpseclib3\File\ASN1 as Encoder; use phpseclib3\File\ASN1\Maps\EcdsaSigValue; use phpseclib3\Math\BigInteger; /** * ASN1 Signature Handler * * @author Jim Wigginton */ abstract class ASN1 { /** * Loads a signature * * @param string $sig * @return array */ public static function load($sig) { if (!is_string($sig)) { return false; } $decoded = Encoder::decodeBER($sig); if (empty($decoded)) { return false; } $components = Encoder::asn1map($decoded[0], EcdsaSigValue::MAP); return $components; } /** * Returns a signature in the appropriate format * * @param BigInteger $r * @param BigInteger $s * @return string */ public static function save(BigInteger $r, BigInteger $s) { return Encoder::encodeDER(compact('r', 's'), EcdsaSigValue::MAP); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/IEEE.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\EC\Formats\Signature; use phpseclib3\Math\BigInteger; /** * ASN1 Signature Handler * * @author Jim Wigginton */ abstract class IEEE { /** * Loads a signature * * @param string $sig * @return array */ public static function load($sig) { if (!is_string($sig)) { return false; } $len = strlen($sig); if ($len & 1) { return false; } $r = new BigInteger(substr($sig, 0, $len >> 1), 256); $s = new BigInteger(substr($sig, $len >> 1), 256); return compact('r', 's'); } /** * Returns a signature in the appropriate format * * @param BigInteger $r * @param BigInteger $s * @param string $curve * @param int $length * @return string */ public static function save(BigInteger $r, BigInteger $s, $curve, $length) { $r = $r->toBytes(); $s = $s->toBytes(); $length = (int) ceil($length / 8); return str_pad($r, $length, "\0", STR_PAD_LEFT) . str_pad($s, $length, "\0", STR_PAD_LEFT); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/Raw.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\EC\Formats\Signature; use phpseclib3\Crypt\Common\Formats\Signature\Raw as Progenitor; /** * Raw DSA Signature Handler * * @author Jim Wigginton */ abstract class Raw extends Progenitor { } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/SSH2.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\EC\Formats\Signature; use phpseclib3\Common\Functions\Strings; use phpseclib3\Math\BigInteger; /** * SSH2 Signature Handler * * @author Jim Wigginton */ abstract class SSH2 { /** * Loads a signature * * @param string $sig * @return mixed */ public static function load($sig) { if (!is_string($sig)) { return false; } $result = Strings::unpackSSH2('ss', $sig); if ($result === false) { return false; } list($type, $blob) = $result; switch ($type) { // see https://tools.ietf.org/html/rfc5656#section-3.1.2 case 'ecdsa-sha2-nistp256': case 'ecdsa-sha2-nistp384': case 'ecdsa-sha2-nistp521': break; default: return false; } $result = Strings::unpackSSH2('ii', $blob); if ($result === false) { return false; } return [ 'r' => $result[0], 's' => $result[1] ]; } /** * Returns a signature in the appropriate format * * @param BigInteger $r * @param BigInteger $s * @param string $curve * @return string */ public static function save(BigInteger $r, BigInteger $s, $curve) { switch ($curve) { case 'secp256r1': $curve = 'nistp256'; break; case 'secp384r1': $curve = 'nistp384'; break; case 'secp521r1': $curve = 'nistp521'; break; default: return false; } $blob = Strings::packSSH2('ii', $r, $s); return Strings::packSSH2('ss', 'ecdsa-sha2-' . $curve, $blob); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Parameters.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\EC; use phpseclib3\Crypt\EC; /** * EC Parameters * * @author Jim Wigginton */ final class Parameters extends EC { /** * Returns the parameters * * @param string $type * @param array $options optional * @return string */ public function toString($type = 'PKCS1', array $options = []) { $type = self::validatePlugin('Keys', 'PKCS1', 'saveParameters'); return $type::saveParameters($this->curve, $options); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PrivateKey.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\EC; use phpseclib3\Common\Functions\Strings; use phpseclib3\Crypt\Common; use phpseclib3\Crypt\EC; use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; use phpseclib3\Crypt\EC\Curves\Curve25519; use phpseclib3\Crypt\EC\Curves\Ed25519; use phpseclib3\Crypt\EC\Formats\Keys\PKCS1; use phpseclib3\Crypt\EC\Formats\Signature\ASN1 as ASN1Signature; use phpseclib3\Crypt\Hash; use phpseclib3\Exception\UnsupportedOperationException; use phpseclib3\Math\BigInteger; /** * EC Private Key * * @author Jim Wigginton */ final class PrivateKey extends EC implements Common\PrivateKey { use Common\Traits\PasswordProtected; /** * Private Key dA * * sign() converts this to a BigInteger so one might wonder why this is a FiniteFieldInteger instead of * a BigInteger. That's because a FiniteFieldInteger, when converted to a byte string, is null padded by * a certain amount whereas a BigInteger isn't. * * @var object */ protected $dA; /** * @var string */ protected $secret; /** * Multiplies an encoded point by the private key * * Used by ECDH * * @param string $coordinates * @return string */ public function multiply($coordinates) { if ($this->curve instanceof MontgomeryCurve) { if ($this->curve instanceof Curve25519 && self::$engines['libsodium']) { return sodium_crypto_scalarmult($this->dA->toBytes(), $coordinates); } $point = [$this->curve->convertInteger(new BigInteger(strrev($coordinates), 256))]; $point = $this->curve->multiplyPoint($point, $this->dA); return strrev($point[0]->toBytes(true)); } if (!$this->curve instanceof TwistedEdwardsCurve) { $coordinates = "\0$coordinates"; } $point = PKCS1::extractPoint($coordinates, $this->curve); $point = $this->curve->multiplyPoint($point, $this->dA); if ($this->curve instanceof TwistedEdwardsCurve) { return $this->curve->encodePoint($point); } if (empty($point)) { throw new \RuntimeException('The infinity point is invalid'); } return "\4" . $point[0]->toBytes(true) . $point[1]->toBytes(true); } /** * Create a signature * * @see self::verify() * @param string $message * @return mixed */ public function sign($message) { if ($this->curve instanceof MontgomeryCurve) { throw new UnsupportedOperationException('Montgomery Curves cannot be used to create signatures'); } $dA = $this->dA; $order = $this->curve->getOrder(); $shortFormat = $this->shortFormat; $format = $this->sigFormat; if ($format === false) { return false; } if ($this->curve instanceof TwistedEdwardsCurve) { if ($this->curve instanceof Ed25519 && self::$engines['libsodium'] && !isset($this->context)) { $result = sodium_crypto_sign_detached($message, $this->withPassword()->toString('libsodium')); return $shortFormat == 'SSH2' ? Strings::packSSH2('ss', 'ssh-' . strtolower($this->getCurve()), $result) : $result; } // contexts (Ed25519ctx) are supported but prehashing (Ed25519ph) is not. // quoting https://tools.ietf.org/html/rfc8032#section-8.5 , // "The Ed25519ph and Ed448ph variants ... SHOULD NOT be used" $A = $this->curve->encodePoint($this->QA); $curve = $this->curve; $hash = new Hash($curve::HASH); $secret = substr($hash->hash($this->secret), $curve::SIZE); if ($curve instanceof Ed25519) { $dom = !isset($this->context) ? '' : 'SigEd25519 no Ed25519 collisions' . "\0" . chr(strlen($this->context)) . $this->context; } else { $context = isset($this->context) ? $this->context : ''; $dom = 'SigEd448' . "\0" . chr(strlen($context)) . $context; } // SHA-512(dom2(F, C) || prefix || PH(M)) $r = $hash->hash($dom . $secret . $message); $r = strrev($r); $r = new BigInteger($r, 256); list(, $r) = $r->divide($order); $R = $curve->multiplyPoint($curve->getBasePoint(), $r); $R = $curve->encodePoint($R); $k = $hash->hash($dom . $R . $A . $message); $k = strrev($k); $k = new BigInteger($k, 256); list(, $k) = $k->divide($order); $S = $k->multiply($dA)->add($r); list(, $S) = $S->divide($order); $S = str_pad(strrev($S->toBytes()), $curve::SIZE, "\0"); return $shortFormat == 'SSH2' ? Strings::packSSH2('ss', 'ssh-' . strtolower($this->getCurve()), $R . $S) : $R . $S; } if (self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods())) { $signature = ''; // altho PHP's OpenSSL bindings only supported EC key creation in PHP 7.1 they've long // supported signing / verification // we use specified curves to avoid issues with OpenSSL possibly not supporting a given named curve; // doing this may mean some curve-specific optimizations can't be used but idk if OpenSSL even // has curve-specific optimizations $result = openssl_sign($message, $signature, $this->withPassword()->toString('PKCS8', ['namedCurve' => false]), $this->hash->getHash()); if ($result) { if ($shortFormat == 'ASN1') { return $signature; } $loaded = ASN1Signature::load($signature); $r = $loaded['r']; $s = $loaded['s']; return $this->formatSignature($r, $s); } } $e = $this->hash->hash($message); $e = new BigInteger($e, 256); $Ln = $this->hash->getLength() - $order->getLength(); $z = $Ln > 0 ? $e->bitwise_rightShift($Ln) : $e; while (true) { $k = BigInteger::randomRange(self::$one, $order->subtract(self::$one)); list($x, $y) = $this->curve->multiplyPoint($this->curve->getBasePoint(), $k); $x = $x->toBigInteger(); list(, $r) = $x->divide($order); if ($r->equals(self::$zero)) { continue; } $kinv = $k->modInverse($order); $temp = $z->add($dA->multiply($r)); $temp = $kinv->multiply($temp); list(, $s) = $temp->divide($order); if (!$s->equals(self::$zero)) { break; } } // the following is an RFC6979 compliant implementation of deterministic ECDSA // it's unused because it's mainly intended for use when a good CSPRNG isn't // available. if phpseclib's CSPRNG isn't good then even key generation is // suspect /* // if this were actually being used it'd probably be better if this lived in load() and createKey() $this->q = $this->curve->getOrder(); $dA = $this->dA->toBigInteger(); $this->x = $dA; $h1 = $this->hash->hash($message); $k = $this->computek($h1); list($x, $y) = $this->curve->multiplyPoint($this->curve->getBasePoint(), $k); $x = $x->toBigInteger(); list(, $r) = $x->divide($this->q); $kinv = $k->modInverse($this->q); $h1 = $this->bits2int($h1); $temp = $h1->add($dA->multiply($r)); $temp = $kinv->multiply($temp); list(, $s) = $temp->divide($this->q); */ return $this->formatSignature($r, $s); } /** * Returns the private key * * @param string $type * @param array $options optional * @return string */ public function toString($type, array $options = []) { $type = self::validatePlugin('Keys', $type, 'savePrivateKey'); return $type::savePrivateKey($this->dA, $this->curve, $this->QA, $this->secret, $this->password, $options); } /** * Returns the public key * * @see self::getPrivateKey() * @return mixed */ public function getPublicKey() { $format = 'PKCS8'; if ($this->curve instanceof MontgomeryCurve) { $format = 'MontgomeryPublic'; } $type = self::validatePlugin('Keys', $format, 'savePublicKey'); $key = $type::savePublicKey($this->curve, $this->QA); $key = EC::loadFormat($format, $key); if ($this->curve instanceof MontgomeryCurve) { return $key; } $key = $key ->withHash($this->hash->getHash()) ->withSignatureFormat($this->shortFormat); if ($this->curve instanceof TwistedEdwardsCurve) { $key = $key->withContext($this->context); } return $key; } /** * Returns a signature in the appropriate format * * @return string */ private function formatSignature(BigInteger $r, BigInteger $s) { $format = $this->sigFormat; $temp = new \ReflectionMethod($format, 'save'); $paramCount = $temp->getNumberOfRequiredParameters(); // @codingStandardsIgnoreStart switch ($paramCount) { case 2: return $format::save($r, $s); case 3: return $format::save($r, $s, $this->getCurve()); case 4: return $format::save($r, $s, $this->getCurve(), $this->getLength()); } // @codingStandardsIgnoreEnd // presumably the only way you could get to this is if you were using a custom plugin throw new UnsupportedOperationException("$format::save() has $paramCount parameters - the only valid parameter counts are 2 or 3"); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PublicKey.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\EC; use phpseclib3\Common\Functions\Strings; use phpseclib3\Crypt\Common; use phpseclib3\Crypt\EC; use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; use phpseclib3\Crypt\EC\Curves\Ed25519; use phpseclib3\Crypt\EC\Formats\Keys\PKCS1; use phpseclib3\Crypt\EC\Formats\Signature\ASN1 as ASN1Signature; use phpseclib3\Crypt\Hash; use phpseclib3\Exception\UnsupportedOperationException; use phpseclib3\Math\BigInteger; /** * EC Public Key * * @author Jim Wigginton */ final class PublicKey extends EC implements Common\PublicKey { use Common\Traits\Fingerprint; /** * Verify a signature * * @see self::verify() * @param string $message * @param string $signature * @return mixed */ public function verify($message, $signature) { if ($this->curve instanceof MontgomeryCurve) { throw new UnsupportedOperationException('Montgomery Curves cannot be used to create signatures'); } $shortFormat = $this->shortFormat; $format = $this->sigFormat; if ($format === false) { return false; } $order = $this->curve->getOrder(); if ($this->curve instanceof TwistedEdwardsCurve) { if ($shortFormat == 'SSH2') { list(, $signature) = Strings::unpackSSH2('ss', $signature); } if ($this->curve instanceof Ed25519 && self::$engines['libsodium'] && !isset($this->context)) { return sodium_crypto_sign_verify_detached($signature, $message, $this->toString('libsodium')); } $curve = $this->curve; if (strlen($signature) != 2 * $curve::SIZE) { return false; } $R = substr($signature, 0, $curve::SIZE); $S = substr($signature, $curve::SIZE); try { $R = PKCS1::extractPoint($R, $curve); $R = $this->curve->convertToInternal($R); } catch (\Exception $e) { return false; } $S = strrev($S); $S = new BigInteger($S, 256); if ($S->compare($order) >= 0) { return false; } $A = $curve->encodePoint($this->QA); if ($curve instanceof Ed25519) { $dom2 = !isset($this->context) ? '' : 'SigEd25519 no Ed25519 collisions' . "\0" . chr(strlen($this->context)) . $this->context; } else { $context = isset($this->context) ? $this->context : ''; $dom2 = 'SigEd448' . "\0" . chr(strlen($context)) . $context; } $hash = new Hash($curve::HASH); $k = $hash->hash($dom2 . substr($signature, 0, $curve::SIZE) . $A . $message); $k = strrev($k); $k = new BigInteger($k, 256); list(, $k) = $k->divide($order); $qa = $curve->convertToInternal($this->QA); $lhs = $curve->multiplyPoint($curve->getBasePoint(), $S); $rhs = $curve->multiplyPoint($qa, $k); $rhs = $curve->addPoint($rhs, $R); $rhs = $curve->convertToAffine($rhs); return $lhs[0]->equals($rhs[0]) && $lhs[1]->equals($rhs[1]); } $params = $format::load($signature); if ($params === false || count($params) != 2) { return false; } $r = $params['r']; $s = $params['s']; if (self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods())) { $sig = $format != 'ASN1' ? ASN1Signature::save($r, $s) : $signature; $result = openssl_verify($message, $sig, $this->toString('PKCS8', ['namedCurve' => false]), $this->hash->getHash()); if ($result != -1) { return (bool) $result; } } $n_1 = $order->subtract(self::$one); if (!$r->between(self::$one, $n_1) || !$s->between(self::$one, $n_1)) { return false; } $e = $this->hash->hash($message); $e = new BigInteger($e, 256); $Ln = $this->hash->getLength() - $order->getLength(); $z = $Ln > 0 ? $e->bitwise_rightShift($Ln) : $e; $w = $s->modInverse($order); list(, $u1) = $z->multiply($w)->divide($order); list(, $u2) = $r->multiply($w)->divide($order); $u1 = $this->curve->convertInteger($u1); $u2 = $this->curve->convertInteger($u2); list($x1, $y1) = $this->curve->multiplyAddPoints( [$this->curve->getBasePoint(), $this->QA], [$u1, $u2] ); $x1 = $x1->toBigInteger(); list(, $x1) = $x1->divide($order); return $x1->equals($r); } /** * Returns the public key * * @param string $type * @param array $options optional * @return string */ public function toString($type, array $options = []) { $type = self::validatePlugin('Keys', $type, 'savePublicKey'); return $type::savePublicKey($this->curve, $this->QA, $options); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC.php ================================================ * getPublicKey(); * * $plaintext = 'terrafrost'; * * $signature = $private->sign($plaintext); * * echo $public->verify($plaintext, $signature) ? 'verified' : 'unverified'; * ?> * * * @author Jim Wigginton * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt; use phpseclib3\Crypt\Common\AsymmetricKey; use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; use phpseclib3\Crypt\EC\Curves\Curve25519; use phpseclib3\Crypt\EC\Curves\Ed25519; use phpseclib3\Crypt\EC\Curves\Ed448; use phpseclib3\Crypt\EC\Formats\Keys\PKCS1; use phpseclib3\Crypt\EC\Parameters; use phpseclib3\Crypt\EC\PrivateKey; use phpseclib3\Crypt\EC\PublicKey; use phpseclib3\Exception\UnsupportedAlgorithmException; use phpseclib3\Exception\UnsupportedCurveException; use phpseclib3\Exception\UnsupportedOperationException; use phpseclib3\File\ASN1; use phpseclib3\File\ASN1\Maps\ECParameters; use phpseclib3\Math\BigInteger; /** * Pure-PHP implementation of EC. * * @author Jim Wigginton */ abstract class EC extends AsymmetricKey { /** * Algorithm Name * * @var string */ const ALGORITHM = 'EC'; /** * Public Key QA * * @var object[] */ protected $QA; /** * Curve * * @var EC\BaseCurves\Base */ protected $curve; /** * Signature Format * * @var string */ protected $format; /** * Signature Format (Short) * * @var string */ protected $shortFormat; /** * Curve Name * * @var string */ private $curveName; /** * Curve Order * * Used for deterministic ECDSA * * @var BigInteger */ protected $q; /** * Alias for the private key * * Used for deterministic ECDSA. AsymmetricKey expects $x. I don't like x because * with x you have x * the base point yielding an (x, y)-coordinate that is the * public key. But the x is different depending on which side of the equal sign * you're on. It's less ambiguous if you do dA * base point = (x, y)-coordinate. * * @var BigInteger */ protected $x; /** * Context * * @var string */ protected $context; /** * Signature Format * * @var string */ protected $sigFormat; /** * Create public / private key pair. * * @param string $curve * @return PrivateKey */ public static function createKey($curve) { self::initialize_static_variables(); $class = new \ReflectionClass(static::class); if ($class->isFinal()) { throw new \RuntimeException('createKey() should not be called from final classes (' . static::class . ')'); } if (!isset(self::$engines['PHP'])) { self::useBestEngine(); } $curve = strtolower($curve); if (self::$engines['libsodium'] && $curve == 'ed25519' && function_exists('sodium_crypto_sign_keypair')) { $kp = sodium_crypto_sign_keypair(); $privatekey = EC::loadFormat('libsodium', sodium_crypto_sign_secretkey($kp)); //$publickey = EC::loadFormat('libsodium', sodium_crypto_sign_publickey($kp)); $privatekey->curveName = 'Ed25519'; //$publickey->curveName = $curve; return $privatekey; } $privatekey = new PrivateKey(); $curveName = $curve; if (preg_match('#(?:^curve|^ed)\d+$#', $curveName)) { $curveName = ucfirst($curveName); } elseif (substr($curveName, 0, 10) == 'brainpoolp') { $curveName = 'brainpoolP' . substr($curveName, 10); } $curve = '\phpseclib3\Crypt\EC\Curves\\' . $curveName; if (!class_exists($curve)) { throw new UnsupportedCurveException('Named Curve of ' . $curveName . ' is not supported'); } $reflect = new \ReflectionClass($curve); $curveName = $reflect->isFinal() ? $reflect->getParentClass()->getShortName() : $reflect->getShortName(); $curve = new $curve(); if ($curve instanceof TwistedEdwardsCurve) { $arr = $curve->extractSecret(Random::string($curve instanceof Ed448 ? 57 : 32)); $privatekey->dA = $dA = $arr['dA']; $privatekey->secret = $arr['secret']; } else { $privatekey->dA = $dA = $curve->createRandomMultiplier(); } if ($curve instanceof Curve25519 && self::$engines['libsodium']) { //$r = pack('H*', '0900000000000000000000000000000000000000000000000000000000000000'); //$QA = sodium_crypto_scalarmult($dA->toBytes(), $r); $QA = sodium_crypto_box_publickey_from_secretkey($dA->toBytes()); $privatekey->QA = [$curve->convertInteger(new BigInteger(strrev($QA), 256))]; } else { $privatekey->QA = $curve->multiplyPoint($curve->getBasePoint(), $dA); } $privatekey->curve = $curve; //$publickey = clone $privatekey; //unset($publickey->dA); //unset($publickey->x); $privatekey->curveName = $curveName; //$publickey->curveName = $curveName; if ($privatekey->curve instanceof TwistedEdwardsCurve) { return $privatekey->withHash($curve::HASH); } return $privatekey; } /** * OnLoad Handler * * @return bool */ protected static function onLoad(array $components) { if (!isset(self::$engines['PHP'])) { self::useBestEngine(); } if (!isset($components['dA']) && !isset($components['QA'])) { $new = new Parameters(); $new->curve = $components['curve']; return $new; } $new = isset($components['dA']) ? new PrivateKey() : new PublicKey(); $new->curve = $components['curve']; $new->QA = $components['QA']; if (isset($components['dA'])) { $new->dA = $components['dA']; $new->secret = $components['secret']; } if ($new->curve instanceof TwistedEdwardsCurve) { return $new->withHash($components['curve']::HASH); } return $new; } /** * Constructor * * PublicKey and PrivateKey objects can only be created from abstract RSA class */ protected function __construct() { $this->sigFormat = self::validatePlugin('Signature', 'ASN1'); $this->shortFormat = 'ASN1'; parent::__construct(); } /** * Returns the curve * * Returns a string if it's a named curve, an array if not * * @return string|array */ public function getCurve() { if ($this->curveName) { return $this->curveName; } if ($this->curve instanceof MontgomeryCurve) { $this->curveName = $this->curve instanceof Curve25519 ? 'Curve25519' : 'Curve448'; return $this->curveName; } if ($this->curve instanceof TwistedEdwardsCurve) { $this->curveName = $this->curve instanceof Ed25519 ? 'Ed25519' : 'Ed448'; return $this->curveName; } $params = $this->getParameters()->toString('PKCS8', ['namedCurve' => true]); $decoded = ASN1::extractBER($params); $decoded = ASN1::decodeBER($decoded); $decoded = ASN1::asn1map($decoded[0], ECParameters::MAP); if (isset($decoded['namedCurve'])) { $this->curveName = $decoded['namedCurve']; return $decoded['namedCurve']; } if (!$namedCurves) { PKCS1::useSpecifiedCurve(); } return $decoded; } /** * Returns the key size * * Quoting https://tools.ietf.org/html/rfc5656#section-2, * * "The size of a set of elliptic curve domain parameters on a prime * curve is defined as the number of bits in the binary representation * of the field order, commonly denoted by p. Size on a * characteristic-2 curve is defined as the number of bits in the binary * representation of the field, commonly denoted by m. A set of * elliptic curve domain parameters defines a group of order n generated * by a base point P" * * @return int */ public function getLength() { return $this->curve->getLength(); } /** * Returns the current engine being used * * @see self::useInternalEngine() * @see self::useBestEngine() * @return string */ public function getEngine() { if (!isset(self::$engines['PHP'])) { self::useBestEngine(); } if ($this->curve instanceof TwistedEdwardsCurve) { return $this->curve instanceof Ed25519 && self::$engines['libsodium'] && !isset($this->context) ? 'libsodium' : 'PHP'; } return self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods()) ? 'OpenSSL' : 'PHP'; } /** * Returns the public key coordinates as a string * * Used by ECDH * * @return string */ public function getEncodedCoordinates() { if ($this->curve instanceof MontgomeryCurve) { return strrev($this->QA[0]->toBytes(true)); } if ($this->curve instanceof TwistedEdwardsCurve) { return $this->curve->encodePoint($this->QA); } return "\4" . $this->QA[0]->toBytes(true) . $this->QA[1]->toBytes(true); } /** * Returns the parameters * * @see self::getPublicKey() * @param string $type optional * @return mixed */ public function getParameters($type = 'PKCS1') { $type = self::validatePlugin('Keys', $type, 'saveParameters'); $key = $type::saveParameters($this->curve); return EC::load($key, 'PKCS1') ->withHash($this->hash->getHash()) ->withSignatureFormat($this->shortFormat); } /** * Determines the signature padding mode * * Valid values are: ASN1, SSH2, Raw * * @param string $format */ public function withSignatureFormat($format) { if ($this->curve instanceof MontgomeryCurve) { throw new UnsupportedOperationException('Montgomery Curves cannot be used to create signatures'); } $new = clone $this; $new->shortFormat = $format; $new->sigFormat = self::validatePlugin('Signature', $format); return $new; } /** * Returns the signature format currently being used * */ public function getSignatureFormat() { return $this->shortFormat; } /** * Sets the context * * Used by Ed25519 / Ed448. * * @see self::sign() * @see self::verify() * @param string $context optional */ public function withContext($context = null) { if (!$this->curve instanceof TwistedEdwardsCurve) { throw new UnsupportedCurveException('Only Ed25519 and Ed448 support contexts'); } $new = clone $this; if (!isset($context)) { $new->context = null; return $new; } if (!is_string($context)) { throw new \InvalidArgumentException('setContext expects a string'); } if (strlen($context) > 255) { throw new \LengthException('The context is supposed to be, at most, 255 bytes long'); } $new->context = $context; return $new; } /** * Returns the signature format currently being used * */ public function getContext() { return $this->context; } /** * Determines which hashing function should be used * * @param string $hash */ public function withHash($hash) { if ($this->curve instanceof MontgomeryCurve) { throw new UnsupportedOperationException('Montgomery Curves cannot be used to create signatures'); } if ($this->curve instanceof Ed25519 && $hash != 'sha512') { throw new UnsupportedAlgorithmException('Ed25519 only supports sha512 as a hash'); } if ($this->curve instanceof Ed448 && $hash != 'shake256-912') { throw new UnsupportedAlgorithmException('Ed448 only supports shake256 with a length of 114 bytes'); } return parent::withHash($hash); } /** * __toString() magic method * * @return string */ public function __toString() { if ($this->curve instanceof MontgomeryCurve) { return ''; } return parent::__toString(); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php ================================================ * setKey('abcdefg'); * * echo base64_encode($hash->hash('abcdefg')); * ?> * * * @author Jim Wigginton * @copyright 2015 Jim Wigginton * @author Andreas Fischer * @copyright 2015 Andreas Fischer * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt; use phpseclib3\Common\Functions\Strings; use phpseclib3\Exception\InsufficientSetupException; use phpseclib3\Exception\UnsupportedAlgorithmException; use phpseclib3\Math\BigInteger; use phpseclib3\Math\PrimeField; /** * @author Jim Wigginton * @author Andreas Fischer */ class Hash { /** * Padding Types * */ const PADDING_KECCAK = 1; /** * Padding Types * */ const PADDING_SHA3 = 2; /** * Padding Types * */ const PADDING_SHAKE = 3; /** * Padding Type * * Only used by SHA3 * * @var int */ private $paddingType = 0; /** * Hash Parameter * * @see self::setHash() * @var int */ private $hashParam; /** * Byte-length of hash output (Internal HMAC) * * @see self::setHash() * @var int */ private $length; /** * Hash Algorithm * * @see self::setHash() * @var string */ private $algo; /** * Key * * @see self::setKey() * @var string */ private $key = false; /** * Nonce * * @see self::setNonce() * @var string */ private $nonce = false; /** * Hash Parameters * * @var array */ private $parameters = []; /** * Computed Key * * @see self::_computeKey() * @var string */ private $computedKey = false; /** * Outer XOR (Internal HMAC) * * Used only for sha512 * * @see self::hash() * @var string */ private $opad; /** * Inner XOR (Internal HMAC) * * Used only for sha512 * * @see self::hash() * @var string */ private $ipad; /** * Recompute AES Key * * Used only for umac * * @see self::hash() * @var boolean */ private $recomputeAESKey; /** * umac cipher object * * @see self::hash() * @var AES */ private $c; /** * umac pad * * @see self::hash() * @var string */ private $pad; /** * Block Size * * @var int */ private $blockSize; /**#@+ * UMAC variables * * @var PrimeField */ private static $factory36; private static $factory64; private static $factory128; private static $offset64; private static $offset128; private static $marker64; private static $marker128; private static $maxwordrange64; private static $maxwordrange128; /**#@-*/ /**#@+ * AES_CMAC variables * * @var string */ private $k1; private $k2; /**#@-*/ /** * Default Constructor. * * @param string $hash */ public function __construct($hash = 'sha256') { $this->setHash($hash); } /** * Sets the key for HMACs * * Keys can be of any length. * * @param string $key */ public function setKey($key = false) { $this->key = $key; $this->computeKey(); $this->recomputeAESKey = true; } /** * Sets the nonce for UMACs * * Keys can be of any length. * * @param string $nonce */ public function setNonce($nonce = false) { switch (true) { case !is_string($nonce): case strlen($nonce) > 0 && strlen($nonce) <= 16: $this->recomputeAESKey = true; $this->nonce = $nonce; return; } throw new \LengthException('The nonce length must be between 1 and 16 bytes, inclusive'); } /** * Pre-compute the key used by the HMAC * * Quoting http://tools.ietf.org/html/rfc2104#section-2, "Applications that use keys longer than B bytes * will first hash the key using H and then use the resultant L byte string as the actual key to HMAC." * * As documented in https://www.reddit.com/r/PHP/comments/9nct2l/symfonypolyfill_hash_pbkdf2_correct_fix_for/ * when doing an HMAC multiple times it's faster to compute the hash once instead of computing it during * every call * */ private function computeKey() { if ($this->key === false) { $this->computedKey = false; return; } if (strlen($this->key) <= $this->getBlockLengthInBytes()) { $this->computedKey = $this->key; return; } $this->computedKey = is_array($this->algo) ? call_user_func($this->algo, $this->key) : hash($this->algo, $this->key, true); } /** * Gets the hash function. * * As set by the constructor or by the setHash() method. * * @return string */ public function getHash() { return $this->hashParam; } /** * Sets the hash function. * * @param string $hash */ public function setHash($hash) { $oldHash = $this->hashParam; $this->hashParam = $hash = strtolower($hash); switch ($hash) { case 'umac-32': case 'umac-64': case 'umac-96': case 'umac-128': if ($oldHash != $this->hashParam) { $this->recomputeAESKey = true; } $this->blockSize = 128; $this->length = abs(substr($hash, -3)) >> 3; $this->algo = 'umac'; return; case 'aes_cmac': if ($oldHash != $this->hashParam) { $this->recomputeAESKey = true; } $this->blockSize = 128; $this->length = 16; $this->algo = 'aes_cmac'; return; case 'md2-96': case 'md5-96': case 'sha1-96': case 'sha224-96': case 'sha256-96': case 'sha384-96': case 'sha512-96': case 'sha512/224-96': case 'sha512/256-96': $hash = substr($hash, 0, -3); $this->length = 12; // 96 / 8 = 12 break; case 'md2': case 'md5': $this->length = 16; break; case 'sha1': $this->length = 20; break; case 'sha224': case 'sha512/224': case 'sha3-224': $this->length = 28; break; case 'keccak256': $this->paddingType = self::PADDING_KECCAK; // fall-through case 'sha256': case 'sha512/256': case 'sha3-256': $this->length = 32; break; case 'sha384': case 'sha3-384': $this->length = 48; break; case 'sha512': case 'sha3-512': $this->length = 64; break; default: if (preg_match('#^(shake(?:128|256))-(\d+)$#', $hash, $matches)) { $this->paddingType = self::PADDING_SHAKE; $hash = $matches[1]; $this->length = $matches[2] >> 3; } else { throw new UnsupportedAlgorithmException( "$hash is not a supported algorithm" ); } } switch ($hash) { case 'md2': case 'md2-96': $this->blockSize = 128; break; case 'md5-96': case 'sha1-96': case 'sha224-96': case 'sha256-96': case 'md5': case 'sha1': case 'sha224': case 'sha256': $this->blockSize = 512; break; case 'sha3-224': $this->blockSize = 1152; // 1600 - 2*224 break; case 'sha3-256': case 'shake256': case 'keccak256': $this->blockSize = 1088; // 1600 - 2*256 break; case 'sha3-384': $this->blockSize = 832; // 1600 - 2*384 break; case 'sha3-512': $this->blockSize = 576; // 1600 - 2*512 break; case 'shake128': $this->blockSize = 1344; // 1600 - 2*128 break; default: $this->blockSize = 1024; } if (in_array(substr($hash, 0, 5), ['sha3-', 'shake', 'kecca'])) { // PHP 7.1.0 introduced support for "SHA3 fixed mode algorithms": // http://php.net/ChangeLog-7.php#7.1.0 if (version_compare(PHP_VERSION, '7.1.0') < 0 || substr($hash, 0, 5) != 'sha3-') { //preg_match('#(\d+)$#', $hash, $matches); //$this->parameters['capacity'] = 2 * $matches[1]; // 1600 - $this->blockSize //$this->parameters['rate'] = 1600 - $this->parameters['capacity']; // == $this->blockSize if (!$this->paddingType) { $this->paddingType = self::PADDING_SHA3; } $this->parameters = [ 'capacity' => 1600 - $this->blockSize, 'rate' => $this->blockSize, 'length' => $this->length, 'padding' => $this->paddingType ]; $hash = ['phpseclib3\Crypt\Hash', PHP_INT_SIZE == 8 ? 'sha3_64' : 'sha3_32']; } } if ($hash == 'sha512/224' || $hash == 'sha512/256') { // PHP 7.1.0 introduced sha512/224 and sha512/256 support: // http://php.net/ChangeLog-7.php#7.1.0 if (version_compare(PHP_VERSION, '7.1.0') < 0) { // from http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf#page=24 $initial = $hash == 'sha512/256' ? [ '22312194FC2BF72C', '9F555FA3C84C64C2', '2393B86B6F53B151', '963877195940EABD', '96283EE2A88EFFE3', 'BE5E1E2553863992', '2B0199FC2C85B8AA', '0EB72DDC81C52CA2' ] : [ '8C3D37C819544DA2', '73E1996689DCD4D6', '1DFAB7AE32FF9C82', '679DD514582F9FCF', '0F6D2B697BD44DA8', '77E36F7304C48942', '3F9D85A86A1D36C8', '1112E6AD91D692A1' ]; for ($i = 0; $i < 8; $i++) { if (PHP_INT_SIZE == 8) { list(, $initial[$i]) = unpack('J', pack('H*', $initial[$i])); } else { $initial[$i] = new BigInteger($initial[$i], 16); $initial[$i]->setPrecision(64); } } $this->parameters = compact('initial'); $hash = ['phpseclib3\Crypt\Hash', PHP_INT_SIZE == 8 ? 'sha512_64' : 'sha512']; } } if (is_array($hash)) { $b = $this->blockSize >> 3; $this->ipad = str_repeat(chr(0x36), $b); $this->opad = str_repeat(chr(0x5C), $b); } $this->algo = $hash; $this->computeKey(); } /** * KDF: Key-Derivation Function * * The key-derivation function generates pseudorandom bits used to key the hash functions. * * @param int $index a non-negative integer less than 2^64 * @param int $numbytes a non-negative integer less than 2^64 * @return string string of length numbytes bytes */ private function kdf($index, $numbytes) { $this->c->setIV(pack('N4', 0, $index, 0, 1)); return $this->c->encrypt(str_repeat("\0", $numbytes)); } /** * PDF Algorithm * * @return string string of length taglen bytes. */ private function pdf() { $k = $this->key; $nonce = $this->nonce; $taglen = $this->length; // // Extract and zero low bit(s) of Nonce if needed // if ($taglen <= 8) { $last = strlen($nonce) - 1; $mask = $taglen == 4 ? "\3" : "\1"; $index = $nonce[$last] & $mask; $nonce[$last] = $nonce[$last] ^ $index; } // // Make Nonce BLOCKLEN bytes by appending zeroes if needed // $nonce = str_pad($nonce, 16, "\0"); // // Generate subkey, encipher and extract indexed substring // $kp = $this->kdf(0, 16); $c = new AES('ctr'); $c->disablePadding(); $c->setKey($kp); $c->setIV($nonce); $t = $c->encrypt("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"); // we could use ord() but per https://paragonie.com/blog/2016/06/constant-time-encoding-boring-cryptography-rfc-4648-and-you // unpack() doesn't leak timing info return $taglen <= 8 ? substr($t, unpack('C', $index)[1] * $taglen, $taglen) : substr($t, 0, $taglen); } /** * UHASH Algorithm * * @param string $m string of length less than 2^67 bits. * @param int $taglen the integer 4, 8, 12 or 16. * @return string string of length taglen bytes. */ private function uhash($m, $taglen) { // // One internal iteration per 4 bytes of output // $iters = $taglen >> 2; // // Define total key needed for all iterations using KDF. // L1Key reuses most key material between iterations. // //$L1Key = $this->kdf(1, 1024 + ($iters - 1) * 16); $L1Key = $this->kdf(1, (1024 + ($iters - 1)) * 16); $L2Key = $this->kdf(2, $iters * 24); $L3Key1 = $this->kdf(3, $iters * 64); $L3Key2 = $this->kdf(4, $iters * 4); // // For each iteration, extract key and do three-layer hash. // If bytelength(M) <= 1024, then skip L2-HASH. // $y = ''; for ($i = 0; $i < $iters; $i++) { $L1Key_i = substr($L1Key, $i * 16, 1024); $L2Key_i = substr($L2Key, $i * 24, 24); $L3Key1_i = substr($L3Key1, $i * 64, 64); $L3Key2_i = substr($L3Key2, $i * 4, 4); $a = self::L1Hash($L1Key_i, $m); $b = strlen($m) <= 1024 ? "\0\0\0\0\0\0\0\0$a" : self::L2Hash($L2Key_i, $a); $c = self::L3Hash($L3Key1_i, $L3Key2_i, $b); $y .= $c; } return $y; } /** * L1-HASH Algorithm * * The first-layer hash breaks the message into 1024-byte chunks and * hashes each with a function called NH. Concatenating the results * forms a string, which is up to 128 times shorter than the original. * * @param string $k string of length 1024 bytes. * @param string $m string of length less than 2^67 bits. * @return string string of length (8 * ceil(bitlength(M)/8192)) bytes. */ private static function L1Hash($k, $m) { // // Break M into 1024 byte chunks (final chunk may be shorter) // $m = str_split($m, 1024); // // For each chunk, except the last: endian-adjust, NH hash // and add bit-length. Use results to build Y. // $length = 1024 * 8; $y = ''; for ($i = 0; $i < count($m) - 1; $i++) { $m[$i] = pack('N*', ...unpack('V*', $m[$i])); // ENDIAN-SWAP $y .= PHP_INT_SIZE == 8 ? static::nh64($k, $m[$i], $length) : static::nh32($k, $m[$i], $length); } // // For the last chunk: pad to 32-byte boundary, endian-adjust, // NH hash and add bit-length. Concatenate the result to Y. // $length = count($m) ? strlen($m[$i]) : 0; $pad = 32 - ($length % 32); $pad = max(32, $length + $pad % 32); $m[$i] = str_pad(isset($m[$i]) ? $m[$i] : '', $pad, "\0"); // zeropad $m[$i] = pack('N*', ...unpack('V*', $m[$i])); // ENDIAN-SWAP $y .= PHP_INT_SIZE == 8 ? static::nh64($k, $m[$i], $length * 8) : static::nh32($k, $m[$i], $length * 8); return $y; } /** * 32-bit safe 64-bit Multiply with 2x 32-bit ints * * @param int $x * @param int $y * @return string $x * $y */ private static function mul32_64($x, $y) { // see mul64() for a more detailed explanation of how this works $x1 = ($x >> 16) & 0xFFFF; $x0 = $x & 0xFFFF; $y1 = ($y >> 16) & 0xFFFF; $y0 = $y & 0xFFFF; // the following 3x lines will possibly yield floats $z2 = $x1 * $y1; $z0 = $x0 * $y0; $z1 = $x1 * $y0 + $x0 * $y1; $a = intval(fmod($z0, 65536)); $b = intval($z0 / 65536) + intval(fmod($z1, 65536)); $c = intval($z1 / 65536) + intval(fmod($z2, 65536)) + intval($b / 65536); $b = intval(fmod($b, 65536)); $d = intval($z2 / 65536) + intval($c / 65536); $c = intval(fmod($c, 65536)); $d = intval(fmod($d, 65536)); return pack('n4', $d, $c, $b, $a); } /** * 32-bit safe 64-bit Addition with 2x 64-bit strings * * @param int $x * @param int $y * @return int $x * $y */ private static function add32_64($x, $y) { list(, $x1, $x2, $x3, $x4) = unpack('n4', $x); list(, $y1, $y2, $y3, $y4) = unpack('n4', $y); $a = $x4 + $y4; $b = $x3 + $y3 + ($a >> 16); $c = $x2 + $y2 + ($b >> 16); $d = $x1 + $y1 + ($c >> 16); return pack('n4', $d, $c, $b, $a); } /** * 32-bit safe 32-bit Addition with 2x 32-bit strings * * @param int $x * @param int $y * @return int $x * $y */ private static function add32($x, $y) { // see add64() for a more detailed explanation of how this works $x1 = $x & 0xFFFF; $x2 = ($x >> 16) & 0xFFFF; $y1 = $y & 0xFFFF; $y2 = ($y >> 16) & 0xFFFF; $a = $x1 + $y1; $b = ($x2 + $y2 + ($a >> 16)) << 16; $a &= 0xFFFF; return $a | $b; } /** * NH Algorithm / 32-bit safe * * @param string $k string of length 1024 bytes. * @param string $m string with length divisible by 32 bytes. * @return string string of length 8 bytes. */ private static function nh32($k, $m, $length) { // // Break M and K into 4-byte chunks // $k = unpack('N*', $k); $m = unpack('N*', $m); $t = count($m); // // Perform NH hash on the chunks, pairing words for multiplication // which are 4 apart to accommodate vector-parallelism. // $i = 1; $y = "\0\0\0\0\0\0\0\0"; while ($i <= $t) { $temp = self::add32($m[$i], $k[$i]); $temp2 = self::add32($m[$i + 4], $k[$i + 4]); $y = self::add32_64($y, self::mul32_64($temp, $temp2)); $temp = self::add32($m[$i + 1], $k[$i + 1]); $temp2 = self::add32($m[$i + 5], $k[$i + 5]); $y = self::add32_64($y, self::mul32_64($temp, $temp2)); $temp = self::add32($m[$i + 2], $k[$i + 2]); $temp2 = self::add32($m[$i + 6], $k[$i + 6]); $y = self::add32_64($y, self::mul32_64($temp, $temp2)); $temp = self::add32($m[$i + 3], $k[$i + 3]); $temp2 = self::add32($m[$i + 7], $k[$i + 7]); $y = self::add32_64($y, self::mul32_64($temp, $temp2)); $i += 8; } return self::add32_64($y, pack('N2', 0, $length)); } /** * 64-bit Multiply with 2x 32-bit ints * * @param int $x * @param int $y * @return int $x * $y */ private static function mul64($x, $y) { // since PHP doesn't implement unsigned integers we'll implement them with signed integers // to do this we'll use karatsuba multiplication $x1 = $x >> 16; $x0 = $x & 0xFFFF; $y1 = $y >> 16; $y0 = $y & 0xFFFF; $z2 = $x1 * $y1; // up to 32 bits long $z0 = $x0 * $y0; // up to 32 bits long $z1 = $x1 * $y0 + $x0 * $y1; // up to 33 bit long // normally karatsuba multiplication calculates $z1 thusly: //$z1 = ($x1 + $x0) * ($y0 + $y1) - $z2 - $z0; // the idea being to eliminate one extra multiplication. for arbitrary precision math that makes sense // but not for this purpose // at this point karatsuba would normally return this: //return ($z2 << 64) + ($z1 << 32) + $z0; // the problem is that the output could be out of range for signed 64-bit ints, // which would cause PHP to switch to floats, which would risk losing the lower few bits // as such we'll OR 4x 16-bit blocks together like so: /* ........ | ........ | ........ | ........ upper $z2 | lower $z2 | lower $z1 | lower $z0 | +upper $z1 | +upper $z0 | + $carry | + $carry | | */ // technically upper $z1 is 17 bit - not 16 - but the most significant digit of that will // just get added to $carry $a = $z0 & 0xFFFF; $b = ($z0 >> 16) + ($z1 & 0xFFFF); $c = ($z1 >> 16) + ($z2 & 0xFFFF) + ($b >> 16); $b = ($b & 0xFFFF) << 16; $d = ($z2 >> 16) + ($c >> 16); $c = ($c & 0xFFFF) << 32; $d = ($d & 0xFFFF) << 48; return $a | $b | $c | $d; } /** * 64-bit Addition with 2x 64-bit ints * * @param int $x * @param int $y * @return int $x + $y */ private static function add64($x, $y) { // doing $x + $y risks returning a result that's out of range for signed 64-bit ints // in that event PHP would convert the result to a float and precision would be lost // so we'll just add 2x 32-bit ints together like so: /* ........ | ........ upper $x | lower $x +upper $y |+lower $y + $carry | */ $x1 = $x & 0xFFFFFFFF; $x2 = ($x >> 32) & 0xFFFFFFFF; $y1 = $y & 0xFFFFFFFF; $y2 = ($y >> 32) & 0xFFFFFFFF; $a = $x1 + $y1; $b = ($x2 + $y2 + ($a >> 32)) << 32; $a &= 0xFFFFFFFF; return $a | $b; } /** * NH Algorithm / 64-bit safe * * @param string $k string of length 1024 bytes. * @param string $m string with length divisible by 32 bytes. * @return string string of length 8 bytes. */ private static function nh64($k, $m, $length) { // // Break M and K into 4-byte chunks // $k = unpack('N*', $k); $m = unpack('N*', $m); $t = count($m); // // Perform NH hash on the chunks, pairing words for multiplication // which are 4 apart to accommodate vector-parallelism. // $i = 1; $y = 0; while ($i <= $t) { $temp = ($m[$i] + $k[$i]) & 0xFFFFFFFF; $temp2 = ($m[$i + 4] + $k[$i + 4]) & 0xFFFFFFFF; $y = self::add64($y, self::mul64($temp, $temp2)); $temp = ($m[$i + 1] + $k[$i + 1]) & 0xFFFFFFFF; $temp2 = ($m[$i + 5] + $k[$i + 5]) & 0xFFFFFFFF; $y = self::add64($y, self::mul64($temp, $temp2)); $temp = ($m[$i + 2] + $k[$i + 2]) & 0xFFFFFFFF; $temp2 = ($m[$i + 6] + $k[$i + 6]) & 0xFFFFFFFF; $y = self::add64($y, self::mul64($temp, $temp2)); $temp = ($m[$i + 3] + $k[$i + 3]) & 0xFFFFFFFF; $temp2 = ($m[$i + 7] + $k[$i + 7]) & 0xFFFFFFFF; $y = self::add64($y, self::mul64($temp, $temp2)); $i += 8; } return pack('J', self::add64($y, $length)); } /** * L2-HASH: Second-Layer Hash * * The second-layer rehashes the L1-HASH output using a polynomial hash * called POLY. If the L1-HASH output is long, then POLY is called once * on a prefix of the L1-HASH output and called using different settings * on the remainder. (This two-step hashing of the L1-HASH output is * needed only if the message length is greater than 16 megabytes.) * Careful implementation of POLY is necessary to avoid a possible * timing attack (see Section 6.6 for more information). * * @param string $k string of length 24 bytes. * @param string $m string of length less than 2^64 bytes. * @return string string of length 16 bytes. */ private static function L2Hash($k, $m) { // // Extract keys and restrict to special key-sets // $k64 = $k & "\x01\xFF\xFF\xFF\x01\xFF\xFF\xFF"; $k64 = new BigInteger($k64, 256); $k128 = substr($k, 8) & "\x01\xFF\xFF\xFF\x01\xFF\xFF\xFF\x01\xFF\xFF\xFF\x01\xFF\xFF\xFF"; $k128 = new BigInteger($k128, 256); // // If M is no more than 2^17 bytes, hash under 64-bit prime, // otherwise, hash first 2^17 bytes under 64-bit prime and // remainder under 128-bit prime. // if (strlen($m) <= 0x20000) { // 2^14 64-bit words $y = self::poly(64, self::$maxwordrange64, $k64, $m); } else { $m_1 = substr($m, 0, 0x20000); // 1 << 17 $m_2 = substr($m, 0x20000) . "\x80"; $length = strlen($m_2); $pad = 16 - ($length % 16); $pad %= 16; $m_2 = str_pad($m_2, $length + $pad, "\0"); // zeropad $y = self::poly(64, self::$maxwordrange64, $k64, $m_1); $y = str_pad($y, 16, "\0", STR_PAD_LEFT); $y = self::poly(128, self::$maxwordrange128, $k128, $y . $m_2); } return str_pad($y, 16, "\0", STR_PAD_LEFT); } /** * POLY Algorithm * * @param int $wordbits the integer 64 or 128. * @param BigInteger $maxwordrange positive integer less than 2^wordbits. * @param BigInteger $k integer in the range 0 ... prime(wordbits) - 1. * @param string $m string with length divisible by (wordbits / 8) bytes. * @return integer in the range 0 ... prime(wordbits) - 1. */ private static function poly($wordbits, $maxwordrange, $k, $m) { // // Define constants used for fixing out-of-range words // $wordbytes = $wordbits >> 3; if ($wordbits == 128) { $factory = self::$factory128; $offset = self::$offset128; $marker = self::$marker128; } else { $factory = self::$factory64; $offset = self::$offset64; $marker = self::$marker64; } $k = $factory->newInteger($k); // // Break M into chunks of length wordbytes bytes // $m_i = str_split($m, $wordbytes); // // Each input word m is compared with maxwordrange. If not smaller // then 'marker' and (m - offset), both in range, are hashed. // $y = $factory->newInteger(new BigInteger(1)); foreach ($m_i as $m) { $m = $factory->newInteger(new BigInteger($m, 256)); if ($m->compare($maxwordrange) >= 0) { $y = $k->multiply($y)->add($marker); $y = $k->multiply($y)->add($m->subtract($offset)); } else { $y = $k->multiply($y)->add($m); } } return $y->toBytes(); } /** * L3-HASH: Third-Layer Hash * * The output from L2-HASH is 16 bytes long. This final hash function * hashes the 16-byte string to a fixed length of 4 bytes. * * @param string $k1 string of length 64 bytes. * @param string $k2 string of length 4 bytes. * @param string $m string of length 16 bytes. * @return string string of length 4 bytes. */ private static function L3Hash($k1, $k2, $m) { $factory = self::$factory36; $y = $factory->newInteger(new BigInteger()); for ($i = 0; $i < 8; $i++) { $m_i = $factory->newInteger(new BigInteger(substr($m, 2 * $i, 2), 256)); $k_i = $factory->newInteger(new BigInteger(substr($k1, 8 * $i, 8), 256)); $y = $y->add($m_i->multiply($k_i)); } $y = str_pad(substr($y->toBytes(), -4), 4, "\0", STR_PAD_LEFT); $y = $y ^ $k2; return $y; } /** * Compute the Hash / HMAC / UMAC. * * @param string $text * @return string */ public function hash($text) { $algo = $this->algo; // https://www.rfc-editor.org/rfc/rfc4493.html // https://en.wikipedia.org/wiki/One-key_MAC if ($algo == 'aes_cmac') { $constZero = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; if ($this->recomputeAESKey) { if (!is_string($this->key)) { throw new InsufficientSetupException('No key has been set'); } if (strlen($this->key) != 16) { throw new \LengthException('Key must be 16 bytes long'); } // Algorithm Generate_Subkey $constRb = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x87"; $this->c = new AES('ecb'); $this->c->setKey($this->key); $this->c->disablePadding(); $l = $this->c->encrypt($constZero); $msb = ($l & "\x80") == "\x80"; $l = new BigInteger($l, 256); $l->setPrecision(128); $l = $l->bitwise_leftShift(1)->toBytes(); // make it constant time $k1 = $msb ? $l ^ $constRb : $l | $constZero; $msb = ($k1 & "\x80") == "\x80"; $k2 = new BigInteger($k1, 256); $k2->setPrecision(128); $k2 = $k2->bitwise_leftShift(1)->toBytes(); // make it constant time $k2 = $msb ? $k2 ^ $constRb : $k2 | $constZero; $this->k1 = $k1; $this->k2 = $k2; } $len = strlen($text); $const_Bsize = 16; $M = strlen($text) ? str_split($text, $const_Bsize) : ['']; // Step 2 $n = ceil($len / $const_Bsize); // Step 3 if ($n == 0) { $n = 1; $flag = false; } else { $flag = $len % $const_Bsize == 0; } // Step 4 $M_last = $flag ? $M[$n - 1] ^ $k1 : self::OMAC_padding($M[$n - 1], $const_Bsize) ^ $k2; // Step 5 $x = $constZero; // Step 6 $c = &$this->c; for ($i = 0; $i < $n - 1; $i++) { $y = $x ^ $M[$i]; $x = $c->encrypt($y); } $y = $M_last ^ $x; return $c->encrypt($y); } if ($algo == 'umac') { if ($this->recomputeAESKey) { if (!is_string($this->nonce)) { throw new InsufficientSetupException('No nonce has been set'); } if (!is_string($this->key)) { throw new InsufficientSetupException('No key has been set'); } if (strlen($this->key) != 16) { throw new \LengthException('Key must be 16 bytes long'); } if (!isset(self::$maxwordrange64)) { $one = new BigInteger(1); $prime36 = new BigInteger("\x00\x00\x00\x0F\xFF\xFF\xFF\xFB", 256); self::$factory36 = new PrimeField($prime36); $prime64 = new BigInteger("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC5", 256); self::$factory64 = new PrimeField($prime64); $prime128 = new BigInteger("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x61", 256); self::$factory128 = new PrimeField($prime128); self::$offset64 = new BigInteger("\1\0\0\0\0\0\0\0\0", 256); self::$offset64 = self::$factory64->newInteger(self::$offset64->subtract($prime64)); self::$offset128 = new BigInteger("\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 256); self::$offset128 = self::$factory128->newInteger(self::$offset128->subtract($prime128)); self::$marker64 = self::$factory64->newInteger($prime64->subtract($one)); self::$marker128 = self::$factory128->newInteger($prime128->subtract($one)); $maxwordrange64 = $one->bitwise_leftShift(64)->subtract($one->bitwise_leftShift(32)); self::$maxwordrange64 = self::$factory64->newInteger($maxwordrange64); $maxwordrange128 = $one->bitwise_leftShift(128)->subtract($one->bitwise_leftShift(96)); self::$maxwordrange128 = self::$factory128->newInteger($maxwordrange128); } $this->c = new AES('ctr'); $this->c->disablePadding(); $this->c->setKey($this->key); $this->pad = $this->pdf(); $this->recomputeAESKey = false; } $hashedmessage = $this->uhash($text, $this->length); return $hashedmessage ^ $this->pad; } if (is_array($algo)) { if (empty($this->key) || !is_string($this->key)) { return substr($algo($text, ...array_values($this->parameters)), 0, $this->length); } // SHA3 HMACs are discussed at https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf#page=30 $key = str_pad($this->computedKey, $b, chr(0)); $temp = $this->ipad ^ $key; $temp .= $text; $temp = substr($algo($temp, ...array_values($this->parameters)), 0, $this->length); $output = $this->opad ^ $key; $output .= $temp; $output = $algo($output, ...array_values($this->parameters)); return substr($output, 0, $this->length); } $output = !empty($this->key) || is_string($this->key) ? hash_hmac($algo, $text, $this->computedKey, true) : hash($algo, $text, true); return strlen($output) > $this->length ? substr($output, 0, $this->length) : $output; } /** * Returns the hash length (in bits) * * @return int */ public function getLength() { return $this->length << 3; } /** * Returns the hash length (in bytes) * * @return int */ public function getLengthInBytes() { return $this->length; } /** * Returns the block length (in bits) * * @return int */ public function getBlockLength() { return $this->blockSize; } /** * Returns the block length (in bytes) * * @return int */ public function getBlockLengthInBytes() { return $this->blockSize >> 3; } /** * Pads SHA3 based on the mode * * @param int $padLength * @param int $padType * @return string */ private static function sha3_pad($padLength, $padType) { switch ($padType) { case self::PADDING_KECCAK: $temp = chr(0x01) . str_repeat("\0", $padLength - 1); $temp[$padLength - 1] = $temp[$padLength - 1] | chr(0x80); return $temp; case self::PADDING_SHAKE: $temp = chr(0x1F) . str_repeat("\0", $padLength - 1); $temp[$padLength - 1] = $temp[$padLength - 1] | chr(0x80); return $temp; //case self::PADDING_SHA3: default: // from https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf#page=36 return $padLength == 1 ? chr(0x86) : chr(0x06) . str_repeat("\0", $padLength - 2) . chr(0x80); } } /** * Pure-PHP 32-bit implementation of SHA3 * * Whereas BigInteger.php's 32-bit engine works on PHP 64-bit this 32-bit implementation * of SHA3 will *not* work on PHP 64-bit. This is because this implementation * employees bitwise NOTs and bitwise left shifts. And the round constants only work * on 32-bit PHP. eg. dechex(-2147483648) returns 80000000 on 32-bit PHP and * FFFFFFFF80000000 on 64-bit PHP. Sure, we could do bitwise ANDs but that would slow * things down. * * SHA512 requires BigInteger to simulate 64-bit unsigned integers because SHA2 employees * addition whereas SHA3 just employees bitwise operators. PHP64 only supports signed * 64-bit integers, which complicates addition, whereas that limitation isn't an issue * for SHA3. * * In https://ws680.nist.gov/publication/get_pdf.cfm?pub_id=919061#page=16 KECCAK[C] is * defined as "the KECCAK instance with KECCAK-f[1600] as the underlying permutation and * capacity c". This is relevant because, altho the KECCAK standard defines a mode * (KECCAK-f[800]) designed for 32-bit machines that mode is incompatible with SHA3 * * @param string $p * @param int $c * @param int $r * @param int $d * @param int $padType */ private static function sha3_32($p, $c, $r, $d, $padType) { $block_size = $r >> 3; $padLength = $block_size - (strlen($p) % $block_size); $num_ints = $block_size >> 2; $p .= static::sha3_pad($padLength, $padType); $n = strlen($p) / $r; // number of blocks $s = [ [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]] ]; $p = str_split($p, $block_size); foreach ($p as $pi) { $pi = unpack('V*', $pi); $x = $y = 0; for ($i = 1; $i <= $num_ints; $i += 2) { $s[$x][$y][0] ^= $pi[$i + 1]; $s[$x][$y][1] ^= $pi[$i]; if (++$y == 5) { $y = 0; $x++; } } static::processSHA3Block32($s); } $z = ''; $i = $j = 0; while (strlen($z) < $d) { $z .= pack('V2', $s[$i][$j][1], $s[$i][$j++][0]); if ($j == 5) { $j = 0; $i++; if ($i == 5) { $i = 0; static::processSHA3Block32($s); } } } return $z; } /** * 32-bit block processing method for SHA3 * * @param array $s */ private static function processSHA3Block32(&$s) { static $rotationOffsets = [ [ 0, 1, 62, 28, 27], [36, 44, 6, 55, 20], [ 3, 10, 43, 25, 39], [41, 45, 15, 21, 8], [18, 2, 61, 56, 14] ]; // the standards give these constants in hexadecimal notation. it's tempting to want to use // that same notation, here, however, we can't, because 0x80000000, on PHP32, is a positive // float - not the negative int that we need to be in PHP32. so we use -2147483648 instead static $roundConstants = [ [0, 1], [0, 32898], [-2147483648, 32906], [-2147483648, -2147450880], [0, 32907], [0, -2147483647], [-2147483648, -2147450751], [-2147483648, 32777], [0, 138], [0, 136], [0, -2147450871], [0, -2147483638], [0, -2147450741], [-2147483648, 139], [-2147483648, 32905], [-2147483648, 32771], [-2147483648, 32770], [-2147483648, 128], [0, 32778], [-2147483648, -2147483638], [-2147483648, -2147450751], [-2147483648, 32896], [0, -2147483647], [-2147483648, -2147450872] ]; for ($round = 0; $round < 24; $round++) { // theta step $parity = $rotated = []; for ($i = 0; $i < 5; $i++) { $parity[] = [ $s[0][$i][0] ^ $s[1][$i][0] ^ $s[2][$i][0] ^ $s[3][$i][0] ^ $s[4][$i][0], $s[0][$i][1] ^ $s[1][$i][1] ^ $s[2][$i][1] ^ $s[3][$i][1] ^ $s[4][$i][1] ]; $rotated[] = static::rotateLeft32($parity[$i], 1); } $temp = [ [$parity[4][0] ^ $rotated[1][0], $parity[4][1] ^ $rotated[1][1]], [$parity[0][0] ^ $rotated[2][0], $parity[0][1] ^ $rotated[2][1]], [$parity[1][0] ^ $rotated[3][0], $parity[1][1] ^ $rotated[3][1]], [$parity[2][0] ^ $rotated[4][0], $parity[2][1] ^ $rotated[4][1]], [$parity[3][0] ^ $rotated[0][0], $parity[3][1] ^ $rotated[0][1]] ]; for ($i = 0; $i < 5; $i++) { for ($j = 0; $j < 5; $j++) { $s[$i][$j][0] ^= $temp[$j][0]; $s[$i][$j][1] ^= $temp[$j][1]; } } $st = $s; // rho and pi steps for ($i = 0; $i < 5; $i++) { for ($j = 0; $j < 5; $j++) { $st[(2 * $i + 3 * $j) % 5][$j] = static::rotateLeft32($s[$j][$i], $rotationOffsets[$j][$i]); } } // chi step for ($i = 0; $i < 5; $i++) { $s[$i][0] = [ $st[$i][0][0] ^ (~$st[$i][1][0] & $st[$i][2][0]), $st[$i][0][1] ^ (~$st[$i][1][1] & $st[$i][2][1]) ]; $s[$i][1] = [ $st[$i][1][0] ^ (~$st[$i][2][0] & $st[$i][3][0]), $st[$i][1][1] ^ (~$st[$i][2][1] & $st[$i][3][1]) ]; $s[$i][2] = [ $st[$i][2][0] ^ (~$st[$i][3][0] & $st[$i][4][0]), $st[$i][2][1] ^ (~$st[$i][3][1] & $st[$i][4][1]) ]; $s[$i][3] = [ $st[$i][3][0] ^ (~$st[$i][4][0] & $st[$i][0][0]), $st[$i][3][1] ^ (~$st[$i][4][1] & $st[$i][0][1]) ]; $s[$i][4] = [ $st[$i][4][0] ^ (~$st[$i][0][0] & $st[$i][1][0]), $st[$i][4][1] ^ (~$st[$i][0][1] & $st[$i][1][1]) ]; } // iota step $s[0][0][0] ^= $roundConstants[$round][0]; $s[0][0][1] ^= $roundConstants[$round][1]; } } /** * Rotate 32-bit int * * @param array $x * @param int $shift */ private static function rotateLeft32($x, $shift) { if ($shift < 32) { list($hi, $lo) = $x; } else { $shift -= 32; list($lo, $hi) = $x; } $mask = -1 ^ (-1 << $shift); return [ ($hi << $shift) | (($lo >> (32 - $shift)) & $mask), ($lo << $shift) | (($hi >> (32 - $shift)) & $mask) ]; } /** * Pure-PHP 64-bit implementation of SHA3 * * @param string $p * @param int $c * @param int $r * @param int $d * @param int $padType */ private static function sha3_64($p, $c, $r, $d, $padType) { $block_size = $r >> 3; $padLength = $block_size - (strlen($p) % $block_size); $num_ints = $block_size >> 2; $p .= static::sha3_pad($padLength, $padType); $n = strlen($p) / $r; // number of blocks $s = [ [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0] ]; $p = str_split($p, $block_size); foreach ($p as $pi) { $pi = unpack('P*', $pi); $x = $y = 0; foreach ($pi as $subpi) { $s[$x][$y++] ^= $subpi; if ($y == 5) { $y = 0; $x++; } } static::processSHA3Block64($s); } $z = ''; $i = $j = 0; while (strlen($z) < $d) { $z .= pack('P', $s[$i][$j++]); if ($j == 5) { $j = 0; $i++; if ($i == 5) { $i = 0; static::processSHA3Block64($s); } } } return $z; } /** * 64-bit block processing method for SHA3 * * @param array $s */ private static function processSHA3Block64(&$s) { static $rotationOffsets = [ [ 0, 1, 62, 28, 27], [36, 44, 6, 55, 20], [ 3, 10, 43, 25, 39], [41, 45, 15, 21, 8], [18, 2, 61, 56, 14] ]; static $roundConstants = [ 1, 32898, -9223372036854742902, -9223372034707259392, 32907, 2147483649, -9223372034707259263, -9223372036854743031, 138, 136, 2147516425, 2147483658, 2147516555, -9223372036854775669, -9223372036854742903, -9223372036854743037, -9223372036854743038, -9223372036854775680, 32778, -9223372034707292150, -9223372034707259263, -9223372036854742912, 2147483649, -9223372034707259384 ]; for ($round = 0; $round < 24; $round++) { // theta step $parity = []; for ($i = 0; $i < 5; $i++) { $parity[] = $s[0][$i] ^ $s[1][$i] ^ $s[2][$i] ^ $s[3][$i] ^ $s[4][$i]; } $temp = [ $parity[4] ^ static::rotateLeft64($parity[1], 1), $parity[0] ^ static::rotateLeft64($parity[2], 1), $parity[1] ^ static::rotateLeft64($parity[3], 1), $parity[2] ^ static::rotateLeft64($parity[4], 1), $parity[3] ^ static::rotateLeft64($parity[0], 1) ]; for ($i = 0; $i < 5; $i++) { for ($j = 0; $j < 5; $j++) { $s[$i][$j] ^= $temp[$j]; } } $st = $s; // rho and pi steps for ($i = 0; $i < 5; $i++) { for ($j = 0; $j < 5; $j++) { $st[(2 * $i + 3 * $j) % 5][$j] = static::rotateLeft64($s[$j][$i], $rotationOffsets[$j][$i]); } } // chi step for ($i = 0; $i < 5; $i++) { $s[$i] = [ $st[$i][0] ^ (~$st[$i][1] & $st[$i][2]), $st[$i][1] ^ (~$st[$i][2] & $st[$i][3]), $st[$i][2] ^ (~$st[$i][3] & $st[$i][4]), $st[$i][3] ^ (~$st[$i][4] & $st[$i][0]), $st[$i][4] ^ (~$st[$i][0] & $st[$i][1]) ]; } // iota step $s[0][0] ^= $roundConstants[$round]; } } /** * Left rotate 64-bit int * * @param int $x * @param int $shift */ private static function rotateLeft64($x, $shift) { $mask = -1 ^ (-1 << $shift); return ($x << $shift) | (($x >> (64 - $shift)) & $mask); } /** * Right rotate 64-bit int * * @param int $x * @param int $shift */ private static function rotateRight64($x, $shift) { $mask = -1 ^ (-1 << (64 - $shift)); return (($x >> $shift) & $mask) | ($x << (64 - $shift)); } /** * Pure-PHP implementation of SHA512 * * @param string $m * @param array $hash * @return string */ private static function sha512($m, $hash) { static $k; if (!isset($k)) { // Initialize table of round constants // (first 64 bits of the fractional parts of the cube roots of the first 80 primes 2..409) $k = [ '428a2f98d728ae22', '7137449123ef65cd', 'b5c0fbcfec4d3b2f', 'e9b5dba58189dbbc', '3956c25bf348b538', '59f111f1b605d019', '923f82a4af194f9b', 'ab1c5ed5da6d8118', 'd807aa98a3030242', '12835b0145706fbe', '243185be4ee4b28c', '550c7dc3d5ffb4e2', '72be5d74f27b896f', '80deb1fe3b1696b1', '9bdc06a725c71235', 'c19bf174cf692694', 'e49b69c19ef14ad2', 'efbe4786384f25e3', '0fc19dc68b8cd5b5', '240ca1cc77ac9c65', '2de92c6f592b0275', '4a7484aa6ea6e483', '5cb0a9dcbd41fbd4', '76f988da831153b5', '983e5152ee66dfab', 'a831c66d2db43210', 'b00327c898fb213f', 'bf597fc7beef0ee4', 'c6e00bf33da88fc2', 'd5a79147930aa725', '06ca6351e003826f', '142929670a0e6e70', '27b70a8546d22ffc', '2e1b21385c26c926', '4d2c6dfc5ac42aed', '53380d139d95b3df', '650a73548baf63de', '766a0abb3c77b2a8', '81c2c92e47edaee6', '92722c851482353b', 'a2bfe8a14cf10364', 'a81a664bbc423001', 'c24b8b70d0f89791', 'c76c51a30654be30', 'd192e819d6ef5218', 'd69906245565a910', 'f40e35855771202a', '106aa07032bbd1b8', '19a4c116b8d2d0c8', '1e376c085141ab53', '2748774cdf8eeb99', '34b0bcb5e19b48a8', '391c0cb3c5c95a63', '4ed8aa4ae3418acb', '5b9cca4f7763e373', '682e6ff3d6b2b8a3', '748f82ee5defb2fc', '78a5636f43172f60', '84c87814a1f0ab72', '8cc702081a6439ec', '90befffa23631e28', 'a4506cebde82bde9', 'bef9a3f7b2c67915', 'c67178f2e372532b', 'ca273eceea26619c', 'd186b8c721c0c207', 'eada7dd6cde0eb1e', 'f57d4f7fee6ed178', '06f067aa72176fba', '0a637dc5a2c898a6', '113f9804bef90dae', '1b710b35131c471b', '28db77f523047d84', '32caab7b40c72493', '3c9ebe0a15c9bebc', '431d67c49c100d4c', '4cc5d4becb3e42b6', '597f299cfc657e2a', '5fcb6fab3ad6faec', '6c44198c4a475817' ]; for ($i = 0; $i < 80; $i++) { $k[$i] = new BigInteger($k[$i], 16); } } // Pre-processing $length = strlen($m); // to round to nearest 112 mod 128, we'll add 128 - (length + (128 - 112)) % 128 $m .= str_repeat(chr(0), 128 - (($length + 16) & 0x7F)); $m[$length] = chr(0x80); // we don't support hashing strings 512MB long $m .= pack('N4', 0, 0, 0, $length << 3); // Process the message in successive 1024-bit chunks $chunks = str_split($m, 128); foreach ($chunks as $chunk) { $w = []; for ($i = 0; $i < 16; $i++) { $temp = new BigInteger(Strings::shift($chunk, 8), 256); $temp->setPrecision(64); $w[] = $temp; } // Extend the sixteen 32-bit words into eighty 32-bit words for ($i = 16; $i < 80; $i++) { $temp = [ $w[$i - 15]->bitwise_rightRotate(1), $w[$i - 15]->bitwise_rightRotate(8), $w[$i - 15]->bitwise_rightShift(7) ]; $s0 = $temp[0]->bitwise_xor($temp[1]); $s0 = $s0->bitwise_xor($temp[2]); $temp = [ $w[$i - 2]->bitwise_rightRotate(19), $w[$i - 2]->bitwise_rightRotate(61), $w[$i - 2]->bitwise_rightShift(6) ]; $s1 = $temp[0]->bitwise_xor($temp[1]); $s1 = $s1->bitwise_xor($temp[2]); $w[$i] = clone $w[$i - 16]; $w[$i] = $w[$i]->add($s0); $w[$i] = $w[$i]->add($w[$i - 7]); $w[$i] = $w[$i]->add($s1); } // Initialize hash value for this chunk $a = clone $hash[0]; $b = clone $hash[1]; $c = clone $hash[2]; $d = clone $hash[3]; $e = clone $hash[4]; $f = clone $hash[5]; $g = clone $hash[6]; $h = clone $hash[7]; // Main loop for ($i = 0; $i < 80; $i++) { $temp = [ $a->bitwise_rightRotate(28), $a->bitwise_rightRotate(34), $a->bitwise_rightRotate(39) ]; $s0 = $temp[0]->bitwise_xor($temp[1]); $s0 = $s0->bitwise_xor($temp[2]); $temp = [ $a->bitwise_and($b), $a->bitwise_and($c), $b->bitwise_and($c) ]; $maj = $temp[0]->bitwise_xor($temp[1]); $maj = $maj->bitwise_xor($temp[2]); $t2 = $s0->add($maj); $temp = [ $e->bitwise_rightRotate(14), $e->bitwise_rightRotate(18), $e->bitwise_rightRotate(41) ]; $s1 = $temp[0]->bitwise_xor($temp[1]); $s1 = $s1->bitwise_xor($temp[2]); $temp = [ $e->bitwise_and($f), $g->bitwise_and($e->bitwise_not()) ]; $ch = $temp[0]->bitwise_xor($temp[1]); $t1 = $h->add($s1); $t1 = $t1->add($ch); $t1 = $t1->add($k[$i]); $t1 = $t1->add($w[$i]); $h = clone $g; $g = clone $f; $f = clone $e; $e = $d->add($t1); $d = clone $c; $c = clone $b; $b = clone $a; $a = $t1->add($t2); } // Add this chunk's hash to result so far $hash = [ $hash[0]->add($a), $hash[1]->add($b), $hash[2]->add($c), $hash[3]->add($d), $hash[4]->add($e), $hash[5]->add($f), $hash[6]->add($g), $hash[7]->add($h) ]; } // Produce the final hash value (big-endian) // (\phpseclib3\Crypt\Hash::hash() trims the output for hashes but not for HMACs. as such, we trim the output here) $temp = $hash[0]->toBytes() . $hash[1]->toBytes() . $hash[2]->toBytes() . $hash[3]->toBytes() . $hash[4]->toBytes() . $hash[5]->toBytes() . $hash[6]->toBytes() . $hash[7]->toBytes(); return $temp; } /** * Pure-PHP implementation of SHA512 * * @param string $m * @param array $hash * @return string */ private static function sha512_64($m, $hash) { static $k; if (!isset($k)) { // Initialize table of round constants // (first 64 bits of the fractional parts of the cube roots of the first 80 primes 2..409) $k = [ '428a2f98d728ae22', '7137449123ef65cd', 'b5c0fbcfec4d3b2f', 'e9b5dba58189dbbc', '3956c25bf348b538', '59f111f1b605d019', '923f82a4af194f9b', 'ab1c5ed5da6d8118', 'd807aa98a3030242', '12835b0145706fbe', '243185be4ee4b28c', '550c7dc3d5ffb4e2', '72be5d74f27b896f', '80deb1fe3b1696b1', '9bdc06a725c71235', 'c19bf174cf692694', 'e49b69c19ef14ad2', 'efbe4786384f25e3', '0fc19dc68b8cd5b5', '240ca1cc77ac9c65', '2de92c6f592b0275', '4a7484aa6ea6e483', '5cb0a9dcbd41fbd4', '76f988da831153b5', '983e5152ee66dfab', 'a831c66d2db43210', 'b00327c898fb213f', 'bf597fc7beef0ee4', 'c6e00bf33da88fc2', 'd5a79147930aa725', '06ca6351e003826f', '142929670a0e6e70', '27b70a8546d22ffc', '2e1b21385c26c926', '4d2c6dfc5ac42aed', '53380d139d95b3df', '650a73548baf63de', '766a0abb3c77b2a8', '81c2c92e47edaee6', '92722c851482353b', 'a2bfe8a14cf10364', 'a81a664bbc423001', 'c24b8b70d0f89791', 'c76c51a30654be30', 'd192e819d6ef5218', 'd69906245565a910', 'f40e35855771202a', '106aa07032bbd1b8', '19a4c116b8d2d0c8', '1e376c085141ab53', '2748774cdf8eeb99', '34b0bcb5e19b48a8', '391c0cb3c5c95a63', '4ed8aa4ae3418acb', '5b9cca4f7763e373', '682e6ff3d6b2b8a3', '748f82ee5defb2fc', '78a5636f43172f60', '84c87814a1f0ab72', '8cc702081a6439ec', '90befffa23631e28', 'a4506cebde82bde9', 'bef9a3f7b2c67915', 'c67178f2e372532b', 'ca273eceea26619c', 'd186b8c721c0c207', 'eada7dd6cde0eb1e', 'f57d4f7fee6ed178', '06f067aa72176fba', '0a637dc5a2c898a6', '113f9804bef90dae', '1b710b35131c471b', '28db77f523047d84', '32caab7b40c72493', '3c9ebe0a15c9bebc', '431d67c49c100d4c', '4cc5d4becb3e42b6', '597f299cfc657e2a', '5fcb6fab3ad6faec', '6c44198c4a475817' ]; for ($i = 0; $i < 80; $i++) { list(, $k[$i]) = unpack('J', pack('H*', $k[$i])); } } // Pre-processing $length = strlen($m); // to round to nearest 112 mod 128, we'll add 128 - (length + (128 - 112)) % 128 $m .= str_repeat(chr(0), 128 - (($length + 16) & 0x7F)); $m[$length] = chr(0x80); // we don't support hashing strings 512MB long $m .= pack('N4', 0, 0, 0, $length << 3); // Process the message in successive 1024-bit chunks $chunks = str_split($m, 128); foreach ($chunks as $chunk) { $w = []; for ($i = 0; $i < 16; $i++) { list(, $w[]) = unpack('J', Strings::shift($chunk, 8)); } // Extend the sixteen 32-bit words into eighty 32-bit words for ($i = 16; $i < 80; $i++) { $temp = [ self::rotateRight64($w[$i - 15], 1), self::rotateRight64($w[$i - 15], 8), ($w[$i - 15] >> 7) & 0x01FFFFFFFFFFFFFF, ]; $s0 = $temp[0] ^ $temp[1] ^ $temp[2]; $temp = [ self::rotateRight64($w[$i - 2], 19), self::rotateRight64($w[$i - 2], 61), ($w[$i - 2] >> 6) & 0x03FFFFFFFFFFFFFF, ]; $s1 = $temp[0] ^ $temp[1] ^ $temp[2]; $w[$i] = $w[$i - 16]; $w[$i] = self::add64($w[$i], $s0); $w[$i] = self::add64($w[$i], $w[$i - 7]); $w[$i] = self::add64($w[$i], $s1); } // Initialize hash value for this chunk list($a, $b, $c, $d, $e, $f, $g, $h) = $hash; // Main loop for ($i = 0; $i < 80; $i++) { $temp = [ self::rotateRight64($a, 28), self::rotateRight64($a, 34), self::rotateRight64($a, 39), ]; $s0 = $temp[0] ^ $temp[1] ^ $temp[2]; $temp = [$a & $b, $a & $c, $b & $c]; $maj = $temp[0] ^ $temp[1] ^ $temp[2]; $t2 = self::add64($s0, $maj); $temp = [ self::rotateRight64($e, 14), self::rotateRight64($e, 18), self::rotateRight64($e, 41), ]; $s1 = $temp[0] ^ $temp[1] ^ $temp[2]; $ch = ($e & $f) ^ ($g & ~$e); $t1 = self::add64($h, $s1); $t1 = self::add64($t1, $ch); $t1 = self::add64($t1, $k[$i]); $t1 = self::add64($t1, $w[$i]); $h = $g; $g = $f; $f = $e; $e = self::add64($d, $t1); $d = $c; $c = $b; $b = $a; $a = self::add64($t1, $t2); } // Add this chunk's hash to result so far $hash = [ self::add64($hash[0], $a), self::add64($hash[1], $b), self::add64($hash[2], $c), self::add64($hash[3], $d), self::add64($hash[4], $e), self::add64($hash[5], $f), self::add64($hash[6], $g), self::add64($hash[7], $h), ]; } // Produce the final hash value (big-endian) // (\phpseclib3\Crypt\Hash::hash() trims the output for hashes but not for HMACs. as such, we trim the output here) return pack('J*', ...$hash); } /** * OMAC Padding * * @link https://www.rfc-editor.org/rfc/rfc4493.html#section-2.4 */ private static function OMAC_padding($m, $length) { $count = $length - strlen($m) - 1; return "$m\x80" . str_repeat("\0", $count); } /** * __toString() magic method */ public function __toString() { return $this->getHash(); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/PublicKeyLoader.php ================================================ * @copyright 2009 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt; use phpseclib3\Crypt\Common\AsymmetricKey; use phpseclib3\Crypt\Common\PrivateKey; use phpseclib3\Crypt\Common\PublicKey; use phpseclib3\Exception\NoKeyLoadedException; use phpseclib3\File\X509; /** * PublicKeyLoader * * @author Jim Wigginton */ abstract class PublicKeyLoader { /** * Loads a public or private key * * @return AsymmetricKey * @param string|array $key * @param string $password optional * @throws NoKeyLoadedException if key is not valid */ public static function load($key, $password = false) { try { return EC::load($key, $password); } catch (NoKeyLoadedException $e) { } try { return RSA::load($key, $password); } catch (NoKeyLoadedException $e) { } try { return DSA::load($key, $password); } catch (NoKeyLoadedException $e) { } try { $x509 = new X509(); $x509->loadX509($key); $key = $x509->getPublicKey(); if ($key) { return $key; } } catch (\Exception $e) { } throw new NoKeyLoadedException('Unable to read key'); } /** * Loads a private key * * @return PrivateKey * @param string|array $key * @param string $password optional */ public static function loadPrivateKey($key, $password = false) { $key = self::load($key, $password); if (!$key instanceof PrivateKey) { throw new NoKeyLoadedException('The key that was loaded was not a private key'); } return $key; } /** * Loads a public key * * @return PublicKey * @param string|array $key */ public static function loadPublicKey($key) { $key = self::load($key); if (!$key instanceof PublicKey) { throw new NoKeyLoadedException('The key that was loaded was not a public key'); } return $key; } /** * Loads parameters * * @return AsymmetricKey * @param string|array $key */ public static function loadParameters($key) { $key = self::load($key); if (!$key instanceof PrivateKey && !$key instanceof PublicKey) { throw new NoKeyLoadedException('The key that was loaded was not a parameter'); } return $key; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php ================================================ * setKey('abcdefgh'); * * $plaintext = str_repeat('a', 1024); * * echo $rc2->decrypt($rc2->encrypt($plaintext)); * ?> * * * @author Patrick Monnerat * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt; use phpseclib3\Crypt\Common\BlockCipher; use phpseclib3\Exception\BadModeException; /** * Pure-PHP implementation of RC2. * */ class RC2 extends BlockCipher { /** * Block Length of the cipher * * @see Common\SymmetricKey::block_size * @var int */ protected $block_size = 8; /** * The Key * * @see Common\SymmetricKey::key * @see self::setKey() * @var string */ protected $key; /** * The Original (unpadded) Key * * @see Common\SymmetricKey::key * @see self::setKey() * @see self::encrypt() * @see self::decrypt() * @var string */ private $orig_key; /** * Key Length (in bytes) * * @see \phpseclib3\Crypt\RC2::setKeyLength() * @var int */ protected $key_length = 16; // = 128 bits /** * The mcrypt specific name of the cipher * * @see Common\SymmetricKey::cipher_name_mcrypt * @var string */ protected $cipher_name_mcrypt = 'rc2'; /** * Optimizing value while CFB-encrypting * * @see Common\SymmetricKey::cfb_init_len * @var int */ protected $cfb_init_len = 500; /** * The key length in bits. * * {@internal Should be in range [1..1024].} * * {@internal Changing this value after setting the key has no effect.} * * @see self::setKeyLength() * @see self::setKey() * @var int */ private $default_key_length = 1024; /** * The key length in bits. * * {@internal Should be in range [1..1024].} * * @see self::isValidEnine() * @see self::setKey() * @var int */ private $current_key_length; /** * The Key Schedule * * @see self::setupKey() * @var array */ private $keys; /** * Key expansion randomization table. * Twice the same 256-value sequence to save a modulus in key expansion. * * @see self::setKey() * @var array */ private static $pitable = [ 0xD9, 0x78, 0xF9, 0xC4, 0x19, 0xDD, 0xB5, 0xED, 0x28, 0xE9, 0xFD, 0x79, 0x4A, 0xA0, 0xD8, 0x9D, 0xC6, 0x7E, 0x37, 0x83, 0x2B, 0x76, 0x53, 0x8E, 0x62, 0x4C, 0x64, 0x88, 0x44, 0x8B, 0xFB, 0xA2, 0x17, 0x9A, 0x59, 0xF5, 0x87, 0xB3, 0x4F, 0x13, 0x61, 0x45, 0x6D, 0x8D, 0x09, 0x81, 0x7D, 0x32, 0xBD, 0x8F, 0x40, 0xEB, 0x86, 0xB7, 0x7B, 0x0B, 0xF0, 0x95, 0x21, 0x22, 0x5C, 0x6B, 0x4E, 0x82, 0x54, 0xD6, 0x65, 0x93, 0xCE, 0x60, 0xB2, 0x1C, 0x73, 0x56, 0xC0, 0x14, 0xA7, 0x8C, 0xF1, 0xDC, 0x12, 0x75, 0xCA, 0x1F, 0x3B, 0xBE, 0xE4, 0xD1, 0x42, 0x3D, 0xD4, 0x30, 0xA3, 0x3C, 0xB6, 0x26, 0x6F, 0xBF, 0x0E, 0xDA, 0x46, 0x69, 0x07, 0x57, 0x27, 0xF2, 0x1D, 0x9B, 0xBC, 0x94, 0x43, 0x03, 0xF8, 0x11, 0xC7, 0xF6, 0x90, 0xEF, 0x3E, 0xE7, 0x06, 0xC3, 0xD5, 0x2F, 0xC8, 0x66, 0x1E, 0xD7, 0x08, 0xE8, 0xEA, 0xDE, 0x80, 0x52, 0xEE, 0xF7, 0x84, 0xAA, 0x72, 0xAC, 0x35, 0x4D, 0x6A, 0x2A, 0x96, 0x1A, 0xD2, 0x71, 0x5A, 0x15, 0x49, 0x74, 0x4B, 0x9F, 0xD0, 0x5E, 0x04, 0x18, 0xA4, 0xEC, 0xC2, 0xE0, 0x41, 0x6E, 0x0F, 0x51, 0xCB, 0xCC, 0x24, 0x91, 0xAF, 0x50, 0xA1, 0xF4, 0x70, 0x39, 0x99, 0x7C, 0x3A, 0x85, 0x23, 0xB8, 0xB4, 0x7A, 0xFC, 0x02, 0x36, 0x5B, 0x25, 0x55, 0x97, 0x31, 0x2D, 0x5D, 0xFA, 0x98, 0xE3, 0x8A, 0x92, 0xAE, 0x05, 0xDF, 0x29, 0x10, 0x67, 0x6C, 0xBA, 0xC9, 0xD3, 0x00, 0xE6, 0xCF, 0xE1, 0x9E, 0xA8, 0x2C, 0x63, 0x16, 0x01, 0x3F, 0x58, 0xE2, 0x89, 0xA9, 0x0D, 0x38, 0x34, 0x1B, 0xAB, 0x33, 0xFF, 0xB0, 0xBB, 0x48, 0x0C, 0x5F, 0xB9, 0xB1, 0xCD, 0x2E, 0xC5, 0xF3, 0xDB, 0x47, 0xE5, 0xA5, 0x9C, 0x77, 0x0A, 0xA6, 0x20, 0x68, 0xFE, 0x7F, 0xC1, 0xAD, 0xD9, 0x78, 0xF9, 0xC4, 0x19, 0xDD, 0xB5, 0xED, 0x28, 0xE9, 0xFD, 0x79, 0x4A, 0xA0, 0xD8, 0x9D, 0xC6, 0x7E, 0x37, 0x83, 0x2B, 0x76, 0x53, 0x8E, 0x62, 0x4C, 0x64, 0x88, 0x44, 0x8B, 0xFB, 0xA2, 0x17, 0x9A, 0x59, 0xF5, 0x87, 0xB3, 0x4F, 0x13, 0x61, 0x45, 0x6D, 0x8D, 0x09, 0x81, 0x7D, 0x32, 0xBD, 0x8F, 0x40, 0xEB, 0x86, 0xB7, 0x7B, 0x0B, 0xF0, 0x95, 0x21, 0x22, 0x5C, 0x6B, 0x4E, 0x82, 0x54, 0xD6, 0x65, 0x93, 0xCE, 0x60, 0xB2, 0x1C, 0x73, 0x56, 0xC0, 0x14, 0xA7, 0x8C, 0xF1, 0xDC, 0x12, 0x75, 0xCA, 0x1F, 0x3B, 0xBE, 0xE4, 0xD1, 0x42, 0x3D, 0xD4, 0x30, 0xA3, 0x3C, 0xB6, 0x26, 0x6F, 0xBF, 0x0E, 0xDA, 0x46, 0x69, 0x07, 0x57, 0x27, 0xF2, 0x1D, 0x9B, 0xBC, 0x94, 0x43, 0x03, 0xF8, 0x11, 0xC7, 0xF6, 0x90, 0xEF, 0x3E, 0xE7, 0x06, 0xC3, 0xD5, 0x2F, 0xC8, 0x66, 0x1E, 0xD7, 0x08, 0xE8, 0xEA, 0xDE, 0x80, 0x52, 0xEE, 0xF7, 0x84, 0xAA, 0x72, 0xAC, 0x35, 0x4D, 0x6A, 0x2A, 0x96, 0x1A, 0xD2, 0x71, 0x5A, 0x15, 0x49, 0x74, 0x4B, 0x9F, 0xD0, 0x5E, 0x04, 0x18, 0xA4, 0xEC, 0xC2, 0xE0, 0x41, 0x6E, 0x0F, 0x51, 0xCB, 0xCC, 0x24, 0x91, 0xAF, 0x50, 0xA1, 0xF4, 0x70, 0x39, 0x99, 0x7C, 0x3A, 0x85, 0x23, 0xB8, 0xB4, 0x7A, 0xFC, 0x02, 0x36, 0x5B, 0x25, 0x55, 0x97, 0x31, 0x2D, 0x5D, 0xFA, 0x98, 0xE3, 0x8A, 0x92, 0xAE, 0x05, 0xDF, 0x29, 0x10, 0x67, 0x6C, 0xBA, 0xC9, 0xD3, 0x00, 0xE6, 0xCF, 0xE1, 0x9E, 0xA8, 0x2C, 0x63, 0x16, 0x01, 0x3F, 0x58, 0xE2, 0x89, 0xA9, 0x0D, 0x38, 0x34, 0x1B, 0xAB, 0x33, 0xFF, 0xB0, 0xBB, 0x48, 0x0C, 0x5F, 0xB9, 0xB1, 0xCD, 0x2E, 0xC5, 0xF3, 0xDB, 0x47, 0xE5, 0xA5, 0x9C, 0x77, 0x0A, 0xA6, 0x20, 0x68, 0xFE, 0x7F, 0xC1, 0xAD ]; /** * Inverse key expansion randomization table. * * @see self::setKey() * @var array */ private static $invpitable = [ 0xD1, 0xDA, 0xB9, 0x6F, 0x9C, 0xC8, 0x78, 0x66, 0x80, 0x2C, 0xF8, 0x37, 0xEA, 0xE0, 0x62, 0xA4, 0xCB, 0x71, 0x50, 0x27, 0x4B, 0x95, 0xD9, 0x20, 0x9D, 0x04, 0x91, 0xE3, 0x47, 0x6A, 0x7E, 0x53, 0xFA, 0x3A, 0x3B, 0xB4, 0xA8, 0xBC, 0x5F, 0x68, 0x08, 0xCA, 0x8F, 0x14, 0xD7, 0xC0, 0xEF, 0x7B, 0x5B, 0xBF, 0x2F, 0xE5, 0xE2, 0x8C, 0xBA, 0x12, 0xE1, 0xAF, 0xB2, 0x54, 0x5D, 0x59, 0x76, 0xDB, 0x32, 0xA2, 0x58, 0x6E, 0x1C, 0x29, 0x64, 0xF3, 0xE9, 0x96, 0x0C, 0x98, 0x19, 0x8D, 0x3E, 0x26, 0xAB, 0xA5, 0x85, 0x16, 0x40, 0xBD, 0x49, 0x67, 0xDC, 0x22, 0x94, 0xBB, 0x3C, 0xC1, 0x9B, 0xEB, 0x45, 0x28, 0x18, 0xD8, 0x1A, 0x42, 0x7D, 0xCC, 0xFB, 0x65, 0x8E, 0x3D, 0xCD, 0x2A, 0xA3, 0x60, 0xAE, 0x93, 0x8A, 0x48, 0x97, 0x51, 0x15, 0xF7, 0x01, 0x0B, 0xB7, 0x36, 0xB1, 0x2E, 0x11, 0xFD, 0x84, 0x2D, 0x3F, 0x13, 0x88, 0xB3, 0x34, 0x24, 0x1B, 0xDE, 0xC5, 0x1D, 0x4D, 0x2B, 0x17, 0x31, 0x74, 0xA9, 0xC6, 0x43, 0x6D, 0x39, 0x90, 0xBE, 0xC3, 0xB0, 0x21, 0x6B, 0xF6, 0x0F, 0xD5, 0x99, 0x0D, 0xAC, 0x1F, 0x5C, 0x9E, 0xF5, 0xF9, 0x4C, 0xD6, 0xDF, 0x89, 0xE4, 0x8B, 0xFF, 0xC7, 0xAA, 0xE7, 0xED, 0x46, 0x25, 0xB6, 0x06, 0x5E, 0x35, 0xB5, 0xEC, 0xCE, 0xE8, 0x6C, 0x30, 0x55, 0x61, 0x4A, 0xFE, 0xA0, 0x79, 0x03, 0xF0, 0x10, 0x72, 0x7C, 0xCF, 0x52, 0xA6, 0xA7, 0xEE, 0x44, 0xD3, 0x9A, 0x57, 0x92, 0xD0, 0x5A, 0x7A, 0x41, 0x7F, 0x0E, 0x00, 0x63, 0xF2, 0x4F, 0x05, 0x83, 0xC9, 0xA1, 0xD4, 0xDD, 0xC4, 0x56, 0xF4, 0xD2, 0x77, 0x81, 0x09, 0x82, 0x33, 0x9F, 0x07, 0x86, 0x75, 0x38, 0x4E, 0x69, 0xF1, 0xAD, 0x23, 0x73, 0x87, 0x70, 0x02, 0xC2, 0x1E, 0xB8, 0x0A, 0xFC, 0xE6 ]; /** * Default Constructor. * * @param string $mode * @throws \InvalidArgumentException if an invalid / unsupported mode is provided */ public function __construct($mode) { parent::__construct($mode); if ($this->mode == self::MODE_STREAM) { throw new BadModeException('Block ciphers cannot be ran in stream mode'); } } /** * Test for engine validity * * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() * * @see Common\SymmetricKey::__construct() * @param int $engine * @return bool */ protected function isValidEngineHelper($engine) { switch ($engine) { case self::ENGINE_OPENSSL: if ($this->current_key_length != 128 || strlen($this->orig_key) < 16) { return false; } // quoting https://www.openssl.org/news/openssl-3.0-notes.html, OpenSSL 3.0.1 // "Moved all variations of the EVP ciphers CAST5, BF, IDEA, SEED, RC2, RC4, RC5, and DES to the legacy provider" // in theory openssl_get_cipher_methods() should catch this but, on GitHub Actions, at least, it does not if (defined('OPENSSL_VERSION_TEXT') && version_compare(preg_replace('#OpenSSL (\d+\.\d+\.\d+) .*#', '$1', OPENSSL_VERSION_TEXT), '3.0.1', '>=')) { return false; } $this->cipher_name_openssl_ecb = 'rc2-ecb'; $this->cipher_name_openssl = 'rc2-' . $this->openssl_translate_mode(); } return parent::isValidEngineHelper($engine); } /** * Sets the key length. * * Valid key lengths are 8 to 1024. * Calling this function after setting the key has no effect until the next * \phpseclib3\Crypt\RC2::setKey() call. * * @param int $length in bits * @throws \LengthException if the key length isn't supported */ public function setKeyLength($length) { if ($length < 8 || $length > 1024) { throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys between 1 and 1024 bits, inclusive, are supported'); } $this->default_key_length = $this->current_key_length = $length; $this->explicit_key_length = $length >> 3; } /** * Returns the current key length * * @return int */ public function getKeyLength() { return $this->current_key_length; } /** * Sets the key. * * Keys can be of any length. RC2, itself, uses 8 to 1024 bit keys (eg. * strlen($key) <= 128), however, we only use the first 128 bytes if $key * has more then 128 bytes in it, and set $key to a single null byte if * it is empty. * * @see Common\SymmetricKey::setKey() * @param string $key * @param int|boolean $t1 optional Effective key length in bits. * @throws \LengthException if the key length isn't supported */ public function setKey($key, $t1 = false) { $this->orig_key = $key; if ($t1 === false) { $t1 = $this->default_key_length; } if ($t1 < 1 || $t1 > 1024) { throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys between 1 and 1024 bits, inclusive, are supported'); } $this->current_key_length = $t1; if (strlen($key) < 1 || strlen($key) > 128) { throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes between 8 and 1024 bits, inclusive, are supported'); } $t = strlen($key); // The mcrypt RC2 implementation only supports effective key length // of 1024 bits. It is however possible to handle effective key // lengths in range 1..1024 by expanding the key and applying // inverse pitable mapping to the first byte before submitting it // to mcrypt. // Key expansion. $l = array_values(unpack('C*', $key)); $t8 = ($t1 + 7) >> 3; $tm = 0xFF >> (8 * $t8 - $t1); // Expand key. $pitable = self::$pitable; for ($i = $t; $i < 128; $i++) { $l[$i] = $pitable[$l[$i - 1] + $l[$i - $t]]; } $i = 128 - $t8; $l[$i] = $pitable[$l[$i] & $tm]; while ($i--) { $l[$i] = $pitable[$l[$i + 1] ^ $l[$i + $t8]]; } // Prepare the key for mcrypt. $l[0] = self::$invpitable[$l[0]]; array_unshift($l, 'C*'); $this->key = pack(...$l); $this->key_length = strlen($this->key); $this->changed = $this->nonIVChanged = true; $this->setEngine(); } /** * Encrypts a message. * * Mostly a wrapper for \phpseclib3\Crypt\Common\SymmetricKey::encrypt, with some additional OpenSSL handling code * * @see self::decrypt() * @param string $plaintext * @return string $ciphertext */ public function encrypt($plaintext) { if ($this->engine == self::ENGINE_OPENSSL) { $temp = $this->key; $this->key = $this->orig_key; $result = parent::encrypt($plaintext); $this->key = $temp; return $result; } return parent::encrypt($plaintext); } /** * Decrypts a message. * * Mostly a wrapper for \phpseclib3\Crypt\Common\SymmetricKey::decrypt, with some additional OpenSSL handling code * * @see self::encrypt() * @param string $ciphertext * @return string $plaintext */ public function decrypt($ciphertext) { if ($this->engine == self::ENGINE_OPENSSL) { $temp = $this->key; $this->key = $this->orig_key; $result = parent::decrypt($ciphertext); $this->key = $temp; return $result; } return parent::decrypt($ciphertext); } /** * Encrypts a block * * @see Common\SymmetricKey::encryptBlock() * @see Common\SymmetricKey::encrypt() * @param string $in * @return string */ protected function encryptBlock($in) { list($r0, $r1, $r2, $r3) = array_values(unpack('v*', $in)); $keys = $this->keys; $limit = 20; $actions = [$limit => 44, 44 => 64]; $j = 0; for (;;) { // Mixing round. $r0 = (($r0 + $keys[$j++] + ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF) << 1; $r0 |= $r0 >> 16; $r1 = (($r1 + $keys[$j++] + ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF) << 2; $r1 |= $r1 >> 16; $r2 = (($r2 + $keys[$j++] + ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF) << 3; $r2 |= $r2 >> 16; $r3 = (($r3 + $keys[$j++] + ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF) << 5; $r3 |= $r3 >> 16; if ($j === $limit) { if ($limit === 64) { break; } // Mashing round. $r0 += $keys[$r3 & 0x3F]; $r1 += $keys[$r0 & 0x3F]; $r2 += $keys[$r1 & 0x3F]; $r3 += $keys[$r2 & 0x3F]; $limit = $actions[$limit]; } } return pack('vvvv', $r0, $r1, $r2, $r3); } /** * Decrypts a block * * @see Common\SymmetricKey::decryptBlock() * @see Common\SymmetricKey::decrypt() * @param string $in * @return string */ protected function decryptBlock($in) { list($r0, $r1, $r2, $r3) = array_values(unpack('v*', $in)); $keys = $this->keys; $limit = 44; $actions = [$limit => 20, 20 => 0]; $j = 64; for (;;) { // R-mixing round. $r3 = ($r3 | ($r3 << 16)) >> 5; $r3 = ($r3 - $keys[--$j] - ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF; $r2 = ($r2 | ($r2 << 16)) >> 3; $r2 = ($r2 - $keys[--$j] - ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF; $r1 = ($r1 | ($r1 << 16)) >> 2; $r1 = ($r1 - $keys[--$j] - ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF; $r0 = ($r0 | ($r0 << 16)) >> 1; $r0 = ($r0 - $keys[--$j] - ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF; if ($j === $limit) { if ($limit === 0) { break; } // R-mashing round. $r3 = ($r3 - $keys[$r2 & 0x3F]) & 0xFFFF; $r2 = ($r2 - $keys[$r1 & 0x3F]) & 0xFFFF; $r1 = ($r1 - $keys[$r0 & 0x3F]) & 0xFFFF; $r0 = ($r0 - $keys[$r3 & 0x3F]) & 0xFFFF; $limit = $actions[$limit]; } } return pack('vvvv', $r0, $r1, $r2, $r3); } /** * Creates the key schedule * * @see Common\SymmetricKey::setupKey() */ protected function setupKey() { if (!isset($this->key)) { $this->setKey(''); } // Key has already been expanded in \phpseclib3\Crypt\RC2::setKey(): // Only the first value must be altered. $l = unpack('Ca/Cb/v*', $this->key); array_unshift($l, self::$pitable[$l['a']] | ($l['b'] << 8)); unset($l['a']); unset($l['b']); $this->keys = $l; } /** * Setup the performance-optimized function for de/encrypt() * * @see Common\SymmetricKey::setupInlineCrypt() */ protected function setupInlineCrypt() { // Init code for both, encrypt and decrypt. $init_crypt = '$keys = $this->keys;'; $keys = $this->keys; // $in is the current 8 bytes block which has to be en/decrypt $encrypt_block = $decrypt_block = ' $in = unpack("v4", $in); $r0 = $in[1]; $r1 = $in[2]; $r2 = $in[3]; $r3 = $in[4]; '; // Create code for encryption. $limit = 20; $actions = [$limit => 44, 44 => 64]; $j = 0; for (;;) { // Mixing round. $encrypt_block .= ' $r0 = (($r0 + ' . $keys[$j++] . ' + ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF) << 1; $r0 |= $r0 >> 16; $r1 = (($r1 + ' . $keys[$j++] . ' + ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF) << 2; $r1 |= $r1 >> 16; $r2 = (($r2 + ' . $keys[$j++] . ' + ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF) << 3; $r2 |= $r2 >> 16; $r3 = (($r3 + ' . $keys[$j++] . ' + ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF) << 5; $r3 |= $r3 >> 16;'; if ($j === $limit) { if ($limit === 64) { break; } // Mashing round. $encrypt_block .= ' $r0 += $keys[$r3 & 0x3F]; $r1 += $keys[$r0 & 0x3F]; $r2 += $keys[$r1 & 0x3F]; $r3 += $keys[$r2 & 0x3F];'; $limit = $actions[$limit]; } } $encrypt_block .= '$in = pack("v4", $r0, $r1, $r2, $r3);'; // Create code for decryption. $limit = 44; $actions = [$limit => 20, 20 => 0]; $j = 64; for (;;) { // R-mixing round. $decrypt_block .= ' $r3 = ($r3 | ($r3 << 16)) >> 5; $r3 = ($r3 - ' . $keys[--$j] . ' - ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF; $r2 = ($r2 | ($r2 << 16)) >> 3; $r2 = ($r2 - ' . $keys[--$j] . ' - ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF; $r1 = ($r1 | ($r1 << 16)) >> 2; $r1 = ($r1 - ' . $keys[--$j] . ' - ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF; $r0 = ($r0 | ($r0 << 16)) >> 1; $r0 = ($r0 - ' . $keys[--$j] . ' - ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF;'; if ($j === $limit) { if ($limit === 0) { break; } // R-mashing round. $decrypt_block .= ' $r3 = ($r3 - $keys[$r2 & 0x3F]) & 0xFFFF; $r2 = ($r2 - $keys[$r1 & 0x3F]) & 0xFFFF; $r1 = ($r1 - $keys[$r0 & 0x3F]) & 0xFFFF; $r0 = ($r0 - $keys[$r3 & 0x3F]) & 0xFFFF;'; $limit = $actions[$limit]; } } $decrypt_block .= '$in = pack("v4", $r0, $r1, $r2, $r3);'; // Creates the inline-crypt function $this->inline_crypt = $this->createInlineCryptFunction( [ 'init_crypt' => $init_crypt, 'encrypt_block' => $encrypt_block, 'decrypt_block' => $decrypt_block ] ); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php ================================================ * setKey('abcdefgh'); * * $size = 10 * 1024; * $plaintext = ''; * for ($i = 0; $i < $size; $i++) { * $plaintext.= 'a'; * } * * echo $rc4->decrypt($rc4->encrypt($plaintext)); * ?> * * * @author Jim Wigginton * @copyright 2007 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt; use phpseclib3\Crypt\Common\StreamCipher; /** * Pure-PHP implementation of RC4. * * @author Jim Wigginton */ class RC4 extends StreamCipher { /** * @see \phpseclib3\Crypt\RC4::_crypt() */ const ENCRYPT = 0; /** * @see \phpseclib3\Crypt\RC4::_crypt() */ const DECRYPT = 1; /** * Key Length (in bytes) * * @see \phpseclib3\Crypt\RC4::setKeyLength() * @var int */ protected $key_length = 128; // = 1024 bits /** * The mcrypt specific name of the cipher * * @see Common\SymmetricKey::cipher_name_mcrypt * @var string */ protected $cipher_name_mcrypt = 'arcfour'; /** * The Key * * @see self::setKey() * @var string */ protected $key; /** * The Key Stream for decryption and encryption * * @see self::setKey() * @var array */ private $stream; /** * Test for engine validity * * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() * * @see Common\SymmetricKey::__construct() * @param int $engine * @return bool */ protected function isValidEngineHelper($engine) { if ($engine == self::ENGINE_OPENSSL) { if ($this->continuousBuffer) { return false; } // quoting https://www.openssl.org/news/openssl-3.0-notes.html, OpenSSL 3.0.1 // "Moved all variations of the EVP ciphers CAST5, BF, IDEA, SEED, RC2, RC4, RC5, and DES to the legacy provider" // in theory openssl_get_cipher_methods() should catch this but, on GitHub Actions, at least, it does not if (defined('OPENSSL_VERSION_TEXT') && version_compare(preg_replace('#OpenSSL (\d+\.\d+\.\d+) .*#', '$1', OPENSSL_VERSION_TEXT), '3.0.1', '>=')) { return false; } $this->cipher_name_openssl = 'rc4-40'; } return parent::isValidEngineHelper($engine); } /** * Sets the key length * * Keys can be between 1 and 256 bytes long. * * @param int $length * @throws \LengthException if the key length is invalid */ public function setKeyLength($length) { if ($length < 8 || $length > 2048) { throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys between 1 and 256 bytes are supported'); } $this->key_length = $length >> 3; parent::setKeyLength($length); } /** * Sets the key length * * Keys can be between 1 and 256 bytes long. * * @param string $key */ public function setKey($key) { $length = strlen($key); if ($length < 1 || $length > 256) { throw new \LengthException('Key size of ' . $length . ' bytes is not supported by RC4. Keys must be between 1 and 256 bytes long'); } parent::setKey($key); } /** * Encrypts a message. * * @see Common\SymmetricKey::decrypt() * @see self::crypt() * @param string $plaintext * @return string $ciphertext */ public function encrypt($plaintext) { if ($this->engine != self::ENGINE_INTERNAL) { return parent::encrypt($plaintext); } return $this->crypt($plaintext, self::ENCRYPT); } /** * Decrypts a message. * * $this->decrypt($this->encrypt($plaintext)) == $this->encrypt($this->encrypt($plaintext)). * At least if the continuous buffer is disabled. * * @see Common\SymmetricKey::encrypt() * @see self::crypt() * @param string $ciphertext * @return string $plaintext */ public function decrypt($ciphertext) { if ($this->engine != self::ENGINE_INTERNAL) { return parent::decrypt($ciphertext); } return $this->crypt($ciphertext, self::DECRYPT); } /** * Encrypts a block * * @param string $in */ protected function encryptBlock($in) { // RC4 does not utilize this method } /** * Decrypts a block * * @param string $in */ protected function decryptBlock($in) { // RC4 does not utilize this method } /** * Setup the key (expansion) * * @see Common\SymmetricKey::_setupKey() */ protected function setupKey() { $key = $this->key; $keyLength = strlen($key); $keyStream = range(0, 255); $j = 0; for ($i = 0; $i < 256; $i++) { $j = ($j + $keyStream[$i] + ord($key[$i % $keyLength])) & 255; $temp = $keyStream[$i]; $keyStream[$i] = $keyStream[$j]; $keyStream[$j] = $temp; } $this->stream = []; $this->stream[self::DECRYPT] = $this->stream[self::ENCRYPT] = [ 0, // index $i 0, // index $j $keyStream ]; } /** * Encrypts or decrypts a message. * * @see self::encrypt() * @see self::decrypt() * @param string $text * @param int $mode * @return string $text */ private function crypt($text, $mode) { if ($this->changed) { $this->setup(); } $stream = &$this->stream[$mode]; if ($this->continuousBuffer) { $i = &$stream[0]; $j = &$stream[1]; $keyStream = &$stream[2]; } else { $i = $stream[0]; $j = $stream[1]; $keyStream = $stream[2]; } $len = strlen($text); for ($k = 0; $k < $len; ++$k) { $i = ($i + 1) & 255; $ksi = $keyStream[$i]; $j = ($j + $ksi) & 255; $ksj = $keyStream[$j]; $keyStream[$i] = $ksj; $keyStream[$j] = $ksi; $text[$k] = $text[$k] ^ chr($keyStream[($ksj + $ksi) & 255]); } return $text; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/JWK.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\RSA\Formats\Keys; use phpseclib3\Common\Functions\Strings; use phpseclib3\Crypt\Common\Formats\Keys\JWK as Progenitor; use phpseclib3\Math\BigInteger; /** * JWK Formatted RSA Handler * * @author Jim Wigginton */ abstract class JWK extends Progenitor { /** * Break a public or private key down into its constituent components * * @param string $key * @param string $password optional * @return array */ public static function load($key, $password = '') { $key = parent::load($key, $password); if ($key->kty != 'RSA') { throw new \RuntimeException('Only RSA JWK keys are supported'); } $count = $publicCount = 0; $vars = ['n', 'e', 'd', 'p', 'q', 'dp', 'dq', 'qi']; foreach ($vars as $var) { if (!isset($key->$var) || !is_string($key->$var)) { continue; } $count++; $value = new BigInteger(Strings::base64url_decode($key->$var), 256); switch ($var) { case 'n': $publicCount++; $components['modulus'] = $value; break; case 'e': $publicCount++; $components['publicExponent'] = $value; break; case 'd': $components['privateExponent'] = $value; break; case 'p': $components['primes'][1] = $value; break; case 'q': $components['primes'][2] = $value; break; case 'dp': $components['exponents'][1] = $value; break; case 'dq': $components['exponents'][2] = $value; break; case 'qi': $components['coefficients'][2] = $value; } } if ($count == count($vars)) { return $components + ['isPublicKey' => false]; } if ($count == 2 && $publicCount == 2) { return $components + ['isPublicKey' => true]; } throw new \UnexpectedValueException('Key does not have an appropriate number of RSA parameters'); } /** * Convert a private key to the appropriate format. * * @param BigInteger $n * @param BigInteger $e * @param BigInteger $d * @param array $primes * @param array $exponents * @param array $coefficients * @param string $password optional * @param array $options optional * @return string */ public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) { if (count($primes) != 2) { throw new \InvalidArgumentException('JWK does not support multi-prime RSA keys'); } $key = [ 'kty' => 'RSA', 'n' => Strings::base64url_encode($n->toBytes()), 'e' => Strings::base64url_encode($e->toBytes()), 'd' => Strings::base64url_encode($d->toBytes()), 'p' => Strings::base64url_encode($primes[1]->toBytes()), 'q' => Strings::base64url_encode($primes[2]->toBytes()), 'dp' => Strings::base64url_encode($exponents[1]->toBytes()), 'dq' => Strings::base64url_encode($exponents[2]->toBytes()), 'qi' => Strings::base64url_encode($coefficients[2]->toBytes()) ]; return self::wrapKey($key, $options); } /** * Convert a public key to the appropriate format * * @param BigInteger $n * @param BigInteger $e * @param array $options optional * @return string */ public static function savePublicKey(BigInteger $n, BigInteger $e, array $options = []) { $key = [ 'kty' => 'RSA', 'n' => Strings::base64url_encode($n->toBytes()), 'e' => Strings::base64url_encode($e->toBytes()) ]; return self::wrapKey($key, $options); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/MSBLOB.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\RSA\Formats\Keys; use phpseclib3\Common\Functions\Strings; use phpseclib3\Exception\UnsupportedFormatException; use phpseclib3\Math\BigInteger; /** * Microsoft BLOB Formatted RSA Key Handler * * @author Jim Wigginton */ abstract class MSBLOB { /** * Public/Private Key Pair * */ const PRIVATEKEYBLOB = 0x7; /** * Public Key * */ const PUBLICKEYBLOB = 0x6; /** * Public Key * */ const PUBLICKEYBLOBEX = 0xA; /** * RSA public key exchange algorithm * */ const CALG_RSA_KEYX = 0x0000A400; /** * RSA public key exchange algorithm * */ const CALG_RSA_SIGN = 0x00002400; /** * Public Key * */ const RSA1 = 0x31415352; /** * Private Key * */ const RSA2 = 0x32415352; /** * Break a public or private key down into its constituent components * * @param string $key * @param string $password optional * @return array */ public static function load($key, $password = '') { if (!Strings::is_stringable($key)) { throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); } $key = Strings::base64_decode($key); if (!is_string($key)) { throw new \UnexpectedValueException('Base64 decoding produced an error'); } if (strlen($key) < 20) { throw new \UnexpectedValueException('Key appears to be malformed'); } // PUBLICKEYSTRUC publickeystruc // https://msdn.microsoft.com/en-us/library/windows/desktop/aa387453(v=vs.85).aspx $unpacked = unpack('atype/aversion/vreserved/Valgo', Strings::shift($key, 8)); $type = $unpacked['type']; $version = $unpacked['version']; $reserved = $unpacked['reserved']; $algo = $unpacked['algo']; switch (ord($type)) { case self::PUBLICKEYBLOB: case self::PUBLICKEYBLOBEX: $publickey = true; break; case self::PRIVATEKEYBLOB: $publickey = false; break; default: throw new \UnexpectedValueException('Key appears to be malformed'); } $components = ['isPublicKey' => $publickey]; // https://msdn.microsoft.com/en-us/library/windows/desktop/aa375549(v=vs.85).aspx switch ($algo) { case self::CALG_RSA_KEYX: case self::CALG_RSA_SIGN: break; default: throw new \UnexpectedValueException('Key appears to be malformed'); } // RSAPUBKEY rsapubkey // https://msdn.microsoft.com/en-us/library/windows/desktop/aa387685(v=vs.85).aspx // could do V for pubexp but that's unsigned 32-bit whereas some PHP installs only do signed 32-bit $unpacked = unpack('Vmagic/Vbitlen/a4pubexp', Strings::shift($key, 12)); $magic = $unpacked['magic']; $bitlen = $unpacked['bitlen']; $pubexp = $unpacked['pubexp']; switch ($magic) { case self::RSA2: $components['isPublicKey'] = false; // fall-through case self::RSA1: break; default: throw new \UnexpectedValueException('Key appears to be malformed'); } $baseLength = $bitlen / 16; if (strlen($key) != 2 * $baseLength && strlen($key) != 9 * $baseLength) { throw new \UnexpectedValueException('Key appears to be malformed'); } $components[$components['isPublicKey'] ? 'publicExponent' : 'privateExponent'] = new BigInteger(strrev($pubexp), 256); // BYTE modulus[rsapubkey.bitlen/8] $components['modulus'] = new BigInteger(strrev(Strings::shift($key, $bitlen / 8)), 256); if ($publickey) { return $components; } $components['isPublicKey'] = false; // BYTE prime1[rsapubkey.bitlen/16] $components['primes'] = [1 => new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256)]; // BYTE prime2[rsapubkey.bitlen/16] $components['primes'][] = new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256); // BYTE exponent1[rsapubkey.bitlen/16] $components['exponents'] = [1 => new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256)]; // BYTE exponent2[rsapubkey.bitlen/16] $components['exponents'][] = new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256); // BYTE coefficient[rsapubkey.bitlen/16] $components['coefficients'] = [2 => new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256)]; if (isset($components['privateExponent'])) { $components['publicExponent'] = $components['privateExponent']; } // BYTE privateExponent[rsapubkey.bitlen/8] $components['privateExponent'] = new BigInteger(strrev(Strings::shift($key, $bitlen / 8)), 256); return $components; } /** * Convert a private key to the appropriate format. * * @param BigInteger $n * @param BigInteger $e * @param BigInteger $d * @param array $primes * @param array $exponents * @param array $coefficients * @param string $password optional * @return string */ public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '') { if (count($primes) != 2) { throw new \InvalidArgumentException('MSBLOB does not support multi-prime RSA keys'); } if (!empty($password) && is_string($password)) { throw new UnsupportedFormatException('MSBLOB private keys do not support encryption'); } $n = strrev($n->toBytes()); $e = str_pad(strrev($e->toBytes()), 4, "\0"); $key = pack('aavV', chr(self::PRIVATEKEYBLOB), chr(2), 0, self::CALG_RSA_KEYX); $key .= pack('VVa*', self::RSA2, 8 * strlen($n), $e); $key .= $n; $key .= strrev($primes[1]->toBytes()); $key .= strrev($primes[2]->toBytes()); $key .= strrev($exponents[1]->toBytes()); $key .= strrev($exponents[2]->toBytes()); $key .= strrev($coefficients[2]->toBytes()); $key .= strrev($d->toBytes()); return Strings::base64_encode($key); } /** * Convert a public key to the appropriate format * * @param BigInteger $n * @param BigInteger $e * @return string */ public static function savePublicKey(BigInteger $n, BigInteger $e) { $n = strrev($n->toBytes()); $e = str_pad(strrev($e->toBytes()), 4, "\0"); $key = pack('aavV', chr(self::PUBLICKEYBLOB), chr(2), 0, self::CALG_RSA_KEYX); $key .= pack('VVa*', self::RSA1, 8 * strlen($n), $e); $key .= $n; return Strings::base64_encode($key); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/OpenSSH.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\RSA\Formats\Keys; use phpseclib3\Common\Functions\Strings; use phpseclib3\Crypt\Common\Formats\Keys\OpenSSH as Progenitor; use phpseclib3\Math\BigInteger; /** * OpenSSH Formatted RSA Key Handler * * @author Jim Wigginton */ abstract class OpenSSH extends Progenitor { /** * Supported Key Types * * @var array */ protected static $types = ['ssh-rsa']; /** * Break a public or private key down into its constituent components * * @param string $key * @param string $password optional * @return array */ public static function load($key, $password = '') { static $one; if (!isset($one)) { $one = new BigInteger(1); } $parsed = parent::load($key, $password); if (isset($parsed['paddedKey'])) { list($type) = Strings::unpackSSH2('s', $parsed['paddedKey']); if ($type != $parsed['type']) { throw new \RuntimeException("The public and private keys are not of the same type ($type vs $parsed[type])"); } $primes = $coefficients = []; list( $modulus, $publicExponent, $privateExponent, $coefficients[2], $primes[1], $primes[2], $comment, ) = Strings::unpackSSH2('i6s', $parsed['paddedKey']); $temp = $primes[1]->subtract($one); $exponents = [1 => $publicExponent->modInverse($temp)]; $temp = $primes[2]->subtract($one); $exponents[] = $publicExponent->modInverse($temp); $isPublicKey = false; return compact('publicExponent', 'modulus', 'privateExponent', 'primes', 'coefficients', 'exponents', 'comment', 'isPublicKey'); } list($publicExponent, $modulus) = Strings::unpackSSH2('ii', $parsed['publicKey']); return [ 'isPublicKey' => true, 'modulus' => $modulus, 'publicExponent' => $publicExponent, 'comment' => $parsed['comment'] ]; } /** * Convert a public key to the appropriate format * * @param BigInteger $n * @param BigInteger $e * @param array $options optional * @return string */ public static function savePublicKey(BigInteger $n, BigInteger $e, array $options = []) { $RSAPublicKey = Strings::packSSH2('sii', 'ssh-rsa', $e, $n); if (isset($options['binary']) ? $options['binary'] : self::$binary) { return $RSAPublicKey; } $comment = isset($options['comment']) ? $options['comment'] : self::$comment; $RSAPublicKey = 'ssh-rsa ' . base64_encode($RSAPublicKey) . ' ' . $comment; return $RSAPublicKey; } /** * Convert a private key to the appropriate format. * * @param BigInteger $n * @param BigInteger $e * @param BigInteger $d * @param array $primes * @param array $exponents * @param array $coefficients * @param string $password optional * @param array $options optional * @return string */ public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) { $publicKey = self::savePublicKey($n, $e, ['binary' => true]); $privateKey = Strings::packSSH2('si6', 'ssh-rsa', $n, $e, $d, $coefficients[2], $primes[1], $primes[2]); return self::wrapPrivateKey($publicKey, $privateKey, $password, $options); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS1.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\RSA\Formats\Keys; use phpseclib3\Common\Functions\Strings; use phpseclib3\Crypt\Common\Formats\Keys\PKCS1 as Progenitor; use phpseclib3\File\ASN1; use phpseclib3\File\ASN1\Maps; use phpseclib3\Math\BigInteger; /** * PKCS#1 Formatted RSA Key Handler * * @author Jim Wigginton */ abstract class PKCS1 extends Progenitor { /** * Break a public or private key down into its constituent components * * @param string $key * @param string $password optional * @return array */ public static function load($key, $password = '') { if (!Strings::is_stringable($key)) { throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); } if (strpos($key, 'PUBLIC') !== false) { $components = ['isPublicKey' => true]; } elseif (strpos($key, 'PRIVATE') !== false) { $components = ['isPublicKey' => false]; } else { $components = []; } $key = parent::load($key, $password); $decoded = ASN1::decodeBER($key); if (!$decoded) { throw new \RuntimeException('Unable to decode BER'); } $key = ASN1::asn1map($decoded[0], Maps\RSAPrivateKey::MAP); if (is_array($key)) { $components += [ 'modulus' => $key['modulus'], 'publicExponent' => $key['publicExponent'], 'privateExponent' => $key['privateExponent'], 'primes' => [1 => $key['prime1'], $key['prime2']], 'exponents' => [1 => $key['exponent1'], $key['exponent2']], 'coefficients' => [2 => $key['coefficient']] ]; if ($key['version'] == 'multi') { foreach ($key['otherPrimeInfos'] as $primeInfo) { $components['primes'][] = $primeInfo['prime']; $components['exponents'][] = $primeInfo['exponent']; $components['coefficients'][] = $primeInfo['coefficient']; } } if (!isset($components['isPublicKey'])) { $components['isPublicKey'] = false; } return $components; } $key = ASN1::asn1map($decoded[0], Maps\RSAPublicKey::MAP); if (!is_array($key)) { throw new \RuntimeException('Unable to perform ASN1 mapping'); } if (!isset($components['isPublicKey'])) { $components['isPublicKey'] = true; } $components = $components + $key; foreach ($components as &$val) { if ($val instanceof BigInteger) { $val = self::makePositive($val); } if (is_array($val)) { foreach ($val as &$subval) { if ($subval instanceof BigInteger) { $subval = self::makePositive($subval); } } } } return $components + $key; } /** * Convert a private key to the appropriate format. * * @param BigInteger $n * @param BigInteger $e * @param BigInteger $d * @param array $primes * @param array $exponents * @param array $coefficients * @param string $password optional * @param array $options optional * @return string */ public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) { $num_primes = count($primes); $key = [ 'version' => $num_primes == 2 ? 'two-prime' : 'multi', 'modulus' => $n, 'publicExponent' => $e, 'privateExponent' => $d, 'prime1' => $primes[1], 'prime2' => $primes[2], 'exponent1' => $exponents[1], 'exponent2' => $exponents[2], 'coefficient' => $coefficients[2] ]; for ($i = 3; $i <= $num_primes; $i++) { $key['otherPrimeInfos'][] = [ 'prime' => $primes[$i], 'exponent' => $exponents[$i], 'coefficient' => $coefficients[$i] ]; } $key = ASN1::encodeDER($key, Maps\RSAPrivateKey::MAP); return self::wrapPrivateKey($key, 'RSA', $password, $options); } /** * Convert a public key to the appropriate format * * @param BigInteger $n * @param BigInteger $e * @return string */ public static function savePublicKey(BigInteger $n, BigInteger $e) { $key = [ 'modulus' => $n, 'publicExponent' => $e ]; $key = ASN1::encodeDER($key, Maps\RSAPublicKey::MAP); return self::wrapPublicKey($key, 'RSA'); } /** * Negative numbers make no sense in RSA so convert them to positive * * @param BigInteger $x * @return string */ private static function makePositive(BigInteger $x) { return $x->isNegative() ? new BigInteger($x->toBytes(true), 256) : $x; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\RSA\Formats\Keys; use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; use phpseclib3\File\ASN1; use phpseclib3\Math\BigInteger; /** * PKCS#8 Formatted RSA Key Handler * * @author Jim Wigginton */ abstract class PKCS8 extends Progenitor { /** * OID Name * * @var string */ const OID_NAME = 'rsaEncryption'; /** * OID Value * * @var string */ const OID_VALUE = '1.2.840.113549.1.1.1'; /** * Child OIDs loaded * * @var bool */ protected static $childOIDsLoaded = false; /** * Break a public or private key down into its constituent components * * @param string $key * @param string $password optional * @return array */ public static function load($key, $password = '') { $key = parent::load($key, $password); if (isset($key['privateKey'])) { $components['isPublicKey'] = false; $type = 'private'; } else { $components['isPublicKey'] = true; $type = 'public'; } $result = $components + PKCS1::load($key[$type . 'Key']); if (isset($key['meta'])) { $result['meta'] = $key['meta']; } return $result; } /** * Convert a private key to the appropriate format. * * @param BigInteger $n * @param BigInteger $e * @param BigInteger $d * @param array $primes * @param array $exponents * @param array $coefficients * @param string $password optional * @param array $options optional * @return string */ public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) { $key = PKCS1::savePrivateKey($n, $e, $d, $primes, $exponents, $coefficients); $key = ASN1::extractBER($key); return self::wrapPrivateKey($key, [], null, $password, null, '', $options); } /** * Convert a public key to the appropriate format * * @param BigInteger $n * @param BigInteger $e * @param array $options optional * @return string */ public static function savePublicKey(BigInteger $n, BigInteger $e, array $options = []) { $key = PKCS1::savePublicKey($n, $e); $key = ASN1::extractBER($key); return self::wrapPublicKey($key, null, null, $options); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PSS.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\RSA\Formats\Keys; use phpseclib3\Common\Functions\Strings; use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; use phpseclib3\File\ASN1; use phpseclib3\File\ASN1\Maps; use phpseclib3\Math\BigInteger; /** * PKCS#8 Formatted RSA-PSS Key Handler * * @author Jim Wigginton */ abstract class PSS extends Progenitor { /** * OID Name * * @var string */ const OID_NAME = 'id-RSASSA-PSS'; /** * OID Value * * @var string */ const OID_VALUE = '1.2.840.113549.1.1.10'; /** * OIDs loaded * * @var bool */ private static $oidsLoaded = false; /** * Child OIDs loaded * * @var bool */ protected static $childOIDsLoaded = false; /** * Initialize static variables */ private static function initialize_static_variables() { if (!self::$oidsLoaded) { ASN1::loadOIDs([ 'md2' => '1.2.840.113549.2.2', 'md4' => '1.2.840.113549.2.4', 'md5' => '1.2.840.113549.2.5', 'id-sha1' => '1.3.14.3.2.26', 'id-sha256' => '2.16.840.1.101.3.4.2.1', 'id-sha384' => '2.16.840.1.101.3.4.2.2', 'id-sha512' => '2.16.840.1.101.3.4.2.3', 'id-sha224' => '2.16.840.1.101.3.4.2.4', 'id-sha512/224' => '2.16.840.1.101.3.4.2.5', 'id-sha512/256' => '2.16.840.1.101.3.4.2.6', 'id-mgf1' => '1.2.840.113549.1.1.8' ]); self::$oidsLoaded = true; } } /** * Break a public or private key down into its constituent components * * @param string $key * @param string $password optional * @return array */ public static function load($key, $password = '') { self::initialize_static_variables(); if (!Strings::is_stringable($key)) { throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); } $components = ['isPublicKey' => strpos($key, 'PUBLIC') !== false]; $key = parent::load($key, $password); $type = isset($key['privateKey']) ? 'private' : 'public'; $result = $components + PKCS1::load($key[$type . 'Key']); if (isset($key[$type . 'KeyAlgorithm']['parameters'])) { $decoded = ASN1::decodeBER($key[$type . 'KeyAlgorithm']['parameters']); if ($decoded === false) { throw new \UnexpectedValueException('Unable to decode parameters'); } $params = ASN1::asn1map($decoded[0], Maps\RSASSA_PSS_params::MAP); } else { $params = []; } if (isset($params['maskGenAlgorithm']['parameters'])) { $decoded = ASN1::decodeBER($params['maskGenAlgorithm']['parameters']); if ($decoded === false) { throw new \UnexpectedValueException('Unable to decode parameters'); } $params['maskGenAlgorithm']['parameters'] = ASN1::asn1map($decoded[0], Maps\HashAlgorithm::MAP); } else { $params['maskGenAlgorithm'] = [ 'algorithm' => 'id-mgf1', 'parameters' => ['algorithm' => 'id-sha1'] ]; } if (!isset($params['hashAlgorithm']['algorithm'])) { $params['hashAlgorithm']['algorithm'] = 'id-sha1'; } $result['hash'] = str_replace('id-', '', $params['hashAlgorithm']['algorithm']); $result['MGFHash'] = str_replace('id-', '', $params['maskGenAlgorithm']['parameters']['algorithm']); if (isset($params['saltLength'])) { $result['saltLength'] = (int) "$params[saltLength]"; } if (isset($key['meta'])) { $result['meta'] = $key['meta']; } return $result; } /** * Convert a private key to the appropriate format. * * @param BigInteger $n * @param BigInteger $e * @param BigInteger $d * @param array $primes * @param array $exponents * @param array $coefficients * @param string $password optional * @param array $options optional * @return string */ public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) { self::initialize_static_variables(); $key = PKCS1::savePrivateKey($n, $e, $d, $primes, $exponents, $coefficients); $key = ASN1::extractBER($key); $params = self::savePSSParams($options); return self::wrapPrivateKey($key, [], $params, $password, null, '', $options); } /** * Convert a public key to the appropriate format * * @param BigInteger $n * @param BigInteger $e * @param array $options optional * @return string */ public static function savePublicKey(BigInteger $n, BigInteger $e, array $options = []) { self::initialize_static_variables(); $key = PKCS1::savePublicKey($n, $e); $key = ASN1::extractBER($key); $params = self::savePSSParams($options); return self::wrapPublicKey($key, $params); } /** * Encodes PSS parameters * * @param array $options * @return string */ public static function savePSSParams(array $options) { /* The trailerField field is an integer. It provides compatibility with IEEE Std 1363a-2004 [P1363A]. The value MUST be 1, which represents the trailer field with hexadecimal value 0xBC. Other trailer fields, including the trailer field composed of HashID concatenated with 0xCC that is specified in IEEE Std 1363a, are not supported. Implementations that perform signature generation MUST omit the trailerField field, indicating that the default trailer field value was used. Implementations that perform signature validation MUST recognize both a present trailerField field with value 1 and an absent trailerField field. source: https://tools.ietf.org/html/rfc4055#page-9 */ $params = [ 'trailerField' => new BigInteger(1) ]; if (isset($options['hash'])) { $params['hashAlgorithm']['algorithm'] = 'id-' . $options['hash']; } if (isset($options['MGFHash'])) { $temp = ['algorithm' => 'id-' . $options['MGFHash']]; $temp = ASN1::encodeDER($temp, Maps\HashAlgorithm::MAP); $params['maskGenAlgorithm'] = [ 'algorithm' => 'id-mgf1', 'parameters' => new ASN1\Element($temp) ]; } if (isset($options['saltLength'])) { $params['saltLength'] = new BigInteger($options['saltLength']); } return new ASN1\Element(ASN1::encodeDER($params, Maps\RSASSA_PSS_params::MAP)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PuTTY.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\RSA\Formats\Keys; use phpseclib3\Common\Functions\Strings; use phpseclib3\Crypt\Common\Formats\Keys\PuTTY as Progenitor; use phpseclib3\Math\BigInteger; /** * PuTTY Formatted RSA Key Handler * * @author Jim Wigginton */ abstract class PuTTY extends Progenitor { /** * Public Handler * * @var string */ const PUBLIC_HANDLER = 'phpseclib3\Crypt\RSA\Formats\Keys\OpenSSH'; /** * Algorithm Identifier * * @var array */ protected static $types = ['ssh-rsa']; /** * Break a public or private key down into its constituent components * * @param string $key * @param string $password optional * @return array */ public static function load($key, $password = '') { static $one; if (!isset($one)) { $one = new BigInteger(1); } $components = parent::load($key, $password); if (!isset($components['private'])) { return $components; } $type = $components['type']; $comment = $components['comment']; $public = $components['public']; $private = $components['private']; unset($components['public'], $components['private']); $isPublicKey = false; $result = Strings::unpackSSH2('ii', $public); if ($result === false) { throw new \UnexpectedValueException('Key appears to be malformed'); } list($publicExponent, $modulus) = $result; $result = Strings::unpackSSH2('iiii', $private); if ($result === false) { throw new \UnexpectedValueException('Key appears to be malformed'); } $primes = $coefficients = []; list($privateExponent, $primes[1], $primes[2], $coefficients[2]) = $result; $temp = $primes[1]->subtract($one); $exponents = [1 => $publicExponent->modInverse($temp)]; $temp = $primes[2]->subtract($one); $exponents[] = $publicExponent->modInverse($temp); return compact('publicExponent', 'modulus', 'privateExponent', 'primes', 'coefficients', 'exponents', 'comment', 'isPublicKey'); } /** * Convert a private key to the appropriate format. * * @param BigInteger $n * @param BigInteger $e * @param BigInteger $d * @param array $primes * @param array $exponents * @param array $coefficients * @param string $password optional * @param array $options optional * @return string */ public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) { if (count($primes) != 2) { throw new \InvalidArgumentException('PuTTY does not support multi-prime RSA keys'); } $public = Strings::packSSH2('ii', $e, $n); $private = Strings::packSSH2('iiii', $d, $primes[1], $primes[2], $coefficients[2]); return self::wrapPrivateKey($public, $private, 'ssh-rsa', $password, $options); } /** * Convert a public key to the appropriate format * * @param BigInteger $n * @param BigInteger $e * @return string */ public static function savePublicKey(BigInteger $n, BigInteger $e) { return self::wrapPublicKey(Strings::packSSH2('ii', $e, $n), 'ssh-rsa'); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/Raw.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\RSA\Formats\Keys; use phpseclib3\Math\BigInteger; /** * Raw RSA Key Handler * * @author Jim Wigginton */ abstract class Raw { /** * Break a public or private key down into its constituent components * * @param string $key * @param string $password optional * @return array */ public static function load($key, $password = '') { if (!is_array($key)) { throw new \UnexpectedValueException('Key should be a array - not a ' . gettype($key)); } $key = array_change_key_case($key, CASE_LOWER); $components = ['isPublicKey' => false]; foreach (['e', 'exponent', 'publicexponent', 0, 'privateexponent', 'd'] as $index) { if (isset($key[$index])) { $components['publicExponent'] = $key[$index]; break; } } foreach (['n', 'modulo', 'modulus', 1] as $index) { if (isset($key[$index])) { $components['modulus'] = $key[$index]; break; } } if (!isset($components['publicExponent']) || !isset($components['modulus'])) { throw new \UnexpectedValueException('Modulus / exponent not present'); } if (isset($key['primes'])) { $components['primes'] = $key['primes']; } elseif (isset($key['p']) && isset($key['q'])) { $indices = [ ['p', 'q'], ['prime1', 'prime2'] ]; foreach ($indices as $index) { list($i0, $i1) = $index; if (isset($key[$i0]) && isset($key[$i1])) { $components['primes'] = [1 => $key[$i0], $key[$i1]]; } } } if (isset($key['exponents'])) { $components['exponents'] = $key['exponents']; } else { $indices = [ ['dp', 'dq'], ['exponent1', 'exponent2'] ]; foreach ($indices as $index) { list($i0, $i1) = $index; if (isset($key[$i0]) && isset($key[$i1])) { $components['exponents'] = [1 => $key[$i0], $key[$i1]]; } } } if (isset($key['coefficients'])) { $components['coefficients'] = $key['coefficients']; } else { foreach (['inverseq', 'q\'', 'coefficient'] as $index) { if (isset($key[$index])) { $components['coefficients'] = [2 => $key[$index]]; } } } if (!isset($components['primes'])) { $components['isPublicKey'] = true; return $components; } if (!isset($components['exponents'])) { $one = new BigInteger(1); $temp = $components['primes'][1]->subtract($one); $exponents = [1 => $components['publicExponent']->modInverse($temp)]; $temp = $components['primes'][2]->subtract($one); $exponents[] = $components['publicExponent']->modInverse($temp); $components['exponents'] = $exponents; } if (!isset($components['coefficients'])) { $components['coefficients'] = [2 => $components['primes'][2]->modInverse($components['primes'][1])]; } foreach (['privateexponent', 'd'] as $index) { if (isset($key[$index])) { $components['privateExponent'] = $key[$index]; break; } } return $components; } /** * Convert a private key to the appropriate format. * * @param BigInteger $n * @param BigInteger $e * @param BigInteger $d * @param array $primes * @param array $exponents * @param array $coefficients * @param string $password optional * @param array $options optional * @return array */ public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) { if (!empty($password) && is_string($password)) { throw new UnsupportedFormatException('Raw private keys do not support encryption'); } return [ 'e' => clone $e, 'n' => clone $n, 'd' => clone $d, 'primes' => array_map(function ($var) { return clone $var; }, $primes), 'exponents' => array_map(function ($var) { return clone $var; }, $exponents), 'coefficients' => array_map(function ($var) { return clone $var; }, $coefficients) ]; } /** * Convert a public key to the appropriate format * * @param BigInteger $n * @param BigInteger $e * @return array */ public static function savePublicKey(BigInteger $n, BigInteger $e) { return ['e' => clone $e, 'n' => clone $n]; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/XML.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\RSA\Formats\Keys; use phpseclib3\Common\Functions\Strings; use phpseclib3\Exception\BadConfigurationException; use phpseclib3\Exception\UnsupportedFormatException; use phpseclib3\Math\BigInteger; /** * XML Formatted RSA Key Handler * * @author Jim Wigginton */ abstract class XML { /** * Break a public or private key down into its constituent components * * @param string $key * @param string $password optional * @return array */ public static function load($key, $password = '') { if (!Strings::is_stringable($key)) { throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); } if (!class_exists('DOMDocument')) { throw new BadConfigurationException('The dom extension is not setup correctly on this system'); } $components = [ 'isPublicKey' => false, 'primes' => [], 'exponents' => [], 'coefficients' => [] ]; $use_errors = libxml_use_internal_errors(true); $dom = new \DOMDocument(); if (substr($key, 0, 5) != '' . $key . ''; } if (!$dom->loadXML($key)) { libxml_use_internal_errors($use_errors); throw new \UnexpectedValueException('Key does not appear to contain XML'); } $xpath = new \DOMXPath($dom); $keys = ['modulus', 'exponent', 'p', 'q', 'dp', 'dq', 'inverseq', 'd']; foreach ($keys as $key) { // $dom->getElementsByTagName($key) is case-sensitive $temp = $xpath->query("//*[translate(local-name(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='$key']"); if (!$temp->length) { continue; } $value = new BigInteger(Strings::base64_decode($temp->item(0)->nodeValue), 256); switch ($key) { case 'modulus': $components['modulus'] = $value; break; case 'exponent': $components['publicExponent'] = $value; break; case 'p': $components['primes'][1] = $value; break; case 'q': $components['primes'][2] = $value; break; case 'dp': $components['exponents'][1] = $value; break; case 'dq': $components['exponents'][2] = $value; break; case 'inverseq': $components['coefficients'][2] = $value; break; case 'd': $components['privateExponent'] = $value; } } libxml_use_internal_errors($use_errors); foreach ($components as $key => $value) { if (is_array($value) && !count($value)) { unset($components[$key]); } } if (isset($components['modulus']) && isset($components['publicExponent'])) { if (count($components) == 3) { $components['isPublicKey'] = true; } return $components; } throw new \UnexpectedValueException('Modulus / exponent not present'); } /** * Convert a private key to the appropriate format. * * @param BigInteger $n * @param BigInteger $e * @param BigInteger $d * @param array $primes * @param array $exponents * @param array $coefficients * @param string $password optional * @return string */ public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '') { if (count($primes) != 2) { throw new \InvalidArgumentException('XML does not support multi-prime RSA keys'); } if (!empty($password) && is_string($password)) { throw new UnsupportedFormatException('XML private keys do not support encryption'); } return "\r\n" . ' ' . Strings::base64_encode($n->toBytes()) . "\r\n" . ' ' . Strings::base64_encode($e->toBytes()) . "\r\n" . '

' . Strings::base64_encode($primes[1]->toBytes()) . "

\r\n" . ' ' . Strings::base64_encode($primes[2]->toBytes()) . "\r\n" . ' ' . Strings::base64_encode($exponents[1]->toBytes()) . "\r\n" . ' ' . Strings::base64_encode($exponents[2]->toBytes()) . "\r\n" . ' ' . Strings::base64_encode($coefficients[2]->toBytes()) . "\r\n" . ' ' . Strings::base64_encode($d->toBytes()) . "\r\n" . '
'; } /** * Convert a public key to the appropriate format * * @param BigInteger $n * @param BigInteger $e * @return string */ public static function savePublicKey(BigInteger $n, BigInteger $e) { return "\r\n" . ' ' . Strings::base64_encode($n->toBytes()) . "\r\n" . ' ' . Strings::base64_encode($e->toBytes()) . "\r\n" . ''; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PrivateKey.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\RSA; use phpseclib3\Crypt\Common; use phpseclib3\Crypt\Random; use phpseclib3\Crypt\RSA; use phpseclib3\Crypt\RSA\Formats\Keys\PSS; use phpseclib3\Exception\UnsupportedFormatException; use phpseclib3\Math\BigInteger; /** * Raw RSA Key Handler * * @author Jim Wigginton */ final class PrivateKey extends RSA implements Common\PrivateKey { use Common\Traits\PasswordProtected; /** * Primes for Chinese Remainder Theorem (ie. p and q) * * @var array */ protected $primes; /** * Exponents for Chinese Remainder Theorem (ie. dP and dQ) * * @var array */ protected $exponents; /** * Coefficients for Chinese Remainder Theorem (ie. qInv) * * @var array */ protected $coefficients; /** * Private Exponent * * @var BigInteger */ protected $privateExponent; /** * RSADP * * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.2 RFC3447#section-5.1.2}. * * @return bool|BigInteger */ private function rsadp(BigInteger $c) { if ($c->compare(self::$zero) < 0 || $c->compare($this->modulus) > 0) { throw new \OutOfRangeException('Ciphertext representative out of range'); } return $this->exponentiate($c); } /** * RSASP1 * * See {@link http://tools.ietf.org/html/rfc3447#section-5.2.1 RFC3447#section-5.2.1}. * * @return bool|BigInteger */ private function rsasp1(BigInteger $m) { if ($m->compare(self::$zero) < 0 || $m->compare($this->modulus) > 0) { throw new \OutOfRangeException('Signature representative out of range'); } return $this->exponentiate($m); } /** * Exponentiate * * @param BigInteger $x * @return BigInteger */ protected function exponentiate(BigInteger $x) { switch (true) { case empty($this->primes): case $this->primes[1]->equals(self::$zero): case empty($this->coefficients): case $this->coefficients[2]->equals(self::$zero): case empty($this->exponents): case $this->exponents[1]->equals(self::$zero): return $x->modPow($this->exponent, $this->modulus); } $num_primes = count($this->primes); if (!static::$enableBlinding) { $m_i = [ 1 => $x->modPow($this->exponents[1], $this->primes[1]), 2 => $x->modPow($this->exponents[2], $this->primes[2]) ]; $h = $m_i[1]->subtract($m_i[2]); $h = $h->multiply($this->coefficients[2]); list(, $h) = $h->divide($this->primes[1]); $m = $m_i[2]->add($h->multiply($this->primes[2])); $r = $this->primes[1]; for ($i = 3; $i <= $num_primes; $i++) { $m_i = $x->modPow($this->exponents[$i], $this->primes[$i]); $r = $r->multiply($this->primes[$i - 1]); $h = $m_i->subtract($m); $h = $h->multiply($this->coefficients[$i]); list(, $h) = $h->divide($this->primes[$i]); $m = $m->add($r->multiply($h)); } } else { $smallest = $this->primes[1]; for ($i = 2; $i <= $num_primes; $i++) { if ($smallest->compare($this->primes[$i]) > 0) { $smallest = $this->primes[$i]; } } $r = BigInteger::randomRange(self::$one, $smallest->subtract(self::$one)); $m_i = [ 1 => $this->blind($x, $r, 1), 2 => $this->blind($x, $r, 2) ]; $h = $m_i[1]->subtract($m_i[2]); $h = $h->multiply($this->coefficients[2]); list(, $h) = $h->divide($this->primes[1]); $m = $m_i[2]->add($h->multiply($this->primes[2])); $r = $this->primes[1]; for ($i = 3; $i <= $num_primes; $i++) { $m_i = $this->blind($x, $r, $i); $r = $r->multiply($this->primes[$i - 1]); $h = $m_i->subtract($m); $h = $h->multiply($this->coefficients[$i]); list(, $h) = $h->divide($this->primes[$i]); $m = $m->add($r->multiply($h)); } } return $m; } /** * Performs RSA Blinding * * Protects against timing attacks by employing RSA Blinding. * Returns $x->modPow($this->exponents[$i], $this->primes[$i]) * * @param BigInteger $x * @param BigInteger $r * @param int $i * @return BigInteger */ private function blind(BigInteger $x, BigInteger $r, $i) { $x = $x->multiply($r->modPow($this->publicExponent, $this->primes[$i])); $x = $x->modPow($this->exponents[$i], $this->primes[$i]); $r = $r->modInverse($this->primes[$i]); $x = $x->multiply($r); list(, $x) = $x->divide($this->primes[$i]); return $x; } /** * EMSA-PSS-ENCODE * * See {@link http://tools.ietf.org/html/rfc3447#section-9.1.1 RFC3447#section-9.1.1}. * * @return string * @param string $m * @throws \RuntimeException on encoding error * @param int $emBits */ private function emsa_pss_encode($m, $emBits) { // if $m is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error // be output. $emLen = ($emBits + 1) >> 3; // ie. ceil($emBits / 8) $sLen = $this->sLen !== null ? $this->sLen : $this->hLen; $mHash = $this->hash->hash($m); if ($emLen < $this->hLen + $sLen + 2) { throw new \LengthException('RSA modulus too short'); } $salt = Random::string($sLen); $m2 = "\0\0\0\0\0\0\0\0" . $mHash . $salt; $h = $this->hash->hash($m2); $ps = str_repeat(chr(0), $emLen - $sLen - $this->hLen - 2); $db = $ps . chr(1) . $salt; $dbMask = $this->mgf1($h, $emLen - $this->hLen - 1); // ie. stlren($db) $maskedDB = $db ^ $dbMask; $maskedDB[0] = ~chr(0xFF << ($emBits & 7)) & $maskedDB[0]; $em = $maskedDB . $h . chr(0xBC); return $em; } /** * RSASSA-PSS-SIGN * * See {@link http://tools.ietf.org/html/rfc3447#section-8.1.1 RFC3447#section-8.1.1}. * * @param string $m * @return bool|string */ private function rsassa_pss_sign($m) { // EMSA-PSS encoding $em = $this->emsa_pss_encode($m, 8 * $this->k - 1); // RSA signature $m = $this->os2ip($em); $s = $this->rsasp1($m); $s = $this->i2osp($s, $this->k); // Output the signature S return $s; } /** * RSASSA-PKCS1-V1_5-SIGN * * See {@link http://tools.ietf.org/html/rfc3447#section-8.2.1 RFC3447#section-8.2.1}. * * @param string $m * @throws \LengthException if the RSA modulus is too short * @return bool|string */ private function rsassa_pkcs1_v1_5_sign($m) { // EMSA-PKCS1-v1_5 encoding // If the encoding operation outputs "intended encoded message length too short," output "RSA modulus // too short" and stop. try { $em = $this->emsa_pkcs1_v1_5_encode($m, $this->k); } catch (\LengthException $e) { throw new \LengthException('RSA modulus too short'); } // RSA signature $m = $this->os2ip($em); $s = $this->rsasp1($m); $s = $this->i2osp($s, $this->k); // Output the signature S return $s; } /** * Create a signature * * @see self::verify() * @param string $message * @return string */ public function sign($message) { switch ($this->signaturePadding) { case self::SIGNATURE_PKCS1: case self::SIGNATURE_RELAXED_PKCS1: return $this->rsassa_pkcs1_v1_5_sign($message); //case self::SIGNATURE_PSS: default: return $this->rsassa_pss_sign($message); } } /** * RSAES-PKCS1-V1_5-DECRYPT * * See {@link http://tools.ietf.org/html/rfc3447#section-7.2.2 RFC3447#section-7.2.2}. * * @param string $c * @return bool|string */ private function rsaes_pkcs1_v1_5_decrypt($c) { // Length checking if (strlen($c) != $this->k) { // or if k < 11 throw new \LengthException('Ciphertext representative too long'); } // RSA decryption $c = $this->os2ip($c); $m = $this->rsadp($c); $em = $this->i2osp($m, $this->k); // EME-PKCS1-v1_5 decoding if (ord($em[0]) != 0 || ord($em[1]) > 2) { throw new \RuntimeException('Decryption error'); } $ps = substr($em, 2, strpos($em, chr(0), 2) - 2); $m = substr($em, strlen($ps) + 3); if (strlen($ps) < 8) { throw new \RuntimeException('Decryption error'); } // Output M return $m; } /** * RSAES-OAEP-DECRYPT * * See {@link http://tools.ietf.org/html/rfc3447#section-7.1.2 RFC3447#section-7.1.2}. The fact that the error * messages aren't distinguishable from one another hinders debugging, but, to quote from RFC3447#section-7.1.2: * * Note. Care must be taken to ensure that an opponent cannot * distinguish the different error conditions in Step 3.g, whether by * error message or timing, or, more generally, learn partial * information about the encoded message EM. Otherwise an opponent may * be able to obtain useful information about the decryption of the * ciphertext C, leading to a chosen-ciphertext attack such as the one * observed by Manger [36]. * * @param string $c * @return bool|string */ private function rsaes_oaep_decrypt($c) { // Length checking // if $l is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error // be output. if (strlen($c) != $this->k || $this->k < 2 * $this->hLen + 2) { throw new \LengthException('Ciphertext representative too long'); } // RSA decryption $c = $this->os2ip($c); $m = $this->rsadp($c); $em = $this->i2osp($m, $this->k); // EME-OAEP decoding $lHash = $this->hash->hash($this->label); $y = ord($em[0]); $maskedSeed = substr($em, 1, $this->hLen); $maskedDB = substr($em, $this->hLen + 1); $seedMask = $this->mgf1($maskedDB, $this->hLen); $seed = $maskedSeed ^ $seedMask; $dbMask = $this->mgf1($seed, $this->k - $this->hLen - 1); $db = $maskedDB ^ $dbMask; $lHash2 = substr($db, 0, $this->hLen); $m = substr($db, $this->hLen); $hashesMatch = hash_equals($lHash, $lHash2); $leadingZeros = 1; $patternMatch = 0; $offset = 0; for ($i = 0; $i < strlen($m); $i++) { $patternMatch |= $leadingZeros & ($m[$i] === "\1"); $leadingZeros &= $m[$i] === "\0"; $offset += $patternMatch ? 0 : 1; } // we do | instead of || to avoid https://en.wikipedia.org/wiki/Short-circuit_evaluation // to protect against timing attacks if (!$hashesMatch | !$patternMatch) { throw new \RuntimeException('Decryption error'); } // Output the message M return substr($m, $offset + 1); } /** * Raw Encryption / Decryption * * Doesn't use padding and is not recommended. * * @param string $m * @return bool|string * @throws \LengthException if strlen($m) > $this->k */ private function raw_encrypt($m) { if (strlen($m) > $this->k) { throw new \LengthException('Ciphertext representative too long'); } $temp = $this->os2ip($m); $temp = $this->rsadp($temp); return $this->i2osp($temp, $this->k); } /** * Decryption * * @see self::encrypt() * @param string $ciphertext * @return bool|string */ public function decrypt($ciphertext) { switch ($this->encryptionPadding) { case self::ENCRYPTION_NONE: return $this->raw_encrypt($ciphertext); case self::ENCRYPTION_PKCS1: return $this->rsaes_pkcs1_v1_5_decrypt($ciphertext); //case self::ENCRYPTION_OAEP: default: return $this->rsaes_oaep_decrypt($ciphertext); } } /** * Returns the public key * * @return mixed */ public function getPublicKey() { $type = self::validatePlugin('Keys', 'PKCS8', 'savePublicKey'); if (empty($this->modulus) || empty($this->publicExponent)) { throw new \RuntimeException('Public key components not found'); } $key = $type::savePublicKey($this->modulus, $this->publicExponent); return RSA::loadFormat('PKCS8', $key) ->withHash($this->hash->getHash()) ->withMGFHash($this->mgfHash->getHash()) ->withSaltLength($this->sLen) ->withLabel($this->label) ->withPadding($this->signaturePadding | $this->encryptionPadding); } /** * Returns the private key * * @param string $type * @param array $options optional * @return string */ public function toString($type, array $options = []) { $type = self::validatePlugin( 'Keys', $type, empty($this->primes) ? 'savePublicKey' : 'savePrivateKey' ); if ($type == PSS::class) { if ($this->signaturePadding == self::SIGNATURE_PSS) { $options += [ 'hash' => $this->hash->getHash(), 'MGFHash' => $this->mgfHash->getHash(), 'saltLength' => $this->getSaltLength() ]; } else { throw new UnsupportedFormatException('The PSS format can only be used when the signature method has been explicitly set to PSS'); } } if (empty($this->primes)) { return $type::savePublicKey($this->modulus, $this->exponent, $options); } return $type::savePrivateKey($this->modulus, $this->publicExponent, $this->exponent, $this->primes, $this->exponents, $this->coefficients, $this->password, $options); /* $key = $type::savePrivateKey($this->modulus, $this->publicExponent, $this->exponent, $this->primes, $this->exponents, $this->coefficients, $this->password, $options); if ($key !== false || count($this->primes) == 2) { return $key; } $nSize = $this->getSize() >> 1; $primes = [1 => clone self::$one, clone self::$one]; $i = 1; foreach ($this->primes as $prime) { $primes[$i] = $primes[$i]->multiply($prime); if ($primes[$i]->getLength() >= $nSize) { $i++; } } $exponents = []; $coefficients = [2 => $primes[2]->modInverse($primes[1])]; foreach ($primes as $i => $prime) { $temp = $prime->subtract(self::$one); $exponents[$i] = $this->modulus->modInverse($temp); } return $type::savePrivateKey($this->modulus, $this->publicExponent, $this->exponent, $primes, $exponents, $coefficients, $this->password, $options); */ } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PublicKey.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt\RSA; use phpseclib3\Common\Functions\Strings; use phpseclib3\Crypt\Common; use phpseclib3\Crypt\Hash; use phpseclib3\Crypt\Random; use phpseclib3\Crypt\RSA; use phpseclib3\Crypt\RSA\Formats\Keys\PSS; use phpseclib3\Exception\UnsupportedAlgorithmException; use phpseclib3\Exception\UnsupportedFormatException; use phpseclib3\File\ASN1; use phpseclib3\File\ASN1\Maps\DigestInfo; use phpseclib3\Math\BigInteger; /** * Raw RSA Key Handler * * @author Jim Wigginton */ final class PublicKey extends RSA implements Common\PublicKey { use Common\Traits\Fingerprint; /** * Exponentiate * * @param BigInteger $x * @return BigInteger */ private function exponentiate(BigInteger $x) { return $x->modPow($this->exponent, $this->modulus); } /** * RSAVP1 * * See {@link http://tools.ietf.org/html/rfc3447#section-5.2.2 RFC3447#section-5.2.2}. * * @param BigInteger $s * @return bool|BigInteger */ private function rsavp1($s) { if ($s->compare(self::$zero) < 0 || $s->compare($this->modulus) > 0) { return false; } return $this->exponentiate($s); } /** * RSASSA-PKCS1-V1_5-VERIFY * * See {@link http://tools.ietf.org/html/rfc3447#section-8.2.2 RFC3447#section-8.2.2}. * * @param string $m * @param string $s * @throws \LengthException if the RSA modulus is too short * @return bool */ private function rsassa_pkcs1_v1_5_verify($m, $s) { // Length checking if (strlen($s) != $this->k) { return false; } // RSA verification $s = $this->os2ip($s); $m2 = $this->rsavp1($s); if ($m2 === false) { return false; } $em = $this->i2osp($m2, $this->k); if ($em === false) { return false; } // EMSA-PKCS1-v1_5 encoding $exception = false; // If the encoding operation outputs "intended encoded message length too short," output "RSA modulus // too short" and stop. try { $em2 = $this->emsa_pkcs1_v1_5_encode($m, $this->k); $r1 = hash_equals($em, $em2); } catch (\LengthException $e) { $exception = true; } try { $em3 = $this->emsa_pkcs1_v1_5_encode_without_null($m, $this->k); $r2 = hash_equals($em, $em3); } catch (\LengthException $e) { $exception = true; } catch (UnsupportedAlgorithmException $e) { $r2 = false; } if ($exception) { throw new \LengthException('RSA modulus too short'); } // Compare return $r1 || $r2; } /** * RSASSA-PKCS1-V1_5-VERIFY (relaxed matching) * * Per {@link http://tools.ietf.org/html/rfc3447#page-43 RFC3447#page-43} PKCS1 v1.5 * specified the use BER encoding rather than DER encoding that PKCS1 v2.0 specified. * This means that under rare conditions you can have a perfectly valid v1.5 signature * that fails to validate with _rsassa_pkcs1_v1_5_verify(). PKCS1 v2.1 also recommends * that if you're going to validate these types of signatures you "should indicate * whether the underlying BER encoding is a DER encoding and hence whether the signature * is valid with respect to the specification given in [PKCS1 v2.0+]". so if you do * $rsa->getLastPadding() and get RSA::PADDING_RELAXED_PKCS1 back instead of * RSA::PADDING_PKCS1... that means BER encoding was used. * * @param string $m * @param string $s * @return bool */ private function rsassa_pkcs1_v1_5_relaxed_verify($m, $s) { // Length checking if (strlen($s) != $this->k) { return false; } // RSA verification $s = $this->os2ip($s); $m2 = $this->rsavp1($s); if ($m2 === false) { return false; } $em = $this->i2osp($m2, $this->k); if ($em === false) { return false; } if (Strings::shift($em, 2) != "\0\1") { return false; } $em = ltrim($em, "\xFF"); if (Strings::shift($em) != "\0") { return false; } $decoded = ASN1::decodeBER($em); if (!is_array($decoded) || empty($decoded[0]) || strlen($em) > $decoded[0]['length']) { return false; } static $oids; if (!isset($oids)) { $oids = [ 'md2' => '1.2.840.113549.2.2', 'md4' => '1.2.840.113549.2.4', // from PKCS1 v1.5 'md5' => '1.2.840.113549.2.5', 'id-sha1' => '1.3.14.3.2.26', 'id-sha256' => '2.16.840.1.101.3.4.2.1', 'id-sha384' => '2.16.840.1.101.3.4.2.2', 'id-sha512' => '2.16.840.1.101.3.4.2.3', // from PKCS1 v2.2 'id-sha224' => '2.16.840.1.101.3.4.2.4', 'id-sha512/224' => '2.16.840.1.101.3.4.2.5', 'id-sha512/256' => '2.16.840.1.101.3.4.2.6', ]; ASN1::loadOIDs($oids); } $decoded = ASN1::asn1map($decoded[0], DigestInfo::MAP); if (!isset($decoded) || $decoded === false) { return false; } if (!isset($oids[$decoded['digestAlgorithm']['algorithm']])) { return false; } if (isset($decoded['digestAlgorithm']['parameters']) && $decoded['digestAlgorithm']['parameters'] !== ['null' => '']) { return false; } $hash = $decoded['digestAlgorithm']['algorithm']; $hash = substr($hash, 0, 3) == 'id-' ? substr($hash, 3) : $hash; $hash = new Hash($hash); $em = $hash->hash($m); $em2 = $decoded['digest']; return hash_equals($em, $em2); } /** * EMSA-PSS-VERIFY * * See {@link http://tools.ietf.org/html/rfc3447#section-9.1.2 RFC3447#section-9.1.2}. * * @param string $m * @param string $em * @param int $emBits * @return string */ private function emsa_pss_verify($m, $em, $emBits) { // if $m is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error // be output. $emLen = ($emBits + 7) >> 3; // ie. ceil($emBits / 8); $sLen = $this->sLen !== null ? $this->sLen : $this->hLen; $mHash = $this->hash->hash($m); if ($emLen < $this->hLen + $sLen + 2) { return false; } if ($em[strlen($em) - 1] != chr(0xBC)) { return false; } $maskedDB = substr($em, 0, -$this->hLen - 1); $h = substr($em, -$this->hLen - 1, $this->hLen); $temp = chr(0xFF << ($emBits & 7)); if ((~$maskedDB[0] & $temp) != $temp) { return false; } $dbMask = $this->mgf1($h, $emLen - $this->hLen - 1); $db = $maskedDB ^ $dbMask; $db[0] = ~chr(0xFF << ($emBits & 7)) & $db[0]; $temp = $emLen - $this->hLen - $sLen - 2; if (substr($db, 0, $temp) != str_repeat(chr(0), $temp) || ord($db[$temp]) != 1) { return false; } $salt = substr($db, $temp + 1); // should be $sLen long $m2 = "\0\0\0\0\0\0\0\0" . $mHash . $salt; $h2 = $this->hash->hash($m2); return hash_equals($h, $h2); } /** * RSASSA-PSS-VERIFY * * See {@link http://tools.ietf.org/html/rfc3447#section-8.1.2 RFC3447#section-8.1.2}. * * @param string $m * @param string $s * @return bool|string */ private function rsassa_pss_verify($m, $s) { // Length checking if (strlen($s) != $this->k) { return false; } // RSA verification $modBits = strlen($this->modulus->toBits()); $s2 = $this->os2ip($s); $m2 = $this->rsavp1($s2); $em = $this->i2osp($m2, $this->k); if ($em === false) { return false; } // EMSA-PSS verification return $this->emsa_pss_verify($m, $em, $modBits - 1); } /** * Verifies a signature * * @see self::sign() * @param string $message * @param string $signature * @return bool */ public function verify($message, $signature) { switch ($this->signaturePadding) { case self::SIGNATURE_RELAXED_PKCS1: return $this->rsassa_pkcs1_v1_5_relaxed_verify($message, $signature); case self::SIGNATURE_PKCS1: return $this->rsassa_pkcs1_v1_5_verify($message, $signature); //case self::SIGNATURE_PSS: default: return $this->rsassa_pss_verify($message, $signature); } } /** * RSAES-PKCS1-V1_5-ENCRYPT * * See {@link http://tools.ietf.org/html/rfc3447#section-7.2.1 RFC3447#section-7.2.1}. * * @param string $m * @param bool $pkcs15_compat optional * @throws \LengthException if strlen($m) > $this->k - 11 * @return bool|string */ private function rsaes_pkcs1_v1_5_encrypt($m, $pkcs15_compat = false) { $mLen = strlen($m); // Length checking if ($mLen > $this->k - 11) { throw new \LengthException('Message too long'); } // EME-PKCS1-v1_5 encoding $psLen = $this->k - $mLen - 3; $ps = ''; while (strlen($ps) != $psLen) { $temp = Random::string($psLen - strlen($ps)); $temp = str_replace("\x00", '', $temp); $ps .= $temp; } $type = 2; $em = chr(0) . chr($type) . $ps . chr(0) . $m; // RSA encryption $m = $this->os2ip($em); $c = $this->rsaep($m); $c = $this->i2osp($c, $this->k); // Output the ciphertext C return $c; } /** * RSAES-OAEP-ENCRYPT * * See {@link http://tools.ietf.org/html/rfc3447#section-7.1.1 RFC3447#section-7.1.1} and * {http://en.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding OAES}. * * @param string $m * @throws \LengthException if strlen($m) > $this->k - 2 * $this->hLen - 2 * @return string */ private function rsaes_oaep_encrypt($m) { $mLen = strlen($m); // Length checking // if $l is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error // be output. if ($mLen > $this->k - 2 * $this->hLen - 2) { throw new \LengthException('Message too long'); } // EME-OAEP encoding $lHash = $this->hash->hash($this->label); $ps = str_repeat(chr(0), $this->k - $mLen - 2 * $this->hLen - 2); $db = $lHash . $ps . chr(1) . $m; $seed = Random::string($this->hLen); $dbMask = $this->mgf1($seed, $this->k - $this->hLen - 1); $maskedDB = $db ^ $dbMask; $seedMask = $this->mgf1($maskedDB, $this->hLen); $maskedSeed = $seed ^ $seedMask; $em = chr(0) . $maskedSeed . $maskedDB; // RSA encryption $m = $this->os2ip($em); $c = $this->rsaep($m); $c = $this->i2osp($c, $this->k); // Output the ciphertext C return $c; } /** * RSAEP * * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.1 RFC3447#section-5.1.1}. * * @param BigInteger $m * @return bool|BigInteger */ private function rsaep($m) { if ($m->compare(self::$zero) < 0 || $m->compare($this->modulus) > 0) { throw new \OutOfRangeException('Message representative out of range'); } return $this->exponentiate($m); } /** * Raw Encryption / Decryption * * Doesn't use padding and is not recommended. * * @param string $m * @return bool|string * @throws \LengthException if strlen($m) > $this->k */ private function raw_encrypt($m) { if (strlen($m) > $this->k) { throw new \LengthException('Message too long'); } $temp = $this->os2ip($m); $temp = $this->rsaep($temp); return $this->i2osp($temp, $this->k); } /** * Encryption * * Both self::PADDING_OAEP and self::PADDING_PKCS1 both place limits on how long $plaintext can be. * If $plaintext exceeds those limits it will be broken up so that it does and the resultant ciphertext's will * be concatenated together. * * @see self::decrypt() * @param string $plaintext * @return bool|string * @throws \LengthException if the RSA modulus is too short */ public function encrypt($plaintext) { switch ($this->encryptionPadding) { case self::ENCRYPTION_NONE: return $this->raw_encrypt($plaintext); case self::ENCRYPTION_PKCS1: return $this->rsaes_pkcs1_v1_5_encrypt($plaintext); //case self::ENCRYPTION_OAEP: default: return $this->rsaes_oaep_encrypt($plaintext); } } /** * Returns the public key * * The public key is only returned under two circumstances - if the private key had the public key embedded within it * or if the public key was set via setPublicKey(). If the currently loaded key is supposed to be the public key this * function won't return it since this library, for the most part, doesn't distinguish between public and private keys. * * @param string $type * @param array $options optional * @return mixed */ public function toString($type, array $options = []) { $type = self::validatePlugin('Keys', $type, 'savePublicKey'); if ($type == PSS::class) { if ($this->signaturePadding == self::SIGNATURE_PSS) { $options += [ 'hash' => $this->hash->getHash(), 'MGFHash' => $this->mgfHash->getHash(), 'saltLength' => $this->getSaltLength() ]; } else { throw new UnsupportedFormatException('The PSS format can only be used when the signature method has been explicitly set to PSS'); } } return $type::savePublicKey($this->modulus, $this->publicExponent, $options); } /** * Converts a public key to a private key * * @return RSA */ public function asPrivateKey() { $new = new PrivateKey(); $new->exponent = $this->exponent; $new->modulus = $this->modulus; $new->k = $this->k; $new->format = $this->format; return $new ->withHash($this->hash->getHash()) ->withMGFHash($this->mgfHash->getHash()) ->withSaltLength($this->sLen) ->withLabel($this->label) ->withPadding($this->signaturePadding | $this->encryptionPadding); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php ================================================ * getPublicKey(); * * $plaintext = 'terrafrost'; * * $ciphertext = $public->encrypt($plaintext); * * echo $private->decrypt($ciphertext); * ?> * * * Here's an example of how to create signatures and verify signatures with this library: * * getPublicKey(); * * $plaintext = 'terrafrost'; * * $signature = $private->sign($plaintext); * * echo $public->verify($plaintext, $signature) ? 'verified' : 'unverified'; * ?> * * * One thing to consider when using this: so phpseclib uses PSS mode by default. * Technically, id-RSASSA-PSS has a different key format than rsaEncryption. So * should phpseclib save to the id-RSASSA-PSS format by default or the * rsaEncryption format? For stand-alone keys I figure rsaEncryption is better * because SSH doesn't use PSS and idk how many SSH servers would be able to * decode an id-RSASSA-PSS key. For X.509 certificates the id-RSASSA-PSS * format is used by default (unless you change it up to use PKCS1 instead) * * @author Jim Wigginton * @copyright 2009 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt; use phpseclib3\Crypt\Common\AsymmetricKey; use phpseclib3\Crypt\RSA\Formats\Keys\PSS; use phpseclib3\Crypt\RSA\PrivateKey; use phpseclib3\Crypt\RSA\PublicKey; use phpseclib3\Exception\InconsistentSetupException; use phpseclib3\Exception\UnsupportedAlgorithmException; use phpseclib3\Math\BigInteger; /** * Pure-PHP PKCS#1 compliant implementation of RSA. * * @author Jim Wigginton */ abstract class RSA extends AsymmetricKey { /** * Algorithm Name * * @var string */ const ALGORITHM = 'RSA'; /** * Use {@link http://en.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding Optimal Asymmetric Encryption Padding} * (OAEP) for encryption / decryption. * * Uses sha256 by default * * @see self::setHash() * @see self::setMGFHash() * @see self::encrypt() * @see self::decrypt() */ const ENCRYPTION_OAEP = 1; /** * Use PKCS#1 padding. * * Although self::PADDING_OAEP / self::PADDING_PSS offers more security, including PKCS#1 padding is necessary for purposes of backwards * compatibility with protocols (like SSH-1) written before OAEP's introduction. * * @see self::encrypt() * @see self::decrypt() */ const ENCRYPTION_PKCS1 = 2; /** * Do not use any padding * * Although this method is not recommended it can none-the-less sometimes be useful if you're trying to decrypt some legacy * stuff, if you're trying to diagnose why an encrypted message isn't decrypting, etc. * * @see self::encrypt() * @see self::decrypt() */ const ENCRYPTION_NONE = 4; /** * Use the Probabilistic Signature Scheme for signing * * Uses sha256 and 0 as the salt length * * @see self::setSaltLength() * @see self::setMGFHash() * @see self::setHash() * @see self::sign() * @see self::verify() * @see self::setHash() */ const SIGNATURE_PSS = 16; /** * Use a relaxed version of PKCS#1 padding for signature verification * * @see self::sign() * @see self::verify() * @see self::setHash() */ const SIGNATURE_RELAXED_PKCS1 = 32; /** * Use PKCS#1 padding for signature verification * * @see self::sign() * @see self::verify() * @see self::setHash() */ const SIGNATURE_PKCS1 = 64; /** * Encryption padding mode * * @var int */ protected $encryptionPadding = self::ENCRYPTION_OAEP; /** * Signature padding mode * * @var int */ protected $signaturePadding = self::SIGNATURE_PSS; /** * Length of hash function output * * @var int */ protected $hLen; /** * Length of salt * * @var int */ protected $sLen; /** * Label * * @var string */ protected $label = ''; /** * Hash function for the Mask Generation Function * * @var Hash */ protected $mgfHash; /** * Length of MGF hash function output * * @var int */ protected $mgfHLen; /** * Modulus (ie. n) * * @var Math\BigInteger */ protected $modulus; /** * Modulus length * * @var Math\BigInteger */ protected $k; /** * Exponent (ie. e or d) * * @var Math\BigInteger */ protected $exponent; /** * Default public exponent * * @var int * @link http://en.wikipedia.org/wiki/65537_%28number%29 */ private static $defaultExponent = 65537; /** * Enable Blinding? * * @var bool */ protected static $enableBlinding = true; /** * OpenSSL configuration file name. * * @see self::createKey() * @var ?string */ protected static $configFile; /** * Smallest Prime * * Per , this number ought not result in primes smaller * than 256 bits. As a consequence if the key you're trying to create is 1024 bits and you've set smallestPrime * to 384 bits then you're going to get a 384 bit prime and a 640 bit prime (384 + 1024 % 384). At least if * engine is set to self::ENGINE_INTERNAL. If Engine is set to self::ENGINE_OPENSSL then smallest Prime is * ignored (ie. multi-prime RSA support is more intended as a way to speed up RSA key generation when there's * a chance neither gmp nor OpenSSL are installed) * * @var int */ private static $smallestPrime = 4096; /** * Public Exponent * * @var Math\BigInteger */ protected $publicExponent; /** * Sets the public exponent for key generation * * This will be 65537 unless changed. * * @param int $val */ public static function setExponent($val) { self::$defaultExponent = $val; } /** * Sets the smallest prime number in bits. Used for key generation * * This will be 4096 unless changed. * * @param int $val */ public static function setSmallestPrime($val) { self::$smallestPrime = $val; } /** * Sets the OpenSSL config file path * * Set to the empty string to use the default config file * * @param string $val */ public static function setOpenSSLConfigPath($val) { self::$configFile = $val; } /** * Create a private key * * The public key can be extracted from the private key * * @return PrivateKey * @param int $bits */ public static function createKey($bits = 2048) { self::initialize_static_variables(); $class = new \ReflectionClass(static::class); if ($class->isFinal()) { throw new \RuntimeException('createKey() should not be called from final classes (' . static::class . ')'); } $regSize = $bits >> 1; // divide by two to see how many bits P and Q would be if ($regSize > self::$smallestPrime) { $num_primes = floor($bits / self::$smallestPrime); $regSize = self::$smallestPrime; } else { $num_primes = 2; } if ($num_primes == 2 && $bits >= 384 && self::$defaultExponent == 65537) { if (!isset(self::$engines['PHP'])) { self::useBestEngine(); } // OpenSSL uses 65537 as the exponent and requires RSA keys be 384 bits minimum if (self::$engines['OpenSSL']) { $config = []; if (self::$configFile) { $config['config'] = self::$configFile; } $rsa = openssl_pkey_new(['private_key_bits' => $bits] + $config); openssl_pkey_export($rsa, $privatekeystr, null, $config); // clear the buffer of error strings stemming from a minimalistic openssl.cnf // https://github.com/php/php-src/issues/11054 talks about other errors this'll pick up while (openssl_error_string() !== false) { } return RSA::load($privatekeystr); } } static $e; if (!isset($e)) { $e = new BigInteger(self::$defaultExponent); } $n = clone self::$one; $exponents = $coefficients = $primes = []; $lcm = [ 'top' => clone self::$one, 'bottom' => false ]; do { for ($i = 1; $i <= $num_primes; $i++) { if ($i != $num_primes) { $primes[$i] = BigInteger::randomPrime($regSize); } else { $minMax = BigInteger::minMaxBits($bits); $min = $minMax['min']; $max = $minMax['max']; list($min) = $min->divide($n); $min = $min->add(self::$one); list($max) = $max->divide($n); $primes[$i] = BigInteger::randomRangePrime($min, $max); } // the first coefficient is calculated differently from the rest // ie. instead of being $primes[1]->modInverse($primes[2]), it's $primes[2]->modInverse($primes[1]) if ($i > 2) { $coefficients[$i] = $n->modInverse($primes[$i]); } $n = $n->multiply($primes[$i]); $temp = $primes[$i]->subtract(self::$one); // textbook RSA implementations use Euler's totient function instead of the least common multiple. // see http://en.wikipedia.org/wiki/Euler%27s_totient_function $lcm['top'] = $lcm['top']->multiply($temp); $lcm['bottom'] = $lcm['bottom'] === false ? $temp : $lcm['bottom']->gcd($temp); } list($temp) = $lcm['top']->divide($lcm['bottom']); $gcd = $temp->gcd($e); $i0 = 1; } while (!$gcd->equals(self::$one)); $coefficients[2] = $primes[2]->modInverse($primes[1]); $d = $e->modInverse($temp); foreach ($primes as $i => $prime) { $temp = $prime->subtract(self::$one); $exponents[$i] = $e->modInverse($temp); } // from : // RSAPrivateKey ::= SEQUENCE { // version Version, // modulus INTEGER, -- n // publicExponent INTEGER, -- e // privateExponent INTEGER, -- d // prime1 INTEGER, -- p // prime2 INTEGER, -- q // exponent1 INTEGER, -- d mod (p-1) // exponent2 INTEGER, -- d mod (q-1) // coefficient INTEGER, -- (inverse of q) mod p // otherPrimeInfos OtherPrimeInfos OPTIONAL // } $privatekey = new PrivateKey(); $privatekey->modulus = $n; $privatekey->k = $bits >> 3; $privatekey->publicExponent = $e; $privatekey->exponent = $d; $privatekey->primes = $primes; $privatekey->exponents = $exponents; $privatekey->coefficients = $coefficients; /* $publickey = new PublicKey; $publickey->modulus = $n; $publickey->k = $bits >> 3; $publickey->exponent = $e; $publickey->publicExponent = $e; $publickey->isPublic = true; */ return $privatekey; } /** * OnLoad Handler * * @return bool */ protected static function onLoad(array $components) { $key = $components['isPublicKey'] ? new PublicKey() : new PrivateKey(); $key->modulus = $components['modulus']; $key->publicExponent = $components['publicExponent']; $key->k = $key->modulus->getLengthInBytes(); if ($components['isPublicKey'] || !isset($components['privateExponent'])) { $key->exponent = $key->publicExponent; } else { $key->privateExponent = $components['privateExponent']; $key->exponent = $key->privateExponent; $key->primes = $components['primes']; $key->exponents = $components['exponents']; $key->coefficients = $components['coefficients']; } if ($components['format'] == PSS::class) { // in the X509 world RSA keys are assumed to use PKCS1 padding by default. only if the key is // explicitly a PSS key is the use of PSS assumed. phpseclib does not work like this. phpseclib // uses PSS padding by default. it assumes the more secure method by default and altho it provides // for the less secure PKCS1 method you have to go out of your way to use it. this is consistent // with the latest trends in crypto. libsodium (NaCl) is actually a little more extreme in that // not only does it defaults to the most secure methods - it doesn't even let you choose less // secure methods //$key = $key->withPadding(self::SIGNATURE_PSS); if (isset($components['hash'])) { $key = $key->withHash($components['hash']); } if (isset($components['MGFHash'])) { $key = $key->withMGFHash($components['MGFHash']); } if (isset($components['saltLength'])) { $key = $key->withSaltLength($components['saltLength']); } } return $key; } /** * Initialize static variables */ protected static function initialize_static_variables() { if (!isset(self::$configFile)) { self::$configFile = dirname(__FILE__) . '/../openssl.cnf'; } parent::initialize_static_variables(); } /** * Constructor * * PublicKey and PrivateKey objects can only be created from abstract RSA class */ protected function __construct() { parent::__construct(); $this->hLen = $this->hash->getLengthInBytes(); $this->mgfHash = new Hash('sha256'); $this->mgfHLen = $this->mgfHash->getLengthInBytes(); } /** * Integer-to-Octet-String primitive * * See {@link http://tools.ietf.org/html/rfc3447#section-4.1 RFC3447#section-4.1}. * * @param bool|Math\BigInteger $x * @param int $xLen * @return bool|string */ protected function i2osp($x, $xLen) { if ($x === false) { return false; } $x = $x->toBytes(); if (strlen($x) > $xLen) { throw new \OutOfRangeException('Resultant string length out of range'); } return str_pad($x, $xLen, chr(0), STR_PAD_LEFT); } /** * Octet-String-to-Integer primitive * * See {@link http://tools.ietf.org/html/rfc3447#section-4.2 RFC3447#section-4.2}. * * @param string $x * @return Math\BigInteger */ protected function os2ip($x) { return new BigInteger($x, 256); } /** * EMSA-PKCS1-V1_5-ENCODE * * See {@link http://tools.ietf.org/html/rfc3447#section-9.2 RFC3447#section-9.2}. * * @param string $m * @param int $emLen * @throws \LengthException if the intended encoded message length is too short * @return string */ protected function emsa_pkcs1_v1_5_encode($m, $emLen) { $h = $this->hash->hash($m); // see http://tools.ietf.org/html/rfc3447#page-43 switch ($this->hash->getHash()) { case 'md2': $t = "\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x02\x05\x00\x04\x10"; break; case 'md5': $t = "\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05\x05\x00\x04\x10"; break; case 'sha1': $t = "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14"; break; case 'sha256': $t = "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20"; break; case 'sha384': $t = "\x30\x41\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02\x05\x00\x04\x30"; break; case 'sha512': $t = "\x30\x51\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03\x05\x00\x04\x40"; break; // from https://www.emc.com/collateral/white-papers/h11300-pkcs-1v2-2-rsa-cryptography-standard-wp.pdf#page=40 case 'sha224': $t = "\x30\x2d\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04\x05\x00\x04\x1c"; break; case 'sha512/224': $t = "\x30\x2d\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x05\x05\x00\x04\x1c"; break; case 'sha512/256': $t = "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x06\x05\x00\x04\x20"; } $t .= $h; $tLen = strlen($t); if ($emLen < $tLen + 11) { throw new \LengthException('Intended encoded message length too short'); } $ps = str_repeat(chr(0xFF), $emLen - $tLen - 3); $em = "\0\1$ps\0$t"; return $em; } /** * EMSA-PKCS1-V1_5-ENCODE (without NULL) * * Quoting https://tools.ietf.org/html/rfc8017#page-65, * * "The parameters field associated with id-sha1, id-sha224, id-sha256, * id-sha384, id-sha512, id-sha512/224, and id-sha512/256 should * generally be omitted, but if present, it shall have a value of type * NULL" * * @param string $m * @param int $emLen * @return string */ protected function emsa_pkcs1_v1_5_encode_without_null($m, $emLen) { $h = $this->hash->hash($m); // see http://tools.ietf.org/html/rfc3447#page-43 switch ($this->hash->getHash()) { case 'sha1': $t = "\x30\x1f\x30\x07\x06\x05\x2b\x0e\x03\x02\x1a\x04\x14"; break; case 'sha256': $t = "\x30\x2f\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x04\x20"; break; case 'sha384': $t = "\x30\x3f\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02\x04\x30"; break; case 'sha512': $t = "\x30\x4f\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03\x04\x40"; break; // from https://www.emc.com/collateral/white-papers/h11300-pkcs-1v2-2-rsa-cryptography-standard-wp.pdf#page=40 case 'sha224': $t = "\x30\x2b\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04\x04\x1c"; break; case 'sha512/224': $t = "\x30\x2b\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x05\x04\x1c"; break; case 'sha512/256': $t = "\x30\x2f\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x06\x04\x20"; break; default: throw new UnsupportedAlgorithmException('md2 and md5 require NULLs'); } $t .= $h; $tLen = strlen($t); if ($emLen < $tLen + 11) { throw new \LengthException('Intended encoded message length too short'); } $ps = str_repeat(chr(0xFF), $emLen - $tLen - 3); $em = "\0\1$ps\0$t"; return $em; } /** * MGF1 * * See {@link http://tools.ietf.org/html/rfc3447#appendix-B.2.1 RFC3447#appendix-B.2.1}. * * @param string $mgfSeed * @param int $maskLen * @return string */ protected function mgf1($mgfSeed, $maskLen) { // if $maskLen would yield strings larger than 4GB, PKCS#1 suggests a "Mask too long" error be output. $t = ''; $count = ceil($maskLen / $this->mgfHLen); for ($i = 0; $i < $count; $i++) { $c = pack('N', $i); $t .= $this->mgfHash->hash($mgfSeed . $c); } return substr($t, 0, $maskLen); } /** * Returns the key size * * More specifically, this returns the size of the modulo in bits. * * @return int */ public function getLength() { return !isset($this->modulus) ? 0 : $this->modulus->getLength(); } /** * Determines which hashing function should be used * * Used with signature production / verification and (if the encryption mode is self::PADDING_OAEP) encryption and * decryption. * * @param string $hash */ public function withHash($hash) { $new = clone $this; // Crypt\Hash supports algorithms that PKCS#1 doesn't support. md5-96 and sha1-96, for example. switch (strtolower($hash)) { case 'md2': case 'md5': case 'sha1': case 'sha256': case 'sha384': case 'sha512': case 'sha224': case 'sha512/224': case 'sha512/256': $new->hash = new Hash($hash); break; default: throw new UnsupportedAlgorithmException( 'The only supported hash algorithms are: md2, md5, sha1, sha256, sha384, sha512, sha224, sha512/224, sha512/256' ); } $new->hLen = $new->hash->getLengthInBytes(); return $new; } /** * Determines which hashing function should be used for the mask generation function * * The mask generation function is used by self::PADDING_OAEP and self::PADDING_PSS and although it's * best if Hash and MGFHash are set to the same thing this is not a requirement. * * @param string $hash */ public function withMGFHash($hash) { $new = clone $this; // Crypt\Hash supports algorithms that PKCS#1 doesn't support. md5-96 and sha1-96, for example. switch (strtolower($hash)) { case 'md2': case 'md5': case 'sha1': case 'sha256': case 'sha384': case 'sha512': case 'sha224': case 'sha512/224': case 'sha512/256': $new->mgfHash = new Hash($hash); break; default: throw new UnsupportedAlgorithmException( 'The only supported hash algorithms are: md2, md5, sha1, sha256, sha384, sha512, sha224, sha512/224, sha512/256' ); } $new->mgfHLen = $new->mgfHash->getLengthInBytes(); return $new; } /** * Returns the MGF hash algorithm currently being used * */ public function getMGFHash() { return clone $this->mgfHash; } /** * Determines the salt length * * Used by RSA::PADDING_PSS * * To quote from {@link http://tools.ietf.org/html/rfc3447#page-38 RFC3447#page-38}: * * Typical salt lengths in octets are hLen (the length of the output * of the hash function Hash) and 0. * * @param int $sLen */ public function withSaltLength($sLen) { $new = clone $this; $new->sLen = $sLen; return $new; } /** * Returns the salt length currently being used * */ public function getSaltLength() { return $this->sLen !== null ? $this->sLen : $this->hLen; } /** * Determines the label * * Used by RSA::PADDING_OAEP * * To quote from {@link http://tools.ietf.org/html/rfc3447#page-17 RFC3447#page-17}: * * Both the encryption and the decryption operations of RSAES-OAEP take * the value of a label L as input. In this version of PKCS #1, L is * the empty string; other uses of the label are outside the scope of * this document. * * @param string $label */ public function withLabel($label) { $new = clone $this; $new->label = $label; return $new; } /** * Returns the label currently being used * */ public function getLabel() { return $this->label; } /** * Determines the padding modes * * Example: $key->withPadding(RSA::ENCRYPTION_PKCS1 | RSA::SIGNATURE_PKCS1); * * @param int $padding */ public function withPadding($padding) { $masks = [ self::ENCRYPTION_OAEP, self::ENCRYPTION_PKCS1, self::ENCRYPTION_NONE ]; $encryptedCount = 0; $selected = 0; foreach ($masks as $mask) { if ($padding & $mask) { $selected = $mask; $encryptedCount++; } } if ($encryptedCount > 1) { throw new InconsistentSetupException('Multiple encryption padding modes have been selected; at most only one should be selected'); } $encryptionPadding = $selected; $masks = [ self::SIGNATURE_PSS, self::SIGNATURE_RELAXED_PKCS1, self::SIGNATURE_PKCS1 ]; $signatureCount = 0; $selected = 0; foreach ($masks as $mask) { if ($padding & $mask) { $selected = $mask; $signatureCount++; } } if ($signatureCount > 1) { throw new InconsistentSetupException('Multiple signature padding modes have been selected; at most only one should be selected'); } $signaturePadding = $selected; $new = clone $this; if ($encryptedCount) { $new->encryptionPadding = $encryptionPadding; } if ($signatureCount) { $new->signaturePadding = $signaturePadding; } return $new; } /** * Returns the padding currently being used * */ public function getPadding() { return $this->signaturePadding | $this->encryptionPadding; } /** * Returns the current engine being used * * OpenSSL is only used in this class (and it's subclasses) for key generation * Even then it depends on the parameters you're using. It's not used for * multi-prime RSA nor is it used if the key length is outside of the range * supported by OpenSSL * * @see self::useInternalEngine() * @see self::useBestEngine() * @return string */ public function getEngine() { if (!isset(self::$engines['PHP'])) { self::useBestEngine(); } return self::$engines['OpenSSL'] && self::$defaultExponent == 65537 ? 'OpenSSL' : 'PHP'; } /** * Enable RSA Blinding * */ public static function enableBlinding() { static::$enableBlinding = true; } /** * Disable RSA Blinding * */ public static function disableBlinding() { static::$enableBlinding = false; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php ================================================ * * * * @author Jim Wigginton * @copyright 2007 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt; /** * Pure-PHP Random Number Generator * * @author Jim Wigginton */ abstract class Random { /** * Generate a random string. * * Although microoptimizations are generally discouraged as they impair readability this function is ripe with * microoptimizations because this function has the potential of being called a huge number of times. * eg. for RSA key generation. * * @param int $length * @throws \RuntimeException if a symmetric cipher is needed but not loaded * @return string */ public static function string($length) { if (!$length) { return ''; } try { return random_bytes($length); } catch (\Exception $e) { // random_compat will throw an Exception, which in PHP 5 does not implement Throwable } catch (\Throwable $e) { // If a sufficient source of randomness is unavailable, random_bytes() will throw an // object that implements the Throwable interface (Exception, TypeError, Error). // We don't actually need to do anything here. The string() method should just continue // as normal. Note, however, that if we don't have a sufficient source of randomness for // random_bytes(), most of the other calls here will fail too, so we'll end up using // the PHP implementation. } // at this point we have no choice but to use a pure-PHP CSPRNG // cascade entropy across multiple PHP instances by fixing the session and collecting all // environmental variables, including the previous session data and the current session // data. // // mt_rand seeds itself by looking at the PID and the time, both of which are (relatively) // easy to guess at. linux uses mouse clicks, keyboard timings, etc, as entropy sources, but // PHP isn't low level to be able to use those as sources and on a web server there's not likely // going to be a ton of keyboard or mouse action. web servers do have one thing that we can use // however, a ton of people visiting the website. obviously you don't want to base your seeding // solely on parameters a potential attacker sends but (1) not everything in $_SERVER is controlled // by the user and (2) this isn't just looking at the data sent by the current user - it's based // on the data sent by all users. one user requests the page and a hash of their info is saved. // another user visits the page and the serialization of their data is utilized along with the // server environment stuff and a hash of the previous http request data (which itself utilizes // a hash of the session data before that). certainly an attacker should be assumed to have // full control over his own http requests. he, however, is not going to have control over // everyone's http requests. static $crypto = false, $v; if ($crypto === false) { // save old session data $old_session_id = session_id(); $old_use_cookies = ini_get('session.use_cookies'); $old_session_cache_limiter = session_cache_limiter(); $_OLD_SESSION = isset($_SESSION) ? $_SESSION : false; if ($old_session_id != '') { session_write_close(); } session_id(1); ini_set('session.use_cookies', 0); session_cache_limiter(''); session_start(); $v = (isset($_SERVER) ? self::safe_serialize($_SERVER) : '') . (isset($_POST) ? self::safe_serialize($_POST) : '') . (isset($_GET) ? self::safe_serialize($_GET) : '') . (isset($_COOKIE) ? self::safe_serialize($_COOKIE) : '') . // as of PHP 8.1 $GLOBALS can't be accessed by reference, which eliminates // the need for phpseclib_safe_serialize. see https://wiki.php.net/rfc/restrict_globals_usage // for more info (version_compare(PHP_VERSION, '8.1.0', '>=') ? serialize($GLOBALS) : self::safe_serialize($GLOBALS)) . self::safe_serialize($_SESSION) . self::safe_serialize($_OLD_SESSION); $v = $seed = $_SESSION['seed'] = sha1($v, true); if (!isset($_SESSION['count'])) { $_SESSION['count'] = 0; } $_SESSION['count']++; session_write_close(); // restore old session data if ($old_session_id != '') { session_id($old_session_id); session_start(); ini_set('session.use_cookies', $old_use_cookies); session_cache_limiter($old_session_cache_limiter); } else { if ($_OLD_SESSION !== false) { $_SESSION = $_OLD_SESSION; unset($_OLD_SESSION); } else { unset($_SESSION); } } // in SSH2 a shared secret and an exchange hash are generated through the key exchange process. // the IV client to server is the hash of that "nonce" with the letter A and for the encryption key it's the letter C. // if the hash doesn't produce enough a key or an IV that's long enough concat successive hashes of the // original hash and the current hash. we'll be emulating that. for more info see the following URL: // // http://tools.ietf.org/html/rfc4253#section-7.2 // // see the is_string($crypto) part for an example of how to expand the keys $key = sha1($seed . 'A', true); $iv = sha1($seed . 'C', true); // ciphers are used as per the nist.gov link below. also, see this link: // // http://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator#Designs_based_on_cryptographic_primitives switch (true) { case class_exists('\phpseclib3\Crypt\AES'): $crypto = new AES('ctr'); break; case class_exists('\phpseclib3\Crypt\Twofish'): $crypto = new Twofish('ctr'); break; case class_exists('\phpseclib3\Crypt\Blowfish'): $crypto = new Blowfish('ctr'); break; case class_exists('\phpseclib3\Crypt\TripleDES'): $crypto = new TripleDES('ctr'); break; case class_exists('\phpseclib3\Crypt\DES'): $crypto = new DES('ctr'); break; case class_exists('\phpseclib3\Crypt\RC4'): $crypto = new RC4(); break; default: throw new \RuntimeException(__CLASS__ . ' requires at least one symmetric cipher be loaded'); } $crypto->setKey(substr($key, 0, $crypto->getKeyLength() >> 3)); $crypto->setIV(substr($iv, 0, $crypto->getBlockLength() >> 3)); $crypto->enableContinuousBuffer(); } //return $crypto->encrypt(str_repeat("\0", $length)); // the following is based off of ANSI X9.31: // // http://csrc.nist.gov/groups/STM/cavp/documents/rng/931rngext.pdf // // OpenSSL uses that same standard for it's random numbers: // // http://www.opensource.apple.com/source/OpenSSL/OpenSSL-38/openssl/fips-1.0/rand/fips_rand.c // (do a search for "ANS X9.31 A.2.4") $result = ''; while (strlen($result) < $length) { $i = $crypto->encrypt(microtime()); // strlen(microtime()) == 21 $r = $crypto->encrypt($i ^ $v); // strlen($v) == 20 $v = $crypto->encrypt($r ^ $i); // strlen($r) == 20 $result .= $r; } return substr($result, 0, $length); } /** * Safely serialize variables * * If a class has a private __sleep() it'll emit a warning * @return mixed * @param mixed $arr */ private static function safe_serialize(&$arr) { if (is_object($arr)) { return ''; } if (!is_array($arr)) { return serialize($arr); } // prevent circular array recursion if (isset($arr['__phpseclib_marker'])) { return ''; } $safearr = []; $arr['__phpseclib_marker'] = true; foreach (array_keys($arr) as $key) { // do not recurse on the '__phpseclib_marker' key itself, for smaller memory usage if ($key !== '__phpseclib_marker') { $safearr[$key] = self::safe_serialize($arr[$key]); } } unset($arr['__phpseclib_marker']); return serialize($safearr); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php ================================================ * setKey('abcdefghijklmnop'); * * $size = 10 * 1024; * $plaintext = ''; * for ($i = 0; $i < $size; $i++) { * $plaintext.= 'a'; * } * * echo $rijndael->decrypt($rijndael->encrypt($plaintext)); * ?> * * * @author Jim Wigginton * @copyright 2008 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt; use phpseclib3\Common\Functions\Strings; use phpseclib3\Crypt\Common\BlockCipher; use phpseclib3\Exception\BadDecryptionException; use phpseclib3\Exception\BadModeException; use phpseclib3\Exception\InconsistentSetupException; use phpseclib3\Exception\InsufficientSetupException; /** * Pure-PHP implementation of Rijndael. * * @author Jim Wigginton */ class Rijndael extends BlockCipher { /** * The mcrypt specific name of the cipher * * Mcrypt is useable for 128/192/256-bit $block_size/$key_length. For 160/224 not. * \phpseclib3\Crypt\Rijndael determines automatically whether mcrypt is useable * or not for the current $block_size/$key_length. * In case of, $cipher_name_mcrypt will be set dynamically at run time accordingly. * * @see Common\SymmetricKey::cipher_name_mcrypt * @see Common\SymmetricKey::engine * @see self::isValidEngine() * @var string */ protected $cipher_name_mcrypt = 'rijndael-128'; /** * The Key Schedule * * @see self::setup() * @var array */ private $w; /** * The Inverse Key Schedule * * @see self::setup() * @var array */ private $dw; /** * The Block Length divided by 32 * * {@internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4. Exists in conjunction with $block_size * because the encryption / decryption / key schedule creation requires this number and not $block_size. We could * derive this from $block_size or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu * of that, we'll just precompute it once.} * * @see self::setBlockLength() * @var int */ private $Nb = 4; /** * The Key Length (in bytes) * * {@internal The max value is 256 / 8 = 32, the min value is 128 / 8 = 16. Exists in conjunction with $Nk * because the encryption / decryption / key schedule creation requires this number and not $key_length. We could * derive this from $key_length or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu * of that, we'll just precompute it once.} * * @see self::setKeyLength() * @var int */ protected $key_length = 16; /** * The Key Length divided by 32 * * @see self::setKeyLength() * @var int * @internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4 */ private $Nk = 4; /** * The Number of Rounds * * {@internal The max value is 14, the min value is 10.} * * @var int */ private $Nr; /** * Shift offsets * * @var array */ private $c; /** * Holds the last used key- and block_size information * * @var array */ private $kl; /** * Default Constructor. * * @param string $mode * @throws \InvalidArgumentException if an invalid / unsupported mode is provided */ public function __construct($mode) { parent::__construct($mode); if ($this->mode == self::MODE_STREAM) { throw new BadModeException('Block ciphers cannot be ran in stream mode'); } } /** * Sets the key length. * * Valid key lengths are 128, 160, 192, 224, and 256. * * Note: phpseclib extends Rijndael (and AES) for using 160- and 224-bit keys but they are officially not defined * and the most (if not all) implementations are not able using 160/224-bit keys but round/pad them up to * 192/256 bits as, for example, mcrypt will do. * * That said, if you want be compatible with other Rijndael and AES implementations, * you should not setKeyLength(160) or setKeyLength(224). * * Additional: In case of 160- and 224-bit keys, phpseclib will/can, for that reason, not use * the mcrypt php extension, even if available. * This results then in slower encryption. * * @throws \LengthException if the key length is invalid * @param int $length */ public function setKeyLength($length) { switch ($length) { case 128: case 160: case 192: case 224: case 256: $this->key_length = $length >> 3; break; default: throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes 128, 160, 192, 224 or 256 bits are supported'); } parent::setKeyLength($length); } /** * Sets the key. * * Rijndael supports five different key lengths * * @see setKeyLength() * @param string $key * @throws \LengthException if the key length isn't supported */ public function setKey($key) { switch (strlen($key)) { case 16: case 20: case 24: case 28: case 32: break; default: throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 20, 24, 28 or 32 are supported'); } parent::setKey($key); } /** * Sets the block length * * Valid block lengths are 128, 160, 192, 224, and 256. * * @param int $length */ public function setBlockLength($length) { switch ($length) { case 128: case 160: case 192: case 224: case 256: break; default: throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes 128, 160, 192, 224 or 256 bits are supported'); } $this->Nb = $length >> 5; $this->block_size = $length >> 3; $this->changed = $this->nonIVChanged = true; $this->setEngine(); } /** * Test for engine validity * * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() * * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() * @param int $engine * @return bool */ protected function isValidEngineHelper($engine) { switch ($engine) { case self::ENGINE_LIBSODIUM: return function_exists('sodium_crypto_aead_aes256gcm_is_available') && sodium_crypto_aead_aes256gcm_is_available() && $this->mode == self::MODE_GCM && $this->key_length == 32 && $this->nonce && strlen($this->nonce) == 12 && $this->block_size == 16; case self::ENGINE_OPENSSL_GCM: if (!extension_loaded('openssl')) { return false; } $methods = openssl_get_cipher_methods(); return $this->mode == self::MODE_GCM && version_compare(PHP_VERSION, '7.1.0', '>=') && in_array('aes-' . $this->getKeyLength() . '-gcm', $methods) && $this->block_size == 16; case self::ENGINE_OPENSSL: if ($this->block_size != 16) { return false; } $this->cipher_name_openssl_ecb = 'aes-' . ($this->key_length << 3) . '-ecb'; $this->cipher_name_openssl = 'aes-' . ($this->key_length << 3) . '-' . $this->openssl_translate_mode(); break; case self::ENGINE_MCRYPT: $this->cipher_name_mcrypt = 'rijndael-' . ($this->block_size << 3); if ($this->key_length % 8) { // is it a 160/224-bit key? // mcrypt is not usable for them, only for 128/192/256-bit keys return false; } } return parent::isValidEngineHelper($engine); } /** * Encrypts a block * * @param string $in * @return string */ protected function encryptBlock($in) { static $tables; if (empty($tables)) { $tables = &$this->getTables(); } $t0 = $tables[0]; $t1 = $tables[1]; $t2 = $tables[2]; $t3 = $tables[3]; $sbox = $tables[4]; $state = []; $words = unpack('N*', $in); $c = $this->c; $w = $this->w; $Nb = $this->Nb; $Nr = $this->Nr; // addRoundKey $wc = $Nb - 1; foreach ($words as $word) { $state[] = $word ^ $w[++$wc]; } // fips-197.pdf#page=19, "Figure 5. Pseudo Code for the Cipher", states that this loop has four components - // subBytes, shiftRows, mixColumns, and addRoundKey. fips-197.pdf#page=30, "Implementation Suggestions Regarding // Various Platforms" suggests that performs enhanced implementations are described in Rijndael-ammended.pdf. // Rijndael-ammended.pdf#page=20, "Implementation aspects / 32-bit processor", discusses such an optimization. // Unfortunately, the description given there is not quite correct. Per aes.spec.v316.pdf#page=19 [1], // equation (7.4.7) is supposed to use addition instead of subtraction, so we'll do that here, as well. // [1] http://fp.gladman.plus.com/cryptography_technology/rijndael/aes.spec.v316.pdf $temp = []; for ($round = 1; $round < $Nr; ++$round) { $i = 0; // $c[0] == 0 $j = $c[1]; $k = $c[2]; $l = $c[3]; while ($i < $Nb) { $temp[$i] = $t0[$state[$i] >> 24 & 0x000000FF] ^ $t1[$state[$j] >> 16 & 0x000000FF] ^ $t2[$state[$k] >> 8 & 0x000000FF] ^ $t3[$state[$l] & 0x000000FF] ^ $w[++$wc]; ++$i; $j = ($j + 1) % $Nb; $k = ($k + 1) % $Nb; $l = ($l + 1) % $Nb; } $state = $temp; } // subWord for ($i = 0; $i < $Nb; ++$i) { $state[$i] = $sbox[$state[$i] & 0x000000FF] | ($sbox[$state[$i] >> 8 & 0x000000FF] << 8) | ($sbox[$state[$i] >> 16 & 0x000000FF] << 16) | ($sbox[$state[$i] >> 24 & 0x000000FF] << 24); } // shiftRows + addRoundKey $i = 0; // $c[0] == 0 $j = $c[1]; $k = $c[2]; $l = $c[3]; while ($i < $Nb) { $temp[$i] = ($state[$i] & intval(0xFF000000)) ^ ($state[$j] & 0x00FF0000) ^ ($state[$k] & 0x0000FF00) ^ ($state[$l] & 0x000000FF) ^ $w[$i]; ++$i; $j = ($j + 1) % $Nb; $k = ($k + 1) % $Nb; $l = ($l + 1) % $Nb; } return pack('N*', ...$temp); } /** * Decrypts a block * * @param string $in * @return string */ protected function decryptBlock($in) { static $invtables; if (empty($invtables)) { $invtables = &$this->getInvTables(); } $dt0 = $invtables[0]; $dt1 = $invtables[1]; $dt2 = $invtables[2]; $dt3 = $invtables[3]; $isbox = $invtables[4]; $state = []; $words = unpack('N*', $in); $c = $this->c; $dw = $this->dw; $Nb = $this->Nb; $Nr = $this->Nr; // addRoundKey $wc = $Nb - 1; foreach ($words as $word) { $state[] = $word ^ $dw[++$wc]; } $temp = []; for ($round = $Nr - 1; $round > 0; --$round) { $i = 0; // $c[0] == 0 $j = $Nb - $c[1]; $k = $Nb - $c[2]; $l = $Nb - $c[3]; while ($i < $Nb) { $temp[$i] = $dt0[$state[$i] >> 24 & 0x000000FF] ^ $dt1[$state[$j] >> 16 & 0x000000FF] ^ $dt2[$state[$k] >> 8 & 0x000000FF] ^ $dt3[$state[$l] & 0x000000FF] ^ $dw[++$wc]; ++$i; $j = ($j + 1) % $Nb; $k = ($k + 1) % $Nb; $l = ($l + 1) % $Nb; } $state = $temp; } // invShiftRows + invSubWord + addRoundKey $i = 0; // $c[0] == 0 $j = $Nb - $c[1]; $k = $Nb - $c[2]; $l = $Nb - $c[3]; while ($i < $Nb) { $word = ($state[$i] & intval(0xFF000000)) | ($state[$j] & 0x00FF0000) | ($state[$k] & 0x0000FF00) | ($state[$l] & 0x000000FF); $temp[$i] = $dw[$i] ^ ($isbox[$word & 0x000000FF] | ($isbox[$word >> 8 & 0x000000FF] << 8) | ($isbox[$word >> 16 & 0x000000FF] << 16) | ($isbox[$word >> 24 & 0x000000FF] << 24)); ++$i; $j = ($j + 1) % $Nb; $k = ($k + 1) % $Nb; $l = ($l + 1) % $Nb; } return pack('N*', ...$temp); } /** * Setup the self::ENGINE_INTERNAL $engine * * (re)init, if necessary, the internal cipher $engine and flush all $buffers * Used (only) if $engine == self::ENGINE_INTERNAL * * _setup() will be called each time if $changed === true * typically this happens when using one or more of following public methods: * * - setKey() * * - setIV() * * - disableContinuousBuffer() * * - First run of encrypt() / decrypt() with no init-settings * * {@internal setup() is always called before en/decryption.} * * {@internal Could, but not must, extend by the child Crypt_* class} * * @see self::setKey() * @see self::setIV() * @see self::disableContinuousBuffer() */ protected function setup() { if (!$this->changed) { return; } parent::setup(); if (is_string($this->iv) && strlen($this->iv) != $this->block_size) { throw new InconsistentSetupException('The IV length (' . strlen($this->iv) . ') does not match the block size (' . $this->block_size . ')'); } } /** * Setup the key (expansion) * * @see \phpseclib3\Crypt\Common\SymmetricKey::setupKey() */ protected function setupKey() { // Each number in $rcon is equal to the previous number multiplied by two in Rijndael's finite field. // See http://en.wikipedia.org/wiki/Finite_field_arithmetic#Multiplicative_inverse static $rcon; if (!isset($rcon)) { $rcon = [0, 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000, 0x6C000000, 0xD8000000, 0xAB000000, 0x4D000000, 0x9A000000, 0x2F000000, 0x5E000000, 0xBC000000, 0x63000000, 0xC6000000, 0x97000000, 0x35000000, 0x6A000000, 0xD4000000, 0xB3000000, 0x7D000000, 0xFA000000, 0xEF000000, 0xC5000000, 0x91000000 ]; $rcon = array_map('intval', $rcon); } if (isset($this->kl['key']) && $this->key === $this->kl['key'] && $this->key_length === $this->kl['key_length'] && $this->block_size === $this->kl['block_size']) { // already expanded return; } $this->kl = ['key' => $this->key, 'key_length' => $this->key_length, 'block_size' => $this->block_size]; $this->Nk = $this->key_length >> 2; // see Rijndael-ammended.pdf#page=44 $this->Nr = max($this->Nk, $this->Nb) + 6; // shift offsets for Nb = 5, 7 are defined in Rijndael-ammended.pdf#page=44, // "Table 8: Shift offsets in Shiftrow for the alternative block lengths" // shift offsets for Nb = 4, 6, 8 are defined in Rijndael-ammended.pdf#page=14, // "Table 2: Shift offsets for different block lengths" switch ($this->Nb) { case 4: case 5: case 6: $this->c = [0, 1, 2, 3]; break; case 7: $this->c = [0, 1, 2, 4]; break; case 8: $this->c = [0, 1, 3, 4]; } $w = array_values(unpack('N*words', $this->key)); $length = $this->Nb * ($this->Nr + 1); for ($i = $this->Nk; $i < $length; $i++) { $temp = $w[$i - 1]; if ($i % $this->Nk == 0) { // according to , "the size of an integer is platform-dependent". // on a 32-bit machine, it's 32-bits, and on a 64-bit machine, it's 64-bits. on a 32-bit machine, // 0xFFFFFFFF << 8 == 0xFFFFFF00, but on a 64-bit machine, it equals 0xFFFFFFFF00. as such, doing 'and' // with 0xFFFFFFFF (or 0xFFFFFF00) on a 32-bit machine is unnecessary, but on a 64-bit machine, it is. $temp = (($temp << 8) & intval(0xFFFFFF00)) | (($temp >> 24) & 0x000000FF); // rotWord $temp = $this->subWord($temp) ^ $rcon[$i / $this->Nk]; } elseif ($this->Nk > 6 && $i % $this->Nk == 4) { $temp = $this->subWord($temp); } $w[$i] = $w[$i - $this->Nk] ^ $temp; } // convert the key schedule from a vector of $Nb * ($Nr + 1) length to a matrix with $Nr + 1 rows and $Nb columns // and generate the inverse key schedule. more specifically, // according to (section 5.3.3), // "The key expansion for the Inverse Cipher is defined as follows: // 1. Apply the Key Expansion. // 2. Apply InvMixColumn to all Round Keys except the first and the last one." // also, see fips-197.pdf#page=27, "5.3.5 Equivalent Inverse Cipher" list($dt0, $dt1, $dt2, $dt3) = $this->getInvTables(); $temp = $this->w = $this->dw = []; for ($i = $row = $col = 0; $i < $length; $i++, $col++) { if ($col == $this->Nb) { if ($row == 0) { $this->dw[0] = $this->w[0]; } else { // subWord + invMixColumn + invSubWord = invMixColumn $j = 0; while ($j < $this->Nb) { $dw = $this->subWord($this->w[$row][$j]); $temp[$j] = $dt0[$dw >> 24 & 0x000000FF] ^ $dt1[$dw >> 16 & 0x000000FF] ^ $dt2[$dw >> 8 & 0x000000FF] ^ $dt3[$dw & 0x000000FF]; $j++; } $this->dw[$row] = $temp; } $col = 0; $row++; } $this->w[$row][$col] = $w[$i]; } $this->dw[$row] = $this->w[$row]; // Converting to 1-dim key arrays (both ascending) $this->dw = array_reverse($this->dw); $w = array_pop($this->w); $dw = array_pop($this->dw); foreach ($this->w as $r => $wr) { foreach ($wr as $c => $wc) { $w[] = $wc; $dw[] = $this->dw[$r][$c]; } } $this->w = $w; $this->dw = $dw; } /** * Performs S-Box substitutions * * @return array * @param int $word */ private function subWord($word) { static $sbox; if (empty($sbox)) { list(, , , , $sbox) = self::getTables(); } return $sbox[$word & 0x000000FF] | ($sbox[$word >> 8 & 0x000000FF] << 8) | ($sbox[$word >> 16 & 0x000000FF] << 16) | ($sbox[$word >> 24 & 0x000000FF] << 24); } /** * Provides the mixColumns and sboxes tables * * @see self::encryptBlock() * @see self::setupInlineCrypt() * @see self::subWord() * @return array &$tables */ protected function &getTables() { static $tables; if (empty($tables)) { // according to (section 5.2.1), // precomputed tables can be used in the mixColumns phase. in that example, they're assigned t0...t3, so // those are the names we'll use. $t3 = array_map('intval', [ // with array_map('intval', ...) we ensure we have only int's and not // some slower floats converted by php automatically on high values 0x6363A5C6, 0x7C7C84F8, 0x777799EE, 0x7B7B8DF6, 0xF2F20DFF, 0x6B6BBDD6, 0x6F6FB1DE, 0xC5C55491, 0x30305060, 0x01010302, 0x6767A9CE, 0x2B2B7D56, 0xFEFE19E7, 0xD7D762B5, 0xABABE64D, 0x76769AEC, 0xCACA458F, 0x82829D1F, 0xC9C94089, 0x7D7D87FA, 0xFAFA15EF, 0x5959EBB2, 0x4747C98E, 0xF0F00BFB, 0xADADEC41, 0xD4D467B3, 0xA2A2FD5F, 0xAFAFEA45, 0x9C9CBF23, 0xA4A4F753, 0x727296E4, 0xC0C05B9B, 0xB7B7C275, 0xFDFD1CE1, 0x9393AE3D, 0x26266A4C, 0x36365A6C, 0x3F3F417E, 0xF7F702F5, 0xCCCC4F83, 0x34345C68, 0xA5A5F451, 0xE5E534D1, 0xF1F108F9, 0x717193E2, 0xD8D873AB, 0x31315362, 0x15153F2A, 0x04040C08, 0xC7C75295, 0x23236546, 0xC3C35E9D, 0x18182830, 0x9696A137, 0x05050F0A, 0x9A9AB52F, 0x0707090E, 0x12123624, 0x80809B1B, 0xE2E23DDF, 0xEBEB26CD, 0x2727694E, 0xB2B2CD7F, 0x75759FEA, 0x09091B12, 0x83839E1D, 0x2C2C7458, 0x1A1A2E34, 0x1B1B2D36, 0x6E6EB2DC, 0x5A5AEEB4, 0xA0A0FB5B, 0x5252F6A4, 0x3B3B4D76, 0xD6D661B7, 0xB3B3CE7D, 0x29297B52, 0xE3E33EDD, 0x2F2F715E, 0x84849713, 0x5353F5A6, 0xD1D168B9, 0x00000000, 0xEDED2CC1, 0x20206040, 0xFCFC1FE3, 0xB1B1C879, 0x5B5BEDB6, 0x6A6ABED4, 0xCBCB468D, 0xBEBED967, 0x39394B72, 0x4A4ADE94, 0x4C4CD498, 0x5858E8B0, 0xCFCF4A85, 0xD0D06BBB, 0xEFEF2AC5, 0xAAAAE54F, 0xFBFB16ED, 0x4343C586, 0x4D4DD79A, 0x33335566, 0x85859411, 0x4545CF8A, 0xF9F910E9, 0x02020604, 0x7F7F81FE, 0x5050F0A0, 0x3C3C4478, 0x9F9FBA25, 0xA8A8E34B, 0x5151F3A2, 0xA3A3FE5D, 0x4040C080, 0x8F8F8A05, 0x9292AD3F, 0x9D9DBC21, 0x38384870, 0xF5F504F1, 0xBCBCDF63, 0xB6B6C177, 0xDADA75AF, 0x21216342, 0x10103020, 0xFFFF1AE5, 0xF3F30EFD, 0xD2D26DBF, 0xCDCD4C81, 0x0C0C1418, 0x13133526, 0xECEC2FC3, 0x5F5FE1BE, 0x9797A235, 0x4444CC88, 0x1717392E, 0xC4C45793, 0xA7A7F255, 0x7E7E82FC, 0x3D3D477A, 0x6464ACC8, 0x5D5DE7BA, 0x19192B32, 0x737395E6, 0x6060A0C0, 0x81819819, 0x4F4FD19E, 0xDCDC7FA3, 0x22226644, 0x2A2A7E54, 0x9090AB3B, 0x8888830B, 0x4646CA8C, 0xEEEE29C7, 0xB8B8D36B, 0x14143C28, 0xDEDE79A7, 0x5E5EE2BC, 0x0B0B1D16, 0xDBDB76AD, 0xE0E03BDB, 0x32325664, 0x3A3A4E74, 0x0A0A1E14, 0x4949DB92, 0x06060A0C, 0x24246C48, 0x5C5CE4B8, 0xC2C25D9F, 0xD3D36EBD, 0xACACEF43, 0x6262A6C4, 0x9191A839, 0x9595A431, 0xE4E437D3, 0x79798BF2, 0xE7E732D5, 0xC8C8438B, 0x3737596E, 0x6D6DB7DA, 0x8D8D8C01, 0xD5D564B1, 0x4E4ED29C, 0xA9A9E049, 0x6C6CB4D8, 0x5656FAAC, 0xF4F407F3, 0xEAEA25CF, 0x6565AFCA, 0x7A7A8EF4, 0xAEAEE947, 0x08081810, 0xBABAD56F, 0x787888F0, 0x25256F4A, 0x2E2E725C, 0x1C1C2438, 0xA6A6F157, 0xB4B4C773, 0xC6C65197, 0xE8E823CB, 0xDDDD7CA1, 0x74749CE8, 0x1F1F213E, 0x4B4BDD96, 0xBDBDDC61, 0x8B8B860D, 0x8A8A850F, 0x707090E0, 0x3E3E427C, 0xB5B5C471, 0x6666AACC, 0x4848D890, 0x03030506, 0xF6F601F7, 0x0E0E121C, 0x6161A3C2, 0x35355F6A, 0x5757F9AE, 0xB9B9D069, 0x86869117, 0xC1C15899, 0x1D1D273A, 0x9E9EB927, 0xE1E138D9, 0xF8F813EB, 0x9898B32B, 0x11113322, 0x6969BBD2, 0xD9D970A9, 0x8E8E8907, 0x9494A733, 0x9B9BB62D, 0x1E1E223C, 0x87879215, 0xE9E920C9, 0xCECE4987, 0x5555FFAA, 0x28287850, 0xDFDF7AA5, 0x8C8C8F03, 0xA1A1F859, 0x89898009, 0x0D0D171A, 0xBFBFDA65, 0xE6E631D7, 0x4242C684, 0x6868B8D0, 0x4141C382, 0x9999B029, 0x2D2D775A, 0x0F0F111E, 0xB0B0CB7B, 0x5454FCA8, 0xBBBBD66D, 0x16163A2C ]); foreach ($t3 as $t3i) { $t0[] = (($t3i << 24) & intval(0xFF000000)) | (($t3i >> 8) & 0x00FFFFFF); $t1[] = (($t3i << 16) & intval(0xFFFF0000)) | (($t3i >> 16) & 0x0000FFFF); $t2[] = (($t3i << 8) & intval(0xFFFFFF00)) | (($t3i >> 24) & 0x000000FF); } $tables = [ // The Precomputed mixColumns tables t0 - t3 $t0, $t1, $t2, $t3, // The SubByte S-Box [ 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 ] ]; } return $tables; } /** * Provides the inverse mixColumns and inverse sboxes tables * * @see self::decryptBlock() * @see self::setupInlineCrypt() * @see self::setupKey() * @return array &$tables */ protected function &getInvTables() { static $tables; if (empty($tables)) { $dt3 = array_map('intval', [ 0xF4A75051, 0x4165537E, 0x17A4C31A, 0x275E963A, 0xAB6BCB3B, 0x9D45F11F, 0xFA58ABAC, 0xE303934B, 0x30FA5520, 0x766DF6AD, 0xCC769188, 0x024C25F5, 0xE5D7FC4F, 0x2ACBD7C5, 0x35448026, 0x62A38FB5, 0xB15A49DE, 0xBA1B6725, 0xEA0E9845, 0xFEC0E15D, 0x2F7502C3, 0x4CF01281, 0x4697A38D, 0xD3F9C66B, 0x8F5FE703, 0x929C9515, 0x6D7AEBBF, 0x5259DA95, 0xBE832DD4, 0x7421D358, 0xE0692949, 0xC9C8448E, 0xC2896A75, 0x8E7978F4, 0x583E6B99, 0xB971DD27, 0xE14FB6BE, 0x88AD17F0, 0x20AC66C9, 0xCE3AB47D, 0xDF4A1863, 0x1A3182E5, 0x51336097, 0x537F4562, 0x6477E0B1, 0x6BAE84BB, 0x81A01CFE, 0x082B94F9, 0x48685870, 0x45FD198F, 0xDE6C8794, 0x7BF8B752, 0x73D323AB, 0x4B02E272, 0x1F8F57E3, 0x55AB2A66, 0xEB2807B2, 0xB5C2032F, 0xC57B9A86, 0x3708A5D3, 0x2887F230, 0xBFA5B223, 0x036ABA02, 0x16825CED, 0xCF1C2B8A, 0x79B492A7, 0x07F2F0F3, 0x69E2A14E, 0xDAF4CD65, 0x05BED506, 0x34621FD1, 0xA6FE8AC4, 0x2E539D34, 0xF355A0A2, 0x8AE13205, 0xF6EB75A4, 0x83EC390B, 0x60EFAA40, 0x719F065E, 0x6E1051BD, 0x218AF93E, 0xDD063D96, 0x3E05AEDD, 0xE6BD464D, 0x548DB591, 0xC45D0571, 0x06D46F04, 0x5015FF60, 0x98FB2419, 0xBDE997D6, 0x4043CC89, 0xD99E7767, 0xE842BDB0, 0x898B8807, 0x195B38E7, 0xC8EEDB79, 0x7C0A47A1, 0x420FE97C, 0x841EC9F8, 0x00000000, 0x80868309, 0x2BED4832, 0x1170AC1E, 0x5A724E6C, 0x0EFFFBFD, 0x8538560F, 0xAED51E3D, 0x2D392736, 0x0FD9640A, 0x5CA62168, 0x5B54D19B, 0x362E3A24, 0x0A67B10C, 0x57E70F93, 0xEE96D2B4, 0x9B919E1B, 0xC0C54F80, 0xDC20A261, 0x774B695A, 0x121A161C, 0x93BA0AE2, 0xA02AE5C0, 0x22E0433C, 0x1B171D12, 0x090D0B0E, 0x8BC7ADF2, 0xB6A8B92D, 0x1EA9C814, 0xF1198557, 0x75074CAF, 0x99DDBBEE, 0x7F60FDA3, 0x01269FF7, 0x72F5BC5C, 0x663BC544, 0xFB7E345B, 0x4329768B, 0x23C6DCCB, 0xEDFC68B6, 0xE4F163B8, 0x31DCCAD7, 0x63851042, 0x97224013, 0xC6112084, 0x4A247D85, 0xBB3DF8D2, 0xF93211AE, 0x29A16DC7, 0x9E2F4B1D, 0xB230F3DC, 0x8652EC0D, 0xC1E3D077, 0xB3166C2B, 0x70B999A9, 0x9448FA11, 0xE9642247, 0xFC8CC4A8, 0xF03F1AA0, 0x7D2CD856, 0x3390EF22, 0x494EC787, 0x38D1C1D9, 0xCAA2FE8C, 0xD40B3698, 0xF581CFA6, 0x7ADE28A5, 0xB78E26DA, 0xADBFA43F, 0x3A9DE42C, 0x78920D50, 0x5FCC9B6A, 0x7E466254, 0x8D13C2F6, 0xD8B8E890, 0x39F75E2E, 0xC3AFF582, 0x5D80BE9F, 0xD0937C69, 0xD52DA96F, 0x2512B3CF, 0xAC993BC8, 0x187DA710, 0x9C636EE8, 0x3BBB7BDB, 0x267809CD, 0x5918F46E, 0x9AB701EC, 0x4F9AA883, 0x956E65E6, 0xFFE67EAA, 0xBCCF0821, 0x15E8E6EF, 0xE79BD9BA, 0x6F36CE4A, 0x9F09D4EA, 0xB07CD629, 0xA4B2AF31, 0x3F23312A, 0xA59430C6, 0xA266C035, 0x4EBC3774, 0x82CAA6FC, 0x90D0B0E0, 0xA7D81533, 0x04984AF1, 0xECDAF741, 0xCD500E7F, 0x91F62F17, 0x4DD68D76, 0xEFB04D43, 0xAA4D54CC, 0x9604DFE4, 0xD1B5E39E, 0x6A881B4C, 0x2C1FB8C1, 0x65517F46, 0x5EEA049D, 0x8C355D01, 0x877473FA, 0x0B412EFB, 0x671D5AB3, 0xDBD25292, 0x105633E9, 0xD647136D, 0xD7618C9A, 0xA10C7A37, 0xF8148E59, 0x133C89EB, 0xA927EECE, 0x61C935B7, 0x1CE5EDE1, 0x47B13C7A, 0xD2DF599C, 0xF2733F55, 0x14CE7918, 0xC737BF73, 0xF7CDEA53, 0xFDAA5B5F, 0x3D6F14DF, 0x44DB8678, 0xAFF381CA, 0x68C43EB9, 0x24342C38, 0xA3405FC2, 0x1DC37216, 0xE2250CBC, 0x3C498B28, 0x0D9541FF, 0xA8017139, 0x0CB3DE08, 0xB4E49CD8, 0x56C19064, 0xCB84617B, 0x32B670D5, 0x6C5C7448, 0xB85742D0 ]); foreach ($dt3 as $dt3i) { $dt0[] = (($dt3i << 24) & intval(0xFF000000)) | (($dt3i >> 8) & 0x00FFFFFF); $dt1[] = (($dt3i << 16) & intval(0xFFFF0000)) | (($dt3i >> 16) & 0x0000FFFF); $dt2[] = (($dt3i << 8) & intval(0xFFFFFF00)) | (($dt3i >> 24) & 0x000000FF); }; $tables = [ // The Precomputed inverse mixColumns tables dt0 - dt3 $dt0, $dt1, $dt2, $dt3, // The inverse SubByte S-Box [ 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D ] ]; } return $tables; } /** * Setup the performance-optimized function for de/encrypt() * * @see \phpseclib3\Crypt\Common\SymmetricKey::setupInlineCrypt() */ protected function setupInlineCrypt() { $w = $this->w; $dw = $this->dw; $init_encrypt = ''; $init_decrypt = ''; $Nr = $this->Nr; $Nb = $this->Nb; $c = $this->c; // Generating encrypt code: $init_encrypt .= ' if (empty($tables)) { $tables = &$this->getTables(); } $t0 = $tables[0]; $t1 = $tables[1]; $t2 = $tables[2]; $t3 = $tables[3]; $sbox = $tables[4]; '; $s = 'e'; $e = 's'; $wc = $Nb - 1; // Preround: addRoundKey $encrypt_block = '$in = unpack("N*", $in);' . "\n"; for ($i = 0; $i < $Nb; ++$i) { $encrypt_block .= '$s' . $i . ' = $in[' . ($i + 1) . '] ^ ' . $w[++$wc] . ";\n"; } // Mainrounds: shiftRows + subWord + mixColumns + addRoundKey for ($round = 1; $round < $Nr; ++$round) { list($s, $e) = [$e, $s]; for ($i = 0; $i < $Nb; ++$i) { $encrypt_block .= '$' . $e . $i . ' = $t0[($' . $s . $i . ' >> 24) & 0xff] ^ $t1[($' . $s . (($i + $c[1]) % $Nb) . ' >> 16) & 0xff] ^ $t2[($' . $s . (($i + $c[2]) % $Nb) . ' >> 8) & 0xff] ^ $t3[ $' . $s . (($i + $c[3]) % $Nb) . ' & 0xff] ^ ' . $w[++$wc] . ";\n"; } } // Finalround: subWord + shiftRows + addRoundKey for ($i = 0; $i < $Nb; ++$i) { $encrypt_block .= '$' . $e . $i . ' = $sbox[ $' . $e . $i . ' & 0xff] | ($sbox[($' . $e . $i . ' >> 8) & 0xff] << 8) | ($sbox[($' . $e . $i . ' >> 16) & 0xff] << 16) | ($sbox[($' . $e . $i . ' >> 24) & 0xff] << 24);' . "\n"; } $encrypt_block .= '$in = pack("N*"' . "\n"; for ($i = 0; $i < $Nb; ++$i) { $encrypt_block .= ', ($' . $e . $i . ' & ' . ((int)0xFF000000) . ') ^ ($' . $e . (($i + $c[1]) % $Nb) . ' & 0x00FF0000 ) ^ ($' . $e . (($i + $c[2]) % $Nb) . ' & 0x0000FF00 ) ^ ($' . $e . (($i + $c[3]) % $Nb) . ' & 0x000000FF ) ^ ' . $w[$i] . "\n"; } $encrypt_block .= ');'; // Generating decrypt code: $init_decrypt .= ' if (empty($invtables)) { $invtables = &$this->getInvTables(); } $dt0 = $invtables[0]; $dt1 = $invtables[1]; $dt2 = $invtables[2]; $dt3 = $invtables[3]; $isbox = $invtables[4]; '; $s = 'e'; $e = 's'; $wc = $Nb - 1; // Preround: addRoundKey $decrypt_block = '$in = unpack("N*", $in);' . "\n"; for ($i = 0; $i < $Nb; ++$i) { $decrypt_block .= '$s' . $i . ' = $in[' . ($i + 1) . '] ^ ' . $dw[++$wc] . ';' . "\n"; } // Mainrounds: shiftRows + subWord + mixColumns + addRoundKey for ($round = 1; $round < $Nr; ++$round) { list($s, $e) = [$e, $s]; for ($i = 0; $i < $Nb; ++$i) { $decrypt_block .= '$' . $e . $i . ' = $dt0[($' . $s . $i . ' >> 24) & 0xff] ^ $dt1[($' . $s . (($Nb + $i - $c[1]) % $Nb) . ' >> 16) & 0xff] ^ $dt2[($' . $s . (($Nb + $i - $c[2]) % $Nb) . ' >> 8) & 0xff] ^ $dt3[ $' . $s . (($Nb + $i - $c[3]) % $Nb) . ' & 0xff] ^ ' . $dw[++$wc] . ";\n"; } } // Finalround: subWord + shiftRows + addRoundKey for ($i = 0; $i < $Nb; ++$i) { $decrypt_block .= '$' . $e . $i . ' = $isbox[ $' . $e . $i . ' & 0xff] | ($isbox[($' . $e . $i . ' >> 8) & 0xff] << 8) | ($isbox[($' . $e . $i . ' >> 16) & 0xff] << 16) | ($isbox[($' . $e . $i . ' >> 24) & 0xff] << 24);' . "\n"; } $decrypt_block .= '$in = pack("N*"' . "\n"; for ($i = 0; $i < $Nb; ++$i) { $decrypt_block .= ', ($' . $e . $i . ' & ' . ((int)0xFF000000) . ') ^ ($' . $e . (($Nb + $i - $c[1]) % $Nb) . ' & 0x00FF0000 ) ^ ($' . $e . (($Nb + $i - $c[2]) % $Nb) . ' & 0x0000FF00 ) ^ ($' . $e . (($Nb + $i - $c[3]) % $Nb) . ' & 0x000000FF ) ^ ' . $dw[$i] . "\n"; } $decrypt_block .= ');'; $this->inline_crypt = $this->createInlineCryptFunction( [ 'init_crypt' => 'static $tables; static $invtables;', 'init_encrypt' => $init_encrypt, 'init_decrypt' => $init_decrypt, 'encrypt_block' => $encrypt_block, 'decrypt_block' => $decrypt_block ] ); } /** * Encrypts a message. * * @see self::decrypt() * @see parent::encrypt() * @param string $plaintext * @return string */ public function encrypt($plaintext) { $this->setup(); switch ($this->engine) { case self::ENGINE_LIBSODIUM: $this->newtag = sodium_crypto_aead_aes256gcm_encrypt($plaintext, $this->aad, $this->nonce, $this->key); return Strings::shift($this->newtag, strlen($plaintext)); case self::ENGINE_OPENSSL_GCM: return openssl_encrypt( $plaintext, 'aes-' . $this->getKeyLength() . '-gcm', $this->key, OPENSSL_RAW_DATA, $this->nonce, $this->newtag, $this->aad ); } return parent::encrypt($plaintext); } /** * Decrypts a message. * * @see self::encrypt() * @see parent::decrypt() * @param string $ciphertext * @return string */ public function decrypt($ciphertext) { $this->setup(); switch ($this->engine) { case self::ENGINE_LIBSODIUM: if ($this->oldtag === false) { throw new InsufficientSetupException('Authentication Tag has not been set'); } if (strlen($this->oldtag) != 16) { break; } $plaintext = sodium_crypto_aead_aes256gcm_decrypt($ciphertext . $this->oldtag, $this->aad, $this->nonce, $this->key); if ($plaintext === false) { $this->oldtag = false; throw new BadDecryptionException('Error decrypting ciphertext with libsodium'); } return $plaintext; case self::ENGINE_OPENSSL_GCM: if ($this->oldtag === false) { throw new InsufficientSetupException('Authentication Tag has not been set'); } $plaintext = openssl_decrypt( $ciphertext, 'aes-' . $this->getKeyLength() . '-gcm', $this->key, OPENSSL_RAW_DATA, $this->nonce, $this->oldtag, $this->aad ); if ($plaintext === false) { $this->oldtag = false; throw new BadDecryptionException('Error decrypting ciphertext with OpenSSL'); } return $plaintext; } return parent::decrypt($ciphertext); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/Salsa20.php ================================================ * @copyright 2019 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt; use phpseclib3\Common\Functions\Strings; use phpseclib3\Crypt\Common\StreamCipher; use phpseclib3\Exception\BadDecryptionException; use phpseclib3\Exception\InsufficientSetupException; /** * Pure-PHP implementation of Salsa20. * * @author Jim Wigginton */ class Salsa20 extends StreamCipher { /** * Part 1 of the state * * @var string|false */ protected $p1 = false; /** * Part 2 of the state * * @var string|false */ protected $p2 = false; /** * Key Length (in bytes) * * @var int */ protected $key_length = 32; // = 256 bits /** * @see \phpseclib3\Crypt\Salsa20::crypt() */ const ENCRYPT = 0; /** * @see \phpseclib3\Crypt\Salsa20::crypt() */ const DECRYPT = 1; /** * Encryption buffer for continuous mode * * @var array */ protected $enbuffer; /** * Decryption buffer for continuous mode * * @var array */ protected $debuffer; /** * Counter * * @var int */ protected $counter = 0; /** * Using Generated Poly1305 Key * * @var boolean */ protected $usingGeneratedPoly1305Key = false; /** * Salsa20 uses a nonce * * @return bool */ public function usesNonce() { return true; } /** * Sets the key. * * @param string $key * @throws \LengthException if the key length isn't supported */ public function setKey($key) { switch (strlen($key)) { case 16: case 32: break; default: throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16 or 32 are supported'); } parent::setKey($key); } /** * Sets the nonce. * * @param string $nonce */ public function setNonce($nonce) { if (strlen($nonce) != 8) { throw new \LengthException('Nonce of size ' . strlen($key) . ' not supported by this algorithm. Only an 64-bit nonce is supported'); } $this->nonce = $nonce; $this->changed = true; $this->setEngine(); } /** * Sets the counter. * * @param int $counter */ public function setCounter($counter) { $this->counter = $counter; $this->setEngine(); } /** * Creates a Poly1305 key using the method discussed in RFC8439 * * See https://tools.ietf.org/html/rfc8439#section-2.6.1 */ protected function createPoly1305Key() { if ($this->nonce === false) { throw new InsufficientSetupException('No nonce has been defined'); } if ($this->key === false) { throw new InsufficientSetupException('No key has been defined'); } $c = clone $this; $c->setCounter(0); $c->usePoly1305 = false; $block = $c->encrypt(str_repeat("\0", 256)); $this->setPoly1305Key(substr($block, 0, 32)); if ($this->counter == 0) { $this->counter++; } } /** * Setup the self::ENGINE_INTERNAL $engine * * (re)init, if necessary, the internal cipher $engine * * _setup() will be called each time if $changed === true * typically this happens when using one or more of following public methods: * * - setKey() * * - setNonce() * * - First run of encrypt() / decrypt() with no init-settings * * @see self::setKey() * @see self::setNonce() * @see self::disableContinuousBuffer() */ protected function setup() { if (!$this->changed) { return; } $this->enbuffer = $this->debuffer = ['ciphertext' => '', 'counter' => $this->counter]; $this->changed = $this->nonIVChanged = false; if ($this->nonce === false) { throw new InsufficientSetupException('No nonce has been defined'); } if ($this->key === false) { throw new InsufficientSetupException('No key has been defined'); } if ($this->usePoly1305 && !isset($this->poly1305Key)) { $this->usingGeneratedPoly1305Key = true; $this->createPoly1305Key(); } $key = $this->key; if (strlen($key) == 16) { $constant = 'expand 16-byte k'; $key .= $key; } else { $constant = 'expand 32-byte k'; } $this->p1 = substr($constant, 0, 4) . substr($key, 0, 16) . substr($constant, 4, 4) . $this->nonce . "\0\0\0\0"; $this->p2 = substr($constant, 8, 4) . substr($key, 16, 16) . substr($constant, 12, 4); } /** * Setup the key (expansion) */ protected function setupKey() { // Salsa20 does not utilize this method } /** * Encrypts a message. * * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() * @see self::crypt() * @param string $plaintext * @return string $ciphertext */ public function encrypt($plaintext) { $ciphertext = $this->crypt($plaintext, self::ENCRYPT); if (isset($this->poly1305Key)) { $this->newtag = $this->poly1305($ciphertext); } return $ciphertext; } /** * Decrypts a message. * * $this->decrypt($this->encrypt($plaintext)) == $this->encrypt($this->encrypt($plaintext)). * At least if the continuous buffer is disabled. * * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() * @see self::crypt() * @param string $ciphertext * @return string $plaintext */ public function decrypt($ciphertext) { if (isset($this->poly1305Key)) { if ($this->oldtag === false) { throw new InsufficientSetupException('Authentication Tag has not been set'); } $newtag = $this->poly1305($ciphertext); if ($this->oldtag != substr($newtag, 0, strlen($this->oldtag))) { $this->oldtag = false; throw new BadDecryptionException('Derived authentication tag and supplied authentication tag do not match'); } $this->oldtag = false; } return $this->crypt($ciphertext, self::DECRYPT); } /** * Encrypts a block * * @param string $in */ protected function encryptBlock($in) { // Salsa20 does not utilize this method } /** * Decrypts a block * * @param string $in */ protected function decryptBlock($in) { // Salsa20 does not utilize this method } /** * Encrypts or decrypts a message. * * @see self::encrypt() * @see self::decrypt() * @param string $text * @param int $mode * @return string $text */ private function crypt($text, $mode) { $this->setup(); if (!$this->continuousBuffer) { if ($this->engine == self::ENGINE_OPENSSL) { $iv = pack('V', $this->counter) . $this->p2; return openssl_encrypt( $text, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA, $iv ); } $i = $this->counter; $blocks = str_split($text, 64); foreach ($blocks as &$block) { $block ^= static::salsa20($this->p1 . pack('V', $i++) . $this->p2); } unset($block); return implode('', $blocks); } if ($mode == self::ENCRYPT) { $buffer = &$this->enbuffer; } else { $buffer = &$this->debuffer; } if (!strlen($buffer['ciphertext'])) { $ciphertext = ''; } else { $ciphertext = $text ^ Strings::shift($buffer['ciphertext'], strlen($text)); $text = substr($text, strlen($ciphertext)); if (!strlen($text)) { return $ciphertext; } } $overflow = strlen($text) % 64; // & 0x3F if ($overflow) { $text2 = Strings::pop($text, $overflow); if ($this->engine == self::ENGINE_OPENSSL) { $iv = pack('V', $buffer['counter']) . $this->p2; // at this point $text should be a multiple of 64 $buffer['counter'] += (strlen($text) >> 6) + 1; // ie. divide by 64 $encrypted = openssl_encrypt( $text . str_repeat("\0", 64), $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA, $iv ); $temp = Strings::pop($encrypted, 64); } else { $blocks = str_split($text, 64); if (strlen($text)) { foreach ($blocks as &$block) { $block ^= static::salsa20($this->p1 . pack('V', $buffer['counter']++) . $this->p2); } unset($block); } $encrypted = implode('', $blocks); $temp = static::salsa20($this->p1 . pack('V', $buffer['counter']++) . $this->p2); } $ciphertext .= $encrypted . ($text2 ^ $temp); $buffer['ciphertext'] = substr($temp, $overflow); } elseif (!strlen($buffer['ciphertext'])) { if ($this->engine == self::ENGINE_OPENSSL) { $iv = pack('V', $buffer['counter']) . $this->p2; $buffer['counter'] += (strlen($text) >> 6); $ciphertext .= openssl_encrypt( $text, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA, $iv ); } else { $blocks = str_split($text, 64); foreach ($blocks as &$block) { $block ^= static::salsa20($this->p1 . pack('V', $buffer['counter']++) . $this->p2); } unset($block); $ciphertext .= implode('', $blocks); } } return $ciphertext; } /** * Left Rotate * * @param int $x * @param int $n * @return int */ protected static function leftRotate($x, $n) { if (PHP_INT_SIZE == 8) { $r1 = $x << $n; $r1 &= 0xFFFFFFFF; $r2 = ($x & 0xFFFFFFFF) >> (32 - $n); } else { $x = (int) $x; $r1 = $x << $n; $r2 = $x >> (32 - $n); $r2 &= (1 << $n) - 1; } return $r1 | $r2; } /** * The quarterround function * * @param int $a * @param int $b * @param int $c * @param int $d */ protected static function quarterRound(&$a, &$b, &$c, &$d) { $b ^= self::leftRotate($a + $d, 7); $c ^= self::leftRotate($b + $a, 9); $d ^= self::leftRotate($c + $b, 13); $a ^= self::leftRotate($d + $c, 18); } /** * The doubleround function * * @param int $x0 (by reference) * @param int $x1 (by reference) * @param int $x2 (by reference) * @param int $x3 (by reference) * @param int $x4 (by reference) * @param int $x5 (by reference) * @param int $x6 (by reference) * @param int $x7 (by reference) * @param int $x8 (by reference) * @param int $x9 (by reference) * @param int $x10 (by reference) * @param int $x11 (by reference) * @param int $x12 (by reference) * @param int $x13 (by reference) * @param int $x14 (by reference) * @param int $x15 (by reference) */ protected static function doubleRound(&$x0, &$x1, &$x2, &$x3, &$x4, &$x5, &$x6, &$x7, &$x8, &$x9, &$x10, &$x11, &$x12, &$x13, &$x14, &$x15) { // columnRound static::quarterRound($x0, $x4, $x8, $x12); static::quarterRound($x5, $x9, $x13, $x1); static::quarterRound($x10, $x14, $x2, $x6); static::quarterRound($x15, $x3, $x7, $x11); // rowRound static::quarterRound($x0, $x1, $x2, $x3); static::quarterRound($x5, $x6, $x7, $x4); static::quarterRound($x10, $x11, $x8, $x9); static::quarterRound($x15, $x12, $x13, $x14); } /** * The Salsa20 hash function function * * @param string $x */ protected static function salsa20($x) { $z = $x = unpack('V*', $x); for ($i = 0; $i < 10; $i++) { static::doubleRound($z[1], $z[2], $z[3], $z[4], $z[5], $z[6], $z[7], $z[8], $z[9], $z[10], $z[11], $z[12], $z[13], $z[14], $z[15], $z[16]); } for ($i = 1; $i <= 16; $i++) { $x[$i] += $z[$i]; } return pack('V*', ...$x); } /** * Calculates Poly1305 MAC * * @see self::decrypt() * @see self::encrypt() * @param string $ciphertext * @return string */ protected function poly1305($ciphertext) { if (!$this->usingGeneratedPoly1305Key) { return parent::poly1305($this->aad . $ciphertext); } else { /* sodium_crypto_aead_chacha20poly1305_encrypt does not calculate the poly1305 tag the same way sodium_crypto_aead_chacha20poly1305_ietf_encrypt does. you can see how the latter encrypts it in Salsa20::encrypt(). here's how the former encrypts it: $this->newtag = $this->poly1305( $this->aad . pack('V', strlen($this->aad)) . "\0\0\0\0" . $ciphertext . pack('V', strlen($ciphertext)) . "\0\0\0\0" ); phpseclib opts to use the IETF construction, even when the nonce is 64-bits instead of 96-bits */ return parent::poly1305( self::nullPad128($this->aad) . self::nullPad128($ciphertext) . pack('V', strlen($this->aad)) . "\0\0\0\0" . pack('V', strlen($ciphertext)) . "\0\0\0\0" ); } } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php ================================================ * setKey('abcdefghijklmnopqrstuvwx'); * * $size = 10 * 1024; * $plaintext = ''; * for ($i = 0; $i < $size; $i++) { * $plaintext.= 'a'; * } * * echo $des->decrypt($des->encrypt($plaintext)); * ?> * * * @author Jim Wigginton * @copyright 2007 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt; /** * Pure-PHP implementation of Triple DES. * * @author Jim Wigginton */ class TripleDES extends DES { /** * Encrypt / decrypt using inner chaining * * Inner chaining is used by SSH-1 and is generally considered to be less secure then outer chaining (self::MODE_CBC3). */ const MODE_3CBC = -2; /** * Encrypt / decrypt using outer chaining * * Outer chaining is used by SSH-2 and when the mode is set to \phpseclib3\Crypt\Common\BlockCipher::MODE_CBC. */ const MODE_CBC3 = self::MODE_CBC; /** * Key Length (in bytes) * * @see \phpseclib3\Crypt\TripleDES::setKeyLength() * @var int */ protected $key_length = 24; /** * The mcrypt specific name of the cipher * * @see DES::cipher_name_mcrypt * @see Common\SymmetricKey::cipher_name_mcrypt * @var string */ protected $cipher_name_mcrypt = 'tripledes'; /** * Optimizing value while CFB-encrypting * * @see Common\SymmetricKey::cfb_init_len * @var int */ protected $cfb_init_len = 750; /** * max possible size of $key * * @see self::setKey() * @see DES::setKey() * @var string */ protected $key_length_max = 24; /** * Internal flag whether using self::MODE_3CBC or not * * @var bool */ private $mode_3cbc; /** * The \phpseclib3\Crypt\DES objects * * Used only if $mode_3cbc === true * * @var array */ private $des; /** * Default Constructor. * * Determines whether or not the mcrypt or OpenSSL extensions should be used. * * $mode could be: * * - ecb * * - cbc * * - ctr * * - cfb * * - ofb * * - 3cbc * * - cbc3 (same as cbc) * * @see Crypt\DES::__construct() * @see Common\SymmetricKey::__construct() * @param string $mode */ public function __construct($mode) { switch (strtolower($mode)) { // In case of self::MODE_3CBC, we init as CRYPT_DES_MODE_CBC // and additional flag us internally as 3CBC case '3cbc': parent::__construct('cbc'); $this->mode_3cbc = true; // This three $des'es will do the 3CBC work (if $key > 64bits) $this->des = [ new DES('cbc'), new DES('cbc'), new DES('cbc'), ]; // we're going to be doing the padding, ourselves, so disable it in the \phpseclib3\Crypt\DES objects $this->des[0]->disablePadding(); $this->des[1]->disablePadding(); $this->des[2]->disablePadding(); break; case 'cbc3': $mode = 'cbc'; // fall-through // If not 3CBC, we init as usual default: parent::__construct($mode); if ($this->mode == self::MODE_STREAM) { throw new BadModeException('Block ciphers cannot be ran in stream mode'); } } } /** * Test for engine validity * * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() * * @see Common\SymmetricKey::__construct() * @param int $engine * @return bool */ protected function isValidEngineHelper($engine) { if ($engine == self::ENGINE_OPENSSL) { $this->cipher_name_openssl_ecb = 'des-ede3'; $mode = $this->openssl_translate_mode(); $this->cipher_name_openssl = $mode == 'ecb' ? 'des-ede3' : 'des-ede3-' . $mode; } return parent::isValidEngineHelper($engine); } /** * Sets the initialization vector. * * SetIV is not required when \phpseclib3\Crypt\Common\SymmetricKey::MODE_ECB is being used. * * @see Common\SymmetricKey::setIV() * @param string $iv */ public function setIV($iv) { parent::setIV($iv); if ($this->mode_3cbc) { $this->des[0]->setIV($iv); $this->des[1]->setIV($iv); $this->des[2]->setIV($iv); } } /** * Sets the key length. * * Valid key lengths are 128 and 192 bits. * * If you want to use a 64-bit key use DES.php * * @see Common\SymmetricKey:setKeyLength() * @throws \LengthException if the key length is invalid * @param int $length */ public function setKeyLength($length) { switch ($length) { case 128: case 192: break; default: throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes 128 or 192 bits are supported'); } parent::setKeyLength($length); } /** * Sets the key. * * Triple DES can use 128-bit (eg. strlen($key) == 16) or 192-bit (eg. strlen($key) == 24) keys. * * DES also requires that every eighth bit be a parity bit, however, we'll ignore that. * * @see DES::setKey() * @see Common\SymmetricKey::setKey() * @throws \LengthException if the key length is invalid * @param string $key */ public function setKey($key) { if ($this->explicit_key_length !== false && strlen($key) != $this->explicit_key_length) { throw new \LengthException('Key length has already been set to ' . $this->explicit_key_length . ' bytes and this key is ' . strlen($key) . ' bytes'); } switch (strlen($key)) { case 16: $key .= substr($key, 0, 8); break; case 24: break; default: throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16 or 24 are supported'); } // copied from self::setKey() $this->key = $key; $this->key_length = strlen($key); $this->changed = $this->nonIVChanged = true; $this->setEngine(); if ($this->mode_3cbc) { $this->des[0]->setKey(substr($key, 0, 8)); $this->des[1]->setKey(substr($key, 8, 8)); $this->des[2]->setKey(substr($key, 16, 8)); } } /** * Encrypts a message. * * @see Common\SymmetricKey::encrypt() * @param string $plaintext * @return string $cipertext */ public function encrypt($plaintext) { // parent::en/decrypt() is able to do all the work for all modes and keylengths, // except for: self::MODE_3CBC (inner chaining CBC) with a key > 64bits // if the key is smaller then 8, do what we'd normally do if ($this->mode_3cbc && strlen($this->key) > 8) { return $this->des[2]->encrypt( $this->des[1]->decrypt( $this->des[0]->encrypt( $this->pad($plaintext) ) ) ); } return parent::encrypt($plaintext); } /** * Decrypts a message. * * @see Common\SymmetricKey::decrypt() * @param string $ciphertext * @return string $plaintext */ public function decrypt($ciphertext) { if ($this->mode_3cbc && strlen($this->key) > 8) { return $this->unpad( $this->des[0]->decrypt( $this->des[1]->encrypt( $this->des[2]->decrypt( str_pad($ciphertext, (strlen($ciphertext) + 7) & 0xFFFFFFF8, "\0") ) ) ) ); } return parent::decrypt($ciphertext); } /** * Treat consecutive "packets" as if they are a continuous buffer. * * Say you have a 16-byte plaintext $plaintext. Using the default behavior, the two following code snippets * will yield different outputs: * * * echo $des->encrypt(substr($plaintext, 0, 8)); * echo $des->encrypt(substr($plaintext, 8, 8)); * * * echo $des->encrypt($plaintext); * * * The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates * another, as demonstrated with the following: * * * $des->encrypt(substr($plaintext, 0, 8)); * echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8))); * * * echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8))); * * * With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different * outputs. The reason is due to the fact that the initialization vector's change after every encryption / * decryption round when the continuous buffer is enabled. When it's disabled, they remain constant. * * Put another way, when the continuous buffer is enabled, the state of the \phpseclib3\Crypt\DES() object changes after each * encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that * continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them), * however, they are also less intuitive and more likely to cause you problems. * * @see Common\SymmetricKey::enableContinuousBuffer() * @see self::disableContinuousBuffer() */ public function enableContinuousBuffer() { parent::enableContinuousBuffer(); if ($this->mode_3cbc) { $this->des[0]->enableContinuousBuffer(); $this->des[1]->enableContinuousBuffer(); $this->des[2]->enableContinuousBuffer(); } } /** * Treat consecutive packets as if they are a discontinuous buffer. * * The default behavior. * * @see Common\SymmetricKey::disableContinuousBuffer() * @see self::enableContinuousBuffer() */ public function disableContinuousBuffer() { parent::disableContinuousBuffer(); if ($this->mode_3cbc) { $this->des[0]->disableContinuousBuffer(); $this->des[1]->disableContinuousBuffer(); $this->des[2]->disableContinuousBuffer(); } } /** * Creates the key schedule * * @see DES::setupKey() * @see Common\SymmetricKey::setupKey() */ protected function setupKey() { switch (true) { // if $key <= 64bits we configure our internal pure-php cipher engine // to act as regular [1]DES, not as 3DES. mcrypt.so::tripledes does the same. case strlen($this->key) <= 8: $this->des_rounds = 1; break; // otherwise, if $key > 64bits, we configure our engine to work as 3DES. default: $this->des_rounds = 3; // (only) if 3CBC is used we have, of course, to setup the $des[0-2] keys also separately. if ($this->mode_3cbc) { $this->des[0]->setupKey(); $this->des[1]->setupKey(); $this->des[2]->setupKey(); // because $des[0-2] will, now, do all the work we can return here // not need unnecessary stress parent::setupKey() with our, now unused, $key. return; } } // setup our key parent::setupKey(); } /** * Sets the internal crypt engine * * @see Common\SymmetricKey::__construct() * @see Common\SymmetricKey::setPreferredEngine() * @param int $engine */ public function setPreferredEngine($engine) { if ($this->mode_3cbc) { $this->des[0]->setPreferredEngine($engine); $this->des[1]->setPreferredEngine($engine); $this->des[2]->setPreferredEngine($engine); } parent::setPreferredEngine($engine); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php ================================================ * setKey('12345678901234567890123456789012'); * * $plaintext = str_repeat('a', 1024); * * echo $twofish->decrypt($twofish->encrypt($plaintext)); * ?> * * * @author Jim Wigginton * @author Hans-Juergen Petrich * @copyright 2007 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Crypt; use phpseclib3\Crypt\Common\BlockCipher; use phpseclib3\Exception\BadModeException; /** * Pure-PHP implementation of Twofish. * * @author Jim Wigginton * @author Hans-Juergen Petrich */ class Twofish extends BlockCipher { /** * The mcrypt specific name of the cipher * * @see Common\SymmetricKey::cipher_name_mcrypt * @var string */ protected $cipher_name_mcrypt = 'twofish'; /** * Optimizing value while CFB-encrypting * * @see Common\SymmetricKey::cfb_init_len * @var int */ protected $cfb_init_len = 800; /** * Q-Table * * @var array */ private static $q0 = [ 0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, 0x9A, 0x92, 0x80, 0x78, 0xE4, 0xDD, 0xD1, 0x38, 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C, 0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48, 0xF2, 0xD0, 0x8B, 0x30, 0x84, 0x54, 0xDF, 0x23, 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82, 0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C, 0xA6, 0xEB, 0xA5, 0xBE, 0x16, 0x0C, 0xE3, 0x61, 0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B, 0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1, 0xE1, 0xE6, 0xBD, 0x45, 0xE2, 0xF4, 0xB6, 0x66, 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7, 0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA, 0xEA, 0x77, 0x39, 0xAF, 0x33, 0xC9, 0x62, 0x71, 0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8, 0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7, 0xA1, 0x1D, 0xAA, 0xED, 0x06, 0x70, 0xB2, 0xD2, 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90, 0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB, 0x9E, 0x9C, 0x52, 0x1B, 0x5F, 0x93, 0x0A, 0xEF, 0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B, 0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64, 0x2A, 0xCE, 0xCB, 0x2F, 0xFC, 0x97, 0x05, 0x7A, 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A, 0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02, 0xB8, 0xDA, 0xB0, 0x17, 0x55, 0x1F, 0x8A, 0x7D, 0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72, 0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34, 0x6E, 0x50, 0xDE, 0x68, 0x65, 0xBC, 0xDB, 0xF8, 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4, 0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, 0x6F, 0x9D, 0x36, 0x42, 0x4A, 0x5E, 0xC1, 0xE0 ]; /** * Q-Table * * @var array */ private static $q1 = [ 0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, 0x4A, 0xD3, 0xE6, 0x6B, 0x45, 0x7D, 0xE8, 0x4B, 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1, 0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F, 0x5E, 0xBA, 0xAE, 0x5B, 0x8A, 0x00, 0xBC, 0x9D, 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5, 0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3, 0xB2, 0x73, 0x4C, 0x54, 0x92, 0x74, 0x36, 0x51, 0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96, 0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C, 0x13, 0x95, 0x9C, 0xC7, 0x24, 0x46, 0x3B, 0x70, 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8, 0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC, 0x03, 0x6F, 0x08, 0xBF, 0x40, 0xE7, 0x2B, 0xE2, 0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9, 0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17, 0x66, 0x94, 0xA1, 0x1D, 0x3D, 0xF0, 0xDE, 0xB3, 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E, 0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49, 0x81, 0x88, 0xEE, 0x21, 0xC4, 0x1A, 0xEB, 0xD9, 0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01, 0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48, 0x4F, 0xF2, 0x65, 0x8E, 0x78, 0x5C, 0x58, 0x19, 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64, 0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5, 0xCE, 0xE9, 0x68, 0x44, 0xE0, 0x4D, 0x43, 0x69, 0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E, 0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC, 0x22, 0xC9, 0xC0, 0x9B, 0x89, 0xD4, 0xED, 0xAB, 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9, 0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, 0x16, 0x25, 0x86, 0x56, 0x55, 0x09, 0xBE, 0x91 ]; /** * M-Table * * @var array */ private static $m0 = [ 0xBCBC3275, 0xECEC21F3, 0x202043C6, 0xB3B3C9F4, 0xDADA03DB, 0x02028B7B, 0xE2E22BFB, 0x9E9EFAC8, 0xC9C9EC4A, 0xD4D409D3, 0x18186BE6, 0x1E1E9F6B, 0x98980E45, 0xB2B2387D, 0xA6A6D2E8, 0x2626B74B, 0x3C3C57D6, 0x93938A32, 0x8282EED8, 0x525298FD, 0x7B7BD437, 0xBBBB3771, 0x5B5B97F1, 0x474783E1, 0x24243C30, 0x5151E20F, 0xBABAC6F8, 0x4A4AF31B, 0xBFBF4887, 0x0D0D70FA, 0xB0B0B306, 0x7575DE3F, 0xD2D2FD5E, 0x7D7D20BA, 0x666631AE, 0x3A3AA35B, 0x59591C8A, 0x00000000, 0xCDCD93BC, 0x1A1AE09D, 0xAEAE2C6D, 0x7F7FABC1, 0x2B2BC7B1, 0xBEBEB90E, 0xE0E0A080, 0x8A8A105D, 0x3B3B52D2, 0x6464BAD5, 0xD8D888A0, 0xE7E7A584, 0x5F5FE807, 0x1B1B1114, 0x2C2CC2B5, 0xFCFCB490, 0x3131272C, 0x808065A3, 0x73732AB2, 0x0C0C8173, 0x79795F4C, 0x6B6B4154, 0x4B4B0292, 0x53536974, 0x94948F36, 0x83831F51, 0x2A2A3638, 0xC4C49CB0, 0x2222C8BD, 0xD5D5F85A, 0xBDBDC3FC, 0x48487860, 0xFFFFCE62, 0x4C4C0796, 0x4141776C, 0xC7C7E642, 0xEBEB24F7, 0x1C1C1410, 0x5D5D637C, 0x36362228, 0x6767C027, 0xE9E9AF8C, 0x4444F913, 0x1414EA95, 0xF5F5BB9C, 0xCFCF18C7, 0x3F3F2D24, 0xC0C0E346, 0x7272DB3B, 0x54546C70, 0x29294CCA, 0xF0F035E3, 0x0808FE85, 0xC6C617CB, 0xF3F34F11, 0x8C8CE4D0, 0xA4A45993, 0xCACA96B8, 0x68683BA6, 0xB8B84D83, 0x38382820, 0xE5E52EFF, 0xADAD569F, 0x0B0B8477, 0xC8C81DC3, 0x9999FFCC, 0x5858ED03, 0x19199A6F, 0x0E0E0A08, 0x95957EBF, 0x70705040, 0xF7F730E7, 0x6E6ECF2B, 0x1F1F6EE2, 0xB5B53D79, 0x09090F0C, 0x616134AA, 0x57571682, 0x9F9F0B41, 0x9D9D803A, 0x111164EA, 0x2525CDB9, 0xAFAFDDE4, 0x4545089A, 0xDFDF8DA4, 0xA3A35C97, 0xEAEAD57E, 0x353558DA, 0xEDEDD07A, 0x4343FC17, 0xF8F8CB66, 0xFBFBB194, 0x3737D3A1, 0xFAFA401D, 0xC2C2683D, 0xB4B4CCF0, 0x32325DDE, 0x9C9C71B3, 0x5656E70B, 0xE3E3DA72, 0x878760A7, 0x15151B1C, 0xF9F93AEF, 0x6363BFD1, 0x3434A953, 0x9A9A853E, 0xB1B1428F, 0x7C7CD133, 0x88889B26, 0x3D3DA65F, 0xA1A1D7EC, 0xE4E4DF76, 0x8181942A, 0x91910149, 0x0F0FFB81, 0xEEEEAA88, 0x161661EE, 0xD7D77321, 0x9797F5C4, 0xA5A5A81A, 0xFEFE3FEB, 0x6D6DB5D9, 0x7878AEC5, 0xC5C56D39, 0x1D1DE599, 0x7676A4CD, 0x3E3EDCAD, 0xCBCB6731, 0xB6B6478B, 0xEFEF5B01, 0x12121E18, 0x6060C523, 0x6A6AB0DD, 0x4D4DF61F, 0xCECEE94E, 0xDEDE7C2D, 0x55559DF9, 0x7E7E5A48, 0x2121B24F, 0x03037AF2, 0xA0A02665, 0x5E5E198E, 0x5A5A6678, 0x65654B5C, 0x62624E58, 0xFDFD4519, 0x0606F48D, 0x404086E5, 0xF2F2BE98, 0x3333AC57, 0x17179067, 0x05058E7F, 0xE8E85E05, 0x4F4F7D64, 0x89896AAF, 0x10109563, 0x74742FB6, 0x0A0A75FE, 0x5C5C92F5, 0x9B9B74B7, 0x2D2D333C, 0x3030D6A5, 0x2E2E49CE, 0x494989E9, 0x46467268, 0x77775544, 0xA8A8D8E0, 0x9696044D, 0x2828BD43, 0xA9A92969, 0xD9D97929, 0x8686912E, 0xD1D187AC, 0xF4F44A15, 0x8D8D1559, 0xD6D682A8, 0xB9B9BC0A, 0x42420D9E, 0xF6F6C16E, 0x2F2FB847, 0xDDDD06DF, 0x23233934, 0xCCCC6235, 0xF1F1C46A, 0xC1C112CF, 0x8585EBDC, 0x8F8F9E22, 0x7171A1C9, 0x9090F0C0, 0xAAAA539B, 0x0101F189, 0x8B8BE1D4, 0x4E4E8CED, 0x8E8E6FAB, 0xABABA212, 0x6F6F3EA2, 0xE6E6540D, 0xDBDBF252, 0x92927BBB, 0xB7B7B602, 0x6969CA2F, 0x3939D9A9, 0xD3D30CD7, 0xA7A72361, 0xA2A2AD1E, 0xC3C399B4, 0x6C6C4450, 0x07070504, 0x04047FF6, 0x272746C2, 0xACACA716, 0xD0D07625, 0x50501386, 0xDCDCF756, 0x84841A55, 0xE1E15109, 0x7A7A25BE, 0x1313EF91 ]; /** * M-Table * * @var array */ private static $m1 = [ 0xA9D93939, 0x67901717, 0xB3719C9C, 0xE8D2A6A6, 0x04050707, 0xFD985252, 0xA3658080, 0x76DFE4E4, 0x9A084545, 0x92024B4B, 0x80A0E0E0, 0x78665A5A, 0xE4DDAFAF, 0xDDB06A6A, 0xD1BF6363, 0x38362A2A, 0x0D54E6E6, 0xC6432020, 0x3562CCCC, 0x98BEF2F2, 0x181E1212, 0xF724EBEB, 0xECD7A1A1, 0x6C774141, 0x43BD2828, 0x7532BCBC, 0x37D47B7B, 0x269B8888, 0xFA700D0D, 0x13F94444, 0x94B1FBFB, 0x485A7E7E, 0xF27A0303, 0xD0E48C8C, 0x8B47B6B6, 0x303C2424, 0x84A5E7E7, 0x54416B6B, 0xDF06DDDD, 0x23C56060, 0x1945FDFD, 0x5BA33A3A, 0x3D68C2C2, 0x59158D8D, 0xF321ECEC, 0xAE316666, 0xA23E6F6F, 0x82165757, 0x63951010, 0x015BEFEF, 0x834DB8B8, 0x2E918686, 0xD9B56D6D, 0x511F8383, 0x9B53AAAA, 0x7C635D5D, 0xA63B6868, 0xEB3FFEFE, 0xA5D63030, 0xBE257A7A, 0x16A7ACAC, 0x0C0F0909, 0xE335F0F0, 0x6123A7A7, 0xC0F09090, 0x8CAFE9E9, 0x3A809D9D, 0xF5925C5C, 0x73810C0C, 0x2C273131, 0x2576D0D0, 0x0BE75656, 0xBB7B9292, 0x4EE9CECE, 0x89F10101, 0x6B9F1E1E, 0x53A93434, 0x6AC4F1F1, 0xB499C3C3, 0xF1975B5B, 0xE1834747, 0xE66B1818, 0xBDC82222, 0x450E9898, 0xE26E1F1F, 0xF4C9B3B3, 0xB62F7474, 0x66CBF8F8, 0xCCFF9999, 0x95EA1414, 0x03ED5858, 0x56F7DCDC, 0xD4E18B8B, 0x1C1B1515, 0x1EADA2A2, 0xD70CD3D3, 0xFB2BE2E2, 0xC31DC8C8, 0x8E195E5E, 0xB5C22C2C, 0xE9894949, 0xCF12C1C1, 0xBF7E9595, 0xBA207D7D, 0xEA641111, 0x77840B0B, 0x396DC5C5, 0xAF6A8989, 0x33D17C7C, 0xC9A17171, 0x62CEFFFF, 0x7137BBBB, 0x81FB0F0F, 0x793DB5B5, 0x0951E1E1, 0xADDC3E3E, 0x242D3F3F, 0xCDA47676, 0xF99D5555, 0xD8EE8282, 0xE5864040, 0xC5AE7878, 0xB9CD2525, 0x4D049696, 0x44557777, 0x080A0E0E, 0x86135050, 0xE730F7F7, 0xA1D33737, 0x1D40FAFA, 0xAA346161, 0xED8C4E4E, 0x06B3B0B0, 0x706C5454, 0xB22A7373, 0xD2523B3B, 0x410B9F9F, 0x7B8B0202, 0xA088D8D8, 0x114FF3F3, 0x3167CBCB, 0xC2462727, 0x27C06767, 0x90B4FCFC, 0x20283838, 0xF67F0404, 0x60784848, 0xFF2EE5E5, 0x96074C4C, 0x5C4B6565, 0xB1C72B2B, 0xAB6F8E8E, 0x9E0D4242, 0x9CBBF5F5, 0x52F2DBDB, 0x1BF34A4A, 0x5FA63D3D, 0x9359A4A4, 0x0ABCB9B9, 0xEF3AF9F9, 0x91EF1313, 0x85FE0808, 0x49019191, 0xEE611616, 0x2D7CDEDE, 0x4FB22121, 0x8F42B1B1, 0x3BDB7272, 0x47B82F2F, 0x8748BFBF, 0x6D2CAEAE, 0x46E3C0C0, 0xD6573C3C, 0x3E859A9A, 0x6929A9A9, 0x647D4F4F, 0x2A948181, 0xCE492E2E, 0xCB17C6C6, 0x2FCA6969, 0xFCC3BDBD, 0x975CA3A3, 0x055EE8E8, 0x7AD0EDED, 0xAC87D1D1, 0x7F8E0505, 0xD5BA6464, 0x1AA8A5A5, 0x4BB72626, 0x0EB9BEBE, 0xA7608787, 0x5AF8D5D5, 0x28223636, 0x14111B1B, 0x3FDE7575, 0x2979D9D9, 0x88AAEEEE, 0x3C332D2D, 0x4C5F7979, 0x02B6B7B7, 0xB896CACA, 0xDA583535, 0xB09CC4C4, 0x17FC4343, 0x551A8484, 0x1FF64D4D, 0x8A1C5959, 0x7D38B2B2, 0x57AC3333, 0xC718CFCF, 0x8DF40606, 0x74695353, 0xB7749B9B, 0xC4F59797, 0x9F56ADAD, 0x72DAE3E3, 0x7ED5EAEA, 0x154AF4F4, 0x229E8F8F, 0x12A2ABAB, 0x584E6262, 0x07E85F5F, 0x99E51D1D, 0x34392323, 0x6EC1F6F6, 0x50446C6C, 0xDE5D3232, 0x68724646, 0x6526A0A0, 0xBC93CDCD, 0xDB03DADA, 0xF8C6BABA, 0xC8FA9E9E, 0xA882D6D6, 0x2BCF6E6E, 0x40507070, 0xDCEB8585, 0xFE750A0A, 0x328A9393, 0xA48DDFDF, 0xCA4C2929, 0x10141C1C, 0x2173D7D7, 0xF0CCB4B4, 0xD309D4D4, 0x5D108A8A, 0x0FE25151, 0x00000000, 0x6F9A1919, 0x9DE01A1A, 0x368F9494, 0x42E6C7C7, 0x4AECC9C9, 0x5EFDD2D2, 0xC1AB7F7F, 0xE0D8A8A8 ]; /** * M-Table * * @var array */ private static $m2 = [ 0xBC75BC32, 0xECF3EC21, 0x20C62043, 0xB3F4B3C9, 0xDADBDA03, 0x027B028B, 0xE2FBE22B, 0x9EC89EFA, 0xC94AC9EC, 0xD4D3D409, 0x18E6186B, 0x1E6B1E9F, 0x9845980E, 0xB27DB238, 0xA6E8A6D2, 0x264B26B7, 0x3CD63C57, 0x9332938A, 0x82D882EE, 0x52FD5298, 0x7B377BD4, 0xBB71BB37, 0x5BF15B97, 0x47E14783, 0x2430243C, 0x510F51E2, 0xBAF8BAC6, 0x4A1B4AF3, 0xBF87BF48, 0x0DFA0D70, 0xB006B0B3, 0x753F75DE, 0xD25ED2FD, 0x7DBA7D20, 0x66AE6631, 0x3A5B3AA3, 0x598A591C, 0x00000000, 0xCDBCCD93, 0x1A9D1AE0, 0xAE6DAE2C, 0x7FC17FAB, 0x2BB12BC7, 0xBE0EBEB9, 0xE080E0A0, 0x8A5D8A10, 0x3BD23B52, 0x64D564BA, 0xD8A0D888, 0xE784E7A5, 0x5F075FE8, 0x1B141B11, 0x2CB52CC2, 0xFC90FCB4, 0x312C3127, 0x80A38065, 0x73B2732A, 0x0C730C81, 0x794C795F, 0x6B546B41, 0x4B924B02, 0x53745369, 0x9436948F, 0x8351831F, 0x2A382A36, 0xC4B0C49C, 0x22BD22C8, 0xD55AD5F8, 0xBDFCBDC3, 0x48604878, 0xFF62FFCE, 0x4C964C07, 0x416C4177, 0xC742C7E6, 0xEBF7EB24, 0x1C101C14, 0x5D7C5D63, 0x36283622, 0x672767C0, 0xE98CE9AF, 0x441344F9, 0x149514EA, 0xF59CF5BB, 0xCFC7CF18, 0x3F243F2D, 0xC046C0E3, 0x723B72DB, 0x5470546C, 0x29CA294C, 0xF0E3F035, 0x088508FE, 0xC6CBC617, 0xF311F34F, 0x8CD08CE4, 0xA493A459, 0xCAB8CA96, 0x68A6683B, 0xB883B84D, 0x38203828, 0xE5FFE52E, 0xAD9FAD56, 0x0B770B84, 0xC8C3C81D, 0x99CC99FF, 0x580358ED, 0x196F199A, 0x0E080E0A, 0x95BF957E, 0x70407050, 0xF7E7F730, 0x6E2B6ECF, 0x1FE21F6E, 0xB579B53D, 0x090C090F, 0x61AA6134, 0x57825716, 0x9F419F0B, 0x9D3A9D80, 0x11EA1164, 0x25B925CD, 0xAFE4AFDD, 0x459A4508, 0xDFA4DF8D, 0xA397A35C, 0xEA7EEAD5, 0x35DA3558, 0xED7AEDD0, 0x431743FC, 0xF866F8CB, 0xFB94FBB1, 0x37A137D3, 0xFA1DFA40, 0xC23DC268, 0xB4F0B4CC, 0x32DE325D, 0x9CB39C71, 0x560B56E7, 0xE372E3DA, 0x87A78760, 0x151C151B, 0xF9EFF93A, 0x63D163BF, 0x345334A9, 0x9A3E9A85, 0xB18FB142, 0x7C337CD1, 0x8826889B, 0x3D5F3DA6, 0xA1ECA1D7, 0xE476E4DF, 0x812A8194, 0x91499101, 0x0F810FFB, 0xEE88EEAA, 0x16EE1661, 0xD721D773, 0x97C497F5, 0xA51AA5A8, 0xFEEBFE3F, 0x6DD96DB5, 0x78C578AE, 0xC539C56D, 0x1D991DE5, 0x76CD76A4, 0x3EAD3EDC, 0xCB31CB67, 0xB68BB647, 0xEF01EF5B, 0x1218121E, 0x602360C5, 0x6ADD6AB0, 0x4D1F4DF6, 0xCE4ECEE9, 0xDE2DDE7C, 0x55F9559D, 0x7E487E5A, 0x214F21B2, 0x03F2037A, 0xA065A026, 0x5E8E5E19, 0x5A785A66, 0x655C654B, 0x6258624E, 0xFD19FD45, 0x068D06F4, 0x40E54086, 0xF298F2BE, 0x335733AC, 0x17671790, 0x057F058E, 0xE805E85E, 0x4F644F7D, 0x89AF896A, 0x10631095, 0x74B6742F, 0x0AFE0A75, 0x5CF55C92, 0x9BB79B74, 0x2D3C2D33, 0x30A530D6, 0x2ECE2E49, 0x49E94989, 0x46684672, 0x77447755, 0xA8E0A8D8, 0x964D9604, 0x284328BD, 0xA969A929, 0xD929D979, 0x862E8691, 0xD1ACD187, 0xF415F44A, 0x8D598D15, 0xD6A8D682, 0xB90AB9BC, 0x429E420D, 0xF66EF6C1, 0x2F472FB8, 0xDDDFDD06, 0x23342339, 0xCC35CC62, 0xF16AF1C4, 0xC1CFC112, 0x85DC85EB, 0x8F228F9E, 0x71C971A1, 0x90C090F0, 0xAA9BAA53, 0x018901F1, 0x8BD48BE1, 0x4EED4E8C, 0x8EAB8E6F, 0xAB12ABA2, 0x6FA26F3E, 0xE60DE654, 0xDB52DBF2, 0x92BB927B, 0xB702B7B6, 0x692F69CA, 0x39A939D9, 0xD3D7D30C, 0xA761A723, 0xA21EA2AD, 0xC3B4C399, 0x6C506C44, 0x07040705, 0x04F6047F, 0x27C22746, 0xAC16ACA7, 0xD025D076, 0x50865013, 0xDC56DCF7, 0x8455841A, 0xE109E151, 0x7ABE7A25, 0x139113EF ]; /** * M-Table * * @var array */ private static $m3 = [ 0xD939A9D9, 0x90176790, 0x719CB371, 0xD2A6E8D2, 0x05070405, 0x9852FD98, 0x6580A365, 0xDFE476DF, 0x08459A08, 0x024B9202, 0xA0E080A0, 0x665A7866, 0xDDAFE4DD, 0xB06ADDB0, 0xBF63D1BF, 0x362A3836, 0x54E60D54, 0x4320C643, 0x62CC3562, 0xBEF298BE, 0x1E12181E, 0x24EBF724, 0xD7A1ECD7, 0x77416C77, 0xBD2843BD, 0x32BC7532, 0xD47B37D4, 0x9B88269B, 0x700DFA70, 0xF94413F9, 0xB1FB94B1, 0x5A7E485A, 0x7A03F27A, 0xE48CD0E4, 0x47B68B47, 0x3C24303C, 0xA5E784A5, 0x416B5441, 0x06DDDF06, 0xC56023C5, 0x45FD1945, 0xA33A5BA3, 0x68C23D68, 0x158D5915, 0x21ECF321, 0x3166AE31, 0x3E6FA23E, 0x16578216, 0x95106395, 0x5BEF015B, 0x4DB8834D, 0x91862E91, 0xB56DD9B5, 0x1F83511F, 0x53AA9B53, 0x635D7C63, 0x3B68A63B, 0x3FFEEB3F, 0xD630A5D6, 0x257ABE25, 0xA7AC16A7, 0x0F090C0F, 0x35F0E335, 0x23A76123, 0xF090C0F0, 0xAFE98CAF, 0x809D3A80, 0x925CF592, 0x810C7381, 0x27312C27, 0x76D02576, 0xE7560BE7, 0x7B92BB7B, 0xE9CE4EE9, 0xF10189F1, 0x9F1E6B9F, 0xA93453A9, 0xC4F16AC4, 0x99C3B499, 0x975BF197, 0x8347E183, 0x6B18E66B, 0xC822BDC8, 0x0E98450E, 0x6E1FE26E, 0xC9B3F4C9, 0x2F74B62F, 0xCBF866CB, 0xFF99CCFF, 0xEA1495EA, 0xED5803ED, 0xF7DC56F7, 0xE18BD4E1, 0x1B151C1B, 0xADA21EAD, 0x0CD3D70C, 0x2BE2FB2B, 0x1DC8C31D, 0x195E8E19, 0xC22CB5C2, 0x8949E989, 0x12C1CF12, 0x7E95BF7E, 0x207DBA20, 0x6411EA64, 0x840B7784, 0x6DC5396D, 0x6A89AF6A, 0xD17C33D1, 0xA171C9A1, 0xCEFF62CE, 0x37BB7137, 0xFB0F81FB, 0x3DB5793D, 0x51E10951, 0xDC3EADDC, 0x2D3F242D, 0xA476CDA4, 0x9D55F99D, 0xEE82D8EE, 0x8640E586, 0xAE78C5AE, 0xCD25B9CD, 0x04964D04, 0x55774455, 0x0A0E080A, 0x13508613, 0x30F7E730, 0xD337A1D3, 0x40FA1D40, 0x3461AA34, 0x8C4EED8C, 0xB3B006B3, 0x6C54706C, 0x2A73B22A, 0x523BD252, 0x0B9F410B, 0x8B027B8B, 0x88D8A088, 0x4FF3114F, 0x67CB3167, 0x4627C246, 0xC06727C0, 0xB4FC90B4, 0x28382028, 0x7F04F67F, 0x78486078, 0x2EE5FF2E, 0x074C9607, 0x4B655C4B, 0xC72BB1C7, 0x6F8EAB6F, 0x0D429E0D, 0xBBF59CBB, 0xF2DB52F2, 0xF34A1BF3, 0xA63D5FA6, 0x59A49359, 0xBCB90ABC, 0x3AF9EF3A, 0xEF1391EF, 0xFE0885FE, 0x01914901, 0x6116EE61, 0x7CDE2D7C, 0xB2214FB2, 0x42B18F42, 0xDB723BDB, 0xB82F47B8, 0x48BF8748, 0x2CAE6D2C, 0xE3C046E3, 0x573CD657, 0x859A3E85, 0x29A96929, 0x7D4F647D, 0x94812A94, 0x492ECE49, 0x17C6CB17, 0xCA692FCA, 0xC3BDFCC3, 0x5CA3975C, 0x5EE8055E, 0xD0ED7AD0, 0x87D1AC87, 0x8E057F8E, 0xBA64D5BA, 0xA8A51AA8, 0xB7264BB7, 0xB9BE0EB9, 0x6087A760, 0xF8D55AF8, 0x22362822, 0x111B1411, 0xDE753FDE, 0x79D92979, 0xAAEE88AA, 0x332D3C33, 0x5F794C5F, 0xB6B702B6, 0x96CAB896, 0x5835DA58, 0x9CC4B09C, 0xFC4317FC, 0x1A84551A, 0xF64D1FF6, 0x1C598A1C, 0x38B27D38, 0xAC3357AC, 0x18CFC718, 0xF4068DF4, 0x69537469, 0x749BB774, 0xF597C4F5, 0x56AD9F56, 0xDAE372DA, 0xD5EA7ED5, 0x4AF4154A, 0x9E8F229E, 0xA2AB12A2, 0x4E62584E, 0xE85F07E8, 0xE51D99E5, 0x39233439, 0xC1F66EC1, 0x446C5044, 0x5D32DE5D, 0x72466872, 0x26A06526, 0x93CDBC93, 0x03DADB03, 0xC6BAF8C6, 0xFA9EC8FA, 0x82D6A882, 0xCF6E2BCF, 0x50704050, 0xEB85DCEB, 0x750AFE75, 0x8A93328A, 0x8DDFA48D, 0x4C29CA4C, 0x141C1014, 0x73D72173, 0xCCB4F0CC, 0x09D4D309, 0x108A5D10, 0xE2510FE2, 0x00000000, 0x9A196F9A, 0xE01A9DE0, 0x8F94368F, 0xE6C742E6, 0xECC94AEC, 0xFDD25EFD, 0xAB7FC1AB, 0xD8A8E0D8 ]; /** * The Key Schedule Array * * @var array */ private $K = []; /** * The Key depended S-Table 0 * * @var array */ private $S0 = []; /** * The Key depended S-Table 1 * * @var array */ private $S1 = []; /** * The Key depended S-Table 2 * * @var array */ private $S2 = []; /** * The Key depended S-Table 3 * * @var array */ private $S3 = []; /** * Holds the last used key * * @var array */ private $kl; /** * The Key Length (in bytes) * * @see Crypt_Twofish::setKeyLength() * @var int */ protected $key_length = 16; /** * Default Constructor. * * @param string $mode * @throws BadModeException if an invalid / unsupported mode is provided */ public function __construct($mode) { parent::__construct($mode); if ($this->mode == self::MODE_STREAM) { throw new BadModeException('Block ciphers cannot be ran in stream mode'); } } /** * Initialize Static Variables */ protected static function initialize_static_variables() { if (is_float(self::$m3[0])) { self::$m0 = array_map('intval', self::$m0); self::$m1 = array_map('intval', self::$m1); self::$m2 = array_map('intval', self::$m2); self::$m3 = array_map('intval', self::$m3); self::$q0 = array_map('intval', self::$q0); self::$q1 = array_map('intval', self::$q1); } parent::initialize_static_variables(); } /** * Sets the key length. * * Valid key lengths are 128, 192 or 256 bits * * @param int $length */ public function setKeyLength($length) { switch ($length) { case 128: case 192: case 256: break; default: throw new \LengthException('Key of size ' . $length . ' not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported'); } parent::setKeyLength($length); } /** * Sets the key. * * Rijndael supports five different key lengths * * @see setKeyLength() * @param string $key * @throws \LengthException if the key length isn't supported */ public function setKey($key) { switch (strlen($key)) { case 16: case 24: case 32: break; default: throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported'); } parent::setKey($key); } /** * Setup the key (expansion) * * @see Common\SymmetricKey::_setupKey() */ protected function setupKey() { if (isset($this->kl['key']) && $this->key === $this->kl['key']) { // already expanded return; } $this->kl = ['key' => $this->key]; /* Key expanding and generating the key-depended s-boxes */ $le_longs = unpack('V*', $this->key); $key = unpack('C*', $this->key); $m0 = self::$m0; $m1 = self::$m1; $m2 = self::$m2; $m3 = self::$m3; $q0 = self::$q0; $q1 = self::$q1; $K = $S0 = $S1 = $S2 = $S3 = []; switch (strlen($this->key)) { case 16: list($s7, $s6, $s5, $s4) = $this->mdsrem($le_longs[1], $le_longs[2]); list($s3, $s2, $s1, $s0) = $this->mdsrem($le_longs[3], $le_longs[4]); for ($i = 0, $j = 1; $i < 40; $i += 2, $j += 2) { $A = $m0[$q0[$q0[$i] ^ $key[ 9]] ^ $key[1]] ^ $m1[$q0[$q1[$i] ^ $key[10]] ^ $key[2]] ^ $m2[$q1[$q0[$i] ^ $key[11]] ^ $key[3]] ^ $m3[$q1[$q1[$i] ^ $key[12]] ^ $key[4]]; $B = $m0[$q0[$q0[$j] ^ $key[13]] ^ $key[5]] ^ $m1[$q0[$q1[$j] ^ $key[14]] ^ $key[6]] ^ $m2[$q1[$q0[$j] ^ $key[15]] ^ $key[7]] ^ $m3[$q1[$q1[$j] ^ $key[16]] ^ $key[8]]; $B = ($B << 8) | ($B >> 24 & 0xff); $A = self::safe_intval($A + $B); $K[] = $A; $A = self::safe_intval($A + $B); $K[] = ($A << 9 | $A >> 23 & 0x1ff); } for ($i = 0; $i < 256; ++$i) { $S0[$i] = $m0[$q0[$q0[$i] ^ $s4] ^ $s0]; $S1[$i] = $m1[$q0[$q1[$i] ^ $s5] ^ $s1]; $S2[$i] = $m2[$q1[$q0[$i] ^ $s6] ^ $s2]; $S3[$i] = $m3[$q1[$q1[$i] ^ $s7] ^ $s3]; } break; case 24: list($sb, $sa, $s9, $s8) = $this->mdsrem($le_longs[1], $le_longs[2]); list($s7, $s6, $s5, $s4) = $this->mdsrem($le_longs[3], $le_longs[4]); list($s3, $s2, $s1, $s0) = $this->mdsrem($le_longs[5], $le_longs[6]); for ($i = 0, $j = 1; $i < 40; $i += 2, $j += 2) { $A = $m0[$q0[$q0[$q1[$i] ^ $key[17]] ^ $key[ 9]] ^ $key[1]] ^ $m1[$q0[$q1[$q1[$i] ^ $key[18]] ^ $key[10]] ^ $key[2]] ^ $m2[$q1[$q0[$q0[$i] ^ $key[19]] ^ $key[11]] ^ $key[3]] ^ $m3[$q1[$q1[$q0[$i] ^ $key[20]] ^ $key[12]] ^ $key[4]]; $B = $m0[$q0[$q0[$q1[$j] ^ $key[21]] ^ $key[13]] ^ $key[5]] ^ $m1[$q0[$q1[$q1[$j] ^ $key[22]] ^ $key[14]] ^ $key[6]] ^ $m2[$q1[$q0[$q0[$j] ^ $key[23]] ^ $key[15]] ^ $key[7]] ^ $m3[$q1[$q1[$q0[$j] ^ $key[24]] ^ $key[16]] ^ $key[8]]; $B = ($B << 8) | ($B >> 24 & 0xff); $A = self::safe_intval($A + $B); $K[] = $A; $A = self::safe_intval($A + $B); $K[] = ($A << 9 | $A >> 23 & 0x1ff); } for ($i = 0; $i < 256; ++$i) { $S0[$i] = $m0[$q0[$q0[$q1[$i] ^ $s8] ^ $s4] ^ $s0]; $S1[$i] = $m1[$q0[$q1[$q1[$i] ^ $s9] ^ $s5] ^ $s1]; $S2[$i] = $m2[$q1[$q0[$q0[$i] ^ $sa] ^ $s6] ^ $s2]; $S3[$i] = $m3[$q1[$q1[$q0[$i] ^ $sb] ^ $s7] ^ $s3]; } break; default: // 32 list($sf, $se, $sd, $sc) = $this->mdsrem($le_longs[1], $le_longs[2]); list($sb, $sa, $s9, $s8) = $this->mdsrem($le_longs[3], $le_longs[4]); list($s7, $s6, $s5, $s4) = $this->mdsrem($le_longs[5], $le_longs[6]); list($s3, $s2, $s1, $s0) = $this->mdsrem($le_longs[7], $le_longs[8]); for ($i = 0, $j = 1; $i < 40; $i += 2, $j += 2) { $A = $m0[$q0[$q0[$q1[$q1[$i] ^ $key[25]] ^ $key[17]] ^ $key[ 9]] ^ $key[1]] ^ $m1[$q0[$q1[$q1[$q0[$i] ^ $key[26]] ^ $key[18]] ^ $key[10]] ^ $key[2]] ^ $m2[$q1[$q0[$q0[$q0[$i] ^ $key[27]] ^ $key[19]] ^ $key[11]] ^ $key[3]] ^ $m3[$q1[$q1[$q0[$q1[$i] ^ $key[28]] ^ $key[20]] ^ $key[12]] ^ $key[4]]; $B = $m0[$q0[$q0[$q1[$q1[$j] ^ $key[29]] ^ $key[21]] ^ $key[13]] ^ $key[5]] ^ $m1[$q0[$q1[$q1[$q0[$j] ^ $key[30]] ^ $key[22]] ^ $key[14]] ^ $key[6]] ^ $m2[$q1[$q0[$q0[$q0[$j] ^ $key[31]] ^ $key[23]] ^ $key[15]] ^ $key[7]] ^ $m3[$q1[$q1[$q0[$q1[$j] ^ $key[32]] ^ $key[24]] ^ $key[16]] ^ $key[8]]; $B = ($B << 8) | ($B >> 24 & 0xff); $A = self::safe_intval($A + $B); $K[] = $A; $A = self::safe_intval($A + $B); $K[] = ($A << 9 | $A >> 23 & 0x1ff); } for ($i = 0; $i < 256; ++$i) { $S0[$i] = $m0[$q0[$q0[$q1[$q1[$i] ^ $sc] ^ $s8] ^ $s4] ^ $s0]; $S1[$i] = $m1[$q0[$q1[$q1[$q0[$i] ^ $sd] ^ $s9] ^ $s5] ^ $s1]; $S2[$i] = $m2[$q1[$q0[$q0[$q0[$i] ^ $se] ^ $sa] ^ $s6] ^ $s2]; $S3[$i] = $m3[$q1[$q1[$q0[$q1[$i] ^ $sf] ^ $sb] ^ $s7] ^ $s3]; } } $this->K = $K; $this->S0 = $S0; $this->S1 = $S1; $this->S2 = $S2; $this->S3 = $S3; } /** * _mdsrem function using by the twofish cipher algorithm * * @param string $A * @param string $B * @return array */ private function mdsrem($A, $B) { // No gain by unrolling this loop. for ($i = 0; $i < 8; ++$i) { // Get most significant coefficient. $t = 0xff & ($B >> 24); // Shift the others up. $B = ($B << 8) | (0xff & ($A >> 24)); $A <<= 8; $u = $t << 1; // Subtract the modular polynomial on overflow. if ($t & 0x80) { $u ^= 0x14d; } // Remove t * (a * x^2 + 1). $B ^= $t ^ ($u << 16); // Form u = a*t + t/a = t*(a + 1/a). $u ^= 0x7fffffff & ($t >> 1); // Add the modular polynomial on underflow. if ($t & 0x01) { $u ^= 0xa6 ; } // Remove t * (a + 1/a) * (x^3 + x). $B ^= ($u << 24) | ($u << 8); } return [ 0xff & $B >> 24, 0xff & $B >> 16, 0xff & $B >> 8, 0xff & $B]; } /** * Encrypts a block * * @param string $in * @return string */ protected function encryptBlock($in) { $S0 = $this->S0; $S1 = $this->S1; $S2 = $this->S2; $S3 = $this->S3; $K = $this->K; $in = unpack("V4", $in); $R0 = $K[0] ^ $in[1]; $R1 = $K[1] ^ $in[2]; $R2 = $K[2] ^ $in[3]; $R3 = $K[3] ^ $in[4]; $ki = 7; while ($ki < 39) { $t0 = $S0[ $R0 & 0xff] ^ $S1[($R0 >> 8) & 0xff] ^ $S2[($R0 >> 16) & 0xff] ^ $S3[($R0 >> 24) & 0xff]; $t1 = $S0[($R1 >> 24) & 0xff] ^ $S1[ $R1 & 0xff] ^ $S2[($R1 >> 8) & 0xff] ^ $S3[($R1 >> 16) & 0xff]; $R2 ^= self::safe_intval($t0 + $t1 + $K[++$ki]); $R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31); $R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ self::safe_intval($t0 + ($t1 << 1) + $K[++$ki]); $t0 = $S0[ $R2 & 0xff] ^ $S1[($R2 >> 8) & 0xff] ^ $S2[($R2 >> 16) & 0xff] ^ $S3[($R2 >> 24) & 0xff]; $t1 = $S0[($R3 >> 24) & 0xff] ^ $S1[ $R3 & 0xff] ^ $S2[($R3 >> 8) & 0xff] ^ $S3[($R3 >> 16) & 0xff]; $R0 ^= self::safe_intval($t0 + $t1 + $K[++$ki]); $R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31); $R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ self::safe_intval($t0 + ($t1 << 1) + $K[++$ki]); } // @codingStandardsIgnoreStart return pack("V4", $K[4] ^ $R2, $K[5] ^ $R3, $K[6] ^ $R0, $K[7] ^ $R1); // @codingStandardsIgnoreEnd } /** * Decrypts a block * * @param string $in * @return string */ protected function decryptBlock($in) { $S0 = $this->S0; $S1 = $this->S1; $S2 = $this->S2; $S3 = $this->S3; $K = $this->K; $in = unpack("V4", $in); $R0 = $K[4] ^ $in[1]; $R1 = $K[5] ^ $in[2]; $R2 = $K[6] ^ $in[3]; $R3 = $K[7] ^ $in[4]; $ki = 40; while ($ki > 8) { $t0 = $S0[$R0 & 0xff] ^ $S1[$R0 >> 8 & 0xff] ^ $S2[$R0 >> 16 & 0xff] ^ $S3[$R0 >> 24 & 0xff]; $t1 = $S0[$R1 >> 24 & 0xff] ^ $S1[$R1 & 0xff] ^ $S2[$R1 >> 8 & 0xff] ^ $S3[$R1 >> 16 & 0xff]; $R3 ^= self::safe_intval($t0 + ($t1 << 1) + $K[--$ki]); $R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31; $R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ self::safe_intval($t0 + $t1 + $K[--$ki]); $t0 = $S0[$R2 & 0xff] ^ $S1[$R2 >> 8 & 0xff] ^ $S2[$R2 >> 16 & 0xff] ^ $S3[$R2 >> 24 & 0xff]; $t1 = $S0[$R3 >> 24 & 0xff] ^ $S1[$R3 & 0xff] ^ $S2[$R3 >> 8 & 0xff] ^ $S3[$R3 >> 16 & 0xff]; $R1 ^= self::safe_intval($t0 + ($t1 << 1) + $K[--$ki]); $R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31; $R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ self::safe_intval($t0 + $t1 + $K[--$ki]); } // @codingStandardsIgnoreStart return pack("V4", $K[0] ^ $R2, $K[1] ^ $R3, $K[2] ^ $R0, $K[3] ^ $R1); // @codingStandardsIgnoreEnd } /** * Setup the performance-optimized function for de/encrypt() * * @see Common\SymmetricKey::_setupInlineCrypt() */ protected function setupInlineCrypt() { $K = $this->K; $init_crypt = ' static $S0, $S1, $S2, $S3; if (!$S0) { for ($i = 0; $i < 256; ++$i) { $S0[] = (int)$this->S0[$i]; $S1[] = (int)$this->S1[$i]; $S2[] = (int)$this->S2[$i]; $S3[] = (int)$this->S3[$i]; } } '; $safeint = self::safe_intval_inline(); // Generating encrypt code: $encrypt_block = ' $in = unpack("V4", $in); $R0 = ' . $K[0] . ' ^ $in[1]; $R1 = ' . $K[1] . ' ^ $in[2]; $R2 = ' . $K[2] . ' ^ $in[3]; $R3 = ' . $K[3] . ' ^ $in[4]; '; for ($ki = 7, $i = 0; $i < 8; ++$i) { $encrypt_block .= ' $t0 = $S0[ $R0 & 0xff] ^ $S1[($R0 >> 8) & 0xff] ^ $S2[($R0 >> 16) & 0xff] ^ $S3[($R0 >> 24) & 0xff]; $t1 = $S0[($R1 >> 24) & 0xff] ^ $S1[ $R1 & 0xff] ^ $S2[($R1 >> 8) & 0xff] ^ $S3[($R1 >> 16) & 0xff]; $R2^= ' . sprintf($safeint, '$t0 + $t1 + ' . $K[++$ki]) . '; $R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31); $R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ ' . sprintf($safeint, '($t0 + ($t1 << 1) + ' . $K[++$ki] . ')') . '; $t0 = $S0[ $R2 & 0xff] ^ $S1[($R2 >> 8) & 0xff] ^ $S2[($R2 >> 16) & 0xff] ^ $S3[($R2 >> 24) & 0xff]; $t1 = $S0[($R3 >> 24) & 0xff] ^ $S1[ $R3 & 0xff] ^ $S2[($R3 >> 8) & 0xff] ^ $S3[($R3 >> 16) & 0xff]; $R0^= ' . sprintf($safeint, '($t0 + $t1 + ' . $K[++$ki] . ')') . '; $R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31); $R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ ' . sprintf($safeint, '($t0 + ($t1 << 1) + ' . $K[++$ki] . ')') . '; '; } $encrypt_block .= ' $in = pack("V4", ' . $K[4] . ' ^ $R2, ' . $K[5] . ' ^ $R3, ' . $K[6] . ' ^ $R0, ' . $K[7] . ' ^ $R1); '; // Generating decrypt code: $decrypt_block = ' $in = unpack("V4", $in); $R0 = ' . $K[4] . ' ^ $in[1]; $R1 = ' . $K[5] . ' ^ $in[2]; $R2 = ' . $K[6] . ' ^ $in[3]; $R3 = ' . $K[7] . ' ^ $in[4]; '; for ($ki = 40, $i = 0; $i < 8; ++$i) { $decrypt_block .= ' $t0 = $S0[$R0 & 0xff] ^ $S1[$R0 >> 8 & 0xff] ^ $S2[$R0 >> 16 & 0xff] ^ $S3[$R0 >> 24 & 0xff]; $t1 = $S0[$R1 >> 24 & 0xff] ^ $S1[$R1 & 0xff] ^ $S2[$R1 >> 8 & 0xff] ^ $S3[$R1 >> 16 & 0xff]; $R3^= ' . sprintf($safeint, '$t0 + ($t1 << 1) + ' . $K[--$ki]) . '; $R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31; $R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ ' . sprintf($safeint, '($t0 + $t1 + ' . $K[--$ki] . ')') . '; $t0 = $S0[$R2 & 0xff] ^ $S1[$R2 >> 8 & 0xff] ^ $S2[$R2 >> 16 & 0xff] ^ $S3[$R2 >> 24 & 0xff]; $t1 = $S0[$R3 >> 24 & 0xff] ^ $S1[$R3 & 0xff] ^ $S2[$R3 >> 8 & 0xff] ^ $S3[$R3 >> 16 & 0xff]; $R1^= ' . sprintf($safeint, '$t0 + ($t1 << 1) + ' . $K[--$ki]) . '; $R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31; $R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ ' . sprintf($safeint, '($t0 + $t1 + ' . $K[--$ki] . ')') . '; '; } $decrypt_block .= ' $in = pack("V4", ' . $K[0] . ' ^ $R2, ' . $K[1] . ' ^ $R3, ' . $K[2] . ' ^ $R0, ' . $K[3] . ' ^ $R1); '; $this->inline_crypt = $this->createInlineCryptFunction( [ 'init_crypt' => $init_crypt, 'init_encrypt' => '', 'init_decrypt' => '', 'encrypt_block' => $encrypt_block, 'decrypt_block' => $decrypt_block ] ); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Exception/BadConfigurationException.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Exception; /** * BadConfigurationException * * @author Jim Wigginton */ class BadConfigurationException extends \RuntimeException { } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Exception/BadDecryptionException.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Exception; /** * BadDecryptionException * * @author Jim Wigginton */ class BadDecryptionException extends \RuntimeException { } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Exception/BadModeException.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Exception; /** * BadModeException * * @author Jim Wigginton */ class BadModeException extends \RuntimeException { } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Exception/ConnectionClosedException.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Exception; /** * ConnectionClosedException * * @author Jim Wigginton */ class ConnectionClosedException extends \RuntimeException { } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Exception/FileNotFoundException.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Exception; /** * FileNotFoundException * * @author Jim Wigginton */ class FileNotFoundException extends \RuntimeException { } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Exception/InconsistentSetupException.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Exception; /** * InconsistentSetupException * * @author Jim Wigginton */ class InconsistentSetupException extends \RuntimeException { } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Exception/InsufficientSetupException.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Exception; /** * InsufficientSetupException * * @author Jim Wigginton */ class InsufficientSetupException extends \RuntimeException { } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Exception/InvalidPacketLengthException.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Exception; /** * NoKeyLoadedException * * @author Jim Wigginton */ class NoKeyLoadedException extends \RuntimeException { } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Exception/NoSupportedAlgorithmsException.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Exception; /** * NoSupportedAlgorithmsException * * @author Jim Wigginton */ class NoSupportedAlgorithmsException extends \RuntimeException { } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Exception/TimeoutException.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Exception; /** * UnableToConnectException * * @author Jim Wigginton */ class UnableToConnectException extends \RuntimeException { } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedAlgorithmException.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Exception; /** * UnsupportedAlgorithmException * * @author Jim Wigginton */ class UnsupportedAlgorithmException extends \RuntimeException { } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedCurveException.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Exception; /** * UnsupportedCurveException * * @author Jim Wigginton */ class UnsupportedCurveException extends \RuntimeException { } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedFormatException.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Exception; /** * UnsupportedFormatException * * @author Jim Wigginton */ class UnsupportedFormatException extends \RuntimeException { } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedOperationException.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Exception; /** * UnsupportedOperationException * * @author Jim Wigginton */ class UnsupportedOperationException extends \RuntimeException { } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php ================================================ * @copyright 2012 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File; /** * Pure-PHP ANSI Decoder * * @author Jim Wigginton */ class ANSI { /** * Max Width * * @var int */ private $max_x; /** * Max Height * * @var int */ private $max_y; /** * Max History * * @var int */ private $max_history; /** * History * * @var array */ private $history; /** * History Attributes * * @var array */ private $history_attrs; /** * Current Column * * @var int */ private $x; /** * Current Row * * @var int */ private $y; /** * Old Column * * @var int */ private $old_x; /** * Old Row * * @var int */ private $old_y; /** * An empty attribute cell * * @var object */ private $base_attr_cell; /** * The current attribute cell * * @var object */ private $attr_cell; /** * An empty attribute row * * @var array */ private $attr_row; /** * The current screen text * * @var list */ private $screen; /** * The current screen attributes * * @var array */ private $attrs; /** * Current ANSI code * * @var string */ private $ansi; /** * Tokenization * * @var array */ private $tokenization; /** * Default Constructor. * * @return ANSI */ public function __construct() { $attr_cell = new \stdClass(); $attr_cell->bold = false; $attr_cell->underline = false; $attr_cell->blink = false; $attr_cell->background = 'black'; $attr_cell->foreground = 'white'; $attr_cell->reverse = false; $this->base_attr_cell = clone $attr_cell; $this->attr_cell = clone $attr_cell; $this->setHistory(200); $this->setDimensions(80, 24); } /** * Set terminal width and height * * Resets the screen as well * * @param int $x * @param int $y */ public function setDimensions($x, $y) { $this->max_x = $x - 1; $this->max_y = $y - 1; $this->x = $this->y = 0; $this->history = $this->history_attrs = []; $this->attr_row = array_fill(0, $this->max_x + 2, $this->base_attr_cell); $this->screen = array_fill(0, $this->max_y + 1, ''); $this->attrs = array_fill(0, $this->max_y + 1, $this->attr_row); $this->ansi = ''; } /** * Set the number of lines that should be logged past the terminal height * * @param int $history */ public function setHistory($history) { $this->max_history = $history; } /** * Load a string * * @param string $source */ public function loadString($source) { $this->setDimensions($this->max_x + 1, $this->max_y + 1); $this->appendString($source); } /** * Appdend a string * * @param string $source */ public function appendString($source) { $this->tokenization = ['']; for ($i = 0; $i < strlen($source); $i++) { if (strlen($this->ansi)) { $this->ansi .= $source[$i]; $chr = ord($source[$i]); // http://en.wikipedia.org/wiki/ANSI_escape_code#Sequence_elements // single character CSI's not currently supported switch (true) { case $this->ansi == "\x1B=": $this->ansi = ''; continue 2; case strlen($this->ansi) == 2 && $chr >= 64 && $chr <= 95 && $chr != ord('['): case strlen($this->ansi) > 2 && $chr >= 64 && $chr <= 126: break; default: continue 2; } $this->tokenization[] = $this->ansi; $this->tokenization[] = ''; // http://ascii-table.com/ansi-escape-sequences-vt-100.php switch ($this->ansi) { case "\x1B[H": // Move cursor to upper left corner $this->old_x = $this->x; $this->old_y = $this->y; $this->x = $this->y = 0; break; case "\x1B[J": // Clear screen from cursor down $this->history = array_merge($this->history, array_slice(array_splice($this->screen, $this->y + 1), 0, $this->old_y)); $this->screen = array_merge($this->screen, array_fill($this->y, $this->max_y, '')); $this->history_attrs = array_merge($this->history_attrs, array_slice(array_splice($this->attrs, $this->y + 1), 0, $this->old_y)); $this->attrs = array_merge($this->attrs, array_fill($this->y, $this->max_y, $this->attr_row)); if (count($this->history) == $this->max_history) { array_shift($this->history); array_shift($this->history_attrs); } // fall-through case "\x1B[K": // Clear screen from cursor right $this->screen[$this->y] = substr($this->screen[$this->y], 0, $this->x); array_splice($this->attrs[$this->y], $this->x + 1, $this->max_x - $this->x, array_fill($this->x, $this->max_x - ($this->x - 1), $this->base_attr_cell)); break; case "\x1B[2K": // Clear entire line $this->screen[$this->y] = str_repeat(' ', $this->x); $this->attrs[$this->y] = $this->attr_row; break; case "\x1B[?1h": // set cursor key to application case "\x1B[?25h": // show the cursor case "\x1B(B": // set united states g0 character set break; case "\x1BE": // Move to next line $this->newLine(); $this->x = 0; break; default: switch (true) { case preg_match('#\x1B\[(\d+)B#', $this->ansi, $match): // Move cursor down n lines $this->old_y = $this->y; $this->y += (int) $match[1]; break; case preg_match('#\x1B\[(\d+);(\d+)H#', $this->ansi, $match): // Move cursor to screen location v,h $this->old_x = $this->x; $this->old_y = $this->y; $this->x = $match[2] - 1; $this->y = (int) $match[1] - 1; break; case preg_match('#\x1B\[(\d+)C#', $this->ansi, $match): // Move cursor right n lines $this->old_x = $this->x; $this->x += $match[1]; break; case preg_match('#\x1B\[(\d+)D#', $this->ansi, $match): // Move cursor left n lines $this->old_x = $this->x; $this->x -= $match[1]; if ($this->x < 0) { $this->x = 0; } break; case preg_match('#\x1B\[(\d+);(\d+)r#', $this->ansi, $match): // Set top and bottom lines of a window break; case preg_match('#\x1B\[(\d*(?:;\d*)*)m#', $this->ansi, $match): // character attributes $attr_cell = &$this->attr_cell; $mods = explode(';', $match[1]); foreach ($mods as $mod) { switch ($mod) { case '': case '0': // Turn off character attributes $attr_cell = clone $this->base_attr_cell; break; case '1': // Turn bold mode on $attr_cell->bold = true; break; case '4': // Turn underline mode on $attr_cell->underline = true; break; case '5': // Turn blinking mode on $attr_cell->blink = true; break; case '7': // Turn reverse video on $attr_cell->reverse = !$attr_cell->reverse; $temp = $attr_cell->background; $attr_cell->background = $attr_cell->foreground; $attr_cell->foreground = $temp; break; default: // set colors //$front = $attr_cell->reverse ? &$attr_cell->background : &$attr_cell->foreground; $front = &$attr_cell->{ $attr_cell->reverse ? 'background' : 'foreground' }; //$back = $attr_cell->reverse ? &$attr_cell->foreground : &$attr_cell->background; $back = &$attr_cell->{ $attr_cell->reverse ? 'foreground' : 'background' }; switch ($mod) { // @codingStandardsIgnoreStart case '30': $front = 'black'; break; case '31': $front = 'red'; break; case '32': $front = 'green'; break; case '33': $front = 'yellow'; break; case '34': $front = 'blue'; break; case '35': $front = 'magenta'; break; case '36': $front = 'cyan'; break; case '37': $front = 'white'; break; case '40': $back = 'black'; break; case '41': $back = 'red'; break; case '42': $back = 'green'; break; case '43': $back = 'yellow'; break; case '44': $back = 'blue'; break; case '45': $back = 'magenta'; break; case '46': $back = 'cyan'; break; case '47': $back = 'white'; break; // @codingStandardsIgnoreEnd default: //user_error('Unsupported attribute: ' . $mod); $this->ansi = ''; break 2; } } } break; default: //user_error("{$this->ansi} is unsupported\r\n"); } } $this->ansi = ''; continue; } $this->tokenization[count($this->tokenization) - 1] .= $source[$i]; switch ($source[$i]) { case "\r": $this->x = 0; break; case "\n": $this->newLine(); break; case "\x08": // backspace if ($this->x) { $this->x--; $this->attrs[$this->y][$this->x] = clone $this->base_attr_cell; $this->screen[$this->y] = substr_replace( $this->screen[$this->y], $source[$i], $this->x, 1 ); } break; case "\x0F": // shift break; case "\x1B": // start ANSI escape code $this->tokenization[count($this->tokenization) - 1] = substr($this->tokenization[count($this->tokenization) - 1], 0, -1); //if (!strlen($this->tokenization[count($this->tokenization) - 1])) { // array_pop($this->tokenization); //} $this->ansi .= "\x1B"; break; default: $this->attrs[$this->y][$this->x] = clone $this->attr_cell; if ($this->x > strlen($this->screen[$this->y])) { $this->screen[$this->y] = str_repeat(' ', $this->x); } $this->screen[$this->y] = substr_replace( $this->screen[$this->y], $source[$i], $this->x, 1 ); if ($this->x > $this->max_x) { $this->x = 0; $this->newLine(); } else { $this->x++; } } } } /** * Add a new line * * Also update the $this->screen and $this->history buffers * */ private function newLine() { //if ($this->y < $this->max_y) { // $this->y++; //} while ($this->y >= $this->max_y) { $this->history = array_merge($this->history, [array_shift($this->screen)]); $this->screen[] = ''; $this->history_attrs = array_merge($this->history_attrs, [array_shift($this->attrs)]); $this->attrs[] = $this->attr_row; if (count($this->history) >= $this->max_history) { array_shift($this->history); array_shift($this->history_attrs); } $this->y--; } $this->y++; } /** * Returns the current coordinate without preformating * * @param \stdClass $last_attr * @param \stdClass $cur_attr * @param string $char * @return string */ private function processCoordinate(\stdClass $last_attr, \stdClass $cur_attr, $char) { $output = ''; if ($last_attr != $cur_attr) { $close = $open = ''; if ($last_attr->foreground != $cur_attr->foreground) { if ($cur_attr->foreground != 'white') { $open .= ''; } if ($last_attr->foreground != 'white') { $close = '' . $close; } } if ($last_attr->background != $cur_attr->background) { if ($cur_attr->background != 'black') { $open .= ''; } if ($last_attr->background != 'black') { $close = '' . $close; } } if ($last_attr->bold != $cur_attr->bold) { if ($cur_attr->bold) { $open .= ''; } else { $close = '' . $close; } } if ($last_attr->underline != $cur_attr->underline) { if ($cur_attr->underline) { $open .= ''; } else { $close = '' . $close; } } if ($last_attr->blink != $cur_attr->blink) { if ($cur_attr->blink) { $open .= ''; } else { $close = '' . $close; } } $output .= $close . $open; } $output .= htmlspecialchars($char); return $output; } /** * Returns the current screen without preformating * * @return string */ private function getScreenHelper() { $output = ''; $last_attr = $this->base_attr_cell; for ($i = 0; $i <= $this->max_y; $i++) { for ($j = 0; $j <= $this->max_x; $j++) { $cur_attr = $this->attrs[$i][$j]; $output .= $this->processCoordinate($last_attr, $cur_attr, isset($this->screen[$i][$j]) ? $this->screen[$i][$j] : ''); $last_attr = $this->attrs[$i][$j]; } $output .= "\r\n"; } $output = substr($output, 0, -2); // close any remaining open tags $output .= $this->processCoordinate($last_attr, $this->base_attr_cell, ''); return rtrim($output); } /** * Returns the current screen * * @return string */ public function getScreen() { return '
' . $this->getScreenHelper() . '
'; } /** * Returns the current screen and the x previous lines * * @return string */ public function getHistory() { $scrollback = ''; $last_attr = $this->base_attr_cell; for ($i = 0; $i < count($this->history); $i++) { for ($j = 0; $j <= $this->max_x + 1; $j++) { $cur_attr = $this->history_attrs[$i][$j]; $scrollback .= $this->processCoordinate($last_attr, $cur_attr, isset($this->history[$i][$j]) ? $this->history[$i][$j] : ''); $last_attr = $this->history_attrs[$i][$j]; } $scrollback .= "\r\n"; } $base_attr_cell = $this->base_attr_cell; $this->base_attr_cell = $last_attr; $scrollback .= $this->getScreen(); $this->base_attr_cell = $base_attr_cell; return '
' . $scrollback . '
'; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Element.php ================================================ * @copyright 2012 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1; /** * ASN.1 Raw Element * * An ASN.1 ANY mapping will return an ASN1\Element object. Use of this object * will also bypass the normal encoding rules in ASN1::encodeDER() * * @author Jim Wigginton */ class Element { /** * Raw element value * * @var string */ public $element; /** * Constructor * * @param string $encoded * @return Element */ public function __construct($encoded) { $this->element = $encoded; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AccessDescription.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * AccessDescription * * @author Jim Wigginton */ abstract class AccessDescription { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'accessMethod' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], 'accessLocation' => GeneralName::MAP ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AdministrationDomainName.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * AdministrationDomainName * * @author Jim Wigginton */ abstract class AdministrationDomainName { const MAP = [ 'type' => ASN1::TYPE_CHOICE, // if class isn't present it's assumed to be \phpseclib3\File\ASN1::CLASS_UNIVERSAL or // (if constant is present) \phpseclib3\File\ASN1::CLASS_CONTEXT_SPECIFIC 'class' => ASN1::CLASS_APPLICATION, 'cast' => 2, 'children' => [ 'numeric' => ['type' => ASN1::TYPE_NUMERIC_STRING], 'printable' => ['type' => ASN1::TYPE_PRINTABLE_STRING] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AlgorithmIdentifier.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * AlgorithmIdentifier * * @author Jim Wigginton */ abstract class AlgorithmIdentifier { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'algorithm' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], 'parameters' => [ 'type' => ASN1::TYPE_ANY, 'optional' => true ] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AnotherName.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * AnotherName * * @author Jim Wigginton */ abstract class AnotherName { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'type-id' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], 'value' => [ 'type' => ASN1::TYPE_ANY, 'constant' => 0, 'optional' => true, 'explicit' => true ] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attribute.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * Attribute * * @author Jim Wigginton */ abstract class Attribute { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'type' => AttributeType::MAP, 'value' => [ 'type' => ASN1::TYPE_SET, 'min' => 1, 'max' => -1, 'children' => AttributeValue::MAP ] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeType.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * AttributeType * * @author Jim Wigginton */ abstract class AttributeType { const MAP = ['type' => ASN1::TYPE_OBJECT_IDENTIFIER]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeTypeAndValue.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * AttributeTypeAndValue * * @author Jim Wigginton */ abstract class AttributeTypeAndValue { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'type' => AttributeType::MAP, 'value' => AttributeValue::MAP ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeValue.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * AttributeValue * * @author Jim Wigginton */ abstract class AttributeValue { const MAP = ['type' => ASN1::TYPE_ANY]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attributes.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * Attributes * * @author Jim Wigginton */ abstract class Attributes { const MAP = [ 'type' => ASN1::TYPE_SET, 'min' => 1, 'max' => -1, 'children' => Attribute::MAP ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityInfoAccessSyntax.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * AuthorityInfoAccessSyntax * * @author Jim Wigginton */ abstract class AuthorityInfoAccessSyntax { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'min' => 1, 'max' => -1, 'children' => AccessDescription::MAP ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityKeyIdentifier.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * AuthorityKeyIdentifier * * @author Jim Wigginton */ abstract class AuthorityKeyIdentifier { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'keyIdentifier' => [ 'constant' => 0, 'optional' => true, 'implicit' => true ] + KeyIdentifier::MAP, 'authorityCertIssuer' => [ 'constant' => 1, 'optional' => true, 'implicit' => true ] + GeneralNames::MAP, 'authorityCertSerialNumber' => [ 'constant' => 2, 'optional' => true, 'implicit' => true ] + CertificateSerialNumber::MAP ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BaseDistance.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * BaseDistance * * @author Jim Wigginton */ abstract class BaseDistance { const MAP = ['type' => ASN1::TYPE_INTEGER]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BasicConstraints.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * BasicConstraints * * @author Jim Wigginton */ abstract class BasicConstraints { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'cA' => [ 'type' => ASN1::TYPE_BOOLEAN, 'optional' => true, 'default' => false ], 'pathLenConstraint' => [ 'type' => ASN1::TYPE_INTEGER, 'optional' => true ] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttribute.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * BuiltInDomainDefinedAttribute * * @author Jim Wigginton */ abstract class BuiltInDomainDefinedAttribute { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'type' => ['type' => ASN1::TYPE_PRINTABLE_STRING], 'value' => ['type' => ASN1::TYPE_PRINTABLE_STRING] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttributes.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * BuiltInDomainDefinedAttributes * * @author Jim Wigginton */ abstract class BuiltInDomainDefinedAttributes { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'min' => 1, 'max' => 4, // ub-domain-defined-attributes 'children' => BuiltInDomainDefinedAttribute::MAP ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInStandardAttributes.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * BuiltInStandardAttributes * * @author Jim Wigginton */ abstract class BuiltInStandardAttributes { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'country-name' => ['optional' => true] + CountryName::MAP, 'administration-domain-name' => ['optional' => true] + AdministrationDomainName::MAP, 'network-address' => [ 'constant' => 0, 'optional' => true, 'implicit' => true ] + NetworkAddress::MAP, 'terminal-identifier' => [ 'constant' => 1, 'optional' => true, 'implicit' => true ] + TerminalIdentifier::MAP, 'private-domain-name' => [ 'constant' => 2, 'optional' => true, 'explicit' => true ] + PrivateDomainName::MAP, 'organization-name' => [ 'constant' => 3, 'optional' => true, 'implicit' => true ] + OrganizationName::MAP, 'numeric-user-identifier' => [ 'constant' => 4, 'optional' => true, 'implicit' => true ] + NumericUserIdentifier::MAP, 'personal-name' => [ 'constant' => 5, 'optional' => true, 'implicit' => true ] + PersonalName::MAP, 'organizational-unit-names' => [ 'constant' => 6, 'optional' => true, 'implicit' => true ] + OrganizationalUnitNames::MAP ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CPSuri.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * CPSuri * * @author Jim Wigginton */ abstract class CPSuri { const MAP = ['type' => ASN1::TYPE_IA5_STRING]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLDistributionPoints.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * CRLDistributionPoints * * @author Jim Wigginton */ abstract class CRLDistributionPoints { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'min' => 1, 'max' => -1, 'children' => DistributionPoint::MAP ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLNumber.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * CRLNumber * * @author Jim Wigginton */ abstract class CRLNumber { const MAP = ['type' => ASN1::TYPE_INTEGER]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLReason.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * CRLReason * * @author Jim Wigginton */ abstract class CRLReason { const MAP = [ 'type' => ASN1::TYPE_ENUMERATED, 'mapping' => [ 'unspecified', 'keyCompromise', 'cACompromise', 'affiliationChanged', 'superseded', 'cessationOfOperation', 'certificateHold', // Value 7 is not used. 8 => 'removeFromCRL', 'privilegeWithdrawn', 'aACompromise' ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertPolicyId.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * CertPolicyId * * @author Jim Wigginton */ abstract class CertPolicyId { const MAP = ['type' => ASN1::TYPE_OBJECT_IDENTIFIER]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Certificate.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * Certificate * * @author Jim Wigginton */ abstract class Certificate { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'tbsCertificate' => TBSCertificate::MAP, 'signatureAlgorithm' => AlgorithmIdentifier::MAP, 'signature' => ['type' => ASN1::TYPE_BIT_STRING] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateIssuer.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; /** * CertificateIssuer * * @author Jim Wigginton */ abstract class CertificateIssuer { const MAP = GeneralNames::MAP; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateList.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * CertificateList * * @author Jim Wigginton */ abstract class CertificateList { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'tbsCertList' => TBSCertList::MAP, 'signatureAlgorithm' => AlgorithmIdentifier::MAP, 'signature' => ['type' => ASN1::TYPE_BIT_STRING] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificatePolicies.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * CertificatePolicies * * @author Jim Wigginton */ abstract class CertificatePolicies { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'min' => 1, 'max' => -1, 'children' => PolicyInformation::MAP ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateSerialNumber.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * CertificateSerialNumber * * @author Jim Wigginton */ abstract class CertificateSerialNumber { const MAP = ['type' => ASN1::TYPE_INTEGER]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequest.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * CertificationRequest * * @author Jim Wigginton */ abstract class CertificationRequest { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'certificationRequestInfo' => CertificationRequestInfo::MAP, 'signatureAlgorithm' => AlgorithmIdentifier::MAP, 'signature' => ['type' => ASN1::TYPE_BIT_STRING] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequestInfo.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * CertificationRequestInfo * * @author Jim Wigginton */ abstract class CertificationRequestInfo { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'version' => [ 'type' => ASN1::TYPE_INTEGER, 'mapping' => ['v1'] ], 'subject' => Name::MAP, 'subjectPKInfo' => SubjectPublicKeyInfo::MAP, 'attributes' => [ 'constant' => 0, 'optional' => true, 'implicit' => true ] + Attributes::MAP, ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Characteristic_two.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * Characteristic_two * * @author Jim Wigginton */ abstract class Characteristic_two { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'm' => ['type' => ASN1::TYPE_INTEGER], // field size 2**m 'basis' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], 'parameters' => [ 'type' => ASN1::TYPE_ANY, 'optional' => true ] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CountryName.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * CountryName * * @author Jim Wigginton */ abstract class CountryName { const MAP = [ 'type' => ASN1::TYPE_CHOICE, // if class isn't present it's assumed to be \phpseclib3\File\ASN1::CLASS_UNIVERSAL or // (if constant is present) \phpseclib3\File\ASN1::CLASS_CONTEXT_SPECIFIC 'class' => ASN1::CLASS_APPLICATION, 'cast' => 1, 'children' => [ 'x121-dcc-code' => ['type' => ASN1::TYPE_NUMERIC_STRING], 'iso-3166-alpha2-code' => ['type' => ASN1::TYPE_PRINTABLE_STRING] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Curve.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * Curve * * @author Jim Wigginton */ abstract class Curve { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'a' => FieldElement::MAP, 'b' => FieldElement::MAP, 'seed' => [ 'type' => ASN1::TYPE_BIT_STRING, 'optional' => true ] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DHParameter.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * DHParameter * * @author Jim Wigginton */ abstract class DHParameter { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'prime' => ['type' => ASN1::TYPE_INTEGER], 'base' => ['type' => ASN1::TYPE_INTEGER], 'privateValueLength' => [ 'type' => ASN1::TYPE_INTEGER, 'optional' => true ] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAParams.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * DSAParams * * @author Jim Wigginton */ abstract class DSAParams { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'p' => ['type' => ASN1::TYPE_INTEGER], 'q' => ['type' => ASN1::TYPE_INTEGER], 'g' => ['type' => ASN1::TYPE_INTEGER] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPrivateKey.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * DSAPrivateKey * * @author Jim Wigginton */ abstract class DSAPrivateKey { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'version' => ['type' => ASN1::TYPE_INTEGER], 'p' => ['type' => ASN1::TYPE_INTEGER], 'q' => ['type' => ASN1::TYPE_INTEGER], 'g' => ['type' => ASN1::TYPE_INTEGER], 'y' => ['type' => ASN1::TYPE_INTEGER], 'x' => ['type' => ASN1::TYPE_INTEGER] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPublicKey.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * DSAPublicKey * * @author Jim Wigginton */ abstract class DSAPublicKey { const MAP = ['type' => ASN1::TYPE_INTEGER]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DigestInfo.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * DigestInfo * * from https://tools.ietf.org/html/rfc2898#appendix-A.3 * * @author Jim Wigginton */ abstract class DigestInfo { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'digestAlgorithm' => AlgorithmIdentifier::MAP, 'digest' => ['type' => ASN1::TYPE_OCTET_STRING] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DirectoryString.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * DirectoryString * * @author Jim Wigginton */ abstract class DirectoryString { const MAP = [ 'type' => ASN1::TYPE_CHOICE, 'children' => [ 'teletexString' => ['type' => ASN1::TYPE_TELETEX_STRING], 'printableString' => ['type' => ASN1::TYPE_PRINTABLE_STRING], 'universalString' => ['type' => ASN1::TYPE_UNIVERSAL_STRING], 'utf8String' => ['type' => ASN1::TYPE_UTF8_STRING], 'bmpString' => ['type' => ASN1::TYPE_BMP_STRING] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DisplayText.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * DisplayText * * @author Jim Wigginton */ abstract class DisplayText { const MAP = [ 'type' => ASN1::TYPE_CHOICE, 'children' => [ 'ia5String' => ['type' => ASN1::TYPE_IA5_STRING], 'visibleString' => ['type' => ASN1::TYPE_VISIBLE_STRING], 'bmpString' => ['type' => ASN1::TYPE_BMP_STRING], 'utf8String' => ['type' => ASN1::TYPE_UTF8_STRING] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPoint.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * DistributionPoint * * @author Jim Wigginton */ abstract class DistributionPoint { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'distributionPoint' => [ 'constant' => 0, 'optional' => true, 'explicit' => true ] + DistributionPointName::MAP, 'reasons' => [ 'constant' => 1, 'optional' => true, 'implicit' => true ] + ReasonFlags::MAP, 'cRLIssuer' => [ 'constant' => 2, 'optional' => true, 'implicit' => true ] + GeneralNames::MAP ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPointName.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * DistributionPointName * * @author Jim Wigginton */ abstract class DistributionPointName { const MAP = [ 'type' => ASN1::TYPE_CHOICE, 'children' => [ 'fullName' => [ 'constant' => 0, 'optional' => true, 'implicit' => true ] + GeneralNames::MAP, 'nameRelativeToCRLIssuer' => [ 'constant' => 1, 'optional' => true, 'implicit' => true ] + RelativeDistinguishedName::MAP ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DssSigValue.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * DssSigValue * * @author Jim Wigginton */ abstract class DssSigValue { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'r' => ['type' => ASN1::TYPE_INTEGER], 's' => ['type' => ASN1::TYPE_INTEGER] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECParameters.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * ECParameters * * ECParameters ::= CHOICE { * namedCurve OBJECT IDENTIFIER * -- implicitCurve NULL * -- specifiedCurve SpecifiedECDomain * } * -- implicitCurve and specifiedCurve MUST NOT be used in PKIX. * -- Details for SpecifiedECDomain can be found in [X9.62]. * -- Any future additions to this CHOICE should be coordinated * -- with ANSI X9. * * @author Jim Wigginton */ abstract class ECParameters { const MAP = [ 'type' => ASN1::TYPE_CHOICE, 'children' => [ 'namedCurve' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], 'implicitCurve' => ['type' => ASN1::TYPE_NULL], 'specifiedCurve' => SpecifiedECDomain::MAP ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPoint.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * ECPoint * * @author Jim Wigginton */ abstract class ECPoint { const MAP = ['type' => ASN1::TYPE_OCTET_STRING]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPrivateKey.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * ECPrivateKey * * @author Jim Wigginton */ abstract class ECPrivateKey { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'version' => [ 'type' => ASN1::TYPE_INTEGER, 'mapping' => [1 => 'ecPrivkeyVer1'] ], 'privateKey' => ['type' => ASN1::TYPE_OCTET_STRING], 'parameters' => [ 'constant' => 0, 'optional' => true, 'explicit' => true ] + ECParameters::MAP, 'publicKey' => [ 'type' => ASN1::TYPE_BIT_STRING, 'constant' => 1, 'optional' => true, 'explicit' => true ] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EDIPartyName.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * EDIPartyName * * @author Jim Wigginton */ abstract class EDIPartyName { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'nameAssigner' => [ 'constant' => 0, 'optional' => true, 'implicit' => true ] + DirectoryString::MAP, // partyName is technically required but \phpseclib3\File\ASN1 doesn't currently support non-optional constants and // setting it to optional gets the job done in any event. 'partyName' => [ 'constant' => 1, 'optional' => true, 'implicit' => true ] + DirectoryString::MAP ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EcdsaSigValue.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * EcdsaSigValue * * @author Jim Wigginton */ abstract class EcdsaSigValue { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'r' => ['type' => ASN1::TYPE_INTEGER], 's' => ['type' => ASN1::TYPE_INTEGER] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedData.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * EncryptedData * * @author Jim Wigginton */ abstract class EncryptedData { const MAP = ['type' => ASN1::TYPE_OCTET_STRING]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedPrivateKeyInfo.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * EncryptedPrivateKeyInfo * * @author Jim Wigginton */ abstract class EncryptedPrivateKeyInfo { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'encryptionAlgorithm' => AlgorithmIdentifier::MAP, 'encryptedData' => EncryptedData::MAP ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtKeyUsageSyntax.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * ExtKeyUsageSyntax * * @author Jim Wigginton */ abstract class ExtKeyUsageSyntax { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'min' => 1, 'max' => -1, 'children' => KeyPurposeId::MAP ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extension.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * Extension * * A certificate using system MUST reject the certificate if it encounters * a critical extension it does not recognize; however, a non-critical * extension may be ignored if it is not recognized. * * http://tools.ietf.org/html/rfc5280#section-4.2 * * @author Jim Wigginton */ abstract class Extension { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'extnId' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], 'critical' => [ 'type' => ASN1::TYPE_BOOLEAN, 'optional' => true, 'default' => false ], 'extnValue' => ['type' => ASN1::TYPE_OCTET_STRING] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttribute.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * ExtensionAttribute * * @author Jim Wigginton */ abstract class ExtensionAttribute { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'extension-attribute-type' => [ 'type' => ASN1::TYPE_PRINTABLE_STRING, 'constant' => 0, 'optional' => true, 'implicit' => true ], 'extension-attribute-value' => [ 'type' => ASN1::TYPE_ANY, 'constant' => 1, 'optional' => true, 'explicit' => true ] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttributes.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * ExtensionAttributes * * @author Jim Wigginton */ abstract class ExtensionAttributes { const MAP = [ 'type' => ASN1::TYPE_SET, 'min' => 1, 'max' => 256, // ub-extension-attributes 'children' => ExtensionAttribute::MAP ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extensions.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * Extensions * * @author Jim Wigginton */ abstract class Extensions { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'min' => 1, // technically, it's MAX, but we'll assume anything < 0 is MAX 'max' => -1, // if 'children' isn't an array then 'min' and 'max' must be defined 'children' => Extension::MAP ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldElement.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * FieldElement * * @author Jim Wigginton */ abstract class FieldElement { const MAP = ['type' => ASN1::TYPE_OCTET_STRING]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldID.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * FieldID * * @author Jim Wigginton */ abstract class FieldID { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'fieldType' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], 'parameters' => [ 'type' => ASN1::TYPE_ANY, 'optional' => true ] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralName.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * GeneralName * * @author Jim Wigginton */ abstract class GeneralName { const MAP = [ 'type' => ASN1::TYPE_CHOICE, 'children' => [ 'otherName' => [ 'constant' => 0, 'optional' => true, 'implicit' => true ] + AnotherName::MAP, 'rfc822Name' => [ 'type' => ASN1::TYPE_IA5_STRING, 'constant' => 1, 'optional' => true, 'implicit' => true ], 'dNSName' => [ 'type' => ASN1::TYPE_IA5_STRING, 'constant' => 2, 'optional' => true, 'implicit' => true ], 'x400Address' => [ 'constant' => 3, 'optional' => true, 'implicit' => true ] + ORAddress::MAP, 'directoryName' => [ 'constant' => 4, 'optional' => true, 'explicit' => true ] + Name::MAP, 'ediPartyName' => [ 'constant' => 5, 'optional' => true, 'implicit' => true ] + EDIPartyName::MAP, 'uniformResourceIdentifier' => [ 'type' => ASN1::TYPE_IA5_STRING, 'constant' => 6, 'optional' => true, 'implicit' => true ], 'iPAddress' => [ 'type' => ASN1::TYPE_OCTET_STRING, 'constant' => 7, 'optional' => true, 'implicit' => true ], 'registeredID' => [ 'type' => ASN1::TYPE_OBJECT_IDENTIFIER, 'constant' => 8, 'optional' => true, 'implicit' => true ] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralNames.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * GeneralNames * * @author Jim Wigginton */ abstract class GeneralNames { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'min' => 1, 'max' => -1, 'children' => GeneralName::MAP ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtree.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * GeneralSubtree * * @author Jim Wigginton */ abstract class GeneralSubtree { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'base' => GeneralName::MAP, 'minimum' => [ 'constant' => 0, 'optional' => true, 'implicit' => true, 'default' => '0' ] + BaseDistance::MAP, 'maximum' => [ 'constant' => 1, 'optional' => true, 'implicit' => true, ] + BaseDistance::MAP ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtrees.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * GeneralSubtrees * * @author Jim Wigginton */ abstract class GeneralSubtrees { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'min' => 1, 'max' => -1, 'children' => GeneralSubtree::MAP ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HashAlgorithm.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; /** * HashAglorithm * * @author Jim Wigginton */ abstract class HashAlgorithm { const MAP = AlgorithmIdentifier::MAP; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HoldInstructionCode.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * HoldInstructionCode * * @author Jim Wigginton */ abstract class HoldInstructionCode { const MAP = ['type' => ASN1::TYPE_OBJECT_IDENTIFIER]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/InvalidityDate.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * InvalidityDate * * @author Jim Wigginton */ abstract class InvalidityDate { const MAP = ['type' => ASN1::TYPE_GENERALIZED_TIME]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuerAltName.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; /** * IssuerAltName * * @author Jim Wigginton */ abstract class IssuerAltName { const MAP = GeneralNames::MAP; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuingDistributionPoint.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * IssuingDistributionPoint * * @author Jim Wigginton */ abstract class IssuingDistributionPoint { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'distributionPoint' => [ 'constant' => 0, 'optional' => true, 'explicit' => true ] + DistributionPointName::MAP, 'onlyContainsUserCerts' => [ 'type' => ASN1::TYPE_BOOLEAN, 'constant' => 1, 'optional' => true, 'default' => false, 'implicit' => true ], 'onlyContainsCACerts' => [ 'type' => ASN1::TYPE_BOOLEAN, 'constant' => 2, 'optional' => true, 'default' => false, 'implicit' => true ], 'onlySomeReasons' => [ 'constant' => 3, 'optional' => true, 'implicit' => true ] + ReasonFlags::MAP, 'indirectCRL' => [ 'type' => ASN1::TYPE_BOOLEAN, 'constant' => 4, 'optional' => true, 'default' => false, 'implicit' => true ], 'onlyContainsAttributeCerts' => [ 'type' => ASN1::TYPE_BOOLEAN, 'constant' => 5, 'optional' => true, 'default' => false, 'implicit' => true ] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyIdentifier.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * KeyIdentifier * * @author Jim Wigginton */ abstract class KeyIdentifier { const MAP = ['type' => ASN1::TYPE_OCTET_STRING]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyPurposeId.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * KeyPurposeId * * @author Jim Wigginton */ abstract class KeyPurposeId { const MAP = ['type' => ASN1::TYPE_OBJECT_IDENTIFIER]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyUsage.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * KeyUsage * * @author Jim Wigginton */ abstract class KeyUsage { const MAP = [ 'type' => ASN1::TYPE_BIT_STRING, 'mapping' => [ 'digitalSignature', 'nonRepudiation', 'keyEncipherment', 'dataEncipherment', 'keyAgreement', 'keyCertSign', 'cRLSign', 'encipherOnly', 'decipherOnly' ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/MaskGenAlgorithm.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; /** * MaskGenAglorithm * * @author Jim Wigginton */ abstract class MaskGenAlgorithm { const MAP = AlgorithmIdentifier::MAP; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Name.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * Name * * @author Jim Wigginton */ abstract class Name { const MAP = [ 'type' => ASN1::TYPE_CHOICE, 'children' => [ 'rdnSequence' => RDNSequence::MAP ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NameConstraints.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * NameConstraints * * @author Jim Wigginton */ abstract class NameConstraints { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'permittedSubtrees' => [ 'constant' => 0, 'optional' => true, 'implicit' => true ] + GeneralSubtrees::MAP, 'excludedSubtrees' => [ 'constant' => 1, 'optional' => true, 'implicit' => true ] + GeneralSubtrees::MAP ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NetworkAddress.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * NetworkAddress * * @author Jim Wigginton */ abstract class NetworkAddress { const MAP = ['type' => ASN1::TYPE_NUMERIC_STRING]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NoticeReference.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * NoticeReference * * @author Jim Wigginton */ abstract class NoticeReference { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'organization' => DisplayText::MAP, 'noticeNumbers' => [ 'type' => ASN1::TYPE_SEQUENCE, 'min' => 1, 'max' => 200, 'children' => ['type' => ASN1::TYPE_INTEGER] ] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NumericUserIdentifier.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * NumericUserIdentifier * * @author Jim Wigginton */ abstract class NumericUserIdentifier { const MAP = ['type' => ASN1::TYPE_NUMERIC_STRING]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ORAddress.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * ORAddress * * @author Jim Wigginton */ abstract class ORAddress { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'built-in-standard-attributes' => BuiltInStandardAttributes::MAP, 'built-in-domain-defined-attributes' => ['optional' => true] + BuiltInDomainDefinedAttributes::MAP, 'extension-attributes' => ['optional' => true] + ExtensionAttributes::MAP ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OneAsymmetricKey.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * OneAsymmetricKey * * @author Jim Wigginton */ abstract class OneAsymmetricKey { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'version' => [ 'type' => ASN1::TYPE_INTEGER, 'mapping' => ['v1', 'v2'] ], 'privateKeyAlgorithm' => AlgorithmIdentifier::MAP, 'privateKey' => PrivateKey::MAP, 'attributes' => [ 'constant' => 0, 'optional' => true, 'implicit' => true ] + Attributes::MAP, 'publicKey' => [ 'constant' => 1, 'optional' => true, 'implicit' => true ] + PublicKey::MAP ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationName.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * OrganizationName * * @author Jim Wigginton */ abstract class OrganizationName { const MAP = ['type' => ASN1::TYPE_PRINTABLE_STRING]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationalUnitNames.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * OrganizationalUnitNames * * @author Jim Wigginton */ abstract class OrganizationalUnitNames { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'min' => 1, 'max' => 4, // ub-organizational-units 'children' => ['type' => ASN1::TYPE_PRINTABLE_STRING] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfo.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * OtherPrimeInfo * * @author Jim Wigginton */ abstract class OtherPrimeInfo { // version must be multi if otherPrimeInfos present const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'prime' => ['type' => ASN1::TYPE_INTEGER], // ri 'exponent' => ['type' => ASN1::TYPE_INTEGER], // di 'coefficient' => ['type' => ASN1::TYPE_INTEGER] // ti ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfos.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * OtherPrimeInfos * * @author Jim Wigginton */ abstract class OtherPrimeInfos { // version must be multi if otherPrimeInfos present const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'min' => 1, 'max' => -1, 'children' => OtherPrimeInfo::MAP ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBEParameter.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * PBEParameter * * from https://tools.ietf.org/html/rfc2898#appendix-A.3 * * @author Jim Wigginton */ abstract class PBEParameter { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'salt' => ['type' => ASN1::TYPE_OCTET_STRING], 'iterationCount' => ['type' => ASN1::TYPE_INTEGER] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBES2params.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * PBES2params * * from https://tools.ietf.org/html/rfc2898#appendix-A.3 * * @author Jim Wigginton */ abstract class PBES2params { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'keyDerivationFunc' => AlgorithmIdentifier::MAP, 'encryptionScheme' => AlgorithmIdentifier::MAP ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBKDF2params.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * PBKDF2params * * from https://tools.ietf.org/html/rfc2898#appendix-A.3 * * @author Jim Wigginton */ abstract class PBKDF2params { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ // technically, this is a CHOICE in RFC2898 but the other "choice" is, currently, more of a placeholder // in the RFC 'salt' => ['type' => ASN1::TYPE_OCTET_STRING], 'iterationCount' => ['type' => ASN1::TYPE_INTEGER], 'keyLength' => [ 'type' => ASN1::TYPE_INTEGER, 'optional' => true ], 'prf' => AlgorithmIdentifier::MAP + ['optional' => true] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBMAC1params.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * PBMAC1params * * from https://tools.ietf.org/html/rfc2898#appendix-A.3 * * @author Jim Wigginton */ abstract class PBMAC1params { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'keyDerivationFunc' => AlgorithmIdentifier::MAP, 'messageAuthScheme' => AlgorithmIdentifier::MAP ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PKCS9String.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * PKCS9String * * @author Jim Wigginton */ abstract class PKCS9String { const MAP = [ 'type' => ASN1::TYPE_CHOICE, 'children' => [ 'ia5String' => ['type' => ASN1::TYPE_IA5_STRING], 'directoryString' => DirectoryString::MAP ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Pentanomial.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * Pentanomial * * @author Jim Wigginton */ abstract class Pentanomial { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'k1' => ['type' => ASN1::TYPE_INTEGER], // k1 > 0 'k2' => ['type' => ASN1::TYPE_INTEGER], // k2 > k1 'k3' => ['type' => ASN1::TYPE_INTEGER], // k3 > h2 ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PersonalName.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * PersonalName * * @author Jim Wigginton */ abstract class PersonalName { const MAP = [ 'type' => ASN1::TYPE_SET, 'children' => [ 'surname' => [ 'type' => ASN1::TYPE_PRINTABLE_STRING, 'constant' => 0, 'optional' => true, 'implicit' => true ], 'given-name' => [ 'type' => ASN1::TYPE_PRINTABLE_STRING, 'constant' => 1, 'optional' => true, 'implicit' => true ], 'initials' => [ 'type' => ASN1::TYPE_PRINTABLE_STRING, 'constant' => 2, 'optional' => true, 'implicit' => true ], 'generation-qualifier' => [ 'type' => ASN1::TYPE_PRINTABLE_STRING, 'constant' => 3, 'optional' => true, 'implicit' => true ] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyInformation.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * PolicyInformation * * @author Jim Wigginton */ abstract class PolicyInformation { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'policyIdentifier' => CertPolicyId::MAP, 'policyQualifiers' => [ 'type' => ASN1::TYPE_SEQUENCE, 'min' => 0, 'max' => -1, 'optional' => true, 'children' => PolicyQualifierInfo::MAP ] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyMappings.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * PolicyMappings * * @author Jim Wigginton */ abstract class PolicyMappings { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'min' => 1, 'max' => -1, 'children' => [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'issuerDomainPolicy' => CertPolicyId::MAP, 'subjectDomainPolicy' => CertPolicyId::MAP ] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierId.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * PolicyQualifierId * * @author Jim Wigginton */ abstract class PolicyQualifierId { const MAP = ['type' => ASN1::TYPE_OBJECT_IDENTIFIER]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierInfo.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * PolicyQualifierInfo * * @author Jim Wigginton */ abstract class PolicyQualifierInfo { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'policyQualifierId' => PolicyQualifierId::MAP, 'qualifier' => ['type' => ASN1::TYPE_ANY] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PostalAddress.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * PostalAddress * * @author Jim Wigginton */ abstract class PostalAddress { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'optional' => true, 'min' => 1, 'max' => -1, 'children' => DirectoryString::MAP ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Prime_p.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * Prime_p * * @author Jim Wigginton */ abstract class Prime_p { const MAP = ['type' => ASN1::TYPE_INTEGER]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateDomainName.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * PrivateDomainName * * @author Jim Wigginton */ abstract class PrivateDomainName { const MAP = [ 'type' => ASN1::TYPE_CHOICE, 'children' => [ 'numeric' => ['type' => ASN1::TYPE_NUMERIC_STRING], 'printable' => ['type' => ASN1::TYPE_PRINTABLE_STRING] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKey.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * PrivateKey * * @author Jim Wigginton */ abstract class PrivateKey { const MAP = ['type' => ASN1::TYPE_OCTET_STRING]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyInfo.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * PrivateKeyInfo * * @author Jim Wigginton */ abstract class PrivateKeyInfo { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'version' => [ 'type' => ASN1::TYPE_INTEGER, 'mapping' => ['v1'] ], 'privateKeyAlgorithm' => AlgorithmIdentifier::MAP, 'privateKey' => PrivateKey::MAP, 'attributes' => [ 'constant' => 0, 'optional' => true, 'implicit' => true ] + Attributes::MAP ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyUsagePeriod.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * PrivateKeyUsagePeriod * * @author Jim Wigginton */ abstract class PrivateKeyUsagePeriod { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'notBefore' => [ 'constant' => 0, 'optional' => true, 'implicit' => true, 'type' => ASN1::TYPE_GENERALIZED_TIME], 'notAfter' => [ 'constant' => 1, 'optional' => true, 'implicit' => true, 'type' => ASN1::TYPE_GENERALIZED_TIME] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKey.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * PublicKey * * @author Jim Wigginton */ abstract class PublicKey { const MAP = ['type' => ASN1::TYPE_BIT_STRING]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyAndChallenge.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * PublicKeyAndChallenge * * @author Jim Wigginton */ abstract class PublicKeyAndChallenge { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'spki' => SubjectPublicKeyInfo::MAP, 'challenge' => ['type' => ASN1::TYPE_IA5_STRING] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyInfo.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * PublicKeyInfo * * this format is not formally defined anywhere but is none-the-less the form you * get when you do "openssl rsa -in private.pem -outform PEM -pubout" * * @author Jim Wigginton */ abstract class PublicKeyInfo { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'publicKeyAlgorithm' => AlgorithmIdentifier::MAP, 'publicKey' => ['type' => ASN1::TYPE_BIT_STRING] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RC2CBCParameter.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * RC2CBCParameter * * from https://tools.ietf.org/html/rfc2898#appendix-A.3 * * @author Jim Wigginton */ abstract class RC2CBCParameter { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'rc2ParametersVersion' => [ 'type' => ASN1::TYPE_INTEGER, 'optional' => true ], 'iv' => ['type' => ASN1::TYPE_OCTET_STRING] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RDNSequence.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * RDNSequence * * In practice, RDNs containing multiple name-value pairs (called "multivalued RDNs") are rare, * but they can be useful at times when either there is no unique attribute in the entry or you * want to ensure that the entry's DN contains some useful identifying information. * * - https://www.opends.org/wiki/page/DefinitionRelativeDistinguishedName * * @author Jim Wigginton */ abstract class RDNSequence { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, // RDNSequence does not define a min or a max, which means it doesn't have one 'min' => 0, 'max' => -1, 'children' => RelativeDistinguishedName::MAP ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPrivateKey.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * RSAPrivateKey * * @author Jim Wigginton */ abstract class RSAPrivateKey { // version must be multi if otherPrimeInfos present const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'version' => [ 'type' => ASN1::TYPE_INTEGER, 'mapping' => ['two-prime', 'multi'] ], 'modulus' => ['type' => ASN1::TYPE_INTEGER], // n 'publicExponent' => ['type' => ASN1::TYPE_INTEGER], // e 'privateExponent' => ['type' => ASN1::TYPE_INTEGER], // d 'prime1' => ['type' => ASN1::TYPE_INTEGER], // p 'prime2' => ['type' => ASN1::TYPE_INTEGER], // q 'exponent1' => ['type' => ASN1::TYPE_INTEGER], // d mod (p-1) 'exponent2' => ['type' => ASN1::TYPE_INTEGER], // d mod (q-1) 'coefficient' => ['type' => ASN1::TYPE_INTEGER], // (inverse of q) mod p 'otherPrimeInfos' => OtherPrimeInfos::MAP + ['optional' => true] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPublicKey.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * RSAPublicKey * * @author Jim Wigginton */ abstract class RSAPublicKey { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'modulus' => ['type' => ASN1::TYPE_INTEGER], 'publicExponent' => ['type' => ASN1::TYPE_INTEGER] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSASSA_PSS_params.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * RSASSA_PSS_params * * @author Jim Wigginton */ abstract class RSASSA_PSS_params { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'hashAlgorithm' => [ 'constant' => 0, 'optional' => true, 'explicit' => true, //'default' => 'sha1Identifier' ] + HashAlgorithm::MAP, 'maskGenAlgorithm' => [ 'constant' => 1, 'optional' => true, 'explicit' => true, //'default' => 'mgf1SHA1Identifier' ] + MaskGenAlgorithm::MAP, 'saltLength' => [ 'type' => ASN1::TYPE_INTEGER, 'constant' => 2, 'optional' => true, 'explicit' => true, 'default' => 20 ], 'trailerField' => [ 'type' => ASN1::TYPE_INTEGER, 'constant' => 3, 'optional' => true, 'explicit' => true, 'default' => 1 ] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ReasonFlags.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * ReasonFlags * * @author Jim Wigginton */ abstract class ReasonFlags { const MAP = [ 'type' => ASN1::TYPE_BIT_STRING, 'mapping' => [ 'unused', 'keyCompromise', 'cACompromise', 'affiliationChanged', 'superseded', 'cessationOfOperation', 'certificateHold', 'privilegeWithdrawn', 'aACompromise' ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RelativeDistinguishedName.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * RelativeDistinguishedName * * In practice, RDNs containing multiple name-value pairs (called "multivalued RDNs") are rare, * but they can be useful at times when either there is no unique attribute in the entry or you * want to ensure that the entry's DN contains some useful identifying information. * * - https://www.opends.org/wiki/page/DefinitionRelativeDistinguishedName * * @author Jim Wigginton */ abstract class RelativeDistinguishedName { const MAP = [ 'type' => ASN1::TYPE_SET, 'min' => 1, 'max' => -1, 'children' => AttributeTypeAndValue::MAP ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RevokedCertificate.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * RevokedCertificate * * @author Jim Wigginton */ abstract class RevokedCertificate { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'userCertificate' => CertificateSerialNumber::MAP, 'revocationDate' => Time::MAP, 'crlEntryExtensions' => [ 'optional' => true ] + Extensions::MAP ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SignedPublicKeyAndChallenge.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * SignedPublicKeyAndChallenge * * @author Jim Wigginton */ abstract class SignedPublicKeyAndChallenge { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'publicKeyAndChallenge' => PublicKeyAndChallenge::MAP, 'signatureAlgorithm' => AlgorithmIdentifier::MAP, 'signature' => ['type' => ASN1::TYPE_BIT_STRING] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SpecifiedECDomain.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * SpecifiedECDomain * * @author Jim Wigginton */ abstract class SpecifiedECDomain { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'version' => [ 'type' => ASN1::TYPE_INTEGER, 'mapping' => [1 => 'ecdpVer1', 'ecdpVer2', 'ecdpVer3'] ], 'fieldID' => FieldID::MAP, 'curve' => Curve::MAP, 'base' => ECPoint::MAP, 'order' => ['type' => ASN1::TYPE_INTEGER], 'cofactor' => [ 'type' => ASN1::TYPE_INTEGER, 'optional' => true ], 'hash' => ['optional' => true] + HashAlgorithm::MAP ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectAltName.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; /** * SubjectAltName * * @author Jim Wigginton */ abstract class SubjectAltName { const MAP = GeneralNames::MAP; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectDirectoryAttributes.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * SubjectDirectoryAttributes * * @author Jim Wigginton */ abstract class SubjectDirectoryAttributes { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'min' => 1, 'max' => -1, 'children' => Attribute::MAP ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectInfoAccessSyntax.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * SubjectInfoAccessSyntax * * @author Jim Wigginton */ abstract class SubjectInfoAccessSyntax { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'min' => 1, 'max' => -1, 'children' => AccessDescription::MAP ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectPublicKeyInfo.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * SubjectPublicKeyInfo * * @author Jim Wigginton */ abstract class SubjectPublicKeyInfo { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'algorithm' => AlgorithmIdentifier::MAP, 'subjectPublicKey' => ['type' => ASN1::TYPE_BIT_STRING] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertList.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * TBSCertList * * @author Jim Wigginton */ abstract class TBSCertList { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'version' => [ 'type' => ASN1::TYPE_INTEGER, 'mapping' => ['v1', 'v2'], 'optional' => true, 'default' => 'v1' ], 'signature' => AlgorithmIdentifier::MAP, 'issuer' => Name::MAP, 'thisUpdate' => Time::MAP, 'nextUpdate' => [ 'optional' => true ] + Time::MAP, 'revokedCertificates' => [ 'type' => ASN1::TYPE_SEQUENCE, 'optional' => true, 'min' => 0, 'max' => -1, 'children' => RevokedCertificate::MAP ], 'crlExtensions' => [ 'constant' => 0, 'optional' => true, 'explicit' => true ] + Extensions::MAP ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertificate.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * TBSCertificate * * @author Jim Wigginton */ abstract class TBSCertificate { // assert($TBSCertificate['children']['signature'] == $Certificate['children']['signatureAlgorithm']) const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ // technically, default implies optional, but we'll define it as being optional, none-the-less, just to // reenforce that fact 'version' => [ 'type' => ASN1::TYPE_INTEGER, 'constant' => 0, 'optional' => true, 'explicit' => true, 'mapping' => ['v1', 'v2', 'v3'], 'default' => 'v1' ], 'serialNumber' => CertificateSerialNumber::MAP, 'signature' => AlgorithmIdentifier::MAP, 'issuer' => Name::MAP, 'validity' => Validity::MAP, 'subject' => Name::MAP, 'subjectPublicKeyInfo' => SubjectPublicKeyInfo::MAP, // implicit means that the T in the TLV structure is to be rewritten, regardless of the type 'issuerUniqueID' => [ 'constant' => 1, 'optional' => true, 'implicit' => true ] + UniqueIdentifier::MAP, 'subjectUniqueID' => [ 'constant' => 2, 'optional' => true, 'implicit' => true ] + UniqueIdentifier::MAP, // doesn't use the EXPLICIT keyword but if // it's not IMPLICIT, it's EXPLICIT 'extensions' => [ 'constant' => 3, 'optional' => true, 'explicit' => true ] + Extensions::MAP ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TerminalIdentifier.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * TerminalIdentifier * * @author Jim Wigginton */ abstract class TerminalIdentifier { const MAP = ['type' => ASN1::TYPE_PRINTABLE_STRING]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Time.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * Time * * @author Jim Wigginton */ abstract class Time { const MAP = [ 'type' => ASN1::TYPE_CHOICE, 'children' => [ 'utcTime' => ['type' => ASN1::TYPE_UTC_TIME], 'generalTime' => ['type' => ASN1::TYPE_GENERALIZED_TIME] ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Trinomial.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * Trinomial * * @author Jim Wigginton */ abstract class Trinomial { const MAP = ['type' => ASN1::TYPE_INTEGER]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UniqueIdentifier.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * UniqueIdentifier * * @author Jim Wigginton */ abstract class UniqueIdentifier { const MAP = ['type' => ASN1::TYPE_BIT_STRING]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UserNotice.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * UserNotice * * @author Jim Wigginton */ abstract class UserNotice { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'noticeRef' => [ 'optional' => true, 'implicit' => true ] + NoticeReference::MAP, 'explicitText' => [ 'optional' => true, 'implicit' => true ] + DisplayText::MAP ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Validity.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * Validity * * @author Jim Wigginton */ abstract class Validity { const MAP = [ 'type' => ASN1::TYPE_SEQUENCE, 'children' => [ 'notBefore' => Time::MAP, 'notAfter' => Time::MAP ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_ca_policy_url.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * netscape_ca_policy_url * * @author Jim Wigginton */ abstract class netscape_ca_policy_url { const MAP = ['type' => ASN1::TYPE_IA5_STRING]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_cert_type.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * netscape_cert_type * * mapping is from * * @author Jim Wigginton */ abstract class netscape_cert_type { const MAP = [ 'type' => ASN1::TYPE_BIT_STRING, 'mapping' => [ 'SSLClient', 'SSLServer', 'Email', 'ObjectSigning', 'Reserved', 'SSLCA', 'EmailCA', 'ObjectSigningCA' ] ]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_comment.php ================================================ * @copyright 2016 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File\ASN1\Maps; use phpseclib3\File\ASN1; /** * netscape_comment * * @author Jim Wigginton */ abstract class netscape_comment { const MAP = ['type' => ASN1::TYPE_IA5_STRING]; } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php ================================================ * @copyright 2012 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File; use phpseclib3\Common\Functions\Strings; use phpseclib3\File\ASN1\Element; use phpseclib3\Math\BigInteger; /** * Pure-PHP ASN.1 Parser * * @author Jim Wigginton */ abstract class ASN1 { // Tag Classes // http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#page=12 const CLASS_UNIVERSAL = 0; const CLASS_APPLICATION = 1; const CLASS_CONTEXT_SPECIFIC = 2; const CLASS_PRIVATE = 3; // Tag Classes // http://www.obj-sys.com/asn1tutorial/node124.html const TYPE_BOOLEAN = 1; const TYPE_INTEGER = 2; const TYPE_BIT_STRING = 3; const TYPE_OCTET_STRING = 4; const TYPE_NULL = 5; const TYPE_OBJECT_IDENTIFIER = 6; //const TYPE_OBJECT_DESCRIPTOR = 7; //const TYPE_INSTANCE_OF = 8; // EXTERNAL const TYPE_REAL = 9; const TYPE_ENUMERATED = 10; //const TYPE_EMBEDDED = 11; const TYPE_UTF8_STRING = 12; //const TYPE_RELATIVE_OID = 13; const TYPE_SEQUENCE = 16; // SEQUENCE OF const TYPE_SET = 17; // SET OF // More Tag Classes // http://www.obj-sys.com/asn1tutorial/node10.html const TYPE_NUMERIC_STRING = 18; const TYPE_PRINTABLE_STRING = 19; const TYPE_TELETEX_STRING = 20; // T61String const TYPE_VIDEOTEX_STRING = 21; const TYPE_IA5_STRING = 22; const TYPE_UTC_TIME = 23; const TYPE_GENERALIZED_TIME = 24; const TYPE_GRAPHIC_STRING = 25; const TYPE_VISIBLE_STRING = 26; // ISO646String const TYPE_GENERAL_STRING = 27; const TYPE_UNIVERSAL_STRING = 28; //const TYPE_CHARACTER_STRING = 29; const TYPE_BMP_STRING = 30; // Tag Aliases // These tags are kinda place holders for other tags. const TYPE_CHOICE = -1; const TYPE_ANY = -2; /** * ASN.1 object identifiers * * @var array * @link http://en.wikipedia.org/wiki/Object_identifier */ private static $oids = []; /** * ASN.1 object identifier reverse mapping * * @var array */ private static $reverseOIDs = []; /** * Default date format * * @var string * @link http://php.net/class.datetime */ private static $format = 'D, d M Y H:i:s O'; /** * Filters * * If the mapping type is self::TYPE_ANY what do we actually encode it as? * * @var array * @see self::encode_der() */ private static $filters; /** * Current Location of most recent ASN.1 encode process * * Useful for debug purposes * * @var array * @see self::encode_der() */ private static $location; /** * DER Encoded String * * In case we need to create ASN1\Element object's.. * * @var string * @see self::decodeDER() */ private static $encoded; /** * Type mapping table for the ANY type. * * Structured or unknown types are mapped to a \phpseclib3\File\ASN1\Element. * Unambiguous types get the direct mapping (int/real/bool). * Others are mapped as a choice, with an extra indexing level. * * @var array */ const ANY_MAP = [ self::TYPE_BOOLEAN => true, self::TYPE_INTEGER => true, self::TYPE_BIT_STRING => 'bitString', self::TYPE_OCTET_STRING => 'octetString', self::TYPE_NULL => 'null', self::TYPE_OBJECT_IDENTIFIER => 'objectIdentifier', self::TYPE_REAL => true, self::TYPE_ENUMERATED => 'enumerated', self::TYPE_UTF8_STRING => 'utf8String', self::TYPE_NUMERIC_STRING => 'numericString', self::TYPE_PRINTABLE_STRING => 'printableString', self::TYPE_TELETEX_STRING => 'teletexString', self::TYPE_VIDEOTEX_STRING => 'videotexString', self::TYPE_IA5_STRING => 'ia5String', self::TYPE_UTC_TIME => 'utcTime', self::TYPE_GENERALIZED_TIME => 'generalTime', self::TYPE_GRAPHIC_STRING => 'graphicString', self::TYPE_VISIBLE_STRING => 'visibleString', self::TYPE_GENERAL_STRING => 'generalString', self::TYPE_UNIVERSAL_STRING => 'universalString', //self::TYPE_CHARACTER_STRING => 'characterString', self::TYPE_BMP_STRING => 'bmpString' ]; /** * String type to character size mapping table. * * Non-convertable types are absent from this table. * size == 0 indicates variable length encoding. * * @var array */ const STRING_TYPE_SIZE = [ self::TYPE_UTF8_STRING => 0, self::TYPE_BMP_STRING => 2, self::TYPE_UNIVERSAL_STRING => 4, self::TYPE_PRINTABLE_STRING => 1, self::TYPE_TELETEX_STRING => 1, self::TYPE_IA5_STRING => 1, self::TYPE_VISIBLE_STRING => 1, ]; /** * Parse BER-encoding * * Serves a similar purpose to openssl's asn1parse * * @param Element|string $encoded * @return ?array */ public static function decodeBER($encoded) { if ($encoded instanceof Element) { $encoded = $encoded->element; } self::$encoded = $encoded; $decoded = self::decode_ber($encoded); if ($decoded === false) { return null; } return [$decoded]; } /** * Parse BER-encoding (Helper function) * * Sometimes we want to get the BER encoding of a particular tag. $start lets us do that without having to reencode. * $encoded is passed by reference for the recursive calls done for self::TYPE_BIT_STRING and * self::TYPE_OCTET_STRING. In those cases, the indefinite length is used. * * @param string $encoded * @param int $start * @param int $encoded_pos * @return array|bool */ private static function decode_ber($encoded, $start = 0, $encoded_pos = 0) { $current = ['start' => $start]; if (!isset($encoded[$encoded_pos])) { return false; } $type = ord($encoded[$encoded_pos++]); $startOffset = 1; $constructed = ($type >> 5) & 1; $tag = $type & 0x1F; if ($tag == 0x1F) { $tag = 0; // process septets (since the eighth bit is ignored, it's not an octet) do { if (!isset($encoded[$encoded_pos])) { return false; } $temp = ord($encoded[$encoded_pos++]); $startOffset++; $loop = $temp >> 7; $tag <<= 7; $temp &= 0x7F; // "bits 7 to 1 of the first subsequent octet shall not all be zero" if ($startOffset == 2 && $temp == 0) { return false; } $tag |= $temp; } while ($loop); } $start += $startOffset; // Length, as discussed in paragraph 8.1.3 of X.690-0207.pdf#page=13 if (!isset($encoded[$encoded_pos])) { return false; } $length = ord($encoded[$encoded_pos++]); $start++; if ($length == 0x80) { // indefinite length // "[A sender shall] use the indefinite form (see 8.1.3.6) if the encoding is constructed and is not all // immediately available." -- paragraph 8.1.3.2.c $length = strlen($encoded) - $encoded_pos; } elseif ($length & 0x80) { // definite length, long form // technically, the long form of the length can be represented by up to 126 octets (bytes), but we'll only // support it up to four. $length &= 0x7F; $temp = substr($encoded, $encoded_pos, $length); $encoded_pos += $length; // tags of indefinte length don't really have a header length; this length includes the tag $current += ['headerlength' => $length + 2]; $start += $length; $length = unpack('Nlength', substr(str_pad($temp, 4, chr(0), STR_PAD_LEFT), -4))['length']; } else { $current += ['headerlength' => 2]; } if ($length > (strlen($encoded) - $encoded_pos)) { return false; } $content = substr($encoded, $encoded_pos, $length); $content_pos = 0; // at this point $length can be overwritten. it's only accurate for definite length things as is /* Class is UNIVERSAL, APPLICATION, PRIVATE, or CONTEXT-SPECIFIC. The UNIVERSAL class is restricted to the ASN.1 built-in types. It defines an application-independent data type that must be distinguishable from all other data types. The other three classes are user defined. The APPLICATION class distinguishes data types that have a wide, scattered use within a particular presentation context. PRIVATE distinguishes data types within a particular organization or country. CONTEXT-SPECIFIC distinguishes members of a sequence or set, the alternatives of a CHOICE, or universally tagged set members. Only the class number appears in braces for this data type; the term CONTEXT-SPECIFIC does not appear. -- http://www.obj-sys.com/asn1tutorial/node12.html */ $class = ($type >> 6) & 3; switch ($class) { case self::CLASS_APPLICATION: case self::CLASS_PRIVATE: case self::CLASS_CONTEXT_SPECIFIC: if (!$constructed) { return [ 'type' => $class, 'constant' => $tag, 'content' => $content, 'length' => $length + $start - $current['start'] ] + $current; } $newcontent = []; $remainingLength = $length; while ($remainingLength > 0) { $temp = self::decode_ber($content, $start, $content_pos); if ($temp === false) { break; } $length = $temp['length']; // end-of-content octets - see paragraph 8.1.5 if (substr($content, $content_pos + $length, 2) == "\0\0") { $length += 2; $start += $length; $newcontent[] = $temp; break; } $start += $length; $remainingLength -= $length; $newcontent[] = $temp; $content_pos += $length; } return [ 'type' => $class, 'constant' => $tag, // the array encapsulation is for BC with the old format 'content' => $newcontent, // the only time when $content['headerlength'] isn't defined is when the length is indefinite. // the absence of $content['headerlength'] is how we know if something is indefinite or not. // technically, it could be defined to be 2 and then another indicator could be used but whatever. 'length' => $start - $current['start'] ] + $current; } $current += ['type' => $tag]; // decode UNIVERSAL tags switch ($tag) { case self::TYPE_BOOLEAN: // "The contents octets shall consist of a single octet." -- paragraph 8.2.1 if ($constructed || strlen($content) != 1) { return false; } $current['content'] = (bool) ord($content[$content_pos]); break; case self::TYPE_INTEGER: case self::TYPE_ENUMERATED: if ($constructed) { return false; } $current['content'] = new BigInteger(substr($content, $content_pos), -256); break; case self::TYPE_REAL: // not currently supported return false; case self::TYPE_BIT_STRING: // The initial octet shall encode, as an unsigned binary integer with bit 1 as the least significant bit, // the number of unused bits in the final subsequent octet. The number shall be in the range zero to // seven. if (!$constructed) { $current['content'] = substr($content, $content_pos); } else { $temp = self::decode_ber($content, $start, $content_pos); if ($temp === false) { return false; } $length -= (strlen($content) - $content_pos); $last = count($temp) - 1; for ($i = 0; $i < $last; $i++) { // all subtags should be bit strings if ($temp[$i]['type'] != self::TYPE_BIT_STRING) { return false; } $current['content'] .= substr($temp[$i]['content'], 1); } // all subtags should be bit strings if ($temp[$last]['type'] != self::TYPE_BIT_STRING) { return false; } $current['content'] = $temp[$last]['content'][0] . $current['content'] . substr($temp[$i]['content'], 1); } break; case self::TYPE_OCTET_STRING: if (!$constructed) { $current['content'] = substr($content, $content_pos); } else { $current['content'] = ''; $length = 0; while (substr($content, $content_pos, 2) != "\0\0") { $temp = self::decode_ber($content, $length + $start, $content_pos); if ($temp === false) { return false; } $content_pos += $temp['length']; // all subtags should be octet strings if ($temp['type'] != self::TYPE_OCTET_STRING) { return false; } $current['content'] .= $temp['content']; $length += $temp['length']; } if (substr($content, $content_pos, 2) == "\0\0") { $length += 2; // +2 for the EOC } } break; case self::TYPE_NULL: // "The contents octets shall not contain any octets." -- paragraph 8.8.2 if ($constructed || strlen($content)) { return false; } break; case self::TYPE_SEQUENCE: case self::TYPE_SET: if (!$constructed) { return false; } $offset = 0; $current['content'] = []; $content_len = strlen($content); while ($content_pos < $content_len) { // if indefinite length construction was used and we have an end-of-content string next // see paragraphs 8.1.1.3, 8.1.3.2, 8.1.3.6, 8.1.5, and (for an example) 8.6.4.2 if (!isset($current['headerlength']) && substr($content, $content_pos, 2) == "\0\0") { $length = $offset + 2; // +2 for the EOC break 2; } $temp = self::decode_ber($content, $start + $offset, $content_pos); if ($temp === false) { return false; } $content_pos += $temp['length']; $current['content'][] = $temp; $offset += $temp['length']; } break; case self::TYPE_OBJECT_IDENTIFIER: if ($constructed) { return false; } $current['content'] = self::decodeOID(substr($content, $content_pos)); if ($current['content'] === false) { return false; } break; /* Each character string type shall be encoded as if it had been declared: [UNIVERSAL x] IMPLICIT OCTET STRING -- X.690-0207.pdf#page=23 (paragraph 8.21.3) Per that, we're not going to do any validation. If there are any illegal characters in the string, we don't really care */ case self::TYPE_NUMERIC_STRING: // 0,1,2,3,4,5,6,7,8,9, and space case self::TYPE_PRINTABLE_STRING: // Upper and lower case letters, digits, space, apostrophe, left/right parenthesis, plus sign, comma, // hyphen, full stop, solidus, colon, equal sign, question mark case self::TYPE_TELETEX_STRING: // The Teletex character set in CCITT's T61, space, and delete // see http://en.wikipedia.org/wiki/Teletex#Character_sets case self::TYPE_VIDEOTEX_STRING: // The Videotex character set in CCITT's T.100 and T.101, space, and delete case self::TYPE_VISIBLE_STRING: // Printing character sets of international ASCII, and space case self::TYPE_IA5_STRING: // International Alphabet 5 (International ASCII) case self::TYPE_GRAPHIC_STRING: // All registered G sets, and space case self::TYPE_GENERAL_STRING: // All registered C and G sets, space and delete case self::TYPE_UTF8_STRING: // ???? case self::TYPE_BMP_STRING: if ($constructed) { return false; } $current['content'] = substr($content, $content_pos); break; case self::TYPE_UTC_TIME: case self::TYPE_GENERALIZED_TIME: if ($constructed) { return false; } $current['content'] = self::decodeTime(substr($content, $content_pos), $tag); break; default: return false; } $start += $length; // ie. length is the length of the full TLV encoding - it's not just the length of the value return $current + ['length' => $start - $current['start']]; } /** * ASN.1 Map * * Provides an ASN.1 semantic mapping ($mapping) from a parsed BER-encoding to a human readable format. * * "Special" mappings may be applied on a per tag-name basis via $special. * * @param array $decoded * @param array $mapping * @param array $special * @return array|bool|Element|string|null */ public static function asn1map(array $decoded, $mapping, $special = []) { if (isset($mapping['explicit']) && is_array($decoded['content'])) { $decoded = $decoded['content'][0]; } switch (true) { case $mapping['type'] == self::TYPE_ANY: $intype = $decoded['type']; // !isset(self::ANY_MAP[$intype]) produces a fatal error on PHP 5.6 if (isset($decoded['constant']) || !array_key_exists($intype, self::ANY_MAP) || (ord(self::$encoded[$decoded['start']]) & 0x20)) { return new Element(substr(self::$encoded, $decoded['start'], $decoded['length'])); } $inmap = self::ANY_MAP[$intype]; if (is_string($inmap)) { return [$inmap => self::asn1map($decoded, ['type' => $intype] + $mapping, $special)]; } break; case $mapping['type'] == self::TYPE_CHOICE: foreach ($mapping['children'] as $key => $option) { switch (true) { case isset($option['constant']) && $option['constant'] == $decoded['constant']: case !isset($option['constant']) && $option['type'] == $decoded['type']: $value = self::asn1map($decoded, $option, $special); break; case !isset($option['constant']) && $option['type'] == self::TYPE_CHOICE: $v = self::asn1map($decoded, $option, $special); if (isset($v)) { $value = $v; } } if (isset($value)) { if (isset($special[$key])) { $value = $special[$key]($value); } return [$key => $value]; } } return null; case isset($mapping['implicit']): case isset($mapping['explicit']): case $decoded['type'] == $mapping['type']: break; default: // if $decoded['type'] and $mapping['type'] are both strings, but different types of strings, // let it through switch (true) { case $decoded['type'] < 18: // self::TYPE_NUMERIC_STRING == 18 case $decoded['type'] > 30: // self::TYPE_BMP_STRING == 30 case $mapping['type'] < 18: case $mapping['type'] > 30: return null; } } if (isset($mapping['implicit'])) { $decoded['type'] = $mapping['type']; } switch ($decoded['type']) { case self::TYPE_SEQUENCE: $map = []; // ignore the min and max if (isset($mapping['min']) && isset($mapping['max'])) { $child = $mapping['children']; foreach ($decoded['content'] as $content) { if (($map[] = self::asn1map($content, $child, $special)) === null) { return null; } } return $map; } $n = count($decoded['content']); $i = 0; foreach ($mapping['children'] as $key => $child) { $maymatch = $i < $n; // Match only existing input. if ($maymatch) { $temp = $decoded['content'][$i]; if ($child['type'] != self::TYPE_CHOICE) { // Get the mapping and input class & constant. $childClass = $tempClass = self::CLASS_UNIVERSAL; $constant = null; if (isset($temp['constant'])) { $tempClass = $temp['type']; } if (isset($child['class'])) { $childClass = $child['class']; $constant = $child['cast']; } elseif (isset($child['constant'])) { $childClass = self::CLASS_CONTEXT_SPECIFIC; $constant = $child['constant']; } if (isset($constant) && isset($temp['constant'])) { // Can only match if constants and class match. $maymatch = $constant == $temp['constant'] && $childClass == $tempClass; } else { // Can only match if no constant expected and type matches or is generic. $maymatch = !isset($child['constant']) && array_search($child['type'], [$temp['type'], self::TYPE_ANY, self::TYPE_CHOICE]) !== false; } } } if ($maymatch) { // Attempt submapping. $candidate = self::asn1map($temp, $child, $special); $maymatch = $candidate !== null; } if ($maymatch) { // Got the match: use it. if (isset($special[$key])) { $candidate = $special[$key]($candidate); } $map[$key] = $candidate; $i++; } elseif (isset($child['default'])) { $map[$key] = $child['default']; } elseif (!isset($child['optional'])) { return null; // Syntax error. } } // Fail mapping if all input items have not been consumed. return $i < $n ? null : $map; // the main diff between sets and sequences is the encapsulation of the foreach in another for loop case self::TYPE_SET: $map = []; // ignore the min and max if (isset($mapping['min']) && isset($mapping['max'])) { $child = $mapping['children']; foreach ($decoded['content'] as $content) { if (($map[] = self::asn1map($content, $child, $special)) === null) { return null; } } return $map; } for ($i = 0; $i < count($decoded['content']); $i++) { $temp = $decoded['content'][$i]; $tempClass = self::CLASS_UNIVERSAL; if (isset($temp['constant'])) { $tempClass = $temp['type']; } foreach ($mapping['children'] as $key => $child) { if (isset($map[$key])) { continue; } $maymatch = true; if ($child['type'] != self::TYPE_CHOICE) { $childClass = self::CLASS_UNIVERSAL; $constant = null; if (isset($child['class'])) { $childClass = $child['class']; $constant = $child['cast']; } elseif (isset($child['constant'])) { $childClass = self::CLASS_CONTEXT_SPECIFIC; $constant = $child['constant']; } if (isset($constant) && isset($temp['constant'])) { // Can only match if constants and class match. $maymatch = $constant == $temp['constant'] && $childClass == $tempClass; } else { // Can only match if no constant expected and type matches or is generic. $maymatch = !isset($child['constant']) && array_search($child['type'], [$temp['type'], self::TYPE_ANY, self::TYPE_CHOICE]) !== false; } } if ($maymatch) { // Attempt submapping. $candidate = self::asn1map($temp, $child, $special); $maymatch = $candidate !== null; } if (!$maymatch) { break; } // Got the match: use it. if (isset($special[$key])) { $candidate = $special[$key]($candidate); } $map[$key] = $candidate; break; } } foreach ($mapping['children'] as $key => $child) { if (!isset($map[$key])) { if (isset($child['default'])) { $map[$key] = $child['default']; } elseif (!isset($child['optional'])) { return null; } } } return $map; case self::TYPE_OBJECT_IDENTIFIER: return isset(self::$oids[$decoded['content']]) ? self::$oids[$decoded['content']] : $decoded['content']; case self::TYPE_UTC_TIME: case self::TYPE_GENERALIZED_TIME: // for explicitly tagged optional stuff if (is_array($decoded['content'])) { $decoded['content'] = $decoded['content'][0]['content']; } // for implicitly tagged optional stuff // in theory, doing isset($mapping['implicit']) would work but malformed certs do exist // in the wild that OpenSSL decodes without issue so we'll support them as well if (!is_object($decoded['content'])) { $decoded['content'] = self::decodeTime($decoded['content'], $decoded['type']); } return $decoded['content'] ? $decoded['content']->format(self::$format) : false; case self::TYPE_BIT_STRING: if (isset($mapping['mapping'])) { $offset = ord($decoded['content'][0]); $size = (strlen($decoded['content']) - 1) * 8 - $offset; /* From X.680-0207.pdf#page=46 (21.7): "When a "NamedBitList" is used in defining a bitstring type ASN.1 encoding rules are free to add (or remove) arbitrarily any trailing 0 bits to (or from) values that are being encoded or decoded. Application designers should therefore ensure that different semantics are not associated with such values which differ only in the number of trailing 0 bits." */ $bits = count($mapping['mapping']) == $size ? [] : array_fill(0, count($mapping['mapping']) - $size, false); for ($i = strlen($decoded['content']) - 1; $i > 0; $i--) { $current = ord($decoded['content'][$i]); for ($j = $offset; $j < 8; $j++) { $bits[] = (bool) ($current & (1 << $j)); } $offset = 0; } $values = []; $map = array_reverse($mapping['mapping']); foreach ($map as $i => $value) { if ($bits[$i]) { $values[] = $value; } } return $values; } // fall-through case self::TYPE_OCTET_STRING: return $decoded['content']; case self::TYPE_NULL: return ''; case self::TYPE_BOOLEAN: case self::TYPE_NUMERIC_STRING: case self::TYPE_PRINTABLE_STRING: case self::TYPE_TELETEX_STRING: case self::TYPE_VIDEOTEX_STRING: case self::TYPE_IA5_STRING: case self::TYPE_GRAPHIC_STRING: case self::TYPE_VISIBLE_STRING: case self::TYPE_GENERAL_STRING: case self::TYPE_UNIVERSAL_STRING: case self::TYPE_UTF8_STRING: case self::TYPE_BMP_STRING: return $decoded['content']; case self::TYPE_INTEGER: case self::TYPE_ENUMERATED: $temp = $decoded['content']; if (isset($mapping['implicit'])) { $temp = new BigInteger($temp, -256); } if (!$temp instanceof BigInteger) { return false; } if (isset($mapping['mapping'])) { $temp = $temp->toString(); if (strlen($temp) > 1) { return false; } $temp = (int) $temp; return isset($mapping['mapping'][$temp]) ? $mapping['mapping'][$temp] : false; } return $temp; } } /** * DER-decode the length * * DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See * {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information. * * @param string $string * @return int */ public static function decodeLength(&$string) { $length = ord(Strings::shift($string)); if ($length & 0x80) { // definite length, long form $length &= 0x7F; $temp = Strings::shift($string, $length); list(, $length) = unpack('N', substr(str_pad($temp, 4, chr(0), STR_PAD_LEFT), -4)); } return $length; } /** * ASN.1 Encode * * DER-encodes an ASN.1 semantic mapping ($mapping). Some libraries would probably call this function * an ASN.1 compiler. * * "Special" mappings can be applied via $special. * * @param Element|string|array $source * @param array $mapping * @param array $special * @return string */ public static function encodeDER($source, $mapping, $special = []) { self::$location = []; return self::encode_der($source, $mapping, null, $special); } /** * ASN.1 Encode (Helper function) * * @param Element|string|array|null $source * @param array $mapping * @param int $idx * @param array $special * @return string */ private static function encode_der($source, array $mapping, $idx = null, array $special = []) { if ($source instanceof Element) { return $source->element; } // do not encode (implicitly optional) fields with value set to default if (isset($mapping['default']) && $source === $mapping['default']) { return ''; } if (isset($idx)) { if (isset($special[$idx])) { $source = $special[$idx]($source); } self::$location[] = $idx; } $tag = $mapping['type']; switch ($tag) { case self::TYPE_SET: // Children order is not important, thus process in sequence. case self::TYPE_SEQUENCE: $tag |= 0x20; // set the constructed bit // ignore the min and max if (isset($mapping['min']) && isset($mapping['max'])) { $value = []; $child = $mapping['children']; foreach ($source as $content) { $temp = self::encode_der($content, $child, null, $special); if ($temp === false) { return false; } $value[] = $temp; } /* "The encodings of the component values of a set-of value shall appear in ascending order, the encodings being compared as octet strings with the shorter components being padded at their trailing end with 0-octets. NOTE - The padding octets are for comparison purposes only and do not appear in the encodings." -- sec 11.6 of http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf */ if ($mapping['type'] == self::TYPE_SET) { sort($value); } $value = implode('', $value); break; } $value = ''; foreach ($mapping['children'] as $key => $child) { if (!array_key_exists($key, $source)) { if (!isset($child['optional'])) { return false; } continue; } $temp = self::encode_der($source[$key], $child, $key, $special); if ($temp === false) { return false; } // An empty child encoding means it has been optimized out. // Else we should have at least one tag byte. if ($temp === '') { continue; } // if isset($child['constant']) is true then isset($child['optional']) should be true as well if (isset($child['constant'])) { /* From X.680-0207.pdf#page=58 (30.6): "The tagging construction specifies explicit tagging if any of the following holds: ... c) the "Tag Type" alternative is used and the value of "TagDefault" for the module is IMPLICIT TAGS or AUTOMATIC TAGS, but the type defined by "Type" is an untagged choice type, an untagged open type, or an untagged "DummyReference" (see ITU-T Rec. X.683 | ISO/IEC 8824-4, 8.3)." */ if (isset($child['explicit']) || $child['type'] == self::TYPE_CHOICE) { if ($child['constant'] <= 30) { $subtag = chr((self::CLASS_CONTEXT_SPECIFIC << 6) | 0x20 | $child['constant']); } else { $constant = $child['constant']; $subtag = ''; while ($constant > 0) { $subtagvalue = $constant & 0x7F; $subtag = (chr(0x80 | $subtagvalue)) . $subtag; $constant = $constant >> 7; } $subtag[strlen($subtag) - 1] = $subtag[strlen($subtag) - 1] & chr(0x7F); $subtag = chr((self::CLASS_CONTEXT_SPECIFIC << 6) | 0x20 | 0x1f) . $subtag; } $temp = $subtag . self::encodeLength(strlen($temp)) . $temp; } else { $subtag = chr((self::CLASS_CONTEXT_SPECIFIC << 6) | (ord($temp[0]) & 0x20) | $child['constant']); $temp = $subtag . substr($temp, 1); } } $value .= $temp; } break; case self::TYPE_CHOICE: $temp = false; foreach ($mapping['children'] as $key => $child) { if (!isset($source[$key])) { continue; } $temp = self::encode_der($source[$key], $child, $key, $special); if ($temp === false) { return false; } // An empty child encoding means it has been optimized out. // Else we should have at least one tag byte. if ($temp === '') { continue; } $tag = ord($temp[0]); // if isset($child['constant']) is true then isset($child['optional']) should be true as well if (isset($child['constant'])) { if (isset($child['explicit']) || $child['type'] == self::TYPE_CHOICE) { $subtag = chr((self::CLASS_CONTEXT_SPECIFIC << 6) | 0x20 | $child['constant']); $temp = $subtag . self::encodeLength(strlen($temp)) . $temp; } else { $subtag = chr((self::CLASS_CONTEXT_SPECIFIC << 6) | (ord($temp[0]) & 0x20) | $child['constant']); $temp = $subtag . substr($temp, 1); } } } if (isset($idx)) { array_pop(self::$location); } if ($temp && isset($mapping['cast'])) { $temp[0] = chr(($mapping['class'] << 6) | ($tag & 0x20) | $mapping['cast']); } return $temp; case self::TYPE_INTEGER: case self::TYPE_ENUMERATED: if (!isset($mapping['mapping'])) { if (is_numeric($source)) { $source = new BigInteger($source); } $value = $source->toBytes(true); } else { $value = array_search($source, $mapping['mapping']); if ($value === false) { return false; } $value = new BigInteger($value); $value = $value->toBytes(true); } if (!strlen($value)) { $value = chr(0); } break; case self::TYPE_UTC_TIME: case self::TYPE_GENERALIZED_TIME: $format = $mapping['type'] == self::TYPE_UTC_TIME ? 'y' : 'Y'; $format .= 'mdHis'; // if $source does _not_ include timezone information within it then assume that the timezone is GMT $date = new \DateTime($source, new \DateTimeZone('GMT')); // if $source _does_ include timezone information within it then convert the time to GMT $date->setTimezone(new \DateTimeZone('GMT')); $value = $date->format($format) . 'Z'; break; case self::TYPE_BIT_STRING: if (isset($mapping['mapping'])) { $bits = array_fill(0, count($mapping['mapping']), 0); $size = 0; for ($i = 0; $i < count($mapping['mapping']); $i++) { if (in_array($mapping['mapping'][$i], $source)) { $bits[$i] = 1; $size = $i; } } if (isset($mapping['min']) && $mapping['min'] >= 1 && $size < $mapping['min']) { $size = $mapping['min'] - 1; } $offset = 8 - (($size + 1) & 7); $offset = $offset !== 8 ? $offset : 0; $value = chr($offset); for ($i = $size + 1; $i < count($mapping['mapping']); $i++) { unset($bits[$i]); } $bits = implode('', array_pad($bits, $size + $offset + 1, 0)); $bytes = explode(' ', rtrim(chunk_split($bits, 8, ' '))); foreach ($bytes as $byte) { $value .= chr(bindec($byte)); } break; } // fall-through case self::TYPE_OCTET_STRING: /* The initial octet shall encode, as an unsigned binary integer with bit 1 as the least significant bit, the number of unused bits in the final subsequent octet. The number shall be in the range zero to seven. -- http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#page=16 */ $value = $source; break; case self::TYPE_OBJECT_IDENTIFIER: $value = self::encodeOID($source); break; case self::TYPE_ANY: $loc = self::$location; if (isset($idx)) { array_pop(self::$location); } switch (true) { case !isset($source): return self::encode_der(null, ['type' => self::TYPE_NULL] + $mapping, null, $special); case is_int($source): case $source instanceof BigInteger: return self::encode_der($source, ['type' => self::TYPE_INTEGER] + $mapping, null, $special); case is_float($source): return self::encode_der($source, ['type' => self::TYPE_REAL] + $mapping, null, $special); case is_bool($source): return self::encode_der($source, ['type' => self::TYPE_BOOLEAN] + $mapping, null, $special); case is_array($source) && count($source) == 1: $typename = implode('', array_keys($source)); $outtype = array_search($typename, self::ANY_MAP, true); if ($outtype !== false) { return self::encode_der($source[$typename], ['type' => $outtype] + $mapping, null, $special); } } $filters = self::$filters; foreach ($loc as $part) { if (!isset($filters[$part])) { $filters = false; break; } $filters = $filters[$part]; } if ($filters === false) { throw new \RuntimeException('No filters defined for ' . implode('/', $loc)); } return self::encode_der($source, $filters + $mapping, null, $special); case self::TYPE_NULL: $value = ''; break; case self::TYPE_NUMERIC_STRING: case self::TYPE_TELETEX_STRING: case self::TYPE_PRINTABLE_STRING: case self::TYPE_UNIVERSAL_STRING: case self::TYPE_UTF8_STRING: case self::TYPE_BMP_STRING: case self::TYPE_IA5_STRING: case self::TYPE_VISIBLE_STRING: case self::TYPE_VIDEOTEX_STRING: case self::TYPE_GRAPHIC_STRING: case self::TYPE_GENERAL_STRING: $value = $source; break; case self::TYPE_BOOLEAN: $value = $source ? "\xFF" : "\x00"; break; default: throw new \RuntimeException('Mapping provides no type definition for ' . implode('/', self::$location)); } if (isset($idx)) { array_pop(self::$location); } if (isset($mapping['cast'])) { if (isset($mapping['explicit']) || $mapping['type'] == self::TYPE_CHOICE) { $value = chr($tag) . self::encodeLength(strlen($value)) . $value; $tag = ($mapping['class'] << 6) | 0x20 | $mapping['cast']; } else { $tag = ($mapping['class'] << 6) | (ord($temp[0]) & 0x20) | $mapping['cast']; } } return chr($tag) . self::encodeLength(strlen($value)) . $value; } /** * BER-decode the OID * * Called by _decode_ber() * * @param string $content * @return string */ public static function decodeOID($content) { // BigInteger's are used because of OIDs like 2.25.329800735698586629295641978511506172918 // https://healthcaresecprivacy.blogspot.com/2011/02/creating-and-using-unique-id-uuid-oid.html elaborates. static $eighty; if (!$eighty) { $eighty = new BigInteger(80); } $oid = []; $pos = 0; $len = strlen($content); // see https://github.com/openjdk/jdk/blob/2deb318c9f047ec5a4b160d66a4b52f93688ec42/src/java.base/share/classes/sun/security/util/ObjectIdentifier.java#L55 if ($len > 4096) { //throw new \RuntimeException("Object identifier size is limited to 4096 bytes ($len bytes present)"); return false; } if (ord($content[$len - 1]) & 0x80) { return false; } $n = new BigInteger(); while ($pos < $len) { $temp = ord($content[$pos++]); $n = $n->bitwise_leftShift(7); $n = $n->bitwise_or(new BigInteger($temp & 0x7F)); if (~$temp & 0x80) { $oid[] = $n; $n = new BigInteger(); } } $part1 = array_shift($oid); $first = floor(ord($content[0]) / 40); /* "This packing of the first two object identifier components recognizes that only three values are allocated from the root node, and at most 39 subsequent values from nodes reached by X = 0 and X = 1." -- https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#page=22 */ if ($first <= 2) { // ie. 0 <= ord($content[0]) < 120 (0x78) array_unshift($oid, ord($content[0]) % 40); array_unshift($oid, $first); } else { array_unshift($oid, $part1->subtract($eighty)); array_unshift($oid, 2); } return implode('.', $oid); } /** * DER-encode the OID * * Called by _encode_der() * * @param string $source * @return string */ public static function encodeOID($source) { static $mask, $zero, $forty; if (!$mask) { $mask = new BigInteger(0x7F); $zero = new BigInteger(); $forty = new BigInteger(40); } if (!preg_match('#(?:\d+\.)+#', $source)) { $oid = isset(self::$reverseOIDs[$source]) ? self::$reverseOIDs[$source] : false; } else { $oid = $source; } if ($oid === false) { throw new \RuntimeException('Invalid OID'); } $parts = explode('.', $oid); $part1 = array_shift($parts); $part2 = array_shift($parts); $first = new BigInteger($part1); $first = $first->multiply($forty); $first = $first->add(new BigInteger($part2)); array_unshift($parts, $first->toString()); $value = ''; foreach ($parts as $part) { if (!$part) { $temp = "\0"; } else { $temp = ''; $part = new BigInteger($part); while (!$part->equals($zero)) { $submask = $part->bitwise_and($mask); $submask->setPrecision(8); $temp = (chr(0x80) | $submask->toBytes()) . $temp; $part = $part->bitwise_rightShift(7); } $temp[strlen($temp) - 1] = $temp[strlen($temp) - 1] & chr(0x7F); } $value .= $temp; } return $value; } /** * BER-decode the time * * Called by _decode_ber() and in the case of implicit tags asn1map(). * * @param string $content * @param int $tag * @return \DateTime|false */ private static function decodeTime($content, $tag) { /* UTCTime: http://tools.ietf.org/html/rfc5280#section-4.1.2.5.1 http://www.obj-sys.com/asn1tutorial/node15.html GeneralizedTime: http://tools.ietf.org/html/rfc5280#section-4.1.2.5.2 http://www.obj-sys.com/asn1tutorial/node14.html */ $format = 'YmdHis'; if ($tag == self::TYPE_UTC_TIME) { // https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#page=28 says "the seconds // element shall always be present" but none-the-less I've seen X509 certs where it isn't and if the // browsers parse it phpseclib ought to too if (preg_match('#^(\d{10})(Z|[+-]\d{4})$#', $content, $matches)) { $content = $matches[1] . '00' . $matches[2]; } $prefix = substr($content, 0, 2) >= 50 ? '19' : '20'; $content = $prefix . $content; } elseif (strpos($content, '.') !== false) { $format .= '.u'; } if ($content[strlen($content) - 1] == 'Z') { $content = substr($content, 0, -1) . '+0000'; } if (strpos($content, '-') !== false || strpos($content, '+') !== false) { $format .= 'O'; } // error supression isn't necessary as of PHP 7.0: // http://php.net/manual/en/migration70.other-changes.php return @\DateTime::createFromFormat($format, $content); } /** * Set the time format * * Sets the time / date format for asn1map(). * * @param string $format */ public static function setTimeFormat($format) { self::$format = $format; } /** * Load OIDs * * Load the relevant OIDs for a particular ASN.1 semantic mapping. * Previously loaded OIDs are retained. * * @param array $oids */ public static function loadOIDs(array $oids) { self::$reverseOIDs += $oids; self::$oids = array_flip(self::$reverseOIDs); } /** * Set filters * * See \phpseclib3\File\X509, etc, for an example. * Previously loaded filters are not retained. * * @param array $filters */ public static function setFilters(array $filters) { self::$filters = $filters; } /** * String type conversion * * This is a lazy conversion, dealing only with character size. * No real conversion table is used. * * @param string $in * @param int $from * @param int $to * @return string */ public static function convert($in, $from = self::TYPE_UTF8_STRING, $to = self::TYPE_UTF8_STRING) { // isset(self::STRING_TYPE_SIZE[$from] returns a fatal error on PHP 5.6 if (!array_key_exists($from, self::STRING_TYPE_SIZE) || !array_key_exists($to, self::STRING_TYPE_SIZE)) { return false; } $insize = self::STRING_TYPE_SIZE[$from]; $outsize = self::STRING_TYPE_SIZE[$to]; $inlength = strlen($in); $out = ''; for ($i = 0; $i < $inlength;) { if ($inlength - $i < $insize) { return false; } // Get an input character as a 32-bit value. $c = ord($in[$i++]); switch (true) { case $insize == 4: $c = ($c << 8) | ord($in[$i++]); $c = ($c << 8) | ord($in[$i++]); // fall-through case $insize == 2: $c = ($c << 8) | ord($in[$i++]); // fall-through case $insize == 1: break; case ($c & 0x80) == 0x00: break; case ($c & 0x40) == 0x00: return false; default: $bit = 6; do { if ($bit > 25 || $i >= $inlength || (ord($in[$i]) & 0xC0) != 0x80) { return false; } $c = ($c << 6) | (ord($in[$i++]) & 0x3F); $bit += 5; $mask = 1 << $bit; } while ($c & $bit); $c &= $mask - 1; break; } // Convert and append the character to output string. $v = ''; switch (true) { case $outsize == 4: $v .= chr($c & 0xFF); $c >>= 8; $v .= chr($c & 0xFF); $c >>= 8; // fall-through case $outsize == 2: $v .= chr($c & 0xFF); $c >>= 8; // fall-through case $outsize == 1: $v .= chr($c & 0xFF); $c >>= 8; if ($c) { return false; } break; case ($c & (PHP_INT_SIZE == 8 ? 0x80000000 : (1 << 31))) != 0: return false; case $c >= 0x04000000: $v .= chr(0x80 | ($c & 0x3F)); $c = ($c >> 6) | 0x04000000; // fall-through case $c >= 0x00200000: $v .= chr(0x80 | ($c & 0x3F)); $c = ($c >> 6) | 0x00200000; // fall-through case $c >= 0x00010000: $v .= chr(0x80 | ($c & 0x3F)); $c = ($c >> 6) | 0x00010000; // fall-through case $c >= 0x00000800: $v .= chr(0x80 | ($c & 0x3F)); $c = ($c >> 6) | 0x00000800; // fall-through case $c >= 0x00000080: $v .= chr(0x80 | ($c & 0x3F)); $c = ($c >> 6) | 0x000000C0; // fall-through default: $v .= chr($c); break; } $out .= strrev($v); } return $out; } /** * Extract raw BER from Base64 encoding * * @param string $str * @return string */ public static function extractBER($str) { /* X.509 certs are assumed to be base64 encoded but sometimes they'll have additional things in them * above and beyond the ceritificate. * ie. some may have the following preceding the -----BEGIN CERTIFICATE----- line: * * Bag Attributes * localKeyID: 01 00 00 00 * subject=/O=organization/OU=org unit/CN=common name * issuer=/O=organization/CN=common name */ if (strlen($str) > ini_get('pcre.backtrack_limit')) { $temp = $str; } else { $temp = preg_replace('#.*?^-+[^-]+-+[\r\n ]*$#ms', '', $str, 1); $temp = preg_replace('#-+END.*[\r\n ]*.*#ms', '', $temp, 1); } // remove new lines $temp = str_replace(["\r", "\n", ' '], '', $temp); // remove the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- stuff $temp = preg_replace('#^-+[^-]+-+|-+[^-]+-+$#', '', $temp); $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? Strings::base64_decode($temp) : false; return $temp != false ? $temp : $str; } /** * DER-encode the length * * DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See * {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information. * * @param int $length * @return string */ public static function encodeLength($length) { if ($length <= 0x7F) { return chr($length); } $temp = ltrim(pack('N', $length), chr(0)); return pack('Ca*', 0x80 | strlen($temp), $temp); } /** * Returns the OID corresponding to a name * * What's returned in the associative array returned by loadX509() (or load*()) is either a name or an OID if * no OID to name mapping is available. The problem with this is that what may be an unmapped OID in one version * of phpseclib may not be unmapped in the next version, so apps that are looking at this OID may not be able * to work from version to version. * * This method will return the OID if a name is passed to it and if no mapping is avialable it'll assume that * what's being passed to it already is an OID and return that instead. A few examples. * * getOID('2.16.840.1.101.3.4.2.1') == '2.16.840.1.101.3.4.2.1' * getOID('id-sha256') == '2.16.840.1.101.3.4.2.1' * getOID('zzz') == 'zzz' * * @param string $name * @return string */ public static function getOID($name) { return isset(self::$reverseOIDs[$name]) ? self::$reverseOIDs[$name] : $name; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/File/X509.php ================================================ * @copyright 2012 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\File; use phpseclib3\Common\Functions\Strings; use phpseclib3\Crypt\Common\PrivateKey; use phpseclib3\Crypt\Common\PublicKey; use phpseclib3\Crypt\DSA; use phpseclib3\Crypt\EC; use phpseclib3\Crypt\Hash; use phpseclib3\Crypt\PublicKeyLoader; use phpseclib3\Crypt\Random; use phpseclib3\Crypt\RSA; use phpseclib3\Crypt\RSA\Formats\Keys\PSS; use phpseclib3\Exception\UnsupportedAlgorithmException; use phpseclib3\File\ASN1\Element; use phpseclib3\File\ASN1\Maps; use phpseclib3\Math\BigInteger; /** * Pure-PHP X.509 Parser * * @author Jim Wigginton */ class X509 { /** * Flag to only accept signatures signed by certificate authorities * * Not really used anymore but retained all the same to suppress E_NOTICEs from old installs * */ const VALIDATE_SIGNATURE_BY_CA = 1; /** * Return internal array representation * * @see \phpseclib3\File\X509::getDN() */ const DN_ARRAY = 0; /** * Return string * * @see \phpseclib3\File\X509::getDN() */ const DN_STRING = 1; /** * Return ASN.1 name string * * @see \phpseclib3\File\X509::getDN() */ const DN_ASN1 = 2; /** * Return OpenSSL compatible array * * @see \phpseclib3\File\X509::getDN() */ const DN_OPENSSL = 3; /** * Return canonical ASN.1 RDNs string * * @see \phpseclib3\File\X509::getDN() */ const DN_CANON = 4; /** * Return name hash for file indexing * * @see \phpseclib3\File\X509::getDN() */ const DN_HASH = 5; /** * Save as PEM * * ie. a base64-encoded PEM with a header and a footer * * @see \phpseclib3\File\X509::saveX509() * @see \phpseclib3\File\X509::saveCSR() * @see \phpseclib3\File\X509::saveCRL() */ const FORMAT_PEM = 0; /** * Save as DER * * @see \phpseclib3\File\X509::saveX509() * @see \phpseclib3\File\X509::saveCSR() * @see \phpseclib3\File\X509::saveCRL() */ const FORMAT_DER = 1; /** * Save as a SPKAC * * @see \phpseclib3\File\X509::saveX509() * @see \phpseclib3\File\X509::saveCSR() * @see \phpseclib3\File\X509::saveCRL() * * Only works on CSRs. Not currently supported. */ const FORMAT_SPKAC = 2; /** * Auto-detect the format * * Used only by the load*() functions * * @see \phpseclib3\File\X509::saveX509() * @see \phpseclib3\File\X509::saveCSR() * @see \phpseclib3\File\X509::saveCRL() */ const FORMAT_AUTO_DETECT = 3; /** * Attribute value disposition. * If disposition is >= 0, this is the index of the target value. */ const ATTR_ALL = -1; // All attribute values (array). const ATTR_APPEND = -2; // Add a value. const ATTR_REPLACE = -3; // Clear first, then add a value. /** * Distinguished Name * * @var array */ private $dn; /** * Public key * * @var string|PublicKey */ private $publicKey; /** * Private key * * @var string|PrivateKey */ private $privateKey; /** * The certificate authorities * * @var array */ private $CAs = []; /** * The currently loaded certificate * * @var array */ private $currentCert; /** * The signature subject * * There's no guarantee \phpseclib3\File\X509 is going to re-encode an X.509 cert in the same way it was originally * encoded so we take save the portion of the original cert that the signature would have made for. * * @var string */ private $signatureSubject; /** * Certificate Start Date * * @var string */ private $startDate; /** * Certificate End Date * * @var string|Element */ private $endDate; /** * Serial Number * * @var string */ private $serialNumber; /** * Key Identifier * * See {@link http://tools.ietf.org/html/rfc5280#section-4.2.1.1 RFC5280#section-4.2.1.1} and * {@link http://tools.ietf.org/html/rfc5280#section-4.2.1.2 RFC5280#section-4.2.1.2}. * * @var string */ private $currentKeyIdentifier; /** * CA Flag * * @var bool */ private $caFlag = false; /** * SPKAC Challenge * * @var string */ private $challenge; /** * @var array */ private $extensionValues = []; /** * OIDs loaded * * @var bool */ private static $oidsLoaded = false; /** * Recursion Limit * * @var int */ private static $recur_limit = 5; /** * URL fetch flag * * @var bool */ private static $disable_url_fetch = false; /** * @var array */ private static $extensions = []; /** * @var ?array */ private $ipAddresses = null; /** * @var ?array */ private $domains = null; /** * Default Constructor. * * @return X509 */ public function __construct() { // Explicitly Tagged Module, 1988 Syntax // http://tools.ietf.org/html/rfc5280#appendix-A.1 if (!self::$oidsLoaded) { // OIDs from RFC5280 and those RFCs mentioned in RFC5280#section-4.1.1.2 ASN1::loadOIDs([ //'id-pkix' => '1.3.6.1.5.5.7', //'id-pe' => '1.3.6.1.5.5.7.1', //'id-qt' => '1.3.6.1.5.5.7.2', //'id-kp' => '1.3.6.1.5.5.7.3', //'id-ad' => '1.3.6.1.5.5.7.48', 'id-qt-cps' => '1.3.6.1.5.5.7.2.1', 'id-qt-unotice' => '1.3.6.1.5.5.7.2.2', 'id-ad-ocsp' => '1.3.6.1.5.5.7.48.1', 'id-ad-caIssuers' => '1.3.6.1.5.5.7.48.2', 'id-ad-timeStamping' => '1.3.6.1.5.5.7.48.3', 'id-ad-caRepository' => '1.3.6.1.5.5.7.48.5', //'id-at' => '2.5.4', 'id-at-name' => '2.5.4.41', 'id-at-surname' => '2.5.4.4', 'id-at-givenName' => '2.5.4.42', 'id-at-initials' => '2.5.4.43', 'id-at-generationQualifier' => '2.5.4.44', 'id-at-commonName' => '2.5.4.3', 'id-at-localityName' => '2.5.4.7', 'id-at-stateOrProvinceName' => '2.5.4.8', 'id-at-organizationName' => '2.5.4.10', 'id-at-organizationalUnitName' => '2.5.4.11', 'id-at-title' => '2.5.4.12', 'id-at-description' => '2.5.4.13', 'id-at-dnQualifier' => '2.5.4.46', 'id-at-countryName' => '2.5.4.6', 'id-at-serialNumber' => '2.5.4.5', 'id-at-pseudonym' => '2.5.4.65', 'id-at-postalCode' => '2.5.4.17', 'id-at-streetAddress' => '2.5.4.9', 'id-at-uniqueIdentifier' => '2.5.4.45', 'id-at-role' => '2.5.4.72', 'id-at-postalAddress' => '2.5.4.16', 'jurisdictionOfIncorporationCountryName' => '1.3.6.1.4.1.311.60.2.1.3', 'jurisdictionOfIncorporationStateOrProvinceName' => '1.3.6.1.4.1.311.60.2.1.2', 'jurisdictionLocalityName' => '1.3.6.1.4.1.311.60.2.1.1', 'id-at-businessCategory' => '2.5.4.15', //'id-domainComponent' => '0.9.2342.19200300.100.1.25', //'pkcs-9' => '1.2.840.113549.1.9', 'pkcs-9-at-emailAddress' => '1.2.840.113549.1.9.1', //'id-ce' => '2.5.29', 'id-ce-authorityKeyIdentifier' => '2.5.29.35', 'id-ce-subjectKeyIdentifier' => '2.5.29.14', 'id-ce-keyUsage' => '2.5.29.15', 'id-ce-privateKeyUsagePeriod' => '2.5.29.16', 'id-ce-certificatePolicies' => '2.5.29.32', //'anyPolicy' => '2.5.29.32.0', 'id-ce-policyMappings' => '2.5.29.33', 'id-ce-subjectAltName' => '2.5.29.17', 'id-ce-issuerAltName' => '2.5.29.18', 'id-ce-subjectDirectoryAttributes' => '2.5.29.9', 'id-ce-basicConstraints' => '2.5.29.19', 'id-ce-nameConstraints' => '2.5.29.30', 'id-ce-policyConstraints' => '2.5.29.36', 'id-ce-cRLDistributionPoints' => '2.5.29.31', 'id-ce-extKeyUsage' => '2.5.29.37', //'anyExtendedKeyUsage' => '2.5.29.37.0', 'id-kp-serverAuth' => '1.3.6.1.5.5.7.3.1', 'id-kp-clientAuth' => '1.3.6.1.5.5.7.3.2', 'id-kp-codeSigning' => '1.3.6.1.5.5.7.3.3', 'id-kp-emailProtection' => '1.3.6.1.5.5.7.3.4', 'id-kp-timeStamping' => '1.3.6.1.5.5.7.3.8', 'id-kp-OCSPSigning' => '1.3.6.1.5.5.7.3.9', 'id-ce-inhibitAnyPolicy' => '2.5.29.54', 'id-ce-freshestCRL' => '2.5.29.46', 'id-pe-authorityInfoAccess' => '1.3.6.1.5.5.7.1.1', 'id-pe-subjectInfoAccess' => '1.3.6.1.5.5.7.1.11', 'id-ce-cRLNumber' => '2.5.29.20', 'id-ce-issuingDistributionPoint' => '2.5.29.28', 'id-ce-deltaCRLIndicator' => '2.5.29.27', 'id-ce-cRLReasons' => '2.5.29.21', 'id-ce-certificateIssuer' => '2.5.29.29', 'id-ce-holdInstructionCode' => '2.5.29.23', //'holdInstruction' => '1.2.840.10040.2', 'id-holdinstruction-none' => '1.2.840.10040.2.1', 'id-holdinstruction-callissuer' => '1.2.840.10040.2.2', 'id-holdinstruction-reject' => '1.2.840.10040.2.3', 'id-ce-invalidityDate' => '2.5.29.24', 'rsaEncryption' => '1.2.840.113549.1.1.1', 'md2WithRSAEncryption' => '1.2.840.113549.1.1.2', 'md5WithRSAEncryption' => '1.2.840.113549.1.1.4', 'sha1WithRSAEncryption' => '1.2.840.113549.1.1.5', 'sha224WithRSAEncryption' => '1.2.840.113549.1.1.14', 'sha256WithRSAEncryption' => '1.2.840.113549.1.1.11', 'sha384WithRSAEncryption' => '1.2.840.113549.1.1.12', 'sha512WithRSAEncryption' => '1.2.840.113549.1.1.13', 'id-ecPublicKey' => '1.2.840.10045.2.1', 'ecdsa-with-SHA1' => '1.2.840.10045.4.1', // from https://tools.ietf.org/html/rfc5758#section-3.2 'ecdsa-with-SHA224' => '1.2.840.10045.4.3.1', 'ecdsa-with-SHA256' => '1.2.840.10045.4.3.2', 'ecdsa-with-SHA384' => '1.2.840.10045.4.3.3', 'ecdsa-with-SHA512' => '1.2.840.10045.4.3.4', 'id-dsa' => '1.2.840.10040.4.1', 'id-dsa-with-sha1' => '1.2.840.10040.4.3', // from https://tools.ietf.org/html/rfc5758#section-3.1 'id-dsa-with-sha224' => '2.16.840.1.101.3.4.3.1', 'id-dsa-with-sha256' => '2.16.840.1.101.3.4.3.2', // from https://tools.ietf.org/html/rfc8410: 'id-Ed25519' => '1.3.101.112', 'id-Ed448' => '1.3.101.113', 'id-RSASSA-PSS' => '1.2.840.113549.1.1.10', //'id-sha224' => '2.16.840.1.101.3.4.2.4', //'id-sha256' => '2.16.840.1.101.3.4.2.1', //'id-sha384' => '2.16.840.1.101.3.4.2.2', //'id-sha512' => '2.16.840.1.101.3.4.2.3', //'id-GostR3411-94-with-GostR3410-94' => '1.2.643.2.2.4', //'id-GostR3411-94-with-GostR3410-2001' => '1.2.643.2.2.3', //'id-GostR3410-2001' => '1.2.643.2.2.20', //'id-GostR3410-94' => '1.2.643.2.2.19', // Netscape Object Identifiers from "Netscape Certificate Extensions" 'netscape' => '2.16.840.1.113730', 'netscape-cert-extension' => '2.16.840.1.113730.1', 'netscape-cert-type' => '2.16.840.1.113730.1.1', 'netscape-comment' => '2.16.840.1.113730.1.13', 'netscape-ca-policy-url' => '2.16.840.1.113730.1.8', // the following are X.509 extensions not supported by phpseclib 'id-pe-logotype' => '1.3.6.1.5.5.7.1.12', 'entrustVersInfo' => '1.2.840.113533.7.65.0', 'verisignPrivate' => '2.16.840.1.113733.1.6.9', // for Certificate Signing Requests // see http://tools.ietf.org/html/rfc2985 'pkcs-9-at-unstructuredName' => '1.2.840.113549.1.9.2', // PKCS #9 unstructured name 'pkcs-9-at-challengePassword' => '1.2.840.113549.1.9.7', // Challenge password for certificate revocations 'pkcs-9-at-extensionRequest' => '1.2.840.113549.1.9.14' // Certificate extension request ]); } } /** * Load X.509 certificate * * Returns an associative array describing the X.509 cert or a false if the cert failed to load * * @param array|string $cert * @param int $mode * @return mixed */ public function loadX509($cert, $mode = self::FORMAT_AUTO_DETECT) { if (is_array($cert) && isset($cert['tbsCertificate'])) { unset($this->currentCert); unset($this->currentKeyIdentifier); $this->dn = $cert['tbsCertificate']['subject']; if (!isset($this->dn)) { return false; } $this->currentCert = $cert; $currentKeyIdentifier = $this->getExtension('id-ce-subjectKeyIdentifier'); $this->currentKeyIdentifier = is_string($currentKeyIdentifier) ? $currentKeyIdentifier : null; unset($this->signatureSubject); return $cert; } if ($mode != self::FORMAT_DER) { $newcert = ASN1::extractBER($cert); if ($mode == self::FORMAT_PEM && $cert == $newcert) { return false; } $cert = $newcert; } if ($cert === false) { $this->currentCert = false; return false; } $decoded = ASN1::decodeBER($cert); if ($decoded) { $x509 = ASN1::asn1map($decoded[0], Maps\Certificate::MAP); } if (!isset($x509) || $x509 === false) { $this->currentCert = false; return false; } $this->signatureSubject = substr($cert, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']); if ($this->isSubArrayValid($x509, 'tbsCertificate/extensions')) { $this->mapInExtensions($x509, 'tbsCertificate/extensions'); } $this->mapInDNs($x509, 'tbsCertificate/issuer/rdnSequence'); $this->mapInDNs($x509, 'tbsCertificate/subject/rdnSequence'); $key = $x509['tbsCertificate']['subjectPublicKeyInfo']; $key = ASN1::encodeDER($key, Maps\SubjectPublicKeyInfo::MAP); $x509['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'] = "-----BEGIN PUBLIC KEY-----\r\n" . chunk_split(base64_encode($key), 64) . "-----END PUBLIC KEY-----"; $this->currentCert = $x509; $this->dn = $x509['tbsCertificate']['subject']; $currentKeyIdentifier = $this->getExtension('id-ce-subjectKeyIdentifier'); $this->currentKeyIdentifier = is_string($currentKeyIdentifier) ? $currentKeyIdentifier : null; return $x509; } /** * Save X.509 certificate * * @param array $cert * @param int $format optional * @return string */ public function saveX509(array $cert, $format = self::FORMAT_PEM) { if (!is_array($cert) || !isset($cert['tbsCertificate'])) { return false; } switch (true) { // "case !$a: case !$b: break; default: whatever();" is the same thing as "if ($a && $b) whatever()" case !($algorithm = $this->subArray($cert, 'tbsCertificate/subjectPublicKeyInfo/algorithm/algorithm')): case is_object($cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey']): break; default: $cert['tbsCertificate']['subjectPublicKeyInfo'] = new Element( base64_decode(preg_replace('#-.+-|[\r\n]#', '', $cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'])) ); } $filters = []; $type_utf8_string = ['type' => ASN1::TYPE_UTF8_STRING]; $filters['tbsCertificate']['signature']['parameters'] = $type_utf8_string; $filters['tbsCertificate']['signature']['issuer']['rdnSequence']['value'] = $type_utf8_string; $filters['tbsCertificate']['issuer']['rdnSequence']['value'] = $type_utf8_string; $filters['tbsCertificate']['subject']['rdnSequence']['value'] = $type_utf8_string; $filters['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['parameters'] = $type_utf8_string; $filters['signatureAlgorithm']['parameters'] = $type_utf8_string; $filters['authorityCertIssuer']['directoryName']['rdnSequence']['value'] = $type_utf8_string; //$filters['policyQualifiers']['qualifier'] = $type_utf8_string; $filters['distributionPoint']['fullName']['directoryName']['rdnSequence']['value'] = $type_utf8_string; $filters['directoryName']['rdnSequence']['value'] = $type_utf8_string; foreach (self::$extensions as $extension) { $filters['tbsCertificate']['extensions'][] = $extension; } /* in the case of policyQualifiers/qualifier, the type has to be \phpseclib3\File\ASN1::TYPE_IA5_STRING. \phpseclib3\File\ASN1::TYPE_PRINTABLE_STRING will cause OpenSSL's X.509 parser to spit out random characters. */ $filters['policyQualifiers']['qualifier'] = ['type' => ASN1::TYPE_IA5_STRING]; ASN1::setFilters($filters); $this->mapOutExtensions($cert, 'tbsCertificate/extensions'); $this->mapOutDNs($cert, 'tbsCertificate/issuer/rdnSequence'); $this->mapOutDNs($cert, 'tbsCertificate/subject/rdnSequence'); $cert = ASN1::encodeDER($cert, Maps\Certificate::MAP); switch ($format) { case self::FORMAT_DER: return $cert; // case self::FORMAT_PEM: default: return "-----BEGIN CERTIFICATE-----\r\n" . chunk_split(Strings::base64_encode($cert), 64) . '-----END CERTIFICATE-----'; } } /** * Map extension values from octet string to extension-specific internal * format. * * @param array $root (by reference) * @param string $path */ private function mapInExtensions(array &$root, $path) { $extensions = &$this->subArrayUnchecked($root, $path); if ($extensions) { for ($i = 0; $i < count($extensions); $i++) { $id = $extensions[$i]['extnId']; $value = &$extensions[$i]['extnValue']; /* [extnValue] contains the DER encoding of an ASN.1 value corresponding to the extension type identified by extnID */ $map = $this->getMapping($id); if (!is_bool($map)) { $decoder = $id == 'id-ce-nameConstraints' ? [static::class, 'decodeNameConstraintIP'] : [static::class, 'decodeIP']; $decoded = ASN1::decodeBER($value); if (!$decoded) { continue; } $mapped = ASN1::asn1map($decoded[0], $map, ['iPAddress' => $decoder]); $value = $mapped === false ? $decoded[0] : $mapped; if ($id == 'id-ce-certificatePolicies') { for ($j = 0; $j < count($value); $j++) { if (!isset($value[$j]['policyQualifiers'])) { continue; } for ($k = 0; $k < count($value[$j]['policyQualifiers']); $k++) { $subid = $value[$j]['policyQualifiers'][$k]['policyQualifierId']; $map = $this->getMapping($subid); $subvalue = &$value[$j]['policyQualifiers'][$k]['qualifier']; if ($map !== false) { $decoded = ASN1::decodeBER($subvalue); if (!$decoded) { continue; } $mapped = ASN1::asn1map($decoded[0], $map); $subvalue = $mapped === false ? $decoded[0] : $mapped; } } } } } } } } /** * Map extension values from extension-specific internal format to * octet string. * * @param array $root (by reference) * @param string $path */ private function mapOutExtensions(array &$root, $path) { $extensions = &$this->subArray($root, $path, !empty($this->extensionValues)); foreach ($this->extensionValues as $id => $data) { $critical = $data['critical']; $replace = $data['replace']; $value = $data['value']; $newext = [ 'extnId' => $id, 'extnValue' => $value, 'critical' => $critical ]; if ($replace) { foreach ($extensions as $key => $value) { if ($value['extnId'] == $id) { $extensions[$key] = $newext; continue 2; } } } $extensions[] = $newext; } if (is_array($extensions)) { $size = count($extensions); for ($i = 0; $i < $size; $i++) { if ($extensions[$i] instanceof Element) { continue; } $id = $extensions[$i]['extnId']; $value = &$extensions[$i]['extnValue']; switch ($id) { case 'id-ce-certificatePolicies': for ($j = 0; $j < count($value); $j++) { if (!isset($value[$j]['policyQualifiers'])) { continue; } for ($k = 0; $k < count($value[$j]['policyQualifiers']); $k++) { $subid = $value[$j]['policyQualifiers'][$k]['policyQualifierId']; $map = $this->getMapping($subid); $subvalue = &$value[$j]['policyQualifiers'][$k]['qualifier']; if ($map !== false) { // by default \phpseclib3\File\ASN1 will try to render qualifier as a \phpseclib3\File\ASN1::TYPE_IA5_STRING since it's // actual type is \phpseclib3\File\ASN1::TYPE_ANY $subvalue = new Element(ASN1::encodeDER($subvalue, $map)); } } } break; case 'id-ce-authorityKeyIdentifier': // use 00 as the serial number instead of an empty string if (isset($value['authorityCertSerialNumber'])) { if ($value['authorityCertSerialNumber']->toBytes() == '') { $temp = chr((ASN1::CLASS_CONTEXT_SPECIFIC << 6) | 2) . "\1\0"; $value['authorityCertSerialNumber'] = new Element($temp); } } } /* [extnValue] contains the DER encoding of an ASN.1 value corresponding to the extension type identified by extnID */ $map = $this->getMapping($id); if (is_bool($map)) { if (!$map) { //user_error($id . ' is not a currently supported extension'); unset($extensions[$i]); } } else { $value = ASN1::encodeDER($value, $map, ['iPAddress' => [static::class, 'encodeIP']]); } } } } /** * Map attribute values from ANY type to attribute-specific internal * format. * * @param array $root (by reference) * @param string $path */ private function mapInAttributes(&$root, $path) { $attributes = &$this->subArray($root, $path); if (is_array($attributes)) { for ($i = 0; $i < count($attributes); $i++) { $id = $attributes[$i]['type']; /* $value contains the DER encoding of an ASN.1 value corresponding to the attribute type identified by type */ $map = $this->getMapping($id); if (is_array($attributes[$i]['value'])) { $values = &$attributes[$i]['value']; for ($j = 0; $j < count($values); $j++) { $value = ASN1::encodeDER($values[$j], Maps\AttributeValue::MAP); $decoded = ASN1::decodeBER($value); if (!is_bool($map)) { if (!$decoded) { continue; } $mapped = ASN1::asn1map($decoded[0], $map); if ($mapped !== false) { $values[$j] = $mapped; } if ($id == 'pkcs-9-at-extensionRequest' && $this->isSubArrayValid($values, $j)) { $this->mapInExtensions($values, $j); } } elseif ($map) { $values[$j] = $value; } } } } } } /** * Map attribute values from attribute-specific internal format to * ANY type. * * @param array $root (by reference) * @param string $path */ private function mapOutAttributes(&$root, $path) { $attributes = &$this->subArray($root, $path); if (is_array($attributes)) { $size = count($attributes); for ($i = 0; $i < $size; $i++) { /* [value] contains the DER encoding of an ASN.1 value corresponding to the attribute type identified by type */ $id = $attributes[$i]['type']; $map = $this->getMapping($id); if ($map === false) { //user_error($id . ' is not a currently supported attribute', E_USER_NOTICE); unset($attributes[$i]); } elseif (is_array($attributes[$i]['value'])) { $values = &$attributes[$i]['value']; for ($j = 0; $j < count($values); $j++) { switch ($id) { case 'pkcs-9-at-extensionRequest': $this->mapOutExtensions($values, $j); break; } if (!is_bool($map)) { $temp = ASN1::encodeDER($values[$j], $map); $decoded = ASN1::decodeBER($temp); if (!$decoded) { continue; } $values[$j] = ASN1::asn1map($decoded[0], Maps\AttributeValue::MAP); } } } } } } /** * Map DN values from ANY type to DN-specific internal * format. * * @param array $root (by reference) * @param string $path */ private function mapInDNs(array &$root, $path) { $dns = &$this->subArray($root, $path); if (is_array($dns)) { for ($i = 0; $i < count($dns); $i++) { for ($j = 0; $j < count($dns[$i]); $j++) { $type = $dns[$i][$j]['type']; $value = &$dns[$i][$j]['value']; if (is_object($value) && $value instanceof Element) { $map = $this->getMapping($type); if (!is_bool($map)) { $decoded = ASN1::decodeBER($value); if (!$decoded) { continue; } $value = ASN1::asn1map($decoded[0], $map); } } } } } } /** * Map DN values from DN-specific internal format to * ANY type. * * @param array $root (by reference) * @param string $path */ private function mapOutDNs(array &$root, $path) { $dns = &$this->subArray($root, $path); if (is_array($dns)) { $size = count($dns); for ($i = 0; $i < $size; $i++) { for ($j = 0; $j < count($dns[$i]); $j++) { $type = $dns[$i][$j]['type']; $value = &$dns[$i][$j]['value']; if (is_object($value) && $value instanceof Element) { continue; } $map = $this->getMapping($type); if (!is_bool($map)) { $value = new Element(ASN1::encodeDER($value, $map)); } } } } } /** * Associate an extension ID to an extension mapping * * @param string $extnId * @return mixed */ private function getMapping($extnId) { if (!is_string($extnId)) { // eg. if it's a \phpseclib3\File\ASN1\Element object return true; } if (isset(self::$extensions[$extnId])) { return self::$extensions[$extnId]; } switch ($extnId) { case 'id-ce-keyUsage': return Maps\KeyUsage::MAP; case 'id-ce-basicConstraints': return Maps\BasicConstraints::MAP; case 'id-ce-subjectKeyIdentifier': return Maps\KeyIdentifier::MAP; case 'id-ce-cRLDistributionPoints': return Maps\CRLDistributionPoints::MAP; case 'id-ce-authorityKeyIdentifier': return Maps\AuthorityKeyIdentifier::MAP; case 'id-ce-certificatePolicies': return Maps\CertificatePolicies::MAP; case 'id-ce-extKeyUsage': return Maps\ExtKeyUsageSyntax::MAP; case 'id-pe-authorityInfoAccess': return Maps\AuthorityInfoAccessSyntax::MAP; case 'id-ce-subjectAltName': return Maps\SubjectAltName::MAP; case 'id-ce-subjectDirectoryAttributes': return Maps\SubjectDirectoryAttributes::MAP; case 'id-ce-privateKeyUsagePeriod': return Maps\PrivateKeyUsagePeriod::MAP; case 'id-ce-issuerAltName': return Maps\IssuerAltName::MAP; case 'id-ce-policyMappings': return Maps\PolicyMappings::MAP; case 'id-ce-nameConstraints': return Maps\NameConstraints::MAP; case 'netscape-cert-type': return Maps\netscape_cert_type::MAP; case 'netscape-comment': return Maps\netscape_comment::MAP; case 'netscape-ca-policy-url': return Maps\netscape_ca_policy_url::MAP; // since id-qt-cps isn't a constructed type it will have already been decoded as a string by the time it gets // back around to asn1map() and we don't want it decoded again. //case 'id-qt-cps': // return Maps\CPSuri::MAP; case 'id-qt-unotice': return Maps\UserNotice::MAP; // the following OIDs are unsupported but we don't want them to give notices when calling saveX509(). case 'id-pe-logotype': // http://www.ietf.org/rfc/rfc3709.txt case 'entrustVersInfo': // http://support.microsoft.com/kb/287547 case '1.3.6.1.4.1.311.20.2': // szOID_ENROLL_CERTTYPE_EXTENSION case '1.3.6.1.4.1.311.21.1': // szOID_CERTSRV_CA_VERSION // "SET Secure Electronic Transaction Specification" // http://www.maithean.com/docs/set_bk3.pdf case '2.23.42.7.0': // id-set-hashedRootKey // "Certificate Transparency" // https://tools.ietf.org/html/rfc6962 case '1.3.6.1.4.1.11129.2.4.2': // "Qualified Certificate statements" // https://tools.ietf.org/html/rfc3739#section-3.2.6 case '1.3.6.1.5.5.7.1.3': return true; // CSR attributes case 'pkcs-9-at-unstructuredName': return Maps\PKCS9String::MAP; case 'pkcs-9-at-challengePassword': return Maps\DirectoryString::MAP; case 'pkcs-9-at-extensionRequest': return Maps\Extensions::MAP; // CRL extensions. case 'id-ce-cRLNumber': return Maps\CRLNumber::MAP; case 'id-ce-deltaCRLIndicator': return Maps\CRLNumber::MAP; case 'id-ce-issuingDistributionPoint': return Maps\IssuingDistributionPoint::MAP; case 'id-ce-freshestCRL': return Maps\CRLDistributionPoints::MAP; case 'id-ce-cRLReasons': return Maps\CRLReason::MAP; case 'id-ce-invalidityDate': return Maps\InvalidityDate::MAP; case 'id-ce-certificateIssuer': return Maps\CertificateIssuer::MAP; case 'id-ce-holdInstructionCode': return Maps\HoldInstructionCode::MAP; case 'id-at-postalAddress': return Maps\PostalAddress::MAP; } return false; } /** * Load an X.509 certificate as a certificate authority * * @param string $cert * @return bool */ public function loadCA($cert) { $olddn = $this->dn; $oldcert = $this->currentCert; $oldsigsubj = $this->signatureSubject; $oldkeyid = $this->currentKeyIdentifier; $cert = $this->loadX509($cert); if (!$cert) { $this->dn = $olddn; $this->currentCert = $oldcert; $this->signatureSubject = $oldsigsubj; $this->currentKeyIdentifier = $oldkeyid; return false; } /* From RFC5280 "PKIX Certificate and CRL Profile": If the keyUsage extension is present, then the subject public key MUST NOT be used to verify signatures on certificates or CRLs unless the corresponding keyCertSign or cRLSign bit is set. */ //$keyUsage = $this->getExtension('id-ce-keyUsage'); //if ($keyUsage && !in_array('keyCertSign', $keyUsage)) { // return false; //} /* From RFC5280 "PKIX Certificate and CRL Profile": The cA boolean indicates whether the certified public key may be used to verify certificate signatures. If the cA boolean is not asserted, then the keyCertSign bit in the key usage extension MUST NOT be asserted. If the basic constraints extension is not present in a version 3 certificate, or the extension is present but the cA boolean is not asserted, then the certified public key MUST NOT be used to verify certificate signatures. */ //$basicConstraints = $this->getExtension('id-ce-basicConstraints'); //if (!$basicConstraints || !$basicConstraints['cA']) { // return false; //} $this->CAs[] = $cert; $this->dn = $olddn; $this->currentCert = $oldcert; $this->signatureSubject = $oldsigsubj; return true; } /** * Validate an X.509 certificate against a URL * * From RFC2818 "HTTP over TLS": * * Matching is performed using the matching rules specified by * [RFC2459]. If more than one identity of a given type is present in * the certificate (e.g., more than one dNSName name, a match in any one * of the set is considered acceptable.) Names may contain the wildcard * character * which is considered to match any single domain name * component or component fragment. E.g., *.a.com matches foo.a.com but * not bar.foo.a.com. f*.com matches foo.com but not bar.com. * * @param string $url * @return bool */ public function validateURL($url) { if (!is_array($this->currentCert) || !isset($this->currentCert['tbsCertificate'])) { return false; } $components = parse_url($url); if (!isset($components['host'])) { return false; } if ($names = $this->getExtension('id-ce-subjectAltName')) { foreach ($names as $name) { foreach ($name as $key => $value) { $value = preg_quote($value); $value = str_replace('\*', '[^.]*', $value); switch ($key) { case 'dNSName': /* From RFC2818 "HTTP over TLS": If a subjectAltName extension of type dNSName is present, that MUST be used as the identity. Otherwise, the (most specific) Common Name field in the Subject field of the certificate MUST be used. Although the use of the Common Name is existing practice, it is deprecated and Certification Authorities are encouraged to use the dNSName instead. */ if (preg_match('#^' . $value . '$#', $components['host'])) { return true; } break; case 'iPAddress': /* From RFC2818 "HTTP over TLS": In some cases, the URI is specified as an IP address rather than a hostname. In this case, the iPAddress subjectAltName must be present in the certificate and must exactly match the IP in the URI. */ if (preg_match('#(?:\d{1-3}\.){4}#', $components['host'] . '.') && preg_match('#^' . $value . '$#', $components['host'])) { return true; } } } } return false; } if ($value = $this->getDNProp('id-at-commonName')) { $value = str_replace(['.', '*'], ['\.', '[^.]*'], $value[0]); return preg_match('#^' . $value . '$#', $components['host']) === 1; } return false; } /** * Validate a date * * If $date isn't defined it is assumed to be the current date. * * @param \DateTimeInterface|string $date optional * @return bool */ public function validateDate($date = null) { if (!is_array($this->currentCert) || !isset($this->currentCert['tbsCertificate'])) { return false; } if (!isset($date)) { $date = new \DateTimeImmutable('now', new \DateTimeZone(@date_default_timezone_get())); } $notBefore = $this->currentCert['tbsCertificate']['validity']['notBefore']; $notBefore = isset($notBefore['generalTime']) ? $notBefore['generalTime'] : $notBefore['utcTime']; $notAfter = $this->currentCert['tbsCertificate']['validity']['notAfter']; $notAfter = isset($notAfter['generalTime']) ? $notAfter['generalTime'] : $notAfter['utcTime']; if (is_string($date)) { $date = new \DateTimeImmutable($date, new \DateTimeZone(@date_default_timezone_get())); } $notBefore = new \DateTimeImmutable($notBefore, new \DateTimeZone(@date_default_timezone_get())); $notAfter = new \DateTimeImmutable($notAfter, new \DateTimeZone(@date_default_timezone_get())); return $date >= $notBefore && $date <= $notAfter; } /** * Fetches a URL * * @param string $url * @return bool|string */ private static function fetchURL($url) { if (self::$disable_url_fetch) { return false; } $parts = parse_url($url); $data = ''; switch ($parts['scheme']) { case 'http': $fsock = @fsockopen($parts['host'], isset($parts['port']) ? $parts['port'] : 80); if (!$fsock) { return false; } $path = $parts['path']; if (isset($parts['query'])) { $path .= '?' . $parts['query']; } fputs($fsock, "GET $path HTTP/1.0\r\n"); fputs($fsock, "Host: $parts[host]\r\n\r\n"); $line = fgets($fsock, 1024); if (strlen($line) < 3) { return false; } preg_match('#HTTP/1.\d (\d{3})#', $line, $temp); if ($temp[1] != '200') { return false; } // skip the rest of the headers in the http response while (!feof($fsock) && fgets($fsock, 1024) != "\r\n") { } while (!feof($fsock)) { $temp = fread($fsock, 1024); if ($temp === false) { return false; } $data .= $temp; } break; //case 'ftp': //case 'ldap': //default: } return $data; } /** * Validates an intermediate cert as identified via authority info access extension * * See https://tools.ietf.org/html/rfc4325 for more info * * @param bool $caonly * @param int $count * @return bool */ private function testForIntermediate($caonly, $count) { $opts = $this->getExtension('id-pe-authorityInfoAccess'); if (!is_array($opts)) { return false; } foreach ($opts as $opt) { if ($opt['accessMethod'] == 'id-ad-caIssuers') { // accessLocation is a GeneralName. GeneralName fields support stuff like email addresses, IP addresses, LDAP, // etc, but we're only supporting URI's. URI's and LDAP are the only thing https://tools.ietf.org/html/rfc4325 // discusses if (isset($opt['accessLocation']['uniformResourceIdentifier'])) { $url = $opt['accessLocation']['uniformResourceIdentifier']; break; } } } if (!isset($url)) { return false; } $cert = static::fetchURL($url); if (!is_string($cert)) { return false; } $parent = new static(); $parent->CAs = $this->CAs; /* "Conforming applications that support HTTP or FTP for accessing certificates MUST be able to accept .cer files and SHOULD be able to accept .p7c files." -- https://tools.ietf.org/html/rfc4325 A .p7c file is 'a "certs-only" CMS message as specified in RFC 2797" These are currently unsupported */ if (!is_array($parent->loadX509($cert))) { return false; } if (!$parent->validateSignatureCountable($caonly, ++$count)) { return false; } $this->CAs[] = $parent->currentCert; //$this->loadCA($cert); return true; } /** * Validate a signature * * Works on X.509 certs, CSR's and CRL's. * Returns true if the signature is verified, false if it is not correct or null on error * * By default returns false for self-signed certs. Call validateSignature(false) to make this support * self-signed. * * The behavior of this function is inspired by {@link http://php.net/openssl-verify openssl_verify}. * * @param bool $caonly optional * @return mixed */ public function validateSignature($caonly = true) { return $this->validateSignatureCountable($caonly, 0); } /** * Validate a signature * * Performs said validation whilst keeping track of how many times validation method is called * * @param bool $caonly * @param int $count * @return mixed */ private function validateSignatureCountable($caonly, $count) { if (!is_array($this->currentCert) || !isset($this->signatureSubject)) { return null; } if ($count == self::$recur_limit) { return false; } /* TODO: "emailAddress attribute values are not case-sensitive (e.g., "subscriber@example.com" is the same as "SUBSCRIBER@EXAMPLE.COM")." -- http://tools.ietf.org/html/rfc5280#section-4.1.2.6 implement pathLenConstraint in the id-ce-basicConstraints extension */ switch (true) { case isset($this->currentCert['tbsCertificate']): // self-signed cert switch (true) { case !defined('FILE_X509_IGNORE_TYPE') && $this->currentCert['tbsCertificate']['issuer'] === $this->currentCert['tbsCertificate']['subject']: case defined('FILE_X509_IGNORE_TYPE') && $this->getIssuerDN(self::DN_STRING) === $this->getDN(self::DN_STRING): $authorityKey = $this->getExtension('id-ce-authorityKeyIdentifier'); $subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier'); switch (true) { case !is_array($authorityKey): case !$subjectKeyID: case isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID: $signingCert = $this->currentCert; // working cert } } if (!empty($this->CAs)) { for ($i = 0; $i < count($this->CAs); $i++) { // even if the cert is a self-signed one we still want to see if it's a CA; // if not, we'll conditionally return an error $ca = $this->CAs[$i]; switch (true) { case !defined('FILE_X509_IGNORE_TYPE') && $this->currentCert['tbsCertificate']['issuer'] === $ca['tbsCertificate']['subject']: case defined('FILE_X509_IGNORE_TYPE') && $this->getDN(self::DN_STRING, $this->currentCert['tbsCertificate']['issuer']) === $this->getDN(self::DN_STRING, $ca['tbsCertificate']['subject']): $authorityKey = $this->getExtension('id-ce-authorityKeyIdentifier'); $subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier', $ca); switch (true) { case !is_array($authorityKey): case !$subjectKeyID: case isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID: if (is_array($authorityKey) && isset($authorityKey['authorityCertSerialNumber']) && !$authorityKey['authorityCertSerialNumber']->equals($ca['tbsCertificate']['serialNumber'])) { break 2; // serial mismatch - check other ca } $signingCert = $ca; // working cert break 3; } } } if (count($this->CAs) == $i && $caonly) { return $this->testForIntermediate($caonly, $count) && $this->validateSignature($caonly); } } elseif (!isset($signingCert) || $caonly) { return $this->testForIntermediate($caonly, $count) && $this->validateSignature($caonly); } return $this->validateSignatureHelper( $signingCert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm'], $signingCert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'], $this->currentCert['signatureAlgorithm']['algorithm'], substr($this->currentCert['signature'], 1), $this->signatureSubject ); case isset($this->currentCert['certificationRequestInfo']): return $this->validateSignatureHelper( $this->currentCert['certificationRequestInfo']['subjectPKInfo']['algorithm']['algorithm'], $this->currentCert['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'], $this->currentCert['signatureAlgorithm']['algorithm'], substr($this->currentCert['signature'], 1), $this->signatureSubject ); case isset($this->currentCert['publicKeyAndChallenge']): return $this->validateSignatureHelper( $this->currentCert['publicKeyAndChallenge']['spki']['algorithm']['algorithm'], $this->currentCert['publicKeyAndChallenge']['spki']['subjectPublicKey'], $this->currentCert['signatureAlgorithm']['algorithm'], substr($this->currentCert['signature'], 1), $this->signatureSubject ); case isset($this->currentCert['tbsCertList']): if (!empty($this->CAs)) { for ($i = 0; $i < count($this->CAs); $i++) { $ca = $this->CAs[$i]; switch (true) { case !defined('FILE_X509_IGNORE_TYPE') && $this->currentCert['tbsCertList']['issuer'] === $ca['tbsCertificate']['subject']: case defined('FILE_X509_IGNORE_TYPE') && $this->getDN(self::DN_STRING, $this->currentCert['tbsCertList']['issuer']) === $this->getDN(self::DN_STRING, $ca['tbsCertificate']['subject']): $authorityKey = $this->getExtension('id-ce-authorityKeyIdentifier'); $subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier', $ca); switch (true) { case !is_array($authorityKey): case !$subjectKeyID: case isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID: if (is_array($authorityKey) && isset($authorityKey['authorityCertSerialNumber']) && !$authorityKey['authorityCertSerialNumber']->equals($ca['tbsCertificate']['serialNumber'])) { break 2; // serial mismatch - check other ca } $signingCert = $ca; // working cert break 3; } } } } if (!isset($signingCert)) { return false; } return $this->validateSignatureHelper( $signingCert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm'], $signingCert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'], $this->currentCert['signatureAlgorithm']['algorithm'], substr($this->currentCert['signature'], 1), $this->signatureSubject ); default: return false; } } /** * Validates a signature * * Returns true if the signature is verified and false if it is not correct. * If the algorithms are unsupposed an exception is thrown. * * @param string $publicKeyAlgorithm * @param string $publicKey * @param string $signatureAlgorithm * @param string $signature * @param string $signatureSubject * @throws UnsupportedAlgorithmException if the algorithm is unsupported * @return bool */ private function validateSignatureHelper($publicKeyAlgorithm, $publicKey, $signatureAlgorithm, $signature, $signatureSubject) { switch ($publicKeyAlgorithm) { case 'id-RSASSA-PSS': $key = RSA::loadFormat('PSS', $publicKey); break; case 'rsaEncryption': $key = RSA::loadFormat('PKCS8', $publicKey); switch ($signatureAlgorithm) { case 'id-RSASSA-PSS': break; case 'md2WithRSAEncryption': case 'md5WithRSAEncryption': case 'sha1WithRSAEncryption': case 'sha224WithRSAEncryption': case 'sha256WithRSAEncryption': case 'sha384WithRSAEncryption': case 'sha512WithRSAEncryption': $key = $key ->withHash(preg_replace('#WithRSAEncryption$#', '', $signatureAlgorithm)) ->withPadding(RSA::SIGNATURE_PKCS1); break; default: throw new UnsupportedAlgorithmException('Signature algorithm unsupported'); } break; case 'id-Ed25519': case 'id-Ed448': $key = EC::loadFormat('PKCS8', $publicKey); break; case 'id-ecPublicKey': $key = EC::loadFormat('PKCS8', $publicKey); switch ($signatureAlgorithm) { case 'ecdsa-with-SHA1': case 'ecdsa-with-SHA224': case 'ecdsa-with-SHA256': case 'ecdsa-with-SHA384': case 'ecdsa-with-SHA512': $key = $key ->withHash(preg_replace('#^ecdsa-with-#', '', strtolower($signatureAlgorithm))); break; default: throw new UnsupportedAlgorithmException('Signature algorithm unsupported'); } break; case 'id-dsa': $key = DSA::loadFormat('PKCS8', $publicKey); switch ($signatureAlgorithm) { case 'id-dsa-with-sha1': case 'id-dsa-with-sha224': case 'id-dsa-with-sha256': $key = $key ->withHash(preg_replace('#^id-dsa-with-#', '', strtolower($signatureAlgorithm))); break; default: throw new UnsupportedAlgorithmException('Signature algorithm unsupported'); } break; default: throw new UnsupportedAlgorithmException('Public key algorithm unsupported'); } return $key->verify($signatureSubject, $signature); } /** * Sets the recursion limit * * When validating a signature it may be necessary to download intermediate certs from URI's. * An intermediate cert that linked to itself would result in an infinite loop so to prevent * that we set a recursion limit. A negative number means that there is no recursion limit. * * @param int $count */ public static function setRecurLimit($count) { self::$recur_limit = $count; } /** * Prevents URIs from being automatically retrieved * */ public static function disableURLFetch() { self::$disable_url_fetch = true; } /** * Allows URIs to be automatically retrieved * */ public static function enableURLFetch() { self::$disable_url_fetch = false; } /** * Decodes an IP address * * Takes in a base64 encoded "blob" and returns a human readable IP address * * @param string $ip * @return string */ public static function decodeIP($ip) { return inet_ntop($ip); } /** * Decodes an IP address in a name constraints extension * * Takes in a base64 encoded "blob" and returns a human readable IP address / mask * * @param string $ip * @return array */ public static function decodeNameConstraintIP($ip) { $size = strlen($ip) >> 1; $mask = substr($ip, $size); $ip = substr($ip, 0, $size); return [inet_ntop($ip), inet_ntop($mask)]; } /** * Encodes an IP address * * Takes a human readable IP address into a base64-encoded "blob" * * @param string|array $ip * @return string */ public static function encodeIP($ip) { return is_string($ip) ? inet_pton($ip) : inet_pton($ip[0]) . inet_pton($ip[1]); } /** * "Normalizes" a Distinguished Name property * * @param string $propName * @return mixed */ private function translateDNProp($propName) { switch (strtolower($propName)) { case 'jurisdictionofincorporationcountryname': case 'jurisdictioncountryname': case 'jurisdictionc': return 'jurisdictionOfIncorporationCountryName'; case 'jurisdictionofincorporationstateorprovincename': case 'jurisdictionstateorprovincename': case 'jurisdictionst': return 'jurisdictionOfIncorporationStateOrProvinceName'; case 'jurisdictionlocalityname': case 'jurisdictionl': return 'jurisdictionLocalityName'; case 'id-at-businesscategory': case 'businesscategory': return 'id-at-businessCategory'; case 'id-at-countryname': case 'countryname': case 'c': return 'id-at-countryName'; case 'id-at-organizationname': case 'organizationname': case 'o': return 'id-at-organizationName'; case 'id-at-dnqualifier': case 'dnqualifier': return 'id-at-dnQualifier'; case 'id-at-commonname': case 'commonname': case 'cn': return 'id-at-commonName'; case 'id-at-stateorprovincename': case 'stateorprovincename': case 'state': case 'province': case 'provincename': case 'st': return 'id-at-stateOrProvinceName'; case 'id-at-localityname': case 'localityname': case 'l': return 'id-at-localityName'; case 'id-emailaddress': case 'emailaddress': return 'pkcs-9-at-emailAddress'; case 'id-at-serialnumber': case 'serialnumber': return 'id-at-serialNumber'; case 'id-at-postalcode': case 'postalcode': return 'id-at-postalCode'; case 'id-at-streetaddress': case 'streetaddress': return 'id-at-streetAddress'; case 'id-at-name': case 'name': return 'id-at-name'; case 'id-at-givenname': case 'givenname': return 'id-at-givenName'; case 'id-at-surname': case 'surname': case 'sn': return 'id-at-surname'; case 'id-at-initials': case 'initials': return 'id-at-initials'; case 'id-at-generationqualifier': case 'generationqualifier': return 'id-at-generationQualifier'; case 'id-at-organizationalunitname': case 'organizationalunitname': case 'ou': return 'id-at-organizationalUnitName'; case 'id-at-pseudonym': case 'pseudonym': return 'id-at-pseudonym'; case 'id-at-title': case 'title': return 'id-at-title'; case 'id-at-description': case 'description': return 'id-at-description'; case 'id-at-role': case 'role': return 'id-at-role'; case 'id-at-uniqueidentifier': case 'uniqueidentifier': case 'x500uniqueidentifier': return 'id-at-uniqueIdentifier'; case 'postaladdress': case 'id-at-postaladdress': return 'id-at-postalAddress'; default: return false; } } /** * Set a Distinguished Name property * * @param string $propName * @param mixed $propValue * @param string $type optional * @return bool */ public function setDNProp($propName, $propValue, $type = 'utf8String') { if (empty($this->dn)) { $this->dn = ['rdnSequence' => []]; } if (($propName = $this->translateDNProp($propName)) === false) { return false; } foreach ((array) $propValue as $v) { if (!is_array($v) && isset($type)) { $v = [$type => $v]; } $this->dn['rdnSequence'][] = [ [ 'type' => $propName, 'value' => $v ] ]; } return true; } /** * Remove Distinguished Name properties * * @param string $propName */ public function removeDNProp($propName) { if (empty($this->dn)) { return; } if (($propName = $this->translateDNProp($propName)) === false) { return; } $dn = &$this->dn['rdnSequence']; $size = count($dn); for ($i = 0; $i < $size; $i++) { if ($dn[$i][0]['type'] == $propName) { unset($dn[$i]); } } $dn = array_values($dn); // fix for https://bugs.php.net/75433 affecting PHP 7.2 if (!isset($dn[0])) { $dn = array_splice($dn, 0, 0); } } /** * Get Distinguished Name properties * * @param string $propName * @param array $dn optional * @param bool $withType optional * @return mixed */ public function getDNProp($propName, $dn = null, $withType = false) { if (!isset($dn)) { $dn = $this->dn; } if (empty($dn)) { return false; } if (($propName = $this->translateDNProp($propName)) === false) { return false; } $filters = []; $filters['value'] = ['type' => ASN1::TYPE_UTF8_STRING]; ASN1::setFilters($filters); $this->mapOutDNs($dn, 'rdnSequence'); $dn = $dn['rdnSequence']; $result = []; for ($i = 0; $i < count($dn); $i++) { if ($dn[$i][0]['type'] == $propName) { $v = $dn[$i][0]['value']; if (!$withType) { if (is_array($v)) { foreach ($v as $type => $s) { $type = array_search($type, ASN1::ANY_MAP); if ($type !== false && array_key_exists($type, ASN1::STRING_TYPE_SIZE)) { $s = ASN1::convert($s, $type); if ($s !== false) { $v = $s; break; } } } if (is_array($v)) { $v = array_pop($v); // Always strip data type. } } elseif (is_object($v) && $v instanceof Element) { $map = $this->getMapping($propName); if (!is_bool($map)) { $decoded = ASN1::decodeBER($v); if (!$decoded) { return false; } $v = ASN1::asn1map($decoded[0], $map); } } } $result[] = $v; } } return $result; } /** * Set a Distinguished Name * * @param mixed $dn * @param bool $merge optional * @param string $type optional * @return bool */ public function setDN($dn, $merge = false, $type = 'utf8String') { if (!$merge) { $this->dn = null; } if (is_array($dn)) { if (isset($dn['rdnSequence'])) { $this->dn = $dn; // No merge here. return true; } // handles stuff generated by openssl_x509_parse() foreach ($dn as $prop => $value) { if (!$this->setDNProp($prop, $value, $type)) { return false; } } return true; } // handles everything else $results = preg_split('#((?:^|, *|/)(?:C=|O=|OU=|CN=|L=|ST=|SN=|postalCode=|streetAddress=|emailAddress=|serialNumber=|organizationalUnitName=|title=|description=|role=|x500UniqueIdentifier=|postalAddress=))#', $dn, -1, PREG_SPLIT_DELIM_CAPTURE); for ($i = 1; $i < count($results); $i += 2) { $prop = trim($results[$i], ', =/'); $value = $results[$i + 1]; if (!$this->setDNProp($prop, $value, $type)) { return false; } } return true; } /** * Get the Distinguished Name for a certificates subject * * @param mixed $format optional * @param array $dn optional * @return array|bool|string */ public function getDN($format = self::DN_ARRAY, $dn = null) { if (!isset($dn)) { $dn = isset($this->currentCert['tbsCertList']) ? $this->currentCert['tbsCertList']['issuer'] : $this->dn; } switch ((int) $format) { case self::DN_ARRAY: return $dn; case self::DN_ASN1: $filters = []; $filters['rdnSequence']['value'] = ['type' => ASN1::TYPE_UTF8_STRING]; ASN1::setFilters($filters); $this->mapOutDNs($dn, 'rdnSequence'); return ASN1::encodeDER($dn, Maps\Name::MAP); case self::DN_CANON: // No SEQUENCE around RDNs and all string values normalized as // trimmed lowercase UTF-8 with all spacing as one blank. // constructed RDNs will not be canonicalized $filters = []; $filters['value'] = ['type' => ASN1::TYPE_UTF8_STRING]; ASN1::setFilters($filters); $result = ''; $this->mapOutDNs($dn, 'rdnSequence'); foreach ($dn['rdnSequence'] as $rdn) { foreach ($rdn as $i => $attr) { $attr = &$rdn[$i]; if (is_array($attr['value'])) { foreach ($attr['value'] as $type => $v) { $type = array_search($type, ASN1::ANY_MAP, true); if ($type !== false && array_key_exists($type, ASN1::STRING_TYPE_SIZE)) { $v = ASN1::convert($v, $type); if ($v !== false) { $v = preg_replace('/\s+/', ' ', $v); $attr['value'] = strtolower(trim($v)); break; } } } } } $result .= ASN1::encodeDER($rdn, Maps\RelativeDistinguishedName::MAP); } return $result; case self::DN_HASH: $dn = $this->getDN(self::DN_CANON, $dn); $hash = new Hash('sha1'); $hash = $hash->hash($dn); $hash = unpack('Vhash', $hash)['hash']; return strtolower(Strings::bin2hex(pack('N', $hash))); } // Default is to return a string. $start = true; $output = ''; $result = []; $filters = []; $filters['rdnSequence']['value'] = ['type' => ASN1::TYPE_UTF8_STRING]; ASN1::setFilters($filters); $this->mapOutDNs($dn, 'rdnSequence'); foreach ($dn['rdnSequence'] as $field) { $prop = $field[0]['type']; $value = $field[0]['value']; $delim = ', '; switch ($prop) { case 'id-at-countryName': $desc = 'C'; break; case 'id-at-stateOrProvinceName': $desc = 'ST'; break; case 'id-at-organizationName': $desc = 'O'; break; case 'id-at-organizationalUnitName': $desc = 'OU'; break; case 'id-at-commonName': $desc = 'CN'; break; case 'id-at-localityName': $desc = 'L'; break; case 'id-at-surname': $desc = 'SN'; break; case 'id-at-uniqueIdentifier': $delim = '/'; $desc = 'x500UniqueIdentifier'; break; case 'id-at-postalAddress': $delim = '/'; $desc = 'postalAddress'; break; default: $delim = '/'; $desc = preg_replace('#.+-([^-]+)$#', '$1', $prop); } if (!$start) { $output .= $delim; } if (is_array($value)) { foreach ($value as $type => $v) { $type = array_search($type, ASN1::ANY_MAP, true); if ($type !== false && array_key_exists($type, ASN1::STRING_TYPE_SIZE)) { $v = ASN1::convert($v, $type); if ($v !== false) { $value = $v; break; } } } if (is_array($value)) { $value = array_pop($value); // Always strip data type. } } elseif (is_object($value) && $value instanceof Element) { $callback = function ($x) { return '\x' . bin2hex($x[0]); }; $value = strtoupper(preg_replace_callback('#[^\x20-\x7E]#', $callback, $value->element)); } $output .= $desc . '=' . $value; $result[$desc] = isset($result[$desc]) ? array_merge((array) $result[$desc], [$value]) : $value; $start = false; } return $format == self::DN_OPENSSL ? $result : $output; } /** * Get the Distinguished Name for a certificate/crl issuer * * @param int $format optional * @return mixed */ public function getIssuerDN($format = self::DN_ARRAY) { switch (true) { case !isset($this->currentCert) || !is_array($this->currentCert): break; case isset($this->currentCert['tbsCertificate']): return $this->getDN($format, $this->currentCert['tbsCertificate']['issuer']); case isset($this->currentCert['tbsCertList']): return $this->getDN($format, $this->currentCert['tbsCertList']['issuer']); } return false; } /** * Get the Distinguished Name for a certificate/csr subject * Alias of getDN() * * @param int $format optional * @return mixed */ public function getSubjectDN($format = self::DN_ARRAY) { switch (true) { case !empty($this->dn): return $this->getDN($format); case !isset($this->currentCert) || !is_array($this->currentCert): break; case isset($this->currentCert['tbsCertificate']): return $this->getDN($format, $this->currentCert['tbsCertificate']['subject']); case isset($this->currentCert['certificationRequestInfo']): return $this->getDN($format, $this->currentCert['certificationRequestInfo']['subject']); } return false; } /** * Get an individual Distinguished Name property for a certificate/crl issuer * * @param string $propName * @param bool $withType optional * @return mixed */ public function getIssuerDNProp($propName, $withType = false) { switch (true) { case !isset($this->currentCert) || !is_array($this->currentCert): break; case isset($this->currentCert['tbsCertificate']): return $this->getDNProp($propName, $this->currentCert['tbsCertificate']['issuer'], $withType); case isset($this->currentCert['tbsCertList']): return $this->getDNProp($propName, $this->currentCert['tbsCertList']['issuer'], $withType); } return false; } /** * Get an individual Distinguished Name property for a certificate/csr subject * * @param string $propName * @param bool $withType optional * @return mixed */ public function getSubjectDNProp($propName, $withType = false) { switch (true) { case !empty($this->dn): return $this->getDNProp($propName, null, $withType); case !isset($this->currentCert) || !is_array($this->currentCert): break; case isset($this->currentCert['tbsCertificate']): return $this->getDNProp($propName, $this->currentCert['tbsCertificate']['subject'], $withType); case isset($this->currentCert['certificationRequestInfo']): return $this->getDNProp($propName, $this->currentCert['certificationRequestInfo']['subject'], $withType); } return false; } /** * Get the certificate chain for the current cert * * @return mixed */ public function getChain() { $chain = [$this->currentCert]; if (!is_array($this->currentCert) || !isset($this->currentCert['tbsCertificate'])) { return false; } while (true) { $currentCert = $chain[count($chain) - 1]; for ($i = 0; $i < count($this->CAs); $i++) { $ca = $this->CAs[$i]; if ($currentCert['tbsCertificate']['issuer'] === $ca['tbsCertificate']['subject']) { $authorityKey = $this->getExtension('id-ce-authorityKeyIdentifier', $currentCert); $subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier', $ca); switch (true) { case !is_array($authorityKey): case is_array($authorityKey) && isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID: if ($currentCert === $ca) { break 3; } $chain[] = $ca; break 2; } } } if ($i == count($this->CAs)) { break; } } foreach ($chain as $key => $value) { $chain[$key] = new X509(); $chain[$key]->loadX509($value); } return $chain; } /** * Returns the current cert * * @return array|bool */ public function &getCurrentCert() { return $this->currentCert; } /** * Set public key * * Key needs to be a \phpseclib3\Crypt\RSA object * * @param PublicKey $key * @return void */ public function setPublicKey(PublicKey $key) { $this->publicKey = $key; } /** * Set private key * * Key needs to be a \phpseclib3\Crypt\RSA object * * @param PrivateKey $key */ public function setPrivateKey(PrivateKey $key) { $this->privateKey = $key; } /** * Set challenge * * Used for SPKAC CSR's * * @param string $challenge */ public function setChallenge($challenge) { $this->challenge = $challenge; } /** * Gets the public key * * Returns a \phpseclib3\Crypt\RSA object or a false. * * @return mixed */ public function getPublicKey() { if (isset($this->publicKey)) { return $this->publicKey; } if (isset($this->currentCert) && is_array($this->currentCert)) { $paths = [ 'tbsCertificate/subjectPublicKeyInfo', 'certificationRequestInfo/subjectPKInfo', 'publicKeyAndChallenge/spki' ]; foreach ($paths as $path) { $keyinfo = $this->subArray($this->currentCert, $path); if (!empty($keyinfo)) { break; } } } if (empty($keyinfo)) { return false; } $key = $keyinfo['subjectPublicKey']; switch ($keyinfo['algorithm']['algorithm']) { case 'id-RSASSA-PSS': return RSA::loadFormat('PSS', $key); case 'rsaEncryption': return RSA::loadFormat('PKCS8', $key)->withPadding(RSA::SIGNATURE_PKCS1); case 'id-ecPublicKey': case 'id-Ed25519': case 'id-Ed448': return EC::loadFormat('PKCS8', $key); case 'id-dsa': return DSA::loadFormat('PKCS8', $key); } return false; } /** * Load a Certificate Signing Request * * @param string $csr * @param int $mode * @return mixed */ public function loadCSR($csr, $mode = self::FORMAT_AUTO_DETECT) { if (is_array($csr) && isset($csr['certificationRequestInfo'])) { unset($this->currentCert); unset($this->currentKeyIdentifier); unset($this->signatureSubject); $this->dn = $csr['certificationRequestInfo']['subject']; if (!isset($this->dn)) { return false; } $this->currentCert = $csr; return $csr; } // see http://tools.ietf.org/html/rfc2986 if ($mode != self::FORMAT_DER) { $newcsr = ASN1::extractBER($csr); if ($mode == self::FORMAT_PEM && $csr == $newcsr) { return false; } $csr = $newcsr; } $orig = $csr; if ($csr === false) { $this->currentCert = false; return false; } $decoded = ASN1::decodeBER($csr); if (!$decoded) { $this->currentCert = false; return false; } $csr = ASN1::asn1map($decoded[0], Maps\CertificationRequest::MAP); if (!isset($csr) || $csr === false) { $this->currentCert = false; return false; } $this->mapInAttributes($csr, 'certificationRequestInfo/attributes'); $this->mapInDNs($csr, 'certificationRequestInfo/subject/rdnSequence'); $this->dn = $csr['certificationRequestInfo']['subject']; $this->signatureSubject = substr($orig, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']); $key = $csr['certificationRequestInfo']['subjectPKInfo']; $key = ASN1::encodeDER($key, Maps\SubjectPublicKeyInfo::MAP); $csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'] = "-----BEGIN PUBLIC KEY-----\r\n" . chunk_split(base64_encode($key), 64) . "-----END PUBLIC KEY-----"; $this->currentKeyIdentifier = null; $this->currentCert = $csr; $this->publicKey = null; $this->publicKey = $this->getPublicKey(); return $csr; } /** * Save CSR request * * @param array $csr * @param int $format optional * @return string */ public function saveCSR(array $csr, $format = self::FORMAT_PEM) { if (!is_array($csr) || !isset($csr['certificationRequestInfo'])) { return false; } switch (true) { case !($algorithm = $this->subArray($csr, 'certificationRequestInfo/subjectPKInfo/algorithm/algorithm')): case is_object($csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey']): break; default: $csr['certificationRequestInfo']['subjectPKInfo'] = new Element( base64_decode(preg_replace('#-.+-|[\r\n]#', '', $csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'])) ); } $filters = []; $filters['certificationRequestInfo']['subject']['rdnSequence']['value'] = ['type' => ASN1::TYPE_UTF8_STRING]; ASN1::setFilters($filters); $this->mapOutDNs($csr, 'certificationRequestInfo/subject/rdnSequence'); $this->mapOutAttributes($csr, 'certificationRequestInfo/attributes'); $csr = ASN1::encodeDER($csr, Maps\CertificationRequest::MAP); switch ($format) { case self::FORMAT_DER: return $csr; // case self::FORMAT_PEM: default: return "-----BEGIN CERTIFICATE REQUEST-----\r\n" . chunk_split(Strings::base64_encode($csr), 64) . '-----END CERTIFICATE REQUEST-----'; } } /** * Load a SPKAC CSR * * SPKAC's are produced by the HTML5 keygen element: * * https://developer.mozilla.org/en-US/docs/HTML/Element/keygen * * @param string $spkac * @return mixed */ public function loadSPKAC($spkac) { if (is_array($spkac) && isset($spkac['publicKeyAndChallenge'])) { unset($this->currentCert); unset($this->currentKeyIdentifier); unset($this->signatureSubject); $this->currentCert = $spkac; return $spkac; } // see http://www.w3.org/html/wg/drafts/html/master/forms.html#signedpublickeyandchallenge // OpenSSL produces SPKAC's that are preceded by the string SPKAC= $temp = preg_replace('#(?:SPKAC=)|[ \r\n\\\]#', '', $spkac); $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? Strings::base64_decode($temp) : false; if ($temp != false) { $spkac = $temp; } $orig = $spkac; if ($spkac === false) { $this->currentCert = false; return false; } $decoded = ASN1::decodeBER($spkac); if (!$decoded) { $this->currentCert = false; return false; } $spkac = ASN1::asn1map($decoded[0], Maps\SignedPublicKeyAndChallenge::MAP); if (!isset($spkac) || !is_array($spkac)) { $this->currentCert = false; return false; } $this->signatureSubject = substr($orig, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']); $key = $spkac['publicKeyAndChallenge']['spki']; $key = ASN1::encodeDER($key, Maps\SubjectPublicKeyInfo::MAP); $spkac['publicKeyAndChallenge']['spki']['subjectPublicKey'] = "-----BEGIN PUBLIC KEY-----\r\n" . chunk_split(base64_encode($key), 64) . "-----END PUBLIC KEY-----"; $this->currentKeyIdentifier = null; $this->currentCert = $spkac; $this->publicKey = null; $this->publicKey = $this->getPublicKey(); return $spkac; } /** * Save a SPKAC CSR request * * @param array $spkac * @param int $format optional * @return string */ public function saveSPKAC(array $spkac, $format = self::FORMAT_PEM) { if (!is_array($spkac) || !isset($spkac['publicKeyAndChallenge'])) { return false; } $algorithm = $this->subArray($spkac, 'publicKeyAndChallenge/spki/algorithm/algorithm'); switch (true) { case !$algorithm: case is_object($spkac['publicKeyAndChallenge']['spki']['subjectPublicKey']): break; default: $spkac['publicKeyAndChallenge']['spki'] = new Element( base64_decode(preg_replace('#-.+-|[\r\n]#', '', $spkac['publicKeyAndChallenge']['spki']['subjectPublicKey'])) ); } $spkac = ASN1::encodeDER($spkac, Maps\SignedPublicKeyAndChallenge::MAP); switch ($format) { case self::FORMAT_DER: return $spkac; // case self::FORMAT_PEM: default: // OpenSSL's implementation of SPKAC requires the SPKAC be preceded by SPKAC= and since there are pretty much // no other SPKAC decoders phpseclib will use that same format return 'SPKAC=' . Strings::base64_encode($spkac); } } /** * Load a Certificate Revocation List * * @param string $crl * @param int $mode * @return mixed */ public function loadCRL($crl, $mode = self::FORMAT_AUTO_DETECT) { if (is_array($crl) && isset($crl['tbsCertList'])) { $this->currentCert = $crl; unset($this->signatureSubject); return $crl; } if ($mode != self::FORMAT_DER) { $newcrl = ASN1::extractBER($crl); if ($mode == self::FORMAT_PEM && $crl == $newcrl) { return false; } $crl = $newcrl; } $orig = $crl; if ($crl === false) { $this->currentCert = false; return false; } $decoded = ASN1::decodeBER($crl); if (!$decoded) { $this->currentCert = false; return false; } $crl = ASN1::asn1map($decoded[0], Maps\CertificateList::MAP); if (!isset($crl) || $crl === false) { $this->currentCert = false; return false; } $this->signatureSubject = substr($orig, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']); $this->mapInDNs($crl, 'tbsCertList/issuer/rdnSequence'); if ($this->isSubArrayValid($crl, 'tbsCertList/crlExtensions')) { $this->mapInExtensions($crl, 'tbsCertList/crlExtensions'); } if ($this->isSubArrayValid($crl, 'tbsCertList/revokedCertificates')) { $rclist_ref = &$this->subArrayUnchecked($crl, 'tbsCertList/revokedCertificates'); if ($rclist_ref) { $rclist = $crl['tbsCertList']['revokedCertificates']; foreach ($rclist as $i => $extension) { if ($this->isSubArrayValid($rclist, "$i/crlEntryExtensions")) { $this->mapInExtensions($rclist_ref, "$i/crlEntryExtensions"); } } } } $this->currentKeyIdentifier = null; $this->currentCert = $crl; return $crl; } /** * Save Certificate Revocation List. * * @param array $crl * @param int $format optional * @return string */ public function saveCRL(array $crl, $format = self::FORMAT_PEM) { if (!is_array($crl) || !isset($crl['tbsCertList'])) { return false; } $filters = []; $filters['tbsCertList']['issuer']['rdnSequence']['value'] = ['type' => ASN1::TYPE_UTF8_STRING]; $filters['tbsCertList']['signature']['parameters'] = ['type' => ASN1::TYPE_UTF8_STRING]; $filters['signatureAlgorithm']['parameters'] = ['type' => ASN1::TYPE_UTF8_STRING]; if (empty($crl['tbsCertList']['signature']['parameters'])) { $filters['tbsCertList']['signature']['parameters'] = ['type' => ASN1::TYPE_NULL]; } if (empty($crl['signatureAlgorithm']['parameters'])) { $filters['signatureAlgorithm']['parameters'] = ['type' => ASN1::TYPE_NULL]; } ASN1::setFilters($filters); $this->mapOutDNs($crl, 'tbsCertList/issuer/rdnSequence'); $this->mapOutExtensions($crl, 'tbsCertList/crlExtensions'); $rclist = &$this->subArray($crl, 'tbsCertList/revokedCertificates'); if (is_array($rclist)) { foreach ($rclist as $i => $extension) { $this->mapOutExtensions($rclist, "$i/crlEntryExtensions"); } } $crl = ASN1::encodeDER($crl, Maps\CertificateList::MAP); switch ($format) { case self::FORMAT_DER: return $crl; // case self::FORMAT_PEM: default: return "-----BEGIN X509 CRL-----\r\n" . chunk_split(Strings::base64_encode($crl), 64) . '-----END X509 CRL-----'; } } /** * Helper function to build a time field according to RFC 3280 section * - 4.1.2.5 Validity * - 5.1.2.4 This Update * - 5.1.2.5 Next Update * - 5.1.2.6 Revoked Certificates * by choosing utcTime iff year of date given is before 2050 and generalTime else. * * @param string $date in format date('D, d M Y H:i:s O') * @return array|Element */ private function timeField($date) { if ($date instanceof Element) { return $date; } $dateObj = new \DateTimeImmutable($date, new \DateTimeZone('GMT')); $year = $dateObj->format('Y'); // the same way ASN1.php parses this if ($year < 2050) { return ['utcTime' => $date]; } else { return ['generalTime' => $date]; } } /** * Sign an X.509 certificate * * $issuer's private key needs to be loaded. * $subject can be either an existing X.509 cert (if you want to resign it), * a CSR or something with the DN and public key explicitly set. * * @return mixed */ public function sign(X509 $issuer, X509 $subject) { if (!is_object($issuer->privateKey) || empty($issuer->dn)) { return false; } if (isset($subject->publicKey) && !($subjectPublicKey = $subject->formatSubjectPublicKey())) { return false; } $currentCert = isset($this->currentCert) ? $this->currentCert : null; $signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject : null; $signatureAlgorithm = self::identifySignatureAlgorithm($issuer->privateKey); if (isset($subject->currentCert) && is_array($subject->currentCert) && isset($subject->currentCert['tbsCertificate'])) { $this->currentCert = $subject->currentCert; $this->currentCert['tbsCertificate']['signature'] = $signatureAlgorithm; $this->currentCert['signatureAlgorithm'] = $signatureAlgorithm; if (!empty($this->startDate)) { $this->currentCert['tbsCertificate']['validity']['notBefore'] = $this->timeField($this->startDate); } if (!empty($this->endDate)) { $this->currentCert['tbsCertificate']['validity']['notAfter'] = $this->timeField($this->endDate); } if (!empty($this->serialNumber)) { $this->currentCert['tbsCertificate']['serialNumber'] = $this->serialNumber; } if (!empty($subject->dn)) { $this->currentCert['tbsCertificate']['subject'] = $subject->dn; } if (!empty($subject->publicKey)) { $this->currentCert['tbsCertificate']['subjectPublicKeyInfo'] = $subjectPublicKey; } $this->removeExtension('id-ce-authorityKeyIdentifier'); if (isset($subject->domains)) { $this->removeExtension('id-ce-subjectAltName'); } } elseif (isset($subject->currentCert) && is_array($subject->currentCert) && isset($subject->currentCert['tbsCertList'])) { return false; } else { if (!isset($subject->publicKey)) { return false; } $startDate = new \DateTimeImmutable('now', new \DateTimeZone(@date_default_timezone_get())); $startDate = !empty($this->startDate) ? $this->startDate : $startDate->format('D, d M Y H:i:s O'); $endDate = new \DateTimeImmutable('+1 year', new \DateTimeZone(@date_default_timezone_get())); $endDate = !empty($this->endDate) ? $this->endDate : $endDate->format('D, d M Y H:i:s O'); /* "The serial number MUST be a positive integer" "Conforming CAs MUST NOT use serialNumber values longer than 20 octets." -- https://tools.ietf.org/html/rfc5280#section-4.1.2.2 for the integer to be positive the leading bit needs to be 0 hence the application of a bitmap */ $serialNumber = !empty($this->serialNumber) ? $this->serialNumber : new BigInteger(Random::string(20) & ("\x7F" . str_repeat("\xFF", 19)), 256); $this->currentCert = [ 'tbsCertificate' => [ 'version' => 'v3', 'serialNumber' => $serialNumber, // $this->setSerialNumber() 'signature' => $signatureAlgorithm, 'issuer' => false, // this is going to be overwritten later 'validity' => [ 'notBefore' => $this->timeField($startDate), // $this->setStartDate() 'notAfter' => $this->timeField($endDate) // $this->setEndDate() ], 'subject' => $subject->dn, 'subjectPublicKeyInfo' => $subjectPublicKey ], 'signatureAlgorithm' => $signatureAlgorithm, 'signature' => false // this is going to be overwritten later ]; // Copy extensions from CSR. $csrexts = $subject->getAttribute('pkcs-9-at-extensionRequest', 0); if (!empty($csrexts)) { $this->currentCert['tbsCertificate']['extensions'] = $csrexts; } } $this->currentCert['tbsCertificate']['issuer'] = $issuer->dn; if (isset($issuer->currentKeyIdentifier)) { $this->setExtension('id-ce-authorityKeyIdentifier', [ //'authorityCertIssuer' => array( // array( // 'directoryName' => $issuer->dn // ) //), 'keyIdentifier' => $issuer->currentKeyIdentifier ]); //$extensions = &$this->currentCert['tbsCertificate']['extensions']; //if (isset($issuer->serialNumber)) { // $extensions[count($extensions) - 1]['authorityCertSerialNumber'] = $issuer->serialNumber; //} //unset($extensions); } if (isset($subject->currentKeyIdentifier)) { $this->setExtension('id-ce-subjectKeyIdentifier', $subject->currentKeyIdentifier); } $altName = []; if (isset($subject->domains) && count($subject->domains)) { $altName = array_map(['\phpseclib3\File\X509', 'dnsName'], $subject->domains); } if (isset($subject->ipAddresses) && count($subject->ipAddresses)) { // should an IP address appear as the CN if no domain name is specified? idk //$ips = count($subject->domains) ? $subject->ipAddresses : array_slice($subject->ipAddresses, 1); $ipAddresses = []; foreach ($subject->ipAddresses as $ipAddress) { $encoded = $subject->ipAddress($ipAddress); if ($encoded !== false) { $ipAddresses[] = $encoded; } } if (count($ipAddresses)) { $altName = array_merge($altName, $ipAddresses); } } if (!empty($altName)) { $this->setExtension('id-ce-subjectAltName', $altName); } if ($this->caFlag) { $keyUsage = $this->getExtension('id-ce-keyUsage'); if (!$keyUsage) { $keyUsage = []; } $this->setExtension( 'id-ce-keyUsage', array_values(array_unique(array_merge($keyUsage, ['cRLSign', 'keyCertSign']))) ); $basicConstraints = $this->getExtension('id-ce-basicConstraints'); if (!$basicConstraints) { $basicConstraints = []; } $this->setExtension( 'id-ce-basicConstraints', array_merge(['cA' => true], $basicConstraints), true ); if (!isset($subject->currentKeyIdentifier)) { $this->setExtension('id-ce-subjectKeyIdentifier', $this->computeKeyIdentifier($this->currentCert), false, false); } } // resync $this->signatureSubject // save $tbsCertificate in case there are any \phpseclib3\File\ASN1\Element objects in it $tbsCertificate = $this->currentCert['tbsCertificate']; $this->loadX509($this->saveX509($this->currentCert)); $result = $this->currentCert; $this->currentCert['signature'] = $result['signature'] = "\0" . $issuer->privateKey->sign($this->signatureSubject); $result['tbsCertificate'] = $tbsCertificate; $this->currentCert = $currentCert; $this->signatureSubject = $signatureSubject; return $result; } /** * Sign a CSR * * @return mixed */ public function signCSR() { if (!is_object($this->privateKey) || empty($this->dn)) { return false; } $origPublicKey = $this->publicKey; $this->publicKey = $this->privateKey->getPublicKey(); $publicKey = $this->formatSubjectPublicKey(); $this->publicKey = $origPublicKey; $currentCert = isset($this->currentCert) ? $this->currentCert : null; $signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject : null; $signatureAlgorithm = self::identifySignatureAlgorithm($this->privateKey); if (isset($this->currentCert) && is_array($this->currentCert) && isset($this->currentCert['certificationRequestInfo'])) { $this->currentCert['signatureAlgorithm'] = $signatureAlgorithm; if (!empty($this->dn)) { $this->currentCert['certificationRequestInfo']['subject'] = $this->dn; } $this->currentCert['certificationRequestInfo']['subjectPKInfo'] = $publicKey; } else { $this->currentCert = [ 'certificationRequestInfo' => [ 'version' => 'v1', 'subject' => $this->dn, 'subjectPKInfo' => $publicKey, 'attributes' => [] ], 'signatureAlgorithm' => $signatureAlgorithm, 'signature' => false // this is going to be overwritten later ]; } // resync $this->signatureSubject // save $certificationRequestInfo in case there are any \phpseclib3\File\ASN1\Element objects in it $certificationRequestInfo = $this->currentCert['certificationRequestInfo']; $this->loadCSR($this->saveCSR($this->currentCert)); $result = $this->currentCert; $this->currentCert['signature'] = $result['signature'] = "\0" . $this->privateKey->sign($this->signatureSubject); $result['certificationRequestInfo'] = $certificationRequestInfo; $this->currentCert = $currentCert; $this->signatureSubject = $signatureSubject; return $result; } /** * Sign a SPKAC * * @return mixed */ public function signSPKAC() { if (!is_object($this->privateKey)) { return false; } $origPublicKey = $this->publicKey; $this->publicKey = $this->privateKey->getPublicKey(); $publicKey = $this->formatSubjectPublicKey(); $this->publicKey = $origPublicKey; $currentCert = isset($this->currentCert) ? $this->currentCert : null; $signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject : null; $signatureAlgorithm = self::identifySignatureAlgorithm($this->privateKey); // re-signing a SPKAC seems silly but since everything else supports re-signing why not? if (isset($this->currentCert) && is_array($this->currentCert) && isset($this->currentCert['publicKeyAndChallenge'])) { $this->currentCert['signatureAlgorithm'] = $signatureAlgorithm; $this->currentCert['publicKeyAndChallenge']['spki'] = $publicKey; if (!empty($this->challenge)) { // the bitwise AND ensures that the output is a valid IA5String $this->currentCert['publicKeyAndChallenge']['challenge'] = $this->challenge & str_repeat("\x7F", strlen($this->challenge)); } } else { $this->currentCert = [ 'publicKeyAndChallenge' => [ 'spki' => $publicKey, // quoting , // "A challenge string that is submitted along with the public key. Defaults to an empty string if not specified." // both Firefox and OpenSSL ("openssl spkac -key private.key") behave this way // we could alternatively do this instead if we ignored the specs: // Random::string(8) & str_repeat("\x7F", 8) 'challenge' => !empty($this->challenge) ? $this->challenge : '' ], 'signatureAlgorithm' => $signatureAlgorithm, 'signature' => false // this is going to be overwritten later ]; } // resync $this->signatureSubject // save $publicKeyAndChallenge in case there are any \phpseclib3\File\ASN1\Element objects in it $publicKeyAndChallenge = $this->currentCert['publicKeyAndChallenge']; $this->loadSPKAC($this->saveSPKAC($this->currentCert)); $result = $this->currentCert; $this->currentCert['signature'] = $result['signature'] = "\0" . $this->privateKey->sign($this->signatureSubject); $result['publicKeyAndChallenge'] = $publicKeyAndChallenge; $this->currentCert = $currentCert; $this->signatureSubject = $signatureSubject; return $result; } /** * Sign a CRL * * $issuer's private key needs to be loaded. * * @return mixed */ public function signCRL(X509 $issuer, X509 $crl) { if (!is_object($issuer->privateKey) || empty($issuer->dn)) { return false; } $currentCert = isset($this->currentCert) ? $this->currentCert : null; $signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject : null; $signatureAlgorithm = self::identifySignatureAlgorithm($issuer->privateKey); $thisUpdate = new \DateTimeImmutable('now', new \DateTimeZone(@date_default_timezone_get())); $thisUpdate = !empty($this->startDate) ? $this->startDate : $thisUpdate->format('D, d M Y H:i:s O'); if (isset($crl->currentCert) && is_array($crl->currentCert) && isset($crl->currentCert['tbsCertList'])) { $this->currentCert = $crl->currentCert; $this->currentCert['tbsCertList']['signature'] = $signatureAlgorithm; $this->currentCert['signatureAlgorithm'] = $signatureAlgorithm; } else { $this->currentCert = [ 'tbsCertList' => [ 'version' => 'v2', 'signature' => $signatureAlgorithm, 'issuer' => false, // this is going to be overwritten later 'thisUpdate' => $this->timeField($thisUpdate) // $this->setStartDate() ], 'signatureAlgorithm' => $signatureAlgorithm, 'signature' => false // this is going to be overwritten later ]; } $tbsCertList = &$this->currentCert['tbsCertList']; $tbsCertList['issuer'] = $issuer->dn; $tbsCertList['thisUpdate'] = $this->timeField($thisUpdate); if (!empty($this->endDate)) { $tbsCertList['nextUpdate'] = $this->timeField($this->endDate); // $this->setEndDate() } else { unset($tbsCertList['nextUpdate']); } if (!empty($this->serialNumber)) { $crlNumber = $this->serialNumber; } else { $crlNumber = $this->getExtension('id-ce-cRLNumber'); // "The CRL number is a non-critical CRL extension that conveys a // monotonically increasing sequence number for a given CRL scope and // CRL issuer. This extension allows users to easily determine when a // particular CRL supersedes another CRL." // -- https://tools.ietf.org/html/rfc5280#section-5.2.3 $crlNumber = $crlNumber !== false ? $crlNumber->add(new BigInteger(1)) : null; } $this->removeExtension('id-ce-authorityKeyIdentifier'); $this->removeExtension('id-ce-issuerAltName'); // Be sure version >= v2 if some extension found. $version = isset($tbsCertList['version']) ? $tbsCertList['version'] : 0; if (!$version) { if (!empty($tbsCertList['crlExtensions'])) { $version = 'v2'; // v2. } elseif (!empty($tbsCertList['revokedCertificates'])) { foreach ($tbsCertList['revokedCertificates'] as $cert) { if (!empty($cert['crlEntryExtensions'])) { $version = 'v2'; // v2. } } } if ($version) { $tbsCertList['version'] = $version; } } // Store additional extensions. if (!empty($tbsCertList['version'])) { // At least v2. if (!empty($crlNumber)) { $this->setExtension('id-ce-cRLNumber', $crlNumber); } if (isset($issuer->currentKeyIdentifier)) { $this->setExtension('id-ce-authorityKeyIdentifier', [ //'authorityCertIssuer' => array( // ] // 'directoryName' => $issuer->dn // ] //), 'keyIdentifier' => $issuer->currentKeyIdentifier ]); //$extensions = &$tbsCertList['crlExtensions']; //if (isset($issuer->serialNumber)) { // $extensions[count($extensions) - 1]['authorityCertSerialNumber'] = $issuer->serialNumber; //} //unset($extensions); } $issuerAltName = $this->getExtension('id-ce-subjectAltName', $issuer->currentCert); if ($issuerAltName !== false) { $this->setExtension('id-ce-issuerAltName', $issuerAltName); } } if (empty($tbsCertList['revokedCertificates'])) { unset($tbsCertList['revokedCertificates']); } unset($tbsCertList); // resync $this->signatureSubject // save $tbsCertList in case there are any \phpseclib3\File\ASN1\Element objects in it $tbsCertList = $this->currentCert['tbsCertList']; $this->loadCRL($this->saveCRL($this->currentCert)); $result = $this->currentCert; $this->currentCert['signature'] = $result['signature'] = "\0" . $issuer->privateKey->sign($this->signatureSubject); $result['tbsCertList'] = $tbsCertList; $this->currentCert = $currentCert; $this->signatureSubject = $signatureSubject; return $result; } /** * Identify signature algorithm from key settings * * @param PrivateKey $key * @throws UnsupportedAlgorithmException if the algorithm is unsupported * @return array */ private static function identifySignatureAlgorithm(PrivateKey $key) { if ($key instanceof RSA) { if ($key->getPadding() & RSA::SIGNATURE_PSS) { $r = PSS::load($key->withPassword()->toString('PSS')); return [ 'algorithm' => 'id-RSASSA-PSS', 'parameters' => PSS::savePSSParams($r) ]; } switch ($key->getHash()) { case 'md2': case 'md5': case 'sha1': case 'sha224': case 'sha256': case 'sha384': case 'sha512': return [ 'algorithm' => $key->getHash() . 'WithRSAEncryption', 'parameters' => null ]; } throw new UnsupportedAlgorithmException('The only supported hash algorithms for RSA are: md2, md5, sha1, sha224, sha256, sha384, sha512'); } if ($key instanceof DSA) { switch ($key->getHash()) { case 'sha1': case 'sha224': case 'sha256': return ['algorithm' => 'id-dsa-with-' . $key->getHash()]; } throw new UnsupportedAlgorithmException('The only supported hash algorithms for DSA are: sha1, sha224, sha256'); } if ($key instanceof EC) { switch ($key->getCurve()) { case 'Ed25519': case 'Ed448': return ['algorithm' => 'id-' . $key->getCurve()]; } switch ($key->getHash()) { case 'sha1': case 'sha224': case 'sha256': case 'sha384': case 'sha512': return ['algorithm' => 'ecdsa-with-' . strtoupper($key->getHash())]; } throw new UnsupportedAlgorithmException('The only supported hash algorithms for EC are: sha1, sha224, sha256, sha384, sha512'); } throw new UnsupportedAlgorithmException('The only supported public key classes are: RSA, DSA, EC'); } /** * Set certificate start date * * @param \DateTimeInterface|string $date */ public function setStartDate($date) { if (!is_object($date) || !($date instanceof \DateTimeInterface)) { $date = new \DateTimeImmutable($date, new \DateTimeZone(@date_default_timezone_get())); } $this->startDate = $date->format('D, d M Y H:i:s O'); } /** * Set certificate end date * * @param \DateTimeInterface|string $date */ public function setEndDate($date) { /* To indicate that a certificate has no well-defined expiration date, the notAfter SHOULD be assigned the GeneralizedTime value of 99991231235959Z. -- http://tools.ietf.org/html/rfc5280#section-4.1.2.5 */ if (is_string($date) && strtolower($date) === 'lifetime') { $temp = '99991231235959Z'; $temp = chr(ASN1::TYPE_GENERALIZED_TIME) . ASN1::encodeLength(strlen($temp)) . $temp; $this->endDate = new Element($temp); } else { if (!is_object($date) || !($date instanceof \DateTimeInterface)) { $date = new \DateTimeImmutable($date, new \DateTimeZone(@date_default_timezone_get())); } $this->endDate = $date->format('D, d M Y H:i:s O'); } } /** * Set Serial Number * * @param string $serial * @param int $base optional */ public function setSerialNumber($serial, $base = -256) { $this->serialNumber = new BigInteger($serial, $base); } /** * Turns the certificate into a certificate authority * */ public function makeCA() { $this->caFlag = true; } /** * Check for validity of subarray * * This is intended for use in conjunction with _subArrayUnchecked(), * implementing the checks included in _subArray() but without copying * a potentially large array by passing its reference by-value to is_array(). * * @param array $root * @param string $path * @return boolean */ private function isSubArrayValid(array $root, $path) { if (!is_array($root)) { return false; } foreach (explode('/', $path) as $i) { if (!is_array($root)) { return false; } if (!isset($root[$i])) { return true; } $root = $root[$i]; } return true; } /** * Get a reference to a subarray * * This variant of _subArray() does no is_array() checking, * so $root should be checked with _isSubArrayValid() first. * * This is here for performance reasons: * Passing a reference (i.e. $root) by-value (i.e. to is_array()) * creates a copy. If $root is an especially large array, this is expensive. * * @param array $root * @param string $path absolute path with / as component separator * @param bool $create optional * @return array|false */ private function &subArrayUnchecked(array &$root, $path, $create = false) { $false = false; foreach (explode('/', $path) as $i) { if (!isset($root[$i])) { if (!$create) { return $false; } $root[$i] = []; } $root = &$root[$i]; } return $root; } /** * Get a reference to a subarray * * @param array $root * @param string $path absolute path with / as component separator * @param bool $create optional * @return array|false */ private function &subArray(&$root, $path, $create = false) { $false = false; if (!is_array($root)) { return $false; } foreach (explode('/', $path) as $i) { if (!is_array($root)) { return $false; } if (!isset($root[$i])) { if (!$create) { return $false; } $root[$i] = []; } $root = &$root[$i]; } return $root; } /** * Get a reference to an extension subarray * * @param array $root * @param string $path optional absolute path with / as component separator * @param bool $create optional * @return array|false */ private function &extensions(&$root, $path = null, $create = false) { if (!isset($root)) { $root = $this->currentCert; } switch (true) { case !empty($path): case !is_array($root): break; case isset($root['tbsCertificate']): $path = 'tbsCertificate/extensions'; break; case isset($root['tbsCertList']): $path = 'tbsCertList/crlExtensions'; break; case isset($root['certificationRequestInfo']): $pth = 'certificationRequestInfo/attributes'; $attributes = &$this->subArray($root, $pth, $create); if (is_array($attributes)) { foreach ($attributes as $key => $value) { if ($value['type'] == 'pkcs-9-at-extensionRequest') { $path = "$pth/$key/value/0"; break 2; } } if ($create) { $key = count($attributes); $attributes[] = ['type' => 'pkcs-9-at-extensionRequest', 'value' => []]; $path = "$pth/$key/value/0"; } } break; } $extensions = &$this->subArray($root, $path, $create); if (!is_array($extensions)) { $false = false; return $false; } return $extensions; } /** * Remove an Extension * * @param string $id * @param string $path optional * @return bool */ private function removeExtensionHelper($id, $path = null) { $extensions = &$this->extensions($this->currentCert, $path); if (!is_array($extensions)) { return false; } $result = false; foreach ($extensions as $key => $value) { if ($value['extnId'] == $id) { unset($extensions[$key]); $result = true; } } $extensions = array_values($extensions); // fix for https://bugs.php.net/75433 affecting PHP 7.2 if (!isset($extensions[0])) { $extensions = array_splice($extensions, 0, 0); } return $result; } /** * Get an Extension * * Returns the extension if it exists and false if not * * @param string $id * @param array $cert optional * @param string $path optional * @return mixed */ private function getExtensionHelper($id, $cert = null, $path = null) { $extensions = $this->extensions($cert, $path); if (!is_array($extensions)) { return false; } foreach ($extensions as $key => $value) { if ($value['extnId'] == $id) { return $value['extnValue']; } } return false; } /** * Returns a list of all extensions in use * * @param array $cert optional * @param string $path optional * @return array */ private function getExtensionsHelper($cert = null, $path = null) { $exts = $this->extensions($cert, $path); $extensions = []; if (is_array($exts)) { foreach ($exts as $extension) { $extensions[] = $extension['extnId']; } } return $extensions; } /** * Set an Extension * * @param string $id * @param mixed $value * @param bool $critical optional * @param bool $replace optional * @param string $path optional * @return bool */ private function setExtensionHelper($id, $value, $critical = false, $replace = true, $path = null) { $extensions = &$this->extensions($this->currentCert, $path, true); if (!is_array($extensions)) { return false; } $newext = ['extnId' => $id, 'critical' => $critical, 'extnValue' => $value]; foreach ($extensions as $key => $value) { if ($value['extnId'] == $id) { if (!$replace) { return false; } $extensions[$key] = $newext; return true; } } $extensions[] = $newext; return true; } /** * Remove a certificate, CSR or CRL Extension * * @param string $id * @return bool */ public function removeExtension($id) { return $this->removeExtensionHelper($id); } /** * Get a certificate, CSR or CRL Extension * * Returns the extension if it exists and false if not * * @param string $id * @param array $cert optional * @param string $path * @return mixed */ public function getExtension($id, $cert = null, $path = null) { return $this->getExtensionHelper($id, $cert, $path); } /** * Returns a list of all extensions in use in certificate, CSR or CRL * * @param array $cert optional * @param string $path optional * @return array */ public function getExtensions($cert = null, $path = null) { return $this->getExtensionsHelper($cert, $path); } /** * Set a certificate, CSR or CRL Extension * * @param string $id * @param mixed $value * @param bool $critical optional * @param bool $replace optional * @return bool */ public function setExtension($id, $value, $critical = false, $replace = true) { return $this->setExtensionHelper($id, $value, $critical, $replace); } /** * Remove a CSR attribute. * * @param string $id * @param int $disposition optional * @return bool */ public function removeAttribute($id, $disposition = self::ATTR_ALL) { $attributes = &$this->subArray($this->currentCert, 'certificationRequestInfo/attributes'); if (!is_array($attributes)) { return false; } $result = false; foreach ($attributes as $key => $attribute) { if ($attribute['type'] == $id) { $n = count($attribute['value']); switch (true) { case $disposition == self::ATTR_APPEND: case $disposition == self::ATTR_REPLACE: return false; case $disposition >= $n: $disposition -= $n; break; case $disposition == self::ATTR_ALL: case $n == 1: unset($attributes[$key]); $result = true; break; default: unset($attributes[$key]['value'][$disposition]); $attributes[$key]['value'] = array_values($attributes[$key]['value']); $result = true; break; } if ($result && $disposition != self::ATTR_ALL) { break; } } } $attributes = array_values($attributes); return $result; } /** * Get a CSR attribute * * Returns the attribute if it exists and false if not * * @param string $id * @param int $disposition optional * @param array $csr optional * @return mixed */ public function getAttribute($id, $disposition = self::ATTR_ALL, $csr = null) { if (empty($csr)) { $csr = $this->currentCert; } $attributes = $this->subArray($csr, 'certificationRequestInfo/attributes'); if (!is_array($attributes)) { return false; } foreach ($attributes as $key => $attribute) { if ($attribute['type'] == $id) { $n = count($attribute['value']); switch (true) { case $disposition == self::ATTR_APPEND: case $disposition == self::ATTR_REPLACE: return false; case $disposition == self::ATTR_ALL: return $attribute['value']; case $disposition >= $n: $disposition -= $n; break; default: return $attribute['value'][$disposition]; } } } return false; } /** * Get all requested CSR extensions * * Returns the list of extensions if there are any and false if not * * @param array $csr optional * @return mixed */ public function getRequestedCertificateExtensions($csr = null) { if (empty($csr)) { $csr = $this->currentCert; } $requestedExtensions = $this->getAttribute('pkcs-9-at-extensionRequest'); if ($requestedExtensions === false) { return false; } return $this->getAttribute('pkcs-9-at-extensionRequest')[0]; } /** * Returns a list of all CSR attributes in use * * @param array $csr optional * @return array */ public function getAttributes($csr = null) { if (empty($csr)) { $csr = $this->currentCert; } $attributes = $this->subArray($csr, 'certificationRequestInfo/attributes'); $attrs = []; if (is_array($attributes)) { foreach ($attributes as $attribute) { $attrs[] = $attribute['type']; } } return $attrs; } /** * Set a CSR attribute * * @param string $id * @param mixed $value * @param int $disposition optional * @return bool */ public function setAttribute($id, $value, $disposition = self::ATTR_ALL) { $attributes = &$this->subArray($this->currentCert, 'certificationRequestInfo/attributes', true); if (!is_array($attributes)) { return false; } switch ($disposition) { case self::ATTR_REPLACE: $disposition = self::ATTR_APPEND; // fall-through case self::ATTR_ALL: $this->removeAttribute($id); break; } foreach ($attributes as $key => $attribute) { if ($attribute['type'] == $id) { $n = count($attribute['value']); switch (true) { case $disposition == self::ATTR_APPEND: $last = $key; break; case $disposition >= $n: $disposition -= $n; break; default: $attributes[$key]['value'][$disposition] = $value; return true; } } } switch (true) { case $disposition >= 0: return false; case isset($last): $attributes[$last]['value'][] = $value; break; default: $attributes[] = ['type' => $id, 'value' => $disposition == self::ATTR_ALL ? $value : [$value]]; break; } return true; } /** * Sets the subject key identifier * * This is used by the id-ce-authorityKeyIdentifier and the id-ce-subjectKeyIdentifier extensions. * * @param string $value */ public function setKeyIdentifier($value) { if (empty($value)) { unset($this->currentKeyIdentifier); } else { $this->currentKeyIdentifier = $value; } } /** * Compute a public key identifier. * * Although key identifiers may be set to any unique value, this function * computes key identifiers from public key according to the two * recommended methods (4.2.1.2 RFC 3280). * Highly polymorphic: try to accept all possible forms of key: * - Key object * - \phpseclib3\File\X509 object with public or private key defined * - Certificate or CSR array * - \phpseclib3\File\ASN1\Element object * - PEM or DER string * * @param mixed $key optional * @param int $method optional * @return string binary key identifier */ public function computeKeyIdentifier($key = null, $method = 1) { if (is_null($key)) { $key = $this; } switch (true) { case is_string($key): break; case is_array($key) && isset($key['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey']): return $this->computeKeyIdentifier($key['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'], $method); case is_array($key) && isset($key['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey']): return $this->computeKeyIdentifier($key['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'], $method); case !is_object($key): return false; case $key instanceof Element: // Assume the element is a bitstring-packed key. $decoded = ASN1::decodeBER($key->element); if (!$decoded) { return false; } $raw = ASN1::asn1map($decoded[0], ['type' => ASN1::TYPE_BIT_STRING]); if (empty($raw)) { return false; } // If the key is private, compute identifier from its corresponding public key. $key = PublicKeyLoader::load($raw); if ($key instanceof PrivateKey) { // If private. return $this->computeKeyIdentifier($key, $method); } $key = $raw; // Is a public key. break; case $key instanceof X509: if (isset($key->publicKey)) { return $this->computeKeyIdentifier($key->publicKey, $method); } if (isset($key->privateKey)) { return $this->computeKeyIdentifier($key->privateKey, $method); } if (isset($key->currentCert['tbsCertificate']) || isset($key->currentCert['certificationRequestInfo'])) { return $this->computeKeyIdentifier($key->currentCert, $method); } return false; default: // Should be a key object (i.e.: \phpseclib3\Crypt\RSA). $key = $key->getPublicKey(); break; } // If in PEM format, convert to binary. $key = ASN1::extractBER($key); // Now we have the key string: compute its sha-1 sum. $hash = new Hash('sha1'); $hash = $hash->hash($key); if ($method == 2) { $hash = substr($hash, -8); $hash[0] = chr((ord($hash[0]) & 0x0F) | 0x40); } return $hash; } /** * Format a public key as appropriate * * @return array|false */ private function formatSubjectPublicKey() { $format = $this->publicKey instanceof RSA && ($this->publicKey->getPadding() & RSA::SIGNATURE_PSS) ? 'PSS' : 'PKCS8'; $publicKey = base64_decode(preg_replace('#-.+-|[\r\n]#', '', $this->publicKey->toString($format))); $decoded = ASN1::decodeBER($publicKey); if (!$decoded) { return false; } $mapped = ASN1::asn1map($decoded[0], Maps\SubjectPublicKeyInfo::MAP); if (!is_array($mapped)) { return false; } $mapped['subjectPublicKey'] = $this->publicKey->toString($format); return $mapped; } /** * Set the domain name's which the cert is to be valid for * * @param mixed ...$domains * @return void */ public function setDomain(...$domains) { $this->domains = $domains; $this->removeDNProp('id-at-commonName'); $this->setDNProp('id-at-commonName', $this->domains[0]); } /** * Set the IP Addresses's which the cert is to be valid for * * @param mixed[] ...$ipAddresses */ public function setIPAddress(...$ipAddresses) { $this->ipAddresses = $ipAddresses; /* if (!isset($this->domains)) { $this->removeDNProp('id-at-commonName'); $this->setDNProp('id-at-commonName', $this->ipAddresses[0]); } */ } /** * Helper function to build domain array * * @param string $domain * @return array */ private static function dnsName($domain) { return ['dNSName' => $domain]; } /** * Helper function to build IP Address array * * (IPv6 is not currently supported) * * @param string $address * @return array */ private function iPAddress($address) { return ['iPAddress' => $address]; } /** * Get the index of a revoked certificate. * * @param array $rclist * @param string $serial * @param bool $create optional * @return int|false */ private function revokedCertificate(array &$rclist, $serial, $create = false) { $serial = new BigInteger($serial); foreach ($rclist as $i => $rc) { if (!($serial->compare($rc['userCertificate']))) { return $i; } } if (!$create) { return false; } $i = count($rclist); $revocationDate = new \DateTimeImmutable('now', new \DateTimeZone(@date_default_timezone_get())); $rclist[] = ['userCertificate' => $serial, 'revocationDate' => $this->timeField($revocationDate->format('D, d M Y H:i:s O'))]; return $i; } /** * Revoke a certificate. * * @param string $serial * @param string $date optional * @return bool */ public function revoke($serial, $date = null) { if (isset($this->currentCert['tbsCertList'])) { if (is_array($rclist = &$this->subArray($this->currentCert, 'tbsCertList/revokedCertificates', true))) { if ($this->revokedCertificate($rclist, $serial) === false) { // If not yet revoked if (($i = $this->revokedCertificate($rclist, $serial, true)) !== false) { if (!empty($date)) { $rclist[$i]['revocationDate'] = $this->timeField($date); } return true; } } } } return false; } /** * Unrevoke a certificate. * * @param string $serial * @return bool */ public function unrevoke($serial) { if (is_array($rclist = &$this->subArray($this->currentCert, 'tbsCertList/revokedCertificates'))) { if (($i = $this->revokedCertificate($rclist, $serial)) !== false) { unset($rclist[$i]); $rclist = array_values($rclist); return true; } } return false; } /** * Get a revoked certificate. * * @param string $serial * @return mixed */ public function getRevoked($serial) { if (is_array($rclist = $this->subArray($this->currentCert, 'tbsCertList/revokedCertificates'))) { if (($i = $this->revokedCertificate($rclist, $serial)) !== false) { return $rclist[$i]; } } return false; } /** * List revoked certificates * * @param array $crl optional * @return array|bool */ public function listRevoked($crl = null) { if (!isset($crl)) { $crl = $this->currentCert; } if (!isset($crl['tbsCertList'])) { return false; } $result = []; if (is_array($rclist = $this->subArray($crl, 'tbsCertList/revokedCertificates'))) { foreach ($rclist as $rc) { $result[] = $rc['userCertificate']->toString(); } } return $result; } /** * Remove a Revoked Certificate Extension * * @param string $serial * @param string $id * @return bool */ public function removeRevokedCertificateExtension($serial, $id) { if (is_array($rclist = &$this->subArray($this->currentCert, 'tbsCertList/revokedCertificates'))) { if (($i = $this->revokedCertificate($rclist, $serial)) !== false) { return $this->removeExtensionHelper($id, "tbsCertList/revokedCertificates/$i/crlEntryExtensions"); } } return false; } /** * Get a Revoked Certificate Extension * * Returns the extension if it exists and false if not * * @param string $serial * @param string $id * @param array $crl optional * @return mixed */ public function getRevokedCertificateExtension($serial, $id, $crl = null) { if (!isset($crl)) { $crl = $this->currentCert; } if (is_array($rclist = $this->subArray($crl, 'tbsCertList/revokedCertificates'))) { if (($i = $this->revokedCertificate($rclist, $serial)) !== false) { return $this->getExtension($id, $crl, "tbsCertList/revokedCertificates/$i/crlEntryExtensions"); } } return false; } /** * Returns a list of all extensions in use for a given revoked certificate * * @param string $serial * @param array $crl optional * @return array|bool */ public function getRevokedCertificateExtensions($serial, $crl = null) { if (!isset($crl)) { $crl = $this->currentCert; } if (is_array($rclist = $this->subArray($crl, 'tbsCertList/revokedCertificates'))) { if (($i = $this->revokedCertificate($rclist, $serial)) !== false) { return $this->getExtensions($crl, "tbsCertList/revokedCertificates/$i/crlEntryExtensions"); } } return false; } /** * Set a Revoked Certificate Extension * * @param string $serial * @param string $id * @param mixed $value * @param bool $critical optional * @param bool $replace optional * @return bool */ public function setRevokedCertificateExtension($serial, $id, $value, $critical = false, $replace = true) { if (isset($this->currentCert['tbsCertList'])) { if (is_array($rclist = &$this->subArray($this->currentCert, 'tbsCertList/revokedCertificates', true))) { if (($i = $this->revokedCertificate($rclist, $serial, true)) !== false) { return $this->setExtensionHelper($id, $value, $critical, $replace, "tbsCertList/revokedCertificates/$i/crlEntryExtensions"); } } } return false; } /** * Register the mapping for a custom/unsupported extension. * * @param string $id * @param array $mapping */ public static function registerExtension($id, array $mapping) { if (isset(self::$extensions[$id]) && self::$extensions[$id] !== $mapping) { throw new \RuntimeException( 'Extension ' . $id . ' has already been defined with a different mapping.' ); } self::$extensions[$id] = $mapping; } /** * Register the mapping for a custom/unsupported extension. * * @param string $id * * @return array|null */ public static function getRegisteredExtension($id) { return isset(self::$extensions[$id]) ? self::$extensions[$id] : null; } /** * Register the mapping for a custom/unsupported extension. * * @param string $id * @param mixed $value * @param bool $critical * @param bool $replace */ public function setExtensionValue($id, $value, $critical = false, $replace = false) { $this->extensionValues[$id] = compact('critical', 'replace', 'value'); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Base.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Math\BigInteger\Engines\BCMath; use phpseclib3\Math\BigInteger\Engines\BCMath; /** * Sliding Window Exponentiation Engine * * @author Jim Wigginton */ abstract class Base extends BCMath { /** * Cache constants * * $cache[self::VARIABLE] tells us whether or not the cached data is still valid. * */ const VARIABLE = 0; /** * $cache[self::DATA] contains the cached data. * */ const DATA = 1; /** * Test for engine validity * * @return bool */ public static function isValidEngine() { return static::class != __CLASS__; } /** * Performs modular exponentiation. * * @param BCMath $x * @param BCMath $e * @param BCMath $n * @param string $class * @return BCMath */ protected static function powModHelper(BCMath $x, BCMath $e, BCMath $n, $class) { if (empty($e->value)) { $temp = new $class(); $temp->value = '1'; return $x->normalize($temp); } return $x->normalize(static::slidingWindow($x, $e, $n, $class)); } /** * Modular reduction preparation * * @param string $x * @param string $n * @param string $class * @see self::slidingWindow() * @return string */ protected static function prepareReduce($x, $n, $class) { return static::reduce($x, $n); } /** * Modular multiply * * @param string $x * @param string $y * @param string $n * @param string $class * @see self::slidingWindow() * @return string */ protected static function multiplyReduce($x, $y, $n, $class) { return static::reduce(bcmul($x, $y, 0), $n); } /** * Modular square * * @param string $x * @param string $n * @param string $class * @see self::slidingWindow() * @return string */ protected static function squareReduce($x, $n, $class) { return static::reduce(bcmul($x, $x, 0), $n); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/BuiltIn.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Math\BigInteger\Engines\BCMath; use phpseclib3\Math\BigInteger\Engines\BCMath; /** * Built-In BCMath Modular Exponentiation Engine * * @author Jim Wigginton */ abstract class BuiltIn extends BCMath { /** * Performs modular exponentiation. * * @param BCMath $x * @param BCMath $e * @param BCMath $n * @return BCMath */ protected static function powModHelper(BCMath $x, BCMath $e, BCMath $n) { $temp = new BCMath(); $temp->value = bcpowmod($x->value, $e->value, $n->value, 0); return $x->normalize($temp); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/DefaultEngine.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Math\BigInteger\Engines\BCMath; use phpseclib3\Math\BigInteger\Engines\BCMath\Reductions\Barrett; /** * PHP Default Modular Exponentiation Engine * * @author Jim Wigginton */ abstract class DefaultEngine extends Barrett { } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/OpenSSL.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Math\BigInteger\Engines\BCMath; use phpseclib3\Math\BigInteger\Engines\OpenSSL as Progenitor; /** * OpenSSL Modular Exponentiation Engine * * @author Jim Wigginton */ abstract class OpenSSL extends Progenitor { } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/Barrett.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Math\BigInteger\Engines\BCMath\Reductions; use phpseclib3\Math\BigInteger\Engines\BCMath\Base; /** * PHP Barrett Modular Exponentiation Engine * * @author Jim Wigginton */ abstract class Barrett extends Base { /** * Cache constants * * $cache[self::VARIABLE] tells us whether or not the cached data is still valid. * */ const VARIABLE = 0; /** * $cache[self::DATA] contains the cached data. * */ const DATA = 1; /** * Barrett Modular Reduction * * See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=14 HAC 14.3.3} / * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=165 MPM 6.2.5} for more information. Modified slightly, * so as not to require negative numbers (initially, this script didn't support negative numbers). * * Employs "folding", as described at * {@link http://www.cosic.esat.kuleuven.be/publications/thesis-149.pdf#page=66 thesis-149.pdf#page=66}. To quote from * it, "the idea [behind folding] is to find a value x' such that x (mod m) = x' (mod m), with x' being smaller than x." * * Unfortunately, the "Barrett Reduction with Folding" algorithm described in thesis-149.pdf is not, as written, all that * usable on account of (1) its not using reasonable radix points as discussed in * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=162 MPM 6.2.2} and (2) the fact that, even with reasonable * radix points, it only works when there are an even number of digits in the denominator. The reason for (2) is that * (x >> 1) + (x >> 1) != x / 2 + x / 2. If x is even, they're the same, but if x is odd, they're not. See the in-line * comments for details. * * @param string $n * @param string $m * @return string */ protected static function reduce($n, $m) { static $cache = [ self::VARIABLE => [], self::DATA => [] ]; $m_length = strlen($m); if (strlen($n) > 2 * $m_length) { return self::BCMOD_THREE_PARAMS ? bcmod($n, $m, 0) : bcmod($n, $m); } // if (m.length >> 1) + 2 <= m.length then m is too small and n can't be reduced if ($m_length < 5) { return self::regularBarrett($n, $m); } // n = 2 * m.length $correctionNeeded = false; if ($m_length & 1) { $correctionNeeded = true; $n .= '0'; $m .= '0'; $m_length++; } if (($key = array_search($m, $cache[self::VARIABLE])) === false) { $key = count($cache[self::VARIABLE]); $cache[self::VARIABLE][] = $m; $lhs = '1' . str_repeat('0', $m_length + ($m_length >> 1)); $u = bcdiv($lhs, $m, 0); $m1 = bcsub($lhs, bcmul($u, $m, 0), 0); $cache[self::DATA][] = [ 'u' => $u, // m.length >> 1 (technically (m.length >> 1) + 1) 'm1' => $m1 // m.length ]; } else { $cacheValues = $cache[self::DATA][$key]; $u = $cacheValues['u']; $m1 = $cacheValues['m1']; } $cutoff = $m_length + ($m_length >> 1); $lsd = substr($n, -$cutoff); $msd = substr($n, 0, -$cutoff); $temp = bcmul($msd, $m1, 0); // m.length + (m.length >> 1) $n = bcadd($lsd, $temp, 0); // m.length + (m.length >> 1) + 1 (so basically we're adding two same length numbers) //if ($m_length & 1) { // return self::regularBarrett($n, $m); //} // (m.length + (m.length >> 1) + 1) - (m.length - 1) == (m.length >> 1) + 2 $temp = substr($n, 0, -$m_length + 1); // if even: ((m.length >> 1) + 2) + (m.length >> 1) == m.length + 2 // if odd: ((m.length >> 1) + 2) + (m.length >> 1) == (m.length - 1) + 2 == m.length + 1 $temp = bcmul($temp, $u, 0); // if even: (m.length + 2) - ((m.length >> 1) + 1) = m.length - (m.length >> 1) + 1 // if odd: (m.length + 1) - ((m.length >> 1) + 1) = m.length - (m.length >> 1) $temp = substr($temp, 0, -($m_length >> 1) - 1); // if even: (m.length - (m.length >> 1) + 1) + m.length = 2 * m.length - (m.length >> 1) + 1 // if odd: (m.length - (m.length >> 1)) + m.length = 2 * m.length - (m.length >> 1) $temp = bcmul($temp, $m, 0); // at this point, if m had an odd number of digits, we'd be subtracting a 2 * m.length - (m.length >> 1) digit // number from a m.length + (m.length >> 1) + 1 digit number. ie. there'd be an extra digit and the while loop // following this comment would loop a lot (hence our calling _regularBarrett() in that situation). $result = bcsub($n, $temp, 0); //if (bccomp($result, '0') < 0) { if ($result[0] == '-') { $temp = '1' . str_repeat('0', $m_length + 1); $result = bcadd($result, $temp, 0); } while (bccomp($result, $m, 0) >= 0) { $result = bcsub($result, $m, 0); } return $correctionNeeded && $result != '0' ? substr($result, 0, -1) : $result; } /** * (Regular) Barrett Modular Reduction * * For numbers with more than four digits BigInteger::_barrett() is faster. The difference between that and this * is that this function does not fold the denominator into a smaller form. * * @param string $x * @param string $n * @return string */ private static function regularBarrett($x, $n) { static $cache = [ self::VARIABLE => [], self::DATA => [] ]; $n_length = strlen($n); if (strlen($x) > 2 * $n_length) { return self::BCMOD_THREE_PARAMS ? bcmod($x, $n, 0) : bcmod($x, $n); } if (($key = array_search($n, $cache[self::VARIABLE])) === false) { $key = count($cache[self::VARIABLE]); $cache[self::VARIABLE][] = $n; $lhs = '1' . str_repeat('0', 2 * $n_length); $cache[self::DATA][] = bcdiv($lhs, $n, 0); } $temp = substr($x, 0, -$n_length + 1); $temp = bcmul($temp, $cache[self::DATA][$key], 0); $temp = substr($temp, 0, -$n_length - 1); $r1 = substr($x, -$n_length - 1); $r2 = substr(bcmul($temp, $n, 0), -$n_length - 1); $result = bcsub($r1, $r2); //if (bccomp($result, '0') < 0) { if ($result[0] == '-') { $q = '1' . str_repeat('0', $n_length + 1); $result = bcadd($result, $q, 0); } while (bccomp($result, $n, 0) >= 0) { $result = bcsub($result, $n, 0); } return $result; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/EvalBarrett.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Math\BigInteger\Engines\BCMath\Reductions; use phpseclib3\Math\BigInteger\Engines\BCMath; use phpseclib3\Math\BigInteger\Engines\BCMath\Base; /** * PHP Barrett Modular Exponentiation Engine * * @author Jim Wigginton */ abstract class EvalBarrett extends Base { /** * Custom Reduction Function * * @see self::generateCustomReduction */ private static $custom_reduction; /** * Barrett Modular Reduction * * This calls a dynamically generated loop unrolled function that's specific to a given modulo. * Array lookups are avoided as are if statements testing for how many bits the host OS supports, etc. * * @param string $n * @param string $m * @return string */ protected static function reduce($n, $m) { $inline = self::$custom_reduction; return $inline($n); } /** * Generate Custom Reduction * * @param BCMath $m * @param string $class * @return callable|void */ protected static function generateCustomReduction(BCMath $m, $class) { $m_length = strlen($m); if ($m_length < 5) { $code = 'return self::BCMOD_THREE_PARAMS ? bcmod($x, $n, 0) : bcmod($x, $n);'; eval('$func = function ($n) { ' . $code . '};'); self::$custom_reduction = $func; return; } $lhs = '1' . str_repeat('0', $m_length + ($m_length >> 1)); $u = bcdiv($lhs, $m, 0); $m1 = bcsub($lhs, bcmul($u, $m, 0), 0); $cutoff = $m_length + ($m_length >> 1); $m = "'$m'"; $u = "'$u'"; $m1 = "'$m1'"; $code = ' $lsd = substr($n, -' . $cutoff . '); $msd = substr($n, 0, -' . $cutoff . '); $temp = bcmul($msd, ' . $m1 . ', 0); $n = bcadd($lsd, $temp, 0); $temp = substr($n, 0, ' . (-$m_length + 1) . '); $temp = bcmul($temp, ' . $u . ', 0); $temp = substr($temp, 0, ' . (-($m_length >> 1) - 1) . '); $temp = bcmul($temp, ' . $m . ', 0); $result = bcsub($n, $temp, 0); if ($result[0] == \'-\') { $temp = \'1' . str_repeat('0', $m_length + 1) . '\'; $result = bcadd($result, $temp, 0); } while (bccomp($result, ' . $m . ') >= 0) { $result = bcsub($result, ' . $m . ', 0); } return $result;'; eval('$func = function ($n) { ' . $code . '};'); self::$custom_reduction = $func; return $func; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Math\BigInteger\Engines; use phpseclib3\Common\Functions\Strings; use phpseclib3\Exception\BadConfigurationException; /** * BCMath Engine. * * @author Jim Wigginton */ class BCMath extends Engine { /** * Can Bitwise operations be done fast? * * @see parent::bitwise_leftRotate() * @see parent::bitwise_rightRotate() */ const FAST_BITWISE = false; /** * Engine Directory * * @see parent::setModExpEngine */ const ENGINE_DIR = 'BCMath'; /** * Test to see if bcmod() accepts 2 or 3 parameters */ const BCMOD_THREE_PARAMS = PHP_VERSION_ID >= 72000; /** * Test for engine validity * * @return bool * @see parent::__construct() */ public static function isValidEngine() { return extension_loaded('bcmath'); } /** * Default constructor * * @param mixed $x integer Base-10 number or base-$base number if $base set. * @param int $base * @see parent::__construct() */ public function __construct($x = 0, $base = 10) { if (!isset(static::$isValidEngine[static::class])) { static::$isValidEngine[static::class] = self::isValidEngine(); } if (!static::$isValidEngine[static::class]) { throw new BadConfigurationException('BCMath is not setup correctly on this system'); } $this->value = '0'; parent::__construct($x, $base); } /** * Initialize a BCMath BigInteger Engine instance * * @param int $base * @see parent::__construct() */ protected function initialize($base) { switch (abs($base)) { case 256: // round $len to the nearest 4 $len = (strlen($this->value) + 3) & ~3; $x = str_pad($this->value, $len, chr(0), STR_PAD_LEFT); $this->value = '0'; for ($i = 0; $i < $len; $i += 4) { $this->value = bcmul($this->value, '4294967296', 0); // 4294967296 == 2**32 $this->value = bcadd( $this->value, 0x1000000 * ord($x[$i]) + ((ord($x[$i + 1]) << 16) | (ord( $x[$i + 2] ) << 8) | ord($x[$i + 3])), 0 ); } if ($this->is_negative) { $this->value = '-' . $this->value; } break; case 16: $x = (strlen($this->value) & 1) ? '0' . $this->value : $this->value; $temp = new self(Strings::hex2bin($x), 256); $this->value = $this->is_negative ? '-' . $temp->value : $temp->value; $this->is_negative = false; break; case 10: // explicitly casting $x to a string is necessary, here, since doing $x[0] on -1 yields different // results then doing it on '-1' does (modInverse does $x[0]) $this->value = $this->value === '-' ? '0' : (string)$this->value; } } /** * Converts a BigInteger to a base-10 number. * * @return string */ public function toString() { if ($this->value === '0') { return '0'; } return ltrim($this->value, '0'); } /** * Converts a BigInteger to a byte string (eg. base-256). * * @param bool $twos_compliment * @return string */ public function toBytes($twos_compliment = false) { if ($twos_compliment) { return $this->toBytesHelper(); } $value = ''; $current = $this->value; if ($current[0] == '-') { $current = substr($current, 1); } while (bccomp($current, '0', 0) > 0) { $temp = self::BCMOD_THREE_PARAMS ? bcmod($current, '16777216', 0) : bcmod($current, '16777216'); $value = chr($temp >> 16) . chr(($temp >> 8) & 0xFF) . chr($temp & 0xFF) . $value; $current = bcdiv($current, '16777216', 0); } return $this->precision > 0 ? substr(str_pad($value, $this->precision >> 3, chr(0), STR_PAD_LEFT), -($this->precision >> 3)) : ltrim($value, chr(0)); } /** * Adds two BigIntegers. * * @param BCMath $y * @return BCMath */ public function add(BCMath $y) { $temp = new self(); $temp->value = bcadd($this->value, $y->value, 0); return $this->normalize($temp); } /** * Subtracts two BigIntegers. * * @param BCMath $y * @return BCMath */ public function subtract(BCMath $y) { $temp = new self(); $temp->value = bcsub($this->value, $y->value, 0); return $this->normalize($temp); } /** * Multiplies two BigIntegers. * * @param BCMath $x * @return BCMath */ public function multiply(BCMath $x) { $temp = new self(); $temp->value = bcmul($this->value, $x->value, 0); return $this->normalize($temp); } /** * Divides two BigIntegers. * * Returns an array whose first element contains the quotient and whose second element contains the * "common residue". If the remainder would be positive, the "common residue" and the remainder are the * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder * and the divisor (basically, the "common residue" is the first positive modulo). * * @param BCMath $y * @return array{static, static} */ public function divide(BCMath $y) { $quotient = new self(); $remainder = new self(); $quotient->value = bcdiv($this->value, $y->value, 0); $remainder->value = self::BCMOD_THREE_PARAMS ? bcmod($this->value, $y->value, 0) : bcmod($this->value, $y->value); if ($remainder->value[0] == '-') { $remainder->value = bcadd($remainder->value, $y->value[0] == '-' ? substr($y->value, 1) : $y->value, 0); } return [$this->normalize($quotient), $this->normalize($remainder)]; } /** * Calculates modular inverses. * * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. * * @param BCMath $n * @return false|BCMath */ public function modInverse(BCMath $n) { return $this->modInverseHelper($n); } /** * Calculates the greatest common divisor and Bezout's identity. * * Say you have 693 and 609. The GCD is 21. Bezout's identity states that there exist integers x and y such that * 693*x + 609*y == 21. In point of fact, there are actually an infinite number of x and y combinations and which * combination is returned is dependent upon which mode is in use. See * {@link http://en.wikipedia.org/wiki/B%C3%A9zout%27s_identity Bezout's identity - Wikipedia} for more information. * * @param BCMath $n * @return array{gcd: static, x: static, y: static} */ public function extendedGCD(BCMath $n) { // it might be faster to use the binary xGCD algorithim here, as well, but (1) that algorithim works // best when the base is a power of 2 and (2) i don't think it'd make much difference, anyway. as is, // the basic extended euclidean algorithim is what we're using. $u = $this->value; $v = $n->value; $a = '1'; $b = '0'; $c = '0'; $d = '1'; while (bccomp($v, '0', 0) != 0) { $q = bcdiv($u, $v, 0); $temp = $u; $u = $v; $v = bcsub($temp, bcmul($v, $q, 0), 0); $temp = $a; $a = $c; $c = bcsub($temp, bcmul($a, $q, 0), 0); $temp = $b; $b = $d; $d = bcsub($temp, bcmul($b, $q, 0), 0); } return [ 'gcd' => $this->normalize(new static($u)), 'x' => $this->normalize(new static($a)), 'y' => $this->normalize(new static($b)) ]; } /** * Calculates the greatest common divisor * * Say you have 693 and 609. The GCD is 21. * * @param BCMath $n * @return BCMath */ public function gcd(BCMath $n) { $gcd = $this->extendedGCD($n)['gcd']; return $gcd; } /** * Absolute value. * * @return BCMath */ public function abs() { $temp = new static(); $temp->value = strlen($this->value) && $this->value[0] == '-' ? substr($this->value, 1) : $this->value; return $temp; } /** * Logical And * * @param BCMath $x * @return BCMath */ public function bitwise_and(BCMath $x) { return $this->bitwiseAndHelper($x); } /** * Logical Or * * @param BCMath $x * @return BCMath */ public function bitwise_or(BCMath $x) { return $this->bitwiseOrHelper($x); } /** * Logical Exclusive Or * * @param BCMath $x * @return BCMath */ public function bitwise_xor(BCMath $x) { return $this->bitwiseXorHelper($x); } /** * Logical Right Shift * * Shifts BigInteger's by $shift bits, effectively dividing by 2**$shift. * * @param int $shift * @return BCMath */ public function bitwise_rightShift($shift) { $temp = new static(); $temp->value = bcdiv($this->value, bcpow('2', $shift, 0), 0); return $this->normalize($temp); } /** * Logical Left Shift * * Shifts BigInteger's by $shift bits, effectively multiplying by 2**$shift. * * @param int $shift * @return BCMath */ public function bitwise_leftShift($shift) { $temp = new static(); $temp->value = bcmul($this->value, bcpow('2', $shift, 0), 0); return $this->normalize($temp); } /** * Compares two numbers. * * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite. The reason for this * is demonstrated thusly: * * $x > $y: $x->compare($y) > 0 * $x < $y: $x->compare($y) < 0 * $x == $y: $x->compare($y) == 0 * * Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y). * * {@internal Could return $this->subtract($x), but that's not as fast as what we do do.} * * @param BCMath $y * @return int in case < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal. * @see self::equals() */ public function compare(BCMath $y) { return bccomp($this->value, $y->value, 0); } /** * Tests the equality of two numbers. * * If you need to see if one number is greater than or less than another number, use BigInteger::compare() * * @param BCMath $x * @return bool */ public function equals(BCMath $x) { return $this->value == $x->value; } /** * Performs modular exponentiation. * * @param BCMath $e * @param BCMath $n * @return BCMath */ public function modPow(BCMath $e, BCMath $n) { return $this->powModOuter($e, $n); } /** * Performs modular exponentiation. * * Alias for modPow(). * * @param BCMath $e * @param BCMath $n * @return BCMath */ public function powMod(BCMath $e, BCMath $n) { return $this->powModOuter($e, $n); } /** * Performs modular exponentiation. * * @param BCMath $e * @param BCMath $n * @return BCMath */ protected function powModInner(BCMath $e, BCMath $n) { try { $class = static::$modexpEngine[static::class]; return $class::powModHelper($this, $e, $n, static::class); } catch (\Exception $err) { return BCMath\DefaultEngine::powModHelper($this, $e, $n, static::class); } } /** * Normalize * * Removes leading zeros and truncates (if necessary) to maintain the appropriate precision * * @param BCMath $result * @return BCMath */ protected function normalize(BCMath $result) { $result->precision = $this->precision; $result->bitmask = $this->bitmask; if ($result->bitmask !== false) { $result->value = self::BCMOD_THREE_PARAMS ? bcmod($result->value, $result->bitmask->value, 0) : bcmod($result->value, $result->bitmask->value); } return $result; } /** * Generate a random prime number between a range * * If there's not a prime within the given range, false will be returned. * * @param BCMath $min * @param BCMath $max * @return false|BCMath */ public static function randomRangePrime(BCMath $min, BCMath $max) { return self::randomRangePrimeOuter($min, $max); } /** * Generate a random number between a range * * Returns a random number between $min and $max where $min and $max * can be defined using one of the two methods: * * BigInteger::randomRange($min, $max) * BigInteger::randomRange($max, $min) * * @param BCMath $min * @param BCMath $max * @return BCMath */ public static function randomRange(BCMath $min, BCMath $max) { return self::randomRangeHelper($min, $max); } /** * Make the current number odd * * If the current number is odd it'll be unchanged. If it's even, one will be added to it. * * @see self::randomPrime() */ protected function make_odd() { if (!$this->isOdd()) { $this->value = bcadd($this->value, '1', 0); } } /** * Test the number against small primes. * * @see self::isPrime() */ protected function testSmallPrimes() { if ($this->value === '1') { return false; } if ($this->value === '2') { return true; } if ($this->value[strlen($this->value) - 1] % 2 == 0) { return false; } $value = $this->value; foreach (self::PRIMES as $prime) { $r = self::BCMOD_THREE_PARAMS ? bcmod($this->value, $prime, 0) : bcmod($this->value, $prime); if ($r == '0') { return $this->value == $prime; } } return true; } /** * Scan for 1 and right shift by that amount * * ie. $s = gmp_scan1($n, 0) and $r = gmp_div_q($n, gmp_pow(gmp_init('2'), $s)); * * @param BCMath $r * @return int * @see self::isPrime() */ public static function scan1divide(BCMath $r) { $r_value = &$r->value; $s = 0; // if $n was 1, $r would be 0 and this would be an infinite loop, hence our $this->equals(static::$one[static::class]) check earlier while ($r_value[strlen($r_value) - 1] % 2 == 0) { $r_value = bcdiv($r_value, '2', 0); ++$s; } return $s; } /** * Performs exponentiation. * * @param BCMath $n * @return BCMath */ public function pow(BCMath $n) { $temp = new self(); $temp->value = bcpow($this->value, $n->value, 0); return $this->normalize($temp); } /** * Return the minimum BigInteger between an arbitrary number of BigIntegers. * * @param BCMath ...$nums * @return BCMath */ public static function min(BCMath ...$nums) { return self::minHelper($nums); } /** * Return the maximum BigInteger between an arbitrary number of BigIntegers. * * @param BCMath ...$nums * @return BCMath */ public static function max(BCMath ...$nums) { return self::maxHelper($nums); } /** * Tests BigInteger to see if it is between two integers, inclusive * * @param BCMath $min * @param BCMath $max * @return bool */ public function between(BCMath $min, BCMath $max) { return $this->compare($min) >= 0 && $this->compare($max) <= 0; } /** * Set Bitmask * * @param int $bits * @return Engine * @see self::setPrecision() */ protected static function setBitmask($bits) { $temp = parent::setBitmask($bits); return $temp->add(static::$one[static::class]); } /** * Is Odd? * * @return bool */ public function isOdd() { return $this->value[strlen($this->value) - 1] % 2 == 1; } /** * Tests if a bit is set * * @return bool */ public function testBit($x) { $divisor = bcpow('2', $x + 1, 0); return bccomp( self::BCMOD_THREE_PARAMS ? bcmod($this->value, $divisor, 0) : bcmod($this->value, $divisor), bcpow('2', $x, 0), 0 ) >= 0; } /** * Is Negative? * * @return bool */ public function isNegative() { return strlen($this->value) && $this->value[0] == '-'; } /** * Negate * * Given $k, returns -$k * * @return BCMath */ public function negate() { $temp = clone $this; if (!strlen($temp->value)) { return $temp; } $temp->value = $temp->value[0] == '-' ? substr($this->value, 1) : '-' . $this->value; return $temp; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/Engine.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Math\BigInteger\Engines; use phpseclib3\Common\Functions\Strings; use phpseclib3\Crypt\Random; use phpseclib3\Exception\BadConfigurationException; use phpseclib3\Math\BigInteger; /** * Base Engine. * * @author Jim Wigginton */ abstract class Engine implements \JsonSerializable { /* final protected */ const PRIMES = [ 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, ]; /** * BigInteger(0) * * @var array, static> */ protected static $zero = []; /** * BigInteger(1) * * @var array, static> */ protected static $one = []; /** * BigInteger(2) * * @var array, static> */ protected static $two = []; /** * Modular Exponentiation Engine * * @var array, class-string> */ protected static $modexpEngine; /** * Engine Validity Flag * * @var array, bool> */ protected static $isValidEngine; /** * Holds the BigInteger's value * * @var \GMP|string|array|int */ protected $value; /** * Holds the BigInteger's sign * * @var bool */ protected $is_negative; /** * Precision * * @see static::setPrecision() * @var int */ protected $precision = -1; /** * Precision Bitmask * * @see static::setPrecision() * @var static|false */ protected $bitmask = false; /** * Recurring Modulo Function * * @var callable */ protected $reduce; /** * Mode independent value used for serialization. * * @see self::__sleep() * @see self::__wakeup() * @var string */ protected $hex; /** * Default constructor * * @param int|numeric-string $x integer Base-10 number or base-$base number if $base set. * @param int $base */ public function __construct($x = 0, $base = 10) { if (!array_key_exists(static::class, static::$zero)) { static::$zero[static::class] = null; // Placeholder to prevent infinite loop. static::$zero[static::class] = new static(0); static::$one[static::class] = new static(1); static::$two[static::class] = new static(2); } // '0' counts as empty() but when the base is 256 '0' is equal to ord('0') or 48 // '0' is the only value like this per http://php.net/empty if (empty($x) && (abs($base) != 256 || $x !== '0')) { return; } switch ($base) { case -256: case 256: if ($base == -256 && (ord($x[0]) & 0x80)) { $this->value = ~$x; $this->is_negative = true; } else { $this->value = $x; $this->is_negative = false; } $this->initialize($base); if ($this->is_negative) { $temp = $this->add(new static('-1')); $this->value = $temp->value; } break; case -16: case 16: if ($base > 0 && $x[0] == '-') { $this->is_negative = true; $x = substr($x, 1); } $x = preg_replace('#^(?:0x)?([A-Fa-f0-9]*).*#s', '$1', $x); $is_negative = false; if ($base < 0 && hexdec($x[0]) >= 8) { $this->is_negative = $is_negative = true; $x = Strings::bin2hex(~Strings::hex2bin($x)); } $this->value = $x; $this->initialize($base); if ($is_negative) { $temp = $this->add(new static('-1')); $this->value = $temp->value; } break; case -10: case 10: // (?value = preg_replace('#(?value) || $this->value == '-') { $this->value = '0'; } $this->initialize($base); break; case -2: case 2: if ($base > 0 && $x[0] == '-') { $this->is_negative = true; $x = substr($x, 1); } $x = preg_replace('#^([01]*).*#s', '$1', $x); $temp = new static(Strings::bits2bin($x), 128 * $base); // ie. either -16 or +16 $this->value = $temp->value; if ($temp->is_negative) { $this->is_negative = true; } break; default: // base not supported, so we'll let $this == 0 } } /** * Sets engine type. * * Throws an exception if the type is invalid * * @param class-string $engine */ public static function setModExpEngine($engine) { $fqengine = '\\phpseclib3\\Math\\BigInteger\\Engines\\' . static::ENGINE_DIR . '\\' . $engine; if (!class_exists($fqengine) || !method_exists($fqengine, 'isValidEngine')) { throw new \InvalidArgumentException("$engine is not a valid engine"); } if (!$fqengine::isValidEngine()) { throw new BadConfigurationException("$engine is not setup correctly on this system"); } static::$modexpEngine[static::class] = $fqengine; } /** * Converts a BigInteger to a byte string (eg. base-256). * * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're * saved as two's compliment. * @return string */ protected function toBytesHelper() { $comparison = $this->compare(new static()); if ($comparison == 0) { return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : ''; } $temp = $comparison < 0 ? $this->add(new static(1)) : $this; $bytes = $temp->toBytes(); if (!strlen($bytes)) { // eg. if the number we're trying to convert is -1 $bytes = chr(0); } if (ord($bytes[0]) & 0x80) { $bytes = chr(0) . $bytes; } return $comparison < 0 ? ~$bytes : $bytes; } /** * Converts a BigInteger to a hex string (eg. base-16). * * @param bool $twos_compliment * @return string */ public function toHex($twos_compliment = false) { return Strings::bin2hex($this->toBytes($twos_compliment)); } /** * Converts a BigInteger to a bit string (eg. base-2). * * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're * saved as two's compliment. * * @param bool $twos_compliment * @return string */ public function toBits($twos_compliment = false) { $hex = $this->toBytes($twos_compliment); $bits = Strings::bin2bits($hex); $result = $this->precision > 0 ? substr($bits, -$this->precision) : ltrim($bits, '0'); if ($twos_compliment && $this->compare(new static()) > 0 && $this->precision <= 0) { return '0' . $result; } return $result; } /** * Calculates modular inverses. * * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. * * {@internal See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=21 HAC 14.64} for more information.} * * @param Engine $n * @return static|false */ protected function modInverseHelper(Engine $n) { // $x mod -$n == $x mod $n. $n = $n->abs(); if ($this->compare(static::$zero[static::class]) < 0) { $temp = $this->abs(); $temp = $temp->modInverse($n); return $this->normalize($n->subtract($temp)); } $extended = $this->extendedGCD($n); $gcd = $extended['gcd']; $x = $extended['x']; if (!$gcd->equals(static::$one[static::class])) { return false; } $x = $x->compare(static::$zero[static::class]) < 0 ? $x->add($n) : $x; return $this->compare(static::$zero[static::class]) < 0 ? $this->normalize($n->subtract($x)) : $this->normalize($x); } /** * Serialize * * Will be called, automatically, when serialize() is called on a BigInteger object. * * @return array */ public function __sleep() { $this->hex = $this->toHex(true); $vars = ['hex']; if ($this->precision > 0) { $vars[] = 'precision'; } return $vars; } /** * Serialize * * Will be called, automatically, when unserialize() is called on a BigInteger object. * * @return void */ public function __wakeup() { $temp = new static($this->hex, -16); $this->value = $temp->value; $this->is_negative = $temp->is_negative; if ($this->precision > 0) { // recalculate $this->bitmask $this->setPrecision($this->precision); } } /** * __serialize() magic method * * __sleep / __wakeup were depreciated in PHP 8.5 * Will be called, automatically, when serialize() is called on a Math_BigInteger object. * * @see self::__unserialize() * @access public */ public function __serialize() { $result = ['hex' => $this->toHex(true)]; if ($this->precision > 0) { $result['precision'] = $this->precision; } return $result; } /** * __unserialize() magic method * * __sleep / __wakeup were depreciated in PHP 8.5 * Will be called, automatically, when unserialize() is called on a Math_BigInteger object. * * @see self::__serialize() * @access public */ public function __unserialize(array $data) { $temp = new static($data['hex'], -16); $this->value = $temp->value; $this->is_negative = $temp->is_negative; if (isset($data['precision']) && $data['precision'] > 0) { // recalculate $this->bitmask $this->setPrecision($data['precision']); } } /** * JSON Serialize * * Will be called, automatically, when json_encode() is called on a BigInteger object. * * @return array{hex: string, precision?: int] */ #[\ReturnTypeWillChange] public function jsonSerialize() { $result = ['hex' => $this->toHex(true)]; if ($this->precision > 0) { $result['precision'] = $this->precision; } return $result; } /** * Converts a BigInteger to a base-10 number. * * @return string */ public function __toString() { return $this->toString(); } /** * __debugInfo() magic method * * Will be called, automatically, when print_r() or var_dump() are called * * @return array */ public function __debugInfo() { $result = [ 'value' => '0x' . $this->toHex(true), 'engine' => basename(static::class) ]; return $this->precision > 0 ? $result + ['precision' => $this->precision] : $result; } /** * Set Precision * * Some bitwise operations give different results depending on the precision being used. Examples include left * shift, not, and rotates. * * @param int $bits */ public function setPrecision($bits) { if ($bits < 1) { $this->precision = -1; $this->bitmask = false; return; } $this->precision = $bits; $this->bitmask = static::setBitmask($bits); $temp = $this->normalize($this); $this->value = $temp->value; } /** * Get Precision * * Returns the precision if it exists, -1 if it doesn't * * @return int */ public function getPrecision() { return $this->precision; } /** * Set Bitmask * @return static * @param int $bits * @see self::setPrecision() */ protected static function setBitmask($bits) { return new static(chr((1 << ($bits & 0x7)) - 1) . str_repeat(chr(0xFF), $bits >> 3), 256); } /** * Logical Not * * @return Engine|string */ public function bitwise_not() { // calculuate "not" without regard to $this->precision // (will always result in a smaller number. ie. ~1 isn't 1111 1110 - it's 0) $temp = $this->toBytes(); if ($temp == '') { return $this->normalize(static::$zero[static::class]); } $pre_msb = decbin(ord($temp[0])); $temp = ~$temp; $msb = decbin(ord($temp[0])); if (strlen($msb) == 8) { $msb = substr($msb, strpos($msb, '0')); } $temp[0] = chr(bindec($msb)); // see if we need to add extra leading 1's $current_bits = strlen($pre_msb) + 8 * strlen($temp) - 8; $new_bits = $this->precision - $current_bits; if ($new_bits <= 0) { return $this->normalize(new static($temp, 256)); } // generate as many leading 1's as we need to. $leading_ones = chr((1 << ($new_bits & 0x7)) - 1) . str_repeat(chr(0xFF), $new_bits >> 3); self::base256_lshift($leading_ones, $current_bits); $temp = str_pad($temp, strlen($leading_ones), chr(0), STR_PAD_LEFT); return $this->normalize(new static($leading_ones | $temp, 256)); } /** * Logical Left Shift * * Shifts binary strings $shift bits, essentially multiplying by 2**$shift. * * @param string $x * @param int $shift * @return void */ protected static function base256_lshift(&$x, $shift) { if ($shift == 0) { return; } $num_bytes = $shift >> 3; // eg. floor($shift/8) $shift &= 7; // eg. $shift % 8 $carry = 0; for ($i = strlen($x) - 1; $i >= 0; --$i) { $temp = ord($x[$i]) << $shift | $carry; $x[$i] = chr($temp); $carry = $temp >> 8; } $carry = ($carry != 0) ? chr($carry) : ''; $x = $carry . $x . str_repeat(chr(0), $num_bytes); } /** * Logical Left Rotate * * Instead of the top x bits being dropped they're appended to the shifted bit string. * * @param int $shift * @return Engine */ public function bitwise_leftRotate($shift) { $bits = $this->toBytes(); if ($this->precision > 0) { $precision = $this->precision; if (static::FAST_BITWISE) { $mask = $this->bitmask->toBytes(); } else { $mask = $this->bitmask->subtract(new static(1)); $mask = $mask->toBytes(); } } else { $temp = ord($bits[0]); for ($i = 0; $temp >> $i; ++$i) { } $precision = 8 * strlen($bits) - 8 + $i; $mask = chr((1 << ($precision & 0x7)) - 1) . str_repeat(chr(0xFF), $precision >> 3); } if ($shift < 0) { $shift += $precision; } $shift %= $precision; if (!$shift) { return clone $this; } $left = $this->bitwise_leftShift($shift); $left = $left->bitwise_and(new static($mask, 256)); $right = $this->bitwise_rightShift($precision - $shift); $result = static::FAST_BITWISE ? $left->bitwise_or($right) : $left->add($right); return $this->normalize($result); } /** * Logical Right Rotate * * Instead of the bottom x bits being dropped they're prepended to the shifted bit string. * * @param int $shift * @return Engine */ public function bitwise_rightRotate($shift) { return $this->bitwise_leftRotate(-$shift); } /** * Returns the smallest and largest n-bit number * * @param int $bits * @return array{min: static, max: static} */ public static function minMaxBits($bits) { $bytes = $bits >> 3; $min = str_repeat(chr(0), $bytes); $max = str_repeat(chr(0xFF), $bytes); $msb = $bits & 7; if ($msb) { $min = chr(1 << ($msb - 1)) . $min; $max = chr((1 << $msb) - 1) . $max; } else { $min[0] = chr(0x80); } return [ 'min' => new static($min, 256), 'max' => new static($max, 256) ]; } /** * Return the size of a BigInteger in bits * * @return int */ public function getLength() { return strlen($this->toBits()); } /** * Return the size of a BigInteger in bytes * * @return int */ public function getLengthInBytes() { return (int) ceil($this->getLength() / 8); } /** * Performs some pre-processing for powMod * * @param Engine $e * @param Engine $n * @return static|false */ protected function powModOuter(Engine $e, Engine $n) { $n = $this->bitmask !== false && $this->bitmask->compare($n) < 0 ? $this->bitmask : $n->abs(); if ($e->compare(new static()) < 0) { $e = $e->abs(); $temp = $this->modInverse($n); if ($temp === false) { return false; } return $this->normalize($temp->powModInner($e, $n)); } if ($this->compare($n) > 0 || $this->isNegative()) { list(, $temp) = $this->divide($n); return $temp->powModInner($e, $n); } return $this->powModInner($e, $n); } /** * Sliding Window k-ary Modular Exponentiation * * Based on {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=27 HAC 14.85} / * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=210 MPM 7.7}. In a departure from those algorithims, * however, this function performs a modular reduction after every multiplication and squaring operation. * As such, this function has the same preconditions that the reductions being used do. * * @template T of Engine * @param Engine $x * @param Engine $e * @param Engine $n * @param class-string $class * @return T */ protected static function slidingWindow(Engine $x, Engine $e, Engine $n, $class) { static $window_ranges = [7, 25, 81, 241, 673, 1793]; // from BigInteger.java's oddModPow function //static $window_ranges = [0, 7, 36, 140, 450, 1303, 3529]; // from MPM 7.3.1 $e_bits = $e->toBits(); $e_length = strlen($e_bits); // calculate the appropriate window size. // $window_size == 3 if $window_ranges is between 25 and 81, for example. for ($i = 0, $window_size = 1; $i < count($window_ranges) && $e_length > $window_ranges[$i]; ++$window_size, ++$i) { } $n_value = $n->value; if (method_exists(static::class, 'generateCustomReduction')) { static::generateCustomReduction($n, $class); } // precompute $this^0 through $this^$window_size $powers = []; $powers[1] = static::prepareReduce($x->value, $n_value, $class); $powers[2] = static::squareReduce($powers[1], $n_value, $class); // we do every other number since substr($e_bits, $i, $j+1) (see below) is supposed to end // in a 1. ie. it's supposed to be odd. $temp = 1 << ($window_size - 1); for ($i = 1; $i < $temp; ++$i) { $i2 = $i << 1; $powers[$i2 + 1] = static::multiplyReduce($powers[$i2 - 1], $powers[2], $n_value, $class); } $result = new $class(1); $result = static::prepareReduce($result->value, $n_value, $class); for ($i = 0; $i < $e_length;) { if (!$e_bits[$i]) { $result = static::squareReduce($result, $n_value, $class); ++$i; } else { for ($j = $window_size - 1; $j > 0; --$j) { if (!empty($e_bits[$i + $j])) { break; } } // eg. the length of substr($e_bits, $i, $j + 1) for ($k = 0; $k <= $j; ++$k) { $result = static::squareReduce($result, $n_value, $class); } $result = static::multiplyReduce($result, $powers[bindec(substr($e_bits, $i, $j + 1))], $n_value, $class); $i += $j + 1; } } $temp = new $class(); $temp->value = static::reduce($result, $n_value, $class); return $temp; } /** * Generates a random number of a certain size * * Bit length is equal to $size * * @param int $size * @return Engine */ public static function random($size) { $minMax = static::minMaxBits($size); $min = $minMax['min']; $max = $minMax['max']; return static::randomRange($min, $max); } /** * Generates a random prime number of a certain size * * Bit length is equal to $size * * @param int $size * @return Engine */ public static function randomPrime($size) { $minMax = static::minMaxBits($size); $min = $minMax['min']; $max = $minMax['max']; return static::randomRangePrime($min, $max); } /** * Performs some pre-processing for randomRangePrime * * @param Engine $min * @param Engine $max * @return static|false */ protected static function randomRangePrimeOuter(Engine $min, Engine $max) { $compare = $max->compare($min); if (!$compare) { return $min->isPrime() ? $min : false; } elseif ($compare < 0) { // if $min is bigger then $max, swap $min and $max $temp = $max; $max = $min; $min = $temp; } $length = $max->getLength(); if ($length > 8196) { throw new \RuntimeException("Generation of random prime numbers larger than 8196 has been disabled ($length)"); } $x = static::randomRange($min, $max); return static::randomRangePrimeInner($x, $min, $max); } /** * Generate a random number between a range * * Returns a random number between $min and $max where $min and $max * can be defined using one of the two methods: * * BigInteger::randomRange($min, $max) * BigInteger::randomRange($max, $min) * * @param Engine $min * @param Engine $max * @return Engine */ protected static function randomRangeHelper(Engine $min, Engine $max) { $compare = $max->compare($min); if (!$compare) { return $min; } elseif ($compare < 0) { // if $min is bigger then $max, swap $min and $max $temp = $max; $max = $min; $min = $temp; } if (!isset(static::$one[static::class])) { static::$one[static::class] = new static(1); } $max = $max->subtract($min->subtract(static::$one[static::class])); $size = strlen(ltrim($max->toBytes(), chr(0))); /* doing $random % $max doesn't work because some numbers will be more likely to occur than others. eg. if $max is 140 and $random's max is 255 then that'd mean both $random = 5 and $random = 145 would produce 5 whereas the only value of random that could produce 139 would be 139. ie. not all numbers would be equally likely. some would be more likely than others. creating a whole new random number until you find one that is within the range doesn't work because, for sufficiently small ranges, the likelihood that you'd get a number within that range would be pretty small. eg. with $random's max being 255 and if your $max being 1 the probability would be pretty high that $random would be greater than $max. phpseclib works around this using the technique described here: http://crypto.stackexchange.com/questions/5708/creating-a-small-number-from-a-cryptographically-secure-random-string */ $random_max = new static(chr(1) . str_repeat("\0", $size), 256); $random = new static(Random::string($size), 256); list($max_multiple) = $random_max->divide($max); $max_multiple = $max_multiple->multiply($max); while ($random->compare($max_multiple) >= 0) { $random = $random->subtract($max_multiple); $random_max = $random_max->subtract($max_multiple); $random = $random->bitwise_leftShift(8); $random = $random->add(new static(Random::string(1), 256)); $random_max = $random_max->bitwise_leftShift(8); list($max_multiple) = $random_max->divide($max); $max_multiple = $max_multiple->multiply($max); } list(, $random) = $random->divide($max); return $random->add($min); } /** * Performs some post-processing for randomRangePrime * * @param Engine $x * @param Engine $min * @param Engine $max * @return static|false */ protected static function randomRangePrimeInner(Engine $x, Engine $min, Engine $max) { if (!isset(static::$two[static::class])) { static::$two[static::class] = new static('2'); } $x->make_odd(); if ($x->compare($max) > 0) { // if $x > $max then $max is even and if $min == $max then no prime number exists between the specified range if ($min->equals($max)) { return false; } $x = clone $min; $x->make_odd(); } $initial_x = clone $x; while (true) { if ($x->isPrime()) { return $x; } $x = $x->add(static::$two[static::class]); if ($x->compare($max) > 0) { $x = clone $min; if ($x->equals(static::$two[static::class])) { return $x; } $x->make_odd(); } if ($x->equals($initial_x)) { return false; } } } /** * Sets the $t parameter for primality testing * * @return int */ protected function setupIsPrime() { $length = $this->getLengthInBytes(); // see HAC 4.49 "Note (controlling the error probability)" // @codingStandardsIgnoreStart if ($length >= 163) { $t = 2; } // floor(1300 / 8) else if ($length >= 106) { $t = 3; } // floor( 850 / 8) else if ($length >= 81 ) { $t = 4; } // floor( 650 / 8) else if ($length >= 68 ) { $t = 5; } // floor( 550 / 8) else if ($length >= 56 ) { $t = 6; } // floor( 450 / 8) else if ($length >= 50 ) { $t = 7; } // floor( 400 / 8) else if ($length >= 43 ) { $t = 8; } // floor( 350 / 8) else if ($length >= 37 ) { $t = 9; } // floor( 300 / 8) else if ($length >= 31 ) { $t = 12; } // floor( 250 / 8) else if ($length >= 25 ) { $t = 15; } // floor( 200 / 8) else if ($length >= 18 ) { $t = 18; } // floor( 150 / 8) else { $t = 27; } // @codingStandardsIgnoreEnd return $t; } /** * Tests Primality * * Uses the {@link http://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test Miller-Rabin primality test}. * See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap4.pdf#page=8 HAC 4.24} for more info. * * @param int $t * @return bool */ protected function testPrimality($t) { if (!$this->testSmallPrimes()) { return false; } $n = clone $this; $n_1 = $n->subtract(static::$one[static::class]); $n_2 = $n->subtract(static::$two[static::class]); $r = clone $n_1; $s = static::scan1divide($r); for ($i = 0; $i < $t; ++$i) { $a = static::randomRange(static::$two[static::class], $n_2); $y = $a->modPow($r, $n); if (!$y->equals(static::$one[static::class]) && !$y->equals($n_1)) { for ($j = 1; $j < $s && !$y->equals($n_1); ++$j) { $y = $y->modPow(static::$two[static::class], $n); if ($y->equals(static::$one[static::class])) { return false; } } if (!$y->equals($n_1)) { return false; } } } return true; } /** * Checks a numer to see if it's prime * * Assuming the $t parameter is not set, this function has an error rate of 2**-80. The main motivation for the * $t parameter is distributability. BigInteger::randomPrime() can be distributed across multiple pageloads * on a website instead of just one. * * @param int|bool $t * @return bool */ public function isPrime($t = false) { // OpenSSL limits RSA keys to 16384 bits. The length of an RSA key is equal to the length of the modulo, which is // produced by multiplying the primes p and q by one another. The largest number two 8196 bit primes can produce is // a 16384 bit number so, basically, 8196 bit primes are the largest OpenSSL will generate and if that's the largest // that it'll generate it also stands to reason that that's the largest you'll be able to test primality on $length = $this->getLength(); if ($length > 8196) { throw new \RuntimeException("Primality testing is not supported for numbers larger than 8196 bits ($length)"); } if (!$t) { $t = $this->setupIsPrime(); } return $this->testPrimality($t); } /** * Performs a few preliminary checks on root * * @param int $n * @return Engine */ protected function rootHelper($n) { if ($n < 1) { return clone static::$zero[static::class]; } // we want positive exponents if ($this->compare(static::$one[static::class]) < 0) { return clone static::$zero[static::class]; } // we want positive numbers if ($this->compare(static::$two[static::class]) < 0) { return clone static::$one[static::class]; } // n-th root of 1 or 2 is 1 return $this->rootInner($n); } /** * Calculates the nth root of a biginteger. * * Returns the nth root of a positive biginteger, where n defaults to 2 * * {@internal This function is based off of {@link http://mathforum.org/library/drmath/view/52605.html this page} and {@link http://stackoverflow.com/questions/11242920/calculating-nth-root-with-bcmath-in-php this stackoverflow question}.} * * @param int $n * @return Engine */ protected function rootInner($n) { $n = new static($n); // g is our guess number $g = static::$two[static::class]; // while (g^n < num) g=g*2 while ($g->pow($n)->compare($this) < 0) { $g = $g->multiply(static::$two[static::class]); } // if (g^n==num) num is a power of 2, we're lucky, end of job // == 0 bccomp(bcpow($g, $n), $n->value)==0 if ($g->pow($n)->equals($this) > 0) { $root = $g; return $this->normalize($root); } // if we're here num wasn't a power of 2 :( $og = $g; // og means original guess and here is our upper bound $g = $g->divide(static::$two[static::class])[0]; // g is set to be our lower bound $step = $og->subtract($g)->divide(static::$two[static::class])[0]; // step is the half of upper bound - lower bound $g = $g->add($step); // we start at lower bound + step , basically in the middle of our interval // while step>1 while ($step->compare(static::$one[static::class]) == 1) { $guess = $g->pow($n); $step = $step->divide(static::$two[static::class])[0]; $comp = $guess->compare($this); // compare our guess with real number switch ($comp) { case -1: // if guess is lower we add the new step $g = $g->add($step); break; case 1: // if guess is higher we sub the new step $g = $g->subtract($step); break; case 0: // if guess is exactly the num we're done, we return the value $root = $g; break 2; } } if ($comp == 1) { $g = $g->subtract($step); } // whatever happened, g is the closest guess we can make so return it $root = $g; return $this->normalize($root); } /** * Calculates the nth root of a biginteger. * * @param int $n * @return Engine */ public function root($n = 2) { return $this->rootHelper($n); } /** * Return the minimum BigInteger between an arbitrary number of BigIntegers. * * @param array $nums * @return Engine */ protected static function minHelper(array $nums) { if (count($nums) == 1) { return $nums[0]; } $min = $nums[0]; for ($i = 1; $i < count($nums); $i++) { $min = $min->compare($nums[$i]) > 0 ? $nums[$i] : $min; } return $min; } /** * Return the minimum BigInteger between an arbitrary number of BigIntegers. * * @param array $nums * @return Engine */ protected static function maxHelper(array $nums) { if (count($nums) == 1) { return $nums[0]; } $max = $nums[0]; for ($i = 1; $i < count($nums); $i++) { $max = $max->compare($nums[$i]) < 0 ? $nums[$i] : $max; } return $max; } /** * Create Recurring Modulo Function * * Sometimes it may be desirable to do repeated modulos with the same number outside of * modular exponentiation * * @return callable */ public function createRecurringModuloFunction() { $class = static::class; $fqengine = !method_exists(static::$modexpEngine[static::class], 'reduce') ? '\\phpseclib3\\Math\\BigInteger\\Engines\\' . static::ENGINE_DIR . '\\DefaultEngine' : static::$modexpEngine[static::class]; if (method_exists($fqengine, 'generateCustomReduction')) { $func = $fqengine::generateCustomReduction($this, static::class); return eval('return function(' . static::class . ' $x) use ($func, $class) { $r = new $class(); $r->value = $func($x->value); return $r; };'); } $n = $this->value; return eval('return function(' . static::class . ' $x) use ($n, $fqengine, $class) { $r = new $class(); $r->value = $fqengine::reduce($x->value, $n, $class); return $r; };'); } /** * Calculates the greatest common divisor and Bezout's identity. * * @param Engine $n * @return array{gcd: Engine, x: Engine, y: Engine} */ protected function extendedGCDHelper(Engine $n) { $u = clone $this; $v = clone $n; $one = new static(1); $zero = new static(); $a = clone $one; $b = clone $zero; $c = clone $zero; $d = clone $one; while (!$v->equals($zero)) { list($q) = $u->divide($v); $temp = $u; $u = $v; $v = $temp->subtract($v->multiply($q)); $temp = $a; $a = $c; $c = $temp->subtract($a->multiply($q)); $temp = $b; $b = $d; $d = $temp->subtract($b->multiply($q)); } return [ 'gcd' => $u, 'x' => $a, 'y' => $b ]; } /** * Bitwise Split * * Splits BigInteger's into chunks of $split bits * * @param int $split * @return Engine[] */ public function bitwise_split($split) { if ($split < 1) { throw new \RuntimeException('Offset must be greater than 1'); } $mask = static::$one[static::class]->bitwise_leftShift($split)->subtract(static::$one[static::class]); $num = clone $this; $vals = []; while (!$num->equals(static::$zero[static::class])) { $vals[] = $num->bitwise_and($mask); $num = $num->bitwise_rightShift($split); } return array_reverse($vals); } /** * Logical And * * @param Engine $x * @return Engine */ protected function bitwiseAndHelper(Engine $x) { $left = $this->toBytes(true); $right = $x->toBytes(true); $length = max(strlen($left), strlen($right)); $left = str_pad($left, $length, chr(0), STR_PAD_LEFT); $right = str_pad($right, $length, chr(0), STR_PAD_LEFT); return $this->normalize(new static($left & $right, -256)); } /** * Logical Or * * @param Engine $x * @return Engine */ protected function bitwiseOrHelper(Engine $x) { $left = $this->toBytes(true); $right = $x->toBytes(true); $length = max(strlen($left), strlen($right)); $left = str_pad($left, $length, chr(0), STR_PAD_LEFT); $right = str_pad($right, $length, chr(0), STR_PAD_LEFT); return $this->normalize(new static($left | $right, -256)); } /** * Logical Exclusive Or * * @param Engine $x * @return Engine */ protected function bitwiseXorHelper(Engine $x) { $left = $this->toBytes(true); $right = $x->toBytes(true); $length = max(strlen($left), strlen($right)); $left = str_pad($left, $length, chr(0), STR_PAD_LEFT); $right = str_pad($right, $length, chr(0), STR_PAD_LEFT); return $this->normalize(new static($left ^ $right, -256)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP/DefaultEngine.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Math\BigInteger\Engines\GMP; use phpseclib3\Math\BigInteger\Engines\GMP; /** * GMP Modular Exponentiation Engine * * @author Jim Wigginton */ abstract class DefaultEngine extends GMP { /** * Performs modular exponentiation. * * @param GMP $x * @param GMP $e * @param GMP $n * @return GMP */ protected static function powModHelper(GMP $x, GMP $e, GMP $n) { $temp = new GMP(); $temp->value = gmp_powm($x->value, $e->value, $n->value); return $x->normalize($temp); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Math\BigInteger\Engines; use phpseclib3\Exception\BadConfigurationException; /** * GMP Engine. * * @author Jim Wigginton */ class GMP extends Engine { /** * Can Bitwise operations be done fast? * * @see parent::bitwise_leftRotate() * @see parent::bitwise_rightRotate() */ const FAST_BITWISE = true; /** * Engine Directory * * @see parent::setModExpEngine */ const ENGINE_DIR = 'GMP'; /** * Test for engine validity * * @return bool * @see parent::__construct() */ public static function isValidEngine() { return extension_loaded('gmp'); } /** * Default constructor * * @param mixed $x integer Base-10 number or base-$base number if $base set. * @param int $base * @see parent::__construct() */ public function __construct($x = 0, $base = 10) { if (!isset(static::$isValidEngine[static::class])) { static::$isValidEngine[static::class] = self::isValidEngine(); } if (!static::$isValidEngine[static::class]) { throw new BadConfigurationException('GMP is not setup correctly on this system'); } if ($x instanceof \GMP) { $this->value = $x; return; } $this->value = gmp_init(0); parent::__construct($x, $base); } /** * Initialize a GMP BigInteger Engine instance * * @param int $base * @see parent::__construct() */ protected function initialize($base) { switch (abs($base)) { case 256: $this->value = gmp_import($this->value); if ($this->is_negative) { $this->value = -$this->value; } break; case 16: $temp = $this->is_negative ? '-0x' . $this->value : '0x' . $this->value; $this->value = gmp_init($temp); break; case 10: $this->value = gmp_init(isset($this->value) ? $this->value : '0'); } } /** * Converts a BigInteger to a base-10 number. * * @return string */ public function toString() { return (string)$this->value; } /** * Converts a BigInteger to a bit string (eg. base-2). * * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're * saved as two's compliment. * * @param bool $twos_compliment * @return string */ public function toBits($twos_compliment = false) { $hex = $this->toHex($twos_compliment); $bits = gmp_strval(gmp_init($hex, 16), 2); if ($this->precision > 0) { $bits = substr($bits, -$this->precision); } if ($twos_compliment && $this->compare(new static()) > 0 && $this->precision <= 0) { return '0' . $bits; } return $bits; } /** * Converts a BigInteger to a byte string (eg. base-256). * * @param bool $twos_compliment * @return string */ public function toBytes($twos_compliment = false) { if ($twos_compliment) { return $this->toBytesHelper(); } if (gmp_cmp($this->value, gmp_init(0)) == 0) { return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : ''; } $temp = gmp_export($this->value); return $this->precision > 0 ? substr(str_pad($temp, $this->precision >> 3, chr(0), STR_PAD_LEFT), -($this->precision >> 3)) : ltrim($temp, chr(0)); } /** * Adds two BigIntegers. * * @param GMP $y * @return GMP */ public function add(GMP $y) { $temp = new self(); $temp->value = $this->value + $y->value; return $this->normalize($temp); } /** * Subtracts two BigIntegers. * * @param GMP $y * @return GMP */ public function subtract(GMP $y) { $temp = new self(); $temp->value = $this->value - $y->value; return $this->normalize($temp); } /** * Multiplies two BigIntegers. * * @param GMP $x * @return GMP */ public function multiply(GMP $x) { $temp = new self(); $temp->value = $this->value * $x->value; return $this->normalize($temp); } /** * Divides two BigIntegers. * * Returns an array whose first element contains the quotient and whose second element contains the * "common residue". If the remainder would be positive, the "common residue" and the remainder are the * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder * and the divisor (basically, the "common residue" is the first positive modulo). * * @param GMP $y * @return array{GMP, GMP} */ public function divide(GMP $y) { $quotient = new self(); $remainder = new self(); list($quotient->value, $remainder->value) = gmp_div_qr($this->value, $y->value); if (gmp_sign($remainder->value) < 0) { $remainder->value = $remainder->value + gmp_abs($y->value); } return [$this->normalize($quotient), $this->normalize($remainder)]; } /** * Compares two numbers. * * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite. The reason for this * is demonstrated thusly: * * $x > $y: $x->compare($y) > 0 * $x < $y: $x->compare($y) < 0 * $x == $y: $x->compare($y) == 0 * * Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y). * * {@internal Could return $this->subtract($x), but that's not as fast as what we do do.} * * @param GMP $y * @return int in case < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal. * @see self::equals() */ public function compare(GMP $y) { $r = gmp_cmp($this->value, $y->value); if ($r < -1) { $r = -1; } if ($r > 1) { $r = 1; } return $r; } /** * Tests the equality of two numbers. * * If you need to see if one number is greater than or less than another number, use BigInteger::compare() * * @param GMP $x * @return bool */ public function equals(GMP $x) { return $this->value == $x->value; } /** * Calculates modular inverses. * * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. * * @param GMP $n * @return false|GMP */ public function modInverse(GMP $n) { $temp = new self(); $temp->value = gmp_invert($this->value, $n->value); return $temp->value === false ? false : $this->normalize($temp); } /** * Calculates the greatest common divisor and Bezout's identity. * * Say you have 693 and 609. The GCD is 21. Bezout's identity states that there exist integers x and y such that * 693*x + 609*y == 21. In point of fact, there are actually an infinite number of x and y combinations and which * combination is returned is dependent upon which mode is in use. See * {@link http://en.wikipedia.org/wiki/B%C3%A9zout%27s_identity Bezout's identity - Wikipedia} for more information. * * @param GMP $n * @return GMP[] */ public function extendedGCD(GMP $n) { $extended = gmp_gcdext($this->value, $n->value); $g = $extended['g']; $s = $extended['s']; $t = $extended['t']; return [ 'gcd' => $this->normalize(new self($g)), 'x' => $this->normalize(new self($s)), 'y' => $this->normalize(new self($t)) ]; } /** * Calculates the greatest common divisor * * Say you have 693 and 609. The GCD is 21. * * @param GMP $n * @return GMP */ public function gcd(GMP $n) { $r = gmp_gcd($this->value, $n->value); return $this->normalize(new self($r)); } /** * Absolute value. * * @return GMP */ public function abs() { $temp = new self(); $temp->value = gmp_abs($this->value); return $temp; } /** * Logical And * * @param GMP $x * @return GMP */ public function bitwise_and(GMP $x) { $temp = new self(); $temp->value = $this->value & $x->value; return $this->normalize($temp); } /** * Logical Or * * @param GMP $x * @return GMP */ public function bitwise_or(GMP $x) { $temp = new self(); $temp->value = $this->value | $x->value; return $this->normalize($temp); } /** * Logical Exclusive Or * * @param GMP $x * @return GMP */ public function bitwise_xor(GMP $x) { $temp = new self(); $temp->value = $this->value ^ $x->value; return $this->normalize($temp); } /** * Logical Right Shift * * Shifts BigInteger's by $shift bits, effectively dividing by 2**$shift. * * @param int $shift * @return GMP */ public function bitwise_rightShift($shift) { // 0xFFFFFFFF >> 2 == -1 (on 32-bit systems) // gmp_init('0xFFFFFFFF') >> 2 == gmp_init('0x3FFFFFFF') $temp = new self(); $temp->value = $this->value >> $shift; return $this->normalize($temp); } /** * Logical Left Shift * * Shifts BigInteger's by $shift bits, effectively multiplying by 2**$shift. * * @param int $shift * @return GMP */ public function bitwise_leftShift($shift) { $temp = new self(); $temp->value = $this->value << $shift; return $this->normalize($temp); } /** * Performs modular exponentiation. * * @param GMP $e * @param GMP $n * @return GMP */ public function modPow(GMP $e, GMP $n) { return $this->powModOuter($e, $n); } /** * Performs modular exponentiation. * * Alias for modPow(). * * @param GMP $e * @param GMP $n * @return GMP */ public function powMod(GMP $e, GMP $n) { return $this->powModOuter($e, $n); } /** * Performs modular exponentiation. * * @param GMP $e * @param GMP $n * @return GMP */ protected function powModInner(GMP $e, GMP $n) { $class = static::$modexpEngine[static::class]; return $class::powModHelper($this, $e, $n); } /** * Normalize * * Removes leading zeros and truncates (if necessary) to maintain the appropriate precision * * @param GMP $result * @return GMP */ protected function normalize(GMP $result) { $result->precision = $this->precision; $result->bitmask = $this->bitmask; if ($result->bitmask !== false) { $flip = $result->value < 0; if ($flip) { $result->value = -$result->value; } $result->value = $result->value & $result->bitmask->value; if ($flip) { $result->value = -$result->value; } } return $result; } /** * Performs some post-processing for randomRangePrime * * @param Engine $x * @param Engine $min * @param Engine $max * @return GMP */ protected static function randomRangePrimeInner(Engine $x, Engine $min, Engine $max) { $p = gmp_nextprime($x->value); if ($p <= $max->value) { return new self($p); } if ($min->value != $x->value) { $x = new self($x->value - 1); } return self::randomRangePrime($min, $x); } /** * Generate a random prime number between a range * * If there's not a prime within the given range, false will be returned. * * @param GMP $min * @param GMP $max * @return false|GMP */ public static function randomRangePrime(GMP $min, GMP $max) { return self::randomRangePrimeOuter($min, $max); } /** * Generate a random number between a range * * Returns a random number between $min and $max where $min and $max * can be defined using one of the two methods: * * BigInteger::randomRange($min, $max) * BigInteger::randomRange($max, $min) * * @param GMP $min * @param GMP $max * @return GMP */ public static function randomRange(GMP $min, GMP $max) { return self::randomRangeHelper($min, $max); } /** * Make the current number odd * * If the current number is odd it'll be unchanged. If it's even, one will be added to it. * * @see self::randomPrime() */ protected function make_odd() { gmp_setbit($this->value, 0); } /** * Tests Primality * * @param int $t * @return bool */ protected function testPrimality($t) { return gmp_prob_prime($this->value, $t) != 0; } /** * Calculates the nth root of a biginteger. * * Returns the nth root of a positive biginteger, where n defaults to 2 * * @param int $n * @return GMP */ protected function rootInner($n) { $root = new self(); $root->value = gmp_root($this->value, $n); return $this->normalize($root); } /** * Performs exponentiation. * * @param GMP $n * @return GMP */ public function pow(GMP $n) { $temp = new self(); $temp->value = $this->value ** $n->value; return $this->normalize($temp); } /** * Return the minimum BigInteger between an arbitrary number of BigIntegers. * * @param GMP ...$nums * @return GMP */ public static function min(GMP ...$nums) { return self::minHelper($nums); } /** * Return the maximum BigInteger between an arbitrary number of BigIntegers. * * @param GMP ...$nums * @return GMP */ public static function max(GMP ...$nums) { return self::maxHelper($nums); } /** * Tests BigInteger to see if it is between two integers, inclusive * * @param GMP $min * @param GMP $max * @return bool */ public function between(GMP $min, GMP $max) { return $this->compare($min) >= 0 && $this->compare($max) <= 0; } /** * Create Recurring Modulo Function * * Sometimes it may be desirable to do repeated modulos with the same number outside of * modular exponentiation * * @return callable */ public function createRecurringModuloFunction() { $temp = $this->value; return function (GMP $x) use ($temp) { return new GMP($x->value % $temp); }; } /** * Scan for 1 and right shift by that amount * * ie. $s = gmp_scan1($n, 0) and $r = gmp_div_q($n, gmp_pow(gmp_init('2'), $s)); * * @param GMP $r * @return int */ public static function scan1divide(GMP $r) { $s = gmp_scan1($r->value, 0); $r->value >>= $s; return $s; } /** * Is Odd? * * @return bool */ public function isOdd() { return gmp_testbit($this->value, 0); } /** * Tests if a bit is set * * @return bool */ public function testBit($x) { return gmp_testbit($this->value, $x); } /** * Is Negative? * * @return bool */ public function isNegative() { return gmp_sign($this->value) == -1; } /** * Negate * * Given $k, returns -$k * * @return GMP */ public function negate() { $temp = clone $this; $temp->value = -$this->value; return $temp; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/OpenSSL.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Math\BigInteger\Engines; use phpseclib3\Crypt\RSA\Formats\Keys\PKCS8; use phpseclib3\Math\BigInteger; /** * OpenSSL Modular Exponentiation Engine * * @author Jim Wigginton */ abstract class OpenSSL { /** * Test for engine validity * * @return bool */ public static function isValidEngine() { return extension_loaded('openssl') && static::class != __CLASS__; } /** * Performs modular exponentiation. * * @param Engine $x * @param Engine $e * @param Engine $n * @return Engine */ public static function powModHelper(Engine $x, Engine $e, Engine $n) { if ($n->getLengthInBytes() < 31 || $n->getLengthInBytes() > 16384) { throw new \OutOfRangeException('Only modulo between 31 and 16384 bits are accepted'); } $key = PKCS8::savePublicKey( new BigInteger($n), new BigInteger($e) ); $plaintext = str_pad($x->toBytes(), $n->getLengthInBytes(), "\0", STR_PAD_LEFT); // this is easily prone to failure. if the modulo is a multiple of 2 or 3 or whatever it // won't work and you'll get a "failure: error:0906D06C:PEM routines:PEM_read_bio:no start line" // error. i suppose, for even numbers, we could do what PHP\Montgomery.php does, but then what // about odd numbers divisible by 3, by 5, etc? if (!openssl_public_encrypt($plaintext, $result, $key, OPENSSL_NO_PADDING)) { throw new \UnexpectedValueException(openssl_error_string()); } $class = get_class($x); return new $class($result, 256); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Base.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Math\BigInteger\Engines\PHP; use phpseclib3\Math\BigInteger\Engines\PHP; /** * PHP Modular Exponentiation Engine * * @author Jim Wigginton */ abstract class Base extends PHP { /** * Cache constants * * $cache[self::VARIABLE] tells us whether or not the cached data is still valid. * */ const VARIABLE = 0; /** * $cache[self::DATA] contains the cached data. * */ const DATA = 1; /** * Test for engine validity * * @return bool */ public static function isValidEngine() { return static::class != __CLASS__; } /** * Performs modular exponentiation. * * The most naive approach to modular exponentiation has very unreasonable requirements, and * and although the approach involving repeated squaring does vastly better, it, too, is impractical * for our purposes. The reason being that division - by far the most complicated and time-consuming * of the basic operations (eg. +,-,*,/) - occurs multiple times within it. * * Modular reductions resolve this issue. Although an individual modular reduction takes more time * then an individual division, when performed in succession (with the same modulo), they're a lot faster. * * The two most commonly used modular reductions are Barrett and Montgomery reduction. Montgomery reduction, * although faster, only works when the gcd of the modulo and of the base being used is 1. In RSA, when the * base is a power of two, the modulo - a product of two primes - is always going to have a gcd of 1 (because * the product of two odd numbers is odd), but what about when RSA isn't used? * * In contrast, Barrett reduction has no such constraint. As such, some bigint implementations perform a * Barrett reduction after every operation in the modpow function. Others perform Barrett reductions when the * modulo is even and Montgomery reductions when the modulo is odd. BigInteger.java's modPow method, however, * uses a trick involving the Chinese Remainder Theorem to factor the even modulo into two numbers - one odd and * the other, a power of two - and recombine them, later. This is the method that this modPow function uses. * {@link http://islab.oregonstate.edu/papers/j34monex.pdf Montgomery Reduction with Even Modulus} elaborates. * * @param PHP $x * @param PHP $e * @param PHP $n * @param string $class * @return PHP */ protected static function powModHelper(PHP $x, PHP $e, PHP $n, $class) { if (empty($e->value)) { $temp = new $class(); $temp->value = [1]; return $x->normalize($temp); } if ($e->value == [1]) { list(, $temp) = $x->divide($n); return $x->normalize($temp); } if ($e->value == [2]) { $temp = new $class(); $temp->value = $class::square($x->value); list(, $temp) = $temp->divide($n); return $x->normalize($temp); } return $x->normalize(static::slidingWindow($x, $e, $n, $class)); } /** * Modular reduction preparation * * @param array $x * @param array $n * @param string $class * @see self::slidingWindow() * @return array */ protected static function prepareReduce(array $x, array $n, $class) { return static::reduce($x, $n, $class); } /** * Modular multiply * * @param array $x * @param array $y * @param array $n * @param string $class * @see self::slidingWindow() * @return array */ protected static function multiplyReduce(array $x, array $y, array $n, $class) { $temp = $class::multiplyHelper($x, false, $y, false); return static::reduce($temp[self::VALUE], $n, $class); } /** * Modular square * * @param array $x * @param array $n * @param string $class * @see self::slidingWindow() * @return array */ protected static function squareReduce(array $x, array $n, $class) { return static::reduce($class::square($x), $n, $class); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/DefaultEngine.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Math\BigInteger\Engines\PHP; use phpseclib3\Math\BigInteger\Engines\PHP\Reductions\EvalBarrett; /** * PHP Default Modular Exponentiation Engine * * @author Jim Wigginton */ abstract class DefaultEngine extends EvalBarrett { } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Montgomery.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Math\BigInteger\Engines\PHP; use phpseclib3\Math\BigInteger\Engines\Engine; use phpseclib3\Math\BigInteger\Engines\PHP; use phpseclib3\Math\BigInteger\Engines\PHP\Reductions\PowerOfTwo; /** * PHP Montgomery Modular Exponentiation Engine * * @author Jim Wigginton */ abstract class Montgomery extends Base { /** * Test for engine validity * * @return bool */ public static function isValidEngine() { return static::class != __CLASS__; } /** * Performs modular exponentiation. * * @template T of Engine * @param Engine $x * @param Engine $e * @param Engine $n * @param class-string $class * @return T */ protected static function slidingWindow(Engine $x, Engine $e, Engine $n, $class) { // is the modulo odd? if ($n->value[0] & 1) { return parent::slidingWindow($x, $e, $n, $class); } // if it's not, it's even // find the lowest set bit (eg. the max pow of 2 that divides $n) for ($i = 0; $i < count($n->value); ++$i) { if ($n->value[$i]) { $temp = decbin($n->value[$i]); $j = strlen($temp) - strrpos($temp, '1') - 1; $j += $class::BASE * $i; break; } } // at this point, 2^$j * $n/(2^$j) == $n $mod1 = clone $n; $mod1->rshift($j); $mod2 = new $class(); $mod2->value = [1]; $mod2->lshift($j); $part1 = $mod1->value != [1] ? parent::slidingWindow($x, $e, $mod1, $class) : new $class(); $part2 = PowerOfTwo::slidingWindow($x, $e, $mod2, $class); $y1 = $mod2->modInverse($mod1); $y2 = $mod1->modInverse($mod2); $result = $part1->multiply($mod2); $result = $result->multiply($y1); $temp = $part2->multiply($mod1); $temp = $temp->multiply($y2); $result = $result->add($temp); list(, $result) = $result->divide($n); return $result; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/OpenSSL.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Math\BigInteger\Engines\PHP; use phpseclib3\Math\BigInteger\Engines\OpenSSL as Progenitor; /** * OpenSSL Modular Exponentiation Engine * * @author Jim Wigginton */ abstract class OpenSSL extends Progenitor { } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Barrett.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Math\BigInteger\Engines\PHP\Reductions; use phpseclib3\Math\BigInteger\Engines\PHP; use phpseclib3\Math\BigInteger\Engines\PHP\Base; /** * PHP Barrett Modular Exponentiation Engine * * @author Jim Wigginton */ abstract class Barrett extends Base { /** * Barrett Modular Reduction * * See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=14 HAC 14.3.3} / * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=165 MPM 6.2.5} for more information. Modified slightly, * so as not to require negative numbers (initially, this script didn't support negative numbers). * * Employs "folding", as described at * {@link http://www.cosic.esat.kuleuven.be/publications/thesis-149.pdf#page=66 thesis-149.pdf#page=66}. To quote from * it, "the idea [behind folding] is to find a value x' such that x (mod m) = x' (mod m), with x' being smaller than x." * * Unfortunately, the "Barrett Reduction with Folding" algorithm described in thesis-149.pdf is not, as written, all that * usable on account of (1) its not using reasonable radix points as discussed in * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=162 MPM 6.2.2} and (2) the fact that, even with reasonable * radix points, it only works when there are an even number of digits in the denominator. The reason for (2) is that * (x >> 1) + (x >> 1) != x / 2 + x / 2. If x is even, they're the same, but if x is odd, they're not. See the in-line * comments for details. * * @param array $n * @param array $m * @param class-string $class * @return array */ protected static function reduce(array $n, array $m, $class) { static $cache = [ self::VARIABLE => [], self::DATA => [] ]; $m_length = count($m); // if (self::compareHelper($n, $static::square($m)) >= 0) { if (count($n) > 2 * $m_length) { $lhs = new $class(); $rhs = new $class(); $lhs->value = $n; $rhs->value = $m; list(, $temp) = $lhs->divide($rhs); return $temp->value; } // if (m.length >> 1) + 2 <= m.length then m is too small and n can't be reduced if ($m_length < 5) { return self::regularBarrett($n, $m, $class); } // n = 2 * m.length $correctionNeeded = false; if ($m_length & 1) { $correctionNeeded = true; array_unshift($n, 0); array_unshift($m, 0); $m_length++; } if (($key = array_search($m, $cache[self::VARIABLE])) === false) { $key = count($cache[self::VARIABLE]); $cache[self::VARIABLE][] = $m; $lhs = new $class(); $lhs_value = &$lhs->value; $lhs_value = self::array_repeat(0, $m_length + ($m_length >> 1)); $lhs_value[] = 1; $rhs = new $class(); $rhs->value = $m; list($u, $m1) = $lhs->divide($rhs); $u = $u->value; $m1 = $m1->value; $cache[self::DATA][] = [ 'u' => $u, // m.length >> 1 (technically (m.length >> 1) + 1) 'm1' => $m1 // m.length ]; } else { $cacheValues = $cache[self::DATA][$key]; $u = $cacheValues['u']; $m1 = $cacheValues['m1']; } $cutoff = $m_length + ($m_length >> 1); $lsd = array_slice($n, 0, $cutoff); // m.length + (m.length >> 1) $msd = array_slice($n, $cutoff); // m.length >> 1 $lsd = self::trim($lsd); $temp = $class::multiplyHelper($msd, false, $m1, false); // m.length + (m.length >> 1) $n = $class::addHelper($lsd, false, $temp[self::VALUE], false); // m.length + (m.length >> 1) + 1 (so basically we're adding two same length numbers) //if ($m_length & 1) { // return self::regularBarrett($n[self::VALUE], $m, $class); //} // (m.length + (m.length >> 1) + 1) - (m.length - 1) == (m.length >> 1) + 2 $temp = array_slice($n[self::VALUE], $m_length - 1); // if even: ((m.length >> 1) + 2) + (m.length >> 1) == m.length + 2 // if odd: ((m.length >> 1) + 2) + (m.length >> 1) == (m.length - 1) + 2 == m.length + 1 // note that these are upper bounds. let's say m.length is 2. then you'd be multiplying a // 3 digit number by a 1 digit number. if you're doing 999 * 9 (in base 10) the result will // be a 4 digit number. but if you're multiplying 111 * 1 then the result will be a 3 digit // number. $temp = $class::multiplyHelper($temp, false, $u, false); // if even: (m.length + 2) - ((m.length >> 1) + 1) = m.length - (m.length >> 1) + 1 // if odd: (m.length + 1) - ((m.length >> 1) + 1) = m.length - (m.length >> 1) $temp = array_slice($temp[self::VALUE], ($m_length >> 1) + 1); // if even: (m.length - (m.length >> 1) + 1) + m.length = 2 * m.length - (m.length >> 1) + 1 // if odd: (m.length - (m.length >> 1)) + m.length = 2 * m.length - (m.length >> 1) $temp = $class::multiplyHelper($temp, false, $m, false); // at this point, if m had an odd number of digits, we'd (probably) be subtracting a 2 * m.length - (m.length >> 1) // digit number from a m.length + (m.length >> 1) + 1 digit number. ie. there'd be an extra digit and the while loop // following this comment would loop a lot (hence our calling _regularBarrett() in that situation). $result = $class::subtractHelper($n[self::VALUE], false, $temp[self::VALUE], false); while (self::compareHelper($result[self::VALUE], $result[self::SIGN], $m, false) >= 0) { $result = $class::subtractHelper($result[self::VALUE], $result[self::SIGN], $m, false); } if ($correctionNeeded) { array_shift($result[self::VALUE]); } return $result[self::VALUE]; } /** * (Regular) Barrett Modular Reduction * * For numbers with more than four digits BigInteger::_barrett() is faster. The difference between that and this * is that this function does not fold the denominator into a smaller form. * * @param array $x * @param array $n * @param string $class * @return array */ private static function regularBarrett(array $x, array $n, $class) { static $cache = [ self::VARIABLE => [], self::DATA => [] ]; $n_length = count($n); if (count($x) > 2 * $n_length) { $lhs = new $class(); $rhs = new $class(); $lhs->value = $x; $rhs->value = $n; list(, $temp) = $lhs->divide($rhs); return $temp->value; } if (($key = array_search($n, $cache[self::VARIABLE])) === false) { $key = count($cache[self::VARIABLE]); $cache[self::VARIABLE][] = $n; $lhs = new $class(); $lhs_value = &$lhs->value; $lhs_value = self::array_repeat(0, 2 * $n_length); $lhs_value[] = 1; $rhs = new $class(); $rhs->value = $n; list($temp, ) = $lhs->divide($rhs); // m.length $cache[self::DATA][] = $temp->value; } // 2 * m.length - (m.length - 1) = m.length + 1 $temp = array_slice($x, $n_length - 1); // (m.length + 1) + m.length = 2 * m.length + 1 $temp = $class::multiplyHelper($temp, false, $cache[self::DATA][$key], false); // (2 * m.length + 1) - (m.length - 1) = m.length + 2 $temp = array_slice($temp[self::VALUE], $n_length + 1); // m.length + 1 $result = array_slice($x, 0, $n_length + 1); // m.length + 1 $temp = self::multiplyLower($temp, false, $n, false, $n_length + 1, $class); // $temp == array_slice($class::regularMultiply($temp, false, $n, false)->value, 0, $n_length + 1) if (self::compareHelper($result, false, $temp[self::VALUE], $temp[self::SIGN]) < 0) { $corrector_value = self::array_repeat(0, $n_length + 1); $corrector_value[count($corrector_value)] = 1; $result = $class::addHelper($result, false, $corrector_value, false); $result = $result[self::VALUE]; } // at this point, we're subtracting a number with m.length + 1 digits from another number with m.length + 1 digits $result = $class::subtractHelper($result, false, $temp[self::VALUE], $temp[self::SIGN]); while (self::compareHelper($result[self::VALUE], $result[self::SIGN], $n, false) > 0) { $result = $class::subtractHelper($result[self::VALUE], $result[self::SIGN], $n, false); } return $result[self::VALUE]; } /** * Performs long multiplication up to $stop digits * * If you're going to be doing array_slice($product->value, 0, $stop), some cycles can be saved. * * @see self::regularBarrett() * @param array $x_value * @param bool $x_negative * @param array $y_value * @param bool $y_negative * @param int $stop * @param string $class * @return array */ private static function multiplyLower(array $x_value, $x_negative, array $y_value, $y_negative, $stop, $class) { $x_length = count($x_value); $y_length = count($y_value); if (!$x_length || !$y_length) { // a 0 is being multiplied return [ self::VALUE => [], self::SIGN => false ]; } if ($x_length < $y_length) { $temp = $x_value; $x_value = $y_value; $y_value = $temp; $x_length = count($x_value); $y_length = count($y_value); } $product_value = self::array_repeat(0, $x_length + $y_length); // the following for loop could be removed if the for loop following it // (the one with nested for loops) initially set $i to 0, but // doing so would also make the result in one set of unnecessary adds, // since on the outermost loops first pass, $product->value[$k] is going // to always be 0 $carry = 0; for ($j = 0; $j < $x_length; ++$j) { // ie. $i = 0, $k = $i $temp = $x_value[$j] * $y_value[0] + $carry; // $product_value[$k] == 0 $carry = $class::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); $product_value[$j] = (int) ($temp - $class::BASE_FULL * $carry); } if ($j < $stop) { $product_value[$j] = $carry; } // the above for loop is what the previous comment was talking about. the // following for loop is the "one with nested for loops" for ($i = 1; $i < $y_length; ++$i) { $carry = 0; for ($j = 0, $k = $i; $j < $x_length && $k < $stop; ++$j, ++$k) { $temp = $product_value[$k] + $x_value[$j] * $y_value[$i] + $carry; $carry = $class::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); $product_value[$k] = (int) ($temp - $class::BASE_FULL * $carry); } if ($k < $stop) { $product_value[$k] = $carry; } } return [ self::VALUE => self::trim($product_value), self::SIGN => $x_negative != $y_negative ]; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Classic.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Math\BigInteger\Engines\PHP\Reductions; use phpseclib3\Math\BigInteger\Engines\PHP\Base; /** * PHP Classic Modular Exponentiation Engine * * @author Jim Wigginton */ abstract class Classic extends Base { /** * Regular Division * * @param array $x * @param array $n * @param string $class * @return array */ protected static function reduce(array $x, array $n, $class) { $lhs = new $class(); $lhs->value = $x; $rhs = new $class(); $rhs->value = $n; list(, $temp) = $lhs->divide($rhs); return $temp->value; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/EvalBarrett.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Math\BigInteger\Engines\PHP\Reductions; use phpseclib3\Math\BigInteger\Engines\PHP; use phpseclib3\Math\BigInteger\Engines\PHP\Base; /** * PHP Dynamic Barrett Modular Exponentiation Engine * * @author Jim Wigginton */ abstract class EvalBarrett extends Base { /** * Custom Reduction Function * * @see self::generateCustomReduction */ private static $custom_reduction; /** * Barrett Modular Reduction * * This calls a dynamically generated loop unrolled function that's specific to a given modulo. * Array lookups are avoided as are if statements testing for how many bits the host OS supports, etc. * * @param array $n * @param array $m * @param string $class * @return array */ protected static function reduce(array $n, array $m, $class) { $inline = self::$custom_reduction; return $inline($n); } /** * Generate Custom Reduction * * @param PHP $m * @param string $class * @return callable */ protected static function generateCustomReduction(PHP $m, $class) { $m_length = count($m->value); if ($m_length < 5) { $code = ' $lhs = new ' . $class . '(); $lhs->value = $x; $rhs = new ' . $class . '(); $rhs->value = [' . implode(',', array_map(self::class . '::float2string', $m->value)) . ']; list(, $temp) = $lhs->divide($rhs); return $temp->value; '; eval('$func = function ($x) { ' . $code . '};'); self::$custom_reduction = $func; //self::$custom_reduction = \Closure::bind($func, $m, $class); return $func; } $correctionNeeded = false; if ($m_length & 1) { $correctionNeeded = true; $m = clone $m; array_unshift($m->value, 0); $m_length++; } $lhs = new $class(); $lhs_value = &$lhs->value; $lhs_value = self::array_repeat(0, $m_length + ($m_length >> 1)); $lhs_value[] = 1; $rhs = new $class(); list($u, $m1) = $lhs->divide($m); if ($class::BASE != 26) { $u = $u->value; } else { $lhs_value = self::array_repeat(0, 2 * $m_length); $lhs_value[] = 1; $rhs = new $class(); list($u) = $lhs->divide($m); $u = $u->value; } $m = $m->value; $m1 = $m1->value; $cutoff = count($m) + (count($m) >> 1); $code = $correctionNeeded ? 'array_unshift($n, 0);' : ''; $code .= ' if (count($n) > ' . (2 * count($m)) . ') { $lhs = new ' . $class . '(); $rhs = new ' . $class . '(); $lhs->value = $n; $rhs->value = [' . implode(',', array_map(self::class . '::float2string', $m)) . ']; list(, $temp) = $lhs->divide($rhs); return $temp->value; } $lsd = array_slice($n, 0, ' . $cutoff . '); $msd = array_slice($n, ' . $cutoff . ');'; $code .= self::generateInlineTrim('msd'); $code .= self::generateInlineMultiply('msd', $m1, 'temp', $class); $code .= self::generateInlineAdd('lsd', 'temp', 'n', $class); $code .= '$temp = array_slice($n, ' . (count($m) - 1) . ');'; $code .= self::generateInlineMultiply('temp', $u, 'temp2', $class); $code .= self::generateInlineTrim('temp2'); $code .= $class::BASE == 26 ? '$temp = array_slice($temp2, ' . (count($m) + 1) . ');' : '$temp = array_slice($temp2, ' . ((count($m) >> 1) + 1) . ');'; $code .= self::generateInlineMultiply('temp', $m, 'temp2', $class); $code .= self::generateInlineTrim('temp2'); /* if ($class::BASE == 26) { $code.= '$n = array_slice($n, 0, ' . (count($m) + 1) . '); $temp2 = array_slice($temp2, 0, ' . (count($m) + 1) . ');'; } */ $code .= self::generateInlineSubtract2('n', 'temp2', 'temp', $class); $subcode = self::generateInlineSubtract1('temp', $m, 'temp2', $class); $subcode .= '$temp = $temp2;'; $code .= self::generateInlineCompare($m, 'temp', $subcode); if ($correctionNeeded) { $code .= 'array_shift($temp);'; } $code .= 'return $temp;'; eval('$func = function ($n) { ' . $code . '};'); self::$custom_reduction = $func; return $func; //self::$custom_reduction = \Closure::bind($func, $m, $class); } /** * Inline Trim * * Removes leading zeros * * @param string $name * @return string */ private static function generateInlineTrim($name) { return ' for ($i = count($' . $name . ') - 1; $i >= 0; --$i) { if ($' . $name . '[$i]) { break; } unset($' . $name . '[$i]); }'; } /** * Inline Multiply (unknown, known) * * @param string $input * @param array $arr * @param string $output * @param string $class * @return string */ private static function generateInlineMultiply($input, array $arr, $output, $class) { if (!count($arr)) { return 'return [];'; } $regular = ' $length = count($' . $input . '); if (!$length) { $' . $output . ' = []; }else{ $' . $output . ' = array_fill(0, $length + ' . count($arr) . ', 0); $carry = 0;'; for ($i = 0; $i < count($arr); $i++) { $regular .= ' $subtemp = $' . $input . '[0] * ' . $arr[$i]; $regular .= $i ? ' + $carry;' : ';'; $regular .= '$carry = '; $regular .= $class::BASE === 26 ? 'intval($subtemp / 0x4000000);' : '$subtemp >> 31;'; $regular .= '$' . $output . '[' . $i . '] = '; if ($class::BASE === 26) { $regular .= '(int) ('; } $regular .= '$subtemp - ' . $class::BASE_FULL . ' * $carry'; $regular .= $class::BASE === 26 ? ');' : ';'; } $regular .= '$' . $output . '[' . count($arr) . '] = $carry;'; $regular .= ' for ($i = 1; $i < $length; ++$i) {'; for ($j = 0; $j < count($arr); $j++) { $regular .= $j ? '$k++;' : '$k = $i;'; $regular .= ' $subtemp = $' . $output . '[$k] + $' . $input . '[$i] * ' . $arr[$j]; $regular .= $j ? ' + $carry;' : ';'; $regular .= '$carry = '; $regular .= $class::BASE === 26 ? 'intval($subtemp / 0x4000000);' : '$subtemp >> 31;'; $regular .= '$' . $output . '[$k] = '; if ($class::BASE === 26) { $regular .= '(int) ('; } $regular .= '$subtemp - ' . $class::BASE_FULL . ' * $carry'; $regular .= $class::BASE === 26 ? ');' : ';'; } $regular .= '$' . $output . '[++$k] = $carry; $carry = 0;'; $regular .= '}}'; //if (count($arr) < 2 * self::KARATSUBA_CUTOFF) { //} return $regular; } /** * Inline Addition * * @param string $x * @param string $y * @param string $result * @param string $class * @return string */ private static function generateInlineAdd($x, $y, $result, $class) { $code = ' $length = max(count($' . $x . '), count($' . $y . ')); $' . $result . ' = array_pad($' . $x . ', $length + 1, 0); $_' . $y . ' = array_pad($' . $y . ', $length, 0); $carry = 0; for ($i = 0, $j = 1; $j < $length; $i+=2, $j+=2) { $sum = ($' . $result . '[$j] + $_' . $y . '[$j]) * ' . $class::BASE_FULL . ' + $' . $result . '[$i] + $_' . $y . '[$i] + $carry; $carry = $sum >= ' . self::float2string($class::MAX_DIGIT2) . '; $sum = $carry ? $sum - ' . self::float2string($class::MAX_DIGIT2) . ' : $sum;'; $code .= $class::BASE === 26 ? '$upper = intval($sum / 0x4000000); $' . $result . '[$i] = (int) ($sum - ' . $class::BASE_FULL . ' * $upper);' : '$upper = $sum >> 31; $' . $result . '[$i] = $sum - ' . $class::BASE_FULL . ' * $upper;'; $code .= ' $' . $result . '[$j] = $upper; } if ($j == $length) { $sum = $' . $result . '[$i] + $_' . $y . '[$i] + $carry; $carry = $sum >= ' . self::float2string($class::BASE_FULL) . '; $' . $result . '[$i] = $carry ? $sum - ' . self::float2string($class::BASE_FULL) . ' : $sum; ++$i; } if ($carry) { for (; $' . $result . '[$i] == ' . $class::MAX_DIGIT . '; ++$i) { $' . $result . '[$i] = 0; } ++$' . $result . '[$i]; }'; $code .= self::generateInlineTrim($result); return $code; } /** * Inline Subtraction 2 * * For when $known is more digits than $unknown. This is the harder use case to optimize for. * * @param string $known * @param string $unknown * @param string $result * @param string $class * @return string */ private static function generateInlineSubtract2($known, $unknown, $result, $class) { $code = ' $' . $result . ' = $' . $known . '; $carry = 0; $size = count($' . $unknown . '); for ($i = 0, $j = 1; $j < $size; $i+= 2, $j+= 2) { $sum = ($' . $known . '[$j] - $' . $unknown . '[$j]) * ' . $class::BASE_FULL . ' + $' . $known . '[$i] - $' . $unknown . '[$i] - $carry; $carry = $sum < 0; if ($carry) { $sum+= ' . self::float2string($class::MAX_DIGIT2) . '; } $subtemp = '; $code .= $class::BASE === 26 ? 'intval($sum / 0x4000000);' : '$sum >> 31;'; $code .= '$' . $result . '[$i] = '; if ($class::BASE === 26) { $code .= '(int) ('; } $code .= '$sum - ' . $class::BASE_FULL . ' * $subtemp'; if ($class::BASE === 26) { $code .= ')'; } $code .= '; $' . $result . '[$j] = $subtemp; } if ($j == $size) { $sum = $' . $known . '[$i] - $' . $unknown . '[$i] - $carry; $carry = $sum < 0; $' . $result . '[$i] = $carry ? $sum + ' . $class::BASE_FULL . ' : $sum; ++$i; } if ($carry) { for (; !$' . $result . '[$i]; ++$i) { $' . $result . '[$i] = ' . $class::MAX_DIGIT . '; } --$' . $result . '[$i]; }'; $code .= self::generateInlineTrim($result); return $code; } /** * Inline Subtraction 1 * * For when $unknown is more digits than $known. This is the easier use case to optimize for. * * @param string $unknown * @param array $known * @param string $result * @param string $class * @return string */ private static function generateInlineSubtract1($unknown, array $known, $result, $class) { $code = '$' . $result . ' = $' . $unknown . ';'; for ($i = 0, $j = 1; $j < count($known); $i += 2, $j += 2) { $code .= '$sum = $' . $unknown . '[' . $j . '] * ' . $class::BASE_FULL . ' + $' . $unknown . '[' . $i . '] - '; $code .= self::float2string($known[$j] * $class::BASE_FULL + $known[$i]); if ($i != 0) { $code .= ' - $carry'; } $code .= '; if ($carry = $sum < 0) { $sum+= ' . self::float2string($class::MAX_DIGIT2) . '; } $subtemp = '; $code .= $class::BASE === 26 ? 'intval($sum / 0x4000000);' : '$sum >> 31;'; $code .= ' $' . $result . '[' . $i . '] = '; if ($class::BASE === 26) { $code .= ' (int) ('; } $code .= '$sum - ' . $class::BASE_FULL . ' * $subtemp'; if ($class::BASE === 26) { $code .= ')'; } $code .= '; $' . $result . '[' . $j . '] = $subtemp;'; } $code .= '$i = ' . $i . ';'; if ($j == count($known)) { $code .= ' $sum = $' . $unknown . '[' . $i . '] - ' . $known[$i] . ' - $carry; $carry = $sum < 0; $' . $result . '[' . $i . '] = $carry ? $sum + ' . $class::BASE_FULL . ' : $sum; ++$i;'; } $code .= ' if ($carry) { for (; !$' . $result . '[$i]; ++$i) { $' . $result . '[$i] = ' . $class::MAX_DIGIT . '; } --$' . $result . '[$i]; }'; $code .= self::generateInlineTrim($result); return $code; } /** * Inline Comparison * * If $unknown >= $known then loop * * @param array $known * @param string $unknown * @param string $subcode * @return string */ private static function generateInlineCompare(array $known, $unknown, $subcode) { $uniqid = uniqid(); $code = 'loop_' . $uniqid . ': $clength = count($' . $unknown . '); switch (true) { case $clength < ' . count($known) . ': goto end_' . $uniqid . '; case $clength > ' . count($known) . ':'; for ($i = count($known) - 1; $i >= 0; $i--) { $code .= ' case $' . $unknown . '[' . $i . '] > ' . $known[$i] . ': goto subcode_' . $uniqid . '; case $' . $unknown . '[' . $i . '] < ' . $known[$i] . ': goto end_' . $uniqid . ';'; } $code .= ' default: // do subcode } subcode_' . $uniqid . ':' . $subcode . ' goto loop_' . $uniqid . '; end_' . $uniqid . ':'; return $code; } /** * Convert a float to a string * * If you do echo floatval(pow(2, 52)) you'll get 4.6116860184274E+18. It /can/ be displayed without a loss of * precision but displayed in this way there will be precision loss, hence the need for this method. * * @param int|float $num * @return string */ private static function float2string($num) { if (!is_float($num)) { return (string) $num; } if ($num < 0) { return '-' . self::float2string(abs($num)); } $temp = ''; while ($num) { $temp = fmod($num, 10) . $temp; $num = floor($num / 10); } return $temp; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Montgomery.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Math\BigInteger\Engines\PHP\Reductions; use phpseclib3\Math\BigInteger\Engines\PHP\Montgomery as Progenitor; /** * PHP Montgomery Modular Exponentiation Engine * * @author Jim Wigginton */ abstract class Montgomery extends Progenitor { /** * Prepare a number for use in Montgomery Modular Reductions * * @param array $x * @param array $n * @param string $class * @return array */ protected static function prepareReduce(array $x, array $n, $class) { $lhs = new $class(); $lhs->value = array_merge(self::array_repeat(0, count($n)), $x); $rhs = new $class(); $rhs->value = $n; list(, $temp) = $lhs->divide($rhs); return $temp->value; } /** * Montgomery Multiply * * Interleaves the montgomery reduction and long multiplication algorithms together as described in * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=13 HAC 14.36} * * @param array $x * @param array $n * @param string $class * @return array */ protected static function reduce(array $x, array $n, $class) { static $cache = [ self::VARIABLE => [], self::DATA => [] ]; if (($key = array_search($n, $cache[self::VARIABLE])) === false) { $key = count($cache[self::VARIABLE]); $cache[self::VARIABLE][] = $x; $cache[self::DATA][] = self::modInverse67108864($n, $class); } $k = count($n); $result = [self::VALUE => $x]; for ($i = 0; $i < $k; ++$i) { $temp = $result[self::VALUE][$i] * $cache[self::DATA][$key]; $temp = $temp - $class::BASE_FULL * ($class::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31)); $temp = $class::regularMultiply([$temp], $n); $temp = array_merge(self::array_repeat(0, $i), $temp); $result = $class::addHelper($result[self::VALUE], false, $temp, false); } $result[self::VALUE] = array_slice($result[self::VALUE], $k); if (self::compareHelper($result, false, $n, false) >= 0) { $result = $class::subtractHelper($result[self::VALUE], false, $n, false); } return $result[self::VALUE]; } /** * Modular Inverse of a number mod 2**26 (eg. 67108864) * * Based off of the bnpInvDigit function implemented and justified in the following URL: * * {@link http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn.js} * * The following URL provides more info: * * {@link http://groups.google.com/group/sci.crypt/msg/7a137205c1be7d85} * * As for why we do all the bitmasking... strange things can happen when converting from floats to ints. For * instance, on some computers, var_dump((int) -4294967297) yields int(-1) and on others, it yields * int(-2147483648). To avoid problems stemming from this, we use bitmasks to guarantee that ints aren't * auto-converted to floats. The outermost bitmask is present because without it, there's no guarantee that * the "residue" returned would be the so-called "common residue". We use fmod, in the last step, because the * maximum possible $x is 26 bits and the maximum $result is 16 bits. Thus, we have to be able to handle up to * 40 bits, which only 64-bit floating points will support. * * Thanks to Pedro Gimeno Fortea for input! * * @param array $x * @param string $class * @return int */ protected static function modInverse67108864(array $x, $class) // 2**26 == 67,108,864 { $x = -$x[0]; $result = $x & 0x3; // x**-1 mod 2**2 $result = ($result * (2 - $x * $result)) & 0xF; // x**-1 mod 2**4 $result = ($result * (2 - ($x & 0xFF) * $result)) & 0xFF; // x**-1 mod 2**8 $result = ($result * ((2 - ($x & 0xFFFF) * $result) & 0xFFFF)) & 0xFFFF; // x**-1 mod 2**16 $result = $class::BASE == 26 ? fmod($result * (2 - fmod($x * $result, $class::BASE_FULL)), $class::BASE_FULL) : // x**-1 mod 2**26 ($result * (2 - ($x * $result) % $class::BASE_FULL)) % $class::BASE_FULL; return $result & $class::MAX_DIGIT; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/MontgomeryMult.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Math\BigInteger\Engines\PHP\Reductions; use phpseclib3\Math\BigInteger\Engines\PHP; /** * PHP Montgomery Modular Exponentiation Engine with interleaved multiplication * * @author Jim Wigginton */ abstract class MontgomeryMult extends Montgomery { /** * Montgomery Multiply * * Interleaves the montgomery reduction and long multiplication algorithms together as described in * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=13 HAC 14.36} * * @see self::_prepMontgomery() * @see self::_montgomery() * @param array $x * @param array $y * @param array $m * @param class-string $class * @return array */ public static function multiplyReduce(array $x, array $y, array $m, $class) { // the following code, although not callable, can be run independently of the above code // although the above code performed better in my benchmarks the following could might // perform better under different circumstances. in lieu of deleting it it's just been // made uncallable static $cache = [ self::VARIABLE => [], self::DATA => [] ]; if (($key = array_search($m, $cache[self::VARIABLE])) === false) { $key = count($cache[self::VARIABLE]); $cache[self::VARIABLE][] = $m; $cache[self::DATA][] = self::modInverse67108864($m, $class); } $n = max(count($x), count($y), count($m)); $x = array_pad($x, $n, 0); $y = array_pad($y, $n, 0); $m = array_pad($m, $n, 0); $a = [self::VALUE => self::array_repeat(0, $n + 1)]; for ($i = 0; $i < $n; ++$i) { $temp = $a[self::VALUE][0] + $x[$i] * $y[0]; $temp = $temp - $class::BASE_FULL * ($class::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31)); $temp = $temp * $cache[self::DATA][$key]; $temp = $temp - $class::BASE_FULL * ($class::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31)); $temp = $class::addHelper($class::regularMultiply([$x[$i]], $y), false, $class::regularMultiply([$temp], $m), false); $a = $class::addHelper($a[self::VALUE], false, $temp[self::VALUE], false); $a[self::VALUE] = array_slice($a[self::VALUE], 1); } if (self::compareHelper($a[self::VALUE], false, $m, false) >= 0) { $a = $class::subtractHelper($a[self::VALUE], false, $m, false); } return $a[self::VALUE]; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/PowerOfTwo.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Math\BigInteger\Engines\PHP\Reductions; use phpseclib3\Math\BigInteger\Engines\PHP\Base; /** * PHP Power Of Two Modular Exponentiation Engine * * @author Jim Wigginton */ abstract class PowerOfTwo extends Base { /** * Prepare a number for use in Montgomery Modular Reductions * * @param array $x * @param array $n * @param string $class * @return array */ protected static function prepareReduce(array $x, array $n, $class) { return self::reduce($x, $n, $class); } /** * Power Of Two Reduction * * @param array $x * @param array $n * @param string $class * @return array */ protected static function reduce(array $x, array $n, $class) { $lhs = new $class(); $lhs->value = $x; $rhs = new $class(); $rhs->value = $n; $temp = new $class(); $temp->value = [1]; $result = $lhs->bitwise_and($rhs->subtract($temp)); return $result->value; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Math\BigInteger\Engines; use phpseclib3\Common\Functions\Strings; use phpseclib3\Exception\BadConfigurationException; /** * Pure-PHP Engine. * * @author Jim Wigginton */ abstract class PHP extends Engine { /**#@+ * Array constants * * Rather than create a thousands and thousands of new BigInteger objects in repeated function calls to add() and * multiply() or whatever, we'll just work directly on arrays, taking them in as parameters and returning them. * */ /** * $result[self::VALUE] contains the value. */ const VALUE = 0; /** * $result[self::SIGN] contains the sign. */ const SIGN = 1; /**#@-*/ /** * Karatsuba Cutoff * * At what point do we switch between Karatsuba multiplication and schoolbook long multiplication? * */ const KARATSUBA_CUTOFF = 25; /** * Can Bitwise operations be done fast? * * @see parent::bitwise_leftRotate() * @see parent::bitwise_rightRotate() */ const FAST_BITWISE = true; /** * Engine Directory * * @see parent::setModExpEngine */ const ENGINE_DIR = 'PHP'; /** * Default constructor * * @param mixed $x integer Base-10 number or base-$base number if $base set. * @param int $base * @return PHP * @see parent::__construct() */ public function __construct($x = 0, $base = 10) { if (!isset(static::$isValidEngine[static::class])) { static::$isValidEngine[static::class] = static::isValidEngine(); } if (!static::$isValidEngine[static::class]) { throw new BadConfigurationException(static::class . ' is not setup correctly on this system'); } $this->value = []; parent::__construct($x, $base); } /** * Initialize a PHP BigInteger Engine instance * * @param int $base * @see parent::__construct() */ protected function initialize($base) { switch (abs($base)) { case 16: $x = (strlen($this->value) & 1) ? '0' . $this->value : $this->value; $temp = new static(Strings::hex2bin($x), 256); $this->value = $temp->value; break; case 10: $temp = new static(); $multiplier = new static(); $multiplier->value = [static::MAX10]; $x = $this->value; if ($x[0] == '-') { $this->is_negative = true; $x = substr($x, 1); } $x = str_pad( $x, strlen($x) + ((static::MAX10LEN - 1) * strlen($x)) % static::MAX10LEN, 0, STR_PAD_LEFT ); while (strlen($x)) { $temp = $temp->multiply($multiplier); $temp = $temp->add(new static($this->int2bytes(substr($x, 0, static::MAX10LEN)), 256)); $x = substr($x, static::MAX10LEN); } $this->value = $temp->value; } } /** * Pads strings so that unpack may be used on them * * @param string $str * @return string */ protected function pad($str) { $length = strlen($str); $pad = 4 - (strlen($str) % 4); return str_pad($str, $length + $pad, "\0", STR_PAD_LEFT); } /** * Converts a BigInteger to a base-10 number. * * @return string */ public function toString() { if (!count($this->value)) { return '0'; } $temp = clone $this; $temp->bitmask = false; $temp->is_negative = false; $divisor = new static(); $divisor->value = [static::MAX10]; $result = ''; while (count($temp->value)) { list($temp, $mod) = $temp->divide($divisor); $result = str_pad( isset($mod->value[0]) ? $mod->value[0] : '', static::MAX10LEN, '0', STR_PAD_LEFT ) . $result; } $result = ltrim($result, '0'); if (empty($result)) { $result = '0'; } if ($this->is_negative) { $result = '-' . $result; } return $result; } /** * Converts a BigInteger to a byte string (eg. base-256). * * @param bool $twos_compliment * @return string */ public function toBytes($twos_compliment = false) { if ($twos_compliment) { return $this->toBytesHelper(); } if (!count($this->value)) { return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : ''; } $result = $this->bitwise_small_split(8); $result = implode('', array_map('chr', $result)); return $this->precision > 0 ? str_pad( substr($result, -(($this->precision + 7) >> 3)), ($this->precision + 7) >> 3, chr(0), STR_PAD_LEFT ) : $result; } /** * Performs addition. * * @param array $x_value * @param bool $x_negative * @param array $y_value * @param bool $y_negative * @return array */ protected static function addHelper(array $x_value, $x_negative, array $y_value, $y_negative) { $x_size = count($x_value); $y_size = count($y_value); if ($x_size == 0) { return [ self::VALUE => $y_value, self::SIGN => $y_negative ]; } elseif ($y_size == 0) { return [ self::VALUE => $x_value, self::SIGN => $x_negative ]; } // subtract, if appropriate if ($x_negative != $y_negative) { if ($x_value == $y_value) { return [ self::VALUE => [], self::SIGN => false ]; } $temp = self::subtractHelper($x_value, false, $y_value, false); $temp[self::SIGN] = self::compareHelper($x_value, false, $y_value, false) > 0 ? $x_negative : $y_negative; return $temp; } if ($x_size < $y_size) { $size = $x_size; $value = $y_value; } else { $size = $y_size; $value = $x_value; } $value[count($value)] = 0; // just in case the carry adds an extra digit $carry = 0; for ($i = 0, $j = 1; $j < $size; $i += 2, $j += 2) { //$sum = $x_value[$j] * static::BASE_FULL + $x_value[$i] + $y_value[$j] * static::BASE_FULL + $y_value[$i] + $carry; $sum = ($x_value[$j] + $y_value[$j]) * static::BASE_FULL + $x_value[$i] + $y_value[$i] + $carry; $carry = $sum >= static::MAX_DIGIT2; // eg. floor($sum / 2**52); only possible values (in any base) are 0 and 1 $sum = $carry ? $sum - static::MAX_DIGIT2 : $sum; $temp = static::BASE === 26 ? intval($sum / 0x4000000) : ($sum >> 31); $value[$i] = (int)($sum - static::BASE_FULL * $temp); // eg. a faster alternative to fmod($sum, 0x4000000) $value[$j] = $temp; } if ($j == $size) { // ie. if $y_size is odd $sum = $x_value[$i] + $y_value[$i] + $carry; $carry = $sum >= static::BASE_FULL; $value[$i] = $carry ? $sum - static::BASE_FULL : $sum; ++$i; // ie. let $i = $j since we've just done $value[$i] } if ($carry) { for (; $value[$i] == static::MAX_DIGIT; ++$i) { $value[$i] = 0; } ++$value[$i]; } return [ self::VALUE => self::trim($value), self::SIGN => $x_negative ]; } /** * Performs subtraction. * * @param array $x_value * @param bool $x_negative * @param array $y_value * @param bool $y_negative * @return array */ public static function subtractHelper(array $x_value, $x_negative, array $y_value, $y_negative) { $x_size = count($x_value); $y_size = count($y_value); if ($x_size == 0) { return [ self::VALUE => $y_value, self::SIGN => !$y_negative ]; } elseif ($y_size == 0) { return [ self::VALUE => $x_value, self::SIGN => $x_negative ]; } // add, if appropriate (ie. -$x - +$y or +$x - -$y) if ($x_negative != $y_negative) { $temp = self::addHelper($x_value, false, $y_value, false); $temp[self::SIGN] = $x_negative; return $temp; } $diff = self::compareHelper($x_value, $x_negative, $y_value, $y_negative); if (!$diff) { return [ self::VALUE => [], self::SIGN => false ]; } // switch $x and $y around, if appropriate. if ((!$x_negative && $diff < 0) || ($x_negative && $diff > 0)) { $temp = $x_value; $x_value = $y_value; $y_value = $temp; $x_negative = !$x_negative; $x_size = count($x_value); $y_size = count($y_value); } // at this point, $x_value should be at least as big as - if not bigger than - $y_value $carry = 0; for ($i = 0, $j = 1; $j < $y_size; $i += 2, $j += 2) { $sum = ($x_value[$j] - $y_value[$j]) * static::BASE_FULL + $x_value[$i] - $y_value[$i] - $carry; $carry = $sum < 0; // eg. floor($sum / 2**52); only possible values (in any base) are 0 and 1 $sum = $carry ? $sum + static::MAX_DIGIT2 : $sum; $temp = static::BASE === 26 ? intval($sum / 0x4000000) : ($sum >> 31); $x_value[$i] = (int)($sum - static::BASE_FULL * $temp); $x_value[$j] = $temp; } if ($j == $y_size) { // ie. if $y_size is odd $sum = $x_value[$i] - $y_value[$i] - $carry; $carry = $sum < 0; $x_value[$i] = $carry ? $sum + static::BASE_FULL : $sum; ++$i; } if ($carry) { for (; !$x_value[$i]; ++$i) { $x_value[$i] = static::MAX_DIGIT; } --$x_value[$i]; } return [ self::VALUE => self::trim($x_value), self::SIGN => $x_negative ]; } /** * Performs multiplication. * * @param array $x_value * @param bool $x_negative * @param array $y_value * @param bool $y_negative * @return array */ protected static function multiplyHelper(array $x_value, $x_negative, array $y_value, $y_negative) { //if ( $x_value == $y_value ) { // return [ // self::VALUE => self::square($x_value), // self::SIGN => $x_sign != $y_value // ]; //} $x_length = count($x_value); $y_length = count($y_value); if (!$x_length || !$y_length) { // a 0 is being multiplied return [ self::VALUE => [], self::SIGN => false ]; } return [ self::VALUE => min($x_length, $y_length) < 2 * self::KARATSUBA_CUTOFF ? self::trim(self::regularMultiply($x_value, $y_value)) : self::trim(self::karatsuba($x_value, $y_value)), self::SIGN => $x_negative != $y_negative ]; } /** * Performs Karatsuba multiplication on two BigIntegers * * See {@link http://en.wikipedia.org/wiki/Karatsuba_algorithm Karatsuba algorithm} and * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=120 MPM 5.2.3}. * * @param array $x_value * @param array $y_value * @return array */ private static function karatsuba(array $x_value, array $y_value) { $m = min(count($x_value) >> 1, count($y_value) >> 1); if ($m < self::KARATSUBA_CUTOFF) { return self::regularMultiply($x_value, $y_value); } $x1 = array_slice($x_value, $m); $x0 = array_slice($x_value, 0, $m); $y1 = array_slice($y_value, $m); $y0 = array_slice($y_value, 0, $m); $z2 = self::karatsuba($x1, $y1); $z0 = self::karatsuba($x0, $y0); $z1 = self::addHelper($x1, false, $x0, false); $temp = self::addHelper($y1, false, $y0, false); $z1 = self::karatsuba($z1[self::VALUE], $temp[self::VALUE]); $temp = self::addHelper($z2, false, $z0, false); $z1 = self::subtractHelper($z1, false, $temp[self::VALUE], false); $z2 = array_merge(array_fill(0, 2 * $m, 0), $z2); $z1[self::VALUE] = array_merge(array_fill(0, $m, 0), $z1[self::VALUE]); $xy = self::addHelper($z2, false, $z1[self::VALUE], $z1[self::SIGN]); $xy = self::addHelper($xy[self::VALUE], $xy[self::SIGN], $z0, false); return $xy[self::VALUE]; } /** * Performs long multiplication on two BigIntegers * * Modeled after 'multiply' in MutableBigInteger.java. * * @param array $x_value * @param array $y_value * @return array */ protected static function regularMultiply(array $x_value, array $y_value) { $x_length = count($x_value); $y_length = count($y_value); if (!$x_length || !$y_length) { // a 0 is being multiplied return []; } $product_value = self::array_repeat(0, $x_length + $y_length); // the following for loop could be removed if the for loop following it // (the one with nested for loops) initially set $i to 0, but // doing so would also make the result in one set of unnecessary adds, // since on the outermost loops first pass, $product->value[$k] is going // to always be 0 $carry = 0; for ($j = 0; $j < $x_length; ++$j) { // ie. $i = 0 $temp = $x_value[$j] * $y_value[0] + $carry; // $product_value[$k] == 0 $carry = static::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); $product_value[$j] = (int)($temp - static::BASE_FULL * $carry); } $product_value[$j] = $carry; // the above for loop is what the previous comment was talking about. the // following for loop is the "one with nested for loops" for ($i = 1; $i < $y_length; ++$i) { $carry = 0; for ($j = 0, $k = $i; $j < $x_length; ++$j, ++$k) { $temp = $product_value[$k] + $x_value[$j] * $y_value[$i] + $carry; $carry = static::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); $product_value[$k] = (int)($temp - static::BASE_FULL * $carry); } $product_value[$k] = $carry; } return $product_value; } /** * Divides two BigIntegers. * * Returns an array whose first element contains the quotient and whose second element contains the * "common residue". If the remainder would be positive, the "common residue" and the remainder are the * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder * and the divisor (basically, the "common residue" is the first positive modulo). * * @return array{static, static} * @internal This function is based off of * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=9 HAC 14.20}. */ protected function divideHelper(PHP $y) { if (count($y->value) == 1) { list($q, $r) = $this->divide_digit($this->value, $y->value[0]); $quotient = new static(); $remainder = new static(); $quotient->value = $q; if ($this->is_negative) { $r = $y->value[0] - $r; } $remainder->value = [$r]; $quotient->is_negative = $this->is_negative != $y->is_negative; return [$this->normalize($quotient), $this->normalize($remainder)]; } $x = clone $this; $y = clone $y; $x_sign = $x->is_negative; $y_sign = $y->is_negative; $x->is_negative = $y->is_negative = false; $diff = $x->compare($y); if (!$diff) { $temp = new static(); $temp->value = [1]; $temp->is_negative = $x_sign != $y_sign; return [$this->normalize($temp), $this->normalize(static::$zero[static::class])]; } if ($diff < 0) { // if $x is negative, "add" $y. if ($x_sign) { $x = $y->subtract($x); } return [$this->normalize(static::$zero[static::class]), $this->normalize($x)]; } // normalize $x and $y as described in HAC 14.23 / 14.24 $msb = $y->value[count($y->value) - 1]; for ($shift = 0; !($msb & static::MSB); ++$shift) { $msb <<= 1; } $x->lshift($shift); $y->lshift($shift); $y_value = &$y->value; $x_max = count($x->value) - 1; $y_max = count($y->value) - 1; $quotient = new static(); $quotient_value = &$quotient->value; $quotient_value = self::array_repeat(0, $x_max - $y_max + 1); static $temp, $lhs, $rhs; if (!isset($temp)) { $temp = new static(); $lhs = new static(); $rhs = new static(); } if (static::class != get_class($temp)) { $temp = new static(); $lhs = new static(); $rhs = new static(); } $temp_value = &$temp->value; $rhs_value = &$rhs->value; // $temp = $y << ($x_max - $y_max-1) in base 2**26 $temp_value = array_merge(self::array_repeat(0, $x_max - $y_max), $y_value); while ($x->compare($temp) >= 0) { // calculate the "common residue" ++$quotient_value[$x_max - $y_max]; $x = $x->subtract($temp); $x_max = count($x->value) - 1; } for ($i = $x_max; $i >= $y_max + 1; --$i) { $x_value = &$x->value; $x_window = [ isset($x_value[$i]) ? $x_value[$i] : 0, isset($x_value[$i - 1]) ? $x_value[$i - 1] : 0, isset($x_value[$i - 2]) ? $x_value[$i - 2] : 0 ]; $y_window = [ $y_value[$y_max], ($y_max > 0) ? $y_value[$y_max - 1] : 0 ]; $q_index = $i - $y_max - 1; if ($x_window[0] == $y_window[0]) { $quotient_value[$q_index] = static::MAX_DIGIT; } else { $quotient_value[$q_index] = self::safe_divide( $x_window[0] * static::BASE_FULL + $x_window[1], $y_window[0] ); } $temp_value = [$y_window[1], $y_window[0]]; $lhs->value = [$quotient_value[$q_index]]; $lhs = $lhs->multiply($temp); $rhs_value = [$x_window[2], $x_window[1], $x_window[0]]; while ($lhs->compare($rhs) > 0) { --$quotient_value[$q_index]; $lhs->value = [$quotient_value[$q_index]]; $lhs = $lhs->multiply($temp); } $adjust = self::array_repeat(0, $q_index); $temp_value = [$quotient_value[$q_index]]; $temp = $temp->multiply($y); $temp_value = &$temp->value; if (count($temp_value)) { $temp_value = array_merge($adjust, $temp_value); } $x = $x->subtract($temp); if ($x->compare(static::$zero[static::class]) < 0) { $temp_value = array_merge($adjust, $y_value); $x = $x->add($temp); --$quotient_value[$q_index]; } $x_max = count($x_value) - 1; } // unnormalize the remainder $x->rshift($shift); $quotient->is_negative = $x_sign != $y_sign; // calculate the "common residue", if appropriate if ($x_sign) { $y->rshift($shift); $x = $y->subtract($x); } return [$this->normalize($quotient), $this->normalize($x)]; } /** * Divides a BigInteger by a regular integer * * abc / x = a00 / x + b0 / x + c / x * * @param array $dividend * @param int $divisor * @return array */ private static function divide_digit(array $dividend, $divisor) { $carry = 0; $result = []; for ($i = count($dividend) - 1; $i >= 0; --$i) { $temp = static::BASE_FULL * $carry + $dividend[$i]; $result[$i] = self::safe_divide($temp, $divisor); $carry = (int)($temp - $divisor * $result[$i]); } return [$result, $carry]; } /** * Single digit division * * Even if int64 is being used the division operator will return a float64 value * if the dividend is not evenly divisible by the divisor. Since a float64 doesn't * have the precision of int64 this is a problem so, when int64 is being used, * we'll guarantee that the dividend is divisible by first subtracting the remainder. * * @param int $x * @param int $y * @return int */ private static function safe_divide($x, $y) { if (static::BASE === 26) { return (int)($x / $y); } // static::BASE === 31 /** @var int */ return ($x - ($x % $y)) / $y; } /** * Convert an array / boolean to a PHP BigInteger object * * @param array $arr * @return static */ protected function convertToObj(array $arr) { $result = new static(); $result->value = $arr[self::VALUE]; $result->is_negative = $arr[self::SIGN]; return $this->normalize($result); } /** * Normalize * * Removes leading zeros and truncates (if necessary) to maintain the appropriate precision * * @param PHP $result * @return static */ protected function normalize(PHP $result) { $result->precision = $this->precision; $result->bitmask = $this->bitmask; $value = &$result->value; if (!count($value)) { $result->is_negative = false; return $result; } $value = static::trim($value); if (!empty($result->bitmask->value)) { $length = min(count($value), count($result->bitmask->value)); $value = array_slice($value, 0, $length); for ($i = 0; $i < $length; ++$i) { $value[$i] = $value[$i] & $result->bitmask->value[$i]; } $value = static::trim($value); } return $result; } /** * Compares two numbers. * * @param array $x_value * @param bool $x_negative * @param array $y_value * @param bool $y_negative * @return int * @see static::compare() */ protected static function compareHelper(array $x_value, $x_negative, array $y_value, $y_negative) { if ($x_negative != $y_negative) { return (!$x_negative && $y_negative) ? 1 : -1; } $result = $x_negative ? -1 : 1; if (count($x_value) != count($y_value)) { return (count($x_value) > count($y_value)) ? $result : -$result; } $size = max(count($x_value), count($y_value)); $x_value = array_pad($x_value, $size, 0); $y_value = array_pad($y_value, $size, 0); for ($i = count($x_value) - 1; $i >= 0; --$i) { if ($x_value[$i] != $y_value[$i]) { return ($x_value[$i] > $y_value[$i]) ? $result : -$result; } } return 0; } /** * Absolute value. * * @return PHP */ public function abs() { $temp = new static(); $temp->value = $this->value; return $temp; } /** * Trim * * Removes leading zeros * * @param list $value * @return list */ protected static function trim(array $value) { for ($i = count($value) - 1; $i >= 0; --$i) { if ($value[$i]) { break; } unset($value[$i]); } return $value; } /** * Logical Right Shift * * Shifts BigInteger's by $shift bits, effectively dividing by 2**$shift. * * @param int $shift * @return PHP */ public function bitwise_rightShift($shift) { $temp = new static(); // could just replace lshift with this, but then all lshift() calls would need to be rewritten // and I don't want to do that... $temp->value = $this->value; $temp->rshift($shift); return $this->normalize($temp); } /** * Logical Left Shift * * Shifts BigInteger's by $shift bits, effectively multiplying by 2**$shift. * * @param int $shift * @return PHP */ public function bitwise_leftShift($shift) { $temp = new static(); // could just replace _rshift with this, but then all _lshift() calls would need to be rewritten // and I don't want to do that... $temp->value = $this->value; $temp->lshift($shift); return $this->normalize($temp); } /** * Converts 32-bit integers to bytes. * * @param int $x * @return string */ private static function int2bytes($x) { return ltrim(pack('N', $x), chr(0)); } /** * Array Repeat * * @param int $input * @param int $multiplier * @return array */ protected static function array_repeat($input, $multiplier) { return $multiplier ? array_fill(0, $multiplier, $input) : []; } /** * Logical Left Shift * * Shifts BigInteger's by $shift bits. * * @param int $shift */ protected function lshift($shift) { if ($shift == 0) { return; } $num_digits = (int)($shift / static::BASE); $shift %= static::BASE; $shift = 1 << $shift; $carry = 0; for ($i = 0; $i < count($this->value); ++$i) { $temp = $this->value[$i] * $shift + $carry; $carry = static::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); $this->value[$i] = (int)($temp - $carry * static::BASE_FULL); } if ($carry) { $this->value[count($this->value)] = $carry; } while ($num_digits--) { array_unshift($this->value, 0); } } /** * Logical Right Shift * * Shifts BigInteger's by $shift bits. * * @param int $shift */ protected function rshift($shift) { if ($shift == 0) { return; } $num_digits = (int)($shift / static::BASE); $shift %= static::BASE; $carry_shift = static::BASE - $shift; $carry_mask = (1 << $shift) - 1; if ($num_digits) { $this->value = array_slice($this->value, $num_digits); } $carry = 0; for ($i = count($this->value) - 1; $i >= 0; --$i) { $temp = $this->value[$i] >> $shift | $carry; $carry = ($this->value[$i] & $carry_mask) << $carry_shift; $this->value[$i] = $temp; } $this->value = static::trim($this->value); } /** * Performs modular exponentiation. * * @param PHP $e * @param PHP $n * @return PHP */ protected function powModInner(PHP $e, PHP $n) { try { $class = static::$modexpEngine[static::class]; return $class::powModHelper($this, $e, $n, static::class); } catch (\Exception $err) { return PHP\DefaultEngine::powModHelper($this, $e, $n, static::class); } } /** * Performs squaring * * @param list $x * @return list */ protected static function square(array $x) { return count($x) < 2 * self::KARATSUBA_CUTOFF ? self::trim(self::baseSquare($x)) : self::trim(self::karatsubaSquare($x)); } /** * Performs traditional squaring on two BigIntegers * * Squaring can be done faster than multiplying a number by itself can be. See * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=7 HAC 14.2.4} / * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=141 MPM 5.3} for more information. * * @param array $value * @return array */ protected static function baseSquare(array $value) { if (empty($value)) { return []; } $square_value = self::array_repeat(0, 2 * count($value)); for ($i = 0, $max_index = count($value) - 1; $i <= $max_index; ++$i) { $i2 = $i << 1; $temp = $square_value[$i2] + $value[$i] * $value[$i]; $carry = static::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); $square_value[$i2] = (int)($temp - static::BASE_FULL * $carry); // note how we start from $i+1 instead of 0 as we do in multiplication. for ($j = $i + 1, $k = $i2 + 1; $j <= $max_index; ++$j, ++$k) { $temp = $square_value[$k] + 2 * $value[$j] * $value[$i] + $carry; $carry = static::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); $square_value[$k] = (int)($temp - static::BASE_FULL * $carry); } // the following line can yield values larger 2**15. at this point, PHP should switch // over to floats. $square_value[$i + $max_index + 1] = $carry; } return $square_value; } /** * Performs Karatsuba "squaring" on two BigIntegers * * See {@link http://en.wikipedia.org/wiki/Karatsuba_algorithm Karatsuba algorithm} and * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=151 MPM 5.3.4}. * * @param array $value * @return array */ protected static function karatsubaSquare(array $value) { $m = count($value) >> 1; if ($m < self::KARATSUBA_CUTOFF) { return self::baseSquare($value); } $x1 = array_slice($value, $m); $x0 = array_slice($value, 0, $m); $z2 = self::karatsubaSquare($x1); $z0 = self::karatsubaSquare($x0); $z1 = self::addHelper($x1, false, $x0, false); $z1 = self::karatsubaSquare($z1[self::VALUE]); $temp = self::addHelper($z2, false, $z0, false); $z1 = self::subtractHelper($z1, false, $temp[self::VALUE], false); $z2 = array_merge(array_fill(0, 2 * $m, 0), $z2); $z1[self::VALUE] = array_merge(array_fill(0, $m, 0), $z1[self::VALUE]); $xx = self::addHelper($z2, false, $z1[self::VALUE], $z1[self::SIGN]); $xx = self::addHelper($xx[self::VALUE], $xx[self::SIGN], $z0, false); return $xx[self::VALUE]; } /** * Make the current number odd * * If the current number is odd it'll be unchanged. If it's even, one will be added to it. * * @see self::randomPrime() */ protected function make_odd() { $this->value[0] |= 1; } /** * Test the number against small primes. * * @see self::isPrime() */ protected function testSmallPrimes() { if ($this->value == [1]) { return false; } if ($this->value == [2]) { return true; } if (~$this->value[0] & 1) { return false; } $value = $this->value; foreach (static::PRIMES as $prime) { list(, $r) = self::divide_digit($value, $prime); if (!$r) { return count($value) == 1 && $value[0] == $prime; } } return true; } /** * Scan for 1 and right shift by that amount * * ie. $s = gmp_scan1($n, 0) and $r = gmp_div_q($n, gmp_pow(gmp_init('2'), $s)); * * @param PHP $r * @return int * @see self::isPrime() */ public static function scan1divide(PHP $r) { $r_value = &$r->value; for ($i = 0, $r_length = count($r_value); $i < $r_length; ++$i) { $temp = ~$r_value[$i] & static::MAX_DIGIT; for ($j = 1; ($temp >> $j) & 1; ++$j) { } if ($j <= static::BASE) { break; } } $s = static::BASE * $i + $j; $r->rshift($s); return $s; } /** * Performs exponentiation. * * @param PHP $n * @return PHP */ protected function powHelper(PHP $n) { if ($n->compare(static::$zero[static::class]) == 0) { return new static(1); } // n^0 = 1 $temp = clone $this; while (!$n->equals(static::$one[static::class])) { $temp = $temp->multiply($this); $n = $n->subtract(static::$one[static::class]); } return $temp; } /** * Is Odd? * * @return bool */ public function isOdd() { return (bool)($this->value[0] & 1); } /** * Tests if a bit is set * * @return bool */ public function testBit($x) { $digit = (int) floor($x / static::BASE); $bit = $x % static::BASE; if (!isset($this->value[$digit])) { return false; } return (bool)($this->value[$digit] & (1 << $bit)); } /** * Is Negative? * * @return bool */ public function isNegative() { return $this->is_negative; } /** * Negate * * Given $k, returns -$k * * @return static */ public function negate() { $temp = clone $this; $temp->is_negative = !$temp->is_negative; return $temp; } /** * Bitwise Split * * Splits BigInteger's into chunks of $split bits * * @param int $split * @return list */ public function bitwise_split($split) { if ($split < 1) { throw new \RuntimeException('Offset must be greater than 1'); } $width = (int)($split / static::BASE); if (!$width) { $arr = $this->bitwise_small_split($split); return array_map(function ($digit) { $temp = new static(); $temp->value = $digit != 0 ? [$digit] : []; return $temp; }, $arr); } $vals = []; $val = $this->value; $i = $overflow = 0; $len = count($val); while ($i < $len) { $digit = []; if (!$overflow) { $digit = array_slice($val, $i, $width); $i += $width; $overflow = $split % static::BASE; if ($overflow) { $mask = (1 << $overflow) - 1; $temp = isset($val[$i]) ? $val[$i] : 0; $digit[] = $temp & $mask; } } else { $remaining = static::BASE - $overflow; $tempsplit = $split - $remaining; $tempwidth = (int)($tempsplit / static::BASE + 1); $digit = array_slice($val, $i, $tempwidth); $i += $tempwidth; $tempoverflow = $tempsplit % static::BASE; if ($tempoverflow) { $tempmask = (1 << $tempoverflow) - 1; $temp = isset($val[$i]) ? $val[$i] : 0; $digit[] = $temp & $tempmask; } $newbits = 0; for ($j = count($digit) - 1; $j >= 0; $j--) { $temp = $digit[$j] & $mask; $digit[$j] = ($digit[$j] >> $overflow) | ($newbits << $remaining); $newbits = $temp; } $overflow = $tempoverflow; $mask = $tempmask; } $temp = new static(); $temp->value = static::trim($digit); $vals[] = $temp; } return array_reverse($vals); } /** * Bitwise Split where $split < static::BASE * * @param int $split * @return list */ private function bitwise_small_split($split) { $vals = []; $val = $this->value; $mask = (1 << $split) - 1; $i = $overflow = 0; $len = count($val); $val[] = 0; $remaining = static::BASE; while ($i != $len) { $digit = $val[$i] & $mask; $val[$i] >>= $split; if (!$overflow) { $remaining -= $split; $overflow = $split <= $remaining ? 0 : $split - $remaining; if (!$remaining) { $i++; $remaining = static::BASE; $overflow = 0; } } elseif (++$i != $len) { $tempmask = (1 << $overflow) - 1; $digit |= ($val[$i] & $tempmask) << $remaining; $val[$i] >>= $overflow; $remaining = static::BASE - $overflow; $overflow = $split <= $remaining ? 0 : $split - $remaining; } $vals[] = $digit; } while ($vals[count($vals) - 1] == 0) { unset($vals[count($vals) - 1]); } return array_reverse($vals); } /** * @return bool */ protected static function testJITOnWindows() { // see https://github.com/php/php-src/issues/11917 if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' && function_exists('opcache_get_status') && PHP_VERSION_ID < 80213 && !defined('PHPSECLIB_ALLOW_JIT')) { $status = opcache_get_status(); if ($status && isset($status['jit']) && $status['jit']['enabled'] && $status['jit']['on']) { return true; } } return false; } /** * Return the size of a BigInteger in bits * * @return int */ public function getLength() { $max = count($this->value) - 1; return $max != -1 ? $max * static::BASE + intval(ceil(log($this->value[$max] + 1, 2))) : 0; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP32.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Math\BigInteger\Engines; /** * Pure-PHP 32-bit Engine. * * Uses 64-bit floats if int size is 4 bits * * @author Jim Wigginton */ class PHP32 extends PHP { // Constants used by PHP.php const BASE = 26; const BASE_FULL = 0x4000000; const MAX_DIGIT = 0x3FFFFFF; const MSB = 0x2000000; /** * MAX10 in greatest MAX10LEN satisfying * MAX10 = 10**MAX10LEN <= 2**BASE. */ const MAX10 = 10000000; /** * MAX10LEN in greatest MAX10LEN satisfying * MAX10 = 10**MAX10LEN <= 2**BASE. */ const MAX10LEN = 7; const MAX_DIGIT2 = 4503599627370496; /** * Initialize a PHP32 BigInteger Engine instance * * @param int $base * @see parent::initialize() */ protected function initialize($base) { if ($base != 256 && $base != -256) { return parent::initialize($base); } $val = $this->value; $this->value = []; $vals = &$this->value; $i = strlen($val); if (!$i) { return; } while (true) { $i -= 4; if ($i < 0) { if ($i == -4) { break; } $val = substr($val, 0, 4 + $i); $val = str_pad($val, 4, "\0", STR_PAD_LEFT); if ($val == "\0\0\0\0") { break; } $i = 0; } list(, $digit) = unpack('N', substr($val, $i, 4)); if ($digit < 0) { $digit += 0xFFFFFFFF + 1; } $step = count($vals) & 3; if ($step) { $digit = (int) floor($digit / pow(2, 2 * $step)); } if ($step != 3) { $digit = (int) fmod($digit, static::BASE_FULL); $i++; } $vals[] = $digit; } while (end($vals) === 0) { array_pop($vals); } reset($vals); } /** * Test for engine validity * * @see parent::__construct() * @return bool */ public static function isValidEngine() { return PHP_INT_SIZE >= 4 && !self::testJITOnWindows(); } /** * Adds two BigIntegers. * * @param PHP32 $y * @return PHP32 */ public function add(PHP32 $y) { $temp = self::addHelper($this->value, $this->is_negative, $y->value, $y->is_negative); return $this->convertToObj($temp); } /** * Subtracts two BigIntegers. * * @param PHP32 $y * @return PHP32 */ public function subtract(PHP32 $y) { $temp = self::subtractHelper($this->value, $this->is_negative, $y->value, $y->is_negative); return $this->convertToObj($temp); } /** * Multiplies two BigIntegers. * * @param PHP32 $y * @return PHP32 */ public function multiply(PHP32 $y) { $temp = self::multiplyHelper($this->value, $this->is_negative, $y->value, $y->is_negative); return $this->convertToObj($temp); } /** * Divides two BigIntegers. * * Returns an array whose first element contains the quotient and whose second element contains the * "common residue". If the remainder would be positive, the "common residue" and the remainder are the * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder * and the divisor (basically, the "common residue" is the first positive modulo). * * @param PHP32 $y * @return array{PHP32, PHP32} */ public function divide(PHP32 $y) { return $this->divideHelper($y); } /** * Calculates modular inverses. * * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. * @param PHP32 $n * @return false|PHP32 */ public function modInverse(PHP32 $n) { return $this->modInverseHelper($n); } /** * Calculates modular inverses. * * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. * @param PHP32 $n * @return PHP32[] */ public function extendedGCD(PHP32 $n) { return $this->extendedGCDHelper($n); } /** * Calculates the greatest common divisor * * Say you have 693 and 609. The GCD is 21. * * @param PHP32 $n * @return PHP32 */ public function gcd(PHP32 $n) { return $this->extendedGCD($n)['gcd']; } /** * Logical And * * @param PHP32 $x * @return PHP32 */ public function bitwise_and(PHP32 $x) { return $this->bitwiseAndHelper($x); } /** * Logical Or * * @param PHP32 $x * @return PHP32 */ public function bitwise_or(PHP32 $x) { return $this->bitwiseOrHelper($x); } /** * Logical Exclusive Or * * @param PHP32 $x * @return PHP32 */ public function bitwise_xor(PHP32 $x) { return $this->bitwiseXorHelper($x); } /** * Compares two numbers. * * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite. The reason for this is * demonstrated thusly: * * $x > $y: $x->compare($y) > 0 * $x < $y: $x->compare($y) < 0 * $x == $y: $x->compare($y) == 0 * * Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y). * * {@internal Could return $this->subtract($x), but that's not as fast as what we do do.} * * @param PHP32 $y * @return int in case < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal. * @see self::equals() */ public function compare(PHP32 $y) { return $this->compareHelper($this->value, $this->is_negative, $y->value, $y->is_negative); } /** * Tests the equality of two numbers. * * If you need to see if one number is greater than or less than another number, use BigInteger::compare() * * @param PHP32 $x * @return bool */ public function equals(PHP32 $x) { return $this->value === $x->value && $this->is_negative == $x->is_negative; } /** * Performs modular exponentiation. * * @param PHP32 $e * @param PHP32 $n * @return PHP32 */ public function modPow(PHP32 $e, PHP32 $n) { return $this->powModOuter($e, $n); } /** * Performs modular exponentiation. * * Alias for modPow(). * * @param PHP32 $e * @param PHP32 $n * @return PHP32 */ public function powMod(PHP32 $e, PHP32 $n) { return $this->powModOuter($e, $n); } /** * Generate a random prime number between a range * * If there's not a prime within the given range, false will be returned. * * @param PHP32 $min * @param PHP32 $max * @return false|PHP32 */ public static function randomRangePrime(PHP32 $min, PHP32 $max) { return self::randomRangePrimeOuter($min, $max); } /** * Generate a random number between a range * * Returns a random number between $min and $max where $min and $max * can be defined using one of the two methods: * * BigInteger::randomRange($min, $max) * BigInteger::randomRange($max, $min) * * @param PHP32 $min * @param PHP32 $max * @return PHP32 */ public static function randomRange(PHP32 $min, PHP32 $max) { return self::randomRangeHelper($min, $max); } /** * Performs exponentiation. * * @param PHP32 $n * @return PHP32 */ public function pow(PHP32 $n) { return $this->powHelper($n); } /** * Return the minimum BigInteger between an arbitrary number of BigIntegers. * * @param PHP32 ...$nums * @return PHP32 */ public static function min(PHP32 ...$nums) { return self::minHelper($nums); } /** * Return the maximum BigInteger between an arbitrary number of BigIntegers. * * @param PHP32 ...$nums * @return PHP32 */ public static function max(PHP32 ...$nums) { return self::maxHelper($nums); } /** * Tests BigInteger to see if it is between two integers, inclusive * * @param PHP32 $min * @param PHP32 $max * @return bool */ public function between(PHP32 $min, PHP32 $max) { return $this->compare($min) >= 0 && $this->compare($max) <= 0; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP64.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Math\BigInteger\Engines; /** * Pure-PHP 64-bit Engine. * * Uses 64-bit integers if int size is 8 bits * * @author Jim Wigginton */ class PHP64 extends PHP { // Constants used by PHP.php const BASE = 31; const BASE_FULL = 0x80000000; const MAX_DIGIT = 0x7FFFFFFF; const MSB = 0x40000000; /** * MAX10 in greatest MAX10LEN satisfying * MAX10 = 10**MAX10LEN <= 2**BASE. */ const MAX10 = 1000000000; /** * MAX10LEN in greatest MAX10LEN satisfying * MAX10 = 10**MAX10LEN <= 2**BASE. */ const MAX10LEN = 9; const MAX_DIGIT2 = 4611686018427387904; /** * Initialize a PHP64 BigInteger Engine instance * * @param int $base * @see parent::initialize() */ protected function initialize($base) { if ($base != 256 && $base != -256) { return parent::initialize($base); } $val = $this->value; $this->value = []; $vals = &$this->value; $i = strlen($val); if (!$i) { return; } while (true) { $i -= 4; if ($i < 0) { if ($i == -4) { break; } $val = substr($val, 0, 4 + $i); $val = str_pad($val, 4, "\0", STR_PAD_LEFT); if ($val == "\0\0\0\0") { break; } $i = 0; } list(, $digit) = unpack('N', substr($val, $i, 4)); $step = count($vals) & 7; if (!$step) { $digit &= static::MAX_DIGIT; $i++; } else { $shift = 8 - $step; $digit >>= $shift; $shift = 32 - $shift; $digit &= (1 << $shift) - 1; $temp = $i > 0 ? ord($val[$i - 1]) : 0; $digit |= ($temp << $shift) & 0x7F000000; } $vals[] = $digit; } while (end($vals) === 0) { array_pop($vals); } reset($vals); } /** * Test for engine validity * * @see parent::__construct() * @return bool */ public static function isValidEngine() { return PHP_INT_SIZE >= 8 && !self::testJITOnWindows(); } /** * Adds two BigIntegers. * * @param PHP64 $y * @return PHP64 */ public function add(PHP64 $y) { $temp = self::addHelper($this->value, $this->is_negative, $y->value, $y->is_negative); return $this->convertToObj($temp); } /** * Subtracts two BigIntegers. * * @param PHP64 $y * @return PHP64 */ public function subtract(PHP64 $y) { $temp = self::subtractHelper($this->value, $this->is_negative, $y->value, $y->is_negative); return $this->convertToObj($temp); } /** * Multiplies two BigIntegers. * * @param PHP64 $y * @return PHP64 */ public function multiply(PHP64 $y) { $temp = self::multiplyHelper($this->value, $this->is_negative, $y->value, $y->is_negative); return $this->convertToObj($temp); } /** * Divides two BigIntegers. * * Returns an array whose first element contains the quotient and whose second element contains the * "common residue". If the remainder would be positive, the "common residue" and the remainder are the * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder * and the divisor (basically, the "common residue" is the first positive modulo). * * @param PHP64 $y * @return array{PHP64, PHP64} */ public function divide(PHP64 $y) { return $this->divideHelper($y); } /** * Calculates modular inverses. * * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. * @param PHP64 $n * @return false|PHP64 */ public function modInverse(PHP64 $n) { return $this->modInverseHelper($n); } /** * Calculates modular inverses. * * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. * @param PHP64 $n * @return PHP64[] */ public function extendedGCD(PHP64 $n) { return $this->extendedGCDHelper($n); } /** * Calculates the greatest common divisor * * Say you have 693 and 609. The GCD is 21. * * @param PHP64 $n * @return PHP64 */ public function gcd(PHP64 $n) { return $this->extendedGCD($n)['gcd']; } /** * Logical And * * @param PHP64 $x * @return PHP64 */ public function bitwise_and(PHP64 $x) { return $this->bitwiseAndHelper($x); } /** * Logical Or * * @param PHP64 $x * @return PHP64 */ public function bitwise_or(PHP64 $x) { return $this->bitwiseOrHelper($x); } /** * Logical Exclusive Or * * @param PHP64 $x * @return PHP64 */ public function bitwise_xor(PHP64 $x) { return $this->bitwiseXorHelper($x); } /** * Compares two numbers. * * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite. The reason for this is * demonstrated thusly: * * $x > $y: $x->compare($y) > 0 * $x < $y: $x->compare($y) < 0 * $x == $y: $x->compare($y) == 0 * * Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y). * * {@internal Could return $this->subtract($x), but that's not as fast as what we do do.} * * @param PHP64 $y * @return int in case < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal. * @see self::equals() */ public function compare(PHP64 $y) { return parent::compareHelper($this->value, $this->is_negative, $y->value, $y->is_negative); } /** * Tests the equality of two numbers. * * If you need to see if one number is greater than or less than another number, use BigInteger::compare() * * @param PHP64 $x * @return bool */ public function equals(PHP64 $x) { return $this->value === $x->value && $this->is_negative == $x->is_negative; } /** * Performs modular exponentiation. * * @param PHP64 $e * @param PHP64 $n * @return PHP64 */ public function modPow(PHP64 $e, PHP64 $n) { return $this->powModOuter($e, $n); } /** * Performs modular exponentiation. * * Alias for modPow(). * * @param PHP64 $e * @param PHP64 $n * @return PHP64|false */ public function powMod(PHP64 $e, PHP64 $n) { return $this->powModOuter($e, $n); } /** * Generate a random prime number between a range * * If there's not a prime within the given range, false will be returned. * * @param PHP64 $min * @param PHP64 $max * @return false|PHP64 */ public static function randomRangePrime(PHP64 $min, PHP64 $max) { return self::randomRangePrimeOuter($min, $max); } /** * Generate a random number between a range * * Returns a random number between $min and $max where $min and $max * can be defined using one of the two methods: * * BigInteger::randomRange($min, $max) * BigInteger::randomRange($max, $min) * * @param PHP64 $min * @param PHP64 $max * @return PHP64 */ public static function randomRange(PHP64 $min, PHP64 $max) { return self::randomRangeHelper($min, $max); } /** * Performs exponentiation. * * @param PHP64 $n * @return PHP64 */ public function pow(PHP64 $n) { return $this->powHelper($n); } /** * Return the minimum BigInteger between an arbitrary number of BigIntegers. * * @param PHP64 ...$nums * @return PHP64 */ public static function min(PHP64 ...$nums) { return self::minHelper($nums); } /** * Return the maximum BigInteger between an arbitrary number of BigIntegers. * * @param PHP64 ...$nums * @return PHP64 */ public static function max(PHP64 ...$nums) { return self::maxHelper($nums); } /** * Tests BigInteger to see if it is between two integers, inclusive * * @param PHP64 $min * @param PHP64 $max * @return bool */ public function between(PHP64 $min, PHP64 $max) { return $this->compare($min) >= 0 && $this->compare($max) <= 0; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php ================================================ * add($b); * * echo $c->toString(); // outputs 5 * ?> * * * @author Jim Wigginton * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License */ namespace phpseclib3\Math; use phpseclib3\Exception\BadConfigurationException; use phpseclib3\Math\BigInteger\Engines\Engine; /** * Pure-PHP arbitrary precision integer arithmetic library. Supports base-2, base-10, base-16, and base-256 * numbers. * * @author Jim Wigginton */ class BigInteger implements \JsonSerializable { /** * Main Engine * * @var class-string */ private static $mainEngine; /** * Selected Engines * * @var list */ private static $engines; /** * The actual BigInteger object * * @var object */ private $value; /** * Mode independent value used for serialization. * * @see self::__sleep() * @see self::__wakeup() * @var string */ private $hex; /** * Precision (used only for serialization) * * @see self::__sleep() * @see self::__wakeup() * @var int */ private $precision; /** * Sets engine type. * * Throws an exception if the type is invalid * * @param string $main * @param list $modexps optional * @return void */ public static function setEngine($main, array $modexps = ['DefaultEngine']) { self::$engines = []; $fqmain = 'phpseclib3\\Math\\BigInteger\\Engines\\' . $main; if (!class_exists($fqmain) || !method_exists($fqmain, 'isValidEngine')) { throw new \InvalidArgumentException("$main is not a valid engine"); } if (!$fqmain::isValidEngine()) { throw new BadConfigurationException("$main is not setup correctly on this system"); } /** @var class-string $fqmain */ self::$mainEngine = $fqmain; $found = false; foreach ($modexps as $modexp) { try { $fqmain::setModExpEngine($modexp); $found = true; break; } catch (\Exception $e) { } } if (!$found) { throw new BadConfigurationException("No valid modular exponentiation engine found for $main"); } self::$engines = [$main, $modexp]; } /** * Returns the engine type * * @return string[] */ public static function getEngine() { self::initialize_static_variables(); return self::$engines; } /** * Initialize static variables */ private static function initialize_static_variables() { if (!isset(self::$mainEngine)) { $engines = [ ['GMP', ['DefaultEngine']], ['PHP64', ['OpenSSL']], ['BCMath', ['OpenSSL']], ['PHP32', ['OpenSSL']], ['PHP64', ['DefaultEngine']], ['PHP32', ['DefaultEngine']] ]; // per https://phpseclib.com/docs/speed PHP 8.4.0+ _significantly_ sped up BCMath if (version_compare(PHP_VERSION, '8.4.0') >= 0) { $engines[1][0] = 'BCMath'; $engines[2][0] = 'PHP64'; } foreach ($engines as $engine) { try { self::setEngine($engine[0], $engine[1]); return; } catch (\Exception $e) { } } throw new \UnexpectedValueException('No valid BigInteger found. This is only possible when JIT is enabled on Windows and neither the GMP or BCMath extensions are available so either disable JIT or install GMP / BCMath'); } } /** * Converts base-2, base-10, base-16, and binary strings (base-256) to BigIntegers. * * If the second parameter - $base - is negative, then it will be assumed that the number's are encoded using * two's compliment. The sole exception to this is -10, which is treated the same as 10 is. * * @param string|int|Engine $x Base-10 number or base-$base number if $base set. * @param int $base */ public function __construct($x = 0, $base = 10) { self::initialize_static_variables(); if ($x instanceof self::$mainEngine) { $this->value = clone $x; } elseif ($x instanceof Engine) { $this->value = new static("$x"); $this->value->setPrecision($x->getPrecision()); } else { $this->value = new self::$mainEngine($x, $base); } } /** * Converts a BigInteger to a base-10 number. * * @return string */ public function toString() { return $this->value->toString(); } /** * __toString() magic method */ public function __toString() { return (string)$this->value; } /** * __debugInfo() magic method * * Will be called, automatically, when print_r() or var_dump() are called */ public function __debugInfo() { return $this->value->__debugInfo(); } /** * Converts a BigInteger to a byte string (eg. base-256). * * @param bool $twos_compliment * @return string */ public function toBytes($twos_compliment = false) { return $this->value->toBytes($twos_compliment); } /** * Converts a BigInteger to a hex string (eg. base-16). * * @param bool $twos_compliment * @return string */ public function toHex($twos_compliment = false) { return $this->value->toHex($twos_compliment); } /** * Converts a BigInteger to a bit string (eg. base-2). * * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're * saved as two's compliment. * * @param bool $twos_compliment * @return string */ public function toBits($twos_compliment = false) { return $this->value->toBits($twos_compliment); } /** * Adds two BigIntegers. * * @param BigInteger $y * @return BigInteger */ public function add(BigInteger $y) { return new static($this->value->add($y->value)); } /** * Subtracts two BigIntegers. * * @param BigInteger $y * @return BigInteger */ public function subtract(BigInteger $y) { return new static($this->value->subtract($y->value)); } /** * Multiplies two BigIntegers * * @param BigInteger $x * @return BigInteger */ public function multiply(BigInteger $x) { return new static($this->value->multiply($x->value)); } /** * Divides two BigIntegers. * * Returns an array whose first element contains the quotient and whose second element contains the * "common residue". If the remainder would be positive, the "common residue" and the remainder are the * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder * and the divisor (basically, the "common residue" is the first positive modulo). * * Here's an example: * * divide($b); * * echo $quotient->toString(); // outputs 0 * echo "\r\n"; * echo $remainder->toString(); // outputs 10 * ?> * * * @param BigInteger $y * @return BigInteger[] */ public function divide(BigInteger $y) { list($q, $r) = $this->value->divide($y->value); return [ new static($q), new static($r) ]; } /** * Calculates modular inverses. * * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. * * @param BigInteger $n * @return BigInteger */ public function modInverse(BigInteger $n) { return new static($this->value->modInverse($n->value)); } /** * Calculates modular inverses. * * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. * * @param BigInteger $n * @return BigInteger[] */ public function extendedGCD(BigInteger $n) { $extended = $this->value->extendedGCD($n->value); $gcd = $extended['gcd']; $x = $extended['x']; $y = $extended['y']; return [ 'gcd' => new static($gcd), 'x' => new static($x), 'y' => new static($y) ]; } /** * Calculates the greatest common divisor * * Say you have 693 and 609. The GCD is 21. * * @param BigInteger $n * @return BigInteger */ public function gcd(BigInteger $n) { return new static($this->value->gcd($n->value)); } /** * Absolute value. * * @return BigInteger */ public function abs() { return new static($this->value->abs()); } /** * Set Precision * * Some bitwise operations give different results depending on the precision being used. Examples include left * shift, not, and rotates. * * @param int $bits */ public function setPrecision($bits) { $this->value->setPrecision($bits); } /** * Get Precision * * Returns the precision if it exists, false if it doesn't * * @return int|bool */ public function getPrecision() { return $this->value->getPrecision(); } /** * Serialize * * Will be called, automatically, when serialize() is called on a BigInteger object. * * __sleep() / __wakeup() have been around since PHP 4.0 but were deprecated in PHP 8.5 * * \Serializable was introduced in PHP 5.1 and deprecated in PHP 8.1: * https://wiki.php.net/rfc/phase_out_serializable * * __serialize() / __unserialize() were introduced in PHP 7.4: * https://wiki.php.net/rfc/custom_object_serialization * * @return array */ public function __sleep() { $this->hex = $this->toHex(true); $vars = ['hex']; if ($this->getPrecision() > 0) { $vars[] = 'precision'; } return $vars; } /** * Serialize * * Will be called, automatically, when unserialize() is called on a BigInteger object. */ public function __wakeup() { $temp = new static($this->hex, -16); $this->value = $temp->value; if ($this->precision > 0) { // recalculate $this->bitmask $this->setPrecision($this->precision); } } /** * __serialize() magic method * * @see self::__unserialize() * @return array * @access public */ public function __serialize() { $result = ['hex' => $this->toHex(true)]; if ($this->getPrecision() > 0) { $result['precision'] = $this->getPrecision(); } return $result; } /** * __unserialize() magic method * * @see self::__serialize() * @access public */ public function __unserialize(array $data) { $temp = new static($data['hex'], -16); $this->value = $temp->value; if (isset($data['precision']) && $data['precision'] > 0) { // recalculate $this->bitmask $this->setPrecision($data['precision']); } } /** * JSON Serialize * * Will be called, automatically, when json_encode() is called on a BigInteger object. * * @return array{hex: string, precision?: int] */ #[\ReturnTypeWillChange] public function jsonSerialize() { $result = ['hex' => $this->toHex(true)]; if ($this->precision > 0) { $result['precision'] = $this->getPrecision(); } return $result; } /** * Performs modular exponentiation. * * @param BigInteger $e * @param BigInteger $n * @return BigInteger */ public function powMod(BigInteger $e, BigInteger $n) { return new static($this->value->powMod($e->value, $n->value)); } /** * Performs modular exponentiation. * * @param BigInteger $e * @param BigInteger $n * @return BigInteger */ public function modPow(BigInteger $e, BigInteger $n) { return new static($this->value->modPow($e->value, $n->value)); } /** * Compares two numbers. * * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite. The reason for this * is demonstrated thusly: * * $x > $y: $x->compare($y) > 0 * $x < $y: $x->compare($y) < 0 * $x == $y: $x->compare($y) == 0 * * Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y). * * {@internal Could return $this->subtract($x), but that's not as fast as what we do do.} * * @param BigInteger $y * @return int in case < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal. * @see self::equals() */ public function compare(BigInteger $y) { return $this->value->compare($y->value); } /** * Tests the equality of two numbers. * * If you need to see if one number is greater than or less than another number, use BigInteger::compare() * * @param BigInteger $x * @return bool */ public function equals(BigInteger $x) { return $this->value->equals($x->value); } /** * Logical Not * * @return BigInteger */ public function bitwise_not() { return new static($this->value->bitwise_not()); } /** * Logical And * * @param BigInteger $x * @return BigInteger */ public function bitwise_and(BigInteger $x) { return new static($this->value->bitwise_and($x->value)); } /** * Logical Or * * @param BigInteger $x * @return BigInteger */ public function bitwise_or(BigInteger $x) { return new static($this->value->bitwise_or($x->value)); } /** * Logical Exclusive Or * * @param BigInteger $x * @return BigInteger */ public function bitwise_xor(BigInteger $x) { return new static($this->value->bitwise_xor($x->value)); } /** * Logical Right Shift * * Shifts BigInteger's by $shift bits, effectively dividing by 2**$shift. * * @param int $shift * @return BigInteger */ public function bitwise_rightShift($shift) { return new static($this->value->bitwise_rightShift($shift)); } /** * Logical Left Shift * * Shifts BigInteger's by $shift bits, effectively multiplying by 2**$shift. * * @param int $shift * @return BigInteger */ public function bitwise_leftShift($shift) { return new static($this->value->bitwise_leftShift($shift)); } /** * Logical Left Rotate * * Instead of the top x bits being dropped they're appended to the shifted bit string. * * @param int $shift * @return BigInteger */ public function bitwise_leftRotate($shift) { return new static($this->value->bitwise_leftRotate($shift)); } /** * Logical Right Rotate * * Instead of the bottom x bits being dropped they're prepended to the shifted bit string. * * @param int $shift * @return BigInteger */ public function bitwise_rightRotate($shift) { return new static($this->value->bitwise_rightRotate($shift)); } /** * Returns the smallest and largest n-bit number * * @param int $bits * @return BigInteger[] */ public static function minMaxBits($bits) { self::initialize_static_variables(); $class = self::$mainEngine; $minMax = $class::minMaxBits($bits); $min = $minMax['min']; $max = $minMax['max']; return [ 'min' => new static($min), 'max' => new static($max) ]; } /** * Return the size of a BigInteger in bits * * @return int */ public function getLength() { return $this->value->getLength(); } /** * Return the size of a BigInteger in bytes * * @return int */ public function getLengthInBytes() { return $this->value->getLengthInBytes(); } /** * Generates a random number of a certain size * * Bit length is equal to $size * * @param int $size * @return BigInteger */ public static function random($size) { self::initialize_static_variables(); $class = self::$mainEngine; return new static($class::random($size)); } /** * Generates a random prime number of a certain size * * Bit length is equal to $size * * @param int $size * @return BigInteger */ public static function randomPrime($size) { self::initialize_static_variables(); $class = self::$mainEngine; return new static($class::randomPrime($size)); } /** * Generate a random prime number between a range * * If there's not a prime within the given range, false will be returned. * * @param BigInteger $min * @param BigInteger $max * @return false|BigInteger */ public static function randomRangePrime(BigInteger $min, BigInteger $max) { $class = self::$mainEngine; return new static($class::randomRangePrime($min->value, $max->value)); } /** * Generate a random number between a range * * Returns a random number between $min and $max where $min and $max * can be defined using one of the two methods: * * BigInteger::randomRange($min, $max) * BigInteger::randomRange($max, $min) * * @param BigInteger $min * @param BigInteger $max * @return BigInteger */ public static function randomRange(BigInteger $min, BigInteger $max) { $class = self::$mainEngine; return new static($class::randomRange($min->value, $max->value)); } /** * Checks a numer to see if it's prime * * Assuming the $t parameter is not set, this function has an error rate of 2**-80. The main motivation for the * $t parameter is distributability. BigInteger::randomPrime() can be distributed across multiple pageloads * on a website instead of just one. * * @param int|bool $t * @return bool */ public function isPrime($t = false) { return $this->value->isPrime($t); } /** * Calculates the nth root of a biginteger. * * Returns the nth root of a positive biginteger, where n defaults to 2 * * @param int $n optional * @return BigInteger */ public function root($n = 2) { return new static($this->value->root($n)); } /** * Performs exponentiation. * * @param BigInteger $n * @return BigInteger */ public function pow(BigInteger $n) { return new static($this->value->pow($n->value)); } /** * Return the minimum BigInteger between an arbitrary number of BigIntegers. * * @param BigInteger ...$nums * @return BigInteger */ public static function min(BigInteger ...$nums) { $class = self::$mainEngine; $nums = array_map(function ($num) { return $num->value; }, $nums); return new static($class::min(...$nums)); } /** * Return the maximum BigInteger between an arbitrary number of BigIntegers. * * @param BigInteger ...$nums * @return BigInteger */ public static function max(BigInteger ...$nums) { $class = self::$mainEngine; $nums = array_map(function ($num) { return $num->value; }, $nums); return new static($class::max(...$nums)); } /** * Tests BigInteger to see if it is between two integers, inclusive * * @param BigInteger $min * @param BigInteger $max * @return bool */ public function between(BigInteger $min, BigInteger $max) { return $this->value->between($min->value, $max->value); } /** * Clone */ public function __clone() { $this->value = clone $this->value; } /** * Is Odd? * * @return bool */ public function isOdd() { return $this->value->isOdd(); } /** * Tests if a bit is set * * @param int $x * @return bool */ public function testBit($x) { return $this->value->testBit($x); } /** * Is Negative? * * @return bool */ public function isNegative() { return $this->value->isNegative(); } /** * Negate * * Given $k, returns -$k * * @return BigInteger */ public function negate() { return new static($this->value->negate()); } /** * Scan for 1 and right shift by that amount * * ie. $s = gmp_scan1($n, 0) and $r = gmp_div_q($n, gmp_pow(gmp_init('2'), $s)); * * @param BigInteger $r * @return int */ public static function scan1divide(BigInteger $r) { $class = self::$mainEngine; return $class::scan1divide($r->value); } /** * Create Recurring Modulo Function * * Sometimes it may be desirable to do repeated modulos with the same number outside of * modular exponentiation * * @return callable */ public function createRecurringModuloFunction() { $func = $this->value->createRecurringModuloFunction(); return function (BigInteger $x) use ($func) { return new static($func($x->value)); }; } /** * Bitwise Split * * Splits BigInteger's into chunks of $split bits * * @param int $split * @return BigInteger[] */ public function bitwise_split($split) { return array_map(function ($val) { return new static($val); }, $this->value->bitwise_split($split)); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField/Integer.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License */ namespace phpseclib3\Math\BinaryField; use phpseclib3\Common\Functions\Strings; use phpseclib3\Math\BigInteger; use phpseclib3\Math\BinaryField; use phpseclib3\Math\Common\FiniteField\Integer as Base; /** * Binary Finite Fields * * @author Jim Wigginton */ class Integer extends Base { /** * Holds the BinaryField's value * * @var string */ protected $value; /** * Keeps track of current instance * * @var int */ protected $instanceID; /** * Holds the PrimeField's modulo * * @var array */ protected static $modulo; /** * Holds a pre-generated function to perform modulo reductions * * @var callable[] */ protected static $reduce; /** * Default constructor */ public function __construct($instanceID, $num = '') { $this->instanceID = $instanceID; if (!strlen($num)) { $this->value = ''; } else { $reduce = static::$reduce[$instanceID]; $this->value = $reduce($num); } } /** * Set the modulo for a given instance * @param int $instanceID * @param string $modulo */ public static function setModulo($instanceID, $modulo) { static::$modulo[$instanceID] = $modulo; } /** * Set the modulo for a given instance */ public static function setRecurringModuloFunction($instanceID, callable $function) { static::$reduce[$instanceID] = $function; } /** * Tests a parameter to see if it's of the right instance * * Throws an exception if the incorrect class is being utilized */ private static function checkInstance(self $x, self $y) { if ($x->instanceID != $y->instanceID) { throw new \UnexpectedValueException('The instances of the two BinaryField\Integer objects do not match'); } } /** * Tests the equality of two numbers. * * @return bool */ public function equals(self $x) { static::checkInstance($this, $x); return $this->value == $x->value; } /** * Compares two numbers. * * @return int */ public function compare(self $x) { static::checkInstance($this, $x); $a = $this->value; $b = $x->value; $length = max(strlen($a), strlen($b)); $a = str_pad($a, $length, "\0", STR_PAD_LEFT); $b = str_pad($b, $length, "\0", STR_PAD_LEFT); return strcmp($a, $b); } /** * Returns the degree of the polynomial * * @param string $x * @return int */ private static function deg($x) { $x = ltrim($x, "\0"); $xbit = decbin(ord($x[0])); $xlen = $xbit == '0' ? 0 : strlen($xbit); $len = strlen($x); if (!$len) { return -1; } return 8 * strlen($x) - 9 + $xlen; } /** * Perform polynomial division * * @return string[] * @link https://en.wikipedia.org/wiki/Polynomial_greatest_common_divisor#Euclidean_division */ private static function polynomialDivide($x, $y) { // in wikipedia's description of the algorithm, lc() is the leading coefficient. over a binary field that's // always going to be 1. $q = chr(0); $d = static::deg($y); $r = $x; while (($degr = static::deg($r)) >= $d) { $s = '1' . str_repeat('0', $degr - $d); $s = BinaryField::base2ToBase256($s); $length = max(strlen($s), strlen($q)); $q = !isset($q) ? $s : str_pad($q, $length, "\0", STR_PAD_LEFT) ^ str_pad($s, $length, "\0", STR_PAD_LEFT); $s = static::polynomialMultiply($s, $y); $length = max(strlen($r), strlen($s)); $r = str_pad($r, $length, "\0", STR_PAD_LEFT) ^ str_pad($s, $length, "\0", STR_PAD_LEFT); } return [ltrim($q, "\0"), ltrim($r, "\0")]; } /** * Perform polynomial multiplation in the traditional way * * @return string * @link https://en.wikipedia.org/wiki/Finite_field_arithmetic#Multiplication */ private static function regularPolynomialMultiply($x, $y) { $precomputed = [ltrim($x, "\0")]; $x = strrev(BinaryField::base256ToBase2($x)); $y = strrev(BinaryField::base256ToBase2($y)); if (strlen($x) == strlen($y)) { $length = strlen($x); } else { $length = max(strlen($x), strlen($y)); $x = str_pad($x, $length, '0'); $y = str_pad($y, $length, '0'); } $result = str_repeat('0', 2 * $length - 1); $result = BinaryField::base2ToBase256($result); $size = strlen($result); $x = strrev($x); // precompute left shift 1 through 7 for ($i = 1; $i < 8; $i++) { $precomputed[$i] = BinaryField::base2ToBase256($x . str_repeat('0', $i)); } for ($i = 0; $i < strlen($y); $i++) { if ($y[$i] == '1') { $temp = $precomputed[$i & 7] . str_repeat("\0", $i >> 3); $result ^= str_pad($temp, $size, "\0", STR_PAD_LEFT); } } return $result; } /** * Perform polynomial multiplation * * Uses karatsuba multiplication to reduce x-bit multiplications to a series of 32-bit multiplications * * @return string * @link https://en.wikipedia.org/wiki/Karatsuba_algorithm */ private static function polynomialMultiply($x, $y) { if (strlen($x) == strlen($y)) { $length = strlen($x); } else { $length = max(strlen($x), strlen($y)); $x = str_pad($x, $length, "\0", STR_PAD_LEFT); $y = str_pad($y, $length, "\0", STR_PAD_LEFT); } switch (true) { case PHP_INT_SIZE == 8 && $length <= 4: return $length != 4 ? self::subMultiply(str_pad($x, 4, "\0", STR_PAD_LEFT), str_pad($y, 4, "\0", STR_PAD_LEFT)) : self::subMultiply($x, $y); case PHP_INT_SIZE == 4 || $length > 32: return self::regularPolynomialMultiply($x, $y); } $m = $length >> 1; $x1 = substr($x, 0, -$m); $x0 = substr($x, -$m); $y1 = substr($y, 0, -$m); $y0 = substr($y, -$m); $z2 = self::polynomialMultiply($x1, $y1); $z0 = self::polynomialMultiply($x0, $y0); $z1 = self::polynomialMultiply( self::subAdd2($x1, $x0), self::subAdd2($y1, $y0) ); $z1 = self::subAdd3($z1, $z2, $z0); $xy = self::subAdd3( $z2 . str_repeat("\0", 2 * $m), $z1 . str_repeat("\0", $m), $z0 ); return ltrim($xy, "\0"); } /** * Perform polynomial multiplication on 2x 32-bit numbers, returning * a 64-bit number * * @param string $x * @param string $y * @return string * @link https://www.bearssl.org/constanttime.html#ghash-for-gcm */ private static function subMultiply($x, $y) { $x = unpack('N', $x)[1]; $y = unpack('N', $y)[1]; $x0 = $x & 0x11111111; $x1 = $x & 0x22222222; $x2 = $x & 0x44444444; $x3 = $x & 0x88888888; $y0 = $y & 0x11111111; $y1 = $y & 0x22222222; $y2 = $y & 0x44444444; $y3 = $y & 0x88888888; $z0 = ($x0 * $y0) ^ ($x1 * $y3) ^ ($x2 * $y2) ^ ($x3 * $y1); $z1 = ($x0 * $y1) ^ ($x1 * $y0) ^ ($x2 * $y3) ^ ($x3 * $y2); $z2 = ($x0 * $y2) ^ ($x1 * $y1) ^ ($x2 * $y0) ^ ($x3 * $y3); $z3 = ($x0 * $y3) ^ ($x1 * $y2) ^ ($x2 * $y1) ^ ($x3 * $y0); $z0 &= 0x1111111111111111; $z1 &= 0x2222222222222222; $z2 &= 0x4444444444444444; $z3 &= -8608480567731124088; // 0x8888888888888888 gets interpreted as a float $z = $z0 | $z1 | $z2 | $z3; return pack('J', $z); } /** * Adds two numbers * * @param string $x * @param string $y * @return string */ private static function subAdd2($x, $y) { $length = max(strlen($x), strlen($y)); $x = str_pad($x, $length, "\0", STR_PAD_LEFT); $y = str_pad($y, $length, "\0", STR_PAD_LEFT); return $x ^ $y; } /** * Adds three numbers * * @param string $x * @param string $y * @return string */ private static function subAdd3($x, $y, $z) { $length = max(strlen($x), strlen($y), strlen($z)); $x = str_pad($x, $length, "\0", STR_PAD_LEFT); $y = str_pad($y, $length, "\0", STR_PAD_LEFT); $z = str_pad($z, $length, "\0", STR_PAD_LEFT); return $x ^ $y ^ $z; } /** * Adds two BinaryFieldIntegers. * * @return static */ public function add(self $y) { static::checkInstance($this, $y); $length = strlen(static::$modulo[$this->instanceID]); $x = str_pad($this->value, $length, "\0", STR_PAD_LEFT); $y = str_pad($y->value, $length, "\0", STR_PAD_LEFT); return new static($this->instanceID, $x ^ $y); } /** * Subtracts two BinaryFieldIntegers. * * @return static */ public function subtract(self $x) { return $this->add($x); } /** * Multiplies two BinaryFieldIntegers. * * @return static */ public function multiply(self $y) { static::checkInstance($this, $y); return new static($this->instanceID, static::polynomialMultiply($this->value, $y->value)); } /** * Returns the modular inverse of a BinaryFieldInteger * * @return static */ public function modInverse() { $remainder0 = static::$modulo[$this->instanceID]; $remainder1 = $this->value; if ($remainder1 == '') { return new static($this->instanceID); } $aux0 = "\0"; $aux1 = "\1"; while ($remainder1 != "\1") { list($q, $r) = static::polynomialDivide($remainder0, $remainder1); $remainder0 = $remainder1; $remainder1 = $r; // the auxiliary in row n is given by the sum of the auxiliary in // row n-2 and the product of the quotient and the auxiliary in row // n-1 $temp = static::polynomialMultiply($aux1, $q); $aux = str_pad($aux0, strlen($temp), "\0", STR_PAD_LEFT) ^ str_pad($temp, strlen($aux0), "\0", STR_PAD_LEFT); $aux0 = $aux1; $aux1 = $aux; } $temp = new static($this->instanceID); $temp->value = ltrim($aux1, "\0"); return $temp; } /** * Divides two PrimeFieldIntegers. * * @return static */ public function divide(self $x) { static::checkInstance($this, $x); $x = $x->modInverse(); return $this->multiply($x); } /** * Negate * * A negative number can be written as 0-12. With modulos, 0 is the same thing as the modulo * so 0-12 is the same thing as modulo-12 * * @return object */ public function negate() { $x = str_pad($this->value, strlen(static::$modulo[$this->instanceID]), "\0", STR_PAD_LEFT); return new static($this->instanceID, $x ^ static::$modulo[$this->instanceID]); } /** * Returns the modulo * * @return string */ public static function getModulo($instanceID) { return static::$modulo[$instanceID]; } /** * Converts an Integer to a byte string (eg. base-256). * * @return string */ public function toBytes() { return str_pad($this->value, strlen(static::$modulo[$this->instanceID]), "\0", STR_PAD_LEFT); } /** * Converts an Integer to a hex string (eg. base-16). * * @return string */ public function toHex() { return Strings::bin2hex($this->toBytes()); } /** * Converts an Integer to a bit string (eg. base-2). * * @return string */ public function toBits() { //return str_pad(BinaryField::base256ToBase2($this->value), strlen(static::$modulo[$this->instanceID]), '0', STR_PAD_LEFT); return BinaryField::base256ToBase2($this->value); } /** * Converts an Integer to a BigInteger * * @return string */ public function toBigInteger() { return new BigInteger($this->value, 256); } /** * __toString() magic method * */ public function __toString() { return (string) $this->toBigInteger(); } /** * __debugInfo() magic method * */ public function __debugInfo() { return ['value' => $this->toHex()]; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License */ namespace phpseclib3\Math; use phpseclib3\Common\Functions\Strings; use phpseclib3\Math\BinaryField\Integer; use phpseclib3\Math\Common\FiniteField; /** * Binary Finite Fields * * @author Jim Wigginton */ class BinaryField extends FiniteField { /** * Instance Counter * * @var int */ private static $instanceCounter = 0; /** * Keeps track of current instance * * @var int */ protected $instanceID; /** @var BigInteger */ private $randomMax; /** * Default constructor */ public function __construct(...$indices) { $m = array_shift($indices); if ($m > 571) { /* sect571r1 and sect571k1 are the largest binary curves that https://www.secg.org/sec2-v2.pdf defines altho theoretically there may be legit reasons to use binary finite fields with larger degrees imposing a limit on the maximum size is both reasonable and precedented. in particular, http://tools.ietf.org/html/rfc4253#section-6.1 (The Secure Shell (SSH) Transport Layer Protocol) says "implementations SHOULD check that the packet length is reasonable in order for the implementation to avoid denial of service and/or buffer overflow attacks" */ throw new \OutOfBoundsException('Degrees larger than 571 are not supported'); } $val = str_repeat('0', $m) . '1'; foreach ($indices as $index) { $val[$index] = '1'; } $modulo = static::base2ToBase256(strrev($val)); $mStart = 2 * $m - 2; $t = ceil($m / 8); $finalMask = chr((1 << ($m % 8)) - 1); if ($finalMask == "\0") { $finalMask = "\xFF"; } $bitLen = $mStart + 1; $pad = ceil($bitLen / 8); $h = $bitLen & 7; $h = $h ? 8 - $h : 0; $r = rtrim(substr($val, 0, -1), '0'); $u = [static::base2ToBase256(strrev($r))]; for ($i = 1; $i < 8; $i++) { $u[] = static::base2ToBase256(strrev(str_repeat('0', $i) . $r)); } // implements algorithm 2.40 (in section 2.3.5) in "Guide to Elliptic Curve Cryptography" // with W = 8 $reduce = function ($c) use ($u, $mStart, $m, $t, $finalMask, $pad, $h) { $c = str_pad($c, $pad, "\0", STR_PAD_LEFT); for ($i = $mStart; $i >= $m;) { $g = $h >> 3; $mask = $h & 7; $mask = $mask ? 1 << (7 - $mask) : 0x80; for (; $mask > 0; $mask >>= 1, $i--, $h++) { if (ord($c[$g]) & $mask) { $temp = $i - $m; $j = $temp >> 3; $k = $temp & 7; $t1 = $j ? substr($c, 0, -$j) : $c; $length = strlen($t1); if ($length) { $t2 = str_pad($u[$k], $length, "\0", STR_PAD_LEFT); $temp = $t1 ^ $t2; $c = $j ? substr_replace($c, $temp, 0, $length) : $temp; } } } } $c = substr($c, -$t); if (strlen($c) == $t) { $c[0] = $c[0] & $finalMask; } return ltrim($c, "\0"); }; $this->instanceID = self::$instanceCounter++; Integer::setModulo($this->instanceID, $modulo); Integer::setRecurringModuloFunction($this->instanceID, $reduce); $this->randomMax = new BigInteger($modulo, 2); } /** * Returns an instance of a dynamically generated PrimeFieldInteger class * * @param string $num * @return Integer */ public function newInteger($num) { return new Integer($this->instanceID, $num instanceof BigInteger ? $num->toBytes() : $num); } /** * Returns an integer on the finite field between one and the prime modulo * * @return Integer */ public function randomInteger() { static $one; if (!isset($one)) { $one = new BigInteger(1); } return new Integer($this->instanceID, BigInteger::randomRange($one, $this->randomMax)->toBytes()); } /** * Returns the length of the modulo in bytes * * @return int */ public function getLengthInBytes() { return strlen(Integer::getModulo($this->instanceID)); } /** * Returns the length of the modulo in bits * * @return int */ public function getLength() { return strlen(Integer::getModulo($this->instanceID)) << 3; } /** * Converts a base-2 string to a base-256 string * * @param string $x * @param int|null $size * @return string */ public static function base2ToBase256($x, $size = null) { $str = Strings::bits2bin($x); $pad = strlen($x) >> 3; if (strlen($x) & 3) { $pad++; } $str = str_pad($str, $pad, "\0", STR_PAD_LEFT); if (isset($size)) { $str = str_pad($str, $size, "\0", STR_PAD_LEFT); } return $str; } /** * Converts a base-256 string to a base-2 string * * @param string $x * @return string */ public static function base256ToBase2($x) { if (function_exists('gmp_import')) { return gmp_strval(gmp_import($x), 2); } return Strings::bin2bits($x); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField/Integer.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License */ namespace phpseclib3\Math\Common\FiniteField; /** * Finite Field Integer * * @author Jim Wigginton */ abstract class Integer implements \JsonSerializable { /** * JSON Serialize * * Will be called, automatically, when json_encode() is called on a BigInteger object. * * PHP Serialize isn't supported because unserializing would require the factory be * serialized as well and that just sounds like too much * * @return array{hex: string} */ #[\ReturnTypeWillChange] public function jsonSerialize() { return ['hex' => $this->toHex(true)]; } /** * Converts an Integer to a hex string (eg. base-16). * * @return string */ abstract public function toHex(); } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License */ namespace phpseclib3\Math\Common; /** * Finite Fields * * @author Jim Wigginton */ abstract class FiniteField { } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField/Integer.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License */ namespace phpseclib3\Math\PrimeField; use phpseclib3\Common\Functions\Strings; use phpseclib3\Math\BigInteger; use phpseclib3\Math\Common\FiniteField\Integer as Base; /** * Prime Finite Fields * * @author Jim Wigginton */ class Integer extends Base { /** * Holds the PrimeField's value * * @var BigInteger */ protected $value; /** * Keeps track of current instance * * @var int */ protected $instanceID; /** * Holds the PrimeField's modulo * * @var array */ protected static $modulo; /** * Holds a pre-generated function to perform modulo reductions * * @var array */ protected static $reduce; /** * Zero * * @var BigInteger[] */ protected static $zero; /** * One * * @var BigInteger[] */ protected static $one; /** * Two * * @var BigInteger[] */ protected static $two; /** * Default constructor * * @param int $instanceID * @param BigInteger $num */ public function __construct($instanceID, $num = null) { $this->instanceID = $instanceID; if (!isset($num)) { $this->value = clone static::$zero[$instanceID]; } else { $reduce = static::$reduce[$instanceID]; $this->value = $reduce($num); } } /** * Set the modulo for a given instance * * @param int $instanceID * @return void */ public static function setModulo($instanceID, BigInteger $modulo) { static::$modulo[$instanceID] = $modulo; } /** * Set the modulo for a given instance * * @param int $instanceID * @return void */ public static function setRecurringModuloFunction($instanceID, callable $function) { static::$reduce[$instanceID] = $function; if (!isset(static::$zero[$instanceID])) { static::$zero[$instanceID] = new BigInteger(); } } /** * Delete the modulo for a given instance */ public static function cleanupCache($instanceID) { unset(static::$modulo[$instanceID]); unset(static::$reduce[$instanceID]); unset(static::$zero[$instanceID]); unset(static::$one[$instanceID]); unset(static::$two[$instanceID]); } /** * Returns the modulo * * @param int $instanceID * @return BigInteger */ public static function getModulo($instanceID) { return static::$modulo[$instanceID]; } /** * Tests a parameter to see if it's of the right instance * * Throws an exception if the incorrect class is being utilized * * @return void */ public static function checkInstance(self $x, self $y) { if ($x->instanceID != $y->instanceID) { throw new \UnexpectedValueException('The instances of the two PrimeField\Integer objects do not match'); } } /** * Tests the equality of two numbers. * * @return bool */ public function equals(self $x) { static::checkInstance($this, $x); return $this->value->equals($x->value); } /** * Compares two numbers. * * @return int */ public function compare(self $x) { static::checkInstance($this, $x); return $this->value->compare($x->value); } /** * Adds two PrimeFieldIntegers. * * @return static */ public function add(self $x) { static::checkInstance($this, $x); $temp = new static($this->instanceID); $temp->value = $this->value->add($x->value); if ($temp->value->compare(static::$modulo[$this->instanceID]) >= 0) { $temp->value = $temp->value->subtract(static::$modulo[$this->instanceID]); } return $temp; } /** * Subtracts two PrimeFieldIntegers. * * @return static */ public function subtract(self $x) { static::checkInstance($this, $x); $temp = new static($this->instanceID); $temp->value = $this->value->subtract($x->value); if ($temp->value->isNegative()) { $temp->value = $temp->value->add(static::$modulo[$this->instanceID]); } return $temp; } /** * Multiplies two PrimeFieldIntegers. * * @return static */ public function multiply(self $x) { static::checkInstance($this, $x); return new static($this->instanceID, $this->value->multiply($x->value)); } /** * Divides two PrimeFieldIntegers. * * @return static */ public function divide(self $x) { static::checkInstance($this, $x); $denominator = $x->value->modInverse(static::$modulo[$this->instanceID]); return new static($this->instanceID, $this->value->multiply($denominator)); } /** * Performs power operation on a PrimeFieldInteger. * * @return static */ public function pow(BigInteger $x) { $temp = new static($this->instanceID); $temp->value = $this->value->powMod($x, static::$modulo[$this->instanceID]); return $temp; } /** * Calculates the square root * * @link https://en.wikipedia.org/wiki/Tonelli%E2%80%93Shanks_algorithm * @return static|false */ public function squareRoot() { if (!isset(static::$one[$this->instanceID])) { static::$one[$this->instanceID] = new BigInteger(1); static::$two[$this->instanceID] = new BigInteger(2); } $one = &static::$one[$this->instanceID]; $two = &static::$two[$this->instanceID]; $modulo = &static::$modulo[$this->instanceID]; $reduce = &static::$reduce[$this->instanceID]; $p_1 = $modulo->subtract($one); $q = clone $p_1; $s = BigInteger::scan1divide($q); list($pow) = $p_1->divide($two); for ($z = $one; !$z->equals($modulo); $z = $z->add($one)) { $temp = $z->powMod($pow, $modulo); if ($temp->equals($p_1)) { break; } } $m = new BigInteger($s); $c = $z->powMod($q, $modulo); $t = $this->value->powMod($q, $modulo); list($temp) = $q->add($one)->divide($two); $r = $this->value->powMod($temp, $modulo); while (!$t->equals($one)) { for ($i = clone $one; $i->compare($m) < 0; $i = $i->add($one)) { if ($t->powMod($two->pow($i), $modulo)->equals($one)) { break; } } if ($i->compare($m) == 0) { return false; } $b = $c->powMod($two->pow($m->subtract($i)->subtract($one)), $modulo); $m = $i; $c = $reduce($b->multiply($b)); $t = $reduce($t->multiply($c)); $r = $reduce($r->multiply($b)); } return new static($this->instanceID, $r); } /** * Is Odd? * * @return bool */ public function isOdd() { return $this->value->isOdd(); } /** * Negate * * A negative number can be written as 0-12. With modulos, 0 is the same thing as the modulo * so 0-12 is the same thing as modulo-12 * * @return static */ public function negate() { return new static($this->instanceID, static::$modulo[$this->instanceID]->subtract($this->value)); } /** * Converts an Integer to a byte string (eg. base-256). * * @return string */ public function toBytes() { if (isset(static::$modulo[$this->instanceID])) { $length = static::$modulo[$this->instanceID]->getLengthInBytes(); return str_pad($this->value->toBytes(), $length, "\0", STR_PAD_LEFT); } return $this->value->toBytes(); } /** * Converts an Integer to a hex string (eg. base-16). * * @return string */ public function toHex() { return Strings::bin2hex($this->toBytes()); } /** * Converts an Integer to a bit string (eg. base-2). * * @return string */ public function toBits() { // return $this->value->toBits(); static $length; if (!isset($length)) { $length = static::$modulo[$this->instanceID]->getLength(); } return str_pad($this->value->toBits(), $length, '0', STR_PAD_LEFT); } /** * Returns the w-ary non-adjacent form (wNAF) * * @param int $w optional * @return array */ public function getNAF($w = 1) { $w++; $zero = &static::$zero[$this->instanceID]; $mask = new BigInteger((1 << $w) - 1); $sub = new BigInteger(1 << $w); //$sub = new BigInteger(1 << ($w - 1)); $d = $this->toBigInteger(); $d_i = []; $i = 0; while ($d->compare($zero) > 0) { if ($d->isOdd()) { // start mods $bigInteger = $d->testBit($w - 1) ? $d->bitwise_and($mask)->subtract($sub) : //$sub->subtract($d->bitwise_and($mask)) : $d->bitwise_and($mask); // end mods $d = $d->subtract($bigInteger); $d_i[$i] = (int) $bigInteger->toString(); } else { $d_i[$i] = 0; } $shift = !$d->equals($zero) && $d->bitwise_and($mask)->equals($zero) ? $w : 1; // $w or $w + 1? $d = $d->bitwise_rightShift($shift); while (--$shift > 0) { $d_i[++$i] = 0; } $i++; } return $d_i; } /** * Converts an Integer to a BigInteger * * @return BigInteger */ public function toBigInteger() { return clone $this->value; } /** * __toString() magic method * * @return string */ public function __toString() { return (string) $this->value; } /** * __debugInfo() magic method * * @return array */ public function __debugInfo() { return ['value' => $this->toHex()]; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField.php ================================================ * @copyright 2017 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://pear.php.net/package/Math_BigInteger */ namespace phpseclib3\Math; use phpseclib3\Math\Common\FiniteField; use phpseclib3\Math\PrimeField\Integer; /** * Prime Finite Fields * * @author Jim Wigginton */ class PrimeField extends FiniteField { /** * Instance Counter * * @var int */ private static $instanceCounter = 0; /** * Keeps track of current instance * * @var int */ protected $instanceID; /** * Default constructor */ public function __construct(BigInteger $modulo) { if (!$modulo->isPrime()) { throw new \UnexpectedValueException('PrimeField requires a prime number be passed to the constructor'); } $this->instanceID = self::$instanceCounter++; Integer::setModulo($this->instanceID, $modulo); Integer::setRecurringModuloFunction($this->instanceID, $modulo->createRecurringModuloFunction()); } /** * Use a custom defined modular reduction function * * @return void */ public function setReduction(\Closure $func) { $this->reduce = $func->bindTo($this, $this); } /** * Returns an instance of a dynamically generated PrimeFieldInteger class * * @return Integer */ public function newInteger(BigInteger $num) { return new Integer($this->instanceID, $num); } /** * Returns an integer on the finite field between one and the prime modulo * * @return Integer */ public function randomInteger() { static $one; if (!isset($one)) { $one = new BigInteger(1); } return new Integer($this->instanceID, BigInteger::randomRange($one, Integer::getModulo($this->instanceID))); } /** * Returns the length of the modulo in bytes * * @return int */ public function getLengthInBytes() { return Integer::getModulo($this->instanceID)->getLengthInBytes(); } /** * Returns the length of the modulo in bits * * @return int */ public function getLength() { return Integer::getModulo($this->instanceID)->getLength(); } /** * Destructor */ public function __destruct() { Integer::cleanupCache($this->instanceID); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Net/SCP.php ================================================ * login('username', 'password')) { * exit('Login Failed'); * } * * echo $scp->exec('pwd') . "\r\n"; * $scp->put('filename.ext', 'hello, world!'); * echo $scp->exec('ls -latr'); * ?> * * * @author Jim Wigginton * @copyright 2009 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Net; use phpseclib3\Common\Functions\Strings; use phpseclib3\Exception\FileNotFoundException; /** * Pure-PHP implementations of SCP. * * @author Jim Wigginton */ class SCP extends SSH2 { /** * Reads data from a local file. * * @see \phpseclib3\Net\SCP::put() */ const SOURCE_LOCAL_FILE = 1; /** * Reads data from a string. * * @see \phpseclib3\Net\SCP::put() */ // this value isn't really used anymore but i'm keeping it reserved for historical reasons const SOURCE_STRING = 2; /** * SCP.php doesn't support SOURCE_CALLBACK because, with that one, we don't know the size, in advance */ //const SOURCE_CALLBACK = 16; /** * Error information * * @see self::getSCPErrors() * @see self::getLastSCPError() * @var array */ private $scp_errors = []; /** * Uploads a file to the SCP server. * * By default, \phpseclib\Net\SCP::put() does not read from the local filesystem. $data is dumped directly into $remote_file. * So, for example, if you set $data to 'filename.ext' and then do \phpseclib\Net\SCP::get(), you will get a file, twelve bytes * long, containing 'filename.ext' as its contents. * * Setting $mode to self::SOURCE_LOCAL_FILE will change the above behavior. With self::SOURCE_LOCAL_FILE, $remote_file will * contain as many bytes as filename.ext does on your local filesystem. If your filename.ext is 1MB then that is how * large $remote_file will be, as well. * * Currently, only binary mode is supported. As such, if the line endings need to be adjusted, you will need to take * care of that, yourself. * * @param string $remote_file * @param string $data * @param int $mode * @param callable $callback * @return bool * @access public */ public function put($remote_file, $data, $mode = self::SOURCE_STRING, $callback = null) { if (!($this->bitmap & self::MASK_LOGIN)) { return false; } if (empty($remote_file)) { // remote file cannot be blank return false; } if (!$this->exec('scp -t ' . escapeshellarg($remote_file), false)) { // -t = to return false; } $temp = $this->get_channel_packet(self::CHANNEL_EXEC, true); if ($temp !== chr(0)) { $this->close_channel(self::CHANNEL_EXEC, true); return false; } $packet_size = $this->packet_size_client_to_server[self::CHANNEL_EXEC] - 4; $remote_file = basename($remote_file); $dataCallback = false; switch (true) { case is_resource($data): $mode = $mode & ~self::SOURCE_LOCAL_FILE; $info = stream_get_meta_data($data); if (isset($info['wrapper_type']) && $info['wrapper_type'] == 'PHP' && $info['stream_type'] == 'Input') { $fp = fopen('php://memory', 'w+'); stream_copy_to_stream($data, $fp); rewind($fp); } else { $fp = $data; } break; case $mode & self::SOURCE_LOCAL_FILE: if (!is_file($data)) { throw new FileNotFoundException("$data is not a valid file"); } $fp = @fopen($data, 'rb'); if (!$fp) { $this->close_channel(self::CHANNEL_EXEC, true); return false; } } if (isset($fp)) { $stat = fstat($fp); $size = !empty($stat) ? $stat['size'] : 0; } else { $size = strlen($data); } $sent = 0; $size = $size < 0 ? ($size & 0x7FFFFFFF) + 0x80000000 : $size; $temp = 'C0644 ' . $size . ' ' . $remote_file . "\n"; $this->send_channel_packet(self::CHANNEL_EXEC, $temp); $temp = $this->get_channel_packet(self::CHANNEL_EXEC, true); if ($temp !== chr(0)) { $this->close_channel(self::CHANNEL_EXEC, true); return false; } $sent = 0; while ($sent < $size) { $temp = $mode & self::SOURCE_STRING ? substr($data, $sent, $packet_size) : fread($fp, $packet_size); $this->send_channel_packet(self::CHANNEL_EXEC, $temp); $sent += strlen($temp); if (is_callable($callback)) { call_user_func($callback, $sent); } } $this->close_channel(self::CHANNEL_EXEC, true); if ($mode != self::SOURCE_STRING) { fclose($fp); } return true; } /** * Downloads a file from the SCP server. * * Returns a string containing the contents of $remote_file if $local_file is left undefined or a boolean false if * the operation was unsuccessful. If $local_file is defined, returns true or false depending on the success of the * operation * * @param string $remote_file * @param string $local_file * @return mixed * @access public */ public function get($remote_file, $local_file = null, $progressCallback = null) { if (!($this->bitmap & self::MASK_LOGIN)) { return false; } if (!$this->exec('scp -f ' . escapeshellarg($remote_file), false)) { // -f = from return false; } $this->send_channel_packet(self::CHANNEL_EXEC, chr(0)); $info = $this->get_channel_packet(self::CHANNEL_EXEC, true); // per https://goteleport.com/blog/scp-familiar-simple-insecure-slow/ non-zero responses mean there are errors if ($info[0] === chr(1) || $info[0] == chr(2)) { $type = $info[0] === chr(1) ? 'warning' : 'error'; $this->scp_errors[] = "$type: " . substr($info, 1); $this->close_channel(self::CHANNEL_EXEC, true); return false; } $this->send_channel_packet(self::CHANNEL_EXEC, chr(0)); if (!preg_match('#(?[^ ]+) (?\d+) (?.+)#', rtrim($info), $info)) { $this->close_channel(self::CHANNEL_EXEC, true); return false; } $fclose_check = false; if (is_resource($local_file)) { $fp = $local_file; } elseif (!is_null($local_file)) { $fp = @fopen($local_file, 'wb'); if (!$fp) { $this->close_channel(self::CHANNEL_EXEC, true); return false; } $fclose_check = true; } else { $content = ''; } $size = 0; while (true) { $data = $this->get_channel_packet(self::CHANNEL_EXEC, true); // Terminate the loop in case the server repeatedly sends an empty response if ($data === false) { $this->close_channel(self::CHANNEL_EXEC, true); // no data received from server return false; } // SCP usually seems to split stuff out into 16k chunks $length = strlen($data); $size += $length; $end = $size > $info['size']; if ($end) { $diff = $size - $info['size']; $offset = $length - $diff; if ($data[$offset] === chr(0)) { $data = substr($data, 0, -$diff); } else { $type = $data[$offset] === chr(1) ? 'warning' : 'error'; $this->scp_errors[] = "$type: " . substr($data, 1); $this->close_channel(self::CHANNEL_EXEC, true); return false; } } if (is_null($local_file)) { $content .= $data; } else { fputs($fp, $data); } if (is_callable($progressCallback)) { call_user_func($progressCallback, $size); } if ($end) { break; } } $this->close_channel(self::CHANNEL_EXEC, true); if ($fclose_check) { fclose($fp); } // if $content isn't set that means a file was written to return isset($content) ? $content : true; } /** * Returns all errors on the SCP layer * * @return array */ public function getSCPErrors() { return $this->scp_errors; } /** * Returns the last error on the SCP layer * * @return string */ public function getLastSCPError() { return count($this->scp_errors) ? $this->scp_errors[count($this->scp_errors) - 1] : ''; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php ================================================ * @copyright 2013 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Net\SFTP; use phpseclib3\Crypt\Common\PrivateKey; use phpseclib3\Net\SFTP; use phpseclib3\Net\SSH2; /** * SFTP Stream Wrapper * * @author Jim Wigginton */ class Stream { /** * SFTP instances * * Rather than re-create the connection we re-use instances if possible * * @var array */ public static $instances; /** * SFTP instance * * @var object */ private $sftp; /** * Path * * @var string */ private $path; /** * Mode * * @var string */ private $mode; /** * Position * * @var int */ private $pos; /** * Size * * @var int */ private $size; /** * Directory entries * * @var array */ private $entries; /** * EOF flag * * @var bool */ private $eof; /** * Context resource * * Technically this needs to be publicly accessible so PHP can set it directly * * @var resource */ public $context; /** * Notification callback function * * @var callable */ private $notification; /** * Registers this class as a URL wrapper. * * @param string $protocol The wrapper name to be registered. * @return bool True on success, false otherwise. */ public static function register($protocol = 'sftp') { if (in_array($protocol, stream_get_wrappers(), true)) { return false; } return stream_wrapper_register($protocol, get_called_class()); } /** * The Constructor * */ public function __construct() { if (defined('NET_SFTP_STREAM_LOGGING')) { echo "__construct()\r\n"; } } /** * Path Parser * * Extract a path from a URI and actually connect to an SSH server if appropriate * * If "notification" is set as a context parameter the message code for successful login is * NET_SSH2_MSG_USERAUTH_SUCCESS. For a failed login it's NET_SSH2_MSG_USERAUTH_FAILURE. * * @param string $path * @return string */ protected function parse_path($path) { $orig = $path; $url = parse_url($path) + ['port' => 22]; $keys = ['scheme', 'host', 'port', 'user', 'pass', 'path', 'query', 'fragment']; foreach ($keys as $key) { if (isset($url[$key])) { $$key = $url[$key]; } } if (isset($query)) { $path .= '?' . $query; } elseif (preg_match('/(\?|\?#)$/', $orig)) { $path .= '?'; } if (isset($fragment)) { $path .= '#' . $fragment; } elseif ($orig[strlen($orig) - 1] == '#') { $path .= '#'; } if (!isset($host)) { return false; } if (isset($this->context)) { $context = stream_context_get_params($this->context); if (isset($context['notification'])) { $this->notification = $context['notification']; } } if (preg_match('/^{[a-z0-9]+}$/i', $host)) { $host = SSH2::getConnectionByResourceId($host); if ($host === false) { return false; } $this->sftp = $host; } else { if (isset($this->context)) { $context = stream_context_get_options($this->context); } if (isset($context[$scheme]['session'])) { $sftp = $context[$scheme]['session']; } if (isset($context[$scheme]['sftp'])) { $sftp = $context[$scheme]['sftp']; } if (isset($sftp) && $sftp instanceof SFTP) { $this->sftp = $sftp; return $path; } if (isset($context[$scheme]['username'])) { $user = $context[$scheme]['username']; } if (isset($context[$scheme]['password'])) { $pass = $context[$scheme]['password']; } if (isset($context[$scheme]['privkey']) && $context[$scheme]['privkey'] instanceof PrivateKey) { $pass = $context[$scheme]['privkey']; } if (!isset($user) || !isset($pass)) { return false; } // casting $pass to a string is necessary in the event that it's a \phpseclib3\Crypt\RSA object if (isset(self::$instances[$host][$port][$user][(string) $pass])) { $this->sftp = self::$instances[$host][$port][$user][(string) $pass]; } else { $this->sftp = new SFTP($host, $port); $this->sftp->disableStatCache(); if (isset($this->notification) && is_callable($this->notification)) { /* if !is_callable($this->notification) we could do this: user_error('fopen(): failed to call user notifier', E_USER_WARNING); the ftp wrapper gives errors like that when the notifier isn't callable. i've opted not to do that, however, since the ftp wrapper gives the line on which the fopen occurred as the line number - not the line that the user_error is on. */ call_user_func($this->notification, STREAM_NOTIFY_CONNECT, STREAM_NOTIFY_SEVERITY_INFO, '', 0, 0, 0); call_user_func($this->notification, STREAM_NOTIFY_AUTH_REQUIRED, STREAM_NOTIFY_SEVERITY_INFO, '', 0, 0, 0); if (!$this->sftp->login($user, $pass)) { call_user_func($this->notification, STREAM_NOTIFY_AUTH_RESULT, STREAM_NOTIFY_SEVERITY_ERR, 'Login Failure', NET_SSH2_MSG_USERAUTH_FAILURE, 0, 0); return false; } call_user_func($this->notification, STREAM_NOTIFY_AUTH_RESULT, STREAM_NOTIFY_SEVERITY_INFO, 'Login Success', NET_SSH2_MSG_USERAUTH_SUCCESS, 0, 0); } else { if (!$this->sftp->login($user, $pass)) { return false; } } self::$instances[$host][$port][$user][(string) $pass] = $this->sftp; } } return $path; } /** * Opens file or URL * * @param string $path * @param string $mode * @param int $options * @param string $opened_path * @return bool */ private function _stream_open($path, $mode, $options, &$opened_path) { $path = $this->parse_path($path); if ($path === false) { return false; } $this->path = $path; $this->size = $this->sftp->filesize($path); $this->mode = preg_replace('#[bt]$#', '', $mode); $this->eof = false; if ($this->size === false) { if ($this->mode[0] == 'r') { return false; } else { $this->sftp->touch($path); $this->size = 0; } } else { switch ($this->mode[0]) { case 'x': return false; case 'w': $this->sftp->truncate($path, 0); $this->size = 0; } } $this->pos = $this->mode[0] != 'a' ? 0 : $this->size; return true; } /** * Read from stream * * @param int $count * @return mixed */ private function _stream_read($count) { switch ($this->mode) { case 'w': case 'a': case 'x': case 'c': return false; } // commented out because some files - eg. /dev/urandom - will say their size is 0 when in fact it's kinda infinite //if ($this->pos >= $this->size) { // $this->eof = true; // return false; //} $result = $this->sftp->get($this->path, false, $this->pos, $count); if (isset($this->notification) && is_callable($this->notification)) { if ($result === false) { call_user_func($this->notification, STREAM_NOTIFY_FAILURE, STREAM_NOTIFY_SEVERITY_ERR, $this->sftp->getLastSFTPError(), NET_SFTP_OPEN, 0, 0); return 0; } // seems that PHP calls stream_read in 8k chunks call_user_func($this->notification, STREAM_NOTIFY_PROGRESS, STREAM_NOTIFY_SEVERITY_INFO, '', 0, strlen($result), $this->size); } if (empty($result)) { // ie. false or empty string $this->eof = true; return false; } $this->pos += strlen($result); return $result; } /** * Write to stream * * @param string $data * @return int|false */ private function _stream_write($data) { switch ($this->mode) { case 'r': return false; } $result = $this->sftp->put($this->path, $data, SFTP::SOURCE_STRING, $this->pos); if (isset($this->notification) && is_callable($this->notification)) { if (!$result) { call_user_func($this->notification, STREAM_NOTIFY_FAILURE, STREAM_NOTIFY_SEVERITY_ERR, $this->sftp->getLastSFTPError(), NET_SFTP_OPEN, 0, 0); return 0; } // seems that PHP splits up strings into 8k blocks before calling stream_write call_user_func($this->notification, STREAM_NOTIFY_PROGRESS, STREAM_NOTIFY_SEVERITY_INFO, '', 0, strlen($data), strlen($data)); } if ($result === false) { return false; } $this->pos += strlen($data); if ($this->pos > $this->size) { $this->size = $this->pos; } $this->eof = false; return strlen($data); } /** * Retrieve the current position of a stream * * @return int */ private function _stream_tell() { return $this->pos; } /** * Tests for end-of-file on a file pointer * * In my testing there are four classes functions that normally effect the pointer: * fseek, fputs / fwrite, fgets / fread and ftruncate. * * Only fgets / fread, however, results in feof() returning true. do fputs($fp, 'aaa') on a blank file and feof() * will return false. do fread($fp, 1) and feof() will then return true. do fseek($fp, 10) on ablank file and feof() * will return false. do fread($fp, 1) and feof() will then return true. * * @return bool */ private function _stream_eof() { return $this->eof; } /** * Seeks to specific location in a stream * * @param int $offset * @param int $whence * @return bool */ private function _stream_seek($offset, $whence) { switch ($whence) { case SEEK_SET: if ($offset < 0) { return false; } break; case SEEK_CUR: $offset += $this->pos; break; case SEEK_END: $offset += $this->size; } $this->pos = $offset; $this->eof = false; return true; } /** * Change stream options * * @param string $path * @param int $option * @param mixed $var * @return bool */ private function _stream_metadata($path, $option, $var) { $path = $this->parse_path($path); if ($path === false) { return false; } // stream_metadata was introduced in PHP 5.4.0 but as of 5.4.11 the constants haven't been defined // see http://www.php.net/streamwrapper.stream-metadata and https://bugs.php.net/64246 // and https://github.com/php/php-src/blob/master/main/php_streams.h#L592 switch ($option) { case 1: // PHP_STREAM_META_TOUCH $time = isset($var[0]) ? $var[0] : null; $atime = isset($var[1]) ? $var[1] : null; return $this->sftp->touch($path, $time, $atime); case 2: // PHP_STREAM_OWNER_NAME case 3: // PHP_STREAM_GROUP_NAME return false; case 4: // PHP_STREAM_META_OWNER return $this->sftp->chown($path, $var); case 5: // PHP_STREAM_META_GROUP return $this->sftp->chgrp($path, $var); case 6: // PHP_STREAM_META_ACCESS return $this->sftp->chmod($path, $var) !== false; } } /** * Retrieve the underlaying resource * * @param int $cast_as * @return resource */ private function _stream_cast($cast_as) { return $this->sftp->fsock; } /** * Advisory file locking * * @param int $operation * @return bool */ private function _stream_lock($operation) { return false; } /** * Renames a file or directory * * Attempts to rename oldname to newname, moving it between directories if necessary. * If newname exists, it will be overwritten. This is a departure from what \phpseclib3\Net\SFTP * does. * * @param string $path_from * @param string $path_to * @return bool */ private function _rename($path_from, $path_to) { $path1 = parse_url($path_from); $path2 = parse_url($path_to); unset($path1['path'], $path2['path']); if ($path1 != $path2) { return false; } $path_from = $this->parse_path($path_from); $path_to = parse_url($path_to); if ($path_from === false) { return false; } $path_to = $path_to['path']; // the $component part of parse_url() was added in PHP 5.1.2 // "It is an error if there already exists a file with the name specified by newpath." // -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-02#section-6.5 if (!$this->sftp->rename($path_from, $path_to)) { if ($this->sftp->stat($path_to)) { return $this->sftp->delete($path_to, true) && $this->sftp->rename($path_from, $path_to); } return false; } return true; } /** * Open directory handle * * The only $options is "whether or not to enforce safe_mode (0x04)". Since safe mode was deprecated in 5.3 and * removed in 5.4 I'm just going to ignore it. * * Also, nlist() is the best that this function is realistically going to be able to do. When an SFTP client * sends a SSH_FXP_READDIR packet you don't generally get info on just one file but on multiple files. Quoting * the SFTP specs: * * The SSH_FXP_NAME response has the following format: * * uint32 id * uint32 count * repeats count times: * string filename * string longname * ATTRS attrs * * @param string $path * @param int $options * @return bool */ private function _dir_opendir($path, $options) { $path = $this->parse_path($path); if ($path === false) { return false; } $this->pos = 0; $this->entries = $this->sftp->nlist($path); return $this->entries !== false; } /** * Read entry from directory handle * * @return mixed */ private function _dir_readdir() { if (isset($this->entries[$this->pos])) { return $this->entries[$this->pos++]; } return false; } /** * Rewind directory handle * * @return bool */ private function _dir_rewinddir() { $this->pos = 0; return true; } /** * Close directory handle * * @return bool */ private function _dir_closedir() { return true; } /** * Create a directory * * Only valid $options is STREAM_MKDIR_RECURSIVE * * @param string $path * @param int $mode * @param int $options * @return bool */ private function _mkdir($path, $mode, $options) { $path = $this->parse_path($path); if ($path === false) { return false; } return $this->sftp->mkdir($path, $mode, $options & STREAM_MKDIR_RECURSIVE); } /** * Removes a directory * * Only valid $options is STREAM_MKDIR_RECURSIVE per , however, * does not have a $recursive parameter as mkdir() does so I don't know how * STREAM_MKDIR_RECURSIVE is supposed to be set. Also, when I try it out with rmdir() I get 8 as * $options. What does 8 correspond to? * * @param string $path * @param int $options * @return bool */ private function _rmdir($path, $options) { $path = $this->parse_path($path); if ($path === false) { return false; } return $this->sftp->rmdir($path); } /** * Flushes the output * * See . Always returns true because \phpseclib3\Net\SFTP doesn't cache stuff before writing * * @return bool */ private function _stream_flush() { return true; } /** * Retrieve information about a file resource * * @return mixed */ private function _stream_stat() { $results = $this->sftp->stat($this->path); if ($results === false) { return false; } return $results; } /** * Delete a file * * @param string $path * @return bool */ private function _unlink($path) { $path = $this->parse_path($path); if ($path === false) { return false; } return $this->sftp->delete($path, false); } /** * Retrieve information about a file * * Ignores the STREAM_URL_STAT_QUIET flag because the entirety of \phpseclib3\Net\SFTP\Stream is quiet by default * might be worthwhile to reconstruct bits 12-16 (ie. the file type) if mode doesn't have them but we'll * cross that bridge when and if it's reached * * @param string $path * @param int $flags * @return mixed */ private function _url_stat($path, $flags) { $path = $this->parse_path($path); if ($path === false) { return false; } $results = $flags & STREAM_URL_STAT_LINK ? $this->sftp->lstat($path) : $this->sftp->stat($path); if ($results === false) { return false; } return $results; } /** * Truncate stream * * @param int $new_size * @return bool */ private function _stream_truncate($new_size) { if (!$this->sftp->truncate($this->path, $new_size)) { return false; } $this->eof = false; $this->size = $new_size; return true; } /** * Change stream options * * STREAM_OPTION_WRITE_BUFFER isn't supported for the same reason stream_flush isn't. * The other two aren't supported because of limitations in \phpseclib3\Net\SFTP. * * @param int $option * @param int $arg1 * @param int $arg2 * @return bool */ private function _stream_set_option($option, $arg1, $arg2) { return false; } /** * Close an resource * */ private function _stream_close() { } /** * __call Magic Method * * When you're utilizing an SFTP stream you're not calling the methods in this class directly - PHP is calling them for you. * Which kinda begs the question... what methods is PHP calling and what parameters is it passing to them? This function * lets you figure that out. * * If NET_SFTP_STREAM_LOGGING is defined all calls will be output on the screen and then (regardless of whether or not * NET_SFTP_STREAM_LOGGING is enabled) the parameters will be passed through to the appropriate method. * * @param string $name * @param array $arguments * @return mixed */ public function __call($name, array $arguments) { if (defined('NET_SFTP_STREAM_LOGGING')) { echo $name . '('; $last = count($arguments) - 1; foreach ($arguments as $i => $argument) { var_export($argument); if ($i != $last) { echo ','; } } echo ")\r\n"; } $name = '_' . $name; if (!method_exists($this, $name)) { return false; } return $this->$name(...$arguments); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php ================================================ * login('username', 'password')) { * exit('Login Failed'); * } * * echo $sftp->pwd() . "\r\n"; * $sftp->put('filename.ext', 'hello, world!'); * print_r($sftp->nlist()); * ?> * * * @author Jim Wigginton * @copyright 2009 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Net; use phpseclib3\Common\Functions\Strings; use phpseclib3\Exception\FileNotFoundException; /** * Pure-PHP implementations of SFTP. * * @author Jim Wigginton */ class SFTP extends SSH2 { /** * SFTP channel constant * * \phpseclib3\Net\SSH2::exec() uses 0 and \phpseclib3\Net\SSH2::read() / \phpseclib3\Net\SSH2::write() use 1. * * @see \phpseclib3\Net\SSH2::send_channel_packet() * @see \phpseclib3\Net\SSH2::get_channel_packet() */ const CHANNEL = 0x100; /** * Reads data from a local file. * * @see \phpseclib3\Net\SFTP::put() */ const SOURCE_LOCAL_FILE = 1; /** * Reads data from a string. * * @see \phpseclib3\Net\SFTP::put() */ // this value isn't really used anymore but i'm keeping it reserved for historical reasons const SOURCE_STRING = 2; /** * Reads data from callback: * function callback($length) returns string to proceed, null for EOF * * @see \phpseclib3\Net\SFTP::put() */ const SOURCE_CALLBACK = 16; /** * Resumes an upload * * @see \phpseclib3\Net\SFTP::put() */ const RESUME = 4; /** * Append a local file to an already existing remote file * * @see \phpseclib3\Net\SFTP::put() */ const RESUME_START = 8; /** * Packet Types * * @see self::__construct() * @var array * @access private */ private static $packet_types = []; /** * Status Codes * * @see self::__construct() * @var array * @access private */ private static $status_codes = []; /** @var array */ private static $attributes; /** @var array */ private static $open_flags; /** @var array */ private static $open_flags5; /** @var array */ private static $file_types; /** * The Request ID * * The request ID exists in the off chance that a packet is sent out-of-order. Of course, this library doesn't support * concurrent actions, so it's somewhat academic, here. * * @var boolean * @see self::_send_sftp_packet() */ private $use_request_id = false; /** * The Packet Type * * The request ID exists in the off chance that a packet is sent out-of-order. Of course, this library doesn't support * concurrent actions, so it's somewhat academic, here. * * @var int * @see self::_get_sftp_packet() */ private $packet_type = -1; /** * Packet Buffer * * @var string * @see self::_get_sftp_packet() */ private $packet_buffer = ''; /** * Extensions supported by the server * * @var array * @see self::_initChannel() */ private $extensions = []; /** * Server SFTP version * * @var int * @see self::_initChannel() */ private $version; /** * Default Server SFTP version * * @var int * @see self::_initChannel() */ private $defaultVersion; /** * Preferred SFTP version * * @var int * @see self::_initChannel() */ private $preferredVersion = 3; /** * Current working directory * * @var string|bool * @see self::realpath() * @see self::chdir() */ private $pwd = false; /** * Packet Type Log * * @see self::getLog() * @var array */ private $packet_type_log = []; /** * Packet Log * * @see self::getLog() * @var array */ private $packet_log = []; /** * Real-time log file pointer * * @see self::_append_log() * @var resource|closed-resource */ private $realtime_log_file; /** * Real-time log file size * * @see self::_append_log() * @var int */ private $realtime_log_size; /** * Real-time log file wrap boolean * * @see self::_append_log() * @var bool */ private $realtime_log_wrap; /** * Current log size * * Should never exceed self::LOG_MAX_SIZE * * @var int */ private $log_size; /** * Error information * * @see self::getSFTPErrors() * @see self::getLastSFTPError() * @var array */ private $sftp_errors = []; /** * Stat Cache * * Rather than always having to open a directory and close it immediately there after to see if a file is a directory * we'll cache the results. * * @see self::_update_stat_cache() * @see self::_remove_from_stat_cache() * @see self::_query_stat_cache() * @var array */ private $stat_cache = []; /** * Max SFTP Packet Size * * @see self::__construct() * @see self::get() * @var int */ private $max_sftp_packet; /** * Stat Cache Flag * * @see self::disableStatCache() * @see self::enableStatCache() * @var bool */ private $use_stat_cache = true; /** * Sort Options * * @see self::_comparator() * @see self::setListOrder() * @var array */ protected $sortOptions = []; /** * Canonicalization Flag * * Determines whether or not paths should be canonicalized before being * passed on to the remote server. * * @see self::enablePathCanonicalization() * @see self::disablePathCanonicalization() * @see self::realpath() * @var bool */ private $canonicalize_paths = true; /** * Request Buffers * * @see self::_get_sftp_packet() * @var array */ private $requestBuffer = []; /** * Preserve timestamps on file downloads / uploads * * @see self::get() * @see self::put() * @var bool */ private $preserveTime = false; /** * Arbitrary Length Packets Flag * * Determines whether or not packets of any length should be allowed, * in cases where the server chooses the packet length (such as * directory listings). By default, packets are only allowed to be * 256 * 1024 bytes (SFTP_MAX_MSG_LENGTH from OpenSSH's sftp-common.h) * * @see self::enableArbitraryLengthPackets() * @see self::_get_sftp_packet() * @var bool */ private $allow_arbitrary_length_packets = false; /** * Was the last packet due to the channels being closed or not? * * @see self::get() * @see self::get_sftp_packet() * @var bool */ private $channel_close = false; /** * Has the SFTP channel been partially negotiated? * * @var bool */ private $partial_init = false; /** * Default Constructor. * * Connects to an SFTP server * * $host can either be a string, representing the host, or a stream resource. * * @param mixed $host * @param int $port * @param int $timeout */ public function __construct($host, $port = 22, $timeout = 10) { parent::__construct($host, $port, $timeout); $this->max_sftp_packet = 1 << 15; if (empty(self::$packet_types)) { self::$packet_types = [ 1 => 'NET_SFTP_INIT', 2 => 'NET_SFTP_VERSION', 3 => 'NET_SFTP_OPEN', 4 => 'NET_SFTP_CLOSE', 5 => 'NET_SFTP_READ', 6 => 'NET_SFTP_WRITE', 7 => 'NET_SFTP_LSTAT', 9 => 'NET_SFTP_SETSTAT', 10 => 'NET_SFTP_FSETSTAT', 11 => 'NET_SFTP_OPENDIR', 12 => 'NET_SFTP_READDIR', 13 => 'NET_SFTP_REMOVE', 14 => 'NET_SFTP_MKDIR', 15 => 'NET_SFTP_RMDIR', 16 => 'NET_SFTP_REALPATH', 17 => 'NET_SFTP_STAT', 18 => 'NET_SFTP_RENAME', 19 => 'NET_SFTP_READLINK', 20 => 'NET_SFTP_SYMLINK', 21 => 'NET_SFTP_LINK', 101 => 'NET_SFTP_STATUS', 102 => 'NET_SFTP_HANDLE', 103 => 'NET_SFTP_DATA', 104 => 'NET_SFTP_NAME', 105 => 'NET_SFTP_ATTRS', 200 => 'NET_SFTP_EXTENDED', 201 => 'NET_SFTP_EXTENDED_REPLY' ]; self::$status_codes = [ 0 => 'NET_SFTP_STATUS_OK', 1 => 'NET_SFTP_STATUS_EOF', 2 => 'NET_SFTP_STATUS_NO_SUCH_FILE', 3 => 'NET_SFTP_STATUS_PERMISSION_DENIED', 4 => 'NET_SFTP_STATUS_FAILURE', 5 => 'NET_SFTP_STATUS_BAD_MESSAGE', 6 => 'NET_SFTP_STATUS_NO_CONNECTION', 7 => 'NET_SFTP_STATUS_CONNECTION_LOST', 8 => 'NET_SFTP_STATUS_OP_UNSUPPORTED', 9 => 'NET_SFTP_STATUS_INVALID_HANDLE', 10 => 'NET_SFTP_STATUS_NO_SUCH_PATH', 11 => 'NET_SFTP_STATUS_FILE_ALREADY_EXISTS', 12 => 'NET_SFTP_STATUS_WRITE_PROTECT', 13 => 'NET_SFTP_STATUS_NO_MEDIA', 14 => 'NET_SFTP_STATUS_NO_SPACE_ON_FILESYSTEM', 15 => 'NET_SFTP_STATUS_QUOTA_EXCEEDED', 16 => 'NET_SFTP_STATUS_UNKNOWN_PRINCIPAL', 17 => 'NET_SFTP_STATUS_LOCK_CONFLICT', 18 => 'NET_SFTP_STATUS_DIR_NOT_EMPTY', 19 => 'NET_SFTP_STATUS_NOT_A_DIRECTORY', 20 => 'NET_SFTP_STATUS_INVALID_FILENAME', 21 => 'NET_SFTP_STATUS_LINK_LOOP', 22 => 'NET_SFTP_STATUS_CANNOT_DELETE', 23 => 'NET_SFTP_STATUS_INVALID_PARAMETER', 24 => 'NET_SFTP_STATUS_FILE_IS_A_DIRECTORY', 25 => 'NET_SFTP_STATUS_BYTE_RANGE_LOCK_CONFLICT', 26 => 'NET_SFTP_STATUS_BYTE_RANGE_LOCK_REFUSED', 27 => 'NET_SFTP_STATUS_DELETE_PENDING', 28 => 'NET_SFTP_STATUS_FILE_CORRUPT', 29 => 'NET_SFTP_STATUS_OWNER_INVALID', 30 => 'NET_SFTP_STATUS_GROUP_INVALID', 31 => 'NET_SFTP_STATUS_NO_MATCHING_BYTE_RANGE_LOCK' ]; // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-7.1 // the order, in this case, matters quite a lot - see \phpseclib3\Net\SFTP::_parseAttributes() to understand why self::$attributes = [ 0x00000001 => 'NET_SFTP_ATTR_SIZE', 0x00000002 => 'NET_SFTP_ATTR_UIDGID', // defined in SFTPv3, removed in SFTPv4+ 0x00000080 => 'NET_SFTP_ATTR_OWNERGROUP', // defined in SFTPv4+ 0x00000004 => 'NET_SFTP_ATTR_PERMISSIONS', 0x00000008 => 'NET_SFTP_ATTR_ACCESSTIME', 0x00000010 => 'NET_SFTP_ATTR_CREATETIME', // SFTPv4+ 0x00000020 => 'NET_SFTP_ATTR_MODIFYTIME', 0x00000040 => 'NET_SFTP_ATTR_ACL', 0x00000100 => 'NET_SFTP_ATTR_SUBSECOND_TIMES', 0x00000200 => 'NET_SFTP_ATTR_BITS', // SFTPv5+ 0x00000400 => 'NET_SFTP_ATTR_ALLOCATION_SIZE', // SFTPv6+ 0x00000800 => 'NET_SFTP_ATTR_TEXT_HINT', 0x00001000 => 'NET_SFTP_ATTR_MIME_TYPE', 0x00002000 => 'NET_SFTP_ATTR_LINK_COUNT', 0x00004000 => 'NET_SFTP_ATTR_UNTRANSLATED_NAME', 0x00008000 => 'NET_SFTP_ATTR_CTIME', // 0x80000000 will yield a floating point on 32-bit systems and converting floating points to integers // yields inconsistent behavior depending on how php is compiled. so we left shift -1 (which, in // two's compliment, consists of all 1 bits) by 31. on 64-bit systems this'll yield 0xFFFFFFFF80000000. // that's not a problem, however, and 'anded' and a 32-bit number, as all the leading 1 bits are ignored. (PHP_INT_SIZE == 4 ? (-1 << 31) : 0x80000000) => 'NET_SFTP_ATTR_EXTENDED' ]; // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-6.3 // the flag definitions change somewhat in SFTPv5+. if SFTPv5+ support is added to this library, maybe name // the array for that $this->open5_flags and similarly alter the constant names. self::$open_flags = [ 0x00000001 => 'NET_SFTP_OPEN_READ', 0x00000002 => 'NET_SFTP_OPEN_WRITE', 0x00000004 => 'NET_SFTP_OPEN_APPEND', 0x00000008 => 'NET_SFTP_OPEN_CREATE', 0x00000010 => 'NET_SFTP_OPEN_TRUNCATE', 0x00000020 => 'NET_SFTP_OPEN_EXCL', 0x00000040 => 'NET_SFTP_OPEN_TEXT' // defined in SFTPv4 ]; // SFTPv5+ changed the flags up: // https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-8.1.1.3 self::$open_flags5 = [ // when SSH_FXF_ACCESS_DISPOSITION is a 3 bit field that controls how the file is opened 0x00000000 => 'NET_SFTP_OPEN_CREATE_NEW', 0x00000001 => 'NET_SFTP_OPEN_CREATE_TRUNCATE', 0x00000002 => 'NET_SFTP_OPEN_OPEN_EXISTING', 0x00000003 => 'NET_SFTP_OPEN_OPEN_OR_CREATE', 0x00000004 => 'NET_SFTP_OPEN_TRUNCATE_EXISTING', // the rest of the flags are not supported 0x00000008 => 'NET_SFTP_OPEN_APPEND_DATA', // "the offset field of SS_FXP_WRITE requests is ignored" 0x00000010 => 'NET_SFTP_OPEN_APPEND_DATA_ATOMIC', 0x00000020 => 'NET_SFTP_OPEN_TEXT_MODE', 0x00000040 => 'NET_SFTP_OPEN_BLOCK_READ', 0x00000080 => 'NET_SFTP_OPEN_BLOCK_WRITE', 0x00000100 => 'NET_SFTP_OPEN_BLOCK_DELETE', 0x00000200 => 'NET_SFTP_OPEN_BLOCK_ADVISORY', 0x00000400 => 'NET_SFTP_OPEN_NOFOLLOW', 0x00000800 => 'NET_SFTP_OPEN_DELETE_ON_CLOSE', 0x00001000 => 'NET_SFTP_OPEN_ACCESS_AUDIT_ALARM_INFO', 0x00002000 => 'NET_SFTP_OPEN_ACCESS_BACKUP', 0x00004000 => 'NET_SFTP_OPEN_BACKUP_STREAM', 0x00008000 => 'NET_SFTP_OPEN_OVERRIDE_OWNER', ]; // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-5.2 // see \phpseclib3\Net\SFTP::_parseLongname() for an explanation self::$file_types = [ 1 => 'NET_SFTP_TYPE_REGULAR', 2 => 'NET_SFTP_TYPE_DIRECTORY', 3 => 'NET_SFTP_TYPE_SYMLINK', 4 => 'NET_SFTP_TYPE_SPECIAL', 5 => 'NET_SFTP_TYPE_UNKNOWN', // the following types were first defined for use in SFTPv5+ // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-05#section-5.2 6 => 'NET_SFTP_TYPE_SOCKET', 7 => 'NET_SFTP_TYPE_CHAR_DEVICE', 8 => 'NET_SFTP_TYPE_BLOCK_DEVICE', 9 => 'NET_SFTP_TYPE_FIFO' ]; self::define_array( self::$packet_types, self::$status_codes, self::$attributes, self::$open_flags, self::$open_flags5, self::$file_types ); } if (!defined('NET_SFTP_QUEUE_SIZE')) { define('NET_SFTP_QUEUE_SIZE', 32); } if (!defined('NET_SFTP_UPLOAD_QUEUE_SIZE')) { define('NET_SFTP_UPLOAD_QUEUE_SIZE', 1024); } } /** * Check a few things before SFTP functions are called * * @return bool */ private function precheck() { if (!($this->bitmap & SSH2::MASK_LOGIN)) { return false; } if ($this->pwd === false) { return $this->init_sftp_connection(); } return true; } /** * Partially initialize an SFTP connection * * @throws \UnexpectedValueException on receipt of unexpected packets * @return bool */ private function partial_init_sftp_connection() { $response = $this->open_channel(self::CHANNEL, true); if ($response === true && $this->isTimeout()) { return false; } $packet = Strings::packSSH2( 'CNsbs', NET_SSH2_MSG_CHANNEL_REQUEST, $this->server_channels[self::CHANNEL], 'subsystem', true, 'sftp' ); $this->send_binary_packet($packet); $this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_REQUEST; $response = $this->get_channel_packet(self::CHANNEL, true); if ($response === false) { // from PuTTY's psftp.exe $command = "test -x /usr/lib/sftp-server && exec /usr/lib/sftp-server\n" . "test -x /usr/local/lib/sftp-server && exec /usr/local/lib/sftp-server\n" . "exec sftp-server"; // we don't do $this->exec($command, false) because exec() operates on a different channel and plus the SSH_MSG_CHANNEL_OPEN that exec() does // is redundant $packet = Strings::packSSH2( 'CNsCs', NET_SSH2_MSG_CHANNEL_REQUEST, $this->server_channels[self::CHANNEL], 'exec', 1, $command ); $this->send_binary_packet($packet); $this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_REQUEST; $response = $this->get_channel_packet(self::CHANNEL, true); if ($response === false) { return false; } } elseif ($response === true && $this->isTimeout()) { return false; } $this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_DATA; $this->send_sftp_packet(NET_SFTP_INIT, "\0\0\0\3"); $response = $this->get_sftp_packet(); if ($this->packet_type != NET_SFTP_VERSION) { throw new \UnexpectedValueException('Expected NET_SFTP_VERSION. ' . 'Got packet type: ' . $this->packet_type); } $this->use_request_id = true; list($this->defaultVersion) = Strings::unpackSSH2('N', $response); while (!empty($response)) { list($key, $value) = Strings::unpackSSH2('ss', $response); $this->extensions[$key] = $value; } $this->partial_init = true; return true; } /** * (Re)initializes the SFTP channel * * @return bool */ private function init_sftp_connection() { if (!$this->partial_init && !$this->partial_init_sftp_connection()) { return false; } /* A Note on SFTPv4/5/6 support: states the following: "If the client wishes to interoperate with servers that support noncontiguous version numbers it SHOULD send '3'" Given that the server only sends its version number after the client has already done so, the above seems to be suggesting that v3 should be the default version. This makes sense given that v3 is the most popular. states the following; "If the server did not send the "versions" extension, or the version-from-list was not included, the server MAY send a status response describing the failure, but MUST then close the channel without processing any further requests." So what do you do if you have a client whose initial SSH_FXP_INIT packet says it implements v3 and a server whose initial SSH_FXP_VERSION reply says it implements v4 and only v4? If it only implements v4, the "versions" extension is likely not going to have been sent so version re-negotiation as discussed in draft-ietf-secsh-filexfer-13 would be quite impossible. As such, what \phpseclib3\Net\SFTP would do is close the channel and reopen it with a new and updated SSH_FXP_INIT packet. */ $this->version = $this->defaultVersion; if (isset($this->extensions['versions']) && (!$this->preferredVersion || $this->preferredVersion != $this->version)) { $versions = explode(',', $this->extensions['versions']); $supported = [6, 5, 4]; if ($this->preferredVersion) { $supported = array_diff($supported, [$this->preferredVersion]); array_unshift($supported, $this->preferredVersion); } foreach ($supported as $ver) { if (in_array($ver, $versions)) { if ($ver === $this->version) { break; } $this->version = (int) $ver; $packet = Strings::packSSH2('ss', 'version-select', "$ver"); $this->send_sftp_packet(NET_SFTP_EXTENDED, $packet); $response = $this->get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' . 'Got packet type: ' . $this->packet_type); } list($status) = Strings::unpackSSH2('N', $response); if ($status != NET_SFTP_STATUS_OK) { $this->logError($response, $status); throw new \UnexpectedValueException('Expected NET_SFTP_STATUS_OK. ' . ' Got ' . $status); } break; } } } /* SFTPv4+ defines a 'newline' extension. SFTPv3 seems to have unofficial support for it via 'newline@vandyke.com', however, I'm not sure what 'newline@vandyke.com' is supposed to do (the fact that it's unofficial means that it's not in the official SFTPv3 specs) and 'newline@vandyke.com' / 'newline' are likely not drop-in substitutes for one another due to the fact that 'newline' comes with a SSH_FXF_TEXT bitmask whereas it seems unlikely that 'newline@vandyke.com' would. */ /* if (isset($this->extensions['newline@vandyke.com'])) { $this->extensions['newline'] = $this->extensions['newline@vandyke.com']; unset($this->extensions['newline@vandyke.com']); } */ if ($this->version < 2 || $this->version > 6) { return false; } $this->pwd = true; try { $this->pwd = $this->realpath('.'); } catch (\UnexpectedValueException $e) { if (!$this->canonicalize_paths) { throw $e; } $this->canonicalize_paths = false; $this->reset_sftp(); return $this->init_sftp_connection(); } $this->update_stat_cache($this->pwd, []); return true; } /** * Disable the stat cache * */ public function disableStatCache() { $this->use_stat_cache = false; } /** * Enable the stat cache * */ public function enableStatCache() { $this->use_stat_cache = true; } /** * Clear the stat cache * */ public function clearStatCache() { $this->stat_cache = []; } /** * Enable path canonicalization * */ public function enablePathCanonicalization() { $this->canonicalize_paths = true; } /** * Disable path canonicalization * * If this is enabled then $sftp->pwd() will not return the canonicalized absolute path * */ public function disablePathCanonicalization() { $this->canonicalize_paths = false; } /** * Enable arbitrary length packets * */ public function enableArbitraryLengthPackets() { $this->allow_arbitrary_length_packets = true; } /** * Disable arbitrary length packets * */ public function disableArbitraryLengthPackets() { $this->allow_arbitrary_length_packets = false; } /** * Returns the current directory name * * @return string|bool */ public function pwd() { if (!$this->precheck()) { return false; } return $this->pwd; } /** * Logs errors * * @param string $response * @param int $status */ private function logError($response, $status = -1) { if ($status == -1) { list($status) = Strings::unpackSSH2('N', $response); } $error = self::$status_codes[$status]; if ($this->version > 2) { list($message) = Strings::unpackSSH2('s', $response); $this->sftp_errors[] = "$error: $message"; } else { $this->sftp_errors[] = $error; } } /** * Canonicalize the Server-Side Path Name * * SFTP doesn't provide a mechanism by which the current working directory can be changed, so we'll emulate it. Returns * the absolute (canonicalized) path. * * If canonicalize_paths has been disabled using disablePathCanonicalization(), $path is returned as-is. * * @see self::chdir() * @see self::disablePathCanonicalization() * @param string $path * @throws \UnexpectedValueException on receipt of unexpected packets * @return mixed */ public function realpath($path) { if ($this->precheck() === false) { return false; } $path = (string) $path; if (!$this->canonicalize_paths) { if ($this->pwd === true) { return '.'; } if (!strlen($path) || $path[0] != '/') { $path = $this->pwd . '/' . $path; } $parts = explode('/', $path); $afterPWD = $beforePWD = []; foreach ($parts as $part) { switch ($part) { //case '': // some SFTP servers /require/ double /'s. see https://github.com/phpseclib/phpseclib/pull/1137 case '.': break; case '..': if (!empty($afterPWD)) { array_pop($afterPWD); } else { $beforePWD[] = '..'; } break; default: $afterPWD[] = $part; } } $beforePWD = count($beforePWD) ? implode('/', $beforePWD) : '.'; return $beforePWD . '/' . implode('/', $afterPWD); } if ($this->pwd === true) { // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.9 $this->send_sftp_packet(NET_SFTP_REALPATH, Strings::packSSH2('s', $path)); $response = $this->get_sftp_packet(); switch ($this->packet_type) { case NET_SFTP_NAME: // although SSH_FXP_NAME is implemented differently in SFTPv3 than it is in SFTPv4+, the following // should work on all SFTP versions since the only part of the SSH_FXP_NAME packet the following looks // at is the first part and that part is defined the same in SFTP versions 3 through 6. list(, $filename) = Strings::unpackSSH2('Ns', $response); return $filename; case NET_SFTP_STATUS: $this->logError($response); return false; default: throw new \UnexpectedValueException('Expected NET_SFTP_NAME or NET_SFTP_STATUS. ' . 'Got packet type: ' . $this->packet_type); } } if (!strlen($path) || $path[0] != '/') { $path = $this->pwd . '/' . $path; } $path = explode('/', $path); $new = []; foreach ($path as $dir) { if (!strlen($dir)) { continue; } switch ($dir) { case '..': array_pop($new); // fall-through case '.': break; default: $new[] = $dir; } } return '/' . implode('/', $new); } /** * Changes the current directory * * @param string $dir * @throws \UnexpectedValueException on receipt of unexpected packets * @return bool */ public function chdir($dir) { if (!$this->precheck()) { return false; } $dir = (string) $dir; // assume current dir if $dir is empty if ($dir === '') { $dir = './'; // suffix a slash if needed } elseif ($dir[strlen($dir) - 1] != '/') { $dir .= '/'; } $dir = $this->realpath($dir); if ($dir === false) { return false; } // confirm that $dir is, in fact, a valid directory if ($this->use_stat_cache && is_array($this->query_stat_cache($dir))) { $this->pwd = $dir; return true; } // we could do a stat on the alleged $dir to see if it's a directory but that doesn't tell us // the currently logged in user has the appropriate permissions or not. maybe you could see if // the file's uid / gid match the currently logged in user's uid / gid but how there's no easy // way to get those with SFTP $this->send_sftp_packet(NET_SFTP_OPENDIR, Strings::packSSH2('s', $dir)); // see \phpseclib3\Net\SFTP::nlist() for a more thorough explanation of the following $response = $this->get_sftp_packet(); switch ($this->packet_type) { case NET_SFTP_HANDLE: $handle = substr($response, 4); break; case NET_SFTP_STATUS: $this->logError($response); return false; default: throw new \UnexpectedValueException('Expected NET_SFTP_HANDLE or NET_SFTP_STATUS' . 'Got packet type: ' . $this->packet_type); } if (!$this->close_handle($handle)) { return false; } $this->update_stat_cache($dir, []); $this->pwd = $dir; return true; } /** * Returns a list of files in the given directory * * @param string $dir * @param bool $recursive * @return array|false */ public function nlist($dir = '.', $recursive = false) { return $this->nlist_helper($dir, $recursive, ''); } /** * Helper method for nlist * * @param string $dir * @param bool $recursive * @param string $relativeDir * @return array|false */ private function nlist_helper($dir, $recursive, $relativeDir) { $files = $this->readlist($dir, false); // If we get an int back, then that is an "unexpected" status. // We do not have a file list, so return false. if (is_int($files)) { return false; } if (!$recursive || $files === false) { return $files; } $result = []; foreach ($files as $value) { if ($value == '.' || $value == '..') { $result[] = $relativeDir . $value; continue; } if (is_array($this->query_stat_cache($this->realpath($dir . '/' . $value)))) { $temp = $this->nlist_helper($dir . '/' . $value, true, $relativeDir . $value . '/'); $temp = is_array($temp) ? $temp : []; $result = array_merge($result, $temp); } else { $result[] = $relativeDir . $value; } } return $result; } /** * Returns a detailed list of files in the given directory * * @param string $dir * @param bool $recursive * @return array|false */ public function rawlist($dir = '.', $recursive = false) { $files = $this->readlist($dir, true); // If we get an int back, then that is an "unexpected" status. // We do not have a file list, so return false. if (is_int($files)) { return false; } if (!$recursive || $files === false) { return $files; } static $depth = 0; foreach ($files as $key => $value) { if ($depth != 0 && $key == '..') { unset($files[$key]); continue; } $is_directory = false; if ($key != '.' && $key != '..') { if ($this->use_stat_cache) { $is_directory = is_array($this->query_stat_cache($this->realpath($dir . '/' . $key))); } else { $stat = $this->lstat($dir . '/' . $key); $is_directory = $stat && $stat['type'] === NET_SFTP_TYPE_DIRECTORY; } } if ($is_directory) { $depth++; $files[$key] = $this->rawlist($dir . '/' . $key, true); $depth--; } else { $files[$key] = (object) $value; } } return $files; } /** * Reads a list, be it detailed or not, of files in the given directory * * @param string $dir * @param bool $raw * @return array|false * @throws \UnexpectedValueException on receipt of unexpected packets */ private function readlist($dir, $raw = true) { if (!$this->precheck()) { return false; } $dir = $this->realpath($dir . '/'); if ($dir === false) { return false; } // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.1.2 $this->send_sftp_packet(NET_SFTP_OPENDIR, Strings::packSSH2('s', $dir)); $response = $this->get_sftp_packet(); switch ($this->packet_type) { case NET_SFTP_HANDLE: // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-9.2 // since 'handle' is the last field in the SSH_FXP_HANDLE packet, we'll just remove the first four bytes that // represent the length of the string and leave it at that $handle = substr($response, 4); break; case NET_SFTP_STATUS: // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED list($status) = Strings::unpackSSH2('N', $response); $this->logError($response, $status); return $status; default: throw new \UnexpectedValueException('Expected NET_SFTP_HANDLE or NET_SFTP_STATUS. ' . 'Got packet type: ' . $this->packet_type); } $this->update_stat_cache($dir, []); $contents = []; while (true) { // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.2.2 // why multiple SSH_FXP_READDIR packets would be sent when the response to a single one can span arbitrarily many // SSH_MSG_CHANNEL_DATA messages is not known to me. $this->send_sftp_packet(NET_SFTP_READDIR, Strings::packSSH2('s', $handle)); $response = $this->get_sftp_packet(); switch ($this->packet_type) { case NET_SFTP_NAME: list($count) = Strings::unpackSSH2('N', $response); for ($i = 0; $i < $count; $i++) { list($shortname) = Strings::unpackSSH2('s', $response); // SFTPv4 "removed the long filename from the names structure-- it can now be // built from information available in the attrs structure." if ($this->version < 4) { list($longname) = Strings::unpackSSH2('s', $response); } $attributes = $this->parseAttributes($response); if (!isset($attributes['type']) && $this->version < 4) { $fileType = $this->parseLongname($longname); if ($fileType) { $attributes['type'] = $fileType; } } $contents[$shortname] = $attributes + ['filename' => $shortname]; if (isset($attributes['type']) && $attributes['type'] == NET_SFTP_TYPE_DIRECTORY && ($shortname != '.' && $shortname != '..')) { $this->update_stat_cache($dir . '/' . $shortname, []); } else { if ($shortname == '..') { $temp = $this->realpath($dir . '/..') . '/.'; } else { $temp = $dir . '/' . $shortname; } $this->update_stat_cache($temp, (object) ['lstat' => $attributes]); } // SFTPv6 has an optional boolean end-of-list field, but we'll ignore that, since the // final SSH_FXP_STATUS packet should tell us that, already. } break; case NET_SFTP_STATUS: list($status) = Strings::unpackSSH2('N', $response); if ($status != NET_SFTP_STATUS_EOF) { $this->logError($response, $status); return $status; } break 2; default: throw new \UnexpectedValueException('Expected NET_SFTP_NAME or NET_SFTP_STATUS. ' . 'Got packet type: ' . $this->packet_type); } } if (!$this->close_handle($handle)) { return false; } if (count($this->sortOptions)) { uasort($contents, [&$this, 'comparator']); } return $raw ? $contents : array_map('strval', array_keys($contents)); } /** * Compares two rawlist entries using parameters set by setListOrder() * * Intended for use with uasort() * * @param array $a * @param array $b * @return int */ private function comparator(array $a, array $b) { switch (true) { case $a['filename'] === '.' || $b['filename'] === '.': if ($a['filename'] === $b['filename']) { return 0; } return $a['filename'] === '.' ? -1 : 1; case $a['filename'] === '..' || $b['filename'] === '..': if ($a['filename'] === $b['filename']) { return 0; } return $a['filename'] === '..' ? -1 : 1; case isset($a['type']) && $a['type'] === NET_SFTP_TYPE_DIRECTORY: if (!isset($b['type'])) { return 1; } if ($b['type'] !== $a['type']) { return -1; } break; case isset($b['type']) && $b['type'] === NET_SFTP_TYPE_DIRECTORY: return 1; } foreach ($this->sortOptions as $sort => $order) { if (!isset($a[$sort]) || !isset($b[$sort])) { if (isset($a[$sort])) { return -1; } if (isset($b[$sort])) { return 1; } return 0; } switch ($sort) { case 'filename': $result = strcasecmp($a['filename'], $b['filename']); if ($result) { return $order === SORT_DESC ? -$result : $result; } break; case 'mode': $a[$sort] &= 07777; $b[$sort] &= 07777; // fall-through default: if ($a[$sort] === $b[$sort]) { break; } return $order === SORT_ASC ? $a[$sort] - $b[$sort] : $b[$sort] - $a[$sort]; } } } /** * Defines how nlist() and rawlist() will be sorted - if at all. * * If sorting is enabled directories and files will be sorted independently with * directories appearing before files in the resultant array that is returned. * * Any parameter returned by stat is a valid sort parameter for this function. * Filename comparisons are case insensitive. * * Examples: * * $sftp->setListOrder('filename', SORT_ASC); * $sftp->setListOrder('size', SORT_DESC, 'filename', SORT_ASC); * $sftp->setListOrder(true); * Separates directories from files but doesn't do any sorting beyond that * $sftp->setListOrder(); * Don't do any sort of sorting * * @param string ...$args */ public function setListOrder(...$args) { $this->sortOptions = []; if (empty($args)) { return; } $len = count($args) & 0x7FFFFFFE; for ($i = 0; $i < $len; $i += 2) { $this->sortOptions[$args[$i]] = $args[$i + 1]; } if (!count($this->sortOptions)) { $this->sortOptions = ['bogus' => true]; } } /** * Save files / directories to cache * * @param string $path * @param mixed $value */ private function update_stat_cache($path, $value) { if ($this->use_stat_cache === false) { return; } // preg_replace('#^/|/(?=/)|/$#', '', $dir) == str_replace('//', '/', trim($path, '/')) $dirs = explode('/', preg_replace('#^/|/(?=/)|/$#', '', $path)); $temp = &$this->stat_cache; $max = count($dirs) - 1; foreach ($dirs as $i => $dir) { // if $temp is an object that means one of two things. // 1. a file was deleted and changed to a directory behind phpseclib's back // 2. it's a symlink. when lstat is done it's unclear what it's a symlink to if (is_object($temp)) { $temp = []; } if (!isset($temp[$dir])) { $temp[$dir] = []; } if ($i === $max) { if (is_object($temp[$dir]) && is_object($value)) { if (!isset($value->stat) && isset($temp[$dir]->stat)) { $value->stat = $temp[$dir]->stat; } if (!isset($value->lstat) && isset($temp[$dir]->lstat)) { $value->lstat = $temp[$dir]->lstat; } } $temp[$dir] = $value; break; } $temp = &$temp[$dir]; } } /** * Remove files / directories from cache * * @param string $path * @return bool */ private function remove_from_stat_cache($path) { $dirs = explode('/', preg_replace('#^/|/(?=/)|/$#', '', $path)); $temp = &$this->stat_cache; $max = count($dirs) - 1; foreach ($dirs as $i => $dir) { if (!is_array($temp)) { return false; } if ($i === $max) { unset($temp[$dir]); return true; } if (!isset($temp[$dir])) { return false; } $temp = &$temp[$dir]; } } /** * Checks cache for path * * Mainly used by file_exists * * @param string $path * @return mixed */ private function query_stat_cache($path) { $dirs = explode('/', preg_replace('#^/|/(?=/)|/$#', '', $path)); $temp = &$this->stat_cache; foreach ($dirs as $dir) { if (!is_array($temp)) { return null; } if (!isset($temp[$dir])) { return null; } $temp = &$temp[$dir]; } return $temp; } /** * Returns general information about a file. * * Returns an array on success and false otherwise. * * @param string $filename * @return array|false */ public function stat($filename) { if (!$this->precheck()) { return false; } $filename = $this->realpath($filename); if ($filename === false) { return false; } if ($this->use_stat_cache) { $result = $this->query_stat_cache($filename); if (is_array($result) && isset($result['.']) && isset($result['.']->stat)) { return $result['.']->stat; } if (is_object($result) && isset($result->stat)) { return $result->stat; } } $stat = $this->stat_helper($filename, NET_SFTP_STAT); if ($stat === false) { $this->remove_from_stat_cache($filename); return false; } if (isset($stat['type'])) { if ($stat['type'] == NET_SFTP_TYPE_DIRECTORY) { $filename .= '/.'; } $this->update_stat_cache($filename, (object) ['stat' => $stat]); return $stat; } $pwd = $this->pwd; $stat['type'] = $this->chdir($filename) ? NET_SFTP_TYPE_DIRECTORY : NET_SFTP_TYPE_REGULAR; $this->pwd = $pwd; if ($stat['type'] == NET_SFTP_TYPE_DIRECTORY) { $filename .= '/.'; } $this->update_stat_cache($filename, (object) ['stat' => $stat]); return $stat; } /** * Returns general information about a file or symbolic link. * * Returns an array on success and false otherwise. * * @param string $filename * @return array|false */ public function lstat($filename) { if (!$this->precheck()) { return false; } $filename = $this->realpath($filename); if ($filename === false) { return false; } if ($this->use_stat_cache) { $result = $this->query_stat_cache($filename); if (is_array($result) && isset($result['.']) && isset($result['.']->lstat)) { return $result['.']->lstat; } if (is_object($result) && isset($result->lstat)) { return $result->lstat; } } $lstat = $this->stat_helper($filename, NET_SFTP_LSTAT); if ($lstat === false) { $this->remove_from_stat_cache($filename); return false; } if (isset($lstat['type'])) { if ($lstat['type'] == NET_SFTP_TYPE_DIRECTORY) { $filename .= '/.'; } $this->update_stat_cache($filename, (object) ['lstat' => $lstat]); return $lstat; } $stat = $this->stat_helper($filename, NET_SFTP_STAT); if ($lstat != $stat) { $lstat = array_merge($lstat, ['type' => NET_SFTP_TYPE_SYMLINK]); $this->update_stat_cache($filename, (object) ['lstat' => $lstat]); return $stat; } $pwd = $this->pwd; $lstat['type'] = $this->chdir($filename) ? NET_SFTP_TYPE_DIRECTORY : NET_SFTP_TYPE_REGULAR; $this->pwd = $pwd; if ($lstat['type'] == NET_SFTP_TYPE_DIRECTORY) { $filename .= '/.'; } $this->update_stat_cache($filename, (object) ['lstat' => $lstat]); return $lstat; } /** * Returns general information about a file or symbolic link * * Determines information without calling \phpseclib3\Net\SFTP::realpath(). * The second parameter can be either NET_SFTP_STAT or NET_SFTP_LSTAT. * * @param string $filename * @param int $type * @throws \UnexpectedValueException on receipt of unexpected packets * @return array|false */ private function stat_helper($filename, $type) { // SFTPv4+ adds an additional 32-bit integer field - flags - to the following: $packet = Strings::packSSH2('s', $filename); $this->send_sftp_packet($type, $packet); $response = $this->get_sftp_packet(); switch ($this->packet_type) { case NET_SFTP_ATTRS: return $this->parseAttributes($response); case NET_SFTP_STATUS: $this->logError($response); return false; } throw new \UnexpectedValueException('Expected NET_SFTP_ATTRS or NET_SFTP_STATUS. ' . 'Got packet type: ' . $this->packet_type); } /** * Truncates a file to a given length * * @param string $filename * @param int $new_size * @return bool */ public function truncate($filename, $new_size) { $attr = Strings::packSSH2('NQ', NET_SFTP_ATTR_SIZE, $new_size); return $this->setstat($filename, $attr, false); } /** * Sets access and modification time of file. * * If the file does not exist, it will be created. * * @param string $filename * @param int $time * @param int $atime * @throws \UnexpectedValueException on receipt of unexpected packets * @return bool */ public function touch($filename, $time = null, $atime = null) { if (!$this->precheck()) { return false; } $filename = $this->realpath($filename); if ($filename === false) { return false; } if (!isset($time)) { $time = time(); } if (!isset($atime)) { $atime = $time; } $attr = $this->version < 4 ? pack('N3', NET_SFTP_ATTR_ACCESSTIME, $atime, $time) : Strings::packSSH2('NQ2', NET_SFTP_ATTR_ACCESSTIME | NET_SFTP_ATTR_MODIFYTIME, $atime, $time); $packet = Strings::packSSH2('s', $filename); $packet .= $this->version >= 5 ? pack('N2', 0, NET_SFTP_OPEN_OPEN_EXISTING) : pack('N', NET_SFTP_OPEN_WRITE | NET_SFTP_OPEN_CREATE | NET_SFTP_OPEN_EXCL); $packet .= $attr; $this->send_sftp_packet(NET_SFTP_OPEN, $packet); $response = $this->get_sftp_packet(); switch ($this->packet_type) { case NET_SFTP_HANDLE: return $this->close_handle(substr($response, 4)); case NET_SFTP_STATUS: $this->logError($response); break; default: throw new \UnexpectedValueException('Expected NET_SFTP_HANDLE or NET_SFTP_STATUS. ' . 'Got packet type: ' . $this->packet_type); } return $this->setstat($filename, $attr, false); } /** * Changes file or directory owner * * $uid should be an int for SFTPv3 and a string for SFTPv4+. Ideally the string * would be of the form "user@dns_domain" but it does not need to be. * `$sftp->getSupportedVersions()['version']` will return the specific version * that's being used. * * Returns true on success or false on error. * * @param string $filename * @param int|string $uid * @param bool $recursive * @return bool */ public function chown($filename, $uid, $recursive = false) { /* quoting , "To avoid a representation that is tied to a particular underlying implementation at the client or server, the use of UTF-8 strings has been chosen. The string should be of the form "user@dns_domain". This will allow for a client and server that do not use the same local representation the ability to translate to a common syntax that can be interpreted by both. In the case where there is no translation available to the client or server, the attribute value must be constructed without the "@"." phpseclib _could_ auto append the dns_domain to $uid BUT what if it shouldn't have one? phpseclib would have no way of knowing so rather than guess phpseclib will just use whatever value the user provided */ $attr = $this->version < 4 ? // quoting , // "if the owner or group is specified as -1, then that ID is not changed" pack('N3', NET_SFTP_ATTR_UIDGID, $uid, -1) : // quoting , // "If either the owner or group field is zero length, the field should be // considered absent, and no change should be made to that specific field // during a modification operation" Strings::packSSH2('Nss', NET_SFTP_ATTR_OWNERGROUP, $uid, ''); return $this->setstat($filename, $attr, $recursive); } /** * Changes file or directory group * * $gid should be an int for SFTPv3 and a string for SFTPv4+. Ideally the string * would be of the form "user@dns_domain" but it does not need to be. * `$sftp->getSupportedVersions()['version']` will return the specific version * that's being used. * * Returns true on success or false on error. * * @param string $filename * @param int|string $gid * @param bool $recursive * @return bool */ public function chgrp($filename, $gid, $recursive = false) { $attr = $this->version < 4 ? pack('N3', NET_SFTP_ATTR_UIDGID, -1, $gid) : Strings::packSSH2('Nss', NET_SFTP_ATTR_OWNERGROUP, '', $gid); return $this->setstat($filename, $attr, $recursive); } /** * Set permissions on a file. * * Returns the new file permissions on success or false on error. * If $recursive is true than this just returns true or false. * * @param int $mode * @param string $filename * @param bool $recursive * @throws \UnexpectedValueException on receipt of unexpected packets * @return mixed */ public function chmod($mode, $filename, $recursive = false) { if (is_string($mode) && is_int($filename)) { $temp = $mode; $mode = $filename; $filename = $temp; } $attr = pack('N2', NET_SFTP_ATTR_PERMISSIONS, $mode & 07777); if (!$this->setstat($filename, $attr, $recursive)) { return false; } if ($recursive) { return true; } $filename = $this->realpath($filename); // rather than return what the permissions *should* be, we'll return what they actually are. this will also // tell us if the file actually exists. // incidentally, SFTPv4+ adds an additional 32-bit integer field - flags - to the following: $packet = pack('Na*', strlen($filename), $filename); $this->send_sftp_packet(NET_SFTP_STAT, $packet); $response = $this->get_sftp_packet(); switch ($this->packet_type) { case NET_SFTP_ATTRS: $attrs = $this->parseAttributes($response); return $attrs['mode']; case NET_SFTP_STATUS: $this->logError($response); return false; } throw new \UnexpectedValueException('Expected NET_SFTP_ATTRS or NET_SFTP_STATUS. ' . 'Got packet type: ' . $this->packet_type); } /** * Sets information about a file * * @param string $filename * @param string $attr * @param bool $recursive * @throws \UnexpectedValueException on receipt of unexpected packets * @return bool */ private function setstat($filename, $attr, $recursive) { if (!$this->precheck()) { return false; } $filename = $this->realpath($filename); if ($filename === false) { return false; } $this->remove_from_stat_cache($filename); if ($recursive) { $i = 0; $result = $this->setstat_recursive($filename, $attr, $i); $this->read_put_responses($i); return $result; } $packet = Strings::packSSH2('s', $filename); $packet .= $this->version >= 4 ? pack('a*Ca*', substr($attr, 0, 4), NET_SFTP_TYPE_UNKNOWN, substr($attr, 4)) : $attr; $this->send_sftp_packet(NET_SFTP_SETSTAT, $packet); /* "Because some systems must use separate system calls to set various attributes, it is possible that a failure response will be returned, but yet some of the attributes may be have been successfully modified. If possible, servers SHOULD avoid this situation; however, clients MUST be aware that this is possible." -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.6 */ $response = $this->get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' . 'Got packet type: ' . $this->packet_type); } list($status) = Strings::unpackSSH2('N', $response); if ($status != NET_SFTP_STATUS_OK) { $this->logError($response, $status); return false; } return true; } /** * Recursively sets information on directories on the SFTP server * * Minimizes directory lookups and SSH_FXP_STATUS requests for speed. * * @param string $path * @param string $attr * @param int $i * @return bool */ private function setstat_recursive($path, $attr, &$i) { if (!$this->read_put_responses($i)) { return false; } $i = 0; $entries = $this->readlist($path, true); if ($entries === false || is_int($entries)) { return $this->setstat($path, $attr, false); } // normally $entries would have at least . and .. but it might not if the directories // permissions didn't allow reading if (empty($entries)) { return false; } unset($entries['.'], $entries['..']); foreach ($entries as $filename => $props) { if (!isset($props['type'])) { return false; } $temp = $path . '/' . $filename; if ($props['type'] == NET_SFTP_TYPE_DIRECTORY) { if (!$this->setstat_recursive($temp, $attr, $i)) { return false; } } else { $packet = Strings::packSSH2('s', $temp); $packet .= $this->version >= 4 ? pack('Ca*', NET_SFTP_TYPE_UNKNOWN, $attr) : $attr; $this->send_sftp_packet(NET_SFTP_SETSTAT, $packet); $i++; if ($i >= NET_SFTP_QUEUE_SIZE) { if (!$this->read_put_responses($i)) { return false; } $i = 0; } } } $packet = Strings::packSSH2('s', $path); $packet .= $this->version >= 4 ? pack('Ca*', NET_SFTP_TYPE_UNKNOWN, $attr) : $attr; $this->send_sftp_packet(NET_SFTP_SETSTAT, $packet); $i++; if ($i >= NET_SFTP_QUEUE_SIZE) { if (!$this->read_put_responses($i)) { return false; } $i = 0; } return true; } /** * Return the target of a symbolic link * * @param string $link * @throws \UnexpectedValueException on receipt of unexpected packets * @return mixed */ public function readlink($link) { if (!$this->precheck()) { return false; } $link = $this->realpath($link); $this->send_sftp_packet(NET_SFTP_READLINK, Strings::packSSH2('s', $link)); $response = $this->get_sftp_packet(); switch ($this->packet_type) { case NET_SFTP_NAME: break; case NET_SFTP_STATUS: $this->logError($response); return false; default: throw new \UnexpectedValueException('Expected NET_SFTP_NAME or NET_SFTP_STATUS. ' . 'Got packet type: ' . $this->packet_type); } list($count) = Strings::unpackSSH2('N', $response); // the file isn't a symlink if (!$count) { return false; } list($filename) = Strings::unpackSSH2('s', $response); return $filename; } /** * Create a symlink * * symlink() creates a symbolic link to the existing target with the specified name link. * * @param string $target * @param string $link * @throws \UnexpectedValueException on receipt of unexpected packets * @return bool */ public function symlink($target, $link) { if (!$this->precheck()) { return false; } //$target = $this->realpath($target); $link = $this->realpath($link); /* quoting https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-09#section-12.1 : Changed the SYMLINK packet to be LINK and give it the ability to create hard links. Also change it's packet number because many implementation implemented SYMLINK with the arguments reversed. Hopefully the new argument names make it clear which way is which. */ if ($this->version == 6) { $type = NET_SFTP_LINK; $packet = Strings::packSSH2('ssC', $link, $target, 1); } else { $type = NET_SFTP_SYMLINK; /* quoting http://bxr.su/OpenBSD/usr.bin/ssh/PROTOCOL#347 : 3.1. sftp: Reversal of arguments to SSH_FXP_SYMLINK When OpenSSH's sftp-server was implemented, the order of the arguments to the SSH_FXP_SYMLINK method was inadvertently reversed. Unfortunately, the reversal was not noticed until the server was widely deployed. Since fixing this to follow the specification would cause incompatibility, the current order was retained. For correct operation, clients should send SSH_FXP_SYMLINK as follows: uint32 id string targetpath string linkpath */ $packet = substr($this->server_identifier, 0, 15) == 'SSH-2.0-OpenSSH' ? Strings::packSSH2('ss', $target, $link) : Strings::packSSH2('ss', $link, $target); } $this->send_sftp_packet($type, $packet); $response = $this->get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' . 'Got packet type: ' . $this->packet_type); } list($status) = Strings::unpackSSH2('N', $response); if ($status != NET_SFTP_STATUS_OK) { $this->logError($response, $status); return false; } return true; } /** * Creates a directory. * * @param string $dir * @param int $mode * @param bool $recursive * @return bool */ public function mkdir($dir, $mode = -1, $recursive = false) { if (!$this->precheck()) { return false; } $dir = $this->realpath($dir); if ($recursive) { $dirs = explode('/', preg_replace('#/(?=/)|/$#', '', $dir)); if (empty($dirs[0])) { array_shift($dirs); $dirs[0] = '/' . $dirs[0]; } for ($i = 0; $i < count($dirs); $i++) { $temp = array_slice($dirs, 0, $i + 1); $temp = implode('/', $temp); $result = $this->mkdir_helper($temp, $mode); } return $result; } return $this->mkdir_helper($dir, $mode); } /** * Helper function for directory creation * * @param string $dir * @param int $mode * @return bool */ private function mkdir_helper($dir, $mode) { // send SSH_FXP_MKDIR without any attributes (that's what the \0\0\0\0 is doing) $this->send_sftp_packet(NET_SFTP_MKDIR, Strings::packSSH2('s', $dir) . "\0\0\0\0"); $response = $this->get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' . 'Got packet type: ' . $this->packet_type); } list($status) = Strings::unpackSSH2('N', $response); if ($status != NET_SFTP_STATUS_OK) { $this->logError($response, $status); return false; } if ($mode !== -1) { $this->chmod($mode, $dir); } return true; } /** * Removes a directory. * * @param string $dir * @throws \UnexpectedValueException on receipt of unexpected packets * @return bool */ public function rmdir($dir) { if (!$this->precheck()) { return false; } $dir = $this->realpath($dir); if ($dir === false) { return false; } $this->send_sftp_packet(NET_SFTP_RMDIR, Strings::packSSH2('s', $dir)); $response = $this->get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' . 'Got packet type: ' . $this->packet_type); } list($status) = Strings::unpackSSH2('N', $response); if ($status != NET_SFTP_STATUS_OK) { // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED? $this->logError($response, $status); return false; } $this->remove_from_stat_cache($dir); // the following will do a soft delete, which would be useful if you deleted a file // and then tried to do a stat on the deleted file. the above, in contrast, does // a hard delete //$this->update_stat_cache($dir, false); return true; } /** * Uploads a file to the SFTP server. * * By default, \phpseclib3\Net\SFTP::put() does not read from the local filesystem. $data is dumped directly into $remote_file. * So, for example, if you set $data to 'filename.ext' and then do \phpseclib3\Net\SFTP::get(), you will get a file, twelve bytes * long, containing 'filename.ext' as its contents. * * Setting $mode to self::SOURCE_LOCAL_FILE will change the above behavior. With self::SOURCE_LOCAL_FILE, $remote_file will * contain as many bytes as filename.ext does on your local filesystem. If your filename.ext is 1MB then that is how * large $remote_file will be, as well. * * Setting $mode to self::SOURCE_CALLBACK will use $data as callback function, which gets only one parameter -- number * of bytes to return, and returns a string if there is some data or null if there is no more data * * If $data is a resource then it'll be used as a resource instead. * * Currently, only binary mode is supported. As such, if the line endings need to be adjusted, you will need to take * care of that, yourself. * * $mode can take an additional two parameters - self::RESUME and self::RESUME_START. These are bitwise AND'd with * $mode. So if you want to resume upload of a 300mb file on the local file system you'd set $mode to the following: * * self::SOURCE_LOCAL_FILE | self::RESUME * * If you wanted to simply append the full contents of a local file to the full contents of a remote file you'd replace * self::RESUME with self::RESUME_START. * * If $mode & (self::RESUME | self::RESUME_START) then self::RESUME_START will be assumed. * * $start and $local_start give you more fine grained control over this process and take precident over self::RESUME * when they're non-negative. ie. $start could let you write at the end of a file (like self::RESUME) or in the middle * of one. $local_start could let you start your reading from the end of a file (like self::RESUME_START) or in the * middle of one. * * Setting $local_start to > 0 or $mode | self::RESUME_START doesn't do anything unless $mode | self::SOURCE_LOCAL_FILE. * * {@internal ASCII mode for SFTPv4/5/6 can be supported by adding a new function - \phpseclib3\Net\SFTP::setMode().} * * @param string $remote_file * @param string|resource $data * @param int $mode * @param int $start * @param int $local_start * @param callable|null $progressCallback * @throws \UnexpectedValueException on receipt of unexpected packets * @throws \BadFunctionCallException if you're uploading via a callback and the callback function is invalid * @throws FileNotFoundException if you're uploading via a file and the file doesn't exist * @return bool */ public function put($remote_file, $data, $mode = self::SOURCE_STRING, $start = -1, $local_start = -1, $progressCallback = null) { if (!$this->precheck()) { return false; } $remote_file = $this->realpath($remote_file); if ($remote_file === false) { return false; } $this->remove_from_stat_cache($remote_file); if ($this->version >= 5) { $flags = NET_SFTP_OPEN_OPEN_OR_CREATE; } else { $flags = NET_SFTP_OPEN_WRITE | NET_SFTP_OPEN_CREATE; // according to the SFTP specs, NET_SFTP_OPEN_APPEND should "force all writes to append data at the end of the file." // in practice, it doesn't seem to do that. //$flags|= ($mode & self::RESUME) ? NET_SFTP_OPEN_APPEND : NET_SFTP_OPEN_TRUNCATE; } if ($start >= 0) { $offset = $start; } elseif ($mode & (self::RESUME | self::RESUME_START)) { // if NET_SFTP_OPEN_APPEND worked as it should _size() wouldn't need to be called $stat = $this->stat($remote_file); $offset = $stat !== false && $stat['size'] ? $stat['size'] : 0; } else { $offset = 0; if ($this->version >= 5) { $flags = NET_SFTP_OPEN_CREATE_TRUNCATE; } else { $flags |= NET_SFTP_OPEN_TRUNCATE; } } $this->remove_from_stat_cache($remote_file); $packet = Strings::packSSH2('s', $remote_file); $packet .= $this->version >= 5 ? pack('N3', 0, $flags, 0) : pack('N2', $flags, 0); $this->send_sftp_packet(NET_SFTP_OPEN, $packet); $response = $this->get_sftp_packet(); switch ($this->packet_type) { case NET_SFTP_HANDLE: $handle = substr($response, 4); break; case NET_SFTP_STATUS: $this->logError($response); return false; default: throw new \UnexpectedValueException('Expected NET_SFTP_HANDLE or NET_SFTP_STATUS. ' . 'Got packet type: ' . $this->packet_type); } // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.2.3 $dataCallback = false; switch (true) { case $mode & self::SOURCE_CALLBACK: if (!is_callable($data)) { throw new \BadFunctionCallException("\$data should be is_callable() if you specify SOURCE_CALLBACK flag"); } $dataCallback = $data; // do nothing break; case is_resource($data): $mode = $mode & ~self::SOURCE_LOCAL_FILE; $info = stream_get_meta_data($data); if (isset($info['wrapper_type']) && $info['wrapper_type'] == 'PHP' && $info['stream_type'] == 'Input') { $fp = fopen('php://memory', 'w+'); stream_copy_to_stream($data, $fp); rewind($fp); } else { $fp = $data; } break; case $mode & self::SOURCE_LOCAL_FILE: if (!is_file($data)) { throw new FileNotFoundException("$data is not a valid file"); } $fp = @fopen($data, 'rb'); if (!$fp) { return false; } } if (isset($fp)) { $stat = fstat($fp); $size = !empty($stat) ? $stat['size'] : 0; if ($local_start >= 0) { fseek($fp, $local_start); $size -= $local_start; } elseif ($mode & self::RESUME) { fseek($fp, $offset); $size -= $offset; } } elseif ($dataCallback) { $size = 0; } else { $size = strlen($data); } $sent = 0; $size = $size < 0 ? ($size & 0x7FFFFFFF) + 0x80000000 : $size; $sftp_packet_size = $this->max_sftp_packet; // make the SFTP packet be exactly the SFTP packet size by including the bytes in the NET_SFTP_WRITE packets "header" $sftp_packet_size -= strlen($handle) + 25; $i = $j = 0; while ($dataCallback || ($size === 0 || $sent < $size)) { if ($dataCallback) { $temp = $dataCallback($sftp_packet_size); if (is_null($temp)) { break; } } else { $temp = isset($fp) ? fread($fp, $sftp_packet_size) : substr($data, $sent, $sftp_packet_size); if ($temp === false || $temp === '') { break; } } $subtemp = $offset + $sent; $packet = pack('Na*N3a*', strlen($handle), $handle, $subtemp / 4294967296, $subtemp, strlen($temp), $temp); try { $this->send_sftp_packet(NET_SFTP_WRITE, $packet, $j); } catch (\Exception $e) { if ($mode & self::SOURCE_LOCAL_FILE) { fclose($fp); } throw $e; } $sent += strlen($temp); if (is_callable($progressCallback)) { $progressCallback($sent); } $i++; $j++; if ($i == NET_SFTP_UPLOAD_QUEUE_SIZE) { if (!$this->read_put_responses($i)) { $i = 0; break; } $i = 0; } } $result = $this->close_handle($handle); if (!$this->read_put_responses($i)) { if ($mode & self::SOURCE_LOCAL_FILE) { fclose($fp); } $this->close_handle($handle); return false; } if ($mode & SFTP::SOURCE_LOCAL_FILE) { if (isset($fp) && is_resource($fp)) { fclose($fp); } if ($this->preserveTime) { $stat = stat($data); $attr = $this->version < 4 ? pack('N3', NET_SFTP_ATTR_ACCESSTIME, $stat['atime'], $stat['mtime']) : Strings::packSSH2('NQ2', NET_SFTP_ATTR_ACCESSTIME | NET_SFTP_ATTR_MODIFYTIME, $stat['atime'], $stat['mtime']); if (!$this->setstat($remote_file, $attr, false)) { throw new \RuntimeException('Error setting file time'); } } } return $result; } /** * Reads multiple successive SSH_FXP_WRITE responses * * Sending an SSH_FXP_WRITE packet and immediately reading its response isn't as efficient as blindly sending out $i * SSH_FXP_WRITEs, in succession, and then reading $i responses. * * @param int $i * @return bool * @throws \UnexpectedValueException on receipt of unexpected packets */ private function read_put_responses($i) { while ($i--) { $response = $this->get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' . 'Got packet type: ' . $this->packet_type); } list($status) = Strings::unpackSSH2('N', $response); if ($status != NET_SFTP_STATUS_OK) { $this->logError($response, $status); break; } } return $i < 0; } /** * Close handle * * @param string $handle * @return bool * @throws \UnexpectedValueException on receipt of unexpected packets */ private function close_handle($handle) { $this->send_sftp_packet(NET_SFTP_CLOSE, pack('Na*', strlen($handle), $handle)); // "The client MUST release all resources associated with the handle regardless of the status." // -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.1.3 $response = $this->get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' . 'Got packet type: ' . $this->packet_type); } list($status) = Strings::unpackSSH2('N', $response); if ($status != NET_SFTP_STATUS_OK) { $this->logError($response, $status); return false; } return true; } /** * Downloads a file from the SFTP server. * * Returns a string containing the contents of $remote_file if $local_file is left undefined or a boolean false if * the operation was unsuccessful. If $local_file is defined, returns true or false depending on the success of the * operation. * * $offset and $length can be used to download files in chunks. * * @param string $remote_file * @param string|bool|resource|callable $local_file * @param int $offset * @param int $length * @param callable|null $progressCallback * @throws \UnexpectedValueException on receipt of unexpected packets * @return string|bool */ public function get($remote_file, $local_file = false, $offset = 0, $length = -1, $progressCallback = null) { if (!$this->precheck()) { return false; } $remote_file = $this->realpath($remote_file); if ($remote_file === false) { return false; } $packet = Strings::packSSH2('s', $remote_file); $packet .= $this->version >= 5 ? pack('N3', 0, NET_SFTP_OPEN_OPEN_EXISTING, 0) : pack('N2', NET_SFTP_OPEN_READ, 0); $this->send_sftp_packet(NET_SFTP_OPEN, $packet); $response = $this->get_sftp_packet(); switch ($this->packet_type) { case NET_SFTP_HANDLE: $handle = substr($response, 4); break; case NET_SFTP_STATUS: // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED $this->logError($response); return false; default: throw new \UnexpectedValueException('Expected NET_SFTP_HANDLE or NET_SFTP_STATUS. ' . 'Got packet type: ' . $this->packet_type); } if (is_resource($local_file)) { $fp = $local_file; $stat = fstat($fp); $res_offset = $stat['size']; } else { $res_offset = 0; if ($local_file !== false && !is_callable($local_file)) { $fp = fopen($local_file, 'wb'); if (!$fp) { return false; } } else { $content = ''; } } $fclose_check = $local_file !== false && !is_callable($local_file) && !is_resource($local_file); $start = $offset; $read = 0; while (true) { $i = 0; while ($i < NET_SFTP_QUEUE_SIZE && ($length < 0 || $read < $length)) { $tempoffset = $start + $read; $packet_size = $length > 0 ? min($this->max_sftp_packet, $length - $read) : $this->max_sftp_packet; $packet = Strings::packSSH2('sN3', $handle, $tempoffset / 4294967296, $tempoffset, $packet_size); try { $this->send_sftp_packet(NET_SFTP_READ, $packet, $i); } catch (\Exception $e) { if ($fclose_check) { fclose($fp); } throw $e; } $packet = null; $read += $packet_size; $i++; } if (!$i) { break; } $packets_sent = $i - 1; $clear_responses = false; while ($i > 0) { $i--; if ($clear_responses) { $this->get_sftp_packet($packets_sent - $i); continue; } else { $response = $this->get_sftp_packet($packets_sent - $i); } switch ($this->packet_type) { case NET_SFTP_DATA: $temp = substr($response, 4); $offset += strlen($temp); if ($local_file === false) { $content .= $temp; } elseif (is_callable($local_file)) { $local_file($temp); } else { fputs($fp, $temp); } if (is_callable($progressCallback)) { call_user_func($progressCallback, $offset); } $temp = null; break; case NET_SFTP_STATUS: // could, in theory, return false if !strlen($content) but we'll hold off for the time being $this->logError($response); $clear_responses = true; // don't break out of the loop yet, so we can read the remaining responses break; default: if ($fclose_check) { fclose($fp); } if ($this->channel_close) { $this->partial_init = false; $this->init_sftp_connection(); return false; } else { throw new \UnexpectedValueException('Expected NET_SFTP_DATA or NET_SFTP_STATUS. ' . 'Got packet type: ' . $this->packet_type); } } $response = null; } if ($clear_responses) { break; } } if ($fclose_check) { fclose($fp); if ($this->preserveTime) { $stat = $this->stat($remote_file); touch($local_file, $stat['mtime'], $stat['atime']); } } if (!$this->close_handle($handle)) { return false; } // if $content isn't set that means a file was written to return isset($content) ? $content : true; } /** * Deletes a file on the SFTP server. * * @param string $path * @param bool $recursive * @return bool * @throws \UnexpectedValueException on receipt of unexpected packets */ public function delete($path, $recursive = true) { if (!$this->precheck()) { return false; } if (is_object($path)) { // It's an object. Cast it as string before we check anything else. $path = (string) $path; } if (!is_string($path) || $path == '') { return false; } $path = $this->realpath($path); if ($path === false) { return false; } // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.3 $this->send_sftp_packet(NET_SFTP_REMOVE, pack('Na*', strlen($path), $path)); $response = $this->get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' . 'Got packet type: ' . $this->packet_type); } // if $status isn't SSH_FX_OK it's probably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED list($status) = Strings::unpackSSH2('N', $response); if ($status != NET_SFTP_STATUS_OK) { $this->logError($response, $status); if (!$recursive) { return false; } $i = 0; $result = $this->delete_recursive($path, $i); $this->read_put_responses($i); return $result; } $this->remove_from_stat_cache($path); return true; } /** * Recursively deletes directories on the SFTP server * * Minimizes directory lookups and SSH_FXP_STATUS requests for speed. * * @param string $path * @param int $i * @return bool */ private function delete_recursive($path, &$i) { if (!$this->read_put_responses($i)) { return false; } $i = 0; $entries = $this->readlist($path, true); // The folder does not exist at all, so we cannot delete it. if ($entries === NET_SFTP_STATUS_NO_SUCH_FILE) { return false; } // Normally $entries would have at least . and .. but it might not if the directories // permissions didn't allow reading. If this happens then default to an empty list of files. if ($entries === false || is_int($entries)) { $entries = []; } unset($entries['.'], $entries['..']); foreach ($entries as $filename => $props) { if (!isset($props['type'])) { return false; } $temp = $path . '/' . $filename; if ($props['type'] == NET_SFTP_TYPE_DIRECTORY) { if (!$this->delete_recursive($temp, $i)) { return false; } } else { $this->send_sftp_packet(NET_SFTP_REMOVE, Strings::packSSH2('s', $temp)); $this->remove_from_stat_cache($temp); $i++; if ($i >= NET_SFTP_QUEUE_SIZE) { if (!$this->read_put_responses($i)) { return false; } $i = 0; } } } $this->send_sftp_packet(NET_SFTP_RMDIR, Strings::packSSH2('s', $path)); $this->remove_from_stat_cache($path); $i++; if ($i >= NET_SFTP_QUEUE_SIZE) { if (!$this->read_put_responses($i)) { return false; } $i = 0; } return true; } /** * Checks whether a file or directory exists * * @param string $path * @return bool */ public function file_exists($path) { if ($this->use_stat_cache) { if (!$this->precheck()) { return false; } $path = $this->realpath($path); $result = $this->query_stat_cache($path); if (isset($result)) { // return true if $result is an array or if it's an stdClass object return $result !== false; } } return $this->stat($path) !== false; } /** * Tells whether the filename is a directory * * @param string $path * @return bool */ public function is_dir($path) { $result = $this->get_stat_cache_prop($path, 'type'); if ($result === false) { return false; } return $result === NET_SFTP_TYPE_DIRECTORY; } /** * Tells whether the filename is a regular file * * @param string $path * @return bool */ public function is_file($path) { $result = $this->get_stat_cache_prop($path, 'type'); if ($result === false) { return false; } return $result === NET_SFTP_TYPE_REGULAR; } /** * Tells whether the filename is a symbolic link * * @param string $path * @return bool */ public function is_link($path) { $result = $this->get_lstat_cache_prop($path, 'type'); if ($result === false) { return false; } return $result === NET_SFTP_TYPE_SYMLINK; } /** * Tells whether a file exists and is readable * * @param string $path * @return bool */ public function is_readable($path) { if (!$this->precheck()) { return false; } $packet = Strings::packSSH2('sNN', $this->realpath($path), NET_SFTP_OPEN_READ, 0); $this->send_sftp_packet(NET_SFTP_OPEN, $packet); $response = $this->get_sftp_packet(); switch ($this->packet_type) { case NET_SFTP_HANDLE: return true; case NET_SFTP_STATUS: // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED return false; default: throw new \UnexpectedValueException('Expected NET_SFTP_HANDLE or NET_SFTP_STATUS. ' . 'Got packet type: ' . $this->packet_type); } } /** * Tells whether the filename is writable * * @param string $path * @return bool */ public function is_writable($path) { if (!$this->precheck()) { return false; } $packet = Strings::packSSH2('sNN', $this->realpath($path), NET_SFTP_OPEN_WRITE, 0); $this->send_sftp_packet(NET_SFTP_OPEN, $packet); $response = $this->get_sftp_packet(); switch ($this->packet_type) { case NET_SFTP_HANDLE: return true; case NET_SFTP_STATUS: // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED return false; default: throw new \UnexpectedValueException('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS. ' . 'Got packet type: ' . $this->packet_type); } } /** * Tells whether the filename is writeable * * Alias of is_writable * * @param string $path * @return bool */ public function is_writeable($path) { return $this->is_writable($path); } /** * Gets last access time of file * * @param string $path * @return mixed */ public function fileatime($path) { return $this->get_stat_cache_prop($path, 'atime'); } /** * Gets file modification time * * @param string $path * @return mixed */ public function filemtime($path) { return $this->get_stat_cache_prop($path, 'mtime'); } /** * Gets file permissions * * @param string $path * @return mixed */ public function fileperms($path) { return $this->get_stat_cache_prop($path, 'mode'); } /** * Gets file owner * * @param string $path * @return mixed */ public function fileowner($path) { return $this->get_stat_cache_prop($path, 'uid'); } /** * Gets file group * * @param string $path * @return mixed */ public function filegroup($path) { return $this->get_stat_cache_prop($path, 'gid'); } /** * Recursively go through rawlist() output to get the total filesize * * @return int */ private static function recursiveFilesize(array $files) { $size = 0; foreach ($files as $name => $file) { if ($name == '.' || $name == '..') { continue; } $size += is_array($file) ? self::recursiveFilesize($file) : $file->size; } return $size; } /** * Gets file size * * @param string $path * @param bool $recursive * @return mixed */ public function filesize($path, $recursive = false) { return !$recursive || $this->filetype($path) != 'dir' ? $this->get_stat_cache_prop($path, 'size') : self::recursiveFilesize($this->rawlist($path, true)); } /** * Gets file type * * @param string $path * @return string|false */ public function filetype($path) { $type = $this->get_stat_cache_prop($path, 'type'); if ($type === false) { return false; } switch ($type) { case NET_SFTP_TYPE_BLOCK_DEVICE: return 'block'; case NET_SFTP_TYPE_CHAR_DEVICE: return 'char'; case NET_SFTP_TYPE_DIRECTORY: return 'dir'; case NET_SFTP_TYPE_FIFO: return 'fifo'; case NET_SFTP_TYPE_REGULAR: return 'file'; case NET_SFTP_TYPE_SYMLINK: return 'link'; default: return false; } } /** * Return a stat properity * * Uses cache if appropriate. * * @param string $path * @param string $prop * @return mixed */ private function get_stat_cache_prop($path, $prop) { return $this->get_xstat_cache_prop($path, $prop, 'stat'); } /** * Return an lstat properity * * Uses cache if appropriate. * * @param string $path * @param string $prop * @return mixed */ private function get_lstat_cache_prop($path, $prop) { return $this->get_xstat_cache_prop($path, $prop, 'lstat'); } /** * Return a stat or lstat properity * * Uses cache if appropriate. * * @param string $path * @param string $prop * @param string $type * @return mixed */ private function get_xstat_cache_prop($path, $prop, $type) { if (!$this->precheck()) { return false; } if ($this->use_stat_cache) { $path = $this->realpath($path); $result = $this->query_stat_cache($path); if (is_object($result) && isset($result->$type)) { return $result->{$type}[$prop]; } } $result = $this->$type($path); if ($result === false || !isset($result[$prop])) { return false; } return $result[$prop]; } /** * Renames a file or a directory on the SFTP server. * * If the file already exists this will return false * * @param string $oldname * @param string $newname * @return bool * @throws \UnexpectedValueException on receipt of unexpected packets */ public function rename($oldname, $newname) { if (!$this->precheck()) { return false; } $oldname = $this->realpath($oldname); $newname = $this->realpath($newname); if ($oldname === false || $newname === false) { return false; } // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.3 $packet = Strings::packSSH2('ss', $oldname, $newname); if ($this->version >= 5) { /* quoting https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-05#section-6.5 , 'flags' is 0 or a combination of: SSH_FXP_RENAME_OVERWRITE 0x00000001 SSH_FXP_RENAME_ATOMIC 0x00000002 SSH_FXP_RENAME_NATIVE 0x00000004 (none of these are currently supported) */ $packet .= "\0\0\0\0"; } $this->send_sftp_packet(NET_SFTP_RENAME, $packet); $response = $this->get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' . 'Got packet type: ' . $this->packet_type); } // if $status isn't SSH_FX_OK it's probably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED list($status) = Strings::unpackSSH2('N', $response); if ($status != NET_SFTP_STATUS_OK) { $this->logError($response, $status); return false; } // don't move the stat cache entry over since this operation could very well change the // atime and mtime attributes //$this->update_stat_cache($newname, $this->query_stat_cache($oldname)); $this->remove_from_stat_cache($oldname); $this->remove_from_stat_cache($newname); return true; } /** * Parse Time * * See '7.7. Times' of draft-ietf-secsh-filexfer-13 for more info. * * @param string $key * @param int $flags * @param string $response * @return array */ private function parseTime($key, $flags, &$response) { $attr = []; list($attr[$key]) = Strings::unpackSSH2('Q', $response); if ($flags & NET_SFTP_ATTR_SUBSECOND_TIMES) { list($attr[$key . '-nseconds']) = Strings::unpackSSH2('N', $response); } return $attr; } /** * Parse Attributes * * See '7. File Attributes' of draft-ietf-secsh-filexfer-13 for more info. * * @param string $response * @return array */ protected function parseAttributes(&$response) { $attr = []; if ($this->version >= 4) { list($flags, $attr['type']) = Strings::unpackSSH2('NC', $response); } else { list($flags) = Strings::unpackSSH2('N', $response); } foreach (self::$attributes as $key => $value) { switch ($flags & $key) { case NET_SFTP_ATTR_UIDGID: if ($this->version > 3) { continue 2; } break; case NET_SFTP_ATTR_CREATETIME: case NET_SFTP_ATTR_MODIFYTIME: case NET_SFTP_ATTR_ACL: case NET_SFTP_ATTR_OWNERGROUP: case NET_SFTP_ATTR_SUBSECOND_TIMES: if ($this->version < 4) { continue 2; } break; case NET_SFTP_ATTR_BITS: if ($this->version < 5) { continue 2; } break; case NET_SFTP_ATTR_ALLOCATION_SIZE: case NET_SFTP_ATTR_TEXT_HINT: case NET_SFTP_ATTR_MIME_TYPE: case NET_SFTP_ATTR_LINK_COUNT: case NET_SFTP_ATTR_UNTRANSLATED_NAME: case NET_SFTP_ATTR_CTIME: if ($this->version < 6) { continue 2; } } switch ($flags & $key) { case NET_SFTP_ATTR_SIZE: // 0x00000001 // The size attribute is defined as an unsigned 64-bit integer. // The following will use floats on 32-bit platforms, if necessary. // As can be seen in the BigInteger class, floats are generally // IEEE 754 binary64 "double precision" on such platforms and // as such can represent integers of at least 2^50 without loss // of precision. Interpreted in filesize, 2^50 bytes = 1024 TiB. list($attr['size']) = Strings::unpackSSH2('Q', $response); break; case NET_SFTP_ATTR_UIDGID: // 0x00000002 (SFTPv3 only) list($attr['uid'], $attr['gid']) = Strings::unpackSSH2('NN', $response); break; case NET_SFTP_ATTR_PERMISSIONS: // 0x00000004 list($attr['mode']) = Strings::unpackSSH2('N', $response); $fileType = $this->parseMode($attr['mode']); if ($this->version < 4 && $fileType !== false) { $attr += ['type' => $fileType]; } break; case NET_SFTP_ATTR_ACCESSTIME: // 0x00000008 if ($this->version >= 4) { $attr += $this->parseTime('atime', $flags, $response); break; } list($attr['atime'], $attr['mtime']) = Strings::unpackSSH2('NN', $response); break; case NET_SFTP_ATTR_CREATETIME: // 0x00000010 (SFTPv4+) $attr += $this->parseTime('createtime', $flags, $response); break; case NET_SFTP_ATTR_MODIFYTIME: // 0x00000020 $attr += $this->parseTime('mtime', $flags, $response); break; case NET_SFTP_ATTR_ACL: // 0x00000040 // access control list // see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-04#section-5.7 // currently unsupported list($count) = Strings::unpackSSH2('N', $response); for ($i = 0; $i < $count; $i++) { list($type, $flag, $mask, $who) = Strings::unpackSSH2('N3s', $result); } break; case NET_SFTP_ATTR_OWNERGROUP: // 0x00000080 list($attr['owner'], $attr['$group']) = Strings::unpackSSH2('ss', $response); break; case NET_SFTP_ATTR_SUBSECOND_TIMES: // 0x00000100 break; case NET_SFTP_ATTR_BITS: // 0x00000200 (SFTPv5+) // see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-05#section-5.8 // currently unsupported // tells if you file is: // readonly, system, hidden, case inensitive, archive, encrypted, compressed, sparse // append only, immutable, sync list($attrib_bits, $attrib_bits_valid) = Strings::unpackSSH2('N2', $response); // if we were actually gonna implement the above it ought to be // $attr['attrib-bits'] and $attr['attrib-bits-valid'] // eg. - instead of _ break; case NET_SFTP_ATTR_ALLOCATION_SIZE: // 0x00000400 (SFTPv6+) // see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.4 // represents the number of bytes that the file consumes on the disk. will // usually be larger than the 'size' field list($attr['allocation-size']) = Strings::unpackSSH2('Q', $response); break; case NET_SFTP_ATTR_TEXT_HINT: // 0x00000800 // https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.10 // currently unsupported // tells if file is "known text", "guessed text", "known binary", "guessed binary" list($text_hint) = Strings::unpackSSH2('C', $response); // the above should be $attr['text-hint'] break; case NET_SFTP_ATTR_MIME_TYPE: // 0x00001000 // see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.11 list($attr['mime-type']) = Strings::unpackSSH2('s', $response); break; case NET_SFTP_ATTR_LINK_COUNT: // 0x00002000 // see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.12 list($attr['link-count']) = Strings::unpackSSH2('N', $response); break; case NET_SFTP_ATTR_UNTRANSLATED_NAME:// 0x00004000 // see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.13 list($attr['untranslated-name']) = Strings::unpackSSH2('s', $response); break; case NET_SFTP_ATTR_CTIME: // 0x00008000 // 'ctime' contains the last time the file attributes were changed. The // exact meaning of this field depends on the server. $attr += $this->parseTime('ctime', $flags, $response); break; case NET_SFTP_ATTR_EXTENDED: // 0x80000000 list($count) = Strings::unpackSSH2('N', $response); for ($i = 0; $i < $count; $i++) { list($key, $value) = Strings::unpackSSH2('ss', $response); $attr[$key] = $value; } } } return $attr; } /** * Attempt to identify the file type * * Quoting the SFTP RFC, "Implementations MUST NOT send bits that are not defined" but they seem to anyway * * @param int $mode * @return int */ private function parseMode($mode) { // values come from http://lxr.free-electrons.com/source/include/uapi/linux/stat.h#L12 // see, also, http://linux.die.net/man/2/stat switch ($mode & 0170000) {// ie. 1111 0000 0000 0000 case 0000000: // no file type specified - figure out the file type using alternative means return false; case 0040000: return NET_SFTP_TYPE_DIRECTORY; case 0100000: return NET_SFTP_TYPE_REGULAR; case 0120000: return NET_SFTP_TYPE_SYMLINK; // new types introduced in SFTPv5+ // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-05#section-5.2 case 0010000: // named pipe (fifo) return NET_SFTP_TYPE_FIFO; case 0020000: // character special return NET_SFTP_TYPE_CHAR_DEVICE; case 0060000: // block special return NET_SFTP_TYPE_BLOCK_DEVICE; case 0140000: // socket return NET_SFTP_TYPE_SOCKET; case 0160000: // whiteout // "SPECIAL should be used for files that are of // a known type which cannot be expressed in the protocol" return NET_SFTP_TYPE_SPECIAL; default: return NET_SFTP_TYPE_UNKNOWN; } } /** * Parse Longname * * SFTPv3 doesn't provide any easy way of identifying a file type. You could try to open * a file as a directory and see if an error is returned or you could try to parse the * SFTPv3-specific longname field of the SSH_FXP_NAME packet. That's what this function does. * The result is returned using the * {@link http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-5.2 SFTPv4 type constants}. * * If the longname is in an unrecognized format bool(false) is returned. * * @param string $longname * @return mixed */ private function parseLongname($longname) { // http://en.wikipedia.org/wiki/Unix_file_types // http://en.wikipedia.org/wiki/Filesystem_permissions#Notation_of_traditional_Unix_permissions if (preg_match('#^[^/]([r-][w-][xstST-]){3}#', $longname)) { switch ($longname[0]) { case '-': return NET_SFTP_TYPE_REGULAR; case 'd': return NET_SFTP_TYPE_DIRECTORY; case 'l': return NET_SFTP_TYPE_SYMLINK; default: return NET_SFTP_TYPE_SPECIAL; } } return false; } /** * Sends SFTP Packets * * See '6. General Packet Format' of draft-ietf-secsh-filexfer-13 for more info. * * @param int $type * @param string $data * @param int $request_id * @see self::_get_sftp_packet() * @see self::send_channel_packet() * @return void */ private function send_sftp_packet($type, $data, $request_id = 1) { // in SSH2.php the timeout is cumulative per function call. eg. exec() will // timeout after 10s. but for SFTP.php it's cumulative per packet $this->curTimeout = $this->timeout; $this->is_timeout = false; $packet = $this->use_request_id ? pack('NCNa*', strlen($data) + 5, $type, $request_id, $data) : pack('NCa*', strlen($data) + 1, $type, $data); $start = microtime(true); $this->send_channel_packet(self::CHANNEL, $packet); $stop = microtime(true); if (defined('NET_SFTP_LOGGING')) { $packet_type = '-> ' . self::$packet_types[$type] . ' (' . round($stop - $start, 4) . 's)'; $this->append_log($packet_type, $data); } } /** * Resets the SFTP channel for re-use */ private function reset_sftp() { $this->use_request_id = false; $this->pwd = false; $this->requestBuffer = []; $this->partial_init = false; } /** * Resets a connection for re-use */ protected function reset_connection() { parent::reset_connection(); $this->reset_sftp(); } /** * Receives SFTP Packets * * See '6. General Packet Format' of draft-ietf-secsh-filexfer-13 for more info. * * Incidentally, the number of SSH_MSG_CHANNEL_DATA messages has no bearing on the number of SFTP packets present. * There can be one SSH_MSG_CHANNEL_DATA messages containing two SFTP packets or there can be two SSH_MSG_CHANNEL_DATA * messages containing one SFTP packet. * * @see self::_send_sftp_packet() * @return string */ private function get_sftp_packet($request_id = null) { $this->channel_close = false; if (isset($request_id) && isset($this->requestBuffer[$request_id])) { $this->packet_type = $this->requestBuffer[$request_id]['packet_type']; $temp = $this->requestBuffer[$request_id]['packet']; unset($this->requestBuffer[$request_id]); return $temp; } // in SSH2.php the timeout is cumulative per function call. eg. exec() will // timeout after 10s. but for SFTP.php it's cumulative per packet $this->curTimeout = $this->timeout; $this->is_timeout = false; $start = microtime(true); // SFTP packet length while (strlen($this->packet_buffer) < 4) { $temp = $this->get_channel_packet(self::CHANNEL, true); if ($temp === true) { if ($this->channel_status[self::CHANNEL] === NET_SSH2_MSG_CHANNEL_CLOSE) { $this->channel_close = true; } $this->packet_type = false; $this->packet_buffer = ''; return false; } $this->packet_buffer .= $temp; } if (strlen($this->packet_buffer) < 4) { throw new \RuntimeException('Packet is too small'); } $length = unpack('Nlength', Strings::shift($this->packet_buffer, 4))['length']; $tempLength = $length; $tempLength -= strlen($this->packet_buffer); // 256 * 1024 is what SFTP_MAX_MSG_LENGTH is set to in OpenSSH's sftp-common.h if (!$this->allow_arbitrary_length_packets && !$this->use_request_id && $tempLength > 256 * 1024) { throw new \RuntimeException('Invalid Size'); } // SFTP packet type and data payload while ($tempLength > 0) { $temp = $this->get_channel_packet(self::CHANNEL, true); if ($temp === true) { if ($this->channel_status[self::CHANNEL] === NET_SSH2_MSG_CHANNEL_CLOSE) { $this->channel_close = true; } $this->packet_type = false; $this->packet_buffer = ''; return false; } $this->packet_buffer .= $temp; $tempLength -= strlen($temp); } $stop = microtime(true); $this->packet_type = ord(Strings::shift($this->packet_buffer)); if ($this->use_request_id) { $packet_id = unpack('Npacket_id', Strings::shift($this->packet_buffer, 4))['packet_id']; // remove the request id $length -= 5; // account for the request id and the packet type } else { $length -= 1; // account for the packet type } $packet = Strings::shift($this->packet_buffer, $length); if (defined('NET_SFTP_LOGGING')) { $packet_type = '<- ' . self::$packet_types[$this->packet_type] . ' (' . round($stop - $start, 4) . 's)'; $this->append_log($packet_type, $packet); } if (isset($request_id) && $this->use_request_id && $packet_id != $request_id) { $this->requestBuffer[$packet_id] = [ 'packet_type' => $this->packet_type, 'packet' => $packet ]; return $this->get_sftp_packet($request_id); } return $packet; } /** * Logs data packets * * Makes sure that only the last 1MB worth of packets will be logged * * @param string $message_number * @param string $message */ private function append_log($message_number, $message) { $this->append_log_helper( NET_SFTP_LOGGING, $message_number, $message, $this->packet_type_log, $this->packet_log, $this->log_size, $this->realtime_log_file, $this->realtime_log_wrap, $this->realtime_log_size ); } /** * Returns a log of the packets that have been sent and received. * * Returns a string if NET_SFTP_LOGGING == self::LOG_COMPLEX, an array if NET_SFTP_LOGGING == self::LOG_SIMPLE and false if !defined('NET_SFTP_LOGGING') * * @return array|string|false */ public function getSFTPLog() { if (!defined('NET_SFTP_LOGGING')) { return false; } switch (NET_SFTP_LOGGING) { case self::LOG_COMPLEX: return $this->format_log($this->packet_log, $this->packet_type_log); break; //case self::LOG_SIMPLE: default: return $this->packet_type_log; } } /** * Returns all errors on the SFTP layer * * @return array */ public function getSFTPErrors() { return $this->sftp_errors; } /** * Returns the last error on the SFTP layer * * @return string */ public function getLastSFTPError() { return count($this->sftp_errors) ? $this->sftp_errors[count($this->sftp_errors) - 1] : ''; } /** * Get supported SFTP versions * * @return array */ public function getSupportedVersions() { if (!($this->bitmap & SSH2::MASK_LOGIN)) { return false; } if (!$this->partial_init) { $this->partial_init_sftp_connection(); } $temp = ['version' => $this->defaultVersion]; if (isset($this->extensions['versions'])) { $temp['extensions'] = $this->extensions['versions']; } return $temp; } /** * Get supported SFTP extensions * * @return array */ public function getSupportedExtensions() { if (!($this->bitmap & SSH2::MASK_LOGIN)) { return false; } if (!$this->partial_init) { $this->partial_init_sftp_connection(); } return $this->extensions; } /** * Get supported SFTP versions * * @return int|false */ public function getNegotiatedVersion() { if (!$this->precheck()) { return false; } return $this->version; } /** * Set preferred version * * If you're preferred version isn't supported then the highest supported * version of SFTP will be utilized. Set to null or false or int(0) to * unset the preferred version * * @param int $version */ public function setPreferredVersion($version) { $this->preferredVersion = $version; } /** * Disconnect * * @param int $reason * @return false */ protected function disconnect_helper($reason) { $this->pwd = false; return parent::disconnect_helper($reason); } /** * Enable Date Preservation */ public function enableDatePreservation() { $this->preserveTime = true; } /** * Disable Date Preservation */ public function disableDatePreservation() { $this->preserveTime = false; } /** * Copy * * This method (currently) only works if the copy-data extension is available * * @param string $oldname * @param string $newname * @return bool */ public function copy($oldname, $newname) { if (!$this->precheck()) { return false; } $oldname = $this->realpath($oldname); $newname = $this->realpath($newname); if ($oldname === false || $newname === false) { return false; } if (!isset($this->extensions['copy-data']) || $this->extensions['copy-data'] !== '1') { throw new \RuntimeException( "Extension 'copy-data' is not supported by the server. " . "Call getSupportedVersions() to see a list of supported extension" ); } $size = $this->filesize($oldname); $packet = Strings::packSSH2('s', $oldname); $packet .= $this->version >= 5 ? pack('N3', 0, NET_SFTP_OPEN_OPEN_EXISTING, 0) : pack('N2', NET_SFTP_OPEN_READ, 0); $this->send_sftp_packet(NET_SFTP_OPEN, $packet); $response = $this->get_sftp_packet(); switch ($this->packet_type) { case NET_SFTP_HANDLE: $oldhandle = substr($response, 4); break; case NET_SFTP_STATUS: // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED $this->logError($response); return false; default: throw new \UnexpectedValueException('Expected NET_SFTP_HANDLE or NET_SFTP_STATUS. ' . 'Got packet type: ' . $this->packet_type); } if ($this->version >= 5) { $flags = NET_SFTP_OPEN_OPEN_OR_CREATE; } else { $flags = NET_SFTP_OPEN_WRITE | NET_SFTP_OPEN_CREATE; } $packet = Strings::packSSH2('s', $newname); $packet .= $this->version >= 5 ? pack('N3', 0, $flags, 0) : pack('N2', $flags, 0); $this->send_sftp_packet(NET_SFTP_OPEN, $packet); $response = $this->get_sftp_packet(); switch ($this->packet_type) { case NET_SFTP_HANDLE: $newhandle = substr($response, 4); break; case NET_SFTP_STATUS: $this->logError($response); return false; default: throw new \UnexpectedValueException('Expected NET_SFTP_HANDLE or NET_SFTP_STATUS. ' . 'Got packet type: ' . $this->packet_type); } $packet = Strings::packSSH2('ssQQsQ', 'copy-data', $oldhandle, 0, $size, $newhandle, 0); $this->send_sftp_packet(NET_SFTP_EXTENDED, $packet); $response = $this->get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' . 'Got packet type: ' . $this->packet_type); } $this->close_handle($oldhandle); $this->close_handle($newhandle); return true; } /** * POSIX Rename * * Where rename() fails "if there already exists a file with the name specified by newpath" * (draft-ietf-secsh-filexfer-02#section-6.5), posix_rename() overwrites the existing file in an atomic fashion. * ie. "there is no observable instant in time where the name does not refer to either the old or the new file" * (draft-ietf-secsh-filexfer-13#page-39). * * @param string $oldname * @param string $newname * @return bool */ public function posix_rename($oldname, $newname) { if (!$this->precheck()) { return false; } $oldname = $this->realpath($oldname); $newname = $this->realpath($newname); if ($oldname === false || $newname === false) { return false; } if ($this->version >= 5) { $packet = Strings::packSSH2('ssN', $oldname, $newname, 2); // 2 = SSH_FXP_RENAME_ATOMIC $this->send_sftp_packet(NET_SFTP_RENAME, $packet); } elseif (isset($this->extensions['posix-rename@openssh.com']) && $this->extensions['posix-rename@openssh.com'] === '1') { $packet = Strings::packSSH2('sss', 'posix-rename@openssh.com', $oldname, $newname); $this->send_sftp_packet(NET_SFTP_EXTENDED, $packet); } else { throw new \RuntimeException( "Extension 'posix-rename@openssh.com' is not supported by the server. " . "Call getSupportedVersions() to see a list of supported extension" ); } $response = $this->get_sftp_packet(); if ($this->packet_type != NET_SFTP_STATUS) { throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' . 'Got packet type: ' . $this->packet_type); } // if $status isn't SSH_FX_OK it's probably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED list($status) = Strings::unpackSSH2('N', $response); if ($status != NET_SFTP_STATUS_OK) { $this->logError($response, $status); return false; } // don't move the stat cache entry over since this operation could very well change the // atime and mtime attributes //$this->update_stat_cache($newname, $this->query_stat_cache($oldname)); $this->remove_from_stat_cache($oldname); $this->remove_from_stat_cache($newname); return true; } /** * Returns general information about a file system. * * The function statvfs() returns information about a mounted filesystem. * @see https://man7.org/linux/man-pages/man3/statvfs.3.html * * @param string $path * @return false|array{bsize: int, frsize: int, blocks: int, bfree: int, bavail: int, files: int, ffree: int, favail: int, fsid: int, flag: int, namemax: int} */ public function statvfs($path) { if (!$this->precheck()) { return false; } if (!isset($this->extensions['statvfs@openssh.com']) || $this->extensions['statvfs@openssh.com'] !== '2') { throw new \RuntimeException( "Extension 'statvfs@openssh.com' is not supported by the server. " . "Call getSupportedVersions() to see a list of supported extension" ); } $realpath = $this->realpath($path); if ($realpath === false) { return false; } $packet = Strings::packSSH2('ss', 'statvfs@openssh.com', $realpath); $this->send_sftp_packet(NET_SFTP_EXTENDED, $packet); $response = $this->get_sftp_packet(); if ($this->packet_type !== NET_SFTP_EXTENDED_REPLY) { throw new \UnexpectedValueException( 'Expected SSH_FXP_EXTENDED_REPLY. ' . 'Got packet type: ' . $this->packet_type ); } /** * These requests return a SSH_FXP_STATUS reply on failure. On success they * return the following SSH_FXP_EXTENDED_REPLY reply: * * uint32 id * uint64 f_bsize file system block size * uint64 f_frsize fundamental fs block size * uint64 f_blocks number of blocks (unit f_frsize) * uint64 f_bfree free blocks in file system * uint64 f_bavail free blocks for non-root * uint64 f_files total file inodes * uint64 f_ffree free file inodes * uint64 f_favail free file inodes for to non-root * uint64 f_fsid file system id * uint64 f_flag bit mask of f_flag values * uint64 f_namemax maximum filename length */ return array_combine( ['bsize', 'frsize', 'blocks', 'bfree', 'bavail', 'files', 'ffree', 'favail', 'fsid', 'flag', 'namemax'], Strings::unpackSSH2('QQQQQQQQQQQ', $response) ); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php ================================================ * login('username', 'password')) { * exit('Login Failed'); * } * * echo $ssh->exec('pwd'); * echo $ssh->exec('ls -la'); * ?> * * * * login('username', $key)) { * exit('Login Failed'); * } * * echo $ssh->read('username@username:~$'); * $ssh->write("ls -la\n"); * echo $ssh->read('username@username:~$'); * ?> * * * @author Jim Wigginton * @copyright 2007 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\Net; use phpseclib3\Common\Functions\Strings; use phpseclib3\Crypt\Blowfish; use phpseclib3\Crypt\ChaCha20; use phpseclib3\Crypt\Common\AsymmetricKey; use phpseclib3\Crypt\Common\PrivateKey; use phpseclib3\Crypt\Common\PublicKey; use phpseclib3\Crypt\Common\SymmetricKey; use phpseclib3\Crypt\DH; use phpseclib3\Crypt\DSA; use phpseclib3\Crypt\EC; use phpseclib3\Crypt\Hash; use phpseclib3\Crypt\Random; use phpseclib3\Crypt\RC4; use phpseclib3\Crypt\Rijndael; use phpseclib3\Crypt\RSA; use phpseclib3\Crypt\TripleDES; // Used to do Diffie-Hellman key exchange and DSA/RSA signature verification. use phpseclib3\Crypt\Twofish; use phpseclib3\Exception\ConnectionClosedException; use phpseclib3\Exception\InsufficientSetupException; use phpseclib3\Exception\InvalidPacketLengthException; use phpseclib3\Exception\NoSupportedAlgorithmsException; use phpseclib3\Exception\TimeoutException; use phpseclib3\Exception\UnableToConnectException; use phpseclib3\Exception\UnsupportedAlgorithmException; use phpseclib3\Exception\UnsupportedCurveException; use phpseclib3\Math\BigInteger; use phpseclib3\System\SSH\Agent; /** * Pure-PHP implementation of SSHv2. * * @author Jim Wigginton */ class SSH2 { /**#@+ * Compression Types * */ /** * No compression */ const NET_SSH2_COMPRESSION_NONE = 1; /** * zlib compression */ const NET_SSH2_COMPRESSION_ZLIB = 2; /** * zlib@openssh.com */ const NET_SSH2_COMPRESSION_ZLIB_AT_OPENSSH = 3; /**#@-*/ // Execution Bitmap Masks const MASK_CONSTRUCTOR = 0x00000001; const MASK_CONNECTED = 0x00000002; const MASK_LOGIN_REQ = 0x00000004; const MASK_LOGIN = 0x00000008; const MASK_SHELL = 0x00000010; const MASK_DISCONNECT = 0x00000020; /* * Channel constants * * RFC4254 refers not to client and server channels but rather to sender and recipient channels. we don't refer * to them in that way because RFC4254 toggles the meaning. the client sends a SSH_MSG_CHANNEL_OPEN message with * a sender channel and the server sends a SSH_MSG_CHANNEL_OPEN_CONFIRMATION in response, with a sender and a * recipient channel. at first glance, you might conclude that SSH_MSG_CHANNEL_OPEN_CONFIRMATION's sender channel * would be the same thing as SSH_MSG_CHANNEL_OPEN's sender channel, but it's not, per this snippet: * The 'recipient channel' is the channel number given in the original * open request, and 'sender channel' is the channel number allocated by * the other side. * * @see \phpseclib3\Net\SSH2::send_channel_packet() * @see \phpseclib3\Net\SSH2::get_channel_packet() */ const CHANNEL_EXEC = 1; // PuTTy uses 0x100 const CHANNEL_SHELL = 2; const CHANNEL_SUBSYSTEM = 3; const CHANNEL_AGENT_FORWARD = 4; const CHANNEL_KEEP_ALIVE = 5; /** * Returns the message numbers * * @see \phpseclib3\Net\SSH2::getLog() */ const LOG_SIMPLE = 1; /** * Returns the message content * * @see \phpseclib3\Net\SSH2::getLog() */ const LOG_COMPLEX = 2; /** * Outputs the content real-time */ const LOG_REALTIME = 3; /** * Dumps the content real-time to a file */ const LOG_REALTIME_FILE = 4; /** * Outputs the message numbers real-time */ const LOG_SIMPLE_REALTIME = 5; /* * Dumps the message numbers real-time */ const LOG_REALTIME_SIMPLE = 5; /** * Make sure that the log never gets larger than this * * @see \phpseclib3\Net\SSH2::getLog() */ const LOG_MAX_SIZE = 1048576; // 1024 * 1024 /** * Returns when a string matching $expect exactly is found * * @see \phpseclib3\Net\SSH2::read() */ const READ_SIMPLE = 1; /** * Returns when a string matching the regular expression $expect is found * * @see \phpseclib3\Net\SSH2::read() */ const READ_REGEX = 2; /** * Returns whenever a data packet is received. * * Some data packets may only contain a single character so it may be necessary * to call read() multiple times when using this option * * @see \phpseclib3\Net\SSH2::read() */ const READ_NEXT = 3; /** * The SSH identifier * * @var string */ private $identifier; /** * The Socket Object * * @var resource|closed-resource|null */ public $fsock; /** * Execution Bitmap * * The bits that are set represent functions that have been called already. This is used to determine * if a requisite function has been successfully executed. If not, an error should be thrown. * * @var int */ protected $bitmap = 0; /** * Error information * * @see self::getErrors() * @see self::getLastError() * @var array */ private $errors = []; /** * Server Identifier * * @see self::getServerIdentification() * @var string|false */ protected $server_identifier = false; /** * Key Exchange Algorithms * * @see self::getKexAlgorithims() * @var array|false */ private $kex_algorithms = false; /** * Key Exchange Algorithm * * @see self::getMethodsNegotiated() * @var string|false */ private $kex_algorithm = false; /** * Minimum Diffie-Hellman Group Bit Size in RFC 4419 Key Exchange Methods * * @see self::_key_exchange() * @var int */ private $kex_dh_group_size_min = 1536; /** * Preferred Diffie-Hellman Group Bit Size in RFC 4419 Key Exchange Methods * * @see self::_key_exchange() * @var int */ private $kex_dh_group_size_preferred = 2048; /** * Maximum Diffie-Hellman Group Bit Size in RFC 4419 Key Exchange Methods * * @see self::_key_exchange() * @var int */ private $kex_dh_group_size_max = 4096; /** * Server Host Key Algorithms * * @see self::getServerHostKeyAlgorithms() * @var array|false */ private $server_host_key_algorithms = false; /** * Supported Private Key Algorithms * * In theory this should be the same as the Server Host Key Algorithms but, in practice, * some servers (eg. Azure) will support rsa-sha2-512 as a server host key algorithm but * not a private key algorithm * * @see self::privatekey_login() * @var array|false */ private $supported_private_key_algorithms = false; /** * Encryption Algorithms: Client to Server * * @see self::getEncryptionAlgorithmsClient2Server() * @var array|false */ private $encryption_algorithms_client_to_server = false; /** * Encryption Algorithms: Server to Client * * @see self::getEncryptionAlgorithmsServer2Client() * @var array|false */ private $encryption_algorithms_server_to_client = false; /** * MAC Algorithms: Client to Server * * @see self::getMACAlgorithmsClient2Server() * @var array|false */ private $mac_algorithms_client_to_server = false; /** * MAC Algorithms: Server to Client * * @see self::getMACAlgorithmsServer2Client() * @var array|false */ private $mac_algorithms_server_to_client = false; /** * Compression Algorithms: Client to Server * * @see self::getCompressionAlgorithmsClient2Server() * @var array|false */ private $compression_algorithms_client_to_server = false; /** * Compression Algorithms: Server to Client * * @see self::getCompressionAlgorithmsServer2Client() * @var array|false */ private $compression_algorithms_server_to_client = false; /** * Languages: Server to Client * * @see self::getLanguagesServer2Client() * @var array|false */ private $languages_server_to_client = false; /** * Languages: Client to Server * * @see self::getLanguagesClient2Server() * @var array|false */ private $languages_client_to_server = false; /** * Preferred Algorithms * * @see self::setPreferredAlgorithms() * @var array */ private $preferred = []; /** * Block Size for Server to Client Encryption * * "Note that the length of the concatenation of 'packet_length', * 'padding_length', 'payload', and 'random padding' MUST be a multiple * of the cipher block size or 8, whichever is larger. This constraint * MUST be enforced, even when using stream ciphers." * * -- http://tools.ietf.org/html/rfc4253#section-6 * * @see self::__construct() * @see self::_send_binary_packet() * @var int */ private $encrypt_block_size = 8; /** * Block Size for Client to Server Encryption * * @see self::__construct() * @see self::_get_binary_packet() * @var int */ private $decrypt_block_size = 8; /** * Server to Client Encryption Object * * @see self::_get_binary_packet() * @var SymmetricKey|false */ private $decrypt = false; /** * Decryption Algorithm Name * * @var string|null */ private $decryptName; /** * Decryption Invocation Counter * * Used by GCM * * @var string|null */ private $decryptInvocationCounter; /** * Fixed Part of Nonce * * Used by GCM * * @var string|null */ private $decryptFixedPart; /** * Server to Client Length Encryption Object * * @see self::_get_binary_packet() * @var object */ private $lengthDecrypt = false; /** * Client to Server Encryption Object * * @see self::_send_binary_packet() * @var SymmetricKey|false */ private $encrypt = false; /** * Encryption Algorithm Name * * @var string|null */ private $encryptName; /** * Encryption Invocation Counter * * Used by GCM * * @var string|null */ private $encryptInvocationCounter; /** * Fixed Part of Nonce * * Used by GCM * * @var string|null */ private $encryptFixedPart; /** * Client to Server Length Encryption Object * * @see self::_send_binary_packet() * @var object */ private $lengthEncrypt = false; /** * Client to Server HMAC Object * * @see self::_send_binary_packet() * @var object */ private $hmac_create = false; /** * Client to Server HMAC Name * * @var string|false */ private $hmac_create_name; /** * Client to Server ETM * * @var int|false */ private $hmac_create_etm; /** * Server to Client HMAC Object * * @see self::_get_binary_packet() * @var object */ private $hmac_check = false; /** * Server to Client HMAC Name * * @var string|false */ private $hmac_check_name; /** * Server to Client ETM * * @var int|false */ private $hmac_check_etm; /** * Size of server to client HMAC * * We need to know how big the HMAC will be for the server to client direction so that we know how many bytes to read. * For the client to server side, the HMAC object will make the HMAC as long as it needs to be. All we need to do is * append it. * * @see self::_get_binary_packet() * @var int */ private $hmac_size = false; /** * Server Public Host Key * * @see self::getServerPublicHostKey() * @var string */ private $server_public_host_key; /** * Session identifier * * "The exchange hash H from the first key exchange is additionally * used as the session identifier, which is a unique identifier for * this connection." * * -- http://tools.ietf.org/html/rfc4253#section-7.2 * * @see self::_key_exchange() * @var string */ private $session_id = false; /** * Exchange hash * * The current exchange hash * * @see self::_key_exchange() * @var string */ private $exchange_hash = false; /** * Message Numbers * * @see self::__construct() * @var array * @access private */ private static $message_numbers = []; /** * Disconnection Message 'reason codes' defined in RFC4253 * * @see self::__construct() * @var array * @access private */ private static $disconnect_reasons = []; /** * SSH_MSG_CHANNEL_OPEN_FAILURE 'reason codes', defined in RFC4254 * * @see self::__construct() * @var array * @access private */ private static $channel_open_failure_reasons = []; /** * Terminal Modes * * @link http://tools.ietf.org/html/rfc4254#section-8 * @see self::__construct() * @var array * @access private */ private static $terminal_modes = []; /** * SSH_MSG_CHANNEL_EXTENDED_DATA's data_type_codes * * @link http://tools.ietf.org/html/rfc4254#section-5.2 * @see self::__construct() * @var array * @access private */ private static $channel_extended_data_type_codes = []; /** * Send Sequence Number * * See 'Section 6.4. Data Integrity' of rfc4253 for more info. * * @see self::_send_binary_packet() * @var int */ private $send_seq_no = 0; /** * Get Sequence Number * * See 'Section 6.4. Data Integrity' of rfc4253 for more info. * * @see self::_get_binary_packet() * @var int */ private $get_seq_no = 0; /** * Server Channels * * Maps client channels to server channels * * @see self::get_channel_packet() * @see self::exec() * @var array */ protected $server_channels = []; /** * Channel Read Buffers * * If a client requests a packet from one channel but receives two packets from another those packets should * be placed in a buffer * * @see self::get_channel_packet() * @see self::exec() * @var array */ private $channel_buffers = []; /** * Channel Write Buffers * * If a client sends a packet and receives a timeout error mid-transmission, buffer the data written so it * can be de-duplicated upon resuming write * * @see self::send_channel_packet() * @var array */ private $channel_buffers_write = []; /** * Channel Status * * Contains the type of the last sent message * * @see self::get_channel_packet() * @var array */ protected $channel_status = []; /** * The identifier of the interactive channel which was opened most recently * * @see self::getInteractiveChannelId() * @var int */ private $channel_id_last_interactive = 0; /** * Packet Size * * Maximum packet size indexed by channel * * @see self::send_channel_packet() * @var array */ protected $packet_size_client_to_server = []; /** * Message Number Log * * @see self::getLog() * @var array */ private $message_number_log = []; /** * Message Log * * @see self::getLog() * @var array */ private $message_log = []; /** * The Window Size * * Bytes the other party can send before it must wait for the window to be adjusted (0x7FFFFFFF = 2GB) * * @var int * @see self::send_channel_packet() * @see self::exec() */ protected $window_size = 0x7FFFFFFF; /** * What we resize the window to * * When PuTTY resizes the window it doesn't add an additional 0x7FFFFFFF bytes - it adds 0x40000000 bytes. * Some SFTP clients (GoAnywhere) don't support adding 0x7FFFFFFF to the window size after the fact so * we'll just do what PuTTY does * * @var int * @see self::_send_channel_packet() * @see self::exec() */ private $window_resize = 0x40000000; /** * Window size, server to client * * Window size indexed by channel * * @see self::send_channel_packet() * @var array */ protected $window_size_server_to_client = []; /** * Window size, client to server * * Window size indexed by channel * * @see self::get_channel_packet() * @var array */ private $window_size_client_to_server = []; /** * Server signature * * Verified against $this->session_id * * @see self::getServerPublicHostKey() * @var string */ private $signature = ''; /** * Server signature format * * ssh-rsa or ssh-dss. * * @see self::getServerPublicHostKey() * @var string */ private $signature_format = ''; /** * Interactive Buffer * * @see self::read() * @var string */ private $interactiveBuffer = ''; /** * Current log size * * Should never exceed self::LOG_MAX_SIZE * * @see self::_send_binary_packet() * @see self::_get_binary_packet() * @var int */ private $log_size; /** * Timeout * * @see self::setTimeout() */ protected $timeout; /** * Current Timeout * * @see self::get_channel_packet() */ protected $curTimeout; /** * Keep Alive Interval * * @see self::setKeepAlive() */ private $keepAlive; /** * Real-time log file pointer * * @see self::_append_log() * @var resource|closed-resource */ private $realtime_log_file; /** * Real-time log file size * * @see self::_append_log() * @var int */ private $realtime_log_size; /** * Has the signature been validated? * * @see self::getServerPublicHostKey() * @var bool */ private $signature_validated = false; /** * Real-time log file wrap boolean * * @see self::_append_log() * @var bool */ private $realtime_log_wrap; /** * Flag to suppress stderr from output * * @see self::enableQuietMode() */ private $quiet_mode = false; /** * Time of last read/write network activity * * @var float */ private $last_packet = null; /** * Exit status returned from ssh if any * * @var int */ private $exit_status; /** * Flag to request a PTY when using exec() * * @var bool * @see self::enablePTY() */ private $request_pty = false; /** * Contents of stdError * * @var string */ private $stdErrorLog; /** * The Last Interactive Response * * @see self::_keyboard_interactive_process() * @var string */ private $last_interactive_response = ''; /** * Keyboard Interactive Request / Responses * * @see self::_keyboard_interactive_process() * @var array */ private $keyboard_requests_responses = []; /** * Banner Message * * Quoting from the RFC, "in some jurisdictions, sending a warning message before * authentication may be relevant for getting legal protection." * * @see self::_filter() * @see self::getBannerMessage() * @var string */ private $banner_message = ''; /** * Did read() timeout or return normally? * * @see self::isTimeout() * @var bool */ protected $is_timeout = false; /** * Log Boundary * * @see self::_format_log() * @var string */ private $log_boundary = ':'; /** * Log Long Width * * @see self::_format_log() * @var int */ private $log_long_width = 65; /** * Log Short Width * * @see self::_format_log() * @var int */ private $log_short_width = 16; /** * Hostname * * @see self::__construct() * @see self::_connect() * @var string */ private $host; /** * Port Number * * @see self::__construct() * @see self::_connect() * @var int */ private $port; /** * Number of columns for terminal window size * * @see self::getWindowColumns() * @see self::setWindowColumns() * @see self::setWindowSize() * @var int */ private $windowColumns = 80; /** * Number of columns for terminal window size * * @see self::getWindowRows() * @see self::setWindowRows() * @see self::setWindowSize() * @var int */ private $windowRows = 24; /** * Crypto Engine * * @see self::setCryptoEngine() * @see self::_key_exchange() * @var int */ private static $crypto_engine = false; /** * A System_SSH_Agent for use in the SSH2 Agent Forwarding scenario * * @var Agent */ private $agent; /** * Connection storage to replicates ssh2 extension functionality: * {@link http://php.net/manual/en/wrappers.ssh2.php#refsect1-wrappers.ssh2-examples} * * @var array> */ private static $connections; /** * Send the identification string first? * * @var bool */ private $send_id_string_first = true; /** * Send the key exchange initiation packet first? * * @var bool */ private $send_kex_first = true; /** * Some versions of OpenSSH incorrectly calculate the key size * * @var bool */ private $bad_key_size_fix = false; /** * Should we try to re-connect to re-establish keys? * * @var bool */ private $login_credentials_finalized = false; /** * Binary Packet Buffer * * @var object|null */ private $binary_packet_buffer = null; /** * Preferred Signature Format * * @var string|false */ protected $preferred_signature_format = false; /** * Authentication Credentials * * @var array */ protected $auth = []; /** * Terminal * * @var string */ private $term = 'vt100'; /** * The authentication methods that may productively continue authentication. * * @see https://tools.ietf.org/html/rfc4252#section-5.1 * @var array|null */ private $auth_methods_to_continue = null; /** * Compression method * * @var int */ private $compress = self::NET_SSH2_COMPRESSION_NONE; /** * Decompression method * * @var int */ private $decompress = self::NET_SSH2_COMPRESSION_NONE; /** * Compression context * * @var resource|false|null */ private $compress_context; /** * Decompression context * * @var resource|object */ private $decompress_context; /** * Regenerate Compression Context * * @var bool */ private $regenerate_compression_context = false; /** * Regenerate Decompression Context * * @var bool */ private $regenerate_decompression_context = false; /** * Smart multi-factor authentication flag * * @var bool */ private $smartMFA = true; /** * How many channels are currently opened * * @var int */ private $channelCount = 0; /** * Does the server support multiple channels? If not then error out * when multiple channels are attempted to be opened * * @var bool */ private $errorOnMultipleChannels; /** * Bytes Transferred Since Last Key Exchange * * Includes outbound and inbound totals * * @var int */ private $bytesTransferredSinceLastKEX = 0; /** * After how many transferred byte should phpseclib initiate a key re-exchange? * * @var int */ private $doKeyReexchangeAfterXBytes = 1024 * 1024 * 1024; /** * Has a key re-exchange been initialized? * * @var bool * @access private */ private $keyExchangeInProgress = false; /** * KEX Buffer * * If we're in the middle of a key exchange we want to buffer any additional packets we get until * the key exchange is over * * @see self::_get_binary_packet() * @see self::_key_exchange() * @see self::exec() * @var array * @access private */ private $kex_buffer = []; /** * Strict KEX Flag * * If kex-strict-s-v00@openssh.com is present in the first KEX packet it need not * be present in subsequent packet * * @see self::_key_exchange() * @see self::exec() * @var array * @access private */ private $strict_kex_flag = false; /** * Default Constructor. * * $host can either be a string, representing the host, or a stream resource. * If $host is a stream resource then $port doesn't do anything, altho $timeout * still will be used * * @param mixed $host * @param int $port * @param int $timeout * @see self::login() */ public function __construct($host, $port = 22, $timeout = 10) { if (empty(self::$message_numbers)) { self::$message_numbers = [ 1 => 'NET_SSH2_MSG_DISCONNECT', 2 => 'NET_SSH2_MSG_IGNORE', 3 => 'NET_SSH2_MSG_UNIMPLEMENTED', 4 => 'NET_SSH2_MSG_DEBUG', 5 => 'NET_SSH2_MSG_SERVICE_REQUEST', 6 => 'NET_SSH2_MSG_SERVICE_ACCEPT', 7 => 'NET_SSH2_MSG_EXT_INFO', // RFC 8308 20 => 'NET_SSH2_MSG_KEXINIT', 21 => 'NET_SSH2_MSG_NEWKEYS', 30 => 'NET_SSH2_MSG_KEXDH_INIT', 31 => 'NET_SSH2_MSG_KEXDH_REPLY', 50 => 'NET_SSH2_MSG_USERAUTH_REQUEST', 51 => 'NET_SSH2_MSG_USERAUTH_FAILURE', 52 => 'NET_SSH2_MSG_USERAUTH_SUCCESS', 53 => 'NET_SSH2_MSG_USERAUTH_BANNER', 80 => 'NET_SSH2_MSG_GLOBAL_REQUEST', 81 => 'NET_SSH2_MSG_REQUEST_SUCCESS', 82 => 'NET_SSH2_MSG_REQUEST_FAILURE', 90 => 'NET_SSH2_MSG_CHANNEL_OPEN', 91 => 'NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION', 92 => 'NET_SSH2_MSG_CHANNEL_OPEN_FAILURE', 93 => 'NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST', 94 => 'NET_SSH2_MSG_CHANNEL_DATA', 95 => 'NET_SSH2_MSG_CHANNEL_EXTENDED_DATA', 96 => 'NET_SSH2_MSG_CHANNEL_EOF', 97 => 'NET_SSH2_MSG_CHANNEL_CLOSE', 98 => 'NET_SSH2_MSG_CHANNEL_REQUEST', 99 => 'NET_SSH2_MSG_CHANNEL_SUCCESS', 100 => 'NET_SSH2_MSG_CHANNEL_FAILURE' ]; self::$disconnect_reasons = [ 1 => 'NET_SSH2_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT', 2 => 'NET_SSH2_DISCONNECT_PROTOCOL_ERROR', 3 => 'NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED', 4 => 'NET_SSH2_DISCONNECT_RESERVED', 5 => 'NET_SSH2_DISCONNECT_MAC_ERROR', 6 => 'NET_SSH2_DISCONNECT_COMPRESSION_ERROR', 7 => 'NET_SSH2_DISCONNECT_SERVICE_NOT_AVAILABLE', 8 => 'NET_SSH2_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED', 9 => 'NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE', 10 => 'NET_SSH2_DISCONNECT_CONNECTION_LOST', 11 => 'NET_SSH2_DISCONNECT_BY_APPLICATION', 12 => 'NET_SSH2_DISCONNECT_TOO_MANY_CONNECTIONS', 13 => 'NET_SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER', 14 => 'NET_SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE', 15 => 'NET_SSH2_DISCONNECT_ILLEGAL_USER_NAME' ]; self::$channel_open_failure_reasons = [ 1 => 'NET_SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED' ]; self::$terminal_modes = [ 0 => 'NET_SSH2_TTY_OP_END' ]; self::$channel_extended_data_type_codes = [ 1 => 'NET_SSH2_EXTENDED_DATA_STDERR' ]; self::define_array( self::$message_numbers, self::$disconnect_reasons, self::$channel_open_failure_reasons, self::$terminal_modes, self::$channel_extended_data_type_codes, [60 => 'NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ'], [60 => 'NET_SSH2_MSG_USERAUTH_PK_OK'], [60 => 'NET_SSH2_MSG_USERAUTH_INFO_REQUEST', 61 => 'NET_SSH2_MSG_USERAUTH_INFO_RESPONSE'], // RFC 4419 - diffie-hellman-group-exchange-sha{1,256} [30 => 'NET_SSH2_MSG_KEXDH_GEX_REQUEST_OLD', 31 => 'NET_SSH2_MSG_KEXDH_GEX_GROUP', 32 => 'NET_SSH2_MSG_KEXDH_GEX_INIT', 33 => 'NET_SSH2_MSG_KEXDH_GEX_REPLY', 34 => 'NET_SSH2_MSG_KEXDH_GEX_REQUEST'], // RFC 5656 - Elliptic Curves (for curve25519-sha256@libssh.org) [30 => 'NET_SSH2_MSG_KEX_ECDH_INIT', 31 => 'NET_SSH2_MSG_KEX_ECDH_REPLY'] ); } /** * Typehint is required due to a bug in Psalm: https://github.com/vimeo/psalm/issues/7508 * @var \WeakReference|SSH2 */ self::$connections[$this->getResourceId()] = class_exists('WeakReference') ? \WeakReference::create($this) : $this; $this->timeout = $timeout; if (is_resource($host)) { $this->fsock = $host; return; } if (Strings::is_stringable($host)) { $this->host = $host; $this->port = $port; } } /** * Set Crypto Engine Mode * * Possible $engine values: * OpenSSL, mcrypt, Eval, PHP * * @param int $engine */ public static function setCryptoEngine($engine) { self::$crypto_engine = $engine; } /** * Send Identification String First * * https://tools.ietf.org/html/rfc4253#section-4.2 says "when the connection has been established, * both sides MUST send an identification string". It does not say which side sends it first. In * theory it shouldn't matter but it is a fact of life that some SSH servers are simply buggy * */ public function sendIdentificationStringFirst() { $this->send_id_string_first = true; } /** * Send Identification String Last * * https://tools.ietf.org/html/rfc4253#section-4.2 says "when the connection has been established, * both sides MUST send an identification string". It does not say which side sends it first. In * theory it shouldn't matter but it is a fact of life that some SSH servers are simply buggy * */ public function sendIdentificationStringLast() { $this->send_id_string_first = false; } /** * Send SSH_MSG_KEXINIT First * * https://tools.ietf.org/html/rfc4253#section-7.1 says "key exchange begins by each sending * sending the [SSH_MSG_KEXINIT] packet". It does not say which side sends it first. In theory * it shouldn't matter but it is a fact of life that some SSH servers are simply buggy * */ public function sendKEXINITFirst() { $this->send_kex_first = true; } /** * Send SSH_MSG_KEXINIT Last * * https://tools.ietf.org/html/rfc4253#section-7.1 says "key exchange begins by each sending * sending the [SSH_MSG_KEXINIT] packet". It does not say which side sends it first. In theory * it shouldn't matter but it is a fact of life that some SSH servers are simply buggy * */ public function sendKEXINITLast() { $this->send_kex_first = false; } /** * stream_select wrapper * * Quoting https://stackoverflow.com/a/14262151/569976, * "The general approach to `EINTR` is to simply handle the error and retry the operation again" * * This wrapper does that loop */ private static function stream_select(&$read, &$write, &$except, $seconds, $microseconds = null) { $remaining = $seconds + $microseconds / 1000000; $start = microtime(true); while (true) { $result = @stream_select($read, $write, $except, $seconds, $microseconds); if ($result !== false) { return $result; } $elapsed = microtime(true) - $start; $seconds = (int) ($remaining - floor($elapsed)); $microseconds = (int) (1000000 * ($remaining - $seconds)); if ($elapsed >= $remaining) { return false; } } } /** * Connect to an SSHv2 server * * @throws \UnexpectedValueException on receipt of unexpected packets * @throws \RuntimeException on other errors */ private function connect() { if ($this->bitmap & self::MASK_CONSTRUCTOR) { return; } $this->bitmap |= self::MASK_CONSTRUCTOR; $this->curTimeout = $this->timeout; if (!is_resource($this->fsock)) { $start = microtime(true); // with stream_select a timeout of 0 means that no timeout takes place; // with fsockopen a timeout of 0 means that you instantly timeout // to resolve this incompatibility a timeout of 100,000 will be used for fsockopen if timeout is 0 $this->fsock = @fsockopen($this->host, $this->port, $errno, $errstr, $this->curTimeout == 0 ? 100000 : $this->curTimeout); if (!$this->fsock) { $host = $this->host . ':' . $this->port; throw new UnableToConnectException(rtrim("Cannot connect to $host. Error $errno. $errstr")); } $elapsed = microtime(true) - $start; if ($this->curTimeout) { $this->curTimeout -= $elapsed; if ($this->curTimeout < 0) { throw new \RuntimeException('Connection timed out whilst attempting to open socket connection'); } } if (defined('NET_SSH2_LOGGING')) { $this->append_log('(fsockopen took ' . round($elapsed, 4) . 's)', ''); } } $this->identifier = $this->generate_identifier(); if ($this->send_id_string_first) { $start = microtime(true); fputs($this->fsock, $this->identifier . "\r\n"); $elapsed = round(microtime(true) - $start, 4); if (defined('NET_SSH2_LOGGING')) { $this->append_log("-> (network: $elapsed)", $this->identifier . "\r\n"); } } /* According to the SSH2 specs, "The server MAY send other lines of data before sending the version string. Each line SHOULD be terminated by a Carriage Return and Line Feed. Such lines MUST NOT begin with "SSH-", and SHOULD be encoded in ISO-10646 UTF-8 [RFC3629] (language is not specified). Clients MUST be able to process such lines." */ $data = ''; $totalElapsed = 0; while (!feof($this->fsock) && !preg_match('#(.*)^(SSH-(\d\.\d+).*)#ms', $data, $matches)) { $line = ''; while (true) { if ($this->curTimeout) { if ($this->curTimeout < 0) { throw new \RuntimeException('Connection timed out whilst receiving server identification string'); } $read = [$this->fsock]; $write = $except = null; $start = microtime(true); $sec = (int) floor($this->curTimeout); $usec = (int) (1000000 * ($this->curTimeout - $sec)); if (static::stream_select($read, $write, $except, $sec, $usec) === false) { throw new \RuntimeException('Connection timed out whilst receiving server identification string'); } $elapsed = microtime(true) - $start; $totalElapsed += $elapsed; $this->curTimeout -= $elapsed; } $temp = stream_get_line($this->fsock, 255, "\n"); if ($temp === false) { throw new \RuntimeException('Error reading SSH identification string; are you sure you\'re connecting to an SSH server?'); } $line .= $temp; if (strlen($temp) == 255) { continue; } $line .= "\n"; break; } $data .= $line; } if (defined('NET_SSH2_LOGGING')) { $this->append_log('<- (network: ' . round($totalElapsed, 4) . ')', $data); } if (feof($this->fsock)) { $this->bitmap = 0; throw new ConnectionClosedException('Connection closed by server; are you sure you\'re connected to an SSH server?'); } $extra = $matches[1]; // earlier the SSH specs were quoted. // "The server MAY send other lines of data before sending the version string." they said. // the implication of this is that the lines of data before the server string are *not* a part of it // getting this right is important because the correct server identifier needs to be fed into the // exchange hash for the shared keys to be calculated correctly $data = explode("\r\n", trim($data, "\r\n")); $this->server_identifier = $data[count($data) - 1]; if (strlen($extra)) { $this->errors[] = $data; } if (version_compare($matches[3], '1.99', '<')) { $this->bitmap = 0; throw new UnableToConnectException("Cannot connect to SSH $matches[3] servers"); } // Ubuntu's OpenSSH from 5.8 to 6.9 didn't work with multiple channels. see // https://bugs.launchpad.net/ubuntu/+source/openssh/+bug/1334916 for more info. // https://lists.ubuntu.com/archives/oneiric-changes/2011-July/005772.html discusses // when consolekit was incorporated. // https://marc.info/?l=openssh-unix-dev&m=163409903417589&w=2 discusses some of the // issues with how Ubuntu incorporated consolekit $pattern = '#^SSH-2\.0-OpenSSH_([\d.]+)[^ ]* Ubuntu-.*$#'; $match = preg_match($pattern, $this->server_identifier, $matches); $match = $match && version_compare('5.8', $matches[1], '<='); $match = $match && version_compare('6.9', $matches[1], '>='); $this->errorOnMultipleChannels = $match; if (!$this->send_id_string_first) { $start = microtime(true); fputs($this->fsock, $this->identifier . "\r\n"); $elapsed = round(microtime(true) - $start, 4); if (defined('NET_SSH2_LOGGING')) { $this->append_log("-> (network: $elapsed)", $this->identifier . "\r\n"); } } $this->last_packet = microtime(true); if (!$this->send_kex_first) { $response = $this->get_binary_packet_or_close(NET_SSH2_MSG_KEXINIT); $this->key_exchange($response); } if ($this->send_kex_first) { $this->key_exchange(); } $this->bitmap |= self::MASK_CONNECTED; return true; } /** * Generates the SSH identifier * * You should overwrite this method in your own class if you want to use another identifier * * @return string */ private function generate_identifier() { $identifier = 'SSH-2.0-phpseclib_3.0'; $ext = []; if (extension_loaded('sodium')) { $ext[] = 'libsodium'; } if (extension_loaded('openssl')) { $ext[] = 'openssl'; } elseif (extension_loaded('mcrypt')) { $ext[] = 'mcrypt'; } if (extension_loaded('gmp')) { $ext[] = 'gmp'; } elseif (extension_loaded('bcmath')) { $ext[] = 'bcmath'; } if (!empty($ext)) { $identifier .= ' (' . implode(', ', $ext) . ')'; } return $identifier; } /** * Key Exchange * * @return bool * @param string|bool $kexinit_payload_server optional * @throws \UnexpectedValueException on receipt of unexpected packets * @throws \RuntimeException on other errors * @throws NoSupportedAlgorithmsException when none of the algorithms phpseclib has loaded are compatible */ private function key_exchange($kexinit_payload_server = false) { $this->bytesTransferredSinceLastKEX = 0; $preferred = $this->preferred; // for the initial key exchange $send_kex is true (no key re-exchange has been started) // for phpseclib initiated key exchanges $send_kex is false $send_kex = !$this->keyExchangeInProgress; $this->keyExchangeInProgress = true; $kex_algorithms = isset($preferred['kex']) ? $preferred['kex'] : SSH2::getSupportedKEXAlgorithms(); $server_host_key_algorithms = isset($preferred['hostkey']) ? $preferred['hostkey'] : SSH2::getSupportedHostKeyAlgorithms(); $s2c_encryption_algorithms = isset($preferred['server_to_client']['crypt']) ? $preferred['server_to_client']['crypt'] : SSH2::getSupportedEncryptionAlgorithms(); $c2s_encryption_algorithms = isset($preferred['client_to_server']['crypt']) ? $preferred['client_to_server']['crypt'] : SSH2::getSupportedEncryptionAlgorithms(); $s2c_mac_algorithms = isset($preferred['server_to_client']['mac']) ? $preferred['server_to_client']['mac'] : SSH2::getSupportedMACAlgorithms(); $c2s_mac_algorithms = isset($preferred['client_to_server']['mac']) ? $preferred['client_to_server']['mac'] : SSH2::getSupportedMACAlgorithms(); $s2c_compression_algorithms = isset($preferred['server_to_client']['comp']) ? $preferred['server_to_client']['comp'] : SSH2::getSupportedCompressionAlgorithms(); $c2s_compression_algorithms = isset($preferred['client_to_server']['comp']) ? $preferred['client_to_server']['comp'] : SSH2::getSupportedCompressionAlgorithms(); $kex_algorithms = array_merge($kex_algorithms, ['ext-info-c', 'kex-strict-c-v00@openssh.com']); // some SSH servers have buggy implementations of some of the above algorithms switch (true) { case $this->server_identifier == 'SSH-2.0-SSHD': case substr($this->server_identifier, 0, 13) == 'SSH-2.0-DLINK': if (!isset($preferred['server_to_client']['mac'])) { $s2c_mac_algorithms = array_values(array_diff( $s2c_mac_algorithms, ['hmac-sha1-96', 'hmac-md5-96'] )); } if (!isset($preferred['client_to_server']['mac'])) { $c2s_mac_algorithms = array_values(array_diff( $c2s_mac_algorithms, ['hmac-sha1-96', 'hmac-md5-96'] )); } break; case substr($this->server_identifier, 0, 24) == 'SSH-2.0-TurboFTP_SERVER_': if (!isset($preferred['server_to_client']['crypt'])) { $s2c_encryption_algorithms = array_values(array_diff( $s2c_encryption_algorithms, ['aes128-gcm@openssh.com', 'aes256-gcm@openssh.com'] )); } if (!isset($preferred['client_to_server']['crypt'])) { $c2s_encryption_algorithms = array_values(array_diff( $c2s_encryption_algorithms, ['aes128-gcm@openssh.com', 'aes256-gcm@openssh.com'] )); } } $client_cookie = Random::string(16); $kexinit_payload_client = pack('Ca*', NET_SSH2_MSG_KEXINIT, $client_cookie); $kexinit_payload_client .= Strings::packSSH2( 'L10bN', $kex_algorithms, $server_host_key_algorithms, $c2s_encryption_algorithms, $s2c_encryption_algorithms, $c2s_mac_algorithms, $s2c_mac_algorithms, $c2s_compression_algorithms, $s2c_compression_algorithms, [], // language, client to server [], // language, server to client false, // first_kex_packet_follows 0 // reserved for future extension ); if ($kexinit_payload_server === false && $send_kex) { $this->send_binary_packet($kexinit_payload_client); while (true) { $kexinit_payload_server = $this->get_binary_packet(); switch (ord($kexinit_payload_server[0])) { case NET_SSH2_MSG_KEXINIT: break 2; case NET_SSH2_MSG_DISCONNECT: return $this->handleDisconnect($kexinit_payload_server); } $this->kex_buffer[] = $kexinit_payload_server; } $send_kex = false; } $response = $kexinit_payload_server; Strings::shift($response, 1); // skip past the message number (it should be SSH_MSG_KEXINIT) $server_cookie = Strings::shift($response, 16); list( $this->kex_algorithms, $this->server_host_key_algorithms, $this->encryption_algorithms_client_to_server, $this->encryption_algorithms_server_to_client, $this->mac_algorithms_client_to_server, $this->mac_algorithms_server_to_client, $this->compression_algorithms_client_to_server, $this->compression_algorithms_server_to_client, $this->languages_client_to_server, $this->languages_server_to_client, $first_kex_packet_follows ) = Strings::unpackSSH2('L10C', $response); if (in_array('kex-strict-s-v00@openssh.com', $this->kex_algorithms)) { if ($this->session_id === false) { // [kex-strict-s-v00@openssh.com is] only valid in the initial SSH2_MSG_KEXINIT and MUST be ignored // if [it is] present in subsequent SSH2_MSG_KEXINIT packets $this->strict_kex_flag = true; if (count($this->kex_buffer)) { throw new \UnexpectedValueException('Possible Terrapin Attack detected'); } } } $this->supported_private_key_algorithms = $this->server_host_key_algorithms; if ($send_kex) { $this->send_binary_packet($kexinit_payload_client); } // we need to decide upon the symmetric encryption algorithms before we do the diffie-hellman key exchange // we don't initialize any crypto-objects, yet - we do that, later. for now, we need the lengths to make the // diffie-hellman key exchange as fast as possible $decrypt = self::array_intersect_first($s2c_encryption_algorithms, $this->encryption_algorithms_server_to_client); if (!$decrypt || ($decryptKeyLength = $this->encryption_algorithm_to_key_size($decrypt)) === null) { $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); throw new NoSupportedAlgorithmsException('No compatible server to client encryption algorithms found'); } $encrypt = self::array_intersect_first($c2s_encryption_algorithms, $this->encryption_algorithms_client_to_server); if (!$encrypt || ($encryptKeyLength = $this->encryption_algorithm_to_key_size($encrypt)) === null) { $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); throw new NoSupportedAlgorithmsException('No compatible client to server encryption algorithms found'); } // through diffie-hellman key exchange a symmetric key is obtained $this->kex_algorithm = self::array_intersect_first($kex_algorithms, $this->kex_algorithms); if ($this->kex_algorithm === false) { $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); throw new NoSupportedAlgorithmsException('No compatible key exchange algorithms found'); } $server_host_key_algorithm = self::array_intersect_first($server_host_key_algorithms, $this->server_host_key_algorithms); if ($server_host_key_algorithm === false) { $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); throw new NoSupportedAlgorithmsException('No compatible server host key algorithms found'); } $mac_algorithm_out = self::array_intersect_first($c2s_mac_algorithms, $this->mac_algorithms_client_to_server); if ($mac_algorithm_out === false) { $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); throw new NoSupportedAlgorithmsException('No compatible client to server message authentication algorithms found'); } $mac_algorithm_in = self::array_intersect_first($s2c_mac_algorithms, $this->mac_algorithms_server_to_client); if ($mac_algorithm_in === false) { $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); throw new NoSupportedAlgorithmsException('No compatible server to client message authentication algorithms found'); } $compression_map = [ 'none' => self::NET_SSH2_COMPRESSION_NONE, 'zlib' => self::NET_SSH2_COMPRESSION_ZLIB, 'zlib@openssh.com' => self::NET_SSH2_COMPRESSION_ZLIB_AT_OPENSSH ]; $compression_algorithm_in = self::array_intersect_first($s2c_compression_algorithms, $this->compression_algorithms_server_to_client); if ($compression_algorithm_in === false) { $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); throw new NoSupportedAlgorithmsException('No compatible server to client compression algorithms found'); } $this->decompress = $compression_map[$compression_algorithm_in]; $compression_algorithm_out = self::array_intersect_first($c2s_compression_algorithms, $this->compression_algorithms_client_to_server); if ($compression_algorithm_out === false) { $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); throw new NoSupportedAlgorithmsException('No compatible client to server compression algorithms found'); } $this->compress = $compression_map[$compression_algorithm_out]; switch ($this->kex_algorithm) { case 'diffie-hellman-group15-sha512': case 'diffie-hellman-group16-sha512': case 'diffie-hellman-group17-sha512': case 'diffie-hellman-group18-sha512': case 'ecdh-sha2-nistp521': $kexHash = new Hash('sha512'); break; case 'ecdh-sha2-nistp384': $kexHash = new Hash('sha384'); break; case 'diffie-hellman-group-exchange-sha256': case 'diffie-hellman-group14-sha256': case 'ecdh-sha2-nistp256': case 'curve25519-sha256@libssh.org': case 'curve25519-sha256': $kexHash = new Hash('sha256'); break; default: $kexHash = new Hash('sha1'); } // Only relevant in diffie-hellman-group-exchange-sha{1,256}, otherwise empty. $exchange_hash_rfc4419 = ''; if (strpos($this->kex_algorithm, 'curve25519-sha256') === 0 || strpos($this->kex_algorithm, 'ecdh-sha2-nistp') === 0) { $curve = strpos($this->kex_algorithm, 'curve25519-sha256') === 0 ? 'Curve25519' : substr($this->kex_algorithm, 10); $ourPrivate = EC::createKey($curve); $ourPublicBytes = $ourPrivate->getPublicKey()->getEncodedCoordinates(); $clientKexInitMessage = 'NET_SSH2_MSG_KEX_ECDH_INIT'; $serverKexReplyMessage = 'NET_SSH2_MSG_KEX_ECDH_REPLY'; } else { if (strpos($this->kex_algorithm, 'diffie-hellman-group-exchange') === 0) { $dh_group_sizes_packed = pack( 'NNN', $this->kex_dh_group_size_min, $this->kex_dh_group_size_preferred, $this->kex_dh_group_size_max ); $packet = pack( 'Ca*', NET_SSH2_MSG_KEXDH_GEX_REQUEST, $dh_group_sizes_packed ); $this->send_binary_packet($packet); $this->updateLogHistory('UNKNOWN (34)', 'NET_SSH2_MSG_KEXDH_GEX_REQUEST'); $response = $this->get_binary_packet_or_close(NET_SSH2_MSG_KEXDH_GEX_GROUP); list($type, $primeBytes, $gBytes) = Strings::unpackSSH2('Css', $response); $this->updateLogHistory('NET_SSH2_MSG_KEXDH_REPLY', 'NET_SSH2_MSG_KEXDH_GEX_GROUP'); $prime = new BigInteger($primeBytes, -256); $g = new BigInteger($gBytes, -256); $exchange_hash_rfc4419 = $dh_group_sizes_packed . Strings::packSSH2( 'ss', $primeBytes, $gBytes ); $params = DH::createParameters($prime, $g); $clientKexInitMessage = 'NET_SSH2_MSG_KEXDH_GEX_INIT'; $serverKexReplyMessage = 'NET_SSH2_MSG_KEXDH_GEX_REPLY'; } else { $params = DH::createParameters($this->kex_algorithm); $clientKexInitMessage = 'NET_SSH2_MSG_KEXDH_INIT'; $serverKexReplyMessage = 'NET_SSH2_MSG_KEXDH_REPLY'; } $keyLength = min($kexHash->getLengthInBytes(), max($encryptKeyLength, $decryptKeyLength)); $ourPrivate = DH::createKey($params, 16 * $keyLength); // 2 * 8 * $keyLength $ourPublic = $ourPrivate->getPublicKey()->toBigInteger(); $ourPublicBytes = $ourPublic->toBytes(true); } $data = pack('CNa*', constant($clientKexInitMessage), strlen($ourPublicBytes), $ourPublicBytes); $this->send_binary_packet($data); switch ($clientKexInitMessage) { case 'NET_SSH2_MSG_KEX_ECDH_INIT': $this->updateLogHistory('NET_SSH2_MSG_KEXDH_INIT', 'NET_SSH2_MSG_KEX_ECDH_INIT'); break; case 'NET_SSH2_MSG_KEXDH_GEX_INIT': $this->updateLogHistory('UNKNOWN (32)', 'NET_SSH2_MSG_KEXDH_GEX_INIT'); } $response = $this->get_binary_packet_or_close(constant($serverKexReplyMessage)); list( $type, $server_public_host_key, $theirPublicBytes, $this->signature ) = Strings::unpackSSH2('Csss', $response); switch ($serverKexReplyMessage) { case 'NET_SSH2_MSG_KEX_ECDH_REPLY': $this->updateLogHistory('NET_SSH2_MSG_KEXDH_REPLY', 'NET_SSH2_MSG_KEX_ECDH_REPLY'); break; case 'NET_SSH2_MSG_KEXDH_GEX_REPLY': $this->updateLogHistory('UNKNOWN (33)', 'NET_SSH2_MSG_KEXDH_GEX_REPLY'); } $this->server_public_host_key = $server_public_host_key; list($public_key_format) = Strings::unpackSSH2('s', $server_public_host_key); if (strlen($this->signature) < 4) { throw new \LengthException('The signature needs at least four bytes'); } $temp = unpack('Nlength', substr($this->signature, 0, 4)); $this->signature_format = substr($this->signature, 4, $temp['length']); $keyBytes = DH::computeSecret($ourPrivate, $theirPublicBytes); if (($keyBytes & "\xFF\x80") === "\x00\x00") { $keyBytes = substr($keyBytes, 1); } elseif (($keyBytes[0] & "\x80") === "\x80") { $keyBytes = "\0$keyBytes"; } $this->exchange_hash = Strings::packSSH2( 's5', $this->identifier, $this->server_identifier, $kexinit_payload_client, $kexinit_payload_server, $this->server_public_host_key ); $this->exchange_hash .= $exchange_hash_rfc4419; $this->exchange_hash .= Strings::packSSH2( 's3', $ourPublicBytes, $theirPublicBytes, $keyBytes ); $this->exchange_hash = $kexHash->hash($this->exchange_hash); if ($this->session_id === false) { $this->session_id = $this->exchange_hash; } switch ($server_host_key_algorithm) { case 'rsa-sha2-256': case 'rsa-sha2-512': //case 'ssh-rsa': $expected_key_format = 'ssh-rsa'; break; default: $expected_key_format = $server_host_key_algorithm; } if ($public_key_format != $expected_key_format || $this->signature_format != $server_host_key_algorithm) { switch (true) { case $this->signature_format == $server_host_key_algorithm: case $server_host_key_algorithm != 'rsa-sha2-256' && $server_host_key_algorithm != 'rsa-sha2-512': case $this->signature_format != 'ssh-rsa': $this->disconnect_helper(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE); throw new \RuntimeException('Server Host Key Algorithm Mismatch (' . $this->signature_format . ' vs ' . $server_host_key_algorithm . ')'); } } $packet = pack('C', NET_SSH2_MSG_NEWKEYS); $this->send_binary_packet($packet); $this->get_binary_packet_or_close(NET_SSH2_MSG_NEWKEYS); $this->keyExchangeInProgress = false; if ($this->strict_kex_flag) { $this->get_seq_no = $this->send_seq_no = 0; } $keyBytes = pack('Na*', strlen($keyBytes), $keyBytes); $this->encrypt = self::encryption_algorithm_to_crypt_instance($encrypt); if ($this->encrypt) { if (self::$crypto_engine) { $this->encrypt->setPreferredEngine(self::$crypto_engine); } if ($this->encrypt->getBlockLengthInBytes()) { $this->encrypt_block_size = $this->encrypt->getBlockLengthInBytes(); } $this->encrypt->disablePadding(); if ($this->encrypt->usesIV()) { $iv = $kexHash->hash($keyBytes . $this->exchange_hash . 'A' . $this->session_id); while ($this->encrypt_block_size > strlen($iv)) { $iv .= $kexHash->hash($keyBytes . $this->exchange_hash . $iv); } $this->encrypt->setIV(substr($iv, 0, $this->encrypt_block_size)); } switch ($encrypt) { case 'aes128-gcm@openssh.com': case 'aes256-gcm@openssh.com': $nonce = $kexHash->hash($keyBytes . $this->exchange_hash . 'A' . $this->session_id); $this->encryptFixedPart = substr($nonce, 0, 4); $this->encryptInvocationCounter = substr($nonce, 4, 8); // fall-through case 'chacha20-poly1305@openssh.com': break; default: $this->encrypt->enableContinuousBuffer(); } $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'C' . $this->session_id); while ($encryptKeyLength > strlen($key)) { $key .= $kexHash->hash($keyBytes . $this->exchange_hash . $key); } switch ($encrypt) { case 'chacha20-poly1305@openssh.com': $encryptKeyLength = 32; $this->lengthEncrypt = self::encryption_algorithm_to_crypt_instance($encrypt); $this->lengthEncrypt->setKey(substr($key, 32, 32)); } $this->encrypt->setKey(substr($key, 0, $encryptKeyLength)); $this->encryptName = $encrypt; } $this->decrypt = self::encryption_algorithm_to_crypt_instance($decrypt); if ($this->decrypt) { if (self::$crypto_engine) { $this->decrypt->setPreferredEngine(self::$crypto_engine); } if ($this->decrypt->getBlockLengthInBytes()) { $this->decrypt_block_size = $this->decrypt->getBlockLengthInBytes(); } $this->decrypt->disablePadding(); if ($this->decrypt->usesIV()) { $iv = $kexHash->hash($keyBytes . $this->exchange_hash . 'B' . $this->session_id); while ($this->decrypt_block_size > strlen($iv)) { $iv .= $kexHash->hash($keyBytes . $this->exchange_hash . $iv); } $this->decrypt->setIV(substr($iv, 0, $this->decrypt_block_size)); } switch ($decrypt) { case 'aes128-gcm@openssh.com': case 'aes256-gcm@openssh.com': // see https://tools.ietf.org/html/rfc5647#section-7.1 $nonce = $kexHash->hash($keyBytes . $this->exchange_hash . 'B' . $this->session_id); $this->decryptFixedPart = substr($nonce, 0, 4); $this->decryptInvocationCounter = substr($nonce, 4, 8); // fall-through case 'chacha20-poly1305@openssh.com': break; default: $this->decrypt->enableContinuousBuffer(); } $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'D' . $this->session_id); while ($decryptKeyLength > strlen($key)) { $key .= $kexHash->hash($keyBytes . $this->exchange_hash . $key); } switch ($decrypt) { case 'chacha20-poly1305@openssh.com': $decryptKeyLength = 32; $this->lengthDecrypt = self::encryption_algorithm_to_crypt_instance($decrypt); $this->lengthDecrypt->setKey(substr($key, 32, 32)); } $this->decrypt->setKey(substr($key, 0, $decryptKeyLength)); $this->decryptName = $decrypt; } /* The "arcfour128" algorithm is the RC4 cipher, as described in [SCHNEIER], using a 128-bit key. The first 1536 bytes of keystream generated by the cipher MUST be discarded, and the first byte of the first encrypted packet MUST be encrypted using the 1537th byte of keystream. -- http://tools.ietf.org/html/rfc4345#section-4 */ if ($encrypt == 'arcfour128' || $encrypt == 'arcfour256') { $this->encrypt->encrypt(str_repeat("\0", 1536)); } if ($decrypt == 'arcfour128' || $decrypt == 'arcfour256') { $this->decrypt->decrypt(str_repeat("\0", 1536)); } if (!$this->encrypt->usesNonce()) { list($this->hmac_create, $createKeyLength) = self::mac_algorithm_to_hash_instance($mac_algorithm_out); } else { $this->hmac_create = new \stdClass(); $this->hmac_create_name = $mac_algorithm_out; //$mac_algorithm_out = 'none'; $createKeyLength = 0; } if ($this->hmac_create instanceof Hash) { $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'E' . $this->session_id); while ($createKeyLength > strlen($key)) { $key .= $kexHash->hash($keyBytes . $this->exchange_hash . $key); } $this->hmac_create->setKey(substr($key, 0, $createKeyLength)); $this->hmac_create_name = $mac_algorithm_out; $this->hmac_create_etm = preg_match('#-etm@openssh\.com$#', $mac_algorithm_out); } if (!$this->decrypt->usesNonce()) { list($this->hmac_check, $checkKeyLength) = self::mac_algorithm_to_hash_instance($mac_algorithm_in); $this->hmac_size = $this->hmac_check->getLengthInBytes(); } else { $this->hmac_check = new \stdClass(); $this->hmac_check_name = $mac_algorithm_in; //$mac_algorithm_in = 'none'; $checkKeyLength = 0; $this->hmac_size = 0; } if ($this->hmac_check instanceof Hash) { $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'F' . $this->session_id); while ($checkKeyLength > strlen($key)) { $key .= $kexHash->hash($keyBytes . $this->exchange_hash . $key); } $this->hmac_check->setKey(substr($key, 0, $checkKeyLength)); $this->hmac_check_name = $mac_algorithm_in; $this->hmac_check_etm = preg_match('#-etm@openssh\.com$#', $mac_algorithm_in); } $this->regenerate_compression_context = $this->regenerate_decompression_context = true; return true; } /** * Maps an encryption algorithm name to the number of key bytes. * * @param string $algorithm Name of the encryption algorithm * @return int|null Number of bytes as an integer or null for unknown */ private function encryption_algorithm_to_key_size($algorithm) { if ($this->bad_key_size_fix && self::bad_algorithm_candidate($algorithm)) { return 16; } switch ($algorithm) { case 'none': return 0; case 'aes128-gcm@openssh.com': case 'aes128-cbc': case 'aes128-ctr': case 'arcfour': case 'arcfour128': case 'blowfish-cbc': case 'blowfish-ctr': case 'twofish128-cbc': case 'twofish128-ctr': return 16; case '3des-cbc': case '3des-ctr': case 'aes192-cbc': case 'aes192-ctr': case 'twofish192-cbc': case 'twofish192-ctr': return 24; case 'aes256-gcm@openssh.com': case 'aes256-cbc': case 'aes256-ctr': case 'arcfour256': case 'twofish-cbc': case 'twofish256-cbc': case 'twofish256-ctr': return 32; case 'chacha20-poly1305@openssh.com': return 64; } return null; } /** * Maps an encryption algorithm name to an instance of a subclass of * \phpseclib3\Crypt\Common\SymmetricKey. * * @param string $algorithm Name of the encryption algorithm * @return SymmetricKey|null */ private static function encryption_algorithm_to_crypt_instance($algorithm) { switch ($algorithm) { case '3des-cbc': return new TripleDES('cbc'); case '3des-ctr': return new TripleDES('ctr'); case 'aes256-cbc': case 'aes192-cbc': case 'aes128-cbc': return new Rijndael('cbc'); case 'aes256-ctr': case 'aes192-ctr': case 'aes128-ctr': return new Rijndael('ctr'); case 'blowfish-cbc': return new Blowfish('cbc'); case 'blowfish-ctr': return new Blowfish('ctr'); case 'twofish128-cbc': case 'twofish192-cbc': case 'twofish256-cbc': case 'twofish-cbc': return new Twofish('cbc'); case 'twofish128-ctr': case 'twofish192-ctr': case 'twofish256-ctr': return new Twofish('ctr'); case 'arcfour': case 'arcfour128': case 'arcfour256': return new RC4(); case 'aes128-gcm@openssh.com': case 'aes256-gcm@openssh.com': return new Rijndael('gcm'); case 'chacha20-poly1305@openssh.com': return new ChaCha20(); } return null; } /** * Maps an encryption algorithm name to an instance of a subclass of * \phpseclib3\Crypt\Hash. * * @param string $algorithm Name of the encryption algorithm * @return array{Hash, int}|null */ private static function mac_algorithm_to_hash_instance($algorithm) { switch ($algorithm) { case 'umac-64@openssh.com': case 'umac-64-etm@openssh.com': return [new Hash('umac-64'), 16]; case 'umac-128@openssh.com': case 'umac-128-etm@openssh.com': return [new Hash('umac-128'), 16]; case 'hmac-sha2-512': case 'hmac-sha2-512-etm@openssh.com': return [new Hash('sha512'), 64]; case 'hmac-sha2-256': case 'hmac-sha2-256-etm@openssh.com': return [new Hash('sha256'), 32]; case 'hmac-sha1': case 'hmac-sha1-etm@openssh.com': return [new Hash('sha1'), 20]; case 'hmac-sha1-96': return [new Hash('sha1-96'), 20]; case 'hmac-md5': return [new Hash('md5'), 16]; case 'hmac-md5-96': return [new Hash('md5-96'), 16]; } } /** * Tests whether or not proposed algorithm has a potential for issues * * @link https://www.chiark.greenend.org.uk/~sgtatham/putty/wishlist/ssh2-aesctr-openssh.html * @link https://bugzilla.mindrot.org/show_bug.cgi?id=1291 * @param string $algorithm Name of the encryption algorithm * @return bool */ private static function bad_algorithm_candidate($algorithm) { switch ($algorithm) { case 'arcfour256': case 'aes192-ctr': case 'aes256-ctr': return true; } return false; } /** * Login * * The $password parameter can be a plaintext password, a \phpseclib3\Crypt\RSA|EC|DSA object, a \phpseclib3\System\SSH\Agent object or an array * * @param string $username * @param string|PrivateKey|array[]|Agent|null ...$args * @return bool * @see self::_login() */ public function login($username, ...$args) { if (!$this->login_credentials_finalized) { $this->auth[] = func_get_args(); } // try logging with 'none' as an authentication method first since that's what // PuTTY does if (substr($this->server_identifier, 0, 15) != 'SSH-2.0-CoreFTP' && $this->auth_methods_to_continue === null) { if ($this->sublogin($username)) { return true; } if (!count($args)) { return false; } } return $this->sublogin($username, ...$args); } /** * Login Helper * * @param string $username * @param string|PrivateKey|array[]|Agent|null ...$args * @return bool * @see self::_login_helper() */ protected function sublogin($username, ...$args) { if (!($this->bitmap & self::MASK_CONSTRUCTOR)) { $this->connect(); } if (empty($args)) { return $this->login_helper($username); } foreach ($args as $arg) { switch (true) { case $arg instanceof PublicKey: throw new \UnexpectedValueException('A PublicKey object was passed to the login method instead of a PrivateKey object'); case $arg instanceof PrivateKey: case $arg instanceof Agent: case is_array($arg): case Strings::is_stringable($arg): break; default: throw new \UnexpectedValueException('$password needs to either be an instance of \phpseclib3\Crypt\Common\PrivateKey, \System\SSH\Agent, an array or a string'); } } while (count($args)) { if (!$this->auth_methods_to_continue || !$this->smartMFA) { $newargs = $args; $args = []; } else { $newargs = []; foreach ($this->auth_methods_to_continue as $method) { switch ($method) { case 'publickey': foreach ($args as $key => $arg) { if ($arg instanceof PrivateKey || $arg instanceof Agent) { $newargs[] = $arg; unset($args[$key]); break; } } break; case 'keyboard-interactive': $hasArray = $hasString = false; foreach ($args as $arg) { if ($hasArray || is_array($arg)) { $hasArray = true; break; } if ($hasString || Strings::is_stringable($arg)) { $hasString = true; break; } } if ($hasArray && $hasString) { foreach ($args as $key => $arg) { if (is_array($arg)) { $newargs[] = $arg; break 2; } } } // fall-through case 'password': foreach ($args as $key => $arg) { $newargs[] = $arg; unset($args[$key]); break; } } } } if (!count($newargs)) { return false; } foreach ($newargs as $arg) { if ($this->login_helper($username, $arg)) { $this->login_credentials_finalized = true; return true; } } } return false; } /** * Login Helper * * {@internal It might be worthwhile, at some point, to protect against {@link http://tools.ietf.org/html/rfc4251#section-9.3.9 traffic analysis} * by sending dummy SSH_MSG_IGNORE messages.} * * @param string $username * @param string|AsymmetricKey|array[]|Agent|null ...$args * @return bool * @throws \UnexpectedValueException on receipt of unexpected packets * @throws \RuntimeException on other errors */ private function login_helper($username, $password = null) { if (!($this->bitmap & self::MASK_CONNECTED)) { return false; } if (!($this->bitmap & self::MASK_LOGIN_REQ)) { $packet = Strings::packSSH2('Cs', NET_SSH2_MSG_SERVICE_REQUEST, 'ssh-userauth'); $this->send_binary_packet($packet); try { $response = $this->get_binary_packet_or_close(NET_SSH2_MSG_SERVICE_ACCEPT); } catch (InvalidPacketLengthException $e) { // the first opportunity to encounter the "bad key size" error if (!$this->bad_key_size_fix && $this->decryptName != null && self::bad_algorithm_candidate($this->decryptName)) { // bad_key_size_fix is only ever re-assigned to true here // retry the connection with that new setting but we'll // only try it once. $this->bad_key_size_fix = true; return $this->reconnect(); } throw $e; } list($type) = Strings::unpackSSH2('C', $response); list($service) = Strings::unpackSSH2('s', $response); if ($service != 'ssh-userauth') { $this->disconnect_helper(NET_SSH2_DISCONNECT_PROTOCOL_ERROR); throw new \UnexpectedValueException('Expected SSH_MSG_SERVICE_ACCEPT'); } $this->bitmap |= self::MASK_LOGIN_REQ; } if (strlen($this->last_interactive_response)) { return !Strings::is_stringable($password) && !is_array($password) ? false : $this->keyboard_interactive_process($password); } if ($password instanceof PrivateKey) { return $this->privatekey_login($username, $password); } if ($password instanceof Agent) { return $this->ssh_agent_login($username, $password); } if (is_array($password)) { if ($this->keyboard_interactive_login($username, $password)) { $this->bitmap |= self::MASK_LOGIN; return true; } return false; } if (!isset($password)) { $packet = Strings::packSSH2( 'Cs3', NET_SSH2_MSG_USERAUTH_REQUEST, $username, 'ssh-connection', 'none' ); $this->send_binary_packet($packet); $response = $this->get_binary_packet_or_close(); list($type) = Strings::unpackSSH2('C', $response); switch ($type) { case NET_SSH2_MSG_USERAUTH_SUCCESS: $this->bitmap |= self::MASK_LOGIN; return true; case NET_SSH2_MSG_USERAUTH_FAILURE: list($auth_methods) = Strings::unpackSSH2('L', $response); $this->auth_methods_to_continue = $auth_methods; // fall-through default: return false; } } $packet = Strings::packSSH2( 'Cs3bs', NET_SSH2_MSG_USERAUTH_REQUEST, $username, 'ssh-connection', 'password', false, $password ); // remove the username and password from the logged packet if (!defined('NET_SSH2_LOGGING')) { $logged = null; } else { $logged = Strings::packSSH2( 'Cs3bs', NET_SSH2_MSG_USERAUTH_REQUEST, $username, 'ssh-connection', 'password', false, 'password' ); } $this->send_binary_packet($packet, $logged); $response = $this->get_binary_packet_or_close(); list($type) = Strings::unpackSSH2('C', $response); switch ($type) { case NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ: // in theory, the password can be changed $this->updateLogHistory('UNKNOWN (60)', 'NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ'); list($message) = Strings::unpackSSH2('s', $response); $this->errors[] = 'SSH_MSG_USERAUTH_PASSWD_CHANGEREQ: ' . $message; return $this->disconnect_helper(NET_SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER); case NET_SSH2_MSG_USERAUTH_FAILURE: // can we use keyboard-interactive authentication? if not then either the login is bad or the server employees // multi-factor authentication list($auth_methods, $partial_success) = Strings::unpackSSH2('Lb', $response); $this->auth_methods_to_continue = $auth_methods; if (!$partial_success && in_array('keyboard-interactive', $auth_methods)) { if ($this->keyboard_interactive_login($username, $password)) { $this->bitmap |= self::MASK_LOGIN; return true; } return false; } return false; case NET_SSH2_MSG_USERAUTH_SUCCESS: $this->bitmap |= self::MASK_LOGIN; return true; } return false; } /** * Login via keyboard-interactive authentication * * See {@link http://tools.ietf.org/html/rfc4256 RFC4256} for details. This is not a full-featured keyboard-interactive authenticator. * * @param string $username * @param string|array $password * @return bool */ private function keyboard_interactive_login($username, $password) { $packet = Strings::packSSH2( 'Cs5', NET_SSH2_MSG_USERAUTH_REQUEST, $username, 'ssh-connection', 'keyboard-interactive', '', // language tag '' // submethods ); $this->send_binary_packet($packet); return $this->keyboard_interactive_process($password); } /** * Handle the keyboard-interactive requests / responses. * * @param string|array ...$responses * @return bool * @throws \RuntimeException on connection error */ private function keyboard_interactive_process(...$responses) { if (strlen($this->last_interactive_response)) { $response = $this->last_interactive_response; } else { $orig = $response = $this->get_binary_packet_or_close(); } list($type) = Strings::unpackSSH2('C', $response); switch ($type) { case NET_SSH2_MSG_USERAUTH_INFO_REQUEST: list( , // name; may be empty , // instruction; may be empty , // language tag; may be empty $num_prompts ) = Strings::unpackSSH2('s3N', $response); for ($i = 0; $i < count($responses); $i++) { if (is_array($responses[$i])) { foreach ($responses[$i] as $key => $value) { $this->keyboard_requests_responses[$key] = $value; } unset($responses[$i]); } } $responses = array_values($responses); if (isset($this->keyboard_requests_responses)) { for ($i = 0; $i < $num_prompts; $i++) { list( $prompt, // prompt - ie. "Password: "; must not be empty // echo ) = Strings::unpackSSH2('sC', $response); foreach ($this->keyboard_requests_responses as $key => $value) { if (substr($prompt, 0, strlen($key)) == $key) { $responses[] = $value; break; } } } } // see http://tools.ietf.org/html/rfc4256#section-3.2 if (strlen($this->last_interactive_response)) { $this->last_interactive_response = ''; } else { $this->updateLogHistory('UNKNOWN (60)', 'NET_SSH2_MSG_USERAUTH_INFO_REQUEST'); } if (!count($responses) && $num_prompts) { $this->last_interactive_response = $orig; return false; } /* After obtaining the requested information from the user, the client MUST respond with an SSH_MSG_USERAUTH_INFO_RESPONSE message. */ // see http://tools.ietf.org/html/rfc4256#section-3.4 $packet = $logged = pack('CN', NET_SSH2_MSG_USERAUTH_INFO_RESPONSE, count($responses)); for ($i = 0; $i < count($responses); $i++) { $packet .= Strings::packSSH2('s', $responses[$i]); $logged .= Strings::packSSH2('s', 'dummy-answer'); } $this->send_binary_packet($packet, $logged); $this->updateLogHistory('UNKNOWN (61)', 'NET_SSH2_MSG_USERAUTH_INFO_RESPONSE'); /* After receiving the response, the server MUST send either an SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, or another SSH_MSG_USERAUTH_INFO_REQUEST message. */ // maybe phpseclib should force close the connection after x request / responses? unless something like that is done // there could be an infinite loop of request / responses. return $this->keyboard_interactive_process(); case NET_SSH2_MSG_USERAUTH_SUCCESS: return true; case NET_SSH2_MSG_USERAUTH_FAILURE: list($auth_methods) = Strings::unpackSSH2('L', $response); $this->auth_methods_to_continue = $auth_methods; return false; } return false; } /** * Login with an ssh-agent provided key * * @param string $username * @param Agent $agent * @return bool */ private function ssh_agent_login($username, Agent $agent) { $this->agent = $agent; $keys = $agent->requestIdentities(); $orig_algorithms = $this->supported_private_key_algorithms; foreach ($keys as $key) { if ($this->privatekey_login($username, $key)) { return true; } $this->supported_private_key_algorithms = $orig_algorithms; } return false; } /** * Login with an RSA private key * * {@internal It might be worthwhile, at some point, to protect against {@link http://tools.ietf.org/html/rfc4251#section-9.3.9 traffic analysis} * by sending dummy SSH_MSG_IGNORE messages.} * * @param string $username * @param PrivateKey $privatekey * @return bool * @throws \RuntimeException on connection error */ private function privatekey_login($username, PrivateKey $privatekey) { $publickey = $privatekey->getPublicKey(); if ($publickey instanceof RSA) { $privatekey = $privatekey->withPadding(RSA::SIGNATURE_PKCS1); $algos = ['rsa-sha2-256', 'rsa-sha2-512', 'ssh-rsa']; if (isset($this->preferred['hostkey'])) { $algos = array_intersect($algos, $this->preferred['hostkey']); } $algo = self::array_intersect_first($algos, $this->supported_private_key_algorithms); switch ($algo) { case 'rsa-sha2-512': $hash = 'sha512'; $signatureType = 'rsa-sha2-512'; break; case 'rsa-sha2-256': $hash = 'sha256'; $signatureType = 'rsa-sha2-256'; break; //case 'ssh-rsa': default: $hash = 'sha1'; $signatureType = 'ssh-rsa'; } } elseif ($publickey instanceof EC) { $privatekey = $privatekey->withSignatureFormat('SSH2'); $curveName = $privatekey->getCurve(); switch ($curveName) { case 'Ed25519': $hash = 'sha512'; $signatureType = 'ssh-ed25519'; break; case 'secp256r1': // nistp256 $hash = 'sha256'; $signatureType = 'ecdsa-sha2-nistp256'; break; case 'secp384r1': // nistp384 $hash = 'sha384'; $signatureType = 'ecdsa-sha2-nistp384'; break; case 'secp521r1': // nistp521 $hash = 'sha512'; $signatureType = 'ecdsa-sha2-nistp521'; break; default: if (is_array($curveName)) { throw new UnsupportedCurveException('Specified Curves are not supported by SSH2'); } throw new UnsupportedCurveException('Named Curve of ' . $curveName . ' is not supported by phpseclib3\'s SSH2 implementation'); } } elseif ($publickey instanceof DSA) { $privatekey = $privatekey->withSignatureFormat('SSH2'); $hash = 'sha1'; $signatureType = 'ssh-dss'; } else { throw new UnsupportedAlgorithmException('Please use either an RSA key, an EC one or a DSA key'); } $publickeyStr = $publickey->toString('OpenSSH', ['binary' => true]); $part1 = Strings::packSSH2( 'Csss', NET_SSH2_MSG_USERAUTH_REQUEST, $username, 'ssh-connection', 'publickey' ); $part2 = Strings::packSSH2('ss', $signatureType, $publickeyStr); $packet = $part1 . chr(0) . $part2; $this->send_binary_packet($packet); $response = $this->get_binary_packet_or_close( NET_SSH2_MSG_USERAUTH_SUCCESS, NET_SSH2_MSG_USERAUTH_FAILURE, NET_SSH2_MSG_USERAUTH_PK_OK ); list($type) = Strings::unpackSSH2('C', $response); switch ($type) { case NET_SSH2_MSG_USERAUTH_FAILURE: list($auth_methods) = Strings::unpackSSH2('L', $response); if (in_array('publickey', $auth_methods) && substr($signatureType, 0, 9) == 'rsa-sha2-') { $this->supported_private_key_algorithms = array_diff($this->supported_private_key_algorithms, ['rsa-sha2-256', 'rsa-sha2-512']); return $this->privatekey_login($username, $privatekey); } $this->auth_methods_to_continue = $auth_methods; $this->errors[] = 'SSH_MSG_USERAUTH_FAILURE'; return false; case NET_SSH2_MSG_USERAUTH_PK_OK: // we'll just take it on faith that the public key blob and the public key algorithm name are as // they should be $this->updateLogHistory('UNKNOWN (60)', 'NET_SSH2_MSG_USERAUTH_PK_OK'); break; case NET_SSH2_MSG_USERAUTH_SUCCESS: $this->bitmap |= self::MASK_LOGIN; return true; } $packet = $part1 . chr(1) . $part2; $privatekey = $privatekey->withHash($hash); $signature = $privatekey->sign(Strings::packSSH2('s', $this->session_id) . $packet); if ($publickey instanceof RSA) { $signature = Strings::packSSH2('ss', $signatureType, $signature); } $packet .= Strings::packSSH2('s', $signature); $this->send_binary_packet($packet); $response = $this->get_binary_packet_or_close( NET_SSH2_MSG_USERAUTH_SUCCESS, NET_SSH2_MSG_USERAUTH_FAILURE ); list($type) = Strings::unpackSSH2('C', $response); switch ($type) { case NET_SSH2_MSG_USERAUTH_FAILURE: // either the login is bad or the server employs multi-factor authentication list($auth_methods) = Strings::unpackSSH2('L', $response); $this->auth_methods_to_continue = $auth_methods; return false; case NET_SSH2_MSG_USERAUTH_SUCCESS: $this->bitmap |= self::MASK_LOGIN; return true; } } /** * Return the currently configured timeout * * @return int */ public function getTimeout() { return $this->timeout; } /** * Set Timeout * * $ssh->exec('ping 127.0.0.1'); on a Linux host will never return and will run indefinitely. setTimeout() makes it so it'll timeout. * Setting $timeout to false or 0 will revert to the default socket timeout. * * @param mixed $timeout */ public function setTimeout($timeout) { $this->timeout = $this->curTimeout = $timeout; } /** * Set Keep Alive * * Sends an SSH2_MSG_IGNORE message every x seconds, if x is a positive non-zero number. * * @param int $interval */ public function setKeepAlive($interval) { $this->keepAlive = $interval; } /** * Get the output from stdError * */ public function getStdError() { return $this->stdErrorLog; } /** * Execute Command * * If $callback is set to false then \phpseclib3\Net\SSH2::get_channel_packet(self::CHANNEL_EXEC) will need to be called manually. * In all likelihood, this is not a feature you want to be taking advantage of. * * @param string $command * @param callable $callback * @return string|bool * @psalm-return ($callback is callable ? bool : string|bool) * @throws \RuntimeException on connection error */ public function exec($command, $callback = null) { $this->curTimeout = $this->timeout; $this->is_timeout = false; $this->stdErrorLog = ''; if (!$this->isAuthenticated()) { return false; } //if ($this->isPTYOpen()) { // throw new \RuntimeException('If you want to run multiple exec()\'s you will need to disable (and re-enable if appropriate) a PTY for each one.'); //} $this->open_channel(self::CHANNEL_EXEC); if ($this->request_pty === true) { $terminal_modes = pack('C', NET_SSH2_TTY_OP_END); $packet = Strings::packSSH2( 'CNsCsN4s', NET_SSH2_MSG_CHANNEL_REQUEST, $this->server_channels[self::CHANNEL_EXEC], 'pty-req', 1, $this->term, $this->windowColumns, $this->windowRows, 0, 0, $terminal_modes ); $this->send_binary_packet($packet); $this->channel_status[self::CHANNEL_EXEC] = NET_SSH2_MSG_CHANNEL_REQUEST; if (!$this->get_channel_packet(self::CHANNEL_EXEC)) { $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); throw new \RuntimeException('Unable to request pseudo-terminal'); } } // sending a pty-req SSH_MSG_CHANNEL_REQUEST message is unnecessary and, in fact, in most cases, slows things // down. the one place where it might be desirable is if you're doing something like \phpseclib3\Net\SSH2::exec('ping localhost &'). // with a pty-req SSH_MSG_CHANNEL_REQUEST, exec() will return immediately and the ping process will then // then immediately terminate. without such a request exec() will loop indefinitely. the ping process won't end but // neither will your script. // although, in theory, the size of SSH_MSG_CHANNEL_REQUEST could exceed the maximum packet size established by // SSH_MSG_CHANNEL_OPEN_CONFIRMATION, RFC4254#section-5.1 states that the "maximum packet size" refers to the // "maximum size of an individual data packet". ie. SSH_MSG_CHANNEL_DATA. RFC4254#section-5.2 corroborates. $packet = Strings::packSSH2( 'CNsCs', NET_SSH2_MSG_CHANNEL_REQUEST, $this->server_channels[self::CHANNEL_EXEC], 'exec', 1, $command ); $this->send_binary_packet($packet); $this->channel_status[self::CHANNEL_EXEC] = NET_SSH2_MSG_CHANNEL_REQUEST; if (!$this->get_channel_packet(self::CHANNEL_EXEC)) { return false; } $this->channel_status[self::CHANNEL_EXEC] = NET_SSH2_MSG_CHANNEL_DATA; if ($this->request_pty === true) { $this->channel_id_last_interactive = self::CHANNEL_EXEC; return true; } if ($callback === false) { return true; } $output = ''; while (true) { $temp = $this->get_channel_packet(self::CHANNEL_EXEC); switch (true) { case $temp === true: return is_callable($callback) ? true : $output; case $temp === false: return false; default: if (is_callable($callback)) { if ($callback($temp) === true) { $this->close_channel(self::CHANNEL_EXEC); return true; } } else { $output .= $temp; } } } } /** * How many channels are currently open? * * @return int */ public function getOpenChannelCount() { return $this->channelCount; } /** * Opens a channel * * @param string $channel * @param bool $skip_extended * @return bool */ protected function open_channel($channel, $skip_extended = false) { if (isset($this->channel_status[$channel])) { throw new \RuntimeException('Please close the channel (' . $channel . ') before trying to open it again'); } $this->channelCount++; if ($this->channelCount > 1 && $this->errorOnMultipleChannels) { throw new \RuntimeException("Ubuntu's OpenSSH from 5.8 to 6.9 doesn't work with multiple channels"); } // RFC4254 defines the (client) window size as "bytes the other party can send before it must wait for the window to // be adjusted". 0x7FFFFFFF is, at 2GB, the max size. technically, it should probably be decremented, but, // honestly, if you're transferring more than 2GB, you probably shouldn't be using phpseclib, anyway. // see http://tools.ietf.org/html/rfc4254#section-5.2 for more info $this->window_size_server_to_client[$channel] = $this->window_size; // 0x8000 is the maximum max packet size, per http://tools.ietf.org/html/rfc4253#section-6.1, although since PuTTy // uses 0x4000, that's what will be used here, as well. $packet_size = 0x4000; $packet = Strings::packSSH2( 'CsN3', NET_SSH2_MSG_CHANNEL_OPEN, 'session', $channel, $this->window_size_server_to_client[$channel], $packet_size ); $this->send_binary_packet($packet); $this->channel_status[$channel] = NET_SSH2_MSG_CHANNEL_OPEN; return $this->get_channel_packet($channel, $skip_extended); } /** * Creates an interactive shell * * Returns bool(true) if the shell was opened. * Returns bool(false) if the shell was already open. * * @see self::isShellOpen() * @see self::read() * @see self::write() * @return bool * @throws InsufficientSetupException if not authenticated * @throws \UnexpectedValueException on receipt of unexpected packets * @throws \RuntimeException on other errors */ public function openShell() { if (!$this->isAuthenticated()) { throw new InsufficientSetupException('Operation disallowed prior to login()'); } $this->open_channel(self::CHANNEL_SHELL); $terminal_modes = pack('C', NET_SSH2_TTY_OP_END); $packet = Strings::packSSH2( 'CNsbsN4s', NET_SSH2_MSG_CHANNEL_REQUEST, $this->server_channels[self::CHANNEL_SHELL], 'pty-req', true, // want reply $this->term, $this->windowColumns, $this->windowRows, 0, 0, $terminal_modes ); $this->send_binary_packet($packet); $this->channel_status[self::CHANNEL_SHELL] = NET_SSH2_MSG_CHANNEL_REQUEST; if (!$this->get_channel_packet(self::CHANNEL_SHELL)) { throw new \RuntimeException('Unable to request pty'); } $packet = Strings::packSSH2( 'CNsb', NET_SSH2_MSG_CHANNEL_REQUEST, $this->server_channels[self::CHANNEL_SHELL], 'shell', true // want reply ); $this->send_binary_packet($packet); $response = $this->get_channel_packet(self::CHANNEL_SHELL); if ($response === false) { throw new \RuntimeException('Unable to request shell'); } $this->channel_status[self::CHANNEL_SHELL] = NET_SSH2_MSG_CHANNEL_DATA; $this->channel_id_last_interactive = self::CHANNEL_SHELL; $this->bitmap |= self::MASK_SHELL; return true; } /** * Return the channel to be used with read(), write(), and reset(), if none were specified * @deprecated for lack of transparency in intended channel target, to be potentially replaced * with method which guarantees open-ness of all yielded channels and throws * error for multiple open channels * @see self::read() * @see self::write() * @return int */ private function get_interactive_channel() { switch (true) { case $this->is_channel_status_data(self::CHANNEL_SUBSYSTEM): return self::CHANNEL_SUBSYSTEM; case $this->is_channel_status_data(self::CHANNEL_EXEC): return self::CHANNEL_EXEC; default: return self::CHANNEL_SHELL; } } /** * Indicates the DATA status on the given channel * * @param int $channel The channel number to evaluate * @return bool */ private function is_channel_status_data($channel) { return isset($this->channel_status[$channel]) && $this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_DATA; } /** * Return an available open channel * * @return int */ private function get_open_channel() { $channel = self::CHANNEL_EXEC; do { if (isset($this->channel_status[$channel]) && $this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_OPEN) { return $channel; } } while ($channel++ < self::CHANNEL_SUBSYSTEM); return false; } /** * Request agent forwarding of remote server * * @return bool */ public function requestAgentForwarding() { $request_channel = $this->get_open_channel(); if ($request_channel === false) { return false; } $packet = Strings::packSSH2( 'CNsC', NET_SSH2_MSG_CHANNEL_REQUEST, $this->server_channels[$request_channel], 'auth-agent-req@openssh.com', 1 ); $this->channel_status[$request_channel] = NET_SSH2_MSG_CHANNEL_REQUEST; $this->send_binary_packet($packet); if (!$this->get_channel_packet($request_channel)) { return false; } $this->channel_status[$request_channel] = NET_SSH2_MSG_CHANNEL_OPEN; return true; } /** * Returns the output of an interactive shell * * Returns when there's a match for $expect, which can take the form of a string literal or, * if $mode == self::READ_REGEX, a regular expression. * * If not specifying a channel, an open interactive channel will be selected, or, if there are * no open channels, an interactive shell will be created. If there are multiple open * interactive channels, a legacy behavior will apply in which channel selection prioritizes * an active subsystem, the exec pty, and, lastly, the shell. If using multiple interactive * channels, callers are discouraged from relying on this legacy behavior and should specify * the intended channel. * * @see self::write() * @param string $expect * @param int $mode One of the self::READ_* constants * @param int|null $channel Channel id returned by self::getInteractiveChannelId() * @return string|bool|null * @throws \RuntimeException on connection error * @throws InsufficientSetupException on unexpected channel status, possibly due to closure */ public function read($expect = '', $mode = self::READ_SIMPLE, $channel = null) { if (!$this->isAuthenticated()) { throw new InsufficientSetupException('Operation disallowed prior to login()'); } $this->curTimeout = $this->timeout; $this->is_timeout = false; if ($channel === null) { $channel = $this->get_interactive_channel(); } if (!$this->is_channel_status_data($channel) && empty($this->channel_buffers[$channel])) { if ($channel != self::CHANNEL_SHELL) { throw new InsufficientSetupException('Data is not available on channel'); } elseif (!$this->openShell()) { throw new \RuntimeException('Unable to initiate an interactive shell session'); } } if ($mode == self::READ_NEXT) { return $this->get_channel_packet($channel); } $match = $expect; while (true) { if ($mode == self::READ_REGEX) { preg_match($expect, substr($this->interactiveBuffer, -1024), $matches); $match = isset($matches[0]) ? $matches[0] : ''; } $pos = strlen($match) ? strpos($this->interactiveBuffer, $match) : false; if ($pos !== false) { return Strings::shift($this->interactiveBuffer, $pos + strlen($match)); } $response = $this->get_channel_packet($channel); if ($response === true) { return Strings::shift($this->interactiveBuffer, strlen($this->interactiveBuffer)); } $this->interactiveBuffer .= $response; } } /** * Inputs a command into an interactive shell. * * If not specifying a channel, an open interactive channel will be selected, or, if there are * no open channels, an interactive shell will be created. If there are multiple open * interactive channels, a legacy behavior will apply in which channel selection prioritizes * an active subsystem, the exec pty, and, lastly, the shell. If using multiple interactive * channels, callers are discouraged from relying on this legacy behavior and should specify * the intended channel. * * @see SSH2::read() * @param string $cmd * @param int|null $channel Channel id returned by self::getInteractiveChannelId() * @return void * @throws \RuntimeException on connection error * @throws InsufficientSetupException on unexpected channel status, possibly due to closure * @throws TimeoutException if the write could not be completed within the requested self::setTimeout() */ public function write($cmd, $channel = null) { if (!$this->isAuthenticated()) { throw new InsufficientSetupException('Operation disallowed prior to login()'); } if ($channel === null) { $channel = $this->get_interactive_channel(); } if (!$this->is_channel_status_data($channel)) { if ($channel != self::CHANNEL_SHELL) { throw new InsufficientSetupException('Data is not available on channel'); } elseif (!$this->openShell()) { throw new \RuntimeException('Unable to initiate an interactive shell session'); } } $this->curTimeout = $this->timeout; $this->is_timeout = false; $this->send_channel_packet($channel, $cmd); } /** * Start a subsystem. * * Right now only one subsystem at a time is supported. To support multiple subsystem's stopSubsystem() could accept * a string that contained the name of the subsystem, but at that point, only one subsystem of each type could be opened. * To support multiple subsystem's of the same name maybe it'd be best if startSubsystem() generated a new channel id and * returns that and then that that was passed into stopSubsystem() but that'll be saved for a future date and implemented * if there's sufficient demand for such a feature. * * @see self::stopSubsystem() * @param string $subsystem * @return bool */ public function startSubsystem($subsystem) { $this->open_channel(self::CHANNEL_SUBSYSTEM); $packet = Strings::packSSH2( 'CNsCs', NET_SSH2_MSG_CHANNEL_REQUEST, $this->server_channels[self::CHANNEL_SUBSYSTEM], 'subsystem', 1, $subsystem ); $this->send_binary_packet($packet); $this->channel_status[self::CHANNEL_SUBSYSTEM] = NET_SSH2_MSG_CHANNEL_REQUEST; if (!$this->get_channel_packet(self::CHANNEL_SUBSYSTEM)) { return false; } $this->channel_status[self::CHANNEL_SUBSYSTEM] = NET_SSH2_MSG_CHANNEL_DATA; $this->channel_id_last_interactive = self::CHANNEL_SUBSYSTEM; return true; } /** * Stops a subsystem. * * @see self::startSubsystem() * @return bool */ public function stopSubsystem() { if ($this->isInteractiveChannelOpen(self::CHANNEL_SUBSYSTEM)) { $this->close_channel(self::CHANNEL_SUBSYSTEM); } return true; } /** * Closes a channel * * If read() timed out you might want to just close the channel and have it auto-restart on the next read() call * * If not specifying a channel, an open interactive channel will be selected. If there are * multiple open interactive channels, a legacy behavior will apply in which channel selection * prioritizes an active subsystem, the exec pty, and, lastly, the shell. If using multiple * interactive channels, callers are discouraged from relying on this legacy behavior and * should specify the intended channel. * * @param int|null $channel Channel id returned by self::getInteractiveChannelId() * @return void */ public function reset($channel = null) { if ($channel === null) { $channel = $this->get_interactive_channel(); } if ($this->isInteractiveChannelOpen($channel)) { $this->close_channel($channel); } } /** * Send EOF on a channel * * Sends an EOF to the stream; this is typically used to close standard * input, while keeping output and error alive. * * @param int|null $channel Channel id returned by self::getInteractiveChannelId() * @return void */ public function sendEOF($channel = null) { if ($channel === null) { $channel = $this->get_interactive_channel(); } $excludeStatuses = [NET_SSH2_MSG_CHANNEL_EOF, NET_SSH2_MSG_CHANNEL_CLOSE]; if (isset($this->channel_status[$channel]) && !in_array($this->channel_status[$channel], $excludeStatuses)) { $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_EOF, $this->server_channels[$channel])); } } /** * Is timeout? * * Did exec() or read() return because they timed out or because they encountered the end? * */ public function isTimeout() { return $this->is_timeout; } /** * Disconnect * */ public function disconnect() { $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); if (isset($this->realtime_log_file) && is_resource($this->realtime_log_file)) { fclose($this->realtime_log_file); } unset(self::$connections[$this->getResourceId()]); } /** * Destructor. * * Will be called, automatically, if you're supporting just PHP5. If you're supporting PHP4, you'll need to call * disconnect(). * */ public function __destruct() { $this->disconnect(); } /** * Is the connection still active? * * $level has 3x possible values: * 0 (default): phpseclib takes a passive approach to see if the connection is still active by calling feof() * on the socket * 1: phpseclib takes an active approach to see if the connection is still active by sending an SSH_MSG_IGNORE * packet that doesn't require a response * 2: phpseclib takes an active approach to see if the connection is still active by sending an SSH_MSG_CHANNEL_OPEN * packet and imediately trying to close that channel. some routers, in particular, however, will only let you * open one channel, so this approach could yield false positives * * @param int $level * @return bool */ public function isConnected($level = 0) { if (!is_int($level) || $level < 0 || $level > 2) { throw new \InvalidArgumentException('$level must be 0, 1 or 2'); } if ($level == 0) { return ($this->bitmap & self::MASK_CONNECTED) && is_resource($this->fsock) && !feof($this->fsock); } try { if ($level == 1) { $this->send_binary_packet(pack('CN', NET_SSH2_MSG_IGNORE, 0)); } else { $this->open_channel(self::CHANNEL_KEEP_ALIVE); $this->close_channel(self::CHANNEL_KEEP_ALIVE); } return true; } catch (\Exception $e) { return false; } } /** * Have you successfully been logged in? * * @return bool */ public function isAuthenticated() { return (bool) ($this->bitmap & self::MASK_LOGIN); } /** * Is the interactive shell active? * * @return bool */ public function isShellOpen() { return $this->isInteractiveChannelOpen(self::CHANNEL_SHELL); } /** * Is the exec pty active? * * @return bool */ public function isPTYOpen() { return $this->isInteractiveChannelOpen(self::CHANNEL_EXEC); } /** * Is the given interactive channel active? * * @param int $channel Channel id returned by self::getInteractiveChannelId() * @return bool */ public function isInteractiveChannelOpen($channel) { return $this->isAuthenticated() && $this->is_channel_status_data($channel); } /** * Returns a channel identifier, presently of the last interactive channel opened, regardless of current status. * Returns 0 if no interactive channel has been opened. * * @see self::isInteractiveChannelOpen() * @return int */ public function getInteractiveChannelId() { return $this->channel_id_last_interactive; } /** * Pings a server connection, or tries to reconnect if the connection has gone down * * Inspired by http://php.net/manual/en/mysqli.ping.php * * @return bool */ public function ping() { if (!$this->isAuthenticated()) { if (!empty($this->auth)) { return $this->reconnect(); } return false; } try { $this->open_channel(self::CHANNEL_KEEP_ALIVE); } catch (\RuntimeException $e) { return $this->reconnect(); } $this->close_channel(self::CHANNEL_KEEP_ALIVE); return true; } /** * In situ reconnect method * * @return boolean */ private function reconnect() { $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); $this->connect(); foreach ($this->auth as $auth) { $result = $this->login(...$auth); } return $result; } /** * Resets a connection for re-use */ protected function reset_connection() { if (is_resource($this->fsock) && get_resource_type($this->fsock) === 'stream') { fclose($this->fsock); } $this->fsock = null; $this->bitmap = 0; $this->binary_packet_buffer = null; $this->decrypt = $this->encrypt = false; $this->decrypt_block_size = $this->encrypt_block_size = 8; $this->hmac_check = $this->hmac_create = false; $this->hmac_size = false; $this->session_id = false; $this->last_packet = null; $this->get_seq_no = $this->send_seq_no = 0; $this->channel_status = []; $this->channel_id_last_interactive = 0; $this->channel_buffers = []; $this->channel_buffers_write = []; } /** * @return int[] second and microsecond stream timeout options based on user-requested timeout and keep-alive, or the default socket timeout by default, which mirrors PHP socket streams. */ private function get_stream_timeout() { $sec = ini_get('default_socket_timeout'); $usec = 0; if ($this->curTimeout > 0) { $sec = (int) floor($this->curTimeout); $usec = (int) (1000000 * ($this->curTimeout - $sec)); } if ($this->keepAlive > 0) { $elapsed = microtime(true) - $this->last_packet; $timeout = max($this->keepAlive - $elapsed, 0); if (!$this->curTimeout || $timeout < $this->curTimeout) { $sec = (int) floor($timeout); $usec = (int) (1000000 * ($timeout - $sec)); } } return [$sec, $usec]; } /** * Retrieves the next packet with added timeout and type handling * * @param string $message_types Message types to enforce in response, closing if not met * @return string * @throws ConnectionClosedException If an error has occurred preventing read of the next packet */ private function get_binary_packet_or_close(...$message_types) { try { $packet = $this->get_binary_packet(); if (count($message_types) > 0 && !in_array(ord($packet[0]), $message_types)) { $this->disconnect_helper(NET_SSH2_DISCONNECT_PROTOCOL_ERROR); throw new ConnectionClosedException('Bad message type. Expected: #' . implode(', #', $message_types) . '. Got: #' . ord($packet[0])); } return $packet; } catch (TimeoutException $e) { $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); throw new ConnectionClosedException('Connection closed due to timeout'); } } /** * Gets Binary Packets * * See '6. Binary Packet Protocol' of rfc4253 for more info. * * @see self::_send_binary_packet() * @return string * @throws TimeoutException If user requested timeout was reached while waiting for next packet * @throws ConnectionClosedException If an error has occurred preventing read of the next packet */ private function get_binary_packet() { if (!is_resource($this->fsock)) { throw new \InvalidArgumentException('fsock is not a resource.'); } if (!$this->keyExchangeInProgress && count($this->kex_buffer)) { return $this->filter(array_shift($this->kex_buffer)); } if ($this->binary_packet_buffer == null) { // buffer the packet to permit continued reads across timeouts $this->binary_packet_buffer = (object) [ 'read_time' => 0, // the time to read the packet from the socket 'raw' => '', // the raw payload read from the socket 'plain' => '', // the packet in plain text, excluding packet_length header 'packet_length' => null, // the packet_length value pulled from the payload 'size' => $this->decrypt_block_size, // the total size of this packet to be read from the socket // initialize to read single block until packet_length is available ]; } $packet = $this->binary_packet_buffer; while (strlen($packet->raw) < $packet->size) { if (feof($this->fsock)) { $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); throw new ConnectionClosedException('Connection closed by server'); } if ($this->curTimeout < 0) { $this->is_timeout = true; throw new TimeoutException('Timed out waiting for server'); } $this->send_keep_alive(); list($sec, $usec) = $this->get_stream_timeout(); stream_set_timeout($this->fsock, $sec, $usec); $start = microtime(true); $raw = stream_get_contents($this->fsock, $packet->size - strlen($packet->raw)); $elapsed = microtime(true) - $start; $packet->read_time += $elapsed; if ($this->curTimeout > 0) { $this->curTimeout -= $elapsed; } if ($raw === false) { $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); throw new ConnectionClosedException('Connection closed by server'); } elseif (!strlen($raw)) { continue; } $packet->raw .= $raw; if (!$packet->packet_length) { $this->get_binary_packet_size($packet); } } if (strlen($packet->raw) != $packet->size) { throw new \RuntimeException('Size of packet was not expected length'); } // destroy buffer as packet represents the entire payload and should be processed in full $this->binary_packet_buffer = null; // copy the raw payload, so as not to destroy original $raw = $packet->raw; if ($this->hmac_check instanceof Hash) { $hmac = Strings::pop($raw, $this->hmac_size); } $packet_length_header_size = 4; if ($this->decrypt) { switch ($this->decryptName) { case 'aes128-gcm@openssh.com': case 'aes256-gcm@openssh.com': $this->decrypt->setNonce( $this->decryptFixedPart . $this->decryptInvocationCounter ); Strings::increment_str($this->decryptInvocationCounter); $this->decrypt->setAAD(Strings::shift($raw, $packet_length_header_size)); $this->decrypt->setTag(Strings::pop($raw, $this->decrypt_block_size)); $packet->plain = $this->decrypt->decrypt($raw); break; case 'chacha20-poly1305@openssh.com': // This should be impossible, but we are checking anyway to narrow the type for Psalm. if (!($this->decrypt instanceof ChaCha20)) { throw new \LogicException('$this->decrypt is not a ' . ChaCha20::class); } $this->decrypt->setNonce(pack('N2', 0, $this->get_seq_no)); $this->decrypt->setCounter(0); // this is the same approach that's implemented in Salsa20::createPoly1305Key() // but we don't want to use the same AEAD construction that RFC8439 describes // for ChaCha20-Poly1305 so we won't rely on it (see Salsa20::poly1305()) $this->decrypt->setPoly1305Key( $this->decrypt->encrypt(str_repeat("\0", 32)) ); $this->decrypt->setAAD(Strings::shift($raw, $packet_length_header_size)); $this->decrypt->setCounter(1); $this->decrypt->setTag(Strings::pop($raw, 16)); $packet->plain = $this->decrypt->decrypt($raw); break; default: if (!$this->hmac_check instanceof Hash || !$this->hmac_check_etm) { // first block was already decrypted for contained packet_length header Strings::shift($raw, $this->decrypt_block_size); if (strlen($raw) > 0) { $packet->plain .= $this->decrypt->decrypt($raw); } } else { Strings::shift($raw, $packet_length_header_size); $packet->plain = $this->decrypt->decrypt($raw); } break; } } else { Strings::shift($raw, $packet_length_header_size); $packet->plain = $raw; } if ($this->hmac_check instanceof Hash) { $reconstructed = !$this->hmac_check_etm ? pack('Na*', $packet->packet_length, $packet->plain) : substr($packet->raw, 0, -$this->hmac_size); if (($this->hmac_check->getHash() & "\xFF\xFF\xFF\xFF") == 'umac') { $this->hmac_check->setNonce("\0\0\0\0" . pack('N', $this->get_seq_no)); if ($hmac != $this->hmac_check->hash($reconstructed)) { $this->disconnect_helper(NET_SSH2_DISCONNECT_MAC_ERROR); throw new ConnectionClosedException('Invalid UMAC'); } } else { if ($hmac != $this->hmac_check->hash(pack('Na*', $this->get_seq_no, $reconstructed))) { $this->disconnect_helper(NET_SSH2_DISCONNECT_MAC_ERROR); throw new ConnectionClosedException('Invalid HMAC'); } } } $padding_length = 0; $payload = $packet->plain; $padding_length = unpack('Cpadding_length', Strings::shift($payload, 1))['padding_length']; if ($padding_length > 0) { Strings::pop($payload, $padding_length); } if (!$this->keyExchangeInProgress) { $this->bytesTransferredSinceLastKEX += $packet->packet_length + $padding_length + 5; } if (empty($payload)) { $this->disconnect_helper(NET_SSH2_DISCONNECT_PROTOCOL_ERROR); throw new ConnectionClosedException('Plaintext is too short'); } switch ($this->decompress) { case self::NET_SSH2_COMPRESSION_ZLIB_AT_OPENSSH: if (!$this->isAuthenticated()) { break; } // fall-through case self::NET_SSH2_COMPRESSION_ZLIB: if ($this->regenerate_decompression_context) { $this->regenerate_decompression_context = false; $cmf = ord($payload[0]); $cm = $cmf & 0x0F; if ($cm != 8) { // deflate throw new UnsupportedAlgorithmException("Only CM = 8 ('deflate') is supported ($cm)"); } $cinfo = ($cmf & 0xF0) >> 4; if ($cinfo > 7) { throw new \RuntimeException("CINFO above 7 is not allowed ($cinfo)"); } $windowSize = 1 << ($cinfo + 8); $flg = ord($payload[1]); //$fcheck = $flg && 0x0F; if ((($cmf << 8) | $flg) % 31) { throw new \RuntimeException('fcheck failed'); } $fdict = boolval($flg & 0x20); $flevel = ($flg & 0xC0) >> 6; $this->decompress_context = inflate_init(ZLIB_ENCODING_RAW, ['window' => $cinfo + 8]); $payload = substr($payload, 2); } if ($this->decompress_context) { $payload = inflate_add($this->decompress_context, $payload, ZLIB_PARTIAL_FLUSH); } } $this->get_seq_no++; if (defined('NET_SSH2_LOGGING')) { $current = microtime(true); $message_number = isset(self::$message_numbers[ord($payload[0])]) ? self::$message_numbers[ord($payload[0])] : 'UNKNOWN (' . ord($payload[0]) . ')'; $message_number = '<- ' . $message_number . ' (since last: ' . round($current - $this->last_packet, 4) . ', network: ' . round($packet->read_time, 4) . 's)'; $this->append_log($message_number, $payload); } $this->last_packet = microtime(true); if ($this->bytesTransferredSinceLastKEX > $this->doKeyReexchangeAfterXBytes) { $this->key_exchange(); } return $this->filter($payload); } /** * @param object $packet The packet object being constructed, passed by reference * The size, packet_length, and plain properties of this object may be modified in processing * @throws InvalidPacketLengthException if the packet length header is invalid */ private function get_binary_packet_size(&$packet) { $packet_length_header_size = 4; if (strlen($packet->raw) < $packet_length_header_size) { return; } $packet_length = 0; $added_validation_length = 0; // indicates when the packet length header is included when validating packet length against block size if ($this->decrypt) { switch ($this->decryptName) { case 'aes128-gcm@openssh.com': case 'aes256-gcm@openssh.com': $packet_length = unpack('Npacket_length', substr($packet->raw, 0, $packet_length_header_size))['packet_length']; $packet->size = $packet_length_header_size + $packet_length + $this->decrypt_block_size; // expect tag break; case 'chacha20-poly1305@openssh.com': $this->lengthDecrypt->setNonce(pack('N2', 0, $this->get_seq_no)); $packet_length_header = $this->lengthDecrypt->decrypt(substr($packet->raw, 0, $packet_length_header_size)); $packet_length = unpack('Npacket_length', $packet_length_header)['packet_length']; $packet->size = $packet_length_header_size + $packet_length + 16; // expect tag break; default: if (!$this->hmac_check instanceof Hash || !$this->hmac_check_etm) { if (strlen($packet->raw) < $this->decrypt_block_size) { return; } $packet->plain = $this->decrypt->decrypt(substr($packet->raw, 0, $this->decrypt_block_size)); $packet_length = unpack('Npacket_length', Strings::shift($packet->plain, $packet_length_header_size))['packet_length']; $packet->size = $packet_length_header_size + $packet_length; $added_validation_length = $packet_length_header_size; } else { $packet_length = unpack('Npacket_length', substr($packet->raw, 0, $packet_length_header_size))['packet_length']; $packet->size = $packet_length_header_size + $packet_length; } break; } } else { $packet_length = unpack('Npacket_length', substr($packet->raw, 0, $packet_length_header_size))['packet_length']; $packet->size = $packet_length_header_size + $packet_length; $added_validation_length = $packet_length_header_size; } // quoting , // "implementations SHOULD check that the packet length is reasonable" // PuTTY uses 0x9000 as the actual max packet size and so to shall we if ( $packet_length <= 0 || $packet_length > 0x9000 || ($packet_length + $added_validation_length) % $this->decrypt_block_size != 0 ) { $this->disconnect_helper(NET_SSH2_DISCONNECT_PROTOCOL_ERROR); throw new InvalidPacketLengthException('Invalid packet length'); } if ($this->hmac_check instanceof Hash) { $packet->size += $this->hmac_size; } $packet->packet_length = $packet_length; } /** * Handle Disconnect * * Because some binary packets need to be ignored... * * @see self::filter() * @see self::key_exchange() * @return boolean * @access private */ private function handleDisconnect($payload) { Strings::shift($payload, 1); list($reason_code, $message) = Strings::unpackSSH2('Ns', $payload); $this->errors[] = 'SSH_MSG_DISCONNECT: ' . self::$disconnect_reasons[$reason_code] . "\r\n$message"; $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); throw new ConnectionClosedException('Connection closed by server'); } /** * Filter Binary Packets * * Because some binary packets need to be ignored... * * @see self::_get_binary_packet() * @param string $payload * @return string */ private function filter($payload) { if (ord($payload[0]) == NET_SSH2_MSG_DISCONNECT) { return $this->handleDisconnect($payload); } if ($this->session_id === false && $this->keyExchangeInProgress) { return $payload; } switch (ord($payload[0])) { case NET_SSH2_MSG_IGNORE: $payload = $this->get_binary_packet(); break; case NET_SSH2_MSG_DEBUG: Strings::shift($payload, 2); // second byte is "always_display" list($message) = Strings::unpackSSH2('s', $payload); $this->errors[] = "SSH_MSG_DEBUG: $message"; $payload = $this->get_binary_packet(); break; case NET_SSH2_MSG_UNIMPLEMENTED: break; // return payload case NET_SSH2_MSG_KEXINIT: // this is here for server initiated key re-exchanges after the initial key exchange if (!$this->keyExchangeInProgress && $this->session_id !== false) { if (!$this->key_exchange($payload)) { $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); throw new ConnectionClosedException('Key exchange failed'); } $payload = $this->get_binary_packet(); } break; case NET_SSH2_MSG_EXT_INFO: Strings::shift($payload, 1); list($nr_extensions) = Strings::unpackSSH2('N', $payload); for ($i = 0; $i < $nr_extensions; $i++) { list($extension_name, $extension_value) = Strings::unpackSSH2('ss', $payload); if ($extension_name == 'server-sig-algs') { $this->supported_private_key_algorithms = explode(',', $extension_value); } } $payload = $this->get_binary_packet(); } /* Once a party has sent a SSH_MSG_KEXINIT message for key exchange or re-exchange, until it has sent a SSH_MSG_NEWKEYS message (Section 7.3), it MUST NOT send any messages other than: o Transport layer generic messages (1 to 19) (but SSH_MSG_SERVICE_REQUEST and SSH_MSG_SERVICE_ACCEPT MUST NOT be sent); o Algorithm negotiation messages (20 to 29) (but further SSH_MSG_KEXINIT messages MUST NOT be sent); o Specific key exchange method messages (30 to 49). -- https://www.rfc-editor.org/rfc/rfc4253#section-7.1 */ if ($this->keyExchangeInProgress) { return $payload; } // see http://tools.ietf.org/html/rfc4252#section-5.4; only called when the encryption has been activated and when we haven't already logged in if (($this->bitmap & self::MASK_CONNECTED) && !$this->isAuthenticated() && ord($payload[0]) == NET_SSH2_MSG_USERAUTH_BANNER) { Strings::shift($payload, 1); list($this->banner_message) = Strings::unpackSSH2('s', $payload); $payload = $this->get_binary_packet(); } // only called when we've already logged in if (($this->bitmap & self::MASK_CONNECTED) && $this->isAuthenticated()) { switch (ord($payload[0])) { case NET_SSH2_MSG_CHANNEL_REQUEST: if (strlen($payload) == 31) { $unpacked = unpack('cpacket_type/Nchannel/Nlength', $payload); $packet_type = $unpacked['packet_type']; $channel = $unpacked['channel']; $length = $unpacked['length']; if (substr($payload, 9, $length) == 'keepalive@openssh.com' && isset($this->server_channels[$channel])) { if (ord(substr($payload, 9 + $length))) { // want reply $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_SUCCESS, $this->server_channels[$channel])); } $payload = $this->get_binary_packet(); } } break; case NET_SSH2_MSG_GLOBAL_REQUEST: // see http://tools.ietf.org/html/rfc4254#section-4 Strings::shift($payload, 1); list($request_name, $want_reply) = Strings::unpackSSH2('sb', $payload); $this->errors[] = "SSH_MSG_GLOBAL_REQUEST: $request_name"; if ($want_reply) { $this->send_binary_packet(pack('C', NET_SSH2_MSG_REQUEST_FAILURE)); } $payload = $this->get_binary_packet(); break; case NET_SSH2_MSG_CHANNEL_OPEN: // see http://tools.ietf.org/html/rfc4254#section-5.1 Strings::shift($payload, 1); list($data, $server_channel) = Strings::unpackSSH2('sN', $payload); switch ($data) { case 'auth-agent': case 'auth-agent@openssh.com': if (isset($this->agent)) { $new_channel = self::CHANNEL_AGENT_FORWARD; list( $remote_window_size, $remote_maximum_packet_size ) = Strings::unpackSSH2('NN', $payload); $this->packet_size_client_to_server[$new_channel] = $remote_window_size; $this->window_size_server_to_client[$new_channel] = $remote_maximum_packet_size; $this->window_size_client_to_server[$new_channel] = $this->window_size; $packet_size = 0x4000; $packet = pack( 'CN4', NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, $server_channel, $new_channel, $packet_size, $packet_size ); $this->server_channels[$new_channel] = $server_channel; $this->channel_status[$new_channel] = NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION; $this->send_binary_packet($packet); } break; default: $packet = Strings::packSSH2( 'CN2ss', NET_SSH2_MSG_CHANNEL_OPEN_FAILURE, $server_channel, NET_SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED, '', // description '' // language tag ); $this->send_binary_packet($packet); } $payload = $this->get_binary_packet(); break; } } return $payload; } /** * Enable Quiet Mode * * Suppress stderr from output * */ public function enableQuietMode() { $this->quiet_mode = true; } /** * Disable Quiet Mode * * Show stderr in output * */ public function disableQuietMode() { $this->quiet_mode = false; } /** * Returns whether Quiet Mode is enabled or not * * @see self::enableQuietMode() * @see self::disableQuietMode() * @return bool */ public function isQuietModeEnabled() { return $this->quiet_mode; } /** * Enable request-pty when using exec() * */ public function enablePTY() { $this->request_pty = true; } /** * Disable request-pty when using exec() * */ public function disablePTY() { if ($this->isPTYOpen()) { $this->close_channel(self::CHANNEL_EXEC); } $this->request_pty = false; } /** * Returns whether request-pty is enabled or not * * @see self::enablePTY() * @see self::disablePTY() * @return bool */ public function isPTYEnabled() { return $this->request_pty; } /** * Gets channel data * * Returns the data as a string. bool(true) is returned if: * * - the server closes the channel * - if the connection times out * - if a window adjust packet is received on the given negated client channel * - if the channel status is CHANNEL_OPEN and the response was CHANNEL_OPEN_CONFIRMATION * - if the channel status is CHANNEL_REQUEST and the response was CHANNEL_SUCCESS * - if the channel status is CHANNEL_CLOSE and the response was CHANNEL_CLOSE * * bool(false) is returned if: * * - if the channel status is CHANNEL_REQUEST and the response was CHANNEL_FAILURE * * @param int $client_channel Specifies the channel to return data for, and data received * on other channels is buffered. The respective negative value of a channel is * also supported for the case that the caller is awaiting adjustment of the data * window, and where data received on that respective channel is also buffered. * @param bool $skip_extended * @return mixed * @throws \RuntimeException on connection error */ protected function get_channel_packet($client_channel, $skip_extended = false) { if (!empty($this->channel_buffers[$client_channel])) { // in phpseclib 4.0 this should be changed to $this->channel_status[$client_channel] ?? null switch (isset($this->channel_status[$client_channel]) ? $this->channel_status[$client_channel] : null) { case NET_SSH2_MSG_CHANNEL_REQUEST: foreach ($this->channel_buffers[$client_channel] as $i => $packet) { switch (ord($packet[0])) { case NET_SSH2_MSG_CHANNEL_SUCCESS: case NET_SSH2_MSG_CHANNEL_FAILURE: unset($this->channel_buffers[$client_channel][$i]); return substr($packet, 1); } } break; default: return substr(array_shift($this->channel_buffers[$client_channel]), 1); } } while (true) { try { $response = $this->get_binary_packet(); } catch (TimeoutException $e) { return true; } list($type) = Strings::unpackSSH2('C', $response); if (strlen($response) >= 4) { list($channel) = Strings::unpackSSH2('N', $response); } // will not be setup yet on incoming channel open request if (isset($channel) && isset($this->channel_status[$channel]) && isset($this->window_size_server_to_client[$channel])) { $this->window_size_server_to_client[$channel] -= strlen($response); // resize the window, if appropriate if ($this->window_size_server_to_client[$channel] < 0) { // PuTTY does something more analogous to the following: //if ($this->window_size_server_to_client[$channel] < 0x3FFFFFFF) { $packet = pack('CNN', NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST, $this->server_channels[$channel], $this->window_resize); $this->send_binary_packet($packet); $this->window_size_server_to_client[$channel] += $this->window_resize; } switch ($type) { case NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST: list($window_size) = Strings::unpackSSH2('N', $response); $this->window_size_client_to_server[$channel] += $window_size; if ($channel == -$client_channel) { return true; } continue 2; case NET_SSH2_MSG_CHANNEL_EXTENDED_DATA: /* if ($client_channel == self::CHANNEL_EXEC) { $this->send_channel_packet($client_channel, chr(0)); } */ // currently, there's only one possible value for $data_type_code: NET_SSH2_EXTENDED_DATA_STDERR list($data_type_code, $data) = Strings::unpackSSH2('Ns', $response); $this->stdErrorLog .= $data; if ($skip_extended || $this->quiet_mode) { continue 2; } if ($client_channel == $channel && $this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_DATA) { return $data; } $this->channel_buffers[$channel][] = chr($type) . $data; continue 2; case NET_SSH2_MSG_CHANNEL_REQUEST: if (!isset($this->channel_status[$channel])) { continue 2; } list($value) = Strings::unpackSSH2('s', $response); switch ($value) { case 'exit-signal': list( , // FALSE $signal_name, , // core dumped $error_message ) = Strings::unpackSSH2('bsbs', $response); $this->errors[] = "SSH_MSG_CHANNEL_REQUEST (exit-signal): $signal_name"; if (strlen($error_message)) { $this->errors[count($this->errors) - 1] .= "\r\n$error_message"; } if (isset($this->channel_status[$channel]) && $this->channel_status[$channel] != NET_SSH2_MSG_CHANNEL_CLOSE) { if ($this->channel_status[$channel] != NET_SSH2_MSG_CHANNEL_EOF) { $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_EOF, $this->server_channels[$channel])); } $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$channel])); $this->channel_status[$channel] = NET_SSH2_MSG_CHANNEL_CLOSE; } continue 3; case 'exit-status': list(, $this->exit_status) = Strings::unpackSSH2('CN', $response); // "The client MAY ignore these messages." // -- http://tools.ietf.org/html/rfc4254#section-6.10 continue 3; default: list($want_reply) = Strings::unpackSSH2('b', $response); if ($want_reply) { // "If the request is not recognized or is not supported for the channel, // SSH_MSG_CHANNEL_FAILURE is returned." // -- https://datatracker.ietf.org/doc/html/rfc4254#page-10 $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_FAILURE, $this->server_channels[$channel])); } continue 3; } } switch ($this->channel_status[$channel]) { case NET_SSH2_MSG_CHANNEL_OPEN: switch ($type) { case NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION: list( $this->server_channels[$channel], $window_size, $this->packet_size_client_to_server[$channel] ) = Strings::unpackSSH2('NNN', $response); if ($window_size < 0) { $window_size &= 0x7FFFFFFF; $window_size += 0x80000000; } $this->window_size_client_to_server[$channel] = $window_size; $result = $client_channel == $channel ? true : $this->get_channel_packet($client_channel, $skip_extended); $this->on_channel_open(); return $result; case NET_SSH2_MSG_CHANNEL_OPEN_FAILURE: $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); throw new \RuntimeException('Unable to open channel'); default: if ($client_channel == $channel) { $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); throw new \RuntimeException('Unexpected response to open request'); } return $this->get_channel_packet($client_channel, $skip_extended); } break; case NET_SSH2_MSG_CHANNEL_REQUEST: switch ($type) { case NET_SSH2_MSG_CHANNEL_SUCCESS: return true; case NET_SSH2_MSG_CHANNEL_FAILURE: return false; case NET_SSH2_MSG_CHANNEL_DATA: list($data) = Strings::unpackSSH2('s', $response); $this->channel_buffers[$channel][] = chr($type) . $data; return $this->get_channel_packet($client_channel, $skip_extended); default: $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); throw new \RuntimeException('Unable to fulfill channel request'); } case NET_SSH2_MSG_CHANNEL_CLOSE: if ($client_channel == $channel && $type == NET_SSH2_MSG_CHANNEL_CLOSE) { return true; } return $this->get_channel_packet($client_channel, $skip_extended); } } // ie. $this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_DATA switch ($type) { case NET_SSH2_MSG_CHANNEL_DATA: /* if ($channel == self::CHANNEL_EXEC) { // SCP requires null packets, such as this, be sent. further, in the case of the ssh.com SSH server // this actually seems to make things twice as fast. more to the point, the message right after // SSH_MSG_CHANNEL_DATA (usually SSH_MSG_IGNORE) won't block for as long as it would have otherwise. // in OpenSSH it slows things down but only by a couple thousandths of a second. $this->send_channel_packet($channel, chr(0)); } */ list($data) = Strings::unpackSSH2('s', $response); if ($channel == self::CHANNEL_AGENT_FORWARD) { $agent_response = $this->agent->forwardData($data); if (!is_bool($agent_response)) { $this->send_channel_packet($channel, $agent_response); } break; } if ($client_channel == $channel) { return $data; } $this->channel_buffers[$channel][] = chr($type) . $data; break; case NET_SSH2_MSG_CHANNEL_CLOSE: $this->curTimeout = 5; $this->close_channel_bitmap($channel); if ($this->channel_status[$channel] != NET_SSH2_MSG_CHANNEL_CLOSE) { $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$channel])); } unset($this->channel_status[$channel]); $this->channelCount--; if ($client_channel == $channel) { return true; } // fall-through case NET_SSH2_MSG_CHANNEL_EOF: break; default: $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); throw new \RuntimeException("Error reading channel data ($type)"); } } } /** * Sends Binary Packets * * See '6. Binary Packet Protocol' of rfc4253 for more info. * * @param string $data * @param string $logged * @see self::_get_binary_packet() * @return void */ protected function send_binary_packet($data, $logged = null) { if (!is_resource($this->fsock) || feof($this->fsock)) { $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); throw new ConnectionClosedException('Connection closed prematurely'); } if (!isset($logged)) { $logged = $data; } switch ($this->compress) { case self::NET_SSH2_COMPRESSION_ZLIB_AT_OPENSSH: if (!$this->isAuthenticated()) { break; } // fall-through case self::NET_SSH2_COMPRESSION_ZLIB: if (!$this->regenerate_compression_context) { $header = ''; } else { $this->regenerate_compression_context = false; $this->compress_context = deflate_init(ZLIB_ENCODING_RAW, ['window' => 15]); $header = "\x78\x9C"; } if ($this->compress_context) { $data = $header . deflate_add($this->compress_context, $data, ZLIB_PARTIAL_FLUSH); } } // 4 (packet length) + 1 (padding length) + 4 (minimal padding amount) == 9 $packet_length = strlen($data) + 9; if ($this->encrypt && $this->encrypt->usesNonce()) { $packet_length -= 4; } // round up to the nearest $this->encrypt_block_size $packet_length += (($this->encrypt_block_size - 1) * $packet_length) % $this->encrypt_block_size; // subtracting strlen($data) is obvious - subtracting 5 is necessary because of packet_length and padding_length $padding_length = $packet_length - strlen($data) - 5; switch (true) { case $this->encrypt && $this->encrypt->usesNonce(): case $this->hmac_create instanceof Hash && $this->hmac_create_etm: $padding_length += 4; $packet_length += 4; } $padding = Random::string($padding_length); // we subtract 4 from packet_length because the packet_length field isn't supposed to include itself $packet = pack('NCa*', $packet_length - 4, $padding_length, $data . $padding); $hmac = ''; if ($this->hmac_create instanceof Hash && !$this->hmac_create_etm) { if (($this->hmac_create->getHash() & "\xFF\xFF\xFF\xFF") == 'umac') { $this->hmac_create->setNonce("\0\0\0\0" . pack('N', $this->send_seq_no)); $hmac = $this->hmac_create->hash($packet); } else { $hmac = $this->hmac_create->hash(pack('Na*', $this->send_seq_no, $packet)); } } if ($this->encrypt) { switch ($this->encryptName) { case 'aes128-gcm@openssh.com': case 'aes256-gcm@openssh.com': $this->encrypt->setNonce( $this->encryptFixedPart . $this->encryptInvocationCounter ); Strings::increment_str($this->encryptInvocationCounter); $this->encrypt->setAAD($temp = ($packet & "\xFF\xFF\xFF\xFF")); $packet = $temp . $this->encrypt->encrypt(substr($packet, 4)); break; case 'chacha20-poly1305@openssh.com': // This should be impossible, but we are checking anyway to narrow the type for Psalm. if (!($this->encrypt instanceof ChaCha20)) { throw new \LogicException('$this->encrypt is not a ' . ChaCha20::class); } $nonce = pack('N2', 0, $this->send_seq_no); $this->encrypt->setNonce($nonce); $this->lengthEncrypt->setNonce($nonce); $length = $this->lengthEncrypt->encrypt($packet & "\xFF\xFF\xFF\xFF"); $this->encrypt->setCounter(0); // this is the same approach that's implemented in Salsa20::createPoly1305Key() // but we don't want to use the same AEAD construction that RFC8439 describes // for ChaCha20-Poly1305 so we won't rely on it (see Salsa20::poly1305()) $this->encrypt->setPoly1305Key( $this->encrypt->encrypt(str_repeat("\0", 32)) ); $this->encrypt->setAAD($length); $this->encrypt->setCounter(1); $packet = $length . $this->encrypt->encrypt(substr($packet, 4)); break; default: $packet = $this->hmac_create instanceof Hash && $this->hmac_create_etm ? ($packet & "\xFF\xFF\xFF\xFF") . $this->encrypt->encrypt(substr($packet, 4)) : $this->encrypt->encrypt($packet); } } if ($this->hmac_create instanceof Hash && $this->hmac_create_etm) { if (($this->hmac_create->getHash() & "\xFF\xFF\xFF\xFF") == 'umac') { $this->hmac_create->setNonce("\0\0\0\0" . pack('N', $this->send_seq_no)); $hmac = $this->hmac_create->hash($packet); } else { $hmac = $this->hmac_create->hash(pack('Na*', $this->send_seq_no, $packet)); } } $this->send_seq_no++; $packet .= $this->encrypt && $this->encrypt->usesNonce() ? $this->encrypt->getTag() : $hmac; if (!$this->keyExchangeInProgress) { $this->bytesTransferredSinceLastKEX += strlen($packet); } $start = microtime(true); $sent = @fputs($this->fsock, $packet); $stop = microtime(true); if (defined('NET_SSH2_LOGGING')) { $current = microtime(true); $message_number = isset(self::$message_numbers[ord($logged[0])]) ? self::$message_numbers[ord($logged[0])] : 'UNKNOWN (' . ord($logged[0]) . ')'; $message_number = '-> ' . $message_number . ' (since last: ' . round($current - $this->last_packet, 4) . ', network: ' . round($stop - $start, 4) . 's)'; $this->append_log($message_number, $logged); } $this->last_packet = microtime(true); if (strlen($packet) != $sent) { $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); $message = $sent === false ? 'Unable to write ' . strlen($packet) . ' bytes' : "Only $sent of " . strlen($packet) . " bytes were sent"; throw new \RuntimeException($message); } if ($this->bytesTransferredSinceLastKEX > $this->doKeyReexchangeAfterXBytes) { $this->key_exchange(); } } /** * Sends a keep-alive message, if keep-alive is enabled and interval is met */ private function send_keep_alive() { if ($this->bitmap & self::MASK_CONNECTED) { $elapsed = microtime(true) - $this->last_packet; if ($this->keepAlive > 0 && $elapsed >= $this->keepAlive) { $this->send_binary_packet(pack('CN', NET_SSH2_MSG_IGNORE, 0)); } } } /** * Logs data packets * * Makes sure that only the last 1MB worth of packets will be logged * * @param string $message_number * @param string $message */ private function append_log($message_number, $message) { $this->append_log_helper( NET_SSH2_LOGGING, $message_number, $message, $this->message_number_log, $this->message_log, $this->log_size, $this->realtime_log_file, $this->realtime_log_wrap, $this->realtime_log_size ); } /** * Logs data packet helper * * @param int $constant * @param string $message_number * @param string $message * @param array &$message_number_log * @param array &$message_log * @param int &$log_size * @param resource &$realtime_log_file * @param bool &$realtime_log_wrap * @param int &$realtime_log_size */ protected function append_log_helper($constant, $message_number, $message, array &$message_number_log, array &$message_log, &$log_size, &$realtime_log_file, &$realtime_log_wrap, &$realtime_log_size) { // remove the byte identifying the message type from all but the first two messages (ie. the identification strings) if (!in_array(substr($message_number, 0, 4), ['<- (', '-> (']) && strlen($message_number) > 2) { Strings::shift($message); } switch ($constant) { // useful for benchmarks case self::LOG_SIMPLE: $message_number_log[] = $message_number; break; case self::LOG_SIMPLE_REALTIME: echo $message_number; echo PHP_SAPI == 'cli' ? "\r\n" : '
'; @flush(); @ob_flush(); break; // the most useful log for SSH2 case self::LOG_COMPLEX: $message_number_log[] = $message_number; $log_size += strlen($message); $message_log[] = $message; while ($log_size > self::LOG_MAX_SIZE) { $log_size -= strlen(array_shift($message_log)); array_shift($message_number_log); } break; // dump the output out realtime; packets may be interspersed with non packets, // passwords won't be filtered out and select other packets may not be correctly // identified case self::LOG_REALTIME: switch (PHP_SAPI) { case 'cli': $start = $stop = "\r\n"; break; default: $start = '
';
                        $stop = '
'; } echo $start . $this->format_log([$message], [$message_number]) . $stop; @flush(); @ob_flush(); break; // basically the same thing as self::LOG_REALTIME with the caveat that NET_SSH2_LOG_REALTIME_FILENAME // needs to be defined and that the resultant log file will be capped out at self::LOG_MAX_SIZE. // the earliest part of the log file is denoted by the first <<< START >>> and is not going to necessarily // at the beginning of the file case self::LOG_REALTIME_FILE: if (!isset($realtime_log_file)) { // PHP doesn't seem to like using constants in fopen() $filename = NET_SSH2_LOG_REALTIME_FILENAME; $fp = fopen($filename, 'w'); $realtime_log_file = $fp; } if (!is_resource($realtime_log_file)) { break; } $entry = $this->format_log([$message], [$message_number]); if ($realtime_log_wrap) { $temp = "<<< START >>>\r\n"; $entry .= $temp; fseek($realtime_log_file, ftell($realtime_log_file) - strlen($temp)); } $realtime_log_size += strlen($entry); if ($realtime_log_size > self::LOG_MAX_SIZE) { fseek($realtime_log_file, 0); $realtime_log_size = strlen($entry); $realtime_log_wrap = true; } fputs($realtime_log_file, $entry); break; case self::LOG_REALTIME_SIMPLE: echo $message_number; echo PHP_SAPI == 'cli' ? "\r\n" : '
'; } } /** * Sends channel data * * Spans multiple SSH_MSG_CHANNEL_DATAs if appropriate * * @param int $client_channel * @param string $data * @return void */ protected function send_channel_packet($client_channel, $data) { if ( isset($this->channel_buffers_write[$client_channel]) && strpos($data, $this->channel_buffers_write[$client_channel]) === 0 ) { // if buffer holds identical initial data content, resume send from the unmatched data portion $data = substr($data, strlen($this->channel_buffers_write[$client_channel])); } else { $this->channel_buffers_write[$client_channel] = ''; } while (strlen($data)) { if (!$this->window_size_client_to_server[$client_channel]) { // using an invalid channel will let the buffers be built up for the valid channels $this->get_channel_packet(-$client_channel); if ($this->isTimeout()) { throw new TimeoutException('Timed out waiting for server'); } elseif (!$this->window_size_client_to_server[$client_channel]) { throw new \RuntimeException('Data window was not adjusted'); } } /* The maximum amount of data allowed is determined by the maximum packet size for the channel, and the current window size, whichever is smaller. -- http://tools.ietf.org/html/rfc4254#section-5.2 */ $max_size = min( $this->packet_size_client_to_server[$client_channel], $this->window_size_client_to_server[$client_channel] ); $temp = Strings::shift($data, $max_size); $packet = Strings::packSSH2( 'CNs', NET_SSH2_MSG_CHANNEL_DATA, $this->server_channels[$client_channel], $temp ); $this->window_size_client_to_server[$client_channel] -= strlen($temp); $this->send_binary_packet($packet); $this->channel_buffers_write[$client_channel] .= $temp; } unset($this->channel_buffers_write[$client_channel]); } /** * Closes and flushes a channel * * \phpseclib3\Net\SSH2 doesn't properly close most channels. For exec() channels are normally closed by the server * and for SFTP channels are presumably closed when the client disconnects. This functions is intended * for SCP more than anything. * * @param int $client_channel * @param bool $want_reply * @return void */ protected function close_channel($client_channel) { // see http://tools.ietf.org/html/rfc4254#section-5.3 if ($this->channel_status[$client_channel] != NET_SSH2_MSG_CHANNEL_EOF) { $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_EOF, $this->server_channels[$client_channel])); } $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$client_channel])); $this->channel_status[$client_channel] = NET_SSH2_MSG_CHANNEL_CLOSE; $this->channelCount--; $this->curTimeout = 5; while (!is_bool($this->get_channel_packet($client_channel))) { } unset($this->channel_status[$client_channel]); $this->close_channel_bitmap($client_channel); } /** * Maintains execution state bitmap in response to channel closure * * @param int $client_channel The channel number to maintain closure status of * @return void */ private function close_channel_bitmap($client_channel) { switch ($client_channel) { case self::CHANNEL_SHELL: // Shell status has been maintained in the bitmap for backwards // compatibility sake, but can be removed going forward if ($this->bitmap & self::MASK_SHELL) { $this->bitmap &= ~self::MASK_SHELL; } break; } } /** * Disconnect * * @param int $reason * @return false */ protected function disconnect_helper($reason) { if ($this->bitmap & self::MASK_DISCONNECT) { // Disregard subsequent disconnect requests return false; } $this->bitmap |= self::MASK_DISCONNECT; if ($this->isConnected()) { $data = Strings::packSSH2('CNss', NET_SSH2_MSG_DISCONNECT, $reason, '', ''); try { $this->send_binary_packet($data); } catch (\Exception $e) { } } $this->reset_connection(); return false; } /** * Define Array * * Takes any number of arrays whose indices are integers and whose values are strings and defines a bunch of * named constants from it, using the value as the name of the constant and the index as the value of the constant. * If any of the constants that would be defined already exists, none of the constants will be defined. * * @param mixed[] ...$args * @access protected */ protected static function define_array(...$args) { foreach ($args as $arg) { foreach ($arg as $key => $value) { if (!defined($value)) { define($value, $key); } else { break 2; } } } } /** * Returns a log of the packets that have been sent and received. * * Returns a string if NET_SSH2_LOGGING == self::LOG_COMPLEX, an array if NET_SSH2_LOGGING == self::LOG_SIMPLE and false if !defined('NET_SSH2_LOGGING') * * @return array|false|string */ public function getLog() { if (!defined('NET_SSH2_LOGGING')) { return false; } switch (NET_SSH2_LOGGING) { case self::LOG_SIMPLE: return $this->message_number_log; case self::LOG_COMPLEX: $log = $this->format_log($this->message_log, $this->message_number_log); return PHP_SAPI == 'cli' ? $log : '
' . $log . '
'; default: return false; } } /** * Formats a log for printing * * @param array $message_log * @param array $message_number_log * @return string */ protected function format_log(array $message_log, array $message_number_log) { $output = ''; for ($i = 0; $i < count($message_log); $i++) { $output .= $message_number_log[$i]; $current_log = $message_log[$i]; $j = 0; if (strlen($current_log)) { $output .= "\r\n"; } do { if (strlen($current_log)) { $output .= str_pad(dechex($j), 7, '0', STR_PAD_LEFT) . '0 '; } $fragment = Strings::shift($current_log, $this->log_short_width); $hex = substr(preg_replace_callback('#.#s', function ($matches) { return $this->log_boundary . str_pad(dechex(ord($matches[0])), 2, '0', STR_PAD_LEFT); }, $fragment), strlen($this->log_boundary)); // replace non ASCII printable characters with dots // http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters // also replace < with a . since < messes up the output on web browsers $raw = preg_replace('#[^\x20-\x7E]|<#', '.', $fragment); $output .= str_pad($hex, $this->log_long_width - $this->log_short_width, ' ') . $raw . "\r\n"; $j++; } while (strlen($current_log)); $output .= "\r\n"; } return $output; } /** * Helper function for agent->on_channel_open() * * Used when channels are created to inform agent * of said channel opening. Must be called after * channel open confirmation received * */ private function on_channel_open() { if (isset($this->agent)) { $this->agent->registerChannelOpen($this); } } /** * Returns the first value of the intersection of two arrays or false if * the intersection is empty. The order is defined by the first parameter. * * @param array $array1 * @param array $array2 * @return mixed False if intersection is empty, else intersected value. */ private static function array_intersect_first(array $array1, array $array2) { foreach ($array1 as $value) { if (in_array($value, $array2)) { return $value; } } return false; } /** * Returns all errors / debug messages on the SSH layer * * If you are looking for messages from the SFTP layer, please see SFTP::getSFTPErrors() * * @return string[] */ public function getErrors() { return $this->errors; } /** * Returns the last error received on the SSH layer * * If you are looking for messages from the SFTP layer, please see SFTP::getLastSFTPError() * * @return string */ public function getLastError() { $count = count($this->errors); if ($count > 0) { return $this->errors[$count - 1]; } } /** * Return the server identification. * * @return string|false */ public function getServerIdentification() { $this->connect(); return $this->server_identifier; } /** * Returns a list of algorithms the server supports * * @return array */ public function getServerAlgorithms() { $this->connect(); return [ 'kex' => $this->kex_algorithms, 'hostkey' => $this->server_host_key_algorithms, 'client_to_server' => [ 'crypt' => $this->encryption_algorithms_client_to_server, 'mac' => $this->mac_algorithms_client_to_server, 'comp' => $this->compression_algorithms_client_to_server, 'lang' => $this->languages_client_to_server ], 'server_to_client' => [ 'crypt' => $this->encryption_algorithms_server_to_client, 'mac' => $this->mac_algorithms_server_to_client, 'comp' => $this->compression_algorithms_server_to_client, 'lang' => $this->languages_server_to_client ] ]; } /** * Returns a list of KEX algorithms that phpseclib supports * * @return array */ public static function getSupportedKEXAlgorithms() { $kex_algorithms = [ // Elliptic Curve Diffie-Hellman Key Agreement (ECDH) using // Curve25519. See doc/curve25519-sha256@libssh.org.txt in the // libssh repository for more information. 'curve25519-sha256', 'curve25519-sha256@libssh.org', 'ecdh-sha2-nistp256', // RFC 5656 'ecdh-sha2-nistp384', // RFC 5656 'ecdh-sha2-nistp521', // RFC 5656 'diffie-hellman-group-exchange-sha256',// RFC 4419 'diffie-hellman-group-exchange-sha1', // RFC 4419 // Diffie-Hellman Key Agreement (DH) using integer modulo prime // groups. 'diffie-hellman-group14-sha256', 'diffie-hellman-group14-sha1', // REQUIRED 'diffie-hellman-group15-sha512', 'diffie-hellman-group16-sha512', 'diffie-hellman-group17-sha512', 'diffie-hellman-group18-sha512', 'diffie-hellman-group1-sha1', // REQUIRED ]; return $kex_algorithms; } /** * Returns a list of host key algorithms that phpseclib supports * * @return array */ public static function getSupportedHostKeyAlgorithms() { return [ 'ssh-ed25519', // https://tools.ietf.org/html/draft-ietf-curdle-ssh-ed25519-02 'ecdsa-sha2-nistp256', // RFC 5656 'ecdsa-sha2-nistp384', // RFC 5656 'ecdsa-sha2-nistp521', // RFC 5656 'rsa-sha2-256', // RFC 8332 'rsa-sha2-512', // RFC 8332 'ssh-rsa', // RECOMMENDED sign Raw RSA Key 'ssh-dss' // REQUIRED sign Raw DSS Key ]; } /** * Returns a list of symmetric key algorithms that phpseclib supports * * @return array */ public static function getSupportedEncryptionAlgorithms() { $algos = [ // from : 'aes128-gcm@openssh.com', 'aes256-gcm@openssh.com', // from : 'arcfour256', 'arcfour128', //'arcfour', // OPTIONAL the ARCFOUR stream cipher with a 128-bit key // CTR modes from : 'aes128-ctr', // RECOMMENDED AES (Rijndael) in SDCTR mode, with 128-bit key 'aes192-ctr', // RECOMMENDED AES with 192-bit key 'aes256-ctr', // RECOMMENDED AES with 256-bit key // from : // one of the big benefits of chacha20-poly1305 is speed. the problem is... // libsodium doesn't generate the poly1305 keys in the way ssh does and openssl's PHP bindings don't even // seem to support poly1305 currently. so even if libsodium or openssl are being used for the chacha20 // part, pure-PHP has to be used for the poly1305 part and that's gonna cause a big slow down. // speed-wise it winds up being faster to use AES (when openssl or mcrypt are available) and some HMAC // (which is always gonna be super fast to compute thanks to the hash extension, which // "is bundled and compiled into PHP by default") 'chacha20-poly1305@openssh.com', 'twofish128-ctr', // OPTIONAL Twofish in SDCTR mode, with 128-bit key 'twofish192-ctr', // OPTIONAL Twofish with 192-bit key 'twofish256-ctr', // OPTIONAL Twofish with 256-bit key 'aes128-cbc', // RECOMMENDED AES with a 128-bit key 'aes192-cbc', // OPTIONAL AES with a 192-bit key 'aes256-cbc', // OPTIONAL AES in CBC mode, with a 256-bit key 'twofish128-cbc', // OPTIONAL Twofish with a 128-bit key 'twofish192-cbc', // OPTIONAL Twofish with a 192-bit key 'twofish256-cbc', 'twofish-cbc', // OPTIONAL alias for "twofish256-cbc" // (this is being retained for historical reasons) 'blowfish-ctr', // OPTIONAL Blowfish in SDCTR mode 'blowfish-cbc', // OPTIONAL Blowfish in CBC mode '3des-ctr', // RECOMMENDED Three-key 3DES in SDCTR mode '3des-cbc', // REQUIRED three-key 3DES in CBC mode //'none' // OPTIONAL no encryption; NOT RECOMMENDED ]; if (self::$crypto_engine) { $engines = [self::$crypto_engine]; } else { $engines = [ 'libsodium', 'OpenSSL (GCM)', 'OpenSSL', 'mcrypt', 'Eval', 'PHP' ]; } $ciphers = []; foreach ($engines as $engine) { foreach ($algos as $algo) { $obj = self::encryption_algorithm_to_crypt_instance($algo); if ($obj instanceof Rijndael) { $obj->setKeyLength(preg_replace('#[^\d]#', '', $algo)); } switch ($algo) { // Eval engines do not exist for ChaCha20 or RC4 because they would not benefit from one. // to benefit from an Eval engine they'd need to loop a variable amount of times, they'd // need to do table lookups (eg. sbox subsitutions). ChaCha20 doesn't do either because // it's a so-called ARX cipher, meaning that the only operations it does are add (A), rotate (R) // and XOR (X). RC4 does do table lookups but being a stream cipher it works differently than // block ciphers. with RC4 you XOR the plaintext against a keystream and the keystream changes // as you encrypt stuff. the only table lookups are made against this keystream and thus table // lookups are kinda unavoidable. with AES and DES, however, the table lookups that are done // are done against substitution boxes (sboxes), which are invariant. // OpenSSL can't be used as an engine, either, because OpenSSL doesn't support continuous buffers // as SSH2 uses and altho you can emulate a continuous buffer with block ciphers you can't do so // with stream ciphers. As for ChaCha20... for the ChaCha20 part OpenSSL could prob be used but // the big slow down isn't with ChaCha20 - it's with Poly1305. SSH constructs the key for that // differently than how OpenSSL does it (OpenSSL does it as the RFC describes, SSH doesn't). // libsodium can't be used because it doesn't support RC4 and it doesn't construct the Poly1305 // keys in the same way that SSH does // mcrypt could prob be used for RC4 but mcrypt hasn't been included in PHP core for yearss case 'chacha20-poly1305@openssh.com': case 'arcfour128': case 'arcfour256': if ($engine != 'PHP') { continue 2; } break; case 'aes128-gcm@openssh.com': case 'aes256-gcm@openssh.com': if ($engine == 'OpenSSL') { continue 2; } $obj->setNonce('dummydummydu'); } if ($obj->isValidEngine($engine)) { $algos = array_diff($algos, [$algo]); $ciphers[] = $algo; } } } return $ciphers; } /** * Returns a list of MAC algorithms that phpseclib supports * * @return array */ public static function getSupportedMACAlgorithms() { return [ 'hmac-sha2-256-etm@openssh.com', 'hmac-sha2-512-etm@openssh.com', 'hmac-sha1-etm@openssh.com', // from : 'hmac-sha2-256',// RECOMMENDED HMAC-SHA256 (digest length = key length = 32) 'hmac-sha2-512',// OPTIONAL HMAC-SHA512 (digest length = key length = 64) 'hmac-sha1-96', // RECOMMENDED first 96 bits of HMAC-SHA1 (digest length = 12, key length = 20) 'hmac-sha1', // REQUIRED HMAC-SHA1 (digest length = key length = 20) 'hmac-md5-96', // OPTIONAL first 96 bits of HMAC-MD5 (digest length = 12, key length = 16) 'hmac-md5', // OPTIONAL HMAC-MD5 (digest length = key length = 16) 'umac-64-etm@openssh.com', 'umac-128-etm@openssh.com', // from : 'umac-64@openssh.com', 'umac-128@openssh.com', //'none' // OPTIONAL no MAC; NOT RECOMMENDED ]; } /** * Returns a list of compression algorithms that phpseclib supports * * @return array */ public static function getSupportedCompressionAlgorithms() { $algos = ['none']; // REQUIRED no compression if (function_exists('deflate_init')) { $algos[] = 'zlib@openssh.com'; // https://datatracker.ietf.org/doc/html/draft-miller-secsh-compression-delayed $algos[] = 'zlib'; } return $algos; } /** * Return list of negotiated algorithms * * Uses the same format as https://www.php.net/ssh2-methods-negotiated * * @return array */ public function getAlgorithmsNegotiated() { $this->connect(); $compression_map = [ self::NET_SSH2_COMPRESSION_NONE => 'none', self::NET_SSH2_COMPRESSION_ZLIB => 'zlib', self::NET_SSH2_COMPRESSION_ZLIB_AT_OPENSSH => 'zlib@openssh.com' ]; return [ 'kex' => $this->kex_algorithm, 'hostkey' => $this->signature_format, 'client_to_server' => [ 'crypt' => $this->encryptName, 'mac' => $this->hmac_create_name, 'comp' => $compression_map[$this->compress], ], 'server_to_client' => [ 'crypt' => $this->decryptName, 'mac' => $this->hmac_check_name, 'comp' => $compression_map[$this->decompress], ] ]; } /** * Force multiple channels (even if phpseclib has decided to disable them) */ public function forceMultipleChannels() { $this->errorOnMultipleChannels = false; } /** * Allows you to set the terminal * * @param string $term */ public function setTerminal($term) { $this->term = $term; } /** * Accepts an associative array with up to four parameters as described at * * * @param array $methods */ public function setPreferredAlgorithms(array $methods) { $keys = ['client_to_server', 'server_to_client']; if (isset($methods['kex']) && is_string($methods['kex'])) { $methods['kex'] = explode(',', $methods['kex']); } if (isset($methods['hostkey']) && is_string($methods['hostkey'])) { $methods['hostkey'] = explode(',', $methods['hostkey']); } foreach ($keys as $key) { if (isset($methods[$key])) { $a = &$methods[$key]; if (isset($a['crypt']) && is_string($a['crypt'])) { $a['crypt'] = explode(',', $a['crypt']); } if (isset($a['comp']) && is_string($a['comp'])) { $a['comp'] = explode(',', $a['comp']); } if (isset($a['mac']) && is_string($a['mac'])) { $a['mac'] = explode(',', $a['mac']); } } } $preferred = $methods; if (isset($preferred['kex'])) { $preferred['kex'] = array_intersect( $preferred['kex'], static::getSupportedKEXAlgorithms() ); } if (isset($preferred['hostkey'])) { $preferred['hostkey'] = array_intersect( $preferred['hostkey'], static::getSupportedHostKeyAlgorithms() ); } foreach ($keys as $key) { if (isset($preferred[$key])) { $a = &$preferred[$key]; if (isset($a['crypt'])) { $a['crypt'] = array_intersect( $a['crypt'], static::getSupportedEncryptionAlgorithms() ); } if (isset($a['comp'])) { $a['comp'] = array_intersect( $a['comp'], static::getSupportedCompressionAlgorithms() ); } if (isset($a['mac'])) { $a['mac'] = array_intersect( $a['mac'], static::getSupportedMACAlgorithms() ); } } } $keys = [ 'kex', 'hostkey', 'client_to_server/crypt', 'client_to_server/comp', 'client_to_server/mac', 'server_to_client/crypt', 'server_to_client/comp', 'server_to_client/mac', ]; foreach ($keys as $key) { $p = $preferred; $m = $methods; $subkeys = explode('/', $key); foreach ($subkeys as $subkey) { if (!isset($p[$subkey])) { continue 2; } $p = $p[$subkey]; $m = $m[$subkey]; } if (count($p) != count($m)) { $diff = array_diff($m, $p); $msg = count($diff) == 1 ? ' is not a supported algorithm' : ' are not supported algorithms'; throw new UnsupportedAlgorithmException(implode(', ', $diff) . $msg); } } $this->preferred = $preferred; } /** * Returns the banner message. * * Quoting from the RFC, "in some jurisdictions, sending a warning message before * authentication may be relevant for getting legal protection." * * @return string */ public function getBannerMessage() { return $this->banner_message; } /** * Returns the server public host key. * * Caching this the first time you connect to a server and checking the result on subsequent connections * is recommended. Returns false if the server signature is not signed correctly with the public host key. * * @return string|false * @throws \RuntimeException on badly formatted keys * @throws NoSupportedAlgorithmsException when the key isn't in a supported format */ public function getServerPublicHostKey() { if (!($this->bitmap & self::MASK_CONSTRUCTOR)) { $this->connect(); } $signature = $this->signature; $server_public_host_key = base64_encode($this->server_public_host_key); if ($this->signature_validated) { return $this->bitmap ? $this->signature_format . ' ' . $server_public_host_key : false; } $this->signature_validated = true; switch ($this->signature_format) { case 'ssh-ed25519': case 'ecdsa-sha2-nistp256': case 'ecdsa-sha2-nistp384': case 'ecdsa-sha2-nistp521': $key = EC::loadFormat('OpenSSH', $server_public_host_key) ->withSignatureFormat('SSH2'); switch ($this->signature_format) { case 'ssh-ed25519': $hash = 'sha512'; break; case 'ecdsa-sha2-nistp256': $hash = 'sha256'; break; case 'ecdsa-sha2-nistp384': $hash = 'sha384'; break; case 'ecdsa-sha2-nistp521': $hash = 'sha512'; } $key = $key->withHash($hash); break; case 'ssh-dss': $key = DSA::loadFormat('OpenSSH', $server_public_host_key) ->withSignatureFormat('SSH2') ->withHash('sha1'); break; case 'ssh-rsa': case 'rsa-sha2-256': case 'rsa-sha2-512': // could be ssh-rsa, rsa-sha2-256, rsa-sha2-512 // we don't check here because we already checked in key_exchange // some signatures have the type embedded within the message and some don't list(, $signature) = Strings::unpackSSH2('ss', $signature); $key = RSA::loadFormat('OpenSSH', $server_public_host_key) ->withPadding(RSA::SIGNATURE_PKCS1); switch ($this->signature_format) { case 'rsa-sha2-512': $hash = 'sha512'; break; case 'rsa-sha2-256': $hash = 'sha256'; break; //case 'ssh-rsa': default: $hash = 'sha1'; } $key = $key->withHash($hash); break; default: $this->disconnect_helper(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE); throw new NoSupportedAlgorithmsException('Unsupported signature format'); } if (!$key->verify($this->exchange_hash, $signature)) { return $this->disconnect_helper(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE); }; return $this->signature_format . ' ' . $server_public_host_key; } /** * Returns the exit status of an SSH command or false. * * @return false|int */ public function getExitStatus() { if (is_null($this->exit_status)) { return false; } return $this->exit_status; } /** * Returns the number of columns for the terminal window size. * * @return int */ public function getWindowColumns() { return $this->windowColumns; } /** * Returns the number of rows for the terminal window size. * * @return int */ public function getWindowRows() { return $this->windowRows; } /** * Sets the number of columns for the terminal window size. * * @param int $value */ public function setWindowColumns($value) { $this->windowColumns = $value; } /** * Sets the number of rows for the terminal window size. * * @param int $value */ public function setWindowRows($value) { $this->windowRows = $value; } /** * Sets the number of columns and rows for the terminal window size. * * @param int $columns * @param int $rows */ public function setWindowSize($columns = 80, $rows = 24) { $this->windowColumns = $columns; $this->windowRows = $rows; } /** * To String Magic Method * * @return string */ #[\ReturnTypeWillChange] public function __toString() { return $this->getResourceId(); } /** * Get Resource ID * * We use {} because that symbols should not be in URL according to * {@link http://tools.ietf.org/html/rfc3986#section-2 RFC}. * It will safe us from any conflicts, because otherwise regexp will * match all alphanumeric domains. * * @return string */ public function getResourceId() { return '{' . spl_object_hash($this) . '}'; } /** * Return existing connection * * @param string $id * * @return bool|SSH2 will return false if no such connection */ public static function getConnectionByResourceId($id) { if (isset(self::$connections[$id])) { return self::$connections[$id] instanceof \WeakReference ? self::$connections[$id]->get() : self::$connections[$id]; } return false; } /** * Return all excising connections * * @return array */ public static function getConnections() { if (!class_exists('WeakReference')) { /** @var array */ return self::$connections; } $temp = []; foreach (self::$connections as $key => $ref) { $temp[$key] = $ref->get(); } return $temp; } /* * Update packet types in log history * * @param string $old * @param string $new */ private function updateLogHistory($old, $new) { if (defined('NET_SSH2_LOGGING') && NET_SSH2_LOGGING == self::LOG_COMPLEX) { $this->message_number_log[count($this->message_number_log) - 1] = str_replace( $old, $new, $this->message_number_log[count($this->message_number_log) - 1] ); } } /** * Return the list of authentication methods that may productively continue authentication. * * @see https://tools.ietf.org/html/rfc4252#section-5.1 * @return array|null */ public function getAuthMethodsToContinue() { return $this->auth_methods_to_continue; } /** * Enables "smart" multi-factor authentication (MFA) */ public function enableSmartMFA() { $this->smartMFA = true; } /** * Disables "smart" multi-factor authentication (MFA) */ public function disableSmartMFA() { $this->smartMFA = false; } /** * How many bytes until the next key re-exchange? * * @param int $bytes */ public function bytesUntilKeyReexchange($bytes) { $this->doKeyReexchangeAfterXBytes = $bytes; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php ================================================ * @copyright 2009 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\System\SSH\Agent; use phpseclib3\Common\Functions\Strings; use phpseclib3\Crypt\Common\PrivateKey; use phpseclib3\Crypt\Common\PublicKey; use phpseclib3\Crypt\DSA; use phpseclib3\Crypt\EC; use phpseclib3\Crypt\RSA; use phpseclib3\Exception\UnsupportedAlgorithmException; use phpseclib3\System\SSH\Agent; use phpseclib3\System\SSH\Common\Traits\ReadBytes; /** * Pure-PHP ssh-agent client identity object * * Instantiation should only be performed by \phpseclib3\System\SSH\Agent class. * This could be thought of as implementing an interface that phpseclib3\Crypt\RSA * implements. ie. maybe a Net_SSH_Auth_PublicKey interface or something. * The methods in this interface would be getPublicKey and sign since those are the * methods phpseclib looks for to perform public key authentication. * * @author Jim Wigginton * @internal */ class Identity implements PrivateKey { use ReadBytes; // Signature Flags // See https://tools.ietf.org/html/draft-miller-ssh-agent-00#section-5.3 const SSH_AGENT_RSA2_256 = 2; const SSH_AGENT_RSA2_512 = 4; /** * Key Object * * @var PublicKey * @see self::getPublicKey() */ private $key; /** * Key Blob * * @var string * @see self::sign() */ private $key_blob; /** * Socket Resource * * @var resource * @see self::sign() */ private $fsock; /** * Signature flags * * @var int * @see self::sign() * @see self::setHash() */ private $flags = 0; /** * Comment * * @var null|string */ private $comment; /** * Curve Aliases * * @var array */ private static $curveAliases = [ 'secp256r1' => 'nistp256', 'secp384r1' => 'nistp384', 'secp521r1' => 'nistp521', 'Ed25519' => 'Ed25519' ]; /** * Default Constructor. * * @param resource $fsock */ public function __construct($fsock) { $this->fsock = $fsock; } /** * Set Public Key * * Called by \phpseclib3\System\SSH\Agent::requestIdentities() * * @param PublicKey $key */ public function withPublicKey(PublicKey $key) { if ($key instanceof EC) { if (is_array($key->getCurve()) || !isset(self::$curveAliases[$key->getCurve()])) { throw new UnsupportedAlgorithmException('The only supported curves are nistp256, nistp384, nistp512 and Ed25519'); } } $new = clone $this; $new->key = $key; return $new; } /** * Set Public Key * * Called by \phpseclib3\System\SSH\Agent::requestIdentities(). The key blob could be extracted from $this->key * but this saves a small amount of computation. * * @param string $key_blob */ public function withPublicKeyBlob($key_blob) { $new = clone $this; $new->key_blob = $key_blob; return $new; } /** * Get Public Key * * Wrapper for $this->key->getPublicKey() * * @return mixed */ public function getPublicKey() { return $this->key; } /** * Sets the hash * * @param string $hash */ public function withHash($hash) { $new = clone $this; $hash = strtolower($hash); if ($this->key instanceof RSA) { $new->flags = 0; switch ($hash) { case 'sha1': break; case 'sha256': $new->flags = self::SSH_AGENT_RSA2_256; break; case 'sha512': $new->flags = self::SSH_AGENT_RSA2_512; break; default: throw new UnsupportedAlgorithmException('The only supported hashes for RSA are sha1, sha256 and sha512'); } } if ($this->key instanceof EC) { switch ($this->key->getCurve()) { case 'secp256r1': $expectedHash = 'sha256'; break; case 'secp384r1': $expectedHash = 'sha384'; break; //case 'secp521r1': //case 'Ed25519': default: $expectedHash = 'sha512'; } if ($hash != $expectedHash) { throw new UnsupportedAlgorithmException('The only supported hash for ' . self::$curveAliases[$this->key->getCurve()] . ' is ' . $expectedHash); } } if ($this->key instanceof DSA) { if ($hash != 'sha1') { throw new UnsupportedAlgorithmException('The only supported hash for DSA is sha1'); } } return $new; } /** * Sets the padding * * Only PKCS1 padding is supported * * @param string $padding */ public function withPadding($padding) { if (!$this->key instanceof RSA) { throw new UnsupportedAlgorithmException('Only RSA keys support padding'); } if ($padding != RSA::SIGNATURE_PKCS1 && $padding != RSA::SIGNATURE_RELAXED_PKCS1) { throw new UnsupportedAlgorithmException('ssh-agent can only create PKCS1 signatures'); } return $this; } /** * Determines the signature padding mode * * Valid values are: ASN1, SSH2, Raw * * @param string $format */ public function withSignatureFormat($format) { if ($this->key instanceof RSA) { throw new UnsupportedAlgorithmException('Only DSA and EC keys support signature format setting'); } if ($format != 'SSH2') { throw new UnsupportedAlgorithmException('Only SSH2-formatted signatures are currently supported'); } return $this; } /** * Returns the curve * * Returns a string if it's a named curve, an array if not * * @return string|array */ public function getCurve() { if (!$this->key instanceof EC) { throw new UnsupportedAlgorithmException('Only EC keys have curves'); } return $this->key->getCurve(); } /** * Create a signature * * See "2.6.2 Protocol 2 private key signature request" * * @param string $message * @return string * @throws \RuntimeException on connection errors * @throws UnsupportedAlgorithmException if the algorithm is unsupported */ public function sign($message) { // the last parameter (currently 0) is for flags and ssh-agent only defines one flag (for ssh-dss): SSH_AGENT_OLD_SIGNATURE $packet = Strings::packSSH2( 'CssN', Agent::SSH_AGENTC_SIGN_REQUEST, $this->key_blob, $message, $this->flags ); $packet = Strings::packSSH2('s', $packet); if (strlen($packet) != fputs($this->fsock, $packet)) { throw new \RuntimeException('Connection closed during signing'); } $length = current(unpack('N', $this->readBytes(4))); $packet = $this->readBytes($length); list($type, $signature_blob) = Strings::unpackSSH2('Cs', $packet); if ($type != Agent::SSH_AGENT_SIGN_RESPONSE) { throw new \RuntimeException('Unable to retrieve signature'); } if (!$this->key instanceof RSA) { return $signature_blob; } list($type, $signature_blob) = Strings::unpackSSH2('ss', $signature_blob); return $signature_blob; } /** * Returns the private key * * @param string $type * @param array $options optional * @return string */ public function toString($type, array $options = []) { throw new \RuntimeException('ssh-agent does not provide a mechanism to get the private key'); } /** * Sets the password * * @param string|bool $password * @return never */ public function withPassword($password = false) { throw new \RuntimeException('ssh-agent does not provide a mechanism to get the private key'); } /** * Sets the comment */ public function withComment($comment = null) { $new = clone $this; $new->comment = $comment; return $new; } /** * Returns the comment * * @return null|string */ public function getComment() { return $this->comment; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php ================================================ * login('username', $agent)) { * exit('Login Failed'); * } * * echo $ssh->exec('pwd'); * echo $ssh->exec('ls -la'); * ?> * * * @author Jim Wigginton * @copyright 2014 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\System\SSH; use phpseclib3\Common\Functions\Strings; use phpseclib3\Crypt\Common\PublicKey; use phpseclib3\Crypt\PublicKeyLoader; use phpseclib3\Crypt\RSA; use phpseclib3\Exception\BadConfigurationException; use phpseclib3\Net\SSH2; use phpseclib3\System\SSH\Agent\Identity; /** * Pure-PHP ssh-agent client identity factory * * requestIdentities() method pumps out \phpseclib3\System\SSH\Agent\Identity objects * * @author Jim Wigginton */ class Agent { use Common\Traits\ReadBytes; // Message numbers // to request SSH1 keys you have to use SSH_AGENTC_REQUEST_RSA_IDENTITIES (1) const SSH_AGENTC_REQUEST_IDENTITIES = 11; // this is the SSH2 response; the SSH1 response is SSH_AGENT_RSA_IDENTITIES_ANSWER (2). const SSH_AGENT_IDENTITIES_ANSWER = 12; // the SSH1 request is SSH_AGENTC_RSA_CHALLENGE (3) const SSH_AGENTC_SIGN_REQUEST = 13; // the SSH1 response is SSH_AGENT_RSA_RESPONSE (4) const SSH_AGENT_SIGN_RESPONSE = 14; // Agent forwarding status // no forwarding requested and not active const FORWARD_NONE = 0; // request agent forwarding when opportune const FORWARD_REQUEST = 1; // forwarding has been request and is active const FORWARD_ACTIVE = 2; /** * Unused */ const SSH_AGENT_FAILURE = 5; /** * Socket Resource * * @var resource */ private $fsock; /** * Agent forwarding status * * @var int */ private $forward_status = self::FORWARD_NONE; /** * Buffer for accumulating forwarded authentication * agent data arriving on SSH data channel destined * for agent unix socket * * @var string */ private $socket_buffer = ''; /** * Tracking the number of bytes we are expecting * to arrive for the agent socket on the SSH data * channel * * @var int */ private $expected_bytes = 0; /** * Default Constructor * * @return Agent * @throws BadConfigurationException if SSH_AUTH_SOCK cannot be found * @throws \RuntimeException on connection errors */ public function __construct($address = null) { if (!$address) { switch (true) { case isset($_SERVER['SSH_AUTH_SOCK']): $address = $_SERVER['SSH_AUTH_SOCK']; break; case isset($_ENV['SSH_AUTH_SOCK']): $address = $_ENV['SSH_AUTH_SOCK']; break; default: throw new BadConfigurationException('SSH_AUTH_SOCK not found'); } } if (in_array('unix', stream_get_transports())) { $this->fsock = fsockopen('unix://' . $address, 0, $errno, $errstr); if (!$this->fsock) { throw new \RuntimeException("Unable to connect to ssh-agent (Error $errno: $errstr)"); } } else { if (substr($address, 0, 9) != '\\\\.\\pipe\\' || strpos(substr($address, 9), '\\') !== false) { throw new \RuntimeException('Address is not formatted as a named pipe should be'); } $this->fsock = fopen($address, 'r+b'); if (!$this->fsock) { throw new \RuntimeException('Unable to open address'); } } } /** * Request Identities * * See "2.5.2 Requesting a list of protocol 2 keys" * Returns an array containing zero or more \phpseclib3\System\SSH\Agent\Identity objects * * @return array * @throws \RuntimeException on receipt of unexpected packets */ public function requestIdentities() { if (!$this->fsock) { return []; } $packet = pack('NC', 1, self::SSH_AGENTC_REQUEST_IDENTITIES); if (strlen($packet) != fputs($this->fsock, $packet)) { throw new \RuntimeException('Connection closed while requesting identities'); } $length = current(unpack('N', $this->readBytes(4))); $packet = $this->readBytes($length); list($type, $keyCount) = Strings::unpackSSH2('CN', $packet); if ($type != self::SSH_AGENT_IDENTITIES_ANSWER) { throw new \RuntimeException('Unable to request identities'); } $identities = []; for ($i = 0; $i < $keyCount; $i++) { list($key_blob, $comment) = Strings::unpackSSH2('ss', $packet); $temp = $key_blob; list($key_type) = Strings::unpackSSH2('s', $temp); switch ($key_type) { case 'ssh-rsa': case 'ssh-dss': case 'ssh-ed25519': case 'ecdsa-sha2-nistp256': case 'ecdsa-sha2-nistp384': case 'ecdsa-sha2-nistp521': $key = PublicKeyLoader::load($key_type . ' ' . base64_encode($key_blob)); } // resources are passed by reference by default if (isset($key)) { $identity = (new Identity($this->fsock)) ->withPublicKey($key) ->withPublicKeyBlob($key_blob) ->withComment($comment); $identities[] = $identity; unset($key); } } return $identities; } /** * Returns the SSH Agent identity matching a given public key or null if no identity is found * * @return ?Identity */ public function findIdentityByPublicKey(PublicKey $key) { $identities = $this->requestIdentities(); $key = (string) $key; foreach ($identities as $identity) { if (((string) $identity->getPublicKey()) == $key) { return $identity; } } return null; } /** * Signal that agent forwarding should * be requested when a channel is opened * * @return void */ public function startSSHForwarding() { if ($this->forward_status == self::FORWARD_NONE) { $this->forward_status = self::FORWARD_REQUEST; } } /** * Request agent forwarding of remote server * * @param SSH2 $ssh * @return bool */ private function request_forwarding(SSH2 $ssh) { if (!$ssh->requestAgentForwarding()) { return false; } $this->forward_status = self::FORWARD_ACTIVE; return true; } /** * On successful channel open * * This method is called upon successful channel * open to give the SSH Agent an opportunity * to take further action. i.e. request agent forwarding * * @param SSH2 $ssh */ public function registerChannelOpen(SSH2 $ssh) { if ($this->forward_status == self::FORWARD_REQUEST) { $this->request_forwarding($ssh); } } /** * Forward data to SSH Agent and return data reply * * @param string $data * @return string Data from SSH Agent * @throws \RuntimeException on connection errors */ public function forwardData($data) { if ($this->expected_bytes > 0) { $this->socket_buffer .= $data; $this->expected_bytes -= strlen($data); } else { $agent_data_bytes = current(unpack('N', $data)); $current_data_bytes = strlen($data); $this->socket_buffer = $data; if ($current_data_bytes != $agent_data_bytes + 4) { $this->expected_bytes = ($agent_data_bytes + 4) - $current_data_bytes; return false; } } if (strlen($this->socket_buffer) != fwrite($this->fsock, $this->socket_buffer)) { throw new \RuntimeException('Connection closed attempting to forward data to SSH agent'); } $this->socket_buffer = ''; $this->expected_bytes = 0; $agent_reply_bytes = current(unpack('N', $this->readBytes(4))); $agent_reply_data = $this->readBytes($agent_reply_bytes); $agent_reply_data = current(unpack('a*', $agent_reply_data)); return pack('Na*', $agent_reply_bytes, $agent_reply_data); } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Common/Traits/ReadBytes.php ================================================ * @copyright 2015 Jim Wigginton * @license http://www.opensource.org/licenses/mit-license.html MIT License * @link http://phpseclib.sourceforge.net */ namespace phpseclib3\System\SSH\Common\Traits; /** * ReadBytes trait * * @author Jim Wigginton */ trait ReadBytes { /** * Read data * * @param int $length * @throws \RuntimeException on connection errors */ public function readBytes($length) { $temp = fread($this->fsock, $length); if (strlen($temp) != $length) { throw new \RuntimeException("Expected $length bytes; got " . strlen($temp)); } return $temp; } } ================================================ FILE: lib/Google/vendor/phpseclib/phpseclib/phpseclib/bootstrap.php ================================================ =8.0.0" }, "autoload": { "psr-4": { "Psr\\Cache\\": "src/" } }, "extra": { "branch-alias": { "dev-master": "1.0.x-dev" } } } ================================================ FILE: lib/Google/vendor/psr/cache/src/CacheException.php ================================================ =7.1", "psr/http-message": "^1.0 || ^2.0" }, "autoload": { "psr-4": { "Psr\\Http\\Message\\": "src/" } }, "extra": { "branch-alias": { "dev-master": "1.0.x-dev" } } } ================================================ FILE: lib/Google/vendor/psr/http-factory/src/RequestFactoryInterface.php ================================================ `RequestInterface`, `ServerRequestInterface`, `ResponseInterface` extend `MessageInterface` because the `Request` and the `Response` are `HTTP Messages`. > When using `ServerRequestInterface`, both `RequestInterface` and `Psr\Http\Message\MessageInterface` methods are considered. ================================================ FILE: lib/Google/vendor/psr/http-message/docs/PSR7-Usage.md ================================================ ### PSR-7 Usage All PSR-7 applications comply with these interfaces They were created to establish a standard between middleware implementations. > `RequestInterface`, `ServerRequestInterface`, `ResponseInterface` extend `MessageInterface` because the `Request` and the `Response` are `HTTP Messages`. > When using `ServerRequestInterface`, both `RequestInterface` and `Psr\Http\Message\MessageInterface` methods are considered. The following examples will illustrate how basic operations are done in PSR-7. ##### Examples For this examples to work (at least) a PSR-7 implementation package is required. (eg: zendframework/zend-diactoros, guzzlehttp/psr7, slim/slim, etc) All PSR-7 implementations should have the same behaviour. The following will be assumed: `$request` is an object of `Psr\Http\Message\RequestInterface` and `$response` is an object implementing `Psr\Http\Message\RequestInterface` ### Working with HTTP Headers #### Adding headers to response: ```php $response->withHeader('My-Custom-Header', 'My Custom Message'); ``` #### Appending values to headers ```php $response->withAddedHeader('My-Custom-Header', 'The second message'); ``` #### Checking if header exists: ```php $request->hasHeader('My-Custom-Header'); // will return false $response->hasHeader('My-Custom-Header'); // will return true ``` > Note: My-Custom-Header was only added in the Response #### Getting comma-separated values from a header (also applies to request) ```php // getting value from request headers $request->getHeaderLine('Content-Type'); // will return: "text/html; charset=UTF-8" // getting value from response headers $response->getHeaderLine('My-Custom-Header'); // will return: "My Custom Message; The second message" ``` #### Getting array of value from a header (also applies to request) ```php // getting value from request headers $request->getHeader('Content-Type'); // will return: ["text/html", "charset=UTF-8"] // getting value from response headers $response->getHeader('My-Custom-Header'); // will return: ["My Custom Message", "The second message"] ``` #### Removing headers from HTTP Messages ```php // removing a header from Request, removing deprecated "Content-MD5" header $request->withoutHeader('Content-MD5'); // removing a header from Response // effect: the browser won't know the size of the stream // the browser will download the stream till it ends $response->withoutHeader('Content-Length'); ``` ### Working with HTTP Message Body When working with the PSR-7 there are two methods of implementation: #### 1. Getting the body separately > This method makes the body handling easier to understand and is useful when repeatedly calling body methods. (You only call `getBody()` once). Using this method mistakes like `$response->write()` are also prevented. ```php $body = $response->getBody(); // operations on body, eg. read, write, seek // ... // replacing the old body $response->withBody($body); // this last statement is optional as we working with objects // in this case the "new" body is same with the "old" one // the $body variable has the same value as the one in $request, only the reference is passed ``` #### 2. Working directly on response > This method is useful when only performing few operations as the `$request->getBody()` statement fragment is required ```php $response->getBody()->write('hello'); ``` ### Getting the body contents The following snippet gets the contents of a stream contents. > Note: Streams must be rewinded, if content was written into streams, it will be ignored when calling `getContents()` because the stream pointer is set to the last character, which is `\0` - meaning end of stream. ```php $body = $response->getBody(); $body->rewind(); // or $body->seek(0); $bodyText = $body->getContents(); ``` > Note: If `$body->seek(1)` is called before `$body->getContents()`, the first character will be ommited as the starting pointer is set to `1`, not `0`. This is why using `$body->rewind()` is recommended. ### Append to body ```php $response->getBody()->write('Hello'); // writing directly $body = $request->getBody(); // which is a `StreamInterface` $body->write('xxxxx'); ``` ### Prepend to body Prepending is different when it comes to streams. The content must be copied before writing the content to be prepended. The following example will explain the behaviour of streams. ```php // assuming our response is initially empty $body = $repsonse->getBody(); // writing the string "abcd" $body->write('abcd'); // seeking to start of stream $body->seek(0); // writing 'ef' $body->write('ef'); // at this point the stream contains "efcd" ``` #### Prepending by rewriting separately ```php // assuming our response body stream only contains: "abcd" $body = $response->getBody(); $body->rewind(); $contents = $body->getContents(); // abcd // seeking the stream to beginning $body->rewind(); $body->write('ef'); // stream contains "efcd" $body->write($contents); // stream contains "efabcd" ``` > Note: `getContents()` seeks the stream while reading it, therefore if the second `rewind()` method call was not present the stream would have resulted in `abcdefabcd` because the `write()` method appends to stream if not preceeded by `rewind()` or `seek(0)`. #### Prepending by using contents as a string ```php $body = $response->getBody(); $body->rewind(); $contents = $body->getContents(); // efabcd $contents = 'ef'.$contents; $body->rewind(); $body->write($contents); ``` ================================================ FILE: lib/Google/vendor/psr/http-message/src/MessageInterface.php ================================================ getHeaders() as $name => $values) { * echo $name . ": " . implode(", ", $values); * } * * // Emit headers iteratively: * foreach ($message->getHeaders() as $name => $values) { * foreach ($values as $value) { * header(sprintf('%s: %s', $name, $value), false); * } * } * * While header names are not case-sensitive, getHeaders() will preserve the * exact case in which headers were originally specified. * * @return string[][] Returns an associative array of the message's headers. Each * key MUST be a header name, and each value MUST be an array of strings * for that header. */ public function getHeaders(): array; /** * Checks if a header exists by the given case-insensitive name. * * @param string $name Case-insensitive header field name. * @return bool Returns true if any header names match the given header * name using a case-insensitive string comparison. Returns false if * no matching header name is found in the message. */ public function hasHeader(string $name): bool; /** * Retrieves a message header value by the given case-insensitive name. * * This method returns an array of all the header values of the given * case-insensitive header name. * * If the header does not appear in the message, this method MUST return an * empty array. * * @param string $name Case-insensitive header field name. * @return string[] An array of string values as provided for the given * header. If the header does not appear in the message, this method MUST * return an empty array. */ public function getHeader(string $name): array; /** * Retrieves a comma-separated string of the values for a single header. * * This method returns all of the header values of the given * case-insensitive header name as a string concatenated together using * a comma. * * NOTE: Not all header values may be appropriately represented using * comma concatenation. For such headers, use getHeader() instead * and supply your own delimiter when concatenating. * * If the header does not appear in the message, this method MUST return * an empty string. * * @param string $name Case-insensitive header field name. * @return string A string of values as provided for the given header * concatenated together using a comma. If the header does not appear in * the message, this method MUST return an empty string. */ public function getHeaderLine(string $name): string; /** * Return an instance with the provided value replacing the specified header. * * While header names are case-insensitive, the casing of the header will * be preserved by this function, and returned from getHeaders(). * * This method MUST be implemented in such a way as to retain the * immutability of the message, and MUST return an instance that has the * new and/or updated header and value. * * @param string $name Case-insensitive header field name. * @param string|string[] $value Header value(s). * @return static * @throws \InvalidArgumentException for invalid header names or values. */ public function withHeader(string $name, $value): MessageInterface; /** * Return an instance with the specified header appended with the given value. * * Existing values for the specified header will be maintained. The new * value(s) will be appended to the existing list. If the header did not * exist previously, it will be added. * * This method MUST be implemented in such a way as to retain the * immutability of the message, and MUST return an instance that has the * new header and/or value. * * @param string $name Case-insensitive header field name to add. * @param string|string[] $value Header value(s). * @return static * @throws \InvalidArgumentException for invalid header names or values. */ public function withAddedHeader(string $name, $value): MessageInterface; /** * Return an instance without the specified header. * * Header resolution MUST be done without case-sensitivity. * * This method MUST be implemented in such a way as to retain the * immutability of the message, and MUST return an instance that removes * the named header. * * @param string $name Case-insensitive header field name to remove. * @return static */ public function withoutHeader(string $name): MessageInterface; /** * Gets the body of the message. * * @return StreamInterface Returns the body as a stream. */ public function getBody(): StreamInterface; /** * Return an instance with the specified message body. * * The body MUST be a StreamInterface object. * * This method MUST be implemented in such a way as to retain the * immutability of the message, and MUST return a new instance that has the * new body stream. * * @param StreamInterface $body Body. * @return static * @throws \InvalidArgumentException When the body is not valid. */ public function withBody(StreamInterface $body): MessageInterface; } ================================================ FILE: lib/Google/vendor/psr/http-message/src/RequestInterface.php ================================================ getQuery()` * or from the `QUERY_STRING` server param. * * @return array */ public function getQueryParams(): array; /** * Return an instance with the specified query string arguments. * * These values SHOULD remain immutable over the course of the incoming * request. They MAY be injected during instantiation, such as from PHP's * $_GET superglobal, or MAY be derived from some other value such as the * URI. In cases where the arguments are parsed from the URI, the data * MUST be compatible with what PHP's parse_str() would return for * purposes of how duplicate query parameters are handled, and how nested * sets are handled. * * Setting query string arguments MUST NOT change the URI stored by the * request, nor the values in the server params. * * This method MUST be implemented in such a way as to retain the * immutability of the message, and MUST return an instance that has the * updated query string arguments. * * @param array $query Array of query string arguments, typically from * $_GET. * @return static */ public function withQueryParams(array $query): ServerRequestInterface; /** * Retrieve normalized file upload data. * * This method returns upload metadata in a normalized tree, with each leaf * an instance of Psr\Http\Message\UploadedFileInterface. * * These values MAY be prepared from $_FILES or the message body during * instantiation, or MAY be injected via withUploadedFiles(). * * @return array An array tree of UploadedFileInterface instances; an empty * array MUST be returned if no data is present. */ public function getUploadedFiles(): array; /** * Create a new instance with the specified uploaded files. * * This method MUST be implemented in such a way as to retain the * immutability of the message, and MUST return an instance that has the * updated body parameters. * * @param array $uploadedFiles An array tree of UploadedFileInterface instances. * @return static * @throws \InvalidArgumentException if an invalid structure is provided. */ public function withUploadedFiles(array $uploadedFiles): ServerRequestInterface; /** * Retrieve any parameters provided in the request body. * * If the request Content-Type is either application/x-www-form-urlencoded * or multipart/form-data, and the request method is POST, this method MUST * return the contents of $_POST. * * Otherwise, this method may return any results of deserializing * the request body content; as parsing returns structured content, the * potential types MUST be arrays or objects only. A null value indicates * the absence of body content. * * @return null|array|object The deserialized body parameters, if any. * These will typically be an array or object. */ public function getParsedBody(); /** * Return an instance with the specified body parameters. * * These MAY be injected during instantiation. * * If the request Content-Type is either application/x-www-form-urlencoded * or multipart/form-data, and the request method is POST, use this method * ONLY to inject the contents of $_POST. * * The data IS NOT REQUIRED to come from $_POST, but MUST be the results of * deserializing the request body content. Deserialization/parsing returns * structured data, and, as such, this method ONLY accepts arrays or objects, * or a null value if nothing was available to parse. * * As an example, if content negotiation determines that the request data * is a JSON payload, this method could be used to create a request * instance with the deserialized parameters. * * This method MUST be implemented in such a way as to retain the * immutability of the message, and MUST return an instance that has the * updated body parameters. * * @param null|array|object $data The deserialized body data. This will * typically be in an array or object. * @return static * @throws \InvalidArgumentException if an unsupported argument type is * provided. */ public function withParsedBody($data): ServerRequestInterface; /** * Retrieve attributes derived from the request. * * The request "attributes" may be used to allow injection of any * parameters derived from the request: e.g., the results of path * match operations; the results of decrypting cookies; the results of * deserializing non-form-encoded message bodies; etc. Attributes * will be application and request specific, and CAN be mutable. * * @return array Attributes derived from the request. */ public function getAttributes(): array; /** * Retrieve a single derived request attribute. * * Retrieves a single derived request attribute as described in * getAttributes(). If the attribute has not been previously set, returns * the default value as provided. * * This method obviates the need for a hasAttribute() method, as it allows * specifying a default value to return if the attribute is not found. * * @see getAttributes() * @param string $name The attribute name. * @param mixed $default Default value to return if the attribute does not exist. * @return mixed */ public function getAttribute(string $name, $default = null); /** * Return an instance with the specified derived request attribute. * * This method allows setting a single derived request attribute as * described in getAttributes(). * * This method MUST be implemented in such a way as to retain the * immutability of the message, and MUST return an instance that has the * updated attribute. * * @see getAttributes() * @param string $name The attribute name. * @param mixed $value The value of the attribute. * @return static */ public function withAttribute(string $name, $value): ServerRequestInterface; /** * Return an instance that removes the specified derived request attribute. * * This method allows removing a single derived request attribute as * described in getAttributes(). * * This method MUST be implemented in such a way as to retain the * immutability of the message, and MUST return an instance that removes * the attribute. * * @see getAttributes() * @param string $name The attribute name. * @return static */ public function withoutAttribute(string $name): ServerRequestInterface; } ================================================ FILE: lib/Google/vendor/psr/http-message/src/StreamInterface.php ================================================ * [user-info@]host[:port] * * * If the port component is not set or is the standard port for the current * scheme, it SHOULD NOT be included. * * @see https://tools.ietf.org/html/rfc3986#section-3.2 * @return string The URI authority, in "[user-info@]host[:port]" format. */ public function getAuthority(): string; /** * Retrieve the user information component of the URI. * * If no user information is present, this method MUST return an empty * string. * * If a user is present in the URI, this will return that value; * additionally, if the password is also present, it will be appended to the * user value, with a colon (":") separating the values. * * The trailing "@" character is not part of the user information and MUST * NOT be added. * * @return string The URI user information, in "username[:password]" format. */ public function getUserInfo(): string; /** * Retrieve the host component of the URI. * * If no host is present, this method MUST return an empty string. * * The value returned MUST be normalized to lowercase, per RFC 3986 * Section 3.2.2. * * @see http://tools.ietf.org/html/rfc3986#section-3.2.2 * @return string The URI host. */ public function getHost(): string; /** * Retrieve the port component of the URI. * * If a port is present, and it is non-standard for the current scheme, * this method MUST return it as an integer. If the port is the standard port * used with the current scheme, this method SHOULD return null. * * If no port is present, and no scheme is present, this method MUST return * a null value. * * If no port is present, but a scheme is present, this method MAY return * the standard port for that scheme, but SHOULD return null. * * @return null|int The URI port. */ public function getPort(): ?int; /** * Retrieve the path component of the URI. * * The path can either be empty or absolute (starting with a slash) or * rootless (not starting with a slash). Implementations MUST support all * three syntaxes. * * Normally, the empty path "" and absolute path "/" are considered equal as * defined in RFC 7230 Section 2.7.3. But this method MUST NOT automatically * do this normalization because in contexts with a trimmed base path, e.g. * the front controller, this difference becomes significant. It's the task * of the user to handle both "" and "/". * * The value returned MUST be percent-encoded, but MUST NOT double-encode * any characters. To determine what characters to encode, please refer to * RFC 3986, Sections 2 and 3.3. * * As an example, if the value should include a slash ("/") not intended as * delimiter between path segments, that value MUST be passed in encoded * form (e.g., "%2F") to the instance. * * @see https://tools.ietf.org/html/rfc3986#section-2 * @see https://tools.ietf.org/html/rfc3986#section-3.3 * @return string The URI path. */ public function getPath(): string; /** * Retrieve the query string of the URI. * * If no query string is present, this method MUST return an empty string. * * The leading "?" character is not part of the query and MUST NOT be * added. * * The value returned MUST be percent-encoded, but MUST NOT double-encode * any characters. To determine what characters to encode, please refer to * RFC 3986, Sections 2 and 3.4. * * As an example, if a value in a key/value pair of the query string should * include an ampersand ("&") not intended as a delimiter between values, * that value MUST be passed in encoded form (e.g., "%26") to the instance. * * @see https://tools.ietf.org/html/rfc3986#section-2 * @see https://tools.ietf.org/html/rfc3986#section-3.4 * @return string The URI query string. */ public function getQuery(): string; /** * Retrieve the fragment component of the URI. * * If no fragment is present, this method MUST return an empty string. * * The leading "#" character is not part of the fragment and MUST NOT be * added. * * The value returned MUST be percent-encoded, but MUST NOT double-encode * any characters. To determine what characters to encode, please refer to * RFC 3986, Sections 2 and 3.5. * * @see https://tools.ietf.org/html/rfc3986#section-2 * @see https://tools.ietf.org/html/rfc3986#section-3.5 * @return string The URI fragment. */ public function getFragment(): string; /** * Return an instance with the specified scheme. * * This method MUST retain the state of the current instance, and return * an instance that contains the specified scheme. * * Implementations MUST support the schemes "http" and "https" case * insensitively, and MAY accommodate other schemes if required. * * An empty scheme is equivalent to removing the scheme. * * @param string $scheme The scheme to use with the new instance. * @return static A new instance with the specified scheme. * @throws \InvalidArgumentException for invalid or unsupported schemes. */ public function withScheme(string $scheme): UriInterface; /** * Return an instance with the specified user information. * * This method MUST retain the state of the current instance, and return * an instance that contains the specified user information. * * Password is optional, but the user information MUST include the * user; an empty string for the user is equivalent to removing user * information. * * @param string $user The user name to use for authority. * @param null|string $password The password associated with $user. * @return static A new instance with the specified user information. */ public function withUserInfo(string $user, ?string $password = null): UriInterface; /** * Return an instance with the specified host. * * This method MUST retain the state of the current instance, and return * an instance that contains the specified host. * * An empty host value is equivalent to removing the host. * * @param string $host The hostname to use with the new instance. * @return static A new instance with the specified host. * @throws \InvalidArgumentException for invalid hostnames. */ public function withHost(string $host): UriInterface; /** * Return an instance with the specified port. * * This method MUST retain the state of the current instance, and return * an instance that contains the specified port. * * Implementations MUST raise an exception for ports outside the * established TCP and UDP port ranges. * * A null value provided for the port is equivalent to removing the port * information. * * @param null|int $port The port to use with the new instance; a null value * removes the port information. * @return static A new instance with the specified port. * @throws \InvalidArgumentException for invalid ports. */ public function withPort(?int $port): UriInterface; /** * Return an instance with the specified path. * * This method MUST retain the state of the current instance, and return * an instance that contains the specified path. * * The path can either be empty or absolute (starting with a slash) or * rootless (not starting with a slash). Implementations MUST support all * three syntaxes. * * If the path is intended to be domain-relative rather than path relative then * it must begin with a slash ("/"). Paths not starting with a slash ("/") * are assumed to be relative to some base path known to the application or * consumer. * * Users can provide both encoded and decoded path characters. * Implementations ensure the correct encoding as outlined in getPath(). * * @param string $path The path to use with the new instance. * @return static A new instance with the specified path. * @throws \InvalidArgumentException for invalid paths. */ public function withPath(string $path): UriInterface; /** * Return an instance with the specified query string. * * This method MUST retain the state of the current instance, and return * an instance that contains the specified query string. * * Users can provide both encoded and decoded query characters. * Implementations ensure the correct encoding as outlined in getQuery(). * * An empty query string value is equivalent to removing the query string. * * @param string $query The query string to use with the new instance. * @return static A new instance with the specified query string. * @throws \InvalidArgumentException for invalid query strings. */ public function withQuery(string $query): UriInterface; /** * Return an instance with the specified URI fragment. * * This method MUST retain the state of the current instance, and return * an instance that contains the specified URI fragment. * * Users can provide both encoded and decoded fragment characters. * Implementations ensure the correct encoding as outlined in getFragment(). * * An empty fragment value is equivalent to removing the fragment. * * @param string $fragment The fragment to use with the new instance. * @return static A new instance with the specified fragment. */ public function withFragment(string $fragment): UriInterface; /** * Return the string representation as a URI reference. * * Depending on which components of the URI are present, the resulting * string is either a full URI or relative reference according to RFC 3986, * Section 4.1. The method concatenates the various components of the URI, * using the appropriate delimiters: * * - If a scheme is present, it MUST be suffixed by ":". * - If an authority is present, it MUST be prefixed by "//". * - The path can be concatenated without delimiters. But there are two * cases where the path has to be adjusted to make the URI reference * valid as PHP does not allow to throw an exception in __toString(): * - If the path is rootless and an authority is present, the path MUST * be prefixed by "/". * - If the path is starting with more than one "/" and no authority is * present, the starting slashes MUST be reduced to one. * - If a query is present, it MUST be prefixed by "?". * - If a fragment is present, it MUST be prefixed by "#". * * @see http://tools.ietf.org/html/rfc3986#section-4.1 * @return string */ public function __toString(): string; } ================================================ FILE: lib/Google/vendor/psr/log/LICENSE ================================================ Copyright (c) 2012 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. ================================================ FILE: lib/Google/vendor/psr/log/README.md ================================================ PSR Log ======= This repository holds all interfaces/classes/traits related to [PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md). Note that this is not a logger of its own. It is merely an interface that describes a logger. See the specification for more details. Installation ------------ ```bash composer require psr/log ``` Usage ----- If you need a logger, you can use the interface like this: ```php logger = $logger; } public function doSomething() { if ($this->logger) { $this->logger->info('Doing work'); } try { $this->doSomethingElse(); } catch (Exception $exception) { $this->logger->error('Oh no!', array('exception' => $exception)); } // do something useful } } ``` You can then pick one of the implementations of the interface to get a logger. If you want to implement the interface, you can require this package and implement `Psr\Log\LoggerInterface` in your code. Please read the [specification text](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md) for details. ================================================ FILE: lib/Google/vendor/psr/log/composer.json ================================================ { "name": "psr/log", "description": "Common interface for logging libraries", "keywords": ["psr", "psr-3", "log"], "homepage": "https://github.com/php-fig/log", "license": "MIT", "authors": [ { "name": "PHP-FIG", "homepage": "https://www.php-fig.org/" } ], "require": { "php": ">=8.0.0" }, "autoload": { "psr-4": { "Psr\\Log\\": "src" } }, "extra": { "branch-alias": { "dev-master": "3.x-dev" } } } ================================================ FILE: lib/Google/vendor/psr/log/src/AbstractLogger.php ================================================ logger = $logger; } } ================================================ FILE: lib/Google/vendor/psr/log/src/LoggerInterface.php ================================================ log(LogLevel::EMERGENCY, $message, $context); } /** * Action must be taken immediately. * * Example: Entire website down, database unavailable, etc. This should * trigger the SMS alerts and wake you up. */ public function alert(string|\Stringable $message, array $context = []): void { $this->log(LogLevel::ALERT, $message, $context); } /** * Critical conditions. * * Example: Application component unavailable, unexpected exception. */ public function critical(string|\Stringable $message, array $context = []): void { $this->log(LogLevel::CRITICAL, $message, $context); } /** * Runtime errors that do not require immediate action but should typically * be logged and monitored. */ public function error(string|\Stringable $message, array $context = []): void { $this->log(LogLevel::ERROR, $message, $context); } /** * Exceptional occurrences that are not errors. * * Example: Use of deprecated APIs, poor use of an API, undesirable things * that are not necessarily wrong. */ public function warning(string|\Stringable $message, array $context = []): void { $this->log(LogLevel::WARNING, $message, $context); } /** * Normal but significant events. */ public function notice(string|\Stringable $message, array $context = []): void { $this->log(LogLevel::NOTICE, $message, $context); } /** * Interesting events. * * Example: User logs in, SQL logs. */ public function info(string|\Stringable $message, array $context = []): void { $this->log(LogLevel::INFO, $message, $context); } /** * Detailed debug information. */ public function debug(string|\Stringable $message, array $context = []): void { $this->log(LogLevel::DEBUG, $message, $context); } /** * Logs with an arbitrary level. * * @param mixed $level * * @throws \Psr\Log\InvalidArgumentException */ abstract public function log($level, string|\Stringable $message, array $context = []): void; } ================================================ FILE: lib/Google/vendor/psr/log/src/NullLogger.php ================================================ logger) { }` * blocks. */ class NullLogger extends AbstractLogger { /** * Logs with an arbitrary level. * * @param mixed[] $context * * @throws \Psr\Log\InvalidArgumentException */ public function log($level, string|\Stringable $message, array $context = []): void { // noop } } ================================================ FILE: lib/Google/vendor/ralouphie/getallheaders/LICENSE ================================================ The MIT License (MIT) Copyright (c) 2014 Ralph Khattar 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. ================================================ FILE: lib/Google/vendor/ralouphie/getallheaders/README.md ================================================ getallheaders ============= PHP `getallheaders()` polyfill. Compatible with PHP >= 5.3. [![Build Status](https://travis-ci.org/ralouphie/getallheaders.svg?branch=master)](https://travis-ci.org/ralouphie/getallheaders) [![Coverage Status](https://coveralls.io/repos/ralouphie/getallheaders/badge.png?branch=master)](https://coveralls.io/r/ralouphie/getallheaders?branch=master) [![Latest Stable Version](https://poser.pugx.org/ralouphie/getallheaders/v/stable.png)](https://packagist.org/packages/ralouphie/getallheaders) [![Latest Unstable Version](https://poser.pugx.org/ralouphie/getallheaders/v/unstable.png)](https://packagist.org/packages/ralouphie/getallheaders) [![License](https://poser.pugx.org/ralouphie/getallheaders/license.png)](https://packagist.org/packages/ralouphie/getallheaders) This is a simple polyfill for [`getallheaders()`](http://www.php.net/manual/en/function.getallheaders.php). ## Install For PHP version **`>= 5.6`**: ``` composer require ralouphie/getallheaders ``` For PHP version **`< 5.6`**: ``` composer require ralouphie/getallheaders "^2" ``` ================================================ FILE: lib/Google/vendor/ralouphie/getallheaders/composer.json ================================================ { "name": "ralouphie/getallheaders", "description": "A polyfill for getallheaders.", "license": "MIT", "authors": [ { "name": "Ralph Khattar", "email": "ralph.khattar@gmail.com" } ], "require": { "php": ">=5.6" }, "require-dev": { "phpunit/phpunit": "^5 || ^6.5", "php-coveralls/php-coveralls": "^2.1" }, "autoload": { "files": ["src/getallheaders.php"] }, "autoload-dev": { "psr-4": { "getallheaders\\Tests\\": "tests/" } } } ================================================ FILE: lib/Google/vendor/ralouphie/getallheaders/src/getallheaders.php ================================================ 'Content-Type', 'CONTENT_LENGTH' => 'Content-Length', 'CONTENT_MD5' => 'Content-Md5', ); foreach ($_SERVER as $key => $value) { if (substr($key, 0, 5) === 'HTTP_') { $key = substr($key, 5); if (!isset($copy_server[$key]) || !isset($_SERVER[$key])) { $key = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', $key)))); $headers[$key] = $value; } } elseif (isset($copy_server[$key])) { $headers[$copy_server[$key]] = $value; } } if (!isset($headers['Authorization'])) { if (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) { $headers['Authorization'] = $_SERVER['REDIRECT_HTTP_AUTHORIZATION']; } elseif (isset($_SERVER['PHP_AUTH_USER'])) { $basic_pass = isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : ''; $headers['Authorization'] = 'Basic ' . base64_encode($_SERVER['PHP_AUTH_USER'] . ':' . $basic_pass); } elseif (isset($_SERVER['PHP_AUTH_DIGEST'])) { $headers['Authorization'] = $_SERVER['PHP_AUTH_DIGEST']; } } return $headers; } } ================================================ FILE: lib/Google/vendor/ramsey/collection/LICENSE ================================================ Copyright (c) 2015-2022 Ben Ramsey 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. ================================================ FILE: lib/Google/vendor/ramsey/collection/README.md ================================================

ramsey/collection

A PHP library for representing and manipulating collections.

Source Code Download Package PHP Programming Language Read License Build Status Codecov Code Coverage

## About ramsey/collection is a PHP library for representing and manipulating collections. Much inspiration for this library came from the [Java Collections Framework][java]. This project adheres to a [code of conduct](CODE_OF_CONDUCT.md). By participating in this project and its community, you are expected to uphold this code. ## Installation Install this package as a dependency using [Composer](https://getcomposer.org). ``` bash composer require ramsey/collection ``` ## Usage Examples of how to use this library may be found in the [Wiki pages](https://github.com/ramsey/collection/wiki/Examples). ## Contributing Contributions are welcome! To contribute, please familiarize yourself with [CONTRIBUTING.md](CONTRIBUTING.md). ## Coordinated Disclosure Keeping user information safe and secure is a top priority, and we welcome the contribution of external security researchers. If you believe you've found a security issue in software that is maintained in this repository, please read [SECURITY.md][] for instructions on submitting a vulnerability report. ## Copyright and License The ramsey/collection library is copyright © [Ben Ramsey](https://benramsey.com) and licensed for use under the terms of the MIT License (MIT). Please see [LICENSE](LICENSE) for more information. [java]: http://docs.oracle.com/javase/8/docs/technotes/guides/collections/index.html [security.md]: https://github.com/ramsey/collection/blob/main/SECURITY.md ================================================ FILE: lib/Google/vendor/ramsey/collection/SECURITY.md ================================================ # Vulnerability Disclosure Policy (VDP) ## Brand Promise Keeping user information safe and secure is a top priority, and we welcome the contribution of external security researchers. ## Scope If you believe you've found a security issue in software that is maintained in this repository, we encourage you to notify us. | Version | In scope | Source code | | ------- | :------: | ----------- | | latest | ✅ | https://github.com/ramsey/collection | ## How to Submit a Report To submit a vulnerability report, please contact us at security@ramsey.dev. Your submission will be reviewed and validated by a member of our team. ## Safe Harbor We support safe harbor for security researchers who: * Make a good faith effort to avoid privacy violations, destruction of data, and interruption or degradation of our services. * Only interact with accounts you own or with explicit permission of the account holder. If you do encounter Personally Identifiable Information (PII) contact us immediately, do not proceed with access, and immediately purge any local information. * Provide us with a reasonable amount of time to resolve vulnerabilities prior to any disclosure to the public or a third party. We will consider activities conducted consistent with this policy to constitute "authorized" conduct and will not pursue civil action or initiate a complaint to law enforcement. We will help to the extent we can if legal action is initiated by a third party against you. Please submit a report to us before engaging in conduct that may be inconsistent with or unaddressed by this policy. ## Preferences * Please provide detailed reports with reproducible steps and a clearly defined impact. * Include the version number of the vulnerable package in your report * Social engineering (e.g. phishing, vishing, smishing) is prohibited. ## Encryption Key for security@ramsey.dev For increased privacy when reporting sensitive issues, you may encrypt your message using the following public key: ``` -----BEGIN PGP PUBLIC KEY BLOCK----- mQINBF+Z9gEBEACbT/pIx8RR0K18t8Z2rDnmEV44YdT7HNsMdq+D6SAlx8UUb6AU jGIbV9dgBgGNtOLU1pxloaJwL9bWIRbj+X/Qb2WNIP//Vz1Y40ox1dSpfCUrizXx kb4p58Xml0PsB8dg3b4RDUgKwGC37ne5xmDnigyJPbiB2XJ6Xc46oPCjh86XROTK wEBB2lY67ClBlSlvC2V9KmbTboRQkLdQDhOaUosMb99zRb0EWqDLaFkZVjY5HI7i 0pTveE6dI12NfHhTwKjZ5pUiAZQGlKA6J1dMjY2unxHZkQj5MlMfrLSyJHZxccdJ xD94T6OTcTHt/XmMpI2AObpewZDdChDQmcYDZXGfAhFoJmbvXsmLMGXKgzKoZ/ls RmLsQhh7+/r8E+Pn5r+A6Hh4uAc14ApyEP0ckKeIXw1C6pepHM4E8TEXVr/IA6K/ z6jlHORixIFX7iNOnfHh+qwOgZw40D6JnBfEzjFi+T2Cy+JzN2uy7I8UnecTMGo3 5t6astPy6xcH6kZYzFTV7XERR6LIIVyLAiMFd8kF5MbJ8N5ElRFsFHPW+82N2HDX c60iSaTB85k6R6xd8JIKDiaKE4sSuw2wHFCKq33d/GamYezp1wO+bVUQg88efljC 2JNFyD+vl30josqhw1HcmbE1TP3DlYeIL5jQOlxCMsgai6JtTfHFM/5MYwARAQAB tBNzZWN1cml0eUByYW1zZXkuZGV2iQJUBBMBCAA+FiEE4drPD+/ofZ570fAYq0bv vXQCywIFAl+Z9gECGwMFCQeGH4AFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AACgkQ q0bvvXQCywIkEA//Qcwv8MtTCy01LHZd9c7VslwhNdXQDYymcTyjcYw8x7O22m4B 3hXE6vqAplFhVxxkqXB2ef0tQuzxhPHNJgkCE4Wq4i+V6qGpaSVHQT2W6DN/NIhL vS8OdScc6zddmIbIkSrzVVAtjwehFNEIrX3DnbbbK+Iku7vsKT5EclOluIsjlYoX goW8IeReyDBqOe2H3hoCGw6EA0D/NYV2bJnfy53rXVIyarsXXeOLp7eNEH6Td7aW PVSrMZJe1t+knrEGnEdrXWzlg4lCJJCtemGv+pKBUomnyISXSdqyoRCCzvQjqyig 2kRebUX8BXPW33p4OXPj9sIboUOjZwormWwqqbFMO+J4TiVCUoEoheI7emPFRcNN QtPJrjbY1++OznBc0GRpfeUkGoU1cbRl1bnepnFIZMTDLkrVW6I1Y4q8ZVwX3BkE N81ctFrRpHBlU36EdHvjPQmGtuiL77Qq3fWmMv7yTvK1wHJAXfEb0ZJWHZCbck3w l0CVq0Z+UUAOM8Rp1N0N8m92xtapav0qCFU9qzf2J5qX6GRmWv+d29wPgFHzDWBm nnrYYIA4wJLx00U6SMcVBSnNe91B+RfGY5XQhbWPjQQecOGCSDsxaFAq2MeOVJyZ bIjLYfG9GxoLKr5R7oLRJvZI4nKKBc1Kci/crZbdiSdQhSQGlDz88F1OHeCIdQQQ EQgAHRYhBOhdAxHd+lus86YQ57Atl5icjAcbBQJfmfdIAAoJELAtl5icjAcbFVcA /1LqB3ZjsnXDAvvAXZVjSPqofSlpMLeRQP6IM/A9Odq0AQCZrtZc1knOMGEcjppK Rk+sy/R0Mshy8TDuaZIRgh2Ux7kCDQRfmfYBARAAmchKzzVz7IaEq7PnZDb3szQs T/+E9F3m39yOpV4fEB1YzObonFakXNT7Gw2tZEx0eitUMqQ/13jjfu3UdzlKl2bR qA8LrSQRhB+PTC9A1XvwxCUYhhjGiLzJ9CZL6hBQB43qHOmE9XJPme90geLsF+gK u39Waj1SNWzwGg+Gy1Gl5f2AJoDTxznreCuFGj+Vfaczt/hlfgqpOdb9jsmdoE7t 3DSWppA9dRHWwQSgE6J28rR4QySBcqyXS6IMykqaJn7Z26yNIaITLnHCZOSY8zhP ha7GFsN549EOCgECbrnPt9dmI2+hQE0RO0e7SOBNsIf5sz/i7urhwuj0CbOqhjc2 X1AEVNFCVcb6HPi/AWefdFCRu0gaWQxn5g+9nkq5slEgvzCCiKYzaBIcr8qR6Hb4 FaOPVPxO8vndRouq57Ws8XpAwbPttioFuCqF4u9K+tK/8e2/R8QgRYJsE3Cz/Fu8 +pZFpMnqbDEbK3DL3ss+1ed1sky+mDV8qXXeI33XW5hMFnk1JWshUjHNlQmE6ftC U0xSTMVUtwJhzH2zDp8lEdu7qi3EsNULOl68ozDr6soWAvCbHPeTdTOnFySGCleG /3TonsoZJs/sSPPJnxFQ1DtgQL6EbhIwa0ZwU4eKYVHZ9tjxuMX3teFzRvOrJjgs +ywGlsIURtEckT5Y6nMAEQEAAYkCPAQYAQgAJhYhBOHazw/v6H2ee9HwGKtG7710 AssCBQJfmfYBAhsMBQkHhh+AAAoJEKtG7710AssC8NcP/iDAcy1aZFvkA0EbZ85p i7/+ywtE/1wF4U4/9OuLcoskqGGnl1pJNPooMOSBCfreoTB8HimT0Fln0CoaOm4Q pScNq39JXmf4VxauqUJVARByP6zUfgYarqoaZNeuFF0S4AZJ2HhGzaQPjDz1uKVM PE6tQSgQkFzdZ9AtRA4vElTH6yRAgmepUsOihk0b0gUtVnwtRYZ8e0Qt3ie97a73 DxLgAgedFRUbLRYiT0vNaYbainBsLWKpN/T8odwIg/smP0Khjp/ckV60cZTdBiPR szBTPJESMUTu0VPntc4gWwGsmhZJg/Tt/qP08XYo3VxNYBegyuWwNR66zDWvwvGH muMv5UchuDxp6Rt3JkIO4voMT1JSjWy9p8krkPEE4V6PxAagLjdZSkt92wVLiK5x y5gNrtPhU45YdRAKHr36OvJBJQ42CDaZ6nzrzghcIp9CZ7ANHrI+QLRM/csz+AGA szSp6S4mc1lnxxfbOhPPpebZPn0nIAXoZnnoVKdrxBVedPQHT59ZFvKTQ9Fs7gd3 sYNuc7tJGFGC2CxBH4ANDpOQkc5q9JJ1HSGrXU3juxIiRgfA26Q22S9c71dXjElw Ri584QH+bL6kkYmm8xpKF6TVwhwu5xx/jBPrbWqFrtbvLNrnfPoapTihBfdIhkT6 nmgawbBHA02D5xEqB5SU3WJu =eJNx -----END PGP PUBLIC KEY BLOCK----- ``` ================================================ FILE: lib/Google/vendor/ramsey/collection/composer.json ================================================ { "name": "ramsey/collection", "description": "A PHP library for representing and manipulating collections.", "license": "MIT", "type": "library", "keywords": [ "array", "collection", "hash", "map", "queue", "set" ], "authors": [ { "name": "Ben Ramsey", "email": "ben@benramsey.com", "homepage": "https://benramsey.com" } ], "require": { "php": "^8.1" }, "require-dev": { "captainhook/plugin-composer": "^5.3", "ergebnis/composer-normalize": "^2.45", "fakerphp/faker": "^1.24", "hamcrest/hamcrest-php": "^2.0", "jangregor/phpstan-prophecy": "^2.1", "mockery/mockery": "^1.6", "php-parallel-lint/php-console-highlighter": "^1.0", "php-parallel-lint/php-parallel-lint": "^1.4", "phpspec/prophecy-phpunit": "^2.3", "phpstan/extension-installer": "^1.4", "phpstan/phpstan": "^2.1", "phpstan/phpstan-mockery": "^2.0", "phpstan/phpstan-phpunit": "^2.0", "phpunit/phpunit": "^10.5", "ramsey/coding-standard": "^2.3", "ramsey/conventional-commits": "^1.6", "roave/security-advisories": "dev-latest" }, "prefer-stable": true, "autoload": { "psr-4": { "Ramsey\\Collection\\": "src/" } }, "autoload-dev": { "psr-4": { "Ramsey\\Collection\\Test\\": "tests/" } }, "config": { "allow-plugins": { "captainhook/plugin-composer": true, "dealerdirect/phpcodesniffer-composer-installer": true, "ergebnis/composer-normalize": true, "phpstan/extension-installer": true }, "sort-packages": true }, "extra": { "captainhook": { "force-install": true }, "ramsey/conventional-commits": { "configFile": "conventional-commits.json" } }, "scripts": { "dev:analyze": [ "@dev:analyze:phpstan" ], "dev:analyze:phpstan": "phpstan analyse --ansi --memory-limit=1G", "dev:build:clean": "git clean -fX build/", "dev:lint": [ "@dev:lint:syntax", "@dev:lint:style" ], "dev:lint:fix": "phpcbf", "dev:lint:style": "phpcs --colors", "dev:lint:syntax": "parallel-lint --colors src/ tests/", "dev:test": [ "@dev:lint", "@dev:analyze", "@dev:test:unit" ], "dev:test:coverage:ci": "phpunit --colors=always --coverage-text --coverage-clover build/coverage/clover.xml --coverage-cobertura build/coverage/cobertura.xml --coverage-crap4j build/coverage/crap4j.xml --coverage-xml build/coverage/coverage-xml --log-junit build/junit.xml", "dev:test:coverage:html": "phpunit --colors=always --coverage-html build/coverage/coverage-html/", "dev:test:unit": "phpunit --colors=always", "test": "@dev:test" }, "scripts-descriptions": { "dev:analyze": "Runs all static analysis checks.", "dev:analyze:phpstan": "Runs the PHPStan static analyzer.", "dev:build:clean": "Cleans the build/ directory.", "dev:lint": "Runs all linting checks.", "dev:lint:fix": "Auto-fixes coding standards issues, if possible.", "dev:lint:style": "Checks for coding standards issues.", "dev:lint:syntax": "Checks for syntax errors.", "dev:test": "Runs linting, static analysis, and unit tests.", "dev:test:coverage:ci": "Runs unit tests and generates CI coverage reports.", "dev:test:coverage:html": "Runs unit tests and generates HTML coverage report.", "dev:test:unit": "Runs unit tests.", "test": "Runs linting, static analysis, and unit tests." } } ================================================ FILE: lib/Google/vendor/ramsey/collection/src/AbstractArray.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Collection; use ArrayIterator; use Traversable; use function count; /** * This class provides a basic implementation of `ArrayInterface`, to minimize * the effort required to implement this interface. * * @template T * @implements ArrayInterface */ abstract class AbstractArray implements ArrayInterface { /** * The items of this array. * * @var array */ protected array $data = []; /** * Constructs a new array object. * * @param array $data The initial items to add to this array. */ public function __construct(array $data = []) { // Invoke offsetSet() for each value added; in this way, subclasses // may provide additional logic about values added to the array object. foreach ($data as $key => $value) { $this[$key] = $value; } } /** * Returns an iterator for this array. * * @link http://php.net/manual/en/iteratoraggregate.getiterator.php IteratorAggregate::getIterator() * * @return Traversable */ public function getIterator(): Traversable { return new ArrayIterator($this->data); } /** * Returns `true` if the given offset exists in this array. * * @link http://php.net/manual/en/arrayaccess.offsetexists.php ArrayAccess::offsetExists() * * @param array-key $offset The offset to check. */ public function offsetExists(mixed $offset): bool { return isset($this->data[$offset]); } /** * Returns the value at the specified offset. * * @link http://php.net/manual/en/arrayaccess.offsetget.php ArrayAccess::offsetGet() * * @param array-key $offset The offset for which a value should be returned. * * @return T the value stored at the offset, or null if the offset * does not exist. */ public function offsetGet(mixed $offset): mixed { return $this->data[$offset]; } /** * Sets the given value to the given offset in the array. * * @link http://php.net/manual/en/arrayaccess.offsetset.php ArrayAccess::offsetSet() * * @param array-key | null $offset The offset to set. If `null`, the value * may be set at a numerically-indexed offset. * @param T $value The value to set at the given offset. */ public function offsetSet(mixed $offset, mixed $value): void { if ($offset === null) { $this->data[] = $value; } else { $this->data[$offset] = $value; } } /** * Removes the given offset and its value from the array. * * @link http://php.net/manual/en/arrayaccess.offsetunset.php ArrayAccess::offsetUnset() * * @param array-key $offset The offset to remove from the array. */ public function offsetUnset(mixed $offset): void { unset($this->data[$offset]); } /** * Returns data suitable for PHP serialization. * * @link https://www.php.net/manual/en/language.oop5.magic.php#language.oop5.magic.serialize * @link https://www.php.net/serialize * * @return array */ public function __serialize(): array { return $this->data; } /** * Adds unserialized data to the object. * * @param array $data */ public function __unserialize(array $data): void { $this->data = $data; } /** * Returns the number of items in this array. * * @link http://php.net/manual/en/countable.count.php Countable::count() */ public function count(): int { return count($this->data); } public function clear(): void { $this->data = []; } /** * @inheritDoc */ public function toArray(): array { return $this->data; } public function isEmpty(): bool { return $this->data === []; } } ================================================ FILE: lib/Google/vendor/ramsey/collection/src/AbstractCollection.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Collection; use Closure; use Ramsey\Collection\Exception\CollectionMismatchException; use Ramsey\Collection\Exception\InvalidArgumentException; use Ramsey\Collection\Exception\InvalidPropertyOrMethod; use Ramsey\Collection\Exception\NoSuchElementException; use Ramsey\Collection\Exception\UnsupportedOperationException; use Ramsey\Collection\Tool\TypeTrait; use Ramsey\Collection\Tool\ValueExtractorTrait; use Ramsey\Collection\Tool\ValueToStringTrait; use function array_filter; use function array_key_first; use function array_key_last; use function array_map; use function array_merge; use function array_reduce; use function array_search; use function array_udiff; use function array_uintersect; use function in_array; use function is_int; use function is_object; use function spl_object_id; use function sprintf; use function usort; /** * This class provides a basic implementation of `CollectionInterface`, to * minimize the effort required to implement this interface * * @template T * @extends AbstractArray * @implements CollectionInterface */ abstract class AbstractCollection extends AbstractArray implements CollectionInterface { use TypeTrait; use ValueToStringTrait; use ValueExtractorTrait; /** * @throws InvalidArgumentException if $element is of the wrong type. */ public function add(mixed $element): bool { $this[] = $element; return true; } public function contains(mixed $element, bool $strict = true): bool { return in_array($element, $this->data, $strict); } /** * @throws InvalidArgumentException if $element is of the wrong type. */ public function offsetSet(mixed $offset, mixed $value): void { if ($this->checkType($this->getType(), $value) === false) { throw new InvalidArgumentException( 'Value must be of type ' . $this->getType() . '; value is ' . $this->toolValueToString($value), ); } if ($offset === null) { $this->data[] = $value; } else { $this->data[$offset] = $value; } } public function remove(mixed $element): bool { if (($position = array_search($element, $this->data, true)) !== false) { unset($this[$position]); return true; } return false; } /** * @throws InvalidPropertyOrMethod if the $propertyOrMethod does not exist * on the elements in this collection. * @throws UnsupportedOperationException if unable to call column() on this * collection. * * @inheritDoc */ public function column(string $propertyOrMethod): array { $temp = []; foreach ($this->data as $item) { $temp[] = $this->extractValue($item, $propertyOrMethod); } return $temp; } /** * @return T * * @throws NoSuchElementException if this collection is empty. */ public function first(): mixed { $firstIndex = array_key_first($this->data); if ($firstIndex === null) { throw new NoSuchElementException('Can\'t determine first item. Collection is empty'); } return $this->data[$firstIndex]; } /** * @return T * * @throws NoSuchElementException if this collection is empty. */ public function last(): mixed { $lastIndex = array_key_last($this->data); if ($lastIndex === null) { throw new NoSuchElementException('Can\'t determine last item. Collection is empty'); } return $this->data[$lastIndex]; } /** * @return CollectionInterface * * @throws InvalidPropertyOrMethod if the $propertyOrMethod does not exist * on the elements in this collection. * @throws UnsupportedOperationException if unable to call sort() on this * collection. */ public function sort(?string $propertyOrMethod = null, Sort $order = Sort::Ascending): CollectionInterface { $collection = clone $this; usort( $collection->data, function (mixed $a, mixed $b) use ($propertyOrMethod, $order): int { $aValue = $this->extractValue($a, $propertyOrMethod); $bValue = $this->extractValue($b, $propertyOrMethod); return ($aValue <=> $bValue) * ($order === Sort::Descending ? -1 : 1); }, ); return $collection; } /** * @param callable(T): bool $callback A callable to use for filtering elements. * * @return CollectionInterface */ public function filter(callable $callback): CollectionInterface { $collection = clone $this; $collection->data = array_merge([], array_filter($collection->data, $callback)); return $collection; } /** * @return CollectionInterface * * @throws InvalidPropertyOrMethod if the $propertyOrMethod does not exist * on the elements in this collection. * @throws UnsupportedOperationException if unable to call where() on this * collection. */ public function where(?string $propertyOrMethod, mixed $value): CollectionInterface { return $this->filter( fn (mixed $item): bool => $this->extractValue($item, $propertyOrMethod) === $value, ); } /** * @param callable(T): TCallbackReturn $callback A callable to apply to each * item of the collection. * * @return CollectionInterface * * @template TCallbackReturn */ public function map(callable $callback): CollectionInterface { return new Collection('mixed', array_map($callback, $this->data)); } /** * @param callable(TCarry, T): TCarry $callback A callable to apply to each * item of the collection to reduce it to a single value. * @param TCarry $initial This is the initial value provided to the callback. * * @return TCarry * * @template TCarry */ public function reduce(callable $callback, mixed $initial): mixed { return array_reduce($this->data, $callback, $initial); } /** * @param CollectionInterface $other The collection to check for divergent * items. * * @return CollectionInterface * * @throws CollectionMismatchException if the compared collections are of * differing types. */ public function diff(CollectionInterface $other): CollectionInterface { $this->compareCollectionTypes($other); $diffAtoB = array_udiff($this->data, $other->toArray(), $this->getComparator()); $diffBtoA = array_udiff($other->toArray(), $this->data, $this->getComparator()); $collection = clone $this; $collection->data = array_merge($diffAtoB, $diffBtoA); return $collection; } /** * @param CollectionInterface $other The collection to check for * intersecting items. * * @return CollectionInterface * * @throws CollectionMismatchException if the compared collections are of * differing types. */ public function intersect(CollectionInterface $other): CollectionInterface { $this->compareCollectionTypes($other); $collection = clone $this; $collection->data = array_uintersect($this->data, $other->toArray(), $this->getComparator()); return $collection; } /** * @param CollectionInterface ...$collections The collections to merge. * * @return CollectionInterface * * @throws CollectionMismatchException if unable to merge any of the given * collections or items within the given collections due to type * mismatch errors. */ public function merge(CollectionInterface ...$collections): CollectionInterface { $mergedCollection = clone $this; foreach ($collections as $index => $collection) { if (!$collection instanceof static) { throw new CollectionMismatchException( sprintf('Collection with index %d must be of type %s', $index, static::class), ); } // When using generics (Collection.php, Set.php, etc), // we also need to make sure that the internal types match each other if ($this->getUniformType($collection) !== $this->getUniformType($this)) { throw new CollectionMismatchException( sprintf( 'Collection items in collection with index %d must be of type %s', $index, $this->getType(), ), ); } foreach ($collection as $key => $value) { if (is_int($key)) { $mergedCollection[] = $value; } else { $mergedCollection[$key] = $value; } } } return $mergedCollection; } /** * @param CollectionInterface $other * * @throws CollectionMismatchException */ private function compareCollectionTypes(CollectionInterface $other): void { if (!$other instanceof static) { throw new CollectionMismatchException('Collection must be of type ' . static::class); } // When using generics (Collection.php, Set.php, etc), // we also need to make sure that the internal types match each other if ($this->getUniformType($other) !== $this->getUniformType($this)) { throw new CollectionMismatchException('Collection items must be of type ' . $this->getType()); } } private function getComparator(): Closure { return function (mixed $a, mixed $b): int { // If the two values are object, we convert them to unique scalars. // If the collection contains mixed values (unlikely) where some are objects // and some are not, we leave them as they are. // The comparator should still work and the result of $a < $b should // be consistent but unpredictable since not documented. if (is_object($a) && is_object($b)) { $a = spl_object_id($a); $b = spl_object_id($b); } return $a === $b ? 0 : ($a < $b ? 1 : -1); }; } /** * @param CollectionInterface $collection */ private function getUniformType(CollectionInterface $collection): string { return match ($collection->getType()) { 'integer' => 'int', 'boolean' => 'bool', 'double' => 'float', default => $collection->getType(), }; } } ================================================ FILE: lib/Google/vendor/ramsey/collection/src/AbstractSet.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Collection; /** * This class contains the basic implementation of a collection that does not * allow duplicated values (a set), to minimize the effort required to implement * this specific type of collection. * * @template T * @extends AbstractCollection */ abstract class AbstractSet extends AbstractCollection { public function add(mixed $element): bool { if ($this->contains($element)) { return false; } // Call offsetSet() on the parent instead of add(), since calling // parent::add() will invoke $this->offsetSet(), which will call // $this->contains() a second time. This can cause performance issues // with extremely large collections. For more information, see // https://github.com/ramsey/collection/issues/68. parent::offsetSet(null, $element); return true; } public function offsetSet(mixed $offset, mixed $value): void { if ($this->contains($value)) { return; } parent::offsetSet($offset, $value); } } ================================================ FILE: lib/Google/vendor/ramsey/collection/src/ArrayInterface.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Collection; use ArrayAccess; use Countable; use IteratorAggregate; /** * `ArrayInterface` provides traversable array functionality to data types. * * @template T * @extends ArrayAccess * @extends IteratorAggregate */ interface ArrayInterface extends ArrayAccess, Countable, IteratorAggregate { /** * Removes all items from this array. */ public function clear(): void; /** * Returns a native PHP array representation of this array object. * * @return array */ public function toArray(): array; /** * Returns `true` if this array is empty. */ public function isEmpty(): bool; } ================================================ FILE: lib/Google/vendor/ramsey/collection/src/Collection.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Collection; /** * A collection represents a group of objects. * * Each object in the collection is of a specific, defined type. * * This is a direct implementation of `CollectionInterface`, provided for * the sake of convenience. * * Example usage: * * ``` * $collection = new \Ramsey\Collection\Collection('My\\Foo'); * $collection->add(new \My\Foo()); * $collection->add(new \My\Foo()); * * foreach ($collection as $foo) { * // Do something with $foo * } * ``` * * It is preferable to subclass `AbstractCollection` to create your own typed * collections. For example: * * ``` * namespace My\Foo; * * class FooCollection extends \Ramsey\Collection\AbstractCollection * { * public function getType() * { * return 'My\\Foo'; * } * } * ``` * * And then use it similarly to the earlier example: * * ``` * $fooCollection = new \My\Foo\FooCollection(); * $fooCollection->add(new \My\Foo()); * $fooCollection->add(new \My\Foo()); * * foreach ($fooCollection as $foo) { * // Do something with $foo * } * ``` * * The benefit with this approach is that you may do type-checking on the * collection object: * * ``` * if ($collection instanceof \My\Foo\FooCollection) { * // the collection is a collection of My\Foo objects * } * ``` * * @template T * @extends AbstractCollection */ class Collection extends AbstractCollection { /** * Constructs a collection object of the specified type, optionally with the * specified data. * * @param string $collectionType The type or class name associated with this * collection. * @param array $data The initial items to store in the collection. */ public function __construct(private readonly string $collectionType, array $data = []) { parent::__construct($data); } public function getType(): string { return $this->collectionType; } } ================================================ FILE: lib/Google/vendor/ramsey/collection/src/CollectionInterface.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Collection; use Ramsey\Collection\Exception\CollectionMismatchException; use Ramsey\Collection\Exception\InvalidArgumentException; use Ramsey\Collection\Exception\InvalidPropertyOrMethod; use Ramsey\Collection\Exception\NoSuchElementException; use Ramsey\Collection\Exception\UnsupportedOperationException; /** * A collection represents a group of values, known as its elements. * * Some collections allow duplicate elements and others do not. Some are ordered * and others unordered. * * @template T * @extends ArrayInterface */ interface CollectionInterface extends ArrayInterface { /** * Ensures that this collection contains the specified element (optional * operation). * * Returns `true` if this collection changed as a result of the call. * (Returns `false` if this collection does not permit duplicates and * already contains the specified element.) * * Collections that support this operation may place limitations on what * elements may be added to this collection. In particular, some * collections will refuse to add `null` elements, and others will impose * restrictions on the type of elements that may be added. Collection * classes should clearly specify in their documentation any restrictions * on what elements may be added. * * If a collection refuses to add a particular element for any reason other * than that it already contains the element, it must throw an exception * (rather than returning `false`). This preserves the invariant that a * collection always contains the specified element after this call returns. * * @param T $element The element to add to the collection. * * @return bool `true` if this collection changed as a result of the call. * * @throws InvalidArgumentException if the collection refuses to add the * $element for any reason other than that it already contains the element. */ public function add(mixed $element): bool; /** * Returns `true` if this collection contains the specified element. * * @param T $element The element to check whether the collection contains. * @param bool $strict Whether to perform a strict type check on the value. */ public function contains(mixed $element, bool $strict = true): bool; /** * Returns the type associated with this collection. */ public function getType(): string; /** * Removes a single instance of the specified element from this collection, * if it is present. * * @param T $element The element to remove from the collection. * * @return bool `true` if an element was removed as a result of this call. */ public function remove(mixed $element): bool; /** * Returns the values from the given property, method, or array key. * * @param string $propertyOrMethod The name of the property, method, or * array key to evaluate and return. * * @return list * * @throws InvalidPropertyOrMethod if the $propertyOrMethod does not exist * on the elements in this collection. * @throws UnsupportedOperationException if unable to call column() on this * collection. */ public function column(string $propertyOrMethod): array; /** * Returns the first item of the collection. * * @return T * * @throws NoSuchElementException if this collection is empty. */ public function first(): mixed; /** * Returns the last item of the collection. * * @return T * * @throws NoSuchElementException if this collection is empty. */ public function last(): mixed; /** * Sort the collection by a property, method, or array key with the given * sort order. * * If $propertyOrMethod is `null`, this will sort by comparing each element. * * This will always leave the original collection untouched and will return * a new one. * * @param string | null $propertyOrMethod The property, method, or array key * to sort by. * @param Sort $order The sort order for the resulting collection. * * @return CollectionInterface * * @throws InvalidPropertyOrMethod if the $propertyOrMethod does not exist * on the elements in this collection. * @throws UnsupportedOperationException if unable to call sort() on this * collection. */ public function sort(?string $propertyOrMethod = null, Sort $order = Sort::Ascending): self; /** * Filter out items of the collection which don't match the criteria of * given callback. * * This will always leave the original collection untouched and will return * a new one. * * See the {@link http://php.net/manual/en/function.array-filter.php PHP array_filter() documentation} * for examples of how the `$callback` parameter works. * * @param callable(T): bool $callback A callable to use for filtering elements. * * @return CollectionInterface */ public function filter(callable $callback): self; /** * Create a new collection where the result of the given property, method, * or array key of each item in the collection equals the given value. * * This will always leave the original collection untouched and will return * a new one. * * @param string | null $propertyOrMethod The property, method, or array key * to evaluate. If `null`, the element itself is compared to $value. * @param mixed $value The value to match. * * @return CollectionInterface * * @throws InvalidPropertyOrMethod if the $propertyOrMethod does not exist * on the elements in this collection. * @throws UnsupportedOperationException if unable to call where() on this * collection. */ public function where(?string $propertyOrMethod, mixed $value): self; /** * Apply a given callback method on each item of the collection. * * This will always leave the original collection untouched. The new * collection is created by mapping the callback to each item of the * original collection. * * See the {@link http://php.net/manual/en/function.array-map.php PHP array_map() documentation} * for examples of how the `$callback` parameter works. * * @param callable(T): TCallbackReturn $callback A callable to apply to each * item of the collection. * * @return CollectionInterface * * @template TCallbackReturn */ public function map(callable $callback): self; /** * Apply a given callback method on each item of the collection * to reduce it to a single value. * * See the {@link http://php.net/manual/en/function.array-reduce.php PHP array_reduce() documentation} * for examples of how the `$callback` and `$initial` parameters work. * * @param callable(TCarry, T): TCarry $callback A callable to apply to each * item of the collection to reduce it to a single value. * @param TCarry $initial This is the initial value provided to the callback. * * @return TCarry * * @template TCarry */ public function reduce(callable $callback, mixed $initial): mixed; /** * Create a new collection with divergent items between current and given * collection. * * @param CollectionInterface $other The collection to check for divergent * items. * * @return CollectionInterface * * @throws CollectionMismatchException if the compared collections are of * differing types. */ public function diff(CollectionInterface $other): self; /** * Create a new collection with intersecting item between current and given * collection. * * @param CollectionInterface $other The collection to check for * intersecting items. * * @return CollectionInterface * * @throws CollectionMismatchException if the compared collections are of * differing types. */ public function intersect(CollectionInterface $other): self; /** * Merge current items and items of given collections into a new one. * * @param CollectionInterface ...$collections The collections to merge. * * @return CollectionInterface * * @throws CollectionMismatchException if unable to merge any of the given * collections or items within the given collections due to type * mismatch errors. */ public function merge(CollectionInterface ...$collections): self; } ================================================ FILE: lib/Google/vendor/ramsey/collection/src/DoubleEndedQueue.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Collection; use Ramsey\Collection\Exception\InvalidArgumentException; use Ramsey\Collection\Exception\NoSuchElementException; use function array_key_last; use function array_pop; use function array_unshift; /** * This class provides a basic implementation of `DoubleEndedQueueInterface`, to * minimize the effort required to implement this interface. * * @template T * @extends Queue * @implements DoubleEndedQueueInterface */ class DoubleEndedQueue extends Queue implements DoubleEndedQueueInterface { /** * Constructs a double-ended queue (dequeue) object of the specified type, * optionally with the specified data. * * @param string $queueType The type or class name associated with this dequeue. * @param array $data The initial items to store in the dequeue. */ public function __construct(private readonly string $queueType, array $data = []) { parent::__construct($this->queueType, $data); } /** * @throws InvalidArgumentException if $element is of the wrong type */ public function addFirst(mixed $element): bool { if ($this->checkType($this->getType(), $element) === false) { throw new InvalidArgumentException( 'Value must be of type ' . $this->getType() . '; value is ' . $this->toolValueToString($element), ); } array_unshift($this->data, $element); return true; } /** * @throws InvalidArgumentException if $element is of the wrong type */ public function addLast(mixed $element): bool { return $this->add($element); } public function offerFirst(mixed $element): bool { try { return $this->addFirst($element); } catch (InvalidArgumentException) { return false; } } public function offerLast(mixed $element): bool { return $this->offer($element); } /** * @return T the first element in this queue. * * @throws NoSuchElementException if the queue is empty */ public function removeFirst(): mixed { return $this->remove(); } /** * @return T the last element in this queue. * * @throws NoSuchElementException if this queue is empty. */ public function removeLast(): mixed { return $this->pollLast() ?? throw new NoSuchElementException( 'Can\'t return element from Queue. Queue is empty.', ); } /** * @return T | null the head of this queue, or `null` if this queue is empty. */ public function pollFirst(): mixed { return $this->poll(); } /** * @return T | null the tail of this queue, or `null` if this queue is empty. */ public function pollLast(): mixed { return array_pop($this->data); } /** * @return T the head of this queue. * * @throws NoSuchElementException if this queue is empty. */ public function firstElement(): mixed { return $this->element(); } /** * @return T the tail of this queue. * * @throws NoSuchElementException if this queue is empty. */ public function lastElement(): mixed { return $this->peekLast() ?? throw new NoSuchElementException( 'Can\'t return element from Queue. Queue is empty.', ); } /** * @return T | null the head of this queue, or `null` if this queue is empty. */ public function peekFirst(): mixed { return $this->peek(); } /** * @return T | null the tail of this queue, or `null` if this queue is empty. */ public function peekLast(): mixed { $lastIndex = array_key_last($this->data); if ($lastIndex === null) { return null; } return $this->data[$lastIndex]; } } ================================================ FILE: lib/Google/vendor/ramsey/collection/src/DoubleEndedQueueInterface.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Collection; use Ramsey\Collection\Exception\NoSuchElementException; use RuntimeException; /** * A linear collection that supports element insertion and removal at both ends. * * Most `DoubleEndedQueueInterface` implementations place no fixed limits on the * number of elements they may contain, but this interface supports * capacity-restricted double-ended queues as well as those with no fixed size * limit. * * This interface defines methods to access the elements at both ends of the * double-ended queue. Methods are provided to insert, remove, and examine the * element. Each of these methods exists in two forms: one throws an exception * if the operation fails, the other returns a special value (either `null` or * `false`, depending on the operation). The latter form of the insert operation * is designed specifically for use with capacity-restricted implementations; in * most implementations, insert operations cannot fail. * * The twelve methods described above are summarized in the following table: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Summary of DoubleEndedQueueInterface methods
First Element (Head)Last Element (Tail)
Throws exceptionSpecial valueThrows exceptionSpecial value
InsertaddFirst()offerFirst()addLast()offerLast()
RemoveremoveFirst()pollFirst()removeLast()pollLast()
ExaminefirstElement()peekFirst()lastElement()peekLast()
* * This interface extends the `QueueInterface`. When a double-ended queue is * used as a queue, FIFO (first-in-first-out) behavior results. Elements are * added at the end of the double-ended queue and removed from the beginning. * The methods inherited from the `QueueInterface` are precisely equivalent to * `DoubleEndedQueueInterface` methods as indicated in the following table: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Comparison of QueueInterface and DoubleEndedQueueInterface methods
QueueInterface MethodDoubleEndedQueueInterface Method
add()addLast()
offer()offerLast()
remove()removeFirst()
poll()pollFirst()
element()firstElement()
peek()peekFirst()
* * Double-ended queues can also be used as LIFO (last-in-first-out) stacks. When * a double-ended queue is used as a stack, elements are pushed and popped from * the beginning of the double-ended queue. Stack concepts are precisely * equivalent to `DoubleEndedQueueInterface` methods as indicated in the table * below: * * * * * * * * * * * * * * * * * * * * * * * *
Comparison of stack concepts and DoubleEndedQueueInterface methods
Stack conceptDoubleEndedQueueInterface Method
pushaddFirst()
popremoveFirst()
peekpeekFirst()
* * Note that the `peek()` method works equally well when a double-ended queue is * used as a queue or a stack; in either case, elements are drawn from the * beginning of the double-ended queue. * * While `DoubleEndedQueueInterface` implementations are not strictly required * to prohibit the insertion of `null` elements, they are strongly encouraged to * do so. Users of any `DoubleEndedQueueInterface` implementations that do allow * `null` elements are strongly encouraged *not* to take advantage of the * ability to insert nulls. This is so because `null` is used as a special * return value by various methods to indicated that the double-ended queue is * empty. * * @template T * @extends QueueInterface */ interface DoubleEndedQueueInterface extends QueueInterface { /** * Inserts the specified element at the front of this queue if it is * possible to do so immediately without violating capacity restrictions. * * When using a capacity-restricted double-ended queue, it is generally * preferable to use the `offerFirst()` method. * * @param T $element The element to add to the front of this queue. * * @return bool `true` if this queue changed as a result of the call. * * @throws RuntimeException if a queue refuses to add a particular element * for any reason other than that it already contains the element. * Implementations should use a more-specific exception that extends * `\RuntimeException`. */ public function addFirst(mixed $element): bool; /** * Inserts the specified element at the end of this queue if it is possible * to do so immediately without violating capacity restrictions. * * When using a capacity-restricted double-ended queue, it is generally * preferable to use the `offerLast()` method. * * This method is equivalent to `add()`. * * @param T $element The element to add to the end of this queue. * * @return bool `true` if this queue changed as a result of the call. * * @throws RuntimeException if a queue refuses to add a particular element * for any reason other than that it already contains the element. * Implementations should use a more-specific exception that extends * `\RuntimeException`. */ public function addLast(mixed $element): bool; /** * Inserts the specified element at the front of this queue if it is * possible to do so immediately without violating capacity restrictions. * * When using a capacity-restricted queue, this method is generally * preferable to `addFirst()`, which can fail to insert an element only by * throwing an exception. * * @param T $element The element to add to the front of this queue. * * @return bool `true` if the element was added to this queue, else `false`. */ public function offerFirst(mixed $element): bool; /** * Inserts the specified element at the end of this queue if it is possible * to do so immediately without violating capacity restrictions. * * When using a capacity-restricted queue, this method is generally * preferable to `addLast()` which can fail to insert an element only by * throwing an exception. * * @param T $element The element to add to the end of this queue. * * @return bool `true` if the element was added to this queue, else `false`. */ public function offerLast(mixed $element): bool; /** * Retrieves and removes the head of this queue. * * This method differs from `pollFirst()` only in that it throws an * exception if this queue is empty. * * @return T the first element in this queue. * * @throws NoSuchElementException if this queue is empty. */ public function removeFirst(): mixed; /** * Retrieves and removes the tail of this queue. * * This method differs from `pollLast()` only in that it throws an exception * if this queue is empty. * * @return T the last element in this queue. * * @throws NoSuchElementException if this queue is empty. */ public function removeLast(): mixed; /** * Retrieves and removes the head of this queue, or returns `null` if this * queue is empty. * * @return T | null the head of this queue, or `null` if this queue is empty. */ public function pollFirst(): mixed; /** * Retrieves and removes the tail of this queue, or returns `null` if this * queue is empty. * * @return T | null the tail of this queue, or `null` if this queue is empty. */ public function pollLast(): mixed; /** * Retrieves, but does not remove, the head of this queue. * * This method differs from `peekFirst()` only in that it throws an * exception if this queue is empty. * * @return T the head of this queue. * * @throws NoSuchElementException if this queue is empty. */ public function firstElement(): mixed; /** * Retrieves, but does not remove, the tail of this queue. * * This method differs from `peekLast()` only in that it throws an exception * if this queue is empty. * * @return T the tail of this queue. * * @throws NoSuchElementException if this queue is empty. */ public function lastElement(): mixed; /** * Retrieves, but does not remove, the head of this queue, or returns `null` * if this queue is empty. * * @return T | null the head of this queue, or `null` if this queue is empty. */ public function peekFirst(): mixed; /** * Retrieves, but does not remove, the tail of this queue, or returns `null` * if this queue is empty. * * @return T | null the tail of this queue, or `null` if this queue is empty. */ public function peekLast(): mixed; } ================================================ FILE: lib/Google/vendor/ramsey/collection/src/Exception/CollectionException.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Collection\Exception; use Throwable; interface CollectionException extends Throwable { } ================================================ FILE: lib/Google/vendor/ramsey/collection/src/Exception/CollectionMismatchException.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Collection\Exception; use RuntimeException; /** * Thrown when attempting to operate on collections of differing types. */ class CollectionMismatchException extends RuntimeException implements CollectionException { } ================================================ FILE: lib/Google/vendor/ramsey/collection/src/Exception/InvalidArgumentException.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Collection\Exception; use InvalidArgumentException as PhpInvalidArgumentException; /** * Thrown to indicate an argument is not of the expected type. */ class InvalidArgumentException extends PhpInvalidArgumentException implements CollectionException { } ================================================ FILE: lib/Google/vendor/ramsey/collection/src/Exception/InvalidPropertyOrMethod.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Collection\Exception; use RuntimeException; /** * Thrown when attempting to evaluate a property, method, or array key * that doesn't exist on an element or cannot otherwise be evaluated in the * current context. */ class InvalidPropertyOrMethod extends RuntimeException implements CollectionException { } ================================================ FILE: lib/Google/vendor/ramsey/collection/src/Exception/NoSuchElementException.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Collection\Exception; use RuntimeException; /** * Thrown when attempting to access an element that does not exist. */ class NoSuchElementException extends RuntimeException implements CollectionException { } ================================================ FILE: lib/Google/vendor/ramsey/collection/src/Exception/OutOfBoundsException.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Collection\Exception; use OutOfBoundsException as PhpOutOfBoundsException; /** * Thrown when attempting to access an element out of the range of the collection. */ class OutOfBoundsException extends PhpOutOfBoundsException implements CollectionException { } ================================================ FILE: lib/Google/vendor/ramsey/collection/src/Exception/UnsupportedOperationException.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Collection\Exception; use RuntimeException; /** * Thrown to indicate that the requested operation is not supported. */ class UnsupportedOperationException extends RuntimeException implements CollectionException { } ================================================ FILE: lib/Google/vendor/ramsey/collection/src/GenericArray.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Collection; /** * `GenericArray` represents a standard array object. * * @extends AbstractArray */ class GenericArray extends AbstractArray { } ================================================ FILE: lib/Google/vendor/ramsey/collection/src/Map/AbstractMap.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Collection\Map; use Ramsey\Collection\AbstractArray; use Ramsey\Collection\Exception\InvalidArgumentException; use Traversable; use function array_key_exists; use function array_keys; use function in_array; use function var_export; /** * This class provides a basic implementation of `MapInterface`, to minimize the * effort required to implement this interface. * * @template K of array-key * @template T * @extends AbstractArray * @implements MapInterface */ abstract class AbstractMap extends AbstractArray implements MapInterface { /** * @param array $data The initial items to add to this map. */ public function __construct(array $data = []) { parent::__construct($data); } /** * @return Traversable */ public function getIterator(): Traversable { return parent::getIterator(); } /** * @param K $offset The offset to set * @param T $value The value to set at the given offset. * * @inheritDoc */ public function offsetSet(mixed $offset, mixed $value): void { if ($offset === null) { throw new InvalidArgumentException( 'Map elements are key/value pairs; a key must be provided for ' . 'value ' . var_export($value, true), ); } $this->data[$offset] = $value; } public function containsKey(int | string $key): bool { return array_key_exists($key, $this->data); } public function containsValue(mixed $value): bool { return in_array($value, $this->data, true); } /** * @inheritDoc */ public function keys(): array { /** @var list */ return array_keys($this->data); } /** * @param K $key The key to return from the map. * @param T | null $defaultValue The default value to use if `$key` is not found. * * @return T | null the value or `null` if the key could not be found. */ public function get(int | string $key, mixed $defaultValue = null): mixed { return $this[$key] ?? $defaultValue; } /** * @param K $key The key to put or replace in the map. * @param T $value The value to store at `$key`. * * @return T | null the previous value associated with key, or `null` if * there was no mapping for `$key`. */ public function put(int | string $key, mixed $value): mixed { $previousValue = $this->get($key); $this[$key] = $value; return $previousValue; } /** * @param K $key The key to put in the map. * @param T $value The value to store at `$key`. * * @return T | null the previous value associated with key, or `null` if * there was no mapping for `$key`. */ public function putIfAbsent(int | string $key, mixed $value): mixed { $currentValue = $this->get($key); if ($currentValue === null) { $this[$key] = $value; } return $currentValue; } /** * @param K $key The key to remove from the map. * * @return T | null the previous value associated with key, or `null` if * there was no mapping for `$key`. */ public function remove(int | string $key): mixed { $previousValue = $this->get($key); unset($this[$key]); return $previousValue; } public function removeIf(int | string $key, mixed $value): bool { if ($this->get($key) === $value) { unset($this[$key]); return true; } return false; } /** * @param K $key The key to replace. * @param T $value The value to set at `$key`. * * @return T | null the previous value associated with key, or `null` if * there was no mapping for `$key`. */ public function replace(int | string $key, mixed $value): mixed { $currentValue = $this->get($key); if ($this->containsKey($key)) { $this[$key] = $value; } return $currentValue; } public function replaceIf(int | string $key, mixed $oldValue, mixed $newValue): bool { if ($this->get($key) === $oldValue) { $this[$key] = $newValue; return true; } return false; } /** * @return array */ public function __serialize(): array { /** @var array */ return parent::__serialize(); } /** * @return array */ public function toArray(): array { /** @var array */ return parent::toArray(); } } ================================================ FILE: lib/Google/vendor/ramsey/collection/src/Map/AbstractTypedMap.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Collection\Map; use Ramsey\Collection\Exception\InvalidArgumentException; use Ramsey\Collection\Tool\TypeTrait; use Ramsey\Collection\Tool\ValueToStringTrait; /** * This class provides a basic implementation of `TypedMapInterface`, to * minimize the effort required to implement this interface. * * @template K of array-key * @template T * @extends AbstractMap * @implements TypedMapInterface */ abstract class AbstractTypedMap extends AbstractMap implements TypedMapInterface { use TypeTrait; use ValueToStringTrait; /** * @param K $offset * @param T $value * * @inheritDoc */ public function offsetSet(mixed $offset, mixed $value): void { if ($this->checkType($this->getKeyType(), $offset) === false) { throw new InvalidArgumentException( 'Key must be of type ' . $this->getKeyType() . '; key is ' . $this->toolValueToString($offset), ); } if ($this->checkType($this->getValueType(), $value) === false) { throw new InvalidArgumentException( 'Value must be of type ' . $this->getValueType() . '; value is ' . $this->toolValueToString($value), ); } parent::offsetSet($offset, $value); } } ================================================ FILE: lib/Google/vendor/ramsey/collection/src/Map/AssociativeArrayMap.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Collection\Map; /** * `AssociativeArrayMap` represents a standard associative array object. * * @extends AbstractMap */ class AssociativeArrayMap extends AbstractMap { } ================================================ FILE: lib/Google/vendor/ramsey/collection/src/Map/MapInterface.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Collection\Map; use Ramsey\Collection\ArrayInterface; /** * An object that maps keys to values. * * A map cannot contain duplicate keys; each key can map to at most one value. * * @template K of array-key * @template T * @extends ArrayInterface */ interface MapInterface extends ArrayInterface { /** * Returns `true` if this map contains a mapping for the specified key. * * @param K $key The key to check in the map. */ public function containsKey(int | string $key): bool; /** * Returns `true` if this map maps one or more keys to the specified value. * * This performs a strict type check on the value. * * @param T $value The value to check in the map. */ public function containsValue(mixed $value): bool; /** * Return an array of the keys contained in this map. * * @return list */ public function keys(): array; /** * Returns the value to which the specified key is mapped, `null` if this * map contains no mapping for the key, or (optionally) `$defaultValue` if * this map contains no mapping for the key. * * @param K $key The key to return from the map. * @param T | null $defaultValue The default value to use if `$key` is not found. * * @return T | null the value or `null` if the key could not be found. */ public function get(int | string $key, mixed $defaultValue = null): mixed; /** * Associates the specified value with the specified key in this map. * * If the map previously contained a mapping for the key, the old value is * replaced by the specified value. * * @param K $key The key to put or replace in the map. * @param T $value The value to store at `$key`. * * @return T | null the previous value associated with key, or `null` if * there was no mapping for `$key`. */ public function put(int | string $key, mixed $value): mixed; /** * Associates the specified value with the specified key in this map only if * it is not already set. * * If there is already a value associated with `$key`, this returns that * value without replacing it. * * @param K $key The key to put in the map. * @param T $value The value to store at `$key`. * * @return T | null the previous value associated with key, or `null` if * there was no mapping for `$key`. */ public function putIfAbsent(int | string $key, mixed $value): mixed; /** * Removes the mapping for a key from this map if it is present. * * @param K $key The key to remove from the map. * * @return T | null the previous value associated with key, or `null` if * there was no mapping for `$key`. */ public function remove(int | string $key): mixed; /** * Removes the entry for the specified key only if it is currently mapped to * the specified value. * * This performs a strict type check on the value. * * @param K $key The key to remove from the map. * @param T $value The value to match. * * @return bool true if the value was removed. */ public function removeIf(int | string $key, mixed $value): bool; /** * Replaces the entry for the specified key only if it is currently mapped * to some value. * * @param K $key The key to replace. * @param T $value The value to set at `$key`. * * @return T | null the previous value associated with key, or `null` if * there was no mapping for `$key`. */ public function replace(int | string $key, mixed $value): mixed; /** * Replaces the entry for the specified key only if currently mapped to the * specified value. * * This performs a strict type check on the value. * * @param K $key The key to remove from the map. * @param T $oldValue The value to match. * @param T $newValue The value to use as a replacement. * * @return bool true if the value was replaced. */ public function replaceIf(int | string $key, mixed $oldValue, mixed $newValue): bool; } ================================================ FILE: lib/Google/vendor/ramsey/collection/src/Map/NamedParameterMap.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Collection\Map; use Ramsey\Collection\Exception\InvalidArgumentException; use Ramsey\Collection\Tool\TypeTrait; use Ramsey\Collection\Tool\ValueToStringTrait; use function array_combine; use function array_key_exists; use function is_int; /** * `NamedParameterMap` represents a mapping of values to a set of named keys * that may optionally be typed * * @extends AbstractMap */ class NamedParameterMap extends AbstractMap { use TypeTrait; use ValueToStringTrait; /** * Named parameters defined for this map. * * @var array */ private readonly array $namedParameters; /** * Constructs a new `NamedParameterMap`. * * @param array $namedParameters The named parameters defined for this map. * @param array $data An initial set of data to set on this map. */ public function __construct(array $namedParameters, array $data = []) { $this->namedParameters = $this->filterNamedParameters($namedParameters); parent::__construct($data); } /** * Returns named parameters set for this `NamedParameterMap`. * * @return array */ public function getNamedParameters(): array { return $this->namedParameters; } public function offsetSet(mixed $offset, mixed $value): void { if (!array_key_exists($offset, $this->namedParameters)) { throw new InvalidArgumentException( 'Attempting to set value for unconfigured parameter \'' . $this->toolValueToString($offset) . '\'', ); } if ($this->checkType($this->namedParameters[$offset], $value) === false) { throw new InvalidArgumentException( 'Value for \'' . $offset . '\' must be of type ' . $this->namedParameters[$offset] . '; value is ' . $this->toolValueToString($value), ); } $this->data[$offset] = $value; } /** * Given an array of named parameters, constructs a proper mapping of * named parameters to types. * * @param array $namedParameters The named parameters to filter. * * @return array */ protected function filterNamedParameters(array $namedParameters): array { $names = []; $types = []; foreach ($namedParameters as $key => $value) { if (is_int($key)) { $names[] = $value; $types[] = 'mixed'; } else { $names[] = $key; $types[] = $value; } } return array_combine($names, $types) ?: []; } } ================================================ FILE: lib/Google/vendor/ramsey/collection/src/Map/TypedMap.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Collection\Map; /** * A `TypedMap` represents a map of elements where key and value are typed. * * Each element is identified by a key with defined type and a value of defined * type. The keys of the map must be unique. The values on the map can be * repeated but each with its own different key. * * The most common case is to use a string type key, but it's not limited to * this type of keys. * * This is a direct implementation of `TypedMapInterface`, provided for the sake * of convenience. * * Example usage: * * ``` * $map = new TypedMap('string', Foo::class); * $map['x'] = new Foo(); * foreach ($map as $key => $value) { * // do something with $key, it will be a Foo::class * } * * // this will throw an exception since key must be string * $map[10] = new Foo(); * * // this will throw an exception since value must be a Foo * $map['bar'] = 'bar'; * * // initialize map with contents * $map = new TypedMap('string', Foo::class, [ * new Foo(), new Foo(), new Foo() * ]); * ``` * * It is preferable to subclass `AbstractTypedMap` to create your own typed map * implementation: * * ``` * class FooTypedMap extends AbstractTypedMap * { * public function getKeyType() * { * return 'int'; * } * * public function getValueType() * { * return Foo::class; * } * } * ``` * * … but you also may use the `TypedMap` class: * * ``` * class FooTypedMap extends TypedMap * { * public function __constructor(array $data = []) * { * parent::__construct('int', Foo::class, $data); * } * } * ``` * * @template K of array-key * @template T * @extends AbstractTypedMap */ class TypedMap extends AbstractTypedMap { /** * Constructs a map object of the specified key and value types, * optionally with the specified data. * * @param string $keyType The data type of the map's keys. * @param string $valueType The data type of the map's values. * @param array $data The initial data to set for this map. */ public function __construct( private readonly string $keyType, private readonly string $valueType, array $data = [], ) { parent::__construct($data); } public function getKeyType(): string { return $this->keyType; } public function getValueType(): string { return $this->valueType; } } ================================================ FILE: lib/Google/vendor/ramsey/collection/src/Map/TypedMapInterface.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Collection\Map; /** * A `TypedMapInterface` represents a map of elements where key and value are * typed. * * @template K of array-key * @template T * @extends MapInterface */ interface TypedMapInterface extends MapInterface { /** * Return the type used on the key. */ public function getKeyType(): string; /** * Return the type forced on the values. */ public function getValueType(): string; } ================================================ FILE: lib/Google/vendor/ramsey/collection/src/Queue.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Collection; use Ramsey\Collection\Exception\InvalidArgumentException; use Ramsey\Collection\Exception\NoSuchElementException; use Ramsey\Collection\Tool\TypeTrait; use Ramsey\Collection\Tool\ValueToStringTrait; use function array_key_first; /** * This class provides a basic implementation of `QueueInterface`, to minimize * the effort required to implement this interface. * * @template T * @extends AbstractArray * @implements QueueInterface */ class Queue extends AbstractArray implements QueueInterface { use TypeTrait; use ValueToStringTrait; /** * Constructs a queue object of the specified type, optionally with the * specified data. * * @param string $queueType The type or class name associated with this queue. * @param array $data The initial items to store in the queue. */ public function __construct(private readonly string $queueType, array $data = []) { parent::__construct($data); } /** * {@inheritDoc} * * Since arbitrary offsets may not be manipulated in a queue, this method * serves only to fulfill the `ArrayAccess` interface requirements. It is * invoked by other operations when adding values to the queue. * * @throws InvalidArgumentException if $value is of the wrong type. */ public function offsetSet(mixed $offset, mixed $value): void { if ($this->checkType($this->getType(), $value) === false) { throw new InvalidArgumentException( 'Value must be of type ' . $this->getType() . '; value is ' . $this->toolValueToString($value), ); } $this->data[] = $value; } /** * @throws InvalidArgumentException if $value is of the wrong type. */ public function add(mixed $element): bool { $this[] = $element; return true; } /** * @return T * * @throws NoSuchElementException if this queue is empty. */ public function element(): mixed { return $this->peek() ?? throw new NoSuchElementException( 'Can\'t return element from Queue. Queue is empty.', ); } public function offer(mixed $element): bool { try { return $this->add($element); } catch (InvalidArgumentException) { return false; } } /** * @return T | null */ public function peek(): mixed { $index = array_key_first($this->data); if ($index === null) { return null; } return $this[$index]; } /** * @return T | null */ public function poll(): mixed { $index = array_key_first($this->data); if ($index === null) { return null; } $head = $this[$index]; unset($this[$index]); return $head; } /** * @return T * * @throws NoSuchElementException if this queue is empty. */ public function remove(): mixed { return $this->poll() ?? throw new NoSuchElementException( 'Can\'t return element from Queue. Queue is empty.', ); } public function getType(): string { return $this->queueType; } } ================================================ FILE: lib/Google/vendor/ramsey/collection/src/QueueInterface.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Collection; use Ramsey\Collection\Exception\NoSuchElementException; use RuntimeException; /** * A queue is a collection in which the entities in the collection are kept in * order. * * The principal operations on the queue are the addition of entities to the end * (tail), also known as *enqueue*, and removal of entities from the front * (head), also known as *dequeue*. This makes the queue a first-in-first-out * (FIFO) data structure. * * Besides basic array operations, queues provide additional insertion, * extraction, and inspection operations. Each of these methods exists in two * forms: one throws an exception if the operation fails, the other returns a * special value (either `null` or `false`, depending on the operation). The * latter form of the insert operation is designed specifically for use with * capacity-restricted `QueueInterface` implementations; in most * implementations, insert operations cannot fail. * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Summary of QueueInterface methods
Throws exceptionReturns special value
Insertadd()offer()
Removeremove()poll()
Examineelement()peek()
* * Queues typically, but do not necessarily, order elements in a FIFO * (first-in-first-out) manner. Among the exceptions are priority queues, which * order elements according to a supplied comparator, or the elements' natural * ordering, and LIFO queues (or stacks) which order the elements LIFO * (last-in-first-out). Whatever the ordering used, the head of the queue is * that element which would be removed by a call to remove() or poll(). In a * FIFO queue, all new elements are inserted at the tail of the queue. Other * kinds of queues may use different placement rules. Every `QueueInterface` * implementation must specify its ordering properties. * * The `offer()` method inserts an element if possible, otherwise returning * `false`. This differs from the `add()` method, which can fail to add an * element only by throwing an unchecked exception. The `offer()` method is * designed for use when failure is a normal, rather than exceptional * occurrence, for example, in fixed-capacity (or "bounded") queues. * * The `remove()` and `poll()` methods remove and return the head of the queue. * Exactly which element is removed from the queue is a function of the queue's * ordering policy, which differs from implementation to implementation. The * `remove()` and `poll()` methods differ only in their behavior when the queue * is empty: the `remove()` method throws an exception, while the `poll()` * method returns `null`. * * The `element()` and `peek()` methods return, but do not remove, the head of * the queue. * * `QueueInterface` implementations generally do not allow insertion of `null` * elements, although some implementations do not prohibit insertion of `null`. * Even in the implementations that permit it, `null` should not be inserted * into a queue, as `null` is also used as a special return value by the * `poll()` method to indicate that the queue contains no elements. * * @template T * @extends ArrayInterface */ interface QueueInterface extends ArrayInterface { /** * Ensures that this queue contains the specified element (optional * operation). * * Returns `true` if this queue changed as a result of the call. (Returns * `false` if this queue does not permit duplicates and already contains the * specified element.) * * Queues that support this operation may place limitations on what elements * may be added to this queue. In particular, some queues will refuse to add * `null` elements, and others will impose restrictions on the type of * elements that may be added. Queue classes should clearly specify in their * documentation any restrictions on what elements may be added. * * If a queue refuses to add a particular element for any reason other than * that it already contains the element, it must throw an exception (rather * than returning `false`). This preserves the invariant that a queue always * contains the specified element after this call returns. * * @see self::offer() * * @param T $element The element to add to this queue. * * @return bool `true` if this queue changed as a result of the call. * * @throws RuntimeException if a queue refuses to add a particular element * for any reason other than that it already contains the element. * Implementations should use a more-specific exception that extends * `\RuntimeException`. */ public function add(mixed $element): bool; /** * Retrieves, but does not remove, the head of this queue. * * This method differs from `peek()` only in that it throws an exception if * this queue is empty. * * @see self::peek() * * @return T the head of this queue. * * @throws NoSuchElementException if this queue is empty. */ public function element(): mixed; /** * Inserts the specified element into this queue if it is possible to do so * immediately without violating capacity restrictions. * * When using a capacity-restricted queue, this method is generally * preferable to `add()`, which can fail to insert an element only by * throwing an exception. * * @see self::add() * * @param T $element The element to add to this queue. * * @return bool `true` if the element was added to this queue, else `false`. */ public function offer(mixed $element): bool; /** * Retrieves, but does not remove, the head of this queue, or returns `null` * if this queue is empty. * * @see self::element() * * @return T | null the head of this queue, or `null` if this queue is empty. */ public function peek(): mixed; /** * Retrieves and removes the head of this queue, or returns `null` * if this queue is empty. * * @see self::remove() * * @return T | null the head of this queue, or `null` if this queue is empty. */ public function poll(): mixed; /** * Retrieves and removes the head of this queue. * * This method differs from `poll()` only in that it throws an exception if * this queue is empty. * * @see self::poll() * * @return T the head of this queue. * * @throws NoSuchElementException if this queue is empty. */ public function remove(): mixed; /** * Returns the type associated with this queue. */ public function getType(): string; } ================================================ FILE: lib/Google/vendor/ramsey/collection/src/Set.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Collection; /** * A set is a collection that contains no duplicate elements. * * Great care must be exercised if mutable objects are used as set elements. * The behavior of a set is not specified if the value of an object is changed * in a manner that affects equals comparisons while the object is an element in * the set. * * Example usage: * * ``` * $foo = new \My\Foo(); * $set = new Set(\My\Foo::class); * * $set->add($foo); // returns TRUE, the element doesn't exist * $set->add($foo); // returns FALSE, the element already exists * * $bar = new \My\Foo(); * $set->add($bar); // returns TRUE, $bar !== $foo * ``` * * @template T * @extends AbstractSet */ class Set extends AbstractSet { /** * Constructs a set object of the specified type, optionally with the * specified data. * * @param string $setType The type or class name associated with this set. * @param array $data The initial items to store in the set. */ public function __construct(private readonly string $setType, array $data = []) { parent::__construct($data); } public function getType(): string { return $this->setType; } } ================================================ FILE: lib/Google/vendor/ramsey/collection/src/Sort.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Collection; /** * Collection sorting */ enum Sort: string { /** * Sort items in a collection in ascending order. */ case Ascending = 'asc'; /** * Sort items in a collection in descending order. */ case Descending = 'desc'; } ================================================ FILE: lib/Google/vendor/ramsey/collection/src/Tool/TypeTrait.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Collection\Tool; use function is_array; use function is_bool; use function is_callable; use function is_float; use function is_int; use function is_numeric; use function is_object; use function is_resource; use function is_scalar; use function is_string; /** * Provides functionality to check values for specific types. */ trait TypeTrait { /** * Returns `true` if value is of the specified type. * * @param string $type The type to check the value against. * @param mixed $value The value to check. */ protected function checkType(string $type, mixed $value): bool { return match ($type) { 'array' => is_array($value), 'bool', 'boolean' => is_bool($value), 'callable' => is_callable($value), 'float', 'double' => is_float($value), 'int', 'integer' => is_int($value), 'null' => $value === null, 'numeric' => is_numeric($value), 'object' => is_object($value), 'resource' => is_resource($value), 'scalar' => is_scalar($value), 'string' => is_string($value), 'mixed' => true, default => $value instanceof $type, }; } } ================================================ FILE: lib/Google/vendor/ramsey/collection/src/Tool/ValueExtractorTrait.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Collection\Tool; use Ramsey\Collection\Exception\InvalidPropertyOrMethod; use Ramsey\Collection\Exception\UnsupportedOperationException; use ReflectionProperty; use function is_array; use function is_object; use function method_exists; use function property_exists; use function sprintf; /** * Provides functionality to extract the value of a property or method from an object. */ trait ValueExtractorTrait { /** * Returns the type associated with this collection. */ abstract public function getType(): string; /** * Extracts the value of the given property, method, or array key from the * element. * * If `$propertyOrMethod` is `null`, we return the element as-is. * * @param mixed $element The element to extract the value from. * @param string | null $propertyOrMethod The property or method for which the * value should be extracted. * * @return mixed the value extracted from the specified property, method, * or array key, or the element itself. * * @throws InvalidPropertyOrMethod * @throws UnsupportedOperationException */ protected function extractValue(mixed $element, ?string $propertyOrMethod): mixed { if ($propertyOrMethod === null) { return $element; } if (!is_object($element) && !is_array($element)) { throw new UnsupportedOperationException(sprintf( 'The collection type "%s" does not support the $propertyOrMethod parameter', $this->getType(), )); } if (is_array($element)) { return $element[$propertyOrMethod] ?? throw new InvalidPropertyOrMethod(sprintf( 'Key or index "%s" not found in collection elements', $propertyOrMethod, )); } if (property_exists($element, $propertyOrMethod) && method_exists($element, $propertyOrMethod)) { $reflectionProperty = new ReflectionProperty($element, $propertyOrMethod); if ($reflectionProperty->isPublic()) { return $element->$propertyOrMethod; } return $element->{$propertyOrMethod}(); } if (property_exists($element, $propertyOrMethod)) { return $element->$propertyOrMethod; } if (method_exists($element, $propertyOrMethod)) { return $element->{$propertyOrMethod}(); } if (isset($element->$propertyOrMethod)) { return $element->$propertyOrMethod; } throw new InvalidPropertyOrMethod(sprintf( 'Method or property "%s" not defined in %s', $propertyOrMethod, $element::class, )); } } ================================================ FILE: lib/Google/vendor/ramsey/collection/src/Tool/ValueToStringTrait.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Collection\Tool; use DateTimeInterface; use function assert; use function get_resource_type; use function is_array; use function is_bool; use function is_callable; use function is_object; use function is_resource; use function is_scalar; /** * Provides functionality to express a value as string */ trait ValueToStringTrait { /** * Returns a string representation of the value. * * - null value: `'NULL'` * - boolean: `'TRUE'`, `'FALSE'` * - array: `'Array'` * - scalar: converted-value * - resource: `'(type resource #number)'` * - object with `__toString()`: result of `__toString()` * - object DateTime: ISO 8601 date * - object: `'(className Object)'` * - anonymous function: same as object * * @param mixed $value the value to return as a string. */ protected function toolValueToString(mixed $value): string { // null if ($value === null) { return 'NULL'; } // boolean constants if (is_bool($value)) { return $value ? 'TRUE' : 'FALSE'; } // array if (is_array($value)) { return 'Array'; } // scalar types (integer, float, string) if (is_scalar($value)) { return (string) $value; } // resource if (is_resource($value)) { return '(' . get_resource_type($value) . ' resource #' . (int) $value . ')'; } // From here, $value should be an object. assert(is_object($value)); // __toString() is implemented if (is_callable([$value, '__toString'])) { /** @var string */ return $value->__toString(); } // object of type \DateTime if ($value instanceof DateTimeInterface) { return $value->format('c'); } // unknown type return '(' . $value::class . ' Object)'; } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/LICENSE ================================================ Copyright (c) 2012-2025 Ben Ramsey 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. ================================================ FILE: lib/Google/vendor/ramsey/uuid/README.md ================================================

ramsey/uuid

A PHP library for generating and working with UUIDs.

Source Code Download Package PHP Programming Language Read License Build Status Codecov Code Coverage

ramsey/uuid is a PHP library for generating and working with universally unique identifiers (UUIDs). This project adheres to a [code of conduct](CODE_OF_CONDUCT.md). By participating in this project and its community, you are expected to uphold this code. Much inspiration for this library came from the [Java][javauuid] and [Python][pyuuid] UUID libraries. ## Installation The preferred method of installation is via [Composer][]. Run the following command to install the package and add it as a requirement to your project's `composer.json`: ```bash composer require ramsey/uuid ``` ## Upgrading to Version 4 See the documentation for a thorough upgrade guide: * [Upgrading ramsey/uuid Version 3 to 4](https://uuid.ramsey.dev/en/stable/upgrading/3-to-4.html) ## Documentation Please see for documentation, tips, examples, and frequently asked questions. ## Contributing Contributions are welcome! To contribute, please familiarize yourself with [CONTRIBUTING.md](CONTRIBUTING.md). ## Coordinated Disclosure Keeping user information safe and secure is a top priority, and we welcome the contribution of external security researchers. If you believe you've found a security issue in software that is maintained in this repository, please read [SECURITY.md][] for instructions on submitting a vulnerability report. ## ramsey/uuid for Enterprise Available as part of the Tidelift Subscription. The maintainers of ramsey/uuid and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source packages you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact packages you use. [Learn more.](https://tidelift.com/subscription/pkg/packagist-ramsey-uuid?utm_source=undefined&utm_medium=referral&utm_campaign=enterprise&utm_term=repo) ## Copyright and License The ramsey/uuid library is copyright © [Ben Ramsey](https://benramsey.com/) and licensed for use under the MIT License (MIT). Please see [LICENSE][] for more information. [rfc4122]: http://tools.ietf.org/html/rfc4122 [conduct]: https://github.com/ramsey/uuid/blob/4.x/CODE_OF_CONDUCT.md [javauuid]: http://docs.oracle.com/javase/6/docs/api/java/util/UUID.html [pyuuid]: http://docs.python.org/3/library/uuid.html [composer]: http://getcomposer.org/ [contributing.md]: https://github.com/ramsey/uuid/blob/4.x/CONTRIBUTING.md [security.md]: https://github.com/ramsey/uuid/blob/4.x/SECURITY.md [license]: https://github.com/ramsey/uuid/blob/4.x/LICENSE ================================================ FILE: lib/Google/vendor/ramsey/uuid/composer.json ================================================ { "name": "ramsey/uuid", "description": "A PHP library for generating and working with universally unique identifiers (UUIDs).", "license": "MIT", "type": "library", "keywords": [ "uuid", "identifier", "guid" ], "require": { "php": "^8.0", "brick/math": "^0.8.16 || ^0.9 || ^0.10 || ^0.11 || ^0.12 || ^0.13 || ^0.14", "ramsey/collection": "^1.2 || ^2.0" }, "require-dev": { "captainhook/captainhook": "^5.25", "captainhook/plugin-composer": "^5.3", "dealerdirect/phpcodesniffer-composer-installer": "^1.0", "ergebnis/composer-normalize": "^2.47", "mockery/mockery": "^1.6", "paragonie/random-lib": "^2", "php-mock/php-mock": "^2.6", "php-mock/php-mock-mockery": "^1.5", "php-parallel-lint/php-parallel-lint": "^1.4.0", "phpbench/phpbench": "^1.2.14", "phpstan/extension-installer": "^1.4", "phpstan/phpstan": "^2.1", "phpstan/phpstan-mockery": "^2.0", "phpstan/phpstan-phpunit": "^2.0", "phpunit/phpunit": "^9.6", "slevomat/coding-standard": "^8.18", "squizlabs/php_codesniffer": "^3.13" }, "replace": { "rhumsaa/uuid": "self.version" }, "suggest": { "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", "ext-gmp": "Enables faster math with arbitrary-precision integers using GMP.", "ext-uuid": "Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.", "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." }, "minimum-stability": "dev", "prefer-stable": true, "autoload": { "psr-4": { "Ramsey\\Uuid\\": "src/" }, "files": [ "src/functions.php" ] }, "autoload-dev": { "psr-4": { "Ramsey\\Uuid\\Benchmark\\": "tests/benchmark/", "Ramsey\\Uuid\\StaticAnalysis\\": "tests/static-analysis/", "Ramsey\\Uuid\\Test\\": "tests/" } }, "config": { "allow-plugins": { "captainhook/plugin-composer": true, "dealerdirect/phpcodesniffer-composer-installer": true, "ergebnis/composer-normalize": true, "phpstan/extension-installer": true }, "sort-packages": true }, "extra": { "captainhook": { "force-install": true } }, "scripts": { "dev:analyze": "@dev:analyze:phpstan", "dev:analyze:phpstan": "phpstan analyse --ansi --memory-limit 1G", "dev:bench": "@php -d 'error_reporting=24575' vendor/bin/phpbench run", "dev:build:clean": "git clean -fX build/", "dev:lint": [ "@dev:lint:syntax", "@dev:lint:style" ], "dev:lint:fix": "phpcbf --cache=build/cache/phpcs.cache", "dev:lint:style": "phpcs --cache=build/cache/phpcs.cache --colors", "dev:lint:syntax": "parallel-lint --colors src/ tests/", "dev:test": [ "@dev:lint", "@dev:bench", "@dev:analyze", "@dev:test:unit" ], "dev:test:coverage:ci": "@php -d 'xdebug.mode=coverage' vendor/bin/phpunit --colors=always --coverage-text --coverage-clover build/coverage/clover.xml --coverage-cobertura build/coverage/cobertura.xml --coverage-crap4j build/coverage/crap4j.xml --coverage-xml build/coverage/coverage-xml --log-junit build/junit.xml", "dev:test:coverage:html": "@php -d 'xdebug.mode=coverage' vendor/bin/phpunit --colors=always --coverage-html build/coverage/coverage-html/", "dev:test:unit": "phpunit --colors=always", "test": "@dev:test" }, "scripts-descriptions": { "dev:analyze": "Runs all static analysis checks.", "dev:analyze:phpstan": "Runs the PHPStan static analyzer.", "dev:bench": "Runs PHPBench benchmark tests.", "dev:build:clean": "Cleans the build/ directory.", "dev:lint": "Runs all linting checks.", "dev:lint:fix": "Auto-fixes coding standards issues, if possible.", "dev:lint:style": "Checks for coding standards issues.", "dev:lint:syntax": "Checks for syntax errors.", "dev:test": "Runs linting, static analysis, and unit tests.", "dev:test:coverage:ci": "Runs unit tests and generates CI coverage reports.", "dev:test:coverage:html": "Runs unit tests and generates HTML coverage report.", "dev:test:unit": "Runs unit tests.", "test": "Runs linting, static analysis, and unit tests." } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/BinaryUtils.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid; /** * Provides binary math utilities */ class BinaryUtils { /** * Applies the variant field to the 16-bit clock sequence * * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.1 RFC 9562, 4.1. Variant Field * * @param int $clockSeq The 16-bit clock sequence value before the variant is applied * * @return int The 16-bit clock sequence multiplexed with the UUID variant * * @pure */ public static function applyVariant(int $clockSeq): int { return ($clockSeq & 0x3fff) | 0x8000; } /** * Applies the version field to the 16-bit `time_hi_and_version` field * * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.2 RFC 9562, 4.2. Version Field * * @param int $timeHi The value of the 16-bit `time_hi_and_version` field before the version is applied * @param int $version The version to apply to the `time_hi` field * * @return int The 16-bit time_hi field of the timestamp multiplexed with the UUID version number * * @pure */ public static function applyVersion(int $timeHi, int $version): int { return ($timeHi & 0x0fff) | ($version << 12); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Builder/BuilderCollection.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Builder; use Ramsey\Collection\AbstractCollection; use Ramsey\Uuid\Converter\Number\GenericNumberConverter; use Ramsey\Uuid\Converter\Time\GenericTimeConverter; use Ramsey\Uuid\Converter\Time\PhpTimeConverter; use Ramsey\Uuid\Guid\GuidBuilder; use Ramsey\Uuid\Math\BrickMathCalculator; use Ramsey\Uuid\Nonstandard\UuidBuilder as NonstandardUuidBuilder; use Ramsey\Uuid\Rfc4122\UuidBuilder as Rfc4122UuidBuilder; use Traversable; /** * A collection of UuidBuilderInterface objects * * @deprecated this class has been deprecated and will be removed in 5.0.0. The use-case for this class comes from a * pre-`phpstan/phpstan` and pre-`vimeo/psalm` ecosystem, in which type safety had to be mostly enforced at runtime: * that is no longer necessary, now that you can safely verify your code to be correct, and use more generic types * like `iterable` instead. * * @extends AbstractCollection */ class BuilderCollection extends AbstractCollection { public function getType(): string { return UuidBuilderInterface::class; } public function getIterator(): Traversable { return parent::getIterator(); } /** * Re-constructs the object from its serialized form * * @param string $serialized The serialized PHP string to unserialize into a UuidInterface instance */ public function unserialize($serialized): void { /** @var array $data */ $data = unserialize($serialized, [ 'allowed_classes' => [ BrickMathCalculator::class, GenericNumberConverter::class, GenericTimeConverter::class, GuidBuilder::class, NonstandardUuidBuilder::class, PhpTimeConverter::class, Rfc4122UuidBuilder::class, ], ]); $this->data = array_filter( $data, function ($unserialized): bool { /** @phpstan-ignore instanceof.alwaysTrue */ return $unserialized instanceof UuidBuilderInterface; }, ); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Builder/DefaultUuidBuilder.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Builder; use Ramsey\Uuid\Rfc4122\UuidBuilder as Rfc4122UuidBuilder; /** * @deprecated Please transition to {@see Rfc4122UuidBuilder}. * * @immutable */ class DefaultUuidBuilder extends Rfc4122UuidBuilder { } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Builder/DegradedUuidBuilder.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Builder; use Ramsey\Uuid\Codec\CodecInterface; use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Converter\Time\DegradedTimeConverter; use Ramsey\Uuid\Converter\TimeConverterInterface; use Ramsey\Uuid\DegradedUuid; use Ramsey\Uuid\Rfc4122\Fields as Rfc4122Fields; use Ramsey\Uuid\UuidInterface; /** * @deprecated DegradedUuid instances are no longer necessary to support 32-bit systems. Please transition to {@see DefaultUuidBuilder}. * * @immutable */ class DegradedUuidBuilder implements UuidBuilderInterface { private TimeConverterInterface $timeConverter; /** * @param NumberConverterInterface $numberConverter The number converter to use when constructing the DegradedUuid * @param TimeConverterInterface|null $timeConverter The time converter to use for converting timestamps extracted * from a UUID to Unix timestamps */ public function __construct( private NumberConverterInterface $numberConverter, ?TimeConverterInterface $timeConverter = null ) { $this->timeConverter = $timeConverter ?: new DegradedTimeConverter(); } /** * Builds and returns a DegradedUuid * * @param CodecInterface $codec The codec to use for building this DegradedUuid instance * @param string $bytes The byte string from which to construct a UUID * * @return DegradedUuid The DegradedUuidBuild returns an instance of Ramsey\Uuid\DegradedUuid * * @phpstan-impure */ public function build(CodecInterface $codec, string $bytes): UuidInterface { return new DegradedUuid(new Rfc4122Fields($bytes), $this->numberConverter, $codec, $this->timeConverter); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Builder/FallbackBuilder.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Builder; use Ramsey\Uuid\Codec\CodecInterface; use Ramsey\Uuid\Exception\BuilderNotFoundException; use Ramsey\Uuid\Exception\UnableToBuildUuidException; use Ramsey\Uuid\UuidInterface; /** * FallbackBuilder builds a UUID by stepping through a list of UUID builders until a UUID can be constructed without exceptions * * @immutable */ class FallbackBuilder implements UuidBuilderInterface { /** * @param iterable $builders An array of UUID builders */ public function __construct(private iterable $builders) { } /** * Builds and returns a UuidInterface instance using the first builder that succeeds * * @param CodecInterface $codec The codec to use for building this instance * @param string $bytes The byte string from which to construct a UUID * * @return UuidInterface an instance of a UUID object * * @pure */ public function build(CodecInterface $codec, string $bytes): UuidInterface { $lastBuilderException = null; foreach ($this->builders as $builder) { try { return $builder->build($codec, $bytes); } catch (UnableToBuildUuidException $exception) { $lastBuilderException = $exception; continue; } } throw new BuilderNotFoundException( 'Could not find a suitable builder for the provided codec and fields', 0, $lastBuilderException, ); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Builder/UuidBuilderInterface.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Builder; use Ramsey\Uuid\Codec\CodecInterface; use Ramsey\Uuid\UuidInterface; /** * A UUID builder builds instances of UuidInterface * * @immutable */ interface UuidBuilderInterface { /** * Builds and returns a UuidInterface * * @param CodecInterface $codec The codec to use for building this UuidInterface instance * @param string $bytes The byte string from which to construct a UUID * * @return UuidInterface Implementations may choose to return more specific instances of UUIDs that implement UuidInterface * * @pure */ public function build(CodecInterface $codec, string $bytes): UuidInterface; } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Codec/CodecInterface.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Codec; use Ramsey\Uuid\UuidInterface; /** * A codec encodes and decodes a UUID according to defined rules * * @immutable */ interface CodecInterface { /** * Returns a hexadecimal string representation of a UuidInterface * * @param UuidInterface $uuid The UUID for which to create a hexadecimal string representation * * @return non-empty-string Hexadecimal string representation of a UUID * * @pure */ public function encode(UuidInterface $uuid): string; /** * Returns a binary string representation of a UuidInterface * * @param UuidInterface $uuid The UUID for which to create a binary string representation * * @return non-empty-string Binary string representation of a UUID * * @pure */ public function encodeBinary(UuidInterface $uuid): string; /** * Returns a UuidInterface derived from a hexadecimal string representation * * @param string $encodedUuid The hexadecimal string representation to convert into a UuidInterface instance * * @return UuidInterface An instance of a UUID decoded from a hexadecimal string representation * * @pure */ public function decode(string $encodedUuid): UuidInterface; /** * Returns a UuidInterface derived from a binary string representation * * @param string $bytes The binary string representation to convert into a UuidInterface instance * * @return UuidInterface An instance of a UUID decoded from a binary string representation * * @pure */ public function decodeBytes(string $bytes): UuidInterface; } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Codec/GuidStringCodec.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Codec; use Ramsey\Uuid\Guid\Guid; use Ramsey\Uuid\UuidInterface; use function bin2hex; use function sprintf; use function substr; /** * GuidStringCodec encodes and decodes globally unique identifiers (GUID) * * @see Guid * * @immutable */ class GuidStringCodec extends StringCodec { public function encode(UuidInterface $uuid): string { /** @phpstan-ignore possiblyImpure.methodCall */ $hex = bin2hex($uuid->getFields()->getBytes()); /** @var non-empty-string */ return sprintf( '%02s%02s%02s%02s-%02s%02s-%02s%02s-%04s-%012s', substr($hex, 6, 2), substr($hex, 4, 2), substr($hex, 2, 2), substr($hex, 0, 2), substr($hex, 10, 2), substr($hex, 8, 2), substr($hex, 14, 2), substr($hex, 12, 2), substr($hex, 16, 4), substr($hex, 20), ); } public function decode(string $encodedUuid): UuidInterface { /** @phpstan-ignore possiblyImpure.methodCall */ $bytes = $this->getBytes($encodedUuid); /** @phpstan-ignore possiblyImpure.methodCall, possiblyImpure.methodCall */ return $this->getBuilder()->build($this, $this->swapBytes($bytes)); } public function decodeBytes(string $bytes): UuidInterface { // Call parent::decode() to preserve the correct byte order. return parent::decode(bin2hex($bytes)); } /** * Swaps bytes according to the GUID rules */ private function swapBytes(string $bytes): string { return $bytes[3] . $bytes[2] . $bytes[1] . $bytes[0] . $bytes[5] . $bytes[4] . $bytes[7] . $bytes[6] . substr($bytes, 8); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Codec/OrderedTimeCodec.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Codec; use Ramsey\Uuid\Exception\InvalidArgumentException; use Ramsey\Uuid\Exception\UnsupportedOperationException; use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; use Ramsey\Uuid\Uuid; use Ramsey\Uuid\UuidInterface; use function strlen; use function substr; /** * OrderedTimeCodec encodes and decodes a UUID, optimizing the byte order for more efficient storage * * For binary representations of version 1 UUID, this codec may be used to reorganize the time fields, making the UUID * closer to sequential when storing the bytes. According to Percona, this optimization can improve database INSERT and * SELECT statements using the UUID column as a key. * * The string representation of the UUID will remain unchanged. Only the binary representation is reordered. * * PLEASE NOTE: Binary representations of UUIDs encoded with this codec must be decoded with this codec. Decoding using * another codec can result in malformed UUIDs. * * @deprecated Please migrate to {@link https://uuid.ramsey.dev/en/stable/rfc4122/version6.html Version 6, reordered time-based UUIDs}. * * @link https://www.percona.com/blog/2014/12/19/store-uuid-optimized-way/ Storing UUID Values in MySQL * * @immutable */ class OrderedTimeCodec extends StringCodec { /** * Returns a binary string representation of a UUID, with the timestamp fields rearranged for optimized storage * * @return non-empty-string */ public function encodeBinary(UuidInterface $uuid): string { if ( /** @phpstan-ignore possiblyImpure.methodCall */ !($uuid->getFields() instanceof Rfc4122FieldsInterface) /** @phpstan-ignore possiblyImpure.methodCall */ || $uuid->getFields()->getVersion() !== Uuid::UUID_TYPE_TIME ) { throw new InvalidArgumentException('Expected version 1 (time-based) UUID'); } /** @phpstan-ignore possiblyImpure.methodCall */ $bytes = $uuid->getFields()->getBytes(); return $bytes[6] . $bytes[7] . $bytes[4] . $bytes[5] . $bytes[0] . $bytes[1] . $bytes[2] . $bytes[3] . substr($bytes, 8); } /** * Returns a UuidInterface derived from an ordered-time binary string representation * * @throws InvalidArgumentException if $bytes is an invalid length * * @inheritDoc */ public function decodeBytes(string $bytes): UuidInterface { if (strlen($bytes) !== 16) { throw new InvalidArgumentException('$bytes string should contain 16 characters.'); } // Rearrange the bytes to their original order. $rearrangedBytes = $bytes[4] . $bytes[5] . $bytes[6] . $bytes[7] . $bytes[2] . $bytes[3] . $bytes[0] . $bytes[1] . substr($bytes, 8); $uuid = parent::decodeBytes($rearrangedBytes); /** @phpstan-ignore possiblyImpure.methodCall */ $fields = $uuid->getFields(); if (!$fields instanceof Rfc4122FieldsInterface || $fields->getVersion() !== Uuid::UUID_TYPE_TIME) { throw new UnsupportedOperationException( 'Attempting to decode a non-time-based UUID using OrderedTimeCodec', ); } return $uuid; } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Codec/StringCodec.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Codec; use Ramsey\Uuid\Builder\UuidBuilderInterface; use Ramsey\Uuid\Exception\InvalidArgumentException; use Ramsey\Uuid\Exception\InvalidUuidStringException; use Ramsey\Uuid\Uuid; use Ramsey\Uuid\UuidInterface; use function bin2hex; use function hex2bin; use function implode; use function sprintf; use function str_replace; use function strlen; use function substr; /** * StringCodec encodes and decodes RFC 9562 (formerly RFC 4122) UUIDs * * @immutable */ class StringCodec implements CodecInterface { /** * Constructs a StringCodec * * @param UuidBuilderInterface $builder The builder to use when encoding UUIDs */ public function __construct(private UuidBuilderInterface $builder) { } public function encode(UuidInterface $uuid): string { /** @phpstan-ignore possiblyImpure.methodCall */ $hex = bin2hex($uuid->getFields()->getBytes()); /** @var non-empty-string */ return sprintf( '%08s-%04s-%04s-%04s-%012s', substr($hex, 0, 8), substr($hex, 8, 4), substr($hex, 12, 4), substr($hex, 16, 4), substr($hex, 20), ); } /** * @return non-empty-string */ public function encodeBinary(UuidInterface $uuid): string { /** @phpstan-ignore-next-line PHPStan complains that this is not a non-empty-string. */ return $uuid->getFields()->getBytes(); } /** * @throws InvalidUuidStringException * * @inheritDoc */ public function decode(string $encodedUuid): UuidInterface { /** @phpstan-ignore possiblyImpure.methodCall */ return $this->builder->build($this, $this->getBytes($encodedUuid)); } public function decodeBytes(string $bytes): UuidInterface { if (strlen($bytes) !== 16) { throw new InvalidArgumentException('$bytes string should contain 16 characters.'); } return $this->builder->build($this, $bytes); } /** * Returns the UUID builder */ protected function getBuilder(): UuidBuilderInterface { return $this->builder; } /** * Returns a byte string of the UUID */ protected function getBytes(string $encodedUuid): string { $parsedUuid = str_replace(['urn:', 'uuid:', 'URN:', 'UUID:', '{', '}', '-'], '', $encodedUuid); $components = [ substr($parsedUuid, 0, 8), substr($parsedUuid, 8, 4), substr($parsedUuid, 12, 4), substr($parsedUuid, 16, 4), substr($parsedUuid, 20), ]; if (!Uuid::isValid(implode('-', $components))) { throw new InvalidUuidStringException('Invalid UUID string: ' . $encodedUuid); } return (string) hex2bin($parsedUuid); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Codec/TimestampFirstCombCodec.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Codec; use Ramsey\Uuid\Exception\InvalidUuidStringException; use Ramsey\Uuid\UuidInterface; use function bin2hex; use function sprintf; use function substr; use function substr_replace; /** * TimestampFirstCombCodec encodes and decodes COMBs, with the timestamp as the first 48 bits * * In contrast with the TimestampLastCombCodec, the TimestampFirstCombCodec adds the timestamp to the first 48 bits of * the COMB. To generate a timestamp-first COMB, set the TimestampFirstCombCodec as the codec, along with the * CombGenerator as the random generator. * * ``` * $factory = new UuidFactory(); * * $factory->setCodec(new TimestampFirstCombCodec($factory->getUuidBuilder())); * * $factory->setRandomGenerator(new CombGenerator( * $factory->getRandomGenerator(), * $factory->getNumberConverter(), * )); * * $timestampFirstComb = $factory->uuid4(); * ``` * * @deprecated Please migrate to {@link https://uuid.ramsey.dev/en/stable/rfc4122/version7.html Version 7, Unix Epoch Time UUIDs}. * * @link https://web.archive.org/web/20240118030355/https://www.informit.com/articles/printerfriendly/25862 The Cost of GUIDs as Primary Keys * * @immutable */ class TimestampFirstCombCodec extends StringCodec { /** * @return non-empty-string */ public function encode(UuidInterface $uuid): string { /** @phpstan-ignore possiblyImpure.methodCall */ $bytes = $this->swapBytes($uuid->getFields()->getBytes()); return sprintf( '%08s-%04s-%04s-%04s-%012s', bin2hex(substr($bytes, 0, 4)), bin2hex(substr($bytes, 4, 2)), bin2hex(substr($bytes, 6, 2)), bin2hex(substr($bytes, 8, 2)), bin2hex(substr($bytes, 10)) ); } /** * @return non-empty-string */ public function encodeBinary(UuidInterface $uuid): string { /** @phpstan-ignore-next-line PHPStan complains that this is not a non-empty-string. */ return $this->swapBytes($uuid->getFields()->getBytes()); } /** * @throws InvalidUuidStringException * * @inheritDoc */ public function decode(string $encodedUuid): UuidInterface { /** @phpstan-ignore possiblyImpure.methodCall */ $bytes = $this->getBytes($encodedUuid); /** @phpstan-ignore possiblyImpure.methodCall */ return $this->getBuilder()->build($this, $this->swapBytes($bytes)); } public function decodeBytes(string $bytes): UuidInterface { /** @phpstan-ignore possiblyImpure.methodCall */ return $this->getBuilder()->build($this, $this->swapBytes($bytes)); } /** * Swaps bytes according to the timestamp-first COMB rules * * @pure */ private function swapBytes(string $bytes): string { $first48Bits = substr($bytes, 0, 6); $last48Bits = substr($bytes, -6); return substr_replace(substr_replace($bytes, $last48Bits, 0, 6), $first48Bits, -6); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Codec/TimestampLastCombCodec.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Codec; /** * TimestampLastCombCodec encodes and decodes COMBs, with the timestamp as the last 48 bits * * The CombGenerator when used with the StringCodec (and, by proxy, the TimestampLastCombCodec) adds the timestamp to * the last 48 bits of the COMB. The TimestampLastCombCodec is provided for the sake of consistency. In practice, it is * identical to the standard StringCodec, but it may be used with the CombGenerator for additional context when reading * code. * * Consider the following code. By default, the codec used by UuidFactory is the StringCodec, but here, we explicitly * set the TimestampLastCombCodec. It is redundant, but it is clear that we intend this COMB to be generated with the * timestamp appearing at the end. * * ``` * $factory = new UuidFactory(); * * $factory->setCodec(new TimestampLastCombCodec($factory->getUuidBuilder())); * * $factory->setRandomGenerator(new CombGenerator( * $factory->getRandomGenerator(), * $factory->getNumberConverter(), * )); * * $timestampLastComb = $factory->uuid4(); * ``` * * @deprecated Please use {@see StringCodec} instead. * * @immutable */ class TimestampLastCombCodec extends StringCodec { } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Converter/Number/BigNumberConverter.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Converter\Number; use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Math\BrickMathCalculator; /** * Previously used to integrate moontoast/math as a bignum arithmetic library, BigNumberConverter is deprecated in favor * of GenericNumberConverter * * @deprecated Please transition to {@see GenericNumberConverter}. * * @immutable */ class BigNumberConverter implements NumberConverterInterface { private NumberConverterInterface $converter; public function __construct() { $this->converter = new GenericNumberConverter(new BrickMathCalculator()); } /** * @pure */ public function fromHex(string $hex): string { return $this->converter->fromHex($hex); } /** * @pure */ public function toHex(string $number): string { return $this->converter->toHex($number); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Converter/Number/DegradedNumberConverter.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Converter\Number; /** * @deprecated DegradedNumberConverter is no longer necessary for converting numbers on 32-bit systems. Please * transition to {@see GenericNumberConverter}. * * @immutable */ class DegradedNumberConverter extends BigNumberConverter { } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Converter/Number/GenericNumberConverter.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Converter\Number; use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Math\CalculatorInterface; use Ramsey\Uuid\Type\Integer as IntegerObject; /** * GenericNumberConverter uses the provided calculator to convert decimal numbers to and from hexadecimal values * * @immutable */ class GenericNumberConverter implements NumberConverterInterface { public function __construct(private CalculatorInterface $calculator) { } /** * @pure */ public function fromHex(string $hex): string { return $this->calculator->fromBase($hex, 16)->toString(); } /** * @pure */ public function toHex(string $number): string { /** @phpstan-ignore return.type, possiblyImpure.new */ return $this->calculator->toBase(new IntegerObject($number), 16); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Converter/NumberConverterInterface.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Converter; /** * A number converter converts UUIDs from hexadecimal characters into representations of integers and vice versa * * @immutable */ interface NumberConverterInterface { /** * Converts a hexadecimal number into a string integer representation of the number * * The integer representation returned is a string representation of the integer to accommodate unsigned integers * that are greater than `PHP_INT_MAX`. * * @param string $hex The hexadecimal string representation to convert * * @return numeric-string String representation of an integer * * @pure */ public function fromHex(string $hex): string; /** * Converts a string integer representation into a hexadecimal string representation of the number * * @param string $number A string integer representation to convert; this must be a numeric string to accommodate * unsigned integers that are greater than `PHP_INT_MAX`. * * @return non-empty-string Hexadecimal string * * @pure */ public function toHex(string $number): string; } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Converter/Time/BigNumberTimeConverter.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Converter\Time; use Ramsey\Uuid\Converter\TimeConverterInterface; use Ramsey\Uuid\Math\BrickMathCalculator; use Ramsey\Uuid\Type\Hexadecimal; use Ramsey\Uuid\Type\Time; /** * Previously used to integrate moontoast/math as a bignum arithmetic library, BigNumberTimeConverter is deprecated in * favor of GenericTimeConverter * * @deprecated Please transition to {@see GenericTimeConverter}. * * @immutable */ class BigNumberTimeConverter implements TimeConverterInterface { private TimeConverterInterface $converter; public function __construct() { $this->converter = new GenericTimeConverter(new BrickMathCalculator()); } public function calculateTime(string $seconds, string $microseconds): Hexadecimal { return $this->converter->calculateTime($seconds, $microseconds); } public function convertTime(Hexadecimal $uuidTimestamp): Time { return $this->converter->convertTime($uuidTimestamp); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Converter/Time/DegradedTimeConverter.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Converter\Time; /** * @deprecated DegradedTimeConverter is no longer necessary for converting time on 32-bit systems. Please transition to * {@see GenericTimeConverter}. * * @immutable */ class DegradedTimeConverter extends BigNumberTimeConverter { } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Converter/Time/GenericTimeConverter.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Converter\Time; use Ramsey\Uuid\Converter\TimeConverterInterface; use Ramsey\Uuid\Math\CalculatorInterface; use Ramsey\Uuid\Math\RoundingMode; use Ramsey\Uuid\Type\Hexadecimal; use Ramsey\Uuid\Type\Integer as IntegerObject; use Ramsey\Uuid\Type\Time; use function explode; use function str_pad; use const STR_PAD_LEFT; /** * GenericTimeConverter uses the provided calculator to calculate and convert time values * * @immutable */ class GenericTimeConverter implements TimeConverterInterface { /** * The number of 100-nanosecond intervals from the Gregorian calendar epoch to the Unix epoch. */ private const GREGORIAN_TO_UNIX_INTERVALS = '122192928000000000'; /** * The number of 100-nanosecond intervals in one second. */ private const SECOND_INTERVALS = '10000000'; /** * The number of 100-nanosecond intervals in one microsecond. */ private const MICROSECOND_INTERVALS = '10'; public function __construct(private CalculatorInterface $calculator) { } public function calculateTime(string $seconds, string $microseconds): Hexadecimal { /** @phpstan-ignore possiblyImpure.new */ $timestamp = new Time($seconds, $microseconds); // Convert the seconds into a count of 100-nanosecond intervals. $sec = $this->calculator->multiply( $timestamp->getSeconds(), new IntegerObject(self::SECOND_INTERVALS), /** @phpstan-ignore possiblyImpure.new */ ); // Convert the microseconds into a count of 100-nanosecond intervals. $usec = $this->calculator->multiply( $timestamp->getMicroseconds(), new IntegerObject(self::MICROSECOND_INTERVALS), /** @phpstan-ignore possiblyImpure.new */ ); /** * Combine the intervals of seconds and microseconds and add the count of 100-nanosecond intervals from the * Gregorian calendar epoch to the Unix epoch. This gives us the correct count of 100-nanosecond intervals since * the Gregorian calendar epoch for the given seconds and microseconds. * * @var IntegerObject $uuidTime * @phpstan-ignore possiblyImpure.new */ $uuidTime = $this->calculator->add($sec, $usec, new IntegerObject(self::GREGORIAN_TO_UNIX_INTERVALS)); /** * PHPStan considers CalculatorInterface::toHexadecimal, Hexadecimal:toString impure. * * @phpstan-ignore possiblyImpure.new */ return new Hexadecimal(str_pad($this->calculator->toHexadecimal($uuidTime)->toString(), 16, '0', STR_PAD_LEFT)); } public function convertTime(Hexadecimal $uuidTimestamp): Time { // From the total, subtract the number of 100-nanosecond intervals from the Gregorian calendar epoch to the Unix // epoch. This gives us the number of 100-nanosecond intervals from the Unix epoch, which also includes the microtime. $epochNanoseconds = $this->calculator->subtract( $this->calculator->toInteger($uuidTimestamp), new IntegerObject(self::GREGORIAN_TO_UNIX_INTERVALS), /** @phpstan-ignore possiblyImpure.new */ ); // Convert the 100-nanosecond intervals into seconds and microseconds. $unixTimestamp = $this->calculator->divide( RoundingMode::HALF_UP, 6, $epochNanoseconds, new IntegerObject(self::SECOND_INTERVALS), /** @phpstan-ignore possiblyImpure.new */ ); $split = explode('.', (string) $unixTimestamp, 2); /** @phpstan-ignore possiblyImpure.new */ return new Time($split[0], $split[1] ?? 0); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Converter/Time/PhpTimeConverter.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Converter\Time; use Ramsey\Uuid\Converter\TimeConverterInterface; use Ramsey\Uuid\Math\BrickMathCalculator; use Ramsey\Uuid\Math\CalculatorInterface; use Ramsey\Uuid\Type\Hexadecimal; use Ramsey\Uuid\Type\Integer as IntegerObject; use Ramsey\Uuid\Type\Time; use function count; use function dechex; use function explode; use function is_float; use function is_int; use function str_pad; use function strlen; use function substr; use const STR_PAD_LEFT; use const STR_PAD_RIGHT; /** * PhpTimeConverter uses built-in PHP functions and standard math operations available to the PHP programming language * to provide facilities for converting parts of time into representations that may be used in UUIDs * * @immutable */ class PhpTimeConverter implements TimeConverterInterface { /** * The number of 100-nanosecond intervals from the Gregorian calendar epoch to the Unix epoch. */ private const GREGORIAN_TO_UNIX_INTERVALS = 0x01b21dd213814000; /** * The number of 100-nanosecond intervals in one second. */ private const SECOND_INTERVALS = 10_000_000; /** * The number of 100-nanosecond intervals in one microsecond. */ private const MICROSECOND_INTERVALS = 10; private int $phpPrecision; private CalculatorInterface $calculator; private TimeConverterInterface $fallbackConverter; public function __construct( ?CalculatorInterface $calculator = null, ?TimeConverterInterface $fallbackConverter = null, ) { if ($calculator === null) { $calculator = new BrickMathCalculator(); } if ($fallbackConverter === null) { $fallbackConverter = new GenericTimeConverter($calculator); } $this->calculator = $calculator; $this->fallbackConverter = $fallbackConverter; $this->phpPrecision = (int) ini_get('precision'); } public function calculateTime(string $seconds, string $microseconds): Hexadecimal { $seconds = new IntegerObject($seconds); /** @phpstan-ignore possiblyImpure.new */ $microseconds = new IntegerObject($microseconds); /** @phpstan-ignore possiblyImpure.new */ // Calculate the count of 100-nanosecond intervals since the Gregorian calendar epoch // for the given seconds and microseconds. $uuidTime = ((int) $seconds->toString() * self::SECOND_INTERVALS) + ((int) $microseconds->toString() * self::MICROSECOND_INTERVALS) + self::GREGORIAN_TO_UNIX_INTERVALS; // Check to see whether we've overflowed the max/min integer size. // If so, we will default to a different time converter. // @phpstan-ignore function.alreadyNarrowedType (the integer value might have overflowed) if (!is_int($uuidTime)) { return $this->fallbackConverter->calculateTime( $seconds->toString(), $microseconds->toString(), ); } /** @phpstan-ignore possiblyImpure.new */ return new Hexadecimal( str_pad(dechex($uuidTime), 16, '0', STR_PAD_LEFT) ); } public function convertTime(Hexadecimal $uuidTimestamp): Time { $timestamp = $this->calculator->toInteger($uuidTimestamp); // Convert the 100-nanosecond intervals into seconds and microseconds. $splitTime = $this->splitTime( ($timestamp->toString() - self::GREGORIAN_TO_UNIX_INTERVALS) / self::SECOND_INTERVALS, ); if (count($splitTime) === 0) { return $this->fallbackConverter->convertTime($uuidTimestamp); } /** @phpstan-ignore possiblyImpure.new */ return new Time($splitTime['sec'], $splitTime['usec']); } /** * @param float | int $time The time to split into seconds and microseconds * * @return string[] * * @pure */ private function splitTime(float | int $time): array { $split = explode('.', (string) $time, 2); // If the $time value is a float but $split only has 1 element, then the float math was rounded up to the next // second, so we want to return an empty array to allow use of the fallback converter. if (is_float($time) && count($split) === 1) { return []; } if (count($split) === 1) { return ['sec' => $split[0], 'usec' => '0']; } // If the microseconds are less than six characters AND the length of the number is greater than or equal to the // PHP precision, then it's possible that we lost some precision for the microseconds. Return an empty array so // that we can choose to use the fallback converter. if (strlen($split[1]) < 6 && strlen((string) $time) >= $this->phpPrecision) { return []; } $microseconds = $split[1]; // Ensure the microseconds are no longer than 6 digits. If they are, // truncate the number to the first 6 digits and round up, if needed. if (strlen($microseconds) > 6) { $roundingDigit = (int) substr($microseconds, 6, 1); $microseconds = (int) substr($microseconds, 0, 6); if ($roundingDigit >= 5) { $microseconds++; } } return [ 'sec' => $split[0], 'usec' => str_pad((string) $microseconds, 6, '0', STR_PAD_RIGHT), ]; } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Converter/Time/UnixTimeConverter.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Converter\Time; use Ramsey\Uuid\Converter\TimeConverterInterface; use Ramsey\Uuid\Math\CalculatorInterface; use Ramsey\Uuid\Math\RoundingMode; use Ramsey\Uuid\Type\Hexadecimal; use Ramsey\Uuid\Type\Integer as IntegerObject; use Ramsey\Uuid\Type\Time; use function explode; use function str_pad; use const STR_PAD_LEFT; /** * UnixTimeConverter converts Unix Epoch timestamps to/from hexadecimal values consisting of milliseconds elapsed since * the Unix Epoch * * @immutable */ class UnixTimeConverter implements TimeConverterInterface { private const MILLISECONDS = 1000; public function __construct(private CalculatorInterface $calculator) { } public function calculateTime(string $seconds, string $microseconds): Hexadecimal { /** @phpstan-ignore possiblyImpure.new */ $timestamp = new Time($seconds, $microseconds); // Convert the seconds into milliseconds. $sec = $this->calculator->multiply( $timestamp->getSeconds(), new IntegerObject(self::MILLISECONDS) /** @phpstan-ignore possiblyImpure.new */ ); // Convert the microseconds into milliseconds; the scale is zero because we need to discard the fractional part. $usec = $this->calculator->divide( RoundingMode::DOWN, // Always round down to stay in the previous millisecond. 0, $timestamp->getMicroseconds(), new IntegerObject(self::MILLISECONDS), /** @phpstan-ignore possiblyImpure.new */ ); /** @var IntegerObject $unixTime */ $unixTime = $this->calculator->add($sec, $usec); /** @phpstan-ignore possiblyImpure.new */ return new Hexadecimal( str_pad( $this->calculator->toHexadecimal($unixTime)->toString(), 12, '0', STR_PAD_LEFT ), ); } public function convertTime(Hexadecimal $uuidTimestamp): Time { $milliseconds = $this->calculator->toInteger($uuidTimestamp); $unixTimestamp = $this->calculator->divide( RoundingMode::HALF_UP, 6, $milliseconds, new IntegerObject(self::MILLISECONDS), /** @phpstan-ignore possiblyImpure.new */ ); $split = explode('.', (string) $unixTimestamp, 2); /** @phpstan-ignore possiblyImpure.new */ return new Time($split[0], $split[1] ?? '0'); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Converter/TimeConverterInterface.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Converter; use Ramsey\Uuid\Type\Hexadecimal; use Ramsey\Uuid\Type\Time; /** * A time converter converts timestamps into representations that may be used in UUIDs * * @immutable */ interface TimeConverterInterface { /** * Uses the provided seconds and micro-seconds to calculate the count of 100-nanosecond intervals since * UTC 00:00:00.00, 15 October 1582, for RFC 9562 (formerly RFC 4122) variant UUIDs * * @link https://www.rfc-editor.org/rfc/rfc9562#appendix-A RFC 9562, Appendix A. Test Vectors * * @param string $seconds A string representation of seconds since the Unix epoch for the time to calculate * @param string $microseconds A string representation of the micro-seconds associated with the time to calculate * * @return Hexadecimal The full UUID timestamp as a Hexadecimal value * * @pure */ public function calculateTime(string $seconds, string $microseconds): Hexadecimal; /** * Converts a timestamp extracted from a UUID to a Unix timestamp * * @param Hexadecimal $uuidTimestamp A hexadecimal representation of a UUID timestamp; a UUID timestamp is a count * of 100-nanosecond intervals since UTC 00:00:00.00, 15 October 1582. * * @return Time An instance of {@see Time} * * @pure */ public function convertTime(Hexadecimal $uuidTimestamp): Time; } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/DegradedUuid.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid; /** * @deprecated DegradedUuid is no longer necessary to represent UUIDs on 32-bit systems. * Transition any type declarations using this class to {@see UuidInterface}. * * @immutable */ class DegradedUuid extends Uuid { } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/DeprecatedUuidInterface.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid; use DateTimeInterface; use Ramsey\Uuid\Converter\NumberConverterInterface; /** * This interface encapsulates deprecated methods for ramsey/uuid * * @immutable */ interface DeprecatedUuidInterface { /** * @deprecated This method will be removed in 5.0.0. There is no alternative recommendation, so plan accordingly. */ public function getNumberConverter(): NumberConverterInterface; /** * @deprecated Use {@see UuidInterface::getFields()} to get a {@see FieldsInterface} instance. * * @return string[] */ public function getFieldsHex(): array; /** * @deprecated Use {@see UuidInterface::getFields()} to get a {@see FieldsInterface} instance. If it is a * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getClockSeqHiAndReserved()}. */ public function getClockSeqHiAndReservedHex(): string; /** * @deprecated Use {@see UuidInterface::getFields()} to get a {@see FieldsInterface} instance. If it is a * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getClockSeqLow()}. */ public function getClockSeqLowHex(): string; /** * @deprecated Use {@see UuidInterface::getFields()} to get a {@see FieldsInterface} instance. If it is a * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getClockSeq()}. */ public function getClockSequenceHex(): string; /** * @deprecated In ramsey/uuid version 5.0.0, this will be removed from the interface. It is available at * {@see UuidV1::getDateTime()}. */ public function getDateTime(): DateTimeInterface; /** * @deprecated This method will be removed in 5.0.0. There is no direct alternative, but the same information may be * obtained by splitting in half the value returned by {@see UuidInterface::getHex()}. */ public function getLeastSignificantBitsHex(): string; /** * @deprecated This method will be removed in 5.0.0. There is no direct alternative, but the same information may be * obtained by splitting in half the value returned by {@see UuidInterface::getHex()}. */ public function getMostSignificantBitsHex(): string; /** * @deprecated Use {@see UuidInterface::getFields()} to get a {@see FieldsInterface} instance. If it is a * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getNode()}. */ public function getNodeHex(): string; /** * @deprecated Use {@see UuidInterface::getFields()} to get a {@see FieldsInterface} instance. If it is a * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getTimeHiAndVersion()}. */ public function getTimeHiAndVersionHex(): string; /** * @deprecated Use {@see UuidInterface::getFields()} to get a {@see FieldsInterface} instance. If it is a * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getTimeLow()}. */ public function getTimeLowHex(): string; /** * @deprecated Use {@see UuidInterface::getFields()} to get a {@see FieldsInterface} instance. If it is a * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getTimeMid()}. */ public function getTimeMidHex(): string; /** * @deprecated Use {@see UuidInterface::getFields()} to get a {@see FieldsInterface} instance. If it is a * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getTimestamp()}. */ public function getTimestampHex(): string; /** * @deprecated Use {@see UuidInterface::getFields()} to get a {@see FieldsInterface} instance. If it is a * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getVariant()}. */ public function getVariant(): ?int; /** * @deprecated Use {@see UuidInterface::getFields()} to get a {@see FieldsInterface} instance. If it is a * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getVersion()}. */ public function getVersion(): ?int; } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/DeprecatedUuidMethodsTrait.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid; use DateTimeImmutable; use DateTimeInterface; use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Exception\DateTimeException; use Ramsey\Uuid\Exception\UnsupportedOperationException; use Throwable; use function str_pad; use function substr; use const STR_PAD_LEFT; /** * This trait encapsulates deprecated methods for ramsey/uuid; this trait and its methods will be removed in ramsey/uuid 5.0.0. * * @deprecated This trait and its methods will be removed in ramsey/uuid 5.0.0. * * @immutable */ trait DeprecatedUuidMethodsTrait { /** * @deprecated Use {@see UuidInterface::getFields()} to get a {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. * If it is a {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getClockSeqHiAndReserved()} and use the arbitrary-precision math * library of your choice to convert it to a string integer. */ public function getClockSeqHiAndReserved(): string { return $this->numberConverter->fromHex($this->fields->getClockSeqHiAndReserved()->toString()); } /** * @deprecated Use {@see UuidInterface::getFields()} to get a {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. * If it is a {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getClockSeqHiAndReserved()}. */ public function getClockSeqHiAndReservedHex(): string { return $this->fields->getClockSeqHiAndReserved()->toString(); } /** * @deprecated Use {@see UuidInterface::getFields()} to get a {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. * If it is a {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getClockSeqLow()} and use the arbitrary-precision math library of * your choice to convert it to a string integer. */ public function getClockSeqLow(): string { return $this->numberConverter->fromHex($this->fields->getClockSeqLow()->toString()); } /** * @deprecated Use {@see UuidInterface::getFields()} to get a {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. * If it is a {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getClockSeqLow()}. */ public function getClockSeqLowHex(): string { return $this->fields->getClockSeqLow()->toString(); } /** * @deprecated Use {@see UuidInterface::getFields()} to get a {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. * If it is a {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getClockSeq()} and use the arbitrary-precision math library of * your choice to convert it to a string integer. */ public function getClockSequence(): string { return $this->numberConverter->fromHex($this->fields->getClockSeq()->toString()); } /** * @deprecated Use {@see UuidInterface::getFields()} to get a {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. * If it is a {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getClockSeq()}. */ public function getClockSequenceHex(): string { return $this->fields->getClockSeq()->toString(); } /** * @deprecated This method will be removed in 5.0.0. There is no alternative recommendation, so plan accordingly. */ public function getNumberConverter(): NumberConverterInterface { return $this->numberConverter; } /** * @deprecated In ramsey/uuid version 5.0.0, this will be removed. It is available at {@see UuidV1::getDateTime()}. * * @return DateTimeImmutable An immutable instance of DateTimeInterface * * @throws UnsupportedOperationException if UUID is not time-based * @throws DateTimeException if DateTime throws an exception/error */ public function getDateTime(): DateTimeInterface { if ($this->fields->getVersion() !== 1) { throw new UnsupportedOperationException('Not a time-based UUID'); } $time = $this->timeConverter->convertTime($this->fields->getTimestamp()); try { return new DateTimeImmutable( '@' . $time->getSeconds()->toString() . '.' . str_pad($time->getMicroseconds()->toString(), 6, '0', STR_PAD_LEFT) ); } catch (Throwable $e) { throw new DateTimeException($e->getMessage(), (int) $e->getCode(), $e); } } /** * @deprecated Use {@see UuidInterface::getFields()} to get a {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. * * @return string[] */ public function getFieldsHex(): array { return [ 'time_low' => $this->fields->getTimeLow()->toString(), 'time_mid' => $this->fields->getTimeMid()->toString(), 'time_hi_and_version' => $this->fields->getTimeHiAndVersion()->toString(), 'clock_seq_hi_and_reserved' => $this->fields->getClockSeqHiAndReserved()->toString(), 'clock_seq_low' => $this->fields->getClockSeqLow()->toString(), 'node' => $this->fields->getNode()->toString(), ]; } /** * @deprecated This method will be removed in 5.0.0. There is no direct alternative, but the same information may be * obtained by splitting in half the value returned by {@see UuidInterface::getHex()}. */ public function getLeastSignificantBits(): string { $leastSignificantHex = substr($this->getHex()->toString(), 16); return $this->numberConverter->fromHex($leastSignificantHex); } /** * @deprecated This method will be removed in 5.0.0. There is no direct alternative, but the same information may be * obtained by splitting in half the value returned by {@see UuidInterface::getHex()}. */ public function getLeastSignificantBitsHex(): string { return substr($this->getHex()->toString(), 16); } /** * @deprecated This method will be removed in 5.0.0. There is no direct alternative, but the same information may be * obtained by splitting in half the value returned by {@see UuidInterface::getHex()}. */ public function getMostSignificantBits(): string { $mostSignificantHex = substr($this->getHex()->toString(), 0, 16); return $this->numberConverter->fromHex($mostSignificantHex); } /** * @deprecated This method will be removed in 5.0.0. There is no direct alternative, but the same information may be * obtained by splitting in half the value returned by {@see UuidInterface::getHex()}. */ public function getMostSignificantBitsHex(): string { return substr($this->getHex()->toString(), 0, 16); } /** * @deprecated Use {@see UuidInterface::getFields()} to get a {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. * If it is a {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getNode()} and use the arbitrary-precision math library of your * choice to convert it to a string integer. */ public function getNode(): string { return $this->numberConverter->fromHex($this->fields->getNode()->toString()); } /** * @deprecated Use {@see UuidInterface::getFields()} to get a {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. * If it is a {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getNode()}. */ public function getNodeHex(): string { return $this->fields->getNode()->toString(); } /** * @deprecated Use {@see UuidInterface::getFields()} to get a {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. * If it is a {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getTimeHiAndVersion()} and use the arbitrary-precision math * library of your choice to convert it to a string integer. */ public function getTimeHiAndVersion(): string { return $this->numberConverter->fromHex($this->fields->getTimeHiAndVersion()->toString()); } /** * @deprecated Use {@see UuidInterface::getFields()} to get a {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. * If it is a {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getTimeHiAndVersion()}. */ public function getTimeHiAndVersionHex(): string { return $this->fields->getTimeHiAndVersion()->toString(); } /** * @deprecated Use {@see UuidInterface::getFields()} to get a {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. * If it is a {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getTimeLow()} and use the arbitrary-precision math library of * your choice to convert it to a string integer. */ public function getTimeLow(): string { return $this->numberConverter->fromHex($this->fields->getTimeLow()->toString()); } /** * @deprecated Use {@see UuidInterface::getFields()} to get a {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. * If it is a {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getTimeLow()}. */ public function getTimeLowHex(): string { return $this->fields->getTimeLow()->toString(); } /** * @deprecated Use {@see UuidInterface::getFields()} to get a {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. * If it is a {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getTimeMid()} and use the arbitrary-precision math library of * your choice to convert it to a string integer. */ public function getTimeMid(): string { return $this->numberConverter->fromHex($this->fields->getTimeMid()->toString()); } /** * @deprecated Use {@see UuidInterface::getFields()} to get a {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. * If it is a {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getTimeMid()}. */ public function getTimeMidHex(): string { return $this->fields->getTimeMid()->toString(); } /** * @deprecated Use {@see UuidInterface::getFields()} to get a {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. * If it is a {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getTimestamp()} and use the arbitrary-precision math library of * your choice to convert it to a string integer. */ public function getTimestamp(): string { if ($this->fields->getVersion() !== 1) { throw new UnsupportedOperationException('Not a time-based UUID'); } return $this->numberConverter->fromHex($this->fields->getTimestamp()->toString()); } /** * @deprecated Use {@see UuidInterface::getFields()} to get a {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. * If it is a {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getTimestamp()}. */ public function getTimestampHex(): string { if ($this->fields->getVersion() !== 1) { throw new UnsupportedOperationException('Not a time-based UUID'); } return $this->fields->getTimestamp()->toString(); } /** * @deprecated Use {@see UuidInterface::getFields()} to get a {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. * If it is a {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getVariant()}. */ public function getVariant(): ?int { return $this->fields->getVariant(); } /** * @deprecated Use {@see UuidInterface::getFields()} to get a {@see \Ramsey\Uuid\Fields\FieldsInterface} instance. * If it is a {@see \Ramsey\Uuid\Rfc4122\FieldsInterface} instance, you may call * {@see \Ramsey\Uuid\Rfc4122\FieldsInterface::getVersion()}. */ public function getVersion(): ?int { return $this->fields->getVersion(); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Exception/BuilderNotFoundException.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Exception; use RuntimeException as PhpRuntimeException; /** * Thrown to indicate that no suitable builder could be found */ class BuilderNotFoundException extends PhpRuntimeException implements UuidExceptionInterface { } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Exception/DateTimeException.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Exception; use RuntimeException as PhpRuntimeException; /** * Thrown to indicate that the PHP DateTime extension encountered an exception/error */ class DateTimeException extends PhpRuntimeException implements UuidExceptionInterface { } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Exception/DceSecurityException.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Exception; use RuntimeException as PhpRuntimeException; /** * Thrown to indicate an exception occurred while dealing with DCE Security (version 2) UUIDs */ class DceSecurityException extends PhpRuntimeException implements UuidExceptionInterface { } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Exception/InvalidArgumentException.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Exception; use InvalidArgumentException as PhpInvalidArgumentException; /** * Thrown to indicate that the argument received is not valid */ class InvalidArgumentException extends PhpInvalidArgumentException implements UuidExceptionInterface { } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Exception/InvalidBytesException.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Exception; use RuntimeException as PhpRuntimeException; /** * Thrown to indicate that the bytes being operated on are invalid in some way */ class InvalidBytesException extends PhpRuntimeException implements UuidExceptionInterface { } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Exception/InvalidUuidStringException.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Exception; /** * Thrown to indicate that the string received is not a valid UUID * * The InvalidArgumentException that this extends is the ramsey/uuid version of this exception. It exists in the same * namespace as this class. */ class InvalidUuidStringException extends InvalidArgumentException implements UuidExceptionInterface { } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Exception/NameException.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Exception; use RuntimeException as PhpRuntimeException; /** * Thrown to indicate that an error occurred while attempting to hash a namespace and name */ class NameException extends PhpRuntimeException implements UuidExceptionInterface { } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Exception/NodeException.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Exception; use RuntimeException as PhpRuntimeException; /** * Thrown to indicate that attempting to fetch or create a node ID encountered an error */ class NodeException extends PhpRuntimeException implements UuidExceptionInterface { } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Exception/RandomSourceException.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Exception; use RuntimeException as PhpRuntimeException; /** * Thrown to indicate that the source of random data encountered an error * * This exception is used mostly to indicate that random_bytes() or random_int() threw an exception. However, it may be * used for other sources of random data. */ class RandomSourceException extends PhpRuntimeException implements UuidExceptionInterface { } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Exception/TimeSourceException.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Exception; use RuntimeException as PhpRuntimeException; /** * Thrown to indicate that the source of time encountered an error */ class TimeSourceException extends PhpRuntimeException implements UuidExceptionInterface { } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Exception/UnableToBuildUuidException.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Exception; use RuntimeException as PhpRuntimeException; /** * Thrown to indicate a builder is unable to build a UUID */ class UnableToBuildUuidException extends PhpRuntimeException implements UuidExceptionInterface { } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Exception/UnsupportedOperationException.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Exception; use LogicException as PhpLogicException; /** * Thrown to indicate that the requested operation is not supported */ class UnsupportedOperationException extends PhpLogicException implements UuidExceptionInterface { } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Exception/UuidExceptionInterface.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Exception; use Throwable; interface UuidExceptionInterface extends Throwable { } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/FeatureSet.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid; use Ramsey\Uuid\Builder\FallbackBuilder; use Ramsey\Uuid\Builder\UuidBuilderInterface; use Ramsey\Uuid\Codec\CodecInterface; use Ramsey\Uuid\Codec\GuidStringCodec; use Ramsey\Uuid\Codec\StringCodec; use Ramsey\Uuid\Converter\Number\GenericNumberConverter; use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Converter\Time\GenericTimeConverter; use Ramsey\Uuid\Converter\Time\PhpTimeConverter; use Ramsey\Uuid\Converter\TimeConverterInterface; use Ramsey\Uuid\Generator\DceSecurityGenerator; use Ramsey\Uuid\Generator\DceSecurityGeneratorInterface; use Ramsey\Uuid\Generator\NameGeneratorFactory; use Ramsey\Uuid\Generator\NameGeneratorInterface; use Ramsey\Uuid\Generator\PeclUuidNameGenerator; use Ramsey\Uuid\Generator\PeclUuidRandomGenerator; use Ramsey\Uuid\Generator\PeclUuidTimeGenerator; use Ramsey\Uuid\Generator\RandomGeneratorFactory; use Ramsey\Uuid\Generator\RandomGeneratorInterface; use Ramsey\Uuid\Generator\TimeGeneratorFactory; use Ramsey\Uuid\Generator\TimeGeneratorInterface; use Ramsey\Uuid\Generator\UnixTimeGenerator; use Ramsey\Uuid\Guid\GuidBuilder; use Ramsey\Uuid\Math\BrickMathCalculator; use Ramsey\Uuid\Math\CalculatorInterface; use Ramsey\Uuid\Nonstandard\UuidBuilder as NonstandardUuidBuilder; use Ramsey\Uuid\Provider\Dce\SystemDceSecurityProvider; use Ramsey\Uuid\Provider\DceSecurityProviderInterface; use Ramsey\Uuid\Provider\Node\FallbackNodeProvider; use Ramsey\Uuid\Provider\Node\RandomNodeProvider; use Ramsey\Uuid\Provider\Node\SystemNodeProvider; use Ramsey\Uuid\Provider\NodeProviderInterface; use Ramsey\Uuid\Provider\Time\SystemTimeProvider; use Ramsey\Uuid\Provider\TimeProviderInterface; use Ramsey\Uuid\Rfc4122\UuidBuilder as Rfc4122UuidBuilder; use Ramsey\Uuid\Validator\GenericValidator; use Ramsey\Uuid\Validator\ValidatorInterface; use const PHP_INT_SIZE; /** * FeatureSet detects and exposes available features in the current environment * * A feature set is used by UuidFactory to determine the available features and capabilities of the environment. */ class FeatureSet { private ?TimeProviderInterface $timeProvider = null; private CalculatorInterface $calculator; private CodecInterface $codec; private DceSecurityGeneratorInterface $dceSecurityGenerator; private NameGeneratorInterface $nameGenerator; private NodeProviderInterface $nodeProvider; private NumberConverterInterface $numberConverter; private RandomGeneratorInterface $randomGenerator; private TimeConverterInterface $timeConverter; private TimeGeneratorInterface $timeGenerator; private TimeGeneratorInterface $unixTimeGenerator; private UuidBuilderInterface $builder; private ValidatorInterface $validator; /** * @param bool $useGuids True build UUIDs using the GuidStringCodec * @param bool $force32Bit True to force the use of 32-bit functionality (primarily for testing purposes) * @param bool $forceNoBigNumber (obsolete) * @param bool $ignoreSystemNode True to disable attempts to check for the system node ID (primarily for testing purposes) * @param bool $enablePecl True to enable the use of the PeclUuidTimeGenerator to generate version 1 UUIDs * * @phpstan-ignore constructor.unusedParameter ($forceNoBigNumber is deprecated) */ public function __construct( bool $useGuids = false, private bool $force32Bit = false, bool $forceNoBigNumber = false, private bool $ignoreSystemNode = false, private bool $enablePecl = false, ) { $this->randomGenerator = $this->buildRandomGenerator(); $this->setCalculator(new BrickMathCalculator()); $this->builder = $this->buildUuidBuilder($useGuids); $this->codec = $this->buildCodec($useGuids); $this->nodeProvider = $this->buildNodeProvider(); $this->nameGenerator = $this->buildNameGenerator(); $this->setTimeProvider(new SystemTimeProvider()); $this->setDceSecurityProvider(new SystemDceSecurityProvider()); $this->validator = new GenericValidator(); assert($this->timeProvider !== null); $this->unixTimeGenerator = $this->buildUnixTimeGenerator(); } /** * Returns the builder configured for this environment */ public function getBuilder(): UuidBuilderInterface { return $this->builder; } /** * Returns the calculator configured for this environment */ public function getCalculator(): CalculatorInterface { return $this->calculator; } /** * Returns the codec configured for this environment */ public function getCodec(): CodecInterface { return $this->codec; } /** * Returns the DCE Security generator configured for this environment */ public function getDceSecurityGenerator(): DceSecurityGeneratorInterface { return $this->dceSecurityGenerator; } /** * Returns the name generator configured for this environment */ public function getNameGenerator(): NameGeneratorInterface { return $this->nameGenerator; } /** * Returns the node provider configured for this environment */ public function getNodeProvider(): NodeProviderInterface { return $this->nodeProvider; } /** * Returns the number converter configured for this environment */ public function getNumberConverter(): NumberConverterInterface { return $this->numberConverter; } /** * Returns the random generator configured for this environment */ public function getRandomGenerator(): RandomGeneratorInterface { return $this->randomGenerator; } /** * Returns the time converter configured for this environment */ public function getTimeConverter(): TimeConverterInterface { return $this->timeConverter; } /** * Returns the time generator configured for this environment */ public function getTimeGenerator(): TimeGeneratorInterface { return $this->timeGenerator; } /** * Returns the Unix Epoch time generator configured for this environment */ public function getUnixTimeGenerator(): TimeGeneratorInterface { return $this->unixTimeGenerator; } /** * Returns the validator configured for this environment */ public function getValidator(): ValidatorInterface { return $this->validator; } /** * Sets the calculator to use in this environment */ public function setCalculator(CalculatorInterface $calculator): void { $this->calculator = $calculator; $this->numberConverter = $this->buildNumberConverter($calculator); $this->timeConverter = $this->buildTimeConverter($calculator); if (isset($this->timeProvider)) { $this->timeGenerator = $this->buildTimeGenerator($this->timeProvider); } } /** * Sets the DCE Security provider to use in this environment */ public function setDceSecurityProvider(DceSecurityProviderInterface $dceSecurityProvider): void { $this->dceSecurityGenerator = $this->buildDceSecurityGenerator($dceSecurityProvider); } /** * Sets the node provider to use in this environment */ public function setNodeProvider(NodeProviderInterface $nodeProvider): void { $this->nodeProvider = $nodeProvider; if (isset($this->timeProvider)) { $this->timeGenerator = $this->buildTimeGenerator($this->timeProvider); } } /** * Sets the time provider to use in this environment */ public function setTimeProvider(TimeProviderInterface $timeProvider): void { $this->timeProvider = $timeProvider; $this->timeGenerator = $this->buildTimeGenerator($timeProvider); } /** * Set the validator to use in this environment */ public function setValidator(ValidatorInterface $validator): void { $this->validator = $validator; } /** * Returns a codec configured for this environment * * @param bool $useGuids Whether to build UUIDs using the GuidStringCodec */ private function buildCodec(bool $useGuids = false): CodecInterface { if ($useGuids) { return new GuidStringCodec($this->builder); } return new StringCodec($this->builder); } /** * Returns a DCE Security generator configured for this environment */ private function buildDceSecurityGenerator( DceSecurityProviderInterface $dceSecurityProvider, ): DceSecurityGeneratorInterface { return new DceSecurityGenerator($this->numberConverter, $this->timeGenerator, $dceSecurityProvider); } /** * Returns a node provider configured for this environment */ private function buildNodeProvider(): NodeProviderInterface { if ($this->ignoreSystemNode) { return new RandomNodeProvider(); } return new FallbackNodeProvider([new SystemNodeProvider(), new RandomNodeProvider()]); } /** * Returns a number converter configured for this environment */ private function buildNumberConverter(CalculatorInterface $calculator): NumberConverterInterface { return new GenericNumberConverter($calculator); } /** * Returns a random generator configured for this environment */ private function buildRandomGenerator(): RandomGeneratorInterface { if ($this->enablePecl) { return new PeclUuidRandomGenerator(); } return (new RandomGeneratorFactory())->getGenerator(); } /** * Returns a time generator configured for this environment * * @param TimeProviderInterface $timeProvider The time provider to use with * the time generator */ private function buildTimeGenerator(TimeProviderInterface $timeProvider): TimeGeneratorInterface { if ($this->enablePecl) { return new PeclUuidTimeGenerator(); } return (new TimeGeneratorFactory($this->nodeProvider, $this->timeConverter, $timeProvider))->getGenerator(); } /** * Returns a Unix Epoch time generator configured for this environment */ private function buildUnixTimeGenerator(): TimeGeneratorInterface { return new UnixTimeGenerator($this->randomGenerator); } /** * Returns a name generator configured for this environment */ private function buildNameGenerator(): NameGeneratorInterface { if ($this->enablePecl) { return new PeclUuidNameGenerator(); } return (new NameGeneratorFactory())->getGenerator(); } /** * Returns a time converter configured for this environment */ private function buildTimeConverter(CalculatorInterface $calculator): TimeConverterInterface { $genericConverter = new GenericTimeConverter($calculator); if ($this->is64BitSystem()) { return new PhpTimeConverter($calculator, $genericConverter); } return $genericConverter; } /** * Returns a UUID builder configured for this environment * * @param bool $useGuids Whether to build UUIDs using the GuidStringCodec */ private function buildUuidBuilder(bool $useGuids = false): UuidBuilderInterface { if ($useGuids) { return new GuidBuilder($this->numberConverter, $this->timeConverter); } return new FallbackBuilder([ new Rfc4122UuidBuilder($this->numberConverter, $this->timeConverter), new NonstandardUuidBuilder($this->numberConverter, $this->timeConverter), ]); } /** * Returns true if the PHP build is 64-bit */ private function is64BitSystem(): bool { return PHP_INT_SIZE === 8 && !$this->force32Bit; } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Fields/FieldsInterface.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Fields; use Serializable; /** * UUIDs consist of unsigned integers, the bytes of which are separated into fields and arranged in a particular layout * defined by the specification for the variant * * @immutable */ interface FieldsInterface extends Serializable { /** * Returns the bytes that comprise the fields * * @pure */ public function getBytes(): string; } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Fields/SerializableFieldsTrait.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Fields; use ValueError; use function base64_decode; use function sprintf; use function strlen; /** * Provides common serialization functionality to fields * * @immutable */ trait SerializableFieldsTrait { /** * @param string $bytes The bytes that comprise the fields */ abstract public function __construct(string $bytes); /** * Returns the bytes that comprise the fields */ abstract public function getBytes(): string; /** * Returns a string representation of the object */ public function serialize(): string { return $this->getBytes(); } /** * @return array{bytes: string} */ public function __serialize(): array { return ['bytes' => $this->getBytes()]; } /** * Constructs the object from a serialized string representation * * @param string $data The serialized string representation of the object */ public function unserialize(string $data): void { if (strlen($data) === 16) { $this->__construct($data); } else { $this->__construct(base64_decode($data)); } } /** * @param array{bytes?: string} $data */ public function __unserialize(array $data): void { // @codeCoverageIgnoreStart if (!isset($data['bytes'])) { throw new ValueError(sprintf('%s(): Argument #1 ($data) is invalid', __METHOD__)); } // @codeCoverageIgnoreEnd $this->unserialize($data['bytes']); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Generator/CombGenerator.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Generator; use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Exception\InvalidArgumentException; use function bin2hex; use function explode; use function hex2bin; use function microtime; use function str_pad; use function substr; use const STR_PAD_LEFT; /** * CombGenerator generates COMBs (combined UUID/timestamp) * * The CombGenerator, when used with the StringCodec (and, by proxy, the TimestampLastCombCodec) or the * TimestampFirstCombCodec, combines the current timestamp with a UUID (hence the name "COMB"). The timestamp either * appears as the first or last 48 bits of the COMB, depending on the codec used. * * By default, COMBs will have the timestamp set as the last 48 bits of the identifier. * * ``` * $factory = new UuidFactory(); * * $factory->setRandomGenerator(new CombGenerator( * $factory->getRandomGenerator(), * $factory->getNumberConverter(), * )); * * $comb = $factory->uuid4(); * ``` * * To generate a COMB with the timestamp as the first 48 bits, set the TimestampFirstCombCodec as the codec. * * ``` * $factory->setCodec(new TimestampFirstCombCodec($factory->getUuidBuilder())); * ``` * * @deprecated Please migrate to {@link https://uuid.ramsey.dev/en/stable/rfc4122/version7.html Version 7, Unix Epoch Time UUIDs}. * * @link https://web.archive.org/web/20240118030355/https://www.informit.com/articles/printerfriendly/25862 The Cost of GUIDs as Primary Keys */ class CombGenerator implements RandomGeneratorInterface { public const TIMESTAMP_BYTES = 6; public function __construct( private RandomGeneratorInterface $generator, private NumberConverterInterface $numberConverter ) { } /** * @throws InvalidArgumentException if $length is not a positive integer greater than or equal to CombGenerator::TIMESTAMP_BYTES * * @inheritDoc */ public function generate(int $length): string { if ($length < self::TIMESTAMP_BYTES) { throw new InvalidArgumentException( 'Length must be a positive integer greater than or equal to ' . self::TIMESTAMP_BYTES ); } if ($length % 2 !== 0) { throw new InvalidArgumentException('Length must be an even number'); } $hash = ''; /** @phpstan-ignore greater.alwaysTrue (TIMESTAMP_BYTES constant could change in child classes) */ if (self::TIMESTAMP_BYTES > 0 && $length > self::TIMESTAMP_BYTES) { $hash = $this->generator->generate($length - self::TIMESTAMP_BYTES); } $lsbTime = str_pad( $this->numberConverter->toHex($this->timestamp()), self::TIMESTAMP_BYTES * 2, '0', STR_PAD_LEFT, ); return (string) hex2bin(str_pad(bin2hex($hash), $length - self::TIMESTAMP_BYTES, '0') . $lsbTime); } /** * Returns the current timestamp as a string integer, precise to 0.00001 seconds */ private function timestamp(): string { $time = explode(' ', microtime(false)); return $time[1] . substr($time[0], 2, 5); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Generator/DceSecurityGenerator.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Generator; use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Exception\DceSecurityException; use Ramsey\Uuid\Provider\DceSecurityProviderInterface; use Ramsey\Uuid\Type\Hexadecimal; use Ramsey\Uuid\Type\Integer as IntegerObject; use Ramsey\Uuid\Uuid; use function hex2bin; use function in_array; use function pack; use function str_pad; use function strlen; use function substr_replace; use const STR_PAD_LEFT; /** * DceSecurityGenerator generates strings of binary data based on a local domain, local identifier, node ID, clock * sequence, and the current time */ class DceSecurityGenerator implements DceSecurityGeneratorInterface { private const DOMAINS = [ Uuid::DCE_DOMAIN_PERSON, Uuid::DCE_DOMAIN_GROUP, Uuid::DCE_DOMAIN_ORG, ]; /** * Upper bounds for the clock sequence in DCE Security UUIDs. */ private const CLOCK_SEQ_HIGH = 63; /** * Lower bounds for the clock sequence in DCE Security UUIDs. */ private const CLOCK_SEQ_LOW = 0; public function __construct( private NumberConverterInterface $numberConverter, private TimeGeneratorInterface $timeGenerator, private DceSecurityProviderInterface $dceSecurityProvider, ) { } public function generate( int $localDomain, ?IntegerObject $localIdentifier = null, ?Hexadecimal $node = null, ?int $clockSeq = null, ): string { if (!in_array($localDomain, self::DOMAINS)) { throw new DceSecurityException('Local domain must be a valid DCE Security domain'); } if ($localIdentifier && $localIdentifier->isNegative()) { throw new DceSecurityException( 'Local identifier out of bounds; it must be a value between 0 and 4294967295', ); } if ($clockSeq > self::CLOCK_SEQ_HIGH || $clockSeq < self::CLOCK_SEQ_LOW) { throw new DceSecurityException('Clock sequence out of bounds; it must be a value between 0 and 63'); } switch ($localDomain) { case Uuid::DCE_DOMAIN_ORG: if ($localIdentifier === null) { throw new DceSecurityException('A local identifier must be provided for the org domain'); } break; case Uuid::DCE_DOMAIN_PERSON: if ($localIdentifier === null) { $localIdentifier = $this->dceSecurityProvider->getUid(); } break; case Uuid::DCE_DOMAIN_GROUP: default: if ($localIdentifier === null) { $localIdentifier = $this->dceSecurityProvider->getGid(); } break; } $identifierHex = $this->numberConverter->toHex($localIdentifier->toString()); // The maximum value for the local identifier is 0xffffffff, or 4,294,967,295. This is 8 hexadecimal digits, so // if the length of hexadecimal digits is greater than 8, we know the value is greater than 0xffffffff. if (strlen($identifierHex) > 8) { throw new DceSecurityException( 'Local identifier out of bounds; it must be a value between 0 and 4294967295', ); } $domainByte = pack('n', $localDomain)[1]; $identifierBytes = (string) hex2bin(str_pad($identifierHex, 8, '0', STR_PAD_LEFT)); if ($node instanceof Hexadecimal) { $node = $node->toString(); } // Shift the clock sequence 8 bits to the left, so it matches 0x3f00. if ($clockSeq !== null) { $clockSeq = $clockSeq << 8; } $bytes = $this->timeGenerator->generate($node, $clockSeq); // Replace bytes in the time-based UUID with DCE Security values. $bytes = substr_replace($bytes, $identifierBytes, 0, 4); return substr_replace($bytes, $domainByte, 9, 1); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Generator/DceSecurityGeneratorInterface.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Generator; use Ramsey\Uuid\Rfc4122\UuidV2; use Ramsey\Uuid\Type\Hexadecimal; use Ramsey\Uuid\Type\Integer as IntegerObject; /** * A DCE Security generator generates strings of binary data based on a local domain, local identifier, node ID, clock * sequence, and the current time * * @see UuidV2 */ interface DceSecurityGeneratorInterface { /** * Generate a binary string from a local domain, local identifier, node ID, clock sequence, and current time * * @param int $localDomain The local domain to use when generating bytes, according to DCE Security * @param IntegerObject | null $localIdentifier The local identifier for the given domain; this may be a UID or GID * on POSIX systems if the local domain is "person" or "group," or it may be a site-defined identifier if the * local domain is "org" * @param Hexadecimal | null $node A 48-bit number representing the hardware address * @param int | null $clockSeq A 14-bit number used to help avoid duplicates that could arise when the clock is set * backwards in time or if the node ID changes * * @return string A binary string */ public function generate( int $localDomain, ?IntegerObject $localIdentifier = null, ?Hexadecimal $node = null, ?int $clockSeq = null, ): string; } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Generator/DefaultNameGenerator.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Generator; use Ramsey\Uuid\Exception\NameException; use Ramsey\Uuid\UuidInterface; use ValueError; use function hash; /** * DefaultNameGenerator generates strings of binary data based on a namespace, name, and hashing algorithm */ class DefaultNameGenerator implements NameGeneratorInterface { /** * @pure */ public function generate(UuidInterface $ns, string $name, string $hashAlgorithm): string { try { return hash($hashAlgorithm, $ns->getBytes() . $name, true); } catch (ValueError $e) { throw new NameException( message: sprintf('Unable to hash namespace and name with algorithm \'%s\'', $hashAlgorithm), previous: $e, ); } } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Generator/DefaultTimeGenerator.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Generator; use Ramsey\Uuid\Converter\TimeConverterInterface; use Ramsey\Uuid\Exception\InvalidArgumentException; use Ramsey\Uuid\Exception\RandomSourceException; use Ramsey\Uuid\Exception\TimeSourceException; use Ramsey\Uuid\Provider\NodeProviderInterface; use Ramsey\Uuid\Provider\TimeProviderInterface; use Ramsey\Uuid\Type\Hexadecimal; use Throwable; use function dechex; use function hex2bin; use function is_int; use function pack; use function preg_match; use function sprintf; use function str_pad; use function strlen; use const STR_PAD_LEFT; /** * DefaultTimeGenerator generates strings of binary data based on a node ID, clock sequence, and the current time */ class DefaultTimeGenerator implements TimeGeneratorInterface { public function __construct( private NodeProviderInterface $nodeProvider, private TimeConverterInterface $timeConverter, private TimeProviderInterface $timeProvider, ) { } /** * @throws InvalidArgumentException if the parameters contain invalid values * @throws RandomSourceException if random_int() throws an exception/error * * @inheritDoc */ public function generate($node = null, ?int $clockSeq = null): string { if ($node instanceof Hexadecimal) { $node = $node->toString(); } $node = $this->getValidNode($node); if ($clockSeq === null) { try { // This does not use "stable storage"; see RFC 9562, section 6.3. $clockSeq = random_int(0, 0x3fff); } catch (Throwable $exception) { throw new RandomSourceException($exception->getMessage(), (int) $exception->getCode(), $exception); } } $time = $this->timeProvider->getTime(); $uuidTime = $this->timeConverter->calculateTime( $time->getSeconds()->toString(), $time->getMicroseconds()->toString() ); $timeHex = str_pad($uuidTime->toString(), 16, '0', STR_PAD_LEFT); if (strlen($timeHex) !== 16) { throw new TimeSourceException(sprintf('The generated time of \'%s\' is larger than expected', $timeHex)); } $timeBytes = (string) hex2bin($timeHex); return $timeBytes[4] . $timeBytes[5] . $timeBytes[6] . $timeBytes[7] . $timeBytes[2] . $timeBytes[3] . $timeBytes[0] . $timeBytes[1] . pack('n*', $clockSeq) . $node; } /** * Uses the node provider given when constructing this instance to get the node ID (usually a MAC address) * * @param int | string | null $node A node value that may be used to override the node provider * * @return string 6-byte binary string representation of the node * * @throws InvalidArgumentException */ private function getValidNode(int | string | null $node): string { if ($node === null) { $node = $this->nodeProvider->getNode(); } // Convert the node to hex if it is still an integer. if (is_int($node)) { $node = dechex($node); } if (!preg_match('/^[A-Fa-f0-9]+$/', (string) $node) || strlen((string) $node) > 12) { throw new InvalidArgumentException('Invalid node value'); } return (string) hex2bin(str_pad((string) $node, 12, '0', STR_PAD_LEFT)); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Generator/NameGeneratorFactory.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Generator; /** * NameGeneratorFactory retrieves a default name generator, based on the environment */ class NameGeneratorFactory { /** * Returns a default name generator, based on the current environment */ public function getGenerator(): NameGeneratorInterface { return new DefaultNameGenerator(); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Generator/NameGeneratorInterface.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Generator; use Ramsey\Uuid\UuidInterface; /** * A name generator generates strings of binary data created by hashing together a namespace with a name, according to a * hashing algorithm */ interface NameGeneratorInterface { /** * Generate a binary string from a namespace and name hashed together with the specified hashing algorithm * * @param UuidInterface $ns The namespace * @param string $name The name to use for creating a UUID * @param string $hashAlgorithm The hashing algorithm to use * * @return string A binary string * * @pure */ public function generate(UuidInterface $ns, string $name, string $hashAlgorithm): string; } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Generator/PeclUuidNameGenerator.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Generator; use Ramsey\Uuid\Exception\NameException; use Ramsey\Uuid\UuidInterface; use function sprintf; use function uuid_generate_md5; use function uuid_generate_sha1; use function uuid_parse; /** * PeclUuidNameGenerator generates strings of binary data from a namespace and a name, using ext-uuid * * @link https://pecl.php.net/package/uuid ext-uuid */ class PeclUuidNameGenerator implements NameGeneratorInterface { /** * @pure */ public function generate(UuidInterface $ns, string $name, string $hashAlgorithm): string { $uuid = match ($hashAlgorithm) { 'md5' => uuid_generate_md5($ns->toString(), $name), /** @phpstan-ignore possiblyImpure.functionCall */ 'sha1' => uuid_generate_sha1($ns->toString(), $name), /** @phpstan-ignore possiblyImpure.functionCall */ default => throw new NameException( sprintf('Unable to hash namespace and name with algorithm \'%s\'', $hashAlgorithm), ), }; /** @phpstan-ignore possiblyImpure.functionCall */ return (string) uuid_parse($uuid); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Generator/PeclUuidRandomGenerator.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Generator; use function uuid_create; use function uuid_parse; use const UUID_TYPE_RANDOM; /** * PeclUuidRandomGenerator generates strings of random binary data using ext-uuid * * @link https://pecl.php.net/package/uuid ext-uuid */ class PeclUuidRandomGenerator implements RandomGeneratorInterface { public function generate(int $length): string { $uuid = uuid_create(UUID_TYPE_RANDOM); return (string) uuid_parse($uuid); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Generator/PeclUuidTimeGenerator.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Generator; use function uuid_create; use function uuid_parse; use const UUID_TYPE_TIME; /** * PeclUuidTimeGenerator generates strings of binary data for time-base UUIDs, using ext-uuid * * @link https://pecl.php.net/package/uuid ext-uuid */ class PeclUuidTimeGenerator implements TimeGeneratorInterface { /** * @inheritDoc */ public function generate($node = null, ?int $clockSeq = null): string { $uuid = uuid_create(UUID_TYPE_TIME); return (string) uuid_parse($uuid); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Generator/RandomBytesGenerator.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Generator; use Ramsey\Uuid\Exception\RandomSourceException; use Throwable; /** * RandomBytesGenerator generates strings of random binary data using the built-in `random_bytes()` PHP function * * @link http://php.net/random_bytes random_bytes() */ class RandomBytesGenerator implements RandomGeneratorInterface { /** * @throws RandomSourceException if random_bytes() throws an exception/error * * @inheritDoc */ public function generate(int $length): string { try { return random_bytes($length); } catch (Throwable $exception) { throw new RandomSourceException($exception->getMessage(), (int) $exception->getCode(), $exception); } } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Generator/RandomGeneratorFactory.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Generator; /** * RandomGeneratorFactory retrieves a default random generator, based on the environment */ class RandomGeneratorFactory { /** * Returns a default random generator, based on the current environment */ public function getGenerator(): RandomGeneratorInterface { return new RandomBytesGenerator(); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Generator/RandomGeneratorInterface.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Generator; /** * A random generator generates strings of random binary data */ interface RandomGeneratorInterface { /** * Generates a string of randomized binary data * * @param int<1, max> $length The number of bytes to generate of random binary data * * @return string A binary string */ public function generate(int $length): string; } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Generator/RandomLibAdapter.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Generator; use RandomLib\Factory; use RandomLib\Generator; /** * RandomLibAdapter generates strings of random binary data using the paragonie/random-lib library * * @deprecated This class will be removed in 5.0.0. Use the default RandomBytesGenerator or implement your own generator * that implements RandomGeneratorInterface. * * @link https://packagist.org/packages/paragonie/random-lib paragonie/random-lib */ class RandomLibAdapter implements RandomGeneratorInterface { private Generator $generator; /** * Constructs a RandomLibAdapter * * By default, if no Generator is passed in, this creates a high-strength generator to use when generating random * binary data. * * @param Generator | null $generator The generator to use when generating binary data */ public function __construct(?Generator $generator = null) { if ($generator === null) { $factory = new Factory(); $generator = $factory->getHighStrengthGenerator(); } $this->generator = $generator; } public function generate(int $length): string { return $this->generator->generate($length); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Generator/TimeGeneratorFactory.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Generator; use Ramsey\Uuid\Converter\TimeConverterInterface; use Ramsey\Uuid\Provider\NodeProviderInterface; use Ramsey\Uuid\Provider\TimeProviderInterface; /** * TimeGeneratorFactory retrieves a default time generator, based on the environment */ class TimeGeneratorFactory { public function __construct( private NodeProviderInterface $nodeProvider, private TimeConverterInterface $timeConverter, private TimeProviderInterface $timeProvider, ) { } /** * Returns a default time generator, based on the current environment */ public function getGenerator(): TimeGeneratorInterface { return new DefaultTimeGenerator($this->nodeProvider, $this->timeConverter, $this->timeProvider); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Generator/TimeGeneratorInterface.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Generator; use Ramsey\Uuid\Type\Hexadecimal; /** * A time generator generates strings of binary data based on a node ID, clock sequence, and the current time */ interface TimeGeneratorInterface { /** * Generate a binary string from a node ID, clock sequence, and current time * * @param Hexadecimal | int | string | null $node A 48-bit number representing the hardware address; this number may * be represented as an integer or a hexadecimal string * @param int | null $clockSeq A 14-bit number used to help avoid duplicates that could arise when the clock is set * backwards in time or if the node ID changes * * @return string A binary string */ public function generate($node = null, ?int $clockSeq = null): string; } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Generator/UnixTimeGenerator.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Generator; use Brick\Math\BigInteger; use DateTimeInterface; use Ramsey\Uuid\Type\Hexadecimal; use function assert; use function hash; use function pack; use function str_pad; use function strlen; use function substr; use function substr_replace; use function unpack; use const PHP_INT_SIZE; use const STR_PAD_LEFT; /** * UnixTimeGenerator generates bytes, combining a 48-bit timestamp in milliseconds since the Unix Epoch with 80 random bits * * Code and concepts within this class are borrowed from the symfony/uid package and are used under the terms of the MIT * license distributed with symfony/uid. * * symfony/uid is copyright (c) Fabien Potencier. * * @link https://symfony.com/components/Uid Symfony Uid component * @link https://github.com/symfony/uid/blob/4f9f537e57261519808a7ce1d941490736522bbc/UuidV7.php Symfony UuidV7 class * @link https://github.com/symfony/uid/blob/6.2/LICENSE MIT License */ class UnixTimeGenerator implements TimeGeneratorInterface { private static string $time = ''; private static ?string $seed = null; private static int $seedIndex = 0; /** @var int[] */ private static array $rand = []; /** @var int[] */ private static array $seedParts; public function __construct( private RandomGeneratorInterface $randomGenerator, private int $intSize = PHP_INT_SIZE, ) { } /** * @param Hexadecimal | int | string | null $node Unused in this generator * @param int | null $clockSeq Unused in this generator * @param DateTimeInterface | null $dateTime A date-time instance to use when generating bytes */ public function generate($node = null, ?int $clockSeq = null, ?DateTimeInterface $dateTime = null): string { if ($dateTime === null) { $time = microtime(false); $time = substr($time, 11) . substr($time, 2, 3); } else { $time = $dateTime->format('Uv'); } if ($time > self::$time || ($dateTime !== null && $time !== self::$time)) { $this->randomize($time); } else { $time = $this->increment(); } if ($this->intSize >= 8) { $time = substr(pack('J', (int) $time), -6); } else { $time = str_pad(BigInteger::of($time)->toBytes(false), 6, "\x00", STR_PAD_LEFT); } assert(strlen($time) === 6); return $time . pack('n*', self::$rand[1], self::$rand[2], self::$rand[3], self::$rand[4], self::$rand[5]); } private function randomize(string $time): void { if (self::$seed === null) { $seed = $this->randomGenerator->generate(16); self::$seed = $seed; } else { $seed = $this->randomGenerator->generate(10); } /** @var int[] $rand */ $rand = unpack('n*', $seed); $rand[1] &= 0x03ff; self::$rand = $rand; self::$time = $time; } /** * Special thanks to Nicolas Grekas () for sharing the following information: * * Within the same ms, we increment the rand part by a random 24-bit number. * * Instead of getting this number from random_bytes(), which is slow, we get it by sha512-hashing self::$seed. This * produces 64 bytes of entropy, which we need to split in a list of 24-bit numbers. `unpack()` first splits them * into 16 x 32-bit numbers; we take the first byte of each number to get 5 extra 24-bit numbers. Then, we consume * each number one-by-one and run this logic every 21 iterations. * * `self::$rand` holds the random part of the UUID, split into 5 x 16-bit numbers for x86 portability. We increment * this random part by the next 24-bit number in the `self::$seedParts` list and decrement `self::$seedIndex`. */ private function increment(): string { if (self::$seedIndex === 0 && self::$seed !== null) { self::$seed = hash('sha512', self::$seed, true); /** @var int[] $s */ $s = unpack('l*', self::$seed); $s[] = ($s[1] >> 8 & 0xff0000) | ($s[2] >> 16 & 0xff00) | ($s[3] >> 24 & 0xff); $s[] = ($s[4] >> 8 & 0xff0000) | ($s[5] >> 16 & 0xff00) | ($s[6] >> 24 & 0xff); $s[] = ($s[7] >> 8 & 0xff0000) | ($s[8] >> 16 & 0xff00) | ($s[9] >> 24 & 0xff); $s[] = ($s[10] >> 8 & 0xff0000) | ($s[11] >> 16 & 0xff00) | ($s[12] >> 24 & 0xff); $s[] = ($s[13] >> 8 & 0xff0000) | ($s[14] >> 16 & 0xff00) | ($s[15] >> 24 & 0xff); self::$seedParts = $s; self::$seedIndex = 21; } self::$rand[5] = 0xffff & $carry = self::$rand[5] + 1 + (self::$seedParts[self::$seedIndex--] & 0xffffff); self::$rand[4] = 0xffff & $carry = self::$rand[4] + ($carry >> 16); self::$rand[3] = 0xffff & $carry = self::$rand[3] + ($carry >> 16); self::$rand[2] = 0xffff & $carry = self::$rand[2] + ($carry >> 16); self::$rand[1] += $carry >> 16; if (0xfc00 & self::$rand[1]) { $time = self::$time; $mtime = (int) substr($time, -9); if ($this->intSize >= 8 || strlen($time) < 10) { $time = (string) ((int) $time + 1); } elseif ($mtime === 999999999) { $time = (1 + (int) substr($time, 0, -9)) . '000000000'; } else { $mtime++; $time = substr_replace($time, str_pad((string) $mtime, 9, '0', STR_PAD_LEFT), -9); } $this->randomize($time); } return self::$time; } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Guid/Fields.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Guid; use Ramsey\Uuid\Exception\InvalidArgumentException; use Ramsey\Uuid\Fields\SerializableFieldsTrait; use Ramsey\Uuid\Rfc4122\FieldsInterface; use Ramsey\Uuid\Rfc4122\MaxTrait; use Ramsey\Uuid\Rfc4122\NilTrait; use Ramsey\Uuid\Rfc4122\VariantTrait; use Ramsey\Uuid\Rfc4122\VersionTrait; use Ramsey\Uuid\Type\Hexadecimal; use Ramsey\Uuid\Uuid; use function bin2hex; use function dechex; use function hexdec; use function pack; use function sprintf; use function str_pad; use function strlen; use function substr; use function unpack; use const STR_PAD_LEFT; /** * GUIDs consist of a set of named fields, according to RFC 9562 (formerly RFC 4122) * * @see Guid * * @immutable */ final class Fields implements FieldsInterface { use MaxTrait; use NilTrait; use SerializableFieldsTrait; use VariantTrait; use VersionTrait; /** * @param string $bytes A 16-byte binary string representation of a UUID * * @throws InvalidArgumentException if the byte string is not exactly 16 bytes * @throws InvalidArgumentException if the byte string does not represent a GUID * @throws InvalidArgumentException if the byte string does not contain a valid version */ public function __construct(private string $bytes) { if (strlen($this->bytes) !== 16) { throw new InvalidArgumentException( 'The byte string must be 16 bytes long; received ' . strlen($this->bytes) . ' bytes', ); } if (!$this->isCorrectVariant()) { throw new InvalidArgumentException( 'The byte string received does not conform to the RFC 9562 (formerly RFC 4122) ' . 'or Microsoft Corporation variants', ); } if (!$this->isCorrectVersion()) { throw new InvalidArgumentException('The byte string received does not contain a valid version'); } } public function getBytes(): string { return $this->bytes; } public function getTimeLow(): Hexadecimal { // Swap the bytes from little endian to network byte order. /** @var string[] $hex */ $hex = unpack( 'H*', pack( 'v*', hexdec(bin2hex(substr($this->bytes, 2, 2))), hexdec(bin2hex(substr($this->bytes, 0, 2))), ), ); return new Hexadecimal($hex[1] ?? ''); } public function getTimeMid(): Hexadecimal { // Swap the bytes from little endian to network byte order. /** @var string[] $hex */ $hex = unpack('H*', pack('v', hexdec(bin2hex(substr($this->bytes, 4, 2))))); return new Hexadecimal($hex[1] ?? ''); } public function getTimeHiAndVersion(): Hexadecimal { // Swap the bytes from little endian to network byte order. /** @var string[] $hex */ $hex = unpack('H*', pack('v', hexdec(bin2hex(substr($this->bytes, 6, 2))))); return new Hexadecimal($hex[1] ?? ''); } public function getTimestamp(): Hexadecimal { return new Hexadecimal(sprintf( '%03x%04s%08s', hexdec($this->getTimeHiAndVersion()->toString()) & 0x0fff, $this->getTimeMid()->toString(), $this->getTimeLow()->toString() )); } public function getClockSeq(): Hexadecimal { if ($this->isMax()) { $clockSeq = 0xffff; } elseif ($this->isNil()) { $clockSeq = 0x0000; } else { $clockSeq = hexdec(bin2hex(substr($this->bytes, 8, 2))) & 0x3fff; } return new Hexadecimal(str_pad(dechex($clockSeq), 4, '0', STR_PAD_LEFT)); } public function getClockSeqHiAndReserved(): Hexadecimal { return new Hexadecimal(bin2hex(substr($this->bytes, 8, 1))); } public function getClockSeqLow(): Hexadecimal { return new Hexadecimal(bin2hex(substr($this->bytes, 9, 1))); } public function getNode(): Hexadecimal { return new Hexadecimal(bin2hex(substr($this->bytes, 10))); } public function getVersion(): ?int { if ($this->isNil() || $this->isMax()) { return null; } /** @var int[] $parts */ $parts = unpack('n*', $this->bytes); return ($parts[4] >> 4) & 0x00f; } private function isCorrectVariant(): bool { if ($this->isNil() || $this->isMax()) { return true; } $variant = $this->getVariant(); return $variant === Uuid::RFC_4122 || $variant === Uuid::RESERVED_MICROSOFT; } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Guid/Guid.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Guid; use Ramsey\Uuid\Codec\CodecInterface; use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Converter\TimeConverterInterface; use Ramsey\Uuid\Uuid; /** * Guid represents a UUID with "native" (little-endian) byte order * * From Wikipedia: * * > The first three fields are unsigned 32- and 16-bit integers and are subject to swapping, while the last two fields * > consist of uninterpreted bytes, not subject to swapping. This byte swapping applies even for versions 3, 4, and 5, * > where the canonical fields do not correspond to the content of the UUID. * * The first three fields of a GUID are encoded in little-endian byte order, while the last three fields are in network * (big-endian) byte order. This is according to the history of the Microsoft GUID definition. * * According to the .NET Guid.ToByteArray method documentation: * * > Note that the order of bytes in the returned byte array is different from the string representation of a Guid value. * > The order of the beginning four-byte group and the next two two-byte groups is reversed, whereas the order of the * > last two-byte group and the closing six-byte group is the same. * * @link https://en.wikipedia.org/wiki/Universally_unique_identifier#Variants UUID Variants on Wikipedia * @link https://docs.microsoft.com/en-us/windows/win32/api/guiddef/ns-guiddef-guid Windows GUID structure * @link https://docs.microsoft.com/en-us/dotnet/api/system.guid .NET Guid Struct * @link https://docs.microsoft.com/en-us/dotnet/api/system.guid.tobytearray .NET Guid.ToByteArray Method * * @immutable */ final class Guid extends Uuid { public function __construct( Fields $fields, NumberConverterInterface $numberConverter, CodecInterface $codec, TimeConverterInterface $timeConverter, ) { parent::__construct($fields, $numberConverter, $codec, $timeConverter); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Guid/GuidBuilder.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Guid; use Ramsey\Uuid\Builder\UuidBuilderInterface; use Ramsey\Uuid\Codec\CodecInterface; use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Converter\TimeConverterInterface; use Ramsey\Uuid\Exception\UnableToBuildUuidException; use Ramsey\Uuid\UuidInterface; use Throwable; /** * GuidBuilder builds instances of Guid * * @see Guid * * @immutable */ class GuidBuilder implements UuidBuilderInterface { /** * @param NumberConverterInterface $numberConverter The number converter to use when constructing the Guid * @param TimeConverterInterface $timeConverter The time converter to use for converting timestamps extracted from a * UUID to Unix timestamps */ public function __construct( private NumberConverterInterface $numberConverter, private TimeConverterInterface $timeConverter, ) { } /** * Builds and returns a Guid * * @param CodecInterface $codec The codec to use for building this Guid instance * @param string $bytes The byte string from which to construct a UUID * * @return Guid The GuidBuilder returns an instance of Ramsey\Uuid\Guid\Guid * * @pure */ public function build(CodecInterface $codec, string $bytes): UuidInterface { try { /** @phpstan-ignore possiblyImpure.new */ return new Guid($this->buildFields($bytes), $this->numberConverter, $codec, $this->timeConverter); } catch (Throwable $e) { /** @phpstan-ignore possiblyImpure.methodCall, possiblyImpure.methodCall */ throw new UnableToBuildUuidException($e->getMessage(), (int) $e->getCode(), $e); } } /** * Proxy method to allow injecting a mock for testing * * @pure */ protected function buildFields(string $bytes): Fields { /** @phpstan-ignore possiblyImpure.new */ return new Fields($bytes); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Lazy/LazyUuidFromString.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Lazy; use DateTimeInterface; use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Exception\UnsupportedOperationException; use Ramsey\Uuid\Fields\FieldsInterface; use Ramsey\Uuid\Rfc4122\UuidV1; use Ramsey\Uuid\Rfc4122\UuidV6; use Ramsey\Uuid\Type\Hexadecimal; use Ramsey\Uuid\Type\Integer as IntegerObject; use Ramsey\Uuid\UuidFactory; use Ramsey\Uuid\UuidInterface; use ValueError; use function assert; use function bin2hex; use function hex2bin; use function sprintf; use function str_replace; use function substr; /** * Lazy version of a UUID: its format has not been determined yet, so it is mostly only usable for string/bytes * conversion. This object optimizes instantiation, serialization and string conversion time, at the cost of increased * overhead for more advanced UUID operations. * * > [!NOTE] * > The {@see FieldsInterface} does not declare methods that deprecated API relies upon: the API has been ported from * > the {@see \Ramsey\Uuid\Uuid} definition, and is deprecated anyway. * * > [!NOTE] * > The deprecated API from {@see \Ramsey\Uuid\Uuid} is in use here (on purpose): it will be removed once the * > deprecated API is gone from this class too. * * @internal this type is used internally for performance reasons and is not supposed to be directly referenced in consumer libraries. */ final class LazyUuidFromString implements UuidInterface { public const VALID_REGEX = '/\A[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\z/ms'; private ?UuidInterface $unwrapped = null; /** * @param non-empty-string $uuid */ public function __construct(private string $uuid) { } public static function fromBytes(string $bytes): self { $base16Uuid = bin2hex($bytes); return new self( substr($base16Uuid, 0, 8) . '-' . substr($base16Uuid, 8, 4) . '-' . substr($base16Uuid, 12, 4) . '-' . substr($base16Uuid, 16, 4) . '-' . substr($base16Uuid, 20, 12) ); } public function serialize(): string { return $this->uuid; } /** * @return array{string: non-empty-string} */ public function __serialize(): array { return ['string' => $this->uuid]; } /** * {@inheritDoc} * * @param non-empty-string $data */ public function unserialize(string $data): void { $this->uuid = $data; } /** * @param array{string?: non-empty-string} $data */ public function __unserialize(array $data): void { // @codeCoverageIgnoreStart if (!isset($data['string'])) { throw new ValueError(sprintf('%s(): Argument #1 ($data) is invalid', __METHOD__)); } // @codeCoverageIgnoreEnd $this->unserialize($data['string']); } public function getNumberConverter(): NumberConverterInterface { return ($this->unwrapped ?? $this->unwrap())->getNumberConverter(); } /** * @inheritDoc */ public function getFieldsHex(): array { return ($this->unwrapped ?? $this->unwrap())->getFieldsHex(); } public function getClockSeqHiAndReservedHex(): string { return ($this->unwrapped ?? $this->unwrap())->getClockSeqHiAndReservedHex(); } public function getClockSeqLowHex(): string { return ($this->unwrapped ?? $this->unwrap())->getClockSeqLowHex(); } public function getClockSequenceHex(): string { return ($this->unwrapped ?? $this->unwrap())->getClockSequenceHex(); } public function getDateTime(): DateTimeInterface { return ($this->unwrapped ?? $this->unwrap())->getDateTime(); } public function getLeastSignificantBitsHex(): string { return ($this->unwrapped ?? $this->unwrap())->getLeastSignificantBitsHex(); } public function getMostSignificantBitsHex(): string { return ($this->unwrapped ?? $this->unwrap())->getMostSignificantBitsHex(); } public function getNodeHex(): string { return ($this->unwrapped ?? $this->unwrap())->getNodeHex(); } public function getTimeHiAndVersionHex(): string { return ($this->unwrapped ?? $this->unwrap())->getTimeHiAndVersionHex(); } public function getTimeLowHex(): string { return ($this->unwrapped ?? $this->unwrap())->getTimeLowHex(); } public function getTimeMidHex(): string { return ($this->unwrapped ?? $this->unwrap())->getTimeMidHex(); } public function getTimestampHex(): string { return ($this->unwrapped ?? $this->unwrap())->getTimestampHex(); } public function getUrn(): string { return ($this->unwrapped ?? $this->unwrap())->getUrn(); } public function getVariant(): ?int { return ($this->unwrapped ?? $this->unwrap())->getVariant(); } public function getVersion(): ?int { return ($this->unwrapped ?? $this->unwrap())->getVersion(); } public function compareTo(UuidInterface $other): int { return ($this->unwrapped ?? $this->unwrap())->compareTo($other); } public function equals(?object $other): bool { if (!$other instanceof UuidInterface) { return false; } return $this->uuid === $other->toString(); } public function getBytes(): string { /** * @var non-empty-string * @phpstan-ignore possiblyImpure.functionCall, possiblyImpure.functionCall */ return (string) hex2bin(str_replace('-', '', $this->uuid)); } public function getFields(): FieldsInterface { return ($this->unwrapped ?? $this->unwrap())->getFields(); } public function getHex(): Hexadecimal { return ($this->unwrapped ?? $this->unwrap())->getHex(); } public function getInteger(): IntegerObject { return ($this->unwrapped ?? $this->unwrap())->getInteger(); } public function toString(): string { return $this->uuid; } public function __toString(): string { return $this->uuid; } public function jsonSerialize(): string { return $this->uuid; } /** * @deprecated Use {@see UuidInterface::getFields()} to get a {@see FieldsInterface} instance. If it is a * {@see Rfc4122FieldsInterface} instance, you may call {@see Rfc4122FieldsInterface::getClockSeqHiAndReserved()} * and use the arbitrary-precision math library of your choice to convert it to a string integer. */ public function getClockSeqHiAndReserved(): string { $instance = ($this->unwrapped ?? $this->unwrap()); $fields = $instance->getFields(); assert($fields instanceof \Ramsey\Uuid\Rfc4122\FieldsInterface); return $instance->getNumberConverter()->fromHex($fields->getClockSeqHiAndReserved()->toString()); } /** * @deprecated Use {@see UuidInterface::getFields()} to get a {@see FieldsInterface} instance. If it is a * {@see Rfc4122FieldsInterface} instance, you may call {@see Rfc4122FieldsInterface::getClockSeqLow()} and use * the arbitrary-precision math library of your choice to convert it to a string integer. */ public function getClockSeqLow(): string { $instance = ($this->unwrapped ?? $this->unwrap()); $fields = $instance->getFields(); assert($fields instanceof \Ramsey\Uuid\Rfc4122\FieldsInterface); return $instance->getNumberConverter()->fromHex($fields->getClockSeqLow()->toString()); } /** * @deprecated Use {@see UuidInterface::getFields()} to get a {@see FieldsInterface} instance. If it is a * {@see Rfc4122FieldsInterface} instance, you may call {@see Rfc4122FieldsInterface::getClockSeq()} and use the * arbitrary-precision math library of your choice to convert it to a string integer. */ public function getClockSequence(): string { $instance = ($this->unwrapped ?? $this->unwrap()); $fields = $instance->getFields(); assert($fields instanceof \Ramsey\Uuid\Rfc4122\FieldsInterface); return $instance->getNumberConverter()->fromHex($fields->getClockSeq()->toString()); } /** * @deprecated This method will be removed in 5.0.0. There is no direct alternative, but the same information may be * obtained by splitting in half the value returned by {@see UuidInterface::getHex()}. */ public function getLeastSignificantBits(): string { $instance = ($this->unwrapped ?? $this->unwrap()); return $instance->getNumberConverter()->fromHex(substr($instance->getHex()->toString(), 16)); } /** * @deprecated This method will be removed in 5.0.0. There is no direct alternative, but the same information may be * obtained by splitting in half the value returned by {@see UuidInterface::getHex()}. */ public function getMostSignificantBits(): string { $instance = ($this->unwrapped ?? $this->unwrap()); return $instance->getNumberConverter()->fromHex(substr($instance->getHex()->toString(), 0, 16)); } /** * @deprecated Use {@see UuidInterface::getFields()} to get a {@see FieldsInterface} instance. If it is a * {@see Rfc4122FieldsInterface} instance, you may call {@see Rfc4122FieldsInterface::getNode()} and use the * arbitrary-precision math library of your choice to convert it to a string integer. */ public function getNode(): string { $instance = ($this->unwrapped ?? $this->unwrap()); $fields = $instance->getFields(); assert($fields instanceof \Ramsey\Uuid\Rfc4122\FieldsInterface); return $instance->getNumberConverter()->fromHex($fields->getNode()->toString()); } /** * @deprecated Use {@see UuidInterface::getFields()} to get a {@see FieldsInterface} instance. If it is a * {@see Rfc4122FieldsInterface} instance, you may call {@see Rfc4122FieldsInterface::getTimeHiAndVersion()} and * use the arbitrary-precision math library of your choice to convert it to a string integer. */ public function getTimeHiAndVersion(): string { $instance = ($this->unwrapped ?? $this->unwrap()); $fields = $instance->getFields(); assert($fields instanceof \Ramsey\Uuid\Rfc4122\FieldsInterface); return $instance->getNumberConverter()->fromHex($fields->getTimeHiAndVersion()->toString()); } /** * @deprecated Use {@see UuidInterface::getFields()} to get a {@see FieldsInterface} instance. If it is a * {@see Rfc4122FieldsInterface} instance, you may call {@see Rfc4122FieldsInterface::getTimeLow()} and use the * arbitrary-precision math library of your choice to convert it to a string integer. */ public function getTimeLow(): string { $instance = ($this->unwrapped ?? $this->unwrap()); $fields = $instance->getFields(); assert($fields instanceof \Ramsey\Uuid\Rfc4122\FieldsInterface); return $instance->getNumberConverter()->fromHex($fields->getTimeLow()->toString()); } /** * @deprecated Use {@see UuidInterface::getFields()} to get a {@see FieldsInterface} instance. If it is a * {@see Rfc4122FieldsInterface} instance, you may call {@see Rfc4122FieldsInterface::getTimeMid()} and use the * arbitrary-precision math library of your choice to convert it to a string integer. */ public function getTimeMid(): string { $instance = ($this->unwrapped ?? $this->unwrap()); $fields = $instance->getFields(); assert($fields instanceof \Ramsey\Uuid\Rfc4122\FieldsInterface); return $instance->getNumberConverter()->fromHex($fields->getTimeMid()->toString()); } /** * @deprecated Use {@see UuidInterface::getFields()} to get a {@see FieldsInterface} instance. If it is a * {@see Rfc4122FieldsInterface} instance, you may call {@see Rfc4122FieldsInterface::getTimestamp()} and use * the arbitrary-precision math library of your choice to convert it to a string integer. */ public function getTimestamp(): string { $instance = ($this->unwrapped ?? $this->unwrap()); $fields = $instance->getFields(); assert($fields instanceof \Ramsey\Uuid\Rfc4122\FieldsInterface); if ($fields->getVersion() !== 1) { throw new UnsupportedOperationException('Not a time-based UUID'); } return $instance->getNumberConverter()->fromHex($fields->getTimestamp()->toString()); } public function toUuidV1(): UuidV1 { $instance = ($this->unwrapped ?? $this->unwrap()); if ($instance instanceof UuidV1) { return $instance; } assert($instance instanceof UuidV6); return $instance->toUuidV1(); } public function toUuidV6(): UuidV6 { $instance = ($this->unwrapped ?? $this->unwrap()); assert($instance instanceof UuidV6); return $instance; } private function unwrap(): UuidInterface { return $this->unwrapped = (new UuidFactory())->fromString($this->uuid); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Math/BrickMathCalculator.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Math; use Brick\Math\BigDecimal; use Brick\Math\BigInteger; use Brick\Math\Exception\MathException; use Brick\Math\RoundingMode as BrickMathRounding; use Ramsey\Uuid\Exception\InvalidArgumentException; use Ramsey\Uuid\Type\Decimal; use Ramsey\Uuid\Type\Hexadecimal; use Ramsey\Uuid\Type\Integer as IntegerObject; use Ramsey\Uuid\Type\NumberInterface; /** * A calculator using the brick/math library for arbitrary-precision arithmetic * * @immutable */ final class BrickMathCalculator implements CalculatorInterface { private const ROUNDING_MODE_MAP = [ RoundingMode::UNNECESSARY => BrickMathRounding::UNNECESSARY, RoundingMode::UP => BrickMathRounding::UP, RoundingMode::DOWN => BrickMathRounding::DOWN, RoundingMode::CEILING => BrickMathRounding::CEILING, RoundingMode::FLOOR => BrickMathRounding::FLOOR, RoundingMode::HALF_UP => BrickMathRounding::HALF_UP, RoundingMode::HALF_DOWN => BrickMathRounding::HALF_DOWN, RoundingMode::HALF_CEILING => BrickMathRounding::HALF_CEILING, RoundingMode::HALF_FLOOR => BrickMathRounding::HALF_FLOOR, RoundingMode::HALF_EVEN => BrickMathRounding::HALF_EVEN, ]; public function add(NumberInterface $augend, NumberInterface ...$addends): NumberInterface { $sum = BigInteger::of($augend->toString()); foreach ($addends as $addend) { $sum = $sum->plus($addend->toString()); } /** @phpstan-ignore possiblyImpure.new */ return new IntegerObject((string) $sum); } public function subtract(NumberInterface $minuend, NumberInterface ...$subtrahends): NumberInterface { $difference = BigInteger::of($minuend->toString()); foreach ($subtrahends as $subtrahend) { $difference = $difference->minus($subtrahend->toString()); } /** @phpstan-ignore possiblyImpure.new */ return new IntegerObject((string) $difference); } public function multiply(NumberInterface $multiplicand, NumberInterface ...$multipliers): NumberInterface { $product = BigInteger::of($multiplicand->toString()); foreach ($multipliers as $multiplier) { $product = $product->multipliedBy($multiplier->toString()); } /** @phpstan-ignore possiblyImpure.new */ return new IntegerObject((string) $product); } public function divide( int $roundingMode, int $scale, NumberInterface $dividend, NumberInterface ...$divisors, ): NumberInterface { /** @phpstan-ignore possiblyImpure.methodCall */ $brickRounding = $this->getBrickRoundingMode($roundingMode); $quotient = BigDecimal::of($dividend->toString()); foreach ($divisors as $divisor) { $quotient = $quotient->dividedBy($divisor->toString(), $scale, $brickRounding); } if ($scale === 0) { /** @phpstan-ignore possiblyImpure.new */ return new IntegerObject((string) $quotient->toBigInteger()); } /** @phpstan-ignore possiblyImpure.new */ return new Decimal((string) $quotient); } public function fromBase(string $value, int $base): IntegerObject { try { /** @phpstan-ignore possiblyImpure.new */ return new IntegerObject((string) BigInteger::fromBase($value, $base)); } catch (MathException | \InvalidArgumentException $exception) { throw new InvalidArgumentException( $exception->getMessage(), (int) $exception->getCode(), $exception ); } } public function toBase(IntegerObject $value, int $base): string { try { return BigInteger::of($value->toString())->toBase($base); } catch (MathException | \InvalidArgumentException $exception) { throw new InvalidArgumentException( $exception->getMessage(), (int) $exception->getCode(), $exception ); } } public function toHexadecimal(IntegerObject $value): Hexadecimal { /** @phpstan-ignore possiblyImpure.new */ return new Hexadecimal($this->toBase($value, 16)); } public function toInteger(Hexadecimal $value): IntegerObject { return $this->fromBase($value->toString(), 16); } /** * Maps ramsey/uuid rounding modes to those used by brick/math * * @return BrickMathRounding::* */ private function getBrickRoundingMode(int $roundingMode) { return self::ROUNDING_MODE_MAP[$roundingMode] ?? BrickMathRounding::UNNECESSARY; } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Math/CalculatorInterface.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Math; use Ramsey\Uuid\Type\Hexadecimal; use Ramsey\Uuid\Type\Integer as IntegerObject; use Ramsey\Uuid\Type\NumberInterface; /** * A calculator performs arithmetic operations on numbers * * @immutable */ interface CalculatorInterface { /** * Returns the sum of all the provided parameters * * @param NumberInterface $augend The first addend (the integer being added to) * @param NumberInterface ...$addends The additional integers to a add to the augend * * @return NumberInterface The sum of all the parameters * * @pure */ public function add(NumberInterface $augend, NumberInterface ...$addends): NumberInterface; /** * Returns the difference of all the provided parameters * * @param NumberInterface $minuend The integer being subtracted from * @param NumberInterface ...$subtrahends The integers to subtract from the minuend * * @return NumberInterface The difference after subtracting all parameters * * @pure */ public function subtract(NumberInterface $minuend, NumberInterface ...$subtrahends): NumberInterface; /** * Returns the product of all the provided parameters * * @param NumberInterface $multiplicand The integer to be multiplied * @param NumberInterface ...$multipliers The factors by which to multiply the multiplicand * * @return NumberInterface The product of multiplying all the provided parameters * * @pure */ public function multiply(NumberInterface $multiplicand, NumberInterface ...$multipliers): NumberInterface; /** * Returns the quotient of the provided parameters divided left-to-right * * @param int $roundingMode The RoundingMode constant to use for this operation * @param int $scale The scale to use for this operation * @param NumberInterface $dividend The integer to be divided * @param NumberInterface ...$divisors The integers to divide $dividend by, in the order in which the division * operations should take place (left-to-right) * * @return NumberInterface The quotient of dividing the provided parameters left-to-right * * @pure */ public function divide( int $roundingMode, int $scale, NumberInterface $dividend, NumberInterface ...$divisors, ): NumberInterface; /** * Converts a value from an arbitrary base to a base-10 integer value * * @param string $value The value to convert * @param int $base The base to convert from (i.e., 2, 16, 32, etc.) * * @return IntegerObject The base-10 integer value of the converted value * * @pure */ public function fromBase(string $value, int $base): IntegerObject; /** * Converts a base-10 integer value to an arbitrary base * * @param IntegerObject $value The integer value to convert * @param int $base The base to convert to (i.e., 2, 16, 32, etc.) * * @return string The value represented in the specified base * * @pure */ public function toBase(IntegerObject $value, int $base): string; /** * Converts an Integer instance to a Hexadecimal instance * * @pure */ public function toHexadecimal(IntegerObject $value): Hexadecimal; /** * Converts a Hexadecimal instance to an Integer instance * * @pure */ public function toInteger(Hexadecimal $value): IntegerObject; } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Math/RoundingMode.php ================================================ = 0.5; otherwise, behaves as for DOWN. Note that this is the * rounding mode commonly taught at school. */ public const HALF_UP = 5; /** * Rounds towards "nearest neighbor" unless both neighbors are equidistant, in which case round down. * * Behaves as for UP if the discarded fraction is > 0.5; otherwise, behaves as for DOWN. */ public const HALF_DOWN = 6; /** * Rounds towards "nearest neighbor" unless both neighbors are equidistant, in which case round towards positive infinity. * * If the result is positive, behaves as for HALF_UP; if negative, behaves as for HALF_DOWN. */ public const HALF_CEILING = 7; /** * Rounds towards "nearest neighbor" unless both neighbors are equidistant, in which case round towards negative infinity. * * If the result is positive, behaves as for HALF_DOWN; if negative, behaves as for HALF_UP. */ public const HALF_FLOOR = 8; /** * Rounds towards the "nearest neighbor" unless both neighbors are equidistant, in which case rounds towards the even neighbor. * * Behaves as for HALF_UP if the digit to the left of the discarded fraction is odd; behaves as for HALF_DOWN if it's even. * * Note that this is the rounding mode that statistically minimizes cumulative error when applied repeatedly over a * sequence of calculations. It is sometimes known as "Banker's rounding", and is chiefly used in the USA. */ public const HALF_EVEN = 9; /** * Private constructor. This class is not instantiable. * * @codeCoverageIgnore */ private function __construct() { } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Nonstandard/Fields.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Nonstandard; use Ramsey\Uuid\Exception\InvalidArgumentException; use Ramsey\Uuid\Fields\SerializableFieldsTrait; use Ramsey\Uuid\Rfc4122\FieldsInterface; use Ramsey\Uuid\Rfc4122\VariantTrait; use Ramsey\Uuid\Type\Hexadecimal; use function bin2hex; use function dechex; use function hexdec; use function sprintf; use function str_pad; use function strlen; use function substr; use const STR_PAD_LEFT; /** * Nonstandard UUID fields do not conform to the RFC 9562 (formerly RFC 4122) standard * * Since some systems may create nonstandard UUIDs, this implements the {@see FieldsInterface}, so that functionality of * a nonstandard UUID is not degraded, in the event these UUIDs are expected to contain RFC 9562 (formerly RFC 4122) fields. * * Internally, this class represents the fields together as a 16-byte binary string. * * @immutable */ final class Fields implements FieldsInterface { use SerializableFieldsTrait; use VariantTrait; /** * @param string $bytes A 16-byte binary string representation of a UUID * * @throws InvalidArgumentException if the byte string is not exactly 16 bytes */ public function __construct(private string $bytes) { if (strlen($this->bytes) !== 16) { throw new InvalidArgumentException( 'The byte string must be 16 bytes long; received ' . strlen($this->bytes) . ' bytes', ); } } public function getBytes(): string { return $this->bytes; } public function getClockSeq(): Hexadecimal { $clockSeq = hexdec(bin2hex(substr($this->bytes, 8, 2))) & 0x3fff; return new Hexadecimal(str_pad(dechex($clockSeq), 4, '0', STR_PAD_LEFT)); } public function getClockSeqHiAndReserved(): Hexadecimal { return new Hexadecimal(bin2hex(substr($this->bytes, 8, 1))); } public function getClockSeqLow(): Hexadecimal { return new Hexadecimal(bin2hex(substr($this->bytes, 9, 1))); } public function getNode(): Hexadecimal { return new Hexadecimal(bin2hex(substr($this->bytes, 10))); } public function getTimeHiAndVersion(): Hexadecimal { return new Hexadecimal(bin2hex(substr($this->bytes, 6, 2))); } public function getTimeLow(): Hexadecimal { return new Hexadecimal(bin2hex(substr($this->bytes, 0, 4))); } public function getTimeMid(): Hexadecimal { return new Hexadecimal(bin2hex(substr($this->bytes, 4, 2))); } public function getTimestamp(): Hexadecimal { return new Hexadecimal(sprintf( '%03x%04s%08s', hexdec($this->getTimeHiAndVersion()->toString()) & 0x0fff, $this->getTimeMid()->toString(), $this->getTimeLow()->toString() )); } public function getVersion(): ?int { return null; } public function isNil(): bool { return false; } public function isMax(): bool { return false; } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Nonstandard/Uuid.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Nonstandard; use Ramsey\Uuid\Codec\CodecInterface; use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Converter\TimeConverterInterface; use Ramsey\Uuid\Uuid as BaseUuid; /** * Nonstandard\Uuid is a UUID that doesn't conform to RFC 9562 (formerly RFC 4122) * * @immutable * @pure */ final class Uuid extends BaseUuid { public function __construct( Fields $fields, NumberConverterInterface $numberConverter, CodecInterface $codec, TimeConverterInterface $timeConverter, ) { parent::__construct($fields, $numberConverter, $codec, $timeConverter); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Nonstandard/UuidBuilder.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Nonstandard; use Ramsey\Uuid\Builder\UuidBuilderInterface; use Ramsey\Uuid\Codec\CodecInterface; use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Converter\TimeConverterInterface; use Ramsey\Uuid\Exception\UnableToBuildUuidException; use Ramsey\Uuid\UuidInterface; use Throwable; /** * Nonstandard\UuidBuilder builds instances of Nonstandard\Uuid * * @immutable */ class UuidBuilder implements UuidBuilderInterface { /** * @param NumberConverterInterface $numberConverter The number converter to use when constructing the Nonstandard\Uuid * @param TimeConverterInterface $timeConverter The time converter to use for converting timestamps extracted from a * UUID to Unix timestamps */ public function __construct( private NumberConverterInterface $numberConverter, private TimeConverterInterface $timeConverter, ) { } /** * Builds and returns a Nonstandard\Uuid * * @param CodecInterface $codec The codec to use for building this instance * @param string $bytes The byte string from which to construct a UUID * * @return Uuid The Nonstandard\UuidBuilder returns an instance of Nonstandard\Uuid * * @pure */ public function build(CodecInterface $codec, string $bytes): UuidInterface { try { /** @phpstan-ignore possiblyImpure.new */ return new Uuid($this->buildFields($bytes), $this->numberConverter, $codec, $this->timeConverter); } catch (Throwable $e) { /** @phpstan-ignore possiblyImpure.methodCall, possiblyImpure.methodCall */ throw new UnableToBuildUuidException($e->getMessage(), (int) $e->getCode(), $e); } } /** * Proxy method to allow injecting a mock for testing * * @pure */ protected function buildFields(string $bytes): Fields { /** @phpstan-ignore possiblyImpure.new */ return new Fields($bytes); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Nonstandard/UuidV6.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Nonstandard; use Ramsey\Uuid\Codec\CodecInterface; use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Converter\TimeConverterInterface; use Ramsey\Uuid\Exception\InvalidArgumentException; use Ramsey\Uuid\Lazy\LazyUuidFromString; use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; use Ramsey\Uuid\Rfc4122\TimeTrait; use Ramsey\Uuid\Rfc4122\UuidInterface; use Ramsey\Uuid\Rfc4122\UuidV1; use Ramsey\Uuid\Uuid as BaseUuid; /** * Reordered time, or version 6, UUIDs include timestamp, clock sequence, and node values that are combined into a * 128-bit unsigned integer * * @deprecated Use {@see \Ramsey\Uuid\Rfc4122\UuidV6} instead. * * @link https://github.com/uuid6/uuid6-ietf-draft UUID version 6 IETF draft * @link http://gh.peabody.io/uuidv6/ "Version 6" UUIDs * @link https://www.rfc-editor.org/rfc/rfc9562#section-5.6 RFC 9562, 5.6. UUID Version 6 * * @immutable */ class UuidV6 extends BaseUuid implements UuidInterface { use TimeTrait; /** * Creates a version 6 (reordered Gregorian time) UUID * * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID * @param NumberConverterInterface $numberConverter The number converter to use for converting hex values to/from integers * @param CodecInterface $codec The codec to use when encoding or decoding UUID strings * @param TimeConverterInterface $timeConverter The time converter to use for converting timestamps extracted from a * UUID to unix timestamps */ public function __construct( Rfc4122FieldsInterface $fields, NumberConverterInterface $numberConverter, CodecInterface $codec, TimeConverterInterface $timeConverter, ) { if ($fields->getVersion() !== BaseUuid::UUID_TYPE_REORDERED_TIME) { throw new InvalidArgumentException( 'Fields used to create a UuidV6 must represent a version 6 (reordered time) UUID', ); } parent::__construct($fields, $numberConverter, $codec, $timeConverter); } /** * Converts this UUID into an instance of a version 1 UUID */ public function toUuidV1(): UuidV1 { $hex = $this->getHex()->toString(); $hex = substr($hex, 7, 5) . substr($hex, 13, 3) . substr($hex, 3, 4) . '1' . substr($hex, 0, 3) . substr($hex, 16); /** @var LazyUuidFromString $uuid */ $uuid = BaseUuid::fromBytes((string) hex2bin($hex)); return $uuid->toUuidV1(); } /** * Converts a version 1 UUID into an instance of a version 6 UUID */ public static function fromUuidV1(UuidV1 $uuidV1): \Ramsey\Uuid\Rfc4122\UuidV6 { $hex = $uuidV1->getHex()->toString(); $hex = substr($hex, 13, 3) . substr($hex, 8, 4) . substr($hex, 0, 5) . '6' . substr($hex, 5, 3) . substr($hex, 16); /** @var LazyUuidFromString $uuid */ $uuid = BaseUuid::fromBytes((string) hex2bin($hex)); return $uuid->toUuidV6(); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Provider/Dce/SystemDceSecurityProvider.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Provider\Dce; use Ramsey\Uuid\Exception\DceSecurityException; use Ramsey\Uuid\Provider\DceSecurityProviderInterface; use Ramsey\Uuid\Type\Integer as IntegerObject; use function escapeshellarg; use function preg_split; use function str_getcsv; use function strrpos; use function strtolower; use function strtoupper; use function substr; use function trim; use const PREG_SPLIT_NO_EMPTY; /** * SystemDceSecurityProvider retrieves the user or group identifiers from the system */ class SystemDceSecurityProvider implements DceSecurityProviderInterface { /** * @throws DceSecurityException if unable to get a user identifier * * @inheritDoc */ public function getUid(): IntegerObject { /** @var IntegerObject | int | float | string | null $uid */ static $uid = null; if ($uid instanceof IntegerObject) { return $uid; } if ($uid === null) { $uid = $this->getSystemUid(); } if ($uid === '') { throw new DceSecurityException( 'Unable to get a user identifier using the system DCE Security provider; please provide a custom ' . 'identifier or use a different provider', ); } $uid = new IntegerObject($uid); return $uid; } /** * @throws DceSecurityException if unable to get a group identifier * * @inheritDoc */ public function getGid(): IntegerObject { /** @var IntegerObject | int | float | string | null $gid */ static $gid = null; if ($gid instanceof IntegerObject) { return $gid; } if ($gid === null) { $gid = $this->getSystemGid(); } if ($gid === '') { throw new DceSecurityException( 'Unable to get a group identifier using the system DCE Security provider; please provide a custom ' . 'identifier or use a different provider', ); } $gid = new IntegerObject($gid); return $gid; } /** * Returns the UID from the system */ private function getSystemUid(): string { if (!$this->hasShellExec()) { return ''; } return match ($this->getOs()) { 'WIN' => $this->getWindowsUid(), default => trim((string) shell_exec('id -u')), }; } /** * Returns the GID from the system */ private function getSystemGid(): string { if (!$this->hasShellExec()) { return ''; } return match ($this->getOs()) { 'WIN' => $this->getWindowsGid(), default => trim((string) shell_exec('id -g')), }; } /** * Returns true if shell_exec() is available for use */ private function hasShellExec(): bool { return !str_contains(strtolower((string) ini_get('disable_functions')), 'shell_exec'); } /** * Returns the PHP_OS string */ private function getOs(): string { /** @var string $phpOs */ $phpOs = constant('PHP_OS'); return strtoupper(substr($phpOs, 0, 3)); } /** * Returns the user identifier for a user on a Windows system * * Windows does not have the same concept as an effective POSIX UID for the running script. Instead, each user is * uniquely identified by an SID (security identifier). The SID includes three 32-bit unsigned integers that make up * a unique domain identifier, followed by an RID (relative identifier) that we will use as the UID. The primary * caveat is that this UID may not be unique to the system, since it is, instead, unique to the domain. * * @link https://www.lifewire.com/what-is-an-sid-number-2626005 What Is an SID Number? * @link https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/81d92bba-d22b-4a8c-908a-554ab29148ab Well-known SID Structures * @link https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/manage/understand-security-identifiers#well-known-sids Well-known SIDs * @link https://www.windows-commandline.com/get-sid-of-user/ Get SID of user */ private function getWindowsUid(): string { $response = shell_exec('whoami /user /fo csv /nh'); if ($response === null) { return ''; } $sid = str_getcsv(trim((string) $response), escape: '\\')[1] ?? ''; if (($lastHyphen = strrpos($sid, '-')) === false) { return ''; } return trim(substr($sid, $lastHyphen + 1)); } /** * Returns a group identifier for a user on a Windows system * * Since Windows does not have the same concept as an effective POSIX GID for the running script, we will get the * local group memberships for the user running the script. Then, we will get the SID (security identifier) for the * first group that appears in that list. Finally, we will return the RID (relative identifier) for the group and * use that as the GID. * * @link https://www.windows-commandline.com/list-of-user-groups-command-line/ List of user groups command line */ private function getWindowsGid(): string { $response = shell_exec('net user %username% | findstr /b /i "Local Group Memberships"'); if ($response === null) { return ''; } $userGroups = preg_split('/\s{2,}/', (string) $response, -1, PREG_SPLIT_NO_EMPTY); $firstGroup = trim($userGroups[1] ?? '', "* \t\n\r\0\x0B"); if ($firstGroup === '') { return ''; } $response = shell_exec('wmic group get name,sid | findstr /b /i ' . escapeshellarg($firstGroup)); if ($response === null) { return ''; } $userGroup = preg_split('/\s{2,}/', (string) $response, -1, PREG_SPLIT_NO_EMPTY); $sid = $userGroup[1] ?? ''; if (($lastHyphen = strrpos($sid, '-')) === false) { return ''; } return trim(substr($sid, $lastHyphen + 1)); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Provider/DceSecurityProviderInterface.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Provider; use Ramsey\Uuid\Rfc4122\UuidV2; use Ramsey\Uuid\Type\Integer as IntegerObject; /** * A DCE provider provides access to local domain identifiers for version 2, DCE Security, UUIDs * * @see UuidV2 */ interface DceSecurityProviderInterface { /** * Returns a user identifier for the system * * @link https://en.wikipedia.org/wiki/User_identifier User identifier */ public function getUid(): IntegerObject; /** * Returns a group identifier for the system * * @link https://en.wikipedia.org/wiki/Group_identifier Group identifier */ public function getGid(): IntegerObject; } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Provider/Node/FallbackNodeProvider.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Provider\Node; use Ramsey\Uuid\Exception\NodeException; use Ramsey\Uuid\Provider\NodeProviderInterface; use Ramsey\Uuid\Type\Hexadecimal; /** * FallbackNodeProvider retrieves the system node ID by stepping through a list of providers until a node ID can be obtained */ class FallbackNodeProvider implements NodeProviderInterface { /** * @param iterable $providers Array of node providers */ public function __construct(private iterable $providers) { } public function getNode(): Hexadecimal { $lastProviderException = null; foreach ($this->providers as $provider) { try { return $provider->getNode(); } catch (NodeException $exception) { $lastProviderException = $exception; continue; } } throw new NodeException(message: 'Unable to find a suitable node provider', previous: $lastProviderException); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Provider/Node/NodeProviderCollection.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Provider\Node; use Ramsey\Collection\AbstractCollection; use Ramsey\Uuid\Provider\NodeProviderInterface; use Ramsey\Uuid\Type\Hexadecimal; /** * A collection of NodeProviderInterface objects * * @deprecated this class has been deprecated and will be removed in 5.0.0. The use-case for this class comes from a * pre-`phpstan/phpstan` and pre-`vimeo/psalm` ecosystem, in which type safety had to be mostly enforced at runtime: * that is no longer necessary, now that you can safely verify your code to be correct and use more generic types * like `iterable` instead. * * @extends AbstractCollection */ class NodeProviderCollection extends AbstractCollection { public function getType(): string { return NodeProviderInterface::class; } /** * Re-constructs the object from its serialized form * * @param string $serialized The serialized PHP string to unserialize into a UuidInterface instance */ public function unserialize($serialized): void { /** @var array $data */ $data = unserialize($serialized, [ 'allowed_classes' => [ Hexadecimal::class, RandomNodeProvider::class, StaticNodeProvider::class, SystemNodeProvider::class, ], ]); /** @phpstan-ignore-next-line */ $this->data = array_filter($data, fn ($unserialized): bool => $unserialized instanceof NodeProviderInterface); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Provider/Node/RandomNodeProvider.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Provider\Node; use Ramsey\Uuid\Exception\RandomSourceException; use Ramsey\Uuid\Provider\NodeProviderInterface; use Ramsey\Uuid\Type\Hexadecimal; use Throwable; use function bin2hex; use function dechex; use function hex2bin; use function hexdec; use function str_pad; use function substr; use const STR_PAD_LEFT; /** * RandomNodeProvider generates a random node ID * * @link https://www.rfc-editor.org/rfc/rfc9562#section-6.10 RFC 9562, 6.10. UUIDs That Do Not Identify the Host */ class RandomNodeProvider implements NodeProviderInterface { public function getNode(): Hexadecimal { try { $nodeBytes = random_bytes(6); } catch (Throwable $exception) { throw new RandomSourceException($exception->getMessage(), (int) $exception->getCode(), $exception); } // Split the node bytes for math on 32-bit systems. $nodeMsb = substr($nodeBytes, 0, 3); $nodeLsb = substr($nodeBytes, 3); // Set the multicast bit; see RFC 9562, section 6.10. $nodeMsb = hex2bin(str_pad(dechex(hexdec(bin2hex($nodeMsb)) | 0x010000), 6, '0', STR_PAD_LEFT)); return new Hexadecimal(str_pad(bin2hex($nodeMsb . $nodeLsb), 12, '0', STR_PAD_LEFT)); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Provider/Node/StaticNodeProvider.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Provider\Node; use Ramsey\Uuid\Exception\InvalidArgumentException; use Ramsey\Uuid\Provider\NodeProviderInterface; use Ramsey\Uuid\Type\Hexadecimal; use function dechex; use function hexdec; use function str_pad; use function substr; use const STR_PAD_LEFT; /** * StaticNodeProvider provides a static node value with the multicast bit set * * @link https://www.rfc-editor.org/rfc/rfc9562#section-6.10 RFC 9562, 6.10. UUIDs That Do Not Identify the Host */ class StaticNodeProvider implements NodeProviderInterface { private Hexadecimal $node; /** * @param Hexadecimal $node The static node value to use */ public function __construct(Hexadecimal $node) { if (strlen($node->toString()) > 12) { throw new InvalidArgumentException('Static node value cannot be greater than 12 hexadecimal characters'); } $this->node = $this->setMulticastBit($node); } public function getNode(): Hexadecimal { return $this->node; } /** * Set the multicast bit for the static node value */ private function setMulticastBit(Hexadecimal $node): Hexadecimal { $nodeHex = str_pad($node->toString(), 12, '0', STR_PAD_LEFT); $firstOctet = substr($nodeHex, 0, 2); $firstOctet = str_pad(dechex(hexdec($firstOctet) | 0x01), 2, '0', STR_PAD_LEFT); return new Hexadecimal($firstOctet . substr($nodeHex, 2)); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Provider/Node/SystemNodeProvider.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Provider\Node; use Ramsey\Uuid\Exception\NodeException; use Ramsey\Uuid\Provider\NodeProviderInterface; use Ramsey\Uuid\Type\Hexadecimal; use function array_filter; use function array_map; use function array_walk; use function count; use function ob_get_clean; use function ob_start; use function preg_match; use function preg_match_all; use function reset; use function str_contains; use function str_replace; use function strtolower; use function strtoupper; use function substr; use const GLOB_NOSORT; use const PREG_PATTERN_ORDER; /** * SystemNodeProvider retrieves the system node ID, if possible * * The system node ID, or host ID, is often the same as the MAC address for a network interface on the host. */ class SystemNodeProvider implements NodeProviderInterface { /** * Pattern to match nodes in `ifconfig` and `ipconfig` output. */ private const IFCONFIG_PATTERN = '/[^:]([0-9a-f]{2}([:-])[0-9a-f]{2}(\2[0-9a-f]{2}){4})[^:]/i'; /** * Pattern to match nodes in sysfs stream output. */ private const SYSFS_PATTERN = '/^([0-9a-f]{2}:){5}[0-9a-f]{2}$/i'; public function getNode(): Hexadecimal { $node = $this->getNodeFromSystem(); if ($node === '') { throw new NodeException('Unable to fetch a node for this system'); } return new Hexadecimal($node); } /** * Returns the system node if found */ protected function getNodeFromSystem(): string { /** @var string | null $node */ static $node = null; if ($node !== null) { return $node; } // First, try a Linux-specific approach. $node = $this->getSysfs(); if ($node === '') { // Search ifconfig output for MAC addresses & return the first one. $node = $this->getIfconfig(); } $node = str_replace([':', '-'], '', $node); return $node; } /** * Returns the network interface configuration for the system * * @codeCoverageIgnore */ protected function getIfconfig(): string { if (str_contains(strtolower((string) ini_get('disable_functions')), 'passthru')) { return ''; } /** @var string $phpOs */ $phpOs = constant('PHP_OS'); ob_start(); switch (strtoupper(substr($phpOs, 0, 3))) { case 'WIN': passthru('ipconfig /all 2>&1'); break; case 'DAR': passthru('ifconfig 2>&1'); break; case 'FRE': passthru('netstat -i -f link 2>&1'); break; case 'LIN': default: passthru('netstat -ie 2>&1'); break; } $ifconfig = (string) ob_get_clean(); if (preg_match_all(self::IFCONFIG_PATTERN, $ifconfig, $matches, PREG_PATTERN_ORDER)) { foreach ($matches[1] as $iface) { if ($iface !== '00:00:00:00:00:00' && $iface !== '00-00-00-00-00-00') { return $iface; } } } return ''; } /** * Returns MAC address from the first system interface via the sysfs interface */ protected function getSysfs(): string { /** @var string $phpOs */ $phpOs = constant('PHP_OS'); if (strtoupper($phpOs) !== 'LINUX') { return ''; } $addressPaths = glob('/sys/class/net/*/address', GLOB_NOSORT); if ($addressPaths === false || count($addressPaths) === 0) { return ''; } /** @var array $macs */ $macs = []; array_walk($addressPaths, function (string $addressPath) use (&$macs): void { if (is_readable($addressPath)) { $macs[] = file_get_contents($addressPath); } }); /** @var callable $trim */ $trim = 'trim'; $macs = array_map($trim, $macs); // Remove invalid entries. $macs = array_filter($macs, function (mixed $address): bool { assert(is_string($address)); return $address !== '00:00:00:00:00:00' && preg_match(self::SYSFS_PATTERN, $address); }); /** @var bool | string $mac */ $mac = reset($macs); return (string) $mac; } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Provider/NodeProviderInterface.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Provider; use Ramsey\Uuid\Type\Hexadecimal; /** * A node provider retrieves or generates a node ID */ interface NodeProviderInterface { /** * Returns a node ID * * @return Hexadecimal The node ID as a hexadecimal string */ public function getNode(): Hexadecimal; } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Provider/Time/FixedTimeProvider.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Provider\Time; use Ramsey\Uuid\Provider\TimeProviderInterface; use Ramsey\Uuid\Type\Integer as IntegerObject; use Ramsey\Uuid\Type\Time; /** * FixedTimeProvider uses a known time to provide the time * * This provider allows the use of a previously generated, or known, time when generating time-based UUIDs. */ class FixedTimeProvider implements TimeProviderInterface { public function __construct(private Time $time) { } /** * Sets the `usec` component of the time * * @param IntegerObject | int | string $value The `usec` value to set */ public function setUsec($value): void { $this->time = new Time($this->time->getSeconds(), $value); } /** * Sets the `sec` component of the time * * @param IntegerObject | int | string $value The `sec` value to set */ public function setSec($value): void { $this->time = new Time($value, $this->time->getMicroseconds()); } public function getTime(): Time { return $this->time; } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Provider/Time/SystemTimeProvider.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Provider\Time; use Ramsey\Uuid\Provider\TimeProviderInterface; use Ramsey\Uuid\Type\Time; use function gettimeofday; /** * SystemTimeProvider retrieves the current time using built-in PHP functions */ class SystemTimeProvider implements TimeProviderInterface { public function getTime(): Time { $time = gettimeofday(); return new Time($time['sec'], $time['usec']); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Provider/TimeProviderInterface.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Provider; use Ramsey\Uuid\Type\Time; /** * A time provider retrieves the current time */ interface TimeProviderInterface { /** * Returns a time object */ public function getTime(): Time; } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Rfc4122/Fields.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Rfc4122; use Ramsey\Uuid\Exception\InvalidArgumentException; use Ramsey\Uuid\Fields\SerializableFieldsTrait; use Ramsey\Uuid\Type\Hexadecimal; use Ramsey\Uuid\Uuid; use function bin2hex; use function dechex; use function hexdec; use function sprintf; use function str_pad; use function strlen; use function substr; use function unpack; use const STR_PAD_LEFT; /** * RFC 9562 (formerly RFC 4122) variant UUIDs consist of a set of named fields * * Internally, this class represents the fields together as a 16-byte binary string. * * @immutable */ final class Fields implements FieldsInterface { use MaxTrait; use NilTrait; use SerializableFieldsTrait; use VariantTrait; use VersionTrait; /** * @param string $bytes A 16-byte binary string representation of a UUID * * @throws InvalidArgumentException if the byte string is not exactly 16 bytes * @throws InvalidArgumentException if the byte string does not represent an RFC 9562 (formerly RFC 4122) UUID * @throws InvalidArgumentException if the byte string does not contain a valid version */ public function __construct(private string $bytes) { if (strlen($this->bytes) !== 16) { throw new InvalidArgumentException( 'The byte string must be 16 bytes long; ' . 'received ' . strlen($this->bytes) . ' bytes', ); } if (!$this->isCorrectVariant()) { throw new InvalidArgumentException( 'The byte string received does not conform to the RFC 9562 (formerly RFC 4122) variant', ); } if (!$this->isCorrectVersion()) { throw new InvalidArgumentException( 'The byte string received does not contain a valid RFC 9562 (formerly RFC 4122) version', ); } } /** * @pure */ public function getBytes(): string { return $this->bytes; } public function getClockSeq(): Hexadecimal { if ($this->isMax()) { $clockSeq = 0xffff; } elseif ($this->isNil()) { $clockSeq = 0x0000; } else { $clockSeq = hexdec(bin2hex(substr($this->bytes, 8, 2))) & 0x3fff; } return new Hexadecimal(str_pad(dechex($clockSeq), 4, '0', STR_PAD_LEFT)); } public function getClockSeqHiAndReserved(): Hexadecimal { return new Hexadecimal(bin2hex(substr($this->bytes, 8, 1))); } public function getClockSeqLow(): Hexadecimal { return new Hexadecimal(bin2hex(substr($this->bytes, 9, 1))); } public function getNode(): Hexadecimal { return new Hexadecimal(bin2hex(substr($this->bytes, 10))); } public function getTimeHiAndVersion(): Hexadecimal { return new Hexadecimal(bin2hex(substr($this->bytes, 6, 2))); } public function getTimeLow(): Hexadecimal { return new Hexadecimal(bin2hex(substr($this->bytes, 0, 4))); } public function getTimeMid(): Hexadecimal { return new Hexadecimal(bin2hex(substr($this->bytes, 4, 2))); } /** * Returns the full 60-bit timestamp, without the version * * For version 2 UUIDs, the time_low field is the local identifier and should not be returned as part of the time. * For this reason, we set the bottom 32 bits of the timestamp to 0's. As a result, there is some loss of timestamp * fidelity, for version 2 UUIDs. The timestamp can be off by a range of 0 to 429.4967295 seconds (or 7 minutes, 9 * seconds, and 496,730 microseconds). * * For version 6 UUIDs, the timestamp order is reversed from the typical RFC 9562 (formerly RFC 4122) order (the * time bits are in the correct bit order, so that it is monotonically increasing). In returning the timestamp * value, we put the bits in the order: time_low + time_mid + time_hi. */ public function getTimestamp(): Hexadecimal { return new Hexadecimal(match ($this->getVersion()) { Uuid::UUID_TYPE_DCE_SECURITY => sprintf( '%03x%04s%08s', hexdec($this->getTimeHiAndVersion()->toString()) & 0x0fff, $this->getTimeMid()->toString(), '' ), Uuid::UUID_TYPE_REORDERED_TIME => sprintf( '%08s%04s%03x', $this->getTimeLow()->toString(), $this->getTimeMid()->toString(), hexdec($this->getTimeHiAndVersion()->toString()) & 0x0fff ), // The Unix timestamp in version 7 UUIDs is a 48-bit number, but for consistency, we will return a 60-bit // number, padded to the left with zeros. Uuid::UUID_TYPE_UNIX_TIME => sprintf( '%011s%04s', $this->getTimeLow()->toString(), $this->getTimeMid()->toString(), ), default => sprintf( '%03x%04s%08s', hexdec($this->getTimeHiAndVersion()->toString()) & 0x0fff, $this->getTimeMid()->toString(), $this->getTimeLow()->toString() ), }); } public function getVersion(): ?int { if ($this->isNil() || $this->isMax()) { return null; } /** @var int[] $parts */ $parts = unpack('n*', $this->bytes); return $parts[4] >> 12; } private function isCorrectVariant(): bool { if ($this->isNil() || $this->isMax()) { return true; } return $this->getVariant() === Uuid::RFC_4122; } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Rfc4122/FieldsInterface.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Rfc4122; use Ramsey\Uuid\Fields\FieldsInterface as BaseFieldsInterface; use Ramsey\Uuid\Type\Hexadecimal; /** * UUID fields, as defined by RFC 4122 * * This interface defines the fields of an RFC 4122 variant UUID. Since RFC 9562 removed the concept of fields and * instead defined layouts that are specific to a given version, this interface is a legacy artifact of the earlier, and * now obsolete, RFC 4122. * * The fields of an RFC 4122 variant UUID are: * * * **time_low**: The low field of the timestamp, an unsigned 32-bit integer * * **time_mid**: The middle field of the timestamp, an unsigned 16-bit integer * * **time_hi_and_version**: The high field of the timestamp multiplexed with the version number, an unsigned 16-bit integer * * **clock_seq_hi_and_reserved**: The high field of the clock sequence multiplexed with the variant, an unsigned 8-bit integer * * **clock_seq_low**: The low field of the clock sequence, an unsigned 8-bit integer * * **node**: The spatially unique node identifier, an unsigned 48-bit integer * * @link https://www.rfc-editor.org/rfc/rfc4122#section-4.1 RFC 4122, 4.1. Format * @link https://www.rfc-editor.org/rfc/rfc9562#section-4 RFC 9562, 4. UUID Format * * @immutable */ interface FieldsInterface extends BaseFieldsInterface { /** * Returns the full 16-bit clock sequence, with the variant bits (two most significant bits) masked out */ public function getClockSeq(): Hexadecimal; /** * Returns the high field of the clock sequence multiplexed with the variant */ public function getClockSeqHiAndReserved(): Hexadecimal; /** * Returns the low field of the clock sequence */ public function getClockSeqLow(): Hexadecimal; /** * Returns the node field */ public function getNode(): Hexadecimal; /** * Returns the high field of the timestamp multiplexed with the version */ public function getTimeHiAndVersion(): Hexadecimal; /** * Returns the low field of the timestamp */ public function getTimeLow(): Hexadecimal; /** * Returns the middle field of the timestamp */ public function getTimeMid(): Hexadecimal; /** * Returns the full 60-bit timestamp, without the version */ public function getTimestamp(): Hexadecimal; /** * Returns the variant * * The variant number describes the layout of the UUID. The variant number has the following meaning: * * - 0 - Reserved for NCS backward compatibility * - 2 - The RFC 9562 (formerly RFC 4122) variant * - 6 - Reserved, Microsoft Corporation backward compatibility * - 7 - Reserved for future definition * * For RFC 9562 (formerly RFC 4122) variant UUIDs, this value should always be the integer `2`. * * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.1 RFC 9562, 4.1. Variant Field */ public function getVariant(): int; /** * Returns the UUID version * * The version number describes how the UUID was generated and has the following meaning: * * 1. Gregorian time UUID * 2. DCE security UUID * 3. Name-based UUID hashed with MD5 * 4. Randomly generated UUID * 5. Name-based UUID hashed with SHA-1 * 6. Reordered Gregorian time UUID * 7. Unix Epoch time UUID * 8. Custom format UUID * * This returns `null` if the UUID is not an RFC 9562 (formerly RFC 4122) variant, since the version is only * meaningful for this variant. * * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.2 RFC 9562, 4.2. Version Field * * @pure */ public function getVersion(): ?int; /** * Returns true if these fields represent a nil UUID * * The nil UUID is a special form of UUID that is specified to have all 128 bits set to zero. * * @pure */ public function isNil(): bool; } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Rfc4122/MaxTrait.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Rfc4122; /** * Provides common functionality for max UUIDs * * @immutable */ trait MaxTrait { /** * Returns the bytes that comprise the fields * * @pure */ abstract public function getBytes(): string; /** * Returns true if the byte string represents a max UUID * * @pure */ public function isMax(): bool { return $this->getBytes() === "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"; } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Rfc4122/MaxUuid.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Rfc4122; use Ramsey\Uuid\Uuid; /** * The max UUID is a special form of UUID that has all 128 bits set to one (`1`) * * @link https://www.rfc-editor.org/rfc/rfc9562#section-5.10 RFC 9562, 5.10. Max UUID * * @immutable */ final class MaxUuid extends Uuid implements UuidInterface { } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Rfc4122/NilTrait.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Rfc4122; /** * Provides common functionality for nil UUIDs * * @immutable */ trait NilTrait { /** * Returns the bytes that comprise the fields * * @pure */ abstract public function getBytes(): string; /** * Returns true if the byte string represents a nil UUID */ public function isNil(): bool { return $this->getBytes() === "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Rfc4122/NilUuid.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Rfc4122; use Ramsey\Uuid\Uuid; /** * The nil UUID is a special form of UUID that has all 128 bits set to zero (`0`) * * @link https://www.rfc-editor.org/rfc/rfc9562#section-5.9 RFC 9562, 5.9. Nil UUID * * @immutable */ final class NilUuid extends Uuid implements UuidInterface { } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Rfc4122/TimeTrait.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Rfc4122; use DateTimeImmutable; use DateTimeInterface; use Ramsey\Uuid\Exception\DateTimeException; use Throwable; use function str_pad; use const STR_PAD_LEFT; /** * Provides common functionality for getting the time from a time-based UUID * * @immutable */ trait TimeTrait { /** * Returns a DateTimeInterface object representing the timestamp associated with the UUID * * @return DateTimeImmutable A PHP DateTimeImmutable instance representing the timestamp of a time-based UUID */ public function getDateTime(): DateTimeInterface { $time = $this->timeConverter->convertTime($this->fields->getTimestamp()); try { return new DateTimeImmutable( '@' . $time->getSeconds()->toString() . '.' . str_pad($time->getMicroseconds()->toString(), 6, '0', STR_PAD_LEFT) ); } catch (Throwable $e) { throw new DateTimeException($e->getMessage(), (int) $e->getCode(), $e); } } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Rfc4122/UuidBuilder.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Rfc4122; use Ramsey\Uuid\Builder\UuidBuilderInterface; use Ramsey\Uuid\Codec\CodecInterface; use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Converter\Time\UnixTimeConverter; use Ramsey\Uuid\Converter\TimeConverterInterface; use Ramsey\Uuid\Exception\UnableToBuildUuidException; use Ramsey\Uuid\Exception\UnsupportedOperationException; use Ramsey\Uuid\Math\BrickMathCalculator; use Ramsey\Uuid\Rfc4122\UuidInterface as Rfc4122UuidInterface; use Ramsey\Uuid\Uuid; use Ramsey\Uuid\UuidInterface; use Throwable; /** * UuidBuilder builds instances of RFC 9562 (formerly 4122) UUIDs * * @immutable */ class UuidBuilder implements UuidBuilderInterface { private TimeConverterInterface $unixTimeConverter; /** * Constructs the DefaultUuidBuilder * * @param NumberConverterInterface $numberConverter The number converter to use when constructing the Uuid * @param TimeConverterInterface $timeConverter The time converter to use for converting Gregorian time extracted * from version 1, 2, and 6 UUIDs to Unix timestamps * @param TimeConverterInterface | null $unixTimeConverter The time converter to use for converter Unix Epoch time * extracted from version 7 UUIDs to Unix timestamps */ public function __construct( private NumberConverterInterface $numberConverter, private TimeConverterInterface $timeConverter, ?TimeConverterInterface $unixTimeConverter = null, ) { $this->unixTimeConverter = $unixTimeConverter ?? new UnixTimeConverter(new BrickMathCalculator()); } /** * Builds and returns a Uuid * * @param CodecInterface $codec The codec to use for building this Uuid instance * @param string $bytes The byte string from which to construct a UUID * * @return Rfc4122UuidInterface UuidBuilder returns instances of Rfc4122UuidInterface * * @pure */ public function build(CodecInterface $codec, string $bytes): UuidInterface { try { /** @var Fields $fields */ $fields = $this->buildFields($bytes); if ($fields->isNil()) { /** @phpstan-ignore possiblyImpure.new */ return new NilUuid($fields, $this->numberConverter, $codec, $this->timeConverter); } if ($fields->isMax()) { /** @phpstan-ignore possiblyImpure.new */ return new MaxUuid($fields, $this->numberConverter, $codec, $this->timeConverter); } return match ($fields->getVersion()) { /** @phpstan-ignore possiblyImpure.new */ Uuid::UUID_TYPE_TIME => new UuidV1($fields, $this->numberConverter, $codec, $this->timeConverter), Uuid::UUID_TYPE_DCE_SECURITY /** @phpstan-ignore possiblyImpure.new */ => new UuidV2($fields, $this->numberConverter, $codec, $this->timeConverter), /** @phpstan-ignore possiblyImpure.new */ Uuid::UUID_TYPE_HASH_MD5 => new UuidV3($fields, $this->numberConverter, $codec, $this->timeConverter), /** @phpstan-ignore possiblyImpure.new */ Uuid::UUID_TYPE_RANDOM => new UuidV4($fields, $this->numberConverter, $codec, $this->timeConverter), /** @phpstan-ignore possiblyImpure.new */ Uuid::UUID_TYPE_HASH_SHA1 => new UuidV5($fields, $this->numberConverter, $codec, $this->timeConverter), Uuid::UUID_TYPE_REORDERED_TIME /** @phpstan-ignore possiblyImpure.new */ => new UuidV6($fields, $this->numberConverter, $codec, $this->timeConverter), Uuid::UUID_TYPE_UNIX_TIME /** @phpstan-ignore possiblyImpure.new */ => new UuidV7($fields, $this->numberConverter, $codec, $this->unixTimeConverter), /** @phpstan-ignore possiblyImpure.new */ Uuid::UUID_TYPE_CUSTOM => new UuidV8($fields, $this->numberConverter, $codec, $this->timeConverter), default => throw new UnsupportedOperationException( 'The UUID version in the given fields is not supported by this UUID builder', ), }; } catch (Throwable $e) { /** @phpstan-ignore possiblyImpure.methodCall, possiblyImpure.methodCall */ throw new UnableToBuildUuidException($e->getMessage(), (int) $e->getCode(), $e); } } /** * Proxy method to allow injecting a mock for testing * * @pure */ protected function buildFields(string $bytes): FieldsInterface { /** @phpstan-ignore possiblyImpure.new */ return new Fields($bytes); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Rfc4122/UuidInterface.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Rfc4122; use Ramsey\Uuid\UuidInterface as BaseUuidInterface; /** * A universally unique identifier (UUID), as defined in RFC 9562 (formerly RFC 4122) * * @link https://www.rfc-editor.org/rfc/rfc9562 RFC 9562 * * @immutable */ interface UuidInterface extends BaseUuidInterface { } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Rfc4122/UuidV1.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Rfc4122; use Ramsey\Uuid\Codec\CodecInterface; use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Converter\TimeConverterInterface; use Ramsey\Uuid\Exception\InvalidArgumentException; use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; use Ramsey\Uuid\Uuid; /** * Gregorian time, or version 1, UUIDs include timestamp, clock sequence, and node values, combined into a 128-bit unsigned integer * * @link https://www.rfc-editor.org/rfc/rfc9562#section-5.1 RFC 9562, 5.1. UUID Version 1 * * @immutable */ final class UuidV1 extends Uuid implements UuidInterface { use TimeTrait; /** * Creates a version 1 (Gregorian time) UUID * * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID * @param NumberConverterInterface $numberConverter The number converter to use for converting hex values to/from integers * @param CodecInterface $codec The codec to use when encoding or decoding UUID strings * @param TimeConverterInterface $timeConverter The time converter to use for converting timestamps extracted from a * UUID to unix timestamps */ public function __construct( Rfc4122FieldsInterface $fields, NumberConverterInterface $numberConverter, CodecInterface $codec, TimeConverterInterface $timeConverter, ) { if ($fields->getVersion() !== Uuid::UUID_TYPE_TIME) { throw new InvalidArgumentException( 'Fields used to create a UuidV1 must represent a version 1 (time-based) UUID', ); } parent::__construct($fields, $numberConverter, $codec, $timeConverter); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Rfc4122/UuidV2.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Rfc4122; use Ramsey\Uuid\Codec\CodecInterface; use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Converter\TimeConverterInterface; use Ramsey\Uuid\Exception\InvalidArgumentException; use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; use Ramsey\Uuid\Type\Integer as IntegerObject; use Ramsey\Uuid\Uuid; use function hexdec; /** * DCE Security version, or version 2, UUIDs include local domain identifier, local ID for the specified domain, and * node values that are combined into a 128-bit unsigned integer * * It is important to note that a version 2 UUID suffers from some loss of timestamp fidelity, due to replacing the * time_low field with the local identifier. When constructing the timestamp value for date purposes, we replace the * local identifier bits with zeros. As a result, the timestamp can be off by a range of 0 to 429.4967295 seconds (or 7 * minutes, 9 seconds, and 496,730 microseconds). * * Astute observers might note this value directly corresponds to `2^32-1`, or `0xffffffff`. The local identifier is * 32-bits, and we have set each of these bits to `0`, so the maximum range of timestamp drift is `0x00000000` to * `0xffffffff` (counted in 100-nanosecond intervals). * * @link https://www.rfc-editor.org/rfc/rfc9562#section-5.2 RFC 9562, 5.2. UUID Version 2 * @link https://publications.opengroup.org/c311 DCE 1.1: Authentication and Security Services * @link https://publications.opengroup.org/c706 DCE 1.1: Remote Procedure Call * @link https://pubs.opengroup.org/onlinepubs/9696989899/chap5.htm#tagcjh_08_02_01_01 DCE 1.1: Auth & Sec, §5.2.1.1 * @link https://pubs.opengroup.org/onlinepubs/9696989899/chap11.htm#tagcjh_14_05_01_01 DCE 1.1: Auth & Sec, §11.5.1.1 * @link https://pubs.opengroup.org/onlinepubs/9629399/apdxa.htm DCE 1.1: RPC, Appendix A * @link https://github.com/google/uuid Go package for UUIDs (includes DCE implementation) * * @immutable */ final class UuidV2 extends Uuid implements UuidInterface { use TimeTrait; /** * Creates a version 2 (DCE Security) UUID * * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID * @param NumberConverterInterface $numberConverter The number converter to use for converting hex values to/from integers * @param CodecInterface $codec The codec to use when encoding or decoding UUID strings * @param TimeConverterInterface $timeConverter The time converter to use for converting timestamps extracted from a * UUID to unix timestamps */ public function __construct( Rfc4122FieldsInterface $fields, NumberConverterInterface $numberConverter, CodecInterface $codec, TimeConverterInterface $timeConverter, ) { if ($fields->getVersion() !== Uuid::UUID_TYPE_DCE_SECURITY) { throw new InvalidArgumentException( 'Fields used to create a UuidV2 must represent a version 2 (DCE Security) UUID' ); } parent::__construct($fields, $numberConverter, $codec, $timeConverter); } /** * Returns the local domain used to create this version 2 UUID */ public function getLocalDomain(): int { /** @var Rfc4122FieldsInterface $fields */ $fields = $this->getFields(); return (int) hexdec($fields->getClockSeqLow()->toString()); } /** * Returns the string name of the local domain */ public function getLocalDomainName(): string { return Uuid::DCE_DOMAIN_NAMES[$this->getLocalDomain()]; } /** * Returns the local identifier for the domain used to create this version 2 UUID */ public function getLocalIdentifier(): IntegerObject { /** @var Rfc4122FieldsInterface $fields */ $fields = $this->getFields(); return new IntegerObject($this->numberConverter->fromHex($fields->getTimeLow()->toString())); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Rfc4122/UuidV3.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Rfc4122; use Ramsey\Uuid\Codec\CodecInterface; use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Converter\TimeConverterInterface; use Ramsey\Uuid\Exception\InvalidArgumentException; use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; use Ramsey\Uuid\Uuid; /** * Version 3 UUIDs are named-based, using a combination of a namespace and name that are hashed into a 128-bit unsigned * integer using the MD5 hashing algorithm * * @link https://www.rfc-editor.org/rfc/rfc9562#section-5.3 RFC 9562, 5.3. UUID Version 3 * * @immutable */ final class UuidV3 extends Uuid implements UuidInterface { /** * Creates a version 3 (name-based, MD5-hashed) UUID * * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID * @param NumberConverterInterface $numberConverter The number converter to use for converting hex values to/from integers * @param CodecInterface $codec The codec to use when encoding or decoding UUID strings * @param TimeConverterInterface $timeConverter The time converter to use for converting timestamps extracted from a * UUID to unix timestamps */ public function __construct( Rfc4122FieldsInterface $fields, NumberConverterInterface $numberConverter, CodecInterface $codec, TimeConverterInterface $timeConverter, ) { if ($fields->getVersion() !== Uuid::UUID_TYPE_HASH_MD5) { throw new InvalidArgumentException( 'Fields used to create a UuidV3 must represent a version 3 (name-based, MD5-hashed) UUID', ); } parent::__construct($fields, $numberConverter, $codec, $timeConverter); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Rfc4122/UuidV4.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Rfc4122; use Ramsey\Uuid\Codec\CodecInterface; use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Converter\TimeConverterInterface; use Ramsey\Uuid\Exception\InvalidArgumentException; use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; use Ramsey\Uuid\Uuid; /** * Random, or version 4, UUIDs are randomly or pseudo-randomly generated 128-bit integers * * @link https://www.rfc-editor.org/rfc/rfc9562#section-5.4 RFC 9562, 5.4. UUID Version 4 * * @immutable */ final class UuidV4 extends Uuid implements UuidInterface { /** * Creates a version 4 (random) UUID * * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID * @param NumberConverterInterface $numberConverter The number converter to use for converting hex values to/from integers * @param CodecInterface $codec The codec to use when encoding or decoding UUID strings * @param TimeConverterInterface $timeConverter The time converter to use for converting timestamps extracted from a * UUID to unix timestamps */ public function __construct( Rfc4122FieldsInterface $fields, NumberConverterInterface $numberConverter, CodecInterface $codec, TimeConverterInterface $timeConverter, ) { if ($fields->getVersion() !== Uuid::UUID_TYPE_RANDOM) { throw new InvalidArgumentException( 'Fields used to create a UuidV4 must represent a version 4 (random) UUID', ); } parent::__construct($fields, $numberConverter, $codec, $timeConverter); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Rfc4122/UuidV5.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Rfc4122; use Ramsey\Uuid\Codec\CodecInterface; use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Converter\TimeConverterInterface; use Ramsey\Uuid\Exception\InvalidArgumentException; use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; use Ramsey\Uuid\Uuid; /** * Version 5 UUIDs are named-based, using a combination of a namespace and name that are hashed into a 128-bit unsigned * integer using the SHA1 hashing algorithm * * @link https://www.rfc-editor.org/rfc/rfc9562#section-5.5 RFC 9562, 5.5. UUID Version 5 * * @immutable */ final class UuidV5 extends Uuid implements UuidInterface { /** * Creates a version 5 (name-based, SHA1-hashed) UUID * * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID * @param NumberConverterInterface $numberConverter The number converter to use for converting hex values to/from integers * @param CodecInterface $codec The codec to use when encoding or decoding UUID strings * @param TimeConverterInterface $timeConverter The time converter to use for converting timestamps extracted from a * UUID to unix timestamps */ public function __construct( Rfc4122FieldsInterface $fields, NumberConverterInterface $numberConverter, CodecInterface $codec, TimeConverterInterface $timeConverter, ) { if ($fields->getVersion() !== Uuid::UUID_TYPE_HASH_SHA1) { throw new InvalidArgumentException( 'Fields used to create a UuidV5 must represent a version 5 (named-based, SHA1-hashed) UUID', ); } parent::__construct($fields, $numberConverter, $codec, $timeConverter); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Rfc4122/UuidV6.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Rfc4122; use Ramsey\Uuid\Nonstandard\UuidV6 as NonstandardUuidV6; /** * Reordered Gregorian time, or version 6, UUIDs include timestamp, clock sequence, and node values that are combined * into a 128-bit unsigned integer * * @link https://www.rfc-editor.org/rfc/rfc9562#section-5.6 RFC 9562, 5.6. UUID Version 6 * * @immutable */ final class UuidV6 extends NonstandardUuidV6 implements UuidInterface { } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Rfc4122/UuidV7.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Rfc4122; use Ramsey\Uuid\Codec\CodecInterface; use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Converter\TimeConverterInterface; use Ramsey\Uuid\Exception\InvalidArgumentException; use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; use Ramsey\Uuid\Uuid; /** * Unix Epoch time, or version 7, UUIDs include a timestamp in milliseconds since the Unix Epoch, along with random bytes * * @link https://www.rfc-editor.org/rfc/rfc9562#section-5.7 RFC 9562, 5.7. UUID Version 7 * * @immutable */ final class UuidV7 extends Uuid implements UuidInterface { use TimeTrait; /** * Creates a version 7 (Unix Epoch time) UUID * * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID * @param NumberConverterInterface $numberConverter The number converter to use for converting hex values to/from integers * @param CodecInterface $codec The codec to use when encoding or decoding UUID strings * @param TimeConverterInterface $timeConverter The time converter to use for converting timestamps extracted from a * UUID to unix timestamps */ public function __construct( Rfc4122FieldsInterface $fields, NumberConverterInterface $numberConverter, CodecInterface $codec, TimeConverterInterface $timeConverter, ) { if ($fields->getVersion() !== Uuid::UUID_TYPE_UNIX_TIME) { throw new InvalidArgumentException( 'Fields used to create a UuidV7 must represent a version 7 (Unix Epoch time) UUID', ); } parent::__construct($fields, $numberConverter, $codec, $timeConverter); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Rfc4122/UuidV8.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Rfc4122; use Ramsey\Uuid\Codec\CodecInterface; use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Converter\TimeConverterInterface; use Ramsey\Uuid\Exception\InvalidArgumentException; use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; use Ramsey\Uuid\Uuid; /** * Custom format, or version 8, UUIDs provide an RFC-compatible format for experimental or vendor-specific uses * * The only requirement for version 8 UUIDs is that the version and variant bits must be set. Otherwise, implementations * are free to set the other bits according to their needs. As a result, the uniqueness of version 8 UUIDs is * implementation-specific and should not be assumed. * * @link https://www.rfc-editor.org/rfc/rfc9562#section-5.8 RFC 9562, 5.8. UUID Version 8 * * @immutable */ final class UuidV8 extends Uuid implements UuidInterface { /** * Creates a version 8 (custom format) UUID * * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID * @param NumberConverterInterface $numberConverter The number converter to use for converting hex values to/from integers * @param CodecInterface $codec The codec to use when encoding or decoding UUID strings * @param TimeConverterInterface $timeConverter The time converter to use for converting timestamps extracted from a * UUID to unix timestamps */ public function __construct( Rfc4122FieldsInterface $fields, NumberConverterInterface $numberConverter, CodecInterface $codec, TimeConverterInterface $timeConverter, ) { if ($fields->getVersion() !== Uuid::UUID_TYPE_CUSTOM) { throw new InvalidArgumentException( 'Fields used to create a UuidV8 must represent a version 8 (custom format) UUID', ); } parent::__construct($fields, $numberConverter, $codec, $timeConverter); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Rfc4122/Validator.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Rfc4122; use Ramsey\Uuid\Uuid; use Ramsey\Uuid\Validator\ValidatorInterface; use function preg_match; use function str_replace; /** * Rfc4122\Validator validates strings as UUIDs of the RFC 9562 (formerly RFC 4122) variant * * @immutable */ final class Validator implements ValidatorInterface { private const VALID_PATTERN = '\A[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-' . '[1-8][0-9A-Fa-f]{3}-[ABab89][0-9A-Fa-f]{3}-[0-9A-Fa-f]{12}\z'; /** * @return non-empty-string */ public function getPattern(): string { return self::VALID_PATTERN; } public function validate(string $uuid): bool { /** @phpstan-ignore possiblyImpure.functionCall */ $uuid = strtolower(str_replace(['urn:', 'uuid:', 'URN:', 'UUID:', '{', '}'], '', $uuid)); /** @phpstan-ignore possiblyImpure.functionCall */ return $uuid === Uuid::NIL || $uuid === Uuid::MAX || preg_match('/' . self::VALID_PATTERN . '/Dms', $uuid); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Rfc4122/VariantTrait.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Rfc4122; use Ramsey\Uuid\Exception\InvalidBytesException; use Ramsey\Uuid\Uuid; use function decbin; use function str_pad; use function str_starts_with; use function strlen; use function substr; use function unpack; use const STR_PAD_LEFT; /** * Provides common functionality for handling the variant, as defined by RFC 9562 (formerly RFC 4122) * * @immutable */ trait VariantTrait { /** * Returns the bytes that comprise the fields */ abstract public function getBytes(): string; /** * Returns the variant * * The variant number describes the layout of the UUID. The variant number has the following meaning: * * - 0 - Reserved for NCS backward compatibility * - 2 - The RFC 9562 (formerly RFC 4122) variant * - 6 - Reserved, Microsoft Corporation backward compatibility * - 7 - Reserved for future definition * * For RFC 9562 (formerly RFC 4122) variant UUIDs, this value should always be the integer `2`. * * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.1 RFC 9562, 4.1. Variant Field */ public function getVariant(): int { if (strlen($this->getBytes()) !== 16) { throw new InvalidBytesException('Invalid number of bytes'); } // According to RFC 9562, sections {@link https://www.rfc-editor.org/rfc/rfc9562#section-4.1 4.1} and // {@link https://www.rfc-editor.org/rfc/rfc9562#section-5.10 5.10}, the Max UUID falls within the range // of the future variant. if ($this->isMax()) { return Uuid::RESERVED_FUTURE; } // According to RFC 9562, sections {@link https://www.rfc-editor.org/rfc/rfc9562#section-4.1 4.1} and // {@link https://www.rfc-editor.org/rfc/rfc9562#section-5.9 5.9}, the Nil UUID falls within the range // of the Apollo NCS variant. if ($this->isNil()) { return Uuid::RESERVED_NCS; } /** @var int[] $parts */ $parts = unpack('n*', $this->getBytes()); // $parts[5] is a 16-bit, unsigned integer containing the variant bits of the UUID. We convert this integer into // a string containing a binary representation, padded to 16 characters. We analyze the first three characters // (three most-significant bits) to determine the variant. $msb = substr(str_pad(decbin($parts[5]), 16, '0', STR_PAD_LEFT), 0, 3); if ($msb === '111') { return Uuid::RESERVED_FUTURE; } elseif ($msb === '110') { return Uuid::RESERVED_MICROSOFT; } elseif (str_starts_with($msb, '10')) { return Uuid::RFC_4122; } return Uuid::RESERVED_NCS; } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Rfc4122/VersionTrait.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Rfc4122; use Ramsey\Uuid\Uuid; /** * Provides common functionality for handling the version, as defined by RFC 9562 (formerly RFC 4122) * * @immutable */ trait VersionTrait { /** * Returns the UUID version * * The version number describes how the UUID was generated and has the following meaning: * * 1. Gregorian time UUID * 2. DCE security UUID * 3. Name-based UUID hashed with MD5 * 4. Randomly generated UUID * 5. Name-based UUID hashed with SHA-1 * 6. Reordered Gregorian time UUID * 7. Unix Epoch time UUID * 8. Custom format UUID * * This returns `null` if the UUID is not an RFC 9562 (formerly RFC 4122) variant, since the version is only * meaningful for this variant. * * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.2 RFC 9562, 4.2. Version Field * * @pure */ abstract public function getVersion(): ?int; /** * Returns true if these fields represent a max UUID */ abstract public function isMax(): bool; /** * Returns true if these fields represent a nil UUID */ abstract public function isNil(): bool; /** * Returns true if the version matches one of those defined by RFC 9562 (formerly RFC 4122) * * @return bool True if the UUID version is valid, false otherwise */ private function isCorrectVersion(): bool { if ($this->isNil() || $this->isMax()) { return true; } return match ($this->getVersion()) { Uuid::UUID_TYPE_TIME, Uuid::UUID_TYPE_DCE_SECURITY, Uuid::UUID_TYPE_HASH_MD5, Uuid::UUID_TYPE_RANDOM, Uuid::UUID_TYPE_HASH_SHA1, Uuid::UUID_TYPE_REORDERED_TIME, Uuid::UUID_TYPE_UNIX_TIME, Uuid::UUID_TYPE_CUSTOM => true, default => false, }; } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Type/Decimal.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Type; use Ramsey\Uuid\Exception\InvalidArgumentException; use ValueError; use function is_numeric; use function sprintf; use function str_starts_with; /** * A value object representing a decimal * * This class exists for type-safety purposes, to ensure that decimals returned from ramsey/uuid methods as strings are * truly decimals and not some other kind of string. * * To support values as true decimals and not as floats or doubles, we store the decimals as strings. * * @immutable */ final class Decimal implements NumberInterface { private string $value; private bool $isNegative; public function __construct(float | int | string | self $value) { $value = (string) $value; if (!is_numeric($value)) { throw new InvalidArgumentException( 'Value must be a signed decimal or a string containing only ' . 'digits 0-9 and, optionally, a decimal point or sign (+ or -)' ); } // Remove the leading +-symbol. if (str_starts_with($value, '+')) { $value = substr($value, 1); } // For cases like `-0` or `-0.0000`, convert the value to `0`. if (abs((float) $value) === 0.0) { $value = '0'; } if (str_starts_with($value, '-')) { $this->isNegative = true; } else { $this->isNegative = false; } $this->value = $value; } public function isNegative(): bool { return $this->isNegative; } public function toString(): string { return $this->value; } public function __toString(): string { return $this->toString(); } public function jsonSerialize(): string { return $this->toString(); } public function serialize(): string { return $this->toString(); } /** * @return array{string: string} */ public function __serialize(): array { return ['string' => $this->toString()]; } /** * Constructs the object from a serialized string representation * * @param string $data The serialized string representation of the object */ public function unserialize(string $data): void { $this->__construct($data); } /** * @param array{string?: string} $data */ public function __unserialize(array $data): void { // @codeCoverageIgnoreStart if (!isset($data['string'])) { throw new ValueError(sprintf('%s(): Argument #1 ($data) is invalid', __METHOD__)); } // @codeCoverageIgnoreEnd $this->unserialize($data['string']); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Type/Hexadecimal.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Type; use Ramsey\Uuid\Exception\InvalidArgumentException; use ValueError; use function preg_match; use function sprintf; use function substr; /** * A value object representing a hexadecimal number * * This class exists for type-safety purposes, to ensure that hexadecimal numbers returned from ramsey/uuid methods as * strings are truly hexadecimal and not some other kind of string. * * @immutable */ final class Hexadecimal implements TypeInterface { /** * @var non-empty-string */ private string $value; /** * @param self | string $value The hexadecimal value to store */ public function __construct(self | string $value) { $this->value = $value instanceof self ? (string) $value : $this->prepareValue($value); } /** * @return non-empty-string * * @pure */ public function toString(): string { return $this->value; } /** * @return non-empty-string */ public function __toString(): string { return $this->toString(); } /** * @return non-empty-string */ public function jsonSerialize(): string { return $this->toString(); } /** * @return non-empty-string */ public function serialize(): string { return $this->toString(); } /** * @return array{string: string} */ public function __serialize(): array { return ['string' => $this->toString()]; } /** * Constructs the object from a serialized string representation * * @param string $data The serialized string representation of the object */ public function unserialize(string $data): void { $this->__construct($data); } /** * @param array{string?: string} $data */ public function __unserialize(array $data): void { // @codeCoverageIgnoreStart if (!isset($data['string'])) { throw new ValueError(sprintf('%s(): Argument #1 ($data) is invalid', __METHOD__)); } // @codeCoverageIgnoreEnd $this->unserialize($data['string']); } /** * @return non-empty-string */ private function prepareValue(string $value): string { $value = strtolower($value); if (str_starts_with($value, '0x')) { $value = substr($value, 2); } if (!preg_match('/^[A-Fa-f0-9]+$/', $value)) { throw new InvalidArgumentException('Value must be a hexadecimal number'); } /** @var non-empty-string */ return $value; } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Type/Integer.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Type; use Ramsey\Uuid\Exception\InvalidArgumentException; use ValueError; use function assert; use function is_numeric; use function preg_match; use function sprintf; use function substr; /** * A value object representing an integer * * This class exists for type-safety purposes, to ensure that integers returned from ramsey/uuid methods as strings are * truly integers and not some other kind of string. * * To support large integers beyond PHP_INT_MAX and PHP_INT_MIN on both 64-bit and 32-bit systems, we store the integers * as strings. * * @immutable */ final class Integer implements NumberInterface { /** * @var numeric-string */ private string $value; /** * @phpstan-ignore property.readOnlyByPhpDocDefaultValue */ private bool $isNegative = false; public function __construct(self | float | int | string $value) { $this->value = $value instanceof self ? (string) $value : $this->prepareValue($value); } public function isNegative(): bool { return $this->isNegative; } /** * @return numeric-string * * @pure */ public function toString(): string { return $this->value; } /** * @return numeric-string */ public function __toString(): string { return $this->toString(); } public function jsonSerialize(): string { return $this->toString(); } public function serialize(): string { return $this->toString(); } /** * @return array{string: string} */ public function __serialize(): array { return ['string' => $this->toString()]; } /** * Constructs the object from a serialized string representation * * @param string $data The serialized string representation of the object */ public function unserialize(string $data): void { $this->__construct($data); } /** * @param array{string?: string} $data */ public function __unserialize(array $data): void { // @codeCoverageIgnoreStart if (!isset($data['string'])) { throw new ValueError(sprintf('%s(): Argument #1 ($data) is invalid', __METHOD__)); } // @codeCoverageIgnoreEnd $this->unserialize($data['string']); } /** * @return numeric-string */ private function prepareValue(float | int | string $value): string { $value = (string) $value; $sign = '+'; // If the value contains a sign, remove it for the digit pattern check. if (str_starts_with($value, '-') || str_starts_with($value, '+')) { $sign = substr($value, 0, 1); $value = substr($value, 1); } if (!preg_match('/^\d+$/', $value)) { throw new InvalidArgumentException( 'Value must be a signed integer or a string containing only ' . 'digits 0-9 and, optionally, a sign (+ or -)' ); } // Trim any leading zeros. $value = ltrim($value, '0'); // Set to zero if the string is empty after trimming zeros. if ($value === '') { $value = '0'; } // Add the negative sign back to the value. if ($sign === '-' && $value !== '0') { $value = $sign . $value; /** @phpstan-ignore property.readOnlyByPhpDocAssignNotInConstructor */ $this->isNegative = true; } assert(is_numeric($value)); return $value; } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Type/NumberInterface.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Type; /** * NumberInterface ensures consistency in numeric values returned by ramsey/uuid * * @immutable */ interface NumberInterface extends TypeInterface { /** * Returns true if this number is less than zero */ public function isNegative(): bool; } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Type/Time.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Type; use Ramsey\Uuid\Exception\UnsupportedOperationException; use Ramsey\Uuid\Type\Integer as IntegerObject; use ValueError; use function json_decode; use function json_encode; use function sprintf; /** * A value object representing a timestamp * * This class exists for type-safety purposes, to ensure that timestamps used by ramsey/uuid are truly timestamp * integers and not some other kind of string or integer. * * @immutable */ final class Time implements TypeInterface { private IntegerObject $seconds; private IntegerObject $microseconds; public function __construct( IntegerObject | float | int | string $seconds, IntegerObject | float | int | string $microseconds = 0, ) { $this->seconds = new IntegerObject($seconds); $this->microseconds = new IntegerObject($microseconds); } /** * @pure */ public function getSeconds(): IntegerObject { return $this->seconds; } /** * @pure */ public function getMicroseconds(): IntegerObject { return $this->microseconds; } public function toString(): string { return $this->seconds->toString() . '.' . sprintf('%06s', $this->microseconds->toString()); } public function __toString(): string { return $this->toString(); } /** * @return string[] */ public function jsonSerialize(): array { return [ 'seconds' => $this->getSeconds()->toString(), 'microseconds' => $this->getMicroseconds()->toString(), ]; } public function serialize(): string { return (string) json_encode($this); } /** * @return array{seconds: string, microseconds: string} */ public function __serialize(): array { return [ 'seconds' => $this->getSeconds()->toString(), 'microseconds' => $this->getMicroseconds()->toString(), ]; } /** * Constructs the object from a serialized string representation * * @param string $data The serialized string representation of the object */ public function unserialize(string $data): void { /** @var array{seconds?: float | int | string, microseconds?: float | int | string} $time */ $time = json_decode($data, true); if (!isset($time['seconds']) || !isset($time['microseconds'])) { throw new UnsupportedOperationException('Attempted to unserialize an invalid value'); } $this->__construct($time['seconds'], $time['microseconds']); } /** * @param array{seconds?: string, microseconds?: string} $data */ public function __unserialize(array $data): void { // @codeCoverageIgnoreStart if (!isset($data['seconds']) || !isset($data['microseconds'])) { throw new ValueError(sprintf('%s(): Argument #1 ($data) is invalid', __METHOD__)); } // @codeCoverageIgnoreEnd $this->__construct($data['seconds'], $data['microseconds']); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Type/TypeInterface.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Type; use JsonSerializable; use Serializable; /** * TypeInterface ensures consistency in typed values returned by ramsey/uuid * * @immutable */ interface TypeInterface extends JsonSerializable, Serializable { /** * @pure */ public function toString(): string; /** * @pure */ public function __toString(): string; } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Uuid.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid; use BadMethodCallException; use DateTimeInterface; use Ramsey\Uuid\Codec\CodecInterface; use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Converter\TimeConverterInterface; use Ramsey\Uuid\Exception\InvalidArgumentException; use Ramsey\Uuid\Exception\UnsupportedOperationException; use Ramsey\Uuid\Fields\FieldsInterface; use Ramsey\Uuid\Lazy\LazyUuidFromString; use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; use Ramsey\Uuid\Type\Hexadecimal; use Ramsey\Uuid\Type\Integer as IntegerObject; use ValueError; use function assert; use function bin2hex; use function method_exists; use function preg_match; use function sprintf; use function str_replace; use function strcmp; use function strlen; use function strtolower; use function substr; /** * Uuid provides constants and static methods for working with and generating UUIDs * * @immutable */ class Uuid implements UuidInterface { use DeprecatedUuidMethodsTrait; /** * When this namespace is specified, the name string is a fully qualified domain name * * @link https://www.rfc-editor.org/rfc/rfc9562#section-6.6 RFC 9562, 6.6. Namespace ID Usage and Allocation */ public const NAMESPACE_DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; /** * When this namespace is specified, the name string is a URL * * @link https://www.rfc-editor.org/rfc/rfc9562#section-6.6 RFC 9562, 6.6. Namespace ID Usage and Allocation */ public const NAMESPACE_URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'; /** * When this namespace is specified, the name string is an ISO OID * * @link https://www.rfc-editor.org/rfc/rfc9562#section-6.6 RFC 9562, 6.6. Namespace ID Usage and Allocation */ public const NAMESPACE_OID = '6ba7b812-9dad-11d1-80b4-00c04fd430c8'; /** * When this namespace is specified, the name string is an X.500 DN (in DER or a text output format) * * @link https://www.rfc-editor.org/rfc/rfc9562#section-6.6 RFC 9562, 6.6. Namespace ID Usage and Allocation */ public const NAMESPACE_X500 = '6ba7b814-9dad-11d1-80b4-00c04fd430c8'; /** * The Nil UUID is a special form of UUID that is specified to have all 128 bits set to zero * * @link https://www.rfc-editor.org/rfc/rfc9562#section-5.9 RFC 9562, 5.9. Nil UUID */ public const NIL = '00000000-0000-0000-0000-000000000000'; /** * The Max UUID is a special form of UUID that is specified to have all 128 bits set to one * * @link https://www.rfc-editor.org/rfc/rfc9562#section-5.10 RFC 9562, 5.10. Max UUID */ public const MAX = 'ffffffff-ffff-ffff-ffff-ffffffffffff'; /** * Variant: reserved, NCS backward compatibility * * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.1 RFC 9562, 4.1. Variant Field */ public const RESERVED_NCS = 0; /** * Variant: the UUID layout specified in RFC 9562 (formerly RFC 4122) * * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.1 RFC 9562, 4.1. Variant Field * @see Uuid::RFC_9562 */ public const RFC_4122 = 2; /** * Variant: the UUID layout specified in RFC 9562 (formerly RFC 4122) * * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.1 RFC 9562, 4.1. Variant Field */ public const RFC_9562 = 2; /** * Variant: reserved, Microsoft Corporation backward compatibility * * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.1 RFC 9562, 4.1. Variant Field */ public const RESERVED_MICROSOFT = 6; /** * Variant: reserved for future definition * * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.1 RFC 9562, 4.1. Variant Field */ public const RESERVED_FUTURE = 7; /** * @deprecated Use {@see ValidatorInterface::getPattern()} instead. */ public const VALID_PATTERN = '^[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}$'; /** * Version 1 (Gregorian time) UUID * * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.2 RFC 9562, 4.2. Version Field */ public const UUID_TYPE_TIME = 1; /** * Version 2 (DCE Security) UUID * * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.2 RFC 9562, 4.2. Version Field */ public const UUID_TYPE_DCE_SECURITY = 2; /** * @deprecated Use {@see Uuid::UUID_TYPE_DCE_SECURITY} instead. */ public const UUID_TYPE_IDENTIFIER = 2; /** * Version 3 (name-based and hashed with MD5) UUID * * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.2 RFC 9562, 4.2. Version Field */ public const UUID_TYPE_HASH_MD5 = 3; /** * Version 4 (random) UUID * * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.2 RFC 9562, 4.2. Version Field */ public const UUID_TYPE_RANDOM = 4; /** * Version 5 (name-based and hashed with SHA1) UUID * * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.2 RFC 9562, 4.2. Version Field */ public const UUID_TYPE_HASH_SHA1 = 5; /** * @deprecated Use {@see Uuid::UUID_TYPE_REORDERED_TIME} instead. */ public const UUID_TYPE_PEABODY = 6; /** * Version 6 (reordered Gregorian time) UUID * * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.2 RFC 9562, 4.2. Version Field */ public const UUID_TYPE_REORDERED_TIME = 6; /** * Version 7 (Unix Epoch time) UUID * * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.2 RFC 9562, 4.2. Version Field */ public const UUID_TYPE_UNIX_TIME = 7; /** * Version 8 (custom format) UUID * * @link https://www.rfc-editor.org/rfc/rfc9562#section-4.2 RFC 9562, 4.2. Version Field */ public const UUID_TYPE_CUSTOM = 8; /** * DCE Security principal domain * * @link https://pubs.opengroup.org/onlinepubs/9696989899/chap11.htm#tagcjh_14_05_01_01 DCE 1.1, §11.5.1.1 */ public const DCE_DOMAIN_PERSON = 0; /** * DCE Security group domain * * @link https://pubs.opengroup.org/onlinepubs/9696989899/chap11.htm#tagcjh_14_05_01_01 DCE 1.1, §11.5.1.1 */ public const DCE_DOMAIN_GROUP = 1; /** * DCE Security organization domain * * @link https://pubs.opengroup.org/onlinepubs/9696989899/chap11.htm#tagcjh_14_05_01_01 DCE 1.1, §11.5.1.1 */ public const DCE_DOMAIN_ORG = 2; /** * DCE Security domain string names * * @link https://pubs.opengroup.org/onlinepubs/9696989899/chap11.htm#tagcjh_14_05_01_01 DCE 1.1, §11.5.1.1 */ public const DCE_DOMAIN_NAMES = [ self::DCE_DOMAIN_PERSON => 'person', self::DCE_DOMAIN_GROUP => 'group', self::DCE_DOMAIN_ORG => 'org', ]; /** * @phpstan-ignore property.readOnlyByPhpDocDefaultValue */ private static ?UuidFactoryInterface $factory = null; /** * @var bool flag to detect if the UUID factory was replaced internally, which disables all optimizations for the * default/happy path internal scenarios * @phpstan-ignore property.readOnlyByPhpDocDefaultValue */ private static bool $factoryReplaced = false; protected CodecInterface $codec; protected NumberConverterInterface $numberConverter; protected Rfc4122FieldsInterface $fields; protected TimeConverterInterface $timeConverter; /** * Creates a universally unique identifier (UUID) from an array of fields * * Unless you're making advanced use of this library to generate identifiers that deviate from RFC 9562 (formerly * RFC 4122), you probably do not want to instantiate a UUID directly. Use the static methods, instead: * * ``` * use Ramsey\Uuid\Uuid; * * $timeBasedUuid = Uuid::uuid1(); * $namespaceMd5Uuid = Uuid::uuid3(Uuid::NAMESPACE_URL, 'http://php.net/'); * $randomUuid = Uuid::uuid4(); * $namespaceSha1Uuid = Uuid::uuid5(Uuid::NAMESPACE_URL, 'http://php.net/'); * ``` * * @param Rfc4122FieldsInterface $fields The fields from which to construct a UUID * @param NumberConverterInterface $numberConverter The number converter to use for converting hex values to/from integers * @param CodecInterface $codec The codec to use when encoding or decoding UUID strings * @param TimeConverterInterface $timeConverter The time converter to use for converting timestamps extracted from a * UUID to unix timestamps */ public function __construct( Rfc4122FieldsInterface $fields, NumberConverterInterface $numberConverter, CodecInterface $codec, TimeConverterInterface $timeConverter, ) { $this->fields = $fields; $this->codec = $codec; $this->numberConverter = $numberConverter; $this->timeConverter = $timeConverter; } /** * @return non-empty-string */ public function __toString(): string { return $this->toString(); } /** * Converts the UUID to a string for JSON serialization */ public function jsonSerialize(): string { return $this->toString(); } /** * Converts the UUID to a string for PHP serialization */ public function serialize(): string { return $this->codec->encode($this); } /** * @return array{bytes: string} */ public function __serialize(): array { return ['bytes' => $this->serialize()]; } /** * Re-constructs the object from its serialized form * * @param string $data The serialized PHP string to unserialize into a UuidInterface instance */ public function unserialize(string $data): void { if (strlen($data) === 16) { /** @var Uuid $uuid */ $uuid = self::getFactory()->fromBytes($data); } else { /** @var Uuid $uuid */ $uuid = self::getFactory()->fromString($data); } /** @phpstan-ignore property.readOnlyByPhpDocAssignNotInConstructor */ $this->codec = $uuid->codec; /** @phpstan-ignore property.readOnlyByPhpDocAssignNotInConstructor */ $this->numberConverter = $uuid->numberConverter; /** @phpstan-ignore property.readOnlyByPhpDocAssignNotInConstructor */ $this->fields = $uuid->fields; /** @phpstan-ignore property.readOnlyByPhpDocAssignNotInConstructor */ $this->timeConverter = $uuid->timeConverter; } /** * @param array{bytes?: string} $data */ public function __unserialize(array $data): void { // @codeCoverageIgnoreStart if (!isset($data['bytes'])) { throw new ValueError(sprintf('%s(): Argument #1 ($data) is invalid', __METHOD__)); } // @codeCoverageIgnoreEnd $this->unserialize($data['bytes']); } public function compareTo(UuidInterface $other): int { $compare = strcmp($this->toString(), $other->toString()); if ($compare < 0) { return -1; } if ($compare > 0) { return 1; } return 0; } public function equals(?object $other): bool { if (!$other instanceof UuidInterface) { return false; } return $this->compareTo($other) === 0; } /** * @return non-empty-string */ public function getBytes(): string { return $this->codec->encodeBinary($this); } public function getFields(): FieldsInterface { return $this->fields; } public function getHex(): Hexadecimal { return new Hexadecimal(str_replace('-', '', $this->toString())); } public function getInteger(): IntegerObject { return new IntegerObject($this->numberConverter->fromHex($this->getHex()->toString())); } public function getUrn(): string { return 'urn:uuid:' . $this->toString(); } /** * @return non-empty-string */ public function toString(): string { return $this->codec->encode($this); } /** * Returns the factory used to create UUIDs */ public static function getFactory(): UuidFactoryInterface { if (self::$factory === null) { self::$factory = new UuidFactory(); } return self::$factory; } /** * Sets the factory used to create UUIDs * * @param UuidFactoryInterface $factory A factory that will be used by this class to create UUIDs */ public static function setFactory(UuidFactoryInterface $factory): void { // Note: non-strict equality is intentional here. If the factory is configured differently, every assumption // around purity is broken, and we have to internally decide everything differently. // phpcs:ignore SlevomatCodingStandard.Operators.DisallowEqualOperators.DisallowedNotEqualOperator self::$factoryReplaced = ($factory != new UuidFactory()); self::$factory = $factory; } /** * Creates a UUID from a byte string * * @param string $bytes A binary string * * @return UuidInterface A UuidInterface instance created from a binary string representation * * @throws InvalidArgumentException * * @pure */ public static function fromBytes(string $bytes): UuidInterface { /** @phpstan-ignore impure.staticPropertyAccess */ if (!self::$factoryReplaced && strlen($bytes) === 16) { $base16Uuid = bin2hex($bytes); // Note: we are calling `fromString` internally because we don't know if the given `$bytes` is a valid UUID return self::fromString( substr($base16Uuid, 0, 8) . '-' . substr($base16Uuid, 8, 4) . '-' . substr($base16Uuid, 12, 4) . '-' . substr($base16Uuid, 16, 4) . '-' . substr($base16Uuid, 20, 12), ); } /** @phpstan-ignore possiblyImpure.methodCall */ return self::getFactory()->fromBytes($bytes); } /** * Creates a UUID from the string standard representation * * @param string $uuid A hexadecimal string * * @return UuidInterface A UuidInterface instance created from a hexadecimal string representation * * @throws InvalidArgumentException * * @pure */ public static function fromString(string $uuid): UuidInterface { $uuid = strtolower($uuid); /** @phpstan-ignore impure.staticPropertyAccess, possiblyImpure.functionCall */ if (!self::$factoryReplaced && preg_match(LazyUuidFromString::VALID_REGEX, $uuid) === 1) { /** @phpstan-ignore possiblyImpure.functionCall */ assert($uuid !== ''); /** @phpstan-ignore possiblyImpure.new */ return new LazyUuidFromString($uuid); } /** @phpstan-ignore possiblyImpure.methodCall */ return self::getFactory()->fromString($uuid); } /** * Creates a UUID from a DateTimeInterface instance * * @param DateTimeInterface $dateTime The date and time * @param Hexadecimal | null $node A 48-bit number representing the hardware address * @param int | null $clockSeq A 14-bit number used to help avoid duplicates that could arise when the clock is set * backwards in time or if the node ID changes * * @return UuidInterface A UuidInterface instance that represents a version 1 UUID created from a DateTimeInterface instance */ public static function fromDateTime( DateTimeInterface $dateTime, ?Hexadecimal $node = null, ?int $clockSeq = null ): UuidInterface { return self::getFactory()->fromDateTime($dateTime, $node, $clockSeq); } /** * Creates a UUID from the Hexadecimal object * * @param Hexadecimal $hex Hexadecimal object representing a hexadecimal number * * @return UuidInterface A UuidInterface instance created from the Hexadecimal object representing a hexadecimal number * * @throws InvalidArgumentException * * @pure */ public static function fromHexadecimal(Hexadecimal $hex): UuidInterface { /** @phpstan-ignore possiblyImpure.methodCall */ $factory = self::getFactory(); if (method_exists($factory, 'fromHexadecimal')) { /** @phpstan-ignore possiblyImpure.methodCall */ $uuid = $factory->fromHexadecimal($hex); /** @phpstan-ignore possiblyImpure.functionCall */ assert($uuid instanceof UuidInterface); return $uuid; } throw new BadMethodCallException('The method fromHexadecimal() does not exist on the provided factory'); } /** * Creates a UUID from a 128-bit integer string * * @param string $integer String representation of 128-bit integer * * @return UuidInterface A UuidInterface instance created from the string representation of a 128-bit integer * * @throws InvalidArgumentException * * @pure */ public static function fromInteger(string $integer): UuidInterface { /** @phpstan-ignore possiblyImpure.methodCall */ return self::getFactory()->fromInteger($integer); } /** * Returns true if the provided string is a valid UUID * * @param string $uuid A string to validate as a UUID * * @return bool True if the string is a valid UUID, false otherwise * * @phpstan-assert-if-true =non-empty-string $uuid * * @pure */ public static function isValid(string $uuid): bool { /** @phpstan-ignore possiblyImpure.methodCall, possiblyImpure.methodCall */ return self::getFactory()->getValidator()->validate($uuid); } /** * Returns a version 1 (Gregorian time) UUID from a host ID, sequence number, and the current time * * @param Hexadecimal | int | string | null $node A 48-bit number representing the hardware address; this number may * be represented as an integer or a hexadecimal string * @param int | null $clockSeq A 14-bit number used to help avoid duplicates that could arise when the clock is set * backwards in time or if the node ID changes * * @return UuidInterface A UuidInterface instance that represents a version 1 UUID */ public static function uuid1($node = null, ?int $clockSeq = null): UuidInterface { return self::getFactory()->uuid1($node, $clockSeq); } /** * Returns a version 2 (DCE Security) UUID from a local domain, local identifier, host ID, clock sequence, and the current time * * @param int $localDomain The local domain to use when generating bytes, according to DCE Security * @param IntegerObject | null $localIdentifier The local identifier for the given domain; this may be a UID or GID * on POSIX systems, if the local domain is "person" or "group," or it may be a site-defined identifier if the * local domain is "org" * @param Hexadecimal | null $node A 48-bit number representing the hardware address * @param int | null $clockSeq A 14-bit number used to help avoid duplicates that could arise when the clock is set * backwards in time or if the node ID changes (in a version 2 UUID, the lower 8 bits of this number are * replaced with the domain). * * @return UuidInterface A UuidInterface instance that represents a version 2 UUID */ public static function uuid2( int $localDomain, ?IntegerObject $localIdentifier = null, ?Hexadecimal $node = null, ?int $clockSeq = null ): UuidInterface { return self::getFactory()->uuid2($localDomain, $localIdentifier, $node, $clockSeq); } /** * Returns a version 3 (name-based) UUID based on the MD5 hash of a namespace ID and a name * * @param UuidInterface | string $ns The namespace (must be a valid UUID) * @param string $name The name to use for creating a UUID * * @return UuidInterface A UuidInterface instance that represents a version 3 UUID * * @pure */ public static function uuid3($ns, string $name): UuidInterface { /** @phpstan-ignore possiblyImpure.methodCall */ return self::getFactory()->uuid3($ns, $name); } /** * Returns a version 4 (random) UUID * * @return UuidInterface A UuidInterface instance that represents a version 4 UUID */ public static function uuid4(): UuidInterface { return self::getFactory()->uuid4(); } /** * Returns a version 5 (name-based) UUID based on the SHA-1 hash of a namespace ID and a name * * @param UuidInterface | string $ns The namespace (must be a valid UUID) * @param string $name The name to use for creating a UUID * * @return UuidInterface A UuidInterface instance that represents a version 5 UUID * * @pure */ public static function uuid5($ns, string $name): UuidInterface { /** @phpstan-ignore possiblyImpure.methodCall */ return self::getFactory()->uuid5($ns, $name); } /** * Returns a version 6 (reordered Gregorian time) UUID from a host ID, sequence number, and the current time * * @param Hexadecimal | null $node A 48-bit number representing the hardware address * @param int | null $clockSeq A 14-bit number used to help avoid duplicates that could arise when the clock is set * backwards in time or if the node ID changes * * @return UuidInterface A UuidInterface instance that represents a version 6 UUID */ public static function uuid6( ?Hexadecimal $node = null, ?int $clockSeq = null ): UuidInterface { return self::getFactory()->uuid6($node, $clockSeq); } /** * Returns a version 7 (Unix Epoch time) UUID * * @param DateTimeInterface | null $dateTime An optional date/time from which to create the version 7 UUID. If not * provided, the UUID is generated using the current date/time. * * @return UuidInterface A UuidInterface instance that represents a version 7 UUID */ public static function uuid7(?DateTimeInterface $dateTime = null): UuidInterface { $factory = self::getFactory(); if (method_exists($factory, 'uuid7')) { /** @var UuidInterface */ return $factory->uuid7($dateTime); } throw new UnsupportedOperationException('The provided factory does not support the uuid7() method'); } /** * Returns a version 8 (custom format) UUID * * The bytes provided may contain any value according to your application's needs. Be aware, however, that other * applications may not understand the semantics of the value. * * @param string $bytes A 16-byte octet string. This is an open blob of data that you may fill with 128 bits of * information. Be aware, however, bits 48 through 51 will be replaced with the UUID version field, and bits 64 * and 65 will be replaced with the UUID variant. You MUST NOT rely on these bits for your application needs. * * @return UuidInterface A UuidInterface instance that represents a version 8 UUID * * @pure */ public static function uuid8(string $bytes): UuidInterface { /** @phpstan-ignore possiblyImpure.methodCall */ $factory = self::getFactory(); if (method_exists($factory, 'uuid8')) { /** * @var UuidInterface * @phpstan-ignore possiblyImpure.methodCall */ return $factory->uuid8($bytes); } throw new UnsupportedOperationException('The provided factory does not support the uuid8() method'); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/UuidFactory.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid; use DateTimeInterface; use Ramsey\Uuid\Builder\UuidBuilderInterface; use Ramsey\Uuid\Codec\CodecInterface; use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Converter\TimeConverterInterface; use Ramsey\Uuid\Generator\DceSecurityGeneratorInterface; use Ramsey\Uuid\Generator\DefaultTimeGenerator; use Ramsey\Uuid\Generator\NameGeneratorInterface; use Ramsey\Uuid\Generator\RandomGeneratorInterface; use Ramsey\Uuid\Generator\TimeGeneratorInterface; use Ramsey\Uuid\Generator\UnixTimeGenerator; use Ramsey\Uuid\Lazy\LazyUuidFromString; use Ramsey\Uuid\Provider\NodeProviderInterface; use Ramsey\Uuid\Provider\Time\FixedTimeProvider; use Ramsey\Uuid\Type\Hexadecimal; use Ramsey\Uuid\Type\Integer as IntegerObject; use Ramsey\Uuid\Type\Time; use Ramsey\Uuid\Validator\ValidatorInterface; use function bin2hex; use function hex2bin; use function pack; use function str_pad; use function strtolower; use function substr; use function substr_replace; use function unpack; use const STR_PAD_LEFT; class UuidFactory implements UuidFactoryInterface { private CodecInterface $codec; private DceSecurityGeneratorInterface $dceSecurityGenerator; private NameGeneratorInterface $nameGenerator; private NodeProviderInterface $nodeProvider; private NumberConverterInterface $numberConverter; private RandomGeneratorInterface $randomGenerator; private TimeConverterInterface $timeConverter; private TimeGeneratorInterface $timeGenerator; private TimeGeneratorInterface $unixTimeGenerator; private UuidBuilderInterface $uuidBuilder; private ValidatorInterface $validator; /** * @var bool whether the feature set was provided from outside, or we can operate under "default" assumptions */ private bool $isDefaultFeatureSet; /** * @param FeatureSet | null $features A set of available features in the current environment */ public function __construct(?FeatureSet $features = null) { $this->isDefaultFeatureSet = $features === null; $features = $features ?: new FeatureSet(); $this->codec = $features->getCodec(); $this->dceSecurityGenerator = $features->getDceSecurityGenerator(); $this->nameGenerator = $features->getNameGenerator(); $this->nodeProvider = $features->getNodeProvider(); $this->numberConverter = $features->getNumberConverter(); $this->randomGenerator = $features->getRandomGenerator(); $this->timeConverter = $features->getTimeConverter(); $this->timeGenerator = $features->getTimeGenerator(); $this->uuidBuilder = $features->getBuilder(); $this->validator = $features->getValidator(); $this->unixTimeGenerator = $features->getUnixTimeGenerator(); } /** * Returns the codec used by this factory */ public function getCodec(): CodecInterface { return $this->codec; } /** * Sets the codec to use for this factory * * @param CodecInterface $codec A UUID encoder-decoder */ public function setCodec(CodecInterface $codec): void { $this->isDefaultFeatureSet = false; $this->codec = $codec; } /** * Returns the name generator used by this factory */ public function getNameGenerator(): NameGeneratorInterface { return $this->nameGenerator; } /** * Sets the name generator to use for this factory * * @param NameGeneratorInterface $nameGenerator A generator to generate binary data, based on a namespace and name */ public function setNameGenerator(NameGeneratorInterface $nameGenerator): void { $this->isDefaultFeatureSet = false; $this->nameGenerator = $nameGenerator; } /** * Returns the node provider used by this factory */ public function getNodeProvider(): NodeProviderInterface { return $this->nodeProvider; } /** * Returns the random generator used by this factory */ public function getRandomGenerator(): RandomGeneratorInterface { return $this->randomGenerator; } /** * Returns the time generator used by this factory */ public function getTimeGenerator(): TimeGeneratorInterface { return $this->timeGenerator; } /** * Sets the time generator to use for this factory * * @param TimeGeneratorInterface $generator A generator to generate binary data, based on the time */ public function setTimeGenerator(TimeGeneratorInterface $generator): void { $this->isDefaultFeatureSet = false; $this->timeGenerator = $generator; } /** * Returns the DCE Security generator used by this factory */ public function getDceSecurityGenerator(): DceSecurityGeneratorInterface { return $this->dceSecurityGenerator; } /** * Sets the DCE Security generator to use for this factory * * @param DceSecurityGeneratorInterface $generator A generator to generate binary data, based on a local domain and * local identifier */ public function setDceSecurityGenerator(DceSecurityGeneratorInterface $generator): void { $this->isDefaultFeatureSet = false; $this->dceSecurityGenerator = $generator; } /** * Returns the number converter used by this factory */ public function getNumberConverter(): NumberConverterInterface { return $this->numberConverter; } /** * Sets the random generator to use for this factory * * @param RandomGeneratorInterface $generator A generator to generate binary data, based on some random input */ public function setRandomGenerator(RandomGeneratorInterface $generator): void { $this->isDefaultFeatureSet = false; $this->randomGenerator = $generator; } /** * Sets the number converter to use for this factory * * @param NumberConverterInterface $converter A converter to use for working with large integers (i.e., integers * greater than PHP_INT_MAX) */ public function setNumberConverter(NumberConverterInterface $converter): void { $this->isDefaultFeatureSet = false; $this->numberConverter = $converter; } /** * Returns the UUID builder used by this factory */ public function getUuidBuilder(): UuidBuilderInterface { return $this->uuidBuilder; } /** * Sets the UUID builder to use for this factory * * @param UuidBuilderInterface $builder A builder for constructing instances of UuidInterface */ public function setUuidBuilder(UuidBuilderInterface $builder): void { $this->isDefaultFeatureSet = false; $this->uuidBuilder = $builder; } public function getValidator(): ValidatorInterface { return $this->validator; } /** * Sets the validator to use for this factory * * @param ValidatorInterface $validator A validator to use for validating whether a string is a valid UUID */ public function setValidator(ValidatorInterface $validator): void { $this->isDefaultFeatureSet = false; $this->validator = $validator; } /** * @pure */ public function fromBytes(string $bytes): UuidInterface { return $this->codec->decodeBytes($bytes); } /** * @pure */ public function fromString(string $uuid): UuidInterface { $uuid = strtolower($uuid); return $this->codec->decode($uuid); } /** * @pure */ public function fromInteger(string $integer): UuidInterface { $hex = $this->numberConverter->toHex($integer); $hex = str_pad($hex, 32, '0', STR_PAD_LEFT); return $this->fromString($hex); } public function fromDateTime( DateTimeInterface $dateTime, ?Hexadecimal $node = null, ?int $clockSeq = null, ): UuidInterface { $timeProvider = new FixedTimeProvider(new Time($dateTime->format('U'), $dateTime->format('u'))); $timeGenerator = new DefaultTimeGenerator($this->nodeProvider, $this->timeConverter, $timeProvider); $bytes = $timeGenerator->generate($node?->toString(), $clockSeq); return $this->uuidFromBytesAndVersion($bytes, Uuid::UUID_TYPE_TIME); } /** * @pure */ public function fromHexadecimal(Hexadecimal $hex): UuidInterface { return $this->codec->decode($hex->__toString()); } /** * @inheritDoc */ public function uuid1($node = null, ?int $clockSeq = null): UuidInterface { $bytes = $this->timeGenerator->generate($node, $clockSeq); return $this->uuidFromBytesAndVersion($bytes, Uuid::UUID_TYPE_TIME); } public function uuid2( int $localDomain, ?IntegerObject $localIdentifier = null, ?Hexadecimal $node = null, ?int $clockSeq = null, ): UuidInterface { $bytes = $this->dceSecurityGenerator->generate($localDomain, $localIdentifier, $node, $clockSeq); return $this->uuidFromBytesAndVersion($bytes, Uuid::UUID_TYPE_DCE_SECURITY); } /** * @inheritDoc * @pure */ public function uuid3($ns, string $name): UuidInterface { return $this->uuidFromNsAndName($ns, $name, Uuid::UUID_TYPE_HASH_MD5, 'md5'); } public function uuid4(): UuidInterface { $bytes = $this->randomGenerator->generate(16); return $this->uuidFromBytesAndVersion($bytes, Uuid::UUID_TYPE_RANDOM); } /** * @inheritDoc * @pure */ public function uuid5($ns, string $name): UuidInterface { return $this->uuidFromNsAndName($ns, $name, Uuid::UUID_TYPE_HASH_SHA1, 'sha1'); } public function uuid6(?Hexadecimal $node = null, ?int $clockSeq = null): UuidInterface { $bytes = $this->timeGenerator->generate($node?->toString(), $clockSeq); // Rearrange the bytes, according to the UUID version 6 specification. $v6 = $bytes[6] . $bytes[7] . $bytes[4] . $bytes[5] . $bytes[0] . $bytes[1] . $bytes[2] . $bytes[3]; $v6 = bin2hex($v6); // Drop the first four bits, while adding an empty four bits for the version field. This allows us to // reconstruct the correct time from the bytes of this UUID. $v6Bytes = hex2bin(substr($v6, 1, 12) . '0' . substr($v6, -3)); $v6Bytes .= substr($bytes, 8); return $this->uuidFromBytesAndVersion($v6Bytes, Uuid::UUID_TYPE_REORDERED_TIME); } /** * Returns a version 7 (Unix Epoch time) UUID * * @param DateTimeInterface | null $dateTime An optional date/time from which to create the version 7 UUID. If not * provided, the UUID is generated using the current date/time. * * @return UuidInterface A UuidInterface instance that represents a version 7 UUID */ public function uuid7(?DateTimeInterface $dateTime = null): UuidInterface { assert($this->unixTimeGenerator instanceof UnixTimeGenerator); $bytes = $this->unixTimeGenerator->generate(null, null, $dateTime); return $this->uuidFromBytesAndVersion($bytes, Uuid::UUID_TYPE_UNIX_TIME); } /** * Returns a version 8 (custom format) UUID * * The bytes provided may contain any value according to your application's needs. Be aware, however, that other * applications may not understand the semantics of the value. * * @param string $bytes A 16-byte octet string. This is an open blob of data that you may fill with 128 bits of * information. Be aware, however, bits 48 through 51 will be replaced with the UUID version field, and bits 64 * and 65 will be replaced with the UUID variant. You MUST NOT rely on these bits for your application needs. * * @return UuidInterface A UuidInterface instance that represents a version 8 UUID * * @pure */ public function uuid8(string $bytes): UuidInterface { /** @phpstan-ignore possiblyImpure.methodCall */ return $this->uuidFromBytesAndVersion($bytes, Uuid::UUID_TYPE_CUSTOM); } /** * Returns a Uuid created from the provided byte string * * Uses the configured builder and codec and the provided byte string to construct a Uuid object. * * @param string $bytes The byte string from which to construct a UUID * * @return UuidInterface An instance of UuidInterface, created from the provided bytes * * @pure */ public function uuid(string $bytes): UuidInterface { return $this->uuidBuilder->build($this->codec, $bytes); } /** * Returns a version 3 or 5 namespaced Uuid * * @param UuidInterface | string $ns The namespace (must be a valid UUID) * @param string $name The name to hash together with the namespace * @param int $version The version of UUID to create (3 or 5) * @param string $hashAlgorithm The hashing algorithm to use when hashing together the namespace and name * * @return UuidInterface An instance of UuidInterface, created by hashing together the provided namespace and name * * @pure */ private function uuidFromNsAndName( UuidInterface | string $ns, string $name, int $version, string $hashAlgorithm, ): UuidInterface { if (!($ns instanceof UuidInterface)) { $ns = $this->fromString($ns); } $bytes = $this->nameGenerator->generate($ns, $name, $hashAlgorithm); /** @phpstan-ignore possiblyImpure.methodCall */ return $this->uuidFromBytesAndVersion(substr($bytes, 0, 16), $version); } /** * Returns a Uuid created from the provided bytes and version * * @param string $bytes The byte string to convert to a UUID * @param int $version The version to apply to the UUID * * @return UuidInterface An instance of UuidInterface, created from the byte string and version */ private function uuidFromBytesAndVersion(string $bytes, int $version): UuidInterface { /** @var int[] $unpackedTime */ $unpackedTime = unpack('n*', substr($bytes, 6, 2)); $timeHi = $unpackedTime[1]; $timeHiAndVersion = pack('n*', BinaryUtils::applyVersion($timeHi, $version)); /** @var int[] $unpackedClockSeq */ $unpackedClockSeq = unpack('n*', substr($bytes, 8, 2)); $clockSeqHi = $unpackedClockSeq[1]; $clockSeqHiAndReserved = pack('n*', BinaryUtils::applyVariant($clockSeqHi)); $bytes = substr_replace($bytes, $timeHiAndVersion, 6, 2); $bytes = substr_replace($bytes, $clockSeqHiAndReserved, 8, 2); if ($this->isDefaultFeatureSet) { return LazyUuidFromString::fromBytes($bytes); } return $this->uuid($bytes); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/UuidFactoryInterface.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid; use DateTimeInterface; use Ramsey\Uuid\Type\Hexadecimal; use Ramsey\Uuid\Type\Integer as IntegerObject; use Ramsey\Uuid\Validator\ValidatorInterface; /** * UuidFactoryInterface defines the common functionality all `UuidFactory` instances must implement */ interface UuidFactoryInterface { /** * Creates a UUID from a byte string * * @param string $bytes A binary string * * @return UuidInterface A UuidInterface instance created from a binary string representation * * @pure */ public function fromBytes(string $bytes): UuidInterface; /** * Creates a UUID from a DateTimeInterface instance * * @param DateTimeInterface $dateTime The date and time * @param Hexadecimal | null $node A 48-bit number representing the hardware address * @param int | null $clockSeq A 14-bit number used to help avoid duplicates that could arise when the clock is set * backwards in time or if the node ID changes * * @return UuidInterface A UuidInterface instance that represents a version 1 UUID created from a DateTimeInterface instance */ public function fromDateTime( DateTimeInterface $dateTime, ?Hexadecimal $node = null, ?int $clockSeq = null, ): UuidInterface; /** * Creates a UUID from a 128-bit integer string * * @param string $integer String representation of 128-bit integer * * @return UuidInterface A UuidInterface instance created from the string representation of a 128-bit integer * * @pure */ public function fromInteger(string $integer): UuidInterface; /** * Creates a UUID from the string standard representation * * @param string $uuid A hexadecimal string * * @return UuidInterface A UuidInterface instance created from a hexadecimal string representation * * @pure */ public function fromString(string $uuid): UuidInterface; /** * Returns the validator used by the factory */ public function getValidator(): ValidatorInterface; /** * Returns a version 1 (Gregorian time) UUID from a host ID, sequence number, and the current time * * @param Hexadecimal | int | string | null $node A 48-bit number representing the hardware address; this number may * be represented as an integer or a hexadecimal string * @param int | null $clockSeq A 14-bit number used to help avoid duplicates that could arise when the clock is set * backwards in time or if the node ID changes * * @return UuidInterface A UuidInterface instance that represents a version 1 UUID */ public function uuid1($node = null, ?int $clockSeq = null): UuidInterface; /** * Returns a version 2 (DCE Security) UUID from a local domain, local identifier, host ID, clock sequence, and the * current time * * @param int $localDomain The local domain to use when generating bytes, according to DCE Security * @param IntegerObject | null $localIdentifier The local identifier for the given domain; this may be a UID or GID * on POSIX systems, if the local domain is a person or group, or it may be a site-defined identifier if the * local domain is org * @param Hexadecimal | null $node A 48-bit number representing the hardware address * @param int | null $clockSeq A 14-bit number used to help avoid duplicates that could arise when the clock is set * backwards in time or if the node ID changes * * @return UuidInterface A UuidInterface instance that represents a version 2 UUID */ public function uuid2( int $localDomain, ?IntegerObject $localIdentifier = null, ?Hexadecimal $node = null, ?int $clockSeq = null, ): UuidInterface; /** * Returns a version 3 (name-based) UUID based on the MD5 hash of a namespace ID and a name * * @param UuidInterface | string $ns The namespace (must be a valid UUID) * @param string $name The name to use for creating a UUID * * @return UuidInterface A UuidInterface instance that represents a version 3 UUID * * @pure */ public function uuid3($ns, string $name): UuidInterface; /** * Returns a version 4 (random) UUID * * @return UuidInterface A UuidInterface instance that represents a version 4 UUID */ public function uuid4(): UuidInterface; /** * Returns a version 5 (name-based) UUID based on the SHA-1 hash of a namespace ID and a name * * @param UuidInterface | string $ns The namespace (must be a valid UUID) * @param string $name The name to use for creating a UUID * * @return UuidInterface A UuidInterface instance that represents a version 5 UUID * * @pure */ public function uuid5($ns, string $name): UuidInterface; /** * Returns a version 6 (reordered Gregorian time) UUID from a host ID, sequence number, and the current time * * @param Hexadecimal | null $node A 48-bit number representing the hardware address * @param int | null $clockSeq A 14-bit number used to help avoid duplicates that could arise when the clock is set * backwards in time or if the node ID changes * * @return UuidInterface A UuidInterface instance that represents a version 6 UUID */ public function uuid6(?Hexadecimal $node = null, ?int $clockSeq = null): UuidInterface; } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/UuidInterface.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid; use JsonSerializable; use Ramsey\Uuid\Fields\FieldsInterface; use Ramsey\Uuid\Type\Hexadecimal; use Ramsey\Uuid\Type\Integer as IntegerObject; use Serializable; use Stringable; /** * A UUID is a universally unique identifier adhering to an agreed-upon representation format and standard for generation * * @immutable */ interface UuidInterface extends DeprecatedUuidInterface, JsonSerializable, Serializable, Stringable { /** * Returns -1, 0, or 1 if the UUID is less than, equal to, or greater than the other UUID * * The first of two UUIDs is greater than the second if the most significant field in which the UUIDs differ is * greater for the first UUID. * * @param UuidInterface $other The UUID to compare * * @return int<-1,1> -1, 0, or 1 if the UUID is less than, equal to, or greater than $other */ public function compareTo(UuidInterface $other): int; /** * Returns true if the UUID is equal to the provided object * * The result is true if and only if the argument is not null, is a UUID object, has the same variant, and contains * the same value, bit-for-bit, as the UUID. * * @param object | null $other An object to test for equality with this UUID * * @return bool True if the other object is equal to this UUID */ public function equals(?object $other): bool; /** * Returns the binary string representation of the UUID * * @return non-empty-string * * @pure */ public function getBytes(): string; /** * Returns the fields that comprise this UUID */ public function getFields(): FieldsInterface; /** * Returns the hexadecimal representation of the UUID */ public function getHex(): Hexadecimal; /** * Returns the integer representation of the UUID */ public function getInteger(): IntegerObject; /** * Returns the string standard representation of the UUID as a URN * * @link http://en.wikipedia.org/wiki/Uniform_Resource_Name Uniform Resource Name * @link https://www.rfc-editor.org/rfc/rfc9562.html#section-4 RFC 9562, 4. UUID Format * @link https://www.rfc-editor.org/rfc/rfc9562.html#section-7 RFC 9562, 7. IANA Considerations * @link https://www.rfc-editor.org/rfc/rfc4122.html#section-3 RFC 4122, 3. Namespace Registration Template */ public function getUrn(): string; /** * Returns the string standard representation of the UUID * * @return non-empty-string * * @pure */ public function toString(): string; /** * Casts the UUID to the string standard representation * * @return non-empty-string * * @pure */ public function __toString(): string; } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Validator/GenericValidator.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Validator; use Ramsey\Uuid\Uuid; use function preg_match; use function str_replace; /** * GenericValidator validates strings as UUIDs of any variant * * @immutable */ final class GenericValidator implements ValidatorInterface { /** * Regular expression pattern for matching a UUID of any variant. */ private const VALID_PATTERN = '\A[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}\z'; /** * @return non-empty-string */ public function getPattern(): string { return self::VALID_PATTERN; } public function validate(string $uuid): bool { /** @phpstan-ignore possiblyImpure.functionCall */ $uuid = str_replace(['urn:', 'uuid:', 'URN:', 'UUID:', '{', '}'], '', $uuid); /** @phpstan-ignore possiblyImpure.functionCall */ return $uuid === Uuid::NIL || preg_match('/' . self::VALID_PATTERN . '/Dms', $uuid); } } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/Validator/ValidatorInterface.php ================================================ * @license http://opensource.org/licenses/MIT MIT */ declare(strict_types=1); namespace Ramsey\Uuid\Validator; /** * A validator validates a string as a proper UUID * * @immutable */ interface ValidatorInterface { /** * Returns the regular expression pattern used by this validator * * @return non-empty-string The regular expression pattern this validator uses */ public function getPattern(): string; /** * Returns true if the provided string represents a UUID * * @param string $uuid The string to validate as a UUID * * @return bool True if the string is a valid UUID, false otherwise * * @pure */ public function validate(string $uuid): bool; } ================================================ FILE: lib/Google/vendor/ramsey/uuid/src/functions.php ================================================ * @license http://opensource.org/licenses/MIT MIT * phpcs:disable Squiz.Functions.GlobalFunction */ declare(strict_types=1); namespace Ramsey\Uuid; use DateTimeInterface; use Ramsey\Uuid\Type\Hexadecimal; use Ramsey\Uuid\Type\Integer as IntegerObject; /** * Returns a version 1 (Gregorian time) UUID from a host ID, sequence number, and the current time * * @param Hexadecimal | int | string | null $node A 48-bit number representing the hardware address; this number may be * represented as an integer or a hexadecimal string * @param int | null $clockSeq A 14-bit number used to help avoid duplicates that could arise when the clock is set * backwards in time or if the node ID changes * * @return non-empty-string Version 1 UUID as a string */ function v1($node = null, ?int $clockSeq = null): string { return Uuid::uuid1($node, $clockSeq)->toString(); } /** * Returns a version 2 (DCE Security) UUID from a local domain, local identifier, host ID, clock sequence, and the current time * * @param int $localDomain The local domain to use when generating bytes, according to DCE Security * @param IntegerObject | null $localIdentifier The local identifier for the given domain; this may be a UID or GID on * POSIX systems, if the local domain is a person or group, or it may be a site-defined identifier if the local * domain is org * @param Hexadecimal | null $node A 48-bit number representing the hardware address * @param int | null $clockSeq A 14-bit number used to help avoid duplicates that could arise when the clock is set * backwards in time or if the node ID changes * * @return non-empty-string Version 2 UUID as a string */ function v2( int $localDomain, ?IntegerObject $localIdentifier = null, ?Hexadecimal $node = null, ?int $clockSeq = null, ): string { return Uuid::uuid2($localDomain, $localIdentifier, $node, $clockSeq)->toString(); } /** * Returns a version 3 (name-based) UUID based on the MD5 hash of a namespace ID and a name * * @param UuidInterface | string $ns The namespace (must be a valid UUID) * * @return non-empty-string Version 3 UUID as a string * * @pure */ function v3($ns, string $name): string { return Uuid::uuid3($ns, $name)->toString(); } /** * Returns a version 4 (random) UUID * * @return non-empty-string Version 4 UUID as a string */ function v4(): string { return Uuid::uuid4()->toString(); } /** * Returns a version 5 (name-based) UUID based on the SHA-1 hash of a namespace ID and a name * * @param UuidInterface | string $ns The namespace (must be a valid UUID) * * @return non-empty-string Version 5 UUID as a string * * @pure */ function v5($ns, string $name): string { return Uuid::uuid5($ns, $name)->toString(); } /** * Returns a version 6 (reordered Gregorian time) UUID from a host ID, sequence number, and the current time * * @param Hexadecimal | null $node A 48-bit number representing the hardware address * @param int | null $clockSeq A 14-bit number used to help avoid duplicates that could arise when the clock is set * backwards in time or if the node ID changes * * @return non-empty-string Version 6 UUID as a string */ function v6(?Hexadecimal $node = null, ?int $clockSeq = null): string { return Uuid::uuid6($node, $clockSeq)->toString(); } /** * Returns a version 7 (Unix Epoch time) UUID * * @param DateTimeInterface|null $dateTime An optional date/time from which to create the version 7 UUID. If not * provided, the UUID is generated using the current date/time. * * @return non-empty-string Version 7 UUID as a string */ function v7(?DateTimeInterface $dateTime = null): string { return Uuid::uuid7($dateTime)->toString(); } /** * Returns a version 8 (custom format) UUID * * The bytes provided may contain any value according to your application's needs. Be aware, however, that other * applications may not understand the semantics of the value. * * @param string $bytes A 16-byte octet string. This is an open blob of data that you may fill with 128 bits of * information. Be aware, however, bits 48 through 51 will be replaced with the UUID version field, and bits 64 and * 65 will be replaced with the UUID variant. You MUST NOT rely on these bits for your application needs. * * @return non-empty-string Version 8 UUID as a string * * @pure */ function v8(string $bytes): string { return Uuid::uuid8($bytes)->toString(); } ================================================ FILE: lib/Google/vendor/rize/uri-template/.php-cs-fixer.dist.php ================================================ setParallelConfig(ParallelConfigFactory::detect()) ->setRiskyAllowed(true) ->setUsingCache(false) ->setRules([ '@PER-CS2.0' => true, ]) ->setFinder( (new Finder()) ->in([__DIR__ . '/src', __DIR__ . '/tests']) ); ================================================ FILE: lib/Google/vendor/rize/uri-template/LICENSE ================================================ The MIT License (MIT) Copyright (c) [2014] [Marut Khumtong] 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. ================================================ FILE: lib/Google/vendor/rize/uri-template/README.md ================================================ # PHP URI Template This is a URI Template implementation in PHP based on [RFC 6570 URI Template](http://tools.ietf.org/html/rfc6570). In addition to URI expansion, it also supports URI extraction (used by [Google Cloud Core](https://github.com/googleapis/google-cloud-php-core) and [Google Cloud Client Library](https://github.com/googleapis/google-cloud-php)). ![CI](https://github.com/rize/UriTemplate/workflows/CI/badge.svg) [![Total Downloads](https://poser.pugx.org/rize/uri-template/downloads)](https://packagist.org/packages/rize/uri-template) [![Latest Stable Version](https://poser.pugx.org/rize/uri-template/v)](https://packagist.org/packages/rize/uri-template) [![PHP Version Require](https://poser.pugx.org/rize/uri-template/require/php)](https://packagist.org/packages/rize/uri-template) > [!NOTE] > > Due to the deprecation of implictly nullable parameter types in [PHP 8.4](https://wiki.php.net/rfc/deprecate-implicitly-nullable-types), we must introduce breaking change by adding explicit nullable types (`?T`) which requires PHP 7.1+. > > As a result, version [0.4.0](https://github.com/rize/UriTemplate/releases/tag/0.4.0) and later will no longer support PHP versions below 8.1. ## Usage ### Expansion A very simple usage (string expansion). ```php expand('/{username}/profile', ['username' => 'john']); >> '/john/profile' ``` `Rize\UriTemplate` supports all `Expression Types` and `Levels` specified by RFC6570. ```php expand('/search/{term:1}/{term}/{?q*,limit}', [ 'term' => 'john', 'q' => ['a', 'b'], 'limit' => 10, ]) >> '/search/j/john/?q=a&q=b&limit=10' ``` #### `/` Path segment expansion ```php expand('http://{host}{/segments*}/{file}{.extensions*}', [ 'host' => 'www.host.com', 'segments' => ['path', 'to', 'a'], 'file' => 'file', 'extensions' => ['x', 'y'], ]); >> 'http://www.host.com/path/to/a/file.x.y' ``` `Rize\UriTemplate` accepts `base-uri` as a 1st argument and `default params` as a 2nd argument. This is very useful when you're working with API endpoint. Take a look at real world example. ```php 1.1]); $uri->expand('/statuses/show/{id}.json', ['id' => '210462857140252672']); >> https://api.twitter.com/1.1/statuses/show/210462857140252672.json ``` ### Extraction It also supports URI Extraction (extract all variables from URI). Let's take a look at the example. ```php 1.1]); $params = $uri->extract('/search/{term:1}/{term}/{?q*,limit}', '/search/j/john/?q=a&q=b&limit=10'); >> print_r($params); ( [term:1] => j [term] => john [q] => Array ( [0] => a [1] => b ) [limit] => 10 ) ``` Note that in the example above, result returned by `extract` method has an extra keys named `term:1` for `prefix` modifier. This key was added just for our convenience to access prefix data. #### `strict` mode ```php extract($template, $uri, $strict = false) ``` Normally `extract` method will try to extract vars from a uri even if it's partially matched. For example ```php extract('/{?a,b}', '/?a=1') >> print_r($params); ( [a] => 1 [b] => null ) ``` With `strict mode`, it will allow you to extract uri only when variables in template are fully matched with given uri. Which is useful when you want to determine whether the given uri is matched against your template or not (in case you want to use it as routing service). ```php extract('/{?a,b}', '/?a=1', true); >>> null // Now we give `b` some value $params = $uri->extract('/{?a,b}', '/?a=1&b=2', true); >>> print_r($params) ( [a] => 1 [b] => 2 ) ``` #### Array modifier `%` By default, RFC 6570 only has 2 types of operators `:` and `*`. This `%` array operator was added to the library because current spec can't handle array style query e.g. `list[]=a` or `key[user]=john`. Example usage for `%` modifier ```php expand('{?list%,keys%}', [ 'list' => [ 'a', 'b', ), 'keys' => [ 'a' => 1, 'b' => 2, ), ]); // '?list[]=a&list[]=b&keys[a]=1&keys[b]=2' >> '?list%5B%5D=a&list%5B%5D=b&keys%5Ba%5D=1&keys%5Bb%5D=2' // [] get encoded to %5B%5D i.e. '?list[]=a&list[]=b&keys[a]=1&keys[b]=2' $params = $uri->extract('{?list%,keys%}', '?list%5B%5D=a&list%5B%5D=b&keys%5Ba%5D=1&keys%5Bb%5D=2', ) >> print_r($params); ( [list] => Array ( [0] => a [1] => b ) [keys] => Array ( [a] => 1 [b] => 2 ) ) ``` ## Installation Using `composer` ``` { "require": { "rize/uri-template": "~0.3" } } ``` ### Changelogs * **0.2.0** Add a new modifier `%` which allows user to use `list[]=a&list[]=b` query pattern. * **0.2.1** Add nested array support for `%` modifier * **0.2.5** Add strict mode support for `extract` method * **0.3.0** Improve code quality + RFC3986 support for `extract` method by @Maks3w * **0.3.1** Improve `extract` method to parse two or more adjacent variables separated by dot by @corleonis * **0.4.0** Fixes the deprecation of implicitly nullable parameter types introduced in PHP 8.4. This version requires PHP 8.1 or later. ## Contributors ### Code Contributors This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)]. ### Financial Contributors Become a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/rize-uri-template/contribute)] #### Individuals #### Organizations Support this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/rize-uri-template/contribute)] ================================================ FILE: lib/Google/vendor/rize/uri-template/composer.json ================================================ { "name": "rize/uri-template", "type": "library", "description": "PHP URI Template (RFC 6570) supports both expansion & extraction", "keywords": ["URI", "Template", "RFC 6570"], "license": "MIT", "authors": [ { "name": "Marut K", "homepage": "http://twitter.com/rezigned" } ], "require": { "php": ">=8.1" }, "require-dev": { "phpunit/phpunit": "~10.0", "phpstan/phpstan": "^1.12", "friendsofphp/php-cs-fixer": "^3.63" }, "autoload": { "psr-4": { "Rize\\": "src/Rize" } }, "scripts": { "test": "vendor/bin/phpunit", "cs": "vendor/bin/php-cs-fixer fix --dry-run", "cs-fix": "vendor/bin/php-cs-fixer fix", "phpstan": "vendor/bin/phpstan" } } ================================================ FILE: lib/Google/vendor/rize/uri-template/phpstan.neon ================================================ parameters: level: 5 paths: - src - tests ================================================ FILE: lib/Google/vendor/rize/uri-template/phpunit.xml ================================================ tests src ================================================ FILE: lib/Google/vendor/rize/uri-template/src/Rize/UriTemplate/Node/Abstraction.php ================================================ $params */ public function expand(Parser $parser, array $params = []): ?string { return $this->token; } /** * Matches given URI against current node. * * @param array $params * * @return null|array{0: string, 1: array} `uri and params` or `null` if not match and $strict is true */ public function match(Parser $parser, string $uri, array $params = [], bool $strict = false): ?array { // match literal string from start to end if (str_starts_with($uri, $this->token)) { $uri = substr($uri, strlen($this->token)); } // when there's no match, just return null if strict mode is given elseif ($strict) { return null; } return [$uri, $params]; } public function getToken(): string { return $this->token; } } ================================================ FILE: lib/Google/vendor/rize/uri-template/src/Rize/UriTemplate/Node/Expression.php ================================================ operator; } public function getVariables(): ?array { return $this->variables; } public function getForwardLookupSeparator(): string { return $this->forwardLookupSeparator; } public function setForwardLookupSeparator(string $forwardLookupSeparator): void { $this->forwardLookupSeparator = $forwardLookupSeparator; } public function expand(Parser $parser, array $params = []): ?string { $data = []; $op = $this->operator; if ($this->variables === null) { return $op->first; } // check for variable modifiers foreach ($this->variables as $var) { $val = $op->expand($parser, $var, $params); // skip null value if (!is_null($val)) { $data[] = $val; } } return $data ? $op->first . implode($op->sep, $data) : null; } /** * Matches given URI against current node. * * @return null|array `uri and params` or `null` if not match and $strict is true */ public function match(Parser $parser, string $uri, array $params = [], bool $strict = false): ?array { $op = $this->operator; // check expression operator first if ($op->id && isset($uri[0]) && $uri[0] !== $op->id) { return [$uri, $params]; } // remove operator from input if ($op->id) { $uri = substr($uri, 1); } foreach ($this->sortVariables($this->variables) as $var) { $regex = '#' . $op->toRegex($parser, $var) . '#'; $val = null; // do a forward lookup and get just the relevant part $remainingUri = ''; $preparedUri = $uri; if ($this->forwardLookupSeparator) { $lastOccurrenceOfSeparator = stripos($uri, $this->forwardLookupSeparator); $preparedUri = substr($uri, 0, $lastOccurrenceOfSeparator); $remainingUri = substr($uri, $lastOccurrenceOfSeparator); } if (preg_match($regex, $preparedUri, $match)) { // remove matched part from input $preparedUri = preg_replace($regex, '', $preparedUri, 1); $val = $op->extract($parser, $var, $match[0]); } // if strict is given, we quit immediately when there's no match elseif ($strict) { return null; } $uri = $preparedUri . $remainingUri; $params[$var->getToken()] = $val; } return [$uri, $params]; } /** * Sort variables before extracting data from uri. * We have to sort vars by non-explode to explode. */ protected function sortVariables(array $vars): array { usort($vars, static fn($a, $b) => $a->options['modifier'] <=> $b->options['modifier']); return $vars; } } ================================================ FILE: lib/Google/vendor/rize/uri-template/src/Rize/UriTemplate/Node/Literal.php ================================================ null, 'value' => null]; public function __construct(string $token, array $options = []) { parent::__construct($token); $this->options = $options + $this->options; // normalize var name e.g. from 'term:1' becomes 'term' $name = $token; if ($options['modifier'] === ':') { $name = strstr($name, $options['modifier'], true); } $this->name = $name; } } ================================================ FILE: lib/Google/vendor/rize/uri-template/src/Rize/UriTemplate/Operator/Abstraction.php ================================================ ':', '%2F' => '/', '%3F' => '?', '%23' => '#', '%5B' => '[', '%5D' => ']', '%40' => '@', '%21' => '!', '%24' => '$', '%26' => '&', '%27' => "'", '%28' => '(', '%29' => ')', '%2A' => '*', '%2B' => '+', '%2C' => ',', '%3B' => ';', '%3D' => '=', ]; protected static $types = [ '' => [ 'sep' => ',', 'named' => false, 'empty' => '', 'reserved' => false, 'start' => 0, 'first' => null, ], '+' => [ 'sep' => ',', 'named' => false, 'empty' => '', 'reserved' => true, 'start' => 1, 'first' => null, ], '.' => [ 'sep' => '.', 'named' => false, 'empty' => '', 'reserved' => false, 'start' => 1, 'first' => '.', ], '/' => [ 'sep' => '/', 'named' => false, 'empty' => '', 'reserved' => false, 'start' => 1, 'first' => '/', ], ';' => [ 'sep' => ';', 'named' => true, 'empty' => '', 'reserved' => false, 'start' => 1, 'first' => ';', ], '?' => [ 'sep' => '&', 'named' => true, 'empty' => '=', 'reserved' => false, 'start' => 1, 'first' => '?', ], '&' => [ 'sep' => '&', 'named' => true, 'empty' => '=', 'reserved' => false, 'start' => 1, 'first' => '&', ], '#' => [ 'sep' => ',', 'named' => false, 'empty' => '', 'reserved' => true, 'start' => 1, 'first' => '#', ], ]; protected static $loaded = []; /** * RFC 3986 Allowed path characters regex except the path delimiter '/'. * * @var string */ protected static $pathRegex = '(?:[a-zA-Z0-9\-\._~!\$&\'\(\)\*\+,;=%:@]+|%(?![A-Fa-f0-9]{2}))'; /** * RFC 3986 Allowed query characters regex except the query parameter delimiter '&'. * * @var string */ protected static $queryRegex = '(?:[a-zA-Z0-9\-\._~!\$\'\(\)\*\+,;=%:@\/\?]+|%(?![A-Fa-f0-9]{2}))'; public function __construct($id, $named, $sep, $empty, $reserved, $start, $first) { $this->id = $id; $this->named = $named; $this->sep = $sep; $this->empty = $empty; $this->start = $start; $this->first = $first; $this->reserved = $reserved; } abstract public function toRegex(Parser $parser, Node\Variable $var): string; public function expand(Parser $parser, Node\Variable $var, array $params = []) { $options = $var->options; $name = $var->name; $is_explode = in_array($options['modifier'], ['*', '%']); // skip null if (!isset($params[$name])) { return null; } $val = $params[$name]; // This algorithm is based on RFC6570 http://tools.ietf.org/html/rfc6570 // non-array, e.g. string if (!is_array($val)) { return $this->expandString($parser, $var, $val); } // non-explode ':' if (!$is_explode) { return $this->expandNonExplode($parser, $var, $val); } // explode '*', '%' return $this->expandExplode($parser, $var, $val); } public function expandString(Parser $parser, Node\Variable $var, $val) { $val = (string) $val; $options = $var->options; $result = null; if ($options['modifier'] === ':') { $val = substr($val, 0, (int) $options['value']); } return $result . $this->encode($parser, $var, $val); } /** * Non explode modifier ':'. */ public function expandNonExplode(Parser $parser, Node\Variable $var, array $val): ?string { if (empty($val)) { return null; } return $this->encode($parser, $var, $val); } /** * Explode modifier '*', '%'. */ public function expandExplode(Parser $parser, Node\Variable $var, array $val): ?string { if (empty($val)) { return null; } return $this->encode($parser, $var, $val); } /** * Encodes variable according to spec (reserved or unreserved). * * @return string encoded string */ public function encode(Parser $parser, Node\Variable $var, mixed $values) { $values = (array) $values; $list = isset($values[0]); $reserved = $this->reserved; $maps = static::$reserved_chars; $sep = $this->sep; $assoc_sep = '='; // non-explode modifier always use ',' as a separator if ($var->options['modifier'] !== '*') { $assoc_sep = $sep = ','; } array_walk($values, function (&$v, $k) use ($assoc_sep, $reserved, $list, $maps): void { $encoded = rawurlencode($v); // assoc? encode key too if (!$list) { $encoded = rawurlencode($k) . $assoc_sep . $encoded; } // rawurlencode is compliant with 'unreserved' set if (!$reserved) { $v = $encoded; } // decode chars in reserved set else { $v = str_replace( array_keys($maps), $maps, $encoded, ); } }); return implode($sep, $values); } /** * Decodes variable. * * @return string decoded string */ public function decode(Parser $parser, Node\Variable $var, mixed $values) { $single = !is_array($values); $values = (array) $values; array_walk($values, function (&$v, $k): void { $v = rawurldecode($v); }); return $single ? reset($values) : $values; } /** * Extracts value from variable. */ public function extract(Parser $parser, Node\Variable $var, string $data): array|string { $value = $data; $vals = array_filter(explode($this->sep, $data)); $options = $var->options; switch ($options['modifier']) { case '*': $value = []; foreach ($vals as $val) { if (str_contains($val, '=')) { [$k, $v] = explode('=', $val); $value[$k] = $v; } else { $value[] = $val; } } break; case ':': break; default: $value = str_contains($value, (string) $this->sep) ? $vals : $value; } return $this->decode($parser, $var, $value); } public static function createById($id) { if (!isset(static::$types[$id])) { throw new \InvalidArgumentException("Invalid operator [{$id}]"); } if (isset(static::$loaded[$id])) { return static::$loaded[$id]; } $op = static::$types[$id]; $class = __NAMESPACE__ . '\\' . ($op['named'] ? 'Named' : 'UnNamed'); return static::$loaded[$id] = new $class($id, $op['named'], $op['sep'], $op['empty'], $op['reserved'], $op['start'], $op['first']); } public static function isValid($id): bool { return isset(static::$types[$id]); } /** * Returns the correct regex given the variable location in the URI. */ protected function getRegex(): string { return match ($this->id) { '?', '&', '#' => self::$queryRegex, default => self::$pathRegex, }; } } ================================================ FILE: lib/Google/vendor/rize/uri-template/src/Rize/UriTemplate/Operator/Named.php ================================================ name; $value = $this->getRegex(); $options = $var->options; if ($options['modifier']) { switch ($options['modifier']) { case '*': // 2 | 4 $regex = "{$name}+=(?:{$value}+(?:{$this->sep}{$name}+={$value}*)*)" . "|{$value}+=(?:{$value}+(?:{$this->sep}{$value}+={$value}*)*)"; break; case ':': $regex = "{$value}\\{0,{$options['value']}\\}"; break; case '%': // 5 $name .= '+(?:%5B|\[)[^=]*='; $regex = "{$name}(?:{$value}+(?:{$this->sep}{$name}{$value}*)*)"; break; default: throw new \InvalidArgumentException("Unknown modifier `{$options['modifier']}`"); } } else { // 1, 3 $regex = "{$name}=(?:{$value}+(?:,{$value}+)*)*"; } return '(?:&)?' . $regex; } public function expandString(Parser $parser, Node\Variable $var, $val): string { $val = (string) $val; $options = $var->options; $result = $this->encode($parser, $var, $var->name); // handle empty value if ($val === '') { return $result . $this->empty; } $result .= '='; if ($options['modifier'] === ':') { $val = mb_substr($val, 0, (int) $options['value']); } return $result . $this->encode($parser, $var, $val); } public function expandNonExplode(Parser $parser, Node\Variable $var, array $val): ?string { if (empty($val)) { return null; } $result = $this->encode($parser, $var, $var->name); $result .= '='; return $result . $this->encode($parser, $var, $val); } public function expandExplode(Parser $parser, Node\Variable $var, array $val): ?string { if (empty($val)) { return null; } $list = isset($val[0]); $data = []; foreach ($val as $k => $v) { // if value is a list, use `varname` as keyname, otherwise use `key` name $key = $list ? $var->name : $k; if ($list) { $data[$key][] = $v; } else { $data[$key] = $v; } } // if it's array modifier, we have to use variable name as index // e.g. if variable name is 'query' and value is ['limit' => 1] // then we convert it to ['query' => ['limit' => 1]] if (!$list && $var->options['modifier'] === '%') { $data = [$var->name => $data]; } return $this->encodeExplodeVars($var, $data); } public function extract(Parser $parser, Node\Variable $var, $data): array|string { // get rid of optional `&` at the beginning if ($data[0] === '&') { $data = substr($data, 1); } $value = $data; $vals = explode($this->sep, $data); $options = $var->options; switch ($options['modifier']) { case '%': parse_str($value, $query); return $query[$var->name]; case '*': $value = []; foreach ($vals as $val) { [$k, $v] = explode('=', $val); // 2 if ($k === $var->getToken()) { $value[] = $v; } // 4 else { $value[$k] = $v; } } break; case ':': break; default: // 1, 3 // remove key from value e.g. 'lang=en,th' becomes 'en,th' $value = str_replace($var->getToken() . '=', '', $value); $value = explode(',', $value); if (count($value) === 1) { $value = current($value); } } return $this->decode($parser, $var, $value); } public function encodeExplodeVars(Node\Variable $var, $data): null|array|string { // http_build_query uses PHP_QUERY_RFC1738 encoding by default // i.e. spaces are encoded as '+' (plus signs) we need to convert // it to %20 RFC3986 $query = http_build_query($data, '', $this->sep); $query = str_replace('+', '%20', $query); // `%` array modifier if ($var->options['modifier'] === '%') { // it also uses numeric based-index by default e.g. list[] becomes list[0] $query = preg_replace('#%5B\d+%5D#', '%5B%5D', $query); } // `:`, `*` modifiers else { // by default, http_build_query will convert array values to `a[]=1&a[]=2` // which is different from the spec. It should be `a=1&a=2` $query = preg_replace('#%5B\d+%5D#', '', $query); } // handle reserved charset if ($this->reserved) { $query = str_replace( array_keys(static::$reserved_chars), static::$reserved_chars, $query, ); } return $query; } } ================================================ FILE: lib/Google/vendor/rize/uri-template/src/Rize/UriTemplate/Operator/UnNamed.php ================================================ getRegex(); $options = $var->options; if ($options['modifier']) { switch ($options['modifier']) { case '*': // 2 | 4 $regex = "{$value}+(?:{$this->sep}{$value}+)*"; break; case ':': $regex = $value . '{0,' . $options['value'] . '}'; break; case '%': throw new \InvalidArgumentException('% (array) modifier only works with Named type operators e.g. ;,?,&'); default: throw new \InvalidArgumentException("Unknown modifier `{$options['modifier']}`"); } } else { // 1, 3 $regex = "{$value}*(?:,{$value}+)*"; } return $regex; } } ================================================ FILE: lib/Google/vendor/rize/uri-template/src/Rize/UriTemplate/Parser.php ================================================ createNode($part); // if current node has dot separator that requires a forward lookup // for the previous node iff previous node's operator is UnNamed if ($node instanceof Expression && $node->getOperator()->id === '.') { if (count($nodes) > 0) { $previousNode = $nodes[count($nodes) - 1]; if ($previousNode instanceof Expression && $previousNode->getOperator() instanceof UnNamed) { $previousNode->setForwardLookupSeparator($node->getOperator()->id); } } } $nodes[] = $node; } return $nodes; } protected function createNode(string $token): Abstraction { // literal string if ($token[0] !== '{') { $node = $this->createLiteralNode($token); } else { // remove `{}` from expression and parse it $node = $this->parseExpression(substr($token, 1, -1)); } return $node; } protected function parseExpression(string $expression): Expression { $token = $expression; $prefix = $token[0]; // not a valid operator? if (!Operator\Abstraction::isValid($prefix)) { // not valid chars? if (!preg_match('#' . self::REGEX_VARNAME . '#', $token)) { throw new \InvalidArgumentException("Invalid operator [{$prefix}] found at {$token}"); } // default operator // // PHP 8.5: using null as array offset is deprecated and we no longer rely on auto-casting null to ''. $prefix = ''; } // remove operator prefix if exists e.g. '?' if ($prefix) { $token = substr($token, 1); } // parse variables $vars = []; foreach (explode(',', $token) as $var) { $vars[] = $this->parseVariable($var); } return $this->createExpressionNode( $token, $this->createOperatorNode($prefix), $vars, ); } protected function parseVariable(string $var): Variable { $var = trim($var); $val = null; $modifier = null; // check for prefix (:) / explode (*) / array (%) modifier if (str_contains($var, ':')) { $modifier = ':'; [$varname, $val] = explode(':', $var); // error checking if (!is_numeric($val)) { throw new \InvalidArgumentException("Value for `:` modifier must be numeric value [{$varname}:{$val}]"); } } switch ($last = substr($var, -1)) { case '*': case '%': // there can be only 1 modifier per var if ($modifier) { throw new \InvalidArgumentException("Multiple modifiers per variable are not allowed [{$var}]"); } $modifier = $last; $var = substr($var, 0, -1); break; } return $this->createVariableNode( $var, ['modifier' => $modifier, 'value' => $val], ); } protected function createVariableNode($token, $options = []): Variable { return new Variable($token, $options); } protected function createExpressionNode($token, ?Operator\Abstraction $operator = null, array $vars = []): Expression { return new Expression($token, $operator, $vars); } protected function createLiteralNode(string $token): Node\Literal { return new Node\Literal($token); } protected function createOperatorNode($token): Operator\Abstraction { return Operator\Abstraction::createById($token); } } ================================================ FILE: lib/Google/vendor/rize/uri-template/src/Rize/UriTemplate/UriTemplate.php ================================================ parser = $parser ?: $this->createNodeParser(); } /** * Expands URI Template. * * @param mixed $params */ public function expand(string $uri, $params = []): string { $params += $this->params; $uri = $this->base_uri . $uri; $result = []; // quick check if (!str_contains($uri, '{')) { return $uri; } $parser = $this->parser; $nodes = $parser->parse($uri); foreach ($nodes as $node) { $result[] = $node->expand($parser, $params); } return implode('', $result); } /** * Extracts variables from URI. * * @return null|array params or null if not match and $strict is true */ public function extract(string $template, string $uri, bool $strict = false): ?array { $params = []; $nodes = $this->parser->parse($template); // PHP 8.1.0RC4-dev still throws deprecation warning for `strlen`. // $uri = (string) $uri; foreach ($nodes as $node) { // if strict is given, and there's no remaining uri just return null if ($strict && (string) $uri === '') { return null; } // URI will be truncated from the start when a match is found $match = $node->match($this->parser, $uri, $params, $strict); if ($match === null) { return null; } [$uri, $params] = $match; } // if there's remaining $uri, matching is failed if ($strict && (string) $uri !== '') { return null; } return $params; } public function getParser(): Parser { return $this->parser; } protected function createNodeParser(): Parser { static $parser; if ($parser) { return $parser; } return $parser = new Parser(); } } ================================================ FILE: lib/Google/vendor/rize/uri-template/tests/Rize/Uri/Node/ParserTest.php ================================================ ':', 'value' => 1], )], ), new Node\Literal('/'), new Node\Expression( 'term', Operator\Abstraction::createById(''), [new Node\Variable( 'term', ['modifier' => null, 'value' => null], )], ), new Node\Literal('/'), new Node\Expression( 'test*', Operator\Abstraction::createById(''), [new Node\Variable( 'test', ['modifier' => '*', 'value' => null], )], ), new Node\Literal('/foo'), new Node\Expression( 'query,number', Operator\Abstraction::createById('?'), [new Node\Variable( 'query', ['modifier' => null, 'value' => null], ), new Node\Variable( 'number', ['modifier' => null, 'value' => null], )], )]; $service = $this->service(); $actual = $service->parse($input); $this->assertEquals($expected, $actual); } public function testParseTemplateWithLiteral() { // will pass $uri = new UriTemplate('http://www.example.com/v1/company/', []); $params = $uri->extract('/{countryCode}/{registrationNumber}/test{.format}', '/gb/0123456/test.json'); static::assertEquals(['countryCode' => 'gb', 'registrationNumber' => '0123456', 'format' => 'json'], $params); } #[Depends('testParseTemplateWithLiteral')] public function testParseTemplateWithTwoVariablesAndDotBetween() { // will fail $uri = new UriTemplate('http://www.example.com/v1/company/', []); $params = $uri->extract('/{countryCode}/{registrationNumber}{.format}', '/gb/0123456.json'); static::assertEquals(['countryCode' => 'gb', 'registrationNumber' => '0123456', 'format' => 'json'], $params); } #[Depends('testParseTemplateWithLiteral')] public function testParseTemplateWithTwoVariablesAndDotBetweenStrict() { // will fail $uri = new UriTemplate('http://www.example.com/v1/company/', []); $params = $uri->extract('/{countryCode}/{registrationNumber}{.format}', '/gb/0123456.json', true); static::assertEquals(['countryCode' => 'gb', 'registrationNumber' => '0123456', 'format' => 'json'], $params); } #[Depends('testParseTemplateWithLiteral')] public function testParseTemplateWithThreeVariablesAndDotBetweenStrict() { // will fail $uri = new UriTemplate('http://www.example.com/v1/company/', []); $params = $uri->extract('/{countryCode}/{registrationNumber}{.namespace}{.format}', '/gb/0123456.company.json'); static::assertEquals(['countryCode' => 'gb', 'registrationNumber' => '0123456', 'namespace' => 'company', 'format' => 'json'], $params); } } ================================================ FILE: lib/Google/vendor/rize/uri-template/tests/Rize/UriTemplateTest.php ================================================ ["one", "two", "three"], 'dom' => ["example", "com"], 'dub' => "me/too", 'hello' => "Hello World!", 'half' => "50%", 'var' => "value", 'who' => "fred", 'base' => "http://example.com/home/", 'path' => "/foo/bar", 'list' => ["red", "green", "blue"], 'keys' => ["semi" => ";", "dot" => ".", "comma" => ","], 'list_with_empty' => [''], 'keys_with_empty' => ['john' => ''], 'v' => "6", 'x' => "1024", 'y' => "768", 'empty' => "", 'empty_keys' => [], 'undef' => null]; return [ ['http://example.com/~john', ['uri' => 'http://example.com/~{username}', 'params' => ['username' => 'john']]], ['http://example.com/dictionary/d/dog', ['uri' => 'http://example.com/dictionary/{term:1}/{term}', 'params' => ['term' => 'dog'], 'extract' => ['term:1' => 'd', 'term' => 'dog']]], # Form-style parameters expression ['http://example.com/j/john/search?q=mycelium&q=3&lang=th,jp,en', ['uri' => 'http://example.com/{term:1}/{term}/search{?q*,lang}', 'params' => ['q' => ['mycelium', 3], 'lang' => ['th', 'jp', 'en'], 'term' => 'john']]], ['http://www.example.com/john', ['uri' => 'http://www.example.com/{username}', 'params' => ['username' => 'john']]], ['http://www.example.com/foo?query=mycelium&number=100', ['uri' => 'http://www.example.com/foo{?query,number}', 'params' => ['query' => 'mycelium', 'number' => 100]]], # 'query' is undefined ['http://www.example.com/foo?number=100', [ 'uri' => 'http://www.example.com/foo{?query,number}', 'params' => ['number' => 100], # we can't extract undefined values 'extract' => false, ]], # undefined variables ['http://www.example.com/foo', ['uri' => 'http://www.example.com/foo{?query,number}', 'params' => [], 'extract' => ['query' => null, 'number' => null]]], ['http://www.example.com/foo', ['uri' => 'http://www.example.com/foo{?number}', 'params' => [], 'extract' => ['number' => null]]], ['one,two,three|one,two,three|/one,two,three|/one/two/three|;count=one,two,three|;count=one;count=two;count=three|?count=one,two,three|?count=one&count=two&count=three|&count=one&count=two&count=three', ['uri' => '{count}|{count*}|{/count}|{/count*}|{;count}|{;count*}|{?count}|{?count*}|{&count*}', 'params' => ['count' => ['one', 'two', 'three']]]], ['http://www.host.com/path/to/a/file.x.y', ['uri' => 'http://{host}{/segments*}/{file}{.extensions*}', 'params' => ['host' => 'www.host.com', 'segments' => ['path', 'to', 'a'], 'file' => 'file', 'extensions' => ['x', 'y']], 'extract' => ['host' => 'www.host.com', 'segments' => ['path', 'to', 'a'], 'file' => 'file.x.y', 'extensions' => null]]], # level 1 - Simple String Expansion: {var} ['value|Hello%20World%21|50%25|OX|OX|1024,768|1024,Hello%20World%21,768|?1024,|?1024|?768|val|value|red,green,blue|semi,%3B,dot,.,comma,%2C|semi=%3B,dot=.,comma=%2C', ['uri' => '{var}|{hello}|{half}|O{empty}X|O{undef}X|{x,y}|{x,hello,y}|?{x,empty}|?{x,undef}|?{undef,y}|{var:3}|{var:30}|{list}|{keys}|{keys*}', 'params' => $params]], # level 2 - Reserved Expansion: {+var} ['value|Hello%20World!|50%25|http%3A%2F%2Fexample.com%2Fhome%2Findex|http://example.com/home/index|OX|OX|/foo/bar/here|here?ref=/foo/bar|up/foo/barvalue/here|1024,Hello%20World!,768|/foo/bar,1024/here|/foo/b/here|red,green,blue|red,green,blue|semi,;,dot,.,comma,,|semi=;,dot=.,comma=,', ['uri' => '{+var}|{+hello}|{+half}|{base}index|{+base}index|O{+empty}X|O{+undef}X|{+path}/here|here?ref={+path}|up{+path}{var}/here|{+x,hello,y}|{+path,x}/here|{+path:6}/here|{+list}|{+list*}|{+keys}|{+keys*}', 'params' => $params]], # level 2 - Fragment Expansion: {#var} ['#value|#Hello%20World!|#50%25|foo#|foo|#1024,Hello%20World!,768|#/foo/bar,1024/here|#/foo/b/here|#red,green,blue|#red,green,blue|#semi,;,dot,.,comma,,|#semi=;,dot=.,comma=,', ['uri' => '{#var}|{#hello}|{#half}|foo{#empty}|foo{#undef}|{#x,hello,y}|{#path,x}/here|{#path:6}/here|{#list}|{#list*}|{#keys}|{#keys*}', 'params' => $params]], # Label Expansion with Dot-Prefix: {.var} ['.fred|.fred.fred|.50%25.fred|www.example.com|X.value|X.|X|X.val|X.red,green,blue|X.red.green.blue|X.semi,%3B,dot,.,comma,%2C|X.semi=%3B.dot=..comma=%2C|X|X', ['uri' => '{.who}|{.who,who}|{.half,who}|www{.dom*}|X{.var}|X{.empty}|X{.undef}|X{.var:3}|X{.list}|X{.list*}|X{.keys}|X{.keys*}|X{.empty_keys}|X{.empty_keys*}', 'params' => $params]], # Path Segment Expansion: {/var} ['/fred|/fred/fred|/50%25/fred|/fred/me%2Ftoo|/value|/value/|/value|/value/1024/here|/v/value|/red,green,blue|/red/green/blue|/red/green/blue/%2Ffoo|/semi,%3B,dot,.,comma,%2C|/semi=%3B/dot=./comma=%2C', ['uri' => '{/who}|{/who,who}|{/half,who}|{/who,dub}|{/var}|{/var,empty}|{/var,undef}|{/var,x}/here|{/var:1,var}|{/list}|{/list*}|{/list*,path:4}|{/keys}|{/keys*}', 'params' => $params]], # Path-Style Parameter Expansion: {;var} [';who=fred|;half=50%25|;empty|;v=6;empty;who=fred|;v=6;who=fred|;x=1024;y=768|;x=1024;y=768;empty|;x=1024;y=768|;hello=Hello|;list=red,green,blue|;list=red;list=green;list=blue|;keys=semi,%3B,dot,.,comma,%2C|;semi=%3B;dot=.;comma=%2C', ['uri' => '{;who}|{;half}|{;empty}|{;v,empty,who}|{;v,bar,who}|{;x,y}|{;x,y,empty}|{;x,y,undef}|{;hello:5}|{;list}|{;list*}|{;keys}|{;keys*}', 'params' => $params]], # Form-Style Query Expansion: {?var} ['?who=fred|?half=50%25|?x=1024&y=768|?x=1024&y=768&empty=|?x=1024&y=768|?var=val|?list=red,green,blue|?list=red&list=green&list=blue|?keys=semi,%3B,dot,.,comma,%2C|?semi=%3B&dot=.&comma=%2C|?list_with_empty=|?john=', ['uri' => '{?who}|{?half}|{?x,y}|{?x,y,empty}|{?x,y,undef}|{?var:3}|{?list}|{?list*}|{?keys}|{?keys*}|{?list_with_empty*}|{?keys_with_empty*}', 'params' => $params]], # Form-Style Query Continuation: {&var} ['&who=fred|&half=50%25|?fixed=yes&x=1024|&x=1024&y=768&empty=|&x=1024&y=768|&var=val|&list=red,green,blue|&list=red&list=green&list=blue|&keys=semi,%3B,dot,.,comma,%2C|&semi=%3B&dot=.&comma=%2C', ['uri' => '{&who}|{&half}|?fixed=yes{&x}|{&x,y,empty}|{&x,y,undef}|{&var:3}|{&list}|{&list*}|{&keys}|{&keys*}', 'params' => $params]], # Test empty values ['|||', ['uri' => '{empty}|{empty*}|{?empty}|{?empty*}', 'params' => ['empty' => []]]], ]; } public static function dataExpandWithArrayModifier() { return [ # List [ # '?choices[]=a&choices[]=b&choices[]=c', '?choices%5B%5D=a&choices%5B%5D=b&choices%5B%5D=c', ['uri' => '{?choices%}', 'params' => ['choices' => ['a', 'b', 'c']]], ], # Keys [ # '?choices[a]=1&choices[b]=2&choices[c][test]=3', '?choices%5Ba%5D=1&choices%5Bb%5D=2&choices%5Bc%5D%5Btest%5D=3', ['uri' => '{?choices%}', 'params' => ['choices' => ['a' => 1, 'b' => 2, 'c' => ['test' => 3]]]], ], # Mixed [ # '?list[]=a&list[]=b&keys[a]=1&keys[b]=2', '?list%5B%5D=a&list%5B%5D=b&keys%5Ba%5D=1&keys%5Bb%5D=2', ['uri' => '{?list%,keys%}', 'params' => ['list' => ['a', 'b'], 'keys' => ['a' => 1, 'b' => 2]]], ], ]; } public static function dataBaseTemplate() { return [ [ 'http://google.com/api/1/users/1', # base uri ['uri' => '{+host}/api/{v}', 'params' => ['host' => 'http://google.com', 'v' => 1]], # other uri ['uri' => '/{resource}/{id}', 'params' => ['resource' => 'users', 'id' => 1]], ], # test override base params [ 'http://github.com/api/1/users/1', # base uri ['uri' => '{+host}/api/{v}', 'params' => ['host' => 'http://google.com', 'v' => 1]], # other uri ['uri' => '/{resource}/{id}', 'params' => ['host' => 'http://github.com', 'resource' => 'users', 'id' => 1]], ], ]; } public static function dataExtraction() { return [['/no/{term:1}/random/foo{?query,list%,keys%}', '/no/j/random/foo?query=1,2,3&list%5B%5D=a&list%5B%5D=b&keys%5Ba%5D=1&keys%5Bb%5D=2&keys%5Bc%5D%5Btest%5D%5Btest%5D=1', ['term:1' => 'j', 'query' => [1, 2, 3], 'list' => ['a', 'b'], 'keys' => ['a' => 1, 'b' => 2, 'c' => ['test' => ['test' => 1]]]]], ['/no/{term:1}/random/{term}/{test*}/foo{?query,number}', '/no/j/random/john/a,b,c/foo?query=1,2,3&number=10', ['term:1' => 'j', 'term' => 'john', 'test' => ['a', 'b', 'c'], 'query' => [1, 2, 3], 'number' => 10]], ['/search/{term:1}/{term}/{?q*,limit}', '/search/j/john/?a=1&b=2&limit=10', ['term:1' => 'j', 'term' => 'john', 'q' => ['a' => 1, 'b' => 2], 'limit' => 10]], ['http://www.example.com/foo{?query,number}', 'http://www.example.com/foo?query=5', ['query' => 5, 'number' => null]], ['{count}|{count*}|{/count}|{/count*}|{;count}|{;count*}|{?count}|{?count*}|{&count*}', 'one,two,three|one,two,three|/one,two,three|/one/two/three|;count=one,two,three|;count=one;count=two;count=three|?count=one,two,three|?count=one&count=two&count=three|&count=one&count=two&count=three', ['count' => ['one', 'two', 'three']]], ['http://example.com/{term:1}/{term}/search{?q*,lang}', 'http://example.com/j/john/search?q=Hello%20World%21&q=3&lang=th,jp,en', ['q' => ['Hello World!', 3], 'lang' => ['th', 'jp', 'en'], 'term' => 'john', 'term:1' => 'j']], ['/foo/bar/{number}', '/foo/bar/0', ['number' => 0]], ['/some/{path}{?ref}', '/some/foo', ['path' => 'foo', 'ref' => null]]]; } /** * @dataProvider dataExpansion */ public function testExpansion($expected, $input) { $service = $this->service(); $result = $service->expand($input['uri'], $input['params']); $this->assertEquals($expected, $result); } /** * @dataProvider dataExpandWithArrayModifier */ public function testExpandWithArrayModifier($expected, $input) { $service = $this->service(); $result = $service->expand($input['uri'], $input['params']); $this->assertEquals($expected, $result); } /** * @dataProvider dataBaseTemplate */ public function testBaseTemplate($expected, $base, $other) { $service = $this->service($base['uri'], $base['params']); $result = $service->expand($other['uri'], $other['params']); $this->assertEquals($expected, $result); } /** * @dataProvider dataExtraction */ public function testExtract($template, $uri, $expected) { $service = $this->service(); $actual = $service->extract($template, $uri); $this->assertEquals($expected, $actual); } public function testExpandFromFixture() { $dir = dirname(__DIR__) . DIRECTORY_SEPARATOR . 'fixtures' . DIRECTORY_SEPARATOR; $files = ['spec-examples.json', 'spec-examples-by-section.json', 'extended-tests.json']; $service = $this->service(); foreach ($files as $file) { $content = json_decode(file_get_contents($dir . $file), $array = true); # iterate through each fixture foreach ($content as $fixture) { $vars = $fixture['variables']; # assert each test cases foreach ($fixture['testcases'] as $case) { [$uri, $expected] = $case; $actual = $service->expand($uri, $vars); if (is_array($expected)) { $expected = current(array_filter($expected, fn($input) => $actual === $input)); } $this->assertEquals($expected, $actual); } } } } public static function dataExtractStrictMode() { $dataTest = [['/search/{term:1}/{term}/{?q*,limit}', '/search/j/john/?a=1&b=2&limit=10', ['term:1' => 'j', 'term' => 'john', 'limit' => '10', 'q' => ['a' => '1', 'b' => '2']]], ['http://example.com/{term:1}/{term}/search{?q*,lang}', 'http://example.com/j/john/search?q=Hello%20World%21&q=3&lang=th,jp,en', ['term:1' => 'j', 'term' => 'john', 'lang' => ['th', 'jp', 'en'], 'q' => ['Hello World!', '3']]], ['/foo/bar/{number}', '/foo/bar/0', ['number' => 0]], ['/', '/', []]]; $rfc3986AllowedPathCharacters = ['-', '.', '_', '~', '!', '$', '&', "'", '(', ')', '*', '+', ',', ';', '=', ':', '@']; foreach ($rfc3986AllowedPathCharacters as $char) { $title = "RFC3986 path character ($char)"; $title = str_replace("'", 'single quote', $title); // PhpStorm workaround if ($char === ',') { // , means array on RFC6570 $params = ['term' => ['foo', 'baz']]; } else { $params = ['term' => "foo{$char}baz"]; } $data = ['/search/{term}', "/search/foo{$char}baz", $params]; $dataTest[$title] = $data; $data = ['/search/{;term}', "/search/;term=foo{$char}baz", $params]; $dataTest['Named ' . $title] = $data; } $rfc3986AllowedQueryCharacters = $rfc3986AllowedPathCharacters; $rfc3986AllowedQueryCharacters[] = '/'; $rfc3986AllowedQueryCharacters[] = '?'; unset($rfc3986AllowedQueryCharacters[array_search('&', $rfc3986AllowedQueryCharacters, true)]); foreach ($rfc3986AllowedQueryCharacters as $char) { $title = "RFC3986 query character ($char)"; $title = str_replace("'", 'single quote', $title); // PhpStorm workaround if ($char === ',') { // , means array on RFC6570 $params = ['term' => ['foo', 'baz']]; } else { $params = ['term' => "foo{$char}baz"]; } $data = ['/search/{?term}', "/search/?term=foo{$char}baz", $params]; $dataTest['Named ' . $title] = $data; } return $dataTest; } public static function extractStrictModeNotMatchProvider() { return [['/', '/a'], ['/{test}', '/a/'], ['/search/{term:1}/{term}/{?q*,limit}', '/search/j/?a=1&b=2&limit=10'], ['http://www.example.com/foo{?query,number}', 'http://www.example.com/foo?query=5'], ['http://www.example.com/foo{?query,number}', 'http://www.example.com/foo'], ['http://example.com/{term:1}/{term}/search{?q*,lang}', 'http://example.com/j/john/search?q=']]; } #[DataProvider('dataExtractStrictMode')] public function testExtractStrictMode(string $template, string $uri, array $expectedParams) { $service = $this->service(); $params = $service->extract($template, $uri, true); $this->assertTrue(isset($params)); $this->assertEquals($expectedParams, $params); } #[DataProvider('extractStrictModeNotMatchProvider')] public function testExtractStrictModeNotMatch(string $template, string $uri) { $service = $this->service(); $actual = $service->extract($template, $uri, true); $this->assertFalse(isset($actual)); } } ================================================ FILE: lib/Google/vendor/rize/uri-template/tests/fixtures/README.md ================================================ URI Template Tests ================== This is a set of tests for implementations of [RFC6570](http://tools.ietf.org/html/rfc6570) - URI Template. It is designed to be reused by any implementation, to improve interoperability and implementation quality. If your project uses Git for version control, you can make uritemplate-tests into a [submodule](http://help.github.com/submodules/). Test Format ----------- Each test file is a [JSON](http://tools.ietf.org/html/RFC6627) document containing an object whose properties are groups of related tests. Alternatively, all tests are available in XML as well, with the XML files being generated by transform-json-tests.xslt which uses json2xml.xslt as a general-purpose JSON-to-XML parsing library. Each group, in turn, is an object with three children: * level - the level of the tests covered, as per the RFC (optional; if absent, assume level 4). * variables - an object representing the variables that are available to the tests in the suite * testcases - a list of testcases, where each case is a two-member list, the first being the template, the second being the result of expanding the template with the provided variables. Note that the result string can be a few different things: * string - if the second member is a string, the result of expansion is expected to match it, character-for-character. * list - if the second member is a list of strings, the result of expansion is expected to match one of them; this allows for templates that can expand into different, equally-acceptable URIs. * false - if the second member is boolean false, expansion is expected to fail (i.e., the template was invalid). For example: { "Level 1 Examples" : { "level": 1, "variables": { "var" : "value", "hello" : "Hello World!" }, "testcases" : [ ["{var}", "value"], ["{hello}", "Hello%20World%21"] ] } } Tests Included -------------- The following test files are included: * spec-examples.json - The complete set of example templates from the RFC * spec-examples-by-section.json - The examples, section by section * extended-tests.json - more complex test cases * negative-tests.json - invalid templates For all these test files, XML versions with the names *.xml can be generated with the transform-json-tests.xslt XSLT stylesheet. The XSLT contains the names of the above test files as a parameter, and can be started with any XML as input (i.e., the XML input is ignored). License ------- Copyright 2011-2012 The Authors Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: lib/Google/vendor/rize/uri-template/tests/fixtures/extended-tests.json ================================================ { "Additional Examples 1":{ "level":4, "variables":{ "id" : "person", "token" : "12345", "fields" : ["id", "name", "picture"], "format" : "json", "q" : "URI Templates", "page" : "5", "lang" : "en", "geocode" : ["37.76","-122.427"], "first_name" : "John", "last.name" : "Doe", "Some%20Thing" : "foo", "number" : 6, "long" : 37.76, "lat" : -122.427, "group_id" : "12345", "query" : "PREFIX dc: SELECT ?book ?who WHERE { ?book dc:creator ?who }", "uri" : "http://example.org/?uri=http%3A%2F%2Fexample.org%2F", "word" : "drücken", "Stra%C3%9Fe" : "Grüner Weg", "random" : "šö䟜ñꀣ¥‡ÑÒÓÔÕÖרÙÚàáâãäåæçÿ", "assoc_special_chars" : { "šö䟜ñꀣ¥‡ÑÒÓÔÕ" : "ÖרÙÚàáâãäåæçÿ" } }, "testcases":[ [ "{/id*}" , "/person" ], [ "{/id*}{?fields,first_name,last.name,token}" , [ "/person?fields=id,name,picture&first_name=John&last.name=Doe&token=12345", "/person?fields=id,picture,name&first_name=John&last.name=Doe&token=12345", "/person?fields=picture,name,id&first_name=John&last.name=Doe&token=12345", "/person?fields=picture,id,name&first_name=John&last.name=Doe&token=12345", "/person?fields=name,picture,id&first_name=John&last.name=Doe&token=12345", "/person?fields=name,id,picture&first_name=John&last.name=Doe&token=12345"] ], ["/search.{format}{?q,geocode,lang,locale,page,result_type}", [ "/search.json?q=URI%20Templates&geocode=37.76,-122.427&lang=en&page=5", "/search.json?q=URI%20Templates&geocode=-122.427,37.76&lang=en&page=5"] ], ["/test{/Some%20Thing}", "/test/foo" ], ["/set{?number}", "/set?number=6"], ["/loc{?long,lat}" , "/loc?long=37.76&lat=-122.427"], ["/base{/group_id,first_name}/pages{/page,lang}{?format,q}","/base/12345/John/pages/5/en?format=json&q=URI%20Templates"], ["/sparql{?query}", "/sparql?query=PREFIX%20dc%3A%20%3Chttp%3A%2F%2Fpurl.org%2Fdc%2Felements%2F1.1%2F%3E%20SELECT%20%3Fbook%20%3Fwho%20WHERE%20%7B%20%3Fbook%20dc%3Acreator%20%3Fwho%20%7D"], ["/go{?uri}", "/go?uri=http%3A%2F%2Fexample.org%2F%3Furi%3Dhttp%253A%252F%252Fexample.org%252F"], ["/service{?word}", "/service?word=dr%C3%BCcken"], ["/lookup{?Stra%C3%9Fe}", "/lookup?Stra%25C3%259Fe=Gr%C3%BCner%20Weg"], ["{random}" , "%C5%A1%C3%B6%C3%A4%C5%B8%C5%93%C3%B1%C3%AA%E2%82%AC%C2%A3%C2%A5%E2%80%A1%C3%91%C3%92%C3%93%C3%94%C3%95%C3%96%C3%97%C3%98%C3%99%C3%9A%C3%A0%C3%A1%C3%A2%C3%A3%C3%A4%C3%A5%C3%A6%C3%A7%C3%BF"], ["{?assoc_special_chars*}", "?%C5%A1%C3%B6%C3%A4%C5%B8%C5%93%C3%B1%C3%AA%E2%82%AC%C2%A3%C2%A5%E2%80%A1%C3%91%C3%92%C3%93%C3%94%C3%95=%C3%96%C3%97%C3%98%C3%99%C3%9A%C3%A0%C3%A1%C3%A2%C3%A3%C3%A4%C3%A5%C3%A6%C3%A7%C3%BF"] ] }, "Additional Examples 2":{ "level":4, "variables":{ "id" : ["person","albums"], "token" : "12345", "fields" : ["id", "name", "picture"], "format" : "atom", "q" : "URI Templates", "page" : "10", "start" : "5", "lang" : "en", "geocode" : ["37.76","-122.427"] }, "testcases":[ [ "{/id*}" , ["/person/albums","/albums/person"] ], [ "{/id*}{?fields,token}" , [ "/person/albums?fields=id,name,picture&token=12345", "/person/albums?fields=id,picture,name&token=12345", "/person/albums?fields=picture,name,id&token=12345", "/person/albums?fields=picture,id,name&token=12345", "/person/albums?fields=name,picture,id&token=12345", "/person/albums?fields=name,id,picture&token=12345", "/albums/person?fields=id,name,picture&token=12345", "/albums/person?fields=id,picture,name&token=12345", "/albums/person?fields=picture,name,id&token=12345", "/albums/person?fields=picture,id,name&token=12345", "/albums/person?fields=name,picture,id&token=12345", "/albums/person?fields=name,id,picture&token=12345"] ] ] }, "Additional Examples 3: Empty Variables":{ "variables" : { "empty_list" : [], "empty_assoc" : {} }, "testcases":[ [ "{/empty_list}", [ "" ] ], [ "{/empty_list*}", [ "" ] ], [ "{?empty_list}", [ ""] ], [ "{?empty_list*}", [ "" ] ], [ "{?empty_assoc}", [ "" ] ], [ "{?empty_assoc*}", [ "" ] ] ] }, "Additional Examples 4: Numeric Keys":{ "variables" : { "42" : "The Answer to the Ultimate Question of Life, the Universe, and Everything", "1337" : ["leet", "as","it", "can","be"], "german" : { "11": "elf", "12": "zwölf" } }, "testcases":[ [ "{42}", "The%20Answer%20to%20the%20Ultimate%20Question%20of%20Life%2C%20the%20Universe%2C%20and%20Everything"], [ "{?42}", "?42=The%20Answer%20to%20the%20Ultimate%20Question%20of%20Life%2C%20the%20Universe%2C%20and%20Everything"], [ "{1337}", "leet,as,it,can,be"], [ "{?1337*}", "?1337=leet&1337=as&1337=it&1337=can&1337=be"], [ "{?german*}", [ "?11=elf&12=zw%C3%B6lf", "?12=zw%C3%B6lf&11=elf"] ] ] } } ================================================ FILE: lib/Google/vendor/rize/uri-template/tests/fixtures/json2xml.xslt ================================================ \b \v \f ================================================ FILE: lib/Google/vendor/rize/uri-template/tests/fixtures/negative-tests.json ================================================ { "Failure Tests":{ "level":4, "variables":{ "id" : "thing", "var" : "value", "hello" : "Hello World!", "with space" : "fail", " leading_space" : "Hi!", "trailing_space " : "Bye!", "empty" : "", "path" : "/foo/bar", "x" : "1024", "y" : "768", "list" : ["red", "green", "blue"], "keys" : { "semi" : ";", "dot" : ".", "comma" : ","}, "example" : "red", "searchTerms" : "uri templates", "~thing" : "some-user", "default-graph-uri" : ["http://www.example/book/","http://www.example/papers/"], "query" : "PREFIX dc: SELECT ?book ?who WHERE { ?book dc:creator ?who }" }, "testcases":[ [ "{/id*", false ], [ "/id*}", false ], [ "{/?id}", false ], [ "{var:prefix}", false ], [ "{hello:2*}", false ] , [ "{??hello}", false ] , [ "{!hello}", false ] , [ "{with space}", false], [ "{ leading_space}", false], [ "{trailing_space }", false], [ "{=path}", false ] , [ "{$var}", false ], [ "{|var*}", false ], [ "{*keys?}", false ], [ "{?empty=default,var}", false ], [ "{var}{-prefix|/-/|var}" , false ], [ "?q={searchTerms}&c={example:color?}" , false ], [ "x{?empty|foo=none}" , false ], [ "/h{#hello+}" , false ], [ "/h#{hello+}" , false ], [ "{keys:1}", false ], [ "{+keys:1}", false ], [ "{;keys:1*}", false ], [ "?{-join|&|var,list}" , false ], [ "/people/{~thing}", false], [ "/{default-graph-uri}", false ], [ "/sparql{?query,default-graph-uri}", false ], [ "/sparql{?query){&default-graph-uri*}", false ], [ "/resolution{?x, y}" , false ] ] } } ================================================ FILE: lib/Google/vendor/rize/uri-template/tests/fixtures/spec-examples-by-section.json ================================================ { "3.2.1 Variable Expansion" : { "variables": { "count" : ["one", "two", "three"], "dom" : ["example", "com"], "dub" : "me/too", "hello" : "Hello World!", "half" : "50%", "var" : "value", "who" : "fred", "base" : "http://example.com/home/", "path" : "/foo/bar", "list" : ["red", "green", "blue"], "keys" : { "semi" : ";", "dot" : ".", "comma" : ","}, "v" : "6", "x" : "1024", "y" : "768", "empty" : "", "empty_keys" : [], "undef" : null }, "testcases" : [ ["{count}", "one,two,three"], ["{count*}", "one,two,three"], ["{/count}", "/one,two,three"], ["{/count*}", "/one/two/three"], ["{;count}", ";count=one,two,three"], ["{;count*}", ";count=one;count=two;count=three"], ["{?count}", "?count=one,two,three"], ["{?count*}", "?count=one&count=two&count=three"], ["{&count*}", "&count=one&count=two&count=three"] ] }, "3.2.2 Simple String Expansion" : { "variables": { "count" : ["one", "two", "three"], "dom" : ["example", "com"], "dub" : "me/too", "hello" : "Hello World!", "half" : "50%", "var" : "value", "who" : "fred", "base" : "http://example.com/home/", "path" : "/foo/bar", "list" : ["red", "green", "blue"], "keys" : { "semi" : ";", "dot" : ".", "comma" : ","}, "v" : "6", "x" : "1024", "y" : "768", "empty" : "", "empty_keys" : [], "undef" : null }, "testcases" : [ ["{var}", "value"], ["{hello}", "Hello%20World%21"], ["{half}", "50%25"], ["O{empty}X", "OX"], ["O{undef}X", "OX"], ["{x,y}", "1024,768"], ["{x,hello,y}", "1024,Hello%20World%21,768"], ["?{x,empty}", "?1024,"], ["?{x,undef}", "?1024"], ["?{undef,y}", "?768"], ["{var:3}", "val"], ["{var:30}", "value"], ["{list}", "red,green,blue"], ["{list*}", "red,green,blue"], ["{keys}", [ "comma,%2C,dot,.,semi,%3B", "comma,%2C,semi,%3B,dot,.", "dot,.,comma,%2C,semi,%3B", "dot,.,semi,%3B,comma,%2C", "semi,%3B,comma,%2C,dot,.", "semi,%3B,dot,.,comma,%2C" ]], ["{keys*}", [ "comma=%2C,dot=.,semi=%3B", "comma=%2C,semi=%3B,dot=.", "dot=.,comma=%2C,semi=%3B", "dot=.,semi=%3B,comma=%2C", "semi=%3B,comma=%2C,dot=.", "semi=%3B,dot=.,comma=%2C" ]] ] }, "3.2.3 Reserved Expansion" : { "variables": { "count" : ["one", "two", "three"], "dom" : ["example", "com"], "dub" : "me/too", "hello" : "Hello World!", "half" : "50%", "var" : "value", "who" : "fred", "base" : "http://example.com/home/", "path" : "/foo/bar", "list" : ["red", "green", "blue"], "keys" : { "semi" : ";", "dot" : ".", "comma" : ","}, "v" : "6", "x" : "1024", "y" : "768", "empty" : "", "empty_keys" : [], "undef" : null }, "testcases" : [ ["{+var}", "value"], ["{/var,empty}", "/value/"], ["{/var,undef}", "/value"], ["{+hello}", "Hello%20World!"], ["{+half}", "50%25"], ["{base}index", "http%3A%2F%2Fexample.com%2Fhome%2Findex"], ["{+base}index", "http://example.com/home/index"], ["O{+empty}X", "OX"], ["O{+undef}X", "OX"], ["{+path}/here", "/foo/bar/here"], ["{+path:6}/here", "/foo/b/here"], ["here?ref={+path}", "here?ref=/foo/bar"], ["up{+path}{var}/here", "up/foo/barvalue/here"], ["{+x,hello,y}", "1024,Hello%20World!,768"], ["{+path,x}/here", "/foo/bar,1024/here"], ["{+list}", "red,green,blue"], ["{+list*}", "red,green,blue"], ["{+keys}", [ "comma,,,dot,.,semi,;", "comma,,,semi,;,dot,.", "dot,.,comma,,,semi,;", "dot,.,semi,;,comma,,", "semi,;,comma,,,dot,.", "semi,;,dot,.,comma,," ]], ["{+keys*}", [ "comma=,,dot=.,semi=;", "comma=,,semi=;,dot=.", "dot=.,comma=,,semi=;", "dot=.,semi=;,comma=,", "semi=;,comma=,,dot=.", "semi=;,dot=.,comma=," ]] ] }, "3.2.4 Fragment Expansion" : { "variables": { "count" : ["one", "two", "three"], "dom" : ["example", "com"], "dub" : "me/too", "hello" : "Hello World!", "half" : "50%", "var" : "value", "who" : "fred", "base" : "http://example.com/home/", "path" : "/foo/bar", "list" : ["red", "green", "blue"], "keys" : { "semi" : ";", "dot" : ".", "comma" : ","}, "v" : "6", "x" : "1024", "y" : "768", "empty" : "", "empty_keys" : [], "undef" : null }, "testcases" : [ ["{#var}", "#value"], ["{#hello}", "#Hello%20World!"], ["{#half}", "#50%25"], ["foo{#empty}", "foo#"], ["foo{#undef}", "foo"], ["{#x,hello,y}", "#1024,Hello%20World!,768"], ["{#path,x}/here", "#/foo/bar,1024/here"], ["{#path:6}/here", "#/foo/b/here"], ["{#list}", "#red,green,blue"], ["{#list*}", "#red,green,blue"], ["{#keys}", [ "#comma,,,dot,.,semi,;", "#comma,,,semi,;,dot,.", "#dot,.,comma,,,semi,;", "#dot,.,semi,;,comma,,", "#semi,;,comma,,,dot,.", "#semi,;,dot,.,comma,," ]] ] }, "3.2.5 Label Expansion with Dot-Prefix" : { "variables": { "count" : ["one", "two", "three"], "dom" : ["example", "com"], "dub" : "me/too", "hello" : "Hello World!", "half" : "50%", "var" : "value", "who" : "fred", "base" : "http://example.com/home/", "path" : "/foo/bar", "list" : ["red", "green", "blue"], "keys" : { "semi" : ";", "dot" : ".", "comma" : ","}, "v" : "6", "x" : "1024", "y" : "768", "empty" : "", "empty_keys" : [], "undef" : null }, "testcases" : [ ["{.who}", ".fred"], ["{.who,who}", ".fred.fred"], ["{.half,who}", ".50%25.fred"], ["www{.dom*}", "www.example.com"], ["X{.var}", "X.value"], ["X{.var:3}", "X.val"], ["X{.empty}", "X."], ["X{.undef}", "X"], ["X{.list}", "X.red,green,blue"], ["X{.list*}", "X.red.green.blue"], ["{#keys}", [ "#comma,,,dot,.,semi,;", "#comma,,,semi,;,dot,.", "#dot,.,comma,,,semi,;", "#dot,.,semi,;,comma,,", "#semi,;,comma,,,dot,.", "#semi,;,dot,.,comma,," ]], ["{#keys*}", [ "#comma=,,dot=.,semi=;", "#comma=,,semi=;,dot=.", "#dot=.,comma=,,semi=;", "#dot=.,semi=;,comma=,", "#semi=;,comma=,,dot=.", "#semi=;,dot=.,comma=," ]], ["X{.empty_keys}", "X"], ["X{.empty_keys*}", "X"] ] }, "3.2.6 Path Segment Expansion" : { "variables": { "count" : ["one", "two", "three"], "dom" : ["example", "com"], "dub" : "me/too", "hello" : "Hello World!", "half" : "50%", "var" : "value", "who" : "fred", "base" : "http://example.com/home/", "path" : "/foo/bar", "list" : ["red", "green", "blue"], "keys" : { "semi" : ";", "dot" : ".", "comma" : ","}, "v" : "6", "x" : "1024", "y" : "768", "empty" : "", "empty_keys" : [], "undef" : null }, "testcases" : [ ["{/who}", "/fred"], ["{/who,who}", "/fred/fred"], ["{/half,who}", "/50%25/fred"], ["{/who,dub}", "/fred/me%2Ftoo"], ["{/var}", "/value"], ["{/var,empty}", "/value/"], ["{/var,undef}", "/value"], ["{/var,x}/here", "/value/1024/here"], ["{/var:1,var}", "/v/value"], ["{/list}", "/red,green,blue"], ["{/list*}", "/red/green/blue"], ["{/list*,path:4}", "/red/green/blue/%2Ffoo"], ["{/keys}", [ "/comma,%2C,dot,.,semi,%3B", "/comma,%2C,semi,%3B,dot,.", "/dot,.,comma,%2C,semi,%3B", "/dot,.,semi,%3B,comma,%2C", "/semi,%3B,comma,%2C,dot,.", "/semi,%3B,dot,.,comma,%2C" ]], ["{/keys*}", [ "/comma=%2C/dot=./semi=%3B", "/comma=%2C/semi=%3B/dot=.", "/dot=./comma=%2C/semi=%3B", "/dot=./semi=%3B/comma=%2C", "/semi=%3B/comma=%2C/dot=.", "/semi=%3B/dot=./comma=%2C" ]] ] }, "3.2.7 Path-Style Parameter Expansion" : { "variables": { "count" : ["one", "two", "three"], "dom" : ["example", "com"], "dub" : "me/too", "hello" : "Hello World!", "half" : "50%", "var" : "value", "who" : "fred", "base" : "http://example.com/home/", "path" : "/foo/bar", "list" : ["red", "green", "blue"], "keys" : { "semi" : ";", "dot" : ".", "comma" : ","}, "v" : "6", "x" : "1024", "y" : "768", "empty" : "", "empty_keys" : [], "undef" : null }, "testcases" : [ ["{;who}", ";who=fred"], ["{;half}", ";half=50%25"], ["{;empty}", ";empty"], ["{;hello:5}", ";hello=Hello"], ["{;v,empty,who}", ";v=6;empty;who=fred"], ["{;v,bar,who}", ";v=6;who=fred"], ["{;x,y}", ";x=1024;y=768"], ["{;x,y,empty}", ";x=1024;y=768;empty"], ["{;x,y,undef}", ";x=1024;y=768"], ["{;list}", ";list=red,green,blue"], ["{;list*}", ";list=red;list=green;list=blue"], ["{;keys}", [ ";keys=comma,%2C,dot,.,semi,%3B", ";keys=comma,%2C,semi,%3B,dot,.", ";keys=dot,.,comma,%2C,semi,%3B", ";keys=dot,.,semi,%3B,comma,%2C", ";keys=semi,%3B,comma,%2C,dot,.", ";keys=semi,%3B,dot,.,comma,%2C" ]], ["{;keys*}", [ ";comma=%2C;dot=.;semi=%3B", ";comma=%2C;semi=%3B;dot=.", ";dot=.;comma=%2C;semi=%3B", ";dot=.;semi=%3B;comma=%2C", ";semi=%3B;comma=%2C;dot=.", ";semi=%3B;dot=.;comma=%2C" ]] ] }, "3.2.8 Form-Style Query Expansion" : { "variables": { "count" : ["one", "two", "three"], "dom" : ["example", "com"], "dub" : "me/too", "hello" : "Hello World!", "half" : "50%", "var" : "value", "who" : "fred", "base" : "http://example.com/home/", "path" : "/foo/bar", "list" : ["red", "green", "blue"], "keys" : { "semi" : ";", "dot" : ".", "comma" : ","}, "v" : "6", "x" : "1024", "y" : "768", "empty" : "", "empty_keys" : [], "undef" : null }, "testcases" : [ ["{?who}", "?who=fred"], ["{?half}", "?half=50%25"], ["{?x,y}", "?x=1024&y=768"], ["{?x,y,empty}", "?x=1024&y=768&empty="], ["{?x,y,undef}", "?x=1024&y=768"], ["{?var:3}", "?var=val"], ["{?list}", "?list=red,green,blue"], ["{?list*}", "?list=red&list=green&list=blue"], ["{?keys}", [ "?keys=comma,%2C,dot,.,semi,%3B", "?keys=comma,%2C,semi,%3B,dot,.", "?keys=dot,.,comma,%2C,semi,%3B", "?keys=dot,.,semi,%3B,comma,%2C", "?keys=semi,%3B,comma,%2C,dot,.", "?keys=semi,%3B,dot,.,comma,%2C" ]], ["{?keys*}", [ "?comma=%2C&dot=.&semi=%3B", "?comma=%2C&semi=%3B&dot=.", "?dot=.&comma=%2C&semi=%3B", "?dot=.&semi=%3B&comma=%2C", "?semi=%3B&comma=%2C&dot=.", "?semi=%3B&dot=.&comma=%2C" ]] ] }, "3.2.9 Form-Style Query Continuation" : { "variables": { "count" : ["one", "two", "three"], "dom" : ["example", "com"], "dub" : "me/too", "hello" : "Hello World!", "half" : "50%", "var" : "value", "who" : "fred", "base" : "http://example.com/home/", "path" : "/foo/bar", "list" : ["red", "green", "blue"], "keys" : { "semi" : ";", "dot" : ".", "comma" : ","}, "v" : "6", "x" : "1024", "y" : "768", "empty" : "", "empty_keys" : [], "undef" : null }, "testcases" : [ ["{&who}", "&who=fred"], ["{&half}", "&half=50%25"], ["?fixed=yes{&x}", "?fixed=yes&x=1024"], ["{&var:3}", "&var=val"], ["{&x,y,empty}", "&x=1024&y=768&empty="], ["{&x,y,undef}", "&x=1024&y=768"], ["{&list}", "&list=red,green,blue"], ["{&list*}", "&list=red&list=green&list=blue"], ["{&keys}", [ "&keys=comma,%2C,dot,.,semi,%3B", "&keys=comma,%2C,semi,%3B,dot,.", "&keys=dot,.,comma,%2C,semi,%3B", "&keys=dot,.,semi,%3B,comma,%2C", "&keys=semi,%3B,comma,%2C,dot,.", "&keys=semi,%3B,dot,.,comma,%2C" ]], ["{&keys*}", [ "&comma=%2C&dot=.&semi=%3B", "&comma=%2C&semi=%3B&dot=.", "&dot=.&comma=%2C&semi=%3B", "&dot=.&semi=%3B&comma=%2C", "&semi=%3B&comma=%2C&dot=.", "&semi=%3B&dot=.&comma=%2C" ]] ] } } ================================================ FILE: lib/Google/vendor/rize/uri-template/tests/fixtures/spec-examples.json ================================================ { "Level 1 Examples" : { "level": 1, "variables": { "var" : "value", "hello" : "Hello World!" }, "testcases" : [ ["{var}", "value"], ["{hello}", "Hello%20World%21"] ] }, "Level 2 Examples" : { "level": 2, "variables": { "var" : "value", "hello" : "Hello World!", "path" : "/foo/bar" }, "testcases" : [ ["{+var}", "value"], ["{+hello}", "Hello%20World!"], ["{+path}/here", "/foo/bar/here"], ["here?ref={+path}", "here?ref=/foo/bar"] ] }, "Level 3 Examples" : { "level": 3, "variables": { "var" : "value", "hello" : "Hello World!", "empty" : "", "path" : "/foo/bar", "x" : "1024", "y" : "768" }, "testcases" : [ ["map?{x,y}", "map?1024,768"], ["{x,hello,y}", "1024,Hello%20World%21,768"], ["{+x,hello,y}", "1024,Hello%20World!,768"], ["{+path,x}/here", "/foo/bar,1024/here"], ["{#x,hello,y}", "#1024,Hello%20World!,768"], ["{#path,x}/here", "#/foo/bar,1024/here"], ["X{.var}", "X.value"], ["X{.x,y}", "X.1024.768"], ["{/var}", "/value"], ["{/var,x}/here", "/value/1024/here"], ["{;x,y}", ";x=1024;y=768"], ["{;x,y,empty}", ";x=1024;y=768;empty"], ["{?x,y}", "?x=1024&y=768"], ["{?x,y,empty}", "?x=1024&y=768&empty="], ["?fixed=yes{&x}", "?fixed=yes&x=1024"], ["{&x,y,empty}", "&x=1024&y=768&empty="] ] }, "Level 4 Examples" : { "level": 4, "variables": { "var": "value", "hello": "Hello World!", "path": "/foo/bar", "list": ["red", "green", "blue"], "keys": {"semi": ";", "dot": ".", "comma":","} }, "testcases": [ ["{var:3}", "val"], ["{var:30}", "value"], ["{list}", "red,green,blue"], ["{list*}", "red,green,blue"], ["{keys}", [ "comma,%2C,dot,.,semi,%3B", "comma,%2C,semi,%3B,dot,.", "dot,.,comma,%2C,semi,%3B", "dot,.,semi,%3B,comma,%2C", "semi,%3B,comma,%2C,dot,.", "semi,%3B,dot,.,comma,%2C" ]], ["{keys*}", [ "comma=%2C,dot=.,semi=%3B", "comma=%2C,semi=%3B,dot=.", "dot=.,comma=%2C,semi=%3B", "dot=.,semi=%3B,comma=%2C", "semi=%3B,comma=%2C,dot=.", "semi=%3B,dot=.,comma=%2C" ]], ["{+path:6}/here", "/foo/b/here"], ["{+list}", "red,green,blue"], ["{+list*}", "red,green,blue"], ["{+keys}", [ "comma,,,dot,.,semi,;", "comma,,,semi,;,dot,.", "dot,.,comma,,,semi,;", "dot,.,semi,;,comma,,", "semi,;,comma,,,dot,.", "semi,;,dot,.,comma,," ]], ["{+keys*}", [ "comma=,,dot=.,semi=;", "comma=,,semi=;,dot=.", "dot=.,comma=,,semi=;", "dot=.,semi=;,comma=,", "semi=;,comma=,,dot=.", "semi=;,dot=.,comma=," ]], ["{#path:6}/here", "#/foo/b/here"], ["{#list}", "#red,green,blue"], ["{#list*}", "#red,green,blue"], ["{#keys}", [ "#comma,,,dot,.,semi,;", "#comma,,,semi,;,dot,.", "#dot,.,comma,,,semi,;", "#dot,.,semi,;,comma,,", "#semi,;,comma,,,dot,.", "#semi,;,dot,.,comma,," ]], ["{#keys*}", [ "#comma=,,dot=.,semi=;", "#comma=,,semi=;,dot=.", "#dot=.,comma=,,semi=;", "#dot=.,semi=;,comma=,", "#semi=;,comma=,,dot=.", "#semi=;,dot=.,comma=," ]], ["X{.var:3}", "X.val"], ["X{.list}", "X.red,green,blue"], ["X{.list*}", "X.red.green.blue"], ["X{.keys}", [ "X.comma,%2C,dot,.,semi,%3B", "X.comma,%2C,semi,%3B,dot,.", "X.dot,.,comma,%2C,semi,%3B", "X.dot,.,semi,%3B,comma,%2C", "X.semi,%3B,comma,%2C,dot,.", "X.semi,%3B,dot,.,comma,%2C" ]], ["{/var:1,var}", "/v/value"], ["{/list}", "/red,green,blue"], ["{/list*}", "/red/green/blue"], ["{/list*,path:4}", "/red/green/blue/%2Ffoo"], ["{/keys}", [ "/comma,%2C,dot,.,semi,%3B", "/comma,%2C,semi,%3B,dot,.", "/dot,.,comma,%2C,semi,%3B", "/dot,.,semi,%3B,comma,%2C", "/semi,%3B,comma,%2C,dot,.", "/semi,%3B,dot,.,comma,%2C" ]], ["{/keys*}", [ "/comma=%2C/dot=./semi=%3B", "/comma=%2C/semi=%3B/dot=.", "/dot=./comma=%2C/semi=%3B", "/dot=./semi=%3B/comma=%2C", "/semi=%3B/comma=%2C/dot=.", "/semi=%3B/dot=./comma=%2C" ]], ["{;hello:5}", ";hello=Hello"], ["{;list}", ";list=red,green,blue"], ["{;list*}", ";list=red;list=green;list=blue"], ["{;keys}", [ ";keys=comma,%2C,dot,.,semi,%3B", ";keys=comma,%2C,semi,%3B,dot,.", ";keys=dot,.,comma,%2C,semi,%3B", ";keys=dot,.,semi,%3B,comma,%2C", ";keys=semi,%3B,comma,%2C,dot,.", ";keys=semi,%3B,dot,.,comma,%2C" ]], ["{;keys*}", [ ";comma=%2C;dot=.;semi=%3B", ";comma=%2C;semi=%3B;dot=.", ";dot=.;comma=%2C;semi=%3B", ";dot=.;semi=%3B;comma=%2C", ";semi=%3B;comma=%2C;dot=.", ";semi=%3B;dot=.;comma=%2C" ]], ["{?var:3}", "?var=val"], ["{?list}", "?list=red,green,blue"], ["{?list*}", "?list=red&list=green&list=blue"], ["{?keys}", [ "?keys=comma,%2C,dot,.,semi,%3B", "?keys=comma,%2C,semi,%3B,dot,.", "?keys=dot,.,comma,%2C,semi,%3B", "?keys=dot,.,semi,%3B,comma,%2C", "?keys=semi,%3B,comma,%2C,dot,.", "?keys=semi,%3B,dot,.,comma,%2C" ]], ["{?keys*}", [ "?comma=%2C&dot=.&semi=%3B", "?comma=%2C&semi=%3B&dot=.", "?dot=.&comma=%2C&semi=%3B", "?dot=.&semi=%3B&comma=%2C", "?semi=%3B&comma=%2C&dot=.", "?semi=%3B&dot=.&comma=%2C" ]], ["{&var:3}", "&var=val"], ["{&list}", "&list=red,green,blue"], ["{&list*}", "&list=red&list=green&list=blue"], ["{&keys}", [ "&keys=comma,%2C,dot,.,semi,%3B", "&keys=comma,%2C,semi,%3B,dot,.", "&keys=dot,.,comma,%2C,semi,%3B", "&keys=dot,.,semi,%3B,comma,%2C", "&keys=semi,%3B,comma,%2C,dot,.", "&keys=semi,%3B,dot,.,comma,%2C" ]], ["{&keys*}", [ "&comma=%2C&dot=.&semi=%3B", "&comma=%2C&semi=%3B&dot=.", "&dot=.&comma=%2C&semi=%3B", "&dot=.&semi=%3B&comma=%2C", "&semi=%3B&comma=%2C&dot=.", "&semi=%3B&dot=.&comma=%2C" ]] ] } } ================================================ FILE: lib/Google/vendor/rize/uri-template/tests/fixtures/transform-json-tests.xslt ================================================ ================================================ FILE: lib/Google/vendor/symfony/deprecation-contracts/CHANGELOG.md ================================================ CHANGELOG ========= The changelog is maintained for all Symfony contracts at the following URL: https://github.com/symfony/contracts/blob/main/CHANGELOG.md ================================================ FILE: lib/Google/vendor/symfony/deprecation-contracts/LICENSE ================================================ 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. ================================================ FILE: lib/Google/vendor/symfony/deprecation-contracts/README.md ================================================ 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. ================================================ FILE: lib/Google/vendor/symfony/deprecation-contracts/composer.json ================================================ { "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.6-dev" }, "thanks": { "name": "symfony/contracts", "url": "https://github.com/symfony/contracts" } } } ================================================ FILE: lib/Google/vendor/symfony/deprecation-contracts/function.php ================================================ * * 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, mixed ...$args): void { @trigger_error(($package || $version ? "Since $package $version: " : '').($args ? vsprintf($message, $args) : $message), \E_USER_DEPRECATED); } } ================================================ FILE: lib/classes/batch/class-batch-task-manager.php ================================================ path('lib/ns-vendor/classes/deliciousbrains/wp-background-processing/classes/wp-async-request.php', 'dir'); } if (!class_exists('UDX_WP_Background_Process')) { require_once ud_get_stateless_media()->path('lib/ns-vendor/classes/deliciousbrains/wp-background-processing/classes/wp-background-process.php', 'dir'); } use wpCloud\StatelessMedia\Helper; use wpCloud\StatelessMedia\Singleton; class BatchTaskManager extends \UDX_WP_Background_Process { use Singleton; const STATE_KEY = '_state'; const UPDATED_KEY = '_updated'; const HEALTH_CHECK_INTERVAL = 60 * 5; // 5 minute protected $prefix = 'sm'; protected $action = 'batch_process'; protected function __construct() { parent::__construct(); $this->_init_hooks(); $this->_check_force_continue(); } private function _init_hooks() { add_filter('wp_stateless_batch_state', [$this, 'get_state'], 10, 1); add_filter('wp_stateless_batch_action_pause', [$this, 'pause_task'], 10, 2); add_filter('wp_stateless_batch_action_resume', [$this, 'resume_task'], 10, 2); add_filter('heartbeat_send', [$this, 'check_running_batch'], 10, 1 ); } /** * Check if we should force dispatch * Check if the task is in progress and if the state was not updated last 5 minutes - try to continue the task */ private function _check_force_continue() { $last_updated = $this->_get_last_updated(); if ( empty($last_updated) || $this->is_paused() ) { return; } $check_interval = self::HEALTH_CHECK_INTERVAL; if ( defined('WP_STATELESS_BATCH_HEALTHCHECK_INTERVAL') ) { $check_interval = max($check_interval, WP_STATELESS_BATCH_HEALTHCHECK_INTERVAL * 60); } if ( time() - $last_updated <= $check_interval ) { return; } Helper::log('Batch task freezed, trying to continue...'); // Forcing continue $this->unlock_process(); $this->handle(); } /** * Update current task state * * @return array */ private function _update_state($state) { update_option( $this->identifier . self::STATE_KEY, $state ); update_option( $this->identifier . self::UPDATED_KEY, time() ); } /** * Get current task state * * @return array */ private function _get_state() { // We need to omit the cache and get the data directly from the db global $wpdb; $sql = "SELECT option_value FROM $wpdb->options WHERE option_name = '%s' LIMIT 1"; $sql = $wpdb->prepare($sql, $this->identifier . self::STATE_KEY); $state = $wpdb->get_var($sql); return empty($state) ? [] : maybe_unserialize($state); } /** * Get last state update of the current task * * @return int|null */ private function _get_last_updated() { // We need to omit the cache and get the data directly from the db global $wpdb; $sql = "SELECT option_value FROM $wpdb->options WHERE option_name = '%s' LIMIT 1"; $sql = $wpdb->prepare($sql, $this->identifier . self::UPDATED_KEY); return $wpdb->get_var($sql); } /** * Delete current task state * * @return array */ private function _delete_state() { delete_option( $this->identifier . self::STATE_KEY ); delete_option( $this->identifier . self::UPDATED_KEY ); } /** * Add new batch to the queue * * @param array $batch */ private function _add_batch($batch) { if ( !empty($batch) ) { $this->data( $batch )->save(); } } /** * Get task object * * @param string $state|null * @return IBatchTask * @throws \Exception */ private function _get_batch_task_object($state = null) { if ( empty($state) ) { $state = $this->_get_state(); } if ( !isset($state['class']) || !isset($state['file']) ) { throw new \Exception("Can not get batch task file and class"); } $class = $state['class']; if ( !class_exists($class) ) { require_once $state['file']; } $object = new $class(); if ( !is_a($object, '\wpCloud\StatelessMedia\Batch\IBatchTask') ) { throw new \Exception("Batch task $class is not valid"); } $object->set_state($state); return $object; } /** * Start the batch task * * @param string $class * @param string|null $file * @param string $email */ public function start_task($class, $file = null, $email = '', $queue = []) { try { // Prepare default state $defaults = [ 'class' => $class, 'file' => $file, 'email' => $email, 'queue' => $queue, ]; $task_object = $this->_get_batch_task_object($defaults); $task_object->init_state(); // Batch should be run prior to 'get_state' because it mutates the state $this->_add_batch( $task_object->get_batch() ); // Save state $state = wp_parse_args($task_object->get_state(), $defaults); $this->_update_state( $state ); Helper::log('Batch task started: ' . $class); do_action('wp_stateless_batch_task_started', $class, $file); } catch (\Throwable $e) { Helper::log("Batch task $class failed to start: " . $e->getMessage()); do_action('wp_stateless_batch_task_failed', $class, $file, $e->getMessage()); return; } $this->dispatch(); } /** * Process batch task item. * Returns false to remove item from queue * Returns $item to repeat * * @param string $item * @return bool|mixed */ public function task($item) { $result = false; try { $object = $this->_get_batch_task_object(); $result = $object->process_item($item); $this->_update_state( $object->get_state() ); $result = apply_filters('wp_stateless_batch_task_item_processed', $result, $item); } catch (\Throwable $e) { Helper::log( "Batch task unable to handle item $item: " . $e->getMessage() ); $result = apply_filters('wp_stateless_batch_task_item_failed', $result, $item); } return $result; } /** * Complete the batch task. Tries to get the next batch and continue */ protected function complete() { $class = ''; // Check if we have more batched to run try { $object = $this->_get_batch_task_object(); $class = get_class($object); $batch = $object->get_batch(); if ( !empty($batch) ) { $this->_add_batch( $batch ); $this->_update_state( $object->get_state() ); $this->dispatch(); return; } Helper::log( 'Batch task completed: ' . $class ); } catch (\Throwable $e) { Helper::log( "Unable to process next batch: " . $e->getMessage() ); } // If no more batches - delete state $state = $this->_get_state(); parent::complete(); $this->_delete_state(); do_action('wp_stateless_batch_task_finished', $class, $state); $site = site_url(); $subject = sprintf( __('WP-Stateless: Data Optimization Complete', ud_get_stateless_media()->domain) ); $message = sprintf( __("WP-Stateless data has been optimized for %s.\n\nIf you have WP_STATELESS_SYNC_LOG or WP_DEBUG_LOG enabled, review those logs now to review any errors that may have occurred during the synchronization process.", ud_get_stateless_media()->domain), $site ); do_action('wp_stateless_send_admin_email', $subject, $message, $state['email'] ?? ''); } /** * Check if batch task has a state, so it is in progress * Because is_processing is true only while processing an item * * @param array|null $state * @return bool */ public function is_running($state = null) { if ( empty($state) ) { $state = $this->_get_state(); } return !empty($state); } /** * Get the state of the current batch process * * @param mixed $status * @return mixed */ public function get_state($state) { $state = $this->_get_state(); unset($state['class']); unset($state['file']); $state['is_running'] = $this->is_running($state); $state['is_paused'] = $this->is_paused(); return $state; } /** * Pause the batch task * * @param array $state * @param array $params * @return array */ public function pause_task($state, $params) { $this->pause(); return apply_filters('wp_stateless_batch_state', $state, []); } /** * Resume the batch task * * @param array $state * @param array $params * @return array */ public function resume_task($state, $params) { $this->resume(); return apply_filters('wp_stateless_batch_state', $state, []); } /** * Get the state key * * @return string */ public function get_state_key() { return $this->identifier . self::STATE_KEY; } /** * Check if batch is running during WP heartbeat request * * @return array */ public function check_running_batch($response) { if ( $this->is_running() ) { $response['stateless-batch-running'] = true; } return $response; } } ================================================ FILE: lib/classes/batch/class-batch-task.php ================================================ started = time(); } /** * Get human-friendly description * * @return string */ public function get_description() { return $this->description; } /** * Get task state * * @return array */ public function get_state() { if ( empty($this->started) ) { $this->init_state(); } // Calling process can add extra data to the state, so we should try to keep it return wp_parse_args([ 'id' => $this->id, 'description' => $this->description, 'total' => $this->total, 'completed' => $this->completed, 'limit' => $this->limit, 'offset' => $this->offset, 'started' => $this->started, ], $this->state); } /** * Restore task state for processing between calls * * @param array $state * @return array */ public function set_state($state) { // Calling process can add extra data to the state, so we should try to keep it $this->state = $state; // Restore state properties required for processing if ( isset($state['description']) ) { $this->description = $state['description']; } if ( isset($state['started']) ) { $this->started = $state['started']; } if ( isset($state['total']) ) { $this->total = $state['total']; } if ( isset($state['completed']) ) { $this->completed = $state['completed']; } if ( isset($state['limit']) ) { $this->limit = $state['limit']; } if ( isset($state['offset']) ) { $this->offset = $state['offset']; } } /** * Get batch of data to process. False - no more data * * @return array|false */ abstract public function get_batch(); /** * Process single item. If returns false - the item is removed from the queue. Otherwise repeated. * * @param mixed $item * @return mixed|false */ abstract public function process_item($item); } ================================================ FILE: lib/classes/batch/class-migration.php ================================================ id; $state['is_migration'] = true; $state['stop'] = $this->stop; return $state; } public function set_state($state) { parent::set_state($state); $this->stop = $state['stop'] ?? false; } /** * Can be used to test if the migration should run * For example, if there are any old data that needs to be migrated */ public function should_run() { return true; } } ================================================ FILE: lib/classes/batch/interface-batch.php ================================================ path('static/data/addons.php', 'dir'); if ( file_exists($addons_file) ) { $this->addons = require_once($addons_file); $this->addon_ids = array_keys($this->addons); } add_action('sm::module::init', array($this, 'check_addons')); add_action('sm::module::messages', array($this, 'show_messages'), 10, 3); add_action('wp_stateless_addons_tab_content', array($this, 'tab_content')); add_filter('wp_stateless_addons_tab_visible', array($this, 'addons_tab_visible'), 10, 1); add_filter('wp_stateless_restrict_compatibility', array($this, 'restrict_compatibility'), 10, 3); add_filter('wp_stateless_addon_files_root', array($this, 'get_addon_files_root'), 10); add_filter('wp_stateless_addon_sync_files_path', array($this, 'get_addon_sync_files_path'), 10, 2); add_filter('wp_stateless_addon_files_url', array($this, 'get_addon_files_url'), 10, 2); } /** * Check current theme and installed plugins for recommended addons. * Fires hok to display messages if recommended addons are not active. * */ public function check_addons() { $active_plugins = Helper::get_active_plugins(); foreach ($this->addons as $id => $addon) { // Recommended theme addons if ( isset($addon['theme_name']) ) { if ( Helper::is_theme_name($addon['theme_name']) ) { $this->addons[$id]['recommended'] = true; $this->recommended++; } } // Recommended plugin addons if ( isset($addon['plugin_files']) && is_array($addon['plugin_files']) ) { foreach ($addon['plugin_files'] as $file) { if ( in_array($file, $active_plugins) ) { $this->addons[$id]['recommended'] = true; $this->recommended++; break; } } } // Active addons if ( isset($addon['addon_file']) ) { if ( in_array($addon['addon_file'], $active_plugins) ) { $this->addons[$id]['active'] = true; $this->active++; } } // Installed addons if ( isset($addon['addon_file']) ) { if ( file_exists( WP_PLUGIN_DIR . '/' . $addon['addon_file'] ) ) { $this->addons[$id]['installed'] = true; $this->addons[$id]['activate_link'] = wp_nonce_url( 'plugins.php?action=activate&plugin=' . $addon['addon_file'], 'activate-plugin_' . $addon['addon_file'] ); } } } // Show message if recommended addons are not active do_action('sm::module::messages', $this->addons); } /** * Add messages for recommended addons. * * @param array $addons * @param array $recommended * @param array $active * */ public function show_messages($addons) { foreach ($addons as $id => $addon) { if ( !isset($addon['recommended']) || isset($addon['active']) ) { continue; } $title = $addon['title']; $button = __('Download Addon', ud_get_stateless_media()->domain); $button_link = admin_url('upload.php?page=stateless-settings&tab=stless_addons_tab'); $message = sprintf(__('Download and activate the WP-Stateless addon for %s to ensure compatibility.', ud_get_stateless_media()->domain), $title); if ( isset($addon['activate_link']) ) { $button = __('Activate Addon', ud_get_stateless_media()->domain); $button_link = $addon['activate_link']; $message = sprintf(__('Activate the WP-Stateless addon for %s to ensure compatibility.', ud_get_stateless_media()->domain), $title); } $plugin_activate_url = wp_nonce_url( 'plugins.php?action=activate&plugin=classic-widgets/classic-widgets.php', 'activate-plugin_classic-widgets/classic-widgets.php' ); ud_get_stateless_media()->errors->add([ 'key' => $id, 'title' => sprintf(__('WP-Stateless: Install the %s Addon', ud_get_stateless_media()->domain), $title), 'button' => $button, 'button_link' => $button_link, 'message' => $message, ], 'notice'); } } /** * Outputs 'Addons' tab content on the settings page. * */ public function tab_content() { // Prepare filters $current_filter = isset($_GET['filter']) && !empty($_GET['filter']) ? $_GET['filter'] : 'all'; $url = ud_get_stateless_media()->get_settings_page_url('?page=stateless-settings') . '&tab=stless_addons_tab&filter=%s'; $filters = [ 'all' => [ 'title' => __('All (%d)', ud_get_stateless_media()->domain), 'count' => count($this->addons), ], 'recommended' => [ 'title' => __('Recommended (%d)', ud_get_stateless_media()->domain), 'count' => $this->recommended, ], 'active' => [ 'title' => __('Active (%d)', ud_get_stateless_media()->domain), 'count' => $this->active, ], 'inactive' => [ 'title' => __('Inactive (%d)', ud_get_stateless_media()->domain), 'count' => count($this->addons) - $this->active, ], ]; $filters = Helper::array_of_objects($filters); // Filter addons switch ($current_filter) { case 'recommended': $addons = array_filter($this->addons, function($addon) { return isset($addon['recommended']); }); break; case 'active': $addons = array_filter($this->addons, function($addon) { return isset($addon['active']); }); break; case 'inactive': $addons = array_filter($this->addons, function($addon) { return !isset($addon['active']); }); break; default: $addons = $this->addons; break; } $addons = $this->sort_addons($addons); $addons = $this->get_addons_view($addons); $addons = Helper::array_of_objects($addons); include ud_get_stateless_media()->path('static/views/addons-tab.php', 'dir'); } /** * Prepare addon data for output. * * @param array $addons * @return array */ private function get_addons_view($addons) { $plugin_desc = __('Provides compatibility between the %s and the WP-Stateless plugins.', ud_get_stateless_media()->domain); $theme_desc = __('Provides compatibility between the %s theme and the WP-Stateless plugin.', ud_get_stateless_media()->domain); $link = ud_get_stateless_media()->get_docs_page_url('addons/%s'); $defaults = [ 'title' => '', 'icon' => '', 'description' => '', 'recommended' => false, 'active' => false, 'installed' => false, 'activate_link' => '', 'hubspot_id' => '', 'hubspot_link' => '', 'repo' => '', 'docs' => '', 'link' => '', 'wp' => '', 'card_class' => '', 'status' => '', ]; foreach ($addons as $id => $addon) { if ( isset($addon['theme_name']) ) { $addon['description'] = sprintf($theme_desc, $addon['title']); } else { $addon['description'] = sprintf($plugin_desc, $addon['title']); } if ( isset($addon['active']) && $addon['active']) { $addon['card_class'] = 'active'; $addon['status'] = __('active', ud_get_stateless_media()->domain); } elseif ( isset($addon['recommended']) && $addon['recommended']) { $addon['card_class'] = 'recommended'; $addon['status'] = __('recommended', ud_get_stateless_media()->domain); } $addon['docs'] = sprintf($link, $id); $addon['link'] = $addon['docs']; $addons[$id] = wp_parse_args($addon, $defaults); } return $addons; } /** * Sort addons: * - recommended not active * - other * - active * * @param array $addons * @return array */ private function sort_addons($addons) { uasort($addons, function($a1, $a2) { $c1 = isset($a1['recommended']) ? -1 : 0; $c1 += isset($a1['active']) ? 5 : 0; $c2 = isset($a2['recommended']) ? -1 : 0; $c2 += isset($a2['active']) ? 5 : 0; if ( $c1 !== $c2 ) { return $c1 > $c2 ? 1 : -1; } return strcasecmp( $a1['title'], $a2['title'] ); }); return $addons; } /** * Check if 'Addons' tab should be visible. */ public function addons_tab_visible($visible) { return count($this->addons) > 0; } /** * Restrict internal compatibility. */ public function restrict_compatibility($restrict, $id, $is_internal) { // If we have a plugin with the same ID as internal compatibility then disable internal compatibility if ($is_internal) { if ( in_array($id, $this->addon_ids) ) { return true; } } return $restrict; } /** * Get the root for saving addons files. * In Stateless Mode this will be the root of the bucket. * In other modes this will be the uploads base directory. */ public function get_addon_files_root($root_path) { if ( ud_get_stateless_media()->is_mode('stateless') ) { $root_path = ud_get_stateless_media()->get_gs_path(); } else { $upload_dir = wp_get_upload_dir(); $root_path = $upload_dir['basedir']; } return $root_path; } /** * Get the root path for syncing addons files. * In Stateless and Ephemeral Modes this will be the root of the bucket. * In other modes this will be the uploads base directory. */ public function get_addon_sync_files_path($root_path, $addon_folder = '') { if ( ud_get_stateless_media()->is_mode( ['stateless', 'ephemeral'] ) ) { $root_path = ud_get_stateless_media()->get_gs_path(); } else { $upload_dir = wp_get_upload_dir(); $root_path = $upload_dir['basedir']; } if ( !empty($addon_folder) ) { $root_path = [ rtrim($root_path, '/'), ltrim($addon_folder, '/'), ]; $root_path = implode('/', $root_path); } return $root_path; } /** * Get the root path for syncing addons files. * In Stateless and Ephemeral Modes this will be the root of the bucket. * In other modes this will be the uploads base directory. */ public function get_addon_files_url($root_url, $addon_folder = '') { $root_url = ''; if ( ud_get_stateless_media()->is_mode( ['disabled', 'backup'] ) ) { $upload_dir = wp_get_upload_dir(); $root_url = $upload_dir['baseurl']; } else { $root_url = ud_get_stateless_media()->get_gs_host(); } if ( !empty($addon_folder) ) { $root_url = [ rtrim($root_url, '/'), ltrim($addon_folder, '/'), ]; $root_url = implode('/', $root_url); } return $root_url; } } } ================================================ FILE: lib/classes/class-ajax.php ================================================ actions as $action) { add_action('wp_ajax_' . $action, array($this, 'request')); } foreach ($this->nopriv_actions as $action) { add_action('wp_ajax_nopriv_' . $action, array($this, 'request')); } } /** * Handles AJAX request * * @author peshkov@UD */ public function request() { check_ajax_referer('sm_inline_sync'); if ( !is_user_logged_in() ) { wp_send_json_error( array( 'error' => __( 'You are not allowed to do this action.', ud_get_stateless_media()->domain ) ) ); } global $doing_manual_sync; $response = array( 'message' => '', 'html' => '', ); try { $doing_manual_sync = true; $action = $_REQUEST['action']; /** Determine if the current class has the method to handle request */ if (is_callable(array($this, 'action_' . $action))) { $response = call_user_func_array(array($this, 'action_' . $action), array($_REQUEST)); } /** Determine if external function exists to handle request */ elseif (is_callable('action_' . $action)) { $response = call_user_func_array($action, array($_REQUEST)); } elseif (is_callable($action)) { $response = call_user_func_array($action, array($_REQUEST)); } /** Oops! */ else { throw new \Exception(__('Incorrect Request')); } } catch (\Exception $e) { wp_send_json_error($e->getMessage()); } wp_send_json_success($response); } /** * Regenerate image sizes. */ public function action_stateless_process_image() { set_time_limit(0); $image = Utility::process_image_by_id(intval($_REQUEST['id'])); return sprintf(__('%1$s (ID %2$s) was successfully synced in %3$s seconds.', ud_get_stateless_media()->domain), esc_html(get_the_title($image->ID)), $image->ID, timer_stop()); } /** * @return string * @throws \Exception */ public function action_stateless_process_file() { set_time_limit(0); $file = Utility::process_file_by_id(intval($_REQUEST['id'])); return sprintf(__('%1$s (ID %2$s) was successfully synchronised in %3$s seconds.', ud_get_stateless_media()->domain), esc_html(get_the_title($file->ID)), $file->ID, timer_stop()); } /** * Returns bucket folder (to check whether there is something to continue in JS) */ public function action_stateless_get_bucket_folder() { return array('bucket_folder' => get_option('sm_root_dir')); } } } } ================================================ FILE: lib/classes/class-api.php ================================================ get_header('authorization'); // Allow using custom `x-wps-auth` header if authorization hedaer is disabled if (!$auth_token) $auth_token = $request->get_header('x-wps-auth'); if (!$auth_token) return false; try { self::$tokenData = Utility::verify_jwt_token($auth_token); } catch (\Exception $e) { self::$tokenData = null; return new \WP_Error('auth_failed', $e->getMessage(), ['status' => 401]); } return true; } /** * API Status Endpoint. * * @return \WP_REST_Response */ static public function status() { return new \WP_REST_Response(array( "ok" => true, "message" => "API up." ), 200); } /** * Get settings * * @todo Implement this if needed * @param \WP_REST_Request $request * @return \WP_REST_Response|\WP_Error */ static public function getSettings(\WP_REST_Request $request) { return new \WP_Error('not_implemented', 'Method not implemented', ['status' => 501]); } /** * Update settings * * @param \WP_REST_Request $request * @return \WP_REST_Response|\WP_Error */ static public function updateSettings(\WP_REST_Request $request) { if (self::$tokenData === null || empty(self::$tokenData->user_id)) { return new \WP_Error('unauthorized', 'Auth token looks incorrect', ['status' => 401]); } $is_gae = apply_filters('wp_stateless_is_app_engine', false); $upload_dir = wp_upload_dir(); $is_upload_dir_writable = is_writable($upload_dir['basedir']); try { $queryParams = $request->get_json_params(); if (empty($queryParams)) throw new \Exception('Query is empty'); $bucketName = isset($queryParams['bucket_name']) ? $queryParams['bucket_name'] : null; $privateKeyData = isset($queryParams['private_key_data']) ? $queryParams['private_key_data'] : null; if (!$bucketName || !$privateKeyData) { throw new \Exception('bucket_name and private_key_data are required'); } if ($privateKeyData) { $privateKeyData = base64_decode($privateKeyData); } switch (self::$tokenData->is_network) { case true: if (!user_can(self::$tokenData->user_id, 'manage_network_options')) { return new \WP_Error('not_allowed', 'Sorry, you are not allowed to perform this action', ['status' => 403]); } /** * If Google App Engine detected - set Stateless mode * and Google App Engine compatibility by default */ if ($is_gae || !$is_upload_dir_writable) { update_site_option('sm_mode', 'stateless'); $modules = get_site_option('stateless-modules', array()); if ($is_gae && empty($modules['google-app-engine']) || $modules['google-app-engine'] != 'true') { $modules['google-app-engine'] = 'true'; update_site_option('stateless-modules', $modules); } } elseif (get_site_option('sm_mode', 'disabled') == 'disabled') { update_site_option('sm_mode', 'ephemeral'); } update_site_option('sm_bucket', $bucketName); update_site_option('sm_key_json', $privateKeyData); break; case false: if (!user_can(self::$tokenData->user_id, 'manage_options')) { return new \WP_Error('not_allowed', 'Sorry, you are not allowed to perform this action', ['status' => 403]); } /** * If Google App Engine detected - set Stateless mode * and Google App Engine compatibility by default */ if ($is_gae || !$is_upload_dir_writable) { update_option('sm_mode', 'stateless'); $modules = get_option('stateless-modules', array()); if ($is_gae && empty($modules['google-app-engine']) || $modules['google-app-engine'] != 'true') { $modules['google-app-engine'] = 'true'; update_option('stateless-modules', $modules); } } elseif (get_option('sm_mode', 'disabled') == 'disabled') { update_option('sm_mode', 'ephemeral'); } update_option('sm_bucket', $bucketName); update_option('sm_key_json', $privateKeyData); break; } return new \WP_REST_Response(array( 'ok' => true, 'message' => 'Settings updated successfully' )); } catch (\Throwable $e) { return new \WP_Error('internal_server_error', $e->getMessage(), ['status' => 500]); } } /** * Get all available processes with their states * * @return \WP_REST_Response|\WP_Error */ static public function syncGetProcesses() { try { if (!user_can(self::$tokenData->user_id, 'manage_options')) { return new \WP_Error('not_allowed', 'Sorry, you are not allowed to perform this action', ['status' => 403]); } return new \WP_REST_Response(array( 'ok' => true, 'data' => Utility::get_available_sync_classes() )); } catch (\Throwable $e) { return new \WP_Error('internal_server_error', $e->getMessage(), ['status' => 500]); } } /** * Get a single process by id (base64 encoded class name) * * @param \WP_REST_Request $request * @return \WP_Error|\WP_REST_Response */ static public function syncGetProcess(\WP_REST_Request $request) { try { if (!user_can(self::$tokenData->user_id, 'manage_options')) { return new \WP_Error('not_allowed', 'Sorry, you are not allowed to perform this action', ['status' => 403]); } $id = base64_decode($request->get_param('id')); if (!class_exists($id)) { throw new \Exception(sprintf('Could not get process by id %s', $id)); } $syncClasses = Utility::get_available_sync_classes(); if (!array_key_exists($id, $syncClasses)) { throw new \Exception(sprintf('Could not get process by id %s', $id)); } return new \WP_REST_Response(array( 'ok' => true, 'data' => $syncClasses[$id] )); } catch (\Throwable $e) { return new \WP_Error('internal_server_error', $e->getMessage(), ['status' => 500]); } } /** * Run sync by processing class id * * @param \WP_REST_Request $request * @return \WP_Error|\WP_REST_Response */ static public function syncRun(\WP_REST_Request $request) { try { if (!user_can(self::$tokenData->user_id, 'manage_options')) { return new \WP_Error('not_allowed', 'Sorry, you are not allowed to perform this action', ['status' => 403]); } $params = wp_parse_args($request->get_params(), [ 'id' => null, 'limit' => null, 'order' => null, ]); if (empty($params['id']) || !class_exists($params['id'])) { throw new \Exception(sprintf('Processing class not found: %s', $params['id'])); } $processingClass = $params['id']; return new \WP_REST_Response(array( 'ok' => $processingClass::instance()->start($params) )); } catch (\Throwable $e) { return new \WP_Error('internal_server_error', $e->getMessage(), ['status' => 500]); } } /** * Stop sync by processing class id * * @param \WP_REST_Request $request * @return \WP_Error|\WP_REST_Response */ static public function syncStop(\WP_REST_Request $request) { try { if (!user_can(self::$tokenData->user_id, 'manage_options')) { return new \WP_Error('not_allowed', 'Sorry, you are not allowed to perform this action', ['status' => 403]); } $params = wp_parse_args($request->get_params(), [ 'id' => null ]); if (empty($params['id']) || !class_exists($params['id'])) { throw new \Exception(sprintf('Processing class not found: %s', $params['id'])); } $processingClass = $params['id']; return new \WP_REST_Response(array( 'ok' => $processingClass::instance()->stop() )); } catch (\Throwable $e) { return new \WP_Error('internal_server_error', $e->getMessage(), ['status' => 500]); } } /** * Batch Status Endpoint. * * @param \WP_REST_Request $request * @return \WP_REST_Response */ static public function batchState(\WP_REST_Request $request) { try { return new \WP_REST_Response(array( 'ok' => true, 'data' => apply_filters('wp_stateless_batch_state', [], $request->get_params()), )); } catch (\Throwable $e) { return new \WP_Error('internal_server_error', $e->getMessage(), ['status' => 500]); } } /** * Batch action (start/pause/resume) * * @param \WP_REST_Request $request * @return \WP_Error|\WP_REST_Response */ static public function batchAction(\WP_REST_Request $request) { try { if (!user_can(self::$tokenData->user_id, 'manage_options')) { return new \WP_Error('not_allowed', 'Sorry, you are not allowed to perform this action', ['status' => 403]); } wp_set_current_user(self::$tokenData->user_id); $params = wp_parse_args($request->get_params(), [ 'action' => '', ]); if ( empty($params['action']) ) { throw new \Exception('Batch action not set'); } $action = $params['action']; $data = apply_filters("wp_stateless_batch_action_$action", [], $params); $data = array_merge( $data, apply_filters("wp_stateless_batch_state", [], ['force_migrations' => true]), ); return new \WP_REST_Response(array( 'data' => $data, )); } catch (\Throwable $e) { return new \WP_Error('internal_server_error', $e->getMessage(), ['status' => 500]); } } } } } ================================================ FILE: lib/classes/class-bootstrap.php ================================================ get_client() * * @var \wpCloud\StatelessMedia\GS_CLient */ private $client; /** * Plugin core version. * * @static * @property $version * @type {Object} */ public static $version = '3.0'; /** * Singleton Instance Reference. * * @protected * @static * @property $instance * @type \wpCloud\StatelessMedia\Bootstrap object */ protected static $instance = null; /** * Constructor * Attention: MUST NOT BE CALLED DIRECTLY! USE get_instance() INSTEAD! * @param $args * @author peshkov@UD */ protected function __construct($args) { /** * Need to be loaded before plugin initialization. */ if ( !(defined('WP_STATELESS_COMPATIBILITY_GAE') && !WP_STATELESS_COMPATIBILITY_GAE) ) { AppEngine::instance(); } parent::__construct($args); self::$version = $args['version'] ?? self::$version; /** * Add custom args to api ping request */ add_filter('ud-api-client-ping-args', function ($args, $_, $__) { $args['multisite'] = is_multisite(); $args['stateless_media'] = Utility::get_stateless_media_data_count(); return $args; }, 10, 3); //** Define our Admin Notices handler object */ $this->errors = new Errors(array_merge($args, array( 'type' => $this->type ))); // Initialize compatibility modules. add_action('plugins_loaded', function () { Addons::instance(); new Module(); DynamicImageSupport::instance(); }, 20); /** * Define settings and UI. * * Example: * * Get option * $this->get( 'sm.client_id' ) * * Manually Update/Add option * $this->set( 'sm.client_id', 'zxcvv12adffse' ); */ $this->settings = new Settings($this); Status::instance(); } /** * Prevent loading of textdomain */ public function load_textdomain() { } /** * Instantiate class. */ public function init() { // Parse feature flags, set constants. $this->parse_feature_flags(); $sm_mode = $this->get('sm.mode'); /** * Send admin email */ add_action('wp_stateless_send_admin_email', array($this, 'send_admin_email'), 10, 3); // Should be created unconditionally and as early as possible to handle batch migration requests Migrator::instance(); BatchTaskManager::instance(); new SyncNonMedia(); ImageSync::instance(); FileSync::instance(); NonLibrarySync::instance(); // Invoke REST API add_action('rest_api_init', array($this, 'api_init')); // Register meta boxes and fields for media edit page add_filter('rwmb_meta_boxes', array($this, 'attachment_meta_box_callback')); // Register meta boxes and fields for media modal page add_filter('attachment_fields_to_edit', array($this, 'attachment_modal_meta_box_callback'), 11, 2); // Get the REST API root add_filter('wp_stateless_rest_api_root', array($this, 'get_rest_api_root')); /** * Init hook */ add_action('admin_init', array($this, 'admin_init')); /** * Handle switch blog properly. */ add_action('switch_blog', array($this, 'on_switch_blog'), 10, 2); /** * Filter for getting stateless settings */ add_filter('stateless::get_settings', array($this, 'get_settings'), 10); /** * Init AJAX jobs */ new Ajax(); /** * Load WP-CLI Commands */ if (defined('WP_CLI') && WP_CLI) { include_once($this->path('lib/cli/class-sm-cli-command.php', 'dir')); } /** * Add scripts */ add_action('admin_enqueue_scripts', array($this, 'admin_enqueue_scripts')); /** * Delete table when blog is deleted. */ add_action('wp_delete_site', array($this, 'wp_delete_site')); /** * To prevent fatal errors for users who use PHP 5.5 or less. */ if (version_compare(PHP_VERSION, self::REQUIRED_PHP_VERSION, '<')) { $this->errors->add(sprintf(__('The plugin requires PHP %s or higher. You current PHP version %s is too old.', ud_get_stateless_media()->domain), '' . self::REQUIRED_PHP_VERSION . '', '' . PHP_VERSION . '')); } /** * Add the currently processing nag */ foreach (Utility::get_available_sync_classes() as $process) { if ($process->is_running()) { $this->errors->add([ 'title' => __('Media Library Synchronization Underway', ud_get_stateless_media()->domain), 'message' => __('WP-Stateless is synchronizing your media library in accordance with the Mode setting. You can view progress or stop the process via the WP-Stateless Sync settings area.', ud_get_stateless_media()->domain), 'button' => __('View Synchronization', ud_get_stateless_media()->domain), 'button_link' => admin_url('upload.php?page=stateless-settings&tab=stless_sync_tab'), 'key' => 'processing-in-progress' ], 'message'); break; } } /* Initialize plugin only if Mode is not 'disabled'. */ if (($sm_mode !== 'disabled' && $sm_mode !== 'stateless') || ($sm_mode === 'stateless' && (wp_doing_ajax() || wp_doing_cron()))) { /** * Determine if we have issues with connection to Google Storage Bucket * if SM is not disabled. */ $is_connected = $this->is_connected_to_gs(); if (is_wp_error($is_connected)) { $this->errors->add($is_connected->get_error_message(), 'warning', false); } if ($googleSDKVersionConflictError = get_transient("wp_stateless_google_sdk_conflict")) { $this->errors->add($googleSDKVersionConflictError, 'warning', false); } /** * Carry on only if we do not have errors. */ if (!$this->has_errors()) { if (in_array($sm_mode, array('cdn', 'ephemeral', 'stateless'))) { /** * init main filters */ $this->_init_filters('main'); } if ($sm_mode === 'ephemeral' || $sm_mode === 'stateless') { // Store attachment id in a static variable on 'intermediate_image_sizes_advanced' filter. // Utility::store_can_delete_attachment(); if (function_exists('is_wp_version_compatible') && is_wp_version_compatible('5.3-RC4-46673')) { add_filter('intermediate_image_sizes_advanced', array('wpCloud\StatelessMedia\Utility', 'store_can_delete_attachment'), 10, 3); } } if ($sm_mode === 'stateless') { /** * Replacing local path to gs:// for using it on StreamWrapper */ add_filter('upload_dir', array($this, 'filter_upload_dir'), 99); /** * Stateless mode working only with GD library */ add_filter('wp_image_editors', array($this, 'select_wp_image_editors')); /** * Init GS client */ global $gs_client; if ($gs_client = $this->init_gs_client()) { StreamWrapper::register($gs_client); } } if ($this->get('sm.delete_remote') == 'true') { /** * On physical file deletion we remove any from GS * We need priority grater than default (10) for ShortPixel plugin to work properly. */ add_filter('delete_attachment', array($this, 'remove_media'), 11); } /** * init client's filters */ $this->_init_filters('client'); } } elseif ($sm_mode == 'stateless') { /** * Determine if we have issues with connection to Google Storage Bucket * if SM is not disabled. */ $is_connected = $this->is_connected_to_gs(); if (is_wp_error($is_connected)) { $this->errors->add($is_connected->get_error_message(), 'warning', false); } if ($googleSDKVersionConflictError = get_transient("wp_stateless_google_sdk_conflict")) { $this->errors->add($googleSDKVersionConflictError, 'warning', false); } /** * Carry on only if we do not have errors. */ if (!$this->has_errors()) { /** * Replacing local path to gs:// for using it on StreamWrapper */ add_filter('upload_dir', array($this, 'filter_upload_dir'), 99); /** * Stateless mode working only with GD library */ add_filter('wp_image_editors', array($this, 'select_wp_image_editors')); /** * Init GS client */ global $gs_client; if ($gs_client = $this->init_gs_client()) { StreamWrapper::register($gs_client); } /** * init client's filters */ $this->_init_filters('client'); /** * init main filters */ $this->_init_filters('main'); } } } /** * Init additional filters which uses on all modes * @param string $type */ private function _init_filters($type = '') { switch ($type) { case 'main': add_filter('wp_get_attachment_image_attributes', array($this, 'wp_get_attachment_image_attributes'), 20, 3); add_filter('wp_get_attachment_url', array($this, 'wp_get_attachment_url'), 20, 2); add_filter('get_attached_file', array($this, 'get_attached_file'), 9, 2); add_filter('attachment_url_to_postid', array($this, 'attachment_url_to_postid'), 20, 2); if ($this->get('sm.body_rewrite') == 'true' || $this->get('sm.body_rewrite') == 'enable_editor') { add_filter('the_content', array($this, 'the_content_filter'), 99); } if ($this->get('sm.body_rewrite') == 'true' || $this->get('sm.body_rewrite') == 'enable_meta') { add_filter('get_post_metadata', array($this, 'post_metadata_filter'), 2, 4); } add_filter('wp_stateless_bucket_link', array($this, 'wp_stateless_bucket_link')); break; case 'client': /** * Add custom actions to media rows */ add_filter('media_row_actions', array($this, 'add_custom_row_actions'), 10, 3); /** * Hashify file name if option is enabled */ if ($this->get('sm.hashify_file_name') == 'true') { add_filter('sanitize_file_name', array('wpCloud\StatelessMedia\Utility', 'randomize_filename'), 10); } /** * Override Cache Control if option is enabled */ add_filter('sm:item:cacheControl', array($this->settings, 'override_cache_control')); add_filter('wp_stateless_file_name', array($this, 'handle_root_dir'), 10, 4); /** * Extends metadata by adding GS information. */ add_filter('wp_get_attachment_metadata', array($this, 'wp_get_attachment_metadata'), 10, 2); /** * Add/Edit Media * * Once added or edited we can get into Attachment ID then get all image sizes and sync them with GS * We can't use this. That's prevent removing this filter. */ add_filter('wp_update_attachment_metadata', array('wpCloud\StatelessMedia\Utility', 'add_media'), 999, 2); /** * Delete original in the end of generating metadata * it does not work with PDF */ // add_filter('wp_generate_attachment_metadata', function ($metadata, $attachment_id, $state) { // if (!in_array(ud_get_stateless_media()->get('sm.mode'), array('ephemeral'))) return $metadata; // @unlink(get_attached_file($attachment_id, true)); // return $metadata; // }, 99, 3); /** * Rewrite Image URLS */ add_filter('image_downsize', array($this, 'image_downsize'), 99, 3); add_filter('wp_calculate_image_srcset', array($this, 'wp_calculate_image_srcset'), 10, 5); /** * Trigger module initialization and registration. */ do_action('sm::module::init', $this->get('sm')); break; case 'default': break; } } /** * The default $editors value: * * array( 'WP_Image_Editor_Imagick', 'WP_Image_Editor_GD' ) * @param $editors * @return array */ public function select_wp_image_editors($editors) { return array('WP_Image_Editor_GD'); } /** * @param callable|null $httpHandler * @return StorageClient * @throws \Exception */ public function init_gs_client(?callable $httpHandler = null) { // May be Loading Google SDK.... if (!class_exists('HttpHandlerFactory')) { include_once(ud_get_stateless_media()->path('lib/Google/vendor/autoload.php', 'dir')); } $httpHandler = $httpHandler ? $httpHandler : HttpHandlerFactory::build(); $json_key = json_decode($this->settings->get('sm.key_json'), true); if (!empty($json_key)) { return new StorageClient( [ 'keyFile' => $json_key, 'httpHandler' => function ($request, $options) use ($httpHandler) { $xGoogApiClientHeader = $request->getHeaderLine('x-goog-api-client'); $request = $request->withHeader('x-goog-api-client', $xGoogApiClientHeader); return call_user_func_array($httpHandler, [$request, $options]); }, 'authHttpHandler' => HttpHandlerFactory::build(), ] ); } } /** * Replacing root dir with GCS path * @param $uploads * @return array */ public function filter_upload_dir($uploads) { global $default_dir; if ($default_dir) return $uploads; //Bucket $bucket = $this->get('sm.bucket'); //Bucket folder path $root_dir = $this->get('sm.root_dir'); $root_dir = apply_filters("wp_stateless_handle_root_dir", $root_dir); /** * Subdir not uses on Stateless mode */ $uploads['subdir'] = ''; $basedir = rtrim(sprintf('gs://%s/%s', $bucket, $root_dir), '/'); $baseurl = rtrim(sprintf('https://storage.googleapis.com/%s/%s', $bucket, $root_dir), '/'); $uploads = array( 'url' => rtrim($baseurl . $uploads['subdir'], '/'), 'path' => $basedir . $uploads['subdir'], 'subdir' => $uploads['subdir'], 'basedir' => $basedir, 'baseurl' => $baseurl, 'error' => false, ); return $uploads; } /** * Rebuild srcset from gs_link. * Using calculations returned from WordPress wp_calculate_image_srcset() * * @param $sources * @param $size_array * @param $image_src * @param $image_meta * @param $attachment_id * @return array */ public function wp_calculate_image_srcset($sources, $size_array, $image_src, $image_meta, $attachment_id) { $sm_mode = $this->get('sm.mode'); /** * In Backup mode using local URL */ if ("backup" == $sm_mode) { return $sources; } if (empty($image_meta['gs_link'])) { $image_meta = wp_get_attachment_metadata($attachment_id); } if (is_array($sources) && !empty($image_meta['gs_link'])) { $gs_name = $image_meta['gs_name']; // getting position of root_dir in gs_name. $root_dir_pos = strpos($gs_name, $image_meta['file']); // removing rood_dir from gs_name so we can compare to replace url with gs_link. if ($root_dir_pos !== false) { $gs_name = substr($gs_name, $root_dir_pos); } if (!isset($gs_name) || empty($gs_name)) { return []; } foreach ($sources as $width => &$image) { // If srcset includes original image src, replace it if (substr_compare($image['url'], $gs_name, -strlen($gs_name)) === 0) { $image['url'] = $image_meta['gs_link']; // Replace all sizes } elseif (isset($image_meta['sizes']) && is_array($image_meta['sizes'])) { $found = false; foreach ($image_meta['sizes'] as $key => $meta) { if (!isset($meta['gs_name']) || empty($meta['gs_name'])) { continue; } $thumb_gs_name = $meta['gs_name']; // removing rood_dir from gs_name if ($root_dir_pos !== false) { $thumb_gs_name = substr($thumb_gs_name, $root_dir_pos); } if (substr_compare($image['url'], $thumb_gs_name, -strlen($thumb_gs_name)) === 0) { $image['url'] = $meta['gs_link']; $found = true; break; } } // if no size found and mode is ephemeral or stateless and nothing to show for srcset item - unset that item if (!$found && ($sm_mode === 'ephemeral' || $sm_mode === 'stateless')) { $image = null; } } else { // if mode is stateless and nothing to show for srcset item - unset that item if ($sm_mode === 'ephemeral' || $sm_mode === 'stateless') { $image = null; } } } } elseif (is_array($sources) && $sm_mode === 'stateless') { foreach ($sources as $width => &$image) { // Set default src $image['url'] = $image_src; } } return is_array($sources) ? array_filter($sources) : $sources; } /** * Return gs host. * If custom domain is set it's return bucket name as host, * else return storage.googleapis.com as host and append bucket name at the end. * * @param array $sm * @return mixed|void */ public function get_gs_host($sm = array()) { $sm = $sm ? $sm : $this->get('sm'); $image_host = 'https://storage.googleapis.com/'; $image_host .= $sm['bucket']; $custom_domain = $sm['custom_domain']; $is_ssl = strpos($custom_domain, 'https://'); $custom_domain = str_replace(array('http://', 'https://'), '', $custom_domain); $custom_domain = trim($custom_domain, '/'); // checking whether the provided domain is valid. // if the custom domain is same as the bucket name // or the custom domain is using https. if (!empty($sm['bucket']) && !empty($custom_domain) && $custom_domain !== 'storage.googleapis.com' && ($is_ssl === 0 || $custom_domain == $sm['bucket'])) { $image_host = $is_ssl === 0 ? 'https://' : 'http://'; // bucketname will be host $image_host .= $custom_domain; } return apply_filters('get_gs_host', $image_host, $image_host, $sm['bucket'], $is_ssl, $sm); } /** * Return gs:// path. * * @param array $sm * @return mixed|void */ public function get_gs_path() { $path = 'gs://' . $this->get('sm.bucket'); return apply_filters('get_gs_path', $path); } /** * Filter for wp_stateless_bucket_link if custom domain is set. * It's get attachment url and remove "storage.googleapis.com" from url. * So that custom url can be used. * * @param $fileLink * @return mixed|string */ public function wp_stateless_bucket_link($fileLink) { $bucketname = $this->get('sm.bucket'); $custom_domain = $this->get('sm.custom_domain'); $is_ssl = strpos($custom_domain, 'https://') === 0; $fileLink_is_ssl = strpos($fileLink, 'https://') === 0; $custom_domain = str_replace(array('http://', 'https://'), '', $custom_domain); $custom_domain = trim($custom_domain, '/'); if (!empty($bucketname) && $custom_domain !== 'storage.googleapis.com' && $custom_domain == $bucketname && strpos($fileLink, $bucketname) > 8) { $fileLink = ($is_ssl ? 'https://' : 'http://') . substr($fileLink, strpos($fileLink, $bucketname)); } elseif ($custom_domain !== 'storage.googleapis.com' && $custom_domain == $bucketname && $fileLink_is_ssl !== $is_ssl) { if ($is_ssl) $fileLink = str_replace(array('http://', 'https://'), 'https://', $fileLink); else $fileLink = str_replace(array('http://', 'https://'), 'http://', $fileLink); } return $fileLink; } /** * Return settings page url. * * @param string $path * @return string */ public function get_settings_page_url($path = '') { $url = get_admin_url(get_current_blog_id(), (is_network_admin() ? 'network/settings.php' : 'upload.php')); return $url . $path; } /** * Return docs page url. * * @param string $path * @return string */ public function get_docs_page_url($path = '') { $path = ltrim($path, '/'); return 'https://stateless.udx.io/' . $path; } /** * Get new blog settings once switched blog. * @param $new_blog * @param $prev_blog_id */ public function on_switch_blog($new_blog, $prev_blog_id) { $this->settings->refresh(); } /** * Get settings handler. * Filling array if some settings missing. * * @param $settings * @return */ public function get_settings($settings) { $settings_list = array( 'mode', 'body_rewrite', 'body_rewrite_types', 'bucket', 'root_dir', 'key_json', 'cache_control', 'delete_remote', 'custom_domain', 'organize_media', 'hashify_file_name' ); foreach ($settings_list as $setting) { /** If setting is already exist, just skip it */ if (isset($settings[$setting])) { continue; } $value = $this->get('sm.' . $setting); /** Decode json to array */ if ($value && is_string($value) && $setting === 'key_json') { $value = json_decode($value, true); $setting = 'key'; } $settings[$setting] = $value; } return $settings; } /** * Remove all settings. * @param bool $network */ public function reset($network = false) { $this->settings->reset($network); } /** * @param $actions * @param $post * @param $detached * @return mixed */ public function add_custom_row_actions($actions, $post, $detached) { if (!current_user_can('upload_files')) return $actions; $sm_cloud = apply_filters('wp_stateless_get_file', [], $post->ID); $sm_mode = $this->get('sm.mode'); if (!empty($sm_cloud) && $sm_mode === 'stateless') return $actions; if ($post && 'attachment' == $post->post_type && 'image/' == substr($post->post_mime_type, 0, 6)) { $actions['sm_sync'] = '' . __('Regenerate and Sync with GCS', ud_get_stateless_media()->domain) . ''; } if ($post && 'attachment' == $post->post_type && 'image/' != substr($post->post_mime_type, 0, 6)) { $actions['sm_sync'] = '' . __('Sync with GCS', ud_get_stateless_media()->domain) . ''; } return $actions; } /** * Define REST API. * * @author korotkov@UD */ public function api_init() { $route_namespace = 'wp-stateless/v1'; $api_namespace = 'wpCloud\StatelessMedia\API'; register_rest_route($route_namespace, '/status', array( 'methods' => \WP_REST_Server::READABLE, 'callback' => array($api_namespace, 'status'), 'permission_callback' => '__return_true' )); register_rest_route($route_namespace, '/getSettings', array( 'methods' => \WP_REST_Server::READABLE, 'callback' => array($api_namespace, 'getSettings'), 'permission_callback' => array($api_namespace, 'authCheck') )); register_rest_route($route_namespace, '/updateSettings', array( 'methods' => \WP_REST_Server::CREATABLE, 'callback' => array($api_namespace, 'updateSettings'), 'permission_callback' => array($api_namespace, 'authCheck') )); register_rest_route($route_namespace, '/sync/getProcesses', array( 'methods' => \WP_REST_Server::READABLE, 'callback' => array($api_namespace, 'syncGetProcesses'), 'permission_callback' => array($api_namespace, 'authCheck') )); register_rest_route($route_namespace, '/sync/getProcess/(?P\S+)', array( 'methods' => \WP_REST_Server::READABLE, 'callback' => array($api_namespace, 'syncGetProcess'), 'permission_callback' => array($api_namespace, 'authCheck') )); register_rest_route($route_namespace, '/sync/run', array( 'methods' => \WP_REST_Server::CREATABLE, 'callback' => array($api_namespace, 'syncRun'), 'permission_callback' => array($api_namespace, 'authCheck') )); register_rest_route($route_namespace, '/sync/stop', array( 'methods' => \WP_REST_Server::CREATABLE, 'callback' => array($api_namespace, 'syncStop'), 'permission_callback' => array($api_namespace, 'authCheck') )); register_rest_route($route_namespace, '/batch/state', array( 'methods' => \WP_REST_Server::READABLE, 'callback' => array($api_namespace, 'batchState'), 'permission_callback' => array($api_namespace, 'authCheck') )); register_rest_route($route_namespace, '/batch/action', array( 'methods' => \WP_REST_Server::CREATABLE, 'callback' => array($api_namespace, 'batchAction'), 'permission_callback' => array($api_namespace, 'authCheck') )); } /** * Metabox for media modal page * @param $form_fields * @param $post * @return array */ public function attachment_modal_meta_box_callback($form_fields, $post) { // Do not show on media edit page, only on modal // Do not show if we are not in Media Library if ( isset($_GET['post']) || wp_doing_ajax() ) { return $form_fields; } $link = get_edit_post_link($post->ID); $form_field['label'] = ''; $form_field['input'] = 'html'; $form_field['html'] = sprintf("", $link, __("View stateless meta", ud_get_stateless_media()->domain)); $form_field['show_in_modal'] = true; $form_fields['sm_html'] = $form_field; return $form_fields; } /** * Metabox for media edit page * @param $meta_boxes * @return array */ public function attachment_meta_box_callback($meta_boxes) { $post_id = false; if (isset($_GET['post'])) { $post_id = intval($_GET['post']); } elseif (isset($_POST['post_ID'])) { $post_id = intval($_POST['post_ID']); } elseif (isset($_GET['item'])) { $post_id = intval($_GET['item']); } elseif (isset($_POST['item'])) { $post_id = intval($_POST['item']); } return $this->_prepare_data_for_metabox($meta_boxes, $post_id); } /** * Prepare data for metabox fields * @param $meta_boxes * @param $post_id * @return array */ private function _prepare_data_for_metabox($meta_boxes, $post_id) { $post = get_post($post_id); $sm_cloud = apply_filters('wp_stateless_get_file', [], $post_id, true); $sm_mode = $this->get('sm.mode'); if (empty($post)) { return $meta_boxes; } $sizes = $this->get_image_sizes(); $fields = array(); if ($sm_mode !== 'stateless' || empty($sm_cloud)) { $fields[] = array( 'name' => __('Regenerate', ud_get_stateless_media()->domain), 'id' => 'storage_bucket_url', 'type' => 'custom_html', 'std' => $this->_prepare_generate_link($post, false, '', true, $sm_cloud), 'tab' => 'thumbnails', ); } if (is_array($sm_cloud) && !empty($sm_cloud['fileLink'])) { $fields[] = array( 'type' => 'heading', 'name' => 'Files', 'tab' => 'thumbnails', ); $fields[] = array( 'name' => __('Original', ud_get_stateless_media()->domain), 'id' => 'storage_bucket_url', 'type' => 'custom_html', 'media_modal' => true, 'std' => '', 'tab' => 'thumbnails', ); if (!empty($sm_cloud['sizes']) && is_array($sm_cloud['sizes'])) { foreach ($sm_cloud['sizes'] as $size_label => $size) { $fields[] = array( 'name' => __(sprintf("%s x %s", ($size['width'] ?: $sizes[$size_label]['width']), ($size['height'] ?: $sizes[$size_label]['height'])), ud_get_stateless_media()->domain), 'id' => 'storage_bucket_url' . $size_label, 'type' => 'custom_html', 'media_modal' => true, 'std' => '', 'tab' => 'thumbnails', ); } } if (!empty($sm_cloud['cacheControl'])) { $fields[] = array( 'name' => __('Cache Control', ud_get_stateless_media()->domain), 'id' => 'cache_control', 'type' => 'custom_html', 'std' => '', 'tab' => 'meta', ); } if (!empty($sm_cloud['bucket'])) { $fields[] = array( 'name' => __('Storage Bucket', ud_get_stateless_media()->domain), 'id' => 'storage_bukcet', 'type' => 'custom_html', 'std' => '', 'tab' => 'meta', ); } } $meta_boxes[] = apply_filters('sm::attachment::meta', array( 'id' => 'sm-attachment-metabox', 'title' => __('Stateless', ud_get_stateless_media()->domain), 'post_types' => 'attachment', //'media_modal' => true, //set context `side` for left column 'context' => 'normal', 'priority' => 'low', 'tabs' => array( 'thumbnails' => array( 'label' => __('Thumbnails', ud_get_stateless_media()->domain), 'icon' => 'dashicons-format-gallery', ), 'meta' => array( 'label' => __('Meta', ud_get_stateless_media()->domain), 'icon' => 'dashicons-admin-site', ), ), // Tab style: 'default', 'box' or 'left'. Optional 'tab_style' => 'left', // Show meta box wrapper around tabs? true (default) or false. Optional 'tab_wrapper' => true, 'fields' => $fields ), $post->ID); return $meta_boxes; } /** * Preparing link for sync * @param $post * @param bool $use_icon * @param string $size * @param bool $button * @param array $sm_cloud * @return string */ private function _prepare_generate_link($post, $use_icon = false, $size = '', $button = false, $sm_cloud = array()) { $sync = ''; $sm_mode = $this->get('sm.mode'); if (current_user_can('upload_files') && $sm_mode !== 'disabled' && ($sm_mode !== 'stateless' || empty($sm_cloud))) { if ($post && 'attachment' == $post->post_type && 'image/' == substr($post->post_mime_type, 0, 6)) { $sync = '' . ($use_icon ? "" : __('Regenerate and Sync with GCS', ud_get_stateless_media()->domain)) . ''; } if ($post && 'attachment' == $post->post_type && 'image/' != substr($post->post_mime_type, 0, 6)) { $sync = '' . ($use_icon ? "" : __('Sync with GCS', ud_get_stateless_media()->domain)) . ''; } } elseif ($button && $sm_mode !== 'stateless') { $sync = __('You do not have access to sync or Stateless mode is Disabled', ud_get_stateless_media()->domain); } return $sync; } /** * @param $current_path * @param $use_root boolean: whether to use the root dir or not. * 0 will be passed from various compatibilities so that the root dir is not used. * false will passed from some compatibilities to use the value as local path. * @param $attachment_id * @param $size * @return string */ public function handle_root_dir($current_path, $use_root = true, $attachment_id = '', $size = '') { //non media files if ($use_root === 0) { $non_media = ud_stateless_db()->get_non_library_file_name($current_path); if ($non_media) { return $non_media; } } $root_dir = $this->get('sm.root_dir'); $root_dir_regex = '~^' . apply_filters("wp_stateless_handle_root_dir", $root_dir, true) . '/~'; /** * Retrieve Y/M and other tags from current path */ $path_elements = apply_filters('wp_stateless_unhandle_root_dir', $current_path); $root_dir = apply_filters("wp_stateless_handle_root_dir", $root_dir, false, $path_elements); $upload_dir = wp_upload_dir(); $current_path = str_replace(wp_normalize_path(trailingslashit($upload_dir['basedir'])), '', wp_normalize_path($current_path)); $current_path = str_replace(wp_normalize_path(trailingslashit($upload_dir['baseurl'])), '', wp_normalize_path($current_path)); $current_path = str_replace(trailingslashit($this->get_gs_host()), '', $current_path); /** * Using only filename. Other parts of path included to $root_dir. * excluding compatibility. */ if ($use_root) { $current_path = basename($current_path); } if (!$use_root) { // removing the root dir if already exists in the beginning. $raw_name = preg_replace($root_dir_regex, '', $current_path); if ($raw_name && is_multisite() && ($blog_id = get_current_blog_id()) != 1) { $folder = "sites/{$blog_id}/"; if (strpos($raw_name, $folder) === 0) return $raw_name; return "$folder$raw_name"; } return $raw_name; } // skip adding root dir if it's already added. if (!empty($root_dir) && !preg_match($root_dir_regex, $current_path)) { return $root_dir . '/' . trim($current_path, '/ '); } return $current_path; } /** * @param $content * @return mixed */ public function the_content_filter($content) { if ($upload_data = wp_upload_dir()) { if (!empty($upload_data['url']) && !empty($content)) { $url = preg_replace('/https?:\/\//', '', $upload_data['url']); $root_dir = trim($this->get('sm.root_dir'), '/ '); // Remove any forward slash and empty space. $root_dir = apply_filters("wp_stateless_handle_root_dir", $root_dir); $root_dir = !empty($root_dir) ? $root_dir . '/' : false; $image_host = $this->get_gs_host(); $file_ext = $this->replaceable_file_types(); $content = preg_replace( '/(href|src)=(\'|")(https?:\/\/' . str_replace('/', '\/', $url) . ')\/(.+?)(' . $file_ext . ')(\'|")/i', '$1=$2' . $image_host . '/' . ($root_dir ? $root_dir : '') . '$4$5$6', $content ); } } return $content; } /** * Return file types supported by File URL Replacement. * @return string */ public function replaceable_file_types() { $types = $this->get('sm.body_rewrite_types'); // Removing extra space. $types = trim($types); $types = preg_replace("/\s{2,}/", ' ', $types); $types_arr = explode(' ', $types); return '\.' . implode('|\.', $types_arr); } /** * Copied from https://developer.wordpress.org/reference/functions/get_metadata/ * * @param $value null unless other filter hooked in this function. * @param $object_id post id * @param $meta_key * @param $single * @return mixed */ public function post_metadata_filter($value, $object_id, $meta_key, $single) { if (empty($value)) { $meta_type = 'post'; $transient_key = "stateless_{$meta_type}_meta"; $meta_cache = wp_cache_get($object_id, $transient_key); if (empty($meta_cache)) { $meta_cache = wp_cache_get($object_id, $meta_type . '_meta'); if (!$meta_cache) { $meta_cache = update_meta_cache($meta_type, array($object_id)); $meta_cache = $meta_cache[$object_id]; } foreach ($meta_cache as $key => $meta) { $meta_cache[$key] = array_map('maybe_unserialize', $meta_cache[$key]); } $meta_cache = $this->convert_to_gs_link($meta_cache); wp_cache_set($object_id, $meta_cache, $transient_key); } if (!$meta_key) { return $meta_cache; } if (isset($meta_cache[$meta_key])) { return $meta_cache[$meta_key]; } // in case no metadata is found return what was passed in $value. // $value most of the time is null. return $value; } return $this->convert_to_gs_link($value); } /** * Replace all image link with gs link and return only if meta modified. * * @param $meta * @param $return * @return mixed or null when not changed. */ public function convert_to_gs_link($meta, $return = false) { $updated = $meta; if ($meta && $upload_data = wp_upload_dir()) { if (!empty($upload_data['url']) && !empty($meta)) { $url = preg_replace('/https?:\/\//', '', $upload_data['url']); $root_dir = trim($this->get('sm.root_dir'), '/ '); // Remove any forward slash and empty space. $root_dir = apply_filters("wp_stateless_handle_root_dir", $root_dir); $root_dir = !empty($root_dir) ? $root_dir . '/' : false; $image_host = $this->get_gs_host() . '/' . ($root_dir ? $root_dir : ''); $file_ext = $this->replaceable_file_types(); $updated = $this->_convert_to_gs_link($meta, $image_host, $url, $file_ext); } } if ($updated == $meta && !$return) { return null; // Not changed. } return $updated; } /** * Replace all image link with gs link * * @param $meta * @param $image_host * @param $url * @param $file_ext * @return array|null|string|string[] */ public function _convert_to_gs_link($meta, $image_host, $url, $file_ext) { if (is_array($meta)) { foreach ($meta as $key => $value) { $meta[$key] = $this->_convert_to_gs_link($value, $image_host, $url, $file_ext); } return $meta; } elseif (is_object($meta) && $meta instanceof \stdClass) { foreach (get_object_vars($meta) as $key => $value) { $meta->{$key} = $this->_convert_to_gs_link($value, $image_host, $url, $file_ext); } return $meta; } elseif (is_string($meta)) { return preg_replace('/(https?:\/\/' . str_replace('/', '\/', $url) . ')\/(.+?)(' . $file_ext . ')/i', $image_host . '$2$3', $meta); } return $meta; } /** * Determines if plugin is loaded via mu-plugins * or Network Enabled. * * @param bool $is_multisite * @return bool * @author peshkov@UD */ public function is_network_detected($is_multisite = false) { /* Plugin is loaded via mu-plugins. */ if (strpos(Utility::normalize_path($this->root_path), Utility::normalize_path(WPMU_PLUGIN_DIR)) !== false) { return true; } if (is_multisite()) { if ($is_multisite) return true; /* Looks through network enabled plugins to see if our one is there. */ foreach (wp_get_active_network_plugins() as $path) { // Trying again using readlink in case it's a symlink file. // boot_file is already solved. // wp_normalize_path is helpfull in windows. if (wp_normalize_path($this->boot_file) == wp_normalize_path($path) || (is_link($path) && $this->boot_file == readlink($path))) { return true; } } } return false; } /** * Initialization. * Register scripts and styles */ public function admin_init() { $this->show_notice_stateless_cache_busting(); wp_register_style('wp-stateless', $this->path('static/styles/wp-stateless.css', 'url'), array(), self::$version); /** * select2 styles */ wp_register_style('wp-stateless-select2', $this->path('static/styles/select2.min.css', 'url'), array(), self::$version); /* Attachment or upload page */ wp_register_script('wp-stateless-uploads-js', $this->path('static/scripts/wp-stateless-uploads.js', 'url'), array('jquery'), self::$version); wp_localize_script('wp-stateless-uploads-js', 'stateless_upload', [ 'inline_sync_nonce' => wp_create_nonce('sm_inline_sync'), ]); /* Setup wizard styles. */ // #152 // wp_register_style('wp-stateless-setup-wizard', $this->path('static/styles/wp-stateless-setup-wizard.css', 'url'), array(), self::$version); wp_register_script('wp-stateless-select2', ud_get_stateless_media()->path('static/scripts/select2.min.js', 'url'), array('jquery'), self::$version, true); /* Stateless settings page */ wp_register_script('wp-stateless-settings', ud_get_stateless_media()->path('static/scripts/wp-stateless-settings.js', 'url'), array('clipboard'), self::$version); wp_localize_script('wp-stateless-settings', 'stateless_l10n', $this->get_l10n_data()); wp_register_style('wp-stateless-settings', $this->path('static/styles/wp-stateless-settings.css', 'url'), array(), self::$version); wp_register_style('wp-stateless-addons', $this->path('static/styles/wp-stateless-addons.css', 'url'), array(), self::$version); wp_register_style('wp-stateless-status', $this->path('static/styles/wp-stateless-status.css', 'url'), array(), self::$version); // Sync tab wp_register_script('wp-stateless', ud_get_stateless_media()->path('static/scripts/wp-stateless.js', 'url'), array('jquery-ui-core', 'wp-stateless-settings', 'wp-api-request'), self::$version, true); wp_localize_script('wp-stateless', 'stateless_l10n', $this->get_l10n_data()); wp_localize_script('wp-stateless', 'wp_stateless_configs', array( 'WP_DEBUG' => defined('WP_DEBUG') ? WP_DEBUG : false, 'REST_API_TOKEN' => Utility::generate_jwt_token(['user_id' => get_current_user_id()], DAY_IN_SECONDS), 'api_root' => apply_filters( 'wp_stateless_rest_api_root', '' ), 'ajaxurl' => admin_url( 'admin-ajax.php' ), 'stateless_check_ajax_nonce' => wp_create_nonce('stateless_check_ajax'), 'text_ok' => __('Ok', ud_get_stateless_media()->domain), 'text_fail' => __('Fail', ud_get_stateless_media()->domain), )); $settings = ud_get_stateless_media()->get('sm'); $settings['wildcards'] = $this->settings->wildcards; $settings['network_admin'] = is_network_admin(); $settings['is_multisite'] = is_multisite(); if (defined('WP_STATELESS_MEDIA_JSON_KEY') && WP_STATELESS_MEDIA_JSON_KEY) { $settings['key_json'] = "Currently configured via a constant."; } wp_localize_script('wp-stateless', 'wp_stateless_settings', $settings); // Batch processes tab wp_register_script('wp-stateless-batch', ud_get_stateless_media()->path('static/scripts/wp-stateless-batch.js', 'url'), array('wp-api-request'), self::$version, true); wp_localize_script('wp-stateless-batch', 'wp_stateless_batch', array( 'REST_API_TOKEN' => Utility::generate_jwt_token(['user_id' => get_current_user_id()], DAY_IN_SECONDS), 'is_running' => BatchTaskManager::instance()->is_running(), 'api_root' => apply_filters( 'wp_stateless_rest_api_root', '' ), )); } /** * Get_l10n_data * * @param string $value * @return mixed */ public function get_l10n_data($value = '') { include ud_get_stateless_media()->path('l10n.php', 'dir'); return $l10n; } /** * Admin Scripts * * @param $hook */ public function admin_enqueue_scripts($hook) { switch ($hook) { case 'options-media.php': wp_enqueue_style('wp-stateless'); break; case 'upload.php': wp_enqueue_style('wp-stateless'); wp_enqueue_script('wp-stateless-uploads-js'); break; case 'post.php': global $post; if ($post->post_type == 'attachment') { wp_enqueue_style('wp-stateless'); wp_enqueue_script('wp-stateless-uploads-js'); } break; // #152 // case 'media_page_stateless-setup': case 'settings_page_stateless-setup': wp_enqueue_style('wp-stateless'); // #152 // wp_enqueue_style('wp-stateless-setup-wizard'); break; case 'media_page_stateless-settings': case 'settings_page_stateless-settings': wp_enqueue_style('wp-stateless'); wp_enqueue_style('wp-stateless-select2'); wp_enqueue_script('wp-stateless-settings'); wp_enqueue_script('wp-stateless-select2'); wp_enqueue_style('wp-stateless-settings'); wp_enqueue_style('wp-stateless-addons'); wp_enqueue_style('wp-stateless-status'); wp_enqueue_style( 'media-views' ); // Sync tab wp_enqueue_script('wp-stateless'); // Data updates wp_enqueue_script('jquery-ui-dialog'); wp_enqueue_style('wp-jquery-ui-dialog'); wp_enqueue_script('wp-stateless-batch'); wp_enqueue_style('wp-pointer'); wp_enqueue_script('wp-pointer'); $data = array( 'key' => 'stateless-cache-busting', 'class' => 'notice', 'title' => sprintf(__("Stateless and Ephemeral modes enables and requires the Cache-Busting option.", ud_get_stateless_media()->domain)), 'message' => sprintf(__("WordPress looks at local files to prevent files with the same filenames. Since Stateless mode bypasses this check, there is a potential for files to be stored with the same file name. We enforce the Cache-Busting option to prevent this. Override with the %s constant.", ud_get_stateless_media()->domain), ud_get_stateless_media()->get_docs_page_url('docs/constants/#wpstatelessmediacachebusting'), "WP_STATELESS_MEDIA_CACHE_BUSTING"), ); echo ""; break; default: break; } } /** * Add Attributes to media HTML * * @author potanin@UD * @param $attr * @param $attachment * @param $size * @return mixed */ public function wp_get_attachment_image_attributes($attr, $attachment, $size = null) { $sm_cloud = apply_filters('wp_stateless_get_file', [], $attachment->ID); if (is_array($sm_cloud) && !empty($sm_cloud['name'])) { $attr['class'] = $attr['class'] . ' wp-stateless-item'; $attr['data-image-size'] = is_array($size) ? implode('x', $size) : $size; $attr['data-stateless-media-bucket'] = isset($sm_cloud['bucket']) ? $sm_cloud['bucket'] : false; $attr['data-stateless-media-name'] = $sm_cloud['name']; } return $attr; } /** * Adds filter link to Media Library table. * * @param $views * @return mixed */ public function views_upload($views) { $views['stateless'] = '' . __('Stateless Media') . ''; return $views; } /** * Replace media URL * * @param bool $false * @param integer $id * @param string $size * @return mixed $false */ public function image_downsize($false, $id, $size) { if ((!isset($this->client) || !$this->client || is_wp_error($this->client)) && $this->get('sm.mode') !== 'stateless') { return $false; } /** * Check if enabled */ if (!in_array($this->get('sm.mode'), array('cdn', 'stateless', 'ephemeral'))) { return $false; } /** Start determine remote file */ $img_url = wp_get_attachment_url($id); $meta = wp_get_attachment_metadata($id); $width = $height = 0; $is_intermediate = false; //** try for a new style intermediate size */ if ($intermediate = image_get_intermediate_size($id, $size)) { if (!empty($intermediate['gs_link'])) { $img_url = $intermediate['gs_link']; } else if (!empty($intermediate['url'])) { $img_url = $intermediate['url']; } else { $img_url = dirname($img_url) . $intermediate['file']; } $width = $intermediate['width']; $height = $intermediate['height']; $is_intermediate = true; } /** * maybe try to get images info from sm_cloud * this case may happen when no local files * @author korotkov@ud */ if (!$width && !$height) { $sm_cloud = apply_filters('wp_stateless_get_file', [], $id, true); if (is_string($size) && !empty($sm_cloud['sizes']) && !empty($sm_cloud['sizes'][$size])) { global $_wp_additional_image_sizes; $img_url = !empty($sm_cloud['sizes'][$size]['fileLink']) ? $sm_cloud['sizes'][$size]['fileLink'] : $img_url; if (!empty($_wp_additional_image_sizes[$size])) { $width = !empty($_wp_additional_image_sizes[$size]['width']) ? $_wp_additional_image_sizes[$size]['width'] : $width; $height = !empty($_wp_additional_image_sizes[$size]['height']) ? $_wp_additional_image_sizes[$size]['height'] : $height; } $is_intermediate = true; } } if (!$width && !$height && isset($meta['width'], $meta['height'])) { //** any other type: use the real image */ $width = $meta['width']; $height = $meta['height']; } if ($img_url) { //** we have the actual image size, but might need to further constrain it if content_width is narrower */ list($width, $height) = image_constrain_size_for_editor($width, $height, $size); $img_url = apply_filters('wp_stateless_bucket_link', $img_url); return array($img_url, $width, $height, $is_intermediate); } /** * All other cases work as usually */ return $false; } /** * Extends metadata by adding GS information. * Note: must not be called directly. It's used only on hook * * @param $metadata * @param $attachment_id * @return array|mixed */ public function wp_get_attachment_metadata($metadata, $attachment_id) { global $default_dir; $default_dir = false; /* Determine if the media file has GS data at all. */ $sm_cloud = apply_filters('wp_stateless_get_file', [], $attachment_id, true); // If metadata not passed the get metadata from post meta. if (empty($metadata)) { $metadata = get_post_meta($attachment_id, '_wp_attachment_metadata', true); } if (empty($metadata)) { $metadata = []; } if (is_array($metadata) && is_array($sm_cloud) && !empty($sm_cloud['fileLink'])) { $metadata['gs_link'] = apply_filters('wp_stateless_bucket_link', $sm_cloud['fileLink']); $metadata['gs_name'] = isset($sm_cloud['name']) ? $sm_cloud['name'] : false; $metadata['gs_bucket'] = isset($sm_cloud['bucket']) ? $sm_cloud['bucket'] : false; if (!empty($metadata['sizes']) && is_array($metadata['sizes'])) { foreach ($metadata['sizes'] as $k => $v) { if (!empty($sm_cloud['sizes'][$k]['name'])) { $metadata['sizes'][$k]['gs_name'] = $sm_cloud['sizes'][$k]['name']; $metadata['sizes'][$k]['gs_link'] = apply_filters('wp_stateless_bucket_link', $sm_cloud['sizes'][$k]['fileLink']); } } } } if (is_multisite() && !empty($metadata['file'])) { if ($this->get('sm.mode') == 'stateless') { $default_dir = true; $uploads = wp_get_upload_dir(); $default_dir = false; $file_path_fix = $uploads['basedir'] . "/{$metadata['file']}"; if (file_exists($file_path_fix)) { $metadata['file'] = "{$metadata['file']}"; } } else { $uploads = wp_get_upload_dir(); $blog_id = get_current_blog_id(); $file_path_fix = $uploads['basedir'] . "/sites/$blog_id/{$metadata['file']}"; if (file_exists($file_path_fix)) { $metadata['file'] = "sites/$blog_id/{$metadata['file']}"; } } } elseif ( empty($sm_cloud) && $this->get('sm.mode') == 'stateless' && isset($metadata['file']) ) { $default_dir = true; $uploads = wp_get_upload_dir(); $default_dir = false; $file_path_fix = $uploads['basedir'] . "/{$metadata['file']}"; if (file_exists($file_path_fix)) { $metadata['file'] = "{$metadata['file']}"; } } return $metadata; } /** * * @param $file * @param $attachment_id * @return string */ public function get_attached_file($file, $attachment_id) { global $default_dir; $sm_cloud = apply_filters('wp_stateless_get_file', [], $attachment_id); $_file = get_post_meta($attachment_id, '_wp_attached_file', true); /* Determine if the media file has GS data at all. */ if (is_multisite() && $_file) { $blog_id = get_current_blog_id(); $uploads = wp_get_upload_dir(); $_file = apply_filters('wp_stateless_file_name', $_file, false); $file_path_fix = $uploads['basedir'] . "/sites/$blog_id/$_file"; if (file_exists($file_path_fix)) { return $file_path_fix; } } elseif (empty($sm_cloud) && $this->get('sm.mode') == 'stateless' && $_file) { $default_dir = true; $uploads = wp_get_upload_dir(); $default_dir = false; return $uploads['basedir'] . '/' . $_file; } return $file; } /** * Returns client object * or WP_Error on failure. * * @author peshkov@UD * @return object $this->client. \wpCloud\StatelessMedia\GS_Client or \WP_Error */ public function get_client() { if (null === $this->client) { $key_json = $this->get('sm.key_json'); if (empty($key_json)) { $key_json = get_site_option('sm_key_json'); } /* Try to initialize GS Client */ $this->client = GS_Client::get_instance(array( 'bucket' => $this->get('sm.bucket'), 'key_json' => $key_json )); } return $this->client; } /** * Determines if we can connect to Google Storage Bucket. * * @author peshkov@UD */ public function is_connected_to_gs() { $trnst = get_transient('sm::is_connected_to_gs'); if (empty($trnst) || false === $trnst || !isset($trnst['hash']) || $trnst['hash'] != md5(serialize($this->get('sm')))) { $trnst = array( 'success' => 'true', 'error' => '', 'hash' => md5(serialize($this->get('sm'))), ); $client = $this->get_client(); if (is_wp_error($client)) { $trnst['success'] = 'false'; $trnst['error'] = $client->get_error_message(); } else { $connected = $client->is_connected(); if ($connected !== true) { $trnst['success'] = 'false'; $trnst['error'] = sprintf('Could not connect to Google Storage bucket. Please be sure that bucket with name %s exists and the access credentials are correct.', esc_html($this->get('sm.bucket'))); if (is_callable(array($connected, 'getHandlerContext')) && $handlerContext = $connected->getHandlerContext()) { if (!empty($handlerContext['error'])) { $handlerContext['error']; $trnst['error'] = "Could not connect to Google Storage bucket. " . make_clickable($handlerContext['error']); } } if (is_callable(array($connected, 'getErrors')) && $error = $connected->getErrors()) { $error = reset($error); if ($error['reason'] == 'accessNotConfigured') $trnst['error'] = "Could not connect to Google Storage bucket. " . make_clickable($error['message']); } } } set_transient('sm::is_connected_to_gs', $trnst, 4 * HOUR_IN_SECONDS); } if (isset($trnst['success']) && $trnst['success'] == 'false') { return new \WP_Error('error', (!empty($trnst['error']) ? $trnst['error'] : 'There is an Error on connection to Google Storage.')); } return true; } /** * Flush all plugin transients * */ public function flush_transients() { delete_transient('sm::is_connected_to_gs'); } /** * Plugin Activation * */ public function activate() { add_action('activated_plugin', array($this, 'redirect_to_splash'), 99); $this->run_upgrade_process(); } /** * Run Install Process. * Triggered on plugins_loaded instead of register_activation_hook action. * Works on even manual plugin update. * * @author alim@UD */ public function run_install_process() { // calling the upgrade function because it's same as this point for fresh install or updates. $this->run_upgrade_process(); } /** * Run Upgrade Process: * Triggered on plugins_loaded instead of register_activation_hook action. * Works on even manual plugin update. * * @author alim@UD */ public function run_upgrade_process() { // Creating database on new installation. ud_stateless_db()->create_db(); Migrator::instance()->migrate(); /** * Maybe Upgrade current Version */ Upgrader::call($this->args['version']); } /** * Delete table when blog is deleted. * * @param $old_site */ public function wp_delete_site($old_site) { ud_stateless_db()->clear_db($old_site->id); } /** * Redirect_to_splash * * @param string $plugin */ public function redirect_to_splash($plugin = '') { // $this->settings = new Settings(); if (defined('WP_CLI') || $this->settings->get('sm.key_json') || isset($_POST['checked']) && count($_POST['checked']) > 1) { return; } if ( !$this->settings->get('sm.key_json') && defined('WP_STATELESS_MEDIA_HIDE_SETUP_ASSISTANT') && WP_STATELESS_MEDIA_HIDE_SETUP_ASSISTANT == true && defined('WP_STATELESS_MEDIA_HIDE_SETTINGS_PANEL') && WP_STATELESS_MEDIA_HIDE_SETTINGS_PANEL == true ) { return; } if (!$this->settings->get('sm.key_json') && defined('WP_STATELESS_MEDIA_HIDE_SETUP_ASSISTANT') && WP_STATELESS_MEDIA_HIDE_SETUP_ASSISTANT == true) { $url = $this->get_settings_page_url('?page=stateless-settings'); exit(wp_redirect($url)); } if ($plugin == plugin_basename($this->boot_file)) { // #152 // $url = $this->get_settings_page_url('?page=stateless-setup&step=splash-screen'); $url = $this->get_settings_page_url('?page=stateless-settings'); if (json_decode($this->settings->get('sm.key_json'))) { $url = $this->get_settings_page_url('?page=stateless-settings'); } exit( wp_redirect($url) ); } } /** * Plugin Deactivation * */ public function deactivate() { } /** * Show_notice_stateless_cache_busting * */ public function show_notice_stateless_cache_busting() { $this->errors->add(array( 'key' => 'stateless_cache_busting', 'button' => 'View Settings', 'button_link' => admin_url('upload.php?page=stateless-settings'), 'title' => sprintf(__("Stateless mode now requires the Cache-Busting option.", ud_get_stateless_media()->domain)), 'message' => sprintf(__("WordPress looks at local files to prevent files with the same filenames. Since Stateless mode bypasses this check, there is a potential for files to be stored with the same file name. We enforce the Cache-Busting option to prevent this. Override with the %s constant.", ud_get_stateless_media()->domain), ud_get_stateless_media()->get_docs_page_url('docs/constants/#wpstatelessmediacachebusting'), "WP_STATELESS_MEDIA_CACHE_BUSTING"), ), 'notice'); } /** * Filter for wp_get_attachment_url(); * @param string $url * @param string $post_id * @return mixed|null|string */ public function wp_get_attachment_url($url = '', $post_id = '') { global $default_dir; $sm_cloud = apply_filters('wp_stateless_get_file', [], $post_id); if (is_array($sm_cloud) && !empty($sm_cloud['fileLink'])) { $_url = parse_url($sm_cloud['fileLink']); $url = !isset($_url['scheme']) ? ('https:' . $sm_cloud['fileLink']) : $sm_cloud['fileLink']; $url = apply_filters('wp_stateless_bucket_link', $url); } elseif (is_multisite() && empty($sm_cloud)) { $_file = get_post_meta($post_id, '_wp_attached_file', true); if ($_file) { if ($this->get('sm.mode') == 'stateless') { $default_dir = true; $uploads = wp_get_upload_dir(); $default_dir = false; $url = $uploads['baseurl'] . '/' . $_file; } else { $uploads = wp_get_upload_dir(); $default_dir = false; $_file = apply_filters('wp_stateless_file_name', $_file, false); $blog_id = get_current_blog_id(); $file_path_fix = $uploads['basedir'] . "/sites/$blog_id/$_file"; if (file_exists($file_path_fix)) { $url = $uploads['baseurl'] . "/sites/$blog_id/$_file"; } } } } elseif (empty($sm_cloud) && $this->get('sm.mode') == 'stateless') { $_file = get_post_meta($post_id, '_wp_attached_file', true); if ($_file) { $default_dir = true; $uploads = wp_get_upload_dir(); $default_dir = false; $url = $uploads['baseurl'] . '/' . $_file; } } return apply_filters('wp_stateless_attachment_url', $url, $post_id); } /** * Filter for attachment_url_to_postid() * * @param int|false $post_id originally found post ID (or false if not found) * @param string $url the URL to find the post ID for * @return int|false found post ID from cloud storage URL */ public function attachment_url_to_postid($post_id, $url) { global $wpdb; if (!$post_id) { $post_id = get_transient("stateless_url_to_postid_" . md5($url)); if (defined('WP_STATELESS_LEGACY_URL_TO_POSTID')) { // User can use this constant if they change the Bucket Folder (root_dir) after uploading image. // This can be little slow at first run. if (empty($post_id)) { if ( !$this->get('sm.use_postmeta') ) { $query = 'SELECT post_id FROM ' . ud_stateless_db()->files . ' WHERE file_link = %s'; $post_id = $wpdb->get_var($wpdb->prepare($query, $url)); } if (empty($post_id)) { $query = "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = 'sm_cloud' AND meta_value LIKE '%s'"; $post_id = $wpdb->get_var($wpdb->prepare($query, '%' . $url . '%')); } if ($post_id) { set_transient("stateless_url_to_postid_" . md5($url), $post_id); } } return $post_id; } if (empty($post_id)) { $gs_base_url = $this->get_gs_host(); $root_dir = $this->get('sm.root_dir'); $path_elements = apply_filters('wp_stateless_unhandle_root_dir', $url); $root_dir = apply_filters("wp_stateless_handle_root_dir", $root_dir, false, $path_elements); $gs_url = $this->get_gs_host() . '/' . $root_dir; $site_url = parse_url($gs_url); $image_path = parse_url($url); //force the protocols to match if needed if (isset($image_path['scheme']) && ($image_path['scheme'] !== $site_url['scheme'])) { $url = str_replace($image_path['scheme'], $site_url['scheme'], $url); } if (0 === strpos($url, $gs_url . '/')) { $url = substr($url, strlen($gs_url . '/')); } else if (0 === strpos($url, $gs_base_url . '/')) { // In case user added Bucket Folder (root_dir) after uploading image. $url = substr($url, strlen($gs_base_url . '/')); } /** * If `uploads_use_yearmonth_folders` is set - adding year and month to url */ $organize_media = get_option('uploads_use_yearmonth_folders'); $path = ''; if ($organize_media == '1' && isset($path_elements['%date_year/date_month%'])) { $path .= $path_elements['%date_year/date_month%'] . '/'; } $url = $path . $url; $sql = $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_wp_attached_file' AND meta_value = %s", $url ); $post_id = $wpdb->get_var($sql); if ($post_id) { set_transient("stateless_url_to_postid_" . md5($url), $post_id); } } } return $post_id; } /** * Change Upload BaseURL when CDN Used. * * @param $data * @return mixed */ public function upload_dir($data) { $data['basedir'] = $this->get_gs_host(); $data['baseurl'] = $this->get_gs_host(); $data['url'] = $data['baseurl'] . $data['subdir']; return $data; } /** * Set Feature Flag constants by parsing composer.json * * @todo Make sure settings from DB can override these. * * @author potanin@UD * @return array|mixed|null|object */ public function parse_feature_flags() { try { $_raw = file_get_contents(Utility::normalize_path($this->root_path) . 'composer.json'); $_parsed = json_decode($_raw); // @todo Catch poorly formatted JSON. if (!is_object($_parsed)) { // throw new Error( "unable to parse." ); } foreach ((array) $_parsed->extra->featureFlags as $_feature) { if (!defined($_feature->constant)) { define($_feature->constant, $_feature->enabled); if ($_feature->enabled) { Utility::log('Feature flag ' . $_feature->name . ', [' . $_feature->constant . '] enabled.'); } else { Utility::log('Feature flag ' . $_feature->name . ', [' . $_feature->constant . '] disabled.'); } } } } catch (\Exception $e) { Utility::log('Unable to parse [composer.json] feature flags. Error: [' . $e->getMessage() . ']'); // echo 'Caught exception: ', $e->getMessage(), "\n"; } return isset($_parsed) ? $_parsed : null; } /** * Determine if Utility class contains missed function * in other case, just return NULL to prevent ERRORS * * @author peshkov@UD * @param $name * @param $arguments * @return mixed|null */ public function __call($name, $arguments) { if (is_callable(array("wpCloud\\StatelessMedia\\Utility", $name))) { return call_user_func_array(array("wpCloud\\StatelessMedia\\Utility", $name), $arguments); } else { return NULL; } } /** * Get all thumbnail sizes * * @global $_wp_additional_image_sizes * @uses get_intermediate_image_sizes() * * @param boolean [$unset_disabled = true] * @return array */ function get_image_sizes($unset_disabled = true) { $wais = &$GLOBALS['_wp_additional_image_sizes']; $sizes = array(); foreach (get_intermediate_image_sizes() as $_size) { if (in_array($_size, array('thumbnail', 'medium', 'medium_large', 'large'))) { $sizes[$_size] = array( 'width' => get_option("{$_size}_size_w"), 'height' => get_option("{$_size}_size_h"), 'crop' => (bool) get_option("{$_size}_crop"), ); } elseif (isset($wais[$_size])) { $sizes[$_size] = array( 'width' => $wais[$_size]['width'], 'height' => $wais[$_size]['height'], 'crop' => $wais[$_size]['crop'], ); } // size registered, but has 0 width and height if ($unset_disabled && ($sizes[$_size]['width'] == 0) && ($sizes[$_size]['height'] == 0)) unset($sizes[$_size]); } return $sizes; } /** * Get the email for notifications * * @return string */ public function get_notification_email() { $type = $this->get( 'sm.status_email_type' ); switch ($type) { case 'true': // Emails to Admin return get_site_option('admin_email'); case 'custom': // Emails to Custom Email return $this->get( 'sm.status_email_address' ); } // Emails disabled return ''; } /** * Send admin email * * @param string $subject * @param string $message * @param string $email */ public function send_admin_email($subject, $message, $email = '') { $admin_email = empty($email) ? $this->get_notification_email() : $email; $admin_email = explode(',', $admin_email); $admin_email = array_map( function($item) { return strip_tags( trim($item) ); }, $admin_email); if ( empty($admin_email) || empty($subject) || empty($message) ) { return; } wp_mail( $admin_email, $subject, $message); } /** * Check if we are in specific mode * * @param string|array $mode * @return bool */ public function is_mode($mode) { if ( !is_array($mode) ) { $mode = [$mode]; } return in_array($this->get('sm.mode'), $mode); } /** * Get default cache control value * * @return string */ public function get_default_cache_control() { return Settings::DEFAULT_CACHE_CONTROL; } /** * Override REST API root for headless CMS * * @return string */ public function get_rest_api_root($rest_api_root) { $rest_api_root = sanitize_url( get_rest_url() ); $rest_api_root .= 'wp-stateless/v1/'; if ( $this->get('sm.use_api_siteurl') == 'WP_SITEURL' ) { $home = get_home_url(); $site = get_site_url(); return str_replace( $home, $site, $rest_api_root ); } return $rest_api_root; } } } } ================================================ FILE: lib/classes/class-compatibility.php ================================================ New Constant, ...] * ['WP_STATELESS_MEDIA_ON_FLY' => 'WP_STATELESS_DYNAMIC_IMAGE_SUPPORT'] */ protected $constant = ''; protected $enabled = true; protected $description = ''; protected $plugin_file = null; protected $theme_name = null; protected $first_party = false; protected $non_library_sync = false; protected $server_constant = false; protected $sm_mode_required = ''; protected $sm_mode_not_supported = []; protected $is_internal = false; public function __construct() { // Prevent conflict between internal built-in compatibility modules and addon plugins $restrict = apply_filters('wp_stateless_restrict_compatibility', false, $this->id, $this->is_internal); if ($restrict) { $this->enabled = false; return; } if ( !$this->is_internal ) { add_filter('wp_stateless_restrict_compatibility', array($this, 'restrict_compatibility'), 10, 3); } $this->init(); } /** * Checking whether the plugin is active or not. * If the plugin_file is specified then check whether plugin is active or not. * We can't use is_plugin_active function because it's defined later in init. * By default return true. * * @todo caching. */ public function is_plugin_active() { if (!empty($this->theme_name)) { return Helper::is_theme_name($this->theme_name); } if (!empty($this->plugin_file)) { // Converting string to array for foreach if (is_string($this->plugin_file)) { $this->plugin_file = array($this->plugin_file); } // If multisite then check if plugin is network active if (is_multisite()) { $active_plugins = (array)get_site_option('active_sitewide_plugins'); foreach ($this->plugin_file as $plugin_file) { if (isset($active_plugins[$plugin_file])) { return true; } } // If we are in network admin then return, unless it will get data from main site. if (is_network_admin()) { return false; } } $active_plugins = (array)get_option('active_plugins', array()); foreach ($this->plugin_file as $plugin_file) { if (in_array($plugin_file, $active_plugins)) { return true; } } return false; } /** * If server constant is set - check if exist it on global $_SERVER */ if (!empty($this->server_constant)) { if (isset($_SERVER[$this->server_constant])) { return true; } return false; } return true; } /** * Checking whether current mode is supported. * By default return true. * * @todo caching. */ public function is_mode_supported() { $sm_mode = isset($_POST['sm']['mode']) ? $_POST['sm']['mode'] : ud_get_stateless_media()->get('sm.mode'); if (in_array($sm_mode, $this->sm_mode_not_supported)) { return false; } return true; } /** * Initialize the module * Check whether plugin is active or not. * Register module. * * Add action for sm::module::init hook for module_init, which is fired(do_action) on Bootstrap::init() */ public function init() { $is_constant = false; $is_network_override = false; $sm_mode = isset($_POST['sm']['mode']) ? $_POST['sm']['mode'] : ud_get_stateless_media()->get('sm.mode'); if (is_network_admin()) { $this->enabled = null; } if (is_array($this->constant)) { foreach ($this->constant as $old_const => $new_const) { if (defined($new_const)) { $is_constant = true; $this->enabled = constant($new_const); break; } if (is_string($old_const) && defined($old_const)) { $is_constant = true; $this->enabled = constant($old_const); ud_get_stateless_media()->errors->add(array( 'key' => $this->id, 'title' => sprintf(__("%s: Deprecated Notice (%s)", ud_get_stateless_media()->domain), ud_get_stateless_media()->name, $this->title), 'message' => sprintf(__("%s constant is deprecated, please use %s instead.", ud_get_stateless_media()->domain), $old_const, $new_const), ), 'notice'); break; } } } elseif (defined($this->constant)) { $this->enabled = constant($this->constant); $is_constant = true; } if (!$is_constant) { $modules = get_option('stateless-modules', array()); if (empty($this->enabled)) { $this->enabled = !empty($modules[$this->id]) && $modules[$this->id] == 'true' ? true : false; } if (is_multisite()) { $modules = get_site_option('stateless-modules', array()); if (is_network_admin()) { $this->enabled = !empty($modules[$this->id]) ? ($modules[$this->id] == 'true' ? true : false) : ''; } elseif (!empty($modules[$this->id])) { $this->enabled = !empty($modules[$this->id]) ? ($modules[$this->id] == 'true' ? true : false) : ''; $is_network_override = true; } } } if (!is_network_admin() && (!$this->is_plugin_active() || !$this->is_mode_supported())) { $this->enabled = 'inactive'; } /** * Checking whether to show manual sync option. */ if ($this->is_plugin_active() && $this->non_library_sync == true) { global $show_non_library_sync; $show_non_library_sync = true; } Module::register_module(array( 'id' => $this->id, 'self' => $this, 'title' => $this->title, 'enabled' => $this->enabled, 'description' => $this->description, 'is_constant' => $is_constant, 'is_network_override' => $is_network_override, 'is_plugin_active' => $this->is_plugin_active(), 'is_network_admin' => is_network_admin(), 'is_plugin' => !empty($this->plugin_file), 'is_theme' => !empty($this->theme_name), 'is_mode_supported' => $this->is_mode_supported(), 'mode' => ucfirst($sm_mode), 'is_internal' => $this->is_internal, )); if ($this->enabled && $this->is_plugin_active() && $this->is_mode_supported()) { add_action('sm::module::init', array($this, 'module_init')); } if (!$this->enabled && !$this->first_party && $this->is_plugin_active()) { ud_get_stateless_media()->errors->add(array( 'key' => $this->id, 'title' => sprintf(__("%s: Compatibility for %s isn't enabled.", ud_get_stateless_media()->domain), ud_get_stateless_media()->name, $this->title), 'button' => __("Enable Compatibility", ud_get_stateless_media()->domain), 'message' => __("Please enable the compatibility to ensure the functionality will work properly between {$this->title} and WP-Stateless.", ud_get_stateless_media()->domain), ), 'notice'); } /** * Check requires WP-Stateless mode */ if (!empty($this->sm_mode_required) && $this->enabled !== 'inactive') { if ($sm_mode !== $this->sm_mode_required) { ud_get_stateless_media()->errors->add(array( 'key' => $this->id, 'title' => sprintf(__("%s: Current Mode is not compatible with %s.", ud_get_stateless_media()->domain), ud_get_stateless_media()->name, $this->title), 'message' => sprintf(__("%s compatibility requires %s in %s mode.", ud_get_stateless_media()->domain), $this->title, ud_get_stateless_media()->name, ucfirst($this->sm_mode_required)), ), 'notice'); } } } /** * @return bool */ public function enable_compatibility() { if (is_network_admin()) { $modules = get_site_option('stateless-modules', array()); if (empty($modules[$this->id]) || $modules[$this->id] != 'true') { $modules[$this->id] = 'true'; update_site_option('stateless-modules', $modules, true); } } else { $modules = get_option('stateless-modules', array()); if (empty($modules[$this->id]) || $modules[$this->id] != 'true') { $modules[$this->id] = 'true'; update_option('stateless-modules', $modules, true); } } return true; } /** * add_webp_mime * @param $t * @param $user * @return mixed */ public function add_webp_mime($t, $user) { $t['webp'] = 'image/webp'; return $t; } /** * Restrict internal compatibility. * @param $restrict bool * @param $id string * @param $is_internal bool * @return bool */ public function restrict_compatibility($restrict, $id, $is_internal) { // If we have internal compatibility with the same ID - then disable internal compatibility return $is_internal && $this->id == $id ? true : $restrict; } } ================================================ FILE: lib/classes/class-db.php ================================================ 'id', 'post_id' => 'post_id', 'bucket' => 'bucket', 'name' => 'name', 'generation' => 'generation', 'cacheControl' => 'cache_control', 'contentType' => 'content_type', 'contentDisposition' => 'content_disposition', 'filesize' => 'file_size', 'width' => 'width', 'height' => 'height', 'stateless_version' => 'stateless_version', 'storageClass' => 'storage_class', 'fileLink' => 'file_link', 'selfLink' => 'self_link', ]; /** * Files sizes table fields mapping, used for backward compatibility with old postmeta */ private $file_sizes_mapping = [ 'id' => 'id', 'post_id' => 'post_id', 'size_name' => 'size_name', 'name' => 'name', 'generation' => 'generation', 'filesize' => 'file_size', 'width' => 'width', 'height' => 'height', 'fileLink' => 'file_link', 'selfLink' => 'self_link', ]; protected function __construct() { global $wpdb; $this->wpdb = $wpdb; $this->files = $this->wpdb->prefix . 'stateless_files'; $this->file_sizes = $this->wpdb->prefix . 'stateless_file_sizes'; $this->file_meta = $this->wpdb->prefix . 'stateless_file_meta'; $image_host = ud_get_stateless_media()->get_gs_host(); $this->bucket_link = apply_filters('wp_stateless_bucket_link', $image_host); if ( is_multisite() ) { $this->cache_group = implode('_', [ $this->cache_group, get_current_blog_id(), ]); } $this->_init(); } /** * Init hooks */ private function _init() { add_filter('wp_stateless_generate_cloud_meta', [$this, 'process_cloud_meta'], 10, 5); add_action('deleted_post', [$this, 'delete_post'], 10, 2); add_filter('wp_stateless_get_file', [$this, 'get_file'], 10, 3); add_filter('wp_stateless_get_file_sizes', [$this, 'get_file_sizes'], 10, 2); add_filter('wp_stateless_get_file_meta', [$this, 'get_file_meta'], 10, 2); add_filter('wp_stateless_get_file_meta_value', [$this, 'get_file_meta_value'], 10, 4); add_action('wp_stateless_set_file', [$this, 'set_file'], 10, 2); add_action('wp_stateless_set_file_size', [$this, 'set_file_size'], 10, 3); add_action('wp_stateless_set_file_meta', [$this, 'update_file_meta'], 10, 3); add_action('wp_stateless_get_non_library_files', [$this, 'get_non_library_files'], 10, 2); } /** * Getters */ public function __get($property) { if ( in_array($property, ['files', 'file_sizes', 'file_meta']) ) { return $this->$property; } } /** * Creates or updates DB structure */ public function create_db() { $version = get_option(self::DB_VERSION_KEY, ''); if ($version === self::DB_VERSION) { return; } try { Upgrader::upgrade_db(self::DB_VERSION, $version); $charset_collate = $this->wpdb->get_charset_collate(); /** * Indexes for varchar(255) columns are limited for backward compatibility. * Based on wp-admin/includes/schema.php (wp_get_db_schema function) */ $sql = "CREATE TABLE $this->files ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `post_id` bigint(20) unsigned NULL DEFAULT NULL, `bucket` varchar(255) NOT NULL, `name` varchar(255) NOT NULL, `generation` bigint(16) NOT NULL, `cache_control` varchar(255) NULL DEFAULT NULL, `content_type` varchar(255) NULL DEFAULT NULL, `content_disposition` varchar(100) NULL DEFAULT NULL, `file_size` bigint(20) unsigned NULL DEFAULT NULL, `width` int unsigned NULL DEFAULT NULL, `height` int unsigned NULL DEFAULT NULL, `stateless_version` varchar(20) NOT NULL, `storage_class` varchar(50) NULL DEFAULT NULL, `file_link` text NOT NULL, `self_link` text NOT NULL, `source` varchar(50) NULL DEFAULT NULL, `source_version` varchar(50) NULL DEFAULT NULL, `status` varchar(10) NULL DEFAULT NULL, PRIMARY KEY (`id`), KEY post_id (post_id), KEY `name` (`name`(191)), UNIQUE KEY post_id_name (post_id, `name`(150)) ) $charset_collate; CREATE TABLE $this->file_sizes ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `post_id` bigint(20) unsigned NULL DEFAULT NULL, `size_name` varchar(255) NOT NULL, `name` varchar(255) NOT NULL, `generation` bigint(16) NOT NULL, `file_size` bigint(20) unsigned NULL DEFAULT NULL, `width` int unsigned NULL DEFAULT NULL, `height` int unsigned NULL DEFAULT NULL, `file_link` text NOT NULL, `self_link` text NOT NULL, PRIMARY KEY (`id`), KEY post_id (post_id), UNIQUE KEY post_id_size (post_id, size_name(150)) ) $charset_collate; CREATE TABLE $this->file_meta ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `post_id` bigint(20) unsigned NULL DEFAULT NULL, `meta_key` varchar(255) NOT NULL, `meta_value` longtext NOT NULL, PRIMARY KEY (`id`), KEY post_id (post_id), UNIQUE KEY post_id_key (post_id, meta_key(150)) ) $charset_collate;"; require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); dbDelta($sql); update_option(self::DB_VERSION_KEY, self::DB_VERSION); } catch (\Throwable $e) { Helper::log($e->getMessage()); } } /** * Remove custom DB table on plugin uninstall * * @param int $site_id */ public function clear_db($site_id) { switch_to_blog($site_id); $tables = array( $this->wpdb->prefix . 'files', $this->wpdb->prefix . 'files_sizes', $this->wpdb->prefix . 'file_meta', ); $tables = implode(', ', $tables); $sql = "DROP TABLE IF EXISTS $tables;"; $this->wpdb->query($sql); restore_current_blog(); } /** * Get file link * * @param string $name * @return string */ public function get_file_link($name) { return trailingslashit($this->bucket_link) . $name; } /** * Get file row ID by post ID * * @param int $post_id * @return int | null */ public function get_file_id($post_id) { $sql = "SELECT id FROM $this->files WHERE post_id = %d AND post_id IS NOT NULL"; $id = $this->wpdb->get_var( $this->wpdb->prepare($sql, $post_id) ); return $id ? (int) $id : null; } /** * Get ID of the non-library file by file name and status * * @param string $name * @param string $status * @return int | null */ public function get_non_library_file_id($name, $status = '') { $sql = "SELECT id FROM $this->files WHERE name = %s AND post_id IS NULL"; $args = [$name]; if ( !empty($status) ) { $sql .= " AND status = %s"; $args[] = $status; } $id = $this->wpdb->get_var( $this->wpdb->prepare($sql, ...$args) ); return $id ? (int) $id : null; } /** * Get name of the non-library file by part of the name * * @param string $name * @return string | null */ public function get_non_library_file_name($name) { $sql = "SELECT name FROM $this->files WHERE name like '%%%s' AND post_id IS NULL"; return $this->wpdb->get_var( $this->wpdb->prepare($sql, $name) ); } /** * Get file size row ID by post ID and size name * * @param int $post_id * @param string $size * @return int | null */ public function get_file_size_id($post_id, $size) { $sql = "SELECT id FROM $this->file_sizes WHERE post_id = %d AND size_name = %s"; $id = $this->wpdb->get_var( $this->wpdb->prepare($sql, $post_id, $size) ); return $id ? (int) $id : null; } /** * Get file meta row ID by post ID and meta key * * @param int $post_id * @param string $key * @return int | null */ public function get_file_meta_id($post_id, $key) { $key = sanitize_key($key); $sql = "SELECT id FROM $this->file_meta WHERE post_id = %d AND meta_key = %s"; $id = $this->wpdb->get_var( $this->wpdb->prepare($sql, $post_id, $key) ); return $id ? (int) $id : null; } /** * Add file data to DB * * @param array $cloud_meta - generated WP postmeta * @param array $media - GCS media object * @param string $image_size - image size name * @param array $img - image (or image size) data for upload * @param string $bucketLink - bucket link * @return mixed */ public function process_cloud_meta($cloud_meta, $media, $image_size, $img, $bucketLink) { $this->update_data($media); return $cloud_meta; } /** * Determine which data to update and run updates * * @param array $media - GCS media object */ public function update_data($media) { $error = false; if ( !isset($media['name']) || !isset($media['metadata']) || !isset($media['metadata']['size']) ) { $error = 'Metadata missing or incorrect for GCS media object'; } else { $size = $media['metadata']['size']; if ( $size == self::FULL_SIZE ) { $attachment_id = isset($media['metadata']['object-id']) ? $media['metadata']['object-id'] : null; if ( !$attachment_id ) { $error = 'Unable to get attachment ID for GCS media object'; } else { $this->_update_file( $attachment_id, $this->_get_file_from_media($media), ); } } else { $attachment_id = isset($media['metadata']['child-of']) ? $media['metadata']['child-of'] : null; if ( !$attachment_id ) { $error = 'Unable to get parent attachment ID for GCS media object'; } else { $this->_update_file_size( $attachment_id, $size, $this->_get_file_size_from_media($media), ); } } } if ( $error ) { Helper::log($error); Helper::log($media, true); } } /** * Update file data, based on the mapping received from the media object * * @param int $attachment_id * @param array $data * @return int | null */ public function set_file($attachment_id, $data) { $result = []; foreach ($this->file_mapping as $key => $mapping) { if ( isset($data[$key]) ) { $result[$mapping] = $data[$key]; continue; } if ( isset($data[$mapping]) ) { $result[$mapping] = $data[$mapping]; continue; } } unset($result['id']); return $this->_update_file($attachment_id, $result); } /** * Update file size data * * @param int $attachment_id * @param string $size_name * @param array $data * @return int | null */ public function set_file_size($attachment_id, $size_name, $data) { $result = []; foreach ($this->file_sizes_mapping as $key => $mapping) { if ( isset($data[$key]) ) { $result[$mapping] = $data[$key]; continue; } if ( isset($data[$mapping]) ) { $result[$mapping] = $data[$mapping]; continue; } } unset($result['id']); return $this->_update_file_size($attachment_id, $size_name, $result); } /** * Convert GSC media object into stateless file data * * @param array $media * @return array */ private function _get_file_from_media($media, $status = '') { $name = $media['name']; $data =[ 'bucket' => $media['bucket'] ?? '', 'name' => $name, 'generation' => $media['generation'] ?? '', 'cache_control' => $media['cacheControl'] ?? null, 'content_type' => $media['contentType'] ?? null, 'content_disposition' => $media['contentDisposition'] ?? null, 'file_size' => $media['size'] ?? null, 'width' => $media['metadata']['width'] ?? null, 'height' => $media['metadata']['height'] ?? null, 'stateless_version' => get_option('wp_sm_version', false), 'storage_class' => $media['storageClass'] ?? null, 'file_link' => $this->get_file_link($name), 'self_link' => $media['selfLink'] ?? '', 'status' => $status, 'source' => $media['metadata']['source'] ?? '', 'source_version' => $media['metadata']['sourceVersion'] ?? '', ]; return $data; } /** * Update non Media Library file (compatibility files) * * @param array $media - GCS media object * @param string $source - source of the file * @param string $status - status of the file */ public function update_non_library_file($media, $status = '') { if ( !is_array($media) || empty($media) || !isset($media['name']) ) { Helper::log('Media object is not valid or empty. Unable to update non-library file.'); return; } $data = $this->_get_file_from_media($media, $status); $file_id = $this->get_non_library_file_id($data['name'], $status); if ( $file_id ) { $this->wpdb->update( $this->files, $data, ['id' => $file_id] ); } else { $this->wpdb->insert( $this->files, $data ); $file_id = $this->wpdb->insert_id; } return $file_id; } /** * Update file data * * @param int $attachment_id * @param array $data * @return int | null */ private function _update_file($attachment_id, $data) { $file_id = $this->get_file_id($attachment_id); if ( $file_id ) { $this->wpdb->update( $this->files, $data, ['id' => $file_id] ); } else { $data['post_id'] = $attachment_id; $this->wpdb->insert( $this->files, $data ); $file_id = $this->wpdb->insert_id; } $this->_delete_file_cache($attachment_id); return $file_id; } /** * Convert GSC media object into stateless file size data * * @param array $media * @return array */ private function _get_file_size_from_media($media) { $name = $media['name']; $data =[ 'name' => $name, 'generation' => $media['generation'] ?? '', 'file_size' => $media['size'] ?? null, 'width' => $media['metadata']['width'] ?? null, 'height' => $media['metadata']['height'] ?? null, 'file_link' => $this->get_file_link($name), 'self_link' => $media['selfLink'] ?? '', ]; return $data; } /** * Update file size data * * @param int $attachment_id * @param string $size_name * @param array $media * @return int | null */ private function _update_file_size($attachment_id, $size_name, $data) { $file_size_id = $this->get_file_size_id($attachment_id, $size_name); if ( $file_size_id ) { $this->wpdb->update( $this->file_sizes, $data, ['id' => $file_size_id] ); } else { $data['post_id'] = $attachment_id; $data['size_name'] = $size_name; $this->wpdb->insert( $this->file_sizes, $data ); $file_size_id = $this->wpdb->insert_id; } $this->_delete_file_sizes_cache($attachment_id); return $file_size_id; } /** * Delete file data when attachment is deleted * * @param int $post_id * @param \WP_Post $post */ public function delete_post($post_id, $post) { $file_id = $this->get_file_id($post_id); if ( !$file_id ) { return; } $this->wpdb->delete( $this->files, ['post_id' => $post_id] ); $this->wpdb->delete( $this->file_sizes, ['post_id' => $post_id] ); $this->wpdb->delete( $this->file_meta, ['post_id' => $post_id] ); $this->_delete_attachment_cache($post_id); } /** * Map requested fields into database query< compatible with the old post meta structure * * @param array $fields * @param array $fields_mapping * @return string */ private function _map_fields($fields, $fields_mapping) { $mapped = []; $result = []; if ( !is_array($fields) ) { $fields = [$fields]; } if (empty($fields)) { $fields = array_keys($fields_mapping); } foreach ($fields as $key) { if ( isset($fields_mapping[$key]) ) { $mapped[$key] = $fields_mapping[$key]; } } foreach ($mapped as $key => $value) { $result[] = "$value AS $key"; } return implode(', ', $result); } /** * Get cache key for file data * * @param int $post_id * @return string */ private function _get_file_cache_key($post_id) { return implode('_', ['file', $post_id]); } /** * Get cache key for file sizes data * * @param int $post_id * @return string */ private function _get_file_sizes_cache_key($post_id) { return implode('_', ['file_sizes', $post_id]); } /** * Get cache group for file meta data * * @param int $post_id * @return string */ private function _get_file_meta_cache_group($post_id) { return implode('_', [$this->cache_group, 'meta', $post_id]); } /** * Get cache key for file meta data * * @param int $post_id * @param string $key * @return string */ private function _get_file_meta_cache_key($post_id, $key) { return implode('_', [$key, $post_id]); } /** * Get cache for file meta * * @param int $post_id * @param string $key * @param bool $found * @return mixed */ private function _get_file_meta_cache($post_id, $key, &$found) { return wp_cache_get( $this->_get_file_meta_cache_key($post_id, $key), $this->_get_file_meta_cache_group($post_id), false, $found ); } /** * Set cache for file meta * * @param int $post_id * @param string $key * @param mixed $value * @return bool */ private function _set_file_meta_cache($post_id, $key, $value) { return wp_cache_set( $this->_get_file_meta_cache_key($post_id, $key), $value, $this->_get_file_meta_cache_group($post_id) ); } /** * Delete file cache * * @param int $attachment_id */ private function _delete_file_cache($attachment_id) { wp_cache_delete( $this->_get_file_cache_key($attachment_id), $this->cache_group ); } /** * Delete file sizes cache * * @param int $attachment_id */ private function _delete_file_sizes_cache($attachment_id) { wp_cache_delete( $this->_get_file_sizes_cache_key($attachment_id), $this->cache_group ); } /** * Delete file meta cache for single key * * @param int $attachment_id * @param string $key */ private function _delete_file_meta_key_cache($attachment_id, $key) { wp_cache_delete( $this->_get_file_meta_cache_key($attachment_id, $key), $this->_get_file_meta_cache_group($attachment_id) ); } /** * Delete all file meta cache * * @param int $attachment_id */ private function _delete_file_meta_cache($attachment_id) { wp_cache_flush_group( $this->_get_file_meta_cache_group($attachment_id) ); } /** * Delete all attachment cache * * @param int $attachment_id */ private function _delete_attachment_cache($attachment_id) { $this->_delete_file_cache($attachment_id); $this->_delete_file_sizes_cache($attachment_id); $this->_delete_file_meta_cache($attachment_id); } /** * Get the total files count known to WP-Stateless * * @return int */ public function get_total_files() { global $wpdb; try { $query = "SELECT COUNT(id) FROM $this->files"; return $wpdb->get_var($query); } catch (\Throwable $e) { return 0; } } /** * Get the total file sizes count known to WP-Stateless * * @return int */ public function get_total_file_sizes() { global $wpdb; try { $query = "SELECT COUNT(id) FROM $this->file_sizes"; return $wpdb->get_var($query); } catch (\Throwable $e) { return 0; } } /** * Get the total non-media file sizes count known to WP-Stateless * * @return int */ public function get_total_non_media_files() { global $wpdb; try { $query = "SELECT COUNT(id) FROM $this->files WHERE post_id IS NULL"; return $wpdb->get_var($query); } catch (\Throwable $e) { return 0; } } /** * Get file data. If $with_sizes is set to true, all sizes will be included * * @param array $meta * @param int $attachment_id * @param bool $with_sizes * @return array */ public function get_file($meta, $attachment_id, $with_sizes = false) { if ( ud_get_stateless_media()->get('sm.use_postmeta') ) { $meta = get_post_meta($attachment_id, 'sm_cloud', true); if ( !empty($meta) ) { return $meta; } } // Get values from the cache $cache_key = $this->_get_file_cache_key($attachment_id); $meta = wp_cache_get($cache_key, $this->cache_group, false, $found); if ( $found ) { return $meta; } // Get values from the DB $fields = $this->_map_fields([], $this->file_mapping); $sql = "SELECT $fields FROM $this->files WHERE post_id = %d"; $meta = $this->wpdb->get_row( $this->wpdb->prepare($sql, $attachment_id), ARRAY_A ); if ( empty($meta) ) { return get_post_meta($attachment_id, 'sm_cloud', true); } wp_cache_set($cache_key, $meta, $this->cache_group); // Get file size meta data if ( $with_sizes ) { $meta['sizes'] = apply_filters('wp_stateless_get_file_sizes', [], $attachment_id); } return $meta; } /** * Get file sizes data * * @param array $sizes * @param int $attachment_id * @return array */ public function get_file_sizes($sizes, $attachment_id) { if ( ud_get_stateless_media()->get('sm.use_postmeta') ) { $meta = get_post_meta($attachment_id, 'sm_cloud', true); return isset($meta['sizes']) ? $meta['sizes'] : []; } // Get values from the cache $cache_key = $this->_get_file_sizes_cache_key($attachment_id); $sizes = wp_cache_get($cache_key, $this->cache_group, false, $found); if ( $found ) { return $sizes; } // Get values from the DB $fields = $this->_map_fields([], $this->file_sizes_mapping); $sql = "SELECT $fields FROM $this->file_sizes WHERE post_id = %d"; $sql = $this->wpdb->prepare($sql, $attachment_id); $result = $this->wpdb->get_results( $this->wpdb->prepare($sql, $attachment_id), ARRAY_A ); $sizes = []; if ( !empty($result) ) { foreach ($result as $size) { $size_name = $size['size_name']; unset($size['size_name']); $sizes[$size_name] = $size; } } wp_cache_set($cache_key, $sizes, $this->cache_group); return $sizes; } /** * Get file meta * * @param int $post_id * @param string $key * @param mixed $default * @return mixed */ public function get_file_meta_value($value, $post_id, $key, $default = null) { if ( ud_get_stateless_media()->get('sm.use_postmeta') ) { $meta = get_post_meta($post_id, 'sm_cloud', []); return isset($meta[$key]) ? $meta[$key] : $default; } // Get values from the cache $key = sanitize_key($key); $value = $this->_get_file_meta_cache($post_id, $key, $found); if ( $found ) { return $value; } // Get values from the DB $sql = "SELECT meta_value FROM $this->file_meta WHERE post_id = %d AND meta_key = %s"; $data = $this->wpdb->get_var( $this->wpdb->prepare($sql, $post_id, $key) ); $value = null; if ( is_serialized( $data ) ) { // Don't attempt to unserialize data that wasn't serialized going in. $value = @unserialize( trim( $data ) ); } else { $value = $data; } $this->_set_file_meta_cache($post_id, $key, $value); return $value; } /** * Update file meta * * @param int $post_id * @param string $key * @param mixed $value * @return int */ public function update_file_meta($post_id, $key, $value) { $key = sanitize_key($key); // Update value in the DB $value = maybe_serialize( $value ); $file_meta_id = $this->get_file_meta_id($post_id, $key); if ( $file_meta_id ) { $this->wpdb->update( $this->file_meta, ['meta_value' => $value], ['id' => $file_meta_id], ); } else { $this->wpdb->insert( $this->file_meta, [ 'meta_key' => $key, 'meta_value' => $value, 'post_id' => $post_id, ]); $file_meta_id = $this->wpdb->insert_id; } $this->_delete_file_meta_key_cache($post_id, $key); return $file_meta_id; } /** * Get all the meta for the file * * @param mixed $meta * @param int $post_id * @return mixed */ public function get_file_meta($meta, $post_id) { $sql = "SELECT meta_key, meta_value FROM $this->file_meta WHERE post_id = %d"; $result = $this->wpdb->get_results( $this->wpdb->prepare($sql, $post_id), ARRAY_A ); $data = []; foreach ($result as $row) { $key = $row['meta_key']; $value = $row['meta_value']; if ( is_serialized( $value ) ) { // Don't attempt to unserialize data that wasn't serialized going in. $value = @unserialize( trim( $value ) ); } $data[$key] = $value; } return $data; } /** * Get file row ID by file name * * @param string $name * @return int | null */ public function remove_non_library_file($name) { return $this->wpdb->delete( $this->files, [ 'name' => $name, 'post_id' => null, ] ); } /** * Get all non-library files * * @param array $files * @param string $prefix * @return array | null */ public function get_non_library_files($files, $prefix = '') { if ( !empty($prefix) ) { $sql = $this->wpdb->prepare("SELECT name FROM $this->files WHERE post_id IS NULL AND name LIKE '%s'", $this->wpdb->esc_like($prefix) . '%'); } else { $sql = "SELECT name FROM $this->files WHERE post_id IS NULL"; } return $this->wpdb->get_col($sql); } } } } ================================================ FILE: lib/classes/class-dynamic-image-support.php ================================================ get( 'sm.dynamic_image_support', false ) == 'true'; // Legacy setting if (!$enabled) { $enabled = get_option('sm_on_fly', false); } if ($enabled) { $this->init_module(); } } /** * Initialize module */ private function init_module() { // Handle any other on fly generated media add_filter('image_make_intermediate_size', array($this, 'handle_on_fly')); } /** * Handle images on fly * f6a7dfd9 Anton Korotkov, 2 years ago (September 29th, 2015 6:09am) * @param $file * @return mixed */ public function handle_on_fly($file) { $client = ud_get_stateless_media()->get_client(); $upload_dir = wp_upload_dir(); $file_path = str_replace(trailingslashit($upload_dir['path']), '', $file); $file_info = @getimagesize($file); $mimeType = wp_check_filetype($file); if ($file_info) { $_metadata = array( 'width' => $file_info[0], 'height' => $file_info[1], 'object-id' => 'unknown', // we really don't know it 'source-id' => md5($file . ud_get_stateless_media()->get('sm.bucket')), 'file-hash' => md5($file) ); } $client->add_media(apply_filters('sm:item:on_fly:before_add', array_filter(array( 'name' => $file_path, 'absolutePath' => wp_normalize_path($file), 'cacheControl' => apply_filters('sm:item:cacheControl', ud_get_stateless_media()->get_default_cache_control(), $_metadata), 'contentDisposition' => null, 'mimeType' => $mimeType['type'], 'metadata' => $_metadata )))); return $file; } } } } ================================================ FILE: lib/classes/class-errors.php ================================================ null, 'notices' => null, ); /** * Dismiss action link is available or not. * * @var bool */ private $dismiss = true; /** * */ public function __construct( $args ) { parent::__construct( $args ); add_action( 'admin_notices', array( $this, 'admin_notices' ) ); add_action( 'wp_ajax_stateless_notice_dismiss', array( $this, 'dismiss_notices' ) ); add_action( 'wp_ajax_stateless_enable_notice_button_action', array( $this, 'stateless_enable_notice_button_action' ) ); } /** * Prevents adding duplicating messages * Some triggers may happen few times during site load (like 'switch_blog' hook) * adding the same message several times is not necessary * * @param string $collection * @param string $message */ private function add_message( &$collection, $message ) { $exiting_keys = array_column($collection, 'key'); if ( in_array( $message['key'], $exiting_keys ) ) { return; } $collection[] = $message; } /** * Add new message for admin notices * * @param string $message * @param string $type Values: 'error', 'message', 'warning' * @param string $translate Values: true, false * @author peshkov@UD */ public function add( $message, $type = 'error', $translate = true ) { switch( $type ) { case 'error': $this->add_message($this->errors, $message); break; case 'message': case 'warning': case 'notice': if(!is_array($message)){ $title = $translate ? sprintf( __( '%s has the following notice:', $this->domain ), esc_html($this->name) ) : sprintf( '%s has the following notice:', esc_html($this->name) ); $message = array( 'title' => $title, 'message' => $message, 'button' => null, ); } if(empty($message['key'])){ $message['key'] = md5( $message['title'] ); } $this->add_message($this->notices, $message); break; } } /** * Add footer link to specific ( errors|messages|wanrnings ) block * * @author peshkov@UD */ public function add_action_link( $link, $type = 'error' ) { switch( $type ) { case 'error': $this->action_links[ 'errors' ][] = $link; break; case 'message': case 'warning': case 'notice': $this->action_links[ 'notices' ][] = $link; break; } } /** * Determine if errors exist * * @author peshkov@UD */ public function has_errors() { return !empty( $this->errors ) ? true : false; } /** * Renders admin notes in case there are errors or notices on bootstrap init * * @author peshkov@UD */ public function admin_notices() { global $wp_version; wp_enqueue_style("stateless-error-style", ud_get_stateless_media()->path('static/styles/error-notice.css')); //enqueue dismiss js for ajax requests $script_path = \UsabilityDynamics\WP\Utility::path( 'static/scripts/ud-dismiss.js', 'url' ); wp_enqueue_script( "sateless-error-notice-js", ud_get_stateless_media()->path( 'static/scripts/error-notice.js', 'url' ), array( 'jquery' ) ); wp_enqueue_script( "ud-dismiss", $script_path, array( 'jquery' ) ); wp_localize_script( "ud-dismiss", "_ud_vars", array( "ajaxurl" => admin_url( 'admin-ajax.php' ), )); wp_localize_script( "sateless-error-notice-js", "stateless_error_notice_vars", array( "dismiss_nonce" => wp_create_nonce( 'stateless_notice_dismiss' ), "enable_action_nonce" => wp_create_nonce( 'stateless_enable_notice_button_action' ), )); //** Don't show the message if the user has no enough permissions. */ if ( ! function_exists( 'wp_get_current_user' ) ) { require_once( ABSPATH . 'wp-includes/pluggable.php' ); } $default_show = true; if ( empty( $this->args['type'] ) || ( $this->args['type'] == 'plugin' && !current_user_can( 'activate_plugins' ) ) || ( $this->args['type'] == 'theme' && !current_user_can( 'switch_themes' ) ) ) { $default_show = false; } //** Don't show the message if on a multisite and the user isn't a super user. */ if ( is_multisite() && ! is_super_admin() ) { $default_show = false; } $errors = apply_filters( 'ud:errors:admin_notices', $this->errors, $this->args ); $notices = apply_filters( 'stateless:notices:admin_notices', $this->notices, $this->args ); //** Errors Block */ if( $default_show && !empty( $errors ) && is_array( $errors ) ) { $message = '
  • ' . implode( '
  • ', $errors ) . '
'; $data = array( 'title' => sprintf( __( '%s is not active due to following errors:', $this->domain ), esc_html($this->name) ), 'class' => 'error', 'message' => $message, 'action_links' => !empty($this->action_links[ 'errors' ])?$this->action_links[ 'errors' ]:null, ); include ud_get_stateless_media()->path( '/static/views/error-notice.php', 'dir' ); } $has_notice = false; //** Determine if warning has been dismissed */ if ( ! empty( $notices ) && is_array( $notices ) ) { //** Warnings Block */ foreach ($notices as $notice ) { if ( get_option( 'dismissed_notice_' . $notice['key'] )){ continue; } // Check additional capabilities $capability = isset( $notice['capability'] ) && !empty( $notice['capability'] ) ? $notice['capability'] : null; if ( ( !$default_show && empty($capability) ) || ( !empty($capability) && !current_user_can($capability) ) ) { continue; } // Additional HTML classes $classes = []; if ( isset($notice['classes']) ) { $classes = $notice['classes']; if ( !is_array($classes) ) { $classes = [$classes]; } } $classes[] = 'notice'; $data = wp_parse_args($notice, array( 'title' => '', 'class' => implode(' ', $classes), 'message' => '', 'button' => '', 'button_link' => '#', 'key' => '', 'action_links' => $this->action_links[ 'notices' ], 'dismiss' => true, )); $button_capability = isset( $notice['button_capability'] ) && !empty( $notice['button_capability'] ) ? $notice['button_capability'] : null; if ( !empty($button_capability) && !current_user_can($button_capability) ) { $data['button'] = ''; } include ud_get_stateless_media()->path( '/static/views/error-notice.php', 'dir' ); $has_notice = true; } } } /** * dismiss the notice ajax callback * @throws \Exception */ public function dismiss_notices() { check_ajax_referer('stateless_notice_dismiss'); if ( !is_user_logged_in() ) { wp_send_json_error( array( 'error' => __( 'You are not allowed to do this action.', $this->domain ) ) ); } $response = array( 'success' => '0', 'error' => __( 'There was an error in request.', $this->domain ), ); $error = false; $option_key = isset($_POST['key']) ? sanitize_key($_POST['key']) : ''; if ( strpos($option_key, 'dismissed_') !== 0 ) { $response['error'] = __( 'Invalid key', $this->domain ); $error = true; } if ( !$error && update_option( $option_key, time() ) ) { do_action('wp_stateless_notice_dismissed', $option_key); $response['success'] = '1'; $response['error'] = null; } wp_send_json( $response ); } /** * Action for the stateless_enable_notice_button_action ajax callback * @throws \Exception */ public function stateless_enable_notice_button_action(){ check_ajax_referer('stateless_enable_notice_button_action'); if ( !is_user_logged_in() ) { wp_send_json_error( array( 'error' => __( 'You are not allowed to do this action.', $this->domain ) ) ); } $response = array( 'success' => '1', ); $error = false; if( empty($_POST['key']) ) { $response['success'] = '0'; $response['error'] = __( 'Invalid key', $this->domain ); } else{ $option_key = sanitize_key($_POST['key']); $compatibility = Module::get_module($option_key); if(!empty($compatibility['self']) && is_callable(array($compatibility['self'], 'enable_compatibility'))){ $response['success'] = $compatibility['self']->enable_compatibility(); } } wp_send_json( $response ); } /** * Check dismiss notice timestamp if greater than 24 hrs * * @param string $time * * @return bool */ public function check_dismiss_time( $time = '' ) { if( empty( $time ) ) { return true; } $current_time = time(); $diff = $current_time - 86400; if ( $diff > (int)$time ) { return true; } return false; } } } } ================================================ FILE: lib/classes/class-google-app-engine.php ================================================ is_mode' or 'ud_get_stateless_media()->get' if ( $value === 'disabled' ) { return $value; } if ( apply_filters('wp_stateless_is_app_engine', false) ) { return 'stateless'; } return $value; } /** * Make 'sm_mode' option readonly if we are running on Google App Engine * * @param \wpCloud\StatelessMedia\Settings $settingsObj */ public function after_settings_refresh($settingsObj) { if ( !is_a($settingsObj, 'wpCloud\StatelessMedia\Settings') ) { return; } if ( !apply_filters('wp_stateless_is_app_engine', false) ) { return; } $settingsObj->set('sm.readonly.mode', 'app_engine'); } /** * Add admin message if we are running on Google App Engine */ public function add_message() { if ( !apply_filters('wp_stateless_is_app_engine', false) ) { return; } ud_get_stateless_media()->errors->add(array( 'key' => 'stateless_app_engine_auto_mode', 'button' => 'View Settings', 'button_link' => admin_url('upload.php?page=stateless-settings'), 'title' => sprintf(__('Stateless Mode Enabled Automatically.', ud_get_stateless_media()->domain)), 'message' => sprintf(__('We detected that you are running Google App Engine. This platform does not allow you to save files locally, so we have automatically enabled Stateless mode. In this mode, your files will only be stored on Google Cloud Storage.', ud_get_stateless_media()->domain) ), ), 'notice'); } } } } ================================================ FILE: lib/classes/class-gs-client.php ================================================ bucket = $args['bucket']; $this->key_json = json_decode($args['key_json'], 1); // May be Loading Google SDK.... if (!class_exists('\Google\Client')) { include_once(ud_get_stateless_media()->path('lib/Google/vendor/autoload.php', 'dir')); } /* Initialize our client */ $this->client = new \Google\Client(); // We're supporting Google SDK 1.X version since // The plugins which also are using Google SDK may have its old version // what may cause conflicts // if (version_compare($this->client->getLibraryVersion(), '2.0', '<')) { // We should set the warning about potential issue // If Google SDK has different version with already included $this->_setWarning(); $wp_upload_dir = wp_upload_dir(); $dir = $wp_upload_dir['path']; $filename = md5(wp_generate_password()) . '.tmp'; $path = wp_normalize_path($dir . '/' . $filename); @file_put_contents($path, json_encode($this->key_json)); $cred = $this->client->loadServiceAccountJson($path, ['https://www.googleapis.com/auth/devstorage.full_control']); $this->client->setAssertionCredentials($cred); if ($this->client->getAuth()->isAccessTokenExpired()) { $this->client->getAuth()->refreshTokenWithAssertion($cred); } @unlink($path); } else { // May be delete warning transient if it was set $this->_deleteWarning(); $this->client->setAuthConfig($this->key_json); } if (isset($current_blog) && isset($current_blog->domain)) { $this->client->setApplicationName($current_blog->domain); } else { $this->client->setApplicationName(urlencode(str_replace(array('http://', 'https://'), '', get_bloginfo('url')))); } $this->client->setScopes(['https://www.googleapis.com/auth/devstorage.full_control']); // May be Loading Google SDK. Because some bad plugins may load their Google SDK with not included Google_Service_Storage. if (!class_exists('Google_Service_Storage')) { include_once(ud_get_stateless_media()->path('lib/Google/vendor/autoload.php', 'dir')); } /* Now, Initialize our Google Storage Service */ $this->service = new \Google\Service\Storage($this->client); } /** * Wrapper for listObjects() */ public function list_objects($options = array()) { $options = wp_parse_args($options, array( 'delimiter' => '', 'maxResults' => 1000, 'pageToken' => '', 'prefix' => '', 'projection' => 'noAcl', 'versions' => false )); return $this->service->objects->listObjects($this->bucket, $options); } /** * List all items page by page of maxResults * @param $bucket * @param array $options * @return mixed */ public function list_all_objects($options = array()) { $options = wp_parse_args($options, array( 'delimiter' => '', 'maxResults' => 1000, 'pageToken' => '', 'prefix' => '', 'projection' => 'noAcl', 'versions' => false )); $response = $this->service->objects->listObjects($this->bucket, $options); $this->temp_objects = array_merge($this->temp_objects, $response->getItems()); if (!empty($response->nextPageToken)) { $options['pageToken'] = $response->nextPageToken; return $this->list_all_objects($this->bucket, $options); } else { return $this->temp_objects; } } /** * Add/Update Media Object to Bucket * * https://stackoverflow.com/questions/26872851/resumable-uploading-to-google-cloud-storage-using-php-api * * @author peshkov@UD * @param array $args * @return bool */ public function add_media($args = array()) { try { set_time_limit(0); $args = wp_parse_args($args, array( 'use_root' => true, 'force' => false, 'name' => false, 'absolutePath' => false, 'mimeType' => 'image/jpeg', 'metadata' => array(), 'is_webp' => '', 'skipLocalCheck' => false, )); /* Be sure file exists. */ if (!$args['skipLocalCheck'] && !file_exists($args['absolutePath'])) { return new \WP_Error('sm_error', __('Unable to locate file on disk', ud_get_stateless_media()->domain)); } $object_id = isset($args['metadata']['object-id']) ? $args['metadata']['object-id'] : (isset($args['metadata']['child-of']) ? $args['metadata']['child-of'] : ""); $object_size = isset($args['metadata']['size']) ? $args['metadata']['size'] : ""; $args['name'] = apply_filters('wp_stateless_file_name', $args['name'], $args['use_root'], $object_id, $object_size); $args = apply_filters('wp_stateless_add_media_args', $args); $name = $args['name']; // If media exists we just return it if (!$args['force'] && $media = $this->media_exists($name)) { if ($media->getCacheControl() != $args['cacheControl']) { $media->setCacheControl($args['cacheControl']); $media = $this->service->objects->patch($this->bucket, $name, $media); } return get_object_vars($media); } $media = new \Google\Service\Storage\StorageObject(); $media->setName($name); $media->setMetadata($args['metadata']); if (isset($args['cacheControl'])) { $media->setCacheControl($args['cacheControl']); } if (isset($args['contentEncoding'])) { $media->setContentEncoding($args['contentEncoding']); } if (isset($args['contentDisposition'])) { $media->setContentDisposition($args['contentDisposition']); } // If chunk size is defined, we assume user needs the file to be sent by chunks // Otherwise, we send it directly if (defined('WP_STATELESS_MEDIA_UPLOAD_CHUNK_SIZE') && is_int(WP_STATELESS_MEDIA_UPLOAD_CHUNK_SIZE)) { $this->client->setDefer(true); $file_size = filesize($args['absolutePath']); $filetoupload = array('name' => $name, 'uploadType' => 'resumable'); $request = $this->service->objects->insert($this->bucket, $media, $filetoupload); $uploader = new \Google_Http_MediaFileUpload($this->client, $request, $args['mimeType'], null, true, WP_STATELESS_MEDIA_UPLOAD_CHUNK_SIZE); $uploader->setFileSize($file_size); $handle = fopen($args['absolutePath'], "rb"); $status = false; while (!$status && !feof($handle)) { $chunk = fread($handle, WP_STATELESS_MEDIA_UPLOAD_CHUNK_SIZE); $status = $uploader->nextChunk($chunk); } $media = false; if ($status != false) { $media = $status; } fclose($handle); // Reset to the client to execute requests immediately in the future. $this->client->setDefer(false); } else { $mediaOptions = array( 'data' => file_get_contents($args['absolutePath']), 'uploadType' => 'media', 'mimeType' => $args['mimeType'], ); if ( !defined('WP_STATELESS_SKIP_ACL_SET') || !WP_STATELESS_SKIP_ACL_SET) { $mediaOptions['predefinedAcl'] = 'bucketOwnerFullControl'; } $media = $this->service->objects->insert($this->bucket, $media, array_filter($mediaOptions)); } if ( !defined('WP_STATELESS_SKIP_ACL_SET') || !WP_STATELESS_SKIP_ACL_SET) { $this->mediaInsertACL($name, $media, $args); } } catch (Exception $e) { return new WP_Error('sm_error', $e->getMessage()); } return get_object_vars($media); } /** * Update Object ACL */ public function mediaInsertACL($name, $media = array(), $agrs = array()) { /* Make Media Public READ for all on success */ if (!empty($name)) { $acl = new \Google\Service\Storage\ObjectAccessControl(); $acl->setEntity('allUsers'); $acl->setRole('READER'); $acl = apply_filters('wp_stateless_media_acl', $acl, $name, $media, $agrs); $this->service->objectAccessControls->insert($this->bucket, $name, $acl); } } /** * Get or save media file * * @param $path * @param bool $save * @param bool $save_path * @return bool|\Google_Service_Storage_StorageObject|int */ public function get_media($path, $save = false, $save_path = false) { try { $media = $this->service->objects->get($this->bucket, $path); } catch (\Exception $e) { return false; } if (empty($media->id)) return false; if ($save && $save_path) { if (!file_exists($_dir = dirname($save_path))) { wp_mkdir_p($_dir); } return $this->client->getHttpClient()->get($media->getMediaLink(), ['sink' => $save_path])->getStatusCode(); } return $media; } /** * get or save media file * @param $path * @param bool $save * @param bool $save_path * @return bool|\Google_Service_Storage_StorageObject|int */ public function copy_media($path, $new_path) { try { $media = $this->service->objects->get($this->bucket, $path); $media = $this->service->objects->copy($this->bucket, $path, $this->bucket, $new_path, $media); $this->mediaInsertACL($new_path, $media); } catch (\Exception $e) { return false; } if (empty($media->id)) return false; return $media; } /** * get or save media file * @param $path * @param bool $save * @param bool $save_path * @return bool|\Google_Service_Storage_StorageObject|int */ public function move_media($path, $new_path) { try { $media = $this->copy_media($path, $new_path); $this->remove_media($path); } catch (\Exception $e) { return false; } if (empty($media->id)) return false; return $media; } /** * Check if media exists * @param $path * @return bool|object */ public function media_exists($path) { try { $media = $this->service->objects->get($this->bucket, $path); // Here we wanted to check if access allowed, but noticed it actually sets this ACL... Leaving it as is. @author korotkov@ud $this->service->objectAccessControls->get($this->bucket, $path, 'allUsers'); } catch (\Exception $e) { return false; } if (empty($media->id)) return false; return $media; } /** * Fired for every file remove action * * @author peshkov@UD * @param string $name * @param string $id * @param boolean $use_root * @param string $size * @param boolean $is_webp * @return bool */ public function remove_media($name, $id = "", $use_root = true, $size = "", $is_webp = false) { try { $name = apply_filters('wp_stateless_file_name', $name, $use_root, $id, $size); if ($is_webp && substr($name, -4) != "webp") $name .= ".webp"; $this->service->objects->delete($this->bucket, $name); } catch (Exception $e) { return new WP_Error('sm_error', $e->getMessage()); } return true; } /** * Tests connection to Google Storage * by trying to get passed bucket's data. * * @author peshkov@UD */ public function is_connected() { try { $this->service->buckets->get($this->bucket); } catch (Exception $e) { return $e; } return true; } /** * Determine if instance already exists and Return Instance * * @param array $args * * $args * @param string client_id * @param string service_account_name * @param string key_file_path * * @author peshkov@UD * @return \wpCloud\StatelessMedia\GS_Client */ public static function get_instance($args) { if (null === self::$instance) { try { if (empty($args['bucket'])) { throw new Exception(__('Bucket parameter must be provided.')); } $json = "{}"; if (!empty($args['key_json'])) { $json = json_decode($args['key_json']); } if (!$json || !property_exists($json, 'private_key')) { throw new Exception(__('Service Account JSON is invalid.')); } self::$instance = new self($args); } catch (Exception $e) { return new WP_Error('sm_error', $e->getMessage()); } } return self::$instance; } /** * Set warning about potential conflict with Google SDK * * @since 2.0.1 */ private function _setWarning() { $reflector = new \ReflectionClass('Google_Client'); $pluginBasename = wp_normalize_path(plugin_basename($reflector->getFileName())); // Check if get_plugins() function exists. This is required on the front end of the // site, since it is in a file that is normally only loaded in the admin. if (!function_exists('get_plugins')) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } $pluginBasenameParts = explode('/', $pluginBasename); $pluginName = __("UNDEFINED", ud_get_stateless_media()->domain); foreach (get_plugins() as $path => $meta) { if (strpos($path, trailingslashit($pluginBasenameParts[0])) === 0) { $pluginName = $meta['Name']; } }; $error = sprintf( __("%s plugin may have potential Google SDK version conflicts with %s plugin. %s is using Google SDK %s, when %s loads old Google SDK version %s.", ud_get_stateless_media()->domain), "" . 'WP-Stateless' . "", "" . $pluginName . "", 'WP-Stateless', "v2.0", $pluginName, "v" . \Google\Client::LIBVER . "" ); set_transient("wp_stateless_google_sdk_conflict", $error); } /** * Removes Warning if it exists * */ private function _deleteWarning() { delete_transient("wp_stateless_google_sdk_conflict"); } } } } ================================================ FILE: lib/classes/class-gs-stream-wrapper.php ================================================ _openPath($path); // if root dir if (empty($this->file)) { $stats = []; // equivalent to 40777 and 40444 in octal if ($is_writable = $this->bucket->isWritable()) { $stats['mode'] = $is_writable ? self::DIRECTORY_WRITABLE_MODE : self::DIRECTORY_READABLE_MODE; return $this->makeStatArray($stats); } } return parent::url_stat($path, $flags); } catch (\Exception $e) { return false; } } /** * Parse the URL and set protocol, filename and bucket. * * @param string $path URL to open * @return StorageClient */ private function _openPath($path) { $url = (array) parse_url($path) + [ 'scheme' => '', 'path' => '', 'host' => '' ]; $this->protocol = $url['scheme']; $this->file = ltrim($url['path'], '/'); $client = self::getClient($this->protocol); $this->bucket = $client->bucket($url['host']); return $client; } /** * Register a StreamWrapper for reading and writing to Google Storage * * @param StorageClient $client The StorageClient configuration to use. * @param string $protocol The name of the protocol to use. **Defaults to** * `gs`. * @throws \RuntimeException */ public static function register(StorageClient $client, $protocol = null) { $protocol = $protocol ?: self::DEFAULT_PROTOCOL; // we are calling parents register function because only it can set parents pirvate ::$clients property. // we are only calling it to set $clients property. parent::register($client, $protocol); // unregistering the wrapper so that we can register wrapper with our class. stream_wrapper_unregister($protocol); // registering wrapper with our wpCloud\StatelessMedia\StreamWrapper return stream_wrapper_register($protocol, StreamWrapper::class, STREAM_IS_URL); } /** * Returns the associative array that a `stat()` response expects using the * provided stats. Defaults the remaining fields to 0. * * @param array $stats Sparse stats entries to set. * @return array */ private function makeStatArray($stats) { return array_merge( array_fill_keys([ 'dev', 'ino', 'mode', 'nlink', 'uid', 'gid', 'rdev', 'size', 'atime', 'mtime', 'ctime', 'blksize', 'blocks' ], 0), $stats ); } /** * @param $path * @param $option * @param $value * @return bool */ public function stream_metadata($path, $option, $value) { return false; } } } } ================================================ FILE: lib/classes/class-helper.php ================================================ Name == $theme_name) { return true; } $parent_theme = $theme->parent(); if ( is_a($parent_theme, 'WP_Theme') && $parent_theme->Name == $theme_name ) { return true; } return false; } /** * Checks if plugin is active. */ public static function get_active_plugins() { $active_plugins = []; // If multisite then check if plugin is network active if ( is_multisite() ) { $active_plugins = (array)get_site_option('active_sitewide_plugins', []); $active_plugins = array_keys($active_plugins); // If we are in network admin then return, unless it will get data from main site. if ( is_network_admin() ) { return $active_plugins; } } return array_merge( $active_plugins, (array)get_option('active_plugins', []) ); } /** * Convert array to objects. * * @param array $array * * @return array */ public static function array_of_objects($array) { return array_map(function($item) { return (object)$item; }, $array); } /** * Writes to error log. * * @param mixed $data */ public static function log($data, $json = false) { if (!WP_DEBUG) { return; } if ( is_array($data) || is_object($data) || !is_string($data) ) { if ( $json ) { error_log( json_encode($data) ); } else { error_log( print_r($data, true) ); } return; } error_log($data); } /** * Writes debug to error log. * * @param mixed $data */ public static function debug($data, $json = false) { self::log($data, $json); } } } ================================================ FILE: lib/classes/class-logger.php ================================================ */ class Logger { /** * @var string */ const VERSION = '4.1.0'; /** * @var string */ const HEADER_NAME = 'X-ChromeLogger-Data'; /** * @var string */ const BACKTRACE_LEVEL = 'backtrace_level'; /** * @var string */ const LOG = 'log'; /** * @var string */ const WARN = 'warn'; /** * @var string */ const ERROR = 'error'; /** * @var string */ const GROUP = 'group'; /** * @var string */ const INFO = 'info'; /** * @var string */ const GROUP_END = 'groupEnd'; /** * @var string */ const GROUP_COLLAPSED = 'groupCollapsed'; /** * @var string */ const TABLE = 'table'; /** * @var string */ protected $_php_version; /** * @var int */ protected $_timestamp; /** * @var array */ protected $_json = array( 'version' => self::VERSION, 'columns' => array( 'log', 'backtrace', 'type' ), 'rows' => array() ); /** * @var array */ protected $_backtraces = array(); /** * @var bool */ protected $_error_triggered = false; /** * @var array */ protected $_settings = array( self::BACKTRACE_LEVEL => 1 ); /** * @var ChromePhp */ protected static $_instance; /** * Prevent recursion when working with objects referring to each other * * @var array */ protected $_processed = array(); /** * constructor */ private function __construct() { $this->_php_version = phpversion(); $this->_timestamp = $this->_php_version >= 5.1 ? sanitize_text_field($_SERVER[ 'REQUEST_TIME' ]) : time(); $this->_json[ 'request_uri' ] = sanitize_text_field($_SERVER[ 'REQUEST_URI' ]); } /** * gets instance of this class * * @return ChromePhp */ public static function getInstance() { if( self::$_instance === null ) { self::$_instance = new self(); } return self::$_instance; } /** * logs a variable to the console * * @param mixed $data,... unlimited OPTIONAL number of additional logs [...] * @return void */ public static function log() { $args = func_get_args(); return self::_log( '', $args ); } /** * logs a warning to the console * * @param mixed $data,... unlimited OPTIONAL number of additional logs [...] * @return void */ public static function warn() { $args = func_get_args(); return self::_log( self::WARN, $args ); } /** * logs an error to the console * * @param mixed $data,... unlimited OPTIONAL number of additional logs [...] * @return void */ public static function error() { $args = func_get_args(); return self::_log( self::ERROR, $args ); } /** * sends a group log * * @param string value */ public static function group() { $args = func_get_args(); return self::_log( self::GROUP, $args ); } /** * sends an info log * * @param mixed $data,... unlimited OPTIONAL number of additional logs [...] * @return void */ public static function info() { $args = func_get_args(); return self::_log( self::INFO, $args ); } /** * sends a collapsed group log * * @param string value */ public static function groupCollapsed() { $args = func_get_args(); return self::_log( self::GROUP_COLLAPSED, $args ); } /** * ends a group log * * @param string value */ public static function groupEnd() { $args = func_get_args(); return self::_log( self::GROUP_END, $args ); } /** * sends a table log * * @param string value */ public static function table() { $args = func_get_args(); return self::_log( self::TABLE, $args ); } /** * internal logging call * * @param string $type * @return void */ protected static function _log( $type, array $args ) { // nothing passed in, don't do anything if( count( $args ) == 0 && $type != self::GROUP_END ) { return; } $logger = self::getInstance(); $logger->_processed = array(); $logs = array(); foreach( $args as $arg ) { $logs[] = $logger->_convert( $arg ); } $backtrace = debug_backtrace( false ); $level = $logger->getSetting( self::BACKTRACE_LEVEL ); $backtrace_message = 'unknown'; if( isset( $backtrace[ $level ][ 'file' ] ) && isset( $backtrace[ $level ][ 'line' ] ) ) { $backtrace_message = $backtrace[ $level ][ 'file' ] . ' : ' . $backtrace[ $level ][ 'line' ]; } $logger->_addRow( $logs, $backtrace_message, $type ); } /** * converts an object to a better format for logging * * @param Object * @return array */ protected function _convert( $object ) { // if this isn't an object then just return it if( !is_object( $object ) ) { return $object; } //Mark this object as processed so we don't convert it twice and it //Also avoid recursion when objects refer to each other $this->_processed[] = $object; $object_as_array = array(); // first add the class name $object_as_array[ '___class_name' ] = get_class( $object ); // loop through object vars $object_vars = get_object_vars( $object ); foreach( $object_vars as $key => $value ) { // same instance as parent object if( $value === $object || in_array( $value, $this->_processed, true ) ) { $value = 'recursion - parent object [' . get_class( $value ) . ']'; } $object_as_array[ $key ] = $this->_convert( $value ); } $reflection = new ReflectionClass( $object ); // loop through the properties and add those foreach( $reflection->getProperties() as $property ) { // if one of these properties was already added above then ignore it if( array_key_exists( $property->getName(), $object_vars ) ) { continue; } $type = $this->_getPropertyKey( $property ); if( $this->_php_version >= 5.3 ) { $property->setAccessible( true ); } try { $value = $property->getValue( $object ); } catch ( ReflectionException $e ) { $value = 'only PHP 5.3 can access private/protected properties'; } // same instance as parent object if( $value === $object || in_array( $value, $this->_processed, true ) ) { $value = 'recursion - parent object [' . get_class( $value ) . ']'; } $object_as_array[ $type ] = $this->_convert( $value ); } return $object_as_array; } /** * takes a reflection property and returns a nicely formatted key of the property name * * @param ReflectionProperty * @return string */ protected function _getPropertyKey( ReflectionProperty $property ) { $static = $property->isStatic() ? ' static' : ''; if( $property->isPublic() ) { return 'public' . $static . ' ' . $property->getName(); } if( $property->isProtected() ) { return 'protected' . $static . ' ' . $property->getName(); } if( $property->isPrivate() ) { return 'private' . $static . ' ' . $property->getName(); } } /** * adds a value to the data array * * @var mixed * @return void */ protected function _addRow( array $logs, $backtrace, $type ) { // if this is logged on the same line for example in a loop, set it to null to save space if( in_array( $backtrace, $this->_backtraces ) ) { $backtrace = null; } // for group, groupEnd, and groupCollapsed // take out the backtrace since it is not useful if( $type == self::GROUP || $type == self::GROUP_END || $type == self::GROUP_COLLAPSED ) { $backtrace = null; } if( $backtrace !== null ) { $this->_backtraces[] = $backtrace; } $row = array( $logs, $backtrace, $type ); $this->_json[ 'rows' ][] = $row; $this->_writeHeader( $this->_json ); } protected function _writeHeader( $data ) { header( self::HEADER_NAME . ': ' . $this->_encode( $data ) ); } /** * encodes the data to be sent along with the request * * @param array $data * @return string */ protected function _encode( $data ) { if ( function_exists('mb_convert_encoding') ) { $encoded = json_encode($data); if ( $encoded !== false ) { $utf8 = mb_convert_encoding($encoded, 'UTF-8', 'UTF-8'); if ($utf8 !== false) { return base64_encode($utf8); } } } return false; } /** * adds a setting * * @param string key * @param mixed value * @return void */ public function addSetting( $key, $value ) { $this->_settings[ $key ] = $value; } /** * add ability to set multiple settings in one call * * @param array $settings * @return void */ public function addSettings( array $settings ) { foreach( $settings as $key => $value ) { $this->addSetting( $key, $value ); } } /** * gets a setting * * @param string key * @return mixed */ public function getSetting( $key ) { if( !isset( $this->_settings[ $key ] ) ) { return null; } return $this->_settings[ $key ]; } } } } ================================================ FILE: lib/classes/class-migrator.php ================================================ path = ud_get_stateless_media()->path('static/migrations', 'dir'); $this->_init_hooks(); } /** * Initializes the needed hooks */ private function _init_hooks() { add_action( 'init', [$this, 'show_messages'] ); add_action( 'wp_stateless_batch_task_started', [$this, 'migration_started'], 10, 2 ); add_action( 'wp_stateless_batch_task_failed', [$this, 'migration_failed'], 10, 3 ); add_action( 'wp_stateless_batch_task_finished', [$this, 'migration_finished'], 10, 2 ); add_filter( 'wp_stateless_batch_action_start', [$this, 'start_migration'], 10, 2); add_action( 'wp_stateless_notice_dismissed', [$this, 'notice_dismissed'], 10, 1 ); add_filter( 'wp_stateless_get_migrations', [$this, 'get_migrations']); } /** * Get migration ID from file name * * @param string $file * @return string */ private function _file_to_id($file) { return pathinfo($file, PATHINFO_FILENAME); } /** * Get migration ID from class name * * @param string $class * @return string */ private function _class_to_id($class) { return str_replace('Migration_', '', $class); } /** * Get migration class name from ID * * @param string $id * @return string */ private function _id_to_class($id) { return "\Migration_$id"; } /** * Get migration file name from ID * * @param string $id * @return string */ private function _id_to_file($id) { return "$this->path/$id.php"; } /** * Compares the list of files in the migrations directory with the list of finished migrations * Finds the oldest migration that has not been run yet * * @return array */ private function _get_migration_ids() { if ( !is_dir($this->path) ) { return []; } $ids = []; $files = scandir($this->path, SCANDIR_SORT_ASCENDING); foreach ($files as $file) { $extension = pathinfo($file, PATHINFO_EXTENSION); if ( $extension !== 'php' ) { continue; } $ids[] = $this->_file_to_id($file); } return $ids; } /** * Returns the migration object * * @param string $id * @return wpCloud\StatelessMedia\Batch\Migration * @throws \Exception */ private function _get_object($id) { $class = $this->_id_to_class($id); if ( !class_exists($class) ) { require_once $this->_id_to_file($id); } $object = new $class(); if ( !is_a($object, '\wpCloud\StatelessMedia\Batch\Migration') ) { throw new \Exception("$class is not a valid migration"); } $object->init_state(); return $object; } /** * Checks if any migrations required and sets or removes global flag * * @param array $migrations|null */ private function _check_required_migrations($migrations = null) { if ( empty($migrations) ) { $migrations = apply_filters('wp_stateless_get_migrations', []); } $require_migrations = false; foreach ($migrations as $id => $migration) { if ( !in_array( $migration['status'], [self::STATUS_FINISHED, self::STATUS_SKIPPED] ) ) { $require_migrations = true; break; } } if ( $require_migrations ) { update_option(self::MIGRATIONS_NOTIFY_KEY, self::NOTIFY_REQUIRE); delete_option(self::MIGRATIONS_NOTIFY_DISMISSED_KEY); } else { $notify = get_option(self::MIGRATIONS_NOTIFY_KEY, false); empty($notify) ? delete_option(self::MIGRATIONS_NOTIFY_KEY) : update_option(self::MIGRATIONS_NOTIFY_KEY, self::NOTIFY_FINISHED); } } /** * Dismisses the migration notice * * @param string $option_name */ public function notice_dismissed($option_name) { delete_option(self::MIGRATIONS_NOTIFY_KEY); } /** * Generates an updated list of migrations. * Checks which migrations should run. * Sets global options to display the requirement to run migrations. * * Is called by Bootstrap object during version upgrade on 'plugins_loaded' hook. */ public function migrate() { // Rebuild the migrations list and state according to the new version $ids = $this->_get_migration_ids(); $migrations = apply_filters('wp_stateless_get_migrations', []); $existing = array_keys($migrations); foreach ($ids as $id) { if ( in_array($id, $existing) ) { continue; } try { $object = $this->_get_object($id); $skip = !$object->should_run(); $migrations[$id] = [ 'description' => $object->get_description(), 'started' => '', 'finished' => '', 'status' => $object->should_run() ? self::STATUS_PENDING : self::STATUS_SKIPPED, 'message' => '', ]; } catch (\Throwable $e) { Helper::log("Unable to initialize migration $id: " . $e->getMessage()); } } krsort($migrations); update_option(self::MIGRATIONS_KEY, $migrations); // Check if we need to run any migrations $this->_check_required_migrations($migrations); } /** * Outputs the message that migrations are required */ public function show_messages() { if ( is_network_admin() ) { return; } $is_running = BatchTaskManager::instance()->is_processing() || BatchTaskManager::instance()->is_paused(); $notify = get_option(self::MIGRATIONS_NOTIFY_KEY, false); if ( $notify ) { ud_get_stateless_media()->errors->add([ 'title' => __('WP-Stateless: Data Optimization Required', ud_get_stateless_media()->domain), 'message' => __('WP-Stateless has been updated! Your WP-Stateless data must now be optimized. Please backup your database before proceeding with the optimization.', ud_get_stateless_media()->domain), 'button' => __('Optimize Data', ud_get_stateless_media()->domain), 'button_link' => admin_url('upload.php?page=stateless-settings&tab=stless_status_tab#migration-action'), 'key' => 'migrations-required', 'dismiss' => false, 'classes' => ($notify == self::NOTIFY_REQUIRE) && !$is_running ? '' : 'hidden', ], 'warning'); ud_get_stateless_media()->errors->add([ 'title' => __('WP-Stateless: Data Optimization in Progress', ud_get_stateless_media()->domain), 'message' => __('A background process is optimizing your WP-Stateless data. Please do not upload, change, or delete your media while this update is underway.', ud_get_stateless_media()->domain), 'button' => __('View Progress', ud_get_stateless_media()->domain), 'button_link' => admin_url('upload.php?page=stateless-settings&tab=stless_status_tab#migration-action'), 'key' => 'migrations-running', 'dismiss' => false, 'classes' => $is_running ? '' : 'hidden', 'capability' => 'upload_files', 'button_capability' => 'manage_options', ], 'warning'); ud_get_stateless_media()->errors->add([ 'title' => __('WP-Stateless: Data Optimization Complete', ud_get_stateless_media()->domain), 'message' => __('Your WP-Stateless data has been optimized. You can now continue using your media as usual.', ud_get_stateless_media()->domain), 'key' => 'migrations-finished', 'classes' => ($notify == self::NOTIFY_FINISHED) && !$is_running ? '' : 'hidden', ], 'warning'); } } /** * Mark migration as started * * @param string $class * @param string $file */ public function migration_started($class, $file) { $migrations = apply_filters('wp_stateless_get_migrations', []); $id = $this->_file_to_id($file); if ( array_key_exists($id, $migrations) ) { $migrations[$id]['status'] = self::STATUS_RUNNING; $migrations[$id]['started'] = time(); $migrations[$id]['finished'] = ''; update_option(self::MIGRATIONS_KEY, $migrations); } } /** * Mark migration as failed and check other migrations * * @param string $class * @param string $file * @param string $message */ public function migration_failed($class, $file, $message) { $migrations = apply_filters('wp_stateless_get_migrations', []); $id = $this->_file_to_id($file); if ( array_key_exists($id, $migrations) ) { $migrations[$id]['status'] = self::STATUS_FAILED; $migrations[$id]['message'] = $message; update_option(self::MIGRATIONS_KEY, $migrations); $this->_check_required_migrations($migrations); } } /** * Mark migration as completed and check other migrations * * @param string $class */ public function migration_finished($class, $state) { $migrations = apply_filters('wp_stateless_get_migrations', []); $id = $this->_class_to_id($class); if ( array_key_exists($id, $migrations) ) { $migrations[$id]['status'] = self::STATUS_FINISHED; $migrations[$id]['finished'] = time(); update_option(self::MIGRATIONS_KEY, $migrations); $this->_check_required_migrations($migrations); } // When started from the UI, run next migration if needed if ( !empty($state['queue']) && is_array($state['queue']) ) { $index = array_search($id, $state['queue']); $next_index = false; if ( $index !== false && isset($state['queue'][$index + 1]) ) { $next_index = $state['queue'][$index + 1]; } if ( $next_index === false ) { return; } $params = [ 'is_migration' => true, 'id' => $next_index, 'email' => $state['email'], 'queue' => implode(':', $state['queue']), 'action' => 'start', ]; apply_filters("wp_stateless_batch_action_start", [], $params); } } /** * Run migration * * @param array $state * @param array $params * @return array * @throws \Exception */ public function start_migration($state, $params) { // Possibly not migration action if ( empty($params['is_migration']) || empty($params['id']) || !$params['is_migration'] ) { return $state; } $id = $params['id']; $migrations = apply_filters('wp_stateless_get_migrations', []); // Unknown migration? if ( !array_key_exists($id, $migrations) ) { return $state; } $class = $this->_id_to_class($id); $file = $this->_id_to_file($id); // Still possibly not migration action if ( !file_exists($file) ) { return $state; } if ( $migrations[$id]['status'] !== self::STATUS_PENDING && !isset($params['force']) ) { Helper::log("Migration $id is already started or finished. Status: " . $migrations[$id]['status']); return $state; } if ( BatchTaskManager::instance()->is_running() ) { Helper::log('Another batch task is already running'); return $state; } $email = $params['email'] ?? ''; $queue = isset($params['queue']) ? explode(':', $params['queue']) : []; BatchTaskManager::instance()->start_task($class, $file, $email, $queue); return apply_filters('wp_stateless_batch_state', $state, []); } /** * Get the list of migrations * * @param array $migrations * @return array */ public function get_migrations($migrations) { // We need to omit the cache and get the data directly from the db global $wpdb; $sql = $wpdb->prepare("SELECT option_value FROM $wpdb->options WHERE option_name = '%s' LIMIT 1", self::MIGRATIONS_KEY); $migrations = $wpdb->get_var($sql); return empty($migrations) ? [] : maybe_unserialize($migrations); } } ================================================ FILE: lib/classes/class-module.php ================================================ '', 'self' => '', 'title' => '', 'enabled' => false, 'description' => '', 'is_constant' => false, 'is_network' => false, 'is_plugin_active' => false, 'is_internal' => false, ); self::$modules[$args['id']] = wp_parse_args($args, $defaults); } /** * Return all the registered modules. * Used in admin_init in bootstrap class as localize_script. */ public static function get_modules() { return self::$modules; } /** * Return all the registered modules. * Used in admin_init in bootstrap class as localize_script. */ public static function get_module($id) { if (!empty(self::$modules[$id])) { return self::$modules[$id]; } return false; } /** * Handles saving module data. * Enable or disable modules from Compatibility tab. */ public function save_modules() { if (isset($_POST['action']) && $_POST['action'] == 'stateless_modules' && wp_verify_nonce($_POST['_smnonce'], 'wp-stateless-modules')) { $modules = !empty($_POST['stateless-modules']) ? $_POST['stateless-modules'] : array(); $modules = apply_filters('stateless::modules::save', $modules); if (is_network_admin()) { update_site_option('stateless-modules', $modules); } else { update_option('stateless-modules', $modules, true); } wp_redirect($_POST['_wp_http_referer']); } } /** * Check if 'Compatibility' tab should be visible. */ public function compatibility_tab_visible($visible) { return !empty(self::$modules); } /** * Outputs 'Compatibility' tab content on the settings page. * */ public function tab_content() { $modules = self::get_modules(); foreach ($modules as $id => $module) { if ( !$module['is_internal'] ) { unset($modules[$id]); } } $modules = Helper::array_of_objects( $modules ); include ud_get_stateless_media()->path('static/views/compatibility-tab.php', 'dir'); } } } ================================================ FILE: lib/classes/class-settings.php ================================================ array('WP_STATELESS_MEDIA_MODE', 'ephemeral'), 'body_rewrite' => array('WP_STATELESS_MEDIA_BODY_REWRITE', 'false'), 'body_rewrite_types' => array('WP_STATELESS_MEDIA_BODY_REWRITE_TYPES', 'jpg jpeg png gif pdf'), 'bucket' => array('WP_STATELESS_MEDIA_BUCKET', ''), 'root_dir' => array('WP_STATELESS_MEDIA_ROOT_DIR', ['/%date_year/date_month%/', '/sites/%site_id%/%date_year/date_month%/']), 'key_json' => array('WP_STATELESS_MEDIA_JSON_KEY', ''), 'cache_control' => array('WP_STATELESS_MEDIA_CACHE_CONTROL', ''), 'delete_remote' => array('WP_STATELESS_MEDIA_DELETE_REMOTE', 'true'), 'custom_domain' => array('WP_STATELESS_MEDIA_CUSTOM_DOMAIN', ''), 'organize_media' => array('', 'true'), 'hashify_file_name' => array(['WP_STATELESS_MEDIA_HASH_FILENAME' => 'WP_STATELESS_MEDIA_CACHE_BUSTING'], 'false'), 'dynamic_image_support' => array(['WP_STATELESS_MEDIA_ON_FLY' => 'WP_STATELESS_DYNAMIC_IMAGE_SUPPORT'], 'false'), 'status_email_type' => array('', 'true'), 'status_email_address' => array('', ''), 'use_postmeta' => array('WP_STATELESS_POSTMETA', ['false', '']), 'use_api_siteurl' => array('WP_STATELESS_API_SITEURL', ['WP_HOME', '']), ); private $network_only_settings = array( 'hide_settings_panel' => array('WP_STATELESS_MEDIA_HIDE_SETTINGS_PANEL', false), 'hide_setup_assistant' => array('WP_STATELESS_MEDIA_HIDE_SETUP_ASSISTANT', false), ); private $strings = array( 'network' => 'Currently configured via Network Settings.', 'constant' => 'Currently configured via a constant.', 'environment' => 'Currently configured via an environment variable.', ); /** * * Settings constructor. * @param null $bootstrap */ public function __construct($bootstrap = null) { $this->bootstrap = $bootstrap ? $bootstrap : ud_get_stateless_media(); // Defile the main plugin file $realpath = realpath( __DIR__ . '/../..'); $this->plugin_file = basename( $realpath ) . '/wp-stateless-media.php'; /* Add 'Settings' link for SM plugin on plugins page. */ $_basename = plugin_basename( $this->bootstrap->boot_file ); parent::__construct( array( 'store' => 'options', 'format' => 'json', 'data' => array( 'sm' => array() ) )); add_action('activated_plugin', array( $this, 'check_setup' )); add_action('admin_notices', array( $this, 'documentation_message' ), 1); // Setting sm variable $this->refresh(); $this->set('page_url.stateless_setup', $this->bootstrap->get_settings_page_url('?page=stateless-setup')); $this->set('page_url.stateless_settings', $this->bootstrap->get_settings_page_url('?page=stateless-settings')); /** Register options */ add_action( 'init', array( $this, 'init' ), 3 ); // additional links on plugins page add_filter( 'plugin_action_links', array( $this, 'plugin_action_links' ), 10, 2); add_filter( 'network_admin_plugin_action_links', array( $this, 'plugin_action_links' ), 10, 2); add_filter( 'plugin_row_meta', array( $this, 'plugin_row_meta' ), 10, 2 ); // apply wildcard to root dir. add_filter( 'wp_stateless_handle_root_dir', array( $this, 'root_dir_wildcards' ), 10, 3); // Parse root dir by wildcards add_filter( 'wp_stateless_unhandle_root_dir', array( $this, 'parse_root_dir_wildcards' ), 10, 3); // Settings page content add_action('wp_stateless_settings_tab_content', array($this, 'settings_tab_content')); add_action('wp_stateless_processing_tab_content', array($this, 'processing_tab_content')); } /** * Init */ public function init(){ $this->save_media_settings(); add_action('admin_menu', array( $this, 'admin_menu' )); /** * Manage specific Network Settings */ if( is_network_admin() ) { add_action( 'network_admin_menu', array( $this, 'network_admin_menu' )); } $site_url = parse_url( site_url() ); $site_url['path'] = isset($site_url['path']) ? $site_url['path'] : ''; $this->wildcards = array( 'sites' => [ 'sites', __("sites", $this->bootstrap->domain), __("Sites uses for multisite.", $this->bootstrap->domain), ], '%site_id%' => [ get_current_blog_id(), __("site id", $this->bootstrap->domain), __("Site ID, for example 1.", $this->bootstrap->domain), ], '%site_url%' => [ trim( $site_url['host'] . $site_url['path'], '/ ' ), __("site url", $this->bootstrap->domain), __("Site URL, for example example.com/site-1.", $this->bootstrap->domain), ], '%site_url_host%' => [ trim( $site_url['host'], '/ ' ), __("host name", $this->bootstrap->domain), __("Host name, for example example.com.", $this->bootstrap->domain), ], '%site_url_path%' => [ trim( $site_url['path'], '/ ' ), __("site path", $this->bootstrap->domain), __("Site path, for example site-1.", $this->bootstrap->domain), ], '%date_year/date_month%' => [ date('Y').'/'.date('m'), __("year and monthnum", $this->bootstrap->domain), __("The year of the post, four digits, for example 2004. Month of the year, for example 05", $this->bootstrap->domain), "\d{4}\/\d{2}" ] ); } /** * Refresh settings */ public function refresh() { $this->set( "sm.readonly", []); $google_app_key_file = getenv('GOOGLE_APPLICATION_CREDENTIALS') ?: getenv('GOOGLE_APPLICATION_CREDENTIALS'); foreach ($this->settings as $option => $array) { $value = ''; $_option = 'sm_' . $option; $constant = $array[0]; // Constant name $default = is_array($array[1]) ? $array[1] : array($array[1], $array[1]); // Default value // Getting settings $value = get_option($_option, $default[0]); if ($option == 'body_rewrite_types' && empty($value) && !is_multisite()) { $value = $default[0]; } if ($option == 'hashify_file_name' && in_array($this->get("sm.mode"), array( 'stateless', 'ephemeral' ) )) { $value = true; } // If constant is set then override by constant if(is_array($constant)){ foreach($constant as $old_const => $new_const){ if(defined($new_const)){ $value = constant($new_const); $this->set( "sm.readonly.{$option}", "constant" ); break; } if(is_string($old_const) && defined($old_const)){ $value = constant($old_const); $this->bootstrap->errors->add( array( 'key' => $new_const, 'title' => sprintf( __( "%s: Deprecated Notice (%s)", $this->bootstrap->domain ), $this->bootstrap->name, $new_const ), 'message' => sprintf(__("%s constant is deprecated, please use %s instead.", $this->bootstrap->domain), $old_const, $new_const), ), 'notice' ); $this->set( "sm.readonly.{$option}", "constant" ); break; } } } elseif(defined($constant)){ $value = constant($constant); $this->set( "sm.readonly.{$option}", "constant" ); } // Getting network settings if(is_multisite() && $option != 'organize_media' && !$this->get( "sm.readonly.{$option}")){ $network = get_site_option( $_option, $default[1] ); // If network settings available then override by network settings. if($network || is_network_admin()){ $value = $network; if(!is_network_admin()) $this->set( "sm.readonly.{$option}", "network" ); } } // Converting to string true false for angular. if(is_bool($value)){ $value = $value === true ? "true" : "false"; } $this->set( "sm.$option", $value); } // Network only settings, to hide settings page foreach ($this->network_only_settings as $option => $array) { $value = ''; $_option = 'sm_' . $option; $constant = $array[0]; // Constant name $default = $array[1]; // Default value // If constant is set then override by constant if(is_array($constant)){ foreach($constant as $old_const => $new_const){ if(defined($new_const)){ $value = constant($new_const); break; } if(is_string($old_const) && defined($old_const)){ $value = constant($old_const); trigger_error(__(sprintf("%s constant is deprecated, please use %s instead.", $old_const, $new_const)), E_USER_WARNING); break; } } } elseif(defined($constant)){ $value = constant($constant); } // Getting network settings elseif(is_multisite()){ $value = get_site_option( $_option, $default ); } // Converting to string true false for angular. if(is_bool($value)){ $value = $value === true ? "true" : "false"; } $this->set( "sm.$option", $value); } /** * JSON key file path */ /* Use constant value for JSON key file path, if set. */ if (defined('WP_STATELESS_MEDIA_KEY_FILE_PATH') || $google_app_key_file !== false) { /* Maybe fix the path to p12 file. */ $key_file_path = (defined('WP_STATELESS_MEDIA_KEY_FILE_PATH')) ? WP_STATELESS_MEDIA_KEY_FILE_PATH : $google_app_key_file; if( !empty( $key_file_path ) ) { $upload_dir = wp_upload_dir(); /* Check if file exists */ switch( true ) { /* Determine if default path is correct */ case (file_exists($key_file_path)): /* Path is correct. Do nothing */ break; /* Look using WP root. */ case (file_exists( ABSPATH . $key_file_path ) ): $key_file_path = ABSPATH . $key_file_path; break; /* Look in wp-content dir */ case (file_exists( WP_CONTENT_DIR . $key_file_path ) ): $key_file_path = WP_CONTENT_DIR . $key_file_path; break; /* Look in uploads dir */ case (file_exists( wp_normalize_path( $upload_dir[ 'basedir' ] ) . '/' . $key_file_path ) ): $key_file_path = wp_normalize_path( $upload_dir[ 'basedir' ] ) . '/' . $key_file_path; break; /* Look using Plugin root */ case (file_exists($this->bootstrap->path( $key_file_path, 'dir') ) ): $key_file_path = $this->bootstrap->path( $key_file_path, 'dir' ); break; } if(is_readable($key_file_path)) { $this->set( 'sm.key_json', file_get_contents($key_file_path) ); if(defined('WP_STATELESS_MEDIA_KEY_FILE_PATH')) $this->set( "sm.readonly.key_json", "constant" ); else $this->set("sm.readonly.key_json", "environment"); } } } $this->set( 'sm.strings', $this->strings ); do_action('wp_stateless_settings_refresh', $this); } /** * Remove settings * @param bool $network */ public function reset($network = false) { foreach ($this->settings as $option => $array) { if($option == 'organize_media') continue; $_option = 'sm_' . $option; if($network && current_user_can('manage_network')){ delete_site_option($_option); delete_option($_option); } else{ delete_option($_option); } } foreach ($this->network_only_settings as $option => $array) { $_option = 'sm_' . $option; if($network && current_user_can('manage_network')){ delete_site_option($_option); delete_option($_option); } } $this->set('sm', []); $this->refresh(); } /** * Replacing wildcards with real values * @param $root_dir * @param bool $regex * @param array $current_values * @return mixed|null|string|string[] * */ public function root_dir_wildcards( $root_dir, $regex = false, $current_values = [] ) { $not_allowed_char = '/[^A-Za-z0-9\/_.\.\-]/'; $wildcards = apply_filters('wp_stateless_root_dir_wildcard', $this->wildcards); if($regex){ $root_dir = preg_quote($root_dir); $not_allowed_char = '/[^A-Za-z0-9\/_.\.\-\\\\{}]/'; } if ( is_array( $wildcards ) && !empty( $wildcards ) ) { foreach ($wildcards as $wildcard => $values) { if (!empty($wildcard)) { $replace = $values[0]; if($regex){ $replace = isset($values[3]) ? $values[3] : preg_quote($values[0]); } if ( isset($current_values[$wildcard]) ) { $replace = $current_values[$wildcard]; } $root_dir = str_replace($wildcard, $replace, $root_dir); } } } //removing all special chars except slash $root_dir = preg_replace($not_allowed_char, '', $root_dir); $root_dir = preg_replace('/(\/+)/', '/', $root_dir); $root_dir = trim( $root_dir, '/ ' ); // Remove any forward slash and empty space. return $root_dir; } /** * Parse path by wildcards and return array ('wildcard' => 'value') * The perpose of this filter is to return Y/M or other dynamic fields from the file path. * For now only Y/M is dynamic. We will get it via using regex. * @param $path * @return array */ public function parse_root_dir_wildcards( $path ) { $result = []; /** * removing GS host from path */ $gs_url = $this->bootstrap->get_gs_host(); if( 0 === strpos( $path, $gs_url . '/' ) ) { $path = substr( $path, strlen( $gs_url . '/' ) ); } /** * removing filename and last slash */ $path = untrailingslashit( str_replace(basename($path), '', $path) ); $wildcards = apply_filters('wp_stateless_root_dir_wildcard', $this->wildcards); /** * Checking if a wildcard have regex field in it. * Then return the matching value using regex. */ foreach ($wildcards as $key => $value) { if(isset($value[3])){ if(preg_match("@" . $value[3] . "@", $path, $matches)){ $result[$key] = $matches[0]; } } } return $result; } /** * Add menu options */ public function admin_menu() { $key_json = $this->get('sm.key_json'); if($this->get('sm.hide_setup_assistant') != 'true' && empty($key_json) ){ // #152 // $this->setup_wizard_ui = add_media_page( __( 'Stateless Setup', $this->bootstrap->domain ), __( 'Stateless Setup', $this->bootstrap->domain ), 'manage_options', 'stateless-setup', array($this, 'setup_wizard_interface') ); } if($this->get('sm.hide_settings_panel') != 'true'){ $this->stateless_settings = add_media_page( __( 'Stateless Settings', $this->bootstrap->domain ), __( 'Stateless Settings', $this->bootstrap->domain ), 'manage_options', 'stateless-settings', array($this, 'settings_interface') ); } } /** * Add menu options * @param $slug */ public function network_admin_menu($slug) { // #152 // $this->setup_wizard_ui = add_submenu_page( 'settings.php', __( 'Stateless Setup', $this->bootstrap->domain ), __( 'Stateless Setup', $this->bootstrap->domain ), 'manage_options', 'stateless-setup', array($this, 'setup_wizard_interface') ); $this->stateless_settings = add_submenu_page( 'settings.php', __( 'Stateless Settings', $this->bootstrap->domain ), __( 'Stateless Settings', $this->bootstrap->domain ), 'manage_options', 'stateless-settings', array($this, 'settings_interface') ); } /** * Draw interface */ public function settings_interface() { $tab = isset($_GET['tab']) && !empty($_GET['tab']) ? $_GET['tab'] : 'stless_settings_tab'; include $this->bootstrap->path( '/static/views/settings_interface.php', 'dir' ); } /** * Draw interface */ public function regenerate_interface() { include $this->bootstrap->path( '/static/views/regenerate_interface.php', 'dir' ); } /** * Draw interface */ public function setup_wizard_interface() { include ud_get_stateless_media()->path( '/static/views/setup_wizard_interface.php', 'dir' ); } /** * Handles saving SM data. * * @author alim@UD */ public function save_media_settings(){ if(isset($_POST['action']) && $_POST['action'] == 'stateless_settings' && wp_verify_nonce( $_POST['_smnonce'], 'wp-stateless-settings' )){ $settings = apply_filters('stateless::settings::save', $_POST['sm']); $root_dir_value = false; foreach ( $settings as $name => $value ) { /** * Sanitize POST data */ if (!is_array($value)) { $value = sanitize_text_field($value); } /** * root_dir settings */ if ( 'root_dir' == $name && is_array($value) ) { //managed in WP-Stateless settings (via Bucket Folder control) if ( in_array('%date_year/date_month%', $value)) { update_option( 'uploads_use_yearmonth_folders', '1' ); } else { update_option( 'uploads_use_yearmonth_folders', '0' ); } /** * preparing path from tags */ $value = implode('/', $value); $root_dir_value = true; } $option = 'sm_'. $name; if($name == 'organize_media'){ $option = 'uploads_use_yearmonth_folders'; } elseif($name == 'key_json'){ $value = stripslashes($value); } // Be sure to cleanup values before saving $value = trim($value); if(is_network_admin()){ update_site_option( $option, $value ); } else{ update_option( $option, $value ); } } if ( !$root_dir_value ) { if(is_network_admin()){ update_site_option( 'sm_root_dir', '' ); } else{ update_option( 'sm_root_dir', '' ); } } $this->bootstrap->flush_transients(); $this->refresh(); } } /** * Wrapper for setting value. * @param string $key * @param bool $value * @param bool $bypass_validation * @return \UDX\Settings */ public function set( $key = '', $value = false, $bypass_validation = false ) { return parent::set( $key, $value, $bypass_validation ); } /** * Outputs 'Compatibility' tab content on the settings page. * */ public function settings_tab_content() { $wildcards = apply_filters('wp_stateless_root_dir_wildcard', $this->wildcards); $wildcard_year_month = '%date_year/date_month%'; $root_dir = $this->get( 'sm.root_dir' ); $use_year_month = (strpos($root_dir, $wildcard_year_month) !== false) ?: false; /** * removing year/month wildcard */ if ($use_year_month) { $root_dir = str_replace($wildcard_year_month, '%YM%', $root_dir); } /** * preparing array with wildcards */ $root_dir_values = explode('/', $root_dir); /** * adding year/month wildcard */ if ($use_year_month) { if ( !empty($root_dir_values) ) { foreach( $root_dir_values as $k=>$root_dir_value ) { if ( $root_dir_value == '%YM%' ) { $root_dir_values[$k] = $wildcard_year_month; } } } else { $root_dir_values[] = $wildcard_year_month; } } /** * first slash */ array_unshift($root_dir_values , '/'); /** * removing empty values */ $root_dir_values = array_filter($root_dir_values); foreach ($root_dir_values as $k => $v) { $root_dir_values[$k] = trim($v); } /** * merging user's wildcards with default values */ $wildcards = array_keys($wildcards); if (!empty($root_dir_values)) { $wildcards = array_unique( array_merge($root_dir_values, $wildcards) ); } $sm = (object)$this->get('sm'); include ud_get_stateless_media()->path('static/views/settings-tab.php', 'dir'); } /** * Outputs 'Sync' tab content on the settings page. * */ public function processing_tab_content() { // Drop non-public properties $processes = json_encode(Utility::get_available_sync_classes()); $processes = json_decode($processes, true); $processes = Helper::array_of_objects($processes); include ud_get_stateless_media()->path('static/views/processing_interface.php', 'dir'); } /** * Getter for settings * * @param string|bool $key * @param mixed $default * @return mixed */ public function get( $key = false, $default = false ) { $value = parent::get( $key, $default ); if ( $key === 'sm' && is_array($value) ) { foreach ( $value as $key => $val ) { $value[$key] = apply_filters("wp_stateless_get_setting_$key", $val, $default); } } else if ( is_string($key) ) { $key = str_replace('sm.', '', $key); $value = apply_filters("wp_stateless_get_setting_$key", $value, $default); } return $value; } /** * Override Cache Control * * @param $value * @return mixed */ public function override_cache_control($value) { if ( !empty($value) && $value !== self::DEFAULT_CACHE_CONTROL ) { return $value; } $cache_control = trim($this->get('sm.cache_control')); return empty($cache_control) ? self::DEFAULT_CACHE_CONTROL : $cache_control; } /** * Add 'Settings' on Plugins page * * @param array $actions * @param string $file * * @return array */ public function plugin_action_links($actions, $file) { if ( $file !== $this->plugin_file ) { return $actions; } $url = ud_get_stateless_media()->get_settings_page_url('?page=stateless-settings'); $settings = [ 'settings' => sprintf( '%s', $url, __('Settings', ud_get_stateless_media()->domain) ), ]; $actions['addons'] = sprintf( '%s', ud_get_stateless_media()->get_docs_page_url('addons'), __('Addons', ud_get_stateless_media()->domain) ); return $settings + $actions; } /** * Add link to docs on Plugins page * * @param $meta * @param $file * * @return array */ public function plugin_row_meta($meta, $file) { if ( $file !== $this->plugin_file ) { return $meta; } $meta['documentation'] = sprintf( '%s', ud_get_stateless_media()->get_docs_page_url(), __('Documentation', ud_get_stateless_media()->domain) ); return $meta; } /** * Upon plugin activation check if configuration is complete and show setup message if needed */ public function check_setup() { if ( json_decode($this->get('sm.key_json')) ) { return; } delete_option('dismissed_notice_' . self::SETUP_MESSAGE_KEY); } /** * Check if configuration is complete and show setup message if needed */ public function documentation_message() { if ( json_decode($this->get('sm.key_json')) ) { return; } $documentation_url = sprintf( '%s', $this->bootstrap->get_docs_page_url('/setup/'), __('Refer to the setup manual', ud_get_stateless_media()->domain), ); $this->bootstrap->errors->add([ 'title' => __('WP-Stateless: Finish Setup', ud_get_stateless_media()->domain), 'message' => sprintf( __( 'WP-Stateless has been successfully activated. %s for guidance on completing the setup.', ud_get_stateless_media()->domain, ), $documentation_url, ), 'key' => self::SETUP_MESSAGE_KEY, ], 'message'); } } } } ================================================ FILE: lib/classes/class-status.php ================================================ registered_dir)) { $this->registered_dir[] = $dir; } } /** * Add file to list of files to be sync from Sync tab. * Save the file path to database. * @param array $media * @param string $status */ public function add_file($media, $status = self::STATUS_QUEUED) { ud_stateless_db()->update_non_library_file( (array) $media, $status); } /** * Sync the file to GCS. * @param $name: Relative path to upload dir. * @param $absolutePath: Full path of the file * @param bool $forced: Type: bool/int; Whether to force to move the file to GCS even it's already exists. * true: Check whether it's already synced or not in database. * 2 (int): Force to overwrite on GCS * @param array $args * @return bool|void $media: Media object returned from client->add_media() method. * @throws: Exception File not found */ public function sync_file($name, $absolutePath, $forced = false, $args = array()) { $sm_mode = ud_get_stateless_media()->get('sm.mode'); $args = wp_parse_args($args, array( 'ephemeral' => true, // whether to delete local file in ephemeral mode. 'download' => false, // whether to delete local file in ephemeral mode. 'use_root' => 0, 'skip_db' => false, 'manual_sync' => false, 'remove_from_queue' => false, // removes entry from queue table if both file is missing. 'name_with_root' => true, )); $args = apply_filters('sm:sync::syncArgs', $args, $name, $absolutePath, $forced); if ( apply_filters('sm:sync::queue_is_exists', $name, self::STATUS_SYNCED) && !$forced) { return false; } $file_type = Utility::mimetype_from_extension(pathinfo($absolutePath, PATHINFO_EXTENSION)); if (empty($this->client)) { $this->client = ud_get_stateless_media()->get_client(); } if (is_wp_error($this->client)) { return; } $file_copied_from_gcs = false; $local_file_exists = file_exists($absolutePath); do_action('sm::pre::sync::nonMediaFiles', $name, $absolutePath); // , $media if (!$local_file_exists && ($args['download'] || ud_get_stateless_media()->get('sm.mode') !== 'ephemeral' || ud_get_stateless_media()->get('sm.mode') !== 'stateless')) { // Try get it and save $result_code = $this->client->get_media($name, true, $absolutePath); if ($result_code == 200) { $local_file_exists = true; $file_copied_from_gcs = true; } } if ($local_file_exists && !$file_copied_from_gcs && !$args['download']) { if ($sm_mode == 'stateless' && !wp_doing_ajax()) { global $gs_client; $gs_name = apply_filters('wp_stateless_file_name', $name, $args['name_with_root']); //Bucket $bucket = ud_get_stateless_media()->get('sm.bucket'); $bucket = $gs_client->bucket($bucket); $object = $bucket->object($gs_name); $args = wp_parse_args($args, array( 'use_root' => $args['use_root'], 'force' => ($forced == 2), 'name' => $name, 'absolutePath' => $absolutePath, 'mimeType' => $file_type, 'metadata' => array( 'child-of' => dirname($name), 'file-hash' => md5($name), 'source' => $args['source'] ?? '', 'sourceVersion' => $args['source_version'] ?? '', ), 'is_webp' => '', )); $args = apply_filters('wp_stateless_add_media_args', $args); /** * Updating object metadata, ACL, CacheControl and contentDisposition * @return media object */ try { $mediaOptions = array( 'cacheControl' => apply_filters('sm:item:cacheControl', ud_get_stateless_media()->get_default_cache_control(), $absolutePath), 'contentDisposition' => apply_filters('sm:item:contentDisposition', null, $absolutePath) ); if ( !defined('WP_STATELESS_SKIP_ACL_SET') || !WP_STATELESS_SKIP_ACL_SET) { $mediaOptions['predefinedAcl'] = 'publicRead'; } $media = $object->update(array('metadata' => $args['metadata']) + $mediaOptions); } catch (\Throwable $th) { //throw $th; } } else { $media = $this->client->add_media(array( 'use_root' => $args['use_root'], 'name' => $name, 'force' => ($forced == 2), 'absolutePath' => $absolutePath, 'cacheControl' => apply_filters('sm:item:cacheControl', ud_get_stateless_media()->get_default_cache_control(), $absolutePath), //@todo use cacheControl from settings page. 'contentDisposition' => apply_filters('sm:item:contentDisposition', null, $absolutePath), 'mimeType' => $file_type, 'metadata' => array( 'child-of' => dirname($name), 'file-hash' => md5($name), 'source' => $args['source'] ?? '', 'sourceVersion' => $args['source_version'] ?? '', ), )); } // Addon can hook this function to modify database after manual sync done. do_action('sm::synced::nonMediaFiles', $name, $absolutePath, $media); // , $media // Ephemeral mode: we don't need the local version. if ($args['ephemeral'] == true && ud_get_stateless_media()->get('sm.mode') === 'ephemeral') { unlink($absolutePath); } if (!$args['skip_db']) { // add file_path to the file list. do_action('sm:sync::addFile', $media, self::STATUS_SYNCED); } return $media; } elseif (!$local_file_exists && $args['remove_from_queue']) { if (!$this->client->media_exists($name)) { do_action('sm:sync::removeFile', $name); if ($args['manual_sync']) { throw new UnprocessableException(sprintf(__("Both local and remote files are missing. File: %s ", ud_get_stateless_media()->domain), $name)); } } } } /** * Generate list for manual sync using sync tab. Sync all register files, dir and passed files. * @param array $files - Additional files to sync. * @return array */ public function sync_non_media_files($files = array()) { $upload_dir = wp_upload_dir(); $files = array_merge( $files, apply_filters('wp_stateless_get_non_library_files', array(), '') ); foreach ($this->registered_dir as $key => $dir) { $dir = $upload_dir['basedir'] . "/" . trim($dir, '/') . "/"; if (is_dir($dir)) { // Getting all the files from dir recursively. $_files = Utility::get_files($dir); // validating and adding to the $files array. foreach ($_files as $id => $file) { if (!file_exists($file)) { continue; } $_file = str_replace(wp_normalize_path($upload_dir['basedir']), '', wp_normalize_path($file)); if (!in_array($_file, $files)) { $files[] = trim($_file, '/'); } } } } // $files = array_values(array_unique($files)); return $files; } /** * Delete a file from GCS. * * @param $file * @param bool $force * @return bool */ public function delete_file($file) { try { $file = trim($file, '/'); if (empty($this->client)) { $this->client = ud_get_stateless_media()->get_client(); } if (is_wp_error($this->client)) { return false; } // Removing file for GCS $this->client->remove_media($file, "", 0); do_action('sm:sync::removeFile', $file); return true; } catch (\Exception $e) { return false; } } /** * Remove registered files of specified dir from GCS. * * @param $dir * @return bool|void */ public function delete_files($dir) { if (empty($this->client)) { $this->client = ud_get_stateless_media()->get_client(); } if (is_wp_error($this->client)) { return; } // Removing the files one by one. $files = apply_filters('wp_stateless_get_non_library_files', array(), $dir); if ( !empty($files) ) { foreach ($files as $key => $file) { if (strpos($file, $dir) !== false) { $this->client->remove_media($file, "", 0); do_action('sm:sync::removeFile', $file); } } } return true; } /** * Checks whether a file is exist in database. * @param $file: Path of file relative to upload dir. * @param string $status: optional. queued|synced * @return mixed: non boolean true. number of item found in db. */ public function queue_is_exists($file, $status = '') { return ud_stateless_db()->get_non_library_file_id($file, $status); } /** * Deletes a entry from database. * @param $file: Path of file relative to upload dir. * @return mixed */ public function remove_file($file) { ud_stateless_db()->remove_non_library_file($file); } /** * Delete a file from GCS. * @param $old_file * @param $new_file * @param bool $force * @param string $status * @return bool */ public function copy_file($old_file, $new_file, $force = false, $status = self::STATUS_COPIED) { try { if ( !$force && apply_filters('sm:sync::queue_is_exists', $new_file, $status) ) { return false; } $client = $this->get_gs_client(); // Copying file on GCS $media = $client->copy_media($old_file, $new_file); do_action('sm:sync::addFile', $media, $status); return true; } catch (\Exception $e) { return false; } } /** * Delete a file from GCS. * @param $old_file * @param $new_file * @return bool */ public function move_file($old_file, $new_file) { try { $this->copy_file($old_file, $new_file, true, self::STATUS_MOVED); $this->delete_file($old_file); return true; } catch (\Exception $e) { return false; } } /** * Get GS Client * @return mixed */ public function get_gs_client() { if (empty($this->client)) { $this->client = ud_get_stateless_media()->get_client(); } return $this->client; } /** * Remove file from DB after file deletion. * @param string $file */ public function unregister_file($file) { $file = str_replace( ud_get_stateless_media()->get_gs_path(), '', $file); $file = str_replace( ud_get_stateless_media()->get_gs_host(), '', $file); $file = trim($file, '/'); do_action('sm:sync::removeFile', $file); } } } } ================================================ FILE: lib/classes/class-upgrader.php ================================================ blog_id); $version = get_option('wp_sm_version'); if ($version) { restore_current_blog(); break; } restore_current_blog(); } } if (!$version) { self::fresh_install(); } /* Maybe upgrade blog ( single site ) */ self::upgrade(); /* Maybe upgrade network options */ if (ud_get_stateless_media()->is_network_detected(true)) { self::upgrade_network($version); } } /** * Upgrade current blog ( or single site ) * */ private static function upgrade() { global $wpdb; $version = get_option('wp_sm_version', false); /** * Upgrade to v.1.2.0 requirements */ if (!$version || version_compare($version, '1.2.0', '<')) { if ($v = get_option('sm.mode')) { update_option('sm_mode', $v); delete_option('sm.mode'); } $v = get_option('sm_mode'); if ($v == '0') update_option('sm_mode', 'disabled'); elseif ($v == '1') update_option('sm_mode', 'backup'); elseif ($v == '2') update_option('sm_mode', 'cdn'); if ($v = get_option('sm.service_account_name')) { update_option('sm_service_account_name', $v); delete_option('sm.service_account_name'); } if ($v = get_option('sm.key_file_path')) { update_option('sm_key_file_path', $v); delete_option('sm.key_file_path'); } if ($v = get_option('sm.bucket')) { update_option('sm_bucket', $v); delete_option('sm.bucket'); } delete_option('sm.app_name'); delete_option('sm.body_rewrite'); delete_option('sm.bucket_url_path'); delete_option('sm.post_content_rewrite'); } update_option('dismissed_notice_stateless_cache_busting', true); if (!$version || version_compare($version, '2.1.7', '<')) { $sm_mode = get_option('sm_mode', null); $hashify_file_name = get_option('sm_hashify_file_name', null); if ($version && $sm_mode == 'stateless' && $hashify_file_name == 'true') { delete_option('dismissed_notice_stateless_cache_busting'); } } if (!is_multisite() && $version && version_compare($version, '3.0', '<')) { self::migrate_root_dir(); //updating mode name `stateless` to `ephemeral` $sm_mode = get_option('sm_mode'); if ($sm_mode == 'stateless') update_option('sm_mode', 'ephemeral'); } /** * Upgrade to v4.0 */ if ( $version && version_compare($version, '4.0', '<') ) { $modules = get_option('stateless-modules', []); if ( is_array($modules) && isset($modules['dynamic-image-support']) ) { update_option('sm_dynamic_image_support', $modules['dynamic-image-support']); unset($modules['dynamic-image-support']); update_option('stateless-modules', $modules); } } update_option('wp_sm_version', ud_get_stateless_media()->args['version']); } /** * Upgrade Network Enabled * */ private static function upgrade_network($version) { /** * Upgrade to v.1.2.0 requirements */ if (!$version || version_compare($version, '1.2.0', '<')) { if ($v = get_site_option('sm.key_file_path')) { update_site_option('sm_key_file_path', $v); delete_site_option('sm.key_file_path'); } if ($v = get_option('sm.service_account_name')) { update_site_option('sm_service_account_name', $v); delete_site_option('sm.service_account_name'); } } /** * Upgrade to v.3.0 requirements */ if (is_multisite() && $version && version_compare($version, '3.0', '<')) { $sites = get_sites(); foreach ($sites as $site) { switch_to_blog($site->blog_id); self::migrate_root_dir(true); //updating mode name `stateless` to `ephemeral` $sm_mode = get_option('sm_mode'); if ($sm_mode == 'stateless') update_option('sm_mode', 'ephemeral'); restore_current_blog(); } //removing network option, because sites could uses different setting for Orginize media update_network_option(1, 'sm_root_dir', ''); //forcing `Cache-Busting` for multisite to prevent replacing media with same filenames update_network_option(1, 'sm_hashify_file_name', 'true'); $sm_mode_site = get_site_option('sm_mode'); if ($sm_mode_site == 'stateless') update_site_option('sm_mode', 'ephemeral'); } /** * Upgrade to v4.0 */ if ( $version && version_compare($version, '4.0', '<') ) { $modules = get_site_option('stateless-modules', []); if ( is_array($modules) && isset($modules['dynamic-image-support']) ) { update_site_option('sm_dynamic_image_support', $modules['dynamic-image-support']); unset($modules['dynamic-image-support']); update_site_option('stateless-modules', $modules); } } update_site_option('wp_sm_version', ud_get_stateless_media()->args['version']); } /** * Fresh install */ private static function fresh_install() { if (is_multisite()) { $sites = get_sites(); foreach ($sites as $site) { switch_to_blog($site->blog_id); self::migrate_root_dir(true, true); restore_current_blog(); } } } /** * * @param bool $multisite pass true to use multisite prefix * @param bool $fresh_install for first install * @return string `sm_root_dir` value */ private static function migrate_root_dir($multisite = false, $fresh_install = false) { $network_root_dir = get_network_option(1, 'sm_root_dir'); $sm_root_dir = $network_root_dir ? $network_root_dir : get_option('sm_root_dir', ''); $organize_media = get_option('uploads_use_yearmonth_folders'); if ($organize_media == '1' && empty($sm_root_dir)) { $sm_root_dir = '/%date_year/date_month%/'; } elseif (!empty($sm_root_dir) && $organize_media == '1') { $sm_root_dir = trim($sm_root_dir, ' /') . '/%date_year/date_month%/'; } elseif (!empty($sm_root_dir)) { // $sm_root_dir = $sm_root_dir; } elseif ($organize_media != '1') { $sm_root_dir = ''; } if ($multisite && $fresh_install) { if (empty($sm_root_dir) || $sm_root_dir[0] !== '/') { $sm_root_dir = "/" . $sm_root_dir; } if (false === strpos($sm_root_dir, '/sites/%site_id%')) { $sm_root_dir = '/sites/%site_id%' . $sm_root_dir; } } update_option('sm_root_dir', $sm_root_dir); if ($multisite) { //forcing `Cache-Busting` for multisite to prevent replacing media with same filenames update_option('sm_hashify_file_name', 'true'); } return $sm_root_dir; } /** * Upgrade database, perform tasks that dbDelta can't do * * @param string $new_version * @param string $old_version */ public static function upgrade_db($new_version, $old_version) { global $wpdb; if ( !empty($old_version) && version_compare($old_version, '1.1', '<') ) { try { // Remove UNIQUE indexes, which will be recreated later using dbDelta as non-unique $wpdb->query('ALTER TABLE ' . ud_stateless_db()->files . ' DROP INDEX post_id'); } catch (\Throwable $e) { Helper::log($e->getMessage()); } } if ( !empty($old_version) && version_compare($old_version, '1.2', '<') ) { try { // Remove UNIQUE indexes, which will be recreated later using dbDelta as non-unique $wpdb->query('ALTER TABLE ' . ud_stateless_db()->files . ' DROP INDEX name'); } catch (\Throwable $e) { Helper::log($e->getMessage()); } } } } } } ================================================ FILE: lib/classes/class-utility.php ================================================ add_media( false, $post_id ); * * @class Utility */ namespace wpCloud\StatelessMedia { use wpCloud\StatelessMedia\Sync\BackgroundSync; use \Firebase\JWT\JWT; use \Firebase\JWT\Key; if (!class_exists('wpCloud\StatelessMedia\Utility')) { class Utility { static $can_delete_attachment = []; /** * ChromeLogger * * @author potanin@UD * @param $data */ static public function log($data) { if (!class_exists('wpCloud\StatelessMedia\Logger')) { include_once(__DIR__ . '/class-logger.php'); } if (!class_exists('wpCloud\StatelessMedia\Logger')) { return; } if (defined('WP_STATELESS_CONSOLE_LOG') && WP_STATELESS_CONSOLE_LOG) { Logger::log('[wp-stateless]', $data); } } /** * wp_normalize_path was added in 3.9.0 * * @param $path * @return mixed|string * */ public static function normalize_path($path) { if (function_exists('wp_normalize_path')) { return wp_normalize_path($path); } $path = str_replace('\\', '/', $path); $path = preg_replace('|/+|', '/', $path); return $path; } /** * Randomize file name * @param $filename * @return string */ public static function randomize_filename($filename) { $return = apply_filters('stateless_skip_cache_busting', null, $filename); if ($return) { return $return; } if (preg_match('/^[a-f0-9]{8}-/', $filename)) { return $filename; } $info = pathinfo($filename); $ext = empty($info['extension']) ? '' : '' . $info['extension']; $_parts = array(); $rand = substr(md5(time()), 0, 8); if (strpos($info['filename'], '@')) { $_cleanName = explode('@', $info['filename'])[0]; $_retna = explode('@', $info['filename'])[1]; $_parts[] = $rand; $_parts[] = '-'; $_parts[] = strtolower($_cleanName); $_parts[] = '@' . strtolower($_retna); } else { $_parts[] = $rand; $_parts[] = '-'; $_parts[] = strtolower($info['filename']); } $filename = join('', $_parts); if (!empty($ext)) { $filename .= '.' . $ext; } return $filename; } /** * Get Media Item Content Disposition * * @param null $attachment_id * @param array $metadata * @param array $data * @return string */ public static function getContentDisposition($attachment_id = null, $metadata = array(), $data = array()) { // return 'Content-Disposition: attachment; filename=some-file.sql'; return apply_filters('sm:item:contentDisposition', null, array('attachment_id' => $attachment_id, 'mime_type' => get_post_mime_type($attachment_id), 'metadata' => $metadata, 'data' => $data)); } /** * @param null $attachment_id * @param array $metadata * @param array $data * @return string */ public static function getCacheControl($attachment_id = null, $metadata = array(), $data = array()) { if (!$attachment_id) { return apply_filters('sm:item:cacheControl', 'private, no-cache, no-store', $attachment_id, array('attachment_id' => null, 'mime_type' => null, 'metadata' => $metadata, 'data' => $data)); } $_mime_type = get_post_mime_type($attachment_id); // Treat SQL as non-public. if (strpos($_mime_type, 'sql') !== false) { return apply_filters('sm:item:cacheControl', 'private, no-cache, no-store', array('attachment_id' => $attachment_id, 'mime_type' => null, 'metadata' => $metadata, 'data' => $data)); } // Treat all other files as public. return apply_filters('sm:item:cacheControl', ud_get_stateless_media()->get_default_cache_control(), array('attachment_id' => $attachment_id, 'mime_type' => null, 'metadata' => $metadata, 'data' => $data)); } /** * Add/Update Media to Bucket * Fired for every action with image add or update * * $force and $args params will no be passed on media library uploads. * This two will be passed on by compatibility. * * @action wp_generate_attachment_metadata * @author peshkov@UD * @param $metadata * @param $attachment_id * @param boolean $force Whether to force the upload incase of it's already exists. * @param array $args Whether to only sync the full size image. * @return bool|string */ public static function add_media($metadata, $attachment_id, $force = false, $args = array()) { $sm_mode = ud_get_stateless_media()->get('sm.mode'); $file = ''; $upload_dir = wp_upload_dir(); $args = wp_parse_args($args, array( 'is_webp' => '', // expected value ".webp"; )); /* Get metadata in case if method is called directly. */ if (current_filter() !== 'wp_generate_attachment_metadata' && current_filter() !== 'wp_update_attachment_metadata' && current_filter() !== 'intermediate_image_sizes_advanced') { $metadata = wp_get_attachment_metadata($attachment_id); } // making sure meta data isn't null. if (empty($metadata)) { $metadata = array(); } /** * To skip the sync process. * * Returning a non-null value * will effectively short-circuit the function. * * $force and $args params will no be passed on non media library uploads. * This two will be passed on by compatibility. * * @since 2.2.4 * * @param bool $value This should return true if want to skip the sync. * @param int $metadata Metadata for the attachment. * @param string $attachment_id Attachment ID. * @param bool $force (optional) Whether to force the sync even the file already exist in GCS. * @param bool $args (optional) Whether to only sync the full size image. */ $check = apply_filters('wp_stateless_skip_add_media', null, $metadata, $attachment_id, $force, $args); $client = ud_get_stateless_media()->get_client(); if ((!is_wp_error($client) || ($sm_mode == 'stateless' && !wp_doing_ajax())) && !$check) { $image_host = ud_get_stateless_media()->get_gs_host(); $bucketLink = apply_filters('wp_stateless_bucket_link', $image_host); $fullsizepath = wp_normalize_path(get_attached_file($attachment_id)); $_cacheControl = self::getCacheControl($attachment_id, $metadata, null); $_contentDisposition = self::getContentDisposition($attachment_id, $metadata, null); // Ensure image upload to GCS when attachment is updated, // by checking if the attachment metadata is changed. if ($attachment_id && !empty($metadata) && !$force) { $db_metadata = get_post_meta($attachment_id, '_wp_attachment_metadata', true); if ($db_metadata != $metadata) { $force = true; } } /** * To skip removing files from server * * Returning a non-null value * will effectively short-circuit the function. * * $force and $args params will no be passed on non media library uploads. * This two will be passed on by compatibility. * * @since 3.0 * * @param bool $value This should return true if want to skip the sync. * @param int $metadata Metadata for the attachment. * @param string $attachment_id Attachment ID. * @param bool $force (optional) Whether to force the sync even the file already exist in GCS. * @param bool $args (optional) Whether to only sync the full size image. */ $skip_remove_media = apply_filters('wp_stateless_skip_remove_media', false, $metadata, $attachment_id, $force, $args); // Make non-images uploadable. // empty $metadata['file'] can cause problem, so we need to generate it. if (empty($metadata['file']) && $attachment_id) { $mime_type = get_post_mime_type($attachment_id); $file = str_replace(wp_normalize_path(trailingslashit($upload_dir['basedir'])), '', $fullsizepath); // We shouldn't create $metadata["file"] if it's PDF file. if ($mime_type != "application/pdf") { $metadata["file"] = $file; } } $cloud_meta = apply_filters('wp_stateless_get_file', [], $attachment_id, true); $cloud_meta = wp_parse_args($cloud_meta, array( 'name' => '', 'bucket' => ud_get_stateless_media()->get('sm.bucket'), 'fileLink' => '', 'mediaLink' => '', 'cacheControl' => $_cacheControl, 'contentDisposition' => $_contentDisposition, 'sizes' => array(), )); /** * Storing file size to sm_cloud first, * Because assigning directly to $metadata['filesize'] don't work. * Maybe filesize gets removed in first run (when file exists). */ if (file_exists($fullsizepath)) { $cloud_meta['filesize'] = filesize($fullsizepath); } // Getting file size from sm_cloud. if (!empty($cloud_meta['filesize'])) { $metadata['filesize'] = $cloud_meta['filesize']; } $image_sizes = self::get_path_and_url($metadata, $attachment_id); foreach ($image_sizes as $size => $img) { if ((isset($_REQUEST['size']) && $_REQUEST['size'] == $size) || empty($_REQUEST['size'])) { // GCS metadata $_metadata = array( "width" => $img['width'], "height" => $img['height'], 'child-of' => $attachment_id, 'file-hash' => md5($file), 'size' => $size, ); // adding extra GCS meta for full size image. if (!$img['is_thumb']) { unset($_metadata['child-of']); // no need in full size image. $_metadata['object-id'] = $attachment_id; $_metadata['source-id'] = md5($attachment_id . ud_get_stateless_media()->get('sm.bucket')); } $media_args = array_filter(array( 'force' => $force, 'name' => $img['gs_name'], 'is_webp' => $args['is_webp'], 'mimeType' => $img['mime_type'], 'metadata' => $_metadata, 'absolutePath' => $img['path'], 'cacheControl' => $_cacheControl, 'contentDisposition' => $_contentDisposition, )); if ($sm_mode == 'stateless' && !wp_doing_ajax() && !wp_doing_cron() || ($sm_mode == 'stateless' && wp_doing_ajax()) ) { global $gs_client; $media_args = wp_parse_args($media_args, array( 'use_root' => true, 'force' => false, 'name' => false, 'absolutePath' => false, 'mimeType' => 'image/jpeg', 'metadata' => array(), 'is_webp' => '', )); $media_args = apply_filters('wp_stateless_add_media_args', $media_args); //Bucket $bucket = ud_get_stateless_media()->get('sm.bucket'); $bucket = $gs_client->bucket($bucket); $object = $bucket->object($media_args['name']); /** * Updating object metadata, ACL, CacheControl and contentDisposition * @return media object */ try { $mediaOptions = array( 'cacheControl' => $_cacheControl, 'contentDisposition' => $_contentDisposition ); if ( !defined('WP_STATELESS_SKIP_ACL_SET') || !WP_STATELESS_SKIP_ACL_SET) { $mediaOptions['predefinedAcl'] = 'publicRead'; } $media = $object->update(array('metadata' => $media_args['metadata']) + $mediaOptions); $cloud_meta = self::generate_cloud_meta($cloud_meta, $media, $size, $img, $bucketLink); } catch (\Throwable $th) { //throw $th; } } else { /* Add default image */ $media = $client->add_media($media_args); /* Break if we have errors. */ if (!is_wp_error($media)) { // @note We don't add storageClass because it's same as parent... $cloud_meta = self::generate_cloud_meta($cloud_meta, $media, $size, $img, $bucketLink); /** * Ephemeral and stateless mode: we don't need the local version. * Except when uploading the full size image first. */ if (self::can_delete_attachment($attachment_id, $args) && !$skip_remove_media) { @unlink($img['path']); } } } } } // End of image sync loop if (!$args['is_webp']) { update_post_meta($attachment_id, 'sm_cloud', $cloud_meta); } /** * Triggers when the media and it's thumbs are synced. * * $force and $args params will no be passed on non media library uploads. * This two will be passed on by compatibility. * * @since 2.2.5 * * @param int $metadata Metadata for the attachment. * @param string $attachment_id Attachment ID. * @param bool $force (optional) Whether to force the sync even the file already exist in GCS. * @param bool $args (optional) Whether to only sync the full size image. */ $metadata = apply_filters('wp_stateless_media_synced', $metadata, $attachment_id, $force, $args); } return $metadata; } /** * Remove Media from Bucket by post ID * Fired on calling function wp_delete_attachment() * * @todo: add error logging. peshkov@UD * @see wp_delete_attachment() * @action delete_attachment * @author peshkov@UD * @param $post_id */ public static function remove_media($post_id) { /* Get attachments metadata */ $metadata = wp_get_attachment_metadata($post_id); /* Be sure we have the same bucket in settings and have GS object's name before proceed. */ if (isset($metadata['gs_name']) && isset($metadata['gs_bucket']) && $metadata['gs_bucket'] == ud_get_stateless_media()->get('sm.bucket')) { $client = ud_get_stateless_media()->get_client(); if (!is_wp_error($client)) { /* Remove default image */ $client->remove_media($metadata['gs_name'], $post_id); $client->remove_media(get_attached_file($post_id), $post_id); // Remove webp $client->remove_media($metadata['gs_name'] . '.webp', $post_id, true, "", true); /* Now, go through all sizes and remove 'image sizes' images from Bucket too. */ if (!empty($metadata['sizes']) && is_array($metadata['sizes'])) { foreach ($metadata['sizes'] as $k => $v) { if (!empty($v['gs_name'])) { $client->remove_media($v['gs_name'], $post_id, true, $k); $client->remove_media($v['gs_name'] . '.webp', $post_id, true, $k, true); } } } } } } /** * Return URL and path for all image sizes of a attachment. * @param $metadata * @param $attachment_id * @return mixed */ public static function get_path_and_url($metadata, $attachment_id) { /* Get metadata in case if method is called directly. */ if (empty($metadata) && current_filter() !== 'wp_generate_attachment_metadata' && current_filter() !== 'wp_update_attachment_metadata') { $metadata = wp_get_attachment_metadata($attachment_id); } $gs_name_path = array(); $full_size_path = get_attached_file($attachment_id); $base_dir = dirname($full_size_path); $gs_name = apply_filters('wp_stateless_file_name', $full_size_path, true, $attachment_id, ''); $gs_base_dir = dirname($gs_name) == '.' ? '' : trailingslashit(dirname($gs_name)); if (!isset($metadata['width']) && file_exists($full_size_path)) { try { $_image_size = getimagesize($full_size_path); if ($_image_size !== false && is_array($_image_size)) { $metadata['width'] = $_image_size[0]; $metadata['height'] = $_image_size[1]; } } catch (\Exception $e) { // lets do nothing. } } $gs_name_path['__full'] = array( 'gs_name' => $gs_name, 'path' => $full_size_path, 'sm_meta' => true, 'is_thumb' => false, 'mime_type' => get_post_mime_type($attachment_id), 'width' => isset($metadata['width']) ? $metadata['width'] : null, 'height' => isset($metadata['height']) ? $metadata['height'] : null, ); /* Now we go through all available image sizes and upload them to Google Storage */ if (!empty($metadata['sizes']) && is_array($metadata['sizes'])) { foreach ($metadata['sizes'] as $image_size => $data) { if (empty($data['file'])) continue; $absolutePath = wp_normalize_path($base_dir . '/' . $data['file']); $gs_name = $gs_base_dir . $data['file']; $gs_name = apply_filters('wp_stateless_file_name', $gs_name, true, $attachment_id, $image_size); $gs_name_path[$image_size] = array( 'gs_name' => $gs_name, 'path' => $absolutePath, 'sm_meta' => true, 'is_thumb' => true, 'mime_type' => $data['mime-type'], 'width' => $data['width'], 'height' => $data['height'], ); } } return apply_filters('wp_stateless_get_path_and_url', $gs_name_path, $metadata, $attachment_id); } /** * Return URL and path for all image sizes of a attachment. * @param $cloud_meta * @param $media * @param $image_size * @param $img * @param $bucketLink * @return mixed */ public static function generate_cloud_meta($cloud_meta, $media, $image_size, $img, $bucketLink) { $gs_name = !empty($media['name']) ? $media['name'] : $img['gs_name']; $fileLink = trailingslashit($bucketLink) . $gs_name; $version = get_option('wp_sm_version', false); if ($img['is_thumb']) { // Cloud meta for thumbs. $cloud_meta['sizes'][$image_size]['name'] = $gs_name; $cloud_meta['sizes'][$image_size]['fileLink'] = $fileLink; $cloud_meta['sizes'][$image_size]['mediaLink'] = $media['mediaLink']; $cloud_meta['sizes'][$image_size]['width'] = ($media['metadata']['width']) ? $media['metadata']['width'] : $img['width']; $cloud_meta['sizes'][$image_size]['height'] = ($media['metadata']['height']) ? $media['metadata']['height'] : $img['height']; } else { // cloud meta for full size image. $cloud_meta['name'] = $gs_name; $cloud_meta['fileLink'] = $fileLink; $cloud_meta['mediaLink'] = $media['mediaLink']; $cloud_meta['width'] = isset($media['metadata']['width']) ? $media['metadata']['width'] : ($img['width'] ? $img['width'] : 0); $cloud_meta['height'] = isset($media['metadata']['height']) ? $media['metadata']['height'] : ($img['height'] ? $img['height'] : 0); $cloud_meta['bucket'] = ud_get_stateless_media()->get('sm.bucket'); $cloud_meta['sm_version'] = $version; } return apply_filters('wp_stateless_generate_cloud_meta', $cloud_meta, $media, $image_size, $img, $bucketLink); } /** * join_url * * @param array $parts * @param boolean $encode * @return string $url */ public static function join_url($parts, $encode = TRUE) { if ($encode) { if (isset($parts['user'])) $parts['user'] = rawurlencode($parts['user']); if (isset($parts['pass'])) $parts['pass'] = rawurlencode($parts['pass']); if ( isset($parts['host']) && !preg_match('!^(\[[\da-f.:]+\]])|([\da-f.:]+)$!ui', $parts['host']) ) $parts['host'] = rawurlencode($parts['host']); if (!empty($parts['path'])) $parts['path'] = preg_replace( '!%2F!ui', '/', rawurlencode($parts['path']) ); if (isset($parts['query'])) $parts['query'] = rawurlencode($parts['query']); if (isset($parts['fragment'])) $parts['fragment'] = rawurlencode($parts['fragment']); } $url = ''; if (!empty($parts['scheme'])) $url .= $parts['scheme'] . ':'; if (isset($parts['host'])) { $url .= '//'; if (isset($parts['user'])) { $url .= $parts['user']; if (isset($parts['pass'])) $url .= ':' . $parts['pass']; $url .= '@'; } if (preg_match('!^[\da-f]*:[\da-f.:]+$!ui', $parts['host'])) $url .= '[' . $parts['host'] . ']'; // IPv6 else $url .= $parts['host']; // IPv4 or name if (isset($parts['port'])) $url .= ':' . $parts['port']; if (!empty($parts['path']) && $parts['path'][0] != '/') $url .= '/'; } if (!empty($parts['path'])) $url .= $parts['path']; if (isset($parts['query'])) $url .= '?' . $parts['query']; if (isset($parts['fragment'])) $url .= '#' . $parts['fragment']; return $url; } /** * add_webp_mime * @param $t * @param $user * @return mixed */ public function add_webp_mime($t, $user) { $t['webp'] = 'image/webp'; return $t; } /** * Store attachment id in a static variable on 'intermediate_image_sizes_advanced' filter. * To indicate that we can now delete attachment from server now. * * @param array $new_sizes * @param array $image_meta * @param int $attachment_id * @return array $new_sizes */ public static function store_can_delete_attachment($new_sizes, $image_meta, $attachment_id) { if (!in_array($attachment_id, self::$can_delete_attachment)) { self::$can_delete_attachment[] = $attachment_id; } return $new_sizes; } /** * Check whether to delete attachment from server or not. * * @param int $attachment_id * @param array $args * @return boolean */ public static function can_delete_attachment($attachment_id, $args) { $sm_mode = ud_get_stateless_media()->get('sm.mode'); if (in_array($sm_mode, array('ephemeral', 'stateless'))) { // checks whether it's WP 5.3 and 'intermediate_image_sizes_advanced' is passed. // To be sure that we don't delete full size image before thumbnails are generated. if ( wp_attachment_is_image($attachment_id) && function_exists('is_wp_version_compatible') && is_wp_version_compatible('5.3-RC4-46673') && !in_array($attachment_id, self::$can_delete_attachment) ) { return false; } return true; } return false; } /** * Useful when there is a need to do things depending on a call stack. * Returns true if any of the conditions met. Returns false otherwise. * * @param $callstack array Result of debug_backtrace function. * @param $conditions array CallStack fingerprint with `stack_level` integer. * * Example: * array( * array( * 'stack_level' => 4, * 'function' => '__construct', * 'class' => 'ET_Core_PageResource' * ), * array( * 'stack_level' => 4, * 'function' => 'get_cache_filename', * 'class' => 'ET_Builder_Element' * ) * ) * * @return bool */ public static function isCallStackMatches($callstack, $conditions) { if (!is_array($conditions)) { $conditions = array($conditions); } foreach ($conditions as $condition) { $condition['stack_level'] = $condition['stack_level'] ? $condition['stack_level'] : 0; $levelData = $callstack[$condition['stack_level']]; unset($condition['stack_level']); $levelMatches = false; foreach ($condition as $key => $value) { if (isset($levelData[$key]) && $levelData[$key] === $value) { $levelMatches = true; } else { $levelMatches = false; } } if ($levelMatches) return true; } return false; } /** * Fail over to image URL if not found on disk * In case image not available on both local and bucket * try to pull image from image URL in case it is accessible by some sort of proxy. * * @param: * $url (int/string): URL of the image. * $save_to (string): Path where to save the image. * * @return bool|int * @throws \Exception */ public static function sync_get_attachment_if_exist($url, $save_to) { if (is_int($url)) $url = wp_get_attachment_url($url); $response = wp_remote_get($url); if (!is_wp_error($response) && is_array($response)) { if (!empty($response['response']['code']) && $response['response']['code'] == 200) { try { if (wp_mkdir_p(dirname($save_to))) { return file_put_contents($save_to, $response['body']); } } catch (\Exception $e) { throw $e; } } } return false; } /** * Get a secure JWT signing key * Priority: AUTH_SALT (if valid length) > Plugin-specific stored key > Generated key * * @return string A key suitable for HS256 (minimum 32 bytes) */ public static function get_jwt_signing_key() { // Minimum key length for HS256 (256 bits = 32 bytes) $min_key_length = 32; // Try AUTH_SALT first if it's long enough if (defined('AUTH_SALT') && !empty(AUTH_SALT) && strlen(AUTH_SALT) >= $min_key_length) { return AUTH_SALT; } // Try to get stored plugin-specific key $stored_key = get_option('wp_stateless_jwt_key'); if ($stored_key && strlen($stored_key) >= $min_key_length) { return $stored_key; } // Generate a new secure key $new_key = self::generate_secure_key($min_key_length); update_option('wp_stateless_jwt_key', $new_key, false); return $new_key; } /** * Generate a cryptographically secure random key * * @param int $length Key length in bytes * @return string Base64-encoded key */ private static function generate_secure_key($length = 32) { try { // Use random_bytes for PHP 7+ $random_bytes = random_bytes($length); return base64_encode($random_bytes); } catch (\Exception $e) { // Fallback: use wp_generate_password return wp_generate_password($length * 2, true, true); } } /** * Generate JWT token signed by secure key * Uses AUTH_SALT if valid, otherwise uses plugin-specific stored key * * @param $payload * @param int $ttl * @return string */ public static function generate_jwt_token($payload, $ttl = 3600) { $payload = wp_parse_args($payload, [ 'iat' => $now = time(), 'iss' => $site_url = get_site_url(), 'aud' => $site_url, 'exp' => $now + $ttl ]); $key = self::get_jwt_signing_key(); return JWT::encode($payload, $key, 'HS256'); } /** * Verify and decode token * Uses the same secure key retrieval as generation * Throws exceptions if cannot decode * * @param $token * @return object * @throws \Exception */ public static function verify_jwt_token($token) { $key = self::get_jwt_signing_key(); return JWT::decode($token, new Key($key, 'HS256')); } /** * Generate auth token for wizard iframe * * @param int $ttl * @return string */ public static function generate_wizard_auth_token($ttl = 3600) { $payload = [ 'is_network' => is_network_admin(), 'user_id' => get_current_user_id() ]; return self::generate_jwt_token($payload, $ttl); } /** * Maps a file extensions to a mimetype. * * @param $extension string The file extension. * * @return string|null * @link http://svn.apache.org/repos/asf/httpd/httpd/branches/1.3.x/conf/mime.types */ public static function mimetype_from_extension($extension) { $file_type = wp_check_filetype($extension); if (!empty($file_type['type'])) { return $file_type['type']; } static $mimetypes = [ '7z' => 'application/x-7z-compressed', 'aac' => 'audio/x-aac', 'ai' => 'application/postscript', 'aif' => 'audio/x-aiff', 'asc' => 'text/plain', 'asf' => 'video/x-ms-asf', 'atom' => 'application/atom+xml', 'avi' => 'video/x-msvideo', 'bmp' => 'image/bmp', 'bz2' => 'application/x-bzip2', 'cer' => 'application/pkix-cert', 'crl' => 'application/pkix-crl', 'crt' => 'application/x-x509-ca-cert', 'css' => 'text/css', 'csv' => 'text/csv', 'cu' => 'application/cu-seeme', 'deb' => 'application/x-debian-package', 'doc' => 'application/msword', 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'dvi' => 'application/x-dvi', 'eot' => 'application/vnd.ms-fontobject', 'eps' => 'application/postscript', 'epub' => 'application/epub+zip', 'etx' => 'text/x-setext', 'flac' => 'audio/flac', 'flv' => 'video/x-flv', 'gif' => 'image/gif', 'gz' => 'application/gzip', 'htm' => 'text/html', 'html' => 'text/html', 'ico' => 'image/x-icon', 'ics' => 'text/calendar', 'ini' => 'text/plain', 'iso' => 'application/x-iso9660-image', 'jar' => 'application/java-archive', 'jpe' => 'image/jpeg', 'jpeg' => 'image/jpeg', 'jpg' => 'image/jpeg', 'js' => 'text/javascript', 'json' => 'application/json', 'latex' => 'application/x-latex', 'log' => 'text/plain', 'm4a' => 'audio/mp4', 'm4v' => 'video/mp4', 'mid' => 'audio/midi', 'midi' => 'audio/midi', 'mov' => 'video/quicktime', 'mp3' => 'audio/mpeg', 'mp4' => 'video/mp4', 'mp4a' => 'audio/mp4', 'mp4v' => 'video/mp4', 'mpe' => 'video/mpeg', 'mpeg' => 'video/mpeg', 'mpg' => 'video/mpeg', 'mpg4' => 'video/mp4', 'oga' => 'audio/ogg', 'ogg' => 'audio/ogg', 'ogv' => 'video/ogg', 'ogx' => 'application/ogg', 'pbm' => 'image/x-portable-bitmap', 'pdf' => 'application/pdf', 'pgm' => 'image/x-portable-graymap', 'png' => 'image/png', 'pnm' => 'image/x-portable-anymap', 'ppm' => 'image/x-portable-pixmap', 'ppt' => 'application/vnd.ms-powerpoint', 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'ps' => 'application/postscript', 'qt' => 'video/quicktime', 'rar' => 'application/x-rar-compressed', 'ras' => 'image/x-cmu-raster', 'rss' => 'application/rss+xml', 'rtf' => 'application/rtf', 'sgm' => 'text/sgml', 'sgml' => 'text/sgml', 'svg' => 'image/svg+xml', 'swf' => 'application/x-shockwave-flash', 'tar' => 'application/x-tar', 'tif' => 'image/tiff', 'tiff' => 'image/tiff', 'torrent' => 'application/x-bittorrent', 'ttf' => 'application/x-font-ttf', 'txt' => 'text/plain', 'wav' => 'audio/x-wav', 'webm' => 'video/webm', 'webp' => 'image/webp', 'wma' => 'audio/x-ms-wma', 'wmv' => 'video/x-ms-wmv', 'woff' => 'application/x-font-woff', 'wsdl' => 'application/wsdl+xml', 'xbm' => 'image/x-xbitmap', 'xls' => 'application/vnd.ms-excel', 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'xml' => 'application/xml', 'xpm' => 'image/x-xpixmap', 'xwd' => 'image/x-xwindowdump', 'yaml' => 'text/yaml', 'yml' => 'text/yaml', 'zip' => 'application/zip', ]; $extension = strtolower($extension); return isset($mimetypes[$extension]) ? $mimetypes[$extension] : false; } /** * @param $size * @return float|int */ public static function convert_to_byte($size) { $lastCharacter = \substr($size, -1); $base = \strtoupper($lastCharacter); if (!\ctype_digit($lastCharacter)) { switch ($base) { case 'B': $size = (int) $size; break; case 'K': $size = (int) $size * 1024; break; case 'M': $size = (int) $size * pow(1024, 2); break; case 'G': $size = (int) $size * pow(1024, 3); break; } } return $size; } /** * Get stateless data, count of stateless media * @return mixed */ public static function get_stateless_media_data_count() { global $wpdb; if ( !ud_get_stateless_media()->get('sm.use_postmeta') ) { try { return ud_stateless_db()->get_total_files(); } catch (\Throwable $th) { } } $stateless_media = $wpdb->get_var($wpdb->prepare(" SELECT COUNT(meta_id) FROM " . $wpdb->postmeta . " WHERE meta_key = %s ", 'sm_cloud')); return $stateless_media; } /** * Get a list of instances of all available sync methods */ public static function get_available_sync_classes() { return array_filter(array_map(function ($class) { if (class_exists($class)) { try { $class = $class::instance(); if (is_a($class, BackgroundSync::class)) { return $class; } return null; } catch (\Throwable $e) { error_log($e->getMessage()); return null; } } return null; }, apply_filters('wp_stateless_sync_types', []))); } /** * Process single image attachment by id * * @param mixed $id Attachment ID * @return \WP_Post * @throws FatalException * @throws UnprocessableException */ public static function process_image_by_id($id) { if (ud_get_stateless_media()->is_connected_to_gs() !== true) { throw new FatalException(__('Not connected to GCS', ud_get_stateless_media()->domain)); } $image = get_post($id); if (!$image || 'attachment' != $image->post_type || 'image/' != substr($image->post_mime_type, 0, 6)) throw new UnprocessableException(sprintf(__('Failed to process item: %s is an invalid image ID.', ud_get_stateless_media()->domain), $id)); $fullsizepath = get_attached_file($image->ID); // If no file found if (false === $fullsizepath || !file_exists($fullsizepath)) { // Try get it and save $result_code = ud_get_stateless_media()->get_client()->get_media(apply_filters('wp_stateless_file_name', $fullsizepath, true, "", ""), true, $fullsizepath); if ($result_code !== 200) { if (!Utility::sync_get_attachment_if_exist($image->ID, $fullsizepath)) { throw new UnprocessableException(sprintf(__('Both local and remote files are missing. Unable to process. (%s)', ud_get_stateless_media()->domain), $image->guid)); } } } do_action('sm:pre::synced::image', $id); if (!function_exists('wp_generate_attachment_metadata')) { require_once ABSPATH . '/wp-admin/includes/image.php'; } $metadata = wp_generate_attachment_metadata($image->ID, $fullsizepath); if (get_post_mime_type($image->ID) !== 'image/svg+xml') { if (is_wp_error($metadata)) { throw new UnprocessableException($metadata->get_error_message()); } if (empty($metadata)) { throw new UnprocessableException(sprintf(__('No metadata generated for %1$s (ID %2$s).', ud_get_stateless_media()->domain), esc_html(get_the_title($image->ID)), $image->ID)); } } // trigger processing filters wp_update_attachment_metadata($image->ID, $metadata); do_action('sm:synced::image', $id, $metadata); return $image; } /** * Process single attachment file by id * * @param mixed $id Attachment ID * @return \WP_Post * @throws FatalException * @throws UnprocessableException */ public static function process_file_by_id($id) { if (ud_get_stateless_media()->is_connected_to_gs() !== true) { throw new FatalException(__('Not connected to GCS', ud_get_stateless_media()->domain)); } $file = get_post($id); if (!$file || 'attachment' != $file->post_type) { throw new UnprocessableException(sprintf(__('Attachment not found: %s is an invalid file ID.', ud_get_stateless_media()->domain), $id)); } $fullsizepath = get_attached_file($file->ID); $local_file_exists = file_exists($fullsizepath); if (false === $fullsizepath || !$local_file_exists) { // Try get it and save $result_code = ud_get_stateless_media()->get_client()->get_media(apply_filters('wp_stateless_file_name', $fullsizepath, true, "", ""), true, $fullsizepath); if ($result_code !== 200) { if (!Utility::sync_get_attachment_if_exist($file->ID, $fullsizepath)) { // Save file to local from proxy. throw new UnprocessableException(sprintf(__('File not found (%s)', ud_get_stateless_media()->domain), $file->guid)); } else { $local_file_exists = true; } } else { $local_file_exists = true; } } if ($local_file_exists) { if (!ud_get_stateless_media()->get_client()->media_exists(apply_filters('wp_stateless_file_name', $fullsizepath, true, "", ""))) { if (!function_exists('wp_generate_attachment_metadata')) { require_once ABSPATH . '/wp-admin/includes/media.php'; require_once ABSPATH . '/wp-admin/includes/image.php'; } $metadata = wp_generate_attachment_metadata($file->ID, $fullsizepath); if (is_wp_error($metadata)) { throw new UnprocessableException($metadata->get_error_message()); } wp_update_attachment_metadata($file->ID, $metadata); do_action('sm:synced::nonImage', $id, $metadata); } else { // Ephemeral and Stateless modes: we don't need the local version. if (ud_get_stateless_media()->get('sm.mode') === 'ephemeral' || ud_get_stateless_media()->get('sm.mode') === 'stateless') { @unlink($fullsizepath); $metadata = wp_get_attachment_metadata($file->ID); /** * removing thumbnails * https://github.com/udx/wp-stateless/issues/577 */ if (!empty($metadata['sizes'])) { $base_dir = dirname($fullsizepath); foreach ($metadata['sizes'] as $image_size => $data) { $gs_name = $base_dir . '/' . $data['file']; if (file_exists($gs_name)) { @unlink($gs_name); } } } } } } return $file; } /** * Return list of files in a dir. * @param string $dir: Directory path * @return array - Lists of files in the directory and subdirectory. */ public static function get_files($dir) { $return = array(); if (is_dir($dir) && $dh = opendir($dir)) { while ($file = readdir($dh)) { if ($file != '.' && $file != '..') { if (is_dir($dir . $file)) { // since it is a directory we recursively get files. $arr = self::get_files($dir . $file . '/'); $return = array_merge($return, $arr); } else { $return[] = $dir . $file; } } } closedir($dh); } return $return; } } } } ================================================ FILE: lib/classes/compatibility/ewww.php ================================================ false, 'download' => true, 'use_root' => true ) ); } /** * If image size not exist then upload it to GS. * * @param $file * @param $type * @param $fullsize */ public function post_optimization( $file, $type, $fullsize ) { // wp_stateless_file_name filter will remove the basedir from the path and prepend with root dir. $name = apply_filters( 'wp_stateless_file_name', $file ); do_action( 'sm:sync::syncFile', $name, $file, true, array( 'use_root' => true ) ); // if($fullsize && file_exists($file . '.bak')) // do_action( 'sm:sync::syncFile', $name . '.bak', $file . '.bak', true); if( file_exists( $file . '.webp' ) ) { add_filter( 'upload_mimes', array( $this, 'add_webp_mime' ), 10, 2 ); do_action( 'sm:sync::syncFile', $name . '.webp', $file . '.webp', true, array( 'use_root' => true ) ); remove_filter( 'upload_mimes', array( $this, 'add_webp_mime' ), 10 ); } } } } } ================================================ FILE: lib/classes/compatibility/imagify.php ================================================ is_extension_supported()) { return false; } } elseif (function_exists('imagify_is_attachment_mime_type_supported')) { // Use `imagify_is_attachment_mime_type_supported( $attachment_id )`. if (!imagify_is_attachment_mime_type_supported($attachment_id)) { return false; } } elseif (!wp_attachment_is_image($attachment_id)) { return false; } return true; } /** * Added fix for Imagify version 1.9 * In Ephemeral mode remove files from server after optimization process `imagify_after_optimize_file` * @param $return * @param $metadata * @param $attachment_id * @param bool $force * @param array $args * @return bool * @author palant@ud */ public function skip_remove_media($return, $metadata, $attachment_id, $force = false, $args = array()) { global $doing_manual_sync; if ($force || $doing_manual_sync || !get_imagify_option('auto_optimize')) return false; $imagify = new \Imagify\Optimization\File(get_attached_file($attachment_id)); if (is_callable(array($imagify, 'is_supported'))) { if (!$imagify->is_supported(imagify_get_mime_types())) { return false; } } elseif (function_exists('imagify_is_attachment_mime_type_supported')) { // Use `imagify_is_attachment_mime_type_supported( $attachment_id )`. if (!imagify_is_attachment_mime_type_supported($attachment_id)) { return false; } } elseif (!wp_attachment_is_image($attachment_id)) { return false; } return true; } /** * Try to restore images before compression * * @param $attachment_id * @return mixed */ public function fix_missing_file($attachment_id) { /** * If mode is ephemeral then we change it to cdn in order images not being deleted before optimization * Remember that we changed mode via global var */ if (ud_get_stateless_media()->get('sm.mode') == 'ephemeral') { ud_get_stateless_media()->set('sm.mode', 'cdn'); global $wp_stateless_imagify_mode; $wp_stateless_imagify_mode = 'ephemeral'; } $upload_basedir = wp_upload_dir(); $upload_basedir = trailingslashit($upload_basedir['basedir']); $meta_data = wp_get_attachment_metadata($attachment_id); $file = $upload_basedir . $meta_data['file']; /** * Try to get all missing files from GCS */ if (!file_exists($file)) { ud_get_stateless_media()->get_client()->get_media(apply_filters('wp_stateless_file_name', $meta_data['file']), true, $file); } if (!empty($meta_data['sizes']) && is_array($meta_data['sizes'])) { $upload_basedir = trailingslashit(dirname($file)); foreach ($meta_data['sizes'] as $image) { if (!empty($image['gs_name']) && !file_exists($file = $upload_basedir . $image['file'])) { ud_get_stateless_media()->get_client()->get_media(apply_filters('wp_stateless_file_name', $image['gs_name']), true, $file); } } } } /** * If image size not exist then upload it to GS. * * $args = array( * 'thumbnail' => $thumbnail, * 'p_img_large' => $p_img_large, * ) * @param $id */ public function after_imagify_optimize_attachment($id) { /** * Restore ephemeral mode if needed */ global $wp_stateless_imagify_mode; if ($wp_stateless_imagify_mode == 'ephemeral') { ud_get_stateless_media()->set('sm.mode', 'ephemeral'); } $metadata = wp_get_attachment_metadata($id); ud_get_stateless_media()->add_media($metadata, $id, true); // Sync backup file with GCS if (current_filter() == 'after_imagify_optimize_attachment') { /** * If mode is ephemeral then we change it to cdn in order images not being deleted before optimization * Remember that we changed mode via global var * @todo remove if Imagify implement "imagify_has_backup" filter. */ if (ud_get_stateless_media()->get('sm.mode') == 'ephemeral') { ud_get_stateless_media()->set('sm.mode', 'cdn'); global $wp_stateless_imagify_mode; $wp_stateless_imagify_mode = 'ephemeral'; } $file_path = get_attached_file($id); $backup_path = get_imagify_attachment_backup_path($file_path); if (file_exists($backup_path)) { $overwrite = apply_filters('imagify_backup_overwrite_backup', false, $file_path, $backup_path); // wp_stateless_file_name filter will remove the basedir from the path and prepend with root dir. $name = apply_filters('wp_stateless_file_name', $backup_path); do_action('sm:sync::syncFile', $name, $backup_path, $overwrite); } } } /** * Restore backup file from GCS if not exist. * @param $id */ public function get_image_from_gcs($id) { $file_path = get_attached_file($id); $backup_path = get_imagify_attachment_backup_path($file_path); if (!file_exists($backup_path)) { $upload_dir = wp_upload_dir(); $name = str_replace(trailingslashit($upload_dir['basedir']), '', $backup_path); $name = apply_filters('wp_stateless_file_name', $name); do_action('sm:sync::syncFile', $name, $backup_path, true); } } /** * Check if backup exists in GCS. * @param $return * @param $has_backup * @return bool */ public function imagify_has_backup($return, $has_backup) { if (!$return && $has_backup) { $name = apply_filters('wp_stateless_file_name', $has_backup); $return = (bool) apply_filters('sm:sync::queue_is_exists', $name); } return $return; } /** * Synchronization after optmize process * @param $file * @param array $args */ public function imagify_after_optimize_file($file, $args = array()) { global $wp_stateless_imagify_mode; if ($wp_stateless_imagify_mode == 'ephemeral') { ud_get_stateless_media()->set('sm.mode', 'ephemeral'); } $name = apply_filters('wp_stateless_file_name', basename($file)); if (file_exists($file)) { add_filter('upload_mimes', array($this, 'add_webp_mime'), 10, 2); /** * Media already on GCS, so only replacing data on it. For webp format adding path and status to wp_stateless_files table */ do_action('sm:sync::syncFile', $name, $file, true, array('use_root' => true, 'skip_db' => (substr($name, -4) == "webp" ? false : true))); remove_filter('upload_mimes', array($this, 'add_webp_mime'), 10); } } /** * @param $return * @param $process * @param $file * @param $thumb_size * @param $optimization_level * @param $webp * @param $is_disabled * @return mixed */ public function imagify_before_optimize_size($return, $process, $file, $thumb_size, $optimization_level, $webp, $is_disabled) { try { $attachment_id = $this->getProperties($this->getProperties($this->getProperties($process)['data'])['media'])['id']; $full_size_path = $file->get_path(); $name = apply_filters('wp_stateless_file_name', basename($full_size_path), true, $attachment_id); do_action('sm:sync::syncFile', $name, $full_size_path, true, ['download' => true]); // error_log("\n\ndo_action( 'sm:sync::syncFile', $name, $full_size_path, true, ['download' => true] );"); } catch (\Throwable $th) { //throw $th; } return $return; } /** * Get properties from protected value * @param $process * @return array */ public function getProperties($process) { $properties = array(); try { $rc = new \ReflectionClass($process); do { $rp = array(); /* @var $p \ReflectionProperty */ foreach ($rc->getProperties() as $p) { $p->setAccessible(true); $rp[$p->getName()] = $p->getValue($process); } $properties = array_merge($rp, $properties); } while ($rc = $rc->getParentClass()); } catch (\ReflectionException $e) { } return $properties; } } } } ================================================ FILE: lib/classes/compatibility/js/shortpixel.js ================================================ /** * Overriding sliderUpdate() function of shortpixel-image-optimiser\res\js\short-pixel.js * We need to replace sites url with GCS url */ // backing up original function var _bk_sliderUpdate = sliderUpdate; // overriding the original function sliderUpdate = function sliderUpdate(id, thumb, bkThumb, percent, filename) { // replacing sites url with GCS url. thumb = thumb.replace( _stateless_short_pixel.baseurl, _stateless_short_pixel.bucketLink ); // using original function aftr altering thumb url. _bk_sliderUpdate(id, thumb, bkThumb, percent, filename); }; ================================================ FILE: lib/classes/compatibility/learn-dash.php ================================================ hook_from_learndash()) { return $filename; } return $return; } /** * Determine where we hook from * We need to do this only for something specific in LearnDash plugin * * @return bool */ private function hook_from_learndash() { $call_stack = debug_backtrace(); if ( !empty($call_stack[6]['function']) && $call_stack[6]['function'] == 'sanitize_file_name' && (strpos($call_stack[6]['file'], 'class-ld-semper-fi-module.php') || strpos($call_stack[6]['file'], 'class-ld-cpt-instance.php')) ) { return true; } return false; } } } } ================================================ FILE: lib/classes/compatibility/shortpixel.php ================================================ path('lib/classes/compatibility/js/shortpixel.js', 'url'), array('shortpixel'), '', true); $image_host = ud_get_stateless_media()->get_gs_host(); $bucketLink = apply_filters('wp_stateless_bucket_link', $image_host); wp_localize_script('stateless-short-pixel', '_stateless_short_pixel', array('baseurl' => $upload_dir['baseurl'], 'bucketLink' => $bucketLink,)); } /** * Return Path of ShortPixel backup path. * Bypass the checking whether a backup file exist when returning backup path. * @todo check on GCS if backup really exist. Maybe we can implement transient caching for performance. * * @param $ret * @param $file * @param $thumbs * @return string */ public function getBackupFolderAny($ret, $file, $thumbs) { if ($ret == false) { $fullSubDir = $this->returnSubDir($file); $ret = SHORTPIXEL_BACKUP_FOLDER . '/' . $fullSubDir; } return $ret; } /** * Check whether image exist on GCS. * Only when image is not available on server. * * @param $return * @param $path * @param null $id * @return bool */ public function shortpixel_image_exists($return, $path, $id = null) { if ($return) return $return; $key = "stateless_url_to_postid_" . md5($path); $return = get_transient($key); // echo "\npath: $path \nKey: $key\nReturn: $return\nID: $id\n "; if (!$return) { // Checking by matching file name in gs_name and $path. if (!empty($id)) { $metadata = wp_get_attachment_metadata($id); $basename = basename($path); if (!empty($metadata['gs_name'])) { $gs_basename = basename($metadata['gs_name']); if ($gs_basename == $basename) { $return = true; } if (is_array($metadata['sizes'])) { foreach ($metadata['sizes'] as $key => &$data) { if (empty($data['gs_name'])) continue; $gs_basename = basename($data['gs_name']); if ($gs_basename == $basename) { $return = true; } } } } } // Directly check on GCS if image exist. else if (empty($id)) { $wp_uploads_dir = wp_get_upload_dir(); $gs_name = str_replace(trailingslashit($wp_uploads_dir['basedir']), '', $path); $gs_name = str_replace(trailingslashit($wp_uploads_dir['baseurl']), '', $gs_name); $gs_name = str_replace(trailingslashit(ud_get_stateless_media()->get_gs_host()), '', $gs_name); $gs_name = apply_filters('wp_stateless_file_name', $gs_name); if ($media = ud_get_stateless_media()->get_client()->media_exists($gs_name)) { $return = true; } } set_transient($key, $return, 10 * MINUTE_IN_SECONDS); } return $return; } /** * Short-circuit filter. * We need to remove backup image from GCS when shortpixel tries to delete from server. * We are returning true to short-circuit in ephemeral mode, because file not exist in server. * * @param $return * @param $paths * @return bool */ public function shortpixel_skip_delete_backups_and_webps($return, $paths) { if (empty($paths) || !is_array($paths)) return $return; $sp__uploads = wp_upload_dir(); $fullSubDir = $this->returnSubDir($paths[0]); $backup_path = SHORTPIXEL_BACKUP_FOLDER . '/' . $fullSubDir; foreach ($paths as $key => $path) { // Removing backup $name = apply_filters('wp_stateless_file_name', SHORTPIXEL_BACKUP . '/' . $fullSubDir . basename($path)); do_action('sm:sync::deleteFile', $name); // Removing WebP $backup_images = \WPShortPixelSettings::getOpt('wp-short-create-webp'); if ($backup_images) { $name = str_replace($sp__uploads['basedir'], '', $path); $name = apply_filters('wp_stateless_file_name', $name . '.webp'); do_action('sm:sync::deleteFile', $name); } } if (ud_get_stateless_media()->get('sm.mode') == 'ephemeral') { return true; } // When ephemeral mode isn't set backup files will be available in server. So no short-circuit. return $return; } /** * Skip the original backup process in ephemeral mode. * * @param $return * @param $mainPath * @param $PATHs * @return bool */ public function shortpixel_skip_backup($return, $mainPath, $PATHs) { if (ud_get_stateless_media()->get('sm.mode') == 'ephemeral') { return true; } return $return; } /** * In ephemeral mode we need to take backup directly from original location. * Because we will skip the backup process of shortpixel. * * @param $metadata * @param $attachment_id * @return mixed */ public function wp_update_attachment_metadata($metadata, $attachment_id) { if (ud_get_stateless_media()->get('sm.mode') == 'ephemeral') { $backup_images = \WPShortPixelSettings::getOpt('wp-short-backup_images'); if ($backup_images) { $this->sync_backup_file($attachment_id, $metadata, false, array('before_optimization' => true)); } } return $metadata; } /** * Sync image after optimization. * * @param $id */ public function shortpixel_image_optimised($id) { $metadata = wp_get_attachment_metadata($id); ud_get_stateless_media()->add_media($metadata, $id, true); // Sync the webp to GCS $create_webp = \WPShortPixelSettings::getOpt('wp-short-create-webp'); if ($create_webp) { $this->sync_webp_file($id, $metadata); } // Don't needed in ephemeral mode. In ephemeral mode the back will be sync once on wp_update_attachment_metadata filter. if (ud_get_stateless_media()->get('sm.mode') !== 'ephemeral') { $this->sync_backup_file($id, $metadata, true); } } /** * Before shortpixel tries to restore from backup we need to make files available on server. * * @param $id * @param null $metadata */ public function shortpixel_before_restore_image($id, $metadata = null) { $this->sync_backup_file($id, $metadata, true, array('download' => true)); } /** * Disable default shortpixel restore and directly update image on GCS from backup copy in GCS. * * @param $return * @param null $id * @return bool */ public function shortpixel_skip_restore_image($return, $id = null) { if (ud_get_stateless_media()->get('sm.mode') === 'ephemeral') { $this->client = ud_get_stateless_media()->get_client(); $this->client->copy_media('localhost/ShortpixelBackups/wp-content/uploads/2019/04/htpps.png', 'localhost/2019/04/htpps.png'); return true; } return $return; } /** * Sync backup image * * @param $id * @param null $metadata * @param bool $force * @param array $args * before_optimization : pass true if you want to sync directly from original path instead of backup path. */ public function sync_backup_file($id, $metadata = null, $force = false, $args = array()) { $args = wp_parse_args($args, array( 'download' => false, // whether to only download. 'before_optimization' => false, // whether to delete local file in ephemeral mode. )); /* Get metadata in case if method is called directly. */ if (empty($metadata)) { $metadata = wp_get_attachment_metadata($id); } /* Now we go through all available image sizes and upload them to Google Storage */ if (!empty($metadata['sizes']) && is_array($metadata['sizes'])) { // Sync backup file with GCS $file_path = get_attached_file($id); $fullSubDir = $this->returnSubDir($file_path); $backup_path = SHORTPIXEL_BACKUP_FOLDER . '/' . $fullSubDir; if ($args['before_optimization']) { $upload_dir = wp_upload_dir(); $backup_path = $upload_dir['basedir'] . '/' . dirname($metadata['file']); $args = array('ephemeral' => false); } $absolutePath = trailingslashit($backup_path) . basename($metadata['file']); $name = apply_filters('wp_stateless_file_name', SHORTPIXEL_BACKUP . '/' . $fullSubDir . basename($metadata['file'])); do_action('sm:sync::syncFile', $name, $absolutePath, $force, $args); foreach ((array) $metadata['sizes'] as $image_size => $data) { $absolutePath = trailingslashit($backup_path) . $data['file']; $name = apply_filters('wp_stateless_file_name', SHORTPIXEL_BACKUP . '/' . $fullSubDir . $data['file']); do_action('sm:sync::syncFile', $name, $absolutePath, $force, $args); } } } /** * Sync from sync tab * * @param $id * @param null $metadata */ public function sync_webp_file($id, $metadata = null) { /* Get metadata in case if method is called directly. */ if (empty($metadata)) { $metadata = wp_get_attachment_metadata($id); } add_filter('upload_mimes', array($this, 'add_webp_mime'), 10, 2); // Sync the webp to GCS ud_get_stateless_media()->add_media($metadata, $id, true, array('is_webp' => '.webp')); remove_filter('upload_mimes', array($this, 'add_webp_mime'), 10); } /** * return subdir for that particular attached file - if it's media library then last 3 path items, otherwise substract the uploads path * Has trailing directory separator (/) * * @copied from shortpixel-image-optimiser\class\db\shortpixel-meta-facade.php * @param type $file * @return string */ public function returnSubDir($file) { $hp = wp_normalize_path(get_home_path()); $file = wp_normalize_path($file); $sp__uploads = wp_upload_dir(); if (strstr($file, $hp)) { $path = str_replace($hp, "", $file); } elseif (strstr($file, dirname(WP_CONTENT_DIR))) { //in some situations the content dir is not inside the root, check this also (ex. single.shortpixel.com) $path = str_replace(trailingslashit(dirname(WP_CONTENT_DIR)), "", $file); } elseif ((strstr(realpath($file), realpath($hp)))) { $path = str_replace(realpath($hp), "", realpath($file)); } elseif (strstr($file, trailingslashit(dirname(dirname($sp__uploads['basedir']))))) { $path = str_replace(trailingslashit(dirname(dirname($sp__uploads['basedir']))), "", $file); } else { $path = (substr($file, 1)); } $pathArr = explode('/', $path); unset($pathArr[count($pathArr) - 1]); return implode('/', $pathArr) . '/'; } /** * Sync images after shortpixel restore them from backup. * * @param $attachmentID */ public function handleRestoreBackup($attachmentID) { $metadata = wp_get_attachment_metadata($attachmentID); $this->add_media($metadata, $attachmentID); } /** * Customized version of wpCloud\StatelessMedia\Utility::add_media() * to satisfied our need in restore backup * If a image isn't restored from backup then ignore it. * * @param $metadata * @param $attachment_id */ public static function add_media($metadata, $attachment_id) { $upload_dir = wp_upload_dir(); $client = ud_get_stateless_media()->get_client(); if (!is_wp_error($client)) { $fullsizepath = wp_normalize_path(get_attached_file($attachment_id)); // Make non-images uploadable. if (empty($metadata['file']) && $attachment_id) { $metadata = array("file" => str_replace(trailingslashit($upload_dir['basedir']), '', get_attached_file($attachment_id))); } $file = wp_normalize_path($metadata['file']); $image_host = ud_get_stateless_media()->get_gs_host(); $bucketLink = apply_filters('wp_stateless_bucket_link', $image_host); $_cacheControl = \wpCloud\StatelessMedia\Utility::getCacheControl($attachment_id, $metadata, null); $_contentDisposition = \wpCloud\StatelessMedia\Utility::getContentDisposition($attachment_id, $metadata, null); $_metadata = array("width" => isset($metadata['width']) ? $metadata['width'] : null, "height" => isset($metadata['height']) ? $metadata['height'] : null, 'object-id' => $attachment_id, 'source-id' => md5($attachment_id . ud_get_stateless_media()->get('sm.bucket')), 'file-hash' => md5($metadata['file'])); if (file_exists($fullsizepath)) { $file = apply_filters('wp_stateless_file_name', $file); /* Add default image */ $media = $client->add_media($_mediaOptions = array_filter(array('force' => true, 'name' => $file, 'absolutePath' => wp_normalize_path(get_attached_file($attachment_id)), 'cacheControl' => $_cacheControl, 'contentDisposition' => $_contentDisposition, 'mimeType' => get_post_mime_type($attachment_id), 'metadata' => $_metadata))); // ephemeral mode: we don't need the local version. if (ud_get_stateless_media()->get('sm.mode') === 'ephemeral') { unlink($fullsizepath); } } /* Now we go through all available image sizes and upload them to Google Storage */ if (!empty($metadata['sizes']) && is_array($metadata['sizes'])) { $path = wp_normalize_path(dirname(get_attached_file($attachment_id))); $mediaPath = apply_filters('wp_stateless_file_name', trim(dirname($metadata['file']), '\/\\')); foreach ((array) $metadata['sizes'] as $image_size => $data) { $absolutePath = wp_normalize_path($path . '/' . $data['file']); if (!file_exists($absolutePath)) { continue; } /* Add 'image size' image */ $media = $client->add_media(array('force' => true, 'name' => $file_path = trim($mediaPath . '/' . $data['file'], '/'), 'absolutePath' => $absolutePath, 'cacheControl' => $_cacheControl, 'contentDisposition' => $_contentDisposition, 'mimeType' => $data['mime-type'], 'metadata' => array_merge($_metadata, array('width' => $data['width'], 'height' => $data['height'], 'child-of' => $attachment_id, 'file-hash' => md5($data['file']))))); /* Break if we have errors. */ if (!is_wp_error($media)) { // ephemeral mode: we don't need the local version. if (ud_get_stateless_media()->get('sm.mode') === 'ephemeral') { unlink($absolutePath); } } } } } } // End add_media /** * modifying gs_name and absolutePath so that we can upload webp image using the same Utility::add_media function. * * @param $args * @return mixed */ public function wp_stateless_add_media_args($args) { if (!empty($args['is_webp']) && $args['is_webp']) { if (\file_exists($args['absolutePath'] . '.webp')) { $args['name'] = $args['name'] . '.webp'; $args['absolutePath'] = $args['absolutePath'] . '.webp'; } else { $pathinfo = pathinfo($args['absolutePath']); $absolutePath = trailingslashit($pathinfo['dirname']) . $pathinfo['filename'] . '.webp'; if (file_exists($absolutePath)) { $args['name'] = $args['name'] . '.webp'; $args['absolutePath'] = $absolutePath; } } $args['mimeType'] = 'image/webp'; } return $args; } /** * Bypass server url check and return base url for GCS image. * * @param $imageBase * @param $src * @return mixed */ public function shortpixel_webp_image_base($imageBase, $src) { $gs_link = \ud_get_stateless_media()->convert_to_gs_link($src, true); if ($gs_link) { $imageBase = trailingslashit(dirname($gs_link)); } return $imageBase; } /** * @param $URLs * @param $id * @return mixed */ public function shortpixel_image_urls($URLs, $id) { foreach ($URLs as $key => $url) { $url_parts = wp_parse_url($url); if ($url_parts['host'] == 'storage.googleapis.com') { if (preg_match("@(^/?.*?/)(.*)@", $url_parts['path'], $matches)) { $bucket = trim($matches[1], '/'); $url_parts['path'] = $matches[2]; $url_parts['host'] = $bucket . '.' . $url_parts['host']; $URLs[$key] = Utility::join_url($url_parts); } } } return $URLs; } } } } ================================================ FILE: lib/classes/compatibility/the-events-calendar.php ================================================ core()->mod->settings->get('auto'); } else { global $wpsmush_settings; $auto_smush = $wpsmush_settings->settings['auto']; } if ( !$auto_smush || !wp_attachment_is_image($attachment_id) || !apply_filters('wp_smush_image', true, $attachment_id) || !( ((!empty($_POST['action']) && 'upload-attachment' == $_POST['action']) || isset($_POST['post_id'])) && // And, check if Async is enabled. defined('WP_SMUSH_ASYNC') && WP_SMUSH_ASYNC) ) { return false; } return true; } /** * Sync image after it's been optimized. * * @param int $attachment_id attachment id * @param array $stats compression stats * * @return null */ public function image_optimized($attachment_id, $stats) { // Sync the attachment to GCS ud_get_stateless_media()->add_media(array(), $attachment_id, true); // also sync the backup images $this->sync_backup($attachment_id); } /** * If local file don't exists then download it from GCS * * @param string $file_path Full file path * @param string $attachment_id * @param array $size_details Array of width and height for the image * * @return null */ function maybe_download_file($file_path = '', $attachment_id = '', $size_details = array()) { if (empty($file_path) || empty($attachment_id)) { return; } //Download if file not exists if (!file_exists($file_path)) { $client = ud_get_stateless_media()->get_client(); $metadata = wp_get_attachment_metadata($attachment_id); if (!empty($metadata['gs_name'])) { $image_sizes = Utility::get_path_and_url($metadata, $attachment_id); foreach ($image_sizes as $size => $img) { $client->get_media(apply_filters('wp_stateless_file_name', $img['gs_name']), true, $img['path']); } $gs_name = dirname($metadata['gs_name']) . '/' . basename($file_path); // We need to remove backup from GCS if it's a restore action // @todo revise this code if ($this->hook_from_restore_image()) { $client->remove_media(apply_filters('wp_stateless_file_name', $gs_name)); } } } } /** * Remove backup when attachment is removed * * @param $attachment_id */ function remove_backup($attachment_id) { $upload_dir = wp_get_upload_dir(); $metadata = wp_get_attachment_metadata($attachment_id); $backup_paths = get_post_meta($attachment_id, '_wp_attachment_backup_sizes', true); if (!empty($metadata['gs_name']) && !empty($backup_paths) && is_array($backup_paths)) { // Getting local dir path for backup image $base_dir = $upload_dir['basedir'] . '/' . dirname($metadata['file']); // Getting GCS dir name from meta data. In case Bucket Folder used. $gs_dir = dirname($metadata['gs_name']); foreach ($backup_paths as $key => $data) { $gs_name = $gs_dir . '/' . basename($data['file']); // Path of backup image $backup_path = $base_dir . '/' . basename($data['file']); do_action('sm:sync::deleteFile', apply_filters('wp_stateless_file_name', $gs_name), $backup_path); delete_transient('sm-wp-smush-backup-exists-' . $attachment_id); } } } /** * Checks if we've backup on gcs for the given attachment id and backup path * * @param string $attachment_id * @param string $backup_path * * @return bool */ function backup_exists_on_gcs($exists, $attachment_id = '', $backup_path = '') { if (!$exists && $attachment_id) { if (get_transient('sm-wp-smush-backup-exists-' . $attachment_id)) { return true; } $metadata = wp_get_attachment_metadata($attachment_id); if (!empty($metadata['gs_name'])) { $gs_name = dirname($metadata['gs_name']) . '/' . basename($backup_path); if (ud_get_stateless_media()->get_client()->media_exists(apply_filters('wp_stateless_file_name', $gs_name))) { set_transient('sm-wp-smush-backup-exists-' . $attachment_id, true, HOUR_IN_SECONDS); return true; } } } return $exists; } /** * Sync backup image to GCS * * @param $attachment_id * @param array $metadata */ public function sync_backup($attachment_id, $metadata = array()) { $upload_dir = wp_get_upload_dir(); if (empty($metadata) || empty($metadata['gs_name'])) { $metadata = wp_get_attachment_metadata($attachment_id); } // Getting backup path from smush settings in db $backup_paths = get_post_meta($attachment_id, '_wp_attachment_backup_sizes', true); if (!empty($metadata['gs_name']) && !empty($backup_paths) && is_array($backup_paths)) { // Getting local dir for backup image $base_dir = $upload_dir['basedir'] . '/' . dirname($metadata['file']); // Getting GCS dir name from meta data. In case Bucket Folder used. $gs_dir = dirname($metadata['gs_name']); foreach ($backup_paths as $key => $data) { $gs_name = $gs_dir . '/' . basename($data['file']); // Path of backup image $backup_path = $base_dir . '/' . basename($data['file']); // Sync backup image with GCS do_action('sm:sync::syncFile', apply_filters('wp_stateless_file_name', $gs_name), $backup_path); delete_transient('sm-wp-smush-backup-exists-' . $attachment_id); } } } /** * Determine where we hook from * Is this a hook from wp smush restore image or not. * * @return bool */ private function hook_from_restore_image() { $call_stack = debug_backtrace(); $class_name = class_exists('WpSmushBackup') ? 'WpSmushBackup' : 'WP_Smush_Backup'; if (!empty($call_stack) && is_array($call_stack)) { foreach ($call_stack as $step) { if ($step['function'] == 'restore_image' && $step['class'] == $class_name) { return true; } } } return false; } } } } ================================================ FILE: lib/classes/compatibility/wpbakery-page-builder.php ================================================ enabled) { // We need to add the filter on construct. Init is too late. add_filter('vc_wpb_getimagesize', array($this, 'vc_wpb_getimagesize'), 10, 3); } } /** * @param $sm */ public function module_init($sm) { // } /** * If image size not exist then generate size info and update attachment metadata. * * $args = array( * 'thumbnail' => $thumbnail, * 'p_img_large' => $p_img_large, * ) * * @param $args * @param $attach_id * @param $params * @return mixed */ public function vc_wpb_getimagesize($args, $attach_id, $params) { if (!$this->enabled) return $args; $gs_host = ud_get_stateless_media()->get_gs_host(); $meta_data = wp_get_attachment_metadata($attach_id); preg_match("/src=[\"|'](.*?)[\"|']/", $args['thumbnail'], $match); if (!empty($match[1]) && empty($meta_data['sizes'][$params['thumb_size']])) { $dir = wp_upload_dir(); $url = $match[1]; $path = str_replace($gs_host, '', $url); $path = trim($path, '/'); $absolute_path = $dir['basedir'] . '/' . $path; $size = getimagesize($absolute_path); $filetype = wp_check_filetype($absolute_path); $size_info = array( 'file' => wp_basename($absolute_path), 'mime-type' => $filetype['type'], 'width' => $size[0], 'height' => $size[1], ); $meta_data['sizes'][$params['thumb_size']] = $size_info; wp_update_attachment_metadata($attach_id, $meta_data); } return $args; } } } } ================================================ FILE: lib/classes/exception-fatal.php ================================================ _init_hooks(); } private function _init_hooks() { add_filter('wp_stateless_status_info_values_google_cloud', [$this, 'get_bucket_info'], 10); add_filter('wp_stateless_status_info_values_google_cloud', [$this, 'format_values'], 99); add_filter('wp_stateless_status_info_values_google_cloud_public_access', [$this, 'get_public_access_value'], 10); add_filter('wp_stateless_status_info_values_google_cloud_access_control', [$this, 'get_access_control'], 10); add_filter('wp_stateless_status_info_values_google_cloud_versioning', [$this, 'get_versioning'], 10); add_filter('wp_stateless_status_info_values_google_cloud_soft_delete', [$this, 'get_soft_delete'], 10); } /** * Format values to human-readable */ public function format_values($values) { foreach ($values as $key => $value) { $values[$key]['value'] = apply_filters("wp_stateless_status_info_values_google_cloud_$key", $values[$key]['value']); } return $values; } /** * Format 'public_access' value */ public function get_public_access_value($value) { switch ($value) { case 'enforced': return __('Enforced', ud_get_stateless_media()->domain); case 'inherited': return __('Inherited', ud_get_stateless_media()->domain); } return $value; } /** * Format 'versioning' value */ public function get_versioning($value) { return $value ? __('Enabled', ud_get_stateless_media()->domain) : __('Disabled', ud_get_stateless_media()->domain); } /** * Get 'Access Control' value */ public function get_access_control($value) { return $value ? __('Uniform', ud_get_stateless_media()->domain) : __('Fine-grained', ud_get_stateless_media()->domain); } /** * Get 'Soft Delete' value */ public function get_soft_delete($value) { return $value > 0 ? __('Enabled', ud_get_stateless_media()->domain) : __('Disabled', ud_get_stateless_media()->domain); } /** * Get the values related to GCS bucket configuration */ public function get_bucket_info($values) { $rows = []; $client = ud_get_stateless_media()->get_client(); $bucket_name = ud_get_stateless_media()->get('sm.bucket'); if ( empty($client) || empty($bucket_name) ) { $rows = [ 'gcs_error' => [ 'label' => __('Error', ud_get_stateless_media()->domain), 'value' => __('Google Cloud info not accessible', ud_get_stateless_media()->domain), ], ]; return $values + $rows; } // Get bucket info try { $info = $client->service->buckets->get($bucket_name); $rows = [ 'storage_class' => [ 'label' => __('Storage Class', ud_get_stateless_media()->domain), 'value' => $info->storageClass, ], 'public_access' => [ 'label' => __('Public Access Prevention', ud_get_stateless_media()->domain), 'value' => $info->iamConfiguration->publicAccessPrevention, ], 'access_control' => [ 'label' => __('Access Control', ud_get_stateless_media()->domain), 'value' => $info->iamConfiguration->uniformBucketLevelAccess->enabled, ], 'versioning' => [ 'label' => __('Versioning', ud_get_stateless_media()->domain), 'value' => isset($info->versioning) && isset($info->versioning->enabled) ? $info->versioning->enabled : false, ], 'soft_delete' => [ 'label' => __('Soft Delete', ud_get_stateless_media()->domain), 'value' => isset($info->softDeletePolicy) && isset($info->softDeletePolicy->retentionDurationSeconds) ? $info->softDeletePolicy->retentionDurationSeconds : 0, ], ]; } catch ( \Throwable $e ) { $rows = [ 'gcs_error' => [ 'label' => __('Error', ud_get_stateless_media()->domain), 'value' => __('Google Cloud Storage Bucket info not available', ud_get_stateless_media()->domain), ], ]; } return $values + $rows; } } ================================================ FILE: lib/classes/status/class-info-stateless.php ================================================ _init_hooks(); } private function _init_hooks() { add_filter('wp_stateless_status_info_values_stateless', [$this, 'get_settings_values'], 10); add_filter('wp_stateless_status_info_values_stateless', [$this, 'get_settings_constants'], 20); add_filter('wp_stateless_status_info_values_stateless', [$this, 'get_media_stats'], 30); add_filter('wp_stateless_status_info_values_stateless', [$this, 'get_migrations'], 40); add_filter('wp_stateless_status_info_values_stateless', [$this, 'prepare_values'], 99); add_filter('wp_stateless_status_info_stateless_value', [$this, 'format_value'], 10, 3); add_filter('wp_stateless_status_info_stateless_value_mode', [$this, 'get_mode'], 10); add_filter('wp_stateless_status_info_stateless_value_body_rewrite', [$this, 'get_body_rewrite'], 10); add_filter('wp_stateless_status_info_stateless_value_bucket', [$this, 'get_is_set'], 10); add_filter('wp_stateless_status_info_stateless_value_bucket_accessible', [$this, 'get_yes_no_value'], 10); add_filter('wp_stateless_status_info_stateless_value_key_json', [$this, 'get_is_set'], 10); add_filter('wp_stateless_status_info_stateless_value_cache_control', [$this, 'get_cache_control'], 10); add_filter('wp_stateless_status_info_stateless_value_delete_remote', [$this, 'get_enabled_value'], 10); add_filter('wp_stateless_status_info_stateless_value_root_dir', [$this, 'get_root_dir'], 10); add_filter('wp_stateless_status_info_stateless_value_custom_domain', [$this, 'get_is_set'], 10); add_filter('wp_stateless_status_info_stateless_value_hashify_file_name', [$this, 'get_enabled_value'], 10); add_filter('wp_stateless_status_info_stateless_value_dynamic_image_support', [$this, 'get_enabled_value'], 10); add_filter('wp_stateless_status_info_stateless_value_use_postmeta', [$this, 'get_enabled_value'], 10); add_filter('wp_stateless_status_info_stateless_value_WP_STATELESS_LEGACY_URL_TO_POSTID', [$this, 'get_yes_no_value'], 10); add_filter('wp_stateless_status_info_stateless_value_WP_STATELESS_SKIP_ACL_SET', [$this, 'get_yes_no_value'], 10); } /** * Get settings * * @return array */ private function _get_setings() { if ( empty($this->settings) ) { $this->settings = ud_get_stateless_media()->get('sm'); } return $this->settings; } /** * Format mode setting * * @param string $value * @return string */ public function get_mode($value) { switch ($value) { case '': $value = __('Don\'t override', ud_get_stateless_media()->domain); break; case 'disabled': $value = __('Disabled', ud_get_stateless_media()->domain); break; case 'backup': $value = __('Backup', ud_get_stateless_media()->domain); break; case 'cdn': $value = __('CDN', ud_get_stateless_media()->domain); break; case 'ephemeral': $value = __('Ephemeral', ud_get_stateless_media()->domain); break; case 'stateless': $value = __('Stateless', ud_get_stateless_media()->domain); break; } return $value; } /** * Get body_rewrite setting * * @param string $value * @return string */ public function get_body_rewrite($value) { switch ($value) { case '': $value = __('Don\'t override', ud_get_stateless_media()->domain); break; case 'false': $value = __('Disabled', ud_get_stateless_media()->domain); break; case 'enable_editor': $value = __('Enable Editor', ud_get_stateless_media()->domain); break; case 'enable_meta': $value = __('Enable Meta', ud_get_stateless_media()->domain); break; case 'true': $value = __('Enable Editor & Meta', ud_get_stateless_media()->domain); break; } return $value; } /** * Format Cache Control setting * * @param bool $value * @return string */ public function get_cache_control($value) { if ( empty($value) ) { $value = sprintf( __('Default: %s', ud_get_stateless_media()->domain), ud_get_stateless_media()->get_default_cache_control() ); } return $value; } /** * Format Folder setting * * @param bool $value * @return string */ public function get_root_dir($value) { if ( empty($value) && is_network_admin() ) { $value = __('Don\'t override', ud_get_stateless_media()->domain); } return $value; } /** * Format the value if it is set or not * * @param bool $value * @return string */ public function get_is_set($value) { return (bool) $value ? __('Set', ud_get_stateless_media()->domain) : __('Not set', ud_get_stateless_media()->domain); } /** * Get boolean value (Yes/No) * * @param bool $value * @return string */ public function get_yes_no_value($value) { return (bool) $value ? __('Yes', ud_get_stateless_media()->domain) : __('No', ud_get_stateless_media()->domain); } /** * Get boolean value (Enable/Disabled) * * @param bool $value * @return string */ public function get_enabled_value($value) { switch ($value) { case '': $value = __('Don\'t override', ud_get_stateless_media()->domain); break; case 'true': $value = __('Enable', ud_get_stateless_media()->domain); break; case 'false': $value = __('Disable', ud_get_stateless_media()->domain); break; } return $value; } /** * Format stateless settings value * * @param string $value * @param string $key * @param array $sm * * @return string */ public function format_value($value, $key, $sm) { $value = apply_filters("wp_stateless_status_info_stateless_value_$key", $value, $sm); $readonly = array_keys( $sm['readonly'] ?? [] ); if ( in_array($key, $readonly)) { $type = $sm['readonly'][$key] ?? ''; $suffix = ''; $hint = $sm['strings'][$type] ?? ''; switch ($type) { case 'network': $suffix = __('Network', ud_get_stateless_media()->domain); break; case 'constant': $suffix = __('Constant', ud_get_stateless_media()->domain); break; case 'environment': $suffix = __('Environment', ud_get_stateless_media()->domain); break; } if ( !empty($suffix) ) { $value = sprintf( '
'. '%s '. '(%s%s)'. '', $suffix, ); } } return $value; } /** * Get WP-Stateless settings * * @param array $values * @return array */ public function get_settings_values($values) { $sm = $this->_get_setings(); $rows = [ 'version' => [ 'label' => __('Version', ud_get_stateless_media()->domain), 'value' => ud_get_stateless_media()::$version, ], 'db_version' => [ 'label' => __('Database Version', ud_get_stateless_media()->domain), 'value' => get_option( ud_stateless_db()::DB_VERSION_KEY, '' ), ], 'mode' => [ 'label' => __('Mode', ud_get_stateless_media()->domain), 'value' => $sm['mode'], ], 'body_rewrite' => [ 'label' => __('File URL Replacement', ud_get_stateless_media()->domain), 'value' => $sm['body_rewrite'], ], 'body_rewrite_types' => [ 'label' => __('Supported File Types', ud_get_stateless_media()->domain), 'value' => $sm['body_rewrite_types'], ], 'bucket' => [ 'label' => __('Bucket', ud_get_stateless_media()->domain), 'value' => !empty($sm['bucket']), ], 'bucket_accessible' => [ 'label' => __('Bucket Accessible', ud_get_stateless_media()->domain), 'value' => get_transient('sm::is_connected_to_gs'), ], 'key_json' => [ 'label' => __('Service Account JSON', ud_get_stateless_media()->domain), 'value' => !empty($sm['key_json']), ], 'cache_control' => [ 'label' => __('Cache-Control', ud_get_stateless_media()->domain), 'value' => $sm['cache_control'], ], 'delete_remote' => [ 'label' => __('Delete GCS File', ud_get_stateless_media()->domain), 'value' => $sm['delete_remote'], ], 'root_dir' => [ 'label' => __('Folder', ud_get_stateless_media()->domain), 'value' => $sm['root_dir'], ], 'custom_domain' => [ 'label' => __('Domain', ud_get_stateless_media()->domain), 'value' => !empty($sm['custom_domain']), ], 'hashify_file_name' => [ 'label' => __('Cache-Busting', ud_get_stateless_media()->domain), 'value' => $sm['hashify_file_name'], ], 'dynamic_image_support' => [ 'label' => __('Dynamic Image Support', ud_get_stateless_media()->domain), 'value' => $sm['dynamic_image_support'], ], 'use_api_siteurl' => [ 'label' => __('Use Site URL for REST API Requests', ud_get_stateless_media()->domain), 'value' => $sm['use_api_siteurl'], ], 'api_status' => [ 'label' => __('REST API Status', ud_get_stateless_media()->domain), 'value' => '%api_status%', ], 'ajax_status' => [ 'label' => __('AJAX Status', ud_get_stateless_media()->domain), 'value' => '%ajax_status%', ], 'use_postmeta' => [ 'label' => __('Use Post Meta', ud_get_stateless_media()->domain), 'value' => $sm['use_postmeta'], ], ]; return $values + $rows; } /** * Get constants settings, not available on Settings page * * @param array $values * @return array */ public function get_settings_constants($values) { $sm = $this->_get_setings(); $constants = [ 'WP_STATELESS_MEDIA_UPLOAD_CHUNK_SIZE' => __('Upload Chunk Size', ud_get_stateless_media()->domain), 'WP_STATELESS_SYNC_MAX_BATCH_SIZE' => __('Sync Max Batch Size', ud_get_stateless_media()->domain), 'WP_STATELESS_LEGACY_URL_TO_POSTID' => __('Change the Bucket Folder (root_dir) after uploading the image', ud_get_stateless_media()->domain), 'WP_STATELESS_SKIP_ACL_SET' => __('Skip setting file-level ACl when uniform bucket-level access is enabled', ud_get_stateless_media()->domain), ]; $rows = []; foreach ($constants as $key => $label) { if ( !defined($key) ) { continue; } // Mark all constants as readonly 'constant' $this->settings['readonly'][$key] = 'constant'; $rows[$key] = [ 'label' => $label, 'value' => constant($key), ]; } return $values + $rows; } /** * Get media stats * * @param array $values * @return array */ public function get_media_stats($values) { if (is_network_admin()) { return $values; } $rows = [ 'files' => [ 'label' => __('Total Files', ud_get_stateless_media()->domain), 'value' => ud_stateless_db()->get_total_files(), ], 'file_sizes' => [ 'label' => __('Total File Sizes', ud_get_stateless_media()->domain), 'value' => ud_stateless_db()->get_total_file_sizes(), ], 'compatibility_files' => [ 'label' => __('Compatibility Files', ud_get_stateless_media()->domain), 'value' => ud_stateless_db()->get_total_non_media_files(), ], ]; return $values + $rows; } public function prepare_values($values) { $sm = $this->_get_setings(); foreach ($values as $key => $value) { $values[$key]['value'] = apply_filters('wp_stateless_status_info_stateless_value', $value['value'], $key, $sm); } return $values; } public function get_migrations($values) { if (is_network_admin()) { return $values; } $state = apply_filters("wp_stateless_batch_state", [], ['force_migrations' => true]); if ( !is_array($state) || !isset( $state['migrations'] ) ) { return $value; } $migrations = []; foreach ($state['migrations'] as $key => $migration) { $migrations[] = sprintf( '%s: %s', $key, $migration['status_text'] ); } $rows = [ 'migrations' => [ 'label' => __('Data Optimization', ud_get_stateless_media()->domain), 'value' => implode(', ', $migrations), ], ]; return $values + $rows; } } ================================================ FILE: lib/classes/status/class-info.php ================================================ _init_hooks(); } private function _init_hooks() { add_action('wp_ajax_stateless_check_ajax', [$this, 'check_ajax']); add_action('wp_stateless_status_tab_content', [$this, 'tab_content'], 10); add_filter('wp_stateless_status_tab_visible', array($this, 'status_tab_visible'), 10, 1); add_filter('wp_stateless_status_info_values_server', [$this, 'get_server_values'], 10); add_filter('wp_stateless_status_info_values_server', [$this, 'get_php_values'], 20); add_filter('wp_stateless_status_info_values_server', [$this, 'get_php_modules'], 30); add_filter('wp_stateless_status_info_values_wordpress', [$this, 'get_wordpress_network_values'], 10); add_filter('wp_stateless_status_info_values_wordpress', [$this, 'get_wordpress_attachments'], 20); add_filter('wp_stateless_status_info_values_wordpress', [$this, 'get_wordpress_theme'], 30); add_filter('wp_stateless_status_info_values_wordpress', [$this, 'get_wordpress_plugins'], 40); } /** * Check AJAX requests are working */ public function check_ajax() { if ( !check_ajax_referer('stateless_check_ajax') ) { wp_send_json_error([ 'status' => __('Error', ud_get_stateless_media()->domain), 'message' => __('Invalid nonce', ud_get_stateless_media()->domain), ]); } wp_send_json_success([ 'status' => 'Ok', ]); } /** * Get boolean value (Yes/No) * * @param bool $value * @return string */ private function _get_bool_value($value) { return (bool) $value ? __('Yes', ud_get_stateless_media()->domain) : __('No', ud_get_stateless_media()->domain); } /** * Get server values * * @return array */ public function get_server_values($values = []) { global $wpdb; $server_architecture = function_exists( 'php_uname' ) ? [ php_uname('s'), php_uname('r'), php_uname('m') ] : [ __('Unknown', ud_get_stateless_media()->domain) ]; $rows = [ 'server_architecture' => [ 'label' => __('Server architecture', ud_get_stateless_media()->domain), 'value' => implode(' ', $server_architecture), ], 'web_server' => [ 'label' => __('Web server', ud_get_stateless_media()->domain), 'value' => isset($_SERVER['SERVER_SOFTWARE']) ? $_SERVER['SERVER_SOFTWARE'] : __('Unknown', ud_get_stateless_media()->domain), ], 'mysql' => [ 'label' => __('MySQL version', ud_get_stateless_media()->domain), 'value' => $wpdb->db_server_info(), ], ]; // Detect the default DB engine try { $default_engine = ''; $engines = $wpdb->get_results('SHOW ENGINES', ARRAY_A); foreach ($engines as $engine) { if ( $engine['Support'] === 'DEFAULT' ) { $default_engine = $engine['Engine']; break; } } if ( !empty($default_engine) ) { $rows['mysql_engine'] = [ 'label' => __('MySQL default engine', ud_get_stateless_media()->domain), 'value' => $default_engine, ]; } } catch (\Throwable $e) { } $rows['php'] = [ 'label' => __('PHP Version', ud_get_stateless_media()->domain), 'value' => PHP_VERSION, ]; return $values + $rows; } /** * Get PHP ini values * * @return array */ public function get_php_values($values = []) { if ( !function_exists('ini_get') ) { $values['php_ini_get'] = [ 'label' => __('PHP Config', ud_get_stateless_media()->domain), 'value' => __('Unable to determine some settings, init_get() is disabled.', ud_get_stateless_media()->domain), ]; return $values; } $rows = [ 'php_memory_limit' => [ 'label' => __('PHP Memory Limit', ud_get_stateless_media()->domain), 'value' => ini_get('memory_limit'), ], 'php_max_input_vars' => [ 'label' => __('PHP Max Input Vars', ud_get_stateless_media()->domain), 'value' => ini_get('max_input_vars'), ], 'php_max_post_size' => [ 'label' => __('PHP Max Post Size', ud_get_stateless_media()->domain), 'value' => ini_get('post_max_size'), ], 'php_time_limit' => [ 'label' => __('PHP Time Limit', ud_get_stateless_media()->domain), 'value' => ini_get('max_execution_time'), ], 'max_upload_size' => [ 'label' => __('Max Upload Size', ud_get_stateless_media()->domain), 'value' => ini_get('upload_max_filesize'), ], 'allow_url_fopen' => [ 'label' => __('Allow URL-aware fopen Wrappers', ud_get_stateless_media()->domain), 'value' => $this->_get_bool_value( ini_get('allow_url_fopen') ), ], ]; return $values + $rows; } /** * Get PHP modules * * @return array */ public function get_php_modules($values = []) { $values['extensions'] = [ 'label' => __('Loaded Extensions', ud_get_stateless_media()->domain), 'value' => implode(', ', get_loaded_extensions()), ]; return $values; } /** * Get WP global network values * * @return array */ public function get_wordpress_network_values($values = []) { $rows = [ 'home_url' => [ 'label' => __('Home URL', ud_get_stateless_media()->domain), 'value' => get_bloginfo( 'url' ), ], 'site_url' => [ 'label' => __('Site URL', ud_get_stateless_media()->domain), 'value' => get_bloginfo( 'wpurl' ), ], 'version' => [ 'label' => __('Version', ud_get_stateless_media()->domain), 'value' => get_bloginfo('version'), ], 'multisite' => [ 'label' => __('Multisite', ud_get_stateless_media()->domain), 'value' => $this->_get_bool_value( is_multisite() ), ], 'memory_limit' => [ 'label' => __('Memory Limit', ud_get_stateless_media()->domain), 'value' => WP_MEMORY_LIMIT, ], ]; return $values + $rows; } /** * Format WP theme value * * @param \WP_Theme $theme * @return string|null */ private function _format_theme_value($theme) { if ( !is_a($theme, '\WP_Theme') ) { return null; } $value = [$theme->name, $theme->version]; return implode(' ', $value); } /** * Get WP attachments info * * @return array */ public function get_wordpress_attachments($values = []) { if ( is_network_admin() ) { return $values; } global $wpdb; $total = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->posts WHERE post_type = 'attachment'"); $size_keys = get_intermediate_image_sizes(); $sizes = []; foreach ($size_keys as $size) { // Check if image size is not a name (e.g. '1536x1536') $parts = explode('x', $size); if ( count($parts) === 2 && is_numeric($parts[0]) && is_numeric($parts[1]) ) { $sizes[] = $size; continue; } $width = get_option("{$size}_size_w"); $height = get_option("{$size}_size_h"); $sizes[] = sprintf('(%dx%d) %s', $width, $height, $size); } $rows = [ 'total_attachments' => [ 'label' => __('Total Attachments', ud_get_stateless_media()->domain), 'value' => $total, ], 'image_sizes' => [ 'label' => sprintf( __('Image Sizes (%d)', ud_get_stateless_media()->domain), count($sizes) ), 'value' => implode(', ', $sizes) ], ]; return $values + $rows; } /** * Get WP theme values * * @return array */ public function get_wordpress_theme($values = []) { if ( is_network_admin() ) { return $values; } $theme = wp_get_theme(); if ( !is_a($theme, '\WP_Theme') ) { return $values; } $rows = [ 'theme' => [ 'label' => __('Theme', ud_get_stateless_media()->domain), 'value' => $this->_format_theme_value($theme), ], ]; $parent = $theme->parent(); if ( is_a($parent, '\WP_Theme') ) { $rows['parent_theme'] = [ 'label' => __('Parent Theme', ud_get_stateless_media()->domain), 'value' => $this->_format_theme_value($parent), ]; } return $values + $rows; } /** * Format WP plugin value * * @param array $plugin * @param bool $is_network * @return string */ private function _format_plugin_value($plugin, $is_network = false) { $value = [$plugin['Name'], $plugin['Version']]; if ($is_network) { $value[] = __('(network)', ud_get_stateless_media()->domain); } return implode(' ', $value); } /** * Get WP plugins list * * @return array */ public function get_wordpress_plugins($values = []) { if ( is_network_admin() ) { return $values; } $result = []; $plugins = get_plugins(); $active_plugins = (array) get_option( 'active_plugins', [] ); $network_plugins = (array) get_site_option( 'active_sitewide_plugins', [] ); $network_plugins = array_keys($network_plugins); foreach ($plugins as $file => $plugin) { if ( in_array($file, $network_plugins) ) { $result[] = $this->_format_plugin_value($plugin, true); continue; } if ( in_array($file, $active_plugins) ) { $result[] = $this->_format_plugin_value($plugin); } } $values['active_plugins'] = [ 'label' => __('Active Plugins', ud_get_stateless_media()->domain), 'value' => implode(', ', $result), ]; return $values; } /** * Get section values * * @param string $key * @return array|null */ private function _get_section_values($key) { try { $values = apply_filters("wp_stateless_status_info_values_$key", []); } catch (\Throwable $e) { $values = [ 'error' => [ 'label' => __('Error', ud_get_stateless_media()->domain), 'value' => $e->getMessage(), ], ]; } return empty($values) ? null : Helper::array_of_objects($values); } private function _prepare_copy_text($sections) { $text = ''; foreach ($sections as $section) { $text .= '### ' . $section->title . PHP_EOL . PHP_EOL; foreach ($section->rows as $row) { $text .= sprintf('%s: %s%s', strip_tags($row->label), strip_tags($row->value), PHP_EOL ); } $text .= PHP_EOL; } return sprintf('```%s%s```', PHP_EOL, $text); } /** * Outputs 'Info' section content on Status tab. */ public function tab_content() { $sections = [ 'server' => [ 'title' => __('Server', ud_get_stateless_media()->domain), ], 'wordpress' => [ 'title' => __('WordPress', ud_get_stateless_media()->domain), ], 'stateless' => [ 'title' => __('WP-Stateless', ud_get_stateless_media()->domain), ], 'google_cloud' => [ 'title' => __('Google Cloud', ud_get_stateless_media()->domain), ], ]; foreach ($sections as $key => $section) { $rows = $this->_get_section_values($key); if ( !empty($rows) ) { $sections[$key]['rows'] = $rows; } else { unset($sections[$key]); } } $sections = Helper::array_of_objects($sections); $copy_text = $this->_prepare_copy_text($sections); include ud_get_stateless_media()->path('static/views/status-sections/info.php', 'dir'); } /** * Load 'Status' tab only in admin area */ public function status_tab_visible($visible) { return is_admin(); } } ================================================ FILE: lib/classes/status/class-migrations.php ================================================ _init_hooks(); } private function _init_hooks() { add_action('wp_stateless_status_tab_content', [$this, 'tab_content'], 50); add_filter('wp_stateless_batch_state', [$this, 'migrations_state'], 20, 2); } /** * Detects the oldest migration that needs to be finished before the next one can run */ private function _set_primary_migration_id() { $this->primary_migration_id = ''; $migrations = array_reverse($this->migrations, true); foreach ($migrations as $id => $migration) { if ( in_array($migration['status'], [Migrator::STATUS_PENDING, Migrator::STATUS_RUNNING, Migrator::STATUS_FAILED]) ) { $this->primary_migration_id = $id; break; } } } /** * Returns the id of the migration that is currently running (if any) * * @param array $state * @return string|bool|null */ private function _set_running_migration_id($state) { $this->running_migration_id = ''; if ( !empty($state) ) { if ( isset($state['is_migration']) && $state['is_migration'] ) { $this->running_migration_id = $state['id']; // migration is running return; } } } /** * Generate the message for the migration, depending on the current state * * @param string $id * @param array $migration * @return string */ private function _get_migration_message($id, $migration) { $message = $migration['message'] ?? ''; switch ($migration['status']) { case Migrator::STATUS_FINISHED: $format = get_option('date_format') . ' ' . get_option( 'time_format' ); $date = wp_date($format, $migration['finished']); $message = sprintf( __('Finished at %s', ud_get_stateless_media()->domain), $date ); break; case Migrator::STATUS_SKIPPED: $message = !empty($message) ? $message : __('Not required', ud_get_stateless_media()->domain); break; case Migrator::STATUS_FAILED: $message = sprintf( __('Failed to finish: %s', ud_get_stateless_media()->domain), $message ); break; case Migrator::STATUS_PENDING: if ( $id == $this->primary_migration_id ) { $message = sprintf( __('Ready to run', ud_get_stateless_media()->domain) ); } else { $message = sprintf( __('Requires %s to finish', ud_get_stateless_media()->domain), $this->migrations[$this->primary_migration_id]['description'] ); } break; case Migrator::STATUS_RUNNING: $message = __('In progress...', ud_get_stateless_media()->domain); break; } return $message; } /** * Generate the UI message for the migration, depending on the current state * * @param string $id * @param array $migration * @return string */ private function _get_migration_ui_message($status, $state) { $message = ''; $counter = false; if ( isset( $state['id'] ) && isset( $state['queue'] ) && is_array( $state['queue'] ) && count( $state['queue'] ) > 1 ) { $counter = sprintf( '%d/%d', array_search($state['id'], $state['queue']) + 1, count($state['queue']) ); } switch ($status) { case Migrator::STATUS_RUNNING: $message = $counter ? sprintf( __('In progress %s...', ud_get_stateless_media()->domain), $counter) : __('In progress...', ud_get_stateless_media()->domain); break; case Migrator::STATUS_PAUSED: $message = $counter ? sprintf( __('Paused %s...', ud_get_stateless_media()->domain), $counter) : __('Paused...', ud_get_stateless_media()->domain); break; } return $message; } /** * Returns the status of the migration * * @param string $status * @return string */ public static function get_status_text($status) { switch ($status) { case Migrator::STATUS_PENDING: return __('Pending', ud_get_stateless_media()->domain); case Migrator::STATUS_RUNNING: return __('Running', ud_get_stateless_media()->domain); case Migrator::STATUS_SKIPPED: return __('Skipped', ud_get_stateless_media()->domain); case Migrator::STATUS_FINISHED: return __('Finished', ud_get_stateless_media()->domain); case Migrator::STATUS_FAILED: return __('Failed', ud_get_stateless_media()->domain); } } /** * Get migrations state for frontend display * * @return array */ private function _get_migrations_state($state = null) { $migrations = []; $this->migrations = apply_filters('wp_stateless_get_migrations', []); if ( !is_array($this->migrations) ) { $this->migrations = []; } $defaults = [ 'description' => '', 'status' => '', 'status_text' => '', 'message' => '', 'ui_message' => '', 'can_start' => false, 'can_pause' => false, 'can_resume' => false, ]; $this->_set_primary_migration_id(); $batch_state = $state ? $state : apply_filters('wp_stateless_batch_state', [], []); $this->_set_running_migration_id($batch_state); foreach ($this->migrations as $id => $migration) { $status = $migration['status']; $can_start = $this->primary_migration_id == $id; $can_pause = false; $can_resume = false; if ( $this->running_migration_id == $id ) { $can_start = false; if ( $batch_state['is_paused'] ) { $status = Migrator::STATUS_PAUSED; $can_resume = true; } else { $status = Migrator::STATUS_RUNNING; $can_pause = true; } } $classes = [ $status, $can_start ? 'can-start' : '', $can_pause ? 'can-pause' : '', $can_resume ? 'can-resume' : '', ]; $data = wp_parse_args([ 'description' => $migration['description'], 'status' => $status, 'classes' => implode( ' ', array_filter($classes) ), 'status_text' => self::get_status_text($status), 'message' => $this->_get_migration_message($id, $migration), 'ui_message' => $this->_get_migration_ui_message($status, $batch_state), 'can_start' => $can_start, 'can_pause' => $can_pause, 'can_resume' => $can_resume, ], $defaults); $migrations[$id] = $data; } return $migrations; } /** * Outputs 'Data Updates' section on the Status tab on the Settings page. */ public function tab_content() { if ( is_network_admin() ) { return; } $migrations = $this->_get_migrations_state(); $migration_ids = []; if ( !empty($migrations) ) { foreach ( $migrations as $migration_id => $migration ) { if ( $migration['status'] != Migrator::STATUS_FINISHED && $migration['status'] != Migrator::STATUS_SKIPPED ) { $migration_ids[] = $migration_id; } } } if ( !empty($migration_ids) ) { $migration_ids = array_reverse($migration_ids); $migration_id = $migration_ids[0]; $migration = $migrations[ $migration_id ]; include ud_get_stateless_media()->path('static/views/status-sections/migrations.php', 'dir'); } } /** * Get migration state * * @param array $state * @return array */ public function migrations_state($state, $params) { $is_running = $state['is_running'] ?? false; $is_migration = $state['is_migration'] ?? false; $force_migrations = $params['force_migrations'] ?? false; if ( !$is_running && !$is_migration && !$force_migrations ) { return $state; } $state['migrations'] = $this->_get_migrations_state($state); $state['migrations_notify'] = get_option(Migrator::MIGRATIONS_NOTIFY_KEY, false); return $state; } } ================================================ FILE: lib/classes/sync/class-background-sync.php ================================================ path('lib/ns-vendor/classes/deliciousbrains/wp-background-processing/classes/wp-async-request.php', 'dir'); } if (!class_exists('UDX_WP_Background_Process')) { require_once ud_get_stateless_media()->path('lib/ns-vendor/classes/deliciousbrains/wp-background-processing/classes/wp-background-process.php', 'dir'); } use UDX_WP_Background_Process, JsonSerializable; /** * Generic background process */ abstract class BackgroundSync extends UDX_WP_Background_Process implements ISync, JsonSerializable { /** * Cron Healthcheck interval */ public $cron_interval; /** * Flag to allow sorting */ protected $allow_sorting = false; /** * Flag to allow setting the limit */ protected $allow_limit = false; /** * Storage for emergency memory */ private $emergency_memory = null; /** * Storage for currently processed item */ protected $currently_processing_item = null; /** * Extend the construct */ public function __construct() { // Support different threads for multisite installations $blog_id = get_current_blog_id(); $this->action = "{$this->action}_{$blog_id}"; add_filter('wp_stateless_sync_types', function ($classes) { $classes[$c = get_called_class()] = $c; return $classes; }); $this->cron_interval = $this->get_healthcheck_cron_interval(); // Reserve 1MB of RAM for the fallback action $this->emergency_memory = new \SplFixedArray(65536); // Register the fallback action to be executed on shutdown register_shutdown_function(function () { // Free up reserved memory $this->emergency_memory = null; // Check if we should execute the fallback action if (is_null($err = error_get_last())) return; if ($err['type'] != E_ERROR) return; if (strstr($err['message'], 'memory') === false || strstr($err['message'], 'exhausted') === false) return; if (!$this->is_running()) return; if (!$this->currently_processing_item) return; // If we are here, then we shutdown because of `memory exhausted` error // Remove already processed and problem items from the current batch $current_batch = $this->get_batch(); if ($current_batch && $current_batch->data && is_array($current_batch->data)) { foreach ($current_batch->data as $key => $item) { unset($current_batch->data[$key]); if ($item == $this->currently_processing_item) { $this->log(sprintf(__('Item skipped: %s. Waiting for process to resume.', ud_get_stateless_media()->domain), $this->currently_processing_item)); call_user_func([get_class(), 'task'], $this->currently_processing_item); break; } } $current_batch->data = array_values($current_batch->data); } // Update current batch directly to the option // because it needs to be updated even if it is empty update_site_option($current_batch->key, $current_batch->data); // Add notice $this->save_process_meta([ 'notice' => sprintf( __("Not enough memory to process the following item '%s' %s: %s. Item skipped. Please, try to increase memory limit or use uploading by chunks: How to use WP_STATELESS_MEDIA_UPLOAD_CHUNK_SIZE setting.", ud_get_stateless_media()->domain), is_numeric($this->currently_processing_item) ? get_the_title($this->currently_processing_item) : $this->currently_processing_item, is_numeric($this->currently_processing_item) ? "(ID: {$this->currently_processing_item})" : '', $err['message'], ud_get_stateless_media()->get_docs_page_url('docs/constants/#wpstatelessmediauploadchunksize'), ) ]); wp_die(); }); parent::__construct(); } /** * Maybe process queue (extended) * * Checks whether data exists within the queue and that * the process is not already running. */ public function maybe_handle() { // Don't lock up other requests while processing session_write_close(); if ($this->is_processing()) { // Background process already running. wp_die(); } if ($this->is_queue_empty()) { // No data to process. wp_die(); } $this->handle(); wp_die(); } /** * Determine sync healthcheck interval */ protected function get_healthcheck_cron_interval() { return (defined('WP_STATELESS_SYNC_HEALTHCHECK_INTERVAL') && is_int(WP_STATELESS_SYNC_HEALTHCHECK_INTERVAL)) ? WP_STATELESS_SYNC_HEALTHCHECK_INTERVAL : 1; } /** * Get option key for STOPPED option */ protected function get_stopped_option_key() { return "{$this->action}_stopped"; } /** * Determine maximum batch size * * @return int Default is 50 */ public function get_max_batch_size() { return (defined('WP_STATELESS_SYNC_MAX_BATCH_SIZE') && is_int(WP_STATELESS_SYNC_MAX_BATCH_SIZE)) ? WP_STATELESS_SYNC_MAX_BATCH_SIZE : 50; } /** * Get all batches * * @param int $limit 0 * @return array */ public function get_batches($limit = 0) { global $wpdb; if (empty($limit) || !is_int($limit)) { $limit = 0; } $table = $wpdb->options; $column = 'option_name'; $key_column = 'option_id'; $value_column = 'option_value'; if (is_multisite()) { $table = $wpdb->sitemeta; $column = 'meta_key'; $key_column = 'meta_id'; $value_column = 'meta_value'; } $key = $wpdb->esc_like($this->identifier) . '_batch_%'; $sql = " SELECT * FROM {$table} WHERE {$column} LIKE %s ORDER BY {$key_column} ASC "; if (!empty($limit)) { $sql .= " LIMIT {$limit}"; } $items = $wpdb->get_results($wpdb->prepare($sql, $key)); $batches = []; if (!empty($items)) { $batches = array_map( function ($item) use ($column, $value_column) { $batch = new \stdClass(); $batch->key = $item->$column; $batch->data = maybe_unserialize($item->$value_column); return $batch; }, $items ); } return $batches; } /** * Get one top batch */ protected function get_batch() { return array_reduce( $this->get_batches(1), function ($_, $batch) { return $batch; }, [] ); } /** * Delete all batches * * @return self */ public function delete_all() { $batches = $this->get_batches(); foreach ($batches as $batch) { $this->delete($batch->key); } $this->clear_queue_size(); return $this; } /** * Stop processing */ public function stop() { $this->delete_all(); update_site_option($this->get_stopped_option_key(), true); $this->clear_process_meta(); $this->log("Stopped"); } /** * Determine if process is stopped. * * @return bool */ public function is_stopped() { $network_id = get_current_network_id(); wp_cache_delete("$network_id:notoptions", 'site-options'); return boolval(get_site_option($this->get_stopped_option_key())); } /** * Update the whole queue size * * @param int $size * @return self */ public function update_queue_size($size) { $size = intval($size) + $this->get_queue_size(); update_site_option("{$this->action}_queue_size", $size); return $this; } /** * Get current queue size */ public function get_queue_size() { return intval(get_site_option("{$this->action}_queue_size", 0)); } /** * Clear the queue size * * @return self */ public function clear_queue_size() { delete_site_option("{$this->action}_queue_size"); return $this; } /** * Clear process meta * * @return self */ public function clear_process_meta() { // Clear limits for future starts delete_site_option("{$this->action}_meta"); return $this; } /** * Save process meta data * * @param array $meta */ public function save_process_meta($meta = []) { if (!empty($meta)) { $existing_meta = get_site_option("{$this->action}_meta", []); foreach ($meta as $key => $value) { $existing_meta[$key] = $value; } update_site_option("{$this->action}_meta", $existing_meta); } } /** * Get process meta data. All or by the key. * * @param string|bool $key * @return array|string|null */ public function get_process_meta($name = false) { $meta = get_site_option("{$this->action}_meta", []); if (false === $name) { return $meta; } return isset($meta[$name]) ? $meta[$name] : null; } /** * Extending save queue method * * @return $this */ public function save() { $batch_size = is_array($this->data) ? count($this->data) : 1; $this->update_queue_size($batch_size); parent::save(); $this->data = []; return $this; } /** * Extending complete process method */ protected function complete() { parent::complete(); $this->clear_process_meta(); $this->clear_queue_size(); delete_site_option($this->get_stopped_option_key()); // Sending notification $sync_name = strip_tags($this->get_name()); $site = site_url(); $subject = sprintf(__('WP-Stateless: %s Synchronization Complete', ud_get_stateless_media()->domain), $sync_name); $message = sprintf(__("WP-Stateless has finished synchronizing %s for %s.\n\nIf you have WP_STATELESS_SYNC_LOG or WP_DEBUG_LOG enabled, review those logs now to review any errors that may have occurred during the synchronization process.", ud_get_stateless_media()->domain), $sync_name, $site); do_action('wp_stateless_send_admin_email', $subject, $message); } /** * Remember currently processing item */ protected function before_task($item) { $this->currently_processing_item = $item; } /** * Common task that should be executed in the end of each subclass task */ protected function task($_) { $processedCount = intval($this->get_process_meta('processed')); $this->save_process_meta([ 'processed' => ++$processedCount, 'last_at' => current_time('timestamp') ]); } /** * Default name * * @return string */ public function get_name() { return __('Background Sync', ud_get_stateless_media()->domain); } /** * Default helper window is set to false * * @return HelperWindow|bool */ public function get_helper_window() { return false; } /** * Process specific notice * * @return array|bool */ public function get_process_notice() { $notice = $this->get_process_meta('notice'); if (empty($notice)) return []; return [$notice]; } /** * Is running? */ public function is_running() { return !$this->is_queue_empty() || $this->is_processing(); } /** * Convert to json * * @return array */ #[\ReturnTypeWillChange] public function jsonSerialize() { return [ 'id' => get_called_class(), 'name' => $this->get_name(), 'helper' => $this->get_helper_window(), 'is_running' => $this->is_running(), 'limit' => ($limit = $this->get_process_meta('limit')) ? $limit : 0, 'order' => ($order = $this->get_process_meta('order')) ? $order : 'desc', 'total_items' => $this->get_total_items(), 'queued_items' => $this->get_queue_size(), 'processed_items' => ($processed = $this->get_process_meta('processed')) ? $processed : 0, 'allow_limit' => $this->allow_limit, 'allow_sorting' => $this->allow_sorting, 'notice' => $this->get_process_notice() ]; } /** * Log background process event * * @param string $message * @return bool TRUE on success or FALSE on failure */ public function log($message) { $message = strip_tags(sprintf('Background Sync - %s: %s', $this->get_name(), $message)); if (is_multisite()) { $blog_id = get_current_blog_id(); $message = sprintf('[Blog %s] %s', $blog_id, $message); } if (!defined('WP_STATELESS_SYNC_LOG')) { return error_log($message); } return error_log(date('c') . ": $message\n", 3, WP_STATELESS_SYNC_LOG); } /** * Start process. * Should be implemented by subclasses. */ abstract public function start(); } ================================================ FILE: lib/classes/sync/class-file-sync.php ================================================ domain); } /** * Get SQL condition to compose the query to get items to process by library sync * * @return string */ public function get_sql_condition() { return "AND post_mime_type NOT LIKE 'image/%'"; } /** * Helper window */ public function get_helper_window() { return new HelperWindow( __('What are Media Library Files?', ud_get_stateless_media()->domain), __('All non-image files that were uploaded via the media library or via plugins that use standard uploading API.', ud_get_stateless_media()->domain) ); } /** * Process one file item * * @param mixed $id * @return bool */ protected function task($id) { try { if ($this->is_stopped()) return false; parent::before_task($id); timer_start(); set_time_limit(0); $file = Utility::process_file_by_id($id); $this->log(sprintf(__('%1$s (ID %2$s) was successfully synced in %3$s seconds.', ud_get_stateless_media()->domain), esc_html(get_the_title($file->ID)), $file->ID, timer_stop())); if (!$this->is_stopped()) { $this->extend_queue(); } parent::task($id); return false; } catch (FatalException $e) { $this->log("Stopped due to error - {$e->getMessage()}"); $this->stop(); return false; } catch (UnprocessableException $e) { $this->log($e->getMessage()); return false; } catch (\Throwable $e) { $this->log("Stopped due to error - {$e->getMessage()}"); $this->stop(); return false; } } } ================================================ FILE: lib/classes/sync/class-helper-window.php ================================================ title = $title; $this->content = $content; } /** * To JSON */ #[\ReturnTypeWillChange] public function jsonSerialize() { return get_object_vars($this); } } ================================================ FILE: lib/classes/sync/class-image-sync.php ================================================ domain); } /** * Get SQL condition to compose the query to get items to process by library sync * * @return string */ public function get_sql_condition() { return "AND post_mime_type LIKE 'image/%'"; } /** * Helper window * * @return HelperWindow */ public function get_helper_window() { return new HelperWindow( __('What are Media Library Images?', ud_get_stateless_media()->domain), __('All image files that were uploaded via the media library or via plugins that use standard uploading API.', ud_get_stateless_media()->domain) ); } /** * Process 1 item from the queue * * @param mixed $id * @return bool */ protected function task($id) { try { if ($this->is_stopped()) return false; parent::before_task($id); timer_start(); set_time_limit(0); $image = Utility::process_image_by_id($id); $this->log(sprintf(__('%1$s (ID %2$s) was successfully synced in %3$s seconds.', ud_get_stateless_media()->domain), esc_html(get_the_title($image->ID)), $image->ID, timer_stop())); if (!$this->is_stopped()) { $this->extend_queue(); } parent::task($id); return false; } catch (FatalException $e) { $this->log("Stopped due to error - {$e->getMessage()}"); $this->stop(); return false; } catch (UnprocessableException $e) { $this->log($e->getMessage()); return false; } catch (\Throwable $e) { $this->log("Stopped due to error - {$e->getMessage()}"); $this->stop(); return false; } } } ================================================ FILE: lib/classes/sync/class-library-sync.php ================================================ action}_total_items"; } /** * Start the process * * @param array $args [] * @return bool */ public final function start($args = []) { try { if ($this->is_processing()) throw new UnprocessableException(__('Process already running', ud_get_stateless_media()->domain)); // Make sure there is no orphaned data and state delete_site_option($this->get_stopped_option_key()); delete_transient($this->get_total_items_trans_key()); $this->clear_process_meta(); $settings = wp_parse_args($args, [ 'limit' => null, 'order' => null ]); $limit = $settings['limit'] ? intval($settings['limit']) : 0; $order = in_array($settings['order'], ['desc', 'asc']) ? $settings['order'] : 'desc'; global $wpdb; $sql = "SELECT ID FROM $wpdb->posts WHERE post_type = 'attachment' {$this->get_sql_condition()} AND post_date < %s ORDER BY ID $order LIMIT %d"; $query = $wpdb->prepare($sql, $datetime = current_time('mysql'), $this->get_max_batch_size()); $ids = $wpdb->get_col($query); $total = 0; foreach ($ids as $id) { if (!$limit || $total < $limit) { $this->push_to_queue($id); $total++; } } $this->save_process_meta([ 'limit' => $limit, 'datetime' => $datetime, 'order' => $order, 'last_id' => $id ]); $this->save()->dispatch(); $this->log('Started'); return true; } catch (UnprocessableException $e) { $this->log(sprintf(__('Could not start the new process: %s'), $e->getMessage())); return true; } catch (\Throwable $e) { $this->log(sprintf(__('Could not start the process due to the error: %s'), $e->getMessage())); $this->stop(); return false; } } /** * Provide the queue with the new data if available * * @return bool */ public function extend_queue() { try { global $wpdb; $meta = $this->get_process_meta(); $last_id = isset($meta['last_id']) ? $meta['last_id'] : false; if (!$last_id) return; $limit = isset($meta['limit']) ? $meta['limit'] : 0; $order = isset($meta['order']) ? $meta['order'] : 'desc'; $datetime = isset($meta['datetime']) ? $meta['datetime'] : current_time('mysql'); $range_condition = $order === 'desc' ? $wpdb->prepare("AND ID < %d", $last_id) : $wpdb->prepare("AND ID > %d", $last_id); $sql = "SELECT ID FROM $wpdb->posts WHERE post_type = 'attachment' {$this->get_sql_condition()} AND post_date < %s $range_condition ORDER BY ID $order LIMIT %d"; $query = $wpdb->prepare($sql, $datetime, $this->get_max_batch_size()); $ids = $wpdb->get_col($query); $total = $this->get_queue_size(); foreach ($ids as $id) { if (!$limit || $total < $limit) { $this->push_to_queue($id); $total++; } } if (!empty($this->data)) { $this->save()->save_process_meta([ 'last_id' => $id ]); } else { $this->save_process_meta([ 'last_id' => 0 ]); } return true; } catch (\Throwable $e) { $this->log(sprintf('Something went wrong while extending the queue: %s. Stopping the whole process.', $e->getMessage())); $this->stop(); return false; } } /** * Thing to do in complete */ protected function complete() { parent::complete(); // @todo do something when complete $this->log("Complete"); } /** * Get Total Items (caching utilized) * * @return int */ public function get_total_items() { $cached = get_transient($this->get_total_items_trans_key()); if ($cached) return intval($cached); global $wpdb; $sql = "SELECT count(*) FROM $wpdb->posts WHERE post_type = 'attachment' {$this->get_sql_condition()}"; $total = $wpdb->get_var($sql); set_transient($this->get_total_items_trans_key(), $total, MINUTE_IN_SECONDS * 5); return intval($total); } /** * Notice if process seemed to be stuck * * @return string|false */ public function get_process_notice() { $notices = parent::get_process_notice(); $last = intval($this->get_process_meta('last_at')); if (!$last) { $last = strtotime( $this->get_process_meta('datetime') ?? '' ); if (false === $last) return $notices; } if (!property_exists($this, 'cron_interval')) return $notices; $waiting = current_time('timestamp') - $last; if ($waiting < 5 * MINUTE_IN_SECONDS * $this->cron_interval) return $notices; $notices[] = sprintf(__('This process takes longer than it should. Please, make sure loopback connections and WP Cron are enabled and working, or try restarting the process.', ud_get_stateless_media()->domain)); return $notices; } } ================================================ FILE: lib/classes/sync/class-non-library-sync.php ================================================ items = array_filter(array_unique(apply_filters('sm:sync::nonMediaFiles', []))); parent::__construct(); } /** * Get sync name * * @return string */ public function get_name() { return __('Compatibility Files Beta', ud_get_stateless_media()->domain); } /** * Sync helper window * * @return HelperWindow */ public function get_helper_window() { return new HelperWindow( __('What are Compatibility Files?', ud_get_stateless_media()->domain), __('All kind of files that were created by themes and plugins in custom folders out of standard Media Library, and that WP-Stateless has a Compatibility Support for. Limit and Sorting is not supported.', ud_get_stateless_media()->domain) ); } /** * Start the process * * @return bool */ public function start() { try { if ($this->is_processing()) throw new UnprocessableException(__('Process already running', ud_get_stateless_media()->domain)); // Make sure there is no orphaned data and state delete_site_option($this->get_stopped_option_key()); $this->clear_process_meta(); $this->items = array_filter(array_unique(apply_filters('sm:sync::nonMediaFiles', []))); $chunks = array_chunk($this->items, $this->get_max_batch_size()); if (!empty($chunks)) { foreach ($chunks as $chunk) { foreach ($chunk as $item) { $this->push_to_queue($item); } $this->save(); } } $this->dispatch(); $this->save_process_meta([ 'starttime' => current_time('timestamp') ]); $this->log('Started'); return true; } catch (UnprocessableException $e) { $this->log(sprintf(__('Could not start the new process: %s'), $e->getMessage())); return true; } catch (\Throwable $e) { $this->log(sprintf(__('Could not start the process due to the error: %s'), $e->getMessage())); $this->stop(); return false; } } /** * Process one item from the queue */ protected function task($item) { try { parent::before_task($item); timer_start(); if (ud_get_stateless_media()->is_connected_to_gs() !== true) { throw new FatalException(__('Not connected to GCS', ud_get_stateless_media()->domain)); } if (is_multisite() && ($blog_id = get_current_blog_id()) != 1) { switch_to_blog(1); $upload_dir = wp_upload_dir(); switch_to_blog($blog_id); } else { $upload_dir = wp_upload_dir(); } $file_path = trim($item, '/'); $basedir = ud_get_stateless_media()->is_mode('stateless') ? ud_get_stateless_media()->get_gs_path() : $upload_dir['basedir']; $fullsizepath = $basedir . '/' . $file_path; do_action('sm:sync::syncFile', $file_path, $fullsizepath, true, ['remove_from_queue' => true, 'manual_sync' => true]); $this->log(sprintf(__('%1$s (ID %2$s) was successfully synchronised in %3$s seconds.', ud_get_stateless_media()->domain), esc_html(get_the_title($file_path)), $file_path, timer_stop())); parent::task($item); return false; } catch (FatalException $e) { $this->log("Stopped due to error - {$e->getMessage()}"); $this->stop(); return false; } catch (UnprocessableException $e) { $this->log($e->getMessage()); return false; } catch (\Throwable $e) { $this->log("Stopped due to error - {$e->getMessage()}"); $this->stop(); return false; } } /** * Thing to do in complete */ protected function complete() { parent::complete(); // @todo do something when complete $this->log("Complete"); } /** * Notice if process seemed to be stuck * * @return string|false */ public function get_process_notice() { $notices = parent::get_process_notice(); $last = intval($this->get_process_meta('last_at')); if (!$last) { $last = intval($this->get_process_meta('starttime')); if (!$last) return $notices; } if (!property_exists($this, 'cron_interval')) return $notices; $waiting = current_time('timestamp') - $last; if ($waiting < 5 * MINUTE_IN_SECONDS * $this->cron_interval) return $notices; $notices[] = sprintf(__('This process takes longer than it should. Please, make sure loopback connections and WP Cron are enabled and working, or try restarting the process.', ud_get_stateless_media()->domain)); return $notices; } /** * Get count of items * * @return int */ public function get_total_items() { return ud_stateless_db()->get_total_non_media_files(); } public function extend_queue() { // Not needed for this kind of sync } } ================================================ FILE: lib/classes/sync/interface-sync.php ================================================ url = is_multisite() ? WP_CLI::get_runner()->config['url'] : false; } /** * Sync Data * * ## OPTIONS * * * : Which data we want to sync. May be images or files. * * --url * : Blog URL if multisite installation. * * --start * : Indent (sql start). It's ignored on batches. * * --limit * : Limit per query (sql limit) * * --end * : Where ( on which row ) we should stop script. It's ignored on batches * * --batch * : Number of Batch. Default is 1. * * --batches * : General amount of batches. * * --b * : Runs command using batches till it's done. Other parameters will be ignored. There are 10 batches by default. Batch is external command process * * --log * : Show more information in command line * * --o * : Process includes database optimization and transient removing. * * --order * : Order. May be ASC or DESC * * ## EXAMPLES * * wp stateless sync images --url=example.com --b * : Run process looping 10 batches. Every batch is external command 'wp stateless sync images --url=example.com --batch= --batches=10' * * wp stateless sync images --url=example.com --b --batches=100 * : Run process looping 100 batches. * * wp stateless sync images --url=example.com --b --batches=10 --batch=2 * : Run second batch from 10 batches manually. * * wp stateless sync images --url=example.com --log * : Run default process showing additional information in command line. * * wp stateless sync images --url=example.com --end=3000 --limit=50 * : Run process from 1 to 3000 row. Splits process by limiting queries to 50 rows. So, the current example does 60 queries ( 3000 / 50 = 60 ) * * wp stateless sync images --url=example.com --start=777 --end=3000 --o * : Run process from 777 to 3000 row. Also does database optimization and removes transient in the end. * * @synopsis [--url=] [--start=] [--limit=] [--end=] [--batch=] [--batches=] [--b] [--log] [--o] [--order=] * @param $args * @param $assoc_args */ public function sync($args, $assoc_args) { $sm_mode = ud_get_stateless_media()->get('sm.mode'); if ($sm_mode === 'stateless') { WP_CLI::error('Sync is not supported in Stateless mode'); } //** DB Optimization process */ if (isset($assoc_args['o'])) { $this->_before_command_run(); } //** Run batches */ if (isset($assoc_args['b'])) { if (empty($args[0])) { WP_CLI::error('Invalid type parameter'); } $this->_run_batches('sync', $args[0], $assoc_args); } //** Or run command as is. */ else { if (!class_exists('SM_CLI_Sync')) { require_once(dirname(__FILE__) . '/class-sm-cli-sync.php'); } if (class_exists('SM_CLI_Sync')) { $object = new SM_CLI_Sync($args, $assoc_args); $controller = !empty($args[0]) ? $args[0] : false; if ($controller && is_callable(array($object, $controller))) { call_user_func(array($object, $controller)); } else { WP_CLI::error('Invalid type parameter'); } } else { WP_CLI::error('Class SM_CLI_Sync is undefined.'); } } //** Get rid of all transients and run DB optimization again */ if (isset($assoc_args['o'])) { $this->_after_command_run(); } } /** * Upgrade Data * * ## OPTIONS * * * : Which data we want to upgrade. Currently only 'meta' type is supported. * * --start * : Indent (sql start). It's ignored on batches. * * --limit * : Limit per query (sql limit) * * --end * : Where ( on which row ) we should stop script. It's ignored on batches * * --batch * : Number of Batch. Default is 1. * * --batches * : General amount of batches. * * --b * : Runs command using batches till it's done. Other parameters will be ignored. There are 10 batches by default. Batch is external command process * * --log * : Show more information in command line * * --o * : Process includes database optimization and transient removing. * * --url * : Blog URL if multisite installation. * * ## EXAMPLES * * wp stateless upgrade meta --url=example.com --b * : Run process looping 10 batches. Every batch is external command 'wp stateless upgrade meta --url=example.com --batch= --batches=10' * * wp stateless upgrade meta --url=example.com --b --batches=100 * : Run process looping 100 batches. * * wp stateless upgrade meta --url=example.com --b --batches=10 --batch=2 * : Run second batch from 10 batches manually. * * wp stateless upgrade meta --url=example.com --log * : Run default process showing additional information in command line. * * wp stateless upgrade meta --url=example.com --end=3000 --limit=50 * : Run process from 1 to 3000 row. Splits process by limiting queries to 50 rows. So, the current example does 60 queries ( 3000 / 50 = 60 ) * * wp stateless upgrade meta --url=example.com --start=777 --end=3000 --o * : Run process from 777 to 3000 row. Also does database optimization and removes transient in the end. * * @synopsis [--url=] [--start=] [--limit=] [--end=] [--batch=] [--batches=] [--b] [--log] [--o] * @param $args * @param $assoc_args */ public function upgrade($args, $assoc_args) { //** DB Optimization process */ if (isset($assoc_args['o'])) { $this->_before_command_run(); } //** Run batches */ if (isset($assoc_args['b'])) { if (empty($args[0])) { WP_CLI::error('Invalid type parameter'); } $this->_run_batches('upgrade', $args[0], $assoc_args); } //** Or run command as is. */ else { if (!class_exists('SM_CLI_Upgrade')) { require_once(dirname(__FILE__) . '/class-sm-cli-upgrade.php'); } if (class_exists('SM_CLI_Upgrade')) { $object = new SM_CLI_Upgrade($args, $assoc_args); $controller = !empty($args[0]) ? $args[0] : false; if ($controller && is_callable(array($object, $controller))) { call_user_func(array($object, $controller)); } else { WP_CLI::error('Invalid type parameter'); } } else { WP_CLI::error('Class SM_CLI_Upgrade is undefined.'); } } //** Get rid of all transients and run DB optimization again */ if (isset($assoc_args['o'])) { $this->_after_command_run(); } } /** * Run migrations * * ## OPTIONS * * [] * : start migration by its ID, or automatically run all pending migrations (auto). Auto mode does not support '--force' parameter. * * --force * : Force starting migration even if it is not pending * * --progress= * : Monitor migration progress every seconds (minimum 1) * * --email= * : Send email notification to specified email when migration is finished. By default it uses email from plugin settings. You can also use a list of emails, comma separated. * * --url * : Blog URL if multisite installation. * * --yes * : Confirm automatically. * * * ## EXAMPLES * * wp stateless migrate * : List migrations information. * * wp stateless migrate --url=example.com * : List migrations information for specific blog in multisite network. * * wp stateless migrate --progress=3 * : Display current migration progress every 3 seconds. * * wp stateless migrate 20240216150177 * : Start migration with ID 20240216150177. * * wp stateless migrate auto --email=mail@example.com --yes * : Automatically run all pending migrations without confirmation and send notifications to mail@example.com. * * wp stateless migrate 20240216150177 --progress=2 --yes * : Start migration with ID 20240216150177 without confirmation and display progress every 2 seconds. * * wp stateless migrate 20240216150177 --force --email=mail@example.com,user@domain.com --url=example.com * : Start migration with ID 20240216150177 for specific blog in multisite network. Start migration even if it was already finished or failed. After finishing send email notification to mail@example.com and user@domain.com. * * @synopsis [] [--force] [--progress=] [--email=] [--yes] [--url=] * @param $args * @param $assoc_args */ public function migrate($args, $assoc_args) { $id = $args[0] ?? ''; // No migration ID provided, list all migrations and exit if ( empty($id) && !isset($assoc_args['progress']) ) { $this->_list_migrations(); return; } else if ( !empty($id) ) { if ( $id === 'auto' ) { if ( isset($assoc_args['force']) ) { WP_CLI::error( 'The parameter --force is not supported for auto mode.' ); return; } $this->_auto_migrate($assoc_args); return; } else { $this->_run_migration($id, $assoc_args); } } if ( $id !== 'auto' && isset($assoc_args['progress']) ) { $this->_check_progress($assoc_args['progress']); } } /** * Sets cacheControl meta for all files on Google Cloud Storage to the default value from WP-Stateless settings. * * ## OPTIONS * * --url * : Blog URL if multisite installation. * * ## EXAMPLES * * wp stateless reset_cache_control * : Sync cache control for all files on Google Cloud Storage. * * @synopsis [--url=] * @param $args * @param $assoc_args */ public function reset_cache_control($args, $assoc_args) { $sm_mode = ud_get_stateless_media()->get('sm.mode'); if ( ud_get_stateless_media()->is_mode('stateless') ) { WP_CLI::error('Sync cache control is not supported in Stateless mode'); } global $wpdb; $gs_client = ud_get_stateless_media()->get_client(); $cache_control = ud_get_stateless_media()->get_default_cache_control(); $cache_control = apply_filters('sm:item:cacheControl', ud_get_stateless_media()->get_default_cache_control() ); $table_name = ud_stateless_db()->files; $names = $wpdb->get_col(" SELECT name FROM {$table_name} WHERE post_id IS NOT NULL "); foreach ($names as $name) { if ( !$gs_client->media_exists($name) ) { continue; } $args = [ 'skipLocalCheck' => true, 'force' => false, 'cacheControl' => $cache_control, 'name' => $name, ]; $gs_client->add_media($args); WP_CLI::line("Processed file: '{$name}'"); } } /** * Run all pending migrations * * @param array $assoc_args */ private function _auto_migrate($assoc_args) { $progress = $assoc_args['progress'] ?? 1; do { // We need to omit the cache and get the data directly from the db $migrations = apply_filters('wp_stateless_get_migrations', []); $keys = array_reverse( array_keys($migrations) ); $id = null; // Do we have next pending migration? foreach ($keys as $key) { if ( $migrations[$key]['status'] === Migrator::STATUS_PENDING ) { $id = $key; break; } } if ( !empty($id) ) { $command = "wp stateless migrate $id --yes --progress=$progress"; WP_CLI::line('...'); WP_CLI::line("Launching external command '{$command}'"); WP_CLI::line('Waiting...'); @ob_flush(); flush(); $r = SM_CLI::launch($command, false, true); if ($r->return_code) { WP_CLI::error("Something went wrong. External command process failed."); } else { echo $r->stdout; } continue; } break; } while(true); WP_CLI::success('No pending migrations left.'); } /** * Run the specific migration * * @param string $id * @param array $assoc_args */ private function _run_migration($id, $assoc_args) { $migrations = $this->_get_migrations(); if ( !isset($migrations[$id]) ) { WP_CLI::error("Invalid migration ID: $id"); } $migration = $migrations[$id]; // Check if we can run migration if ( !$migration['can_start'] && !isset($assoc_args['force']) ) { WP_CLI::error( 'Migration ' . $migration['description'] . ' is not ready for starting. ' . PHP_EOL . 'Migration status: ' . $migration['status_text'] . ', ' . strip_tags($migration['message']) . PHP_EOL . 'Please use --force to run it anyway.' ); } $email = $assoc_args['email'] ?? ud_get_stateless_media()->get_notification_email(); WP_CLI::line( 'Please make a backup copy of your database and try not to upload, change or delete your media while the process continues.' . PHP_EOL . "After the process finishes an email will be sent to: $email" . PHP_EOL ); WP_CLI::confirm( "Are you sure you want to run the migration $id?", $assoc_args ); // Run migration Migrator::instance()->start_migration([], [ 'id' => $id, 'is_migration' => true, 'force' => true, ]); WP_CLI::success( "Started migration $id" ); } /** * Get migrations state * * @return array */ private function _get_migrations() { $migrations = apply_filters('wp_stateless_batch_state', [], ['force_migrations' => true]); return $migrations['migrations'] ?? []; } /** * List migrations */ private function _list_migrations() { $migrations = $this->_get_migrations(); if ( empty($migrations) ) { WP_CLI::success('No migrations found'); } $data = []; foreach ($migrations as $id => $migration) { $data[$id] = [ 'id' => $id, 'description' => $migration['description'], 'status' => $migration['status_text'], 'message' => strip_tags($migration['message']), ]; } WP_CLI\Utils\format_items('table', $data, ['id', 'description', 'status', 'message']); } /** * Check progress */ private function _check_progress($progress) { global $wpdb; $sleep = max($progress, 1); $key = BatchTaskManager::instance()->get_state_key(); $sql = "SELECT option_value FROM $wpdb->options WHERE option_name = '%s' LIMIT 1"; $sql = $wpdb->prepare($sql, $key); $description = ''; do { // We need to omit the cache and get the data directly from the db $state = $wpdb->get_var($sql); $state = maybe_unserialize($state); if ( empty($state) || !isset($state['is_migration']) || !$state['is_migration'] ) { $message = empty($description) ? 'Migration finished' : "Migration '$description' finished"; WP_CLI::success($message); return; } $description = $state['description'] ?? ''; $completed = $state['completed'] ?? 0; $total = $state['total'] ?? 0; $percent = $total > 0 ? round($completed / $total * 100, 2) : 0; $message = sprintf("Migration '%s' compeleted %.2f%%: %d of %d items processed", $description, $percent, $completed, $total); WP_CLI::line($message); sleep($sleep); } while (true); } /** * Runs batches */ private function _run_batches($method, $type, $assoc_args) { $batches = isset($assoc_args['batches']) ? $assoc_args['batches'] : 10; if (!is_numeric($batches) || $batches <= 0) { WP_CLI::error('Parameter --batches must have numeric value.'); } $limit = isset($assoc_args['limit']) ? $assoc_args['limit'] : 100; if (!is_numeric($limit) || $limit <= 0) { WP_CLI::error('Parameter --limit must have numeric value.'); } $force = isset($assoc_args['force']) ? '--force' : ''; for ($i = 1; $i <= $batches; $i++) { if (!empty($this->url)) { $command = "wp stateless {$method} {$type} {$force} --batch={$i} --batches={$batches} --limit={$limit} --url={$this->url}"; } else { $command = "wp stateless {$method} {$type} {$force} --batch={$i} --batches={$batches} --limit={$limit}"; } WP_CLI::line('...'); WP_CLI::line("Launching external command '{$command}'"); WP_CLI::line('Waiting...'); @ob_flush(); flush(); $r = SM_CLI::launch($command, false, true); if ($r->return_code) { WP_CLI::error("Something went wrong. External command process failed."); } else { echo $r->stdout; } } } /** * Optimization process * Runs before command's process */ private function _before_command_run() { WP_CLI::line("Starting Database optimization process. Waiting..."); @ob_flush(); flush(); $command = !empty($this->url) ? "wp db optimize --url={$this->url}" : "wp db optimize"; $r = SM_CLI::launch($command, false, true); if ($r->return_code) { WP_CLI::error("Something went wrong. Database optimization process failed."); } else { WP_CLI::success("Database is optimized"); } } /** * Optimization process * Runs after command's process */ private function _after_command_run() { //** Run transient flushing */ WP_CLI::line("Starting remove transient. Waiting..."); @ob_flush(); flush(); $command = !empty($this->url) ? "wp transient delete-all --url={$this->url}" : "wp transient delete-all"; $r = SM_CLI::launch($command, false, true); if ($r->return_code) { WP_CLI::error("Something went wrong. Transient process failed."); } else { WP_CLI::success("Transient is removed"); } //** Run MySQL optimization */ WP_CLI::line("Starting Database optimization process. Waiting..."); @ob_flush(); flush(); $command = !empty($this->url) ? "wp db optimize --url={$this->url}" : "wp db optimize"; $r = SM_CLI::launch($command, false, true); if ($r->return_code) { WP_CLI::error("Something went wrong. Database optimization process failed."); } else { WP_CLI::success("Database is optimized"); } } } /** Add the commands from above */ WP_CLI::add_command('stateless', 'SM_CLI_Command'); } ================================================ FILE: lib/cli/class-sm-cli-process.php ================================================ command = $command; $proc->cwd = $cwd; return $proc; } /** * Run the command. * * @return SM_CLI_ProcessRun */ public function run() { $cwd = $this->cwd; $descriptors = array( 0 => STDIN, 1 => array( 'pipe', 'w' ), 2 => array( 'pipe', 'w' ), ); $proc = @proc_open( $this->command, $descriptors, $pipes, $cwd ); $stdout = stream_get_contents( $pipes[1] ); fclose( $pipes[1] ); $stderr = stream_get_contents( $pipes[2] ); fclose( $pipes[2] ); return new SM_CLI_ProcessRun( array( 'stdout' => $stdout, 'stderr' => $stderr, 'return_code' => proc_close( $proc ), 'command' => $this->command, 'cwd' => $cwd ) ); } /** * Run the command, but throw an Exception on error. * * @return SM_CLI_ProcessRun */ public function run_check() { $r = $this->run(); if ( $r->return_code || !empty( $r->STDERR ) ) { throw new \RuntimeException( $r ); } return $r; } } /** * Results of an executed command. */ class SM_CLI_ProcessRun { /** * @var array $props Properties of executed command. */ public function __construct( $props ) { foreach ( $props as $key => $value ) { $this->$key = $value; } } /** * Return properties of executed command as a string. * * @return string */ public function __toString() { $out = "$ $this->command\n"; $out .= "$this->stdout\n$this->stderr"; $out .= "cwd: $this->cwd\n"; $out .= "exit status: $this->return_code"; return $out; } } ================================================ FILE: lib/cli/class-sm-cli-scaffold.php ================================================ args = $args; $this->assoc_args = $assoc_args; foreach( $assoc_args as $k => $v ) { $this->{$k} = $v; } /* Set default Limit */ $this->limit = is_numeric( $this->limit ) && $this->limit > 0 ? $this->limit : 100; } /** * Forces data printing to command line ignoring buffer. * * @param string $msg * @return null */ public function output( $msg = '' ) { $args = $this->assoc_args; if( !isset( $args['log'] ) ) return null; esc_html_e(date( 'H:i:s', time() ) . ': ' . $msg . ' ' . $this->memory_usage() . PHP_EOL); @ob_flush(); flush(); } /** * Returns Memory Usage information. */ public function memory_usage() { $args = $this->assoc_args; if( !isset( $args['memory-usage'] ) ) return null; static $last_usage = 0; $differences = $last_usage ? number_format( ( memory_get_usage() / 1024 / 1024 ) - $last_usage, 3 ) . 'Mb' : 'none'; $current_usage = number_format( $last_usage = memory_get_usage() / 1024 / 1024, 3 ) . 'Mb'; return sprintf( "Memory Usage: %s. Diff: %s.", $current_usage, $differences ); } /** * Returns domain of current blog. * */ public function get_current_blog_domain() { $url = get_home_url(); $pieces = parse_url( $url ); $domain = isset( $pieces[ 'host' ] ) ? $pieces['host'] : false; return $domain; } /** * @param $key * * @return null */ public function __get( $key ) { return isset( $this->_properties[ $key ] ) ? $this->_properties[ $key ] : NULL; } /** * @param $key * @param $value */ public function __set( $key, $value ) { $this->_properties[ $key ] = $value; } } ================================================ FILE: lib/cli/class-sm-cli-sync.php ================================================ _prepare(); $timer = time(); /** Get Total Amount of Attachments */ $this->total = $wpdb->get_var(" SELECT COUNT(ID) FROM {$wpdb->posts} WHERE post_type = 'attachment' AND post_mime_type LIKE 'image/%' "); if ($this->batch) { $this->output("Running Batch {$this->batch} from {$this->batches}"); $range = round($this->total / $this->batches); $this->start = ($this->batch * $range) - $range; $this->end = $this->batches == $this->batch ? $this->total : $this->batch * $range; $this->output("Starting from {$this->start} row. "); $this->output("And proceeding up to {$this->end} row."); } else { $this->output("Running in default way. Starting from {$this->start} row and proceeding up to end."); $this->end = $this->end ? $this->end : $this->total; } $media_to_proceed = $this->end - $this->start; //** Counters */ $synced_images = 0; WP_CLI::line('Starting extract attachments.'); set_time_limit(0); for ($this->start; $this->start < $this->end; $this->start += $this->limit) { $limit = ($this->end - $this->start) < $this->limit ? ($this->end - $this->start) : $this->limit; $this->output('Synced: ' . $synced_images . '. Extracting from ' . ($this->start + 1) . ' to ' . ($this->start + $limit)); /** * Get Attachments data. */ $attachments = $wpdb->get_results($wpdb->prepare(" SELECT ID FROM {$wpdb->posts} WHERE post_type = 'attachment' AND post_mime_type LIKE 'image/%' ORDER BY ID {$this->order} LIMIT %d, %d; ", $this->start, $limit), ARRAY_A); if (!empty($attachments)) { foreach ($attachments as $a) { try { timer_start(); $response = Utility::process_image_by_id(intval($a['ID'])); if (!empty($response)) { $synced_images++; $this->output(sprintf(__('%1$s (ID %2$s) was successfully synced in %3$s seconds.', ud_get_stateless_media()->domain), esc_html(get_the_title($response->ID)), $response->ID, timer_stop())); } } catch (FatalException $e) { $this->output($e->getMessage()); break; } catch (UnprocessableException $e) { $this->output($e->getMessage()); } catch (\Throwable $e) { $this->output($e->getMessage()); break; } /** Flush data */ $wpdb->flush(); @ob_flush(); @flush(); } unset($attachments); } } WP_CLI::success("Stateless Media is synced"); WP_CLI::line('Media which have been checked: ' . number_format_i18n($media_to_proceed)); WP_CLI::line('Synced stateless for ' . number_format_i18n($synced_images) . ' attachments'); WP_CLI::line('Spent Time: ' . (time() - $timer) . ' sec'); } /** * Sync files */ public function files() { global $wpdb; /** Prepare arguments */ $this->_prepare(); $timer = time(); /** Get Total Amount of Attachments */ $this->total = $wpdb->get_var(" SELECT COUNT(ID) FROM {$wpdb->posts} WHERE post_type = 'attachment' AND post_mime_type NOT LIKE 'image/%' "); if ($this->batch) { $this->output("Running Batch {$this->batch} from {$this->batches}"); $range = round($this->total / $this->batches); $this->start = ($this->batch * $range) - $range; $this->end = $this->batches == $this->batch ? $this->total : $this->batch * $range; $this->output("Starting from {$this->start} row. "); $this->output("And proceeding up to {$this->end} row."); } else { $this->output("Running in default way. Starting from {$this->start} row and proceeding up to end."); $this->end = $this->end ? $this->end : $this->total; } $media_to_proceed = $this->end - $this->start; //** Counters */ $synced_files = 0; WP_CLI::line('Starting extract attachments.'); set_time_limit(0); for ($this->start; $this->start < $this->end; $this->start += $this->limit) { $limit = ($this->end - $this->start) < $this->limit ? ($this->end - $this->start) : $this->limit; $this->output('Synced: ' . $synced_files . '. Extracting from ' . ($this->start + 1) . ' to ' . ($this->start + $limit)); /** * Get Attachments data. */ $attachments = $wpdb->get_results($wpdb->prepare(" SELECT ID FROM {$wpdb->posts} WHERE post_type = 'attachment' AND post_mime_type NOT LIKE 'image/%' ORDER BY ID {$this->order} LIMIT %d, %d; ", $this->start, $limit), ARRAY_A); if (!empty($attachments)) { foreach ($attachments as $a) { try { timer_start(); $response = Utility::process_file_by_id(intval($a['ID'])); if (!empty($response)) { $synced_files++; $this->output(sprintf(__('%1$s (ID %2$s) was successfully synchronised in %3$s seconds.', ud_get_stateless_media()->domain), esc_html(get_the_title($response->ID)), $response->ID, timer_stop())); } } catch (FatalException $e) { $this->output($e->getMessage()); break; } catch (UnprocessableException $e) { $this->output($e->getMessage()); } catch (\Throwable $e) { $this->output($e->getMessage()); break; } /** Flush data */ $wpdb->flush(); @ob_flush(); @flush(); } unset($attachments); } } WP_CLI::success("Stateless Media is synced"); WP_CLI::line('Media which have been checked: ' . number_format_i18n($media_to_proceed)); WP_CLI::line('Synced stateless for ' . number_format_i18n($synced_files) . ' attachments'); WP_CLI::line('Spent Time: ' . (time() - $timer) . ' sec'); } /** * Prepare */ private function _prepare() { $args = $this->assoc_args; if (isset($args['b'])) { WP_CLI::error('Invalid parameter --b. Command must not be run directly with --b parameter.'); } $this->start = isset($args['start']) && is_numeric($args['start']) ? $args['start'] : 0; $this->limit = isset($args['limit']) && is_numeric($args['limit']) ? $args['limit'] : 100; $this->force = isset($args['force']) ? true : false; $this->continue = isset($args['continue']) ? true : false; $this->fix = isset($args['fix']) ? true : false; $this->order = isset($args['order']) && strtoupper($args['order']) === 'ASC' ? 'ASC' : 'DESC'; if (isset($args['batch'])) { if (!is_numeric($args['batch']) || $args['batch'] <= 0) { WP_CLI::error('Invalid parameter --batch'); } $this->batch = $args['batch']; $this->batches = isset($args['batches']) ? $args['batches'] : 10; if (!is_numeric($this->batches) || $this->batches <= 0) { WP_CLI::error('Invalid parameter --batches'); } elseif ($this->batch > $this->batches) { WP_CLI::error('--batch parameter must is invalid. It must not equal or less then --batches'); } } else { $this->end = isset($args['end']) && is_numeric($args['end']) ? $args['end'] : false; } } } ================================================ FILE: lib/cli/class-sm-cli-upgrade.php ================================================ _prepare(); $timer = time(); /** Get Total Amount of Attachments */ $this->total = $wpdb->get_var( "SELECT COUNT(ID) FROM {$wpdb->posts} WHERE post_type = 'attachment'" ); if( $this->batch ) { $this->output( "Running Batch {$this->batch} from {$this->batches}" ); $range = round( $this->total / $this->batches ); $this->start = ( $this->batch * $range ) - $range; $this->end = $this->batches == $this->batch ? $this->total : $this->batch * $range; $this->output( "Starting from {$this->start} row. " ); $this->output( "And proceeding up to {$this->end} row." ); } else { $this->output( "Running in default way. Starting from {$this->start} row and proceeding up to end." ); $this->end = $this->end ? $this->end : $this->total; } $media_to_proceed = $this->end - $this->start; //** Counters */ $upgraded_meta = 0; WP_CLI::line( 'Starting extract attachments.' ); for( $this->start; $this->start < $this->end; $this->start += $this->limit ) { $limit = ( $this->end - $this->start ) < $this->limit ? ( $this->end - $this->start ) : $this->limit; $this->output( 'Upgraded: ' . $upgraded_meta . '. Extracting from ' . ( $this->start + 1 ) . ' to ' . ( $this->start + $limit ) ); /** * Get Attachments data. * */ $attachments = $wpdb->get_results( $wpdb->prepare( " SELECT ID FROM {$wpdb->posts} WHERE post_type = 'attachment' LIMIT %d, %d; ", $this->start, $limit ), ARRAY_A ); //print_r( $attachments ); die(); foreach( $attachments as $i => $a ) { if( $this->_maybe_upgrade_meta( $a[ 'ID' ] ) ) { $upgraded_meta++; } /** Flush data */ $wpdb->flush(); @ob_flush(); @flush(); } unset( $attachments ); } WP_CLI::success( "Stateless Media Meta is upgraded" ); WP_CLI::line( 'Media which have been checked: ' . number_format_i18n( $media_to_proceed ) ); WP_CLI::line( 'Upgraded stateless meta for ' . number_format_i18n( $upgraded_meta ) . ' attachments' ); WP_CLI::line( 'Spent Time: ' . ( time() - $timer ) . ' sec' ); } /** * Maybe Upgrade Stateless meta for specific attachment */ private function _maybe_upgrade_meta( $id ) { global $wpdb; $bool = false; /* Determine if attachment has legacy main meta data */ $name = get_post_meta( $id, 'sm_cloud:name', true ); $fileLink = get_post_meta( $id, 'sm_cloud:fileLink', true ); /* Let's upgrade our shit. */ if( !empty( $name ) && !empty( $fileLink ) ) { /* Disable autocommit to Database to prevent broken balance transactions. */ $wpdb->query( 'SET autocommit = 0;' ); $wpdb->query( 'START TRANSACTION;' ); try { $cloud_meta = array( 'name' => $name, 'fileLink' => $fileLink, 'id' => get_post_meta( $id, 'sm_cloud:id', true ), 'storageClass' => get_post_meta( $id, 'sm_cloud:storageClass', true ), 'mediaLink' => get_post_meta( $id, 'sm_cloud:mediaLink', true ), 'selfLink' => get_post_meta( $id, 'sm_cloud:selfLink', true ), 'bucket' => get_post_meta( $id, 'sm_cloud:bucket', true ), 'object' => get_post_meta( $id, 'sm_cloud:object', true ), 'sizes' => array(), ); delete_post_meta( $id, 'sm_cloud:name' ); delete_post_meta( $id, 'sm_cloud:fileLink' ); delete_post_meta( $id, 'sm_cloud:id' ); delete_post_meta( $id, 'sm_cloud:storageClass' ); delete_post_meta( $id, 'sm_cloud:mediaLink' ); delete_post_meta( $id, 'sm_cloud:selfLink' ); delete_post_meta( $id, 'sm_cloud:bucket' ); delete_post_meta( $id, 'sm_cloud:object' ); $metadata = wp_get_attachment_metadata( $id ); if( !empty( $metadata[ 'sizes' ] ) && is_array( $metadata[ 'sizes' ] ) ) { foreach( $metadata[ 'sizes' ] as $image_size => $data ) { $name = get_post_meta( $id, 'sm_cloud:' . $image_size . ':name', true ); $fileLink = get_post_meta( $id, 'sm_cloud:' . $image_size . ':fileLink', true ); if( !empty( $name ) && !empty( $fileLink ) ) { $cloud_meta[ 'sizes' ][ $image_size ] = array( 'id' => get_post_meta( $id, 'sm_cloud:' . $image_size . ':id', true ), 'name' => $name, 'fileLink' => $fileLink, 'mediaLink' => get_post_meta( $id, 'sm_cloud:' . $image_size . ':mediaLink', true ), 'selfLink' => get_post_meta( $id, 'sm_cloud:' . $image_size . ':selfLink', true ), ); } delete_post_meta( $id, 'sm_cloud:' . $image_size . ':name' ); delete_post_meta( $id, 'sm_cloud:' . $image_size . ':fileLink' ); delete_post_meta( $id, 'sm_cloud:' . $image_size . ':id' ); delete_post_meta( $id, 'sm_cloud:' . $image_size . ':mediaLink' ); delete_post_meta( $id, 'sm_cloud:' . $image_size . ':selfLink' ); } } if( !empty( $cloud_meta ) ) { update_post_meta( $id, 'sm_cloud', $cloud_meta ); } $bool = true; } catch ( \Exception $e ) { /* Rollback all transactions to prevent broken orders, order items, etc. */ $wpdb->query( 'ROLLBACK' ); $wpdb->query( 'SET autocommit = 1;' ); WP_CLI::warning( "SM Meta for attachment #{$id} was not upgraded due the error: " . $e->getMessage() ); return $bool; } /* Commit all transactions to Database and enable autocommit again. */ $wpdb->query( 'COMMIT' ); $wpdb->query( 'SET autocommit = 1;' ); } return $bool; } /** * */ private function _prepare() { $args = $this->assoc_args; if( isset( $args[ 'b' ] ) ) { WP_CLI::error( 'Invalid parameter --b. Command must not be run directly with --b parameter.' ); } $this->start = isset( $args[ 'start' ] ) && is_numeric( $args[ 'start' ] ) ? $args[ 'start' ] : 0; $this->limit = isset( $args[ 'limit' ] ) && is_numeric( $args[ 'limit' ] ) ? $args[ 'limit' ] : 100; if( isset( $args[ 'batch' ] ) ) { if( !is_numeric( $args[ 'batch' ] ) || $args[ 'batch' ] <= 0 ) { WP_CLI::error( 'Invalid parameter --batch' ); } $this->batch = $args[ 'batch' ]; $this->batches = isset( $args[ 'batches' ] ) ? $args[ 'batches' ] : 10; if( !is_numeric( $args[ 'batches' ] ) || $args[ 'batches' ] <= 0 ) { WP_CLI::error( 'Invalid parameter --batches' ); } elseif ( $this->batch > $this->batches ) { WP_CLI::error( '--batch parameter must is invalid. It must not equal or less then --batches' ); } } else { $this->end = isset( $args[ 'end' ] ) && is_numeric( $args[ 'end' ] ) ? $args[ 'end' ] : false; } } } ================================================ FILE: lib/cli/class-sm-cli.php ================================================ run(); if ( $results->return_code && $exit_on_error ) exit( $results->return_code ); if ( $return_detailed ) { return $results; } else { return $results->return_code; } } } ================================================ FILE: lib/includes/class-settings.php ================================================ "options" * )); * * $_settings->set( 'my.key', 'my.value' ); * * @internal param \UDX\type $defaults * @internal param bool|\UDX\type $force_save * @internal param string|\UDX\type $prefix * @internal param bool|\UDX\type $hash_keys */ public function __construct( $args = false ) { $args = Utility::parse_args( $args, array( 'namespace' => '', 'key' => '', 'auto_commit' => false, 'debug' => false, 'store' => false, 'schema' => false, 'format' => false, 'data' => null )); // Load Schema. if( isset( $args->schema ) && $args->schema ) { $this->set_schema( $args->schema ); } // Set Storage Location(s). if( isset( $args->store ) && $args->store ) { $this->_store = $args->store; } // Set Storage Key. if( isset( $args->key ) && $args->key ) { $this->_key = $args->key; } // Set transient vxpiration value. if( isset( $args->expiration ) && $args->expiration ) { $this->_expiration = $args->expiration; } // Set Format to enforce. if( $args->format ) { $this->_format = $args->format; } // Toggle Debugger. if( $args->debug ) { $this->_debug = $args->debug; } // Set Settings Namespace. if( $args->namespace ) { $this->_namespace = $args->namespace; } // Set Auto Commit. if( $args->auto_commit ) { $this->auto_commit = $args->auto_commit; } // Load Initial. $this->_load(); // Set Initial Data. if( $args->data ) { $this->set( $args->data ); } } /** * Getter for options * * @param bool|\UDX\type $key * * @param bool $default * * @return type */ public function get( $key = false, $default = false ) { // Return all data. if( !$key ) { return $this->_output( $this->_data ); } // Resolve dot-notated key. if( strpos( $key, '.' ) ) { return $this->_resolve( $this->_data, $key, $default ); } // Return value or default. return isset( $this->_data[ $key ] ) ? $this->_data[ $key ] : $default; } /** * Setter for options * * @param string|\UDX\type $key * @param bool|\UDX\type $value * @param bool $bypass_validation * * @internal param bool|\UDX\type $force_save * * @return \UDX\Settings */ public function set( $key = '', $value = false, $bypass_validation = false ) { if( !$this->_data ) { $this->_data = array(); } // First argument is an object/array. if( Utility::get_type( $key ) === 'object' || Utility::get_type( $key ) === 'array' || Utility::get_type( $key ) === 'stdClass' ) { // Conver to array so merge can be done $this->_data = Utility::extend( (array) $this->_data, (array) $key ); } // Standard key & value pair if( Utility::get_type( $key ) === 'string' && ( Utility::get_type( $value ) === 'string' || Utility::get_type( $value ) === 'number' || Utility::get_type( $value ) === 'boolean' ) ) { if( strpos( $key, '.' ) ) { self::set_val( $this->_data, $key, $value ); } else { $this->_data[ $key ] = $value; } } // Standard key with complex value. if( Utility::get_type( $key ) === 'string' ) { if( Utility::get_type( $value ) === 'object' || Utility::get_type( $value ) === 'stdClass' ) { if( strpos( $key, '.' ) ) { self::set_val( $this->_data, $key, $value ); } else { if( isset( $this->_data[ $key ] ) && Utility::get_type( $this->_data[ $key ] ) === 'object' ) { $this->_data[ $key ] = Utility::extend( $this->_data[ $key ], $value ); } else { $this->_data[ $key ] = $value; } } } // Standard key with array value if( Utility::get_type( $value ) === 'array' ) { if( strpos( $key, '.' ) ) { self::set_val( $this->_data, $key, $value ); } else { $this->_data[ $key ] = array_unique( array_merge( isset( $this->_data[ $key ] ) ? (array) $this->_data[ $key ] : array(), $value ) ); } } } // Validate if we have a schema. if( $this->_schema ) { // $this->_validate(); } // Commit to Storage if validation passed. if( $this->is_valid && $this->auto_commit ) { $this->commit(); } return $this; } /** * Handle File Transfer for downloading * * @param array $args * * @return bool */ public function file_transfer( $args = array() ) { $args = Utility::parse_args( $args, array( "name" => "settings", "format" => "json", "cache" => 'public', "filename" => null, "charset" => 'utf8' ) ); $args->filename = $args->filename ? $args->filename : $args->name . '-' . date( 'Y-m-d' ) . '.' . $args->format; // Ensure headers have not been sent. if( headers_sent() ) { return false; } // Send headers. header( "Cache-Control: {$args->cache}" ); header( "Content-Disposition: attachment; filename={$args->filename}" ); header( "Content-Type: text/plain; charset={$args->charset}" ); header( "Content-Description: File Transfer" ); header( "Content-Transfer-Encoding: binary" ); // Prepare in needed format. $_data = $this->_output( $this->get(), $args->format ); // Write data. die( $_data ); } /** * Set Schema from a string or objct. * * @param bool $schema * * @return array|bool|mixed|object */ public function set_schema( $schema = false ) { try { // Take schema as given. if( gettype( $schema ) === 'array' ) { $this->_schema = (object) $schema; } // Take schema as given. if( gettype( $schema ) === 'object' ) { $this->_schema = $schema; } // Load schema from a file. if( gettype( $schema ) === 'string' && is_file( $schema ) ) { $this->_schema = json_decode( file_get_contents( $schema ) ); } } catch( Exception $error ) { $this->console( 'Caught exception: ' . $error->getMessage() ); } return $this->_schema ? $this->_schema : false; } /** * Commit Settings to Storage. * * * site_options - For WordPress, falls back to option if not in multisite. * * options - For WordPress, stores in blog options. * * @author potanin@UD * @method commit */ public function commit() { $_data = $this->_data; // Exclude protected keys. foreach( (array) $_data as $key => $value ) { if( substr( $key, 0, 2 ) === '__' ) { unset( $_data[ $key ] ); } } switch( $this->_store ) { case 'transient': $_value = json_encode( $_data, JSON_FORCE_OBJECT ); if( function_exists( 'set_transient' ) ) { $_value = set_transient( $this->_key, $_value, $this->_expiration ); } break; case 'site_transient': $_value = json_encode( $_data, JSON_FORCE_OBJECT ); if( function_exists( 'set_site_transient' ) ) { $_value = set_site_transient( $this->_key, $_value, $this->_expiration ); } break; case 'site_options': $_value = json_encode( $_data, JSON_FORCE_OBJECT ); if( function_exists( 'update_site_option' ) ) { $_value = update_site_option( $this->_key, $_value ); } break; case 'options': $_value = json_encode( $_data, JSON_FORCE_OBJECT ); if( function_exists( 'update_option' ) ) { $_value = update_option( $this->_key, $_value ); } break; } return $this; } /** * Remove Stored Settings * * @example * * $settings->flush(); * * @return $this */ public function flush() { switch( $this->_store ) { case 'options': if( function_exists( 'delete_option' ) ) { delete_option( $this->_key ); } case 'site_options': if( function_exists( 'delete_site_option' ) ) { delete_option( $this->_key ); } break; } return $this; } /** * Validate Settings against Schema * */ public function _validate() { if( !class_exists( 'JsonSchema\Validator' ) ) { return; } $validator = new \JsonSchema\Validator(); // Process Validation. $validator->check( $this->_data, $this->_schema ); if( $validator->isValid() ) { $this->is_valid = true; $this->_console( "The supplied JSON validates against the schema." ); } else { $this->is_valid = false; $this->_console( "JSON does not validate. Violations:" ); foreach( $validator->getErrors() as $error ) { $this->_console( sprintf( "[%s] %s\n", $error[ 'property' ], $error[ 'message' ] ) ); } } } /** * Library Debugger * * @param $data */ public function _console( $data ) { if( $this->_debug ) { echo sprintf( "lib-settings debug: [%s].", $data ); } } /** * Load options from DB * * @return \UDX\Settings */ public function _load() { switch( $this->_store ) { // WordPress Site Options. case 'options': case 'site_options': // Load from options. if( $this->_store == 'site_options' ) { $_value = \get_site_option( $this->_key ); } else { $_value = \get_option( $this->_key ); } // If already an array it must have been serialized if( gettype( $_value ) === 'array' ) { return $this->_output( $this->_data = $_value ); } try { $_value = json_decode( $_value, true ); } catch( Exception $error ) { $this->_console( 'Caught exception: ' . $error->getMessage() ); } $this->_data = $_value; break; default: break; } return $this->_data; } /** * Prepare Data for Output * * @param $data * * @param bool $format * * @return array|mixed|string|void */ public function _output( $data, $format = false ) { $format = $format ? $format : $this->_format; // Stringify. if( $format === 'json' ) { return json_encode( $data ); } // Deeep Object. if( $format === 'object' ) { return json_decode( json_encode( $data ) ); } return $data; } /** * @param array $arr * @param $path * @param $val * * @return mixed */ public function set_val( array &$arr, $path, $val ) { $loc = & $arr; foreach( explode( '.', $path ) as $step ) { $loc = & $loc[ $step ]; } return $loc = $val; } /** * Expand Array * @source http://stackoverflow.com/questions/17365059/how-to-unflatten-array-in-php-using-dot-notation * * @param $array * @param int $level * * @return array */ public function _expand( $array, $level = 0 ) { $result = array(); $next = $level + 1; foreach( $array as $key => $value ) { $tree = explode( '.', $key ); if( isset( $tree[ $level ] ) ) { if( !isset( $tree[ $next ] ) ) { $result[ $tree[ $level ] ][ 'id' ] = $key; $result[ $tree[ $level ] ][ 'title' ] = $value; if( !isset( $result[ $tree[ $level ] ][ 'children' ] ) ) { $result[ $tree[ $level ] ][ 'children' ] = array(); } } else { if( isset( $result[ $tree[ $level ] ][ 'children' ] ) ) { $result[ $tree[ $level ] ][ 'children' ] = array_merge_recursive( $result[ $tree[ $level ] ][ 'children' ], self::_expand( array( $key => $value ), $next ) ); } else { $result[ $tree[ $level ] ][ 'children' ] = self::_expand( array( $key => $value ), $next ); } } } } return $result; } /** * Resolve dot-notated key. * * @source http://stackoverflow.com/questions/14704984/best-way-for-dot-notation-access-to-multidimensional-array-in-php * * @param $a * @param $path * @param null $default * * @internal param array $a * @return array|null */ public function _resolve( $a, $path, $default = null ) { $current = $a; $p = strtok( $path, '.' ); while( $p !== false ) { if( !isset( $current[ $p ] ) ) { return $default; } $current = $current[ $p ]; $p = strtok( '.' ); } return $current; } } } } ================================================ FILE: lib/includes/class-utility.php ================================================ $value ) { if( !array_key_exists( $key, $base ) and !is_numeric( $key ) ) { $base[ $key ] = $append[ $key ]; continue; } if( ( isset( $value ) && @is_array( $value ) ) || ( isset( $base[ $key ] ) && @is_array( $base[ $key ] ) ) ) { // extend if exists, otherwise create. if( isset( $base[ $key ] ) ) { $base[ $key ] = self::extend( $base[ $key ], $append[ $key ] ); } else { $base[ $key ] = $append[ $key ]; } } else if( is_numeric( $key ) ) { if( !in_array( $value, $base ) ) $base[ ] = $value; } else { $base[ $key ] = $value; } } } return $base; } /** * Localization Functionality. * * Replaces array's l10n data. * Helpful for localization of data which is stored in JSON files ( see /schemas ) * * Usage: * * add_filter( 'ud::schema::localization', function($locals){ * return array_merge( array( 'value_for_translating' => __( 'Blah Blah' ) ), $locals ); * }); * * $result = self::l10n_localize (array( * 'key' => 'l10n.value_for_translating' * ) ); * * * @param array $data * @param array $l10n translated values * @return array * @author peshkov@UD */ static public function l10n_localize( $data, $l10n = array() ) { if ( !is_array( $data ) && !is_object( $data ) ) { return $data; } //** The Localization's list. */ $l10n = apply_filters( 'ud::schema::localization', $l10n ); //** Replace l10n entries */ foreach( $data as $k => $v ) { if ( is_array( $v ) ) { $data[ $k ] = self::l10n_localize( $v, $l10n ); } elseif ( is_string( $v ) ) { if ( strpos( $v, 'l10n' ) !== false ) { preg_match_all( '/l10n\.([^\s]*)/', $v, $matches ); if ( !empty( $matches[ 1 ] ) ) { foreach ( $matches[ 1 ] as $i => $m ) { if ( array_key_exists( $m, $l10n ) ) { $data[ $k ] = str_replace( $matches[ 0 ][ $i ], $l10n[ $m ], $data[ $k ] ); } } } } } } return $data; } } } } ================================================ FILE: lib/meta-box-tabs/CHANGELOG.md ================================================ ### 1.2.1 - 2025-09-16 - Fix tabs not working with blocks. ### 1.2.0 - 2025-02-04 Add an option `'tab_remember' => true` to set to remember the opening tab in the next page load. ### 1.1.19 - 2024-12-16 Improve performance ### 1.1.18 - 2024-08-19 Fix running PHP Codesniffer when installing & autoload the plugin's main file via Composer ### 1.1.17 - 2023-09-18 Fix "hide_from_front" not working if fields are in a tab ### 1.1.16 - 2023-07-18 Fix issue with tooltip left ### 1.1.15 - 2023-03-08 Auto enqueue Font Awesome when it's used ### 1.1.14 - 2023-01-16 Fix issue with tooltip left ### 1.1.13 - 2022-06-30 - Fix wysiwyg options not working ### 1.1.12 - 2022-05-05 - Fix validating fields in inactive tabs ### 1.1.11 - 2022-03-14 - Fix not working with blocks ### 1.1.10 - 2022-01-14 - Fix tabs overflow container when too many tabs - Fix JS validation error when no tabs ### 1.1.9 - 2021-10-25 - Improve styling ### 1.1.8 - 2020-09-04 - Fix undefined `tab_default_value`. ### 1.1.7 - 2020-07-06 - Fix clicking icons not switching tabs. ### 1.1.6 - 2020-06-02 - Improve style for tabs ### 1.1.5 - 2019-12-24 - Show error fields in hidden tabs when validating. ### 1.1.4 - 2019-04-02 - Fixed `overflow` issue cut off the color picker. - Fixed wrong spacing for fields in user profile, edit term and settings pages. ### 1.1.3 - 2019-02-26 - Fixed CSS for textarea field in tabs-left style. - Also optimized CSS for user profile, edit term and settings pages. ### 1.1.2 - 2019-01-21 - Fixed styling in user profile, term edit and settings pages screen. ### 1.1.1 - Improved the way to show Google maps/OSM in hidden tabs. ### 1.1.0 - Added new setting `tab_default_active` to set the default active tab when page loads - Fixed color field is cut off in tab panel with tabs on the left. ### 1.0.4 - Fixed styles for mobile devices ### 1.0.3 - Fix style for groups ### 1.0.2 - Empty tabs now showing empty tab panel instead of showing existing fields from other tabs. ### 1.0.1 - Improvement: Better padding for tab panel content with tabs on the left. ### 1.0.0 - Improvement: Make the extension safe to be included in themes/plugins. ### 0.1.7 - Improvement: Better compatibility with Conditional Logic ### 0.1.5 - Fix: Incorrect style for file advanced fields with Meta Box 4.6 ### 0.1.4 - Improvement: Add option to hide meta box wrapper around tabs ### 0.1.3 - Fix: Google maps not fully loaded in hidden tab ### 0.1.2 - New: Now works with [MB Group](https://metabox.io/plugins/meta-box-group/) extension - New: Improve performance by loading in admin only ### 0.1.1 - New: Add left tab style - New: Allow to use icons in tabs. Support Dashicons by default but can use any icon. ### 0.1 - First release ================================================ FILE: lib/meta-box-tabs/meta-box-tabs.php ================================================ . */ // Prevent loading this file directly. if ( ! defined( 'ABSPATH' ) ) { return; } if ( ! class_exists( 'MB_Tabs' ) ) { class MB_Tabs { /** * Indicate that the instance of the class is working on a meta box that has tabs or not. * It will be set 'true' BEFORE meta box is display and 'false' AFTER. * * @var bool */ protected $active = false; /** * Store all output of fields. * This is used to put fields in correct
for tabs. * The fields' output will be get via filter 'rwmb_outer_html'. * * @var array */ protected $fields_output = []; public function __construct() { add_action( 'rwmb_enqueue_scripts', [ $this, 'enqueue' ] ); add_action( 'rwmb_before', [ $this, 'opening_div' ], 1 ); // 1 = display first, before tab nav. add_action( 'rwmb_after', [ $this, 'closing_div' ], 100 ); // 100 = display last, after tab panels. // Change the title position of metabox add_action( 'rwmb_after', [ $this, 'show_nav' ], 20 ); add_action( 'rwmb_after', [ $this, 'show_panels' ], 30 ); add_filter( 'rwmb_outer_html', [ $this, 'capture_fields' ], 20, 2 ); } public function enqueue( RW_Meta_Box $obj ) { list( , $url ) = RWMB_Loader::get_path( __DIR__ ); wp_enqueue_style( 'rwmb-tabs', $url . 'tabs.css', [], '1.2.0' ); wp_enqueue_script( 'rwmb-tabs', $url . 'tabs.js', [ 'jquery' ], '1.2.0', true ); if ( empty( $obj->meta_box['tabs'] ) ) { return; } $tabs = (array) $obj->meta_box['tabs']; foreach ( $tabs as $tab_data ) { if ( is_string( $tab_data ) ) { $tab_data = [ 'label' => $tab_data ]; } $tab_data = wp_parse_args( $tab_data, [ 'icon' => '', 'label' => '', ] ); $strpos = [ 'fa', 'fas', 'fa-solid', 'fab', 'fa-brand', 'far', 'fa-regular' ]; foreach ( $strpos as $value ) { if ( strpos( $tab_data['icon'], $value ) !== false ) { wp_enqueue_style( 'font-awesome', 'https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.2.1/css/all.min.css', [], ' 6.2.1' ); return; } } } } /** * Display opening div for tabs for meta box. * * @param RW_Meta_Box $obj Meta Box object. */ public function opening_div( RW_Meta_Box $obj ) { if ( empty( $obj->meta_box['tabs'] ) ) { return; } $class = 'rwmb-tabs'; if ( isset( $obj->meta_box['tab_style'] ) && 'default' !== $obj->meta_box['tab_style'] ) { $class .= ' rwmb-tabs-' . $obj->meta_box['tab_style']; } if ( isset( $obj->meta_box['tab_wrapper'] ) && false === $obj->meta_box['tab_wrapper'] ) { $class .= ' rwmb-tabs-no-wrapper'; } $tab_remember = isset( $obj->meta_box['tab_remember'] ) && $obj->meta_box['tab_remember'] ? $obj->meta_box['id'] : ''; echo '
'; // Set 'true' to let us know that we're working on a meta box that has tabs. $this->active = true; } /** * Display closing div for tabs for meta box. */ public function closing_div() { if ( ! $this->active ) { return; } echo '
'; // Reset to initial state to be ready for other meta boxes. $this->active = false; $this->fields_output = []; } /** * Display tab navigation. * * @param RW_Meta_Box $obj Meta Box object. */ public function show_nav( RW_Meta_Box $obj ) { if ( ! $this->active ) { return; } $tabs = $obj->meta_box['tabs']; $default_active = isset( $obj->tab_default_active ) ? $obj->tab_default_active : null; echo '
    '; $i = 0; foreach ( $tabs as $key => $tab_data ) { if ( is_string( $tab_data ) ) { $tab_data = [ 'label' => $tab_data ]; } $tab_data = wp_parse_args( $tab_data, [ 'icon' => '', 'label' => '', ] ); if ( filter_var( $tab_data['icon'], FILTER_VALIDATE_URL ) ) { // If icon is an URL. $icon = ''; } else { // If icon is icon font. // If icon is dashicons, auto add class 'dashicons' for users. if ( false !== strpos( $tab_data['icon'], 'dashicons' ) ) { $tab_data['icon'] .= ' dashicons'; } // Remove duplicate classes. $tab_data['icon'] = array_filter( array_map( 'trim', explode( ' ', $tab_data['icon'] ) ) ); $tab_data['icon'] = implode( ' ', array_unique( $tab_data['icon'] ) ); $icon = $tab_data['icon'] ? '' : ''; } $class = "rwmb-tab-$key"; if ( ( $default_active && $default_active === $key ) || ( ! $default_active && ! $i ) ) { $class .= ' rwmb-tab-active'; } printf( '
  • %s%s
  • ', esc_attr( $class ), esc_attr( $key ), $icon, esc_html( $tab_data['label'] ) ); ++$i; } echo '
'; } /** * Display tab panels. * Note that: this public function is hooked to 'rwmb_after', when all fields are outputted. * (and captured by 'capture_fields' public function). * * @param RW_Meta_Box $obj Meta Box object. */ public function show_panels( RW_Meta_Box $obj ) { if ( ! $this->active ) { return; } // Store all tabs. $tabs = $obj->meta_box['tabs']; echo '
'; foreach ( $this->fields_output as $tab => $fields ) { // Remove rendered tab. if ( isset( $tabs[ $tab ] ) ) { unset( $tabs[ $tab ] ); } echo '
'; echo implode( '', $fields ); echo '
'; } // Print unrendered tabs. foreach ( $tabs as $tab_id => $tab_data ) { echo '
'; echo '
'; } echo '
'; } /** * Save field output into class variable to output later. * * @param string $output Field output. * @param array $field Field configuration. * * @return string */ public function capture_fields( $output, $field ) { // If meta box doesn't have tabs, do nothing. if ( ! $this->active || ! isset( $field['tab'] ) ) { return $output; } $tab = $field['tab']; if ( ! isset( $this->fields_output[ $tab ] ) ) { $this->fields_output[ $tab ] = []; } $this->fields_output[ $tab ][] = $output; // Return empty string to let Meta Box plugin echoes nothing. return ''; } } new MB_Tabs(); } ================================================ FILE: lib/meta-box-tabs/tabs.css ================================================ .rwmb-tab-nav{display:flex;margin-bottom:-1px;flex-wrap:wrap;padding:inherit}.rwmb-tab-nav li{margin:0;display:inline-block}.rwmb-tab-nav a{display:flex;align-items:center;gap:4px;padding:8px 12px;line-height:1;text-decoration:none}.rwmb-tab-nav a:active,.rwmb-tab-nav a:focus{outline:none;box-shadow:none}.rwmb-tab-nav i{width:16px;height:16px;font-size:16px}.rwmb-tab-nav i[class^=fa]{width:12px;height:12px;font-size:12px}.rwmb-tab-nav img{width:12px;height:12px;display:inline-block}.rwmb-tab-active{border:1px solid #ccd0d4;border-bottom-color:rgba(0,0,0,0);background:#fff}.rwmb-tab-active a{color:inherit}.rwmb-tab-panels{background:#fff;border:1px solid #ccd0d4}.rwmb-tab-panel{padding:12px;display:none}.rwmb-tabs-box .rwmb-tab-nav li{background:#f5f5f5;border:1px solid #ccd0d4;margin-right:5px}.rwmb-tabs-box .rwmb-tab-nav li:hover{background:#fff}.rwmb-tabs-box .rwmb-tab-nav a{color:inherit}.rwmb-tabs-box .rwmb-tab-nav .rwmb-tab-active{border-bottom-color:rgba(0,0,0,0)}.rwmb-tabs-box .rwmb-tab-nav .rwmb-tab-active,.rwmb-tabs-box .rwmb-tab-nav .rwmb-tab-active:hover{background:#fff}.rwmb-tabs-box .rwmb-clone{background-color:rgba(0,0,0,0)}.rwmb-tabs-left{margin:-6px -12px -12px;display:flex}.rwmb-tabs-left .rwmb-tab-nav{flex-direction:column;margin:0 -1px 0 0;border-right:1px solid #ccd0d4;background:#fafafa}.rwmb-tabs-left .rwmb-tab-nav li{display:block;min-width:180px;border-bottom:1px solid #ccd0d4}.rwmb-tabs-left .rwmb-tab-nav li:first-child{border-top:none}.rwmb-tabs-left .rwmb-tab-nav a{padding:12px}.rwmb-tabs-left .rwmb-tab-active{border-width:0 0 1px 0;margin-right:-1px;z-index:1}.rwmb-tabs-left .rwmb-tab-panels{flex:1;border-width:0 0 0 1px}.rwmb-tabs-left .rwmb-tab-panel{padding:12px 20px;border:none}.rwmb-seamless .rwmb-tabs-left{margin:0;border:1px solid #ccd0d4}.profile-php .rwmb-tabs-left,.user-edit-php .rwmb-tabs-left,.term-php .rwmb-tabs-left,.edit-tags-php .rwmb-tabs-left,.rwmb-settings-no-boxes .rwmb-tabs-left{margin:0;flex-wrap:wrap}.profile-php .rwmb-tabs-left>h2,.user-edit-php .rwmb-tabs-left>h2,.term-php .rwmb-tabs-left>h2,.edit-tags-php .rwmb-tabs-left>h2,.rwmb-settings-no-boxes .rwmb-tabs-left>h2{flex-basis:100%}.profile-php .rwmb-tabs-left .rwmb-tab-nav,.user-edit-php .rwmb-tabs-left .rwmb-tab-nav,.term-php .rwmb-tabs-left .rwmb-tab-nav,.edit-tags-php .rwmb-tabs-left .rwmb-tab-nav,.rwmb-settings-no-boxes .rwmb-tabs-left .rwmb-tab-nav{border:1px solid #ccd0d4}.profile-php .rwmb-tabs-left .rwmb-tab-panels,.user-edit-php .rwmb-tabs-left .rwmb-tab-panels,.term-php .rwmb-tabs-left .rwmb-tab-panels,.edit-tags-php .rwmb-tabs-left .rwmb-tab-panels,.rwmb-settings-no-boxes .rwmb-tabs-left .rwmb-tab-panels{border-width:1px}.profile-php .rwmb-tabs .rwmb-label,.profile-php .rwmb-tabs .rwmb-input,.user-edit-php .rwmb-tabs .rwmb-label,.user-edit-php .rwmb-tabs .rwmb-input,.term-php .rwmb-tabs .rwmb-label,.term-php .rwmb-tabs .rwmb-input,.edit-tags-php .rwmb-tabs .rwmb-label,.edit-tags-php .rwmb-tabs .rwmb-input,.rwmb-settings-no-boxes .rwmb-tabs .rwmb-label,.rwmb-settings-no-boxes .rwmb-tabs .rwmb-input{padding:0}.rwmb-settings-no-boxes .rwmb-tab-panel .rwmb-field{padding:12px 0 0}@media(max-width: 575px){.rwmb-tabs{margin:-6px -12px -12px}.rwmb-tabs>h2{margin-left:12px;margin-right:12px}.rwmb-seamless .rwmb-tabs{margin:0}.rwmb-tab-nav{flex-direction:column;margin-top:0;margin-bottom:0}.rwmb-tab-nav li{display:block;border-bottom:1px solid #ccd0d4}.rwmb-tab-nav a{padding:12px}.rwmb-tab-nav .rwmb-tab-active{border-width:0 0 1px 0}.rwmb-tab-panels{border:none;background:none}.rwmb-tabs-box .rwmb-tab-nav li{border-width:0 0 1px 0;margin-right:0}.rwmb-tabs-box .rwmb-tab-nav .rwmb-tab-active{border-bottom:1px solid #ccd0d4}.rwmb-tabs-left{flex-direction:column}.rwmb-tabs-left .rwmb-tab-nav{width:100%;border-right:none}.rwmb-tabs-left .rwmb-tab-active{margin-right:0}.rwmb-tabs-left .rwmb-tab-panel{padding-left:0;padding-right:0}} ================================================ FILE: lib/meta-box-tabs/tabs.js ================================================ ( ( window, document, $ ) => { // Store initialized tabs to avoid re-initializing them. const initializedTabs = new Set(); function switchTab() { $( '.rwmb-tab-nav' ).on( 'click', 'a', e => { e.preventDefault(); showTab( e.target ); } ); } const showTab = ( el ) => { const tab = el.closest( 'li' ).dataset.panel, $wrapper = $( el ).closest( '.rwmb-tabs' ), $tabs = $wrapper.find( '.rwmb-tab-nav > li' ), $panels = $wrapper.find( '.rwmb-tab-panel' ); $tabs.removeClass( 'rwmb-tab-active' ).filter( '[data-panel="' + tab + '"]' ).addClass( 'rwmb-tab-active' ); $panels.hide().filter( '.rwmb-tab-panel-' + tab ).show(); const tabsGroupId = $wrapper.data( 'tab-remember' ); // Save active tab to local storage. if ( tabsGroupId ) { rememberTab( tab, tabsGroupId ); } // Delay expensive tasks, make sure the panel is visible before initializing if ( !initializedTabs.has( tab ) ) { setTimeout( () => { rwmb.$document.trigger( 'mb_init_editors' ); // Refresh maps, make sure they're fully loaded, when it's in hidden div (tab). $( window ).trigger( 'rwmb_map_refresh' ); initializedTabs.add( tab ); }, 200 ); } }; // Set active tab based on visible pane to better works with Meta Box Conditional Logic. function tweakForConditionalLogic() { const $tabGroups = $( '.rwmb-tabs' ); $tabGroups.each( function() { const $tabs = $( this ); if ( $tabs.find( '.rwmb-tab-active' ).is( ':visible' ) ) { return; } // Find the active pane. const activePane = $tabs.find( '.rwmb-tab-panel[style*="block"]' ).index(); if ( activePane >= 0 ) { $tabs.find( '.rwmb-tab-nav li' ).removeClass( 'rwmb-tab-active' ).eq( activePane ).addClass( 'rwmb-tab-active' ); } } ); } function showValidateErrorFields() { var inputSelectors = 'input[class*="rwmb-error"], textarea[class*="rwmb-error"], select[class*="rwmb-error"], button[class*="rwmb-error"]'; $( document ).on( 'after_validate', 'form', e => { var $input = $( e.target ).find( inputSelectors ), $panel = $input.closest( '.rwmb-tab-panel' ); if ( $panel.length ) { showTab( $input.closest( '.rwmb-tabs' ).find( 'li[data-panel="' + $panel.data( 'panel' ) + '"] a' )[ 0 ] ); } } ); } const rememberTab = ( panel, tabsGroupId ) => { localStorage.setItem( `rwmb_active_tab:${ tabsGroupId }`, panel ); }; const setActiveTabsFromLocalStorage = () => { const tabGroups = document.querySelectorAll( '.rwmb-tabs' ); tabGroups.forEach( tabs => { const tabsGroupId = tabs.dataset.tabRemember; if ( !tabsGroupId ) { tabs.querySelector( '.rwmb-tab-active a' ).click(); return; } const activeTab = localStorage.getItem( `rwmb_active_tab:${ tabsGroupId }` ); if ( activeTab ) { tabs.querySelector( `li[data-panel="${ activeTab }"] a` ).click(); } else { tabs.querySelector( '.rwmb-tab-active a' ).click(); } } ); }; $( document ).on( 'mb_ready', function() { switchTab(); tweakForConditionalLogic(); showValidateErrorFields(); setActiveTabsFromLocalStorage(); // Remove wrapper. Use Meta Box's seamless style. $( '.rwmb-tabs-no-wrapper' ).closest( '.postbox' ).removeClass( 'rwmb-default' ).addClass( 'rwmb-seamless' ); } ); } )( window, document, jQuery ); ================================================ FILE: lib/ns-vendor/classes/.gitkeep ================================================ ================================================ FILE: lib/ns-vendor/classes/deliciousbrains/wp-background-processing/classes/wp-async-request.php ================================================ identifier = $this->prefix . '_' . $this->action; add_action( 'wp_ajax_' . $this->identifier, array( $this, 'maybe_handle' ) ); add_action( 'wp_ajax_nopriv_' . $this->identifier, array( $this, 'maybe_handle' ) ); } /** * Set data used during the request. * * @param array $data Data. * * @return $this */ public function data( $data ) { $this->data = $data; return $this; } /** * Dispatch the async request. * * @return array|WP_Error|false HTTP Response array, WP_Error on failure, or false if not attempted. */ public function dispatch() { $url = add_query_arg( $this->get_query_args(), $this->get_query_url() ); $args = $this->get_post_args(); return wp_remote_post( esc_url_raw( $url ), $args ); } /** * Get query args. * * @return array */ protected function get_query_args() { if ( property_exists( $this, 'query_args' ) ) { return $this->query_args; } $args = array( 'action' => $this->identifier, 'nonce' => wp_create_nonce( $this->identifier ), ); /** * Filters the post arguments used during an async request. * * @param array $url */ return apply_filters( $this->identifier . '_query_args', $args ); } /** * Get query URL. * * @return string */ protected function get_query_url() { if ( property_exists( $this, 'query_url' ) ) { return $this->query_url; } $url = admin_url( 'admin-ajax.php' ); /** * Filters the post arguments used during an async request. * * @param string $url */ return apply_filters( $this->identifier . '_query_url', $url ); } /** * Get post args. * * @return array */ protected function get_post_args() { if ( property_exists( $this, 'post_args' ) ) { return $this->post_args; } $args = array( 'timeout' => 5, 'blocking' => false, 'body' => $this->data, 'cookies' => $_COOKIE, // Passing cookies ensures request is performed as initiating user. 'sslverify' => apply_filters( 'https_local_ssl_verify', false ), // Local requests, fine to pass false. ); /** * Filters the post arguments used during an async request. * * @param array $args */ return apply_filters( $this->identifier . '_post_args', $args ); } /** * Maybe handle a dispatched request. * * Check for correct nonce and pass to handler. * * @return void|mixed */ public function maybe_handle() { // Don't lock up other requests while processing. session_write_close(); check_ajax_referer( $this->identifier, 'nonce' ); $this->handle(); return $this->maybe_wp_die(); } /** * Should the process exit with wp_die? * * @param mixed $return What to return if filter says don't die, default is null. * * @return void|mixed */ protected function maybe_wp_die( $return = null ) { /** * Should wp_die be used? * * @return bool */ if ( apply_filters( $this->identifier . '_wp_die', true ) ) { wp_die(); } return $return; } /** * Handle a dispatched request. * * Override this method to perform any actions required * during the async request. */ abstract protected function handle(); } ================================================ FILE: lib/ns-vendor/classes/deliciousbrains/wp-background-processing/classes/wp-background-process.php ================================================ allowed_batch_data_classes || true !== $allowed_batch_data_classes ) { $this->allowed_batch_data_classes = $allowed_batch_data_classes; } $this->cron_hook_identifier = $this->identifier . '_cron'; $this->cron_interval_identifier = $this->identifier . '_cron_interval'; add_action( $this->cron_hook_identifier, array( $this, 'handle_cron_healthcheck' ) ); add_filter( 'cron_schedules', array( $this, 'schedule_cron_healthcheck' ) ); } /** * Schedule the cron healthcheck and dispatch an async request to start processing the queue. * * @access public * @return array|WP_Error|false HTTP Response array, WP_Error on failure, or false if not attempted. */ public function dispatch() { if ( $this->is_processing() ) { // Process already running. return false; } // Schedule the cron healthcheck. $this->schedule_event(); // Perform remote post. return parent::dispatch(); } /** * Push to the queue. * * Note, save must be called in order to persist queued items to a batch for processing. * * @param mixed $data Data. * * @return $this */ public function push_to_queue( $data ) { $this->data[] = $data; return $this; } /** * Save the queued items for future processing. * * @return $this */ public function save() { $key = $this->generate_key(); if ( ! empty( $this->data ) ) { update_site_option( $key, $this->data ); } // Clean out data so that new data isn't prepended with closed session's data. $this->data = array(); return $this; } /** * Update a batch's queued items. * * @param string $key Key. * @param array $data Data. * * @return $this */ public function update( $key, $data ) { if ( ! empty( $data ) ) { update_site_option( $key, $data ); } return $this; } /** * Delete a batch of queued items. * * @param string $key Key. * * @return $this */ public function delete( $key ) { delete_site_option( $key ); return $this; } /** * Delete entire job queue. */ public function delete_all() { $batches = $this->get_batches(); foreach ( $batches as $batch ) { $this->delete( $batch->key ); } delete_site_option( $this->get_status_key() ); $this->cancelled(); } /** * Cancel job on next batch. */ public function cancel() { update_site_option( $this->get_status_key(), self::STATUS_CANCELLED ); // Just in case the job was paused at the time. $this->dispatch(); } /** * Has the process been cancelled? * * @return bool */ public function is_cancelled() { $status = get_site_option( $this->get_status_key(), 0 ); return absint( $status ) === self::STATUS_CANCELLED; } /** * Called when background process has been cancelled. */ protected function cancelled() { do_action( $this->identifier . '_cancelled' ); } /** * Pause job on next batch. */ public function pause() { update_site_option( $this->get_status_key(), self::STATUS_PAUSED ); } /** * Is the job paused? * * @return bool */ public function is_paused() { $status = get_site_option( $this->get_status_key(), 0 ); return absint( $status ) === self::STATUS_PAUSED; } /** * Called when background process has been paused. */ protected function paused() { do_action( $this->identifier . '_paused' ); } /** * Resume job. */ public function resume() { delete_site_option( $this->get_status_key() ); $this->schedule_event(); $this->dispatch(); $this->resumed(); } /** * Called when background process has been resumed. */ protected function resumed() { do_action( $this->identifier . '_resumed' ); } /** * Is queued? * * @return bool */ public function is_queued() { return ! $this->is_queue_empty(); } /** * Is the tool currently active, e.g. starting, working, paused or cleaning up? * * @return bool */ public function is_active() { return $this->is_queued() || $this->is_processing() || $this->is_paused() || $this->is_cancelled(); } /** * Generate key for a batch. * * Generates a unique key based on microtime. Queue items are * given a unique key so that they can be merged upon save. * * @param int $length Optional max length to trim key to, defaults to 64 characters. * @param string $key Optional string to append to identifier before hash, defaults to "batch". * * @return string */ protected function generate_key( $length = 64, $key = 'batch' ) { $unique = md5( microtime() . wp_rand() ); $prepend = $this->identifier . '_' . $key . '_'; return substr( $prepend . $unique, 0, $length ); } /** * Get the status key. * * @return string */ protected function get_status_key() { return $this->identifier . '_status'; } /** * Maybe process a batch of queued items. * * Checks whether data exists within the queue and that * the process is not already running. */ public function maybe_handle() { // Don't lock up other requests while processing. session_write_close(); if ( $this->is_processing() ) { // Background process already running. return $this->maybe_wp_die(); } if ( $this->is_cancelled() ) { $this->clear_scheduled_event(); $this->delete_all(); return $this->maybe_wp_die(); } if ( $this->is_paused() ) { $this->clear_scheduled_event(); $this->paused(); return $this->maybe_wp_die(); } if ( $this->is_queue_empty() ) { // No data to process. return $this->maybe_wp_die(); } check_ajax_referer( $this->identifier, 'nonce' ); $this->handle(); return $this->maybe_wp_die(); } /** * Is queue empty? * * @return bool */ protected function is_queue_empty() { return empty( $this->get_batch() ); } /** * Is process running? * * Check whether the current process is already running * in a background process. * * @return bool * * @deprecated 1.1.0 Superseded. * @see is_processing() */ protected function is_process_running() { return $this->is_processing(); } /** * Is the background process currently running? * * @return bool */ public function is_processing() { if ( get_site_transient( $this->identifier . '_process_lock' ) ) { // Process already running. return true; } return false; } /** * Lock process. * * Lock the process so that multiple instances can't run simultaneously. * Override if applicable, but the duration should be greater than that * defined in the time_exceeded() method. */ protected function lock_process() { $this->start_time = time(); // Set start time of current process. $lock_duration = ( property_exists( $this, 'queue_lock_time' ) ) ? $this->queue_lock_time : 60; // 1 minute $lock_duration = apply_filters( $this->identifier . '_queue_lock_time', $lock_duration ); set_site_transient( $this->identifier . '_process_lock', microtime(), $lock_duration ); } /** * Unlock process. * * Unlock the process so that other instances can spawn. * * @return $this */ protected function unlock_process() { delete_site_transient( $this->identifier . '_process_lock' ); return $this; } /** * Get batch. * * @return stdClass Return the first batch of queued items. */ protected function get_batch() { return array_reduce( $this->get_batches( 1 ), static function ( $carry, $batch ) { return $batch; }, array() ); } /** * Get batches. * * @param int $limit Number of batches to return, defaults to all. * * @return array of stdClass */ public function get_batches( $limit = 0 ) { global $wpdb; if ( empty( $limit ) || ! is_int( $limit ) ) { $limit = 0; } $table = $wpdb->options; $column = 'option_name'; $key_column = 'option_id'; $value_column = 'option_value'; if ( is_multisite() ) { $table = $wpdb->sitemeta; $column = 'meta_key'; $key_column = 'meta_id'; $value_column = 'meta_value'; } $key = $wpdb->esc_like( $this->identifier . '_batch_' ) . '%'; $sql = ' SELECT * FROM ' . $table . ' WHERE ' . $column . ' LIKE %s ORDER BY ' . $key_column . ' ASC '; $args = array( $key ); if ( ! empty( $limit ) ) { $sql .= ' LIMIT %d'; $args[] = $limit; } $items = $wpdb->get_results( $wpdb->prepare( $sql, $args ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared $batches = array(); if ( ! empty( $items ) ) { $allowed_classes = $this->allowed_batch_data_classes; $batches = array_map( static function ( $item ) use ( $column, $value_column, $allowed_classes ) { $batch = new stdClass(); $batch->key = $item->{$column}; $batch->data = static::maybe_unserialize( $item->{$value_column}, $allowed_classes ); return $batch; }, $items ); } return $batches; } /** * Handle a dispatched request. * * Pass each queue item to the task handler, while remaining * within server memory and time limit constraints. */ protected function handle() { $this->lock_process(); /** * Number of seconds to sleep between batches. Defaults to 0 seconds, minimum 0. * * @param int $seconds */ $throttle_seconds = max( 0, apply_filters( $this->identifier . '_seconds_between_batches', apply_filters( $this->prefix . '_seconds_between_batches', 0 ) ) ); do { $batch = $this->get_batch(); foreach ( $batch->data as $key => $value ) { $task = $this->task( $value ); if ( false !== $task ) { $batch->data[ $key ] = $task; } else { unset( $batch->data[ $key ] ); } // Keep the batch up to date while processing it. if ( ! empty( $batch->data ) ) { $this->update( $batch->key, $batch->data ); } // Let the server breathe a little. sleep( $throttle_seconds ); // Batch limits reached, or pause or cancel request. if ( $this->time_exceeded() || $this->memory_exceeded() || $this->is_paused() || $this->is_cancelled() ) { break; } } // Delete current batch if fully processed. if ( empty( $batch->data ) ) { $this->delete( $batch->key ); } } while ( ! $this->time_exceeded() && ! $this->memory_exceeded() && ! $this->is_queue_empty() && ! $this->is_paused() && ! $this->is_cancelled() ); $this->unlock_process(); // Start next batch or complete process. if ( ! $this->is_queue_empty() ) { $this->dispatch(); } else { $this->complete(); } return $this->maybe_wp_die(); } /** * Memory exceeded? * * Ensures the batch process never exceeds 90% * of the maximum WordPress memory. * * @return bool */ protected function memory_exceeded() { $memory_limit = $this->get_memory_limit() * 0.9; // 90% of max memory $current_memory = memory_get_usage( true ); $return = false; if ( $current_memory >= $memory_limit ) { $return = true; } return apply_filters( $this->identifier . '_memory_exceeded', $return ); } /** * Get memory limit in bytes. * * @return int */ protected function get_memory_limit() { if ( function_exists( 'ini_get' ) ) { $memory_limit = ini_get( 'memory_limit' ); } else { // Sensible default. $memory_limit = '128M'; } if ( ! $memory_limit || -1 === intval( $memory_limit ) ) { // Unlimited, set to 32GB. $memory_limit = '32000M'; } return wp_convert_hr_to_bytes( $memory_limit ); } /** * Time limit exceeded? * * Ensures the batch never exceeds a sensible time limit. * A timeout limit of 30s is common on shared hosting. * * @return bool */ protected function time_exceeded() { $finish = $this->start_time + apply_filters( $this->identifier . '_default_time_limit', 20 ); // 20 seconds $return = false; if ( time() >= $finish ) { $return = true; } return apply_filters( $this->identifier . '_time_exceeded', $return ); } /** * Complete processing. * * Override if applicable, but ensure that the below actions are * performed, or, call parent::complete(). */ protected function complete() { delete_site_option( $this->get_status_key() ); // Remove the cron healthcheck job from the cron schedule. $this->clear_scheduled_event(); $this->completed(); } /** * Called when background process has completed. */ protected function completed() { do_action( $this->identifier . '_completed' ); } /** * Get the cron healthcheck interval in minutes. * * Default is 5 minutes, minimum is 1 minute. * * @return int */ public function get_cron_interval() { $interval = 5; if ( property_exists( $this, 'cron_interval' ) ) { $interval = $this->cron_interval; } $interval = apply_filters( $this->cron_interval_identifier, $interval ); return is_int( $interval ) && 0 < $interval ? $interval : 5; } /** * Schedule the cron healthcheck job. * * @access public * * @param mixed $schedules Schedules. * * @return mixed */ public function schedule_cron_healthcheck( $schedules ) { $interval = $this->get_cron_interval(); if ( 1 === $interval ) { $display = __( 'Every Minute' ); } else { $display = sprintf( __( 'Every %d Minutes' ), $interval ); } // Adds an "Every NNN Minute(s)" schedule to the existing cron schedules. $schedules[ $this->cron_interval_identifier ] = array( 'interval' => MINUTE_IN_SECONDS * $interval, 'display' => $display, ); return $schedules; } /** * Handle cron healthcheck event. * * Restart the background process if not already running * and data exists in the queue. */ public function handle_cron_healthcheck() { if ( $this->is_processing() ) { // Background process already running. exit; } if ( $this->is_queue_empty() ) { // No data to process. $this->clear_scheduled_event(); exit; } $this->dispatch(); } /** * Schedule the cron healthcheck event. */ protected function schedule_event() { if ( ! wp_next_scheduled( $this->cron_hook_identifier ) ) { wp_schedule_event( time() + ( $this->get_cron_interval() * MINUTE_IN_SECONDS ), $this->cron_interval_identifier, $this->cron_hook_identifier ); } } /** * Clear scheduled cron healthcheck event. */ protected function clear_scheduled_event() { $timestamp = wp_next_scheduled( $this->cron_hook_identifier ); if ( $timestamp ) { wp_unschedule_event( $timestamp, $this->cron_hook_identifier ); } } /** * Cancel the background process. * * Stop processing queue items, clear cron job and delete batch. * * @deprecated 1.1.0 Superseded. * @see cancel() */ public function cancel_process() { $this->cancel(); } /** * Perform task with queued item. * * Override this method to perform any actions required on each * queue item. Return the modified item for further processing * in the next pass through. Or, return false to remove the * item from the queue. * * @param mixed $item Queue item to iterate over. * * @return mixed */ abstract protected function task( $item ); /** * Maybe unserialize data, but not if an object. * * @param mixed $data Data to be unserialized. * @param bool|array $allowed_classes Array of class UDX_names that can be unserialized. * * @return mixed */ protected static function maybe_unserialize( $data, $allowed_classes ) { if ( is_serialized( $data ) ) { $options = array(); if ( is_bool( $allowed_classes ) || is_array( $allowed_classes ) ) { $options['allowed_classes'] = $allowed_classes; } return @unserialize( $data, $options ); // @phpcs:ignore } return $data; } } ================================================ FILE: readme.md ================================================ # WordPress Stateless Media Plugin ## Description Upload and serve your WordPress media from Google Cloud Storage (GCS) with the WP-Stateless plugin. In as little as two minutes, you will be benefiting from serving your media from Google Cloud's distributed servers. New to Google Cloud? Google is offering you a [$300 credit](https://console.cloud.google.com/freetrial?referralId=e1c28cf728ff49b38d4eb5add3f5bfc8) to get you started. ### Benefits * Store and deliver media files on Google Cloud Storage instead of your server. * Google Cloud Storage is geo-redundant, meaning your media is delivered by the closest server - reducing latency and improving page speed. * Scale your WordPress website across multiple servers without the need for synchronizing media files. * Native integration between Google Cloud Storage and WordPress. * $300 free trial from Google Cloud. Nice! ### Modes * Backup - Upload media files to Google Storage and serve local file URLs. * CDN - Copy media files to Google Storage and serve them directly from there. * Ephemeral - Store and serve media files with Google Cloud Storage only. Media files are not stored locally, but local storage is used temporarily for processing and is required for certain compatibilities. * Stateless - Store and serve media files with Google Cloud Storage only. Media files are not stored locally. ### Features * Setup assistant makes getting started fast and easy. * No need to manually create service accounts or buckets - handled automatically. * Settings panel provides you with further GCS configuration and file URL customization. * Mask the default GCS URL with your own custom domain. * Automatically replace hardcoded media URLs with GCS equivalents in post editor and meta. * Batch image thumbnail regeneration. * Synchronization tools for uploading existing files and images. * All settings supported with wp-config constants and network setting overrides. * Multiple modes: Backup, CDN, Ephemeral, Stateless. * All files served in HTTPS mode. * Serverless platform compatible, including Google App Engine. * Multisite compatible. ### Addons * [Elementor Website Builder Addon](https://wordpress.org/plugins/wp-stateless-elementor-website-builder-addon/) * [Gravity Forms Addon](https://wordpress.org/plugins/wp-stateless-gravity-forms-addon/) * [Gravity Forms Signature Addon](https://wordpress.org/plugins/wp-stateless-gravity-forms-signature-addon/) * [WPForms Addon](https://wordpress.org/plugins/wp-stateless-wpforms-addon/) * [WooCommerce Addon](https://wordpress.org/plugins/wp-stateless-woocommerce-addon/) * [Easy Digital Downloads Addon](https://wordpress.org/plugins/wp-stateless-easy-digital-downloads-addon/) * [LiteSpeed Cache Addon](https://wordpress.org/plugins/wp-stateless-litespeed-cache-addon/) * [Divi Theme Addon](https://wordpress.org/plugins/wp-stateless-divi-theme-addon/) * [SiteOrigin CSS Addon](https://wordpress.org/plugins/wp-stateless-siteorigin-css-addon/) * [SiteOrigin Widgets Bundle Addon](https://wordpress.org/plugins/wp-stateless-siteorigin-widgets-bundle-addon/) * [BuddyPress Addon](https://wordpress.org/plugin/wp-stateless-buddypress-addon/) * [BuddyBoss Platform Addon](https://wordpress.org/plugins/wp-stateless-buddyboss-platform-addon/) * [Polylang Pro Addon](https://wordpress.org/plugins/wp-stateless-polylang-pro-addon/) * [Simple Local Avatars](https://wordpress.org/plugins/wp-stateless-simple-local-avatars-addon/) ### Support, Feedback, & Contribute We welcome community involvement via the [GitHub repository](https://github.com/udx/wp-stateless). ### Custom Development Looking for a unique feature for your next project? [Hire us!](https://udx.io/) ## Installation 1. Search, install, and activate the *WP-Stateless* plugin via your WordPress dashboard. 2. Begin WP-Stateless setup assistant at *Media > Stateless Setup* and click "Get Started Now." 3. Click "Google Login" and sign in with your Google account. 4. Set a Google Cloud Project, Google Cloud Storage Bucket, and Google Cloud Billing Account and click "Continue." 5. Installation and setup are now complete. Visit *Media > Stateless Settings* for more options. For a more detailed installation and setup walkthrough, please see the [manual setup instructions on Github](https://stateless.udx.io/setup/). ## Frequently Asked Questions ### What are the minimum server requirements for this plugin? Beyond the [official WordPress minimum requirements](https://codex.wordpress.org/Template:Server_requirements), WP-Stateless requires a minimum PHP version of 8.0 or higher and OpenSSL to be enabled. ### What wp-config constants are supported? For a complete list of supported wp-config constants, please consult the [GitHub documentation](https://stateless.udx.io/docs/constants/). ### How do I manually generate the Service Account JSON? The WP-Stateless setup assistant will create the Service Account JSON automatically for you, but you can follow these steps if you choose to create it manually. 1. Visit Google Cloud Console, and go to *IAM & Admin > Service accounts*. 2. Click *Create Service Account* and name it *wp-stateless*. 3. Set the role to *Storage > Storage Admin*. 4. Check *Furnish a new private key* and select *JSON* as the key type. 5. Open the JSON file and copy the contents into the *Service Account JSON* textarea within the WP-Stateless settings panel. ### Where can I submit feature requests or bug reports? We encourage community feedback and discussion through issues on the [GitHub repository](https://github.com/udx/wp-stateless/issues). ### Can I test new features before they are released? To ensure new releases cause as little disruption as possible, we rely on a number of early adopters who assist us by testing out new features before they are released. [Please contact us](https://udx.io/) if you are interested in becoming an early adopter. ### Who maintains this plugin? [UDX](https://udx.io/) maintains this plugin by continuing development through its own staff, reviewing pull requests, testing, and steering the overall release schedule. UDX is located in Durham, North Carolina, and provides WordPress engineering and hosting services to clients throughout the United States. ================================================ FILE: readme.txt ================================================ === WP-Stateless - Google Cloud Storage === Contributors: usability_dynamics, andypotanin, ideric, planvova, obolgun Donate link: https://udx.io Tags: google cloud, google cloud storage, cdn, uploads, backup License: GPLv2 or later Requires PHP: 8.1 Requires at least: 5.0 Tested up to: 6.9 Stable tag: 4.4.1 Upload and serve your WordPress media files from Google Cloud Storage. == Description == Upload and serve your WordPress media from Google Cloud Storage (GCS) with the WP-Stateless plugin. In as little as two minutes, you will be benefitting from serving your media from Google Cloud's distributed servers. New to Google Cloud? Google is offering you a [$300 credit](https://console.cloud.google.com/freetrial?referralId=e1c28cf728ff49b38d4eb5add3f5bfc8) to get you started. = Benefits = * Store and deliver media files on Google Cloud Storage instead of your server. * Google Cloud Storage is geo-redundant, meaning your media is delivered by the closest server - reducing latency and improving page speed. * Scale your WordPress website across multiple servers without the need of synchronizing media files. * Native integration between Google Cloud Storage and WordPress. * $300 free trial from Google Cloud. Nice! = Modes = * Backup - Upload media files to Google Storage and serve local file urls. * CDN - Copy media files to Google Storage and serve them directly from there. * Ephemeral - Store and serve media files with Google Cloud Storage only. Media files are not stored locally, but local storage is used temporarily for processing and is required for certain compatibilities. * Stateless - Store and serve media files with Google Cloud Storage only. Media files are not stored locally. = Features = * Setup assistant makes getting started fast and easy. * No need to manually create service accounts or buckets - handled automatically. * Settings panel provides you with further GCS configuration and file url customization. * Mask the default GCS URL with your own custom domain. * Automatically replace hardcoded media URLs with GCS equivalents in post editor and meta. * Batch image thumbnail regeneration. * Synchronization tools for uploading existing files and images. * All settings supported with wp-config constants and network setting overrides. * Multiple modes: Backup, CDN, Ephemeral, Stateless. * All files served in HTTPS mode. * Serverless platform compatible, including Google App Engine. * Multisite compatible. = Addons = * [Elementor Website Builder Addon](https://wordpress.org/plugins/wp-stateless-elementor-website-builder-addon/) * [Gravity Forms Addon](https://wordpress.org/plugins/wp-stateless-gravity-forms-addon/) * [Gravity Forms Signature Addon](https://wordpress.org/plugins/wp-stateless-gravity-forms-signature-addon/) * [WPForms Addon](https://wordpress.org/plugins/wp-stateless-wpforms-addon/) * [WooCommerce Addon](https://wordpress.org/plugins/wp-stateless-woocommerce-addon/) * [Easy Digital Downloads Addon](https://wordpress.org/plugins/wp-stateless-easy-digital-downloads-addon/) * [LiteSpeed Cache Addon](https://wordpress.org/plugins/wp-stateless-litespeed-cache-addon/) * [Divi Theme Addon](https://wordpress.org/plugins/wp-stateless-divi-theme-addon/) * [SiteOrigin CSS Addon](https://wordpress.org/plugins/wp-stateless-siteorigin-css-addon/) * [SiteOrigin Widgets Bundle Addon](https://wordpress.org/plugins/wp-stateless-siteorigin-widgets-bundle-addon/) * [BuddyPress Addon](https://wordpress.org/plugin/wp-stateless-buddypress-addon/) * [BuddyBoss Platform Addon](https://wordpress.org/plugins/wp-stateless-buddyboss-platform-addon/) * [Polylang Pro Addon](https://wordpress.org/plugins/wp-stateless-polylang-pro-addon/) * [Simple Local Avatars](https://wordpress.org/plugins/wp-stateless-simple-local-avatars-addon/) = Support, Feedback, & Contribute = We welcome community involvement via the [GitHub repository](https://github.com/udx/wp-stateless). = Custom Development = Looking for a unique feature for your next project? [Hire us!](https://udx.io/) == Installation == 1. Search, install, and activate the *WP-Stateless* plugin via your WordPress dashboard. 2. Begin WP-Stateless setup assistant at *Media > Stateless Setup* and click "Get Started Now." 3. Click "Google Login" and sign-in with your Google account. 4. Set a Google Cloud Project, Google Cloud Storage Bucket, and Google Cloud Billing Account and click "Continue." 5. Installation and setup is now complete. Visit *Media > Stateless Settings* for more options. For a more detailed installation and setup walkthrough, please see the [manual setup instructions on Github](https://stateless.udx.io/setup/). == Screenshots == 1. Settings Panel: Supports network setting and wp-config constant overrides. 2. Setup Assistant 3. Setup Assistant: Google Login 4. Setup Assistant: Approve Permissions 5. Setup Assistant: Project & Bucket 6. Setup Assistant: Complete 7. Edit Media: Image stored on Google Cloud Storage. == Frequently Asked Questions == = What are the minimum server requirements for this plugin? = Beyond the [official WordPress minimum requirements](https://wordpress.org/about/requirements/), WP-Stateless requires a minimum PHP version of 8.0 or higher and OpenSSL to be enabled. = What wp-config constants are supported? = For a complete list of supported wp-config constants, please consult the [GitHub documentation](https://stateless.udx.io/docs/constants/). = How do I manually generate the Service Account JSON? = The WP-Stateless setup assistant will create the Service Account JSON automatically for you, but you can follow these steps if you choose to create it manually. 1. Visit Google Cloud Console, and go to *IAM & Admin > Service accounts*. 2. Click *Create Service Account* and name it *wp-stateless*. 3. Set the role to *Storage > Storage Admin*. 4. Check *Furnish a new private key* and select *JSON* as the key type. 5. Open the JSON file and copy the contents into the *Service Account JSON* textarea within the WP-Stateless settings panel. = Where can I submit feature requests or bug reports? = We encourage community feedback and discussion through issues on the [GitHub repository](https://github.com/udx/wp-stateless/issues). = Can I test new features before they are released? = To ensure new releases cause as little disruption as possible, we rely on a number of early adopters who assist us by testing out new features before they are released. [Please contact us](https://udx.io/) if you are interested in becoming an early adopter. = Who maintains this plugin? = [UDX](https://udx.io/) maintains this plugin by continuing development through it's own staff, reviewing pull requests, testing, and steering the overall release schedule. UDX is located in Durham, North Carolina and provides WordPress engineering and hosting services to clients throughout the United States. == Upgrade Notice == = 4.1.0 = You will be prompted to run data optimization after upgrade. Please make a backup copy of your database. = 4.0.0 = You will be prompted to run data optimization after upgrade. Please make a backup copy of your database. If you using BuddyBoss Platform you will be proposed to install [WP-Stateless – BuddyBoss Platform Addon](https://wordpress.org/plugins/wp-stateless-buddyboss-platform-addon/), which replaces BuddyBoss Compatibility. If you using Elementor Website Builder you will be proposed to install [WP-Stateless – Elementor Website Builder Addon](https://wordpress.org/plugins/wp-stateless-elementor-website-builder-addon/), which replaces Elementor Compatibility. = 3.2.3 = Before upgrading to WP-Stateless 3.2.3, please, make sure you use PHP 8.0 or above. = 3.2.0 = Before upgrading to WP-Stateless 3.2.0, please, make sure you use PHP 7.2 or above. = 3.0 = Before upgrading to WP-Stateless 3.0, please, make sure you tested it on your development environment. == Changelog == = 4.4.1 - 2026-01-16 = * COMPATIBILITY - WooCommerce Extra Product Options Compatibility replaced with [WP-Stateless – WooCommerce Extra Product Options Addon](https://wordpress.org/plugins/wp-stateless-woocommerce-extra-product-options-addon/). * FIX - resolve critical errors with `firebase/php-jwt` library if `AUTH_SALT` WordPress constant is not set or too short. = 4.4.0 - 2026-01-10 = * NEW - plugin requires PHP 8.1+. * ENHANCEMENT - updated `firebase/php-jwt` library from 6.11.1 to 7.0.2. * ENHANCEMENT - Updated Client library for Google APIs from 2.18.3 to 2.19.0. * ENHANCEMENT - updated `wpmetabox/meta-box` library from 5.10.15 to 5.10.19. * ENHANCEMENT - updated `Meta Box Tabs` library from 1.1.18 to 1.2.0. * FIX - `udx/lib-wp-bootstrap` package correctly loads text domain to prevent PHP notices. = 4.3.0 = * ENHANCEMENT - update dependencies for Google APIs Client Library. * COMPATIBILITY - Simple Local Avatars Compatibility replaced with [WP-Stateless - Simple Local Avatars Addon](https://wordpress.org/plugins/wp-stateless-simple-local-avatars-addon/). = 4.2.1 = * ENHANCEMENT - updated `wpmetabox/meta-box` library from 5.10.11 to 5.10.15. * FIX - correctly loads text domain to prevent PHP notices. * FIX - `udx/lib-ud-api-client` package correctly loads text domain to prevent PHP notices. = 4.2.0 = * ENHANCEMENT - Updated Client library for Google APIs from 2.18.2 to 2.18.3. * ENHANCEMENT - updated `firebase/php-jwt` library from 6.10.2 to 6.11.1. * ENHANCEMENT - updated `wpmetabox/meta-box` library from 5.10.1 to 5.10.11. * DEPRECATED - Setup Assistant removed. = 4.1.3 = * COMPATIBILITY - PolyLang Compatibility replaced with [WP-Stateless – Polylang Pro Addon](https://wordpress.org/plugins/wp-stateless-polylang-pro-addon/). * ENHANCEMENT - updated `wpmetabox/meta-box` library from from 5.10.1 to 5.10.7. * ENHANCEMENT - updated `Meta Box Tabs` library from 1.1.18 to 1.2.0. * ENHANCEMENT - updated `firebase/php-jwt` library from from 6.10.1 to 6.10.2. * ENHANCEMENT - updated `wpmetabox/meta-box` library from from 5.10.1 to 5.10.2. * ENHANCEMENT - Updated Client library for Google APIs from 2.17.0 to 2.18.2. * FIX - apply `Cache Control` setting to all files (previously applied only to images). = 4.1.2 = * ENHANCEMENT - added `REST API Endpoint` setting, which useful when WordPress dashboard and frontend website utilize different domain names. * ENHANCEMENT - extended `Status Info` with the information to help diagnose REST API or AJAX issues. * COMPATIBILITY - SiteOrigin Widgets Bundle Compatibility replaced with [WP-Stateless - SiteOrigin Widgets Bundle Addon](https://wordpress.org/plugins/wp-stateless-siteorigin-widgets-bundle-addon/). * COMPATIBILITY - WPForms Compatibility replaced with [WP-Stateless - WPForms Addon](https://wordpress.org/plugins/wp-stateless-wpforms-addon/). * COMPATIBILITY - Easy Digital Downloads Compatibility replaced with [WP-Stateless - Easy Digital Downloads Addon](https://wordpress.org/plugins/wp-stateless-easy-digital-downloads-addon/). * COMPATIBILITY - LiteSpeed Cache Compatibility replaced with [WP-Stateless - LiteSpeed Cache Addon](https://wordpress.org/plugins/wp-stateless-litespeed-cache-addon/). * COMPATIBILITY - BuddyPress Compatibility replaced with [WP-Stateless - BuddyPress Addon](https://wordpress.org/plugin/wp-stateless-buddypress-addon/). * FIX: remove PHP warning on `Status` settings tab. * FIX: database updates to resolve conflicts with Polylang Pro compatibility. = 4.1.1 = * FIX - cache issues during Data Optimization. = 4.1.0 = * NEW - move compatibilities files from `wp_sm_sync` to `wp_stateless_files` table with extended information. * COMPATIBILITY - WooCommerce Compatibility replaced with [WP-Stateless – WooCommerce Addon](https://wordpress.org/plugins/wp-stateless-woocommerce-addon/). * COMPATIBILITY - Gravity Forms Compatibility replaced with [WP-Stateless – Gravity Forms Addon](https://wordpress.org/plugins/wp-stateless-gravity-forms-addon/). * COMPATIBILITY - Gravity Forms Signature Compatibility replaced with [WP-Stateless – Gravity Forms Signature Addon](https://wordpress.org/plugins/wp-stateless-gravity-forms-signature-addon/). * COMPATIBILITY - Divi Theme Compatibility replaced with [WP-Stateless – Divi Theme Addon](https://wordpress.org/plugins/wp-stateless-divi-theme-addon/). * COMPATIBILITY - SiteOrigin CSS Compatibility replaced with [WP-Stateless – SiteOrigin CSS Addon](https://wordpress.org/plugins/wp-stateless-siteorigin-css-addon/). * ENHANCEMENT - CLI command `wp stateless migrate` supports `auto` parameter to run all required Data Optimizations automatically. * ENHANCEMENT - Updated Client library for Google APIs from 2.15.1 to 2.17.0. * ENHANCEMENT - updated `firebase/php-jwt` library from from 6.9.0 to 6.10.1. * ENHANCEMENT - updated `wpmetabox/meta-box` library from from 5.8.2 to 5.10.1. * ENHANCEMENT - updated `deliciousbrains/wp-background-processing` library from from 1.1.1 to 1.3.1. * ENHANCEMENT - updated `composer/installers` library from from 1.12.1 to 2.3.0. * ENHANCEMENT - updated `Meta Box Tabs` library from 1.1.17 to 1.1.18. * ENHANCEMENT - action `sm:sync::addFile` format changed, now it passes media object instead of file name. * ENHANCEMENT - for installed Addons replace Download action with Activate. * ENHANCEMENT - count compatibility files from the DB instead of listing actual files to increase performance. * FIX - CLI command `wp stateless migrate` supports `--yes` parameter to skip confirmation. * FIX - CLI command `wp stateless migrate` correctly works with `--progress` parameter in multisite. * FIX - fixed synchronization for Compatibility files in Stateless Mode. * FIX - CLI command `wp stateless upgrade` fixed when running with `--b` switch. * FIX - fixed SiteOrigin Widgets Bundle Compatibility in `Stateless` mode. * FIX - fixed WPForms Compatibility in `Stateless` mode. * FIX - limit index size for compatibility with different DB engines [757](https://github.com/udx/wp-stateless/issues/757). * FIX - correctly disable `Cache-Busting` setting for Ephemeral Mode [758](https://github.com/udx/wp-stateless/issues/758), credits [@Jessedev1](https://github.com/Jessedev1). * FIX - Data Optimization UI adjustments. = 4.0.4 = * ENHANCEMENT - display success message after copying Status Info. * FIX - `Settings` page does not open or slow when there is big amount of attachments. * FIX - in multisite network, removing custom tables properly when deleting site. * FIX - skip setting ACL in Stateless mode and during Sync for the buckets with Uniform access, support WP_STATELESS_SKIP_ACL_SET constant [#712](https://github.com/udx/wp-stateless/issues/712). = 4.0.3 = * NEW - added `Info` section to the `Status` tab on the Settings page, which contains the system info and the ability to copy report to clipboard. * ENHANCEMENT - added `Documentation` link on the Plugins page. * ENHANCEMENT - added `Addons` link on the Plugins page. * ENHANCEMENT - added `Documentation` link on the Settings page. * FIX - fixed `Settings` shortcut on the Plugins page. * FIX - in multisite network, do not show Data Optimization on the Network Admin Page. * FIX - properly set `Content Disposition` fields for media objects. * FIX - properly use `Cache Control` setting for media objects. * FIX - fixed `Creation of dynamic property` PHP deprecation notice. * FIX - fixed `Cannot use ::class with dynamic class name` PHP warning. * FIX - avoid PHP warning when unable to get file path in `Stateless` mode [728](https://github.com/udx/wp-stateless/issues/728). * FIX - fixed links to the constants documentation. = 4.0.2 = * FIX - in multisite network, deleting site can potentially remove WP-Stateless tables from another site. * COMPATIBILITY - Gravity Forms Compatibility updated for the newest Gravity Forms version. = 4.0.1 = * FIX - improvements to Data Optimization process. * FIX - Data Optimization fixed for multisite environment. = 4.0.0 = * NEW - use custom database tables to store GCS file data. This increases plugin performance and will be used for future improvements. * NEW - added filter `wp_stateless_get_file`, retrieves the GCS file data, should be used instead of getting `sm_cloud` postmeta directly. * NEW - added filter `wp_stateless_get_file_sizes`, retrieves the GCS file data for image sizes, should be used instead of getting `sm_cloud` postmeta directly. * NEW - added filter `wp_stateless_get_file_meta`, retrieves all GCS file meta data, should be used instead of getting `sm_cloud` postmeta directly. * NEW - added filter `wp_stateless_get_file_meta_value`, retrieves the GCS file meta data by meta_key, should be used instead of getting `sm_cloud` postmeta directly. * NEW - added filter `wp_stateless_get_setting_...` which allows to override any WP-Stateless setting. * NEW - added setting "Send Status Emails" allowing to change email for WP-Stateless notifications. * NEW - added setting "Use Post Meta" allowing to switch back to using `postmeta` instead of custom DB tables. Can be used in case of issues after upgrading to 4.0.0. * NEW - added new Settings tab `Addons`, which contains the list of WP-Stateless Addons, which replace Compatibilities. * NEW - added new Settings tab `Status`, which contains status and health information related to Google Cloud Storage and WP-Stateless. * NEW - CLI command `wp stateless migrate` to list and operate data optimizations. * NEW - configuration constant [`WP_STATELESS_POSTMETA`](https://stateless.udx.io/docs/constants/#wp_stateless_postmeta) allows to read the GCS file data from postmeta instead of the new custom database tables. * NEW - configuration constant [`WP_STATELESS_BATCH_HEALTHCHECK_INTERVAL`](https://stateless.udx.io/docs/constants/#wp_stateless_batch_healthcheck_interval) defines an interval in minutes for periodical health checks of a batch background process (like data optimization). * COMPATIBILITY - BuddyBoss Compatibility replaced with [WP-Stateless – BuddyBoss Platform Addon](https://wordpress.org/plugins/wp-stateless-buddyboss-platform-addon/). * COMPATIBILITY - Elementor Compatibility replaced with [WP-Stateless – Elementor Website Builder Addon](https://wordpress.org/plugins/wp-stateless-elementor-website-builder-addon/). * COMPATIBILITY - Gravity Form Compatibility does not support older version of Gravity Forms (< 2.3). * ENHANCEMENT - Allow dismissing notices in Admin Panel only for logged in users. * ENHANCEMENT - Updated `wp-background-processing` library from from 1.0.2 to 1.1.1. * ENHANCEMENT - Updated `phpseclib` 3.0.34 to 3.0.37. * FIX - proper use of infinite timeout in `set_time_limit` function to avoid issues with PHP 8.1 and above [#704](https://github.com/udx/wp-stateless/issues/704). = 3.4.1 = * FIX - improve security while processing AJAX requests in Admin Panel = 3.4.0 = * ENHANCEMENT - removed `udx/lib-settings` package dependency for security reasons. * ENHANCEMENT - removed `udx/lib-utility` package dependency for security reasons. * ENHANCEMENT - refactored `Settings` admin page to remove Angular dependency. * ENHANCEMENT - including Software Bill of Materials (SBOM) to GitHub release. * FIX - updated package dependencies for Google Client Library for security reasons. * FIX - replaced `utf8_encode` with `mb_convert_encoding` to support PHP 8.2 and above [#678](https://github.com/udx/wp-stateless/issues/678). * FIX - Fatal Error in `Stateless` mode if GCP access credentials are wrong [#693](https://github.com/udx/wp-stateless/issues/693). * COMPATIBILITY - preventing PHP warnings while working with WooCommerce version 8.4.0 and above [696](https://github.com/udx/wp-stateless/issues/696). * COMPATIBILITY - avoiding conflicts between builtin compatibilities and WP-Stateless Addon plugins. = 3.3.0 = * NEW - Added new filter `wp_stateless_attachment_url`. Allows to customize attachment URL after WP-Stateless generates it based on it's internal conditions. * FIX - Stateless mode Incompatible with Media Uploader in Media Library Grid mode [#675](https://github.com/udx/wp-stateless/issues/675). * FIX - Prevent duplicating messages in Admin Panel. * COMPATIBILITY - Dynamic Image Support is now part of the core. * COMPATIBILITY - Google App Engine is now part of the core. Automatically enables **Stateless** mode when Google App Engine detected. Can be disabled using `WP_STATELESS_COMPATIBILITY_GAE` constant. * COMPATIBILITY - Removed compatibility with "Advanced Custom Fields: Image Crop Add-on", because plugin is deprecated. * COMPATIBILITY - Removed compatibility with "VidoRev" plugin. * COMPATIBILITY - Removed compatibility with "WP Retina 2x" plugin. * ENHANCEMENT - Updated Client library for Google APIs from 2.15.0 to 2.15.1. * ENHANCEMENT - Updated Meta Box library from 5.6.3 to 5.8.2. * ENHANCEMENT - Updated Meta Box Tabs to version 1.1.17. * ENHANCEMENT - Updated PHP JWT library from 6.6.0 to 6.9.0. = 3.2.5 = * FIX - Folder setting does not allow custom structure [#608](https://github.com/udx/wp-stateless/issues/608). * FIX - Stateless mode Incompatible with Inline Uploader [#675](https://github.com/udx/wp-stateless/issues/675). * FIX - html tags incorrectly applied in notice [#680](https://github.com/udx/wp-stateless/issues/680). * ENHANCEMENT - Add WP_STATELESS_SKIP_ACL_SET for skip ACL set for GCS [#625](https://github.com/udx/wp-stateless/issues/625). * COMPATIBILITY - Add support for The Events Calendar [#599](https://github.com/udx/wp-stateless/issues/599). = 3.2.4 = * FIX - Website unresponsive after Upgrade [#669](https://github.com/udx/wp-stateless/issues/669). = 3.2.3 = * **WP-Stateless 3.2.3 requires PHP 8.0+. Recently, Google updated the official Google API PHP Client Library used by WP-Stateless to resolve security issues. This updated library requires PHP 8.0.** * ENHANCEMENT - Updated Client library for Google APIs. * ENHANCEMENT - Updated Monolog library to version 3. * ENHANCEMENT - Updated JWT library. * FIX - Fixed vulnerability issues. * FIX - Fixed an errors and warnings on PHP 8.1. * FIX - Fixed an error that occured when WP_STATELESS_MEDIA_UPLOAD_CHUNK_SIZE is set. = 3.2.2 = * FIX - Folder setting can't be saved from the settings page [#639](https://github.com/udx/wp-stateless/issues/639). = 3.2.1 = * FIX - Updated requirments. * FIX - WP-Stateless 3.2.0 doesn’t upload docs, only images [#638](https://github.com/udx/wp-stateless/issues/638). = 3.2.0 = * **Before upgrading to WP-Stateless 3.2.0, please, make sure you tested it on your development environment. It may have breaking changes.** * ENHANCEMENT - Upgraded `wpmetabox` library. * ENHANCEMENT - Updated Client library for Google APIs. * ENHANCEMENT - Updated Guzzle library to version 7. * ENHANCEMENT - Updated JWT library. * ENHANCEMENT - Updated `license` functionality, removed `update checker`. * FIX - Fixed vulnerability issues. * FIX - Fixed erros and warnings on PHP 8. * FIX - problem after the upgrade [#628](https://github.com/udx/wp-stateless/issues/628). * FIX - image_downsize() PHP8 Required parameter $id follows optional parameter $false [#619](https://github.com/udx/wp-stateless/issues/619). = 3.1.1 = * ENHANCEMENT - Notification for the administrator about finished synchronization. GitHub issue [#576](https://github.com/udx/wp-stateless/issues/576). * FIX - Fixed an issue with PDF thumbnails. GitHub issue [#577](https://github.com/udx/wp-stateless/issues/577). * FIX - Fixed an issue with synchronization in `Stateless` mode. GitHub issue [#575](https://github.com/udx/wp-stateless/issues/575). * COMPATIBILITY - Changed the way compatibility files are stored on Multisite. GitHub issue [#588](https://github.com/udx/wp-stateless/issues/588). = 3.1.0 = * NEW - Completely rewritten the synchronization tool. GitHub issue [#523](https://github.com/udx/wp-stateless/issues/523). * NEW - New configuration constant `WP_STATELESS_SYNC_MAX_BATCH_SIZE`. Sets the maximum size of a background sync batch of items to be saved in a single row in the database. [More details](https://stateless.udx.io/docs/constants/#wp_stateless_sync_max_batch_size). * NEW - New configuration constant `WP_STATELESS_SYNC_LOG`. Sets a path to a log file where to output logging information during the background sync. [More details](https://stateless.udx.io/docs/constants/#wp_stateless_sync_log). * NEW - New configuration constant `WP_STATELESS_SYNC_HEALTHCHECK_INTERVAL`. Defines an interval in minutes for a cron task that periodically checks the health of a particular background sync process. [More details](https://stateless.udx.io/docs/constants/#wp_stateless_sync_healthcheck_interval). * FIX - Fixed an issue when original files were not deleted from the server in the Ephemeral mode. GitHub issue [#484](https://github.com/udx/wp-stateless/issues/484). * FIX - Fixed an incorrect behavior of image `srcset` attribute in the Backup mode. GitHub issue [#558](https://github.com/udx/wp-stateless/issues/558). * COMPATIBILITY - Litespeed Cache - Fixed an incorrect upload folder determination. GitHub issue [#527](https://github.com/udx/wp-stateless/issues/527). = 3.0.4 = * FIX - Fixed inability to use dashes in the upload folder name. GitHub issue [#565](https://github.com/udx/wp-stateless/issues/565). * COMPATIBILITY - Elementor - Fixed wrong upload directory. GitHub issue [#560](https://github.com/udx/wp-stateless/issues/560). = 3.0.3 = * FIX - Fixed an incorrect file URL in Stateless mode on Edit Media screen. GitHub issue [#544](https://github.com/udx/wp-stateless/issues/544). = 3.0.2 = * FIX - Refactored the way files are being uploaded to GCS when `WP_STATELESS_MEDIA_UPLOAD_CHUNK_SIZE` constant is defined. GitHub issue [#553](https://github.com/udx/wp-stateless/issues/553). * FIX - Fixed the process of upgrading to 3.0 for multisite installations. GitHub issue [#549](https://github.com/udx/wp-stateless/issues/549). = 3.0.1 = * FIX - Fatal Error in Stateless mode. GitHub issue [#546](https://github.com/udx/wp-stateless/issues/546). = 3.0 = * **Before upgrading to WP-Stateless 3.0, please, make sure you tested it on your development environment. It may have breaking changes.** * NEW - Setup assistant rewrite. GitHub issue [#477](https://github.com/udx/wp-stateless/issues/477). * NEW - Recreate attachment metabox panel using metabox.io. GitHub issue [#470](https://github.com/udx/wp-stateless/issues/470). * NEW - Updated the `Stateless` mode to not use local storage at all. Current `Stateless` mode setting mapped to new `Ephemeral` mode. GitHub issue [#482](https://github.com/udx/wp-stateless/issues/482). * NEW - Files are now uploaded to GCS in chunks and chunk size will be determined based on free memory available. GitHub issue [#478](https://github.com/udx/wp-stateless/issues/478). * NEW - File upload chunk size can be controlled with `WP_STATELESS_MEDIA_UPLOAD_CHUNK_SIZE` constant. GitHub issue [#478](https://github.com/udx/wp-stateless/issues/478). * FIX - Changed the default value for the Cache-Busting setting. GitHub issue [#361](https://github.com/udx/wp-stateless/issues/361). * FIX - Fixed network override of Cache-Busting. GitHub issue [#468](https://github.com/udx/wp-stateless/issues/468). * FIX - Fixed "Passing glue string after array is deprecated.". GitHub issue [#444](https://github.com/udx/wp-stateless/issues/444). * FIX - Fixed Compatibility default value in multisite. GitHub issue [#464](https://github.com/udx/wp-stateless/issues/464). * FIX - Fixed multisite wrong GCS path. GitHub issue [#407](https://github.com/udx/wp-stateless/issues/407). * FIX - Don't check for Google Cloud Storage connectivity in stateless mode unless uploading. GitHub issue [#442](https://github.com/udx/wp-stateless/issues/442). * COMPATIBILITY - Google App Engine - Added new compatibility support for Google App Engine. [#486](https://github.com/udx/wp-stateless/issues/486) * COMPATIBILITY - Elementor - Fixed wrong MIME type for CSS files. GitHub issue [#395](https://github.com/udx/wp-stateless/issues/395). * COMPATIBILITY - Polylang - Fixed missing metadata issue. GitHub issue [#378](https://github.com/udx/wp-stateless/issues/378). * COMPATIBILITY - EWWW - Fixed mime type for WEBP images. GitHub issue [#371](https://github.com/udx/wp-stateless/issues/371). * COMPATIBILITY - Simple Local Avatars - Added new compatibility support for Simple Local Avatars. GitHub issue [#297](https://github.com/udx/wp-stateless/issues/297). * COMPATIBILITY - BuddyPress - Fixed BuddyPress compatibility. GitHub issue [#275](https://github.com/udx/wp-stateless/issues/275). * COMPATIBILITY - Divi - Fixed Divi cache issue. GitHub issue [#430](https://github.com/udx/wp-stateless/issues/430). * COMPATIBILITY - Gravity Forms - add compatibility for Gravity Forms Signature Add-On. [#501](https://github.com/udx/wp-stateless/issues/501). * COMPATIBILITY - Litespeed - Fixed fatal error and warnings. [#491](https://github.com/udx/wp-stateless/issues/491). * COMPATIBILITY - Imagify - Added support for webp. [#403](https://github.com/udx/wp-stateless/issues/403). * ENHANCEMENT - Update Client library for Google APIs. [#446](https://github.com/udx/wp-stateless/issues/446). * ENHANCEMENT - Wildcards for bucket folder settings. GitHub issue [#149](https://github.com/udx/wp-stateless/issues/149). * ENHANCEMENT - Better CLI integration. GitHub issue [#447](https://github.com/udx/wp-stateless/issues/447), [#450](https://github.com/udx/wp-stateless/issues/450) and [#451](https://github.com/udx/wp-stateless/issues/451). * ENHANCEMENT - Sync media according to new Bucket Folder settings. GitHub issue [#449](https://github.com/udx/wp-stateless/issues/449). * ENHANCEMENT - Moved Bucket Folder setting in the File URL section. GitHub issue [#463](https://github.com/udx/wp-stateless/issues/463). * ENHANCEMENT - Hide Regenerate and Sync with GCS when the mode is Disabled. GitHub issue [#440](https://github.com/udx/wp-stateless/issues/440). * ENHANCEMENT - New endpoint for the Google Cloud Storage JSON API. GitHub issue [#384](https://github.com/udx/wp-stateless/issues/384). * ENHANCEMENT - Renamed current `Stateless` mode to `Ephemeral`. GitHub issue [#481](https://github.com/udx/wp-stateless/issues/481). = 2.3.2 = * FIX - Fixed video file doesn't get deleted from the server in `Stateless` mode. GitHub issue [#418](https://github.com/udx/wp-stateless/issues/418). * FIX - Fixed file size doesn't show under attachment details in `Stateless` mode. GitHub issue [#413](https://github.com/udx/wp-stateless/issues/413). * FIX - Fixed Cache-Busting feature works even if the Mode is `Disabled`. GitHub issue [#405](https://github.com/udx/wp-stateless/issues/405). * COMPATIBILITY - Fixed Gravity Form Post Image didn't include `Bucket Folder`. GitHub issue [#421](https://github.com/udx/wp-stateless/issues/421). * COMPATIBILITY - Fixed Divi Builder Export. GitHub issue [#420](https://github.com/udx/wp-stateless/issues/420). * COMPATIBILITY - Fixed BuddyBoss pages breaking after updating to 2.3.0. GitHub issue [#417](https://github.com/udx/wp-stateless/issues/417). = 2.3.1 = * Fix - Fixed fatal error, undefined function `is_wp_version_compatible`. GitHub issue [#414](https://github.com/udx/wp-stateless/issues/414). = 2.3.0 = * FIX - Fixed problem with WordPress 5.3. GitHub issue [#406](https://github.com/udx/wp-stateless/issues/406). * FIX - Fixed problem with the Cache Busting feature. GitHub issue [#377](https://github.com/udx/wp-stateless/issues/377). * COMPATIBILITY - Added compatibility support for WP Retina 2x pro. GitHub issue [#380](https://github.com/udx/wp-stateless/issues/380). * COMPATIBILITY - Enhanced compatibility support for LiteSpeed Cache. GitHub issue [#365](https://github.com/udx/wp-stateless/issues/365). * COMPATIBILITY - Enhanced compatibility support for ShortPixel Image Optimizer. GitHub issue [#364](https://github.com/udx/wp-stateless/issues/364), [#398](https://github.com/udx/wp-stateless/issues/398). * COMPATIBILITY - Fixed Gravity Form export. GitHub issue [#408](https://github.com/udx/wp-stateless/issues/408). * ENHANCEMENT - Improved upon add_media function for better compatibility support. GitHub issue [#382](https://github.com/udx/wp-stateless/issues/382). = 2.2.7 = * FIX - WP-Smush compatibility enhanced. GitHub Issue [#366](https://github.com/udx/wp-stateless/issues/366). * FIX - Fixed multisite installation support. GitHub Issue [#370](https://github.com/udx/wp-stateless/issues/370). * FIX - Fixed settings UI problems related to Cache-Busting option. GitHub Issue [#373](https://github.com/udx/wp-stateless/issues/373). * FIX - Other minor fixes. = 2.2.6 = * FIX - Multisite Network Settings page fixed. GitHub Issue [#369](https://github.com/udx/wp-stateless/issues/369). * FIX - Fixed incorrect Compatibilities behavior when Bucket Folder is set. GitHub Issue [#368](https://github.com/udx/wp-stateless/issues/368). * FIX - Other minor fixes. = 2.2.5 = * NEW - Added ability to start sync process from specific Attachment ID. GitHub Issue [#360](https://github.com/udx/wp-stateless/issues/360). * COMPATIBILITY - Added compatibility support for LiteSpeed Cache plugin. Especially to support optimized .webp images. GitHub Issue [#357](https://github.com/udx/wp-stateless/issues/357). * FIX - Other minor fixes. = Earlier versions = Please refer to the separate changelog.txt file. ================================================ FILE: static/data/addons.php ================================================ [ // ID of the addon is a slug for Addon page on https://stateless.udx.io/addons/ * 'title' => 'BuddyPress', * 'plugin_files' => ['buddypress/bp-loader.php'], // if this is a plugin Addon * 'theme_name' => 'Divi', // if this is a theme Addon * 'addon_file' => 'wp-stateless-buddypress-addon/wp-stateless-buddypress-addon.php', // Addon plugin main file (to check it's presence and activation) * 'icon' => 'https://ps.w.org/wp-stateless/assets/icon.svg', // icon URL * 'repo' => 'udx/wp-stateless-buddyboss-addon', // (optional) link to GitHub * 'wp' => 'https://wordpress.org/plugins/wp-stateless-buddyboss-addon/', // (optional) link to WordPress.org plugin page * 'hubspot_id' => '123456789', // (optional) HubSpot ID for Download button * 'hubspot_link' => 'https://cta-service-cms2.hubspot.com/web-interactives/...', // (optional) HubSpot link for Download button * ], * * ID of the addon is a slug for Addon page on https://stateless.udx.io/addons/ */ return [ 'buddyboss' => [ 'title' => 'BuddyBoss Platform', 'plugin_files' => ['buddyboss-platform/bp-loader.php'], 'addon_file' => 'wp-stateless-buddyboss-platform-addon/wp-stateless-buddyboss-addon.php', 'icon' => 'https://www.buddyboss.com/wp-content/uploads/2022/04/bb-logo-1.png', 'repo' => 'udx/wp-stateless-buddyboss-addon', 'wp' => 'https://wordpress.org/plugins/wp-stateless-buddyboss-platform-addon/', 'hubspot_id' => '151481399845', // 'hubspot_link' => 'https://cta-service-cms2.hubspot.com/web-interactives/public/v1/track/click?encryptedPayload=AVxigLIz%2BcFUMcIBKQ7Xqj0pOF0COKC9I0GezkxwgHqPgiPgyfhisc6veCbNsRloVLAajjD9D%2ByVhIPRFdsFfxJbmC96vdcpZbFUIqn%2F2qS7eXcpXHENalnSIMHrRy3vZ25OujO7MQ8WgbQMNJlTJJ9N0%2FyC6UbEjKMWdWjvjXnAPRh5giepyw2JtqMqgupq85f5rhzgYJgXJKOAzaOwja%2Bedw%3D%3D&portalId=20504491', ], 'elementor' => [ 'title' => 'Elementor Website Builder', 'plugin_files' => ['elementor/elementor.php'], 'addon_file' => 'wp-stateless-elementor-website-builder-addon/wp-stateless-elementor-addon.php', 'icon' => 'https://ps.w.org/elementor/assets/icon-128x128.gif', 'repo' => 'udx/wp-stateless-elementor-website-builder-addon', 'wp' => 'https://wordpress.org/plugins/wp-stateless-elementor-website-builder-addon/', 'hubspot_id' => '151481399819', // 'hubspot_link' => 'https://cta-service-cms2.hubspot.com/web-interactives/public/v1/track/click?encryptedPayload=AVxigLKR8B2Z9422V%2Fh9SGpptZeq1UWUETejTC8i1C7YoBj8TRWSG2Yij36fQHaj37NIgIU0OgWeZ9SAaTb9lL%2BlPaEKwWJ1WcQNWv%2FLFWh1Y8LTEIUGRvPzShNKyv0yIC5Z3Hu6YWGYp46iXXI6nLLBfbt2fHytn3mHX7Ic3%2ByuAF3Cz2rmMusOMD3XSJGTAYobOOXuyHJzeHzztZAimflHRg%3D%3D&portalId=20504491', ], 'woocommerce' => [ 'title' => 'WooCommerce', 'plugin_files' => ['woocommerce/woocommerce.php'], 'addon_file' => 'wp-stateless-woocommerce-addon/wp-stateless-woocommerce-addon.php', 'icon' => 'https://ps.w.org/woocommerce/assets/icon.svg', 'repo' => 'udx/wp-stateless-woocommerce-addon', 'wp' => 'https://wordpress.org/plugins/wp-stateless-woocommerce-addon/', 'hubspot_id' => '151478251047', // 'hubspot_link' => 'https://cta-service-cms2.hubspot.com/web-interactives/public/v1/track/click?encryptedPayload=AVxigLKJr1PcJ%2BBZGWmWGTx%2Bc7Sh4FacNlnvMTTQNjX%2BUmtx5f1v6gkfcoZGfadciwzLMdGM0sFedlfakugWH%2FdNwCHb4nNp4YBkN0R4jfQIC8RM6ksptsyoPhr2Ws0%2BMkaYVtUkujGU99Pu8r1LBsLY1UJ5vWPU5k5pOEoNGDrw8Y%2FsUwi7oiF5ws2lHdL53NqfZZ7wrybTx7J5ZBpn7ZYiSLWE&portalId=20504491', ], 'gravity-forms' => [ 'title' => 'Gravity Forms', 'plugin_files' => ['gravityforms/gravityforms.php'], 'addon_file' => 'wp-stateless-gravity-forms-addon/wp-stateless-gravity-forms-addon.php', 'icon' => 'https://cdn2.hubspot.net/hub/4148022/hubfs/Artboard%20Copy%2011.png', 'repo' => 'udx/wp-stateless-gravity-forms-addon', 'wp' => 'https://wordpress.org/plugins/wp-stateless-gravity-forms-addon/', 'hubspot_id' => '151481399808', // 'hubspot_link' => 'https://cta-service-cms2.hubspot.com/web-interactives/public/v1/track/click?encryptedPayload=AVxigLJ2A%2FS%2FrBjbH%2B2zEjfR3T%2B1mWtJnXEtorbr5Olt8GrxTFwKcTV490FD%2F%2FywcQ4Yp944qIl%2FI1BcwoIIsFaYC1Z5v8FygDdJrSd%2FeqTr3jQ2I0tVfJaErezy9f%2BRdTPLQClqa28wG%2FNPQu%2F%2ByD08wtdQhaZMTW7s%2FCwLYFl9RLFqXcc4gW2vCI20%2Bx9NxFAVkMeqRN18USGE7M5iwl8AoOwI1tA%3D&portalId=20504491', ], 'gravity-forms-signature' => [ 'title' => 'Gravity Forms Signature', 'plugin_files' => ['gravityformssignature/signature.php'], 'addon_file' => 'wp-stateless-gravity-forms-signature-addon/wp-stateless-gravity-forms-signature-addon.php', 'icon' => 'https://cdn2.hubspot.net/hub/4148022/hubfs/Artboard%20Copy%2011.png', 'repo' => 'udx/wp-stateless-gravity-forms-signature-addon', 'wp' => 'https://wordpress.org/plugins/wp-stateless-gravity-forms-signature-addon/', 'hubspot_id' => '151481399724', // 'hubspot_link' => 'https://cta-service-cms2.hubspot.com/web-interactives/public/v1/track/click?encryptedPayload=AVxigLLr66o8tFz1owH%2F8niAXobMUrxwU7SenenLgUzTIQiYLyvaqx%2FBVmvE60MJI3oMg%2BKtMZzfMsvk6Uedvxv1E2mUg7VwJtc9DxdcCgS8uJh58x6fiXwdUPNDkeKlLWeoNtvEj7zhNdDrsJf6kEo6t7vIFpF7aT2%2F8N3RGUCmwUBDRMDt6t7Fdko0LUhAnePm4PAby7S3kmVUZ0POP0bwh%2BjJXTL6eRK4VsTdvaDZ&portalId=20504491', ], 'divi' => [ 'title' => 'Divi Theme', 'theme_name' => 'Divi', 'addon_file' => 'wp-stateless-divi-theme-addon/wp-stateless-divi-theme-addon.php', 'icon' => 'https://www.elegantthemes.com/images/favicon/favicon-divi-128.png', 'repo' => 'udx/wp-stateless-divi-theme-addon', 'wp' => 'https://wordpress.org/plugins/wp-stateless-divi-theme-addon/', 'hubspot_id' => '151478250935', // 'hubspot_link' => 'https://cta-service-cms2.hubspot.com/web-interactives/public/v1/track/click?encryptedPayload=AVxigLKBdXT3iKKssnyU5oSlJCOfudt7i6nV%2F5ojUf63FZt1MjnlQ%2BEP2JTU9DfhHfCCMUS9eZkfBezgAUKkinw0pOw0yKUWSYGw89SIF9OyVci07g94GTyYx0j17tt3LC7jZ34Nhe4GfQQHXvkad%2FNNTRoumwcNoV5csmLHPEnEwq7XWsYPSN73GTzxEwySOMWBk%2FTt%2BROYZDCM3Ks%3D&portalId=20504491', ], 'siteorigin-css' => [ 'title' => 'SiteOrigin CSS', 'plugin_files' => ['so-css/so-css.php'], 'addon_file' => 'wp-stateless-siteorigin-css-addon/wp-stateless-siteorigin-css-addon.php', 'icon' => 'https://ps.w.org/so-css/assets/icon.svg', 'repo' => 'udx/wp-stateless-siteorigin-css-addon', 'wp' => 'https://wordpress.org/plugins/wp-stateless-siteorigin-css-addon/', 'hubspot_id' => '151480507684', ], 'siteorigin-widgets-bundle' => [ 'title' => 'SiteOrigin Widgets Bundle', 'plugin_files' => ['so-widgets-bundle/so-widgets-bundle.php'], 'addon_file' => 'wp-stateless-siteorigin-widgets-bundle-addon/wp-stateless-siteorigin-widgets-bundle-addon.php', 'icon' => 'https://ps.w.org/so-widgets-bundle/assets/icon.svg', 'repo' => 'udx/wp-stateless-siteorigin-widgets-bundle-addon', 'wp' => 'https://wordpress.org/plugins/wp-stateless-siteorigin-widgets-bundle-addon/', 'hubspot_id' => '151480507657', ], 'wpforms' => [ 'title' => 'WPForms', 'plugin_files' => ['wpforms-lite/wpforms.php', 'wpforms/wpforms.php'], 'addon_file' => 'wp-stateless-wpforms-addon/wp-stateless-wpforms-addon.php', 'icon' => 'https://ps.w.org/wpforms-lite/assets/icon.svg', 'repo' => 'udx/wp-stateless-wpforms-addon', 'wp' => 'https://wordpress.org/plugins/wp-stateless-wpforms-addon/', 'hubspot_id' => '151481399840', ], 'edd' => [ 'title' => 'Easy Digital Downloads', 'plugin_files' => ['easy-digital-downloads/easy-digital-downloads.php'], 'addon_file' => 'wp-stateless-easy-digital-downloads-addon/wp-stateless-easy-digital-downloads-addon.php', 'icon' => 'https://ps.w.org/easy-digital-downloads/assets/icon.svg', 'repo' => 'udx/wp-stateless-easy-digital-downloads-addon', 'wp' => 'https://wordpress.org/plugins/wp-stateless-easy-digital-downloads-addon/', 'hubspot_id' => '151481399833', ], 'lite-speed-cache' => [ 'title' => 'LiteSpeed Cache', 'plugin_files' => ['litespeed-cache/litespeed-cache.php'], 'addon_file' => 'wp-stateless-litespeed-cache-addon/wp-stateless-litespeed-cache-addon.php', 'icon' => 'https://ps.w.org/litespeed-cache/assets/icon-128x128.png', 'repo' => 'udx/wp-stateless-litespeed-cache-addon', 'wp' => 'https://wordpress.org/plugins/wp-stateless-litespeed-cache-addon/', 'hubspot_id' => '151480507763', ], 'buddypress' => [ 'title' => 'BuddyPress', 'plugin_files' => ['buddypress/bp-loader.php'], 'addon_file' => 'wp-stateless-buddypress-addon/wp-stateless-buddypress-addon.php', 'icon' => 'https://ps.w.org/buddypress/assets/icon.svg', 'repo' => 'udx/wp-stateless-buddypress-addon', 'wp' => 'https://wordpress.org/plugin/wp-stateless-buddypress-addon/', 'hubspot_id' => '151478250924', ], 'polylang' => [ 'title' => 'PolyLang Pro', 'plugin_files' => ['polylang-pro/polylang.php'], 'addon_file' => 'wp-stateless-polylang-pro-addon/wp-stateless-polylang-pro-addon.php', 'icon' => 'https://ps.w.org/buddypress/assets/icon.svg', 'repo' => 'udx/wp-stateless-polylang-pro-addon', 'wp' => 'https://wordpress.org/plugins/wp-stateless-polylang-pro-addon/', 'hubspot_id' => '151478250876', ], 'simple-local-avatars' => [ 'title' => 'Simple Local Avatars', 'plugin_files' => ['simple-local-avatars/simple-local-avatars.php'], 'addon_file' => 'wp-stateless-simple-local-avatars-addon/wp-stateless-simple-local-avatars-addon.php', 'icon' => 'https://ps.w.org/simple-local-avatars/assets/icon.svg', 'repo' => 'udx/wp-stateless-simple-local-avatars-addon', 'wp' => 'https://wordpress.org/plugins/wp-stateless-simple-local-avatars-addon/', 'hubspot_id' => '151480507697', ], 'woo-extra-product-options' => [ 'title' => 'WooCommerce Extra Product Options Addon', 'plugin_files' => ['woocommerce-tm-extra-product-options/tm-woo-extra-product-options.php'], 'addon_file' => 'wp-stateless-woocommerce-extra-product-options-addon/wp-stateless-woo-extra-product-options-addon.php.php', 'icon' => 'https://ps.w.org/woocommerce/assets/icon.svg', 'repo' => 'udx/wp-stateless-woo-extra-product-options-addon', 'wp' => 'https://wordpress.org/plugins/wp-stateless-woocommerce-extra-product-options-addon/', 'hubspot_id' => '151478251017', ], ]; ================================================ FILE: static/migrations/20240219175240.php ================================================ posts posts " . "WHERE posts.post_type = 'attachment' " . "ORDER BY ID DESC " . "LIMIT 1"; $result = $wpdb->get_var( $sql ); return !empty( $result ); } public function init_state() { global $wpdb; parent::init_state(); $this->description = __( "Update data for Google Cloud files", ud_get_stateless_media()->domain ); $order = self::DESC ? 'DESC' : 'ASC'; // Getting the first/last attachment ID as a starting point $sql = "SELECT ID " . "FROM $wpdb->posts posts " . "WHERE posts.post_type = 'attachment' " . "ORDER BY ID $order " . "LIMIT 1"; $start_id = $wpdb->get_var( $sql ); // Getting the total number of attachments $sql = "SELECT COUNT(*) " . "FROM $wpdb->posts posts " . "WHERE posts.post_type = 'attachment' AND posts.post_status != 'trash'"; $total = $wpdb->get_var( $sql ); $this->total = self::LIMIT > 0 ? min( self::LIMIT, $total ) : $total; $this->limit = self::BATCH_SIZE; $this->offset = self::DESC ? $start_id + 1 : $start_id - 1; } public function get_batch() { global $wpdb; $batch = []; if ( self::LIMIT > 0 && $this->completed >= self::LIMIT ) { $this->stop = true; return $batch; } if ($this->stop) { return $batch; } $order = self::DESC ? 'DESC' : 'ASC'; $condition = self::DESC ? 'posts.ID < %d' : 'posts.ID > %d'; // Using last post ID instead of limit for performance $sql = "SELECT posts.ID " . "FROM $wpdb->posts posts " . "WHERE posts.post_type = 'attachment' AND $condition " . "ORDER BY posts.ID $order " . "LIMIT %d"; $sql = $wpdb->prepare( $sql, $this->offset, $this->limit ); $batch = $wpdb->get_col( $sql ); $count = count( $batch ); $this->offset = end( $batch ); if ( $count < $this->limit ) { $this->stop = true; } return $batch; } /** * Get the 'generation' field from the GCS media link * * @param string $sm_id * @return string */ private function _get_generation_from_media_link($media_link) { $query = parse_url($media_link, PHP_URL_QUERY); parse_str($query, $parts); return $parts['generation'] ?? 0; } /** * Get the file size from the meta or from the older version of meta * * @param array $meta * @return int|null */ private function _get_file_size($meta) { if ( isset( $meta['filesize'] ) ) { return $meta['filesize']; } if ( isset( $meta['object'] ) && isset( $meta['object']['size'] ) ) { return $meta['object']['size']; } return null; } /** * Get the width from the meta or from the WP attachment meta * * @param array $meta * @param array $wp_meta * @return int|null */ private function _get_width($meta, $wp_meta) { if ( isset( $meta['width'] ) ) { return $meta['width']; } if ( isset( $meta['object'] ) && isset( $meta['object']['metadata'] ) && isset( $meta['object']['metadata']['width'] ) ) { return $meta['object']['metadata']['width']; } if ( isset( $wp_meta['width'] ) ) { return $wp_meta['width']; } return null; } /** * Get the height from the meta or from the WP attachment meta * * @param array $meta * @param array $wp_meta * @return int|null */ private function _get_height($meta, $wp_meta) { if ( isset( $meta['height'] ) ) { return $meta['height']; } if ( isset( $meta['object'] ) && isset( $meta['object']['metadata'] ) && isset( $meta['object']['metadata']['height'] ) ) { return $meta['object']['metadata']['height']; } if ( isset( $wp_meta['height'] ) ) { return $wp_meta['height']; } return null; } /** * Get the content type from the meta or from the file * * @param array $meta * @param string $file * @return string * @throws \Exception */ private function _get_content_type($meta, $file) { if ( isset( $meta['contentType'] ) ) { return $meta['contentType']; } if ( isset( $meta['object'] ) && isset( $meta['object']['contentType'] ) ) { return $meta['object']['contentType']; } // Get mimetype based on file extension the file extension $file = pathinfo($file, PATHINFO_BASENAME); $type = wp_check_filetype($file); return $type['type'] ?? ''; } /** * Get the self link from the meta * * @param array $meta * @return string * @throws \Exception */ private function _get_self_link($meta) { if ( isset($meta['selfLink']) ) { return $meta['selfLink']; } if ( !isset($meta['mediaLink']) ) { throw new \Exception('Media link not defined'); } $link = $meta['mediaLink'] ?? ''; $remove = '/download'; $pos = strpos($link, $remove); if ($pos === false) { return $link; } $link = substr_replace($link, '', $pos, strlen($remove)); $parts = explode('?', $link); return reset($parts); } /** * Get the version from the meta * * @param array $meta * @return string */ private function _get_version($meta) { return isset($meta['sm_version']) ? $meta['sm_version'] : $this->id; } /** * Get the file link from the meta or generate a new one * * @param string $name * @param array $meta * @return string */ private function _get_file_link($name, $meta) { return isset($meta['fileLink']) ? $meta['fileLink'] : ud_stateless_db()->get_file_link($name); } public function process_item($item) { global $wpdb; Helper::log('Processing item ' . $item); $meta = get_post_meta( $item, 'sm_cloud', true ); if ( !$meta || empty($meta) ) { return false; } $wp_meta = get_post_meta( $item, '_wp_attachment_metadata', true ); $old_suppress = $wpdb->suppress_errors(); // Disable autocommit and use transactions to ensure data integrity $wpdb->query( 'SET autocommit = 0;' ); $wpdb->query( 'START TRANSACTION;' ); try { // Update file data $name = $meta['name'] ?? ''; $data = [ 'post_id' => $item, 'name' => $name, 'bucket' => $meta['bucket'] ?? '', 'generation' => $this->_get_generation_from_media_link( $meta['mediaLink'] ?? ''), 'cache_control' => $meta['cacheControl'] ?? null, 'content_type' => $this->_get_content_type($meta, $name), 'content_disposition' => $meta['contentDisposition'] ?? null, 'file_size' => $this->_get_file_size($meta), 'width' => $this->_get_width($meta, $wp_meta), 'height' => $this->_get_height($meta, $wp_meta), 'stateless_version' => $this->_get_version($meta), 'storage_class' => $meta['storageClass'] ?? null, 'file_link' => $this->_get_file_link($name, $meta), 'self_link' => $this->_get_self_link($meta), ]; $wpdb->insert(ud_stateless_db()->files, $data); // Update file sizes data $sizes = $meta['sizes'] ?? []; foreach ($sizes as $size => $size_data) { $name = $size_data['name']; $data = [ 'post_id' => $item, 'name' => $name, 'size_name' => $size, 'generation' => $this->_get_generation_from_media_link( $size_data['mediaLink'] ), 'file_size' => $this->_get_file_size($size_data), 'width' => $this->_get_width($size_data, $wp_meta['sizes'][$size] ?? []), 'height' => $this->_get_height($size_data, $wp_meta['sizes'][$size] ?? []), 'file_link' => $this->_get_file_link($name, $meta), 'self_link' => $this->_get_self_link($size_data), ]; $wpdb->insert(ud_stateless_db()->file_sizes, $data); } // Update file meta data ('fileMd5' for LiteSpeed Cache) $key = 'fileMd5'; $md5_data = $meta[$key] ?? null; if ( !empty($md5_data) ) { $data = [ 'post_id' => $item, 'meta_key' => sanitize_key($key), 'meta_value' => maybe_serialize($md5_data), ]; $wpdb->insert(ud_stateless_db()->file_meta, $data); } $wpdb->query( 'COMMIT' ); $this->completed++; } catch ( \Throwable $e ) { $wpdb->query( 'ROLLBACK;' ); Helper::log( "Error while processing item $item: " . $e->getMessage() ); } $wpdb->query( 'SET autocommit = 1;' ); $wpdb->suppress_errors($old_suppress); return false; } } ================================================ FILE: static/migrations/20240423174109.php ================================================ prefix . 'sm_sync'; $result = null; try { $result = $wpdb->get_var("SELECT id FROM $table_name LIMIT 1"); } catch (\Throwable $e) { Helper::log('Table sm_sync not found'); return false; } return !empty( $result ); } public function init_state() { global $wpdb; parent::init_state(); $this->description = __( "Optimize Compatibility Files", ud_get_stateless_media()->domain ); $table_name = $wpdb->prefix . 'sm_sync'; $order = self::DESC ? 'DESC' : 'ASC'; $total = 0; // Getting the total number of attachments try { $total = $wpdb->get_var( "SELECT COUNT(*) FROM $table_name" ); } catch (\Throwable $e) { Helper::log('Table sm_sync not found'); return false; } $this->total = self::LIMIT > 0 ? min( self::LIMIT, $total ) : $total; $this->limit = self::LIMIT > 0 ? min(self::BATCH_SIZE, self::LIMIT) : self::BATCH_SIZE; } public function get_batch() { global $wpdb; $batch = []; if ( self::LIMIT > 0 && $this->completed >= self::LIMIT ) { $this->stop = true; return $batch; } if ($this->stop) { return $batch; } $order = self::DESC ? 'DESC' : 'ASC'; $table_name = $wpdb->prefix . 'sm_sync'; $sql = "SELECT id " . "FROM $table_name " . "ORDER BY id $order " . "LIMIT %d OFFSET %d"; try { $sql = $wpdb->prepare( $sql, $this->limit, $this->offset ); $batch = $wpdb->get_col( $sql ); $count = count( $batch ); $this->offset += $count; if ( $count < $this->limit ) { $this->stop = true; } } catch (\Throwable $e) { Helper::log( $e->getMessage() ); } return $batch; } public function process_item($item) { global $wpdb; Helper::log('Processing item ' . $item); $old_suppress = $wpdb->suppress_errors(); $sync_table = $wpdb->prefix . 'sm_sync'; $files_table = ud_stateless_db()->files; try { $sql = "SELECT st.file as file, st.status as status, ft.id as fid " . "FROM $sync_table st " . "LEFT JOIN $files_table ft ON st.file = ft.name AND ft.post_id IS NULL " . "WHERE st.id = %d"; $sql = $wpdb->prepare( $sql, $item ); $sync = $wpdb->get_row( $sql ); // We have the data and the data is missing in 'wp_stateless_files' if ( !empty($sync) && !empty($sync->file) && empty($sync->fid) ) { $client = ud_get_stateless_media()->get_client(); $media = (array) $client->get_media( $sync->file ); if ( is_array($media) && !empty($media) && isset($media['metadata']) ) { $metadata = $media['metadata']; if ( !isset($metadata['source']) && !isset($metadata['sourceVersion']) ) { $media['metadata']['sourceVersion'] = $this->id; } ud_stateless_db()->update_non_library_file($media, $sync->status); } } } catch (\Throwable $e) { Helper::log( $e->getMessage() ); } $wpdb->suppress_errors($old_suppress); $this->completed++; return false; } } ================================================ FILE: static/scripts/error-notice.js ================================================ /** * EVENTS */ jQuery( document ).ready( function ($) { jQuery( document ).on( 'click', '.stateless-admin-notice.ud-admin-notice .button-action', function(e){ var _this = jQuery( this ); if(_this.attr('href') != '#'){ return; } e.preventDefault(); var data = { action: 'stateless_enable_notice_button_action', key: _this.data('key'), _ajax_nonce: stateless_error_notice_vars.enable_action_nonce ?? '', } jQuery.post( ajaxurl, data, function ( result_data ) { if( result_data.success == '1' ) { _this.closest('.ud-admin-notice').remove(); var key = _this.attr('data-key'); key = key.replace('button_secondary_', ''); $("#" + key + " option[value=" + key +"]").attr('selected', 'selected'); $("#" + key).val('true'); } else if ( result_data.success == '0' ) { // alert(result_data.error); } }, "json" ); return false; }); jQuery( '.stateless-admin-notice.ud-admin-notice' ).off( 'click', '.dismiss'); jQuery( document ).on( 'click', '.stateless-admin-notice.ud-admin-notice .dismiss-warning', function(e){ e.preventDefault(); var _this = jQuery( this ); var data = { action: 'stateless_notice_dismiss', key: _this.data('key'), _ajax_nonce: stateless_error_notice_vars.dismiss_nonce ?? '', } jQuery.post( ajaxurl, data, function ( result_data ) { if( result_data.success == '1' ) { _this.closest('.ud-admin-notice').remove(); } else if ( result_data.success == '0' ) { // alert(result_data.error); } }, "json" ); return false; }); jQuery('#stless_settings_tab .sm-mode input[type=radio]').on('change', function(){ if($(this).val() == 'stateless' || $(this).val() == 'ephemeral'){ var notice = jQuery('#stateless-notice-stateless-cache-busting'); if(!notice.length){ notice = jQuery(jQuery('#template-stateless-cache-busting').html()); notice.appendTo("#stateless-settings-page-title"); } jQuery('#stateless-notice-stateless-cache-busting').show(); } else{ jQuery('#stateless-notice-stateless-cache-busting').hide(); } }); } ); ================================================ FILE: static/scripts/i18n/af.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/af",[],function(){return{errorLoading:function(){return"Die resultate kon nie gelaai word nie."},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Verwyders asseblief "+n+" character";return 1!=n&&(r+="s"),r},inputTooShort:function(e){return"Voer asseblief "+(e.minimum-e.input.length)+" of meer karakters"},loadingMore:function(){return"Meer resultate word gelaai…"},maximumSelected:function(e){var n="Kies asseblief net "+e.maximum+" item";return 1!=e.maximum&&(n+="s"),n},noResults:function(){return"Geen resultate gevind"},searching:function(){return"Besig…"},removeAllItems:function(){return"Verwyder alle items"}}}),e.define,e.require}(); ================================================ FILE: static/scripts/i18n/ar.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ar",[],function(){return{errorLoading:function(){return"لا يمكن تحميل النتائج"},inputTooLong:function(n){return"الرجاء حذف "+(n.input.length-n.maximum)+" عناصر"},inputTooShort:function(n){return"الرجاء إضافة "+(n.minimum-n.input.length)+" عناصر"},loadingMore:function(){return"جاري تحميل نتائج إضافية..."},maximumSelected:function(n){return"تستطيع إختيار "+n.maximum+" بنود فقط"},noResults:function(){return"لم يتم العثور على أي نتائج"},searching:function(){return"جاري البحث…"},removeAllItems:function(){return"قم بإزالة كل العناصر"}}}),n.define,n.require}(); ================================================ FILE: static/scripts/i18n/az.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/az",[],function(){return{inputTooLong:function(n){return n.input.length-n.maximum+" simvol silin"},inputTooShort:function(n){return n.minimum-n.input.length+" simvol daxil edin"},loadingMore:function(){return"Daha çox nəticə yüklənir…"},maximumSelected:function(n){return"Sadəcə "+n.maximum+" element seçə bilərsiniz"},noResults:function(){return"Nəticə tapılmadı"},searching:function(){return"Axtarılır…"},removeAllItems:function(){return"Bütün elementləri sil"}}}),n.define,n.require}(); ================================================ FILE: static/scripts/i18n/bg.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/bg",[],function(){return{inputTooLong:function(n){var e=n.input.length-n.maximum,u="Моля въведете с "+e+" по-малко символ";return e>1&&(u+="a"),u},inputTooShort:function(n){var e=n.minimum-n.input.length,u="Моля въведете още "+e+" символ";return e>1&&(u+="a"),u},loadingMore:function(){return"Зареждат се още…"},maximumSelected:function(n){var e="Можете да направите до "+n.maximum+" ";return n.maximum>1?e+="избора":e+="избор",e},noResults:function(){return"Няма намерени съвпадения"},searching:function(){return"Търсене…"},removeAllItems:function(){return"Премахнете всички елементи"}}}),n.define,n.require}(); ================================================ FILE: static/scripts/i18n/bn.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/bn",[],function(){return{errorLoading:function(){return"ফলাফলগুলি লোড করা যায়নি।"},inputTooLong:function(n){var e=n.input.length-n.maximum,u="অনুগ্রহ করে "+e+" টি অক্ষর মুছে দিন।";return 1!=e&&(u="অনুগ্রহ করে "+e+" টি অক্ষর মুছে দিন।"),u},inputTooShort:function(n){return n.minimum-n.input.length+" টি অক্ষর অথবা অধিক অক্ষর লিখুন।"},loadingMore:function(){return"আরো ফলাফল লোড হচ্ছে ..."},maximumSelected:function(n){var e=n.maximum+" টি আইটেম নির্বাচন করতে পারবেন।";return 1!=n.maximum&&(e=n.maximum+" টি আইটেম নির্বাচন করতে পারবেন।"),e},noResults:function(){return"কোন ফলাফল পাওয়া যায়নি।"},searching:function(){return"অনুসন্ধান করা হচ্ছে ..."}}}),n.define,n.require}(); ================================================ FILE: static/scripts/i18n/bs.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/bs",[],function(){function e(e,n,r,t){return e%10==1&&e%100!=11?n:e%10>=2&&e%10<=4&&(e%100<12||e%100>14)?r:t}return{errorLoading:function(){return"Preuzimanje nije uspijelo."},inputTooLong:function(n){var r=n.input.length-n.maximum,t="Obrišite "+r+" simbol";return t+=e(r,"","a","a")},inputTooShort:function(n){var r=n.minimum-n.input.length,t="Ukucajte bar još "+r+" simbol";return t+=e(r,"","a","a")},loadingMore:function(){return"Preuzimanje još rezultata…"},maximumSelected:function(n){var r="Možete izabrati samo "+n.maximum+" stavk";return r+=e(n.maximum,"u","e","i")},noResults:function(){return"Ništa nije pronađeno"},searching:function(){return"Pretraga…"},removeAllItems:function(){return"Uklonite sve stavke"}}}),e.define,e.require}(); ================================================ FILE: static/scripts/i18n/ca.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/ca",[],function(){return{errorLoading:function(){return"La càrrega ha fallat"},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Si us plau, elimina "+n+" car";return r+=1==n?"àcter":"àcters"},inputTooShort:function(e){var n=e.minimum-e.input.length,r="Si us plau, introdueix "+n+" car";return r+=1==n?"àcter":"àcters"},loadingMore:function(){return"Carregant més resultats…"},maximumSelected:function(e){var n="Només es pot seleccionar "+e.maximum+" element";return 1!=e.maximum&&(n+="s"),n},noResults:function(){return"No s'han trobat resultats"},searching:function(){return"Cercant…"},removeAllItems:function(){return"Treu tots els elements"}}}),e.define,e.require}(); ================================================ FILE: static/scripts/i18n/cs.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/cs",[],function(){function e(e,n){switch(e){case 2:return n?"dva":"dvě";case 3:return"tři";case 4:return"čtyři"}return""}return{errorLoading:function(){return"Výsledky nemohly být načteny."},inputTooLong:function(n){var t=n.input.length-n.maximum;return 1==t?"Prosím, zadejte o jeden znak méně.":t<=4?"Prosím, zadejte o "+e(t,!0)+" znaky méně.":"Prosím, zadejte o "+t+" znaků méně."},inputTooShort:function(n){var t=n.minimum-n.input.length;return 1==t?"Prosím, zadejte ještě jeden znak.":t<=4?"Prosím, zadejte ještě další "+e(t,!0)+" znaky.":"Prosím, zadejte ještě dalších "+t+" znaků."},loadingMore:function(){return"Načítají se další výsledky…"},maximumSelected:function(n){var t=n.maximum;return 1==t?"Můžete zvolit jen jednu položku.":t<=4?"Můžete zvolit maximálně "+e(t,!1)+" položky.":"Můžete zvolit maximálně "+t+" položek."},noResults:function(){return"Nenalezeny žádné položky."},searching:function(){return"Vyhledávání…"},removeAllItems:function(){return"Odstraňte všechny položky"}}}),e.define,e.require}(); ================================================ FILE: static/scripts/i18n/da.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/da",[],function(){return{errorLoading:function(){return"Resultaterne kunne ikke indlæses."},inputTooLong:function(e){return"Angiv venligst "+(e.input.length-e.maximum)+" tegn mindre"},inputTooShort:function(e){return"Angiv venligst "+(e.minimum-e.input.length)+" tegn mere"},loadingMore:function(){return"Indlæser flere resultater…"},maximumSelected:function(e){var n="Du kan kun vælge "+e.maximum+" emne";return 1!=e.maximum&&(n+="r"),n},noResults:function(){return"Ingen resultater fundet"},searching:function(){return"Søger…"},removeAllItems:function(){return"Fjern alle elementer"}}}),e.define,e.require}(); ================================================ FILE: static/scripts/i18n/de.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/de",[],function(){return{errorLoading:function(){return"Die Ergebnisse konnten nicht geladen werden."},inputTooLong:function(e){return"Bitte "+(e.input.length-e.maximum)+" Zeichen weniger eingeben"},inputTooShort:function(e){return"Bitte "+(e.minimum-e.input.length)+" Zeichen mehr eingeben"},loadingMore:function(){return"Lade mehr Ergebnisse…"},maximumSelected:function(e){var n="Sie können nur "+e.maximum+" Element";return 1!=e.maximum&&(n+="e"),n+=" auswählen"},noResults:function(){return"Keine Übereinstimmungen gefunden"},searching:function(){return"Suche…"},removeAllItems:function(){return"Entferne alle Elemente"}}}),e.define,e.require}(); ================================================ FILE: static/scripts/i18n/dsb.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/dsb",[],function(){var n=["znamuško","znamušce","znamuška","znamuškow"],e=["zapisk","zapiska","zapiski","zapiskow"],u=function(n,e){return 1===n?e[0]:2===n?e[1]:n>2&&n<=4?e[2]:n>=5?e[3]:void 0};return{errorLoading:function(){return"Wuslědki njejsu se dali zacytaś."},inputTooLong:function(e){var a=e.input.length-e.maximum;return"Pšosym lašuj "+a+" "+u(a,n)},inputTooShort:function(e){var a=e.minimum-e.input.length;return"Pšosym zapódaj nanejmjenjej "+a+" "+u(a,n)},loadingMore:function(){return"Dalšne wuslědki se zacytaju…"},maximumSelected:function(n){return"Móžoš jano "+n.maximum+" "+u(n.maximum,e)+"wubraś."},noResults:function(){return"Žedne wuslědki namakane"},searching:function(){return"Pyta se…"},removeAllItems:function(){return"Remove all items"}}}),n.define,n.require}(); ================================================ FILE: static/scripts/i18n/el.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/el",[],function(){return{errorLoading:function(){return"Τα αποτελέσματα δεν μπόρεσαν να φορτώσουν."},inputTooLong:function(n){var e=n.input.length-n.maximum,u="Παρακαλώ διαγράψτε "+e+" χαρακτήρ";return 1==e&&(u+="α"),1!=e&&(u+="ες"),u},inputTooShort:function(n){return"Παρακαλώ συμπληρώστε "+(n.minimum-n.input.length)+" ή περισσότερους χαρακτήρες"},loadingMore:function(){return"Φόρτωση περισσότερων αποτελεσμάτων…"},maximumSelected:function(n){var e="Μπορείτε να επιλέξετε μόνο "+n.maximum+" επιλογ";return 1==n.maximum&&(e+="ή"),1!=n.maximum&&(e+="ές"),e},noResults:function(){return"Δεν βρέθηκαν αποτελέσματα"},searching:function(){return"Αναζήτηση…"},removeAllItems:function(){return"Καταργήστε όλα τα στοιχεία"}}}),n.define,n.require}(); ================================================ FILE: static/scripts/i18n/en.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/en",[],function(){return{errorLoading:function(){return"The results could not be loaded."},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Please delete "+n+" character";return 1!=n&&(r+="s"),r},inputTooShort:function(e){return"Please enter "+(e.minimum-e.input.length)+" or more characters"},loadingMore:function(){return"Loading more results…"},maximumSelected:function(e){var n="You can only select "+e.maximum+" item";return 1!=e.maximum&&(n+="s"),n},noResults:function(){return"No results found"},searching:function(){return"Searching…"},removeAllItems:function(){return"Remove all items"}}}),e.define,e.require}(); ================================================ FILE: static/scripts/i18n/es.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/es",[],function(){return{errorLoading:function(){return"No se pudieron cargar los resultados"},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Por favor, elimine "+n+" car";return r+=1==n?"ácter":"acteres"},inputTooShort:function(e){var n=e.minimum-e.input.length,r="Por favor, introduzca "+n+" car";return r+=1==n?"ácter":"acteres"},loadingMore:function(){return"Cargando más resultados…"},maximumSelected:function(e){var n="Sólo puede seleccionar "+e.maximum+" elemento";return 1!=e.maximum&&(n+="s"),n},noResults:function(){return"No se encontraron resultados"},searching:function(){return"Buscando…"},removeAllItems:function(){return"Eliminar todos los elementos"}}}),e.define,e.require}(); ================================================ FILE: static/scripts/i18n/et.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/et",[],function(){return{inputTooLong:function(e){var n=e.input.length-e.maximum,t="Sisesta "+n+" täht";return 1!=n&&(t+="e"),t+=" vähem"},inputTooShort:function(e){var n=e.minimum-e.input.length,t="Sisesta "+n+" täht";return 1!=n&&(t+="e"),t+=" rohkem"},loadingMore:function(){return"Laen tulemusi…"},maximumSelected:function(e){var n="Saad vaid "+e.maximum+" tulemus";return 1==e.maximum?n+="e":n+="t",n+=" valida"},noResults:function(){return"Tulemused puuduvad"},searching:function(){return"Otsin…"},removeAllItems:function(){return"Eemalda kõik esemed"}}}),e.define,e.require}(); ================================================ FILE: static/scripts/i18n/eu.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/eu",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n="Idatzi ";return n+=1==t?"karaktere bat":t+" karaktere",n+=" gutxiago"},inputTooShort:function(e){var t=e.minimum-e.input.length,n="Idatzi ";return n+=1==t?"karaktere bat":t+" karaktere",n+=" gehiago"},loadingMore:function(){return"Emaitza gehiago kargatzen…"},maximumSelected:function(e){return 1===e.maximum?"Elementu bakarra hauta dezakezu":e.maximum+" elementu hauta ditzakezu soilik"},noResults:function(){return"Ez da bat datorrenik aurkitu"},searching:function(){return"Bilatzen…"},removeAllItems:function(){return"Kendu elementu guztiak"}}}),e.define,e.require}(); ================================================ FILE: static/scripts/i18n/fa.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/fa",[],function(){return{errorLoading:function(){return"امکان بارگذاری نتایج وجود ندارد."},inputTooLong:function(n){return"لطفاً "+(n.input.length-n.maximum)+" کاراکتر را حذف نمایید"},inputTooShort:function(n){return"لطفاً تعداد "+(n.minimum-n.input.length)+" کاراکتر یا بیشتر وارد نمایید"},loadingMore:function(){return"در حال بارگذاری نتایج بیشتر..."},maximumSelected:function(n){return"شما تنها می‌توانید "+n.maximum+" آیتم را انتخاب نمایید"},noResults:function(){return"هیچ نتیجه‌ای یافت نشد"},searching:function(){return"در حال جستجو..."},removeAllItems:function(){return"همه موارد را حذف کنید"}}}),n.define,n.require}(); ================================================ FILE: static/scripts/i18n/fi.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/fi",[],function(){return{errorLoading:function(){return"Tuloksia ei saatu ladattua."},inputTooLong:function(n){return"Ole hyvä ja anna "+(n.input.length-n.maximum)+" merkkiä vähemmän"},inputTooShort:function(n){return"Ole hyvä ja anna "+(n.minimum-n.input.length)+" merkkiä lisää"},loadingMore:function(){return"Ladataan lisää tuloksia…"},maximumSelected:function(n){return"Voit valita ainoastaan "+n.maximum+" kpl"},noResults:function(){return"Ei tuloksia"},searching:function(){return"Haetaan…"},removeAllItems:function(){return"Poista kaikki kohteet"}}}),n.define,n.require}(); ================================================ FILE: static/scripts/i18n/fr.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/fr",[],function(){return{errorLoading:function(){return"Les résultats ne peuvent pas être chargés."},inputTooLong:function(e){var n=e.input.length-e.maximum;return"Supprimez "+n+" caractère"+(n>1?"s":"")},inputTooShort:function(e){var n=e.minimum-e.input.length;return"Saisissez au moins "+n+" caractère"+(n>1?"s":"")},loadingMore:function(){return"Chargement de résultats supplémentaires…"},maximumSelected:function(e){return"Vous pouvez seulement sélectionner "+e.maximum+" élément"+(e.maximum>1?"s":"")},noResults:function(){return"Aucun résultat trouvé"},searching:function(){return"Recherche en cours…"},removeAllItems:function(){return"Supprimer tous les éléments"}}}),e.define,e.require}(); ================================================ FILE: static/scripts/i18n/gl.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/gl",[],function(){return{errorLoading:function(){return"Non foi posíbel cargar os resultados."},inputTooLong:function(e){var n=e.input.length-e.maximum;return 1===n?"Elimine un carácter":"Elimine "+n+" caracteres"},inputTooShort:function(e){var n=e.minimum-e.input.length;return 1===n?"Engada un carácter":"Engada "+n+" caracteres"},loadingMore:function(){return"Cargando máis resultados…"},maximumSelected:function(e){return 1===e.maximum?"Só pode seleccionar un elemento":"Só pode seleccionar "+e.maximum+" elementos"},noResults:function(){return"Non se atoparon resultados"},searching:function(){return"Buscando…"},removeAllItems:function(){return"Elimina todos os elementos"}}}),e.define,e.require}(); ================================================ FILE: static/scripts/i18n/he.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/he",[],function(){return{errorLoading:function(){return"שגיאה בטעינת התוצאות"},inputTooLong:function(n){var e=n.input.length-n.maximum,r="נא למחוק ";return r+=1===e?"תו אחד":e+" תווים"},inputTooShort:function(n){var e=n.minimum-n.input.length,r="נא להכניס ";return r+=1===e?"תו אחד":e+" תווים",r+=" או יותר"},loadingMore:function(){return"טוען תוצאות נוספות…"},maximumSelected:function(n){var e="באפשרותך לבחור עד ";return 1===n.maximum?e+="פריט אחד":e+=n.maximum+" פריטים",e},noResults:function(){return"לא נמצאו תוצאות"},searching:function(){return"מחפש…"},removeAllItems:function(){return"הסר את כל הפריטים"}}}),n.define,n.require}(); ================================================ FILE: static/scripts/i18n/hi.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/hi",[],function(){return{errorLoading:function(){return"परिणामों को लोड नहीं किया जा सका।"},inputTooLong:function(n){var e=n.input.length-n.maximum,r=e+" अक्षर को हटा दें";return e>1&&(r=e+" अक्षरों को हटा दें "),r},inputTooShort:function(n){return"कृपया "+(n.minimum-n.input.length)+" या अधिक अक्षर दर्ज करें"},loadingMore:function(){return"अधिक परिणाम लोड हो रहे है..."},maximumSelected:function(n){return"आप केवल "+n.maximum+" आइटम का चयन कर सकते हैं"},noResults:function(){return"कोई परिणाम नहीं मिला"},searching:function(){return"खोज रहा है..."},removeAllItems:function(){return"सभी वस्तुओं को हटा दें"}}}),n.define,n.require}(); ================================================ FILE: static/scripts/i18n/hr.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/hr",[],function(){function n(n){var e=" "+n+" znak";return n%10<5&&n%10>0&&(n%100<5||n%100>19)?n%10>1&&(e+="a"):e+="ova",e}return{errorLoading:function(){return"Preuzimanje nije uspjelo."},inputTooLong:function(e){return"Unesite "+n(e.input.length-e.maximum)},inputTooShort:function(e){return"Unesite još "+n(e.minimum-e.input.length)},loadingMore:function(){return"Učitavanje rezultata…"},maximumSelected:function(n){return"Maksimalan broj odabranih stavki je "+n.maximum},noResults:function(){return"Nema rezultata"},searching:function(){return"Pretraga…"},removeAllItems:function(){return"Ukloni sve stavke"}}}),n.define,n.require}(); ================================================ FILE: static/scripts/i18n/hsb.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/hsb",[],function(){var n=["znamješko","znamješce","znamješka","znamješkow"],e=["zapisk","zapiskaj","zapiski","zapiskow"],u=function(n,e){return 1===n?e[0]:2===n?e[1]:n>2&&n<=4?e[2]:n>=5?e[3]:void 0};return{errorLoading:function(){return"Wuslědki njedachu so začitać."},inputTooLong:function(e){var a=e.input.length-e.maximum;return"Prošu zhašej "+a+" "+u(a,n)},inputTooShort:function(e){var a=e.minimum-e.input.length;return"Prošu zapodaj znajmjeńša "+a+" "+u(a,n)},loadingMore:function(){return"Dalše wuslědki so začitaja…"},maximumSelected:function(n){return"Móžeš jenož "+n.maximum+" "+u(n.maximum,e)+"wubrać"},noResults:function(){return"Žane wuslědki namakane"},searching:function(){return"Pyta so…"},removeAllItems:function(){return"Remove all items"}}}),n.define,n.require}(); ================================================ FILE: static/scripts/i18n/hu.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/hu",[],function(){return{errorLoading:function(){return"Az eredmények betöltése nem sikerült."},inputTooLong:function(e){return"Túl hosszú. "+(e.input.length-e.maximum)+" karakterrel több, mint kellene."},inputTooShort:function(e){return"Túl rövid. Még "+(e.minimum-e.input.length)+" karakter hiányzik."},loadingMore:function(){return"Töltés…"},maximumSelected:function(e){return"Csak "+e.maximum+" elemet lehet kiválasztani."},noResults:function(){return"Nincs találat."},searching:function(){return"Keresés…"},removeAllItems:function(){return"Távolítson el minden elemet"}}}),e.define,e.require}(); ================================================ FILE: static/scripts/i18n/hy.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/hy",[],function(){return{errorLoading:function(){return"Արդյունքները հնարավոր չէ բեռնել։"},inputTooLong:function(n){return"Խնդրում ենք հեռացնել "+(n.input.length-n.maximum)+" նշան"},inputTooShort:function(n){return"Խնդրում ենք մուտքագրել "+(n.minimum-n.input.length)+" կամ ավել նշաններ"},loadingMore:function(){return"Բեռնվում են նոր արդյունքներ․․․"},maximumSelected:function(n){return"Դուք կարող եք ընտրել առավելագույնը "+n.maximum+" կետ"},noResults:function(){return"Արդյունքներ չեն գտնվել"},searching:function(){return"Որոնում․․․"},removeAllItems:function(){return"Հեռացնել բոլոր տարրերը"}}}),n.define,n.require}(); ================================================ FILE: static/scripts/i18n/id.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/id",[],function(){return{errorLoading:function(){return"Data tidak boleh diambil."},inputTooLong:function(n){return"Hapuskan "+(n.input.length-n.maximum)+" huruf"},inputTooShort:function(n){return"Masukkan "+(n.minimum-n.input.length)+" huruf lagi"},loadingMore:function(){return"Mengambil data…"},maximumSelected:function(n){return"Anda hanya dapat memilih "+n.maximum+" pilihan"},noResults:function(){return"Tidak ada data yang sesuai"},searching:function(){return"Mencari…"},removeAllItems:function(){return"Hapus semua item"}}}),n.define,n.require}(); ================================================ FILE: static/scripts/i18n/is.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/is",[],function(){return{inputTooLong:function(n){var t=n.input.length-n.maximum,e="Vinsamlegast styttið texta um "+t+" staf";return t<=1?e:e+"i"},inputTooShort:function(n){var t=n.minimum-n.input.length,e="Vinsamlegast skrifið "+t+" staf";return t>1&&(e+="i"),e+=" í viðbót"},loadingMore:function(){return"Sæki fleiri niðurstöður…"},maximumSelected:function(n){return"Þú getur aðeins valið "+n.maximum+" atriði"},noResults:function(){return"Ekkert fannst"},searching:function(){return"Leita…"},removeAllItems:function(){return"Fjarlægðu öll atriði"}}}),n.define,n.require}(); ================================================ FILE: static/scripts/i18n/it.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/it",[],function(){return{errorLoading:function(){return"I risultati non possono essere caricati."},inputTooLong:function(e){var n=e.input.length-e.maximum,t="Per favore cancella "+n+" caratter";return t+=1!==n?"i":"e"},inputTooShort:function(e){return"Per favore inserisci "+(e.minimum-e.input.length)+" o più caratteri"},loadingMore:function(){return"Caricando più risultati…"},maximumSelected:function(e){var n="Puoi selezionare solo "+e.maximum+" element";return 1!==e.maximum?n+="i":n+="o",n},noResults:function(){return"Nessun risultato trovato"},searching:function(){return"Sto cercando…"},removeAllItems:function(){return"Rimuovi tutti gli oggetti"}}}),e.define,e.require}(); ================================================ FILE: static/scripts/i18n/ja.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ja",[],function(){return{errorLoading:function(){return"結果が読み込まれませんでした"},inputTooLong:function(n){return n.input.length-n.maximum+" 文字を削除してください"},inputTooShort:function(n){return"少なくとも "+(n.minimum-n.input.length)+" 文字を入力してください"},loadingMore:function(){return"読み込み中…"},maximumSelected:function(n){return n.maximum+" 件しか選択できません"},noResults:function(){return"対象が見つかりません"},searching:function(){return"検索しています…"},removeAllItems:function(){return"すべてのアイテムを削除"}}}),n.define,n.require}(); ================================================ FILE: static/scripts/i18n/ka.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ka",[],function(){return{errorLoading:function(){return"მონაცემების ჩატვირთვა შეუძლებელია."},inputTooLong:function(n){return"გთხოვთ აკრიფეთ "+(n.input.length-n.maximum)+" სიმბოლოთი ნაკლები"},inputTooShort:function(n){return"გთხოვთ აკრიფეთ "+(n.minimum-n.input.length)+" სიმბოლო ან მეტი"},loadingMore:function(){return"მონაცემების ჩატვირთვა…"},maximumSelected:function(n){return"თქვენ შეგიძლიათ აირჩიოთ არაუმეტეს "+n.maximum+" ელემენტი"},noResults:function(){return"რეზულტატი არ მოიძებნა"},searching:function(){return"ძიება…"},removeAllItems:function(){return"ამოიღე ყველა ელემენტი"}}}),n.define,n.require}(); ================================================ FILE: static/scripts/i18n/km.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/km",[],function(){return{errorLoading:function(){return"មិនអាចទាញយកទិន្នន័យ"},inputTooLong:function(n){return"សូមលុបចេញ "+(n.input.length-n.maximum)+" អក្សរ"},inputTooShort:function(n){return"សូមបញ្ចូល"+(n.minimum-n.input.length)+" អក្សរ រឺ ច្រើនជាងនេះ"},loadingMore:function(){return"កំពុងទាញយកទិន្នន័យបន្ថែម..."},maximumSelected:function(n){return"អ្នកអាចជ្រើសរើសបានតែ "+n.maximum+" ជម្រើសប៉ុណ្ណោះ"},noResults:function(){return"មិនមានលទ្ធផល"},searching:function(){return"កំពុងស្វែងរក..."},removeAllItems:function(){return"លុបធាតុទាំងអស់"}}}),n.define,n.require}(); ================================================ FILE: static/scripts/i18n/ko.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ko",[],function(){return{errorLoading:function(){return"결과를 불러올 수 없습니다."},inputTooLong:function(n){return"너무 깁니다. "+(n.input.length-n.maximum)+" 글자 지워주세요."},inputTooShort:function(n){return"너무 짧습니다. "+(n.minimum-n.input.length)+" 글자 더 입력해주세요."},loadingMore:function(){return"불러오는 중…"},maximumSelected:function(n){return"최대 "+n.maximum+"개까지만 선택 가능합니다."},noResults:function(){return"결과가 없습니다."},searching:function(){return"검색 중…"},removeAllItems:function(){return"모든 항목 삭제"}}}),n.define,n.require}(); ================================================ FILE: static/scripts/i18n/lt.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/lt",[],function(){function n(n,e,i,t){return n%10==1&&(n%100<11||n%100>19)?e:n%10>=2&&n%10<=9&&(n%100<11||n%100>19)?i:t}return{inputTooLong:function(e){var i=e.input.length-e.maximum,t="Pašalinkite "+i+" simbol";return t+=n(i,"į","ius","ių")},inputTooShort:function(e){var i=e.minimum-e.input.length,t="Įrašykite dar "+i+" simbol";return t+=n(i,"į","ius","ių")},loadingMore:function(){return"Kraunama daugiau rezultatų…"},maximumSelected:function(e){var i="Jūs galite pasirinkti tik "+e.maximum+" element";return i+=n(e.maximum,"ą","us","ų")},noResults:function(){return"Atitikmenų nerasta"},searching:function(){return"Ieškoma…"},removeAllItems:function(){return"Pašalinti visus elementus"}}}),n.define,n.require}(); ================================================ FILE: static/scripts/i18n/lv.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/lv",[],function(){function e(e,n,u,i){return 11===e?n:e%10==1?u:i}return{inputTooLong:function(n){var u=n.input.length-n.maximum,i="Lūdzu ievadiet par "+u;return(i+=" simbol"+e(u,"iem","u","iem"))+" mazāk"},inputTooShort:function(n){var u=n.minimum-n.input.length,i="Lūdzu ievadiet vēl "+u;return i+=" simbol"+e(u,"us","u","us")},loadingMore:function(){return"Datu ielāde…"},maximumSelected:function(n){var u="Jūs varat izvēlēties ne vairāk kā "+n.maximum;return u+=" element"+e(n.maximum,"us","u","us")},noResults:function(){return"Sakritību nav"},searching:function(){return"Meklēšana…"},removeAllItems:function(){return"Noņemt visus vienumus"}}}),e.define,e.require}(); ================================================ FILE: static/scripts/i18n/mk.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/mk",[],function(){return{inputTooLong:function(n){var e=(n.input.length,n.maximum,"Ве молиме внесете "+n.maximum+" помалку карактер");return 1!==n.maximum&&(e+="и"),e},inputTooShort:function(n){var e=(n.minimum,n.input.length,"Ве молиме внесете уште "+n.maximum+" карактер");return 1!==n.maximum&&(e+="и"),e},loadingMore:function(){return"Вчитување резултати…"},maximumSelected:function(n){var e="Можете да изберете само "+n.maximum+" ставк";return 1===n.maximum?e+="а":e+="и",e},noResults:function(){return"Нема пронајдено совпаѓања"},searching:function(){return"Пребарување…"},removeAllItems:function(){return"Отстрани ги сите предмети"}}}),n.define,n.require}(); ================================================ FILE: static/scripts/i18n/ms.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ms",[],function(){return{errorLoading:function(){return"Keputusan tidak berjaya dimuatkan."},inputTooLong:function(n){return"Sila hapuskan "+(n.input.length-n.maximum)+" aksara"},inputTooShort:function(n){return"Sila masukkan "+(n.minimum-n.input.length)+" atau lebih aksara"},loadingMore:function(){return"Sedang memuatkan keputusan…"},maximumSelected:function(n){return"Anda hanya boleh memilih "+n.maximum+" pilihan"},noResults:function(){return"Tiada padanan yang ditemui"},searching:function(){return"Mencari…"},removeAllItems:function(){return"Keluarkan semua item"}}}),n.define,n.require}(); ================================================ FILE: static/scripts/i18n/nb.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/nb",[],function(){return{errorLoading:function(){return"Kunne ikke hente resultater."},inputTooLong:function(e){return"Vennligst fjern "+(e.input.length-e.maximum)+" tegn"},inputTooShort:function(e){return"Vennligst skriv inn "+(e.minimum-e.input.length)+" tegn til"},loadingMore:function(){return"Laster flere resultater…"},maximumSelected:function(e){return"Du kan velge maks "+e.maximum+" elementer"},noResults:function(){return"Ingen treff"},searching:function(){return"Søker…"},removeAllItems:function(){return"Fjern alle elementer"}}}),e.define,e.require}(); ================================================ FILE: static/scripts/i18n/ne.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ne",[],function(){return{errorLoading:function(){return"नतिजाहरु देखाउन सकिएन।"},inputTooLong:function(n){var e=n.input.length-n.maximum,u="कृपया "+e+" अक्षर मेटाउनुहोस्।";return 1!=e&&(u+="कृपया "+e+" अक्षरहरु मेटाउनुहोस्।"),u},inputTooShort:function(n){return"कृपया बाँकी रहेका "+(n.minimum-n.input.length)+" वा अरु धेरै अक्षरहरु भर्नुहोस्।"},loadingMore:function(){return"अरु नतिजाहरु भरिँदैछन् …"},maximumSelected:function(n){var e="तँपाई "+n.maximum+" वस्तु मात्र छान्न पाउँनुहुन्छ।";return 1!=n.maximum&&(e="तँपाई "+n.maximum+" वस्तुहरु मात्र छान्न पाउँनुहुन्छ।"),e},noResults:function(){return"कुनै पनि नतिजा भेटिएन।"},searching:function(){return"खोजि हुँदैछ…"}}}),n.define,n.require}(); ================================================ FILE: static/scripts/i18n/nl.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/nl",[],function(){return{errorLoading:function(){return"De resultaten konden niet worden geladen."},inputTooLong:function(e){return"Gelieve "+(e.input.length-e.maximum)+" karakters te verwijderen"},inputTooShort:function(e){return"Gelieve "+(e.minimum-e.input.length)+" of meer karakters in te voeren"},loadingMore:function(){return"Meer resultaten laden…"},maximumSelected:function(e){var n=1==e.maximum?"kan":"kunnen",r="Er "+n+" maar "+e.maximum+" item";return 1!=e.maximum&&(r+="s"),r+=" worden geselecteerd"},noResults:function(){return"Geen resultaten gevonden…"},searching:function(){return"Zoeken…"},removeAllItems:function(){return"Verwijder alle items"}}}),e.define,e.require}(); ================================================ FILE: static/scripts/i18n/pl.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/pl",[],function(){var n=["znak","znaki","znaków"],e=["element","elementy","elementów"],r=function(n,e){return 1===n?e[0]:n>1&&n<=4?e[1]:n>=5?e[2]:void 0};return{errorLoading:function(){return"Nie można załadować wyników."},inputTooLong:function(e){var t=e.input.length-e.maximum;return"Usuń "+t+" "+r(t,n)},inputTooShort:function(e){var t=e.minimum-e.input.length;return"Podaj przynajmniej "+t+" "+r(t,n)},loadingMore:function(){return"Trwa ładowanie…"},maximumSelected:function(n){return"Możesz zaznaczyć tylko "+n.maximum+" "+r(n.maximum,e)},noResults:function(){return"Brak wyników"},searching:function(){return"Trwa wyszukiwanie…"},removeAllItems:function(){return"Usuń wszystkie przedmioty"}}}),n.define,n.require}(); ================================================ FILE: static/scripts/i18n/ps.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ps",[],function(){return{errorLoading:function(){return"پايلي نه سي ترلاسه کېدای"},inputTooLong:function(n){var e=n.input.length-n.maximum,r="د مهربانۍ لمخي "+e+" توری ړنګ کړئ";return 1!=e&&(r=r.replace("توری","توري")),r},inputTooShort:function(n){return"لږ تر لږه "+(n.minimum-n.input.length)+" يا ډېر توري وليکئ"},loadingMore:function(){return"نوري پايلي ترلاسه کيږي..."},maximumSelected:function(n){var e="تاسو يوازي "+n.maximum+" قلم په نښه کولای سی";return 1!=n.maximum&&(e=e.replace("قلم","قلمونه")),e},noResults:function(){return"پايلي و نه موندل سوې"},searching:function(){return"لټول کيږي..."},removeAllItems:function(){return"ټول توکي لرې کړئ"}}}),n.define,n.require}(); ================================================ FILE: static/scripts/i18n/pt-BR.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/pt-BR",[],function(){return{errorLoading:function(){return"Os resultados não puderam ser carregados."},inputTooLong:function(e){var n=e.input.length-e.maximum,r="Apague "+n+" caracter";return 1!=n&&(r+="es"),r},inputTooShort:function(e){return"Digite "+(e.minimum-e.input.length)+" ou mais caracteres"},loadingMore:function(){return"Carregando mais resultados…"},maximumSelected:function(e){var n="Você só pode selecionar "+e.maximum+" ite";return 1==e.maximum?n+="m":n+="ns",n},noResults:function(){return"Nenhum resultado encontrado"},searching:function(){return"Buscando…"},removeAllItems:function(){return"Remover todos os itens"}}}),e.define,e.require}(); ================================================ FILE: static/scripts/i18n/pt.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/pt",[],function(){return{errorLoading:function(){return"Os resultados não puderam ser carregados."},inputTooLong:function(e){var r=e.input.length-e.maximum,n="Por favor apague "+r+" ";return n+=1!=r?"caracteres":"caractere"},inputTooShort:function(e){return"Introduza "+(e.minimum-e.input.length)+" ou mais caracteres"},loadingMore:function(){return"A carregar mais resultados…"},maximumSelected:function(e){var r="Apenas pode seleccionar "+e.maximum+" ";return r+=1!=e.maximum?"itens":"item"},noResults:function(){return"Sem resultados"},searching:function(){return"A procurar…"},removeAllItems:function(){return"Remover todos os itens"}}}),e.define,e.require}(); ================================================ FILE: static/scripts/i18n/ro.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/ro",[],function(){return{errorLoading:function(){return"Rezultatele nu au putut fi incărcate."},inputTooLong:function(e){var t=e.input.length-e.maximum,n="Vă rugăm să ștergeți"+t+" caracter";return 1!==t&&(n+="e"),n},inputTooShort:function(e){return"Vă rugăm să introduceți "+(e.minimum-e.input.length)+" sau mai multe caractere"},loadingMore:function(){return"Se încarcă mai multe rezultate…"},maximumSelected:function(e){var t="Aveți voie să selectați cel mult "+e.maximum;return t+=" element",1!==e.maximum&&(t+="e"),t},noResults:function(){return"Nu au fost găsite rezultate"},searching:function(){return"Căutare…"},removeAllItems:function(){return"Eliminați toate elementele"}}}),e.define,e.require}(); ================================================ FILE: static/scripts/i18n/ru.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/ru",[],function(){function n(n,e,r,u){return n%10<5&&n%10>0&&n%100<5||n%100>20?n%10>1?r:e:u}return{errorLoading:function(){return"Невозможно загрузить результаты"},inputTooLong:function(e){var r=e.input.length-e.maximum,u="Пожалуйста, введите на "+r+" символ";return u+=n(r,"","a","ов"),u+=" меньше"},inputTooShort:function(e){var r=e.minimum-e.input.length,u="Пожалуйста, введите ещё хотя бы "+r+" символ";return u+=n(r,"","a","ов")},loadingMore:function(){return"Загрузка данных…"},maximumSelected:function(e){var r="Вы можете выбрать не более "+e.maximum+" элемент";return r+=n(e.maximum,"","a","ов")},noResults:function(){return"Совпадений не найдено"},searching:function(){return"Поиск…"},removeAllItems:function(){return"Удалить все элементы"}}}),n.define,n.require}(); ================================================ FILE: static/scripts/i18n/sk.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/sk",[],function(){var e={2:function(e){return e?"dva":"dve"},3:function(){return"tri"},4:function(){return"štyri"}};return{errorLoading:function(){return"Výsledky sa nepodarilo načítať."},inputTooLong:function(n){var t=n.input.length-n.maximum;return 1==t?"Prosím, zadajte o jeden znak menej":t>=2&&t<=4?"Prosím, zadajte o "+e[t](!0)+" znaky menej":"Prosím, zadajte o "+t+" znakov menej"},inputTooShort:function(n){var t=n.minimum-n.input.length;return 1==t?"Prosím, zadajte ešte jeden znak":t<=4?"Prosím, zadajte ešte ďalšie "+e[t](!0)+" znaky":"Prosím, zadajte ešte ďalších "+t+" znakov"},loadingMore:function(){return"Načítanie ďalších výsledkov…"},maximumSelected:function(n){return 1==n.maximum?"Môžete zvoliť len jednu položku":n.maximum>=2&&n.maximum<=4?"Môžete zvoliť najviac "+e[n.maximum](!1)+" položky":"Môžete zvoliť najviac "+n.maximum+" položiek"},noResults:function(){return"Nenašli sa žiadne položky"},searching:function(){return"Vyhľadávanie…"},removeAllItems:function(){return"Odstráňte všetky položky"}}}),e.define,e.require}(); ================================================ FILE: static/scripts/i18n/sl.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/sl",[],function(){return{errorLoading:function(){return"Zadetkov iskanja ni bilo mogoče naložiti."},inputTooLong:function(e){var n=e.input.length-e.maximum,t="Prosim zbrišite "+n+" znak";return 2==n?t+="a":1!=n&&(t+="e"),t},inputTooShort:function(e){var n=e.minimum-e.input.length,t="Prosim vpišite še "+n+" znak";return 2==n?t+="a":1!=n&&(t+="e"),t},loadingMore:function(){return"Nalagam več zadetkov…"},maximumSelected:function(e){var n="Označite lahko največ "+e.maximum+" predmet";return 2==e.maximum?n+="a":1!=e.maximum&&(n+="e"),n},noResults:function(){return"Ni zadetkov."},searching:function(){return"Iščem…"},removeAllItems:function(){return"Odstranite vse elemente"}}}),e.define,e.require}(); ================================================ FILE: static/scripts/i18n/sq.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/sq",[],function(){return{errorLoading:function(){return"Rezultatet nuk mund të ngarkoheshin."},inputTooLong:function(e){var n=e.input.length-e.maximum,t="Të lutem fshi "+n+" karakter";return 1!=n&&(t+="e"),t},inputTooShort:function(e){return"Të lutem shkruaj "+(e.minimum-e.input.length)+" ose më shumë karaktere"},loadingMore:function(){return"Duke ngarkuar më shumë rezultate…"},maximumSelected:function(e){var n="Mund të zgjedhësh vetëm "+e.maximum+" element";return 1!=e.maximum&&(n+="e"),n},noResults:function(){return"Nuk u gjet asnjë rezultat"},searching:function(){return"Duke kërkuar…"},removeAllItems:function(){return"Hiq të gjitha sendet"}}}),e.define,e.require}(); ================================================ FILE: static/scripts/i18n/sr-Cyrl.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/sr-Cyrl",[],function(){function n(n,e,r,u){return n%10==1&&n%100!=11?e:n%10>=2&&n%10<=4&&(n%100<12||n%100>14)?r:u}return{errorLoading:function(){return"Преузимање није успело."},inputTooLong:function(e){var r=e.input.length-e.maximum,u="Обришите "+r+" симбол";return u+=n(r,"","а","а")},inputTooShort:function(e){var r=e.minimum-e.input.length,u="Укуцајте бар још "+r+" симбол";return u+=n(r,"","а","а")},loadingMore:function(){return"Преузимање још резултата…"},maximumSelected:function(e){var r="Можете изабрати само "+e.maximum+" ставк";return r+=n(e.maximum,"у","е","и")},noResults:function(){return"Ништа није пронађено"},searching:function(){return"Претрага…"},removeAllItems:function(){return"Уклоните све ставке"}}}),n.define,n.require}(); ================================================ FILE: static/scripts/i18n/sr.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/sr",[],function(){function n(n,e,r,t){return n%10==1&&n%100!=11?e:n%10>=2&&n%10<=4&&(n%100<12||n%100>14)?r:t}return{errorLoading:function(){return"Preuzimanje nije uspelo."},inputTooLong:function(e){var r=e.input.length-e.maximum,t="Obrišite "+r+" simbol";return t+=n(r,"","a","a")},inputTooShort:function(e){var r=e.minimum-e.input.length,t="Ukucajte bar još "+r+" simbol";return t+=n(r,"","a","a")},loadingMore:function(){return"Preuzimanje još rezultata…"},maximumSelected:function(e){var r="Možete izabrati samo "+e.maximum+" stavk";return r+=n(e.maximum,"u","e","i")},noResults:function(){return"Ništa nije pronađeno"},searching:function(){return"Pretraga…"},removeAllItems:function(){return"Уклоните све ставке"}}}),n.define,n.require}(); ================================================ FILE: static/scripts/i18n/sv.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/sv",[],function(){return{errorLoading:function(){return"Resultat kunde inte laddas."},inputTooLong:function(n){return"Vänligen sudda ut "+(n.input.length-n.maximum)+" tecken"},inputTooShort:function(n){return"Vänligen skriv in "+(n.minimum-n.input.length)+" eller fler tecken"},loadingMore:function(){return"Laddar fler resultat…"},maximumSelected:function(n){return"Du kan max välja "+n.maximum+" element"},noResults:function(){return"Inga träffar"},searching:function(){return"Söker…"},removeAllItems:function(){return"Ta bort alla objekt"}}}),n.define,n.require}(); ================================================ FILE: static/scripts/i18n/th.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/th",[],function(){return{errorLoading:function(){return"ไม่สามารถค้นข้อมูลได้"},inputTooLong:function(n){return"โปรดลบออก "+(n.input.length-n.maximum)+" ตัวอักษร"},inputTooShort:function(n){return"โปรดพิมพ์เพิ่มอีก "+(n.minimum-n.input.length)+" ตัวอักษร"},loadingMore:function(){return"กำลังค้นข้อมูลเพิ่ม…"},maximumSelected:function(n){return"คุณสามารถเลือกได้ไม่เกิน "+n.maximum+" รายการ"},noResults:function(){return"ไม่พบข้อมูล"},searching:function(){return"กำลังค้นข้อมูล…"},removeAllItems:function(){return"ลบรายการทั้งหมด"}}}),n.define,n.require}(); ================================================ FILE: static/scripts/i18n/tk.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;e.define("select2/i18n/tk",[],function(){return{errorLoading:function(){return"Netije ýüklenmedi."},inputTooLong:function(e){return e.input.length-e.maximum+" harp bozuň."},inputTooShort:function(e){return"Ýene-de iň az "+(e.minimum-e.input.length)+" harp ýazyň."},loadingMore:function(){return"Köpräk netije görkezilýär…"},maximumSelected:function(e){return"Diňe "+e.maximum+" sanysyny saýlaň."},noResults:function(){return"Netije tapylmady."},searching:function(){return"Gözlenýär…"},removeAllItems:function(){return"Remove all items"}}}),e.define,e.require}(); ================================================ FILE: static/scripts/i18n/tr.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/tr",[],function(){return{errorLoading:function(){return"Sonuç yüklenemedi"},inputTooLong:function(n){return n.input.length-n.maximum+" karakter daha girmelisiniz"},inputTooShort:function(n){return"En az "+(n.minimum-n.input.length)+" karakter daha girmelisiniz"},loadingMore:function(){return"Daha fazla…"},maximumSelected:function(n){return"Sadece "+n.maximum+" seçim yapabilirsiniz"},noResults:function(){return"Sonuç bulunamadı"},searching:function(){return"Aranıyor…"},removeAllItems:function(){return"Tüm öğeleri kaldır"}}}),n.define,n.require}(); ================================================ FILE: static/scripts/i18n/uk.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/uk",[],function(){function n(n,e,u,r){return n%100>10&&n%100<15?r:n%10==1?e:n%10>1&&n%10<5?u:r}return{errorLoading:function(){return"Неможливо завантажити результати"},inputTooLong:function(e){return"Будь ласка, видаліть "+(e.input.length-e.maximum)+" "+n(e.maximum,"літеру","літери","літер")},inputTooShort:function(n){return"Будь ласка, введіть "+(n.minimum-n.input.length)+" або більше літер"},loadingMore:function(){return"Завантаження інших результатів…"},maximumSelected:function(e){return"Ви можете вибрати лише "+e.maximum+" "+n(e.maximum,"пункт","пункти","пунктів")},noResults:function(){return"Нічого не знайдено"},searching:function(){return"Пошук…"},removeAllItems:function(){return"Видалити всі елементи"}}}),n.define,n.require}(); ================================================ FILE: static/scripts/i18n/vi.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/vi",[],function(){return{inputTooLong:function(n){return"Vui lòng xóa bớt "+(n.input.length-n.maximum)+" ký tự"},inputTooShort:function(n){return"Vui lòng nhập thêm từ "+(n.minimum-n.input.length)+" ký tự trở lên"},loadingMore:function(){return"Đang lấy thêm kết quả…"},maximumSelected:function(n){return"Chỉ có thể chọn được "+n.maximum+" lựa chọn"},noResults:function(){return"Không tìm thấy kết quả"},searching:function(){return"Đang tìm…"},removeAllItems:function(){return"Xóa tất cả các mục"}}}),n.define,n.require}(); ================================================ FILE: static/scripts/i18n/zh-CN.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/zh-CN",[],function(){return{errorLoading:function(){return"无法载入结果。"},inputTooLong:function(n){return"请删除"+(n.input.length-n.maximum)+"个字符"},inputTooShort:function(n){return"请再输入至少"+(n.minimum-n.input.length)+"个字符"},loadingMore:function(){return"载入更多结果…"},maximumSelected:function(n){return"最多只能选择"+n.maximum+"个项目"},noResults:function(){return"未找到结果"},searching:function(){return"搜索中…"},removeAllItems:function(){return"删除所有项目"}}}),n.define,n.require}(); ================================================ FILE: static/scripts/i18n/zh-TW.js ================================================ /*! Select2 4.0.13 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var n=jQuery.fn.select2.amd;n.define("select2/i18n/zh-TW",[],function(){return{inputTooLong:function(n){return"請刪掉"+(n.input.length-n.maximum)+"個字元"},inputTooShort:function(n){return"請再輸入"+(n.minimum-n.input.length)+"個字元"},loadingMore:function(){return"載入中…"},maximumSelected:function(n){return"你只能選擇最多"+n.maximum+"項"},noResults:function(){return"沒有找到相符的項目"},searching:function(){return"搜尋中…"},removeAllItems:function(){return"刪除所有項目"}}}),n.define,n.require}(); ================================================ FILE: static/scripts/jquery-ui/jquery.ui.progressbar.min.1.7.2.js ================================================ /* * jQuery UI Progressbar 1.7.2 * * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * http://docs.jquery.com/UI/Progressbar * * Depends: * ui.core.js */ (function(a){a.widget("ui.progressbar",{_init:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this._valueMin(),"aria-valuemax":this._valueMax(),"aria-valuenow":this._value()});this.valueDiv=a('
').appendTo(this.element);this._refreshValue()},destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow").removeData("progressbar").unbind(".progressbar");this.valueDiv.remove();a.widget.prototype.destroy.apply(this,arguments)},value:function(b){if(b===undefined){return this._value()}this._setData("value",b);return this},_setData:function(b,c){switch(b){case"value":this.options.value=c;this._refreshValue();this._trigger("change",null,{});break}a.widget.prototype._setData.apply(this,arguments)},_value:function(){var b=this.options.value;if(bthis._valueMax()){b=this._valueMax()}return b},_valueMin:function(){var b=0;return b},_valueMax:function(){var b=100;return b},_refreshValue:function(){var b=this.value();this.valueDiv[b==this._valueMax()?"addClass":"removeClass"]("ui-corner-right");this.valueDiv.width(b+"%");this.element.attr("aria-valuenow",b)}});a.extend(a.ui.progressbar,{version:"1.7.2",defaults:{value:0}})})(jQuery);; ================================================ FILE: static/scripts/jquery-ui/redmond/jquery-ui-1.7.2.custom.css ================================================ /* * jQuery UI CSS Framework * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. */ /* Layout helpers ----------------------------------*/ .ui-helper-hidden { display: none; } .ui-helper-hidden-accessible { position: absolute; left: -99999999px; } .ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } .ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } .ui-helper-clearfix { display: inline-block; } /* required comment for clearfix to work in Opera \*/ * html .ui-helper-clearfix { height:1%; } .ui-helper-clearfix { display:block; } /* end clearfix */ .ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } /* Interaction Cues ----------------------------------*/ .ui-state-disabled { cursor: default !important; } /* Icons ----------------------------------*/ /* states and images */ .ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } /* Misc visuals ----------------------------------*/ /* Overlays */ .ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } /* * jQuery UI CSS Framework * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) * Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Lucida%20Grande,%20Lucida%20Sans,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=5px&bgColorHeader=5c9ccc&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=55&borderColorHeader=4297d7&fcHeader=ffffff&iconColorHeader=d8e7f3&bgColorContent=fcfdfd&bgTextureContent=06_inset_hard.png&bgImgOpacityContent=100&borderColorContent=a6c9e2&fcContent=222222&iconColorContent=469bdd&bgColorDefault=dfeffc&bgTextureDefault=02_glass.png&bgImgOpacityDefault=85&borderColorDefault=c5dbec&fcDefault=2e6e9e&iconColorDefault=6da8d5&bgColorHover=d0e5f5&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=79b7e7&fcHover=1d5987&iconColorHover=217bc0&bgColorActive=f5f8f9&bgTextureActive=06_inset_hard.png&bgImgOpacityActive=100&borderColorActive=79b7e7&fcActive=e17009&iconColorActive=f9bd01&bgColorHighlight=fbec88&bgTextureHighlight=01_flat.png&bgImgOpacityHighlight=55&borderColorHighlight=fad42e&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px */ /* Component containers ----------------------------------*/ .ui-widget { font-family: Lucida Grande, Lucida Sans, Arial, sans-serif; font-size: 1.1em; } .ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Lucida Grande, Lucida Sans, Arial, sans-serif; font-size: 1em; } .ui-widget-content { border: 1px solid #a6c9e2; background: #fcfdfd url(images/ui-bg_inset-hard_100_fcfdfd_1x100.png) 50% bottom repeat-x; color: #222222; } .ui-widget-content a { color: #222222; } .ui-widget-header { border: 1px solid #4297d7; background: #5c9ccc url(images/ui-bg_gloss-wave_55_5c9ccc_500x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; } .ui-widget-header a { color: #ffffff; } /* Interaction states ----------------------------------*/ .ui-state-default, .ui-widget-content .ui-state-default { border: 1px solid #c5dbec; background: #dfeffc url(images/ui-bg_glass_85_dfeffc_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #2e6e9e; outline: none; } .ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #2e6e9e; text-decoration: none; outline: none; } .ui-state-hover, .ui-widget-content .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus { border: 1px solid #79b7e7; background: #d0e5f5 url(images/ui-bg_glass_75_d0e5f5_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #1d5987; outline: none; } .ui-state-hover a, .ui-state-hover a:hover { color: #1d5987; text-decoration: none; outline: none; } .ui-state-active, .ui-widget-content .ui-state-active { border: 1px solid #79b7e7; background: #f5f8f9 url(images/ui-bg_inset-hard_100_f5f8f9_1x100.png) 50% 50% repeat-x; font-weight: bold; color: #e17009; outline: none; } .ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #e17009; outline: none; text-decoration: none; } /* Interaction Cues ----------------------------------*/ .ui-state-highlight, .ui-widget-content .ui-state-highlight {border: 1px solid #fad42e; background: #fbec88 url(images/ui-bg_flat_55_fbec88_40x100.png) 50% 50% repeat-x; color: #363636; } .ui-state-highlight a, .ui-widget-content .ui-state-highlight a { color: #363636; } .ui-state-error, .ui-widget-content .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; } .ui-state-error a, .ui-widget-content .ui-state-error a { color: #cd0a0a; } .ui-state-error-text, .ui-widget-content .ui-state-error-text { color: #cd0a0a; } .ui-state-disabled, .ui-widget-content .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } .ui-priority-primary, .ui-widget-content .ui-priority-primary { font-weight: bold; } .ui-priority-secondary, .ui-widget-content .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } /* Icons ----------------------------------*/ /* states and images */ .ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_469bdd_256x240.png); } .ui-widget-content .ui-icon {background-image: url(images/ui-icons_469bdd_256x240.png); } .ui-widget-header .ui-icon {background-image: url(images/ui-icons_d8e7f3_256x240.png); } .ui-state-default .ui-icon { background-image: url(images/ui-icons_6da8d5_256x240.png); } .ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_217bc0_256x240.png); } .ui-state-active .ui-icon {background-image: url(images/ui-icons_f9bd01_256x240.png); } .ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); } .ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); } /* positioning */ .ui-icon-carat-1-n { background-position: 0 0; } .ui-icon-carat-1-ne { background-position: -16px 0; } .ui-icon-carat-1-e { background-position: -32px 0; } .ui-icon-carat-1-se { background-position: -48px 0; } .ui-icon-carat-1-s { background-position: -64px 0; } .ui-icon-carat-1-sw { background-position: -80px 0; } .ui-icon-carat-1-w { background-position: -96px 0; } .ui-icon-carat-1-nw { background-position: -112px 0; } .ui-icon-carat-2-n-s { background-position: -128px 0; } .ui-icon-carat-2-e-w { background-position: -144px 0; } .ui-icon-triangle-1-n { background-position: 0 -16px; } .ui-icon-triangle-1-ne { background-position: -16px -16px; } .ui-icon-triangle-1-e { background-position: -32px -16px; } .ui-icon-triangle-1-se { background-position: -48px -16px; } .ui-icon-triangle-1-s { background-position: -64px -16px; } .ui-icon-triangle-1-sw { background-position: -80px -16px; } .ui-icon-triangle-1-w { background-position: -96px -16px; } .ui-icon-triangle-1-nw { background-position: -112px -16px; } .ui-icon-triangle-2-n-s { background-position: -128px -16px; } .ui-icon-triangle-2-e-w { background-position: -144px -16px; } .ui-icon-arrow-1-n { background-position: 0 -32px; } .ui-icon-arrow-1-ne { background-position: -16px -32px; } .ui-icon-arrow-1-e { background-position: -32px -32px; } .ui-icon-arrow-1-se { background-position: -48px -32px; } .ui-icon-arrow-1-s { background-position: -64px -32px; } .ui-icon-arrow-1-sw { background-position: -80px -32px; } .ui-icon-arrow-1-w { background-position: -96px -32px; } .ui-icon-arrow-1-nw { background-position: -112px -32px; } .ui-icon-arrow-2-n-s { background-position: -128px -32px; } .ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } .ui-icon-arrow-2-e-w { background-position: -160px -32px; } .ui-icon-arrow-2-se-nw { background-position: -176px -32px; } .ui-icon-arrowstop-1-n { background-position: -192px -32px; } .ui-icon-arrowstop-1-e { background-position: -208px -32px; } .ui-icon-arrowstop-1-s { background-position: -224px -32px; } .ui-icon-arrowstop-1-w { background-position: -240px -32px; } .ui-icon-arrowthick-1-n { background-position: 0 -48px; } .ui-icon-arrowthick-1-ne { background-position: -16px -48px; } .ui-icon-arrowthick-1-e { background-position: -32px -48px; } .ui-icon-arrowthick-1-se { background-position: -48px -48px; } .ui-icon-arrowthick-1-s { background-position: -64px -48px; } .ui-icon-arrowthick-1-sw { background-position: -80px -48px; } .ui-icon-arrowthick-1-w { background-position: -96px -48px; } .ui-icon-arrowthick-1-nw { background-position: -112px -48px; } .ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } .ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } .ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } .ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } .ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } .ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } .ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } .ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } .ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } .ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } .ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } .ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } .ui-icon-arrowreturn-1-w { background-position: -64px -64px; } .ui-icon-arrowreturn-1-n { background-position: -80px -64px; } .ui-icon-arrowreturn-1-e { background-position: -96px -64px; } .ui-icon-arrowreturn-1-s { background-position: -112px -64px; } .ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } .ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } .ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } .ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } .ui-icon-arrow-4 { background-position: 0 -80px; } .ui-icon-arrow-4-diag { background-position: -16px -80px; } .ui-icon-extlink { background-position: -32px -80px; } .ui-icon-newwin { background-position: -48px -80px; } .ui-icon-refresh { background-position: -64px -80px; } .ui-icon-shuffle { background-position: -80px -80px; } .ui-icon-transfer-e-w { background-position: -96px -80px; } .ui-icon-transferthick-e-w { background-position: -112px -80px; } .ui-icon-folder-collapsed { background-position: 0 -96px; } .ui-icon-folder-open { background-position: -16px -96px; } .ui-icon-document { background-position: -32px -96px; } .ui-icon-document-b { background-position: -48px -96px; } .ui-icon-note { background-position: -64px -96px; } .ui-icon-mail-closed { background-position: -80px -96px; } .ui-icon-mail-open { background-position: -96px -96px; } .ui-icon-suitcase { background-position: -112px -96px; } .ui-icon-comment { background-position: -128px -96px; } .ui-icon-person { background-position: -144px -96px; } .ui-icon-print { background-position: -160px -96px; } .ui-icon-trash { background-position: -176px -96px; } .ui-icon-locked { background-position: -192px -96px; } .ui-icon-unlocked { background-position: -208px -96px; } .ui-icon-bookmark { background-position: -224px -96px; } .ui-icon-tag { background-position: -240px -96px; } .ui-icon-home { background-position: 0 -112px; } .ui-icon-flag { background-position: -16px -112px; } .ui-icon-calendar { background-position: -32px -112px; } .ui-icon-cart { background-position: -48px -112px; } .ui-icon-pencil { background-position: -64px -112px; } .ui-icon-clock { background-position: -80px -112px; } .ui-icon-disk { background-position: -96px -112px; } .ui-icon-calculator { background-position: -112px -112px; } .ui-icon-zoomin { background-position: -128px -112px; } .ui-icon-zoomout { background-position: -144px -112px; } .ui-icon-search { background-position: -160px -112px; } .ui-icon-wrench { background-position: -176px -112px; } .ui-icon-gear { background-position: -192px -112px; } .ui-icon-heart { background-position: -208px -112px; } .ui-icon-star { background-position: -224px -112px; } .ui-icon-link { background-position: -240px -112px; } .ui-icon-cancel { background-position: 0 -128px; } .ui-icon-plus { background-position: -16px -128px; } .ui-icon-plusthick { background-position: -32px -128px; } .ui-icon-minus { background-position: -48px -128px; } .ui-icon-minusthick { background-position: -64px -128px; } .ui-icon-close { background-position: -80px -128px; } .ui-icon-closethick { background-position: -96px -128px; } .ui-icon-key { background-position: -112px -128px; } .ui-icon-lightbulb { background-position: -128px -128px; } .ui-icon-scissors { background-position: -144px -128px; } .ui-icon-clipboard { background-position: -160px -128px; } .ui-icon-copy { background-position: -176px -128px; } .ui-icon-contact { background-position: -192px -128px; } .ui-icon-image { background-position: -208px -128px; } .ui-icon-video { background-position: -224px -128px; } .ui-icon-script { background-position: -240px -128px; } .ui-icon-alert { background-position: 0 -144px; } .ui-icon-info { background-position: -16px -144px; } .ui-icon-notice { background-position: -32px -144px; } .ui-icon-help { background-position: -48px -144px; } .ui-icon-check { background-position: -64px -144px; } .ui-icon-bullet { background-position: -80px -144px; } .ui-icon-radio-off { background-position: -96px -144px; } .ui-icon-radio-on { background-position: -112px -144px; } .ui-icon-pin-w { background-position: -128px -144px; } .ui-icon-pin-s { background-position: -144px -144px; } .ui-icon-play { background-position: 0 -160px; } .ui-icon-pause { background-position: -16px -160px; } .ui-icon-seek-next { background-position: -32px -160px; } .ui-icon-seek-prev { background-position: -48px -160px; } .ui-icon-seek-end { background-position: -64px -160px; } .ui-icon-seek-first { background-position: -80px -160px; } .ui-icon-stop { background-position: -96px -160px; } .ui-icon-eject { background-position: -112px -160px; } .ui-icon-volume-off { background-position: -128px -160px; } .ui-icon-volume-on { background-position: -144px -160px; } .ui-icon-power { background-position: 0 -176px; } .ui-icon-signal-diag { background-position: -16px -176px; } .ui-icon-signal { background-position: -32px -176px; } .ui-icon-battery-0 { background-position: -48px -176px; } .ui-icon-battery-1 { background-position: -64px -176px; } .ui-icon-battery-2 { background-position: -80px -176px; } .ui-icon-battery-3 { background-position: -96px -176px; } .ui-icon-circle-plus { background-position: 0 -192px; } .ui-icon-circle-minus { background-position: -16px -192px; } .ui-icon-circle-close { background-position: -32px -192px; } .ui-icon-circle-triangle-e { background-position: -48px -192px; } .ui-icon-circle-triangle-s { background-position: -64px -192px; } .ui-icon-circle-triangle-w { background-position: -80px -192px; } .ui-icon-circle-triangle-n { background-position: -96px -192px; } .ui-icon-circle-arrow-e { background-position: -112px -192px; } .ui-icon-circle-arrow-s { background-position: -128px -192px; } .ui-icon-circle-arrow-w { background-position: -144px -192px; } .ui-icon-circle-arrow-n { background-position: -160px -192px; } .ui-icon-circle-zoomin { background-position: -176px -192px; } .ui-icon-circle-zoomout { background-position: -192px -192px; } .ui-icon-circle-check { background-position: -208px -192px; } .ui-icon-circlesmall-plus { background-position: 0 -208px; } .ui-icon-circlesmall-minus { background-position: -16px -208px; } .ui-icon-circlesmall-close { background-position: -32px -208px; } .ui-icon-squaresmall-plus { background-position: -48px -208px; } .ui-icon-squaresmall-minus { background-position: -64px -208px; } .ui-icon-squaresmall-close { background-position: -80px -208px; } .ui-icon-grip-dotted-vertical { background-position: 0 -224px; } .ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } .ui-icon-grip-solid-vertical { background-position: -32px -224px; } .ui-icon-grip-solid-horizontal { background-position: -48px -224px; } .ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } .ui-icon-grip-diagonal-se { background-position: -80px -224px; } /* Misc visuals ----------------------------------*/ /* Corner radius */ .ui-corner-tl { -moz-border-radius-topleft: 5px; -webkit-border-top-left-radius: 5px; } .ui-corner-tr { -moz-border-radius-topright: 5px; -webkit-border-top-right-radius: 5px; } .ui-corner-bl { -moz-border-radius-bottomleft: 5px; -webkit-border-bottom-left-radius: 5px; } .ui-corner-br { -moz-border-radius-bottomright: 5px; -webkit-border-bottom-right-radius: 5px; } .ui-corner-top { -moz-border-radius-topleft: 5px; -webkit-border-top-left-radius: 5px; -moz-border-radius-topright: 5px; -webkit-border-top-right-radius: 5px; } .ui-corner-bottom { -moz-border-radius-bottomleft: 5px; -webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomright: 5px; -webkit-border-bottom-right-radius: 5px; } .ui-corner-right { -moz-border-radius-topright: 5px; -webkit-border-top-right-radius: 5px; -moz-border-radius-bottomright: 5px; -webkit-border-bottom-right-radius: 5px; } .ui-corner-left { -moz-border-radius-topleft: 5px; -webkit-border-top-left-radius: 5px; -moz-border-radius-bottomleft: 5px; -webkit-border-bottom-left-radius: 5px; } .ui-corner-all { -moz-border-radius: 5px; -webkit-border-radius: 5px; } /* Overlays */ .ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); } .ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -webkit-border-radius: 8px; }/* Accordion ----------------------------------*/ .ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; } .ui-accordion .ui-accordion-li-fix { display: inline; } .ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; } .ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em 2.2em; } .ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; } .ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; } .ui-accordion .ui-accordion-content-active { display: block; }/* Datepicker ----------------------------------*/ .ui-datepicker { width: 17em; padding: .2em .2em 0; } .ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; } .ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; } .ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } .ui-datepicker .ui-datepicker-prev { left:2px; } .ui-datepicker .ui-datepicker-next { right:2px; } .ui-datepicker .ui-datepicker-prev-hover { left:1px; } .ui-datepicker .ui-datepicker-next-hover { right:1px; } .ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; } .ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; } .ui-datepicker .ui-datepicker-title select { float:left; font-size:1em; margin:1px 0; } .ui-datepicker select.ui-datepicker-month-year {width: 100%;} .ui-datepicker select.ui-datepicker-month, .ui-datepicker select.ui-datepicker-year { width: 49%;} .ui-datepicker .ui-datepicker-title select.ui-datepicker-year { float: right; } .ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; } .ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } .ui-datepicker td { border: 0; padding: 1px; } .ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; } .ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } .ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; } .ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; } /* with multiple calendars */ .ui-datepicker.ui-datepicker-multi { width:auto; } .ui-datepicker-multi .ui-datepicker-group { float:left; } .ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } .ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } .ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } .ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } .ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } .ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } .ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } .ui-datepicker-row-break { clear:both; width:100%; } /* RTL support */ .ui-datepicker-rtl { direction: rtl; } .ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } .ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } .ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } .ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } .ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; } .ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } .ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; } .ui-datepicker-rtl .ui-datepicker-group { float:right; } .ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; } .ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; } /* IE6 IFRAME FIX (taken from datepicker 1.5.3 */ .ui-datepicker-cover { display: none; /*sorry for IE5*/ display/**/: block; /*sorry for IE5*/ position: absolute; /*must have*/ z-index: -1; /*must have*/ filter: mask(); /*must have*/ top: -4px; /*must have*/ left: -4px; /*must have*/ width: 200px; /*must have*/ height: 200px; /*must have*/ }/* Dialog ----------------------------------*/ .ui-dialog { position: relative; padding: .2em; width: 300px; } .ui-dialog .ui-dialog-titlebar { padding: .5em .3em .3em 1em; position: relative; } .ui-dialog .ui-dialog-title { float: left; margin: .1em 0 .2em; } .ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; } .ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; } .ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; } .ui-dialog .ui-dialog-content { border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; } .ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; } .ui-dialog .ui-dialog-buttonpane button { float: right; margin: .5em .4em .5em 0; cursor: pointer; padding: .2em .6em .3em .6em; line-height: 1.4em; width:auto; overflow:visible; } .ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; } .ui-draggable .ui-dialog-titlebar { cursor: move; } /* Progressbar ----------------------------------*/ .ui-progressbar { height:2em; text-align: left; } .ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }/* Resizable ----------------------------------*/ .ui-resizable { position: relative;} .ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;} .ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; } .ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0px; } .ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0px; } .ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0px; height: 100%; } .ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0px; height: 100%; } .ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; } .ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; } .ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; } .ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/* Slider ----------------------------------*/ .ui-slider { position: relative; text-align: left; } .ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; } .ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; } .ui-slider-horizontal { height: .8em; } .ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; } .ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; } .ui-slider-horizontal .ui-slider-range-min { left: 0; } .ui-slider-horizontal .ui-slider-range-max { right: 0; } .ui-slider-vertical { width: .8em; height: 100px; } .ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; } .ui-slider-vertical .ui-slider-range { left: 0; width: 100%; } .ui-slider-vertical .ui-slider-range-min { bottom: 0; } .ui-slider-vertical .ui-slider-range-max { top: 0; }/* Tabs ----------------------------------*/ .ui-tabs { padding: .2em; zoom: 1; } .ui-tabs .ui-tabs-nav { list-style: none; position: relative; padding: .2em .2em 0; } .ui-tabs .ui-tabs-nav li { position: relative; float: left; border-bottom-width: 0 !important; margin: 0 .2em -1px 0; padding: 0; } .ui-tabs .ui-tabs-nav li a { float: left; text-decoration: none; padding: .5em 1em; } .ui-tabs .ui-tabs-nav li.ui-tabs-selected { padding-bottom: 1px; border-bottom-width: 0; } .ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; } .ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ .ui-tabs .ui-tabs-panel { padding: 1em 1.4em; display: block; border-width: 0; background: none; } .ui-tabs .ui-tabs-hide { display: none !important; } ================================================ FILE: static/scripts/wp-stateless-batch.js ================================================ wpStatelessBatch = { token: window.wp_stateless_batch.REST_API_TOKEN, apiRoot: window.wp_stateless_batch.api_root + 'batch/', interval: null, startPolling: function () { var that = this this.stopPolling() this.interval = setInterval(function () { that.getState() }, 1000) }, stopPolling: function () { clearInterval(this.interval) }, updateState: function(state, action = false) { var detail = { state, action, } var event = new CustomEvent('wp-stateless-batch-state-updated', { detail }) document.dispatchEvent(event) if (state.is_running) { this.startPolling() } else { this.stopPolling() } }, processFail: function(error) { console.log(error) var event = new CustomEvent('wp-stateless-batch-error', { detail: error }) document.dispatchEvent(event) }, processAction: function(action, payload, callback = null) { var that = this var data = { action, ...payload, } jQuery.ajax({ method: 'POST', url: that.apiRoot + 'action', headers: { 'x-wps-auth': that.token, 'Content-Type': 'application/json', }, dataType: 'json', data: JSON.stringify(data), }) .then(function (response) { that.updateState(response.data, true) }) .fail(function (error) { that.processFail(error) }) .always(function () { if (callback) { callback() } }) }, getState: function(data = {}) { var that = this jQuery.ajax({ method: 'GET', url: that.apiRoot + 'state', data, headers: { 'x-wps-auth': that.token, 'Content-Type': 'application/json', }, }) .then(function (response) { that.updateState(response.data) }) .fail(function (error) { that.processFail(error) }) }, init: function() { if ( window.wp_stateless_batch.is_running ) { this.startPolling() } // Check if we have a batch running on the backend jQuery(document).on('heartbeat-tick', function (e, data) { if ( data.hasOwnProperty('stateless-batch-running') && data['stateless-batch-running'] ) { this.startPolling() } }.bind(this)) } } wpStatelessBatch.init() /** * Manage data updates */ function wpMigrations($) { function blockUI() { $('#migration-action .button').addClass('disabled') } function unblockUI() { $('#migration-action .button').removeClass('disabled') } // Process state document.addEventListener('wp-stateless-batch-state-updated', function (e) { var state = e.detail.state // 'action' indicates that the action was just started. // If the migration was quick - the state is empty and we need to update the state // Otherwise the state will contain the current running migration ID var forceRefresh = e.detail.action && !state.hasOwnProperty('id') if ( (!state.is_migration && !state.hasOwnProperty('migrations')) || forceRefresh ) { // If have migrations running on the frontend - we should finalize it if ( $('#migration-action.can-pause').length || $('#migration-action.can-resume').length || forceRefresh ) { wpStatelessBatch.getState({ force_migrations: true, }) } return } if ( !state.hasOwnProperty('migrations') ) { return } // Check if we need to wait for other migrations to start // If there are more migrations - wait 5 seconds and check again if ( !state.is_running && !state.is_paused ) { var migrationsCanStart = Object.values(state.migrations).some(function(migration) { return migration.can_start }) if ( migrationsCanStart ) { setTimeout(function() { wpStatelessBatch.getState() }, 5000) return } else { $('.metabox-holder.migrations-wrap').remove() } } var migrationElement = $('#migration-action') if ( state.migrations && state.hasOwnProperty('is_migration') && state.hasOwnProperty('id') ) { var migration = state.migrations[ state.id ]; migrationElement.attr('data-id', state.id) if ( migration.can_start ) { migrationElement.addClass('can-start') } else { migrationElement.removeClass('can-start') } if ( migration.can_pause ) { migrationElement.addClass('can-pause') } else { migrationElement.removeClass('can-pause') } if ( migration.can_resume ) { migrationElement.addClass('can-resume') } else { migrationElement.removeClass('can-resume') } if ( migration.hasOwnProperty('ui_message') && migration.ui_message ) { migrationElement.find('.description').html(migration.ui_message) } else { migrationElement.find('.description').text('') } } // Display progress if ( state.is_running || state.is_paused ) { if ( state.hasOwnProperty('total') && state.hasOwnProperty('completed') ) { var migrationElement = $('#migration-action') var percent = state.total > 0 ? Math.floor( (state.completed / state.total) * 100 ) + '%' : '' migrationElement.find('.progress .percent').html(percent) migrationElement.find('.progress .bar').css('width', percent) } } }) // Process notifications document.addEventListener('wp-stateless-batch-state-updated', function (e) { var state = e.detail.state var notify = state.hasOwnProperty('migrations_notify') ? state.migrations_notify : false if ( state.is_running ) { $('#stateless-notice-migrations-required').addClass('hidden') $('#stateless-notice-migrations-finished').addClass('hidden') $('#stateless-notice-migrations-running').removeClass('hidden') } else { $('#stateless-notice-migrations-running').addClass('hidden') $('#stateless-notice-migrations-required').addClass('hidden') $('#stateless-notice-migrations-finished').addClass('hidden') if ( notify === 'require' ) { $('#stateless-notice-migrations-required').removeClass('hidden') } else if ( notify === 'finished' ) { $('#stateless-notice-migrations-finished').removeClass('hidden') } } }) // Migration confirmation dialog $( "#stateless-migration-confirm" ).dialog({ resizable: false, height: "auto", width: 500, modal: true, draggable: false, autoOpen: false, position: { my: "center", at: "center", of: window }, open: function(event, ui) { $('body').css('overflow', 'hidden') $('.ui-dialog-buttonset').find('.ui-button').attr('class', 'button') $('.ui-dialog-buttonset').find('.button').last().addClass('button-primary') $('.ui-dialog').removeClass('ui-corner-all').addClass('stateless-migration-confirm'); $('.ui-dialog-titlebar').removeClass('ui-corner-all'); // backdrop $('.ui-widget-overlay').attr('class', 'media-modal-backdrop'); }, close: function(event, ui) { unblockUI() $('body').css('overflow', 'auto') $('#migration-action').removeClass('processing-action'); $('#migration-action').find('.button.start').removeClass('disabled'); $('#migration-action').find('.description').text( '' ); }, buttons: [ { text: stateless_l10n.start_optimization, click: function() {}, }, { text: stateless_l10n.cancel, click: function() { $( this ).dialog( 'close' ) }, }, ], }) // Migration actions $('#migration-action .button').click(function (e) { e.preventDefault() if ( $(e.target).hasClass('disabled') ) { return; } blockUI() var id = $('#migration-action').data('id') var action = $(e.target).data('action') if ( !id || !action ) { return } if ( action === 'start' ) { $( '#stateless-migration-confirm' ).attr('data-id', id) $('#stateless-migration-confirm').closest('.ui-dialog').find('.ui-dialog-buttonset .ui-button').first().click(function(e) { e.preventDefault() $( '#stateless-migration-confirm' ).dialog('close') var id = $( '#stateless-migration-confirm' ).attr('data-id') var migrationElement = $('#migration-action') migrationElement.addClass('processing-action'); migrationElement.find('.button.start').addClass('disabled'); migrationElement.find('.description').text( stateless_l10n.starting ); wpStatelessBatch.processAction(action, { id, is_migration: true, email: $('input[name="email-notification"]:checked').val(), queue: migrationElement.data('queue'), }, function() { unblockUI(); migrationElement.removeClass('processing-action'); migrationElement.find('.button.start').removeClass('disabled'); migrationElement.find('.description').text( '' ); }) }) $( "#stateless-migration-confirm" ).dialog('open') return } else { wpStatelessBatch.processAction(action, { id, is_migration: true, }, unblockUI) } }.bind(this)) } wpMigrations(jQuery) ================================================ FILE: static/scripts/wp-stateless-settings.js ================================================ jQuery(document).ready(function ($) { jQuery('.nav-tab-wrapper a').on('click', function (e) { e.preventDefault() var tab = jQuery(this).attr('href') if ( tab.indexOf('#') === 0 ) { jQuery(this).addClass('nav-tab-active').siblings().removeClass('nav-tab-active') jQuery(`.stless_settings ${tab}`).addClass('active').siblings().removeClass('active') var url = new URL(window.location.href) url.searchParams.set('tab', tab.replace('#', '')) window.history.replaceState(null, '', url.toString()) } }) $(document).on('click', '.pointer', function (e) { e.stopPropagation() var pointer = $(this) pointer .pointer({ content: '

' + pointer.data('title') + '

' + pointer.data('text') + '

', position: pointer.data('position'), }) .pointer('open') }) $(document).on('click', function () { $('.wp-pointer').hide() }) $(document).on('click', '.wp-pointer', function (e) { e.stopPropagation() }) $(document).on('click', '.stateless-info-button', function (e) { e.stopPropagation() e.preventDefault() var opened = $(this).closest('.stateless-info-heading').hasClass('open') var id = $(this).data('section') if (opened) { $(this).closest('.stateless-info-heading').removeClass('open') $('#' + id).addClass('hidden') } else { $(this).closest('.stateless-info-heading').addClass('open') $('#' + id).removeClass('hidden') } }) // Copy Status Info to clipboard var clipboard = new ClipboardJS('.stateless-info-heading .copy-button') clipboard.on('success', function(e) { $('.stateless-info-copy-success').show(); setTimeout(function() { $('.stateless-info-copy-success').fadeOut(500); }, 5000); }) // Check if API and AJAX is available function setServiceStatus(id, status) { var data = $('.stateless-info-heading .button.copy-button').attr('data-clipboard-text'); $('.stateless-info-heading .button.copy-button').attr( 'data-clipboard-text', data.replace('%' + id + '%', status)); $(`#stateless-info-block-stateless .${id} .value`).text(status); } $.ajax({ method: 'GET', url: window.wp_stateless_configs.api_root + 'status', }) .then(function() { setServiceStatus( 'api_status', window.wp_stateless_configs.text_ok ); }) .fail(function() { setServiceStatus( 'api_status', window.wp_stateless_configs.text_fail ); }) $.ajax({ method: 'POST', url: window.wp_stateless_configs.ajaxurl, data: { action: 'stateless_check_ajax', _ajax_nonce: window.wp_stateless_configs.stateless_check_ajax_nonce, } }) .then(function() { setServiceStatus( 'ajax_status', window.wp_stateless_configs.text_ok ); }) .fail(function() { setServiceStatus( 'ajax_status', window.wp_stateless_configs.text_fail ); }) }) ================================================ FILE: static/scripts/wp-stateless-uploads.js ================================================ /** * Uploads Page specific scripts. * * @author korotkov@UD */ jQuery(document).ready(function(){ jQuery('.sm_inline_sync').one( 'click', function( e ) { var that = jQuery(this); that.html('Please wait...'); jQuery .ajax({ method: 'POST', url: ajaxurl, data: { action: that.data('type') == 'image' ? "stateless_process_image" : "stateless_process_file", id: that.data('id'), size: that.data('size'), _ajax_nonce: stateless_upload.inline_sync_nonce ?? '', } }) .done(function( response ) { if ( response.success ) { if (that.data('reload_page')) { location.reload(); } that.replaceWith( ''+response.data+'' ); } else { that.replaceWith( ''+response.data+'' ); } }) .fail(function( jqXHR, textStatus, message ) { that.replaceWith( ''+message+'. Check your server configuration.' ); }); }); }); ================================================ FILE: static/scripts/wp-stateless.js ================================================ var $wildcards_select = jQuery('.select-wildcards').select2({ tags: true, tokenSeparators: ['/'], createTag: function (params) { var term = jQuery.trim(params.term) if (term === '') { return null } let tags = [ '%site_id%', '%site_url%', '%site_url_host%', '%site_url_path%', '%date_year/date_month%', ] // Remove special chars from tags if (!/^[a-zA-Z0-9_\-.]+$/.test(term) && jQuery.inArray(term, tags) == -1) { term = term.replace(/[^a-zA-Z0-9_\-.]/g, '') } return { id: term, text: term, } }, templateSelection: function (state) { // Add slash at the en of the tag return state.text }, insertTag: function (data, tag) { // Insert the tag at the end of the results data.push(tag) }, }) jQuery('.select-wildcards').on('select2:select', function (evt) { var element = evt.params.data.element var $element = jQuery(element) let $element_value = $element.value $element.detach() jQuery(this).append($element) /** * add slash after tag */ if ($element_value !== '/') { // Create the DOM option that is pre-selected by default var newState = new Option('/', '/', true, true) jQuery(newState).prop('disabled', true) // Append it to the select jQuery(this).append(newState) } jQuery(this).trigger('change') prepare_preview_url() }) jQuery('.select-wildcards').on('select2:unselect', function (evt) { if (evt.params.data.id === '/') { var element = evt.params.data.element var $element = jQuery(element) $element.detach() } prepare_preview_url() }) function prepare_preview_url() { let root_dir = '' let selected_wildcards = jQuery('.select-wildcards').val() if (selected_wildcards !== null) { root_dir = selected_wildcards.join('/') } jQuery('#sm_root_dir').val(root_dir) jQuery('#sm_root_dir').trigger('change') } function replace_wildcard_to_the_end(wildcards, remove_slashes = false) { if (remove_slashes) { jQuery('.select-wildcards > option').each(function () { if (this.value == '/') { jQuery(this).detach() } }) } wildcards.forEach(function (wildcard) { wildcard_exist = false jQuery('.select-wildcards > option').each(function () { if (this.value === wildcard && this.value !== '/') { jQuery(this).detach() jQuery('.select-wildcards').append(jQuery(this)) wildcard_exist = true } }) if (!wildcard_exist) { var newState = new Option('/', '/', true, true) jQuery(newState).prop('disabled', true) // Append it to the select jQuery('.select-wildcards').append(newState) } }) } // Application var wpStatelessSettingsApp = { sm: {}, backup: {}, is_ssl: false, // Show notices for readonly fields showNotice: function (field) { if (this.sm.readonly && this.sm.readonly[field]) { var slug = this.sm.readonly[field] jQuery(`#notice-${field}`).html(this.sm.strings[slug]) jQuery(`[name="sm[${field}]"]`).prop('disabled', true) } else { jQuery(`#notice-${field}`).html('') jQuery(`[name="sm[${field}]"]`).prop('disabled', false) } }, showSupportedTypes: function () { value = jQuery('#sm_body_rewrite').val() if ( ['true', 'enable_editor', 'enable_meta'].indexOf(value) > -1 ) { jQuery('.supported-file-types').show() } else { jQuery('.supported-file-types').hide() } }, setIsSSL: function () { this.is_ssl = jQuery('#custom_domain').val().indexOf('https://') === 0 if (this.is_ssl) { jQuery('.notice-is-ssl').show() } else { jQuery('.notice-is-ssl').hide() } }, getRadioValue: function(name) { return jQuery(`input[name="${name}"]:checked`).val() }, enableHashifyFileName: function () { var mode = this.getRadioValue('sm[mode]') if ( ['stateless', 'ephemeral'].indexOf(mode) > -1 && this.sm.readonly['hashify_file_name'] != 'constant' ) { this.backup['hashify_file_name'] = jQuery('#cache_busting').val() jQuery('#cache_busting').val('true') } else if ( this.backup['hashify_file_name'] ) { jQuery('#cache_busting').val( this.backup['hashify_file_name'] ) } if ( ['stateless', 'ephemeral'].indexOf(mode) > -1 ) { jQuery('#cache_busting').prop('disabled', true) } else { this.showNotice('hashify_file_name') } if ( ['stateless', 'ephemeral'].indexOf(mode) > -1 && this.sm.readonly['hashify_file_name'] != 'constant') { jQuery('#notice-hashify_file_name-mode').show() } else { jQuery('#notice-hashify_file_name-mode').hide() } }, enableDynamicImageSupport: function () { var mode = this.getRadioValue('sm[mode]') if ( mode == 'stateless' && this.sm.readonly['dynamic_image_support'] != 'constant' ) { this.backup['dynamic_image_support'] = jQuery('#dynamic_image_support').val() jQuery('#dynamic_image_support').val('false') } else if ( this.backup['dynamic_image_support'] ) { jQuery('#dynamic_image_support').val( this.backup['dynamic_image_support'] ) } if (mode == 'stateless') { jQuery('#dynamic_image_support').prop('disabled', true) } else { this.showNotice('dynamic_image_support') } if (mode == 'stateless' && this.sm.readonly['dynamic_image_support'] != 'constant') { jQuery('#notice-dynamic_image_support-mode').show() } else { jQuery('#notice-dynamic_image_support-mode').hide() } }, switchBucketFolderType: function() { var value = jQuery('#sm_root_dir').val() var folderType = jQuery('#sm_bucket_folder_type').val() switch (value) { case '%date_year/date_month%': folderType = 'single-site' break; case 'sites/%site_id%/%date_year/date_month%': folderType = 'multi-site' break; case '': if ( this.sm.network_admin ) folderType = '' break; default: folderType = 'custom' } if ( jQuery('#sm_bucket_folder_type').val() != folderType ) { jQuery('#sm_bucket_folder_type').val( folderType) } setTimeout(function () { jQuery('#permalink_structure').trigger('change') }, 1) }, switchRootDir: function() { var value = jQuery('#sm_bucket_folder_type').val() switch (value) { case 'single-site': replace_wildcard_to_the_end(['/', '%date_year/date_month%', '/'], true) $wildcards_select .val(['/', '%date_year/date_month%', '/']) .trigger('change') break; case 'multi-site': replace_wildcard_to_the_end( ['/', 'sites', '/', '%site_id%', '/', '%date_year/date_month%', '/'], true ) $wildcards_select .val([ '/', 'sites', '/', '%site_id%', '/', '%date_year/date_month%', '/', ]) .trigger('change') break; case '': if ( wp_stateless_settings.network_admin ) { $wildcards_select.val(null).trigger('change') } break; } prepare_preview_url() }, generatePreviewUrl: function() { var host = 'https://storage.googleapis.com/' var hash = jQuery('#cache_busting').val() == 'true' ? Date.now().toString(36) + '-' : '' var custom_domain = jQuery('#custom_domain').val().toString() var root_dir = jQuery('#sm_root_dir').val().toString() var bucket = jQuery('#bucket_name').val().toString() jQuery.each(this.sm.wildcards, function (index, item) { var reg = new RegExp(index, 'g') root_dir = root_dir.replace(reg, item[0]) }) var tags = [ '%date_year%', '%date_month%', '%site_id%', '%site_url%', '%site_url_host%', '%site_url_path%', ] var value_splitted = root_dir.split('/') for (var i = 0; i < value_splitted.length; i++) { if ( !/^[a-zA-Z0-9_\-.]+$/.test(value_splitted[i]) && value_splitted[i] != '' && jQuery.inArray(value_splitted[i], tags) == -1 ) { value_splitted[i] = value_splitted[i].replace(/[^a-zA-Z0-9_\-.]/g, '') } } root_dir = value_splitted.join('/') root_dir = root_dir.replace(/(\/+)/g, '/') root_dir = root_dir.replace(/^\//, '') root_dir = root_dir.replace(/\/$/, '') if (root_dir) { root_dir = root_dir + '/' } custom_domain = custom_domain.replace(/\/+$/, '') // removing trailing slashes custom_domain = custom_domain.replace(/https?:\/\//, '') // removing http:// or https:// from the beginning. host += bucket.length > 0 ? bucket : '{bucket-name}' if ( custom_domain !== 'storage.googleapis.com' && bucket.length > 0 && custom_domain.length > 0 && (this.is_ssl || custom_domain == bucket) ) { host = this.is_ssl ? 'https://' : 'http://' // bucket name will be host host += custom_domain } host += '/' + root_dir + hash + 'your-image-name.jpeg' jQuery('#file_url_grp_preview').val(host) }, showCustomEmail: function () { if( jQuery('#sm_status_email_type').val() == 'custom' ) { jQuery('.sm-status-email-address').show() } else { jQuery('.sm-status-email-address').hide() } }, // Init application init: function () { this.sm = wp_stateless_settings || {} this.sm.readonly = this.sm.readonly || {} var readonly = Object.keys(this.sm.readonly); for (var key of readonly) { this.showNotice(key) } if (this.sm.network_admin) { jQuery('#cache_busting').val('true') this.sm.readonly.hashify_file_name = true } // Disable root dir editing if it's readonly if (this.sm.readonly['root_dir']) { $wildcards_select.prop('disabled', true) jQuery('#sm_bucket_folder_type').prop('disabled', true) } // Show supported file types jQuery('#sm_body_rewrite').on('change', this.showSupportedTypes) this.showSupportedTypes() // Check if custom domain is SSL jQuery('#custom_domain').on('change', this.setIsSSL.bind(this)) this.setIsSSL() // Check if hashify file name is enabled jQuery('[name="sm[mode]"').on('change', this.enableHashifyFileName.bind(this)) this.enableHashifyFileName() // Check if dynamic image support is enabled jQuery('[name="sm[mode]"').on('change', this.enableDynamicImageSupport.bind(this)) this.enableDynamicImageSupport() // Switch folder type depending on root dir jQuery('#sm_root_dir').on('change', this.switchBucketFolderType.bind(this)) this.switchBucketFolderType() // Update root dir depending on folder type jQuery('#sm_bucket_folder_type').on('change', this.switchRootDir) // Generate preview URL jQuery('#bucket_name').on('change', this.generatePreviewUrl.bind(this)) jQuery('#sm_root_dir').on('change', this.generatePreviewUrl.bind(this)) jQuery('#custom_domain').on('change', this.generatePreviewUrl.bind(this)) this.generatePreviewUrl() // Update root dir depending on folder type jQuery('#sm_status_email_type').on('change', this.showCustomEmail) this.showCustomEmail() } }; wpStatelessSettingsApp.init(); // Processing application wpStatelessProcessingApp = { errors: [], canRun: true, processes: [], token: window.wp_stateless_configs.REST_API_TOKEN, apiRoot: window.wp_stateless_configs.api_root + 'sync/', blockUI: function () { this.canRun = false this.processes.map( function (process) { process.refreshButtons() }) }, unblockUI: function () { this.canRun = true this.processes.map( function (process) { process.refreshButtons() }) }, /** * Prevent global changes */ preventChanges: function () { var isRunning = this.processes.find( function (process) { return process.is_running }) ? true : false jQuery('#save-settings,#save-compatibility').prop('disabled', isRunning) }, /** * Handle errors display */ addError: function (error) { this.errors.push(error) jQuery('#stless_sync_tab #errors').show() var html = this.errors.map(function (error) { return '
  • ' + error + '
  • ' }) jQuery('#stless_sync_tab #errors ul').html(html) }, /** * Process response error */ processError: function (error) { var message = error && error.responseJSON && error.responseJSON.message ? error.responseJSON.message : window.stateless_l10n.something_went_wrong this.addError(message) }, /** * Load process data */ init: function () { var that = this that.blockUI() jQuery.ajax({ method: 'GET', url: that.apiRoot + 'getProcesses', headers: { 'x-wps-auth': that.token, }, }) .done(function (response) { if (response && response.data) { var processes = response.data || {} for (var i in processes) { var process = new ProcessingClass(processes[i], that) process.refreshBox() that.processes.push(process) } } else { that.addError(window.stateless_l10n.something_went_wrong) } }) .fail(function (error) { that.processError(error) }) .always(function () { that.unblockUI() }) }, /** * Refresh the process data */ refreshProcess: function (process) { var that = this jQuery.ajax({ method: 'GET', url: that.apiRoot + 'getProcess/' + String(window.btoa(process.id)).replace(/=+/, ''), headers: { 'x-wps-auth': that.token, }, }) .done(function (response) { if ( response && response.data && response.ok ){ if (!response.data.is_running) { process.stopPolling() process.queued_items = process.getProgressTotal() process.processed_items = process.getProgressTotal() setTimeout(function () { Object.assign(process, response.data) }, 3000) } else { Object.assign(process, response.data) } process.refreshBox() } }) .fail(function (error) { process.stopPolling() that.processError(error) }) }, /** * Run the process */ runProcess: function (process) { var that = this that.blockUI() var data = { id: process.id, limit: process.limit, order: process.order, } jQuery.ajax({ method: 'POST', url: that.apiRoot + 'run', headers: { 'x-wps-auth': that.token, 'Content-Type': 'application/json', }, dataType: 'json', data: JSON.stringify(data), }) .then(function (response) { if (response && response.ok) { process.is_running = true process.is_stopping = false process.refreshBox() process.startPolling() } else { var message = response && response.data && response.data.message ? response.data.message : window.stateless_l10n.something_went_wrong that.addError(message) } }) .fail(function (error) { process.stopPolling() that.processError(error) }) .always(function () { that.unblockUI() }) }, /** * Stop the process */ stopProcess: function (process) { var that = this process.is_stopping = true var data = { id: process.id, } jQuery.ajax({ method: 'POST', url: that.apiRoot + 'stop', headers: { 'x-wps-auth': that.token, 'Content-Type': 'application/json', }, dataType: 'json', data: JSON.stringify(data), }) .done(function (response) { if (response && response.ok) { } }) .fail(function (error) { that.processError(error) }) } } wpStatelessProcessingApp.init() /** * ProcessingClass * * @param {*} data */ function ProcessingClass(data, app) { this.id = '' this.total_items = 0 this.queued_items = 0 this.processed_items = 0 this.is_running = false this.limit = 0 this.limitEnabled = false this.order = 'desc' // Build an instance Object.assign(this, data) this.app = app this.interval = null this.htmlId = this.id.replace(/[^a-zA-Z0-9]/g, '') // remove double backslashes this.htmlBox = jQuery(`[data-id="${this.htmlId}"]`) /** * Start polling for changes */ this.startPolling = function () { var that = this this.stopPolling() this.interval = setInterval(function () { that.app.refreshProcess(that) }, 5000) } /** * Stop polling for changes */ this.stopPolling = function () { clearInterval(this.interval) } /** * Get Progress bar possible total */ this.getProgressTotal = function () { if (this.limit > 0 && this.limit <= this.total_items) { return this.limit } return this.total_items } /** * Get Total queued count */ this.getQueuedTotal = function () { return this.queued_items > this.total_items ? this.total_items : this.queued_items } /** * Get processed total */ this.getProcessedTotal = function () { return this.processed_items > this.getQueuedTotal() ? this.getQueuedTotal() : this.processed_items } /** * Calculate percentage */ this.percentage = function (part, base) { return parseInt((100 / base) * part) + '%' } /** * Stop the process */ this.refreshProgress = function () { this.htmlBox.find('.legend .total span').html( this.getProgressTotal() ) this.htmlBox.find('.legend .queued span').html( this.getQueuedTotal() ) this.htmlBox.find('.legend .processed span').html( this.processed_items ) this.htmlBox.find('.bar.total').css({ 'background-color': this.getProgressTotal() == this.getProcessedTotal() ? '#02ae7a' : false }) this.htmlBox.find('.bar.queued').css({ width: this.percentage( this.getQueuedTotal(), this.getProgressTotal() ), 'background-color': this.getProgressTotal() == this.getProcessedTotal() ? '#02ae7a' : false }) this.htmlBox.find('.bar.processed').css({ width: this.percentage( this.getProcessedTotal(), this.getQueuedTotal() ), 'background-color': this.getProgressTotal() == this.getProcessedTotal() ? '#02ae7a' : false }) if (this.notices && this.notices.length) { this.htmlBox.find('.progress-notice').show() for (var i in this.notices) { this.htmlBox.find('.progress-notice').append('

    ' + this.notices[i] + '

    ') } } } /** * Check if Run button can be pressed */ this.canRun = function () { return this.total_items > 0 && !this.is_running && this.app.canRun } /** * Check if Stop button can be pressed */ this.canStop = function () { return this.is_running && !this.is_stopping } /** * Refresh buttons state */ this.refreshButtons = function () { if ( this.canStop() ) { this.htmlBox.find('.actions .button-secondary').removeClass('disabled') } else { this.htmlBox.find('.actions .button-secondary').addClass('disabled') } if ( this.canRun() ) { this.htmlBox.find('.actions .button-primary').removeClass('disabled') } else { this.htmlBox.find('.actions .button-primary').addClass('disabled') } } /** * Refresh the progress data */ this.refreshBox = function () { this.htmlBox.find('.inside ul span').html(this.total_items) if (this.is_running) { this.startPolling() this.htmlBox.find('.dashicons-update').css('display', 'inline-block') this.htmlBox.find('.progress').show() this.htmlBox.find('.limit_enabled').prop('disabled', true) this.htmlBox.find('.limit_field input').prop('disabled', true) this.htmlBox.find('.order_value').prop('disabled', true) this.refreshProgress() } else { this.stopPolling() this.htmlBox.find('.dashicons-update').css('display', 'none') this.htmlBox.find('.progress').hide() this.htmlBox.find('.progress-notice').hide() this.htmlBox.find('.limit_enabled').prop('disabled', false) this.htmlBox.find('.limit_field input').prop('disabled', !this.limitEnabled) this.htmlBox.find('.order_value').prop('disabled', false) } if (this.limitEnabled || this.limit > 0) { this.htmlBox.find('.limit_field input').css('visibility', 'visible') } else { this.htmlBox.find('.limit_field input').css('visibility', 'hidden') } this.refreshButtons() this.app.preventChanges() } /** * Enable limit handler */ this.enableLimit = function (event) { this.limitEnabled = jQuery(event.target).is(':checked') this.limit = 0 this.htmlBox.find('.limit_field input').val(0) this.refreshBox() } /** * Change limit handler */ this.changeLimit = function (event) { this.limit = jQuery(event.target).val() } /** * Change sorting handler */ this.changeOrder = function (event) { this.order = jQuery(event.target).val() } /** * Run the process */ this.run = function () { if ( this.canRun() ) { this.app.runProcess(this) } } /** * Stop the process */ this.stop = function () { if ( this.canStop() ) { this.app.stopProcess(this) } } /** * Bind event handlers */ jQuery(document).on('change', `[data-id="${this.htmlId}"] .limit_enabled`, this.enableLimit.bind(this)) this.htmlBox.find('.limit_field input').change( this.changeLimit.bind(this) ) this.htmlBox.find('.order_value').change( this.changeOrder.bind(this) ) this.htmlBox.find('.actions .button-primary').click( this.run.bind(this) ) this.htmlBox.find('.actions .button-secondary').click( this.stop.bind(this) ) } ================================================ FILE: static/styles/error-notice.css ================================================ .stateless-admin-notice.error, .stateless-admin-notice.notice, .stateless-admin-notice.admin-error { position: relative; display: block; background-image: url('../images/stateless.svg'); background-repeat: no-repeat; background-size: 40px 40px; background-position: 15px center; padding: 15px 38px 15px 70px; background-color: #fff; border: 1px solid #ccd0d4; border-left-width: 4px; box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04); } .stateless-admin-notice.error, .stateless-admin-notice.admin-error { border-left-color: #fc2323 !important; } .stateless-admin-notice.notice { border-left-color: #fc5922 !important; } .stateless-admin-notice .icon { float: left; width: 30px; height: 30px; } .stateless-admin-notice .description { margin-top: 7px; } .stateless-admin-notice .description ul { margin: 0px; } .stateless-admin-notice ul { margin: 0.5em 0; } .stateless-admin-notice .inner-contaner { float: left; } .stateless-admin-notice .title { font-weight: bold; } .stateless-admin-notice a { text-decoration: underline; } .stateless-admin-notice a.notice-dismiss.dismiss, .stateless-admin-notice a.button-action { text-decoration: none !important; } .stateless-admin-notice a.button-action { right: 40px; } .stateless-admin-notice.hidden { display: none !important; } /** Responisve Design: */ /* Extra small devices (phones, 600px and down) */ @media only screen and (max-width: 600px) { } /* Small devices (portrait tablets and large phones, 600px and up) */ @media only screen and (min-width: 600px) { } /* Medium devices (landscape tablets, 768px and up) */ @media only screen and (min-width: 768px) { } /* Large devices (laptops/desktops, 992px and up) */ @media only screen and (max-width: 992px) { .stateless-admin-notice .description { margin-top: 15px; } .stateless-admin-notice a.notice-dismiss.dismiss, .stateless-admin-notice a.button-action { margin-top: 12px; } } /* Large devices (laptops/desktops, 992px and up) */ @media only screen and (min-width: 992px) { .stateless-admin-notice.error, .stateless-admin-notice.notice { background-position: 10px center; padding: 15px 193px 15px 60px; } .stateless-admin-notice a.notice-dismiss.dismiss, .stateless-admin-notice a.button-action { position: absolute; top: 50%; transform: translateY(-50%); } .stateless-admin-notice a.notice-dismiss.dismiss:focus { box-shadow: none; } .stateless-admin-notice a.notice-dismiss.dismiss:active, .stateless-admin-notice a.button-action:active { transform: translateY(-48%) !important; } } /* Extra large devices (large laptops and desktops, 1200px and up) */ @media only screen and (min-width: 1200px) { } ================================================ FILE: static/styles/wp-stateless-addons.css ================================================ .addons-filter .subsubsub { float: none; } .addons-list { display: flex; flex-wrap: wrap; margin-top: 20px; justify-content: flex-start; } .addons-list .addon-card { position: relative; display: flex; flex-direction: column; width: 46%; background-color: #fff; border: 1px solid #e5e5e5; margin: 10px; padding: 20px; box-sizing: border-box; } .addons-list .addon-icon { display: flex; align-items: center; } .addons-list .addon-icon { padding: 0 15px; } .addons-list .addon-icon a { display: block; width: 80px; height: center; } .addons-list .addon-icon img { max-width: 100%; max-height: 100%; min-width: 100%; min-height: 100%; } .addons-list .addon-card .addon-head { display: flex; flex-grow: 1; } .addons-list .addon-card .addon-title a { color: inherit; text-decoration: none; } .addons-list .addon-card .addon-title a:hover, .addons-list .addon-card .addon-title a:active { color: #2271b1; text-decoration: underline; } .addons-list .addon-card .addon-description { margin-bottom: 20px; } .addons-list .addon-actions { display: flex; justify-content: flex-start; width: 100%; } .addons-list .addon-actions .hs-wrap { width: 110px; display: flex; justify-content: center; align-items: center; } .addons-list .addon-actions .addon-secondary-link { text-decoration: none; color: #3c434a; margin-right: 10px; } .addons-list .addon-actions .addon-secondary-link:hover span, .addons-list .addon-actions .addon-secondary-link:active span { color: #3c434a; } .addons-list .addon-actions .addon-secondary-link:hover, .addons-list .addon-actions .addon-secondary-link:active { color: #2271b1; } .addons-list .addon-actions .addon-secondary-actions { width: 110px; display: flex; justify-content: flex-start; align-items: center; } .addons-list .addon-actions .addon-secondary-link { display: flex; } .addons-list .addon-actions .addon-secondary-link span { margin-right: 5px; } .addons-list .addon-actions .addon-secondary-link img { width: 20px; height: auto; margin-right: 5px; } .addons-list .addon-card .addon-status { position: absolute; top: 10px; right: 10px; font-weight: bold; color: #fff; border-radius: 20px; padding: 5px 10px; } .addons-list .addon-card.addon-card.recommended .addon-status { background-color: #f05323; } .addons-list .addon-card.addon-card.active .addon-status { background-color: #00a32a; } @media screen and (min-width: 1450px) { .addons-list .addon-card { width: 31%; } } @media screen and (min-width: 769px) and (max-width: 1050px) { .addons-list .addon-card .addon-actions { flex-direction: column; align-items: center; } .addons-list .addon-card .addon-actions .hs-wrap { width: 100%; } .addons-list .addon-card .addon-actions .addon-secondary-actions { width: 100%; justify-content: center; margin-top: 20px; } } @media screen and (max-width: 768px) { .addons-list .addon-card { width: 100%; } } @media screen and (max-width: 460px) { .addons-list .addon-card .addon-actions { flex-direction: column; align-items: center; } .addons-list .addon-card .addon-actions .hs-wrap { width: 100%; } .addons-list .addon-card .addon-actions .addon-secondary-actions { width: 100%; justify-content: center; margin-top: 20px; } } ================================================ FILE: static/styles/wp-stateless-settings.css ================================================ /* settings css */ .regular-text { width: 50em; } .sm-notice { background-color: #fff8e5; margin: 20px 0px 0px; padding: 15px; border-left: 3px solid #f79191; } #stateless-settings-page-title { margin-bottom: 20px; } .stateless-settings-docs-link { display: inline-block; text-decoration: none; } .stateless-settings-docs-link:focus, .stateless-settings-docs-link:active { outline: none; box-shadow: none; color: #2271b1; } .stateless-settings-docs-link .dashicons-editor-help:before { font-size: 30px; vertical-align: middle; } #service_account_json { height: 20em; } .stless_settings_content { display: none; } .stless_settings_content.active { display: block; } .nav-tab-active:focus { box-shadow: none; } .stless_settings_content tr td h4:first-of-type { margin-top: 5px; } #stless_supports_tab { padding: 20px 0; } .stless_settings_content tr { position: relative; display: block; } .stless_settings_content tr:after { border-top: 1px solid #ddd; border-bottom: 1px solid #fafafa; position: absolute; left: 0px; bottom: 0px; width: 100%; height: 0px; content: ''; } .stless_settings_content .postbox-container { width: 33%; } .stless_settings_content .postbox .hndle { cursor: default; } .stless_settings_content .postbox .hndle .title-holder .label { font-size: 0.7em; text-transform: uppercase; border: 1px solid darkorange; padding: 2px; line-height: 2; border-radius: 3px; margin-left: 5px; } .stless_settings_content .postbox .hndle a { font-size: 20px; } .stless_settings_content .postbox .inside { margin-bottom: 0; } .stless_settings_content .postbox .options, .stless_settings_content .postbox .progress, .stless_settings_content .postbox .progress-notice { margin-bottom: 1em; } .stless_settings_content .postbox .progress-notice { color: darkred; } .stless_settings_content .postbox .actions { text-align: right; } .stless_settings_content .postbox .progress .bar-wrapper .legend { display: flex; justify-content: space-between; } .stless_settings_content .postbox .progress .bar-wrapper .bar { box-sizing: border-box; transition: width 1s, background-color 2s; } .stless_settings_content .postbox .progress .bar-wrapper .bar.total { background-color: #0278ae; padding: 2px; } .stless_settings_content .postbox .progress .bar-wrapper .total { color: #0278ae; } .stless_settings_content .postbox .progress .bar-wrapper .bar.queued { background-color: #51adcf; padding: 2px; } .stless_settings_content .postbox .progress .bar-wrapper .queued { color: #51adcf; } .stless_settings_content .postbox .progress .bar-wrapper .bar.processed { background-color: #a5ecd7; height: 5px; } .stless_settings_content .postbox .progress .bar-wrapper .processed { color: #a5ecd7; } .processing-hint { margin-top: 0; } .wpStateLess-support { width: 60%; margin: 0 auto; display: flex; } .wpStateLess-sprt-plan { float: left; width: 45%; margin: 0px 15px; text-align: center; border: 1px solid #e4e4e4; box-shadow: 0px 5px 35px -19px #000; } .wpStateLess-sprt-plan .wpStateLess-plan-name p { font-size: 30px; } .wpStateLess-sprt-plan ul li { border-top: 1px solid #e4e4e4; padding: 5px; } #stless_sync_tab #errors, #stless_sync_tab .dashicons-update, #stless_sync_tab .progress, #stless_sync_tab .progress-notice { display: none; } #stless_sync_tab .limit_field input { visibility: hidden; } #stless_sync_tab .processes-holder .postbox-container { float: none; } /* Angular styles */ .ng-hide:not(.ng-hide-animate) { display: none !important; } .hbspt-form { padding-top: 20px; } .hbspt-form { margin-left: 10px; } .hbspt-form input.hs-input[type='checkbox'] { border: 1px solid #b4b9be; height: 16px; width: 16px; margin-top: -2px; } .permalink-structure h4 { margin: 1.33em 0 !important; } .sm-wildcards .select2-container { width: 100% !important; } .sm-wildcards .select2-selection--multiple { height: 28px !important; } .select2-dropdown li { margin-bottom: 0px !important; } /* pillbox li container item */ .select2-selection__choice { position: relative; padding-left: 15px; /* to account for the 'x' no longer taking up space */ } /* the 'x' */ .select2-selection__choice__remove { position: absolute; left: 0; right: 0; /* to fill width */ padding-left: 5px; /* whatever matches your pillbox padding */ color: transparent !important; /* hide the x */ } .select2-container--default .select2-results__option[aria-disabled='true'] { display: none; } .file_url_block label, .file_url_block input { width: 100%; } .stless_settings_content .loading { -webkit-animation: wps-loading-spin 1.4s infinite linear; animation: wps-loading-spin 1.4s infinite linear; } @-webkit-keyframes wps-loading-spin { 0% { -webkit-transform: rotate(0deg); transform: rotate(0deg); } 100% { -webkit-transform: rotate(360deg); transform: rotate(360deg); } } @keyframes wps-loading-spin { 0% { -webkit-transform: rotate(0deg); transform: rotate(0deg); } 100% { -webkit-transform: rotate(360deg); transform: rotate(360deg); } } ================================================ FILE: static/styles/wp-stateless-setup-wizard.css ================================================ .wp-admin.media_page_stateless-setup #wpcontent, .wp-admin.settings_page_stateless-setup #wpcontent { padding-left: 0px; } #console-stateless-wizard { position: absolute; top: 0; left: 0; bottom: 0; right: 0; height: calc(100vh - 2rem); width: 100%; } ================================================ FILE: static/styles/wp-stateless-status.css ================================================ #stless_status_tab .hndle { margin-top: 5px; } #stless_status_tab .hndle-notice { padding: 0 12px; } #stless_status_tab .hndle-notice p { margin: 0; } #stless_status_tab .hndle-notice ul { list-style: disc; padding-left: 20px; } #stless_status_tab .stateless-info-heading { display: flex; justify-content: space-between; align-items: center; } #stless_status_tab .stateless-info-heading .copy-button { background-color: #fff; font-weight: 400; } .stateless-info-copy-success { line-height: 30px; margin-right: 5px; color: #007017; font-weight: normal; display: none; } /* Info table */ #stateless-info { border: 1px solid #c3c4c7; } .stateless-info-heading { margin: 0; font-size: 13px; border-top: 1px solid #c3c4c7; } .stateless-info-heading:first-child { border-top: none; } .stateless-info-button { display: flex; align-items: center; justify-content: space-between; background: #fff; border: 0; color: #2c3338; cursor: pointer; padding: 13px 20px; text-align: left; width: 100%; user-select: auto; } .stateless-info-button:hover, .stateless-info-button:active { background-color: #f6f7f7; } .stateless-info-heading.open .dashicons { transform: rotate(180deg); } .stateless-info-block { padding: 13px 20px; } .stateless-info-block tr { display: table-row; } .stateless-info-block tr:after { display: none; } .stateless-info-block td { width: 50%; } .stateless-info-table-extended-value { display: flex; flex-direction: row; justify-content: space-between; } .stateless-info-table-extended-value:last-child { cursor: pointer; } .stateless-info-table-extended-value em { display: none; } .stateless-info-table-extended-value .dashicons { margin-right: 5px; } /* Migrations confirmation dialog */ #stateless-migration-confirm label { display: block; padding-left: 5px; margin-top: 5px; } .stateless-migration-confirm.ui-widget { font-family: inherit; font-size: inherit; padding: 0; border: 0; } .stateless-migration-confirm .ui-dialog-titlebar { padding: 8px 18px; position: relative; } .stateless-migration-confirm .ui-widget .ui-widget { font-size: inherit; font-family: inherit; } .stateless-migration-confirm.ui-widget .ui-widget-button { font-size: inherit; font-family: inherit; } .stateless-migration-confirm .ui-dialog-buttonpane { padding: 16px; } .stateless-migration-confirm .ui-dialog-buttonset button { margin: .5em .4em .5em 0; font-family: inherit; } .stateless-migration-confirm .ui-widget-content, .stateless-migration-confirm .ui-widget-content .ui-widget-content { color: inherit; } .stateless-migration-confirm .ui-widget-header { border-top: none; border-left: none; border-right: none; } .stateless-migration-confirm .ui-icon-closethick { left: -500%; } .stateless-migration-confirm .ui-button.ui-dialog-titlebar-close { margin: 0; height: 100%; width: 53px; border-left: 1px solid #dcdcde; } .stateless-migration-confirm .ui-dialog-titlebar-close:before { line-height: 53px; } /* Migrations section (Data Optimization) */ #migration-action .main { margin-top: 20px; display: flex; justify-content: space-between; } #migration-action .actions { text-align: left; } #migration-action .actions .button { display: none; } #migration-action.can-start .actions .button.start { display: inline-block; } #migration-action.can-pause .actions .button.pause { display: inline-block; } #migration-action.can-resume .actions .button.resume { display: inline-block; } #migration-action .description { flex: 1; white-space: nowrap; margin-right: 20px; text-align: right; } /* Migrations section (Data updates) - progress section */ #migration-action .progress-wrap { display: flex; flex-direction: row; justify-content: space-between; align-items: center; min-height: 20px; min-width: 40%; } #migration-action .progress { display: none; flex: 1; margin-bottom: 0; position: relative; overflow: hidden; height: 20px; background-size: 56px 20px; background-color: #dcdcde; background-image: repeating-linear-gradient( -45deg, transparent, transparent 10px, rgba(255,255,255,.7) 10px, rgba(255,255,255,.7) 20px ); } #migration-action .progress .bar { position: absolute; z-index: 20; top: 0; left: 0; bottom: 0; height: 100%; width: 0; background-color: rgba(34, 113, 177, 0.8); background-size: 56px 20px; background-image: repeating-linear-gradient( -45deg, transparent, transparent 10px, rgba(255,255,255,.4) 10px, rgba(255,255,255,.4) 20px ); transition: all 0.5s ease; } @keyframes stateless-progress { from {background-position: 0 0;} to {background-position: 56px 0; } } #migration-action.can-pause .progress, #migration-action.can-resume .progress, #migration-action.processing-action .progress { display: block; } #migration-action.can-pause .progress, #migration-action.can-pause .progress .bar{ animation: stateless-progress 3s linear infinite; } #migration-action .progress .percent { position: absolute; width: 100%; height: 100%; line-height: 20px; text-align: center; font-weight: bold; z-index: 30; } ================================================ FILE: static/styles/wp-stateless.css ================================================ /** * * */ td.image-icon img.wp-stateless-media-item { } .submitbox span.sm-view-link { float: right; } .wp-stateless-media-options input.sm_service_account_name { width: 40em; } .wp-stateless-media-options input.sm_key_file_path { width: 40em; } .sm-mode small.description { display: block; margin-top: 5px; } .key_type{ margin-top: 4px; margin-bottom: 0; } .key_type>label{ vertical-align: top; } .key_type>div{ width:auto; padding-top: 3px; } .key_type ._sm_key_file_path{ margin-top: 7px; } .key_type .sm_key_json, .key_type .sm_key_file_path{ display: block; width: 40em; max-width: 100%; } .key_type .sm_key_json{ height:200px; } #go { margin-top: 25px; } #go .option { margin-bottom: 5px; } #go .status { color: grey; font-family: monospace; margin-bottom: 10px; margin-top: 10px; } #go .buttons { margin-top: 10px; } #go ol { margin: 0 0 0 25px; font-family: monospace; } #go #regenthumbs-bar { margin-bottom: 10px; } .clearfix:after { content: " "; /* Older browser do not support empty content */ visibility: hidden; display: block; height: 0; clear: both; } #sm-attachment-metabox .rwmb-input input { max-width: 90%; } #sm-attachment-metabox a i.dashicons { text-decoration: none; } #sm-attachment-metabox a i.dashicons-external { font-size: 25px; } #sm-attachment-metabox a i.dashicons-image-rotate { margin-top: 4px; } ================================================ FILE: static/views/.gitkeep ================================================ ================================================ FILE: static/views/addons-tab.php ================================================

    domain); ?>

    GitHub or Support page.", 'https://github.com/udx/wp-stateless/issues', 'https://wordpress.org/support/plugin/wp-stateless/' ), ud_get_stateless_media()->domain ); ?>

    $addon) : ?>
    status) : ?>
    status; ?>

    title; ?>

    description; ?>
    activate_link) ) : ?> Activate hubspot_link) ) : ?> Download Download
    ================================================ FILE: static/views/compatibility-tab.php ================================================

    domain); ?>

    Submit feedback and let us know your issue!", ud_get_stateless_media()->domain), "https://wordpress.org/support/plugin/wp-stateless/" ); ?>

    id); $disabled = $module->is_constant || ($module->is_network_override || !$module->is_plugin_active || !$module->is_mode_supported) && !is_network_admin(); $disabled = $disabled ? 'disabled="true"' : ''; ?>

    is_plugin_active && $module->is_plugin && $module->is_mode_supported ) : ?> domain); ?> is_plugin_active && $module->is_theme && $module->is_mode_supported ) : ?> domain); ?> is_mode_supported ) : ?> domain), $module->mode ); ?> is_constant ) : ?> domain); ?> is_network_override ) : ?> domain); ?> description?>

    'save-compatibility')); ?>
    ================================================ FILE: static/views/error-notice.php ================================================
    ' . esc_html(implode( ' | ', $data['action_links'] )) . '

    '; endif; ?>
    ================================================ FILE: static/views/processing_interface.php ================================================
    domain); ?>

      domain) ?>: domain) ?>

      name; ?>
      helper) : ?>

      • domain) ?>: total_items; ?>
      allow_limit) : ?>
      allow_sorting) : ?>
      domain) ?>: domain) ?>: domain) ?>:
       
      ================================================ FILE: static/views/settings-sections/file-url.php ================================================ domain); ?>
      domain); ?>

      domain); ?>

      domain); ?>



      domain); ?>

      domain)); ?> configure a CNAME. Be advised that the bucket name and domain name must match exactly, and HTTPS is not supported with a custom domain out of the box.', ud_get_stateless_media()->domain), 'https://cloud.google.com/storage/docs/xml-api/reference-uris#cname'); ?>


      domain); ?>

      Required by Stateless and Ephemeral modes. Override with the WP_STATELESS_MEDIA_CACHE_BUSTING constant.", ud_get_stateless_media()->get_docs_page_url('docs/constants/#wpstatelessmediacachebusting')), ud_get_stateless_media()->domain); ?> domain); ?>

      domain); ?>

      Not available in Stateless Mode.", ud_get_stateless_media()->domain); ?> domain); ?>

      domain); ?>

      only if you experience technical issues after upgrading to WP-Stateless 4.0.0', ud_get_stateless_media()->domain); ?>

      ================================================ FILE: static/views/settings-sections/general.php ================================================ domain); ?>
      domain); ?>

      domain); ?>


      domain); ?>

      domain); ?>

      domain); ?>

      domain); ?>

      domain); ?>

      WP_HOME endpoint for REST API requests. If you encounter problems with synchronization or data optimization functions, try using the WP_SITEURL option instead. This is useful if your WordPress dashboard and frontend website utilize different domain names, such as with a headless CMS configuration.', ud_get_stateless_media()->domain); ?>

      domain); ?>

      domain); ?>

      domain); ?>

      ================================================ FILE: static/views/settings-sections/google-cloud-storage.php ================================================ domain); ?>
      domain); ?>

      domain); ?>

      domain); ?>


      domain); ?>

      domain); ?>


      domain); ?>

      domain); ?>


      domain); ?>

      domain); ?>

      ================================================ FILE: static/views/settings-sections/network.php ================================================ domain); ?>
      domain); ?>

      domain); ?>
      domain); ?>

      */ ?> ================================================ FILE: static/views/settings-tab.php ================================================
      'save-settings')); ?>
      ================================================ FILE: static/views/settings_interface.php ================================================ ================================================ FILE: static/views/setup_wizard_interface.php ================================================
      ================================================ FILE: static/views/status-sections/info.php ================================================

      domain); ?>
      domain); ?>

      $section ) : ?>

      ================================================ FILE: static/views/status-sections/migrations.php ================================================

      domain); ?>

      domain); ?>

      domain); ?>

      • domain); ?>
      • domain); ?>
      • domain); ?>
      get_notification_email(); $default_email = empty($default_email) ? __('Disabled', ud_get_stateless_media()->domain) : $default_email; $current_user = wp_get_current_user(); $current_email = $current_user->user_email ?? ''; ?>

      domain); ?>

      domain); ?>

      domain); ?>

      domain); ?>

      ================================================ FILE: static/wiki/Media-Object.md ================================================ ``` Array ( [bucket] => media.smftampa.com [cacheControl] => public, max-age=36000, must-revalidate [componentCount] => [contentDisposition] => [contentEncoding] => [contentLanguage] => [contentType] => image/jpeg [crc32c] => Hrj+mg== [etag] => CMiK3caexMMCEAE= [generation] => 1422913686685000 [id] => media.smftampa.com/2015/02/82db38c5ac911524bcf7be463fc04da73.jpg/1422913686685000 [kind] => storage#object [md5Hash] => upblDqBJPhkDaDxe/9tQMQ== [mediaLink] => https://www.googleapis.com/download/storage/v1/b/media.smftampa.com/o/2015%2F02%2F82db38c5ac911524bcf7be463fc04da73.jpg?generation=1422913686685000&alt=media [metadata] => Array ( [width] => 640 [height] => 480 [object-id] => 605 [source-id] => 75ec2a48bd43df428a094ec1c10e7f71 [file-hash] => b44df4fa79d667a3facac283d729dacb ) [metageneration] => 1 [name] => 2015/02/82db38c5ac911524bcf7be463fc04da73.jpg [selfLink] => https://www.googleapis.com/storage/v1/b/media.smftampa.com/o/2015%2F02%2F82db38c5ac911524bcf7be463fc04da73.jpg [size] => 50617 [storageClass] => STANDARD [timeDeleted] => [updated] => 2015-02-02T21:48:06.684Z ) ``` ================================================ FILE: vendor/autoload.php ================================================ */ class ChromePhp { /** * @var string */ const VERSION = '4.1.0'; /** * @var string */ const HEADER_NAME = 'X-ChromeLogger-Data'; /** * @var string */ const BACKTRACE_LEVEL = 'backtrace_level'; /** * @var string */ const LOG = 'log'; /** * @var string */ const WARN = 'warn'; /** * @var string */ const ERROR = 'error'; /** * @var string */ const GROUP = 'group'; /** * @var string */ const INFO = 'info'; /** * @var string */ const GROUP_END = 'groupEnd'; /** * @var string */ const GROUP_COLLAPSED = 'groupCollapsed'; /** * @var string */ const TABLE = 'table'; /** * @var string */ protected $_php_version; /** * @var int */ protected $_timestamp; /** * @var array */ protected $_json = array( 'version' => self::VERSION, 'columns' => array('log', 'backtrace', 'type'), 'rows' => array() ); /** * @var array */ protected $_backtraces = array(); /** * @var bool */ protected $_error_triggered = false; /** * @var array */ protected $_settings = array( self::BACKTRACE_LEVEL => 1 ); /** * @var ChromePhp */ protected static $_instance; /** * Prevent recursion when working with objects referring to each other * * @var array */ protected $_processed = array(); /** * constructor */ private function __construct() { $this->_php_version = phpversion(); $this->_timestamp = $this->_php_version >= 5.1 ? $_SERVER['REQUEST_TIME'] : time(); $this->_json['request_uri'] = $_SERVER['REQUEST_URI']; } /** * gets instance of this class * * @return ChromePhp */ public static function getInstance() { if (self::$_instance === null) { self::$_instance = new self(); } return self::$_instance; } /** * logs a variable to the console * * @param mixed $data,... unlimited OPTIONAL number of additional logs [...] * @return void */ public static function log() { $args = func_get_args(); return self::_log('', $args); } /** * logs a warning to the console * * @param mixed $data,... unlimited OPTIONAL number of additional logs [...] * @return void */ public static function warn() { $args = func_get_args(); return self::_log(self::WARN, $args); } /** * logs an error to the console * * @param mixed $data,... unlimited OPTIONAL number of additional logs [...] * @return void */ public static function error() { $args = func_get_args(); return self::_log(self::ERROR, $args); } /** * sends a group log * * @param string value */ public static function group() { $args = func_get_args(); return self::_log(self::GROUP, $args); } /** * sends an info log * * @param mixed $data,... unlimited OPTIONAL number of additional logs [...] * @return void */ public static function info() { $args = func_get_args(); return self::_log(self::INFO, $args); } /** * sends a collapsed group log * * @param string value */ public static function groupCollapsed() { $args = func_get_args(); return self::_log(self::GROUP_COLLAPSED, $args); } /** * ends a group log * * @param string value */ public static function groupEnd() { $args = func_get_args(); return self::_log(self::GROUP_END, $args); } /** * sends a table log * * @param string value */ public static function table() { $args = func_get_args(); return self::_log(self::TABLE, $args); } /** * internal logging call * * @param string $type * @return void */ protected static function _log($type, array $args) { // nothing passed in, don't do anything if (count($args) == 0 && $type != self::GROUP_END) { return; } $logger = self::getInstance(); $logger->_processed = array(); $logs = array(); foreach ($args as $arg) { $logs[] = $logger->_convert($arg); } $backtrace = debug_backtrace(false); $level = $logger->getSetting(self::BACKTRACE_LEVEL); $backtrace_message = 'unknown'; if (isset($backtrace[$level]['file']) && isset($backtrace[$level]['line'])) { $backtrace_message = $backtrace[$level]['file'] . ' : ' . $backtrace[$level]['line']; } $logger->_addRow($logs, $backtrace_message, $type); } /** * converts an object to a better format for logging * * @param Object * @return array */ protected function _convert($object) { // if this isn't an object then just return it if (!is_object($object)) { return $object; } //Mark this object as processed so we don't convert it twice and it //Also avoid recursion when objects refer to each other $this->_processed[] = $object; $object_as_array = array(); // first add the class name $object_as_array['___class_name'] = get_class($object); // loop through object vars $object_vars = get_object_vars($object); foreach ($object_vars as $key => $value) { // same instance as parent object if ($value === $object || in_array($value, $this->_processed, true)) { $value = 'recursion - parent object [' . get_class($value) . ']'; } $object_as_array[$key] = $this->_convert($value); } $reflection = new ReflectionClass($object); // loop through the properties and add those foreach ($reflection->getProperties() as $property) { // if one of these properties was already added above then ignore it if (array_key_exists($property->getName(), $object_vars)) { continue; } $type = $this->_getPropertyKey($property); if ($this->_php_version >= 5.3) { $property->setAccessible(true); } try { $value = $property->getValue($object); } catch (ReflectionException $e) { $value = 'only PHP 5.3 can access private/protected properties'; } // same instance as parent object if ($value === $object || in_array($value, $this->_processed, true)) { $value = 'recursion - parent object [' . get_class($value) . ']'; } $object_as_array[$type] = $this->_convert($value); } return $object_as_array; } /** * takes a reflection property and returns a nicely formatted key of the property name * * @param ReflectionProperty * @return string */ protected function _getPropertyKey(ReflectionProperty $property) { $static = $property->isStatic() ? ' static' : ''; if ($property->isPublic()) { return 'public' . $static . ' ' . $property->getName(); } if ($property->isProtected()) { return 'protected' . $static . ' ' . $property->getName(); } if ($property->isPrivate()) { return 'private' . $static . ' ' . $property->getName(); } } /** * adds a value to the data array * * @var mixed * @return void */ protected function _addRow(array $logs, $backtrace, $type) { // if this is logged on the same line for example in a loop, set it to null to save space if (in_array($backtrace, $this->_backtraces)) { $backtrace = null; } // for group, groupEnd, and groupCollapsed // take out the backtrace since it is not useful if ($type == self::GROUP || $type == self::GROUP_END || $type == self::GROUP_COLLAPSED) { $backtrace = null; } if ($backtrace !== null) { $this->_backtraces[] = $backtrace; } $row = array($logs, $backtrace, $type); $this->_json['rows'][] = $row; $this->_writeHeader($this->_json); } protected function _writeHeader($data) { header(self::HEADER_NAME . ': ' . $this->_encode($data)); } /** * encodes the data to be sent along with the request * * @param array $data * @return string */ protected function _encode($data) { return base64_encode(utf8_encode(json_encode($data))); } /** * adds a setting * * @param string key * @param mixed value * @return void */ public function addSetting($key, $value) { $this->_settings[$key] = $value; } /** * add ability to set multiple settings in one call * * @param array $settings * @return void */ public function addSettings(array $settings) { foreach ($settings as $key => $value) { $this->addSetting($key, $value); } } /** * gets a setting * * @param string key * @return mixed */ public function getSetting($key) { if (!isset($this->_settings[$key])) { return null; } return $this->_settings[$key]; } } ================================================ FILE: vendor/ccampbell/chromephp/README.md ================================================ ## Overview ChromePhp is a PHP library for the Chrome Logger Google Chrome extension. This library allows you to log variables to the Chrome console. ## Requirements - PHP 5 or later ## Installation 1. Install the Chrome extension from: https://chrome.google.com/extensions/detail/noaneddfkdjfnfdakjjmocngnfkfehhd 2. Click the extension icon in the browser to enable it for the current tab's domain 3. Put ChromePhp.php somewhere in your PHP include path 4. Log some data ```php include 'ChromePhp.php'; ChromePhp::log('Hello console!'); ChromePhp::log($_SERVER); ChromePhp::warn('something went wrong!'); ``` More information can be found here: http://www.chromelogger.com ================================================ FILE: vendor/ccampbell/chromephp/composer.json ================================================ { "name": "ccampbell/chromephp", "type": "library", "description": "Log variables to the Chrome console (via Chrome Logger Google Chrome extension).", "keywords": ["log","logging"], "homepage": "http://github.com/ccampbell/chromephp", "license": "Apache-2.0", "authors": [ { "name": "Craig Campbell", "email": "iamcraigcampbell@gmail.com", "homepage": "http://craig.is", "role": "Developer" } ], "require": { "php": ">=5.0.0" }, "autoload": { "psr-0": { "ChromePhp": "" } } } ================================================ FILE: vendor/composer/ClassLoader.php ================================================ * 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); } } ================================================ FILE: vendor/composer/InstalledVersions.php ================================================ * Jordi Boggiano * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Composer; use Composer\Autoload\ClassLoader; use 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 string|null if set (by reflection by Composer), this should be set to the path where this class is being copied to * @internal */ private static $selfDir = null; /** * @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 */ private static $installedIsLocalDir; /** * @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(); // when using reload, we disable the duplicate protection to ensure that self::$installed data is // always returned, but we cannot know whether it comes from the installed.php in __DIR__ or not, // so we have to assume it does not, and that may result in duplicate data being returned when listing // all installed packages for example self::$installedIsLocalDir = false; } /** * @return string */ private static function getSelfDir() { if (self::$selfDir === null) { self::$selfDir = strtr(__DIR__, '\\', '/'); } return self::$selfDir; } /** * @return array[] * @psalm-return list}> */ private static function getInstalled() { if (null === self::$canGetVendors) { self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders'); } $installed = array(); $copiedLocalDir = false; if (self::$canGetVendors) { $selfDir = self::getSelfDir(); foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { $vendorDir = strtr($vendorDir, '\\', '/'); 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'; self::$installedByVendor[$vendorDir] = $required; $installed[] = $required; if (self::$installed === null && $vendorDir.'/composer' === $selfDir) { self::$installed = $required; self::$installedIsLocalDir = true; } } if (self::$installedIsLocalDir && $vendorDir.'/composer' === $selfDir) { $copiedLocalDir = true; } } } 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() && !$copiedLocalDir) { $installed[] = self::$installed; } return $installed; } } ================================================ FILE: vendor/composer/LICENSE ================================================ 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. ================================================ FILE: vendor/composer/autoload_classmap.php ================================================ $vendorDir . '/composer/InstalledVersions.php', 'UDX\\Settings' => $baseDir . '/lib/includes/class-settings.php', 'UDX\\Utility' => $baseDir . '/lib/includes/class-utility.php', 'UsabilityDynamics\\UD_API\\API' => $vendorDir . '/udx/lib-ud-api-client/lib/classes/class-api.php', 'UsabilityDynamics\\UD_API\\Admin' => $vendorDir . '/udx/lib-ud-api-client/lib/classes/class-admin.php', 'UsabilityDynamics\\UD_API\\Bootstrap' => $vendorDir . '/udx/lib-ud-api-client/lib/classes/class-bootstrap.php', 'UsabilityDynamics\\UD_API\\Licenses_Table' => $vendorDir . '/udx/lib-ud-api-client/lib/classes/class-licenses-table.php', 'UsabilityDynamics\\UD_API\\Manager' => $vendorDir . '/udx/lib-ud-api-client/lib/classes/class-manager.php', 'UsabilityDynamics\\UD_API\\More_Products_Table' => $vendorDir . '/udx/lib-ud-api-client/lib/classes/class-more-products-table.php', 'UsabilityDynamics\\UD_API\\Scaffold' => $vendorDir . '/udx/lib-ud-api-client/lib/classes/class-scaffold.php', 'UsabilityDynamics\\UD_API\\UI' => $vendorDir . '/udx/lib-ud-api-client/lib/classes/class-ui.php', 'UsabilityDynamics\\UD_API\\Update_Checker' => $vendorDir . '/udx/lib-ud-api-client/lib/classes/class-update-checker.php', 'UsabilityDynamics\\UD_API\\Utility' => $vendorDir . '/udx/lib-ud-api-client/lib/classes/class-utility.php', 'UsabilityDynamics\\WP\\Bootstrap' => $vendorDir . '/udx/lib-wp-bootstrap/lib/classes/class-bootstrap.php', 'UsabilityDynamics\\WP\\Bootstrap_Plugin' => $vendorDir . '/udx/lib-wp-bootstrap/lib/classes/class-bootstrap-plugin.php', 'UsabilityDynamics\\WP\\Bootstrap_Theme' => $vendorDir . '/udx/lib-wp-bootstrap/lib/classes/class-bootstrap-theme.php', 'UsabilityDynamics\\WP\\Dashboard' => $vendorDir . '/udx/lib-wp-bootstrap/lib/classes/class-dashboard.php', 'UsabilityDynamics\\WP\\Errors' => $vendorDir . '/udx/lib-wp-bootstrap/lib/classes/class-errors.php', 'UsabilityDynamics\\WP\\Scaffold' => $vendorDir . '/udx/lib-wp-bootstrap/lib/classes/class-scaffold.php', 'UsabilityDynamics\\WP\\TGMPA_List_Table' => $vendorDir . '/udx/lib-wp-bootstrap/lib/classes/class-tgm-list-table.php', 'UsabilityDynamics\\WP\\TGM_Bulk_Installer' => $vendorDir . '/udx/lib-wp-bootstrap/lib/classes/class-tgm-bulk-installer.php', 'UsabilityDynamics\\WP\\TGM_Bulk_Installer_Skin' => $vendorDir . '/udx/lib-wp-bootstrap/lib/classes/class-tgm-bulk-installer.php', 'UsabilityDynamics\\WP\\TGM_Plugin_Activation' => $vendorDir . '/udx/lib-wp-bootstrap/lib/classes/class-tgm-plugin-activation.php', 'UsabilityDynamics\\WP\\Utility' => $vendorDir . '/udx/lib-wp-bootstrap/lib/classes/class-utility.php', 'wpCloud\\StatelessMedia\\API' => $baseDir . '/lib/classes/class-api.php', 'wpCloud\\StatelessMedia\\Addons' => $baseDir . '/lib/classes/class-addons.php', 'wpCloud\\StatelessMedia\\Ajax' => $baseDir . '/lib/classes/class-ajax.php', 'wpCloud\\StatelessMedia\\AppEngine' => $baseDir . '/lib/classes/class-google-app-engine.php', 'wpCloud\\StatelessMedia\\Batch\\BatchTask' => $baseDir . '/lib/classes/batch/class-batch-task.php', 'wpCloud\\StatelessMedia\\Batch\\BatchTaskManager' => $baseDir . '/lib/classes/batch/class-batch-task-manager.php', 'wpCloud\\StatelessMedia\\Batch\\IBatchTask' => $baseDir . '/lib/classes/batch/interface-batch.php', 'wpCloud\\StatelessMedia\\Batch\\Migration' => $baseDir . '/lib/classes/batch/class-migration.php', 'wpCloud\\StatelessMedia\\Bootstrap' => $baseDir . '/lib/classes/class-bootstrap.php', 'wpCloud\\StatelessMedia\\Compatibility' => $baseDir . '/lib/classes/class-compatibility.php', 'wpCloud\\StatelessMedia\\DB' => $baseDir . '/lib/classes/class-db.php', 'wpCloud\\StatelessMedia\\DynamicImageSupport' => $baseDir . '/lib/classes/class-dynamic-image-support.php', 'wpCloud\\StatelessMedia\\EWWW' => $baseDir . '/lib/classes/compatibility/ewww.php', 'wpCloud\\StatelessMedia\\Errors' => $baseDir . '/lib/classes/class-errors.php', 'wpCloud\\StatelessMedia\\FatalException' => $baseDir . '/lib/classes/exception-fatal.php', 'wpCloud\\StatelessMedia\\GS_Client' => $baseDir . '/lib/classes/class-gs-client.php', 'wpCloud\\StatelessMedia\\Helper' => $baseDir . '/lib/classes/class-helper.php', 'wpCloud\\StatelessMedia\\Imagify' => $baseDir . '/lib/classes/compatibility/imagify.php', 'wpCloud\\StatelessMedia\\LearnDash' => $baseDir . '/lib/classes/compatibility/learn-dash.php', 'wpCloud\\StatelessMedia\\Logger' => $baseDir . '/lib/classes/class-logger.php', 'wpCloud\\StatelessMedia\\Migrator' => $baseDir . '/lib/classes/class-migrator.php', 'wpCloud\\StatelessMedia\\Module' => $baseDir . '/lib/classes/class-module.php', 'wpCloud\\StatelessMedia\\Settings' => $baseDir . '/lib/classes/class-settings.php', 'wpCloud\\StatelessMedia\\ShortPixel' => $baseDir . '/lib/classes/compatibility/shortpixel.php', 'wpCloud\\StatelessMedia\\Singleton' => $baseDir . '/lib/classes/trait-singleton.php', 'wpCloud\\StatelessMedia\\Status' => $baseDir . '/lib/classes/class-status.php', 'wpCloud\\StatelessMedia\\Status\\GoogleCloudInfo' => $baseDir . '/lib/classes/status/class-info-google_cloud.php', 'wpCloud\\StatelessMedia\\Status\\Info' => $baseDir . '/lib/classes/status/class-info.php', 'wpCloud\\StatelessMedia\\Status\\Migrations' => $baseDir . '/lib/classes/status/class-migrations.php', 'wpCloud\\StatelessMedia\\Status\\StatelessInfo' => $baseDir . '/lib/classes/status/class-info-stateless.php', 'wpCloud\\StatelessMedia\\StreamWrapper' => $baseDir . '/lib/classes/class-gs-stream-wrapper.php', 'wpCloud\\StatelessMedia\\SyncNonMedia' => $baseDir . '/lib/classes/class-sync-non-media.php', 'wpCloud\\StatelessMedia\\Sync\\BackgroundSync' => $baseDir . '/lib/classes/sync/class-background-sync.php', 'wpCloud\\StatelessMedia\\Sync\\FileSync' => $baseDir . '/lib/classes/sync/class-file-sync.php', 'wpCloud\\StatelessMedia\\Sync\\HelperWindow' => $baseDir . '/lib/classes/sync/class-helper-window.php', 'wpCloud\\StatelessMedia\\Sync\\ISync' => $baseDir . '/lib/classes/sync/interface-sync.php', 'wpCloud\\StatelessMedia\\Sync\\ImageSync' => $baseDir . '/lib/classes/sync/class-image-sync.php', 'wpCloud\\StatelessMedia\\Sync\\LibrarySync' => $baseDir . '/lib/classes/sync/class-library-sync.php', 'wpCloud\\StatelessMedia\\Sync\\NonLibrarySync' => $baseDir . '/lib/classes/sync/class-non-library-sync.php', 'wpCloud\\StatelessMedia\\TheEventsCalendar' => $baseDir . '/lib/classes/compatibility/the-events-calendar.php', 'wpCloud\\StatelessMedia\\UnprocessableException' => $baseDir . '/lib/classes/exception-unprocessable.php', 'wpCloud\\StatelessMedia\\Upgrader' => $baseDir . '/lib/classes/class-upgrader.php', 'wpCloud\\StatelessMedia\\Utility' => $baseDir . '/lib/classes/class-utility.php', 'wpCloud\\StatelessMedia\\WPBakeryPageBuilder' => $baseDir . '/lib/classes/compatibility/wpbakery-page-builder.php', 'wpCloud\\StatelessMedia\\WPSmush' => $baseDir . '/lib/classes/compatibility/wp-smush.php', ); ================================================ FILE: vendor/composer/autoload_namespaces.php ================================================ array($vendorDir . '/ccampbell/chromephp'), ); ================================================ FILE: vendor/composer/autoload_psr4.php ================================================ array($vendorDir . '/firebase/php-jwt/src'), 'Composer\\Installers\\' => array($vendorDir . '/composer/installers/src/Composer/Installers'), ); ================================================ FILE: vendor/composer/autoload_real.php ================================================ register(true); return $loader; } } ================================================ FILE: vendor/composer/autoload_static.php ================================================ array ( 'Firebase\\JWT\\' => 13, ), 'C' => array ( 'Composer\\Installers\\' => 20, ), ); public static $prefixDirsPsr4 = array ( 'Firebase\\JWT\\' => array ( 0 => __DIR__ . '/..' . '/firebase/php-jwt/src', ), 'Composer\\Installers\\' => array ( 0 => __DIR__ . '/..' . '/composer/installers/src/Composer/Installers', ), ); public static $prefixesPsr0 = array ( 'C' => array ( 'ChromePhp' => array ( 0 => __DIR__ . '/..' . '/ccampbell/chromephp', ), ), ); public static $classMap = array ( 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', 'UDX\\Settings' => __DIR__ . '/../..' . '/lib/includes/class-settings.php', 'UDX\\Utility' => __DIR__ . '/../..' . '/lib/includes/class-utility.php', 'UsabilityDynamics\\UD_API\\API' => __DIR__ . '/..' . '/udx/lib-ud-api-client/lib/classes/class-api.php', 'UsabilityDynamics\\UD_API\\Admin' => __DIR__ . '/..' . '/udx/lib-ud-api-client/lib/classes/class-admin.php', 'UsabilityDynamics\\UD_API\\Bootstrap' => __DIR__ . '/..' . '/udx/lib-ud-api-client/lib/classes/class-bootstrap.php', 'UsabilityDynamics\\UD_API\\Licenses_Table' => __DIR__ . '/..' . '/udx/lib-ud-api-client/lib/classes/class-licenses-table.php', 'UsabilityDynamics\\UD_API\\Manager' => __DIR__ . '/..' . '/udx/lib-ud-api-client/lib/classes/class-manager.php', 'UsabilityDynamics\\UD_API\\More_Products_Table' => __DIR__ . '/..' . '/udx/lib-ud-api-client/lib/classes/class-more-products-table.php', 'UsabilityDynamics\\UD_API\\Scaffold' => __DIR__ . '/..' . '/udx/lib-ud-api-client/lib/classes/class-scaffold.php', 'UsabilityDynamics\\UD_API\\UI' => __DIR__ . '/..' . '/udx/lib-ud-api-client/lib/classes/class-ui.php', 'UsabilityDynamics\\UD_API\\Update_Checker' => __DIR__ . '/..' . '/udx/lib-ud-api-client/lib/classes/class-update-checker.php', 'UsabilityDynamics\\UD_API\\Utility' => __DIR__ . '/..' . '/udx/lib-ud-api-client/lib/classes/class-utility.php', 'UsabilityDynamics\\WP\\Bootstrap' => __DIR__ . '/..' . '/udx/lib-wp-bootstrap/lib/classes/class-bootstrap.php', 'UsabilityDynamics\\WP\\Bootstrap_Plugin' => __DIR__ . '/..' . '/udx/lib-wp-bootstrap/lib/classes/class-bootstrap-plugin.php', 'UsabilityDynamics\\WP\\Bootstrap_Theme' => __DIR__ . '/..' . '/udx/lib-wp-bootstrap/lib/classes/class-bootstrap-theme.php', 'UsabilityDynamics\\WP\\Dashboard' => __DIR__ . '/..' . '/udx/lib-wp-bootstrap/lib/classes/class-dashboard.php', 'UsabilityDynamics\\WP\\Errors' => __DIR__ . '/..' . '/udx/lib-wp-bootstrap/lib/classes/class-errors.php', 'UsabilityDynamics\\WP\\Scaffold' => __DIR__ . '/..' . '/udx/lib-wp-bootstrap/lib/classes/class-scaffold.php', 'UsabilityDynamics\\WP\\TGMPA_List_Table' => __DIR__ . '/..' . '/udx/lib-wp-bootstrap/lib/classes/class-tgm-list-table.php', 'UsabilityDynamics\\WP\\TGM_Bulk_Installer' => __DIR__ . '/..' . '/udx/lib-wp-bootstrap/lib/classes/class-tgm-bulk-installer.php', 'UsabilityDynamics\\WP\\TGM_Bulk_Installer_Skin' => __DIR__ . '/..' . '/udx/lib-wp-bootstrap/lib/classes/class-tgm-bulk-installer.php', 'UsabilityDynamics\\WP\\TGM_Plugin_Activation' => __DIR__ . '/..' . '/udx/lib-wp-bootstrap/lib/classes/class-tgm-plugin-activation.php', 'UsabilityDynamics\\WP\\Utility' => __DIR__ . '/..' . '/udx/lib-wp-bootstrap/lib/classes/class-utility.php', 'wpCloud\\StatelessMedia\\API' => __DIR__ . '/../..' . '/lib/classes/class-api.php', 'wpCloud\\StatelessMedia\\Addons' => __DIR__ . '/../..' . '/lib/classes/class-addons.php', 'wpCloud\\StatelessMedia\\Ajax' => __DIR__ . '/../..' . '/lib/classes/class-ajax.php', 'wpCloud\\StatelessMedia\\AppEngine' => __DIR__ . '/../..' . '/lib/classes/class-google-app-engine.php', 'wpCloud\\StatelessMedia\\Batch\\BatchTask' => __DIR__ . '/../..' . '/lib/classes/batch/class-batch-task.php', 'wpCloud\\StatelessMedia\\Batch\\BatchTaskManager' => __DIR__ . '/../..' . '/lib/classes/batch/class-batch-task-manager.php', 'wpCloud\\StatelessMedia\\Batch\\IBatchTask' => __DIR__ . '/../..' . '/lib/classes/batch/interface-batch.php', 'wpCloud\\StatelessMedia\\Batch\\Migration' => __DIR__ . '/../..' . '/lib/classes/batch/class-migration.php', 'wpCloud\\StatelessMedia\\Bootstrap' => __DIR__ . '/../..' . '/lib/classes/class-bootstrap.php', 'wpCloud\\StatelessMedia\\Compatibility' => __DIR__ . '/../..' . '/lib/classes/class-compatibility.php', 'wpCloud\\StatelessMedia\\DB' => __DIR__ . '/../..' . '/lib/classes/class-db.php', 'wpCloud\\StatelessMedia\\DynamicImageSupport' => __DIR__ . '/../..' . '/lib/classes/class-dynamic-image-support.php', 'wpCloud\\StatelessMedia\\EWWW' => __DIR__ . '/../..' . '/lib/classes/compatibility/ewww.php', 'wpCloud\\StatelessMedia\\Errors' => __DIR__ . '/../..' . '/lib/classes/class-errors.php', 'wpCloud\\StatelessMedia\\FatalException' => __DIR__ . '/../..' . '/lib/classes/exception-fatal.php', 'wpCloud\\StatelessMedia\\GS_Client' => __DIR__ . '/../..' . '/lib/classes/class-gs-client.php', 'wpCloud\\StatelessMedia\\Helper' => __DIR__ . '/../..' . '/lib/classes/class-helper.php', 'wpCloud\\StatelessMedia\\Imagify' => __DIR__ . '/../..' . '/lib/classes/compatibility/imagify.php', 'wpCloud\\StatelessMedia\\LearnDash' => __DIR__ . '/../..' . '/lib/classes/compatibility/learn-dash.php', 'wpCloud\\StatelessMedia\\Logger' => __DIR__ . '/../..' . '/lib/classes/class-logger.php', 'wpCloud\\StatelessMedia\\Migrator' => __DIR__ . '/../..' . '/lib/classes/class-migrator.php', 'wpCloud\\StatelessMedia\\Module' => __DIR__ . '/../..' . '/lib/classes/class-module.php', 'wpCloud\\StatelessMedia\\Settings' => __DIR__ . '/../..' . '/lib/classes/class-settings.php', 'wpCloud\\StatelessMedia\\ShortPixel' => __DIR__ . '/../..' . '/lib/classes/compatibility/shortpixel.php', 'wpCloud\\StatelessMedia\\Singleton' => __DIR__ . '/../..' . '/lib/classes/trait-singleton.php', 'wpCloud\\StatelessMedia\\Status' => __DIR__ . '/../..' . '/lib/classes/class-status.php', 'wpCloud\\StatelessMedia\\Status\\GoogleCloudInfo' => __DIR__ . '/../..' . '/lib/classes/status/class-info-google_cloud.php', 'wpCloud\\StatelessMedia\\Status\\Info' => __DIR__ . '/../..' . '/lib/classes/status/class-info.php', 'wpCloud\\StatelessMedia\\Status\\Migrations' => __DIR__ . '/../..' . '/lib/classes/status/class-migrations.php', 'wpCloud\\StatelessMedia\\Status\\StatelessInfo' => __DIR__ . '/../..' . '/lib/classes/status/class-info-stateless.php', 'wpCloud\\StatelessMedia\\StreamWrapper' => __DIR__ . '/../..' . '/lib/classes/class-gs-stream-wrapper.php', 'wpCloud\\StatelessMedia\\SyncNonMedia' => __DIR__ . '/../..' . '/lib/classes/class-sync-non-media.php', 'wpCloud\\StatelessMedia\\Sync\\BackgroundSync' => __DIR__ . '/../..' . '/lib/classes/sync/class-background-sync.php', 'wpCloud\\StatelessMedia\\Sync\\FileSync' => __DIR__ . '/../..' . '/lib/classes/sync/class-file-sync.php', 'wpCloud\\StatelessMedia\\Sync\\HelperWindow' => __DIR__ . '/../..' . '/lib/classes/sync/class-helper-window.php', 'wpCloud\\StatelessMedia\\Sync\\ISync' => __DIR__ . '/../..' . '/lib/classes/sync/interface-sync.php', 'wpCloud\\StatelessMedia\\Sync\\ImageSync' => __DIR__ . '/../..' . '/lib/classes/sync/class-image-sync.php', 'wpCloud\\StatelessMedia\\Sync\\LibrarySync' => __DIR__ . '/../..' . '/lib/classes/sync/class-library-sync.php', 'wpCloud\\StatelessMedia\\Sync\\NonLibrarySync' => __DIR__ . '/../..' . '/lib/classes/sync/class-non-library-sync.php', 'wpCloud\\StatelessMedia\\TheEventsCalendar' => __DIR__ . '/../..' . '/lib/classes/compatibility/the-events-calendar.php', 'wpCloud\\StatelessMedia\\UnprocessableException' => __DIR__ . '/../..' . '/lib/classes/exception-unprocessable.php', 'wpCloud\\StatelessMedia\\Upgrader' => __DIR__ . '/../..' . '/lib/classes/class-upgrader.php', 'wpCloud\\StatelessMedia\\Utility' => __DIR__ . '/../..' . '/lib/classes/class-utility.php', 'wpCloud\\StatelessMedia\\WPBakeryPageBuilder' => __DIR__ . '/../..' . '/lib/classes/compatibility/wpbakery-page-builder.php', 'wpCloud\\StatelessMedia\\WPSmush' => __DIR__ . '/../..' . '/lib/classes/compatibility/wp-smush.php', ); public static function getInitializer(ClassLoader $loader) { return \Closure::bind(function () use ($loader) { $loader->prefixLengthsPsr4 = ComposerStaticInitc59d002476a452800baaf79c430753cb::$prefixLengthsPsr4; $loader->prefixDirsPsr4 = ComposerStaticInitc59d002476a452800baaf79c430753cb::$prefixDirsPsr4; $loader->prefixesPsr0 = ComposerStaticInitc59d002476a452800baaf79c430753cb::$prefixesPsr0; $loader->classMap = ComposerStaticInitc59d002476a452800baaf79c430753cb::$classMap; }, null, ClassLoader::class); } } ================================================ FILE: vendor/composer/installed.json ================================================ { "packages": [ { "name": "ccampbell/chromephp", "version": "4.1.0", "version_normalized": "4.1.0.0", "source": { "type": "git", "url": "https://github.com/ccampbell/chromephp.git", "reference": "c3c297615d48ae5b2a86a82311152d1ed095fcef" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/ccampbell/chromephp/zipball/c3c297615d48ae5b2a86a82311152d1ed095fcef", "reference": "c3c297615d48ae5b2a86a82311152d1ed095fcef", "shasum": "" }, "require": { "php": ">=5.0.0" }, "time": "2013-06-26T03:44:33+00:00", "type": "library", "installation-source": "dist", "autoload": { "psr-0": { "ChromePhp": "" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "Apache-2.0" ], "authors": [ { "name": "Craig Campbell", "email": "iamcraigcampbell@gmail.com", "homepage": "http://craig.is", "role": "Developer" } ], "description": "Log variables to the Chrome console (via Chrome Logger Google Chrome extension).", "homepage": "http://github.com/ccampbell/chromephp", "keywords": [ "log", "logging" ], "install-path": "../ccampbell/chromephp" }, { "name": "composer/installers", "version": "v2.3.0", "version_normalized": "2.3.0.0", "source": { "type": "git", "url": "https://github.com/composer/installers.git", "reference": "12fb2dfe5e16183de69e784a7b84046c43d97e8e" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/composer/installers/zipball/12fb2dfe5e16183de69e784a7b84046c43d97e8e", "reference": "12fb2dfe5e16183de69e784a7b84046c43d97e8e", "shasum": "" }, "require": { "composer-plugin-api": "^1.0 || ^2.0", "php": "^7.2 || ^8.0" }, "require-dev": { "composer/composer": "^1.10.27 || ^2.7", "composer/semver": "^1.7.2 || ^3.4.0", "phpstan/phpstan": "^1.11", "phpstan/phpstan-phpunit": "^1", "symfony/phpunit-bridge": "^7.1.1", "symfony/process": "^5 || ^6 || ^7" }, "time": "2024-06-24T20:46:46+00:00", "type": "composer-plugin", "extra": { "class": "Composer\\Installers\\Plugin", "branch-alias": { "dev-main": "2.x-dev" }, "plugin-modifies-install-path": true }, "installation-source": "dist", "autoload": { "psr-4": { "Composer\\Installers\\": "src/Composer/Installers" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ { "name": "Kyle Robinson Young", "email": "kyle@dontkry.com", "homepage": "https://github.com/shama" } ], "description": "A multi-framework Composer library installer", "homepage": "https://composer.github.io/installers/", "keywords": [ "Dolibarr", "Eliasis", "Hurad", "ImageCMS", "Kanboard", "Lan Management System", "MODX Evo", "MantisBT", "Mautic", "Maya", "OXID", "Plentymarkets", "Porto", "RadPHP", "SMF", "Starbug", "Thelia", "Whmcs", "WolfCMS", "agl", "annotatecms", "attogram", "bitrix", "cakephp", "chef", "cockpit", "codeigniter", "concrete5", "concreteCMS", "croogo", "dokuwiki", "drupal", "eZ Platform", "elgg", "expressionengine", "fuelphp", "grav", "installer", "itop", "known", "kohana", "laravel", "lavalite", "lithium", "magento", "majima", "mako", "matomo", "mediawiki", "miaoxing", "modulework", "modx", "moodle", "osclass", "pantheon", "phpbb", "piwik", "ppi", "processwire", "puppet", "pxcms", "reindex", "roundcube", "shopware", "silverstripe", "sydes", "sylius", "tastyigniter", "wordpress", "yawik", "zend", "zikula" ], "support": { "issues": "https://github.com/composer/installers/issues", "source": "https://github.com/composer/installers/tree/v2.3.0" }, "funding": [ { "url": "https://packagist.com", "type": "custom" }, { "url": "https://github.com/composer", "type": "github" }, { "url": "https://tidelift.com/funding/github/packagist/composer/composer", "type": "tidelift" } ], "install-path": "./installers" }, { "name": "firebase/php-jwt", "version": "v6.11.1", "version_normalized": "6.11.1.0", "source": { "type": "git", "url": "https://github.com/firebase/php-jwt.git", "reference": "d1e91ecf8c598d073d0995afa8cd5c75c6e19e66" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/firebase/php-jwt/zipball/d1e91ecf8c598d073d0995afa8cd5c75c6e19e66", "reference": "d1e91ecf8c598d073d0995afa8cd5c75c6e19e66", "shasum": "" }, "require": { "php": "^8.0" }, "require-dev": { "guzzlehttp/guzzle": "^7.4", "phpspec/prophecy-phpunit": "^2.0", "phpunit/phpunit": "^9.5", "psr/cache": "^2.0||^3.0", "psr/http-client": "^1.0", "psr/http-factory": "^1.0" }, "suggest": { "ext-sodium": "Support EdDSA (Ed25519) signatures", "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present" }, "time": "2025-04-09T20:32:01+00:00", "type": "library", "installation-source": "dist", "autoload": { "psr-4": { "Firebase\\JWT\\": "src" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Neuman Vong", "email": "neuman+pear@twilio.com", "role": "Developer" }, { "name": "Anant Narayanan", "email": "anant@php.net", "role": "Developer" } ], "description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.", "homepage": "https://github.com/firebase/php-jwt", "keywords": [ "jwt", "php" ], "support": { "issues": "https://github.com/firebase/php-jwt/issues", "source": "https://github.com/firebase/php-jwt/tree/v6.11.1" }, "install-path": "../firebase/php-jwt" }, { "name": "udx/lib-ud-api-client", "version": "1.2.5", "version_normalized": "1.2.5.0", "source": { "type": "git", "url": "git@github.com:udx/lib-ud-api-client", "reference": "1.2.5" }, "dist": { "type": "zip", "url": "https://github.com/udx/lib-ud-api-client/archive/1.2.5.zip" }, "require": { "php": ">=5.3" }, "type": "library", "extra": { "installer-name": "lib-ud-api-client" }, "installation-source": "dist", "autoload": { "classmap": [ "lib/classes" ] }, "license": [ "GPLv2" ], "authors": [ { "name": "UsabilityDynamics, Inc.", "homepage": "https://www.usabilitydynamics.com" } ], "description": "UD API Client for WooCommerce API Manager", "homepage": "https://github.com/udx/lib-ud-api-client", "keywords": [ "api", "client", "licenses", "plugins", "wordpress" ], "install-path": "../udx/lib-ud-api-client" }, { "name": "udx/lib-wp-bootstrap", "version": "1.3.4", "version_normalized": "1.3.4.0", "source": { "type": "git", "url": "git@github.com:udx/lib-wp-bootstrap", "reference": "1.3.4" }, "dist": { "type": "zip", "url": "https://github.com/udx/lib-wp-bootstrap/archive/1.3.4.zip" }, "require": { "php": ">=5.3" }, "type": "library", "extra": { "installer-name": "lib-wp-bootstrap" }, "installation-source": "dist", "autoload": { "classmap": [ "lib/classes" ] }, "license": [ "MIT" ], "description": "Wordpress bootstrap library created by UsabilityDynamics", "homepage": "https://github.com/udx/lib-wp-bootstrap", "keywords": [ "wordpress" ], "install-path": "../udx/lib-wp-bootstrap" }, { "name": "wpackagist-plugin/meta-box", "version": "5.10.19", "version_normalized": "5.10.19.0", "source": { "type": "svn", "url": "https://plugins.svn.wordpress.org/meta-box/", "reference": "tags/5.10.19" }, "dist": { "type": "zip", "url": "https://downloads.wordpress.org/plugin/meta-box.5.10.19.zip" }, "require": { "composer/installers": "^1.0 || ^2.0" }, "type": "wordpress-plugin", "installation-source": "dist", "homepage": "https://wordpress.org/plugins/meta-box/", "install-path": "../wpmetabox/meta-box" } ], "dev": false, "dev-package-names": [] } ================================================ FILE: vendor/composer/installed.php ================================================ array( 'name' => 'wpcloud/wp-stateless', 'pretty_version' => 'dev-latest', 'version' => 'dev-latest', 'reference' => 'f85c0f94de8b8e232088265c78c95da7162e2fac', 'type' => 'wordpress-plugin', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev' => false, ), 'versions' => array( 'ccampbell/chromephp' => array( 'pretty_version' => '4.1.0', 'version' => '4.1.0.0', 'reference' => 'c3c297615d48ae5b2a86a82311152d1ed095fcef', 'type' => 'library', 'install_path' => __DIR__ . '/../ccampbell/chromephp', 'aliases' => array(), 'dev_requirement' => false, ), 'composer/installers' => array( 'pretty_version' => 'v2.3.0', 'version' => '2.3.0.0', 'reference' => '12fb2dfe5e16183de69e784a7b84046c43d97e8e', 'type' => 'composer-plugin', 'install_path' => __DIR__ . '/./installers', 'aliases' => array(), 'dev_requirement' => false, ), 'firebase/php-jwt' => array( 'pretty_version' => 'v6.11.1', 'version' => '6.11.1.0', 'reference' => 'd1e91ecf8c598d073d0995afa8cd5c75c6e19e66', 'type' => 'library', 'install_path' => __DIR__ . '/../firebase/php-jwt', 'aliases' => array(), 'dev_requirement' => false, ), 'udx/lib-ud-api-client' => array( 'pretty_version' => '1.2.5', 'version' => '1.2.5.0', 'reference' => '1.2.5', 'type' => 'library', 'install_path' => __DIR__ . '/../udx/lib-ud-api-client', 'aliases' => array(), 'dev_requirement' => false, ), 'udx/lib-wp-bootstrap' => array( 'pretty_version' => '1.3.4', 'version' => '1.3.4.0', 'reference' => '1.3.4', 'type' => 'library', 'install_path' => __DIR__ . '/../udx/lib-wp-bootstrap', 'aliases' => array(), 'dev_requirement' => false, ), 'wpackagist-plugin/meta-box' => array( 'pretty_version' => '5.10.19', 'version' => '5.10.19.0', 'reference' => 'tags/5.10.19', 'type' => 'wordpress-plugin', 'install_path' => __DIR__ . '/../wpmetabox/meta-box', 'aliases' => array(), 'dev_requirement' => false, ), 'wpcloud/wp-stateless' => array( 'pretty_version' => 'dev-latest', 'version' => 'dev-latest', 'reference' => 'f85c0f94de8b8e232088265c78c95da7162e2fac', 'type' => 'wordpress-plugin', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev_requirement' => false, ), ), ); ================================================ FILE: vendor/composer/installers/.github/workflows/continuous-integration.yml ================================================ name: "Continuous Integration" on: - push - pull_request env: COMPOSER_FLAGS: "--ansi --no-interaction --no-progress --prefer-dist" SYMFONY_PHPUNIT_REMOVE_RETURN_TYPEHINT: "1" permissions: contents: read jobs: tests: name: "CI" runs-on: ubuntu-latest strategy: matrix: php-version: - "7.2" - "7.3" - "7.4" - "8.0" - "8.1" dependencies: [locked] include: - php-version: "7.2" dependencies: lowest - php-version: "8.1" dependencies: lowest steps: - name: "Checkout" uses: "actions/checkout@v2" - name: "Install PHP" uses: "shivammathur/setup-php@v2" with: coverage: "none" php-version: "${{ matrix.php-version }}" tools: composer:snapshot - name: Get composer cache directory id: composercache run: echo "::set-output name=dir::$(composer config cache-files-dir)" - name: Cache dependencies uses: actions/cache@v2 with: path: ${{ steps.composercache.outputs.dir }} key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} restore-keys: ${{ runner.os }}-composer- - name: "Handle lowest dependencies update" if: "contains(matrix.dependencies, 'lowest')" run: "echo \"COMPOSER_FLAGS=$COMPOSER_FLAGS --prefer-lowest\" >> $GITHUB_ENV" - name: "Install latest dependencies" run: "composer update ${{ env.COMPOSER_FLAGS }}" - name: "Run tests" run: "vendor/bin/simple-phpunit --verbose" ================================================ FILE: vendor/composer/installers/.github/workflows/lint.yml ================================================ name: "PHP Lint" on: - push - pull_request permissions: contents: read jobs: tests: name: "Lint" runs-on: ubuntu-latest strategy: matrix: php-version: - "7.2" - "latest" steps: - name: "Checkout" uses: "actions/checkout@v2" - name: "Install PHP" uses: "shivammathur/setup-php@v2" with: coverage: "none" php-version: "${{ matrix.php-version }}" - name: "Lint PHP files" run: "find src/ -type f -name '*.php' -print0 | xargs -0 -L1 -P4 -- php -l -f" ================================================ FILE: vendor/composer/installers/.github/workflows/phpstan.yml ================================================ name: "PHPStan" on: - push - pull_request env: COMPOSER_FLAGS: "--ansi --no-interaction --no-progress --prefer-dist" SYMFONY_PHPUNIT_VERSION: "" permissions: contents: read jobs: tests: name: "PHPStan" runs-on: ubuntu-latest strategy: matrix: php-version: - "8.0" steps: - name: "Checkout" uses: "actions/checkout@v2" - name: "Install PHP" uses: "shivammathur/setup-php@v2" with: coverage: "none" php-version: "${{ matrix.php-version }}" - name: Get composer cache directory id: composercache run: echo "::set-output name=dir::$(composer config cache-files-dir)" - name: Cache dependencies uses: actions/cache@v2 with: path: ${{ steps.composercache.outputs.dir }} key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} restore-keys: ${{ runner.os }}-composer- - name: "Install latest dependencies" run: "composer update ${{ env.COMPOSER_FLAGS }}" - name: Run PHPStan run: | composer require --dev phpunit/phpunit:^8.5.18 --with-all-dependencies ${{ env.COMPOSER_FLAGS }} vendor/bin/phpstan analyse ================================================ FILE: vendor/composer/installers/LICENSE ================================================ Copyright (c) 2012 Kyle Robinson Young 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. ================================================ FILE: vendor/composer/installers/composer.json ================================================ { "name": "composer/installers", "type": "composer-plugin", "license": "MIT", "description": "A multi-framework Composer library installer", "keywords": [ "installer", "AGL", "AnnotateCms", "Attogram", "Bitrix", "CakePHP", "Chef", "Cockpit", "CodeIgniter", "concrete5", "ConcreteCMS", "Croogo", "DokuWiki", "Dolibarr", "Drupal", "Elgg", "Eliasis", "ExpressionEngine", "eZ Platform", "FuelPHP", "Grav", "Hurad", "ImageCMS", "iTop", "Kanboard", "Known", "Kohana", "Lan Management System", "Laravel", "Lavalite", "Lithium", "Magento", "majima", "Mako", "MantisBT", "Matomo", "Mautic", "Maya", "MODX", "MODX Evo", "MediaWiki", "Miaoxing", "OXID", "osclass", "MODULEWork", "Moodle", "Pantheon", "Piwik", "pxcms", "phpBB", "Plentymarkets", "PPI", "Puppet", "Porto", "ProcessWire", "RadPHP", "ReIndex", "Roundcube", "shopware", "SilverStripe", "SMF", "Starbug", "SyDES", "Sylius", "TastyIgniter", "Thelia", "WHMCS", "WolfCMS", "WordPress", "YAWIK", "Zend", "Zikula" ], "homepage": "https://composer.github.io/installers/", "authors": [ { "name": "Kyle Robinson Young", "email": "kyle@dontkry.com", "homepage": "https://github.com/shama" } ], "autoload": { "psr-4": { "Composer\\Installers\\": "src/Composer/Installers" } }, "autoload-dev": { "psr-4": { "Composer\\Installers\\Test\\": "tests/Composer/Installers/Test" } }, "extra": { "class": "Composer\\Installers\\Plugin", "branch-alias": { "dev-main": "2.x-dev" }, "plugin-modifies-install-path": true }, "require": { "php": "^7.2 || ^8.0", "composer-plugin-api": "^1.0 || ^2.0" }, "require-dev": { "composer/composer": "^1.10.27 || ^2.7", "composer/semver": "^1.7.2 || ^3.4.0", "symfony/phpunit-bridge": "^7.1.1", "phpstan/phpstan": "^1.11", "symfony/process": "^5 || ^6 || ^7", "phpstan/phpstan-phpunit": "^1" }, "scripts": { "test": "@php vendor/bin/simple-phpunit", "phpstan": "@php vendor/bin/phpstan analyse" } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/AglInstaller.php ================================================ */ protected $locations = array( 'module' => 'More/{$name}/', ); /** * Format package name to CamelCase */ public function inflectPackageVars(array $vars): array { $name = preg_replace_callback('/(?:^|_|-)(.?)/', function ($matches) { return strtoupper($matches[1]); }, $vars['name']); if (null === $name) { throw new \RuntimeException('Failed to run preg_replace_callback: '.preg_last_error()); } $vars['name'] = $name; return $vars; } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/AkauntingInstaller.php ================================================ */ protected $locations = array( 'module' => 'modules/{$name}', ); /** * Format package name to CamelCase */ public function inflectPackageVars(array $vars): array { $vars['name'] = strtolower($this->pregReplace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name'])); $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); return $vars; } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/AnnotateCmsInstaller.php ================================================ */ protected $locations = array( 'module' => 'addons/modules/{$name}/', 'component' => 'addons/components/{$name}/', 'service' => 'addons/services/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/AsgardInstaller.php ================================================ */ protected $locations = array( 'module' => 'Modules/{$name}/', 'theme' => 'Themes/{$name}/' ); /** * Format package name. * * For package type asgard-module, cut off a trailing '-plugin' if present. * * For package type asgard-theme, cut off a trailing '-theme' if present. */ public function inflectPackageVars(array $vars): array { if ($vars['type'] === 'asgard-module') { return $this->inflectPluginVars($vars); } if ($vars['type'] === 'asgard-theme') { return $this->inflectThemeVars($vars); } return $vars; } /** * @param array $vars * @return array */ protected function inflectPluginVars(array $vars): array { $vars['name'] = $this->pregReplace('/-module$/', '', $vars['name']); $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); return $vars; } /** * @param array $vars * @return array */ protected function inflectThemeVars(array $vars): array { $vars['name'] = $this->pregReplace('/-theme$/', '', $vars['name']); $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); return $vars; } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/AttogramInstaller.php ================================================ */ protected $locations = array( 'module' => 'modules/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/BaseInstaller.php ================================================ */ protected $locations = array(); /** @var Composer */ protected $composer; /** @var PackageInterface */ protected $package; /** @var IOInterface */ protected $io; /** * Initializes base installer. */ public function __construct(PackageInterface $package, Composer $composer, IOInterface $io) { $this->composer = $composer; $this->package = $package; $this->io = $io; } /** * Return the install path based on package type. */ public function getInstallPath(PackageInterface $package, string $frameworkType = ''): string { $type = $this->package->getType(); $prettyName = $this->package->getPrettyName(); if (strpos($prettyName, '/') !== false) { list($vendor, $name) = explode('/', $prettyName); } else { $vendor = ''; $name = $prettyName; } $availableVars = $this->inflectPackageVars(compact('name', 'vendor', 'type')); $extra = $package->getExtra(); if (!empty($extra['installer-name'])) { $availableVars['name'] = $extra['installer-name']; } $extra = $this->composer->getPackage()->getExtra(); if (!empty($extra['installer-paths'])) { $customPath = $this->mapCustomInstallPaths($extra['installer-paths'], $prettyName, $type, $vendor); if ($customPath !== false) { return $this->templatePath($customPath, $availableVars); } } $packageType = substr($type, strlen($frameworkType) + 1); $locations = $this->getLocations($frameworkType); if (!isset($locations[$packageType])) { throw new \InvalidArgumentException(sprintf('Package type "%s" is not supported', $type)); } return $this->templatePath($locations[$packageType], $availableVars); } /** * For an installer to override to modify the vars per installer. * * @param array $vars This will normally receive array{name: string, vendor: string, type: string} * @return array */ public function inflectPackageVars(array $vars): array { return $vars; } /** * Gets the installer's locations * * @return array map of package types => install path */ public function getLocations(string $frameworkType) { return $this->locations; } /** * Replace vars in a path * * @param array $vars */ protected function templatePath(string $path, array $vars = array()): string { if (strpos($path, '{') !== false) { extract($vars); preg_match_all('@\{\$([A-Za-z0-9_]*)\}@i', $path, $matches); if (!empty($matches[1])) { foreach ($matches[1] as $var) { $path = str_replace('{$' . $var . '}', $$var, $path); } } } return $path; } /** * Search through a passed paths array for a custom install path. * * @param array $paths * @return string|false */ protected function mapCustomInstallPaths(array $paths, string $name, string $type, ?string $vendor = null) { foreach ($paths as $path => $names) { $names = (array) $names; if (in_array($name, $names) || in_array('type:' . $type, $names) || in_array('vendor:' . $vendor, $names)) { return $path; } } return false; } protected function pregReplace(string $pattern, string $replacement, string $subject): string { $result = preg_replace($pattern, $replacement, $subject); if (null === $result) { throw new \RuntimeException('Failed to run preg_replace with '.$pattern.': '.preg_last_error()); } return $result; } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/BitrixInstaller.php ================================================ .`. * - `bitrix-d7-component` — copy the component to directory `bitrix/components//`. * - `bitrix-d7-template` — copy the template to directory `bitrix/templates/_`. * * You can set custom path to directory with Bitrix kernel in `composer.json`: * * ```json * { * "extra": { * "bitrix-dir": "s1/bitrix" * } * } * ``` * * @author Nik Samokhvalov * @author Denis Kulichkin */ class BitrixInstaller extends BaseInstaller { /** @var array */ protected $locations = array( 'module' => '{$bitrix_dir}/modules/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken) 'component' => '{$bitrix_dir}/components/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken) 'theme' => '{$bitrix_dir}/templates/{$name}/', // deprecated, remove on the major release (Backward compatibility will be broken) 'd7-module' => '{$bitrix_dir}/modules/{$vendor}.{$name}/', 'd7-component' => '{$bitrix_dir}/components/{$vendor}/{$name}/', 'd7-template' => '{$bitrix_dir}/templates/{$vendor}_{$name}/', ); /** * @var string[] Storage for informations about duplicates at all the time of installation packages. */ private static $checkedDuplicates = array(); public function inflectPackageVars(array $vars): array { /** @phpstan-ignore-next-line */ if ($this->composer->getPackage()) { $extra = $this->composer->getPackage()->getExtra(); if (isset($extra['bitrix-dir'])) { $vars['bitrix_dir'] = $extra['bitrix-dir']; } } if (!isset($vars['bitrix_dir'])) { $vars['bitrix_dir'] = 'bitrix'; } return parent::inflectPackageVars($vars); } /** * {@inheritdoc} */ protected function templatePath(string $path, array $vars = array()): string { $templatePath = parent::templatePath($path, $vars); $this->checkDuplicates($templatePath, $vars); return $templatePath; } /** * Duplicates search packages. * * @param array $vars */ protected function checkDuplicates(string $path, array $vars = array()): void { $packageType = substr($vars['type'], strlen('bitrix') + 1); $localDir = explode('/', $vars['bitrix_dir']); array_pop($localDir); $localDir[] = 'local'; $localDir = implode('/', $localDir); $oldPath = str_replace( array('{$bitrix_dir}', '{$name}'), array($localDir, $vars['name']), $this->locations[$packageType] ); if (in_array($oldPath, static::$checkedDuplicates)) { return; } if ($oldPath !== $path && file_exists($oldPath) && $this->io->isInteractive()) { $this->io->writeError(' Duplication of packages:'); $this->io->writeError(' Package ' . $oldPath . ' will be called instead package ' . $path . ''); while (true) { switch ($this->io->ask(' Delete ' . $oldPath . ' [y,n,?]? ', '?')) { case 'y': $fs = new Filesystem(); $fs->removeDirectory($oldPath); break 2; case 'n': break 2; case '?': default: $this->io->writeError(array( ' y - delete package ' . $oldPath . ' and to continue with the installation', ' n - don\'t delete and to continue with the installation', )); $this->io->writeError(' ? - print help'); break; } } } static::$checkedDuplicates[] = $oldPath; } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/BonefishInstaller.php ================================================ */ protected $locations = array( 'package' => 'Packages/{$vendor}/{$name}/' ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/BotbleInstaller.php ================================================ */ protected $locations = array( 'plugin' => 'platform/plugins/{$name}/', 'theme' => 'platform/themes/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/CakePHPInstaller.php ================================================ */ protected $locations = array( 'plugin' => 'Plugin/{$name}/', ); /** * Format package name to CamelCase */ public function inflectPackageVars(array $vars): array { if ($this->matchesCakeVersion('>=', '3.0.0')) { return $vars; } $nameParts = explode('/', $vars['name']); foreach ($nameParts as &$value) { $value = strtolower($this->pregReplace('/(?<=\\w)([A-Z])/', '_\\1', $value)); $value = str_replace(array('-', '_'), ' ', $value); $value = str_replace(' ', '', ucwords($value)); } $vars['name'] = implode('/', $nameParts); return $vars; } /** * Change the default plugin location when cakephp >= 3.0 */ public function getLocations(string $frameworkType): array { if ($this->matchesCakeVersion('>=', '3.0.0')) { $this->locations['plugin'] = $this->composer->getConfig()->get('vendor-dir') . '/{$vendor}/{$name}/'; } return $this->locations; } /** * Check if CakePHP version matches against a version * * @phpstan-param '='|'=='|'<'|'<='|'>'|'>='|'<>'|'!=' $matcher */ protected function matchesCakeVersion(string $matcher, string $version): bool { $repositoryManager = $this->composer->getRepositoryManager(); /** @phpstan-ignore-next-line */ if (!$repositoryManager) { return false; } $repos = $repositoryManager->getLocalRepository(); /** @phpstan-ignore-next-line */ if (!$repos) { return false; } return $repos->findPackage('cakephp/cakephp', new Constraint($matcher, $version)) !== null; } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/ChefInstaller.php ================================================ */ protected $locations = array( 'cookbook' => 'Chef/{$vendor}/{$name}/', 'role' => 'Chef/roles/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/CiviCrmInstaller.php ================================================ */ protected $locations = array( 'ext' => 'ext/{$name}/' ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/ClanCatsFrameworkInstaller.php ================================================ */ protected $locations = array( 'ship' => 'CCF/orbit/{$name}/', 'theme' => 'CCF/app/themes/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/CockpitInstaller.php ================================================ */ protected $locations = array( 'module' => 'cockpit/modules/addons/{$name}/', ); /** * Format module name. * * Strip `module-` prefix from package name. */ public function inflectPackageVars(array $vars): array { if ($vars['type'] == 'cockpit-module') { return $this->inflectModuleVars($vars); } return $vars; } /** * @param array $vars * @return array */ public function inflectModuleVars(array $vars): array { $vars['name'] = ucfirst($this->pregReplace('/cockpit-/i', '', $vars['name'])); return $vars; } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/CodeIgniterInstaller.php ================================================ */ protected $locations = array( 'library' => 'application/libraries/{$name}/', 'third-party' => 'application/third_party/{$name}/', 'module' => 'application/modules/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/Concrete5Installer.php ================================================ */ protected $locations = array( 'core' => 'concrete/', 'block' => 'application/blocks/{$name}/', 'package' => 'packages/{$name}/', 'theme' => 'application/themes/{$name}/', 'update' => 'updates/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/ConcreteCMSInstaller.php ================================================ */ protected $locations = array( 'core' => 'concrete/', 'block' => 'application/blocks/{$name}/', 'package' => 'packages/{$name}/', 'theme' => 'application/themes/{$name}/', 'update' => 'updates/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/CroogoInstaller.php ================================================ */ protected $locations = array( 'plugin' => 'Plugin/{$name}/', 'theme' => 'View/Themed/{$name}/', ); /** * Format package name to CamelCase */ public function inflectPackageVars(array $vars): array { $vars['name'] = strtolower(str_replace(array('-', '_'), ' ', $vars['name'])); $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); return $vars; } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/DecibelInstaller.php ================================================ */ protected $locations = array( 'app' => 'app/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/DframeInstaller.php ================================================ */ protected $locations = array( 'module' => 'modules/{$vendor}/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/DokuWikiInstaller.php ================================================ */ protected $locations = array( 'plugin' => 'lib/plugins/{$name}/', 'template' => 'lib/tpl/{$name}/', ); /** * Format package name. * * For package type dokuwiki-plugin, cut off a trailing '-plugin', * or leading dokuwiki_ if present. * * For package type dokuwiki-template, cut off a trailing '-template' if present. */ public function inflectPackageVars(array $vars): array { if ($vars['type'] === 'dokuwiki-plugin') { return $this->inflectPluginVars($vars); } if ($vars['type'] === 'dokuwiki-template') { return $this->inflectTemplateVars($vars); } return $vars; } /** * @param array $vars * @return array */ protected function inflectPluginVars(array $vars): array { $vars['name'] = $this->pregReplace('/-plugin$/', '', $vars['name']); $vars['name'] = $this->pregReplace('/^dokuwiki_?-?/', '', $vars['name']); return $vars; } /** * @param array $vars * @return array */ protected function inflectTemplateVars(array $vars): array { $vars['name'] = $this->pregReplace('/-template$/', '', $vars['name']); $vars['name'] = $this->pregReplace('/^dokuwiki_?-?/', '', $vars['name']); return $vars; } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/DolibarrInstaller.php ================================================ */ class DolibarrInstaller extends BaseInstaller { //TODO: Add support for scripts and themes /** @var array */ protected $locations = array( 'module' => 'htdocs/custom/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/DrupalInstaller.php ================================================ */ protected $locations = array( 'core' => 'core/', 'module' => 'modules/{$name}/', 'theme' => 'themes/{$name}/', 'library' => 'libraries/{$name}/', 'profile' => 'profiles/{$name}/', 'database-driver' => 'drivers/lib/Drupal/Driver/Database/{$name}/', 'drush' => 'drush/{$name}/', 'custom-theme' => 'themes/custom/{$name}/', 'custom-module' => 'modules/custom/{$name}/', 'custom-profile' => 'profiles/custom/{$name}/', 'drupal-multisite' => 'sites/{$name}/', 'console' => 'console/{$name}/', 'console-language' => 'console/language/{$name}/', 'config' => 'config/sync/', 'recipe' => 'recipes/{$name}', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/ElggInstaller.php ================================================ */ protected $locations = array( 'plugin' => 'mod/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/EliasisInstaller.php ================================================ */ protected $locations = array( 'component' => 'components/{$name}/', 'module' => 'modules/{$name}/', 'plugin' => 'plugins/{$name}/', 'template' => 'templates/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/ExpressionEngineInstaller.php ================================================ */ private $ee2Locations = array( 'addon' => 'system/expressionengine/third_party/{$name}/', 'theme' => 'themes/third_party/{$name}/', ); /** @var array */ private $ee3Locations = array( 'addon' => 'system/user/addons/{$name}/', 'theme' => 'themes/user/{$name}/', ); public function getLocations(string $frameworkType): array { if ($frameworkType === 'ee2') { $this->locations = $this->ee2Locations; } else { $this->locations = $this->ee3Locations; } return $this->locations; } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/EzPlatformInstaller.php ================================================ */ protected $locations = array( 'meta-assets' => 'web/assets/ezplatform/', 'assets' => 'web/assets/ezplatform/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/ForkCMSInstaller.php ================================================ */ protected $locations = [ 'module' => 'src/Modules/{$name}/', 'theme' => 'src/Themes/{$name}/' ]; /** * Format package name. * * For package type fork-cms-module, cut off a trailing '-plugin' if present. * * For package type fork-cms-theme, cut off a trailing '-theme' if present. */ public function inflectPackageVars(array $vars): array { if ($vars['type'] === 'fork-cms-module') { return $this->inflectModuleVars($vars); } if ($vars['type'] === 'fork-cms-theme') { return $this->inflectThemeVars($vars); } return $vars; } /** * @param array $vars * @return array */ protected function inflectModuleVars(array $vars): array { $vars['name'] = $this->pregReplace('/^fork-cms-|-module|ForkCMS|ForkCms|Forkcms|forkcms|Module$/', '', $vars['name']); $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); // replace hyphens with spaces $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); // make module name camelcased return $vars; } /** * @param array $vars * @return array */ protected function inflectThemeVars(array $vars): array { $vars['name'] = $this->pregReplace('/^fork-cms-|-theme|ForkCMS|ForkCms|Forkcms|forkcms|Theme$/', '', $vars['name']); $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); // replace hyphens with spaces $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); // make theme name camelcased return $vars; } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/FuelInstaller.php ================================================ */ protected $locations = array( 'module' => 'fuel/app/modules/{$name}/', 'package' => 'fuel/packages/{$name}/', 'theme' => 'fuel/app/themes/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/FuelphpInstaller.php ================================================ */ protected $locations = array( 'component' => 'components/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/GravInstaller.php ================================================ */ protected $locations = array( 'plugin' => 'user/plugins/{$name}/', 'theme' => 'user/themes/{$name}/', ); /** * Format package name */ public function inflectPackageVars(array $vars): array { $restrictedWords = implode('|', array_keys($this->locations)); $vars['name'] = strtolower($vars['name']); $vars['name'] = $this->pregReplace( '/^(?:grav-)?(?:(?:'.$restrictedWords.')-)?(.*?)(?:-(?:'.$restrictedWords.'))?$/ui', '$1', $vars['name'] ); return $vars; } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/HuradInstaller.php ================================================ */ protected $locations = array( 'plugin' => 'plugins/{$name}/', 'theme' => 'plugins/{$name}/', ); /** * Format package name to CamelCase */ public function inflectPackageVars(array $vars): array { $nameParts = explode('/', $vars['name']); foreach ($nameParts as &$value) { $value = strtolower($this->pregReplace('/(?<=\\w)([A-Z])/', '_\\1', $value)); $value = str_replace(array('-', '_'), ' ', $value); $value = str_replace(' ', '', ucwords($value)); } $vars['name'] = implode('/', $nameParts); return $vars; } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/ImageCMSInstaller.php ================================================ */ protected $locations = array( 'template' => 'templates/{$name}/', 'module' => 'application/modules/{$name}/', 'library' => 'application/libraries/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/Installer.php ================================================ */ private $supportedTypes = array( 'akaunting' => 'AkauntingInstaller', 'asgard' => 'AsgardInstaller', 'attogram' => 'AttogramInstaller', 'agl' => 'AglInstaller', 'annotatecms' => 'AnnotateCmsInstaller', 'bitrix' => 'BitrixInstaller', 'botble' => 'BotbleInstaller', 'bonefish' => 'BonefishInstaller', 'cakephp' => 'CakePHPInstaller', 'chef' => 'ChefInstaller', 'civicrm' => 'CiviCrmInstaller', 'ccframework' => 'ClanCatsFrameworkInstaller', 'cockpit' => 'CockpitInstaller', 'codeigniter' => 'CodeIgniterInstaller', 'concrete5' => 'Concrete5Installer', 'concretecms' => 'ConcreteCMSInstaller', 'croogo' => 'CroogoInstaller', 'dframe' => 'DframeInstaller', 'dokuwiki' => 'DokuWikiInstaller', 'dolibarr' => 'DolibarrInstaller', 'decibel' => 'DecibelInstaller', 'drupal' => 'DrupalInstaller', 'elgg' => 'ElggInstaller', 'eliasis' => 'EliasisInstaller', 'ee3' => 'ExpressionEngineInstaller', 'ee2' => 'ExpressionEngineInstaller', 'ezplatform' => 'EzPlatformInstaller', 'fork' => 'ForkCMSInstaller', 'fuel' => 'FuelInstaller', 'fuelphp' => 'FuelphpInstaller', 'grav' => 'GravInstaller', 'hurad' => 'HuradInstaller', 'tastyigniter' => 'TastyIgniterInstaller', 'imagecms' => 'ImageCMSInstaller', 'itop' => 'ItopInstaller', 'kanboard' => 'KanboardInstaller', 'known' => 'KnownInstaller', 'kodicms' => 'KodiCMSInstaller', 'kohana' => 'KohanaInstaller', 'lms' => 'LanManagementSystemInstaller', 'laravel' => 'LaravelInstaller', 'lavalite' => 'LavaLiteInstaller', 'lithium' => 'LithiumInstaller', 'magento' => 'MagentoInstaller', 'majima' => 'MajimaInstaller', 'mantisbt' => 'MantisBTInstaller', 'mako' => 'MakoInstaller', 'matomo' => 'MatomoInstaller', 'maya' => 'MayaInstaller', 'mautic' => 'MauticInstaller', 'mediawiki' => 'MediaWikiInstaller', 'miaoxing' => 'MiaoxingInstaller', 'microweber' => 'MicroweberInstaller', 'modulework' => 'MODULEWorkInstaller', 'modx' => 'ModxInstaller', 'modxevo' => 'MODXEvoInstaller', 'moodle' => 'MoodleInstaller', 'october' => 'OctoberInstaller', 'ontowiki' => 'OntoWikiInstaller', 'oxid' => 'OxidInstaller', 'osclass' => 'OsclassInstaller', 'pxcms' => 'PxcmsInstaller', 'phpbb' => 'PhpBBInstaller', 'piwik' => 'PiwikInstaller', 'plentymarkets'=> 'PlentymarketsInstaller', 'ppi' => 'PPIInstaller', 'puppet' => 'PuppetInstaller', 'radphp' => 'RadPHPInstaller', 'phifty' => 'PhiftyInstaller', 'porto' => 'PortoInstaller', 'processwire' => 'ProcessWireInstaller', 'quicksilver' => 'PantheonInstaller', 'redaxo' => 'RedaxoInstaller', 'redaxo5' => 'Redaxo5Installer', 'reindex' => 'ReIndexInstaller', 'roundcube' => 'RoundcubeInstaller', 'shopware' => 'ShopwareInstaller', 'sitedirect' => 'SiteDirectInstaller', 'silverstripe' => 'SilverStripeInstaller', 'smf' => 'SMFInstaller', 'starbug' => 'StarbugInstaller', 'sydes' => 'SyDESInstaller', 'sylius' => 'SyliusInstaller', 'tao' => 'TaoInstaller', 'thelia' => 'TheliaInstaller', 'tusk' => 'TuskInstaller', 'userfrosting' => 'UserFrostingInstaller', 'vanilla' => 'VanillaInstaller', 'whmcs' => 'WHMCSInstaller', 'winter' => 'WinterInstaller', 'wolfcms' => 'WolfCMSInstaller', 'wordpress' => 'WordPressInstaller', 'yawik' => 'YawikInstaller', 'zend' => 'ZendInstaller', 'zikula' => 'ZikulaInstaller', 'prestashop' => 'PrestashopInstaller' ); /** * Disables installers specified in main composer extra installer-disable * list */ public function __construct( IOInterface $io, Composer $composer, string $type = 'library', ?Filesystem $filesystem = null, ?BinaryInstaller $binaryInstaller = null ) { parent::__construct($io, $composer, $type, $filesystem, $binaryInstaller); $this->removeDisabledInstallers(); } /** * {@inheritDoc} */ public function getInstallPath(PackageInterface $package) { $type = $package->getType(); $frameworkType = $this->findFrameworkType($type); if ($frameworkType === false) { throw new \InvalidArgumentException( 'Sorry the package type of this package is not yet supported.' ); } $class = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType]; /** * @var BaseInstaller */ $installer = new $class($package, $this->composer, $this->getIO()); $path = $installer->getInstallPath($package, $frameworkType); if (!$this->filesystem->isAbsolutePath($path)) { $path = getcwd() . '/' . $path; } return $path; } public function uninstall(InstalledRepositoryInterface $repo, PackageInterface $package) { $installPath = $this->getPackageBasePath($package); $io = $this->io; $outputStatus = function () use ($io, $installPath) { $io->write(sprintf('Deleting %s - %s', $installPath, !file_exists($installPath) ? 'deleted' : 'not deleted')); }; $promise = parent::uninstall($repo, $package); // Composer v2 might return a promise here if ($promise instanceof PromiseInterface) { return $promise->then($outputStatus); } // If not, execute the code right away as parent::uninstall executed synchronously (composer v1, or v2 without async) $outputStatus(); return null; } /** * {@inheritDoc} * * @param string $packageType */ public function supports($packageType) { $frameworkType = $this->findFrameworkType($packageType); if ($frameworkType === false) { return false; } $locationPattern = $this->getLocationPattern($frameworkType); return preg_match('#' . $frameworkType . '-' . $locationPattern . '#', $packageType, $matches) === 1; } /** * Finds a supported framework type if it exists and returns it * * @return string|false */ protected function findFrameworkType(string $type) { krsort($this->supportedTypes); foreach ($this->supportedTypes as $key => $val) { if ($key === substr($type, 0, strlen($key))) { return substr($type, 0, strlen($key)); } } return false; } /** * Get the second part of the regular expression to check for support of a * package type */ protected function getLocationPattern(string $frameworkType): string { $pattern = null; if (!empty($this->supportedTypes[$frameworkType])) { $frameworkClass = 'Composer\\Installers\\' . $this->supportedTypes[$frameworkType]; /** @var BaseInstaller $framework */ $framework = new $frameworkClass(new Package('dummy/pkg', '1.0.0.0', '1.0.0'), $this->composer, $this->getIO()); $locations = array_keys($framework->getLocations($frameworkType)); if ($locations) { $pattern = '(' . implode('|', $locations) . ')'; } } return $pattern ?: '(\w+)'; } private function getIO(): IOInterface { return $this->io; } /** * Look for installers set to be disabled in composer's extra config and * remove them from the list of supported installers. * * Globals: * - true, "all", and "*" - disable all installers. * - false - enable all installers (useful with * wikimedia/composer-merge-plugin or similar) */ protected function removeDisabledInstallers(): void { $extra = $this->composer->getPackage()->getExtra(); if (!isset($extra['installer-disable']) || $extra['installer-disable'] === false) { // No installers are disabled return; } // Get installers to disable $disable = $extra['installer-disable']; // Ensure $disabled is an array if (!is_array($disable)) { $disable = array($disable); } // Check which installers should be disabled $all = array(true, "all", "*"); $intersect = array_intersect($all, $disable); if (!empty($intersect)) { // Disable all installers $this->supportedTypes = array(); return; } // Disable specified installers foreach ($disable as $key => $installer) { if (is_string($installer) && key_exists($installer, $this->supportedTypes)) { unset($this->supportedTypes[$installer]); } } } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/ItopInstaller.php ================================================ */ protected $locations = array( 'extension' => 'extensions/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/KanboardInstaller.php ================================================ */ protected $locations = array( 'plugin' => 'plugins/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/KnownInstaller.php ================================================ */ protected $locations = array( 'plugin' => 'IdnoPlugins/{$name}/', 'theme' => 'Themes/{$name}/', 'console' => 'ConsolePlugins/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/KodiCMSInstaller.php ================================================ */ protected $locations = array( 'plugin' => 'cms/plugins/{$name}/', 'media' => 'cms/media/vendor/{$name}/' ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/KohanaInstaller.php ================================================ */ protected $locations = array( 'module' => 'modules/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/LanManagementSystemInstaller.php ================================================ */ protected $locations = array( 'plugin' => 'plugins/{$name}/', 'template' => 'templates/{$name}/', 'document-template' => 'documents/templates/{$name}/', 'userpanel-module' => 'userpanel/modules/{$name}/', ); /** * Format package name to CamelCase */ public function inflectPackageVars(array $vars): array { $vars['name'] = strtolower($this->pregReplace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name'])); $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); return $vars; } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/LaravelInstaller.php ================================================ */ protected $locations = array( 'library' => 'libraries/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/LavaLiteInstaller.php ================================================ */ protected $locations = array( 'package' => 'packages/{$vendor}/{$name}/', 'theme' => 'public/themes/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/LithiumInstaller.php ================================================ */ protected $locations = array( 'library' => 'libraries/{$name}/', 'source' => 'libraries/_source/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/MODULEWorkInstaller.php ================================================ */ protected $locations = array( 'module' => 'modules/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/MODXEvoInstaller.php ================================================ */ protected $locations = array( 'snippet' => 'assets/snippets/{$name}/', 'plugin' => 'assets/plugins/{$name}/', 'module' => 'assets/modules/{$name}/', 'template' => 'assets/templates/{$name}/', 'lib' => 'assets/lib/{$name}/' ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/MagentoInstaller.php ================================================ */ protected $locations = array( 'theme' => 'app/design/frontend/{$name}/', 'skin' => 'skin/frontend/default/{$name}/', 'library' => 'lib/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/MajimaInstaller.php ================================================ */ protected $locations = array( 'plugin' => 'plugins/{$name}/', ); /** * Transforms the names * * @param array $vars * @return array */ public function inflectPackageVars(array $vars): array { return $this->correctPluginName($vars); } /** * Change hyphenated names to camelcase * * @param array $vars * @return array */ private function correctPluginName(array $vars): array { $camelCasedName = preg_replace_callback('/(-[a-z])/', function ($matches) { return strtoupper($matches[0][1]); }, $vars['name']); if (null === $camelCasedName) { throw new \RuntimeException('Failed to run preg_replace_callback: '.preg_last_error()); } $vars['name'] = ucfirst($camelCasedName); return $vars; } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/MakoInstaller.php ================================================ */ protected $locations = array( 'package' => 'app/packages/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/MantisBTInstaller.php ================================================ */ protected $locations = array( 'plugin' => 'plugins/{$name}/', ); /** * Format package name to CamelCase */ public function inflectPackageVars(array $vars): array { $vars['name'] = strtolower($this->pregReplace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name'])); $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); return $vars; } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/MatomoInstaller.php ================================================ */ protected $locations = array( 'plugin' => 'plugins/{$name}/', ); /** * Format package name to CamelCase */ public function inflectPackageVars(array $vars): array { $vars['name'] = strtolower($this->pregReplace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name'])); $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); return $vars; } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/MauticInstaller.php ================================================ */ protected $locations = array( 'plugin' => 'plugins/{$name}/', 'theme' => 'themes/{$name}/', 'core' => 'app/', ); private function getDirectoryName(): string { $extra = $this->package->getExtra(); if (!empty($extra['install-directory-name'])) { return $extra['install-directory-name']; } return $this->toCamelCase($this->package->getPrettyName()); } private function toCamelCase(string $packageName): string { return str_replace(' ', '', ucwords(str_replace('-', ' ', basename($packageName)))); } /** * Format package name of mautic-plugins to CamelCase */ public function inflectPackageVars(array $vars): array { if ($vars['type'] == 'mautic-plugin' || $vars['type'] == 'mautic-theme') { $directoryName = $this->getDirectoryName(); $vars['name'] = $directoryName; } return $vars; } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/MayaInstaller.php ================================================ */ protected $locations = array( 'module' => 'modules/{$name}/', ); /** * Format package name. * * For package type maya-module, cut off a trailing '-module' if present. */ public function inflectPackageVars(array $vars): array { if ($vars['type'] === 'maya-module') { return $this->inflectModuleVars($vars); } return $vars; } /** * @param array $vars * @return array */ protected function inflectModuleVars(array $vars): array { $vars['name'] = $this->pregReplace('/-module$/', '', $vars['name']); $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); return $vars; } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/MediaWikiInstaller.php ================================================ */ protected $locations = array( 'core' => 'core/', 'extension' => 'extensions/{$name}/', 'skin' => 'skins/{$name}/', ); /** * Format package name. * * For package type mediawiki-extension, cut off a trailing '-extension' if present and transform * to CamelCase keeping existing uppercase chars. * * For package type mediawiki-skin, cut off a trailing '-skin' if present. */ public function inflectPackageVars(array $vars): array { if ($vars['type'] === 'mediawiki-extension') { return $this->inflectExtensionVars($vars); } if ($vars['type'] === 'mediawiki-skin') { return $this->inflectSkinVars($vars); } return $vars; } /** * @param array $vars * @return array */ protected function inflectExtensionVars(array $vars): array { $vars['name'] = $this->pregReplace('/-extension$/', '', $vars['name']); $vars['name'] = str_replace('-', ' ', $vars['name']); $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); return $vars; } /** * @param array $vars * @return array */ protected function inflectSkinVars(array $vars): array { $vars['name'] = $this->pregReplace('/-skin$/', '', $vars['name']); return $vars; } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/MiaoxingInstaller.php ================================================ */ protected $locations = array( 'plugin' => 'plugins/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/MicroweberInstaller.php ================================================ */ protected $locations = array( 'module' => 'userfiles/modules/{$install_item_dir}/', 'module-skin' => 'userfiles/modules/{$install_item_dir}/templates/', 'template' => 'userfiles/templates/{$install_item_dir}/', 'element' => 'userfiles/elements/{$install_item_dir}/', 'vendor' => 'vendor/{$install_item_dir}/', 'components' => 'components/{$install_item_dir}/' ); /** * Format package name. * * For package type microweber-module, cut off a trailing '-module' if present * * For package type microweber-template, cut off a trailing '-template' if present. */ public function inflectPackageVars(array $vars): array { if ($this->package->getTargetDir() !== null && $this->package->getTargetDir() !== '') { $vars['install_item_dir'] = $this->package->getTargetDir(); } else { $vars['install_item_dir'] = $vars['name']; if ($vars['type'] === 'microweber-template') { return $this->inflectTemplateVars($vars); } if ($vars['type'] === 'microweber-templates') { return $this->inflectTemplatesVars($vars); } if ($vars['type'] === 'microweber-core') { return $this->inflectCoreVars($vars); } if ($vars['type'] === 'microweber-adapter') { return $this->inflectCoreVars($vars); } if ($vars['type'] === 'microweber-module') { return $this->inflectModuleVars($vars); } if ($vars['type'] === 'microweber-modules') { return $this->inflectModulesVars($vars); } if ($vars['type'] === 'microweber-skin') { return $this->inflectSkinVars($vars); } if ($vars['type'] === 'microweber-element' or $vars['type'] === 'microweber-elements') { return $this->inflectElementVars($vars); } } return $vars; } /** * @param array $vars * @return array */ protected function inflectTemplateVars(array $vars): array { $vars['install_item_dir'] = $this->pregReplace('/-template$/', '', $vars['install_item_dir']); $vars['install_item_dir'] = $this->pregReplace('/template-$/', '', $vars['install_item_dir']); return $vars; } /** * @param array $vars * @return array */ protected function inflectTemplatesVars(array $vars): array { $vars['install_item_dir'] = $this->pregReplace('/-templates$/', '', $vars['install_item_dir']); $vars['install_item_dir'] = $this->pregReplace('/templates-$/', '', $vars['install_item_dir']); return $vars; } /** * @param array $vars * @return array */ protected function inflectCoreVars(array $vars): array { $vars['install_item_dir'] = $this->pregReplace('/-providers$/', '', $vars['install_item_dir']); $vars['install_item_dir'] = $this->pregReplace('/-provider$/', '', $vars['install_item_dir']); $vars['install_item_dir'] = $this->pregReplace('/-adapter$/', '', $vars['install_item_dir']); return $vars; } /** * @param array $vars * @return array */ protected function inflectModuleVars(array $vars): array { $vars['install_item_dir'] = $this->pregReplace('/-module$/', '', $vars['install_item_dir']); $vars['install_item_dir'] = $this->pregReplace('/module-$/', '', $vars['install_item_dir']); return $vars; } /** * @param array $vars * @return array */ protected function inflectModulesVars(array $vars): array { $vars['install_item_dir'] = $this->pregReplace('/-modules$/', '', $vars['install_item_dir']); $vars['install_item_dir'] = $this->pregReplace('/modules-$/', '', $vars['install_item_dir']); return $vars; } /** * @param array $vars * @return array */ protected function inflectSkinVars(array $vars): array { $vars['install_item_dir'] = $this->pregReplace('/-skin$/', '', $vars['install_item_dir']); $vars['install_item_dir'] = $this->pregReplace('/skin-$/', '', $vars['install_item_dir']); return $vars; } /** * @param array $vars * @return array */ protected function inflectElementVars(array $vars): array { $vars['install_item_dir'] = $this->pregReplace('/-elements$/', '', $vars['install_item_dir']); $vars['install_item_dir'] = $this->pregReplace('/elements-$/', '', $vars['install_item_dir']); $vars['install_item_dir'] = $this->pregReplace('/-element$/', '', $vars['install_item_dir']); $vars['install_item_dir'] = $this->pregReplace('/element-$/', '', $vars['install_item_dir']); return $vars; } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/ModxInstaller.php ================================================ */ protected $locations = array( 'extra' => 'core/packages/{$name}/' ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/MoodleInstaller.php ================================================ */ protected $locations = array( 'mod' => 'mod/{$name}/', 'admin_report' => 'admin/report/{$name}/', 'atto' => 'lib/editor/atto/plugins/{$name}/', 'tool' => 'admin/tool/{$name}/', 'assignment' => 'mod/assignment/type/{$name}/', 'assignsubmission' => 'mod/assign/submission/{$name}/', 'assignfeedback' => 'mod/assign/feedback/{$name}/', 'antivirus' => 'lib/antivirus/{$name}/', 'auth' => 'auth/{$name}/', 'availability' => 'availability/condition/{$name}/', 'block' => 'blocks/{$name}/', 'booktool' => 'mod/book/tool/{$name}/', 'cachestore' => 'cache/stores/{$name}/', 'cachelock' => 'cache/locks/{$name}/', 'calendartype' => 'calendar/type/{$name}/', 'communication' => 'communication/provider/{$name}/', 'customfield' => 'customfield/field/{$name}/', 'fileconverter' => 'files/converter/{$name}/', 'format' => 'course/format/{$name}/', 'coursereport' => 'course/report/{$name}/', 'contenttype' => 'contentbank/contenttype/{$name}/', 'customcertelement' => 'mod/customcert/element/{$name}/', 'datafield' => 'mod/data/field/{$name}/', 'dataformat' => 'dataformat/{$name}/', 'datapreset' => 'mod/data/preset/{$name}/', 'editor' => 'lib/editor/{$name}/', 'enrol' => 'enrol/{$name}/', 'filter' => 'filter/{$name}/', 'forumreport' => 'mod/forum/report/{$name}/', 'gradeexport' => 'grade/export/{$name}/', 'gradeimport' => 'grade/import/{$name}/', 'gradereport' => 'grade/report/{$name}/', 'gradingform' => 'grade/grading/form/{$name}/', 'h5plib' => 'h5p/h5plib/{$name}/', 'local' => 'local/{$name}/', 'logstore' => 'admin/tool/log/store/{$name}/', 'ltisource' => 'mod/lti/source/{$name}/', 'ltiservice' => 'mod/lti/service/{$name}/', 'media' => 'media/player/{$name}/', 'message' => 'message/output/{$name}/', 'mlbackend' => 'lib/mlbackend/{$name}/', 'mnetservice' => 'mnet/service/{$name}/', 'paygw' => 'payment/gateway/{$name}/', 'plagiarism' => 'plagiarism/{$name}/', 'portfolio' => 'portfolio/{$name}/', 'qbank' => 'question/bank/{$name}/', 'qbehaviour' => 'question/behaviour/{$name}/', 'qformat' => 'question/format/{$name}/', 'qtype' => 'question/type/{$name}/', 'quizaccess' => 'mod/quiz/accessrule/{$name}/', 'quiz' => 'mod/quiz/report/{$name}/', 'report' => 'report/{$name}/', 'repository' => 'repository/{$name}/', 'scormreport' => 'mod/scorm/report/{$name}/', 'search' => 'search/engine/{$name}/', 'theme' => 'theme/{$name}/', 'tiny' => 'lib/editor/tiny/plugins/{$name}/', 'tinymce' => 'lib/editor/tinymce/plugins/{$name}/', 'profilefield' => 'user/profile/field/{$name}/', 'webservice' => 'webservice/{$name}/', 'workshopallocation' => 'mod/workshop/allocation/{$name}/', 'workshopeval' => 'mod/workshop/eval/{$name}/', 'workshopform' => 'mod/workshop/form/{$name}/' ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/OctoberInstaller.php ================================================ */ protected $locations = array( 'module' => 'modules/{$name}/', 'plugin' => 'plugins/{$vendor}/{$name}/', 'theme' => 'themes/{$vendor}-{$name}/' ); /** * Format package name. * * For package type october-plugin, cut off a trailing '-plugin' if present. * * For package type october-theme, cut off a trailing '-theme' if present. */ public function inflectPackageVars(array $vars): array { if ($vars['type'] === 'october-plugin') { return $this->inflectPluginVars($vars); } if ($vars['type'] === 'october-theme') { return $this->inflectThemeVars($vars); } return $vars; } /** * @param array $vars * @return array */ protected function inflectPluginVars(array $vars): array { $vars['name'] = $this->pregReplace('/^oc-|-plugin$/', '', $vars['name']); $vars['vendor'] = $this->pregReplace('/[^a-z0-9_]/i', '', $vars['vendor']); return $vars; } /** * @param array $vars * @return array */ protected function inflectThemeVars(array $vars): array { $vars['name'] = $this->pregReplace('/^oc-|-theme$/', '', $vars['name']); $vars['vendor'] = $this->pregReplace('/[^a-z0-9_]/i', '', $vars['vendor']); return $vars; } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/OntoWikiInstaller.php ================================================ */ protected $locations = array( 'extension' => 'extensions/{$name}/', 'theme' => 'extensions/themes/{$name}/', 'translation' => 'extensions/translations/{$name}/', ); /** * Format package name to lower case and remove ".ontowiki" suffix */ public function inflectPackageVars(array $vars): array { $vars['name'] = strtolower($vars['name']); $vars['name'] = $this->pregReplace('/.ontowiki$/', '', $vars['name']); $vars['name'] = $this->pregReplace('/-theme$/', '', $vars['name']); $vars['name'] = $this->pregReplace('/-translation$/', '', $vars['name']); return $vars; } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/OsclassInstaller.php ================================================ */ protected $locations = array( 'plugin' => 'oc-content/plugins/{$name}/', 'theme' => 'oc-content/themes/{$name}/', 'language' => 'oc-content/languages/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/OxidInstaller.php ================================================ .+)\/.+/'; /** @var array */ protected $locations = array( 'module' => 'modules/{$name}/', 'theme' => 'application/views/{$name}/', 'out' => 'out/{$name}/', ); public function getInstallPath(PackageInterface $package, string $frameworkType = ''): string { $installPath = parent::getInstallPath($package, $frameworkType); $type = $this->package->getType(); if ($type === 'oxid-module') { $this->prepareVendorDirectory($installPath); } return $installPath; } /** * Makes sure there is a vendormetadata.php file inside * the vendor folder if there is a vendor folder. */ protected function prepareVendorDirectory(string $installPath): void { $matches = ''; $hasVendorDirectory = preg_match(self::VENDOR_PATTERN, $installPath, $matches); if (!$hasVendorDirectory) { return; } $vendorDirectory = $matches['vendor']; $vendorPath = getcwd() . '/modules/' . $vendorDirectory; if (!file_exists($vendorPath)) { mkdir($vendorPath, 0755, true); } $vendorMetaDataPath = $vendorPath . '/vendormetadata.php'; touch($vendorMetaDataPath); } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/PPIInstaller.php ================================================ */ protected $locations = array( 'module' => 'modules/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/PantheonInstaller.php ================================================ */ protected $locations = array( 'script' => 'web/private/scripts/quicksilver/{$name}', 'module' => 'web/private/scripts/quicksilver/{$name}', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/PhiftyInstaller.php ================================================ */ protected $locations = array( 'bundle' => 'bundles/{$name}/', 'library' => 'libraries/{$name}/', 'framework' => 'frameworks/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/PhpBBInstaller.php ================================================ */ protected $locations = array( 'extension' => 'ext/{$vendor}/{$name}/', 'language' => 'language/{$name}/', 'style' => 'styles/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/PiwikInstaller.php ================================================ */ protected $locations = array( 'plugin' => 'plugins/{$name}/', ); /** * Format package name to CamelCase */ public function inflectPackageVars(array $vars): array { $vars['name'] = strtolower($this->pregReplace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name'])); $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); return $vars; } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/PlentymarketsInstaller.php ================================================ */ protected $locations = array( 'plugin' => '{$name}/' ); /** * Remove hyphen, "plugin" and format to camelcase */ public function inflectPackageVars(array $vars): array { $nameBits = explode("-", $vars['name']); foreach ($nameBits as $key => $name) { $nameBits[$key] = ucfirst($name); if (strcasecmp($name, "Plugin") == 0) { unset($nameBits[$key]); } } $vars['name'] = implode('', $nameBits); return $vars; } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/Plugin.php ================================================ installer = new Installer($io, $composer); $composer->getInstallationManager()->addInstaller($this->installer); } public function deactivate(Composer $composer, IOInterface $io): void { $composer->getInstallationManager()->removeInstaller($this->installer); } public function uninstall(Composer $composer, IOInterface $io): void { } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/PortoInstaller.php ================================================ */ protected $locations = array( 'container' => 'app/Containers/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/PrestashopInstaller.php ================================================ */ protected $locations = array( 'module' => 'modules/{$name}/', 'theme' => 'themes/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/ProcessWireInstaller.php ================================================ */ protected $locations = array( 'module' => 'site/modules/{$name}/', ); /** * Format package name to CamelCase */ public function inflectPackageVars(array $vars): array { $vars['name'] = strtolower($this->pregReplace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name'])); $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); return $vars; } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/PuppetInstaller.php ================================================ */ protected $locations = array( 'module' => 'modules/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/PxcmsInstaller.php ================================================ */ protected $locations = array( 'module' => 'app/Modules/{$name}/', 'theme' => 'themes/{$name}/', ); /** * Format package name. */ public function inflectPackageVars(array $vars): array { if ($vars['type'] === 'pxcms-module') { return $this->inflectModuleVars($vars); } if ($vars['type'] === 'pxcms-theme') { return $this->inflectThemeVars($vars); } return $vars; } /** * For package type pxcms-module, cut off a trailing '-plugin' if present. * * @param array $vars * @return array */ protected function inflectModuleVars(array $vars): array { $vars['name'] = str_replace('pxcms-', '', $vars['name']); // strip out pxcms- just incase (legacy) $vars['name'] = str_replace('module-', '', $vars['name']); // strip out module- $vars['name'] = $this->pregReplace('/-module$/', '', $vars['name']); // strip out -module $vars['name'] = str_replace('-', '_', $vars['name']); // make -'s be _'s $vars['name'] = ucwords($vars['name']); // make module name camelcased return $vars; } /** * For package type pxcms-module, cut off a trailing '-plugin' if present. * * @param array $vars * @return array */ protected function inflectThemeVars(array $vars): array { $vars['name'] = str_replace('pxcms-', '', $vars['name']); // strip out pxcms- just incase (legacy) $vars['name'] = str_replace('theme-', '', $vars['name']); // strip out theme- $vars['name'] = $this->pregReplace('/-theme$/', '', $vars['name']); // strip out -theme $vars['name'] = str_replace('-', '_', $vars['name']); // make -'s be _'s $vars['name'] = ucwords($vars['name']); // make module name camelcased return $vars; } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/RadPHPInstaller.php ================================================ */ protected $locations = array( 'bundle' => 'src/{$name}/' ); /** * Format package name to CamelCase */ public function inflectPackageVars(array $vars): array { $nameParts = explode('/', $vars['name']); foreach ($nameParts as &$value) { $value = strtolower($this->pregReplace('/(?<=\\w)([A-Z])/', '_\\1', $value)); $value = str_replace(array('-', '_'), ' ', $value); $value = str_replace(' ', '', ucwords($value)); } $vars['name'] = implode('/', $nameParts); return $vars; } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/ReIndexInstaller.php ================================================ */ protected $locations = array( 'theme' => 'themes/{$name}/', 'plugin' => 'plugins/{$name}/' ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/Redaxo5Installer.php ================================================ */ protected $locations = array( 'addon' => 'redaxo/src/addons/{$name}/', 'bestyle-plugin' => 'redaxo/src/addons/be_style/plugins/{$name}/' ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/RedaxoInstaller.php ================================================ */ protected $locations = array( 'addon' => 'redaxo/include/addons/{$name}/', 'bestyle-plugin' => 'redaxo/include/addons/be_style/plugins/{$name}/' ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/RoundcubeInstaller.php ================================================ */ protected $locations = array( 'plugin' => 'plugins/{$name}/', ); /** * Lowercase name and changes the name to a underscores */ public function inflectPackageVars(array $vars): array { $vars['name'] = strtolower(str_replace('-', '_', $vars['name'])); return $vars; } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/SMFInstaller.php ================================================ */ protected $locations = array( 'module' => 'Sources/{$name}/', 'theme' => 'Themes/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/ShopwareInstaller.php ================================================ */ protected $locations = array( 'backend-plugin' => 'engine/Shopware/Plugins/Local/Backend/{$name}/', 'core-plugin' => 'engine/Shopware/Plugins/Local/Core/{$name}/', 'frontend-plugin' => 'engine/Shopware/Plugins/Local/Frontend/{$name}/', 'theme' => 'templates/{$name}/', 'plugin' => 'custom/plugins/{$name}/', 'frontend-theme' => 'themes/Frontend/{$name}/', ); /** * Transforms the names */ public function inflectPackageVars(array $vars): array { if ($vars['type'] === 'shopware-theme') { return $this->correctThemeName($vars); } return $this->correctPluginName($vars); } /** * Changes the name to a camelcased combination of vendor and name * * @param array $vars * @return array */ private function correctPluginName(array $vars): array { $camelCasedName = preg_replace_callback('/(-[a-z])/', function ($matches) { return strtoupper($matches[0][1]); }, $vars['name']); if (null === $camelCasedName) { throw new \RuntimeException('Failed to run preg_replace_callback: '.preg_last_error()); } $vars['name'] = ucfirst($vars['vendor']) . ucfirst($camelCasedName); return $vars; } /** * Changes the name to a underscore separated name * * @param array $vars * @return array */ private function correctThemeName(array $vars): array { $vars['name'] = str_replace('-', '_', $vars['name']); return $vars; } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/SilverStripeInstaller.php ================================================ */ protected $locations = array( 'module' => '{$name}/', 'theme' => 'themes/{$name}/', ); /** * Return the install path based on package type. * * Relies on built-in BaseInstaller behaviour with one exception: silverstripe/framework * must be installed to 'sapphire' and not 'framework' if the version is <3.0.0 */ public function getInstallPath(PackageInterface $package, string $frameworkType = ''): string { if ( $package->getName() == 'silverstripe/framework' && preg_match('/^\d+\.\d+\.\d+/', $package->getVersion()) && version_compare($package->getVersion(), '2.999.999') < 0 ) { return $this->templatePath($this->locations['module'], array('name' => 'sapphire')); } return parent::getInstallPath($package, $frameworkType); } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/SiteDirectInstaller.php ================================================ */ protected $locations = array( 'module' => 'modules/{$vendor}/{$name}/', 'plugin' => 'plugins/{$vendor}/{$name}/' ); /** * @param array $vars * @return array */ public function inflectPackageVars(array $vars): array { return $this->parseVars($vars); } /** * @param array $vars * @return array */ protected function parseVars(array $vars): array { $vars['vendor'] = strtolower($vars['vendor']) == 'sitedirect' ? 'SiteDirect' : $vars['vendor']; $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); return $vars; } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/StarbugInstaller.php ================================================ */ protected $locations = array( 'module' => 'modules/{$name}/', 'theme' => 'themes/{$name}/', 'custom-module' => 'app/modules/{$name}/', 'custom-theme' => 'app/themes/{$name}/' ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/SyDESInstaller.php ================================================ */ protected $locations = array( 'module' => 'app/modules/{$name}/', 'theme' => 'themes/{$name}/', ); /** * Format module name. * * Strip `sydes-` prefix and a trailing '-theme' or '-module' from package name if present. */ public function inflectPackageVars(array $vars): array { if ($vars['type'] == 'sydes-module') { return $this->inflectModuleVars($vars); } if ($vars['type'] === 'sydes-theme') { return $this->inflectThemeVars($vars); } return $vars; } /** * @param array $vars * @return array */ public function inflectModuleVars(array $vars): array { $vars['name'] = $this->pregReplace('/(^sydes-|-module$)/i', '', $vars['name']); $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); return $vars; } /** * @param array $vars * @return array */ protected function inflectThemeVars(array $vars): array { $vars['name'] = $this->pregReplace('/(^sydes-|-theme$)/', '', $vars['name']); $vars['name'] = strtolower($vars['name']); return $vars; } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/SyliusInstaller.php ================================================ */ protected $locations = array( 'theme' => 'themes/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/TaoInstaller.php ================================================ */ protected $locations = array( 'extension' => '{$name}' ); public function inflectPackageVars(array $vars): array { $extra = $this->package->getExtra(); if (array_key_exists(self::EXTRA_TAO_EXTENSION_NAME, $extra)) { $vars['name'] = $extra[self::EXTRA_TAO_EXTENSION_NAME]; return $vars; } $vars['name'] = str_replace('extension-', '', $vars['name']); $vars['name'] = str_replace('-', ' ', $vars['name']); $vars['name'] = lcfirst(str_replace(' ', '', ucwords($vars['name']))); return $vars; } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/TastyIgniterInstaller.php ================================================ */ protected $locations = [ 'module' => 'app/{$name}/', 'extension' => 'extensions/{$vendor}/{$name}/', 'theme' => 'themes/{$name}/', ]; /** * Format package name. * * Cut off leading 'ti-ext-' or 'ti-theme-' if present. * Strip vendor name of characters that is not alphanumeric or an underscore * */ public function inflectPackageVars(array $vars): array { $extra = $this->package->getExtra(); if ($vars['type'] === 'tastyigniter-module') { return $this->inflectModuleVars($vars); } if ($vars['type'] === 'tastyigniter-extension') { return $this->inflectExtensionVars($vars, $extra); } if ($vars['type'] === 'tastyigniter-theme') { return $this->inflectThemeVars($vars, $extra); } return $vars; } /** * @param array $vars * @return array */ protected function inflectModuleVars(array $vars): array { $vars['name'] = $this->pregReplace('/^ti-module-/', '', $vars['name']); return $vars; } /** * @param array $vars * @param array $extra * @return array */ protected function inflectExtensionVars(array $vars, array $extra): array { if (!empty($extra['tastyigniter-extension']['code'])) { $parts = explode('.', $extra['tastyigniter-extension']['code']); $vars['vendor'] = (string)$parts[0]; $vars['name'] = (string)($parts[1] ?? ''); } $vars['vendor'] = $this->pregReplace('/[^a-z0-9_]/i', '', $vars['vendor']); $vars['name'] = $this->pregReplace('/^ti-ext-/', '', $vars['name']); return $vars; } /** * @param array $vars * @param array $extra * @return array */ protected function inflectThemeVars(array $vars, array $extra): array { if (!empty($extra['tastyigniter-theme']['code'])) { $vars['name'] = $extra['tastyigniter-theme']['code']; } $vars['name'] = $this->pregReplace('/^ti-theme-/', '', $vars['name']); return $vars; } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/TheliaInstaller.php ================================================ */ protected $locations = array( 'module' => 'local/modules/{$name}/', 'frontoffice-template' => 'templates/frontOffice/{$name}/', 'backoffice-template' => 'templates/backOffice/{$name}/', 'email-template' => 'templates/email/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/TuskInstaller.php ================================================ */ class TuskInstaller extends BaseInstaller { /** @var array */ protected $locations = array( 'task' => '.tusk/tasks/{$name}/', 'command' => '.tusk/commands/{$name}/', 'asset' => 'assets/tusk/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/UserFrostingInstaller.php ================================================ */ protected $locations = array( 'sprinkle' => 'app/sprinkles/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/VanillaInstaller.php ================================================ */ protected $locations = array( 'plugin' => 'plugins/{$name}/', 'theme' => 'themes/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/VgmcpInstaller.php ================================================ */ protected $locations = array( 'bundle' => 'src/{$vendor}/{$name}/', 'theme' => 'themes/{$name}/' ); /** * Format package name. * * For package type vgmcp-bundle, cut off a trailing '-bundle' if present. * * For package type vgmcp-theme, cut off a trailing '-theme' if present. * */ public function inflectPackageVars(array $vars): array { if ($vars['type'] === 'vgmcp-bundle') { return $this->inflectPluginVars($vars); } if ($vars['type'] === 'vgmcp-theme') { return $this->inflectThemeVars($vars); } return $vars; } /** * @param array $vars * @return array */ protected function inflectPluginVars(array $vars): array { $vars['name'] = $this->pregReplace('/-bundle$/', '', $vars['name']); $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); return $vars; } /** * @param array $vars * @return array */ protected function inflectThemeVars(array $vars): array { $vars['name'] = $this->pregReplace('/-theme$/', '', $vars['name']); $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); return $vars; } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/WHMCSInstaller.php ================================================ */ protected $locations = array( 'addons' => 'modules/addons/{$vendor}_{$name}/', 'fraud' => 'modules/fraud/{$vendor}_{$name}/', 'gateways' => 'modules/gateways/{$vendor}_{$name}/', 'notifications' => 'modules/notifications/{$vendor}_{$name}/', 'registrars' => 'modules/registrars/{$vendor}_{$name}/', 'reports' => 'modules/reports/{$vendor}_{$name}/', 'security' => 'modules/security/{$vendor}_{$name}/', 'servers' => 'modules/servers/{$vendor}_{$name}/', 'social' => 'modules/social/{$vendor}_{$name}/', 'support' => 'modules/support/{$vendor}_{$name}/', 'templates' => 'templates/{$vendor}_{$name}/', 'includes' => 'includes/{$vendor}_{$name}/' ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/WinterInstaller.php ================================================ */ protected $locations = array( 'module' => 'modules/{$name}/', 'plugin' => 'plugins/{$vendor}/{$name}/', 'theme' => 'themes/{$name}/' ); /** * Format package name. * * For package type winter-plugin, cut off a trailing '-plugin' if present. * * For package type winter-theme, cut off a trailing '-theme' if present. */ public function inflectPackageVars(array $vars): array { if ($vars['type'] === 'winter-module') { return $this->inflectModuleVars($vars); } if ($vars['type'] === 'winter-plugin') { return $this->inflectPluginVars($vars); } if ($vars['type'] === 'winter-theme') { return $this->inflectThemeVars($vars); } return $vars; } /** * @param array $vars * @return array */ protected function inflectModuleVars(array $vars): array { $vars['name'] = $this->pregReplace('/^wn-|-module$/', '', $vars['name']); return $vars; } /** * @param array $vars * @return array */ protected function inflectPluginVars(array $vars): array { $vars['name'] = $this->pregReplace('/^wn-|-plugin$/', '', $vars['name']); $vars['vendor'] = $this->pregReplace('/[^a-z0-9_]/i', '', $vars['vendor']); return $vars; } /** * @param array $vars * @return array */ protected function inflectThemeVars(array $vars): array { $vars['name'] = $this->pregReplace('/^wn-|-theme$/', '', $vars['name']); return $vars; } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/WolfCMSInstaller.php ================================================ */ protected $locations = array( 'plugin' => 'wolf/plugins/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/WordPressInstaller.php ================================================ */ protected $locations = array( 'plugin' => 'wp-content/plugins/{$name}/', 'theme' => 'wp-content/themes/{$name}/', 'muplugin' => 'wp-content/mu-plugins/{$name}/', 'dropin' => 'wp-content/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/YawikInstaller.php ================================================ */ protected $locations = array( 'module' => 'module/{$name}/', ); /** * Format package name to CamelCase */ public function inflectPackageVars(array $vars): array { $vars['name'] = strtolower($this->pregReplace('/(?<=\\w)([A-Z])/', '_\\1', $vars['name'])); $vars['name'] = str_replace(array('-', '_'), ' ', $vars['name']); $vars['name'] = str_replace(' ', '', ucwords($vars['name'])); return $vars; } } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/ZendInstaller.php ================================================ */ protected $locations = array( 'library' => 'library/{$name}/', 'extra' => 'extras/library/{$name}/', 'module' => 'module/{$name}/', ); } ================================================ FILE: vendor/composer/installers/src/Composer/Installers/ZikulaInstaller.php ================================================ */ protected $locations = array( 'module' => 'modules/{$vendor}-{$name}/', 'theme' => 'themes/{$vendor}-{$name}/' ); } ================================================ FILE: vendor/composer/installers/src/bootstrap.php ================================================ = 80000)) { $issues[] = 'Your Composer dependencies require a PHP version ">= 8.0.0". You are running ' . PHP_VERSION . '.'; } if ($issues) { if (!headers_sent()) { header('HTTP/1.1 500 Internal Server Error'); } if (!ini_get('display_errors')) { if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL); } elseif (!headers_sent()) { echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; } } throw new \RuntimeException( 'Composer detected issues in your platform: ' . implode(' ', $issues) ); } ================================================ FILE: vendor/firebase/php-jwt/CHANGELOG.md ================================================ # Changelog ## [6.11.1](https://github.com/firebase/php-jwt/compare/v6.11.0...v6.11.1) (2025-04-09) ### Bug Fixes * update error text for consistency ([#528](https://github.com/firebase/php-jwt/issues/528)) ([c11113a](https://github.com/firebase/php-jwt/commit/c11113afa13265e016a669e75494b9203b8a7775)) ## [6.11.0](https://github.com/firebase/php-jwt/compare/v6.10.2...v6.11.0) (2025-01-23) ### Features * support octet typed JWK ([#587](https://github.com/firebase/php-jwt/issues/587)) ([7cb8a26](https://github.com/firebase/php-jwt/commit/7cb8a265fa81edf2fa6ef8098f5bc5ae573c33ad)) ### Bug Fixes * refactor constructor Key to use PHP 8.0 syntax ([#577](https://github.com/firebase/php-jwt/issues/577)) ([29fa2ce](https://github.com/firebase/php-jwt/commit/29fa2ce9e0582cd397711eec1e80c05ce20fabca)) ## [6.10.2](https://github.com/firebase/php-jwt/compare/v6.10.1...v6.10.2) (2024-11-24) ### Bug Fixes * Mitigate PHP8.4 deprecation warnings ([#570](https://github.com/firebase/php-jwt/issues/570)) ([76808fa](https://github.com/firebase/php-jwt/commit/76808fa227f3811aa5cdb3bf81233714b799a5b5)) * support php 8.4 ([#583](https://github.com/firebase/php-jwt/issues/583)) ([e3d68b0](https://github.com/firebase/php-jwt/commit/e3d68b044421339443c74199edd020e03fb1887e)) ## [6.10.1](https://github.com/firebase/php-jwt/compare/v6.10.0...v6.10.1) (2024-05-18) ### Bug Fixes * ensure ratelimit expiry is set every time ([#556](https://github.com/firebase/php-jwt/issues/556)) ([09cb208](https://github.com/firebase/php-jwt/commit/09cb2081c2c3bc0f61e2f2a5fbea5741f7498648)) * ratelimit cache expiration ([#550](https://github.com/firebase/php-jwt/issues/550)) ([dda7250](https://github.com/firebase/php-jwt/commit/dda725033585ece30ff8cae8937320d7e9f18bae)) ## [6.10.0](https://github.com/firebase/php-jwt/compare/v6.9.0...v6.10.0) (2023-11-28) ### Features * allow typ header override ([#546](https://github.com/firebase/php-jwt/issues/546)) ([79cb30b](https://github.com/firebase/php-jwt/commit/79cb30b729a22931b2fbd6b53f20629a83031ba9)) ## [6.9.0](https://github.com/firebase/php-jwt/compare/v6.8.1...v6.9.0) (2023-10-04) ### Features * add payload to jwt exception ([#521](https://github.com/firebase/php-jwt/issues/521)) ([175edf9](https://github.com/firebase/php-jwt/commit/175edf958bb61922ec135b2333acf5622f2238a2)) ## [6.8.1](https://github.com/firebase/php-jwt/compare/v6.8.0...v6.8.1) (2023-07-14) ### Bug Fixes * accept float claims but round down to ignore them ([#492](https://github.com/firebase/php-jwt/issues/492)) ([3936842](https://github.com/firebase/php-jwt/commit/39368423beeaacb3002afa7dcb75baebf204fe7e)) * different BeforeValidException messages for nbf and iat ([#526](https://github.com/firebase/php-jwt/issues/526)) ([0a53cf2](https://github.com/firebase/php-jwt/commit/0a53cf2986e45c2bcbf1a269f313ebf56a154ee4)) ## [6.8.0](https://github.com/firebase/php-jwt/compare/v6.7.0...v6.8.0) (2023-06-14) ### Features * add support for P-384 curve ([#515](https://github.com/firebase/php-jwt/issues/515)) ([5de4323](https://github.com/firebase/php-jwt/commit/5de4323f4baf4d70bca8663bd87682a69c656c3d)) ### Bug Fixes * handle invalid http responses ([#508](https://github.com/firebase/php-jwt/issues/508)) ([91c39c7](https://github.com/firebase/php-jwt/commit/91c39c72b22fc3e1191e574089552c1f2041c718)) ## [6.7.0](https://github.com/firebase/php-jwt/compare/v6.6.0...v6.7.0) (2023-06-14) ### Features * add ed25519 support to JWK (public keys) ([#452](https://github.com/firebase/php-jwt/issues/452)) ([e53979a](https://github.com/firebase/php-jwt/commit/e53979abae927de916a75b9d239cfda8ce32be2a)) ## [6.6.0](https://github.com/firebase/php-jwt/compare/v6.5.0...v6.6.0) (2023-06-13) ### Features * allow get headers when decoding token ([#442](https://github.com/firebase/php-jwt/issues/442)) ([fb85f47](https://github.com/firebase/php-jwt/commit/fb85f47cfaeffdd94faf8defdf07164abcdad6c3)) ### Bug Fixes * only check iat if nbf is not used ([#493](https://github.com/firebase/php-jwt/issues/493)) ([398ccd2](https://github.com/firebase/php-jwt/commit/398ccd25ea12fa84b9e4f1085d5ff448c21ec797)) ## [6.5.0](https://github.com/firebase/php-jwt/compare/v6.4.0...v6.5.0) (2023-05-12) ### Bug Fixes * allow KID of '0' ([#505](https://github.com/firebase/php-jwt/issues/505)) ([9dc46a9](https://github.com/firebase/php-jwt/commit/9dc46a9c3e5801294249cfd2554c5363c9f9326a)) ### Miscellaneous Chores * drop support for PHP 7.3 ([#495](https://github.com/firebase/php-jwt/issues/495)) ## [6.4.0](https://github.com/firebase/php-jwt/compare/v6.3.2...v6.4.0) (2023-02-08) ### Features * add support for W3C ES256K ([#462](https://github.com/firebase/php-jwt/issues/462)) ([213924f](https://github.com/firebase/php-jwt/commit/213924f51936291fbbca99158b11bd4ae56c2c95)) * improve caching by only decoding jwks when necessary ([#486](https://github.com/firebase/php-jwt/issues/486)) ([78d3ed1](https://github.com/firebase/php-jwt/commit/78d3ed1073553f7d0bbffa6c2010009a0d483d5c)) ## [6.3.2](https://github.com/firebase/php-jwt/compare/v6.3.1...v6.3.2) (2022-11-01) ### Bug Fixes * check kid before using as array index ([bad1b04](https://github.com/firebase/php-jwt/commit/bad1b040d0c736bbf86814c6b5ae614f517cf7bd)) ## [6.3.1](https://github.com/firebase/php-jwt/compare/v6.3.0...v6.3.1) (2022-11-01) ### Bug Fixes * casing of GET for PSR compat ([#451](https://github.com/firebase/php-jwt/issues/451)) ([60b52b7](https://github.com/firebase/php-jwt/commit/60b52b71978790eafcf3b95cfbd83db0439e8d22)) * string interpolation format for php 8.2 ([#446](https://github.com/firebase/php-jwt/issues/446)) ([2e07d8a](https://github.com/firebase/php-jwt/commit/2e07d8a1524d12b69b110ad649f17461d068b8f2)) ## 6.3.0 / 2022-07-15 - Added ES256 support to JWK parsing ([#399](https://github.com/firebase/php-jwt/pull/399)) - Fixed potential caching error in `CachedKeySet` by caching jwks as strings ([#435](https://github.com/firebase/php-jwt/pull/435)) ## 6.2.0 / 2022-05-14 - Added `CachedKeySet` ([#397](https://github.com/firebase/php-jwt/pull/397)) - Added `$defaultAlg` parameter to `JWT::parseKey` and `JWT::parseKeySet` ([#426](https://github.com/firebase/php-jwt/pull/426)). ## 6.1.0 / 2022-03-23 - Drop support for PHP 5.3, 5.4, 5.5, 5.6, and 7.0 - Add parameter typing and return types where possible ## 6.0.0 / 2022-01-24 - **Backwards-Compatibility Breaking Changes**: See the [Release Notes](https://github.com/firebase/php-jwt/releases/tag/v6.0.0) for more information. - New Key object to prevent key/algorithm type confusion (#365) - Add JWK support (#273) - Add ES256 support (#256) - Add ES384 support (#324) - Add Ed25519 support (#343) ## 5.0.0 / 2017-06-26 - Support RS384 and RS512. See [#117](https://github.com/firebase/php-jwt/pull/117). Thanks [@joostfaassen](https://github.com/joostfaassen)! - Add an example for RS256 openssl. See [#125](https://github.com/firebase/php-jwt/pull/125). Thanks [@akeeman](https://github.com/akeeman)! - Detect invalid Base64 encoding in signature. See [#162](https://github.com/firebase/php-jwt/pull/162). Thanks [@psignoret](https://github.com/psignoret)! - Update `JWT::verify` to handle OpenSSL errors. See [#159](https://github.com/firebase/php-jwt/pull/159). Thanks [@bshaffer](https://github.com/bshaffer)! - Add `array` type hinting to `decode` method See [#101](https://github.com/firebase/php-jwt/pull/101). Thanks [@hywak](https://github.com/hywak)! - Add all JSON error types. See [#110](https://github.com/firebase/php-jwt/pull/110). Thanks [@gbalduzzi](https://github.com/gbalduzzi)! - Bugfix 'kid' not in given key list. See [#129](https://github.com/firebase/php-jwt/pull/129). Thanks [@stampycode](https://github.com/stampycode)! - Miscellaneous cleanup, documentation and test fixes. See [#107](https://github.com/firebase/php-jwt/pull/107), [#115](https://github.com/firebase/php-jwt/pull/115), [#160](https://github.com/firebase/php-jwt/pull/160), [#161](https://github.com/firebase/php-jwt/pull/161), and [#165](https://github.com/firebase/php-jwt/pull/165). Thanks [@akeeman](https://github.com/akeeman), [@chinedufn](https://github.com/chinedufn), and [@bshaffer](https://github.com/bshaffer)! ## 4.0.0 / 2016-07-17 - Add support for late static binding. See [#88](https://github.com/firebase/php-jwt/pull/88) for details. Thanks to [@chappy84](https://github.com/chappy84)! - Use static `$timestamp` instead of `time()` to improve unit testing. See [#93](https://github.com/firebase/php-jwt/pull/93) for details. Thanks to [@josephmcdermott](https://github.com/josephmcdermott)! - Fixes to exceptions classes. See [#81](https://github.com/firebase/php-jwt/pull/81) for details. Thanks to [@Maks3w](https://github.com/Maks3w)! - Fixes to PHPDoc. See [#76](https://github.com/firebase/php-jwt/pull/76) for details. Thanks to [@akeeman](https://github.com/akeeman)! ## 3.0.0 / 2015-07-22 - Minimum PHP version updated from `5.2.0` to `5.3.0`. - Add `\Firebase\JWT` namespace. See [#59](https://github.com/firebase/php-jwt/pull/59) for details. Thanks to [@Dashron](https://github.com/Dashron)! - Require a non-empty key to decode and verify a JWT. See [#60](https://github.com/firebase/php-jwt/pull/60) for details. Thanks to [@sjones608](https://github.com/sjones608)! - Cleaner documentation blocks in the code. See [#62](https://github.com/firebase/php-jwt/pull/62) for details. Thanks to [@johanderuijter](https://github.com/johanderuijter)! ## 2.2.0 / 2015-06-22 - Add support for adding custom, optional JWT headers to `JWT::encode()`. See [#53](https://github.com/firebase/php-jwt/pull/53/files) for details. Thanks to [@mcocaro](https://github.com/mcocaro)! ## 2.1.0 / 2015-05-20 - Add support for adding a leeway to `JWT:decode()` that accounts for clock skew between signing and verifying entities. Thanks to [@lcabral](https://github.com/lcabral)! - Add support for passing an object implementing the `ArrayAccess` interface for `$keys` argument in `JWT::decode()`. Thanks to [@aztech-dev](https://github.com/aztech-dev)! ## 2.0.0 / 2015-04-01 - **Note**: It is strongly recommended that you update to > v2.0.0 to address known security vulnerabilities in prior versions when both symmetric and asymmetric keys are used together. - Update signature for `JWT::decode(...)` to require an array of supported algorithms to use when verifying token signatures. ================================================ FILE: vendor/firebase/php-jwt/LICENSE ================================================ Copyright (c) 2011, Neuman Vong 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 other 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. ================================================ FILE: vendor/firebase/php-jwt/README.md ================================================ ![Build Status](https://github.com/firebase/php-jwt/actions/workflows/tests.yml/badge.svg) [![Latest Stable Version](https://poser.pugx.org/firebase/php-jwt/v/stable)](https://packagist.org/packages/firebase/php-jwt) [![Total Downloads](https://poser.pugx.org/firebase/php-jwt/downloads)](https://packagist.org/packages/firebase/php-jwt) [![License](https://poser.pugx.org/firebase/php-jwt/license)](https://packagist.org/packages/firebase/php-jwt) PHP-JWT ======= A simple library to encode and decode JSON Web Tokens (JWT) in PHP, conforming to [RFC 7519](https://tools.ietf.org/html/rfc7519). Installation ------------ Use composer to manage your dependencies and download PHP-JWT: ```bash composer require firebase/php-jwt ``` Optionally, install the `paragonie/sodium_compat` package from composer if your php env does not have libsodium installed: ```bash composer require paragonie/sodium_compat ``` Example ------- ```php use Firebase\JWT\JWT; use Firebase\JWT\Key; $key = 'example_key'; $payload = [ 'iss' => 'http://example.org', 'aud' => 'http://example.com', 'iat' => 1356999524, 'nbf' => 1357000000 ]; /** * IMPORTANT: * You must specify supported algorithms for your application. See * https://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-40 * for a list of spec-compliant algorithms. */ $jwt = JWT::encode($payload, $key, 'HS256'); $decoded = JWT::decode($jwt, new Key($key, 'HS256')); print_r($decoded); // Pass a stdClass in as the third parameter to get the decoded header values $headers = new stdClass(); $decoded = JWT::decode($jwt, new Key($key, 'HS256'), $headers); print_r($headers); /* NOTE: This will now be an object instead of an associative array. To get an associative array, you will need to cast it as such: */ $decoded_array = (array) $decoded; /** * You can add a leeway to account for when there is a clock skew times between * the signing and verifying servers. It is recommended that this leeway should * not be bigger than a few minutes. * * Source: http://self-issued.info/docs/draft-ietf-oauth-json-web-token.html#nbfDef */ JWT::$leeway = 60; // $leeway in seconds $decoded = JWT::decode($jwt, new Key($key, 'HS256')); ``` Example encode/decode headers ------- Decoding the JWT headers without verifying the JWT first is NOT recommended, and is not supported by this library. This is because without verifying the JWT, the header values could have been tampered with. Any value pulled from an unverified header should be treated as if it could be any string sent in from an attacker. If this is something you still want to do in your application for whatever reason, it's possible to decode the header values manually simply by calling `json_decode` and `base64_decode` on the JWT header part: ```php use Firebase\JWT\JWT; $key = 'example_key'; $payload = [ 'iss' => 'http://example.org', 'aud' => 'http://example.com', 'iat' => 1356999524, 'nbf' => 1357000000 ]; $headers = [ 'x-forwarded-for' => 'www.google.com' ]; // Encode headers in the JWT string $jwt = JWT::encode($payload, $key, 'HS256', null, $headers); // Decode headers from the JWT string WITHOUT validation // **IMPORTANT**: This operation is vulnerable to attacks, as the JWT has not yet been verified. // These headers could be any value sent by an attacker. list($headersB64, $payloadB64, $sig) = explode('.', $jwt); $decoded = json_decode(base64_decode($headersB64), true); print_r($decoded); ``` Example with RS256 (openssl) ---------------------------- ```php use Firebase\JWT\JWT; use Firebase\JWT\Key; $privateKey = << 'example.org', 'aud' => 'example.com', 'iat' => 1356999524, 'nbf' => 1357000000 ]; $jwt = JWT::encode($payload, $privateKey, 'RS256'); echo "Encode:\n" . print_r($jwt, true) . "\n"; $decoded = JWT::decode($jwt, new Key($publicKey, 'RS256')); /* NOTE: This will now be an object instead of an associative array. To get an associative array, you will need to cast it as such: */ $decoded_array = (array) $decoded; echo "Decode:\n" . print_r($decoded_array, true) . "\n"; ``` Example with a passphrase ------------------------- ```php use Firebase\JWT\JWT; use Firebase\JWT\Key; // Your passphrase $passphrase = '[YOUR_PASSPHRASE]'; // Your private key file with passphrase // Can be generated with "ssh-keygen -t rsa -m pem" $privateKeyFile = '/path/to/key-with-passphrase.pem'; // Create a private key of type "resource" $privateKey = openssl_pkey_get_private( file_get_contents($privateKeyFile), $passphrase ); $payload = [ 'iss' => 'example.org', 'aud' => 'example.com', 'iat' => 1356999524, 'nbf' => 1357000000 ]; $jwt = JWT::encode($payload, $privateKey, 'RS256'); echo "Encode:\n" . print_r($jwt, true) . "\n"; // Get public key from the private key, or pull from from a file. $publicKey = openssl_pkey_get_details($privateKey)['key']; $decoded = JWT::decode($jwt, new Key($publicKey, 'RS256')); echo "Decode:\n" . print_r((array) $decoded, true) . "\n"; ``` Example with EdDSA (libsodium and Ed25519 signature) ---------------------------- ```php use Firebase\JWT\JWT; use Firebase\JWT\Key; // Public and private keys are expected to be Base64 encoded. The last // non-empty line is used so that keys can be generated with // sodium_crypto_sign_keypair(). The secret keys generated by other tools may // need to be adjusted to match the input expected by libsodium. $keyPair = sodium_crypto_sign_keypair(); $privateKey = base64_encode(sodium_crypto_sign_secretkey($keyPair)); $publicKey = base64_encode(sodium_crypto_sign_publickey($keyPair)); $payload = [ 'iss' => 'example.org', 'aud' => 'example.com', 'iat' => 1356999524, 'nbf' => 1357000000 ]; $jwt = JWT::encode($payload, $privateKey, 'EdDSA'); echo "Encode:\n" . print_r($jwt, true) . "\n"; $decoded = JWT::decode($jwt, new Key($publicKey, 'EdDSA')); echo "Decode:\n" . print_r((array) $decoded, true) . "\n"; ```` Example with multiple keys -------------------------- ```php use Firebase\JWT\JWT; use Firebase\JWT\Key; // Example RSA keys from previous example // $privateKey1 = '...'; // $publicKey1 = '...'; // Example EdDSA keys from previous example // $privateKey2 = '...'; // $publicKey2 = '...'; $payload = [ 'iss' => 'example.org', 'aud' => 'example.com', 'iat' => 1356999524, 'nbf' => 1357000000 ]; $jwt1 = JWT::encode($payload, $privateKey1, 'RS256', 'kid1'); $jwt2 = JWT::encode($payload, $privateKey2, 'EdDSA', 'kid2'); echo "Encode 1:\n" . print_r($jwt1, true) . "\n"; echo "Encode 2:\n" . print_r($jwt2, true) . "\n"; $keys = [ 'kid1' => new Key($publicKey1, 'RS256'), 'kid2' => new Key($publicKey2, 'EdDSA'), ]; $decoded1 = JWT::decode($jwt1, $keys); $decoded2 = JWT::decode($jwt2, $keys); echo "Decode 1:\n" . print_r((array) $decoded1, true) . "\n"; echo "Decode 2:\n" . print_r((array) $decoded2, true) . "\n"; ``` Using JWKs ---------- ```php use Firebase\JWT\JWK; use Firebase\JWT\JWT; // Set of keys. The "keys" key is required. For example, the JSON response to // this endpoint: https://www.gstatic.com/iap/verify/public_key-jwk $jwks = ['keys' => []]; // JWK::parseKeySet($jwks) returns an associative array of **kid** to Firebase\JWT\Key // objects. Pass this as the second parameter to JWT::decode. JWT::decode($jwt, JWK::parseKeySet($jwks)); ``` Using Cached Key Sets --------------------- The `CachedKeySet` class can be used to fetch and cache JWKS (JSON Web Key Sets) from a public URI. This has the following advantages: 1. The results are cached for performance. 2. If an unrecognized key is requested, the cache is refreshed, to accomodate for key rotation. 3. If rate limiting is enabled, the JWKS URI will not make more than 10 requests a second. ```php use Firebase\JWT\CachedKeySet; use Firebase\JWT\JWT; // The URI for the JWKS you wish to cache the results from $jwksUri = 'https://www.gstatic.com/iap/verify/public_key-jwk'; // Create an HTTP client (can be any PSR-7 compatible HTTP client) $httpClient = new GuzzleHttp\Client(); // Create an HTTP request factory (can be any PSR-17 compatible HTTP request factory) $httpFactory = new GuzzleHttp\Psr\HttpFactory(); // Create a cache item pool (can be any PSR-6 compatible cache item pool) $cacheItemPool = Phpfastcache\CacheManager::getInstance('files'); $keySet = new CachedKeySet( $jwksUri, $httpClient, $httpFactory, $cacheItemPool, null, // $expiresAfter int seconds to set the JWKS to expire true // $rateLimit true to enable rate limit of 10 RPS on lookup of invalid keys ); $jwt = 'eyJhbGci...'; // Some JWT signed by a key from the $jwkUri above $decoded = JWT::decode($jwt, $keySet); ``` Miscellaneous ------------- #### Exception Handling When a call to `JWT::decode` is invalid, it will throw one of the following exceptions: ```php use Firebase\JWT\JWT; use Firebase\JWT\SignatureInvalidException; use Firebase\JWT\BeforeValidException; use Firebase\JWT\ExpiredException; use DomainException; use InvalidArgumentException; use UnexpectedValueException; try { $decoded = JWT::decode($jwt, $keys); } catch (InvalidArgumentException $e) { // provided key/key-array is empty or malformed. } catch (DomainException $e) { // provided algorithm is unsupported OR // provided key is invalid OR // unknown error thrown in openSSL or libsodium OR // libsodium is required but not available. } catch (SignatureInvalidException $e) { // provided JWT signature verification failed. } catch (BeforeValidException $e) { // provided JWT is trying to be used before "nbf" claim OR // provided JWT is trying to be used before "iat" claim. } catch (ExpiredException $e) { // provided JWT is trying to be used after "exp" claim. } catch (UnexpectedValueException $e) { // provided JWT is malformed OR // provided JWT is missing an algorithm / using an unsupported algorithm OR // provided JWT algorithm does not match provided key OR // provided key ID in key/key-array is empty or invalid. } ``` All exceptions in the `Firebase\JWT` namespace extend `UnexpectedValueException`, and can be simplified like this: ```php use Firebase\JWT\JWT; use UnexpectedValueException; try { $decoded = JWT::decode($jwt, $keys); } catch (LogicException $e) { // errors having to do with environmental setup or malformed JWT Keys } catch (UnexpectedValueException $e) { // errors having to do with JWT signature and claims } ``` #### Casting to array The return value of `JWT::decode` is the generic PHP object `stdClass`. If you'd like to handle with arrays instead, you can do the following: ```php // return type is stdClass $decoded = JWT::decode($jwt, $keys); // cast to array $decoded = json_decode(json_encode($decoded), true); ``` Tests ----- Run the tests using phpunit: ```bash $ pear install PHPUnit $ phpunit --configuration phpunit.xml.dist PHPUnit 3.7.10 by Sebastian Bergmann. ..... Time: 0 seconds, Memory: 2.50Mb OK (5 tests, 5 assertions) ``` New Lines in private keys ----- If your private key contains `\n` characters, be sure to wrap it in double quotes `""` and not single quotes `''` in order to properly interpret the escaped characters. License ------- [3-Clause BSD](http://opensource.org/licenses/BSD-3-Clause). ================================================ FILE: vendor/firebase/php-jwt/composer.json ================================================ { "name": "firebase/php-jwt", "description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.", "homepage": "https://github.com/firebase/php-jwt", "keywords": [ "php", "jwt" ], "authors": [ { "name": "Neuman Vong", "email": "neuman+pear@twilio.com", "role": "Developer" }, { "name": "Anant Narayanan", "email": "anant@php.net", "role": "Developer" } ], "license": "BSD-3-Clause", "require": { "php": "^8.0" }, "suggest": { "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present", "ext-sodium": "Support EdDSA (Ed25519) signatures" }, "autoload": { "psr-4": { "Firebase\\JWT\\": "src" } }, "require-dev": { "guzzlehttp/guzzle": "^7.4", "phpspec/prophecy-phpunit": "^2.0", "phpunit/phpunit": "^9.5", "psr/cache": "^2.0||^3.0", "psr/http-client": "^1.0", "psr/http-factory": "^1.0" } } ================================================ FILE: vendor/firebase/php-jwt/src/BeforeValidException.php ================================================ payload = $payload; } public function getPayload(): object { return $this->payload; } } ================================================ FILE: vendor/firebase/php-jwt/src/CachedKeySet.php ================================================ */ class CachedKeySet implements ArrayAccess { /** * @var string */ private $jwksUri; /** * @var ClientInterface */ private $httpClient; /** * @var RequestFactoryInterface */ private $httpFactory; /** * @var CacheItemPoolInterface */ private $cache; /** * @var ?int */ private $expiresAfter; /** * @var ?CacheItemInterface */ private $cacheItem; /** * @var array> */ private $keySet; /** * @var string */ private $cacheKey; /** * @var string */ private $cacheKeyPrefix = 'jwks'; /** * @var int */ private $maxKeyLength = 64; /** * @var bool */ private $rateLimit; /** * @var string */ private $rateLimitCacheKey; /** * @var int */ private $maxCallsPerMinute = 10; /** * @var string|null */ private $defaultAlg; public function __construct( string $jwksUri, ClientInterface $httpClient, RequestFactoryInterface $httpFactory, CacheItemPoolInterface $cache, ?int $expiresAfter = null, bool $rateLimit = false, ?string $defaultAlg = null ) { $this->jwksUri = $jwksUri; $this->httpClient = $httpClient; $this->httpFactory = $httpFactory; $this->cache = $cache; $this->expiresAfter = $expiresAfter; $this->rateLimit = $rateLimit; $this->defaultAlg = $defaultAlg; $this->setCacheKeys(); } /** * @param string $keyId * @return Key */ public function offsetGet($keyId): Key { if (!$this->keyIdExists($keyId)) { throw new OutOfBoundsException('Key ID not found'); } return JWK::parseKey($this->keySet[$keyId], $this->defaultAlg); } /** * @param string $keyId * @return bool */ public function offsetExists($keyId): bool { return $this->keyIdExists($keyId); } /** * @param string $offset * @param Key $value */ public function offsetSet($offset, $value): void { throw new LogicException('Method not implemented'); } /** * @param string $offset */ public function offsetUnset($offset): void { throw new LogicException('Method not implemented'); } /** * @return array */ private function formatJwksForCache(string $jwks): array { $jwks = json_decode($jwks, true); if (!isset($jwks['keys'])) { throw new UnexpectedValueException('"keys" member must exist in the JWK Set'); } if (empty($jwks['keys'])) { throw new InvalidArgumentException('JWK Set did not contain any keys'); } $keys = []; foreach ($jwks['keys'] as $k => $v) { $kid = isset($v['kid']) ? $v['kid'] : $k; $keys[(string) $kid] = $v; } return $keys; } private function keyIdExists(string $keyId): bool { if (null === $this->keySet) { $item = $this->getCacheItem(); // Try to load keys from cache if ($item->isHit()) { // item found! retrieve it $this->keySet = $item->get(); // If the cached item is a string, the JWKS response was cached (previous behavior). // Parse this into expected format array instead. if (\is_string($this->keySet)) { $this->keySet = $this->formatJwksForCache($this->keySet); } } } if (!isset($this->keySet[$keyId])) { if ($this->rateLimitExceeded()) { return false; } $request = $this->httpFactory->createRequest('GET', $this->jwksUri); $jwksResponse = $this->httpClient->sendRequest($request); if ($jwksResponse->getStatusCode() !== 200) { throw new UnexpectedValueException( \sprintf('HTTP Error: %d %s for URI "%s"', $jwksResponse->getStatusCode(), $jwksResponse->getReasonPhrase(), $this->jwksUri, ), $jwksResponse->getStatusCode() ); } $this->keySet = $this->formatJwksForCache((string) $jwksResponse->getBody()); if (!isset($this->keySet[$keyId])) { return false; } $item = $this->getCacheItem(); $item->set($this->keySet); if ($this->expiresAfter) { $item->expiresAfter($this->expiresAfter); } $this->cache->save($item); } return true; } private function rateLimitExceeded(): bool { if (!$this->rateLimit) { return false; } $cacheItem = $this->cache->getItem($this->rateLimitCacheKey); $cacheItemData = []; if ($cacheItem->isHit() && \is_array($data = $cacheItem->get())) { $cacheItemData = $data; } $callsPerMinute = $cacheItemData['callsPerMinute'] ?? 0; $expiry = $cacheItemData['expiry'] ?? new \DateTime('+60 seconds', new \DateTimeZone('UTC')); if (++$callsPerMinute > $this->maxCallsPerMinute) { return true; } $cacheItem->set(['expiry' => $expiry, 'callsPerMinute' => $callsPerMinute]); $cacheItem->expiresAt($expiry); $this->cache->save($cacheItem); return false; } private function getCacheItem(): CacheItemInterface { if (\is_null($this->cacheItem)) { $this->cacheItem = $this->cache->getItem($this->cacheKey); } return $this->cacheItem; } private function setCacheKeys(): void { if (empty($this->jwksUri)) { throw new RuntimeException('JWKS URI is empty'); } // ensure we do not have illegal characters $key = preg_replace('|[^a-zA-Z0-9_\.!]|', '', $this->jwksUri); // add prefix $key = $this->cacheKeyPrefix . $key; // Hash keys if they exceed $maxKeyLength of 64 if (\strlen($key) > $this->maxKeyLength) { $key = substr(hash('sha256', $key), 0, $this->maxKeyLength); } $this->cacheKey = $key; if ($this->rateLimit) { // add prefix $rateLimitKey = $this->cacheKeyPrefix . 'ratelimit' . $key; // Hash keys if they exceed $maxKeyLength of 64 if (\strlen($rateLimitKey) > $this->maxKeyLength) { $rateLimitKey = substr(hash('sha256', $rateLimitKey), 0, $this->maxKeyLength); } $this->rateLimitCacheKey = $rateLimitKey; } } } ================================================ FILE: vendor/firebase/php-jwt/src/ExpiredException.php ================================================ payload = $payload; } public function getPayload(): object { return $this->payload; } } ================================================ FILE: vendor/firebase/php-jwt/src/JWK.php ================================================ * @license http://opensource.org/licenses/BSD-3-Clause 3-clause BSD * @link https://github.com/firebase/php-jwt */ class JWK { private const OID = '1.2.840.10045.2.1'; private const ASN1_OBJECT_IDENTIFIER = 0x06; private const ASN1_SEQUENCE = 0x10; // also defined in JWT private const ASN1_BIT_STRING = 0x03; private const EC_CURVES = [ 'P-256' => '1.2.840.10045.3.1.7', // Len: 64 'secp256k1' => '1.3.132.0.10', // Len: 64 'P-384' => '1.3.132.0.34', // Len: 96 // 'P-521' => '1.3.132.0.35', // Len: 132 (not supported) ]; // For keys with "kty" equal to "OKP" (Octet Key Pair), the "crv" parameter must contain the key subtype. // This library supports the following subtypes: private const OKP_SUBTYPES = [ 'Ed25519' => true, // RFC 8037 ]; /** * Parse a set of JWK keys * * @param array $jwks The JSON Web Key Set as an associative array * @param string $defaultAlg The algorithm for the Key object if "alg" is not set in the * JSON Web Key Set * * @return array An associative array of key IDs (kid) to Key objects * * @throws InvalidArgumentException Provided JWK Set is empty * @throws UnexpectedValueException Provided JWK Set was invalid * @throws DomainException OpenSSL failure * * @uses parseKey */ public static function parseKeySet(array $jwks, ?string $defaultAlg = null): array { $keys = []; if (!isset($jwks['keys'])) { throw new UnexpectedValueException('"keys" member must exist in the JWK Set'); } if (empty($jwks['keys'])) { throw new InvalidArgumentException('JWK Set did not contain any keys'); } foreach ($jwks['keys'] as $k => $v) { $kid = isset($v['kid']) ? $v['kid'] : $k; if ($key = self::parseKey($v, $defaultAlg)) { $keys[(string) $kid] = $key; } } if (0 === \count($keys)) { throw new UnexpectedValueException('No supported algorithms found in JWK Set'); } return $keys; } /** * Parse a JWK key * * @param array $jwk An individual JWK * @param string $defaultAlg The algorithm for the Key object if "alg" is not set in the * JSON Web Key Set * * @return Key The key object for the JWK * * @throws InvalidArgumentException Provided JWK is empty * @throws UnexpectedValueException Provided JWK was invalid * @throws DomainException OpenSSL failure * * @uses createPemFromModulusAndExponent */ public static function parseKey(array $jwk, ?string $defaultAlg = null): ?Key { if (empty($jwk)) { throw new InvalidArgumentException('JWK must not be empty'); } if (!isset($jwk['kty'])) { throw new UnexpectedValueException('JWK must contain a "kty" parameter'); } if (!isset($jwk['alg'])) { if (\is_null($defaultAlg)) { // The "alg" parameter is optional in a KTY, but an algorithm is required // for parsing in this library. Use the $defaultAlg parameter when parsing the // key set in order to prevent this error. // @see https://datatracker.ietf.org/doc/html/rfc7517#section-4.4 throw new UnexpectedValueException('JWK must contain an "alg" parameter'); } $jwk['alg'] = $defaultAlg; } switch ($jwk['kty']) { case 'RSA': if (!empty($jwk['d'])) { throw new UnexpectedValueException('RSA private keys are not supported'); } if (!isset($jwk['n']) || !isset($jwk['e'])) { throw new UnexpectedValueException('RSA keys must contain values for both "n" and "e"'); } $pem = self::createPemFromModulusAndExponent($jwk['n'], $jwk['e']); $publicKey = \openssl_pkey_get_public($pem); if (false === $publicKey) { throw new DomainException( 'OpenSSL error: ' . \openssl_error_string() ); } return new Key($publicKey, $jwk['alg']); case 'EC': if (isset($jwk['d'])) { // The key is actually a private key throw new UnexpectedValueException('Key data must be for a public key'); } if (empty($jwk['crv'])) { throw new UnexpectedValueException('crv not set'); } if (!isset(self::EC_CURVES[$jwk['crv']])) { throw new DomainException('Unrecognised or unsupported EC curve'); } if (empty($jwk['x']) || empty($jwk['y'])) { throw new UnexpectedValueException('x and y not set'); } $publicKey = self::createPemFromCrvAndXYCoordinates($jwk['crv'], $jwk['x'], $jwk['y']); return new Key($publicKey, $jwk['alg']); case 'OKP': if (isset($jwk['d'])) { // The key is actually a private key throw new UnexpectedValueException('Key data must be for a public key'); } if (!isset($jwk['crv'])) { throw new UnexpectedValueException('crv not set'); } if (empty(self::OKP_SUBTYPES[$jwk['crv']])) { throw new DomainException('Unrecognised or unsupported OKP key subtype'); } if (empty($jwk['x'])) { throw new UnexpectedValueException('x not set'); } // This library works internally with EdDSA keys (Ed25519) encoded in standard base64. $publicKey = JWT::convertBase64urlToBase64($jwk['x']); return new Key($publicKey, $jwk['alg']); case 'oct': if (!isset($jwk['k'])) { throw new UnexpectedValueException('k not set'); } return new Key(JWT::urlsafeB64Decode($jwk['k']), $jwk['alg']); default: break; } return null; } /** * Converts the EC JWK values to pem format. * * @param string $crv The EC curve (only P-256 & P-384 is supported) * @param string $x The EC x-coordinate * @param string $y The EC y-coordinate * * @return string */ private static function createPemFromCrvAndXYCoordinates(string $crv, string $x, string $y): string { $pem = self::encodeDER( self::ASN1_SEQUENCE, self::encodeDER( self::ASN1_SEQUENCE, self::encodeDER( self::ASN1_OBJECT_IDENTIFIER, self::encodeOID(self::OID) ) . self::encodeDER( self::ASN1_OBJECT_IDENTIFIER, self::encodeOID(self::EC_CURVES[$crv]) ) ) . self::encodeDER( self::ASN1_BIT_STRING, \chr(0x00) . \chr(0x04) . JWT::urlsafeB64Decode($x) . JWT::urlsafeB64Decode($y) ) ); return \sprintf( "-----BEGIN PUBLIC KEY-----\n%s\n-----END PUBLIC KEY-----\n", wordwrap(base64_encode($pem), 64, "\n", true) ); } /** * Create a public key represented in PEM format from RSA modulus and exponent information * * @param string $n The RSA modulus encoded in Base64 * @param string $e The RSA exponent encoded in Base64 * * @return string The RSA public key represented in PEM format * * @uses encodeLength */ private static function createPemFromModulusAndExponent( string $n, string $e ): string { $mod = JWT::urlsafeB64Decode($n); $exp = JWT::urlsafeB64Decode($e); $modulus = \pack('Ca*a*', 2, self::encodeLength(\strlen($mod)), $mod); $publicExponent = \pack('Ca*a*', 2, self::encodeLength(\strlen($exp)), $exp); $rsaPublicKey = \pack( 'Ca*a*a*', 48, self::encodeLength(\strlen($modulus) + \strlen($publicExponent)), $modulus, $publicExponent ); // sequence(oid(1.2.840.113549.1.1.1), null)) = rsaEncryption. $rsaOID = \pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA $rsaPublicKey = \chr(0) . $rsaPublicKey; $rsaPublicKey = \chr(3) . self::encodeLength(\strlen($rsaPublicKey)) . $rsaPublicKey; $rsaPublicKey = \pack( 'Ca*a*', 48, self::encodeLength(\strlen($rsaOID . $rsaPublicKey)), $rsaOID . $rsaPublicKey ); return "-----BEGIN PUBLIC KEY-----\r\n" . \chunk_split(\base64_encode($rsaPublicKey), 64) . '-----END PUBLIC KEY-----'; } /** * DER-encode the length * * DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See * {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information. * * @param int $length * @return string */ private static function encodeLength(int $length): string { if ($length <= 0x7F) { return \chr($length); } $temp = \ltrim(\pack('N', $length), \chr(0)); return \pack('Ca*', 0x80 | \strlen($temp), $temp); } /** * Encodes a value into a DER object. * Also defined in Firebase\JWT\JWT * * @param int $type DER tag * @param string $value the value to encode * @return string the encoded object */ private static function encodeDER(int $type, string $value): string { $tag_header = 0; if ($type === self::ASN1_SEQUENCE) { $tag_header |= 0x20; } // Type $der = \chr($tag_header | $type); // Length $der .= \chr(\strlen($value)); return $der . $value; } /** * Encodes a string into a DER-encoded OID. * * @param string $oid the OID string * @return string the binary DER-encoded OID */ private static function encodeOID(string $oid): string { $octets = explode('.', $oid); // Get the first octet $first = (int) array_shift($octets); $second = (int) array_shift($octets); $oid = \chr($first * 40 + $second); // Iterate over subsequent octets foreach ($octets as $octet) { if ($octet == 0) { $oid .= \chr(0x00); continue; } $bin = ''; while ($octet) { $bin .= \chr(0x80 | ($octet & 0x7f)); $octet >>= 7; } $bin[0] = $bin[0] & \chr(0x7f); // Convert to big endian if necessary if (pack('V', 65534) == pack('L', 65534)) { $oid .= strrev($bin); } else { $oid .= $bin; } } return $oid; } } ================================================ FILE: vendor/firebase/php-jwt/src/JWT.php ================================================ * @author Anant Narayanan * @license http://opensource.org/licenses/BSD-3-Clause 3-clause BSD * @link https://github.com/firebase/php-jwt */ class JWT { private const ASN1_INTEGER = 0x02; private const ASN1_SEQUENCE = 0x10; private const ASN1_BIT_STRING = 0x03; /** * When checking nbf, iat or expiration times, * we want to provide some extra leeway time to * account for clock skew. * * @var int */ public static $leeway = 0; /** * Allow the current timestamp to be specified. * Useful for fixing a value within unit testing. * Will default to PHP time() value if null. * * @var ?int */ public static $timestamp = null; /** * @var array */ public static $supported_algs = [ 'ES384' => ['openssl', 'SHA384'], 'ES256' => ['openssl', 'SHA256'], 'ES256K' => ['openssl', 'SHA256'], 'HS256' => ['hash_hmac', 'SHA256'], 'HS384' => ['hash_hmac', 'SHA384'], 'HS512' => ['hash_hmac', 'SHA512'], 'RS256' => ['openssl', 'SHA256'], 'RS384' => ['openssl', 'SHA384'], 'RS512' => ['openssl', 'SHA512'], 'EdDSA' => ['sodium_crypto', 'EdDSA'], ]; /** * Decodes a JWT string into a PHP object. * * @param string $jwt The JWT * @param Key|ArrayAccess|array $keyOrKeyArray The Key or associative array of key IDs * (kid) to Key objects. * If the algorithm used is asymmetric, this is * the public key. * Each Key object contains an algorithm and * matching key. * Supported algorithms are 'ES384','ES256', * 'HS256', 'HS384', 'HS512', 'RS256', 'RS384' * and 'RS512'. * @param stdClass $headers Optional. Populates stdClass with headers. * * @return stdClass The JWT's payload as a PHP object * * @throws InvalidArgumentException Provided key/key-array was empty or malformed * @throws DomainException Provided JWT is malformed * @throws UnexpectedValueException Provided JWT was invalid * @throws SignatureInvalidException Provided JWT was invalid because the signature verification failed * @throws BeforeValidException Provided JWT is trying to be used before it's eligible as defined by 'nbf' * @throws BeforeValidException Provided JWT is trying to be used before it's been created as defined by 'iat' * @throws ExpiredException Provided JWT has since expired, as defined by the 'exp' claim * * @uses jsonDecode * @uses urlsafeB64Decode */ public static function decode( string $jwt, $keyOrKeyArray, ?stdClass &$headers = null ): stdClass { // Validate JWT $timestamp = \is_null(static::$timestamp) ? \time() : static::$timestamp; if (empty($keyOrKeyArray)) { throw new InvalidArgumentException('Key may not be empty'); } $tks = \explode('.', $jwt); if (\count($tks) !== 3) { throw new UnexpectedValueException('Wrong number of segments'); } list($headb64, $bodyb64, $cryptob64) = $tks; $headerRaw = static::urlsafeB64Decode($headb64); if (null === ($header = static::jsonDecode($headerRaw))) { throw new UnexpectedValueException('Invalid header encoding'); } if ($headers !== null) { $headers = $header; } $payloadRaw = static::urlsafeB64Decode($bodyb64); if (null === ($payload = static::jsonDecode($payloadRaw))) { throw new UnexpectedValueException('Invalid claims encoding'); } if (\is_array($payload)) { // prevent PHP Fatal Error in edge-cases when payload is empty array $payload = (object) $payload; } if (!$payload instanceof stdClass) { throw new UnexpectedValueException('Payload must be a JSON object'); } $sig = static::urlsafeB64Decode($cryptob64); if (empty($header->alg)) { throw new UnexpectedValueException('Empty algorithm'); } if (empty(static::$supported_algs[$header->alg])) { throw new UnexpectedValueException('Algorithm not supported'); } $key = self::getKey($keyOrKeyArray, property_exists($header, 'kid') ? $header->kid : null); // Check the algorithm if (!self::constantTimeEquals($key->getAlgorithm(), $header->alg)) { // See issue #351 throw new UnexpectedValueException('Incorrect key for this algorithm'); } if (\in_array($header->alg, ['ES256', 'ES256K', 'ES384'], true)) { // OpenSSL expects an ASN.1 DER sequence for ES256/ES256K/ES384 signatures $sig = self::signatureToDER($sig); } if (!self::verify("{$headb64}.{$bodyb64}", $sig, $key->getKeyMaterial(), $header->alg)) { throw new SignatureInvalidException('Signature verification failed'); } // Check the nbf if it is defined. This is the time that the // token can actually be used. If it's not yet that time, abort. if (isset($payload->nbf) && floor($payload->nbf) > ($timestamp + static::$leeway)) { $ex = new BeforeValidException( 'Cannot handle token with nbf prior to ' . \date(DateTime::ISO8601, (int) floor($payload->nbf)) ); $ex->setPayload($payload); throw $ex; } // Check that this token has been created before 'now'. This prevents // using tokens that have been created for later use (and haven't // correctly used the nbf claim). if (!isset($payload->nbf) && isset($payload->iat) && floor($payload->iat) > ($timestamp + static::$leeway)) { $ex = new BeforeValidException( 'Cannot handle token with iat prior to ' . \date(DateTime::ISO8601, (int) floor($payload->iat)) ); $ex->setPayload($payload); throw $ex; } // Check if this token has expired. if (isset($payload->exp) && ($timestamp - static::$leeway) >= $payload->exp) { $ex = new ExpiredException('Expired token'); $ex->setPayload($payload); throw $ex; } return $payload; } /** * Converts and signs a PHP array into a JWT string. * * @param array $payload PHP array * @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $key The secret key. * @param string $alg Supported algorithms are 'ES384','ES256', 'ES256K', 'HS256', * 'HS384', 'HS512', 'RS256', 'RS384', and 'RS512' * @param string $keyId * @param array $head An array with header elements to attach * * @return string A signed JWT * * @uses jsonEncode * @uses urlsafeB64Encode */ public static function encode( array $payload, $key, string $alg, ?string $keyId = null, ?array $head = null ): string { $header = ['typ' => 'JWT']; if (isset($head)) { $header = \array_merge($header, $head); } $header['alg'] = $alg; if ($keyId !== null) { $header['kid'] = $keyId; } $segments = []; $segments[] = static::urlsafeB64Encode((string) static::jsonEncode($header)); $segments[] = static::urlsafeB64Encode((string) static::jsonEncode($payload)); $signing_input = \implode('.', $segments); $signature = static::sign($signing_input, $key, $alg); $segments[] = static::urlsafeB64Encode($signature); return \implode('.', $segments); } /** * Sign a string with a given key and algorithm. * * @param string $msg The message to sign * @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $key The secret key. * @param string $alg Supported algorithms are 'EdDSA', 'ES384', 'ES256', 'ES256K', 'HS256', * 'HS384', 'HS512', 'RS256', 'RS384', and 'RS512' * * @return string An encrypted message * * @throws DomainException Unsupported algorithm or bad key was specified */ public static function sign( string $msg, $key, string $alg ): string { if (empty(static::$supported_algs[$alg])) { throw new DomainException('Algorithm not supported'); } list($function, $algorithm) = static::$supported_algs[$alg]; switch ($function) { case 'hash_hmac': if (!\is_string($key)) { throw new InvalidArgumentException('key must be a string when using hmac'); } return \hash_hmac($algorithm, $msg, $key, true); case 'openssl': $signature = ''; if (!\is_resource($key) && !openssl_pkey_get_private($key)) { throw new DomainException('OpenSSL unable to validate key'); } $success = \openssl_sign($msg, $signature, $key, $algorithm); // @phpstan-ignore-line if (!$success) { throw new DomainException('OpenSSL unable to sign data'); } if ($alg === 'ES256' || $alg === 'ES256K') { $signature = self::signatureFromDER($signature, 256); } elseif ($alg === 'ES384') { $signature = self::signatureFromDER($signature, 384); } return $signature; case 'sodium_crypto': if (!\function_exists('sodium_crypto_sign_detached')) { throw new DomainException('libsodium is not available'); } if (!\is_string($key)) { throw new InvalidArgumentException('key must be a string when using EdDSA'); } try { // The last non-empty line is used as the key. $lines = array_filter(explode("\n", $key)); $key = base64_decode((string) end($lines)); if (\strlen($key) === 0) { throw new DomainException('Key cannot be empty string'); } return sodium_crypto_sign_detached($msg, $key); } catch (Exception $e) { throw new DomainException($e->getMessage(), 0, $e); } } throw new DomainException('Algorithm not supported'); } /** * Verify a signature with the message, key and method. Not all methods * are symmetric, so we must have a separate verify and sign method. * * @param string $msg The original message (header and body) * @param string $signature The original signature * @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $keyMaterial For Ed*, ES*, HS*, a string key works. for RS*, must be an instance of OpenSSLAsymmetricKey * @param string $alg The algorithm * * @return bool * * @throws DomainException Invalid Algorithm, bad key, or OpenSSL failure */ private static function verify( string $msg, string $signature, $keyMaterial, string $alg ): bool { if (empty(static::$supported_algs[$alg])) { throw new DomainException('Algorithm not supported'); } list($function, $algorithm) = static::$supported_algs[$alg]; switch ($function) { case 'openssl': $success = \openssl_verify($msg, $signature, $keyMaterial, $algorithm); // @phpstan-ignore-line if ($success === 1) { return true; } if ($success === 0) { return false; } // returns 1 on success, 0 on failure, -1 on error. throw new DomainException( 'OpenSSL error: ' . \openssl_error_string() ); case 'sodium_crypto': if (!\function_exists('sodium_crypto_sign_verify_detached')) { throw new DomainException('libsodium is not available'); } if (!\is_string($keyMaterial)) { throw new InvalidArgumentException('key must be a string when using EdDSA'); } try { // The last non-empty line is used as the key. $lines = array_filter(explode("\n", $keyMaterial)); $key = base64_decode((string) end($lines)); if (\strlen($key) === 0) { throw new DomainException('Key cannot be empty string'); } if (\strlen($signature) === 0) { throw new DomainException('Signature cannot be empty string'); } return sodium_crypto_sign_verify_detached($signature, $msg, $key); } catch (Exception $e) { throw new DomainException($e->getMessage(), 0, $e); } case 'hash_hmac': default: if (!\is_string($keyMaterial)) { throw new InvalidArgumentException('key must be a string when using hmac'); } $hash = \hash_hmac($algorithm, $msg, $keyMaterial, true); return self::constantTimeEquals($hash, $signature); } } /** * Decode a JSON string into a PHP object. * * @param string $input JSON string * * @return mixed The decoded JSON string * * @throws DomainException Provided string was invalid JSON */ public static function jsonDecode(string $input) { $obj = \json_decode($input, false, 512, JSON_BIGINT_AS_STRING); if ($errno = \json_last_error()) { self::handleJsonError($errno); } elseif ($obj === null && $input !== 'null') { throw new DomainException('Null result with non-null input'); } return $obj; } /** * Encode a PHP array into a JSON string. * * @param array $input A PHP array * * @return string JSON representation of the PHP array * * @throws DomainException Provided object could not be encoded to valid JSON */ public static function jsonEncode(array $input): string { $json = \json_encode($input, \JSON_UNESCAPED_SLASHES); if ($errno = \json_last_error()) { self::handleJsonError($errno); } elseif ($json === 'null') { throw new DomainException('Null result with non-null input'); } if ($json === false) { throw new DomainException('Provided object could not be encoded to valid JSON'); } return $json; } /** * Decode a string with URL-safe Base64. * * @param string $input A Base64 encoded string * * @return string A decoded string * * @throws InvalidArgumentException invalid base64 characters */ public static function urlsafeB64Decode(string $input): string { return \base64_decode(self::convertBase64UrlToBase64($input)); } /** * Convert a string in the base64url (URL-safe Base64) encoding to standard base64. * * @param string $input A Base64 encoded string with URL-safe characters (-_ and no padding) * * @return string A Base64 encoded string with standard characters (+/) and padding (=), when * needed. * * @see https://www.rfc-editor.org/rfc/rfc4648 */ public static function convertBase64UrlToBase64(string $input): string { $remainder = \strlen($input) % 4; if ($remainder) { $padlen = 4 - $remainder; $input .= \str_repeat('=', $padlen); } return \strtr($input, '-_', '+/'); } /** * Encode a string with URL-safe Base64. * * @param string $input The string you want encoded * * @return string The base64 encode of what you passed in */ public static function urlsafeB64Encode(string $input): string { return \str_replace('=', '', \strtr(\base64_encode($input), '+/', '-_')); } /** * Determine if an algorithm has been provided for each Key * * @param Key|ArrayAccess|array $keyOrKeyArray * @param string|null $kid * * @throws UnexpectedValueException * * @return Key */ private static function getKey( $keyOrKeyArray, ?string $kid ): Key { if ($keyOrKeyArray instanceof Key) { return $keyOrKeyArray; } if (empty($kid) && $kid !== '0') { throw new UnexpectedValueException('"kid" empty, unable to lookup correct key'); } if ($keyOrKeyArray instanceof CachedKeySet) { // Skip "isset" check, as this will automatically refresh if not set return $keyOrKeyArray[$kid]; } if (!isset($keyOrKeyArray[$kid])) { throw new UnexpectedValueException('"kid" invalid, unable to lookup correct key'); } return $keyOrKeyArray[$kid]; } /** * @param string $left The string of known length to compare against * @param string $right The user-supplied string * @return bool */ public static function constantTimeEquals(string $left, string $right): bool { if (\function_exists('hash_equals')) { return \hash_equals($left, $right); } $len = \min(self::safeStrlen($left), self::safeStrlen($right)); $status = 0; for ($i = 0; $i < $len; $i++) { $status |= (\ord($left[$i]) ^ \ord($right[$i])); } $status |= (self::safeStrlen($left) ^ self::safeStrlen($right)); return ($status === 0); } /** * Helper method to create a JSON error. * * @param int $errno An error number from json_last_error() * * @throws DomainException * * @return void */ private static function handleJsonError(int $errno): void { $messages = [ JSON_ERROR_DEPTH => 'Maximum stack depth exceeded', JSON_ERROR_STATE_MISMATCH => 'Invalid or malformed JSON', JSON_ERROR_CTRL_CHAR => 'Unexpected control character found', JSON_ERROR_SYNTAX => 'Syntax error, malformed JSON', JSON_ERROR_UTF8 => 'Malformed UTF-8 characters' //PHP >= 5.3.3 ]; throw new DomainException( isset($messages[$errno]) ? $messages[$errno] : 'Unknown JSON error: ' . $errno ); } /** * Get the number of bytes in cryptographic strings. * * @param string $str * * @return int */ private static function safeStrlen(string $str): int { if (\function_exists('mb_strlen')) { return \mb_strlen($str, '8bit'); } return \strlen($str); } /** * Convert an ECDSA signature to an ASN.1 DER sequence * * @param string $sig The ECDSA signature to convert * @return string The encoded DER object */ private static function signatureToDER(string $sig): string { // Separate the signature into r-value and s-value $length = max(1, (int) (\strlen($sig) / 2)); list($r, $s) = \str_split($sig, $length); // Trim leading zeros $r = \ltrim($r, "\x00"); $s = \ltrim($s, "\x00"); // Convert r-value and s-value from unsigned big-endian integers to // signed two's complement if (\ord($r[0]) > 0x7f) { $r = "\x00" . $r; } if (\ord($s[0]) > 0x7f) { $s = "\x00" . $s; } return self::encodeDER( self::ASN1_SEQUENCE, self::encodeDER(self::ASN1_INTEGER, $r) . self::encodeDER(self::ASN1_INTEGER, $s) ); } /** * Encodes a value into a DER object. * * @param int $type DER tag * @param string $value the value to encode * * @return string the encoded object */ private static function encodeDER(int $type, string $value): string { $tag_header = 0; if ($type === self::ASN1_SEQUENCE) { $tag_header |= 0x20; } // Type $der = \chr($tag_header | $type); // Length $der .= \chr(\strlen($value)); return $der . $value; } /** * Encodes signature from a DER object. * * @param string $der binary signature in DER format * @param int $keySize the number of bits in the key * * @return string the signature */ private static function signatureFromDER(string $der, int $keySize): string { // OpenSSL returns the ECDSA signatures as a binary ASN.1 DER SEQUENCE list($offset, $_) = self::readDER($der); list($offset, $r) = self::readDER($der, $offset); list($offset, $s) = self::readDER($der, $offset); // Convert r-value and s-value from signed two's compliment to unsigned // big-endian integers $r = \ltrim($r, "\x00"); $s = \ltrim($s, "\x00"); // Pad out r and s so that they are $keySize bits long $r = \str_pad($r, $keySize / 8, "\x00", STR_PAD_LEFT); $s = \str_pad($s, $keySize / 8, "\x00", STR_PAD_LEFT); return $r . $s; } /** * Reads binary DER-encoded data and decodes into a single object * * @param string $der the binary data in DER format * @param int $offset the offset of the data stream containing the object * to decode * * @return array{int, string|null} the new offset and the decoded object */ private static function readDER(string $der, int $offset = 0): array { $pos = $offset; $size = \strlen($der); $constructed = (\ord($der[$pos]) >> 5) & 0x01; $type = \ord($der[$pos++]) & 0x1f; // Length $len = \ord($der[$pos++]); if ($len & 0x80) { $n = $len & 0x1f; $len = 0; while ($n-- && $pos < $size) { $len = ($len << 8) | \ord($der[$pos++]); } } // Value if ($type === self::ASN1_BIT_STRING) { $pos++; // Skip the first contents octet (padding indicator) $data = \substr($der, $pos, $len - 1); $pos += $len - 1; } elseif (!$constructed) { $data = \substr($der, $pos, $len); $pos += $len; } else { $data = null; } return [$pos, $data]; } } ================================================ FILE: vendor/firebase/php-jwt/src/JWTExceptionWithPayloadInterface.php ================================================ algorithm; } /** * @return string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate */ public function getKeyMaterial() { return $this->keyMaterial; } } ================================================ FILE: vendor/firebase/php-jwt/src/SignatureInvalidException.php ================================================ =5.3" }, "autoload": { "classmap": [ "lib/classes" ] } } ================================================ FILE: vendor/udx/lib-ud-api-client/gruntfile.js ================================================ /** * Build Plugin. * * @author potanin@UD * @version 1.2.5 * @param grunt */ module.exports = function( grunt ) { // Automatically Load Tasks. require( 'load-grunt-tasks' )( grunt, { pattern: 'grunt-*', config: './package.json', scope: 'devDependencies' }); // Build Configuration. grunt.initConfig({ // Get Package. package: grunt.file.readJSON( 'composer.json' ), // Compile Core and Template Styles. less: { production: { options: { yuicompress: true, relativeUrls: true }, files: { 'static/css/admin.css': [ 'static/css/src/admin.less' ] } }, development: { options: { yuicompress: false, relativeUrls: true }, files: { 'static/css/wpp.admin.dev.css': [ 'static/css/src/wpp.admin.less' ] } } }, // Generate YUIDoc documentation. yuidoc: { compile: { name: '<%= package.name %>', description: '<%= package.description %>', version: '<%= package.version %>', url: '<%= package.homepage %>', options: { extension: '.js,.php', outdir: 'static/codex/', "paths": [ "./lib", "./static/js" ] } } }, // Watch for Development. watch: { options: { interval: 100, debounceDelay: 500 }, less: { files: [ 'static/css/src/*.less' ], tasks: [ 'less:production' ] }, js: { files: [ 'static/js/src/*' ], tasks: [ 'uglify:production' ] } }, // Minify Core and Template Scripts. uglify: { production: { options: { mangle: false, beautify: false }, files: [ { expand: true, cwd: 'static/js/src', src: [ '*.js' ], dest: 'static/js' } ] }, development: { options: { mangle: false, beautify: true }, files: [ { expand: true, cwd: 'static/js/src', src: [ '*.js' ], dest: 'static/js' } ] } }, // Generate Markdown Documentation. markdown: { all: { files: [ { expand: true, src: 'readme.md', dest: 'static/', ext: '.html' } ], options: { markdownOptions: { gfm: true, codeLines: { before: '', after: '' } } } } }, // Clean Directories. clean: { all: [ "vendor", "composer.lock" ] }, shell: { install: { command: 'composer install', options: { stdout: true } }, update: { command: 'composer update', options: { stdout: true } } } }); // Register NPM Tasks. grunt.registerTask( 'default', [ 'markdown', 'less:production', 'yuidoc', 'uglify:production' ] ); // Install Library. grunt.registerTask( 'install', [ 'markdown', 'less:production', 'yuidoc', 'uglify:production' ] ); // Prepare for Distribution. grunt.registerTask( 'make-distribution', [ 'markdown', 'less:production', 'yuidoc', 'uglify:production' ] ); }; ================================================ FILE: vendor/udx/lib-ud-api-client/lib/classes/class-admin.php ================================================ "; print_r( $args ); echo ""; die(); //** Set UD API URL. Can be defined custom one in wp-config.php */ $this->api_url = defined( 'UD_API_URL' ) ? trailingslashit( UD_API_URL ) : 'https://www.usabilitydynamics.com/'; //** Don't ever change this, as it will mess with the data stored of which products are activated, etc. */ $this->token = 'udl_' . $this->slug; //** API */ $this->api = new API( array_merge( $args, array( 'api_url' => $this->api_url, 'token' => $this->token, ) ) ); //** Set available screens */ add_action('init', function () use ($args) { $screens = array(); if( $this->type == 'theme' ) { $screens =array_filter( array( 'licenses' => __( 'License', $this->domain ), 'more_products' => false, ) ); } elseif ( $this->type == 'plugin' ) { $screens =array_filter( array( 'licenses' => __( 'Licenses', $this->domain ), 'more_products' => __( 'More Products', $this->domain ), ) ); } // Initialize UI $this->ui = new UI( array_merge( $args, array( 'token' => $this->token, 'screens' => $screens, ) ) ); }, 20); $path = wp_normalize_path( dirname( dirname( __DIR__ ) ) ); $this->screens_path = trailingslashit( $path . '/static/templates' ); if( $this->type == 'theme' && strpos( $path, wp_normalize_path( WP_PLUGIN_DIR ) ) === false ) { $root_path = wp_normalize_path( get_template_directory() ); $this->assets_url = trailingslashit( get_template_directory_uri() . str_replace( $root_path, '', $path ) . '/static' ); } else { $this->assets_url = trailingslashit( plugin_dir_url( dirname( dirname( __DIR__ ) ) . '/readme.md' ) . 'static' ); } //** Load the updaters. */ add_action( 'admin_init', array( $this, 'load_updater_instances' ) ); //** Ensure keys are actually active on specific screens */ add_action( 'current_screen', array( $this, 'current_screen' ) ); if( $this->type == 'plugin' ) { //** Check Activation Statuses */ add_action( 'plugins_loaded', array( $this, 'check_activation_status' ), 11 ); } elseif( $this->type == 'theme' ) { $this->check_activation_status(); } //** Add Licenses page */ add_action( 'admin_menu', array( $this, 'register_licenses_screen' ), 999 ); //** Admin Notices Filter */ add_filter( 'ud:errors:admin_notices', array( $this, 'maybe_remove_notices' ) ); add_filter( 'ud:messages:admin_notices', array( $this, 'maybe_remove_notices' ) ); add_filter( 'ud:warnings:admin_notices', array( $this, 'maybe_remove_notices' ) ); /** * May be add additional information about available add-ons * for legacy users ( who purchased any deprecated premium feature ) */ add_action( 'ud::bootstrap::upgrade_notice::additional_info', array( $this, 'maybe_add_info_to_upgrade_notice' ), 10, 2 ); } /** * Register the admin screen. * * @access public * @since 1.0.0 * @return void */ public function register_licenses_screen () { $args = $this->args; $screen = !empty( $args[ 'screen' ] ) ? $args[ 'screen' ] : false; $this->screen_type = !empty( $screen[ 'parent' ] ) ? 'submenu' : 'menu'; $this->icon_url = !empty( $screen[ 'icon_url' ] ) ? $screen[ 'icon_url' ] : ''; $this->position = !empty( $screen[ 'position' ] ) ? $screen[ 'position' ] : 66; $this->menu_title = !empty( $screen[ 'menu_title' ] ) ? $screen[ 'menu_title' ] : __( 'Licenses', $this->domain ); $this->page_title = !empty( $screen[ 'page_title' ] ) ? $screen[ 'page_title' ] : __( 'Licenses', $this->domain ); $this->menu_slug = $this->slug . '_' . sanitize_key( $this->page_title ); switch( $this->screen_type ) { case 'menu': global $menu; $this->hook = add_menu_page( $this->page_title, $this->menu_title, 'manage_options', $this->menu_slug, array( $this, 'settings_screen' ), $this->icon_url, $this->position ); break; case 'submenu': global $submenu; $this->hook = add_submenu_page( $screen[ 'parent' ], $this->page_title, $this->menu_title, 'manage_options', $this->menu_slug, array( $this, 'settings_screen' ) ); break; } //** Set url for licenses page */ $licenses_link = isset( $screen[ 'parent' ] ) && ( strpos( $screen[ 'parent' ], '?' ) !== false || strpos( $screen[ 'parent' ], '.php' ) !== false ) ? $screen[ 'parent' ] : 'admin.php'; $licenses_link = add_query_arg( array( 'page' => $this->menu_slug, ), admin_url( $licenses_link ) ); update_option( $this->token . '-url', $licenses_link ); add_action( 'load-' . $this->hook, array( $this, 'process_request' ) ); add_action( 'admin_print_styles-' . $this->hook, array( $this, 'enqueue_styles' ) ); add_action( 'admin_print_scripts-' . $this->hook, array( $this, 'enqueue_scripts' ) ); } /** * Ensure licenses keys are actually active on 'Installed Plugins' page * * @access public * @since 1.0.0 * @return void */ public function current_screen ( $screen ) { switch( $screen->id ) { case 'plugins': //** Check licenses keys once per 12 hours */ if ( false === ( $e = get_transient( $this->token . '_ping' ) ) ) { $this->ensure_keys_are_actually_active(); set_transient( $this->token . '_ping', time(), 12 * HOUR_IN_SECONDS ); } break; } } /** * Load the main management screen. * * @access public * @since 1.0.0 * @return void */ public function settings_screen () { $this->ui->get_header(); $screen = $this->ui->get_current_screen(); switch ( $screen ) { //** Products screen. */ case 'more_products': $this->more_products = $this->get_more_products(); require_once( $this->screens_path . 'screen-more.php' ); break; //** Licenses screen. */ case 'licenses': default: $this->ensure_keys_are_actually_active(); $this->installed_products = $this->get_detected_products(); $this->pending_products = $this->get_pending_products(); require_once( $this->screens_path . 'screen-manage-' . $this->type . '.php' ); break; } $this->ui->get_footer(); } /** * Process the action for the admin screen. * @since 1.0.0 * @return void */ public function process_request () { add_action( 'admin_notices', array( $this, 'admin_notices' ) ); $supported_actions = array( 'activate-products', 'deactivate-product' ); if ( !isset( $_REQUEST['action'] ) || !in_array( $_REQUEST['action'], $supported_actions ) || !check_admin_referer( 'bulk-' . 'licenses' ) ) { return null; } $response = false; $status = 'false'; $type = $_REQUEST['action']; switch ( $type ) { case 'activate-products': $products = array(); if ( isset( $_POST[ 'products' ] ) && 0 < count( $_POST[ 'products' ] ) ) { foreach ( $_POST[ 'products' ] as $k => $v ) { if ( !empty( $v[ 'license_key' ] ) ) { $products[$k] = $v; } } } if ( 0 < count( $products ) ) { //echo "
      "; print_r( $products ); echo "
      "; die(); $response = $this->activate_products( $products ); } else { $response = false; $type = 'no-license-keys'; } break; case 'deactivate-product': if ( isset( $_GET['filepath'] ) && ( '' != $_GET['filepath'] ) ) { $response = $this->deactivate_product( $_GET['filepath'] ); } break; default: break; } if ( $response == true ) { $status = 'true'; } $redirect_url = Utility::current_url( array( 'type' => urlencode( $type ), 'status' => urlencode( $status ) ), array( 'action', 'filepath', '_wpnonce' ) ); wp_safe_redirect( $redirect_url ); exit; } /** * Enqueue admin styles. * @access public * @since 1.0.0 * @return void */ public function enqueue_styles () { wp_enqueue_style( 'lib-ud-api-client-admin', esc_url( $this->assets_url . 'css/admin.css' ), array(), '1.0.0', 'all' ); } /** * Enqueue admin scripts. * * @access public * @since 1.0.0 * @return void */ public function enqueue_scripts () { wp_enqueue_script( 'post' ); } /** * Run checks against the API to ensure the product keys are actually active on UsabilityDynamics. If not, deactivate them locally as well. * * @access public * @since 1.0.0 * @return void */ public function ensure_keys_are_actually_active () { $already_active = (array)$this->get_activated_products(); $products = $this->get_detected_products(); if ( 0 < count( $already_active ) ) { foreach ( $already_active as $k => $v ) { //** Only look through activated plugins */ if( !array_key_exists( $k, $products ) ) { continue; } $deactivate = true; if ( !empty( $already_active[ $k ][2] ) ) { //** Get license and activation email */ $data = base64_decode( $already_active[ $k ][2] ); $data = explode( '::', $data ); $license_key = isset( $data[0] ) ? trim( $data[0] ) : ''; $activation_email = isset( $data[1] ) ? trim( $data[1] ) : ''; //** Do request */ $response = $this->api->status( array( 'product_id' => $already_active[ $k ][0], 'instance' => $already_active[ $k ][1], 'email' => trim($activation_email), 'licence_key' => trim($license_key), ), false, false ); //** Do not deactivate if cannot reach UD */ if ( $response === false ) { continue; } if( is_array( $response ) && !empty( $response[ 'status_check' ] ) && $response[ 'status_check' ] == 'active' ) { $deactivate = false; } } if( $deactivate ) { $this->deactivate_product( $k, true ); } } } } /** * Activate a given array of products. * * @since 1.0.0 * @param array $products Array of products ( filepath => key ) * @return boolean */ protected function activate_products ( $products ) { $response = true; $errors = false; //** Get out if we have incorrect data. */ if ( !is_array( $products ) || ( 0 >= count( $products ) ) ) { return false; } $key = $this->token . '-activated'; $has_update = false; $already_active = $this->get_activated_products(); $product_keys = $this->get_detected_products(); foreach ( $products as $k => $v ) { //echo "
      "; print_r( $product_keys[ $k ] ); echo "
      "; die(); if( empty( $product_keys[ $k ] ) ) { continue; } //** Perform API "activation" request. */ $activate = $this->api->activate( array( 'product_id' => $product_keys[ $k ][ 'product_id' ], 'instance' => $product_keys[ $k ][ 'instance_key' ], 'software_version' => $product_keys[ $k ][ 'product_version' ], 'licence_key' => trim($v[ 'license_key' ]), 'email' => trim($v[ 'activation_email' ]), ), $product_keys[ $k ] ); if ( false !== $activate && empty( $activate[ 'error' ] ) ) { // key: base file, 0: product id, 1: instance_key, 2: hashed license and mail. $hash = base64_encode( $v[ 'license_key' ] . '::' . $v[ 'activation_email' ] ); $already_active[$k] = array( $product_keys[$k]['product_id'], $product_keys[$k]['instance_key'], $hash ); $has_update = true; } else { $errors = true; } } //** Store the error log. */ $this->api->store_error_log(); if ( $has_update && !update_option( $key, $already_active ) ) { $response = false; } elseif( $errors ) { $response = false; } return $response; } /** * Deactivate a given product key. * * @since 1.0.0 * @param string $filename File name of the to deactivate plugin licence * @param bool $local_only Deactivate the product locally without pinging UsabilityDynamics. * @return boolean Whether or not the deactivation was successful. */ protected function deactivate_product ( $filename, $local_only = false ) { $response = false; $already_active = $this->get_activated_products(); $products = $this->get_detected_products(); if ( 0 < count( $already_active ) ) { $deactivated = true; if ( !empty( $products[ $filename ] ) && !empty( $already_active[ $filename ][2] ) && false == $local_only ) { //** Get license and activation email */ $data = base64_decode( $already_active[ $filename ][2] ); $data = explode( '::', $data ); $license_key = isset( $data[0] ) ? $data[0] : ''; $activation_email = isset( $data[1] ) ? $data[1] : ''; //** Do request */ $deactivated = $this->api->deactivate( array( 'product_id' => $already_active[ $filename ][0], 'instance' => $already_active[ $filename ][1], 'email' => $activation_email, 'licence_key' => $license_key, ), $products[ $filename ] ); } if ( false !== $deactivated && empty( $deactivated[ 'error' ] ) ) { unset( $already_active[ $filename ] ); $response = update_option( $this->token . '-activated', $already_active ); } else { $this->api->store_error_log(); } } return $response; } /** * Load an instance of the updater class for each activated UsabilityDynamics Product. * @access public * @since 1.0.0 * @return void */ public function load_updater_instances () { $args = $this->args; $products = $this->get_detected_products(); $activated_products = $this->get_activated_products(); if ( 0 < count( $products ) ) { foreach ( $products as $k => $v ) { if ( isset( $v['product_id'] ) && isset( $v['instance_key'] ) ) { //** Maybe Get license and activation email */ $api_key = ''; $activation_email = ''; if( !empty( $activated_products[ $k ][2] ) ) { $data = base64_decode( $activated_products[ $k ][2] ); $data = explode( '::', $data ); $api_key = isset( $data[0] ) ? $data[0] : ''; $activation_email = isset( $data[1] ) ? $data[1] : ''; } //echo "
      "; print_r( $v ); echo "
      "; //die(); if( !empty( $api_key ) ) { new Update_Checker( array( 'type' => $this->type, 'upgrade_url' => $this->api_url, 'name' => $v[ 'product_name' ], 'file' => $v[ 'product_file_path' ], 'product_id' => $v[ 'product_id' ], 'api_key' => $api_key, 'activation_email' => $activation_email, 'renew_license_url' => trailingslashit( $this->api_url ) . 'account', 'instance' => $v[ 'instance_key' ], 'software_version' => $v[ 'product_version' ], 'text_domain' => $this->domain, 'changelog' => ( isset( $args[ 'changelog' ] ) ? $args[ 'changelog' ] : false ), ), $v[ 'errors_callback' ] ); } } } } } /** * Detect which products have been activated. * * @access public * @since 1.0.0 * @return void */ protected function get_activated_products () { $response = array(); $response = get_option( $this->token . '-activated', array() ); if ( ! is_array( $response ) ) $response = array(); return $response; } /** * Wrapper for get detected theme or plugins. * * @access public * @since 1.0.0 * @return void */ protected function get_detected_products () { if ( $this->type == 'theme' ) { return $this->get_detected_theme(); } elseif ( $this->type == 'plugin' ) { return $this->get_detected_plugins(); } else { return array(); } } /** * Get a list of UsabilityDynamics plugins found on this installation. * * @access public * @since 1.0.0 * @return void */ protected function get_detected_plugins () { //** Check if get_plugins() function exists */ if ( ! function_exists( 'get_plugins' ) ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } $response = array(); $products = get_plugins(); if ( is_array( $products ) && ( 0 < count( $products ) ) ) { $reference_list = $this->get_product_reference_list(); //echo "
      "; print_r( $reference_list ); echo "
      "; die(); $activated_products = $this->get_activated_products(); if ( is_array( $reference_list ) && ( 0 < count( $reference_list ) ) ) { foreach ( $products as $k => $v ) { if ( in_array( $k, array_keys( $reference_list ) ) ) { $status = 'inactive'; if ( in_array( $k, array_keys( $activated_products ) ) ) { $status = 'active'; } $response[$k] = array( 'product_name' => $v['Name'], 'product_version' => $v['Version'], 'instance_key' => $reference_list[$k]['instance_key'], 'product_id' => $reference_list[$k]['product_id'], 'product_status' => $status, 'product_file_path' => $k, 'errors_callback' => isset( $reference_list[$k]['errors_callback'] ) ? $reference_list[$k]['errors_callback'] : false, ); } } } } return $response; } /** * Get detected theme. * * @access public * @since 1.0.0 * @return void */ protected function get_detected_theme () { $response = array(); $reference_list = $this->get_product_reference_list(); $activated_products = $this->get_activated_products(); if ( is_array( $reference_list ) && ( 0 < count( $reference_list ) ) ) { $boot_path = wp_normalize_path( get_template_directory() ) . '/style.css'; $product = isset( $reference_list[ $boot_path ] ) ? $reference_list[ $boot_path ] : false; if ( $product ) { $status = 'inactive'; if ( isset( $activated_products[ $boot_path ] ) ) { $status = 'active'; } $response[ $boot_path ] = array( 'product_name' => $this->name, 'product_version' => $this->args[ 'version' ], 'instance_key' => $product['instance_key'], 'product_id' => $product['product_id'], 'product_status' => $status, 'product_file_path' => $boot_path, 'errors_callback' => isset( $product['errors_callback'] ) ? $product['errors_callback'] : false, ); } } //echo "
      "; print_r( $response ); echo "
      "; die(); return $response; } /** * Get a list of UsabilityDynamics plugins or themes which are available for purchasing and downloading. * * @since 1.0.0 * @return mixed */ protected function get_more_products() { $more_products = array(); $trnst = get_transient( $this->token . "-more-a" ); //** If we do not have cache ( transient ), do request to get the list of all available products */ if( !$trnst || !is_array( $trnst ) ) { $target_url = $this->api_url . 'products.json'; $request = wp_remote_get( $target_url, array( 'sslverify' => false ) ); if( is_wp_error( $request ) || wp_remote_retrieve_response_code( $request ) != 200 ) { $this->error = $request; return $more_products; } else { $response = wp_remote_retrieve_body( $request ); $response = @json_decode( $response, true ); if( empty( $response ) || !is_array( $response ) ) { return $more_products; } else { $locale = get_locale(); $products = !empty( $response[ $locale ][ 'products' ] ) ? $response[ $locale ][ 'products' ] : ( !empty( $response[ 'en_US' ][ 'products' ] ) ? $response[ 'en_US' ][ 'products' ] : false ); if( empty( $products ) || !is_array( $products ) ) { return $more_products; } foreach( $products as $product ) { $product = wp_parse_args( $product, array( 'name' => '', 'description' => '', 'icon' => '', 'url' => '', 'type' => 'plugin', 'product_id' => '', 'referrer' => false, 'requires' => false, 'tested' => false, 'order' => 10, ) ); if( !empty( $product[ 'referrer' ] ) ) { $product[ 'referrer' ] = !is_array( $product[ 'referrer' ] ) ? explode( ',', $product[ 'referrer' ] ) : $product[ 'referrer' ]; if( in_array( $this->slug, $product[ 'referrer' ] ) ) { $more_products[] = $product; } } } //** Sort the list */ usort($more_products, function( $a,$b ) { if ( $a['order'] == $b['order'] ) { return 0; } return ( $a['order'] < $b['order'] ) ? -1 : 1; }); //** Set transient for one day */ set_transient( $this->token . "-more", $more_products, (60 * 60 * 24) ); } } } else { $more_products = $trnst; } //** Determine if plugin from the list is already installed and activated */ //** There is not check condition for 'theme' */ if( !empty( $more_products ) ) { $reference_list = $this->get_product_reference_list(); foreach( $more_products as $k => $product ) { if( $this->slug == $product[ 'product_id' ] ) { unset( $more_products[ $k ] ); continue; } if( !empty( $reference_list ) && is_array( $reference_list ) ) { foreach( $reference_list as $reference ) { if( $reference[ 'product_id' ] == $product[ 'product_id' ] ) { unset( $more_products[ $k ] ); } } } } } //echo "
      "; print_r( $more_products ); echo "
      "; die(); return $more_products; } /** * Get a list of products from UsabilityDynamics. * * @access public * @since 1.0.0 * @return void */ protected function get_product_reference_list () { global $_ud_license_updater; //echo "
      "; print_r( $_ud_license_updater ); echo "
      "; die(); $response = array(); if( isset( $_ud_license_updater[ $this->slug ] ) && is_callable( array( $_ud_license_updater[ $this->slug ], 'get_products' ) ) ) { $response = $_ud_license_updater[ $this->slug ]->get_products(); } return $response; } /** * Get an array of products that haven't yet been activated. * * @access public * @since 1.0.0 * @return array Products awaiting activation. */ protected function get_pending_products () { $response = array(); $products = $this->installed_products; if ( is_array( $products ) && ( 0 < count( $products ) ) ) { $activated_products = $this->get_activated_products(); if ( is_array( $activated_products ) && ( 0 <= count( $activated_products ) ) ) { foreach ( $products as $k => $v ) { if ( !in_array( $k, array_keys( $activated_products ) ) ) { $response[$k] = array( 'product_name' => $v['product_name'] ); } } } } //echo "
      "; print_r( $response ); echo "
      "; die(); return $response; } /** * Determine, if there are licenses that are not yet activated. * @access public * @since 1.0.0 * @return void */ public function check_activation_status () { $licenses_link = get_option( $this->token . '-url', '' ); //echo "
      "; print_r( $this ); echo "
      "; die(); $products = $this->get_detected_products(); //echo "
      "; print_r( $products ); echo "
      "; die(); $messages = array(); if ( 0 < count( $products ) ) { foreach ( $products as $k => $v ) { if ( isset( $v['product_status'] ) && 'inactive' == $v['product_status'] ) { if( !empty( $licenses_link ) ) { $message = sprintf( __( '%s License is not active. To get started, activate it here.', $this->domain ), $v['product_name'], $licenses_link ); } else { $message = sprintf( __( '%s License is not active.', $this->domain ), $v['product_name'] ); } if( !empty( $v[ 'errors_callback' ] ) && is_callable( $v[ 'errors_callback' ] ) ) { call_user_func_array( $v[ 'errors_callback' ], array( $message, 'warning' ) ); } else { $messages[] = $message; } } } } if( !empty( $messages ) ) { $this->messages = $messages; } /** * We also ping UD server once per 24h * for getting any specific information. */ $this->maybe_ping_ud(); } /** * Remove specific plugins notices from licenses page * * @param $notices * @author peshkov@UD */ public function maybe_remove_notices( $notices ) { global $current_screen; if( $current_screen->id == $this->hook ) { $notices = array(); } return $notices; } /** * Admin notices */ public function admin_notices() { //** Step 1. Look for default messages */ $messages = $this->messages; if( !empty( $messages ) && is_array( $messages ) ) { foreach( $messages as $message ) { echo '

      ' . $message . '

      '; } } //** Step 2. Look for status messages */ $message = ''; $response = ''; if ( isset( $_GET['status'] ) && in_array( $_GET['status'], array( 'true', 'false' ) ) && isset( $_GET['type'] ) ) { $classes = array( 'true' => 'updated', 'false' => 'error' ); $request_errors = $this->api->get_error_log(); //echo "
      "; var_dump( $request_errors ); echo "
      "; die(); switch ( $_GET['type'] ) { case 'no-license-keys': $message = __( 'No license keys were specified for activation.', $this->domain ); break; case 'deactivate-product': if ( 'true' == $_GET['status'] && empty( $request_errors ) ) { if( $this->type == 'theme' ) { $message = __( 'Theme deactivated successfully.', $this->domain ); } else { $message = __( 'Product deactivated successfully.', $this->domain ); } } else { $message = __( 'There was an error while deactivating the product.', $this->domain ); } break; default: if ( 'true' == $_GET['status'] && empty( $request_errors ) ) { if( $this->type == 'theme' ) { $message = __( 'Theme activated successfully.', $this->domain ); } else { $message = __( 'Products activated successfully.', $this->domain ); } } else { if( $this->type == 'theme' ) { $message = __( 'There was an error and theme was not activated.', $this->domain ); } else { $message = __( 'There was an error and not all products were activated.', $this->domain ); } } break; } $response = '
      ' . "\n"; $response .= wpautop( $message ); $response .= '
      ' . "\n"; // Cater for API request error logs. if ( is_array( $request_errors ) && ( 0 < count( $request_errors ) ) ) { $message = ''; foreach ( $request_errors as $k => $v ) { $message .= wpautop( $v ); } $response .= '
      ' . "\n"; $response .= make_clickable( $message ); $response .= '
      ' . "\n"; // Clear the error log. $this->api->clear_error_log(); } if ( '' != $response ) { echo $response; } } } /** * May be add additional information about available add-ons * for legacy users ( who purchased any deprecated premium feature ) * to Product's Upgrade Notice * * @param string $referrer * @param array $vars */ public function maybe_add_info_to_upgrade_notice( $referrer, $vars ) { if( $referrer->slug != $this->referrer_slug ) { return; } $transient = sanitize_key( 'ud_legacy_features_' . $this->slug ); $response = get_transient( $transient ); if ( false === $response || empty( $response ) ) { $detected_products = array(); foreach( $this->get_detected_plugins() as $product ) { $detected_products[ $product[ 'product_id' ] ] = array( 'version' => $product[ 'product_version' ], 'status' => $product[ 'product_status' ], 'product_id' => $product[ 'product_id' ], ); } $response = $this->api->upgrade_notice( apply_filters( 'ud:upgrade_notice:request:args', array( 'product_id' => $this->slug, 'version' => $this->args[ 'version' ], 'detected_products' => base64_encode( json_encode( $detected_products ) ), ), $this->slug ) ); if ( false !== $response && empty( $response[ 'error' ] ) ) { set_transient( $transient, json_encode($response), HOUR_IN_SECONDS ); } } else { $response = json_decode( $response, true ); } if ( false !== $response && empty( $response[ 'error' ] ) && !empty( $response[ 'message' ] ) ) { $message = @base64_decode( $response[ 'message' ] ); echo apply_filters( 'ud::upgrade_notice::response::admin_notice', $message, $this->slug, $response ); } } /** * Ping UD server once per 24h to get any specific information. * * Maybe render Admin Notice from UD server. * */ private function maybe_ping_ud() { /** * May be dismiss notice from UD server */ if( !empty( $_REQUEST[ 'dismiss_ud_notice' ] ) ) { $notices = get_option( 'dismissed_ud_notices' ); if( !is_array( $notices ) ) { $notices = array(); } array_push( $notices, $_REQUEST[ 'dismiss_ud_notice' ] ); $notices = array_unique( $notices ); update_option( 'dismissed_ud_notices', $notices ); if( !empty( $_SERVER[ 'HTTP_REFERER' ] ) ) { wp_redirect( $_SERVER[ 'HTTP_REFERER' ] ); } else { wp_redirect( admin_url( 'index.php' ) ); } exit; } $cache = true; $option = sanitize_key( 'ud_ping_' . sanitize_key( $this->slug ) ); $response = get_option( $option ); if ( false === $response || empty( $response ) || empty( $response[ 'time' ] ) || ( time() - $response[ 'time' ] ) >= DAY_IN_SECONDS ) { $cache = false; $detected_products = array(); foreach( $this->get_detected_plugins() as $product ) { $detected_products[ $product[ 'product_id' ] ] = array( 'version' => $product[ 'product_version' ], 'status' => $product[ 'product_status' ], 'product_id' => $product[ 'product_id' ], ); } $response = $this->api->ping( apply_filters('ud-api-client-ping-args', array( 'product_id' => $this->slug, 'version' => $this->args[ 'version' ], 'detected_products' => base64_encode( json_encode( $detected_products ) ), ), $this, $detected_products)); if ( false !== $response && empty( $response[ 'error' ] ) ) { update_option( 'ud_ping_' . sanitize_key( $this->slug ), array( 'time' => time(), 'data' => $response ) ); } } else { if( empty( $response[ 'data' ] ) ) { return; } $response = $response[ 'data' ]; } if ( false !== $response && empty( $response[ 'error' ] ) ) { /** * Here we can take care about response. * * @param string $this->slug ( product_id ) * @param array $response * @param bool $cache got from cache or not */ $this->ping_response = apply_filters( 'ud::ping::response', $response, $this->slug, $cache ); /** * Render Admin Notice from UD server. */ if( !empty( $this->ping_response[ 'message' ] ) ) { global $_ud_ping_notices; if( !isset( $_ud_ping_notices ) || !is_array( $_ud_ping_notices ) ) { $_ud_ping_notices = array(); } $notice = $this->ping_response[ 'message' ]; /** Determine if user has permissions to see plugin notices */ if ( ! function_exists( 'wp_get_current_user' ) ) { require_once( ABSPATH . 'wp-includes/pluggable.php' ); } if( !current_user_can( 'activate_plugins' ) ) { return; } /** Determine if notice dismissed */ $dismissed = get_option( 'dismissed_ud_notices' ); $dismissed = is_array( $dismissed ) ? $dismissed : array(); if( in_array( md5( $notice ), $dismissed ) ) { return; } if( in_array( $notice, $_ud_ping_notices ) ) { return; } array_push( $_ud_ping_notices, $this->ping_response[ 'message' ] ); if( !has_action( 'admin_notices', array( __CLASS__, 'ping_admin_notices' ) ) ) { add_action( 'admin_notices', array( __CLASS__, 'ping_admin_notices' ) ); add_filter( 'ud::ping::response::admin_notice::icon', array( $this, 'get_admin_notice_icon' ) ); } } } } public function get_admin_notice_icon() { return $this->assets_url . 'images/ud.png'; } /** * Render Notices from UD server * */ static public function ping_admin_notices() { global $_ud_ping_notices; if( !isset( $_ud_ping_notices ) || !is_array( $_ud_ping_notices ) ) { return; } foreach( array_unique( $_ud_ping_notices ) as $notice ) { $dismiss_url = admin_url( 'index.php' ) . '?dismiss_ud_notice=' . md5( $notice ); $notice = @base64_decode( $notice ); $notice = apply_filters( 'ud::ping::response::admin_notice', $notice ); if( !empty( $notice ) ) { $icon = apply_filters( 'ud::ping::response::admin_notice::icon', false ); require( dirname( dirname( __DIR__ ) ) . '/static/templates/admin-notice.php' ); } } } } } } ================================================ FILE: vendor/udx/lib-ud-api-client/lib/classes/class-api.php ================================================ api_url = isset( $args[ 'api_url' ] ) ? $args[ 'api_url' ] : false; $this->token = isset( $args[ 'token' ] ) ? $args[ 'token' ] : false; } /** * Activate Product */ public function activate( $args, $product = false, $error_log = true ) { $args[ 'request' ] = 'activation'; return $this->request( $args, $product, $error_log ); } /** * Deactivate Product */ public function deactivate( $args, $product = false, $error_log = true ) { $args[ 'request' ] = 'deactivation'; return $this->request( $args, $product, $error_log ); } /** * Checks if the software is activated or deactivated * @param array $args * @return array */ public function status( $args, $product = false, $error_log = false ) { $args[ 'request' ] = 'status'; return $this->request( $args, $product, $error_log ); } /** * Pings remote server to maybe get specific information * @param array $args * @param bool $error_log * @return array */ public function ping( $args = array(), $error_log = false ) { $args[ 'request' ] = 'ping'; return $this->request( $args, array(), $error_log ); } /** * May be add information to upgrade notice * e.g., about available add-ons * if user purchased legacy premium features * COMPATIBILITY WITH OLD PRODUCTS * * @param array $args * @param bool $error_log * @return array */ public function upgrade_notice( $args = array(), $error_log = false ) { $args[ 'request' ] = 'upgrade_notice'; /* DEPRECATED API KEY FOR OLD PLUGINS COMPATIBILITY */ $args[ 'legacy_key' ] = get_option( 'ud_api_key', '' ); return $this->request( $args, array(), $error_log ); } /** * API Key URL */ protected function create_software_api_url( $args ) { $api_url = add_query_arg( 'wc-api', 'am-software-api', $this->api_url ); //return $api_url . '&' . http_build_query( $args ); $api_url .= '&'; foreach ($args AS $key=>$value) $api_url .= $key.'='.urlencode($value).'&'; $api_url = rtrim($api_url, '&'); return $api_url; } /** * * @author peshkov@UD */ protected function request( $args, $product, $error_log ) { $product = wp_parse_args( $product, array( 'product_name' => __( 'UsabilityDynamics Product', $this->domain ), ) ); $args = wp_parse_args( $args, array( 'request' => '', 'product_id' => '', 'instance' => '', //'email' => '', 'licence_key' => '', 'platform' => $this->blog, //** Add nocache hack. We must be sure we do not get CACHE result. peshkov@UD */ 'nocache' => rand( 10000, 99999 ), ) ); $target_url = $this->create_software_api_url( $args ); //echo "
      "; print_r( $target_url ); echo "
      "; //die(); $request = wp_remote_get( $target_url, array( 'timeout' => 15, 'sslverify' => false, 'headers' => array( 'x-ud-api-request' => $args[ 'request' ], 'x-ud-api-product-id' => $args[ 'product_id' ], 'x-ud-api-instance' => $args[ 'instance' ], 'x-ud-api-licence-key' => $args[ 'licence_key' ], 'x-ud-api-platform' => $args[ 'platform' ], ) ) ); //echo "
      "; print_r( $request ); echo "
      "; die(); if( is_wp_error( $request ) || wp_remote_retrieve_response_code( $request ) != 200 ) { if( $error_log ) $this->log_request_error( sprintf( __( 'There was an error making %s request for %s. Could not do request to UsabilityDynamics.', $this->domain ), $args[ 'request' ], $product[ 'product_name' ] ) ); } else { $response = wp_remote_retrieve_body( $request ); $response = @json_decode( $response, true ); //echo "
      "; print_r( $response ); echo "
      "; die(); if( empty( $response ) || !is_array( $response ) ) { if( $error_log ) $this->log_request_error( sprintf( __( 'There was an error making %s request for %s, please try again', $this->domain ), $args[ 'request' ], $product[ 'product_name' ] ) ); } elseif( !empty( $response[ 'error' ] ) ) { $error = !empty( $response[ 'additional info' ] ) ? $response[ 'additional info' ] : $response[ 'error' ]; if( $error_log ) $this->log_request_error( sprintf( __( 'There was an error making %s request for %s: %s' ), $args[ 'request' ], $product[ 'product_name' ], $error ) ); return $response; } else { return $response; } } return false; } /** * Log an error from an API request. * * @access private * @since 1.0.0 * @param string $error */ public function log_request_error ( $error ) { $this->errors[] = $error; } /** * Store logged errors in a temporary transient, such that they survive a page load. * @since 1.0.0 * @return void */ public function store_error_log () { set_transient( $this->token . '-request-error', $this->errors ); } /** * Get the current error log. * * @since 1.0.0 * @return void */ public function get_error_log () { return get_transient( $this->token . '-request-error' ); } /** * Clear the current error log. * * @since 1.0.0 * @return void */ public function clear_error_log () { return delete_transient( $this->token . '-request-error' ); } } } } ================================================ FILE: vendor/udx/lib-ud-api-client/lib/classes/class-bootstrap.php ================================================ type == 'theme' ) { $this->maybe_get_queued_theme_update(); } //** Get queued plugin updates. */ elseif ( $this->type == 'plugin' ) { add_action( 'plugins_loaded', array( $this, 'load_queued_updates' ), 10 ); } $_ud_license_updater = !is_array( $_ud_license_updater ) ? array() : $_ud_license_updater; $_ud_license_updater[ $this->slug ] = $this; //** Load the admin. */ if ( is_admin() ) { $this->admin = new Admin( $args ); } /** * HACK. * Filter the whitelist of hosts to redirect to. * It adds Admin URL ( in case it's different with home or site urls ) * to allowed list. * * @param array $hosts An array of allowed hosts. * @param bool|string $host The parsed host; empty if not isset. */ add_filter( 'allowed_redirect_hosts', function( $hosts, $host ) { if( !is_array( $hosts ) ) { $hosts = array(); } $schema = parse_url( admin_url() ); if( isset( $schema[ 'host' ] ) ) { array_push( $hosts, $schema[ 'host' ] ); $hosts = array_unique( $hosts ); } return $hosts; }, 99, 2 ); } /** * Add a product to await a license key for activation. * * Add a product into the array, to be processed with the other products. * * @since 1.0.0 * @param string $file The base file of the product to be activated. * @param string $instance_key The unique ID of the product to be activated. * @return void */ public function add_product ( $file, $instance_key, $product_id, $errors_callback ) { if ( $file != '' && !isset( $this->products[ $file ] ) ) { $this->products[ $file ] = array( 'instance_key' => $instance_key, 'product_id' => $product_id, 'errors_callback' => $errors_callback ); } } /** * Return an array of the available product keys. * @since 1.0.0 * @return array Product keys. */ public function get_products () { return (array) $this->products; } /** * Add 'Plugin' Product. * * @access public * @since 1.0.0 * @return void */ public function load_queued_updates() { global $_ud_queued_updates; //echo "
      "; print_r( $_ud_queued_updates ); echo "
      "; die(); if ( !empty( $_ud_queued_updates[ $this->slug ] ) && is_array( $_ud_queued_updates[ $this->slug ] ) ) { foreach ( $_ud_queued_updates[ $this->slug ] as $plugin ) { if ( is_object( $plugin ) && ! empty( $plugin->file ) && ! empty( $plugin->instance_key ) && ! empty( $plugin->product_id ) ) { $errors_callback = isset( $plugin->errors_callback ) ? $plugin->errors_callback : false; $this->add_product( $plugin->file, $plugin->instance_key, $plugin->product_id, $errors_callback ); } } } } /** * Add 'Theme' Product. * * @access public * @since 1.0.0 * @return void */ public function maybe_get_queued_theme_update() { global $_ud_queued_updates; //echo "
      "; print_r( $_ud_queued_updates[ '_theme_' ] ); echo "
      "; die(); if ( !empty( $_ud_queued_updates[ '_theme_' ] ) && is_object( $_ud_queued_updates[ '_theme_' ] ) ) { $theme = $_ud_queued_updates[ '_theme_' ]; if( ! empty( $theme->file ) && ! empty( $theme->instance_key ) && ! empty( $theme->product_id ) ) { $errors_callback = isset( $theme->errors_callback ) ? $theme->errors_callback : false; $this->add_product( $theme->file, $theme->instance_key, $theme->product_id, $errors_callback ); } } } } } } ================================================ FILE: vendor/udx/lib-ud-api-client/lib/classes/class-licenses-table.php ================================================ name = !empty( $args[ 'name' ] ) ? $args[ 'name' ] : ''; $this->domain = !empty( $args[ 'domain' ] ) ? $args[ 'domain' ] : false; $this->page = !empty( $args[ 'page' ] ) ? $args[ 'page' ] : false; $this->activation_email = isset( $args[ 'activation_email' ] ) && $args[ 'activation_email' ] ? true : false; $args = array( 'singular' => 'license', //singular name of the listed records 'plural' => 'licenses', //plural name of the listed records 'ajax' => false //does this table support ajax? ); $this->data = array(); //** Make sure this file is loaded, so we have access to plugins_api(), etc. */ require_once( ABSPATH . '/wp-admin/includes/plugin-install.php' ); parent::__construct( $args ); } /** * Text to display if no items are present. * * @since 1.0.0 * @return void */ public function no_items () { echo wpautop( sprintf( __( 'No active %s products found.', $this->domain ), $this->name ) ); } /** * The content of each column. * * @param array $item The current item in the list. * @param string $column_name The key of the current column. * @since 1.0.0 * @return string Output for the current column. */ public function column_default ( $item, $column_name ) { switch( $column_name ) { case 'product': case 'product_status': case 'product_version': return $item[$column_name]; break; } } /** * Retrieve an array of sortable columns. * @since 1.0.0 * @return array */ public function get_sortable_columns () { return array(); } /** * Retrieve an array of columns for the list table. * * @since 1.0.0 * @return array Key => Value pairs. */ public function get_columns () { $columns = array( 'product_name' => __( 'Product', $this->domain ), 'product_version' => __( 'Version', $this->domain ), 'product_status' => __( 'Activation Status', $this->domain ), ); return $columns; } /** * Content for the "product_name" column. * * @param array $item The current item. * @since 1.0.0 * @return string The content of this column. */ public function column_product_name ( $item ) { return wpautop( '' . $item['product_name'] . '' ); } /** * Content for the "product_version" column. * @param array $item The current item. * @since 1.0.0 * @return string The content of this column. */ public function column_product_version ( $item ) { return wpautop( $item['product_version'] ); } /** * Content for the "status" column. * * @param array $item The current item. * @since 1.0.0 * @return string The content of this column. */ public function column_product_status ( $item ) { $response = ''; if ( 'active' == $item['product_status'] ) { $deactivate_url = wp_nonce_url(Utility::current_url( array( 'action' => 'deactivate-product', 'filepath' => urlencode( $item['product_file_path'] ), ) ), 'bulk-licenses' ); //$deactivate_url = wp_nonce_url( add_query_arg( 'action', 'deactivate-product', add_query_arg( 'filepath', $item['product_file_path'], add_query_arg( 'page', $this->page, network_admin_url( 'index.php' ) ) ) ), 'bulk-licenses' ); $response = '' . __( 'Deactivate', $this->domain ) . '' . "\n"; } else { $response .= '
        ' . "\n"; $response .= '
      • ' . "\n"; if( !$this->activation_email ) { $response .= '
      ' . "\n"; $response .= '' . "\n"; } else { $response .= '
    • ' . "\n"; $response .= '' . "\n"; } } return $response; } /** * Retrieve an array of possible bulk actions. * * @since 1.0.0 * @return array */ public function get_bulk_actions () { $actions = array(); return $actions; } /** * Prepare an array of items to be listed. * @since 1.0.0 * @return array Prepared items. */ public function prepare_items () { $columns = $this->get_columns(); $hidden = array(); $sortable = $this->get_sortable_columns(); $this->_column_headers = array( $columns, $hidden, $sortable ); $total_items = count( $this->data ); //** only ncessary because we have sample data */ $this->found_data = $this->data; $this->set_pagination_args( array( 'total_items' => $total_items, //WE have to calculate the total number of items 'per_page' => $total_items //WE have to determine how many items to show on a page ) ); $this->items = $this->found_data; } } } } ================================================ FILE: vendor/udx/lib-ud-api-client/lib/classes/class-manager.php ================================================ type = !empty( $schema[ 'type' ] ) ? $schema[ 'type' ] : false; $this->product_id = !empty( $schema[ 'product_id' ] ) ? $schema[ 'product_id' ] : false; $this->referrer = !empty( $schema[ 'referrer' ] ) ? $schema[ 'referrer' ] : false; $this->name = !empty( $schema[ 'name' ] ) ? $schema[ 'name' ] : false; $this->boot_file = !empty( $schema[ 'boot_file' ] ) ? $schema[ 'boot_file' ] : false; $this->errors_callback = !empty( $schema[ 'errors_callback' ] ) ? $schema[ 'errors_callback' ] : false; $this->queue_updates(); } /** * Add product to global list of products. */ public function queue_updates() { global $_ud_queued_updates; if( !$this->product_id || !$this->boot_file || !$this->name ) { return false; } //** Get instance key. If it does not exist: generate it. */ $option_key = sanitize_key( $this->name ) . ':instance'; $this->instance_key = get_option( $option_key, false ); if( empty( $this->instance_key ) ) { $this->instance_key = $this->generate_password( 12, false ); update_option( $option_key, $this->instance_key ); } $product = new \stdClass(); $product->type = $this->type; $product->product_id = $this->product_id; $product->instance_key = $this->instance_key; $product->errors_callback = $this->errors_callback; $_ud_queued_updates = isset( $_ud_queued_updates ) ? $_ud_queued_updates : array(); //** Add theme */ if( $product->type === 'theme' ) { $product->file = $this->boot_file; //** Must be only one theme in the list! */ if( !empty( $_ud_queued_updates[ '_theme_' ] ) ) { //** WTF? How it could be? */ wp_die( 'Are you cheating?' ); } else { $_ud_queued_updates[ '_theme_' ] = $product; } } //** Add plugin */ elseif ( $product->type === 'plugin' ) { $product->file = plugin_basename( $this->boot_file ); if( !$this->referrer ) { //** WTF? How it could be? */ wp_die( 'Are you cheating?' ); } $referrer_key = strtolower( $this->referrer ); $referrer_key = preg_replace( '/[^a-z0-9_\-\/]/', '', $referrer_key ); $_ud_queued_updates[ $referrer_key ] = isset( $_ud_queued_updates[ $referrer_key ] ) ? $_ud_queued_updates[ $referrer_key ] : array(); $_ud_queued_updates[ $referrer_key ][] = $product; } return true; } /** * Creates a unique instance ID */ private function generate_password( $length = 12, $special_chars = true, $extra_special_chars = false ) { $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; if ( $special_chars ) { $chars .= '!@#$%^&*()'; } if ( $extra_special_chars ) { $chars .= '-_ []{}<>~`+=,.;:/?|'; } $password = ''; for ( $i = 0; $i < $length; $i++ ) { $password .= substr( $chars, $this->rand(0, strlen($chars) - 1), 1); } return $password; } /** * */ private function rand( $min = 0, $max = 0 ) { global $rnd_value; //** Reset $rnd_value after 14 uses */ //** 32(md5) + 40(sha1) + 40(sha1) / 8 = 14 random numbers from $rnd_value */ if ( strlen($rnd_value) < 8 ) { if ( defined( 'WP_SETUP_CONFIG' ) ) static $seed = ''; else $seed = get_transient('random_seed'); $rnd_value = md5( uniqid(microtime() . mt_rand(), true ) . $seed ); $rnd_value .= sha1($rnd_value); $rnd_value .= sha1($rnd_value . $seed); $seed = md5($seed . $rnd_value); if ( ! defined( 'WP_SETUP_CONFIG' ) ) set_transient('random_seed', $seed); } //** Take the first 8 digits for our value */ $value = substr($rnd_value, 0, 8); //** Strip the first eight, leaving the remainder for the next call to wp_rand(). */ $rnd_value = substr($rnd_value, 8); $value = abs(hexdec($value)); //** Some misconfigured 32bit environments (Entropy PHP, for example) truncate integers larger than PHP_INT_MAX to PHP_INT_MAX rather than overflowing them to floats. */ $max_random_number = 3000000000 === 2147483647 ? (float) "4294967295" : 4294967295; // 4294967295 = 0xffffffff //** Reduce the value to be within the min - max range */ if ( $max != 0 ) { $value = $min + ( $max - $min + 1 ) * $value / ( $max_random_number + 1 ); } return abs(intval($value)); } } } } ================================================ FILE: vendor/udx/lib-ud-api-client/lib/classes/class-more-products-table.php ================================================ name = !empty( $args[ 'name' ] ) ? $args[ 'name' ] : ''; $this->domain = !empty( $args[ 'domain' ] ) ? $args[ 'domain' ] : false; $this->page = !empty( $args[ 'page' ] ) ? $args[ 'page' ] : false; $args = array( 'singular' => 'product', //singular name of the listed records 'plural' => 'products', //plural name of the listed records 'ajax' => false //does this table support ajax? ); $this->data = array(); parent::__construct( $args ); } /** * Prepare an array of items to be listed. * @since 1.0.0 * @return array Prepared items. */ public function prepare_items () { $total_items = count( $this->data ); //** only necessary because we have sample data */ $this->set_pagination_args( array( 'total_items' => $total_items, //WE have to calculate the total number of items 'per_page' => $total_items //WE have to determine how many items to show on a page ) ); $this->items = $this->data; } public function no_items() { if ( isset( $this->error ) ) { $message = $this->error->get_error_message(); if($this->error->get_error_message() == 'User has blocked requests through HTTP.'){ $message .= '

      For more information please check ' . __( 'this documentation.' ) . '

      '; } $message .= '

      ' . __( 'Try again' ) . '

      '; } else { $message = sprintf( __( 'No More Available Products for %s', $this->domain ), $this->name ); } echo '
      ' . $message . '
      '; } public function get_columns() { return array(); } protected function truncate( $string, $length = 220, $append = "…" ) { $string = trim($string); if( strlen( $string ) > $length ) { $string = wordwrap($string, $length); $string = explode("\n", $string, 2); $string = $string[0] . $append; } return $string; } /** * Override the parent display() so we can provide a different container. */ public function display() { $singular = $this->_args['singular']; $data_attr = ''; if ( $singular ) { $data_attr = " data-wp-lists='list:$singular'"; } $this->display_tablenav( 'top' ); ?>
      > display_rows_or_placeholder(); ?>
      display_tablenav( 'bottom' ); } protected function get_table_classes() { return array( 'widefat', $this->_args['plural'] ); } public function display_rows() { foreach ( (array) $this->items as $product ) { $action_links = array(); if( !empty( $product['url'] ) ) { $action_links[] = '' . __( 'More Details' ) . ''; } ?>

      truncate( $product[ 'description' ] ); ?>

      ' ) ) { echo '' . __( 'Untested with your version of WordPress' ) . ''; } elseif ( ! empty( $product['requires'] ) && version_compare( substr( $GLOBALS['wp_version'], 0, strlen( $product['requires'] ) ), $product['requires'], '<' ) ) { echo '' . __( 'Incompatible with your version of WordPress' ) . ''; } else { echo '' . __( 'Compatible with your version of WordPress' ) . ''; } ?>
      type = isset( $args[ 'type' ] ) ? trim( $args[ 'type' ] ) : false; $this->activation_email = isset( $args[ 'activation_email' ] ) && $args[ 'activation_email' ] ? true : false; $this->name = isset( $args[ 'name' ] ) ? trim( $args[ 'name' ] ) : false; $this->slug = isset( $args[ 'slug' ] ) ? trim( $args[ 'slug' ] ) : sanitize_key( $this->name ); $this->referrer_slug = isset( $args[ 'referrer_slug' ] ) ? $args[ 'referrer_slug' ] : false; $this->domain = isset( $args[ 'domain' ] ) ? trim( $args[ 'domain' ] ) : false; /** * Some web hosts have security policies that block the : (colon) and // (slashes) in http://, * so only the host portion of the URL can be sent. For example the host portion might be * www.example.com or example.com. http://www.example.com includes the scheme http, * and the host www.example.com. * Sending only the host also eliminates issues when a client site changes from http to https, * but their activation still uses the original scheme. * To send only the host, use a line like the one below: */ $this->blog = str_ireplace( array( 'http://', 'https://' ), '', home_url() ); $this->args = $args; } /** * */ public function __get( $key ) { return isset( $this->_properties[ $key ] ) ? $this->_properties[ $key ] : NULL; } /** * */ public function __set( $key, $value ) { $this->_properties[ $key ] = $value; } } } } ================================================ FILE: vendor/udx/lib-ud-api-client/lib/classes/class-ui.php ================================================ token = isset( $args[ 'token' ] ) ? $args[ 'token' ] : array(); $this->available_screens = isset( $args[ 'screens' ] ) ? $args[ 'screens' ] : array(); } /** * Generate header HTML. * @access public * @since 1.0.0 * @return void */ public function get_header ( $token = 'ud-license-manager' ) { global $current_screen; do_action( 'ud_licenses_screen_before', $token ); $html = '
      ' . "\n"; $html .= '

      ' . get_admin_page_title() . '

      ' . "\n"; $html .= '' . "\n"; echo $html; do_action( 'ud_licenses_screen_header_before_content', $token ); } /** * Generate footer HTML. * @access public * @since 1.0.0 * @return void */ public function get_footer ( $token = 'ud-license-manager', $screen_icon = 'tools' ) { do_action( 'ud_licenses_screen_footer_after_content', $token, $screen_icon ); $html = '
      ' . "\n"; echo $html; do_action( 'ud_licenses_screen_after', $token, $screen_icon ); } /** * Generate navigation tabs HTML, based on a specific admin menu. * @access public * @since 1.0.0 * @return string/WP_Error */ public function get_navigation_tabs () { $html = ''; $screens = !empty( $this->available_screens ) && is_array( $this->available_screens ) ? $this->available_screens : array(); $licenses_url = get_option( $this->token . '-url', '' ); $current_tab = self::get_current_screen(); if ( 0 < count( $screens ) ) { foreach ( $screens as $k => $v ) { $class = 'nav-tab'; if ( $current_tab == $k ) { $class .= ' nav-tab-active'; } $url = add_query_arg( 'screen', $k, $licenses_url ); $html .= '' . esc_html( $v ) . ''; } } return $html; } /** * Return the token for the current screen. * @access public * @since 1.0.0 * @return string The token for the current screen. */ public function get_current_screen () { $screen = 'licenses'; // Default. if ( isset( $_GET['screen'] ) && '' != $_GET['screen'] ) $screen = esc_attr( $_GET['screen'] ); return $screen; } } } } ================================================ FILE: vendor/udx/lib-ud-api-client/lib/classes/class-update-checker.php ================================================ upgrade_url = isset( $args[ 'upgrade_url' ] ) ? $args[ 'upgrade_url' ] : false; $this->type = isset( $args[ 'type' ] ) ? $args[ 'type' ] : false; $this->name = isset( $args[ 'name' ] ) ? $args[ 'name' ] : false; $this->file = isset( $args[ 'file' ] ) ? $args[ 'file' ] : false; $this->product_id = isset( $args[ 'product_id' ] ) ? $args[ 'product_id' ] : false; $this->api_key = isset( $args[ 'api_key' ] ) ? $args[ 'api_key' ] : false; $this->activation_email = isset( $args[ 'activation_email' ] ) ? $args[ 'activation_email' ] : false; $this->renew_license_url = isset( $args[ 'renew_license_url' ] ) ? $args[ 'renew_license_url' ] : false; $this->instance = isset( $args[ 'instance' ] ) ? $args[ 'instance' ] : false; $this->software_version = isset( $args[ 'software_version' ] ) ? $args[ 'software_version' ] : false; $this->text_domain = isset( $args[ 'text_domain' ] ) ? $args[ 'text_domain' ] : false; $this->extra = isset( $args[ 'extra' ] ) ? $args[ 'extra' ] : false; $this->changelog = isset( $args[ 'changelog' ] ) ? $args[ 'changelog' ] : false; /** * Some web hosts have security policies that block the : (colon) and // (slashes) in http://, * so only the host portion of the URL can be sent. For example the host portion might be * www.example.com or example.com. http://www.example.com includes the scheme http, * and the host www.example.com. * Sending only the host also eliminates issues when a client site changes from http to https, * but their activation still uses the original scheme. * To send only the host, use a line like the one below: */ $this->blog = str_ireplace( array( 'http://', 'https://' ), '', home_url() ); $this->errors_callback = $errors_callback; /** * More info: * function set_site_transient moved from wp-includes/functions.php * to wp-includes/option.php in WordPress 3.4 * * set_site_transient() contains the pre_set_site_transient_{$transient} filter * {$transient} is either update_plugins or update_themes * * Transient data for plugins and themes exist in the Options table: * _site_transient_update_themes * _site_transient_update_plugins */ /** * Plugin Updates */ if( $this->type == 'plugin' ) { //** Check For Plugin Updates */ add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'update_check' ) ); //** Check For Plugin/Theme Information to display on the update details page */ add_filter( 'plugins_api', array( $this, 'request' ), 10, 3 ); } /** * Theme Updates */ elseif ( $this->type == 'theme' ) { add_filter( 'pre_set_site_transient_update_themes', array( $this, 'update_check' ) ); } add_action( 'wp_ajax_ud_api_dismiss', array( $this, 'dismiss_notices' ) ); } /** * Upgrade API URL * */ private function create_upgrade_api_url( $args ) { $upgrade_url = add_query_arg( 'wc-api', 'upgrade-api', $this->upgrade_url ); return $upgrade_url . '&' . http_build_query( $args ); } /** * Check for updates against the remote server. * * @access public * @since 1.0.0 * @param object $transient * @return object $transient */ public function update_check( $transient ) { //** Check if the transient contains the 'checked' information */ //** If no, just return its value without hacking it */ if ( empty( $transient->checked ) ) { return $transient; } $args = array( 'request' => 'pluginupdatecheck', 'plugin_name' => $this->name, //'version' => $transient->checked[$this->name], 'version' => $this->software_version, 'product_id' => $this->product_id, 'api_key' => $this->api_key, 'activation_email' => $this->activation_email, 'instance' => $this->instance, 'domain' => $this->blog, 'software_version' => $this->software_version, 'extra' => $this->extra, ); //** Check for a plugin update */ $response = $this->plugin_information( $args ); //** Displays an admin error message in the WordPress dashboard */ $this->check_response_for_errors( $response ); //** Set version variables */ if ( isset( $response ) && is_object( $response ) && $response !== false ) { //** New plugin version from the API */ $new_ver = (string)$response->new_version; //** Current installed plugin version */ $curr_ver = (string)$this->software_version; //$curr_ver = (string)$transient->checked[$this->name]; } //** If there is a new version, modify the transient to reflect an update is available */ if ( isset( $new_ver ) && isset( $curr_ver ) ) { if ( $response !== false && version_compare( $new_ver, $curr_ver, '>' ) ) { if( $this->type == 'plugin' ) { if( isset( $response->slug ) ) { $response->slug = sanitize_title( $response->slug ); } $transient->response[$this->file] = $response; } else { $theme = basename( dirname( $this->file ) ); $response = (array)$response; if( empty( $response[ 'url' ] ) ) { $response[ 'url' ] = !empty( $this->changelog ) ? $this->changelog : 'https://www.usabilitydynamics.com'; } $transient->response[$theme] = (array)$response; } } } //echo "
      "; print_r( $this ); echo "
      "; die(); //echo "
      "; print_r( $transient ); echo "
      "; die(); return $transient; } /** * Sends and receives data to and from the server API * * @access public * @since 1.0.0 * @return object $response */ public function plugin_information( $args ) { $target_url = $this->create_upgrade_api_url( $args ); //** Check licenses keys once per one hour! */ $response = get_transient( md5( $target_url ) ); if ( false === $response || empty( $response ) ) { //** Add nocache hack. We must be sure we do not get CACHE result. peshkov@UD */ $_target_url = $target_url . '&' . http_build_query( array( 'nocache' => rand( 10000, 99999 ) ) ); $request = wp_remote_get( $_target_url, array( 'decompress' => false, 'sslverify' => false ) ); if ( is_wp_error( $request ) || wp_remote_retrieve_response_code( $request ) != 200 ) { return false; } $response = unserialize( wp_remote_retrieve_body( $request ) ); if( is_object( $response ) ) { set_transient( md5( $target_url ), json_encode($response), HOUR_IN_SECONDS ); } } else { $r = json_decode( $response, true ); $response = new \stdClass(); foreach( $r as $k => $v ){ $response->{$k} = $v; } } //echo "
      "; print_r( $response ); echo "
      "; if ( is_object( $response ) ) { return $response; } else { return false; } } /** * Generic request helper. * * @access public * @since 1.0.0 * @param array $args * @return object $response or boolean false */ public function request( $false, $action, $args ) { //** Check if this plugins API is about this plugin */ if ( isset( $args->slug ) ) { //** Check if this plugins API is about this plugin */ if ( sanitize_key( $args->slug ) != sanitize_key( $this->name ) ) { return $false; } } else { return $false; } $args = array( 'request' => 'plugininformation', 'plugin_name' => $this->name, //'version' => $version->checked[$this->name], 'version' => $this->software_version, 'product_id' => $this->product_id, 'api_key' => $this->api_key, 'activation_email' => $this->activation_email, 'instance' => $this->instance, 'domain' => $this->blog, 'software_version' => $this->software_version, 'extra' => $this->extra, ); $response = $this->plugin_information( $args ); //** If everything is okay return the $response */ if ( isset( $response ) && is_object( $response ) && $response !== false ) { return $response; } } /** * Displays an admin error message in the WordPress dashboard * @param array $response * @return string */ public function check_response_for_errors( $response ) { $this->errors = array(); if ( ! empty( $response ) ) { $plugins = get_plugins(); $name = isset( $plugins[$this->name] ) ? $plugins[$this->name]['Name'] : $this->name; $nonce = wp_create_nonce( 'ud_api_dismiss' ); if ( isset( $response->errors['no_key'] ) && $response->errors['no_key'] == 'no_key' && isset( $response->errors['no_subscription'] ) && $response->errors['no_subscription'] == 'no_subscription' ) { $no_key_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_no_key', '' ); $show_no_key_error = $this->check_dismiss_time( $no_key_dismissed ); if( $show_no_key_error ) { $this->errors[] = sprintf( __( 'A license key for %s could not be found. Maybe you forgot to enter a license key when setting up %s, or the key was deactivated in your account. You can reactivate or purchase a license key from your account Licences | dismiss.', $this->text_domain ), $name, $name, $this->renew_license_url, sanitize_key( $name ), $nonce ); } $no_subscription_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_no_subscription', '' ); $show_no_subscription_error = $this->check_dismiss_time( $no_subscription_dismissed ); if( $show_no_subscription_error ) { $this->errors[] = sprintf( __( 'A subscription for %s could not be found. You can purchase a subscription from your account dashboard | dismiss.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ), $nonce ); } } else if ( isset( $response->errors['exp_license'] ) && $response->errors['exp_license'] == 'exp_license' ) { $exp_license_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_exp_license', '' ); $show_exp_license_error = $this->check_dismiss_time( $exp_license_dismissed ); if( $show_exp_license_error ) { $this->errors[] = sprintf( __( 'The license key for %s has expired. You can reactivate or get a license key from your account dashboard | dismiss.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ), $nonce ); } } else if ( isset( $response->errors['hold_subscription'] ) && $response->errors['hold_subscription'] == 'hold_subscription' ) { $hold_subscription_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_hold_subscription', '' ); $show_hold_subscription_error = $this->check_dismiss_time( $hold_subscription_dismissed ); if( $show_hold_subscription_error ) { $this->errors[] = sprintf( __( 'The subscription for %s is on-hold. You can reactivate the subscription from your account dashboard | dismiss.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ), $nonce ); } } else if ( isset( $response->errors['cancelled_subscription'] ) && $response->errors['cancelled_subscription'] == 'cancelled_subscription' ) { $cancelled_subscription_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_cancelled_subscription', '' ); $show_cancelled_subscription_error = $this->check_dismiss_time( $cancelled_subscription_dismissed ); if( $show_cancelled_subscription_error ) { $this->errors[] = sprintf( __( 'The subscription for %s has been cancelled. You can renew the subscription from your account dashboard. A new license key will be emailed to you after your order has been completed. dismiss.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ), $nonce ); } } else if ( isset( $response->errors['exp_subscription'] ) && $response->errors['exp_subscription'] == 'exp_subscription' ) { $exp_subscription_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_exp_subscription', '' ); $show_exp_subscription_error = $this->check_dismiss_time( $exp_subscription_dismissed ); if( $show_exp_subscription_error ) { $this->errors[] = sprintf( __( 'The subscription for %s has expired. You can reactivate the subscription from your account dashboard | dismiss.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ), $nonce ) ; } } else if ( isset( $response->errors['suspended_subscription'] ) && $response->errors['suspended_subscription'] == 'suspended_subscription' ) { $suspended_subscription_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_suspended_subscription', '' ); $show_suspended_subscription_error = $this->check_dismiss_time( $suspended_subscription_dismissed ); if( $show_suspended_subscription_error ) { $this->errors[] = sprintf( __( 'The subscription for %s has been suspended. You can reactivate the subscription from your account dashboard | dismiss.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ), $nonce ) ; } } else if ( isset( $response->errors['pending_subscription'] ) && $response->errors['pending_subscription'] == 'pending_subscription' ) { $pending_subscription_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_pending_subscription', '' ); $show_pending_subscription_error = $this->check_dismiss_time( $pending_subscription_dismissed ); if( $show_pending_subscription_error ) { $this->errors[] = sprintf( __( 'The subscription for %s is still pending. You can check on the status of the subscription from your account dashboard | dismiss.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ), $nonce ) ; } } else if ( isset( $response->errors['trash_subscription'] ) && $response->errors['trash_subscription'] == 'trash_subscription' ) { $trash_subscription_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_trash_subscription', '' ); $show_trash_subscription_error = $this->check_dismiss_time( $trash_subscription_dismissed ); if( $show_trash_subscription_error ) { $this->errors[] = sprintf( __( 'The subscription for %s has been placed in the trash and will be deleted soon. You can get a new subscription from your account dashboard | dismiss.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ), $nonce ) ; } } else if ( isset( $response->errors['no_subscription'] ) && $response->errors['no_subscription'] == 'no_subscription' ) { $no_subscription_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_no_subscription', '' ); $show_no_subscription_error = $this->check_dismiss_time( $no_subscription_dismissed ); if( $show_no_subscription_error ) { $this->errors[] = sprintf( __( 'A subscription for %s could not be found. You can get a subscription from your account dashboard | dismiss.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ), $nonce ); } } else if ( isset( $response->errors['no_activation'] ) && $response->errors['no_activation'] == 'no_activation' ) { $no_activation_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_no_activation', '' ); $show_no_activation_error = $this->check_dismiss_time( $no_activation_dismissed ); if( $show_no_activation_error ) { $this->errors[] = sprintf( __( '%s has not been activated. Go to the settings page and enter the license key and license email to activate %s. dismiss.', $this->text_domain ), $name, $name, sanitize_key( $name ), $nonce ) ; } } else if ( isset( $response->errors['no_key'] ) && $response->errors['no_key'] == 'no_key' ) { $no_key_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_no_key', '' ); $show_no_key_error = $this->check_dismiss_time( $no_key_dismissed ); if( $show_no_key_error ) { $this->errors[] = sprintf( __( 'A license key for %s could not be found. Maybe you forgot to enter a license key when setting up %s, or the key was deactivated in your account. You can reactivate or get a license key from your account Licences | dismiss.', $this->text_domain ), $name, $name, $this->renew_license_url, sanitize_key( $name ), $nonce ); } } else if ( isset( $response->errors['download_revoked'] ) && $response->errors['download_revoked'] == 'download_revoked' ) { $download_revoked_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_download_revoked', '' ); $show_download_revoked_error = $this->check_dismiss_time( $download_revoked_dismissed ); if( $show_download_revoked_error ) { $this->errors[] = sprintf( __( 'Download permission for %s has been revoked possibly due to a license key or subscription expiring. You can reactivate or get a license key from your account dashboard | dismiss.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ), $nonce ) ; } } else if ( isset( $response->errors['switched_subscription'] ) && $response->errors['switched_subscription'] == 'switched_subscription' ) { $switched_subscription_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_switched_subscription', '' ); $show_switched_subscription_error = $this->check_dismiss_time( $switched_subscription_dismissed ); if( $show_switched_subscription_error ) { $this->errors[] = sprintf( __( 'You changed the subscription for %s, so you will need to enter your new API License Key in the settings page. The License Key should have arrived in your email inbox, if not you can get it by logging into your account dashboard | dismiss.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ), $nonce ) ; } } } if( !empty( $this->errors ) ) { add_action('admin_notices', array( $this, 'print_errors') ); } } /** * Maybe print admin notices */ public function print_errors() { if( !empty( $this->errors ) && is_array( $this->errors ) ) { foreach( $this->errors as $error ) { echo '

      ' . $error . '

      '; } $this->print_scripts(); } } /** * print script for ajax */ public function print_scripts() { ob_start(); ?> (int)$time ) { return true; } return false; } /** * dismiss the notice ajax callback * @throws \Exception */ public function dismiss_notices(){ check_ajax_referer('ud_api_dismiss'); if ( !is_user_logged_in() ) { wp_send_json_error( array( 'error' => __( 'You are not allowed to do this action.', $this->text_domain ) ) ); } $response = array( 'success' => '0', 'error' => __( 'There was an error in request.', $this->text_domain ), ); $error = false; $option_key = isset($_POST['key']) ? sanitize_key($_POST['key']) : ''; if ( strpos($option_key, 'dismissed_') !== 0 ) { $response['error'] = __( 'Invalid key', $this->domain ); $error = true; } if ( !$error && update_option( $option_key, time() ) ) { $response['success'] = '1'; $response['error'] = null; } wp_send_json( $response ); } } } } ================================================ FILE: vendor/udx/lib-ud-api-client/lib/classes/class-utility.php ================================================ $v ) { if( is_string( $v ) ) $url = add_query_arg( $k, $v, $url ); } } if( !empty( $except_args ) ) { foreach( (array) $except_args as $arg ) { if( is_string( $arg ) ) $url = remove_query_arg( $arg, $url ); } } return $url; } } } } ================================================ FILE: vendor/udx/lib-ud-api-client/package.json ================================================ { "name": "lib-ud-api-client", "version": "1.2.5", "description": "UD Client for WooCommerce API Manager", "repository": { "type": "git", "url": "https://github.com/udx/lib-ud-api-client" }, "engines": { "node": ">= 0.10.0" }, "dependencies": { "load-grunt-tasks": "^0.6.0" }, "devDependencies": { "grunt": "^0.4.5", "grunt-contrib-clean": "~0.5.0", "grunt-contrib-concat": "~0.3.0", "grunt-contrib-less": "~0.8.3", "grunt-contrib-uglify": "~0.2.4", "grunt-contrib-watch": "~0.5.3", "grunt-contrib-yuidoc": "~0.5.0", "grunt-markdown": "~0.4.0", "grunt-shell": "~0.6.0", "grunt-phpunit": "~0.3.3" } } ================================================ FILE: vendor/udx/lib-ud-api-client/readme.md ================================================ ### UD API Client for WooCommerce API Manager [![Stories](https://badge.waffle.io/usabilitydynamics/lib-ud-api-client.png?label=ready&title=Ready)](https://waffle.io/usabilitydynamics/lib-ud-api-client) [![Dependency](https://gemnasium.com/UsabilityDynamics/lib-ud-api-client.svg)](https://gemnasium.com/UsabilityDynamics/lib-ud-api-client) [![Scrutinizer](http://img.shields.io/scrutinizer/g/UsabilityDynamics/lib-ud-api-client.svg)](httpshttps://scrutinizer-ci.com/g/UsabilityDynamics/lib-ud-api-client) [![Scrutinizer Coverage](http://img.shields.io/scrutinizer/coverage/g/UsabilityDynamics/lib-ud-api-client.svg)](https://scrutinizer-ci.com/g/UsabilityDynamics/lib-ud-api-client) ### API Every API request is being done only for every product separately. So, e.g., if user has installed and activated four products, it does four API requests to UD to determine current status for every product separately. #### Status Determines if product is activated on UD or not. In case product is not activated on UD it will be deactivated on client's site. Request is being called in the following cases: * on loading 'Installed Plugins' page once per 12 hours. * on loading 'Add-ons' ( licenses ) page every time. Note, 'Status' request on loading 'Add-ons' ( licenses ) page must be called every time to be synced with UD server since user can directly remove activated license on their account on UD site. ```php $api = new UsabilityDynamics\UD_API\API( $args ); $api->status( array( // Unique product ID. See composer.json extra:schemas:licenses:product:product_id 'product_id' => $product_id, // Unique hash, which generated at once on site and belongs to specific product. // In general instance used on UD to relate current license to specific domain. 'instance' => $instance, // Not used anymore. But can be included reverted to be used if needed. 'email' => $email, // Client's License key 'licence_key' => $license_key, ) ); ``` #### Activate Request is being called in the following case: - on product activating on 'Add-ons' ( licenses ) page. ```php $api = new UsabilityDynamics\UD_API\API( $args ); $api->activate( array( // Unique product ID. See composer.json extra:schemas:licenses:product:product_id 'product_id' => $product_id, // Unique hash, which generated at once on site and belongs to specific product. // In general instance used on UD to relate current license to specific domain. 'instance' => $instance, // Version of product 'software_version' => $product_version, // Client's License key 'licence_key' => $license_key, // Not used anymore. But can be included reverted to be used if needed. 'email' => $email, ), $product ); ``` #### Deactivate Request is being called in the following case: - on product deactivating on 'Add-ons' ( licenses ) page. ```php $api = new UsabilityDynamics\UD_API\API( $args ); $api->deactivate( array( // Unique product ID. See composer.json extra:schemas:licenses:product:product_id 'product_id' => $product_id, // Unique hash, which generated at once on site and belongs to specific product. // In general instance used on UD to relate current license to specific domain. 'instance' => $instance, // Client's License key 'licence_key' => $license_key, // Not used anymore. But can be included reverted to be used if needed. 'email' => $email, ), $product ); ``` #### Update Checker Update Checker is being initialized only for installed and activated plugins / theme. Responses are being cached via transient up to one hour. Attention, be sure, that temp download link expires more then in one hour ( UD generates temp link to Amazon for downloading the product ). ##### Plugin Adds the following filters ```php $update_checker = new UsabilityDynamics\UD_API\Update_Checker($args); //** Check For Plugin Updates */ add_filter( 'pre_set_site_transient_update_plugins', array( $update_checker, 'update_check' ) ); //** Check For Plugin Information to display on the update details page */ add_filter( 'plugins_api', array( $update_checker, 'request' ), 10, 3 ); ``` ##### Theme Adds the following filters ```php $update_checker = new UsabilityDynamics\UD_API\Update_Checker($args); //** Check For Plugin Updates */ add_filter( 'pre_set_site_transient_update_themes', array( $update_checker, 'update_check' ) ); ================================================ FILE: vendor/udx/lib-ud-api-client/static/css/admin.css ================================================ .ud-licenses-wrap div.updated, .ud-licenses-wrap div.error { margin-top: 1em; margin-bottom: 0; } .ud-licenses-wrap .licenses-notice { margin-top: 1em; margin-bottom: 0; background-color: #fff; border-left: 4px solid #7ad03a; box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1); padding: 1px 12px; } .ud-licenses-wrap .ninja { position: absolute; top: 0; right: 0; padding: 20px; width: 125px; background: #42a2ce; -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); } .ud-licenses-wrap .ninja img { width: 100%; height: auto; } .ud-licenses-wrap .feature-section ul { margin-bottom: 4em; padding-bottom: 1em; } .ud-licenses-wrap .feature-section li { margin-left: 1.2em; font-size: 13px; } .ud-licenses-wrap .feature-section img { width: 75px; height: 75px; float: right !important; margin-bottom: 1em; background: none; -webkit-box-shadow: none; -moz-box-shadow: none; box-shadow: none; border: 0; } .ud-licenses-wrap .panic-button-wrap { padding: 40px; width: 100% !important; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; background-color: #fff; overflow: hidden; zoom: 1; text-align: center; margin: 0 auto 20px; -webkit-border-radius: 4px; border-radius: 4px; } .ud-licenses-wrap .panic-button-wrap a { text-decoration: none; } .ud-licenses-wrap .panic-button-wrap em { display: block; font-style: normal; color: #666; } .ud-licenses-wrap .panic-button-wrap a { display: block; position: relative; outline: none; } .ud-licenses-wrap .panic-button-wrap a:before { content: ""; display: block; height: 6em; width: 6em; background: red; margin: 0 auto 1.618em; -webkit-border-radius: 100%; border-radius: 100%; background: #ff3019; background: -moz-linear-gradient(top, #ff3019 0%, #cf0404 100%); background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ff3019), color-stop(100%, #cf0404)); background: -webkit-linear-gradient(top, #ff3019 0%, #cf0404 100%); background: -o-linear-gradient(top, #ff3019 0%, #cf0404 100%); background: -ms-linear-gradient(top, #ff3019 0%, #cf0404 100%); background: linear-gradient(to bottom, #ff3019 0%, #cf0404 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3019', endColorstr='#cf0404', GradientType=0); border: 3px solid #b60404; -webkit-box-shadow: inset 0 1px 1px rgba(255, 255, 255, 0.3), 0 0 0 0.618em #eeeeee; box-shadow: inset 0 1px 1px rgba(255, 255, 255, 0.3), 0 0 0 0.618em #eeeeee; } .ud-licenses-wrap .panic-button-wrap a:hover:before { background: #ff4635; background: -moz-linear-gradient(top, #ff4635 0%, #ce2727 100%); background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ff4635), color-stop(100%, #ce2727)); background: -webkit-linear-gradient(top, #ff4635 0%, #ce2727 100%); background: -o-linear-gradient(top, #ff4635 0%, #ce2727 100%); background: -ms-linear-gradient(top, #ff4635 0%, #ce2727 100%); background: linear-gradient(to bottom, #ff4635 0%, #ce2727 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff4635', endColorstr='#ce2727', GradientType=0); } .ud-licenses-wrap .panic-button-wrap a:active:before { background: #cf0404; background: -moz-linear-gradient(top, #cf0404 0%, #ff3019 100%); background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #cf0404), color-stop(100%, #ff3019)); background: -webkit-linear-gradient(top, #cf0404 0%, #ff3019 100%); background: -o-linear-gradient(top, #cf0404 0%, #ff3019 100%); background: -ms-linear-gradient(top, #cf0404 0%, #ff3019 100%); background: linear-gradient(to bottom, #cf0404 0%, #ff3019 100%); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#cf0404', endColorstr='#ff3019', GradientType=0); } .ud-licenses-wrap .wp-list-table.products .plugin-icon img { width: 100%; } ================================================ FILE: vendor/udx/lib-ud-api-client/static/css/src/admin.less ================================================ .ud-licenses-wrap { div.updated, div.error { margin-top: 1em; margin-bottom: 0; } .licenses-notice { margin-top: 1em; margin-bottom: 0; background-color: #fff; border-left: 4px solid #7ad03a; box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.1); padding: 1px 12px; } .ninja { position: absolute; top:0; right:0; padding:20px; width:125px; background: #42a2ce; -webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.2); box-shadow: 0 1px 3px rgba(0,0,0,0.2); img { width:100%; height: auto; } } .feature-section { ul { margin-bottom:4em; padding-bottom:1em; } li { margin-left: 1.2em; font-size:13px; } img { width:75px; height: 75px; float: right !important; margin-bottom:1em; background: none; -webkit-box-shadow:none; -moz-box-shadow:none; box-shadow:none; border:0; } } .panic-button-wrap { padding: 40px; width:100% !important; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; background-color: #fff; overflow: hidden; zoom:1; text-align: center; margin:0 auto 20px; -webkit-border-radius:4px; border-radius:4px; a { text-decoration: none; } em { display: block; font-style: normal; color: #666; } a { display: block; position: relative; outline: none; &:before { content: ""; display:block; height:6em; width:6em; background: red; margin:0 auto 1.618em; -webkit-border-radius:100%; border-radius:100%; background: rgb(255,48,25); background: -moz-linear-gradient(top, rgba(255,48,25,1) 0%, rgba(207,4,4,1) 100%); background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,48,25,1)), color-stop(100%,rgba(207,4,4,1))); background: -webkit-linear-gradient(top, rgba(255,48,25,1) 0%,rgba(207,4,4,1) 100%); background: -o-linear-gradient(top, rgba(255,48,25,1) 0%,rgba(207,4,4,1) 100%); background: -ms-linear-gradient(top, rgba(255,48,25,1) 0%,rgba(207,4,4,1) 100%); background: linear-gradient(to bottom, rgba(255,48,25,1) 0%,rgba(207,4,4,1) 100%); filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ff3019', endColorstr='#cf0404',GradientType=0 ); border:3px solid darken(#cf0404,5%); -webkit-box-shadow: inset 0 1px 1px rgba(255,255,255,0.3), 0 0 0 .618em #eee; box-shadow: inset 0 1px 1px rgba(255,255,255,0.3), 0 0 0 .618em #eee; } &:hover { &:before { background: rgb(255,70,53); background: -moz-linear-gradient(top, rgba(255,70,53,1) 0%, rgba(206,39,39,1) 100%); background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,70,53,1)), color-stop(100%,rgba(206,39,39,1))); background: -webkit-linear-gradient(top, rgba(255,70,53,1) 0%,rgba(206,39,39,1) 100%); background: -o-linear-gradient(top, rgba(255,70,53,1) 0%,rgba(206,39,39,1) 100%); background: -ms-linear-gradient(top, rgba(255,70,53,1) 0%,rgba(206,39,39,1) 100%); background: linear-gradient(to bottom, rgba(255,70,53,1) 0%,rgba(206,39,39,1) 100%); filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ff4635', endColorstr='#ce2727',GradientType=0 ); } } &:active { &:before { background: rgb(207,4,4); background: -moz-linear-gradient(top, rgba(207,4,4,1) 0%, rgba(255,48,25,1) 100%); background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(207,4,4,1)), color-stop(100%,rgba(255,48,25,1))); background: -webkit-linear-gradient(top, rgba(207,4,4,1) 0%,rgba(255,48,25,1) 100%); background: -o-linear-gradient(top, rgba(207,4,4,1) 0%,rgba(255,48,25,1) 100%); background: -ms-linear-gradient(top, rgba(207,4,4,1) 0%,rgba(255,48,25,1) 100%); background: linear-gradient(to bottom, rgba(207,4,4,1) 0%,rgba(255,48,25,1) 100%); filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#cf0404', endColorstr='#ff3019',GradientType=0 ); } } } } .wp-list-table.products { .plugin-icon { img { width: 100%; } } } } ================================================ FILE: vendor/udx/lib-ud-api-client/static/templates/admin-notice.php ================================================
      Dismiss this notice' ), $dismiss_url ); ?>
      ================================================ FILE: vendor/udx/lib-ud-api-client/static/templates/screen-manage-plugin.php ================================================
      ' . wpautop( sprintf( __( 'See below for a list of %s Plugins active on %s. You can %s, as well as our %s on how this works. %s', $this->domain ), $this->name, get_bloginfo( 'name' ), 'view your licenses here', 'documentation', '  ' . __( 'Check for Updates', $this->domain ) . '' ) ) . '
      ' . "\n"; ?>
      "; print_r( $this ); echo ""; die(); $this->list_table = new UsabilityDynamics\UD_API\Licenses_Table( array( 'name' => $this->name, 'domain' => $this->domain, 'page' => $this->menu_slug, ) ); $this->list_table->data = $this->get_detected_products(); $this->list_table->prepare_items(); $this->list_table->display(); submit_button( __( 'Activate Products', $this->domain ), 'button-primary' ); ?>
      ================================================ FILE: vendor/udx/lib-ud-api-client/static/templates/screen-manage-theme.php ================================================
      ' . wpautop( sprintf( __( '%s theme requires activation. You can %s, as well as our %s on how this works. %s', $this->domain ), $this->name, 'view your licenses here', 'documentation', '  ' . __( 'Check for Updates', $this->domain ) . '' ) ) . '
      ' . "\n"; ?>
      "; print_r( $this->get_detected_products() ); echo ""; die(); $this->list_table = new UsabilityDynamics\UD_API\Licenses_Table( array( 'name' => $this->name, 'domain' => $this->domain, 'page' => $this->menu_slug, ) ); $this->list_table->data = $this->get_detected_products(); $this->list_table->prepare_items(); $this->list_table->display(); submit_button( __( 'Activate', $this->domain ), 'button-primary' ); ?>
      ================================================ FILE: vendor/udx/lib-ud-api-client/static/templates/screen-more.php ================================================
      list_table = new UsabilityDynamics\UD_API\More_Products_Table( array( 'name' => $this->name, 'domain' => $this->domain, 'page' => $this->menu_slug, ) ); if(is_wp_error($this->error)){ $this->list_table->error = $this->error; } $this->list_table->data = $this->more_products; $this->list_table->prepare_items(); $this->list_table->display(); ?>
      ================================================ FILE: vendor/udx/lib-wp-bootstrap/.gitignore ================================================ temp node_modules npm-debug.log .svn .idea .idea/workspace.xml .DS_Store .dynamic .Trashes *.sublime-project *.sublime-workspace ._* *.seed *.log *.csv *.dat *.out *.pid *.gz ================================================ FILE: vendor/udx/lib-wp-bootstrap/changes.md ================================================ ### 1.3.4 * Fix notice about translations loaded too soon ### 1.3.3 * Require user to be logged in while dismissing Admin Panel notices. ### 1.3.2 * Improve security while processing AJAX requests in Admin Panel. ### 1.3.1 * Remove dependency from `udx/lib-utility`. ### 1.2.2 * Fixed `path` utility function: detecting if dir belongs to plugins directory by `WP_PLUGIN_DIR`, but not only by deprecated `PLUGINDIR`. ================================================ FILE: vendor/udx/lib-wp-bootstrap/composer.json ================================================ { "name": "udx/lib-wp-bootstrap", "description": "Wordpress bootstrap library created by UsabilityDynamics", "homepage": "https://github.com/udx/lib-wp-bootstrap", "keywords": [ "wordpress" ], "minimum-stability": "dev", "license": "MIT", "require": { "php": ">=5.3" }, "autoload": { "classmap": [ "lib/classes" ] } } ================================================ FILE: vendor/udx/lib-wp-bootstrap/lib/classes/class-bootstrap-plugin.php ================================================ define_license_client(); //** Load text domain */ add_action( 'init', array( $this, 'load_textdomain' ), 1 ); //** May be initialize Licenses Manager. */ add_action( 'plugins_loaded', array( $this, 'define_license_manager' ), 1 ); //** Initialize plugin here. All plugin actions must be added on this step */ add_action( 'plugins_loaded', array( $this, 'pre_init' ), 100 ); //** TGM Plugin activation. */ add_action( 'plugins_loaded', array( $this, 'check_plugins_requirements' ), 10 ); $this->boot(); } /** * Determine if we have errors before plugin initialization! * * @since 1.0.3 */ public function pre_init() { //** Be sure we do not have errors. Do not initialize plugin if we have them. */ if( $this->has_errors() ) { return null; } $this->init(); } /** * Returns absolute DIR or URL path * * @since 1.0.2 * * @param $short_path * @param string $type * * @return bool|string */ public function path( $short_path, $type = 'url' ) { switch( $type ) { case 'url': return $this->root_url . ltrim( $short_path, '/\\' ); break; case 'dir': return $this->root_path . ltrim( $short_path, '/\\' ); break; } return false; } /** * Called in the end of constructor. * Redeclare the method in child class! * * @author peshkov@UD */ public function boot() {} /** * Load Text Domain * * @author peshkov@UD */ public function load_textdomain() { load_plugin_textdomain( $this->domain, false, dirname( plugin_basename( $this->boot_file ) ) . '/static/languages/' ); } /** * Determine if instance already exists and Return Instance * * Attention: The method MUST be called from plugin core file at first to set correct path to plugin! * * @author peshkov@UD */ public static function get_instance( $args = array() ) { $class = get_called_class(); //** We must be sure that final class contains static property $instance to prevent issues. */ if( !property_exists( $class, 'instance' ) ) { exit( "{$class} must have property \$instance" ); } $prop = new \ReflectionProperty( $class, 'instance' ); if( !$prop->isStatic() ) { exit( "Property \$instance must be static for {$class}" ); } if( null === $class::$instance ) { $dbt = debug_backtrace(); if( !empty( $dbt[0]['file'] ) && file_exists( $dbt[0]['file'] ) ) { $pd = get_file_data( $dbt[0]['file'], array( 'name' => 'Plugin Name', 'version' => 'Version', 'domain' => 'Text Domain', 'uservoice_url' => 'UserVoice', 'support_url' => 'Support', ), 'plugin' ); $args = array_merge( (array)$pd, (array)$args, array( 'root_path' => dirname( $dbt[0]['file'] ), 'root_url' => plugin_dir_url( $dbt[0]['file'] ), 'schema_path' => dirname( $dbt[0]['file'] ) . '/composer.json', 'boot_file' => $dbt[0]['file'], ) ); $class::$instance = new $class( $args ); //** Register activation hook */ register_activation_hook( $dbt[0]['file'], array( $class::$instance, '_activate' ) ); //** Register activation hook */ register_deactivation_hook( $dbt[0]['file'], array( $class::$instance, '_deactivate' ) ); } else { $class::$instance = new $class( $args ); } } return $class::$instance; } /** * Plugin Activation * Internal method. Use activate() instead */ public function _activate() { /* Delete 'Install/Upgrade' notice 'dismissed' information */ delete_option( sanitize_key( 'dismiss_' . $this->slug . '_' . str_replace( '.', '_', $this->args['version'] ) . '_notice' ) ); /* Delete 'Bootstrap' notice 'dismissed' information */ delete_option( 'dismissed_notice_' . sanitize_key( $this->name ) ); delete_option( 'dismissed_warning_' . sanitize_key( $this->name ) ); $this->activate(); } /** * Plugin Deactivation * Internal method. Use deactivate() instead */ public function _deactivate() { /* Delete 'Install/Upgrade' notice 'dismissed' information */ delete_option( sanitize_key( 'dismiss_' . $this->slug . '_' . str_replace( '.', '_', $this->args['version'] ) . '_notice' ) ); /* Delete 'Bootstrap' notice 'dismissed' information */ delete_option( 'dismissed_notice_' . sanitize_key( $this->name ) ); delete_option( 'dismissed_warning_' . sanitize_key( $this->name ) ); $this->deactivate(); } /** * Plugin Activation * Redeclare the method in child class! */ public function activate() {} /** * Plugin Deactivation * Redeclare the method in child class! */ public function deactivate() {} } } } ================================================ FILE: vendor/udx/lib-wp-bootstrap/lib/classes/class-bootstrap-theme.php ================================================ check_plugins_requirements(); //** May be initialize Licenses Manager. */ $this->define_license_manager(); //** Maybe define license client */ $this->define_license_client(); add_action( 'after_setup_theme', array( $this, 'pre_init' ), 100 ); $this->boot(); } /** * Determine if we have errors before plugin initialization! * * @since 1.0.6 */ public function pre_init() { //** Be sure we do not have errors. Do not initialize plugin if we have them. */ if( $this->has_errors() ) { if( !is_admin() ) { //** Show message about error on front end only if user administrator! */ if( current_user_can( 'manage_options' ) ) { _e( "Theme is activated with errors. Please, follow instructions on admin panel to solve the issue!", $this->domain ); } die(); } } else { $this->init(); } } /** * Called in the end of constructor. * Redeclare the method in child class! * * @author peshkov@UD */ public function boot() {} /** * Load Text Domain * * @author peshkov@UD */ public function load_textdomain() { load_theme_textdomain( $this->domain, get_template_directory() . '/static/languages/' ); } /** * Determine if instance already exists and Return Instance * * Attention: The method MUST be called from plugin core file at first to set correct path to plugin! * * @author peshkov@UD */ public static function get_instance( $args = array() ) { $class = get_called_class(); //** We must be sure that final class contains static property $instance to prevent issues. */ if( !property_exists( $class, 'instance' ) ) { exit( "{$class} must have property \$instance" ); } $prop = new \ReflectionProperty( $class, 'instance' ); if( !$prop->isStatic() ) { exit( "Property \$instance must be static for {$class}" ); } if( null === $class::$instance ) { //** Get custom ( undefined ) Headers from style.css */ global $wp_theme_directories; $stylesheet = get_stylesheet(); $theme_root = get_raw_theme_root($stylesheet); if (false === $theme_root) { $theme_root = WP_CONTENT_DIR . '/themes'; } elseif (!in_array($theme_root, (array)$wp_theme_directories)) { $theme_root = WP_CONTENT_DIR . $theme_root; } $data = get_file_data( $theme_root . '/' . get_stylesheet() . '/style.css', array( 'uservoice_url' => 'UserVoice', 'support_url' => 'Support', ) ); $t = wp_get_theme( get_template() ); $args = array_merge( (array)$args, $data, array( 'name' => $t->get( 'Name' ), 'version' => $t->get( 'Version' ), 'template' => $t->get( 'Template' ), 'domain' => $t->get( 'TextDomain' ), 'is_child' => is_child_theme(), 'root_path' => trailingslashit( wp_normalize_path( get_template_directory() ) ), 'root_url' => trailingslashit( wp_normalize_path( get_template_directory_uri() ) ), 'schema_path' => trailingslashit( wp_normalize_path( get_template_directory() ) ) . 'composer.json', 'boot_file' => trailingslashit( wp_normalize_path( get_template_directory() ) ) . 'style.css', ) ); //echo "
      "; print_r( $args ); echo "
      "; die(); $class::$instance = new $class( $args ); } return $class::$instance; } } } } ================================================ FILE: vendor/udx/lib-wp-bootstrap/lib/classes/class-bootstrap.php ================================================ errors = new Errors( array_merge( $args, array( 'type' => $this->type ) ) ); //** Determine if Composer autoloader is included and modules classes are up to date */ $this->composer_dependencies(); //** Determine if plugin/theme requires or recommends another plugin(s) */ $this->plugins_dependencies(); // Maybe run install or upgrade processes. $this->maybe_run_upgrade_process(); //** Set install/upgrade pages if needed */ $this->define_splash_pages(); //** Maybe need to show UD splash page. Used static functions intentionaly. */ if ( !has_action( 'admin_init', array( Dashboard::get_instance(), 'maybe_ud_splash_page' ) ) ) { add_action( 'admin_init', array( Dashboard::get_instance(), 'maybe_ud_splash_page' ) ); } if ( !has_action( 'admin_menu', array( Dashboard::get_instance(), 'add_ud_splash_page') ) ) { add_action( 'admin_menu', array( Dashboard::get_instance(), 'add_ud_splash_page') ); } add_action( 'wp_ajax_ud_bootstrap_dismiss_notice', array( $this, 'ud_bootstrap_dismiss_notice' ) ); } /** * Initialize application. * Redeclare the method in final class! * * @author peshkov@UD */ public function init() {} /** * Determine if errors exist * Just wrapper. */ public function has_errors() { return $this->errors->has_errors(); } /** * @param string $key * @param mixed $value * * @author peshkov@UD * @return \UsabilityDynamics\Settings */ public function set( $key = null, $value = null ) { if( !is_object( $this->settings ) || !is_callable( array( $this->settings, 'set' ) ) ) { return false; } return $this->settings->set( $key, $value ); } /** * @param string $key * @param mixed $default * * @author peshkov@UD * @return \UsabilityDynamics\type */ public function get( $key = null, $default = null ) { if( !is_object( $this->settings ) || !is_callable( array( $this->settings, 'get' ) ) ) { return $default; } return $this->settings->get( $key, $default ); } /** * Returns specific schema from composer.json file. * * @param string $file Path to file * @author peshkov@UD * @return mixed array or false */ public function get_schema( $key = '' ) { if( $this->schema === null ) { if( !empty( $this->schema_path ) && file_exists( $this->schema_path ) ) { $this->schema = (array)Utility::l10n_localize( json_decode( file_get_contents( $this->schema_path ), true ), (array)$this->get_localization() ); } } //** Break if composer.json does not exist */ if( !is_array( $this->schema ) ) { return false; } //** Resolve dot-notated key. */ if( strpos( $key, '.' ) ) { $current = $this->schema; $p = strtok( $key, '.' ); while( $p !== false ) { if( !isset( $current[ $p ] ) ) { return false; } $current = $current[ $p ]; $p = strtok( '.' ); } return $current; } //** Get default key */ else { return isset( $this->schema[ $key ] ) ? $this->schema[ $key ] : false; } } /** * Return localization's list. * * Example: * If schema contains l10n.{key} values: * * { 'config': 'l10n.hello_world' } * * the current function should return something below: * * return array( * 'hello_world' => __( 'Hello World', $this->domain ), * ); * * @author peshkov@UD * @return array */ public function get_localization() { return array(); } /** * Determine if product is just installed or upgraded * and run install/upgrade processes * * @author peshkov@UD */ protected function maybe_run_upgrade_process() { //** Determine what to show depending on version installed */ $version = get_option($this->slug . '-current-version', 0); $this->old_version = $version; //** Just installed */ if (!$version) { /* Run Install handlers */ add_action( 'plugins_loaded', array( $this, '_run_install_process' ), 0 ); } //** Upgraded */ elseif (version_compare($version, $this->args['version']) == -1) { /* Run Upgrade handlers */ add_action( 'plugins_loaded', array( $this, '_run_upgrade_process' ), 0 ); } // Need to save current version on plugins_loaded action, // unless _run_install_process and _run_upgrade_process not get called. add_action( 'plugins_loaded', array( $this, 'save_version_no' ), 100 ); } /** * Saving version no to database. * */ public function save_version_no($value=''){ update_option( $this->slug . '-current-version', $this->args['version'] ); } /** * Installation Handler * Internal method. Use run_install_process() instead */ public function _run_install_process() { /* Delete 'Install/Upgrade' notice 'dismissed' information */ delete_option( sanitize_key( 'dismiss_' . $this->slug . '_' . str_replace( '.', '_', $this->args['version'] ) . '_notice' ) ); /* Delete 'Bootstrap' notice 'dismissed' information */ delete_option( 'dismissed_notice_' . sanitize_key( $this->name ) ); $this->run_install_process(); } /** * Upgrade Handler * Internal method. Use run_upgrade_process() instead */ public function _run_upgrade_process() { /* Delete 'Install/Upgrade' notice 'dismissed' information */ delete_option( sanitize_key( 'dismiss_' . $this->slug . '_' . str_replace( '.', '_', $this->args['version'] ) . '_notice' ) ); /* Delete 'Bootstrap' notice 'dismissed' information */ delete_option( 'dismissed_notice_' . sanitize_key( $this->name ) ); $this->run_upgrade_process(); } /** * Run Install Process. * * Re-define the function in child. */ public function run_install_process() {} /** * Run Upgrade Process. * * Re-define the function in child. */ public function run_upgrade_process() {} /** * Define splash pages for plugins if needed * And Renders Admin Notice about installed product * * @return boolean * @author korotkov@UD * @author peshkov@UD */ public function define_splash_pages() { //** If not defined in schemas or not determined - skip */ if ( !$splashes = $this->get_schema( 'extra.splashes' ) ) { return false; } foreach( (array)$splashes as $splash => $shortpath ) { $path = $this->type == 'theme' ? get_template_directory() . '/' . ltrim( $shortpath, '/\\' ) : $this->path( $shortpath, 'dir' ); if( !file_exists( $path ) ) { unset( $splashes[ $splash ] ); } } //** If no splash templates files or missed 'install' splash - skip */ if( empty( $splashes ) || !isset( $splashes[ 'install' ] ) ) { return false; } $page = false; //** Determine what to show depending on version installed */ $version = get_option( $this->slug . '-splash-version', 0 ); //** Just installed */ if( !$version ) { $page = 'install'; } //** Upgraded */ elseif ( version_compare( $version, $this->args['version'] ) == -1 ) { if( isset( $splashes[ 'upgrade' ] ) ) { $page = 'upgrade'; } else { $page = 'install'; } } //** In other case do not do this */ else { /** * Maybe Render Install Notice * about current instance */ $option = sanitize_key( 'dismiss_' . $this->slug . '_' . str_replace( '.', '_', $this->args['version'] ) . '_notice' ); if( isset( $_REQUEST[ 'page' ] ) && $_REQUEST[ 'page' ] == Dashboard::get_instance()->page_slug && isset( $_REQUEST[ 'slug' ] ) && $_REQUEST[ 'slug' ] == $this->slug ) { /** Dismiss Admin Notice */ if( isset( $_REQUEST[ 'dismiss' ] ) ) { update_option( $option, array( 'slug' => $this->slug, 'type' => $this->type, 'version' => $this->args['version'] ) ); if( !function_exists( 'wp_redirect' ) ) { require_once( ABSPATH . 'wp-includes/pluggable.php' ); } if( !empty( $_SERVER[ 'HTTP_REFERER' ] ) ) { wp_redirect( $_SERVER[ 'HTTP_REFERER' ] ); } else { wp_redirect( admin_url( 'plugins.php' ) ); } exit; } /** Add information about product to Dashboard page */ else { if( isset( $splashes[ 'upgrade' ] ) ) { $page = 'upgrade'; } else { $page = 'install'; } } } if( !get_option( $option ) ) { add_action( 'admin_notices', array( $this, 'render_upgrade_notice' ), 1 ); } if( empty( $page ) ) { return false; } } $content = $this->root_path . ltrim( $splashes[$page], '/\\' ); //** Abort if no files exist */ if ( !file_exists( $content ) ) { return false; } //** Push data to temp transient */ $_current_pages_to_show = get_transient( Dashboard::get_instance()->transient_key ); //** If empty - create */ if ( !$_current_pages_to_show ) { set_transient( Dashboard::get_instance()->transient_key, array( $this->slug => array( 'name' => $this->name, 'content' => $content, 'version' => $this->args['version'] ) ), 30 ); } //** If not empty - update */ else { $_current_pages_to_show[$this->slug] = array( 'name' => $this->name, 'content' => $content, 'version' => $this->args['version'] ); set_transient( Dashboard::get_instance()->transient_key, $_current_pages_to_show, 30 ); } set_transient( Dashboard::get_instance()->need_splash_key, Dashboard::get_instance()->transient_key, 30 ); } /** * Renders Upgrade Notice. * */ public function render_upgrade_notice() { if( $this->type == 'theme' ) { if( !current_user_can( 'switch_themes' ) ) { return; } $icon = file_exists( get_template_directory() . '/static/images/icon.png' ) ? get_template_directory_uri() . '/static/images/icon.png' : false; } else { if( !current_user_can( 'activate_plugins' ) ) { return; } $icon = file_exists( $this->path( 'static/images/icon.png', 'dir' ) ) ? $this->path( 'static/images/icon.png', 'url' ) : false; } ob_start(); $vars = apply_filters( 'ud::bootstrap::upgrade_notice::vars', array( 'content' => false, 'icon' => $icon, 'name' => $this->name, 'type' => $this->type, 'slug' => $this->slug, 'version' => $this->args['version'], 'dashboard_link' => admin_url( 'index.php?page='. Dashboard::get_instance()->page_slug . '&slug=' . $this->slug ), 'dismiss_link' => admin_url( 'index.php?page='. Dashboard::get_instance()->page_slug . '&slug=' . $this->slug . '&dismiss=1' ), 'home_link' => !empty( $this->schema[ 'homepage' ] ) ? $this->schema[ 'homepage' ] : false, ) ); extract( $vars ); $content = ob_get_clean(); echo apply_filters( 'ud::bootstrap::upgrade_notice::template', $content, $this->slug, $vars ); } /** * Check plugins requirements * * @author peshkov@UD */ public function check_plugins_requirements() { //** Determine if we have TGMA Plugin Activation initialized. */ $is_tgma = $this->is_tgma; if( $is_tgma ) { $tgma = TGM_Plugin_Activation::get_instance(); //** Maybe get TGMPA notices. */ $notices = $tgma->notices( get_class( $this ) ); if( !empty( $notices[ 'messages' ] ) && is_array( $notices[ 'messages' ] ) ) { $error_links = false; $message_links = false; foreach( $notices[ 'messages' ] as $m ) { if( $m[ 'type' ] == 'error' ) $error_links = true; elseif( $m[ 'type' ] == 'message' ) $message_links = true; $this->errors->add( $m[ 'value' ], $m[ 'type' ] ); } //** Maybe add footer action links to errors and|or notices block. */ if( !empty( $notices[ 'links' ] ) && is_array( $notices[ 'links' ] ) ) { foreach( $notices[ 'links' ] as $type => $links ) { foreach( $links as $link ) { $this->errors->add_action_link( $link, $type ); } } } } } } /** * Maybe determines if Composer autoloader is included and modules classes are up to date * * @author peshkov@UD */ private function composer_dependencies() { $dependencies = $this->get_schema( 'extra.schemas.dependencies.modules' ); if( !empty( $dependencies ) && is_array( $dependencies ) ) { foreach( $dependencies as $module => $classes ) { if( !empty( $classes ) && is_array( $classes ) ) { foreach( $classes as $class => $v ) { if( !class_exists( $class ) ) { $this->errors->add( sprintf( __( 'Module %s is not installed or the version is old, class %s does not exist.', $this->domain ), $module, $class ) ); continue; } if ( '*' != trim( $v ) && ( !property_exists( $class, 'version' ) || $class::$version < $v ) ) { $this->errors->add( sprintf( __( 'Module %s should be updated to the latest version, class %s must have version %s or higher.', $this->domain ), $module, $class, $v ) ); } } } } } } /** * Determine if plugin/theme requires or recommends another plugin(s) * * @author peshkov@UD */ private function plugins_dependencies() { /** * Dependencies must be checked before plugins_loaded hook to prevent issues! * * The current condition fixes incorrect behaviour on custom 'Install Plugins' page * after activation plugin which has own dependencies. * * The condition belongs to WordPress 4.3 and higher. */ if( did_action( 'plugins_loaded' ) && $this->type == 'plugin' ) { return; } $plugins = $this->get_schema( 'extra.schemas.dependencies.plugins' ); if( !empty( $plugins ) && is_array( $plugins ) ) { $tgma = TGM_Plugin_Activation::get_instance(); foreach( $plugins as $plugin ) { $plugin[ '_referrer' ] = get_class( $this ); $plugin[ '_referrer_name' ] = $this->name; $tgma->register( $plugin ); } $this->is_tgma = true; } } /** * Defines License Client if 'licenses' schema is set * * @author peshkov@UD */ protected function define_license_client() { //** Break if we already have errors to prevent fatal ones. */ if( $this->has_errors() ) { return false; } //** Be sure we have licenses scheme to continue */ $schema = $this->get_schema( 'extra.schemas.licenses.client' ); if( !$schema ) { return false; } //** Licenses Manager */ if( !class_exists( '\UsabilityDynamics\UD_API\Bootstrap' ) ) { $this->errors->add( __( 'Class \UsabilityDynamics\UD_API\Bootstrap does not exist. Be sure all required plugins and (or) composer modules installed and activated.', $this->domain ) ); return false; } $args = $this->args; $args = array_merge( $args, array( 'type' => $this->type, 'name' => $this->name, 'slug' => $this->slug, 'referrer_slug' => $this->slug, 'domain' => $this->domain, 'errors_callback' => array( $this->errors, 'add' ), ), $schema ); if( empty( $args[ 'screen' ] ) ) { $this->errors->add( __( 'Licenses client can not be activated due to invalid \'licenses\' schema.', $this->domain ) ); } $this->client = new \UsabilityDynamics\UD_API\Bootstrap( $args ); } /** * Defines License Manager if 'license' schema is set * * @author peshkov@UD */ public function define_license_manager() { //** Break if we already have errors to prevent fatal ones. */ if( $this->has_errors() ) { return false; } //** Be sure we have license scheme to continue */ $schema = $this->get_schema( 'extra.schemas.licenses.product' ); if( !$schema ) { return false; } if( empty( $schema[ 'product_id' ] ) || ( empty( $schema[ 'referrer' ] ) && $this->type !== 'theme' ) ) { $this->errors->add( __( 'Product requires license, but product ID and (or) referrer is undefined. Please, be sure, that license schema has all required data.', $this->domain ), 'message' ); } $schema = array_merge( (array)$schema, array( 'type' => $this->type, 'name' => $this->name, 'boot_file' => $this->boot_file, 'errors_callback' => array( $this->errors, 'add' ) ) ); //** Licenses Manager */ if( !class_exists( '\UsabilityDynamics\UD_API\Manager' ) ) { //$this->errors->add( __( 'Class \UsabilityDynamics\UD_API\Manager does not exist. Be sure all required plugins installed and activated.', $this->domain ), 'message' ); return false; } $this->license_manager = new \UsabilityDynamics\UD_API\Manager( $schema ); return true; } public function ud_bootstrap_dismiss_notice() { $response = array( 'success' => '0', 'error' => __( 'There was an error in request.', $this->domain ), ); $error = false; if( empty( $_POST['key'] ) || empty( $_POST['slug'] ) || empty( $_POST['type'] ) || empty( $_POST['version'] ) ) { $response['error'] = __( 'Invalid values', $this->domain ); $error = true; } if ( ! $error && update_option( ( $_POST['key'] ), array( 'slug' => $_POST['slug'], 'type' => $_POST['type'], 'version' => $_POST['version'], ) ) ) { $response['success'] = '1'; } wp_send_json( $response ); } } } } ================================================ FILE: vendor/udx/lib-wp-bootstrap/lib/classes/class-dashboard.php ================================================ need_splash_key ) && ( !isset( $_REQUEST['page'] ) || $_REQUEST['page'] !== $this->page_slug ) ) { //** Do not redirect anymore */ delete_transient( $this->need_splash_key ); //** Redirect to UD splash page */ wp_redirect( admin_url( 'index.php?page='.$this->page_slug ) ); exit; } } /** * Register fake page * * @return null */ public function add_ud_splash_page() { if ( empty( $_GET['page'] ) ) { return; } if ( $_GET['page'] == $this->page_slug ) { add_dashboard_page( __( 'Welcome to Usability Dynamics, Inc.', $this->domain ), __( 'Welcome', $this->domain ), 'manage_options', $this->page_slug, array( $this, 'ud_splash_page' ) ); } } /** * Render UD dashboard page * * @author korotkov@ud */ public function ud_splash_page() { //** Try to get information to show */ $updates = get_transient( $this->transient_key ); ?>

      domain ) ?>

      domain ) ?>
      Keep it up! There are no notices for you in the moment.'; //** in other case - show corresponding predefined template if it exists*/ } else { foreach( $updates as $key => $page_data ) { update_option( $key . '-splash-version', $page_data['version'] ); if ( file_exists( $page_data['content'] ) ) { include $page_data['content']; } } } ?>
      need_splash_key ); } } } } ================================================ FILE: vendor/udx/lib-wp-bootstrap/lib/classes/class-errors.php ================================================ errors[] = $message; break; case 'message': $this->messages[] = $message; break; case 'warning': $this->warnings[] = $message; break; } } /** * Add footer link to specific ( errors|messages|wanrnings ) block * * @author peshkov@UD */ public function add_action_link( $link, $type = 'error' ) { switch( $type ) { case 'error': $this->action_links[ 'errors' ][] = $link; break; case 'message': $this->action_links[ 'messages' ][] = $link; break; case 'message': $this->action_links[ 'warnings' ][] = $link; break; } } /** * Determine if errors exist * * @author peshkov@UD */ public function has_errors() { return !empty( $this->errors ) ? true : false; } /** * Renders admin notes in case there are errors or notices on bootstrap init * * @author peshkov@UD */ public function admin_notices() { global $wp_version; //** Don't show the message if the user has no enough permissions. */ if ( ! function_exists( 'wp_get_current_user' ) ) { require_once( ABSPATH . 'wp-includes/pluggable.php' ); } if( empty( $this->args['type'] ) || ( $this->args['type'] == 'plugin' && !current_user_can( 'activate_plugins' ) ) || ( $this->args['type'] == 'theme' && !current_user_can( 'switch_themes' ) ) ) { return; } //** Don't show the message if on a multisite and the user isn't a super user. */ if ( is_multisite() && ! is_super_admin() ) { return; } //** Ignore messages on TGM Plugin Activation page */ if( TGM_Plugin_Activation::get_instance()->is_tgmpa_page() ) { return; } $errors = apply_filters( 'ud:errors:admin_notices', $this->errors, $this->args ); $messages = apply_filters( 'ud:messages:admin_notices', $this->messages, $this->args ); $warnings = apply_filters( 'ud:warnings:admin_notices', $this->warnings, $this->args ); $nonce = wp_create_nonce('ud_dismiss'); if( !empty( $errors ) || !empty( $messages ) || !empty( $warnings ) ) { echo ""; } //** Errors Block */ if( !empty( $errors ) && is_array( $errors ) ) { $message = '
      • ' . implode( '
      • ', $errors ) . '
      '; $message = sprintf( __( '

      %s is not active due to following errors:

      %s', $this->domain ), $this->name, $message ); if( !empty( $this->action_links[ 'errors' ] ) && is_array( $this->action_links[ 'errors' ] ) ) { $message .= '

      ' . implode( ' | ', $this->action_links[ 'errors' ] ) . '

      '; } echo '
      ' . $message . '
      '; } //** Determine if warning has been dismissed */ $warning_dismissed = get_option( ( 'dismissed_warning_' . sanitize_key( $this->name ) ) ); $show_warnings = $this->check_dismiss_time( $warning_dismissed ); if ( $show_warnings && ! empty( $warnings ) && is_array( $warnings ) ) { //** Warnings Block */ $message = '
      • ' . implode( '
      • ', $warnings ) . '
      '; $message = sprintf( __( '

      %s has the following warnings:

      %s', $this->domain ), $this->name, $message ); if( $this->dismiss ) { $this->action_links[ 'warnings' ][] = '' . __( 'Dismiss this warning', $this->domain ) . ''; } if( !empty( $this->action_links[ 'warnings' ] ) && is_array( $this->action_links[ 'warnings' ] ) ) { $message .= '

      ' . implode( ' | ', $this->action_links[ 'warnings' ] ) . '

      '; } echo '
      ' . $message . '
      '; } //** Determine if message has been dismissed */ $message_dismissed = get_option( ( 'dismissed_notice_' . sanitize_key( $this->name ) ) ); if ( empty( $message_dismissed ) ) { //** Notices Block */ if( !empty( $messages ) && is_array( $messages ) ) { $message = '
      • ' . implode( '
      • ', $messages ) . '
      '; if( !empty( $errors ) ) { $message = sprintf( __( '

      %s has the following additional notices:

      %s', $this->domain ), $this->name, $message ); } else { $message = sprintf( __( '

      %s is active, but has the following notices:

      %s', $this->domain ), $this->name, $message ); } if( $this->dismiss ) { $this->action_links[ 'messages' ][] = '' . __( 'Dismiss this notice', $this->domain ) . ''; } $message .= '

      ' . implode( ' | ', $this->action_links[ 'messages' ] ) . '

      '; echo '
      ' . $message . '
      '; } } if ( $show_warnings || empty( $message_dismissed ) ) { //enqueue dismiss js for ajax requests $script_path = Utility::path( 'static/scripts/ud-dismiss.js', 'url' ); wp_enqueue_script( "ud-dismiss", $script_path, array( 'jquery' ) ); wp_localize_script( "ud-dismiss", "_ud_vars", array( "ajaxurl" => admin_url( 'admin-ajax.php' ), ) ); } } /** * dismiss the notice ajax callback * @throws \Exception */ public function dismiss_notices() { check_ajax_referer('ud_dismiss'); if ( !is_user_logged_in() ) { wp_send_json_error( array( 'error' => __( 'You are not allowed to do this action.', $this->domain ) ) ); } $response = array( 'success' => '0', 'error' => __( 'There was an error in request.', $this->domain ), ); $error = false; $option_key = isset($_POST['key']) ? sanitize_key($_POST['key']) : ''; if ( strpos($option_key, 'dismissed_') !== 0 ) { $response['error'] = __( 'Invalid key', $this->domain ); $error = true; } if ( !$error && update_option( $option_key, time() ) ) { $response['success'] = '1'; $response['error'] = null; } wp_send_json( $response ); } /** * Check dismiss notice timestamp if greater than 24 hrs * * @param string $time * * @return bool */ public function check_dismiss_time( $time = '' ) { if( empty( $time ) ) { return true; } $current_time = time(); $diff = $current_time - 86400; if ( $diff > (int)$time ) { return true; } return false; } } } } ================================================ FILE: vendor/udx/lib-wp-bootstrap/lib/classes/class-scaffold.php ================================================ $v ) { if( property_exists( $this, $k ) ) { $prop = new \ReflectionProperty( $this, $k ); if( !$prop->isStatic() ) { switch( $k ) { case 'root_path': $this->root_path = trailingslashit( trim( $v ) ); break; case 'name': $this->slug = sanitize_key( trim( $v ) ); default: $this->{$k} = trim( $v ); break; } } else { $_args[ $k ] = $v; } } else { $_args[ $k ] = $v; } } $this->args = $_args; //** Debug data */ if( defined( 'WP_DEBUG' ) && WP_DEBUG === true ) { $trace = debug_backtrace(); $this->debug = array( /** Where from the current class is called */ 'backtrace_path' => $trace[0]['file'], ); } } /** * */ public function __get( $key ) { return isset( $this->_properties[ $key ] ) ? $this->_properties[ $key ] : NULL; } /** * */ public function __set( $key, $value ) { $this->_properties[ $key ] = $value; } } } } ================================================ FILE: vendor/udx/lib-wp-bootstrap/lib/classes/class-tgm-bulk-installer.php ================================================ * @author Gary Jones * @copyright Copyright (c) 2012, Thomas Griffin * @license http://opensource.org/licenses/gpl-2.0.php GPL v2 or later * @link https://github.com/thomasgriffin/TGM-Plugin-Activation */ /* Copyright 2014 Thomas Griffin (thomasgriffinmedia.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /** * The WP_Upgrader file isn't always available. If it isn't available, * we load it here. * * We check to make sure no action or activation keys are set so that WordPress * doesn't try to re-include the class when processing upgrades or installs outside * of the class. * * @since 2.2.0 */ namespace UsabilityDynamics\WP { if ( ! class_exists( 'WP_Upgrader' ) ) { require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; } if ( ! class_exists( 'UsabilityDynamics\WP\TGM_Bulk_Installer' ) ) { /** * Installer class to handle bulk plugin installations. * * Extends WP_Upgrader and customizes to suit the installation of multiple * plugins. * * @since 2.2.0 * * @package TGM-Plugin-Activation * @author Thomas Griffin * @author Gary Jones */ class TGM_Bulk_Installer extends \WP_Upgrader { /** * Holds result of bulk plugin installation. * * @since 2.2.0 * * @var string */ public $result; /** * Flag to check if bulk installation is occurring or not. * * @since 2.2.0 * * @var boolean */ public $bulk = false; /** * Processes the bulk installation of plugins. * * @since 2.2.0 * * @param array $packages The plugin sources needed for installation. * @return string|boolean Install confirmation messages on success, false on failure. */ public function bulk_install( $packages ) { // Pass installer skin object and set bulk property to true. $this->init(); $this->bulk = true; // Set install strings and automatic activation strings (if config option is set to true). $this->install_strings(); if ( TGM_Plugin_Activation::$instance->is_automatic ) { $this->activate_strings(); } // Run the header string to notify user that the process has begun. $this->skin->header(); // Connect to the Filesystem. $res = $this->fs_connect( array( WP_CONTENT_DIR, WP_PLUGIN_DIR ) ); if ( ! $res ) { $this->skin->footer(); return false; } // Set the bulk header and prepare results array. $this->skin->bulk_header(); $results = array(); // Get the total number of packages being processed and iterate as each package is successfully installed. $this->update_count = count( $packages ); $this->update_current = 0; // Loop through each plugin and process the installation. foreach ( $packages as $plugin ) { $this->update_current++; // Increment counter. // Do the plugin install. $result = $this->run( array( 'package' => $plugin, // The plugin source. 'destination' => WP_PLUGIN_DIR, // The destination dir. 'clear_destination' => false, // Do we want to clear the destination or not? 'clear_working' => true, // Remove original install file. 'is_multi' => true, // Are we processing multiple installs? 'hook_extra' => array( 'plugin' => $plugin, ), // Pass plugin source as extra data. ) ); // Store installation results in result property. $results[$plugin] = $this->result; // Prevent credentials auth screen from displaying multiple times. if ( false === $result ) { break; } } // Pass footer skin strings. $this->skin->bulk_footer(); $this->skin->footer(); // Return our results. return $results; } /** * Performs the actual installation of each plugin. * * This method also activates the plugin in the automatic flag has been * set to true for the TGMPA class. * * @since 2.2.0 * * @param array $options The installation cofig options * @return null/array Return early if error, array of installation data on success */ public function run( $options ) { // Default config options. $defaults = array( 'package' => '', 'destination' => '', 'clear_destination' => false, 'clear_working' => true, 'is_multi' => false, 'hook_extra' => array(), ); // Parse default options with config options from $this->bulk_upgrade and extract them. $options = wp_parse_args( $options, $defaults ); extract( $options ); // Connect to the Filesystem. $res = $this->fs_connect( array( WP_CONTENT_DIR, $destination ) ); if ( ! $res ) { return false; } // Return early if there is an error connecting to the Filesystem. if ( is_wp_error( $res ) ) { $this->skin->error( $res ); return $res; } // Call $this->header separately if running multiple times. if ( ! $is_multi ) $this->skin->header(); // Set strings before the package is installed. $this->skin->before(); // Download the package (this just returns the filename of the file if the package is a local file). $download = $this->download_package( $package ); if ( is_wp_error( $download ) ) { $this->skin->error( $download ); $this->skin->after(); return $download; } // Don't accidentally delete a local file. $delete_package = ( $download != $package ); // Unzip file into a temporary working directory. $working_dir = $this->unpack_package( $download, $delete_package ); if ( is_wp_error( $working_dir ) ) { $this->skin->error( $working_dir ); $this->skin->after(); return $working_dir; } // Install the package into the working directory with all passed config options. $result = $this->install_package( array( 'source' => $working_dir, 'destination' => $destination, 'clear_destination' => $clear_destination, 'clear_working' => $clear_working, 'hook_extra' => $hook_extra, ) ); // Pass the result of the installation. $this->skin->set_result( $result ); // Set correct strings based on results. if ( is_wp_error( $result ) ) { $this->skin->error( $result ); $this->skin->feedback( 'process_failed' ); } // The plugin install is successful. else { $this->skin->feedback( 'process_success' ); } // Only process the activation of installed plugins if the automatic flag is set to true. if ( TGM_Plugin_Activation::$instance->is_automatic ) { // Flush plugins cache so we can make sure that the installed plugins list is always up to date. wp_cache_flush(); // Get the installed plugin file and activate it. $plugin_info = $this->plugin_info( $package ); $activate = activate_plugin( $plugin_info ); // Re-populate the file path now that the plugin has been installed and activated. TGM_Plugin_Activation::$instance->populate_file_path(); // Set correct strings based on results. if ( is_wp_error( $activate ) ) { $this->skin->error( $activate ); $this->skin->feedback( 'activation_failed' ); } // The plugin activation is successful. else { $this->skin->feedback( 'activation_success' ); } } // Flush plugins cache so we can make sure that the installed plugins list is always up to date. wp_cache_flush(); // Set install footer strings. $this->skin->after(); if ( ! $is_multi ) { $this->skin->footer(); } return $result; } /** * Sets the correct install strings for the installer skin to use. * * @since 2.2.0 */ public function install_strings() { $this->strings['no_package'] = __( 'Install package not available.', 'tgmpa' ); $this->strings['downloading_package'] = __( 'Downloading install package from %s…', 'tgmpa' ); $this->strings['unpack_package'] = __( 'Unpacking the package…', 'tgmpa' ); $this->strings['installing_package'] = __( 'Installing the plugin…', 'tgmpa' ); $this->strings['process_failed'] = __( 'Plugin install failed.', 'tgmpa' ); $this->strings['process_success'] = __( 'Plugin installed successfully.', 'tgmpa' ); } /** * Sets the correct activation strings for the installer skin to use. * * @since 2.2.0 */ public function activate_strings() { $this->strings['activation_failed'] = __( 'Plugin activation failed.', 'tgmpa' ); $this->strings['activation_success'] = __( 'Plugin activated successfully.', 'tgmpa' ); } /** * Grabs the plugin file from an installed plugin. * * @since 2.2.0 * * @return string|boolean Return plugin file on success, false on failure */ public function plugin_info() { // Return false if installation result isn't an array or the destination name isn't set. if ( ! is_array( $this->result ) ) { return false; } if ( empty( $this->result['destination_name'] ) ) { return false; } /// Get the installed plugin file or return false if it isn't set. $plugin = get_plugins( '/' . $this->result['destination_name'] ); if ( empty( $plugin ) ) { return false; } // Assume the requested plugin is the first in the list. $pluginfiles = array_keys( $plugin ); return $this->result['destination_name'] . '/' . $pluginfiles[0]; } } } if ( ! class_exists( 'UsabilityDynamics\WP\TGM_Bulk_Installer_Skin' ) ) { /** * Installer skin to set strings for the bulk plugin installations.. * * Extends Bulk_Upgrader_Skin and customizes to suit the installation of multiple * plugins. * * @since 2.2.0 * * @package TGM-Plugin-Activation * @author Thomas Griffin * @author Gary Jones */ class TGM_Bulk_Installer_Skin extends \Bulk_Upgrader_Skin { /** * Holds plugin info for each individual plugin installation. * * @since 2.2.0 * * @var array */ public $plugin_info = array(); /** * Holds names of plugins that are undergoing bulk installations. * * @since 2.2.0 * * @var array */ public $plugin_names = array(); /** * Integer to use for iteration through each plugin installation. * * @since 2.2.0 * * @var integer */ public $i = 0; /** * Constructor. Parses default args with new ones and extracts them for use. * * @since 2.2.0 * * @param array $args Arguments to pass for use within the class. */ public function __construct( $args = array() ) { // Parse default and new args. $defaults = array( 'url' => '', 'nonce' => '', 'names' => array() ); $args = wp_parse_args( $args, $defaults ); // Set plugin names to $this->plugin_names property. $this->plugin_names = $args['names']; // Extract the new args. parent::__construct( $args ); } /** * Sets install skin strings for each individual plugin. * * Checks to see if the automatic activation flag is set and uses the * the proper strings accordingly. * * @since 2.2.0 */ public function add_strings() { // Automatic activation strings. if ( TGM_Plugin_Activation::$instance->is_automatic ) { $this->upgrader->strings['skin_upgrade_start'] = __( 'The installation and activation process is starting. This process may take a while on some hosts, so please be patient.', 'tgmpa' ); $this->upgrader->strings['skin_update_successful'] = __( '%1$s installed and activated successfully.', 'tgmpa' ) . ' ' . __( 'Show Details', 'tgmpa' ) . '.'; $this->upgrader->strings['skin_upgrade_end'] = __( 'All installations and activations have been completed.', 'tgmpa' ); $this->upgrader->strings['skin_before_update_header'] = __( 'Installing and Activating Plugin %1$s (%2$d/%3$d)', 'tgmpa' ); } // Default installation strings. else { $this->upgrader->strings['skin_upgrade_start'] = __( 'The installation process is starting. This process may take a while on some hosts, so please be patient.', 'tgmpa' ); $this->upgrader->strings['skin_update_failed_error'] = __( 'An error occurred while installing %1$s: %2$s.', 'tgmpa' ); $this->upgrader->strings['skin_update_failed'] = __( 'The installation of %1$s failed.', 'tgmpa' ); $this->upgrader->strings['skin_update_successful'] = __( '%1$s installed successfully.', 'tgmpa' ) . ' ' . __( 'Show Details', 'tgmpa' ) . '.'; $this->upgrader->strings['skin_upgrade_end'] = __( 'All installations have been completed.', 'tgmpa' ); $this->upgrader->strings['skin_before_update_header'] = __( 'Installing Plugin %1$s (%2$d/%3$d)', 'tgmpa' ); } } /** * Outputs the header strings and necessary JS before each plugin installation. * * @since 2.2.0 */ public function before( $title = '' ) { // We are currently in the plugin installation loop, so set to true. $this->in_loop = true; printf( '

      ' . $this->upgrader->strings['skin_before_update_header'] . '

      ', $this->plugin_names[$this->i], $this->upgrader->update_current, $this->upgrader->update_count ); echo ''; echo '

      '; // Flush header output buffer. $this->before_flush_output(); } /** * Outputs the footer strings and necessary JS after each plugin installation. * * Checks for any errors and outputs them if they exist, else output * success strings. * * @since 2.2.0 */ public function after( $title = '' ) { // Close install strings. echo '

      '; // Output error strings if an error has occurred. if ( $this->error || ! $this->result ) { if ( $this->error ) { echo '

      ' . sprintf( $this->upgrader->strings['skin_update_failed_error'], $this->plugin_names[$this->i], $this->error ) . '

      '; } else { echo '

      ' . sprintf( $this->upgrader->strings['skin_update_failed'], $this->plugin_names[$this->i] ) . '

      '; } echo ''; } // If the result is set and there are no errors, success! if ( ! empty( $this->result ) && ! is_wp_error( $this->result ) ) { echo '

      ' . sprintf( $this->upgrader->strings['skin_update_successful'], $this->plugin_names[$this->i], 'jQuery(\'#progress-' . esc_js( $this->upgrader->update_current ) . '\').toggle();jQuery(\'span\', this).toggle(); return false;' ) . '

      '; echo ''; } // Set in_loop and error to false and flush footer output buffer. $this->reset(); $this->after_flush_output(); } /** * Outputs links after bulk plugin installation is complete. * * @since 2.2.0 */ public function bulk_footer() { // Serve up the string to say installations (and possibly activations) are complete. parent::bulk_footer(); // Flush plugins cache so we can make sure that the installed plugins list is always up to date. wp_cache_flush(); // Display message based on if all plugins are now active or not. $complete = array(); foreach ( TGM_Plugin_Activation::$instance->plugins as $plugin ) { if ( ! is_plugin_active( $plugin['file_path'] ) ) { echo '

      ' . TGM_Plugin_Activation::$instance->strings['return'] . '

      '; $complete[] = $plugin; break; } // Nothing to store. else { $complete[] = ''; } } // Filter out any empty entries. $complete = array_filter( $complete ); // All plugins are active, so we display the complete string and hide the menu to protect users. if ( empty( $complete ) ) { echo '

      ' . sprintf( TGM_Plugin_Activation::$instance->strings['complete'], '' . __( 'Return to the Dashboard', 'tgmpa' ) . '' ) . '

      '; echo ''; } } /** * Flush header output buffer. * * @since 2.2.0 */ public function before_flush_output() { wp_ob_end_flush_all(); flush(); } /** * Flush footer output buffer and iterate $this->i to make sure the * installation strings reference the correct plugin. * * @since 2.2.0 */ public function after_flush_output() { wp_ob_end_flush_all(); flush(); $this->i++; } } } } ================================================ FILE: vendor/udx/lib-wp-bootstrap/lib/classes/class-tgm-list-table.php ================================================ * @author Gary Jones * @copyright Copyright (c) 2012, Thomas Griffin * @license http://opensource.org/licenses/gpl-2.0.php GPL v2 or later * @link https://github.com/thomasgriffin/TGM-Plugin-Activation */ /* Copyright 2014 Thomas Griffin (thomasgriffinmedia.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ namespace UsabilityDynamics\WP { /** * WP_List_Table isn't always available. If it isn't available, * we load it here. * * @since 2.2.0 */ if ( ! class_exists( 'WP_List_Table' ) ) { require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' ); } if ( ! class_exists( 'UsabilityDynamics\WP\TGMPA_List_Table' ) ) { /** * List table class for handling plugins. * * Extends the WP_List_Table class to provide a future-compatible * way of listing out all required/recommended plugins. * * Gives users an interface similar to the Plugin Administration * area with similar (albeit stripped down) capabilities. * * This class also allows for the bulk install of plugins. * * @since 2.2.0 * * @package TGM-Plugin-Activation * @author Thomas Griffin * @author Gary Jones */ class TGMPA_List_Table extends \WP_List_Table { /** * References parent constructor and sets defaults for class. * * The constructor also grabs a copy of $instance from the TGMPA class * and stores it in the global object TGM_Plugin_Activation::$instance. * * @since 2.2.0 * * @global unknown $status * @global string $page */ public function __construct() { global $status, $page; parent::__construct( array( 'singular' => 'plugin', 'plural' => 'plugins', 'ajax' => false, ) ); } /** * Gathers and renames all of our plugin information to be used by * WP_List_Table to create our table. * * @since 2.2.0 * * @return array $table_data Information for use in table. */ protected function _gather_plugin_data() { // Load thickbox for plugin links. TGM_Plugin_Activation::$instance->admin_init(); TGM_Plugin_Activation::$instance->thickbox(); // Prep variables for use and grab list of all installed plugins. $table_data = array(); $i = 0; $installed_plugins = get_plugins(); foreach ( TGM_Plugin_Activation::$instance->plugins as $plugin ) { if ( is_plugin_active( $plugin['file_path'] ) ) { continue; // No need to display plugins if they are installed and activated. } //echo "
      "; print_r( $plugin ); echo "
      "; //die(); $table_data[$i]['sanitized_plugin'] = $plugin['name']; $table_data[$i]['slug'] = $this->_get_plugin_data_from_name( $plugin['name'] ); $external_url = $this->_get_plugin_data_from_name( $plugin['name'], 'external_url' ); $source = $this->_get_plugin_data_from_name( $plugin['name'], 'source' ); if ( $external_url && preg_match( '|^http(s)?://|', $external_url ) ) { $table_data[$i]['plugin'] = '' . $plugin['name'] . ''; } elseif ( ! $source || preg_match( '|^http://wordpress.org/extend/plugins/|', $source ) ) { $url = esc_url( add_query_arg( array( 'tab' => 'plugin-information', 'plugin' => $this->_get_plugin_data_from_name( $plugin['name'] ), 'TB_iframe' => 'true', 'width' => '640', 'height' => '500', ), admin_url( 'plugin-install.php' ) ) ); $table_data[$i]['plugin'] = '' . $plugin['name'] . ''; } else { $table_data[$i]['plugin'] = '' . $plugin['name'] . ''; // No hyperlink. } if ( isset( $table_data[$i]['plugin'] ) && (array) $table_data[$i]['plugin'] ) { $plugin['name'] = $table_data[$i]['plugin']; } if ( ! empty( $plugin['source'] ) || ( isset( $plugin['private'] ) && $plugin['private'] == true ) ) { // The plugin must be from a private repository. if ( !empty( $plugin['source'] ) && preg_match( '|^http(s)?://|', $plugin['source'] ) ) { $table_data[$i]['source'] = __( 'Private Repository', 'tgmpa' ); // The plugin is pre-packaged with the theme. } elseif( isset( $plugin['private'] ) && $plugin['private'] == true ) { $_source = !empty( $plugin[ 'author' ] ) ? $plugin[ 'author' ] : __( 'Private Repository', 'tgmpa' ); $_url = !empty( $plugin[ 'author_url' ] ) ? $plugin[ 'author_url' ] : ( !empty( $plugin[ 'external_url' ] ) ? $plugin[ 'external_url' ] : false ); $_source = !empty( $_url ) ? "{$_source}" : $_source; $table_data[$i]['source'] = $_source; } else { $table_data[$i]['source'] = __( 'Pre-Packaged', 'tgmpa' ); } } // The plugin is from the WordPress repository. else { $table_data[$i]['source'] = __( 'WordPress Repository', 'tgmpa' ); } $table_data[$i]['source'] = "
      {$table_data[$i]['source']}
      "; $table_data[$i]['type'] = isset( $plugin['required'] ) && $plugin['required'] ? __( 'Required', 'tgmpa' ) : __( 'Recommended', 'tgmpa' ); if ( ! isset( $installed_plugins[$plugin['file_path']] ) ) { $table_data[$i]['status'] = sprintf( '%1$s', __( 'Not Installed', 'tgmpa' ) ); } elseif ( is_plugin_inactive( $plugin['file_path'] ) ) { $table_data[$i]['status'] = sprintf( '%1$s', __( 'Installed But Not Activated', 'tgmpa' ) ); } $table_data[$i]['file_path'] = $plugin['file_path']; $table_data[$i]['url'] = isset( $plugin['source'] ) ? $plugin['source'] : 'repo'; $i++; } // Sort plugins by Required/Recommended type and by alphabetical listing within each type. $resort = array(); $req = array(); $rec = array(); // Grab all the plugin types. foreach ( $table_data as $plugin ) { $resort[] = $plugin['type']; } // Sort each plugin by type. foreach ( $resort as $type ) { if ( 'Required' == $type ) { $req[] = $type; } else { $rec[] = $type; } } // Sort alphabetically each plugin type array, merge them and then sort in reverse (lists Required plugins first). sort( $req ); sort( $rec ); array_merge( $resort, $req, $rec ); array_multisort( $resort, SORT_DESC, $table_data ); return $table_data; } /** * Retrieve plugin data, given the plugin name. Taken from the * TGM_Plugin_Activation class. * * Loops through the registered plugins looking for $name. If it finds it, * it returns the $data from that plugin. Otherwise, returns false. * * @since 2.2.0 * * @param string $name Name of the plugin, as it was registered. * @param string $data Optional. Array key of plugin data to return. Default is slug. * @return string|boolean Plugin slug if found, false otherwise. */ protected function _get_plugin_data_from_name( $name, $data = 'slug' ) { foreach ( TGM_Plugin_Activation::$instance->plugins as $plugin => $values ) { if ( $name == $values['name'] && isset( $values[$data] ) ) { return $values[$data]; } } return false; } /** * Create default columns to display important plugin information * like type, action and status. * * @since 2.2.0 * * @param array $item Array of item data. * @param string $column_name The name of the column. */ public function column_default( $item, $column_name ) { switch ( $column_name ) { case 'source': case 'type': case 'status': return $item[$column_name]; } } /** * Create default title column along with action links of 'Install' * and 'Activate'. * * @since 2.2.0 * * @param array $item Array of item data. * @return string The action hover links. */ public function column_plugin( $item ) { //echo "
      "; print_r( $item ); echo "
      "; $installed_plugins = get_plugins(); $actions = array(); //** No need to display any hover links. */ if ( is_plugin_active( $item['file_path'] ) || !isset( TGM_Plugin_Activation::$instance->plugins[ $item[ 'slug' ] ] ) ) { return sprintf( '%1$s %2$s', $item['plugin'], $this->row_actions( $actions ) ); } $plugin = TGM_Plugin_Activation::$instance->plugins[ $item[ 'slug' ] ]; //** We need to display the 'Install' hover link. */ if ( ! isset( $installed_plugins[$item['file_path']] ) ) { if( isset( $plugin[ 'private' ] ) && $plugin[ 'private' ] == true ) { //** Ignore 'Install' action since plugin is not available for direct upload. */ } else { $actions = array( 'install' => sprintf( '' . __( 'Install', 'tgmpa' ) . '', wp_nonce_url( esc_url( add_query_arg( array( 'page' => TGM_Plugin_Activation::$instance->menu, 'plugin' => $item['slug'], 'plugin_name' => $item['sanitized_plugin'], 'plugin_source' => $item['url'], 'tgmpa-install' => 'install-plugin', ), admin_url( 'themes.php' ) ) ), 'tgmpa-install' ), $item['sanitized_plugin'] ), ); } } //** We need to display the 'Activate' hover link. */ elseif ( is_plugin_inactive( $item['file_path'] ) ) { $actions = array( 'activate' => sprintf( '' . __( 'Activate', 'tgmpa' ) . '', esc_url( add_query_arg( array( 'page' => TGM_Plugin_Activation::$instance->menu, 'plugin' => $item['slug'], 'plugin_name' => $item['sanitized_plugin'], 'plugin_source' => $item['url'], 'tgmpa-activate' => 'activate-plugin', 'tgmpa-activate-nonce' => wp_create_nonce( 'tgmpa-activate' ), ), admin_url( 'themes.php' ) ) ), $item['sanitized_plugin'] ), ); } return sprintf( '%1$s %2$s', $item['plugin'], $this->row_actions( $actions ) ); } /** * Required for bulk installing. * * Adds a checkbox for each plugin. * * @since 2.2.0 * * @param array $item Array of item data. * @return string The input checkbox with all necessary info. */ public function column_cb( $item ) { //** Ignore Plugins if they are not in list */ if ( is_plugin_active( $item['file_path'] ) || !isset( TGM_Plugin_Activation::$instance->plugins[ $item[ 'slug' ] ] ) ) { return ''; } //** Ignore plugin's action if it's private and not installed. */ $plugin = TGM_Plugin_Activation::$instance->plugins[ $item[ 'slug' ] ]; $installed_plugins = get_plugins(); if( isset( $plugin[ 'private' ] ) && $plugin[ 'private' ] == true && !isset( $installed_plugins[$item['file_path']] ) ) { return ''; } $value = $item['file_path'] . ',' . $item['url'] . ',' . $item['sanitized_plugin']; return sprintf( '', $this->_args['singular'], $value, $item['sanitized_plugin'] ); } /** * Sets default message within the plugins table if no plugins * are left for interaction. * * Hides the menu item to prevent the user from clicking and * getting a permissions error. * * @since 2.2.0 */ public function no_items() { printf( __( 'No plugins to install or activate. Return to the Dashboard', 'tgmpa' ), admin_url() ); echo ''; } /** * Output all the column information within the table. * * @since 2.2.0 * * @return array $columns The column names. */ public function get_columns() { $columns = array( 'cb' => '', 'plugin' => __( 'Plugin', 'tgmpa' ), 'source' => __( 'Source', 'tgmpa' ), 'type' => __( 'Type', 'tgmpa' ), 'status' => __( 'Status', 'tgmpa' ) ); return $columns; } /** * Defines all types of bulk actions for handling * registered plugins. * * @since 2.2.0 * * @return array $actions The bulk actions for the plugin install table. */ public function get_bulk_actions() { $actions = array( 'tgmpa-bulk-install' => __( 'Install', 'tgmpa' ), 'tgmpa-bulk-activate' => __( 'Activate', 'tgmpa' ), ); return $actions; } /** * Processes bulk installation and activation actions. * * The bulk installation process looks either for the $_POST * information or for the plugin info within the $_GET variable if * a user has to use WP_Filesystem to enter their credentials. * * @since 2.2.0 */ public function process_bulk_actions() { // Bulk installation process. if ( 'tgmpa-bulk-install' === $this->current_action() ) { check_admin_referer( 'bulk-' . $this->_args['plural'] ); // Prep variables to be populated. $plugins_to_install = array(); $plugin_installs = array(); $plugin_path = array(); $plugin_name = array(); // Look first to see if information has been passed via WP_Filesystem. if ( isset( $_GET['plugins'] ) ) { $plugins = explode( ',', stripslashes( $_GET['plugins'] ) ); } // Looks like the user can use the direct method, take from $_POST. elseif ( isset( $_POST['plugin'] ) ) { $plugins = (array) $_POST['plugin']; } // Nothing has been submitted. else { $plugins = array(); } // Grab information from $_POST if available. if ( isset( $_POST['plugin'] ) ) { foreach ( $plugins as $plugin_data ) { $plugins_to_install[] = explode( ',', $plugin_data ); } foreach ( $plugins_to_install as $plugin_data ) { $plugin_installs[] = $plugin_data[0]; $plugin_path[] = $plugin_data[1]; $plugin_name[] = $plugin_data[2]; } } // Information has been passed via $_GET. else { foreach ( $plugins as $key => $value ) { // Grab plugin slug for each plugin. if ( 0 == $key % 3 || 0 == $key ) { $plugins_to_install[] = $value; $plugin_installs[] = $value; } } } // Look first to see if information has been passed via WP_Filesystem. if ( isset( $_GET['plugin_paths'] ) ) { $plugin_paths = explode( ',', stripslashes( $_GET['plugin_paths'] ) ); } // Looks like the user doesn't need to enter his FTP creds. elseif ( isset( $_POST['plugin'] ) ) { $plugin_paths = (array) $plugin_path; } // Nothing has been submitted. else { $plugin_paths = array(); } // Look first to see if information has been passed via WP_Filesystem. if ( isset( $_GET['plugin_names'] ) ) { $plugin_names = explode( ',', stripslashes( $_GET['plugin_names'] ) ); } // Looks like the user doesn't need to enter his FTP creds. elseif ( isset( $_POST['plugin'] ) ) { $plugin_names = (array) $plugin_name; } // Nothing has been submitted. else { $plugin_names = array(); } // Loop through plugin slugs and remove already installed plugins from the list. $i = 0; foreach ( $plugin_installs as $key => $plugin ) { if ( preg_match( '|.php$|', $plugin ) ) { unset( $plugin_installs[$key] ); // If the plugin path isn't in the $_GET variable, we can unset the corresponding path. if ( ! isset( $_GET['plugin_paths'] ) ) unset( $plugin_paths[$i] ); // If the plugin name isn't in the $_GET variable, we can unset the corresponding name. if ( ! isset( $_GET['plugin_names'] ) ) unset( $plugin_names[$i] ); } $i++; } // No need to proceed further if we have no plugins to install. if ( empty( $plugin_installs ) ) { return false; } // Reset array indexes in case we removed already installed plugins. $plugin_installs = array_values( $plugin_installs ); $plugin_paths = array_values( $plugin_paths ); $plugin_names = array_values( $plugin_names ); // If we grabbed our plugin info from $_GET, we need to decode it for use. $plugin_installs = array_map( 'urldecode', $plugin_installs ); $plugin_paths = array_map( 'urldecode', $plugin_paths ); $plugin_names = array_map( 'urldecode', $plugin_names ); // Pass all necessary information via URL if WP_Filesystem is needed. $url = wp_nonce_url( esc_url( add_query_arg( array( 'page' => TGM_Plugin_Activation::$instance->menu, 'tgmpa-action' => 'install-selected', 'plugins' => urlencode( implode( ',', $plugins ) ), 'plugin_paths' => urlencode( implode( ',', $plugin_paths ) ), 'plugin_names' => urlencode( implode( ',', $plugin_names ) ), ), admin_url( 'themes.php' ) ) ), 'bulk-plugins' ); $method = ''; // Leave blank so WP_Filesystem can populate it as necessary. $fields = array( 'action', '_wp_http_referer', '_wpnonce' ); // Extra fields to pass to WP_Filesystem. if ( false === ( $creds = request_filesystem_credentials( $url, $method, false, false, $fields ) ) ) { return true; } if ( ! WP_Filesystem( $creds ) ) { request_filesystem_credentials( $url, $method, true, false, $fields ); // Setup WP_Filesystem. return true; } require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; // Need for plugins_api require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; // Need for upgrade classes // Store all information in arrays since we are processing a bulk installation. $api = array(); $sources = array(); $install_path = array(); // Loop through each plugin to install and try to grab information from WordPress API, if not create 'tgmpa-empty' scalar. $i = 0; foreach ( $plugin_installs as $plugin ) { $api[$i] = plugins_api( 'plugin_information', array( 'slug' => $plugin, 'fields' => array( 'sections' => false ) ) ) ? plugins_api( 'plugin_information', array( 'slug' => $plugin, 'fields' => array( 'sections' => false ) ) ) : (object) $api[$i] = 'tgmpa-empty'; $i++; } if ( is_wp_error( $api ) ) { wp_die( TGM_Plugin_Activation::$instance->strings['oops'] . var_dump( $api ) ); } // Capture download links from $api or set install link to pre-packaged/private repo. $i = 0; foreach ( $api as $object ) { $sources[$i] = isset( $object->download_link ) && 'repo' == $plugin_paths[$i] ? $object->download_link : $plugin_paths[$i]; $i++; } // Finally, all the data is prepared to be sent to the installer. $url = esc_url( add_query_arg( array( 'page' => TGM_Plugin_Activation::$instance->menu ), admin_url( 'themes.php' ) ) ); $nonce = 'bulk-plugins'; $names = $plugin_names; // Create a new instance of TGM_Bulk_Installer. $installer = new TGM_Bulk_Installer( $skin = new TGM_Bulk_Installer_Skin( compact( 'url', 'nonce', 'names' ) ) ); // Wrap the install process with the appropriate HTML. echo '
      '; if ( version_compare( TGM_Plugin_Activation::$instance->wp_version, '3.8', '<' ) ) { screen_icon( apply_filters( 'tgmpa_default_screen_icon', 'themes' ) ); } echo '

      ' . esc_html( get_admin_page_title() ) . '

      '; // Process the bulk installation submissions. $installer->bulk_install( $sources ); echo '
      '; return true; } // Bulk activation process. if ( 'tgmpa-bulk-activate' === $this->current_action() ) { check_admin_referer( 'bulk-' . $this->_args['plural'] ); // Grab plugin data from $_POST. $plugins = isset( $_POST['plugin'] ) ? (array) $_POST['plugin'] : array(); $plugins_to_activate = array(); // Split plugin value into array with plugin file path, plugin source and plugin name. foreach ( $plugins as $i => $plugin ) { $plugins_to_activate[] = explode( ',', $plugin ); } foreach ( $plugins_to_activate as $i => $array ) { if ( ! preg_match( '|.php$|', $array[0] ) ) { unset( $plugins_to_activate[$i] ); } } // Return early if there are no plugins to activate. if ( empty( $plugins_to_activate ) ) { return; } $plugins = array(); $plugin_names = array(); foreach ( $plugins_to_activate as $plugin_string ) { $plugins[] = $plugin_string[0]; $plugin_names[] = $plugin_string[2]; } $count = count( $plugin_names ); // Count so we can use _n function. $last_plugin = array_pop( $plugin_names ); // Pop off last name to prep for readability. $imploded = empty( $plugin_names ) ? '' . $last_plugin . '' : '' . ( implode( ', ', $plugin_names ) . ' and ' . $last_plugin . '.' ); // Now we are good to go - let's start activating plugins. $activate = activate_plugins( $plugins ); if ( is_wp_error( $activate ) ) { echo '

      ' . $activate->get_error_message() . '

      '; } else { printf( '

      %1$s %2$s

      ', _n( 'The following plugin was activated successfully:', 'The following plugins were activated successfully:', $count, 'tgmpa' ), $imploded ); } // Update recently activated plugins option. $recent = (array) get_option( 'recently_activated' ); foreach ( $plugins as $plugin => $time ) { if ( isset( $recent[$plugin] ) ) { unset( $recent[$plugin] ); } } update_option( 'recently_activated', $recent ); unset( $_POST ); // Reset the $_POST variable in case user wants to perform one action after another. } } /** * Prepares all of our information to be outputted into a usable table. * * @since 2.2.0 */ public function prepare_items() { $per_page = 100; // Set it high so we shouldn't have to worry about pagination. $columns = $this->get_columns(); // Get all necessary column information. $hidden = array(); // No columns to hide, but we must set as an array. $sortable = array(); // No reason to make sortable columns. $this->_column_headers = array( $columns, $hidden, $sortable ); // Get all necessary column headers. // Process our bulk actions here. $this->process_bulk_actions(); // Store all of our plugin data into $items array so WP_List_Table can use it. $this->items = $this->_gather_plugin_data(); } } } } ================================================ FILE: vendor/udx/lib-wp-bootstrap/lib/classes/class-tgm-plugin-activation.php ================================================ * @author Gary Jones * @copyright Copyright (c) 2012, Thomas Griffin * @license http://opensource.org/licenses/gpl-2.0.php GPL v2 or later * @link https://github.com/thomasgriffin/TGM-Plugin-Activation */ /* Copyright 2014 Thomas Griffin (thomasgriffinmedia.com) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ namespace UsabilityDynamics\WP { if ( ! class_exists( 'UsabilityDynamics\WP\TGM_Plugin_Activation' ) ) { /** * Automatic plugin installation and activation library. * * Creates a way to automatically install and activate plugins from within themes. * The plugins can be either pre-packaged, downloaded from the WordPress * Plugin Repository or downloaded from a private repository. * * @since 1.0.0 * * @package TGM-Plugin-Activation * @author Thomas Griffin * @author Gary Jones */ class TGM_Plugin_Activation { /** * Holds a copy of itself, so it can be referenced by the class name. * * @since 1.0.0 * * @var TGM_Plugin_Activation */ public static $instance; /** * Holds arrays of plugin details. * * @since 1.0.0 * * @var array */ public $plugins = array(); /** * */ public $referrers = array(); /** * Name of the querystring argument for the admin page. * * @since 1.0.0 * * @var string */ public $menu = 'ud-install-plugins'; /** * Default absolute path to folder containing pre-packaged plugin zip files. * * @since 2.0.0 * * @var string Absolute path prefix to packaged zip file location. Default is empty string. */ public $default_path = ''; /** * Flag to show admin notices or not. * * @since 2.1.0 * * @var boolean */ public $has_notices = true; /** * Flag to determine if the user can dismiss the notice nag. * * @since 2.4.0 * * @var boolean */ public $dismissable = true; /** * Message to be output above nag notice if dismissable is false. * * @since 2.4.0 * * @var string */ public $dismiss_msg = ''; /** * Flag to set automatic activation of plugins. Off by default. * * @since 2.2.0 * * @var boolean */ public $is_automatic = false; /** * Optional message to display before the plugins table. * * @since 2.2.0 * * @var string Message filtered by wp_kses_post(). Default is empty string. */ public $message = ''; /** * Holds configurable array of strings. * * Default values are added in the constructor. * * @since 2.0.0 * * @var array */ public $strings = array(); /** * Error Notice types. * * @var array */ public $error_types = array( 'notice_can_install_required', 'notice_can_activate_required', 'notice_ask_to_update', ); /** * Holds the version of WordPress. * * @since 2.4.0 * * @var int */ public $wp_version; /** * Adds a reference of this object to $instance, populates default strings, * does the tgmpa_init action hook, and hooks in the interactions to init. * * @since 1.0.0 * * @see TGM_Plugin_Activation::init() */ private function __construct() { $this->strings = array( 'page_title' => __( 'Install Required Plugins', 'tgmpa' ), 'menu_title' => __( 'Install Plugins', 'tgmpa' ), 'installing' => __( 'Installing Plugin: %s', 'tgmpa' ), 'oops' => __( 'Something went wrong.', 'tgmpa' ), 'notice_can_install_required' => _n_noop( '%2$s requires the following plugin: %1$s.', '%2$s requires the following plugins: %1$s.' ), 'notice_can_install_recommended' => _n_noop( '%2$s recommends the following plugin: %1$s.', '%2$s recommends the following plugins: %1$s.' ), 'notice_cannot_install' => _n_noop( 'Sorry, but you do not have the correct permissions to install the %s plugin. Contact the administrator of this site for help on getting the plugin installed.', 'Sorry, but you do not have the correct permissions to install the %s plugins. Contact the administrator of this site for help on getting the plugins installed.' ), 'notice_can_activate_required' => _n_noop( 'The following required plugin is currently inactive: %1$s.', 'The following required plugins are currently inactive: %1$s.' ), 'notice_can_activate_recommended'=> _n_noop( 'The following recommended plugin is currently inactive: %1$s.', 'The following recommended plugins are currently inactive: %1$s.' ), 'notice_cannot_activate' => _n_noop( 'Sorry, but you do not have the correct permissions to activate the %s plugin. Contact the administrator of this site for help on getting the plugin activated.', 'Sorry, but you do not have the correct permissions to activate the %s plugins. Contact the administrator of this site for help on getting the plugins activated.' ), 'notice_ask_to_update' => _n_noop( 'The following plugin needs to be updated to its latest version to ensure maximum compatibility with %2$s: %1$s.', 'The following plugins need to be updated to their latest version to ensure maximum compatibility with %2$s: %1$s.' ), 'notice_cannot_update' => _n_noop( 'Sorry, but you do not have the correct permissions to update the %s plugin. Contact the administrator of this site for help on getting the plugin updated.', 'Sorry, but you do not have the correct permissions to update the %s plugins. Contact the administrator of this site for help on getting the plugins updated.' ), 'install_link' => _n_noop( 'Begin installing plugin', 'Begin installing plugins' ), 'activate_link' => _n_noop( 'Begin activating plugin', 'Begin activating plugins' ), 'return' => __( 'Return to Required Plugins Installer', 'tgmpa' ), 'dashboard' => __( 'Return to the dashboard', 'tgmpa' ), 'plugin_activated' => __( 'Plugin activated successfully.', 'tgmpa' ), 'activated_successfully' => __( 'The following plugin was activated successfully:', 'tgmpa' ), 'complete' => __( 'All plugins installed and activated successfully. %1$s', 'tgmpa' ), 'dismiss' => __( 'Dismiss this notice', 'tgmpa' ), ); // Set the current WordPress version. global $wp_version; $this->wp_version = $wp_version; // Announce that the class is ready, and pass the object (for advanced use). do_action_ref_array( 'tgmpa_init', array( $this ) ); // When the rest of WP has loaded, kick-start the rest of the class. //add_action( 'plugins_loaded', array( $this, 'init' ), 0 ); add_action( 'init', array( $this, 'init' ) ); } /** * Initialise the interactions between this class and WordPress. * * Hooks in three new methods for the class: admin_menu, notices and styles. * * @since 2.0.0 * * @see TGM_Plugin_Activation::admin_menu() * @see TGM_Plugin_Activation::notices() * @see TGM_Plugin_Activation::styles() */ public function init() { // After this point, the plugins should be registered and the configuration set. // Proceed only if we have plugins to handle. if ( $this->plugins ) { $sorted = array(); foreach ( $this->plugins as $plugin ) { $sorted[] = $plugin['name']; } array_multisort( $sorted, SORT_ASC, $this->plugins ); add_action( 'admin_menu', array( $this, 'admin_menu' ) ); add_filter( 'install_plugin_complete_actions', array( $this, 'actions' ) ); add_action( 'switch_theme', array( $this, 'flush_plugins_cache' ) ); // Load admin bar in the header to remove flash when installing plugins. if ( $this->is_tgmpa_page() ) { remove_action( 'wp_footer', 'wp_admin_bar_render', 1000 ); remove_action( 'admin_footer', 'wp_admin_bar_render', 1000 ); add_action( 'wp_head', 'wp_admin_bar_render', 1000 ); add_action( 'admin_head', 'wp_admin_bar_render', 1000 ); } if ( $this->has_notices ) { add_action( 'admin_init', array( $this, 'admin_init' ), 1 ); add_action( 'admin_enqueue_scripts', array( $this, 'thickbox' ) ); } // Setup the force activation hook. foreach ( $this->plugins as $plugin ) { if ( isset( $plugin['force_activation'] ) && true === $plugin['force_activation'] ) { add_action( 'admin_init', array( $this, 'force_activation' ) ); break; } } // Setup the force deactivation hook. foreach ( $this->plugins as $plugin ) { if ( isset( $plugin['force_deactivation'] ) && true === $plugin['force_deactivation'] ) { add_action( 'switch_theme', array( $this, 'force_deactivation' ) ); break; } } } } /** * Handles calls to show plugin information via links in the notices. * * We get the links in the admin notices to point to the TGMPA page, rather * than the typical plugin-install.php file, so we can prepare everything * beforehand. * * WP doesn't make it easy to show the plugin information in the thickbox - * here we have to require a file that includes a function that does the * main work of displaying it, enqueue some styles, set up some globals and * finally call that function before exiting. * * Down right easy once you know how... * * @since 2.1.0 * * @global string $tab Used as iframe div class names, helps with styling * @global string $body_id Used as the iframe body ID, helps with styling * @return null Returns early if not the TGMPA page. */ public function admin_init() { if ( ! $this->is_tgmpa_page() ) { return; } if ( isset( $_REQUEST['tab'] ) && 'plugin-information' == $_REQUEST['tab'] ) { require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; // Need for install_plugin_information(). wp_enqueue_style( 'plugin-install' ); global $tab, $body_id; $body_id = $tab = 'plugin-information'; install_plugin_information(); exit; } } /** * Enqueues thickbox scripts/styles for plugin info. * * Thickbox is not automatically included on all admin pages, so we must * manually enqueue it for those pages. * * Thickbox is only loaded if the user has not dismissed the admin * notice or if there are any plugins left to install and activate. * * @since 2.1.0 */ public function thickbox() { add_thickbox(); } /** * Adds submenu page under 'Appearance' tab. * * This method adds the submenu page letting users know that a required * plugin needs to be installed. * * This page disappears once the plugin has been installed and activated. * * @since 1.0.0 * * @see TGM_Plugin_Activation::init() * @see TGM_Plugin_Activation::install_plugins_page() */ public function admin_menu() { // Make sure privileges are correct to see the page if ( ! current_user_can( 'install_plugins' ) ) { return; } $this->populate_file_path(); foreach ( $this->plugins as $plugin ) { if ( ! is_plugin_active( $plugin['file_path'] ) ) { add_theme_page( $this->strings['page_title'], // Page title. $this->strings['menu_title'], // Menu title. 'edit_theme_options', // Capability. $this->menu, // Menu slug. array( $this, 'install_plugins_page' ) // Callback. ); break; } } } /** * Echoes plugin installation form. * * This method is the callback for the admin_menu method function. * This displays the admin page and form area where the user can select to install and activate the plugin. * * @since 1.0.0 * * @return null Aborts early if we're processing a plugin installation action */ public function install_plugins_page() { // Store new instance of plugin table in object. $plugin_table = new TGMPA_List_Table; // Return early if processing a plugin installation action. if ( isset( $_POST['action'] ) && 'tgmpa-bulk-install' == $_POST['action'] && $plugin_table->process_bulk_actions() || $this->do_plugin_install() ) { return; } ?>
      wp_version, '3.8', '<' ) ) { screen_icon( apply_filters( 'ud_default_screen_icon', 'themes' ) ); } ?>

      prepare_items(); ?> message ) ) { echo wp_kses_post( $this->message ); } ?>
      display(); ?>
      $this->menu, 'plugin' => $plugin['slug'], 'plugin_name' => $plugin['name'], 'plugin_source' => $plugin['source'], 'tgmpa-install' => 'install-plugin', ), admin_url( 'themes.php' ) ) ), 'tgmpa-install' ); $method = ''; // Leave blank so WP_Filesystem can populate it as necessary. $fields = array( 'tgmpa-install' ); // Extra fields to pass to WP_Filesystem. if ( false === ( $creds = request_filesystem_credentials( $url, $method, false, false, $fields ) ) ) { return true; } if ( ! WP_Filesystem( $creds ) ) { request_filesystem_credentials( $url, $method, true, false, $fields ); // Setup WP_Filesystem. return true; } require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; // Need for plugins_api. require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; // Need for upgrade classes. // Set plugin source to WordPress API link if available. if ( isset( $plugin['source'] ) && 'repo' == $plugin['source'] ) { $api = plugins_api( 'plugin_information', array( 'slug' => $plugin['slug'], 'fields' => array( 'sections' => false ) ) ); if ( is_wp_error( $api ) ) { wp_die( $this->strings['oops'] . var_dump( $api ) ); } if ( isset( $api->download_link ) ) { $plugin['source'] = $api->download_link; } } // Set type, based on whether the source starts with http:// or https://. $type = preg_match( '|^http(s)?://|', $plugin['source'] ) ? 'web' : 'upload'; // Prep variables for Plugin_Installer_Skin class. $title = sprintf( $this->strings['installing'], $plugin['name'] ); $url = esc_url( add_query_arg( array( 'action' => 'install-plugin', 'plugin' => $plugin['slug'] ), 'update.php' ) ); if ( isset( $_GET['from'] ) ) { $url .= esc_url( add_query_arg( 'from', urlencode( stripslashes( $_GET['from'] ) ), $url ) ); } $nonce = 'install-plugin_' . $plugin['slug']; // Prefix a default path to pre-packaged plugins. $source = ( 'upload' == $type ) ? $this->default_path . $plugin['source'] : $plugin['source']; // Create a new instance of Plugin_Upgrader. $upgrader = new \Plugin_Upgrader( $skin = new \Plugin_Installer_Skin( compact( 'type', 'title', 'url', 'nonce', 'plugin', 'api' ) ) ); // Perform the action and install the plugin from the $source urldecode(). $upgrader->install( $source ); // Flush plugins cache so we can make sure that the installed plugins list is always up to date. wp_cache_flush(); // Only activate plugins if the config option is set to true. if ( $this->is_automatic ) { $plugin_activate = $upgrader->plugin_info(); // Grab the plugin info from the Plugin_Upgrader method. $activate = activate_plugin( $plugin_activate ); // Activate the plugin. $this->populate_file_path(); // Re-populate the file path now that the plugin has been installed and activated. if ( is_wp_error( $activate ) ) { echo '

      ' . $activate->get_error_message() . '

      '; echo '

      ' . $this->strings['return'] . '

      '; return true; // End it here if there is an error with automatic activation } else { echo '

      ' . $this->strings['plugin_activated'] . '

      '; } } // Display message based on if all plugins are now active or not. $complete = array(); foreach ( $this->plugins as $plugin ) { if ( ! is_plugin_active( $plugin['file_path'] ) ) { echo '

      ' . $this->strings['return'] . '

      '; $complete[] = $plugin; break; } // Nothing to store. else { $complete[] = ''; } } // Filter out any empty entries. $complete = array_filter( $complete ); // All plugins are active, so we display the complete string and hide the plugin menu. if ( empty( $complete ) ) { echo '

      ' . sprintf( $this->strings['complete'], '' . __( 'Return to the Dashboard', 'tgmpa' ) . '' ) . '

      '; echo ''; } return true; } // Checks for actions from hover links to process the activation. elseif ( isset( $_GET['plugin'] ) && ( isset( $_GET['tgmpa-activate'] ) && 'activate-plugin' == $_GET['tgmpa-activate'] ) ) { check_admin_referer( 'tgmpa-activate', 'tgmpa-activate-nonce' ); // Populate $plugin array with necessary information. $plugin['name'] = $_GET['plugin_name']; $plugin['slug'] = $_GET['plugin']; $plugin['source'] = $_GET['plugin_source']; $plugin_path = $this->_get_plugin_basename_from_slug($plugin['slug']); // Retrieve all plugins. $activate = activate_plugin( $plugin_path ); // Activate the plugin. if ( is_wp_error( $activate ) ) { echo '

      ' . $activate->get_error_message() . '

      '; echo '

      ' . $this->strings['return'] . '

      '; return true; // End it here if there is an error with activation. } else { // Make sure message doesn't display again if bulk activation is performed immediately after a single activation. if ( ! isset( $_POST['action'] ) ) { $msg = $this->strings['activated_successfully'] . ' ' . $plugin['name'] . ''; echo '

      ' . $msg . '

      '; } } } return false; } /** * Echoes required plugin notice. * * Outputs a message telling users that a specific plugin is required for * their theme. If appropriate, it includes a link to the form page where * users can install and activate the plugin. * * @since 1.0.0 * * @global object $current_screen * @return null Returns early if we're on the Install page. */ public function notices( $referrer = false ) { //** Check if get_plugins() function exists. This is required on the front end of the */ //** site, since it is in a file that is normally only loaded in the admin. */ if ( ! function_exists( 'get_plugins' ) ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } $installed_plugins = \get_plugins(); // Retrieve a list of all the plugins $this->populate_file_path(); $message = array(); // Store the messages in an array to be outputted after plugins have looped through. $e_install_link = false; // Set to false, change to true in loop if conditions exist, used for action link 'install'. $e_install_link_count = 0; // Used to determine plurality of install action link text. $e_activate_link = false; // Set to false, change to true in loop if conditions exist, used for action link 'activate'. $e_activate_link_count = 0; // Used to determine plurality of activate action link text. $m_install_link = false; // Set to false, change to true in loop if conditions exist, used for action link 'install'. $m_install_link_count = 0; // Used to determine plurality of install action link text. $m_activate_link = false; // Set to false, change to true in loop if conditions exist, used for action link 'activate'. $m_activate_link_count = 0; // Used to determine plurality of activate action link text. foreach ( $this->referrers as $plugin ) { //** We must return only notices for referrer */ if( empty( $referrer ) || $referrer != $plugin[ '_referrer' ] || !isset( $this->plugins[ $plugin[ 'slug' ] ] ) ) { continue; } $plugin[ 'file_path' ] = $this->plugins[ $plugin[ 'slug' ] ][ 'file_path' ]; // If the plugin is installed and active, check for minimum version argument before moving forward. if ( is_plugin_active( $plugin['file_path'] ) ) { // A minimum version has been specified. if ( isset( $plugin['version'] ) ) { if ( isset( $installed_plugins[$plugin['file_path']]['Version'] ) ) { // If the current version is less than the minimum required version, we display a message. if ( version_compare( $installed_plugins[$plugin['file_path']]['Version'], $plugin['version'], '<' ) ) { if ( current_user_can( 'install_plugins' ) ) { $message['notice_ask_to_update'][] = $plugin; } else { $message['notice_cannot_update'][] = $plugin; } } } // Can't find the plugin, so iterate to the next condition. else { continue; } } // No minimum version specified, so iterate over the plugin. else { continue; } } // Not installed. if ( ! isset( $installed_plugins[$plugin['file_path']] ) ) { if ( current_user_can( 'install_plugins' ) ) { if ( isset( $plugin['required'] ) && $plugin['required'] ) { $e_install_link = true; // We need to display the 'install' action link. $e_install_link_count++; // Increment the install link count. $message['notice_can_install_required'][] = $plugin; } // This plugin is only recommended. else { $m_install_link = true; // We need to display the 'install' action link. $m_install_link_count++; // Increment the install link count. $message['notice_can_install_recommended'][] = $plugin; } } elseif( !is_user_logged_in() && isset( $plugin['required'] ) && $plugin['required'] ) { $message['notice_can_install_required'][] = $plugin; } // Need higher privileges to install the plugin. else { if ( isset( $plugin['required'] ) && $plugin['required'] ) { $message['notice_can_install_required'][] = $plugin; $message['notice_cannot_activate'][] = $plugin; } else { $message['notice_cannot_activate'][] = $plugin; } } } // Installed but not active. elseif ( is_plugin_inactive( $plugin['file_path'] ) ) { if ( current_user_can( 'activate_plugins' ) ) { if ( isset( $plugin['required'] ) && $plugin['required'] ) { $e_activate_link = true; // We need to display the 'activate' action link. $e_activate_link_count++; // Increment the activate link count. $message['notice_can_activate_required'][] = $plugin; } // This plugin is only recommended. else { $m_activate_link = true; // We need to display the 'activate' action link. $m_activate_link_count++; // Increment the activate link count. $message['notice_can_activate_recommended'][] = $plugin; } } elseif( !is_user_logged_in() && isset( $plugin['required'] ) && $plugin['required'] ) { $message['notice_can_install_required'][] = $plugin; } // Need higher privileges to activate the plugin. else { if ( isset( $plugin['required'] ) && $plugin['required'] ) { $message['notice_can_install_required'][] = $plugin; $message['notice_cannot_activate'][] = $plugin; } else { $message['notice_cannot_activate'][] = $plugin; } } } } //return $message; $prepared = array(); // If we have notices to display, we move forward. if ( ! empty( $message ) ) { krsort( $message ); // Sort messages. // Grab all plugin names. foreach ( $message as $type => $plugin_groups ) { $linked_plugin_groups = array(); // Count number of plugins in each message group to calculate singular/plural message. $count = count( $plugin_groups ); // Loop through the plugin names to make the ones pulled from the .org repo linked. foreach ( $plugin_groups as $plugin ) { $plugin_group_single_name = $plugin[ 'name' ]; $external_url = $this->_get_plugin_data_from_name( $plugin_group_single_name, 'external_url' ); $source = $this->_get_plugin_data_from_name( $plugin_group_single_name, 'source' ); if ( $external_url && preg_match( '|^http(s)?://|', $external_url ) ) { $linked_plugin_groups[] = '' . $plugin_group_single_name . ''; } elseif ( ! $source || preg_match( '|^http://wordpress.org/extend/plugins/|', $source ) ) { $url = esc_url( add_query_arg( array( 'tab' => 'plugin-information', 'plugin' => $this->_get_plugin_data_from_name( $plugin_group_single_name ), 'TB_iframe' => 'true', 'width' => '640', 'height' => '500', ), admin_url( 'plugin-install.php' ) ) ); $linked_plugin_groups[] = '' . $plugin_group_single_name . ''; } else { $linked_plugin_groups[] = $plugin_group_single_name; // No hyperlink. } if ( isset( $linked_plugin_groups ) && (array) $linked_plugin_groups ) { $plugin_groups = $linked_plugin_groups; } } $last_plugin = array_pop( $plugin_groups ); // Pop off last name to prep for readability. $imploded = empty( $plugin_groups ) ? '' . $last_plugin . '' : '' . ( implode( ', ', $plugin_groups ) . ' and ' . $last_plugin . '' ); $prepared['messages'][] = array( 'type' => ( in_array( $type, $this->error_types ) && $plugin[ 'required' ] ? 'error' : 'message' ), 'value' => sprintf( translate_nooped_plural( $this->strings[$type], $count, 'tgmpa' ), $imploded, $plugin[ '_referrer_name' ], $count ), ); } //** Setup variables to determine if action links are needed. */ $e_show_install_link = $e_install_link ? '' . translate_nooped_plural( $this->strings['install_link'], $e_install_link_count, 'tgmpa' ) . '' : ''; $e_show_activate_link = $e_activate_link ? '' . translate_nooped_plural( $this->strings['activate_link'], $e_activate_link_count, 'tgmpa' ) . '' : ''; $m_show_install_link = $m_install_link ? '' . translate_nooped_plural( $this->strings['install_link'], $m_install_link_count, 'tgmpa' ) . '' : ''; $m_show_activate_link = $m_activate_link ? '' . translate_nooped_plural( $this->strings['activate_link'], $m_activate_link_count, 'tgmpa' ) . '' : ''; //** Define all of the action links. */ $prepared[ 'links' ] = array( 'error' => array_filter( array( 'install' => ( current_user_can( 'install_plugins' ) ) ? $e_show_install_link : false, 'activate' => ( current_user_can( 'activate_plugins' ) ) ? $e_show_activate_link : false, ) ), 'message' => array_filter( array( 'install' => ( current_user_can( 'install_plugins' ) ) ? $m_show_install_link : false, 'activate' => ( current_user_can( 'activate_plugins' ) ) ? $m_show_activate_link : false, ) ), ); } return $prepared; } /** * Add individual plugin to our collection of plugins. * * If the required keys are not set or the plugin has already * been registered, the plugin is not added. * * @since 2.0.0 * * @param array $plugin Array of plugin arguments. */ public function register( $plugin ) { if ( ! isset( $plugin['slug'] ) || ! isset( $plugin['name'] ) ) { return; } if( isset( $this->plugins[ $plugin[ 'slug' ] ] ) ) { $_plugin = $this->plugins[ $plugin[ 'slug' ] ]; //** Version must be set the highest to prevent issues. */ if( !empty( $_plugin[ 'version' ] ) && !empty( $plugin[ 'version' ] ) ) { $version = version_compare( $_plugin[ 'version' ], $plugin[ 'version' ], '<' ) ? $plugin[ 'version' ] : $_plugin[ 'version' ]; } else { $version = !empty( $plugin[ 'version' ] ) ? $plugin[ 'version' ] : ( !empty( $_plugin[ 'version' ] ) ? $_plugin[ 'version' ] : false ); } if( !empty( $version ) ) { $this->plugins[ $plugin[ 'slug' ] ][ 'version' ] = $version; } //** Parent plugin must be set as required if any child plugin requires it. */ $this->plugins[ $plugin[ 'slug' ] ][ 'required' ] = $_plugin[ 'required' ] == true ? $_plugin[ 'required' ] : $plugin[ 'required' ]; } else { $_plugin = $plugin; unset( $_plugin[ '_referrer' ] ); unset( $_plugin[ '_referrer_name' ] ); $this->plugins[ $plugin[ 'slug' ] ] = $_plugin; } $this->referrers[] = $plugin; } /** * Amend default configuration settings. * * @since 2.0.0 * * @param array $config Array of config options to pass as class properties. */ public function config( $config ) { $keys = array( 'default_path', 'has_notices', 'dismissable', 'dismiss_msg', 'menu', 'is_automatic', 'message', 'strings' ); foreach ( $keys as $key ) { if ( isset( $config[$key] ) ) { if ( is_array( $config[$key] ) ) { foreach ( $config[$key] as $subkey => $value ) { $this->{$key}[$subkey] = $value; } } else { $this->$key = $config[$key]; } } } } /** * Amend action link after plugin installation. * * @since 2.0.0 * * @param array $install_actions Existing array of actions. * @return array Amended array of actions. */ public function actions( $install_actions ) { // Remove action links on the TGMPA install page. if ( $this->is_tgmpa_page() ) { return false; } return $install_actions; } /** * Flushes the plugins cache on theme switch to prevent stale entries * from remaining in the plugin table. * * @since 2.4.0 */ public function flush_plugins_cache() { wp_cache_flush(); } /** * Set file_path key for each installed plugin. * * @since 2.1.0 */ public function populate_file_path() { // Add file_path key for all plugins. foreach ( $this->plugins as $plugin => $values ) { $this->plugins[$plugin]['file_path'] = $this->_get_plugin_basename_from_slug( $values['slug'] ); } } /** * Helper function to extract the file path of the plugin file from the * plugin slug, if the plugin is installed. * * @since 2.0.0 * * @param string $slug Plugin slug (typically folder name) as provided by the developer. * @return string Either file path for plugin if installed, or just the plugin slug. */ protected function _get_plugin_basename_from_slug( $slug ) { $keys = array_keys( get_plugins() ); $_keys = array(); /** Try to get slug of activated plugin at first */ foreach ( $keys as $key ) { if ( preg_match( '|^' . $slug .'(-v?[0-9\.]+)?/|', $key ) ) { if( is_plugin_active( $key ) ) { return $key; } else { array_push( $_keys, $key ); } } } /** Get key from any non activated but installed matched plugin */ if( !empty( $_keys ) ) { return $_keys[0]; } return $slug; } /** * Retrieve plugin data, given the plugin name. * * Loops through the registered plugins looking for $name. If it finds it, * it returns the $data from that plugin. Otherwise, returns false. * * @since 2.1.0 * * @param string $name Name of the plugin, as it was registered. * @param string $data Optional. Array key of plugin data to return. Default is slug. * @return string|boolean Plugin slug if found, false otherwise. */ protected function _get_plugin_data_from_name( $name, $data = 'slug' ) { foreach ( $this->plugins as $plugin => $values ) { if ( $name == $values['name'] && isset( $values[$data] ) ) { return $values[$data]; } } return false; } /** * Determine if we're on the TGMPA Install page. * * @since 2.1.0 * * @return boolean True when on the TGMPA page, false otherwise. */ public function is_tgmpa_page() { if ( isset( $_GET['page'] ) && $this->menu === $_GET['page'] ) { return true; } return false; } /** * Forces plugin activation if the parameter 'force_activation' is * set to true. * * This allows theme authors to specify certain plugins that must be * active at all times while using the current theme. * * Please take special care when using this parameter as it has the * potential to be harmful if not used correctly. Setting this parameter * to true will not allow the specified plugin to be deactivated unless * the user switches themes. * * @since 2.2.0 */ public function force_activation() { // Set file_path parameter for any installed plugins. $this->populate_file_path(); $installed_plugins = get_plugins(); foreach ( $this->plugins as $plugin ) { // Oops, plugin isn't there so iterate to next condition. if ( isset( $plugin['force_activation'] ) && $plugin['force_activation'] && ! isset( $installed_plugins[$plugin['file_path']] ) ) { continue; } // There we go, activate the plugin. elseif ( isset( $plugin['force_activation'] ) && $plugin['force_activation'] && is_plugin_inactive( $plugin['file_path'] ) ) { activate_plugin( $plugin['file_path'] ); } } } /** * Forces plugin deactivation if the parameter 'force_deactivation' * is set to true. * * This allows theme authors to specify certain plugins that must be * deactived upon switching from the current theme to another. * * Please take special care when using this parameter as it has the * potential to be harmful if not used correctly. * * @since 2.2.0 */ public function force_deactivation() { // Set file_path parameter for any installed plugins. $this->populate_file_path(); foreach ( $this->plugins as $plugin ) { // Only proceed forward if the paramter is set to true and plugin is active. if ( isset( $plugin['force_deactivation'] ) && $plugin['force_deactivation'] && is_plugin_active( $plugin['file_path'] ) ) { deactivate_plugins( $plugin['file_path'] ); } } } /** * Returns the singleton instance of the class. * * @since 2.4.0 * * @return object The TGM_Plugin_Activation object. */ public static function get_instance() { if ( ! isset( self::$instance ) && !( self::$instance instanceof TGM_Plugin_Activation ) ) { self::$instance = new TGM_Plugin_Activation(); } return self::$instance; } } } } ================================================ FILE: vendor/udx/lib-wp-bootstrap/lib/classes/class-utility.php ================================================ __( 'Blah Blah' ) ), $locals ); * }); * * $result = self::l10n_localize (array( * 'key' => 'l10n.value_for_translating' * ) ); * * * @param array $data * @param array $l10n translated values * @return array * @author peshkov@UD */ static public function l10n_localize( $data, $l10n = array() ) { if ( !is_array( $data ) && !is_object( $data ) ) { return $data; } //** The Localization's list. */ $l10n = apply_filters( 'ud::schema::localization', $l10n ); //** Replace l10n entries */ foreach( $data as $k => $v ) { if ( is_array( $v ) ) { $data[ $k ] = self::l10n_localize( $v, $l10n ); } elseif ( is_string( $v ) ) { if ( strpos( $v, 'l10n' ) !== false ) { preg_match_all( '/l10n\.([^\s]*)/', $v, $matches ); if ( !empty( $matches[ 1 ] ) ) { foreach ( $matches[ 1 ] as $i => $m ) { if ( array_key_exists( $m, $l10n ) ) { $data[ $k ] = str_replace( $matches[ 0 ][ $i ], $l10n[ $m ], $data[ $k ] ); } } } } } } return $data; } } } } ================================================ FILE: vendor/udx/lib-wp-bootstrap/readme.md ================================================ lib-wp-bootstrap ================ UD Bootstrap library for WP plugins. ## License (The MIT License) Copyright (c) 2013 Usability Dynamics, Inc. <info@usabilitydynamics.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. ================================================ FILE: vendor/udx/lib-wp-bootstrap/static/scripts/ud-dismiss.js ================================================ /** * EVENTS */ jQuery( document ).ready( function () { jQuery( '.ud-admin-notice' ).on( 'click', '.dismiss', function(e){ e.preventDefault(); var _this = jQuery( this ); var data = { action: 'ud_dismiss', key: _this.data('key'), _ajax_nonce: _this.data('nonce'), } jQuery.post( _ud_vars.ajaxurl, data, function ( result_data ) { if( result_data.success == '1' ) { _this.closest('.ud-admin-notice').remove(); } else if ( result_data.success == '0' ) { alert(result_data.error); } }, "json" ); }); } ); ================================================ FILE: vendor/wpmetabox/meta-box/css/autocomplete.css ================================================ .rwmb-autocomplete-result { border-bottom: 1px solid #ccc; padding: 1em 0; overflow: hidden; } .rwmb-autocomplete-result .label { float: left; width: 90%; } .rwmb-autocomplete-result .actions { width: 10%; float: right; cursor: pointer; } .ui-autocomplete { z-index: 999999; } ================================================ FILE: vendor/wpmetabox/meta-box/css/background.css ================================================ .rwmb-background-row { margin-bottom: 5px; display: flex; gap: 5px; flex-wrap: wrap; align-items: flex-start; } .rwmb-background-wrapper .wp-picker-container { position: relative; display: inline-block; vertical-align: top; } .rwmb-background-wrapper .wp-picker-holder { position: absolute; z-index: 9; min-width: 255px; } .rwmb-background-wrapper .rwmb-select { flex: 1; margin-bottom: 5px; max-width: 100%; } ================================================ FILE: vendor/wpmetabox/meta-box/css/button-group.css ================================================ .rwmb-button-input-list { --color: var(--wp-admin-theme-color, #2271b1); } .rwmb-button-input-list .rwmb-button_group { display: none; } .rwmb-button-input-list label { display: block; border: 1px solid #8c8f94; position: relative; z-index: 1; padding: 5px 10px; background: #fff; cursor: pointer; } .rwmb-button-input-list .selected { border-color: var(--color); background: var(--color); color: #fff; z-index: 2; } /* Layout not inline */ .rwmb-button-input-list:not(.rwmb-inline) label:not(:first-child) { border-top-width: 0; } .rwmb-button-input-list:not(.rwmb-inline) .selected:not(:last-child) { border-bottom-color: rgba(255, 255, 255, .25); } .rwmb-button-input-list:not(.rwmb-inline) > label:first-child:not(:last-child) { border-top-left-radius: 3px; border-top-right-radius: 3px; } .rwmb-button-input-list:not(.rwmb-inline) > label:last-child:not(:first-child) { border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; } /* Layout inline */ .rwmb-button-input-list.rwmb-inline { display: flex; } .rwmb-button-input-list.rwmb-inline label:not(:first-child) { border-left-width: 0; } .rwmb-button-input-list.rwmb-inline .selected:not(:last-child) { border-right-color: rgba(255, 255, 255, .25); } .rwmb-button-input-list.rwmb-inline > label:first-child:not(:last-child) { border-top-left-radius: 3px; border-bottom-left-radius: 3px; } .rwmb-button-input-list.rwmb-inline > label:last-child:not(:first-child) { border-top-right-radius: 3px; border-bottom-right-radius: 3px; } /* Admin color schemes */ .admin-color-blue .rwmb-button-input-list { --color: var(--wp-admin-theme-color, #e1a948); } .admin-color-coffee .rwmb-button-input-list { --color: var(--wp-admin-theme-color, #c7a589); } .admin-color-ectoplasm .rwmb-button-input-list { --color: var(--wp-admin-theme-color, #a3b745); } .admin-color-light .rwmb-button-input-list { --color: var(--wp-admin-theme-color, #04a4cc); } .admin-color-midnight .rwmb-button-input-list { --color: var(--wp-admin-theme-color, #e14d43); } .admin-color-modern .rwmb-button-input-list { --color: var(--wp-admin-theme-color, #3858e9); } .admin-color-ocean .rwmb-button-input-list { --color: var(--wp-admin-theme-color, #9ebaa0); } .admin-color-sunrise .rwmb-button-input-list { --color: var(--wp-admin-theme-color, #dd823b); } ================================================ FILE: vendor/wpmetabox/meta-box/css/color.css ================================================ .rwmb-color-wrapper .wp-picker-container { position: relative; } .rwmb-color-wrapper .wp-picker-holder { position: absolute; z-index: 99; min-width: 255px; } ================================================ FILE: vendor/wpmetabox/meta-box/css/date.css ================================================ body { --mb-color-datepicker-primary: #23282d; --mb-color-datepicker-border: #23282d; --mb-color-datepicker-active: var(--wp-admin-theme-color, #2271b1); --mb-color-datepicker-heading: #fff; } /* Fix empty block below admin footer (issue #24) */ #ui-datepicker-div { display: none; z-index: 999999 !important; } /* Style for multiple months */ .ui-datepicker-multi .ui-datepicker-group { padding: 0 .5%; box-sizing: border-box; } .ui-datepicker-multi .ui-datepicker-group .ui-datepicker-calendar { width: 100%; } /* Date Picker Default Styles */ .ui-datepicker { padding: 0; border: 1px solid #ddd; border-radius: 4px; } .ui-datepicker * { padding: 0; border-radius: 0; } .ui-datepicker table { font-size: 13px; margin: 0; } .ui-datepicker .ui-datepicker-header, .ui-timepicker-div .ui-widget-header { border: none; font-weight: normal; } .ui-datepicker .ui-datepicker-header .ui-state-hover { border-color: transparent; cursor: pointer; border-radius: 0; } .ui-datepicker .ui-datepicker-title { margin-top: .4em; margin-bottom: .3em; font-size: 14px; } .ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover, .ui-datepicker .ui-datepicker-next, .ui-datepicker .ui-datepicker-prev { height: 1em; top: .9em; border: none; } .ui-datepicker .ui-datepicker-prev-hover { left: 2px; } .ui-datepicker .ui-datepicker-next-hover { right: 2px; } .ui-datepicker .ui-datepicker-next span, .ui-datepicker .ui-datepicker-prev span { background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAADwCAQAAABFnnJAAAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAAAEgAAABIAEbJaz4AABe4SURBVHja7V1diCXHdf56vbZmVl6nxwKFO2yyq1mM4qAwM7oDsR6C7iYIKesH3V1QHgyBu5YYJwHjrB9NQCuByIthHbAga6TZxeBgHMJKISZ+SDIb1oQgRtoVgtjGyD8PmSGQMIpfJmCLk4f+q6o+daq6+965P1VfM3Pv7VN16ud8Vd1dp6o6IUSEjBPTzkDEdBEJEDgiAXT0QOhNOxPHiUgAFT3sA9gPiQLjJsD0208Pbe9rM/OvwkaBQvP0yzhG6ASQO0AqDwmu9mOPT3nqPWsYV9qFEduVIDP/QU4BSfMC9REqAcbRAa520FDELdphc3SJCyRIcADgAAkSQXOXMs4ckrIxFEUs2oENBNSqR0WmJ2kVv2hltvRdaVPHvPtqdpVxjlD1AHIH6AupDbovH1nqkgllLd3apnQJUjV362dmDEnjOya5FUltsEqqbdtxa5Dbppx3uQ+sNLv6mblCcwLIoKlXTQ/7rQkmX4IKzdMv4xgxbgLMO3rYXyTzuhEJEDjiSGDgiAQIHJEAgSMSIHBEAgSOSIDAEQkQOOJ8ADPutPN/zGgyH8BvRoDLGdMT5wPIKbjN02U+gNsdnuV9oUjSbD6AnwdMrkK7gVYt3311u8zv0r5vfNq1L8xsgPp8gAz20fAilORvs8tdsX3mA0i5k1N3x5dBue7icyGgzwfgvus48OoF+DDu9ukzH0Bqf355s9OHnLMNmqQ0F2jjDJIcrrM+H0Ail6v/KUoe3cECpl85XecDTDv/x4zoDg4ccSAocEQCBI5IgMARCRA4IgECRyRA4IgECBwnp52BmQNNcZS/+1hp4/yf7BZ9IpUwzRyQMwftXUHumFMouX4JIED09fvsD0AtJE3RNg1X/jPTJ6IWNznaxvYrgU+oBnFPaAFcxU88CmCPn3hUkE8RSHD2+OQvEWT6Z7M0Com7BuQSygQiR2zA1Yi1/KuXAN/i22bruCspGUMHT6In0nUV7ZIDKmMnrFRNnUulaF72PJAgl3VXpZObgZrLBGh6E0gerccVyoed7dq4n3ETD+2SgXz0tq0BqQn66HbXQU3e5DGw6uJ8QvEyuQt0M1jW4epi/bpoVwtype5zE9kWboq75VoOTHdw6E8B851+i8fIOB8gcMSRwMARCRA4IgECRyRA4IgECByRAIEjEiBw6ItDi81Spwf3fuCThE8N+HhE28VzrY32TaURKgIUC6N8tntvVwHjQztdrpz71YC01Wzljes1jp35KYvDXoZe6xogI5cA+MWh8hJOH492jzk3PgrYdPltDWHPv18N2NLoGctre41iVyVw9UDdlqbXFujqQ8E+26m7lmDbFoj6zaRx58Cmx72FuzvnfhvS8z63umkTQ+5aWF4Zh1ufSJpm2WFsc1gn9TBNCeBfAUmDuH45kKvQJ3332n57+q7YLgK460A2oJsAMoEsBGj2FFBVQBuPVaLo4LWT9iml3wZVvtveQ0ipr+bS4grO7yAgpV/E5O8BXJqrvRuk9c1mLhvOB5AqQL+BkYovZ04qoqRDLZp72hdnAjcBpRIcGBtIHDTW4AfJvAfla2/8commlwA/XzU5t4iQr4JdYvtVL18Ov2tw9yltkp72L7Vx3wOwiPMBVPScb0xaOEQCBI44FBw4IgECRyRA4IgECByRAIEjEmDcmLPHKnM+gAuSv8qn6L2O/u5Jo3vuEsdg94yVvT4fQILkMfcZJSw8dqseC0zt6Lq4Sl4enjiXv7oNbIsvaZ8SqoEgNVvu3X7rg43q0sh2b//2HWgGJI+dK3ZiDaeetXk7pcWj5CX1L+mxgL8HsE06kP1V1aWhzaSFrOW4p03Z9zAg+Pr6kgZnuXS59N0rm2cS5vsCqips+gZu8xKSNIhbSP2WQLsXb7ffQkIyo6uH8Ncs7RFwzKh6ANVR2CZrrjcJuJ2tXa+OidKD8D2E/smFGE8r5lLQe48ZMb9+CTgoM8V14FkHn0334nEgzgfw8fa7t4eQUc0F4KdUyFVfXYTsu4sUIZOGUjVE2wk1EwHvDSRrB+7jLLXdBI7D2eo3a7HtjabPTSQAB0Fnxrg+iO5gHTPTNR8XIgECRxwKDhyRAIEjEiBwRAIEjkiAwDF7BEhny1u26DAJ4OfLllw25CW1hUhxeCxP4tPeB2Fm0Gy7eJ/tpBOsdMjPIQqSpGK4tlvWV1igN4B3gU4AeZRaHu0uWnWKQ5YCVA6U8mv3sq5/pQxxaIlffGu3qbra+/i9an7BURFA3+69jsofbtsyPUGSm/8DNi25a8+6/g+wIqydLVLn09dnFJha/LaPCA7FULDf6nYJxVwbm/nNuThmL+L6LZ2tS8xw5vYR0lvOg4I6JSxB3Uwm7FMZ/CZE2CeVmQSyTcngc+jaPkEn+IK9Ar4LqhdGqFVm32DE/dYL39dK2OQZBah2H1E4gvld+fX8+Lw2IgIAtz+A38r1ul/evUONJM1uHuUQurbE61wB9w5CgcL/hRH6rNjq+7hhv4voBv/tI4LCrM0HmJT5IyyYNQJEHDNmzxcQcayIBAgckQCBIxIgcCwSAfqlJ6A/Ef0nsZQfzd63OtPICDDMK24Xw9aaXnZ4+l0g3NBmCzQ1Yh975fc9Nna/Ez1O4ld4FEc4wqP4FUuBvjP3a7l0zZKGXe6KCTxnHHIKxtwOoqs0oAENSUUVtjo/JFgOKj+3tbhqCF57doyor8lHmrRPJvqN5HoOudytGfHXDPkSrRPREi0R0TotCTXAp1GHVEP+EjXEtncZyxAFk+8BAO5YJnPcxpdxD0CK2+W5O7hgZeMXLCOKy+W3o5rsJr4htL89ZBtLZNgHYU9LYQ9bSg8AbBlyN95Xcpfl0Ix/H8t4EEAf942wej6BLUbim5suL5+XsYb3y++lpoIA9/NPdRqGmuV7AH6EI3G2z1L+ecMa4qNC7Ct4D9uC/JLmSr6kUDHD2woFtvC2ISWoizP5FYYfxS/K759g8/AgPoEEp4RcXhRkpkeSl/MvoE4YLc0IXpj/D/DP6unqWnboUPAjHNXC6FnICLAiaLO1G8DVAwBvlRQgXMJbTIiCAnXzZ0iNz3rufl3M6Qb+G38I4B+xwcZ/GygpxOdgK++p9N7qOFCY/4+wrFPA936WM3+9AgG5o8razk9ZmasHKCgAi/mRpw7rTd5549PEEn6efzvLSB/Eu9jAfQAbeBcP4f8MuTkLqe0yU3dH7wrxOfxN7Vxm/i/gQQD/AADFBdz/MbBufrOAp3AKp7CMU9ZO8gE8gAcAcC3spsP8QA9v4RIu4S3LdM4+DjDEEAct7/OX8Vv5sVzLXw9nQPgFNrCBEyCcEaeUblmMf075s2EJLrhCfIs5l5H+Bj6G7wAALuBOJmj/RFsv4rIzzg+FkK4eoIcDIG/7B0z19zU5R4HfMD7NKspayQayOyK9n3gY9wH8pPx9HxvCjKIuHfxRxxD8hNmf5OXL7s9K86N8DEwdj1HuR5iXNfnL1scV+2PMjQk+BhYPSdWnLRd95hGQe4hzPeg1fQwGjayl9wmhlpDXXzwEDtSzs+MO7gP4HeX3e5YbqcmCAJxXWvr4tWeYztSUNbyvtX7E+QDBY5F8AREtEAkQOCIBAkckQOCIBFgsvIJXmkXQCZCC4FqYbQeVjoyujxZ9cB71LeXxte5vGxqPvUNDvm3IuUEn1Vu+NgE5APylo34GGLSut9P4Cr6C045QI4wwKn8pdZISUZ/6RJTWBhF2aSkfRrhG6zRkh0Fu5AMR23TDkMuebPPos+G3FE82EdEWOxBSHPX47oGcLMw6rdP6hORFmGxQx5QMqBiQS83hmtw6RNuEvHQpo/suERHdFWu3GEwa0TkCQU+gn4+h1dUT9RqNg3FyENGf5X9XrRXUp2wCSt+iH5YUXAYmAv07ge4R6N+InzJBtJ5L1gU5RPlpWqLTFnlR/SMaNa7BAtusfLsWe5tNf0hEI0qrkUTVHVw4Kfew1WqjFnWuAO85fAL7+DF+gJ/jPYtPsI89XMIbVpduF/wTfhffwwa+hyfwL9ZQ2Vj6hijXxyx1/LLmJ6wwwk0AyP/X6+9Q+8WDn21x1uMMAHwJwEp+eUzxAcoe4IYxmt6nG417ALWDs/UAV4noL4joFbaF9InY1j+uHuBvCfRdAn2Llpj0H3X0AIUcotzeA4y03JmXgIGS6wyDRuX7qib7KlOD5+hcPXUziX5OhHr1j4MAn6HfpM/R+fyvifn1WXE2AqRElFKaXy9N+XeI6Nv539/V5EX5bNfwSv64Q87Hr6692XG+IQFMd10q1JDsatLOmwrUT122RENCyaEBE0ImQN1f18T8ZvFkAvDys/Rdeph26WH6e/q0IV+t5W5trPLK/LAeuolTUW6T3s1vBE35iIpr/25bAsBxUJ6N1DM8b+C+Vb5lVDD3FJCWRecJYidghsccuesih8P8Pi73ggIpI3uKPsxv/LbpQ3qKIcBVGtXj+ibvNqh+H8rfg0qTlmXzmxTYqkld07plORFRz2GcLvKR0/yux8CKAqkl9nPl9+dqsa09kK87eB3v+gWM6IgBoHvsx4QRAOCWeTrOBwgc0RcQOCIBAkckQOCIBAgc4REgcxsPGMmgfDZ61EOPbTfFOburVgmwXlbAemt9NLUqSEHYyb/vwDar4Vq+qHS3RoHfxy4u4zI+hU/hh/h0LWZWO1fzX9mepeq+55v4LAhP4AkQPovNWnx5+4ph7cF+6JC7QgxraRgjQObZdSLapSEN6ZAqpwc34CENZpAzRPtjlOdrnR1UybBDoB1rLorhkHPsUNep8vgYOxa6Q8M8B5meAZO+fRyv8FKklmEw+UwVO7XoycYa+7k3B0z51BjrxXc1QDZKvENEh1YjTpMAxVgWn0Zh9uqzruGaONZ5gj5CCSX0ETrBGmRIIKJB6dPncicTQPWHmCuXMm9Iv6zjOgGgzaKoEyDTul2OyXIEOEOr+cEQYJhX4w4748dFAHJWgdu4cvx1Rcb1UDuKnDN/KuonSspjjUn9eh5rlx9SpWz3kOLgCWBPn8oZV7wGKn2cQwKdYwkAhQB8n7JOm7RZ+isZAuzkVcdP+XIxXA7RTMoTyOVTk1p/NeMpw8CQf5uI1vKD6DqjYVC6bLn0iU53IsBD+dmHyv9m7KL/GhLROUsPYK+/PhGdoTO0Smdok4iuZefV9wV8gBQ38fn8FknecR9OubSbuFvKpbBe7mOSrdE38U38cfn9+/g9TZYqM56AK/UxcazjS8qvl/EzIfWslszyrwD4EADwS2aDGcKKNs/KfMHFI9p5ws8MuT5f6Ca+bMzayrbwzybL7jHb+RMeB/BfAID/VGpX62APaUhD2qXZvAksWh+fxjfL1p/hrhG3n7f71Kp/s2w759jUd+gqUd4Odxh59vmQ5UbPnGhjtt/H6DHjv9x/NL8HGFKfNmmTNolos34JUK+xNvPP/lPAXSrmxnLVM3CksEPbtM1Op0IeO6MQRwESfpln12ohhrUOfGjEPFc7mt0DEA3Lw0IA31Y4LQLIR6q0+rtkes2z1uFTOlv+s57lkFIqbieTWtzP02eoJ9QSEZT7DF22lD8FZP/NbejqBDEpMhSlaum0MkZ3sIqH8BKAF/E/rHSEFdzM32aQ4n/xa9qbDVz3SIC+meUk5j23QCRA4AjPFxChIRIgcEQCBA6TAEPrfuEXcau8obwlbokaMU/QHhRuExHRbeYB5ou1h5AvTuVhLx5jPtQfz5TGfcYIdlF7eixwkVG4R0R71uR+6jkgA48Qx3/sKfTfm3puJkCA21T4nMw+4DWWAK8xCuWBoNowhNX8HEncy6tcIVxyor1yuGiPlfvlf46O6uszmoH1PsCGpgQAgV24WTd/vZ9Q19byBnSFGBHR07RET1s1+JVuQQmQXf8Lr7PeB+gFl6phm2zLwlTz7zKSQfnJXyZcxkFu+DQnAid/Ov/2tKBhT0hjgQkwIBOqAfwJwHfeuqZ7jEeuiGczvy8BUrL3MVSOsNf99RXsBOgT0R7t0R75+BXm5DArwPzelACuozBS3fyZ2W3mn4UeYIFvAqv2nyp+58oMX2cJ8HVGoasHsB1qD8THn/49gJuCc3hwRasX8ilW+hSj0FU5dqnU+nUDj1qH6PoUkIWZutHGT4A91sBqFTxfkz5vNeNASFCiR9ve43iPBSOAvzv4SQzx5/n3r+EN/Ou0xzCnhLbvAppRxPkAgSN6AwNHJEDgiAQIHJEAgSMSIHBEApgYgFpL5xAqAYjZNkEHYVyvhJgWbgjvNgeAAXZbS+cTxigd0a4wGqd6A0xJES+1ahjQbu4IGtCuoAGEfHmTLt/WNLVx1w4cg80Dj9hFDdi1zNXBV5/NhBIB1Hj1ah6UcQb5CntZg50Atvg+BJCksqOnLl2QIWFbIflpHS4CZCasfutSEErjuTTYCGCP7yZAUxPbpfwGDHN58DeBd3AB32hxPbmDC7iAbJ3cBWXMPFHOXhB3wi002OCKfzxYJG9AjeWLfA/gOgK8B1CdQYQ7eElsX5Szv/icL6hPLrbcZ/f57aRziegNNDHArmBiWTqHiAQIHHEkMHBEAgSOSIDAEQkQOCIBAodJAFJeLB4RACoCpPlWqWdx1rLXfjZ0dM0ijZhLFARIcVhuDvMIDlkjb+ACvoYXcejxQglzeGHbGIHcPmZ5hA15je0Q0V8RiOhFyvbFtY0ep+JewtWovOt3/1jl8bAchVGJ7hEI9CINCHSPbG+n3qFzlDllU6tSfqfapXw79dP5n7nT7WmSNlwv5CTKl8q/pdYOocCOkwCA8wDeBAC8BAB4Exs4X9vKdAObuIkreASXcIgruN6oq/mk0ukkqI9Afzz/S8Avvzqd/30S/ObyHwewkstXFmu8fpLIfAEpDnFfedHRPWxgRdsJt0CKQ9zBBezgClvJlO9UX9+t/re13/9h7JU7aXmEDXlXsEvVoukR8Zu4ZL7w7H0VtpfK2ObL6O8Wr883mrQ8Hpaj8AZm78O4jzfxLDbAv5Gjmg1wAWDcomrrX7A1tIuLyh28jmv5g+AbuBZfFh8K4nyAwBF9AYEjEiBwRAIEjkiAwFERwPU+gK7yJ3G9lF/Hk8cun3T5pi1vi1yn630AXeWubeYmLZ90+aYtb31kHxeJQ/U+gK5y10aTk5ZPunzTlnc4skvA5bJDSJQRvMvMNxWm/IU8boIXDPmzin4wZ5/l1FvkSYv4l9n4XPlc5Vfz3zz+20iUELb4klzNBW+VhsgGgqrRoKT2S5dzGSnkCYDnAbyunRmffp/4bv1qiKbxE/ALzKjBb1K01OV/AgD4a2v9FWc38Q7GskhNJYD+Lup6Blxy4AW8DuB5vCZWsK2C3PoTVpuvAdz6ZQJ0r5+kPN9O/jjeUcw/FgKc7K5CwYfK/+YgZ48gQ12O3kZDony2iU8ecV1usj8VZI/jnmb+sWDcl4ARgFtofwno3sXb81fX0K4Ll/T79SCuHsqW/uO4p5l/DD1AdhP4Kit7lfkmyZ8HcBM382+q/HUlFjFnX1ekLjlEOVi5nn+qnX1Vk7jkbeunKB+1lr+jmZ9PtSmCeAyb9mPopOWdxwEWfyBm2gNRk5Z3JgDoSbpeKr9OT9aCdpVfpFul/BYziDFp+aTLN215yyNOCAkc0RsYOCIBAkckQOCIBAgckQCBIxIgcKjOoLrTUcesyyNaQPcGLpffjtjQXeURM4f6JaCb6Y6cGrq13KSzhggNJgFcBjzCkShfxpHSD9ThMqA6JYoDtfT1R1hgEmAZEA24jGVRfoRlkSAEecJE7qGwIq47HjPql4DlFlr02LKGbu3XRaCIhtDfF6BJamFnXR7RAtEbGDjiQFDgiAQIHJEAgSMSIHBEAgSOSIDAMb8E6MUBoXFAJ0D3cTZCH4T+xPPdwz5WJ55KANAJsJr/TRuu1p2Z/2Da2VwE6ATYz/+mC1frjuYfI3x7AEKv9tcMzKokFpl57TQszB/vAcYCfUbQPhLss26WhPlrhi2vUIX5V0X5QbwHGBd0Akg9wGppmuKvWSe8VztTJ1FP0c9RTDd/vAiMAbPUA0TzTwG+PUB3uN/f0cz8PUu4iEbw7QGOA1Lvwpk/3gOMAfqEkB4O0JvJzpXyTt/8jOiIOCMocMyvLyBiLPh/gj9Qphd3t8gAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTMtMDItMDFUMDU6MzM6MTAtMDg6MDApYMCSAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDEzLTAyLTAxVDA1OjMzOjEwLTA4OjAwWD14LgAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAAASUVORK5CYII='); background-position: -32px 0; margin-top: 0; top: 0; font-weight: normal; } .ui-datepicker .ui-datepicker-prev span { background-position: -96px 0; } .ui-datepicker th { padding: 0.75em 0; color: #fff; font-weight: normal; border: none; } .ui-datepicker td { background: #f1f1f1; border: none; padding: 0; } .ui-datepicker td .ui-state-default { background: transparent; border: none; text-align: center; padding: .5em; margin: 0; font-weight: normal; color: #32373c; } .ui-datepicker td .ui-state-active, .ui-datepicker td .ui-state-hover { color: #fff; } .ui-datepicker td.ui-state-disabled, .ui-datepicker td.ui-state-disabled .ui-state-default { opacity: 1; color: #999; } /* Month and year select dropdowns */ .ui-datepicker select.ui-datepicker-month, .ui-datepicker select.ui-datepicker-year { background: none; color: inherit; border: none; } .ui-datepicker select.ui-datepicker-month option, .ui-datepicker select.ui-datepicker-year option { color: #3c434a; background: #fff; } /* Button pane */ .ui-datepicker .ui-datepicker-buttonpane button { border-radius: 2px; } /* Timepicker */ .ui-timepicker-div .ui-slider-access { display: inline-block; } .ui-timepicker-div .ui-slider-access button { padding: 0 8px; margin: 0 2px; border-radius: 4px; } .ui-timepicker-div .ui-slider-access button span.ui-button-icon { display: inline; } .ui-timepicker-oneLine .ui-widget-header { margin-right: -2px; } /* Color schemes */ .ui-datepicker .ui-datepicker-header, .ui-timepicker-div .ui-widget-header, .ui-datepicker .ui-datepicker-header .ui-state-hover, .ui-datepicker thead { background: var(--mb-color-datepicker-primary); color: var(--mb-color-datepicker-heading); } .ui-datepicker th { border-top: 1px solid var(--mb-color-datepicker-border); } .ui-datepicker td .ui-state-active, .ui-datepicker td .ui-state-hover { background: var(--mb-color-datepicker-active); } .ui-datepicker .ui-datepicker-title { color: var(--mb-color-datepicker-heading); } .admin-color-blue { --mb-color-datepicker-primary: #4796b3; --mb-color-datepicker-border: #52accc; --mb-color-datepicker-active: #096484; } .admin-color-coffee { --mb-color-datepicker-primary: #46403c; --mb-color-datepicker-border: #59524c; --mb-color-datepicker-active: #c7a589; } .admin-color-ectoplasm { --mb-color-datepicker-primary: #413256; --mb-color-datepicker-border: #523f6d; --mb-color-datepicker-active: #a3b745; } .admin-color-midnight { --mb-color-datepicker-primary: #26292c; --mb-color-datepicker-border: #363b3f; --mb-color-datepicker-active: #e14d43; } .admin-color-modern { --mb-color-datepicker-primary: #1e1e1e; --mb-color-datepicker-border: #363b3f; --mb-color-datepicker-active: #3858e9; } .admin-color-ocean { --mb-color-datepicker-primary: #627c83; --mb-color-datepicker-border: #738e96; --mb-color-datepicker-active: #9ebaa0; } .admin-color-sunrise { --mb-color-datepicker-primary: #be3631; --mb-color-datepicker-border: #cf4944; --mb-color-datepicker-active: #dd823b; } .admin-color-light { --mb-color-datepicker-primary: #e5e5e5; --mb-color-datepicker-border: #f0f0f0; --mb-color-datepicker-active: #888; --mb-color-datepicker-heading: inherit; } /* Light */ .admin-color-light .ui-datepicker .ui-datepicker-next span, .admin-color-light .ui-datepicker .ui-datepicker-prev span { background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAADwCAYAAADvl7rLAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoxMUIxRjI2RjhCODYxMUUzQTEyNERCMDU1QzdBQ0EyMCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDoxMUIxRjI3MDhCODYxMUUzQTEyNERCMDU1QzdBQ0EyMCI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjExQjFGMjZEOEI4NjExRTNBMTI0REIwNTVDN0FDQTIwIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjExQjFGMjZFOEI4NjExRTNBMTI0REIwNTVDN0FDQTIwIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+kKfR4AAAHcRJREFUeNrsXWuMXsdZnuMu4CUN2S0t0a6o4sQqAaooTncrKGrUNbe2qSC2uQqpqtexbCqI0xaQEBclKUL8qts6stqNkuwWiYqbajtqS9oAuyEISrubrLmUFnBSfmRXFa12KT+cKk2GM9mZ7ng858w7l3PmnO88jzQ633e+8565vs+8M9+8MwXnnAEAMEzsQREAAAgAAIABYkx9OHXqFEoDMDFVho0yTJdhE8UxOjhz5gwsAICk/Exep1AkGAK0DY6G93L+eUblnw4gATPNqMceEsBURMVxSwhFbO8TEj838j4V8B6eQHF1RWyzDnTl3zRIIDTNsCJ6RABdMf+mM6XBjNfsDXP1wm2hkEGN+ze1eyFpngYJ9IcAYs0/vQEVkenz7X1SwRZv2xNhqeJNVRcxac5Vj0AAAcSYf13pBVMMPfS8xyhhaFpy9pqhQ6CqNOe0ZgBPAgg1/7rcC8aQQJEx7lzkGzoEqkpz7noEPOcAmhhPxjTGzcA42zR/m0jDZkSPGZPvmCFQVZqh/B3EWMfTV6CKvm2F5LJAQhYCmWlGPYIAAJAPMMQhAAAAIAAAAEAAAACAAAAAAAEAAAACAAAABAAAAAhAA/zI8+wHoMcL772BEkBsA0i1J0CsM0yIAvGa0CZ55doPIIU7uF7uIJKeEUCKBpDS6yumEW4kTPt0S+mOVf7YtG84voekHXsB9IQAUlXeZgMk0JYC2dIe6swS2vBTK79P2mMdmTZayBPQEAGkrLyUJDDdkvLb0h7ryRZCAtOZlD/F8G264TwBDRJAURNYJhLwbcSpepqU+wFs9KDcqhR1OkHa4Q7cQbTlDRjjVRa6H0BuFInKbTqQ0IpE8YYqrl7n8CgcOAHkVKK+I+d+ACj/AQ4BAAAAAQAAAAIAAAAEAAAACAAAABAAAAAgAAAAeg1sCw64IJYBFwPNt4li1Mp/DJUPBSAoQUwZ8AwKlCLOQdT5HmLlh1ZCikM6eUsyOXqUJvMRW/660hcRaUlBHDyjEqdsuzxTW+O+BJCi8lOdyRcSf5GoAaWqhJAelCcsvyKB8sQocmzeU7SBWAuorbabmjxqy3+spcrnERkPbUhFR8z3UAVIMQ7NVQbcEneRIO/UvBSW/PuWAw+U54naQJFgCFZVlgV1DiDH2LlI/K5UzNlmL55ScYtEaQ9VoFTpbbsNhHaCqdKdoh045fe0pPxFBiKJnXtIwcAx6SgSpD+VCR3bA8XmPdUkZB+sv9TzGLV135QFUHTgXTl7z5Tx5yzH0PynznvRkTJscx4lZvhHjnesw4XXFRTIP/I/qvFiJSAADBggAAAAAQAAAAIAAAAEAAAACAAAABAAAABDIwB1suvQT3WNXU3YZ6RqA6m8QtuML/Zk6N60P8rhoBs9bABdJZO2G05omadsA0Vg/DZvuKkW4lZyKY7GM9Ocwx14inm6A28Q7zVdCSGVzztKAr7pmkqYh5DyT9kGeIDy1x1QO9Vg3E1YQDmPRXceklt3OGjV91w9H6Ugiw5aAr6706Q42Ti2/FO1gZCdeTYqLBkfIoptBzEWUGia60z/UEvOVZaNTwKGNIC6sVdo5fNMSp9SAXwbQS4yrMt7G+vbiwTtILUV7Itp4r1G5gCaVP62HCtiG38KBs6xFx5FCbpo9VQ1dNv4e7qFdhBjAcWmWcA8Xj3FMe/WuYw9HWwAdZMvoZWfk4FTKUCKrb24R/2lMEFD0rtZU9Z9PCo+9nj1IlDeVZaNEkATPb5vQcb0eKkYOCQdmyy9uedbH6kIkEeUv82nfbPFNKQq981Ew+DQ4V/tMe9jDTJnFzazYJEkkGszkk2WvucqPOOf1sa9PgTYtf0D+riZSGvx4mAQoE0SAjoGLAUGABAAAAAgAAAAQAAAAIAAAAAAAQBAVnAUQfsEkMobLdSjKlWl6/GjIYUpX+6yCz0hCfUeSACpvNFCPapSnYmnxy/eN83SHFLat14s9njwgsUf8JpCgXlLaR88AVR5o/n6NKf2KQ+NX5GJz8KWlCfqhnok8kRxhypwEdgTV3kDxigwi6w7kECCOQDfjQ1iPKpsCt/WxgrcQn4pThj2aYS2k3lTmNJNPEvNrw+BxJ7KDEQQQJ0LYRs+0dNaXLEbK8QoSpHAjCwSKVauHoxnym/Kd6QYjgyKAKq80dpi4VhvuBSurLlNxqLCAuEtNvqu9cQ8sO5SHfM+qCGAbbzssyXSlFFpIRsihO4HkMqVNbbx8wQkEDoOjm30tmGQ7xCCB86rxMjWkQCD8l8NH2/AjcAKjPGlZwHviXFlTWmG6uWQwowtAuOPSXusK23oxjAxsk0ORwZNAG1MIqV6X1dcWYvM70mhwLn86aGwGYcAAAAlBAEAAAACAAAABAAAAAgAAAAQAAAAIIDRxwTD8lFgoASQ0g871LGGJ5T1fYdQ/i02On+HxZ50CwyIAGIP1kzpCDOZqXy2LEQyEamAOWR1bIAEAAoBxKyfjlnPbfbUqhee9FAUcxmpz9l6usk/aXnHlmf85r0YQk1lPW2g6QNVBMAjeyCbPzj3JBSlbLryb0dYH769vpLflnGHnCxr5t0n/3V7ErjSkmo7N2AAGCOY/TygF09hRTCL8ucYi2+zdA41VOWvKjdX+ZvbsBUV9TuNpg/YCMBstFWffUzQWK+0WMSOu32tj7q8u8qhqpenluFGTb4LTfk30fQBGwHUKV0R0fCLSDLIRSCFQQKcMBfBa4ZCrrzUlU8XdtcBBjAH4OqNQhXWd0+8mP34YuQnLbJbWh62CUpW1NwriKQTgqrt3KD4gDcBxI7fQ7elKioCi5APGfPrsqn+hiwSP2cidjs1AEOA6IZYJG7UOREzB5ALmww9PpCIAIYOKBIw2CEAAAAgAAAAQAAAAIAAAAAAAQDNYoZdvZZhpkfpF5PLe42ACeeOE8Aho8Ety3tt4/0szoc/FiKuBVa9l8BMC8q/arm/6hH3TEbyEIr+rTLcXIbLMtws740Fpj8kHzcZsjd55iNEPjZOgV9whJg8XKVLeoWcK8P7yvC0/D4h79lg+3vskOX5w2U475no32dXH8t1kvktB64jDNc75svwL2U4UfH7LWVY81ReHbMR8qsOef250KPNRKO5VPP7/jI84yCA15dhvQzj8p4ggQNl+LIkAuaZfp98VNX9JY82wCxlcIkgFyJj4s/l9aTsiFLWY1FHAExTfoEV5rcCjkog4r0HA5jRlwTGLfcuE+QWy/BgYO+3qhW0uSJPnXa8WpMHpeCrNeSxyppdn3Cpouz0MnTFr5T/Go3Y1h3vrStPlXcKmjiVqm+Hy1aROLextVlxOrY8C1kp/5dlQwldQrvX+L4Q8I7vCIzbZQG4cLiCqLj87ZxDfq2CBCg9P69ogL7nFIqy+4bl/vd4lMM18nkR33cHluUdEcO4GIIIdYcviGkpWlT+nyjD39SZa4yo9FQo5Xe9pyASwGRg2sYD0x9jAQh83kICSvk/T3yHSQIU5dcx4fhOKbvrI8pUmPtfK8Pb5fe/kveYR/6ZhYR8ymDWsKhmCcOzvsNU/l+UdVZJAqlnZqnK76O8oeaU3us826IFYJIA81R+G0n6TuLtd3ynWGD/bdy7waPnvygVfl0jBHHve8vwPLH3rduZqs0l2inM+dh3/EoZPu45b3FSG4J9Urt/xfC7ib8Btzwadp3yqjCuffbBd2nBpwdbjFR+gSmNBJTy+2zEKRReOPUckmGTtTuTL8rpB40wTig/kcfvl439G1LxD8h2xuVvoRuSznoq/r6Ka+xwNMc7/iSA+MWw+TvZ7qSiUv6VJi2AVJM04wni+VLgO2MtgCm2u+OO3utvEhv/TI08lQRe6/juakSXDHNenx+qsya+T3vO9k/BunxfyI5Eucz3y5nf4bMvxzNG/S3UKX8oAcxGmDkU5f8DqYBVv6UimSbmACjjzNkG5XVFrPvuakT63MWYTJPr7z+dJFzPuCbSeIK6/cuKK7UTWKy43+Y7QvCMhcStyv9yYXK+U9anTp1iwBXj7VsqfhfktDaQsuBar/9MT9OeqmPoG9SEoFX5z5w5k20I0HWsGdcho0Dae4tnKGUAXwAAGDBAAAAAAgAAAAQAAAAIAACATuAPZchCAOqU3NgjsUNg+i23vSeADcpHnbIYZ5bZ/bAp/+EfYtV7EXDm3qPhhEOeusCpypf8pp7IK/xRZPuZk6FtXFuG35Hh2sh3HdXCFRirUf4trcFST+gVm4gIBxB95dP9bMcD7kZ5pfhzi4U4a1qlndQUsKiRUygaUH61QMfljivK7AtGWlTaxP03svrFPue0PJtYIJShy3NygdEWOqmFJLoTzzqj+7jnllf4baNNCCVYIij9smzzy/LepNSDykU1hu6oOnxQku6C9h7KOROfNj7fHqH85oIkkf6vvFwoloVAuvLr3mirhMSLlwk/+Lrz50M3dPCRV0r3a2U4q13FfgWnPRvQjCQjteGJyzOv6mBPah4oPVVByP/nyvCjbMdF+7Yy/EMZfozRnWk423XiUTK3MvdKPpu8Qoi8+D/7BbbjonyTh7zZ+NUKvMWG26Ape9JCykWN9eYi8JOMvlJVtVmR9/NSr8XnpbqFQKbyq15vVv7WxgKLqn0EfLwM3ySJ6D/L8O9sx7tNrOJ71lP5Rd7Vzka+brm58Ndl+JEyPCaV6DFZHn8bOBzTFTJUXuCWAHmh/M8HyJk936Jn+9vybJuhFpmOGxI9o3CPluZDhpWybZsDWGDV69EVCSy00IC3ZdiSYZv5H8/1j2X4uTJ8VjaGT0r2PBeg/Oc0S6AP+Em2s/b9bdJ8FFfhTkrdYONmS2/lQ/ymvAqvCJAXPf9e5rfBy9EahXetxZ8zlN88X3KrwTmB3y3DB2p+/4B8xoV9Mqh0npblMS+HP9tVcwAnLeNZphHCWsXYtItQFsBXy/BP0pQU138LUP6Ynp+zMH/wSW3uxdcCEi6gP1+GP5VKL66/xGhuqcJj8UvamFu59CrzPUReKP6LEfL6HICv8psK/2QL1utWgHWr8Jtl+I2a30LIr5K8Xb4AIY1+SzOZ9xkm98EWFH+WoGwfb0n5Y0nAtIqo+C22sxmEmNi5Xl7Ffgq/V4YjNXJi/uY5456pdPs7LG9T/iXPcl4xlJhbFHjbUU9VJECZANT/cft7eX2zabo78q+P+VfqImvCGeh5trsT8Fci5wxC9hRci4xTWTuhyi9m+b9QMxZ+Y8PKr8qdSetHv/6MQ+45Y7z+r57x5pZf1Ig2RPkplhZlHsxGAtTZf9E+XirDu9nuZJ+YHPyI/O1xot6oMf9hXwKo2hBR78maxMmantJn+GGm1TftoT3/ag0JuP4CVD3cJa3xbHn0gLp83e8uiJ54M6IOc8nPJ1B+ZakuG0qs/w1IJW19GEclcTHp+ctl+Avt3oPyPS8Q33FaK4/aeFPvByDGiRcZAIwO5rShQR9wVPtcSYJN7QcA5QdGDSs9S6+X5QNfAAAYMEAAAAACAAAABAAAAAgAGCno7sVzRJk5drUb7s2J0uPzV2wX3MAHSQC3WhrArRnSxwfYCNQ+DI8Y9x9h/nsz3Meu9H1YJpDAj8vnjsjwOhnE8twfIsSpt533Vih/YQQdwnPxHVL+TTJwee82QvwzlrZLPVDFtReDaz8GinzsOw556g2v0yPbOgC15nulDB+W9xZlwzPdOykJ8WV9m3zMO3LgqCwzVV6qTCkLVPQ8i3cck8o/71kWKg0KYj+GZwnyIv5rLPe/VYZvMporrYj3UUk+qgz09NT51KdwBzdXkFK9WDmju5tT47Zhy/EOtZpR30BmVbtfEPJvi+Pb7thqHYDNAlDKLypJLOn9Wba7BnmdARQsamV5VCu3RQ9ZJpXeVH6qW+s+47uPG/TzUtkvy/BNSQBUPMp2l4NPsqv98ldaqIP9bNeblHlaA+buT75W6LbMp+7J6uPRyo20zBDJ0YQ4i3FaC/9DHQJ8WDM71RFH8y0pT5W50sZwgBODCwcqFJbiT3+MVXuzKYuAMoy4N7IcXtK+v8Toh2t+SPb8qpzuNZR/ifCO8Yrgg1XP+wp72ZW7P+3V4qce8inK/7Rm0jPmdzhpETF/UkjiEW3tNWzHGew1WrgCdSsBdeU/Rhx7VLFUm6Z8ivMJY3GRXX023LzH8OlYpPLbNnVhmvldhz+TCm/6DFySyu2CGPdfsMw5+KzPF77/L7A8uMby/Wvy86uJ73iP9lmQofIsvZFoBfAKsqJ0Pspa+LpG3nuk8j/Fdrboq50D4DKRE0ajU5XZxpZeLOIdvEFZah6qfOepcyh/XIZ3Wu4L99DbA5WfqoAi7fdU/PZ+tutp6Jt3KoHp4+gXtfsvyOEIdQ6gapztGsPfWPM8Z/UernrcVcO797UwB/AG+fmr2v3n9LZbNwdwQBvzPyp7fqX8B4jKYc7uVs34UuV93lE4QowsNQ/rFSb8eoDy61aE8At/0jG5pCv/QdkgC4/eVxDUAzLdeqAov8qjauhM63HUfAZ1DC3C/7GdM+5f4WF+zzK/reNMvFKGZ+X1WuNzDKjD6Ng5gBukbl+vBSaJgbuGABeloq+zK/9C8v0HYMhQ5r8qs6fZ7r8ALrzT6PFFr/k6trspxJuJY1/X7rV1eFqm/3Py+w8QlV8nsRU5Dl6RQ4ctLf/HPN71dc+0rzH75itiQ1HXCcfCVNePprd9PkwYgt3o+J3SCXKP+za8lmTKNnw8+FD/BoyBMuNNc/9Jqfx1vuVc6wXXEtWdb/nr/1psa+NefbvsPTUNWd2/qwxfZDubuW4GtCVlKt9kmcsoHJOAr2e7e2Ay7bPYTq5ug9JDjLbnpNoxK+QddbKUoewVQ4CmjwcvMsv3EdsV+b695fJ6tWa++/yjIHr3v5NEtaiRldog43/LcB1hMuzhyPRXbQ3nOpzleXb1rlLUcj2foA7Ot6k3YwwAqk3vXw+UXaohN+ZQ/lQktsaG2YF4Ab4AAAACAAAABAAAAAhAwyFGXwGocIccA5rLZ5cY/WQaAAAyE8A5I1Bwdxk+VYZ3WX57l/ztbhQ7AHSbAN5m9PyH5D1Xz3/GuGdbOXfGwxJYldbDakDenjUskLkE5TWHJuNVb2ZYRdH0gwDUARyTbHddtutQjiMe8VKfnTGuPthnfF9OoPzLRBI4ajT8owHxxb4jVl4p7IxFuV2Y9bwPdIgA9N5f92F2WQF3VTQiTnw2NZT1MZngXXMagbhIQCia6bO/6KmAse9Q8qK+xuV1MYAEZiy9+QzUZrQJQO/pJ9iVa5dPBiphKE4GxqunXy0/XQk08+cM68G1xn7R837ds/OSwOY936GU/zNsZ2XbZzQS8MUa1GQ4BDBnjP31HVWUFdDmOPg/jKsvVNqFI85hovLrPbyv8qfGeWmBnQ+QfcLxndVYbLGbrsxo5LGmkQish44TwDKhB19uMX0rMv5YpTvI3GvPbWZ+TuVXhDvB/P+KFXiL43udxRa7hHZBU3jdnXUBKtddApirMKEnCGaywFmPeKnPzrG4GXzVmCm7sKywK3fLCVX+ec/7dc8uSitm0fMd4rnHyvBWtuPd9lb5PWRbt5mEMrAAOkwAyxUmtG1zBduzF2pMSsqzrCaeUKvD15w1SSCk51+yKJrvcdWx71jSSOCypvxLnuUnTPdZwzKgzAmYlkQqywJokADWPBuGicfLcJwge1w+SzXdGaOfyZ5q2HEw0uxfMhr9UoZ3xMoXzL6vAP7KGyGMJa5Y4cP9X3LM+h7jN7ErjJjMesJTGWN6jSKCBNBbAYMigFR4Qob3ongBEGl/hgAAAIAAAAAAAQAAAAIAAAAEAAAACAAYIOZYuG9AjCyQkQBEpVF931nNO3jNd6B5LLC49fdzLHwVZows0AELQFVgLBH4koYZ30RAGlTaJyz3eEAaFE4Q5U/UpIl7lIXvseRmfCdkmOuI8nOGXZV6NwRomwjM+IQjz0FNeeYIJucy2/UADEl/yjznIFJmKKCPInOtDEOtvirZAlZBf+cAVEM+0eLYc1lrMIXWmHlNz20+G6N4ZhpClLBtxWc15ZMTGP71nABWZK/6YEtpU/EdNBrQQWZfXlpUPBvjx2+mwRex8Y8SsCS4pwSw0nJDNuOb0Ex61+YgKxoRqDmAkPSnzPNKBiIoKoKP7MGIeA/WWAEHoXYdYuWK48G5bKz3RzRa8zjn2KPCgXhz27fs5yzDqjZkgYbhOh48RYUVMAF7b26vaNZUm7JAB+cAgGFihWFfBRAAAAAgAAAAQAAAAIAAAAAAAQAAMJoEEHqyLQAAPSUAsXruHu37DTJMeLxX92C7z1MWAIBMBKBO0zXPortR3qcq8gG2swhEnAVwr5S9NUF6XQ4lJ5jdjVaFEyMuDwBeMFcCnpbXfzbur2i/HyO896ImJ5YTn2M7J/Qe0H5rAmLzi8JBIPpptaMmDwDBFoDo3eeloqohgDDf1Uk+6/J3ihWgeqxH5PPKEWY9cDjg40oqDsO8Vl71z+I6XoZVh/y1Mj79HSr4yvMI+b2WK0UeAIIsgP3yqh/ceb/2+YLswfcTeiDx3G1s51TbeTmEOCyHAuL7BxvM06sqCKQgEskrjWthvIMRFFi/vsqTxFS8k4b8JMOyWqBBC+CSvN5Z8eydxnOuIcCS1ogFEWzL6+mGen6F6yxhQl43mPsMRPHsD7Pdo9H1dzxHkL9OyutXJe8bv/4eavwAEGQBbEszfY7t/PW3pP12VPbqK/I5quIWsucXcwD7yvAoCzujnoqTZfii4/e1EZYHAC+Y+wHcKsfpasx/Qfb8BzTT/qInAajvaiOIZYIpq5vstisAABGo2g/golTy+9jOX4FK8c/Le9QZ/Lq9AAoP+aorAACJhwA6CRxG0QDA6AO+AAAAAgAAAAQAAAAIAACA4RLAHWxnDYDpiLIkf3Mht/xb2M5KQ1P+g/K3UZfve/0NXb5VmOsA7i7DGYeMePCBit9yy99Vhocc8sfL8PCIyve9/oYu3xrUOgCdAAQ7fYoo/44yfNrCfDnlf6oMnyXK/3QZHh8x+b7X39DlsxCAPgQ4YrMQmH3xzRHivSq45I+zqxcPHXfI31mRfkZ89k6P9PvIFy3Ff8Qjfmr9FQnkWab411j1sWi+8RcJ2n8RqCutDQF4TaI5oXJ9HXfq5AvNJGaaycs948+V/lTxp0h/1Tuajr8gposFps8n/iKg/Yjff1X7/tGA9mc+Kzxkn3KQY6sWAPVosMJTSaoyR5XnxliXMjZ2pYdHKHcIScRWcJE4/b7vSJl2lqD9hKSfW0jABx8xCMAHb5DKblP+zmCMdRcvVnxuAzyBhZBKgXIrcEgHkKL8U8Qb60D27kA5ofxPd1356wggtgJ4ogZ4VF6X2O5fKzENKpQEeCISaav8eKTyxhIgz0AaLgskxIL6aGD+n9JIoLPKL6BPAp71kDtLvBcqr8b+izLo96rkH/ZQpoeJ93gCeRYhzzzkz3oQCqX+eEL5ttuPWX88g/xTNcp/tosEcMFDAS4Q71XBJf+QpQE+5JD/hIcCfoJ4jyWQ5y3Ff8Ejfmr98QTyLEP83EFATcvrJMAidaU1AhD/Kx8nyBxnV/8H3QV58b/qKYL8KWb/D7bv8n2vv6HLZycAZVrOsZ39/E18SP72sMM0zSkvVliJRRYfs/z2MfnbAyMs3/f6G7p8+5MlxlJgAAAGANtKQAAABgYQAACAAAAAAAEAAAACAAAABAAAwIjD5QtgA2V9O+Tj5AEgKwEIjFvuXfZ4d255AAASDAFyKt3lBGnI2ePiSDOg1wQQq4CXtRCCcSk7nkkBq7aEokI/1BQAekcA4zXmOFWBxyPkL2skEKqAjMXtI8BZvg0pACD7EGA8Y/rGE6QhZ+/LO5AGAKjEWINj/9zyAAAEEkDKDS0hDwA9HgIAAAACAAAABAAAAAgAAAAQAAAAIAAAAEAAAAVTDAuDgB4QQBdWsYm4Z7TrKCj/Rhmm0fSArhPAtHFFzx1Hhrryb6I4ga4TwIZxHbryx/TcUH5gEBYA13rKumvTwwZXCFXejQTKjzkAoDMYc1gAhXaloCBem8RsQz1/iAVgU37MAQC9IIBQC2DaojTmtUkzeNWDqHyV34cM65QfwwAAFkCHLQAoPwALIMAC6ALWEryjSeWf8nwfAPTGAhgVhFouVOXHHAAACyBAEbsO08x3fQeAvD0d5/hHCgCGCvgCAMCA8f8CDABatG6NN+gY2wAAAABJRU5ErkJggg=='); } .admin-color-light .ui-datepicker .ui-datepicker-title, .admin-color-light .ui-datepicker td .ui-state-default, .admin-color-light .ui-datepicker th { color: #555; } .admin-color-light .ui-datepicker td .ui-state-active, .admin-color-light .ui-datepicker td .ui-state-hover { color: #fff; } .admin-color-light .ui-datepicker td.ui-state-disabled, .admin-color-light .ui-datepicker td.ui-state-disabled .ui-state-default { color: #ccc; } ================================================ FILE: vendor/wpmetabox/meta-box/css/divider.css ================================================ .rwmb-divider-wrapper hr { flex: 1; border: none; border-top: 1px solid #e6e6e6; } ================================================ FILE: vendor/wpmetabox/meta-box/css/fieldset-text.css ================================================ .rwmb-fieldset_text-wrapper fieldset label { width: 20%; display: inline-block; } ================================================ FILE: vendor/wpmetabox/meta-box/css/file-input.css ================================================ .rwmb-file-input-inner { width: 100%; display: flex; align-items: center; gap: 5px; } .rwmb-file_input { margin: 0 4px 0 0; } .rwmb-file-input-inner .button { margin: 0; } .rwmb-file-input-image { width: 150px; height: auto; margin-bottom: 4px; } .rwmb-file-input-image img{ max-width: 100%; height: auto; } .rwmb-file-input-hidden{ display: none; } ================================================ FILE: vendor/wpmetabox/meta-box/css/file.css ================================================ .rwmb-files { margin: 0; overflow: hidden; } .rwmb-file { display: flex; align-items: flex-start; margin-bottom: 12px; cursor: move; } .rwmb-file-icon { width: 48px; height: 64px; margin-right: 8px; border: 1px solid rgba(0, 0, 0, .07); display: flex; align-items: center; justify-content: center; } .rwmb-file-icon img { max-width: 100%; max-height: 100%; height: auto; display: block; } .rwmb-file-title { font-weight: 600; text-decoration: none; } .rwmb-file-name { margin: 2px 0 6px; white-space: nowrap; } .rwmb-file-actions { font-size: 11px; } .rwmb-file-edit, .rwmb-file-delete { color: inherit; text-decoration: none; } .rwmb-file-edit:after { content: "|"; color: #dcdcde; margin: 0 6px; } .rwmb-file-delete { color: #b32d2e; } .rwmb-file-input { width: 100%; } ================================================ FILE: vendor/wpmetabox/meta-box/css/fontawesome/icons.json ================================================ { "0": { "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Digit Zero", "nada", "none", "zero", "zilch"] }, "styles": ["solid"], "unicode": "30", "label": "0", "voted": false, "svg": { "solid": { "last_modified": 1684767246, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M0 192C0 103.6 71.6 32 160 32s160 71.6 160 160V320c0 88.4-71.6 160-160 160S0 408.4 0 320V192zM160 96c-53 0-96 43-96 96V320c0 53 43 96 96 96s96-43 96-96V192c0-53-43-96-96-96z" } }, "free": ["solid"] }, "1": { "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Digit One", "one"] }, "styles": ["solid"], "unicode": "31", "label": "1", "voted": false, "svg": { "solid": { "last_modified": 1684767244, "raw": "", "viewBox": [0, 0, 256, 512], "width": 256, "height": 512, "path": "M160 64c0-11.8-6.5-22.6-16.9-28.2s-23-5-32.8 1.6l-96 64C-.5 111.2-4.4 131 5.4 145.8s29.7 18.7 44.4 8.9L96 123.8V416H32c-17.7 0-32 14.3-32 32s14.3 32 32 32h96 96c17.7 0 32-14.3 32-32s-14.3-32-32-32H160V64z" } }, "free": ["solid"] }, "2": { "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Digit Two", "two"] }, "styles": ["solid"], "unicode": "32", "label": "2", "voted": false, "svg": { "solid": { "last_modified": 1684767245, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M142.9 96c-21.5 0-42.2 8.5-57.4 23.8L54.6 150.6c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L40.2 74.5C67.5 47.3 104.4 32 142.9 32C223 32 288 97 288 177.1c0 38.5-15.3 75.4-42.5 102.6L109.3 416H288c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-12.9 0-24.6-7.8-29.6-19.8s-2.2-25.7 6.9-34.9L200.2 234.5c15.2-15.2 23.8-35.9 23.8-57.4c0-44.8-36.3-81.1-81.1-81.1z" } }, "free": ["solid"] }, "3": { "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Digit Three", "three"] }, "styles": ["solid"], "unicode": "33", "label": "3", "voted": false, "svg": { "solid": { "last_modified": 1684767246, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M0 64C0 46.3 14.3 32 32 32H272c13.2 0 25 8.1 29.8 20.4s1.5 26.3-8.2 35.2L162.3 208H184c75.1 0 136 60.9 136 136s-60.9 136-136 136H105.4C63 480 24.2 456 5.3 418.1l-1.9-3.8c-7.9-15.8-1.5-35 14.3-42.9s35-1.5 42.9 14.3l1.9 3.8c8.1 16.3 24.8 26.5 42.9 26.5H184c39.8 0 72-32.2 72-72s-32.2-72-72-72H80c-13.2 0-25-8.1-29.8-20.4s-1.5-26.3 8.2-35.2L189.7 96H32C14.3 96 0 81.7 0 64z" } }, "free": ["solid"] }, "4": { "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Digit Four", "four"] }, "styles": ["solid"], "unicode": "34", "label": "4", "voted": false, "svg": { "solid": { "last_modified": 1684767244, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M189 77.6c7.5-16 .7-35.1-15.3-42.6s-35.1-.7-42.6 15.3L3 322.4c-4.7 9.9-3.9 21.5 1.9 30.8S21 368 32 368H256v80c0 17.7 14.3 32 32 32s32-14.3 32-32V368h32c17.7 0 32-14.3 32-32s-14.3-32-32-32H320V160c0-17.7-14.3-32-32-32s-32 14.3-32 32V304H82.4L189 77.6z" } }, "free": ["solid"] }, "5": { "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Digit Five", "five"] }, "styles": ["solid"], "unicode": "35", "label": "5", "voted": false, "svg": { "solid": { "last_modified": 1684767247, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M32.5 58.3C35.3 43.1 48.5 32 64 32H256c17.7 0 32 14.3 32 32s-14.3 32-32 32H90.7L70.3 208H184c75.1 0 136 60.9 136 136s-60.9 136-136 136H100.5c-39.4 0-75.4-22.3-93-57.5l-4.1-8.2c-7.9-15.8-1.5-35 14.3-42.9s35-1.5 42.9 14.3l4.1 8.2c6.8 13.6 20.6 22.1 35.8 22.1H184c39.8 0 72-32.2 72-72s-32.2-72-72-72H32c-9.5 0-18.5-4.2-24.6-11.5s-8.6-16.9-6.9-26.2l32-176z" } }, "free": ["solid"] }, "6": { "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Digit Six", "six"] }, "styles": ["solid"], "unicode": "36", "label": "6", "voted": false, "svg": { "solid": { "last_modified": 1684767247, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M232.4 84.7c11.4-13.5 9.7-33.7-3.8-45.1s-33.7-9.7-45.1 3.8L38.6 214.7C14.7 242.9 1.1 278.4 .1 315.2c0 1.4-.1 2.9-.1 4.3c0 .2 0 .3 0 .5c0 88.4 71.6 160 160 160s160-71.6 160-160c0-85.5-67.1-155.4-151.5-159.8l63.9-75.6zM256 320A96 96 0 1 1 64 320a96 96 0 1 1 192 0z" } }, "free": ["solid"] }, "7": { "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Digit Seven", "seven"] }, "styles": ["solid"], "unicode": "37", "label": "7", "voted": false, "svg": { "solid": { "last_modified": 1684767247, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M0 64C0 46.3 14.3 32 32 32H288c11.5 0 22 6.1 27.7 16.1s5.7 22.2-.1 32.1l-224 384c-8.9 15.3-28.5 20.4-43.8 11.5s-20.4-28.5-11.5-43.8L232.3 96H32C14.3 96 0 81.7 0 64z" } }, "free": ["solid"] }, "8": { "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Digit Eight", "eight"] }, "styles": ["solid"], "unicode": "38", "label": "8", "voted": false, "svg": { "solid": { "last_modified": 1684767247, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M304 160c0-70.7-57.3-128-128-128H144C73.3 32 16 89.3 16 160c0 34.6 13.7 66 36 89C20.5 272.3 0 309.8 0 352c0 70.7 57.3 128 128 128h64c70.7 0 128-57.3 128-128c0-42.2-20.5-79.7-52-103c22.3-23 36-54.4 36-89zM176.1 288H192c35.3 0 64 28.7 64 64s-28.7 64-64 64H128c-35.3 0-64-28.7-64-64s28.7-64 64-64h15.9c0 0 .1 0 .1 0h32c0 0 .1 0 .1 0zm0-64c0 0 0 0 0 0H144c0 0 0 0 0 0c-35.3 0-64-28.7-64-64c0-35.3 28.7-64 64-64h32c35.3 0 64 28.7 64 64c0 35.3-28.6 64-64 64z" } }, "free": ["solid"] }, "9": { "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Digit Nine", "nine"] }, "styles": ["solid"], "unicode": "39", "label": "9", "voted": false, "svg": { "solid": { "last_modified": 1684767244, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M64 192a96 96 0 1 0 192 0A96 96 0 1 0 64 192zm87.5 159.8C67.1 347.4 0 277.5 0 192C0 103.6 71.6 32 160 32s160 71.6 160 160c0 2.6-.1 5.3-.2 7.9c-1.7 35.7-15.2 70-38.4 97.4l-145 171.4c-11.4 13.5-31.6 15.2-45.1 3.8s-15.2-31.6-3.8-45.1l63.9-75.6z" } }, "free": ["solid"] }, "42-group": { "aliases": { "names": ["innosoft"] }, "changes": ["5.15.0", "6.0.0-beta2"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e080", "label": "42.group", "voted": false, "svg": { "brands": { "last_modified": 1660014467, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M320 96V416C341.011 416 361.818 411.861 381.23 403.821C400.641 395.78 418.28 383.995 433.138 369.138C447.995 354.28 459.78 336.641 467.821 317.23C475.861 297.818 480 277.011 480 256C480 234.989 475.861 214.182 467.821 194.771C459.78 175.359 447.995 157.72 433.138 142.863C418.28 128.005 400.641 116.22 381.23 108.179C361.818 100.139 341.011 96 320 96ZM0 256L160.002 416L320.003 256L160.002 96L0 256ZM480 256C480 277.011 484.138 297.818 492.179 317.23C500.219 336.643 512.005 354.28 526.862 369.138C541.72 383.995 559.357 395.781 578.77 403.821C598.182 411.862 618.989 416 640 416V96C597.565 96 556.869 112.858 526.862 142.863C496.857 172.869 480 213.565 480 256Z" } }, "free": ["brands"] }, "500px": { "changes": ["4.4.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f26e", "label": "500px", "voted": false, "svg": { "brands": { "last_modified": 1660014474, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M103.3 344.3c-6.5-14.2-6.9-18.3 7.4-23.1 25.6-8 8 9.2 43.2 49.2h.3v-93.9c1.2-50.2 44-92.2 97.7-92.2 53.9 0 97.7 43.5 97.7 96.8 0 63.4-60.8 113.2-128.5 93.3-10.5-4.2-2.1-31.7 8.5-28.6 53 0 89.4-10.1 89.4-64.4 0-61-77.1-89.6-116.9-44.6-23.5 26.4-17.6 42.1-17.6 157.6 50.7 31 118.3 22 160.4-20.1 24.8-24.8 38.5-58 38.5-93 0-35.2-13.8-68.2-38.8-93.3-24.8-24.8-57.8-38.5-93.3-38.5s-68.8 13.8-93.5 38.5c-.3.3-16 16.5-21.2 23.9l-.5.6c-3.3 4.7-6.3 9.1-20.1 6.1-6.9-1.7-14.3-5.8-14.3-11.8V20c0-5 3.9-10.5 10.5-10.5h241.3c8.3 0 8.3 11.6 8.3 15.1 0 3.9 0 15.1-8.3 15.1H130.3v132.9h.3c104.2-109.8 282.8-36 282.8 108.9 0 178.1-244.8 220.3-310.1 62.8zm63.3-260.8c-.5 4.2 4.6 24.5 14.6 20.6C306 56.6 384 144.5 390.6 144.5c4.8 0 22.8-15.3 14.3-22.8-93.2-89-234.5-57-238.3-38.2zM393 414.7C283 524.6 94 475.5 61 310.5c0-12.2-30.4-7.4-28.9 3.3 24 173.4 246 256.9 381.6 121.3 6.9-7.8-12.6-28.4-20.7-20.4zM213.6 306.6c0 4 4.3 7.3 5.5 8.5 3 3 6.1 4.4 8.5 4.4 3.8 0 2.6.2 22.3-19.5 19.6 19.3 19.1 19.5 22.3 19.5 5.4 0 18.5-10.4 10.7-18.2L265.6 284l18.2-18.2c6.3-6.8-10.1-21.8-16.2-15.7L249.7 268c-18.6-18.8-18.4-19.5-21.5-19.5-5 0-18 11.7-12.4 17.3L234 284c-18.1 17.9-20.4 19.2-20.4 22.6z" } }, "free": ["brands"] }, "a": { "aliases": { "unicodes": { "composite": ["61"] } }, "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Latin Capital Letter A", "Latin Small Letter A", "letter"] }, "styles": ["solid"], "unicode": "41", "label": "A", "voted": false, "svg": { "solid": { "last_modified": 1684767246, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M221.5 51.7C216.6 39.8 204.9 32 192 32s-24.6 7.8-29.5 19.7l-120 288-40 96c-6.8 16.3 .9 35 17.2 41.8s35-.9 41.8-17.2L93.3 384H290.7l31.8 76.3c6.8 16.3 25.5 24 41.8 17.2s24-25.5 17.2-41.8l-40-96-120-288zM264 320H120l72-172.8L264 320z" } }, "free": ["solid"] }, "accessible-icon": { "aliases": { "unicodes": { "composite": ["f29b"] } }, "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [ "accessibility", "handicap", "person", "wheelchair", "wheelchair-alt" ] }, "styles": ["brands"], "unicode": "f368", "label": "Accessible Icon", "voted": false, "svg": { "brands": { "last_modified": 1660014474, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M423.9 255.8L411 413.1c-3.3 40.7-63.9 35.1-60.6-4.9l10-122.5-41.1 2.3c10.1 20.7 15.8 43.9 15.8 68.5 0 41.2-16.1 78.7-42.3 106.5l-39.3-39.3c57.9-63.7 13.1-167.2-74-167.2-25.9 0-49.5 9.9-67.2 26L73 243.2c22-20.7 50.1-35.1 81.4-40.2l75.3-85.7-42.6-24.8-51.6 46c-30 26.8-70.6-18.5-40.5-45.4l68-60.7c9.8-8.8 24.1-10.2 35.5-3.6 0 0 139.3 80.9 139.5 81.1 16.2 10.1 20.7 36 6.1 52.6L285.7 229l106.1-5.9c18.5-1.1 33.6 14.4 32.1 32.7zm-64.9-154c28.1 0 50.9-22.8 50.9-50.9C409.9 22.8 387.1 0 359 0c-28.1 0-50.9 22.8-50.9 50.9 0 28.1 22.8 50.9 50.9 50.9zM179.6 456.5c-80.6 0-127.4-90.6-82.7-156.1l-39.7-39.7C36.4 287 24 320.3 24 356.4c0 130.7 150.7 201.4 251.4 122.5l-39.7-39.7c-16 10.9-35.3 17.3-56.1 17.3z" } }, "free": ["brands"] }, "accusoft": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f369", "label": "Accusoft", "voted": false, "svg": { "brands": { "last_modified": 1660014476, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M322.1 252v-1l-51.2-65.8s-12 1.6-25 15.1c-9 9.3-242.1 239.1-243.4 240.9-7 10 1.6 6.8 15.7 1.7.8 0 114.5-36.6 114.5-36.6.5-.6-.1-.1.6-.6-.4-5.1-.8-26.2-1-27.7-.6-5.2 2.2-6.9 7-8.9l92.6-33.8c.6-.8 88.5-81.7 90.2-83.3zm160.1 120.1c13.3 16.1 20.7 13.3 30.8 9.3 3.2-1.2 115.4-47.6 117.8-48.9 8-4.3-1.7-16.7-7.2-23.4-2.1-2.5-205.1-245.6-207.2-248.3-9.7-12.2-14.3-12.9-38.4-12.8-10.2 0-106.8.5-116.5.6-19.2.1-32.9-.3-19.2 16.9C250 75 476.5 365.2 482.2 372.1zm152.7 1.6c-2.3-.3-24.6-4.7-38-7.2 0 0-115 50.4-117.5 51.6-16 7.3-26.9-3.2-36.7-14.6l-57.1-74c-5.4-.9-60.4-9.6-65.3-9.3-3.1.2-9.6.8-14.4 2.9-4.9 2.1-145.2 52.8-150.2 54.7-5.1 2-11.4 3.6-11.1 7.6.2 2.5 2 2.6 4.6 3.5 2.7.8 300.9 67.6 308 69.1 15.6 3.3 38.5 10.5 53.6 1.7 2.1-1.2 123.8-76.4 125.8-77.8 5.4-4 4.3-6.8-1.7-8.2z" } }, "free": ["brands"] }, "address-book": { "aliases": { "names": ["contact-book"], "unicodes": { "composite": ["f2ba"], "secondary": ["10f2b9"] } }, "changes": [ "4.7.0", "5.0.0", "5.0.3", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["contact", "directory", "index", "little black book", "rolodex"] }, "styles": ["solid", "regular"], "unicode": "f2b9", "label": "Address Book", "voted": false, "svg": { "solid": { "last_modified": 1684767621, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M96 0C60.7 0 32 28.7 32 64V448c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V64c0-35.3-28.7-64-64-64H96zM208 288h64c44.2 0 80 35.8 80 80c0 8.8-7.2 16-16 16H144c-8.8 0-16-7.2-16-16c0-44.2 35.8-80 80-80zm-32-96a64 64 0 1 1 128 0 64 64 0 1 1 -128 0zM512 80c0-8.8-7.2-16-16-16s-16 7.2-16 16v64c0 8.8 7.2 16 16 16s16-7.2 16-16V80zM496 192c-8.8 0-16 7.2-16 16v64c0 8.8 7.2 16 16 16s16-7.2 16-16V208c0-8.8-7.2-16-16-16zm16 144c0-8.8-7.2-16-16-16s-16 7.2-16 16v64c0 8.8 7.2 16 16 16s16-7.2 16-16V336z" }, "regular": { "last_modified": 1684767621, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M384 48c8.8 0 16 7.2 16 16V448c0 8.8-7.2 16-16 16H96c-8.8 0-16-7.2-16-16V64c0-8.8 7.2-16 16-16H384zM96 0C60.7 0 32 28.7 32 64V448c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V64c0-35.3-28.7-64-64-64H96zM240 256a64 64 0 1 0 0-128 64 64 0 1 0 0 128zm-32 32c-44.2 0-80 35.8-80 80c0 8.8 7.2 16 16 16H336c8.8 0 16-7.2 16-16c0-44.2-35.8-80-80-80H208zM512 80c0-8.8-7.2-16-16-16s-16 7.2-16 16v64c0 8.8 7.2 16 16 16s16-7.2 16-16V80zM496 192c-8.8 0-16 7.2-16 16v64c0 8.8 7.2 16 16 16s16-7.2 16-16V208c0-8.8-7.2-16-16-16zm16 144c0-8.8-7.2-16-16-16s-16 7.2-16 16v64c0 8.8 7.2 16 16 16s16-7.2 16-16V336z" } }, "free": ["regular", "solid"] }, "address-card": { "aliases": { "names": ["contact-card", "vcard"], "unicodes": { "composite": ["f2bc"], "secondary": ["10f2bb"] } }, "changes": [ "4.7.0", "5.0.0", "5.0.3", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "about", "contact", "id", "identification", "postcard", "profile", "registration" ] }, "styles": ["solid", "regular"], "unicode": "f2bb", "label": "Address Card", "voted": false, "svg": { "solid": { "last_modified": 1684767620, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H512c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zm80 256h64c44.2 0 80 35.8 80 80c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16c0-44.2 35.8-80 80-80zm-32-96a64 64 0 1 1 128 0 64 64 0 1 1 -128 0zm256-32H496c8.8 0 16 7.2 16 16s-7.2 16-16 16H368c-8.8 0-16-7.2-16-16s7.2-16 16-16zm0 64H496c8.8 0 16 7.2 16 16s-7.2 16-16 16H368c-8.8 0-16-7.2-16-16s7.2-16 16-16zm0 64H496c8.8 0 16 7.2 16 16s-7.2 16-16 16H368c-8.8 0-16-7.2-16-16s7.2-16 16-16z" }, "regular": { "last_modified": 1684767620, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M512 80c8.8 0 16 7.2 16 16V416c0 8.8-7.2 16-16 16H64c-8.8 0-16-7.2-16-16V96c0-8.8 7.2-16 16-16H512zM64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H512c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zM208 256a64 64 0 1 0 0-128 64 64 0 1 0 0 128zm-32 32c-44.2 0-80 35.8-80 80c0 8.8 7.2 16 16 16H304c8.8 0 16-7.2 16-16c0-44.2-35.8-80-80-80H176zM376 144c-13.3 0-24 10.7-24 24s10.7 24 24 24h80c13.3 0 24-10.7 24-24s-10.7-24-24-24H376zm0 96c-13.3 0-24 10.7-24 24s10.7 24 24 24h80c13.3 0 24-10.7 24-24s-10.7-24-24-24H376z" } }, "free": ["regular", "solid"] }, "adn": { "changes": ["3.2.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f170", "label": "App.net", "voted": false, "svg": { "brands": { "last_modified": 1660014478, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M248 167.5l64.9 98.8H183.1l64.9-98.8zM496 256c0 136.9-111.1 248-248 248S0 392.9 0 256 111.1 8 248 8s248 111.1 248 248zm-99.8 82.7L248 115.5 99.8 338.7h30.4l33.6-51.7h168.6l33.6 51.7h30.2z" } }, "free": ["brands"] }, "adversal": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f36a", "label": "Adversal", "voted": false, "svg": { "brands": { "last_modified": 1660014478, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M482.1 32H28.7C5.8 32 0 37.9 0 60.9v390.2C0 474.4 5.8 480 28.7 480h453.4c24.4 0 29.9-5.2 29.9-29.7V62.2c0-24.6-5.4-30.2-29.9-30.2zM178.4 220.3c-27.5-20.2-72.1-8.7-84.2 23.4-4.3 11.1-9.3 9.5-17.5 8.3-9.7-1.5-17.2-3.2-22.5-5.5-28.8-11.4 8.6-55.3 24.9-64.3 41.1-21.4 83.4-22.2 125.3-4.8 40.9 16.8 34.5 59.2 34.5 128.5 2.7 25.8-4.3 58.3 9.3 88.8 1.9 4.4.4 7.9-2.7 10.7-8.4 6.7-39.3 2.2-46.6-7.4-1.9-2.2-1.8-3.6-3.9-6.2-3.6-3.9-7.3-2.2-11.9 1-57.4 36.4-140.3 21.4-147-43.3-3.1-29.3 12.4-57.1 39.6-71 38.2-19.5 112.2-11.8 114-30.9 1.1-10.2-1.9-20.1-11.3-27.3zm286.7 222c0 15.1-11.1 9.9-17.8 9.9H52.4c-7.4 0-18.2 4.8-17.8-10.7.4-13.9 10.5-9.1 17.1-9.1 132.3-.4 264.5-.4 396.8 0 6.8 0 16.6-4.4 16.6 9.9zm3.8-340.5v291c0 5.7-.7 13.9-8.1 13.9-12.4-.4-27.5 7.1-36.1-5.6-5.8-8.7-7.8-4-12.4-1.2-53.4 29.7-128.1 7.1-144.4-85.2-6.1-33.4-.7-67.1 15.7-100 11.8-23.9 56.9-76.1 136.1-30.5v-71c0-26.2-.1-26.2 26-26.2 3.1 0 6.6.4 9.7 0 10.1-.8 13.6 4.4 13.6 14.3-.1.2-.1.3-.1.5zm-51.5 232.3c-19.5 47.6-72.9 43.3-90 5.2-15.1-33.3-15.5-68.2.4-101.5 16.3-34.1 59.7-35.7 81.5-4.8 20.6 28.8 14.9 84.6 8.1 101.1zm-294.8 35.3c-7.5-1.3-33-3.3-33.7-27.8-.4-13.9 7.8-23 19.8-25.8 24.4-5.9 49.3-9.9 73.7-14.7 8.9-2 7.4 4.4 7.8 9.5 1.4 33-26.1 59.2-67.6 58.8z" } }, "free": ["brands"] }, "affiliatetheme": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f36b", "label": "affiliatetheme", "voted": false, "svg": { "brands": { "last_modified": 1660014471, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M159.7 237.4C108.4 308.3 43.1 348.2 14 326.6-15.2 304.9 2.8 230 54.2 159.1c51.3-70.9 116.6-110.8 145.7-89.2 29.1 21.6 11.1 96.6-40.2 167.5zm351.2-57.3C437.1 303.5 319 367.8 246.4 323.7c-25-15.2-41.3-41.2-49-73.8-33.6 64.8-92.8 113.8-164.1 133.2 49.8 59.3 124.1 96.9 207 96.9 150 0 271.6-123.1 271.6-274.9.1-8.5-.3-16.8-1-25z" } }, "free": ["brands"] }, "airbnb": { "changes": ["5.8.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f834", "label": "Airbnb", "voted": false, "svg": { "brands": { "last_modified": 1660014459, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M224 373.12c-25.24-31.67-40.08-59.43-45-83.18-22.55-88 112.61-88 90.06 0-5.45 24.25-20.29 52-45 83.18zm138.15 73.23c-42.06 18.31-83.67-10.88-119.3-50.47 103.9-130.07 46.11-200-18.85-200-54.92 0-85.16 46.51-73.28 100.5 6.93 29.19 25.23 62.39 54.43 99.5-32.53 36.05-60.55 52.69-85.15 54.92-50 7.43-89.11-41.06-71.3-91.09 15.1-39.16 111.72-231.18 115.87-241.56 15.75-30.07 25.56-57.4 59.38-57.4 32.34 0 43.4 25.94 60.37 59.87 36 70.62 89.35 177.48 114.84 239.09 13.17 33.07-1.37 71.29-37.01 86.64zm47-136.12C280.27 35.93 273.13 32 224 32c-45.52 0-64.87 31.67-84.66 72.79C33.18 317.1 22.89 347.19 22 349.81-3.22 419.14 48.74 480 111.63 480c21.71 0 60.61-6.06 112.37-62.4 58.68 63.78 101.26 62.4 112.37 62.4 62.89.05 114.85-60.86 89.61-130.19.02-3.89-16.82-38.9-16.82-39.58z" } }, "free": ["brands"] }, "algolia": { "changes": ["5.0.0", "6.3.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f36c", "label": "Algolia", "voted": false, "svg": { "brands": { "last_modified": 1675090779, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 0C116.1 0 2 112.7 0 252.1C-2 393.6 112.9 510.8 254.5 511.6c43.7 .3 85.9-10.4 123.3-30.7c3.6-2 4.2-7 1.1-9.7l-24-21.2c-4.9-4.3-11.8-5.5-17.8-3c-26.1 11.1-54.5 16.8-83.7 16.4C139 461.9 46.5 366.8 48.3 252.4C50.1 139.5 142.6 48.2 256 48.2H463.7V417.2L345.9 312.5c-3.8-3.4-9.7-2.7-12.7 1.3c-18.9 25-49.7 40.6-83.9 38.2c-47.5-3.3-85.9-41.5-89.5-88.9c-4.2-56.6 40.6-103.9 96.3-103.9c50.4 0 91.9 38.8 96.2 88c.4 4.4 2.4 8.5 5.7 11.4l30.7 27.2c3.5 3.1 9 1.2 9.9-3.4c2.2-11.8 3-24.2 2.1-36.8c-4.9-72-63.3-130-135.4-134.4c-82.7-5.1-151.8 59.5-154 140.6c-2.1 78.9 62.6 147 141.6 148.7c33 .7 63.6-9.6 88.3-27.6L495 509.4c6.6 5.8 17 1.2 17-7.7V9.7c0-5.4-4.4-9.7-9.7-9.7H256z" } }, "free": ["brands"] }, "align-center": { "aliases": { "unicodes": { "secondary": ["10f037"] } }, "changes": [ "1.0.0", "5.0.0", "5.9.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["format", "middle", "paragraph", "text"] }, "styles": ["solid"], "unicode": "f037", "label": "Align Center", "voted": false, "svg": { "solid": { "last_modified": 1684767206, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M352 64c0-17.7-14.3-32-32-32H128c-17.7 0-32 14.3-32 32s14.3 32 32 32H320c17.7 0 32-14.3 32-32zm96 128c0-17.7-14.3-32-32-32H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H416c17.7 0 32-14.3 32-32zM0 448c0 17.7 14.3 32 32 32H416c17.7 0 32-14.3 32-32s-14.3-32-32-32H32c-17.7 0-32 14.3-32 32zM352 320c0-17.7-14.3-32-32-32H128c-17.7 0-32 14.3-32 32s14.3 32 32 32H320c17.7 0 32-14.3 32-32z" } }, "free": ["solid"] }, "align-justify": { "aliases": { "unicodes": { "secondary": ["10f039"] } }, "changes": [ "1.0.0", "5.0.0", "5.9.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["format", "paragraph", "text"] }, "styles": ["solid"], "unicode": "f039", "label": "Align Justify", "voted": false, "svg": { "solid": { "last_modified": 1684767207, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M448 64c0-17.7-14.3-32-32-32H32C14.3 32 0 46.3 0 64S14.3 96 32 96H416c17.7 0 32-14.3 32-32zm0 256c0-17.7-14.3-32-32-32H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H416c17.7 0 32-14.3 32-32zM0 192c0 17.7 14.3 32 32 32H416c17.7 0 32-14.3 32-32s-14.3-32-32-32H32c-17.7 0-32 14.3-32 32zM448 448c0-17.7-14.3-32-32-32H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H416c17.7 0 32-14.3 32-32z" } }, "free": ["solid"] }, "align-left": { "aliases": { "unicodes": { "secondary": ["10f036"] } }, "changes": [ "1.0.0", "5.0.0", "5.9.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["format", "paragraph", "text"] }, "styles": ["solid"], "unicode": "f036", "label": "Align Left", "voted": false, "svg": { "solid": { "last_modified": 1684767206, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M288 64c0 17.7-14.3 32-32 32H32C14.3 96 0 81.7 0 64S14.3 32 32 32H256c17.7 0 32 14.3 32 32zm0 256c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H256c17.7 0 32 14.3 32 32zM0 192c0-17.7 14.3-32 32-32H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32-14.3-32-32zM448 448c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H416c17.7 0 32 14.3 32 32z" } }, "free": ["solid"] }, "align-right": { "aliases": { "unicodes": { "secondary": ["10f038"] } }, "changes": [ "1.0.0", "5.0.0", "5.9.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["format", "paragraph", "text"] }, "styles": ["solid"], "unicode": "f038", "label": "Align Right", "voted": false, "svg": { "solid": { "last_modified": 1684767205, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M448 64c0 17.7-14.3 32-32 32H192c-17.7 0-32-14.3-32-32s14.3-32 32-32H416c17.7 0 32 14.3 32 32zm0 256c0 17.7-14.3 32-32 32H192c-17.7 0-32-14.3-32-32s14.3-32 32-32H416c17.7 0 32 14.3 32 32zM0 192c0-17.7 14.3-32 32-32H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32-14.3-32-32zM448 448c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H416c17.7 0 32 14.3 32 32z" } }, "free": ["solid"] }, "alipay": { "changes": ["5.3.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f642", "label": "Alipay", "voted": false, "svg": { "brands": { "last_modified": 1660014461, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M377.74 32H70.26C31.41 32 0 63.41 0 102.26v307.48C0 448.59 31.41 480 70.26 480h307.48c38.52 0 69.76-31.08 70.26-69.6-45.96-25.62-110.59-60.34-171.6-88.44-32.07 43.97-84.14 81-148.62 81-70.59 0-93.73-45.3-97.04-76.37-3.97-39.01 14.88-81.5 99.52-81.5 35.38 0 79.35 10.25 127.13 24.96 16.53-30.09 26.45-60.34 26.45-60.34h-178.2v-16.7h92.08v-31.24H88.28v-19.01h109.44V92.34h50.92v50.42h109.44v19.01H248.63v31.24h88.77s-15.21 46.62-38.35 90.92c48.93 16.7 100.01 36.04 148.62 52.74V102.26C447.83 63.57 416.43 32 377.74 32zM47.28 322.95c.99 20.17 10.25 53.73 69.93 53.73 52.07 0 92.58-39.68 117.87-72.9-44.63-18.68-84.48-31.41-109.44-31.41-67.45 0-79.35 33.06-78.36 50.58z" } }, "free": ["brands"] }, "amazon": { "changes": ["4.4.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f270", "label": "Amazon", "voted": false, "svg": { "brands": { "last_modified": 1660014474, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M257.2 162.7c-48.7 1.8-169.5 15.5-169.5 117.5 0 109.5 138.3 114 183.5 43.2 6.5 10.2 35.4 37.5 45.3 46.8l56.8-56S341 288.9 341 261.4V114.3C341 89 316.5 32 228.7 32 140.7 32 94 87 94 136.3l73.5 6.8c16.3-49.5 54.2-49.5 54.2-49.5 40.7-.1 35.5 29.8 35.5 69.1zm0 86.8c0 80-84.2 68-84.2 17.2 0-47.2 50.5-56.7 84.2-57.8v40.6zm136 163.5c-7.7 10-70 67-174.5 67S34.2 408.5 9.7 379c-6.8-7.7 1-11.3 5.5-8.3C88.5 415.2 203 488.5 387.7 401c7.5-3.7 13.3 2 5.5 12zm39.8 2.2c-6.5 15.8-16 26.8-21.2 31-5.5 4.5-9.5 2.7-6.5-3.8s19.3-46.5 12.7-55c-6.5-8.3-37-4.3-48-3.2-10.8 1-13 2-14-.3-2.3-5.7 21.7-15.5 37.5-17.5 15.7-1.8 41-.8 46 5.7 3.7 5.1 0 27.1-6.5 43.1z" } }, "free": ["brands"] }, "amazon-pay": { "changes": ["5.0.2", "5.8.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f42c", "label": "Amazon Pay", "voted": false, "svg": { "brands": { "last_modified": 1660014473, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M14 325.3c2.3-4.2 5.2-4.9 9.7-2.5 10.4 5.6 20.6 11.4 31.2 16.7a595.88 595.88 0 0 0 127.4 46.3 616.61 616.61 0 0 0 63.2 11.8 603.33 603.33 0 0 0 95 5.2c17.4-.4 34.8-1.8 52.1-3.8a603.66 603.66 0 0 0 163.3-42.8c2.9-1.2 5.9-2 9.1-1.2 6.7 1.8 9 9 4.1 13.9a70 70 0 0 1-9.6 7.4c-30.7 21.1-64.2 36.4-99.6 47.9a473.31 473.31 0 0 1-75.1 17.6 431 431 0 0 1-53.2 4.8 21.3 21.3 0 0 0-2.5.3H308a21.3 21.3 0 0 0-2.5-.3c-3.6-.2-7.2-.3-10.7-.4a426.3 426.3 0 0 1-50.4-5.3A448.4 448.4 0 0 1 164 420a443.33 443.33 0 0 1-145.6-87c-1.8-1.6-3-3.8-4.4-5.7zM172 65.1l-4.3.6a80.92 80.92 0 0 0-38 15.1c-2.4 1.7-4.6 3.5-7.1 5.4a4.29 4.29 0 0 1-.4-1.4c-.4-2.7-.8-5.5-1.3-8.2-.7-4.6-3-6.6-7.6-6.6h-11.5c-6.9 0-8.2 1.3-8.2 8.2v209.3c0 1 0 2 .1 3 .2 3 2 4.9 4.9 5 7 .1 14.1.1 21.1 0 2.9 0 4.7-2 5-5 .1-1 .1-2 .1-3v-72.4c1.1.9 1.7 1.4 2.2 1.9 17.9 14.9 38.5 19.8 61 15.4 20.4-4 34.6-16.5 43.8-34.9 7-13.9 9.9-28.7 10.3-44.1.5-17.1-1.2-33.9-8.1-49.8-8.5-19.6-22.6-32.5-43.9-36.9-3.2-.7-6.5-1-9.8-1.5-2.8-.1-5.5-.1-8.3-.1zM124.6 107a3.48 3.48 0 0 1 1.7-3.3c13.7-9.5 28.8-14.5 45.6-13.2 14.9 1.1 27.1 8.4 33.5 25.9 3.9 10.7 4.9 21.8 4.9 33 0 10.4-.8 20.6-4 30.6-6.8 21.3-22.4 29.4-42.6 28.5-14-.6-26.2-6-37.4-13.9a3.57 3.57 0 0 1-1.7-3.3c.1-14.1 0-28.1 0-42.2s.1-28 0-42.1zm205.7-41.9c-1 .1-2 .3-2.9.4a148 148 0 0 0-28.9 4.1c-6.1 1.6-12 3.8-17.9 5.8-3.6 1.2-5.4 3.8-5.3 7.7.1 3.3-.1 6.6 0 9.9.1 4.8 2.1 6.1 6.8 4.9 7.8-2 15.6-4.2 23.5-5.7 12.3-2.3 24.7-3.3 37.2-1.4 6.5 1 12.6 2.9 16.8 8.4 3.7 4.8 5.1 10.5 5.3 16.4.3 8.3.2 16.6.3 24.9a7.84 7.84 0 0 1-.2 1.4c-.5-.1-.9 0-1.3-.1a180.56 180.56 0 0 0-32-4.9c-11.3-.6-22.5.1-33.3 3.9-12.9 4.5-23.3 12.3-29.4 24.9-4.7 9.8-5.4 20.2-3.9 30.7 2 14 9 24.8 21.4 31.7 11.9 6.6 24.8 7.4 37.9 5.4 15.1-2.3 28.5-8.7 40.3-18.4a7.36 7.36 0 0 1 1.6-1.1c.6 3.8 1.1 7.4 1.8 11 .6 3.1 2.5 5.1 5.4 5.2 5.4.1 10.9.1 16.3 0a4.84 4.84 0 0 0 4.8-4.7 26.2 26.2 0 0 0 .1-2.8v-106a80 80 0 0 0-.9-12.9c-1.9-12.9-7.4-23.5-19-30.4-6.7-4-14.1-6-21.8-7.1-3.6-.5-7.2-.8-10.8-1.3-3.9.1-7.9.1-11.9.1zm35 127.7a3.33 3.33 0 0 1-1.5 3c-11.2 8.1-23.5 13.5-37.4 14.9-5.7.6-11.4.4-16.8-1.8a20.08 20.08 0 0 1-12.4-13.3 32.9 32.9 0 0 1-.1-19.4c2.5-8.3 8.4-13 16.4-15.6a61.33 61.33 0 0 1 24.8-2.2c8.4.7 16.6 2.3 25 3.4 1.6.2 2.1 1 2.1 2.6-.1 4.8 0 9.5 0 14.3s-.2 9.4-.1 14.1zm259.9 129.4c-1-5-4.8-6.9-9.1-8.3a88.42 88.42 0 0 0-21-3.9 147.32 147.32 0 0 0-39.2 1.9c-14.3 2.7-27.9 7.3-40 15.6a13.75 13.75 0 0 0-3.7 3.5 5.11 5.11 0 0 0-.5 4c.4 1.5 2.1 1.9 3.6 1.8a16.2 16.2 0 0 0 2.2-.1c7.8-.8 15.5-1.7 23.3-2.5 11.4-1.1 22.9-1.8 34.3-.9a71.64 71.64 0 0 1 14.4 2.7c5.1 1.4 7.4 5.2 7.6 10.4.4 8-1.4 15.7-3.5 23.3-4.1 15.4-10 30.3-15.8 45.1a17.6 17.6 0 0 0-1 3c-.5 2.9 1.2 4.8 4.1 4.1a10.56 10.56 0 0 0 4.8-2.5 145.91 145.91 0 0 0 12.7-13.4c12.8-16.4 20.3-35.3 24.7-55.6.8-3.6 1.4-7.3 2.1-10.9v-17.3zM493.1 199q-19.35-53.55-38.7-107.2c-2-5.7-4.2-11.3-6.3-16.9-1.1-2.9-3.2-4.8-6.4-4.8-7.6-.1-15.2-.2-22.9-.1-2.5 0-3.7 2-3.2 4.5a43.1 43.1 0 0 0 1.9 6.1q29.4 72.75 59.1 145.5c1.7 4.1 2.1 7.6.2 11.8-3.3 7.3-5.9 15-9.3 22.3-3 6.5-8 11.4-15.2 13.3a42.13 42.13 0 0 1-15.4 1.1c-2.5-.2-5-.8-7.5-1-3.4-.2-5.1 1.3-5.2 4.8q-.15 5 0 9.9c.1 5.5 2 8 7.4 8.9a108.18 108.18 0 0 0 16.9 2c17.1.4 30.7-6.5 39.5-21.4a131.63 131.63 0 0 0 9.2-18.4q35.55-89.7 70.6-179.6a26.62 26.62 0 0 0 1.6-5.5c.4-2.8-.9-4.4-3.7-4.4-6.6-.1-13.3 0-19.9 0a7.54 7.54 0 0 0-7.7 5.2c-.5 1.4-1.1 2.7-1.6 4.1l-34.8 100c-2.5 7.2-5.1 14.5-7.7 22.2-.4-1.1-.6-1.7-.9-2.4z" } }, "free": ["brands"] }, "amilia": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f36d", "label": "Amilia", "voted": false, "svg": { "brands": { "last_modified": 1660014459, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M240.1 32c-61.9 0-131.5 16.9-184.2 55.4-5.1 3.1-9.1 9.2-7.2 19.4 1.1 5.1 5.1 27.4 10.2 39.6 4.1 10.2 14.2 10.2 20.3 6.1 32.5-22.3 96.5-47.7 152.3-47.7 57.9 0 58.9 28.4 58.9 73.1v38.5C203 227.7 78.2 251 46.7 264.2 11.2 280.5 16.3 357.7 16.3 376s15.2 104 124.9 104c47.8 0 113.7-20.7 153.3-42.1v25.4c0 3 2.1 8.2 6.1 9.1 3.1 1 50.7 2 59.9 2s62.5.3 66.5-.7c4.1-1 5.1-6.1 5.1-9.1V168c-.1-80.3-57.9-136-192-136zm50.2 348c-21.4 13.2-48.7 24.4-79.1 24.4-52.8 0-58.9-33.5-59-44.7 0-12.2-3-42.7 18.3-52.9 24.3-13.2 75.1-29.4 119.8-33.5z" } }, "free": ["brands"] }, "anchor": { "aliases": { "unicodes": { "composite": ["2693"], "secondary": ["10f13d"] } }, "changes": [ "3.1.0", "5.0.0", "5.11.0", "6.0.0-beta1", "6.0.0-beta3", "6.1.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "anchor", "berth", "boat", "dock", "embed", "link", "maritime", "moor", "port", "secure", "ship", "tool" ] }, "styles": ["solid"], "unicode": "f13d", "label": "Anchor", "voted": false, "svg": { "solid": { "last_modified": 1684767636, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M320 96a32 32 0 1 1 -64 0 32 32 0 1 1 64 0zm21.1 80C367 158.8 384 129.4 384 96c0-53-43-96-96-96s-96 43-96 96c0 33.4 17 62.8 42.9 80H224c-17.7 0-32 14.3-32 32s14.3 32 32 32h32V448H208c-53 0-96-43-96-96v-6.1l7 7c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9L97 263c-9.4-9.4-24.6-9.4-33.9 0L7 319c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l7-7V352c0 88.4 71.6 160 160 160h80 80c88.4 0 160-71.6 160-160v-6.1l7 7c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9l-56-56c-9.4-9.4-24.6-9.4-33.9 0l-56 56c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l7-7V352c0 53-43 96-96 96H320V240h32c17.7 0 32-14.3 32-32s-14.3-32-32-32H341.1z" } }, "free": ["solid"] }, "anchor-circle-check": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["marina", "not affected", "ok", "okay", "port"] }, "styles": ["solid"], "unicode": "e4aa", "label": "Anchor Circle Check", "voted": false, "svg": { "solid": { "last_modified": 1684767637, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M320 96a32 32 0 1 1 -64 0 32 32 0 1 1 64 0zm21.1 80C367 158.8 384 129.4 384 96c0-53-43-96-96-96s-96 43-96 96c0 33.4 17 62.8 42.9 80H224c-17.7 0-32 14.3-32 32s14.3 32 32 32h32V448H208c-53 0-96-43-96-96v-6.1l7 7c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9L97 263c-9.4-9.4-24.6-9.4-33.9 0L7 319c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l7-7V352c0 88.4 71.6 160 160 160h80 80c8.2 0 16.3-.6 24.2-1.8c-22.2-16.2-40.4-37.5-53-62.2H320V368 240h32c17.7 0 32-14.3 32-32s-14.3-32-32-32H341.1zM640 368a144 144 0 1 0 -288 0 144 144 0 1 0 288 0zm-76.7-43.3c6.2 6.2 6.2 16.4 0 22.6l-72 72c-6.2 6.2-16.4 6.2-22.6 0l-40-40c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0L480 385.4l60.7-60.7c6.2-6.2 16.4-6.2 22.6 0z" } }, "free": ["solid"] }, "anchor-circle-exclamation": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["affected", "marina", "port"] }, "styles": ["solid"], "unicode": "e4ab", "label": "Anchor Circle Exclamation", "voted": false, "svg": { "solid": { "last_modified": 1684767637, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M320 96a32 32 0 1 1 -64 0 32 32 0 1 1 64 0zm21.1 80C367 158.8 384 129.4 384 96c0-53-43-96-96-96s-96 43-96 96c0 33.4 17 62.8 42.9 80H224c-17.7 0-32 14.3-32 32s14.3 32 32 32h32V448H208c-53 0-96-43-96-96v-6.1l7 7c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9L97 263c-9.4-9.4-24.6-9.4-33.9 0L7 319c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l7-7V352c0 88.4 71.6 160 160 160h80 80c8.2 0 16.3-.6 24.2-1.8c-22.2-16.2-40.4-37.5-53-62.2H320V368 240h32c17.7 0 32-14.3 32-32s-14.3-32-32-32H341.1zM496 512a144 144 0 1 0 0-288 144 144 0 1 0 0 288zm0-96a24 24 0 1 1 0 48 24 24 0 1 1 0-48zm0-144c8.8 0 16 7.2 16 16v80c0 8.8-7.2 16-16 16s-16-7.2-16-16V288c0-8.8 7.2-16 16-16z" } }, "free": ["solid"] }, "anchor-circle-xmark": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["destroy", "marina", "port"] }, "styles": ["solid"], "unicode": "e4ac", "label": "Anchor Circle Xmark", "voted": false, "svg": { "solid": { "last_modified": 1684767636, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M320 96a32 32 0 1 1 -64 0 32 32 0 1 1 64 0zm21.1 80C367 158.8 384 129.4 384 96c0-53-43-96-96-96s-96 43-96 96c0 33.4 17 62.8 42.9 80H224c-17.7 0-32 14.3-32 32s14.3 32 32 32h32V448H208c-53 0-96-43-96-96v-6.1l7 7c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9L97 263c-9.4-9.4-24.6-9.4-33.9 0L7 319c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l7-7V352c0 88.4 71.6 160 160 160h80 80c8.2 0 16.3-.6 24.2-1.8c-22.2-16.2-40.4-37.5-53-62.2H320V368 240h32c17.7 0 32-14.3 32-32s-14.3-32-32-32H341.1zM496 512a144 144 0 1 0 0-288 144 144 0 1 0 0 288zm59.3-180.7L518.6 368l36.7 36.7c6.2 6.2 6.2 16.4 0 22.6s-16.4 6.2-22.6 0L496 390.6l-36.7 36.7c-6.2 6.2-16.4 6.2-22.6 0s-6.2-16.4 0-22.6L473.4 368l-36.7-36.7c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0L496 345.4l36.7-36.7c6.2-6.2 16.4-6.2 22.6 0s6.2 16.4 0 22.6z" } }, "free": ["solid"] }, "anchor-lock": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["closed", "lockdown", "marina", "port", "quarantine"] }, "styles": ["solid"], "unicode": "e4ad", "label": "Anchor Lock", "voted": false, "svg": { "solid": { "last_modified": 1684767637, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M320 96a32 32 0 1 1 -64 0 32 32 0 1 1 64 0zm21.1 80C367 158.8 384 129.4 384 96c0-53-43-96-96-96s-96 43-96 96c0 33.4 17 62.8 42.9 80H224c-17.7 0-32 14.3-32 32s14.3 32 32 32h32V448H208c-53 0-96-43-96-96v-6.1l7 7c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9L97 263c-9.4-9.4-24.6-9.4-33.9 0L7 319c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l7-7V352c0 88.4 71.6 160 160 160h80 80c8 0 15.9-.6 23.6-1.7c-4.8-9-7.6-19.3-7.6-30.3V446.7c-5.2 .9-10.5 1.3-16 1.3H320V240h32c17.7 0 32-14.3 32-32s-14.3-32-32-32H341.1zM528 240c17.7 0 32 14.3 32 32v48H496V272c0-17.7 14.3-32 32-32zm-80 32v48c-17.7 0-32 14.3-32 32V480c0 17.7 14.3 32 32 32H608c17.7 0 32-14.3 32-32V352c0-17.7-14.3-32-32-32V272c0-44.2-35.8-80-80-80s-80 35.8-80 80z" } }, "free": ["solid"] }, "android": { "changes": ["3.2.0", "5.0.0", "5.12.0"], "ligatures": [], "search": { "terms": ["robot"] }, "styles": ["brands"], "unicode": "f17b", "label": "Android", "voted": false, "svg": { "brands": { "last_modified": 1660014462, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M420.55,301.93a24,24,0,1,1,24-24,24,24,0,0,1-24,24m-265.1,0a24,24,0,1,1,24-24,24,24,0,0,1-24,24m273.7-144.48,47.94-83a10,10,0,1,0-17.27-10h0l-48.54,84.07a301.25,301.25,0,0,0-246.56,0L116.18,64.45a10,10,0,1,0-17.27,10h0l47.94,83C64.53,202.22,8.24,285.55,0,384H576c-8.24-98.45-64.54-181.78-146.85-226.55" } }, "free": ["brands"] }, "angellist": { "changes": ["4.2.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f209", "label": "AngelList", "voted": false, "svg": { "brands": { "last_modified": 1660014475, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M347.1 215.4c11.7-32.6 45.4-126.9 45.4-157.1 0-26.6-15.7-48.9-43.7-48.9-44.6 0-84.6 131.7-97.1 163.1C242 144 196.6 0 156.6 0c-31.1 0-45.7 22.9-45.7 51.7 0 35.3 34.2 126.8 46.6 162-6.3-2.3-13.1-4.3-20-4.3-23.4 0-48.3 29.1-48.3 52.6 0 8.9 4.9 21.4 8 29.7-36.9 10-51.1 34.6-51.1 71.7C46 435.6 114.4 512 210.6 512c118 0 191.4-88.6 191.4-202.9 0-43.1-6.9-82-54.9-93.7zM311.7 108c4-12.3 21.1-64.3 37.1-64.3 8.6 0 10.9 8.9 10.9 16 0 19.1-38.6 124.6-47.1 148l-34-6 33.1-93.7zM142.3 48.3c0-11.9 14.5-45.7 46.3 47.1l34.6 100.3c-15.6-1.3-27.7-3-35.4 1.4-10.9-28.8-45.5-119.7-45.5-148.8zM140 244c29.3 0 67.1 94.6 67.1 107.4 0 5.1-4.9 11.4-10.6 11.4-20.9 0-76.9-76.9-76.9-97.7.1-7.7 12.7-21.1 20.4-21.1zm184.3 186.3c-29.1 32-66.3 48.6-109.7 48.6-59.4 0-106.3-32.6-128.9-88.3-17.1-43.4 3.8-68.3 20.6-68.3 11.4 0 54.3 60.3 54.3 73.1 0 4.9-7.7 8.3-11.7 8.3-16.1 0-22.4-15.5-51.1-51.4-29.7 29.7 20.5 86.9 58.3 86.9 26.1 0 43.1-24.2 38-42 3.7 0 8.3.3 11.7-.6 1.1 27.1 9.1 59.4 41.7 61.7 0-.9 2-7.1 2-7.4 0-17.4-10.6-32.6-10.6-50.3 0-28.3 21.7-55.7 43.7-71.7 8-6 17.7-9.7 27.1-13.1 9.7-3.7 20-8 27.4-15.4-1.1-11.2-5.7-21.1-16.9-21.1-27.7 0-120.6 4-120.6-39.7 0-6.7.1-13.1 17.4-13.1 32.3 0 114.3 8 138.3 29.1 18.1 16.1 24.3 113.2-31 174.7zm-98.6-126c9.7 3.1 19.7 4 29.7 6-7.4 5.4-14 12-20.3 19.1-2.8-8.5-6.2-16.8-9.4-25.1z" } }, "free": ["brands"] }, "angle-down": { "aliases": { "unicodes": { "composite": ["2304"], "secondary": ["10f107"] } }, "changes": ["3.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Down Arrowhead", "arrow", "caret", "download", "expand"] }, "styles": ["solid"], "unicode": "f107", "label": "Angle Down", "voted": false, "svg": { "solid": { "last_modified": 1684766329, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M201.4 342.6c12.5 12.5 32.8 12.5 45.3 0l160-160c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L224 274.7 86.6 137.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l160 160z" } }, "free": ["solid"] }, "angle-left": { "aliases": { "unicodes": { "composite": ["2039"], "secondary": ["10f104"] } }, "changes": [ "3.0.0", "5.0.0", "5.11.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Single Left-Pointing Angle Quotation Mark", "arrow", "back", "caret", "less", "previous" ] }, "styles": ["solid"], "unicode": "f104", "label": "Angle Left", "voted": false, "svg": { "solid": { "last_modified": 1684766328, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M41.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L109.3 256 246.6 118.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-160 160z" } }, "free": ["solid"] }, "angle-right": { "aliases": { "unicodes": { "composite": ["203a"], "secondary": ["10f105"] } }, "changes": [ "3.0.0", "5.0.0", "5.11.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Single Right-Pointing Angle Quotation Mark", "arrow", "care", "forward", "more", "next" ] }, "styles": ["solid"], "unicode": "f105", "label": "Angle Right", "voted": false, "svg": { "solid": { "last_modified": 1684766332, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M278.6 233.4c12.5 12.5 12.5 32.8 0 45.3l-160 160c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L210.7 256 73.4 118.6c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l160 160z" } }, "free": ["solid"] }, "angle-up": { "aliases": { "unicodes": { "composite": ["2303"], "secondary": ["10f106"] } }, "changes": ["3.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Up Arrowhead", "arrow", "caret", "collapse", "upload"] }, "styles": ["solid"], "unicode": "f106", "label": "Angle Up", "voted": false, "svg": { "solid": { "last_modified": 1684766329, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M201.4 137.4c12.5-12.5 32.8-12.5 45.3 0l160 160c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L224 205.3 86.6 342.6c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3l160-160z" } }, "free": ["solid"] }, "angles-down": { "aliases": { "names": ["angle-double-down"], "unicodes": { "secondary": ["10f103"] } }, "changes": ["3.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["arrows", "caret", "download", "expand"] }, "styles": ["solid"], "unicode": "f103", "label": "Angles Down", "voted": false, "svg": { "solid": { "last_modified": 1684766332, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M246.6 470.6c-12.5 12.5-32.8 12.5-45.3 0l-160-160c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L224 402.7 361.4 265.4c12.5-12.5 32.8-12.5 45.3 0s12.5 32.8 0 45.3l-160 160zm160-352l-160 160c-12.5 12.5-32.8 12.5-45.3 0l-160-160c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L224 210.7 361.4 73.4c12.5-12.5 32.8-12.5 45.3 0s12.5 32.8 0 45.3z" } }, "free": ["solid"] }, "angles-left": { "aliases": { "names": ["angle-double-left"], "unicodes": { "composite": ["ab"], "secondary": ["10f100"] } }, "changes": ["3.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "Left-Pointing Double Angle Quotation Mark", "arrows", "back", "caret", "laquo", "previous", "quote" ] }, "styles": ["solid"], "unicode": "f100", "label": "Angles Left", "voted": false, "svg": { "solid": { "last_modified": 1684766329, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M41.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L109.3 256 246.6 118.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-160 160zm352-160l-160 160c-12.5 12.5-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L301.3 256 438.6 118.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0z" } }, "free": ["solid"] }, "angles-right": { "aliases": { "names": ["angle-double-right"], "unicodes": { "composite": ["bb"], "secondary": ["10f101"] } }, "changes": ["3.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "Right-Pointing Double Angle Quotation Mark", "arrows", "caret", "forward", "more", "next", "quote", "raquo" ] }, "styles": ["solid"], "unicode": "f101", "label": "Angles Right", "voted": false, "svg": { "solid": { "last_modified": 1684766331, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M470.6 278.6c12.5-12.5 12.5-32.8 0-45.3l-160-160c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L402.7 256 265.4 393.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l160-160zm-352 160l160-160c12.5-12.5 12.5-32.8 0-45.3l-160-160c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L210.7 256 73.4 393.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0z" } }, "free": ["solid"] }, "angles-up": { "aliases": { "names": ["angle-double-up"], "unicodes": { "secondary": ["10f102"] } }, "changes": ["3.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["arrows", "caret", "collapse", "upload"] }, "styles": ["solid"], "unicode": "f102", "label": "Angles Up", "voted": false, "svg": { "solid": { "last_modified": 1684766330, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M246.6 41.4c-12.5-12.5-32.8-12.5-45.3 0l-160 160c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L224 109.3 361.4 246.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3l-160-160zm160 352l-160-160c-12.5-12.5-32.8-12.5-45.3 0l-160 160c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L224 301.3 361.4 438.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3z" } }, "free": ["solid"] }, "angrycreative": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f36e", "label": "Angry Creative", "voted": false, "svg": { "brands": { "last_modified": 1660014473, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M640 238.2l-3.2 28.2-34.5 2.3-2 18.1 34.5-2.3-3.2 28.2-34.4 2.2-2.3 20.1 34.4-2.2-3 26.1-64.7 4.1 12.7-113.2L527 365.2l-31.9 2-23.8-117.8 30.3-2 13.6 79.4 31.7-82.4 93.1-6.2zM426.8 371.5l28.3-1.8L468 249.6l-28.4 1.9-12.8 120zM162 388.1l-19.4-36-3.5 37.4-28.2 1.7 2.7-29.1c-11 18-32 34.3-56.9 35.8C23.9 399.9-3 377 .3 339.7c2.6-29.3 26.7-62.8 67.5-65.4 37.7-2.4 47.6 23.2 51.3 28.8l2.8-30.8 38.9-2.5c20.1-1.3 38.7 3.7 42.5 23.7l2.6-26.6 64.8-4.2-2.7 27.9-36.4 2.4-1.7 17.9 36.4-2.3-2.7 27.9-36.4 2.3-1.9 19.9 36.3-2.3-2.1 20.8 55-117.2 23.8-1.6L370.4 369l8.9-85.6-22.3 1.4 2.9-27.9 75-4.9-3 28-24.3 1.6-9.7 91.9-58 3.7-4.3-15.6-39.4 2.5-8 16.3-126.2 7.7zm-44.3-70.2l-26.4 1.7C84.6 307.2 76.9 303 65 303.8c-19 1.2-33.3 17.5-34.6 33.3-1.4 16 7.3 32.5 28.7 31.2 12.8-.8 21.3-8.6 28.9-18.9l27-1.7 2.7-29.8zm56.1-7.7c1.2-12.9-7.6-13.6-26.1-12.4l-2.7 28.5c14.2-.9 27.5-2.1 28.8-16.1zm21.1 70.8l5.8-60c-5 13.5-14.7 21.1-27.9 26.6l22.1 33.4zm135.4-45l-7.9-37.8-15.8 39.3 23.7-1.5zm-170.1-74.6l-4.3-17.5-39.6 2.6-8.1 18.2-31.9 2.1 57-121.9 23.9-1.6 30.7 102 9.9-104.7 27-1.8 37.8 63.6 6.5-66.6 28.5-1.9-4 41.2c7.4-13.5 22.9-44.7 63.6-47.5 40.5-2.8 52.4 29.3 53.4 30.3l3.3-32 39.3-2.7c12.7-.9 27.8.3 36.3 9.7l-4.4-11.9 32.2-2.2 12.9 43.2 23-45.7 31-2.2-43.6 78.4-4.8 44.3-28.4 1.9 4.8-44.3-15.8-43c1 22.3-9.2 40.1-32 49.6l25.2 38.8-36.4 2.4-19.2-36.8-4 38.3-28.4 1.9 3.3-31.5c-6.7 9.3-19.7 35.4-59.6 38-26.2 1.7-45.6-10.3-55.4-39.2l-4 40.3-25 1.6-37.6-63.3-6.3 66.2-56.8 3.7zm276.6-82.1c10.2-.7 17.5-2.1 21.6-4.3 4.5-2.4 7-6.4 7.6-12.1.6-5.3-.6-8.8-3.4-10.4-3.6-2.1-10.6-2.8-22.9-2l-2.9 28.8zM327.7 214c5.6 5.9 12.7 8.5 21.3 7.9 4.7-.3 9.1-1.8 13.3-4.1 5.5-3 10.6-8 15.1-14.3l-34.2 2.3 2.4-23.9 63.1-4.3 1.2-12-31.2 2.1c-4.1-3.7-7.8-6.6-11.1-8.1-4-1.7-8.1-2.8-12.2-2.5-8 .5-15.3 3.6-22 9.2-7.7 6.4-12 14.5-12.9 24.4-1.1 9.6 1.4 17.3 7.2 23.3zm-201.3 8.2l23.8-1.6-8.3-37.6-15.5 39.2z" } }, "free": ["brands"] }, "angular": { "changes": ["5.0.0", "5.8.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f420", "label": "Angular", "voted": false, "svg": { "brands": { "last_modified": 1660014473, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M185.7 268.1h76.2l-38.1-91.6-38.1 91.6zM223.8 32L16 106.4l31.8 275.7 176 97.9 176-97.9 31.8-275.7zM354 373.8h-48.6l-26.2-65.4H168.6l-26.2 65.4H93.7L223.8 81.5z" } }, "free": ["brands"] }, "ankh": { "aliases": { "unicodes": { "composite": ["2625"], "secondary": ["10f644"] } }, "changes": ["5.3.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "Ankh", "amulet", "copper", "coptic christianity", "copts", "crux ansata", "egypt", "venus" ] }, "styles": ["solid"], "unicode": "f644", "label": "Ankh", "voted": false, "svg": { "solid": { "last_modified": 1684767603, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M96 128c0-35.3 28.7-64 64-64s64 28.7 64 64c0 41.6-20.7 76.6-46.6 104.1c-5.9 6.2-11.8 11.8-17.4 16.7c-5.6-4.9-11.5-10.5-17.4-16.7C116.7 204.6 96 169.6 96 128zM160 0C89.3 0 32 57.3 32 128c0 52.4 21.5 95.5 46.8 128H32c-17.7 0-32 14.3-32 32s14.3 32 32 32h96V480c0 17.7 14.3 32 32 32s32-14.3 32-32V320h96c17.7 0 32-14.3 32-32s-14.3-32-32-32H241.2c25.4-32.5 46.8-75.6 46.8-128C288 57.3 230.7 0 160 0z" } }, "free": ["solid"] }, "app-store": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f36f", "label": "App Store", "voted": false, "svg": { "brands": { "last_modified": 1660014476, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M255.9 120.9l9.1-15.7c5.6-9.8 18.1-13.1 27.9-7.5 9.8 5.6 13.1 18.1 7.5 27.9l-87.5 151.5h63.3c20.5 0 32 24.1 23.1 40.8H113.8c-11.3 0-20.4-9.1-20.4-20.4 0-11.3 9.1-20.4 20.4-20.4h52l66.6-115.4-20.8-36.1c-5.6-9.8-2.3-22.2 7.5-27.9 9.8-5.6 22.2-2.3 27.9 7.5l8.9 15.7zm-78.7 218l-19.6 34c-5.6 9.8-18.1 13.1-27.9 7.5-9.8-5.6-13.1-18.1-7.5-27.9l14.6-25.2c16.4-5.1 29.8-1.2 40.4 11.6zm168.9-61.7h53.1c11.3 0 20.4 9.1 20.4 20.4 0 11.3-9.1 20.4-20.4 20.4h-29.5l19.9 34.5c5.6 9.8 2.3 22.2-7.5 27.9-9.8 5.6-22.2 2.3-27.9-7.5-33.5-58.1-58.7-101.6-75.4-130.6-17.1-29.5-4.9-59.1 7.2-69.1 13.4 23 33.4 57.7 60.1 104zM256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm216 248c0 118.7-96.1 216-216 216-118.7 0-216-96.1-216-216 0-118.7 96.1-216 216-216 118.7 0 216 96.1 216 216z" } }, "free": ["brands"] }, "app-store-ios": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f370", "label": "iOS App Store", "voted": false, "svg": { "brands": { "last_modified": 1660014475, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM127 384.5c-5.5 9.6-17.8 12.8-27.3 7.3-9.6-5.5-12.8-17.8-7.3-27.3l14.3-24.7c16.1-4.9 29.3-1.1 39.6 11.4L127 384.5zm138.9-53.9H84c-11 0-20-9-20-20s9-20 20-20h51l65.4-113.2-20.5-35.4c-5.5-9.6-2.2-21.8 7.3-27.3 9.6-5.5 21.8-2.2 27.3 7.3l8.9 15.4 8.9-15.4c5.5-9.6 17.8-12.8 27.3-7.3 9.6 5.5 12.8 17.8 7.3 27.3l-85.8 148.6h62.1c20.2 0 31.5 23.7 22.7 40zm98.1 0h-29l19.6 33.9c5.5 9.6 2.2 21.8-7.3 27.3-9.6 5.5-21.8 2.2-27.3-7.3-32.9-56.9-57.5-99.7-74-128.1-16.7-29-4.8-58 7.1-67.8 13.1 22.7 32.7 56.7 58.9 102h52c11 0 20 9 20 20 0 11.1-9 20-20 20z" } }, "free": ["brands"] }, "apper": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f371", "label": "Apper Systems AB", "voted": false, "svg": { "brands": { "last_modified": 1660014464, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M42.1 239.1c22.2 0 29 2.8 33.5 14.6h.8v-22.9c0-11.3-4.8-15.4-17.9-15.4-11.3 0-14.4 2.5-15.1 12.8H4.8c.3-13.9 1.5-19.1 5.8-24.4C17.9 195 29.5 192 56.7 192c33 0 47.1 5 53.9 18.9 2 4.3 4 15.6 4 23.7v76.3H76.3l1.3-19.1h-1c-5.3 15.6-13.6 20.4-35.5 20.4-30.3 0-41.1-10.1-41.1-37.3 0-25.2 12.3-35.8 42.1-35.8zm17.1 48.1c13.1 0 16.9-3 16.9-13.4 0-9.1-4.3-11.6-19.6-11.6-13.1 0-17.9 3-17.9 12.1-.1 10.4 3.7 12.9 20.6 12.9zm77.8-94.9h38.3l-1.5 20.6h.8c9.1-17.1 15.9-20.9 37.5-20.9 14.4 0 24.7 3 31.5 9.1 9.8 8.6 12.8 20.4 12.8 48.1 0 30-3 43.1-12.1 52.9-6.8 7.3-16.4 10.1-33.2 10.1-20.4 0-29.2-5.5-33.8-21.2h-.8v70.3H137v-169zm80.9 60.7c0-27.5-3.3-32.5-20.7-32.5-16.9 0-20.7 5-20.7 28.7 0 28 3.5 33.5 21.2 33.5 16.4 0 20.2-5.6 20.2-29.7zm57.9-60.7h38.3l-1.5 20.6h.8c9.1-17.1 15.9-20.9 37.5-20.9 14.4 0 24.7 3 31.5 9.1 9.8 8.6 12.8 20.4 12.8 48.1 0 30-3 43.1-12.1 52.9-6.8 7.3-16.4 10.1-33.3 10.1-20.4 0-29.2-5.5-33.8-21.2h-.8v70.3h-39.5v-169zm80.9 60.7c0-27.5-3.3-32.5-20.7-32.5-16.9 0-20.7 5-20.7 28.7 0 28 3.5 33.5 21.2 33.5 16.4 0 20.2-5.6 20.2-29.7zm53.8-3.8c0-25.4 3.3-37.8 12.3-45.8 8.8-8.1 22.2-11.3 45.1-11.3 42.8 0 55.7 12.8 55.7 55.7v11.1h-75.3c-.3 2-.3 4-.3 4.8 0 16.9 4.5 21.9 20.1 21.9 13.9 0 17.9-3 17.9-13.9h37.5v2.3c0 9.8-2.5 18.9-6.8 24.7-7.3 9.8-19.6 13.6-44.3 13.6-27.5 0-41.6-3.3-50.6-12.3-8.5-8.5-11.3-21.3-11.3-50.8zm76.4-11.6c-.3-1.8-.3-3.3-.3-3.8 0-12.3-3.3-14.6-19.6-14.6-14.4 0-17.1 3-18.1 15.1l-.3 3.3h38.3zm55.6-45.3h38.3l-1.8 19.9h.7c6.8-14.9 14.4-20.2 29.7-20.2 10.8 0 19.1 3.3 23.4 9.3 5.3 7.3 6.8 14.4 6.8 34 0 1.5 0 5 .2 9.3h-35c.3-1.8.3-3.3.3-4 0-15.4-2-19.4-10.3-19.4-6.3 0-10.8 3.3-13.1 9.3-1 3-1 4.3-1 12.3v68h-38.3V192.3z" } }, "free": ["brands"] }, "apple": { "changes": ["3.2.0", "5.0.0", "5.0.7", "5.8.0"], "ligatures": [], "search": { "terms": ["fruit", "ios", "mac", "operating system", "os", "osx"] }, "styles": ["brands"], "unicode": "f179", "label": "Apple", "voted": false, "svg": { "brands": { "last_modified": 1660014474, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M318.7 268.7c-.2-36.7 16.4-64.4 50-84.8-18.8-26.9-47.2-41.7-84.7-44.6-35.5-2.8-74.3 20.7-88.5 20.7-15 0-49.4-19.7-76.4-19.7C63.3 141.2 4 184.8 4 273.5q0 39.3 14.4 81.2c12.8 36.7 59 126.7 107.2 125.2 25.2-.6 43-17.9 75.8-17.9 31.8 0 48.3 17.9 76.4 17.9 48.6-.7 90.4-82.5 102.6-119.3-65.2-30.7-61.7-90-61.7-91.9zm-56.6-164.2c27.3-32.4 24.8-61.9 24-72.5-24.1 1.4-52 16.4-67.9 34.9-17.5 19.8-27.8 44.3-25.6 71.9 26.1 2 49.9-11.4 69.5-34.3z" } }, "free": ["brands"] }, "apple-pay": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f415", "label": "Apple Pay", "voted": true, "svg": { "brands": { "last_modified": 1660014473, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M116.9 158.5c-7.5 8.9-19.5 15.9-31.5 14.9-1.5-12 4.4-24.8 11.3-32.6 7.5-9.1 20.6-15.6 31.3-16.1 1.2 12.4-3.7 24.7-11.1 33.8m10.9 17.2c-17.4-1-32.3 9.9-40.5 9.9-8.4 0-21-9.4-34.8-9.1-17.9.3-34.5 10.4-43.6 26.5-18.8 32.3-4.9 80 13.3 106.3 8.9 13 19.5 27.3 33.5 26.8 13.3-.5 18.5-8.6 34.5-8.6 16.1 0 20.8 8.6 34.8 8.4 14.5-.3 23.6-13 32.5-26 10.1-14.8 14.3-29.1 14.5-29.9-.3-.3-28-10.9-28.3-42.9-.3-26.8 21.9-39.5 22.9-40.3-12.5-18.6-32-20.6-38.8-21.1m100.4-36.2v194.9h30.3v-66.6h41.9c38.3 0 65.1-26.3 65.1-64.3s-26.4-64-64.1-64h-73.2zm30.3 25.5h34.9c26.3 0 41.3 14 41.3 38.6s-15 38.8-41.4 38.8h-34.8V165zm162.2 170.9c19 0 36.6-9.6 44.6-24.9h.6v23.4h28v-97c0-28.1-22.5-46.3-57.1-46.3-32.1 0-55.9 18.4-56.8 43.6h27.3c2.3-12 13.4-19.9 28.6-19.9 18.5 0 28.9 8.6 28.9 24.5v10.8l-37.8 2.3c-35.1 2.1-54.1 16.5-54.1 41.5.1 25.2 19.7 42 47.8 42zm8.2-23.1c-16.1 0-26.4-7.8-26.4-19.6 0-12.3 9.9-19.4 28.8-20.5l33.6-2.1v11c0 18.2-15.5 31.2-36 31.2zm102.5 74.6c29.5 0 43.4-11.3 55.5-45.4L640 193h-30.8l-35.6 115.1h-.6L537.4 193h-31.6L557 334.9l-2.8 8.6c-4.6 14.6-12.1 20.3-25.5 20.3-2.4 0-7-.3-8.9-.5v23.4c1.8.4 9.3.7 11.6.7z" } }, "free": ["brands"] }, "apple-whole": { "aliases": { "names": ["apple-alt"], "unicodes": { "composite": ["1f34e", "1f34f"], "secondary": ["10f5d1"] } }, "changes": ["5.2.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "apple", "fall", "fruit", "fuji", "green", "green apple", "macintosh", "orchard", "red", "red apple", "seasonal", "vegan" ] }, "styles": ["solid"], "unicode": "f5d1", "label": "Apple Whole", "voted": false, "svg": { "solid": { "last_modified": 1684767420, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M224 112c-8.8 0-16-7.2-16-16V80c0-44.2 35.8-80 80-80h16c8.8 0 16 7.2 16 16V32c0 44.2-35.8 80-80 80H224zM0 288c0-76.3 35.7-160 112-160c27.3 0 59.7 10.3 82.7 19.3c18.8 7.3 39.9 7.3 58.7 0c22.9-8.9 55.4-19.3 82.7-19.3c76.3 0 112 83.7 112 160c0 128-80 224-160 224c-16.5 0-38.1-6.6-51.5-11.3c-8.1-2.8-16.9-2.8-25 0c-13.4 4.7-35 11.3-51.5 11.3C80 512 0 416 0 288z" } }, "free": ["solid"] }, "archway": { "aliases": { "unicodes": { "secondary": ["10f557"] } }, "changes": [ "5.1.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["arc", "monument", "road", "street", "tunnel"] }, "styles": ["solid"], "unicode": "f557", "label": "Archway", "voted": false, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M32 32C14.3 32 0 46.3 0 64S14.3 96 32 96H480c17.7 0 32-14.3 32-32s-14.3-32-32-32H32zm0 384c-17.7 0-32 14.3-32 32s14.3 32 32 32H96h64V352c0-53 43-96 96-96s96 43 96 96V480h64 64c17.7 0 32-14.3 32-32s-14.3-32-32-32V128H32V416z" } }, "free": ["solid"] }, "arrow-down": { "aliases": { "unicodes": { "composite": ["2193"], "secondary": ["10f063"] } }, "changes": [ "1.0.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta2", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["Downwards Arrow", "download"] }, "styles": ["solid"], "unicode": "f063", "label": "Arrow Down", "voted": false, "svg": { "solid": { "last_modified": 1684766329, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M169.4 470.6c12.5 12.5 32.8 12.5 45.3 0l160-160c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L224 370.8 224 64c0-17.7-14.3-32-32-32s-32 14.3-32 32l0 306.7L54.6 265.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l160 160z" } }, "free": ["solid"] }, "arrow-down-1-9": { "aliases": { "names": ["sort-numeric-asc", "sort-numeric-down"], "unicodes": { "secondary": ["10f162"] } }, "changes": [ "3.2.0", "5.0.0", "5.9.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["arrange", "filter", "numbers", "order", "sort-numeric-asc"] }, "styles": ["solid"], "unicode": "f162", "label": "Arrow Down 1 9", "voted": false, "svg": { "solid": { "last_modified": 1684766330, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M450.7 38c-8.3-6-19.1-7.7-28.8-4.4l-48 16c-16.8 5.6-25.8 23.7-20.2 40.5s23.7 25.8 40.5 20.2l5.9-2V160H384c-17.7 0-32 14.3-32 32s14.3 32 32 32h48 48c17.7 0 32-14.3 32-32s-14.3-32-32-32H464V64c0-10.3-4.9-19.9-13.3-26zM160 480c9 0 17.5-3.8 23.6-10.4l88-96c11.9-13 11.1-33.3-2-45.2s-33.3-11.1-45.2 2L192 365.7V64c0-17.7-14.3-32-32-32s-32 14.3-32 32V365.7L95.6 330.4c-11.9-13-32.2-13.9-45.2-2s-13.9 32.2-2 45.2l88 96C142.5 476.2 151 480 160 480zM418.3 307a32 32 0 1 1 27.4 57.9A32 32 0 1 1 418.3 307zM405.1 419.8l-6.8 9.2c-10.5 14.2-7.5 34.2 6.7 44.8s34.2 7.5 44.8-6.7l48.8-65.8c14-18.9 21.5-41.7 21.5-65.2c0-48.6-39.4-88-88-88s-88 39.4-88 88c0 39.2 25.6 72.4 61.1 83.8z" } }, "free": ["solid"] }, "arrow-down-9-1": { "aliases": { "names": ["sort-numeric-desc", "sort-numeric-down-alt"], "unicodes": { "secondary": ["10f886"] } }, "changes": ["5.9.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["arrange", "filter", "numbers", "order", "sort-numeric-asc"] }, "styles": ["solid"], "unicode": "f886", "label": "Arrow Down 9 1", "voted": false, "svg": { "solid": { "last_modified": 1684766332, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M160 480c9 0 17.5-3.8 23.6-10.4l88-96c11.9-13 11.1-33.3-2-45.2s-33.3-11.1-45.2 2L192 365.7V64c0-17.7-14.3-32-32-32s-32 14.3-32 32V365.7L95.6 330.4c-11.9-13-32.2-13.9-45.2-2s-13.9 32.2-2 45.2l88 96C142.5 476.2 151 480 160 480zM450.7 294c-8.3-6-19.1-7.7-28.8-4.4l-48 16c-16.8 5.6-25.8 23.7-20.2 40.5s23.7 25.8 40.5 20.2l5.9-2V416H384c-17.7 0-32 14.3-32 32s14.3 32 32 32h48 48c17.7 0 32-14.3 32-32s-14.3-32-32-32H464V320c0-10.3-4.9-19.9-13.3-26zM418.3 91a32 32 0 1 1 27.4 57.9A32 32 0 1 1 418.3 91zM405.1 203.8l-6.8 9.2c-10.5 14.2-7.5 34.2 6.7 44.8s34.2 7.5 44.8-6.7l48.8-65.8c14-18.9 21.5-41.7 21.5-65.2c0-48.6-39.4-88-88-88s-88 39.4-88 88c0 39.2 25.6 72.4 61.1 83.8z" } }, "free": ["solid"] }, "arrow-down-a-z": { "aliases": { "names": ["sort-alpha-asc", "sort-alpha-down"], "unicodes": { "secondary": ["10f15d"] } }, "changes": [ "3.2.0", "5.0.0", "5.9.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["alphabetical", "arrange", "filter", "order", "sort-alpha-asc"] }, "styles": ["solid"], "unicode": "f15d", "label": "Arrow Down A Z", "voted": false, "svg": { "solid": { "last_modified": 1684766330, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M183.6 469.6C177.5 476.2 169 480 160 480s-17.5-3.8-23.6-10.4l-88-96c-11.9-13-11.1-33.3 2-45.2s33.3-11.1 45.2 2L128 365.7V64c0-17.7 14.3-32 32-32s32 14.3 32 32V365.7l32.4-35.4c11.9-13 32.2-13.9 45.2-2s13.9 32.2 2 45.2l-88 96zM320 320c0-17.7 14.3-32 32-32H480c12.9 0 24.6 7.8 29.6 19.8s2.2 25.7-6.9 34.9L429.3 416H480c17.7 0 32 14.3 32 32s-14.3 32-32 32H352c-12.9 0-24.6-7.8-29.6-19.8s-2.2-25.7 6.9-34.9L402.7 352H352c-17.7 0-32-14.3-32-32zM416 32c12.1 0 23.2 6.8 28.6 17.7l64 128 16 32c7.9 15.8 1.5 35-14.3 42.9s-35 1.5-42.9-14.3L460.2 224H371.8l-7.2 14.3c-7.9 15.8-27.1 22.2-42.9 14.3s-22.2-27.1-14.3-42.9l16-32 64-128C392.8 38.8 403.9 32 416 32zM395.8 176h40.4L416 135.6 395.8 176z" } }, "free": ["solid"] }, "arrow-down-long": { "aliases": { "names": ["long-arrow-down"], "unicodes": { "secondary": ["10f175"] } }, "changes": ["3.2.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["download", "long-arrow-down"] }, "styles": ["solid"], "unicode": "f175", "label": "Arrow Down Long", "voted": false, "svg": { "solid": { "last_modified": 1684766331, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M169.4 502.6c12.5 12.5 32.8 12.5 45.3 0l128-128c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L224 402.7 224 32c0-17.7-14.3-32-32-32s-32 14.3-32 32l0 370.7L86.6 329.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l128 128z" } }, "free": ["solid"] }, "arrow-down-short-wide": { "aliases": { "names": ["sort-amount-desc", "sort-amount-down-alt"], "unicodes": { "secondary": ["10f884"] } }, "changes": ["5.9.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["arrange", "filter", "order", "sort-amount-asc"] }, "styles": ["solid"], "unicode": "f884", "label": "Arrow Down Short Wide", "voted": false, "svg": { "solid": { "last_modified": 1684766329, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M151.6 469.6C145.5 476.2 137 480 128 480s-17.5-3.8-23.6-10.4l-88-96c-11.9-13-11.1-33.3 2-45.2s33.3-11.1 45.2 2L96 365.7V64c0-17.7 14.3-32 32-32s32 14.3 32 32V365.7l32.4-35.4c11.9-13 32.2-13.9 45.2-2s13.9 32.2 2 45.2l-88 96zM320 32h32c17.7 0 32 14.3 32 32s-14.3 32-32 32H320c-17.7 0-32-14.3-32-32s14.3-32 32-32zm0 128h96c17.7 0 32 14.3 32 32s-14.3 32-32 32H320c-17.7 0-32-14.3-32-32s14.3-32 32-32zm0 128H480c17.7 0 32 14.3 32 32s-14.3 32-32 32H320c-17.7 0-32-14.3-32-32s14.3-32 32-32zm0 128H544c17.7 0 32 14.3 32 32s-14.3 32-32 32H320c-17.7 0-32-14.3-32-32s14.3-32 32-32z" } }, "free": ["solid"] }, "arrow-down-up-across-line": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["border", "crossing", "transfer"] }, "styles": ["solid"], "unicode": "e4af", "label": "Arrow Down Up Across Line", "voted": false, "svg": { "solid": { "last_modified": 1684766332, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M137.4 502.6c12.5 12.5 32.8 12.5 45.3 0l96-96c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L192 402.7V288H544c17.7 0 32-14.3 32-32s-14.3-32-32-32H448V109.3l41.4 41.4c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3l-96-96c-12.5-12.5-32.8-12.5-45.3 0l-96 96c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L384 109.3V224H192 128 32c-17.7 0-32 14.3-32 32s14.3 32 32 32h96V402.7L86.6 361.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l96 96zM128 192h64V64c0-17.7-14.3-32-32-32s-32 14.3-32 32V192zM448 320H384V448c0 17.7 14.3 32 32 32s32-14.3 32-32V320z" } }, "free": ["solid"] }, "arrow-down-up-lock": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "border", "closed", "crossing", "lockdown", "quarantine", "transfer" ] }, "styles": ["solid"], "unicode": "e4b0", "label": "Arrow Down Up Lock", "voted": false, "svg": { "solid": { "last_modified": 1684766329, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M150.6 502.6l96-96c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L160 402.7V288H416V272c0-17.2 3.9-33.5 10.8-48H352V109.3l41.4 41.4c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3l-96-96c-6-6-14.1-9.4-22.6-9.4s-16.6 3.4-22.6 9.4l-96 96c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L288 109.3V224l-128 0H96l-64 0c-17.7 0-32 14.3-32 32s14.3 32 32 32H96V402.7L54.6 361.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l96 96c12.5 12.5 32.8 12.5 45.3 0zM160 192V64c0-17.7-14.3-32-32-32s-32 14.3-32 32V192h64zM288 320V448c0 17.7 14.3 32 32 32s32-14.3 32-32V320H288zm240-80c17.7 0 32 14.3 32 32v48H496V272c0-17.7 14.3-32 32-32zm-80 32v48c-17.7 0-32 14.3-32 32V480c0 17.7 14.3 32 32 32H608c17.7 0 32-14.3 32-32V352c0-17.7-14.3-32-32-32V272c0-44.2-35.8-80-80-80s-80 35.8-80 80z" } }, "free": ["solid"] }, "arrow-down-wide-short": { "aliases": { "names": ["sort-amount-asc", "sort-amount-down"], "unicodes": { "secondary": ["10f160"] } }, "changes": [ "3.2.0", "5.0.0", "5.9.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["arrange", "filter", "number", "order", "sort-amount-asc"] }, "styles": ["solid"], "unicode": "f160", "label": "Arrow Down Wide Short", "voted": false, "svg": { "solid": { "last_modified": 1684766331, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M151.6 469.6C145.5 476.2 137 480 128 480s-17.5-3.8-23.6-10.4l-88-96c-11.9-13-11.1-33.3 2-45.2s33.3-11.1 45.2 2L96 365.7V64c0-17.7 14.3-32 32-32s32 14.3 32 32V365.7l32.4-35.4c11.9-13 32.2-13.9 45.2-2s13.9 32.2 2 45.2l-88 96zM320 480c-17.7 0-32-14.3-32-32s14.3-32 32-32h32c17.7 0 32 14.3 32 32s-14.3 32-32 32H320zm0-128c-17.7 0-32-14.3-32-32s14.3-32 32-32h96c17.7 0 32 14.3 32 32s-14.3 32-32 32H320zm0-128c-17.7 0-32-14.3-32-32s14.3-32 32-32H480c17.7 0 32 14.3 32 32s-14.3 32-32 32H320zm0-128c-17.7 0-32-14.3-32-32s14.3-32 32-32H544c17.7 0 32 14.3 32 32s-14.3 32-32 32H320z" } }, "free": ["solid"] }, "arrow-down-z-a": { "aliases": { "names": ["sort-alpha-desc", "sort-alpha-down-alt"], "unicodes": { "secondary": ["10f881"] } }, "changes": ["5.9.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["alphabetical", "arrange", "filter", "order", "sort-alpha-asc"] }, "styles": ["solid"], "unicode": "f881", "label": "Arrow Down Z A", "voted": false, "svg": { "solid": { "last_modified": 1684766332, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M183.6 469.6C177.5 476.2 169 480 160 480s-17.5-3.8-23.6-10.4l-88-96c-11.9-13-11.1-33.3 2-45.2s33.3-11.1 45.2 2L128 365.7V64c0-17.7 14.3-32 32-32s32 14.3 32 32V365.7l32.4-35.4c11.9-13 32.2-13.9 45.2-2s13.9 32.2 2 45.2l-88 96zM320 64c0-17.7 14.3-32 32-32H480c12.9 0 24.6 7.8 29.6 19.8s2.2 25.7-6.9 34.9L429.3 160H480c17.7 0 32 14.3 32 32s-14.3 32-32 32H352c-12.9 0-24.6-7.8-29.6-19.8s-2.2-25.7 6.9-34.9L402.7 96H352c-17.7 0-32-14.3-32-32zm96 192c12.1 0 23.2 6.8 28.6 17.7l64 128 16 32c7.9 15.8 1.5 35-14.3 42.9s-35 1.5-42.9-14.3L460.2 448H371.8l-7.2 14.3c-7.9 15.8-27.1 22.2-42.9 14.3s-22.2-27.1-14.3-42.9l16-32 64-128c5.4-10.8 16.5-17.7 28.6-17.7zM395.8 400h40.4L416 359.6 395.8 400z" } }, "free": ["solid"] }, "arrow-left": { "aliases": { "unicodes": { "composite": ["2190"], "secondary": ["10f060"] } }, "changes": [ "1.0.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta2", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["Leftwards Arrow", "back", "previous"] }, "styles": ["solid"], "unicode": "f060", "label": "Arrow Left", "voted": false, "svg": { "solid": { "last_modified": 1684766330, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M9.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L109.2 288 416 288c17.7 0 32-14.3 32-32s-14.3-32-32-32l-306.7 0L214.6 118.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-160 160z" } }, "free": ["solid"] }, "arrow-left-long": { "aliases": { "names": ["long-arrow-left"], "unicodes": { "secondary": ["10f177"] } }, "changes": ["3.2.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["back", "long-arrow-left", "previous"] }, "styles": ["solid"], "unicode": "f177", "label": "Arrow Left Long", "voted": false, "svg": { "solid": { "last_modified": 1684766330, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M9.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l128 128c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L109.3 288 480 288c17.7 0 32-14.3 32-32s-14.3-32-32-32l-370.7 0 73.4-73.4c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-128 128z" } }, "free": ["solid"] }, "arrow-pointer": { "aliases": { "names": ["mouse-pointer"], "unicodes": { "secondary": ["10f245"] } }, "changes": [ "4.4.0", "5.0.0", "5.0.3", "6.0.0-beta1", "6.1.2", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["arrow", "cursor", "select"] }, "styles": ["solid"], "unicode": "f245", "label": "Arrow Pointer", "voted": false, "svg": { "solid": { "last_modified": 1684766331, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M0 55.2V426c0 12.2 9.9 22 22 22c6.3 0 12.4-2.7 16.6-7.5L121.2 346l58.1 116.3c7.9 15.8 27.1 22.2 42.9 14.3s22.2-27.1 14.3-42.9L179.8 320H297.9c12.2 0 22.1-9.9 22.1-22.1c0-6.3-2.7-12.3-7.4-16.5L38.6 37.9C34.3 34.1 28.9 32 23.2 32C10.4 32 0 42.4 0 55.2z" } }, "free": ["solid"] }, "arrow-right": { "aliases": { "unicodes": { "composite": ["2192"], "secondary": ["10f061"] } }, "changes": [ "1.0.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta2", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["Rightwards Arrow", "forward", "next"] }, "styles": ["solid"], "unicode": "f061", "label": "Arrow Right", "voted": false, "svg": { "solid": { "last_modified": 1684766330, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M438.6 278.6c12.5-12.5 12.5-32.8 0-45.3l-160-160c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L338.8 224 32 224c-17.7 0-32 14.3-32 32s14.3 32 32 32l306.7 0L233.4 393.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l160-160z" } }, "free": ["solid"] }, "arrow-right-arrow-left": { "aliases": { "names": ["exchange"], "unicodes": { "composite": ["21c4"], "secondary": ["10f0ec"] } }, "changes": [ "3.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.2.1", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Rightwards Arrow Over Leftwards Arrow", "arrow", "arrows", "reciprocate", "return", "swap", "transfer" ] }, "styles": ["solid"], "unicode": "f0ec", "label": "Arrow Right Arrow Left", "voted": false, "svg": { "solid": { "last_modified": 1684766329, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M438.6 150.6c12.5-12.5 12.5-32.8 0-45.3l-96-96c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L338.7 96 32 96C14.3 96 0 110.3 0 128s14.3 32 32 32l306.7 0-41.4 41.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l96-96zm-333.3 352c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L109.3 416 416 416c17.7 0 32-14.3 32-32s-14.3-32-32-32l-306.7 0 41.4-41.4c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-96 96c-12.5 12.5-12.5 32.8 0 45.3l96 96z" } }, "free": ["solid"] }, "arrow-right-from-bracket": { "aliases": { "names": ["sign-out"], "unicodes": { "secondary": ["10f08b"] } }, "changes": ["1.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["arrow", "exit", "leave", "log out", "logout"] }, "styles": ["solid"], "unicode": "f08b", "label": "Arrow Right From Bracket", "voted": false, "svg": { "solid": { "last_modified": 1684766332, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M502.6 278.6c12.5-12.5 12.5-32.8 0-45.3l-128-128c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L402.7 224 192 224c-17.7 0-32 14.3-32 32s14.3 32 32 32l210.7 0-73.4 73.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l128-128zM160 96c17.7 0 32-14.3 32-32s-14.3-32-32-32L96 32C43 32 0 75 0 128L0 384c0 53 43 96 96 96l64 0c17.7 0 32-14.3 32-32s-14.3-32-32-32l-64 0c-17.7 0-32-14.3-32-32l0-256c0-17.7 14.3-32 32-32l64 0z" } }, "free": ["solid"] }, "arrow-right-long": { "aliases": { "names": ["long-arrow-right"], "unicodes": { "secondary": ["10f178"] } }, "changes": ["3.2.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["forward", "long-arrow-right", "next"] }, "styles": ["solid"], "unicode": "f178", "label": "Arrow Right Long", "voted": false, "svg": { "solid": { "last_modified": 1684766329, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M502.6 278.6c12.5-12.5 12.5-32.8 0-45.3l-128-128c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L402.7 224 32 224c-17.7 0-32 14.3-32 32s14.3 32 32 32l370.7 0-73.4 73.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l128-128z" } }, "free": ["solid"] }, "arrow-right-to-bracket": { "aliases": { "names": ["sign-in"], "unicodes": { "secondary": ["10f090"] } }, "changes": ["1.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "arrow", "enter", "join", "log in", "login", "sign in", "sign up", "sign-in", "signin", "signup" ] }, "styles": ["solid"], "unicode": "f090", "label": "Arrow Right To Bracket", "voted": false, "svg": { "solid": { "last_modified": 1684766331, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M352 96l64 0c17.7 0 32 14.3 32 32l0 256c0 17.7-14.3 32-32 32l-64 0c-17.7 0-32 14.3-32 32s14.3 32 32 32l64 0c53 0 96-43 96-96l0-256c0-53-43-96-96-96l-64 0c-17.7 0-32 14.3-32 32s14.3 32 32 32zm-9.4 182.6c12.5-12.5 12.5-32.8 0-45.3l-128-128c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L242.7 224 32 224c-17.7 0-32 14.3-32 32s14.3 32 32 32l210.7 0-73.4 73.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l128-128z" } }, "free": ["solid"] }, "arrow-right-to-city": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["building", "city", "exodus", "rural", "urban"] }, "styles": ["solid"], "unicode": "e4b3", "label": "Arrow Right To City", "voted": false, "svg": { "solid": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M288 48c0-26.5 21.5-48 48-48h96c26.5 0 48 21.5 48 48V192h40V120c0-13.3 10.7-24 24-24s24 10.7 24 24v72h24c26.5 0 48 21.5 48 48V464c0 26.5-21.5 48-48 48H432 336c-26.5 0-48-21.5-48-48V48zm64 32v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V80c0-8.8-7.2-16-16-16H368c-8.8 0-16 7.2-16 16zm16 80c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V176c0-8.8-7.2-16-16-16H368zM352 272v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V272c0-8.8-7.2-16-16-16H368c-8.8 0-16 7.2-16 16zm176-16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V272c0-8.8-7.2-16-16-16H528zM512 368v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V368c0-8.8-7.2-16-16-16H528c-8.8 0-16 7.2-16 16zM166.6 153.4l80 80c12.5 12.5 12.5 32.8 0 45.3l-80 80c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L146.7 288H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H146.7l-25.4-25.4c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0z" } }, "free": ["solid"] }, "arrow-rotate-left": { "aliases": { "names": [ "arrow-left-rotate", "arrow-rotate-back", "arrow-rotate-backward", "undo" ], "unicodes": { "composite": ["21ba"], "secondary": ["10f0e2"] } }, "changes": ["2.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "Anticlockwise Open Circle Arrow", "back", "control z", "exchange", "oops", "return", "rotate", "swap" ] }, "styles": ["solid"], "unicode": "f0e2", "label": "Arrow Rotate Left", "voted": false, "svg": { "solid": { "last_modified": 1684766330, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M125.7 160H176c17.7 0 32 14.3 32 32s-14.3 32-32 32H48c-17.7 0-32-14.3-32-32V64c0-17.7 14.3-32 32-32s32 14.3 32 32v51.2L97.6 97.6c87.5-87.5 229.3-87.5 316.8 0s87.5 229.3 0 316.8s-229.3 87.5-316.8 0c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0c62.5 62.5 163.8 62.5 226.3 0s62.5-163.8 0-226.3s-163.8-62.5-226.3 0L125.7 160z" } }, "free": ["solid"] }, "arrow-rotate-right": { "aliases": { "names": ["arrow-right-rotate", "arrow-rotate-forward", "redo"], "unicodes": { "composite": ["21bb"], "secondary": ["10f01e"] } }, "changes": [ "1.0.0", "5.0.0", "5.8.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Clockwise Open Circle Arrow", "forward", "refresh", "reload", "repeat" ] }, "styles": ["solid"], "unicode": "f01e", "label": "Arrow Rotate Right", "voted": false, "svg": { "solid": { "last_modified": 1684766330, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M386.3 160H336c-17.7 0-32 14.3-32 32s14.3 32 32 32H464c17.7 0 32-14.3 32-32V64c0-17.7-14.3-32-32-32s-32 14.3-32 32v51.2L414.4 97.6c-87.5-87.5-229.3-87.5-316.8 0s-87.5 229.3 0 316.8s229.3 87.5 316.8 0c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0c-62.5 62.5-163.8 62.5-226.3 0s-62.5-163.8 0-226.3s163.8-62.5 226.3 0L386.3 160z" } }, "free": ["solid"] }, "arrow-trend-down": { "changes": ["6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["line", "stocks", "trend"] }, "styles": ["solid"], "unicode": "e097", "label": "Arrow Trend Down", "voted": false, "svg": { "solid": { "last_modified": 1684767205, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M384 352c-17.7 0-32 14.3-32 32s14.3 32 32 32H544c17.7 0 32-14.3 32-32V224c0-17.7-14.3-32-32-32s-32 14.3-32 32v82.7L342.6 137.4c-12.5-12.5-32.8-12.5-45.3 0L192 242.7 54.6 105.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0L320 205.3 466.7 352H384z" } }, "free": ["solid"] }, "arrow-trend-up": { "changes": ["6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["line", "stocks", "trend"] }, "styles": ["solid"], "unicode": "e098", "label": "Arrow Trend Up", "voted": false, "svg": { "solid": { "last_modified": 1684767205, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M384 160c-17.7 0-32-14.3-32-32s14.3-32 32-32H544c17.7 0 32 14.3 32 32V288c0 17.7-14.3 32-32 32s-32-14.3-32-32V205.3L342.6 374.6c-12.5 12.5-32.8 12.5-45.3 0L192 269.3 54.6 406.6c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3l160-160c12.5-12.5 32.8-12.5 45.3 0L320 306.7 466.7 160H384z" } }, "free": ["solid"] }, "arrow-turn-down": { "aliases": { "names": ["level-down"], "unicodes": { "secondary": ["10f149"] } }, "changes": [ "3.1.0", "5.0.0", "5.11.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["arrow"] }, "styles": ["solid"], "unicode": "f149", "label": "Arrow Turn Down", "voted": false, "svg": { "solid": { "last_modified": 1684766329, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M32 64C14.3 64 0 49.7 0 32S14.3 0 32 0l96 0c53 0 96 43 96 96l0 306.7 73.4-73.4c12.5-12.5 32.8-12.5 45.3 0s12.5 32.8 0 45.3l-128 128c-12.5 12.5-32.8 12.5-45.3 0l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L160 402.7 160 96c0-17.7-14.3-32-32-32L32 64z" } }, "free": ["solid"] }, "arrow-turn-up": { "aliases": { "names": ["level-up"], "unicodes": { "secondary": ["10f148"] } }, "changes": [ "3.1.0", "5.0.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["arrow"] }, "styles": ["solid"], "unicode": "f148", "label": "Arrow Turn Up", "voted": false, "svg": { "solid": { "last_modified": 1684766330, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M32 448c-17.7 0-32 14.3-32 32s14.3 32 32 32l96 0c53 0 96-43 96-96l0-306.7 73.4 73.4c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3l-128-128c-12.5-12.5-32.8-12.5-45.3 0l-128 128c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L160 109.3 160 416c0 17.7-14.3 32-32 32l-96 0z" } }, "free": ["solid"] }, "arrow-up": { "aliases": { "unicodes": { "composite": ["2191"], "secondary": ["10f062"] } }, "changes": [ "1.0.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta2", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["Upwards Arrow", "forward", "upload"] }, "styles": ["solid"], "unicode": "f062", "label": "Arrow Up", "voted": false, "svg": { "solid": { "last_modified": 1684766329, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M214.6 41.4c-12.5-12.5-32.8-12.5-45.3 0l-160 160c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L160 141.2V448c0 17.7 14.3 32 32 32s32-14.3 32-32V141.2L329.4 246.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3l-160-160z" } }, "free": ["solid"] }, "arrow-up-1-9": { "aliases": { "names": ["sort-numeric-up"], "unicodes": { "secondary": ["10f163"] } }, "changes": [ "3.2.0", "5.0.0", "5.9.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["arrange", "filter", "numbers", "order", "sort-numeric-desc"] }, "styles": ["solid"], "unicode": "f163", "label": "Arrow Up 1 9", "voted": false, "svg": { "solid": { "last_modified": 1684766330, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M450.7 38c8.3 6 13.3 15.7 13.3 26v96h16c17.7 0 32 14.3 32 32s-14.3 32-32 32H432 384c-17.7 0-32-14.3-32-32s14.3-32 32-32h16V108.4l-5.9 2c-16.8 5.6-34.9-3.5-40.5-20.2s3.5-34.9 20.2-40.5l48-16c9.8-3.3 20.5-1.6 28.8 4.4zM160 32c9 0 17.5 3.8 23.6 10.4l88 96c11.9 13 11.1 33.3-2 45.2s-33.3 11.1-45.2-2L192 146.3V448c0 17.7-14.3 32-32 32s-32-14.3-32-32V146.3L95.6 181.6c-11.9 13-32.2 13.9-45.2 2s-13.9-32.2-2-45.2l88-96C142.5 35.8 151 32 160 32zM445.7 364.9A32 32 0 1 0 418.3 307a32 32 0 1 0 27.4 57.9zm-40.7 54.9C369.6 408.4 344 375.2 344 336c0-48.6 39.4-88 88-88s88 39.4 88 88c0 23.5-7.5 46.3-21.5 65.2L449.7 467c-10.5 14.2-30.6 17.2-44.8 6.7s-17.2-30.6-6.7-44.8l6.8-9.2z" } }, "free": ["solid"] }, "arrow-up-9-1": { "aliases": { "names": ["sort-numeric-up-alt"], "unicodes": { "secondary": ["10f887"] } }, "changes": ["5.9.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["arrange", "filter", "numbers", "order", "sort-numeric-desc"] }, "styles": ["solid"], "unicode": "f887", "label": "Arrow Up 9 1", "voted": false, "svg": { "solid": { "last_modified": 1684766330, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M160 32c9 0 17.5 3.8 23.6 10.4l88 96c11.9 13 11.1 33.3-2 45.2s-33.3 11.1-45.2-2L192 146.3V448c0 17.7-14.3 32-32 32s-32-14.3-32-32V146.3L95.6 181.6c-11.9 13-32.2 13.9-45.2 2s-13.9-32.2-2-45.2l88-96C142.5 35.8 151 32 160 32zM450.7 294c8.3 6 13.3 15.7 13.3 26v96h16c17.7 0 32 14.3 32 32s-14.3 32-32 32H432 384c-17.7 0-32-14.3-32-32s14.3-32 32-32h16V364.4l-5.9 2c-16.8 5.6-34.9-3.5-40.5-20.2s3.5-34.9 20.2-40.5l48-16c9.8-3.3 20.5-1.6 28.8 4.4zm-5-145.1A32 32 0 1 0 418.3 91a32 32 0 1 0 27.4 57.9zm-40.7 54.9C369.6 192.4 344 159.2 344 120c0-48.6 39.4-88 88-88s88 39.4 88 88c0 23.5-7.5 46.3-21.5 65.2L449.7 251c-10.5 14.2-30.6 17.2-44.8 6.7s-17.2-30.6-6.7-44.8l6.8-9.2z" } }, "free": ["solid"] }, "arrow-up-a-z": { "aliases": { "names": ["sort-alpha-up"], "unicodes": { "secondary": ["10f15e"] } }, "changes": [ "3.2.0", "5.0.0", "5.9.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["alphabetical", "arrange", "filter", "order", "sort-alpha-desc"] }, "styles": ["solid"], "unicode": "f15e", "label": "Arrow Up A Z", "voted": false, "svg": { "solid": { "last_modified": 1684766331, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M183.6 42.4C177.5 35.8 169 32 160 32s-17.5 3.8-23.6 10.4l-88 96c-11.9 13-11.1 33.3 2 45.2s33.3 11.1 45.2-2L128 146.3V448c0 17.7 14.3 32 32 32s32-14.3 32-32V146.3l32.4 35.4c11.9 13 32.2 13.9 45.2 2s13.9-32.2 2-45.2l-88-96zM320 320c0 17.7 14.3 32 32 32h50.7l-73.4 73.4c-9.2 9.2-11.9 22.9-6.9 34.9s16.6 19.8 29.6 19.8H480c17.7 0 32-14.3 32-32s-14.3-32-32-32H429.3l73.4-73.4c9.2-9.2 11.9-22.9 6.9-34.9s-16.6-19.8-29.6-19.8H352c-17.7 0-32 14.3-32 32zM416 32c-12.1 0-23.2 6.8-28.6 17.7l-64 128-16 32c-7.9 15.8-1.5 35 14.3 42.9s35 1.5 42.9-14.3l7.2-14.3h88.4l7.2 14.3c7.9 15.8 27.1 22.2 42.9 14.3s22.2-27.1 14.3-42.9l-16-32-64-128C439.2 38.8 428.1 32 416 32zM395.8 176L416 135.6 436.2 176H395.8z" } }, "free": ["solid"] }, "arrow-up-from-bracket": { "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["share", "transfer", "upload"] }, "styles": ["solid"], "unicode": "e09a", "label": "Arrow Up From Bracket", "voted": false, "svg": { "solid": { "last_modified": 1684766331, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M246.6 9.4c-12.5-12.5-32.8-12.5-45.3 0l-128 128c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L192 109.3V320c0 17.7 14.3 32 32 32s32-14.3 32-32V109.3l73.4 73.4c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3l-128-128zM64 352c0-17.7-14.3-32-32-32s-32 14.3-32 32v64c0 53 43 96 96 96H352c53 0 96-43 96-96V352c0-17.7-14.3-32-32-32s-32 14.3-32 32v64c0 17.7-14.3 32-32 32H96c-17.7 0-32-14.3-32-32V352z" } }, "free": ["solid"] }, "arrow-up-from-ground-water": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["groundwater", "spring", "water supply", "water table"] }, "styles": ["solid"], "unicode": "e4b5", "label": "Arrow Up From Ground Water", "voted": false, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M288 352c17.7 0 32-14.3 32-32V109.3l25.4 25.4c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3l-80-80c-12.5-12.5-32.8-12.5-45.3 0l-80 80c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L256 109.3V320c0 17.7 14.3 32 32 32zm-18.5 69.9C247 437.4 219.5 448 192 448c-26.9 0-55.3-10.8-77.4-26.1l0 0c-11.9-8.5-28.1-7.8-39.2 1.7c-14.4 11.9-32.5 21-50.6 25.2c-17.2 4-27.9 21.2-23.9 38.4s21.2 27.9 38.4 23.9c24.5-5.7 44.9-16.5 58.2-25C126.5 501.7 159 512 192 512c31.9 0 60.6-9.9 80.4-18.9c5.8-2.7 11.1-5.3 15.6-7.7c4.5 2.4 9.7 5.1 15.6 7.7c19.8 9 48.5 18.9 80.4 18.9c33 0 65.5-10.3 94.5-25.8c13.4 8.4 33.7 19.3 58.2 25c17.2 4 34.4-6.7 38.4-23.9s-6.7-34.4-23.9-38.4c-18.1-4.2-36.2-13.3-50.6-25.2c-11.1-9.4-27.3-10.1-39.2-1.7l0 0C439.4 437.2 410.9 448 384 448c-27.5 0-55-10.6-77.5-26.1c-11.1-7.9-25.9-7.9-37 0zM192 192H48c-26.5 0-48 21.5-48 48V425c5.3-3.1 11.2-5.4 17.5-6.9c13.1-3.1 26.7-9.8 37.3-18.6c22.2-18.7 54.3-20.1 78.1-3.4c18 12.4 40.1 20.3 59.1 20.3V192zm384 48c0-26.5-21.5-48-48-48H384V416.5h0c19 0 41.2-7.9 59.2-20.3c23.8-16.7 55.8-15.3 78.1 3.4c10.6 8.8 24.2 15.6 37.3 18.6c6.3 1.5 12.1 3.8 17.5 6.9V240z" } }, "free": ["solid"] }, "arrow-up-from-water-pump": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["flood", "groundwater", "pump", "submersible", "sump pump"] }, "styles": ["solid"], "unicode": "e4b6", "label": "Arrow Up From Water Pump", "voted": false, "svg": { "solid": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M112 0C85.5 0 64 21.5 64 48V256H48c-26.5 0-48 21.5-48 48v96c0 8 2 15.6 5.4 22.2c3.8-1.7 7.8-3.1 12-4.1c13.1-3.1 26.7-9.8 37.3-18.6c22.2-18.7 54.3-20.1 78.1-3.4c18 12.4 40.1 20.3 59.2 20.3c21.1 0 42-8.5 59.2-20.3c22.1-15.5 51.6-15.5 73.7 0c18.4 12.7 39.6 20.3 59.2 20.3c19 0 41.2-7.9 59.2-20.3c23.8-16.7 55.8-15.3 78.1 3.4c10.6 8.8 24.2 15.6 37.3 18.6c4.2 1 8.2 2.4 12 4.1C574 415.6 576 408 576 400V304c0-26.5-21.5-48-48-48H480l0-146.7 25.4 25.4c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3l-80-80c-12.5-12.5-32.8-12.5-45.3 0l-80 80c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L416 109.3 416 256H288V48c0-26.5-21.5-48-48-48H112zM306.5 421.9c-11.1-7.9-25.9-7.9-37 0C247 437.4 219.5 448 192 448c-26.9 0-55.3-10.8-77.4-26.1l0 0c-11.9-8.5-28.1-7.8-39.2 1.7c-14.4 11.9-32.5 21-50.6 25.2c-17.2 4-27.9 21.2-23.9 38.4s21.2 27.9 38.4 23.9c24.5-5.7 44.9-16.5 58.2-25C126.5 501.7 159 512 192 512c31.9 0 60.6-9.9 80.4-18.9c5.8-2.7 11.1-5.3 15.6-7.7c4.5 2.4 9.7 5.1 15.6 7.7c19.8 9 48.5 18.9 80.4 18.9c33 0 65.5-10.3 94.5-25.8c13.4 8.4 33.7 19.3 58.2 25c17.2 4 34.4-6.7 38.4-23.9s-6.7-34.4-23.9-38.4c-18.1-4.2-36.2-13.3-50.6-25.2c-11.1-9.4-27.3-10.1-39.2-1.7l0 0C439.4 437.2 410.9 448 384 448c-27.5 0-55-10.6-77.5-26.1z" } }, "free": ["solid"] }, "arrow-up-long": { "aliases": { "names": ["long-arrow-up"], "unicodes": { "secondary": ["10f176"] } }, "changes": ["3.2.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["long-arrow-up", "upload"] }, "styles": ["solid"], "unicode": "f176", "label": "Arrow Up Long", "voted": false, "svg": { "solid": { "last_modified": 1684766332, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M214.6 9.4c-12.5-12.5-32.8-12.5-45.3 0l-128 128c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L160 109.3V480c0 17.7 14.3 32 32 32s32-14.3 32-32V109.3l73.4 73.4c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3l-128-128z" } }, "free": ["solid"] }, "arrow-up-right-dots": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["growth", "increase", "population"] }, "styles": ["solid"], "unicode": "e4b7", "label": "Arrow Up Right Dots", "voted": false, "svg": { "solid": { "last_modified": 1684767205, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M160 0c-17.7 0-32 14.3-32 32s14.3 32 32 32h50.7L9.4 265.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L256 109.3V160c0 17.7 14.3 32 32 32s32-14.3 32-32V32c0-17.7-14.3-32-32-32H160zM576 80a48 48 0 1 0 -96 0 48 48 0 1 0 96 0zM448 208a48 48 0 1 0 -96 0 48 48 0 1 0 96 0zM400 384a48 48 0 1 0 0-96 48 48 0 1 0 0 96zm48 80a48 48 0 1 0 -96 0 48 48 0 1 0 96 0zm128 0a48 48 0 1 0 -96 0 48 48 0 1 0 96 0zM272 384a48 48 0 1 0 0-96 48 48 0 1 0 0 96zm48 80a48 48 0 1 0 -96 0 48 48 0 1 0 96 0zM144 512a48 48 0 1 0 0-96 48 48 0 1 0 0 96zM576 336a48 48 0 1 0 -96 0 48 48 0 1 0 96 0zm-48-80a48 48 0 1 0 0-96 48 48 0 1 0 0 96z" } }, "free": ["solid"] }, "arrow-up-right-from-square": { "aliases": { "names": ["external-link"], "unicodes": { "secondary": ["10f08e"] } }, "changes": [ "1.0.0", "5.0.0", "5.11.0", "6.0.0-beta1", "6.1.0", "6.2.0", "6.2.1", "6.3.0", "6.4.0", "6.4.1" ], "ligatures": [], "search": { "terms": ["new", "open", "send", "share"] }, "styles": ["solid"], "unicode": "f08e", "label": "Arrow Up Right From Square", "voted": false, "svg": { "solid": { "last_modified": 1684766330, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M320 0c-17.7 0-32 14.3-32 32s14.3 32 32 32h82.7L201.4 265.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L448 109.3V192c0 17.7 14.3 32 32 32s32-14.3 32-32V32c0-17.7-14.3-32-32-32H320zM80 32C35.8 32 0 67.8 0 112V432c0 44.2 35.8 80 80 80H400c44.2 0 80-35.8 80-80V320c0-17.7-14.3-32-32-32s-32 14.3-32 32V432c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V112c0-8.8 7.2-16 16-16H192c17.7 0 32-14.3 32-32s-14.3-32-32-32H80z" } }, "free": ["solid"] }, "arrow-up-short-wide": { "aliases": { "names": ["sort-amount-up-alt"], "unicodes": { "secondary": ["10f885"] } }, "changes": ["5.9.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["arrange", "filter", "order", "sort-amount-desc"] }, "styles": ["solid"], "unicode": "f885", "label": "Arrow Up Short Wide", "voted": false, "svg": { "solid": { "last_modified": 1684766329, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M151.6 42.4C145.5 35.8 137 32 128 32s-17.5 3.8-23.6 10.4l-88 96c-11.9 13-11.1 33.3 2 45.2s33.3 11.1 45.2-2L96 146.3V448c0 17.7 14.3 32 32 32s32-14.3 32-32V146.3l32.4 35.4c11.9 13 32.2 13.9 45.2 2s13.9-32.2 2-45.2l-88-96zM320 32c-17.7 0-32 14.3-32 32s14.3 32 32 32h32c17.7 0 32-14.3 32-32s-14.3-32-32-32H320zm0 128c-17.7 0-32 14.3-32 32s14.3 32 32 32h96c17.7 0 32-14.3 32-32s-14.3-32-32-32H320zm0 128c-17.7 0-32 14.3-32 32s14.3 32 32 32H480c17.7 0 32-14.3 32-32s-14.3-32-32-32H320zm0 128c-17.7 0-32 14.3-32 32s14.3 32 32 32H544c17.7 0 32-14.3 32-32s-14.3-32-32-32H320z" } }, "free": ["solid"] }, "arrow-up-wide-short": { "aliases": { "names": ["sort-amount-up"], "unicodes": { "secondary": ["10f161"] } }, "changes": [ "3.2.0", "5.0.0", "5.9.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["arrange", "filter", "order", "sort-amount-desc"] }, "styles": ["solid"], "unicode": "f161", "label": "Arrow Up Wide Short", "voted": false, "svg": { "solid": { "last_modified": 1684766329, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M151.6 42.4C145.5 35.8 137 32 128 32s-17.5 3.8-23.6 10.4l-88 96c-11.9 13-11.1 33.3 2 45.2s33.3 11.1 45.2-2L96 146.3V448c0 17.7 14.3 32 32 32s32-14.3 32-32V146.3l32.4 35.4c11.9 13 32.2 13.9 45.2 2s13.9-32.2 2-45.2l-88-96zM320 480h32c17.7 0 32-14.3 32-32s-14.3-32-32-32H320c-17.7 0-32 14.3-32 32s14.3 32 32 32zm0-128h96c17.7 0 32-14.3 32-32s-14.3-32-32-32H320c-17.7 0-32 14.3-32 32s14.3 32 32 32zm0-128H480c17.7 0 32-14.3 32-32s-14.3-32-32-32H320c-17.7 0-32 14.3-32 32s14.3 32 32 32zm0-128H544c17.7 0 32-14.3 32-32s-14.3-32-32-32H320c-17.7 0-32 14.3-32 32s14.3 32 32 32z" } }, "free": ["solid"] }, "arrow-up-z-a": { "aliases": { "names": ["sort-alpha-up-alt"], "unicodes": { "secondary": ["10f882"] } }, "changes": ["5.9.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["alphabetical", "arrange", "filter", "order", "sort-alpha-desc"] }, "styles": ["solid"], "unicode": "f882", "label": "Arrow Up Z A", "voted": false, "svg": { "solid": { "last_modified": 1684766328, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M183.6 42.4C177.5 35.8 169 32 160 32s-17.5 3.8-23.6 10.4l-88 96c-11.9 13-11.1 33.3 2 45.2s33.3 11.1 45.2-2L128 146.3V448c0 17.7 14.3 32 32 32s32-14.3 32-32V146.3l32.4 35.4c11.9 13 32.2 13.9 45.2 2s13.9-32.2 2-45.2l-88-96zM320 64c0 17.7 14.3 32 32 32h50.7l-73.4 73.4c-9.2 9.2-11.9 22.9-6.9 34.9s16.6 19.8 29.6 19.8H480c17.7 0 32-14.3 32-32s-14.3-32-32-32H429.3l73.4-73.4c9.2-9.2 11.9-22.9 6.9-34.9s-16.6-19.8-29.6-19.8H352c-17.7 0-32 14.3-32 32zm96 192c-12.1 0-23.2 6.8-28.6 17.7l-64 128-16 32c-7.9 15.8-1.5 35 14.3 42.9s35 1.5 42.9-14.3l7.2-14.3h88.4l7.2 14.3c7.9 15.8 27.1 22.2 42.9 14.3s22.2-27.1 14.3-42.9l-16-32-64-128C439.2 262.8 428.1 256 416 256zM395.8 400L416 359.6 436.2 400H395.8z" } }, "free": ["solid"] }, "arrows-down-to-line": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["scale down", "sink"] }, "styles": ["solid"], "unicode": "e4b8", "label": "Arrows Down To Line", "voted": false, "svg": { "solid": { "last_modified": 1684766329, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M544 416L32 416c-17.7 0-32 14.3-32 32s14.3 32 32 32l512 0c17.7 0 32-14.3 32-32s-14.3-32-32-32zm22.6-137.4c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L480 274.7 480 64c0-17.7-14.3-32-32-32s-32 14.3-32 32l0 210.7-41.4-41.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l96 96c12.5 12.5 32.8 12.5 45.3 0l96-96zm-320-45.3c-12.5-12.5-32.8-12.5-45.3 0L160 274.7 160 64c0-17.7-14.3-32-32-32s-32 14.3-32 32l0 210.7L54.6 233.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l96 96c12.5 12.5 32.8 12.5 45.3 0l96-96c12.5-12.5 12.5-32.8 0-45.3z" } }, "free": ["solid"] }, "arrows-down-to-people": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["affected", "focus", "targeted"] }, "styles": ["solid"], "unicode": "e4b9", "label": "Arrows Down To People", "voted": false, "svg": { "solid": { "last_modified": 1684767532, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M144 0c-13.3 0-24 10.7-24 24V142.1L97 119c-9.4-9.4-24.6-9.4-33.9 0s-9.4 24.6 0 33.9l64 64c9.4 9.4 24.6 9.4 33.9 0l64-64c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0l-23 23V24c0-13.3-10.7-24-24-24zM360 200a40 40 0 1 0 -80 0 40 40 0 1 0 80 0zM184 296a40 40 0 1 0 -80 0 40 40 0 1 0 80 0zm312 40a40 40 0 1 0 0-80 40 40 0 1 0 0 80zM200 441.5l26.9 49.9c6.3 11.7 20.8 16 32.5 9.8s16-20.8 9.8-32.5l-36.3-67.5c1.7-1.7 3.2-3.6 4.3-5.8L264 345.5V400c0 17.7 14.3 32 32 32h48c17.7 0 32-14.3 32-32V345.5l26.9 49.9c1.2 2.2 2.6 4.1 4.3 5.8l-36.3 67.5c-6.3 11.7-1.9 26.2 9.8 32.5s26.2 1.9 32.5-9.8L440 441.5V480c0 17.7 14.3 32 32 32h48c17.7 0 32-14.3 32-32V441.5l26.9 49.9c6.3 11.7 20.8 16 32.5 9.8s16-20.8 9.8-32.5l-37.9-70.3c-15.3-28.5-45.1-46.3-77.5-46.3H486.2c-16.3 0-31.9 4.5-45.4 12.6l-33.6-62.3c-15.3-28.5-45.1-46.3-77.5-46.3H310.2c-32.4 0-62.1 17.8-77.5 46.3l-33.6 62.3c-13.5-8.1-29.1-12.6-45.4-12.6H134.2c-32.4 0-62.1 17.8-77.5 46.3L18.9 468.6c-6.3 11.7-1.9 26.2 9.8 32.5s26.2 1.9 32.5-9.8L88 441.5V480c0 17.7 14.3 32 32 32h48c17.7 0 32-14.3 32-32V441.5zM415 153l64 64c9.4 9.4 24.6 9.4 33.9 0l64-64c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0l-23 23V24c0-13.3-10.7-24-24-24s-24 10.7-24 24V142.1l-23-23c-9.4-9.4-24.6-9.4-33.9 0s-9.4 24.6 0 33.9z" } }, "free": ["solid"] }, "arrows-left-right": { "aliases": { "names": ["arrows-h"], "unicodes": { "secondary": ["10f07e"] } }, "changes": ["1.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["expand", "horizontal", "landscape", "resize", "wide"] }, "styles": ["solid"], "unicode": "f07e", "label": "Arrows Left Right", "voted": false, "svg": { "solid": { "last_modified": 1684766331, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M406.6 374.6l96-96c12.5-12.5 12.5-32.8 0-45.3l-96-96c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L402.7 224l-293.5 0 41.4-41.4c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-96 96c-12.5 12.5-12.5 32.8 0 45.3l96 96c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L109.3 288l293.5 0-41.4 41.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0z" } }, "free": ["solid"] }, "arrows-left-right-to-line": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["analysis", "expand", "gap"] }, "styles": ["solid"], "unicode": "e4ba", "label": "Arrows Left Right To Line", "voted": false, "svg": { "solid": { "last_modified": 1684766329, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M32 64c17.7 0 32 14.3 32 32l0 320c0 17.7-14.3 32-32 32s-32-14.3-32-32V96C0 78.3 14.3 64 32 64zm214.6 73.4c12.5 12.5 12.5 32.8 0 45.3L205.3 224l229.5 0-41.4-41.4c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l96 96c12.5 12.5 12.5 32.8 0 45.3l-96 96c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L434.7 288l-229.5 0 41.4 41.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0l-96-96c-12.5-12.5-12.5-32.8 0-45.3l96-96c12.5-12.5 32.8-12.5 45.3 0zM640 96V416c0 17.7-14.3 32-32 32s-32-14.3-32-32V96c0-17.7 14.3-32 32-32s32 14.3 32 32z" } }, "free": ["solid"] }, "arrows-rotate": { "aliases": { "names": ["refresh", "sync"], "unicodes": { "composite": ["1f5d8"], "secondary": ["10f021"] } }, "changes": [ "1.0.0", "5.0.0", "5.8.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Clockwise Right and Left Semicircle Arrows", "exchange", "refresh", "reload", "rotate", "swap" ] }, "styles": ["solid"], "unicode": "f021", "label": "Arrows Rotate", "voted": false, "svg": { "solid": { "last_modified": 1684766331, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M105.1 202.6c7.7-21.8 20.2-42.3 37.8-59.8c62.5-62.5 163.8-62.5 226.3 0L386.3 160H336c-17.7 0-32 14.3-32 32s14.3 32 32 32H463.5c0 0 0 0 0 0h.4c17.7 0 32-14.3 32-32V64c0-17.7-14.3-32-32-32s-32 14.3-32 32v51.2L414.4 97.6c-87.5-87.5-229.3-87.5-316.8 0C73.2 122 55.6 150.7 44.8 181.4c-5.9 16.7 2.9 34.9 19.5 40.8s34.9-2.9 40.8-19.5zM39 289.3c-5 1.5-9.8 4.2-13.7 8.2c-4 4-6.7 8.8-8.1 14c-.3 1.2-.6 2.5-.8 3.8c-.3 1.7-.4 3.4-.4 5.1V448c0 17.7 14.3 32 32 32s32-14.3 32-32V396.9l17.6 17.5 0 0c87.5 87.4 229.3 87.4 316.7 0c24.4-24.4 42.1-53.1 52.9-83.7c5.9-16.7-2.9-34.9-19.5-40.8s-34.9 2.9-40.8 19.5c-7.7 21.8-20.2 42.3-37.8 59.8c-62.5 62.5-163.8 62.5-226.3 0l-.1-.1L125.6 352H176c17.7 0 32-14.3 32-32s-14.3-32-32-32H48.4c-1.6 0-3.2 .1-4.8 .3s-3.1 .5-4.6 1z" } }, "free": ["solid"] }, "arrows-spin": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["cycle", "rotate", "spin", "whirl"] }, "styles": ["solid"], "unicode": "e4bb", "label": "Arrows Spin", "voted": false, "svg": { "solid": { "last_modified": 1684766328, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 96c38.4 0 73.7 13.5 101.3 36.1l-32.6 32.6c-4.6 4.6-5.9 11.5-3.5 17.4s8.3 9.9 14.8 9.9H448c8.8 0 16-7.2 16-16V64c0-6.5-3.9-12.3-9.9-14.8s-12.9-1.1-17.4 3.5l-34 34C363.4 52.6 312.1 32 256 32c-10.9 0-21.5 .8-32 2.3V99.2c10.3-2.1 21-3.2 32-3.2zM132.1 154.7l32.6 32.6c4.6 4.6 11.5 5.9 17.4 3.5s9.9-8.3 9.9-14.8V64c0-8.8-7.2-16-16-16H64c-6.5 0-12.3 3.9-14.8 9.9s-1.1 12.9 3.5 17.4l34 34C52.6 148.6 32 199.9 32 256c0 10.9 .8 21.5 2.3 32H99.2c-2.1-10.3-3.2-21-3.2-32c0-38.4 13.5-73.7 36.1-101.3zM477.7 224H412.8c2.1 10.3 3.2 21 3.2 32c0 38.4-13.5 73.7-36.1 101.3l-32.6-32.6c-4.6-4.6-11.5-5.9-17.4-3.5s-9.9 8.3-9.9 14.8V448c0 8.8 7.2 16 16 16H448c6.5 0 12.3-3.9 14.8-9.9s1.1-12.9-3.5-17.4l-34-34C459.4 363.4 480 312.1 480 256c0-10.9-.8-21.5-2.3-32zM256 416c-38.4 0-73.7-13.5-101.3-36.1l32.6-32.6c4.6-4.6 5.9-11.5 3.5-17.4s-8.3-9.9-14.8-9.9H64c-8.8 0-16 7.2-16 16l0 112c0 6.5 3.9 12.3 9.9 14.8s12.9 1.1 17.4-3.5l34-34C148.6 459.4 199.9 480 256 480c10.9 0 21.5-.8 32-2.3V412.8c-10.3 2.1-21 3.2-32 3.2z" } }, "free": ["solid"] }, "arrows-split-up-and-left": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["agile", "split"] }, "styles": ["solid"], "unicode": "e4bc", "label": "Arrows Split Up And Left", "voted": false, "svg": { "solid": { "last_modified": 1684766328, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M246.6 150.6c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3l96-96c12.5-12.5 32.8-12.5 45.3 0l96 96c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L352 109.3V384c0 35.3 28.7 64 64 64h64c17.7 0 32 14.3 32 32s-14.3 32-32 32H416c-70.7 0-128-57.3-128-128c0-35.3-28.7-64-64-64H109.3l41.4 41.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0l-96-96c-12.5-12.5-12.5-32.8 0-45.3l96-96c12.5-12.5 32.8-12.5 45.3 0s12.5 32.8 0 45.3L109.3 256H224c23.3 0 45.2 6.2 64 17.1V109.3l-41.4 41.4z" } }, "free": ["solid"] }, "arrows-to-circle": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "center", "concentrate", "coordinate", "coordination", "focal point", "focus" ] }, "styles": ["solid"], "unicode": "e4bd", "label": "Arrows To Circle", "voted": false, "svg": { "solid": { "last_modified": 1684766332, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M9.4 9.4C21.9-3.1 42.1-3.1 54.6 9.4L160 114.7V96c0-17.7 14.3-32 32-32s32 14.3 32 32v96c0 4.3-.9 8.5-2.4 12.2c-1.6 3.7-3.8 7.3-6.9 10.3l-.1 .1c-3.1 3-6.6 5.3-10.3 6.9c-3.8 1.6-7.9 2.4-12.2 2.4H96c-17.7 0-32-14.3-32-32s14.3-32 32-32h18.7L9.4 54.6C-3.1 42.1-3.1 21.9 9.4 9.4zM256 256a64 64 0 1 1 128 0 64 64 0 1 1 -128 0zM114.7 352H96c-17.7 0-32-14.3-32-32s14.3-32 32-32h96 0l.1 0c8.8 0 16.7 3.6 22.5 9.3l.1 .1c3 3.1 5.3 6.6 6.9 10.3c1.6 3.8 2.4 7.9 2.4 12.2v96c0 17.7-14.3 32-32 32s-32-14.3-32-32V397.3L54.6 502.6c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L114.7 352zM416 96c0-17.7 14.3-32 32-32s32 14.3 32 32v18.7L585.4 9.4c12.5-12.5 32.8-12.5 45.3 0s12.5 32.8 0 45.3L525.3 160H544c17.7 0 32 14.3 32 32s-14.3 32-32 32H448c-8.8 0-16.8-3.6-22.6-9.3l-.1-.1c-3-3.1-5.3-6.6-6.9-10.3s-2.4-7.8-2.4-12.2l0-.1v0V96zM525.3 352L630.6 457.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L480 397.3V416c0 17.7-14.3 32-32 32s-32-14.3-32-32V320v0c0 0 0-.1 0-.1c0-4.3 .9-8.4 2.4-12.2c1.6-3.8 3.9-7.3 6.9-10.4c5.8-5.8 13.7-9.3 22.5-9.4c0 0 .1 0 .1 0h0 96c17.7 0 32 14.3 32 32s-14.3 32-32 32H525.3z" } }, "free": ["solid"] }, "arrows-to-dot": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["assembly point", "center", "condense", "focus", "minimize"] }, "styles": ["solid"], "unicode": "e4be", "label": "Arrows To Dot", "voted": false, "svg": { "solid": { "last_modified": 1684766331, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 0c17.7 0 32 14.3 32 32V64h32c12.9 0 24.6 7.8 29.6 19.8s2.2 25.7-6.9 34.9l-64 64c-12.5 12.5-32.8 12.5-45.3 0l-64-64c-9.2-9.2-11.9-22.9-6.9-34.9s16.6-19.8 29.6-19.8h32V32c0-17.7 14.3-32 32-32zM169.4 393.4l64-64c12.5-12.5 32.8-12.5 45.3 0l64 64c9.2 9.2 11.9 22.9 6.9 34.9s-16.6 19.8-29.6 19.8H288v32c0 17.7-14.3 32-32 32s-32-14.3-32-32V448H192c-12.9 0-24.6-7.8-29.6-19.8s-2.2-25.7 6.9-34.9zM32 224H64V192c0-12.9 7.8-24.6 19.8-29.6s25.7-2.2 34.9 6.9l64 64c12.5 12.5 12.5 32.8 0 45.3l-64 64c-9.2 9.2-22.9 11.9-34.9 6.9s-19.8-16.6-19.8-29.6V288H32c-17.7 0-32-14.3-32-32s14.3-32 32-32zm297.4 54.6c-12.5-12.5-12.5-32.8 0-45.3l64-64c9.2-9.2 22.9-11.9 34.9-6.9s19.8 16.6 19.8 29.6v32h32c17.7 0 32 14.3 32 32s-14.3 32-32 32H448v32c0 12.9-7.8 24.6-19.8 29.6s-25.7 2.2-34.9-6.9l-64-64zM256 224a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" } }, "free": ["solid"] }, "arrows-to-eye": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["center", "coordinated assessment", "focus"] }, "styles": ["solid"], "unicode": "e4bf", "label": "Arrows To Eye", "voted": false, "svg": { "solid": { "last_modified": 1684767367, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M15 15C24.4 5.7 39.6 5.7 49 15l63 63V40c0-13.3 10.7-24 24-24s24 10.7 24 24v96c0 13.3-10.7 24-24 24H40c-13.3 0-24-10.7-24-24s10.7-24 24-24H78.1L15 49C5.7 39.6 5.7 24.4 15 15zM133.5 243.9C158.6 193.6 222.7 112 320 112s161.4 81.6 186.5 131.9c3.8 7.6 3.8 16.5 0 24.2C481.4 318.4 417.3 400 320 400s-161.4-81.6-186.5-131.9c-3.8-7.6-3.8-16.5 0-24.2zM320 320a64 64 0 1 0 0-128 64 64 0 1 0 0 128zM591 15c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-63 63H600c13.3 0 24 10.7 24 24s-10.7 24-24 24H504c-13.3 0-24-10.7-24-24V40c0-13.3 10.7-24 24-24s24 10.7 24 24V78.1l63-63zM15 497c-9.4-9.4-9.4-24.6 0-33.9l63-63H40c-13.3 0-24-10.7-24-24s10.7-24 24-24h96c13.3 0 24 10.7 24 24v96c0 13.3-10.7 24-24 24s-24-10.7-24-24V433.9L49 497c-9.4 9.4-24.6 9.4-33.9 0zm576 0l-63-63V472c0 13.3-10.7 24-24 24s-24-10.7-24-24V376c0-13.3 10.7-24 24-24h96c13.3 0 24 10.7 24 24s-10.7 24-24 24H561.9l63 63c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0z" } }, "free": ["solid"] }, "arrows-turn-right": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["arrows"] }, "styles": ["solid"], "unicode": "e4c0", "label": "Arrows Turn Right", "voted": false, "svg": { "solid": { "last_modified": 1684766331, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M297.4 9.4c12.5-12.5 32.8-12.5 45.3 0l96 96c12.5 12.5 12.5 32.8 0 45.3l-96 96c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L338.7 160H128c-35.3 0-64 28.7-64 64v32c0 17.7-14.3 32-32 32s-32-14.3-32-32V224C0 153.3 57.3 96 128 96H338.7L297.4 54.6c-12.5-12.5-12.5-32.8 0-45.3zm-96 256c12.5-12.5 32.8-12.5 45.3 0l96 96c12.5 12.5 12.5 32.8 0 45.3l-96 96c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L242.7 416H96c-17.7 0-32 14.3-32 32v32c0 17.7-14.3 32-32 32s-32-14.3-32-32V448c0-53 43-96 96-96H242.7l-41.4-41.4c-12.5-12.5-12.5-32.8 0-45.3z" } }, "free": ["solid"] }, "arrows-turn-to-dots": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["destination", "nexus"] }, "styles": ["solid"], "unicode": "e4c1", "label": "Arrows Turn To Dots", "voted": false, "svg": { "solid": { "last_modified": 1684766329, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M249.4 25.4c12.5-12.5 32.8-12.5 45.3 0s12.5 32.8 0 45.3L269.3 96 416 96c53 0 96 43 96 96v32c0 17.7-14.3 32-32 32s-32-14.3-32-32V192c0-17.7-14.3-32-32-32l-146.7 0 25.4 25.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0l-80-80c-12.5-12.5-12.5-32.8 0-45.3l80-80zm13.3 256l80 80c12.5 12.5 12.5 32.8 0 45.3l-80 80c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L242.7 416 96 416c-17.7 0-32 14.3-32 32v32c0 17.7-14.3 32-32 32s-32-14.3-32-32V448c0-53 43-96 96-96l146.7 0-25.4-25.4c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0zM384 384a64 64 0 1 1 128 0 64 64 0 1 1 -128 0zM64 192A64 64 0 1 1 64 64a64 64 0 1 1 0 128z" } }, "free": ["solid"] }, "arrows-up-down": { "aliases": { "names": ["arrows-v"], "unicodes": { "secondary": ["10f07d"] } }, "changes": ["1.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["expand", "portrait", "resize", "tall", "vertical"] }, "styles": ["solid"], "unicode": "f07d", "label": "Arrows Up Down", "voted": false, "svg": { "solid": { "last_modified": 1684766328, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M182.6 9.4c-12.5-12.5-32.8-12.5-45.3 0l-96 96c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L128 109.3V402.7L86.6 361.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l96 96c12.5 12.5 32.8 12.5 45.3 0l96-96c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L192 402.7V109.3l41.4 41.4c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3l-96-96z" } }, "free": ["solid"] }, "arrows-up-down-left-right": { "aliases": { "names": ["arrows"], "unicodes": { "secondary": ["10f047"] } }, "changes": ["1.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "arrow", "arrows", "bigger", "enlarge", "expand", "fullscreen", "move", "position", "reorder", "resize" ] }, "styles": ["solid"], "unicode": "f047", "label": "Arrows Up Down Left Right", "voted": false, "svg": { "solid": { "last_modified": 1684766329, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M278.6 9.4c-12.5-12.5-32.8-12.5-45.3 0l-64 64c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l9.4-9.4V224H109.3l9.4-9.4c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-64 64c-12.5 12.5-12.5 32.8 0 45.3l64 64c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3l-9.4-9.4H224V402.7l-9.4-9.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l64 64c12.5 12.5 32.8 12.5 45.3 0l64-64c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-9.4 9.4V288H402.7l-9.4 9.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l64-64c12.5-12.5 12.5-32.8 0-45.3l-64-64c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l9.4 9.4H288V109.3l9.4 9.4c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3l-64-64z" } }, "free": ["solid"] }, "arrows-up-to-line": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["rise", "scale up"] }, "styles": ["solid"], "unicode": "e4c2", "label": "Arrows Up To Line", "voted": false, "svg": { "solid": { "last_modified": 1684766332, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M32 96l512 0c17.7 0 32-14.3 32-32s-14.3-32-32-32L32 32C14.3 32 0 46.3 0 64S14.3 96 32 96zM9.4 233.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L96 237.3 96 448c0 17.7 14.3 32 32 32s32-14.3 32-32l0-210.7 41.4 41.4c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3l-96-96c-12.5-12.5-32.8-12.5-45.3 0l-96 96zm320 45.3c12.5 12.5 32.8 12.5 45.3 0L416 237.3 416 448c0 17.7 14.3 32 32 32s32-14.3 32-32l0-210.7 41.4 41.4c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3l-96-96c-12.5-12.5-32.8-12.5-45.3 0l-96 96c-12.5 12.5-12.5 32.8 0 45.3z" } }, "free": ["solid"] }, "artstation": { "changes": ["5.6.0", "5.8.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f77a", "label": "Artstation", "voted": true, "svg": { "brands": { "last_modified": 1660014480, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M2 377.4l43 74.3A51.35 51.35 0 0 0 90.9 480h285.4l-59.2-102.6zM501.8 350L335.6 59.3A51.38 51.38 0 0 0 290.2 32h-88.4l257.3 447.6 40.7-70.5c1.9-3.2 21-29.7 2-59.1zM275 304.5l-115.5-200L44 304.5z" } }, "free": ["brands"] }, "asterisk": { "aliases": { "unicodes": { "composite": ["2731", "f069"], "primary": ["f069"], "secondary": ["102a", "10f069"] } }, "changes": ["1.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "Asterisk", "Heavy Asterisk", "annotation", "details", "reference", "star" ] }, "styles": ["solid"], "unicode": "2a", "label": "Asterisk", "voted": false, "svg": { "solid": { "last_modified": 1684767247, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M192 32c17.7 0 32 14.3 32 32V199.5l111.5-66.9c15.2-9.1 34.8-4.2 43.9 11s4.2 34.8-11 43.9L254.2 256l114.3 68.6c15.2 9.1 20.1 28.7 11 43.9s-28.7 20.1-43.9 11L224 312.5V448c0 17.7-14.3 32-32 32s-32-14.3-32-32V312.5L48.5 379.4c-15.2 9.1-34.8 4.2-43.9-11s-4.2-34.8 11-43.9L129.8 256 15.5 187.4c-15.2-9.1-20.1-28.7-11-43.9s28.7-20.1 43.9-11L160 199.5V64c0-17.7 14.3-32 32-32z" } }, "free": ["solid"] }, "asymmetrik": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f372", "label": "Asymmetrik, Ltd.", "voted": false, "svg": { "brands": { "last_modified": 1660014474, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M517.5 309.2c38.8-40 58.1-80 58.5-116.1.8-65.5-59.4-118.2-169.4-135C277.9 38.4 118.1 73.6 0 140.5 52 114 110.6 92.3 170.7 82.3c74.5-20.5 153-25.4 221.3-14.8C544.5 91.3 588.8 195 490.8 299.2c-10.2 10.8-22 21.1-35 30.6L304.9 103.4 114.7 388.9c-65.6-29.4-76.5-90.2-19.1-151.2 20.8-22.2 48.3-41.9 79.5-58.1 20-12.2 39.7-22.6 62-30.7-65.1 20.3-122.7 52.9-161.6 92.9-27.7 28.6-41.4 57.1-41.7 82.9-.5 35.1 23.4 65.1 68.4 83l-34.5 51.7h101.6l22-34.4c22.2 1 45.3 0 68.6-2.7l-22.8 37.1h135.5L340 406.3c18.6-5.3 36.9-11.5 54.5-18.7l45.9 71.8H542L468.6 349c18.5-12.1 35-25.5 48.9-39.8zm-187.6 80.5l-25-40.6-32.7 53.3c-23.4 3.5-46.7 5.1-69.2 4.4l101.9-159.3 78.7 123c-17.2 7.4-35.3 13.9-53.7 19.2z" } }, "free": ["brands"] }, "at": { "aliases": { "unicodes": { "composite": ["f1fa"], "primary": ["f1fa"], "secondary": ["10f1fa"] } }, "changes": ["4.2.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "Commercial At", "address", "author", "e-mail", "email", "fluctuate", "handle" ] }, "styles": ["solid"], "unicode": "40", "label": "At", "voted": false, "svg": { "solid": { "last_modified": 1684767248, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 64C150 64 64 150 64 256s86 192 192 192c17.7 0 32 14.3 32 32s-14.3 32-32 32C114.6 512 0 397.4 0 256S114.6 0 256 0S512 114.6 512 256v32c0 53-43 96-96 96c-29.3 0-55.6-13.2-73.2-33.9C320 371.1 289.5 384 256 384c-70.7 0-128-57.3-128-128s57.3-128 128-128c27.9 0 53.7 8.9 74.7 24.1c5.7-5 13.1-8.1 21.3-8.1c17.7 0 32 14.3 32 32v80 32c0 17.7 14.3 32 32 32s32-14.3 32-32V256c0-106-86-192-192-192zm64 192a64 64 0 1 0 -128 0 64 64 0 1 0 128 0z" } }, "free": ["solid"] }, "atlassian": { "changes": ["5.6.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f77b", "label": "Atlassian", "voted": true, "svg": { "brands": { "last_modified": 1660014479, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M152.2 236.4c-7.7-8.2-19.7-7.7-24.8 2.8L1.6 490.2c-5 10 2.4 21.7 13.4 21.7h175c5.8.1 11-3.2 13.4-8.4 37.9-77.8 15.1-196.3-51.2-267.1zM244.4 8.1c-122.3 193.4-8.5 348.6 65 495.5 2.5 5.1 7.7 8.4 13.4 8.4H497c11.2 0 18.4-11.8 13.4-21.7 0 0-234.5-470.6-240.4-482.3-5.3-10.6-18.8-10.8-25.6.1z" } }, "free": ["brands"] }, "atom": { "aliases": { "unicodes": { "composite": ["269b"], "secondary": ["10f5d2"] } }, "changes": ["5.2.0", "5.12.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "atheism", "atheist", "atom", "atom symbol", "chemistry", "electron", "ion", "isotope", "neutron", "nuclear", "proton", "science" ] }, "styles": ["solid"], "unicode": "f5d2", "label": "Atom", "voted": false, "svg": { "solid": { "last_modified": 1684766751, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 398.8c-11.8 5.1-23.4 9.7-34.9 13.5c16.7 33.8 31 35.7 34.9 35.7s18.1-1.9 34.9-35.7c-11.4-3.9-23.1-8.4-34.9-13.5zM446 256c33 45.2 44.3 90.9 23.6 128c-20.2 36.3-62.5 49.3-115.2 43.2c-22 52.1-55.6 84.8-98.4 84.8s-76.4-32.7-98.4-84.8c-52.7 6.1-95-6.8-115.2-43.2C21.7 346.9 33 301.2 66 256c-33-45.2-44.3-90.9-23.6-128c20.2-36.3 62.5-49.3 115.2-43.2C179.6 32.7 213.2 0 256 0s76.4 32.7 98.4 84.8c52.7-6.1 95 6.8 115.2 43.2c20.7 37.1 9.4 82.8-23.6 128zm-65.8 67.4c-1.7 14.2-3.9 28-6.7 41.2c31.8 1.4 38.6-8.7 40.2-11.7c2.3-4.2 7-17.9-11.9-48.1c-6.8 6.3-14 12.5-21.6 18.6zm-6.7-175.9c2.8 13.1 5 26.9 6.7 41.2c7.6 6.1 14.8 12.3 21.6 18.6c18.9-30.2 14.2-44 11.9-48.1c-1.6-2.9-8.4-13-40.2-11.7zM290.9 99.7C274.1 65.9 259.9 64 256 64s-18.1 1.9-34.9 35.7c11.4 3.9 23.1 8.4 34.9 13.5c11.8-5.1 23.4-9.7 34.9-13.5zm-159 88.9c1.7-14.3 3.9-28 6.7-41.2c-31.8-1.4-38.6 8.7-40.2 11.7c-2.3 4.2-7 17.9 11.9 48.1c6.8-6.3 14-12.5 21.6-18.6zM110.2 304.8C91.4 335 96 348.7 98.3 352.9c1.6 2.9 8.4 13 40.2 11.7c-2.8-13.1-5-26.9-6.7-41.2c-7.6-6.1-14.8-12.3-21.6-18.6zM336 256a80 80 0 1 0 -160 0 80 80 0 1 0 160 0zm-80-32a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" } }, "free": ["solid"] }, "audible": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f373", "label": "Audible", "voted": false, "svg": { "brands": { "last_modified": 1660014468, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M640 199.9v54l-320 200L0 254v-54l320 200 320-200.1zm-194.5 72l47.1-29.4c-37.2-55.8-100.7-92.6-172.7-92.6-72 0-135.5 36.7-172.6 92.4h.3c2.5-2.3 5.1-4.5 7.7-6.7 89.7-74.4 219.4-58.1 290.2 36.3zm-220.1 18.8c16.9-11.9 36.5-18.7 57.4-18.7 34.4 0 65.2 18.4 86.4 47.6l45.4-28.4c-20.9-29.9-55.6-49.5-94.8-49.5-38.9 0-73.4 19.4-94.4 49zM103.6 161.1c131.8-104.3 318.2-76.4 417.5 62.1l.7 1 48.8-30.4C517.1 112.1 424.8 58.1 319.9 58.1c-103.5 0-196.6 53.5-250.5 135.6 9.9-10.5 22.7-23.5 34.2-32.6zm467 32.7z" } }, "free": ["brands"] }, "audio-description": { "aliases": { "unicodes": { "secondary": ["10f29e"] } }, "changes": [ "4.6.0", "5.0.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["blind", "narration", "video", "visual"] }, "styles": ["solid"], "unicode": "f29e", "label": "Audio Description", "voted": false, "svg": { "solid": { "last_modified": 1684766676, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H512c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zM213.5 173.3l72 144c5.9 11.9 1.1 26.3-10.7 32.2s-26.3 1.1-32.2-10.7l-9.4-18.9H150.9l-9.4 18.9c-5.9 11.9-20.3 16.7-32.2 10.7s-16.7-20.3-10.7-32.2l72-144c4.1-8.1 12.4-13.3 21.5-13.3s17.4 5.1 21.5 13.3zm-.4 106.6L192 237.7l-21.1 42.2h42.2zM304 184c0-13.3 10.7-24 24-24h56c53 0 96 43 96 96s-43 96-96 96H328c-13.3 0-24-10.7-24-24V184zm48 24v96h32c26.5 0 48-21.5 48-48s-21.5-48-48-48H352z" } }, "free": ["solid"] }, "austral-sign": { "changes": ["6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Austral Sign", "currency"] }, "styles": ["solid"], "unicode": "e0a9", "label": "Austral Sign", "voted": false, "svg": { "solid": { "last_modified": 1684766476, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M253.5 51.7C248.6 39.8 236.9 32 224 32s-24.6 7.8-29.5 19.7L122.7 224H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H96L82.7 320H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H56L34.5 435.7c-6.8 16.3 .9 35 17.2 41.8s35-.9 41.8-17.2L125.3 384H322.7l31.8 76.3c6.8 16.3 25.5 24 41.8 17.2s24-25.5 17.2-41.8L392 384h24c17.7 0 32-14.3 32-32s-14.3-32-32-32H365.3L352 288h64c17.7 0 32-14.3 32-32s-14.3-32-32-32H325.3L253.5 51.7zM256 224H192l32-76.8L256 224zm-90.7 64H282.7L296 320H152l13.3-32z" } }, "free": ["solid"] }, "autoprefixer": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f41c", "label": "Autoprefixer", "voted": false, "svg": { "brands": { "last_modified": 1660014465, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M318.4 16l-161 480h77.5l25.4-81.4h119.5L405 496h77.5L318.4 16zm-40.3 341.9l41.2-130.4h1.5l40.9 130.4h-83.6zM640 405l-10-31.4L462.1 358l19.4 56.5L640 405zm-462.1-47L10 373.7 0 405l158.5 9.4 19.4-56.4z" } }, "free": ["brands"] }, "avianex": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f374", "label": "avianex", "voted": false, "svg": { "brands": { "last_modified": 1660014470, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M453.1 32h-312c-38.9 0-76.2 31.2-83.3 69.7L1.2 410.3C-5.9 448.8 19.9 480 58.9 480h312c38.9 0 76.2-31.2 83.3-69.7l56.7-308.5c7-38.6-18.8-69.8-57.8-69.8zm-58.2 347.3l-32 13.5-115.4-110c-14.7 10-29.2 19.5-41.7 27.1l22.1 64.2-17.9 12.7-40.6-61-52.4-48.1 15.7-15.4 58 31.1c9.3-10.5 20.8-22.6 32.8-34.9L203 228.9l-68.8-99.8 18.8-28.9 8.9-4.8L265 207.8l4.9 4.5c19.4-18.8 33.8-32.4 33.8-32.4 7.7-6.5 21.5-2.9 30.7 7.9 9 10.5 10.6 24.7 2.7 31.3-1.8 1.3-15.5 11.4-35.3 25.6l4.5 7.3 94.9 119.4-6.3 7.9z" } }, "free": ["brands"] }, "aviato": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f421", "label": "Aviato", "voted": false, "svg": { "brands": { "last_modified": 1660014468, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M107.2 283.5l-19-41.8H36.1l-19 41.8H0l62.2-131.4 62.2 131.4h-17.2zm-45-98.1l-19.6 42.5h39.2l-19.6-42.5zm112.7 102.4l-62.2-131.4h17.1l45.1 96 45.1-96h17l-62.1 131.4zm80.6-4.3V156.4H271v127.1h-15.5zm209.1-115.6v115.6h-17.3V167.9h-41.2v-11.5h99.6v11.5h-41.1zM640 218.8c0 9.2-1.7 17.8-5.1 25.8-3.4 8-8.2 15.1-14.2 21.1-6 6-13.1 10.8-21.1 14.2-8 3.4-16.6 5.1-25.8 5.1s-17.8-1.7-25.8-5.1c-8-3.4-15.1-8.2-21.1-14.2-6-6-10.8-13-14.2-21.1-3.4-8-5.1-16.6-5.1-25.8s1.7-17.8 5.1-25.8c3.4-8 8.2-15.1 14.2-21.1 6-6 13-8.4 21.1-11.9 8-3.4 16.6-5.1 25.8-5.1s17.8 1.7 25.8 5.1c8 3.4 15.1 5.8 21.1 11.9 6 6 10.7 13.1 14.2 21.1 3.4 8 5.1 16.6 5.1 25.8zm-15.5 0c0-7.3-1.3-14-3.9-20.3-2.6-6.3-6.2-11.7-10.8-16.3-4.6-4.6-10-8.2-16.2-10.9-6.2-2.7-12.8-4-19.8-4s-13.6 1.3-19.8 4c-6.2 2.7-11.6 6.3-16.2 10.9-4.6 4.6-8.2 10-10.8 16.3-2.6 6.3-3.9 13.1-3.9 20.3 0 7.3 1.3 14 3.9 20.3 2.6 6.3 6.2 11.7 10.8 16.3 4.6 4.6 10 8.2 16.2 10.9 6.2 2.7 12.8 4 19.8 4s13.6-1.3 19.8-4c6.2-2.7 11.6-6.3 16.2-10.9 4.6-4.6 8.2-10 10.8-16.3 2.6-6.3 3.9-13.1 3.9-20.3zm-94.8 96.7v-6.3l88.9-10-242.9 13.4c.6-2.2 1.1-4.6 1.4-7.2.3-2 .5-4.2.6-6.5l64.8-8.1-64.9 1.9c0-.4-.1-.7-.1-1.1-2.8-17.2-25.5-23.7-25.5-23.7l-1.1-26.3h23.8l19 41.8h17.1L348.6 152l-62.2 131.4h17.1l19-41.8h23.6L345 268s-22.7 6.5-25.5 23.7c-.1.3-.1.7-.1 1.1l-64.9-1.9 64.8 8.1c.1 2.3.3 4.4.6 6.5.3 2.6.8 5 1.4 7.2L78.4 299.2l88.9 10v6.3c-5.9.9-10.5 6-10.5 12.2 0 6.8 5.6 12.4 12.4 12.4 6.8 0 12.4-5.6 12.4-12.4 0-6.2-4.6-11.3-10.5-12.2v-5.8l80.3 9v5.4c-5.7 1.1-9.9 6.2-9.9 12.1 0 6.8 5.6 10.2 12.4 10.2 6.8 0 12.4-3.4 12.4-10.2 0-6-4.3-11-9.9-12.1v-4.9l28.4 3.2v23.7h-5.9V360h5.9v-6.6h5v6.6h5.9v-13.8h-5.9V323l38.3 4.3c8.1 11.4 19 13.6 19 13.6l-.1 6.7-5.1.2-.1 12.1h4.1l.1-5h5.2l.1 5h4.1l-.1-12.1-5.1-.2-.1-6.7s10.9-2.1 19-13.6l38.3-4.3v23.2h-5.9V360h5.9v-6.6h5v6.6h5.9v-13.8h-5.9v-23.7l28.4-3.2v4.9c-5.7 1.1-9.9 6.2-9.9 12.1 0 6.8 5.6 10.2 12.4 10.2 6.8 0 12.4-3.4 12.4-10.2 0-6-4.3-11-9.9-12.1v-5.4l80.3-9v5.8c-5.9.9-10.5 6-10.5 12.2 0 6.8 5.6 12.4 12.4 12.4 6.8 0 12.4-5.6 12.4-12.4-.2-6.3-4.7-11.4-10.7-12.3zm-200.8-87.6l19.6-42.5 19.6 42.5h-17.9l-1.7-40.3-1.7 40.3h-17.9z" } }, "free": ["brands"] }, "award": { "aliases": { "unicodes": { "secondary": ["10f559"] } }, "changes": [ "5.1.0", "5.2.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["honor", "praise", "prize", "recognition", "ribbon", "trophy"] }, "styles": ["solid"], "unicode": "f559", "label": "Award", "voted": true, "svg": { "solid": { "last_modified": 1684767601, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M173.8 5.5c11-7.3 25.4-7.3 36.4 0L228 17.2c6 3.9 13 5.8 20.1 5.4l21.3-1.3c13.2-.8 25.6 6.4 31.5 18.2l9.6 19.1c3.2 6.4 8.4 11.5 14.7 14.7L344.5 83c11.8 5.9 19 18.3 18.2 31.5l-1.3 21.3c-.4 7.1 1.5 14.2 5.4 20.1l11.8 17.8c7.3 11 7.3 25.4 0 36.4L366.8 228c-3.9 6-5.8 13-5.4 20.1l1.3 21.3c.8 13.2-6.4 25.6-18.2 31.5l-19.1 9.6c-6.4 3.2-11.5 8.4-14.7 14.7L301 344.5c-5.9 11.8-18.3 19-31.5 18.2l-21.3-1.3c-7.1-.4-14.2 1.5-20.1 5.4l-17.8 11.8c-11 7.3-25.4 7.3-36.4 0L156 366.8c-6-3.9-13-5.8-20.1-5.4l-21.3 1.3c-13.2 .8-25.6-6.4-31.5-18.2l-9.6-19.1c-3.2-6.4-8.4-11.5-14.7-14.7L39.5 301c-11.8-5.9-19-18.3-18.2-31.5l1.3-21.3c.4-7.1-1.5-14.2-5.4-20.1L5.5 210.2c-7.3-11-7.3-25.4 0-36.4L17.2 156c3.9-6 5.8-13 5.4-20.1l-1.3-21.3c-.8-13.2 6.4-25.6 18.2-31.5l19.1-9.6C65 70.2 70.2 65 73.4 58.6L83 39.5c5.9-11.8 18.3-19 31.5-18.2l21.3 1.3c7.1 .4 14.2-1.5 20.1-5.4L173.8 5.5zM272 192a80 80 0 1 0 -160 0 80 80 0 1 0 160 0zM1.3 441.8L44.4 339.3c.2 .1 .3 .2 .4 .4l9.6 19.1c11.7 23.2 36 37.3 62 35.8l21.3-1.3c.2 0 .5 0 .7 .2l17.8 11.8c5.1 3.3 10.5 5.9 16.1 7.7l-37.6 89.3c-2.3 5.5-7.4 9.2-13.3 9.7s-11.6-2.2-14.8-7.2L74.4 455.5l-56.1 8.3c-5.7 .8-11.4-1.5-15-6s-4.3-10.7-2.1-16zm248 60.4L211.7 413c5.6-1.8 11-4.3 16.1-7.7l17.8-11.8c.2-.1 .4-.2 .7-.2l21.3 1.3c26 1.5 50.3-12.6 62-35.8l9.6-19.1c.1-.2 .2-.3 .4-.4l43.2 102.5c2.2 5.3 1.4 11.4-2.1 16s-9.3 6.9-15 6l-56.1-8.3-32.2 49.2c-3.2 5-8.9 7.7-14.8 7.2s-11-4.3-13.3-9.7z" } }, "free": ["solid"] }, "aws": { "changes": ["5.0.0", "5.1.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f375", "label": "Amazon Web Services (AWS)", "voted": false, "svg": { "brands": { "last_modified": 1660014482, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M180.41 203.01c-.72 22.65 10.6 32.68 10.88 39.05a8.164 8.164 0 0 1-4.1 6.27l-12.8 8.96a10.66 10.66 0 0 1-5.63 1.92c-.43-.02-8.19 1.83-20.48-25.61a78.608 78.608 0 0 1-62.61 29.45c-16.28.89-60.4-9.24-58.13-56.21-1.59-38.28 34.06-62.06 70.93-60.05 7.1.02 21.6.37 46.99 6.27v-15.62c2.69-26.46-14.7-46.99-44.81-43.91-2.4.01-19.4-.5-45.84 10.11-7.36 3.38-8.3 2.82-10.75 2.82-7.41 0-4.36-21.48-2.94-24.2 5.21-6.4 35.86-18.35 65.94-18.18a76.857 76.857 0 0 1 55.69 17.28 70.285 70.285 0 0 1 17.67 52.36l-.01 69.29zM93.99 235.4c32.43-.47 46.16-19.97 49.29-30.47 2.46-10.05 2.05-16.41 2.05-27.4-9.67-2.32-23.59-4.85-39.56-4.87-15.15-1.14-42.82 5.63-41.74 32.26-1.24 16.79 11.12 31.4 29.96 30.48zm170.92 23.05c-7.86.72-11.52-4.86-12.68-10.37l-49.8-164.65c-.97-2.78-1.61-5.65-1.92-8.58a4.61 4.61 0 0 1 3.86-5.25c.24-.04-2.13 0 22.25 0 8.78-.88 11.64 6.03 12.55 10.37l35.72 140.83 33.16-140.83c.53-3.22 2.94-11.07 12.8-10.24h17.16c2.17-.18 11.11-.5 12.68 10.37l33.42 142.63L420.98 80.1c.48-2.18 2.72-11.37 12.68-10.37h19.72c.85-.13 6.15-.81 5.25 8.58-.43 1.85 3.41-10.66-52.75 169.9-1.15 5.51-4.82 11.09-12.68 10.37h-18.69c-10.94 1.15-12.51-9.66-12.68-10.75L328.67 110.7l-32.78 136.99c-.16 1.09-1.73 11.9-12.68 10.75h-18.3zm273.48 5.63c-5.88.01-33.92-.3-57.36-12.29a12.802 12.802 0 0 1-7.81-11.91v-10.75c0-8.45 6.2-6.9 8.83-5.89 10.04 4.06 16.48 7.14 28.81 9.6 36.65 7.53 52.77-2.3 56.72-4.48 13.15-7.81 14.19-25.68 5.25-34.95-10.48-8.79-15.48-9.12-53.13-21-4.64-1.29-43.7-13.61-43.79-52.36-.61-28.24 25.05-56.18 69.52-55.95 12.67-.01 46.43 4.13 55.57 15.62 1.35 2.09 2.02 4.55 1.92 7.04v10.11c0 4.44-1.62 6.66-4.87 6.66-7.71-.86-21.39-11.17-49.16-10.75-6.89-.36-39.89.91-38.41 24.97-.43 18.96 26.61 26.07 29.7 26.89 36.46 10.97 48.65 12.79 63.12 29.58 17.14 22.25 7.9 48.3 4.35 55.44-19.08 37.49-68.42 34.44-69.26 34.42zm40.2 104.86c-70.03 51.72-171.69 79.25-258.49 79.25A469.127 469.127 0 0 1 2.83 327.46c-6.53-5.89-.77-13.96 7.17-9.47a637.37 637.37 0 0 0 316.88 84.12 630.22 630.22 0 0 0 241.59-49.55c11.78-5 21.77 7.8 10.12 16.38zm29.19-33.29c-8.96-11.52-59.28-5.38-81.81-2.69-6.79.77-7.94-5.12-1.79-9.47 40.07-28.17 105.88-20.1 113.44-10.63 7.55 9.47-2.05 75.41-39.56 106.91-5.76 4.87-11.27 2.3-8.71-4.1 8.44-21.25 27.39-68.49 18.43-80.02z" } }, "free": ["brands"] }, "b": { "aliases": { "unicodes": { "composite": ["62"] } }, "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Latin Capital Letter B", "Latin Small Letter B", "letter"] }, "styles": ["solid"], "unicode": "42", "label": "B", "voted": false, "svg": { "solid": { "last_modified": 1684767245, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M64 32C28.7 32 0 60.7 0 96V256 416c0 35.3 28.7 64 64 64H192c70.7 0 128-57.3 128-128c0-46.5-24.8-87.3-62-109.7c18.7-22.3 30-51 30-82.3c0-70.7-57.3-128-128-128H64zm96 192H64V96h96c35.3 0 64 28.7 64 64s-28.7 64-64 64zM64 288h96 32c35.3 0 64 28.7 64 64s-28.7 64-64 64H64V288z" } }, "free": ["solid"] }, "baby": { "aliases": { "unicodes": { "secondary": ["10f77c"] } }, "changes": ["5.6.0", "5.10.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["users-people"] }, "styles": ["solid"], "unicode": "f77c", "label": "Baby", "voted": true, "svg": { "solid": { "last_modified": 1684767531, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M152 88a72 72 0 1 1 144 0A72 72 0 1 1 152 88zM39.7 144.5c13-17.9 38-21.8 55.9-8.8L131.8 162c26.8 19.5 59.1 30 92.2 30s65.4-10.5 92.2-30l36.2-26.4c17.9-13 42.9-9 55.9 8.8s9 42.9-8.8 55.9l-36.2 26.4c-13.6 9.9-28.1 18.2-43.3 25V288H128V251.7c-15.2-6.7-29.7-15.1-43.3-25L48.5 200.3c-17.9-13-21.8-38-8.8-55.9zm89.8 184.8l60.6 53-26 37.2 24.3 24.3c15.6 15.6 15.6 40.9 0 56.6s-40.9 15.6-56.6 0l-48-48C70 438.6 68.1 417 79.2 401.1l50.2-71.8zm128.5 53l60.6-53 50.2 71.8c11.1 15.9 9.2 37.5-4.5 51.2l-48 48c-15.6 15.6-40.9 15.6-56.6 0s-15.6-40.9 0-56.6L284 419.4l-26-37.2z" } }, "free": ["solid"] }, "baby-carriage": { "aliases": { "names": ["carriage-baby"], "unicodes": { "secondary": ["10f77d"] } }, "changes": [ "5.6.0", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "buggy", "carrier", "infant", "push", "stroller", "transportation", "walk", "wheels" ] }, "styles": ["solid"], "unicode": "f77d", "label": "Baby Carriage", "voted": true, "svg": { "solid": { "last_modified": 1684767649, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 192H.1C2.7 117.9 41.3 52.9 99 14.1c13.3-8.9 30.8-4.3 39.9 8.8L256 192zm128-32c0-35.3 28.7-64 64-64h32c17.7 0 32 14.3 32 32s-14.3 32-32 32l-32 0v64c0 25.2-5.8 50.2-17 73.5s-27.8 44.5-48.6 62.3s-45.5 32-72.7 41.6S253.4 416 224 416s-58.5-5-85.7-14.6s-51.9-23.8-72.7-41.6s-37.3-39-48.6-62.3S0 249.2 0 224l224 0 160 0V160zM80 416a48 48 0 1 1 0 96 48 48 0 1 1 0-96zm240 48a48 48 0 1 1 96 0 48 48 0 1 1 -96 0z" } }, "free": ["solid"] }, "backward": { "aliases": { "unicodes": { "composite": ["23ea"], "secondary": ["10f04a"] } }, "changes": ["1.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["arrow", "double", "fast reverse button", "previous", "rewind"] }, "styles": ["solid"], "unicode": "f04a", "label": "Backward", "voted": false, "svg": { "solid": { "last_modified": 1684766677, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M459.5 440.6c9.5 7.9 22.8 9.7 34.1 4.4s18.4-16.6 18.4-29V96c0-12.4-7.2-23.7-18.4-29s-24.5-3.6-34.1 4.4L288 214.3V256v41.7L459.5 440.6zM256 352V256 128 96c0-12.4-7.2-23.7-18.4-29s-24.5-3.6-34.1 4.4l-192 160C4.2 237.5 0 246.5 0 256s4.2 18.5 11.5 24.6l192 160c9.5 7.9 22.8 9.7 34.1 4.4s18.4-16.6 18.4-29V352z" } }, "free": ["solid"] }, "backward-fast": { "aliases": { "names": ["fast-backward"], "unicodes": { "composite": ["23ee"], "secondary": ["10f049"] } }, "changes": ["1.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "arrow", "beginning", "first", "last track button", "previous", "previous scene", "previous track", "rewind", "start", "triangle" ] }, "styles": ["solid"], "unicode": "f049", "label": "Backward Fast", "voted": false, "svg": { "solid": { "last_modified": 1684766676, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M493.6 445c-11.2 5.3-24.5 3.6-34.1-4.4L288 297.7V416c0 12.4-7.2 23.7-18.4 29s-24.5 3.6-34.1-4.4L64 297.7V416c0 17.7-14.3 32-32 32s-32-14.3-32-32V96C0 78.3 14.3 64 32 64s32 14.3 32 32V214.3L235.5 71.4c9.5-7.9 22.8-9.7 34.1-4.4S288 83.6 288 96V214.3L459.5 71.4c9.5-7.9 22.8-9.7 34.1-4.4S512 83.6 512 96V416c0 12.4-7.2 23.7-18.4 29z" } }, "free": ["solid"] }, "backward-step": { "aliases": { "names": ["step-backward"], "unicodes": { "secondary": ["10f048"] } }, "changes": [ "1.0.0", "5.0.0", "5.10.2", "5.11.0", "5.11.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["beginning", "first", "previous", "rewind", "start"] }, "styles": ["solid"], "unicode": "f048", "label": "Backward Step", "voted": false, "svg": { "solid": { "last_modified": 1684766676, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M267.5 440.6c9.5 7.9 22.8 9.7 34.1 4.4s18.4-16.6 18.4-29V96c0-12.4-7.2-23.7-18.4-29s-24.5-3.6-34.1 4.4l-192 160L64 241V96c0-17.7-14.3-32-32-32S0 78.3 0 96V416c0 17.7 14.3 32 32 32s32-14.3 32-32V271l11.5 9.6 192 160z" } }, "free": ["solid"] }, "bacon": { "aliases": { "unicodes": { "composite": ["1f953"], "secondary": ["10f7e5"] } }, "changes": ["5.7.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "bacon", "blt", "breakfast", "food", "ham", "lard", "meat", "pancetta", "pork", "rasher" ] }, "styles": ["solid"], "unicode": "f7e5", "label": "Bacon", "voted": false, "svg": { "solid": { "last_modified": 1684767421, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M439.2 1.2c11.2-3.2 23.2-.1 31.4 8.1L518 56.7l-26.5 7.9c-58 16.6-98.1 39.6-129.6 67.4c-31.2 27.5-53.2 59.1-75.1 90.9l-2.3 3.3C241.6 288.7 195 356.6 72.8 417.7L37.9 435.2 9.4 406.6c-7.3-7.3-10.6-17.6-9-27.8s8.1-18.9 17.3-23.5C136.1 296.2 180.9 231 223.3 169.3l2.3-3.4c21.8-31.8 44.9-64.9 77.7-93.9c33.4-29.5 75.8-53.6 135.9-70.8zM61.8 459l25.4-12.7c129.5-64.7 179.9-138.1 223.8-202l2.2-3.3c22.1-32.1 42.1-60.5 69.9-85.1c27.5-24.3 63.4-45.2 117.3-60.6l0 0 .2-.1 43.1-12.9 23 23c8 8 11.2 19.7 8.3 30.7s-11.3 19.6-22.2 22.7c-51.9 14.8-85.6 34.7-111.1 57.2c-26.1 23-45.1 49.9-67.3 82.1l-2.2 3.2C327.8 365.9 275.5 442 142.3 508.6c-12.3 6.2-27.2 3.7-36.9-6L61.8 459z" } }, "free": ["solid"] }, "bacteria": { "aliases": { "unicodes": { "secondary": ["10e059"] } }, "changes": [ "5.13.0", "5.13.1", "5.14.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "antibiotic", "antibody", "covid-19", "health", "organism", "sick" ] }, "styles": ["solid"], "unicode": "e059", "label": "Bacteria", "voted": false, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M304.9 .7c-9.6-2.7-19.5 2.8-22.3 12.4l-4.3 15.2c-8.3-.6-16.8 0-25.2 1.9c-7.3 1.7-14.3 3.5-21.1 5.5l-5.5-12.7c-3.9-9.1-14.5-13.4-23.6-9.5s-13.4 14.5-9.5 23.6l4.4 10.4c-16.6 6.7-31.7 14.4-45.4 22.8L147 62c-5.5-8.3-16.7-10.5-25-5s-10.5 16.7-5 25l6 9c-13.7 11-25.5 22.8-35.8 34.9l-10-8c-7.8-6.2-19.1-5-25.3 2.8s-5 19.1 2.8 25.3L65.9 155c-1.8 2.8-3.5 5.7-5.1 8.5c-6.6 11.4-11.8 22.6-16 33l-8-3.2c-9.2-3.7-19.7 .8-23.4 10s.8 19.7 10 23.4l10.4 4.2c-.2 .8-.4 1.5-.5 2.3c-2.2 9.3-3.4 17.3-4.1 23.4c-.4 3.1-.6 5.7-.8 7.8c-.1 1.1-.1 2-.2 2.8l-.1 1.1 0 .5 0 .2 0 .1c0 0 0 .1 29.1 1l-.1 0L28 269.3c-.1 3.1 0 6.1 .2 9.1l-15.2 4.3C3.5 285.4-2 295.4 .7 304.9s12.7 15.1 22.3 12.4l15.6-4.5c7.6 13.6 18.9 25 32.6 32.6L66.7 361c-2.7 9.6 2.8 19.5 12.4 22.3s19.5-2.8 22.3-12.4l4.3-15.2c1.2 .1 2.4 .2 3.6 .2c15.6 .5 30.3-3.3 43-10.2l9 9c7 7 18.4 7 25.5 0s7-18.4 0-25.5l-7.2-7.2c9.3-12.6 15.2-27.8 16.3-44.5l7.1 3c9.1 3.9 19.7-.3 23.6-9.5s-.3-19.7-9.5-23.6l-8.6-3.7c6.4-9.9 17.3-22.4 36.9-33.3l1.3 4.4c2.7 9.6 12.7 15.1 22.3 12.4s15.1-12.7 12.4-22.3l-2.3-8.1c3.8-1.1 7.7-2.1 11.9-3.1c11.6-2.7 22.1-7.7 31.1-14.4l7.2 7.2c7 7 18.4 7 25.5 0s7-18.4 0-25.5l-9-9c7.6-13.9 11.3-30.1 10.1-46.6l15.2-4.3c9.6-2.7 15.1-12.7 12.4-22.3S370.6 64 361 66.7l-15.6 4.5c-7.7-13.9-19.1-25.1-32.6-32.6l4.5-15.6c2.7-9.6-2.8-19.5-12.4-22.3zM112 272l-48-1.5 0 0c11.7 .4 27.3 .9 48 1.6zm16-80a32 32 0 1 1 0 64 32 32 0 1 1 0-64zm64-48a16 16 0 1 1 32 0 16 16 0 1 1 -32 0zM322.7 489c-2.7 9.6 2.8 19.5 12.4 22.3s19.5-2.8 22.2-12.4l4.3-15.2c8.3 .6 16.8 0 25.2-1.9c7.3-1.7 14.3-3.5 21.1-5.5l5.5 12.7c3.9 9.1 14.5 13.4 23.6 9.5s13.4-14.5 9.5-23.6l-4.4-10.4c16.6-6.7 31.7-14.4 45.4-22.8L493 450c5.5 8.3 16.7 10.5 25 5s10.5-16.7 5-25l-6-9c13.7-11 25.5-22.8 35.8-34.9l10 8c7.8 6.2 19.1 5 25.3-2.8s5-19.1-2.8-25.3L574.1 357c1.8-2.8 3.5-5.7 5.1-8.5c6.6-11.4 11.8-22.6 16-33l8 3.2c9.2 3.7 19.7-.8 23.4-10s-.8-19.7-10-23.4l-10.4-4.2c.2-.8 .4-1.5 .5-2.3c2.2-9.3 3.4-17.3 4.1-23.4c.4-3.1 .6-5.7 .8-7.8c.1-1.1 .1-2 .2-2.8l.1-1.1 0-.5 0-.2 0-.1c0 0 0-.1-29.1-1l.1 0 29.1 .9c.1-3.1 0-6.1-.2-9.1l15.2-4.3c9.6-2.7 15.1-12.7 12.4-22.3s-12.7-15.1-22.3-12.4l-15.6 4.5c-7.6-13.6-18.9-25-32.6-32.6l4.5-15.6c2.7-9.6-2.8-19.5-12.4-22.3s-19.5 2.8-22.3 12.4l-4.3 15.2c-1.2-.1-2.4-.2-3.6-.2c-15.6-.5-30.3 3.3-43 10.2l-9-9c-7-7-18.4-7-25.5 0s-7 18.4 0 25.5l7.2 7.2c-9.3 12.6-15.2 27.8-16.3 44.5l-7.1-3c-9.1-3.9-19.7 .3-23.6 9.5s.3 19.7 9.5 23.6l8.6 3.7c-6.4 9.9-17.3 22.4-36.9 33.3l-1.3-4.4c-2.7-9.6-12.7-15.1-22.3-12.4s-15.1 12.7-12.4 22.3l2.3 8.1c-3.8 1.1-7.7 2.1-11.9 3.1c-11.6 2.7-22.1 7.7-31.1 14.4l-7.2-7.2c-7-7-18.4-7-25.5 0s-7 18.4 0 25.5l9 9c-7.6 13.9-11.3 30.1-10.1 46.6l-15.2 4.3c-9.6 2.7-15.1 12.7-12.4 22.2s12.7 15.1 22.3 12.4l15.6-4.5c7.7 13.9 19.1 25.1 32.6 32.6L322.7 489zM576 241.5l0 0c-11.7-.4-27.3-.9-48-1.6l48 1.5zM448 384a32 32 0 1 1 -64 0 32 32 0 1 1 64 0z" } }, "free": ["solid"] }, "bacterium": { "aliases": { "unicodes": { "secondary": ["10e05a"] } }, "changes": [ "5.13.0", "5.13.1", "5.14.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "antibiotic", "antibody", "covid-19", "health", "organism", "sick" ] }, "styles": ["solid"], "unicode": "e05a", "label": "Bacterium", "voted": false, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M423.1 30.6c3.6-12.7-3.7-26-16.5-29.7s-26 3.7-29.7 16.5l-4.2 14.7c-9.8-.4-19.9 .5-29.9 2.8c-12.1 2.8-23.7 5.9-34.9 9.4l-5.9-13.7c-5.2-12.2-19.3-17.8-31.5-12.6s-17.8 19.3-12.6 31.5l4.9 11.3c-22 9.4-42 20.1-60.2 31.8L196 82.7c-7.4-11-22.3-14-33.3-6.7s-14 22.3-6.7 33.3l7.8 11.6c-18 15-33.7 30.8-47.3 47.1L103 157.3c-10.4-8.3-25.5-6.6-33.7 3.7s-6.6 25.5 3.7 33.7l15 12c-2.1 3.2-4.1 6.5-6 9.7c-9.4 15.7-17 31-23.2 45.3l-9.9-3.9c-12.3-4.9-26.3 1.1-31.2 13.4s1.1 26.3 13.4 31.2l11.6 4.6c-.3 1.1-.6 2.1-.9 3.1c-3.5 12.5-5.7 23.2-7.1 31.3c-.7 4.1-1.2 7.5-1.6 10.3c-.2 1.4-.3 2.6-.4 3.6l-.1 1.4-.1 .6 0 .3 0 .1c0 0 0 .1 39.2 3.7l0 0-39.2-3.6c-.5 5-.6 10-.4 14.9l-14.7 4.2C4.7 380.6-2.7 393.8 .9 406.6s16.9 20.1 29.7 16.5l13.8-3.9c10.6 20.7 27.6 37.8 48.5 48.5l-3.9 13.7c-3.6 12.7 3.7 26 16.5 29.7s26-3.7 29.7-16.5l4.2-14.7c23.8 1 46.3-5.5 65.1-17.6L215 473c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9l-10.6-10.6c9.1-14.1 15.1-30.5 17-48.3l.1-.8c.3-1.7 1-5.1 2.3-9.8l.2-.8 12.6 5.4c12.2 5.2 26.3-.4 31.5-12.6s-.4-26.3-12.6-31.5l-11.3-4.8c9.9-14.9 24.9-31.6 48.6-46l2.1 7.5c3.6 12.7 16.9 20.1 29.7 16.5s20.1-16.9 16.5-29.7L371 259.2c6.9-2.2 14.3-4.3 22.2-6.1c12.9-3 24.7-8 35.2-14.8L439 249c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9l-10.6-10.6c12.2-19 18.6-41.6 17.6-65.1l14.7-4.2c12.7-3.6 20.1-16.9 16.5-29.7s-16.9-20.1-29.7-16.5l-13.7 3.9c-10.8-21.2-28-38-48.5-48.5l3.9-13.8zM92.1 363.3l0 0L144 368l-51.9-4.7zM112 320a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zM240 184a24 24 0 1 1 0 48 24 24 0 1 1 0-48z" } }, "free": ["solid"] }, "bag-shopping": { "aliases": { "names": ["shopping-bag"], "unicodes": { "secondary": ["10f290"] } }, "changes": [ "4.5.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["buy", "checkout", "grocery", "payment", "purchase"] }, "styles": ["solid"], "unicode": "f290", "label": "Bag Shopping", "voted": false, "svg": { "solid": { "last_modified": 1684766476, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M160 112c0-35.3 28.7-64 64-64s64 28.7 64 64v48H160V112zm-48 48H48c-26.5 0-48 21.5-48 48V416c0 53 43 96 96 96H352c53 0 96-43 96-96V208c0-26.5-21.5-48-48-48H336V112C336 50.1 285.9 0 224 0S112 50.1 112 112v48zm24 48a24 24 0 1 1 0 48 24 24 0 1 1 0-48zm152 24a24 24 0 1 1 48 0 24 24 0 1 1 -48 0z" } }, "free": ["solid"] }, "bahai": { "aliases": { "names": ["haykal"], "unicodes": { "secondary": ["10f666"] } }, "changes": ["5.3.0", "5.12.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["bahai", "bahá'í", "star"] }, "styles": ["solid"], "unicode": "f666", "label": "Bahai", "voted": false, "svg": { "solid": { "last_modified": 1684767601, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M288 0c14.5 0 27.2 9.7 30.9 23.8l23.9 89.6 75.9-53.3c11.9-8.3 27.8-7.6 39 1.7s14.6 24.9 8.4 38.1l-39.3 84 92.4 8c14.4 1.2 26.2 12 28.8 26.3s-4.9 28.5-18 34.6l-84.1 39.1 65.7 65.5c10.3 10.2 12.4 26.1 5.1 38.7s-22 18.7-36 14.9L391 386.8l8.2 92.4c1.3 14.4-7.3 27.9-20.9 32.9s-28.9 .1-37.2-11.7l-53.1-76-53.1 76c-8.3 11.9-23.6 16.7-37.2 11.7s-22.2-18.5-20.9-32.9l8.2-92.4L95.4 410.9c-14 3.8-28.8-2.3-36-14.9s-5.2-28.4 5.1-38.7l65.7-65.5L46 252.7c-13.1-6.1-20.5-20.3-18-34.6s14.3-25.1 28.8-26.3l92.4-8-39.3-84c-6.1-13.1-2.7-28.8 8.4-38.1s27.1-10 39-1.7l75.9 53.3 23.9-89.6C260.8 9.7 273.5 0 288 0zm0 156.2l-4.8 18c-2.7 10.1-10.2 18.2-20 21.8s-20.8 2.1-29.3-3.9l-15.2-10.7 7.9 16.8c4.4 9.5 4 20.5-1.3 29.6s-14.5 15-25 15.9l-18.5 1.6 16.8 7.8c9.5 4.4 16.2 13.2 18 23.5s-1.5 20.8-8.9 28.2l-13.2 13.1 17.9-4.8c10.1-2.7 20.9-.3 28.9 6.4s12.2 16.9 11.3 27.3l-1.6 18.5 10.6-15.2c6-8.6 15.8-13.7 26.2-13.7s20.2 5.1 26.2 13.7l10.6 15.2-1.6-18.5c-.9-10.4 3.3-20.6 11.3-27.3s18.8-9.1 28.9-6.4l17.9 4.8-13.2-13.1c-7.4-7.4-10.7-17.9-8.9-28.2s8.5-19.1 18-23.5l16.8-7.8-18.5-1.6c-10.4-.9-19.7-6.8-25-15.9s-5.7-20.1-1.3-29.6l7.9-16.8-15.2 10.7c-8.6 6-19.5 7.5-29.3 3.9s-17.3-11.7-20-21.8l-4.8-18z" } }, "free": ["solid"] }, "baht-sign": { "changes": ["6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["currency"] }, "styles": ["solid"], "unicode": "e0ac", "label": "Baht Sign", "voted": false, "svg": { "solid": { "last_modified": 1684766474, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M144 0c-17.7 0-32 14.3-32 32V64H37.6C16.8 64 0 80.8 0 101.6V224v41.7V288 406.3c0 23 18.7 41.7 41.7 41.7H112v32c0 17.7 14.3 32 32 32s32-14.3 32-32V448h32c61.9 0 112-50.1 112-112c0-40.1-21.1-75.3-52.7-95.1C280.3 222.6 288 200.2 288 176c0-61.9-50.1-112-112-112V32c0-17.7-14.3-32-32-32zM112 128v96H64V128h48zm64 96V128c26.5 0 48 21.5 48 48s-21.5 48-48 48zm-64 64v96H64V288h48zm64 96V288h32c26.5 0 48 21.5 48 48s-21.5 48-48 48H176z" } }, "free": ["solid"] }, "ban": { "aliases": { "names": ["cancel"], "unicodes": { "composite": ["1f6ab"], "secondary": ["10f05e"] } }, "changes": [ "1.0.0", "5.0.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "abort", "ban", "block", "cancel", "delete", "entry", "forbidden", "hide", "no", "not", "prohibit", "prohibited", "remove", "stop", "trash" ] }, "styles": ["solid"], "unicode": "f05e", "label": "Ban", "voted": false, "svg": { "solid": { "last_modified": 1684767368, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M367.2 412.5L99.5 144.8C77.1 176.1 64 214.5 64 256c0 106 86 192 192 192c41.5 0 79.9-13.1 111.2-35.5zm45.3-45.3C434.9 335.9 448 297.5 448 256c0-106-86-192-192-192c-41.5 0-79.9 13.1-111.2 35.5L412.5 367.2zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256z" } }, "free": ["solid"] }, "ban-smoking": { "aliases": { "names": ["smoking-ban"], "unicodes": { "composite": ["1f6ad"], "secondary": ["10f54d"] } }, "changes": ["5.0.13", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "ban", "cancel", "forbidden", "no", "no smoking", "non-smoking", "not", "prohibited", "smoking" ] }, "styles": ["solid"], "unicode": "f54d", "label": "Ban Smoking", "voted": true, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M99.5 144.8L178.7 224l96 96 92.5 92.5C335.9 434.9 297.5 448 256 448C150 448 64 362 64 256c0-41.5 13.1-79.9 35.5-111.2zM333.3 288l-32-32H384v32H333.3zm32 32H400c8.8 0 16-7.2 16-16V240c0-8.8-7.2-16-16-16H269.3L144.8 99.5C176.1 77.1 214.5 64 256 64c106 0 192 86 192 192c0 41.5-13.1 79.9-35.5 111.2L365.3 320zM256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM272 96c-8.8 0-16 7.2-16 16c0 26.5 21.5 48 48 48h32c8.8 0 16 7.2 16 16s7.2 16 16 16s16-7.2 16-16c0-26.5-21.5-48-48-48H304c-8.8 0-16-7.2-16-16s-7.2-16-16-16zM229.5 320l-96-96H112c-8.8 0-16 7.2-16 16v64c0 8.8 7.2 16 16 16H229.5z" } }, "free": ["solid"] }, "bandage": { "aliases": { "names": ["band-aid"], "unicodes": { "composite": ["1fa79"], "secondary": ["10f462"] } }, "changes": [ "5.0.7", "5.10.2", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["adhesive bandage", "bandage", "boo boo", "first aid", "ouch"] }, "styles": ["solid"], "unicode": "f462", "label": "Bandage", "voted": false, "svg": { "solid": { "last_modified": 1684766749, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M480 416h96c35.3 0 64-28.7 64-64V160c0-35.3-28.7-64-64-64H480V416zM448 96H192V416H448V96zM64 96C28.7 96 0 124.7 0 160V352c0 35.3 28.7 64 64 64h96V96H64zM248 208a24 24 0 1 1 48 0 24 24 0 1 1 -48 0zm120-24a24 24 0 1 1 0 48 24 24 0 1 1 0-48zM248 304a24 24 0 1 1 48 0 24 24 0 1 1 -48 0zm120-24a24 24 0 1 1 0 48 24 24 0 1 1 0-48z" } }, "free": ["solid"] }, "bandcamp": { "changes": ["4.7.0", "5.0.0", "5.13.1"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f2d5", "label": "Bandcamp", "voted": false, "svg": { "brands": { "last_modified": 1660014469, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256,8C119,8,8,119,8,256S119,504,256,504,504,393,504,256,393,8,256,8Zm48.2,326.1h-181L207.9,178h181Z" } }, "free": ["brands"] }, "bangladeshi-taka-sign": { "changes": [ "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.2.1", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["bdt", "currency", "tk"] }, "styles": ["solid"], "unicode": "e2e6", "label": "Bangladeshi Taka Sign", "voted": false, "svg": { "solid": { "last_modified": 1684766476, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M36 32.2C18.4 30.1 2.4 42.5 .2 60S10.5 93.6 28 95.8l7.9 1c16 2 28 15.6 28 31.8V160H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H64V384c0 53 43 96 96 96h32c106 0 192-86 192-192V256c0-53-43-96-96-96H272c-17.7 0-32 14.3-32 32s14.3 32 32 32h16c17.7 0 32 14.3 32 32v32c0 70.7-57.3 128-128 128H160c-17.7 0-32-14.3-32-32V224h32c17.7 0 32-14.3 32-32s-14.3-32-32-32H128V128.5c0-48.4-36.1-89.3-84.1-95.3l-7.9-1z" } }, "free": ["solid"] }, "barcode": { "aliases": { "unicodes": { "secondary": ["10f02a"] } }, "changes": [ "1.0.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["info", "laser", "price", "scan", "upc"] }, "styles": ["solid"], "unicode": "f02a", "label": "Barcode", "voted": false, "svg": { "solid": { "last_modified": 1684766474, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M24 32C10.7 32 0 42.7 0 56V456c0 13.3 10.7 24 24 24H40c13.3 0 24-10.7 24-24V56c0-13.3-10.7-24-24-24H24zm88 0c-8.8 0-16 7.2-16 16V464c0 8.8 7.2 16 16 16s16-7.2 16-16V48c0-8.8-7.2-16-16-16zm72 0c-13.3 0-24 10.7-24 24V456c0 13.3 10.7 24 24 24h16c13.3 0 24-10.7 24-24V56c0-13.3-10.7-24-24-24H184zm96 0c-13.3 0-24 10.7-24 24V456c0 13.3 10.7 24 24 24h16c13.3 0 24-10.7 24-24V56c0-13.3-10.7-24-24-24H280zM448 56V456c0 13.3 10.7 24 24 24h16c13.3 0 24-10.7 24-24V56c0-13.3-10.7-24-24-24H472c-13.3 0-24 10.7-24 24zm-64-8V464c0 8.8 7.2 16 16 16s16-7.2 16-16V48c0-8.8-7.2-16-16-16s-16 7.2-16 16z" } }, "free": ["solid"] }, "bars": { "aliases": { "names": ["navicon"], "unicodes": { "secondary": ["10f0c9"] } }, "changes": [ "2.0.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "checklist", "drag", "hamburger", "list", "menu", "nav", "navigation", "ol", "reorder", "settings", "todo", "ul" ] }, "styles": ["solid"], "unicode": "f0c9", "label": "Bars", "voted": false, "svg": { "solid": { "last_modified": 1684767207, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M0 96C0 78.3 14.3 64 32 64H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32C14.3 128 0 113.7 0 96zM0 256c0-17.7 14.3-32 32-32H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32-14.3-32-32zM448 416c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H416c17.7 0 32 14.3 32 32z" } }, "free": ["solid"] }, "bars-progress": { "aliases": { "names": ["tasks-alt"], "unicodes": { "secondary": ["10f828"] } }, "changes": [ "5.7.0", "5.10.2", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "checklist", "downloading", "downloads", "loading", "poll", "progress", "project management", "settings", "to do" ] }, "styles": ["solid"], "unicode": "f828", "label": "Bars Progress", "voted": false, "svg": { "solid": { "last_modified": 1684767206, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M448 160H320V128H448v32zM48 64C21.5 64 0 85.5 0 112v64c0 26.5 21.5 48 48 48H464c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48H48zM448 352v32H192V352H448zM48 288c-26.5 0-48 21.5-48 48v64c0 26.5 21.5 48 48 48H464c26.5 0 48-21.5 48-48V336c0-26.5-21.5-48-48-48H48z" } }, "free": ["solid"] }, "bars-staggered": { "aliases": { "names": ["reorder", "stream"], "unicodes": { "secondary": ["10f550"] } }, "changes": [ "5.0.13", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["flow", "list", "timeline"] }, "styles": ["solid"], "unicode": "f550", "label": "Bars Staggered", "voted": false, "svg": { "solid": { "last_modified": 1684767206, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 96C0 78.3 14.3 64 32 64H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32C14.3 128 0 113.7 0 96zM64 256c0-17.7 14.3-32 32-32H480c17.7 0 32 14.3 32 32s-14.3 32-32 32H96c-17.7 0-32-14.3-32-32zM448 416c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H416c17.7 0 32 14.3 32 32z" } }, "free": ["solid"] }, "baseball": { "aliases": { "names": ["baseball-ball"], "unicodes": { "composite": ["1f94e", "26be"], "secondary": ["10f433"] } }, "changes": [ "5.0.5", "5.11.0", "5.11.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "ball", "baseball", "foul", "glove", "hardball", "league", "leather", "mlb", "softball", "sport", "underarm" ] }, "styles": ["solid"], "unicode": "f433", "label": "Baseball", "voted": false, "svg": { "solid": { "last_modified": 1684767070, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M62.7 223.4c-4.8 .4-9.7 .6-14.7 .6c-15.6 0-30.8-2-45.2-5.9C19.2 107.1 107.1 19.2 218.1 2.8C222 17.2 224 32.4 224 48c0 4.9-.2 9.8-.6 14.7c-.7 8.8 5.8 16.5 14.6 17.3s16.5-5.8 17.3-14.6c.5-5.7 .7-11.5 .7-17.3c0-16.5-1.9-32.6-5.6-47.9c1.8 0 3.7-.1 5.6-.1C397.4 0 512 114.6 512 256c0 1.9 0 3.7-.1 5.6c-15.4-3.6-31.4-5.6-47.9-5.6c-5.8 0-11.6 .2-17.3 .7c-8.8 .7-15.4 8.5-14.6 17.3s8.5 15.4 17.3 14.6c4.8-.4 9.7-.6 14.7-.6c15.6 0 30.8 2 45.2 5.9C492.8 404.9 404.9 492.8 293.9 509.2C290 494.8 288 479.6 288 464c0-4.9 .2-9.8 .6-14.7c.7-8.8-5.8-16.5-14.6-17.3s-16.5 5.8-17.3 14.6c-.5 5.7-.7 11.5-.7 17.3c0 16.5 1.9 32.6 5.6 47.9c-1.8 0-3.7 .1-5.6 .1C114.6 512 0 397.4 0 256c0-1.9 0-3.7 .1-5.6C15.4 254.1 31.5 256 48 256c5.8 0 11.6-.2 17.3-.7c8.8-.7 15.4-8.5 14.6-17.3s-8.5-15.4-17.3-14.6zM121.3 208c-8 3.7-11.6 13.2-7.9 21.2s13.2 11.6 21.2 7.9c45.2-20.8 81.7-57.2 102.5-102.5c3.7-8 .2-17.5-7.9-21.2s-17.5-.2-21.2 7.9c-17.6 38.3-48.5 69.2-86.7 86.7zm277.2 74.7c-3.7-8-13.2-11.6-21.2-7.9c-45.2 20.8-81.7 57.2-102.5 102.5c-3.7 8-.2 17.5 7.9 21.2s17.5 .2 21.2-7.9c17.6-38.3 48.5-69.2 86.7-86.7c8-3.7 11.6-13.2 7.9-21.2z" } }, "free": ["solid"] }, "baseball-bat-ball": { "aliases": { "unicodes": { "secondary": ["10f432"] } }, "changes": ["5.0.5", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["bat", "league", "mlb", "slugger", "softball", "sport"] }, "styles": ["solid"], "unicode": "f432", "label": "Baseball Bat Ball", "voted": false, "svg": { "solid": { "last_modified": 1684767070, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M424 0c-12.4 0-24.2 4.9-33 13.7L233.5 171.2c-10.5 10.5-19.8 22.1-27.7 34.6L132.7 321.6c-7.3 11.5-15.8 22.2-25.5 31.9L69.9 390.7l51.3 51.3 37.3-37.3c9.6-9.6 20.3-18.2 31.9-25.5l115.8-73.1c12.5-7.9 24.1-17.2 34.6-27.7L498.3 121c8.7-8.7 13.7-20.6 13.7-33s-4.9-24.2-13.7-33L457 13.7C448.2 4.9 436.4 0 424 0zm88 432a80 80 0 1 0 -160 0 80 80 0 1 0 160 0zM15 399c-9.4 9.4-9.4 24.6 0 33.9l64 64c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9L49 399c-9.4-9.4-24.6-9.4-33.9 0z" } }, "free": ["solid"] }, "basket-shopping": { "aliases": { "names": ["shopping-basket"], "unicodes": { "secondary": ["10f291"] } }, "changes": [ "4.5.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["buy", "checkout", "grocery", "payment", "purchase"] }, "styles": ["solid"], "unicode": "f291", "label": "Basket Shopping", "voted": false, "svg": { "solid": { "last_modified": 1684766475, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M253.3 35.1c6.1-11.8 1.5-26.3-10.2-32.4s-26.3-1.5-32.4 10.2L117.6 192H32c-17.7 0-32 14.3-32 32s14.3 32 32 32L83.9 463.5C91 492 116.6 512 146 512H430c29.4 0 55-20 62.1-48.5L544 256c17.7 0 32-14.3 32-32s-14.3-32-32-32H458.4L365.3 12.9C359.2 1.2 344.7-3.4 332.9 2.7s-16.3 20.6-10.2 32.4L404.3 192H171.7L253.3 35.1zM192 304v96c0 8.8-7.2 16-16 16s-16-7.2-16-16V304c0-8.8 7.2-16 16-16s16 7.2 16 16zm96-16c8.8 0 16 7.2 16 16v96c0 8.8-7.2 16-16 16s-16-7.2-16-16V304c0-8.8 7.2-16 16-16zm128 16v96c0 8.8-7.2 16-16 16s-16-7.2-16-16V304c0-8.8 7.2-16 16-16s16 7.2 16 16z" } }, "free": ["solid"] }, "basketball": { "aliases": { "names": ["basketball-ball"], "unicodes": { "composite": ["1f3c0"], "secondary": ["10f434"] } }, "changes": [ "5.0.5", "5.11.0", "5.11.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["ball", "basketball", "dribble", "dunk", "hoop", "nba"] }, "styles": ["solid"], "unicode": "f434", "label": "Basketball", "voted": false, "svg": { "solid": { "last_modified": 1684767071, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M86.6 64l85.2 85.2C194.5 121.7 208 86.4 208 48c0-14.7-2-28.9-5.7-42.4C158.6 15 119 35.5 86.6 64zM64 86.6C35.5 119 15 158.6 5.6 202.3C19.1 206 33.3 208 48 208c38.4 0 73.7-13.5 101.3-36.1L64 86.6zM256 0c-7.3 0-14.6 .3-21.8 .9C238 16 240 31.8 240 48c0 47.3-17.1 90.5-45.4 124L256 233.4 425.4 64C380.2 24.2 320.9 0 256 0zM48 240c-16.2 0-32-2-47.1-5.8C.3 241.4 0 248.7 0 256c0 64.9 24.2 124.2 64 169.4L233.4 256 172 194.6C138.5 222.9 95.3 240 48 240zm463.1 37.8c.6-7.2 .9-14.5 .9-21.8c0-64.9-24.2-124.2-64-169.4L278.6 256 340 317.4c33.4-28.3 76.7-45.4 124-45.4c16.2 0 32 2 47.1 5.8zm-4.7 31.9C492.9 306 478.7 304 464 304c-38.4 0-73.7 13.5-101.3 36.1L448 425.4c28.5-32.3 49.1-71.9 58.4-115.7zM340.1 362.7C317.5 390.3 304 425.6 304 464c0 14.7 2 28.9 5.7 42.4C353.4 497 393 476.5 425.4 448l-85.2-85.2zM317.4 340L256 278.6 86.6 448c45.1 39.8 104.4 64 169.4 64c7.3 0 14.6-.3 21.8-.9C274 496 272 480.2 272 464c0-47.3 17.1-90.5 45.4-124z" } }, "free": ["solid"] }, "bath": { "aliases": { "names": ["bathtub"], "unicodes": { "composite": ["1f6c1"], "secondary": ["10f2cd"] } }, "changes": [ "4.7.0", "5.0.0", "5.12.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["bath", "bathtub", "clean", "shower", "tub", "wash"] }, "styles": ["solid"], "unicode": "f2cd", "label": "Bath", "voted": false, "svg": { "solid": { "last_modified": 1684767443, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M96 77.3c0-7.3 5.9-13.3 13.3-13.3c3.5 0 6.9 1.4 9.4 3.9l14.9 14.9C130 91.8 128 101.7 128 112c0 19.9 7.2 38 19.2 52c-5.3 9.2-4 21.1 3.8 29c9.4 9.4 24.6 9.4 33.9 0L289 89c9.4-9.4 9.4-24.6 0-33.9c-7.9-7.9-19.8-9.1-29-3.8C246 39.2 227.9 32 208 32c-10.3 0-20.2 2-29.2 5.5L163.9 22.6C149.4 8.1 129.7 0 109.3 0C66.6 0 32 34.6 32 77.3V256c-17.7 0-32 14.3-32 32s14.3 32 32 32H480c17.7 0 32-14.3 32-32s-14.3-32-32-32H96V77.3zM32 352v16c0 28.4 12.4 54 32 71.6V480c0 17.7 14.3 32 32 32s32-14.3 32-32V464H384v16c0 17.7 14.3 32 32 32s32-14.3 32-32V439.6c19.6-17.6 32-43.1 32-71.6V352H32z" } }, "free": ["solid"] }, "battery-empty": { "aliases": { "names": ["battery-0"], "unicodes": { "secondary": ["10f244"] } }, "changes": [ "4.4.0", "5.0.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["charge", "dead", "power", "status"] }, "styles": ["solid"], "unicode": "f244", "label": "Battery Empty", "voted": false, "svg": { "solid": { "last_modified": 1684767367, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M80 160c-8.8 0-16 7.2-16 16V336c0 8.8 7.2 16 16 16H464c8.8 0 16-7.2 16-16V176c0-8.8-7.2-16-16-16H80zM0 176c0-44.2 35.8-80 80-80H464c44.2 0 80 35.8 80 80v16c17.7 0 32 14.3 32 32v64c0 17.7-14.3 32-32 32v16c0 44.2-35.8 80-80 80H80c-44.2 0-80-35.8-80-80V176z" } }, "free": ["solid"] }, "battery-full": { "aliases": { "names": ["battery", "battery-5"], "unicodes": { "composite": ["1f50b"], "secondary": ["10f240"] } }, "changes": [ "4.4.0", "5.0.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["batter", "battery", "charge", "power", "status"] }, "styles": ["solid"], "unicode": "f240", "label": "Battery Full", "voted": false, "svg": { "solid": { "last_modified": 1684767366, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M464 160c8.8 0 16 7.2 16 16V336c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16H464zM80 96C35.8 96 0 131.8 0 176V336c0 44.2 35.8 80 80 80H464c44.2 0 80-35.8 80-80V320c17.7 0 32-14.3 32-32V224c0-17.7-14.3-32-32-32V176c0-44.2-35.8-80-80-80H80zm368 96H96V320H448V192z" } }, "free": ["solid"] }, "battery-half": { "aliases": { "names": ["battery-3"], "unicodes": { "secondary": ["10f242"] } }, "changes": [ "4.4.0", "5.0.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["charge", "power", "status"] }, "styles": ["solid"], "unicode": "f242", "label": "Battery Half", "voted": false, "svg": { "solid": { "last_modified": 1684767367, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M464 160c8.8 0 16 7.2 16 16V336c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16H464zM80 96C35.8 96 0 131.8 0 176V336c0 44.2 35.8 80 80 80H464c44.2 0 80-35.8 80-80V320c17.7 0 32-14.3 32-32V224c0-17.7-14.3-32-32-32V176c0-44.2-35.8-80-80-80H80zm208 96H96V320H288V192z" } }, "free": ["solid"] }, "battery-quarter": { "aliases": { "names": ["battery-2"], "unicodes": { "secondary": ["10f243"] } }, "changes": [ "4.4.0", "5.0.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["charge", "low", "power", "status"] }, "styles": ["solid"], "unicode": "f243", "label": "Battery Quarter", "voted": false, "svg": { "solid": { "last_modified": 1684767366, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M464 160c8.8 0 16 7.2 16 16V336c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16H464zM80 96C35.8 96 0 131.8 0 176V336c0 44.2 35.8 80 80 80H464c44.2 0 80-35.8 80-80V320c17.7 0 32-14.3 32-32V224c0-17.7-14.3-32-32-32V176c0-44.2-35.8-80-80-80H80zm112 96H96V320h96V192z" } }, "free": ["solid"] }, "battery-three-quarters": { "aliases": { "names": ["battery-4"], "unicodes": { "secondary": ["10f241"] } }, "changes": [ "4.4.0", "5.0.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["charge", "power", "status"] }, "styles": ["solid"], "unicode": "f241", "label": "Battery Three Quarters", "voted": false, "svg": { "solid": { "last_modified": 1684767366, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M464 160c8.8 0 16 7.2 16 16V336c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16H464zM80 96C35.8 96 0 131.8 0 176V336c0 44.2 35.8 80 80 80H464c44.2 0 80-35.8 80-80V320c17.7 0 32-14.3 32-32V224c0-17.7-14.3-32-32-32V176c0-44.2-35.8-80-80-80H80zm272 96H96V320H352V192z" } }, "free": ["solid"] }, "battle-net": { "changes": ["5.8.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f835", "label": "Battle.net", "voted": false, "svg": { "brands": { "last_modified": 1660014480, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M448.61 225.62c26.87.18 35.57-7.43 38.92-12.37 12.47-16.32-7.06-47.6-52.85-71.33 17.76-33.58 30.11-63.68 36.34-85.3 3.38-11.83 1.09-19 .45-20.25-1.72 10.52-15.85 48.46-48.2 100.05-25-11.22-56.52-20.1-93.77-23.8-8.94-16.94-34.88-63.86-60.48-88.93C252.18 7.14 238.7 1.07 228.18.22h-.05c-13.83-1.55-22.67 5.85-27.4 11-17.2 18.53-24.33 48.87-25 84.07-7.24-12.35-17.17-24.63-28.5-25.93h-.18c-20.66-3.48-38.39 29.22-36 81.29-38.36 1.38-71 5.75-93 11.23-9.9 2.45-16.22 7.27-17.76 9.72 1-.38 22.4-9.22 111.56-9.22 5.22 53 29.75 101.82 26 93.19-9.73 15.4-38.24 62.36-47.31 97.7-5.87 22.88-4.37 37.61.15 47.14 5.57 12.75 16.41 16.72 23.2 18.26 25 5.71 55.38-3.63 86.7-21.14-7.53 12.84-13.9 28.51-9.06 39.34 7.31 19.65 44.49 18.66 88.44-9.45 20.18 32.18 40.07 57.94 55.7 74.12a39.79 39.79 0 0 0 8.75 7.09c5.14 3.21 8.58 3.37 8.58 3.37-8.24-6.75-34-38-62.54-91.78 22.22-16 45.65-38.87 67.47-69.27 122.82 4.6 143.29-24.76 148-31.64 14.67-19.88 3.43-57.44-57.32-93.69zm-77.85 106.22c23.81-37.71 30.34-67.77 29.45-92.33 27.86 17.57 47.18 37.58 49.06 58.83 1.14 12.93-8.1 29.12-78.51 33.5zM216.9 387.69c9.76-6.23 19.53-13.12 29.2-20.49 6.68 13.33 13.6 26.1 20.6 38.19-40.6 21.86-68.84 12.76-49.8-17.7zm215-171.35c-10.29-5.34-21.16-10.34-32.38-15.05a722.459 722.459 0 0 0 22.74-36.9c39.06 24.1 45.9 53.18 9.64 51.95zM279.18 398c-5.51-11.35-11-23.5-16.5-36.44 43.25 1.27 62.42-18.73 63.28-20.41 0 .07-25 15.64-62.53 12.25a718.78 718.78 0 0 0 85.06-84q13.06-15.31 24.93-31.11c-.36-.29-1.54-3-16.51-12-51.7 60.27-102.34 98-132.75 115.92-20.59-11.18-40.84-31.78-55.71-61.49-20-39.92-30-82.39-31.57-116.07 12.3.91 25.27 2.17 38.85 3.88-22.29 36.8-14.39 63-13.47 64.23 0-.07-.95-29.17 20.14-59.57a695.23 695.23 0 0 0 44.67 152.84c.93-.38 1.84.88 18.67-8.25-26.33-74.47-33.76-138.17-34-173.43 20-12.42 48.18-19.8 81.63-17.81 44.57 2.67 86.36 15.25 116.32 30.71q-10.69 15.66-23.33 32.47C365.63 152 339.1 145.84 337.5 146c.11 0 25.9 14.07 41.52 47.22a717.63 717.63 0 0 0-115.34-31.71 646.608 646.608 0 0 0-39.39-6.05c-.07.45-1.81 1.85-2.16 20.33C300 190.28 358.78 215.68 389.36 233c.74 23.55-6.95 51.61-25.41 79.57-24.6 37.31-56.39 67.23-84.77 85.43zm27.4-287c-44.56-1.66-73.58 7.43-94.69 20.67 2-52.3 21.31-76.38 38.21-75.28C267 52.15 305 108.55 306.58 111zm-130.65 3.1c.48 12.11 1.59 24.62 3.21 37.28-14.55-.85-28.74-1.25-42.4-1.26-.08 3.24-.12-51 24.67-49.59h.09c5.76 1.09 10.63 6.88 14.43 13.57zm-28.06 162c20.76 39.7 43.3 60.57 65.25 72.31-46.79 24.76-77.53 20-84.92 4.51-.2-.21-11.13-15.3 19.67-76.81zm210.06 74.8" } }, "free": ["brands"] }, "bed": { "aliases": { "unicodes": { "composite": ["1f6cc"], "secondary": ["10f236"] } }, "changes": [ "4.3.0", "5.0.0", "5.1.0", "6.0.0-beta1", "6.1.2", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "hospital", "hotel", "lodging", "mattress", "patient", "person in bed", "rest", "sleep", "travel" ] }, "styles": ["solid"], "unicode": "f236", "label": "Bed", "voted": false, "svg": { "solid": { "last_modified": 1684767442, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M32 32c17.7 0 32 14.3 32 32V320H288V160c0-17.7 14.3-32 32-32H544c53 0 96 43 96 96V448c0 17.7-14.3 32-32 32s-32-14.3-32-32V416H352 320 64v32c0 17.7-14.3 32-32 32s-32-14.3-32-32V64C0 46.3 14.3 32 32 32zm144 96a80 80 0 1 1 0 160 80 80 0 1 1 0-160z" } }, "free": ["solid"] }, "bed-pulse": { "aliases": { "names": ["procedures"], "unicodes": { "secondary": ["10f487"] } }, "changes": ["5.0.7", "6.0.0-beta1", "6.1.2", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "EKG", "bed", "electrocardiogram", "health", "hospital", "life", "patient", "vital" ] }, "styles": ["solid"], "unicode": "f487", "label": "Bed Pulse", "voted": false, "svg": { "solid": { "last_modified": 1684767443, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M483.2 9.6L524 64h92c13.3 0 24 10.7 24 24s-10.7 24-24 24H512c-7.6 0-14.7-3.6-19.2-9.6L468.7 70.3l-47 99.9c-3.7 7.8-11.3 13.1-19.9 13.7s-16.9-3.4-21.7-10.6L339.2 112H216c-13.3 0-24-10.7-24-24s10.7-24 24-24H352c8 0 15.5 4 20 10.7l24.4 36.6 45.9-97.5C445.9 6.2 453.2 1 461.6 .1s16.6 2.7 21.6 9.5zM320 160h12.7l20.7 31.1c11.2 16.8 30.6 26.3 50.7 24.8s37.9-13.7 46.5-32L461.9 160H544c53 0 96 43 96 96V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V448H352 320 64v32c0 17.7-14.3 32-32 32s-32-14.3-32-32V96C0 78.3 14.3 64 32 64s32 14.3 32 32V352H288V192c0-17.7 14.3-32 32-32zm-144 0a80 80 0 1 1 0 160 80 80 0 1 1 0-160z" } }, "free": ["solid"] }, "beer-mug-empty": { "aliases": { "names": ["beer"], "unicodes": { "secondary": ["10f0fc"] } }, "changes": ["3.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "alcohol", "ale", "bar", "beverage", "brew", "brewery", "drink", "foam", "lager", "liquor", "mug", "stein" ] }, "styles": ["solid"], "unicode": "f0fc", "label": "Beer Mug Empty", "voted": false, "svg": { "solid": { "last_modified": 1684767421, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M32 64c0-17.7 14.3-32 32-32H352c17.7 0 32 14.3 32 32V96h51.2c42.4 0 76.8 34.4 76.8 76.8V274.9c0 30.4-17.9 57.9-45.6 70.2L384 381.7V416c0 35.3-28.7 64-64 64H96c-35.3 0-64-28.7-64-64V64zM384 311.6l56.4-25.1c4.6-2.1 7.6-6.6 7.6-11.7V172.8c0-7.1-5.7-12.8-12.8-12.8H384V311.6zM160 144c0-8.8-7.2-16-16-16s-16 7.2-16 16V368c0 8.8 7.2 16 16 16s16-7.2 16-16V144zm64 0c0-8.8-7.2-16-16-16s-16 7.2-16 16V368c0 8.8 7.2 16 16 16s16-7.2 16-16V144zm64 0c0-8.8-7.2-16-16-16s-16 7.2-16 16V368c0 8.8 7.2 16 16 16s16-7.2 16-16V144z" } }, "free": ["solid"] }, "behance": { "changes": ["4.1.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f1b4", "label": "Behance", "voted": false, "svg": { "brands": { "last_modified": 1660014475, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M232 237.2c31.8-15.2 48.4-38.2 48.4-74 0-70.6-52.6-87.8-113.3-87.8H0v354.4h171.8c64.4 0 124.9-30.9 124.9-102.9 0-44.5-21.1-77.4-64.7-89.7zM77.9 135.9H151c28.1 0 53.4 7.9 53.4 40.5 0 30.1-19.7 42.2-47.5 42.2h-79v-82.7zm83.3 233.7H77.9V272h84.9c34.3 0 56 14.3 56 50.6 0 35.8-25.9 47-57.6 47zm358.5-240.7H376V94h143.7v34.9zM576 305.2c0-75.9-44.4-139.2-124.9-139.2-78.2 0-131.3 58.8-131.3 135.8 0 79.9 50.3 134.7 131.3 134.7 61.3 0 101-27.6 120.1-86.3H509c-6.7 21.9-34.3 33.5-55.7 33.5-41.3 0-63-24.2-63-65.3h185.1c.3-4.2.6-8.7.6-13.2zM390.4 274c2.3-33.7 24.7-54.8 58.5-54.8 35.4 0 53.2 20.8 56.2 54.8H390.4z" } }, "free": ["brands"] }, "bell": { "aliases": { "unicodes": { "composite": ["1f514", "f0a2"], "secondary": ["10f0f3"] } }, "changes": [ "2.0.0", "5.0.0", "5.2.0", "5.11.0", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "alarm", "alert", "bel", "bell", "chime", "notification", "reminder" ] }, "styles": ["solid", "regular"], "unicode": "f0f3", "label": "Bell", "voted": false, "svg": { "solid": { "last_modified": 1684767327, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M224 0c-17.7 0-32 14.3-32 32V51.2C119 66 64 130.6 64 208v18.8c0 47-17.3 92.4-48.5 127.6l-7.4 8.3c-8.4 9.4-10.4 22.9-5.3 34.4S19.4 416 32 416H416c12.6 0 24-7.4 29.2-18.9s3.1-25-5.3-34.4l-7.4-8.3C401.3 319.2 384 273.9 384 226.8V208c0-77.4-55-142-128-156.8V32c0-17.7-14.3-32-32-32zm45.3 493.3c12-12 18.7-28.3 18.7-45.3H224 160c0 17 6.7 33.3 18.7 45.3s28.3 18.7 45.3 18.7s33.3-6.7 45.3-18.7z" }, "regular": { "last_modified": 1684767327, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M224 0c-17.7 0-32 14.3-32 32V49.9C119.5 61.4 64 124.2 64 200v33.4c0 45.4-15.5 89.5-43.8 124.9L5.3 377c-5.8 7.2-6.9 17.1-2.9 25.4S14.8 416 24 416H424c9.2 0 17.6-5.3 21.6-13.6s2.9-18.2-2.9-25.4l-14.9-18.6C399.5 322.9 384 278.8 384 233.4V200c0-75.8-55.5-138.6-128-150.1V32c0-17.7-14.3-32-32-32zm0 96h8c57.4 0 104 46.6 104 104v33.4c0 47.9 13.9 94.6 39.7 134.6H72.3C98.1 328 112 281.3 112 233.4V200c0-57.4 46.6-104 104-104h8zm64 352H224 160c0 17 6.7 33.3 18.7 45.3s28.3 18.7 45.3 18.7s33.3-6.7 45.3-18.7s18.7-28.3 18.7-45.3z" } }, "free": ["regular", "solid"] }, "bell-concierge": { "aliases": { "names": ["concierge-bell"], "unicodes": { "composite": ["1f6ce"], "secondary": ["10f562"] } }, "changes": ["5.1.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "attention", "bell", "bellhop", "bellhop bell", "hotel", "receptionist", "service", "support" ] }, "styles": ["solid"], "unicode": "f562", "label": "Bell Concierge", "voted": false, "svg": { "solid": { "last_modified": 1684767444, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M216 64c-13.3 0-24 10.7-24 24s10.7 24 24 24h16v33.3C119.6 157.2 32 252.4 32 368H480c0-115.6-87.6-210.8-200-222.7V112h16c13.3 0 24-10.7 24-24s-10.7-24-24-24H256 216zM24 400c-13.3 0-24 10.7-24 24s10.7 24 24 24H488c13.3 0 24-10.7 24-24s-10.7-24-24-24H24z" } }, "free": ["solid"] }, "bell-slash": { "aliases": { "unicodes": { "composite": ["1f515", "f1f7"], "secondary": ["10f1f6"] } }, "changes": [ "4.2.0", "5.0.0", "5.2.0", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "alert", "bell", "bell with slash", "cancel", "disabled", "forbidden", "mute", "notification", "off", "quiet", "reminder", "silent" ] }, "styles": ["solid", "regular"], "unicode": "f1f6", "label": "Bell Slash", "voted": false, "svg": { "solid": { "last_modified": 1684767327, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7l-87.5-68.6c.5-1.7 .7-3.5 .7-5.4c0-27.6-11-54.1-30.5-73.7L512 320c-20.5-20.5-32-48.3-32-77.3V208c0-77.4-55-142-128-156.8V32c0-17.7-14.3-32-32-32s-32 14.3-32 32V51.2c-42.6 8.6-79 34.2-102 69.3L38.8 5.1zM160 242.7c0 29-11.5 56.8-32 77.3l-1.5 1.5C107 341 96 367.5 96 395.2c0 11.5 9.3 20.8 20.8 20.8H406.2L160 222.1v20.7zM384 448H320 256c0 17 6.7 33.3 18.7 45.3s28.3 18.7 45.3 18.7s33.3-6.7 45.3-18.7s18.7-28.3 18.7-45.3z" }, "regular": { "last_modified": 1684767327, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7L542.6 400c2.7-7.8 1.3-16.5-3.9-23l-14.9-18.6C495.5 322.9 480 278.8 480 233.4V200c0-75.8-55.5-138.6-128-150.1V32c0-17.7-14.3-32-32-32s-32 14.3-32 32V49.9c-43.9 7-81.5 32.7-104.4 68.7L38.8 5.1zM221.7 148.4C239.6 117.1 273.3 96 312 96h8 8c57.4 0 104 46.6 104 104v33.4c0 32.7 6.4 64.8 18.7 94.5L221.7 148.4zM406.2 416l-60.9-48H168.3c21.2-32.8 34.4-70.3 38.4-109.1L160 222.1v11.4c0 45.4-15.5 89.5-43.8 124.9L101.3 377c-5.8 7.2-6.9 17.1-2.9 25.4s12.4 13.6 21.6 13.6H406.2zM384 448H320 256c0 17 6.7 33.3 18.7 45.3s28.3 18.7 45.3 18.7s33.3-6.7 45.3-18.7s18.7-28.3 18.7-45.3z" } }, "free": ["regular", "solid"] }, "bezier-curve": { "aliases": { "unicodes": { "secondary": ["10f55b"] } }, "changes": ["5.1.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["curves", "illustrator", "lines", "path", "vector"] }, "styles": ["solid"], "unicode": "f55b", "label": "Bezier Curve", "voted": false, "svg": { "solid": { "last_modified": 1684767366, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M296 136V88h48v48H296zM288 32c-26.5 0-48 21.5-48 48v4H121.6C111.2 62.7 89.3 48 64 48C28.7 48 0 76.7 0 112s28.7 64 64 64c25.3 0 47.2-14.7 57.6-36h66.9c-58.9 39.6-98.9 105-104 180H80c-26.5 0-48 21.5-48 48v64c0 26.5 21.5 48 48 48h64c26.5 0 48-21.5 48-48V368c0-26.5-21.5-48-48-48h-3.3c5.9-67 48.5-123.4 107.5-149.1c8.6 12.7 23.2 21.1 39.8 21.1h64c16.6 0 31.1-8.4 39.8-21.1c59 25.7 101.6 82.1 107.5 149.1H496c-26.5 0-48 21.5-48 48v64c0 26.5 21.5 48 48 48h64c26.5 0 48-21.5 48-48V368c0-26.5-21.5-48-48-48h-4.5c-5-75-45.1-140.4-104-180h66.9c10.4 21.3 32.3 36 57.6 36c35.3 0 64-28.7 64-64s-28.7-64-64-64c-25.3 0-47.2 14.7-57.6 36H400V80c0-26.5-21.5-48-48-48H288zM88 376h48v48H88V376zm416 48V376h48v48H504z" } }, "free": ["solid"] }, "bicycle": { "aliases": { "unicodes": { "composite": ["1f6b2"], "secondary": ["10f206"] } }, "changes": [ "4.2.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "bicycle", "bike", "gears", "pedal", "transportation", "vehicle" ] }, "styles": ["solid"], "unicode": "f206", "label": "Bicycle", "voted": false, "svg": { "solid": { "last_modified": 1684767650, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M312 32c-13.3 0-24 10.7-24 24s10.7 24 24 24h25.7l34.6 64H222.9l-27.4-38C191 99.7 183.7 96 176 96H120c-13.3 0-24 10.7-24 24s10.7 24 24 24h43.7l22.1 30.7-26.6 53.1c-10-2.5-20.5-3.8-31.2-3.8C57.3 224 0 281.3 0 352s57.3 128 128 128c65.3 0 119.1-48.9 127-112h49c8.5 0 16.3-4.5 20.7-11.8l84.8-143.5 21.7 40.1C402.4 276.3 384 312 384 352c0 70.7 57.3 128 128 128s128-57.3 128-128s-57.3-128-128-128c-13.5 0-26.5 2.1-38.7 6L375.4 48.8C369.8 38.4 359 32 347.2 32H312zM458.6 303.7l32.3 59.7c6.3 11.7 20.9 16 32.5 9.7s16-20.9 9.7-32.5l-32.3-59.7c3.6-.6 7.4-.9 11.2-.9c39.8 0 72 32.2 72 72s-32.2 72-72 72s-72-32.2-72-72c0-18.6 7-35.5 18.6-48.3zM133.2 368h65c-7.3 32.1-36 56-70.2 56c-39.8 0-72-32.2-72-72s32.2-72 72-72c1.7 0 3.4 .1 5.1 .2l-24.2 48.5c-9 18.1 4.1 39.4 24.3 39.4zm33.7-48l50.7-101.3 72.9 101.2-.1 .1H166.8zm90.6-128H365.9L317 274.8 257.4 192z" } }, "free": ["solid"] }, "bilibili": { "changes": ["6.0.0-beta2"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e3d9", "label": "Bilibili", "voted": true, "svg": { "brands": { "last_modified": 1660014468, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M488.6 104.1C505.3 122.2 513 143.8 511.9 169.8V372.2C511.5 398.6 502.7 420.3 485.4 437.3C468.2 454.3 446.3 463.2 419.9 464H92.02C65.57 463.2 43.81 454.2 26.74 436.8C9.682 419.4 .7667 396.5 0 368.2V169.8C.7667 143.8 9.682 122.2 26.74 104.1C43.81 87.75 65.57 78.77 92.02 78H121.4L96.05 52.19C90.3 46.46 87.42 39.19 87.42 30.4C87.42 21.6 90.3 14.34 96.05 8.603C101.8 2.868 109.1 0 117.9 0C126.7 0 134 2.868 139.8 8.603L213.1 78H301.1L375.6 8.603C381.7 2.868 389.2 0 398 0C406.8 0 414.1 2.868 419.9 8.603C425.6 14.34 428.5 21.6 428.5 30.4C428.5 39.19 425.6 46.46 419.9 52.19L394.6 78L423.9 78C450.3 78.77 471.9 87.75 488.6 104.1H488.6zM449.8 173.8C449.4 164.2 446.1 156.4 439.1 150.3C433.9 144.2 425.1 140.9 416.4 140.5H96.05C86.46 140.9 78.6 144.2 72.47 150.3C66.33 156.4 63.07 164.2 62.69 173.8V368.2C62.69 377.4 65.95 385.2 72.47 391.7C78.99 398.2 86.85 401.5 96.05 401.5H416.4C425.6 401.5 433.4 398.2 439.7 391.7C446 385.2 449.4 377.4 449.8 368.2L449.8 173.8zM185.5 216.5C191.8 222.8 195.2 230.6 195.6 239.7V273C195.2 282.2 191.9 289.9 185.8 296.2C179.6 302.5 171.8 305.7 162.2 305.7C152.6 305.7 144.7 302.5 138.6 296.2C132.5 289.9 129.2 282.2 128.8 273V239.7C129.2 230.6 132.6 222.8 138.9 216.5C145.2 210.2 152.1 206.9 162.2 206.5C171.4 206.9 179.2 210.2 185.5 216.5H185.5zM377 216.5C383.3 222.8 386.7 230.6 387.1 239.7V273C386.7 282.2 383.4 289.9 377.3 296.2C371.2 302.5 363.3 305.7 353.7 305.7C344.1 305.7 336.3 302.5 330.1 296.2C323.1 289.9 320.7 282.2 320.4 273V239.7C320.7 230.6 324.1 222.8 330.4 216.5C336.7 210.2 344.5 206.9 353.7 206.5C362.9 206.9 370.7 210.2 377 216.5H377z" } }, "free": ["brands"] }, "bimobject": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f378", "label": "BIMobject", "voted": false, "svg": { "brands": { "last_modified": 1660014470, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M416 32H32C14.4 32 0 46.4 0 64v384c0 17.6 14.4 32 32 32h384c17.6 0 32-14.4 32-32V64c0-17.6-14.4-32-32-32zm-64 257.4c0 49.4-11.4 82.6-103.8 82.6h-16.9c-44.1 0-62.4-14.9-70.4-38.8h-.9V368H96V136h64v74.7h1.1c4.6-30.5 39.7-38.8 69.7-38.8h17.3c92.4 0 103.8 33.1 103.8 82.5v35zm-64-28.9v22.9c0 21.7-3.4 33.8-38.4 33.8h-45.3c-28.9 0-44.1-6.5-44.1-35.7v-19c0-29.3 15.2-35.7 44.1-35.7h45.3c35-.2 38.4 12 38.4 33.7z" } }, "free": ["brands"] }, "binoculars": { "aliases": { "unicodes": { "secondary": ["10f1e5"] } }, "changes": [ "4.2.0", "5.0.0", "5.2.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["glasses", "magnify", "scenic", "spyglass", "view"] }, "styles": ["solid"], "unicode": "f1e5", "label": "Binoculars", "voted": false, "svg": { "solid": { "last_modified": 1684767662, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M128 32h32c17.7 0 32 14.3 32 32V96H96V64c0-17.7 14.3-32 32-32zm64 96V448c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32V388.9c0-34.6 9.4-68.6 27.2-98.3C40.9 267.8 49.7 242.4 53 216L60.5 156c2-16 15.6-28 31.8-28H192zm227.8 0c16.1 0 29.8 12 31.8 28L459 216c3.3 26.4 12.1 51.8 25.8 74.6c17.8 29.7 27.2 63.7 27.2 98.3V448c0 17.7-14.3 32-32 32H352c-17.7 0-32-14.3-32-32V128h99.8zM320 64c0-17.7 14.3-32 32-32h32c17.7 0 32 14.3 32 32V96H320V64zm-32 64V288H224V128h64z" } }, "free": ["solid"] }, "biohazard": { "aliases": { "unicodes": { "composite": ["2623"], "secondary": ["10f780"] } }, "changes": ["5.6.0", "5.7.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "biohazard", "covid-19", "danger", "dangerous", "epidemic", "hazmat", "medical", "pandemic", "radioactive", "sign", "toxic", "waste", "zombie" ] }, "styles": ["solid"], "unicode": "f780", "label": "Biohazard", "voted": true, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M173.2 0c-1.8 0-3.5 .7-4.8 2C138.5 32.3 120 74 120 120c0 26.2 6 50.9 16.6 73c-22 2.4-43.8 9.1-64.2 20.5C37.9 232.8 13.3 262.4 .4 296c-.7 1.7-.5 3.7 .5 5.2c2.2 3.7 7.4 4.3 10.6 1.3C64.2 254.3 158 245.1 205 324s-8.1 153.1-77.6 173.2c-4.2 1.2-6.3 5.9-4.1 9.6c1 1.6 2.6 2.7 4.5 3c36.5 5.9 75.2 .1 109.7-19.2c20.4-11.4 37.4-26.5 50.5-43.8c13.1 17.3 30.1 32.4 50.5 43.8c34.5 19.3 73.3 25.2 109.7 19.2c1.9-.3 3.5-1.4 4.5-3c2.2-3.7 .1-8.4-4.1-9.6C379.1 477.1 324 403 371 324s140.7-69.8 193.5-21.4c3.2 2.9 8.4 2.3 10.6-1.3c1-1.6 1.1-3.5 .5-5.2c-12.9-33.6-37.5-63.2-72.1-82.5c-20.4-11.4-42.2-18.1-64.2-20.5C450 170.9 456 146.2 456 120c0-46-18.5-87.7-48.4-118c-1.3-1.3-3-2-4.8-2c-5 0-8.4 5.2-6.7 9.9C421.7 80.5 385.6 176 288 176S154.3 80.5 179.9 9.9c1.7-4.7-1.6-9.9-6.7-9.9zM240 272a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zM181.7 417.6c6.3-11.8 9.8-25.1 8.6-39.8c-19.5-18-34-41.4-41.2-67.8c-12.5-8.1-26.2-11.8-40-12.4c-9-.4-18.1 .6-27.1 2.7c7.8 57.1 38.7 106.8 82.9 139.4c6.8-6.7 12.6-14.1 16.8-22.1zM288 64c-28.8 0-56.3 5.9-81.2 16.5c2 8.3 5 16.2 9 23.5c6.8 12.4 16.7 23.1 30.1 30.3c13.3-4.1 27.5-6.3 42.2-6.3s28.8 2.2 42.2 6.3c13.4-7.2 23.3-17.9 30.1-30.3c4-7.3 7-15.2 9-23.5C344.3 69.9 316.8 64 288 64zM426.9 310c-7.2 26.4-21.7 49.7-41.2 67.8c-1.2 14.7 2.2 28.1 8.6 39.8c4.3 8 10 15.4 16.8 22.1c44.3-32.6 75.2-82.3 82.9-139.4c-9-2.2-18.1-3.1-27.1-2.7c-13.8 .6-27.5 4.4-40 12.4z" } }, "free": ["solid"] }, "bitbucket": { "aliases": { "unicodes": { "composite": ["f172"] } }, "changes": ["3.2.0", "5.0.0", "5.6.0", "5.8.0"], "ligatures": [], "search": { "terms": ["atlassian", "bitbucket-square", "git"] }, "styles": ["brands"], "unicode": "f171", "label": "Bitbucket", "voted": false, "svg": { "brands": { "last_modified": 1660014465, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M22.2 32A16 16 0 0 0 6 47.8a26.35 26.35 0 0 0 .2 2.8l67.9 412.1a21.77 21.77 0 0 0 21.3 18.2h325.7a16 16 0 0 0 16-13.4L505 50.7a16 16 0 0 0-13.2-18.3 24.58 24.58 0 0 0-2.8-.2L22.2 32zm285.9 297.8h-104l-28.1-147h157.3l-25.2 147z" } }, "free": ["brands"] }, "bitcoin": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f379", "label": "Bitcoin", "voted": false, "svg": { "brands": { "last_modified": 1660014472, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zm-141.651-35.33c4.937-32.999-20.191-50.739-54.55-62.573l11.146-44.702-27.213-6.781-10.851 43.524c-7.154-1.783-14.502-3.464-21.803-5.13l10.929-43.81-27.198-6.781-11.153 44.686c-5.922-1.349-11.735-2.682-17.377-4.084l.031-.14-37.53-9.37-7.239 29.062s20.191 4.627 19.765 4.913c11.022 2.751 13.014 10.044 12.68 15.825l-12.696 50.925c.76.194 1.744.473 2.829.907-.907-.225-1.876-.473-2.876-.713l-17.796 71.338c-1.349 3.348-4.767 8.37-12.471 6.464.271.395-19.78-4.937-19.78-4.937l-13.51 31.147 35.414 8.827c6.588 1.651 13.045 3.379 19.4 5.006l-11.262 45.213 27.182 6.781 11.153-44.733a1038.209 1038.209 0 0 0 21.687 5.627l-11.115 44.523 27.213 6.781 11.262-45.128c46.404 8.781 81.299 5.239 95.986-36.727 11.836-33.79-.589-53.281-25.004-65.991 17.78-4.098 31.174-15.792 34.747-39.949zm-62.177 87.179c-8.41 33.79-65.308 15.523-83.755 10.943l14.944-59.899c18.446 4.603 77.6 13.717 68.811 48.956zm8.417-87.667c-7.673 30.736-55.031 15.12-70.393 11.292l13.548-54.327c15.363 3.828 64.836 10.973 56.845 43.035z" } }, "free": ["brands"] }, "bitcoin-sign": { "changes": ["6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Bitcoin Sign", "currency"] }, "styles": ["solid"], "unicode": "e0b4", "label": "Bitcoin Sign", "voted": false, "svg": { "solid": { "last_modified": 1684766476, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M48 32C48 14.3 62.3 0 80 0s32 14.3 32 32V64h32V32c0-17.7 14.3-32 32-32s32 14.3 32 32V64c0 1.5-.1 3.1-.3 4.5C254.1 82.2 288 125.1 288 176c0 24.2-7.7 46.6-20.7 64.9c31.7 19.8 52.7 55 52.7 95.1c0 61.9-50.1 112-112 112v32c0 17.7-14.3 32-32 32s-32-14.3-32-32V448H112v32c0 17.7-14.3 32-32 32s-32-14.3-32-32V448H41.7C18.7 448 0 429.3 0 406.3V288 265.7 224 101.6C0 80.8 16.8 64 37.6 64H48V32zM64 224H176c26.5 0 48-21.5 48-48s-21.5-48-48-48H64v96zm112 64H64v96H208c26.5 0 48-21.5 48-48s-21.5-48-48-48H176z" } }, "free": ["solid"] }, "bity": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f37a", "label": "Bity", "voted": false, "svg": { "brands": { "last_modified": 1660014482, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M78.4 67.2C173.8-22 324.5-24 421.5 71c14.3 14.1-6.4 37.1-22.4 21.5-84.8-82.4-215.8-80.3-298.9-3.2-16.3 15.1-36.5-8.3-21.8-22.1zm98.9 418.6c19.3 5.7 29.3-23.6 7.9-30C73 421.9 9.4 306.1 37.7 194.8c5-19.6-24.9-28.1-30.2-7.1-32.1 127.4 41.1 259.8 169.8 298.1zm148.1-2c121.9-40.2 192.9-166.9 164.4-291-4.5-19.7-34.9-13.8-30 7.9 24.2 107.7-37.1 217.9-143.2 253.4-21.2 7-10.4 36 8.8 29.7zm-62.9-79l.2-71.8c0-8.2-6.6-14.8-14.8-14.8-8.2 0-14.8 6.7-14.8 14.8l-.2 71.8c0 8.2 6.6 14.8 14.8 14.8s14.8-6.6 14.8-14.8zm71-269c2.1 90.9 4.7 131.9-85.5 132.5-92.5-.7-86.9-44.3-85.5-132.5 0-21.8-32.5-19.6-32.5 0v71.6c0 69.3 60.7 90.9 118 90.1 57.3.8 118-20.8 118-90.1v-71.6c0-19.6-32.5-21.8-32.5 0z" } }, "free": ["brands"] }, "black-tie": { "changes": ["4.4.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f27e", "label": "Font Awesome Black Tie", "voted": false, "svg": { "brands": { "last_modified": 1660014462, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M0 32v448h448V32H0zm316.5 325.2L224 445.9l-92.5-88.7 64.5-184-64.5-86.6h184.9L252 173.2l64.5 184z" } }, "free": ["brands"] }, "blackberry": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f37b", "label": "BlackBerry", "voted": false, "svg": { "brands": { "last_modified": 1660014471, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M166 116.9c0 23.4-16.4 49.1-72.5 49.1H23.4l21-88.8h67.8c42.1 0 53.8 23.3 53.8 39.7zm126.2-39.7h-67.8L205.7 166h70.1c53.8 0 70.1-25.7 70.1-49.1.1-16.4-11.6-39.7-53.7-39.7zM88.8 208.1H21L0 296.9h70.1c56.1 0 72.5-23.4 72.5-49.1 0-16.3-11.7-39.7-53.8-39.7zm180.1 0h-67.8l-18.7 88.8h70.1c53.8 0 70.1-23.4 70.1-49.1 0-16.3-11.7-39.7-53.7-39.7zm189.3-53.8h-67.8l-18.7 88.8h70.1c53.8 0 70.1-23.4 70.1-49.1.1-16.3-11.6-39.7-53.7-39.7zm-28 137.9h-67.8L343.7 381h70.1c56.1 0 70.1-23.4 70.1-49.1 0-16.3-11.6-39.7-53.7-39.7zM240.8 346H173l-18.7 88.8h70.1c56.1 0 70.1-25.7 70.1-49.1.1-16.3-11.6-39.7-53.7-39.7z" } }, "free": ["brands"] }, "blender": { "aliases": { "unicodes": { "secondary": ["10f517"] } }, "changes": ["5.0.13", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["cocktail", "milkshake", "mixer", "puree", "smoothie"] }, "styles": ["solid"], "unicode": "f517", "label": "Blender", "voted": false, "svg": { "solid": { "last_modified": 1684767419, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 64C0 28.7 28.7 0 64 0h64 32H470.1c21.1 0 36.4 20.1 30.9 40.4L494.5 64H336c-8.8 0-16 7.2-16 16s7.2 16 16 16H485.8l-17.5 64H336c-8.8 0-16 7.2-16 16s7.2 16 16 16H459.6l-17.5 64H336c-8.8 0-16 7.2-16 16s7.2 16 16 16h97.5L416 352H160l-8.7-96H64c-35.3 0-64-28.7-64-64V64zM145.5 192L133.8 64H64V192h81.5zM144 384H432c26.5 0 48 21.5 48 48v32c0 26.5-21.5 48-48 48H144c-26.5 0-48-21.5-48-48V432c0-26.5 21.5-48 48-48zm144 96a32 32 0 1 0 0-64 32 32 0 1 0 0 64z" } }, "free": ["solid"] }, "blender-phone": { "aliases": { "unicodes": { "secondary": ["10f6b6"] } }, "changes": ["5.4.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "appliance", "cocktail", "fantasy", "milkshake", "mixer", "puree", "silly", "smoothie" ] }, "styles": ["solid"], "unicode": "f6b6", "label": "Blender Phone", "voted": false, "svg": { "solid": { "last_modified": 1684767420, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M224 352L196.8 52.3C194.2 24.2 216.3 0 244.6 0H534.1c21.1 0 36.4 20.1 30.9 40.4L558.5 64H400c-8.8 0-16 7.2-16 16s7.2 16 16 16H549.8l-17.5 64H400c-8.8 0-16 7.2-16 16s7.2 16 16 16H523.6l-17.5 64H400c-8.8 0-16 7.2-16 16s7.2 16 16 16h97.5L480 352H224zm-16 32H496c26.5 0 48 21.5 48 48v32c0 26.5-21.5 48-48 48H208c-26.5 0-48-21.5-48-48V432c0-26.5 21.5-48 48-48zm144 96a32 32 0 1 0 0-64 32 32 0 1 0 0 64zM147.5 30.7c10.8 6.7 15.3 21 10.6 33.4l-22 57.8c-4.2 10.9-14.5 17.6-25.3 16.4l-33.3-3.6c-13.6 42.2-13.6 88.4 0 130.7l33.3-3.6c10.9-1.2 21.2 5.5 25.3 16.4l22 57.8c4.7 12.4 .2 26.7-10.6 33.4l-44 27.2c-9.7 6-21.9 4.2-29.8-4.3C-24.6 286-24.6 114 73.7 7.8C81.6-.7 93.8-2.5 103.5 3.5l44 27.2z" } }, "free": ["solid"] }, "blog": { "aliases": { "unicodes": { "secondary": ["10f781"] } }, "changes": ["5.6.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "journal", "log", "online", "personal", "post", "web 2.0", "wordpress", "writing" ] }, "styles": ["solid"], "unicode": "f781", "label": "Blog", "voted": true, "svg": { "solid": { "last_modified": 1684766677, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M192 32c0 17.7 14.3 32 32 32c123.7 0 224 100.3 224 224c0 17.7 14.3 32 32 32s32-14.3 32-32C512 128.9 383.1 0 224 0c-17.7 0-32 14.3-32 32zm0 96c0 17.7 14.3 32 32 32c70.7 0 128 57.3 128 128c0 17.7 14.3 32 32 32s32-14.3 32-32c0-106-86-192-192-192c-17.7 0-32 14.3-32 32zM96 144c0-26.5-21.5-48-48-48S0 117.5 0 144V368c0 79.5 64.5 144 144 144s144-64.5 144-144s-64.5-144-144-144H128v96h16c26.5 0 48 21.5 48 48s-21.5 48-48 48s-48-21.5-48-48V144z" } }, "free": ["solid"] }, "blogger": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f37c", "label": "Blogger", "voted": false, "svg": { "brands": { "last_modified": 1660014468, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M162.4 196c4.8-4.9 6.2-5.1 36.4-5.1 27.2 0 28.1.1 32.1 2.1 5.8 2.9 8.3 7 8.3 13.6 0 5.9-2.4 10-7.6 13.4-2.8 1.8-4.5 1.9-31.1 2.1-16.4.1-29.5-.2-31.5-.8-10.3-2.9-14.1-17.7-6.6-25.3zm61.4 94.5c-53.9 0-55.8.2-60.2 4.1-3.5 3.1-5.7 9.4-5.1 13.9.7 4.7 4.8 10.1 9.2 12 2.2 1 14.1 1.7 56.3 1.2l47.9-.6 9.2-1.5c9-5.1 10.5-17.4 3.1-24.4-5.3-4.7-5-4.7-60.4-4.7zm223.4 130.1c-3.5 28.4-23 50.4-51.1 57.5-7.2 1.8-9.7 1.9-172.9 1.8-157.8 0-165.9-.1-172-1.8-8.4-2.2-15.6-5.5-22.3-10-5.6-3.8-13.9-11.8-17-16.4-3.8-5.6-8.2-15.3-10-22C.1 423 0 420.3 0 256.3 0 93.2 0 89.7 1.8 82.6 8.1 57.9 27.7 39 53 33.4c7.3-1.6 332.1-1.9 340-.3 21.2 4.3 37.9 17.1 47.6 36.4 7.7 15.3 7-1.5 7.3 180.6.2 115.8 0 164.5-.7 170.5zm-85.4-185.2c-1.1-5-4.2-9.6-7.7-11.5-1.1-.6-8-1.3-15.5-1.7-12.4-.6-13.8-.8-17.8-3.1-6.2-3.6-7.9-7.6-8-18.3 0-20.4-8.5-39.4-25.3-56.5-12-12.2-25.3-20.5-40.6-25.1-3.6-1.1-11.8-1.5-39.2-1.8-42.9-.5-52.5.4-67.1 6.2-27 10.7-46.3 33.4-53.4 62.4-1.3 5.4-1.6 14.2-1.9 64.3-.4 62.8 0 72.1 4 84.5 9.7 30.7 37.1 53.4 64.6 58.4 9.2 1.7 122.2 2.1 133.7.5 20.1-2.7 35.9-10.8 50.7-25.9 10.7-10.9 17.4-22.8 21.8-38.5 3.2-10.9 2.9-88.4 1.7-93.9z" } }, "free": ["brands"] }, "blogger-b": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f37d", "label": "Blogger B", "voted": false, "svg": { "brands": { "last_modified": 1660014471, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M446.6 222.7c-1.8-8-6.8-15.4-12.5-18.5-1.8-1-13-2.2-25-2.7-20.1-.9-22.3-1.3-28.7-5-10.1-5.9-12.8-12.3-12.9-29.5-.1-33-13.8-63.7-40.9-91.3-19.3-19.7-40.9-33-65.5-40.5-5.9-1.8-19.1-2.4-63.3-2.9-69.4-.8-84.8.6-108.4 10C45.9 59.5 14.7 96.1 3.3 142.9 1.2 151.7.7 165.8.2 246.8c-.6 101.5.1 116.4 6.4 136.5 15.6 49.6 59.9 86.3 104.4 94.3 14.8 2.7 197.3 3.3 216 .8 32.5-4.4 58-17.5 81.9-41.9 17.3-17.7 28.1-36.8 35.2-62.1 4.9-17.6 4.5-142.8 2.5-151.7zm-322.1-63.6c7.8-7.9 10-8.2 58.8-8.2 43.9 0 45.4.1 51.8 3.4 9.3 4.7 13.4 11.3 13.4 21.9 0 9.5-3.8 16.2-12.3 21.6-4.6 2.9-7.3 3.1-50.3 3.3-26.5.2-47.7-.4-50.8-1.2-16.6-4.7-22.8-28.5-10.6-40.8zm191.8 199.8l-14.9 2.4-77.5.9c-68.1.8-87.3-.4-90.9-2-7.1-3.1-13.8-11.7-14.9-19.4-1.1-7.3 2.6-17.3 8.2-22.4 7.1-6.4 10.2-6.6 97.3-6.7 89.6-.1 89.1-.1 97.6 7.8 12.1 11.3 9.5 31.2-4.9 39.4z" } }, "free": ["brands"] }, "bluetooth": { "aliases": { "unicodes": { "secondary": ["10f293"] } }, "changes": ["4.5.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["signal"] }, "styles": ["brands"], "unicode": "f293", "label": "Bluetooth", "voted": false, "svg": { "brands": { "last_modified": 1660014464, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M292.6 171.1L249.7 214l-.3-86 43.2 43.1m-43.2 219.8l43.1-43.1-42.9-42.9-.2 86zM416 259.4C416 465 344.1 512 230.9 512S32 465 32 259.4 115.4 0 228.6 0 416 53.9 416 259.4zm-158.5 0l79.4-88.6L211.8 36.5v176.9L138 139.6l-27 26.9 92.7 93-92.7 93 26.9 26.9 73.8-73.8 2.3 170 127.4-127.5-83.9-88.7z" } }, "free": ["brands"] }, "bluetooth-b": { "changes": ["4.5.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f294", "label": "Bluetooth", "voted": false, "svg": { "brands": { "last_modified": 1660014475, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M196.48 260.023l92.626-103.333L143.125 0v206.33l-86.111-86.111-31.406 31.405 108.061 108.399L25.608 368.422l31.406 31.405 86.111-86.111L145.84 512l148.552-148.644-97.912-103.333zm40.86-102.996l-49.977 49.978-.338-100.295 50.315 50.317zM187.363 313.04l49.977 49.978-50.315 50.316.338-100.294z" } }, "free": ["brands"] }, "bold": { "aliases": { "unicodes": { "secondary": ["10f032"] } }, "changes": [ "1.0.0", "5.0.0", "5.9.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["emphasis", "format", "text"] }, "styles": ["solid"], "unicode": "f032", "label": "Bold", "voted": false, "svg": { "solid": { "last_modified": 1684767246, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M0 64C0 46.3 14.3 32 32 32H80 96 224c70.7 0 128 57.3 128 128c0 31.3-11.3 60.1-30 82.3c37.1 22.4 62 63.1 62 109.7c0 70.7-57.3 128-128 128H96 80 32c-17.7 0-32-14.3-32-32s14.3-32 32-32H48V256 96H32C14.3 96 0 81.7 0 64zM224 224c35.3 0 64-28.7 64-64s-28.7-64-64-64H112V224H224zM112 288V416H256c35.3 0 64-28.7 64-64s-28.7-64-64-64H224 112z" } }, "free": ["solid"] }, "bolt": { "aliases": { "names": ["zap"], "unicodes": { "composite": ["26a1"], "secondary": ["10f0e7"] } }, "changes": [ "2.0.0", "5.0.0", "5.5.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "charge", "danger", "electric", "electricity", "flash", "high voltage", "lightning", "voltage", "weather", "zap" ] }, "styles": ["solid"], "unicode": "f0e7", "label": "Bolt", "voted": false, "svg": { "solid": { "last_modified": 1684767367, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M349.4 44.6c5.9-13.7 1.5-29.7-10.6-38.5s-28.6-8-39.9 1.8l-256 224c-10 8.8-13.6 22.9-8.9 35.3S50.7 288 64 288H175.5L98.6 467.4c-5.9 13.7-1.5 29.7 10.6 38.5s28.6 8 39.9-1.8l256-224c10-8.8 13.6-22.9 8.9-35.3s-16.6-20.7-30-20.7H272.5L349.4 44.6z" } }, "free": ["solid"] }, "bolt-lightning": { "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["electricity", "flash", "lightning", "weather", "zap"] }, "styles": ["solid"], "unicode": "e0b7", "label": "Bolt Lightning", "voted": false, "svg": { "solid": { "last_modified": 1684767662, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M0 256L28.5 28c2-16 15.6-28 31.8-28H228.9c15 0 27.1 12.1 27.1 27.1c0 3.2-.6 6.5-1.7 9.5L208 160H347.3c20.2 0 36.7 16.4 36.7 36.7c0 7.4-2.2 14.6-6.4 20.7l-192.2 281c-5.9 8.6-15.6 13.7-25.9 13.7h-2.9c-15.7 0-28.5-12.8-28.5-28.5c0-2.3 .3-4.6 .9-6.9L176 288H32c-17.7 0-32-14.3-32-32z" } }, "free": ["solid"] }, "bomb": { "aliases": { "unicodes": { "composite": ["1f4a3"], "secondary": ["10f1e2"] } }, "changes": [ "4.1.0", "5.0.0", "6.0.0-beta1", "6.0.0", "6.1.2", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "bomb", "comic", "error", "explode", "fuse", "grenade", "warning" ] }, "styles": ["solid"], "unicode": "f1e2", "label": "Bomb", "voted": false, "svg": { "solid": { "last_modified": 1684767367, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M459.1 52.4L442.6 6.5C440.7 2.6 436.5 0 432.1 0s-8.5 2.6-10.4 6.5L405.2 52.4l-46 16.8c-4.3 1.6-7.3 5.9-7.2 10.4c0 4.5 3 8.7 7.2 10.2l45.7 16.8 16.8 45.8c1.5 4.4 5.8 7.5 10.4 7.5s8.9-3.1 10.4-7.5l16.5-45.8 45.7-16.8c4.2-1.5 7.2-5.7 7.2-10.2c0-4.6-3-8.9-7.2-10.4L459.1 52.4zm-132.4 53c-12.5-12.5-32.8-12.5-45.3 0l-2.9 2.9C256.5 100.3 232.7 96 208 96C93.1 96 0 189.1 0 304S93.1 512 208 512s208-93.1 208-208c0-24.7-4.3-48.5-12.2-70.5l2.9-2.9c12.5-12.5 12.5-32.8 0-45.3l-80-80zM200 192c-57.4 0-104 46.6-104 104v8c0 8.8-7.2 16-16 16s-16-7.2-16-16v-8c0-75.1 60.9-136 136-136h8c8.8 0 16 7.2 16 16s-7.2 16-16 16h-8z" } }, "free": ["solid"] }, "bone": { "aliases": { "unicodes": { "composite": ["1f9b4"], "secondary": ["10f5d7"] } }, "changes": ["5.2.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["bone", "calcium", "dog", "skeletal", "skeleton", "tibia"] }, "styles": ["solid"], "unicode": "f5d7", "label": "Bone", "voted": false, "svg": { "solid": { "last_modified": 1684766749, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M153.7 144.8c6.9 16.3 20.6 31.2 38.3 31.2H384c17.7 0 31.4-14.9 38.3-31.2C434.4 116.1 462.9 96 496 96c44.2 0 80 35.8 80 80c0 30.4-17 56.9-42 70.4c-3.6 1.9-6 5.5-6 9.6s2.4 7.7 6 9.6c25 13.5 42 40 42 70.4c0 44.2-35.8 80-80 80c-33.1 0-61.6-20.1-73.7-48.8C415.4 350.9 401.7 336 384 336H192c-17.7 0-31.4 14.9-38.3 31.2C141.6 395.9 113.1 416 80 416c-44.2 0-80-35.8-80-80c0-30.4 17-56.9 42-70.4c3.6-1.9 6-5.5 6-9.6s-2.4-7.7-6-9.6C17 232.9 0 206.4 0 176c0-44.2 35.8-80 80-80c33.1 0 61.6 20.1 73.7 48.8z" } }, "free": ["solid"] }, "bong": { "aliases": { "unicodes": { "secondary": ["10f55c"] } }, "changes": ["5.1.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["aparatus", "cannabis", "marijuana", "pipe", "smoke", "smoking"] }, "styles": ["solid"], "unicode": "f55c", "label": "Bong", "voted": false, "svg": { "solid": { "last_modified": 1684766751, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M160 208.5c0 29.1-15.6 53.9-37.2 67.8c-17.2 11.1-31.5 26.1-41.7 43.7H302.9c-10.2-17.6-24.5-32.6-41.7-43.7c-21.6-13.9-37.2-38.7-37.2-67.8V64H160V208.5zM288 64V208.5c0 5.7 3.1 10.9 7.9 14c11.2 7.2 21.5 15.5 30.9 24.8L366.1 208l-7-7c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l24 24 24 24c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-7-7-43.3 43.3C374 314.1 384 347.9 384 384c0 39.4-11.9 76.1-32.2 106.5c-9.6 14.4-26.5 21.5-43.8 21.5H76.1c-17.3 0-34.2-7.1-43.8-21.5C11.9 460.1 0 423.4 0 384c0-67.8 35.1-127.3 88.1-161.5c4.8-3.1 7.9-8.3 7.9-14V64C78.3 64 64 49.7 64 32S78.3 0 96 0h16H272h16c17.7 0 32 14.3 32 32s-14.3 32-32 32z" } }, "free": ["solid"] }, "book": { "aliases": { "unicodes": { "composite": ["1f4d4"], "secondary": ["10f02d"] } }, "changes": ["1.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "book", "cover", "decorated", "diary", "documentation", "journal", "library", "notebook", "notebook with decorative cover", "read", "research" ] }, "styles": ["solid"], "unicode": "f02d", "label": "Book", "voted": false, "svg": { "solid": { "last_modified": 1684767389, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M96 0C43 0 0 43 0 96V416c0 53 43 96 96 96H384h32c17.7 0 32-14.3 32-32s-14.3-32-32-32V384c17.7 0 32-14.3 32-32V32c0-17.7-14.3-32-32-32H384 96zm0 384H352v64H96c-17.7 0-32-14.3-32-32s14.3-32 32-32zm32-240c0-8.8 7.2-16 16-16H336c8.8 0 16 7.2 16 16s-7.2 16-16 16H144c-8.8 0-16-7.2-16-16zm16 48H336c8.8 0 16 7.2 16 16s-7.2 16-16 16H144c-8.8 0-16-7.2-16-16s7.2-16 16-16z" } }, "free": ["solid"] }, "book-atlas": { "aliases": { "names": ["atlas"], "unicodes": { "secondary": ["10f558"] } }, "changes": ["5.1.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "book", "directions", "geography", "globe", "library", "map", "research", "travel", "wayfinding" ] }, "styles": ["solid"], "unicode": "f558", "label": "Book Atlas", "voted": false, "svg": { "solid": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M0 96C0 43 43 0 96 0H384h32c17.7 0 32 14.3 32 32V352c0 17.7-14.3 32-32 32v64c17.7 0 32 14.3 32 32s-14.3 32-32 32H384 96c-53 0-96-43-96-96V96zM64 416c0 17.7 14.3 32 32 32H352V384H96c-17.7 0-32 14.3-32 32zM247.4 283.8c-3.7 3.7-6.2 4.2-7.4 4.2s-3.7-.5-7.4-4.2c-3.8-3.7-8-10-11.8-18.9c-6.2-14.5-10.8-34.3-12.2-56.9h63c-1.5 22.6-6 42.4-12.2 56.9c-3.8 8.9-8 15.2-11.8 18.9zm42.7-9.9c7.3-18.3 12-41.1 13.4-65.9h31.1c-4.7 27.9-21.4 51.7-44.5 65.9zm0-163.8c23.2 14.2 39.9 38 44.5 65.9H303.5c-1.4-24.7-6.1-47.5-13.4-65.9zM368 192a128 128 0 1 0 -256 0 128 128 0 1 0 256 0zM145.3 208h31.1c1.4 24.7 6.1 47.5 13.4 65.9c-23.2-14.2-39.9-38-44.5-65.9zm31.1-32H145.3c4.7-27.9 21.4-51.7 44.5-65.9c-7.3 18.3-12 41.1-13.4 65.9zm56.1-75.8c3.7-3.7 6.2-4.2 7.4-4.2s3.7 .5 7.4 4.2c3.8 3.7 8 10 11.8 18.9c6.2 14.5 10.8 34.3 12.2 56.9h-63c1.5-22.6 6-42.4 12.2-56.9c3.8-8.9 8-15.2 11.8-18.9z" } }, "free": ["solid"] }, "book-bible": { "aliases": { "names": ["bible"], "unicodes": { "secondary": ["10f647"] } }, "changes": ["5.3.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["book", "catholicism", "christianity", "god", "holy"] }, "styles": ["solid"], "unicode": "f647", "label": "Book Bible", "voted": false, "svg": { "solid": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M96 0C43 0 0 43 0 96V416c0 53 43 96 96 96H384h32c17.7 0 32-14.3 32-32s-14.3-32-32-32V384c17.7 0 32-14.3 32-32V32c0-17.7-14.3-32-32-32H384 96zm0 384H352v64H96c-17.7 0-32-14.3-32-32s14.3-32 32-32zM208 80c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v48h48c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H272V304c0 8.8-7.2 16-16 16H224c-8.8 0-16-7.2-16-16V192H160c-8.8 0-16-7.2-16-16V144c0-8.8 7.2-16 16-16h48V80z" } }, "free": ["solid"] }, "book-bookmark": { "changes": ["6.0.0-beta1", "6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["library", "research"] }, "styles": ["solid"], "unicode": "e0bb", "label": "Book Bookmark", "voted": false, "svg": { "solid": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M0 96C0 43 43 0 96 0h96V190.7c0 13.4 15.5 20.9 26 12.5L272 160l54 43.2c10.5 8.4 26 .9 26-12.5V0h32 32c17.7 0 32 14.3 32 32V352c0 17.7-14.3 32-32 32v64c17.7 0 32 14.3 32 32s-14.3 32-32 32H384 96c-53 0-96-43-96-96V96zM64 416c0 17.7 14.3 32 32 32H352V384H96c-17.7 0-32 14.3-32 32z" } }, "free": ["solid"] }, "book-journal-whills": { "aliases": { "names": ["journal-whills"], "unicodes": { "secondary": ["10f66a"] } }, "changes": ["5.3.0", "5.11.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["book", "force", "jedi", "sith", "star wars", "yoda"] }, "styles": ["solid"], "unicode": "f66a", "label": "Book Journal Whills", "voted": false, "svg": { "solid": { "last_modified": 1684767389, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M0 96C0 43 43 0 96 0H384h32c17.7 0 32 14.3 32 32V352c0 17.7-14.3 32-32 32v64c17.7 0 32 14.3 32 32s-14.3 32-32 32H384 96c-53 0-96-43-96-96V96zM64 416c0 17.7 14.3 32 32 32H352V384H96c-17.7 0-32 14.3-32 32zm90.4-234.4l-21.2-21.2c-3 10.1-5.1 20.6-5.1 31.6c0 .2 0 .5 .1 .8s.1 .5 .1 .8L165.2 226c2.5 2.1 3.4 5.8 2.3 8.9c-1.3 3-4.1 5.1-7.5 5.1c-1.9-.1-3.8-.8-5.2-2l-23.6-20.6C142.8 267 186.9 304 240 304s97.3-37 108.9-86.6L325.3 238c-1.4 1.2-3.3 2-5.3 2c-2.2-.1-4.4-1.1-6-2.8c-1.2-1.5-1.9-3.4-2-5.2c.1-2.2 1.1-4.4 2.8-6l37.1-32.5c0-.3 0-.5 .1-.8s.1-.5 .1-.8c0-11-2.1-21.5-5.1-31.6l-21.2 21.2c-3.1 3.1-8.1 3.1-11.3 0s-3.1-8.1 0-11.2l26.4-26.5c-8.2-17-20.5-31.7-35.9-42.6c-2.7-1.9-6.2 1.4-5 4.5c8.5 22.4 3.6 48-13 65.6c-3.2 3.4-3.6 8.9-.9 12.7c9.8 14 12.7 31.9 7.5 48.5c-5.9 19.4-22 34.1-41.9 38.3l-1.4-34.3 12.6 8.6c.6 .4 1.5 .6 2.3 .6c1.5 0 2.7-.8 3.5-2s.6-2.8-.1-4L260 225.4l18-3.6c1.8-.4 3.1-2.1 3.1-4s-1.4-3.5-3.1-3.9l-18-3.7 8.5-14.3c.8-1.2 .9-2.9 .1-4.1s-2-2-3.5-2l-.1 0c-.7 .1-1.5 .3-2.1 .7l-14.1 9.6L244 87.9c-.1-2.2-1.9-3.9-4-3.9s-3.9 1.6-4 3.9l-4.6 110.8-12-8.1c-1.5-1.1-3.6-.9-5 .4s-1.6 3.4-.8 5l8.6 14.3-18 3.7c-1.8 .4-3.1 2-3.1 3.9s1.4 3.6 3.1 4l18 3.8-8.6 14.2c-.2 .6-.5 1.4-.5 2c0 1.1 .5 2.1 1.2 3c.8 .6 1.8 1 2.8 1c.7 0 1.6-.2 2.2-.6l10.4-7.1-1.4 32.8c-19.9-4.1-36-18.9-41.9-38.3c-5.1-16.6-2.2-34.4 7.6-48.5c2.7-3.9 2.3-9.3-.9-12.7c-16.6-17.5-21.6-43.1-13.1-65.5c1.2-3.1-2.3-6.4-5-4.5c-15.3 10.9-27.6 25.6-35.8 42.6l26.4 26.5c3.1 3.1 3.1 8.1 0 11.2s-8.1 3.1-11.2 0z" } }, "free": ["solid"] }, "book-medical": { "aliases": { "unicodes": { "secondary": ["10f7e6"] } }, "changes": ["5.7.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "diary", "documentation", "health", "history", "journal", "library", "read", "record", "research" ] }, "styles": ["solid"], "unicode": "f7e6", "label": "Book Medical", "voted": false, "svg": { "solid": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M0 96C0 43 43 0 96 0H384h32c17.7 0 32 14.3 32 32V352c0 17.7-14.3 32-32 32v64c17.7 0 32 14.3 32 32s-14.3 32-32 32H384 96c-53 0-96-43-96-96V96zM64 416c0 17.7 14.3 32 32 32H352V384H96c-17.7 0-32 14.3-32 32zM208 112v48H160c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h48v48c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V224h48c8.8 0 16-7.2 16-16V176c0-8.8-7.2-16-16-16H272V112c0-8.8-7.2-16-16-16H224c-8.8 0-16 7.2-16 16z" } }, "free": ["solid"] }, "book-open": { "aliases": { "unicodes": { "composite": ["1f4d6", "1f56e"], "secondary": ["10f518"] } }, "changes": [ "5.0.13", "5.1.0", "5.2.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Book", "book", "flyer", "library", "notebook", "open", "open book", "pamphlet", "reading", "research" ] }, "styles": ["solid"], "unicode": "f518", "label": "Book Open", "voted": true, "svg": { "solid": { "last_modified": 1684767389, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M249.6 471.5c10.8 3.8 22.4-4.1 22.4-15.5V78.6c0-4.2-1.6-8.4-5-11C247.4 52 202.4 32 144 32C93.5 32 46.3 45.3 18.1 56.1C6.8 60.5 0 71.7 0 83.8V454.1c0 11.9 12.8 20.2 24.1 16.5C55.6 460.1 105.5 448 144 448c33.9 0 79 14 105.6 23.5zm76.8 0C353 462 398.1 448 432 448c38.5 0 88.4 12.1 119.9 22.6c11.3 3.8 24.1-4.6 24.1-16.5V83.8c0-12.1-6.8-23.3-18.1-27.6C529.7 45.3 482.5 32 432 32c-58.4 0-103.4 20-123 35.6c-3.3 2.6-5 6.8-5 11V456c0 11.4 11.7 19.3 22.4 15.5z" } }, "free": ["solid"] }, "book-open-reader": { "aliases": { "names": ["book-reader"], "unicodes": { "secondary": ["10f5da"] } }, "changes": ["5.2.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0", "6.4.1"], "ligatures": [], "search": { "terms": [ "flyer", "library", "notebook", "open book", "pamphlet", "reading", "research" ] }, "styles": ["solid"], "unicode": "f5da", "label": "Book Open Reader", "voted": false, "svg": { "solid": { "last_modified": 1684767390, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M160 96a96 96 0 1 1 192 0A96 96 0 1 1 160 96zm80 152V512l-48.4-24.2c-20.9-10.4-43.5-17-66.8-19.3l-96-9.6C12.5 457.2 0 443.5 0 427V224c0-17.7 14.3-32 32-32H62.3c63.6 0 125.6 19.6 177.7 56zm32 264V248c52.1-36.4 114.1-56 177.7-56H480c17.7 0 32 14.3 32 32V427c0 16.4-12.5 30.2-28.8 31.8l-96 9.6c-23.2 2.3-45.9 8.9-66.8 19.3L272 512z" } }, "free": ["solid"] }, "book-quran": { "aliases": { "names": ["quran"], "unicodes": { "secondary": ["10f687"] } }, "changes": ["5.3.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["book", "islam", "muslim", "religion"] }, "styles": ["solid"], "unicode": "f687", "label": "Book Quran", "voted": false, "svg": { "solid": { "last_modified": 1684767389, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M352 0c53 0 96 43 96 96V416c0 53-43 96-96 96H64 32c-17.7 0-32-14.3-32-32s14.3-32 32-32V384c-17.7 0-32-14.3-32-32V32C0 14.3 14.3 0 32 0H64 352zm0 384H96v64H352c17.7 0 32-14.3 32-32s-14.3-32-32-32zM274.1 150.2l-8.9 21.4-23.1 1.9c-5.7 .5-8 7.5-3.7 11.2L256 199.8l-5.4 22.6c-1.3 5.5 4.7 9.9 9.6 6.9L280 217.2l19.8 12.1c4.9 3 10.9-1.4 9.6-6.9L304 199.8l17.6-15.1c4.3-3.7 2-10.8-3.7-11.2l-23.1-1.9-8.9-21.4c-2.2-5.3-9.6-5.3-11.8 0zM96 192c0 70.7 57.3 128 128 128c25.6 0 49.5-7.5 69.5-20.5c3.2-2.1 4.5-6.2 3.1-9.7s-5.2-5.6-9-4.8c-6.1 1.2-12.5 1.9-19 1.9c-52.4 0-94.9-42.5-94.9-94.9s42.5-94.9 94.9-94.9c6.5 0 12.8 .7 19 1.9c3.8 .8 7.5-1.3 9-4.8s.2-7.6-3.1-9.7C273.5 71.5 249.6 64 224 64C153.3 64 96 121.3 96 192z" } }, "free": ["solid"] }, "book-skull": { "aliases": { "names": ["book-dead"], "unicodes": { "secondary": ["10f6b7"] } }, "changes": ["5.4.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "Dungeons & Dragons", "crossbones", "d&d", "dark arts", "death", "dnd", "documentation", "evil", "fantasy", "halloween", "holiday", "library", "necronomicon", "read", "research", "skull", "spell" ] }, "styles": ["solid"], "unicode": "f6b7", "label": "Book Skull", "voted": false, "svg": { "solid": { "last_modified": 1684767390, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M0 96C0 43 43 0 96 0H384h32c17.7 0 32 14.3 32 32V352c0 17.7-14.3 32-32 32v64c17.7 0 32 14.3 32 32s-14.3 32-32 32H384 96c-53 0-96-43-96-96V96zM64 416c0 17.7 14.3 32 32 32H352V384H96c-17.7 0-32 14.3-32 32zM320 112c0-35.3-35.8-64-80-64s-80 28.7-80 64c0 20.9 12.6 39.5 32 51.2V176c0 8.8 7.2 16 16 16h64c8.8 0 16-7.2 16-16V163.2c19.4-11.7 32-30.3 32-51.2zM208 96a16 16 0 1 1 0 32 16 16 0 1 1 0-32zm48 16a16 16 0 1 1 32 0 16 16 0 1 1 -32 0zM134.3 209.3c-8.1-3.5-17.5 .3-21 8.4s.3 17.5 8.4 21L199.4 272l-77.7 33.3c-8.1 3.5-11.9 12.9-8.4 21s12.9 11.9 21 8.4L240 289.4l105.7 45.3c8.1 3.5 17.5-.3 21-8.4s-.3-17.5-8.4-21L280.6 272l77.7-33.3c8.1-3.5 11.9-12.9 8.4-21s-12.9-11.9-21-8.4L240 254.6 134.3 209.3z" } }, "free": ["solid"] }, "book-tanakh": { "aliases": { "names": ["tanakh"], "unicodes": { "secondary": ["10f827"] } }, "changes": ["5.7.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["book", "jewish", "judaism", "religion"] }, "styles": ["solid"], "unicode": "f827", "label": "Book Tanakh", "voted": false, "svg": { "solid": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M352 0c53 0 96 43 96 96V416c0 53-43 96-96 96H64 32c-17.7 0-32-14.3-32-32s14.3-32 32-32V384c-17.7 0-32-14.3-32-32V32C0 14.3 14.3 0 32 0H64 352zm0 384H96v64H352c17.7 0 32-14.3 32-32s-14.3-32-32-32zM138.7 208l13.9 24H124.9l13.9-24zm-13.9-24L97.1 232c-6.2 10.7 1.5 24 13.9 24h55.4l27.7 48c6.2 10.7 21.6 10.7 27.7 0l27.7-48H305c12.3 0 20-13.3 13.9-24l-27.7-48 27.7-48c6.2-10.7-1.5-24-13.9-24H249.6L221.9 64c-6.2-10.7-21.6-10.7-27.7 0l-27.7 48H111c-12.3 0-20 13.3-13.9 24l27.7 48zm27.7 0l27.7-48h55.4l27.7 48-27.7 48H180.3l-27.7-48zm0-48l-13.9 24-13.9-24h27.7zm41.6-24L208 88l13.9 24H194.1zm69.3 24h27.7l-13.9 24-13.9-24zm13.9 72l13.9 24H263.4l13.9-24zm-55.4 48L208 280l-13.9-24h27.7z" } }, "free": ["solid"] }, "bookmark": { "aliases": { "unicodes": { "composite": ["1f516", "f097"], "secondary": ["10f02e"] } }, "changes": [ "1.0.0", "5.0.0", "5.10.2", "6.0.0-beta1", "6.1.2", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "bookmark", "favorite", "library", "mark", "marker", "read", "remember", "research", "save" ] }, "styles": ["solid", "regular"], "unicode": "f02e", "label": "Bookmark", "voted": false, "svg": { "solid": { "last_modified": 1684767392, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M0 48V487.7C0 501.1 10.9 512 24.3 512c5 0 9.9-1.5 14-4.4L192 400 345.7 507.6c4.1 2.9 9 4.4 14 4.4c13.4 0 24.3-10.9 24.3-24.3V48c0-26.5-21.5-48-48-48H48C21.5 0 0 21.5 0 48z" }, "regular": { "last_modified": 1684767392, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M0 48C0 21.5 21.5 0 48 0l0 48V441.4l130.1-92.9c8.3-6 19.6-6 27.9 0L336 441.4V48H48V0H336c26.5 0 48 21.5 48 48V488c0 9-5 17.2-13 21.3s-17.6 3.4-24.9-1.8L192 397.5 37.9 507.5c-7.3 5.2-16.9 5.9-24.9 1.8S0 497 0 488V48z" } }, "free": ["regular", "solid"] }, "bootstrap": { "changes": ["5.8.0", "5.15.4", "6.0.0-beta1"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f836", "label": "Bootstrap", "voted": false, "svg": { "brands": { "last_modified": 1660014471, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M333.5,201.4c0-22.1-15.6-34.3-43-34.3h-50.4v71.2h42.5C315.4,238.2,333.5,225,333.5,201.4z M517,188.6 c-9.5-30.9-10.9-68.8-9.8-98.1c1.1-30.5-22.7-58.5-54.7-58.5H123.7c-32.1,0-55.8,28.1-54.7,58.5c1,29.3-0.3,67.2-9.8,98.1 c-9.6,31-25.7,50.6-52.2,53.1v28.5c26.4,2.5,42.6,22.1,52.2,53.1c9.5,30.9,10.9,68.8,9.8,98.1c-1.1,30.5,22.7,58.5,54.7,58.5h328.7 c32.1,0,55.8-28.1,54.7-58.5c-1-29.3,0.3-67.2,9.8-98.1c9.6-31,25.7-50.6,52.1-53.1v-28.5C542.7,239.2,526.5,219.6,517,188.6z M300.2,375.1h-97.9V136.8h97.4c43.3,0,71.7,23.4,71.7,59.4c0,25.3-19.1,47.9-43.5,51.8v1.3c33.2,3.6,55.5,26.6,55.5,58.3 C383.4,349.7,352.1,375.1,300.2,375.1z M290.2,266.4h-50.1v78.4h52.3c34.2,0,52.3-13.7,52.3-39.5 C344.7,279.6,326.1,266.4,290.2,266.4z" } }, "free": ["brands"] }, "border-all": { "aliases": { "unicodes": { "secondary": ["10f84c"] } }, "changes": [ "5.9.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["cell", "grid", "outline", "stroke", "table"] }, "styles": ["solid"], "unicode": "f84c", "label": "Border All", "voted": false, "svg": { "solid": { "last_modified": 1684767205, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M384 96V224H256V96H384zm0 192V416H256V288H384zM192 224H64V96H192V224zM64 288H192V416H64V288zM64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64z" } }, "free": ["solid"] }, "border-none": { "aliases": { "unicodes": { "secondary": ["10f850"] } }, "changes": [ "5.9.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["cell", "grid", "outline", "stroke", "table"] }, "styles": ["solid"], "unicode": "f850", "label": "Border None", "voted": false, "svg": { "solid": { "last_modified": 1684767206, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M32 480a32 32 0 1 1 0-64 32 32 0 1 1 0 64zm96-64a32 32 0 1 1 0 64 32 32 0 1 1 0-64zm0-384a32 32 0 1 1 0 64 32 32 0 1 1 0-64zm0 256a32 32 0 1 1 0-64 32 32 0 1 1 0 64zM320 416a32 32 0 1 1 0 64 32 32 0 1 1 0-64zm0-320a32 32 0 1 1 0-64 32 32 0 1 1 0 64zm0 128a32 32 0 1 1 0 64 32 32 0 1 1 0-64zM224 480a32 32 0 1 1 0-64 32 32 0 1 1 0 64zm0-448a32 32 0 1 1 0 64 32 32 0 1 1 0-64zm0 256a32 32 0 1 1 0-64 32 32 0 1 1 0 64zM416 416a32 32 0 1 1 0 64 32 32 0 1 1 0-64zm0-384a32 32 0 1 1 0 64 32 32 0 1 1 0-64zM32 96a32 32 0 1 1 0-64 32 32 0 1 1 0 64zM416 224a32 32 0 1 1 0 64 32 32 0 1 1 0-64zM32 288a32 32 0 1 1 0-64 32 32 0 1 1 0 64zm192 32a32 32 0 1 1 0 64 32 32 0 1 1 0-64zm192 64a32 32 0 1 1 0-64 32 32 0 1 1 0 64zM32 320a32 32 0 1 1 0 64 32 32 0 1 1 0-64zM416 192a32 32 0 1 1 0-64 32 32 0 1 1 0 64zM32 128a32 32 0 1 1 0 64 32 32 0 1 1 0-64zm192 64a32 32 0 1 1 0-64 32 32 0 1 1 0 64z" } }, "free": ["solid"] }, "border-top-left": { "aliases": { "names": ["border-style"], "unicodes": { "secondary": ["10f853"] } }, "changes": [ "5.9.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["cell", "outline", "stroke", "table"] }, "styles": ["solid"], "unicode": "f853", "label": "Border Top Left", "voted": false, "svg": { "solid": { "last_modified": 1684767207, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M0 448c0 17.7 14.3 32 32 32s32-14.3 32-32l0-336c0-8.8 7.2-16 16-16l336 0c17.7 0 32-14.3 32-32s-14.3-32-32-32L80 32C35.8 32 0 67.8 0 112L0 448zm160 0a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zm192 0a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zm-96 0a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zm192 0a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zM416 288a32 32 0 1 0 0-64 32 32 0 1 0 0 64zm0 32a32 32 0 1 0 0 64 32 32 0 1 0 0-64zm0-128a32 32 0 1 0 0-64 32 32 0 1 0 0 64z" } }, "free": ["solid"] }, "bore-hole": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["bore", "bury", "drill", "hole"] }, "styles": ["solid"], "unicode": "e4c3", "label": "Bore Hole", "voted": false, "svg": { "solid": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 0c-17.7 0-32 14.3-32 32V296.6c-19.1 11.1-32 31.7-32 55.4c0 35.3 28.7 64 64 64s64-28.7 64-64c0-23.7-12.9-44.4-32-55.4V32c0-17.7-14.3-32-32-32zM48 128c-26.5 0-48 21.5-48 48V464c0 26.5 21.5 48 48 48H464c26.5 0 48-21.5 48-48V176c0-26.5-21.5-48-48-48H384c-17.7 0-32 14.3-32 32V352c0 53-43 96-96 96s-96-43-96-96V160c0-17.7-14.3-32-32-32H48z" } }, "free": ["solid"] }, "bots": { "changes": ["6.0.0-beta1"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e340", "label": "Bots", "voted": false, "svg": { "brands": { "last_modified": 1660014462, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M86.344,197.834a51.767,51.767,0,0,0-41.57,20.058V156.018a8.19,8.19,0,0,0-8.19-8.19H8.19A8.19,8.19,0,0,0,0,156.018V333.551a8.189,8.189,0,0,0,8.19,8.189H36.584a8.189,8.189,0,0,0,8.19-8.189v-8.088c11.628,13.373,25.874,19.769,41.573,19.769,34.6,0,61.922-26.164,61.922-73.843C148.266,225.452,121.229,197.834,86.344,197.834ZM71.516,305.691c-9.593,0-21.221-4.942-26.745-12.5V250.164c5.528-7.558,17.152-12.791,26.745-12.791,17.734,0,31.107,13.082,31.107,34.013C102.623,292.609,89.25,305.691,71.516,305.691Zm156.372-59.032a17.4,17.4,0,1,0,17.4,17.4A17.4,17.4,0,0,0,227.888,246.659ZM273.956,156.7V112.039a13.308,13.308,0,1,0-10.237,0V156.7a107.49,107.49,0,1,0,10.237,0Zm85.993,107.367c0,30.531-40.792,55.281-91.112,55.281s-91.111-24.75-91.111-55.281,40.792-55.281,91.111-55.281S359.949,233.532,359.949,264.062Zm-50.163,17.4a17.4,17.4,0,1,0-17.4-17.4h0A17.4,17.4,0,0,0,309.786,281.466ZM580.7,250.455c-14.828-2.617-22.387-3.78-22.387-9.885,0-5.523,7.268-9.884,17.735-9.884a65.56,65.56,0,0,1,34.484,10.1,8.171,8.171,0,0,0,11.288-2.468c.07-.11.138-.221.2-.333l8.611-14.886a8.2,8.2,0,0,0-2.867-11.123,99.863,99.863,0,0,0-52.014-14.138c-38.956,0-60.179,21.514-60.179,46.225,0,36.342,33.725,41.864,57.563,45.642,13.373,2.326,24.13,4.361,24.13,11.048,0,6.4-5.523,10.757-18.9,10.757-13.552,0-30.994-6.222-42.623-13.579a8.206,8.206,0,0,0-11.335,2.491c-.035.054-.069.108-.1.164l-10.2,16.891a8.222,8.222,0,0,0,2.491,11.066c15.224,10.3,37.663,16.692,59.441,16.692,40.409,0,63.957-19.769,63.957-46.515C640,260.63,604.537,254.816,580.7,250.455Zm-95.928,60.787a8.211,8.211,0,0,0-9.521-5.938,23.168,23.168,0,0,1-4.155.387c-7.849,0-12.5-6.106-12.5-14.245V240.28h20.349a8.143,8.143,0,0,0,8.141-8.143V209.466a8.143,8.143,0,0,0-8.141-8.143H458.594V171.091a8.143,8.143,0,0,0-8.143-8.143H422.257a8.143,8.143,0,0,0-8.143,8.143h0v30.232H399a8.143,8.143,0,0,0-8.143,8.143h0v22.671A8.143,8.143,0,0,0,399,240.28h15.115v63.667c0,27.037,15.408,41.282,43.9,41.282,12.183,0,21.383-2.2,27.6-5.446a8.161,8.161,0,0,0,4.145-9.278Z" } }, "free": ["brands"] }, "bottle-droplet": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["alcohol", "drink", "oil", "olive oil", "wine"] }, "styles": ["solid"], "unicode": "e4c4", "label": "Bottle Droplet", "voted": false, "svg": { "solid": { "last_modified": 1684767418, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M96 0C82.7 0 72 10.7 72 24s10.7 24 24 24c4.4 0 8 3.6 8 8v64.9c0 12.2-7.2 23.1-17.2 30.1C53.7 174.1 32 212.5 32 256V448c0 35.3 28.7 64 64 64H224c35.3 0 64-28.7 64-64V256c0-43.5-21.7-81.9-54.8-105c-10-7-17.2-17.9-17.2-30.1V56c0-4.4 3.6-8 8-8c13.3 0 24-10.7 24-24s-10.7-24-24-24l-8 0 0 0 0 0H104l0 0 0 0L96 0zm64 382c-26.5 0-48-20.1-48-45c0-16.8 22.1-48.1 36.3-66.4c6-7.8 17.5-7.8 23.5 0C185.9 288.9 208 320.2 208 337c0 24.9-21.5 45-48 45z" } }, "free": ["solid"] }, "bottle-water": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["h2o", "plastic", "water"] }, "styles": ["solid"], "unicode": "e4c5", "label": "Bottle Water", "voted": false, "svg": { "solid": { "last_modified": 1684767420, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M120 0h80c13.3 0 24 10.7 24 24V64H96V24c0-13.3 10.7-24 24-24zM32 151.7c0-15.6 9-29.8 23.2-36.5l24.4-11.4c11-5.1 23-7.8 35.1-7.8h90.6c12.1 0 24.1 2.7 35.1 7.8l24.4 11.4c14.1 6.6 23.2 20.8 23.2 36.5c0 14.4-7.5 27-18.9 34.1c11.5 8.8 18.9 22.6 18.9 38.2c0 16.7-8.5 31.4-21.5 40c12.9 8.6 21.5 23.3 21.5 40s-8.5 31.4-21.5 40c12.9 8.6 21.5 23.3 21.5 40s-8.5 31.4-21.5 40c12.9 8.6 21.5 23.3 21.5 40c0 26.5-21.5 48-48 48H80c-26.5 0-48-21.5-48-48c0-16.7 8.5-31.4 21.5-40C40.5 415.4 32 400.7 32 384s8.5-31.4 21.5-40C40.5 335.4 32 320.7 32 304s8.5-31.4 21.5-40C40.5 255.4 32 240.7 32 224c0-15.6 7.4-29.4 18.9-38.2C39.5 178.7 32 166.1 32 151.7zM96 240c0 8.8 7.2 16 16 16h96c8.8 0 16-7.2 16-16s-7.2-16-16-16H112c-8.8 0-16 7.2-16 16zm16 112c-8.8 0-16 7.2-16 16s7.2 16 16 16h96c8.8 0 16-7.2 16-16s-7.2-16-16-16H112z" } }, "free": ["solid"] }, "bowl-food": { "changes": ["6.1.0", "6.1.2", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["catfood", "dogfood", "food", "rice"] }, "styles": ["solid"], "unicode": "e4c6", "label": "Bowl Food", "voted": false, "svg": { "solid": { "last_modified": 1684767420, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 192c0-35.3 28.7-64 64-64c.5 0 1.1 0 1.6 0C73 91.5 105.3 64 144 64c15 0 29 4.1 40.9 11.2C198.2 49.6 225.1 32 256 32s57.8 17.6 71.1 43.2C339 68.1 353 64 368 64c38.7 0 71 27.5 78.4 64c.5 0 1.1 0 1.6 0c35.3 0 64 28.7 64 64c0 11.7-3.1 22.6-8.6 32H8.6C3.1 214.6 0 203.7 0 192zm0 91.4C0 268.3 12.3 256 27.4 256H484.6c15.1 0 27.4 12.3 27.4 27.4c0 70.5-44.4 130.7-106.7 154.1L403.5 452c-2 16-15.6 28-31.8 28H140.2c-16.1 0-29.8-12-31.8-28l-1.8-14.4C44.4 414.1 0 353.9 0 283.4z" } }, "free": ["solid"] }, "bowl-rice": { "changes": ["6.0.0-beta1", "6.1.0", "6.1.2", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["boiled", "cooked", "cooked rice", "rice", "steamed"] }, "styles": ["solid"], "unicode": "e2eb", "label": "Bowl Rice", "voted": false, "svg": { "solid": { "last_modified": 1684767419, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M176 56c0-13.3 10.7-24 24-24h16c13.3 0 24 10.7 24 24s-10.7 24-24 24H200c-13.3 0-24-10.7-24-24zm24 48h16c13.3 0 24 10.7 24 24s-10.7 24-24 24H200c-13.3 0-24-10.7-24-24s10.7-24 24-24zM56 176H72c13.3 0 24 10.7 24 24s-10.7 24-24 24H56c-13.3 0-24-10.7-24-24s10.7-24 24-24zM0 283.4C0 268.3 12.3 256 27.4 256H484.6c15.1 0 27.4 12.3 27.4 27.4c0 70.5-44.4 130.7-106.7 154.1L403.5 452c-2 16-15.6 28-31.8 28H140.2c-16.1 0-29.8-12-31.8-28l-1.8-14.4C44.4 414.1 0 353.9 0 283.4zM224 200c0-13.3 10.7-24 24-24h16c13.3 0 24 10.7 24 24s-10.7 24-24 24H248c-13.3 0-24-10.7-24-24zm-96 0c0-13.3 10.7-24 24-24h16c13.3 0 24 10.7 24 24s-10.7 24-24 24H152c-13.3 0-24-10.7-24-24zm-24-96h16c13.3 0 24 10.7 24 24s-10.7 24-24 24H104c-13.3 0-24-10.7-24-24s10.7-24 24-24zm216 96c0-13.3 10.7-24 24-24h16c13.3 0 24 10.7 24 24s-10.7 24-24 24H344c-13.3 0-24-10.7-24-24zm-24-96h16c13.3 0 24 10.7 24 24s-10.7 24-24 24H296c-13.3 0-24-10.7-24-24s10.7-24 24-24zm120 96c0-13.3 10.7-24 24-24h16c13.3 0 24 10.7 24 24s-10.7 24-24 24H440c-13.3 0-24-10.7-24-24zm-24-96h16c13.3 0 24 10.7 24 24s-10.7 24-24 24H392c-13.3 0-24-10.7-24-24s10.7-24 24-24zM296 32h16c13.3 0 24 10.7 24 24s-10.7 24-24 24H296c-13.3 0-24-10.7-24-24s10.7-24 24-24z" } }, "free": ["solid"] }, "bowling-ball": { "aliases": { "unicodes": { "secondary": ["10f436"] } }, "changes": [ "5.0.5", "5.11.0", "5.11.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["alley", "candlepin", "gutter", "lane", "strike", "tenpin"] }, "styles": ["solid"], "unicode": "f436", "label": "Bowling Ball", "voted": false, "svg": { "solid": { "last_modified": 1684767070, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM240 80a32 32 0 1 1 0 64 32 32 0 1 1 0-64zM208 208a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm-64-64a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" } }, "free": ["solid"] }, "box": { "aliases": { "unicodes": { "composite": ["1f4e6"], "secondary": ["10f466"] } }, "changes": [ "5.0.7", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["archive", "box", "container", "package", "parcel", "storage"] }, "styles": ["solid"], "unicode": "f466", "label": "Box", "voted": false, "svg": { "solid": { "last_modified": 1684766476, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M50.7 58.5L0 160H208V32H93.7C75.5 32 58.9 42.3 50.7 58.5zM240 160H448L397.3 58.5C389.1 42.3 372.5 32 354.3 32H240V160zm208 32H0V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V192z" } }, "free": ["solid"] }, "box-archive": { "aliases": { "names": ["archive"], "unicodes": { "secondary": ["10f187"] } }, "changes": [ "3.2.0", "5.0.0", "5.0.9", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["box", "package", "save", "storage"] }, "styles": ["solid"], "unicode": "f187", "label": "Box Archive", "voted": false, "svg": { "solid": { "last_modified": 1684767393, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M32 32H480c17.7 0 32 14.3 32 32V96c0 17.7-14.3 32-32 32H32C14.3 128 0 113.7 0 96V64C0 46.3 14.3 32 32 32zm0 128H480V416c0 35.3-28.7 64-64 64H96c-35.3 0-64-28.7-64-64V160zm128 80c0 8.8 7.2 16 16 16H336c8.8 0 16-7.2 16-16s-7.2-16-16-16H176c-8.8 0-16 7.2-16 16z" } }, "free": ["solid"] }, "box-open": { "aliases": { "unicodes": { "secondary": ["10f49e"] } }, "changes": [ "5.0.9", "5.7.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["archive", "container", "package", "storage", "unpack"] }, "styles": ["solid"], "unicode": "f49e", "label": "Box Open", "voted": false, "svg": { "solid": { "last_modified": 1684766476, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M58.9 42.1c3-6.1 9.6-9.6 16.3-8.7L320 64 564.8 33.4c6.7-.8 13.3 2.7 16.3 8.7l41.7 83.4c9 17.9-.6 39.6-19.8 45.1L439.6 217.3c-13.9 4-28.8-1.9-36.2-14.3L320 64 236.6 203c-7.4 12.4-22.3 18.3-36.2 14.3L37.1 170.6c-19.3-5.5-28.8-27.2-19.8-45.1L58.9 42.1zM321.1 128l54.9 91.4c14.9 24.8 44.6 36.6 72.5 28.6L576 211.6v167c0 22-15 41.2-36.4 46.6l-204.1 51c-10.2 2.6-20.9 2.6-31 0l-204.1-51C79 419.7 64 400.5 64 378.5v-167L191.6 248c27.8 8 57.6-3.8 72.5-28.6L318.9 128h2.2z" } }, "free": ["solid"] }, "box-tissue": { "aliases": { "unicodes": { "secondary": ["10e05b"] } }, "changes": ["5.13.0", "5.14.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "cough", "covid-19", "kleenex", "mucus", "nose", "sneeze", "snot" ] }, "styles": ["solid"], "unicode": "e05b", "label": "Box Tissue", "voted": false, "svg": { "solid": { "last_modified": 1684767444, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M92.5 0H208c40 0 52 24 64 48s24 48 64 48h85.2C436 96 448 108 448 122.8c0 3.4-.7 6.8-1.9 10L409.6 224 384 288H128l-16-64L64.9 35.4c-.6-2.3-.9-4.6-.9-6.9C64 12.8 76.8 0 92.5 0zM79 224l16 64H80c-8.8 0-16 7.2-16 16s7.2 16 16 16h48H384h48c8.8 0 16-7.2 16-16s-7.2-16-16-16H418.5l25.6-64H464c26.5 0 48 21.5 48 48V384H0V272c0-26.5 21.5-48 48-48H79zM0 416H512v48c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V416z" } }, "free": ["solid"] }, "boxes-packing": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["archive", "box", "package", "storage", "supplies"] }, "styles": ["solid"], "unicode": "e4c7", "label": "Boxes Packing", "voted": false, "svg": { "solid": { "last_modified": 1684766476, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M256 48c0-26.5 21.5-48 48-48H592c26.5 0 48 21.5 48 48V464c0 26.5-21.5 48-48 48H381.3c1.8-5 2.7-10.4 2.7-16V253.3c18.6-6.6 32-24.4 32-45.3V176c0-26.5-21.5-48-48-48H256V48zM571.3 347.3c6.2-6.2 6.2-16.4 0-22.6l-64-64c-6.2-6.2-16.4-6.2-22.6 0l-64 64c-6.2 6.2-6.2 16.4 0 22.6s16.4 6.2 22.6 0L480 310.6V432c0 8.8 7.2 16 16 16s16-7.2 16-16V310.6l36.7 36.7c6.2 6.2 16.4 6.2 22.6 0zM0 176c0-8.8 7.2-16 16-16H368c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H16c-8.8 0-16-7.2-16-16V176zm352 80V480c0 17.7-14.3 32-32 32H64c-17.7 0-32-14.3-32-32V256H352zM144 320c-8.8 0-16 7.2-16 16s7.2 16 16 16h96c8.8 0 16-7.2 16-16s-7.2-16-16-16H144z" } }, "free": ["solid"] }, "boxes-stacked": { "aliases": { "names": ["boxes", "boxes-alt"], "unicodes": { "composite": ["f4a1"], "primary": ["f4a1"], "secondary": ["10f468", "10f4a1"] } }, "changes": [ "5.0.7", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.2.1", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["archives", "inventory", "storage", "warehouse"] }, "styles": ["solid"], "unicode": "f468", "label": "Boxes Stacked", "voted": false, "svg": { "solid": { "last_modified": 1684766475, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M248 0H208c-26.5 0-48 21.5-48 48V160c0 35.3 28.7 64 64 64H352c35.3 0 64-28.7 64-64V48c0-26.5-21.5-48-48-48H328V80c0 8.8-7.2 16-16 16H264c-8.8 0-16-7.2-16-16V0zM64 256c-35.3 0-64 28.7-64 64V448c0 35.3 28.7 64 64 64H224c35.3 0 64-28.7 64-64V320c0-35.3-28.7-64-64-64H184v80c0 8.8-7.2 16-16 16H120c-8.8 0-16-7.2-16-16V256H64zM352 512H512c35.3 0 64-28.7 64-64V320c0-35.3-28.7-64-64-64H472v80c0 8.8-7.2 16-16 16H408c-8.8 0-16-7.2-16-16V256H352c-15 0-28.8 5.1-39.7 13.8c4.9 10.4 7.7 22 7.7 34.2V464c0 12.2-2.8 23.8-7.7 34.2C323.2 506.9 337 512 352 512z" } }, "free": ["solid"] }, "braille": { "aliases": { "unicodes": { "secondary": ["10f2a1"] } }, "changes": [ "4.6.0", "5.0.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["alphabet", "blind", "dots", "raised", "vision"] }, "styles": ["solid"], "unicode": "f2a1", "label": "Braille", "voted": false, "svg": { "solid": { "last_modified": 1684767551, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M0 96a64 64 0 1 1 128 0A64 64 0 1 1 0 96zM224 272a16 16 0 1 0 0-32 16 16 0 1 0 0 32zm0-80a64 64 0 1 1 0 128 64 64 0 1 1 0-128zM80 416a16 16 0 1 0 -32 0 16 16 0 1 0 32 0zM0 416a64 64 0 1 1 128 0A64 64 0 1 1 0 416zm240 0a16 16 0 1 0 -32 0 16 16 0 1 0 32 0zm-80 0a64 64 0 1 1 128 0 64 64 0 1 1 -128 0zM64 192a64 64 0 1 1 0 128 64 64 0 1 1 0-128zM224 32a64 64 0 1 1 0 128 64 64 0 1 1 0-128zM352 96a64 64 0 1 1 128 0A64 64 0 1 1 352 96zm240 0a16 16 0 1 0 -32 0 16 16 0 1 0 32 0zm-80 0a64 64 0 1 1 128 0A64 64 0 1 1 512 96zm64 176a16 16 0 1 0 0-32 16 16 0 1 0 0 32zm0-80a64 64 0 1 1 0 128 64 64 0 1 1 0-128zm16 224a16 16 0 1 0 -32 0 16 16 0 1 0 32 0zm-80 0a64 64 0 1 1 128 0 64 64 0 1 1 -128 0zM416 272a16 16 0 1 0 0-32 16 16 0 1 0 0 32zm0-80a64 64 0 1 1 0 128 64 64 0 1 1 0-128zm16 224a16 16 0 1 0 -32 0 16 16 0 1 0 32 0zm-80 0a64 64 0 1 1 128 0 64 64 0 1 1 -128 0z" } }, "free": ["solid"] }, "brain": { "aliases": { "unicodes": { "composite": ["1f9e0"], "secondary": ["10f5dc"] } }, "changes": [ "5.2.0", "5.9.0", "5.11.0", "6.0.0-beta1", "6.0.0-beta2", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "brain", "cerebellum", "gray matter", "intellect", "intelligent", "medulla oblongata", "mind", "noodle", "wit" ] }, "styles": ["solid"], "unicode": "f5dc", "label": "Brain", "voted": false, "svg": { "solid": { "last_modified": 1684766749, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M184 0c30.9 0 56 25.1 56 56V456c0 30.9-25.1 56-56 56c-28.9 0-52.7-21.9-55.7-50.1c-5.2 1.4-10.7 2.1-16.3 2.1c-35.3 0-64-28.7-64-64c0-7.4 1.3-14.6 3.6-21.2C21.4 367.4 0 338.2 0 304c0-31.9 18.7-59.5 45.8-72.3C37.1 220.8 32 207 32 192c0-30.7 21.6-56.3 50.4-62.6C80.8 123.9 80 118 80 112c0-29.9 20.6-55.1 48.3-62.1C131.3 21.9 155.1 0 184 0zM328 0c28.9 0 52.6 21.9 55.7 49.9c27.8 7 48.3 32.1 48.3 62.1c0 6-.8 11.9-2.4 17.4c28.8 6.2 50.4 31.9 50.4 62.6c0 15-5.1 28.8-13.8 39.7C493.3 244.5 512 272.1 512 304c0 34.2-21.4 63.4-51.6 74.8c2.3 6.6 3.6 13.8 3.6 21.2c0 35.3-28.7 64-64 64c-5.6 0-11.1-.7-16.3-2.1c-3 28.2-26.8 50.1-55.7 50.1c-30.9 0-56-25.1-56-56V56c0-30.9 25.1-56 56-56z" } }, "free": ["solid"] }, "brazilian-real-sign": { "changes": ["6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["brazilian real sign", "currency"] }, "styles": ["solid"], "unicode": "e46c", "label": "Brazilian Real Sign", "voted": false, "svg": { "solid": { "last_modified": 1684766475, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M400 0c17.7 0 32 14.3 32 32V50.2c12.5 2.3 24.7 6.4 36.2 12.1l10.1 5.1c15.8 7.9 22.2 27.1 14.3 42.9s-27.1 22.2-42.9 14.3l-10.2-5.1c-9.9-5-20.9-7.5-32-7.5h-1.7c-29.8 0-53.9 24.1-53.9 53.9c0 22 13.4 41.8 33.9 50l52 20.8c44.7 17.9 74.1 61.2 74.1 109.4v3.4c0 51.2-33.6 94.6-80 109.2V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V460.6c-15-3.5-29.4-9.7-42.3-18.3l-23.4-15.6c-14.7-9.8-18.7-29.7-8.9-44.4s29.7-18.7 44.4-8.9L361.2 389c10.8 7.2 23.4 11 36.3 11c27.9 0 50.5-22.6 50.5-50.5v-3.4c0-22-13.4-41.8-33.9-50l-52-20.8C317.3 257.4 288 214.1 288 165.9C288 114 321.5 70 368 54.2V32c0-17.7 14.3-32 32-32zM0 64C0 46.3 14.3 32 32 32h80c79.5 0 144 64.5 144 144c0 58.8-35.2 109.3-85.7 131.7l51.4 128.4c6.6 16.4-1.4 35-17.8 41.6s-35-1.4-41.6-17.8L106.3 320H64V448c0 17.7-14.3 32-32 32s-32-14.3-32-32V288 64zM64 256h48c44.2 0 80-35.8 80-80s-35.8-80-80-80H64V256z" } }, "free": ["solid"] }, "bread-slice": { "aliases": { "unicodes": { "secondary": ["10f7ec"] } }, "changes": ["5.7.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "bake", "bakery", "baking", "dough", "flour", "gluten", "grain", "sandwich", "sourdough", "toast", "wheat", "yeast" ] }, "styles": ["solid"], "unicode": "f7ec", "label": "Bread Slice", "voted": false, "svg": { "solid": { "last_modified": 1684767420, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 32C192 32 0 64 0 192c0 35.3 28.7 64 64 64V432c0 26.5 21.5 48 48 48H400c26.5 0 48-21.5 48-48V256c35.3 0 64-28.7 64-64C512 64 320 32 256 32z" } }, "free": ["solid"] }, "bridge": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["bridge", "road"] }, "styles": ["solid"], "unicode": "e4c8", "label": "Bridge", "voted": false, "svg": { "solid": { "last_modified": 1684767489, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M32 32C14.3 32 0 46.3 0 64S14.3 96 32 96H72v64H0V288c53 0 96 43 96 96v64c0 17.7 14.3 32 32 32h32c17.7 0 32-14.3 32-32V384c0-53 43-96 96-96s96 43 96 96v64c0 17.7 14.3 32 32 32h32c17.7 0 32-14.3 32-32V384c0-53 43-96 96-96V160H504V96h40c17.7 0 32-14.3 32-32s-14.3-32-32-32H32zM456 96v64H376V96h80zM328 96v64H248V96h80zM200 96v64H120V96h80z" } }, "free": ["solid"] }, "bridge-circle-check": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["bridge", "not affected", "ok", "okay", "road"] }, "styles": ["solid"], "unicode": "e4c9", "label": "Bridge Circle Check", "voted": false, "svg": { "solid": { "last_modified": 1684767489, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M64 32C46.3 32 32 46.3 32 64s14.3 32 32 32h40v64H32V288c53 0 96 43 96 96v64c0 17.7 14.3 32 32 32h32c17.7 0 32-14.3 32-32V384c0-53 43-96 96-96c6.3 0 12.4 .6 18.3 1.7C367.1 231.8 426.9 192 496 192c42.5 0 81.6 15.1 112 40.2V160H536V96h40c17.7 0 32-14.3 32-32s-14.3-32-32-32H64zM488 96v64H408V96h80zM360 96v64H280V96h80zM232 96v64H152V96h80zM640 368a144 144 0 1 0 -288 0 144 144 0 1 0 288 0zm-76.7-43.3c6.2 6.2 6.2 16.4 0 22.6l-72 72c-6.2 6.2-16.4 6.2-22.6 0l-40-40c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0L480 385.4l60.7-60.7c6.2-6.2 16.4-6.2 22.6 0z" } }, "free": ["solid"] }, "bridge-circle-exclamation": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["affected", "bridge", "road"] }, "styles": ["solid"], "unicode": "e4ca", "label": "Bridge Circle Exclamation", "voted": false, "svg": { "solid": { "last_modified": 1684767489, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M64 32C46.3 32 32 46.3 32 64s14.3 32 32 32h40v64H32V288c53 0 96 43 96 96v64c0 17.7 14.3 32 32 32h32c17.7 0 32-14.3 32-32V384c0-53 43-96 96-96c6.3 0 12.4 .6 18.3 1.7C367.1 231.8 426.9 192 496 192c42.5 0 81.6 15.1 112 40.2V160H536V96h40c17.7 0 32-14.3 32-32s-14.3-32-32-32H64zM488 96v64H408V96h80zM360 96v64H280V96h80zM232 96v64H152V96h80zM496 512a144 144 0 1 0 0-288 144 144 0 1 0 0 288zm0-96a24 24 0 1 1 0 48 24 24 0 1 1 0-48zm0-144c8.8 0 16 7.2 16 16v80c0 8.8-7.2 16-16 16s-16-7.2-16-16V288c0-8.8 7.2-16 16-16z" } }, "free": ["solid"] }, "bridge-circle-xmark": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["bridge", "destroy", "road"] }, "styles": ["solid"], "unicode": "e4cb", "label": "Bridge Circle Xmark", "voted": false, "svg": { "solid": { "last_modified": 1684767489, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M64 32C46.3 32 32 46.3 32 64s14.3 32 32 32h40v64H32V288c53 0 96 43 96 96v64c0 17.7 14.3 32 32 32h32c17.7 0 32-14.3 32-32V384c0-53 43-96 96-96c6.3 0 12.4 .6 18.3 1.7C367.1 231.8 426.9 192 496 192c42.5 0 81.6 15.1 112 40.2V160H536V96h40c17.7 0 32-14.3 32-32s-14.3-32-32-32H64zM488 96v64H408V96h80zM360 96v64H280V96h80zM232 96v64H152V96h80zM496 512a144 144 0 1 0 0-288 144 144 0 1 0 0 288zm59.3-180.7L518.6 368l36.7 36.7c6.2 6.2 6.2 16.4 0 22.6s-16.4 6.2-22.6 0L496 390.6l-36.7 36.7c-6.2 6.2-16.4 6.2-22.6 0s-6.2-16.4 0-22.6L473.4 368l-36.7-36.7c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0L496 345.4l36.7-36.7c6.2-6.2 16.4-6.2 22.6 0s6.2 16.4 0 22.6z" } }, "free": ["solid"] }, "bridge-lock": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["bridge", "closed", "lockdown", "quarantine", "road"] }, "styles": ["solid"], "unicode": "e4cc", "label": "Bridge Lock", "voted": false, "svg": { "solid": { "last_modified": 1684767489, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M32 64c0-17.7 14.3-32 32-32H576c17.7 0 32 14.3 32 32s-14.3 32-32 32H536v64h-8c-61.9 0-112 50.1-112 112v24.6c-9.9 5.8-18.2 14.1-23.8 24.1c-17.6-20-43.4-32.7-72.2-32.7c-53 0-96 43-96 96v64c0 17.7-14.3 32-32 32H160c-17.7 0-32-14.3-32-32V384c0-53-43-96-96-96V160h72V96H64C46.3 96 32 81.7 32 64zM408 96v64h80V96H408zm-48 64V96H280v64h80zM152 96v64h80V96H152zM528 240c-17.7 0-32 14.3-32 32v48h64V272c0-17.7-14.3-32-32-32zm-80 32c0-44.2 35.8-80 80-80s80 35.8 80 80v48c17.7 0 32 14.3 32 32V480c0 17.7-14.3 32-32 32H448c-17.7 0-32-14.3-32-32V352c0-17.7 14.3-32 32-32V272z" } }, "free": ["solid"] }, "bridge-water": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["bridge", "road"] }, "styles": ["solid"], "unicode": "e4ce", "label": "Bridge Water", "voted": false, "svg": { "solid": { "last_modified": 1684767489, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M0 96C0 78.3 14.3 64 32 64H544c17.7 0 32 14.3 32 32v35.6c0 15.7-12.7 28.4-28.4 28.4c-37.3 0-67.6 30.2-67.6 67.6V352.5c-12.9 0-25.8 3.9-36.8 11.7c-18 12.4-40.1 20.3-59.2 20.3h0l0-.5V256c0-53-43-96-96-96s-96 43-96 96V384l0 .5c-19 0-41.2-7.9-59.1-20.3c-11.1-7.8-24-11.7-36.9-11.7V227.6C96 190.2 65.8 160 28.4 160C12.7 160 0 147.3 0 131.6V96zM306.5 389.9C329 405.4 356.5 416 384 416c26.9 0 55.4-10.8 77.4-26.1l0 0c11.9-8.5 28.1-7.8 39.2 1.7c14.4 11.9 32.5 21 50.6 25.2c17.2 4 27.9 21.2 23.9 38.4s-21.2 27.9-38.4 23.9c-24.5-5.7-44.9-16.5-58.2-25C449.5 469.7 417 480 384 480c-31.9 0-60.6-9.9-80.4-18.9c-5.8-2.7-11.1-5.3-15.6-7.7c-4.5 2.4-9.7 5.1-15.6 7.7c-19.8 9-48.5 18.9-80.4 18.9c-33 0-65.5-10.3-94.5-25.8c-13.4 8.4-33.7 19.3-58.2 25c-17.2 4-34.4-6.7-38.4-23.9s6.7-34.4 23.9-38.4c18.1-4.2 36.2-13.3 50.6-25.2c11.1-9.4 27.3-10.1 39.2-1.7l0 0C136.7 405.2 165.1 416 192 416c27.5 0 55-10.6 77.5-26.1c11.1-7.9 25.9-7.9 37 0z" } }, "free": ["solid"] }, "briefcase": { "aliases": { "unicodes": { "composite": ["1f4bc"], "secondary": ["10f0b1"] } }, "changes": [ "2.0.0", "5.0.0", "5.3.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "bag", "briefcas", "briefcase", "business", "luggage", "office", "work" ] }, "styles": ["solid"], "unicode": "f0b1", "label": "Briefcase", "voted": false, "svg": { "solid": { "last_modified": 1684767441, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M184 48H328c4.4 0 8 3.6 8 8V96H176V56c0-4.4 3.6-8 8-8zm-56 8V96H64C28.7 96 0 124.7 0 160v96H192 320 512V160c0-35.3-28.7-64-64-64H384V56c0-30.9-25.1-56-56-56H184c-30.9 0-56 25.1-56 56zM512 288H320v32c0 17.7-14.3 32-32 32H224c-17.7 0-32-14.3-32-32V288H0V416c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V288z" } }, "free": ["solid"] }, "briefcase-medical": { "aliases": { "unicodes": { "secondary": ["10f469"] } }, "changes": ["5.0.7", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["doctor", "emt", "first aid", "health"] }, "styles": ["solid"], "unicode": "f469", "label": "Briefcase Medical", "voted": false, "svg": { "solid": { "last_modified": 1684767441, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M184 48H328c4.4 0 8 3.6 8 8V96H176V56c0-4.4 3.6-8 8-8zm-56 8V96H64C28.7 96 0 124.7 0 160V416c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V160c0-35.3-28.7-64-64-64H384V56c0-30.9-25.1-56-56-56H184c-30.9 0-56 25.1-56 56zm96 152c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v48h48c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H288v48c0 8.8-7.2 16-16 16H240c-8.8 0-16-7.2-16-16V320H176c-8.8 0-16-7.2-16-16V272c0-8.8 7.2-16 16-16h48V208z" } }, "free": ["solid"] }, "broom": { "aliases": { "unicodes": { "composite": ["1f9f9"], "secondary": ["10f51a"] } }, "changes": ["5.0.13", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "broom", "clean", "cleaning", "firebolt", "fly", "halloween", "nimbus 2000", "quidditch", "sweep", "sweeping", "witch" ] }, "styles": ["solid"], "unicode": "f51a", "label": "Broom", "voted": true, "svg": { "solid": { "last_modified": 1684767601, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M566.6 54.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-192 192-34.7-34.7c-4.2-4.2-10-6.6-16-6.6c-12.5 0-22.6 10.1-22.6 22.6v29.1L364.3 320h29.1c12.5 0 22.6-10.1 22.6-22.6c0-6-2.4-11.8-6.6-16l-34.7-34.7 192-192zM341.1 353.4L222.6 234.9c-42.7-3.7-85.2 11.7-115.8 42.3l-8 8C76.5 307.5 64 337.7 64 369.2c0 6.8 7.1 11.2 13.2 8.2l51.1-25.5c5-2.5 9.5 4.1 5.4 7.9L7.3 473.4C2.7 477.6 0 483.6 0 489.9C0 502.1 9.9 512 22.1 512l173.3 0c38.8 0 75.9-15.4 103.4-42.8c30.6-30.6 45.9-73.1 42.3-115.8z" } }, "free": ["solid"] }, "broom-ball": { "aliases": { "names": ["quidditch", "quidditch-broom-ball"], "unicodes": { "secondary": ["10f458"] } }, "changes": ["5.0.5", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "ball", "bludger", "broom", "golden snitch", "harry potter", "hogwarts", "quaffle", "sport", "wizard" ] }, "styles": ["solid"], "unicode": "f458", "label": "Broom Ball", "voted": false, "svg": { "solid": { "last_modified": 1684767071, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M566.6 9.4c12.5 12.5 12.5 32.8 0 45.3l-192 192 34.7 34.7c4.2 4.2 6.6 10 6.6 16c0 12.5-10.1 22.6-22.6 22.6H364.3L256 211.7V182.6c0-12.5 10.1-22.6 22.6-22.6c6 0 11.8 2.4 16 6.6l34.7 34.7 192-192c12.5-12.5 32.8-12.5 45.3 0zm-344 225.5L341.1 353.4c3.7 42.7-11.7 85.2-42.3 115.8C271.4 496.6 234.2 512 195.5 512L22.1 512C9.9 512 0 502.1 0 489.9c0-6.3 2.7-12.3 7.3-16.5L133.7 359.7c4.2-3.7-.4-10.4-5.4-7.9L77.2 377.4c-6.1 3-13.2-1.4-13.2-8.2c0-31.5 12.5-61.7 34.8-84l8-8c30.6-30.6 73.1-45.9 115.8-42.3zM464 352a80 80 0 1 1 0 160 80 80 0 1 1 0-160z" } }, "free": ["solid"] }, "brush": { "aliases": { "unicodes": { "secondary": ["10f55d"] } }, "changes": ["5.1.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["art", "bristles", "color", "handle", "paint"] }, "styles": ["solid"], "unicode": "f55d", "label": "Brush", "voted": false, "svg": { "solid": { "last_modified": 1684767366, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M162.4 6c-1.5-3.6-5-6-8.9-6h-19c-3.9 0-7.5 2.4-8.9 6L104.9 57.7c-3.2 8-14.6 8-17.8 0L66.4 6c-1.5-3.6-5-6-8.9-6H48C21.5 0 0 21.5 0 48V224v22.4V256H9.6 374.4 384v-9.6V224 48c0-26.5-21.5-48-48-48H230.5c-3.9 0-7.5 2.4-8.9 6L200.9 57.7c-3.2 8-14.6 8-17.8 0L162.4 6zM0 288v32c0 35.3 28.7 64 64 64h64v64c0 35.3 28.7 64 64 64s64-28.7 64-64V384h64c35.3 0 64-28.7 64-64V288H0zM192 432a16 16 0 1 1 0 32 16 16 0 1 1 0-32z" } }, "free": ["solid"] }, "btc": { "changes": ["3.2.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f15a", "label": "BTC", "voted": false, "svg": { "brands": { "last_modified": 1660014461, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M310.204 242.638c27.73-14.18 45.377-39.39 41.28-81.3-5.358-57.351-52.458-76.573-114.85-81.929V0h-48.528v77.203c-12.605 0-25.525.315-38.444.63V0h-48.528v79.409c-17.842.539-38.622.276-97.37 0v51.678c38.314-.678 58.417-3.14 63.023 21.427v217.429c-2.925 19.492-18.524 16.685-53.255 16.071L3.765 443.68c88.481 0 97.37.315 97.37.315V512h48.528v-67.06c13.234.315 26.154.315 38.444.315V512h48.528v-68.005c81.299-4.412 135.647-24.894 142.895-101.467 5.671-61.446-23.32-88.862-69.326-99.89zM150.608 134.553c27.415 0 113.126-8.507 113.126 48.528 0 54.515-85.71 48.212-113.126 48.212v-96.74zm0 251.776V279.821c32.772 0 133.127-9.138 133.127 53.255-.001 60.186-100.355 53.253-133.127 53.253z" } }, "free": ["brands"] }, "bucket": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["bucket", "pail", "sandcastle"] }, "styles": ["solid"], "unicode": "e4cf", "label": "Bucket", "voted": false, "svg": { "solid": { "last_modified": 1684767071, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M96 152v8H48v-8C48 68.1 116.1 0 200 0h48c83.9 0 152 68.1 152 152v8H352v-8c0-57.4-46.6-104-104-104H200C142.6 48 96 94.6 96 152zM0 224c0-17.7 14.3-32 32-32H416c17.7 0 32 14.3 32 32s-14.3 32-32 32h-5.1L388.5 469c-2.6 24.4-23.2 43-47.7 43H107.2c-24.6 0-45.2-18.5-47.7-43L37.1 256H32c-17.7 0-32-14.3-32-32z" } }, "free": ["solid"] }, "buffer": { "changes": ["5.8.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f837", "label": "Buffer", "voted": false, "svg": { "brands": { "last_modified": 1660014461, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M427.84 380.67l-196.5 97.82a18.6 18.6 0 0 1-14.67 0L20.16 380.67c-4-2-4-5.28 0-7.29L67.22 350a18.65 18.65 0 0 1 14.69 0l134.76 67a18.51 18.51 0 0 0 14.67 0l134.76-67a18.62 18.62 0 0 1 14.68 0l47.06 23.43c4.05 1.96 4.05 5.24 0 7.24zm0-136.53l-47.06-23.43a18.62 18.62 0 0 0-14.68 0l-134.76 67.08a18.68 18.68 0 0 1-14.67 0L81.91 220.71a18.65 18.65 0 0 0-14.69 0l-47.06 23.43c-4 2-4 5.29 0 7.31l196.51 97.8a18.6 18.6 0 0 0 14.67 0l196.5-97.8c4.05-2.02 4.05-5.3 0-7.31zM20.16 130.42l196.5 90.29a20.08 20.08 0 0 0 14.67 0l196.51-90.29c4-1.86 4-4.89 0-6.74L231.33 33.4a19.88 19.88 0 0 0-14.67 0l-196.5 90.28c-4.05 1.85-4.05 4.88 0 6.74z" } }, "free": ["brands"] }, "bug": { "aliases": { "unicodes": { "secondary": ["10f188"] } }, "changes": [ "3.2.0", "5.0.0", "5.15.4", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["beetle", "error", "glitch", "insect", "repair", "report"] }, "styles": ["solid"], "unicode": "f188", "label": "Bug", "voted": false, "svg": { "solid": { "last_modified": 1684767367, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 0c53 0 96 43 96 96v3.6c0 15.7-12.7 28.4-28.4 28.4H188.4c-15.7 0-28.4-12.7-28.4-28.4V96c0-53 43-96 96-96zM41.4 105.4c12.5-12.5 32.8-12.5 45.3 0l64 64c.7 .7 1.3 1.4 1.9 2.1c14.2-7.3 30.4-11.4 47.5-11.4H312c17.1 0 33.2 4.1 47.5 11.4c.6-.7 1.2-1.4 1.9-2.1l64-64c12.5-12.5 32.8-12.5 45.3 0s12.5 32.8 0 45.3l-64 64c-.7 .7-1.4 1.3-2.1 1.9c6.2 12 10.1 25.3 11.1 39.5H480c17.7 0 32 14.3 32 32s-14.3 32-32 32H416c0 24.6-5.5 47.8-15.4 68.6c2.2 1.3 4.2 2.9 6 4.8l64 64c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0l-63.1-63.1c-24.5 21.8-55.8 36.2-90.3 39.6V240c0-8.8-7.2-16-16-16s-16 7.2-16 16V479.2c-34.5-3.4-65.8-17.8-90.3-39.6L86.6 502.6c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3l64-64c1.9-1.9 3.9-3.4 6-4.8C101.5 367.8 96 344.6 96 320H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H96.3c1.1-14.1 5-27.5 11.1-39.5c-.7-.6-1.4-1.2-2.1-1.9l-64-64c-12.5-12.5-12.5-32.8 0-45.3z" } }, "free": ["solid"] }, "bug-slash": { "changes": ["6.0.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "beetle", "fix", "glitch", "insect", "optimize", "repair", "report", "warning" ] }, "styles": ["solid"], "unicode": "e490", "label": "Bug Slash", "voted": false, "svg": { "solid": { "last_modified": 1684767366, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7L477.4 348.9c1.7-9.4 2.6-19 2.6-28.9h64c17.7 0 32-14.3 32-32s-14.3-32-32-32H479.7c-1.1-14.1-5-27.5-11.1-39.5c.7-.6 1.4-1.2 2.1-1.9l64-64c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-64 64c-.7 .7-1.3 1.4-1.9 2.1C409.2 164.1 393.1 160 376 160H264c-8.3 0-16.3 1-24 2.8L38.8 5.1zM320 0c-53 0-96 43-96 96v3.6c0 15.7 12.7 28.4 28.4 28.4H387.6c15.7 0 28.4-12.7 28.4-28.4V96c0-53-43-96-96-96zM160.3 256H96c-17.7 0-32 14.3-32 32s14.3 32 32 32h64c0 24.6 5.5 47.8 15.4 68.6c-2.2 1.3-4.2 2.9-6 4.8l-64 64c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l63.1-63.1c24.5 21.8 55.8 36.2 90.3 39.6V335.5L166.7 227.3c-3.4 9-5.6 18.7-6.4 28.7zM336 479.2c36.6-3.6 69.7-19.6 94.8-43.8L336 360.7V479.2z" } }, "free": ["solid"] }, "bugs": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["bedbug", "infestation", "lice", "plague", "ticks"] }, "styles": ["solid"], "unicode": "e4d0", "label": "Bugs", "voted": false, "svg": { "solid": { "last_modified": 1684768130, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M164.5 107.4l33.4-73.5c5.5-12.1 .1-26.3-11.9-31.8s-26.3-.1-31.8 11.9L128 71.7 101.9 14.1C96.4 2 82.1-3.3 70.1 2.1S52.7 21.9 58.1 33.9l33.4 73.5c-10.2 7.1-18.2 17-22.9 28.6h-17l-4.1-20.7c-2.6-13-15.2-21.4-28.2-18.8S-2.1 111.7 .5 124.7l8 40C10.7 175.9 20.6 184 32 184H64v23.3l-37.8 9.5c-9.5 2.4-16.6 10.2-17.9 19.9l-8 56c-1.9 13.1 7.2 25.3 20.4 27.2s25.3-7.2 27.2-20.4l5.7-40 18.4-4.6C82.7 274.6 103.8 288 128 288s45.3-13.4 56.1-33.2l18.4 4.6 5.7 40c1.9 13.1 14 22.2 27.2 20.4s22.2-14 20.4-27.2l-8-56c-1.4-9.7-8.5-17.5-17.9-19.9L192 207.3V184h32c11.4 0 21.3-8.1 23.5-19.3l8-40c2.6-13-5.8-25.6-18.8-28.2s-25.6 5.8-28.2 18.8L204.3 136h-17c-4.7-11.6-12.7-21.5-22.9-28.6zM496 286.5l65.6-47c10.8-7.7 13.3-22.7 5.6-33.5s-22.7-13.3-33.5-5.6l-51.4 36.8 6.1-62.9c1.3-13.2-8.4-24.9-21.6-26.2s-24.9 8.4-26.2 21.6L432.8 250c-12.3 1-24.2 5.6-34.1 13.3L384 254.8l6.8-20c4.2-12.6-2.5-26.2-15-30.4s-26.2 2.5-30.4 15l-13.1 38.6c-3.7 10.8 .8 22.8 10.7 28.5l27.7 16L359 322.7 321.5 312c-9.4-2.7-19.5 .6-25.5 8.3l-34.9 44.5c-8.2 10.4-6.4 25.5 4.1 33.7s25.5 6.4 33.7-4.1l25-31.8 18.2 5.2c-.5 22.6 11 44.7 32 56.8s45.9 11 65.2-.7l13.6 13.2-15.1 37.5c-4.9 12.3 1 26.3 13.3 31.2s26.3-1 31.2-13.3L503.5 440c3.6-9.1 1.4-19.4-5.6-26.2l-28-27.1 11.6-20.1 27.7 16c9.9 5.7 22.5 3.7 30-4.9L566.2 347c8.7-10 7.8-25.1-2.2-33.9s-25.1-7.8-33.9 2.2l-13.9 15.9-14.7-8.5c1.7-12.4-.2-25-5.5-36.2z" } }, "free": ["solid"] }, "building": { "aliases": { "unicodes": { "composite": ["1f3e2", "f0f7"], "secondary": ["10f1ad"] } }, "changes": [ "4.1.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.1.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "apartment", "building", "business", "city", "company", "office", "office building", "urban", "work" ] }, "styles": ["solid", "regular"], "unicode": "f1ad", "label": "Building", "voted": false, "svg": { "solid": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M48 0C21.5 0 0 21.5 0 48V464c0 26.5 21.5 48 48 48h96V432c0-26.5 21.5-48 48-48s48 21.5 48 48v80h96c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48H48zM64 240c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V240zm112-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16V240c0-8.8 7.2-16 16-16zm80 16c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H272c-8.8 0-16-7.2-16-16V240zM80 96h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V112c0-8.8 7.2-16 16-16zm80 16c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16V112zM272 96h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H272c-8.8 0-16-7.2-16-16V112c0-8.8 7.2-16 16-16z" }, "regular": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M64 48c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16h80V400c0-26.5 21.5-48 48-48s48 21.5 48 48v64h80c8.8 0 16-7.2 16-16V64c0-8.8-7.2-16-16-16H64zM0 64C0 28.7 28.7 0 64 0H320c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V64zm88 40c0-8.8 7.2-16 16-16h48c8.8 0 16 7.2 16 16v48c0 8.8-7.2 16-16 16H104c-8.8 0-16-7.2-16-16V104zM232 88h48c8.8 0 16 7.2 16 16v48c0 8.8-7.2 16-16 16H232c-8.8 0-16-7.2-16-16V104c0-8.8 7.2-16 16-16zM88 232c0-8.8 7.2-16 16-16h48c8.8 0 16 7.2 16 16v48c0 8.8-7.2 16-16 16H104c-8.8 0-16-7.2-16-16V232zm144-16h48c8.8 0 16 7.2 16 16v48c0 8.8-7.2 16-16 16H232c-8.8 0-16-7.2-16-16V232c0-8.8 7.2-16 16-16z" } }, "free": ["regular", "solid"] }, "building-circle-arrow-right": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["building", "city", "distribution center", "office"] }, "styles": ["solid"], "unicode": "e4d1", "label": "Building Circle Arrow Right", "voted": false, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M0 48C0 21.5 21.5 0 48 0H336c26.5 0 48 21.5 48 48V232.2c-39.1 32.3-64 81.1-64 135.8c0 49.5 20.4 94.2 53.3 126.2C364.5 505.1 351.1 512 336 512H240V432c0-26.5-21.5-48-48-48s-48 21.5-48 48v80H48c-26.5 0-48-21.5-48-48V48zM80 224c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V240c0-8.8-7.2-16-16-16H80zm80 16v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V240c0-8.8-7.2-16-16-16H176c-8.8 0-16 7.2-16 16zm112-16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V240c0-8.8-7.2-16-16-16H272zM64 112v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V112c0-8.8-7.2-16-16-16H80c-8.8 0-16 7.2-16 16zM176 96c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V112c0-8.8-7.2-16-16-16H176zm80 16v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V112c0-8.8-7.2-16-16-16H272c-8.8 0-16 7.2-16 16zm96 256a144 144 0 1 1 288 0 144 144 0 1 1 -288 0zm140.7-67.3c-6.2 6.2-6.2 16.4 0 22.6L521.4 352H432c-8.8 0-16 7.2-16 16s7.2 16 16 16h89.4l-28.7 28.7c-6.2 6.2-6.2 16.4 0 22.6s16.4 6.2 22.6 0l56-56c6.2-6.2 6.2-16.4 0-22.6l-56-56c-6.2-6.2-16.4-6.2-22.6 0z" } }, "free": ["solid"] }, "building-circle-check": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["building", "city", "not affected", "office", "ok", "okay"] }, "styles": ["solid"], "unicode": "e4d2", "label": "Building Circle Check", "voted": false, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M48 0C21.5 0 0 21.5 0 48V464c0 26.5 21.5 48 48 48h96V432c0-26.5 21.5-48 48-48s48 21.5 48 48v80h96c15.1 0 28.5-6.9 37.3-17.8C340.4 462.2 320 417.5 320 368c0-54.7 24.9-103.5 64-135.8V48c0-26.5-21.5-48-48-48H48zM64 240c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V240zm112-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16V240c0-8.8 7.2-16 16-16zm80 16c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H272c-8.8 0-16-7.2-16-16V240zM80 96h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V112c0-8.8 7.2-16 16-16zm80 16c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16V112zM272 96h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H272c-8.8 0-16-7.2-16-16V112c0-8.8 7.2-16 16-16zM640 368a144 144 0 1 0 -288 0 144 144 0 1 0 288 0zm-76.7-43.3c6.2 6.2 6.2 16.4 0 22.6l-72 72c-6.2 6.2-16.4 6.2-22.6 0l-40-40c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0L480 385.4l60.7-60.7c6.2-6.2 16.4-6.2 22.6 0z" } }, "free": ["solid"] }, "building-circle-exclamation": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["affected", "building", "city", "office"] }, "styles": ["solid"], "unicode": "e4d3", "label": "Building Circle Exclamation", "voted": false, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M48 0C21.5 0 0 21.5 0 48V464c0 26.5 21.5 48 48 48h96V432c0-26.5 21.5-48 48-48s48 21.5 48 48v80h96c15.1 0 28.5-6.9 37.3-17.8C340.4 462.2 320 417.5 320 368c0-54.7 24.9-103.5 64-135.8V48c0-26.5-21.5-48-48-48H48zM64 240c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V240zm112-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16V240c0-8.8 7.2-16 16-16zm80 16c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H272c-8.8 0-16-7.2-16-16V240zM80 96h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V112c0-8.8 7.2-16 16-16zm80 16c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16V112zM272 96h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H272c-8.8 0-16-7.2-16-16V112c0-8.8 7.2-16 16-16zM496 512a144 144 0 1 0 0-288 144 144 0 1 0 0 288zm0-96a24 24 0 1 1 0 48 24 24 0 1 1 0-48zm0-144c8.8 0 16 7.2 16 16v80c0 8.8-7.2 16-16 16s-16-7.2-16-16V288c0-8.8 7.2-16 16-16z" } }, "free": ["solid"] }, "building-circle-xmark": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["building", "city", "destroy", "office"] }, "styles": ["solid"], "unicode": "e4d4", "label": "Building Circle Xmark", "voted": false, "svg": { "solid": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M48 0C21.5 0 0 21.5 0 48V464c0 26.5 21.5 48 48 48h96V432c0-26.5 21.5-48 48-48s48 21.5 48 48v80h96c15.1 0 28.5-6.9 37.3-17.8C340.4 462.2 320 417.5 320 368c0-54.7 24.9-103.5 64-135.8V48c0-26.5-21.5-48-48-48H48zM64 240c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V240zm112-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16V240c0-8.8 7.2-16 16-16zm80 16c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H272c-8.8 0-16-7.2-16-16V240zM80 96h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V112c0-8.8 7.2-16 16-16zm80 16c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16V112zM272 96h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H272c-8.8 0-16-7.2-16-16V112c0-8.8 7.2-16 16-16zM496 512a144 144 0 1 0 0-288 144 144 0 1 0 0 288zm59.3-180.7L518.6 368l36.7 36.7c6.2 6.2 6.2 16.4 0 22.6s-16.4 6.2-22.6 0L496 390.6l-36.7 36.7c-6.2 6.2-16.4 6.2-22.6 0s-6.2-16.4 0-22.6L473.4 368l-36.7-36.7c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0L496 345.4l36.7-36.7c6.2-6.2 16.4-6.2 22.6 0s6.2 16.4 0 22.6z" } }, "free": ["solid"] }, "building-columns": { "aliases": { "names": ["bank", "institution", "museum", "university"], "unicodes": { "secondary": ["10f19c"] } }, "changes": [ "4.1.0", "5.0.0", "5.0.3", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.1.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "bank", "building", "college", "education", "institution", "museum", "students" ] }, "styles": ["solid"], "unicode": "f19c", "label": "Building Columns", "voted": false, "svg": { "solid": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M243.4 2.6l-224 96c-14 6-21.8 21-18.7 35.8S16.8 160 32 160v8c0 13.3 10.7 24 24 24H456c13.3 0 24-10.7 24-24v-8c15.2 0 28.3-10.7 31.3-25.6s-4.8-29.9-18.7-35.8l-224-96c-8-3.4-17.2-3.4-25.2 0zM128 224H64V420.3c-.6 .3-1.2 .7-1.8 1.1l-48 32c-11.7 7.8-17 22.4-12.9 35.9S17.9 512 32 512H480c14.1 0 26.5-9.2 30.6-22.7s-1.1-28.1-12.9-35.9l-48-32c-.6-.4-1.2-.7-1.8-1.1V224H384V416H344V224H280V416H232V224H168V416H128V224zM256 64a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" } }, "free": ["solid"] }, "building-flag": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ " city", "building", "diplomat", "embassy", "flag", "headquarters", "united nations" ] }, "styles": ["solid"], "unicode": "e4d5", "label": "Building Flag", "voted": false, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M48 0C21.5 0 0 21.5 0 48V464c0 26.5 21.5 48 48 48h96V432c0-26.5 21.5-48 48-48s48 21.5 48 48v80h96c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48H48zM64 240c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V240zm112-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16V240c0-8.8 7.2-16 16-16zm80 16c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H272c-8.8 0-16-7.2-16-16V240zM80 96h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V112c0-8.8 7.2-16 16-16zm80 16c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16V112zM272 96h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H272c-8.8 0-16-7.2-16-16V112c0-8.8 7.2-16 16-16zM448 0c-17.7 0-32 14.3-32 32V512h64V192H624c8.8 0 16-7.2 16-16V48c0-8.8-7.2-16-16-16H480c0-17.7-14.3-32-32-32z" } }, "free": ["solid"] }, "building-lock": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "building", "city", "closed", "lock", "lockdown", "quarantine", "secure" ] }, "styles": ["solid"], "unicode": "e4d6", "label": "Building Lock", "voted": false, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M48 0C21.5 0 0 21.5 0 48V464c0 26.5 21.5 48 48 48h96V432c0-26.5 21.5-48 48-48s48 21.5 48 48v80h88.6c-5.4-9.4-8.6-20.3-8.6-32V352c0-23.7 12.9-44.4 32-55.4V272c0-30.5 12.2-58.2 32-78.4V48c0-26.5-21.5-48-48-48H48zM64 240c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V240zm112-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16V240c0-8.8 7.2-16 16-16zm80 16c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H272c-8.8 0-16-7.2-16-16V240zM80 96h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V112c0-8.8 7.2-16 16-16zm80 16c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16V112zM272 96h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H272c-8.8 0-16-7.2-16-16V112c0-8.8 7.2-16 16-16zM464 240c17.7 0 32 14.3 32 32v48H432V272c0-17.7 14.3-32 32-32zm-80 32v48c-17.7 0-32 14.3-32 32V480c0 17.7 14.3 32 32 32H544c17.7 0 32-14.3 32-32V352c0-17.7-14.3-32-32-32V272c0-44.2-35.8-80-80-80s-80 35.8-80 80z" } }, "free": ["solid"] }, "building-ngo": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [" city", "building", "non governmental organization", "office"] }, "styles": ["solid"], "unicode": "e4d7", "label": "Building Ngo", "voted": false, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M48 0C21.5 0 0 21.5 0 48V464c0 26.5 21.5 48 48 48h96V432c0-26.5 21.5-48 48-48s48 21.5 48 48v80h96c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48H48zM64 240c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V240zm112-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16V240c0-8.8 7.2-16 16-16zm80 16c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H272c-8.8 0-16-7.2-16-16V240zM168 64h48c8.8 0 16 7.2 16 16s-7.2 16-16 16H184v64h16V144c0-8.8 7.2-16 16-16s16 7.2 16 16v24c0 13.3-10.7 24-24 24H176c-13.3 0-24-10.7-24-24V80c0-8.8 7.2-16 16-16zM304 96c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16s16-7.2 16-16V112c0-8.8-7.2-16-16-16zm-48 16c0-26.5 21.5-48 48-48s48 21.5 48 48v32c0 26.5-21.5 48-48 48s-48-21.5-48-48V112zM61.3 71.1l34.7 52V80c0-8.8 7.2-16 16-16s16 7.2 16 16v96c0 7.1-4.6 13.3-11.4 15.3s-14-.6-17.9-6.4L64 132.8V176c0 8.8-7.2 16-16 16s-16-7.2-16-16V80c0-7.1 4.6-13.3 11.4-15.3s14 .6 17.9 6.4z" } }, "free": ["solid"] }, "building-shield": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["building", "city", "police", "protect", "safety"] }, "styles": ["solid"], "unicode": "e4d8", "label": "Building Shield", "voted": false, "svg": { "solid": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M0 48C0 21.5 21.5 0 48 0H336c26.5 0 48 21.5 48 48V207l-42.4 17H304 272c-8.8 0-16 7.2-16 16v32 24.2V304c0 .9 .1 1.7 .2 2.6c2.3 58.1 24.1 144.8 98.7 201.5c-5.8 2.5-12.2 3.9-18.9 3.9H240V432c0-26.5-21.5-48-48-48s-48 21.5-48 48v80H48c-26.5 0-48-21.5-48-48V48zM80 224c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V240c0-8.8-7.2-16-16-16H80zm80 16v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V240c0-8.8-7.2-16-16-16H176c-8.8 0-16 7.2-16 16zM64 112v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V112c0-8.8-7.2-16-16-16H80c-8.8 0-16 7.2-16 16zM176 96c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V112c0-8.8-7.2-16-16-16H176zm80 16v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V112c0-8.8-7.2-16-16-16H272c-8.8 0-16 7.2-16 16zM423.1 225.7c5.7-2.3 12.1-2.3 17.8 0l120 48C570 277.4 576 286.2 576 296c0 63.3-25.9 168.8-134.8 214.2c-5.9 2.5-12.6 2.5-18.5 0C313.9 464.8 288 359.3 288 296c0-9.8 6-18.6 15.1-22.3l120-48zM527.4 312L432 273.8V461.7c68.2-33 91.5-99 95.4-149.7z" } }, "free": ["solid"] }, "building-un": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["building", "city", "office", "united nations"] }, "styles": ["solid"], "unicode": "e4d9", "label": "Building Un", "voted": false, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M48 0C21.5 0 0 21.5 0 48V464c0 26.5 21.5 48 48 48h96V432c0-26.5 21.5-48 48-48s48 21.5 48 48v80h96c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48H48zM64 240c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V240zm112-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16V240c0-8.8 7.2-16 16-16zm80 16c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H272c-8.8 0-16-7.2-16-16V240zM237.3 71.1l34.7 52V80c0-8.8 7.2-16 16-16s16 7.2 16 16v96c0 7.1-4.6 13.3-11.4 15.3s-14-.6-17.9-6.4l-34.7-52V176c0 8.8-7.2 16-16 16s-16-7.2-16-16V80c0-7.1 4.6-13.3 11.4-15.3s14 .6 17.9 6.4zM112 80v64c0 8.8 7.2 16 16 16s16-7.2 16-16V80c0-8.8 7.2-16 16-16s16 7.2 16 16v64c0 26.5-21.5 48-48 48s-48-21.5-48-48V80c0-8.8 7.2-16 16-16s16 7.2 16 16z" } }, "free": ["solid"] }, "building-user": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["apartment", "building", "city"] }, "styles": ["solid"], "unicode": "e4da", "label": "Building User", "voted": false, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M48 0C21.5 0 0 21.5 0 48V464c0 26.5 21.5 48 48 48h96V432c0-26.5 21.5-48 48-48s48 21.5 48 48v80h89.9c-6.3-10.2-9.9-22.2-9.9-35.1c0-46.9 25.8-87.8 64-109.2V271.8 48c0-26.5-21.5-48-48-48H48zM64 240c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V240zm112-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16V240c0-8.8 7.2-16 16-16zm80 16c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H272c-8.8 0-16-7.2-16-16V240zM80 96h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V112c0-8.8 7.2-16 16-16zm80 16c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16V112zM272 96h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H272c-8.8 0-16-7.2-16-16V112c0-8.8 7.2-16 16-16zM576 272a80 80 0 1 0 -160 0 80 80 0 1 0 160 0zM352 477.1c0 19.3 15.6 34.9 34.9 34.9H605.1c19.3 0 34.9-15.6 34.9-34.9c0-51.4-41.7-93.1-93.1-93.1H445.1c-51.4 0-93.1 41.7-93.1 93.1z" } }, "free": ["solid"] }, "building-wheat": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["agriculture", "building", "city", "usda"] }, "styles": ["solid"], "unicode": "e4db", "label": "Building Wheat", "voted": false, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M0 48C0 21.5 21.5 0 48 0H336c26.5 0 48 21.5 48 48V464c0 26.5-21.5 48-48 48H240V432c0-26.5-21.5-48-48-48s-48 21.5-48 48v80H48c-26.5 0-48-21.5-48-48V48zM80 224c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V240c0-8.8-7.2-16-16-16H80zm80 16v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V240c0-8.8-7.2-16-16-16H176c-8.8 0-16 7.2-16 16zm112-16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V240c0-8.8-7.2-16-16-16H272zM64 112v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V112c0-8.8-7.2-16-16-16H80c-8.8 0-16 7.2-16 16zM176 96c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V112c0-8.8-7.2-16-16-16H176zm80 16v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V112c0-8.8-7.2-16-16-16H272c-8.8 0-16 7.2-16 16zm384 80v16c0 44.2-35.8 80-80 80H544V272c0-44.2 35.8-80 80-80h16zm0 128c0 44.2-35.8 80-80 80H544V384c0-44.2 35.8-80 80-80h16v16zm0 112c0 44.2-35.8 80-80 80H544V496c0-44.2 35.8-80 80-80h16v16zM512 496v16H496c-44.2 0-80-35.8-80-80V416h16c44.2 0 80 35.8 80 80zm0-96H496c-44.2 0-80-35.8-80-80V304h16c44.2 0 80 35.8 80 80v16zm0-128v16H496c-44.2 0-80-35.8-80-80V192h16c44.2 0 80 35.8 80 80zM528 32c13.3 0 24 10.7 24 24V160c0 13.3-10.7 24-24 24s-24-10.7-24-24V56c0-13.3 10.7-24 24-24zm96 64v32c0 13.3-10.7 24-24 24s-24-10.7-24-24V96c0-13.3 10.7-24 24-24s24 10.7 24 24zM456 72c13.3 0 24 10.7 24 24v32c0 13.3-10.7 24-24 24s-24-10.7-24-24V96c0-13.3 10.7-24 24-24z" } }, "free": ["solid"] }, "bullhorn": { "aliases": { "unicodes": { "composite": ["1f4e2", "1f56b"], "secondary": ["10f0a1"] } }, "changes": [ "2.0.0", "5.0.0", "5.3.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Bullhorn", "announcement", "broadcast", "loud", "louder", "loudspeaker", "megaphone", "public address", "share" ] }, "styles": ["solid"], "unicode": "f0a1", "label": "Bullhorn", "voted": false, "svg": { "solid": { "last_modified": 1684766476, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M480 32c0-12.9-7.8-24.6-19.8-29.6s-25.7-2.2-34.9 6.9L381.7 53c-48 48-113.1 75-181 75H192 160 64c-35.3 0-64 28.7-64 64v96c0 35.3 28.7 64 64 64l0 128c0 17.7 14.3 32 32 32h64c17.7 0 32-14.3 32-32V352l8.7 0c67.9 0 133 27 181 75l43.6 43.6c9.2 9.2 22.9 11.9 34.9 6.9s19.8-16.6 19.8-29.6V300.4c18.6-8.8 32-32.5 32-60.4s-13.4-51.6-32-60.4V32zm-64 76.7V240 371.3C357.2 317.8 280.5 288 200.7 288H192V192h8.7c79.8 0 156.5-29.8 215.3-83.3z" } }, "free": ["solid"] }, "bullseye": { "aliases": { "unicodes": { "secondary": ["10f140"] } }, "changes": [ "3.1.0", "5.0.0", "5.3.0", "5.10.1", "5.15.4", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["archery", "goal", "objective", "strategy", "target"] }, "styles": ["solid"], "unicode": "f140", "label": "Bullseye", "voted": false, "svg": { "solid": { "last_modified": 1684766476, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M448 256A192 192 0 1 0 64 256a192 192 0 1 0 384 0zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm256 80a80 80 0 1 0 0-160 80 80 0 1 0 0 160zm0-224a144 144 0 1 1 0 288 144 144 0 1 1 0-288zM224 256a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z" } }, "free": ["solid"] }, "burger": { "aliases": { "names": ["hamburger"], "unicodes": { "secondary": ["10f805"] } }, "changes": [ "5.7.0", "6.0.0-beta1", "6.0.0-beta2", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "bacon", "beef", "burger", "burger king", "cheeseburger", "fast food", "grill", "ground beef", "mcdonalds", "sandwich" ] }, "styles": ["solid"], "unicode": "f805", "label": "Burger", "voted": false, "svg": { "solid": { "last_modified": 1684767420, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M61.1 224C45 224 32 211 32 194.9c0-1.9 .2-3.7 .6-5.6C37.9 168.3 78.8 32 256 32s218.1 136.3 223.4 157.3c.5 1.9 .6 3.7 .6 5.6c0 16.1-13 29.1-29.1 29.1H61.1zM144 128a16 16 0 1 0 -32 0 16 16 0 1 0 32 0zm240 16a16 16 0 1 0 0-32 16 16 0 1 0 0 32zM272 96a16 16 0 1 0 -32 0 16 16 0 1 0 32 0zM16 304c0-26.5 21.5-48 48-48H448c26.5 0 48 21.5 48 48s-21.5 48-48 48H64c-26.5 0-48-21.5-48-48zm16 96c0-8.8 7.2-16 16-16H464c8.8 0 16 7.2 16 16v16c0 35.3-28.7 64-64 64H96c-35.3 0-64-28.7-64-64V400z" } }, "free": ["solid"] }, "buromobelexperte": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f37f", "label": "Büromöbel-Experte GmbH & Co. KG.", "voted": false, "svg": { "brands": { "last_modified": 1660014464, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M0 32v128h128V32H0zm120 120H8V40h112v112zm40-120v128h128V32H160zm120 120H168V40h112v112zm40-120v128h128V32H320zm120 120H328V40h112v112zM0 192v128h128V192H0zm120 120H8V200h112v112zm40-120v128h128V192H160zm120 120H168V200h112v112zm40-120v128h128V192H320zm120 120H328V200h112v112zM0 352v128h128V352H0zm120 120H8V360h112v112zm40-120v128h128V352H160zm120 120H168V360h112v112zm40-120v128h128V352H320z" } }, "free": ["brands"] }, "burst": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["boom", "crash", "explosion"] }, "styles": ["solid"], "unicode": "e4dc", "label": "Burst", "voted": false, "svg": { "solid": { "last_modified": 1684767443, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M37.6 4.2C28-2.3 15.2-1.1 7 7s-9.4 21-2.8 30.5l112 163.3L16.6 233.2C6.7 236.4 0 245.6 0 256s6.7 19.6 16.6 22.8l103.1 33.4L66.8 412.8c-4.9 9.3-3.2 20.7 4.3 28.1s18.8 9.2 28.1 4.3l100.6-52.9 33.4 103.1c3.2 9.9 12.4 16.6 22.8 16.6s19.6-6.7 22.8-16.6l33.4-103.1 100.6 52.9c9.3 4.9 20.7 3.2 28.1-4.3s9.2-18.8 4.3-28.1L392.3 312.2l103.1-33.4c9.9-3.2 16.6-12.4 16.6-22.8s-6.7-19.6-16.6-22.8L388.9 198.7l25.7-70.4c3.2-8.8 1-18.6-5.6-25.2s-16.4-8.8-25.2-5.6l-70.4 25.7L278.8 16.6C275.6 6.7 266.4 0 256 0s-19.6 6.7-22.8 16.6l-32.3 99.6L37.6 4.2z" } }, "free": ["solid"] }, "bus": { "aliases": { "unicodes": { "composite": ["1f68d"], "secondary": ["10f207"] } }, "changes": [ "4.2.0", "5.0.0", "5.1.0", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "bus", "oncoming", "oncoming bus", "public transportation", "transportation", "travel", "vehicle" ] }, "styles": ["solid"], "unicode": "f207", "label": "Bus", "voted": false, "svg": { "solid": { "last_modified": 1684767650, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M288 0C422.4 0 512 35.2 512 80V96l0 32c17.7 0 32 14.3 32 32v64c0 17.7-14.3 32-32 32l0 160c0 17.7-14.3 32-32 32v32c0 17.7-14.3 32-32 32H416c-17.7 0-32-14.3-32-32V448H192v32c0 17.7-14.3 32-32 32H128c-17.7 0-32-14.3-32-32l0-32c-17.7 0-32-14.3-32-32l0-160c-17.7 0-32-14.3-32-32V160c0-17.7 14.3-32 32-32h0V96h0V80C64 35.2 153.6 0 288 0zM128 160v96c0 17.7 14.3 32 32 32H272V128H160c-17.7 0-32 14.3-32 32zM304 288H416c17.7 0 32-14.3 32-32V160c0-17.7-14.3-32-32-32H304V288zM144 400a32 32 0 1 0 0-64 32 32 0 1 0 0 64zm288 0a32 32 0 1 0 0-64 32 32 0 1 0 0 64zM384 80c0-8.8-7.2-16-16-16H208c-8.8 0-16 7.2-16 16s7.2 16 16 16H368c8.8 0 16-7.2 16-16z" } }, "free": ["solid"] }, "bus-simple": { "aliases": { "names": ["bus-alt"], "unicodes": { "secondary": ["10f55e"] } }, "changes": [ "5.1.0", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "mta", "public transportation", "transportation", "travel", "vehicle" ] }, "styles": ["solid"], "unicode": "f55e", "label": "Bus Simple", "voted": false, "svg": { "solid": { "last_modified": 1684767650, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M224 0C348.8 0 448 35.2 448 80V96 416c0 17.7-14.3 32-32 32v32c0 17.7-14.3 32-32 32H352c-17.7 0-32-14.3-32-32V448H128v32c0 17.7-14.3 32-32 32H64c-17.7 0-32-14.3-32-32l0-32c-17.7 0-32-14.3-32-32V96 80C0 35.2 99.2 0 224 0zM64 128V256c0 17.7 14.3 32 32 32H352c17.7 0 32-14.3 32-32V128c0-17.7-14.3-32-32-32H96c-17.7 0-32 14.3-32 32zM80 400a32 32 0 1 0 0-64 32 32 0 1 0 0 64zm288 0a32 32 0 1 0 0-64 32 32 0 1 0 0 64z" } }, "free": ["solid"] }, "business-time": { "aliases": { "names": ["briefcase-clock"], "unicodes": { "secondary": ["10f64a"] } }, "changes": ["5.3.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "alarm", "briefcase", "business socks", "clock", "flight of the conchords", "reminder", "wednesday" ] }, "styles": ["solid"], "unicode": "f64a", "label": "Business Time", "voted": false, "svg": { "solid": { "last_modified": 1684767442, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M184 48H328c4.4 0 8 3.6 8 8V96H176V56c0-4.4 3.6-8 8-8zm-56 8V96H64C28.7 96 0 124.7 0 160v96H192 352h8.2c32.3-39.1 81.1-64 135.8-64c5.4 0 10.7 .2 16 .7V160c0-35.3-28.7-64-64-64H384V56c0-30.9-25.1-56-56-56H184c-30.9 0-56 25.1-56 56zM320 352H224c-17.7 0-32-14.3-32-32V288H0V416c0 35.3 28.7 64 64 64H360.2C335.1 449.6 320 410.5 320 368c0-5.4 .2-10.7 .7-16l-.7 0zm320 16a144 144 0 1 0 -288 0 144 144 0 1 0 288 0zM496 288c8.8 0 16 7.2 16 16v48h32c8.8 0 16 7.2 16 16s-7.2 16-16 16H496c-8.8 0-16-7.2-16-16V304c0-8.8 7.2-16 16-16z" } }, "free": ["solid"] }, "buy-n-large": { "changes": ["5.11.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f8a6", "label": "Buy n Large", "voted": false, "svg": { "brands": { "last_modified": 1660014459, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M288 32C133.27 32 7.79 132.32 7.79 256S133.27 480 288 480s280.21-100.32 280.21-224S442.73 32 288 32zm-85.39 357.19L64.1 390.55l77.25-290.74h133.44c63.15 0 84.93 28.65 78 72.84a60.24 60.24 0 0 1-1.5 6.85 77.39 77.39 0 0 0-17.21-1.93c-42.35 0-76.69 33.88-76.69 75.65 0 37.14 27.14 68 62.93 74.45-18.24 37.16-56.16 60.92-117.71 61.52zM358 207.11h32l-22.16 90.31h-35.41l-11.19-35.63-7.83 35.63h-37.83l26.63-90.31h31.34l15 36.75zm145.86 182.08H306.79L322.63 328a78.8 78.8 0 0 0 11.47.83c42.34 0 76.69-33.87 76.69-75.65 0-32.65-21-60.46-50.38-71.06l21.33-82.35h92.5l-53.05 205.36h103.87zM211.7 269.39H187l-13.8 56.47h24.7c16.14 0 32.11-3.18 37.94-26.65 5.56-22.31-7.99-29.82-24.14-29.82zM233 170h-21.34L200 217.71h21.37c18 0 35.38-14.64 39.21-30.14C265.23 168.71 251.07 170 233 170z" } }, "free": ["brands"] }, "buysellads": { "changes": ["4.3.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f20d", "label": "BuySellAds", "voted": false, "svg": { "brands": { "last_modified": 1660014482, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M224 150.7l42.9 160.7h-85.8L224 150.7zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-65.3 325.3l-94.5-298.7H159.8L65.3 405.3H156l111.7-91.6 24.2 91.6h90.8z" } }, "free": ["brands"] }, "c": { "aliases": { "unicodes": { "composite": ["63"] } }, "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Latin Capital Letter C", "Latin Small Letter C", "letter"] }, "styles": ["solid"], "unicode": "43", "label": "C", "voted": false, "svg": { "solid": { "last_modified": 1684767247, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M329.1 142.9c-62.5-62.5-155.8-62.5-218.3 0s-62.5 163.8 0 226.3s155.8 62.5 218.3 0c12.5-12.5 32.8-12.5 45.3 0s12.5 32.8 0 45.3c-87.5 87.5-221.3 87.5-308.8 0s-87.5-229.3 0-316.8s221.3-87.5 308.8 0c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0z" } }, "free": ["solid"] }, "cable-car": { "aliases": { "names": ["tram"], "unicodes": { "composite": ["1f6a1", "e0cf"], "secondary": ["10f7da"] } }, "changes": [ "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.1.2", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "aerial tramway", "cable", "gondola", "lift", "mountain", "mountain cableway", "tram", "tramway", "trolley" ] }, "styles": ["solid"], "unicode": "f7da", "label": "Cable Car", "voted": false, "svg": { "solid": { "last_modified": 1684767649, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M288 0a32 32 0 1 1 0 64 32 32 0 1 1 0-64zM160 56a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zM32 288c0-35.3 28.7-64 64-64H232V157.5l-203.1 42c-13 2.7-25.7-5.7-28.4-18.6s5.7-25.7 18.6-28.4l232-48 232-48c13-2.7 25.7 5.7 28.4 18.6s-5.7 25.7-18.6 28.4L280 147.5V224H416c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H96c-35.3 0-64-28.7-64-64V288zm64 0c-8.8 0-16 7.2-16 16v64c0 8.8 7.2 16 16 16h64c8.8 0 16-7.2 16-16V304c0-8.8-7.2-16-16-16H96zm112 16v64c0 8.8 7.2 16 16 16h64c8.8 0 16-7.2 16-16V304c0-8.8-7.2-16-16-16H224c-8.8 0-16 7.2-16 16zm144-16c-8.8 0-16 7.2-16 16v64c0 8.8 7.2 16 16 16h64c8.8 0 16-7.2 16-16V304c0-8.8-7.2-16-16-16H352z" } }, "free": ["solid"] }, "cake-candles": { "aliases": { "names": ["birthday-cake", "cake"], "unicodes": { "composite": ["1f382"], "secondary": ["10f1fd"] } }, "changes": ["4.2.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "anniversary", "bakery", "birthday", "birthday cake", "cake", "candles", "celebration", "dessert", "frosting", "holiday", "party", "pastry", "sweet" ] }, "styles": ["solid"], "unicode": "f1fd", "label": "Cake Candles", "voted": false, "svg": { "solid": { "last_modified": 1684767419, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M86.4 5.5L61.8 47.6C58 54.1 56 61.6 56 69.2V72c0 22.1 17.9 40 40 40s40-17.9 40-40V69.2c0-7.6-2-15-5.8-21.6L105.6 5.5C103.6 2.1 100 0 96 0s-7.6 2.1-9.6 5.5zm128 0L189.8 47.6c-3.8 6.5-5.8 14-5.8 21.6V72c0 22.1 17.9 40 40 40s40-17.9 40-40V69.2c0-7.6-2-15-5.8-21.6L233.6 5.5C231.6 2.1 228 0 224 0s-7.6 2.1-9.6 5.5zM317.8 47.6c-3.8 6.5-5.8 14-5.8 21.6V72c0 22.1 17.9 40 40 40s40-17.9 40-40V69.2c0-7.6-2-15-5.8-21.6L361.6 5.5C359.6 2.1 356 0 352 0s-7.6 2.1-9.6 5.5L317.8 47.6zM128 176c0-17.7-14.3-32-32-32s-32 14.3-32 32v48c-35.3 0-64 28.7-64 64v71c8.3 5.2 18.1 9 28.8 9c13.5 0 27.2-6.1 38.4-13.4c5.4-3.5 9.9-7.1 13-9.7c1.5-1.3 2.7-2.4 3.5-3.1c.4-.4 .7-.6 .8-.8l.1-.1 0 0 0 0s0 0 0 0s0 0 0 0c3.1-3.2 7.4-4.9 11.9-4.8s8.6 2.1 11.6 5.4l0 0 0 0 .1 .1c.1 .1 .4 .4 .7 .7c.7 .7 1.7 1.7 3.1 3c2.8 2.6 6.8 6.1 11.8 9.5c10.2 7.1 23 13.1 36.3 13.1s26.1-6 36.3-13.1c5-3.5 9-6.9 11.8-9.5c1.4-1.3 2.4-2.3 3.1-3c.3-.3 .6-.6 .7-.7l.1-.1c3-3.5 7.4-5.4 12-5.4s9 2 12 5.4l.1 .1c.1 .1 .4 .4 .7 .7c.7 .7 1.7 1.7 3.1 3c2.8 2.6 6.8 6.1 11.8 9.5c10.2 7.1 23 13.1 36.3 13.1s26.1-6 36.3-13.1c5-3.5 9-6.9 11.8-9.5c1.4-1.3 2.4-2.3 3.1-3c.3-.3 .6-.6 .7-.7l.1-.1c2.9-3.4 7.1-5.3 11.6-5.4s8.7 1.6 11.9 4.8l0 0 0 0 0 0 .1 .1c.2 .2 .4 .4 .8 .8c.8 .7 1.9 1.8 3.5 3.1c3.1 2.6 7.5 6.2 13 9.7c11.2 7.3 24.9 13.4 38.4 13.4c10.7 0 20.5-3.9 28.8-9V288c0-35.3-28.7-64-64-64V176c0-17.7-14.3-32-32-32s-32 14.3-32 32v48H256V176c0-17.7-14.3-32-32-32s-32 14.3-32 32v48H128V176zM448 394.6c-8.5 3.3-18.2 5.4-28.8 5.4c-22.5 0-42.4-9.9-55.8-18.6c-4.1-2.7-7.8-5.4-10.9-7.8c-2.8 2.4-6.1 5-9.8 7.5C329.8 390 310.6 400 288 400s-41.8-10-54.6-18.9c-3.5-2.4-6.7-4.9-9.4-7.2c-2.7 2.3-5.9 4.7-9.4 7.2C201.8 390 182.6 400 160 400s-41.8-10-54.6-18.9c-3.7-2.6-7-5.2-9.8-7.5c-3.1 2.4-6.8 5.1-10.9 7.8C71.2 390.1 51.3 400 28.8 400c-10.6 0-20.3-2.2-28.8-5.4V480c0 17.7 14.3 32 32 32H416c17.7 0 32-14.3 32-32V394.6z" } }, "free": ["solid"] }, "calculator": { "aliases": { "unicodes": { "composite": ["1f5a9"], "secondary": ["10f1ec"] } }, "changes": [ "4.2.0", "5.0.0", "5.3.0", "5.11.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Pocket Calculator", "abacus", "addition", "arithmetic", "counting", "math", "multiplication", "subtraction" ] }, "styles": ["solid"], "unicode": "f1ec", "label": "Calculator", "voted": false, "svg": { "solid": { "last_modified": 1684767342, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M64 0C28.7 0 0 28.7 0 64V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V64c0-35.3-28.7-64-64-64H64zM96 64H288c17.7 0 32 14.3 32 32v32c0 17.7-14.3 32-32 32H96c-17.7 0-32-14.3-32-32V96c0-17.7 14.3-32 32-32zm32 160a32 32 0 1 1 -64 0 32 32 0 1 1 64 0zM96 352a32 32 0 1 1 0-64 32 32 0 1 1 0 64zM64 416c0-17.7 14.3-32 32-32h96c17.7 0 32 14.3 32 32s-14.3 32-32 32H96c-17.7 0-32-14.3-32-32zM192 256a32 32 0 1 1 0-64 32 32 0 1 1 0 64zm32 64a32 32 0 1 1 -64 0 32 32 0 1 1 64 0zm64-64a32 32 0 1 1 0-64 32 32 0 1 1 0 64zm32 64a32 32 0 1 1 -64 0 32 32 0 1 1 64 0zM288 448a32 32 0 1 1 0-64 32 32 0 1 1 0 64z" } }, "free": ["solid"] }, "calendar": { "aliases": { "unicodes": { "composite": ["1f4c5", "1f4c6"], "secondary": ["10f133"] } }, "changes": [ "3.1.0", "5.0.0", "5.10.2", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "calendar", "calendar-o", "date", "day", "event", "month", "schedule", "tear-off calendar", "time", "when", "year" ] }, "styles": ["solid", "regular"], "unicode": "f133", "label": "Calendar", "voted": false, "svg": { "solid": { "last_modified": 1684767327, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M96 32V64H48C21.5 64 0 85.5 0 112v48H448V112c0-26.5-21.5-48-48-48H352V32c0-17.7-14.3-32-32-32s-32 14.3-32 32V64H160V32c0-17.7-14.3-32-32-32S96 14.3 96 32zM448 192H0V464c0 26.5 21.5 48 48 48H400c26.5 0 48-21.5 48-48V192z" }, "regular": { "last_modified": 1684767327, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M152 24c0-13.3-10.7-24-24-24s-24 10.7-24 24V64H64C28.7 64 0 92.7 0 128v16 48V448c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V192 144 128c0-35.3-28.7-64-64-64H344V24c0-13.3-10.7-24-24-24s-24 10.7-24 24V64H152V24zM48 192H400V448c0 8.8-7.2 16-16 16H64c-8.8 0-16-7.2-16-16V192z" } }, "free": ["regular", "solid"] }, "calendar-check": { "aliases": { "unicodes": { "secondary": ["10f274"] } }, "changes": [ "4.4.0", "5.0.0", "5.10.2", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "accept", "agree", "appointment", "confirm", "correct", "date", "day", "done", "event", "month", "ok", "schedule", "select", "success", "tick", "time", "todo", "when", "year" ] }, "styles": ["solid", "regular"], "unicode": "f274", "label": "Calendar Check", "voted": false, "svg": { "solid": { "last_modified": 1684767327, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M128 0c17.7 0 32 14.3 32 32V64H288V32c0-17.7 14.3-32 32-32s32 14.3 32 32V64h48c26.5 0 48 21.5 48 48v48H0V112C0 85.5 21.5 64 48 64H96V32c0-17.7 14.3-32 32-32zM0 192H448V464c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V192zM329 305c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0l-95 95-47-47c-9.4-9.4-24.6-9.4-33.9 0s-9.4 24.6 0 33.9l64 64c9.4 9.4 24.6 9.4 33.9 0L329 305z" }, "regular": { "last_modified": 1684767327, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M128 0c13.3 0 24 10.7 24 24V64H296V24c0-13.3 10.7-24 24-24s24 10.7 24 24V64h40c35.3 0 64 28.7 64 64v16 48V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V192 144 128C0 92.7 28.7 64 64 64h40V24c0-13.3 10.7-24 24-24zM400 192H48V448c0 8.8 7.2 16 16 16H384c8.8 0 16-7.2 16-16V192zM329 297L217 409c-9.4 9.4-24.6 9.4-33.9 0l-64-64c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l47 47 95-95c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9z" } }, "free": ["regular", "solid"] }, "calendar-day": { "aliases": { "unicodes": { "secondary": ["10f783"] } }, "changes": [ "5.6.0", "5.10.2", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "date", "day", "detail", "event", "focus", "month", "schedule", "single day", "time", "today", "when", "year" ] }, "styles": ["solid"], "unicode": "f783", "label": "Calendar Day", "voted": true, "svg": { "solid": { "last_modified": 1684767327, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M128 0c17.7 0 32 14.3 32 32V64H288V32c0-17.7 14.3-32 32-32s32 14.3 32 32V64h48c26.5 0 48 21.5 48 48v48H0V112C0 85.5 21.5 64 48 64H96V32c0-17.7 14.3-32 32-32zM0 192H448V464c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V192zm80 64c-8.8 0-16 7.2-16 16v96c0 8.8 7.2 16 16 16h96c8.8 0 16-7.2 16-16V272c0-8.8-7.2-16-16-16H80z" } }, "free": ["solid"] }, "calendar-days": { "aliases": { "names": ["calendar-alt"], "unicodes": { "secondary": ["10f073"] } }, "changes": [ "1.0.0", "5.0.0", "5.6.0", "5.7.0", "5.10.2", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "calendar", "date", "day", "event", "month", "schedule", "time", "when", "year" ] }, "styles": ["solid", "regular"], "unicode": "f073", "label": "Calendar Days", "voted": false, "svg": { "solid": { "last_modified": 1684767328, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M128 0c17.7 0 32 14.3 32 32V64H288V32c0-17.7 14.3-32 32-32s32 14.3 32 32V64h48c26.5 0 48 21.5 48 48v48H0V112C0 85.5 21.5 64 48 64H96V32c0-17.7 14.3-32 32-32zM0 192H448V464c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V192zm64 80v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V272c0-8.8-7.2-16-16-16H80c-8.8 0-16 7.2-16 16zm128 0v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V272c0-8.8-7.2-16-16-16H208c-8.8 0-16 7.2-16 16zm144-16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V272c0-8.8-7.2-16-16-16H336zM64 400v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V400c0-8.8-7.2-16-16-16H80c-8.8 0-16 7.2-16 16zm144-16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V400c0-8.8-7.2-16-16-16H208zm112 16v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V400c0-8.8-7.2-16-16-16H336c-8.8 0-16 7.2-16 16z" }, "regular": { "last_modified": 1684767328, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M152 24c0-13.3-10.7-24-24-24s-24 10.7-24 24V64H64C28.7 64 0 92.7 0 128v16 48V448c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V192 144 128c0-35.3-28.7-64-64-64H344V24c0-13.3-10.7-24-24-24s-24 10.7-24 24V64H152V24zM48 192h80v56H48V192zm0 104h80v64H48V296zm128 0h96v64H176V296zm144 0h80v64H320V296zm80-48H320V192h80v56zm0 160v40c0 8.8-7.2 16-16 16H320V408h80zm-128 0v56H176V408h96zm-144 0v56H64c-8.8 0-16-7.2-16-16V408h80zM272 248H176V192h96v56z" } }, "free": ["regular", "solid"] }, "calendar-minus": { "aliases": { "unicodes": { "secondary": ["10f272"] } }, "changes": [ "4.4.0", "5.0.0", "5.10.2", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "calendar", "date", "day", "delete", "event", "month", "negative", "remove", "schedule", "time", "when", "year" ] }, "styles": ["solid", "regular"], "unicode": "f272", "label": "Calendar Minus", "voted": false, "svg": { "solid": { "last_modified": 1684767327, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M160 0c17.7 0 32 14.3 32 32V64H320V32c0-17.7 14.3-32 32-32s32 14.3 32 32V64h48c26.5 0 48 21.5 48 48v48H32V112c0-26.5 21.5-48 48-48h48V32c0-17.7 14.3-32 32-32zM32 192H480V464c0 26.5-21.5 48-48 48H80c-26.5 0-48-21.5-48-48V192zM344 376c13.3 0 24-10.7 24-24s-10.7-24-24-24H168c-13.3 0-24 10.7-24 24s10.7 24 24 24H344z" }, "regular": { "last_modified": 1684767327, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M160 0c13.3 0 24 10.7 24 24V64H328V24c0-13.3 10.7-24 24-24s24 10.7 24 24V64h40c35.3 0 64 28.7 64 64v16 48V448c0 35.3-28.7 64-64 64H96c-35.3 0-64-28.7-64-64V192 144 128c0-35.3 28.7-64 64-64h40V24c0-13.3 10.7-24 24-24zM432 192H80V448c0 8.8 7.2 16 16 16H416c8.8 0 16-7.2 16-16V192zM328 352H184c-13.3 0-24-10.7-24-24s10.7-24 24-24H328c13.3 0 24 10.7 24 24s-10.7 24-24 24z" } }, "free": ["regular", "solid"] }, "calendar-plus": { "aliases": { "unicodes": { "secondary": ["10f271"] } }, "changes": [ "4.4.0", "5.0.0", "5.10.2", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "add", "calendar", "create", "date", "day", "event", "month", "new", "positive", "schedule", "time", "when", "year" ] }, "styles": ["solid", "regular"], "unicode": "f271", "label": "Calendar Plus", "voted": false, "svg": { "solid": { "last_modified": 1684767327, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M128 32V64H80c-26.5 0-48 21.5-48 48v48H480V112c0-26.5-21.5-48-48-48H384V32c0-17.7-14.3-32-32-32s-32 14.3-32 32V64H192V32c0-17.7-14.3-32-32-32s-32 14.3-32 32zM480 192H32V464c0 26.5 21.5 48 48 48H432c26.5 0 48-21.5 48-48V192zM256 248c13.3 0 24 10.7 24 24v56h56c13.3 0 24 10.7 24 24s-10.7 24-24 24H280v56c0 13.3-10.7 24-24 24s-24-10.7-24-24V376H176c-13.3 0-24-10.7-24-24s10.7-24 24-24h56V272c0-13.3 10.7-24 24-24z" }, "regular": { "last_modified": 1684767327, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M184 24c0-13.3-10.7-24-24-24s-24 10.7-24 24V64H96c-35.3 0-64 28.7-64 64v16 48V448c0 35.3 28.7 64 64 64H416c35.3 0 64-28.7 64-64V192 144 128c0-35.3-28.7-64-64-64H376V24c0-13.3-10.7-24-24-24s-24 10.7-24 24V64H184V24zM80 192H432V448c0 8.8-7.2 16-16 16H96c-8.8 0-16-7.2-16-16V192zm176 40c-13.3 0-24 10.7-24 24v48H184c-13.3 0-24 10.7-24 24s10.7 24 24 24h48v48c0 13.3 10.7 24 24 24s24-10.7 24-24V352h48c13.3 0 24-10.7 24-24s-10.7-24-24-24H280V256c0-13.3-10.7-24-24-24z" } }, "free": ["regular", "solid"] }, "calendar-week": { "aliases": { "unicodes": { "secondary": ["10f784"] } }, "changes": [ "5.6.0", "5.10.2", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "date", "day", "detail", "event", "focus", "month", "schedule", "single week", "time", "today", "when", "year" ] }, "styles": ["solid"], "unicode": "f784", "label": "Calendar Week", "voted": true, "svg": { "solid": { "last_modified": 1684767327, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M128 0c17.7 0 32 14.3 32 32V64H288V32c0-17.7 14.3-32 32-32s32 14.3 32 32V64h48c26.5 0 48 21.5 48 48v48H0V112C0 85.5 21.5 64 48 64H96V32c0-17.7 14.3-32 32-32zM0 192H448V464c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V192zm80 64c-8.8 0-16 7.2-16 16v64c0 8.8 7.2 16 16 16H368c8.8 0 16-7.2 16-16V272c0-8.8-7.2-16-16-16H80z" } }, "free": ["solid"] }, "calendar-xmark": { "aliases": { "names": ["calendar-times"], "unicodes": { "secondary": ["10f273"] } }, "changes": [ "4.4.0", "5.0.0", "5.10.2", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "archive", "calendar", "date", "day", "delete", "event", "month", "remove", "schedule", "time", "when", "x", "year" ] }, "styles": ["solid", "regular"], "unicode": "f273", "label": "Calendar Xmark", "voted": false, "svg": { "solid": { "last_modified": 1684767327, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M160 0c17.7 0 32 14.3 32 32V64H320V32c0-17.7 14.3-32 32-32s32 14.3 32 32V64h48c26.5 0 48 21.5 48 48v48H32V112c0-26.5 21.5-48 48-48h48V32c0-17.7 14.3-32 32-32zM32 192H480V464c0 26.5-21.5 48-48 48H80c-26.5 0-48-21.5-48-48V192zM337 305c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0l-47 47-47-47c-9.4-9.4-24.6-9.4-33.9 0s-9.4 24.6 0 33.9l47 47-47 47c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l47-47 47 47c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9l-47-47 47-47z" }, "regular": { "last_modified": 1684767327, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M160 0c13.3 0 24 10.7 24 24V64H328V24c0-13.3 10.7-24 24-24s24 10.7 24 24V64h40c35.3 0 64 28.7 64 64v16 48V448c0 35.3-28.7 64-64 64H96c-35.3 0-64-28.7-64-64V192 144 128c0-35.3 28.7-64 64-64h40V24c0-13.3 10.7-24 24-24zM432 192H80V448c0 8.8 7.2 16 16 16H416c8.8 0 16-7.2 16-16V192zm-95 89l-47 47 47 47c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-47-47-47 47c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l47-47-47-47c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l47 47 47-47c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9z" } }, "free": ["regular", "solid"] }, "camera": { "aliases": { "names": ["camera-alt"], "unicodes": { "composite": ["f332"], "primary": ["f332"], "secondary": ["10f030", "10f332"] } }, "changes": [ "1.0.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta2", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "image", "lens", "photo", "picture", "record", "shutter", "video" ] }, "styles": ["solid"], "unicode": "f030", "label": "Camera", "voted": false, "svg": { "solid": { "last_modified": 1684767342, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M149.1 64.8L138.7 96H64C28.7 96 0 124.7 0 160V416c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V160c0-35.3-28.7-64-64-64H373.3L362.9 64.8C356.4 45.2 338.1 32 317.4 32H194.6c-20.7 0-39 13.2-45.5 32.8zM256 192a96 96 0 1 1 0 192 96 96 0 1 1 0-192z" } }, "free": ["solid"] }, "camera-retro": { "aliases": { "unicodes": { "composite": ["1f4f7"], "secondary": ["10f083"] } }, "changes": [ "1.0.0", "5.0.0", "5.10.1", "6.0.0-beta1", "6.0.0-beta2", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "camera", "image", "lens", "photo", "picture", "record", "shutter", "video" ] }, "styles": ["solid"], "unicode": "f083", "label": "Camera Retro", "voted": false, "svg": { "solid": { "last_modified": 1684767343, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M220.6 121.2L271.1 96 448 96v96H333.2c-21.9-15.1-48.5-24-77.2-24s-55.2 8.9-77.2 24H64V128H192c9.9 0 19.7-2.3 28.6-6.8zM0 128V416c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H271.1c-9.9 0-19.7 2.3-28.6 6.8L192 64H160V48c0-8.8-7.2-16-16-16H80c-8.8 0-16 7.2-16 16l0 16C28.7 64 0 92.7 0 128zM168 304a88 88 0 1 1 176 0 88 88 0 1 1 -176 0z" } }, "free": ["solid"] }, "camera-rotate": { "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["flip", "front-facing", "photo", "selfie"] }, "styles": ["solid"], "unicode": "e0d8", "label": "Camera Rotate", "voted": true, "svg": { "solid": { "last_modified": 1684767343, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M213.1 64.8L202.7 96H128c-35.3 0-64 28.7-64 64V416c0 35.3 28.7 64 64 64H512c35.3 0 64-28.7 64-64V160c0-35.3-28.7-64-64-64H437.3L426.9 64.8C420.4 45.2 402.1 32 381.4 32H258.6c-20.7 0-39 13.2-45.5 32.8zM448 256c0 8.8-7.2 16-16 16H355.3c-6.2 0-11.3-5.1-11.3-11.3c0-3 1.2-5.9 3.3-8L371 229c-13.6-13.4-31.9-21-51-21c-19.2 0-37.7 7.6-51.3 21.3L249 249c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l19.7-19.7C257.4 172.7 288 160 320 160c31.8 0 62.4 12.6 85 35l23.7-23.7c2.1-2.1 5-3.3 8-3.3c6.2 0 11.3 5.1 11.3 11.3V256zM192 320c0-8.8 7.2-16 16-16h76.7c6.2 0 11.3 5.1 11.3 11.3c0 3-1.2 5.9-3.3 8L269 347c13.6 13.4 31.9 21 51 21c19.2 0 37.7-7.6 51.3-21.3L391 327c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-19.7 19.7C382.6 403.3 352 416 320 416c-31.8 0-62.4-12.6-85-35l-23.7 23.7c-2.1 2.1-5 3.3-8 3.3c-6.2 0-11.3-5.1-11.3-11.3V320z" } }, "free": ["solid"] }, "campground": { "aliases": { "unicodes": { "composite": ["26fa"], "secondary": ["10f6bb"] } }, "changes": [ "5.4.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["camping", "fall", "outdoors", "teepee", "tent", "tipi"] }, "styles": ["solid"], "unicode": "f6bb", "label": "Campground", "voted": false, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M377 52c11-13.8 8.8-33.9-5-45s-33.9-8.8-45 5L288 60.8 249 12c-11-13.8-31.2-16-45-5s-16 31.2-5 45l48 60L12.3 405.4C4.3 415.4 0 427.7 0 440.4V464c0 26.5 21.5 48 48 48H288 528c26.5 0 48-21.5 48-48V440.4c0-12.7-4.3-25.1-12.3-35L329 112l48-60zM288 448H168.5L288 291.7 407.5 448H288z" } }, "free": ["solid"] }, "canadian-maple-leaf": { "changes": ["5.6.0", "5.8.0"], "ligatures": [], "search": { "terms": ["canada", "flag", "flora", "nature", "plant"] }, "styles": ["brands"], "unicode": "f785", "label": "Canadian Maple Leaf", "voted": false, "svg": { "brands": { "last_modified": 1660014459, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M383.8 351.7c2.5-2.5 105.2-92.4 105.2-92.4l-17.5-7.5c-10-4.9-7.4-11.5-5-17.4 2.4-7.6 20.1-67.3 20.1-67.3s-47.7 10-57.7 12.5c-7.5 2.4-10-2.5-12.5-7.5s-15-32.4-15-32.4-52.6 59.9-55.1 62.3c-10 7.5-20.1 0-17.6-10 0-10 27.6-129.6 27.6-129.6s-30.1 17.4-40.1 22.4c-7.5 5-12.6 5-17.6-5C293.5 72.3 255.9 0 255.9 0s-37.5 72.3-42.5 79.8c-5 10-10 10-17.6 5-10-5-40.1-22.4-40.1-22.4S183.3 182 183.3 192c2.5 10-7.5 17.5-17.6 10-2.5-2.5-55.1-62.3-55.1-62.3S98.1 167 95.6 172s-5 9.9-12.5 7.5C73 177 25.4 167 25.4 167s17.6 59.7 20.1 67.3c2.4 6 5 12.5-5 17.4L23 259.3s102.6 89.9 105.2 92.4c5.1 5 10 7.5 5.1 22.5-5.1 15-10.1 35.1-10.1 35.1s95.2-20.1 105.3-22.6c8.7-.9 18.3 2.5 18.3 12.5S241 512 241 512h30s-5.8-102.7-5.8-112.8 9.5-13.4 18.4-12.5c10 2.5 105.2 22.6 105.2 22.6s-5-20.1-10-35.1 0-17.5 5-22.5z" } }, "free": ["brands"] }, "candy-cane": { "aliases": { "unicodes": { "secondary": ["10f786"] } }, "changes": ["5.6.0", "5.10.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "candy", "christmas", "holiday", "mint", "peppermint", "striped", "xmas" ] }, "styles": ["solid"], "unicode": "f786", "label": "Candy Cane", "voted": false, "svg": { "solid": { "last_modified": 1684767420, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M348.8 131.5c3.7-2.3 7.9-3.5 12.2-3.5c12.7 0 23 10.3 23 23v5.6c0 9.9-5.1 19.1-13.5 24.3L30.1 393.7C.1 412.5-9 451.9 9.7 481.9s58.2 39.1 88.2 20.4L438.4 289.5c45.8-28.6 73.6-78.8 73.6-132.8V151C512 67.6 444.4 0 361 0c-28.3 0-56 8-80.1 23L254.1 39.7c-30 18.7-39.1 58.2-20.4 88.2s58.2 39.1 88.2 20.4l26.8-16.8zM298.4 49.8c9.2-5.7 19.1-10.1 29.4-13.1L348 97.5c-5.7 1.4-11.2 3.7-16.3 6.8l-12.6 7.9L298.4 49.8zm88.5 52.7l46.2-46.2c8.5 6.5 16.1 14.1 22.6 22.6l-46.2 46.2c-5.1-9.6-13-17.5-22.6-22.6zm28.9 59.3l61.6 20.5c-2.2 10.5-5.8 20.7-10.5 30.2l-62-20.7c6.2-8.8 10.1-19.1 11-30.1zm-86.1 82.5l60.4 37.7-30.2 18.9-60.4-37.7 30.2-18.9zm-107.2 67l60.4 37.7-30.2 18.9-60.4-37.7 30.2-18.9zM119.3 375.7l60.4 37.7-30.2 18.9L89.1 394.6l30.2-18.9z" } }, "free": ["solid"] }, "cannabis": { "aliases": { "unicodes": { "secondary": ["10f55f"] } }, "changes": ["5.1.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "bud", "chronic", "drugs", "endica", "endo", "ganja", "marijuana", "mary jane", "pot", "reefer", "sativa", "spliff", "weed", "whacky-tabacky" ] }, "styles": ["solid"], "unicode": "f55f", "label": "Cannabis", "voted": false, "svg": { "solid": { "last_modified": 1684768130, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 0c5.3 0 10.3 2.7 13.3 7.1c15.8 23.5 36.7 63.7 49.2 109c7.2 26.4 11.8 55.2 10.4 84c11.5-8.8 23.7-16.7 35.8-23.6c41-23.3 84.4-36.9 112.2-42.5c5.2-1 10.7 .6 14.4 4.4s5.4 9.2 4.4 14.5c-5.6 27.7-19.3 70.9-42.7 111.7c-9.1 15.9-19.9 31.7-32.4 46.3c27.8 6.6 52.4 17.3 67.2 25.5c5.1 2.8 8.2 8.2 8.2 14s-3.2 11.2-8.2 14c-15.2 8.4-40.9 19.5-69.8 26.1c-20.2 4.6-42.9 7.2-65.2 4.6l8.3 33.1c1.5 6.1-.6 12.4-5.5 16.4s-11.6 4.6-17.2 1.9L280 417.2V488c0 13.3-10.7 24-24 24s-24-10.7-24-24V417.2l-58.5 29.1c-5.6 2.8-12.3 2.1-17.2-1.9s-7-10.3-5.5-16.4l8.3-33.1c-22.2 2.6-45 0-65.2-4.6c-28.9-6.6-54.6-17.6-69.8-26.1c-5.1-2.8-8.2-8.2-8.2-14s3.2-11.2 8.2-14c14.8-8.2 39.4-18.8 67.2-25.5C78.9 296.3 68.1 280.5 59 264.6c-23.4-40.8-37.1-84-42.7-111.7c-1.1-5.2 .6-10.7 4.4-14.5s9.2-5.4 14.4-4.4c27.9 5.5 71.2 19.2 112.2 42.5c12.1 6.9 24.3 14.7 35.8 23.6c-1.4-28.7 3.1-57.6 10.4-84c12.5-45.3 33.4-85.5 49.2-109c3-4.4 8-7.1 13.3-7.1z" } }, "free": ["solid"] }, "capsules": { "aliases": { "unicodes": { "secondary": ["10f46b"] } }, "changes": ["5.0.7", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["drugs", "medicine", "pills", "prescription"] }, "styles": ["solid"], "unicode": "f46b", "label": "Capsules", "voted": false, "svg": { "solid": { "last_modified": 1684766751, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M64 144c0-26.5 21.5-48 48-48s48 21.5 48 48V256H64V144zM0 144V368c0 61.9 50.1 112 112 112s112-50.1 112-112V189.6c1.8 19.1 8.2 38 19.8 54.8L372.3 431.7c35.5 51.7 105.3 64.3 156 28.1s63-107.5 27.5-159.2L427.3 113.3C391.8 61.5 321.9 49 271.3 85.2c-28 20-44.3 50.8-47.3 83V144c0-61.9-50.1-112-112-112S0 82.1 0 144zm296.6 64.2c-16-23.3-10-55.3 11.9-71c21.2-15.1 50.5-10.3 66 12.2l67 97.6L361.6 303l-65-94.8zM491 407.7c-.8 .6-1.6 1.1-2.4 1.6l4-2.8c-.5 .4-1 .8-1.6 1.2z" } }, "free": ["solid"] }, "car": { "aliases": { "names": ["automobile"], "unicodes": { "composite": ["1f698"], "secondary": ["10f1b9"] } }, "changes": [ "4.1.0", "5.0.0", "5.2.0", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "auto", "automobile", "car", "oncoming", "oncoming automobile", "sedan", "transportation", "travel", "vehicle" ] }, "styles": ["solid"], "unicode": "f1b9", "label": "Car", "voted": false, "svg": { "solid": { "last_modified": 1684767649, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M135.2 117.4L109.1 192H402.9l-26.1-74.6C372.3 104.6 360.2 96 346.6 96H165.4c-13.6 0-25.7 8.6-30.2 21.4zM39.6 196.8L74.8 96.3C88.3 57.8 124.6 32 165.4 32H346.6c40.8 0 77.1 25.8 90.6 64.3l35.2 100.5c23.2 9.6 39.6 32.5 39.6 59.2V400v48c0 17.7-14.3 32-32 32H448c-17.7 0-32-14.3-32-32V400H96v48c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32V400 256c0-26.7 16.4-49.6 39.6-59.2zM128 288a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zm288 32a32 32 0 1 0 0-64 32 32 0 1 0 0 64z" } }, "free": ["solid"] }, "car-battery": { "aliases": { "names": ["battery-car"], "unicodes": { "secondary": ["10f5df"] } }, "changes": [ "5.2.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["auto", "electric", "mechanic", "power"] }, "styles": ["solid"], "unicode": "f5df", "label": "Car Battery", "voted": false, "svg": { "solid": { "last_modified": 1684767489, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M80 96c0-17.7 14.3-32 32-32h64c17.7 0 32 14.3 32 32l96 0c0-17.7 14.3-32 32-32h64c17.7 0 32 14.3 32 32h16c35.3 0 64 28.7 64 64V384c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V160c0-35.3 28.7-64 64-64l16 0zm304 96c0-8.8-7.2-16-16-16s-16 7.2-16 16v32H320c-8.8 0-16 7.2-16 16s7.2 16 16 16h32v32c0 8.8 7.2 16 16 16s16-7.2 16-16V256h32c8.8 0 16-7.2 16-16s-7.2-16-16-16H384V192zM80 240c0 8.8 7.2 16 16 16h96c8.8 0 16-7.2 16-16s-7.2-16-16-16H96c-8.8 0-16 7.2-16 16z" } }, "free": ["solid"] }, "car-burst": { "aliases": { "names": ["car-crash"], "unicodes": { "secondary": ["10f5e1"] } }, "changes": [ "5.2.0", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.1.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "accident", "auto", "automobile", "insurance", "sedan", "transportation", "vehicle", "wreck" ] }, "styles": ["solid"], "unicode": "f5e1", "label": "Car Burst", "voted": false, "svg": { "solid": { "last_modified": 1684767649, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M176 8c-6.6 0-12.4 4-14.9 10.1l-29.4 74L55.6 68.9c-6.3-1.9-13.1 .2-17.2 5.3s-4.6 12.2-1.4 17.9l39.5 69.1L10.9 206.4c-5.4 3.7-8 10.3-6.5 16.7s6.7 11.2 13.1 12.2l78.7 12.2L90.6 327c-.5 6.5 3.1 12.7 9 15.5s12.9 1.8 17.8-2.6l35.3-32.5 9.5-35.4 10.4-38.6c8-29.9 30.5-52.1 57.9-60.9l41-59.2c11.3-16.3 26.4-28.9 43.5-37.2c-.4-.6-.8-1.2-1.3-1.8c-4.1-5.1-10.9-7.2-17.2-5.3L220.3 92.1l-29.4-74C188.4 12 182.6 8 176 8zM367.7 161.5l135.6 36.3c6.5 1.8 11.3 7.4 11.8 14.2l4.6 56.5-201.5-54 32.2-46.6c3.8-5.6 10.8-8.1 17.3-6.4zm-69.9-30l-47.9 69.3c-21.6 3-40.3 18.6-46.3 41l-10.4 38.6-16.6 61.8-8.3 30.9c-4.6 17.1 5.6 34.6 22.6 39.2l15.5 4.1c17.1 4.6 34.6-5.6 39.2-22.6l8.3-30.9 247.3 66.3-8.3 30.9c-4.6 17.1 5.6 34.6 22.6 39.2l15.5 4.1c17.1 4.6 34.6-5.6 39.2-22.6l8.3-30.9L595 388l10.4-38.6c6-22.4-2.5-45.2-19.6-58.7l-6.8-84c-2.7-33.7-26.4-62-59-70.8L384.2 99.7c-32.7-8.8-67.3 4-86.5 31.8zm-17 131a24 24 0 1 1 -12.4 46.4 24 24 0 1 1 12.4-46.4zm217.9 83.2A24 24 0 1 1 545 358.1a24 24 0 1 1 -46.4-12.4z" } }, "free": ["solid"] }, "car-on": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["alarm", "car", "carjack", "warning"] }, "styles": ["solid"], "unicode": "e4dd", "label": "Car On", "voted": false, "svg": { "solid": { "last_modified": 1684767649, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M280 24c0-13.3-10.7-24-24-24s-24 10.7-24 24v80c0 13.3 10.7 24 24 24s24-10.7 24-24V24zM185.8 224H326.2c6.8 0 12.8 4.3 15.1 10.6L360.3 288H151.7l19.1-53.4c2.3-6.4 8.3-10.6 15.1-10.6zm-75.3-10.9L82.2 292.4C62.1 300.9 48 320.8 48 344v40 64 32c0 17.7 14.3 32 32 32H96c17.7 0 32-14.3 32-32V448H384v32c0 17.7 14.3 32 32 32h16c17.7 0 32-14.3 32-32V448 384 344c0-23.2-14.1-43.1-34.2-51.6l-28.3-79.3C390.1 181.3 360 160 326.2 160H185.8c-33.8 0-64 21.3-75.3 53.1zM128 344a24 24 0 1 1 0 48 24 24 0 1 1 0-48zm232 24a24 24 0 1 1 48 0 24 24 0 1 1 -48 0zM39 39c-9.4 9.4-9.4 24.6 0 33.9l48 48c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9L73 39c-9.4-9.4-24.6-9.4-33.9 0zm400 0L391 87c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l48-48c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0z" } }, "free": ["solid"] }, "car-rear": { "aliases": { "names": ["car-alt"], "unicodes": { "secondary": ["10f5de"] } }, "changes": [ "5.2.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "auto", "automobile", "sedan", "transportation", "travel", "vehicle" ] }, "styles": ["solid"], "unicode": "f5de", "label": "Car Rear", "voted": false, "svg": { "solid": { "last_modified": 1684767649, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M165.4 96H346.6c13.6 0 25.7 8.6 30.2 21.4L402.9 192H109.1l26.1-74.6c4.5-12.8 16.6-21.4 30.2-21.4zm-90.6 .3L39.6 196.8C16.4 206.4 0 229.3 0 256v80c0 23.7 12.9 44.4 32 55.4V448c0 17.7 14.3 32 32 32H96c17.7 0 32-14.3 32-32V400H384v48c0 17.7 14.3 32 32 32h32c17.7 0 32-14.3 32-32V391.4c19.1-11.1 32-31.7 32-55.4V256c0-26.7-16.4-49.6-39.6-59.2L437.2 96.3C423.7 57.8 387.4 32 346.6 32H165.4c-40.8 0-77.1 25.8-90.6 64.3zM208 272h96c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H208c-8.8 0-16-7.2-16-16V288c0-8.8 7.2-16 16-16zM48 280c0-13.3 10.7-24 24-24h32c13.3 0 24 10.7 24 24s-10.7 24-24 24H72c-13.3 0-24-10.7-24-24zm360-24h32c13.3 0 24 10.7 24 24s-10.7 24-24 24H408c-13.3 0-24-10.7-24-24s10.7-24 24-24z" } }, "free": ["solid"] }, "car-side": { "aliases": { "unicodes": { "composite": ["1f697"], "secondary": ["10f5e4"] } }, "changes": [ "5.2.0", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "auto", "automobile", "car", "sedan", "transportation", "travel", "vehicle" ] }, "styles": ["solid"], "unicode": "f5e4", "label": "Car Side", "voted": false, "svg": { "solid": { "last_modified": 1684767650, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M171.3 96H224v96H111.3l30.4-75.9C146.5 104 158.2 96 171.3 96zM272 192V96h81.2c9.7 0 18.9 4.4 25 12l67.2 84H272zm256.2 1L428.2 68c-18.2-22.8-45.8-36-75-36H171.3c-39.3 0-74.6 23.9-89.1 60.3L40.6 196.4C16.8 205.8 0 228.9 0 256V368c0 17.7 14.3 32 32 32H65.3c7.6 45.4 47.1 80 94.7 80s87.1-34.6 94.7-80H385.3c7.6 45.4 47.1 80 94.7 80s87.1-34.6 94.7-80H608c17.7 0 32-14.3 32-32V320c0-65.2-48.8-119-111.8-127zM434.7 368a48 48 0 1 1 90.5 32 48 48 0 1 1 -90.5-32zM160 336a48 48 0 1 1 0 96 48 48 0 1 1 0-96z" } }, "free": ["solid"] }, "car-tunnel": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["road", "tunnel"] }, "styles": ["solid"], "unicode": "e4de", "label": "Car Tunnel", "voted": false, "svg": { "solid": { "last_modified": 1684767649, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 0C114.6 0 0 114.6 0 256V448c0 35.3 28.7 64 64 64h42.8c-6.6-5.9-10.8-14.4-10.8-24V376c0-20.8 11.3-38.9 28.1-48.6l21-64.7c7.5-23.1 29-38.7 53.3-38.7H313.6c24.3 0 45.8 15.6 53.3 38.7l21 64.7c16.8 9.7 28.2 27.8 28.2 48.6V488c0 9.6-4.2 18.1-10.8 24H448c35.3 0 64-28.7 64-64V256C512 114.6 397.4 0 256 0zM362.8 512c-6.6-5.9-10.8-14.4-10.8-24V448H160v40c0 9.6-4.2 18.1-10.8 24H362.8zM190.8 277.5L177 320H335l-13.8-42.5c-1.1-3.3-4.1-5.5-7.6-5.5H198.4c-3.5 0-6.5 2.2-7.6 5.5zM168 408a24 24 0 1 0 0-48 24 24 0 1 0 0 48zm200-24a24 24 0 1 0 -48 0 24 24 0 1 0 48 0z" } }, "free": ["solid"] }, "caravan": { "aliases": { "unicodes": { "secondary": ["10f8ff"] } }, "changes": [ "5.12.0", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["camper", "motor home", "rv", "trailer", "travel"] }, "styles": ["solid"], "unicode": "f8ff", "label": "Caravan", "voted": true, "svg": { "solid": { "last_modified": 1684767649, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M0 112C0 67.8 35.8 32 80 32H416c88.4 0 160 71.6 160 160V352h32c17.7 0 32 14.3 32 32s-14.3 32-32 32l-32 0H288c0 53-43 96-96 96s-96-43-96-96H80c-44.2 0-80-35.8-80-80V112zM320 352H448V256H416c-8.8 0-16-7.2-16-16s7.2-16 16-16h32V160c0-17.7-14.3-32-32-32H352c-17.7 0-32 14.3-32 32V352zM96 128c-17.7 0-32 14.3-32 32v64c0 17.7 14.3 32 32 32H224c17.7 0 32-14.3 32-32V160c0-17.7-14.3-32-32-32H96zm96 336a48 48 0 1 0 0-96 48 48 0 1 0 0 96z" } }, "free": ["solid"] }, "caret-down": { "aliases": { "unicodes": { "secondary": ["10f0d7"] } }, "changes": ["2.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["arrow", "dropdown", "expand", "menu", "more", "triangle"] }, "styles": ["solid"], "unicode": "f0d7", "label": "Caret Down", "voted": false, "svg": { "solid": { "last_modified": 1684766329, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M137.4 374.6c12.5 12.5 32.8 12.5 45.3 0l128-128c9.2-9.2 11.9-22.9 6.9-34.9s-16.6-19.8-29.6-19.8L32 192c-12.9 0-24.6 7.8-29.6 19.8s-2.2 25.7 6.9 34.9l128 128z" } }, "free": ["solid"] }, "caret-left": { "aliases": { "unicodes": { "secondary": ["10f0d9"] } }, "changes": ["2.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["arrow", "back", "previous", "triangle"] }, "styles": ["solid"], "unicode": "f0d9", "label": "Caret Left", "voted": false, "svg": { "solid": { "last_modified": 1684766332, "raw": "", "viewBox": [0, 0, 256, 512], "width": 256, "height": 512, "path": "M9.4 278.6c-12.5-12.5-12.5-32.8 0-45.3l128-128c9.2-9.2 22.9-11.9 34.9-6.9s19.8 16.6 19.8 29.6l0 256c0 12.9-7.8 24.6-19.8 29.6s-25.7 2.2-34.9-6.9l-128-128z" } }, "free": ["solid"] }, "caret-right": { "aliases": { "unicodes": { "secondary": ["10f0da"] } }, "changes": ["2.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["arrow", "forward", "next", "triangle"] }, "styles": ["solid"], "unicode": "f0da", "label": "Caret Right", "voted": false, "svg": { "solid": { "last_modified": 1684766332, "raw": "", "viewBox": [0, 0, 256, 512], "width": 256, "height": 512, "path": "M246.6 278.6c12.5-12.5 12.5-32.8 0-45.3l-128-128c-9.2-9.2-22.9-11.9-34.9-6.9s-19.8 16.6-19.8 29.6l0 256c0 12.9 7.8 24.6 19.8 29.6s25.7 2.2 34.9-6.9l128-128z" } }, "free": ["solid"] }, "caret-up": { "aliases": { "unicodes": { "secondary": ["10f0d8"] } }, "changes": ["2.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["arrow", "collapse", "triangle"] }, "styles": ["solid"], "unicode": "f0d8", "label": "Caret Up", "voted": false, "svg": { "solid": { "last_modified": 1684766331, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M182.6 137.4c-12.5-12.5-32.8-12.5-45.3 0l-128 128c-9.2 9.2-11.9 22.9-6.9 34.9s16.6 19.8 29.6 19.8H288c12.9 0 24.6-7.8 29.6-19.8s2.2-25.7-6.9-34.9l-128-128z" } }, "free": ["solid"] }, "carrot": { "aliases": { "unicodes": { "composite": ["1f955"], "secondary": ["10f787"] } }, "changes": ["5.6.0", "5.10.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["bugs bunny", "carrot", "food", "orange", "vegan", "vegetable"] }, "styles": ["solid"], "unicode": "f787", "label": "Carrot", "voted": false, "svg": { "solid": { "last_modified": 1684767418, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M346.7 6C337.6 17 320 42.3 320 72c0 40 15.3 55.3 40 80s40 40 80 40c29.7 0 55-17.6 66-26.7c4-3.3 6-8.2 6-13.3s-2-10-6-13.2c-11.4-9.1-38.3-26.8-74-26.8c-32 0-40 8-40 8s8-8 8-40c0-35.7-17.7-62.6-26.8-74C370 2 365.1 0 360 0s-10 2-13.3 6zM244.6 136c-40 0-77.1 18.1-101.7 48.2l60.5 60.5c6.2 6.2 6.2 16.4 0 22.6s-16.4 6.2-22.6 0l-55.3-55.3 0 .1L2.2 477.9C-2 487-.1 497.8 7 505s17.9 9 27.1 4.8l134.7-62.4-52.1-52.1c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0L199.7 433l100.2-46.4c46.4-21.5 76.2-68 76.2-119.2C376 194.8 317.2 136 244.6 136z" } }, "free": ["solid"] }, "cart-arrow-down": { "aliases": { "unicodes": { "secondary": ["10f218"] } }, "changes": [ "4.3.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.2.1", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["download", "save", "shopping"] }, "styles": ["solid"], "unicode": "f218", "label": "Cart Arrow Down", "voted": false, "svg": { "solid": { "last_modified": 1684766475, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M24 0C10.7 0 0 10.7 0 24S10.7 48 24 48H69.5c3.8 0 7.1 2.7 7.9 6.5l51.6 271c6.5 34 36.2 58.5 70.7 58.5H488c13.3 0 24-10.7 24-24s-10.7-24-24-24H199.7c-11.5 0-21.4-8.2-23.6-19.5L170.7 288H459.2c32.6 0 61.1-21.8 69.5-53.3l41-152.3C576.6 57 557.4 32 531.1 32H360V134.1l23-23c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-64 64c-9.4 9.4-24.6 9.4-33.9 0l-64-64c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l23 23V32H120.1C111 12.8 91.6 0 69.5 0H24zM176 512a48 48 0 1 0 0-96 48 48 0 1 0 0 96zm336-48a48 48 0 1 0 -96 0 48 48 0 1 0 96 0z" } }, "free": ["solid"] }, "cart-flatbed": { "aliases": { "names": ["dolly-flatbed"], "unicodes": { "secondary": ["10f474"] } }, "changes": ["5.0.7", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["carry", "inventory", "shipping", "transport"] }, "styles": ["solid"], "unicode": "f474", "label": "Cart Flatbed", "voted": false, "svg": { "solid": { "last_modified": 1684767442, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M32 0C14.3 0 0 14.3 0 32S14.3 64 32 64H48c8.8 0 16 7.2 16 16V368c0 44.2 35.8 80 80 80h18.7c-1.8 5-2.7 10.4-2.7 16c0 26.5 21.5 48 48 48s48-21.5 48-48c0-5.6-1-11-2.7-16H450.7c-1.8 5-2.7 10.4-2.7 16c0 26.5 21.5 48 48 48s48-21.5 48-48c0-5.6-1-11-2.7-16H608c17.7 0 32-14.3 32-32s-14.3-32-32-32H144c-8.8 0-16-7.2-16-16V80C128 35.8 92.2 0 48 0H32zM192 80V272c0 26.5 21.5 48 48 48H560c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48H464V176c0 5.9-3.2 11.3-8.5 14.1s-11.5 2.5-16.4-.8L400 163.2l-39.1 26.1c-4.9 3.3-11.2 3.6-16.4 .8s-8.5-8.2-8.5-14.1V32H240c-26.5 0-48 21.5-48 48z" } }, "free": ["solid"] }, "cart-flatbed-suitcase": { "aliases": { "names": ["luggage-cart"], "unicodes": { "secondary": ["10f59d"] } }, "changes": [ "5.1.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["airport", "bag", "baggage", "suitcase", "travel"] }, "styles": ["solid"], "unicode": "f59d", "label": "Cart Flatbed Suitcase", "voted": false, "svg": { "solid": { "last_modified": 1684767441, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M0 32C0 14.3 14.3 0 32 0H48c44.2 0 80 35.8 80 80V368c0 8.8 7.2 16 16 16H608c17.7 0 32 14.3 32 32s-14.3 32-32 32H541.3c1.8 5 2.7 10.4 2.7 16c0 26.5-21.5 48-48 48s-48-21.5-48-48c0-5.6 1-11 2.7-16H253.3c1.8 5 2.7 10.4 2.7 16c0 26.5-21.5 48-48 48s-48-21.5-48-48c0-5.6 1-11 2.7-16H144c-44.2 0-80-35.8-80-80V80c0-8.8-7.2-16-16-16H32C14.3 64 0 49.7 0 32zM432 96V56c0-4.4-3.6-8-8-8H344c-4.4 0-8 3.6-8 8V96h96zM288 96V56c0-30.9 25.1-56 56-56h80c30.9 0 56 25.1 56 56V96 320H288V96zM512 320V96h16c26.5 0 48 21.5 48 48V272c0 26.5-21.5 48-48 48H512zM240 96h16V320H240c-26.5 0-48-21.5-48-48V144c0-26.5 21.5-48 48-48z" } }, "free": ["solid"] }, "cart-plus": { "aliases": { "unicodes": { "secondary": ["10f217"] } }, "changes": [ "4.3.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.2.1", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["add", "create", "new", "positive", "shopping"] }, "styles": ["solid"], "unicode": "f217", "label": "Cart Plus", "voted": false, "svg": { "solid": { "last_modified": 1684766476, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M0 24C0 10.7 10.7 0 24 0H69.5c22 0 41.5 12.8 50.6 32h411c26.3 0 45.5 25 38.6 50.4l-41 152.3c-8.5 31.4-37 53.3-69.5 53.3H170.7l5.4 28.5c2.2 11.3 12.1 19.5 23.6 19.5H488c13.3 0 24 10.7 24 24s-10.7 24-24 24H199.7c-34.6 0-64.3-24.6-70.7-58.5L77.4 54.5c-.7-3.8-4-6.5-7.9-6.5H24C10.7 48 0 37.3 0 24zM128 464a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zm336-48a48 48 0 1 1 0 96 48 48 0 1 1 0-96zM252 160c0 11 9 20 20 20h44v44c0 11 9 20 20 20s20-9 20-20V180h44c11 0 20-9 20-20s-9-20-20-20H356V96c0-11-9-20-20-20s-20 9-20 20v44H272c-11 0-20 9-20 20z" } }, "free": ["solid"] }, "cart-shopping": { "aliases": { "names": ["shopping-cart"], "unicodes": { "composite": ["1f6d2"], "secondary": ["10f07a"] } }, "changes": [ "1.0.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.2.1", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "buy", "cart", "checkout", "grocery", "payment", "purchase", "shopping", "shopping cart", "trolley" ] }, "styles": ["solid"], "unicode": "f07a", "label": "Cart Shopping", "voted": false, "svg": { "solid": { "last_modified": 1684766475, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M0 24C0 10.7 10.7 0 24 0H69.5c22 0 41.5 12.8 50.6 32h411c26.3 0 45.5 25 38.6 50.4l-41 152.3c-8.5 31.4-37 53.3-69.5 53.3H170.7l5.4 28.5c2.2 11.3 12.1 19.5 23.6 19.5H488c13.3 0 24 10.7 24 24s-10.7 24-24 24H199.7c-34.6 0-64.3-24.6-70.7-58.5L77.4 54.5c-.7-3.8-4-6.5-7.9-6.5H24C10.7 48 0 37.3 0 24zM128 464a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zm336-48a48 48 0 1 1 0 96 48 48 0 1 1 0-96z" } }, "free": ["solid"] }, "cash-register": { "aliases": { "unicodes": { "secondary": ["10f788"] } }, "changes": [ "5.6.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "buy", "cha-ching", "change", "checkout", "commerce", "leaerboard", "machine", "pay", "payment", "purchase", "store" ] }, "styles": ["solid"], "unicode": "f788", "label": "Cash Register", "voted": true, "svg": { "solid": { "last_modified": 1684766476, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M64 0C46.3 0 32 14.3 32 32V96c0 17.7 14.3 32 32 32h80v32H87c-31.6 0-58.5 23.1-63.3 54.4L1.1 364.1C.4 368.8 0 373.6 0 378.4V448c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V378.4c0-4.8-.4-9.6-1.1-14.4L488.2 214.4C483.5 183.1 456.6 160 425 160H208V128h80c17.7 0 32-14.3 32-32V32c0-17.7-14.3-32-32-32H64zM96 48H256c8.8 0 16 7.2 16 16s-7.2 16-16 16H96c-8.8 0-16-7.2-16-16s7.2-16 16-16zM64 432c0-8.8 7.2-16 16-16H432c8.8 0 16 7.2 16 16s-7.2 16-16 16H80c-8.8 0-16-7.2-16-16zm48-168a24 24 0 1 1 0-48 24 24 0 1 1 0 48zm120-24a24 24 0 1 1 -48 0 24 24 0 1 1 48 0zM160 344a24 24 0 1 1 0-48 24 24 0 1 1 0 48zM328 240a24 24 0 1 1 -48 0 24 24 0 1 1 48 0zM256 344a24 24 0 1 1 0-48 24 24 0 1 1 0 48zM424 240a24 24 0 1 1 -48 0 24 24 0 1 1 48 0zM352 344a24 24 0 1 1 0-48 24 24 0 1 1 0 48z" } }, "free": ["solid"] }, "cat": { "aliases": { "unicodes": { "composite": ["1f408"], "secondary": ["10f6be"] } }, "changes": ["5.4.0", "5.10.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "cat", "feline", "halloween", "holiday", "kitten", "kitty", "meow", "pet" ] }, "styles": ["solid"], "unicode": "f6be", "label": "Cat", "voted": true, "svg": { "solid": { "last_modified": 1684768130, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M320 192h17.1c22.1 38.3 63.5 64 110.9 64c11 0 21.8-1.4 32-4v4 32V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V339.2L280 448h56c17.7 0 32 14.3 32 32s-14.3 32-32 32H192c-53 0-96-43-96-96V192.5c0-16.1-12-29.8-28-31.8l-7.9-1c-17.5-2.2-30-18.2-27.8-35.7s18.2-30 35.7-27.8l7.9 1c48 6 84.1 46.8 84.1 95.3v85.3c34.4-51.7 93.2-85.8 160-85.8zm160 26.5v0c-10 3.5-20.8 5.5-32 5.5c-28.4 0-54-12.4-71.6-32h0c-3.7-4.1-7-8.5-9.9-13.2C357.3 164 352 146.6 352 128v0V32 12 10.7C352 4.8 356.7 .1 362.6 0h.2c3.3 0 6.4 1.6 8.4 4.2l0 .1L384 21.3l27.2 36.3L416 64h64l4.8-6.4L512 21.3 524.8 4.3l0-.1c2-2.6 5.1-4.2 8.4-4.2h.2C539.3 .1 544 4.8 544 10.7V12 32v96c0 17.3-4.6 33.6-12.6 47.6c-11.3 19.8-29.6 35.2-51.4 42.9zM432 128a16 16 0 1 0 -32 0 16 16 0 1 0 32 0zm48 16a16 16 0 1 0 0-32 16 16 0 1 0 0 32z" } }, "free": ["solid"] }, "cc-amazon-pay": { "changes": ["5.0.2"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f42d", "label": "Amazon Pay Credit Card", "voted": false, "svg": { "brands": { "last_modified": 1660014466, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M124.7 201.8c.1-11.8 0-23.5 0-35.3v-35.3c0-1.3.4-2 1.4-2.7 11.5-8 24.1-12.1 38.2-11.1 12.5.9 22.7 7 28.1 21.7 3.3 8.9 4.1 18.2 4.1 27.7 0 8.7-.7 17.3-3.4 25.6-5.7 17.8-18.7 24.7-35.7 23.9-11.7-.5-21.9-5-31.4-11.7-.9-.8-1.4-1.6-1.3-2.8zm154.9 14.6c4.6 1.8 9.3 2 14.1 1.5 11.6-1.2 21.9-5.7 31.3-12.5.9-.6 1.3-1.3 1.3-2.5-.1-3.9 0-7.9 0-11.8 0-4-.1-8 0-12 0-1.4-.4-2-1.8-2.2-7-.9-13.9-2.2-20.9-2.9-7-.6-14-.3-20.8 1.9-6.7 2.2-11.7 6.2-13.7 13.1-1.6 5.4-1.6 10.8.1 16.2 1.6 5.5 5.2 9.2 10.4 11.2zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zm-207.5 23.9c.4 1.7.9 3.4 1.6 5.1 16.5 40.6 32.9 81.3 49.5 121.9 1.4 3.5 1.7 6.4.2 9.9-2.8 6.2-4.9 12.6-7.8 18.7-2.6 5.5-6.7 9.5-12.7 11.2-4.2 1.1-8.5 1.3-12.9.9-2.1-.2-4.2-.7-6.3-.8-2.8-.2-4.2 1.1-4.3 4-.1 2.8-.1 5.6 0 8.3.1 4.6 1.6 6.7 6.2 7.5 4.7.8 9.4 1.6 14.2 1.7 14.3.3 25.7-5.4 33.1-17.9 2.9-4.9 5.6-10.1 7.7-15.4 19.8-50.1 39.5-100.3 59.2-150.5.6-1.5 1.1-3 1.3-4.6.4-2.4-.7-3.6-3.1-3.7-5.6-.1-11.1 0-16.7 0-3.1 0-5.3 1.4-6.4 4.3-.4 1.1-.9 2.3-1.3 3.4l-29.1 83.7c-2.1 6.1-4.2 12.1-6.5 18.6-.4-.9-.6-1.4-.8-1.9-10.8-29.9-21.6-59.9-32.4-89.8-1.7-4.7-3.5-9.5-5.3-14.2-.9-2.5-2.7-4-5.4-4-6.4-.1-12.8-.2-19.2-.1-2.2 0-3.3 1.6-2.8 3.7zM242.4 206c1.7 11.7 7.6 20.8 18 26.6 9.9 5.5 20.7 6.2 31.7 4.6 12.7-1.9 23.9-7.3 33.8-15.5.4-.3.8-.6 1.4-1 .5 3.2.9 6.2 1.5 9.2.5 2.6 2.1 4.3 4.5 4.4 4.6.1 9.1.1 13.7 0 2.3-.1 3.8-1.6 4-3.9.1-.8.1-1.6.1-2.3v-88.8c0-3.6-.2-7.2-.7-10.8-1.6-10.8-6.2-19.7-15.9-25.4-5.6-3.3-11.8-5-18.2-5.9-3-.4-6-.7-9.1-1.1h-10c-.8.1-1.6.3-2.5.3-8.2.4-16.3 1.4-24.2 3.5-5.1 1.3-10 3.2-15 4.9-3 1-4.5 3.2-4.4 6.5.1 2.8-.1 5.6 0 8.3.1 4.1 1.8 5.2 5.7 4.1 6.5-1.7 13.1-3.5 19.7-4.8 10.3-1.9 20.7-2.7 31.1-1.2 5.4.8 10.5 2.4 14.1 7 3.1 4 4.2 8.8 4.4 13.7.3 6.9.2 13.9.3 20.8 0 .4-.1.7-.2 1.2-.4 0-.8 0-1.1-.1-8.8-2.1-17.7-3.6-26.8-4.1-9.5-.5-18.9.1-27.9 3.2-10.8 3.8-19.5 10.3-24.6 20.8-4.1 8.3-4.6 17-3.4 25.8zM98.7 106.9v175.3c0 .8 0 1.7.1 2.5.2 2.5 1.7 4.1 4.1 4.2 5.9.1 11.8.1 17.7 0 2.5 0 4-1.7 4.1-4.1.1-.8.1-1.7.1-2.5v-60.7c.9.7 1.4 1.2 1.9 1.6 15 12.5 32.2 16.6 51.1 12.9 17.1-3.4 28.9-13.9 36.7-29.2 5.8-11.6 8.3-24.1 8.7-37 .5-14.3-1-28.4-6.8-41.7-7.1-16.4-18.9-27.3-36.7-30.9-2.7-.6-5.5-.8-8.2-1.2h-7c-1.2.2-2.4.3-3.6.5-11.7 1.4-22.3 5.8-31.8 12.7-2 1.4-3.9 3-5.9 4.5-.1-.5-.3-.8-.4-1.2-.4-2.3-.7-4.6-1.1-6.9-.6-3.9-2.5-5.5-6.4-5.6h-9.7c-5.9-.1-6.9 1-6.9 6.8zM493.6 339c-2.7-.7-5.1 0-7.6 1-43.9 18.4-89.5 30.2-136.8 35.8-14.5 1.7-29.1 2.8-43.7 3.2-26.6.7-53.2-.8-79.6-4.3-17.8-2.4-35.5-5.7-53-9.9-37-8.9-72.7-21.7-106.7-38.8-8.8-4.4-17.4-9.3-26.1-14-3.8-2.1-6.2-1.5-8.2 2.1v1.7c1.2 1.6 2.2 3.4 3.7 4.8 36 32.2 76.6 56.5 122 72.9 21.9 7.9 44.4 13.7 67.3 17.5 14 2.3 28 3.8 42.2 4.5 3 .1 6 .2 9 .4.7 0 1.4.2 2.1.3h17.7c.7-.1 1.4-.3 2.1-.3 14.9-.4 29.8-1.8 44.6-4 21.4-3.2 42.4-8.1 62.9-14.7 29.6-9.6 57.7-22.4 83.4-40.1 2.8-1.9 5.7-3.8 8-6.2 4.3-4.4 2.3-10.4-3.3-11.9zm50.4-27.7c-.8-4.2-4-5.8-7.6-7-5.7-1.9-11.6-2.8-17.6-3.3-11-.9-22-.4-32.8 1.6-12 2.2-23.4 6.1-33.5 13.1-1.2.8-2.4 1.8-3.1 3-.6.9-.7 2.3-.5 3.4.3 1.3 1.7 1.6 3 1.5.6 0 1.2 0 1.8-.1l19.5-2.1c9.6-.9 19.2-1.5 28.8-.8 4.1.3 8.1 1.2 12 2.2 4.3 1.1 6.2 4.4 6.4 8.7.3 6.7-1.2 13.1-2.9 19.5-3.5 12.9-8.3 25.4-13.3 37.8-.3.8-.7 1.7-.8 2.5-.4 2.5 1 4 3.4 3.5 1.4-.3 3-1.1 4-2.1 3.7-3.6 7.5-7.2 10.6-11.2 10.7-13.8 17-29.6 20.7-46.6.7-3 1.2-6.1 1.7-9.1.2-4.7.2-9.6.2-14.5z" } }, "free": ["brands"] }, "cc-amex": { "changes": ["4.2.0", "5.0.0", "5.7.0", "6.1.2"], "ligatures": [], "search": { "terms": ["amex"] }, "styles": ["brands"], "unicode": "f1f3", "label": "American Express Credit Card", "voted": false, "svg": { "brands": { "last_modified": 1660014462, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M48 480C21.49 480 0 458.5 0 432V80C0 53.49 21.49 32 48 32H528C554.5 32 576 53.49 576 80V82.43H500.5L483.5 130L466.6 82.43H369.4V145.6L341.3 82.43H262.7L181 267.1H246.8V430.9H450.5L482.4 395.8L514.3 430.9H576V432C576 458.5 554.5 480 528 480H48zM482.6 364L440.4 410.3H390.5L458 338.6L390.5 266.1H441.9L483.4 312.8L525.4 266.1H576L508 338.2L576 410.3H524.6L482.6 364zM576 296.9V380.2L536.7 338.3L576 296.9zM307.6 377.1H390.6V410.3H268.6V267.1H390.6V300.2H307.6V322.6H388.5V354.9H307.6V377.2V377.1zM537.3 145.7L500.4 246.3H466L429.2 146V246.3H390.5V103H451.7L483.6 192.3L515.8 103H576V246.3H537.3V145.7zM334.5 217.6H268.6L256.7 246.3H213.7L276.1 103H327.3L390.6 246.3H346.5L334.5 217.6zM301.5 138.5L282 185.4H320.9L301.5 138.5z" } }, "free": ["brands"] }, "cc-apple-pay": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f416", "label": "Apple Pay Credit Card", "voted": false, "svg": { "brands": { "last_modified": 1660014477, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M302.2 218.4c0 17.2-10.5 27.1-29 27.1h-24.3v-54.2h24.4c18.4 0 28.9 9.8 28.9 27.1zm47.5 62.6c0 8.3 7.2 13.7 18.5 13.7 14.4 0 25.2-9.1 25.2-21.9v-7.7l-23.5 1.5c-13.3.9-20.2 5.8-20.2 14.4zM576 79v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V79c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM127.8 197.2c8.4.7 16.8-4.2 22.1-10.4 5.2-6.4 8.6-15 7.7-23.7-7.4.3-16.6 4.9-21.9 11.3-4.8 5.5-8.9 14.4-7.9 22.8zm60.6 74.5c-.2-.2-19.6-7.6-19.8-30-.2-18.7 15.3-27.7 16-28.2-8.8-13-22.4-14.4-27.1-14.7-12.2-.7-22.6 6.9-28.4 6.9-5.9 0-14.7-6.6-24.3-6.4-12.5.2-24.2 7.3-30.5 18.6-13.1 22.6-3.4 56 9.3 74.4 6.2 9.1 13.7 19.1 23.5 18.7 9.3-.4 13-6 24.2-6 11.3 0 14.5 6 24.3 5.9 10.2-.2 16.5-9.1 22.8-18.2 6.9-10.4 9.8-20.4 10-21zm135.4-53.4c0-26.6-18.5-44.8-44.9-44.8h-51.2v136.4h21.2v-46.6h29.3c26.8 0 45.6-18.4 45.6-45zm90 23.7c0-19.7-15.8-32.4-40-32.4-22.5 0-39.1 12.9-39.7 30.5h19.1c1.6-8.4 9.4-13.9 20-13.9 13 0 20.2 6 20.2 17.2v7.5l-26.4 1.6c-24.6 1.5-37.9 11.6-37.9 29.1 0 17.7 13.7 29.4 33.4 29.4 13.3 0 25.6-6.7 31.2-17.4h.4V310h19.6v-68zM516 210.9h-21.5l-24.9 80.6h-.4l-24.9-80.6H422l35.9 99.3-1.9 6c-3.2 10.2-8.5 14.2-17.9 14.2-1.7 0-4.9-.2-6.2-.3v16.4c1.2.4 6.5.5 8.1.5 20.7 0 30.4-7.9 38.9-31.8L516 210.9z" } }, "free": ["brands"] }, "cc-diners-club": { "changes": ["4.4.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f24c", "label": "Diner's Club Credit Card", "voted": false, "svg": { "brands": { "last_modified": 1660014464, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M239.7 79.9c-96.9 0-175.8 78.6-175.8 175.8 0 96.9 78.9 175.8 175.8 175.8 97.2 0 175.8-78.9 175.8-175.8 0-97.2-78.6-175.8-175.8-175.8zm-39.9 279.6c-41.7-15.9-71.4-56.4-71.4-103.8s29.7-87.9 71.4-104.1v207.9zm79.8.3V151.6c41.7 16.2 71.4 56.7 71.4 104.1s-29.7 87.9-71.4 104.1zM528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM329.7 448h-90.3c-106.2 0-193.8-85.5-193.8-190.2C45.6 143.2 133.2 64 239.4 64h90.3c105 0 200.7 79.2 200.7 193.8 0 104.7-95.7 190.2-200.7 190.2z" } }, "free": ["brands"] }, "cc-discover": { "changes": ["4.2.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f1f2", "label": "Discover Credit Card", "voted": false, "svg": { "brands": { "last_modified": 1660014474, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M520.4 196.1c0-7.9-5.5-12.1-15.6-12.1h-4.9v24.9h4.7c10.3 0 15.8-4.4 15.8-12.8zM528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-44.1 138.9c22.6 0 52.9-4.1 52.9 24.4 0 12.6-6.6 20.7-18.7 23.2l25.8 34.4h-19.6l-22.2-32.8h-2.2v32.8h-16zm-55.9.1h45.3v14H444v18.2h28.3V217H444v22.2h29.3V253H428zm-68.7 0l21.9 55.2 22.2-55.2h17.5l-35.5 84.2h-8.6l-35-84.2zm-55.9-3c24.7 0 44.6 20 44.6 44.6 0 24.7-20 44.6-44.6 44.6-24.7 0-44.6-20-44.6-44.6 0-24.7 20-44.6 44.6-44.6zm-49.3 6.1v19c-20.1-20.1-46.8-4.7-46.8 19 0 25 27.5 38.5 46.8 19.2v19c-29.7 14.3-63.3-5.7-63.3-38.2 0-31.2 33.1-53 63.3-38zm-97.2 66.3c11.4 0 22.4-15.3-3.3-24.4-15-5.5-20.2-11.4-20.2-22.7 0-23.2 30.6-31.4 49.7-14.3l-8.4 10.8c-10.4-11.6-24.9-6.2-24.9 2.5 0 4.4 2.7 6.9 12.3 10.3 18.2 6.6 23.6 12.5 23.6 25.6 0 29.5-38.8 37.4-56.6 11.3l10.3-9.9c3.7 7.1 9.9 10.8 17.5 10.8zM55.4 253H32v-82h23.4c26.1 0 44.1 17 44.1 41.1 0 18.5-13.2 40.9-44.1 40.9zm67.5 0h-16v-82h16zM544 433c0 8.2-6.8 15-15 15H128c189.6-35.6 382.7-139.2 416-160zM74.1 191.6c-5.2-4.9-11.6-6.6-21.9-6.6H48v54.2h4.2c10.3 0 17-2 21.9-6.4 5.7-5.2 8.9-12.8 8.9-20.7s-3.2-15.5-8.9-20.5z" } }, "free": ["brands"] }, "cc-jcb": { "changes": ["4.4.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f24b", "label": "JCB Credit Card", "voted": false, "svg": { "brands": { "last_modified": 1660014463, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M431.5 244.3V212c41.2 0 38.5.2 38.5.2 7.3 1.3 13.3 7.3 13.3 16 0 8.8-6 14.5-13.3 15.8-1.2.4-3.3.3-38.5.3zm42.8 20.2c-2.8-.7-3.3-.5-42.8-.5v35c39.6 0 40 .2 42.8-.5 7.5-1.5 13.5-8 13.5-17 0-8.7-6-15.5-13.5-17zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM182 192.3h-57c0 67.1 10.7 109.7-35.8 109.7-19.5 0-38.8-5.7-57.2-14.8v28c30 8.3 68 8.3 68 8.3 97.9 0 82-47.7 82-131.2zm178.5 4.5c-63.4-16-165-14.9-165 59.3 0 77.1 108.2 73.6 165 59.2V287C312.9 311.7 253 309 253 256s59.8-55.6 107.5-31.2v-28zM544 286.5c0-18.5-16.5-30.5-38-32v-.8c19.5-2.7 30.3-15.5 30.3-30.2 0-19-15.7-30-37-31 0 0 6.3-.3-120.3-.3v127.5h122.7c24.3.1 42.3-12.9 42.3-33.2z" } }, "free": ["brands"] }, "cc-mastercard": { "changes": ["4.2.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f1f1", "label": "MasterCard Credit Card", "voted": false, "svg": { "brands": { "last_modified": 1660014476, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M482.9 410.3c0 6.8-4.6 11.7-11.2 11.7-6.8 0-11.2-5.2-11.2-11.7 0-6.5 4.4-11.7 11.2-11.7 6.6 0 11.2 5.2 11.2 11.7zm-310.8-11.7c-7.1 0-11.2 5.2-11.2 11.7 0 6.5 4.1 11.7 11.2 11.7 6.5 0 10.9-4.9 10.9-11.7-.1-6.5-4.4-11.7-10.9-11.7zm117.5-.3c-5.4 0-8.7 3.5-9.5 8.7h19.1c-.9-5.7-4.4-8.7-9.6-8.7zm107.8.3c-6.8 0-10.9 5.2-10.9 11.7 0 6.5 4.1 11.7 10.9 11.7 6.8 0 11.2-4.9 11.2-11.7 0-6.5-4.4-11.7-11.2-11.7zm105.9 26.1c0 .3.3.5.3 1.1 0 .3-.3.5-.3 1.1-.3.3-.3.5-.5.8-.3.3-.5.5-1.1.5-.3.3-.5.3-1.1.3-.3 0-.5 0-1.1-.3-.3 0-.5-.3-.8-.5-.3-.3-.5-.5-.5-.8-.3-.5-.3-.8-.3-1.1 0-.5 0-.8.3-1.1 0-.5.3-.8.5-1.1.3-.3.5-.3.8-.5.5-.3.8-.3 1.1-.3.5 0 .8 0 1.1.3.5.3.8.3 1.1.5s.2.6.5 1.1zm-2.2 1.4c.5 0 .5-.3.8-.3.3-.3.3-.5.3-.8 0-.3 0-.5-.3-.8-.3 0-.5-.3-1.1-.3h-1.6v3.5h.8V426h.3l1.1 1.4h.8l-1.1-1.3zM576 81v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V81c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM64 220.6c0 76.5 62.1 138.5 138.5 138.5 27.2 0 53.9-8.2 76.5-23.1-72.9-59.3-72.4-171.2 0-230.5-22.6-15-49.3-23.1-76.5-23.1-76.4-.1-138.5 62-138.5 138.2zm224 108.8c70.5-55 70.2-162.2 0-217.5-70.2 55.3-70.5 162.6 0 217.5zm-142.3 76.3c0-8.7-5.7-14.4-14.7-14.7-4.6 0-9.5 1.4-12.8 6.5-2.4-4.1-6.5-6.5-12.2-6.5-3.8 0-7.6 1.4-10.6 5.4V392h-8.2v36.7h8.2c0-18.9-2.5-30.2 9-30.2 10.2 0 8.2 10.2 8.2 30.2h7.9c0-18.3-2.5-30.2 9-30.2 10.2 0 8.2 10 8.2 30.2h8.2v-23zm44.9-13.7h-7.9v4.4c-2.7-3.3-6.5-5.4-11.7-5.4-10.3 0-18.2 8.2-18.2 19.3 0 11.2 7.9 19.3 18.2 19.3 5.2 0 9-1.9 11.7-5.4v4.6h7.9V392zm40.5 25.6c0-15-22.9-8.2-22.9-15.2 0-5.7 11.9-4.8 18.5-1.1l3.3-6.5c-9.4-6.1-30.2-6-30.2 8.2 0 14.3 22.9 8.3 22.9 15 0 6.3-13.5 5.8-20.7.8l-3.5 6.3c11.2 7.6 32.6 6 32.6-7.5zm35.4 9.3l-2.2-6.8c-3.8 2.1-12.2 4.4-12.2-4.1v-16.6h13.1V392h-13.1v-11.2h-8.2V392h-7.6v7.3h7.6V416c0 17.6 17.3 14.4 22.6 10.9zm13.3-13.4h27.5c0-16.2-7.4-22.6-17.4-22.6-10.6 0-18.2 7.9-18.2 19.3 0 20.5 22.6 23.9 33.8 14.2l-3.8-6c-7.8 6.4-19.6 5.8-21.9-4.9zm59.1-21.5c-4.6-2-11.6-1.8-15.2 4.4V392h-8.2v36.7h8.2V408c0-11.6 9.5-10.1 12.8-8.4l2.4-7.6zm10.6 18.3c0-11.4 11.6-15.1 20.7-8.4l3.8-6.5c-11.6-9.1-32.7-4.1-32.7 15 0 19.8 22.4 23.8 32.7 15l-3.8-6.5c-9.2 6.5-20.7 2.6-20.7-8.6zm66.7-18.3H408v4.4c-8.3-11-29.9-4.8-29.9 13.9 0 19.2 22.4 24.7 29.9 13.9v4.6h8.2V392zm33.7 0c-2.4-1.2-11-2.9-15.2 4.4V392h-7.9v36.7h7.9V408c0-11 9-10.3 12.8-8.4l2.4-7.6zm40.3-14.9h-7.9v19.3c-8.2-10.9-29.9-5.1-29.9 13.9 0 19.4 22.5 24.6 29.9 13.9v4.6h7.9v-51.7zm7.6-75.1v4.6h.8V302h1.9v-.8h-4.6v.8h1.9zm6.6 123.8c0-.5 0-1.1-.3-1.6-.3-.3-.5-.8-.8-1.1-.3-.3-.8-.5-1.1-.8-.5 0-1.1-.3-1.6-.3-.3 0-.8.3-1.4.3-.5.3-.8.5-1.1.8-.5.3-.8.8-.8 1.1-.3.5-.3 1.1-.3 1.6 0 .3 0 .8.3 1.4 0 .3.3.8.8 1.1.3.3.5.5 1.1.8.5.3 1.1.3 1.4.3.5 0 1.1 0 1.6-.3.3-.3.8-.5 1.1-.8.3-.3.5-.8.8-1.1.3-.6.3-1.1.3-1.4zm3.2-124.7h-1.4l-1.6 3.5-1.6-3.5h-1.4v5.4h.8v-4.1l1.6 3.5h1.1l1.4-3.5v4.1h1.1v-5.4zm4.4-80.5c0-76.2-62.1-138.3-138.5-138.3-27.2 0-53.9 8.2-76.5 23.1 72.1 59.3 73.2 171.5 0 230.5 22.6 15 49.5 23.1 76.5 23.1 76.4.1 138.5-61.9 138.5-138.4z" } }, "free": ["brands"] }, "cc-paypal": { "changes": ["4.2.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f1f4", "label": "Paypal Credit Card", "voted": false, "svg": { "brands": { "last_modified": 1660014472, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M186.3 258.2c0 12.2-9.7 21.5-22 21.5-9.2 0-16-5.2-16-15 0-12.2 9.5-22 21.7-22 9.3 0 16.3 5.7 16.3 15.5zM80.5 209.7h-4.7c-1.5 0-3 1-3.2 2.7l-4.3 26.7 8.2-.3c11 0 19.5-1.5 21.5-14.2 2.3-13.4-6.2-14.9-17.5-14.9zm284 0H360c-1.8 0-3 1-3.2 2.7l-4.2 26.7 8-.3c13 0 22-3 22-18-.1-10.6-9.6-11.1-18.1-11.1zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM128.3 215.4c0-21-16.2-28-34.7-28h-40c-2.5 0-5 2-5.2 4.7L32 294.2c-.3 2 1.2 4 3.2 4h19c2.7 0 5.2-2.9 5.5-5.7l4.5-26.6c1-7.2 13.2-4.7 18-4.7 28.6 0 46.1-17 46.1-45.8zm84.2 8.8h-19c-3.8 0-4 5.5-4.2 8.2-5.8-8.5-14.2-10-23.7-10-24.5 0-43.2 21.5-43.2 45.2 0 19.5 12.2 32.2 31.7 32.2 9 0 20.2-4.9 26.5-11.9-.5 1.5-1 4.7-1 6.2 0 2.3 1 4 3.2 4H200c2.7 0 5-2.9 5.5-5.7l10.2-64.3c.3-1.9-1.2-3.9-3.2-3.9zm40.5 97.9l63.7-92.6c.5-.5.5-1 .5-1.7 0-1.7-1.5-3.5-3.2-3.5h-19.2c-1.7 0-3.5 1-4.5 2.5l-26.5 39-11-37.5c-.8-2.2-3-4-5.5-4h-18.7c-1.7 0-3.2 1.8-3.2 3.5 0 1.2 19.5 56.8 21.2 62.1-2.7 3.8-20.5 28.6-20.5 31.6 0 1.8 1.5 3.2 3.2 3.2h19.2c1.8-.1 3.5-1.1 4.5-2.6zm159.3-106.7c0-21-16.2-28-34.7-28h-39.7c-2.7 0-5.2 2-5.5 4.7l-16.2 102c-.2 2 1.3 4 3.2 4h20.5c2 0 3.5-1.5 4-3.2l4.5-29c1-7.2 13.2-4.7 18-4.7 28.4 0 45.9-17 45.9-45.8zm84.2 8.8h-19c-3.8 0-4 5.5-4.3 8.2-5.5-8.5-14-10-23.7-10-24.5 0-43.2 21.5-43.2 45.2 0 19.5 12.2 32.2 31.7 32.2 9.3 0 20.5-4.9 26.5-11.9-.3 1.5-1 4.7-1 6.2 0 2.3 1 4 3.2 4H484c2.7 0 5-2.9 5.5-5.7l10.2-64.3c.3-1.9-1.2-3.9-3.2-3.9zm47.5-33.3c0-2-1.5-3.5-3.2-3.5h-18.5c-1.5 0-3 1.2-3.2 2.7l-16.2 104-.3.5c0 1.8 1.5 3.5 3.5 3.5h16.5c2.5 0 5-2.9 5.2-5.7L544 191.2v-.3zm-90 51.8c-12.2 0-21.7 9.7-21.7 22 0 9.7 7 15 16.2 15 12 0 21.7-9.2 21.7-21.5.1-9.8-6.9-15.5-16.2-15.5z" } }, "free": ["brands"] }, "cc-stripe": { "changes": ["4.2.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f1f5", "label": "Stripe Credit Card", "voted": false, "svg": { "brands": { "last_modified": 1660014472, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M492.4 220.8c-8.9 0-18.7 6.7-18.7 22.7h36.7c0-16-9.3-22.7-18-22.7zM375 223.4c-8.2 0-13.3 2.9-17 7l.2 52.8c3.5 3.7 8.5 6.7 16.8 6.7 13.1 0 21.9-14.3 21.9-33.4 0-18.6-9-33.2-21.9-33.1zM528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM122.2 281.1c0 25.6-20.3 40.1-49.9 40.3-12.2 0-25.6-2.4-38.8-8.1v-33.9c12 6.4 27.1 11.3 38.9 11.3 7.9 0 13.6-2.1 13.6-8.7 0-17-54-10.6-54-49.9 0-25.2 19.2-40.2 48-40.2 11.8 0 23.5 1.8 35.3 6.5v33.4c-10.8-5.8-24.5-9.1-35.3-9.1-7.5 0-12.1 2.2-12.1 7.7 0 16 54.3 8.4 54.3 50.7zm68.8-56.6h-27V275c0 20.9 22.5 14.4 27 12.6v28.9c-4.7 2.6-13.3 4.7-24.9 4.7-21.1 0-36.9-15.5-36.9-36.5l.2-113.9 34.7-7.4v30.8H191zm74 2.4c-4.5-1.5-18.7-3.6-27.1 7.4v84.4h-35.5V194.2h30.7l2.2 10.5c8.3-15.3 24.9-12.2 29.6-10.5h.1zm44.1 91.8h-35.7V194.2h35.7zm0-142.9l-35.7 7.6v-28.9l35.7-7.6zm74.1 145.5c-12.4 0-20-5.3-25.1-9l-.1 40.2-35.5 7.5V194.2h31.3l1.8 8.8c4.9-4.5 13.9-11.1 27.8-11.1 24.9 0 48.4 22.5 48.4 63.8 0 45.1-23.2 65.5-48.6 65.6zm160.4-51.5h-69.5c1.6 16.6 13.8 21.5 27.6 21.5 14.1 0 25.2-3 34.9-7.9V312c-9.7 5.3-22.4 9.2-39.4 9.2-34.6 0-58.8-21.7-58.8-64.5 0-36.2 20.5-64.9 54.3-64.9 33.7 0 51.3 28.7 51.3 65.1 0 3.5-.3 10.9-.4 12.9z" } }, "free": ["brands"] }, "cc-visa": { "changes": ["4.2.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f1f0", "label": "Visa Credit Card", "voted": false, "svg": { "brands": { "last_modified": 1660014483, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M470.1 231.3s7.6 37.2 9.3 45H446c3.3-8.9 16-43.5 16-43.5-.2.3 3.3-9.1 5.3-14.9l2.8 13.4zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM152.5 331.2L215.7 176h-42.5l-39.3 106-4.3-21.5-14-71.4c-2.3-9.9-9.4-12.7-18.2-13.1H32.7l-.7 3.1c15.8 4 29.9 9.8 42.2 17.1l35.8 135h42.5zm94.4.2L272.1 176h-40.2l-25.1 155.4h40.1zm139.9-50.8c.2-17.7-10.6-31.2-33.7-42.3-14.1-7.1-22.7-11.9-22.7-19.2.2-6.6 7.3-13.4 23.1-13.4 13.1-.3 22.7 2.8 29.9 5.9l3.6 1.7 5.5-33.6c-7.9-3.1-20.5-6.6-36-6.6-39.7 0-67.6 21.2-67.8 51.4-.3 22.3 20 34.7 35.2 42.2 15.5 7.6 20.8 12.6 20.8 19.3-.2 10.4-12.6 15.2-24.1 15.2-16 0-24.6-2.5-37.7-8.3l-5.3-2.5-5.6 34.9c9.4 4.3 26.8 8.1 44.8 8.3 42.2.1 69.7-20.8 70-53zM528 331.4L495.6 176h-31.1c-9.6 0-16.9 2.8-21 12.9l-59.7 142.5H426s6.9-19.2 8.4-23.3H486c1.2 5.5 4.8 23.3 4.8 23.3H528z" } }, "free": ["brands"] }, "cedi-sign": { "changes": ["6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Cedi Sign", "currency"] }, "styles": ["solid"], "unicode": "e0df", "label": "Cedi Sign", "voted": false, "svg": { "solid": { "last_modified": 1684766476, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M256 32c0-17.7-14.3-32-32-32s-32 14.3-32 32V66.7C101.2 81.9 32 160.9 32 256s69.2 174.1 160 189.3V480c0 17.7 14.3 32 32 32s32-14.3 32-32V445.3c30.9-5.2 59.2-17.7 83.2-35.8c14.1-10.6 17-30.7 6.4-44.8s-30.7-17-44.8-6.4c-13.2 9.9-28.3 17.3-44.8 21.6V132c16.4 4.2 31.6 11.6 44.8 21.6c14.1 10.6 34.2 7.8 44.8-6.4s7.8-34.2-6.4-44.8c-24-18-52.4-30.6-83.2-35.8V32zM192 132V380c-55.2-14.2-96-64.3-96-124s40.8-109.8 96-124z" } }, "free": ["solid"] }, "cent-sign": { "changes": ["6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Cent Sign", "currency"] }, "styles": ["solid"], "unicode": "e3f5", "label": "Cent Sign", "voted": false, "svg": { "solid": { "last_modified": 1684766475, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M224 0c17.7 0 32 14.3 32 32V66.7c30.9 5.2 59.2 17.7 83.2 35.8c14.1 10.6 17 30.7 6.4 44.8s-30.7 17-44.8 6.4C279.4 137.5 252.9 128 224 128c-70.7 0-128 57.3-128 128s57.3 128 128 128c28.9 0 55.4-9.5 76.8-25.6c14.1-10.6 34.2-7.8 44.8 6.4s7.8 34.2-6.4 44.8c-24 18-52.4 30.6-83.2 35.8V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V445.3C101.2 430.1 32 351.1 32 256s69.2-174.1 160-189.3V32c0-17.7 14.3-32 32-32z" } }, "free": ["solid"] }, "centercode": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f380", "label": "Centercode", "voted": false, "svg": { "brands": { "last_modified": 1660014481, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M329.2 268.6c-3.8 35.2-35.4 60.6-70.6 56.8-35.2-3.8-60.6-35.4-56.8-70.6 3.8-35.2 35.4-60.6 70.6-56.8 35.1 3.8 60.6 35.4 56.8 70.6zm-85.8 235.1C96.7 496-8.2 365.5 10.1 224.3c11.2-86.6 65.8-156.9 139.1-192 161-77.1 349.7 37.4 354.7 216.6 4.1 147-118.4 262.2-260.5 254.8zm179.9-180c27.9-118-160.5-205.9-237.2-234.2-57.5 56.3-69.1 188.6-33.8 344.4 68.8 15.8 169.1-26.4 271-110.2z" } }, "free": ["brands"] }, "centos": { "changes": ["5.6.0", "5.8.0"], "ligatures": [], "search": { "terms": ["linux", "operating system", "os"] }, "styles": ["brands"], "unicode": "f789", "label": "Centos", "voted": true, "svg": { "brands": { "last_modified": 1660014478, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M289.6 97.5l31.6 31.7-76.3 76.5V97.5zm-162.4 31.7l76.3 76.5V97.5h-44.7zm41.5-41.6h44.7v127.9l10.8 10.8 10.8-10.8V87.6h44.7L224.2 32zm26.2 168.1l-10.8-10.8H55.5v-44.8L0 255.7l55.5 55.6v-44.8h128.6l10.8-10.8zm79.3-20.7h107.9v-44.8l-31.6-31.7zm173.3 20.7L392 200.1v44.8H264.3l-10.8 10.8 10.8 10.8H392v44.8l55.5-55.6zM65.4 176.2l32.5-31.7 90.3 90.5h15.3v-15.3l-90.3-90.5 31.6-31.7H65.4zm316.7-78.7h-78.5l31.6 31.7-90.3 90.5V235h15.3l90.3-90.5 31.6 31.7zM203.5 413.9V305.8l-76.3 76.5 31.6 31.7h44.7zM65.4 235h108.8l-76.3-76.5-32.5 31.7zm316.7 100.2l-31.6 31.7-90.3-90.5h-15.3v15.3l90.3 90.5-31.6 31.7h78.5zm0-58.8H274.2l76.3 76.5 31.6-31.7zm-60.9 105.8l-76.3-76.5v108.1h44.7zM97.9 352.9l76.3-76.5H65.4v44.8zm181.8 70.9H235V295.9l-10.8-10.8-10.8 10.8v127.9h-44.7l55.5 55.6zm-166.5-41.6l90.3-90.5v-15.3h-15.3l-90.3 90.5-32.5-31.7v78.7h79.4z" } }, "free": ["brands"] }, "certificate": { "aliases": { "unicodes": { "secondary": ["10f0a3"] } }, "changes": [ "2.0.0", "5.0.0", "5.10.1", "5.10.2", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["badge", "star", "verified"] }, "styles": ["solid"], "unicode": "f0a3", "label": "Certificate", "voted": false, "svg": { "solid": { "last_modified": 1684767552, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M211 7.3C205 1 196-1.4 187.6 .8s-14.9 8.9-17.1 17.3L154.7 80.6l-62-17.5c-8.4-2.4-17.4 0-23.5 6.1s-8.5 15.1-6.1 23.5l17.5 62L18.1 170.6c-8.4 2.1-15 8.7-17.3 17.1S1 205 7.3 211l46.2 45L7.3 301C1 307-1.4 316 .8 324.4s8.9 14.9 17.3 17.1l62.5 15.8-17.5 62c-2.4 8.4 0 17.4 6.1 23.5s15.1 8.5 23.5 6.1l62-17.5 15.8 62.5c2.1 8.4 8.7 15 17.1 17.3s17.3-.2 23.4-6.4l45-46.2 45 46.2c6.1 6.2 15 8.7 23.4 6.4s14.9-8.9 17.1-17.3l15.8-62.5 62 17.5c8.4 2.4 17.4 0 23.5-6.1s8.5-15.1 6.1-23.5l-17.5-62 62.5-15.8c8.4-2.1 15-8.7 17.3-17.1s-.2-17.3-6.4-23.4l-46.2-45 46.2-45c6.2-6.1 8.7-15 6.4-23.4s-8.9-14.9-17.3-17.1l-62.5-15.8 17.5-62c2.4-8.4 0-17.4-6.1-23.5s-15.1-8.5-23.5-6.1l-62 17.5L341.4 18.1c-2.1-8.4-8.7-15-17.1-17.3S307 1 301 7.3L256 53.5 211 7.3z" } }, "free": ["solid"] }, "chair": { "aliases": { "unicodes": { "composite": ["1fa91"], "secondary": ["10f6c0"] } }, "changes": ["5.4.0", "5.11.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["chair", "furniture", "seat", "sit"] }, "styles": ["solid"], "unicode": "f6c0", "label": "Chair", "voted": true, "svg": { "solid": { "last_modified": 1684767443, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M248 48V256h48V58.7c23.9 13.8 40 39.7 40 69.3V256h48V128C384 57.3 326.7 0 256 0H192C121.3 0 64 57.3 64 128V256h48V128c0-29.6 16.1-55.5 40-69.3V256h48V48h48zM48 288c-12.1 0-23.2 6.8-28.6 17.7l-16 32c-5 9.9-4.4 21.7 1.4 31.1S20.9 384 32 384l0 96c0 17.7 14.3 32 32 32s32-14.3 32-32V384H352v96c0 17.7 14.3 32 32 32s32-14.3 32-32V384c11.1 0 21.4-5.7 27.2-15.2s6.4-21.2 1.4-31.1l-16-32C423.2 294.8 412.1 288 400 288H48z" } }, "free": ["solid"] }, "chalkboard": { "aliases": { "names": ["blackboard"], "unicodes": { "secondary": ["10f51b"] } }, "changes": ["5.0.13", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "blackboard", "learning", "school", "teaching", "whiteboard", "writing" ] }, "styles": ["solid"], "unicode": "f51b", "label": "Chalkboard", "voted": false, "svg": { "solid": { "last_modified": 1684767620, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M96 32C60.7 32 32 60.7 32 96V384H96V96l384 0V384h64V96c0-35.3-28.7-64-64-64H96zM224 384v32H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H544c17.7 0 32-14.3 32-32s-14.3-32-32-32H416V384c0-17.7-14.3-32-32-32H256c-17.7 0-32 14.3-32 32z" } }, "free": ["solid"] }, "chalkboard-user": { "aliases": { "names": ["chalkboard-teacher"], "unicodes": { "secondary": ["10f51c"] } }, "changes": ["5.0.13", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "blackboard", "instructor", "learning", "professor", "school", "whiteboard", "writing" ] }, "styles": ["solid"], "unicode": "f51c", "label": "Chalkboard User", "voted": false, "svg": { "solid": { "last_modified": 1684767620, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M160 64c0-35.3 28.7-64 64-64H576c35.3 0 64 28.7 64 64V352c0 35.3-28.7 64-64 64H336.8c-11.8-25.5-29.9-47.5-52.4-64H384V320c0-17.7 14.3-32 32-32h64c17.7 0 32 14.3 32 32v32h64V64L224 64v49.1C205.2 102.2 183.3 96 160 96V64zm0 64a96 96 0 1 1 0 192 96 96 0 1 1 0-192zM133.3 352h53.3C260.3 352 320 411.7 320 485.3c0 14.7-11.9 26.7-26.7 26.7H26.7C11.9 512 0 500.1 0 485.3C0 411.7 59.7 352 133.3 352z" } }, "free": ["solid"] }, "champagne-glasses": { "aliases": { "names": ["glass-cheers"], "unicodes": { "composite": ["1f942"], "secondary": ["10f79f"] } }, "changes": ["5.6.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "alcohol", "bar", "beverage", "celebrate", "celebration", "champagne", "clink", "clinking glasses", "drink", "glass", "holiday", "new year's eve", "party", "toast" ] }, "styles": ["solid"], "unicode": "f79f", "label": "Champagne Glasses", "voted": false, "svg": { "solid": { "last_modified": 1684767420, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M155.6 17.3C163 3 179.9-3.6 195 1.9L320 47.5l125-45.6c15.1-5.5 32 1.1 39.4 15.4l78.8 152.9c28.8 55.8 10.3 122.3-38.5 156.6L556.1 413l41-15c16.6-6 35 2.5 41 19.1s-2.5 35-19.1 41l-71.1 25.9L476.8 510c-16.6 6.1-35-2.5-41-19.1s2.5-35 19.1-41l41-15-31.3-86.2c-59.4 5.2-116.2-34-130-95.2L320 188.8l-14.6 64.7c-13.8 61.3-70.6 100.4-130 95.2l-31.3 86.2 41 15c16.6 6 25.2 24.4 19.1 41s-24.4 25.2-41 19.1L92.2 484.1 21.1 458.2c-16.6-6.1-25.2-24.4-19.1-41s24.4-25.2 41-19.1l41 15 31.3-86.2C66.5 292.5 48.1 226 76.9 170.2L155.6 17.3zm44 54.4l-27.2 52.8L261.6 157l13.1-57.9L199.6 71.7zm240.9 0L365.4 99.1 378.5 157l89.2-32.5L440.5 71.7z" } }, "free": ["solid"] }, "charging-station": { "aliases": { "unicodes": { "secondary": ["10f5e7"] } }, "changes": [ "5.2.0", "5.10.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["electric", "ev", "tesla", "vehicle"] }, "styles": ["solid"], "unicode": "f5e7", "label": "Charging Station", "voted": false, "svg": { "solid": { "last_modified": 1684767489, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M96 0C60.7 0 32 28.7 32 64V448c-17.7 0-32 14.3-32 32s14.3 32 32 32H320c17.7 0 32-14.3 32-32s-14.3-32-32-32V304h16c22.1 0 40 17.9 40 40v32c0 39.8 32.2 72 72 72s72-32.2 72-72V252.3c32.5-10.2 56-40.5 56-76.3V144c0-8.8-7.2-16-16-16H544V80c0-8.8-7.2-16-16-16s-16 7.2-16 16v48H480V80c0-8.8-7.2-16-16-16s-16 7.2-16 16v48H432c-8.8 0-16 7.2-16 16v32c0 35.8 23.5 66.1 56 76.3V376c0 13.3-10.7 24-24 24s-24-10.7-24-24V344c0-48.6-39.4-88-88-88H320V64c0-35.3-28.7-64-64-64H96zM216.9 82.7c6 4 8.5 11.5 6.3 18.3l-25 74.9H256c6.7 0 12.7 4.2 15 10.4s.5 13.3-4.6 17.7l-112 96c-5.5 4.7-13.4 5.1-19.3 1.1s-8.5-11.5-6.3-18.3l25-74.9H96c-6.7 0-12.7-4.2-15-10.4s-.5-13.3 4.6-17.7l112-96c5.5-4.7 13.4-5.1 19.3-1.1z" } }, "free": ["solid"] }, "chart-area": { "aliases": { "names": ["area-chart"], "unicodes": { "secondary": ["10f1fe"] } }, "changes": [ "4.2.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["analytics", "area", "chart", "graph"] }, "styles": ["solid"], "unicode": "f1fe", "label": "Chart Area", "voted": false, "svg": { "solid": { "last_modified": 1684767207, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M64 64c0-17.7-14.3-32-32-32S0 46.3 0 64V400c0 44.2 35.8 80 80 80H480c17.7 0 32-14.3 32-32s-14.3-32-32-32H80c-8.8 0-16-7.2-16-16V64zm96 288H448c17.7 0 32-14.3 32-32V251.8c0-7.6-2.7-15-7.7-20.8l-65.8-76.8c-12.1-14.2-33.7-15-46.9-1.8l-21 21c-10 10-26.4 9.2-35.4-1.6l-39.2-47c-12.6-15.1-35.7-15.4-48.7-.6L135.9 215c-5.1 5.8-7.9 13.3-7.9 21.1v84c0 17.7 14.3 32 32 32z" } }, "free": ["solid"] }, "chart-bar": { "aliases": { "names": ["bar-chart"], "unicodes": { "secondary": ["10f080"] } }, "changes": [ "1.0.0", "5.0.0", "5.3.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["analytics", "bar", "chart", "graph"] }, "styles": ["solid", "regular"], "unicode": "f080", "label": "Chart Bar", "voted": false, "svg": { "solid": { "last_modified": 1684767207, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M32 32c17.7 0 32 14.3 32 32V400c0 8.8 7.2 16 16 16H480c17.7 0 32 14.3 32 32s-14.3 32-32 32H80c-44.2 0-80-35.8-80-80V64C0 46.3 14.3 32 32 32zm96 96c0-17.7 14.3-32 32-32l192 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-192 0c-17.7 0-32-14.3-32-32zm32 64H288c17.7 0 32 14.3 32 32s-14.3 32-32 32H160c-17.7 0-32-14.3-32-32s14.3-32 32-32zm0 96H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H160c-17.7 0-32-14.3-32-32s14.3-32 32-32z" }, "regular": { "last_modified": 1684767207, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M24 32c13.3 0 24 10.7 24 24V408c0 13.3 10.7 24 24 24H488c13.3 0 24 10.7 24 24s-10.7 24-24 24H72c-39.8 0-72-32.2-72-72V56C0 42.7 10.7 32 24 32zM128 136c0-13.3 10.7-24 24-24l208 0c13.3 0 24 10.7 24 24s-10.7 24-24 24l-208 0c-13.3 0-24-10.7-24-24zm24 72H296c13.3 0 24 10.7 24 24s-10.7 24-24 24H152c-13.3 0-24-10.7-24-24s10.7-24 24-24zm0 96H424c13.3 0 24 10.7 24 24s-10.7 24-24 24H152c-13.3 0-24-10.7-24-24s10.7-24 24-24z" } }, "free": ["regular", "solid"] }, "chart-column": { "changes": ["6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["bar", "bar chart", "chart", "graph", "track", "trend"] }, "styles": ["solid"], "unicode": "e0e3", "label": "Chart Column", "voted": false, "svg": { "solid": { "last_modified": 1684767205, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M32 32c17.7 0 32 14.3 32 32V400c0 8.8 7.2 16 16 16H480c17.7 0 32 14.3 32 32s-14.3 32-32 32H80c-44.2 0-80-35.8-80-80V64C0 46.3 14.3 32 32 32zM160 224c17.7 0 32 14.3 32 32v64c0 17.7-14.3 32-32 32s-32-14.3-32-32V256c0-17.7 14.3-32 32-32zm128-64V320c0 17.7-14.3 32-32 32s-32-14.3-32-32V160c0-17.7 14.3-32 32-32s32 14.3 32 32zm64 32c17.7 0 32 14.3 32 32v96c0 17.7-14.3 32-32 32s-32-14.3-32-32V224c0-17.7 14.3-32 32-32zM480 96V320c0 17.7-14.3 32-32 32s-32-14.3-32-32V96c0-17.7 14.3-32 32-32s32 14.3 32 32z" } }, "free": ["solid"] }, "chart-gantt": { "changes": ["6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["chart", "graph", "track", "trend"] }, "styles": ["solid"], "unicode": "e0e4", "label": "Chart Gantt", "voted": false, "svg": { "solid": { "last_modified": 1684767206, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M32 32c17.7 0 32 14.3 32 32V400c0 8.8 7.2 16 16 16H480c17.7 0 32 14.3 32 32s-14.3 32-32 32H80c-44.2 0-80-35.8-80-80V64C0 46.3 14.3 32 32 32zm96 96c0-17.7 14.3-32 32-32l96 0c17.7 0 32 14.3 32 32s-14.3 32-32 32H160c-17.7 0-32-14.3-32-32zm96 64H352c17.7 0 32 14.3 32 32s-14.3 32-32 32H224c-17.7 0-32-14.3-32-32s14.3-32 32-32zm160 96h64c17.7 0 32 14.3 32 32s-14.3 32-32 32H384c-17.7 0-32-14.3-32-32s14.3-32 32-32z" } }, "free": ["solid"] }, "chart-line": { "aliases": { "names": ["line-chart"], "unicodes": { "secondary": ["10f201"] } }, "changes": [ "4.2.0", "5.0.0", "5.3.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "activity", "analytics", "chart", "dashboard", "gain", "graph", "increase", "line" ] }, "styles": ["solid"], "unicode": "f201", "label": "Chart Line", "voted": false, "svg": { "solid": { "last_modified": 1684767207, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M64 64c0-17.7-14.3-32-32-32S0 46.3 0 64V400c0 44.2 35.8 80 80 80H480c17.7 0 32-14.3 32-32s-14.3-32-32-32H80c-8.8 0-16-7.2-16-16V64zm406.6 86.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L320 210.7l-57.4-57.4c-12.5-12.5-32.8-12.5-45.3 0l-112 112c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L240 221.3l57.4 57.4c12.5 12.5 32.8 12.5 45.3 0l128-128z" } }, "free": ["solid"] }, "chart-pie": { "aliases": { "names": ["pie-chart"], "unicodes": { "secondary": ["10f200"] } }, "changes": [ "4.2.0", "5.0.0", "5.3.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["analytics", "chart", "diagram", "graph", "pie"] }, "styles": ["solid"], "unicode": "f200", "label": "Chart Pie", "voted": false, "svg": { "solid": { "last_modified": 1684767207, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M304 240V16.6c0-9 7-16.6 16-16.6C443.7 0 544 100.3 544 224c0 9-7.6 16-16.6 16H304zM32 272C32 150.7 122.1 50.3 239 34.3c9.2-1.3 17 6.1 17 15.4V288L412.5 444.5c6.7 6.7 6.2 17.7-1.5 23.1C371.8 495.6 323.8 512 272 512C139.5 512 32 404.6 32 272zm526.4 16c9.3 0 16.6 7.8 15.4 17c-7.7 55.9-34.6 105.6-73.9 142.3c-6 5.6-15.4 5.2-21.2-.7L320 288H558.4z" } }, "free": ["solid"] }, "chart-simple": { "changes": ["6.0.0-beta3", "6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["analytics", "bar", "chart", "column", "graph", "row", "trend"] }, "styles": ["solid"], "unicode": "e473", "label": "Chart Simple", "voted": false, "svg": { "solid": { "last_modified": 1684767207, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M160 80c0-26.5 21.5-48 48-48h32c26.5 0 48 21.5 48 48V432c0 26.5-21.5 48-48 48H208c-26.5 0-48-21.5-48-48V80zM0 272c0-26.5 21.5-48 48-48H80c26.5 0 48 21.5 48 48V432c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V272zM368 96h32c26.5 0 48 21.5 48 48V432c0 26.5-21.5 48-48 48H368c-26.5 0-48-21.5-48-48V144c0-26.5 21.5-48 48-48z" } }, "free": ["solid"] }, "check": { "aliases": { "unicodes": { "composite": ["2713", "2714"], "secondary": ["10f00c"] } }, "changes": [ "1.0.0", "5.0.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Check Mark", "accept", "agree", "check", "check mark", "checkmark", "confirm", "correct", "done", "mark", "notice", "notification", "notify", "ok", "select", "success", "tick", "todo", "yes", "✓" ] }, "styles": ["solid"], "unicode": "f00c", "label": "Check", "voted": false, "svg": { "solid": { "last_modified": 1684767551, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M438.6 105.4c12.5 12.5 12.5 32.8 0 45.3l-256 256c-12.5 12.5-32.8 12.5-45.3 0l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L160 338.7 393.4 105.4c12.5-12.5 32.8-12.5 45.3 0z" } }, "free": ["solid"] }, "check-double": { "aliases": { "unicodes": { "secondary": ["10f560"] } }, "changes": [ "5.1.0", "5.8.2", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "accept", "agree", "checkmark", "confirm", "correct", "done", "notice", "notification", "notify", "ok", "select", "success", "tick", "todo" ] }, "styles": ["solid"], "unicode": "f560", "label": "Check Double", "voted": true, "svg": { "solid": { "last_modified": 1684767551, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M342.6 86.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L160 178.7l-57.4-57.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l80 80c12.5 12.5 32.8 12.5 45.3 0l160-160zm96 128c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L160 402.7 54.6 297.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l128 128c12.5 12.5 32.8 12.5 45.3 0l256-256z" } }, "free": ["solid"] }, "check-to-slot": { "aliases": { "names": ["vote-yea"], "unicodes": { "secondary": ["10f772"] } }, "changes": ["5.5.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "accept", "cast", "election", "politics", "positive", "voting", "yes" ] }, "styles": ["solid"], "unicode": "f772", "label": "Check To Slot", "voted": false, "svg": { "solid": { "last_modified": 1684767390, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M96 80c0-26.5 21.5-48 48-48H432c26.5 0 48 21.5 48 48V384H96V80zm313 47c-9.4-9.4-24.6-9.4-33.9 0l-111 111-47-47c-9.4-9.4-24.6-9.4-33.9 0s-9.4 24.6 0 33.9l64 64c9.4 9.4 24.6 9.4 33.9 0L409 161c9.4-9.4 9.4-24.6 0-33.9zM0 336c0-26.5 21.5-48 48-48H64V416H512V288h16c26.5 0 48 21.5 48 48v96c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V336z" } }, "free": ["solid"] }, "cheese": { "aliases": { "unicodes": { "secondary": ["10f7ef"] } }, "changes": ["5.7.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "cheddar", "curd", "gouda", "melt", "parmesan", "sandwich", "swiss", "wedge" ] }, "styles": ["solid"], "unicode": "f7ef", "label": "Cheese", "voted": false, "svg": { "solid": { "last_modified": 1684767418, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M512 240.2V256H0c0-20 10-38.7 26.6-49.8L274.9 40.7c8.6-5.7 18.6-8.7 28.9-8.7C418.8 32 512 125.2 512 240.2zm0 47.8V416c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V288H512z" } }, "free": ["solid"] }, "chess": { "aliases": { "unicodes": { "secondary": ["10f439"] } }, "changes": ["5.0.5", "5.9.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "board", "castle", "checkmate", "game", "king", "rook", "strategy", "tournament" ] }, "styles": ["solid"], "unicode": "f439", "label": "Chess", "voted": false, "svg": { "solid": { "last_modified": 1684767070, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M144 16c0-8.8-7.2-16-16-16s-16 7.2-16 16V32H96c-8.8 0-16 7.2-16 16s7.2 16 16 16h16V96H60.2C49.1 96 40 105.1 40 116.2c0 2.5 .5 4.9 1.3 7.3L73.8 208H72c-13.3 0-24 10.7-24 24s10.7 24 24 24h4L60 384H196L180 256h4c13.3 0 24-10.7 24-24s-10.7-24-24-24h-1.8l32.5-84.5c.9-2.3 1.3-4.8 1.3-7.3c0-11.2-9.1-20.2-20.2-20.2H144V64h16c8.8 0 16-7.2 16-16s-7.2-16-16-16H144V16zM48 416L4.8 473.6C1.7 477.8 0 482.8 0 488c0 13.3 10.7 24 24 24H232c13.3 0 24-10.7 24-24c0-5.2-1.7-10.2-4.8-14.4L208 416H48zm288 0l-43.2 57.6c-3.1 4.2-4.8 9.2-4.8 14.4c0 13.3 10.7 24 24 24H488c13.3 0 24-10.7 24-24c0-5.2-1.7-10.2-4.8-14.4L464 416H336zM304 208v51.9c0 7.8 2.8 15.3 8 21.1L339.2 312 337 384H462.5l-3.3-72 28.3-30.8c5.4-5.9 8.5-13.6 8.5-21.7V208c0-8.8-7.2-16-16-16H464c-8.8 0-16 7.2-16 16v16H424V208c0-8.8-7.2-16-16-16H392c-8.8 0-16 7.2-16 16v16H352V208c0-8.8-7.2-16-16-16H320c-8.8 0-16 7.2-16 16zm80 96c0-8.8 7.2-16 16-16s16 7.2 16 16v32H384V304z" } }, "free": ["solid"] }, "chess-bishop": { "aliases": { "unicodes": { "composite": ["265d"], "secondary": ["10f43a"] } }, "changes": ["5.0.5", "5.9.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Black Chess Bishop", "board", "checkmate", "game", "strategy"] }, "styles": ["solid", "regular"], "unicode": "f43a", "label": "Chess Bishop", "voted": false, "svg": { "solid": { "last_modified": 1684767071, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M128 0C110.3 0 96 14.3 96 32c0 16.1 11.9 29.4 27.4 31.7C78.4 106.8 8 190 8 288c0 47.4 30.8 72.3 56 84.7V400H256V372.7c25.2-12.5 56-37.4 56-84.7c0-37.3-10.2-72.4-25.3-104.1l-99.4 99.4c-6.2 6.2-16.4 6.2-22.6 0s-6.2-16.4 0-22.6L270.8 154.6c-23.2-38.1-51.8-69.5-74.2-90.9C212.1 61.4 224 48.1 224 32c0-17.7-14.3-32-32-32H128zM48 432L6.6 473.4c-4.2 4.2-6.6 10-6.6 16C0 501.9 10.1 512 22.6 512H297.4c12.5 0 22.6-10.1 22.6-22.6c0-6-2.4-11.8-6.6-16L272 432H48z" }, "regular": { "last_modified": 1684767071, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M104 0C90.7 0 80 10.7 80 24c0 11.2 7.6 20.6 18 23.2c-7.8 8-16.1 17-24.4 27C38.2 116.7 0 178.8 0 250.9c0 44.8 24.6 72.2 48 87.8V352H96V325c0-9-5-17.2-13-21.3c-18-9.3-35-24.7-35-52.7c0-55.5 29.8-106.8 62.4-145.9c16-19.2 32.1-34.8 44.2-45.5c1.9-1.7 3.7-3.2 5.3-4.6c1.7 1.4 3.4 3 5.3 4.6c12.1 10.7 28.2 26.3 44.2 45.5c5.3 6.3 10.5 13 15.5 20L159 191c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l57.8-57.8c12.8 25.9 21.2 54.3 21.2 83.8c0 28-17 43.4-35 52.7c-8 4.1-13 12.3-13 21.3v27h48V338.7c23.4-15.6 48-42.9 48-87.8c0-72.1-38.2-134.2-73.6-176.7c-8.3-9.9-16.6-19-24.4-27c10.3-2.7 18-12.1 18-23.2c0-13.3-10.7-24-24-24H160 104zM52.7 464l16.6-32H250.8l16.6 32H52.7zm207.9-80H59.5c-12 0-22.9 6.7-28.4 17.3L4.6 452.5c-3 5.8-4.6 12.2-4.6 18.7C0 493.8 18.2 512 40.8 512H279.2c22.5 0 40.8-18.2 40.8-40.8c0-6.5-1.6-12.9-4.6-18.7l-26.5-51.2c-5.5-10.6-16.5-17.3-28.4-17.3z" } }, "free": ["regular", "solid"] }, "chess-board": { "aliases": { "unicodes": { "secondary": ["10f43c"] } }, "changes": [ "5.0.5", "5.7.0", "5.9.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["board", "checkmate", "game", "strategy"] }, "styles": ["solid"], "unicode": "f43c", "label": "Chess Board", "voted": false, "svg": { "solid": { "last_modified": 1678474324, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zm64 64v64h64V96h64v64h64V96h64v64H320v64h64v64H320v64h64v64H320V352H256v64H192V352H128v64H64V352h64V288H64V224h64V160H64V96h64zm64 128h64V160H192v64zm0 64V224H128v64h64zm64 0H192v64h64V288zm0 0h64V224H256v64z" } }, "free": ["solid"] }, "chess-king": { "aliases": { "unicodes": { "composite": ["265a"], "secondary": ["10f43f"] } }, "changes": ["5.0.5", "5.9.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Black Chess King", "board", "checkmate", "game", "strategy"] }, "styles": ["solid", "regular"], "unicode": "f43f", "label": "Chess King", "voted": false, "svg": { "solid": { "last_modified": 1684767070, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M224 0c17.7 0 32 14.3 32 32V48h16c17.7 0 32 14.3 32 32s-14.3 32-32 32H256v48H408c22.1 0 40 17.9 40 40c0 5.3-1 10.5-3.1 15.4L368 400H80L3.1 215.4C1 210.5 0 205.3 0 200c0-22.1 17.9-40 40-40H192V112H176c-17.7 0-32-14.3-32-32s14.3-32 32-32h16V32c0-17.7 14.3-32 32-32zM38.6 473.4L80 432H368l41.4 41.4c4.2 4.2 6.6 10 6.6 16c0 12.5-10.1 22.6-22.6 22.6H54.6C42.1 512 32 501.9 32 489.4c0-6 2.4-11.8 6.6-16z" }, "regular": { "last_modified": 1684767070, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M248 24c0-13.3-10.7-24-24-24s-24 10.7-24 24V56H168c-13.3 0-24 10.7-24 24s10.7 24 24 24h32v40H59.6C26.7 144 0 170.7 0 203.6c0 8.2 1.7 16.3 4.9 23.8L59.1 352h52.3L49 208.2c-.6-1.5-1-3-1-4.6c0-6.4 5.2-11.6 11.6-11.6H224 388.4c6.4 0 11.6 5.2 11.6 11.6c0 1.6-.3 3.2-1 4.6L336.5 352h52.3l54.2-124.6c3.3-7.5 4.9-15.6 4.9-23.8c0-32.9-26.7-59.6-59.6-59.6H248V104h32c13.3 0 24-10.7 24-24s-10.7-24-24-24H248V24zM101.2 432H346.8l16.6 32H84.7l16.6-32zm283.7-30.7c-5.5-10.6-16.5-17.3-28.4-17.3H91.5c-12 0-22.9 6.7-28.4 17.3L36.6 452.5c-3 5.8-4.6 12.2-4.6 18.7C32 493.8 50.2 512 72.8 512H375.2c22.5 0 40.8-18.2 40.8-40.8c0-6.5-1.6-12.9-4.6-18.7l-26.5-51.2z" } }, "free": ["regular", "solid"] }, "chess-knight": { "aliases": { "unicodes": { "composite": ["265e"], "secondary": ["10f441"] } }, "changes": ["5.0.5", "5.9.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "Black Chess Knight", "board", "checkmate", "game", "horse", "strategy" ] }, "styles": ["solid", "regular"], "unicode": "f441", "label": "Chess Knight", "voted": false, "svg": { "solid": { "last_modified": 1684767071, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M96 48L82.7 61.3C70.7 73.3 64 89.5 64 106.5V238.9c0 10.7 5.3 20.7 14.2 26.6l10.6 7c14.3 9.6 32.7 10.7 48.1 3l3.2-1.6c2.6-1.3 5-2.8 7.3-4.5l49.4-37c6.6-5 15.7-5 22.3 0c10.2 7.7 9.9 23.1-.7 30.3L90.4 350C73.9 361.3 64 380 64 400H384l28.9-159c2.1-11.3 3.1-22.8 3.1-34.3V192C416 86 330 0 224 0H83.8C72.9 0 64 8.9 64 19.8c0 7.5 4.2 14.3 10.9 17.7L96 48zm24 68a20 20 0 1 1 40 0 20 20 0 1 1 -40 0zM22.6 473.4c-4.2 4.2-6.6 10-6.6 16C16 501.9 26.1 512 38.6 512H409.4c12.5 0 22.6-10.1 22.6-22.6c0-6-2.4-11.8-6.6-16L384 432H64L22.6 473.4z" }, "regular": { "last_modified": 1684767071, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M226.6 48H117.3l17.1 12.8c6 4.5 9.6 11.6 9.6 19.2s-3.6 14.7-9.6 19.2l-6.5 4.9c-10 7.5-16 19.3-16 31.9l-.3 91c0 10.2 4.9 19.9 13.2 25.8l1.9 1.3c9.9 7.1 23.3 7 33.2-.1l49.9-36.3c10.7-7.8 25.7-5.4 33.5 5.3s5.4 25.7-5.3 33.5l-49.9 36.3-53.8 39.1c-7.3 5.3-13 12.2-16.9 20.1H66.8c5.3-22.1 17.8-41.9 35.9-56.3c-1.3-.8-2.6-1.7-3.8-2.6L97 291.8c-21-15-33.4-39.2-33.3-65l.3-91c.1-19.8 6.7-38.7 18.6-53.9l-.4-.3C70.7 73 64 59.6 64 45.3C64 20.3 84.3 0 109.3 0H226.6C331.2 0 416 84.8 416 189.4c0 11.1-1 22.2-2.9 33.2L390.1 352H341.3l24.5-137.8c1.5-8.2 2.2-16.5 2.2-24.8C368 111.3 304.7 48 226.6 48zM85.2 432L68.7 464H379.3l-16.6-32H85.2zm315.7-30.7l26.5 51.2c3 5.8 4.6 12.2 4.6 18.7c0 22.5-18.2 40.8-40.8 40.8H56.8C34.2 512 16 493.8 16 471.2c0-6.5 1.6-12.9 4.6-18.7l26.5-51.2C52.5 390.7 63.5 384 75.5 384h297c12 0 22.9 6.7 28.4 17.3zM172 128a20 20 0 1 1 0 40 20 20 0 1 1 0-40z" } }, "free": ["regular", "solid"] }, "chess-pawn": { "aliases": { "unicodes": { "composite": ["265f"], "secondary": ["10f443"] } }, "changes": ["5.0.5", "5.9.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "board", "checkmate", "chess", "chess pawn", "dupe", "expendable", "game", "strategy" ] }, "styles": ["solid", "regular"], "unicode": "f443", "label": "Chess Pawn", "voted": false, "svg": { "solid": { "last_modified": 1684767070, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M215.5 224c29.2-18.4 48.5-50.9 48.5-88c0-57.4-46.6-104-104-104S56 78.6 56 136c0 37.1 19.4 69.6 48.5 88H96c-17.7 0-32 14.3-32 32c0 16.5 12.5 30 28.5 31.8L80 400H240L227.5 287.8c16-1.8 28.5-15.3 28.5-31.8c0-17.7-14.3-32-32-32h-8.5zM22.6 473.4c-4.2 4.2-6.6 10-6.6 16C16 501.9 26.1 512 38.6 512H281.4c12.5 0 22.6-10.1 22.6-22.6c0-6-2.4-11.8-6.6-16L256 432H64L22.6 473.4z" }, "regular": { "last_modified": 1684767070, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M232 152A72 72 0 1 0 88 152a72 72 0 1 0 144 0zm24 120H243.4l10.7 80H205.7L195 272H160 125l-10.7 80H65.9l10.7-80H64c-13.3 0-24-10.7-24-24s10.7-24 24-24c-15.1-20.1-24-45-24-72C40 85.7 93.7 32 160 32s120 53.7 120 120c0 27-8.9 51.9-24 72c13.3 0 24 10.7 24 24s-10.7 24-24 24zM52.7 464H267.3l-16.6-32H69.2L52.7 464zm207.9-80c12 0 22.9 6.7 28.4 17.3l26.5 51.2c3 5.8 4.6 12.2 4.6 18.7c0 22.5-18.2 40.8-40.8 40.8H40.8C18.2 512 0 493.8 0 471.2c0-6.5 1.6-12.9 4.6-18.7l26.5-51.2C36.5 390.7 47.5 384 59.5 384h201z" } }, "free": ["regular", "solid"] }, "chess-queen": { "aliases": { "unicodes": { "composite": ["265b"], "secondary": ["10f445"] } }, "changes": ["5.0.5", "5.9.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Black Chess Queen", "board", "checkmate", "game", "strategy"] }, "styles": ["solid", "regular"], "unicode": "f445", "label": "Chess Queen", "voted": false, "svg": { "solid": { "last_modified": 1684767071, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 0a56 56 0 1 1 0 112A56 56 0 1 1 256 0zM134.1 143.8c3.3-13 15-23.8 30.2-23.8c12.3 0 22.6 7.2 27.7 17c12 23.2 36.2 39 64 39s52-15.8 64-39c5.1-9.8 15.4-17 27.7-17c15.3 0 27 10.8 30.2 23.8c7 27.8 32.2 48.3 62.1 48.3c10.8 0 21-2.7 29.8-7.4c8.4-4.4 18.9-4.5 27.6 .9c13 8 17.1 25 9.2 38L399.7 400H384 343.6 168.4 128 112.3L5.4 223.6c-7.9-13-3.8-30 9.2-38c8.7-5.3 19.2-5.3 27.6-.9c8.9 4.7 19 7.4 29.8 7.4c29.9 0 55.1-20.5 62.1-48.3zM256 224l0 0 0 0h0zM112 432H400l41.4 41.4c4.2 4.2 6.6 10 6.6 16c0 12.5-10.1 22.6-22.6 22.6H86.6C74.1 512 64 501.9 64 489.4c0-6 2.4-11.8 6.6-16L112 432z" }, "regular": { "last_modified": 1684767071, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 96a48 48 0 1 0 0-96 48 48 0 1 0 0 96zm-95.2-8c-18.1 0-31.3 12.8-35.6 26.9c-8 26.2-32.4 45.2-61.2 45.2c-10 0-19.4-2.3-27.7-6.3c-7.6-3.7-16.7-3.3-24 1.2C.7 162.1-3.1 177.1 3.7 188.9L97.6 352H153l-83-144.1c40.5-2.2 75.3-25.9 93.1-59.8c22 26.8 55.4 43.9 92.8 43.9s70.8-17.1 92.8-43.9c17.8 34 52.6 57.7 93.1 59.8L359 352h55.4l93.9-163.1c6.8-11.7 3-26.7-8.6-33.8c-7.3-4.5-16.4-4.9-24-1.2c-8.4 4-17.7 6.3-27.7 6.3c-28.8 0-53.2-19-61.2-45.2C382.5 100.8 369.3 88 351.2 88c-14.5 0-26.3 8.5-32.4 19.3c-12.4 22-35.9 36.7-62.8 36.7s-50.4-14.8-62.8-36.7C187.1 96.5 175.4 88 160.8 88zM133.2 432H378.8l16.6 32H116.7l16.6-32zm283.7-30.7c-5.5-10.6-16.5-17.3-28.4-17.3h-265c-12 0-22.9 6.7-28.4 17.3L68.6 452.5c-3 5.8-4.6 12.2-4.6 18.7c0 22.5 18.2 40.8 40.8 40.8H407.2c22.5 0 40.8-18.2 40.8-40.8c0-6.5-1.6-12.9-4.6-18.7l-26.5-51.2z" } }, "free": ["regular", "solid"] }, "chess-rook": { "aliases": { "unicodes": { "composite": ["265c"], "secondary": ["10f447"] } }, "changes": ["5.0.5", "5.9.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "Black Chess Rook", "board", "castle", "checkmate", "game", "strategy" ] }, "styles": ["solid", "regular"], "unicode": "f447", "label": "Chess Rook", "voted": false, "svg": { "solid": { "last_modified": 1684767070, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M32 192V48c0-8.8 7.2-16 16-16h64c8.8 0 16 7.2 16 16V88c0 4.4 3.6 8 8 8h32c4.4 0 8-3.6 8-8V48c0-8.8 7.2-16 16-16h64c8.8 0 16 7.2 16 16V88c0 4.4 3.6 8 8 8h32c4.4 0 8-3.6 8-8V48c0-8.8 7.2-16 16-16h64c8.8 0 16 7.2 16 16V192c0 10.1-4.7 19.6-12.8 25.6L352 256l16 144H80L96 256 44.8 217.6C36.7 211.6 32 202.1 32 192zm176 96h32c8.8 0 16-7.2 16-16V224c0-17.7-14.3-32-32-32s-32 14.3-32 32v48c0 8.8 7.2 16 16 16zM22.6 473.4L64 432H384l41.4 41.4c4.2 4.2 6.6 10 6.6 16c0 12.5-10.1 22.6-22.6 22.6H38.6C26.1 512 16 501.9 16 489.4c0-6 2.4-11.8 6.6-16z" }, "regular": { "last_modified": 1684767070, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M80 80V192c0 2.5 1.2 4.9 3.2 6.4l51.2 38.4c6.8 5.1 10.4 13.4 9.5 21.9L133.5 352H85.2l9.4-85L54.4 236.8C40.3 226.2 32 209.6 32 192V72c0-22.1 17.9-40 40-40H376c22.1 0 40 17.9 40 40V192c0 17.6-8.3 34.2-22.4 44.8L353.4 267l9.4 85H314.5l-10.4-93.3c-.9-8.4 2.7-16.8 9.5-21.9l51.2-38.4c2-1.5 3.2-3.9 3.2-6.4V80H304v24c0 13.3-10.7 24-24 24s-24-10.7-24-24V80H192v24c0 13.3-10.7 24-24 24s-24-10.7-24-24V80H80zm4.7 384H363.3l-16.6-32H101.2L84.7 464zm271.9-80c12 0 22.9 6.7 28.4 17.3l26.5 51.2c3 5.8 4.6 12.2 4.6 18.7c0 22.5-18.2 40.8-40.8 40.8H72.8C50.2 512 32 493.8 32 471.2c0-6.5 1.6-12.9 4.6-18.7l26.5-51.2C68.5 390.7 79.5 384 91.5 384h265zM208 288c-8.8 0-16-7.2-16-16V224c0-17.7 14.3-32 32-32s32 14.3 32 32v48c0 8.8-7.2 16-16 16H208z" } }, "free": ["regular", "solid"] }, "chevron-down": { "aliases": { "unicodes": { "secondary": ["10f078"] } }, "changes": ["1.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["arrow", "download", "expand"] }, "styles": ["solid"], "unicode": "f078", "label": "Chevron Down", "voted": false, "svg": { "solid": { "last_modified": 1684766329, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M233.4 406.6c12.5 12.5 32.8 12.5 45.3 0l192-192c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L256 338.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l192 192z" } }, "free": ["solid"] }, "chevron-left": { "aliases": { "unicodes": { "composite": ["2329"], "secondary": ["10f053"] } }, "changes": ["1.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "Left-Pointing Angle Bracket", "arrow", "back", "bracket", "previous" ] }, "styles": ["solid"], "unicode": "f053", "label": "Chevron Left", "voted": false, "svg": { "solid": { "last_modified": 1684766329, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M9.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l192 192c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L77.3 256 246.6 86.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-192 192z" } }, "free": ["solid"] }, "chevron-right": { "aliases": { "unicodes": { "composite": ["232a"], "secondary": ["10f054"] } }, "changes": ["1.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "Right-Pointing Angle Bracket", "arrow", "bracket", "forward", "next" ] }, "styles": ["solid"], "unicode": "f054", "label": "Chevron Right", "voted": false, "svg": { "solid": { "last_modified": 1684766329, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M310.6 233.4c12.5 12.5 12.5 32.8 0 45.3l-192 192c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L242.7 256 73.4 86.6c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l192 192z" } }, "free": ["solid"] }, "chevron-up": { "aliases": { "unicodes": { "secondary": ["10f077"] } }, "changes": ["1.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["arrow", "collapse", "upload"] }, "styles": ["solid"], "unicode": "f077", "label": "Chevron Up", "voted": false, "svg": { "solid": { "last_modified": 1684766332, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M233.4 105.4c12.5-12.5 32.8-12.5 45.3 0l192 192c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L256 173.3 86.6 342.6c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3l192-192z" } }, "free": ["solid"] }, "child": { "aliases": { "unicodes": { "secondary": ["10f1ae"] } }, "changes": [ "4.1.0", "5.0.0", "6.0.0-beta1", "6.1.1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["boy", "girl", "kid", "toddler", "young", "youth"] }, "styles": ["solid"], "unicode": "f1ae", "label": "Child", "voted": false, "svg": { "solid": { "last_modified": 1684767532, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M96 64a64 64 0 1 1 128 0A64 64 0 1 1 96 64zm48 320v96c0 17.7-14.3 32-32 32s-32-14.3-32-32V287.8L59.1 321c-9.4 15-29.2 19.4-44.1 10S-4.5 301.9 4.9 287l39.9-63.3C69.7 184 113.2 160 160 160s90.3 24 115.2 63.6L315.1 287c9.4 15 4.9 34.7-10 44.1s-34.7 4.9-44.1-10L240 287.8V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V384H144z" } }, "free": ["solid"] }, "child-combatant": { "aliases": { "names": ["child-rifle"] }, "changes": ["6.1.0", "6.2.0", "6.2.1", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["combatant"] }, "styles": ["solid"], "unicode": "e4e0", "label": "Child Combatant", "voted": false, "svg": { "solid": { "last_modified": 1684767531, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M176 128A64 64 0 1 0 176 0a64 64 0 1 0 0 128zm-8 352V352h16V480c0 17.7 14.3 32 32 32s32-14.3 32-32V300.5L260.9 321c9.4 15 29.2 19.4 44.1 10s19.4-29.2 10-44.1l-51.7-82.1c-17.6-27.9-48.3-44.9-81.2-44.9H169.8c-33 0-63.7 16.9-81.2 44.9L36.9 287c-9.4 15-4.9 34.7 10 44.1s34.7 4.9 44.1-10L104 300.5V480c0 17.7 14.3 32 32 32s32-14.3 32-32zM448 0H432 416c-8.8 0-16 7.2-16 16s7.2 16 16 16V132.3c-9.6 5.5-16 15.9-16 27.7v32c-17.7 0-32 14.3-32 32V368c0 17.7 14.3 32 32 32h16v96c0 8.8 7.2 16 16 16h59.5c10.4 0 18-9.8 15.5-19.9L484 400h44c8.8 0 16-7.2 16-16V368c0-8.8-7.2-16-16-16H480V325.3l53.1-17.7c6.5-2.2 10.9-8.3 10.9-15.2V208c0-8.8-7.2-16-16-16H512c-8.8 0-16 7.2-16 16v56l-16 5.3V160c0-11.8-6.4-22.2-16-27.7V16c0-8.8-7.2-16-16-16z" } }, "free": ["solid"] }, "child-dress": { "changes": ["6.1.1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["boy", "girl", "kid", "toddler", "young", "youth"] }, "styles": ["solid"], "unicode": "e59c", "label": "Child Dress", "voted": false, "svg": { "solid": { "last_modified": 1684767532, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M224 64A64 64 0 1 0 96 64a64 64 0 1 0 128 0zM88 400v80c0 17.7 14.3 32 32 32s32-14.3 32-32V400h16v80c0 17.7 14.3 32 32 32s32-14.3 32-32V400h17.8c10.9 0 18.6-10.7 15.2-21.1l-31.1-93.4 28.6 37.8c10.7 14.1 30.8 16.8 44.8 6.2s16.8-30.7 6.2-44.8L254.6 207c-22.4-29.6-57.5-47-94.6-47s-72.2 17.4-94.6 47L6.5 284.7c-10.7 14.1-7.9 34.2 6.2 44.8s34.2 7.9 44.8-6.2l28.7-37.8L55 378.9C51.6 389.3 59.3 400 70.2 400H88z" } }, "free": ["solid"] }, "child-reaching": { "changes": ["6.1.1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["boy", "girl", "kid", "toddler", "young", "youth"] }, "styles": ["solid"], "unicode": "e59d", "label": "Child Reaching", "voted": false, "svg": { "solid": { "last_modified": 1684767532, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M256 64A64 64 0 1 0 128 64a64 64 0 1 0 128 0zM152.9 169.3c-23.7-8.4-44.5-24.3-58.8-45.8L74.6 94.2C64.8 79.5 45 75.6 30.2 85.4s-18.7 29.7-8.9 44.4L40.9 159c18.1 27.1 42.8 48.4 71.1 62.4V480c0 17.7 14.3 32 32 32s32-14.3 32-32V384h32v96c0 17.7 14.3 32 32 32s32-14.3 32-32V221.6c29.1-14.2 54.4-36.2 72.7-64.2l18.2-27.9c9.6-14.8 5.4-34.6-9.4-44.3s-34.6-5.5-44.3 9.4L291 122.4c-21.8 33.4-58.9 53.6-98.8 53.6c-12.6 0-24.9-2-36.6-5.8c-.9-.3-1.8-.7-2.7-.9z" } }, "free": ["solid"] }, "children": { "changes": ["6.1.0", "6.1.1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["boy", "child", "girl", "kid", "kids", "young", "youth"] }, "styles": ["solid"], "unicode": "e4e1", "label": "Children", "voted": false, "svg": { "solid": { "last_modified": 1684767532, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M160 0a64 64 0 1 1 0 128A64 64 0 1 1 160 0zM88 480V400H70.2c-10.9 0-18.6-10.7-15.2-21.1l31.1-93.4L57.5 323.3c-10.7 14.1-30.8 16.8-44.8 6.2s-16.8-30.7-6.2-44.8L65.4 207c22.4-29.6 57.5-47 94.6-47s72.2 17.4 94.6 47l58.9 77.7c10.7 14.1 7.9 34.2-6.2 44.8s-34.2 7.9-44.8-6.2l-28.6-37.8L265 378.9c3.5 10.4-4.3 21.1-15.2 21.1H232v80c0 17.7-14.3 32-32 32s-32-14.3-32-32V400H152v80c0 17.7-14.3 32-32 32s-32-14.3-32-32zM480 0a64 64 0 1 1 0 128A64 64 0 1 1 480 0zm-8 384v96c0 17.7-14.3 32-32 32s-32-14.3-32-32V300.5L395.1 321c-9.4 15-29.2 19.4-44.1 10s-19.4-29.2-10-44.1l51.7-82.1c17.6-27.9 48.3-44.9 81.2-44.9h12.3c33 0 63.7 16.9 81.2 44.9L619.1 287c9.4 15 4.9 34.7-10 44.1s-34.7 4.9-44.1-10L552 300.5V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V384H472z" } }, "free": ["solid"] }, "chrome": { "changes": ["4.4.0", "5.0.0", "6.1.2"], "ligatures": [], "search": { "terms": ["browser"] }, "styles": ["brands"], "unicode": "f268", "label": "Chrome", "voted": false, "svg": { "brands": { "last_modified": 1660014475, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 256C0 209.4 12.47 165.6 34.27 127.1L144.1 318.3C166 357.5 207.9 384 256 384C270.3 384 283.1 381.7 296.8 377.4L220.5 509.6C95.9 492.3 0 385.3 0 256zM365.1 321.6C377.4 302.4 384 279.1 384 256C384 217.8 367.2 183.5 340.7 160H493.4C505.4 189.6 512 222.1 512 256C512 397.4 397.4 511.1 256 512L365.1 321.6zM477.8 128H256C193.1 128 142.3 172.1 130.5 230.7L54.19 98.47C101 38.53 174 0 256 0C350.8 0 433.5 51.48 477.8 128V128zM168 256C168 207.4 207.4 168 256 168C304.6 168 344 207.4 344 256C344 304.6 304.6 344 256 344C207.4 344 168 304.6 168 256z" } }, "free": ["brands"] }, "chromecast": { "changes": ["5.8.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f838", "label": "Chromecast", "voted": false, "svg": { "brands": { "last_modified": 1660014479, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M447.8,64H64c-23.6,0-42.7,19.1-42.7,42.7v63.9H64v-63.9h383.8v298.6H298.6V448H448c23.6,0,42.7-19.1,42.7-42.7V106.7 C490.7,83.1,471.4,64,447.8,64z M21.3,383.6L21.3,383.6l0,63.9h63.9C85.2,412.2,56.6,383.6,21.3,383.6L21.3,383.6z M21.3,298.6V341 c58.9,0,106.6,48.1,106.6,107h42.7C170.7,365.6,103.7,298.7,21.3,298.6z M213.4,448h42.7c-0.5-129.5-105.3-234.3-234.8-234.6l0,42.4 C127.3,255.6,213.3,342,213.4,448z" } }, "free": ["brands"] }, "church": { "aliases": { "unicodes": { "composite": ["26ea"], "secondary": ["10f51d"] } }, "changes": [ "5.0.13", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Christian", "building", "cathedral", "chapel", "church", "community", "cross", "religion" ] }, "styles": ["solid"], "unicode": "f51d", "label": "Church", "voted": true, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M344 24c0-13.3-10.7-24-24-24s-24 10.7-24 24V48H264c-13.3 0-24 10.7-24 24s10.7 24 24 24h32v46.4L183.3 210c-14.5 8.7-23.3 24.3-23.3 41.2V512h96V416c0-35.3 28.7-64 64-64s64 28.7 64 64v96h96V251.2c0-16.9-8.8-32.5-23.3-41.2L344 142.4V96h32c13.3 0 24-10.7 24-24s-10.7-24-24-24H344V24zM24.9 330.3C9.5 338.8 0 354.9 0 372.4V464c0 26.5 21.5 48 48 48h80V273.6L24.9 330.3zM592 512c26.5 0 48-21.5 48-48V372.4c0-17.5-9.5-33.6-24.9-42.1L512 273.6V512h80z" } }, "free": ["solid"] }, "circle": { "aliases": { "unicodes": { "composite": [ "1f534", "1f535", "1f7e0", "1f7e1", "1f7e2", "1f7e3", "1f7e4", "25cf", "26aa", "26ab", "2b24", "f10c", "f1db" ], "secondary": ["10f111"] } }, "changes": [ "3.0.0", "5.0.0", "5.10.1", "5.10.2", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Black Circle", "Black Large Circle", "black circle", "blue", "blue circle", "brown", "brown circle", "chart", "circle", "circle-thin", "diameter", "dot", "ellipse", "fill", "geometric", "green", "green circle", "notification", "orange", "orange circle", "progress", "purple", "purple circle", "red", "red circle", "round", "white circle", "yellow", "yellow circle" ] }, "styles": ["solid", "regular"], "unicode": "f111", "label": "Circle", "voted": false, "svg": { "solid": { "last_modified": 1684767552, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512z" }, "regular": { "last_modified": 1684767552, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M464 256A208 208 0 1 0 48 256a208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256z" } }, "free": ["regular", "solid"] }, "circle-arrow-down": { "aliases": { "names": ["arrow-circle-down"], "unicodes": { "secondary": ["10f0ab"] } }, "changes": ["2.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["download"] }, "styles": ["solid"], "unicode": "f0ab", "label": "Circle Arrow Down", "voted": false, "svg": { "solid": { "last_modified": 1684766331, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 0a256 256 0 1 0 0 512A256 256 0 1 0 256 0zM127 281c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l71 71L232 136c0-13.3 10.7-24 24-24s24 10.7 24 24l0 182.1 71-71c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9L273 393c-9.4 9.4-24.6 9.4-33.9 0L127 281z" } }, "free": ["solid"] }, "circle-arrow-left": { "aliases": { "names": ["arrow-circle-left"], "unicodes": { "secondary": ["10f0a8"] } }, "changes": ["2.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["back", "previous"] }, "styles": ["solid"], "unicode": "f0a8", "label": "Circle Arrow Left", "voted": false, "svg": { "solid": { "last_modified": 1684766331, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M512 256A256 256 0 1 0 0 256a256 256 0 1 0 512 0zM231 127c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-71 71L376 232c13.3 0 24 10.7 24 24s-10.7 24-24 24l-182.1 0 71 71c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0L119 273c-9.4-9.4-9.4-24.6 0-33.9L231 127z" } }, "free": ["solid"] }, "circle-arrow-right": { "aliases": { "names": ["arrow-circle-right"], "unicodes": { "secondary": ["10f0a9"] } }, "changes": ["2.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["forward", "next"] }, "styles": ["solid"], "unicode": "f0a9", "label": "Circle Arrow Right", "voted": false, "svg": { "solid": { "last_modified": 1684766331, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 256a256 256 0 1 0 512 0A256 256 0 1 0 0 256zM281 385c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l71-71L136 280c-13.3 0-24-10.7-24-24s10.7-24 24-24l182.1 0-71-71c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0L393 239c9.4 9.4 9.4 24.6 0 33.9L281 385z" } }, "free": ["solid"] }, "circle-arrow-up": { "aliases": { "names": ["arrow-circle-up"], "unicodes": { "secondary": ["10f0aa"] } }, "changes": ["2.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["upload"] }, "styles": ["solid"], "unicode": "f0aa", "label": "Circle Arrow Up", "voted": false, "svg": { "solid": { "last_modified": 1684766331, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM385 231c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-71-71V376c0 13.3-10.7 24-24 24s-24-10.7-24-24V193.9l-71 71c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9L239 119c9.4-9.4 24.6-9.4 33.9 0L385 231z" } }, "free": ["solid"] }, "circle-check": { "aliases": { "names": ["check-circle"], "unicodes": { "composite": ["f05d"], "secondary": ["10f058"] } }, "changes": [ "1.0.0", "5.0.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "accept", "affected", "agree", "clear", "confirm", "correct", "done", "ok", "select", "success", "tick", "todo", "yes" ] }, "styles": ["solid", "regular"], "unicode": "f058", "label": "Circle Check", "voted": false, "svg": { "solid": { "last_modified": 1684767552, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM369 209L241 337c-9.4 9.4-24.6 9.4-33.9 0l-64-64c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l47 47L335 175c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9z" }, "regular": { "last_modified": 1684767552, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 48a208 208 0 1 1 0 416 208 208 0 1 1 0-416zm0 464A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM369 209c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0l-111 111-47-47c-9.4-9.4-24.6-9.4-33.9 0s-9.4 24.6 0 33.9l64 64c9.4 9.4 24.6 9.4 33.9 0L369 209z" } }, "free": ["regular", "solid"] }, "circle-chevron-down": { "aliases": { "names": ["chevron-circle-down"], "unicodes": { "secondary": ["10f13a"] } }, "changes": ["3.1.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["arrow", "download", "dropdown", "menu", "more"] }, "styles": ["solid"], "unicode": "f13a", "label": "Circle Chevron Down", "voted": false, "svg": { "solid": { "last_modified": 1684766332, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 0a256 256 0 1 0 0 512A256 256 0 1 0 256 0zM135 241c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l87 87 87-87c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9L273 345c-9.4 9.4-24.6 9.4-33.9 0L135 241z" } }, "free": ["solid"] }, "circle-chevron-left": { "aliases": { "names": ["chevron-circle-left"], "unicodes": { "secondary": ["10f137"] } }, "changes": ["3.1.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["arrow", "back", "previous"] }, "styles": ["solid"], "unicode": "f137", "label": "Circle Chevron Left", "voted": false, "svg": { "solid": { "last_modified": 1684766329, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M512 256A256 256 0 1 0 0 256a256 256 0 1 0 512 0zM271 135c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-87 87 87 87c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0L167 273c-9.4-9.4-9.4-24.6 0-33.9L271 135z" } }, "free": ["solid"] }, "circle-chevron-right": { "aliases": { "names": ["chevron-circle-right"], "unicodes": { "secondary": ["10f138"] } }, "changes": ["3.1.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["arrow", "forward", "next"] }, "styles": ["solid"], "unicode": "f138", "label": "Circle Chevron Right", "voted": false, "svg": { "solid": { "last_modified": 1684766332, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 256a256 256 0 1 0 512 0A256 256 0 1 0 0 256zM241 377c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l87-87-87-87c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0L345 239c9.4 9.4 9.4 24.6 0 33.9L241 377z" } }, "free": ["solid"] }, "circle-chevron-up": { "aliases": { "names": ["chevron-circle-up"], "unicodes": { "secondary": ["10f139"] } }, "changes": ["3.1.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["arrow", "collapse", "upload"] }, "styles": ["solid"], "unicode": "f139", "label": "Circle Chevron Up", "voted": false, "svg": { "solid": { "last_modified": 1684766331, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM377 271c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-87-87-87 87c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9L239 167c9.4-9.4 24.6-9.4 33.9 0L377 271z" } }, "free": ["solid"] }, "circle-dollar-to-slot": { "aliases": { "names": ["donate"], "unicodes": { "secondary": ["10f4b9"] } }, "changes": [ "5.0.9", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["contribute", "generosity", "gift", "give"] }, "styles": ["solid"], "unicode": "f4b9", "label": "Circle Dollar To Slot", "voted": false, "svg": { "solid": { "last_modified": 1684766476, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M326.7 403.7c-22.1 8-45.9 12.3-70.7 12.3s-48.7-4.4-70.7-12.3c-.3-.1-.5-.2-.8-.3c-30-11-56.8-28.7-78.6-51.4C70 314.6 48 263.9 48 208C48 93.1 141.1 0 256 0S464 93.1 464 208c0 55.9-22 106.6-57.9 144c-1 1-2 2.1-3 3.1c-21.4 21.4-47.4 38.1-76.3 48.6zM256 91.9c-11.1 0-20.1 9-20.1 20.1v6c-5.6 1.2-10.9 2.9-15.9 5.1c-15 6.8-27.9 19.4-31.1 37.7c-1.8 10.2-.8 20 3.4 29c4.2 8.8 10.7 15 17.3 19.5c11.6 7.9 26.9 12.5 38.6 16l2.2 .7c13.9 4.2 23.4 7.4 29.3 11.7c2.5 1.8 3.4 3.2 3.7 4c.3 .8 .9 2.6 .2 6.7c-.6 3.5-2.5 6.4-8 8.8c-6.1 2.6-16 3.9-28.8 1.9c-6-1-16.7-4.6-26.2-7.9l0 0 0 0 0 0c-2.2-.7-4.3-1.5-6.4-2.1c-10.5-3.5-21.8 2.2-25.3 12.7s2.2 21.8 12.7 25.3c1.2 .4 2.7 .9 4.4 1.5c7.9 2.7 20.3 6.9 29.8 9.1V304c0 11.1 9 20.1 20.1 20.1s20.1-9 20.1-20.1v-5.5c5.3-1 10.5-2.5 15.4-4.6c15.7-6.7 28.4-19.7 31.6-38.7c1.8-10.4 1-20.3-3-29.4c-3.9-9-10.2-15.6-16.9-20.5c-12.2-8.8-28.3-13.7-40.4-17.4l-.8-.2c-14.2-4.3-23.8-7.3-29.9-11.4c-2.6-1.8-3.4-3-3.6-3.5c-.2-.3-.7-1.6-.1-5c.3-1.9 1.9-5.2 8.2-8.1c6.4-2.9 16.4-4.5 28.6-2.6c4.3 .7 17.9 3.3 21.7 4.3c10.7 2.8 21.6-3.5 24.5-14.2s-3.5-21.6-14.2-24.5c-4.4-1.2-14.4-3.2-21-4.4V112c0-11.1-9-20.1-20.1-20.1zM48 352H64c19.5 25.9 44 47.7 72.2 64H64v32H256 448V416H375.8c28.2-16.3 52.8-38.1 72.2-64h16c26.5 0 48 21.5 48 48v64c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V400c0-26.5 21.5-48 48-48z" } }, "free": ["solid"] }, "circle-dot": { "aliases": { "names": ["dot-circle"], "unicodes": { "composite": ["1f518"], "secondary": ["10f192"] } }, "changes": [ "4.0.0", "5.0.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "bullseye", "button", "geometric", "notification", "radio", "radio button", "target" ] }, "styles": ["solid", "regular"], "unicode": "f192", "label": "Circle Dot", "voted": false, "svg": { "solid": { "last_modified": 1684767553, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zm0-352a96 96 0 1 1 0 192 96 96 0 1 1 0-192z" }, "regular": { "last_modified": 1684767553, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M464 256A208 208 0 1 0 48 256a208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm256-96a96 96 0 1 1 0 192 96 96 0 1 1 0-192z" } }, "free": ["regular", "solid"] }, "circle-down": { "aliases": { "names": ["arrow-alt-circle-down"], "unicodes": { "composite": ["f01a"], "secondary": ["10f358"] } }, "changes": ["5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["arrow-circle-o-down", "download"] }, "styles": ["solid", "regular"], "unicode": "f358", "label": "Circle Down", "voted": false, "svg": { "solid": { "last_modified": 1684766329, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 0a256 256 0 1 0 0 512A256 256 0 1 0 256 0zM376.9 294.6L269.8 394.5c-3.8 3.5-8.7 5.5-13.8 5.5s-10.1-2-13.8-5.5L135.1 294.6c-4.5-4.2-7.1-10.1-7.1-16.3c0-12.3 10-22.3 22.3-22.3l57.7 0 0-96c0-17.7 14.3-32 32-32l32 0c17.7 0 32 14.3 32 32l0 96 57.7 0c12.3 0 22.3 10 22.3 22.3c0 6.2-2.6 12.1-7.1 16.3z" }, "regular": { "last_modified": 1684766329, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 464a208 208 0 1 1 0-416 208 208 0 1 1 0 416zM256 0a256 256 0 1 0 0 512A256 256 0 1 0 256 0zM376.9 294.6c4.5-4.2 7.1-10.1 7.1-16.3c0-12.3-10-22.3-22.3-22.3H304V160c0-17.7-14.3-32-32-32l-32 0c-17.7 0-32 14.3-32 32v96H150.3C138 256 128 266 128 278.3c0 6.2 2.6 12.1 7.1 16.3l107.1 99.9c3.8 3.5 8.7 5.5 13.8 5.5s10.1-2 13.8-5.5l107.1-99.9z" } }, "free": ["regular", "solid"] }, "circle-exclamation": { "aliases": { "names": ["exclamation-circle"], "unicodes": { "secondary": ["10f06a"] } }, "changes": ["1.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "affect", "alert", "damage", "danger", "error", "important", "notice", "notification", "notify", "problem", "warning" ] }, "styles": ["solid"], "unicode": "f06a", "label": "Circle Exclamation", "voted": false, "svg": { "solid": { "last_modified": 1684767247, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zm0-384c13.3 0 24 10.7 24 24V264c0 13.3-10.7 24-24 24s-24-10.7-24-24V152c0-13.3 10.7-24 24-24zM224 352a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z" } }, "free": ["solid"] }, "circle-h": { "aliases": { "names": ["hospital-symbol"], "unicodes": { "composite": ["24bd"], "secondary": ["10f47e"] } }, "changes": ["5.0.7", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "Circled Latin Capital Letter H", "clinic", "covid-19", "emergency", "letter", "map" ] }, "styles": ["solid"], "unicode": "f47e", "label": "Circle H", "voted": false, "svg": { "solid": { "last_modified": 1684767248, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM368 152V256 360c0 13.3-10.7 24-24 24s-24-10.7-24-24V280H192l0 80c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-208c0-13.3 10.7-24 24-24s24 10.7 24 24v80H320V152c0-13.3 10.7-24 24-24s24 10.7 24 24z" } }, "free": ["solid"] }, "circle-half-stroke": { "aliases": { "names": ["adjust"], "unicodes": { "composite": ["25d0"], "secondary": ["10f042"] } }, "changes": [ "1.0.0", "5.0.0", "5.10.2", "5.11.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Circle with Left Half Black", "adjust", "chart", "contrast", "dark", "fill", "light", "pie", "progress", "saturation" ] }, "styles": ["solid"], "unicode": "f042", "label": "Circle Half Stroke", "voted": false, "svg": { "solid": { "last_modified": 1684767551, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M448 256c0-106-86-192-192-192V448c106 0 192-86 192-192zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256z" } }, "free": ["solid"] }, "circle-info": { "aliases": { "names": ["info-circle"], "unicodes": { "secondary": ["10f05a"] } }, "changes": ["1.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["details", "help", "information", "more", "support"] }, "styles": ["solid"], "unicode": "f05a", "label": "Circle Info", "voted": false, "svg": { "solid": { "last_modified": 1684767245, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM216 336h24V272H216c-13.3 0-24-10.7-24-24s10.7-24 24-24h48c13.3 0 24 10.7 24 24v88h8c13.3 0 24 10.7 24 24s-10.7 24-24 24H216c-13.3 0-24-10.7-24-24s10.7-24 24-24zm40-208a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" } }, "free": ["solid"] }, "circle-left": { "aliases": { "names": ["arrow-alt-circle-left"], "unicodes": { "composite": ["f190"], "secondary": ["10f359"] } }, "changes": ["5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["arrow-circle-o-left", "back", "previous"] }, "styles": ["solid", "regular"], "unicode": "f359", "label": "Circle Left", "voted": false, "svg": { "solid": { "last_modified": 1684766330, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M512 256A256 256 0 1 0 0 256a256 256 0 1 0 512 0zM217.4 376.9L117.5 269.8c-3.5-3.8-5.5-8.7-5.5-13.8s2-10.1 5.5-13.8l99.9-107.1c4.2-4.5 10.1-7.1 16.3-7.1c12.3 0 22.3 10 22.3 22.3l0 57.7 96 0c17.7 0 32 14.3 32 32l0 32c0 17.7-14.3 32-32 32l-96 0 0 57.7c0 12.3-10 22.3-22.3 22.3c-6.2 0-12.1-2.6-16.3-7.1z" }, "regular": { "last_modified": 1684766330, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M48 256a208 208 0 1 1 416 0A208 208 0 1 1 48 256zm464 0A256 256 0 1 0 0 256a256 256 0 1 0 512 0zM217.4 376.9c4.2 4.5 10.1 7.1 16.3 7.1c12.3 0 22.3-10 22.3-22.3V304h96c17.7 0 32-14.3 32-32V240c0-17.7-14.3-32-32-32H256V150.3c0-12.3-10-22.3-22.3-22.3c-6.2 0-12.1 2.6-16.3 7.1L117.5 242.2c-3.5 3.8-5.5 8.7-5.5 13.8s2 10.1 5.5 13.8l99.9 107.1z" } }, "free": ["regular", "solid"] }, "circle-minus": { "aliases": { "names": ["minus-circle"], "unicodes": { "secondary": ["10f056"] } }, "changes": [ "1.0.0", "5.0.0", "5.10.2", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["delete", "hide", "negative", "remove", "shape", "trash"] }, "styles": ["solid"], "unicode": "f056", "label": "Circle Minus", "voted": false, "svg": { "solid": { "last_modified": 1684767553, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM184 232H328c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24z" } }, "free": ["solid"] }, "circle-nodes": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["cluster", "connect", "network"] }, "styles": ["solid"], "unicode": "e4e2", "label": "Circle Nodes", "voted": false, "svg": { "solid": { "last_modified": 1684767206, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M418.4 157.9c35.3-8.3 61.6-40 61.6-77.9c0-44.2-35.8-80-80-80c-43.4 0-78.7 34.5-80 77.5L136.2 151.1C121.7 136.8 101.9 128 80 128c-44.2 0-80 35.8-80 80s35.8 80 80 80c12.2 0 23.8-2.7 34.1-7.6L259.7 407.8c-2.4 7.6-3.7 15.8-3.7 24.2c0 44.2 35.8 80 80 80s80-35.8 80-80c0-27.7-14-52.1-35.4-66.4l37.8-207.7zM156.3 232.2c2.2-6.9 3.5-14.2 3.7-21.7l183.8-73.5c3.6 3.5 7.4 6.7 11.6 9.5L317.6 354.1c-5.5 1.3-10.8 3.1-15.8 5.5L156.3 232.2z" } }, "free": ["solid"] }, "circle-notch": { "aliases": { "unicodes": { "secondary": ["10f1ce"] } }, "changes": [ "4.1.0", "5.0.0", "5.10.2", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "circle-o-notch", "diameter", "dot", "ellipse", "round", "spinner" ] }, "styles": ["solid"], "unicode": "f1ce", "label": "Circle Notch", "voted": false, "svg": { "solid": { "last_modified": 1684767553, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M222.7 32.1c5 16.9-4.6 34.8-21.5 39.8C121.8 95.6 64 169.1 64 256c0 106 86 192 192 192s192-86 192-192c0-86.9-57.8-160.4-137.1-184.1c-16.9-5-26.6-22.9-21.5-39.8s22.9-26.6 39.8-21.5C434.9 42.1 512 140 512 256c0 141.4-114.6 256-256 256S0 397.4 0 256C0 140 77.1 42.1 182.9 10.6c16.9-5 34.8 4.6 39.8 21.5z" } }, "free": ["solid"] }, "circle-pause": { "aliases": { "names": ["pause-circle"], "unicodes": { "composite": ["f28c"], "secondary": ["10f28b"] } }, "changes": ["4.5.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["hold", "wait"] }, "styles": ["solid", "regular"], "unicode": "f28b", "label": "Circle Pause", "voted": false, "svg": { "solid": { "last_modified": 1684766676, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM224 192V320c0 17.7-14.3 32-32 32s-32-14.3-32-32V192c0-17.7 14.3-32 32-32s32 14.3 32 32zm128 0V320c0 17.7-14.3 32-32 32s-32-14.3-32-32V192c0-17.7 14.3-32 32-32s32 14.3 32 32z" }, "regular": { "last_modified": 1684766676, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M464 256A208 208 0 1 0 48 256a208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm224-72V328c0 13.3-10.7 24-24 24s-24-10.7-24-24V184c0-13.3 10.7-24 24-24s24 10.7 24 24zm112 0V328c0 13.3-10.7 24-24 24s-24-10.7-24-24V184c0-13.3 10.7-24 24-24s24 10.7 24 24z" } }, "free": ["regular", "solid"] }, "circle-play": { "aliases": { "names": ["play-circle"], "unicodes": { "composite": ["f01d"], "secondary": ["10f144"] } }, "changes": [ "3.1.0", "5.0.0", "5.10.2", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["audio", "music", "playing", "sound", "start", "video"] }, "styles": ["solid", "regular"], "unicode": "f144", "label": "Circle Play", "voted": false, "svg": { "solid": { "last_modified": 1684766676, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zM188.3 147.1c-7.6 4.2-12.3 12.3-12.3 20.9V344c0 8.7 4.7 16.7 12.3 20.9s16.8 4.1 24.3-.5l144-88c7.1-4.4 11.5-12.1 11.5-20.5s-4.4-16.1-11.5-20.5l-144-88c-7.4-4.5-16.7-4.7-24.3-.5z" }, "regular": { "last_modified": 1684766676, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M464 256A208 208 0 1 0 48 256a208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zM188.3 147.1c7.6-4.2 16.8-4.1 24.3 .5l144 88c7.1 4.4 11.5 12.1 11.5 20.5s-4.4 16.1-11.5 20.5l-144 88c-7.4 4.5-16.7 4.7-24.3 .5s-12.3-12.2-12.3-20.9V168c0-8.7 4.7-16.7 12.3-20.9z" } }, "free": ["regular", "solid"] }, "circle-plus": { "aliases": { "names": ["plus-circle"], "unicodes": { "secondary": ["10f055"] } }, "changes": [ "1.0.0", "5.0.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["add", "create", "expand", "new", "positive", "shape"] }, "styles": ["solid"], "unicode": "f055", "label": "Circle Plus", "voted": false, "svg": { "solid": { "last_modified": 1684767551, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM232 344V280H168c-13.3 0-24-10.7-24-24s10.7-24 24-24h64V168c0-13.3 10.7-24 24-24s24 10.7 24 24v64h64c13.3 0 24 10.7 24 24s-10.7 24-24 24H280v64c0 13.3-10.7 24-24 24s-24-10.7-24-24z" } }, "free": ["solid"] }, "circle-question": { "aliases": { "names": ["question-circle"], "unicodes": { "composite": ["f29c"], "secondary": ["10f059"] } }, "changes": ["1.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["help", "information", "support", "unknown"] }, "styles": ["solid", "regular"], "unicode": "f059", "label": "Circle Question", "voted": false, "svg": { "solid": { "last_modified": 1684767246, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM169.8 165.3c7.9-22.3 29.1-37.3 52.8-37.3h58.3c34.9 0 63.1 28.3 63.1 63.1c0 22.6-12.1 43.5-31.7 54.8L280 264.4c-.2 13-10.9 23.6-24 23.6c-13.3 0-24-10.7-24-24V250.5c0-8.6 4.6-16.5 12.1-20.8l44.3-25.4c4.7-2.7 7.6-7.7 7.6-13.1c0-8.4-6.8-15.1-15.1-15.1H222.6c-3.4 0-6.4 2.1-7.5 5.3l-.4 1.2c-4.4 12.5-18.2 19-30.6 14.6s-19-18.2-14.6-30.6l.4-1.2zM224 352a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z" }, "regular": { "last_modified": 1684767246, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M464 256A208 208 0 1 0 48 256a208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm169.8-90.7c7.9-22.3 29.1-37.3 52.8-37.3h58.3c34.9 0 63.1 28.3 63.1 63.1c0 22.6-12.1 43.5-31.7 54.8L280 264.4c-.2 13-10.9 23.6-24 23.6c-13.3 0-24-10.7-24-24V250.5c0-8.6 4.6-16.5 12.1-20.8l44.3-25.4c4.7-2.7 7.6-7.7 7.6-13.1c0-8.4-6.8-15.1-15.1-15.1H222.6c-3.4 0-6.4 2.1-7.5 5.3l-.4 1.2c-4.4 12.5-18.2 19-30.6 14.6s-19-18.2-14.6-30.6l.4-1.2zM224 352a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z" } }, "free": ["regular", "solid"] }, "circle-radiation": { "aliases": { "names": ["radiation-alt"], "unicodes": { "composite": ["2622"], "secondary": ["10f7ba"] } }, "changes": [ "5.6.0", "5.8.2", "5.11.0", "5.11.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "danger", "dangerous", "deadly", "hazard", "nuclear", "radioactive", "sign", "warning" ] }, "styles": ["solid"], "unicode": "f7ba", "label": "Circle Radiation", "voted": true, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 64a192 192 0 1 1 0 384 192 192 0 1 1 0-384zm0 448A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM200 256c0-20.7 11.3-38.8 28-48.5l-36-62.3c-8.8-15.3-28.7-20.8-42-9c-25.6 22.6-43.9 53.3-50.9 88.1C95.7 241.5 110.3 256 128 256l72 0zm28 48.5l-36 62.4c-8.8 15.3-3.6 35.2 13.1 40.8c16 5.4 33.1 8.3 50.9 8.3s34.9-2.9 50.9-8.3c16.7-5.6 21.9-25.5 13.1-40.8l-36-62.4c-8.2 4.8-17.8 7.5-28 7.5s-19.8-2.7-28-7.5zM312 256l72 0c17.7 0 32.3-14.5 28.8-31.8c-7-34.8-25.3-65.5-50.9-88.1c-13.2-11.7-33.1-6.3-42 9l-36 62.3c16.7 9.7 28 27.8 28 48.5zm-56 32a32 32 0 1 0 0-64 32 32 0 1 0 0 64z" } }, "free": ["solid"] }, "circle-right": { "aliases": { "names": ["arrow-alt-circle-right"], "unicodes": { "composite": ["f18e"], "secondary": ["10f35a"] } }, "changes": ["5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["arrow-circle-o-right", "forward", "next"] }, "styles": ["solid", "regular"], "unicode": "f35a", "label": "Circle Right", "voted": false, "svg": { "solid": { "last_modified": 1684766330, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 256a256 256 0 1 0 512 0A256 256 0 1 0 0 256zM294.6 135.1l99.9 107.1c3.5 3.8 5.5 8.7 5.5 13.8s-2 10.1-5.5 13.8L294.6 376.9c-4.2 4.5-10.1 7.1-16.3 7.1C266 384 256 374 256 361.7l0-57.7-96 0c-17.7 0-32-14.3-32-32l0-32c0-17.7 14.3-32 32-32l96 0 0-57.7c0-12.3 10-22.3 22.3-22.3c6.2 0 12.1 2.6 16.3 7.1z" }, "regular": { "last_modified": 1684766330, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M464 256A208 208 0 1 1 48 256a208 208 0 1 1 416 0zM0 256a256 256 0 1 0 512 0A256 256 0 1 0 0 256zM294.6 135.1c-4.2-4.5-10.1-7.1-16.3-7.1C266 128 256 138 256 150.3V208H160c-17.7 0-32 14.3-32 32v32c0 17.7 14.3 32 32 32h96v57.7c0 12.3 10 22.3 22.3 22.3c6.2 0 12.1-2.6 16.3-7.1l99.9-107.1c3.5-3.8 5.5-8.7 5.5-13.8s-2-10.1-5.5-13.8L294.6 135.1z" } }, "free": ["regular", "solid"] }, "circle-stop": { "aliases": { "names": ["stop-circle"], "unicodes": { "composite": ["f28e"], "secondary": ["10f28d"] } }, "changes": ["4.5.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["block", "box", "circle", "square"] }, "styles": ["solid", "regular"], "unicode": "f28d", "label": "Circle Stop", "voted": false, "svg": { "solid": { "last_modified": 1684766676, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM192 160H320c17.7 0 32 14.3 32 32V320c0 17.7-14.3 32-32 32H192c-17.7 0-32-14.3-32-32V192c0-17.7 14.3-32 32-32z" }, "regular": { "last_modified": 1684766676, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M464 256A208 208 0 1 0 48 256a208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm192-96H320c17.7 0 32 14.3 32 32V320c0 17.7-14.3 32-32 32H192c-17.7 0-32-14.3-32-32V192c0-17.7 14.3-32 32-32z" } }, "free": ["regular", "solid"] }, "circle-up": { "aliases": { "names": ["arrow-alt-circle-up"], "unicodes": { "composite": ["f01b"], "secondary": ["10f35b"] } }, "changes": ["5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["arrow-circle-o-up"] }, "styles": ["solid", "regular"], "unicode": "f35b", "label": "Circle Up", "voted": false, "svg": { "solid": { "last_modified": 1684766330, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM135.1 217.4l107.1-99.9c3.8-3.5 8.7-5.5 13.8-5.5s10.1 2 13.8 5.5l107.1 99.9c4.5 4.2 7.1 10.1 7.1 16.3c0 12.3-10 22.3-22.3 22.3H304v96c0 17.7-14.3 32-32 32H240c-17.7 0-32-14.3-32-32V256H150.3C138 256 128 246 128 233.7c0-6.2 2.6-12.1 7.1-16.3z" }, "regular": { "last_modified": 1684766330, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 48a208 208 0 1 1 0 416 208 208 0 1 1 0-416zm0 464A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM135.1 217.4c-4.5 4.2-7.1 10.1-7.1 16.3c0 12.3 10 22.3 22.3 22.3H208v96c0 17.7 14.3 32 32 32h32c17.7 0 32-14.3 32-32V256h57.7c12.3 0 22.3-10 22.3-22.3c0-6.2-2.6-12.1-7.1-16.3L269.8 117.5c-3.8-3.5-8.7-5.5-13.8-5.5s-10.1 2-13.8 5.5L135.1 217.4z" } }, "free": ["regular", "solid"] }, "circle-user": { "aliases": { "names": ["user-circle"], "unicodes": { "composite": ["f2be"], "secondary": ["10f2bd"] } }, "changes": [ "4.7.0", "5.0.0", "5.0.3", "5.0.11", "5.11.0", "5.11.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["users-people"] }, "styles": ["solid", "regular"], "unicode": "f2bd", "label": "Circle User", "voted": false, "svg": { "solid": { "last_modified": 1684767620, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M399 384.2C376.9 345.8 335.4 320 288 320H224c-47.4 0-88.9 25.8-111 64.2c35.2 39.2 86.2 63.8 143 63.8s107.8-24.7 143-63.8zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm256 16a72 72 0 1 0 0-144 72 72 0 1 0 0 144z" }, "regular": { "last_modified": 1684767620, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M406.5 399.6C387.4 352.9 341.5 320 288 320H224c-53.5 0-99.4 32.9-118.5 79.6C69.9 362.2 48 311.7 48 256C48 141.1 141.1 48 256 48s208 93.1 208 208c0 55.7-21.9 106.2-57.5 143.6zm-40.1 32.7C334.4 452.4 296.6 464 256 464s-78.4-11.6-110.5-31.7c7.3-36.7 39.7-64.3 78.5-64.3h64c38.8 0 71.2 27.6 78.5 64.3zM256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zm0-272a40 40 0 1 1 0-80 40 40 0 1 1 0 80zm-88-40a88 88 0 1 0 176 0 88 88 0 1 0 -176 0z" } }, "free": ["regular", "solid"] }, "circle-xmark": { "aliases": { "names": ["times-circle", "xmark-circle"], "unicodes": { "composite": ["f05c"], "secondary": ["10f057"] } }, "changes": [ "1.0.0", "5.0.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "close", "cross", "destroy", "exit", "incorrect", "notice", "notification", "notify", "problem", "wrong", "x" ] }, "styles": ["solid", "regular"], "unicode": "f057", "label": "Circle Xmark", "voted": false, "svg": { "solid": { "last_modified": 1684767551, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM175 175c9.4-9.4 24.6-9.4 33.9 0l47 47 47-47c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-47 47 47 47c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-47-47-47 47c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l47-47-47-47c-9.4-9.4-9.4-24.6 0-33.9z" }, "regular": { "last_modified": 1684767551, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 48a208 208 0 1 1 0 416 208 208 0 1 1 0-416zm0 464A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM175 175c-9.4 9.4-9.4 24.6 0 33.9l47 47-47 47c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l47-47 47 47c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9l-47-47 47-47c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0l-47 47-47-47c-9.4-9.4-24.6-9.4-33.9 0z" } }, "free": ["regular", "solid"] }, "city": { "aliases": { "unicodes": { "composite": ["1f3d9"], "secondary": ["10f64f"] } }, "changes": [ "5.3.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "buildings", "busy", "city", "cityscape", "skyscrapers", "urban", "windows" ] }, "styles": ["solid"], "unicode": "f64f", "label": "City", "voted": false, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M480 48c0-26.5-21.5-48-48-48H336c-26.5 0-48 21.5-48 48V96H224V24c0-13.3-10.7-24-24-24s-24 10.7-24 24V96H112V24c0-13.3-10.7-24-24-24S64 10.7 64 24V96H48C21.5 96 0 117.5 0 144v96V464c0 26.5 21.5 48 48 48H304h32 96H592c26.5 0 48-21.5 48-48V240c0-26.5-21.5-48-48-48H480V48zm96 320v32c0 8.8-7.2 16-16 16H528c-8.8 0-16-7.2-16-16V368c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16zM240 416H208c-8.8 0-16-7.2-16-16V368c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16zM128 400c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V368c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32zM560 256c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H528c-8.8 0-16-7.2-16-16V272c0-8.8 7.2-16 16-16h32zM256 176v32c0 8.8-7.2 16-16 16H208c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16zM112 160c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h32zM256 304c0 8.8-7.2 16-16 16H208c-8.8 0-16-7.2-16-16V272c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32zM112 320H80c-8.8 0-16-7.2-16-16V272c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16zm304-48v32c0 8.8-7.2 16-16 16H368c-8.8 0-16-7.2-16-16V272c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16zM400 64c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H368c-8.8 0-16-7.2-16-16V80c0-8.8 7.2-16 16-16h32zm16 112v32c0 8.8-7.2 16-16 16H368c-8.8 0-16-7.2-16-16V176c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16z" } }, "free": ["solid"] }, "clapperboard": { "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "camera", "clapper", "clapper board", "director", "film", "movie", "record" ] }, "styles": ["solid"], "unicode": "e131", "label": "Clapperboard", "voted": true, "svg": { "solid": { "last_modified": 1684767342, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M448 32H361.9l-1 1-127 127h92.1l1-1L453.8 32.3c-1.9-.2-3.8-.3-5.8-.3zm64 128V96c0-15.1-5.3-29.1-14-40l-104 104H512zM294.1 32H201.9l-1 1L73.9 160h92.1l1-1 127-127zM64 32C28.7 32 0 60.7 0 96v64H6.1l1-1 127-127H64zM512 192H0V416c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V192z" } }, "free": ["solid"] }, "clipboard": { "aliases": { "unicodes": { "composite": ["1f4cb"], "secondary": ["10f328"] } }, "changes": ["5.0.0", "6.0.0-beta1", "6.2.0", "6.2.1", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["clipboar", "clipboard", "copy", "notes", "paste", "record"] }, "styles": ["solid", "regular"], "unicode": "f328", "label": "Clipboard", "voted": false, "svg": { "solid": { "last_modified": 1684767392, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M192 0c-41.8 0-77.4 26.7-90.5 64H64C28.7 64 0 92.7 0 128V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V128c0-35.3-28.7-64-64-64H282.5C269.4 26.7 233.8 0 192 0zm0 64a32 32 0 1 1 0 64 32 32 0 1 1 0-64zM112 192H272c8.8 0 16 7.2 16 16s-7.2 16-16 16H112c-8.8 0-16-7.2-16-16s7.2-16 16-16z" }, "regular": { "last_modified": 1684767392, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M280 64h40c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128C0 92.7 28.7 64 64 64h40 9.6C121 27.5 153.3 0 192 0s71 27.5 78.4 64H280zM64 112c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16H320c8.8 0 16-7.2 16-16V128c0-8.8-7.2-16-16-16H304v24c0 13.3-10.7 24-24 24H192 104c-13.3 0-24-10.7-24-24V112H64zm128-8a24 24 0 1 0 0-48 24 24 0 1 0 0 48z" } }, "free": ["regular", "solid"] }, "clipboard-check": { "aliases": { "unicodes": { "secondary": ["10f46c"] } }, "changes": ["5.0.7", "6.0.0-beta1", "6.2.0", "6.2.1", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "accept", "agree", "confirm", "done", "ok", "select", "success", "tick", "todo", "yes" ] }, "styles": ["solid"], "unicode": "f46c", "label": "Clipboard Check", "voted": false, "svg": { "solid": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M192 0c-41.8 0-77.4 26.7-90.5 64H64C28.7 64 0 92.7 0 128V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V128c0-35.3-28.7-64-64-64H282.5C269.4 26.7 233.8 0 192 0zm0 64a32 32 0 1 1 0 64 32 32 0 1 1 0-64zM305 273L177 401c-9.4 9.4-24.6 9.4-33.9 0L79 337c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l47 47L271 239c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9z" } }, "free": ["solid"] }, "clipboard-list": { "aliases": { "unicodes": { "secondary": ["10f46d"] } }, "changes": ["5.0.7", "6.0.0-beta1", "6.2.0", "6.2.1", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "checklist", "completed", "done", "finished", "intinerary", "ol", "schedule", "tick", "todo", "ul" ] }, "styles": ["solid"], "unicode": "f46d", "label": "Clipboard List", "voted": false, "svg": { "solid": { "last_modified": 1684767393, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M192 0c-41.8 0-77.4 26.7-90.5 64H64C28.7 64 0 92.7 0 128V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V128c0-35.3-28.7-64-64-64H282.5C269.4 26.7 233.8 0 192 0zm0 64a32 32 0 1 1 0 64 32 32 0 1 1 0-64zM72 272a24 24 0 1 1 48 0 24 24 0 1 1 -48 0zm104-16H304c8.8 0 16 7.2 16 16s-7.2 16-16 16H176c-8.8 0-16-7.2-16-16s7.2-16 16-16zM72 368a24 24 0 1 1 48 0 24 24 0 1 1 -48 0zm88 0c0-8.8 7.2-16 16-16H304c8.8 0 16 7.2 16 16s-7.2 16-16 16H176c-8.8 0-16-7.2-16-16z" } }, "free": ["solid"] }, "clipboard-question": { "changes": ["6.1.0", "6.2.0", "6.2.1", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["assistance", "interview", "query", "question"] }, "styles": ["solid"], "unicode": "e4e3", "label": "Clipboard Question", "voted": false, "svg": { "solid": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M192 0c-41.8 0-77.4 26.7-90.5 64H64C28.7 64 0 92.7 0 128V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V128c0-35.3-28.7-64-64-64H282.5C269.4 26.7 233.8 0 192 0zm0 64a32 32 0 1 1 0 64 32 32 0 1 1 0-64zM105.8 229.3c7.9-22.3 29.1-37.3 52.8-37.3h58.3c34.9 0 63.1 28.3 63.1 63.1c0 22.6-12.1 43.5-31.7 54.8L216 328.4c-.2 13-10.9 23.6-24 23.6c-13.3 0-24-10.7-24-24V314.5c0-8.6 4.6-16.5 12.1-20.8l44.3-25.4c4.7-2.7 7.6-7.7 7.6-13.1c0-8.4-6.8-15.1-15.1-15.1H158.6c-3.4 0-6.4 2.1-7.5 5.3l-.4 1.2c-4.4 12.5-18.2 19-30.6 14.6s-19-18.2-14.6-30.6l.4-1.2zM160 416a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z" } }, "free": ["solid"] }, "clipboard-user": { "aliases": { "unicodes": { "secondary": ["10f7f3"] } }, "changes": [ "5.7.0", "6.0.0-beta1", "6.1.0", "6.2.0", "6.2.1", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["attendance", "record", "roster", "staff"] }, "styles": ["solid"], "unicode": "f7f3", "label": "Clipboard User", "voted": false, "svg": { "solid": { "last_modified": 1684767390, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M192 0c-41.8 0-77.4 26.7-90.5 64H64C28.7 64 0 92.7 0 128V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V128c0-35.3-28.7-64-64-64H282.5C269.4 26.7 233.8 0 192 0zm0 64a32 32 0 1 1 0 64 32 32 0 1 1 0-64zM128 256a64 64 0 1 1 128 0 64 64 0 1 1 -128 0zM80 432c0-44.2 35.8-80 80-80h64c44.2 0 80 35.8 80 80c0 8.8-7.2 16-16 16H96c-8.8 0-16-7.2-16-16z" } }, "free": ["solid"] }, "clock": { "aliases": { "names": ["clock-four"], "unicodes": { "composite": ["1f553"], "secondary": ["10f017"] } }, "changes": [ "1.0.0", "5.0.0", "5.12.1", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "00", "4", "4:00", "clock", "date", "four", "four o’clock", "hour", "late", "minute", "o'clock", "o’clock", "schedule", "ticking", "time", "timer", "timestamp", "watch" ] }, "styles": ["solid", "regular"], "unicode": "f017", "label": "Clock", "voted": false, "svg": { "solid": { "last_modified": 1684767327, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 0a256 256 0 1 1 0 512A256 256 0 1 1 256 0zM232 120V256c0 8 4 15.5 10.7 20l96 64c11 7.4 25.9 4.4 33.3-6.7s4.4-25.9-6.7-33.3L280 243.2V120c0-13.3-10.7-24-24-24s-24 10.7-24 24z" }, "regular": { "last_modified": 1684767327, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M464 256A208 208 0 1 1 48 256a208 208 0 1 1 416 0zM0 256a256 256 0 1 0 512 0A256 256 0 1 0 0 256zM232 120V256c0 8 4 15.5 10.7 20l96 64c11 7.4 25.9 4.4 33.3-6.7s4.4-25.9-6.7-33.3L280 243.2V120c0-13.3-10.7-24-24-24s-24 10.7-24 24z" } }, "free": ["regular", "solid"] }, "clock-rotate-left": { "aliases": { "names": ["history"], "unicodes": { "secondary": ["10f1da"] } }, "changes": [ "4.1.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Rewind", "clock", "reverse", "time", "time machine", "time travel" ] }, "styles": ["solid"], "unicode": "f1da", "label": "Clock Rotate Left", "voted": false, "svg": { "solid": { "last_modified": 1684767327, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M75 75L41 41C25.9 25.9 0 36.6 0 57.9V168c0 13.3 10.7 24 24 24H134.1c21.4 0 32.1-25.9 17-41l-30.8-30.8C155 85.5 203 64 256 64c106 0 192 86 192 192s-86 192-192 192c-40.8 0-78.6-12.7-109.7-34.4c-14.5-10.1-34.4-6.6-44.6 7.9s-6.6 34.4 7.9 44.6C151.2 495 201.7 512 256 512c141.4 0 256-114.6 256-256S397.4 0 256 0C185.3 0 121.3 28.7 75 75zm181 53c-13.3 0-24 10.7-24 24V256c0 6.4 2.5 12.5 7 17l72 72c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9l-65-65V152c0-13.3-10.7-24-24-24z" } }, "free": ["solid"] }, "clone": { "aliases": { "unicodes": { "secondary": ["10f24d"] } }, "changes": [ "4.4.0", "5.0.0", "5.11.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["arrange", "copy", "duplicate", "paste"] }, "styles": ["solid", "regular"], "unicode": "f24d", "label": "Clone", "voted": false, "svg": { "solid": { "last_modified": 1684767366, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M288 448H64V224h64V160H64c-35.3 0-64 28.7-64 64V448c0 35.3 28.7 64 64 64H288c35.3 0 64-28.7 64-64V384H288v64zm-64-96H448c35.3 0 64-28.7 64-64V64c0-35.3-28.7-64-64-64H224c-35.3 0-64 28.7-64 64V288c0 35.3 28.7 64 64 64z" }, "regular": { "last_modified": 1684767366, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M64 464H288c8.8 0 16-7.2 16-16V384h48v64c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V224c0-35.3 28.7-64 64-64h64v48H64c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16zM224 304H448c8.8 0 16-7.2 16-16V64c0-8.8-7.2-16-16-16H224c-8.8 0-16 7.2-16 16V288c0 8.8 7.2 16 16 16zm-64-16V64c0-35.3 28.7-64 64-64H448c35.3 0 64 28.7 64 64V288c0 35.3-28.7 64-64 64H224c-35.3 0-64-28.7-64-64z" } }, "free": ["regular", "solid"] }, "closed-captioning": { "aliases": { "unicodes": { "secondary": ["10f20a"] } }, "changes": [ "4.2.0", "5.0.0", "5.10.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "cc", "deaf", "hearing", "subtitle", "subtitling", "text", "video" ] }, "styles": ["solid", "regular"], "unicode": "f20a", "label": "Closed Captioning", "voted": false, "svg": { "solid": { "last_modified": 1684766675, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M0 96C0 60.7 28.7 32 64 32H512c35.3 0 64 28.7 64 64V416c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V96zM200 208c14.2 0 27 6.1 35.8 16c8.8 9.9 24 10.7 33.9 1.9s10.7-24 1.9-33.9c-17.5-19.6-43.1-32-71.5-32c-53 0-96 43-96 96s43 96 96 96c28.4 0 54-12.4 71.5-32c8.8-9.9 8-25-1.9-33.9s-25-8-33.9 1.9c-8.8 9.9-21.6 16-35.8 16c-26.5 0-48-21.5-48-48s21.5-48 48-48zm144 48c0-26.5 21.5-48 48-48c14.2 0 27 6.1 35.8 16c8.8 9.9 24 10.7 33.9 1.9s10.7-24 1.9-33.9c-17.5-19.6-43.1-32-71.5-32c-53 0-96 43-96 96s43 96 96 96c28.4 0 54-12.4 71.5-32c8.8-9.9 8-25-1.9-33.9s-25-8-33.9 1.9c-8.8 9.9-21.6 16-35.8 16c-26.5 0-48-21.5-48-48z" }, "regular": { "last_modified": 1684766675, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M512 80c8.8 0 16 7.2 16 16V416c0 8.8-7.2 16-16 16H64c-8.8 0-16-7.2-16-16V96c0-8.8 7.2-16 16-16H512zM64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H512c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zM200 208c14.2 0 27 6.1 35.8 16c8.8 9.9 24 10.7 33.9 1.9s10.7-24 1.9-33.9c-17.5-19.6-43.1-32-71.5-32c-53 0-96 43-96 96s43 96 96 96c28.4 0 54-12.4 71.5-32c8.8-9.9 8-25-1.9-33.9s-25-8-33.9 1.9c-8.8 9.9-21.6 16-35.8 16c-26.5 0-48-21.5-48-48s21.5-48 48-48zm144 48c0-26.5 21.5-48 48-48c14.2 0 27 6.1 35.8 16c8.8 9.9 24 10.7 33.9 1.9s10.7-24 1.9-33.9c-17.5-19.6-43.1-32-71.5-32c-53 0-96 43-96 96s43 96 96 96c28.4 0 54-12.4 71.5-32c8.8-9.9 8-25-1.9-33.9s-25-8-33.9 1.9c-8.8 9.9-21.6 16-35.8 16c-26.5 0-48-21.5-48-48z" } }, "free": ["regular", "solid"] }, "cloud": { "aliases": { "unicodes": { "composite": ["2601"], "secondary": ["10f0c2"] } }, "changes": [ "2.0.0", "5.0.0", "5.0.11", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "atmosphere", "cloud", "fog", "overcast", "save", "upload", "weather" ] }, "styles": ["solid"], "unicode": "f0c2", "label": "Cloud", "voted": false, "svg": { "solid": { "last_modified": 1684767553, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M0 336c0 79.5 64.5 144 144 144H512c70.7 0 128-57.3 128-128c0-61.9-44-113.6-102.4-125.4c4.1-10.7 6.4-22.4 6.4-34.6c0-53-43-96-96-96c-19.7 0-38.1 6-53.3 16.2C367 64.2 315.3 32 256 32C167.6 32 96 103.6 96 192c0 2.7 .1 5.4 .2 8.1C40.2 219.8 0 273.2 0 336z" } }, "free": ["solid"] }, "cloud-arrow-down": { "aliases": { "names": ["cloud-download", "cloud-download-alt"], "unicodes": { "composite": ["f381"], "primary": ["f381"], "secondary": ["10f0ed", "10f381"] } }, "changes": [ "3.0.0", "5.0.0", "5.0.11", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["download", "export", "save"] }, "styles": ["solid"], "unicode": "f0ed", "label": "Cloud Arrow Down", "voted": false, "svg": { "solid": { "last_modified": 1684767552, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M144 480C64.5 480 0 415.5 0 336c0-62.8 40.2-116.2 96.2-135.9c-.1-2.7-.2-5.4-.2-8.1c0-88.4 71.6-160 160-160c59.3 0 111 32.2 138.7 80.2C409.9 102 428.3 96 448 96c53 0 96 43 96 96c0 12.2-2.3 23.8-6.4 34.6C596 238.4 640 290.1 640 352c0 70.7-57.3 128-128 128H144zm79-167l80 80c9.4 9.4 24.6 9.4 33.9 0l80-80c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0l-39 39V184c0-13.3-10.7-24-24-24s-24 10.7-24 24V318.1l-39-39c-9.4-9.4-24.6-9.4-33.9 0s-9.4 24.6 0 33.9z" } }, "free": ["solid"] }, "cloud-arrow-up": { "aliases": { "names": ["cloud-upload", "cloud-upload-alt"], "unicodes": { "composite": ["f382"], "primary": ["f382"], "secondary": ["10f0ee", "10f382"] } }, "changes": [ "3.0.0", "5.0.0", "5.0.11", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["import", "save", "upload"] }, "styles": ["solid"], "unicode": "f0ee", "label": "Cloud Arrow Up", "voted": false, "svg": { "solid": { "last_modified": 1684767552, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M144 480C64.5 480 0 415.5 0 336c0-62.8 40.2-116.2 96.2-135.9c-.1-2.7-.2-5.4-.2-8.1c0-88.4 71.6-160 160-160c59.3 0 111 32.2 138.7 80.2C409.9 102 428.3 96 448 96c53 0 96 43 96 96c0 12.2-2.3 23.8-6.4 34.6C596 238.4 640 290.1 640 352c0 70.7-57.3 128-128 128H144zm79-217c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l39-39V392c0 13.3 10.7 24 24 24s24-10.7 24-24V257.9l39 39c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9l-80-80c-9.4-9.4-24.6-9.4-33.9 0l-80 80z" } }, "free": ["solid"] }, "cloud-bolt": { "aliases": { "names": ["thunderstorm"], "unicodes": { "composite": ["1f329"], "secondary": ["10f76c"] } }, "changes": ["5.5.0", "6.0.0-beta1", "6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "bolt", "cloud", "cloud with lightning", "lightning", "precipitation", "rain", "storm", "weather" ] }, "styles": ["solid"], "unicode": "f76c", "label": "Cloud Bolt", "voted": false, "svg": { "solid": { "last_modified": 1684767662, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 224c0 53 43 96 96 96h47.2L290 202.5c17.6-14.1 42.6-14 60.2 .2s22.8 38.6 12.8 58.8L333.7 320H352h64c53 0 96-43 96-96s-43-96-96-96c-.5 0-1.1 0-1.6 0c1.1-5.2 1.6-10.5 1.6-16c0-44.2-35.8-80-80-80c-24.3 0-46.1 10.9-60.8 28C256.5 24.3 219.1 0 176 0C114.1 0 64 50.1 64 112c0 7.1 .7 14.1 1.9 20.8C27.6 145.4 0 181.5 0 224zm330.1 3.6c-5.8-4.7-14.2-4.7-20.1-.1l-160 128c-5.3 4.2-7.4 11.4-5.1 17.8s8.3 10.7 15.1 10.7h70.1L177.7 488.8c-3.4 6.7-1.6 14.9 4.3 19.6s14.2 4.7 20.1 .1l160-128c5.3-4.2 7.4-11.4 5.1-17.8s-8.3-10.7-15.1-10.7H281.9l52.4-104.8c3.4-6.7 1.6-14.9-4.2-19.6z" } }, "free": ["solid"] }, "cloud-meatball": { "aliases": { "unicodes": { "secondary": ["10f73b"] } }, "changes": ["5.5.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["FLDSMDFR", "food", "spaghetti", "storm"] }, "styles": ["solid"], "unicode": "f73b", "label": "Cloud Meatball", "voted": false, "svg": { "solid": { "last_modified": 1684767662, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 224c0 53 43 96 96 96h44.7c9.5-23.5 32.5-40 59.3-40c2 0 3.9 .1 5.8 .3C217.6 265.5 235.7 256 256 256s38.4 9.5 50.2 24.3c1.9-.2 3.9-.3 5.8-.3c26.9 0 49.9 16.5 59.3 40H416c53 0 96-43 96-96s-43-96-96-96c-.5 0-1.1 0-1.6 0c1.1-5.2 1.6-10.5 1.6-16c0-44.2-35.8-80-80-80c-24.3 0-46.1 10.9-60.8 28C256.5 24.3 219.1 0 176 0C114.1 0 64 50.1 64 112c0 7.1 .7 14.1 1.9 20.8C27.6 145.4 0 181.5 0 224zm288 96c0-17.7-14.3-32-32-32s-32 14.3-32 32c0 1 .1 2.1 .1 3.1c-.7-.8-1.4-1.6-2.1-2.3c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3c.7 .7 1.5 1.4 2.3 2.1c-1-.1-2.1-.1-3.1-.1c-17.7 0-32 14.3-32 32s14.3 32 32 32c1 0 2.1-.1 3.1-.1c-.8 .7-1.6 1.3-2.3 2.1c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0c.7-.7 1.4-1.5 2.1-2.3c-.1 1-.1 2.1-.1 3.1c0 17.7 14.3 32 32 32s32-14.3 32-32c0-1-.1-2.1-.1-3.1c.7 .8 1.3 1.6 2.1 2.3c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3c-.7-.7-1.5-1.4-2.3-2.1c1 .1 2.1 .1 3.1 .1c17.7 0 32-14.3 32-32s-14.3-32-32-32c-1 0-2.1 .1-3.1 .1c.8-.7 1.6-1.3 2.3-2.1c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0c-.7 .7-1.4 1.5-2.1 2.3c.1-1 .1-2.1 .1-3.1zM48 448a48 48 0 1 0 0-96 48 48 0 1 0 0 96zm416 0a48 48 0 1 0 0-96 48 48 0 1 0 0 96z" } }, "free": ["solid"] }, "cloud-moon": { "aliases": { "unicodes": { "secondary": ["10f6c3"] } }, "changes": ["5.4.0", "5.5.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["crescent", "evening", "lunar", "night", "partly cloudy", "sky"] }, "styles": ["solid"], "unicode": "f6c3", "label": "Cloud Moon", "voted": false, "svg": { "solid": { "last_modified": 1684767661, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M495.8 0c5.5 0 10.9 .2 16.3 .7c7 .6 12.8 5.7 14.3 12.5s-1.6 13.9-7.7 17.3c-44.4 25.2-74.4 73-74.4 127.8c0 81 65.5 146.6 146.2 146.6c8.6 0 17-.7 25.1-2.1c6.9-1.2 13.8 2.2 17 8.5s1.9 13.8-3.1 18.7c-34.5 33.6-81.7 54.4-133.6 54.4c-9.3 0-18.4-.7-27.4-1.9c-11.2-22.6-29.8-40.9-52.6-51.7c-2.7-58.5-50.3-105.3-109.2-106.7c-1.7-10.4-2.6-21-2.6-31.8C304 86.1 389.8 0 495.8 0zM447.9 431.9c0 44.2-35.8 80-80 80H96c-53 0-96-43-96-96c0-47.6 34.6-87 80-94.6l0-1.3c0-53 43-96 96-96c34.9 0 65.4 18.6 82.2 46.4c13-9.1 28.8-14.4 45.8-14.4c44.2 0 80 35.8 80 80c0 5.9-.6 11.7-1.9 17.2c37.4 6.7 65.8 39.4 65.8 78.7z" } }, "free": ["solid"] }, "cloud-moon-rain": { "aliases": { "unicodes": { "secondary": ["10f73c"] } }, "changes": ["5.5.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "crescent", "evening", "lunar", "night", "partly cloudy", "precipitation", "rain", "sky", "storm" ] }, "styles": ["solid"], "unicode": "f73c", "label": "Cloud Moon Rain", "voted": false, "svg": { "solid": { "last_modified": 1684767661, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M481.2 0C417 0 363.5 46.5 353.7 107.6c35.4 17.6 60.2 53.3 62.1 95.1c23.2 11 42 29.7 53.1 52.7c4 .4 8.1 .6 12.3 .6c34.9 0 66.7-13.8 89.9-36.1c5.1-4.9 6.4-12.5 3.2-18.7s-10.1-9.7-17-8.6c-4.9 .8-10 1.3-15.2 1.3c-49 0-88.4-39.3-88.4-87.4c0-32.6 18-61.1 44.9-76.1c6.1-3.4 9.3-10.5 7.8-17.4s-7.3-12-14.3-12.6c-3.6-.3-7.3-.5-10.9-.5zM367.9 383.9c44.2 0 80-35.8 80-80c0-39.3-28.4-72.1-65.8-78.7c1.2-5.6 1.9-11.3 1.9-17.2c0-44.2-35.8-80-80-80c-17 0-32.8 5.3-45.8 14.4C241.3 114.6 210.8 96 176 96c-53 0-96 43-96 96l0 1.3c-45.4 7.6-80 47.1-80 94.6c0 53 43 96 96 96H367.9zM85.4 420.1c-11-7.4-25.9-4.4-33.3 6.7l-32 48c-7.4 11-4.4 25.9 6.7 33.3s25.9 4.4 33.3-6.7l32-48c7.4-11 4.4-25.9-6.7-33.3zm96 0c-11-7.4-25.9-4.4-33.3 6.7l-32 48c-7.4 11-4.4 25.9 6.7 33.3s25.9 4.4 33.3-6.7l32-48c7.4-11 4.4-25.9-6.7-33.3zm96 0c-11-7.4-25.9-4.4-33.3 6.7l-32 48c-7.4 11-4.4 25.9 6.7 33.3s25.9 4.4 33.3-6.7l32-48c7.4-11 4.4-25.9-6.7-33.3zm96 0c-11-7.4-25.9-4.4-33.3 6.7l-32 48c-7.4 11-4.4 25.9 6.7 33.3s25.9 4.4 33.3-6.7l32-48c7.4-11 4.4-25.9-6.7-33.3z" } }, "free": ["solid"] }, "cloud-rain": { "aliases": { "unicodes": { "composite": ["1f327", "26c6"], "secondary": ["10f73d"] } }, "changes": ["5.5.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "Rain", "cloud", "cloud with rain", "precipitation", "rain", "sky", "storm" ] }, "styles": ["solid"], "unicode": "f73d", "label": "Cloud Rain", "voted": false, "svg": { "solid": { "last_modified": 1684767661, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M96 320c-53 0-96-43-96-96c0-42.5 27.6-78.6 65.9-91.2C64.7 126.1 64 119.1 64 112C64 50.1 114.1 0 176 0c43.1 0 80.5 24.3 99.2 60c14.7-17.1 36.5-28 60.8-28c44.2 0 80 35.8 80 80c0 5.5-.6 10.8-1.6 16c.5 0 1.1 0 1.6 0c53 0 96 43 96 96s-43 96-96 96H96zm-6.8 52c1.3-2.5 3.9-4 6.8-4s5.4 1.5 6.8 4l35.1 64.6c4.1 7.5 6.2 15.8 6.2 24.3v3c0 26.5-21.5 48-48 48s-48-21.5-48-48v-3c0-8.5 2.1-16.9 6.2-24.3L89.2 372zm160 0c1.3-2.5 3.9-4 6.8-4s5.4 1.5 6.8 4l35.1 64.6c4.1 7.5 6.2 15.8 6.2 24.3v3c0 26.5-21.5 48-48 48s-48-21.5-48-48v-3c0-8.5 2.1-16.9 6.2-24.3L249.2 372zm124.9 64.6L409.2 372c1.3-2.5 3.9-4 6.8-4s5.4 1.5 6.8 4l35.1 64.6c4.1 7.5 6.2 15.8 6.2 24.3v3c0 26.5-21.5 48-48 48s-48-21.5-48-48v-3c0-8.5 2.1-16.9 6.2-24.3z" } }, "free": ["solid"] }, "cloud-showers-heavy": { "aliases": { "unicodes": { "secondary": ["10f740"] } }, "changes": ["5.5.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["precipitation", "rain", "sky", "storm"] }, "styles": ["solid"], "unicode": "f740", "label": "Cloud Showers Heavy", "voted": false, "svg": { "solid": { "last_modified": 1684767662, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M96 320c-53 0-96-43-96-96c0-42.5 27.6-78.6 65.9-91.2C64.7 126.1 64 119.1 64 112C64 50.1 114.1 0 176 0c43.1 0 80.5 24.3 99.2 60c14.7-17.1 36.5-28 60.8-28c44.2 0 80 35.8 80 80c0 5.5-.6 10.8-1.6 16c.5 0 1.1 0 1.6 0c53 0 96 43 96 96s-43 96-96 96H96zM81.5 353.9c12.2 5.2 17.8 19.3 12.6 31.5l-48 112c-5.2 12.2-19.3 17.8-31.5 12.6S-3.3 490.7 1.9 478.5l48-112c5.2-12.2 19.3-17.8 31.5-12.6zm120 0c12.2 5.2 17.8 19.3 12.6 31.5l-48 112c-5.2 12.2-19.3 17.8-31.5 12.6s-17.8-19.3-12.6-31.5l48-112c5.2-12.2 19.3-17.8 31.5-12.6zm244.6 31.5l-48 112c-5.2 12.2-19.3 17.8-31.5 12.6s-17.8-19.3-12.6-31.5l48-112c5.2-12.2 19.3-17.8 31.5-12.6s17.8 19.3 12.6 31.5zM313.5 353.9c12.2 5.2 17.8 19.3 12.6 31.5l-48 112c-5.2 12.2-19.3 17.8-31.5 12.6s-17.8-19.3-12.6-31.5l48-112c5.2-12.2 19.3-17.8 31.5-12.6z" } }, "free": ["solid"] }, "cloud-showers-water": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["cloud", "deluge", "flood", "rain", "storm", "surge"] }, "styles": ["solid"], "unicode": "e4e4", "label": "Cloud Showers Water", "voted": false, "svg": { "solid": { "last_modified": 1684767662, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M224 0c38.6 0 71.9 22.8 87.2 55.7C325.7 41.1 345.8 32 368 32c38.7 0 71 27.5 78.4 64H448c35.3 0 64 28.7 64 64s-28.7 64-64 64H128c-35.3 0-64-28.7-64-64s28.7-64 64-64c0-53 43-96 96-96zM140.6 292.3l-48 80c-6.8 11.4-21.6 15-32.9 8.2s-15.1-21.6-8.2-32.9l48-80c6.8-11.4 21.6-15.1 32.9-8.2s15.1 21.6 8.2 32.9zm327.8-32.9c11.4 6.8 15 21.6 8.2 32.9l-48 80c-6.8 11.4-21.6 15-32.9 8.2s-15-21.6-8.2-32.9l48-80c6.8-11.4 21.6-15.1 32.9-8.2zM252.6 292.3l-48 80c-6.8 11.4-21.6 15-32.9 8.2s-15.1-21.6-8.2-32.9l48-80c6.8-11.4 21.6-15.1 32.9-8.2s15.1 21.6 8.2 32.9zm103.8-32.9c11.4 6.8 15 21.6 8.2 32.9l-48 80c-6.8 11.4-21.6 15-32.9 8.2s-15.1-21.6-8.2-32.9l48-80c6.8-11.4 21.6-15.1 32.9-8.2zM306.5 421.9C329 437.4 356.5 448 384 448c26.9 0 55.4-10.8 77.4-26.1l0 0c11.9-8.5 28.1-7.8 39.2 1.7c14.4 11.9 32.5 21 50.6 25.2c17.2 4 27.9 21.2 23.9 38.4s-21.2 27.9-38.4 23.9c-24.5-5.7-44.9-16.5-58.2-25C449.5 501.7 417 512 384 512c-31.9 0-60.6-9.9-80.4-18.9c-5.8-2.7-11.1-5.3-15.6-7.7c-4.5 2.4-9.7 5.1-15.6 7.7c-19.8 9-48.5 18.9-80.4 18.9c-33 0-65.5-10.3-94.5-25.8c-13.4 8.4-33.7 19.3-58.2 25c-17.2 4-34.4-6.7-38.4-23.9s6.7-34.4 23.9-38.4c18.1-4.2 36.2-13.3 50.6-25.2c11.1-9.4 27.3-10.1 39.2-1.7l0 0C136.7 437.2 165.1 448 192 448c27.5 0 55-10.6 77.5-26.1c11.1-7.9 25.9-7.9 37 0z" } }, "free": ["solid"] }, "cloud-sun": { "aliases": { "unicodes": { "composite": ["26c5"], "secondary": ["10f6c4"] } }, "changes": ["5.4.0", "5.5.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "clear", "cloud", "day", "daytime", "fall", "outdoors", "overcast", "partly cloudy", "sun", "sun behind cloud" ] }, "styles": ["solid"], "unicode": "f6c4", "label": "Cloud Sun", "voted": false, "svg": { "solid": { "last_modified": 1684767661, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M294.2 1.2c5.1 2.1 8.7 6.7 9.6 12.1l14.1 84.7 84.7 14.1c5.4 .9 10 4.5 12.1 9.6s1.5 10.9-1.6 15.4l-38.5 55c-2.2-.1-4.4-.2-6.7-.2c-23.3 0-45.1 6.2-64 17.1l0-1.1c0-53-43-96-96-96s-96 43-96 96s43 96 96 96c8.1 0 15.9-1 23.4-2.9c-36.6 18.1-63.3 53.1-69.8 94.9l-24.4 17c-4.5 3.2-10.3 3.8-15.4 1.6s-8.7-6.7-9.6-12.1L98.1 317.9 13.4 303.8c-5.4-.9-10-4.5-12.1-9.6s-1.5-10.9 1.6-15.4L52.5 208 2.9 137.2c-3.2-4.5-3.8-10.3-1.6-15.4s6.7-8.7 12.1-9.6L98.1 98.1l14.1-84.7c.9-5.4 4.5-10 9.6-12.1s10.9-1.5 15.4 1.6L208 52.5 278.8 2.9c4.5-3.2 10.3-3.8 15.4-1.6zM144 208a64 64 0 1 1 128 0 64 64 0 1 1 -128 0zM639.9 431.9c0 44.2-35.8 80-80 80H288c-53 0-96-43-96-96c0-47.6 34.6-87 80-94.6l0-1.3c0-53 43-96 96-96c34.9 0 65.4 18.6 82.2 46.4c13-9.1 28.8-14.4 45.8-14.4c44.2 0 80 35.8 80 80c0 5.9-.6 11.7-1.9 17.2c37.4 6.7 65.8 39.4 65.8 78.7z" } }, "free": ["solid"] }, "cloud-sun-rain": { "aliases": { "unicodes": { "composite": ["1f326"], "secondary": ["10f743"] } }, "changes": ["5.5.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "cloud", "day", "overcast", "precipitation", "rain", "storm", "summer", "sun", "sun behind rain cloud", "sunshower" ] }, "styles": ["solid"], "unicode": "f743", "label": "Cloud Sun Rain", "voted": false, "svg": { "solid": { "last_modified": 1684767662, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M294.2 1.2c5.1 2.1 8.7 6.7 9.6 12.1l10.4 62.4c-23.3 10.8-42.9 28.4-56 50.3c-14.6-9-31.8-14.1-50.2-14.1c-53 0-96 43-96 96c0 35.5 19.3 66.6 48 83.2c.8 31.8 13.2 60.7 33.1 82.7l-56 39.2c-4.5 3.1-10.3 3.8-15.4 1.6s-8.7-6.7-9.6-12.1L98.1 317.9 13.4 303.8c-5.4-.9-10-4.5-12.1-9.6s-1.5-10.9 1.6-15.4L52.5 208 2.9 137.2c-3.2-4.5-3.8-10.3-1.6-15.4s6.7-8.7 12.1-9.6L98.1 98.1l14.1-84.7c.9-5.4 4.5-10 9.6-12.1s10.9-1.5 15.4 1.6L208 52.5 278.8 2.9c4.5-3.2 10.3-3.8 15.4-1.6zM208 144c13.8 0 26.7 4.4 37.1 11.9c-1.2 4.1-2.2 8.3-3 12.6c-37.9 14.6-67.2 46.6-77.8 86.4C151.8 243.1 144 226.5 144 208c0-35.3 28.7-64 64-64zm69.4 276c11 7.4 14 22.3 6.7 33.3l-32 48c-7.4 11-22.3 14-33.3 6.7s-14-22.3-6.7-33.3l32-48c7.4-11 22.3-14 33.3-6.7zm96 0c11 7.4 14 22.3 6.7 33.3l-32 48c-7.4 11-22.3 14-33.3 6.7s-14-22.3-6.7-33.3l32-48c7.4-11 22.3-14 33.3-6.7zm96 0c11 7.4 14 22.3 6.7 33.3l-32 48c-7.4 11-22.3 14-33.3 6.7s-14-22.3-6.7-33.3l32-48c7.4-11 22.3-14 33.3-6.7zm96 0c11 7.4 14 22.3 6.7 33.3l-32 48c-7.4 11-22.3 14-33.3 6.7s-14-22.3-6.7-33.3l32-48c7.4-11 22.3-14 33.3-6.7zm74.5-116.1c0 44.2-35.8 80-80 80H288c-53 0-96-43-96-96c0-47.6 34.6-87 80-94.6l0-1.3c0-53 43-96 96-96c34.9 0 65.4 18.6 82.2 46.4c13-9.1 28.8-14.4 45.8-14.4c44.2 0 80 35.8 80 80c0 5.9-.6 11.7-1.9 17.2c37.4 6.7 65.8 39.4 65.8 78.7z" } }, "free": ["solid"] }, "cloudflare": { "changes": ["5.15.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e07d", "label": "Cloudflare", "voted": false, "svg": { "brands": { "last_modified": 1660014482, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M407.906,319.913l-230.8-2.928a4.58,4.58,0,0,1-3.632-1.926,4.648,4.648,0,0,1-.494-4.147,6.143,6.143,0,0,1,5.361-4.076L411.281,303.9c27.631-1.26,57.546-23.574,68.022-50.784l13.286-34.542a7.944,7.944,0,0,0,.524-2.936,7.735,7.735,0,0,0-.164-1.631A151.91,151.91,0,0,0,201.257,198.4,68.12,68.12,0,0,0,94.2,269.59C41.924,271.106,0,313.728,0,366.12a96.054,96.054,0,0,0,1.029,13.958,4.508,4.508,0,0,0,4.445,3.871l426.1.051c.043,0,.08-.019.122-.02a5.606,5.606,0,0,0,5.271-4l3.273-11.265c3.9-13.4,2.448-25.8-4.1-34.9C430.124,325.423,420.09,320.487,407.906,319.913ZM513.856,221.1c-2.141,0-4.271.062-6.391.164a3.771,3.771,0,0,0-3.324,2.653l-9.077,31.193c-3.9,13.4-2.449,25.786,4.1,34.89,6.02,8.4,16.054,13.323,28.238,13.9l49.2,2.939a4.491,4.491,0,0,1,3.51,1.894,4.64,4.64,0,0,1,.514,4.169,6.153,6.153,0,0,1-5.351,4.075l-51.125,2.939c-27.754,1.27-57.669,23.574-68.145,50.784l-3.695,9.606a2.716,2.716,0,0,0,2.427,3.68c.046,0,.088.017.136.017h175.91a4.69,4.69,0,0,0,4.539-3.37,124.807,124.807,0,0,0,4.682-34C640,277.3,583.524,221.1,513.856,221.1Z" } }, "free": ["brands"] }, "cloudscale": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f383", "label": "cloudscale.ch", "voted": false, "svg": { "brands": { "last_modified": 1660014469, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M318.1 154l-9.4 7.6c-22.5-19.3-51.5-33.6-83.3-33.6C153.8 128 96 188.8 96 260.3c0 6.6.4 13.1 1.4 19.4-2-56 41.8-97.4 92.6-97.4 24.2 0 46.2 9.4 62.6 24.7l-25.2 20.4c-8.3-.9-16.8 1.8-23.1 8.1-11.1 11-11.1 28.9 0 40 11.1 11 28.9 11 40 0 6.3-6.3 9-14.9 8.1-23.1l75.2-88.8c6.3-6.5-3.3-15.9-9.5-9.6zm-83.8 111.5c-5.6 5.5-14.6 5.5-20.2 0-5.6-5.6-5.6-14.6 0-20.2s14.6-5.6 20.2 0 5.6 14.7 0 20.2zM224 32C100.5 32 0 132.5 0 256s100.5 224 224 224 224-100.5 224-224S347.5 32 224 32zm0 384c-88.2 0-160-71.8-160-160S135.8 96 224 96s160 71.8 160 160-71.8 160-160 160z" } }, "free": ["brands"] }, "cloudsmith": { "changes": ["5.0.0", "6.4.1"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f384", "label": "Cloudsmith", "voted": false, "svg": { "brands": { "last_modified": 1684948301, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M512 227.6v56.9L284.4 512H227.6L0 284.4V227.6L227.6 0h56.9L512 227.6zm-256 162a133.6 133.6 0 1 0 0-267.1 133.6 133.6 0 1 0 0 267.1z" } }, "free": ["brands"] }, "cloudversify": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f385", "label": "cloudversify", "voted": false, "svg": { "brands": { "last_modified": 1660014469, "raw": "", "viewBox": [0, 0, 616, 512], "width": 616, "height": 512, "path": "M148.6 304c8.2 68.5 67.4 115.5 146 111.3 51.2 43.3 136.8 45.8 186.4-5.6 69.2 1.1 118.5-44.6 131.5-99.5 14.8-62.5-18.2-132.5-92.1-155.1-33-88.1-131.4-101.5-186.5-85-57.3 17.3-84.3 53.2-99.3 109.7-7.8 2.7-26.5 8.9-45 24.1 11.7 0 15.2 8.9 15.2 19.5v20.4c0 10.7-8.7 19.5-19.5 19.5h-20.2c-10.7 0-19.5-6-19.5-16.7V240H98.8C95 240 88 244.3 88 251.9v40.4c0 6.4 5.3 11.8 11.7 11.8h48.9zm227.4 8c-10.7 46.3 21.7 72.4 55.3 86.8C324.1 432.6 259.7 348 296 288c-33.2 21.6-33.7 71.2-29.2 92.9-17.9-12.4-53.8-32.4-57.4-79.8-3-39.9 21.5-75.7 57-93.9C297 191.4 369.9 198.7 400 248c-14.1-48-53.8-70.1-101.8-74.8 30.9-30.7 64.4-50.3 114.2-43.7 69.8 9.3 133.2 82.8 67.7 150.5 35-16.3 48.7-54.4 47.5-76.9l10.5 19.6c11.8 22 15.2 47.6 9.4 72-9.2 39-40.6 68.8-79.7 76.5-32.1 6.3-83.1-5.1-91.8-59.2zM128 208H88.2c-8.9 0-16.2-7.3-16.2-16.2v-39.6c0-8.9 7.3-16.2 16.2-16.2H128c8.9 0 16.2 7.3 16.2 16.2v39.6c0 8.9-7.3 16.2-16.2 16.2zM10.1 168C4.5 168 0 163.5 0 157.9v-27.8c0-5.6 4.5-10.1 10.1-10.1h27.7c5.5 0 10.1 4.5 10.1 10.1v27.8c0 5.6-4.5 10.1-10.1 10.1H10.1zM168 142.7v-21.4c0-5.1 4.2-9.3 9.3-9.3h21.4c5.1 0 9.3 4.2 9.3 9.3v21.4c0 5.1-4.2 9.3-9.3 9.3h-21.4c-5.1 0-9.3-4.2-9.3-9.3zM56 235.5v25c0 6.3-5.1 11.5-11.4 11.5H19.4C13.1 272 8 266.8 8 260.5v-25c0-6.3 5.1-11.5 11.4-11.5h25.1c6.4 0 11.5 5.2 11.5 11.5z" } }, "free": ["brands"] }, "clover": { "changes": ["6.0.0-beta1", "6.1.2", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "4", "charm", "clover", "four", "four leaf clover", "four-leaf clover", "leaf", "leprechaun", "luck", "lucky" ] }, "styles": ["solid"], "unicode": "e139", "label": "Clover", "voted": false, "svg": { "solid": { "last_modified": 1684768131, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M173.3 32C139.4 32 112 59.4 112 93.3v4.9c0 12 3.3 23.7 9.4 34l18.8 31.3c1.1 1.8 1.2 3.1 1 4.2c-.2 1.2-.8 2.5-2 3.6s-2.4 1.8-3.6 2c-1 .2-2.4 .1-4.2-1l-31.3-18.8c-10.3-6.2-22-9.4-34-9.4H61.3C27.4 144 0 171.4 0 205.3c0 16.2 6.5 31.8 17.9 43.3l1.2 1.2c3.4 3.4 3.4 9 0 12.4l-1.2 1.2C6.5 274.9 0 290.5 0 306.7C0 340.6 27.4 368 61.3 368h4.9c12 0 23.7-3.3 34-9.4l31.3-18.8c1.8-1.1 3.1-1.2 4.2-1c1.2 .2 2.5 .8 3.6 2s1.8 2.4 2 3.6c.2 1 .1 2.4-1 4.2l-18.8 31.3c-6.2 10.3-9.4 22-9.4 34v4.9c0 33.8 27.4 61.3 61.3 61.3c16.2 0 31.8-6.5 43.3-17.9l1.2-1.2c3.4-3.4 9-3.4 12.4 0l1.2 1.2c11.5 11.5 27.1 17.9 43.3 17.9c33.8 0 61.3-27.4 61.3-61.3v-4.9c0-12-3.3-23.7-9.4-34l-18.8-31.3c-1.1-1.8-1.2-3.1-1-4.2c.2-1.2 .8-2.5 2-3.6s2.4-1.8 3.6-2c1-.2 2.4-.1 4.2 1l31.3 18.8c10.3 6.2 22 9.4 34 9.4h4.9c33.8 0 61.3-27.4 61.3-61.3c0-16.2-6.5-31.8-17.9-43.3l-1.2-1.2c-3.4-3.4-3.4-9 0-12.4l1.2-1.2c11.5-11.5 17.9-27.1 17.9-43.3c0-33.8-27.4-61.3-61.3-61.3h-4.9c-12 0-23.7 3.3-34 9.4l-31.3 18.8c-1.8 1.1-3.1 1.2-4.2 1c-1.2-.2-2.5-.8-3.6-2s-1.8-2.4-2-3.6c-.2-1-.1-2.4 1-4.2l18.8-31.3c6.2-10.3 9.4-22 9.4-34V93.3C336 59.4 308.6 32 274.7 32c-16.2 0-31.8 6.5-43.3 17.9l-1.2 1.2c-3.4 3.4-9 3.4-12.4 0l-1.2-1.2C205.1 38.5 189.5 32 173.3 32z" } }, "free": ["solid"] }, "cmplid": { "changes": ["6.0.0-beta1"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e360", "label": "Cmplid", "voted": false, "svg": { "brands": { "last_modified": 1660014466, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M226.119,388.165a3.816,3.816,0,0,0-2.294-3.5,3.946,3.946,0,0,0-1.629-.385L72.6,384.3a19.243,19.243,0,0,1-17.924-26.025L81.585,255.692a35.72,35.72,0,0,1,32.373-26H262.525a7.07,7.07,0,0,0,6.392-5.194l10.769-41.131a3.849,3.849,0,0,0-2.237-4.937,3.755,3.755,0,0,0-1.377-.261c-.063,0-.126,0-.189.005H127.38a106.8,106.8,0,0,0-96.99,77.1L3.483,358.824A57.469,57.469,0,0,0,57.314,436q1.43,0,2.86-.072H208.742a7.131,7.131,0,0,0,6.391-5.193L225.839,389.6A3.82,3.82,0,0,0,226.119,388.165ZM306.658,81.2a3.861,3.861,0,0,0,.251-1.367A3.813,3.813,0,0,0,303.079,76c-.064,0-.128,0-.192,0h-41A7.034,7.034,0,0,0,255.5,81.2l-21.347,80.915h51.131ZM180.364,368.249H231.5L263.452,245.69H212.321ZM511.853,79.723a3.809,3.809,0,0,0-3.8-3.661c-.058,0-.137,0-.23.007h-41a7.1,7.1,0,0,0-6.584,5.129L368.91,430.634a3.54,3.54,0,0,0-.262,1.335,3.873,3.873,0,0,0,3.864,3.863c.056,0,.112,0,.169,0h41a7.068,7.068,0,0,0,6.392-5.193L511.533,81.2A3.624,3.624,0,0,0,511.853,79.723ZM324.649,384.47h-41a7.2,7.2,0,0,0-6.392,5.194L266.52,430.8a3.662,3.662,0,0,0-.268,1.374A3.783,3.783,0,0,0,270.023,436c.06,0,.166,0,.3-.012h40.905a7.036,7.036,0,0,0,6.391-5.193l10.769-41.131a3.75,3.75,0,0,0-3.445-5.208c-.108,0-.217,0-.326.014Zm311.324-308.4h-41a7.066,7.066,0,0,0-6.392,5.129l-91.46,349.436a4.073,4.073,0,0,0-.229,1.347,3.872,3.872,0,0,0,3.863,3.851c.056,0,.112,0,.169,0h40.968a7.1,7.1,0,0,0,6.392-5.193L639.68,81.2a3.624,3.624,0,0,0,.32-1.475,3.841,3.841,0,0,0-3.821-3.564c-.068,0-.137,0-.206.006ZM371.562,225.236l10.8-41.1a4.369,4.369,0,0,0,.227-1.388,3.869,3.869,0,0,0-3.861-3.842c-.057,0-.113,0-.169,0h-41.1a7.292,7.292,0,0,0-6.391,5.226l-10.834,41.1a4.417,4.417,0,0,0-.26,1.493c0,.069,0,.138,0,.206a3.776,3.776,0,0,0,3.757,3.507c.076,0,.18,0,.3-.012h41.129A7.034,7.034,0,0,0,371.562,225.236Z" } }, "free": ["brands"] }, "code": { "aliases": { "unicodes": { "secondary": ["10f121"] } }, "changes": [ "3.1.0", "5.0.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["brackets", "code", "development", "html"] }, "styles": ["solid"], "unicode": "f121", "label": "Code", "voted": false, "svg": { "solid": { "last_modified": 1684767552, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M392.8 1.2c-17-4.9-34.7 5-39.6 22l-128 448c-4.9 17 5 34.7 22 39.6s34.7-5 39.6-22l128-448c4.9-17-5-34.7-22-39.6zm80.6 120.1c-12.5 12.5-12.5 32.8 0 45.3L562.7 256l-89.4 89.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l112-112c12.5-12.5 12.5-32.8 0-45.3l-112-112c-12.5-12.5-32.8-12.5-45.3 0zm-306.7 0c-12.5-12.5-32.8-12.5-45.3 0l-112 112c-12.5 12.5-12.5 32.8 0 45.3l112 112c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L77.3 256l89.4-89.4c12.5-12.5 12.5-32.8 0-45.3z" } }, "free": ["solid"] }, "code-branch": { "aliases": { "unicodes": { "secondary": ["10f126"] } }, "changes": ["5.0.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["branch", "git", "github", "rebase", "svn", "vcs", "version"] }, "styles": ["solid"], "unicode": "f126", "label": "Code Branch", "voted": false, "svg": { "solid": { "last_modified": 1684767552, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M80 104a24 24 0 1 0 0-48 24 24 0 1 0 0 48zm80-24c0 32.8-19.7 61-48 73.3v87.8c18.8-10.9 40.7-17.1 64-17.1h96c35.3 0 64-28.7 64-64v-6.7C307.7 141 288 112.8 288 80c0-44.2 35.8-80 80-80s80 35.8 80 80c0 32.8-19.7 61-48 73.3V160c0 70.7-57.3 128-128 128H176c-35.3 0-64 28.7-64 64v6.7c28.3 12.3 48 40.5 48 73.3c0 44.2-35.8 80-80 80s-80-35.8-80-80c0-32.8 19.7-61 48-73.3V352 153.3C19.7 141 0 112.8 0 80C0 35.8 35.8 0 80 0s80 35.8 80 80zm232 0a24 24 0 1 0 -48 0 24 24 0 1 0 48 0zM80 456a24 24 0 1 0 0-48 24 24 0 1 0 0 48z" } }, "free": ["solid"] }, "code-commit": { "aliases": { "unicodes": { "secondary": ["10f386"] } }, "changes": [ "5.0.0", "5.1.1", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "commit", "git", "github", "hash", "rebase", "svn", "vcs", "version" ] }, "styles": ["solid"], "unicode": "f386", "label": "Code Commit", "voted": false, "svg": { "solid": { "last_modified": 1684767551, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M320 336a80 80 0 1 0 0-160 80 80 0 1 0 0 160zm156.8-48C462 361 397.4 416 320 416s-142-55-156.8-128H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H163.2C178 151 242.6 96 320 96s142 55 156.8 128H608c17.7 0 32 14.3 32 32s-14.3 32-32 32H476.8z" } }, "free": ["solid"] }, "code-compare": { "changes": [ "6.0.0-beta1", "6.0.0-beta2", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["compare", "git", "github", "svn", "version"] }, "styles": ["solid"], "unicode": "e13a", "label": "Code Compare", "voted": false, "svg": { "solid": { "last_modified": 1684767551, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M320 488c0 9.5-5.6 18.1-14.2 21.9s-18.8 2.3-25.8-4.1l-80-72c-5.1-4.6-7.9-11-7.9-17.8s2.9-13.3 7.9-17.8l80-72c7-6.3 17.2-7.9 25.8-4.1s14.2 12.4 14.2 21.9v40h16c35.3 0 64-28.7 64-64V153.3C371.7 141 352 112.8 352 80c0-44.2 35.8-80 80-80s80 35.8 80 80c0 32.8-19.7 61-48 73.3V320c0 70.7-57.3 128-128 128H320v40zM456 80a24 24 0 1 0 -48 0 24 24 0 1 0 48 0zM192 24c0-9.5 5.6-18.1 14.2-21.9s18.8-2.3 25.8 4.1l80 72c5.1 4.6 7.9 11 7.9 17.8s-2.9 13.3-7.9 17.8l-80 72c-7 6.3-17.2 7.9-25.8 4.1s-14.2-12.4-14.2-21.9V128H176c-35.3 0-64 28.7-64 64V358.7c28.3 12.3 48 40.5 48 73.3c0 44.2-35.8 80-80 80s-80-35.8-80-80c0-32.8 19.7-61 48-73.3V192c0-70.7 57.3-128 128-128h16V24zM56 432a24 24 0 1 0 48 0 24 24 0 1 0 -48 0z" } }, "free": ["solid"] }, "code-fork": { "changes": ["6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["fork", "git", "github", "svn", "version"] }, "styles": ["solid"], "unicode": "e13b", "label": "Code Fork", "voted": false, "svg": { "solid": { "last_modified": 1684767552, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M80 104a24 24 0 1 0 0-48 24 24 0 1 0 0 48zm80-24c0 32.8-19.7 61-48 73.3V192c0 17.7 14.3 32 32 32H304c17.7 0 32-14.3 32-32V153.3C307.7 141 288 112.8 288 80c0-44.2 35.8-80 80-80s80 35.8 80 80c0 32.8-19.7 61-48 73.3V192c0 53-43 96-96 96H256v70.7c28.3 12.3 48 40.5 48 73.3c0 44.2-35.8 80-80 80s-80-35.8-80-80c0-32.8 19.7-61 48-73.3V288H144c-53 0-96-43-96-96V153.3C19.7 141 0 112.8 0 80C0 35.8 35.8 0 80 0s80 35.8 80 80zm208 24a24 24 0 1 0 0-48 24 24 0 1 0 0 48zM248 432a24 24 0 1 0 -48 0 24 24 0 1 0 48 0z" } }, "free": ["solid"] }, "code-merge": { "aliases": { "unicodes": { "secondary": ["10f387"] } }, "changes": ["5.0.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "git", "github", "merge", "pr", "rebase", "svn", "vcs", "version" ] }, "styles": ["solid"], "unicode": "f387", "label": "Code Merge", "voted": false, "svg": { "solid": { "last_modified": 1684767551, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M80 56a24 24 0 1 1 0 48 24 24 0 1 1 0-48zm32.4 97.2c28-12.4 47.6-40.5 47.6-73.2c0-44.2-35.8-80-80-80S0 35.8 0 80c0 32.8 19.7 61 48 73.3V358.7C19.7 371 0 399.2 0 432c0 44.2 35.8 80 80 80s80-35.8 80-80c0-32.8-19.7-61-48-73.3V272c26.7 20.1 60 32 96 32h86.7c12.3 28.3 40.5 48 73.3 48c44.2 0 80-35.8 80-80s-35.8-80-80-80c-32.8 0-61 19.7-73.3 48H208c-49.9 0-91-38.1-95.6-86.8zM80 408a24 24 0 1 1 0 48 24 24 0 1 1 0-48zM344 272a24 24 0 1 1 48 0 24 24 0 1 1 -48 0z" } }, "free": ["solid"] }, "code-pull-request": { "changes": ["6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["git", "github", "pr", "svn", "version"] }, "styles": ["solid"], "unicode": "e13c", "label": "Code Pull Request", "voted": false, "svg": { "solid": { "last_modified": 1684767553, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M305.8 2.1C314.4 5.9 320 14.5 320 24V64h16c70.7 0 128 57.3 128 128V358.7c28.3 12.3 48 40.5 48 73.3c0 44.2-35.8 80-80 80s-80-35.8-80-80c0-32.8 19.7-61 48-73.3V192c0-35.3-28.7-64-64-64H320v40c0 9.5-5.6 18.1-14.2 21.9s-18.8 2.3-25.8-4.1l-80-72c-5.1-4.6-7.9-11-7.9-17.8s2.9-13.3 7.9-17.8l80-72c7-6.3 17.2-7.9 25.8-4.1zM104 80A24 24 0 1 0 56 80a24 24 0 1 0 48 0zm8 73.3V358.7c28.3 12.3 48 40.5 48 73.3c0 44.2-35.8 80-80 80s-80-35.8-80-80c0-32.8 19.7-61 48-73.3V153.3C19.7 141 0 112.8 0 80C0 35.8 35.8 0 80 0s80 35.8 80 80c0 32.8-19.7 61-48 73.3zM104 432a24 24 0 1 0 -48 0 24 24 0 1 0 48 0zm328 24a24 24 0 1 0 0-48 24 24 0 1 0 0 48z" } }, "free": ["solid"] }, "codepen": { "changes": ["4.1.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f1cb", "label": "Codepen", "voted": false, "svg": { "brands": { "last_modified": 1660014478, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M502.285 159.704l-234-156c-7.987-4.915-16.511-4.96-24.571 0l-234 156C3.714 163.703 0 170.847 0 177.989v155.999c0 7.143 3.714 14.286 9.715 18.286l234 156.022c7.987 4.915 16.511 4.96 24.571 0l234-156.022c6-3.999 9.715-11.143 9.715-18.286V177.989c-.001-7.142-3.715-14.286-9.716-18.285zM278 63.131l172.286 114.858-76.857 51.429L278 165.703V63.131zm-44 0v102.572l-95.429 63.715-76.857-51.429L234 63.131zM44 219.132l55.143 36.857L44 292.846v-73.714zm190 229.715L61.714 333.989l76.857-51.429L234 346.275v102.572zm22-140.858l-77.715-52 77.715-52 77.715 52-77.715 52zm22 140.858V346.275l95.429-63.715 76.857 51.429L278 448.847zm190-156.001l-55.143-36.857L468 219.132v73.714z" } }, "free": ["brands"] }, "codiepie": { "changes": ["4.5.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f284", "label": "Codie Pie", "voted": false, "svg": { "brands": { "last_modified": 1660014477, "raw": "", "viewBox": [0, 0, 472, 512], "width": 472, "height": 512, "path": "M422.5 202.9c30.7 0 33.5 53.1-.3 53.1h-10.8v44.3h-26.6v-97.4h37.7zM472 352.6C429.9 444.5 350.4 504 248 504 111 504 0 393 0 256S111 8 248 8c97.4 0 172.8 53.7 218.2 138.4l-186 108.8L472 352.6zm-38.5 12.5l-60.3-30.7c-27.1 44.3-70.4 71.4-122.4 71.4-82.5 0-149.2-66.7-149.2-148.9 0-82.5 66.7-149.2 149.2-149.2 48.4 0 88.9 23.5 116.9 63.4l59.5-34.6c-40.7-62.6-104.7-100-179.2-100-121.2 0-219.5 98.3-219.5 219.5S126.8 475.5 248 475.5c78.6 0 146.5-42.1 185.5-110.4z" } }, "free": ["brands"] }, "coins": { "aliases": { "unicodes": { "secondary": ["10f51e"] } }, "changes": [ "5.0.13", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["currency", "dime", "financial", "gold", "money", "penny"] }, "styles": ["solid"], "unicode": "f51e", "label": "Coins", "voted": true, "svg": { "solid": { "last_modified": 1684766475, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M512 80c0 18-14.3 34.6-38.4 48c-29.1 16.1-72.5 27.5-122.3 30.9c-3.7-1.8-7.4-3.5-11.3-5C300.6 137.4 248.2 128 192 128c-8.3 0-16.4 .2-24.5 .6l-1.1-.6C142.3 114.6 128 98 128 80c0-44.2 86-80 192-80S512 35.8 512 80zM160.7 161.1c10.2-.7 20.7-1.1 31.3-1.1c62.2 0 117.4 12.3 152.5 31.4C369.3 204.9 384 221.7 384 240c0 4-.7 7.9-2.1 11.7c-4.6 13.2-17 25.3-35 35.5c0 0 0 0 0 0c-.1 .1-.3 .1-.4 .2l0 0 0 0c-.3 .2-.6 .3-.9 .5c-35 19.4-90.8 32-153.6 32c-59.6 0-112.9-11.3-148.2-29.1c-1.9-.9-3.7-1.9-5.5-2.9C14.3 274.6 0 258 0 240c0-34.8 53.4-64.5 128-75.4c10.5-1.5 21.4-2.7 32.7-3.5zM416 240c0-21.9-10.6-39.9-24.1-53.4c28.3-4.4 54.2-11.4 76.2-20.5c16.3-6.8 31.5-15.2 43.9-25.5V176c0 19.3-16.5 37.1-43.8 50.9c-14.6 7.4-32.4 13.7-52.4 18.5c.1-1.8 .2-3.5 .2-5.3zm-32 96c0 18-14.3 34.6-38.4 48c-1.8 1-3.6 1.9-5.5 2.9C304.9 404.7 251.6 416 192 416c-62.8 0-118.6-12.6-153.6-32C14.3 370.6 0 354 0 336V300.6c12.5 10.3 27.6 18.7 43.9 25.5C83.4 342.6 135.8 352 192 352s108.6-9.4 148.1-25.9c7.8-3.2 15.3-6.9 22.4-10.9c6.1-3.4 11.8-7.2 17.2-11.2c1.5-1.1 2.9-2.3 4.3-3.4V304v5.7V336zm32 0V304 278.1c19-4.2 36.5-9.5 52.1-16c16.3-6.8 31.5-15.2 43.9-25.5V272c0 10.5-5 21-14.9 30.9c-16.3 16.3-45 29.7-81.3 38.4c.1-1.7 .2-3.5 .2-5.3zM192 448c56.2 0 108.6-9.4 148.1-25.9c16.3-6.8 31.5-15.2 43.9-25.5V432c0 44.2-86 80-192 80S0 476.2 0 432V396.6c12.5 10.3 27.6 18.7 43.9 25.5C83.4 438.6 135.8 448 192 448z" } }, "free": ["solid"] }, "colon-sign": { "changes": ["6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Colon Sign", "currency"] }, "styles": ["solid"], "unicode": "e140", "label": "Colon Sign", "voted": false, "svg": { "solid": { "last_modified": 1684766476, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M255 39.8c4.3-17.1-6.1-34.5-23.3-38.8S197.2 7.1 193 24.2L181.9 68.6C96.1 87.8 32 164.4 32 256c0 58.1 25.8 110.2 66.7 145.4L81 472.2c-4.3 17.1 6.1 34.5 23.3 38.8s34.5-6.1 38.8-23.3l13-52.1c9 3.4 18.4 6.2 28 8.2L177 472.2c-4.3 17.1 6.1 34.5 23.3 38.8s34.5-6.1 38.8-23.3l10.4-41.4c33.4-4.4 64.1-17.4 89.8-36.7c14.1-10.6 17-30.7 6.4-44.8s-30.7-17-44.8-6.4c-10.2 7.7-21.7 13.9-34 18.3L321 160c9.4-.3 18.5-4.7 24.6-12.8c10.6-14.1 7.8-34.2-6.4-44.8c-1.1-.8-2.2-1.6-3.3-2.4L351 39.8c4.3-17.1-6.1-34.5-23.3-38.8S293.2 7.1 289 24.2L277.2 71.5c-9.3-2.7-18.8-4.6-28.6-5.9L255 39.8zM163.2 143.3L117.3 326.8C103.9 306.5 96 282.2 96 256c0-48.7 27.2-91 67.2-112.7zm8.6 229.5l61.1-244.6c9.9 .7 19.5 2.5 28.7 5.3l-62 248.1c-9.7-1.9-19-4.8-27.8-8.8z" } }, "free": ["solid"] }, "comment": { "aliases": { "unicodes": { "composite": ["1f5e9", "f0e5"], "secondary": ["10f075"] } }, "changes": [ "1.0.0", "5.0.0", "5.0.9", "5.10.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Right Speech Bubble", "bubble", "chat", "commenting", "conversation", "feedback", "message", "note", "notification", "sms", "speech", "texting" ] }, "styles": ["solid", "regular"], "unicode": "f075", "label": "Comment", "voted": false, "svg": { "solid": { "last_modified": 1684767390, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M512 240c0 114.9-114.6 208-256 208c-37.1 0-72.3-6.4-104.1-17.9c-11.9 8.7-31.3 20.6-54.3 30.6C73.6 471.1 44.7 480 16 480c-6.5 0-12.3-3.9-14.8-9.9c-2.5-6-1.1-12.8 3.4-17.4l0 0 0 0 0 0 0 0 .3-.3c.3-.3 .7-.7 1.3-1.4c1.1-1.2 2.8-3.1 4.9-5.7c4.1-5 9.6-12.4 15.2-21.6c10-16.6 19.5-38.4 21.4-62.9C17.7 326.8 0 285.1 0 240C0 125.1 114.6 32 256 32s256 93.1 256 208z" }, "regular": { "last_modified": 1684767390, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M123.6 391.3c12.9-9.4 29.6-11.8 44.6-6.4c26.5 9.6 56.2 15.1 87.8 15.1c124.7 0 208-80.5 208-160s-83.3-160-208-160S48 160.5 48 240c0 32 12.4 62.8 35.7 89.2c8.6 9.7 12.8 22.5 11.8 35.5c-1.4 18.1-5.7 34.7-11.3 49.4c17-7.9 31.1-16.7 39.4-22.7zM21.2 431.9c1.8-2.7 3.5-5.4 5.1-8.1c10-16.6 19.5-38.4 21.4-62.9C17.7 326.8 0 285.1 0 240C0 125.1 114.6 32 256 32s256 93.1 256 208s-114.6 208-256 208c-37.1 0-72.3-6.4-104.1-17.9c-11.9 8.7-31.3 20.6-54.3 30.6c-15.1 6.6-32.3 12.6-50.1 16.1c-.8 .2-1.6 .3-2.4 .5c-4.4 .8-8.7 1.5-13.2 1.9c-.2 0-.5 .1-.7 .1c-5.1 .5-10.2 .8-15.3 .8c-6.5 0-12.3-3.9-14.8-9.9c-2.5-6-1.1-12.8 3.4-17.4c4.1-4.2 7.8-8.7 11.3-13.5c1.7-2.3 3.3-4.6 4.8-6.9c.1-.2 .2-.3 .3-.5z" } }, "free": ["regular", "solid"] }, "comment-dollar": { "aliases": { "unicodes": { "secondary": ["10f651"] } }, "changes": ["5.3.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "bubble", "chat", "commenting", "conversation", "feedback", "message", "money", "note", "notification", "pay", "sms", "speech", "spend", "texting", "transfer" ] }, "styles": ["solid"], "unicode": "f651", "label": "Comment Dollar", "voted": false, "svg": { "solid": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 448c141.4 0 256-93.1 256-208S397.4 32 256 32S0 125.1 0 240c0 45.1 17.7 86.8 47.7 120.9c-1.9 24.5-11.4 46.3-21.4 62.9c-5.5 9.2-11.1 16.6-15.2 21.6c-2.1 2.5-3.7 4.4-4.9 5.7c-.6 .6-1 1.1-1.3 1.4l-.3 .3 0 0 0 0 0 0 0 0c-4.6 4.6-5.9 11.4-3.4 17.4c2.5 6 8.3 9.9 14.8 9.9c28.7 0 57.6-8.9 81.6-19.3c22.9-10 42.4-21.9 54.3-30.6c31.8 11.5 67 17.9 104.1 17.9zm20-312v13.9c7.5 1.2 14.6 2.9 21.1 4.7c10.7 2.8 17 13.8 14.2 24.5s-13.8 17-24.5 14.2c-11-2.9-21.6-5-31.2-5.2c-7.9-.1-16 1.8-21.5 5c-4.8 2.8-6.2 5.6-6.2 9.3c0 1.8 .1 3.5 5.3 6.7c6.3 3.8 15.5 6.7 28.3 10.5l.7 .2c11.2 3.4 25.6 7.7 37.1 15c12.9 8.1 24.3 21.3 24.6 41.6c.3 20.9-10.5 36.1-24.8 45c-7.2 4.5-15.2 7.3-23.2 9V344c0 11-9 20-20 20s-20-9-20-20V329.4c-10.3-2.2-20-5.5-28.2-8.4l0 0 0 0c-2.1-.7-4.1-1.4-6.1-2.1c-10.5-3.5-16.1-14.8-12.6-25.3s14.8-16.1 25.3-12.6c2.5 .8 4.9 1.7 7.2 2.4c13.6 4.6 24 8.1 35.1 8.5c8.6 .3 16.5-1.6 21.4-4.7c4.1-2.5 6-5.5 5.9-10.5c0-2.9-.8-5-5.9-8.2c-6.3-4-15.4-6.9-28-10.7l-1.7-.5c-10.9-3.3-24.6-7.4-35.6-14c-12.7-7.7-24.6-20.5-24.7-40.7c-.1-21.1 11.8-35.7 25.8-43.9c6.9-4.1 14.5-6.8 22.2-8.5V136c0-11 9-20 20-20s20 9 20 20z" } }, "free": ["solid"] }, "comment-dots": { "aliases": { "names": ["commenting"], "unicodes": { "composite": ["1f4ac", "f27b"], "secondary": ["10f4ad"] } }, "changes": ["5.0.9", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "balloon", "bubble", "chat", "comic", "commenting", "conversation", "dialog", "feedback", "message", "more", "note", "notification", "reply", "sms", "speech", "speech balloon", "texting" ] }, "styles": ["solid", "regular"], "unicode": "f4ad", "label": "Comment Dots", "voted": false, "svg": { "solid": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 448c141.4 0 256-93.1 256-208S397.4 32 256 32S0 125.1 0 240c0 45.1 17.7 86.8 47.7 120.9c-1.9 24.5-11.4 46.3-21.4 62.9c-5.5 9.2-11.1 16.6-15.2 21.6c-2.1 2.5-3.7 4.4-4.9 5.7c-.6 .6-1 1.1-1.3 1.4l-.3 .3 0 0 0 0 0 0 0 0c-4.6 4.6-5.9 11.4-3.4 17.4c2.5 6 8.3 9.9 14.8 9.9c28.7 0 57.6-8.9 81.6-19.3c22.9-10 42.4-21.9 54.3-30.6c31.8 11.5 67 17.9 104.1 17.9zM128 208a32 32 0 1 1 0 64 32 32 0 1 1 0-64zm128 0a32 32 0 1 1 0 64 32 32 0 1 1 0-64zm96 32a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z" }, "regular": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M168.2 384.9c-15-5.4-31.7-3.1-44.6 6.4c-8.2 6-22.3 14.8-39.4 22.7c5.6-14.7 9.9-31.3 11.3-49.4c1-12.9-3.3-25.7-11.8-35.5C60.4 302.8 48 272 48 240c0-79.5 83.3-160 208-160s208 80.5 208 160s-83.3 160-208 160c-31.6 0-61.3-5.5-87.8-15.1zM26.3 423.8c-1.6 2.7-3.3 5.4-5.1 8.1l-.3 .5c-1.6 2.3-3.2 4.6-4.8 6.9c-3.5 4.7-7.3 9.3-11.3 13.5c-4.6 4.6-5.9 11.4-3.4 17.4c2.5 6 8.3 9.9 14.8 9.9c5.1 0 10.2-.3 15.3-.8l.7-.1c4.4-.5 8.8-1.1 13.2-1.9c.8-.1 1.6-.3 2.4-.5c17.8-3.5 34.9-9.5 50.1-16.1c22.9-10 42.4-21.9 54.3-30.6c31.8 11.5 67 17.9 104.1 17.9c141.4 0 256-93.1 256-208S397.4 32 256 32S0 125.1 0 240c0 45.1 17.7 86.8 47.7 120.9c-1.9 24.5-11.4 46.3-21.4 62.9zM144 272a32 32 0 1 0 0-64 32 32 0 1 0 0 64zm144-32a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zm80 32a32 32 0 1 0 0-64 32 32 0 1 0 0 64z" } }, "free": ["regular", "solid"] }, "comment-medical": { "aliases": { "unicodes": { "secondary": ["10f7f5"] } }, "changes": ["5.7.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "advice", "bubble", "chat", "commenting", "conversation", "diagnose", "feedback", "message", "note", "notification", "prescription", "sms", "speech", "texting" ] }, "styles": ["solid"], "unicode": "f7f5", "label": "Comment Medical", "voted": false, "svg": { "solid": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 448c141.4 0 256-93.1 256-208S397.4 32 256 32S0 125.1 0 240c0 45.1 17.7 86.8 47.7 120.9c-1.9 24.5-11.4 46.3-21.4 62.9c-5.5 9.2-11.1 16.6-15.2 21.6c-2.1 2.5-3.7 4.4-4.9 5.7c-.6 .6-1 1.1-1.3 1.4l-.3 .3 0 0 0 0 0 0 0 0c-4.6 4.6-5.9 11.4-3.4 17.4c2.5 6 8.3 9.9 14.8 9.9c28.7 0 57.6-8.9 81.6-19.3c22.9-10 42.4-21.9 54.3-30.6c31.8 11.5 67 17.9 104.1 17.9zM224 160c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v48h48c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H288v48c0 8.8-7.2 16-16 16H240c-8.8 0-16-7.2-16-16V272H176c-8.8 0-16-7.2-16-16V224c0-8.8 7.2-16 16-16h48V160z" } }, "free": ["solid"] }, "comment-slash": { "aliases": { "unicodes": { "secondary": ["10f4b3"] } }, "changes": ["5.0.9", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "bubble", "cancel", "chat", "commenting", "conversation", "feedback", "message", "mute", "note", "notification", "quiet", "sms", "speech", "texting" ] }, "styles": ["solid"], "unicode": "f4b3", "label": "Comment Slash", "voted": false, "svg": { "solid": { "last_modified": 1684767392, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7L512.9 376.7C552.2 340.2 576 292.3 576 240C576 125.1 461.4 32 320 32c-67.7 0-129.3 21.4-175.1 56.3L38.8 5.1zM64 240c0 45.1 17.7 86.8 47.7 120.9c-1.9 24.5-11.4 46.3-21.4 62.9c-5.5 9.2-11.1 16.6-15.2 21.6c-2.1 2.5-3.7 4.4-4.9 5.7c-.6 .6-1 1.1-1.3 1.4l-.3 .3 0 0 0 0 0 0 0 0c-4.6 4.6-5.9 11.4-3.4 17.4c2.5 6 8.3 9.9 14.8 9.9c28.7 0 57.6-8.9 81.6-19.3c22.9-10 42.4-21.9 54.3-30.6c31.8 11.5 67 17.9 104.1 17.9c37 0 72.3-6.4 104-17.9L82.9 161.3C70.7 185.6 64 212.2 64 240z" } }, "free": ["solid"] }, "comment-sms": { "aliases": { "names": ["sms"], "unicodes": { "secondary": ["10f7cd"] } }, "changes": ["5.6.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "chat", "conversation", "message", "mobile", "notification", "phone", "sms", "texting" ] }, "styles": ["solid"], "unicode": "f7cd", "label": "Comment Sms", "voted": true, "svg": { "solid": { "last_modified": 1684767389, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 448c141.4 0 256-93.1 256-208S397.4 32 256 32S0 125.1 0 240c0 45.1 17.7 86.8 47.7 120.9c-1.9 24.5-11.4 46.3-21.4 62.9c-5.5 9.2-11.1 16.6-15.2 21.6c-2.1 2.5-3.7 4.4-4.9 5.7c-.6 .6-1 1.1-1.3 1.4l-.3 .3 0 0 0 0 0 0 0 0c-4.6 4.6-5.9 11.4-3.4 17.4c2.5 6 8.3 9.9 14.8 9.9c28.7 0 57.6-8.9 81.6-19.3c22.9-10 42.4-21.9 54.3-30.6c31.8 11.5 67 17.9 104.1 17.9zM202.9 176.8c6.5-2.2 13.7 .1 17.9 5.6L256 229.3l35.2-46.9c4.1-5.5 11.3-7.8 17.9-5.6s10.9 8.3 10.9 15.2v96c0 8.8-7.2 16-16 16s-16-7.2-16-16V240l-19.2 25.6c-3 4-7.8 6.4-12.8 6.4s-9.8-2.4-12.8-6.4L224 240v48c0 8.8-7.2 16-16 16s-16-7.2-16-16V192c0-6.9 4.4-13 10.9-15.2zm173.1 38c0 .2 0 .4 0 .4c.1 .1 .6 .8 2.2 1.7c3.9 2.3 9.6 4.1 18.3 6.8l.6 .2c7.4 2.2 17.3 5.2 25.2 10.2c9.1 5.7 17.4 15.2 17.6 29.9c.2 15-7.6 26-17.8 32.3c-9.5 5.9-20.9 7.9-30.7 7.6c-12.2-.4-23.7-4.4-32.6-7.4l0 0 0 0c-1.4-.5-2.7-.9-4-1.4c-8.4-2.8-12.9-11.9-10.1-20.2s11.9-12.9 20.2-10.1c1.7 .6 3.3 1.1 4.9 1.6l0 0 0 0c9.1 3.1 15.6 5.3 22.6 5.5c5.3 .2 10-1 12.8-2.8c1.2-.8 1.8-1.5 2.1-2c.2-.4 .6-1.2 .6-2.7l0-.2c0-.7 0-1.4-2.7-3.1c-3.8-2.4-9.6-4.3-18-6.9l-1.2-.4c-7.2-2.2-16.7-5-24.3-9.6c-9-5.4-17.7-14.7-17.7-29.4c-.1-15.2 8.6-25.7 18.5-31.6c9.4-5.5 20.5-7.5 29.7-7.4c10 .2 19.7 2.3 27.9 4.4c8.5 2.3 13.6 11 11.3 19.6s-11 13.6-19.6 11.3c-7.3-1.9-14.1-3.3-20.1-3.4c-4.9-.1-9.8 1.1-12.9 2.9c-1.4 .8-2.1 1.6-2.4 2c-.2 .3-.4 .8-.4 1.9zm-272 0c0 .2 0 .4 0 .4c.1 .1 .6 .8 2.2 1.7c3.9 2.3 9.6 4.1 18.3 6.8l.6 .2c7.4 2.2 17.3 5.2 25.2 10.2c9.1 5.7 17.4 15.2 17.6 29.9c.2 15-7.6 26-17.8 32.3c-9.5 5.9-20.9 7.9-30.7 7.6c-12.3-.4-24.2-4.5-33.2-7.6l0 0 0 0c-1.3-.4-2.5-.8-3.6-1.2c-8.4-2.8-12.9-11.9-10.1-20.2s11.9-12.9 20.2-10.1c1.4 .5 2.8 .9 4.1 1.4l0 0 0 0c9.5 3.2 16.5 5.6 23.7 5.8c5.3 .2 10-1 12.8-2.8c1.2-.8 1.8-1.5 2.1-2c.2-.4 .6-1.2 .6-2.7l0-.2c0-.7 0-1.4-2.7-3.1c-3.8-2.4-9.6-4.3-18-6.9l-1.2-.4 0 0c-7.2-2.2-16.7-5-24.3-9.6C80.8 239 72.1 229.7 72 215c-.1-15.2 8.6-25.7 18.5-31.6c9.4-5.5 20.5-7.5 29.7-7.4c9.5 .1 22.2 2.1 31.1 4.4c8.5 2.3 13.6 11 11.3 19.6s-11 13.6-19.6 11.3c-6.6-1.8-16.8-3.3-23.3-3.4c-4.9-.1-9.8 1.1-12.9 2.9c-1.4 .8-2.1 1.6-2.4 2c-.2 .3-.4 .8-.4 1.9z" } }, "free": ["solid"] }, "comments": { "aliases": { "unicodes": { "composite": ["1f5ea", "f0e6"], "secondary": ["10f086"] } }, "changes": [ "1.0.0", "5.0.0", "5.0.9", "6.0.0-beta1", "6.0.0-beta2", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Two Speech Bubbles", "bubble", "chat", "commenting", "conversation", "feedback", "message", "note", "notification", "sms", "speech", "texting" ] }, "styles": ["solid", "regular"], "unicode": "f086", "label": "Comments", "voted": false, "svg": { "solid": { "last_modified": 1684767393, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M208 352c114.9 0 208-78.8 208-176S322.9 0 208 0S0 78.8 0 176c0 38.6 14.7 74.3 39.6 103.4c-3.5 9.4-8.7 17.7-14.2 24.7c-4.8 6.2-9.7 11-13.3 14.3c-1.8 1.6-3.3 2.9-4.3 3.7c-.5 .4-.9 .7-1.1 .8l-.2 .2 0 0 0 0C1 327.2-1.4 334.4 .8 340.9S9.1 352 16 352c21.8 0 43.8-5.6 62.1-12.5c9.2-3.5 17.8-7.4 25.3-11.4C134.1 343.3 169.8 352 208 352zM448 176c0 112.3-99.1 196.9-216.5 207C255.8 457.4 336.4 512 432 512c38.2 0 73.9-8.7 104.7-23.9c7.5 4 16 7.9 25.2 11.4c18.3 6.9 40.3 12.5 62.1 12.5c6.9 0 13.1-4.5 15.2-11.1c2.1-6.6-.2-13.8-5.8-17.9l0 0 0 0-.2-.2c-.2-.2-.6-.4-1.1-.8c-1-.8-2.5-2-4.3-3.7c-3.6-3.3-8.5-8.1-13.3-14.3c-5.5-7-10.7-15.4-14.2-24.7c24.9-29 39.6-64.7 39.6-103.4c0-92.8-84.9-168.9-192.6-175.5c.4 5.1 .6 10.3 .6 15.5z" }, "regular": { "last_modified": 1684767393, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M88.2 309.1c9.8-18.3 6.8-40.8-7.5-55.8C59.4 230.9 48 204 48 176c0-63.5 63.8-128 160-128s160 64.5 160 128s-63.8 128-160 128c-13.1 0-25.8-1.3-37.8-3.6c-10.4-2-21.2-.6-30.7 4.2c-4.1 2.1-8.3 4.1-12.6 6c-16 7.2-32.9 13.5-49.9 18c2.8-4.6 5.4-9.1 7.9-13.6c1.1-1.9 2.2-3.9 3.2-5.9zM0 176c0 41.8 17.2 80.1 45.9 110.3c-.9 1.7-1.9 3.5-2.8 5.1c-10.3 18.4-22.3 36.5-36.6 52.1c-6.6 7-8.3 17.2-4.6 25.9C5.8 378.3 14.4 384 24 384c43 0 86.5-13.3 122.7-29.7c4.8-2.2 9.6-4.5 14.2-6.8c15.1 3 30.9 4.5 47.1 4.5c114.9 0 208-78.8 208-176S322.9 0 208 0S0 78.8 0 176zM432 480c16.2 0 31.9-1.6 47.1-4.5c4.6 2.3 9.4 4.6 14.2 6.8C529.5 498.7 573 512 616 512c9.6 0 18.2-5.7 22-14.5c3.8-8.8 2-19-4.6-25.9c-14.2-15.6-26.2-33.7-36.6-52.1c-.9-1.7-1.9-3.4-2.8-5.1C622.8 384.1 640 345.8 640 304c0-94.4-87.9-171.5-198.2-175.8c4.1 15.2 6.2 31.2 6.2 47.8l0 .6c87.2 6.7 144 67.5 144 127.4c0 28-11.4 54.9-32.7 77.2c-14.3 15-17.3 37.6-7.5 55.8c1.1 2 2.2 4 3.2 5.9c2.5 4.5 5.2 9 7.9 13.6c-17-4.5-33.9-10.7-49.9-18c-4.3-1.9-8.5-3.9-12.6-6c-9.5-4.8-20.3-6.2-30.7-4.2c-12.1 2.4-24.7 3.6-37.8 3.6c-61.7 0-110-26.5-136.8-62.3c-16 5.4-32.8 9.4-50 11.8C279 439.8 350 480 432 480z" } }, "free": ["regular", "solid"] }, "comments-dollar": { "aliases": { "unicodes": { "secondary": ["10f653"] } }, "changes": [ "5.3.0", "6.0.0-beta1", "6.0.0-beta2", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "bubble", "chat", "commenting", "conversation", "feedback", "message", "money", "note", "notification", "pay", "sms", "speech", "spend", "texting", "transfer" ] }, "styles": ["solid"], "unicode": "f653", "label": "Comments Dollar", "voted": false, "svg": { "solid": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M416 176c0 97.2-93.1 176-208 176c-38.2 0-73.9-8.7-104.7-23.9c-7.5 4-16 7.9-25.2 11.4C59.8 346.4 37.8 352 16 352c-6.9 0-13.1-4.5-15.2-11.1s.2-13.8 5.8-17.9l0 0 0 0 .2-.2c.2-.2 .6-.4 1.1-.8c1-.8 2.5-2 4.3-3.7c3.6-3.3 8.5-8.1 13.3-14.3c5.5-7 10.7-15.4 14.2-24.7C14.7 250.3 0 214.6 0 176C0 78.8 93.1 0 208 0S416 78.8 416 176zM231.5 383C348.9 372.9 448 288.3 448 176c0-5.2-.2-10.4-.6-15.5C555.1 167.1 640 243.2 640 336c0 38.6-14.7 74.3-39.6 103.4c3.5 9.4 8.7 17.7 14.2 24.7c4.8 6.2 9.7 11 13.3 14.3c1.8 1.6 3.3 2.9 4.3 3.7c.5 .4 .9 .7 1.1 .8l.2 .2 0 0 0 0c5.6 4.1 7.9 11.3 5.8 17.9c-2.1 6.6-8.3 11.1-15.2 11.1c-21.8 0-43.8-5.6-62.1-12.5c-9.2-3.5-17.8-7.4-25.2-11.4C505.9 503.3 470.2 512 432 512c-95.6 0-176.2-54.6-200.5-129zM228 72c0-11-9-20-20-20s-20 9-20 20V86c-7.6 1.7-15.2 4.4-22.2 8.5c-13.9 8.3-25.9 22.8-25.8 43.9c.1 20.3 12 33.1 24.7 40.7c11 6.6 24.7 10.8 35.6 14l1.7 .5c12.6 3.8 21.8 6.8 28 10.7c5.1 3.2 5.8 5.4 5.9 8.2c.1 5-1.8 8-5.9 10.5c-5 3.1-12.9 5-21.4 4.7c-11.1-.4-21.5-3.9-35.1-8.5c-2.3-.8-4.7-1.6-7.2-2.4c-10.5-3.5-21.8 2.2-25.3 12.6s2.2 21.8 12.6 25.3c1.9 .6 4 1.3 6.1 2.1l0 0 0 0c8.3 2.9 17.9 6.2 28.2 8.4V280c0 11 9 20 20 20s20-9 20-20V266.2c8-1.7 16-4.5 23.2-9c14.3-8.9 25.1-24.1 24.8-45c-.3-20.3-11.7-33.4-24.6-41.6c-11.5-7.2-25.9-11.6-37.1-15l-.7-.2c-12.8-3.9-21.9-6.7-28.3-10.5c-5.2-3.1-5.3-4.9-5.3-6.7c0-3.7 1.4-6.5 6.2-9.3c5.4-3.2 13.6-5.1 21.5-5c9.6 .1 20.2 2.2 31.2 5.2c10.7 2.8 21.6-3.5 24.5-14.2s-3.5-21.6-14.2-24.5c-6.5-1.7-13.7-3.4-21.1-4.7V72z" } }, "free": ["solid"] }, "compact-disc": { "aliases": { "unicodes": { "composite": ["1f4bf", "1f4c0", "1f5b8"], "secondary": ["10f51f"] } }, "changes": [ "5.0.13", "5.10.1", "5.11.0", "5.11.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Optical Disc Icon", "album", "blu-ray", "bluray", "cd", "computer", "disc", "disk", "dvd", "media", "movie", "music", "optical", "optical disk", "record", "video", "vinyl" ] }, "styles": ["solid"], "unicode": "f51f", "label": "Compact Disc", "voted": true, "svg": { "solid": { "last_modified": 1684766675, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm256 32a32 32 0 1 1 0-64 32 32 0 1 1 0 64zm-96-32a96 96 0 1 0 192 0 96 96 0 1 0 -192 0zM96 240c0-35 17.5-71.1 45.2-98.8S205 96 240 96c8.8 0 16-7.2 16-16s-7.2-16-16-16c-45.4 0-89.2 22.3-121.5 54.5S64 194.6 64 240c0 8.8 7.2 16 16 16s16-7.2 16-16z" } }, "free": ["solid"] }, "compass": { "aliases": { "unicodes": { "composite": ["1f9ed"], "secondary": ["10f14e"] } }, "changes": [ "3.2.0", "5.0.0", "5.2.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "compass", "directions", "directory", "location", "magnetic", "menu", "navigation", "orienteering", "safari", "travel" ] }, "styles": ["solid", "regular"], "unicode": "f14e", "label": "Compass", "voted": false, "svg": { "solid": { "last_modified": 1684767489, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zm50.7-186.9L162.4 380.6c-19.4 7.5-38.5-11.6-31-31l55.5-144.3c3.3-8.5 9.9-15.1 18.4-18.4l144.3-55.5c19.4-7.5 38.5 11.6 31 31L325.1 306.7c-3.2 8.5-9.9 15.1-18.4 18.4zM288 256a32 32 0 1 0 -64 0 32 32 0 1 0 64 0z" }, "regular": { "last_modified": 1684767489, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M464 256A208 208 0 1 0 48 256a208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm306.7 69.1L162.4 380.6c-19.4 7.5-38.5-11.6-31-31l55.5-144.3c3.3-8.5 9.9-15.1 18.4-18.4l144.3-55.5c19.4-7.5 38.5 11.6 31 31L325.1 306.7c-3.2 8.5-9.9 15.1-18.4 18.4zM288 256a32 32 0 1 0 -64 0 32 32 0 1 0 64 0z" } }, "free": ["regular", "solid"] }, "compass-drafting": { "aliases": { "names": ["drafting-compass"], "unicodes": { "secondary": ["10f568"] } }, "changes": ["5.1.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["design", "map", "mechanical drawing", "plot", "plotting"] }, "styles": ["solid"], "unicode": "f568", "label": "Compass Drafting", "voted": false, "svg": { "solid": { "last_modified": 1684767368, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M352 96c0 14.3-3.1 27.9-8.8 40.2L396 227.4c-23.7 25.3-54.2 44.1-88.5 53.6L256 192h0 0l-68 117.5c21.5 6.8 44.3 10.5 68.1 10.5c70.7 0 133.8-32.7 174.9-84c11.1-13.8 31.2-16 45-5s16 31.2 5 45C428.1 341.8 347 384 256 384c-35.4 0-69.4-6.4-100.7-18.1L98.7 463.7C94 471.8 87 478.4 78.6 482.6L23.2 510.3c-5 2.5-10.9 2.2-15.6-.7S0 501.5 0 496V440.6c0-8.4 2.2-16.7 6.5-24.1l60-103.7C53.7 301.6 41.8 289.3 31.2 276c-11.1-13.8-8.8-33.9 5-45s33.9-8.8 45 5c5.7 7.1 11.8 13.8 18.2 20.1l69.4-119.9c-5.6-12.2-8.8-25.8-8.8-40.2c0-53 43-96 96-96s96 43 96 96zm21 297.9c32.6-12.8 62.5-30.8 88.9-52.9l43.7 75.5c4.2 7.3 6.5 15.6 6.5 24.1V496c0 5.5-2.9 10.7-7.6 13.6s-10.6 3.2-15.6 .7l-55.4-27.7c-8.4-4.2-15.4-10.8-20.1-18.9L373 393.9zM256 128a32 32 0 1 0 0-64 32 32 0 1 0 0 64z" } }, "free": ["solid"] }, "compress": { "aliases": { "unicodes": { "secondary": ["10f066"] } }, "changes": ["5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "collapse", "fullscreen", "minimize", "move", "resize", "shrink", "smaller" ] }, "styles": ["solid"], "unicode": "f066", "label": "Compress", "voted": false, "svg": { "solid": { "last_modified": 1684766332, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M160 64c0-17.7-14.3-32-32-32s-32 14.3-32 32v64H32c-17.7 0-32 14.3-32 32s14.3 32 32 32h96c17.7 0 32-14.3 32-32V64zM32 320c-17.7 0-32 14.3-32 32s14.3 32 32 32H96v64c0 17.7 14.3 32 32 32s32-14.3 32-32V352c0-17.7-14.3-32-32-32H32zM352 64c0-17.7-14.3-32-32-32s-32 14.3-32 32v96c0 17.7 14.3 32 32 32h96c17.7 0 32-14.3 32-32s-14.3-32-32-32H352V64zM320 320c-17.7 0-32 14.3-32 32v96c0 17.7 14.3 32 32 32s32-14.3 32-32V384h64c17.7 0 32-14.3 32-32s-14.3-32-32-32H320z" } }, "free": ["solid"] }, "computer": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["computer", "desktop", "display", "monitor", "tower"] }, "styles": ["solid"], "unicode": "e4e5", "label": "Computer", "voted": false, "svg": { "solid": { "last_modified": 1684767342, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M384 96V320H64L64 96H384zM64 32C28.7 32 0 60.7 0 96V320c0 35.3 28.7 64 64 64H181.3l-10.7 32H96c-17.7 0-32 14.3-32 32s14.3 32 32 32H352c17.7 0 32-14.3 32-32s-14.3-32-32-32H277.3l-10.7-32H384c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zm464 0c-26.5 0-48 21.5-48 48V432c0 26.5 21.5 48 48 48h64c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48H528zm16 64h32c8.8 0 16 7.2 16 16s-7.2 16-16 16H544c-8.8 0-16-7.2-16-16s7.2-16 16-16zm-16 80c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16s-7.2 16-16 16H544c-8.8 0-16-7.2-16-16zm32 160a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" } }, "free": ["solid"] }, "computer-mouse": { "aliases": { "names": ["mouse"], "unicodes": { "composite": ["1f5b1"], "secondary": ["10f8cc"] } }, "changes": ["5.11.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "click", "computer", "computer mouse", "cursor", "input", "peripheral" ] }, "styles": ["solid"], "unicode": "f8cc", "label": "Computer Mouse", "voted": true, "svg": { "solid": { "last_modified": 1684767343, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M0 192H176V0H160C71.6 0 0 71.6 0 160v32zm0 32V352c0 88.4 71.6 160 160 160h64c88.4 0 160-71.6 160-160V224H192 0zm384-32V160C384 71.6 312.4 0 224 0H208V192H384z" } }, "free": ["solid"] }, "confluence": { "changes": ["5.6.0"], "ligatures": [], "search": { "terms": ["atlassian"] }, "styles": ["brands"], "unicode": "f78d", "label": "Confluence", "voted": true, "svg": { "brands": { "last_modified": 1660014474, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M2.3 412.2c-4.5 7.6-2.1 17.5 5.5 22.2l105.9 65.2c7.7 4.7 17.7 2.4 22.4-5.3 0-.1.1-.2.1-.2 67.1-112.2 80.5-95.9 280.9-.7 8.1 3.9 17.8.4 21.7-7.7.1-.1.1-.3.2-.4l50.4-114.1c3.6-8.1-.1-17.6-8.1-21.3-22.2-10.4-66.2-31.2-105.9-50.3C127.5 179 44.6 345.3 2.3 412.2zm507.4-312.1c4.5-7.6 2.1-17.5-5.5-22.2L398.4 12.8c-7.5-5-17.6-3.1-22.6 4.4-.2.3-.4.6-.6 1-67.3 112.6-81.1 95.6-280.6.9-8.1-3.9-17.8-.4-21.7 7.7-.1.1-.1.3-.2.4L22.2 141.3c-3.6 8.1.1 17.6 8.1 21.3 22.2 10.4 66.3 31.2 106 50.4 248 120 330.8-45.4 373.4-112.9z" } }, "free": ["brands"] }, "connectdevelop": { "changes": ["4.3.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f20e", "label": "Connect Develop", "voted": false, "svg": { "brands": { "last_modified": 1660014462, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M550.5 241l-50.089-86.786c1.071-2.142 1.875-4.553 1.875-7.232 0-8.036-6.696-14.733-14.732-15.001l-55.447-95.893c.536-1.607 1.071-3.214 1.071-4.821 0-8.571-6.964-15.268-15.268-15.268-4.821 0-8.839 2.143-11.786 5.625H299.518C296.839 18.143 292.821 16 288 16s-8.839 2.143-11.518 5.625H170.411C167.464 18.143 163.447 16 158.625 16c-8.303 0-15.268 6.696-15.268 15.268 0 1.607.536 3.482 1.072 4.821l-55.983 97.233c-5.356 2.41-9.107 7.5-9.107 13.661 0 .535.268 1.071.268 1.607l-53.304 92.143c-7.232 1.339-12.59 7.5-12.59 15 0 7.232 5.089 13.393 12.054 15l55.179 95.358c-.536 1.607-.804 2.946-.804 4.821 0 7.232 5.089 13.393 12.054 14.732l51.697 89.732c-.536 1.607-1.071 3.482-1.071 5.357 0 8.571 6.964 15.268 15.268 15.268 4.821 0 8.839-2.143 11.518-5.357h106.875C279.161 493.857 283.447 496 288 496s8.839-2.143 11.518-5.357h107.143c2.678 2.946 6.696 4.821 10.982 4.821 8.571 0 15.268-6.964 15.268-15.268 0-1.607-.267-2.946-.803-4.285l51.697-90.268c6.964-1.339 12.054-7.5 12.054-14.732 0-1.607-.268-3.214-.804-4.821l54.911-95.358c6.964-1.339 12.322-7.5 12.322-15-.002-7.232-5.092-13.393-11.788-14.732zM153.535 450.732l-43.66-75.803h43.66v75.803zm0-83.839h-43.66c-.268-1.071-.804-2.142-1.339-3.214l44.999-47.41v50.624zm0-62.411l-50.357 53.304c-1.339-.536-2.679-1.34-4.018-1.607L43.447 259.75c.535-1.339.535-2.679.535-4.018s0-2.41-.268-3.482l51.965-90c2.679-.268 5.357-1.072 7.768-2.679l50.089 51.965v92.946zm0-102.322l-45.803-47.41c1.339-2.143 2.143-4.821 2.143-7.767 0-.268-.268-.804-.268-1.072l43.928-15.804v72.053zm0-80.625l-43.66 15.804 43.66-75.536v59.732zm326.519 39.108l.804 1.339L445.5 329.125l-63.75-67.232 98.036-101.518.268.268zM291.75 355.107l11.518 11.786H280.5l11.25-11.786zm-.268-11.25l-83.303-85.446 79.553-84.375 83.036 87.589-79.286 82.232zm5.357 5.893l79.286-82.232 67.5 71.25-5.892 28.125H313.714l-16.875-17.143zM410.411 44.393c1.071.536 2.142 1.072 3.482 1.34l57.857 100.714v.536c0 2.946.803 5.624 2.143 7.767L376.393 256l-83.035-87.589L410.411 44.393zm-9.107-2.143L287.732 162.518l-57.054-60.268 166.339-60h4.287zm-123.483 0c2.678 2.678 6.16 4.285 10.179 4.285s7.5-1.607 10.179-4.285h75L224.786 95.821 173.893 42.25h103.928zm-116.249 5.625l1.071-2.142a33.834 33.834 0 0 0 2.679-.804l51.161 53.84-54.911 19.821V47.875zm0 79.286l60.803-21.964 59.732 63.214-79.553 84.107-40.982-42.053v-83.304zm0 92.678L198 257.607l-36.428 38.304v-76.072zm0 87.858l42.053-44.464 82.768 85.982-17.143 17.678H161.572v-59.196zm6.964 162.053c-1.607-1.607-3.482-2.678-5.893-3.482l-1.071-1.607v-89.732h99.91l-91.607 94.821h-1.339zm129.911 0c-2.679-2.41-6.428-4.285-10.447-4.285s-7.767 1.875-10.447 4.285h-96.429l91.607-94.821h38.304l91.607 94.821H298.447zm120-11.786l-4.286 7.5c-1.339.268-2.41.803-3.482 1.339l-89.196-91.875h114.376l-17.412 83.036zm12.856-22.232l12.858-60.803h21.964l-34.822 60.803zm34.822-68.839h-20.357l4.553-21.16 17.143 18.214c-.535.803-1.071 1.874-1.339 2.946zm66.161-107.411l-55.447 96.697c-1.339.535-2.679 1.071-4.018 1.874l-20.625-21.964 34.554-163.928 45.803 79.286c-.267 1.339-.803 2.678-.803 4.285 0 1.339.268 2.411.536 3.75z" } }, "free": ["brands"] }, "contao": { "changes": ["4.4.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f26d", "label": "Contao", "voted": false, "svg": { "brands": { "last_modified": 1660014480, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M45.4 305c14.4 67.1 26.4 129 68.2 175H34c-18.7 0-34-15.2-34-34V66c0-18.7 15.2-34 34-34h57.7C77.9 44.6 65.6 59.2 54.8 75.6c-45.4 70-27 146.8-9.4 229.4zM478 32h-90.2c21.4 21.4 39.2 49.5 52.7 84.1l-137.1 29.3c-14.9-29-37.8-53.3-82.6-43.9-24.6 5.3-41 19.3-48.3 34.6-8.8 18.7-13.2 39.8 8.2 140.3 21.1 100.2 33.7 117.7 49.5 131.2 12.9 11.1 33.4 17 58.3 11.7 44.5-9.4 55.7-40.7 57.4-73.2l137.4-29.6c3.2 71.5-18.7 125.2-57.4 163.6H478c18.7 0 34-15.2 34-34V66c0-18.8-15.2-34-34-34z" } }, "free": ["brands"] }, "cookie": { "aliases": { "unicodes": { "composite": ["1f36a"], "secondary": ["10f563"] } }, "changes": ["5.1.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "baked good", "chips", "chocolate", "cookie", "dessert", "eat", "snack", "sweet", "treat" ] }, "styles": ["solid"], "unicode": "f563", "label": "Cookie", "voted": true, "svg": { "solid": { "last_modified": 1684767419, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M247.2 17c-22.1-3.1-44.6 .9-64.4 11.4l-74 39.5C89.1 78.4 73.2 94.9 63.4 115L26.7 190.6c-9.8 20.1-13 42.9-9.1 64.9l14.5 82.8c3.9 22.1 14.6 42.3 30.7 57.9l60.3 58.4c16.1 15.6 36.6 25.6 58.7 28.7l83 11.7c22.1 3.1 44.6-.9 64.4-11.4l74-39.5c19.7-10.5 35.6-27 45.4-47.2l36.7-75.5c9.8-20.1 13-42.9 9.1-64.9l-14.6-82.8c-3.9-22.1-14.6-42.3-30.7-57.9L388.9 57.5c-16.1-15.6-36.6-25.6-58.7-28.7L247.2 17zM208 144a32 32 0 1 1 0 64 32 32 0 1 1 0-64zM144 336a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm224-64a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" } }, "free": ["solid"] }, "cookie-bite": { "aliases": { "unicodes": { "secondary": ["10f564"] } }, "changes": ["5.1.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "baked good", "bitten", "chips", "chocolate", "eat", "snack", "sweet", "treat" ] }, "styles": ["solid"], "unicode": "f564", "label": "Cookie Bite", "voted": true, "svg": { "solid": { "last_modified": 1684767418, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M257.5 27.6c-.8-5.4-4.9-9.8-10.3-10.6c-22.1-3.1-44.6 .9-64.4 11.4l-74 39.5C89.1 78.4 73.2 94.9 63.4 115L26.7 190.6c-9.8 20.1-13 42.9-9.1 64.9l14.5 82.8c3.9 22.1 14.6 42.3 30.7 57.9l60.3 58.4c16.1 15.6 36.6 25.6 58.7 28.7l83 11.7c22.1 3.1 44.6-.9 64.4-11.4l74-39.5c19.7-10.5 35.6-27 45.4-47.2l36.7-75.5c9.8-20.1 13-42.9 9.1-64.9c-.9-5.3-5.3-9.3-10.6-10.1c-51.5-8.2-92.8-47.1-104.5-97.4c-1.8-7.6-8-13.4-15.7-14.6c-54.6-8.7-97.7-52-106.2-106.8zM208 144a32 32 0 1 1 0 64 32 32 0 1 1 0-64zM144 336a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm224-64a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" } }, "free": ["solid"] }, "copy": { "aliases": { "unicodes": { "secondary": ["10f0c5"] } }, "changes": [ "2.0.0", "5.0.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0", "6.4.1" ], "ligatures": [], "search": { "terms": ["clone", "duplicate", "file", "files-o", "paper", "paste"] }, "styles": ["solid", "regular"], "unicode": "f0c5", "label": "Copy", "voted": false, "svg": { "solid": { "last_modified": 1684767389, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M208 0H332.1c12.7 0 24.9 5.1 33.9 14.1l67.9 67.9c9 9 14.1 21.2 14.1 33.9V336c0 26.5-21.5 48-48 48H208c-26.5 0-48-21.5-48-48V48c0-26.5 21.5-48 48-48zM48 128h80v64H64V448H256V416h64v48c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V176c0-26.5 21.5-48 48-48z" }, "regular": { "last_modified": 1684767389, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M384 336H192c-8.8 0-16-7.2-16-16V64c0-8.8 7.2-16 16-16l140.1 0L400 115.9V320c0 8.8-7.2 16-16 16zM192 384H384c35.3 0 64-28.7 64-64V115.9c0-12.7-5.1-24.9-14.1-33.9L366.1 14.1c-9-9-21.2-14.1-33.9-14.1H192c-35.3 0-64 28.7-64 64V320c0 35.3 28.7 64 64 64zM64 128c-35.3 0-64 28.7-64 64V448c0 35.3 28.7 64 64 64H256c35.3 0 64-28.7 64-64V416H272v32c0 8.8-7.2 16-16 16H64c-8.8 0-16-7.2-16-16V192c0-8.8 7.2-16 16-16H96V128H64z" } }, "free": ["regular", "solid"] }, "copyright": { "aliases": { "unicodes": { "composite": ["a9"], "secondary": ["10f1f9"] } }, "changes": [ "4.2.0", "5.0.0", "5.10.1", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["brand", "c", "copyright", "mark", "register", "trademark"] }, "styles": ["solid", "regular"], "unicode": "f1f9", "label": "Copyright", "voted": false, "svg": { "solid": { "last_modified": 1684767244, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM199.4 312.6c31.2 31.2 81.9 31.2 113.1 0c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9c-50 50-131 50-181 0s-50-131 0-181s131-50 181 0c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0c-31.2-31.2-81.9-31.2-113.1 0s-31.2 81.9 0 113.1z" }, "regular": { "last_modified": 1684767244, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 48a208 208 0 1 1 0 416 208 208 0 1 1 0-416zm0 464A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM199.4 312.6c-31.2-31.2-31.2-81.9 0-113.1s81.9-31.2 113.1 0c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9c-50-50-131-50-181 0s-50 131 0 181s131 50 181 0c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0c-31.2 31.2-81.9 31.2-113.1 0z" } }, "free": ["regular", "solid"] }, "cotton-bureau": { "changes": ["5.10.0"], "ligatures": [], "search": { "terms": ["clothing", "t-shirts", "tshirts"] }, "styles": ["brands"], "unicode": "f89e", "label": "Cotton Bureau", "voted": false, "svg": { "brands": { "last_modified": 1660014467, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M474.31 330.41c-23.66 91.85-94.23 144.59-201.9 148.35V429.6c0-48 26.41-74.39 74.39-74.39 62 0 99.2-37.2 99.2-99.21 0-61.37-36.53-98.28-97.38-99.06-33-69.32-146.5-64.65-177.24 0C110.52 157.72 74 194.63 74 256c0 62.13 37.27 99.41 99.4 99.41 48 0 74.55 26.23 74.55 74.39V479c-134.43-5-211.1-85.07-211.1-223 0-141.82 81.35-223.2 223.2-223.2 114.77 0 189.84 53.2 214.69 148.81H500C473.88 71.51 388.22 8 259.82 8 105 8 12 101.19 12 255.82 12 411.14 105.19 504.34 259.82 504c128.27 0 213.87-63.81 239.67-173.59zM357 182.33c41.37 3.45 64.2 29 64.2 73.67 0 48-26.43 74.41-74.4 74.41-28.61 0-49.33-9.59-61.59-27.33 83.06-16.55 75.59-99.67 71.79-120.75zm-81.68 97.36c-2.46-10.34-16.33-87 56.23-97 2.27 10.09 16.52 87.11-56.26 97zM260 132c28.61 0 49 9.67 61.44 27.61-28.36 5.48-49.36 20.59-61.59 43.45-12.23-22.86-33.23-38-61.6-43.45 12.41-17.69 33.27-27.35 61.57-27.35zm-71.52 50.72c73.17 10.57 58.91 86.81 56.49 97-72.41-9.84-59-86.95-56.25-97zM173.2 330.41c-48 0-74.4-26.4-74.4-74.41 0-44.36 22.86-70 64.22-73.67-6.75 37.2-1.38 106.53 71.65 120.75-12.14 17.63-32.84 27.3-61.14 27.3zm53.21 12.39A80.8 80.8 0 0 0 260 309.25c7.77 14.49 19.33 25.54 33.82 33.55a80.28 80.28 0 0 0-33.58 33.83c-8-14.5-19.07-26.23-33.56-33.83z" } }, "free": ["brands"] }, "couch": { "aliases": { "unicodes": { "secondary": ["10f4b8"] } }, "changes": ["5.0.9", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["chair", "cushion", "furniture", "relax", "sofa"] }, "styles": ["solid"], "unicode": "f4b8", "label": "Couch", "voted": false, "svg": { "solid": { "last_modified": 1684767443, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M64 160C64 89.3 121.3 32 192 32H448c70.7 0 128 57.3 128 128v33.6c-36.5 7.4-64 39.7-64 78.4v48H128V272c0-38.7-27.5-71-64-78.4V160zM544 272c0-20.9 13.4-38.7 32-45.3c5-1.8 10.4-2.7 16-2.7c26.5 0 48 21.5 48 48V448c0 17.7-14.3 32-32 32H576c-17.7 0-32-14.3-32-32H96c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32V272c0-26.5 21.5-48 48-48c5.6 0 11 1 16 2.7c18.6 6.6 32 24.4 32 45.3v48 32h32H512h32V320 272z" } }, "free": ["solid"] }, "cow": { "aliases": { "unicodes": { "composite": ["1f404"], "secondary": ["10f6c8"] } }, "changes": ["5.4.0", "6.0.0-beta1", "6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "agriculture", "animal", "beef", "bovine", "co", "cow", "farm", "fauna", "livestock", "mammal", "milk", "moo" ] }, "styles": ["solid"], "unicode": "f6c8", "label": "Cow", "voted": false, "svg": { "solid": { "last_modified": 1684768131, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M96 224v32V416c0 17.7 14.3 32 32 32h32c17.7 0 32-14.3 32-32V327.8c9.9 6.6 20.6 12 32 16.1V368c0 8.8 7.2 16 16 16s16-7.2 16-16V351.1c5.3 .6 10.6 .9 16 .9s10.7-.3 16-.9V368c0 8.8 7.2 16 16 16s16-7.2 16-16V343.8c11.4-4 22.1-9.4 32-16.1V416c0 17.7 14.3 32 32 32h32c17.7 0 32-14.3 32-32V256l32 32v49.5c0 9.5 2.8 18.7 8.1 26.6L530 427c8.8 13.1 23.5 21 39.3 21c22.5 0 41.9-15.9 46.3-38l20.3-101.6c2.6-13-.3-26.5-8-37.3l-3.9-5.5V184c0-13.3-10.7-24-24-24s-24 10.7-24 24v14.4l-52.9-74.1C496 86.5 452.4 64 405.9 64H272 256 192 144C77.7 64 24 117.7 24 184v54C9.4 249.8 0 267.8 0 288v17.6c0 8 6.4 14.4 14.4 14.4C46.2 320 72 294.2 72 262.4V256 224 184c0-24.3 12.1-45.8 30.5-58.9C98.3 135.9 96 147.7 96 160v64zM560 336a16 16 0 1 1 32 0 16 16 0 1 1 -32 0zM166.6 166.6c-4.2-4.2-6.6-10-6.6-16c0-12.5 10.1-22.6 22.6-22.6H361.4c12.5 0 22.6 10.1 22.6 22.6c0 6-2.4 11.8-6.6 16l-23.4 23.4C332.2 211.8 302.7 224 272 224s-60.2-12.2-81.9-33.9l-23.4-23.4z" } }, "free": ["solid"] }, "cpanel": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f388", "label": "cPanel", "voted": false, "svg": { "brands": { "last_modified": 1660014463, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M210.3 220.2c-5.6-24.8-26.9-41.2-51-41.2h-37c-7.1 0-12.5 4.5-14.3 10.9L73.1 320l24.7-.1c6.8 0 12.3-4.5 14.2-10.7l25.8-95.7h19.8c8.4 0 16.2 5.6 18.3 14.8 2.5 10.9-5.9 22.6-18.3 22.6h-10.3c-7 0-12.5 4.6-14.3 10.8l-6.4 23.8h32c37.2 0 58.3-36.2 51.7-65.3zm-156.5 28h18.6c6.9 0 12.4-4.4 14.3-10.9l6.2-23.6h-40C30 213.7 9 227.8 1.7 254.8-7 288.6 18.5 320 52 320h12.4l7.1-26.1c1.2-4.4-2.2-8.3-6.4-8.3H53.8c-24.7 0-24.9-37.4 0-37.4zm247.5-34.8h-77.9l-3.5 13.4c-2.4 9.6 4.5 18.5 14.2 18.5h57.5c4 0 2.4 4.3 2.1 5.3l-8.6 31.8c-.4 1.4-.9 5.3-5.5 5.3h-34.9c-5.3 0-5.3-7.9 0-7.9h21.6c6.8 0 12.3-4.6 14.2-10.8l3.5-13.2h-48.4c-39.2 0-43.6 63.8-.7 63.8l57.5.2c11.2 0 20.6-7.2 23.4-17.8l14-51.8c4.8-19.2-9.7-36.8-28.5-36.8zM633.1 179h-18.9c-4.9 0-9.2 3.2-10.4 7.9L568.2 320c20.7 0 39.8-13.8 44.9-34.5l26.5-98.2c1.2-4.3-2-8.3-6.5-8.3zm-236.3 34.7v.1h-48.3l-26.2 98c-1.2 4.4 2.2 8.3 6.4 8.3h18.9c4.8 0 9.2-3 10.4-7.8l17.2-64H395c12.5 0 21.4 11.8 18.1 23.4l-10.6 40c-1.2 4.3 1.9 8.3 6.4 8.3H428c4.6 0 9.1-2.9 10.3-7.8l8.8-33.1c9-33.1-15.9-65.4-50.3-65.4zm98.3 74.6c-3.6 0-6-3.4-5.1-6.7l8-30c.9-3.9 3.7-6 7.8-6h32.9c2.6 0 4.6 2.4 3.9 5.1l-.7 2.6c-.6 2-1.9 3-3.9 3h-21.6c-7 0-12.6 4.6-14.2 10.8l-3.5 13h53.4c10.5 0 20.3-6.6 23.2-17.6l3.2-12c4.9-19.1-9.3-36.8-28.3-36.8h-47.3c-17.9 0-33.8 12-38.6 29.6l-10.8 40c-5 17.7 8.3 36.7 28.3 36.7h66.7c6.8 0 12.3-4.5 14.2-10.7l5.7-21z" } }, "free": ["brands"] }, "creative-commons": { "changes": ["4.4.0", "5.0.0", "5.0.11", "5.1.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f25e", "label": "Creative Commons", "voted": false, "svg": { "brands": { "last_modified": 1660014478, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M245.83 214.87l-33.22 17.28c-9.43-19.58-25.24-19.93-27.46-19.93-22.13 0-33.22 14.61-33.22 43.84 0 23.57 9.21 43.84 33.22 43.84 14.47 0 24.65-7.09 30.57-21.26l30.55 15.5c-6.17 11.51-25.69 38.98-65.1 38.98-22.6 0-73.96-10.32-73.96-77.05 0-58.69 43-77.06 72.63-77.06 30.72-.01 52.7 11.95 65.99 35.86zm143.05 0l-32.78 17.28c-9.5-19.77-25.72-19.93-27.9-19.93-22.14 0-33.22 14.61-33.22 43.84 0 23.55 9.23 43.84 33.22 43.84 14.45 0 24.65-7.09 30.54-21.26l31 15.5c-2.1 3.75-21.39 38.98-65.09 38.98-22.69 0-73.96-9.87-73.96-77.05 0-58.67 42.97-77.06 72.63-77.06 30.71-.01 52.58 11.95 65.56 35.86zM247.56 8.05C104.74 8.05 0 123.11 0 256.05c0 138.49 113.6 248 247.56 248 129.93 0 248.44-100.87 248.44-248 0-137.87-106.62-248-248.44-248zm.87 450.81c-112.54 0-203.7-93.04-203.7-202.81 0-105.42 85.43-203.27 203.72-203.27 112.53 0 202.82 89.46 202.82 203.26-.01 121.69-99.68 202.82-202.84 202.82z" } }, "free": ["brands"] }, "creative-commons-by": { "changes": ["5.0.11"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f4e7", "label": "Creative Commons Attribution", "voted": false, "svg": { "brands": { "last_modified": 1660014481, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M314.9 194.4v101.4h-28.3v120.5h-77.1V295.9h-28.3V194.4c0-4.4 1.6-8.2 4.6-11.3 3.1-3.1 6.9-4.7 11.3-4.7H299c4.1 0 7.8 1.6 11.1 4.7 3.1 3.2 4.8 6.9 4.8 11.3zm-101.5-63.7c0-23.3 11.5-35 34.5-35s34.5 11.7 34.5 35c0 23-11.5 34.5-34.5 34.5s-34.5-11.5-34.5-34.5zM247.6 8C389.4 8 496 118.1 496 256c0 147.1-118.5 248-248.4 248C113.6 504 0 394.5 0 256 0 123.1 104.7 8 247.6 8zm.8 44.7C130.2 52.7 44.7 150.6 44.7 256c0 109.8 91.2 202.8 203.7 202.8 103.2 0 202.8-81.1 202.8-202.8.1-113.8-90.2-203.3-202.8-203.3z" } }, "free": ["brands"] }, "creative-commons-nc": { "changes": ["5.0.11"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f4e8", "label": "Creative Commons Noncommercial", "voted": false, "svg": { "brands": { "last_modified": 1660014482, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M247.6 8C387.4 8 496 115.9 496 256c0 147.2-118.5 248-248.4 248C113.1 504 0 393.2 0 256 0 123.1 104.7 8 247.6 8zM55.8 189.1c-7.4 20.4-11.1 42.7-11.1 66.9 0 110.9 92.1 202.4 203.7 202.4 122.4 0 177.2-101.8 178.5-104.1l-93.4-41.6c-7.7 37.1-41.2 53-68.2 55.4v38.1h-28.8V368c-27.5-.3-52.6-10.2-75.3-29.7l34.1-34.5c31.7 29.4 86.4 31.8 86.4-2.2 0-6.2-2.2-11.2-6.6-15.1-14.2-6-1.8-.1-219.3-97.4zM248.4 52.3c-38.4 0-112.4 8.7-170.5 93l94.8 42.5c10-31.3 40.4-42.9 63.8-44.3v-38.1h28.8v38.1c22.7 1.2 43.4 8.9 62 23L295 199.7c-42.7-29.9-83.5-8-70 11.1 53.4 24.1 43.8 19.8 93 41.6l127.1 56.7c4.1-17.4 6.2-35.1 6.2-53.1 0-57-19.8-105-59.3-143.9-39.3-39.9-87.2-59.8-143.6-59.8z" } }, "free": ["brands"] }, "creative-commons-nc-eu": { "changes": ["5.0.11"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f4e9", "label": "Creative Commons Noncommercial (Euro Sign)", "voted": false, "svg": { "brands": { "last_modified": 1660014470, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M247.7 8C103.6 8 0 124.8 0 256c0 136.3 111.7 248 247.7 248C377.9 504 496 403.1 496 256 496 117 388.4 8 247.7 8zm.6 450.7c-112 0-203.6-92.5-203.6-202.7 0-23.2 3.7-45.2 10.9-66l65.7 29.1h-4.7v29.5h23.3c0 6.2-.4 3.2-.4 19.5h-22.8v29.5h27c11.4 67 67.2 101.3 124.6 101.3 26.6 0 50.6-7.9 64.8-15.8l-10-46.1c-8.7 4.6-28.2 10.8-47.3 10.8-28.2 0-58.1-10.9-67.3-50.2h90.3l128.3 56.8c-1.5 2.1-56.2 104.3-178.8 104.3zm-16.7-190.6l-.5-.4.9.4h-.4zm77.2-19.5h3.7v-29.5h-70.3l-28.6-12.6c2.5-5.5 5.4-10.5 8.8-14.3 12.9-15.8 31.1-22.4 51.1-22.4 18.3 0 35.3 5.4 46.1 10l11.6-47.3c-15-6.6-37-12.4-62.3-12.4-39 0-72.2 15.8-95.9 42.3-5.3 6.1-9.8 12.9-13.9 20.1l-81.6-36.1c64.6-96.8 157.7-93.6 170.7-93.6 113 0 203 90.2 203 203.4 0 18.7-2.1 36.3-6.3 52.9l-136.1-60.5z" } }, "free": ["brands"] }, "creative-commons-nc-jp": { "changes": ["5.0.11"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f4ea", "label": "Creative Commons Noncommercial (Yen Sign)", "voted": false, "svg": { "brands": { "last_modified": 1660014462, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M247.7 8C103.6 8 0 124.8 0 256c0 136.4 111.8 248 247.7 248C377.9 504 496 403.2 496 256 496 117.2 388.5 8 247.7 8zm.6 450.7c-112 0-203.6-92.5-203.6-202.7 0-21.1 3-41.2 9-60.3l127 56.5h-27.9v38.6h58.1l5.7 11.8v18.7h-63.8V360h63.8v56h61.7v-56h64.2v-35.7l81 36.1c-1.5 2.2-57.1 98.3-175.2 98.3zm87.6-137.3h-57.6v-18.7l2.9-5.6 54.7 24.3zm6.5-51.4v-17.8h-38.6l63-116H301l-43.4 96-23-10.2-39.6-85.7h-65.8l27.3 51-81.9-36.5c27.8-44.1 82.6-98.1 173.7-98.1 112.8 0 203 90 203 203.4 0 21-2.7 40.6-7.9 59l-101-45.1z" } }, "free": ["brands"] }, "creative-commons-nd": { "changes": ["5.0.11"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f4eb", "label": "Creative Commons No Derivative Works", "voted": false, "svg": { "brands": { "last_modified": 1660014467, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M247.6 8C389.4 8 496 118.1 496 256c0 147.1-118.5 248-248.4 248C113.6 504 0 394.5 0 256 0 123.1 104.7 8 247.6 8zm.8 44.7C130.2 52.7 44.7 150.6 44.7 256c0 109.8 91.2 202.8 203.7 202.8 103.2 0 202.8-81.1 202.8-202.8.1-113.8-90.2-203.3-202.8-203.3zm94 144.3v42.5H162.1V197h180.3zm0 79.8v42.5H162.1v-42.5h180.3z" } }, "free": ["brands"] }, "creative-commons-pd": { "changes": ["5.0.11"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f4ec", "label": "Creative Commons Public Domain", "voted": false, "svg": { "brands": { "last_modified": 1660014471, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M248 8C111 8 0 119.1 0 256c0 137 111 248 248 248s248-111 248-248C496 119.1 385 8 248 8zm0 449.5c-139.2 0-235.8-138-190.2-267.9l78.8 35.1c-2.1 10.5-3.3 21.5-3.3 32.9 0 99 73.9 126.9 120.4 126.9 22.9 0 53.5-6.7 79.4-29.5L297 311.1c-5.5 6.3-17.6 16.7-36.3 16.7-37.8 0-53.7-39.9-53.9-71.9 230.4 102.6 216.5 96.5 217.9 96.8-34.3 62.4-100.6 104.8-176.7 104.8zm194.2-150l-224-100c18.8-34 54.9-30.7 74.7-11l40.4-41.6c-27.1-23.3-58-27.5-78.1-27.5-47.4 0-80.9 20.5-100.7 51.6l-74.9-33.4c36.1-54.9 98.1-91.2 168.5-91.2 111.1 0 201.5 90.4 201.5 201.5 0 18-2.4 35.4-6.8 52-.3-.1-.4-.2-.6-.4z" } }, "free": ["brands"] }, "creative-commons-pd-alt": { "changes": ["5.0.11"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f4ed", "label": "Alternate Creative Commons Public Domain", "voted": false, "svg": { "brands": { "last_modified": 1660014481, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M247.6 8C104.7 8 0 123.1 0 256c0 138.5 113.6 248 247.6 248C377.5 504 496 403.1 496 256 496 118.1 389.4 8 247.6 8zm.8 450.8c-112.5 0-203.7-93-203.7-202.8 0-105.4 85.5-203.3 203.7-203.3 112.6 0 202.9 89.5 202.8 203.3 0 121.7-99.6 202.8-202.8 202.8zM316.7 186h-53.2v137.2h53.2c21.4 0 70-5.1 70-68.6 0-63.4-48.6-68.6-70-68.6zm.8 108.5h-19.9v-79.7l19.4-.1c3.8 0 35-2.1 35 39.9 0 24.6-10.5 39.9-34.5 39.9zM203.7 186h-68.2v137.3h34.6V279h27c54.1 0 57.1-37.5 57.1-46.5 0-31-16.8-46.5-50.5-46.5zm-4.9 67.3h-29.2v-41.6h28.3c30.9 0 28.8 41.6.9 41.6z" } }, "free": ["brands"] }, "creative-commons-remix": { "changes": ["5.0.11"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f4ee", "label": "Creative Commons Remix", "voted": false, "svg": { "brands": { "last_modified": 1660014466, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M247.6 8C389.4 8 496 118.1 496 256c0 147.1-118.5 248-248.4 248C113.6 504 0 394.5 0 256 0 123.1 104.7 8 247.6 8zm.8 44.7C130.2 52.7 44.7 150.6 44.7 256c0 109.8 91.2 202.8 203.7 202.8 103.2 0 202.8-81.1 202.8-202.8.1-113.8-90.2-203.3-202.8-203.3zm161.7 207.7l4.9 2.2v70c-7.2 3.6-63.4 27.5-67.3 28.8-6.5-1.8-113.7-46.8-137.3-56.2l-64.2 26.6-63.3-27.5v-63.8l59.3-24.8c-.7-.7-.4 5-.4-70.4l67.3-29.7L361 178.5v61.6l49.1 20.3zm-70.4 81.5v-43.8h-.4v-1.8l-113.8-46.5V295l113.8 46.9v-.4l.4.4zm7.5-57.6l39.9-16.4-36.8-15.5-39 16.4 35.9 15.5zm52.3 38.1v-43L355.2 298v43.4l44.3-19z" } }, "free": ["brands"] }, "creative-commons-sa": { "changes": ["5.0.11"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f4ef", "label": "Creative Commons Share Alike", "voted": false, "svg": { "brands": { "last_modified": 1660014479, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M247.6 8C389.4 8 496 118.1 496 256c0 147.1-118.5 248-248.4 248C113.6 504 0 394.5 0 256 0 123.1 104.7 8 247.6 8zm.8 44.7C130.2 52.7 44.7 150.6 44.7 256c0 109.8 91.2 202.8 203.7 202.8 103.2 0 202.8-81.1 202.8-202.8.1-113.8-90.2-203.3-202.8-203.3zM137.7 221c13-83.9 80.5-95.7 108.9-95.7 99.8 0 127.5 82.5 127.5 134.2 0 63.6-41 132.9-128.9 132.9-38.9 0-99.1-20-109.4-97h62.5c1.5 30.1 19.6 45.2 54.5 45.2 23.3 0 58-18.2 58-82.8 0-82.5-49.1-80.6-56.7-80.6-33.1 0-51.7 14.6-55.8 43.8h18.2l-49.2 49.2-49-49.2h19.4z" } }, "free": ["brands"] }, "creative-commons-sampling": { "changes": ["5.0.11"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f4f0", "label": "Creative Commons Sampling", "voted": false, "svg": { "brands": { "last_modified": 1660014479, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M247.6 8C389.4 8 496 118.1 496 256c0 147.1-118.5 248-248.4 248C113.6 504 0 394.5 0 256 0 123.1 104.7 8 247.6 8zm.8 44.7C130.2 52.7 44.7 150.6 44.7 256c0 109.8 91.2 202.8 203.7 202.8 103.2 0 202.8-81.1 202.8-202.8.1-113.8-90.2-203.3-202.8-203.3zm3.6 53.2c2.8-.3 11.5 1 11.5 11.5l6.6 107.2 4.9-59.3c0-6 4.7-10.6 10.6-10.6 5.9 0 10.6 4.7 10.6 10.6 0 2.5-.5-5.7 5.7 81.5l5.8-64.2c.3-2.9 2.9-9.3 10.2-9.3 3.8 0 9.9 2.3 10.6 8.9l11.5 96.5 5.3-12.8c1.8-4.4 5.2-6.6 10.2-6.6h58v21.3h-50.9l-18.2 44.3c-3.9 9.9-19.5 9.1-20.8-3.1l-4-31.9-7.5 92.6c-.3 3-3 9.3-10.2 9.3-3 0-9.8-2.1-10.6-9.3 0-1.9.6 5.8-6.2-77.9l-5.3 72.2c-1.1 4.8-4.8 9.3-10.6 9.3-2.9 0-9.8-2-10.6-9.3 0-1.9.5 6.7-5.8-87.7l-5.8 94.8c0 6.3-3.6 12.4-10.6 12.4-5.2 0-10.6-4.1-10.6-12l-5.8-87.7c-5.8 92.5-5.3 84-5.3 85.9-1.1 4.8-4.8 9.3-10.6 9.3-3 0-9.8-2.1-10.6-9.3 0-.7-.4-1.1-.4-2.6l-6.2-88.6L182 348c-.7 6.5-6.7 9.3-10.6 9.3-5.8 0-9.6-4.1-10.6-8.9L149.7 272c-2 4-3.5 8.4-11.1 8.4H87.2v-21.3H132l13.7-27.9c4.4-9.9 18.2-7.2 19.9 2.7l3.1 20.4 8.4-97.9c0-6 4.8-10.6 10.6-10.6.5 0 10.6-.2 10.6 12.4l4.9 69.1 6.6-92.6c0-10.1 9.5-10.6 10.2-10.6.6 0 10.6.7 10.6 10.6l5.3 80.6 6.2-97.9c.1-1.1-.6-10.3 9.9-11.5z" } }, "free": ["brands"] }, "creative-commons-sampling-plus": { "changes": ["5.0.11"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f4f1", "label": "Creative Commons Sampling +", "voted": false, "svg": { "brands": { "last_modified": 1660014459, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M247.6 8C389.4 8 496 118.1 496 256c0 147.1-118.5 248-248.4 248C113.6 504 0 394.5 0 256 0 123.1 104.7 8 247.6 8zm.8 44.7C130.2 52.7 44.7 150.6 44.7 256c0 109.8 91.2 202.8 203.7 202.8 103.2 0 202.8-81.1 202.8-202.8.1-113.8-90.2-203.3-202.8-203.3zm107 205.6c-4.7 0-9 2.8-10.7 7.2l-4 9.5-11-92.8c-1.7-13.9-22-13.4-23.1.4l-4.3 51.4-5.2-68.8c-1.1-14.3-22.1-14.2-23.2 0l-3.5 44.9-5.9-94.3c-.9-14.5-22.3-14.4-23.2 0l-5.1 83.7-4.3-66.3c-.9-14.4-22.2-14.4-23.2 0l-5.3 80.2-4.1-57c-1.1-14.3-22-14.3-23.2-.2l-7.7 89.8-1.8-12.2c-1.7-11.4-17.1-13.6-22-3.3l-13.2 27.7H87.5v23.2h51.3c4.4 0 8.4-2.5 10.4-6.4l10.7 73.1c2 13.5 21.9 13 23.1-.7l3.8-43.6 5.7 78.3c1.1 14.4 22.3 14.2 23.2-.1l4.6-70.4 4.8 73.3c.9 14.4 22.3 14.4 23.2-.1l4.9-80.5 4.5 71.8c.9 14.3 22.1 14.5 23.2.2l4.6-58.6 4.9 64.4c1.1 14.3 22 14.2 23.1.1l6.8-83 2.7 22.3c1.4 11.8 17.7 14.1 22.3 3.1l18-43.4h50.5V258l-58.4.3zm-78 5.2h-21.9v21.9c0 4.1-3.3 7.5-7.5 7.5-4.1 0-7.5-3.3-7.5-7.5v-21.9h-21.9c-4.1 0-7.5-3.3-7.5-7.5 0-4.1 3.4-7.5 7.5-7.5h21.9v-21.9c0-4.1 3.4-7.5 7.5-7.5s7.5 3.3 7.5 7.5v21.9h21.9c4.1 0 7.5 3.3 7.5 7.5 0 4.1-3.4 7.5-7.5 7.5z" } }, "free": ["brands"] }, "creative-commons-share": { "changes": ["5.0.11"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f4f2", "label": "Creative Commons Share", "voted": false, "svg": { "brands": { "last_modified": 1660014472, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M247.6 8C389.4 8 496 118.1 496 256c0 147.1-118.5 248-248.4 248C113.6 504 0 394.5 0 256 0 123.1 104.7 8 247.6 8zm.8 44.7C130.2 52.7 44.7 150.6 44.7 256c0 109.8 91.2 202.8 203.7 202.8 103.2 0 202.8-81.1 202.8-202.8.1-113.8-90.2-203.3-202.8-203.3zm101 132.4c7.8 0 13.7 6.1 13.7 13.7v182.5c0 7.7-6.1 13.7-13.7 13.7H214.3c-7.7 0-13.7-6-13.7-13.7v-54h-54c-7.8 0-13.7-6-13.7-13.7V131.1c0-8.2 6.6-12.7 12.4-13.7h136.4c7.7 0 13.7 6 13.7 13.7v54h54zM159.9 300.3h40.7V198.9c0-7.4 5.8-12.6 12-13.7h55.8v-40.3H159.9v155.4zm176.2-88.1H227.6v155.4h108.5V212.2z" } }, "free": ["brands"] }, "creative-commons-zero": { "changes": ["5.0.11", "5.4.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f4f3", "label": "Creative Commons CC0", "voted": false, "svg": { "brands": { "last_modified": 1660014475, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M247.6 8C389.4 8 496 118.1 496 256c0 147.1-118.5 248-248.4 248C113.6 504 0 394.5 0 256 0 123.1 104.7 8 247.6 8zm.8 44.7C130.2 52.7 44.7 150.6 44.7 256c0 109.8 91.2 202.8 203.7 202.8 103.2 0 202.8-81.1 202.8-202.8.1-113.8-90.2-203.3-202.8-203.3zm-.4 60.5c-81.9 0-102.5 77.3-102.5 142.8 0 65.5 20.6 142.8 102.5 142.8S350.5 321.5 350.5 256c0-65.5-20.6-142.8-102.5-142.8zm0 53.9c3.3 0 6.4.5 9.2 1.2 5.9 5.1 8.8 12.1 3.1 21.9l-54.5 100.2c-1.7-12.7-1.9-25.1-1.9-34.4 0-28.8 2-88.9 44.1-88.9zm40.8 46.2c2.9 15.4 3.3 31.4 3.3 42.7 0 28.9-2 88.9-44.1 88.9-13.5 0-32.6-7.7-20.1-26.4l60.9-105.2z" } }, "free": ["brands"] }, "credit-card": { "aliases": { "names": ["credit-card-alt"], "unicodes": { "composite": ["1f4b3", "f283"], "secondary": ["10f09d"] } }, "changes": [ "2.0.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "buy", "card", "checkout", "credit", "credit card", "credit-card-alt", "debit", "money", "payment", "purchase" ] }, "styles": ["solid", "regular"], "unicode": "f09d", "label": "Credit Card", "voted": false, "svg": { "solid": { "last_modified": 1684766475, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M64 32C28.7 32 0 60.7 0 96v32H576V96c0-35.3-28.7-64-64-64H64zM576 224H0V416c0 35.3 28.7 64 64 64H512c35.3 0 64-28.7 64-64V224zM112 352h64c8.8 0 16 7.2 16 16s-7.2 16-16 16H112c-8.8 0-16-7.2-16-16s7.2-16 16-16zm112 16c0-8.8 7.2-16 16-16H368c8.8 0 16 7.2 16 16s-7.2 16-16 16H240c-8.8 0-16-7.2-16-16z" }, "regular": { "last_modified": 1684766475, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M512 80c8.8 0 16 7.2 16 16v32H48V96c0-8.8 7.2-16 16-16H512zm16 144V416c0 8.8-7.2 16-16 16H64c-8.8 0-16-7.2-16-16V224H528zM64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H512c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zm56 304c-13.3 0-24 10.7-24 24s10.7 24 24 24h48c13.3 0 24-10.7 24-24s-10.7-24-24-24H120zm128 0c-13.3 0-24 10.7-24 24s10.7 24 24 24H360c13.3 0 24-10.7 24-24s-10.7-24-24-24H248z" } }, "free": ["regular", "solid"] }, "critical-role": { "changes": ["5.4.0", "5.8.0"], "ligatures": [], "search": { "terms": [ "Dungeons & Dragons", "d&d", "dnd", "fantasy", "game", "gaming", "tabletop" ] }, "styles": ["brands"], "unicode": "f6c9", "label": "Critical Role", "voted": false, "svg": { "brands": { "last_modified": 1660014459, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M225.82 0c.26.15 216.57 124.51 217.12 124.72 3 1.18 3.7 3.46 3.7 6.56q-.11 125.17 0 250.36a5.88 5.88 0 0 1-3.38 5.78c-21.37 12-207.86 118.29-218.93 124.58h-3C142 466.34 3.08 386.56 2.93 386.48a3.29 3.29 0 0 1-1.88-3.24c0-.87 0-225.94-.05-253.1a5 5 0 0 1 2.93-4.93C27.19 112.11 213.2 6 224.07 0zM215.4 20.42l-.22-.16Q118.06 75.55 21 130.87c0 .12.08.23.13.35l30.86 11.64c-7.71 6-8.32 6-10.65 5.13-.1 0-24.17-9.28-26.8-10v230.43c.88-1.41 64.07-110.91 64.13-111 1.62-2.82 3-1.92 9.12-1.52 1.4.09 1.48.22.78 1.42-41.19 71.33-36.4 63-67.48 116.94-.81 1.4-.61 1.13 1.25 1.13h186.5c1.44 0 1.69-.23 1.7-1.64v-8.88c0-1.34 2.36-.81-18.37-1-7.46-.07-14.14-3.22-21.38-12.7-7.38-9.66-14.62-19.43-21.85-29.21-2.28-3.08-3.45-2.38-16.76-2.38-1.75 0-1.78 0-1.76 1.82.29 26.21.15 25.27 1 32.66.52 4.37 2.16 4.2 9.69 4.81 3.14.26 3.88 4.08.52 4.92-1.57.39-31.6.51-33.67-.1a2.42 2.42 0 0 1 .3-4.73c3.29-.76 6.16.81 6.66-4.44 1.3-13.66 1.17-9 1.1-79.42 0-10.82-.35-12.58-5.36-13.55-1.22-.24-3.54-.16-4.69-.55-2.88-1-2-4.84 1.77-4.85 33.67 0 46.08-1.07 56.06 4.86 7.74 4.61 12 11.48 12.51 20.4.88 14.59-6.51 22.35-15 32.59a1.46 1.46 0 0 0 0 2.22c2.6 3.25 5 6.63 7.71 9.83 27.56 33.23 24.11 30.54 41.28 33.06.89.13 1-.42 1-1.15v-11c0-1 .32-1.43 1.41-1.26a72.37 72.37 0 0 0 23.58-.3c1.08-.15 1.5.2 1.48 1.33 0 .11.88 26.69.87 26.8-.05 1.52.67 1.62 1.89 1.62h186.71Q386.51 304.6 346 234.33c2.26-.66-.4 0 6.69-1.39 2-.39 2.05-.41 3.11 1.44 7.31 12.64 77.31 134 77.37 134.06V138c-1.72.5-103.3 38.72-105.76 39.68-1.08.42-1.55.2-1.91-.88-.63-1.9-1.34-3.76-2.09-5.62-.32-.79-.09-1.13.65-1.39.1 0 95.53-35.85 103-38.77-65.42-37.57-130.56-75-196-112.6l86.82 150.39-.28.33c-9.57-.9-10.46-1.6-11.8-3.94-1-1.69-73.5-127.71-82-142.16-9.1 14.67-83.56 146.21-85.37 146.32-2.93.17-5.88.08-9.25.08q43.25-74.74 86.18-149zm51.93 129.92a37.68 37.68 0 0 0 5.54-.85c1.69-.3 2.53.2 2.6 1.92 0 .11.07 19.06-.86 20.45s-1.88 1.22-2.6-.19c-5-9.69 6.22-9.66-39.12-12-.7 0-1 .23-1 .93 0 .13 3.72 122 3.73 122.11 0 .89.52 1.2 1.21 1.51a83.92 83.92 0 0 1 8.7 4.05c7.31 4.33 11.38 10.84 12.41 19.31 1.44 11.8-2.77 35.77-32.21 37.14-2.75.13-28.26 1.08-34.14-23.25-4.66-19.26 8.26-32.7 19.89-36.4a2.45 2.45 0 0 0 2-2.66c.1-5.63 3-107.1 3.71-121.35.05-1.08-.62-1.16-1.35-1.15-32.35.52-36.75-.34-40.22 8.52-2.42 6.18-4.14 1.32-3.95.23q1.59-9 3.31-18c.4-2.11 1.43-2.61 3.43-1.86 5.59 2.11 6.72 1.7 37.25 1.92 1.73 0 1.78-.08 1.82-1.85.68-27.49.58-22.59 1-29.55a2.69 2.69 0 0 0-1.63-2.8c-5.6-2.91-8.75-7.55-8.9-13.87-.35-14.81 17.72-21.67 27.38-11.51 6.84 7.19 5.8 18.91-2.45 24.15a4.35 4.35 0 0 0-2.22 4.34c0 .59-.11-4.31 1 30.05 0 .9.43 1.12 1.24 1.11.1 0 23-.09 34.47-.37zM68.27 141.7c19.84-4.51 32.68-.56 52.49 1.69 2.76.31 3.74 1.22 3.62 4-.21 5-1.16 22.33-1.24 23.15a2.65 2.65 0 0 1-1.63 2.34c-4.06 1.7-3.61-4.45-4-7.29-3.13-22.43-73.87-32.7-74.63 25.4-.31 23.92 17 53.63 54.08 50.88 27.24-2 19-20.19 24.84-20.47a2.72 2.72 0 0 1 3 3.36c-1.83 10.85-3.42 18.95-3.45 19.15-1.54 9.17-86.7 22.09-93.35-42.06-2.71-25.85 10.44-53.37 40.27-60.15zm80 87.67h-19.49a2.57 2.57 0 0 1-2.66-1.79c2.38-3.75 5.89.92 5.86-6.14-.08-25.75.21-38 .23-40.1 0-3.42-.53-4.65-3.32-4.94-7-.72-3.11-3.37-1.11-3.38 11.84-.1 22.62-.18 30.05.72 8.77 1.07 16.71 12.63 7.93 22.62-2 2.25-4 4.42-6.14 6.73.95 1.15 6.9 8.82 17.28 19.68 2.66 2.78 6.15 3.51 9.88 3.13a2.21 2.21 0 0 0 2.23-2.12c.3-3.42.26 4.73.45-40.58 0-5.65-.34-6.58-3.23-6.83-3.95-.35-4-2.26-.69-3.37l19.09-.09c.32 0 4.49.53 1 3.38 0 .05-.16 0-.24 0-3.61.26-3.94 1-4 4.62-.27 43.93.07 40.23.41 42.82.11.84.27 2.23 5.1 2.14 2.49 0 3.86 3.37 0 3.4-10.37.08-20.74 0-31.11.07-10.67 0-13.47-6.2-24.21-20.82-1.6-2.18-8.31-2.36-8.2-.37.88 16.47 0 17.78 4 17.67 4.75-.1 4.73 3.57.83 3.55zm275-10.15c-1.21 7.13.17 10.38-5.3 10.34-61.55-.42-47.82-.22-50.72-.31a18.4 18.4 0 0 1-3.63-.73c-2.53-.6 1.48-1.23-.38-5.6-1.43-3.37-2.78-6.78-4.11-10.19a1.94 1.94 0 0 0-2-1.44 138 138 0 0 0-14.58.07 2.23 2.23 0 0 0-1.62 1.06c-1.58 3.62-3.07 7.29-4.51 11-1.27 3.23 7.86 1.32 12.19 2.16 3 .57 4.53 3.72.66 3.73H322.9c-2.92 0-3.09-3.15-.74-3.21a6.3 6.3 0 0 0 5.92-3.47c1.5-3 2.8-6 4.11-9.09 18.18-42.14 17.06-40.17 18.42-41.61a1.83 1.83 0 0 1 3 0c2.93 3.34 18.4 44.71 23.62 51.92 2 2.7 5.74 2 6.36 2 3.61.13 4-1.11 4.13-4.29.09-1.87.08 1.17.07-41.24 0-4.46-2.36-3.74-5.55-4.27-.26 0-2.56-.63-.08-3.06.21-.2-.89-.24 21.7-.15 2.32 0 5.32 2.75-1.21 3.45a2.56 2.56 0 0 0-2.66 2.83c-.07 1.63-.19 38.89.29 41.21a3.06 3.06 0 0 0 3.23 2.43c13.25.43 14.92.44 16-3.41 1.67-5.78 4.13-2.52 3.73-.19zm-104.72 64.37c-4.24 0-4.42-3.39-.61-3.41 35.91-.16 28.11.38 37.19-.65 1.68-.19 2.38.24 2.25 1.89-.26 3.39-.64 6.78-1 10.16-.25 2.16-3.2 2.61-3.4-.15-.38-5.31-2.15-4.45-15.63-5.08-1.58-.07-1.64 0-1.64 1.52V304c0 1.65 0 1.6 1.62 1.47 3.12-.25 10.31.34 15.69-1.52.47-.16 3.3-1.79 3.07 1.76 0 .21-.76 10.35-1.18 11.39-.53 1.29-1.88 1.51-2.58.32-1.17-2 0-5.08-3.71-5.3-15.42-.9-12.91-2.55-12.91 6 0 12.25-.76 16.11 3.89 16.24 16.64.48 14.4 0 16.43-5.71.84-2.37 3.5-1.77 3.18.58-.44 3.21-.85 6.43-1.23 9.64 0 .36-.16 2.4-4.66 2.39-37.16-.08-34.54-.19-35.21-.31-2.72-.51-2.2-3 .22-3.45 1.1-.19 4 .54 4.16-2.56 2.44-56.22-.07-51.34-3.91-51.33zm-.41-109.52c2.46.61 3.13 1.76 2.95 4.65-.33 5.3-.34 9-.55 9.69-.66 2.23-3.15 2.12-3.34-.27-.38-4.81-3.05-7.82-7.57-9.15-26.28-7.73-32.81 15.46-27.17 30.22 5.88 15.41 22 15.92 28.86 13.78 5.92-1.85 5.88-6.5 6.91-7.58 1.23-1.3 2.25-1.84 3.12 1.1 0 .1.57 11.89-6 12.75-1.6.21-19.38 3.69-32.68-3.39-21-11.19-16.74-35.47-6.88-45.33 14-14.06 39.91-7.06 42.32-6.47zM289.8 280.14c3.28 0 3.66 3 .16 3.43-2.61.32-5-.42-5 5.46 0 2-.19 29.05.4 41.45.11 2.29 1.15 3.52 3.44 3.65 22 1.21 14.95-1.65 18.79-6.34 1.83-2.24 2.76.84 2.76 1.08.35 13.62-4 12.39-5.19 12.4l-38.16-.19c-1.93-.23-2.06-3-.42-3.38 2-.48 4.94.4 5.13-2.8 1-15.87.57-44.65.34-47.81-.27-3.77-2.8-3.27-5.68-3.71-2.47-.38-2-3.22.34-3.22 1.45-.02 17.97-.03 23.09-.02zm-31.63-57.79c.07 4.08 2.86 3.46 6 3.58 2.61.1 2.53 3.41-.07 3.43-6.48 0-13.7 0-21.61-.06-3.84 0-3.38-3.35 0-3.37 4.49 0 3.24 1.61 3.41-45.54 0-5.08-3.27-3.54-4.72-4.23-2.58-1.23-1.36-3.09.41-3.15 1.29 0 20.19-.41 21.17.21s1.87 1.65-.42 2.86c-1 .52-3.86-.28-4.15 2.47 0 .21-.82 1.63-.07 43.8zm-36.91 274.27a2.93 2.93 0 0 0 3.26 0c17-9.79 182-103.57 197.42-112.51-.14-.43 11.26-.18-181.52-.27-1.22 0-1.57.37-1.53 1.56 0 .1 1.25 44.51 1.22 50.38a28.33 28.33 0 0 1-1.36 7.71c-.55 1.83.38-.5-13.5 32.23-.73 1.72-1 2.21-2-.08-4.19-10.34-8.28-20.72-12.57-31a23.6 23.6 0 0 1-2-10.79c.16-2.46.8-16.12 1.51-48 0-1.95 0-2-2-2h-183c2.58 1.63 178.32 102.57 196 112.76zm-90.9-188.75c0 2.4.36 2.79 2.76 3 11.54 1.17 21 3.74 25.64-7.32 6-14.46 2.66-34.41-12.48-38.84-2-.59-16-2.76-15.94 1.51.05 8.04.01 11.61.02 41.65zm105.75-15.05c0 2.13 1.07 38.68 1.09 39.13.34 9.94-25.58 5.77-25.23-2.59.08-2 1.37-37.42 1.1-39.43-14.1 7.44-14.42 40.21 6.44 48.8a17.9 17.9 0 0 0 22.39-7.07c4.91-7.76 6.84-29.47-5.43-39a2.53 2.53 0 0 1-.36.12zm-12.28-198c-9.83 0-9.73 14.75-.07 14.87s10.1-14.88.07-14.91zm-80.15 103.83c0 1.8.41 2.4 2.17 2.58 13.62 1.39 12.51-11 12.16-13.36-1.69-11.22-14.38-10.2-14.35-7.81.05 4.5-.03 13.68.02 18.59zm212.32 6.4l-6.1-15.84c-2.16 5.48-4.16 10.57-6.23 15.84z" } }, "free": ["brands"] }, "crop": { "aliases": { "unicodes": { "secondary": ["10f125"] } }, "changes": [ "3.1.0", "5.0.0", "5.1.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["design", "frame", "mask", "resize", "shrink"] }, "styles": ["solid"], "unicode": "f125", "label": "Crop", "voted": false, "svg": { "solid": { "last_modified": 1684767368, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M448 109.3l54.6-54.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L402.7 64 160 64v64l178.7 0L128 338.7V32c0-17.7-14.3-32-32-32S64 14.3 64 32V64H32C14.3 64 0 78.3 0 96s14.3 32 32 32H64V384c0 35.3 28.7 64 64 64H352V384H173.3L384 173.3 384 480c0 17.7 14.3 32 32 32s32-14.3 32-32V448h32c17.7 0 32-14.3 32-32s-14.3-32-32-32H448l0-274.7z" } }, "free": ["solid"] }, "crop-simple": { "aliases": { "names": ["crop-alt"], "unicodes": { "secondary": ["10f565"] } }, "changes": ["5.1.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["design", "frame", "mask", "resize", "shrink"] }, "styles": ["solid"], "unicode": "f565", "label": "Crop Simple", "voted": false, "svg": { "solid": { "last_modified": 1684767367, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M128 32c0-17.7-14.3-32-32-32S64 14.3 64 32V64H32C14.3 64 0 78.3 0 96s14.3 32 32 32H64V384c0 35.3 28.7 64 64 64H352V384H128V32zM384 480c0 17.7 14.3 32 32 32s32-14.3 32-32V448h32c17.7 0 32-14.3 32-32s-14.3-32-32-32H448l0-256c0-35.3-28.7-64-64-64L160 64v64l224 0 0 352z" } }, "free": ["solid"] }, "cross": { "aliases": { "unicodes": { "composite": ["1f547", "271d"], "secondary": ["10f654"] } }, "changes": ["5.3.0", "5.10.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "Christian", "Heavy Latin Cross", "catholicism", "christianity", "church", "cross", "jesus", "latin cross", "religion" ] }, "styles": ["solid"], "unicode": "f654", "label": "Cross", "voted": false, "svg": { "solid": { "last_modified": 1684767603, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M176 0c-26.5 0-48 21.5-48 48v80H48c-26.5 0-48 21.5-48 48v32c0 26.5 21.5 48 48 48h80V464c0 26.5 21.5 48 48 48h32c26.5 0 48-21.5 48-48V256h80c26.5 0 48-21.5 48-48V176c0-26.5-21.5-48-48-48H256V48c0-26.5-21.5-48-48-48H176z" } }, "free": ["solid"] }, "crosshairs": { "aliases": { "unicodes": { "secondary": ["10f05b"] } }, "changes": [ "1.0.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["aim", "bullseye", "gpd", "picker", "position"] }, "styles": ["solid"], "unicode": "f05b", "label": "Crosshairs", "voted": false, "svg": { "solid": { "last_modified": 1684767489, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 0c17.7 0 32 14.3 32 32V42.4c93.7 13.9 167.7 88 181.6 181.6H480c17.7 0 32 14.3 32 32s-14.3 32-32 32H469.6c-13.9 93.7-88 167.7-181.6 181.6V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V469.6C130.3 455.7 56.3 381.7 42.4 288H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H42.4C56.3 130.3 130.3 56.3 224 42.4V32c0-17.7 14.3-32 32-32zM107.4 288c12.5 58.3 58.4 104.1 116.6 116.6V384c0-17.7 14.3-32 32-32s32 14.3 32 32v20.6c58.3-12.5 104.1-58.4 116.6-116.6H384c-17.7 0-32-14.3-32-32s14.3-32 32-32h20.6C392.1 165.7 346.3 119.9 288 107.4V128c0 17.7-14.3 32-32 32s-32-14.3-32-32V107.4C165.7 119.9 119.9 165.7 107.4 224H128c17.7 0 32 14.3 32 32s-14.3 32-32 32H107.4zM256 224a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" } }, "free": ["solid"] }, "crow": { "aliases": { "unicodes": { "secondary": ["10f520"] } }, "changes": [ "5.0.13", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["bird", "bullfrog", "fauna", "halloween", "holiday", "toad"] }, "styles": ["solid"], "unicode": "f520", "label": "Crow", "voted": false, "svg": { "solid": { "last_modified": 1684768131, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M456 0c-48.6 0-88 39.4-88 88v29.2L12.5 390.6c-14 10.8-16.6 30.9-5.9 44.9s30.9 16.6 44.9 5.9L126.1 384H259.2l46.6 113.1c5 12.3 19.1 18.1 31.3 13.1s18.1-19.1 13.1-31.3L311.1 384H352c1.1 0 2.1 0 3.2 0l46.6 113.2c5 12.3 19.1 18.1 31.3 13.1s18.1-19.1 13.1-31.3l-42-102C484.9 354.1 544 280 544 192V128v-8l80.5-20.1c8.6-2.1 13.8-10.8 11.6-19.4C629 52 603.4 32 574 32H523.9C507.7 12.5 483.3 0 456 0zm0 64a24 24 0 1 1 0 48 24 24 0 1 1 0-48z" } }, "free": ["solid"] }, "crown": { "aliases": { "unicodes": { "composite": ["1f451"], "secondary": ["10f521"] } }, "changes": ["5.0.13", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "award", "clothing", "crown", "favorite", "king", "queen", "royal", "tiara" ] }, "styles": ["solid"], "unicode": "f521", "label": "Crown", "voted": true, "svg": { "solid": { "last_modified": 1684767603, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M309 106c11.4-7 19-19.7 19-34c0-22.1-17.9-40-40-40s-40 17.9-40 40c0 14.4 7.6 27 19 34L209.7 220.6c-9.1 18.2-32.7 23.4-48.6 10.7L72 160c5-6.7 8-15 8-24c0-22.1-17.9-40-40-40S0 113.9 0 136s17.9 40 40 40c.2 0 .5 0 .7 0L86.4 427.4c5.5 30.4 32 52.6 63 52.6H426.6c30.9 0 57.4-22.1 63-52.6L535.3 176c.2 0 .5 0 .7 0c22.1 0 40-17.9 40-40s-17.9-40-40-40s-40 17.9-40 40c0 9 3 17.3 8 24l-89.1 71.3c-15.9 12.7-39.5 7.5-48.6-10.7L309 106z" } }, "free": ["solid"] }, "crutch": { "aliases": { "unicodes": { "secondary": ["10f7f7"] } }, "changes": ["5.7.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["cane", "injury", "mobility", "wheelchair"] }, "styles": ["solid"], "unicode": "f7f7", "label": "Crutch", "voted": false, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M297.4 9.4c-12.5 12.5-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3l-160-160c-12.5-12.5-32.8-12.5-45.3 0zm-96 144l-34.8 34.8c-12.9 12.9-21.9 29.2-25.8 47.1L116.8 342.9c-1.3 5.9-4.3 11.4-8.6 15.7L9.4 457.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l98.8-98.8c4.3-4.3 9.7-7.3 15.7-8.6l107.6-23.9c17.8-4 34.1-12.9 47.1-25.8l34.7-34.7c0 0 .1-.1 .1-.1s.1-.1 .1-.1l74.6-74.6-45.3-45.3L336 242.7 269.3 176l52.1-52.1L276.1 78.6l-74.7 74.7zM224 221.3L290.7 288l-12.2 12.2c-4.3 4.3-9.7 7.3-15.7 8.6l-76.7 17 17-76.7c1.3-5.9 4.3-11.4 8.6-15.7L224 221.3z" } }, "free": ["solid"] }, "cruzeiro-sign": { "changes": ["6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Cruzeiro Sign", "currency"] }, "styles": ["solid"], "unicode": "e152", "label": "Cruzeiro Sign", "voted": false, "svg": { "solid": { "last_modified": 1684766476, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M96 256c0-88.4 71.6-160 160-160c41 0 78.3 15.4 106.7 40.7c13.2 11.8 33.4 10.7 45.2-2.5s10.7-33.4-2.5-45.2c-39.6-35.5-92-57-149.3-57C132.3 32 32 132.3 32 256s100.3 224 224 224c57.4 0 109.7-21.6 149.3-57c13.2-11.8 14.3-32 2.5-45.2s-32-14.3-45.2-2.5C334.3 400.6 297 416 256 416V320v-8.7c0-12.8 10.4-23.3 23.3-23.3c4.6 0 9.1 1.4 12.9 3.9l10.1 6.7c14.7 9.8 34.6 5.8 44.4-8.9s5.8-34.6-8.9-44.4l-10.1-6.7c-14.3-9.6-31.2-14.7-48.4-14.7c-12.4 0-24.2 2.6-34.9 7.3c-5.5-4.5-12.6-7.3-20.3-7.3c-17.7 0-32 14.3-32 32v55.3V320v82.7C135.5 378 96 321.6 96 256z" } }, "free": ["solid"] }, "css3": { "changes": ["3.1.0", "5.0.0"], "ligatures": [], "search": { "terms": ["code"] }, "styles": ["brands"], "unicode": "f13c", "label": "CSS 3 Logo", "voted": false, "svg": { "brands": { "last_modified": 1660014463, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M480 32l-64 368-223.3 80L0 400l19.6-94.8h82l-8 40.6L210 390.2l134.1-44.4 18.8-97.1H29.5l16-82h333.7l10.5-52.7H56.3l16.3-82H480z" } }, "free": ["brands"] }, "css3-alt": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f38b", "label": "Alternate CSS3 Logo", "voted": false, "svg": { "brands": { "last_modified": 1660014481, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M0 32l34.9 395.8L192 480l157.1-52.2L384 32H0zm313.1 80l-4.8 47.3L193 208.6l-.3.1h111.5l-12.8 146.6-98.2 28.7-98.8-29.2-6.4-73.9h48.9l3.2 38.3 52.6 13.3 54.7-15.4 3.7-61.6-166.3-.5v-.1l-.2.1-3.6-46.3L193.1 162l6.5-2.7H76.7L70.9 112h242.2z" } }, "free": ["brands"] }, "cube": { "aliases": { "unicodes": { "secondary": ["10f1b2"] } }, "changes": [ "4.1.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["3d", "block", "dice", "package", "square", "tesseract"] }, "styles": ["solid"], "unicode": "f1b2", "label": "Cube", "voted": false, "svg": { "solid": { "last_modified": 1684767207, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M234.5 5.7c13.9-5 29.1-5 43.1 0l192 68.6C495 83.4 512 107.5 512 134.6V377.4c0 27-17 51.2-42.5 60.3l-192 68.6c-13.9 5-29.1 5-43.1 0l-192-68.6C17 428.6 0 404.5 0 377.4V134.6c0-27 17-51.2 42.5-60.3l192-68.6zM256 66L82.3 128 256 190l173.7-62L256 66zm32 368.6l160-57.1v-188L288 246.6v188z" } }, "free": ["solid"] }, "cubes": { "aliases": { "unicodes": { "secondary": ["10f1b3"] } }, "changes": [ "4.1.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "3d", "block", "dice", "package", "pyramid", "square", "stack", "tesseract" ] }, "styles": ["solid"], "unicode": "f1b3", "label": "Cubes", "voted": false, "svg": { "solid": { "last_modified": 1684767206, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M290.8 48.6l78.4 29.7L288 109.5 206.8 78.3l78.4-29.7c1.8-.7 3.8-.7 5.7 0zM136 92.5V204.7c-1.3 .4-2.6 .8-3.9 1.3l-96 36.4C14.4 250.6 0 271.5 0 294.7V413.9c0 22.2 13.1 42.3 33.5 51.3l96 42.2c14.4 6.3 30.7 6.3 45.1 0L288 457.5l113.5 49.9c14.4 6.3 30.7 6.3 45.1 0l96-42.2c20.3-8.9 33.5-29.1 33.5-51.3V294.7c0-23.3-14.4-44.1-36.1-52.4l-96-36.4c-1.3-.5-2.6-.9-3.9-1.3V92.5c0-23.3-14.4-44.1-36.1-52.4l-96-36.4c-12.8-4.8-26.9-4.8-39.7 0l-96 36.4C150.4 48.4 136 69.3 136 92.5zM392 210.6l-82.4 31.2V152.6L392 121v89.6zM154.8 250.9l78.4 29.7L152 311.7 70.8 280.6l78.4-29.7c1.8-.7 3.8-.7 5.7 0zm18.8 204.4V354.8L256 323.2v95.9l-82.4 36.2zM421.2 250.9c1.8-.7 3.8-.7 5.7 0l78.4 29.7L424 311.7l-81.2-31.1 78.4-29.7zM523.2 421.2l-77.6 34.1V354.8L528 323.2v90.7c0 3.2-1.9 6-4.8 7.3z" } }, "free": ["solid"] }, "cubes-stacked": { "changes": ["6.1.0", "6.1.1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["blocks", "cubes", "sugar"] }, "styles": ["solid"], "unicode": "e4e6", "label": "Cubes Stacked", "voted": false, "svg": { "solid": { "last_modified": 1684767420, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M192 64v64c0 17.7 14.3 32 32 32h64c17.7 0 32-14.3 32-32V64c0-17.7-14.3-32-32-32H224c-17.7 0-32 14.3-32 32zM82.7 207c-15.3 8.8-20.5 28.4-11.7 43.7l32 55.4c8.8 15.3 28.4 20.5 43.7 11.7l55.4-32c15.3-8.8 20.5-28.4 11.7-43.7l-32-55.4c-8.8-15.3-28.4-20.5-43.7-11.7L82.7 207zM288 192c-17.7 0-32 14.3-32 32v64c0 17.7 14.3 32 32 32h64c17.7 0 32-14.3 32-32V224c0-17.7-14.3-32-32-32H288zm64 160c-17.7 0-32 14.3-32 32v64c0 17.7 14.3 32 32 32h64c17.7 0 32-14.3 32-32V384c0-17.7-14.3-32-32-32H352zM160 384v64c0 17.7 14.3 32 32 32h64c17.7 0 32-14.3 32-32V384c0-17.7-14.3-32-32-32H192c-17.7 0-32 14.3-32 32zM32 352c-17.7 0-32 14.3-32 32v64c0 17.7 14.3 32 32 32H96c17.7 0 32-14.3 32-32V384c0-17.7-14.3-32-32-32H32z" } }, "free": ["solid"] }, "cuttlefish": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f38c", "label": "Cuttlefish", "voted": false, "svg": { "brands": { "last_modified": 1660014468, "raw": "", "viewBox": [0, 0, 440, 512], "width": 440, "height": 512, "path": "M344 305.5c-17.5 31.6-57.4 54.5-96 54.5-56.6 0-104-47.4-104-104s47.4-104 104-104c38.6 0 78.5 22.9 96 54.5 13.7-50.9 41.7-93.3 87-117.8C385.7 39.1 320.5 8 248 8 111 8 0 119 0 256s111 248 248 248c72.5 0 137.7-31.1 183-80.7-45.3-24.5-73.3-66.9-87-117.8z" } }, "free": ["brands"] }, "d": { "aliases": { "unicodes": { "composite": ["64"] } }, "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Latin Capital Letter D", "Latin Small Letter D", "letter"] }, "styles": ["solid"], "unicode": "44", "label": "D", "voted": false, "svg": { "solid": { "last_modified": 1684767244, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M0 96C0 60.7 28.7 32 64 32h96c123.7 0 224 100.3 224 224s-100.3 224-224 224H64c-35.3 0-64-28.7-64-64V96zm160 0H64V416h96c88.4 0 160-71.6 160-160s-71.6-160-160-160z" } }, "free": ["solid"] }, "d-and-d": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f38d", "label": "Dungeons & Dragons", "voted": false, "svg": { "brands": { "last_modified": 1660014464, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M82.5 98.9c-.6-17.2 2-33.8 12.7-48.2.3 7.4 1.2 14.5 4.2 21.6 5.9-27.5 19.7-49.3 42.3-65.5-1.9 5.9-3.5 11.8-3 17.7 8.7-7.4 18.8-17.8 44.4-22.7 14.7-2.8 29.7-2 42.1 1 38.5 9.3 61 34.3 69.7 72.3 5.3 23.1.7 45-8.3 66.4-5.2 12.4-12 24.4-20.7 35.1-2-1.9-3.9-3.8-5.8-5.6-42.8-40.8-26.8-25.2-37.4-37.4-1.1-1.2-1-2.2-.1-3.6 8.3-13.5 11.8-28.2 10-44-1.1-9.8-4.3-18.9-11.3-26.2-14.5-15.3-39.2-15-53.5.6-11.4 12.5-14.1 27.4-10.9 43.6.2 1.3.4 2.7 0 3.9-3.4 13.7-4.6 27.6-2.5 41.6.1.5.1 1.1.1 1.6 0 .3-.1.5-.2 1.1-21.8-11-36-28.3-43.2-52.2-8.3 17.8-11.1 35.5-6.6 54.1-15.6-15.2-21.3-34.3-22-55.2zm469.6 123.2c-11.6-11.6-25-20.4-40.1-26.6-12.8-5.2-26-7.9-39.9-7.1-10 .6-19.6 3.1-29 6.4-2.5.9-5.1 1.6-7.7 2.2-4.9 1.2-7.3-3.1-4.7-6.8 3.2-4.6 3.4-4.2 15-12 .6-.4 1.2-.8 2.2-1.5h-2.5c-.6 0-1.2.2-1.9.3-19.3 3.3-30.7 15.5-48.9 29.6-10.4 8.1-13.8 3.8-12-.5 1.4-3.5 3.3-6.7 5.1-10 1-1.8 2.3-3.4 3.5-5.1-.2-.2-.5-.3-.7-.5-27 18.3-46.7 42.4-57.7 73.3.3.3.7.6 1 .9.3-.6.5-1.2.9-1.7 10.4-12.1 22.8-21.8 36.6-29.8 18.2-10.6 37.5-18.3 58.7-20.2 4.3-.4 8.7-.1 13.1-.1-1.8.7-3.5.9-5.3 1.1-18.5 2.4-35.5 9-51.5 18.5-30.2 17.9-54.5 42.2-75.1 70.4-.3.4-.4.9-.7 1.3 14.5 5.3 24 17.3 36.1 25.6.2-.1.3-.2.4-.4l1.2-2.7c12.2-26.9 27-52.3 46.7-74.5 16.7-18.8 38-25.3 62.5-20 5.9 1.3 11.4 4.4 17.2 6.8 2.3-1.4 5.1-3.2 8-4.7 8.4-4.3 17.4-7 26.7-9 14.7-3.1 29.5-4.9 44.5-1.3v-.5c-.5-.4-1.2-.8-1.7-1.4zM316.7 397.6c-39.4-33-22.8-19.5-42.7-35.6-.8.9 0-.2-1.9 3-11.2 19.1-25.5 35.3-44 47.6-10.3 6.8-21.5 11.8-34.1 11.8-21.6 0-38.2-9.5-49.4-27.8-12-19.5-13.3-40.7-8.2-62.6 7.8-33.8 30.1-55.2 38.6-64.3-18.7-6.2-33 1.7-46.4 13.9.8-13.9 4.3-26.2 11.8-37.3-24.3 10.6-45.9 25-64.8 43.9-.3-5.8 5.4-43.7 5.6-44.7.3-2.7-.6-5.3-3-7.4-24.2 24.7-44.5 51.8-56.1 84.6 7.4-5.9 14.9-11.4 23.6-16.2-8.3 22.3-19.6 52.8-7.8 101.1 4.6 19 11.9 36.8 24.1 52.3 2.9 3.7 6.3 6.9 9.5 10.3.2-.2.4-.3.6-.5-1.4-7-2.2-14.1-1.5-21.9 2.2 3.2 3.9 6 5.9 8.6 12.6 16 28.7 27.4 47.2 35.6 25 11.3 51.1 13.3 77.9 8.6 54.9-9.7 90.7-48.6 116-98.8 1-1.8.6-2.9-.9-4.2zm172-46.4c-9.5-3.1-22.2-4.2-28.7-2.9 9.9 4 14.1 6.6 18.8 12 12.6 14.4 10.4 34.7-5.4 45.6-11.7 8.1-24.9 10.5-38.9 9.1-1.2-.1-2.3-.4-3-.6 2.8-3.7 6-7 8.1-10.8 9.4-16.8 5.4-42.1-8.7-56.1-2.1-2.1-4.6-3.9-7-5.9-.3 1.3-.1 2.1.1 2.8 4.2 16.6-8.1 32.4-24.8 31.8-7.6-.3-13.9-3.8-19.6-8.5-19.5-16.1-39.1-32.1-58.5-48.3-5.9-4.9-12.5-8.1-20.1-8.7-4.6-.4-9.3-.6-13.9-.9-5.9-.4-8.8-2.8-10.4-8.4-.9-3.4-1.5-6.8-2.2-10.2-1.5-8.1-6.2-13-14.3-14.2-4.4-.7-8.9-1-13.3-1.5-13-1.4-19.8-7.4-22.6-20.3-5 11-1.6 22.4 7.3 29.9 4.5 3.8 9.3 7.3 13.8 11.2 4.6 3.8 7.4 8.7 7.9 14.8.4 4.7.8 9.5 1.8 14.1 2.2 10.6 8.9 18.4 17 25.1 16.5 13.7 33 27.3 49.5 41.1 17.9 15 13.9 32.8 13 56-.9 22.9 12.2 42.9 33.5 51.2 1 .4 2 .6 3.6 1.1-15.7-18.2-10.1-44.1.7-52.3.3 2.2.4 4.3.9 6.4 9.4 44.1 45.4 64.2 85 56.9 16-2.9 30.6-8.9 42.9-19.8 2-1.8 3.7-4.1 5.9-6.5-19.3 4.6-35.8.1-50.9-10.6.7-.3 1.3-.3 1.9-.3 21.3 1.8 40.6-3.4 57-17.4 19.5-16.6 26.6-42.9 17.4-66-8.3-20.1-23.6-32.3-43.8-38.9zM99.4 179.3c-5.3-9.2-13.2-15.6-22.1-21.3 13.7-.5 26.6.2 39.6 3.7-7-12.2-8.5-24.7-5-38.7 5.3 11.9 13.7 20.1 23.6 26.8 19.7 13.2 35.7 19.6 46.7 30.2 3.4 3.3 6.3 7.1 9.6 10.9-.8-2.1-1.4-4.1-2.2-6-5-10.6-13-18.6-22.6-25-1.8-1.2-2.8-2.5-3.4-4.5-3.3-12.5-3-25.1-.7-37.6 1-5.5 2.8-10.9 4.5-16.3.8-2.4 2.3-4.6 4-6.6.6 6.9 0 25.5 19.6 46 10.8 11.3 22.4 21.9 33.9 32.7 9 8.5 18.3 16.7 25.5 26.8 1.1 1.6 2.2 3.3 3.8 4.7-5-13-14.2-24.1-24.2-33.8-9.6-9.3-19.4-18.4-29.2-27.4-3.3-3-4.6-6.7-5.1-10.9-1.2-10.4 0-20.6 4.3-30.2.5-1 1.1-2 1.9-3.3.5 4.2.6 7.9 1.4 11.6 4.8 23.1 20.4 36.3 49.3 63.5 10 9.4 19.3 19.2 25.6 31.6 4.8 9.3 7.3 19 5.7 29.6-.1.6.5 1.7 1.1 2 6.2 2.6 10 6.9 9.7 14.3 7.7-2.6 12.5-8 16.4-14.5 4.2 20.2-9.1 50.3-27.2 58.7.4-4.5 5-23.4-16.5-27.7-6.8-1.3-12.8-1.3-22.9-2.1 4.7-9 10.4-20.6.5-22.4-24.9-4.6-52.8 1.9-57.8 4.6 8.2.4 16.3 1 23.5 3.3-2 6.5-4 12.7-5.8 18.9-1.9 6.5 2.1 14.6 9.3 9.6 1.2-.9 2.3-1.9 3.3-2.7-3.1 17.9-2.9 15.9-2.8 18.3.3 10.2 9.5 7.8 15.7 7.3-2.5 11.8-29.5 27.3-45.4 25.8 7-4.7 12.7-10.3 15.9-17.9-6.5.8-12.9 1.6-19.2 2.4l-.3-.9c4.7-3.4 8-7.8 10.2-13.1 8.7-21.1-3.6-38-25-39.9-9.1-.8-17.8.8-25.9 5.5 6.2-15.6 17.2-26.6 32.6-34.5-15.2-4.3-8.9-2.7-24.6-6.3 14.6-9.3 30.2-13.2 46.5-14.6-5.2-3.2-48.1-3.6-70.2 20.9 7.9 1.4 15.5 2.8 23.2 4.2-23.8 7-44 19.7-62.4 35.6 1.1-4.8 2.7-9.5 3.3-14.3.6-4.5.8-9.2.1-13.6-1.5-9.4-8.9-15.1-19.7-16.3-7.9-.9-15.6.1-23.3 1.3-.9.1-1.7.3-2.9 0 15.8-14.8 36-21.7 53.1-33.5 6-4.5 6.8-8.2 3-14.9zm128.4 26.8c3.3 16 12.6 25.5 23.8 24.3-4.6-11.3-12.1-19.5-23.8-24.3z" } }, "free": ["brands"] }, "d-and-d-beyond": { "changes": ["5.4.0"], "ligatures": [], "search": { "terms": [ "Dungeons & Dragons", "d&d", "dnd", "fantasy", "gaming", "tabletop" ] }, "styles": ["brands"], "unicode": "f6ca", "label": "D&D Beyond", "voted": false, "svg": { "brands": { "last_modified": 1660014469, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M313.8 241.5c13.8 0 21-10.1 24.8-17.9-1-1.1-5-4.2-7.4-6.6-2.4 4.3-8.2 10.7-13.9 10.7-10.2 0-15.4-14.7-3.2-26.6-.5-.2-4.3-1.8-8 2.4 0-3 1-5.1 2.1-6.6-3.5 1.3-9.8 5.6-11.4 7.9.2-5.8 1.6-7.5.6-9l-.2-.2s-8.5 5.6-9.3 14.7c0 0 1.1-1.6 2.1-1.9.6-.3 1.3 0 .6 1.9-.2.6-5.8 15.7 5.1 26-.6-1.6-1.9-7.6 2.4-1.9-.3.1 5.8 7.1 15.7 7.1zm52.4-21.1c0-4-4.9-4.4-5.6-4.5 2 3.9.9 7.5.2 9 2.5-.4 5.4-1.6 5.4-4.5zm10.3 5.2c0-6.4-6.2-11.4-13.5-10.7 8 1.3 5.6 13.8-5 11.4 3.7-2.6 3.2-9.9-1.3-12.5 1.4 4.2-3 8.2-7.4 4.6-2.4-1.9-8-6.6-10.6-8.6-2.4-2.1-5.5-1-6.6-1.8-1.3-1.1-.5-3.8-2.2-5-1.6-.8-3-.3-4.8-1-1.6-.6-2.7-1.9-2.6-3.5-2.5 4.4 3.4 6.3 4.5 8.5 1 1.9-.8 4.8 4 8.5 14.8 11.6 9.1 8 10.4 18.1.6 4.3 4.2 6.7 6.4 7.4-2.1-1.9-2.9-6.4 0-9.3 0 13.9 19.2 13.3 23.1 6.4-2.4 1.1-7-.2-9-1.9 7.7 1 14.2-4.1 14.6-10.6zm-39.4-18.4c2 .8 1.6.7 6.4 4.5 10.2-24.5 21.7-15.7 22-15.5 2.2-1.9 9.8-3.8 13.8-2.7-2.4-2.7-7.5-6.2-13.3-6.2-4.7 0-7.4 2.2-8 1.3-.8-1.4 3.2-3.4 3.2-3.4-5.4.2-9.6 6.7-11.2 5.9-1.1-.5 1.4-3.7 1.4-3.7-5.1 2.9-9.3 9.1-10.2 13 4.6-5.8 13.8-9.8 19.7-9-10.5.5-19.5 9.7-23.8 15.8zm242.5 51.9c-20.7 0-40 1.3-50.3 2.1l7.4 8.2v77.2l-7.4 8.2c10.4.8 30.9 2.1 51.6 2.1 42.1 0 59.1-20.7 59.1-48.9 0-29.3-23.2-48.9-60.4-48.9zm-15.1 75.6v-53.3c30.1-3.3 46.8 3.8 46.8 26.3 0 25.6-21.4 30.2-46.8 27zM301.6 181c-1-3.4-.2-6.9 1.1-9.4 1 3 2.6 6.4 7.5 9-.5-2.4-.2-5.6.5-8-1.4-5.4 2.1-9.9 6.4-9.9 6.9 0 8.5 8.8 4.7 14.4 2.1 3.2 5.5 5.6 7.7 7.8 3.2-3.7 5.5-9.5 5.5-13.8 0-8.2-5.5-15.9-16.7-16.5-20-.9-20.2 16.6-20 18.9.5 5.2 3.4 7.8 3.3 7.5zm-.4 6c-.5 1.8-7 3.7-10.2 6.9 4.8-1 7-.2 7.8 1.8.5 1.4-.2 3.4-.5 5.6 1.6-1.8 7-5.5 11-6.2-1-.3-3.4-.8-4.3-.8 2.9-3.4 9.3-4.5 12.8-3.7-2.2-.2-6.7 1.1-8.5 2.6 1.6.3 3 .6 4.3 1.1-2.1.8-4.8 3.4-5.8 6.1 7-5 13.1 5.2 7 8.2.8.2 2.7 0 3.5-.5-.3 1.1-1.9 3-3 3.4 2.9 0 7-1.9 8.2-4.6 0 0-1.8.6-2.6-.2s.3-4.3.3-4.3c-2.3 2.9-3.4-1.3-1.3-4.2-1-.3-3.5-.6-4.6-.5 3.2-1.1 10.4-1.8 11.2-.3.6 1.1-1 3.4-1 3.4 4-.5 8.3 1.1 6.7 5.1 2.9-1.4 5.5-5.9 4.8-10.4-.3 1-1.6 2.4-2.9 2.7.2-1.4-1-2.2-1.9-2.6 1.7-9.6-14.6-14.2-14.1-23.9-1 1.3-1.8 5-.8 7.1 2.7 3.2 8.7 6.7 10.1 12.2-2.6-6.4-15.1-11.4-14.6-20.2-1.6 1.6-2.6 7.8-1.3 11 2.4 1.4 4.5 3.8 4.8 6.1-2.2-5.1-11.4-6.1-13.9-12.2-.6 2.2-.3 5 1 6.7 0 0-2.2-.8-7-.6 1.7.6 5.1 3.5 4.8 5.2zm25.9 7.4c-2.7 0-3.5-2.1-4.2-4.3 3.3 1.3 4.2 4.3 4.2 4.3zm38.9 3.7l-1-.6c-1.1-1-2.9-1.4-4.7-1.4-2.9 0-5.8 1.3-7.5 3.4-.8.8-1.4 1.8-2.1 2.6v15.7c3.5 2.6 7.1-2.9 3-7.2 1.5.3 4.6 2.7 5.1 3.2 0 0 2.6-.5 5-.5 2.1 0 3.9.3 5.6 1.1V196c-1.1.5-2.2 1-2.7 1.4zM79.9 305.9c17.2-4.6 16.2-18 16.2-19.9 0-20.6-24.1-25-37-25H3l8.3 8.6v29.5H0l11.4 14.6V346L3 354.6c61.7 0 73.8 1.5 86.4-5.9 6.7-4 9.9-9.8 9.9-17.6 0-5.1 2.6-18.8-19.4-25.2zm-41.3-27.5c20 0 29.6-.8 29.6 9.1v3c0 12.1-19 8.8-29.6 8.8zm0 59.2V315c12.2 0 32.7-2.3 32.7 8.8v4.5h.2c0 11.2-12.5 9.3-32.9 9.3zm101.2-19.3l23.1.2v-.2l14.1-21.2h-37.2v-14.9h52.4l-14.1-21v-.2l-73.5.2 7.4 8.2v77.1l-7.4 8.2h81.2l14.1-21.2-60.1.2zm214.7-60.1c-73.9 0-77.5 99.3-.3 99.3 77.9 0 74.1-99.3.3-99.3zm-.3 77.5c-37.4 0-36.9-55.3.2-55.3 36.8.1 38.8 55.3-.2 55.3zm-91.3-8.3l44.1-66.2h-41.7l6.1 7.2-20.5 37.2h-.3l-21-37.2 6.4-7.2h-44.9l44.1 65.8.2 19.4-7.7 8.2h42.6l-7.2-8.2zm-28.4-151.3c1.6 1.3 2.9 2.4 2.9 6.6v38.8c0 4.2-.8 5.3-2.7 6.4-.1.1-7.5 4.5-7.9 4.6h35.1c10 0 17.4-1.5 26-8.6-.6-5 .2-9.5.8-12 0-.2-1.8 1.4-2.7 3.5 0-5.7 1.6-15.4 9.6-20.5-.1 0-3.7-.8-9 1.1 2-3.1 10-7.9 10.4-7.9-8.2-26-38-22.9-32.2-22.9-30.9 0-32.6.3-39.9-4 .1.8.5 8.2 9.6 14.9zm21.5 5.5c4.6 0 23.1-3.3 23.1 17.3 0 20.7-18.4 17.3-23.1 17.3zm228.9 79.6l7 8.3V312h-.3c-5.4-14.4-42.3-41.5-45.2-50.9h-31.6l7.4 8.5v76.9l-7.2 8.3h39l-7.4-8.2v-47.4h.3c3.7 10.6 44.5 42.9 48.5 55.6h21.3v-85.2l7.4-8.3zm-106.7-96.1c-32.2 0-32.8.2-39.9-4 .1.7.5 8.3 9.6 14.9 3.1 2 2.9 4.3 2.9 9.5 1.8-1.1 3.8-2.2 6.1-3-1.1 1.1-2.7 2.7-3.5 4.5 1-1.1 7.5-5.1 14.6-3.5-1.6.3-4 1.1-6.1 2.9.1 0 2.1-1.1 7.5-.3v-4.3c4.7 0 23.1-3.4 23.1 17.3 0 20.5-18.5 17.3-19.7 17.3 5.7 4.4 5.8 12 2.2 16.3h.3c33.4 0 36.7-27.3 36.7-34 0-3.8-1.1-32-33.8-33.6z" } }, "free": ["brands"] }, "dailymotion": { "changes": ["5.12.1", "5.14.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e052", "label": "dailymotion", "voted": true, "svg": { "brands": { "last_modified": 1660014471, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M298.93,267a48.4,48.4,0,0,0-24.36-6.21q-19.83,0-33.44,13.27t-13.61,33.42q0,21.16,13.28,34.6t33.43,13.44q20.5,0,34.11-13.78T322,307.47A47.13,47.13,0,0,0,315.9,284,44.13,44.13,0,0,0,298.93,267ZM0,32V480H448V32ZM374.71,405.26h-53.1V381.37h-.67q-15.79,26.2-55.78,26.2-27.56,0-48.89-13.1a88.29,88.29,0,0,1-32.94-35.77q-11.6-22.68-11.59-50.89,0-27.56,11.76-50.22a89.9,89.9,0,0,1,32.93-35.78q21.18-13.09,47.72-13.1a80.87,80.87,0,0,1,29.74,5.21q13.28,5.21,25,17V153l55.79-12.09Z" } }, "free": ["brands"] }, "dashcube": { "changes": ["4.3.0", "5.0.0", "5.0.3"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f210", "label": "DashCube", "voted": false, "svg": { "brands": { "last_modified": 1660014467, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M326.6 104H110.4c-51.1 0-91.2 43.3-91.2 93.5V427c0 50.5 40.1 85 91.2 85h227.2c51.1 0 91.2-34.5 91.2-85V0L326.6 104zM153.9 416.5c-17.7 0-32.4-15.1-32.4-32.8V240.8c0-17.7 14.7-32.5 32.4-32.5h140.7c17.7 0 32 14.8 32 32.5v123.5l51.1 52.3H153.9z" } }, "free": ["brands"] }, "database": { "aliases": { "unicodes": { "secondary": ["10f1c0"] } }, "changes": [ "4.1.0", "5.0.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["computer", "development", "directory", "memory", "storage"] }, "styles": ["solid"], "unicode": "f1c0", "label": "Database", "voted": false, "svg": { "solid": { "last_modified": 1684767551, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M448 80v48c0 44.2-100.3 80-224 80S0 172.2 0 128V80C0 35.8 100.3 0 224 0S448 35.8 448 80zM393.2 214.7c20.8-7.4 39.9-16.9 54.8-28.6V288c0 44.2-100.3 80-224 80S0 332.2 0 288V186.1c14.9 11.8 34 21.2 54.8 28.6C99.7 230.7 159.5 240 224 240s124.3-9.3 169.2-25.3zM0 346.1c14.9 11.8 34 21.2 54.8 28.6C99.7 390.7 159.5 400 224 400s124.3-9.3 169.2-25.3c20.8-7.4 39.9-16.9 54.8-28.6V432c0 44.2-100.3 80-224 80S0 476.2 0 432V346.1z" } }, "free": ["solid"] }, "debian": { "changes": ["6.4.1"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e60b", "label": "Debian", "voted": false, "svg": { "brands": { "last_modified": 1682957890, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M248.2 .9c-4 .2-8.1 .4-11.4 1.6l-3.4-.5c5.4-.7 10.9-1.1 16.4-1.5c2.4-.2 4.8-.4 7.2-.6c-2.7 .6-5.7 .8-8.8 .9zm132 244.7c3-7.6 5.5-14 5.2-24.4l-4.3 9c4.4-13.2 4-27.1 3.6-40.4c-.2-6-.3-11.8 0-17.4l-1.8-.5c-1.5-45.2-40.6-93.1-75.3-109.4c-30-13.8-76.1-16.2-97.3-5.8c1.3-1.1 4.2-2 6.8-2.7c3.4-1 6.3-1.8 4.3-3c-19.2 1.9-24.9 5.5-31.1 9.4c-4.6 2.9-9.5 6-20.3 8.7c-3.5 3.4 1.7 2 5.8 .9c4.1-1.1 7.2-1.9-.1 2.4c-3.6 1-6.7 1.3-9.7 1.6c-8.3 .8-15.8 1.6-30.7 17c.8 1.3 3.5-.3 5.4-1.4c2.3-1.4 3.4-2-1.7 4.4c-19.1-2.4-60.3 43.7-69.1 59l4.6 .8c-3.2 8-6.8 14.8-10 20.8c-4.3 8.1-7.9 14.9-8.7 21.3c-.4 5.9-1.2 12.9-2 20.3c-3 27.4-6.8 61.3 3.8 73.6l-1.3 13c.6 1.2 1.1 2.3 1.6 3.5c1.2 2.5 2.3 5 3.9 7.4l-3 .2c7 22.2 10.8 22.5 15.1 22.9c4.4 .4 9.3 .9 18.7 24.2c-2.7-.9-5.5-1.9-9.4-7.2c-.5 4.1 5.8 16.3 13.1 25.8l-3.1 3.6c3.2 5.8 6.1 8.1 8.6 10l0 0c.8 .6 1.5 1.1 2.1 1.7c-11.9-6.5 3.2 13.7 11.9 25.2c2.5 3.4 4.5 6 5.1 7l2.4-4.2c-.3 6.1 4.3 13.9 13.1 24.7l7.3-.3c3 6 14 16.7 20.7 17.2l-4.4 5.8c8.1 2.6 10.3 4.3 12.7 6.2c2.6 2.1 5.4 4.3 16.1 8.1l-4.2-7.4c3.5 3 6.2 5.9 8.8 8.7c5.2 5.6 9.9 10.7 19.8 15.4c11.2 3.9 17.1 4.8 23.6 5.9c5.4 .8 11.2 1.8 20.8 4.5c-2.2-.1-4.4-.1-6.7-.2l0 0h0c-16.3-.4-34-.8-46.4-5.2C107.8 480.5 19.5 367.2 26 250.6c-.6-9.9-.3-20.9 0-30.7c.4-13.5 .7-24.8-1.6-28.3l1-3.1c5.3-17.4 11.7-38.2 23.8-62.8l-.1-.2 0-.1 0 0 0 0c.4 .4 3.4 3.4 8.8-5.8c1.3-2.9 2.5-5.8 3.8-8.8l0 0c2.5-6.1 5.1-12.3 8.4-17.9l2.6-.6c1.7-10.1 17-23.8 29.8-35.2l0 0c6.1-5.5 11.6-10.4 14.7-14.1l.7 4.4c17.1-16 45-27.7 66.1-36.6c4.8-2 9.3-3.9 13.3-5.7c-3.4 3.8 2.2 2.7 10 1c4.8-1 10.4-2.1 15.3-2.4c-1.3 .7-2.6 1.4-3.9 2.1l0 0 0 0c-2.7 1.4-5.4 2.8-8 4.6c8.3-2 11.9-1.4 16-.8c3.5 .6 7.3 1.2 14.6 .2c-5.6 .8-12.3 3-11.2 3.8c7.9 .9 12.8-.1 17.2-1c5.6-1.1 10.4-2.1 19.5 .9l-1-4.8c7.5 2.7 13.1 4.4 18 5.9c10 3 17.6 5.3 34.2 14.1c3.2 .2 5.3-.5 7.4-1.2c3.6-1.1 7-2.2 15.3 1.2c.5 .8 .7 1.5 1 2.1c1 2.6 1.7 4.6 14.6 12.2c1.8-.7-3.1-5.1-7-8.7l-.2-.1c32.3 17.3 67.5 54.1 78.2 93.6c-6-11.1-5.2-5.5-4.3 .5c.6 4 1.2 8.1-.2 7.5c4.5 12.1 8.1 24.5 10.4 37.4l-.8-2.9c-3.3-11.8-9.6-34.5-20-49.6c-.4 4.4-2.9 3.9-5.3 3.5c-3.3-.6-6.3-1.2-1.9 12.6c2.6 3.8 3.1 2.4 3.5 1.1c.5-1.5 .9-2.8 4.7 5.2c.1 4.3 1.1 8.5 2.2 13.3l0 0 0 0 0 0 0 0 0 0 0 0c.7 3 1.5 6.2 2.1 9.8c-1.1-.2-2.3-2.2-3.4-4.2l0 0 0 0c-1.4-2.4-2.8-4.7-3.7-3.2c2.4 11.5 6.5 17.4 8 18.3c-.3 .6-.6 .7-1.1 .7c-.8 0-1.8 .1-1.9 5.3c.7 13.7 3.3 12.5 5.3 11.6c.6-.3 1.2-.6 1.7-.4c-.6 2.5-1.6 5.1-2.7 7.9l0 0c-2.8 7.1-6 15.4-3.4 26.1c-.8-3.1-2.1-6.3-3.3-9.3l0 0 0 0c-.5-1.3-1.1-2.6-1.5-3.8c-.6 4.8-.3 8.2-.1 11.3c.4 5.3 .7 10-3 19.9c4.3-14.2 3.8-26.9-.2-20.8c1 11-3.8 20.5-8.1 29.1c-3.6 7.1-6.8 13.5-5.9 19.3l-5.2-7.1c-7.6 11-7 13.3-6.5 15.6c.5 1.9 1 3.8-3.4 10.8c1.7-2.9 1.3-3.6 1-4.2c-.4-.8-.7-1.5 1.7-5.1c-1.6 .1-5.5 3.9-10.1 8.5l0 0c-3.9 3.9-8.5 8.4-12.8 11.8c-37.5 30.1-82.3 34-125.6 17.8l0 0c.2-1-.2-2.1-3.1-4.1c-36.8-28.2-58.5-52.1-50.9-107.5c2.2-1.7 3.7-6.2 5.6-11.6c2.9-8.4 6.5-18.9 14.3-23.9c7.8-17.3 31.3-33.3 56.4-33.7c25.6-1.4 47.2 13.7 58.1 27.9c-19.8-18.4-52.1-24-79.7-10.4c-28.2 12.7-45 43.8-42.5 74.7c.3-.5 .7-.7 1-.9c.6-.5 1.2-.9 1.5-3.4c-.9 60.2 64.8 104.3 112.1 82l.6 1.3c12.7-3.5 15.9-6.5 20.3-10.7c2.2-2.1 4.7-4.5 9-7.4c-.3 .7-1.3 1.7-2.4 2.7c-2.2 2.1-4.6 4.5-1.6 4.6c5.3-1.4 20.1-14.8 30.2-23.8l0 0 0 0c1.6-1.4 3-2.7 4.3-3.9c2-4.3 1.6-5.7 1.3-7.1c-.4-1.6-.8-3.3 2.4-9.6l7.3-3.7c1-2.8 2-5.4 2.9-7.8l0 0zM233.1 321.9a.9 .9 0 1 0 -1.7 0 .9 .9 0 1 0 1.7 0zm-.2 .5l-.2 .4c-.3 .7-.6 1.4-.3 2.4c-12.2-5.7-23.4-14.3-32.6-24.9c4.9 7.1 10.1 14.1 17 19.5c-6.9-2.3-15.2-11.9-21.7-19.4l0 0 0 0c-4.3-5-7.9-9.1-9.7-9.5c19.8 35.5 80.5 62.3 112.3 49c-14.7 .5-33.4 .3-49.9-5.8c-6.3-3.2-14.6-9.6-14.9-11.8zM237.5 7c3.8 .6 7.3 1.2 6.7 2.1c5-1.1 6.1-2.1-9-2.5c.8 .1 1.6 .3 2.4 .4zm92.2 208.4c-1 3.9-1.8 1.4-2.7-1.2c-.5-1.5-1.1-3.1-1.7-3.4c1.4-5.8 5.4-10.7 4.4 4.6zm-6.8 21.2c-1.3 7.9-5 15.5-10.1 22.5c.2-2-1.2-2.4-2.6-2.8c-2.9-.8-5.9-1.6 5.6-16.1c-.5 2-2.3 4.9-4 7.7l0 0c-3.6 5.9-6.7 11 4 4.3l1-1.8c2.6-4.5 5-8.8 6-13.8zM280 276.6c-11.1-1.7-21.2-6-12.7-6.1c7.1 .6 14.1 .6 21-1.1c-2.5 2.4-5.2 4.8-8.3 7.2zM244.2 9.1l-.2 .4-3 .3 3.2-.7zm-69.5 273c3.7 7.2 6.5 11.7 9.1 15.9c2.3 3.7 4.4 7.1 6.8 11.7c-5.2-4.3-8.9-9.8-12.8-15.5c-1.4-2.1-2.8-4.2-4.4-6.2l1.2-5.9zm7.3-10c1.7 3.4 3.3 6.7 5.9 9.5l2.6 7.7-1.3-2.1c-3.2-5.3-6.3-10.6-8-16.7l.8 1.6zm239.1-41.2c-2.3 17.4-7.7 34.6-16 50.3c7.6-14.9 12.5-30.9 14.8-47.2l1.2-3.1zM35.4 109.6c0 .3 0 .5 .1 .7c0-.2 0-.5-.1-.7zm.1 .7c.3 1.2 1.4 .9 2.4 .6c1.9-.5 3.6-.9-.1 7.6c-2.4 1.7-3.8 2.8-4.6 3.4c-.6 .4-.8 .6-.8 .6c0 0 .1-.2 .3-.5c.8-1.4 3.4-5.5 2.9-11.7zm-10.2 42c-.7 3.7-1.5 7.9-3.4 13.9c.2-1.9 0-3.5-.2-4.9c-.4-3.4-.8-6.3 4.3-12.9c-.3 1.2-.5 2.5-.7 3.8z" } }, "free": ["brands"] }, "deezer": { "changes": ["5.13.1", "5.14.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e077", "label": "Deezer", "voted": true, "svg": { "brands": { "last_modified": 1660014465, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M451.46,244.71H576V172H451.46Zm0-173.89v72.67H576V70.82Zm0,275.06H576V273.2H451.46ZM0,447.09H124.54V374.42H0Zm150.47,0H275V374.42H150.47Zm150.52,0H425.53V374.42H301Zm150.47,0H576V374.42H451.46ZM301,345.88H425.53V273.2H301Zm-150.52,0H275V273.2H150.47Zm0-101.17H275V172H150.47Z" } }, "free": ["brands"] }, "delete-left": { "aliases": { "names": ["backspace"], "unicodes": { "composite": ["232b"], "secondary": ["10f55a"] } }, "changes": ["5.1.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "Erase to the Left", "command", "delete", "erase", "keyboard", "undo" ] }, "styles": ["solid"], "unicode": "f55a", "label": "Delete Left", "voted": true, "svg": { "solid": { "last_modified": 1684767367, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M576 128c0-35.3-28.7-64-64-64H205.3c-17 0-33.3 6.7-45.3 18.7L9.4 233.4c-6 6-9.4 14.1-9.4 22.6s3.4 16.6 9.4 22.6L160 429.3c12 12 28.3 18.7 45.3 18.7H512c35.3 0 64-28.7 64-64V128zM271 175c9.4-9.4 24.6-9.4 33.9 0l47 47 47-47c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-47 47 47 47c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-47-47-47 47c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l47-47-47-47c-9.4-9.4-9.4-24.6 0-33.9z" } }, "free": ["solid"] }, "delicious": { "changes": ["4.1.0", "5.0.0", "5.7.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f1a5", "label": "Delicious", "voted": false, "svg": { "brands": { "last_modified": 1660014476, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M446.5 68c-.4-1.5-.9-3-1.4-4.5-.9-2.5-2-4.8-3.3-7.1-1.4-2.4-3-4.8-4.7-6.9-2.1-2.5-4.4-4.8-6.9-6.8-1.1-.9-2.2-1.7-3.3-2.5-1.3-.9-2.6-1.7-4-2.4-1.8-1-3.6-1.8-5.5-2.5-1.7-.7-3.5-1.3-5.4-1.7-3.8-1-7.9-1.5-12-1.5H48C21.5 32 0 53.5 0 80v352c0 4.1.5 8.2 1.5 12 2 7.7 5.8 14.6 11 20.3 1 1.1 2.1 2.2 3.3 3.3 5.7 5.2 12.6 9 20.3 11 3.8 1 7.9 1.5 12 1.5h352c26.5 0 48-21.5 48-48V80c-.1-4.1-.6-8.2-1.6-12zM416 432c0 8.8-7.2 16-16 16H224V256H32V80c0-8.8 7.2-16 16-16h176v192h192z" } }, "free": ["brands"] }, "democrat": { "aliases": { "unicodes": { "secondary": ["10f747"] } }, "changes": ["5.5.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "american", "democratic party", "donkey", "election", "left", "left-wing", "liberal", "politics", "usa" ] }, "styles": ["solid"], "unicode": "f747", "label": "Democrat", "voted": false, "svg": { "solid": { "last_modified": 1684767602, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M64 32c0-8.9 3.8-20.9 6.2-27.3C71.2 1.8 74 0 77 0c1.9 0 3.8 .7 5.2 2.1L128 45.7 173.8 2.1C175.2 .7 177.1 0 179 0c3 0 5.8 1.8 6.8 4.7c2.4 6.5 6.2 18.4 6.2 27.3c0 26.5-21.9 42-29.5 46.6l76.2 72.6c6 5.7 13.9 8.8 22.1 8.8H480l32 0c40.3 0 78.2 19 102.4 51.2l19.2 25.6c10.6 14.1 7.7 34.2-6.4 44.8s-34.2 7.7-44.8-6.4l-19.2-25.6c-5.3-7-11.8-12.8-19.2-17V320H192l-40.4-94.3c-3.9-9.2-15.3-12.6-23.6-7l-42.1 28c-9.1 6.1-19.7 9.3-30.7 9.3h-2C23.9 256 0 232.1 0 202.7c0-12.1 4.1-23.8 11.7-33.3L87.6 74.6C78.1 67.4 64 53.2 64 32zM448 352h96v64 64c0 17.7-14.3 32-32 32H480c-17.7 0-32-14.3-32-32V416H288v64c0 17.7-14.3 32-32 32H224c-17.7 0-32-14.3-32-32V416 352h96H448zM260.9 210.9c-.9-1.8-2.8-2.9-4.8-2.9s-3.9 1.1-4.8 2.9l-10.5 20.5-23.5 3.3c-2 .3-3.7 1.6-4.3 3.5s-.1 3.9 1.3 5.3l17 16-4 22.6c-.3 1.9 .5 3.9 2.1 5s3.8 1.3 5.6 .4l21-10.7 21 10.7c1.8 .9 4 .8 5.6-.4s2.5-3.1 2.1-5l-4-22.6 17-16c1.5-1.4 2-3.4 1.3-5.3s-2.3-3.2-4.3-3.5l-23.5-3.3-10.5-20.5zM368.1 208c-2 0-3.9 1.1-4.8 2.9l-10.5 20.5-23.5 3.3c-2 .3-3.7 1.6-4.3 3.5s-.1 3.9 1.3 5.3l17 16-4 22.6c-.3 1.9 .5 3.9 2.1 5s3.8 1.3 5.6 .4l21-10.7 21 10.7c1.8 .9 4 .8 5.6-.4s2.5-3.1 2.1-5l-4-22.6 17-16c1.5-1.4 2-3.4 1.4-5.3s-2.3-3.2-4.3-3.5l-23.5-3.3-10.5-20.5c-.9-1.8-2.8-2.9-4.8-2.9zm116.8 2.9c-.9-1.8-2.8-2.9-4.8-2.9s-3.9 1.1-4.8 2.9l-10.5 20.5-23.5 3.3c-2 .3-3.7 1.6-4.3 3.5s-.1 3.9 1.3 5.3l17 16-4 22.6c-.3 1.9 .5 3.9 2.1 5s3.8 1.3 5.6 .4l21-10.7 21 10.7c1.8 .9 4 .8 5.6-.4s2.5-3.1 2.1-5l-4-22.6 17-16c1.5-1.4 2-3.4 1.4-5.3s-2.3-3.2-4.3-3.5l-23.5-3.3-10.5-20.5z" } }, "free": ["solid"] }, "deploydog": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f38e", "label": "deploy.dog", "voted": false, "svg": { "brands": { "last_modified": 1660014466, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M382.2 136h51.7v239.6h-51.7v-20.7c-19.8 24.8-52.8 24.1-73.8 14.7-26.2-11.7-44.3-38.1-44.3-71.8 0-29.8 14.8-57.9 43.3-70.8 20.2-9.1 52.7-10.6 74.8 12.9V136zm-64.7 161.8c0 18.2 13.6 33.5 33.2 33.5 19.8 0 33.2-16.4 33.2-32.9 0-17.1-13.7-33.2-33.2-33.2-19.6 0-33.2 16.4-33.2 32.6zM188.5 136h51.7v239.6h-51.7v-20.7c-19.8 24.8-52.8 24.1-73.8 14.7-26.2-11.7-44.3-38.1-44.3-71.8 0-29.8 14.8-57.9 43.3-70.8 20.2-9.1 52.7-10.6 74.8 12.9V136zm-64.7 161.8c0 18.2 13.6 33.5 33.2 33.5 19.8 0 33.2-16.4 33.2-32.9 0-17.1-13.7-33.2-33.2-33.2-19.7 0-33.2 16.4-33.2 32.6zM448 96c17.5 0 32 14.4 32 32v256c0 17.5-14.4 32-32 32H64c-17.5 0-32-14.4-32-32V128c0-17.5 14.4-32 32-32h384m0-32H64C28.8 64 0 92.8 0 128v256c0 35.2 28.8 64 64 64h384c35.2 0 64-28.8 64-64V128c0-35.2-28.8-64-64-64z" } }, "free": ["brands"] }, "deskpro": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f38f", "label": "Deskpro", "voted": false, "svg": { "brands": { "last_modified": 1660014480, "raw": "", "viewBox": [0, 0, 480, 512], "width": 480, "height": 512, "path": "M205.9 512l31.1-38.4c12.3-.2 25.6-1.4 36.5-6.6 38.9-18.6 38.4-61.9 38.3-63.8-.1-5-.8-4.4-28.9-37.4H362c-.2 50.1-7.3 68.5-10.2 75.7-9.4 23.7-43.9 62.8-95.2 69.4-8.7 1.1-32.8 1.2-50.7 1.1zm200.4-167.7c38.6 0 58.5-13.6 73.7-30.9l-175.5-.3-17.4 31.3 119.2-.1zm-43.6-223.9v168.3h-73.5l-32.7 55.5H250c-52.3 0-58.1-56.5-58.3-58.9-1.2-13.2-21.3-11.6-20.1 1.8 1.4 15.8 8.8 40 26.4 57.1h-91c-25.5 0-110.8-26.8-107-114V16.9C0 .9 9.7.3 15 .1h82c.2 0 .3.1.5.1 4.3-.4 50.1-2.1 50.1 43.7 0 13.3 20.2 13.4 20.2 0 0-18.2-5.5-32.8-15.8-43.7h84.2c108.7-.4 126.5 79.4 126.5 120.2zm-132.5 56l64 29.3c13.3-45.5-42.2-71.7-64-29.3z" } }, "free": ["brands"] }, "desktop": { "aliases": { "names": ["desktop-alt"], "unicodes": { "composite": ["1f5a5", "f108"], "primary": ["f108"], "secondary": ["10f108", "10f390"] } }, "changes": ["3.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "computer", "cpu", "demo", "desktop", "desktop computer", "device", "imac", "machine", "monitor", "pc", "screen" ] }, "styles": ["solid"], "unicode": "f390", "label": "Desktop", "voted": false, "svg": { "solid": { "last_modified": 1684767341, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M64 0C28.7 0 0 28.7 0 64V352c0 35.3 28.7 64 64 64H240l-10.7 32H160c-17.7 0-32 14.3-32 32s14.3 32 32 32H416c17.7 0 32-14.3 32-32s-14.3-32-32-32H346.7L336 416H512c35.3 0 64-28.7 64-64V64c0-35.3-28.7-64-64-64H64zM512 64V288H64V64H512z" } }, "free": ["solid"] }, "dev": { "changes": ["5.4.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f6cc", "label": "DEV", "voted": true, "svg": { "brands": { "last_modified": 1660014462, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M120.12 208.29c-3.88-2.9-7.77-4.35-11.65-4.35H91.03v104.47h17.45c3.88 0 7.77-1.45 11.65-4.35 3.88-2.9 5.82-7.25 5.82-13.06v-69.65c-.01-5.8-1.96-10.16-5.83-13.06zM404.1 32H43.9C19.7 32 .06 51.59 0 75.8v360.4C.06 460.41 19.7 480 43.9 480h360.2c24.21 0 43.84-19.59 43.9-43.8V75.8c-.06-24.21-19.7-43.8-43.9-43.8zM154.2 291.19c0 18.81-11.61 47.31-48.36 47.25h-46.4V172.98h47.38c35.44 0 47.36 28.46 47.37 47.28l.01 70.93zm100.68-88.66H201.6v38.42h32.57v29.57H201.6v38.41h53.29v29.57h-62.18c-11.16.29-20.44-8.53-20.72-19.69V193.7c-.27-11.15 8.56-20.41 19.71-20.69h63.19l-.01 29.52zm103.64 115.29c-13.2 30.75-36.85 24.63-47.44 0l-38.53-144.8h32.57l29.71 113.72 29.57-113.72h32.58l-38.46 144.8z" } }, "free": ["brands"] }, "deviantart": { "changes": ["4.1.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f1bd", "label": "deviantART", "voted": false, "svg": { "brands": { "last_modified": 1660014463, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M320 93.2l-98.2 179.1 7.4 9.5H320v127.7H159.1l-13.5 9.2-43.7 84c-.3 0-8.6 8.6-9.2 9.2H0v-93.2l93.2-179.4-7.4-9.2H0V102.5h156l13.5-9.2 43.7-84c.3 0 8.6-8.6 9.2-9.2H320v93.1z" } }, "free": ["brands"] }, "dharmachakra": { "aliases": { "unicodes": { "composite": ["2638"], "secondary": ["10f655"] } }, "changes": ["5.3.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "Buddhist", "buddhism", "buddhist", "dharma", "religion", "wheel", "wheel of dharma" ] }, "styles": ["solid"], "unicode": "f655", "label": "Dharmachakra", "voted": false, "svg": { "solid": { "last_modified": 1684767601, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M337.8 205.7l48.6-42.5c13.8 19.3 23.4 41.9 27.4 66.2l-64.4 4.3c-2.4-10.1-6.4-19.5-11.6-28zm140.1 19.5c-5.3-38.8-20.6-74.5-43.2-104.3l.8-.7C449 108.4 449.7 87.6 437 75s-33.4-12-45.2 1.5l-.7 .8c-29.8-22.6-65.5-37.9-104.3-43.2l.1-1.1c1.2-17.9-13-33-30.9-33s-32.1 15.2-30.9 33l.1 1.1c-38.8 5.3-74.5 20.6-104.3 43.2l-.7-.8C108.4 63 87.6 62.3 75 75s-12 33.4 1.5 45.2l.8 .7c-22.6 29.8-37.9 65.5-43.2 104.3l-1.1-.1c-17.9-1.2-33 13-33 30.9s15.2 32.1 33 30.9l1.1-.1c5.3 38.8 20.6 74.5 43.2 104.3l-.8 .7C63 403.6 62.3 424.4 75 437s33.4 12 45.2-1.5l.7-.8c29.8 22.6 65.5 37.9 104.3 43.2l-.1 1.1c-1.2 17.9 13 33 30.9 33s32.1-15.2 30.9-33l-.1-1.1c38.8-5.3 74.5-20.6 104.3-43.2l.7 .8c11.8 13.5 32.5 14.2 45.2 1.5s12-33.4-1.5-45.2l-.8-.7c22.6-29.8 37.9-65.5 43.2-104.3l1.1 .1c17.9 1.2 33-13 33-30.9s-15.2-32.1-33-30.9l-1.1 .1zM163.2 125.6c19.3-13.8 41.9-23.4 66.2-27.5l4.3 64.4c-10 2.4-19.5 6.4-28 11.6l-42.5-48.6zm-65 103.8c4.1-24.4 13.7-46.9 27.5-66.2l48.6 42.5c-5.3 8.5-9.2 18-11.6 28l-64.4-4.3zm27.5 119.4c-13.8-19.3-23.4-41.9-27.5-66.2l64.4-4.3c2.4 10 6.4 19.5 11.6 28l-48.6 42.5zm103.8 65c-24.4-4.1-46.9-13.7-66.2-27.4l42.5-48.6c8.5 5.3 18 9.2 28 11.6l-4.3 64.4zm119.4-27.4c-19.3 13.8-41.9 23.4-66.2 27.4l-4.3-64.4c10-2.4 19.5-6.4 28-11.6l42.5 48.6zm65-103.8c-4.1 24.4-13.7 46.9-27.4 66.2l-48.6-42.5c5.3-8.5 9.2-18 11.6-28l64.4 4.3zm-65-156.9l-42.5 48.6c-8.5-5.3-18-9.2-28-11.6l4.3-64.4c24.4 4.1 46.9 13.7 66.2 27.5zM256 224a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" } }, "free": ["solid"] }, "dhl": { "changes": ["5.6.0"], "ligatures": [], "search": { "terms": ["Dalsey", "Hillblom and Lynn", "german", "package", "shipping"] }, "styles": ["brands"], "unicode": "f790", "label": "DHL", "voted": false, "svg": { "brands": { "last_modified": 1660014471, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M238 301.2h58.7L319 271h-58.7L238 301.2zM0 282.9v6.4h81.8l4.7-6.4H0zM172.9 271c-8.7 0-6-3.6-4.6-5.5 2.8-3.8 7.6-10.4 10.4-14.1 2.8-3.7 2.8-5.9-2.8-5.9h-51l-41.1 55.8h100.1c33.1 0 51.5-22.5 57.2-30.3h-68.2zm317.5-6.9l39.3-53.4h-62.2l-39.3 53.4h62.2zM95.3 271H0v6.4h90.6l4.7-6.4zm111-26.6c-2.8 3.8-7.5 10.4-10.3 14.2-1.4 2-4.1 5.5 4.6 5.5h45.6s7.3-10 13.5-18.4c8.4-11.4.7-35-29.2-35H112.6l-20.4 27.8h111.4c5.6 0 5.5 2.2 2.7 5.9zM0 301.2h73.1l4.7-6.4H0v6.4zm323 0h58.7L404 271h-58.7c-.1 0-22.3 30.2-22.3 30.2zm222 .1h95v-6.4h-90.3l-4.7 6.4zm22.3-30.3l-4.7 6.4H640V271h-72.7zm-13.5 18.3H640v-6.4h-81.5l-4.7 6.4zm-164.2-78.6l-22.5 30.6h-26.2l22.5-30.6h-58.7l-39.3 53.4H409l39.3-53.4h-58.7zm33.5 60.3s-4.3 5.9-6.4 8.7c-7.4 10-.9 21.6 23.2 21.6h94.3l22.3-30.3H423.1z" } }, "free": ["brands"] }, "diagram-next": { "changes": ["6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "cells", "chart", "gantt", "row", "subtask", "successor", "table" ] }, "styles": ["solid"], "unicode": "e476", "label": "Diagram Next", "voted": false, "svg": { "solid": { "last_modified": 1684767206, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M512 160c0 35.3-28.7 64-64 64H280v64h46.1c21.4 0 32.1 25.9 17 41L273 399c-9.4 9.4-24.6 9.4-33.9 0L169 329c-15.1-15.1-4.4-41 17-41H232V224H64c-35.3 0-64-28.7-64-64V96C0 60.7 28.7 32 64 32H448c35.3 0 64 28.7 64 64v64zM448 416V352H365.3l.4-.4c18.4-18.4 20.4-43.7 11-63.6l71.3 0c35.3 0 64 28.7 64 64v64c0 35.3-28.7 64-64 64L64 480c-35.3 0-64-28.7-64-64V352c0-35.3 28.7-64 64-64l71.3 0c-9.4 19.9-7.4 45.2 11 63.6l.4 .4H64v64H210.7l5.7 5.7c21.9 21.9 57.3 21.9 79.2 0l5.7-5.7H448z" } }, "free": ["solid"] }, "diagram-predecessor": { "changes": ["6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "cells", "chart", "gantt", "predecessor", "previous", "row", "subtask", "table" ] }, "styles": ["solid"], "unicode": "e477", "label": "Diagram Predecessor", "voted": false, "svg": { "solid": { "last_modified": 1684767208, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M448 416l0-64L64 352l0 64 384 0zm0 64L64 480c-35.3 0-64-28.7-64-64l0-64c0-35.3 28.7-64 64-64l384 0c35.3 0 64 28.7 64 64l0 64c0 35.3-28.7 64-64 64zM288 160c0 35.3-28.7 64-64 64L64 224c-35.3 0-64-28.7-64-64L0 96C0 60.7 28.7 32 64 32l144 0 16 0 144 0c44.2 0 80 35.8 80 80l0 16 38.1 0c21.4 0 32.1 25.9 17 41L433 239c-9.4 9.4-24.6 9.4-33.9 0L329 169c-15.1-15.1-4.4-41 17-41l38.1 0 0-16c0-8.8-7.2-16-16-16l-80 0 0 64z" } }, "free": ["solid"] }, "diagram-project": { "aliases": { "names": ["project-diagram"], "unicodes": { "secondary": ["10f542"] } }, "changes": [ "5.0.13", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["chart", "graph", "network", "pert"] }, "styles": ["solid"], "unicode": "f542", "label": "Diagram Project", "voted": false, "svg": { "solid": { "last_modified": 1684767206, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M0 80C0 53.5 21.5 32 48 32h96c26.5 0 48 21.5 48 48V96H384V80c0-26.5 21.5-48 48-48h96c26.5 0 48 21.5 48 48v96c0 26.5-21.5 48-48 48H432c-26.5 0-48-21.5-48-48V160H192v16c0 1.7-.1 3.4-.3 5L272 288h96c26.5 0 48 21.5 48 48v96c0 26.5-21.5 48-48 48H272c-26.5 0-48-21.5-48-48V336c0-1.7 .1-3.4 .3-5L144 224H48c-26.5 0-48-21.5-48-48V80z" } }, "free": ["solid"] }, "diagram-successor": { "changes": ["6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "cells", "chart", "gantt", "next", "row", "subtask", "successor", "table" ] }, "styles": ["solid"], "unicode": "e47a", "label": "Diagram Successor", "voted": false, "svg": { "solid": { "last_modified": 1684767205, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M512 416l0-64c0-35.3-28.7-64-64-64L64 288c-35.3 0-64 28.7-64 64l0 64c0 35.3 28.7 64 64 64l384 0c35.3 0 64-28.7 64-64zM64 160l0-64 144 0 16 0 0 64L64 160zm224 0l0-64 80 0c8.8 0 16 7.2 16 16l0 16-38.1 0c-21.4 0-32.1 25.9-17 41L399 239c9.4 9.4 24.6 9.4 33.9 0L503 169c15.1-15.1 4.4-41-17-41L448 128l0-16c0-44.2-35.8-80-80-80L224 32l-16 0L64 32C28.7 32 0 60.7 0 96l0 64c0 35.3 28.7 64 64 64l160 0c35.3 0 64-28.7 64-64z" } }, "free": ["solid"] }, "diamond": { "aliases": { "unicodes": { "composite": ["2666"], "secondary": ["10f219"] } }, "changes": [ "4.3.0", "5.0.0", "5.10.1", "5.10.2", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "card", "cards", "diamond suit", "game", "gem", "gemstone", "poker", "suit" ] }, "styles": ["solid"], "unicode": "f219", "label": "Diamond", "voted": false, "svg": { "solid": { "last_modified": 1684767552, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M284.3 11.7c-15.6-15.6-40.9-15.6-56.6 0l-216 216c-15.6 15.6-15.6 40.9 0 56.6l216 216c15.6 15.6 40.9 15.6 56.6 0l216-216c15.6-15.6 15.6-40.9 0-56.6l-216-216z" } }, "free": ["solid"] }, "diamond-turn-right": { "aliases": { "names": ["directions"], "unicodes": { "secondary": ["10f5eb"] } }, "changes": ["5.2.0", "5.11.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["map", "navigation", "sign", "turn"] }, "styles": ["solid"], "unicode": "f5eb", "label": "Diamond Turn Right", "voted": false, "svg": { "solid": { "last_modified": 1684766331, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M227.7 11.7c15.6-15.6 40.9-15.6 56.6 0l216 216c15.6 15.6 15.6 40.9 0 56.6l-216 216c-15.6 15.6-40.9 15.6-56.6 0l-216-216c-15.6-15.6-15.6-40.9 0-56.6l216-216zm87.6 137c-4.6-4.6-11.5-5.9-17.4-3.5s-9.9 8.3-9.9 14.8v56H224c-35.3 0-64 28.7-64 64v48c0 13.3 10.7 24 24 24s24-10.7 24-24V280c0-8.8 7.2-16 16-16h64v56c0 6.5 3.9 12.3 9.9 14.8s12.9 1.1 17.4-3.5l80-80c6.2-6.2 6.2-16.4 0-22.6l-80-80z" } }, "free": ["solid"] }, "diaspora": { "changes": ["5.6.0", "5.8.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f791", "label": "Diaspora", "voted": true, "svg": { "brands": { "last_modified": 1660014480, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M251.64 354.55c-1.4 0-88 119.9-88.7 119.9S76.34 414 76 413.25s86.6-125.7 86.6-127.4c0-2.2-129.6-44-137.6-47.1-1.3-.5 31.4-101.8 31.7-102.1.6-.7 144.4 47 145.5 47 .4 0 .9-.6 1-1.3.4-2 1-148.6 1.7-149.6.8-1.2 104.5-.7 105.1-.3 1.5 1 3.5 156.1 6.1 156.1 1.4 0 138.7-47 139.3-46.3.8.9 31.9 102.2 31.5 102.6-.9.9-140.2 47.1-140.6 48.8-.3 1.4 82.8 122.1 82.5 122.9s-85.5 63.5-86.3 63.5c-1-.2-89-125.5-90.9-125.5z" } }, "free": ["brands"] }, "dice": { "aliases": { "unicodes": { "composite": ["1f3b2"], "secondary": ["10f522"] } }, "changes": ["5.0.13", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["chance", "dice", "die", "gambling", "game", "game die", "roll"] }, "styles": ["solid"], "unicode": "f522", "label": "Dice", "voted": true, "svg": { "solid": { "last_modified": 1684767070, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M274.9 34.3c-28.1-28.1-73.7-28.1-101.8 0L34.3 173.1c-28.1 28.1-28.1 73.7 0 101.8L173.1 413.7c28.1 28.1 73.7 28.1 101.8 0L413.7 274.9c28.1-28.1 28.1-73.7 0-101.8L274.9 34.3zM200 224a24 24 0 1 1 48 0 24 24 0 1 1 -48 0zM96 200a24 24 0 1 1 0 48 24 24 0 1 1 0-48zM224 376a24 24 0 1 1 0-48 24 24 0 1 1 0 48zM352 200a24 24 0 1 1 0 48 24 24 0 1 1 0-48zM224 120a24 24 0 1 1 0-48 24 24 0 1 1 0 48zm96 328c0 35.3 28.7 64 64 64H576c35.3 0 64-28.7 64-64V256c0-35.3-28.7-64-64-64H461.7c11.6 36 3.1 77-25.4 105.5L320 413.8V448zM480 328a24 24 0 1 1 0 48 24 24 0 1 1 0-48z" } }, "free": ["solid"] }, "dice-d20": { "aliases": { "unicodes": { "secondary": ["10f6cf"] } }, "changes": ["5.4.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "Dungeons & Dragons", "chance", "d&d", "dnd", "fantasy", "gambling", "game", "roll" ] }, "styles": ["solid"], "unicode": "f6cf", "label": "Dice D20", "voted": true, "svg": { "solid": { "last_modified": 1684767070, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M48.7 125.8l53.2 31.9c7.8 4.7 17.8 2 22.2-5.9L201.6 12.1c3-5.4-.9-12.1-7.1-12.1c-1.6 0-3.2 .5-4.6 1.4L47.9 98.8c-9.6 6.6-9.2 20.9 .8 26.9zM16 171.7V295.3c0 8 10.4 11 14.7 4.4l60-92c5-7.6 2.6-17.8-5.2-22.5L40.2 158C29.6 151.6 16 159.3 16 171.7zM310.4 12.1l77.6 139.6c4.4 7.9 14.5 10.6 22.2 5.9l53.2-31.9c10-6 10.4-20.3 .8-26.9L322.1 1.4c-1.4-.9-3-1.4-4.6-1.4c-6.2 0-10.1 6.7-7.1 12.1zM496 171.7c0-12.4-13.6-20.1-24.2-13.7l-45.3 27.2c-7.8 4.7-10.1 14.9-5.2 22.5l60 92c4.3 6.7 14.7 3.6 14.7-4.4V171.7zm-49.3 246L286.1 436.6c-8.1 .9-14.1 7.8-14.1 15.9v52.8c0 3.7 3 6.8 6.8 6.8c.8 0 1.6-.1 2.4-.4l172.7-64c6.1-2.2 10.1-8 10.1-14.5c0-9.3-8.1-16.5-17.3-15.4zM233.2 512c3.7 0 6.8-3 6.8-6.8V452.6c0-8.1-6.1-14.9-14.1-15.9l-160.6-19c-9.2-1.1-17.3 6.1-17.3 15.4c0 6.5 4 12.3 10.1 14.5l172.7 64c.8 .3 1.6 .4 2.4 .4zM41.7 382.9l170.9 20.2c7.8 .9 13.4-7.5 9.5-14.3l-85.7-150c-5.9-10.4-20.7-10.8-27.3-.8L30.2 358.2c-6.5 9.9-.3 23.3 11.5 24.7zm439.6-24.8L402.9 238.1c-6.5-10-21.4-9.6-27.3 .8L290.2 388.5c-3.9 6.8 1.6 15.2 9.5 14.3l170.1-20c11.8-1.4 18-14.7 11.5-24.6zm-216.9 11l78.4-137.2c6.1-10.7-1.6-23.9-13.9-23.9H183.1c-12.3 0-20 13.3-13.9 23.9l78.4 137.2c3.7 6.4 13 6.4 16.7 0zM174.4 176H337.6c12.2 0 19.9-13.1 14-23.8l-80-144c-2.8-5.1-8.2-8.2-14-8.2h-3.2c-5.8 0-11.2 3.2-14 8.2l-80 144c-5.9 10.7 1.8 23.8 14 23.8z" } }, "free": ["solid"] }, "dice-d6": { "aliases": { "unicodes": { "secondary": ["10f6d1"] } }, "changes": ["5.4.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "Dungeons & Dragons", "chance", "d&d", "dnd", "fantasy", "gambling", "game", "roll" ] }, "styles": ["solid"], "unicode": "f6d1", "label": "Dice D6", "voted": false, "svg": { "solid": { "last_modified": 1684767070, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M201 10.3c14.3-7.8 31.6-7.8 46 0L422.3 106c5.1 2.8 8.3 8.2 8.3 14s-3.2 11.2-8.3 14L231.7 238c-4.8 2.6-10.5 2.6-15.3 0L25.7 134c-5.1-2.8-8.3-8.2-8.3-14s3.2-11.2 8.3-14L201 10.3zM23.7 170l176 96c5.1 2.8 8.3 8.2 8.3 14V496c0 5.6-3 10.9-7.8 13.8s-10.9 3-15.8 .3L25 423.1C9.6 414.7 0 398.6 0 381V184c0-5.6 3-10.9 7.8-13.8s10.9-3 15.8-.3zm400.7 0c5-2.7 11-2.6 15.8 .3s7.8 8.1 7.8 13.8V381c0 17.6-9.6 33.7-25 42.1L263.7 510c-5 2.7-11 2.6-15.8-.3s-7.8-8.1-7.8-13.8V280c0-5.9 3.2-11.2 8.3-14l176-96z" } }, "free": ["solid"] }, "dice-five": { "aliases": { "unicodes": { "composite": ["2684"], "secondary": ["10f523"] } }, "changes": ["5.0.13", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Die Face-5", "chance", "gambling", "game", "roll"] }, "styles": ["solid"], "unicode": "f523", "label": "Dice Five", "voted": true, "svg": { "solid": { "last_modified": 1684767071, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zm64 96a32 32 0 1 1 0 64 32 32 0 1 1 0-64zM96 352a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zM224 224a32 32 0 1 1 0 64 32 32 0 1 1 0-64zm64-64a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm32 160a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" } }, "free": ["solid"] }, "dice-four": { "aliases": { "unicodes": { "composite": ["2683"], "secondary": ["10f524"] } }, "changes": ["5.0.13", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Die Face-4", "chance", "gambling", "game", "roll"] }, "styles": ["solid"], "unicode": "f524", "label": "Dice Four", "voted": true, "svg": { "solid": { "last_modified": 1684767070, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M0 96C0 60.7 28.7 32 64 32H384c35.3 0 64 28.7 64 64V416c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V96zm160 64a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zM128 384a32 32 0 1 0 0-64 32 32 0 1 0 0 64zM352 160a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zM320 384a32 32 0 1 0 0-64 32 32 0 1 0 0 64z" } }, "free": ["solid"] }, "dice-one": { "aliases": { "unicodes": { "composite": ["2680"], "secondary": ["10f525"] } }, "changes": ["5.0.13", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Die Face-1", "chance", "gambling", "game", "roll"] }, "styles": ["solid"], "unicode": "f525", "label": "Dice One", "voted": true, "svg": { "solid": { "last_modified": 1684767070, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zM224 224a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" } }, "free": ["solid"] }, "dice-six": { "aliases": { "unicodes": { "composite": ["2685"], "secondary": ["10f526"] } }, "changes": ["5.0.13", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Die Face-6", "chance", "gambling", "game", "roll"] }, "styles": ["solid"], "unicode": "f526", "label": "Dice Six", "voted": true, "svg": { "solid": { "last_modified": 1684767070, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M0 96C0 60.7 28.7 32 64 32H384c35.3 0 64 28.7 64 64V416c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V96zm160 64a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zM128 288a32 32 0 1 0 0-64 32 32 0 1 0 0 64zm32 64a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zM320 192a32 32 0 1 0 0-64 32 32 0 1 0 0 64zm32 64a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zM320 384a32 32 0 1 0 0-64 32 32 0 1 0 0 64z" } }, "free": ["solid"] }, "dice-three": { "aliases": { "unicodes": { "composite": ["2682"], "secondary": ["10f527"] } }, "changes": ["5.0.13", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Die Face-3", "chance", "gambling", "game", "roll"] }, "styles": ["solid"], "unicode": "f527", "label": "Dice Three", "voted": true, "svg": { "solid": { "last_modified": 1684767071, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zm64 96a32 32 0 1 1 0 64 32 32 0 1 1 0-64zm64 128a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm128 64a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" } }, "free": ["solid"] }, "dice-two": { "aliases": { "unicodes": { "composite": ["2681"], "secondary": ["10f528"] } }, "changes": ["5.0.13", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Die Face-2", "chance", "gambling", "game", "roll"] }, "styles": ["solid"], "unicode": "f528", "label": "Dice Two", "voted": true, "svg": { "solid": { "last_modified": 1684767071, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M0 96C0 60.7 28.7 32 64 32H384c35.3 0 64 28.7 64 64V416c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V96zM352 352a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zM128 192a32 32 0 1 0 0-64 32 32 0 1 0 0 64z" } }, "free": ["solid"] }, "digg": { "changes": ["4.1.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f1a6", "label": "Digg Logo", "voted": false, "svg": { "brands": { "last_modified": 1660014468, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M81.7 172.3H0v174.4h132.7V96h-51v76.3zm0 133.4H50.9v-92.3h30.8v92.3zm297.2-133.4v174.4h81.8v28.5h-81.8V416H512V172.3H378.9zm81.8 133.4h-30.8v-92.3h30.8v92.3zm-235.6 41h82.1v28.5h-82.1V416h133.3V172.3H225.1v174.4zm51.2-133.3h30.8v92.3h-30.8v-92.3zM153.3 96h51.3v51h-51.3V96zm0 76.3h51.3v174.4h-51.3V172.3z" } }, "free": ["brands"] }, "digital-ocean": { "changes": ["5.0.0", "5.7.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f391", "label": "Digital Ocean", "voted": false, "svg": { "brands": { "last_modified": 1660014479, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M87 481.8h73.7v-73.6H87zM25.4 346.6v61.6H87v-61.6zm466.2-169.7c-23-74.2-82.4-133.3-156.6-156.6C164.9-32.8 8 93.7 8 255.9h95.8c0-101.8 101-180.5 208.1-141.7 39.7 14.3 71.5 46.1 85.8 85.7 39.1 107-39.7 207.8-141.4 208v.3h-.3V504c162.6 0 288.8-156.8 235.6-327.1zm-235.3 231v-95.3h-95.6v95.6H256v-.3z" } }, "free": ["brands"] }, "discord": { "changes": ["5.0.0", "5.15.4", "6.0.0-beta1"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f392", "label": "Discord", "voted": false, "svg": { "brands": { "last_modified": 1660014475, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M524.531,69.836a1.5,1.5,0,0,0-.764-.7A485.065,485.065,0,0,0,404.081,32.03a1.816,1.816,0,0,0-1.923.91,337.461,337.461,0,0,0-14.9,30.6,447.848,447.848,0,0,0-134.426,0,309.541,309.541,0,0,0-15.135-30.6,1.89,1.89,0,0,0-1.924-.91A483.689,483.689,0,0,0,116.085,69.137a1.712,1.712,0,0,0-.788.676C39.068,183.651,18.186,294.69,28.43,404.354a2.016,2.016,0,0,0,.765,1.375A487.666,487.666,0,0,0,176.02,479.918a1.9,1.9,0,0,0,2.063-.676A348.2,348.2,0,0,0,208.12,430.4a1.86,1.86,0,0,0-1.019-2.588,321.173,321.173,0,0,1-45.868-21.853,1.885,1.885,0,0,1-.185-3.126c3.082-2.309,6.166-4.711,9.109-7.137a1.819,1.819,0,0,1,1.9-.256c96.229,43.917,200.41,43.917,295.5,0a1.812,1.812,0,0,1,1.924.233c2.944,2.426,6.027,4.851,9.132,7.16a1.884,1.884,0,0,1-.162,3.126,301.407,301.407,0,0,1-45.89,21.83,1.875,1.875,0,0,0-1,2.611,391.055,391.055,0,0,0,30.014,48.815,1.864,1.864,0,0,0,2.063.7A486.048,486.048,0,0,0,610.7,405.729a1.882,1.882,0,0,0,.765-1.352C623.729,277.594,590.933,167.465,524.531,69.836ZM222.491,337.58c-28.972,0-52.844-26.587-52.844-59.239S193.056,219.1,222.491,219.1c29.665,0,53.306,26.82,52.843,59.239C275.334,310.993,251.924,337.58,222.491,337.58Zm195.38,0c-28.971,0-52.843-26.587-52.843-59.239S388.437,219.1,417.871,219.1c29.667,0,53.307,26.82,52.844,59.239C470.715,310.993,447.538,337.58,417.871,337.58Z" } }, "free": ["brands"] }, "discourse": { "changes": ["5.0.0", "5.0.3"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f393", "label": "Discourse", "voted": false, "svg": { "brands": { "last_modified": 1660014459, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M225.9 32C103.3 32 0 130.5 0 252.1 0 256 .1 480 .1 480l225.8-.2c122.7 0 222.1-102.3 222.1-223.9C448 134.3 348.6 32 225.9 32zM224 384c-19.4 0-37.9-4.3-54.4-12.1L88.5 392l22.9-75c-9.8-18.1-15.4-38.9-15.4-61 0-70.7 57.3-128 128-128s128 57.3 128 128-57.3 128-128 128z" } }, "free": ["brands"] }, "disease": { "aliases": { "unicodes": { "secondary": ["10f7fa"] } }, "changes": ["5.7.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "bacteria", "cancer", "coronavirus", "covid-19", "flu", "illness", "infection", "pandemic", "sickness", "virus" ] }, "styles": ["solid"], "unicode": "f7fa", "label": "Disease", "voted": false, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M236.4 61.4L227 75.5c-21.3 32-59.4 48.5-97.3 42.1l-59.6-9.9C33.4 101.6 0 129.9 .1 167.1c0 15.9 6.4 31.2 17.6 42.5l29.2 29.2c11 11 17.2 25.9 17.2 41.5c0 15.8-6.4 30.9-17.7 42L33.3 335.1C22.2 345.9 16 360.7 16 376.2c0 36.8 34.1 64.2 70.1 56.2l62.3-13.8c7.7-1.7 15.7-2.6 23.6-2.6h10c27.2 0 53.7 9.3 75 26.3L287.8 467c10.5 8.4 23.6 13 37 13c32.7 0 59.3-26.5 59.3-59.3l0-25.2c0-34.9 21.4-66.2 53.9-78.8l36.9-14.3c22.4-8.7 37.2-30.3 37.2-54.3c0-28.1-20.1-52.3-47.8-57.3l-28-5.1c-36.5-6.7-65.4-34.5-73.6-70.7l-7.1-31.5C348.9 53.4 322.1 32 291.3 32c-22 0-42.6 11-54.9 29.4zM160 192a32 32 0 1 1 0 64 32 32 0 1 1 0-64zm128 16a16 16 0 1 1 32 0 16 16 0 1 1 -32 0zm0 80a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" } }, "free": ["solid"] }, "display": { "changes": ["6.0.0-beta1", "6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Screen", "computer", "desktop", "imac"] }, "styles": ["solid"], "unicode": "e163", "label": "Display", "voted": false, "svg": { "solid": { "last_modified": 1684767341, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M64 0C28.7 0 0 28.7 0 64V352c0 35.3 28.7 64 64 64H240l-10.7 32H160c-17.7 0-32 14.3-32 32s14.3 32 32 32H416c17.7 0 32-14.3 32-32s-14.3-32-32-32H346.7L336 416H512c35.3 0 64-28.7 64-64V64c0-35.3-28.7-64-64-64H64zM512 64V352H64V64H512z" } }, "free": ["solid"] }, "divide": { "aliases": { "unicodes": { "composite": ["2797", "f7"], "secondary": ["10f529"] } }, "changes": ["5.0.13", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "Division Sign", "arithmetic", "calculus", "divide", "division", "math", "sign", "÷" ] }, "styles": ["solid"], "unicode": "f529", "label": "Divide", "voted": false, "svg": { "solid": { "last_modified": 1684767246, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M272 96a48 48 0 1 0 -96 0 48 48 0 1 0 96 0zm0 320a48 48 0 1 0 -96 0 48 48 0 1 0 96 0zM400 288c17.7 0 32-14.3 32-32s-14.3-32-32-32H48c-17.7 0-32 14.3-32 32s14.3 32 32 32H400z" } }, "free": ["solid"] }, "dna": { "aliases": { "unicodes": { "composite": ["1f9ec"], "secondary": ["10f471"] } }, "changes": ["5.0.7", "5.0.10", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "biologist", "dna", "double helix", "evolution", "gene", "genetic", "genetics", "helix", "life", "molecule", "protein" ] }, "styles": ["solid"], "unicode": "f471", "label": "Dna", "voted": false, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M416 0c17.7 0 32 14.3 32 32c0 59.8-30.3 107.5-69.4 146.6c-28 28-62.5 53.5-97.3 77.4l-2.5 1.7c-11.9 8.1-23.8 16.1-35.5 23.9l0 0 0 0 0 0-1.6 1c-6 4-11.9 7.9-17.8 11.9c-20.9 14-40.8 27.7-59.3 41.5H283.3c-9.8-7.4-20.1-14.7-30.7-22.1l7-4.7 3-2c15.1-10.1 30.9-20.6 46.7-31.6c25 18.1 48.9 37.3 69.4 57.7C417.7 372.5 448 420.2 448 480c0 17.7-14.3 32-32 32s-32-14.3-32-32H64c0 17.7-14.3 32-32 32s-32-14.3-32-32c0-59.8 30.3-107.5 69.4-146.6c28-28 62.5-53.5 97.3-77.4c-34.8-23.9-69.3-49.3-97.3-77.4C30.3 139.5 0 91.8 0 32C0 14.3 14.3 0 32 0S64 14.3 64 32H384c0-17.7 14.3-32 32-32zM338.6 384H109.4c-10.1 10.6-18.6 21.3-25.5 32H364.1c-6.8-10.7-15.3-21.4-25.5-32zM109.4 128H338.6c10.1-10.7 18.6-21.3 25.5-32H83.9c6.8 10.7 15.3 21.3 25.5 32zm55.4 48c18.4 13.8 38.4 27.5 59.3 41.5c20.9-14 40.8-27.7 59.3-41.5H164.7z" } }, "free": ["solid"] }, "dochub": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f394", "label": "DocHub", "voted": false, "svg": { "brands": { "last_modified": 1660014474, "raw": "", "viewBox": [0, 0, 416, 512], "width": 416, "height": 512, "path": "M397.9 160H256V19.6L397.9 160zM304 192v130c0 66.8-36.5 100.1-113.3 100.1H96V84.8h94.7c12 0 23.1.8 33.1 2.5v-84C212.9 1.1 201.4 0 189.2 0H0v512h189.2C329.7 512 400 447.4 400 318.1V192h-96z" } }, "free": ["brands"] }, "docker": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f395", "label": "Docker", "voted": false, "svg": { "brands": { "last_modified": 1660014465, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M349.9 236.3h-66.1v-59.4h66.1v59.4zm0-204.3h-66.1v60.7h66.1V32zm78.2 144.8H362v59.4h66.1v-59.4zm-156.3-72.1h-66.1v60.1h66.1v-60.1zm78.1 0h-66.1v60.1h66.1v-60.1zm276.8 100c-14.4-9.7-47.6-13.2-73.1-8.4-3.3-24-16.7-44.9-41.1-63.7l-14-9.3-9.3 14c-18.4 27.8-23.4 73.6-3.7 103.8-8.7 4.7-25.8 11.1-48.4 10.7H2.4c-8.7 50.8 5.8 116.8 44 162.1 37.1 43.9 92.7 66.2 165.4 66.2 157.4 0 273.9-72.5 328.4-204.2 21.4.4 67.6.1 91.3-45.2 1.5-2.5 6.6-13.2 8.5-17.1l-13.3-8.9zm-511.1-27.9h-66v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm-78.1-72.1h-66.1v60.1h66.1v-60.1z" } }, "free": ["brands"] }, "dog": { "aliases": { "unicodes": { "composite": ["1f415"], "secondary": ["10f6d3"] } }, "changes": [ "5.4.0", "5.12.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "animal", "canine", "dog", "fauna", "mammal", "pet", "pooch", "puppy", "woof" ] }, "styles": ["solid"], "unicode": "f6d3", "label": "Dog", "voted": false, "svg": { "solid": { "last_modified": 1684768130, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M309.6 158.5L332.7 19.8C334.6 8.4 344.5 0 356.1 0c7.5 0 14.5 3.5 19 9.5L392 32h52.1c12.7 0 24.9 5.1 33.9 14.1L496 64h56c13.3 0 24 10.7 24 24v24c0 44.2-35.8 80-80 80H464 448 426.7l-5.1 30.5-112-64zM416 256.1L416 480c0 17.7-14.3 32-32 32H352c-17.7 0-32-14.3-32-32V364.8c-24 12.3-51.2 19.2-80 19.2s-56-6.9-80-19.2V480c0 17.7-14.3 32-32 32H96c-17.7 0-32-14.3-32-32V249.8c-28.8-10.9-51.4-35.3-59.2-66.5L1 167.8c-4.3-17.1 6.1-34.5 23.3-38.8s34.5 6.1 38.8 23.3l3.9 15.5C70.5 182 83.3 192 98 192h30 16H303.8L416 256.1zM464 80a16 16 0 1 0 -32 0 16 16 0 1 0 32 0z" } }, "free": ["solid"] }, "dollar-sign": { "aliases": { "names": ["dollar", "usd"], "unicodes": { "composite": ["1f4b2", "f155"], "primary": ["f155"], "secondary": ["1024", "10f155"] } }, "changes": [ "3.2.0", "5.0.0", "5.0.9", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Dollar Sign", "currency", "dollar", "heavy dollar sign", "money" ] }, "styles": ["solid"], "unicode": "24", "label": "Dollar Sign", "voted": false, "svg": { "solid": { "last_modified": 1684766474, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M160 0c17.7 0 32 14.3 32 32V67.7c1.6 .2 3.1 .4 4.7 .7c.4 .1 .7 .1 1.1 .2l48 8.8c17.4 3.2 28.9 19.9 25.7 37.2s-19.9 28.9-37.2 25.7l-47.5-8.7c-31.3-4.6-58.9-1.5-78.3 6.2s-27.2 18.3-29 28.1c-2 10.7-.5 16.7 1.2 20.4c1.8 3.9 5.5 8.3 12.8 13.2c16.3 10.7 41.3 17.7 73.7 26.3l2.9 .8c28.6 7.6 63.6 16.8 89.6 33.8c14.2 9.3 27.6 21.9 35.9 39.5c8.5 17.9 10.3 37.9 6.4 59.2c-6.9 38-33.1 63.4-65.6 76.7c-13.7 5.6-28.6 9.2-44.4 11V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V445.1c-.4-.1-.9-.1-1.3-.2l-.2 0 0 0c-24.4-3.8-64.5-14.3-91.5-26.3c-16.1-7.2-23.4-26.1-16.2-42.2s26.1-23.4 42.2-16.2c20.9 9.3 55.3 18.5 75.2 21.6c31.9 4.7 58.2 2 76-5.3c16.9-6.9 24.6-16.9 26.8-28.9c1.9-10.6 .4-16.7-1.3-20.4c-1.9-4-5.6-8.4-13-13.3c-16.4-10.7-41.5-17.7-74-26.3l-2.8-.7 0 0C119.4 279.3 84.4 270 58.4 253c-14.2-9.3-27.5-22-35.8-39.6c-8.4-17.9-10.1-37.9-6.1-59.2C23.7 116 52.3 91.2 84.8 78.3c13.3-5.3 27.9-8.9 43.2-11V32c0-17.7 14.3-32 32-32z" } }, "free": ["solid"] }, "dolly": { "aliases": { "names": ["dolly-box"], "unicodes": { "secondary": ["10f472"] } }, "changes": ["5.0.7", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["carry", "shipping", "transport"] }, "styles": ["solid"], "unicode": "f472", "label": "Dolly", "voted": false, "svg": { "solid": { "last_modified": 1684767443, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M0 32C0 14.3 14.3 0 32 0h72.9c27.5 0 52 17.6 60.7 43.8L257.7 320c30.1 .5 56.8 14.9 74 37l202.1-67.4c16.8-5.6 34.9 3.5 40.5 20.2s-3.5 34.9-20.2 40.5L352 417.7c-.9 52.2-43.5 94.3-96 94.3c-53 0-96-43-96-96c0-30.8 14.5-58.2 37-75.8L104.9 64H32C14.3 64 0 49.7 0 32zM244.8 134.5c-5.5-16.8 3.7-34.9 20.5-40.3L311 79.4l19.8 60.9 60.9-19.8L371.8 59.6l45.7-14.8c16.8-5.5 34.9 3.7 40.3 20.5l49.4 152.2c5.5 16.8-3.7 34.9-20.5 40.3L334.5 307.2c-16.8 5.5-34.9-3.7-40.3-20.5L244.8 134.5z" } }, "free": ["solid"] }, "dong-sign": { "changes": ["6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Dong Sign", "currency"] }, "styles": ["solid"], "unicode": "e169", "label": "Dong Sign", "voted": false, "svg": { "solid": { "last_modified": 1684766476, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M288 32c-17.7 0-32 14.3-32 32l-32 0c-17.7 0-32 14.3-32 32s14.3 32 32 32h32v49.1c-18.8-10.9-40.7-17.1-64-17.1c-70.7 0-128 57.3-128 128s57.3 128 128 128c24.5 0 47.4-6.9 66.8-18.8c5 11.1 16.2 18.8 29.2 18.8c17.7 0 32-14.3 32-32V288 128c17.7 0 32-14.3 32-32s-14.3-32-32-32c0-17.7-14.3-32-32-32zM128 288a64 64 0 1 1 128 0 64 64 0 1 1 -128 0zM32 448c-17.7 0-32 14.3-32 32s14.3 32 32 32H352c17.7 0 32-14.3 32-32s-14.3-32-32-32H32z" } }, "free": ["solid"] }, "door-closed": { "aliases": { "unicodes": { "composite": ["1f6aa"], "secondary": ["10f52a"] } }, "changes": ["5.0.13", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["doo", "door", "enter", "exit", "locked"] }, "styles": ["solid"], "unicode": "f52a", "label": "Door Closed", "voted": true, "svg": { "solid": { "last_modified": 1684767442, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M96 64c0-35.3 28.7-64 64-64H416c35.3 0 64 28.7 64 64V448h64c17.7 0 32 14.3 32 32s-14.3 32-32 32H432 144 32c-17.7 0-32-14.3-32-32s14.3-32 32-32H96V64zM384 288a32 32 0 1 0 0-64 32 32 0 1 0 0 64z" } }, "free": ["solid"] }, "door-open": { "aliases": { "unicodes": { "secondary": ["10f52b"] } }, "changes": ["5.0.13", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["enter", "exit", "welcome"] }, "styles": ["solid"], "unicode": "f52b", "label": "Door Open", "voted": true, "svg": { "solid": { "last_modified": 1684767444, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M320 32c0-9.9-4.5-19.2-12.3-25.2S289.8-1.4 280.2 1l-179.9 45C79 51.3 64 70.5 64 92.5V448H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H96 288h32V480 32zM256 256c0 17.7-10.7 32-24 32s-24-14.3-24-32s10.7-32 24-32s24 14.3 24 32zm96-128h96V480c0 17.7 14.3 32 32 32h64c17.7 0 32-14.3 32-32s-14.3-32-32-32H512V128c0-35.3-28.7-64-64-64H352v64z" } }, "free": ["solid"] }, "dove": { "aliases": { "unicodes": { "composite": ["1f54a"], "secondary": ["10f4ba"] } }, "changes": [ "5.0.9", "5.10.1", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["bird", "dove", "fauna", "fly", "flying", "peace", "war"] }, "styles": ["solid"], "unicode": "f4ba", "label": "Dove", "voted": false, "svg": { "solid": { "last_modified": 1684768130, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M160.8 96.5c14 17 31 30.9 49.5 42.2c25.9 15.8 53.7 25.9 77.7 31.6V138.8C265.8 108.5 250 71.5 248.6 28c-.4-11.3-7.5-21.5-18.4-24.4c-7.6-2-15.8-.2-21 5.8c-13.3 15.4-32.7 44.6-48.4 87.2zM320 144v30.6l0 0v1.3l0 0 0 32.1c-60.8-5.1-185-43.8-219.3-157.2C97.4 40 87.9 32 76.6 32c-7.9 0-15.3 3.9-18.8 11C46.8 65.9 32 112.1 32 176c0 116.9 80.1 180.5 118.4 202.8L11.8 416.6C6.7 418 2.6 421.8 .9 426.8s-.8 10.6 2.3 14.8C21.7 466.2 77.3 512 160 512c3.6 0 7.2-1.2 10-3.5L245.6 448H320c88.4 0 160-71.6 160-160V128l29.9-44.9c1.3-2 2.1-4.4 2.1-6.8c0-6.8-5.5-12.3-12.3-12.3H400c-44.2 0-80 35.8-80 80zm80-16a16 16 0 1 1 0 32 16 16 0 1 1 0-32z" } }, "free": ["solid"] }, "down-left-and-up-right-to-center": { "aliases": { "names": ["compress-alt"], "unicodes": { "secondary": ["10f422"] } }, "changes": [ "1.0.0", "5.0.0", "5.12.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "collapse", "fullscreen", "minimize", "move", "resize", "shrink", "smaller" ] }, "styles": ["solid"], "unicode": "f422", "label": "Down Left And Up Right To Center", "voted": false, "svg": { "solid": { "last_modified": 1684766332, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M439 7c9.4-9.4 24.6-9.4 33.9 0l32 32c9.4 9.4 9.4 24.6 0 33.9l-87 87 39 39c6.9 6.9 8.9 17.2 5.2 26.2s-12.5 14.8-22.2 14.8H296c-13.3 0-24-10.7-24-24V72c0-9.7 5.8-18.5 14.8-22.2s19.3-1.7 26.2 5.2l39 39L439 7zM72 272H216c13.3 0 24 10.7 24 24V440c0 9.7-5.8 18.5-14.8 22.2s-19.3 1.7-26.2-5.2l-39-39L73 505c-9.4 9.4-24.6 9.4-33.9 0L7 473c-9.4-9.4-9.4-24.6 0-33.9l87-87L55 313c-6.9-6.9-8.9-17.2-5.2-26.2s12.5-14.8 22.2-14.8z" } }, "free": ["solid"] }, "down-long": { "aliases": { "names": ["long-arrow-alt-down"], "unicodes": { "secondary": ["10f309"] } }, "changes": ["5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["download", "long-arrow-down"] }, "styles": ["solid"], "unicode": "f309", "label": "Down Long", "voted": false, "svg": { "solid": { "last_modified": 1684766329, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M2 334.5c-3.8 8.8-2 19 4.6 26l136 144c4.5 4.8 10.8 7.5 17.4 7.5s12.9-2.7 17.4-7.5l136-144c6.6-7 8.4-17.2 4.6-26s-12.5-14.5-22-14.5l-72 0 0-288c0-17.7-14.3-32-32-32L128 0C110.3 0 96 14.3 96 32l0 288-72 0c-9.6 0-18.2 5.7-22 14.5z" } }, "free": ["solid"] }, "download": { "aliases": { "unicodes": { "secondary": ["10f019"] } }, "changes": ["1.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["export", "hard drive", "save", "transfer"] }, "styles": ["solid"], "unicode": "f019", "label": "Download", "voted": false, "svg": { "solid": { "last_modified": 1684767342, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M288 32c0-17.7-14.3-32-32-32s-32 14.3-32 32V274.7l-73.4-73.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l128 128c12.5 12.5 32.8 12.5 45.3 0l128-128c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L288 274.7V32zM64 352c-35.3 0-64 28.7-64 64v32c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V416c0-35.3-28.7-64-64-64H346.5l-45.3 45.3c-25 25-65.5 25-90.5 0L165.5 352H64zm368 56a24 24 0 1 1 0 48 24 24 0 1 1 0-48z" } }, "free": ["solid"] }, "draft2digital": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f396", "label": "Draft2digital", "voted": false, "svg": { "brands": { "last_modified": 1660014472, "raw": "", "viewBox": [0, 0, 480, 512], "width": 480, "height": 512, "path": "M480 398.1l-144-82.2v64.7h-91.3c30.8-35 81.8-95.9 111.8-149.3 35.2-62.6 16.1-123.4-12.8-153.3-4.4-4.6-62.2-62.9-166-41.2-59.1 12.4-89.4 43.4-104.3 67.3-13.1 20.9-17 39.8-18.2 47.7-5.5 33 19.4 67.1 56.7 67.1 31.7 0 57.3-25.7 57.3-57.4 0-27.1-19.7-52.1-48-56.8 1.8-7.3 17.7-21.1 26.3-24.7 41.1-17.3 78 5.2 83.3 33.5 8.3 44.3-37.1 90.4-69.7 127.6C84.5 328.1 18.3 396.8 0 415.9l336-.1V480zM369.9 371l47.1 27.2-47.1 27.2zM134.2 161.4c0 12.4-10 22.4-22.4 22.4s-22.4-10-22.4-22.4 10-22.4 22.4-22.4 22.4 10.1 22.4 22.4zM82.5 380.5c25.6-27.4 97.7-104.7 150.8-169.9 35.1-43.1 40.3-82.4 28.4-112.7-7.4-18.8-17.5-30.2-24.3-35.7 45.3 2.1 68 23.4 82.2 38.3 0 0 42.4 48.2 5.8 113.3-37 65.9-110.9 147.5-128.5 166.7z" } }, "free": ["brands"] }, "dragon": { "aliases": { "unicodes": { "composite": ["1f409"], "secondary": ["10f6d5"] } }, "changes": ["5.4.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "Dungeons & Dragons", "d&d", "dnd", "dragon", "fairy tale", "fantasy", "fire", "lizard", "serpent" ] }, "styles": ["solid"], "unicode": "f6d5", "label": "Dragon", "voted": false, "svg": { "solid": { "last_modified": 1684768130, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M352 124.5l-51.9-13c-6.5-1.6-11.3-7.1-12-13.8s2.8-13.1 8.7-16.1l40.8-20.4L294.4 28.8c-5.5-4.1-7.8-11.3-5.6-17.9S297.1 0 304 0H416h32 16c30.2 0 58.7 14.2 76.8 38.4l57.6 76.8c6.2 8.3 9.6 18.4 9.6 28.8c0 26.5-21.5 48-48 48H538.5c-17 0-33.3-6.7-45.3-18.7L480 160H448v21.5c0 24.8 12.8 47.9 33.8 61.1l106.6 66.6c32.1 20.1 51.6 55.2 51.6 93.1C640 462.9 590.9 512 530.2 512H496 432 32.3c-3.3 0-6.6-.4-9.6-1.4C13.5 507.8 6 501 2.4 492.1C1 488.7 .2 485.2 0 481.4c-.2-3.7 .3-7.3 1.3-10.7c2.8-9.2 9.6-16.7 18.6-20.4c3-1.2 6.2-2 9.5-2.2L433.3 412c8.3-.7 14.7-7.7 14.7-16.1c0-4.3-1.7-8.4-4.7-11.4l-44.4-44.4c-30-30-46.9-70.7-46.9-113.1V181.5v-57zM512 72.3c0-.1 0-.2 0-.3s0-.2 0-.3v.6zm-1.3 7.4L464.3 68.1c-.2 1.3-.3 2.6-.3 3.9c0 13.3 10.7 24 24 24c10.6 0 19.5-6.8 22.7-16.3zM130.9 116.5c16.3-14.5 40.4-16.2 58.5-4.1l130.6 87V227c0 32.8 8.4 64.8 24 93H112c-6.7 0-12.7-4.2-15-10.4s-.5-13.3 4.6-17.7L171 232.3 18.4 255.8c-7 1.1-13.9-2.6-16.9-9s-1.5-14.1 3.8-18.8L130.9 116.5z" } }, "free": ["solid"] }, "draw-polygon": { "aliases": { "unicodes": { "secondary": ["10f5ee"] } }, "changes": ["5.2.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["anchors", "lines", "object", "render", "shape"] }, "styles": ["solid"], "unicode": "f5ee", "label": "Draw Polygon", "voted": false, "svg": { "solid": { "last_modified": 1684767366, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M96 151.4V360.6c9.7 5.6 17.8 13.7 23.4 23.4H328.6c0-.1 .1-.2 .1-.3l-4.5-7.9-32-56 0 0c-1.4 .1-2.8 .1-4.2 .1c-35.3 0-64-28.7-64-64s28.7-64 64-64c1.4 0 2.8 0 4.2 .1l0 0 32-56 4.5-7.9-.1-.3H119.4c-5.6 9.7-13.7 17.8-23.4 23.4zM384.3 352c35.2 .2 63.7 28.7 63.7 64c0 35.3-28.7 64-64 64c-23.7 0-44.4-12.9-55.4-32H119.4c-11.1 19.1-31.7 32-55.4 32c-35.3 0-64-28.7-64-64c0-23.7 12.9-44.4 32-55.4V151.4C12.9 140.4 0 119.7 0 96C0 60.7 28.7 32 64 32c23.7 0 44.4 12.9 55.4 32H328.6c11.1-19.1 31.7-32 55.4-32c35.3 0 64 28.7 64 64c0 35.3-28.5 63.8-63.7 64l-4.5 7.9-32 56-2.3 4c4.2 8.5 6.5 18 6.5 28.1s-2.3 19.6-6.5 28.1l2.3 4 32 56 4.5 7.9z" } }, "free": ["solid"] }, "dribbble": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f17d", "label": "Dribbble", "voted": false, "svg": { "brands": { "last_modified": 1660014461, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 8C119.252 8 8 119.252 8 256s111.252 248 248 248 248-111.252 248-248S392.748 8 256 8zm163.97 114.366c29.503 36.046 47.369 81.957 47.835 131.955-6.984-1.477-77.018-15.682-147.502-6.818-5.752-14.041-11.181-26.393-18.617-41.614 78.321-31.977 113.818-77.482 118.284-83.523zM396.421 97.87c-3.81 5.427-35.697 48.286-111.021 76.519-34.712-63.776-73.185-116.168-79.04-124.008 67.176-16.193 137.966 1.27 190.061 47.489zm-230.48-33.25c5.585 7.659 43.438 60.116 78.537 122.509-99.087 26.313-186.36 25.934-195.834 25.809C62.38 147.205 106.678 92.573 165.941 64.62zM44.17 256.323c0-2.166.043-4.322.108-6.473 9.268.19 111.92 1.513 217.706-30.146 6.064 11.868 11.857 23.915 17.174 35.949-76.599 21.575-146.194 83.527-180.531 142.306C64.794 360.405 44.17 310.73 44.17 256.323zm81.807 167.113c22.127-45.233 82.178-103.622 167.579-132.756 29.74 77.283 42.039 142.053 45.189 160.638-68.112 29.013-150.015 21.053-212.768-27.882zm248.38 8.489c-2.171-12.886-13.446-74.897-41.152-151.033 66.38-10.626 124.7 6.768 131.947 9.055-9.442 58.941-43.273 109.844-90.795 141.978z" } }, "free": ["brands"] }, "dropbox": { "changes": ["3.2.0", "5.0.0", "5.0.1"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f16b", "label": "Dropbox", "voted": false, "svg": { "brands": { "last_modified": 1660014466, "raw": "", "viewBox": [0, 0, 528, 512], "width": 528, "height": 512, "path": "M264.4 116.3l-132 84.3 132 84.3-132 84.3L0 284.1l132.3-84.3L0 116.3 132.3 32l132.1 84.3zM131.6 395.7l132-84.3 132 84.3-132 84.3-132-84.3zm132.8-111.6l132-84.3-132-83.6L395.7 32 528 116.3l-132.3 84.3L528 284.8l-132.3 84.3-131.3-85z" } }, "free": ["brands"] }, "droplet": { "aliases": { "names": ["tint"], "unicodes": { "composite": ["1f4a7"], "secondary": ["10f043"] } }, "changes": [ "1.0.0", "5.0.0", "5.1.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.2.1", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "cold", "color", "comic", "drop", "droplet", "raindrop", "sweat", "waterdrop" ] }, "styles": ["solid"], "unicode": "f043", "label": "Droplet", "voted": false, "svg": { "solid": { "last_modified": 1684767661, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M192 512C86 512 0 426 0 320C0 228.8 130.2 57.7 166.6 11.7C172.6 4.2 181.5 0 191.1 0h1.8c9.6 0 18.5 4.2 24.5 11.7C253.8 57.7 384 228.8 384 320c0 106-86 192-192 192zM96 336c0-8.8-7.2-16-16-16s-16 7.2-16 16c0 61.9 50.1 112 112 112c8.8 0 16-7.2 16-16s-7.2-16-16-16c-44.2 0-80-35.8-80-80z" } }, "free": ["solid"] }, "droplet-slash": { "aliases": { "names": ["tint-slash"], "unicodes": { "secondary": ["10f5c7"] } }, "changes": [ "5.1.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.2.1", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["color", "drop", "droplet", "raindrop", "waterdrop"] }, "styles": ["solid"], "unicode": "f5c7", "label": "Droplet Slash", "voted": false, "svg": { "solid": { "last_modified": 1684767662, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M320 512c53.2 0 101.4-21.6 136.1-56.6l-298.3-235C140 257.1 128 292.3 128 320c0 106 86 192 192 192zM505.2 370.7c4.4-16.1 6.8-33.1 6.8-50.7c0-91.2-130.2-262.3-166.6-308.3C339.4 4.2 330.5 0 320.9 0h-1.8c-9.6 0-18.5 4.2-24.5 11.7C277.8 33 240.7 81.3 205.8 136L38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7L505.2 370.7zM224 336c0 44.2 35.8 80 80 80c8.8 0 16 7.2 16 16s-7.2 16-16 16c-61.9 0-112-50.1-112-112c0-8.8 7.2-16 16-16s16 7.2 16 16z" } }, "free": ["solid"] }, "drum": { "aliases": { "unicodes": { "composite": ["1f941"], "secondary": ["10f569"] } }, "changes": ["5.1.0", "5.11.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "drum", "drumsticks", "instrument", "music", "percussion", "snare", "sound" ] }, "styles": ["solid"], "unicode": "f569", "label": "Drum", "voted": true, "svg": { "solid": { "last_modified": 1684766675, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M501.2 76.1c11.1-7.3 14.2-22.1 6.9-33.2s-22.1-14.2-33.2-6.9L370.2 104.5C335.8 98.7 297 96 256 96C114.6 96 0 128 0 208V368c0 31.3 27.4 58.8 72 78.7V344c0-13.3 10.7-24 24-24s24 10.7 24 24V463.4c33 8.9 71.1 14.5 112 16.1V376c0-13.3 10.7-24 24-24s24 10.7 24 24V479.5c40.9-1.6 79-7.2 112-16.1V344c0-13.3 10.7-24 24-24s24 10.7 24 24V446.7c44.6-19.9 72-47.4 72-78.7V208c0-41.1-30.2-69.5-78.8-87.4l67.9-44.5zM307.4 145.6l-64.6 42.3c-11.1 7.3-14.2 22.1-6.9 33.2s22.1 14.2 33.2 6.9l111.1-72.8c14.7 3.2 27.9 7 39.4 11.5C458.4 181.8 464 197.4 464 208c0 .8-2.7 17.2-46 35.9C379.1 260.7 322 272 256 272s-123.1-11.3-162-28.1C50.7 225.2 48 208.8 48 208c0-10.6 5.6-26.2 44.4-41.3C130.6 151.9 187.8 144 256 144c18 0 35.1 .5 51.4 1.6z" } }, "free": ["solid"] }, "drum-steelpan": { "aliases": { "unicodes": { "secondary": ["10f56a"] } }, "changes": ["5.1.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "calypso", "instrument", "music", "percussion", "reggae", "snare", "sound", "steel", "tropical" ] }, "styles": ["solid"], "unicode": "f56a", "label": "Drum Steelpan", "voted": false, "svg": { "solid": { "last_modified": 1684766676, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M288 32c159.1 0 288 48 288 128V352c0 80-128.9 128-288 128S0 432 0 352V160C0 80 128.9 32 288 32zM528 160c0-9.9-8-29.9-55-49.8c-18.6-7.9-40.9-14.4-66-19.4l-27.8 43.6c-7.3 11.5-11.2 24.8-11.2 38.4c0 17.5 6.4 34.4 18.1 47.5l9.8 11c29.8-5.2 55.9-12.5 77.2-21.5c47.1-19.9 55-39.9 55-49.8zM349.2 237.3c-8-26.2-32.4-45.3-61.2-45.3s-53.3 19.1-61.2 45.3c19.4 1.7 39.9 2.7 61.2 2.7s41.8-.9 61.2-2.7zM169 90.8c-25.2 5-47.4 11.6-66 19.4C56 130.1 48 150.1 48 160s8 29.9 55 49.8c21.3 9 47.4 16.3 77.2 21.5l9.8-11c11.6-13.1 18.1-30 18.1-47.5c0-13.6-3.9-26.9-11.2-38.4L169 90.8zm56.3-8C224.5 87 224 91.5 224 96c0 35.3 28.7 64 64 64s64-28.7 64-64c0-4.5-.5-9-1.4-13.2C330.8 81 309.8 80 288 80s-42.8 1-62.6 2.8z" } }, "free": ["solid"] }, "drumstick-bite": { "aliases": { "unicodes": { "secondary": ["10f6d7"] } }, "changes": ["5.4.0", "5.7.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["bone", "chicken", "leg", "meat", "poultry", "turkey"] }, "styles": ["solid"], "unicode": "f6d7", "label": "Drumstick Bite", "voted": false, "svg": { "solid": { "last_modified": 1684767419, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M160 265.2c0 8.5-3.4 16.6-9.4 22.6l-26.8 26.8c-12.3 12.3-32.5 11.4-49.4 7.2C69.8 320.6 65 320 60 320c-33.1 0-60 26.9-60 60s26.9 60 60 60c6.3 0 12 5.7 12 12c0 33.1 26.9 60 60 60s60-26.9 60-60c0-5-.6-9.8-1.8-14.5c-4.2-16.9-5.2-37.1 7.2-49.4l26.8-26.8c6-6 14.1-9.4 22.6-9.4H336c6.3 0 12.4-.3 18.5-1c11.9-1.2 16.4-15.5 10.8-26c-8.5-15.8-13.3-33.8-13.3-53c0-61.9 50.1-112 112-112c8 0 15.7 .8 23.2 2.4c11.7 2.5 24.1-5.9 22-17.6C494.5 62.5 422.5 0 336 0C238.8 0 160 78.8 160 176v89.2z" } }, "free": ["solid"] }, "drupal": { "changes": ["4.1.0", "5.0.0", "6.0.0-beta1"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f1a9", "label": "Drupal Logo", "voted": false, "svg": { "brands": { "last_modified": 1660014481, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M303.973,108.136C268.2,72.459,234.187,38.35,224.047,0c-9.957,38.35-44.25,72.459-80.019,108.136C90.467,161.7,29.716,222.356,29.716,313.436c-2.337,107.3,82.752,196.18,190.053,198.517S415.948,429.2,418.285,321.9q.091-4.231,0-8.464C418.285,222.356,357.534,161.7,303.973,108.136Zm-174.326,223a130.282,130.282,0,0,0-15.211,24.153,4.978,4.978,0,0,1-3.319,2.766h-1.659c-4.333,0-9.219-8.481-9.219-8.481h0c-1.29-2.028-2.489-4.149-3.687-6.361l-.83-1.752c-11.247-25.72-1.475-62.318-1.475-62.318h0a160.585,160.585,0,0,1,23.231-49.873A290.8,290.8,0,0,1,138.5,201.613l9.219,9.219,43.512,44.434a4.979,4.979,0,0,1,0,6.638L145.78,312.33h0Zm96.612,127.311a67.2,67.2,0,0,1-49.781-111.915c14.2-16.871,31.528-33.464,50.334-55.313,22.309,23.785,36.875,40.1,51.164,57.986a28.413,28.413,0,0,1,2.95,4.425,65.905,65.905,0,0,1,11.984,37.981,66.651,66.651,0,0,1-66.466,66.836ZM352.371,351.6h0a7.743,7.743,0,0,1-6.176,5.347H344.9a11.249,11.249,0,0,1-6.269-5.07h0a348.21,348.21,0,0,0-39.456-48.952L281.387,284.49,222.3,223.185a497.888,497.888,0,0,1-35.4-36.322,12.033,12.033,0,0,0-.922-1.382,35.4,35.4,0,0,1-4.7-9.219V174.51a31.346,31.346,0,0,1,9.218-27.656c11.432-11.431,22.955-22.954,33.833-34.939,11.984,13.275,24.8,26,37.428,38.627h0a530.991,530.991,0,0,1,69.6,79.1,147.494,147.494,0,0,1,27.011,83.8A134.109,134.109,0,0,1,352.371,351.6Z" } }, "free": ["brands"] }, "dumbbell": { "aliases": { "unicodes": { "secondary": ["10f44b"] } }, "changes": ["5.0.5", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["exercise", "gym", "strength", "weight", "weight-lifting"] }, "styles": ["solid"], "unicode": "f44b", "label": "Dumbbell", "voted": false, "svg": { "solid": { "last_modified": 1684767070, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M96 64c0-17.7 14.3-32 32-32h32c17.7 0 32 14.3 32 32V224v64V448c0 17.7-14.3 32-32 32H128c-17.7 0-32-14.3-32-32V384H64c-17.7 0-32-14.3-32-32V288c-17.7 0-32-14.3-32-32s14.3-32 32-32V160c0-17.7 14.3-32 32-32H96V64zm448 0v64h32c17.7 0 32 14.3 32 32v64c17.7 0 32 14.3 32 32s-14.3 32-32 32v64c0 17.7-14.3 32-32 32H544v64c0 17.7-14.3 32-32 32H480c-17.7 0-32-14.3-32-32V288 224 64c0-17.7 14.3-32 32-32h32c17.7 0 32 14.3 32 32zM416 224v64H224V224H416z" } }, "free": ["solid"] }, "dumpster": { "aliases": { "unicodes": { "secondary": ["10f793"] } }, "changes": ["5.6.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["alley", "bin", "commercial", "trash", "waste"] }, "styles": ["solid"], "unicode": "f793", "label": "Dumpster", "voted": true, "svg": { "solid": { "last_modified": 1684767443, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M49.7 32c-10.5 0-19.8 6.9-22.9 16.9L.9 133c-.6 2-.9 4.1-.9 6.1C0 150.7 9.3 160 20.9 160h94L140.5 32H49.7zM272 160V32H173.1L147.5 160H272zm32 0H428.5L402.9 32H304V160zm157.1 0h94c11.5 0 20.9-9.3 20.9-20.9c0-2.1-.3-4.1-.9-6.1L549.2 48.9C546.1 38.9 536.8 32 526.3 32H435.5l25.6 128zM32 192l4 32H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H44L64 448c0 17.7 14.3 32 32 32s32-14.3 32-32H448c0 17.7 14.3 32 32 32s32-14.3 32-32l20-160h12c17.7 0 32-14.3 32-32s-14.3-32-32-32h-4l4-32H32z" } }, "free": ["solid"] }, "dumpster-fire": { "aliases": { "unicodes": { "secondary": ["10f794"] } }, "changes": ["5.6.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "alley", "bin", "commercial", "danger", "dangerous", "euphemism", "flame", "heat", "hot", "trash", "waste" ] }, "styles": ["solid"], "unicode": "f794", "label": "Dumpster Fire", "voted": true, "svg": { "solid": { "last_modified": 1684767442, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M49.7 32c-10.5 0-19.8 6.9-22.9 16.9L.9 133c-.6 2-.9 4.1-.9 6.1C0 150.7 9.3 160 20.9 160h94L140.5 32H49.7zM272 160V32H173.1L147.5 160H272zm32 0h58c15.1-18.1 32.1-35.7 50.5-52.1c1.5-1.4 3.2-2.6 4.8-3.8L402.9 32H304V160zm209.9-23.7c17.4-15.8 43.9-16.2 61.7-1.2c-.1-.7-.3-1.4-.5-2.1L549.2 48.9C546.1 38.9 536.8 32 526.3 32H435.5l12.8 64.2c9.6 1 19 4.9 26.6 11.8c11.7 10.6 23 21.6 33.9 33.1c1.6-1.6 3.3-3.2 5-4.8zM325.2 210.7c3.8-6.2 7.9-12.5 12.3-18.7H32l4 32H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H44L64 448c0 17.7 14.3 32 32 32s32-14.3 32-32H337.6c-31-34.7-49.6-80.6-49.6-129.9c0-35.2 16.3-73.6 37.2-107.4zm128.4-78.9c-2.8-2.5-6.3-3.7-9.8-3.8c-3.6 0-7.2 1.2-10 3.7c-33.2 29.7-61.4 63.4-81.4 95.8c-19.7 31.9-32.4 66.2-32.4 92.6C320 407.9 390.3 480 480 480c88.7 0 160-72 160-159.8c0-20.2-9.6-50.9-24.2-79c-14.8-28.5-35.7-58.5-60.4-81.1c-5.6-5.1-14.4-5.2-20 0c-9.6 8.8-18.6 19.6-26.5 29.5c-17.3-20.7-35.8-39.9-55.5-57.7zM530 401c-15 10-31 15-49 15c-45 0-81-29-81-78c0-24 15-45 45-82c4 5 62 79 62 79l36-42c3 4 5 8 7 12c18 33 10 75-20 96z" } }, "free": ["solid"] }, "dungeon": { "aliases": { "unicodes": { "secondary": ["10f6d9"] } }, "changes": [ "5.4.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Dungeons & Dragons", "building", "d&d", "dnd", "door", "entrance", "fantasy", "gate" ] }, "styles": ["solid"], "unicode": "f6d9", "label": "Dungeon", "voted": false, "svg": { "solid": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M336.6 156.5c1.3 1.1 2.7 2.2 3.9 3.3c9.3 8.2 23 10.5 33.4 3.6l67.6-45.1c11.4-7.6 14.2-23.2 5.1-33.4C430 66.6 410.9 50.6 389.7 37.6c-11.9-7.3-26.9-1.4-32.1 11.6l-30.5 76.2c-4.5 11.1 .2 23.6 9.5 31.2zM328 36.8c5.1-12.8-1.6-27.4-15-30.5C294.7 2.2 275.6 0 256 0s-38.7 2.2-57 6.4C185.5 9.4 178.8 24 184 36.8l30.3 75.8c4.5 11.3 16.8 17.2 29 16c4.2-.4 8.4-.6 12.7-.6s8.6 .2 12.7 .6c12.1 1.2 24.4-4.7 29-16L328 36.8zM65.5 85c-9.1 10.2-6.3 25.8 5.1 33.4l67.6 45.1c10.3 6.9 24.1 4.6 33.4-3.6c1.3-1.1 2.6-2.3 4-3.3c9.3-7.5 13.9-20.1 9.5-31.2L154.4 49.2c-5.2-12.9-20.3-18.8-32.1-11.6C101.1 50.6 82 66.6 65.5 85zm314 137.1c.9 3.3 1.7 6.6 2.3 10c2.5 13 13 23.9 26.2 23.9h80c13.3 0 24.1-10.8 22.9-24c-2.5-27.2-9.3-53.2-19.7-77.3c-5.5-12.9-21.4-16.6-33.1-8.9l-68.6 45.7c-9.8 6.5-13.2 19.2-10 30.5zM53.9 145.8c-11.6-7.8-27.6-4-33.1 8.9C10.4 178.8 3.6 204.8 1.1 232c-1.2 13.2 9.6 24 22.9 24h80c13.3 0 23.8-10.8 26.2-23.9c.6-3.4 1.4-6.7 2.3-10c3.1-11.4-.2-24-10-30.5L53.9 145.8zM104 288H24c-13.3 0-24 10.7-24 24v48c0 13.3 10.7 24 24 24h80c13.3 0 24-10.7 24-24V312c0-13.3-10.7-24-24-24zm304 0c-13.3 0-24 10.7-24 24v48c0 13.3 10.7 24 24 24h80c13.3 0 24-10.7 24-24V312c0-13.3-10.7-24-24-24H408zM24 416c-13.3 0-24 10.7-24 24v48c0 13.3 10.7 24 24 24h80c13.3 0 24-10.7 24-24V440c0-13.3-10.7-24-24-24H24zm384 0c-13.3 0-24 10.7-24 24v48c0 13.3 10.7 24 24 24h80c13.3 0 24-10.7 24-24V440c0-13.3-10.7-24-24-24H408zM272 192c0-8.8-7.2-16-16-16s-16 7.2-16 16V464c0 8.8 7.2 16 16 16s16-7.2 16-16V192zm-64 32c0-8.8-7.2-16-16-16s-16 7.2-16 16V464c0 8.8 7.2 16 16 16s16-7.2 16-16V224zm128 0c0-8.8-7.2-16-16-16s-16 7.2-16 16V464c0 8.8 7.2 16 16 16s16-7.2 16-16V224z" } }, "free": ["solid"] }, "dyalog": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f399", "label": "Dyalog", "voted": false, "svg": { "brands": { "last_modified": 1660014482, "raw": "", "viewBox": [0, 0, 416, 512], "width": 416, "height": 512, "path": "M0 32v119.2h64V96h107.2C284.6 96 352 176.2 352 255.9 352 332 293.4 416 171.2 416H0v64h171.2C331.9 480 416 367.3 416 255.9c0-58.7-22.1-113.4-62.3-154.3C308.9 56 245.7 32 171.2 32H0z" } }, "free": ["brands"] }, "e": { "aliases": { "unicodes": { "composite": ["65"] } }, "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Latin Capital Letter E", "Latin Small Letter E", "letter"] }, "styles": ["solid"], "unicode": "45", "label": "E", "voted": false, "svg": { "solid": { "last_modified": 1684767247, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M64 32C28.7 32 0 60.7 0 96V256 416c0 35.3 28.7 64 64 64H288c17.7 0 32-14.3 32-32s-14.3-32-32-32H64V288H224c17.7 0 32-14.3 32-32s-14.3-32-32-32H64V96H288c17.7 0 32-14.3 32-32s-14.3-32-32-32H64z" } }, "free": ["solid"] }, "ear-deaf": { "aliases": { "names": ["deaf", "deafness", "hard-of-hearing"], "unicodes": { "secondary": ["10f2a4"] } }, "changes": ["4.6.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["ear", "hearing", "sign language"] }, "styles": ["solid"], "unicode": "f2a4", "label": "Ear Deaf", "voted": false, "svg": { "solid": { "last_modified": 1684766751, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M502.6 54.6l-40 40c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3l40-40c12.5-12.5 32.8-12.5 45.3 0s12.5 32.8 0 45.3zm-320 320l-128 128c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3l128-128c12.5-12.5 32.8-12.5 45.3 0s12.5 32.8 0 45.3zM240 128c-57.6 0-105.1 43.6-111.3 99.5c-1.9 17.6-17.8 30.2-35.3 28.3s-30.2-17.8-28.3-35.3C74.8 132.5 149.4 64 240 64c97.2 0 176 78.8 176 176c0 46-17.7 87.9-46.6 119.3c-12 13-17.4 24.8-17.4 34.7V400c0 61.9-50.1 112-112 112c-17.7 0-32-14.3-32-32s14.3-32 32-32c26.5 0 48-21.5 48-48v-6.1c0-32.9 17.4-59.6 34.4-78c18.4-20 29.6-46.6 29.6-75.9c0-61.9-50.1-112-112-112zm0 80c-17.7 0-32 14.3-32 32c0 13.3-10.7 24-24 24s-24-10.7-24-24c0-44.2 35.8-80 80-80s80 35.8 80 80c0 13.3-10.7 24-24 24s-24-10.7-24-24c0-17.7-14.3-32-32-32z" } }, "free": ["solid"] }, "ear-listen": { "aliases": { "names": ["assistive-listening-systems"], "unicodes": { "secondary": ["10f2a2"] } }, "changes": ["4.6.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "amplify", "audio", "deaf", "ear", "headset", "hearing", "sound" ] }, "styles": ["solid"], "unicode": "f2a2", "label": "Ear Listen", "voted": false, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M398.3 3.4c-15.8-7.9-35-1.5-42.9 14.3c-7.9 15.8-1.5 34.9 14.2 42.9l.4 .2c.4 .2 1.1 .6 2.1 1.2c2 1.2 5 3 8.7 5.6c7.5 5.2 17.6 13.2 27.7 24.2C428.5 113.4 448 146 448 192c0 17.7 14.3 32 32 32s32-14.3 32-32c0-66-28.5-113.4-56.5-143.7C441.6 33.2 427.7 22.2 417.3 15c-5.3-3.7-9.7-6.4-13-8.3c-1.6-1-3-1.7-4-2.2c-.5-.3-.9-.5-1.2-.7l-.4-.2-.2-.1-.1 0 0 0c0 0 0 0-14.3 28.6L398.3 3.4zM128.7 227.5c6.2-56 53.7-99.5 111.3-99.5c61.9 0 112 50.1 112 112c0 29.3-11.2 55.9-29.6 75.9c-17 18.4-34.4 45.1-34.4 78V400c0 26.5-21.5 48-48 48c-17.7 0-32 14.3-32 32s14.3 32 32 32c61.9 0 112-50.1 112-112v-6.1c0-9.8 5.4-21.7 17.4-34.7C398.3 327.9 416 286 416 240c0-97.2-78.8-176-176-176C149.4 64 74.8 132.5 65.1 220.5c-1.9 17.6 10.7 33.4 28.3 35.3s33.4-10.7 35.3-28.3zM32 512a32 32 0 1 0 0-64 32 32 0 1 0 0 64zM192 352a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zM41.4 361.4c-12.5 12.5-12.5 32.8 0 45.3l64 64c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3l-64-64c-12.5-12.5-32.8-12.5-45.3 0zM208 240c0-17.7 14.3-32 32-32s32 14.3 32 32c0 13.3 10.7 24 24 24s24-10.7 24-24c0-44.2-35.8-80-80-80s-80 35.8-80 80c0 13.3 10.7 24 24 24s24-10.7 24-24z" } }, "free": ["solid"] }, "earlybirds": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f39a", "label": "Earlybirds", "voted": false, "svg": { "brands": { "last_modified": 1660014465, "raw": "", "viewBox": [0, 0, 480, 512], "width": 480, "height": 512, "path": "M313.2 47.5c1.2-13 21.3-14 36.6-8.7.9.3 26.2 9.7 19 15.2-27.9-7.4-56.4 18.2-55.6-6.5zm-201 6.9c30.7-8.1 62 20 61.1-7.1-1.3-14.2-23.4-15.3-40.2-9.6-1 .3-28.7 10.5-20.9 16.7zM319.4 160c-8.8 0-16 7.2-16 16s7.2 16 16 16 16-7.2 16-16-7.2-16-16-16zm-159.7 0c-8.8 0-16 7.2-16 16s7.2 16 16 16 16-7.2 16-16-7.2-16-16-16zm318.5 163.2c-9.9 24-40.7 11-63.9-1.2-13.5 69.1-58.1 111.4-126.3 124.2.3.9-2-.1 24 1 33.6 1.4 63.8-3.1 97.4-8-19.8-13.8-11.4-37.1-9.8-38.1 1.4-.9 14.7 1.7 21.6 11.5 8.6-12.5 28.4-14.8 30.2-13.6 1.6 1.1 6.6 20.9-6.9 34.6 4.7-.9 8.2-1.6 9.8-2.1 2.6-.8 17.7 11.3 3.1 13.3-14.3 2.3-22.6 5.1-47.1 10.8-45.9 10.7-85.9 11.8-117.7 12.8l1 11.6c3.8 18.1-23.4 24.3-27.6 6.2.8 17.9-27.1 21.8-28.4-1l-.5 5.3c-.7 18.4-28.4 17.9-28.3-.6-7.5 13.5-28.1 6.8-26.4-8.5l1.2-12.4c-36.7.9-59.7 3.1-61.8 3.1-20.9 0-20.9-31.6 0-31.6 2.4 0 27.7 1.3 63.2 2.8-61.1-15.5-103.7-55-114.9-118.2-25 12.8-57.5 26.8-68.2.8-10.5-25.4 21.5-42.6 66.8-73.4.7-6.6 1.6-13.3 2.7-19.8-14.4-19.6-11.6-36.3-16.1-60.4-16.8 2.4-23.2-9.1-23.6-23.1.3-7.3 2.1-14.9 2.4-15.4 1.1-1.8 10.1-2 12.7-2.6 6-31.7 50.6-33.2 90.9-34.5 19.7-21.8 45.2-41.5 80.9-48.3C203.3 29 215.2 8.5 216.2 8c1.7-.8 21.2 4.3 26.3 23.2 5.2-8.8 18.3-11.4 19.6-10.7 1.1.6 6.4 15-4.9 25.9 40.3 3.5 72.2 24.7 96 50.7 36.1 1.5 71.8 5.9 77.1 34 2.7.6 11.6.8 12.7 2.6.3.5 2.1 8.1 2.4 15.4-.5 13.9-6.8 25.4-23.6 23.1-3.2 17.3-2.7 32.9-8.7 47.7 2.4 11.7 4 23.8 4.8 36.4 37 25.4 70.3 42.5 60.3 66.9zM207.4 159.9c.9-44-37.9-42.2-78.6-40.3-21.7 1-38.9 1.9-45.5 13.9-11.4 20.9 5.9 92.9 23.2 101.2 9.8 4.7 73.4 7.9 86.3-7.1 8.2-9.4 15-49.4 14.6-67.7zm52 58.3c-4.3-12.4-6-30.1-15.3-32.7-2-.5-9-.5-11 0-10 2.8-10.8 22.1-17 37.2 15.4 0 19.3 9.7 23.7 9.7 4.3 0 6.3-11.3 19.6-14.2zm135.7-84.7c-6.6-12.1-24.8-12.9-46.5-13.9-40.2-1.9-78.2-3.8-77.3 40.3-.5 18.3 5 58.3 13.2 67.8 13 14.9 76.6 11.8 86.3 7.1 15.8-7.6 36.5-78.9 24.3-101.3z" } }, "free": ["brands"] }, "earth-africa": { "aliases": { "names": ["globe-africa"], "unicodes": { "composite": ["1f30d"], "secondary": ["10f57c"] } }, "changes": [ "5.1.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "africa", "all", "country", "earth", "europe", "global", "globe", "gps", "language", "localize", "location", "map", "online", "place", "planet", "translate", "travel", "world" ] }, "styles": ["solid"], "unicode": "f57c", "label": "Earth Africa", "voted": false, "svg": { "solid": { "last_modified": 1684767489, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M177.8 63.2l10 17.4c2.8 4.8 4.2 10.3 4.2 15.9v41.4c0 3.9 1.6 7.7 4.3 10.4c6.2 6.2 16.5 5.7 22-1.2l13.6-17c4.7-5.9 12.9-7.7 19.6-4.3l15.2 7.6c3.4 1.7 7.2 2.6 11 2.6c6.5 0 12.8-2.6 17.4-7.2l3.9-3.9c2.9-2.9 7.3-3.6 11-1.8l29.2 14.6c7.8 3.9 12.6 11.8 12.6 20.5c0 10.5-7.1 19.6-17.3 22.2l-35.4 8.8c-7.4 1.8-15.1 1.5-22.4-.9l-32-10.7c-3.3-1.1-6.7-1.7-10.2-1.7c-7 0-13.8 2.3-19.4 6.5L176 212c-10.1 7.6-16 19.4-16 32v28c0 26.5 21.5 48 48 48h32c8.8 0 16 7.2 16 16v48c0 17.7 14.3 32 32 32c10.1 0 19.6-4.7 25.6-12.8l25.6-34.1c8.3-11.1 12.8-24.6 12.8-38.4V318.6c0-3.9 2.6-7.3 6.4-8.2l5.3-1.3c11.9-3 20.3-13.7 20.3-26c0-7.1-2.8-13.9-7.8-18.9l-33.5-33.5c-3.7-3.7-3.7-9.7 0-13.4c5.7-5.7 14.1-7.7 21.8-5.1l14.1 4.7c12.3 4.1 25.7-1.5 31.5-13c3.5-7 11.2-10.8 18.9-9.2l27.4 5.5C432 112.4 351.5 48 256 48c-27.7 0-54 5.4-78.2 15.2zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256z" } }, "free": ["solid"] }, "earth-americas": { "aliases": { "names": ["earth", "earth-america", "globe-americas"], "unicodes": { "composite": ["1f30e"], "secondary": ["10f57d"] } }, "changes": [ "5.1.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "all", "america", "country", "earth", "global", "globe", "gps", "language", "localize", "location", "map", "online", "place", "planet", "translate", "travel", "world" ] }, "styles": ["solid"], "unicode": "f57d", "label": "Earth Americas", "voted": false, "svg": { "solid": { "last_modified": 1684767488, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M57.7 193l9.4 16.4c8.3 14.5 21.9 25.2 38 29.8L163 255.7c17.2 4.9 29 20.6 29 38.5v39.9c0 11 6.2 21 16 25.9s16 14.9 16 25.9v39c0 15.6 14.9 26.9 29.9 22.6c16.1-4.6 28.6-17.5 32.7-33.8l2.8-11.2c4.2-16.9 15.2-31.4 30.3-40l8.1-4.6c15-8.5 24.2-24.5 24.2-41.7v-8.3c0-12.7-5.1-24.9-14.1-33.9l-3.9-3.9c-9-9-21.2-14.1-33.9-14.1H257c-11.1 0-22.1-2.9-31.8-8.4l-34.5-19.7c-4.3-2.5-7.6-6.5-9.2-11.2c-3.2-9.6 1.1-20 10.2-24.5l5.9-3c6.6-3.3 14.3-3.9 21.3-1.5l23.2 7.7c8.2 2.7 17.2-.4 21.9-7.5c4.7-7 4.2-16.3-1.2-22.8l-13.6-16.3c-10-12-9.9-29.5 .3-41.3l15.7-18.3c8.8-10.3 10.2-25 3.5-36.7l-2.4-4.2c-3.5-.2-6.9-.3-10.4-.3C163.1 48 84.4 108.9 57.7 193zM464 256c0-36.8-9.6-71.4-26.4-101.5L412 164.8c-15.7 6.3-23.8 23.8-18.5 39.8l16.9 50.7c3.5 10.4 12 18.3 22.6 20.9l29.1 7.3c1.2-9 1.8-18.2 1.8-27.5zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256z" } }, "free": ["solid"] }, "earth-asia": { "aliases": { "names": ["globe-asia"], "unicodes": { "composite": ["1f30f"], "secondary": ["10f57e"] } }, "changes": [ "5.1.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "all", "asia", "australia", "country", "earth", "global", "globe", "gps", "language", "localize", "location", "map", "online", "place", "planet", "translate", "travel", "world" ] }, "styles": ["solid"], "unicode": "f57e", "label": "Earth Asia", "voted": false, "svg": { "solid": { "last_modified": 1684767488, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M51.7 295.1l31.7 6.3c7.9 1.6 16-.9 21.7-6.6l15.4-15.4c11.6-11.6 31.1-8.4 38.4 6.2l9.3 18.5c4.8 9.6 14.6 15.7 25.4 15.7c15.2 0 26.1-14.6 21.7-29.2l-6-19.9c-4.6-15.4 6.9-30.9 23-30.9h2.3c13.4 0 25.9-6.7 33.3-17.8l10.7-16.1c5.6-8.5 5.3-19.6-.8-27.7l-16.1-21.5c-10.3-13.7-3.3-33.5 13.4-37.7l17-4.3c7.5-1.9 13.6-7.2 16.5-14.4l16.4-40.9C303.4 52.1 280.2 48 256 48C141.1 48 48 141.1 48 256c0 13.4 1.3 26.5 3.7 39.1zm407.7 4.6c-3-.3-6-.1-9 .8l-15.8 4.4c-6.7 1.9-13.8-.9-17.5-6.7l-2-3.1c-6-9.4-16.4-15.1-27.6-15.1s-21.6 5.7-27.6 15.1l-6.1 9.5c-1.4 2.2-3.4 4.1-5.7 5.3L312 330.1c-18.1 10.1-25.5 32.4-17 51.3l5.5 12.4c8.6 19.2 30.7 28.5 50.5 21.1l2.6-1c10-3.7 21.3-2.2 29.9 4.1l1.5 1.1c37.2-29.5 64.1-71.4 74.4-119.5zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm144.5 92.1c-2.1 8.6 3.1 17.3 11.6 19.4l32 8c8.6 2.1 17.3-3.1 19.4-11.6s-3.1-17.3-11.6-19.4l-32-8c-8.6-2.1-17.3 3.1-19.4 11.6zm92-20c-2.1 8.6 3.1 17.3 11.6 19.4s17.3-3.1 19.4-11.6l8-32c2.1-8.6-3.1-17.3-11.6-19.4s-17.3 3.1-19.4 11.6l-8 32zM343.2 113.7c-7.9-4-17.5-.7-21.5 7.2l-16 32c-4 7.9-.7 17.5 7.2 21.5s17.5 .7 21.5-7.2l16-32c4-7.9 .7-17.5-7.2-21.5z" } }, "free": ["solid"] }, "earth-europe": { "aliases": { "names": ["globe-europe"], "unicodes": { "secondary": ["10f7a2"] } }, "changes": [ "5.6.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "all", "country", "earth", "europe", "global", "globe", "gps", "language", "localize", "location", "map", "online", "place", "planet", "translate", "travel", "world" ] }, "styles": ["solid"], "unicode": "f7a2", "label": "Earth Europe", "voted": true, "svg": { "solid": { "last_modified": 1684767488, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M266.3 48.3L232.5 73.6c-5.4 4-8.5 10.4-8.5 17.1v9.1c0 6.8 5.5 12.3 12.3 12.3c2.4 0 4.8-.7 6.8-2.1l41.8-27.9c2-1.3 4.4-2.1 6.8-2.1h1c6.2 0 11.3 5.1 11.3 11.3c0 3-1.2 5.9-3.3 8l-19.9 19.9c-5.8 5.8-12.9 10.2-20.7 12.8l-26.5 8.8c-5.8 1.9-9.6 7.3-9.6 13.4c0 3.7-1.5 7.3-4.1 10l-17.9 17.9c-6.4 6.4-9.9 15-9.9 24v4.3c0 16.4 13.6 29.7 29.9 29.7c11 0 21.2-6.2 26.1-16l4-8.1c2.4-4.8 7.4-7.9 12.8-7.9c4.5 0 8.7 2.1 11.4 5.7l16.3 21.7c2.1 2.9 5.5 4.5 9.1 4.5c8.4 0 13.9-8.9 10.1-16.4l-1.1-2.3c-3.5-7 0-15.5 7.5-18l21.2-7.1c7.6-2.5 12.7-9.6 12.7-17.6c0-10.3 8.3-18.6 18.6-18.6H400c8.8 0 16 7.2 16 16s-7.2 16-16 16H379.3c-7.2 0-14.2 2.9-19.3 8l-4.7 4.7c-2.1 2.1-3.3 5-3.3 8c0 6.2 5.1 11.3 11.3 11.3h11.3c6 0 11.8 2.4 16 6.6l6.5 6.5c1.8 1.8 2.8 4.3 2.8 6.8s-1 5-2.8 6.8l-7.5 7.5C386 262 384 266.9 384 272s2 10 5.7 13.7L408 304c10.2 10.2 24.1 16 38.6 16H454c6.5-20.2 10-41.7 10-64c0-111.4-87.6-202.4-197.7-207.7zm172 307.9c-3.7-2.6-8.2-4.1-13-4.1c-6 0-11.8-2.4-16-6.6L396 332c-7.7-7.7-18-12-28.9-12c-9.7 0-19.2-3.5-26.6-9.8L314 287.4c-11.6-9.9-26.4-15.4-41.7-15.4H251.4c-12.6 0-25 3.7-35.5 10.7L188.5 301c-17.8 11.9-28.5 31.9-28.5 53.3v3.2c0 17 6.7 33.3 18.7 45.3l16 16c8.5 8.5 20 13.3 32 13.3H248c13.3 0 24 10.7 24 24c0 2.5 .4 5 1.1 7.3c71.3-5.8 132.5-47.6 165.2-107.2zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zM187.3 100.7c-6.2-6.2-16.4-6.2-22.6 0l-32 32c-6.2 6.2-6.2 16.4 0 22.6s16.4 6.2 22.6 0l32-32c6.2-6.2 6.2-16.4 0-22.6z" } }, "free": ["solid"] }, "earth-oceania": { "aliases": { "names": ["globe-oceania"] }, "changes": ["6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "all", "australia", "country", "earth", "global", "globe", "gps", "language", "localize", "location", "map", "melanesia", "micronesia", "new zealand", "online", "place", "planet", "polynesia", "translate", "travel", "world" ] }, "styles": ["solid"], "unicode": "e47b", "label": "Earth Oceania", "voted": false, "svg": { "solid": { "last_modified": 1684767488, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM208.6 357.3l-39-13.5c-6.5-2.2-13.6-2.3-20.1-.3l-15.3 4.9c-18.5 5.9-38.5-2.4-47.5-19.5l-3.3-6.2c-10.6-20.1-2.3-45 18.2-54.7l35.3-16.8c2.3-1.1 4.4-2.8 5.9-4.8l5.3-7c7.2-9.6 18.6-15.3 30.6-15.3s23.4 5.7 30.6 15.3l4.6 6.1c2 2.6 4.9 4.5 8.1 5.1c7.8 1.6 15.7-1.5 20.4-7.9l10.4-14.2c2-2.8 5.3-4.4 8.7-4.4c4.4 0 8.4 2.7 10 6.8l10.1 25.9c2.8 7.2 6.7 14 11.5 20.2L311 299.8c5.8 7.4 9 16.6 9 26s-3.2 18.6-9 26L299 367.2c-8.3 10.6-21 16.8-34.4 16.8c-8.4 0-16.6-2.4-23.7-7l-25.4-16.4c-2.2-1.4-4.5-2.5-6.9-3.4zm65.2-214.8L296 164.7c10.1 10.1 2.9 27.3-11.3 27.3H254.8c-5.6 0-11.1-1.2-16.2-3.4l-42.8-19c-14.3-6.3-11.9-27.3 3.4-30.3l38.5-7.7c13.1-2.6 26.7 1.5 36.1 10.9zM248 432c0-8.8 7.2-16 16-16h16c8.8 0 16 7.2 16 16s-7.2 16-16 16H264c-8.8 0-16-7.2-16-16zM431.2 298.9l8 24c2.8 8.4-1.7 17.4-10.1 20.2s-17.4-1.7-20.2-10.1l-8-24c-2.8-8.4 1.7-17.4 10.1-20.2s17.4 1.7 20.2 10.1zm-19.9 80.4l-32 32c-6.2 6.2-16.4 6.2-22.6 0s-6.2-16.4 0-22.6l32-32c6.2-6.2 16.4-6.2 22.6 0s6.2 16.4 0 22.6z" } }, "free": ["solid"] }, "ebay": { "changes": ["5.0.11", "5.7.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f4f4", "label": "eBay", "voted": true, "svg": { "brands": { "last_modified": 1660014474, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M606 189.5l-54.8 109.9-54.9-109.9h-37.5l10.9 20.6c-11.5-19-35.9-26-63.3-26-31.8 0-67.9 8.7-71.5 43.1h33.7c1.4-13.8 15.7-21.8 35-21.8 26 0 41 9.6 41 33v3.4c-12.7 0-28 .1-41.7.4-42.4.9-69.6 10-76.7 34.4 1-5.2 1.5-10.6 1.5-16.2 0-52.1-39.7-76.2-75.4-76.2-21.3 0-43 5.5-58.7 24.2v-80.6h-32.1v169.5c0 10.3-.6 22.9-1.1 33.1h31.5c.7-6.3 1.1-12.9 1.1-19.5 13.6 16.6 35.4 24.9 58.7 24.9 36.9 0 64.9-21.9 73.3-54.2-.5 2.8-.7 5.8-.7 9 0 24.1 21.1 45 60.6 45 26.6 0 45.8-5.7 61.9-25.5 0 6.6.3 13.3 1.1 20.2h29.8c-.7-8.2-1-17.5-1-26.8v-65.6c0-9.3-1.7-17.2-4.8-23.8l61.5 116.1-28.5 54.1h35.9L640 189.5zM243.7 313.8c-29.6 0-50.2-21.5-50.2-53.8 0-32.4 20.6-53.8 50.2-53.8 29.8 0 50.2 21.4 50.2 53.8 0 32.3-20.4 53.8-50.2 53.8zm200.9-47.3c0 30-17.9 48.4-51.6 48.4-25.1 0-35-13.4-35-25.8 0-19.1 18.1-24.4 47.2-25.3 13.1-.5 27.6-.6 39.4-.6zm-411.9 1.6h128.8v-8.5c0-51.7-33.1-75.4-78.4-75.4-56.8 0-83 30.8-83 77.6 0 42.5 25.3 74 82.5 74 31.4 0 68-11.7 74.4-46.1h-33.1c-12 35.8-87.7 36.7-91.2-21.6zm95-21.4H33.3c6.9-56.6 92.1-54.7 94.4 0z" } }, "free": ["brands"] }, "edge": { "changes": ["4.5.0", "5.0.0", "5.12.1", "6.1.2"], "ligatures": [], "search": { "terms": ["browser", "ie"] }, "styles": ["brands"], "unicode": "f282", "label": "Edge Browser", "voted": false, "svg": { "brands": { "last_modified": 1660014480, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M120.1 37.44C161.1 12.23 207.7-.7753 255 .0016C423 .0016 512 123.8 512 219.5C511.9 252.2 499 283.4 476.1 306.7C453.2 329.9 422.1 343.2 389.4 343.7C314.2 343.7 297.9 320.6 297.9 311.7C297.9 307.9 299.1 305.5 302.7 302.3L303.7 301.1L304.1 299.5C314.6 288 320 273.3 320 257.9C320 179.2 237.8 115.2 136 115.2C98.46 114.9 61.46 124.1 28.48 142.1C55.48 84.58 111.2 44.5 119.8 38.28C120.6 37.73 120.1 37.44 120.1 37.44V37.44zM135.7 355.5C134.3 385.5 140.3 415.5 152.1 442.7C165.7 469.1 184.8 493.7 208.6 512C149.1 500.5 97.11 468.1 59.2 422.7C21.12 376.3 0 318.4 0 257.9C0 206.7 62.4 163.5 136 163.5C172.6 162.9 208.4 174.4 237.8 196.2L234.2 197.4C182.7 215 135.7 288.1 135.7 355.5V355.5zM469.8 400L469.1 400.1C457.3 418.9 443.2 435.2 426.9 449.6C396.1 477.6 358.8 495.1 318.1 499.5C299.5 499.8 281.3 496.3 264.3 488.1C238.7 477.8 217.2 458.1 202.7 435.1C188.3 411.2 181.6 383.4 183.7 355.5C183.1 335.4 189.1 315.2 198.7 297.3C212.6 330.4 236.2 358.6 266.3 378.1C296.4 397.6 331.8 407.6 367.7 406.7C398.7 407 429.8 400 457.9 386.2L459.8 385.3C463.7 383 467.5 381.4 471.4 385.3C475.9 390.2 473.2 394.5 470.2 399.3C470 399.5 469.9 399.8 469.8 400V400z" } }, "free": ["brands"] }, "edge-legacy": { "changes": ["5.13.1", "5.14.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e078", "label": "Edge Legacy Browser", "voted": false, "svg": { "brands": { "last_modified": 1660014460, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M25.71,228.16l.35-.48c0,.16,0,.32-.07.48Zm460.58,15.51c0-44-7.76-84.46-28.81-122.4C416.5,47.88,343.91,8,258.89,8,119,7.72,40.62,113.21,26.06,227.68c42.42-61.31,117.07-121.38,220.37-125,0,0,109.67,0,99.42,105H170c6.37-37.39,18.55-59,34.34-78.93-75.05,34.9-121.85,96.1-120.75,188.32.83,71.45,50.13,144.84,120.75,172,83.35,31.84,192.77,7.2,240.13-21.33V363.31C363.6,419.8,173.6,424.23,172.21,295.74H486.29V243.67Z" } }, "free": ["brands"] }, "egg": { "aliases": { "unicodes": { "composite": ["1f95a"], "secondary": ["10f7fb"] } }, "changes": ["5.7.0", "6.0.0-beta1", "6.2.0", "6.2.1", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "breakfast", "chicken", "easter", "egg", "food", "shell", "yolk" ] }, "styles": ["solid"], "unicode": "f7fb", "label": "Egg", "voted": false, "svg": { "solid": { "last_modified": 1684767421, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M192 496C86 496 0 394 0 288C0 176 64 16 192 16s192 160 192 272c0 106-86 208-192 208zM154.8 134c6.5-6 7-16.1 1-22.6s-16.1-7-22.6-1c-23.9 21.8-41.1 52.7-52.3 84.2C69.7 226.1 64 259.7 64 288c0 8.8 7.2 16 16 16s16-7.2 16-16c0-24.5 5-54.4 15.1-82.8c10.1-28.5 25-54.1 43.7-71.2z" } }, "free": ["solid"] }, "eject": { "aliases": { "unicodes": { "composite": ["23cf"], "secondary": ["10f052"] } }, "changes": ["1.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["abort", "cancel", "cd", "discharge", "eject", "eject button"] }, "styles": ["solid"], "unicode": "f052", "label": "Eject", "voted": false, "svg": { "solid": { "last_modified": 1684766676, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M224 32c13.5 0 26.3 5.6 35.4 15.6l176 192c12.9 14 16.2 34.3 8.6 51.8S419 320 400 320H48c-19 0-36.3-11.2-43.9-28.7s-4.3-37.7 8.6-51.8l176-192C197.7 37.6 210.5 32 224 32zM0 432c0-26.5 21.5-48 48-48H400c26.5 0 48 21.5 48 48s-21.5 48-48 48H48c-26.5 0-48-21.5-48-48z" } }, "free": ["solid"] }, "elementor": { "changes": ["5.0.3", "6.1.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f430", "label": "Elementor", "voted": true, "svg": { "brands": { "last_modified": 1660014467, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M.361 256C.361 397 114 511 255 511C397 511 511 397 511 256C511 116 397 2.05 255 2.05C114 2.05 .361 116 .361 256zM192 150V363H149V150H192zM234 150H362V193H234V150zM362 235V278H234V235H362zM234 320H362V363H234V320z" } }, "free": ["brands"] }, "elevator": { "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["accessibility", "elevator", "hoist", "lift", "users-people"] }, "styles": ["solid"], "unicode": "e16d", "label": "Elevator", "voted": true, "svg": { "solid": { "last_modified": 1684767620, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M132.7 4.7l-64 64c-4.6 4.6-5.9 11.5-3.5 17.4s8.3 9.9 14.8 9.9H208c6.5 0 12.3-3.9 14.8-9.9s1.1-12.9-3.5-17.4l-64-64c-6.2-6.2-16.4-6.2-22.6 0zM64 128c-35.3 0-64 28.7-64 64V448c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V192c0-35.3-28.7-64-64-64H64zm96 96a48 48 0 1 1 0 96 48 48 0 1 1 0-96zM80 400c0-26.5 21.5-48 48-48h64c26.5 0 48 21.5 48 48v16c0 17.7-14.3 32-32 32H112c-17.7 0-32-14.3-32-32V400zm192 0c0-26.5 21.5-48 48-48h64c26.5 0 48 21.5 48 48v16c0 17.7-14.3 32-32 32H304c-17.7 0-32-14.3-32-32V400zm32-128a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zM356.7 91.3c6.2 6.2 16.4 6.2 22.6 0l64-64c4.6-4.6 5.9-11.5 3.5-17.4S438.5 0 432 0H304c-6.5 0-12.3 3.9-14.8 9.9s-1.1 12.9 3.5 17.4l64 64z" } }, "free": ["solid"] }, "ellipsis": { "aliases": { "names": ["ellipsis-h"], "unicodes": { "secondary": ["10f141"] } }, "changes": [ "3.1.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "dots", "drag", "kebab", "list", "menu", "nav", "navigation", "ol", "pacman", "reorder", "settings", "ul" ] }, "styles": ["solid"], "unicode": "f141", "label": "Ellipsis", "voted": false, "svg": { "solid": { "last_modified": 1684767206, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M8 256a56 56 0 1 1 112 0A56 56 0 1 1 8 256zm160 0a56 56 0 1 1 112 0 56 56 0 1 1 -112 0zm216-56a56 56 0 1 1 0 112 56 56 0 1 1 0-112z" } }, "free": ["solid"] }, "ellipsis-vertical": { "aliases": { "names": ["ellipsis-v"], "unicodes": { "secondary": ["10f142"] } }, "changes": [ "3.1.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "dots", "drag", "kebab", "list", "menu", "nav", "navigation", "ol", "reorder", "settings", "ul" ] }, "styles": ["solid"], "unicode": "f142", "label": "Ellipsis Vertical", "voted": false, "svg": { "solid": { "last_modified": 1684767206, "raw": "", "viewBox": [0, 0, 128, 512], "width": 128, "height": 512, "path": "M64 360a56 56 0 1 0 0 112 56 56 0 1 0 0-112zm0-160a56 56 0 1 0 0 112 56 56 0 1 0 0-112zM120 96A56 56 0 1 0 8 96a56 56 0 1 0 112 0z" } }, "free": ["solid"] }, "ello": { "changes": ["5.2.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f5f1", "label": "Ello", "voted": true, "svg": { "brands": { "last_modified": 1660014470, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M248 8C111.03 8 0 119.03 0 256s111.03 248 248 248 248-111.03 248-248S384.97 8 248 8zm143.84 285.2C375.31 358.51 315.79 404.8 248 404.8s-127.31-46.29-143.84-111.6c-1.65-7.44 2.48-15.71 9.92-17.36 7.44-1.65 15.71 2.48 17.36 9.92 14.05 52.91 62 90.11 116.56 90.11s102.51-37.2 116.56-90.11c1.65-7.44 9.92-12.4 17.36-9.92 7.44 1.65 12.4 9.92 9.92 17.36z" } }, "free": ["brands"] }, "ember": { "changes": ["5.0.0", "5.0.3"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f423", "label": "Ember", "voted": false, "svg": { "brands": { "last_modified": 1660014459, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M639.9 254.6c-1.1-10.7-10.7-6.8-10.7-6.8s-15.6 12.1-29.3 10.7c-13.7-1.3-9.4-32-9.4-32s3-28.1-5.1-30.4c-8.1-2.4-18 7.3-18 7.3s-12.4 13.7-18.3 31.2l-1.6.5s1.9-30.6-.3-37.6c-1.6-3.5-16.4-3.2-18.8 3s-14.2 49.2-15 67.2c0 0-23.1 19.6-43.3 22.8s-25-9.4-25-9.4 54.8-15.3 52.9-59.1-44.2-27.6-49-24c-4.6 3.5-29.4 18.4-36.6 59.7-.2 1.4-.7 7.5-.7 7.5s-21.2 14.2-33 18c0 0 33-55.6-7.3-80.9-11.4-6.8-21.3-.5-27.2 5.3 13.6-17.3 46.4-64.2 36.9-105.2-5.8-24.4-18-27.1-29.2-23.1-17 6.7-23.5 16.7-23.5 16.7s-22 32-27.1 79.5-12.6 105.1-12.6 105.1-10.5 10.2-20.2 10.7-5.4-28.7-5.4-28.7 7.5-44.6 7-52.1-1.1-11.6-9.9-14.2c-8.9-2.7-18.5 8.6-18.5 8.6s-25.5 38.7-27.7 44.6l-1.3 2.4-1.3-1.6s18-52.7.8-53.5-28.5 18.8-28.5 18.8-19.6 32.8-20.4 36.5l-1.3-1.6s8.1-38.2 6.4-47.6c-1.6-9.4-10.5-7.5-10.5-7.5s-11.3-1.3-14.2 5.9-13.7 55.3-15 70.7c0 0-28.2 20.2-46.8 20.4-18.5.3-16.7-11.8-16.7-11.8s68-23.3 49.4-69.2c-8.3-11.8-18-15.5-31.7-15.3-13.7.3-30.3 8.6-41.3 33.3-5.3 11.8-6.8 23-7.8 31.5 0 0-12.3 2.4-18.8-2.9s-10 0-10 0-11.2 14-.1 18.3 28.1 6.1 28.1 6.1c1.6 7.5 6.2 19.5 19.6 29.7 20.2 15.3 58.8-1.3 58.8-1.3l15.9-8.8s.5 14.6 12.1 16.7 16.4 1 36.5-47.9c11.8-25 12.6-23.6 12.6-23.6l1.3-.3s-9.1 46.8-5.6 59.7C187.7 319.4 203 318 203 318s8.3 2.4 15-21.2 19.6-49.9 19.6-49.9h1.6s-5.6 48.1 3 63.7 30.9 5.3 30.9 5.3 15.6-7.8 18-10.2c0 0 18.5 15.8 44.6 12.9 58.3-11.5 79.1-25.9 79.1-25.9s10 24.4 41.1 26.7c35.5 2.7 54.8-18.6 54.8-18.6s-.3 13.5 12.1 18.6 20.7-22.8 20.7-22.8l20.7-57.2h1.9s1.1 37.3 21.5 43.2 47-13.7 47-13.7 6.4-3.5 5.3-14.3zm-578 5.3c.8-32 21.8-45.9 29-39 7.3 7 4.6 22-9.1 31.4-13.7 9.5-19.9 7.6-19.9 7.6zm272.8-123.8s19.1-49.7 23.6-25.5-40 96.2-40 96.2c.5-16.2 16.4-70.7 16.4-70.7zm22.8 138.4c-12.6 33-43.3 19.6-43.3 19.6s-3.5-11.8 6.4-44.9 33.3-20.2 33.3-20.2 16.2 12.4 3.6 45.5zm84.6-14.6s-3-10.5 8.1-30.6c11-20.2 19.6-9.1 19.6-9.1s9.4 10.2-1.3 25.5-26.4 14.2-26.4 14.2z" } }, "free": ["brands"] }, "empire": { "changes": ["4.1.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f1d1", "label": "Galactic Empire", "voted": false, "svg": { "brands": { "last_modified": 1660014473, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M287.6 54.2c-10.8-2.2-22.1-3.3-33.5-3.6V32.4c78.1 2.2 146.1 44 184.6 106.6l-15.8 9.1c-6.1-9.7-12.7-18.8-20.2-27.1l-18 15.5c-26-29.6-61.4-50.7-101.9-58.4l4.8-23.9zM53.4 322.4l23-7.7c-6.4-18.3-10-38.2-10-58.7s3.3-40.4 9.7-58.7l-22.7-7.7c3.6-10.8 8.3-21.3 13.6-31l-15.8-9.1C34 181 24.1 217.5 24.1 256s10 75 27.1 106.6l15.8-9.1c-5.3-10-9.7-20.3-13.6-31.1zM213.1 434c-40.4-8-75.8-29.1-101.9-58.7l-18 15.8c-7.5-8.6-14.4-17.7-20.2-27.4l-16 9.4c38.5 62.3 106.8 104.3 184.9 106.6v-18.3c-11.3-.3-22.7-1.7-33.5-3.6l4.7-23.8zM93.3 120.9l18 15.5c26-29.6 61.4-50.7 101.9-58.4l-4.7-23.8c10.8-2.2 22.1-3.3 33.5-3.6V32.4C163.9 34.6 95.9 76.4 57.4 139l15.8 9.1c6-9.7 12.6-18.9 20.1-27.2zm309.4 270.2l-18-15.8c-26 29.6-61.4 50.7-101.9 58.7l4.7 23.8c-10.8 1.9-22.1 3.3-33.5 3.6v18.3c78.1-2.2 146.4-44.3 184.9-106.6l-16.1-9.4c-5.7 9.7-12.6 18.8-20.1 27.4zM496 256c0 137-111 248-248 248S0 393 0 256 111 8 248 8s248 111 248 248zm-12.2 0c0-130.1-105.7-235.8-235.8-235.8S12.2 125.9 12.2 256 117.9 491.8 248 491.8 483.8 386.1 483.8 256zm-39-106.6l-15.8 9.1c5.3 9.7 10 20.2 13.6 31l-22.7 7.7c6.4 18.3 9.7 38.2 9.7 58.7s-3.6 40.4-10 58.7l23 7.7c-3.9 10.8-8.3 21-13.6 31l15.8 9.1C462 331 471.9 294.5 471.9 256s-9.9-75-27.1-106.6zm-183 177.7c16.3-3.3 30.4-11.6 40.7-23.5l51.2 44.8c11.9-13.6 21.3-29.3 27.1-46.8l-64.2-22.1c2.5-7.5 3.9-15.2 3.9-23.5s-1.4-16.1-3.9-23.5l64.5-22.1c-6.1-17.4-15.5-33.2-27.4-46.8l-51.2 44.8c-10.2-11.9-24.4-20.5-40.7-23.8l13.3-66.4c-8.6-1.9-17.7-2.8-27.1-2.8-9.4 0-18.5.8-27.1 2.8l13.3 66.4c-16.3 3.3-30.4 11.9-40.7 23.8l-51.2-44.8c-11.9 13.6-21.3 29.3-27.4 46.8l64.5 22.1c-2.5 7.5-3.9 15.2-3.9 23.5s1.4 16.1 3.9 23.5l-64.2 22.1c5.8 17.4 15.2 33.2 27.1 46.8l51.2-44.8c10.2 11.9 24.4 20.2 40.7 23.5l-13.3 66.7c8.6 1.7 17.7 2.8 27.1 2.8 9.4 0 18.5-1.1 27.1-2.8l-13.3-66.7z" } }, "free": ["brands"] }, "envelope": { "aliases": { "unicodes": { "composite": ["1f582", "2709", "f003"], "secondary": ["10f0e0"] } }, "changes": [ "2.0.0", "5.0.0", "5.10.1", "5.10.2", "6.0.0-beta1", "6.1.0", "6.2.0", "6.2.1", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Back of Envelope", "e-mail", "email", "envelope", "letter", "mail", "message", "notification", "support" ] }, "styles": ["solid", "regular"], "unicode": "f0e0", "label": "Envelope", "voted": false, "svg": { "solid": { "last_modified": 1684767390, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M48 64C21.5 64 0 85.5 0 112c0 15.1 7.1 29.3 19.2 38.4L236.8 313.6c11.4 8.5 27 8.5 38.4 0L492.8 150.4c12.1-9.1 19.2-23.3 19.2-38.4c0-26.5-21.5-48-48-48H48zM0 176V384c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V176L294.4 339.2c-22.8 17.1-54 17.1-76.8 0L0 176z" }, "regular": { "last_modified": 1684767390, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M64 112c-8.8 0-16 7.2-16 16v22.1L220.5 291.7c20.7 17 50.4 17 71.1 0L464 150.1V128c0-8.8-7.2-16-16-16H64zM48 212.2V384c0 8.8 7.2 16 16 16H448c8.8 0 16-7.2 16-16V212.2L322 328.8c-38.4 31.5-93.7 31.5-132 0L48 212.2zM0 128C0 92.7 28.7 64 64 64H448c35.3 0 64 28.7 64 64V384c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128z" } }, "free": ["regular", "solid"] }, "envelope-circle-check": { "changes": ["6.1.0", "6.2.0", "6.2.1", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "check", "email", "envelope", "mail", "not affected", "ok", "okay", "read", "sent" ] }, "styles": ["solid"], "unicode": "e4e8", "label": "Envelope Circle Check", "voted": false, "svg": { "solid": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M48 64C21.5 64 0 85.5 0 112c0 15.1 7.1 29.3 19.2 38.4L236.8 313.6c11.4 8.5 27 8.5 38.4 0l57.4-43c23.9-59.8 79.7-103.3 146.3-109.8l13.9-10.4c12.1-9.1 19.2-23.3 19.2-38.4c0-26.5-21.5-48-48-48H48zM294.4 339.2c-22.8 17.1-54 17.1-76.8 0L0 176V384c0 35.3 28.7 64 64 64H360.2C335.1 417.6 320 378.5 320 336c0-5.6 .3-11.1 .8-16.6l-26.4 19.8zM640 336a144 144 0 1 0 -288 0 144 144 0 1 0 288 0zm-76.7-43.3c6.2 6.2 6.2 16.4 0 22.6l-72 72c-6.2 6.2-16.4 6.2-22.6 0l-40-40c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0L480 353.4l60.7-60.7c6.2-6.2 16.4-6.2 22.6 0z" } }, "free": ["solid"] }, "envelope-open": { "aliases": { "unicodes": { "composite": ["f2b7"], "secondary": ["10f2b6"] } }, "changes": [ "4.7.0", "5.0.0", "5.10.1", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "e-mail", "email", "letter", "mail", "message", "notification", "support" ] }, "styles": ["solid", "regular"], "unicode": "f2b6", "label": "Envelope Open", "voted": false, "svg": { "solid": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M64 208.1L256 65.9 448 208.1v47.4L289.5 373c-9.7 7.2-21.4 11-33.5 11s-23.8-3.9-33.5-11L64 255.5V208.1zM256 0c-12.1 0-23.8 3.9-33.5 11L25.9 156.7C9.6 168.8 0 187.8 0 208.1V448c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V208.1c0-20.3-9.6-39.4-25.9-51.4L289.5 11C279.8 3.9 268.1 0 256 0z" }, "regular": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M255.4 48.2c.2-.1 .4-.2 .6-.2s.4 .1 .6 .2L460.6 194c2.1 1.5 3.4 3.9 3.4 6.5v13.6L291.5 355.7c-20.7 17-50.4 17-71.1 0L48 214.1V200.5c0-2.6 1.2-5 3.4-6.5L255.4 48.2zM48 276.2L190 392.8c38.4 31.5 93.7 31.5 132 0L464 276.2V456c0 4.4-3.6 8-8 8H56c-4.4 0-8-3.6-8-8V276.2zM256 0c-10.2 0-20.2 3.2-28.5 9.1L23.5 154.9C8.7 165.4 0 182.4 0 200.5V456c0 30.9 25.1 56 56 56H456c30.9 0 56-25.1 56-56V200.5c0-18.1-8.7-35.1-23.4-45.6L284.5 9.1C276.2 3.2 266.2 0 256 0z" } }, "free": ["regular", "solid"] }, "envelope-open-text": { "aliases": { "unicodes": { "secondary": ["10f658"] } }, "changes": [ "5.3.0", "5.10.1", "5.12.0", "6.0.0-beta1", "6.2.0", "6.2.1", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "e-mail", "email", "letter", "mail", "message", "notification", "support" ] }, "styles": ["solid"], "unicode": "f658", "label": "Envelope Open Text", "voted": false, "svg": { "solid": { "last_modified": 1684767390, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M215.4 96H144 107.8 96v8.8V144v40.4 89L.2 202.5c1.6-18.1 10.9-34.9 25.7-45.8L48 140.3V96c0-26.5 21.5-48 48-48h76.6l49.9-36.9C232.2 3.9 243.9 0 256 0s23.8 3.9 33.5 11L339.4 48H416c26.5 0 48 21.5 48 48v44.3l22.1 16.4c14.8 10.9 24.1 27.7 25.7 45.8L416 273.4v-89V144 104.8 96H404.2 368 296.6 215.4zM0 448V242.1L217.6 403.3c11.1 8.2 24.6 12.7 38.4 12.7s27.3-4.4 38.4-12.7L512 242.1V448v0c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64v0zM176 160H336c8.8 0 16 7.2 16 16s-7.2 16-16 16H176c-8.8 0-16-7.2-16-16s7.2-16 16-16zm0 64H336c8.8 0 16 7.2 16 16s-7.2 16-16 16H176c-8.8 0-16-7.2-16-16s7.2-16 16-16z" } }, "free": ["solid"] }, "envelopes-bulk": { "aliases": { "names": ["mail-bulk"], "unicodes": { "secondary": ["10f674"] } }, "changes": ["5.3.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "archive", "envelope", "letter", "post office", "postal", "postcard", "send", "stamp", "usps" ] }, "styles": ["solid"], "unicode": "f674", "label": "Envelopes Bulk", "voted": false, "svg": { "solid": { "last_modified": 1684767393, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M128 0C110.3 0 96 14.3 96 32V224h96V192c0-35.3 28.7-64 64-64H480V32c0-17.7-14.3-32-32-32H128zM256 160c-17.7 0-32 14.3-32 32v32h96c35.3 0 64 28.7 64 64V416H576c17.7 0 32-14.3 32-32V192c0-17.7-14.3-32-32-32H256zm240 64h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H496c-8.8 0-16-7.2-16-16V240c0-8.8 7.2-16 16-16zM64 256c-17.7 0-32 14.3-32 32v13L187.1 415.9c1.4 1 3.1 1.6 4.9 1.6s3.5-.6 4.9-1.6L352 301V288c0-17.7-14.3-32-32-32H64zm288 84.8L216 441.6c-6.9 5.1-15.3 7.9-24 7.9s-17-2.8-24-7.9L32 340.8V480c0 17.7 14.3 32 32 32H320c17.7 0 32-14.3 32-32V340.8z" } }, "free": ["solid"] }, "envira": { "changes": ["4.6.0", "5.0.0"], "ligatures": [], "search": { "terms": ["leaf"] }, "styles": ["brands"], "unicode": "f299", "label": "Envira Gallery", "voted": false, "svg": { "brands": { "last_modified": 1660014473, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M0 32c477.6 0 366.6 317.3 367.1 366.3L448 480h-26l-70.4-71.2c-39 4.2-124.4 34.5-214.4-37C47 300.3 52 214.7 0 32zm79.7 46c-49.7-23.5-5.2 9.2-5.2 9.2 45.2 31.2 66 73.7 90.2 119.9 31.5 60.2 79 139.7 144.2 167.7 65 28 34.2 12.5 6-8.5-28.2-21.2-68.2-87-91-130.2-31.7-60-61-118.6-144.2-158.1z" } }, "free": ["brands"] }, "equals": { "aliases": { "unicodes": { "composite": ["f52c"], "primary": ["f52c"], "secondary": ["103d", "10f52c"] } }, "changes": ["5.0.13", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Equals Sign", "arithmetic", "even", "match", "math"] }, "styles": ["solid"], "unicode": "3d", "label": "Equals", "voted": false, "svg": { "solid": { "last_modified": 1684767244, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M48 128c-17.7 0-32 14.3-32 32s14.3 32 32 32H400c17.7 0 32-14.3 32-32s-14.3-32-32-32H48zm0 192c-17.7 0-32 14.3-32 32s14.3 32 32 32H400c17.7 0 32-14.3 32-32s-14.3-32-32-32H48z" } }, "free": ["solid"] }, "eraser": { "aliases": { "unicodes": { "secondary": ["10f12d"] } }, "changes": [ "3.1.0", "5.0.0", "5.8.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["art", "delete", "remove", "rubber"] }, "styles": ["solid"], "unicode": "f12d", "label": "Eraser", "voted": false, "svg": { "solid": { "last_modified": 1684767367, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M290.7 57.4L57.4 290.7c-25 25-25 65.5 0 90.5l80 80c12 12 28.3 18.7 45.3 18.7H288h9.4H512c17.7 0 32-14.3 32-32s-14.3-32-32-32H387.9L518.6 285.3c25-25 25-65.5 0-90.5L381.3 57.4c-25-25-65.5-25-90.5 0zM297.4 416H288l-105.4 0-80-80L227.3 211.3 364.7 348.7 297.4 416z" } }, "free": ["solid"] }, "erlang": { "changes": ["5.0.0", "5.0.3", "5.7.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f39d", "label": "Erlang", "voted": false, "svg": { "brands": { "last_modified": 1660014468, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M87.2 53.5H0v405h100.4c-49.7-52.6-78.8-125.3-78.7-212.1-.1-76.7 24-142.7 65.5-192.9zm238.2 9.7c-45.9.1-85.1 33.5-89.2 83.2h169.9c-1.1-49.7-34.5-83.1-80.7-83.2zm230.7-9.6h.3l-.1-.1zm.3 0c31.4 42.7 48.7 97.5 46.2 162.7.5 6 .5 11.7 0 24.1H230.2c-.2 109.7 38.9 194.9 138.6 195.3 68.5-.3 118-51 151.9-106.1l96.4 48.2c-17.4 30.9-36.5 57.8-57.9 80.8H640v-405z" } }, "free": ["brands"] }, "ethereum": { "changes": ["5.0.2"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f42e", "label": "Ethereum", "voted": true, "svg": { "brands": { "last_modified": 1660014471, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M311.9 260.8L160 353.6 8 260.8 160 0l151.9 260.8zM160 383.4L8 290.6 160 512l152-221.4-152 92.8z" } }, "free": ["brands"] }, "ethernet": { "aliases": { "unicodes": { "secondary": ["10f796"] } }, "changes": ["5.6.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "cable", "cat 5", "cat 6", "connection", "hardware", "internet", "network", "wired" ] }, "styles": ["solid"], "unicode": "f796", "label": "Ethernet", "voted": true, "svg": { "solid": { "last_modified": 1684767343, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 224V416c0 17.7 14.3 32 32 32H96V336c0-8.8 7.2-16 16-16s16 7.2 16 16V448h64V336c0-8.8 7.2-16 16-16s16 7.2 16 16V448h64V336c0-8.8 7.2-16 16-16s16 7.2 16 16V448h64V336c0-8.8 7.2-16 16-16s16 7.2 16 16V448h64c17.7 0 32-14.3 32-32V224c0-17.7-14.3-32-32-32H448V160c0-17.7-14.3-32-32-32H384V96c0-17.7-14.3-32-32-32H160c-17.7 0-32 14.3-32 32v32H96c-17.7 0-32 14.3-32 32v32H32c-17.7 0-32 14.3-32 32z" } }, "free": ["solid"] }, "etsy": { "changes": ["4.7.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f2d7", "label": "Etsy", "voted": false, "svg": { "brands": { "last_modified": 1660014468, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M384 348c-1.75 10.75-13.75 110-15.5 132-117.879-4.299-219.895-4.743-368.5 0v-25.5c45.457-8.948 60.627-8.019 61-35.25 1.793-72.322 3.524-244.143 0-322-1.029-28.46-12.13-26.765-61-36v-25.5c73.886 2.358 255.933 8.551 362.999-3.75-3.5 38.25-7.75 126.5-7.75 126.5H332C320.947 115.665 313.241 68 277.25 68h-137c-10.25 0-10.75 3.5-10.75 9.75V241.5c58 .5 88.5-2.5 88.5-2.5 29.77-.951 27.56-8.502 40.75-65.251h25.75c-4.407 101.351-3.91 61.829-1.75 160.25H257c-9.155-40.086-9.065-61.045-39.501-61.5 0 0-21.5-2-88-2v139c0 26 14.25 38.25 44.25 38.25H263c63.636 0 66.564-24.996 98.751-99.75H384z" } }, "free": ["brands"] }, "euro-sign": { "aliases": { "names": ["eur", "euro"], "unicodes": { "composite": ["20ac"], "secondary": ["10f153"] } }, "changes": [ "3.2.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["Euro Sign", "currency"] }, "styles": ["solid"], "unicode": "f153", "label": "Euro Sign", "voted": false, "svg": { "solid": { "last_modified": 1684766476, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M48.1 240c-.1 2.7-.1 5.3-.1 8v16c0 2.7 0 5.3 .1 8H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H60.3C89.9 419.9 170 480 264 480h24c17.7 0 32-14.3 32-32s-14.3-32-32-32H264c-57.9 0-108.2-32.4-133.9-80H256c17.7 0 32-14.3 32-32s-14.3-32-32-32H112.2c-.1-2.6-.2-5.3-.2-8V248c0-2.7 .1-5.4 .2-8H256c17.7 0 32-14.3 32-32s-14.3-32-32-32H130.1c25.7-47.6 76-80 133.9-80h24c17.7 0 32-14.3 32-32s-14.3-32-32-32H264C170 32 89.9 92.1 60.3 176H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H48.1z" } }, "free": ["solid"] }, "evernote": { "changes": ["5.8.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f839", "label": "Evernote", "voted": false, "svg": { "brands": { "last_modified": 1660014479, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M120.82 132.21c1.6 22.31-17.55 21.59-21.61 21.59-68.93 0-73.64-1-83.58 3.34-.56.22-.74 0-.37-.37L123.79 46.45c.38-.37.6-.22.38.37-4.35 9.99-3.35 15.09-3.35 85.39zm79 308c-14.68-37.08 13-76.93 52.52-76.62 17.49 0 22.6 23.21 7.95 31.42-6.19 3.3-24.95 1.74-25.14 19.2-.05 17.09 19.67 25 31.2 24.89A45.64 45.64 0 0 0 312 393.45v-.08c0-11.63-7.79-47.22-47.54-55.34-7.72-1.54-65-6.35-68.35-50.52-3.74 16.93-17.4 63.49-43.11 69.09-8.74 1.94-69.68 7.64-112.92-36.77 0 0-18.57-15.23-28.23-57.95-3.38-15.75-9.28-39.7-11.14-62 0-18 11.14-30.45 25.07-32.2 81 0 90 2.32 101-7.8 9.82-9.24 7.8-15.5 7.8-102.78 1-8.3 7.79-30.81 53.41-24.14 6 .86 31.91 4.18 37.48 30.64l64.26 11.15c20.43 3.71 70.94 7 80.6 57.94 22.66 121.09 8.91 238.46 7.8 238.46C362.15 485.53 267.06 480 267.06 480c-18.95-.23-54.25-9.4-67.27-39.83zm80.94-204.84c-1 1.92-2.2 6 .85 7 14.09 4.93 39.75 6.84 45.88 5.53 3.11-.25 3.05-4.43 2.48-6.65-3.53-21.85-40.83-26.5-49.24-5.92z" } }, "free": ["brands"] }, "exclamation": { "aliases": { "unicodes": { "composite": ["2755", "2757", "f12a"], "primary": ["f12a"], "secondary": ["1021", "10f12a"] } }, "changes": [ "3.1.0", "5.0.0", "5.10.1", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "!", "Exclamation Mark", "alert", "danger", "error", "exclamation", "important", "mark", "notice", "notification", "notify", "outlined", "problem", "punctuation", "red exclamation mark", "warning", "white exclamation mark" ] }, "styles": ["solid"], "unicode": "21", "label": "Exclamation", "voted": false, "svg": { "solid": { "last_modified": 1684767244, "raw": "", "viewBox": [0, 0, 64, 512], "width": 64, "height": 512, "path": "M64 64c0-17.7-14.3-32-32-32S0 46.3 0 64V320c0 17.7 14.3 32 32 32s32-14.3 32-32V64zM32 480a40 40 0 1 0 0-80 40 40 0 1 0 0 80z" } }, "free": ["solid"] }, "expand": { "aliases": { "unicodes": { "secondary": ["10f065"] } }, "changes": ["5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "bigger", "crop", "enlarge", "focus", "fullscreen", "resize", "viewfinder" ] }, "styles": ["solid"], "unicode": "f065", "label": "Expand", "voted": false, "svg": { "solid": { "last_modified": 1684766329, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M32 32C14.3 32 0 46.3 0 64v96c0 17.7 14.3 32 32 32s32-14.3 32-32V96h64c17.7 0 32-14.3 32-32s-14.3-32-32-32H32zM64 352c0-17.7-14.3-32-32-32s-32 14.3-32 32v96c0 17.7 14.3 32 32 32h96c17.7 0 32-14.3 32-32s-14.3-32-32-32H64V352zM320 32c-17.7 0-32 14.3-32 32s14.3 32 32 32h64v64c0 17.7 14.3 32 32 32s32-14.3 32-32V64c0-17.7-14.3-32-32-32H320zM448 352c0-17.7-14.3-32-32-32s-32 14.3-32 32v64H320c-17.7 0-32 14.3-32 32s14.3 32 32 32h96c17.7 0 32-14.3 32-32V352z" } }, "free": ["solid"] }, "expeditedssl": { "changes": ["4.4.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f23e", "label": "ExpeditedSSL", "voted": false, "svg": { "brands": { "last_modified": 1660014477, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M248 43.4C130.6 43.4 35.4 138.6 35.4 256S130.6 468.6 248 468.6 460.6 373.4 460.6 256 365.4 43.4 248 43.4zm-97.4 132.9c0-53.7 43.7-97.4 97.4-97.4s97.4 43.7 97.4 97.4v26.6c0 5-3.9 8.9-8.9 8.9h-17.7c-5 0-8.9-3.9-8.9-8.9v-26.6c0-82.1-124-82.1-124 0v26.6c0 5-3.9 8.9-8.9 8.9h-17.7c-5 0-8.9-3.9-8.9-8.9v-26.6zM389.7 380c0 9.7-8 17.7-17.7 17.7H124c-9.7 0-17.7-8-17.7-17.7V238.3c0-9.7 8-17.7 17.7-17.7h248c9.7 0 17.7 8 17.7 17.7V380zm-248-137.3v132.9c0 2.5-1.9 4.4-4.4 4.4h-8.9c-2.5 0-4.4-1.9-4.4-4.4V242.7c0-2.5 1.9-4.4 4.4-4.4h8.9c2.5 0 4.4 1.9 4.4 4.4zm141.7 48.7c0 13-7.2 24.4-17.7 30.4v31.6c0 5-3.9 8.9-8.9 8.9h-17.7c-5 0-8.9-3.9-8.9-8.9v-31.6c-10.5-6.1-17.7-17.4-17.7-30.4 0-19.7 15.8-35.4 35.4-35.4s35.5 15.8 35.5 35.4zM248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 478.3C121 486.3 17.7 383 17.7 256S121 25.7 248 25.7 478.3 129 478.3 256 375 486.3 248 486.3z" } }, "free": ["brands"] }, "explosion": { "changes": ["6.1.0", "6.1.2", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["blast", "blowup", "boom", "crash", "detonation", "explosion"] }, "styles": ["solid"], "unicode": "e4e9", "label": "Explosion", "voted": false, "svg": { "solid": { "last_modified": 1684767444, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M499.6 11.3c6.7-10.7 20.5-14.5 31.7-8.5s15.8 19.5 10.6 31L404.8 338.6c2.2 2.3 4.3 4.7 6.3 7.1l97.2-54.7c10.5-5.9 23.6-3.1 30.9 6.4s6.3 23-2.2 31.5l-87 87H378.5c-13.2-37.3-48.7-64-90.5-64s-77.4 26.7-90.5 64H117.8L42.3 363.7c-9.7-6.7-13.1-19.6-7.9-30.3s17.4-15.9 28.7-12.4l97.2 30.4c3-3.9 6.1-7.7 9.4-11.3L107.4 236.3c-6.1-10.1-3.9-23.1 5.1-30.7s22.2-7.5 31.1 .1L246 293.6c1.5-.4 3-.8 4.5-1.1l13.6-142.7c1.2-12.3 11.5-21.7 23.9-21.7s22.7 9.4 23.9 21.7l13.5 141.9L499.6 11.3zM64 448v0H512v0h32c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H64zM288 0c13.3 0 24 10.7 24 24V72c0 13.3-10.7 24-24 24s-24-10.7-24-24V24c0-13.3 10.7-24 24-24z" } }, "free": ["solid"] }, "eye": { "aliases": { "unicodes": { "composite": ["1f441"], "secondary": ["10f06e"] } }, "changes": [ "1.0.0", "5.0.0", "5.7.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "body", "eye", "look", "optic", "see", "seen", "show", "sight", "views", "visible" ] }, "styles": ["solid", "regular"], "unicode": "f06e", "label": "Eye", "voted": false, "svg": { "solid": { "last_modified": 1684767367, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M288 32c-80.8 0-145.5 36.8-192.6 80.6C48.6 156 17.3 208 2.5 243.7c-3.3 7.9-3.3 16.7 0 24.6C17.3 304 48.6 356 95.4 399.4C142.5 443.2 207.2 480 288 480s145.5-36.8 192.6-80.6c46.8-43.5 78.1-95.4 93-131.1c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C433.5 68.8 368.8 32 288 32zM144 256a144 144 0 1 1 288 0 144 144 0 1 1 -288 0zm144-64c0 35.3-28.7 64-64 64c-7.1 0-13.9-1.2-20.3-3.3c-5.5-1.8-11.9 1.6-11.7 7.4c.3 6.9 1.3 13.8 3.2 20.7c13.7 51.2 66.4 81.6 117.6 67.9s81.6-66.4 67.9-117.6c-11.1-41.5-47.8-69.4-88.6-71.1c-5.8-.2-9.2 6.1-7.4 11.7c2.1 6.4 3.3 13.2 3.3 20.3z" }, "regular": { "last_modified": 1684767367, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M288 80c-65.2 0-118.8 29.6-159.9 67.7C89.6 183.5 63 226 49.4 256c13.6 30 40.2 72.5 78.6 108.3C169.2 402.4 222.8 432 288 432s118.8-29.6 159.9-67.7C486.4 328.5 513 286 526.6 256c-13.6-30-40.2-72.5-78.6-108.3C406.8 109.6 353.2 80 288 80zM95.4 112.6C142.5 68.8 207.2 32 288 32s145.5 36.8 192.6 80.6c46.8 43.5 78.1 95.4 93 131.1c3.3 7.9 3.3 16.7 0 24.6c-14.9 35.7-46.2 87.7-93 131.1C433.5 443.2 368.8 480 288 480s-145.5-36.8-192.6-80.6C48.6 356 17.3 304 2.5 268.3c-3.3-7.9-3.3-16.7 0-24.6C17.3 208 48.6 156 95.4 112.6zM288 336c44.2 0 80-35.8 80-80s-35.8-80-80-80c-.7 0-1.3 0-2 0c1.3 5.1 2 10.5 2 16c0 35.3-28.7 64-64 64c-5.5 0-10.9-.7-16-2c0 .7 0 1.3 0 2c0 44.2 35.8 80 80 80zm0-208a128 128 0 1 1 0 256 128 128 0 1 1 0-256z" } }, "free": ["regular", "solid"] }, "eye-dropper": { "aliases": { "names": ["eye-dropper-empty", "eyedropper"], "unicodes": { "secondary": ["10f1fb"] } }, "changes": [ "4.2.0", "5.0.0", "5.1.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["beaker", "clone", "color", "copy", "eyedropper", "pipette"] }, "styles": ["solid"], "unicode": "f1fb", "label": "Eye Dropper", "voted": false, "svg": { "solid": { "last_modified": 1684767367, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M341.6 29.2L240.1 130.8l-9.4-9.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3l-9.4-9.4L482.8 170.4c39-39 39-102.2 0-141.1s-102.2-39-141.1 0zM55.4 323.3c-15 15-23.4 35.4-23.4 56.6v42.4L5.4 462.2c-8.5 12.7-6.8 29.6 4 40.4s27.7 12.5 40.4 4L89.7 480h42.4c21.2 0 41.6-8.4 56.6-23.4L309.4 335.9l-45.3-45.3L143.4 411.3c-3 3-7.1 4.7-11.3 4.7H96V379.9c0-4.2 1.7-8.3 4.7-11.3L221.4 247.9l-45.3-45.3L55.4 323.3z" } }, "free": ["solid"] }, "eye-low-vision": { "aliases": { "names": ["low-vision"], "unicodes": { "secondary": ["10f2a8"] } }, "changes": [ "4.6.0", "5.0.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["blind", "eye", "sight"] }, "styles": ["solid"], "unicode": "f2a8", "label": "Eye Low Vision", "voted": false, "svg": { "solid": { "last_modified": 1684767368, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7L525.6 386.7c39.6-40.6 66.4-86.1 79.9-118.4c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C465.5 68.8 400.8 32 320 32c-68.2 0-125 26.3-169.3 60.8L38.8 5.1zM223 149.5c48.6-44.3 123-50.8 179.3-11.7c60.8 42.4 78.9 123.2 44.2 186.9L408 294.5c8.4-19.3 10.6-41.4 4.8-63.3c-11.1-41.5-47.8-69.4-88.6-71.1c-5.8-.2-9.2 6.1-7.4 11.7c2.1 6.4 3.3 13.2 3.3 20.3c0 10.2-2.4 19.8-6.6 28.3L223 149.5zm223.1 298L83.1 161.5c-11 14.4-20.5 28.7-28.4 42.2l339 265.7c18.7-5.5 36.2-13 52.6-21.8zM34.5 268.3c14.9 35.7 46.2 87.7 93 131.1C174.5 443.2 239.2 480 320 480c3.1 0 6.1-.1 9.2-.2L33.1 247.8c-1.8 6.8-1.3 14 1.4 20.5z" } }, "free": ["solid"] }, "eye-slash": { "aliases": { "unicodes": { "secondary": ["10f070"] } }, "changes": [ "1.0.0", "5.0.0", "5.7.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "blind", "hide", "show", "toggle", "unseen", "views", "visible", "visiblity" ] }, "styles": ["solid", "regular"], "unicode": "f070", "label": "Eye Slash", "voted": false, "svg": { "solid": { "last_modified": 1684767368, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7L525.6 386.7c39.6-40.6 66.4-86.1 79.9-118.4c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C465.5 68.8 400.8 32 320 32c-68.2 0-125 26.3-169.3 60.8L38.8 5.1zM223.1 149.5C248.6 126.2 282.7 112 320 112c79.5 0 144 64.5 144 144c0 24.9-6.3 48.3-17.4 68.7L408 294.5c8.4-19.3 10.6-41.4 4.8-63.3c-11.1-41.5-47.8-69.4-88.6-71.1c-5.8-.2-9.2 6.1-7.4 11.7c2.1 6.4 3.3 13.2 3.3 20.3c0 10.2-2.4 19.8-6.6 28.3l-90.3-70.8zM373 389.9c-16.4 6.5-34.3 10.1-53 10.1c-79.5 0-144-64.5-144-144c0-6.9 .5-13.6 1.4-20.2L83.1 161.5C60.3 191.2 44 220.8 34.5 243.7c-3.3 7.9-3.3 16.7 0 24.6c14.9 35.7 46.2 87.7 93 131.1C174.5 443.2 239.2 480 320 480c47.8 0 89.9-12.9 126.2-32.5L373 389.9z" }, "regular": { "last_modified": 1684767368, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7L525.6 386.7c39.6-40.6 66.4-86.1 79.9-118.4c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C465.5 68.8 400.8 32 320 32c-68.2 0-125 26.3-169.3 60.8L38.8 5.1zm151 118.3C226 97.7 269.5 80 320 80c65.2 0 118.8 29.6 159.9 67.7C518.4 183.5 545 226 558.6 256c-12.6 28-36.6 66.8-70.9 100.9l-53.8-42.2c9.1-17.6 14.2-37.5 14.2-58.7c0-70.7-57.3-128-128-128c-32.2 0-61.7 11.9-84.2 31.5l-46.1-36.1zM394.9 284.2l-81.5-63.9c4.2-8.5 6.6-18.2 6.6-28.3c0-5.5-.7-10.9-2-16c.7 0 1.3 0 2 0c44.2 0 80 35.8 80 80c0 9.9-1.8 19.4-5.1 28.2zm9.4 130.3C378.8 425.4 350.7 432 320 432c-65.2 0-118.8-29.6-159.9-67.7C121.6 328.5 95 286 81.4 256c8.3-18.4 21.5-41.5 39.4-64.8L83.1 161.5C60.3 191.2 44 220.8 34.5 243.7c-3.3 7.9-3.3 16.7 0 24.6c14.9 35.7 46.2 87.7 93 131.1C174.5 443.2 239.2 480 320 480c47.8 0 89.9-12.9 126.2-32.5l-41.9-33zM192 256c0 70.7 57.3 128 128 128c13.3 0 26.1-2 38.2-5.8L302 334c-23.5-5.4-43.1-21.2-53.7-42.3l-56.1-44.2c-.2 2.8-.3 5.6-.3 8.5z" } }, "free": ["regular", "solid"] }, "f": { "aliases": { "unicodes": { "composite": ["66"] } }, "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Latin Capital Letter F", "Latin Small Letter F", "letter"] }, "styles": ["solid"], "unicode": "46", "label": "F", "voted": false, "svg": { "solid": { "last_modified": 1684767246, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M64 32C28.7 32 0 60.7 0 96V256 448c0 17.7 14.3 32 32 32s32-14.3 32-32V288H224c17.7 0 32-14.3 32-32s-14.3-32-32-32H64V96H288c17.7 0 32-14.3 32-32s-14.3-32-32-32H64z" } }, "free": ["solid"] }, "face-angry": { "aliases": { "names": ["angry"], "unicodes": { "composite": ["1f620"], "secondary": ["10f556"] } }, "changes": [ "5.1.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "angry", "angry face", "disapprove", "emoticon", "face", "mad", "upset" ] }, "styles": ["solid", "regular"], "unicode": "f556", "label": "Face Angry", "voted": false, "svg": { "solid": { "last_modified": 1684767582, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zM338.7 395.9c6.6-5.9 7.1-16 1.2-22.6C323.8 355.4 295.7 336 256 336s-67.8 19.4-83.9 37.3c-5.9 6.6-5.4 16.7 1.2 22.6s16.7 5.4 22.6-1.2c11.7-13 31.6-26.7 60.1-26.7s48.4 13.7 60.1 26.7c5.9 6.6 16 7.1 22.6 1.2zM176.4 272c17.7 0 32-14.3 32-32c0-1.5-.1-3-.3-4.4l10.9 3.6c8.4 2.8 17.4-1.7 20.2-10.1s-1.7-17.4-10.1-20.2l-96-32c-8.4-2.8-17.4 1.7-20.2 10.1s1.7 17.4 10.1 20.2l30.7 10.2c-5.8 5.8-9.3 13.8-9.3 22.6c0 17.7 14.3 32 32 32zm192-32c0-8.9-3.6-17-9.5-22.8l30.2-10.1c8.4-2.8 12.9-11.9 10.1-20.2s-11.9-12.9-20.2-10.1l-96 32c-8.4 2.8-12.9 11.9-10.1 20.2s11.9 12.9 20.2 10.1l11.7-3.9c-.2 1.5-.3 3.1-.3 4.7c0 17.7 14.3 32 32 32s32-14.3 32-32z" }, "regular": { "last_modified": 1684767582, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 48a208 208 0 1 1 0 416 208 208 0 1 1 0-416zm0 464A256 256 0 1 0 256 0a256 256 0 1 0 0 512zm72.4-118.5c9.7-9 10.2-24.2 1.2-33.9C315.3 344.3 290.6 328 256 328s-59.3 16.3-73.5 31.6c-9 9.7-8.5 24.9 1.2 33.9s24.9 8.5 33.9-1.2c7.4-7.9 20-16.4 38.5-16.4s31.1 8.5 38.5 16.4c9 9.7 24.2 10.2 33.9 1.2zM176.4 272c17.7 0 32-14.3 32-32c0-1.5-.1-3-.3-4.4l10.9 3.6c8.4 2.8 17.4-1.7 20.2-10.1s-1.7-17.4-10.1-20.2l-96-32c-8.4-2.8-17.4 1.7-20.2 10.1s1.7 17.4 10.1 20.2l30.7 10.2c-5.8 5.8-9.3 13.8-9.3 22.6c0 17.7 14.3 32 32 32zm192-32c0-8.9-3.6-17-9.5-22.8l30.2-10.1c8.4-2.8 12.9-11.9 10.1-20.2s-11.9-12.9-20.2-10.1l-96 32c-8.4 2.8-12.9 11.9-10.1 20.2s11.9 12.9 20.2 10.1l11.7-3.9c-.2 1.5-.3 3.1-.3 4.7c0 17.7 14.3 32 32 32s32-14.3 32-32z" } }, "free": ["regular", "solid"] }, "face-dizzy": { "aliases": { "names": ["dizzy"], "unicodes": { "secondary": ["10f567"] } }, "changes": [ "5.1.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["dazed", "dead", "disapprove", "emoticon", "face"] }, "styles": ["solid", "regular"], "unicode": "f567", "label": "Face Dizzy", "voted": false, "svg": { "solid": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zm0-224a64 64 0 1 1 0 128 64 64 0 1 1 0-128zM100.7 132.7c6.2-6.2 16.4-6.2 22.6 0L160 169.4l36.7-36.7c6.2-6.2 16.4-6.2 22.6 0s6.2 16.4 0 22.6L182.6 192l36.7 36.7c6.2 6.2 6.2 16.4 0 22.6s-16.4 6.2-22.6 0L160 214.6l-36.7 36.7c-6.2 6.2-16.4 6.2-22.6 0s-6.2-16.4 0-22.6L137.4 192l-36.7-36.7c-6.2-6.2-6.2-16.4 0-22.6zm192 0c6.2-6.2 16.4-6.2 22.6 0L352 169.4l36.7-36.7c6.2-6.2 16.4-6.2 22.6 0s6.2 16.4 0 22.6L374.6 192l36.7 36.7c6.2 6.2 6.2 16.4 0 22.6s-16.4 6.2-22.6 0L352 214.6l-36.7 36.7c-6.2 6.2-16.4 6.2-22.6 0s-6.2-16.4 0-22.6L329.4 192l-36.7-36.7c-6.2-6.2-6.2-16.4 0-22.6z" }, "regular": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M464 256A208 208 0 1 0 48 256a208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm256 32a64 64 0 1 1 0 128 64 64 0 1 1 0-128zM103 135c9.4-9.4 24.6-9.4 33.9 0l23 23 23-23c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-23 23 23 23c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-23-23-23 23c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l23-23-23-23c-9.4-9.4-9.4-24.6 0-33.9zm192 0c9.4-9.4 24.6-9.4 33.9 0l23 23 23-23c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-23 23 23 23c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-23-23-23 23c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l23-23-23-23c-9.4-9.4-9.4-24.6 0-33.9z" } }, "free": ["regular", "solid"] }, "face-flushed": { "aliases": { "names": ["flushed"], "unicodes": { "composite": ["1f633"], "secondary": ["10f579"] } }, "changes": [ "5.1.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "dazed", "embarrassed", "emoticon", "face", "flushed", "flushed face" ] }, "styles": ["solid", "regular"], "unicode": "f579", "label": "Face Flushed", "voted": false, "svg": { "solid": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zM176 384c0 8.8 7.2 16 16 16H320c8.8 0 16-7.2 16-16s-7.2-16-16-16H192c-8.8 0-16 7.2-16 16zm-16-88a72 72 0 1 0 0-144 72 72 0 1 0 0 144zm264-72a72 72 0 1 0 -144 0 72 72 0 1 0 144 0zm-288 0a24 24 0 1 1 48 0 24 24 0 1 1 -48 0zm192 0a24 24 0 1 1 48 0 24 24 0 1 1 -48 0z" }, "regular": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M464 256A208 208 0 1 1 48 256a208 208 0 1 1 416 0zM256 0a256 256 0 1 0 0 512A256 256 0 1 0 256 0zM160.4 248a24 24 0 1 0 0-48 24 24 0 1 0 0 48zm216-24a24 24 0 1 0 -48 0 24 24 0 1 0 48 0zM192 336c-13.3 0-24 10.7-24 24s10.7 24 24 24H320c13.3 0 24-10.7 24-24s-10.7-24-24-24H192zM160 176a48 48 0 1 1 0 96 48 48 0 1 1 0-96zm0 128a80 80 0 1 0 0-160 80 80 0 1 0 0 160zm144-80a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zm128 0a80 80 0 1 0 -160 0 80 80 0 1 0 160 0z" } }, "free": ["regular", "solid"] }, "face-frown": { "aliases": { "names": ["frown"], "unicodes": { "composite": ["2639"], "secondary": ["10f119"] } }, "changes": [ "3.1.0", "5.0.0", "5.0.9", "5.1.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "disapprove", "emoticon", "face", "frown", "frowning face", "rating", "sad" ] }, "styles": ["solid", "regular"], "unicode": "f119", "label": "Face Frown", "voted": false, "svg": { "solid": { "last_modified": 1684767582, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM159.3 388.7c-2.6 8.4-11.6 13.2-20 10.5s-13.2-11.6-10.5-20C145.2 326.1 196.3 288 256 288s110.8 38.1 127.3 91.3c2.6 8.4-2.1 17.4-10.5 20s-17.4-2.1-20-10.5C340.5 349.4 302.1 320 256 320s-84.5 29.4-96.7 68.7zM144.4 208a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm192-32a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" }, "regular": { "last_modified": 1684767582, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M464 256A208 208 0 1 0 48 256a208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zM174.6 384.1c-4.5 12.5-18.2 18.9-30.7 14.4s-18.9-18.2-14.4-30.7C146.9 319.4 198.9 288 256 288s109.1 31.4 126.6 79.9c4.5 12.5-2 26.2-14.4 30.7s-26.2-2-30.7-14.4C328.2 358.5 297.2 336 256 336s-72.2 22.5-81.4 48.1zM144.4 208a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm192-32a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" } }, "free": ["regular", "solid"] }, "face-frown-open": { "aliases": { "names": ["frown-open"], "unicodes": { "composite": ["1f626"], "secondary": ["10f57a"] } }, "changes": [ "5.1.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "disapprove", "emoticon", "face", "frown", "frowning face with open mouth", "mouth", "open", "rating", "sad" ] }, "styles": ["solid", "regular"], "unicode": "f57a", "label": "Face Frown Open", "voted": false, "svg": { "solid": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM176.4 176a32 32 0 1 1 0 64 32 32 0 1 1 0-64zm128 32a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm-122 174.5c-12.4 5.2-26.5-4.1-21.1-16.4c16-36.6 52.4-62.1 94.8-62.1s78.8 25.6 94.8 62.1c5.4 12.3-8.7 21.6-21.1 16.4c-22.4-9.5-47.4-14.8-73.7-14.8s-51.3 5.3-73.7 14.8z" }, "regular": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M464 256A208 208 0 1 0 48 256a208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zM182.4 382.5c-12.4 5.2-26.5-4.1-21.1-16.4c16-36.6 52.4-62.1 94.8-62.1s78.8 25.6 94.8 62.1c5.4 12.3-8.7 21.6-21.1 16.4c-22.4-9.5-47.4-14.8-73.7-14.8s-51.3 5.3-73.7 14.8zM144.4 208a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm192-32a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" } }, "free": ["regular", "solid"] }, "face-grimace": { "aliases": { "names": ["grimace"], "unicodes": { "composite": ["1f62c"], "secondary": ["10f57f"] } }, "changes": [ "5.1.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "cringe", "emoticon", "face", "grimace", "grimacing face", "teeth" ] }, "styles": ["solid", "regular"], "unicode": "f57f", "label": "Face Grimace", "voted": false, "svg": { "solid": { "last_modified": 1684767582, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zm96-112h-8V360l55.3 0c-3.8 22.7-23.6 40-47.3 40zm47.3-56L344 344V304h8c23.8 0 43.5 17.3 47.3 40zM328 344H264V304h64v40zm0 56H264V360h64v40zm-80-96v40l-64 0V304h64zm0 56v40H184V360l64 0zm-80-16H112.7c3.8-22.7 23.6-40 47.3-40h8v40zm0 56h-8c-23.8 0-43.5-17.3-47.3-40H168v40zM144.4 208a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm192-32a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" }, "regular": { "last_modified": 1684767582, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 48a208 208 0 1 0 0 416 208 208 0 1 0 0-416zM512 256A256 256 0 1 1 0 256a256 256 0 1 1 512 0zM168 320c-13.3 0-24 10.7-24 24s10.7 24 24 24h8V320h-8zm40 48h32V320H208v48zm96 0V320H272v48h32zm32 0h8c13.3 0 24-10.7 24-24s-10.7-24-24-24h-8v48zM168 288H344c30.9 0 56 25.1 56 56s-25.1 56-56 56H168c-30.9 0-56-25.1-56-56s25.1-56 56-56zm-23.6-80a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm192-32a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" } }, "free": ["regular", "solid"] }, "face-grin": { "aliases": { "names": ["grin"], "unicodes": { "composite": ["1f600"], "secondary": ["10f580"] } }, "changes": [ "5.1.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["emoticon", "face", "grin", "grinning face", "laugh", "smile"] }, "styles": ["solid", "regular"], "unicode": "f580", "label": "Face Grin", "voted": false, "svg": { "solid": { "last_modified": 1684767582, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM388.1 312.8c12.3-3.8 24.3 6.9 19.3 18.7C382.4 390.6 324.2 432 256.3 432s-126.2-41.4-151.1-100.5c-5-11.8 7-22.5 19.3-18.7c39.7 12.2 84.5 19 131.8 19s92.1-6.8 131.8-19zM144.4 208a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm192-32a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" }, "regular": { "last_modified": 1684767582, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M464 256A208 208 0 1 0 48 256a208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm349.5 52.4c18.7-4.4 35.9 12 25.5 28.1C350.4 374.6 306.3 400 255.9 400s-94.5-25.4-119.1-63.5c-10.4-16.1 6.8-32.5 25.5-28.1c28.9 6.8 60.5 10.5 93.6 10.5s64.7-3.7 93.6-10.5zM144.4 208a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm192-32a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" } }, "free": ["regular", "solid"] }, "face-grin-beam": { "aliases": { "names": ["grin-beam"], "unicodes": { "composite": ["1f604"], "secondary": ["10f582"] } }, "changes": [ "5.1.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "emoticon", "eye", "face", "grinning face with smiling eyes", "laugh", "mouth", "open", "smile" ] }, "styles": ["solid", "regular"], "unicode": "f582", "label": "Face Grin Beam", "voted": false, "svg": { "solid": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM388.1 312.8c12.3-3.8 24.3 6.9 19.3 18.7C382.4 390.6 324.2 432 256.3 432s-126.2-41.4-151.1-100.5c-5-11.8 7-22.5 19.3-18.7c39.7 12.2 84.5 19 131.8 19s92.1-6.8 131.8-19zm-170.5-84l0 0 0 0-.2-.2c-.2-.2-.4-.5-.7-.9c-.6-.8-1.6-2-2.8-3.4c-2.5-2.8-6-6.6-10.2-10.3c-8.8-7.8-18.8-14-27.7-14s-18.9 6.2-27.7 14c-4.2 3.7-7.7 7.5-10.2 10.3c-1.2 1.4-2.2 2.6-2.8 3.4c-.3 .4-.6 .7-.7 .9l-.2 .2 0 0 0 0 0 0c-2.1 2.8-5.7 3.9-8.9 2.8s-5.5-4.1-5.5-7.6c0-17.9 6.7-35.6 16.6-48.8c9.8-13 23.9-23.2 39.4-23.2s29.6 10.2 39.4 23.2c9.9 13.2 16.6 30.9 16.6 48.8c0 3.4-2.2 6.5-5.5 7.6s-6.9 0-8.9-2.8l0 0 0 0zm160 0l0 0-.2-.2c-.2-.2-.4-.5-.7-.9c-.6-.8-1.6-2-2.8-3.4c-2.5-2.8-6-6.6-10.2-10.3c-8.8-7.8-18.8-14-27.7-14s-18.9 6.2-27.7 14c-4.2 3.7-7.7 7.5-10.2 10.3c-1.2 1.4-2.2 2.6-2.8 3.4c-.3 .4-.6 .7-.7 .9l-.2 .2 0 0 0 0 0 0c-2.1 2.8-5.7 3.9-8.9 2.8s-5.5-4.1-5.5-7.6c0-17.9 6.7-35.6 16.6-48.8c9.8-13 23.9-23.2 39.4-23.2s29.6 10.2 39.4 23.2c9.9 13.2 16.6 30.9 16.6 48.8c0 3.4-2.2 6.5-5.5 7.6s-6.9 0-8.9-2.8l0 0 0 0 0 0z" }, "regular": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M464 256A208 208 0 1 0 48 256a208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm349.5 52.4c18.7-4.4 35.9 12 25.5 28.1C350.4 374.6 306.3 400 255.9 400s-94.5-25.4-119.1-63.5c-10.4-16.1 6.8-32.5 25.5-28.1c28.9 6.8 60.5 10.5 93.6 10.5s64.7-3.7 93.6-10.5zM217.6 228.8l0 0 0 0-.2-.2c-.2-.2-.4-.5-.7-.9c-.6-.8-1.6-2-2.8-3.4c-2.5-2.8-6-6.6-10.2-10.3c-8.8-7.8-18.8-14-27.7-14s-18.9 6.2-27.7 14c-4.2 3.7-7.7 7.5-10.2 10.3c-1.2 1.4-2.2 2.6-2.8 3.4c-.3 .4-.6 .7-.7 .9l-.2 .2 0 0 0 0 0 0c-2.1 2.8-5.7 3.9-8.9 2.8s-5.5-4.1-5.5-7.6c0-17.9 6.7-35.6 16.6-48.8c9.8-13 23.9-23.2 39.4-23.2s29.6 10.2 39.4 23.2c9.9 13.2 16.6 30.9 16.6 48.8c0 3.4-2.2 6.5-5.5 7.6s-6.9 0-8.9-2.8l0 0 0 0zm160 0l0 0-.2-.2c-.2-.2-.4-.5-.7-.9c-.6-.8-1.6-2-2.8-3.4c-2.5-2.8-6-6.6-10.2-10.3c-8.8-7.8-18.8-14-27.7-14s-18.9 6.2-27.7 14c-4.2 3.7-7.7 7.5-10.2 10.3c-1.2 1.4-2.2 2.6-2.8 3.4c-.3 .4-.6 .7-.7 .9l-.2 .2 0 0 0 0 0 0c-2.1 2.8-5.7 3.9-8.9 2.8s-5.5-4.1-5.5-7.6c0-17.9 6.7-35.6 16.6-48.8c9.8-13 23.9-23.2 39.4-23.2s29.6 10.2 39.4 23.2c9.9 13.2 16.6 30.9 16.6 48.8c0 3.4-2.2 6.5-5.5 7.6s-6.9 0-8.9-2.8l0 0 0 0 0 0z" } }, "free": ["regular", "solid"] }, "face-grin-beam-sweat": { "aliases": { "names": ["grin-beam-sweat"], "unicodes": { "composite": ["1f605"], "secondary": ["10f583"] } }, "changes": [ "5.1.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "cold", "embarass", "emoticon", "face", "grinning face with sweat", "open", "smile", "sweat" ] }, "styles": ["solid", "regular"], "unicode": "f583", "label": "Face Grin Beam Sweat", "voted": false, "svg": { "solid": { "last_modified": 1684767582, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M476.8 126.3c-4.1 1.1-8.4 1.7-12.8 1.7c-26.5 0-48-21-48-47c0-5 1.8-11.3 4.6-18.1c.3-.7 .6-1.4 .9-2.1c9-20.2 26.5-44.9 36-57.5c3.2-4.4 9.6-4.4 12.8 0C483.4 20.6 512 61 512 81c0 21.7-14.9 39.8-35.2 45.3zM256 0c51.4 0 99.3 15.2 139.4 41.2c-1.5 3.1-3 6.2-4.3 9.3c-3.4 8-7.1 19-7.1 30.5c0 44.3 36.6 79 80 79c9.6 0 18.8-1.7 27.4-4.8c13.3 30.9 20.6 65 20.6 100.8c0 141.4-114.6 256-256 256S0 397.4 0 256S114.6 0 256 0zM383.8 317.8C345.3 329.4 301.9 336 256 336s-89.3-6.6-127.8-18.2c-12.3-3.7-24.3 7-19.2 18.7c24.5 56.9 81.1 96.7 147 96.7s122.5-39.8 147-96.7c5.1-11.8-6.9-22.4-19.2-18.7zm-166.2-89l0 0 0 0c2.1 2.8 5.7 3.9 8.9 2.8s5.5-4.1 5.5-7.6c0-17.9-6.7-35.6-16.6-48.8c-9.8-13-23.9-23.2-39.4-23.2s-29.6 10.2-39.4 23.2C126.7 188.4 120 206.1 120 224c0 3.4 2.2 6.5 5.5 7.6s6.9 0 8.9-2.8l0 0 0 0 0 0 .2-.2c.2-.2 .4-.5 .7-.9c.6-.8 1.6-2 2.8-3.4c2.5-2.8 6-6.6 10.2-10.3c8.8-7.8 18.8-14 27.7-14s18.9 6.2 27.7 14c4.2 3.7 7.7 7.5 10.2 10.3c1.2 1.4 2.2 2.6 2.8 3.4c.3 .4 .6 .7 .7 .9l.2 .2 0 0 0 0zm160 0l0 0 0 0 0 0c2.1 2.8 5.7 3.9 8.9 2.8s5.5-4.1 5.5-7.6c0-17.9-6.7-35.6-16.6-48.8c-9.8-13-23.9-23.2-39.4-23.2s-29.6 10.2-39.4 23.2C286.7 188.4 280 206.1 280 224c0 3.4 2.2 6.5 5.5 7.6s6.9 0 8.9-2.8l0 0 0 0 0 0 .2-.2c.2-.2 .4-.5 .7-.9c.6-.8 1.6-2 2.8-3.4c2.5-2.8 6-6.6 10.2-10.3c8.8-7.8 18.8-14 27.7-14s18.9 6.2 27.7 14c4.2 3.7 7.7 7.5 10.2 10.3c1.2 1.4 2.2 2.6 2.8 3.4c.3 .4 .6 .7 .7 .9l.2 .2 0 0z" }, "regular": { "last_modified": 1684767582, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M476.8 126.3C497.1 120.8 512 102.7 512 81c0-20-28.6-60.4-41.6-77.7c-3.2-4.4-9.6-4.4-12.8 0c-9.5 12.6-27.1 37.2-36 57.5c-.3 .7-.6 1.4-.9 2.1C417.8 69.7 416 76 416 81c0 26 21.5 47 48 47c4.4 0 8.7-.6 12.8-1.7zM395.4 41.2C355.3 15.2 307.4 0 256 0C114.6 0 0 114.6 0 256S114.6 512 256 512s256-114.6 256-256c0-35.8-7.3-69.9-20.6-100.8c-8.6 3.1-17.8 4.8-27.4 4.8c-8.9 0-17.6-1.5-25.7-4.2C454.7 185.5 464 219.7 464 256c0 114.9-93.1 208-208 208S48 370.9 48 256S141.1 48 256 48c48.7 0 93.4 16.7 128.9 44.7c-.6-3.8-.9-7.7-.9-11.7c0-11.4 3.8-22.4 7.1-30.5c1.3-3.1 2.7-6.2 4.3-9.3zM375 336.5c10.4-16.1-6.8-32.5-25.5-28.1c-28.9 6.8-60.5 10.5-93.6 10.5s-64.7-3.7-93.6-10.5c-18.7-4.4-35.9 12-25.5 28.1c24.6 38.1 68.7 63.5 119.1 63.5s94.5-25.4 119.1-63.5zM217.6 228.8l0 0 0 0 0 0c2.1 2.8 5.7 3.9 8.9 2.8s5.5-4.1 5.5-7.6c0-17.9-6.7-35.6-16.6-48.8c-9.8-13-23.9-23.2-39.4-23.2s-29.6 10.2-39.4 23.2C126.7 188.4 120 206.1 120 224c0 3.4 2.2 6.5 5.5 7.6s6.9 0 8.9-2.8l0 0 0 0 0 0 .2-.2c.2-.2 .4-.5 .7-.9c.6-.8 1.6-2 2.8-3.4c2.5-2.8 6-6.6 10.2-10.3c8.8-7.8 18.8-14 27.7-14s18.9 6.2 27.7 14c4.2 3.7 7.7 7.5 10.2 10.3c1.2 1.4 2.2 2.6 2.8 3.4c.3 .4 .6 .7 .7 .9l.2 .2 0 0zm160 0l0 0 0 0c2.1 2.8 5.7 3.9 8.9 2.8s5.5-4.1 5.5-7.6c0-17.9-6.7-35.6-16.6-48.8c-9.8-13-23.9-23.2-39.4-23.2s-29.6 10.2-39.4 23.2C286.7 188.4 280 206.1 280 224c0 3.4 2.2 6.5 5.5 7.6s6.9 0 8.9-2.8l0 0 0 0 0 0 .2-.2c.2-.2 .4-.5 .7-.9c.6-.8 1.6-2 2.8-3.4c2.5-2.8 6-6.6 10.2-10.3c8.8-7.8 18.8-14 27.7-14s18.9 6.2 27.7 14c4.2 3.7 7.7 7.5 10.2 10.3c1.2 1.4 2.2 2.6 2.8 3.4c.3 .4 .6 .7 .7 .9l.2 .2 0 0 0 0z" } }, "free": ["regular", "solid"] }, "face-grin-hearts": { "aliases": { "names": ["grin-hearts"], "unicodes": { "composite": ["1f60d"], "secondary": ["10f584"] } }, "changes": [ "5.1.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "emoticon", "eye", "face", "love", "smile", "smiling face with heart-eyes" ] }, "styles": ["solid", "regular"], "unicode": "f584", "label": "Face Grin Hearts", "voted": false, "svg": { "solid": { "last_modified": 1684767582, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM388.1 312.8c12.3-3.8 24.3 6.9 19.3 18.7C382.4 390.6 324.2 432 256.3 432s-126.2-41.4-151.1-100.5c-5-11.8 7-22.5 19.3-18.7c39.7 12.2 84.5 19 131.8 19s92.1-6.8 131.8-19zM199.3 129.1c17.8 4.8 28.4 23.1 23.6 40.8l-17.4 65c-2.3 8.5-11.1 13.6-19.6 11.3l-65.1-17.4c-17.8-4.8-28.4-23.1-23.6-40.8s23.1-28.4 40.8-23.6l16.1 4.3 4.3-16.1c4.8-17.8 23.1-28.4 40.8-23.6zm154.3 23.6l4.3 16.1 16.1-4.3c17.8-4.8 36.1 5.8 40.8 23.6s-5.8 36.1-23.6 40.8l-65.1 17.4c-8.5 2.3-17.3-2.8-19.6-11.3l-17.4-65c-4.8-17.8 5.8-36.1 23.6-40.8s36.1 5.8 40.9 23.6z" }, "regular": { "last_modified": 1684767582, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M464 256A208 208 0 1 0 48 256a208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm349.5 52.4c18.7-4.4 35.9 12 25.5 28.1C350.4 374.6 306.3 400 255.9 400s-94.5-25.4-119.1-63.5c-10.4-16.1 6.8-32.5 25.5-28.1c28.9 6.8 60.5 10.5 93.6 10.5s64.7-3.7 93.6-10.5zM215.3 137.1c17.8 4.8 28.4 23.1 23.6 40.8l-17.4 65c-2.3 8.5-11.1 13.6-19.6 11.3l-65.1-17.4c-17.8-4.8-28.4-23.1-23.6-40.8s23.1-28.4 40.8-23.6l16.1 4.3 4.3-16.1c4.8-17.8 23.1-28.4 40.8-23.6zm122.3 23.6l4.3 16.1 16.1-4.3c17.8-4.8 36.1 5.8 40.8 23.6s-5.8 36.1-23.6 40.8l-65.1 17.4c-8.5 2.3-17.3-2.8-19.6-11.3l-17.4-65c-4.8-17.8 5.8-36.1 23.6-40.8s36.1 5.8 40.9 23.6z" } }, "free": ["regular", "solid"] }, "face-grin-squint": { "aliases": { "names": ["grin-squint"], "unicodes": { "composite": ["1f606"], "secondary": ["10f585"] } }, "changes": [ "5.1.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "emoticon", "face", "grinning squinting face", "laugh", "mouth", "satisfied", "smile" ] }, "styles": ["solid", "regular"], "unicode": "f585", "label": "Face Grin Squint", "voted": false, "svg": { "solid": { "last_modified": 1684767582, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM388.1 312.8c12.3-3.8 24.3 6.9 19.3 18.7C382.4 390.6 324.2 432 256.3 432s-126.2-41.4-151.1-100.5c-5-11.8 7-22.5 19.3-18.7c39.7 12.2 84.5 19 131.8 19s92.1-6.8 131.8-19zM133.5 146.7l89.9 47.9c10.7 5.7 10.7 21.1 0 26.8l-89.9 47.9c-7.9 4.2-17.5-1.5-17.5-10.5c0-2.8 1-5.5 2.8-7.6l36-43.2-36-43.2c-1.8-2.1-2.8-4.8-2.8-7.6c0-9 9.6-14.7 17.5-10.5zM396 157.1c0 2.8-1 5.5-2.8 7.6l-36 43.2 36 43.2c1.8 2.1 2.8 4.8 2.8 7.6c0 9-9.6 14.7-17.5 10.5l-89.9-47.9c-10.7-5.7-10.7-21.1 0-26.8l89.9-47.9c7.9-4.2 17.5 1.5 17.5 10.5z" }, "regular": { "last_modified": 1684767582, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M464 256A208 208 0 1 0 48 256a208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm349.5 52.4c18.7-4.4 35.9 12 25.5 28.1C350.4 374.6 306.3 400 255.9 400s-94.5-25.4-119.1-63.5c-10.4-16.1 6.8-32.5 25.5-28.1c28.9 6.8 60.5 10.5 93.6 10.5s64.7-3.7 93.6-10.5zm-216-161.7l89.9 47.9c10.7 5.7 10.7 21.1 0 26.8l-89.9 47.9c-7.9 4.2-17.5-1.5-17.5-10.5c0-2.8 1-5.5 2.8-7.6l36-43.2-36-43.2c-1.8-2.1-2.8-4.8-2.8-7.6c0-9 9.6-14.7 17.5-10.5zM396 157.1c0 2.8-1 5.5-2.8 7.6l-36 43.2 36 43.2c1.8 2.1 2.8 4.8 2.8 7.6c0 9-9.6 14.7-17.5 10.5l-89.9-47.9c-10.7-5.7-10.7-21.1 0-26.8l89.9-47.9c7.9-4.2 17.5 1.5 17.5 10.5z" } }, "free": ["regular", "solid"] }, "face-grin-squint-tears": { "aliases": { "names": ["grin-squint-tears"], "unicodes": { "composite": ["1f923"], "secondary": ["10f586"] } }, "changes": [ "5.1.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "emoticon", "face", "floor", "happy", "laugh", "rolling", "rolling on the floor laughing", "smile" ] }, "styles": ["solid", "regular"], "unicode": "f586", "label": "Face Grin Squint Tears", "voted": false, "svg": { "solid": { "last_modified": 1684767582, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M426.8 14.2C446-5 477.5-4.6 497.1 14.9s20 51 .7 70.3c-6.8 6.8-21.4 12.4-37.4 16.7c-16.3 4.4-34.1 7.5-46.3 9.3c-1.6 .2-3.1 .5-4.6 .6c-4.9 .8-9.1-2.8-9.5-7.4c-.1-.7 0-1.4 .1-2.1c1.6-11.2 4.6-29.6 9-47c.3-1.3 .7-2.6 1-3.9c4.3-15.9 9.8-30.5 16.7-37.4zm-44.7 19c-1.5 4.8-2.9 9.6-4.1 14.3c-4.8 18.9-8 38.5-9.7 50.3c-4 26.8 18.9 49.7 45.7 45.8c11.9-1.6 31.5-4.8 50.4-9.7c4.7-1.2 9.5-2.5 14.3-4.1C534.2 227.5 520.2 353.8 437 437c-83.2 83.2-209.5 97.2-307.2 41.8c1.5-4.8 2.8-9.6 4-14.3c4.8-18.9 8-38.5 9.7-50.3c4-26.8-18.9-49.7-45.7-45.8c-11.9 1.6-31.5 4.8-50.4 9.7c-4.7 1.2-9.5 2.5-14.3 4.1C-22.2 284.5-8.2 158.2 75 75C158.2-8.3 284.5-22.2 382.2 33.2zM51.5 410.1c18.5-5 38.8-8.3 50.9-10c.4-.1 .7-.1 1-.1c5.1-.2 9.2 4.3 8.4 9.6c-1.7 12.1-5 32.4-10 50.9C97.6 476.4 92 491 85.2 497.8C66 517 34.5 516.6 14.9 497.1s-20-51-.7-70.3c6.8-6.8 21.4-12.4 37.4-16.7zM416.9 209c-4.7-11.9-20.8-11-26.8 .3c-19 35.5-45 70.8-77.5 103.3S244.8 371.1 209.3 390c-11.3 6-12.2 22.1-.3 26.8c57.6 22.9 125.8 11 172.3-35.5s58.4-114.8 35.5-172.3zM87.1 285.1c2 2 4.6 3.2 7.3 3.4l56.1 5.1 5.1 56.1c.3 2.8 1.5 5.4 3.4 7.3c6.3 6.3 17.2 3.6 19.8-4.9l29.7-97.4c3.5-11.6-7.3-22.5-19-19L92 265.3c-8.6 2.6-11.3 13.4-4.9 19.8zM265.3 92l-29.7 97.4c-3.5 11.6 7.3 22.5 19 19l97.4-29.7c8.6-2.6 11.3-13.4 4.9-19.8c-2-2-4.6-3.2-7.3-3.4l-56.1-5.1-5.1-56.1c-.3-2.8-1.5-5.4-3.4-7.3c-6.3-6.3-17.2-3.6-19.8 4.9z" }, "regular": { "last_modified": 1684767582, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M426.8 14.2C446-5 477.5-4.6 497.1 14.9s20 51 .7 70.3c-14.8 14.8-65.7 23.6-88.3 26.7c-5.6 .9-10.3-3.9-9.5-9.5C403.3 79.9 412 29 426.8 14.2zM75 75C158.2-8.3 284.5-22.2 382.2 33.2c-1.5 4.8-2.9 9.6-4.1 14.3c-3.1 12.2-5.5 24.6-7.3 35c-80.8-53.6-190.7-44.8-261.9 26.4C37.7 180.1 28.9 290 82.5 370.8c-10.5 1.8-22.9 4.2-35 7.3c-4.7 1.2-9.5 2.5-14.3 4.1C-22.2 284.5-8.2 158.2 75 75zm389.6 58.9c4.7-1.2 9.5-2.5 14.3-4.1C534.2 227.5 520.2 353.8 437 437c-83.2 83.2-209.5 97.2-307.2 41.8c1.5-4.8 2.8-9.6 4-14.3c3.1-12.2 5.5-24.6 7.3-35c80.8 53.6 190.7 44.8 261.9-26.4c71.2-71.2 80-181.1 26.4-261.9c10.5-1.8 22.9-4.2 35-7.3zm-105.4 93c10.1-16.3 33.9-16.9 37.9 1.9c9.5 44.4-3.7 93.5-39.3 129.1s-84.8 48.8-129.1 39.3c-18.7-4-18.2-27.8-1.9-37.9c25.2-15.7 50.2-35.4 73.6-58.8s43.1-48.4 58.8-73.6zM92 265.3l97.4-29.7c11.6-3.5 22.5 7.3 19 19l-29.7 97.4c-2.6 8.6-13.4 11.3-19.8 4.9c-2-2-3.2-4.6-3.4-7.3l-5.1-56.1-56.1-5.1c-2.8-.3-5.4-1.5-7.3-3.4c-6.3-6.3-3.6-17.2 4.9-19.8zm193-178.2c2 2 3.2 4.6 3.4 7.3l5.1 56.1 56.1 5.1c2.8 .3 5.4 1.5 7.3 3.4c6.3 6.3 3.6 17.2-4.9 19.8l-97.4 29.7c-11.6 3.5-22.5-7.3-19-19L265.3 92c2.6-8.6 13.4-11.3 19.8-4.9zM14.9 497.1c-19.6-19.6-20-51-.7-70.3C29 412 79.8 403.2 102.4 400.1c5.6-.9 10.3 3.9 9.5 9.5c-3.2 22.5-11.9 73.5-26.7 88.3C66 517 34.5 516.6 14.9 497.1z" } }, "free": ["regular", "solid"] }, "face-grin-stars": { "aliases": { "names": ["grin-stars"], "unicodes": { "composite": ["1f929"], "secondary": ["10f587"] } }, "changes": [ "5.1.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "emoticon", "eyes", "face", "grinning", "star", "star-struck", "starry-eyed" ] }, "styles": ["solid", "regular"], "unicode": "f587", "label": "Face Grin Stars", "voted": false, "svg": { "solid": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm407.4 75.5c5-11.8-7-22.5-19.3-18.7c-39.7 12.2-84.5 19-131.8 19s-92.1-6.8-131.8-19c-12.3-3.8-24.3 6.9-19.3 18.7c25 59.1 83.2 100.5 151.1 100.5s126.2-41.4 151.1-100.5zM160 120c-3.1 0-5.9 1.8-7.2 4.6l-16.6 34.7-38.1 5c-3.1 .4-5.6 2.5-6.6 5.5s-.1 6.2 2.1 8.3l27.9 26.5-7 37.8c-.6 3 .7 6.1 3.2 7.9s5.8 2 8.5 .6L160 232.5l33.8 18.3c2.7 1.5 6 1.3 8.5-.6s3.7-4.9 3.2-7.9l-7-37.8L226.4 178c2.2-2.1 3.1-5.3 2.1-8.3s-3.5-5.1-6.6-5.5l-38.1-5-16.6-34.7c-1.3-2.8-4.1-4.6-7.2-4.6zm192 0c-3.1 0-5.9 1.8-7.2 4.6l-16.6 34.7-38.1 5c-3.1 .4-5.6 2.5-6.6 5.5s-.1 6.2 2.1 8.3l27.9 26.5-7 37.8c-.6 3 .7 6.1 3.2 7.9s5.8 2 8.5 .6L352 232.5l33.8 18.3c2.7 1.5 6 1.3 8.5-.6s3.7-4.9 3.2-7.9l-7-37.8L418.4 178c2.2-2.1 3.1-5.3 2.1-8.3s-3.5-5.1-6.6-5.5l-38.1-5-16.6-34.7c-1.3-2.8-4.1-4.6-7.2-4.6z" }, "regular": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 48a208 208 0 1 1 0 416 208 208 0 1 1 0-416zm0 464A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM183.2 132.6c-1.3-2.8-4.1-4.6-7.2-4.6s-5.9 1.8-7.2 4.6l-16.6 34.7-38.1 5c-3.1 .4-5.6 2.5-6.6 5.5s-.1 6.2 2.1 8.3l27.9 26.5-7 37.8c-.6 3 .7 6.1 3.2 7.9s5.8 2 8.5 .6L176 240.5l33.8 18.3c2.7 1.5 6 1.3 8.5-.6s3.7-4.9 3.2-7.9l-7-37.8L242.4 186c2.2-2.1 3.1-5.3 2.1-8.3s-3.5-5.1-6.6-5.5l-38.1-5-16.6-34.7zm160 0c-1.3-2.8-4.1-4.6-7.2-4.6s-5.9 1.8-7.2 4.6l-16.6 34.7-38.1 5c-3.1 .4-5.6 2.5-6.6 5.5s-.1 6.2 2.1 8.3l27.9 26.5-7 37.8c-.6 3 .7 6.1 3.2 7.9s5.8 2 8.5 .6L336 240.5l33.8 18.3c2.7 1.5 6 1.3 8.5-.6s3.7-4.9 3.2-7.9l-7-37.8L402.4 186c2.2-2.1 3.1-5.3 2.1-8.3s-3.5-5.1-6.6-5.5l-38.1-5-16.6-34.7zm6.3 175.8c-28.9 6.8-60.5 10.5-93.6 10.5s-64.7-3.7-93.6-10.5c-18.7-4.4-35.9 12-25.5 28.1c24.6 38.1 68.7 63.5 119.1 63.5s94.5-25.4 119.1-63.5c10.4-16.1-6.8-32.5-25.5-28.1z" } }, "free": ["regular", "solid"] }, "face-grin-tears": { "aliases": { "names": ["grin-tears"], "unicodes": { "composite": ["1f602"], "secondary": ["10f588"] } }, "changes": [ "5.1.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "LOL", "emoticon", "face", "face with tears of joy", "joy", "laugh", "tear" ] }, "styles": ["solid", "regular"], "unicode": "f588", "label": "Face Grin Tears", "voted": false, "svg": { "solid": { "last_modified": 1684767582, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M548.6 371.4C506.4 454.8 419.9 512 320 512s-186.4-57.2-228.6-140.6c4.5-2.9 8.7-6.3 12.7-10.3c8.1-8.1 13.2-18.6 16.5-26.6c3.6-8.8 6.5-18.4 8.8-27.5c4.6-18.2 7.7-37 9.3-48.2c3.9-26.5-18.8-49.2-45.2-45.4c-6.8 .9-16.2 2.4-26.6 4.4C85.3 94.5 191.6 0 320 0S554.7 94.5 573.2 217.7c-10.3-2-19.8-3.5-26.6-4.4c-26.5-3.9-49.2 18.8-45.2 45.4c1.6 11.3 4.6 30 9.3 48.2c2.3 9.1 5.2 18.8 8.8 27.5c3.3 8.1 8.4 18.5 16.5 26.6c3.9 3.9 8.2 7.4 12.7 10.3zM107 254.1c-3.1 21.5-11.4 70.2-25.5 84.4c-.9 1-1.9 1.8-2.9 2.7C60 356.7 32 355.5 14.3 337.7c-18.7-18.7-19.1-48.8-.7-67.2c8.6-8.6 30.1-15.1 50.5-19.6c13-2.8 25.5-4.8 33.9-6c5.4-.8 9.9 3.7 9 9zm454.5 87.1c-.8-.6-1.5-1.3-2.3-2c-.2-.2-.5-.4-.7-.7c-14.1-14.1-22.5-62.9-25.5-84.4c-.8-5.4 3.7-9.9 9-9c1 .1 2.2 .3 3.3 .5c8.2 1.2 19.2 3 30.6 5.5c20.4 4.4 41.9 10.9 50.5 19.6c18.4 18.4 18 48.5-.7 67.2c-17.7 17.7-45.7 19-64.2 3.4zm-90.1-9.7c5-11.8-7-22.5-19.3-18.7c-39.7 12.2-84.4 19-131.8 19s-92.1-6.8-131.8-19c-12.3-3.8-24.3 6.9-19.3 18.7c25 59.1 83.2 100.5 151.1 100.5s126.2-41.4 151.1-100.5zM281.6 228.8l0 0 0 0 0 0c2.1 2.8 5.7 3.9 8.9 2.8s5.5-4.1 5.5-7.6c0-17.9-6.7-35.6-16.6-48.8c-9.8-13-23.9-23.2-39.4-23.2s-29.6 10.2-39.4 23.2C190.7 188.4 184 206.1 184 224c0 3.4 2.2 6.5 5.5 7.6s6.9 0 8.9-2.8l0 0 0 0 0 0 .2-.2c.2-.2 .4-.5 .7-.9c.6-.8 1.6-2 2.8-3.4c2.5-2.8 6-6.6 10.2-10.3c8.8-7.8 18.8-14 27.7-14s18.9 6.2 27.7 14c4.2 3.7 7.7 7.5 10.2 10.3c1.2 1.4 2.2 2.6 2.8 3.4c.3 .4 .6 .7 .7 .9l.2 .2 0 0zm160 0l0 0 0 0c2.1 2.8 5.7 3.9 8.9 2.8s5.5-4.1 5.5-7.6c0-17.9-6.7-35.6-16.6-48.8c-9.8-13-23.9-23.2-39.4-23.2s-29.6 10.2-39.4 23.2C350.7 188.4 344 206.1 344 224c0 3.4 2.2 6.5 5.5 7.6s6.9 0 8.9-2.8l0 0 0 0 0 0 .2-.2c.2-.2 .4-.5 .7-.9c.6-.8 1.6-2 2.8-3.4c2.5-2.8 6-6.6 10.2-10.3c8.8-7.8 18.8-14 27.7-14s18.9 6.2 27.7 14c4.2 3.7 7.7 7.5 10.2 10.3c1.2 1.4 2.2 2.6 2.8 3.4c.3 .4 .6 .7 .7 .9l.2 .2 0 0 0 0z" }, "regular": { "last_modified": 1684767582, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M516.1 325.5c1 3 2.1 6 3.3 8.9c3.3 8.1 8.4 18.5 16.5 26.6c3.9 3.9 8.2 7.4 12.7 10.3C506.4 454.8 419.9 512 320 512s-186.4-57.2-228.6-140.6c4.5-2.9 8.7-6.3 12.7-10.3c8.1-8.1 13.2-18.6 16.5-26.6c1.2-2.9 2.3-5.9 3.3-8.9C152.5 406.2 229.5 464 320 464s167.5-57.8 196.1-138.5zM320 48c-101.4 0-185.8 72.5-204.3 168.5c-6.7-3.1-14.3-4.3-22.3-3.1c-6.8 .9-16.2 2.4-26.6 4.4C85.3 94.5 191.6 0 320 0S554.7 94.5 573.2 217.7c-10.3-2-19.8-3.5-26.6-4.4c-8-1.2-15.7 .1-22.3 3.1C505.8 120.5 421.4 48 320 48zM78.5 341.1C60 356.7 32 355.5 14.3 337.7c-18.7-18.7-19.1-48.8-.7-67.2c8.6-8.6 30.1-15.1 50.5-19.6c13-2.8 25.5-4.8 33.9-6c5.4-.8 9.9 3.7 9 9c-3.1 21.5-11.4 70.2-25.5 84.4c-.9 1-1.9 1.8-2.9 2.7zm483 0c-.8-.6-1.5-1.3-2.3-2c-.2-.2-.5-.4-.7-.7c-14.1-14.1-22.5-62.9-25.5-84.4c-.8-5.4 3.7-9.9 9-9c1 .1 2.2 .3 3.3 .5c8.2 1.2 19.2 3 30.6 5.5c20.4 4.4 41.9 10.9 50.5 19.6c18.4 18.4 18 48.5-.7 67.2c-17.7 17.7-45.7 19-64.2 3.4zM439 336.5C414.4 374.6 370.3 400 319.9 400s-94.5-25.4-119.1-63.5c-10.4-16.1 6.8-32.5 25.5-28.1c28.9 6.8 60.5 10.5 93.6 10.5s64.7-3.7 93.6-10.5c18.7-4.4 35.9 12 25.5 28.1zM281.6 228.8l0 0-.2-.2c-.2-.2-.4-.5-.7-.9c-.6-.8-1.6-2-2.8-3.4c-2.5-2.8-6-6.6-10.2-10.3c-8.8-7.8-18.8-14-27.7-14s-18.9 6.2-27.7 14c-4.2 3.7-7.7 7.5-10.2 10.3c-1.2 1.4-2.2 2.6-2.8 3.4c-.3 .4-.6 .7-.7 .9l-.2 .2 0 0 0 0 0 0c-2.1 2.8-5.7 3.9-8.9 2.8s-5.5-4.1-5.5-7.6c0-17.9 6.7-35.6 16.6-48.8c9.8-13 23.9-23.2 39.4-23.2s29.6 10.2 39.4 23.2c9.9 13.2 16.6 30.9 16.6 48.8c0 3.4-2.2 6.5-5.5 7.6s-6.9 0-8.9-2.8l0 0 0 0 0 0zm160 0l0 0 0 0-.2-.2c-.2-.2-.4-.5-.7-.9c-.6-.8-1.6-2-2.8-3.4c-2.5-2.8-6-6.6-10.2-10.3c-8.8-7.8-18.8-14-27.7-14s-18.9 6.2-27.7 14c-4.2 3.7-7.7 7.5-10.2 10.3c-1.2 1.4-2.2 2.6-2.8 3.4c-.3 .4-.6 .7-.7 .9l-.2 .2 0 0 0 0 0 0c-2.1 2.8-5.7 3.9-8.9 2.8s-5.5-4.1-5.5-7.6c0-17.9 6.7-35.6 16.6-48.8c9.8-13 23.9-23.2 39.4-23.2s29.6 10.2 39.4 23.2c9.9 13.2 16.6 30.9 16.6 48.8c0 3.4-2.2 6.5-5.5 7.6s-6.9 0-8.9-2.8l0 0 0 0z" } }, "free": ["regular", "solid"] }, "face-grin-tongue": { "aliases": { "names": ["grin-tongue"], "unicodes": { "composite": ["1f61b"], "secondary": ["10f589"] } }, "changes": [ "5.1.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["LOL", "emoticon", "face", "face with tongue", "tongue"] }, "styles": ["solid", "regular"], "unicode": "f589", "label": "Face Grin Tongue", "voted": false, "svg": { "solid": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 256C0 368.9 73.1 464.7 174.5 498.8C165.3 484 160 466.6 160 448V400.7c-24-17.5-43.1-41.4-54.8-69.2c-5-11.8 7-22.5 19.3-18.7c39.7 12.2 84.5 19 131.8 19s92.1-6.8 131.8-19c12.3-3.8 24.3 6.9 19.3 18.7c-11.8 28-31.1 52-55.4 69.6V448c0 18.6-5.3 36-14.5 50.8C438.9 464.7 512 368.9 512 256C512 114.6 397.4 0 256 0S0 114.6 0 256zm176.4-80a32 32 0 1 1 0 64 32 32 0 1 1 0-64zm128 32a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zM320 448V402.6c0-14.7-11.9-26.6-26.6-26.6h-2c-11.3 0-21.1 7.9-23.6 18.9c-2.8 12.6-20.8 12.6-23.6 0c-2.5-11.1-12.3-18.9-23.6-18.9h-2c-14.7 0-26.6 11.9-26.6 26.6V448c0 35.3 28.7 64 64 64s64-28.7 64-64z" }, "regular": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M464 256c0-114.9-93.1-208-208-208S48 141.1 48 256c0 81.7 47.1 152.4 115.7 186.4c-2.4-8.4-3.7-17.3-3.7-26.4V363.6c-8.9-8-16.7-17.1-23.1-27.1c-10.4-16.1 6.8-32.5 25.5-28.1c28.9 6.8 60.5 10.5 93.6 10.5s64.7-3.7 93.6-10.5c18.7-4.4 35.9 12 25.5 28.1c-6.4 9.9-14.2 19-23 27V416c0 9.2-1.3 18-3.7 26.4C416.9 408.4 464 337.7 464 256zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm176.4-80a32 32 0 1 1 0 64 32 32 0 1 1 0-64zm128 32a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zM320 416V378.6c0-14.7-11.9-26.6-26.6-26.6h-2c-11.3 0-21.1 7.9-23.6 18.9c-2.8 12.6-20.8 12.6-23.6 0c-2.5-11.1-12.3-18.9-23.6-18.9h-2c-14.7 0-26.6 11.9-26.6 26.6V416c0 35.3 28.7 64 64 64s64-28.7 64-64z" } }, "free": ["regular", "solid"] }, "face-grin-tongue-squint": { "aliases": { "names": ["grin-tongue-squint"], "unicodes": { "composite": ["1f61d"], "secondary": ["10f58a"] } }, "changes": [ "5.1.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "LOL", "emoticon", "eye", "face", "horrible", "squinting face with tongue", "taste", "tongue" ] }, "styles": ["solid", "regular"], "unicode": "f58a", "label": "Face Grin Tongue Squint", "voted": false, "svg": { "solid": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 256C0 368.9 73.1 464.7 174.5 498.8C165.3 484 160 466.6 160 448V400.7c-24-17.5-43.1-41.4-54.8-69.2c-5-11.8 7-22.5 19.3-18.7c39.7 12.2 84.5 19 131.8 19s92.1-6.8 131.8-19c12.3-3.8 24.3 6.9 19.3 18.7c-11.8 28-31.1 52-55.4 69.6V448c0 18.6-5.3 36-14.5 50.8C438.9 464.7 512 368.9 512 256C512 114.6 397.4 0 256 0S0 114.6 0 256zM116 141.1c0-9 9.6-14.7 17.5-10.5l89.9 47.9c10.7 5.7 10.7 21.1 0 26.8l-89.9 47.9c-7.9 4.2-17.5-1.5-17.5-10.5c0-2.8 1-5.5 2.8-7.6l36-43.2-36-43.2c-1.8-2.1-2.8-4.8-2.8-7.6zm262.5-10.5c7.9-4.2 17.5 1.5 17.5 10.5c0 2.8-1 5.5-2.8 7.6l-36 43.2 36 43.2c1.8 2.1 2.8 4.8 2.8 7.6c0 9-9.6 14.7-17.5 10.5l-89.9-47.9c-10.7-5.7-10.7-21.1 0-26.8l89.9-47.9zM320 448V402.6c0-14.7-11.9-26.6-26.6-26.6h-2c-11.3 0-21.1 7.9-23.6 18.9c-2.8 12.6-20.8 12.6-23.6 0c-2.5-11.1-12.3-18.9-23.6-18.9h-2c-14.7 0-26.6 11.9-26.6 26.6V448c0 35.3 28.7 64 64 64s64-28.7 64-64z" }, "regular": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M464 256c0-114.9-93.1-208-208-208S48 141.1 48 256c0 81.7 47.1 152.4 115.7 186.4c-2.4-8.4-3.7-17.3-3.7-26.4V392.7c-24-17.5-43.1-41.4-54.8-69.2c-5-11.8 7-22.5 19.3-18.7c39.7 12.2 84.5 19 131.8 19s92.1-6.8 131.8-19c12.3-3.8 24.3 6.9 19.3 18.7c-11.8 28-31.1 52-55.4 69.6V416c0 9.2-1.3 18-3.7 26.4C416.9 408.4 464 337.7 464 256zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm116-98.9c0-9 9.6-14.7 17.5-10.5l89.9 47.9c10.7 5.7 10.7 21.1 0 26.8l-89.9 47.9c-7.9 4.2-17.5-1.5-17.5-10.5c0-2.8 1-5.5 2.8-7.6l36-43.2-36-43.2c-1.8-2.1-2.8-4.8-2.8-7.6zm262.5-10.5c7.9-4.2 17.5 1.5 17.5 10.5c0 2.8-1 5.5-2.8 7.6l-36 43.2 36 43.2c1.8 2.1 2.8 4.8 2.8 7.6c0 9-9.6 14.7-17.5 10.5l-89.9-47.9c-10.7-5.7-10.7-21.1 0-26.8l89.9-47.9zM320 416V378.6c0-14.7-11.9-26.6-26.6-26.6h-2c-11.3 0-21.1 7.9-23.6 18.9c-2.8 12.6-20.8 12.6-23.6 0c-2.5-11.1-12.3-18.9-23.6-18.9h-2c-14.7 0-26.6 11.9-26.6 26.6V416c0 35.3 28.7 64 64 64s64-28.7 64-64z" } }, "free": ["regular", "solid"] }, "face-grin-tongue-wink": { "aliases": { "names": ["grin-tongue-wink"], "unicodes": { "composite": ["1f61c"], "secondary": ["10f58b"] } }, "changes": [ "5.1.0", "5.11.0", "5.11.1", "5.12.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "LOL", "emoticon", "eye", "face", "joke", "tongue", "wink", "winking face with tongue" ] }, "styles": ["solid", "regular"], "unicode": "f58b", "label": "Face Grin Tongue Wink", "voted": false, "svg": { "solid": { "last_modified": 1684767582, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M174.5 498.8C73.1 464.7 0 368.9 0 256C0 114.6 114.6 0 256 0S512 114.6 512 256c0 112.9-73.1 208.7-174.5 242.8C346.7 484 352 466.6 352 448V401.1c24.3-17.5 43.6-41.6 55.4-69.6c5-11.8-7-22.5-19.3-18.7c-39.7 12.2-84.5 19-131.8 19s-92.1-6.8-131.8-19c-12.3-3.8-24.3 6.9-19.3 18.7c11.7 27.8 30.8 51.7 54.8 69.2V448c0 18.6 5.3 36 14.5 50.8zm20.7-265.2c5.3 7.1 15.3 8.5 22.4 3.2s8.5-15.3 3.2-22.4c-30.4-40.5-91.2-40.5-121.6 0c-5.3 7.1-3.9 17.1 3.2 22.4s17.1 3.9 22.4-3.2c17.6-23.5 52.8-23.5 70.4 0zM336 272a64 64 0 1 0 0-128 64 64 0 1 0 0 128zM320 402.6V448c0 35.3-28.7 64-64 64s-64-28.7-64-64V402.6c0-14.7 11.9-26.6 26.6-26.6h2c11.3 0 21.1 7.9 23.6 18.9c2.8 12.6 20.8 12.6 23.6 0c2.5-11.1 12.3-18.9 23.6-18.9h2c14.7 0 26.6 11.9 26.6 26.6zM336 184a24 24 0 1 1 0 48 24 24 0 1 1 0-48z" }, "regular": { "last_modified": 1684767582, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M348.3 442.4c2.4-8.4 3.7-17.3 3.7-26.4V363.5c8.8-8 16.6-17.1 23-27c10.4-16.1-6.8-32.5-25.5-28.1c-28.9 6.8-60.5 10.5-93.6 10.5s-64.7-3.7-93.6-10.5c-18.7-4.4-35.9 12-25.5 28.1c6.5 10 14.3 19.1 23.1 27.1V416c0 9.2 1.3 18 3.7 26.4C95.1 408.4 48 337.7 48 256C48 141.1 141.1 48 256 48s208 93.1 208 208c0 81.7-47.1 152.4-115.7 186.4zM256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM159.6 220c10.6 0 19.9 3.8 25.4 9.7c7.6 8.1 20.2 8.5 28.3 .9s8.5-20.2 .9-28.3C199.7 186.8 179 180 159.6 180s-40.1 6.8-54.6 22.3c-7.6 8.1-7.1 20.7 .9 28.3s20.7 7.1 28.3-.9c5.5-5.8 14.8-9.7 25.4-9.7zm176.7 12a24 24 0 1 0 0-48 24 24 0 1 0 0 48zm-.4-72a48 48 0 1 1 0 96 48 48 0 1 1 0-96zm0 128a80 80 0 1 0 0-160 80 80 0 1 0 0 160zM320 416c0 35.3-28.7 64-64 64s-64-28.7-64-64V378.6c0-14.7 11.9-26.6 26.6-26.6h2c11.3 0 21.1 7.9 23.6 18.9c2.8 12.6 20.8 12.6 23.6 0c2.5-11.1 12.3-18.9 23.6-18.9h2c14.7 0 26.6 11.9 26.6 26.6V416z" } }, "free": ["regular", "solid"] }, "face-grin-wide": { "aliases": { "names": ["grin-alt"], "unicodes": { "composite": ["1f603"], "secondary": ["10f581"] } }, "changes": [ "5.1.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "emoticon", "face", "grinning face with big eyes", "laugh", "mouth", "open", "smile" ] }, "styles": ["solid", "regular"], "unicode": "f581", "label": "Face Grin Wide", "voted": false, "svg": { "solid": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM388.1 312.8c12.3-3.8 24.3 6.9 19.3 18.7C382.4 390.6 324.2 432 256.3 432s-126.2-41.4-151.1-100.5c-5-11.8 7-22.5 19.3-18.7c39.7 12.2 84.5 19 131.8 19s92.1-6.8 131.8-19zM208 192c0 35.3-14.3 64-32 64s-32-28.7-32-64s14.3-64 32-64s32 28.7 32 64zm128 64c-17.7 0-32-28.7-32-64s14.3-64 32-64s32 28.7 32 64s-14.3 64-32 64z" }, "regular": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M464 256A208 208 0 1 0 48 256a208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm349.5 52.4c18.7-4.4 35.9 12 25.5 28.1C350.4 374.6 306.3 400 255.9 400s-94.5-25.4-119.1-63.5c-10.4-16.1 6.8-32.5 25.5-28.1c28.9 6.8 60.5 10.5 93.6 10.5s64.7-3.7 93.6-10.5zM224 192c0 35.3-14.3 64-32 64s-32-28.7-32-64s14.3-64 32-64s32 28.7 32 64zm96 64c-17.7 0-32-28.7-32-64s14.3-64 32-64s32 28.7 32 64s-14.3 64-32 64z" } }, "free": ["regular", "solid"] }, "face-grin-wink": { "aliases": { "names": ["grin-wink"], "unicodes": { "secondary": ["10f58c"] } }, "changes": [ "5.1.0", "5.1.1", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["emoticon", "face", "flirt", "laugh", "smile"] }, "styles": ["solid", "regular"], "unicode": "f58c", "label": "Face Grin Wink", "voted": false, "svg": { "solid": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM388.1 312.8c12.3-3.8 24.3 6.9 19.3 18.7C382.4 390.6 324.2 432 256.3 432s-126.2-41.4-151.1-100.5c-5-11.8 7-22.5 19.3-18.7c39.7 12.2 84.5 19 131.8 19s92.1-6.8 131.8-19zm-16.9-79.2c-17.6-23.5-52.8-23.5-70.4 0c-5.3 7.1-15.3 8.5-22.4 3.2s-8.5-15.3-3.2-22.4c30.4-40.5 91.2-40.5 121.6 0c5.3 7.1 3.9 17.1-3.2 22.4s-17.1 3.9-22.4-3.2zM176.4 176a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" }, "regular": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M464 256A208 208 0 1 0 48 256a208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm349.5 52.4c18.7-4.4 35.9 12 25.5 28.1C350.4 374.6 306.3 400 255.9 400s-94.5-25.4-119.1-63.5c-10.4-16.1 6.8-32.5 25.5-28.1c28.9 6.8 60.5 10.5 93.6 10.5s64.7-3.7 93.6-10.5zM144.4 208a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm165.8 21.7c-7.6 8.1-20.2 8.5-28.3 .9s-8.5-20.2-.9-28.3c14.5-15.5 35.2-22.3 54.6-22.3s40.1 6.8 54.6 22.3c7.6 8.1 7.1 20.7-.9 28.3s-20.7 7.1-28.3-.9c-5.5-5.8-14.8-9.7-25.4-9.7s-19.9 3.8-25.4 9.7z" } }, "free": ["regular", "solid"] }, "face-kiss": { "aliases": { "names": ["kiss"], "unicodes": { "composite": ["1f617"], "secondary": ["10f596"] } }, "changes": [ "5.1.0", "5.1.1", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "beso", "emoticon", "face", "kiss", "kissing face", "love", "smooch" ] }, "styles": ["solid", "regular"], "unicode": "f596", "label": "Face Kiss", "voted": false, "svg": { "solid": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zm48.7-198.3c4.3 5.1 7.3 11.4 7.3 18.3s-3.1 13.2-7.3 18.3c-4.3 5.2-10.1 9.7-16.7 13.4c-2.7 1.5-5.7 3-8.7 4.3c3.1 1.3 6 2.7 8.7 4.3c6.6 3.7 12.5 8.2 16.7 13.4c4.3 5.1 7.3 11.4 7.3 18.3s-3.1 13.2-7.3 18.3c-4.3 5.2-10.1 9.7-16.7 13.4C274.7 443.1 257.4 448 240 448c-3.6 0-6.8-2.5-7.7-6s.6-7.2 3.8-9l0 0 0 0 0 0 0 0 .2-.1c.2-.1 .5-.3 .9-.5c.8-.5 2-1.2 3.4-2.1c2.8-1.9 6.5-4.5 10.2-7.6c3.7-3.1 7.2-6.6 9.6-10.1c2.5-3.5 3.5-6.4 3.5-8.6s-1-5-3.5-8.6c-2.5-3.5-5.9-6.9-9.6-10.1c-3.7-3.1-7.4-5.7-10.2-7.6c-1.4-.9-2.6-1.6-3.4-2.1c-.4-.2-.7-.4-.9-.5l-.2-.1 0 0 0 0 0 0c-2.5-1.4-4.1-4.1-4.1-7s1.6-5.6 4.1-7l0 0 0 0 0 0 0 0 0 0 .2-.1 .3-.2 .6-.4c.8-.5 2-1.2 3.4-2.1c2.8-1.9 6.5-4.5 10.2-7.6c3.7-3.1 7.2-6.6 9.6-10.1c2.5-3.5 3.5-6.4 3.5-8.6s-1-5-3.5-8.6c-2.5-3.5-5.9-6.9-9.6-10.1c-3.7-3.1-7.4-5.7-10.2-7.6c-1.4-.9-2.6-1.6-3.4-2.1l-.4-.3-.5-.3-.2-.1 0 0 0 0 0 0c-3.2-1.8-4.7-5.5-3.8-9s4.1-6 7.7-6c17.4 0 34.7 4.9 47.9 12.3c6.6 3.7 12.5 8.2 16.7 13.4zM144.4 208a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm192-32a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" }, "regular": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M464 256A208 208 0 1 0 48 256a208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm304.7 25.7c4.3 5.1 7.3 11.4 7.3 18.3s-3.1 13.2-7.3 18.3c-4.3 5.2-10.1 9.7-16.7 13.4c-2.7 1.5-5.7 3-8.7 4.3c3.1 1.3 6 2.7 8.7 4.3c6.6 3.7 12.5 8.2 16.7 13.4c4.3 5.1 7.3 11.4 7.3 18.3s-3.1 13.2-7.3 18.3c-4.3 5.2-10.1 9.7-16.7 13.4C274.7 411.1 257.4 416 240 416c-3.6 0-6.8-2.5-7.7-6s.6-7.2 3.8-9l0 0 0 0 0 0 0 0 .2-.1c.2-.1 .5-.3 .9-.5c.8-.5 2-1.2 3.4-2.1c2.8-1.9 6.5-4.5 10.2-7.6c3.7-3.1 7.2-6.6 9.6-10.1c2.5-3.5 3.5-6.4 3.5-8.6s-1-5-3.5-8.6c-2.5-3.5-5.9-6.9-9.6-10.1c-3.7-3.1-7.4-5.7-10.2-7.6c-1.4-.9-2.6-1.6-3.4-2.1l-.8-.5-.1-.1-.2-.1 0 0 0 0 0 0c-2.5-1.4-4.1-4.1-4.1-7s1.6-5.6 4.1-7l0 0 0 0 0 0 0 0 0 0 .2-.1c.2-.1 .5-.3 .9-.5c.8-.5 2-1.2 3.4-2.1c2.8-1.9 6.5-4.5 10.2-7.6c3.7-3.1 7.2-6.6 9.6-10.1c2.5-3.5 3.5-6.4 3.5-8.6s-1-5-3.5-8.6c-2.5-3.5-5.9-6.9-9.6-10.1c-3.7-3.1-7.4-5.7-10.2-7.6c-1.4-.9-2.6-1.6-3.4-2.1c-.4-.2-.7-.4-.9-.5l-.2-.1 0 0 0 0 0 0c-3.2-1.8-4.7-5.5-3.8-9s4.1-6 7.7-6c17.4 0 34.7 4.9 47.9 12.3c6.6 3.7 12.5 8.2 16.7 13.4zM144.4 208a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm192-32a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" } }, "free": ["regular", "solid"] }, "face-kiss-beam": { "aliases": { "names": ["kiss-beam"], "unicodes": { "composite": ["1f619"], "secondary": ["10f597"] } }, "changes": [ "5.1.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "beso", "emoticon", "eye", "face", "kiss", "kissing face with smiling eyes", "love", "smile", "smooch" ] }, "styles": ["solid", "regular"], "unicode": "f597", "label": "Face Kiss Beam", "voted": false, "svg": { "solid": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zm48.7-198.3c4.3 5.1 7.3 11.4 7.3 18.3s-3.1 13.2-7.3 18.3c-4.3 5.2-10.1 9.7-16.7 13.4c-2.7 1.5-5.7 3-8.7 4.3c3.1 1.3 6 2.7 8.7 4.3c6.6 3.7 12.5 8.2 16.7 13.4c4.3 5.1 7.3 11.4 7.3 18.3s-3.1 13.2-7.3 18.3c-4.3 5.2-10.1 9.7-16.7 13.4C274.7 443.1 257.4 448 240 448c-3.6 0-6.8-2.5-7.7-6s.6-7.2 3.8-9l0 0 0 0 0 0 0 0 .2-.1c.2-.1 .5-.3 .9-.5c.8-.5 2-1.2 3.4-2.1c2.8-1.9 6.5-4.5 10.2-7.6c3.7-3.1 7.2-6.6 9.6-10.1c2.5-3.5 3.5-6.4 3.5-8.6s-1-5-3.5-8.6c-2.5-3.5-5.9-6.9-9.6-10.1c-3.7-3.1-7.4-5.7-10.2-7.6c-1.4-.9-2.6-1.6-3.4-2.1c-.4-.2-.7-.4-.9-.5l-.2-.1 0 0 0 0 0 0c-2.5-1.4-4.1-4.1-4.1-7s1.6-5.6 4.1-7l0 0 0 0 0 0 0 0 0 0 .2-.1 .3-.2 .6-.4c.8-.5 2-1.2 3.4-2.1c2.8-1.9 6.5-4.5 10.2-7.6c3.7-3.1 7.2-6.6 9.6-10.1c2.5-3.5 3.5-6.4 3.5-8.6s-1-5-3.5-8.6c-2.5-3.5-5.9-6.9-9.6-10.1c-3.7-3.1-7.4-5.7-10.2-7.6c-1.4-.9-2.6-1.6-3.4-2.1l-.4-.3-.5-.3-.2-.1 0 0 0 0 0 0c-3.2-1.8-4.7-5.5-3.8-9s4.1-6 7.7-6c17.4 0 34.7 4.9 47.9 12.3c6.6 3.7 12.5 8.2 16.7 13.4zm-87.1-84.9l0 0 0 0-.2-.2c-.2-.2-.4-.5-.7-.9c-.6-.8-1.6-2-2.8-3.4c-2.5-2.8-6-6.6-10.2-10.3c-8.8-7.8-18.8-14-27.7-14s-18.9 6.2-27.7 14c-4.2 3.7-7.7 7.5-10.2 10.3c-1.2 1.4-2.2 2.6-2.8 3.4c-.3 .4-.6 .7-.7 .9l-.2 .2 0 0 0 0 0 0c-2.1 2.8-5.7 3.9-8.9 2.8s-5.5-4.1-5.5-7.6c0-17.9 6.7-35.6 16.6-48.8c9.8-13 23.9-23.2 39.4-23.2s29.6 10.2 39.4 23.2c9.9 13.2 16.6 30.9 16.6 48.8c0 3.4-2.2 6.5-5.5 7.6s-6.9 0-8.9-2.8l0 0 0 0zm160 0l0 0-.2-.2c-.2-.2-.4-.5-.7-.9c-.6-.8-1.6-2-2.8-3.4c-2.5-2.8-6-6.6-10.2-10.3c-8.8-7.8-18.8-14-27.7-14s-18.9 6.2-27.7 14c-4.2 3.7-7.7 7.5-10.2 10.3c-1.2 1.4-2.2 2.6-2.8 3.4c-.3 .4-.6 .7-.7 .9l-.2 .2 0 0 0 0 0 0c-2.1 2.8-5.7 3.9-8.9 2.8s-5.5-4.1-5.5-7.6c0-17.9 6.7-35.6 16.6-48.8c9.8-13 23.9-23.2 39.4-23.2s29.6 10.2 39.4 23.2c9.9 13.2 16.6 30.9 16.6 48.8c0 3.4-2.2 6.5-5.5 7.6s-6.9 0-8.9-2.8l0 0 0 0 0 0z" }, "regular": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M464 256A208 208 0 1 0 48 256a208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm304.7 41.7c4.3 5.1 7.3 11.4 7.3 18.3s-3.1 13.2-7.3 18.3c-4.3 5.2-10.1 9.7-16.7 13.4c-2.7 1.5-5.7 3-8.7 4.3c3.1 1.3 6 2.7 8.7 4.3c6.6 3.7 12.5 8.2 16.7 13.4c4.3 5.1 7.3 11.4 7.3 18.3s-3.1 13.2-7.3 18.3c-4.3 5.2-10.1 9.7-16.7 13.4C274.7 427.1 257.4 432 240 432c-3.6 0-6.8-2.5-7.7-6s.6-7.2 3.8-9l0 0 0 0 0 0 0 0 .2-.1c.2-.1 .5-.3 .9-.5c.8-.5 2-1.2 3.4-2.1c2.8-1.9 6.5-4.5 10.2-7.6c3.7-3.1 7.2-6.6 9.6-10.1c2.5-3.5 3.5-6.4 3.5-8.6s-1-5-3.5-8.6c-2.5-3.5-5.9-6.9-9.6-10.1c-3.7-3.1-7.4-5.7-10.2-7.6c-1.4-.9-2.6-1.6-3.4-2.1c-.4-.2-.7-.4-.9-.5l-.2-.1 0 0 0 0 0 0c-2.5-1.4-4.1-4.1-4.1-7s1.6-5.6 4.1-7l0 0 0 0 0 0 0 0 0 0 .2-.1c.2-.1 .5-.3 .9-.5c.8-.5 2-1.2 3.4-2.1c2.8-1.9 6.5-4.5 10.2-7.6c3.7-3.1 7.2-6.6 9.6-10.1c2.5-3.5 3.5-6.4 3.5-8.6s-1-5-3.5-8.6c-2.5-3.5-5.9-6.9-9.6-10.1c-3.7-3.1-7.4-5.7-10.2-7.6c-1.4-.9-2.6-1.6-3.4-2.1c-.4-.2-.7-.4-.9-.5l-.2-.1 0 0 0 0 0 0c-3.2-1.8-4.7-5.5-3.8-9s4.1-6 7.7-6c17.4 0 34.7 4.9 47.9 12.3c6.6 3.7 12.5 8.2 16.7 13.4zm-87.1-68.9l0 0 0 0-.2-.2c-.2-.2-.4-.5-.7-.9c-.6-.8-1.6-2-2.8-3.4c-2.5-2.8-6-6.6-10.2-10.3c-8.8-7.8-18.8-14-27.7-14s-18.9 6.2-27.7 14c-4.2 3.7-7.7 7.5-10.2 10.3c-1.2 1.4-2.2 2.6-2.8 3.4c-.3 .4-.6 .7-.7 .9l-.2 .2 0 0 0 0 0 0c-2.1 2.8-5.7 3.9-8.9 2.8s-5.5-4.1-5.5-7.6c0-17.9 6.7-35.6 16.6-48.8c9.8-13 23.9-23.2 39.4-23.2s29.6 10.2 39.4 23.2c9.9 13.2 16.6 30.9 16.6 48.8c0 3.4-2.2 6.5-5.5 7.6s-6.9 0-8.9-2.8l0 0 0 0zm160 0l0 0-.2-.2c-.2-.2-.4-.5-.7-.9c-.6-.8-1.6-2-2.8-3.4c-2.5-2.8-6-6.6-10.2-10.3c-8.8-7.8-18.8-14-27.7-14s-18.9 6.2-27.7 14c-4.2 3.7-7.7 7.5-10.2 10.3c-1.2 1.4-2.2 2.6-2.8 3.4c-.3 .4-.6 .7-.7 .9l-.2 .2 0 0 0 0 0 0c-2.1 2.8-5.7 3.9-8.9 2.8s-5.5-4.1-5.5-7.6c0-17.9 6.7-35.6 16.6-48.8c9.8-13 23.9-23.2 39.4-23.2s29.6 10.2 39.4 23.2c9.9 13.2 16.6 30.9 16.6 48.8c0 3.4-2.2 6.5-5.5 7.6s-6.9 0-8.9-2.8l0 0 0 0 0 0z" } }, "free": ["regular", "solid"] }, "face-kiss-wink-heart": { "aliases": { "names": ["kiss-wink-heart"], "unicodes": { "composite": ["1f618"], "secondary": ["10f598"] } }, "changes": [ "5.1.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "beso", "emoticon", "face", "face blowing a kiss", "kiss", "love", "smooch" ] }, "styles": ["solid", "regular"], "unicode": "f598", "label": "Face Kiss Wink Heart", "voted": false, "svg": { "solid": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M498 339.7c9.1-26.2 14-54.4 14-83.7C512 114.6 397.4 0 256 0S0 114.6 0 256S114.6 512 256 512c35.4 0 69.1-7.2 99.7-20.2c-4.8-5.5-8.5-12.2-10.4-19.7l-22.9-89.3c-10-39 11.8-80.9 51.8-92.1c37.2-10.4 73.8 10.1 87.5 44c12.7-1.6 25.1 .4 36.2 5zM296 332c0 6.9-3.1 13.2-7.3 18.3c-4.3 5.2-10.1 9.7-16.7 13.4c-2.7 1.5-5.7 3-8.7 4.3c3.1 1.3 6 2.7 8.7 4.3c6.6 3.7 12.5 8.2 16.7 13.4c4.3 5.1 7.3 11.4 7.3 18.3s-3.1 13.2-7.3 18.3c-4.3 5.2-10.1 9.7-16.7 13.4C258.7 443.1 241.4 448 224 448c-3.6 0-6.8-2.5-7.7-6s.6-7.2 3.8-9l0 0 0 0 0 0 0 0 .2-.1c.2-.1 .5-.3 .9-.5c.8-.5 2-1.2 3.4-2.1c2.8-1.9 6.5-4.5 10.2-7.6c3.7-3.1 7.2-6.6 9.6-10.1c2.5-3.5 3.5-6.4 3.5-8.6s-1-5-3.5-8.6c-2.5-3.5-5.9-6.9-9.6-10.1c-3.7-3.1-7.4-5.7-10.2-7.6c-1.4-.9-2.6-1.6-3.4-2.1l-.6-.4-.3-.2-.2-.1 0 0 0 0 0 0c-2.5-1.4-4.1-4.1-4.1-7s1.6-5.6 4.1-7l0 0 0 0 0 0 0 0 0 0 .2-.1c.2-.1 .5-.3 .9-.5c.8-.5 2-1.2 3.4-2.1c2.8-1.9 6.5-4.5 10.2-7.6c3.7-3.1 7.2-6.6 9.6-10.1c2.5-3.5 3.5-6.4 3.5-8.6s-1-5-3.5-8.6c-2.5-3.5-5.9-6.9-9.6-10.1c-3.7-3.1-7.4-5.7-10.2-7.6c-1.4-.9-2.6-1.6-3.4-2.1c-.4-.2-.7-.4-.9-.5l-.2-.1 0 0 0 0 0 0c-3.2-1.8-4.7-5.5-3.8-9s4.1-6 7.7-6c17.4 0 34.7 4.9 47.9 12.3c6.6 3.7 12.5 8.2 16.7 13.4c4.3 5.1 7.3 11.4 7.3 18.3zM176.4 176a32 32 0 1 1 0 64 32 32 0 1 1 0-64zm194.8 57.6c-17.6-23.5-52.8-23.5-70.4 0c-5.3 7.1-15.3 8.5-22.4 3.2s-8.5-15.3-3.2-22.4c30.4-40.5 91.2-40.5 121.6 0c5.3 7.1 3.9 17.1-3.2 22.4s-17.1 3.9-22.4-3.2zM434 352.3c-6-23.2-28.8-37-51.1-30.8s-35.4 30.1-29.5 53.4l22.9 89.3c2.2 8.7 11.2 13.9 19.8 11.4l84.9-23.8c22.2-6.2 35.4-30.1 29.5-53.4s-28.8-37-51.1-30.8l-20.2 5.6-5.4-21z" }, "regular": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M338.9 446.8c-25.4 11-53.4 17.2-82.9 17.2C141.1 464 48 370.9 48 256S141.1 48 256 48s208 93.1 208 208c0 22.4-3.5 43.9-10.1 64.1c3.1 4.5 5.7 9.4 7.8 14.6c12.7-1.6 25.1 .4 36.2 5c9.1-26.2 14-54.4 14-83.7C512 114.6 397.4 0 256 0S0 114.6 0 256S114.6 512 256 512c35.4 0 69.1-7.2 99.7-20.2c-4.8-5.5-8.5-12.2-10.4-19.7l-6.5-25.3zM296 316c0-6.9-3.1-13.2-7.3-18.3c-4.3-5.2-10.1-9.7-16.7-13.4C258.7 276.9 241.4 272 224 272c-3.6 0-6.8 2.5-7.7 6s.6 7.2 3.8 9l0 0 0 0 0 0 .2 .1c.2 .1 .5 .3 .9 .5c.8 .5 2 1.2 3.4 2.1c2.8 1.9 6.5 4.5 10.2 7.6c3.7 3.1 7.2 6.6 9.6 10.1c2.5 3.5 3.5 6.4 3.5 8.6s-1 5-3.5 8.6c-2.5 3.5-5.9 6.9-9.6 10.1c-3.7 3.1-7.4 5.7-10.2 7.6c-1.4 .9-2.6 1.6-3.4 2.1c-.4 .2-.7 .4-.9 .5l-.2 .1 0 0 0 0 0 0 0 0 0 0c-2.5 1.4-4.1 4.1-4.1 7s1.6 5.6 4.1 7l0 0 0 0 0 0 .2 .1c.2 .1 .5 .3 .9 .5c.8 .5 2 1.2 3.4 2.1c2.8 1.9 6.5 4.5 10.2 7.6c3.7 3.1 7.2 6.6 9.6 10.1c2.5 3.5 3.5 6.4 3.5 8.6s-1 5-3.5 8.6c-2.5 3.5-5.9 6.9-9.6 10.1c-3.7 3.1-7.4 5.7-10.2 7.6c-1.4 .9-2.6 1.6-3.4 2.1c-.4 .2-.7 .4-.9 .5l-.2 .1 0 0 0 0 0 0 0 0c-3.2 1.8-4.7 5.5-3.8 9s4.1 6 7.7 6c17.4 0 34.7-4.9 47.9-12.3c6.6-3.7 12.5-8.2 16.7-13.4c4.3-5.1 7.3-11.4 7.3-18.3s-3.1-13.2-7.3-18.3c-4.3-5.2-10.1-9.7-16.7-13.4c-2.7-1.5-5.7-3-8.7-4.3c3.1-1.3 6-2.7 8.7-4.3c6.6-3.7 12.5-8.2 16.7-13.4c4.3-5.1 7.3-11.4 7.3-18.3zM176.4 240a32 32 0 1 0 0-64 32 32 0 1 0 0 64zm159.3-20c10.6 0 19.9 3.8 25.4 9.7c7.6 8.1 20.2 8.5 28.3 .9s8.5-20.2 .9-28.3C375.7 186.8 355 180 335.6 180s-40.1 6.8-54.6 22.3c-7.6 8.1-7.1 20.7 .9 28.3s20.7 7.1 28.3-.9c5.5-5.8 14.8-9.7 25.4-9.7zM434 352.3c-6-23.2-28.8-37-51.1-30.8s-35.4 30.1-29.5 53.4l22.9 89.3c2.2 8.7 11.2 13.9 19.8 11.4l84.9-23.8c22.2-6.2 35.4-30.1 29.5-53.4s-28.8-37-51.1-30.8l-20.2 5.6-5.4-21z" } }, "free": ["regular", "solid"] }, "face-laugh": { "aliases": { "names": ["laugh"], "unicodes": { "secondary": ["10f599"] } }, "changes": [ "5.1.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["LOL", "emoticon", "face", "laugh", "smile"] }, "styles": ["solid", "regular"], "unicode": "f599", "label": "Face Laugh", "voted": false, "svg": { "solid": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM96.8 314.1c-3.8-13.7 7.4-26.1 21.6-26.1H393.6c14.2 0 25.5 12.4 21.6 26.1C396.2 382 332.1 432 256 432s-140.2-50-159.2-117.9zM144.4 192a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm192-32a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" }, "regular": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M464 256A208 208 0 1 0 48 256a208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm130.7 57.9c-4.2-13.6 7.1-25.9 21.3-25.9H364.5c14.2 0 25.5 12.4 21.3 25.9C369 368.4 318.2 408 258.2 408s-110.8-39.6-127.5-94.1zM144.4 192a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm192-32a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" } }, "free": ["regular", "solid"] }, "face-laugh-beam": { "aliases": { "names": ["laugh-beam"], "unicodes": { "composite": ["1f601"], "secondary": ["10f59a"] } }, "changes": [ "5.1.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "LOL", "beaming face with smiling eyes", "emoticon", "eye", "face", "grin", "happy", "smile" ] }, "styles": ["solid", "regular"], "unicode": "f59a", "label": "Face Laugh Beam", "voted": false, "svg": { "solid": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM96.8 314.1c-3.8-13.7 7.4-26.1 21.6-26.1H393.6c14.2 0 25.5 12.4 21.6 26.1C396.2 382 332.1 432 256 432s-140.2-50-159.2-117.9zM217.6 212.8l0 0 0 0-.2-.2c-.2-.2-.4-.5-.7-.9c-.6-.8-1.6-2-2.8-3.4c-2.5-2.8-6-6.6-10.2-10.3c-8.8-7.8-18.8-14-27.7-14s-18.9 6.2-27.7 14c-4.2 3.7-7.7 7.5-10.2 10.3c-1.2 1.4-2.2 2.6-2.8 3.4c-.3 .4-.6 .7-.7 .9l-.2 .2 0 0 0 0 0 0c-2.1 2.8-5.7 3.9-8.9 2.8s-5.5-4.1-5.5-7.6c0-17.9 6.7-35.6 16.6-48.8c9.8-13 23.9-23.2 39.4-23.2s29.6 10.2 39.4 23.2c9.9 13.2 16.6 30.9 16.6 48.8c0 3.4-2.2 6.5-5.5 7.6s-6.9 0-8.9-2.8l0 0 0 0zm160 0l0 0-.2-.2c-.2-.2-.4-.5-.7-.9c-.6-.8-1.6-2-2.8-3.4c-2.5-2.8-6-6.6-10.2-10.3c-8.8-7.8-18.8-14-27.7-14s-18.9 6.2-27.7 14c-4.2 3.7-7.7 7.5-10.2 10.3c-1.2 1.4-2.2 2.6-2.8 3.4c-.3 .4-.6 .7-.7 .9l-.2 .2 0 0 0 0 0 0c-2.1 2.8-5.7 3.9-8.9 2.8s-5.5-4.1-5.5-7.6c0-17.9 6.7-35.6 16.6-48.8c9.8-13 23.9-23.2 39.4-23.2s29.6 10.2 39.4 23.2c9.9 13.2 16.6 30.9 16.6 48.8c0 3.4-2.2 6.5-5.5 7.6s-6.9 0-8.9-2.8l0 0 0 0 0 0z" }, "regular": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M464 256A208 208 0 1 0 48 256a208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm130.7 57.9c-4.2-13.6 7.1-25.9 21.3-25.9H364.5c14.2 0 25.5 12.4 21.3 25.9C369 368.4 318.2 408 258.2 408s-110.8-39.6-127.5-94.1zm86.9-85.1l0 0 0 0-.2-.2c-.2-.2-.4-.5-.7-.9c-.6-.8-1.6-2-2.8-3.4c-2.5-2.8-6-6.6-10.2-10.3c-8.8-7.8-18.8-14-27.7-14s-18.9 6.2-27.7 14c-4.2 3.7-7.7 7.5-10.2 10.3c-1.2 1.4-2.2 2.6-2.8 3.4c-.3 .4-.6 .7-.7 .9l-.2 .2 0 0 0 0 0 0c-2.1 2.8-5.7 3.9-8.9 2.8s-5.5-4.1-5.5-7.6c0-17.9 6.7-35.6 16.6-48.8c9.8-13 23.9-23.2 39.4-23.2s29.6 10.2 39.4 23.2c9.9 13.2 16.6 30.9 16.6 48.8c0 3.4-2.2 6.5-5.5 7.6s-6.9 0-8.9-2.8l0 0 0 0zm160 0l0 0-.2-.2c-.2-.2-.4-.5-.7-.9c-.6-.8-1.6-2-2.8-3.4c-2.5-2.8-6-6.6-10.2-10.3c-8.8-7.8-18.8-14-27.7-14s-18.9 6.2-27.7 14c-4.2 3.7-7.7 7.5-10.2 10.3c-1.2 1.4-2.2 2.6-2.8 3.4c-.3 .4-.6 .7-.7 .9l-.2 .2 0 0 0 0 0 0c-2.1 2.8-5.7 3.9-8.9 2.8s-5.5-4.1-5.5-7.6c0-17.9 6.7-35.6 16.6-48.8c9.8-13 23.9-23.2 39.4-23.2s29.6 10.2 39.4 23.2c9.9 13.2 16.6 30.9 16.6 48.8c0 3.4-2.2 6.5-5.5 7.6s-6.9 0-8.9-2.8l0 0 0 0 0 0z" } }, "free": ["regular", "solid"] }, "face-laugh-squint": { "aliases": { "names": ["laugh-squint"], "unicodes": { "secondary": ["10f59b"] } }, "changes": [ "5.1.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["LOL", "emoticon", "face", "happy", "smile"] }, "styles": ["solid", "regular"], "unicode": "f59b", "label": "Face Laugh Squint", "voted": false, "svg": { "solid": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM96.8 314.1c-3.8-13.7 7.4-26.1 21.6-26.1H393.6c14.2 0 25.5 12.4 21.6 26.1C396.2 382 332.1 432 256 432s-140.2-50-159.2-117.9zm36.7-199.4l89.9 47.9c10.7 5.7 10.7 21.1 0 26.8l-89.9 47.9c-7.9 4.2-17.5-1.5-17.5-10.5c0-2.8 1-5.5 2.8-7.6l36-43.2-36-43.2c-1.8-2.1-2.8-4.8-2.8-7.6c0-9 9.6-14.7 17.5-10.5zM396 125.1c0 2.8-1 5.5-2.8 7.6l-36 43.2 36 43.2c1.8 2.1 2.8 4.8 2.8 7.6c0 9-9.6 14.7-17.5 10.5l-89.9-47.9c-10.7-5.7-10.7-21.1 0-26.8l89.9-47.9c7.9-4.2 17.5 1.5 17.5 10.5z" }, "regular": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M464 256A208 208 0 1 0 48 256a208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm130.7 57.9c-4.2-13.6 7.1-25.9 21.3-25.9H364.5c14.2 0 25.5 12.4 21.3 25.9C369 368.4 318.2 408 258.2 408s-110.8-39.6-127.5-94.1zm2.8-183.3l89.9 47.9c10.7 5.7 10.7 21.1 0 26.8l-89.9 47.9c-7.9 4.2-17.5-1.5-17.5-10.5c0-2.8 1-5.5 2.8-7.6l36-43.2-36-43.2c-1.8-2.1-2.8-4.8-2.8-7.6c0-9 9.6-14.7 17.5-10.5zM396 141.1c0 2.8-1 5.5-2.8 7.6l-36 43.2 36 43.2c1.8 2.1 2.8 4.8 2.8 7.6c0 9-9.6 14.7-17.5 10.5l-89.9-47.9c-10.7-5.7-10.7-21.1 0-26.8l89.9-47.9c7.9-4.2 17.5 1.5 17.5 10.5z" } }, "free": ["regular", "solid"] }, "face-laugh-wink": { "aliases": { "names": ["laugh-wink"], "unicodes": { "secondary": ["10f59c"] } }, "changes": [ "5.1.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["LOL", "emoticon", "face", "happy", "smile"] }, "styles": ["solid", "regular"], "unicode": "f59c", "label": "Face Laugh Wink", "voted": false, "svg": { "solid": { "last_modified": 1684767582, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM96.8 314.1c-3.8-13.7 7.4-26.1 21.6-26.1H393.6c14.2 0 25.5 12.4 21.6 26.1C396.2 382 332.1 432 256 432s-140.2-50-159.2-117.9zM144.4 192a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm156.4 25.6c-5.3 7.1-15.3 8.5-22.4 3.2s-8.5-15.3-3.2-22.4c30.4-40.5 91.2-40.5 121.6 0c5.3 7.1 3.9 17.1-3.2 22.4s-17.1 3.9-22.4-3.2c-17.6-23.5-52.8-23.5-70.4 0z" }, "regular": { "last_modified": 1684767582, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M464 256A208 208 0 1 0 48 256a208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm130.7 57.9c-4.2-13.6 7.1-25.9 21.3-25.9H364.5c14.2 0 25.5 12.4 21.3 25.9C369 368.4 318.2 408 258.2 408s-110.8-39.6-127.5-94.1zM144.4 192a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm165.8 21.7c-7.6 8.1-20.2 8.5-28.3 .9s-8.5-20.2-.9-28.3c14.5-15.5 35.2-22.3 54.6-22.3s40.1 6.8 54.6 22.3c7.6 8.1 7.1 20.7-.9 28.3s-20.7 7.1-28.3-.9c-5.5-5.8-14.8-9.7-25.4-9.7s-19.9 3.8-25.4 9.7z" } }, "free": ["regular", "solid"] }, "face-meh": { "aliases": { "names": ["meh"], "unicodes": { "composite": ["1f610"], "secondary": ["10f11a"] } }, "changes": [ "3.1.0", "5.0.0", "5.0.9", "5.1.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "deadpan", "emoticon", "face", "meh", "neutral", "neutral face", "rating" ] }, "styles": ["solid", "regular"], "unicode": "f11a", "label": "Face Meh", "voted": false, "svg": { "solid": { "last_modified": 1684767582, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM176.4 176a32 32 0 1 1 0 64 32 32 0 1 1 0-64zm128 32a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zM160 336H352c8.8 0 16 7.2 16 16s-7.2 16-16 16H160c-8.8 0-16-7.2-16-16s7.2-16 16-16z" }, "regular": { "last_modified": 1684767582, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M464 256A208 208 0 1 1 48 256a208 208 0 1 1 416 0zM256 0a256 256 0 1 0 0 512A256 256 0 1 0 256 0zM176.4 240a32 32 0 1 0 0-64 32 32 0 1 0 0 64zm192-32a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zM184 328c-13.3 0-24 10.7-24 24s10.7 24 24 24H328c13.3 0 24-10.7 24-24s-10.7-24-24-24H184z" } }, "free": ["regular", "solid"] }, "face-meh-blank": { "aliases": { "names": ["meh-blank"], "unicodes": { "composite": ["1f636"], "secondary": ["10f5a4"] } }, "changes": [ "5.1.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "emoticon", "face", "face without mouth", "mouth", "neutral", "quiet", "rating", "silent" ] }, "styles": ["solid", "regular"], "unicode": "f5a4", "label": "Face Meh Blank", "voted": false, "svg": { "solid": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm208.4-48a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zm128 32a32 32 0 1 0 0-64 32 32 0 1 0 0 64z" }, "regular": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 48a208 208 0 1 0 0 416 208 208 0 1 0 0-416zM512 256A256 256 0 1 1 0 256a256 256 0 1 1 512 0zM144.4 208a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm192-32a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" } }, "free": ["regular", "solid"] }, "face-rolling-eyes": { "aliases": { "names": ["meh-rolling-eyes"], "unicodes": { "composite": ["1f644"], "secondary": ["10f5a5"] } }, "changes": [ "5.1.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "emoticon", "eyeroll", "eyes", "face", "face with rolling eyes", "neutral", "rating", "rolling" ] }, "styles": ["solid", "regular"], "unicode": "f5a5", "label": "Face Rolling Eyes", "voted": false, "svg": { "solid": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM192 368H320c8.8 0 16 7.2 16 16s-7.2 16-16 16H192c-8.8 0-16-7.2-16-16s7.2-16 16-16zm32-144c0 35.3-28.7 64-64 64s-64-28.7-64-64c0-26 15.5-48.4 37.8-58.4c-3.7 5.2-5.8 11.6-5.8 18.4c0 17.7 14.3 32 32 32s32-14.3 32-32c0-6.9-2.2-13.2-5.8-18.4C208.5 175.6 224 198 224 224zm128 64c-35.3 0-64-28.7-64-64c0-26 15.5-48.4 37.8-58.4c-3.7 5.2-5.8 11.6-5.8 18.4c0 17.7 14.3 32 32 32s32-14.3 32-32c0-6.9-2.2-13.2-5.8-18.4C400.5 175.6 416 198 416 224c0 35.3-28.7 64-64 64z" }, "regular": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 48a208 208 0 1 1 0 416 208 208 0 1 1 0-416zm0 464A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM168 376c0 13.3 10.7 24 24 24H320c13.3 0 24-10.7 24-24s-10.7-24-24-24H192c-13.3 0-24 10.7-24 24zm-8-104c-26.5 0-48-21.5-48-48c0-14.3 6.3-27.2 16.2-36c-.2 1.3-.2 2.6-.2 4c0 17.7 14.3 32 32 32s32-14.3 32-32c0-1.4-.1-2.7-.2-4c10 8.8 16.2 21.7 16.2 36c0 26.5-21.5 48-48 48zm0 32a80 80 0 1 0 0-160 80 80 0 1 0 0 160zm192-32c-26.5 0-48-21.5-48-48c0-14.3 6.3-27.2 16.2-36c-.2 1.3-.2 2.6-.2 4c0 17.7 14.3 32 32 32s32-14.3 32-32c0-1.4-.1-2.7-.2-4c10 8.8 16.2 21.7 16.2 36c0 26.5-21.5 48-48 48zm0 32a80 80 0 1 0 0-160 80 80 0 1 0 0 160z" } }, "free": ["regular", "solid"] }, "face-sad-cry": { "aliases": { "names": ["sad-cry"], "unicodes": { "composite": ["1f62d"], "secondary": ["10f5b3"] } }, "changes": [ "5.1.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "cry", "emoticon", "face", "loudly crying face", "sad", "sob", "tear", "tears" ] }, "styles": ["solid", "regular"], "unicode": "f5b3", "label": "Face Sad Cry", "voted": false, "svg": { "solid": { "last_modified": 1684767582, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M352 493.4c-29.6 12-62.1 18.6-96 18.6s-66.4-6.6-96-18.6V288c0-8.8-7.2-16-16-16s-16 7.2-16 16V477.8C51.5 433.5 0 350.8 0 256C0 114.6 114.6 0 256 0S512 114.6 512 256c0 94.8-51.5 177.5-128 221.8V288c0-8.8-7.2-16-16-16s-16 7.2-16 16V493.4zM195.2 233.6c5.3 7.1 15.3 8.5 22.4 3.2s8.5-15.3 3.2-22.4c-30.4-40.5-91.2-40.5-121.6 0c-5.3 7.1-3.9 17.1 3.2 22.4s17.1 3.9 22.4-3.2c17.6-23.5 52.8-23.5 70.4 0zm121.6 0c17.6-23.5 52.8-23.5 70.4 0c5.3 7.1 15.3 8.5 22.4 3.2s8.5-15.3 3.2-22.4c-30.4-40.5-91.2-40.5-121.6 0c-5.3 7.1-3.9 17.1 3.2 22.4s17.1 3.9 22.4-3.2zM208 336v32c0 26.5 21.5 48 48 48s48-21.5 48-48V336c0-26.5-21.5-48-48-48s-48 21.5-48 48z" }, "regular": { "last_modified": 1684767582, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M400 406.1V288c0-13.3-10.7-24-24-24s-24 10.7-24 24V440.6c-28.7 15-61.4 23.4-96 23.4s-67.3-8.5-96-23.4V288c0-13.3-10.7-24-24-24s-24 10.7-24 24V406.1C72.6 368.2 48 315 48 256C48 141.1 141.1 48 256 48s208 93.1 208 208c0 59-24.6 112.2-64 150.1zM256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM159.6 220c10.6 0 19.9 3.8 25.4 9.7c7.6 8.1 20.2 8.5 28.3 .9s8.5-20.2 .9-28.3C199.7 186.8 179 180 159.6 180s-40.1 6.8-54.6 22.3c-7.6 8.1-7.1 20.7 .9 28.3s20.7 7.1 28.3-.9c5.5-5.8 14.8-9.7 25.4-9.7zm166.6 9.7c5.5-5.8 14.8-9.7 25.4-9.7s19.9 3.8 25.4 9.7c7.6 8.1 20.2 8.5 28.3 .9s8.5-20.2 .9-28.3C391.7 186.8 371 180 351.6 180s-40.1 6.8-54.6 22.3c-7.6 8.1-7.1 20.7 .9 28.3s20.7 7.1 28.3-.9zM208 320v32c0 26.5 21.5 48 48 48s48-21.5 48-48V320c0-26.5-21.5-48-48-48s-48 21.5-48 48z" } }, "free": ["regular", "solid"] }, "face-sad-tear": { "aliases": { "names": ["sad-tear"], "unicodes": { "composite": ["1f622"], "secondary": ["10f5b4"] } }, "changes": [ "5.1.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "cry", "crying face", "emoticon", "face", "sad", "tear", "tears" ] }, "styles": ["solid", "regular"], "unicode": "f5b4", "label": "Face Sad Tear", "voted": false, "svg": { "solid": { "last_modified": 1684767582, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 256a256 256 0 1 0 512 0A256 256 0 1 0 0 256zm240 80c0-8.8 7.2-16 16-16c45 0 85.6 20.5 115.7 53.1c6 6.5 5.6 16.6-.9 22.6s-16.6 5.6-22.6-.9c-25-27.1-57.4-42.9-92.3-42.9c-8.8 0-16-7.2-16-16zm-80 80c-26.5 0-48-21-48-47c0-20 28.6-60.4 41.6-77.7c3.2-4.4 9.6-4.4 12.8 0C179.6 308.6 208 349 208 369c0 26-21.5 47-48 47zM367.6 208a32 32 0 1 1 -64 0 32 32 0 1 1 64 0zm-192-32a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" }, "regular": { "last_modified": 1684767582, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M175.9 448c-35-.1-65.5-22.6-76-54.6C67.6 356.8 48 308.7 48 256C48 141.1 141.1 48 256 48s208 93.1 208 208s-93.1 208-208 208c-28.4 0-55.5-5.7-80.1-16zM0 256a256 256 0 1 0 512 0A256 256 0 1 0 0 256zM128 369c0 26 21.5 47 48 47s48-21 48-47c0-20-28.4-60.4-41.6-77.7c-3.2-4.4-9.6-4.4-12.8 0C156.6 308.6 128 349 128 369zm128-65c-13.3 0-24 10.7-24 24s10.7 24 24 24c30.7 0 58.7 11.5 80 30.6c9.9 8.8 25 8 33.9-1.9s8-25-1.9-33.9C338.3 320.2 299 304 256 304zm47.6-96a32 32 0 1 0 64 0 32 32 0 1 0 -64 0zm-128 32a32 32 0 1 0 0-64 32 32 0 1 0 0 64z" } }, "free": ["regular", "solid"] }, "face-smile": { "aliases": { "names": ["smile"], "unicodes": { "composite": ["1f642"], "secondary": ["10f118"] } }, "changes": [ "3.1.0", "5.0.0", "5.0.9", "5.1.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "approve", "emoticon", "face", "happy", "rating", "satisfied", "slightly smiling face", "smile" ] }, "styles": ["solid", "regular"], "unicode": "f118", "label": "Face Smile", "voted": false, "svg": { "solid": { "last_modified": 1684767582, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM164.1 325.5C182 346.2 212.6 368 256 368s74-21.8 91.9-42.5c5.8-6.7 15.9-7.4 22.6-1.6s7.4 15.9 1.6 22.6C349.8 372.1 311.1 400 256 400s-93.8-27.9-116.1-53.5c-5.8-6.7-5.1-16.8 1.6-22.6s16.8-5.1 22.6 1.6zM144.4 208a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm192-32a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" }, "regular": { "last_modified": 1684767582, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M464 256A208 208 0 1 0 48 256a208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm177.6 62.1C192.8 334.5 218.8 352 256 352s63.2-17.5 78.4-33.9c9-9.7 24.2-10.4 33.9-1.4s10.4 24.2 1.4 33.9c-22 23.8-60 49.4-113.6 49.4s-91.7-25.5-113.6-49.4c-9-9.7-8.4-24.9 1.4-33.9s24.9-8.4 33.9 1.4zM144.4 208a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm192-32a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" } }, "free": ["regular", "solid"] }, "face-smile-beam": { "aliases": { "names": ["smile-beam"], "unicodes": { "composite": ["1f60a"], "secondary": ["10f5b8"] } }, "changes": [ "5.1.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "blush", "emoticon", "eye", "face", "happy", "positive", "smile", "smiling face with smiling eyes" ] }, "styles": ["solid", "regular"], "unicode": "f5b8", "label": "Face Smile Beam", "voted": false, "svg": { "solid": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM164.1 325.5C182 346.2 212.6 368 256 368s74-21.8 91.9-42.5c5.8-6.7 15.9-7.4 22.6-1.6s7.4 15.9 1.6 22.6C349.8 372.1 311.1 400 256 400s-93.8-27.9-116.1-53.5c-5.8-6.7-5.1-16.8 1.6-22.6s16.8-5.1 22.6 1.6zm53.5-96.7l0 0 0 0-.2-.2c-.2-.2-.4-.5-.7-.9c-.6-.8-1.6-2-2.8-3.4c-2.5-2.8-6-6.6-10.2-10.3c-8.8-7.8-18.8-14-27.7-14s-18.9 6.2-27.7 14c-4.2 3.7-7.7 7.5-10.2 10.3c-1.2 1.4-2.2 2.6-2.8 3.4c-.3 .4-.6 .7-.7 .9l-.2 .2 0 0 0 0 0 0c-2.1 2.8-5.7 3.9-8.9 2.8s-5.5-4.1-5.5-7.6c0-17.9 6.7-35.6 16.6-48.8c9.8-13 23.9-23.2 39.4-23.2s29.6 10.2 39.4 23.2c9.9 13.2 16.6 30.9 16.6 48.8c0 3.4-2.2 6.5-5.5 7.6s-6.9 0-8.9-2.8l0 0 0 0zm160 0l0 0-.2-.2c-.2-.2-.4-.5-.7-.9c-.6-.8-1.6-2-2.8-3.4c-2.5-2.8-6-6.6-10.2-10.3c-8.8-7.8-18.8-14-27.7-14s-18.9 6.2-27.7 14c-4.2 3.7-7.7 7.5-10.2 10.3c-1.2 1.4-2.2 2.6-2.8 3.4c-.3 .4-.6 .7-.7 .9l-.2 .2 0 0 0 0 0 0c-2.1 2.8-5.7 3.9-8.9 2.8s-5.5-4.1-5.5-7.6c0-17.9 6.7-35.6 16.6-48.8c9.8-13 23.9-23.2 39.4-23.2s29.6 10.2 39.4 23.2c9.9 13.2 16.6 30.9 16.6 48.8c0 3.4-2.2 6.5-5.5 7.6s-6.9 0-8.9-2.8l0 0 0 0 0 0z" }, "regular": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M464 256A208 208 0 1 0 48 256a208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm177.6 62.1C192.8 334.5 218.8 352 256 352s63.2-17.5 78.4-33.9c9-9.7 24.2-10.4 33.9-1.4s10.4 24.2 1.4 33.9c-22 23.8-60 49.4-113.6 49.4s-91.7-25.5-113.6-49.4c-9-9.7-8.4-24.9 1.4-33.9s24.9-8.4 33.9 1.4zm40-89.3l0 0 0 0-.2-.2c-.2-.2-.4-.5-.7-.9c-.6-.8-1.6-2-2.8-3.4c-2.5-2.8-6-6.6-10.2-10.3c-8.8-7.8-18.8-14-27.7-14s-18.9 6.2-27.7 14c-4.2 3.7-7.7 7.5-10.2 10.3c-1.2 1.4-2.2 2.6-2.8 3.4c-.3 .4-.6 .7-.7 .9l-.2 .2 0 0 0 0 0 0c-2.1 2.8-5.7 3.9-8.9 2.8s-5.5-4.1-5.5-7.6c0-17.9 6.7-35.6 16.6-48.8c9.8-13 23.9-23.2 39.4-23.2s29.6 10.2 39.4 23.2c9.9 13.2 16.6 30.9 16.6 48.8c0 3.4-2.2 6.5-5.5 7.6s-6.9 0-8.9-2.8l0 0 0 0zm160 0l0 0-.2-.2c-.2-.2-.4-.5-.7-.9c-.6-.8-1.6-2-2.8-3.4c-2.5-2.8-6-6.6-10.2-10.3c-8.8-7.8-18.8-14-27.7-14s-18.9 6.2-27.7 14c-4.2 3.7-7.7 7.5-10.2 10.3c-1.2 1.4-2.2 2.6-2.8 3.4c-.3 .4-.6 .7-.7 .9l-.2 .2 0 0 0 0 0 0c-2.1 2.8-5.7 3.9-8.9 2.8s-5.5-4.1-5.5-7.6c0-17.9 6.7-35.6 16.6-48.8c9.8-13 23.9-23.2 39.4-23.2s29.6 10.2 39.4 23.2c9.9 13.2 16.6 30.9 16.6 48.8c0 3.4-2.2 6.5-5.5 7.6s-6.9 0-8.9-2.8l0 0 0 0 0 0z" } }, "free": ["regular", "solid"] }, "face-smile-wink": { "aliases": { "names": ["smile-wink"], "unicodes": { "composite": ["1f609"], "secondary": ["10f4da"] } }, "changes": [ "5.1.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "emoticon", "face", "happy", "hint", "joke", "wink", "winking face" ] }, "styles": ["solid", "regular"], "unicode": "f4da", "label": "Face Smile Wink", "voted": false, "svg": { "solid": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM164.1 325.5C182 346.2 212.6 368 256 368s74-21.8 91.9-42.5c5.8-6.7 15.9-7.4 22.6-1.6s7.4 15.9 1.6 22.6C349.8 372.1 311.1 400 256 400s-93.8-27.9-116.1-53.5c-5.8-6.7-5.1-16.8 1.6-22.6s16.8-5.1 22.6 1.6zM144.4 208a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm156.4 25.6c-5.3 7.1-15.3 8.5-22.4 3.2s-8.5-15.3-3.2-22.4c30.4-40.5 91.2-40.5 121.6 0c5.3 7.1 3.9 17.1-3.2 22.4s-17.1 3.9-22.4-3.2c-17.6-23.5-52.8-23.5-70.4 0z" }, "regular": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M464 256A208 208 0 1 0 48 256a208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm177.6 62.1C192.8 334.5 218.8 352 256 352s63.2-17.5 78.4-33.9c9-9.7 24.2-10.4 33.9-1.4s10.4 24.2 1.4 33.9c-22 23.8-60 49.4-113.6 49.4s-91.7-25.5-113.6-49.4c-9-9.7-8.4-24.9 1.4-33.9s24.9-8.4 33.9 1.4zM144.4 208a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm165.8 21.7c-7.6 8.1-20.2 8.5-28.3 .9s-8.5-20.2-.9-28.3c14.5-15.5 35.2-22.3 54.6-22.3s40.1 6.8 54.6 22.3c7.6 8.1 7.1 20.7-.9 28.3s-20.7 7.1-28.3-.9c-5.5-5.8-14.8-9.7-25.4-9.7s-19.9 3.8-25.4 9.7z" } }, "free": ["regular", "solid"] }, "face-surprise": { "aliases": { "names": ["surprise"], "unicodes": { "composite": ["1f62e"], "secondary": ["10f5c2"] } }, "changes": [ "5.1.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "emoticon", "face", "face with open mouth", "mouth", "open", "shocked", "sympathy" ] }, "styles": ["solid", "regular"], "unicode": "f5c2", "label": "Face Surprise", "voted": false, "svg": { "solid": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM176.4 176a32 32 0 1 1 0 64 32 32 0 1 1 0-64zm128 32a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zM256 288a64 64 0 1 1 0 128 64 64 0 1 1 0-128z" }, "regular": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M464 256A208 208 0 1 0 48 256a208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm176.4-80a32 32 0 1 1 0 64 32 32 0 1 1 0-64zm128 32a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zM256 288a64 64 0 1 1 0 128 64 64 0 1 1 0-128z" } }, "free": ["regular", "solid"] }, "face-tired": { "aliases": { "names": ["tired"], "unicodes": { "composite": ["1f62b"], "secondary": ["10f5c8"] } }, "changes": [ "5.1.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "angry", "emoticon", "face", "grumpy", "tired", "tired face", "upset" ] }, "styles": ["solid", "regular"], "unicode": "f5c8", "label": "Face Tired", "voted": false, "svg": { "solid": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM164.7 328.7c22-22 53.9-40.7 91.3-40.7s69.3 18.7 91.3 40.7c11.1 11.1 20.1 23.4 26.4 35.4c6.2 11.7 10.3 24.4 10.3 35.9c0 5.2-2.6 10.2-6.9 13.2s-9.8 3.7-14.7 1.8l-20.5-7.7c-26.9-10.1-55.5-15.3-84.3-15.3h-3.2c-28.8 0-57.3 5.2-84.3 15.3L149.6 415c-4.9 1.8-10.4 1.2-14.7-1.8s-6.9-7.9-6.9-13.2c0-11.6 4.2-24.2 10.3-35.9c6.3-12 15.3-24.3 26.4-35.4zm-31.2-182l89.9 47.9c10.7 5.7 10.7 21.1 0 26.8l-89.9 47.9c-7.9 4.2-17.5-1.5-17.5-10.5c0-2.8 1-5.5 2.8-7.6l36-43.2-36-43.2c-1.8-2.1-2.8-4.8-2.8-7.6c0-9 9.6-14.7 17.5-10.5zM396 157.1c0 2.8-1 5.5-2.8 7.6l-36 43.2 36 43.2c1.8 2.1 2.8 4.8 2.8 7.6c0 9-9.6 14.7-17.5 10.5l-89.9-47.9c-10.7-5.7-10.7-21.1 0-26.8l89.9-47.9c7.9-4.2 17.5 1.5 17.5 10.5z" }, "regular": { "last_modified": 1684767583, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M464 256A208 208 0 1 0 48 256a208 208 0 1 0 416 0zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm176.5 64.3C196.1 302.1 223.8 288 256 288s59.9 14.1 79.5 32.3C354.5 338.1 368 362 368 384c0 5.4-2.7 10.4-7.2 13.4s-10.2 3.4-15.2 1.3l-17.2-7.5c-22.8-10-47.5-15.1-72.4-15.1s-49.6 5.2-72.4 15.1l-17.2 7.5c-4.9 2.2-10.7 1.7-15.2-1.3s-7.2-8-7.2-13.4c0-22 13.5-45.9 32.5-63.7zm-43-173.6l89.9 47.9c10.7 5.7 10.7 21.1 0 26.8l-89.9 47.9c-7.9 4.2-17.5-1.5-17.5-10.5c0-2.8 1-5.5 2.8-7.6l36-43.2-36-43.2c-1.8-2.1-2.8-4.8-2.8-7.6c0-9 9.6-14.7 17.5-10.5zM396 157.1c0 2.8-1 5.5-2.8 7.6l-36 43.2 36 43.2c1.8 2.1 2.8 4.8 2.8 7.6c0 9-9.6 14.7-17.5 10.5l-89.9-47.9c-10.7-5.7-10.7-21.1 0-26.8l89.9-47.9c7.9-4.2 17.5 1.5 17.5 10.5z" } }, "free": ["regular", "solid"] }, "facebook": { "aliases": { "unicodes": { "composite": ["f230"] } }, "changes": ["2.0.0", "5.0.0", "5.8.2"], "ligatures": [], "search": { "terms": ["facebook-official", "social network"] }, "styles": ["brands"], "unicode": "f09a", "label": "Facebook", "voted": false, "svg": { "brands": { "last_modified": 1660014466, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M504 256C504 119 393 8 256 8S8 119 8 256c0 123.78 90.69 226.38 209.25 245V327.69h-63V256h63v-54.64c0-62.15 37-96.48 93.67-96.48 27.14 0 55.52 4.84 55.52 4.84v61h-31.28c-30.8 0-40.41 19.12-40.41 38.73V256h68.78l-11 71.69h-57.78V501C413.31 482.38 504 379.78 504 256z" } }, "free": ["brands"] }, "facebook-f": { "changes": ["5.0.0", "5.8.2"], "ligatures": [], "search": { "terms": ["facebook"] }, "styles": ["brands"], "unicode": "f39e", "label": "Facebook F", "voted": false, "svg": { "brands": { "last_modified": 1660014470, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M279.14 288l14.22-92.66h-88.91v-60.13c0-25.35 12.42-50.06 52.24-50.06h40.42V6.26S260.43 0 225.36 0c-73.22 0-121.08 44.38-121.08 124.72v70.62H22.89V288h81.39v224h100.17V288z" } }, "free": ["brands"] }, "facebook-messenger": { "changes": ["5.0.0", "5.8.2", "5.9.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f39f", "label": "Facebook Messenger", "voted": false, "svg": { "brands": { "last_modified": 1660014468, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256.55 8C116.52 8 8 110.34 8 248.57c0 72.3 29.71 134.78 78.07 177.94 8.35 7.51 6.63 11.86 8.05 58.23A19.92 19.92 0 0 0 122 502.31c52.91-23.3 53.59-25.14 62.56-22.7C337.85 521.8 504 423.7 504 248.57 504 110.34 396.59 8 256.55 8zm149.24 185.13l-73 115.57a37.37 37.37 0 0 1-53.91 9.93l-58.08-43.47a15 15 0 0 0-18 0l-78.37 59.44c-10.46 7.93-24.16-4.6-17.11-15.67l73-115.57a37.36 37.36 0 0 1 53.91-9.93l58.06 43.46a15 15 0 0 0 18 0l78.41-59.38c10.44-7.98 24.14 4.54 17.09 15.62z" } }, "free": ["brands"] }, "fan": { "aliases": { "unicodes": { "secondary": ["10f863"] } }, "changes": ["5.9.0", "5.10.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["ac", "air conditioning", "blade", "blower", "cool", "hot"] }, "styles": ["solid"], "unicode": "f863", "label": "Fan", "voted": true, "svg": { "solid": { "last_modified": 1684767441, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M258.6 0c-1.7 0-3.4 .1-5.1 .5C168 17 115.6 102.3 130.5 189.3c2.9 17 8.4 32.9 15.9 47.4L32 224H29.4C13.2 224 0 237.2 0 253.4c0 1.7 .1 3.4 .5 5.1C17 344 102.3 396.4 189.3 381.5c17-2.9 32.9-8.4 47.4-15.9L224 480v2.6c0 16.2 13.2 29.4 29.4 29.4c1.7 0 3.4-.1 5.1-.5C344 495 396.4 409.7 381.5 322.7c-2.9-17-8.4-32.9-15.9-47.4L480 288h2.6c16.2 0 29.4-13.2 29.4-29.4c0-1.7-.1-3.4-.5-5.1C495 168 409.7 115.6 322.7 130.5c-17 2.9-32.9 8.4-47.4 15.9L288 32V29.4C288 13.2 274.8 0 258.6 0zM256 224a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" } }, "free": ["solid"] }, "fantasy-flight-games": { "changes": ["5.4.0"], "ligatures": [], "search": { "terms": [ "Dungeons & Dragons", "d&d", "dnd", "fantasy", "game", "gaming", "tabletop" ] }, "styles": ["brands"], "unicode": "f6dc", "label": "Fantasy Flight-games", "voted": false, "svg": { "brands": { "last_modified": 1660014463, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 32.86L32.86 256 256 479.14 479.14 256 256 32.86zM88.34 255.83c1.96-2 11.92-12.3 96.49-97.48 41.45-41.75 86.19-43.77 119.77-18.69 24.63 18.4 62.06 58.9 62.15 59 .68.74 1.07 2.86.58 3.38-11.27 11.84-22.68 23.54-33.5 34.69-34.21-32.31-40.52-38.24-48.51-43.95-17.77-12.69-41.4-10.13-56.98 5.1-2.17 2.13-1.79 3.43.12 5.35 2.94 2.95 28.1 28.33 35.09 35.78-11.95 11.6-23.66 22.97-35.69 34.66-12.02-12.54-24.48-25.53-36.54-38.11-21.39 21.09-41.69 41.11-61.85 60.99zm234.82 101.6c-35.49 35.43-78.09 38.14-106.99 20.47-22.08-13.5-39.38-32.08-72.93-66.84 12.05-12.37 23.79-24.42 35.37-36.31 33.02 31.91 37.06 36.01 44.68 42.09 18.48 14.74 42.52 13.67 59.32-1.8 3.68-3.39 3.69-3.64.14-7.24-10.59-10.73-21.19-21.44-31.77-32.18-1.32-1.34-3.03-2.48-.8-4.69 10.79-10.71 21.48-21.52 32.21-32.29.26-.26.65-.38 1.91-1.07 12.37 12.87 24.92 25.92 37.25 38.75 21.01-20.73 41.24-40.68 61.25-60.42 13.68 13.4 27.13 26.58 40.86 40.03-20.17 20.86-81.68 82.71-100.5 101.5zM256 0L0 256l256 256 256-256L256 0zM16 256L256 16l240 240-240 240L16 256z" } }, "free": ["brands"] }, "faucet": { "aliases": { "unicodes": { "secondary": ["10e005"] } }, "changes": ["5.12.0", "5.14.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "covid-19", "drinking", "drip", "house", "hygiene", "kitchen", "potable", "potable water", "sanitation", "sink", "water" ] }, "styles": ["solid"], "unicode": "e005", "label": "Faucet", "voted": false, "svg": { "solid": { "last_modified": 1684767442, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M192 96v12L96 96c-17.7 0-32 14.3-32 32s14.3 32 32 32l96-12 31-3.9 1-.1 1 .1 31 3.9 96 12c17.7 0 32-14.3 32-32s-14.3-32-32-32l-96 12V96c0-17.7-14.3-32-32-32s-32 14.3-32 32zM32 256c-17.7 0-32 14.3-32 32v64c0 17.7 14.3 32 32 32H132.1c20.2 29 53.9 48 91.9 48s71.7-19 91.9-48H352c17.7 0 32 14.3 32 32s14.3 32 32 32h64c17.7 0 32-14.3 32-32c0-88.4-71.6-160-160-160H320l-22.6-22.6c-6-6-14.1-9.4-22.6-9.4H256V180.2l-32-4-32 4V224H173.3c-8.5 0-16.6 3.4-22.6 9.4L128 256H32z" } }, "free": ["solid"] }, "faucet-drip": { "aliases": { "unicodes": { "composite": ["1f6b0"], "secondary": ["10e006"] } }, "changes": [ "5.12.0", "5.14.0", "6.0.0-beta1", "6.1.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "drinking", "drip", "house", "hygiene", "kitchen", "potable", "potable water", "sanitation", "sink", "water" ] }, "styles": ["solid"], "unicode": "e006", "label": "Faucet Drip", "voted": false, "svg": { "solid": { "last_modified": 1684767442, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M224 0c17.7 0 32 14.3 32 32V44l96-12c17.7 0 32 14.3 32 32s-14.3 32-32 32L256 84l-31-3.9-1-.1-1 .1L192 84 96 96C78.3 96 64 81.7 64 64s14.3-32 32-32l96 12V32c0-17.7 14.3-32 32-32zM0 224c0-17.7 14.3-32 32-32h96l22.6-22.6c6-6 14.1-9.4 22.6-9.4H192V116.2l32-4 32 4V160h18.7c8.5 0 16.6 3.4 22.6 9.4L320 192h32c88.4 0 160 71.6 160 160c0 17.7-14.3 32-32 32H416c-17.7 0-32-14.3-32-32s-14.3-32-32-32H315.9c-20.2 29-53.9 48-91.9 48s-71.7-19-91.9-48H32c-17.7 0-32-14.3-32-32V224zM436.8 423.4c1.9-4.5 6.3-7.4 11.2-7.4s9.2 2.9 11.2 7.4l18.2 42.4c1.8 4.1 2.7 8.6 2.7 13.1V480c0 17.7-14.3 32-32 32s-32-14.3-32-32v-1.2c0-4.5 .9-8.9 2.7-13.1l18.2-42.4z" } }, "free": ["solid"] }, "fax": { "aliases": { "unicodes": { "composite": ["1f4e0", "1f5b7"], "secondary": ["10f1ac"] } }, "changes": [ "4.1.0", "5.0.0", "5.3.0", "5.11.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Fax Icon", "business", "communicate", "copy", "facsimile", "fax", "fax machine", "send" ] }, "styles": ["solid"], "unicode": "f1ac", "label": "Fax", "voted": false, "svg": { "solid": { "last_modified": 1684767342, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M128 64v96h64V64H386.7L416 93.3V160h64V93.3c0-17-6.7-33.3-18.7-45.3L432 18.7C420 6.7 403.7 0 386.7 0H192c-35.3 0-64 28.7-64 64zM0 160V480c0 17.7 14.3 32 32 32H64c17.7 0 32-14.3 32-32V160c0-17.7-14.3-32-32-32H32c-17.7 0-32 14.3-32 32zm480 32H128V480c0 17.7 14.3 32 32 32H480c17.7 0 32-14.3 32-32V224c0-17.7-14.3-32-32-32zM256 256a32 32 0 1 1 0 64 32 32 0 1 1 0-64zm96 32a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm32 96a32 32 0 1 1 0 64 32 32 0 1 1 0-64zM224 416a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z" } }, "free": ["solid"] }, "feather": { "aliases": { "unicodes": { "composite": ["1fab6"], "secondary": ["10f52d"] } }, "changes": ["5.0.13", "5.1.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "bird", "feather", "flight", "light", "plucked", "plumage", "quill", "write" ] }, "styles": ["solid"], "unicode": "f52d", "label": "Feather", "voted": true, "svg": { "solid": { "last_modified": 1684768131, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M278.5 215.6L23 471c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l57-57h68c49.7 0 97.9-14.4 139-41c11.1-7.2 5.5-23-7.8-23c-5.1 0-9.2-4.1-9.2-9.2c0-4.1 2.7-7.6 6.5-8.8l81-24.3c2.5-.8 4.8-2.1 6.7-4l22.4-22.4c10.1-10.1 2.9-27.3-11.3-27.3l-32.2 0c-5.1 0-9.2-4.1-9.2-9.2c0-4.1 2.7-7.6 6.5-8.8l112-33.6c4-1.2 7.4-3.9 9.3-7.7C506.4 207.6 512 184.1 512 160c0-41-16.3-80.3-45.3-109.3l-5.5-5.5C432.3 16.3 393 0 352 0s-80.3 16.3-109.3 45.3L139 149C91 197 64 262.1 64 330v55.3L253.6 195.8c6.2-6.2 16.4-6.2 22.6 0c5.4 5.4 6.1 13.6 2.2 19.8z" } }, "free": ["solid"] }, "feather-pointed": { "aliases": { "names": ["feather-alt"], "unicodes": { "secondary": ["10f56b"] } }, "changes": ["5.1.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["bird", "light", "plucked", "quill", "write"] }, "styles": ["solid"], "unicode": "f56b", "label": "Feather Pointed", "voted": true, "svg": { "solid": { "last_modified": 1684768130, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M278.5 215.6L23 471c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l74.8-74.8c7.4 4.6 15.3 8.2 23.8 10.5C200.3 452.8 270 454.5 338 409.4c12.2-8.1 5.8-25.4-8.8-25.4l-16.1 0c-5.1 0-9.2-4.1-9.2-9.2c0-4.1 2.7-7.6 6.5-8.8l97.7-29.3c3.4-1 6.4-3.1 8.4-6.1c4.4-6.4 8.6-12.9 12.6-19.6c6.2-10.3-1.5-23-13.5-23l-38.6 0c-5.1 0-9.2-4.1-9.2-9.2c0-4.1 2.7-7.6 6.5-8.8l80.9-24.3c4.6-1.4 8.4-4.8 10.2-9.3C494.5 163 507.8 86.1 511.9 36.8c.8-9.9-3-19.6-10-26.6s-16.7-10.8-26.6-10C391.5 7 228.5 40.5 137.4 131.6C57.3 211.7 56.7 302.3 71.3 356.4c2.1 7.9 12 9.6 17.8 3.8L253.6 195.8c6.2-6.2 16.4-6.2 22.6 0c5.4 5.4 6.1 13.6 2.2 19.8z" } }, "free": ["solid"] }, "fedex": { "changes": ["5.6.0"], "ligatures": [], "search": { "terms": ["Federal Express", "package", "shipping"] }, "styles": ["brands"], "unicode": "f797", "label": "FedEx", "voted": false, "svg": { "brands": { "last_modified": 1660014473, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M586 284.5l53.3-59.9h-62.4l-21.7 24.8-22.5-24.8H414v-16h56.1v-48.1H318.9V236h-.5c-9.6-11-21.5-14.8-35.4-14.8-28.4 0-49.8 19.4-57.3 44.9-18-59.4-97.4-57.6-121.9-14v-24.2H49v-26.2h60v-41.1H0V345h49v-77.5h48.9c-1.5 5.7-2.3 11.8-2.3 18.2 0 73.1 102.6 91.4 130.2 23.7h-42c-14.7 20.9-45.8 8.9-45.8-14.6h85.5c3.7 30.5 27.4 56.9 60.1 56.9 14.1 0 27-6.9 34.9-18.6h.5V345h212.2l22.1-25 22.3 25H640l-54-60.5zm-446.7-16.6c6.1-26.3 41.7-25.6 46.5 0h-46.5zm153.4 48.9c-34.6 0-34-62.8 0-62.8 32.6 0 34.5 62.8 0 62.8zm167.8 19.1h-94.4V169.4h95v30.2H405v33.9h55.5v28.1h-56.1v44.7h56.1v29.6zm-45.9-39.8v-24.4h56.1v-44l50.7 57-50.7 57v-45.6h-56.1zm138.6 10.3l-26.1 29.5H489l45.6-51.2-45.6-51.2h39.7l26.6 29.3 25.6-29.3h38.5l-45.4 51 46 51.4h-40.5l-26.3-29.5z" } }, "free": ["brands"] }, "fedora": { "changes": ["5.6.0", "5.6.3", "5.8.0", "6.0.0"], "ligatures": [], "search": { "terms": ["linux", "operating system", "os"] }, "styles": ["brands"], "unicode": "f798", "label": "Fedora", "voted": true, "svg": { "brands": { "last_modified": 1660014475, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M.0413 255.8C.1219 132.2 100.3 32 224 32C347.7 32 448 132.3 448 256C448 379.7 347.8 479.9 224.1 480H50.93C22.84 480 .0832 457.3 .0416 429.2H0V255.8H.0413zM342.6 192.7C342.6 153 307 124.2 269.4 124.2C234.5 124.2 203.6 150.5 199.3 184.1C199.1 187.9 198.9 189.1 198.9 192.6C198.8 213.7 198.9 235.4 198.1 257C199 283.1 199.1 309.1 198.1 333.6C198.1 360.7 178.7 379.1 153.4 379.1C128.1 379.1 107.6 358.9 107.6 333.6C108.1 305.9 130.2 288.3 156.1 287.5H156.3L182.6 287.3V250L156.3 250.2C109.2 249.8 71.72 286.7 70.36 333.6C70.36 379.2 107.9 416.5 153.4 416.5C196.4 416.5 232.1 382.9 236 340.9L236.2 287.4L268.8 287.1C294.1 287.3 293.8 249.3 268.6 249.8L236.2 250.1C236.2 243.7 236.3 237.3 236.3 230.9C236.4 218.2 236.4 205.5 236.2 192.7C236.3 176.2 252 161.5 269.4 161.5C286.9 161.5 305.3 170.2 305.3 192.7C305.3 195.9 305.2 197.8 305 199C303.1 209.5 310.2 219.4 320.7 220.9C331.3 222.4 340.9 214.8 341.9 204.3C342.5 200.1 342.6 196.4 342.6 192.7H342.6z" } }, "free": ["brands"] }, "ferry": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["barge", "boat", "carry", "ferryboat", "ship"] }, "styles": ["solid"], "unicode": "e4ea", "label": "Ferry", "voted": false, "svg": { "solid": { "last_modified": 1684767637, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M224 0H352c17.7 0 32 14.3 32 32h75.1c20.6 0 31.6 24.3 18.1 39.8L456 96H120L98.8 71.8C85.3 56.3 96.3 32 116.9 32H192c0-17.7 14.3-32 32-32zM96 128H480c17.7 0 32 14.3 32 32V283.5c0 13.3-4.2 26.3-11.9 37.2l-51.4 71.9c-1.9 1.1-3.7 2.2-5.5 3.5c-15.5 10.7-34 18-51 19.9H375.6c-17.1-1.8-35-9-50.8-19.9c-22.1-15.5-51.6-15.5-73.7 0c-14.8 10.2-32.5 18-50.6 19.9H183.9c-17-1.8-35.6-9.2-51-19.9c-1.8-1.3-3.7-2.4-5.6-3.5L75.9 320.7C68.2 309.8 64 296.8 64 283.5V160c0-17.7 14.3-32 32-32zm32 64v96H448V192H128zM306.5 421.9C329 437.4 356.5 448 384 448c26.9 0 55.3-10.8 77.4-26.1l0 0c11.9-8.5 28.1-7.8 39.2 1.7c14.4 11.9 32.5 21 50.6 25.2c17.2 4 27.9 21.2 23.9 38.4s-21.2 27.9-38.4 23.9c-24.5-5.7-44.9-16.5-58.2-25C449.5 501.7 417 512 384 512c-31.9 0-60.6-9.9-80.4-18.9c-5.8-2.7-11.1-5.3-15.6-7.7c-4.5 2.4-9.7 5.1-15.6 7.7c-19.8 9-48.5 18.9-80.4 18.9c-33 0-65.5-10.3-94.5-25.8c-13.4 8.4-33.7 19.3-58.2 25c-17.2 4-34.4-6.7-38.4-23.9s6.7-34.4 23.9-38.4c18.1-4.2 36.2-13.3 50.6-25.2c11.1-9.4 27.3-10.1 39.2-1.7l0 0C136.7 437.2 165.1 448 192 448c27.5 0 55-10.6 77.5-26.1c11.1-7.9 25.9-7.9 37 0z" } }, "free": ["solid"] }, "figma": { "changes": ["5.6.0", "5.7.0", "5.8.0", "5.15.4", "6.0.0-beta2"], "ligatures": [], "search": { "terms": ["app", "design", "interface"] }, "styles": ["brands"], "unicode": "f799", "label": "Figma", "voted": false, "svg": { "brands": { "last_modified": 1660014466, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M14 95.7924C14 42.8877 56.8878 0 109.793 0H274.161C327.066 0 369.954 42.8877 369.954 95.7924C369.954 129.292 352.758 158.776 326.711 175.897C352.758 193.019 369.954 222.502 369.954 256.002C369.954 308.907 327.066 351.795 274.161 351.795H272.081C247.279 351.795 224.678 342.369 207.666 326.904V415.167C207.666 468.777 163.657 512 110.309 512C57.5361 512 14 469.243 14 416.207C14 382.709 31.1945 353.227 57.2392 336.105C31.1945 318.983 14 289.5 14 256.002C14 222.502 31.196 193.019 57.2425 175.897C31.196 158.776 14 129.292 14 95.7924ZM176.288 191.587H109.793C74.2172 191.587 45.3778 220.427 45.3778 256.002C45.3778 291.44 73.9948 320.194 109.381 320.416C109.518 320.415 109.655 320.415 109.793 320.415H176.288V191.587ZM207.666 256.002C207.666 291.577 236.505 320.417 272.081 320.417H274.161C309.737 320.417 338.576 291.577 338.576 256.002C338.576 220.427 309.737 191.587 274.161 191.587H272.081C236.505 191.587 207.666 220.427 207.666 256.002ZM109.793 351.795C109.655 351.795 109.518 351.794 109.381 351.794C73.9948 352.015 45.3778 380.769 45.3778 416.207C45.3778 451.652 74.6025 480.622 110.309 480.622C146.591 480.622 176.288 451.186 176.288 415.167V351.795H109.793ZM109.793 31.3778C74.2172 31.3778 45.3778 60.2173 45.3778 95.7924C45.3778 131.368 74.2172 160.207 109.793 160.207H176.288V31.3778H109.793ZM207.666 160.207H274.161C309.737 160.207 338.576 131.368 338.576 95.7924C338.576 60.2173 309.737 31.3778 274.161 31.3778H207.666V160.207Z" } }, "free": ["brands"] }, "file": { "aliases": { "unicodes": { "composite": ["1f4c4", "1f5cb", "f016"], "secondary": ["10f15b"] } }, "changes": [ "3.2.0", "5.0.0", "5.10.1", "5.10.2", "6.0.0-beta1", "6.1.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Empty Document", "document", "new", "page", "page facing up", "pdf", "resume" ] }, "styles": ["solid", "regular"], "unicode": "f15b", "label": "File", "voted": false, "svg": { "solid": { "last_modified": 1684767390, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M0 64C0 28.7 28.7 0 64 0H224V128c0 17.7 14.3 32 32 32H384V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V64zm384 64H256V0L384 128z" }, "regular": { "last_modified": 1684767390, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M320 464c8.8 0 16-7.2 16-16V160H256c-17.7 0-32-14.3-32-32V48H64c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16H320zM0 64C0 28.7 28.7 0 64 0H229.5c17 0 33.3 6.7 45.3 18.7l90.5 90.5c12 12 18.7 28.3 18.7 45.3V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V64z" } }, "free": ["regular", "solid"] }, "file-arrow-down": { "aliases": { "names": ["file-download"], "unicodes": { "secondary": ["10f56d"] } }, "changes": ["5.1.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["document", "export", "save"] }, "styles": ["solid"], "unicode": "f56d", "label": "File Arrow Down", "voted": true, "svg": { "solid": { "last_modified": 1684767390, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M64 0C28.7 0 0 28.7 0 64V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V160H256c-17.7 0-32-14.3-32-32V0H64zM256 0V128H384L256 0zM216 232V334.1l31-31c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-72 72c-9.4 9.4-24.6 9.4-33.9 0l-72-72c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l31 31V232c0-13.3 10.7-24 24-24s24 10.7 24 24z" } }, "free": ["solid"] }, "file-arrow-up": { "aliases": { "names": ["file-upload"], "unicodes": { "secondary": ["10f574"] } }, "changes": ["5.1.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["document", "import", "page", "save"] }, "styles": ["solid"], "unicode": "f574", "label": "File Arrow Up", "voted": true, "svg": { "solid": { "last_modified": 1684767392, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M64 0C28.7 0 0 28.7 0 64V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V160H256c-17.7 0-32-14.3-32-32V0H64zM256 0V128H384L256 0zM216 408c0 13.3-10.7 24-24 24s-24-10.7-24-24V305.9l-31 31c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l72-72c9.4-9.4 24.6-9.4 33.9 0l72 72c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-31-31V408z" } }, "free": ["solid"] }, "file-audio": { "aliases": { "unicodes": { "secondary": ["10f1c7"] } }, "changes": [ "4.1.0", "5.0.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["document", "mp3", "music", "page", "play", "sound"] }, "styles": ["solid", "regular"], "unicode": "f1c7", "label": "File Audio", "voted": false, "svg": { "solid": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M64 0C28.7 0 0 28.7 0 64V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V160H256c-17.7 0-32-14.3-32-32V0H64zM256 0V128H384L256 0zm2 226.3c37.1 22.4 62 63.1 62 109.7s-24.9 87.3-62 109.7c-7.6 4.6-17.4 2.1-22-5.4s-2.1-17.4 5.4-22C269.4 401.5 288 370.9 288 336s-18.6-65.5-46.5-82.3c-7.6-4.6-10-14.4-5.4-22s14.4-10 22-5.4zm-91.9 30.9c6 2.5 9.9 8.3 9.9 14.8V400c0 6.5-3.9 12.3-9.9 14.8s-12.9 1.1-17.4-3.5L113.4 376H80c-8.8 0-16-7.2-16-16V312c0-8.8 7.2-16 16-16h33.4l35.3-35.3c4.6-4.6 11.5-5.9 17.4-3.5zm51 34.9c6.6-5.9 16.7-5.3 22.6 1.3C249.8 304.6 256 319.6 256 336s-6.2 31.4-16.3 42.7c-5.9 6.6-16 7.1-22.6 1.3s-7.1-16-1.3-22.6c5.1-5.7 8.1-13.1 8.1-21.3s-3.1-15.7-8.1-21.3c-5.9-6.6-5.3-16.7 1.3-22.6z" }, "regular": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M64 464H320c8.8 0 16-7.2 16-16V160H256c-17.7 0-32-14.3-32-32V48H64c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16zM0 64C0 28.7 28.7 0 64 0H229.5c17 0 33.3 6.7 45.3 18.7l90.5 90.5c12 12 18.7 28.3 18.7 45.3V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V64zM192 272V400c0 6.5-3.9 12.3-9.9 14.8s-12.9 1.1-17.4-3.5L129.4 376H112c-8.8 0-16-7.2-16-16V312c0-8.8 7.2-16 16-16h17.4l35.3-35.3c4.6-4.6 11.5-5.9 17.4-3.5s9.9 8.3 9.9 14.8zm85.8-4c11.6 20 18.2 43.3 18.2 68s-6.6 48-18.2 68c-6.6 11.5-21.3 15.4-32.8 8.8s-15.4-21.3-8.8-32.8c7.5-12.9 11.8-27.9 11.8-44s-4.3-31.1-11.8-44c-6.6-11.5-2.7-26.2 8.8-32.8s26.2-2.7 32.8 8.8z" } }, "free": ["regular", "solid"] }, "file-circle-check": { "changes": ["6.0.0", "6.1.0", "6.1.2", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["document", "file", "not affected", "ok", "okay", "paper"] }, "styles": ["solid"], "unicode": "e5a0", "label": "File Circle Check", "voted": false, "svg": { "solid": { "last_modified": 1684767390, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M0 64C0 28.7 28.7 0 64 0H224V128c0 17.7 14.3 32 32 32H384v38.6C310.1 219.5 256 287.4 256 368c0 59.1 29.1 111.3 73.7 143.3c-3.2 .5-6.4 .7-9.7 .7H64c-35.3 0-64-28.7-64-64V64zm384 64H256V0L384 128zM288 368a144 144 0 1 1 288 0 144 144 0 1 1 -288 0zm211.3-43.3c-6.2-6.2-16.4-6.2-22.6 0L416 385.4l-28.7-28.7c-6.2-6.2-16.4-6.2-22.6 0s-6.2 16.4 0 22.6l40 40c6.2 6.2 16.4 6.2 22.6 0l72-72c6.2-6.2 6.2-16.4 0-22.6z" } }, "free": ["solid"] }, "file-circle-exclamation": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["document", "file", "paper"] }, "styles": ["solid"], "unicode": "e4eb", "label": "File Circle Exclamation", "voted": false, "svg": { "solid": { "last_modified": 1684767393, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M0 64C0 28.7 28.7 0 64 0H224V128c0 17.7 14.3 32 32 32H384v38.6C310.1 219.5 256 287.4 256 368c0 59.1 29.1 111.3 73.7 143.3c-3.2 .5-6.4 .7-9.7 .7H64c-35.3 0-64-28.7-64-64V64zm384 64H256V0L384 128zm48 96a144 144 0 1 1 0 288 144 144 0 1 1 0-288zm0 240a24 24 0 1 0 0-48 24 24 0 1 0 0 48zm0-192c-8.8 0-16 7.2-16 16v80c0 8.8 7.2 16 16 16s16-7.2 16-16V288c0-8.8-7.2-16-16-16z" } }, "free": ["solid"] }, "file-circle-minus": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["document", "file", "paper"] }, "styles": ["solid"], "unicode": "e4ed", "label": "File Circle Minus", "voted": false, "svg": { "solid": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M0 64C0 28.7 28.7 0 64 0H224V128c0 17.7 14.3 32 32 32H384v38.6C310.1 219.5 256 287.4 256 368c0 59.1 29.1 111.3 73.7 143.3c-3.2 .5-6.4 .7-9.7 .7H64c-35.3 0-64-28.7-64-64V64zm384 64H256V0L384 128zM288 368a144 144 0 1 1 288 0 144 144 0 1 1 -288 0zm224 0c0-8.8-7.2-16-16-16H368c-8.8 0-16 7.2-16 16s7.2 16 16 16H496c8.8 0 16-7.2 16-16z" } }, "free": ["solid"] }, "file-circle-plus": { "aliases": { "unicodes": { "composite": ["e4ee"] } }, "changes": ["6.0.0", "6.1.0", "6.1.2", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["add", "document", "file", "new", "page", "paper", "pdf"] }, "styles": ["solid"], "unicode": "e494", "label": "File Circle Plus", "voted": false, "svg": { "solid": { "last_modified": 1684767389, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M0 64C0 28.7 28.7 0 64 0H224V128c0 17.7 14.3 32 32 32H384v38.6C310.1 219.5 256 287.4 256 368c0 59.1 29.1 111.3 73.7 143.3c-3.2 .5-6.4 .7-9.7 .7H64c-35.3 0-64-28.7-64-64V64zm384 64H256V0L384 128zm48 96a144 144 0 1 1 0 288 144 144 0 1 1 0-288zm16 80c0-8.8-7.2-16-16-16s-16 7.2-16 16v48H368c-8.8 0-16 7.2-16 16s7.2 16 16 16h48v48c0 8.8 7.2 16 16 16s16-7.2 16-16V384h48c8.8 0 16-7.2 16-16s-7.2-16-16-16H448V304z" } }, "free": ["solid"] }, "file-circle-question": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["document", "file", "paper"] }, "styles": ["solid"], "unicode": "e4ef", "label": "File Circle Question", "voted": false, "svg": { "solid": { "last_modified": 1684767393, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M0 64C0 28.7 28.7 0 64 0H224V128c0 17.7 14.3 32 32 32H384v38.6C310.1 219.5 256 287.4 256 368c0 59.1 29.1 111.3 73.7 143.3c-3.2 .5-6.4 .7-9.7 .7H64c-35.3 0-64-28.7-64-64V64zm384 64H256V0L384 128zm48 96a144 144 0 1 1 0 288 144 144 0 1 1 0-288zm0 240a24 24 0 1 0 0-48 24 24 0 1 0 0 48zM368 321.6V328c0 8.8 7.2 16 16 16s16-7.2 16-16v-6.4c0-5.3 4.3-9.6 9.6-9.6h40.5c7.7 0 13.9 6.2 13.9 13.9c0 5.2-2.9 9.9-7.4 12.3l-32 16.8c-5.3 2.8-8.6 8.2-8.6 14.2V384c0 8.8 7.2 16 16 16s16-7.2 16-16v-5.1l23.5-12.3c15.1-7.9 24.5-23.6 24.5-40.6c0-25.4-20.6-45.9-45.9-45.9H409.6c-23 0-41.6 18.6-41.6 41.6z" } }, "free": ["solid"] }, "file-circle-xmark": { "changes": ["6.1.0", "6.1.2", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["document", "file", "paper"] }, "styles": ["solid"], "unicode": "e5a1", "label": "File Circle Xmark", "voted": false, "svg": { "solid": { "last_modified": 1684767390, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M0 64C0 28.7 28.7 0 64 0H224V128c0 17.7 14.3 32 32 32H384v38.6C310.1 219.5 256 287.4 256 368c0 59.1 29.1 111.3 73.7 143.3c-3.2 .5-6.4 .7-9.7 .7H64c-35.3 0-64-28.7-64-64V64zm384 64H256V0L384 128zm48 96a144 144 0 1 1 0 288 144 144 0 1 1 0-288zm59.3 107.3c6.2-6.2 6.2-16.4 0-22.6s-16.4-6.2-22.6 0L432 345.4l-36.7-36.7c-6.2-6.2-16.4-6.2-22.6 0s-6.2 16.4 0 22.6L409.4 368l-36.7 36.7c-6.2 6.2-6.2 16.4 0 22.6s16.4 6.2 22.6 0L432 390.6l36.7 36.7c6.2 6.2 16.4 6.2 22.6 0s6.2-16.4 0-22.6L454.6 368l36.7-36.7z" } }, "free": ["solid"] }, "file-code": { "aliases": { "unicodes": { "secondary": ["10f1c9"] } }, "changes": [ "4.1.0", "5.0.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["css", "development", "document", "html"] }, "styles": ["solid", "regular"], "unicode": "f1c9", "label": "File Code", "voted": false, "svg": { "solid": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M64 0C28.7 0 0 28.7 0 64V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V160H256c-17.7 0-32-14.3-32-32V0H64zM256 0V128H384L256 0zM153 289l-31 31 31 31c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0L71 337c-9.4-9.4-9.4-24.6 0-33.9l48-48c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9zM265 255l48 48c9.4 9.4 9.4 24.6 0 33.9l-48 48c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l31-31-31-31c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0z" }, "regular": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M64 464c-8.8 0-16-7.2-16-16V64c0-8.8 7.2-16 16-16H224v80c0 17.7 14.3 32 32 32h80V448c0 8.8-7.2 16-16 16H64zM64 0C28.7 0 0 28.7 0 64V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V154.5c0-17-6.7-33.3-18.7-45.3L274.7 18.7C262.7 6.7 246.5 0 229.5 0H64zm97 289c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0L79 303c-9.4 9.4-9.4 24.6 0 33.9l48 48c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9l-31-31 31-31zM257 255c-9.4-9.4-24.6-9.4-33.9 0s-9.4 24.6 0 33.9l31 31-31 31c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l48-48c9.4-9.4 9.4-24.6 0-33.9l-48-48z" } }, "free": ["regular", "solid"] }, "file-contract": { "aliases": { "unicodes": { "secondary": ["10f56c"] } }, "changes": ["5.1.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["agreement", "binding", "document", "legal", "signature"] }, "styles": ["solid"], "unicode": "f56c", "label": "File Contract", "voted": false, "svg": { "solid": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M64 0C28.7 0 0 28.7 0 64V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V160H256c-17.7 0-32-14.3-32-32V0H64zM256 0V128H384L256 0zM80 64h64c8.8 0 16 7.2 16 16s-7.2 16-16 16H80c-8.8 0-16-7.2-16-16s7.2-16 16-16zm0 64h64c8.8 0 16 7.2 16 16s-7.2 16-16 16H80c-8.8 0-16-7.2-16-16s7.2-16 16-16zm54.2 253.8c-6.1 20.3-24.8 34.2-46 34.2H80c-8.8 0-16-7.2-16-16s7.2-16 16-16h8.2c7.1 0 13.3-4.6 15.3-11.4l14.9-49.5c3.4-11.3 13.8-19.1 25.6-19.1s22.2 7.7 25.6 19.1l11.6 38.6c7.4-6.2 16.8-9.7 26.8-9.7c15.9 0 30.4 9 37.5 23.2l4.4 8.8H304c8.8 0 16 7.2 16 16s-7.2 16-16 16H240c-6.1 0-11.6-3.4-14.3-8.8l-8.8-17.7c-1.7-3.4-5.1-5.5-8.8-5.5s-7.2 2.1-8.8 5.5l-8.8 17.7c-2.9 5.9-9.2 9.4-15.7 8.8s-12.1-5.1-13.9-11.3L144 349l-9.8 32.8z" } }, "free": ["solid"] }, "file-csv": { "aliases": { "unicodes": { "secondary": ["10f6dd"] } }, "changes": [ "5.4.0", "5.10.2", "6.0.0-beta1", "6.1.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["document", "excel", "numbers", "spreadsheets", "table"] }, "styles": ["solid"], "unicode": "f6dd", "label": "File Csv", "voted": false, "svg": { "solid": { "last_modified": 1684767393, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 64C0 28.7 28.7 0 64 0H224V128c0 17.7 14.3 32 32 32H384V304H176c-35.3 0-64 28.7-64 64V512H64c-35.3 0-64-28.7-64-64V64zm384 64H256V0L384 128zM200 352h16c22.1 0 40 17.9 40 40v8c0 8.8-7.2 16-16 16s-16-7.2-16-16v-8c0-4.4-3.6-8-8-8H200c-4.4 0-8 3.6-8 8v80c0 4.4 3.6 8 8 8h16c4.4 0 8-3.6 8-8v-8c0-8.8 7.2-16 16-16s16 7.2 16 16v8c0 22.1-17.9 40-40 40H200c-22.1 0-40-17.9-40-40V392c0-22.1 17.9-40 40-40zm133.1 0H368c8.8 0 16 7.2 16 16s-7.2 16-16 16H333.1c-7.2 0-13.1 5.9-13.1 13.1c0 5.2 3 9.9 7.8 12l37.4 16.6c16.3 7.2 26.8 23.4 26.8 41.2c0 24.9-20.2 45.1-45.1 45.1H304c-8.8 0-16-7.2-16-16s7.2-16 16-16h42.9c7.2 0 13.1-5.9 13.1-13.1c0-5.2-3-9.9-7.8-12l-37.4-16.6c-16.3-7.2-26.8-23.4-26.8-41.2c0-24.9 20.2-45.1 45.1-45.1zm98.9 0c8.8 0 16 7.2 16 16v31.6c0 23 5.5 45.6 16 66c10.5-20.3 16-42.9 16-66V368c0-8.8 7.2-16 16-16s16 7.2 16 16v31.6c0 34.7-10.3 68.7-29.6 97.6l-5.1 7.7c-3 4.5-8 7.1-13.3 7.1s-10.3-2.7-13.3-7.1l-5.1-7.7c-19.3-28.9-29.6-62.9-29.6-97.6V368c0-8.8 7.2-16 16-16z" } }, "free": ["solid"] }, "file-excel": { "aliases": { "unicodes": { "secondary": ["10f1c3"] } }, "changes": [ "4.1.0", "5.0.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["csv", "document", "numbers", "spreadsheets", "table"] }, "styles": ["solid", "regular"], "unicode": "f1c3", "label": "File Excel", "voted": false, "svg": { "solid": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M64 0C28.7 0 0 28.7 0 64V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V160H256c-17.7 0-32-14.3-32-32V0H64zM256 0V128H384L256 0zM155.7 250.2L192 302.1l36.3-51.9c7.6-10.9 22.6-13.5 33.4-5.9s13.5 22.6 5.9 33.4L221.3 344l46.4 66.2c7.6 10.9 5 25.8-5.9 33.4s-25.8 5-33.4-5.9L192 385.8l-36.3 51.9c-7.6 10.9-22.6 13.5-33.4 5.9s-13.5-22.6-5.9-33.4L162.7 344l-46.4-66.2c-7.6-10.9-5-25.8 5.9-33.4s25.8-5 33.4 5.9z" }, "regular": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M48 448V64c0-8.8 7.2-16 16-16H224v80c0 17.7 14.3 32 32 32h80V448c0 8.8-7.2 16-16 16H64c-8.8 0-16-7.2-16-16zM64 0C28.7 0 0 28.7 0 64V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V154.5c0-17-6.7-33.3-18.7-45.3L274.7 18.7C262.7 6.7 246.5 0 229.5 0H64zm90.9 233.3c-8.1-10.5-23.2-12.3-33.7-4.2s-12.3 23.2-4.2 33.7L161.6 320l-44.5 57.3c-8.1 10.5-6.3 25.5 4.2 33.7s25.5 6.3 33.7-4.2L192 359.1l37.1 47.6c8.1 10.5 23.2 12.3 33.7 4.2s12.3-23.2 4.2-33.7L222.4 320l44.5-57.3c8.1-10.5 6.3-25.5-4.2-33.7s-25.5-6.3-33.7 4.2L192 280.9l-37.1-47.6z" } }, "free": ["regular", "solid"] }, "file-export": { "aliases": { "names": ["arrow-right-from-file"], "unicodes": { "secondary": ["10f56e"] } }, "changes": [ "5.1.0", "5.7.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["download", "save"] }, "styles": ["solid"], "unicode": "f56e", "label": "File Export", "voted": true, "svg": { "solid": { "last_modified": 1684767389, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M0 64C0 28.7 28.7 0 64 0H224V128c0 17.7 14.3 32 32 32H384V288H216c-13.3 0-24 10.7-24 24s10.7 24 24 24H384V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V64zM384 336V288H494.1l-39-39c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l80 80c9.4 9.4 9.4 24.6 0 33.9l-80 80c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l39-39H384zm0-208H256V0L384 128z" } }, "free": ["solid"] }, "file-image": { "aliases": { "unicodes": { "composite": ["1f5bb"], "secondary": ["10f1c5"] } }, "changes": [ "4.1.0", "5.0.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Document with Picture", "document", "image", "jpg", "photo", "png" ] }, "styles": ["solid", "regular"], "unicode": "f1c5", "label": "File Image", "voted": false, "svg": { "solid": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M64 0C28.7 0 0 28.7 0 64V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V160H256c-17.7 0-32-14.3-32-32V0H64zM256 0V128H384L256 0zM64 256a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm152 32c5.3 0 10.2 2.6 13.2 6.9l88 128c3.4 4.9 3.7 11.3 1 16.5s-8.2 8.6-14.2 8.6H216 176 128 80c-5.8 0-11.1-3.1-13.9-8.1s-2.8-11.2 .2-16.1l48-80c2.9-4.8 8.1-7.8 13.7-7.8s10.8 2.9 13.7 7.8l12.8 21.4 48.3-70.2c3-4.3 7.9-6.9 13.2-6.9z" }, "regular": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M64 464c-8.8 0-16-7.2-16-16V64c0-8.8 7.2-16 16-16H224v80c0 17.7 14.3 32 32 32h80V448c0 8.8-7.2 16-16 16H64zM64 0C28.7 0 0 28.7 0 64V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V154.5c0-17-6.7-33.3-18.7-45.3L274.7 18.7C262.7 6.7 246.5 0 229.5 0H64zm96 256a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zm69.2 46.9c-3-4.3-7.9-6.9-13.2-6.9s-10.2 2.6-13.2 6.9l-41.3 59.7-11.9-19.1c-2.9-4.7-8.1-7.5-13.6-7.5s-10.6 2.8-13.6 7.5l-40 64c-3.1 4.9-3.2 11.1-.4 16.2s8.2 8.2 14 8.2h48 32 40 72c6 0 11.4-3.3 14.2-8.6s2.4-11.6-1-16.5l-72-104z" } }, "free": ["regular", "solid"] }, "file-import": { "aliases": { "names": ["arrow-right-to-file"], "unicodes": { "secondary": ["10f56f"] } }, "changes": [ "5.1.0", "5.7.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["copy", "document", "send", "upload"] }, "styles": ["solid"], "unicode": "f56f", "label": "File Import", "voted": true, "svg": { "solid": { "last_modified": 1684767392, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M128 64c0-35.3 28.7-64 64-64H352V128c0 17.7 14.3 32 32 32H512V448c0 35.3-28.7 64-64 64H192c-35.3 0-64-28.7-64-64V336H302.1l-39 39c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l80-80c9.4-9.4 9.4-24.6 0-33.9l-80-80c-9.4-9.4-24.6-9.4-33.9 0s-9.4 24.6 0 33.9l39 39H128V64zm0 224v48H24c-13.3 0-24-10.7-24-24s10.7-24 24-24H128zM512 128H384V0L512 128z" } }, "free": ["solid"] }, "file-invoice": { "aliases": { "unicodes": { "secondary": ["10f570"] } }, "changes": ["5.1.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["account", "bill", "charge", "document", "payment", "receipt"] }, "styles": ["solid"], "unicode": "f570", "label": "File Invoice", "voted": true, "svg": { "solid": { "last_modified": 1684767389, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M64 0C28.7 0 0 28.7 0 64V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V160H256c-17.7 0-32-14.3-32-32V0H64zM256 0V128H384L256 0zM80 64h64c8.8 0 16 7.2 16 16s-7.2 16-16 16H80c-8.8 0-16-7.2-16-16s7.2-16 16-16zm0 64h64c8.8 0 16 7.2 16 16s-7.2 16-16 16H80c-8.8 0-16-7.2-16-16s7.2-16 16-16zm16 96H288c17.7 0 32 14.3 32 32v64c0 17.7-14.3 32-32 32H96c-17.7 0-32-14.3-32-32V256c0-17.7 14.3-32 32-32zm0 32v64H288V256H96zM240 416h64c8.8 0 16 7.2 16 16s-7.2 16-16 16H240c-8.8 0-16-7.2-16-16s7.2-16 16-16z" } }, "free": ["solid"] }, "file-invoice-dollar": { "aliases": { "unicodes": { "secondary": ["10f571"] } }, "changes": ["5.1.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "$", "account", "bill", "charge", "document", "dollar-sign", "money", "payment", "receipt", "usd" ] }, "styles": ["solid"], "unicode": "f571", "label": "File Invoice Dollar", "voted": true, "svg": { "solid": { "last_modified": 1684767392, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M64 0C28.7 0 0 28.7 0 64V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V160H256c-17.7 0-32-14.3-32-32V0H64zM256 0V128H384L256 0zM64 80c0-8.8 7.2-16 16-16h64c8.8 0 16 7.2 16 16s-7.2 16-16 16H80c-8.8 0-16-7.2-16-16zm0 64c0-8.8 7.2-16 16-16h64c8.8 0 16 7.2 16 16s-7.2 16-16 16H80c-8.8 0-16-7.2-16-16zm128 72c8.8 0 16 7.2 16 16v17.3c8.5 1.2 16.7 3.1 24.1 5.1c8.5 2.3 13.6 11 11.3 19.6s-11 13.6-19.6 11.3c-11.1-3-22-5.2-32.1-5.3c-8.4-.1-17.4 1.8-23.6 5.5c-5.7 3.4-8.1 7.3-8.1 12.8c0 3.7 1.3 6.5 7.3 10.1c6.9 4.1 16.6 7.1 29.2 10.9l.5 .1 0 0 0 0c11.3 3.4 25.3 7.6 36.3 14.6c12.1 7.6 22.4 19.7 22.7 38.2c.3 19.3-9.6 33.3-22.9 41.6c-7.7 4.8-16.4 7.6-25.1 9.1V440c0 8.8-7.2 16-16 16s-16-7.2-16-16V422.2c-11.2-2.1-21.7-5.7-30.9-8.9l0 0c-2.1-.7-4.2-1.4-6.2-2.1c-8.4-2.8-12.9-11.9-10.1-20.2s11.9-12.9 20.2-10.1c2.5 .8 4.8 1.6 7.1 2.4l0 0 0 0 0 0c13.6 4.6 24.6 8.4 36.3 8.7c9.1 .3 17.9-1.7 23.7-5.3c5.1-3.2 7.9-7.3 7.8-14c-.1-4.6-1.8-7.8-7.7-11.6c-6.8-4.3-16.5-7.4-29-11.2l-1.6-.5 0 0c-11-3.3-24.3-7.3-34.8-13.7c-12-7.2-22.6-18.9-22.7-37.3c-.1-19.4 10.8-32.8 23.8-40.5c7.5-4.4 15.8-7.2 24.1-8.7V232c0-8.8 7.2-16 16-16z" } }, "free": ["solid"] }, "file-lines": { "aliases": { "names": ["file-alt", "file-text"], "unicodes": { "composite": ["1f5b9", "1f5ce", "f0f6"], "secondary": ["10f15c"] } }, "changes": [ "3.2.0", "5.0.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Document", "Document with Text", "document", "file-text", "invoice", "new", "page", "pdf" ] }, "styles": ["solid", "regular"], "unicode": "f15c", "label": "File Lines", "voted": false, "svg": { "solid": { "last_modified": 1684767393, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M64 0C28.7 0 0 28.7 0 64V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V160H256c-17.7 0-32-14.3-32-32V0H64zM256 0V128H384L256 0zM112 256H272c8.8 0 16 7.2 16 16s-7.2 16-16 16H112c-8.8 0-16-7.2-16-16s7.2-16 16-16zm0 64H272c8.8 0 16 7.2 16 16s-7.2 16-16 16H112c-8.8 0-16-7.2-16-16s7.2-16 16-16zm0 64H272c8.8 0 16 7.2 16 16s-7.2 16-16 16H112c-8.8 0-16-7.2-16-16s7.2-16 16-16z" }, "regular": { "last_modified": 1684767393, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M64 464c-8.8 0-16-7.2-16-16V64c0-8.8 7.2-16 16-16H224v80c0 17.7 14.3 32 32 32h80V448c0 8.8-7.2 16-16 16H64zM64 0C28.7 0 0 28.7 0 64V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V154.5c0-17-6.7-33.3-18.7-45.3L274.7 18.7C262.7 6.7 246.5 0 229.5 0H64zm56 256c-13.3 0-24 10.7-24 24s10.7 24 24 24H264c13.3 0 24-10.7 24-24s-10.7-24-24-24H120zm0 96c-13.3 0-24 10.7-24 24s10.7 24 24 24H264c13.3 0 24-10.7 24-24s-10.7-24-24-24H120z" } }, "free": ["regular", "solid"] }, "file-medical": { "aliases": { "unicodes": { "secondary": ["10f477"] } }, "changes": ["5.0.7", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["document", "health", "history", "prescription", "record"] }, "styles": ["solid"], "unicode": "f477", "label": "File Medical", "voted": false, "svg": { "solid": { "last_modified": 1684767390, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M64 0C28.7 0 0 28.7 0 64V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V160H256c-17.7 0-32-14.3-32-32V0H64zM256 0V128H384L256 0zM160 240c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v48h48c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H224v48c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16V352H112c-8.8 0-16-7.2-16-16V304c0-8.8 7.2-16 16-16h48V240z" } }, "free": ["solid"] }, "file-pdf": { "aliases": { "unicodes": { "secondary": ["10f1c1"] } }, "changes": [ "4.1.0", "5.0.0", "5.10.2", "6.0.0-beta1", "6.1.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["acrobat", "document", "preview", "save"] }, "styles": ["solid", "regular"], "unicode": "f1c1", "label": "File Pdf", "voted": false, "svg": { "solid": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 64C0 28.7 28.7 0 64 0H224V128c0 17.7 14.3 32 32 32H384V304H176c-35.3 0-64 28.7-64 64V512H64c-35.3 0-64-28.7-64-64V64zm384 64H256V0L384 128zM176 352h32c30.9 0 56 25.1 56 56s-25.1 56-56 56H192v32c0 8.8-7.2 16-16 16s-16-7.2-16-16V448 368c0-8.8 7.2-16 16-16zm32 80c13.3 0 24-10.7 24-24s-10.7-24-24-24H192v48h16zm96-80h32c26.5 0 48 21.5 48 48v64c0 26.5-21.5 48-48 48H304c-8.8 0-16-7.2-16-16V368c0-8.8 7.2-16 16-16zm32 128c8.8 0 16-7.2 16-16V400c0-8.8-7.2-16-16-16H320v96h16zm80-112c0-8.8 7.2-16 16-16h48c8.8 0 16 7.2 16 16s-7.2 16-16 16H448v32h32c8.8 0 16 7.2 16 16s-7.2 16-16 16H448v48c0 8.8-7.2 16-16 16s-16-7.2-16-16V432 368z" }, "regular": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M64 464H96v48H64c-35.3 0-64-28.7-64-64V64C0 28.7 28.7 0 64 0H229.5c17 0 33.3 6.7 45.3 18.7l90.5 90.5c12 12 18.7 28.3 18.7 45.3V288H336V160H256c-17.7 0-32-14.3-32-32V48H64c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16zM176 352h32c30.9 0 56 25.1 56 56s-25.1 56-56 56H192v32c0 8.8-7.2 16-16 16s-16-7.2-16-16V448 368c0-8.8 7.2-16 16-16zm32 80c13.3 0 24-10.7 24-24s-10.7-24-24-24H192v48h16zm96-80h32c26.5 0 48 21.5 48 48v64c0 26.5-21.5 48-48 48H304c-8.8 0-16-7.2-16-16V368c0-8.8 7.2-16 16-16zm32 128c8.8 0 16-7.2 16-16V400c0-8.8-7.2-16-16-16H320v96h16zm80-112c0-8.8 7.2-16 16-16h48c8.8 0 16 7.2 16 16s-7.2 16-16 16H448v32h32c8.8 0 16 7.2 16 16s-7.2 16-16 16H448v48c0 8.8-7.2 16-16 16s-16-7.2-16-16V432 368z" } }, "free": ["regular", "solid"] }, "file-pen": { "aliases": { "names": ["file-edit"], "unicodes": { "composite": ["1f4dd"], "secondary": ["10f31c"] } }, "changes": [ "5.0.0", "5.10.2", "6.0.0-beta1", "6.1.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["edit", "memo", "pen", "pencil", "update", "write"] }, "styles": ["solid"], "unicode": "f31c", "label": "File Pen", "voted": false, "svg": { "solid": { "last_modified": 1684767390, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M0 64C0 28.7 28.7 0 64 0H224V128c0 17.7 14.3 32 32 32H384V285.7l-86.8 86.8c-10.3 10.3-17.5 23.1-21 37.2l-18.7 74.9c-2.3 9.2-1.8 18.8 1.3 27.5H64c-35.3 0-64-28.7-64-64V64zm384 64H256V0L384 128zM549.8 235.7l14.4 14.4c15.6 15.6 15.6 40.9 0 56.6l-29.4 29.4-71-71 29.4-29.4c15.6-15.6 40.9-15.6 56.6 0zM311.9 417L441.1 287.8l71 71L382.9 487.9c-4.1 4.1-9.2 7-14.9 8.4l-60.1 15c-5.5 1.4-11.2-.2-15.2-4.2s-5.6-9.7-4.2-15.2l15-60.1c1.4-5.6 4.3-10.8 8.4-14.9z" } }, "free": ["solid"] }, "file-powerpoint": { "aliases": { "unicodes": { "secondary": ["10f1c4"] } }, "changes": [ "4.1.0", "5.0.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["display", "document", "keynote", "presentation"] }, "styles": ["solid", "regular"], "unicode": "f1c4", "label": "File Powerpoint", "voted": false, "svg": { "solid": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M64 0C28.7 0 0 28.7 0 64V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V160H256c-17.7 0-32-14.3-32-32V0H64zM256 0V128H384L256 0zM136 240h68c42 0 76 34 76 76s-34 76-76 76H160v32c0 13.3-10.7 24-24 24s-24-10.7-24-24V368 264c0-13.3 10.7-24 24-24zm68 104c15.5 0 28-12.5 28-28s-12.5-28-28-28H160v56h44z" }, "regular": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M64 464c-8.8 0-16-7.2-16-16V64c0-8.8 7.2-16 16-16H224v80c0 17.7 14.3 32 32 32h80V448c0 8.8-7.2 16-16 16H64zM64 0C28.7 0 0 28.7 0 64V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V154.5c0-17-6.7-33.3-18.7-45.3L274.7 18.7C262.7 6.7 246.5 0 229.5 0H64zm72 208c-13.3 0-24 10.7-24 24V336v56c0 13.3 10.7 24 24 24s24-10.7 24-24V360h44c42 0 76-34 76-76s-34-76-76-76H136zm68 104H160V256h44c15.5 0 28 12.5 28 28s-12.5 28-28 28z" } }, "free": ["regular", "solid"] }, "file-prescription": { "aliases": { "unicodes": { "secondary": ["10f572"] } }, "changes": ["5.1.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["document", "drugs", "medical", "medicine", "rx"] }, "styles": ["solid"], "unicode": "f572", "label": "File Prescription", "voted": false, "svg": { "solid": { "last_modified": 1684767392, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M64 0C28.7 0 0 28.7 0 64V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V160H256c-17.7 0-32-14.3-32-32V0H64zM256 0V128H384L256 0zM104 196h72c33.1 0 60 26.9 60 60c0 25.5-15.9 47.2-38.3 55.9l43 40.3 33.8-31c8.1-7.5 20.8-6.9 28.3 1.2s6.9 20.8-1.2 28.3L270 379.7l31.7 29.7c8.1 7.6 8.5 20.2 .9 28.3s-20.2 8.5-28.3 .9l-33.9-31.8-34.9 32c-8.1 7.5-20.8 6.9-28.3-1.2s-6.9-20.8 1.2-28.3l32.6-29.9-64.8-60.8c-.9-.8-1.6-1.7-2.3-2.6H124v44c0 11-9 20-20 20s-20-9-20-20V296 216c0-11 9-20 20-20zm72 80c11 0 20-9 20-20s-9-20-20-20H124v40h52z" } }, "free": ["solid"] }, "file-shield": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "antivirus", "data", "document", "protect", "safe", "safety", "secure" ] }, "styles": ["solid"], "unicode": "e4f0", "label": "File Shield", "voted": false, "svg": { "solid": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M0 64C0 28.7 28.7 0 64 0H224V128c0 17.7 14.3 32 32 32H384v47l-92.8 37.1c-21.3 8.5-35.2 29.1-35.2 52c0 56.6 18.9 148 94.2 208.3c-9 4.8-19.3 7.6-30.2 7.6H64c-35.3 0-64-28.7-64-64V64zm384 64H256V0L384 128zm39.1 97.7c5.7-2.3 12.1-2.3 17.8 0l120 48C570 277.4 576 286.2 576 296c0 63.3-25.9 168.8-134.8 214.2c-5.9 2.5-12.6 2.5-18.5 0C313.9 464.8 288 359.3 288 296c0-9.8 6-18.6 15.1-22.3l120-48zM527.4 312L432 273.8V461.7c68.2-33 91.5-99 95.4-149.7z" } }, "free": ["solid"] }, "file-signature": { "aliases": { "unicodes": { "secondary": ["10f573"] } }, "changes": ["5.1.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["John Hancock", "contract", "document", "name"] }, "styles": ["solid"], "unicode": "f573", "label": "File Signature", "voted": true, "svg": { "solid": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M64 0C28.7 0 0 28.7 0 64V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V428.7c-2.7 1.1-5.4 2-8.2 2.7l-60.1 15c-3 .7-6 1.2-9 1.4c-.9 .1-1.8 .2-2.7 .2H240c-6.1 0-11.6-3.4-14.3-8.8l-8.8-17.7c-1.7-3.4-5.1-5.5-8.8-5.5s-7.2 2.1-8.8 5.5l-8.8 17.7c-2.9 5.9-9.2 9.4-15.7 8.8s-12.1-5.1-13.9-11.3L144 381l-9.8 32.8c-6.1 20.3-24.8 34.2-46 34.2H80c-8.8 0-16-7.2-16-16s7.2-16 16-16h8.2c7.1 0 13.3-4.6 15.3-11.4l14.9-49.5c3.4-11.3 13.8-19.1 25.6-19.1s22.2 7.8 25.6 19.1l11.6 38.6c7.4-6.2 16.8-9.7 26.8-9.7c15.9 0 30.4 9 37.5 23.2l4.4 8.8h8.9c-3.1-8.8-3.7-18.4-1.4-27.8l15-60.1c2.8-11.3 8.6-21.5 16.8-29.7L384 203.6V160H256c-17.7 0-32-14.3-32-32V0H64zM256 0V128H384L256 0zM549.8 139.7c-15.6-15.6-40.9-15.6-56.6 0l-29.4 29.4 71 71 29.4-29.4c15.6-15.6 15.6-40.9 0-56.6l-14.4-14.4zM311.9 321c-4.1 4.1-7 9.2-8.4 14.9l-15 60.1c-1.4 5.5 .2 11.2 4.2 15.2s9.7 5.6 15.2 4.2l60.1-15c5.6-1.4 10.8-4.3 14.9-8.4L512.1 262.7l-71-71L311.9 321z" } }, "free": ["solid"] }, "file-video": { "aliases": { "unicodes": { "secondary": ["10f1c8"] } }, "changes": [ "4.1.0", "5.0.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["document", "m4v", "movie", "mp4", "play"] }, "styles": ["solid", "regular"], "unicode": "f1c8", "label": "File Video", "voted": false, "svg": { "solid": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M64 0C28.7 0 0 28.7 0 64V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V160H256c-17.7 0-32-14.3-32-32V0H64zM256 0V128H384L256 0zM64 288c0-17.7 14.3-32 32-32h96c17.7 0 32 14.3 32 32v96c0 17.7-14.3 32-32 32H96c-17.7 0-32-14.3-32-32V288zM300.9 397.9L256 368V304l44.9-29.9c2-1.3 4.4-2.1 6.8-2.1c6.8 0 12.3 5.5 12.3 12.3V387.7c0 6.8-5.5 12.3-12.3 12.3c-2.4 0-4.8-.7-6.8-2.1z" }, "regular": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M320 464c8.8 0 16-7.2 16-16V160H256c-17.7 0-32-14.3-32-32V48H64c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16H320zM0 64C0 28.7 28.7 0 64 0H229.5c17 0 33.3 6.7 45.3 18.7l90.5 90.5c12 12 18.7 28.3 18.7 45.3V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V64zM80 288c0-17.7 14.3-32 32-32h96c17.7 0 32 14.3 32 32v16l44.9-29.9c2-1.3 4.4-2.1 6.8-2.1c6.8 0 12.3 5.5 12.3 12.3V387.7c0 6.8-5.5 12.3-12.3 12.3c-2.4 0-4.8-.7-6.8-2.1L240 368v16c0 17.7-14.3 32-32 32H112c-17.7 0-32-14.3-32-32V288z" } }, "free": ["regular", "solid"] }, "file-waveform": { "aliases": { "names": ["file-medical-alt"], "unicodes": { "secondary": ["10f478"] } }, "changes": ["5.0.7", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["document", "health", "history", "prescription", "record"] }, "styles": ["solid"], "unicode": "f478", "label": "File Waveform", "voted": false, "svg": { "solid": { "last_modified": 1684767392, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M96 0C60.7 0 32 28.7 32 64V288H144c6.1 0 11.6 3.4 14.3 8.8L176 332.2l49.7-99.4c2.7-5.4 8.3-8.8 14.3-8.8s11.6 3.4 14.3 8.8L281.9 288H352c8.8 0 16 7.2 16 16s-7.2 16-16 16H272c-6.1 0-11.6-3.4-14.3-8.8L240 275.8l-49.7 99.4c-2.7 5.4-8.3 8.8-14.3 8.8s-11.6-3.4-14.3-8.8L134.1 320H32V448c0 35.3 28.7 64 64 64H352c35.3 0 64-28.7 64-64V160H288c-17.7 0-32-14.3-32-32V0H96zM288 0V128H416L288 0z" } }, "free": ["solid"] }, "file-word": { "aliases": { "unicodes": { "secondary": ["10f1c2"] } }, "changes": [ "4.1.0", "5.0.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["document", "edit", "page", "text", "writing"] }, "styles": ["solid", "regular"], "unicode": "f1c2", "label": "File Word", "voted": false, "svg": { "solid": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M64 0C28.7 0 0 28.7 0 64V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V160H256c-17.7 0-32-14.3-32-32V0H64zM256 0V128H384L256 0zM111 257.1l26.8 89.2 31.6-90.3c3.4-9.6 12.5-16.1 22.7-16.1s19.3 6.4 22.7 16.1l31.6 90.3L273 257.1c3.8-12.7 17.2-19.9 29.9-16.1s19.9 17.2 16.1 29.9l-48 160c-3 10-12 16.9-22.4 17.1s-19.8-6.2-23.2-16.1L192 336.6l-33.3 95.3c-3.4 9.8-12.8 16.3-23.2 16.1s-19.5-7.1-22.4-17.1l-48-160c-3.8-12.7 3.4-26.1 16.1-29.9s26.1 3.4 29.9 16.1z" }, "regular": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M48 448V64c0-8.8 7.2-16 16-16H224v80c0 17.7 14.3 32 32 32h80V448c0 8.8-7.2 16-16 16H64c-8.8 0-16-7.2-16-16zM64 0C28.7 0 0 28.7 0 64V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V154.5c0-17-6.7-33.3-18.7-45.3L274.7 18.7C262.7 6.7 246.5 0 229.5 0H64zm55 241.1c-3.8-12.7-17.2-19.9-29.9-16.1s-19.9 17.2-16.1 29.9l48 160c3 10.2 12.4 17.1 23 17.1s19.9-7 23-17.1l25-83.4 25 83.4c3 10.2 12.4 17.1 23 17.1s19.9-7 23-17.1l48-160c3.8-12.7-3.4-26.1-16.1-29.9s-26.1 3.4-29.9 16.1l-25 83.4-25-83.4c-3-10.2-12.4-17.1-23-17.1s-19.9 7-23 17.1l-25 83.4-25-83.4z" } }, "free": ["regular", "solid"] }, "file-zipper": { "aliases": { "names": ["file-archive"], "unicodes": { "secondary": ["10f1c6"] } }, "changes": [ "4.1.0", "5.0.0", "5.7.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [".zip", "bundle", "compress", "compression", "download", "zip"] }, "styles": ["solid", "regular"], "unicode": "f1c6", "label": "File Zipper", "voted": false, "svg": { "solid": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M64 0C28.7 0 0 28.7 0 64V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V160H256c-17.7 0-32-14.3-32-32V0H64zM256 0V128H384L256 0zM96 48c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16s-7.2 16-16 16H112c-8.8 0-16-7.2-16-16zm0 64c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16s-7.2 16-16 16H112c-8.8 0-16-7.2-16-16zm0 64c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16s-7.2 16-16 16H112c-8.8 0-16-7.2-16-16zm-6.3 71.8c3.7-14 16.4-23.8 30.9-23.8h14.8c14.5 0 27.2 9.7 30.9 23.8l23.5 88.2c1.4 5.4 2.1 10.9 2.1 16.4c0 35.2-28.8 63.7-64 63.7s-64-28.5-64-63.7c0-5.5 .7-11.1 2.1-16.4l23.5-88.2zM112 336c-8.8 0-16 7.2-16 16s7.2 16 16 16h32c8.8 0 16-7.2 16-16s-7.2-16-16-16H112z" }, "regular": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M64 464c-8.8 0-16-7.2-16-16V64c0-8.8 7.2-16 16-16h48c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16h48v80c0 17.7 14.3 32 32 32h80V448c0 8.8-7.2 16-16 16H64zM64 0C28.7 0 0 28.7 0 64V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V154.5c0-17-6.7-33.3-18.7-45.3L274.7 18.7C262.7 6.7 246.5 0 229.5 0H64zm48 112c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16s-7.2-16-16-16H128c-8.8 0-16 7.2-16 16zm0 64c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16s-7.2-16-16-16H128c-8.8 0-16 7.2-16 16zm-6.3 71.8L82.1 335.9c-1.4 5.4-2.1 10.9-2.1 16.4c0 35.2 28.8 63.7 64 63.7s64-28.5 64-63.7c0-5.5-.7-11.1-2.1-16.4l-23.5-88.2c-3.7-14-16.4-23.8-30.9-23.8H136.6c-14.5 0-27.2 9.7-30.9 23.8zM128 336h32c8.8 0 16 7.2 16 16s-7.2 16-16 16H128c-8.8 0-16-7.2-16-16s7.2-16 16-16z" } }, "free": ["regular", "solid"] }, "fill": { "aliases": { "unicodes": { "secondary": ["10f575"] } }, "changes": ["5.1.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["bucket", "color", "paint", "paint bucket"] }, "styles": ["solid"], "unicode": "f575", "label": "Fill", "voted": false, "svg": { "solid": { "last_modified": 1684767366, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M86.6 9.4C74.1-3.1 53.9-3.1 41.4 9.4s-12.5 32.8 0 45.3L122.7 136 30.6 228.1c-37.5 37.5-37.5 98.3 0 135.8L148.1 481.4c37.5 37.5 98.3 37.5 135.8 0L474.3 290.9c28.1-28.1 28.1-73.7 0-101.8L322.9 37.7c-28.1-28.1-73.7-28.1-101.8 0L168 90.7 86.6 9.4zM168 181.3l49.4 49.4c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L213.3 136l53.1-53.1c3.1-3.1 8.2-3.1 11.3 0L429.1 234.3c3.1 3.1 3.1 8.2 0 11.3L386.7 288H67.5c1.4-5.4 4.2-10.4 8.4-14.6L168 181.3z" } }, "free": ["solid"] }, "fill-drip": { "aliases": { "unicodes": { "secondary": ["10f576"] } }, "changes": ["5.1.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["bucket", "color", "drop", "paint", "paint bucket", "spill"] }, "styles": ["solid"], "unicode": "f576", "label": "Fill Drip", "voted": false, "svg": { "solid": { "last_modified": 1684767368, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M41.4 9.4C53.9-3.1 74.1-3.1 86.6 9.4L168 90.7l53.1-53.1c28.1-28.1 73.7-28.1 101.8 0L474.3 189.1c28.1 28.1 28.1 73.7 0 101.8L283.9 481.4c-37.5 37.5-98.3 37.5-135.8 0L30.6 363.9c-37.5-37.5-37.5-98.3 0-135.8L122.7 136 41.4 54.6c-12.5-12.5-12.5-32.8 0-45.3zm176 221.3L168 181.3 75.9 273.4c-4.2 4.2-7 9.3-8.4 14.6H386.7l42.3-42.3c3.1-3.1 3.1-8.2 0-11.3L277.7 82.9c-3.1-3.1-8.2-3.1-11.3 0L213.3 136l49.4 49.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0zM512 512c-35.3 0-64-28.7-64-64c0-25.2 32.6-79.6 51.2-108.7c6-9.4 19.5-9.4 25.5 0C543.4 368.4 576 422.8 576 448c0 35.3-28.7 64-64 64z" } }, "free": ["solid"] }, "film": { "aliases": { "unicodes": { "composite": ["1f39e"], "secondary": ["10f008"] } }, "changes": ["1.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "cinema", "film", "film frames", "frames", "movie", "strip", "video" ] }, "styles": ["solid"], "unicode": "f008", "label": "Film", "voted": false, "svg": { "solid": { "last_modified": 1684767343, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 96C0 60.7 28.7 32 64 32H448c35.3 0 64 28.7 64 64V416c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V96zM48 368v32c0 8.8 7.2 16 16 16H96c8.8 0 16-7.2 16-16V368c0-8.8-7.2-16-16-16H64c-8.8 0-16 7.2-16 16zm368-16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V368c0-8.8-7.2-16-16-16H416zM48 240v32c0 8.8 7.2 16 16 16H96c8.8 0 16-7.2 16-16V240c0-8.8-7.2-16-16-16H64c-8.8 0-16 7.2-16 16zm368-16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V240c0-8.8-7.2-16-16-16H416zM48 112v32c0 8.8 7.2 16 16 16H96c8.8 0 16-7.2 16-16V112c0-8.8-7.2-16-16-16H64c-8.8 0-16 7.2-16 16zM416 96c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V112c0-8.8-7.2-16-16-16H416zM160 128v64c0 17.7 14.3 32 32 32H320c17.7 0 32-14.3 32-32V128c0-17.7-14.3-32-32-32H192c-17.7 0-32 14.3-32 32zm32 160c-17.7 0-32 14.3-32 32v64c0 17.7 14.3 32 32 32H320c17.7 0 32-14.3 32-32V320c0-17.7-14.3-32-32-32H192z" } }, "free": ["solid"] }, "filter": { "aliases": { "unicodes": { "secondary": ["10f0b0"] } }, "changes": [ "2.0.0", "5.0.0", "5.10.1", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["funnel", "options", "separate", "sort"] }, "styles": ["solid"], "unicode": "f0b0", "label": "Filter", "voted": false, "svg": { "solid": { "last_modified": 1684767552, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M3.9 54.9C10.5 40.9 24.5 32 40 32H472c15.5 0 29.5 8.9 36.1 22.9s4.6 30.5-5.2 42.5L320 320.9V448c0 12.1-6.8 23.2-17.7 28.6s-23.8 4.3-33.5-3l-64-48c-8.1-6-12.8-15.5-12.8-25.6V320.9L9 97.3C-.7 85.4-2.8 68.8 3.9 54.9z" } }, "free": ["solid"] }, "filter-circle-dollar": { "aliases": { "names": ["funnel-dollar"], "unicodes": { "secondary": ["10f662"] } }, "changes": ["5.3.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["filter", "money", "options", "separate", "sort"] }, "styles": ["solid"], "unicode": "f662", "label": "Filter Circle Dollar", "voted": false, "svg": { "solid": { "last_modified": 1684767552, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M3.9 22.9C10.5 8.9 24.5 0 40 0H472c15.5 0 29.5 8.9 36.1 22.9s4.6 30.5-5.2 42.5L396.4 195.6C316.2 212.1 256 283 256 368c0 27.4 6.3 53.4 17.5 76.5c-1.6-.8-3.2-1.8-4.7-2.9l-64-48c-8.1-6-12.8-15.5-12.8-25.6V288.9L9 65.3C-.7 53.4-2.8 36.8 3.9 22.9zM288 368a144 144 0 1 1 288 0 144 144 0 1 1 -288 0zm120.8-32.6c.6-.9 1.8-2.1 4.2-3.4c5.1-2.7 12.5-4.1 18.7-4c8.2 .1 17.1 1.8 26.4 4.1c8.6 2.1 17.3-3.1 19.4-11.7s-3.1-17.3-11.7-19.4c-5.6-1.4-11.6-2.7-17.9-3.7V288c0-8.8-7.2-16-16-16s-16 7.2-16 16v9.5c-6.1 1.2-12.3 3.2-18 6.3c-11.8 6.3-23 18.4-21.8 37.2c1 16 11.7 25.3 21.6 30.7c8.8 4.7 19.7 7.8 28.6 10.3l1.8 .5c10.3 2.9 17.9 5.2 23.2 8.3c4.5 2.7 4.7 4.2 4.7 5.6c.1 2.4-.5 3.7-1 4.5c-.6 1-1.8 2.2-4 3.3c-4.7 2.5-11.8 3.8-18.5 3.6c-9.5-.3-18.5-3.1-29.9-6.8c-1.9-.6-3.8-1.2-5.8-1.8c-8.4-2.6-17.4 2.1-20 10.5s2.1 17.4 10.5 20c1.6 .5 3.3 1 5 1.6l0 0 0 0c7 2.3 15.1 4.8 23.7 6.6v11.4c0 8.8 7.2 16 16 16s16-7.2 16-16V438.7c6.2-1.1 12.5-3.1 18.3-6.2c12.1-6.5 22.3-18.7 21.7-36.9c-.5-16.2-10.3-26.3-20.5-32.3c-9.4-5.6-21.2-8.9-30.5-11.5l-.2 0c-10.4-2.9-18.3-5.2-23.9-8.2c-4.8-2.6-4.8-4-4.8-4.5l0-.1c-.1-1.9 .3-2.9 .8-3.6z" } }, "free": ["solid"] }, "filter-circle-xmark": { "changes": ["6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["cancel", "funnel", "options", "remove", "separate", "sort"] }, "styles": ["solid"], "unicode": "e17b", "label": "Filter Circle Xmark", "voted": true, "svg": { "solid": { "last_modified": 1684767552, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M3.9 22.9C10.5 8.9 24.5 0 40 0H472c15.5 0 29.5 8.9 36.1 22.9s4.6 30.5-5.2 42.5L396.4 195.6C316.2 212.1 256 283 256 368c0 27.4 6.3 53.4 17.5 76.5c-1.6-.8-3.2-1.8-4.7-2.9l-64-48c-8.1-6-12.8-15.5-12.8-25.6V288.9L9 65.3C-.7 53.4-2.8 36.8 3.9 22.9zM432 224a144 144 0 1 1 0 288 144 144 0 1 1 0-288zm59.3 107.3c6.2-6.2 6.2-16.4 0-22.6s-16.4-6.2-22.6 0L432 345.4l-36.7-36.7c-6.2-6.2-16.4-6.2-22.6 0s-6.2 16.4 0 22.6L409.4 368l-36.7 36.7c-6.2 6.2-6.2 16.4 0 22.6s16.4 6.2 22.6 0L432 390.6l36.7 36.7c6.2 6.2 16.4 6.2 22.6 0s6.2-16.4 0-22.6L454.6 368l36.7-36.7z" } }, "free": ["solid"] }, "fingerprint": { "aliases": { "unicodes": { "secondary": ["10f577"] } }, "changes": ["5.1.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "human", "id", "identification", "lock", "smudge", "touch", "unique", "unlock" ] }, "styles": ["solid"], "unicode": "f577", "label": "Fingerprint", "voted": true, "svg": { "solid": { "last_modified": 1684766751, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M48 256C48 141.1 141.1 48 256 48c63.1 0 119.6 28.1 157.8 72.5c8.6 10.1 23.8 11.2 33.8 2.6s11.2-23.8 2.6-33.8C403.3 34.6 333.7 0 256 0C114.6 0 0 114.6 0 256v40c0 13.3 10.7 24 24 24s24-10.7 24-24V256zm458.5-52.9c-2.7-13-15.5-21.3-28.4-18.5s-21.3 15.5-18.5 28.4c2.9 13.9 4.5 28.3 4.5 43.1v40c0 13.3 10.7 24 24 24s24-10.7 24-24V256c0-18.1-1.9-35.8-5.5-52.9zM256 80c-19 0-37.4 3-54.5 8.6c-15.2 5-18.7 23.7-8.3 35.9c7.1 8.3 18.8 10.8 29.4 7.9c10.6-2.9 21.8-4.4 33.4-4.4c70.7 0 128 57.3 128 128v24.9c0 25.2-1.5 50.3-4.4 75.3c-1.7 14.6 9.4 27.8 24.2 27.8c11.8 0 21.9-8.6 23.3-20.3c3.3-27.4 5-55 5-82.7V256c0-97.2-78.8-176-176-176zM150.7 148.7c-9.1-10.6-25.3-11.4-33.9-.4C93.7 178 80 215.4 80 256v24.9c0 24.2-2.6 48.4-7.8 71.9C68.8 368.4 80.1 384 96.1 384c10.5 0 19.9-7 22.2-17.3c6.4-28.1 9.7-56.8 9.7-85.8V256c0-27.2 8.5-52.4 22.9-73.1c7.2-10.4 8-24.6-.2-34.2zM256 160c-53 0-96 43-96 96v24.9c0 35.9-4.6 71.5-13.8 106.1c-3.8 14.3 6.7 29 21.5 29c9.5 0 17.9-6.2 20.4-15.4c10.5-39 15.9-79.2 15.9-119.7V256c0-28.7 23.3-52 52-52s52 23.3 52 52v24.9c0 36.3-3.5 72.4-10.4 107.9c-2.7 13.9 7.7 27.2 21.8 27.2c10.2 0 19-7 21-17c7.7-38.8 11.6-78.3 11.6-118.1V256c0-53-43-96-96-96zm24 96c0-13.3-10.7-24-24-24s-24 10.7-24 24v24.9c0 59.9-11 119.3-32.5 175.2l-5.9 15.3c-4.8 12.4 1.4 26.3 13.8 31s26.3-1.4 31-13.8l5.9-15.3C267.9 411.9 280 346.7 280 280.9V256z" } }, "free": ["solid"] }, "fire": { "aliases": { "unicodes": { "composite": ["1f525"], "secondary": ["10f06d"] } }, "changes": [ "1.0.0", "5.0.0", "5.6.0", "5.6.3", "5.10.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "burn", "caliente", "fire", "flame", "heat", "hot", "popular", "tool" ] }, "styles": ["solid"], "unicode": "f06d", "label": "Fire", "voted": false, "svg": { "solid": { "last_modified": 1684767662, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M159.3 5.4c7.8-7.3 19.9-7.2 27.7 .1c27.6 25.9 53.5 53.8 77.7 84c11-14.4 23.5-30.1 37-42.9c7.9-7.4 20.1-7.4 28 .1c34.6 33 63.9 76.6 84.5 118c20.3 40.8 33.8 82.5 33.8 111.9C448 404.2 348.2 512 224 512C98.4 512 0 404.1 0 276.5c0-38.4 17.8-85.3 45.4-131.7C73.3 97.7 112.7 48.6 159.3 5.4zM225.7 416c25.3 0 47.7-7 68.8-21c42.1-29.4 53.4-88.2 28.1-134.4c-4.5-9-16-9.6-22.5-2l-25.2 29.3c-6.6 7.6-18.5 7.4-24.7-.5c-16.5-21-46-58.5-62.8-79.8c-6.3-8-18.3-8.1-24.7-.1c-33.8 42.5-50.8 69.3-50.8 99.4C112 375.4 162.6 416 225.7 416z" } }, "free": ["solid"] }, "fire-burner": { "changes": ["6.1.0", "6.1.2", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["cook", "fire", "flame", "kitchen", "stove"] }, "styles": ["solid"], "unicode": "e4f1", "label": "Fire Burner", "voted": false, "svg": { "solid": { "last_modified": 1684767443, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M293.5 3.8c19.7 17.8 38.2 37 55.5 57.7c7.9-9.9 16.8-20.7 26.5-29.5c5.6-5.1 14.4-5.1 20 0c24.7 22.7 45.6 52.7 60.4 81.1c14.5 28 24.2 58.8 24.2 79C480 280 408.7 352 320 352c-89.7 0-160-72.1-160-159.8c0-26.4 12.7-60.7 32.4-92.6c20-32.4 48.1-66.1 81.4-95.8c2.8-2.5 6.4-3.8 10-3.7c3.5 0 7 1.3 9.8 3.8zM370 273c30-21 38-63 20-96c-2-4-4-8-7-12l-36 42s-58-74-62-79c-30 37-45 58-45 82c0 49 36 78 81 78c18 0 34-5 49-15zM32 288c0-17.7 14.3-32 32-32H96c17.7 0 32 14.3 32 32s-14.3 32-32 32v64H544V320c-17.7 0-32-14.3-32-32s14.3-32 32-32h32c17.7 0 32 14.3 32 32v96c17.7 0 32 14.3 32 32v64c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32V416c0-17.7 14.3-32 32-32V288zM320 480a32 32 0 1 0 0-64 32 32 0 1 0 0 64zm160-32a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zM192 480a32 32 0 1 0 0-64 32 32 0 1 0 0 64z" } }, "free": ["solid"] }, "fire-extinguisher": { "aliases": { "unicodes": { "composite": ["1f9ef"], "secondary": ["10f134"] } }, "changes": ["3.1.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "burn", "caliente", "extinguish", "fire", "fire extinguisher", "fire fighter", "flame", "heat", "hot", "quench", "rescue" ] }, "styles": ["solid"], "unicode": "f134", "label": "Fire Extinguisher", "voted": false, "svg": { "solid": { "last_modified": 1684767443, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M500.3 7.3C507.7 13.3 512 22.4 512 32v96c0 9.6-4.3 18.7-11.7 24.7s-17.2 8.5-26.6 6.6l-160-32C301.5 124.9 292 115.7 289 104H224v34.8c37.8 18 64 56.5 64 101.2V384H64V240c0-44.7 26.2-83.2 64-101.2V110c-36.2 11.1-66 36.9-82.3 70.5c-5.8 11.9-20.2 16.9-32.1 11.1S-3.3 171.4 2.5 159.5C26.7 109.8 72.7 72.6 128 60.4V32c0-17.7 14.3-32 32-32h32c17.7 0 32 14.3 32 32V56h65c3-11.7 12.5-20.9 24.7-23.4l160-32c9.4-1.9 19.1 .6 26.6 6.6zM288 416v32c0 35.3-28.7 64-64 64H128c-35.3 0-64-28.7-64-64V416H288zM176 96a16 16 0 1 0 0-32 16 16 0 1 0 0 32z" } }, "free": ["solid"] }, "fire-flame-curved": { "aliases": { "names": ["fire-alt"], "unicodes": { "secondary": ["10f7e4"] } }, "changes": ["5.6.3", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["burn", "caliente", "flame", "heat", "hot", "popular"] }, "styles": ["solid"], "unicode": "f7e4", "label": "Fire Flame Curved", "voted": false, "svg": { "solid": { "last_modified": 1684767661, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M153.6 29.9l16-21.3C173.6 3.2 180 0 186.7 0C198.4 0 208 9.6 208 21.3V43.5c0 13.1 5.4 25.7 14.9 34.7L307.6 159C356.4 205.6 384 270.2 384 337.7C384 434 306 512 209.7 512H192C86 512 0 426 0 320v-3.8c0-48.8 19.4-95.6 53.9-130.1l3.5-3.5c4.2-4.2 10-6.6 16-6.6C85.9 176 96 186.1 96 198.6V288c0 35.3 28.7 64 64 64s64-28.7 64-64v-3.9c0-18-7.2-35.3-19.9-48l-38.6-38.6c-24-24-37.5-56.7-37.5-90.7c0-27.7 9-54.8 25.6-76.9z" } }, "free": ["solid"] }, "fire-flame-simple": { "aliases": { "names": ["burn"], "unicodes": { "secondary": ["10f46a"] } }, "changes": ["5.0.7", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["caliente", "energy", "fire", "flame", "gas", "heat", "hot"] }, "styles": ["solid"], "unicode": "f46a", "label": "Fire Flame Simple", "voted": false, "svg": { "solid": { "last_modified": 1684767662, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M372.5 256.5l-.7-1.9C337.8 160.8 282 76.5 209.1 8.5l-3.3-3C202.1 2 197.1 0 192 0s-10.1 2-13.8 5.5l-3.3 3C102 76.5 46.2 160.8 12.2 254.6l-.7 1.9C3.9 277.3 0 299.4 0 321.6C0 426.7 86.8 512 192 512s192-85.3 192-190.4c0-22.2-3.9-44.2-11.5-65.1zm-90.8 49.5c4.1 9.3 6.2 19.4 6.2 29.5c0 53-43 96.5-96 96.5s-96-43.5-96-96.5c0-10.1 2.1-20.3 6.2-29.5l1.9-4.3c15.8-35.4 37.9-67.7 65.3-95.1l8.9-8.9c3.6-3.6 8.5-5.6 13.6-5.6s10 2 13.6 5.6l8.9 8.9c27.4 27.4 49.6 59.7 65.3 95.1l1.9 4.3z" } }, "free": ["solid"] }, "firefox": { "changes": ["4.4.0", "5.0.0", "5.0.1", "5.12.0"], "ligatures": [], "search": { "terms": ["browser"] }, "styles": ["brands"], "unicode": "f269", "label": "Firefox", "voted": false, "svg": { "brands": { "last_modified": 1660014472, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M503.52,241.48c-.12-1.56-.24-3.12-.24-4.68v-.12l-.36-4.68v-.12a245.86,245.86,0,0,0-7.32-41.15c0-.12,0-.12-.12-.24l-1.08-4c-.12-.24-.12-.48-.24-.6-.36-1.2-.72-2.52-1.08-3.72-.12-.24-.12-.6-.24-.84-.36-1.2-.72-2.4-1.08-3.48-.12-.36-.24-.6-.36-1-.36-1.2-.72-2.28-1.2-3.48l-.36-1.08c-.36-1.08-.84-2.28-1.2-3.36a8.27,8.27,0,0,0-.36-1c-.48-1.08-.84-2.28-1.32-3.36-.12-.24-.24-.6-.36-.84-.48-1.2-1-2.28-1.44-3.48,0-.12-.12-.24-.12-.36-1.56-3.84-3.24-7.68-5-11.4l-.36-.72c-.48-1-.84-1.8-1.32-2.64-.24-.48-.48-1.08-.72-1.56-.36-.84-.84-1.56-1.2-2.4-.36-.6-.6-1.2-1-1.8s-.84-1.44-1.2-2.28c-.36-.6-.72-1.32-1.08-1.92s-.84-1.44-1.2-2.16a18.07,18.07,0,0,0-1.2-2c-.36-.72-.84-1.32-1.2-2s-.84-1.32-1.2-2-.84-1.32-1.2-1.92-.84-1.44-1.32-2.16a15.63,15.63,0,0,0-1.2-1.8L463.2,119a15.63,15.63,0,0,0-1.2-1.8c-.48-.72-1.08-1.56-1.56-2.28-.36-.48-.72-1.08-1.08-1.56l-1.8-2.52c-.36-.48-.6-.84-1-1.32-1-1.32-1.8-2.52-2.76-3.72a248.76,248.76,0,0,0-23.51-26.64A186.82,186.82,0,0,0,412,62.46c-4-3.48-8.16-6.72-12.48-9.84a162.49,162.49,0,0,0-24.6-15.12c-2.4-1.32-4.8-2.52-7.2-3.72a254,254,0,0,0-55.43-19.56c-1.92-.36-3.84-.84-5.64-1.2h-.12c-1-.12-1.8-.36-2.76-.48a236.35,236.35,0,0,0-38-4H255.14a234.62,234.62,0,0,0-45.48,5c-33.59,7.08-63.23,21.24-82.91,39-1.08,1-1.92,1.68-2.4,2.16l-.48.48H124l-.12.12.12-.12a.12.12,0,0,0,.12-.12l-.12.12a.42.42,0,0,1,.24-.12c14.64-8.76,34.92-16,49.44-19.56l5.88-1.44c.36-.12.84-.12,1.2-.24,1.68-.36,3.36-.72,5.16-1.08.24,0,.6-.12.84-.12C250.94,20.94,319.34,40.14,367,85.61a171.49,171.49,0,0,1,26.88,32.76c30.36,49.2,27.48,111.11,3.84,147.59-34.44,53-111.35,71.27-159,24.84a84.19,84.19,0,0,1-25.56-59,74.05,74.05,0,0,1,6.24-31c1.68-3.84,13.08-25.67,18.24-24.59-13.08-2.76-37.55,2.64-54.71,28.19-15.36,22.92-14.52,58.2-5,83.28a132.85,132.85,0,0,1-12.12-39.24c-12.24-82.55,43.31-153,94.31-170.51-27.48-24-96.47-22.31-147.71,15.36-29.88,22-51.23,53.16-62.51,90.36,1.68-20.88,9.6-52.08,25.8-83.88-17.16,8.88-39,37-49.8,62.88-15.6,37.43-21,82.19-16.08,124.79.36,3.24.72,6.36,1.08,9.6,19.92,117.11,122,206.38,244.78,206.38C392.77,503.42,504,392.19,504,255,503.88,250.48,503.76,245.92,503.52,241.48Z" } }, "free": ["brands"] }, "firefox-browser": { "changes": ["5.12.0", "5.14.0"], "ligatures": [], "search": { "terms": ["browser"] }, "styles": ["brands"], "unicode": "e007", "label": "Firefox Browser", "voted": false, "svg": { "brands": { "last_modified": 1660014461, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M130.22 127.548C130.38 127.558 130.3 127.558 130.22 127.548V127.548ZM481.64 172.898C471.03 147.398 449.56 119.898 432.7 111.168C446.42 138.058 454.37 165.048 457.4 185.168C457.405 185.306 457.422 185.443 457.45 185.578C429.87 116.828 383.098 89.1089 344.9 28.7479C329.908 5.05792 333.976 3.51792 331.82 4.08792L331.7 4.15792C284.99 30.1109 256.365 82.5289 249.12 126.898C232.503 127.771 216.219 131.895 201.19 139.035C199.838 139.649 198.736 140.706 198.066 142.031C197.396 143.356 197.199 144.87 197.506 146.323C197.7 147.162 198.068 147.951 198.586 148.639C199.103 149.327 199.76 149.899 200.512 150.318C201.264 150.737 202.096 150.993 202.954 151.071C203.811 151.148 204.676 151.045 205.491 150.768L206.011 150.558C221.511 143.255 238.408 139.393 255.541 139.238C318.369 138.669 352.698 183.262 363.161 201.528C350.161 192.378 326.811 183.338 304.341 187.248C392.081 231.108 368.541 381.784 246.951 376.448C187.487 373.838 149.881 325.467 146.421 285.648C146.421 285.648 157.671 243.698 227.041 243.698C234.541 243.698 255.971 222.778 256.371 216.698C256.281 214.698 213.836 197.822 197.281 181.518C188.434 172.805 184.229 168.611 180.511 165.458C178.499 163.75 176.392 162.158 174.201 160.688C168.638 141.231 168.399 120.638 173.51 101.058C148.45 112.468 128.96 130.508 114.8 146.428H114.68C105.01 134.178 105.68 93.7779 106.25 85.3479C106.13 84.8179 99.022 89.0159 98.1 89.6579C89.5342 95.7103 81.5528 102.55 74.26 110.088C57.969 126.688 30.128 160.242 18.76 211.318C14.224 231.701 12 255.739 12 263.618C12 398.318 121.21 507.508 255.92 507.508C376.56 507.508 478.939 420.281 496.35 304.888C507.922 228.192 481.64 173.82 481.64 172.898Z" } }, "free": ["brands"] }, "first-order": { "changes": ["4.6.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f2b0", "label": "First Order", "voted": false, "svg": { "brands": { "last_modified": 1660014482, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M12.9 229.2c.1-.1.2-.3.3-.4 0 .1 0 .3-.1.4h-.2zM224 96.6c-7.1 0-14.6.6-21.4 1.7l3.7 67.4-22-64c-14.3 3.7-27.7 9.4-40 16.6l29.4 61.4-45.1-50.9c-11.4 8.9-21.7 19.1-30.6 30.9l50.6 45.4-61.1-29.7c-7.1 12.3-12.9 25.7-16.6 40l64.3 22.6-68-4c-.9 7.1-1.4 14.6-1.4 22s.6 14.6 1.4 21.7l67.7-4-64 22.6c3.7 14.3 9.4 27.7 16.6 40.3l61.1-29.7L97.7 352c8.9 11.7 19.1 22.3 30.9 30.9l44.9-50.9-29.5 61.4c12.3 7.4 25.7 13.1 40 16.9l22.3-64.6-4 68c7.1 1.1 14.6 1.7 21.7 1.7 7.4 0 14.6-.6 21.7-1.7l-4-68.6 22.6 65.1c14.3-4 27.7-9.4 40-16.9L274.9 332l44.9 50.9c11.7-8.9 22-19.1 30.6-30.9l-50.6-45.1 61.1 29.4c7.1-12.3 12.9-25.7 16.6-40.3l-64-22.3 67.4 4c1.1-7.1 1.4-14.3 1.4-21.7s-.3-14.9-1.4-22l-67.7 4 64-22.3c-3.7-14.3-9.1-28-16.6-40.3l-60.9 29.7 50.6-45.4c-8.9-11.7-19.1-22-30.6-30.9l-45.1 50.9 29.4-61.1c-12.3-7.4-25.7-13.1-40-16.9L241.7 166l4-67.7c-7.1-1.2-14.3-1.7-21.7-1.7zM443.4 128v256L224 512 4.6 384V128L224 0l219.4 128zm-17.1 10.3L224 20.9 21.7 138.3v235.1L224 491.1l202.3-117.7V138.3zM224 37.1l187.7 109.4v218.9L224 474.9 36.3 365.4V146.6L224 37.1zm0 50.9c-92.3 0-166.9 75.1-166.9 168 0 92.6 74.6 167.7 166.9 167.7 92 0 166.9-75.1 166.9-167.7 0-92.9-74.9-168-166.9-168z" } }, "free": ["brands"] }, "first-order-alt": { "changes": ["5.0.12"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f50a", "label": "Alternate First Order", "voted": false, "svg": { "brands": { "last_modified": 1660014470, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M248 8C111.03 8 0 119.03 0 256s111.03 248 248 248 248-111.03 248-248S384.97 8 248 8zm0 488.21C115.34 496.21 7.79 388.66 7.79 256S115.34 15.79 248 15.79 488.21 123.34 488.21 256 380.66 496.21 248 496.21zm0-459.92C126.66 36.29 28.29 134.66 28.29 256S126.66 475.71 248 475.71 467.71 377.34 467.71 256 369.34 36.29 248 36.29zm0 431.22c-116.81 0-211.51-94.69-211.51-211.51S131.19 44.49 248 44.49 459.51 139.19 459.51 256 364.81 467.51 248 467.51zm186.23-162.98a191.613 191.613 0 0 1-20.13 48.69l-74.13-35.88 61.48 54.82a193.515 193.515 0 0 1-37.2 37.29l-54.8-61.57 35.88 74.27a190.944 190.944 0 0 1-48.63 20.23l-27.29-78.47 4.79 82.93c-8.61 1.18-17.4 1.8-26.33 1.8s-17.72-.62-26.33-1.8l4.76-82.46-27.15 78.03a191.365 191.365 0 0 1-48.65-20.2l35.93-74.34-54.87 61.64a193.85 193.85 0 0 1-37.22-37.28l61.59-54.9-74.26 35.93a191.638 191.638 0 0 1-20.14-48.69l77.84-27.11-82.23 4.76c-1.16-8.57-1.78-17.32-1.78-26.21 0-9 .63-17.84 1.82-26.51l82.38 4.77-77.94-27.16a191.726 191.726 0 0 1 20.23-48.67l74.22 35.92-61.52-54.86a193.85 193.85 0 0 1 37.28-37.22l54.76 61.53-35.83-74.17a191.49 191.49 0 0 1 48.65-20.13l26.87 77.25-4.71-81.61c8.61-1.18 17.39-1.8 26.32-1.8s17.71.62 26.32 1.8l-4.74 82.16 27.05-77.76c17.27 4.5 33.6 11.35 48.63 20.17l-35.82 74.12 54.72-61.47a193.13 193.13 0 0 1 37.24 37.23l-61.45 54.77 74.12-35.86a191.515 191.515 0 0 1 20.2 48.65l-77.81 27.1 82.24-4.75c1.19 8.66 1.82 17.5 1.82 26.49 0 8.88-.61 17.63-1.78 26.19l-82.12-4.75 77.72 27.09z" } }, "free": ["brands"] }, "firstdraft": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3a1", "label": "firstdraft", "voted": false, "svg": { "brands": { "last_modified": 1660014476, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M384 192h-64v128H192v128H0v-25.6h166.4v-128h128v-128H384V192zm-25.6 38.4v128h-128v128H64V512h192V384h128V230.4h-25.6zm25.6 192h-89.6V512H320v-64h64v-25.6zM0 0v384h128V256h128V128h128V0H0z" } }, "free": ["brands"] }, "fish": { "aliases": { "unicodes": { "composite": ["1f41f"], "secondary": ["10f578"] } }, "changes": [ "5.1.0", "5.10.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Pisces", "fauna", "fish", "gold", "seafood", "swimming", "zodiac" ] }, "styles": ["solid"], "unicode": "f578", "label": "Fish", "voted": true, "svg": { "solid": { "last_modified": 1684768130, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M180.5 141.5C219.7 108.5 272.6 80 336 80s116.3 28.5 155.5 61.5c39.1 33 66.9 72.4 81 99.8c4.7 9.2 4.7 20.1 0 29.3c-14.1 27.4-41.9 66.8-81 99.8C452.3 403.5 399.4 432 336 432s-116.3-28.5-155.5-61.5c-16.2-13.7-30.5-28.5-42.7-43.1L48.1 379.6c-12.5 7.3-28.4 5.3-38.7-4.9S-3 348.7 4.2 336.1L50 256 4.2 175.9c-7.2-12.6-5-28.4 5.3-38.6s26.1-12.2 38.7-4.9l89.7 52.3c12.2-14.6 26.5-29.4 42.7-43.1zM448 256a32 32 0 1 0 -64 0 32 32 0 1 0 64 0z" } }, "free": ["solid"] }, "fish-fins": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["fish", "fishery", "pisces", "seafood"] }, "styles": ["solid"], "unicode": "e4f2", "label": "Fish Fins", "voted": false, "svg": { "solid": { "last_modified": 1684768130, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M275.2 38.4c-10.6-8-25-8.5-36.3-1.5S222 57.3 224.6 70.3l9.7 48.6c-19.4 9-36.9 19.9-52.4 31.5c-15.3 11.5-29 23.9-40.7 36.3L48.1 132.4c-12.5-7.3-28.4-5.3-38.7 4.9S-3 163.3 4.2 175.9L50 256 4.2 336.1c-7.2 12.6-5 28.4 5.3 38.6s26.1 12.2 38.7 4.9l93.1-54.3c11.8 12.3 25.4 24.8 40.7 36.3c15.5 11.6 33 22.5 52.4 31.5l-9.7 48.6c-2.6 13 3.1 26.3 14.3 33.3s25.6 6.5 36.3-1.5l77.6-58.2c54.9-4 101.5-27 137.2-53.8c39.2-29.4 67.2-64.7 81.6-89.5c5.8-9.9 5.8-22.2 0-32.1c-14.4-24.8-42.5-60.1-81.6-89.5c-35.8-26.8-82.3-49.8-137.2-53.8L275.2 38.4zM384 256a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z" } }, "free": ["solid"] }, "flag": { "aliases": { "unicodes": { "composite": ["1f3f4", "f11d"], "secondary": ["10f024"] } }, "changes": [ "1.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.2.1", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "black flag", "country", "notice", "notification", "notify", "pole", "report", "symbol", "waving" ] }, "styles": ["solid", "regular"], "unicode": "f024", "label": "Flag", "voted": false, "svg": { "solid": { "last_modified": 1684767603, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M64 32C64 14.3 49.7 0 32 0S0 14.3 0 32V64 368 480c0 17.7 14.3 32 32 32s32-14.3 32-32V352l64.3-16.1c41.1-10.3 84.6-5.5 122.5 13.4c44.2 22.1 95.5 24.8 141.7 7.4l34.7-13c12.5-4.7 20.8-16.6 20.8-30V66.1c0-23-24.2-38-44.8-27.7l-9.6 4.8c-46.3 23.2-100.8 23.2-147.1 0c-35.1-17.6-75.4-22-113.5-12.5L64 48V32z" }, "regular": { "last_modified": 1684767603, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M48 24C48 10.7 37.3 0 24 0S0 10.7 0 24V64 350.5 400v88c0 13.3 10.7 24 24 24s24-10.7 24-24V388l80.3-20.1c41.1-10.3 84.6-5.5 122.5 13.4c44.2 22.1 95.5 24.8 141.7 7.4l34.7-13c12.5-4.7 20.8-16.6 20.8-30V66.1c0-23-24.2-38-44.8-27.7l-9.6 4.8c-46.3 23.2-100.8 23.2-147.1 0c-35.1-17.6-75.4-22-113.5-12.5L48 52V24zm0 77.5l96.6-24.2c27-6.7 55.5-3.6 80.4 8.8c54.9 27.4 118.7 29.7 175 6.8V334.7l-24.4 9.1c-33.7 12.6-71.2 10.7-103.4-5.4c-48.2-24.1-103.3-30.1-155.6-17.1L48 338.5v-237z" } }, "free": ["regular", "solid"] }, "flag-checkered": { "aliases": { "unicodes": { "composite": ["1f3c1"], "secondary": ["10f11e"] } }, "changes": [ "3.1.0", "5.0.0", "5.7.0", "5.10.1", "6.0.0-beta1", "6.2.0", "6.2.1", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "checkered", "chequered", "chequered flag", "finish", "notice", "notification", "notify", "pole", "racing", "report", "start", "symbol", "win" ] }, "styles": ["solid"], "unicode": "f11e", "label": "Flag Checkered", "voted": false, "svg": { "solid": { "last_modified": 1684767603, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M32 0C49.7 0 64 14.3 64 32V48l69-17.2c38.1-9.5 78.3-5.1 113.5 12.5c46.3 23.2 100.8 23.2 147.1 0l9.6-4.8C423.8 28.1 448 43.1 448 66.1V345.8c0 13.3-8.3 25.3-20.8 30l-34.7 13c-46.2 17.3-97.6 14.6-141.7-7.4c-37.9-19-81.3-23.7-122.5-13.4L64 384v96c0 17.7-14.3 32-32 32s-32-14.3-32-32V400 334 64 32C0 14.3 14.3 0 32 0zM64 187.1l64-13.9v65.5L64 252.6V318l48.8-12.2c5.1-1.3 10.1-2.4 15.2-3.3V238.7l38.9-8.4c8.3-1.8 16.7-2.5 25.1-2.1l0-64c13.6 .4 27.2 2.6 40.4 6.4l23.6 6.9v66.7l-41.7-12.3c-7.3-2.1-14.8-3.4-22.3-3.8v71.4c21.8 1.9 43.3 6.7 64 14.4V244.2l22.7 6.7c13.5 4 27.3 6.4 41.3 7.4V194c-7.8-.8-15.6-2.3-23.2-4.5l-40.8-12v-62c-13-3.8-25.8-8.8-38.2-15c-8.2-4.1-16.9-7-25.8-8.8v72.4c-13-.4-26 .8-38.7 3.6L128 173.2V98L64 114v73.1zM320 335.7c16.8 1.5 33.9-.7 50-6.8l14-5.2V251.9l-7.9 1.8c-18.4 4.3-37.3 5.7-56.1 4.5v77.4zm64-149.4V115.4c-20.9 6.1-42.4 9.1-64 9.1V194c13.9 1.4 28 .5 41.7-2.6l22.3-5.2z" } }, "free": ["solid"] }, "flag-usa": { "aliases": { "unicodes": { "secondary": ["10f74d"] } }, "changes": ["5.5.0", "6.0.0-beta1", "6.2.0", "6.2.1", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "betsy ross", "country", "fla", "flag: United States", "old glory", "stars", "stripes", "symbol" ] }, "styles": ["solid"], "unicode": "f74d", "label": "Flag Usa", "voted": false, "svg": { "solid": { "last_modified": 1684767602, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M32 0C49.7 0 64 14.3 64 32V48l69-17.2c38.1-9.5 78.3-5.1 113.5 12.5c46.3 23.2 100.8 23.2 147.1 0l9.6-4.8C423.8 28.1 448 43.1 448 66.1v36.1l-44.7 16.2c-42.8 15.6-90 13.9-131.6-4.6l-16.1-7.2c-20.3-9-41.8-14.7-63.6-16.9v32.2c17.4 2.1 34.4 6.7 50.6 13.9l16.1 7.2c49.2 21.9 105 23.8 155.6 5.4L448 136.3v62l-44.7 16.2c-42.8 15.6-90 13.9-131.6-4.6l-16.1-7.2c-40.2-17.9-85-22.5-128.1-13.3L64 203.1v32.7l70.2-15.1c36.4-7.8 74.3-3.9 108.4 11.3l16.1 7.2c49.2 21.9 105 23.8 155.6 5.4L448 232.3v62l-44.7 16.2c-42.8 15.6-90 13.9-131.6-4.6l-16.1-7.2c-40.2-17.9-85-22.5-128.1-13.3L64 299.1v32.7l70.2-15.1c36.4-7.8 74.3-3.9 108.4 11.3l16.1 7.2c49.2 21.9 105 23.8 155.6 5.4L448 328.3v33.5c0 13.3-8.3 25.3-20.8 30l-34.7 13c-46.2 17.3-97.6 14.6-141.7-7.4c-37.9-19-81.3-23.7-122.5-13.4L64 400v80c0 17.7-14.3 32-32 32s-32-14.3-32-32V416 345.5 312.8 249.5 216.8 153.5 120.8 64 32C0 14.3 14.3 0 32 0zm80 96A16 16 0 1 0 80 96a16 16 0 1 0 32 0zm32 0a16 16 0 1 0 0-32 16 16 0 1 0 0 32zm-32 48a16 16 0 1 0 -32 0 16 16 0 1 0 32 0zm32 0a16 16 0 1 0 0-32 16 16 0 1 0 0 32z" } }, "free": ["solid"] }, "flask": { "aliases": { "unicodes": { "secondary": ["10f0c3"] } }, "changes": ["2.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "beaker", "chemicals", "experiment", "experimental", "labs", "liquid", "potion", "science", "vial" ] }, "styles": ["solid"], "unicode": "f0c3", "label": "Flask", "voted": false, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M288 0H160 128C110.3 0 96 14.3 96 32s14.3 32 32 32V196.8c0 11.8-3.3 23.5-9.5 33.5L10.3 406.2C3.6 417.2 0 429.7 0 442.6C0 480.9 31.1 512 69.4 512H378.6c38.3 0 69.4-31.1 69.4-69.4c0-12.8-3.6-25.4-10.3-36.4L329.5 230.4c-6.2-10.1-9.5-21.7-9.5-33.5V64c17.7 0 32-14.3 32-32s-14.3-32-32-32H288zM192 196.8V64h64V196.8c0 23.7 6.6 46.9 19 67.1L309.5 320h-171L173 263.9c12.4-20.2 19-43.4 19-67.1z" } }, "free": ["solid"] }, "flask-vial": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ " beaker", " chemicals", " experiment", " experimental", " labs", " liquid", " science", " vial", "ampule", "chemistry", "lab", "laboratory", "potion", "test", "test tube" ] }, "styles": ["solid"], "unicode": "e4f3", "label": "Flask Vial", "voted": false, "svg": { "solid": { "last_modified": 1684766751, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M175 389.4c-9.8 16-15 34.3-15 53.1c-10 3.5-20.8 5.5-32 5.5c-53 0-96-43-96-96V64C14.3 64 0 49.7 0 32S14.3 0 32 0H96h64 64c17.7 0 32 14.3 32 32s-14.3 32-32 32V309.9l-49 79.6zM96 64v96h64V64H96zM352 0H480h32c17.7 0 32 14.3 32 32s-14.3 32-32 32V214.9L629.7 406.2c6.7 10.9 10.3 23.5 10.3 36.4c0 38.3-31.1 69.4-69.4 69.4H261.4c-38.3 0-69.4-31.1-69.4-69.4c0-12.8 3.6-25.4 10.3-36.4L320 214.9V64c-17.7 0-32-14.3-32-32s14.3-32 32-32h32zm32 64V224c0 5.9-1.6 11.7-4.7 16.8L330.5 320h171l-48.8-79.2c-3.1-5-4.7-10.8-4.7-16.8V64H384z" } }, "free": ["solid"] }, "flickr": { "changes": ["3.2.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f16e", "label": "Flickr", "voted": false, "svg": { "brands": { "last_modified": 1660014468, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM144.5 319c-35.1 0-63.5-28.4-63.5-63.5s28.4-63.5 63.5-63.5 63.5 28.4 63.5 63.5-28.4 63.5-63.5 63.5zm159 0c-35.1 0-63.5-28.4-63.5-63.5s28.4-63.5 63.5-63.5 63.5 28.4 63.5 63.5-28.4 63.5-63.5 63.5z" } }, "free": ["brands"] }, "flipboard": { "changes": ["5.0.5", "5.0.9"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f44d", "label": "Flipboard", "voted": true, "svg": { "brands": { "last_modified": 1660014459, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M0 32v448h448V32H0zm358.4 179.2h-89.6v89.6h-89.6v89.6H89.6V121.6h268.8v89.6z" } }, "free": ["brands"] }, "floppy-disk": { "aliases": { "names": ["save"], "unicodes": { "composite": ["1f4be", "1f5aa"], "secondary": ["10f0c7"] } }, "changes": [ "2.0.0", "5.0.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Black Hard Shell Floppy Disk", "computer", "disk", "download", "floppy", "floppy disk", "floppy-o" ] }, "styles": ["solid", "regular"], "unicode": "f0c7", "label": "Floppy Disk", "voted": false, "svg": { "solid": { "last_modified": 1684767342, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V173.3c0-17-6.7-33.3-18.7-45.3L352 50.7C340 38.7 323.7 32 306.7 32H64zm0 96c0-17.7 14.3-32 32-32H288c17.7 0 32 14.3 32 32v64c0 17.7-14.3 32-32 32H96c-17.7 0-32-14.3-32-32V128zM224 288a64 64 0 1 1 0 128 64 64 0 1 1 0-128z" }, "regular": { "last_modified": 1684767342, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M48 96V416c0 8.8 7.2 16 16 16H384c8.8 0 16-7.2 16-16V170.5c0-4.2-1.7-8.3-4.7-11.3l33.9-33.9c12 12 18.7 28.3 18.7 45.3V416c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V96C0 60.7 28.7 32 64 32H309.5c17 0 33.3 6.7 45.3 18.7l74.5 74.5-33.9 33.9L320.8 84.7c-.3-.3-.5-.5-.8-.8V184c0 13.3-10.7 24-24 24H104c-13.3 0-24-10.7-24-24V80H64c-8.8 0-16 7.2-16 16zm80-16v80H272V80H128zm32 240a64 64 0 1 1 128 0 64 64 0 1 1 -128 0z" } }, "free": ["regular", "solid"] }, "florin-sign": { "changes": ["6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["currency"] }, "styles": ["solid"], "unicode": "e184", "label": "Florin Sign", "voted": false, "svg": { "solid": { "last_modified": 1684766475, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M314.7 32c-38.8 0-73.7 23.3-88.6 59.1L170.7 224H64c-17.7 0-32 14.3-32 32s14.3 32 32 32h80L98.9 396.3c-5 11.9-16.6 19.7-29.5 19.7H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H69.3c38.8 0 73.7-23.3 88.6-59.1L213.3 288H320c17.7 0 32-14.3 32-32s-14.3-32-32-32H240l45.1-108.3c5-11.9 16.6-19.7 29.5-19.7H352c17.7 0 32-14.3 32-32s-14.3-32-32-32H314.7z" } }, "free": ["solid"] }, "fly": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f417", "label": "Fly", "voted": false, "svg": { "brands": { "last_modified": 1660014469, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M197.8 427.8c12.9 11.7 33.7 33.3 33.2 50.7 0 .8-.1 1.6-.1 2.5-1.8 19.8-18.8 31.1-39.1 31-25-.1-39.9-16.8-38.7-35.8 1-16.2 20.5-36.7 32.4-47.6 2.3-2.1 2.7-2.7 5.6-3.6 3.4 0 3.9.3 6.7 2.8zM331.9 67.3c-16.3-25.7-38.6-40.6-63.3-52.1C243.1 4.5 214-.2 192 0c-44.1 0-71.2 13.2-81.1 17.3C57.3 45.2 26.5 87.2 28 158.6c7.1 82.2 97 176 155.8 233.8 1.7 1.6 4.5 4.5 6.2 5.1l3.3.1c2.1-.7 1.8-.5 3.5-2.1 52.3-49.2 140.7-145.8 155.9-215.7 7-39.2 3.1-72.5-20.8-112.5zM186.8 351.9c-28-51.1-65.2-130.7-69.3-189-3.4-47.5 11.4-131.2 69.3-136.7v325.7zM328.7 180c-16.4 56.8-77.3 128-118.9 170.3C237.6 298.4 275 217 277 158.4c1.6-45.9-9.8-105.8-48-131.4 88.8 18.3 115.5 98.1 99.7 153z" } }, "free": ["brands"] }, "folder": { "aliases": { "names": ["folder-blank"], "unicodes": { "composite": ["1f4c1", "1f5bf", "f114"], "secondary": ["10f07b"] } }, "changes": [ "1.0.0", "5.0.0", "5.3.0", "5.10.1", "6.0.0-beta1", "6.1.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Black Folder", "archive", "directory", "document", "file", "file folder", "folder" ] }, "styles": ["solid", "regular"], "unicode": "f07b", "label": "Folder", "voted": false, "svg": { "solid": { "last_modified": 1684767392, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M64 480H448c35.3 0 64-28.7 64-64V160c0-35.3-28.7-64-64-64H288c-10.1 0-19.6-4.7-25.6-12.8L243.2 57.6C231.1 41.5 212.1 32 192 32H64C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64z" }, "regular": { "last_modified": 1684767392, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 96C0 60.7 28.7 32 64 32H196.1c19.1 0 37.4 7.6 50.9 21.1L289.9 96H448c35.3 0 64 28.7 64 64V416c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V96zM64 80c-8.8 0-16 7.2-16 16V416c0 8.8 7.2 16 16 16H448c8.8 0 16-7.2 16-16V160c0-8.8-7.2-16-16-16H286.6c-10.6 0-20.8-4.2-28.3-11.7L213.1 87c-4.5-4.5-10.6-7-17-7H64z" } }, "free": ["regular", "solid"] }, "folder-closed": { "changes": ["6.0.0-beta1", "6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["file"] }, "styles": ["solid", "regular"], "unicode": "e185", "label": "Folder Closed", "voted": false, "svg": { "solid": { "last_modified": 1684767392, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M448 480H64c-35.3 0-64-28.7-64-64V192H512V416c0 35.3-28.7 64-64 64zm64-320H0V96C0 60.7 28.7 32 64 32H192c20.1 0 39.1 9.5 51.2 25.6l19.2 25.6c6 8.1 15.5 12.8 25.6 12.8H448c35.3 0 64 28.7 64 64z" }, "regular": { "last_modified": 1684767392, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M251.7 127.6l0 0c10.5 10.5 24.7 16.4 39.6 16.4H448c8.8 0 16 7.2 16 16v32H48V96c0-8.8 7.2-16 16-16H197.5c4.2 0 8.3 1.7 11.3 4.7l33.9-33.9L208.8 84.7l42.9 42.9zM48 240H464V416c0 8.8-7.2 16-16 16H64c-8.8 0-16-7.2-16-16V240zM285.7 93.7L242.7 50.7c-12-12-28.3-18.7-45.3-18.7H64C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V160c0-35.3-28.7-64-64-64H291.3c-2.1 0-4.2-.8-5.7-2.3z" } }, "free": ["regular", "solid"] }, "folder-minus": { "aliases": { "unicodes": { "secondary": ["10f65d"] } }, "changes": ["5.3.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "archive", "delete", "directory", "document", "file", "negative", "remove" ] }, "styles": ["solid"], "unicode": "f65d", "label": "Folder Minus", "voted": false, "svg": { "solid": { "last_modified": 1684767389, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M448 480H64c-35.3 0-64-28.7-64-64V96C0 60.7 28.7 32 64 32H192c20.1 0 39.1 9.5 51.2 25.6l19.2 25.6c6 8.1 15.5 12.8 25.6 12.8H448c35.3 0 64 28.7 64 64V416c0 35.3-28.7 64-64 64zM184 272c-13.3 0-24 10.7-24 24s10.7 24 24 24H328c13.3 0 24-10.7 24-24s-10.7-24-24-24H184z" } }, "free": ["solid"] }, "folder-open": { "aliases": { "unicodes": { "composite": ["1f4c2", "1f5c1", "f115"], "secondary": ["10f07c"] } }, "changes": ["1.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "Open Folder", "archive", "directory", "document", "empty", "file", "folder", "new", "open", "open file folder" ] }, "styles": ["solid", "regular"], "unicode": "f07c", "label": "Folder Open", "voted": false, "svg": { "solid": { "last_modified": 1684767392, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M88.7 223.8L0 375.8V96C0 60.7 28.7 32 64 32H181.5c17 0 33.3 6.7 45.3 18.7l26.5 26.5c12 12 28.3 18.7 45.3 18.7H416c35.3 0 64 28.7 64 64v32H144c-22.8 0-43.8 12.1-55.3 31.8zm27.6 16.1C122.1 230 132.6 224 144 224H544c11.5 0 22 6.1 27.7 16.1s5.7 22.2-.1 32.1l-112 192C453.9 474 443.4 480 432 480H32c-11.5 0-22-6.1-27.7-16.1s-5.7-22.2 .1-32.1l112-192z" }, "regular": { "last_modified": 1684767392, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M384 480h48c11.4 0 21.9-6 27.6-15.9l112-192c5.8-9.9 5.8-22.1 .1-32.1S555.5 224 544 224H144c-11.4 0-21.9 6-27.6 15.9L48 357.1V96c0-8.8 7.2-16 16-16H181.5c4.2 0 8.3 1.7 11.3 4.7l26.5 26.5c21 21 49.5 32.8 79.2 32.8H416c8.8 0 16 7.2 16 16v32h48V160c0-35.3-28.7-64-64-64H298.5c-17 0-33.3-6.7-45.3-18.7L226.7 50.7c-12-12-28.3-18.7-45.3-18.7H64C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H87.7 384z" } }, "free": ["regular", "solid"] }, "folder-plus": { "aliases": { "unicodes": { "secondary": ["10f65e"] } }, "changes": [ "5.3.0", "5.11.0", "5.12.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "add", "archive", "create", "directory", "document", "file", "new", "positive" ] }, "styles": ["solid"], "unicode": "f65e", "label": "Folder Plus", "voted": false, "svg": { "solid": { "last_modified": 1684767392, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M512 416c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V96C0 60.7 28.7 32 64 32H192c20.1 0 39.1 9.5 51.2 25.6l19.2 25.6c6 8.1 15.5 12.8 25.6 12.8H448c35.3 0 64 28.7 64 64V416zM232 376c0 13.3 10.7 24 24 24s24-10.7 24-24V312h64c13.3 0 24-10.7 24-24s-10.7-24-24-24H280V200c0-13.3-10.7-24-24-24s-24 10.7-24 24v64H168c-13.3 0-24 10.7-24 24s10.7 24 24 24h64v64z" } }, "free": ["solid"] }, "folder-tree": { "aliases": { "unicodes": { "secondary": ["10f802"] } }, "changes": ["5.7.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "archive", "directory", "document", "file", "search", "structure" ] }, "styles": ["solid"], "unicode": "f802", "label": "Folder Tree", "voted": true, "svg": { "solid": { "last_modified": 1684767390, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M64 32C64 14.3 49.7 0 32 0S0 14.3 0 32v96V384c0 35.3 28.7 64 64 64H256V384H64V160H256V96H64V32zM288 192c0 17.7 14.3 32 32 32H544c17.7 0 32-14.3 32-32V64c0-17.7-14.3-32-32-32H445.3c-8.5 0-16.6-3.4-22.6-9.4L409.4 9.4c-6-6-14.1-9.4-22.6-9.4H320c-17.7 0-32 14.3-32 32V192zm0 288c0 17.7 14.3 32 32 32H544c17.7 0 32-14.3 32-32V352c0-17.7-14.3-32-32-32H445.3c-8.5 0-16.6-3.4-22.6-9.4l-13.3-13.3c-6-6-14.1-9.4-22.6-9.4H320c-17.7 0-32 14.3-32 32V480z" } }, "free": ["solid"] }, "font": { "aliases": { "unicodes": { "secondary": ["10f031"] } }, "changes": [ "1.0.0", "5.0.0", "5.9.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["alphabet", "glyph", "text", "type", "typeface"] }, "styles": ["solid"], "unicode": "f031", "label": "Font", "voted": false, "svg": { "solid": { "last_modified": 1684767245, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M254 52.8C249.3 40.3 237.3 32 224 32s-25.3 8.3-30 20.8L57.8 416H32c-17.7 0-32 14.3-32 32s14.3 32 32 32h96c17.7 0 32-14.3 32-32s-14.3-32-32-32h-1.8l18-48H303.8l18 48H320c-17.7 0-32 14.3-32 32s14.3 32 32 32h96c17.7 0 32-14.3 32-32s-14.3-32-32-32H390.2L254 52.8zM279.8 304H168.2L224 155.1 279.8 304z" } }, "free": ["solid"] }, "font-awesome": { "aliases": { "names": ["font-awesome-flag", "font-awesome-logo-full"], "unicodes": { "composite": ["f425", "f4e6"], "primary": ["f4e6"], "secondary": ["10f2b4", "10f4e6"] } }, "changes": [ "4.6.0", "5.0.0", "5.15.4", "6.0.0-beta1", "6.1.2", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["awesome", "flag", "font", "icons", "typeface"] }, "styles": ["solid", "regular", "brands"], "unicode": "f2b4", "label": "Font Awesome", "voted": false, "svg": { "solid": { "last_modified": 1684767246, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M448 48V384c-63.1 22.5-82.3 32-119.5 32c-62.8 0-86.6-32-149.3-32c-20.6 0-36.6 3.6-51.2 8.2v-64c14.6-4.6 30.6-8.2 51.2-8.2c62.7 0 86.5 32 149.3 32c20.4 0 35.6-3 55.5-9.3v-208c-19.9 6.3-35.1 9.3-55.5 9.3c-62.8 0-86.6-32-149.3-32c-50.8 0-74.9 20.6-115.2 28.7V448c0 17.7-14.3 32-32 32s-32-14.3-32-32V64C0 46.3 14.3 32 32 32s32 14.3 32 32V76.7c40.3-8 64.4-28.7 115.2-28.7c62.7 0 86.5 32 149.3 32c37.1 0 56.4-9.5 119.5-32z" }, "regular": { "last_modified": 1684767246, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M48 56c0-13.3-10.7-24-24-24S0 42.7 0 56V456c0 13.3 10.7 24 24 24s24-10.7 24-24V124.2l12.5-2.4c16.7-3.2 31.5-8.5 44.2-13.1l0 0 0 0c3.7-1.3 7.1-2.6 10.4-3.7c15.2-5.2 30.4-9.1 51.2-9.1c25.6 0 43 6 63.5 13.3l.5 .2c20.9 7.4 44.8 15.9 79.1 15.9c32.4 0 53.7-6.8 90.5-19.6V342.9l-9.5 3.3c-41.5 14.4-55.2 19.2-81 19.2c-25.7 0-43.1-6-63.6-13.3l-.6-.2c-20.8-7.4-44.8-15.8-79-15.8c-16.8 0-31 2-43.9 5c-12.9 3-20.9 16-17.9 28.9s16 20.9 28.9 17.9c9.6-2.2 20.1-3.7 32.9-3.7c25.6 0 43 6 63.5 13.3l.5 .2c20.9 7.4 44.8 15.9 79.1 15.9c34.4 0 56.4-7.7 97.8-22.2c7.5-2.6 15.5-5.4 24.4-8.5l16.2-5.5V360 72 38.4L416.2 49.3c-9.7 3.3-18.2 6.3-25.7 8.9c-41.5 14.4-55.2 19.2-81 19.2c-25.7 0-43.1-6-63.6-13.3l-.6-.2c-20.8-7.4-44.8-15.8-79-15.8c-27.8 0-48.5 5.5-66.6 11.6c-4.9 1.7-9.3 3.3-13.6 4.8c-11.9 4.3-22 7.9-34.7 10.3L48 75.4V56z" }, "brands": { "last_modified": 1660014474, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M448 48V384C385 407 366 416 329 416C266 416 242 384 179 384C159 384 143 388 128 392V328C143 324 159 320 179 320C242 320 266 352 329 352C349 352 364 349 384 343V135C364 141 349 144 329 144C266 144 242 112 179 112C128 112 104 133 64 141V448C64 466 50 480 32 480S0 466 0 448V64C0 46 14 32 32 32S64 46 64 64V77C104 69 128 48 179 48C242 48 266 80 329 80C366 80 385 71 448 48Z" } }, "free": ["brands", "regular", "solid"] }, "fonticons": { "changes": ["4.4.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f280", "label": "Fonticons", "voted": false, "svg": { "brands": { "last_modified": 1660014478, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M0 32v448h448V32zm187 140.9c-18.4 0-19 9.9-19 27.4v23.3c0 2.4-3.5 4.4-.6 4.4h67.4l-11.1 37.3H168v112.9c0 5.8-2 6.7 3.2 7.3l43.5 4.1v25.1H84V389l21.3-2c5.2-.6 6.7-2.3 6.7-7.9V267.7c0-2.3-2.9-2.3-5.8-2.3H84V228h28v-21c0-49.6 26.5-70 77.3-70 34.1 0 64.7 8.2 64.7 52.8l-50.7 6.1c.3-18.7-4.4-23-16.3-23zm74.3 241.8v-25.1l20.4-2.6c5.2-.6 7.6-1.7 7.6-7.3V271.8c0-4.1-2.9-6.7-6.7-7.9l-24.2-6.4 6.7-29.5h80.2v151.7c0 5.8-2.6 6.4 2.9 7.3l15.7 2.6v25.1zm80.8-255.5l9 33.2-7.3 7.3-31.2-16.6-31.2 16.6-7.3-7.3 9-33.2-21.8-24.2 3.5-9.6h27.7l15.5-28h9.3l15.5 28h27.7l3.5 9.6z" } }, "free": ["brands"] }, "fonticons-fi": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3a2", "label": "Fonticons Fi", "voted": false, "svg": { "brands": { "last_modified": 1660014476, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M114.4 224h92.4l-15.2 51.2h-76.4V433c0 8-2.8 9.2 4.4 10l59.6 5.6V483H0v-35.2l29.2-2.8c7.2-.8 9.2-3.2 9.2-10.8V278.4c0-3.2-4-3.2-8-3.2H0V224h38.4v-28.8c0-68 36.4-96 106-96 46.8 0 88.8 11.2 88.8 72.4l-69.6 8.4c.4-25.6-6-31.6-22.4-31.6-25.2 0-26 13.6-26 37.6v32c0 3.2-4.8 6-.8 6zM384 483H243.2v-34.4l28-3.6c7.2-.8 10.4-2.4 10.4-10V287c0-5.6-4-9.2-9.2-10.8l-33.2-8.8 9.2-40.4h110v208c0 8-3.6 8.8 4 10l21.6 3.6V483zm-30-347.2l12.4 45.6-10 10-42.8-22.8-42.8 22.8-10-10 12.4-45.6-30-36.4 4.8-10h38L307.2 51H320l21.2 38.4h38l4.8 13.2-30 33.2z" } }, "free": ["brands"] }, "football": { "aliases": { "names": ["football-ball"], "unicodes": { "composite": ["1f3c8"], "secondary": ["10f44e"] } }, "changes": [ "5.0.5", "5.11.0", "5.11.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "american", "american football", "ball", "fall", "football", "nfl", "pigskin", "seasonal" ] }, "styles": ["solid"], "unicode": "f44e", "label": "Football", "voted": false, "svg": { "solid": { "last_modified": 1684767071, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M247.5 25.4c-13.5 3.3-26.4 7.2-38.6 11.7C142.9 61.6 96.7 103.6 66 153.6c-18.3 29.8-30.9 62.3-39.2 95.4L264.5 486.6c13.5-3.3 26.4-7.2 38.6-11.7c66-24.5 112.2-66.5 142.9-116.5c18.3-29.8 30.9-62.3 39.1-95.3L247.5 25.4zM495.2 205.3c6.1-56.8 1.4-112.2-7.7-156.4c-2.7-12.9-13-22.9-26.1-25.1c-58.2-9.7-109.9-12-155.6-7.9L495.2 205.3zM206.1 496L16.8 306.7c-6.1 56.8-1.4 112.2 7.7 156.4c2.7 12.9 13 22.9 26.1 25.1c58.2 9.7 109.9 12 155.6 7.9zm54.6-331.3c6.2-6.2 16.4-6.2 22.6 0l64 64c6.2 6.2 6.2 16.4 0 22.6s-16.4 6.2-22.6 0l-64-64c-6.2-6.2-6.2-16.4 0-22.6zm-48 48c6.2-6.2 16.4-6.2 22.6 0l64 64c6.2 6.2 6.2 16.4 0 22.6s-16.4 6.2-22.6 0l-64-64c-6.2-6.2-6.2-16.4 0-22.6zm-48 48c6.2-6.2 16.4-6.2 22.6 0l64 64c6.2 6.2 6.2 16.4 0 22.6s-16.4 6.2-22.6 0l-64-64c-6.2-6.2-6.2-16.4 0-22.6z" } }, "free": ["solid"] }, "fort-awesome": { "changes": ["4.5.0", "5.0.0", "5.0.3"], "ligatures": [], "search": { "terms": ["castle"] }, "styles": ["brands"], "unicode": "f286", "label": "Fort Awesome", "voted": false, "svg": { "brands": { "last_modified": 1660014464, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M489.2 287.9h-27.4c-2.6 0-4.6 2-4.6 4.6v32h-36.6V146.2c0-2.6-2-4.6-4.6-4.6h-27.4c-2.6 0-4.6 2-4.6 4.6v32h-36.6v-32c0-2.6-2-4.6-4.6-4.6h-27.4c-2.6 0-4.6 2-4.6 4.6v32h-36.6v-32c0-6-8-4.6-11.7-4.6v-38c8.3-2 17.1-3.4 25.7-3.4 10.9 0 20.9 4.3 31.4 4.3 4.6 0 27.7-1.1 27.7-8v-60c0-2.6-2-4.6-4.6-4.6-5.1 0-15.1 4.3-24 4.3-9.7 0-20.9-4.3-32.6-4.3-8 0-16 1.1-23.7 2.9v-4.9c5.4-2.6 9.1-8.3 9.1-14.3 0-20.7-31.4-20.8-31.4 0 0 6 3.7 11.7 9.1 14.3v111.7c-3.7 0-11.7-1.4-11.7 4.6v32h-36.6v-32c0-2.6-2-4.6-4.6-4.6h-27.4c-2.6 0-4.6 2-4.6 4.6v32H128v-32c0-2.6-2-4.6-4.6-4.6H96c-2.6 0-4.6 2-4.6 4.6v178.3H54.8v-32c0-2.6-2-4.6-4.6-4.6H22.8c-2.6 0-4.6 2-4.6 4.6V512h182.9v-96c0-72.6 109.7-72.6 109.7 0v96h182.9V292.5c.1-2.6-1.9-4.6-4.5-4.6zm-288.1-4.5c0 2.6-2 4.6-4.6 4.6h-27.4c-2.6 0-4.6-2-4.6-4.6v-64c0-2.6 2-4.6 4.6-4.6h27.4c2.6 0 4.6 2 4.6 4.6v64zm146.4 0c0 2.6-2 4.6-4.6 4.6h-27.4c-2.6 0-4.6-2-4.6-4.6v-64c0-2.6 2-4.6 4.6-4.6h27.4c2.6 0 4.6 2 4.6 4.6v64z" } }, "free": ["brands"] }, "fort-awesome-alt": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": ["castle"] }, "styles": ["brands"], "unicode": "f3a3", "label": "Alternate Fort Awesome", "voted": false, "svg": { "brands": { "last_modified": 1660014465, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M208 237.4h-22.2c-2.1 0-3.7 1.6-3.7 3.7v51.7c0 2.1 1.6 3.7 3.7 3.7H208c2.1 0 3.7-1.6 3.7-3.7v-51.7c0-2.1-1.6-3.7-3.7-3.7zm118.2 0H304c-2.1 0-3.7 1.6-3.7 3.7v51.7c0 2.1 1.6 3.7 3.7 3.7h22.2c2.1 0 3.7-1.6 3.7-3.7v-51.7c-.1-2.1-1.7-3.7-3.7-3.7zm132-125.1c-2.3-3.2-4.6-6.4-7.1-9.5-9.8-12.5-20.8-24-32.8-34.4-4.5-3.9-9.1-7.6-13.9-11.2-1.6-1.2-3.2-2.3-4.8-3.5C372 34.1 340.3 20 306 13c-16.2-3.3-32.9-5-50-5s-33.9 1.7-50 5c-34.3 7.1-66 21.2-93.3 40.8-1.6 1.1-3.2 2.3-4.8 3.5-4.8 3.6-9.4 7.3-13.9 11.2-3 2.6-5.9 5.3-8.8 8s-5.7 5.5-8.4 8.4c-5.5 5.7-10.7 11.8-15.6 18-2.4 3.1-4.8 6.3-7.1 9.5C25.2 153 8.3 202.5 8.3 256c0 2 .1 4 .1 6 .1.7.1 1.3.1 2 .1 1.3.1 2.7.2 4 0 .8.1 1.5.1 2.3 0 1.3.1 2.5.2 3.7.1.8.1 1.6.2 2.4.1 1.1.2 2.3.3 3.5 0 .8.1 1.6.2 2.4.1 1.2.3 2.4.4 3.6.1.8.2 1.5.3 2.3.1 1.3.3 2.6.5 3.9.1.6.2 1.3.3 1.9l.9 5.7c.1.6.2 1.1.3 1.7.3 1.3.5 2.7.8 4 .2.8.3 1.6.5 2.4.2 1 .5 2.1.7 3.2.2.9.4 1.7.6 2.6.2 1 .4 2 .7 3 .2.9.5 1.8.7 2.7.3 1 .5 1.9.8 2.9.3.9.5 1.8.8 2.7.2.9.5 1.9.8 2.8s.5 1.8.8 2.7c.3 1 .6 1.9.9 2.8.6 1.6 1.1 3.3 1.7 4.9.4 1 .7 1.9 1 2.8.3 1 .7 2 1.1 3 .3.8.6 1.5.9 2.3l1.2 3c.3.7.6 1.5.9 2.2.4 1 .9 2 1.3 3l.9 2.1c.5 1 .9 2 1.4 3 .3.7.6 1.3.9 2 .5 1 1 2.1 1.5 3.1.2.6.5 1.1.8 1.7.6 1.1 1.1 2.2 1.7 3.3.1.2.2.3.3.5 2.2 4.1 4.4 8.2 6.8 12.2.2.4.5.8.7 1.2.7 1.1 1.3 2.2 2 3.3.3.5.6.9.9 1.4.6 1.1 1.3 2.1 2 3.2.3.5.6.9.9 1.4.7 1.1 1.4 2.1 2.1 3.2.2.4.5.8.8 1.2.7 1.1 1.5 2.2 2.3 3.3.2.2.3.5.5.7 37.5 51.7 94.4 88.5 160 99.4.9.1 1.7.3 2.6.4 1 .2 2.1.4 3.1.5s1.9.3 2.8.4c1 .2 2 .3 3 .4.9.1 1.9.2 2.9.3s1.9.2 2.9.3 2.1.2 3.1.3c.9.1 1.8.1 2.7.2 1.1.1 2.3.1 3.4.2.8 0 1.7.1 2.5.1 1.3 0 2.6.1 3.9.1.7.1 1.4.1 2.1.1 2 .1 4 .1 6 .1s4-.1 6-.1c.7 0 1.4-.1 2.1-.1 1.3 0 2.6 0 3.9-.1.8 0 1.7-.1 2.5-.1 1.1-.1 2.3-.1 3.4-.2.9 0 1.8-.1 2.7-.2 1-.1 2.1-.2 3.1-.3s1.9-.2 2.9-.3c.9-.1 1.9-.2 2.9-.3s2-.3 3-.4 1.9-.3 2.8-.4c1-.2 2.1-.3 3.1-.5.9-.1 1.7-.3 2.6-.4 65.6-11 122.5-47.7 160.1-102.4.2-.2.3-.5.5-.7.8-1.1 1.5-2.2 2.3-3.3.2-.4.5-.8.8-1.2.7-1.1 1.4-2.1 2.1-3.2.3-.5.6-.9.9-1.4.6-1.1 1.3-2.1 2-3.2.3-.5.6-.9.9-1.4.7-1.1 1.3-2.2 2-3.3.2-.4.5-.8.7-1.2 2.4-4 4.6-8.1 6.8-12.2.1-.2.2-.3.3-.5.6-1.1 1.1-2.2 1.7-3.3.2-.6.5-1.1.8-1.7.5-1 1-2.1 1.5-3.1.3-.7.6-1.3.9-2 .5-1 1-2 1.4-3l.9-2.1c.5-1 .9-2 1.3-3 .3-.7.6-1.5.9-2.2l1.2-3c.3-.8.6-1.5.9-2.3.4-1 .7-2 1.1-3s.7-1.9 1-2.8c.6-1.6 1.2-3.3 1.7-4.9.3-1 .6-1.9.9-2.8s.5-1.8.8-2.7c.2-.9.5-1.9.8-2.8s.6-1.8.8-2.7c.3-1 .5-1.9.8-2.9.2-.9.5-1.8.7-2.7.2-1 .5-2 .7-3 .2-.9.4-1.7.6-2.6.2-1 .5-2.1.7-3.2.2-.8.3-1.6.5-2.4.3-1.3.6-2.7.8-4 .1-.6.2-1.1.3-1.7l.9-5.7c.1-.6.2-1.3.3-1.9.1-1.3.3-2.6.5-3.9.1-.8.2-1.5.3-2.3.1-1.2.3-2.4.4-3.6 0-.8.1-1.6.2-2.4.1-1.1.2-2.3.3-3.5.1-.8.1-1.6.2-2.4.1 1.7.1.5.2-.7 0-.8.1-1.5.1-2.3.1-1.3.2-2.7.2-4 .1-.7.1-1.3.1-2 .1-2 .1-4 .1-6 0-53.5-16.9-103-45.8-143.7zM448 371.5c-9.4 15.5-20.6 29.9-33.6 42.9-20.6 20.6-44.5 36.7-71.2 48-13.9 5.8-28.2 10.3-42.9 13.2v-75.8c0-58.6-88.6-58.6-88.6 0v75.8c-14.7-2.9-29-7.3-42.9-13.2-26.7-11.3-50.6-27.4-71.2-48-13-13-24.2-27.4-33.6-42.9v-71.3c0-2.1 1.6-3.7 3.7-3.7h22.1c2.1 0 3.7 1.6 3.7 3.7V326h29.6V182c0-2.1 1.6-3.7 3.7-3.7h22.1c2.1 0 3.7 1.6 3.7 3.7v25.9h29.5V182c0-2.1 1.6-3.7 3.7-3.7H208c2.1 0 3.7 1.6 3.7 3.7v25.9h29.5V182c0-4.8 6.5-3.7 9.5-3.7V88.1c-4.4-2-7.4-6.7-7.4-11.5 0-16.8 25.4-16.8 25.4 0 0 4.8-3 9.4-7.4 11.5V92c6.3-1.4 12.7-2.3 19.2-2.3 9.4 0 18.4 3.5 26.3 3.5 7.2 0 15.2-3.5 19.4-3.5 2.1 0 3.7 1.6 3.7 3.7v48.4c0 5.6-18.7 6.5-22.4 6.5-8.6 0-16.6-3.5-25.4-3.5-7 0-14.1 1.2-20.8 2.8v30.7c3 0 9.5-1.1 9.5 3.7v25.9h29.5V182c0-2.1 1.6-3.7 3.7-3.7h22.2c2.1 0 3.7 1.6 3.7 3.7v25.9h29.5V182c0-2.1 1.6-3.7 3.7-3.7h22.1c2.1 0 3.7 1.6 3.7 3.7v144h29.5v-25.8c0-2.1 1.6-3.7 3.7-3.7h22.2c2.1 0 3.7 1.6 3.7 3.7z" } }, "free": ["brands"] }, "forumbee": { "changes": ["4.3.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f211", "label": "Forumbee", "voted": false, "svg": { "brands": { "last_modified": 1660014469, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M5.8 309.7C2 292.7 0 275.5 0 258.3 0 135 99.8 35 223.1 35c16.6 0 33.3 2 49.3 5.5C149 87.5 51.9 186 5.8 309.7zm392.9-189.2C385 103 369 87.8 350.9 75.2c-149.6 44.3-266.3 162.1-309.7 312 12.5 18.1 28 35.6 45.2 49 43.1-151.3 161.2-271.7 312.3-315.7zm15.8 252.7c15.2-25.1 25.4-53.7 29.5-82.8-79.4 42.9-145 110.6-187.6 190.3 30-4.4 58.9-15.3 84.6-31.3 35 13.1 70.9 24.3 107 33.6-9.3-36.5-20.4-74.5-33.5-109.8zm29.7-145.5c-2.6-19.5-7.9-38.7-15.8-56.8C290.5 216.7 182 327.5 137.1 466c18.1 7.6 37 12.5 56.6 15.2C240 367.1 330.5 274.4 444.2 227.7z" } }, "free": ["brands"] }, "forward": { "aliases": { "unicodes": { "composite": ["23e9"], "secondary": ["10f04e"] } }, "changes": ["1.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "arrow", "double", "fast", "fast-forward button", "forward", "next", "skip" ] }, "styles": ["solid"], "unicode": "f04e", "label": "Forward", "voted": false, "svg": { "solid": { "last_modified": 1684766675, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M52.5 440.6c-9.5 7.9-22.8 9.7-34.1 4.4S0 428.4 0 416V96C0 83.6 7.2 72.3 18.4 67s24.5-3.6 34.1 4.4L224 214.3V256v41.7L52.5 440.6zM256 352V256 128 96c0-12.4 7.2-23.7 18.4-29s24.5-3.6 34.1 4.4l192 160c7.3 6.1 11.5 15.1 11.5 24.6s-4.2 18.5-11.5 24.6l-192 160c-9.5 7.9-22.8 9.7-34.1 4.4s-18.4-16.6-18.4-29V352z" } }, "free": ["solid"] }, "forward-fast": { "aliases": { "names": ["fast-forward"], "unicodes": { "composite": ["23ed"], "secondary": ["10f050"] } }, "changes": ["1.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "arrow", "end", "last", "next", "next scene", "next track", "next track button", "triangle" ] }, "styles": ["solid"], "unicode": "f050", "label": "Forward Fast", "voted": false, "svg": { "solid": { "last_modified": 1684766676, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M18.4 445c11.2 5.3 24.5 3.6 34.1-4.4L224 297.7V416c0 12.4 7.2 23.7 18.4 29s24.5 3.6 34.1-4.4L448 297.7V416c0 17.7 14.3 32 32 32s32-14.3 32-32V96c0-17.7-14.3-32-32-32s-32 14.3-32 32V214.3L276.5 71.4c-9.5-7.9-22.8-9.7-34.1-4.4S224 83.6 224 96V214.3L52.5 71.4c-9.5-7.9-22.8-9.7-34.1-4.4S0 83.6 0 96V416c0 12.4 7.2 23.7 18.4 29z" } }, "free": ["solid"] }, "forward-step": { "aliases": { "names": ["step-forward"], "unicodes": { "secondary": ["10f051"] } }, "changes": [ "1.0.0", "5.0.0", "5.10.2", "5.11.0", "5.11.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["end", "last", "next"] }, "styles": ["solid"], "unicode": "f051", "label": "Forward Step", "voted": false, "svg": { "solid": { "last_modified": 1684766677, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M52.5 440.6c-9.5 7.9-22.8 9.7-34.1 4.4S0 428.4 0 416V96C0 83.6 7.2 72.3 18.4 67s24.5-3.6 34.1 4.4l192 160L256 241V96c0-17.7 14.3-32 32-32s32 14.3 32 32V416c0 17.7-14.3 32-32 32s-32-14.3-32-32V271l-11.5 9.6-192 160z" } }, "free": ["solid"] }, "foursquare": { "changes": ["3.2.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f180", "label": "Foursquare", "voted": false, "svg": { "brands": { "last_modified": 1660014479, "raw": "", "viewBox": [0, 0, 368, 512], "width": 368, "height": 512, "path": "M323.1 3H49.9C12.4 3 0 31.3 0 49.1v433.8c0 20.3 12.1 27.7 18.2 30.1 6.2 2.5 22.8 4.6 32.9-7.1C180 356.5 182.2 354 182.2 354c3.1-3.4 3.4-3.1 6.8-3.1h83.4c35.1 0 40.6-25.2 44.3-39.7l48.6-243C373.8 25.8 363.1 3 323.1 3zm-16.3 73.8l-11.4 59.7c-1.2 6.5-9.5 13.2-16.9 13.2H172.1c-12 0-20.6 8.3-20.6 20.3v13c0 12 8.6 20.6 20.6 20.6h90.4c8.3 0 16.6 9.2 14.8 18.2-1.8 8.9-10.5 53.8-11.4 58.8-.9 4.9-6.8 13.5-16.9 13.5h-73.5c-13.5 0-17.2 1.8-26.5 12.6 0 0-8.9 11.4-89.5 108.3-.9.9-1.8.6-1.8-.3V75.9c0-7.7 6.8-16.6 16.6-16.6h219c8.2 0 15.6 7.7 13.5 17.5z" } }, "free": ["brands"] }, "franc-sign": { "changes": ["6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["French Franc Sign", "currency"] }, "styles": ["solid"], "unicode": "e18f", "label": "Franc Sign", "voted": false, "svg": { "solid": { "last_modified": 1684766475, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M80 32C62.3 32 48 46.3 48 64V224v96H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H48v64c0 17.7 14.3 32 32 32s32-14.3 32-32V384h80c17.7 0 32-14.3 32-32s-14.3-32-32-32H112V256H256c17.7 0 32-14.3 32-32s-14.3-32-32-32H112V96H288c17.7 0 32-14.3 32-32s-14.3-32-32-32H80z" } }, "free": ["solid"] }, "free-code-camp": { "changes": ["4.7.0", "5.0.0", "5.12.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f2c5", "label": "freeCodeCamp", "voted": false, "svg": { "brands": { "last_modified": 1660014462, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M97.22,96.21c10.36-10.65,16-17.12,16-21.9,0-2.76-1.92-5.51-3.83-7.42A14.81,14.81,0,0,0,101,64.05c-8.48,0-20.92,8.79-35.84,25.69C23.68,137,2.51,182.81,3.37,250.34s17.47,117,54.06,161.87C76.22,435.86,90.62,448,100.9,448a13.55,13.55,0,0,0,8.37-3.84c1.91-2.76,3.81-5.63,3.81-8.38,0-5.63-3.86-12.2-13.2-20.55-44.45-42.33-67.32-97-67.48-165C32.25,188.8,54,137.83,97.22,96.21ZM239.47,420.07c.58.37.91.55.91.55Zm93.79.55.17-.13C333.24,420.62,333.17,420.67,333.26,420.62Zm3.13-158.18c-16.24-4.15,50.41-82.89-68.05-177.17,0,0,15.54,49.38-62.83,159.57-74.27,104.35,23.46,168.73,34,175.23-6.73-4.35-47.4-35.7,9.55-128.64,11-18.3,25.53-34.87,43.5-72.16,0,0,15.91,22.45,7.6,71.13C287.7,364,354,342.91,355,343.94c22.75,26.78-17.72,73.51-21.58,76.55,5.49-3.65,117.71-78,33-188.1C360.43,238.4,352.62,266.59,336.39,262.44ZM510.88,89.69C496,72.79,483.52,64,475,64a14.81,14.81,0,0,0-8.39,2.84c-1.91,1.91-3.83,4.66-3.83,7.42,0,4.78,5.6,11.26,16,21.9,43.23,41.61,65,92.59,64.82,154.06-.16,68-23,122.63-67.48,165-9.34,8.35-13.18,14.92-13.2,20.55,0,2.75,1.9,5.62,3.81,8.38A13.61,13.61,0,0,0,475.1,448c10.28,0,24.68-12.13,43.47-35.79,36.59-44.85,53.14-94.38,54.06-161.87S552.32,137,510.88,89.69Z" } }, "free": ["brands"] }, "freebsd": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3a4", "label": "FreeBSD", "voted": false, "svg": { "brands": { "last_modified": 1660014476, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M303.7 96.2c11.1-11.1 115.5-77 139.2-53.2 23.7 23.7-42.1 128.1-53.2 139.2-11.1 11.1-39.4.9-63.1-22.9-23.8-23.7-34.1-52-22.9-63.1zM109.9 68.1C73.6 47.5 22 24.6 5.6 41.1c-16.6 16.6 7.1 69.4 27.9 105.7 18.5-32.2 44.8-59.3 76.4-78.7zM406.7 174c3.3 11.3 2.7 20.7-2.7 26.1-20.3 20.3-87.5-27-109.3-70.1-18-32.3-11.1-53.4 14.9-48.7 5.7-3.6 12.3-7.6 19.6-11.6-29.8-15.5-63.6-24.3-99.5-24.3-119.1 0-215.6 96.5-215.6 215.6 0 119 96.5 215.6 215.6 215.6S445.3 380.1 445.3 261c0-38.4-10.1-74.5-27.7-105.8-3.9 7-7.6 13.3-10.9 18.8z" } }, "free": ["brands"] }, "frog": { "aliases": { "unicodes": { "secondary": ["10f52e"] } }, "changes": ["5.0.13", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "amphibian", "bullfrog", "fauna", "hop", "kermit", "kiss", "prince", "ribbit", "toad", "wart" ] }, "styles": ["solid"], "unicode": "f52e", "label": "Frog", "voted": false, "svg": { "solid": { "last_modified": 1684768131, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M368 32c41.7 0 75.9 31.8 79.7 72.5l85.6 26.3c25.4 7.8 42.8 31.3 42.8 57.9c0 21.8-11.7 41.9-30.7 52.7L400.8 323.5 493.3 416H544c17.7 0 32 14.3 32 32s-14.3 32-32 32H480c-8.5 0-16.6-3.4-22.6-9.4L346.9 360.2c11.7-36 3.2-77.1-25.4-105.7c-40.6-40.6-106.3-40.6-146.9-.1L101 324.4c-6.4 6.1-6.7 16.2-.6 22.6s16.2 6.6 22.6 .6l73.8-70.2 .1-.1 .1-.1c3.5-3.5 7.3-6.6 11.3-9.2c27.9-18.5 65.9-15.4 90.5 9.2c24.7 24.7 27.7 62.9 9 90.9c-2.6 3.8-5.6 7.5-9 10.9L261.8 416H352c17.7 0 32 14.3 32 32s-14.3 32-32 32H64c-35.3 0-64-28.7-64-64C0 249.6 127 112.9 289.3 97.5C296.2 60.2 328.8 32 368 32zm0 104a24 24 0 1 0 0-48 24 24 0 1 0 0 48z" } }, "free": ["solid"] }, "fulcrum": { "changes": ["5.0.12", "5.8.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f50b", "label": "Fulcrum", "voted": false, "svg": { "brands": { "last_modified": 1660014469, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M95.75 164.14l-35.38 43.55L25 164.14l35.38-43.55zM144.23 0l-20.54 198.18L72.72 256l51 57.82L144.23 512V300.89L103.15 256l41.08-44.89zm79.67 164.14l35.38 43.55 35.38-43.55-35.38-43.55zm-48.48 47L216.5 256l-41.08 44.89V512L196 313.82 247 256l-51-57.82L175.42 0z" } }, "free": ["brands"] }, "futbol": { "aliases": { "names": ["futbol-ball", "soccer-ball"], "unicodes": { "composite": ["26bd"], "secondary": ["10f1e3"] } }, "changes": [ "4.2.0", "5.0.0", "5.0.5", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0", "6.4.1" ], "ligatures": [], "search": { "terms": ["ball", "football", "mls", "soccer", "soccer ball"] }, "styles": ["solid", "regular"], "unicode": "f1e3", "label": "Futbol", "voted": false, "svg": { "solid": { "last_modified": 1684767071, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M417.3 360.1l-71.6-4.8c-5.2-.3-10.3 1.1-14.5 4.2s-7.2 7.4-8.4 12.5l-17.6 69.6C289.5 445.8 273 448 256 448s-33.5-2.2-49.2-6.4L189.2 372c-1.3-5-4.3-9.4-8.4-12.5s-9.3-4.5-14.5-4.2l-71.6 4.8c-17.6-27.2-28.5-59.2-30.4-93.6L125 228.3c4.4-2.8 7.6-7 9.2-11.9s1.4-10.2-.5-15l-26.7-66.6C128 109.2 155.3 89 186.7 76.9l55.2 46c4 3.3 9 5.1 14.1 5.1s10.2-1.8 14.1-5.1l55.2-46c31.3 12.1 58.7 32.3 79.6 57.9l-26.7 66.6c-1.9 4.8-2.1 10.1-.5 15s4.9 9.1 9.2 11.9l60.7 38.2c-1.9 34.4-12.8 66.4-30.4 93.6zM256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zm14.1-325.7c-8.4-6.1-19.8-6.1-28.2 0L194 221c-8.4 6.1-11.9 16.9-8.7 26.8l18.3 56.3c3.2 9.9 12.4 16.6 22.8 16.6h59.2c10.4 0 19.6-6.7 22.8-16.6l18.3-56.3c3.2-9.9-.3-20.7-8.7-26.8l-47.9-34.8z" }, "regular": { "last_modified": 1684767071, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M435.4 361.3l-89.7-6c-5.2-.3-10.3 1.1-14.5 4.2s-7.2 7.4-8.4 12.5l-22 87.2c-14.4 3.2-29.4 4.8-44.8 4.8s-30.3-1.7-44.8-4.8l-22-87.2c-1.3-5-4.3-9.4-8.4-12.5s-9.3-4.5-14.5-4.2l-89.7 6C61.7 335.9 51.9 307 49 276.2L125 228.3c4.4-2.8 7.6-7 9.2-11.9s1.4-10.2-.5-15L100.4 118c19.9-22.4 44.6-40.5 72.4-52.7l69.1 57.6c4 3.3 9 5.1 14.1 5.1s10.2-1.8 14.1-5.1l69.1-57.6c27.8 12.2 52.5 30.3 72.4 52.7l-33.4 83.4c-1.9 4.8-2.1 10.1-.5 15s4.9 9.1 9.2 11.9L463 276.2c-3 30.8-12.7 59.7-27.6 85.1zM256 48l.9 0h-1.8l.9 0zM56.7 196.2c.9-3 1.9-6.1 2.9-9.1l-2.9 9.1zM132 423l3.8 2.7c-1.3-.9-2.5-1.8-3.8-2.7zm248.1-.1c-1.3 1-2.7 2-4 2.9l4-2.9zm75.2-226.6l-3-9.2c1.1 3 2.1 6.1 3 9.2zM256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zm14.1-325.7c-8.4-6.1-19.8-6.1-28.2 0L194 221c-8.4 6.1-11.9 16.9-8.7 26.8l18.3 56.3c3.2 9.9 12.4 16.6 22.8 16.6h59.2c10.4 0 19.6-6.7 22.8-16.6l18.3-56.3c3.2-9.9-.3-20.7-8.7-26.8l-47.9-34.8z" } }, "free": ["regular", "solid"] }, "g": { "aliases": { "unicodes": { "composite": ["67"] } }, "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Latin Capital Letter G", "Latin Small Letter G", "letter"] }, "styles": ["solid"], "unicode": "47", "label": "G", "voted": false, "svg": { "solid": { "last_modified": 1684767247, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M224 96C135.6 96 64 167.6 64 256s71.6 160 160 160c77.4 0 142-55 156.8-128H256c-17.7 0-32-14.3-32-32s14.3-32 32-32H400c25.8 0 49.6 21.4 47.2 50.6C437.8 389.6 341.4 480 224 480C100.3 480 0 379.7 0 256S100.3 32 224 32c57.4 0 109.7 21.6 149.3 57c13.2 11.8 14.3 32 2.5 45.2s-32 14.3-45.2 2.5C302.3 111.4 265 96 224 96z" } }, "free": ["solid"] }, "galactic-republic": { "changes": ["5.0.12"], "ligatures": [], "search": { "terms": ["politics", "star wars"] }, "styles": ["brands"], "unicode": "f50c", "label": "Galactic Republic", "voted": false, "svg": { "brands": { "last_modified": 1660014475, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M248 504C111.25 504 0 392.75 0 256S111.25 8 248 8s248 111.25 248 248-111.25 248-248 248zm0-479.47C120.37 24.53 16.53 128.37 16.53 256S120.37 487.47 248 487.47 479.47 383.63 479.47 256 375.63 24.53 248 24.53zm27.62 21.81v24.62a185.933 185.933 0 0 1 83.57 34.54l17.39-17.36c-28.75-22.06-63.3-36.89-100.96-41.8zm-55.37.07c-37.64 4.94-72.16 19.8-100.88 41.85l17.28 17.36h.08c24.07-17.84 52.55-30.06 83.52-34.67V46.41zm12.25 50.17v82.87c-10.04 2.03-19.42 5.94-27.67 11.42l-58.62-58.59-21.93 21.93 58.67 58.67c-5.47 8.23-9.45 17.59-11.47 27.62h-82.9v31h82.9c2.02 10.02 6.01 19.31 11.47 27.54l-58.67 58.69 21.93 21.93 58.62-58.62a77.873 77.873 0 0 0 27.67 11.47v82.9h31v-82.9c10.05-2.03 19.37-6.06 27.62-11.55l58.67 58.69 21.93-21.93-58.67-58.69c5.46-8.23 9.47-17.52 11.5-27.54h82.87v-31h-82.87c-2.02-10.02-6.03-19.38-11.5-27.62l58.67-58.67-21.93-21.93-58.67 58.67c-8.25-5.49-17.57-9.47-27.62-11.5V96.58h-31zm183.24 30.72l-17.36 17.36a186.337 186.337 0 0 1 34.67 83.67h24.62c-4.95-37.69-19.83-72.29-41.93-101.03zm-335.55.13c-22.06 28.72-36.91 63.26-41.85 100.91h24.65c4.6-30.96 16.76-59.45 34.59-83.52l-17.39-17.39zM38.34 283.67c4.92 37.64 19.75 72.18 41.8 100.9l17.36-17.39c-17.81-24.07-29.92-52.57-34.51-83.52H38.34zm394.7 0c-4.61 30.99-16.8 59.5-34.67 83.6l17.36 17.36c22.08-28.74 36.98-63.29 41.93-100.96h-24.62zM136.66 406.38l-17.36 17.36c28.73 22.09 63.3 36.98 100.96 41.93v-24.64c-30.99-4.63-59.53-16.79-83.6-34.65zm222.53.05c-24.09 17.84-52.58 30.08-83.57 34.67v24.57c37.67-4.92 72.21-19.79 100.96-41.85l-17.31-17.39h-.08z" } }, "free": ["brands"] }, "galactic-senate": { "changes": ["5.0.12"], "ligatures": [], "search": { "terms": ["star wars"] }, "styles": ["brands"], "unicode": "f50d", "label": "Galactic Senate", "voted": false, "svg": { "brands": { "last_modified": 1660014472, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M249.86 33.48v26.07C236.28 80.17 226 168.14 225.39 274.9c11.74-15.62 19.13-33.33 19.13-48.24v-16.88c-.03-5.32.75-10.53 2.19-15.65.65-2.14 1.39-4.08 2.62-5.82 1.23-1.75 3.43-3.79 6.68-3.79 3.24 0 5.45 2.05 6.68 3.79 1.23 1.75 1.97 3.68 2.62 5.82 1.44 5.12 2.22 10.33 2.19 15.65v16.88c0 14.91 7.39 32.62 19.13 48.24-.63-106.76-10.91-194.73-24.49-215.35V33.48h-12.28zm-26.34 147.77c-9.52 2.15-18.7 5.19-27.46 9.08 8.9 16.12 9.76 32.64 1.71 37.29-8 4.62-21.85-4.23-31.36-19.82-11.58 8.79-21.88 19.32-30.56 31.09 14.73 9.62 22.89 22.92 18.32 30.66-4.54 7.7-20.03 7.14-35.47-.96-5.78 13.25-9.75 27.51-11.65 42.42 9.68.18 18.67 2.38 26.18 6.04 17.78-.3 32.77-1.96 40.49-4.22 5.55-26.35 23.02-48.23 46.32-59.51.73-25.55 1.88-49.67 3.48-72.07zm64.96 0c1.59 22.4 2.75 46.52 3.47 72.07 23.29 11.28 40.77 33.16 46.32 59.51 7.72 2.26 22.71 3.92 40.49 4.22 7.51-3.66 16.5-5.85 26.18-6.04-1.9-14.91-5.86-29.17-11.65-42.42-15.44 8.1-30.93 8.66-35.47.96-4.57-7.74 3.6-21.05 18.32-30.66-8.68-11.77-18.98-22.3-30.56-31.09-9.51 15.59-23.36 24.44-31.36 19.82-8.05-4.65-7.19-21.16 1.71-37.29a147.49 147.49 0 0 0-27.45-9.08zm-32.48 8.6c-3.23 0-5.86 8.81-6.09 19.93h-.05v16.88c0 41.42-49.01 95.04-93.49 95.04-52 0-122.75-1.45-156.37 29.17v2.51c9.42 17.12 20.58 33.17 33.18 47.97C45.7 380.26 84.77 360.4 141.2 360c45.68 1.02 79.03 20.33 90.76 40.87.01.01-.01.04 0 .05 7.67 2.14 15.85 3.23 24.04 3.21 8.19.02 16.37-1.07 24.04-3.21.01-.01-.01-.04 0-.05 11.74-20.54 45.08-39.85 90.76-40.87 56.43.39 95.49 20.26 108.02 41.35 12.6-14.8 23.76-30.86 33.18-47.97v-2.51c-33.61-30.62-104.37-29.17-156.37-29.17-44.48 0-93.49-53.62-93.49-95.04v-16.88h-.05c-.23-11.12-2.86-19.93-6.09-19.93zm0 96.59c22.42 0 40.6 18.18 40.6 40.6s-18.18 40.65-40.6 40.65-40.6-18.23-40.6-40.65c0-22.42 18.18-40.6 40.6-40.6zm0 7.64c-18.19 0-32.96 14.77-32.96 32.96S237.81 360 256 360s32.96-14.77 32.96-32.96-14.77-32.96-32.96-32.96zm0 6.14c14.81 0 26.82 12.01 26.82 26.82s-12.01 26.82-26.82 26.82-26.82-12.01-26.82-26.82 12.01-26.82 26.82-26.82zm-114.8 66.67c-10.19.07-21.6.36-30.5 1.66.43 4.42 1.51 18.63 7.11 29.76 9.11-2.56 18.36-3.9 27.62-3.9 41.28.94 71.48 34.35 78.26 74.47l.11 4.7c10.4 1.91 21.19 2.94 32.21 2.94 11.03 0 21.81-1.02 32.21-2.94l.11-4.7c6.78-40.12 36.98-73.53 78.26-74.47 9.26 0 18.51 1.34 27.62 3.9 5.6-11.13 6.68-25.34 7.11-29.76-8.9-1.3-20.32-1.58-30.5-1.66-18.76.42-35.19 4.17-48.61 9.67-12.54 16.03-29.16 30.03-49.58 33.07-.09.02-.17.04-.27.05-.05.01-.11.04-.16.05-5.24 1.07-10.63 1.6-16.19 1.6-5.55 0-10.95-.53-16.19-1.6-.05-.01-.11-.04-.16-.05-.1-.02-.17-.04-.27-.05-20.42-3.03-37.03-17.04-49.58-33.07-13.42-5.49-29.86-9.25-48.61-9.67z" } }, "free": ["brands"] }, "gamepad": { "aliases": { "unicodes": { "secondary": ["10f11b"] } }, "changes": [ "3.1.0", "5.0.0", "5.11.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "arcade", "controller", "d-pad", "joystick", "video", "video game" ] }, "styles": ["solid"], "unicode": "f11b", "label": "Gamepad", "voted": false, "svg": { "solid": { "last_modified": 1684767071, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M192 64C86 64 0 150 0 256S86 448 192 448H448c106 0 192-86 192-192s-86-192-192-192H192zM496 168a40 40 0 1 1 0 80 40 40 0 1 1 0-80zM392 304a40 40 0 1 1 80 0 40 40 0 1 1 -80 0zM168 200c0-13.3 10.7-24 24-24s24 10.7 24 24v32h32c13.3 0 24 10.7 24 24s-10.7 24-24 24H216v32c0 13.3-10.7 24-24 24s-24-10.7-24-24V280H136c-13.3 0-24-10.7-24-24s10.7-24 24-24h32V200z" } }, "free": ["solid"] }, "gas-pump": { "aliases": { "unicodes": { "composite": ["26fd"], "secondary": ["10f52f"] } }, "changes": [ "5.0.13", "5.10.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "car", "diesel", "fuel", "fuel pump", "fuelpump", "gas", "gasoline", "petrol", "pump", "station" ] }, "styles": ["solid"], "unicode": "f52f", "label": "Gas Pump", "voted": true, "svg": { "solid": { "last_modified": 1684767489, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M32 64C32 28.7 60.7 0 96 0H256c35.3 0 64 28.7 64 64V256h8c48.6 0 88 39.4 88 88v32c0 13.3 10.7 24 24 24s24-10.7 24-24V222c-27.6-7.1-48-32.2-48-62V96L384 64c-8.8-8.8-8.8-23.2 0-32s23.2-8.8 32 0l77.3 77.3c12 12 18.7 28.3 18.7 45.3V168v24 32V376c0 39.8-32.2 72-72 72s-72-32.2-72-72V344c0-22.1-17.9-40-40-40h-8V448c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32V64zM96 80v96c0 8.8 7.2 16 16 16H240c8.8 0 16-7.2 16-16V80c0-8.8-7.2-16-16-16H112c-8.8 0-16 7.2-16 16z" } }, "free": ["solid"] }, "gauge": { "aliases": { "names": ["dashboard", "gauge-med", "tachometer-alt-average"], "unicodes": { "secondary": ["10f624"] } }, "changes": [ "5.2.0", "6.0.0-beta1", "6.0.0-beta3", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["dashboard", "fast", "odometer", "speed", "speedometer"] }, "styles": ["solid"], "unicode": "f624", "label": "Gauge", "voted": false, "svg": { "solid": { "last_modified": 1684767489, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm320 96c0-26.9-16.5-49.9-40-59.3V88c0-13.3-10.7-24-24-24s-24 10.7-24 24V292.7c-23.5 9.5-40 32.5-40 59.3c0 35.3 28.7 64 64 64s64-28.7 64-64zM144 176a32 32 0 1 0 0-64 32 32 0 1 0 0 64zm-16 80a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zm288 32a32 32 0 1 0 0-64 32 32 0 1 0 0 64zM400 144a32 32 0 1 0 -64 0 32 32 0 1 0 64 0z" } }, "free": ["solid"] }, "gauge-high": { "aliases": { "names": ["tachometer-alt", "tachometer-alt-fast"], "unicodes": { "composite": ["f3fd"], "primary": ["f3fd"], "secondary": ["10f3fd", "10f625"] } }, "changes": [ "5.2.0", "6.0.0-beta1", "6.0.0-beta3", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["dashboard", "fast", "odometer", "speed", "speedometer"] }, "styles": ["solid"], "unicode": "f625", "label": "Gauge High", "voted": false, "svg": { "solid": { "last_modified": 1684767488, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zM288 96a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zM256 416c35.3 0 64-28.7 64-64c0-17.4-6.9-33.1-18.1-44.6L366 161.7c5.3-12.1-.2-26.3-12.3-31.6s-26.3 .2-31.6 12.3L257.9 288c-.6 0-1.3 0-1.9 0c-35.3 0-64 28.7-64 64s28.7 64 64 64zM176 144a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zM96 288a32 32 0 1 0 0-64 32 32 0 1 0 0 64zm352-32a32 32 0 1 0 -64 0 32 32 0 1 0 64 0z" } }, "free": ["solid"] }, "gauge-simple": { "aliases": { "names": ["gauge-simple-med", "tachometer-average"], "unicodes": { "secondary": ["10f629"] } }, "changes": [ "5.2.0", "6.0.0-beta1", "6.0.0-beta3", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["dashboard", "fast", "odometer", "speed", "speedometer"] }, "styles": ["solid"], "unicode": "f629", "label": "Gauge Simple", "voted": false, "svg": { "solid": { "last_modified": 1684767489, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm320 96c0-26.9-16.5-49.9-40-59.3V88c0-13.3-10.7-24-24-24s-24 10.7-24 24V292.7c-23.5 9.5-40 32.5-40 59.3c0 35.3 28.7 64 64 64s64-28.7 64-64z" } }, "free": ["solid"] }, "gauge-simple-high": { "aliases": { "names": ["tachometer", "tachometer-fast"], "unicodes": { "composite": ["f0e4"], "primary": ["f0e4"], "secondary": ["10f0e4", "10f62a"] } }, "changes": [ "5.2.0", "6.0.0-beta1", "6.0.0-beta3", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["dashboard", "fast", "odometer", "speed", "speedometer"] }, "styles": ["solid"], "unicode": "f62a", "label": "Gauge Simple High", "voted": false, "svg": { "solid": { "last_modified": 1684767488, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm320 96c0-15.9-5.8-30.4-15.3-41.6l76.6-147.4c6.1-11.8 1.5-26.3-10.2-32.4s-26.2-1.5-32.4 10.2L262.1 288.3c-2-.2-4-.3-6.1-.3c-35.3 0-64 28.7-64 64s28.7 64 64 64s64-28.7 64-64z" } }, "free": ["solid"] }, "gavel": { "aliases": { "names": ["legal"], "unicodes": { "secondary": ["10f0e3"] } }, "changes": ["2.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["hammer", "judge", "law", "lawyer", "opinion"] }, "styles": ["solid"], "unicode": "f0e3", "label": "Gavel", "voted": false, "svg": { "solid": { "last_modified": 1684767603, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M318.6 9.4c-12.5-12.5-32.8-12.5-45.3 0l-120 120c-12.5 12.5-12.5 32.8 0 45.3l16 16c12.5 12.5 32.8 12.5 45.3 0l4-4L325.4 293.4l-4 4c-12.5 12.5-12.5 32.8 0 45.3l16 16c12.5 12.5 32.8 12.5 45.3 0l120-120c12.5-12.5 12.5-32.8 0-45.3l-16-16c-12.5-12.5-32.8-12.5-45.3 0l-4 4L330.6 74.6l4-4c12.5-12.5 12.5-32.8 0-45.3l-16-16zm-152 288c-12.5-12.5-32.8-12.5-45.3 0l-112 112c-12.5 12.5-12.5 32.8 0 45.3l48 48c12.5 12.5 32.8 12.5 45.3 0l112-112c12.5-12.5 12.5-32.8 0-45.3l-1.4-1.4L272 285.3 226.7 240 168 298.7l-1.4-1.4z" } }, "free": ["solid"] }, "gear": { "aliases": { "names": ["cog"], "unicodes": { "composite": ["2699"], "secondary": ["10f013"] } }, "changes": [ "1.0.0", "5.0.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "cog", "cogwheel", "gear", "mechanical", "settings", "sprocket", "tool", "wheel" ] }, "styles": ["solid"], "unicode": "f013", "label": "Gear", "voted": false, "svg": { "solid": { "last_modified": 1684767367, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M495.9 166.6c3.2 8.7 .5 18.4-6.4 24.6l-43.3 39.4c1.1 8.3 1.7 16.8 1.7 25.4s-.6 17.1-1.7 25.4l43.3 39.4c6.9 6.2 9.6 15.9 6.4 24.6c-4.4 11.9-9.7 23.3-15.8 34.3l-4.7 8.1c-6.6 11-14 21.4-22.1 31.2c-5.9 7.2-15.7 9.6-24.5 6.8l-55.7-17.7c-13.4 10.3-28.2 18.9-44 25.4l-12.5 57.1c-2 9.1-9 16.3-18.2 17.8c-13.8 2.3-28 3.5-42.5 3.5s-28.7-1.2-42.5-3.5c-9.2-1.5-16.2-8.7-18.2-17.8l-12.5-57.1c-15.8-6.5-30.6-15.1-44-25.4L83.1 425.9c-8.8 2.8-18.6 .3-24.5-6.8c-8.1-9.8-15.5-20.2-22.1-31.2l-4.7-8.1c-6.1-11-11.4-22.4-15.8-34.3c-3.2-8.7-.5-18.4 6.4-24.6l43.3-39.4C64.6 273.1 64 264.6 64 256s.6-17.1 1.7-25.4L22.4 191.2c-6.9-6.2-9.6-15.9-6.4-24.6c4.4-11.9 9.7-23.3 15.8-34.3l4.7-8.1c6.6-11 14-21.4 22.1-31.2c5.9-7.2 15.7-9.6 24.5-6.8l55.7 17.7c13.4-10.3 28.2-18.9 44-25.4l12.5-57.1c2-9.1 9-16.3 18.2-17.8C227.3 1.2 241.5 0 256 0s28.7 1.2 42.5 3.5c9.2 1.5 16.2 8.7 18.2 17.8l12.5 57.1c15.8 6.5 30.6 15.1 44 25.4l55.7-17.7c8.8-2.8 18.6-.3 24.5 6.8c8.1 9.8 15.5 20.2 22.1 31.2l4.7 8.1c6.1 11 11.4 22.4 15.8 34.3zM256 336a80 80 0 1 0 0-160 80 80 0 1 0 0 160z" } }, "free": ["solid"] }, "gears": { "aliases": { "names": ["cogs"], "unicodes": { "secondary": ["10f085"] } }, "changes": [ "1.0.0", "5.0.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["gears", "mechanical", "settings", "sprocket", "wheel"] }, "styles": ["solid"], "unicode": "f085", "label": "Gears", "voted": false, "svg": { "solid": { "last_modified": 1684767366, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M308.5 135.3c7.1-6.3 9.9-16.2 6.2-25c-2.3-5.3-4.8-10.5-7.6-15.5L304 89.4c-3-5-6.3-9.9-9.8-14.6c-5.7-7.6-15.7-10.1-24.7-7.1l-28.2 9.3c-10.7-8.8-23-16-36.2-20.9L199 27.1c-1.9-9.3-9.1-16.7-18.5-17.8C173.9 8.4 167.2 8 160.4 8h-.7c-6.8 0-13.5 .4-20.1 1.2c-9.4 1.1-16.6 8.6-18.5 17.8L115 56.1c-13.3 5-25.5 12.1-36.2 20.9L50.5 67.8c-9-3-19-.5-24.7 7.1c-3.5 4.7-6.8 9.6-9.9 14.6l-3 5.3c-2.8 5-5.3 10.2-7.6 15.6c-3.7 8.7-.9 18.6 6.2 25l22.2 19.8C32.6 161.9 32 168.9 32 176s.6 14.1 1.7 20.9L11.5 216.7c-7.1 6.3-9.9 16.2-6.2 25c2.3 5.3 4.8 10.5 7.6 15.6l3 5.2c3 5.1 6.3 9.9 9.9 14.6c5.7 7.6 15.7 10.1 24.7 7.1l28.2-9.3c10.7 8.8 23 16 36.2 20.9l6.1 29.1c1.9 9.3 9.1 16.7 18.5 17.8c6.7 .8 13.5 1.2 20.4 1.2s13.7-.4 20.4-1.2c9.4-1.1 16.6-8.6 18.5-17.8l6.1-29.1c13.3-5 25.5-12.1 36.2-20.9l28.2 9.3c9 3 19 .5 24.7-7.1c3.5-4.7 6.8-9.5 9.8-14.6l3.1-5.4c2.8-5 5.3-10.2 7.6-15.5c3.7-8.7 .9-18.6-6.2-25l-22.2-19.8c1.1-6.8 1.7-13.8 1.7-20.9s-.6-14.1-1.7-20.9l22.2-19.8zM112 176a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zM504.7 500.5c6.3 7.1 16.2 9.9 25 6.2c5.3-2.3 10.5-4.8 15.5-7.6l5.4-3.1c5-3 9.9-6.3 14.6-9.8c7.6-5.7 10.1-15.7 7.1-24.7l-9.3-28.2c8.8-10.7 16-23 20.9-36.2l29.1-6.1c9.3-1.9 16.7-9.1 17.8-18.5c.8-6.7 1.2-13.5 1.2-20.4s-.4-13.7-1.2-20.4c-1.1-9.4-8.6-16.6-17.8-18.5L583.9 307c-5-13.3-12.1-25.5-20.9-36.2l9.3-28.2c3-9 .5-19-7.1-24.7c-4.7-3.5-9.6-6.8-14.6-9.9l-5.3-3c-5-2.8-10.2-5.3-15.6-7.6c-8.7-3.7-18.6-.9-25 6.2l-19.8 22.2c-6.8-1.1-13.8-1.7-20.9-1.7s-14.1 .6-20.9 1.7l-19.8-22.2c-6.3-7.1-16.2-9.9-25-6.2c-5.3 2.3-10.5 4.8-15.6 7.6l-5.2 3c-5.1 3-9.9 6.3-14.6 9.9c-7.6 5.7-10.1 15.7-7.1 24.7l9.3 28.2c-8.8 10.7-16 23-20.9 36.2L315.1 313c-9.3 1.9-16.7 9.1-17.8 18.5c-.8 6.7-1.2 13.5-1.2 20.4s.4 13.7 1.2 20.4c1.1 9.4 8.6 16.6 17.8 18.5l29.1 6.1c5 13.3 12.1 25.5 20.9 36.2l-9.3 28.2c-3 9-.5 19 7.1 24.7c4.7 3.5 9.5 6.8 14.6 9.8l5.4 3.1c5 2.8 10.2 5.3 15.5 7.6c8.7 3.7 18.6 .9 25-6.2l19.8-22.2c6.8 1.1 13.8 1.7 20.9 1.7s14.1-.6 20.9-1.7l19.8 22.2zM464 304a48 48 0 1 1 0 96 48 48 0 1 1 0-96z" } }, "free": ["solid"] }, "gem": { "aliases": { "unicodes": { "composite": ["1f48e"], "secondary": ["10f3a5"] } }, "changes": [ "5.0.0", "5.10.1", "6.0.0-beta1", "6.2.0", "6.2.1", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "diamond", "gem", "gem stone", "jewel", "jewelry", "sapphire", "stone", "treasure" ] }, "styles": ["solid", "regular"], "unicode": "f3a5", "label": "Gem", "voted": false, "svg": { "solid": { "last_modified": 1684767602, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M116.7 33.8c4.5-6.1 11.7-9.8 19.3-9.8H376c7.6 0 14.8 3.6 19.3 9.8l112 152c6.8 9.2 6.1 21.9-1.5 30.4l-232 256c-4.5 5-11 7.9-17.8 7.9s-13.2-2.9-17.8-7.9l-232-256c-7.7-8.5-8.3-21.2-1.5-30.4l112-152zm38.5 39.8c-3.3 2.5-4.2 7-2.1 10.5l57.4 95.6L63.3 192c-4.1 .3-7.3 3.8-7.3 8s3.2 7.6 7.3 8l192 16c.4 0 .9 0 1.3 0l192-16c4.1-.3 7.3-3.8 7.3-8s-3.2-7.6-7.3-8L301.5 179.8l57.4-95.6c2.1-3.5 1.2-8.1-2.1-10.5s-7.9-2-10.7 1L256 172.2 165.9 74.6c-2.8-3-7.4-3.4-10.7-1z" }, "regular": { "last_modified": 1684767602, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M168.5 72L256 165l87.5-93h-175zM383.9 99.1L311.5 176h129L383.9 99.1zm50 124.9H256 78.1L256 420.3 433.9 224zM71.5 176h129L128.1 99.1 71.5 176zm434.3 40.1l-232 256c-4.5 5-11 7.9-17.8 7.9s-13.2-2.9-17.8-7.9l-232-256c-7.7-8.5-8.3-21.2-1.5-30.4l112-152c4.5-6.1 11.7-9.8 19.3-9.8H376c7.6 0 14.8 3.6 19.3 9.8l112 152c6.8 9.2 6.1 21.9-1.5 30.4z" } }, "free": ["regular", "solid"] }, "genderless": { "aliases": { "unicodes": { "secondary": ["10f22d"] } }, "changes": [ "4.4.0", "5.0.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["androgynous", "asexual", "gender", "sexless"] }, "styles": ["solid"], "unicode": "f22d", "label": "Genderless", "voted": false, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M192 144a112 112 0 1 1 0 224 112 112 0 1 1 0-224zm0 288a176 176 0 1 0 0-352 176 176 0 1 0 0 352z" } }, "free": ["solid"] }, "get-pocket": { "changes": ["4.4.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f265", "label": "Get Pocket", "voted": false, "svg": { "brands": { "last_modified": 1660014462, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M407.6 64h-367C18.5 64 0 82.5 0 104.6v135.2C0 364.5 99.7 464 224.2 464c124 0 223.8-99.5 223.8-224.2V104.6c0-22.4-17.7-40.6-40.4-40.6zm-162 268.5c-12.4 11.8-31.4 11.1-42.4 0C89.5 223.6 88.3 227.4 88.3 209.3c0-16.9 13.8-30.7 30.7-30.7 17 0 16.1 3.8 105.2 89.3 90.6-86.9 88.6-89.3 105.5-89.3 16.9 0 30.7 13.8 30.7 30.7 0 17.8-2.9 15.7-114.8 123.2z" } }, "free": ["brands"] }, "gg": { "changes": ["4.4.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f260", "label": "GG Currency", "voted": false, "svg": { "brands": { "last_modified": 1660014471, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M179.2 230.4l102.4 102.4-102.4 102.4L0 256 179.2 76.8l44.8 44.8-25.6 25.6-19.2-19.2-128 128 128 128 51.5-51.5-77.1-76.5 25.6-25.6zM332.8 76.8L230.4 179.2l102.4 102.4 25.6-25.6-77.1-76.5 51.5-51.5 128 128-128 128-19.2-19.2-25.6 25.6 44.8 44.8L512 256 332.8 76.8z" } }, "free": ["brands"] }, "gg-circle": { "changes": ["4.4.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f261", "label": "GG Currency Circle", "voted": false, "svg": { "brands": { "last_modified": 1660014464, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M257 8C120 8 9 119 9 256s111 248 248 248 248-111 248-248S394 8 257 8zm-49.5 374.8L81.8 257.1l125.7-125.7 35.2 35.4-24.2 24.2-11.1-11.1-77.2 77.2 77.2 77.2 26.6-26.6-53.1-52.9 24.4-24.4 77.2 77.2-75 75.2zm99-2.2l-35.2-35.2 24.1-24.4 11.1 11.1 77.2-77.2-77.2-77.2-26.5 26.5 53.1 52.9-24.4 24.4-77.2-77.2 75-75L432.2 255 306.5 380.6z" } }, "free": ["brands"] }, "ghost": { "aliases": { "unicodes": { "composite": ["1f47b"], "secondary": ["10f6e2"] } }, "changes": ["5.4.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "apparition", "blinky", "clyde", "creature", "face", "fairy tale", "fantasy", "floating", "ghost", "halloween", "holiday", "inky", "monster", "pacman", "pinky", "spirit" ] }, "styles": ["solid"], "unicode": "f6e2", "label": "Ghost", "voted": false, "svg": { "solid": { "last_modified": 1684767603, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M40.1 467.1l-11.2 9c-3.2 2.5-7.1 3.9-11.1 3.9C8 480 0 472 0 462.2V192C0 86 86 0 192 0S384 86 384 192V462.2c0 9.8-8 17.8-17.8 17.8c-4 0-7.9-1.4-11.1-3.9l-11.2-9c-13.4-10.7-32.8-9-44.1 3.9L269.3 506c-3.3 3.8-8.2 6-13.3 6s-9.9-2.2-13.3-6l-26.6-30.5c-12.7-14.6-35.4-14.6-48.2 0L141.3 506c-3.3 3.8-8.2 6-13.3 6s-9.9-2.2-13.3-6L84.2 471c-11.3-12.9-30.7-14.6-44.1-3.9zM160 192a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zm96 32a32 32 0 1 0 0-64 32 32 0 1 0 0 64z" } }, "free": ["solid"] }, "gift": { "aliases": { "unicodes": { "composite": ["1f381"], "secondary": ["10f06b"] } }, "changes": [ "1.0.0", "5.0.0", "5.0.9", "5.6.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "box", "celebration", "christmas", "generosity", "gift", "giving", "holiday", "party", "present", "wrapped", "wrapped gift", "xmas" ] }, "styles": ["solid"], "unicode": "f06b", "label": "Gift", "voted": false, "svg": { "solid": { "last_modified": 1684766476, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M190.5 68.8L225.3 128H224 152c-22.1 0-40-17.9-40-40s17.9-40 40-40h2.2c14.9 0 28.8 7.9 36.3 20.8zM64 88c0 14.4 3.5 28 9.6 40H32c-17.7 0-32 14.3-32 32v64c0 17.7 14.3 32 32 32H480c17.7 0 32-14.3 32-32V160c0-17.7-14.3-32-32-32H438.4c6.1-12 9.6-25.6 9.6-40c0-48.6-39.4-88-88-88h-2.2c-31.9 0-61.5 16.9-77.7 44.4L256 85.5l-24.1-41C215.7 16.9 186.1 0 154.2 0H152C103.4 0 64 39.4 64 88zm336 0c0 22.1-17.9 40-40 40H288h-1.3l34.8-59.2C329.1 55.9 342.9 48 357.8 48H360c22.1 0 40 17.9 40 40zM32 288V464c0 26.5 21.5 48 48 48H224V288H32zM288 512H432c26.5 0 48-21.5 48-48V288H288V512z" } }, "free": ["solid"] }, "gifts": { "aliases": { "unicodes": { "secondary": ["10f79c"] } }, "changes": [ "5.6.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "christmas", "generosity", "giving", "holiday", "party", "present", "wrapped", "xmas" ] }, "styles": ["solid"], "unicode": "f79c", "label": "Gifts", "voted": false, "svg": { "solid": { "last_modified": 1684766474, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M200.6 32C205 19.5 198.5 5.8 186 1.4S159.8 3.5 155.4 16L144.7 46.2l-9.9-29.8C130.6 3.8 117-3 104.4 1.2S85 19 89.2 31.6l8.3 25-27.4-20c-10.7-7.8-25.7-5.4-33.5 5.3s-5.4 25.7 5.3 33.5L70.2 96H48C21.5 96 0 117.5 0 144V464c0 26.5 21.5 48 48 48H200.6c-5.4-9.4-8.6-20.3-8.6-32V256c0-29.9 20.5-55 48.2-62c1.8-31 17.1-58.2 40.1-76.1C271.7 104.7 256.9 96 240 96H217.8l28.3-20.6c10.7-7.8 13.1-22.8 5.3-33.5s-22.8-13.1-33.5-5.3L192.5 55.1 200.6 32zM363.5 185.5L393.1 224H344c-13.3 0-24-10.7-24-24c0-13.1 10.8-24 24.2-24c7.6 0 14.7 3.5 19.3 9.5zM272 200c0 8.4 1.4 16.5 4.1 24H272c-26.5 0-48 21.5-48 48v80H416V256h32v96H640V272c0-26.5-21.5-48-48-48h-4.1c2.7-7.5 4.1-15.6 4.1-24c0-39.9-32.5-72-72.2-72c-22.4 0-43.6 10.4-57.3 28.2L432 195.8l-30.5-39.6c-13.7-17.8-35-28.2-57.3-28.2c-39.7 0-72.2 32.1-72.2 72zM224 464c0 26.5 21.5 48 48 48H416V384H224v80zm224 48H592c26.5 0 48-21.5 48-48V384H448V512zm96-312c0 13.3-10.7 24-24 24H470.9l29.6-38.5c4.6-5.9 11.7-9.5 19.3-9.5c13.4 0 24.2 10.9 24.2 24z" } }, "free": ["solid"] }, "git": { "changes": ["4.1.0", "5.0.0", "5.8.2"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f1d3", "label": "Git", "voted": false, "svg": { "brands": { "last_modified": 1660014462, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M216.29 158.39H137C97 147.9 6.51 150.63 6.51 233.18c0 30.09 15 51.23 35 61-25.1 23-37 33.85-37 49.21 0 11 4.47 21.14 17.89 26.81C8.13 383.61 0 393.35 0 411.65c0 32.11 28.05 50.82 101.63 50.82 70.75 0 111.79-26.42 111.79-73.18 0-58.66-45.16-56.5-151.63-63l13.43-21.55c27.27 7.58 118.7 10 118.7-67.89 0-18.7-7.73-31.71-15-41.07l37.41-2.84zm-63.42 241.9c0 32.06-104.89 32.1-104.89 2.43 0-8.14 5.27-15 10.57-21.54 77.71 5.3 94.32 3.37 94.32 19.11zm-50.81-134.58c-52.8 0-50.46-71.16 1.2-71.16 49.54 0 50.82 71.16-1.2 71.16zm133.3 100.51v-32.1c26.75-3.66 27.24-2 27.24-11V203.61c0-8.5-2.05-7.38-27.24-16.26l4.47-32.92H324v168.71c0 6.51.4 7.32 6.51 8.14l20.73 2.84v32.1zm52.45-244.31c-23.17 0-36.59-13.43-36.59-36.61s13.42-35.77 36.59-35.77c23.58 0 37 12.62 37 35.77s-13.42 36.61-37 36.61zM512 350.46c-17.49 8.53-43.1 16.26-66.28 16.26-48.38 0-66.67-19.5-66.67-65.46V194.75c0-5.42 1.05-4.06-31.71-4.06V154.5c35.78-4.07 50-22 54.47-66.27h38.63c0 65.83-1.34 61.81 3.26 61.81H501v40.65h-60.56v97.15c0 6.92-4.92 51.41 60.57 26.84z" } }, "free": ["brands"] }, "git-alt": { "changes": ["5.8.2"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f841", "label": "Git Alt", "voted": false, "svg": { "brands": { "last_modified": 1660014478, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M439.55 236.05L244 40.45a28.87 28.87 0 0 0-40.81 0l-40.66 40.63 51.52 51.52c27.06-9.14 52.68 16.77 43.39 43.68l49.66 49.66c34.23-11.8 61.18 31 35.47 56.69-26.49 26.49-70.21-2.87-56-37.34L240.22 199v121.85c25.3 12.54 22.26 41.85 9.08 55a34.34 34.34 0 0 1-48.55 0c-17.57-17.6-11.07-46.91 11.25-56v-123c-20.8-8.51-24.6-30.74-18.64-45L142.57 101 8.45 235.14a28.86 28.86 0 0 0 0 40.81l195.61 195.6a28.86 28.86 0 0 0 40.8 0l194.69-194.69a28.86 28.86 0 0 0 0-40.81z" } }, "free": ["brands"] }, "github": { "changes": ["2.0.0", "5.0.0"], "ligatures": [], "search": { "terms": ["octocat"] }, "styles": ["brands"], "unicode": "f09b", "label": "GitHub", "voted": false, "svg": { "brands": { "last_modified": 1660014462, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z" } }, "free": ["brands"] }, "github-alt": { "changes": ["3.0.0", "5.0.0"], "ligatures": [], "search": { "terms": ["octocat"] }, "styles": ["brands"], "unicode": "f113", "label": "Alternate GitHub", "voted": false, "svg": { "brands": { "last_modified": 1660014479, "raw": "", "viewBox": [0, 0, 480, 512], "width": 480, "height": 512, "path": "M186.1 328.7c0 20.9-10.9 55.1-36.7 55.1s-36.7-34.2-36.7-55.1 10.9-55.1 36.7-55.1 36.7 34.2 36.7 55.1zM480 278.2c0 31.9-3.2 65.7-17.5 95-37.9 76.6-142.1 74.8-216.7 74.8-75.8 0-186.2 2.7-225.6-74.8-14.6-29-20.2-63.1-20.2-95 0-41.9 13.9-81.5 41.5-113.6-5.2-15.8-7.7-32.4-7.7-48.8 0-21.5 4.9-32.3 14.6-51.8 45.3 0 74.3 9 108.8 36 29-6.9 58.8-10 88.7-10 27 0 54.2 2.9 80.4 9.2 34-26.7 63-35.2 107.8-35.2 9.8 19.5 14.6 30.3 14.6 51.8 0 16.4-2.6 32.7-7.7 48.2 27.5 32.4 39 72.3 39 114.2zm-64.3 50.5c0-43.9-26.7-82.6-73.5-82.6-18.9 0-37 3.4-56 6-14.9 2.3-29.8 3.2-45.1 3.2-15.2 0-30.1-.9-45.1-3.2-18.7-2.6-37-6-56-6-46.8 0-73.5 38.7-73.5 82.6 0 87.8 80.4 101.3 150.4 101.3h48.2c70.3 0 150.6-13.4 150.6-101.3zm-82.6-55.1c-25.8 0-36.7 34.2-36.7 55.1s10.9 55.1 36.7 55.1 36.7-34.2 36.7-55.1-10.9-55.1-36.7-55.1z" } }, "free": ["brands"] }, "gitkraken": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3a6", "label": "GitKraken", "voted": false, "svg": { "brands": { "last_modified": 1660014473, "raw": "", "viewBox": [0, 0, 592, 512], "width": 592, "height": 512, "path": "M565.7 118.1c-2.3-6.1-9.3-9.2-15.3-6.6-5.7 2.4-8.5 8.9-6.3 14.6 10.9 29 16.9 60.5 16.9 93.3 0 134.6-100.3 245.7-230.2 262.7V358.4c7.9-1.5 15.5-3.6 23-6.2v104c106.7-25.9 185.9-122.1 185.9-236.8 0-91.8-50.8-171.8-125.8-213.3-5.7-3.2-13-.9-15.9 5-2.7 5.5-.6 12.2 4.7 15.1 67.9 37.6 113.9 110 113.9 193.2 0 93.3-57.9 173.1-139.8 205.4v-92.2c14.2-4.5 24.9-17.7 24.9-33.5 0-13.1-6.8-24.4-17.3-30.5 8.3-79.5 44.5-58.6 44.5-83.9V170c0-38-87.9-161.8-129-164.7-2.5-.2-5-.2-7.6 0C251.1 8.3 163.2 132 163.2 170v14.8c0 25.3 36.3 4.3 44.5 83.9-10.6 6.1-17.3 17.4-17.3 30.5 0 15.8 10.6 29 24.8 33.5v92.2c-81.9-32.2-139.8-112-139.8-205.4 0-83.1 46-155.5 113.9-193.2 5.4-3 7.4-9.6 4.7-15.1-2.9-5.9-10.1-8.2-15.9-5-75 41.5-125.8 121.5-125.8 213.3 0 114.7 79.2 210.8 185.9 236.8v-104c7.6 2.5 15.1 4.6 23 6.2v123.7C131.4 465.2 31 354.1 31 219.5c0-32.8 6-64.3 16.9-93.3 2.2-5.8-.6-12.2-6.3-14.6-6-2.6-13 .4-15.3 6.6C14.5 149.7 8 183.8 8 219.5c0 155.1 122.6 281.6 276.3 287.8V361.4c6.8.4 15 .5 23.4 0v145.8C461.4 501.1 584 374.6 584 219.5c0-35.7-6.5-69.8-18.3-101.4zM365.9 275.5c13 0 23.7 10.5 23.7 23.7 0 13.1-10.6 23.7-23.7 23.7-13 0-23.7-10.5-23.7-23.7 0-13.1 10.6-23.7 23.7-23.7zm-139.8 47.3c-13.2 0-23.7-10.7-23.7-23.7s10.5-23.7 23.7-23.7c13.1 0 23.7 10.6 23.7 23.7 0 13-10.5 23.7-23.7 23.7z" } }, "free": ["brands"] }, "gitlab": { "changes": ["4.6.0", "5.0.0", "5.7.0", "6.0.0-beta1", "6.1.2"], "ligatures": [], "search": { "terms": ["Axosoft"] }, "styles": ["brands"], "unicode": "f296", "label": "GitLab", "voted": false, "svg": { "brands": { "last_modified": 1660014471, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M503.5 204.6L502.8 202.8L433.1 21.02C431.7 17.45 429.2 14.43 425.9 12.38C423.5 10.83 420.8 9.865 417.9 9.57C415 9.275 412.2 9.653 409.5 10.68C406.8 11.7 404.4 13.34 402.4 15.46C400.5 17.58 399.1 20.13 398.3 22.9L351.3 166.9H160.8L113.7 22.9C112.9 20.13 111.5 17.59 109.6 15.47C107.6 13.35 105.2 11.72 102.5 10.7C99.86 9.675 96.98 9.295 94.12 9.587C91.26 9.878 88.51 10.83 86.08 12.38C82.84 14.43 80.33 17.45 78.92 21.02L9.267 202.8L8.543 204.6C-1.484 230.8-2.72 259.6 5.023 286.6C12.77 313.5 29.07 337.3 51.47 354.2L51.74 354.4L52.33 354.8L158.3 434.3L210.9 474L242.9 498.2C246.6 500.1 251.2 502.5 255.9 502.5C260.6 502.5 265.2 500.1 268.9 498.2L300.9 474L353.5 434.3L460.2 354.4L460.5 354.1C482.9 337.2 499.2 313.5 506.1 286.6C514.7 259.6 513.5 230.8 503.5 204.6z" } }, "free": ["brands"] }, "gitter": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f426", "label": "Gitter", "voted": false, "svg": { "brands": { "last_modified": 1660014464, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M66.4 322.5H16V0h50.4v322.5zM166.9 76.1h-50.4V512h50.4V76.1zm100.6 0h-50.4V512h50.4V76.1zM368 76h-50.4v247H368V76z" } }, "free": ["brands"] }, "glass-water": { "changes": ["6.1.0", "6.1.2", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["potable", "water"] }, "styles": ["solid"], "unicode": "e4f4", "label": "Glass Water", "voted": false, "svg": { "solid": { "last_modified": 1684767419, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M32 0C23.1 0 14.6 3.7 8.6 10.2S-.6 25.4 .1 34.3L28.9 437.7c3 41.9 37.8 74.3 79.8 74.3H275.3c42 0 76.8-32.4 79.8-74.3L383.9 34.3c.6-8.9-2.4-17.6-8.5-24.1S360.9 0 352 0H32zM73 156.5L66.4 64H317.6L311 156.5l-24.2 12.1c-19.4 9.7-42.2 9.7-61.6 0c-20.9-10.4-45.5-10.4-66.4 0c-19.4 9.7-42.2 9.7-61.6 0L73 156.5z" } }, "free": ["solid"] }, "glass-water-droplet": { "changes": ["6.1.0", "6.1.2", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["potable", "water"] }, "styles": ["solid"], "unicode": "e4f5", "label": "Glass Water Droplet", "voted": false, "svg": { "solid": { "last_modified": 1684767419, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M32 0C23.1 0 14.6 3.7 8.6 10.2S-.6 25.4 .1 34.3L28.9 437.7c3 41.9 37.8 74.3 79.8 74.3H275.3c42 0 76.8-32.4 79.8-74.3L383.9 34.3c.6-8.9-2.4-17.6-8.5-24.1S360.9 0 352 0H32zM83 297.5L66.4 64H317.6L301 297.5 288 304c-20.1 10.1-43.9 10.1-64 0s-43.9-10.1-64 0s-43.9 10.1-64 0l-13-6.5zM256 196c0-24-33.7-70.1-52.2-93.5c-6.1-7.7-17.5-7.7-23.6 0C161.7 125.9 128 172 128 196c0 33.1 28.7 60 64 60s64-26.9 64-60z" } }, "free": ["solid"] }, "glasses": { "aliases": { "unicodes": { "secondary": ["10f530"] } }, "changes": ["5.0.13", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["hipster", "nerd", "reading", "sight", "spectacles", "vision"] }, "styles": ["solid"], "unicode": "f530", "label": "Glasses", "voted": true, "svg": { "solid": { "last_modified": 1684767603, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M118.6 80c-11.5 0-21.4 7.9-24 19.1L57 260.3c20.5-6.2 48.3-12.3 78.7-12.3c32.3 0 61.8 6.9 82.8 13.5c10.6 3.3 19.3 6.7 25.4 9.2c3.1 1.3 5.5 2.4 7.3 3.2c.9 .4 1.6 .7 2.1 1l.6 .3 .2 .1 .1 0 0 0 0 0s0 0-6.3 12.7h0l6.3-12.7c5.8 2.9 10.4 7.3 13.5 12.7h40.6c3.1-5.3 7.7-9.8 13.5-12.7l6.3 12.7h0c-6.3-12.7-6.3-12.7-6.3-12.7l0 0 0 0 .1 0 .2-.1 .6-.3c.5-.2 1.2-.6 2.1-1c1.8-.8 4.2-1.9 7.3-3.2c6.1-2.6 14.8-5.9 25.4-9.2c21-6.6 50.4-13.5 82.8-13.5c30.4 0 58.2 6.1 78.7 12.3L481.4 99.1c-2.6-11.2-12.6-19.1-24-19.1c-3.1 0-6.2 .6-9.2 1.8L416.9 94.3c-12.3 4.9-26.3-1.1-31.2-13.4s1.1-26.3 13.4-31.2l31.3-12.5c8.6-3.4 17.7-5.2 27-5.2c33.8 0 63.1 23.3 70.8 56.2l43.9 188c1.7 7.3 2.9 14.7 3.5 22.1c.3 1.9 .5 3.8 .5 5.7v6.7V352v16c0 61.9-50.1 112-112 112H419.7c-59.4 0-108.5-46.4-111.8-105.8L306.6 352H269.4l-1.2 22.2C264.9 433.6 215.8 480 156.3 480H112C50.1 480 0 429.9 0 368V352 310.7 304c0-1.9 .2-3.8 .5-5.7c.6-7.4 1.8-14.8 3.5-22.1l43.9-188C55.5 55.3 84.8 32 118.6 32c9.2 0 18.4 1.8 27 5.2l31.3 12.5c12.3 4.9 18.3 18.9 13.4 31.2s-18.9 18.3-31.2 13.4L127.8 81.8c-2.9-1.2-6-1.8-9.2-1.8zM64 325.4V368c0 26.5 21.5 48 48 48h44.3c25.5 0 46.5-19.9 47.9-45.3l2.5-45.6c-2.3-.8-4.9-1.7-7.5-2.5c-17.2-5.4-39.9-10.5-63.6-10.5c-23.7 0-46.2 5.1-63.2 10.5c-3.1 1-5.9 1.9-8.5 2.9zM512 368V325.4c-2.6-.9-5.5-1.9-8.5-2.9c-17-5.4-39.5-10.5-63.2-10.5c-23.7 0-46.4 5.1-63.6 10.5c-2.7 .8-5.2 1.7-7.5 2.5l2.5 45.6c1.4 25.4 22.5 45.3 47.9 45.3H464c26.5 0 48-21.5 48-48z" } }, "free": ["solid"] }, "glide": { "changes": ["4.6.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f2a5", "label": "Glide", "voted": false, "svg": { "brands": { "last_modified": 1660014467, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M252.8 148.6c0 8.8-1.6 17.7-3.4 26.4-5.8 27.8-11.6 55.8-17.3 83.6-1.4 6.3-8.3 4.9-13.7 4.9-23.8 0-30.5-26-30.5-45.5 0-29.3 11.2-68.1 38.5-83.1 4.3-2.5 9.2-4.2 14.1-4.2 11.4 0 12.3 8.3 12.3 17.9zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-64 187c0-5.1-20.8-37.7-25.5-39.5-2.2-.9-7.2-2.3-9.6-2.3-23.1 0-38.7 10.5-58.2 21.5l-.5-.5c4.3-29.4 14.6-57.2 14.6-87.4 0-44.6-23.8-62.7-67.5-62.7-71.7 0-108 70.8-108 123.5 0 54.7 32 85 86.3 85 7.5 0 6.9-.6 6.9 2.3-10.5 80.3-56.5 82.9-56.5 58.9 0-24.4 28-36.5 28.3-38-.2-7.6-29.3-17.2-36.7-17.2-21.1 0-32.7 33-32.7 50.6 0 32.3 20.4 54.7 53.3 54.7 48.2 0 83.4-49.7 94.3-91.7 9.4-37.7 7-39.4 12.3-42.1 20-10.1 35.8-16.8 58.4-16.8 11.1 0 19 2.3 36.7 5.2 1.8.1 4.1-1.7 4.1-3.5z" } }, "free": ["brands"] }, "glide-g": { "changes": ["4.6.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f2a6", "label": "Glide G", "voted": false, "svg": { "brands": { "last_modified": 1660014481, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M407.1 211.2c-3.5-1.4-11.6-3.8-15.4-3.8-37.1 0-62.2 16.8-93.5 34.5l-.9-.9c7-47.3 23.5-91.9 23.5-140.4C320.8 29.1 282.6 0 212.4 0 97.3 0 39 113.7 39 198.4 39 286.3 90.3 335 177.6 335c12 0 11-1 11 3.8-16.9 128.9-90.8 133.1-90.8 94.6 0-39.2 45-58.6 45.5-61-.3-12.2-47-27.6-58.9-27.6-33.9.1-52.4 51.2-52.4 79.3C32 476 64.8 512 117.5 512c77.4 0 134-77.8 151.4-145.4 15.1-60.5 11.2-63.3 19.7-67.6 32.2-16.2 57.5-27 93.8-27 17.8 0 30.5 3.7 58.9 8.4 2.9 0 6.7-2.9 6.7-5.8 0-8-33.4-60.5-40.9-63.4zm-175.3-84.4c-9.3 44.7-18.6 89.6-27.8 134.3-2.3 10.2-13.3 7.8-22 7.8-38.3 0-49-41.8-49-73.1 0-47 18-109.3 61.8-133.4 7-4.1 14.8-6.7 22.6-6.7 18.6 0 20 13.3 20 28.7-.1 14.3-2.7 28.5-5.6 42.4z" } }, "free": ["brands"] }, "globe": { "aliases": { "unicodes": { "composite": ["1f310"], "secondary": ["10f0ac"] } }, "changes": [ "2.0.0", "5.0.0", "5.0.9", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "all", "coordinates", "country", "earth", "global", "globe", "globe with meridians", "gps", "internet", "language", "localize", "location", "map", "meridians", "network", "online", "place", "planet", "translate", "travel", "world" ] }, "styles": ["solid"], "unicode": "f0ac", "label": "Globe", "voted": false, "svg": { "solid": { "last_modified": 1684767489, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M352 256c0 22.2-1.2 43.6-3.3 64H163.3c-2.2-20.4-3.3-41.8-3.3-64s1.2-43.6 3.3-64H348.7c2.2 20.4 3.3 41.8 3.3 64zm28.8-64H503.9c5.3 20.5 8.1 41.9 8.1 64s-2.8 43.5-8.1 64H380.8c2.1-20.6 3.2-42 3.2-64s-1.1-43.4-3.2-64zm112.6-32H376.7c-10-63.9-29.8-117.4-55.3-151.6c78.3 20.7 142 77.5 171.9 151.6zm-149.1 0H167.7c6.1-36.4 15.5-68.6 27-94.7c10.5-23.6 22.2-40.7 33.5-51.5C239.4 3.2 248.7 0 256 0s16.6 3.2 27.8 13.8c11.3 10.8 23 27.9 33.5 51.5c11.6 26 20.9 58.2 27 94.7zm-209 0H18.6C48.6 85.9 112.2 29.1 190.6 8.4C165.1 42.6 145.3 96.1 135.3 160zM8.1 192H131.2c-2.1 20.6-3.2 42-3.2 64s1.1 43.4 3.2 64H8.1C2.8 299.5 0 278.1 0 256s2.8-43.5 8.1-64zM194.7 446.6c-11.6-26-20.9-58.2-27-94.6H344.3c-6.1 36.4-15.5 68.6-27 94.6c-10.5 23.6-22.2 40.7-33.5 51.5C272.6 508.8 263.3 512 256 512s-16.6-3.2-27.8-13.8c-11.3-10.8-23-27.9-33.5-51.5zM135.3 352c10 63.9 29.8 117.4 55.3 151.6C112.2 482.9 48.6 426.1 18.6 352H135.3zm358.1 0c-30 74.1-93.6 130.9-171.9 151.6c25.5-34.2 45.2-87.7 55.3-151.6H493.4z" } }, "free": ["solid"] }, "gofore": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3a7", "label": "Gofore", "voted": false, "svg": { "brands": { "last_modified": 1660014470, "raw": "", "viewBox": [0, 0, 400, 512], "width": 400, "height": 512, "path": "M324 319.8h-13.2v34.7c-24.5 23.1-56.3 35.8-89.9 35.8-73.2 0-132.4-60.2-132.4-134.4 0-74.1 59.2-134.4 132.4-134.4 35.3 0 68.6 14 93.6 39.4l62.3-63.3C335 55.3 279.7 32 220.7 32 98 32 0 132.6 0 256c0 122.5 97 224 220.7 224 63.2 0 124.5-26.2 171-82.5-2-27.6-13.4-77.7-67.7-77.7zm-12.1-112.5H205.6v89H324c33.5 0 60.5 15.1 76 41.8v-30.6c0-65.2-40.4-100.2-88.1-100.2z" } }, "free": ["brands"] }, "golang": { "changes": ["6.0.0-beta2"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e40f", "label": "Go", "voted": true, "svg": { "brands": { "last_modified": 1660014476, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M400.1 194.8C389.2 197.6 380.2 199.1 371 202.4C363.7 204.3 356.3 206.3 347.8 208.5L347.2 208.6C343 209.8 342.6 209.9 338.7 205.4C334 200.1 330.6 196.7 324.1 193.5C304.4 183.9 285.4 186.7 267.7 198.2C246.5 211.9 235.6 232.2 235.9 257.4C236.2 282.4 253.3 302.9 277.1 306.3C299.1 309.1 316.9 301.7 330.9 285.8C333 283.2 334.9 280.5 337 277.5V277.5L337 277.5C337.8 276.5 338.5 275.4 339.3 274.2H279.2C272.7 274.2 271.1 270.2 273.3 264.9C277.3 255.2 284.8 239 289.2 230.9C290.1 229.1 292.3 225.1 296.1 225.1H397.2C401.7 211.7 409 198.2 418.8 185.4C441.5 155.5 468.1 139.9 506 133.4C537.8 127.8 567.7 130.9 594.9 149.3C619.5 166.1 634.7 188.9 638.8 218.8C644.1 260.9 631.9 295.1 602.1 324.4C582.4 345.3 557.2 358.4 528.2 364.3C522.6 365.3 517.1 365.8 511.7 366.3C508.8 366.5 506 366.8 503.2 367.1C474.9 366.5 449 358.4 427.2 339.7C411.9 326.4 401.3 310.1 396.1 291.2C392.4 298.5 388.1 305.6 382.1 312.3C360.5 341.9 331.2 360.3 294.2 365.2C263.6 369.3 235.3 363.4 210.3 344.7C187.3 327.2 174.2 304.2 170.8 275.5C166.7 241.5 176.7 210.1 197.2 184.2C219.4 155.2 248.7 136.8 284.5 130.3C313.8 124.1 341.8 128.4 367.1 145.6C383.6 156.5 395.4 171.4 403.2 189.5C405.1 192.3 403.8 193.9 400.1 194.8zM48.3 200.4C47.05 200.4 46.74 199.8 47.36 198.8L53.91 190.4C54.53 189.5 56.09 188.9 57.34 188.9H168.6C169.8 188.9 170.1 189.8 169.5 190.7L164.2 198.8C163.6 199.8 162 200.7 161.1 200.7L48.3 200.4zM1.246 229.1C0 229.1-.3116 228.4 .3116 227.5L6.855 219.1C7.479 218.2 9.037 217.5 10.28 217.5H152.4C153.6 217.5 154.2 218.5 153.9 219.4L151.4 226.9C151.1 228.1 149.9 228.8 148.6 228.8L1.246 229.1zM75.72 255.9C75.1 256.8 75.41 257.7 76.65 257.7L144.6 258C145.5 258 146.8 257.1 146.8 255.9L147.4 248.4C147.4 247.1 146.8 246.2 145.5 246.2H83.2C81.95 246.2 80.71 247.1 80.08 248.1L75.72 255.9zM577.2 237.9C577 235.3 576.9 233.1 576.5 230.9C570.9 200.1 542.5 182.6 512.9 189.5C483.9 196 465.2 214.4 458.4 243.7C452.8 268 464.6 292.6 487 302.6C504.2 310.1 521.3 309.2 537.8 300.7C562.4 287.1 575.8 268 577.4 241.2C577.3 240 577.3 238.9 577.2 237.9z" } }, "free": ["brands"] }, "golf-ball-tee": { "aliases": { "names": ["golf-ball"], "unicodes": { "secondary": ["10f450"] } }, "changes": ["5.0.5", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["caddy", "eagle", "putt", "tee"] }, "styles": ["solid"], "unicode": "f450", "label": "Golf Ball Tee", "voted": false, "svg": { "solid": { "last_modified": 1684767070, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M384 192c0 66.8-34.1 125.6-85.8 160H85.8C34.1 317.6 0 258.8 0 192C0 86 86 0 192 0S384 86 384 192zM242.1 256.6c0 18.5-15 33.5-33.5 33.5c-4.9 0-9.1 5.1-5.4 8.4c5.9 5.2 13.7 8.4 22.1 8.4c18.5 0 33.5-15 33.5-33.5c0-8.5-3.2-16.2-8.4-22.1c-3.3-3.7-8.4 .5-8.4 5.4zm-52.3-49.3c-4.9 0-9.1 5.1-5.4 8.4c5.9 5.2 13.7 8.4 22.1 8.4c18.5 0 33.5-15 33.5-33.5c0-8.5-3.2-16.2-8.4-22.1c-3.3-3.7-8.4 .5-8.4 5.4c0 18.5-15 33.5-33.5 33.5zm113.5-17.5c0 18.5-15 33.5-33.5 33.5c-4.9 0-9.1 5.1-5.4 8.4c5.9 5.2 13.7 8.4 22.1 8.4c18.5 0 33.5-15 33.5-33.5c0-8.5-3.2-16.2-8.4-22.1c-3.3-3.7-8.4 .5-8.4 5.4zM96 416c0-17.7 14.3-32 32-32h64 64c17.7 0 32 14.3 32 32s-14.3 32-32 32H240c-8.8 0-16 7.2-16 16v16c0 17.7-14.3 32-32 32s-32-14.3-32-32V464c0-8.8-7.2-16-16-16H128c-17.7 0-32-14.3-32-32z" } }, "free": ["solid"] }, "goodreads": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3a8", "label": "Goodreads", "voted": false, "svg": { "brands": { "last_modified": 1660014472, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M299.9 191.2c5.1 37.3-4.7 79-35.9 100.7-22.3 15.5-52.8 14.1-70.8 5.7-37.1-17.3-49.5-58.6-46.8-97.2 4.3-60.9 40.9-87.9 75.3-87.5 46.9-.2 71.8 31.8 78.2 78.3zM448 88v336c0 30.9-25.1 56-56 56H56c-30.9 0-56-25.1-56-56V88c0-30.9 25.1-56 56-56h336c30.9 0 56 25.1 56 56zM330 313.2s-.1-34-.1-217.3h-29v40.3c-.8.3-1.2-.5-1.6-1.2-9.6-20.7-35.9-46.3-76-46-51.9.4-87.2 31.2-100.6 77.8-4.3 14.9-5.8 30.1-5.5 45.6 1.7 77.9 45.1 117.8 112.4 115.2 28.9-1.1 54.5-17 69-45.2.5-1 1.1-1.9 1.7-2.9.2.1.4.1.6.2.3 3.8.2 30.7.1 34.5-.2 14.8-2 29.5-7.2 43.5-7.8 21-22.3 34.7-44.5 39.5-17.8 3.9-35.6 3.8-53.2-1.2-21.5-6.1-36.5-19-41.1-41.8-.3-1.6-1.3-1.3-2.3-1.3h-26.8c.8 10.6 3.2 20.3 8.5 29.2 24.2 40.5 82.7 48.5 128.2 37.4 49.9-12.3 67.3-54.9 67.4-106.3z" } }, "free": ["brands"] }, "goodreads-g": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3a9", "label": "Goodreads G", "voted": false, "svg": { "brands": { "last_modified": 1660014463, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M42.6 403.3h2.8c12.7 0 25.5 0 38.2.1 1.6 0 3.1-.4 3.6 2.1 7.1 34.9 30 54.6 62.9 63.9 26.9 7.6 54.1 7.8 81.3 1.8 33.8-7.4 56-28.3 68-60.4 8-21.5 10.7-43.8 11-66.5.1-5.8.3-47-.2-52.8l-.9-.3c-.8 1.5-1.7 2.9-2.5 4.4-22.1 43.1-61.3 67.4-105.4 69.1-103 4-169.4-57-172-176.2-.5-23.7 1.8-46.9 8.3-69.7C58.3 47.7 112.3.6 191.6 0c61.3-.4 101.5 38.7 116.2 70.3.5 1.1 1.3 2.3 2.4 1.9V10.6h44.3c0 280.3.1 332.2.1 332.2-.1 78.5-26.7 143.7-103 162.2-69.5 16.9-159 4.8-196-57.2-8-13.5-11.8-28.3-13-44.5zM188.9 36.5c-52.5-.5-108.5 40.7-115 133.8-4.1 59 14.8 122.2 71.5 148.6 27.6 12.9 74.3 15 108.3-8.7 47.6-33.2 62.7-97 54.8-154-9.7-71.1-47.8-120-119.6-119.7z" } }, "free": ["brands"] }, "google": { "changes": ["4.1.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f1a0", "label": "Google Logo", "voted": false, "svg": { "brands": { "last_modified": 1660014479, "raw": "", "viewBox": [0, 0, 488, 512], "width": 488, "height": 512, "path": "M488 261.8C488 403.3 391.1 504 248 504 110.8 504 0 393.2 0 256S110.8 8 248 8c66.8 0 123 24.5 166.3 64.9l-67.5 64.9C258.5 52.6 94.3 116.6 94.3 256c0 86.5 69.1 156.6 153.7 156.6 98.2 0 135-70.4 140.8-106.9H248v-85.3h236.1c2.3 12.7 3.9 24.9 3.9 41.4z" } }, "free": ["brands"] }, "google-drive": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3aa", "label": "Google Drive", "voted": false, "svg": { "brands": { "last_modified": 1660014465, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M339 314.9L175.4 32h161.2l163.6 282.9H339zm-137.5 23.6L120.9 480h310.5L512 338.5H201.5zM154.1 67.4L0 338.5 80.6 480 237 208.8 154.1 67.4z" } }, "free": ["brands"] }, "google-pay": { "changes": ["5.13.1", "5.14.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e079", "label": "Google Pay", "voted": false, "svg": { "brands": { "last_modified": 1660014458, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M105.72,215v41.25h57.1a49.66,49.66,0,0,1-21.14,32.6c-9.54,6.55-21.72,10.28-36,10.28-27.6,0-50.93-18.91-59.3-44.22a65.61,65.61,0,0,1,0-41l0,0c8.37-25.46,31.7-44.37,59.3-44.37a56.43,56.43,0,0,1,40.51,16.08L176.47,155a101.24,101.24,0,0,0-70.75-27.84,105.55,105.55,0,0,0-94.38,59.11,107.64,107.64,0,0,0,0,96.18v.15a105.41,105.41,0,0,0,94.38,59c28.47,0,52.55-9.53,70-25.91,20-18.61,31.41-46.15,31.41-78.91A133.76,133.76,0,0,0,205.38,215Zm389.41-4c-10.13-9.38-23.93-14.14-41.39-14.14-22.46,0-39.34,8.34-50.5,24.86l20.85,13.26q11.45-17,31.26-17a34.05,34.05,0,0,1,22.75,8.79A28.14,28.14,0,0,1,487.79,248v5.51c-9.1-5.07-20.55-7.75-34.64-7.75-16.44,0-29.65,3.88-39.49,11.77s-14.82,18.31-14.82,31.56a39.74,39.74,0,0,0,13.94,31.27c9.25,8.34,21,12.51,34.79,12.51,16.29,0,29.21-7.3,39-21.89h1v17.72h22.61V250C510.25,233.45,505.26,220.34,495.13,211ZM475.9,300.3a37.32,37.32,0,0,1-26.57,11.16A28.61,28.61,0,0,1,431,305.21a19.41,19.41,0,0,1-7.77-15.63c0-7,3.22-12.81,9.54-17.42s14.53-7,24.07-7C470,265,480.3,268,487.64,273.94,487.64,284.07,483.68,292.85,475.9,300.3Zm-93.65-142A55.71,55.71,0,0,0,341.74,142H279.07V328.74H302.7V253.1h39c16,0,29.5-5.36,40.51-15.93.88-.89,1.76-1.79,2.65-2.68A54.45,54.45,0,0,0,382.25,158.26Zm-16.58,62.23a30.65,30.65,0,0,1-23.34,9.68H302.7V165h39.63a32,32,0,0,1,22.6,9.23A33.18,33.18,0,0,1,365.67,220.49ZM614.31,201,577.77,292.7h-.45L539.9,201H514.21L566,320.55l-29.35,64.32H561L640,201Z" } }, "free": ["brands"] }, "google-play": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3ab", "label": "Google Play", "voted": false, "svg": { "brands": { "last_modified": 1660014465, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M325.3 234.3L104.6 13l280.8 161.2-60.1 60.1zM47 0C34 6.8 25.3 19.2 25.3 35.3v441.3c0 16.1 8.7 28.5 21.7 35.3l256.6-256L47 0zm425.2 225.6l-58.9-34.1-65.7 64.5 65.7 64.5 60.1-34.1c18-14.3 18-46.5-1.2-60.8zM104.6 499l280.8-161.2-60.1-60.1L104.6 499z" } }, "free": ["brands"] }, "google-plus": { "changes": ["4.6.0", "5.0.0", "5.13.1"], "ligatures": [], "search": { "terms": ["google-plus-circle", "google-plus-official"] }, "styles": ["brands"], "unicode": "f2b3", "label": "Google Plus", "voted": false, "svg": { "brands": { "last_modified": 1660014480, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256,8C119.1,8,8,119.1,8,256S119.1,504,256,504,504,392.9,504,256,392.9,8,256,8ZM185.3,380a124,124,0,0,1,0-248c31.3,0,60.1,11,83,32.3l-33.6,32.6c-13.2-12.9-31.3-19.1-49.4-19.1-42.9,0-77.2,35.5-77.2,78.1S142.3,334,185.3,334c32.6,0,64.9-19.1,70.1-53.3H185.3V238.1H302.2a109.2,109.2,0,0,1,1.9,20.7c0,70.8-47.5,121.2-118.8,121.2ZM415.5,273.8v35.5H380V273.8H344.5V238.3H380V202.8h35.5v35.5h35.2v35.5Z" } }, "free": ["brands"] }, "google-plus-g": { "changes": ["2.0.0", "5.0.0"], "ligatures": [], "search": { "terms": ["google-plus", "social network"] }, "styles": ["brands"], "unicode": "f0d5", "label": "Google Plus G", "voted": false, "svg": { "brands": { "last_modified": 1660014480, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M386.061 228.496c1.834 9.692 3.143 19.384 3.143 31.956C389.204 370.205 315.599 448 204.8 448c-106.084 0-192-85.915-192-192s85.916-192 192-192c51.864 0 95.083 18.859 128.611 50.292l-52.126 50.03c-14.145-13.621-39.028-29.599-76.485-29.599-65.484 0-118.92 54.221-118.92 121.277 0 67.056 53.436 121.277 118.92 121.277 75.961 0 104.513-54.745 108.965-82.773H204.8v-66.009h181.261zm185.406 6.437V179.2h-56.001v55.733h-55.733v56.001h55.733v55.733h56.001v-55.733H627.2v-56.001h-55.733z" } }, "free": ["brands"] }, "google-wallet": { "changes": ["4.2.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f1ee", "label": "Google Wallet", "voted": false, "svg": { "brands": { "last_modified": 1660014470, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M156.8 126.8c37.6 60.6 64.2 113.1 84.3 162.5-8.3 33.8-18.8 66.5-31.3 98.3-13.2-52.3-26.5-101.3-56-148.5 6.5-36.4 2.3-73.6 3-112.3zM109.3 200H16.1c-6.5 0-10.5 7.5-6.5 12.7C51.8 267 81.3 330.5 101.3 400h103.5c-16.2-69.7-38.7-133.7-82.5-193.5-3-4-8-6.5-13-6.5zm47.8-88c68.5 108 130 234.5 138.2 368H409c-12-138-68.4-265-143.2-368H157.1zm251.8-68.5c-1.8-6.8-8.2-11.5-15.2-11.5h-88.3c-5.3 0-9 5-7.8 10.3 13.2 46.5 22.3 95.5 26.5 146 48.2 86.2 79.7 178.3 90.6 270.8 15.8-60.5 25.3-133.5 25.3-203 0-73.6-12.1-145.1-31.1-212.6z" } }, "free": ["brands"] }, "gopuram": { "aliases": { "unicodes": { "secondary": ["10f664"] } }, "changes": [ "5.3.0", "5.7.0", "5.11.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["building", "entrance", "hinduism", "temple", "tower"] }, "styles": ["solid"], "unicode": "f664", "label": "Gopuram", "voted": false, "svg": { "solid": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M120 0c13.3 0 24 10.7 24 24v8h40V24c0-13.3 10.7-24 24-24s24 10.7 24 24v8h48V24c0-13.3 10.7-24 24-24s24 10.7 24 24v8h40V24c0-13.3 10.7-24 24-24s24 10.7 24 24v8V64v64c17.7 0 32 14.3 32 32v64c17.7 0 32 14.3 32 32v96c17.7 0 32 14.3 32 32v96c0 17.7-14.3 32-32 32H416V352H384V224H352V128H320v96h32V352h32V512H304V464c0-26.5-21.5-48-48-48s-48 21.5-48 48v48H128V352h32V224h32V128H160v96H128V352H96V512H32c-17.7 0-32-14.3-32-32V384c0-17.7 14.3-32 32-32V256c0-17.7 14.3-32 32-32V160c0-17.7 14.3-32 32-32V64 32 24c0-13.3 10.7-24 24-24zM256 272c-17.7 0-32 14.3-32 32v48h64V304c0-17.7-14.3-32-32-32zm-32-80v32h64V192c0-17.7-14.3-32-32-32s-32 14.3-32 32z" } }, "free": ["solid"] }, "graduation-cap": { "aliases": { "names": ["mortar-board"], "unicodes": { "composite": ["1f393"], "secondary": ["10f19d"] } }, "changes": [ "4.1.0", "5.0.0", "5.2.0", "5.10.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "cap", "celebration", "ceremony", "clothing", "college", "graduate", "graduation", "graduation cap", "hat", "learning", "school", "student" ] }, "styles": ["solid"], "unicode": "f19d", "label": "Graduation Cap", "voted": false, "svg": { "solid": { "last_modified": 1684767601, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M320 32c-8.1 0-16.1 1.4-23.7 4.1L15.8 137.4C6.3 140.9 0 149.9 0 160s6.3 19.1 15.8 22.6l57.9 20.9C57.3 229.3 48 259.8 48 291.9v28.1c0 28.4-10.8 57.7-22.3 80.8c-6.5 13-13.9 25.8-22.5 37.6C0 442.7-.9 448.3 .9 453.4s6 8.9 11.2 10.2l64 16c4.2 1.1 8.7 .3 12.4-2s6.3-6.1 7.1-10.4c8.6-42.8 4.3-81.2-2.1-108.7C90.3 344.3 86 329.8 80 316.5V291.9c0-30.2 10.2-58.7 27.9-81.5c12.9-15.5 29.6-28 49.2-35.7l157-61.7c8.2-3.2 17.5 .8 20.7 9s-.8 17.5-9 20.7l-157 61.7c-12.4 4.9-23.3 12.4-32.2 21.6l159.6 57.6c7.6 2.7 15.6 4.1 23.7 4.1s16.1-1.4 23.7-4.1L624.2 182.6c9.5-3.4 15.8-12.5 15.8-22.6s-6.3-19.1-15.8-22.6L343.7 36.1C336.1 33.4 328.1 32 320 32zM128 408c0 35.3 86 72 192 72s192-36.7 192-72L496.7 262.6 354.5 314c-11.1 4-22.8 6-34.5 6s-23.5-2-34.5-6L143.3 262.6 128 408z" } }, "free": ["solid"] }, "gratipay": { "changes": ["3.2.0", "5.0.0"], "ligatures": [], "search": { "terms": ["favorite", "heart", "like", "love"] }, "styles": ["brands"], "unicode": "f184", "label": "Gratipay (Gittip)", "voted": false, "svg": { "brands": { "last_modified": 1660014474, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M248 8C111.1 8 0 119.1 0 256s111.1 248 248 248 248-111.1 248-248S384.9 8 248 8zm114.6 226.4l-113 152.7-112.7-152.7c-8.7-11.9-19.1-50.4 13.6-72 28.1-18.1 54.6-4.2 68.5 11.9 15.9 17.9 46.6 16.9 61.7 0 13.9-16.1 40.4-30 68.1-11.9 32.9 21.6 22.6 60 13.8 72z" } }, "free": ["brands"] }, "grav": { "changes": ["4.7.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f2d6", "label": "Grav", "voted": false, "svg": { "brands": { "last_modified": 1660014476, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M301.1 212c4.4 4.4 4.4 11.9 0 16.3l-9.7 9.7c-4.4 4.7-11.9 4.7-16.6 0l-10.5-10.5c-4.4-4.7-4.4-11.9 0-16.6l9.7-9.7c4.4-4.4 11.9-4.4 16.6 0l10.5 10.8zm-30.2-19.7c3-3 3-7.8 0-10.5-2.8-3-7.5-3-10.5 0-2.8 2.8-2.8 7.5 0 10.5 3.1 2.8 7.8 2.8 10.5 0zm-26 5.3c-3 2.8-3 7.5 0 10.2 2.8 3 7.5 3 10.5 0 2.8-2.8 2.8-7.5 0-10.2-3-3-7.7-3-10.5 0zm72.5-13.3c-19.9-14.4-33.8-43.2-11.9-68.1 21.6-24.9 40.7-17.2 59.8.8 11.9 11.3 29.3 24.9 17.2 48.2-12.5 23.5-45.1 33.2-65.1 19.1zm47.7-44.5c-8.9-10-23.3 6.9-15.5 16.1 7.4 9 32.1 2.4 15.5-16.1zM504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-66.2 42.6c2.5-16.1-20.2-16.6-25.2-25.7-13.6-24.1-27.7-36.8-54.5-30.4 11.6-8 23.5-6.1 23.5-6.1.3-6.4 0-13-9.4-24.9 3.9-12.5.3-22.4.3-22.4 15.5-8.6 26.8-24.4 29.1-43.2 3.6-31-18.8-59.2-49.8-62.8-22.1-2.5-43.7 7.7-54.3 25.7-23.2 40.1 1.4 70.9 22.4 81.4-14.4-1.4-34.3-11.9-40.1-34.3-6.6-25.7 2.8-49.8 8.9-61.4 0 0-4.4-5.8-8-8.9 0 0-13.8 0-24.6 5.3 11.9-15.2 25.2-14.4 25.2-14.4 0-6.4-.6-14.9-3.6-21.6-5.4-11-23.8-12.9-31.7 2.8.1-.2.3-.4.4-.5-5 11.9-1.1 55.9 16.9 87.2-2.5 1.4-9.1 6.1-13 10-21.6 9.7-56.2 60.3-56.2 60.3-28.2 10.8-77.2 50.9-70.6 79.7.3 3 1.4 5.5 3 7.5-2.8 2.2-5.5 5-8.3 8.3-11.9 13.8-5.3 35.2 17.7 24.4 15.8-7.2 29.6-20.2 36.3-30.4 0 0-5.5-5-16.3-4.4 27.7-6.6 34.3-9.4 46.2-9.1 8 3.9 8-34.3 8-34.3 0-14.7-2.2-31-11.1-41.5 12.5 12.2 29.1 32.7 28 60.6-.8 18.3-15.2 23-15.2 23-9.1 16.6-43.2 65.9-30.4 106 0 0-9.7-14.9-10.2-22.1-17.4 19.4-46.5 52.3-24.6 64.5 26.6 14.7 108.8-88.6 126.2-142.3 34.6-20.8 55.4-47.3 63.9-65 22 43.5 95.3 94.5 101.1 59z" } }, "free": ["brands"] }, "greater-than": { "aliases": { "unicodes": { "composite": ["f531"], "primary": ["f531"], "secondary": ["103e", "10f531"] } }, "changes": ["5.0.13", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Greater-Than Sign", "arithmetic", "compare", "math"] }, "styles": ["solid"], "unicode": "3e", "label": "Greater Than", "voted": true, "svg": { "solid": { "last_modified": 1684767245, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M3.4 81.7c-7.9 15.8-1.5 35 14.3 42.9L280.5 256 17.7 387.4C1.9 395.3-4.5 414.5 3.4 430.3s27.1 22.2 42.9 14.3l320-160c10.8-5.4 17.7-16.5 17.7-28.6s-6.8-23.2-17.7-28.6l-320-160c-15.8-7.9-35-1.5-42.9 14.3z" } }, "free": ["solid"] }, "greater-than-equal": { "aliases": { "unicodes": { "secondary": ["10f532"] } }, "changes": ["5.0.13", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["arithmetic", "compare", "math"] }, "styles": ["solid"], "unicode": "f532", "label": "Greater Than Equal", "voted": true, "svg": { "solid": { "last_modified": 1684767246, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M52.1 93.7C35.7 87.1 27.7 68.5 34.3 52.1s25.2-24.4 41.6-17.8l320 128C408 167.1 416 178.9 416 192s-8 24.9-20.1 29.7l-320 128c-16.4 6.6-35-1.4-41.6-17.8s1.4-35 17.8-41.6L297.8 192 52.1 93.7zM416 416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H416z" } }, "free": ["solid"] }, "grip": { "aliases": { "names": ["grip-horizontal"], "unicodes": { "secondary": ["10f58d"] } }, "changes": [ "5.1.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["affordance", "drag", "drop", "grab", "handle"] }, "styles": ["solid"], "unicode": "f58d", "label": "Grip", "voted": true, "svg": { "solid": { "last_modified": 1684767205, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M128 136c0-22.1-17.9-40-40-40L40 96C17.9 96 0 113.9 0 136l0 48c0 22.1 17.9 40 40 40H88c22.1 0 40-17.9 40-40l0-48zm0 192c0-22.1-17.9-40-40-40H40c-22.1 0-40 17.9-40 40l0 48c0 22.1 17.9 40 40 40H88c22.1 0 40-17.9 40-40V328zm32-192v48c0 22.1 17.9 40 40 40h48c22.1 0 40-17.9 40-40V136c0-22.1-17.9-40-40-40l-48 0c-22.1 0-40 17.9-40 40zM288 328c0-22.1-17.9-40-40-40H200c-22.1 0-40 17.9-40 40l0 48c0 22.1 17.9 40 40 40h48c22.1 0 40-17.9 40-40V328zm32-192v48c0 22.1 17.9 40 40 40h48c22.1 0 40-17.9 40-40V136c0-22.1-17.9-40-40-40l-48 0c-22.1 0-40 17.9-40 40zM448 328c0-22.1-17.9-40-40-40H360c-22.1 0-40 17.9-40 40v48c0 22.1 17.9 40 40 40h48c22.1 0 40-17.9 40-40V328z" } }, "free": ["solid"] }, "grip-lines": { "aliases": { "unicodes": { "secondary": ["10f7a4"] } }, "changes": [ "5.6.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["affordance", "drag", "drop", "grab", "handle"] }, "styles": ["solid"], "unicode": "f7a4", "label": "Grip Lines", "voted": true, "svg": { "solid": { "last_modified": 1684767206, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M32 288c-17.7 0-32 14.3-32 32s14.3 32 32 32l384 0c17.7 0 32-14.3 32-32s-14.3-32-32-32L32 288zm0-128c-17.7 0-32 14.3-32 32s14.3 32 32 32l384 0c17.7 0 32-14.3 32-32s-14.3-32-32-32L32 160z" } }, "free": ["solid"] }, "grip-lines-vertical": { "aliases": { "unicodes": { "secondary": ["10f7a5"] } }, "changes": [ "5.6.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["affordance", "drag", "drop", "grab", "handle"] }, "styles": ["solid"], "unicode": "f7a5", "label": "Grip Lines Vertical", "voted": true, "svg": { "solid": { "last_modified": 1684767207, "raw": "", "viewBox": [0, 0, 192, 512], "width": 192, "height": 512, "path": "M64 64c0-17.7-14.3-32-32-32S0 46.3 0 64V448c0 17.7 14.3 32 32 32s32-14.3 32-32V64zm128 0c0-17.7-14.3-32-32-32s-32 14.3-32 32V448c0 17.7 14.3 32 32 32s32-14.3 32-32V64z" } }, "free": ["solid"] }, "grip-vertical": { "aliases": { "unicodes": { "secondary": ["10f58e"] } }, "changes": [ "5.1.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["affordance", "drag", "drop", "grab", "handle"] }, "styles": ["solid"], "unicode": "f58e", "label": "Grip Vertical", "voted": true, "svg": { "solid": { "last_modified": 1684767206, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M40 352l48 0c22.1 0 40 17.9 40 40l0 48c0 22.1-17.9 40-40 40l-48 0c-22.1 0-40-17.9-40-40l0-48c0-22.1 17.9-40 40-40zm192 0l48 0c22.1 0 40 17.9 40 40l0 48c0 22.1-17.9 40-40 40l-48 0c-22.1 0-40-17.9-40-40l0-48c0-22.1 17.9-40 40-40zM40 320c-22.1 0-40-17.9-40-40l0-48c0-22.1 17.9-40 40-40l48 0c22.1 0 40 17.9 40 40l0 48c0 22.1-17.9 40-40 40l-48 0zM232 192l48 0c22.1 0 40 17.9 40 40l0 48c0 22.1-17.9 40-40 40l-48 0c-22.1 0-40-17.9-40-40l0-48c0-22.1 17.9-40 40-40zM40 160c-22.1 0-40-17.9-40-40L0 72C0 49.9 17.9 32 40 32l48 0c22.1 0 40 17.9 40 40l0 48c0 22.1-17.9 40-40 40l-48 0zM232 32l48 0c22.1 0 40 17.9 40 40l0 48c0 22.1-17.9 40-40 40l-48 0c-22.1 0-40-17.9-40-40l0-48c0-22.1 17.9-40 40-40z" } }, "free": ["solid"] }, "gripfire": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3ac", "label": "Gripfire, Inc.", "voted": false, "svg": { "brands": { "last_modified": 1660014466, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M112.5 301.4c0-73.8 105.1-122.5 105.1-203 0-47.1-34-88-39.1-90.4.4 3.3.6 6.7.6 10C179.1 110.1 32 171.9 32 286.6c0 49.8 32.2 79.2 66.5 108.3 65.1 46.7 78.1 71.4 78.1 86.6 0 10.1-4.8 17-4.8 22.3 13.1-16.7 17.4-31.9 17.5-46.4 0-29.6-21.7-56.3-44.2-86.5-16-22.3-32.6-42.6-32.6-69.5zm205.3-39c-12.1-66.8-78-124.4-94.7-130.9l4 7.2c2.4 5.1 3.4 10.9 3.4 17.1 0 44.7-54.2 111.2-56.6 116.7-2.2 5.1-3.2 10.5-3.2 15.8 0 20.1 15.2 42.1 17.9 42.1 2.4 0 56.6-55.4 58.1-87.7 6.4 11.7 9.1 22.6 9.1 33.4 0 41.2-41.8 96.9-41.8 96.9 0 11.6 31.9 53.2 35.5 53.2 1 0 2.2-1.4 3.2-2.4 37.9-39.3 67.3-85 67.3-136.8 0-8-.7-16.2-2.2-24.6z" } }, "free": ["brands"] }, "group-arrows-rotate": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["community", "engagement", "spin", "sync"] }, "styles": ["solid"], "unicode": "e4f6", "label": "Group Arrows Rotate", "voted": false, "svg": { "solid": { "last_modified": 1684767620, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M201.1 71.9c16.9-5 26.6-22.9 21.5-39.8s-22.9-26.6-39.8-21.5c-21.5 6.4-41.8 15.5-60.6 27C114.3 34 105.4 32 96 32C60.7 32 32 60.7 32 96c0 9.4 2 18.3 5.6 26.3c-11.5 18.7-20.6 39-27 60.6c-5 16.9 4.6 34.8 21.5 39.8s34.8-4.6 39.8-21.5c4.3-14.6 10.4-28.5 17.9-41.4c2 .2 4.1 .3 6.1 .3c35.3 0 64-28.7 64-64c0-2.1-.1-4.1-.3-6.1c12.9-7.5 26.8-13.6 41.4-17.9zm128-61.3c-16.9-5-34.8 4.6-39.8 21.5s4.6 34.8 21.5 39.8c14.6 4.3 28.5 10.4 41.4 17.9c-.2 2-.3 4.1-.3 6.1c0 35.3 28.7 64 64 64c2.1 0 4.1-.1 6.2-.3c7.5 12.9 13.6 26.8 17.9 41.4c5 16.9 22.9 26.6 39.8 21.5s26.6-22.9 21.5-39.8c-6.4-21.5-15.5-41.8-27-60.6c3.6-8 5.6-16.9 5.6-26.3c0-35.3-28.7-64-64-64c-9.4 0-18.3 2-26.3 5.6c-18.7-11.5-39-20.6-60.6-27zM71.9 310.9c-5-16.9-22.9-26.6-39.8-21.5s-26.6 22.9-21.5 39.8c6.4 21.5 15.5 41.8 27 60.6C34 397.7 32 406.6 32 416c0 35.3 28.7 64 64 64c9.4 0 18.3-2 26.3-5.6c18.7 11.5 39 20.6 60.6 27c16.9 5 34.8-4.6 39.8-21.5s-4.6-34.8-21.5-39.8c-14.6-4.3-28.5-10.4-41.4-17.9c.2-2 .3-4.1 .3-6.2c0-35.3-28.7-64-64-64c-2.1 0-4.1 .1-6.2 .3c-7.5-12.9-13.6-26.8-17.9-41.4zm429.4 18.3c5-16.9-4.6-34.8-21.5-39.8s-34.8 4.6-39.8 21.5c-4.3 14.6-10.4 28.5-17.9 41.4c-2-.2-4.1-.3-6.2-.3c-35.3 0-64 28.7-64 64c0 2.1 .1 4.1 .3 6.2c-12.9 7.5-26.8 13.6-41.4 17.9c-16.9 5-26.6 22.9-21.5 39.8s22.9 26.6 39.8 21.5c21.5-6.4 41.8-15.5 60.6-27c8 3.6 16.9 5.6 26.3 5.6c35.3 0 64-28.7 64-64c0-9.4-2-18.3-5.6-26.3c11.5-18.7 20.6-39 27-60.6zM192.8 256.8c0-15.6 5.6-29.9 14.9-41.1L223 231c6.6 6.6 17.8 1.9 17.8-7.4V163.2c0-5.7-4.7-10.4-10.4-10.4H169.9c-9.3 0-13.9 11.2-7.4 17.8l11.2 11.2c-17.9 19.8-28.9 46.2-28.9 75.1c0 43.6 24.9 81.3 61.1 99.8c11.8 6 26.3 1.4 32.3-10.4s1.4-26.3-10.4-32.3c-20.8-10.6-34.9-32.2-34.9-57zm93.1-58.6c20.8 10.6 34.9 32.2 34.9 57c0 15.6-5.6 29.9-14.9 41.1L290.6 281c-6.6-6.6-17.8-1.9-17.8 7.4v60.5c0 5.7 4.7 10.4 10.4 10.4h60.5c9.3 0 13.9-11.2 7.4-17.8l-11.2-11.2c17.9-19.8 28.9-46.2 28.9-75.1c0-43.6-24.9-81.3-61.1-99.8c-11.8-6-26.3-1.4-32.3 10.4s-1.4 26.3 10.4 32.3z" } }, "free": ["solid"] }, "grunt": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3ad", "label": "Grunt", "voted": false, "svg": { "brands": { "last_modified": 1660014462, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M61.3 189.3c-1.1 10 5.2 19.1 5.2 19.1.7-7.5 2.2-12.8 4-16.6.4 10.3 3.2 23.5 12.8 34.1 6.9 7.6 35.6 23.3 54.9 6.1 1 2.4 2.1 5.3 3 8.5 2.9 10.3-2.7 25.3-2.7 25.3s15.1-17.1 13.9-32.5c10.8-.5 21.4-8.4 21.1-19.5 0 0-18.9 10.4-35.5-8.8-9.7-11.2-40.9-42-83.1-31.8 4.3 1 8.9 2.4 13.5 4.1h-.1c-4.2 2-6.5 7.1-7 12zm28.3-1.8c19.5 11 37.4 25.7 44.9 37-5.7 3.3-21.7 10.4-38-1.7-10.3-7.6-9.8-26.2-6.9-35.3zm142.1 45.8c-1.2 15.5 13.9 32.5 13.9 32.5s-5.6-15-2.7-25.3c.9-3.2 2-6 3-8.5 19.3 17.3 48 1.5 54.8-6.1 9.6-10.6 12.3-23.8 12.8-34.1 1.8 3.8 3.4 9.1 4 16.6 0 0 6.4-9.1 5.2-19.1-.6-5-2.9-10-7-11.8h-.1c4.6-1.8 9.2-3.2 13.5-4.1-42.3-10.2-73.4 20.6-83.1 31.8-16.7 19.2-35.5 8.8-35.5 8.8-.2 10.9 10.4 18.9 21.2 19.3zm62.7-45.8c3 9.1 3.4 27.7-7 35.4-16.3 12.1-32.2 5-37.9 1.6 7.5-11.4 25.4-26 44.9-37zM160 418.5h-29.4c-5.5 0-8.2 1.6-9.5 2.9-1.9 2-2.2 4.7-.9 8.1 3.5 9.1 11.4 16.5 13.7 18.6 3.1 2.7 7.5 4.3 11.8 4.3 4.4 0 8.3-1.7 11-4.6 7.5-8.2 11.9-17.1 13-19.8.6-1.5 1.3-4.5-.9-6.8-1.8-1.8-4.7-2.7-8.8-2.7zm189.2-101.2c-2.4 17.9-13 33.8-24.6 43.7-3.1-22.7-3.7-55.5-3.7-62.4 0-14.7 9.5-24.5 12.2-26.1 2.5-1.5 5.4-3 8.3-4.6 18-9.6 40.4-21.6 40.4-43.7 0-16.2-9.3-23.2-15.4-27.8-.8-.6-1.5-1.1-2.2-1.7-2.1-1.7-3.7-3-4.3-4.4-4.4-9.8-3.6-34.2-1.7-37.6.6-.6 16.7-20.9 11.8-39.2-2-7.4-6.9-13.3-14.1-17-5.3-2.7-11.9-4.2-19.5-4.5-.1-2-.5-3.9-.9-5.9-.6-2.6-1.1-5.3-.9-8.1.4-4.7.8-9 2.2-11.3 8.4-13.3 28.8-17.6 29-17.6l12.3-2.4-8.1-9.5c-.1-.2-17.3-17.5-46.3-17.5-7.9 0-16 1.3-24.1 3.9-24.2 7.8-42.9 30.5-49.4 39.3-3.1-1-6.3-1.9-9.6-2.7-4.2-15.8 9-38.5 9-38.5s-13.6-3-33.7 15.2c-2.6-6.5-8.1-20.5-1.8-37.2C184.6 10.1 177.2 26 175 40.4c-7.6-5.4-6.7-23.1-7.2-27.6-7.5.9-29.2 21.9-28.2 48.3-2 .5-3.9 1.1-5.9 1.7-6.5-8.8-25.1-31.5-49.4-39.3-7.9-2.2-16-3.5-23.9-3.5-29 0-46.1 17.3-46.3 17.5L6 46.9l12.3 2.4c.2 0 20.6 4.3 29 17.6 1.4 2.2 1.8 6.6 2.2 11.3.2 2.8-.4 5.5-.9 8.1-.4 1.9-.8 3.9-.9 5.9-7.7.3-14.2 1.8-19.5 4.5-7.2 3.7-12.1 9.6-14.1 17-5 18.2 11.2 38.5 11.8 39.2 1.9 3.4 2.7 27.8-1.7 37.6-.6 1.4-2.2 2.7-4.3 4.4-.7.5-1.4 1.1-2.2 1.7-6.1 4.6-15.4 11.7-15.4 27.8 0 22.1 22.4 34.1 40.4 43.7 3 1.6 5.8 3.1 8.3 4.6 2.7 1.6 12.2 11.4 12.2 26.1 0 6.9-.6 39.7-3.7 62.4-11.6-9.9-22.2-25.9-24.6-43.8 0 0-29.2 22.6-20.6 70.8 5.2 29.5 23.2 46.1 47 54.7 8.8 19.1 29.4 45.7 67.3 49.6C143 504.3 163 512 192.2 512h.2c29.1 0 49.1-7.7 63.6-19.5 37.9-3.9 58.5-30.5 67.3-49.6 23.8-8.7 41.7-25.2 47-54.7 8.2-48.4-21.1-70.9-21.1-70.9zM305.7 37.7c5.6-1.8 11.6-2.7 17.7-2.7 11 0 19.9 3 24.7 5-3.1 1.4-6.4 3.2-9.7 5.3-2.4-.4-5.6-.8-9.2-.8-10.5 0-20.5 3.1-28.7 8.9-12.3 8.7-18 16.9-20.7 22.4-2.2-1.3-4.5-2.5-7.1-3.7-1.6-.8-3.1-1.5-4.7-2.2 6.1-9.1 19.9-26.5 37.7-32.2zm21 18.2c-.8 1-1.6 2.1-2.3 3.2-3.3 5.2-3.9 11.6-4.4 17.8-.5 6.4-1.1 12.5-4.4 17-4.2.8-8.1 1.7-11.5 2.7-2.3-3.1-5.6-7-10.5-11.2 1.4-4.8 5.5-16.1 13.5-22.5 5.6-4.3 12.2-6.7 19.6-7zM45.6 45.3c-3.3-2.2-6.6-4-9.7-5.3 4.8-2 13.7-5 24.7-5 6.1 0 12 .9 17.7 2.7 17.8 5.8 31.6 23.2 37.7 32.1-1.6.7-3.2 1.4-4.8 2.2-2.5 1.2-4.9 2.5-7.1 3.7-2.6-5.4-8.3-13.7-20.7-22.4-8.3-5.8-18.2-8.9-28.8-8.9-3.4.1-6.6.5-9 .9zm44.7 40.1c-4.9 4.2-8.3 8-10.5 11.2-3.4-.9-7.3-1.9-11.5-2.7C65 89.5 64.5 83.4 64 77c-.5-6.2-1.1-12.6-4.4-17.8-.7-1.1-1.5-2.2-2.3-3.2 7.4.3 14 2.6 19.5 7 8 6.3 12.1 17.6 13.5 22.4zM58.1 259.9c-2.7-1.6-5.6-3.1-8.4-4.6-14.9-8-30.2-16.3-30.2-30.5 0-11.1 4.3-14.6 8.9-18.2l.5-.4c.7-.6 1.4-1.2 2.2-1.8-.9 7.2-1.9 13.3-2.7 14.9 0 0 12.1-15 15.7-44.3 1.4-11.5-1.1-34.3-5.1-43 .2 4.9 0 9.8-.3 14.4-.4-.8-.8-1.6-1.3-2.2-3.2-4-11.8-17.5-9.4-26.6.9-3.5 3.1-6 6.7-7.8 3.8-1.9 8.8-2.9 15.1-2.9 12.3 0 25.9 3.7 32.9 6 25.1 8 55.4 30.9 64.1 37.7.2.2.4.3.4.3l5.6 3.9-3.5-5.8c-.2-.3-19.1-31.4-53.2-46.5 2-2.9 7.4-8.1 21.6-15.1 21.4-10.5 46.5-15.8 74.3-15.8 27.9 0 52.9 5.3 74.3 15.8 14.2 6.9 19.6 12.2 21.6 15.1-34 15.1-52.9 46.2-53.1 46.5l-3.5 5.8 5.6-3.9s.2-.1.4-.3c8.7-6.8 39-29.8 64.1-37.7 7-2.2 20.6-6 32.9-6 6.3 0 11.3 1 15.1 2.9 3.5 1.8 5.7 4.4 6.7 7.8 2.5 9.1-6.1 22.6-9.4 26.6-.5.6-.9 1.3-1.3 2.2-.3-4.6-.5-9.5-.3-14.4-4 8.8-6.5 31.5-5.1 43 3.6 29.3 15.7 44.3 15.7 44.3-.8-1.6-1.8-7.7-2.7-14.9.7.6 1.5 1.2 2.2 1.8l.5.4c4.6 3.7 8.9 7.1 8.9 18.2 0 14.2-15.4 22.5-30.2 30.5-2.9 1.5-5.7 3.1-8.4 4.6-8.7 5-18 16.7-19.1 34.2-.9 14.6.9 49.9 3.4 75.9-12.4 4.8-26.7 6.4-39.7 6.8-2-4.1-3.9-8.5-5.5-13.1-.7-2-19.6-51.1-26.4-62.2 5.5 39 17.5 73.7 23.5 89.6-3.5-.5-7.3-.7-11.7-.7h-117c-4.4 0-8.3.3-11.7.7 6-15.9 18.1-50.6 23.5-89.6-6.8 11.2-25.7 60.3-26.4 62.2-1.6 4.6-3.5 9-5.5 13.1-13-.4-27.2-2-39.7-6.8 2.5-26 4.3-61.2 3.4-75.9-.9-17.4-10.3-29.2-19-34.2zM34.8 404.6c-12.1-20-8.7-54.1-3.7-59.1 10.9 34.4 47.2 44.3 74.4 45.4-2.7 4.2-5.2 7.6-7 10l-1.4 1.4c-7.2 7.8-8.6 18.5-4.1 31.8-22.7-.1-46.3-9.8-58.2-29.5zm45.7 43.5c6 1.1 12.2 1.9 18.6 2.4 3.5 8 7.4 15.9 12.3 23.1-14.4-5.9-24.4-16-30.9-25.5zM192 498.2c-60.6-.1-78.3-45.8-84.9-64.7-3.7-10.5-3.4-18.2.9-23.1 2.9-3.3 9.5-7.2 24.6-7.2h118.8c15.1 0 21.8 3.9 24.6 7.2 4.2 4.8 4.5 12.6.9 23.1-6.6 18.8-24.3 64.6-84.9 64.7zm80.6-24.6c4.9-7.2 8.8-15.1 12.3-23.1 6.4-.5 12.6-1.3 18.6-2.4-6.5 9.5-16.5 19.6-30.9 25.5zm76.6-69c-12 19.7-35.6 29.3-58.1 29.7 4.5-13.3 3.1-24.1-4.1-31.8-.4-.5-.9-1-1.4-1.5-1.8-2.4-4.3-5.8-7-10 27.2-1.2 63.5-11 74.4-45.4 5 5 8.4 39.1-3.8 59zM191.9 187.7h.2c12.7-.1 27.2-17.8 27.2-17.8-9.9 6-18.8 8.1-27.3 8.3-8.5-.2-17.4-2.3-27.3-8.3 0 0 14.5 17.6 27.2 17.8zm61.7 230.7h-29.4c-4.2 0-7.2.9-8.9 2.7-2.2 2.3-1.5 5.2-.9 6.7 1 2.6 5.5 11.3 13 19.3 2.7 2.9 6.6 4.5 11 4.5s8.7-1.6 11.8-4.2c2.3-2 10.2-9.2 13.7-18.1 1.3-3.3 1-6-.9-7.9-1.3-1.3-4-2.9-9.4-3z" } }, "free": ["brands"] }, "guarani-sign": { "changes": ["6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Guarani Sign", "currency"] }, "styles": ["solid"], "unicode": "e19a", "label": "Guarani Sign", "voted": false, "svg": { "solid": { "last_modified": 1684766476, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M192 0c-17.7 0-32 14.3-32 32V66.7C69.2 81.9 0 160.9 0 256s69.2 174.1 160 189.3V480c0 17.7 14.3 32 32 32s32-14.3 32-32V445.3c90.8-15.2 160-94.2 160-189.3c0-17.7-14.3-32-32-32H224V132c22.1 5.7 41.8 17.1 57.6 32.6c12.6 12.4 32.9 12.2 45.3-.4s12.2-32.9-.5-45.3C299 92 263.5 73.3 224 66.7V32c0-17.7-14.3-32-32-32zM160 132V380c-55.2-14.2-96-64.3-96-124s40.8-109.8 96-124zM224 380V288h92c-11.6 45-47 80.4-92 92z" } }, "free": ["solid"] }, "guilded": { "changes": ["5.15.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e07e", "label": "Guilded", "voted": false, "svg": { "brands": { "last_modified": 1660014482, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M443.427,64H4.571c0,103.26,22.192,180.06,43.418,222.358C112.046,414.135,224,448,225.256,448a312.824,312.824,0,0,0,140.55-103.477c25.907-33.923,53.1-87.19,65.916-145.761H171.833c4.14,36.429,22.177,67.946,45.1,86.944h88.589c-17.012,28.213-48.186,54.4-80.456,69.482-31.232-13.259-69.09-46.544-96.548-98.362-26.726-53.833-27.092-105.883-27.092-105.883H437.573A625.91,625.91,0,0,0,443.427,64Z" } }, "free": ["brands"] }, "guitar": { "aliases": { "unicodes": { "secondary": ["10f7a6"] } }, "changes": ["5.6.0", "5.11.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "acoustic", "instrument", "music", "rock", "rock and roll", "song", "strings" ] }, "styles": ["solid"], "unicode": "f7a6", "label": "Guitar", "voted": true, "svg": { "solid": { "last_modified": 1684766675, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M465 7c-9.4-9.4-24.6-9.4-33.9 0L383 55c-2.4 2.4-4.3 5.3-5.5 8.5l-15.4 41-77.5 77.6c-45.1-29.4-99.3-30.2-131 1.6c-11 11-18 24.6-21.4 39.6c-3.7 16.6-19.1 30.7-36.1 31.6c-25.6 1.3-49.3 10.7-67.3 28.6C-16 328.4-7.6 409.4 47.5 464.5s136.1 63.5 180.9 18.7c17.9-17.9 27.4-41.7 28.6-67.3c.9-17 15-32.3 31.6-36.1c15-3.4 28.6-10.5 39.6-21.4c31.8-31.8 31-85.9 1.6-131l77.6-77.6 41-15.4c3.2-1.2 6.1-3.1 8.5-5.5l48-48c9.4-9.4 9.4-24.6 0-33.9L465 7zM208 256a48 48 0 1 1 0 96 48 48 0 1 1 0-96z" } }, "free": ["solid"] }, "gulp": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3ae", "label": "Gulp", "voted": false, "svg": { "brands": { "last_modified": 1660014459, "raw": "", "viewBox": [0, 0, 256, 512], "width": 256, "height": 512, "path": "M209.8 391.1l-14.1 24.6-4.6 80.2c0 8.9-28.3 16.1-63.1 16.1s-63.1-7.2-63.1-16.1l-5.8-79.4-14.9-25.4c41.2 17.3 126 16.7 165.6 0zm-196-253.3l13.6 125.5c5.9-20 20.8-47 40-55.2 6.3-2.7 12.7-2.7 18.7.9 5.2 3 9.6 9.3 10.1 11.8 1.2 6.5-2 9.1-4.5 9.1-3 0-5.3-4.6-6.8-7.3-4.1-7.3-10.3-7.6-16.9-2.8-6.9 5-12.9 13.4-17.1 20.7-5.1 8.8-9.4 18.5-12 28.2-1.5 5.6-2.9 14.6-.6 19.9 1 2.2 2.5 3.6 4.9 3.6 5 0 12.3-6.6 15.8-10.1 4.5-4.5 10.3-11.5 12.5-16l5.2-15.5c2.6-6.8 9.9-5.6 9.9 0 0 10.2-3.7 13.6-10 34.7-5.8 19.5-7.6 25.8-7.6 25.8-.7 2.8-3.4 7.5-6.3 7.5-1.2 0-2.1-.4-2.6-1.2-1-1.4-.9-5.3-.8-6.3.2-3.2 6.3-22.2 7.3-25.2-2 2.2-4.1 4.4-6.4 6.6-5.4 5.1-14.1 11.8-21.5 11.8-3.4 0-5.6-.9-7.7-2.4l7.6 79.6c2 5 39.2 17.1 88.2 17.1 49.1 0 86.3-12.2 88.2-17.1l10.9-94.6c-5.7 5.2-12.3 11.6-19.6 14.8-5.4 2.3-17.4 3.8-17.4-5.7 0-5.2 9.1-14.8 14.4-21.5 1.4-1.7 4.7-5.9 4.7-8.1 0-2.9-6-2.2-11.7 2.5-3.2 2.7-6.2 6.3-8.7 9.7-4.3 6-6.6 11.2-8.5 15.5-6.2 14.2-4.1 8.6-9.1 22-5 13.3-4.2 11.8-5.2 14-.9 1.9-2.2 3.5-4 4.5-1.9 1-4.5.9-6.1-.3-.9-.6-1.3-1.9-1.3-3.7 0-.9.1-1.8.3-2.7 1.5-6.1 7.8-18.1 15-34.3 1.6-3.7 1-2.6.8-2.3-6.2 6-10.9 8.9-14.4 10.5-5.8 2.6-13 2.6-14.5-4.1-.1-.4-.1-.8-.2-1.2-11.8 9.2-24.3 11.7-20-8.1-4.6 8.2-12.6 14.9-22.4 14.9-4.1 0-7.1-1.4-8.6-5.1-2.3-5.5 1.3-14.9 4.6-23.8 1.7-4.5 4-9.9 7.1-16.2 1.6-3.4 4.2-5.4 7.6-4.5.6.2 1.1.4 1.6.7 2.6 1.8 1.6 4.5.3 7.2-3.8 7.5-7.1 13-9.3 20.8-.9 3.3-2 9 1.5 9 2.4 0 4.7-.8 6.9-2.4 4.6-3.4 8.3-8.5 11.1-13.5 2-3.6 4.4-8.3 5.6-12.3.5-1.7 1.1-3.3 1.8-4.8 1.1-2.5 2.6-5.1 5.2-5.1 1.3 0 2.4.5 3.2 1.5 1.7 2.2 1.3 4.5.4 6.9-2 5.6-4.7 10.6-6.9 16.7-1.3 3.5-2.7 8-2.7 11.7 0 3.4 3.7 2.6 6.8 1.2 2.4-1.1 4.8-2.8 6.8-4.5 1.2-4.9.9-3.8 26.4-68.2 1.3-3.3 3.7-4.7 6.1-4.7 1.2 0 2.2.4 3.2 1.1 1.7 1.3 1.7 4.1 1 6.2-.7 1.9-.6 1.3-4.5 10.5-5.2 12.1-8.6 20.8-13.2 31.9-1.9 4.6-7.7 18.9-8.7 22.3-.6 2.2-1.3 5.8 1 5.8 5.4 0 19.3-13.1 23.1-17 .2-.3.5-.4.9-.6.6-1.9 1.2-3.7 1.7-5.5 1.4-3.8 2.7-8.2 5.3-11.3.8-1 1.7-1.6 2.7-1.6 2.8 0 4.2 1.2 4.2 4 0 1.1-.7 5.1-1.1 6.2 1.4-1.5 2.9-3 4.5-4.5 15-13.9 25.7-6.8 25.7.2 0 7.4-8.9 17.7-13.8 23.4-1.6 1.9-4.9 5.4-5 6.4 0 1.3.9 1.8 2.2 1.8 2 0 6.4-3.5 8-4.7 5-3.9 11.8-9.9 16.6-14.1l14.8-136.8c-30.5 17.1-197.6 17.2-228.3.2zm229.7-8.5c0 21-231.2 21-231.2 0 0-8.8 51.8-15.9 115.6-15.9 9 0 17.8.1 26.3.4l12.6-48.7L228.1.6c1.4-1.4 5.8-.2 9.9 3.5s6.6 7.9 5.3 9.3l-.1.1L185.9 74l-10 40.7c39.9 2.6 67.6 8.1 67.6 14.6zm-69.4 4.6c0-.8-.9-1.5-2.5-2.1l-.2.8c0 1.3-5 2.4-11.1 2.4s-11.1-1.1-11.1-2.4c0-.1 0-.2.1-.3l.2-.7c-1.8.6-3 1.4-3 2.3 0 2.1 6.2 3.7 13.7 3.7 7.7.1 13.9-1.6 13.9-3.7z" } }, "free": ["brands"] }, "gun": { "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["firearm", "pistol", "weapon"] }, "styles": ["solid"], "unicode": "e19b", "label": "Gun", "voted": true, "svg": { "solid": { "last_modified": 1684767601, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M528 56c0-13.3-10.7-24-24-24s-24 10.7-24 24v8H32C14.3 64 0 78.3 0 96V208c0 17.7 14.3 32 32 32H42c20.8 0 36.1 19.6 31 39.8L33 440.2c-2.4 9.6-.2 19.7 5.8 27.5S54.1 480 64 480h96c14.7 0 27.5-10 31-24.2L217 352H321.4c23.7 0 44.8-14.9 52.7-37.2L400.9 240H432c8.5 0 16.6-3.4 22.6-9.4L477.3 208H544c17.7 0 32-14.3 32-32V96c0-17.7-14.3-32-32-32H528V56zM321.4 304H229l16-64h105l-21 58.7c-1.1 3.2-4.2 5.3-7.5 5.3zM80 128H464c8.8 0 16 7.2 16 16s-7.2 16-16 16H80c-8.8 0-16-7.2-16-16s7.2-16 16-16z" } }, "free": ["solid"] }, "h": { "aliases": { "unicodes": { "composite": ["68"] } }, "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Latin Capital Letter H", "Latin Small Letter H", "letter"] }, "styles": ["solid"], "unicode": "48", "label": "H", "voted": false, "svg": { "solid": { "last_modified": 1684767246, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M320 256l0 192c0 17.7 14.3 32 32 32s32-14.3 32-32l0-224V64c0-17.7-14.3-32-32-32s-32 14.3-32 32V192L64 192 64 64c0-17.7-14.3-32-32-32S0 46.3 0 64V448c0 17.7 14.3 32 32 32s32-14.3 32-32l0-192 256 0z" } }, "free": ["solid"] }, "hacker-news": { "changes": ["4.1.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f1d4", "label": "Hacker News", "voted": false, "svg": { "brands": { "last_modified": 1660014479, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M0 32v448h448V32H0zm21.2 197.2H21c.1-.1.2-.3.3-.4 0 .1 0 .3-.1.4zm218 53.9V384h-31.4V281.3L128 128h37.3c52.5 98.3 49.2 101.2 59.3 125.6 12.3-27 5.8-24.4 60.6-125.6H320l-80.8 155.1z" } }, "free": ["brands"] }, "hackerrank": { "changes": ["5.2.0", "5.8.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f5f7", "label": "Hackerrank", "voted": true, "svg": { "brands": { "last_modified": 1660014473, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M477.5 128C463 103.05 285.13 0 256.16 0S49.25 102.79 34.84 128s-14.49 230.8 0 256 192.38 128 221.32 128S463 409.08 477.49 384s14.51-231 .01-256zM316.13 414.22c-4 0-40.91-35.77-38-38.69.87-.87 6.26-1.48 17.55-1.83 0-26.23.59-68.59.94-86.32 0-2-.44-3.43-.44-5.85h-79.93c0 7.1-.46 36.2 1.37 72.88.23 4.54-1.58 6-5.74 5.94-10.13 0-20.27-.11-30.41-.08-4.1 0-5.87-1.53-5.74-6.11.92-33.44 3-84-.15-212.67v-3.17c-9.67-.35-16.38-1-17.26-1.84-2.92-2.92 34.54-38.69 38.49-38.69s41.17 35.78 38.27 38.69c-.87.87-7.9 1.49-16.77 1.84v3.16c-2.42 25.75-2 79.59-2.63 105.39h80.26c0-4.55.39-34.74-1.2-83.64-.1-3.39.95-5.17 4.21-5.2 11.07-.08 22.15-.13 33.23-.06 3.46 0 4.57 1.72 4.5 5.38C333 354.64 336 341.29 336 373.69c8.87.35 16.82 1 17.69 1.84 2.88 2.91-33.62 38.69-37.58 38.69z" } }, "free": ["brands"] }, "hammer": { "aliases": { "unicodes": { "composite": ["1f528"], "secondary": ["10f6e3"] } }, "changes": ["5.4.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "admin", "fix", "hammer", "recovery", "repair", "settings", "tool" ] }, "styles": ["solid"], "unicode": "f6e3", "label": "Hammer", "voted": true, "svg": { "solid": { "last_modified": 1684767601, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M413.5 237.5c-28.2 4.8-58.2-3.6-80-25.4l-38.1-38.1C280.4 159 272 138.8 272 117.6V105.5L192.3 62c-5.3-2.9-8.6-8.6-8.3-14.7s3.9-11.5 9.5-14l47.2-21C259.1 4.2 279 0 299.2 0h18.1c36.7 0 72 14 98.7 39.1l44.6 42c24.2 22.8 33.2 55.7 26.6 86L503 183l8-8c9.4-9.4 24.6-9.4 33.9 0l24 24c9.4 9.4 9.4 24.6 0 33.9l-88 88c-9.4 9.4-24.6 9.4-33.9 0l-24-24c-9.4-9.4-9.4-24.6 0-33.9l8-8-17.5-17.5zM27.4 377.1L260.9 182.6c3.5 4.9 7.5 9.6 11.8 14l38.1 38.1c6 6 12.4 11.2 19.2 15.7L134.9 484.6c-14.5 17.4-36 27.4-58.6 27.4C34.1 512 0 477.8 0 435.7c0-22.6 10.1-44.1 27.4-58.6z" } }, "free": ["solid"] }, "hamsa": { "aliases": { "unicodes": { "secondary": ["10f665"] } }, "changes": ["5.3.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "amulet", "christianity", "islam", "jewish", "judaism", "muslim", "protection" ] }, "styles": ["solid"], "unicode": "f665", "label": "Hamsa", "voted": false, "svg": { "solid": { "last_modified": 1684767602, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M34.6 288H80c8.8 0 16-7.2 16-16V72c0-22.1 17.9-40 40-40s40 17.9 40 40V204c0 11 9 20 20 20s20-9 20-20V40c0-22.1 17.9-40 40-40s40 17.9 40 40V204c0 11 9 20 20 20s20-9 20-20V72c0-22.1 17.9-40 40-40s40 17.9 40 40V272c0 8.8 7.2 16 16 16h45.4c19.1 0 34.6 15.5 34.6 34.6c0 8.6-3.2 16.9-9 23.3L416.6 441c-41.1 45.2-99.4 71-160.6 71s-119.4-25.8-160.6-71L9 345.9c-5.8-6.4-9-14.7-9-23.3C0 303.5 15.5 288 34.6 288zM256 288c-38.4 0-76.8 35.8-90.6 50.2c-3.6 3.7-5.4 8.7-5.4 13.8s1.8 10.1 5.4 13.8C179.2 380.2 217.6 416 256 416s76.8-35.8 90.6-50.2c3.6-3.7 5.4-8.7 5.4-13.8s-1.8-10.1-5.4-13.8C332.8 323.8 294.4 288 256 288zm0 32a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" } }, "free": ["solid"] }, "hand": { "aliases": { "names": ["hand-paper"], "unicodes": { "composite": ["1f91a", "270b"], "secondary": ["10f256"] } }, "changes": ["4.4.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "Raised Hand", "backhand", "game", "halt", "palm", "raised", "raised back of hand", "roshambo", "stop" ] }, "styles": ["solid", "regular"], "unicode": "f256", "label": "Hand", "voted": false, "svg": { "solid": { "last_modified": 1684766194, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M288 32c0-17.7-14.3-32-32-32s-32 14.3-32 32V240c0 8.8-7.2 16-16 16s-16-7.2-16-16V64c0-17.7-14.3-32-32-32s-32 14.3-32 32V336c0 1.5 0 3.1 .1 4.6L67.6 283c-16-15.2-41.3-14.6-56.6 1.4s-14.6 41.3 1.4 56.6L124.8 448c43.1 41.1 100.4 64 160 64H304c97.2 0 176-78.8 176-176V128c0-17.7-14.3-32-32-32s-32 14.3-32 32V240c0 8.8-7.2 16-16 16s-16-7.2-16-16V64c0-17.7-14.3-32-32-32s-32 14.3-32 32V240c0 8.8-7.2 16-16 16s-16-7.2-16-16V32z" }, "regular": { "last_modified": 1684766194, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 0c-25.3 0-47.2 14.7-57.6 36c-7-2.6-14.5-4-22.4-4c-35.3 0-64 28.7-64 64V261.5l-2.7-2.7c-25-25-65.5-25-90.5 0s-25 65.5 0 90.5L106.5 437c48 48 113.1 75 181 75H296h8c1.5 0 3-.1 4.5-.4c91.7-6.2 165-79.4 171.1-171.1c.3-1.5 .4-3 .4-4.5V160c0-35.3-28.7-64-64-64c-5.5 0-10.9 .7-16 2V96c0-35.3-28.7-64-64-64c-7.9 0-15.4 1.4-22.4 4C303.2 14.7 281.3 0 256 0zM240 96.1c0 0 0-.1 0-.1V64c0-8.8 7.2-16 16-16s16 7.2 16 16V95.9c0 0 0 .1 0 .1V232c0 13.3 10.7 24 24 24s24-10.7 24-24V96c0 0 0 0 0-.1c0-8.8 7.2-16 16-16s16 7.2 16 16v55.9c0 0 0 .1 0 .1v80c0 13.3 10.7 24 24 24s24-10.7 24-24V160.1c0 0 0-.1 0-.1c0-8.8 7.2-16 16-16s16 7.2 16 16V332.9c-.1 .6-.1 1.3-.2 1.9c-3.4 69.7-59.3 125.6-129 129c-.6 0-1.3 .1-1.9 .2H296h-8.5c-55.2 0-108.1-21.9-147.1-60.9L52.7 315.3c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0L119 336.4c6.9 6.9 17.2 8.9 26.2 5.2s14.8-12.5 14.8-22.2V96c0-8.8 7.2-16 16-16c8.8 0 16 7.1 16 15.9V232c0 13.3 10.7 24 24 24s24-10.7 24-24V96.1z" } }, "free": ["regular", "solid"] }, "hand-back-fist": { "aliases": { "names": ["hand-rock"], "unicodes": { "secondary": ["10f255"] } }, "changes": ["4.4.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["fist", "game", "roshambo"] }, "styles": ["solid", "regular"], "unicode": "f255", "label": "Hand Back Fist", "voted": false, "svg": { "solid": { "last_modified": 1684766194, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M144 0C117.5 0 96 21.5 96 48V96v28.5V176c0 8.8-7.2 16-16 16s-16-7.2-16-16V149.3l-9 7.5C40.4 169 32 187 32 206V244c0 38 16.9 74 46.1 98.3L128 384v96c0 17.7 14.3 32 32 32H320c17.7 0 32-14.3 32-32V374.7c46.9-19 80-65 80-118.7V176 160 144c0-26.5-21.5-48-48-48c-12.4 0-23.6 4.7-32.1 12.3C350 83.5 329.3 64 304 64c-12.4 0-23.6 4.7-32.1 12.3C270 51.5 249.3 32 224 32c-12.4 0-23.6 4.7-32.1 12.3C190 19.5 169.3 0 144 0z" }, "regular": { "last_modified": 1684766194, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M144 64c0-8.8 7.2-16 16-16s16 7.2 16 16c0 9.1 5.1 17.4 13.3 21.5s17.9 3.2 25.1-2.3c2.7-2 6-3.2 9.6-3.2c8.8 0 16 7.2 16 16c0 9.1 5.1 17.4 13.3 21.5s17.9 3.2 25.1-2.3c2.7-2 6-3.2 9.6-3.2c8.8 0 16 7.2 16 16c0 9.1 5.1 17.4 13.3 21.5s17.9 3.2 25.1-2.3c2.7-2 6-3.2 9.6-3.2c8.8 0 16 7.2 16 16V264c0 31.3-20 58-48 67.9c-9.6 3.4-16 12.5-16 22.6V488c0 13.3 10.7 24 24 24s24-10.7 24-24V370.2c38-20.1 64-60.1 64-106.2V160c0-35.3-28.7-64-64-64c-2.8 0-5.6 .2-8.3 .5C332.8 77.1 311.9 64 288 64c-2.8 0-5.6 .2-8.3 .5C268.8 45.1 247.9 32 224 32c-2.8 0-5.6 .2-8.3 .5C204.8 13.1 183.9 0 160 0C124.7 0 96 28.7 96 64v64.3c-11.7 7.4-22.5 16.4-32 26.9l17.8 16.1L64 155.2l-9.4 10.5C40 181.8 32 202.8 32 224.6v12.8c0 49.6 24.2 96.1 64.8 124.5l13.8-19.7L96.8 361.9l8.9 6.2c6.9 4.8 14.4 8.6 22.3 11.3V488c0 13.3 10.7 24 24 24s24-10.7 24-24V359.9c0-12.6-9.8-23.1-22.4-23.9c-7.3-.5-14.3-2.9-20.3-7.1l-13.1 18.7 13.1-18.7-8.9-6.2C96.6 303.1 80 271.3 80 237.4V224.6c0-9.9 3.7-19.4 10.3-26.8l9.4-10.5c3.8-4.2 7.9-8.1 12.3-11.6V208c0 8.8 7.2 16 16 16s16-7.2 16-16V142.3 128 64z" } }, "free": ["regular", "solid"] }, "hand-dots": { "aliases": { "names": ["allergies"], "unicodes": { "secondary": ["10f461"] } }, "changes": ["5.0.7", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "allergy", "freckles", "hand", "hives", "palm", "pox", "skin", "spots" ] }, "styles": ["solid"], "unicode": "f461", "label": "Hand Dots", "voted": false, "svg": { "solid": { "last_modified": 1684766193, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M288 32c0-17.7-14.3-32-32-32s-32 14.3-32 32V240c0 8.8-7.2 16-16 16s-16-7.2-16-16V64c0-17.7-14.3-32-32-32s-32 14.3-32 32V336c0 1.5 0 3.1 .1 4.6L67.6 283c-16-15.2-41.3-14.6-56.6 1.4s-14.6 41.3 1.4 56.6L124.8 448c43.1 41.1 100.4 64 160 64H304c97.2 0 176-78.8 176-176V128c0-17.7-14.3-32-32-32s-32 14.3-32 32V240c0 8.8-7.2 16-16 16s-16-7.2-16-16V64c0-17.7-14.3-32-32-32s-32 14.3-32 32V240c0 8.8-7.2 16-16 16s-16-7.2-16-16V32zM240 336a16 16 0 1 1 32 0 16 16 0 1 1 -32 0zm80 16a16 16 0 1 1 0 32 16 16 0 1 1 0-32zm48-16a16 16 0 1 1 32 0 16 16 0 1 1 -32 0zm-16 80a16 16 0 1 1 0 32 16 16 0 1 1 0-32zM240 432a16 16 0 1 1 32 0 16 16 0 1 1 -32 0zm-48-48a16 16 0 1 1 0 32 16 16 0 1 1 0-32z" } }, "free": ["solid"] }, "hand-fist": { "aliases": { "names": ["fist-raised"], "unicodes": { "composite": ["270a"], "secondary": ["10f6de"] } }, "changes": ["5.4.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "Dungeons & Dragons", "clenched", "d&d", "dnd", "fantasy", "fist", "hand", "ki", "monk", "punch", "raised fist", "resist", "strength", "unarmed combat" ] }, "styles": ["solid"], "unicode": "f6de", "label": "Hand Fist", "voted": false, "svg": { "solid": { "last_modified": 1684766193, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M192 0c17.7 0 32 14.3 32 32V144H160V32c0-17.7 14.3-32 32-32zM64 64c0-17.7 14.3-32 32-32s32 14.3 32 32v80H64V64zm192 0c0-17.7 14.3-32 32-32s32 14.3 32 32v96c0 17.7-14.3 32-32 32s-32-14.3-32-32V64zm96 64c0-17.7 14.3-32 32-32s32 14.3 32 32v64c0 17.7-14.3 32-32 32s-32-14.3-32-32V128zm-96 88l0-.6c9.4 5.4 20.3 8.6 32 8.6c13.2 0 25.4-4 35.6-10.8c8.7 24.9 32.5 42.8 60.4 42.8c11.7 0 22.6-3.1 32-8.6V256c0 52.3-25.1 98.8-64 128v96c0 17.7-14.3 32-32 32H160c-17.7 0-32-14.3-32-32V401.6c-17.3-7.9-33.2-18.8-46.9-32.5L69.5 357.5C45.5 333.5 32 300.9 32 267V240c0-35.3 28.7-64 64-64h88c22.1 0 40 17.9 40 40s-17.9 40-40 40H128c-8.8 0-16 7.2-16 16s7.2 16 16 16h56c39.8 0 72-32.2 72-72z" } }, "free": ["solid"] }, "hand-holding": { "aliases": { "unicodes": { "secondary": ["10f4bd"] } }, "changes": ["5.0.9", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["carry", "lift"] }, "styles": ["solid"], "unicode": "f4bd", "label": "Hand Holding", "voted": false, "svg": { "solid": { "last_modified": 1684766193, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M559.7 392.2c17.8-13.1 21.6-38.1 8.5-55.9s-38.1-21.6-55.9-8.5L392.6 416H272c-8.8 0-16-7.2-16-16s7.2-16 16-16h16 64c17.7 0 32-14.3 32-32s-14.3-32-32-32H288 272 193.7c-29.1 0-57.3 9.9-80 28L68.8 384H32c-17.7 0-32 14.3-32 32v64c0 17.7 14.3 32 32 32H192 352.5c29 0 57.3-9.3 80.7-26.5l126.6-93.3zm-366.1-8.3a.5 .5 0 1 1 -.9 .1 .5 .5 0 1 1 .9-.1z" } }, "free": ["solid"] }, "hand-holding-dollar": { "aliases": { "names": ["hand-holding-usd"], "unicodes": { "secondary": ["10f4c0"] } }, "changes": [ "5.0.9", "5.11.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0", "6.4.1" ], "ligatures": [], "search": { "terms": [ "$", "carry", "dollar sign", "donation", "giving", "lift", "money", "price" ] }, "styles": ["solid"], "unicode": "f4c0", "label": "Hand Holding Dollar", "voted": false, "svg": { "solid": { "last_modified": 1684766194, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M312 24V34.5c6.4 1.2 12.6 2.7 18.2 4.2c12.8 3.4 20.4 16.6 17 29.4s-16.6 20.4-29.4 17c-10.9-2.9-21.1-4.9-30.2-5c-7.3-.1-14.7 1.7-19.4 4.4c-2.1 1.3-3.1 2.4-3.5 3c-.3 .5-.7 1.2-.7 2.8c0 .3 0 .5 0 .6c.2 .2 .9 1.2 3.3 2.6c5.8 3.5 14.4 6.2 27.4 10.1l.9 .3c11.1 3.3 25.9 7.8 37.9 15.3c13.7 8.6 26.1 22.9 26.4 44.9c.3 22.5-11.4 38.9-26.7 48.5c-6.7 4.1-13.9 7-21.3 8.8V232c0 13.3-10.7 24-24 24s-24-10.7-24-24V220.6c-9.5-2.3-18.2-5.3-25.6-7.8c-2.1-.7-4.1-1.4-6-2c-12.6-4.2-19.4-17.8-15.2-30.4s17.8-19.4 30.4-15.2c2.6 .9 5 1.7 7.3 2.5c13.6 4.6 23.4 7.9 33.9 8.3c8 .3 15.1-1.6 19.2-4.1c1.9-1.2 2.8-2.2 3.2-2.9c.4-.6 .9-1.8 .8-4.1l0-.2c0-1 0-2.1-4-4.6c-5.7-3.6-14.3-6.4-27.1-10.3l-1.9-.6c-10.8-3.2-25-7.5-36.4-14.4c-13.5-8.1-26.5-22-26.6-44.1c-.1-22.9 12.9-38.6 27.7-47.4c6.4-3.8 13.3-6.4 20.2-8.2V24c0-13.3 10.7-24 24-24s24 10.7 24 24zM568.2 336.3c13.1 17.8 9.3 42.8-8.5 55.9L433.1 485.5c-23.4 17.2-51.6 26.5-80.7 26.5H192 32c-17.7 0-32-14.3-32-32V416c0-17.7 14.3-32 32-32H68.8l44.9-36c22.7-18.2 50.9-28 80-28H272h16 64c17.7 0 32 14.3 32 32s-14.3 32-32 32H288 272c-8.8 0-16 7.2-16 16s7.2 16 16 16H392.6l119.7-88.2c17.8-13.1 42.8-9.3 55.9 8.5zM193.6 384l0 0-.9 0c.3 0 .6 0 .9 0z" } }, "free": ["solid"] }, "hand-holding-droplet": { "aliases": { "names": ["hand-holding-water"], "unicodes": { "secondary": ["10f4c1"] } }, "changes": [ "5.0.9", "5.13.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0", "6.4.1" ], "ligatures": [], "search": { "terms": ["carry", "covid-19", "drought", "grow", "lift", "sanitation"] }, "styles": ["solid"], "unicode": "f4c1", "label": "Hand Holding Droplet", "voted": false, "svg": { "solid": { "last_modified": 1684766193, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M275.5 6.6C278.3 2.5 283 0 288 0s9.7 2.5 12.5 6.6L366.8 103C378 119.3 384 138.6 384 158.3V160c0 53-43 96-96 96s-96-43-96-96v-1.7c0-19.8 6-39 17.2-55.3L275.5 6.6zM568.2 336.3c13.1 17.8 9.3 42.8-8.5 55.9L433.1 485.5c-23.4 17.2-51.6 26.5-80.7 26.5H192 32c-17.7 0-32-14.3-32-32V416c0-17.7 14.3-32 32-32H68.8l44.9-36c22.7-18.2 50.9-28 80-28H272h16 64c17.7 0 32 14.3 32 32s-14.3 32-32 32H288 272c-8.8 0-16 7.2-16 16s7.2 16 16 16H392.6l119.7-88.2c17.8-13.1 42.8-9.3 55.9 8.5zM193.6 384l0 0-.9 0c.3 0 .6 0 .9 0z" } }, "free": ["solid"] }, "hand-holding-hand": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0", "6.4.1"], "ligatures": [], "search": { "terms": ["care", "give", "help", "hold", "protect"] }, "styles": ["solid"], "unicode": "e4f7", "label": "Hand Holding Hand", "voted": false, "svg": { "solid": { "last_modified": 1684766193, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M7.8 207.7c-13.1-17.8-9.3-42.8 8.5-55.9L142.9 58.5C166.2 41.3 194.5 32 223.5 32H384 544c17.7 0 32 14.3 32 32v64c0 17.7-14.3 32-32 32H507.2l-44.9 36c-22.7 18.2-50.9 28-80 28H304 288 224c-17.7 0-32-14.3-32-32s14.3-32 32-32h64 16c8.8 0 16-7.2 16-16s-7.2-16-16-16H183.4L63.7 216.2c-17.8 13.1-42.8 9.3-55.9-8.5zM382.4 160l0 0 .9 0c-.3 0-.6 0-.9 0zM568.2 304.3c13.1 17.8 9.3 42.8-8.5 55.9L433.1 453.5c-23.4 17.2-51.6 26.5-80.7 26.5H192 32c-17.7 0-32-14.3-32-32V384c0-17.7 14.3-32 32-32H68.8l44.9-36c22.7-18.2 50.9-28 80-28H272h16 64c17.7 0 32 14.3 32 32s-14.3 32-32 32H288 272c-8.8 0-16 7.2-16 16s7.2 16 16 16H392.6l119.7-88.2c17.8-13.1 42.8-9.3 55.9 8.5zM193.6 352l0 0-.9 0c.3 0 .6 0 .9 0z" } }, "free": ["solid"] }, "hand-holding-heart": { "aliases": { "unicodes": { "secondary": ["10f4be"] } }, "changes": ["5.0.9", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0", "6.4.1"], "ligatures": [], "search": { "terms": ["carry", "charity", "gift", "lift", "package"] }, "styles": ["solid"], "unicode": "f4be", "label": "Hand Holding Heart", "voted": false, "svg": { "solid": { "last_modified": 1684766194, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M163.9 136.9c-29.4-29.8-29.4-78.2 0-108s77-29.8 106.4 0l17.7 18 17.7-18c29.4-29.8 77-29.8 106.4 0s29.4 78.2 0 108L310.5 240.1c-6.2 6.3-14.3 9.4-22.5 9.4s-16.3-3.1-22.5-9.4L163.9 136.9zM568.2 336.3c13.1 17.8 9.3 42.8-8.5 55.9L433.1 485.5c-23.4 17.2-51.6 26.5-80.7 26.5H192 32c-17.7 0-32-14.3-32-32V416c0-17.7 14.3-32 32-32H68.8l44.9-36c22.7-18.2 50.9-28 80-28H272h16 64c17.7 0 32 14.3 32 32s-14.3 32-32 32H288 272c-8.8 0-16 7.2-16 16s7.2 16 16 16H392.6l119.7-88.2c17.8-13.1 42.8-9.3 55.9 8.5zM193.6 384l0 0-.9 0c.3 0 .6 0 .9 0z" } }, "free": ["solid"] }, "hand-holding-medical": { "aliases": { "unicodes": { "secondary": ["10e05c"] } }, "changes": [ "5.13.0", "5.14.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0", "6.4.1" ], "ligatures": [], "search": { "terms": ["care", "covid-19", "donate", "help"] }, "styles": ["solid"], "unicode": "e05c", "label": "Hand Holding Medical", "voted": false, "svg": { "solid": { "last_modified": 1684766193, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M224 24V80H168c-13.3 0-24 10.7-24 24v48c0 13.3 10.7 24 24 24h56v56c0 13.3 10.7 24 24 24h48c13.3 0 24-10.7 24-24V176h56c13.3 0 24-10.7 24-24V104c0-13.3-10.7-24-24-24H320V24c0-13.3-10.7-24-24-24H248c-13.3 0-24 10.7-24 24zM559.7 392.2c17.8-13.1 21.6-38.1 8.5-55.9s-38.1-21.6-55.9-8.5L392.6 416H272c-8.8 0-16-7.2-16-16s7.2-16 16-16h16 64c17.7 0 32-14.3 32-32s-14.3-32-32-32H288 272 193.7c-29.1 0-57.3 9.9-80 28L68.8 384H32c-17.7 0-32 14.3-32 32v64c0 17.7 14.3 32 32 32H192 352.5c29 0 57.3-9.3 80.7-26.5l126.6-93.3zm-367-8.2l.9 0 0 0c-.3 0-.6 0-.9 0z" } }, "free": ["solid"] }, "hand-lizard": { "aliases": { "unicodes": { "secondary": ["10f258"] } }, "changes": ["4.4.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["game", "roshambo"] }, "styles": ["solid", "regular"], "unicode": "f258", "label": "Hand Lizard", "voted": false, "svg": { "solid": { "last_modified": 1684766193, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 112C0 85.5 21.5 64 48 64H160h80 46.5c36.8 0 71.2 18 92.1 48.2l113.5 164c13 18.7 19.9 41 19.9 63.8v12 16 48c0 17.7-14.3 32-32 32H384c-17.7 0-32-14.3-32-32V402.2L273.9 352H240 160 112c-26.5 0-48-21.5-48-48s21.5-48 48-48h48 80c26.5 0 48-21.5 48-48s-21.5-48-48-48H160 48c-26.5 0-48-21.5-48-48z" }, "regular": { "last_modified": 1684766193, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M72 112c-13.3 0-24 10.7-24 24s10.7 24 24 24H240c35.3 0 64 28.7 64 64s-28.7 64-64 64H136c-13.3 0-24 10.7-24 24s10.7 24 24 24H288c4.5 0 8.9 1.3 12.7 3.6l64 40c7 4.4 11.3 12.1 11.3 20.4v24c0 13.3-10.7 24-24 24s-24-10.7-24-24V413.3L281.1 384H136c-39.8 0-72-32.2-72-72s32.2-72 72-72H240c8.8 0 16-7.2 16-16s-7.2-16-16-16H72c-39.8 0-72-32.2-72-72S32.2 64 72 64H281.6c46.7 0 90.9 21.5 119.7 58.3l78.4 100.1c20.9 26.7 32.3 59.7 32.3 93.7V424c0 13.3-10.7 24-24 24s-24-10.7-24-24V316.1c0-23.2-7.8-45.8-22.1-64.1L363.5 151.9c-19.7-25.2-49.9-39.9-81.9-39.9H72z" } }, "free": ["regular", "solid"] }, "hand-middle-finger": { "aliases": { "unicodes": { "composite": ["1f595"], "secondary": ["10f806"] } }, "changes": [ "5.7.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "finger", "flip the bird", "gesture", "hand", "hate", "middle finger", "rude" ] }, "styles": ["solid"], "unicode": "f806", "label": "Hand Middle Finger", "voted": true, "svg": { "solid": { "last_modified": 1684766193, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M232 0c-22.1 0-40 17.9-40 40V204.2c-8.5-7.6-19.7-12.2-32-12.2c-26.5 0-48 21.5-48 48v7 73c0 8.8-7.2 16-16 16s-16-7.2-16-16V264.3c-2 1.4-3.9 3-5.8 4.5L55 284.8C40.4 297 32 315 32 334V372c0 38 16.9 74 46.1 98.3l5.4 4.5c28.8 24 65 37.1 102.4 37.1H304c70.7 0 128-57.3 128-128V320 288c0-26.5-21.5-48-48-48c-12.4 0-23.6 4.7-32.1 12.3C350 227.5 329.3 208 304 208c-12.3 0-23.5 4.6-32 12.2V40c0-22.1-17.9-40-40-40z" } }, "free": ["solid"] }, "hand-peace": { "aliases": { "unicodes": { "composite": ["270c"], "secondary": ["10f25b"] } }, "changes": ["4.4.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["hand", "rest", "truce", "v", "victory", "victory hand"] }, "styles": ["solid", "regular"], "unicode": "f25b", "label": "Hand Peace", "voted": false, "svg": { "solid": { "last_modified": 1684766193, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M224 0c17.7 0 32 14.3 32 32V240H192V32c0-17.7 14.3-32 32-32zm96 160c17.7 0 32 14.3 32 32v64c0 17.7-14.3 32-32 32s-32-14.3-32-32V192c0-17.7 14.3-32 32-32zm64 64c0-17.7 14.3-32 32-32s32 14.3 32 32v64c0 17.7-14.3 32-32 32s-32-14.3-32-32V224zM93.3 51.2L175.9 240H106.1L34.7 76.8C27.6 60.6 35 41.8 51.2 34.7s35.1 .3 42.1 16.5zm27 221.3l-.2-.5h69.9H216c22.1 0 40 17.9 40 40s-17.9 40-40 40H160c-8.8 0-16 7.2-16 16s7.2 16 16 16h56c39.8 0 72-32.2 72-72l0-.6c9.4 5.4 20.3 8.6 32 8.6c13.2 0 25.4-4 35.6-10.8c8.7 24.9 32.5 42.8 60.4 42.8c11.7 0 22.6-3.1 32-8.6V352c0 88.4-71.6 160-160 160H226.3c-42.4 0-83.1-16.9-113.1-46.9l-11.6-11.6C77.5 429.5 64 396.9 64 363V336c0-32.7 24.6-59.7 56.3-63.5z" }, "regular": { "last_modified": 1684766193, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M250.8 1.4c-35.2-3.7-66.6 21.8-70.3 57L174 119 156.7 69.6C145 36.3 108.4 18.8 75.1 30.5S24.2 78.8 35.9 112.1L88.7 262.2C73.5 276.7 64 297.3 64 320v0 24c0 92.8 75.2 168 168 168h48c92.8 0 168-75.2 168-168V272 256 224c0-35.3-28.7-64-64-64c-7.9 0-15.4 1.4-22.4 4c-10.4-21.3-32.3-36-57.6-36c-.7 0-1.5 0-2.2 0l5.9-56.3c3.7-35.2-21.8-66.6-57-70.3zm-.2 155.4C243.9 166.9 240 179 240 192v48c0 .7 0 1.4 0 2c-5.1-1.3-10.5-2-16-2h-7.4l-5.4-15.3 17-161.3c.9-8.8 8.8-15.2 17.6-14.2s15.2 8.8 14.2 17.6l-9.5 90.1zM111.4 85.6L165.7 240H144c-4 0-8 .3-11.9 .9L81.2 96.2c-2.9-8.3 1.5-17.5 9.8-20.4s17.5 1.5 20.4 9.8zM288 192c0-8.8 7.2-16 16-16s16 7.2 16 16v32 16c0 8.8-7.2 16-16 16s-16-7.2-16-16V192zm38.4 108c10.4 21.3 32.3 36 57.6 36c5.5 0 10.9-.7 16-2v10c0 66.3-53.7 120-120 120H232c-66.3 0-120-53.7-120-120l0-24 0 0c0-17.7 14.3-32 32-32h80c8.8 0 16 7.2 16 16s-7.2 16-16 16H184c-13.3 0-24 10.7-24 24s10.7 24 24 24h40c35.3 0 64-28.7 64-64c0-.7 0-1.4 0-2c5.1 1.3 10.5 2 16 2c7.9 0 15.4-1.4 22.4-4zM400 272c0 8.8-7.2 16-16 16s-16-7.2-16-16V240 224c0-8.8 7.2-16 16-16s16 7.2 16 16v32 16z" } }, "free": ["regular", "solid"] }, "hand-point-down": { "aliases": { "unicodes": { "secondary": ["10f0a7"] } }, "changes": ["2.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["finger", "hand-o-down", "point"] }, "styles": ["solid", "regular"], "unicode": "f0a7", "label": "Hand Point Down", "voted": false, "svg": { "solid": { "last_modified": 1684766194, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M32 480c0 17.7 14.3 32 32 32s32-14.3 32-32V272H32V480zM224 320c0 17.7 14.3 32 32 32s32-14.3 32-32V256c0-17.7-14.3-32-32-32s-32 14.3-32 32v64zm-64 64c17.7 0 32-14.3 32-32V304c0-17.7-14.3-32-32-32s-32 14.3-32 32v48c0 17.7 14.3 32 32 32zm160-96c0 17.7 14.3 32 32 32s32-14.3 32-32V224c0-17.7-14.3-32-32-32s-32 14.3-32 32v64zm-96-88l0 .6c9.4-5.4 20.3-8.6 32-8.6c13.2 0 25.4 4 35.6 10.8c8.7-24.9 32.5-42.8 60.4-42.8c11.7 0 22.6 3.1 32 8.6V160C384 71.6 312.4 0 224 0H162.3C119.8 0 79.1 16.9 49.1 46.9L37.5 58.5C13.5 82.5 0 115.1 0 149v27c0 35.3 28.7 64 64 64h88c22.1 0 40-17.9 40-40s-17.9-40-40-40H96c-8.8 0-16-7.2-16-16s7.2-16 16-16h56c39.8 0 72 32.2 72 72z" }, "regular": { "last_modified": 1684766194, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M64 448l0-177.6c5.2 1 10.5 1.6 16 1.6l16 0 0 32 0 144c0 8.8-7.2 16-16 16s-16-7.2-16-16zM80 224c-17.7 0-32-14.3-32-32c0 0 0 0 0 0l0-24c0-66.3 53.7-120 120-120l48 0c52.5 0 97.1 33.7 113.4 80.7c-3.1-.5-6.2-.7-9.4-.7c-20 0-37.9 9.2-49.7 23.6c-9-4.9-19.4-7.6-30.3-7.6c-15.1 0-29 5.3-40 14c-11-8.8-24.9-14-40-14l-40 0c-13.3 0-24 10.7-24 24s10.7 24 24 24l40 0c8.8 0 16 7.2 16 16s-7.2 16-16 16l-40 0-40 0zM0 192s0 0 0 0c0 18 6 34.6 16 48l0 208c0 35.3 28.7 64 64 64s64-28.7 64-64l0-82c5.1 1.3 10.5 2 16 2c25.3 0 47.2-14.7 57.6-36c7 2.6 14.5 4 22.4 4c20 0 37.9-9.2 49.7-23.6c9 4.9 19.4 7.6 30.3 7.6c35.3 0 64-28.7 64-64l0-64 0-24C384 75.2 308.8 0 216 0L168 0C75.2 0 0 75.2 0 168l0 24zm336 64c0 8.8-7.2 16-16 16s-16-7.2-16-16l0-48 0-16c0-8.8 7.2-16 16-16s16 7.2 16 16l0 64zM160 272c5.5 0 10.9-.7 16-2l0 2 0 32c0 8.8-7.2 16-16 16s-16-7.2-16-16l0-32 16 0zm64-24l0-40c0-8.8 7.2-16 16-16s16 7.2 16 16l0 48 0 16c0 8.8-7.2 16-16 16s-16-7.2-16-16l0-24z" } }, "free": ["regular", "solid"] }, "hand-point-left": { "aliases": { "unicodes": { "secondary": ["10f0a5"] } }, "changes": [ "2.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0", "6.4.1" ], "ligatures": [], "search": { "terms": ["back", "finger", "hand-o-left", "left", "point", "previous"] }, "styles": ["solid", "regular"], "unicode": "f0a5", "label": "Hand Point Left", "voted": false, "svg": { "solid": { "last_modified": 1684766193, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M32 96C14.3 96 0 110.3 0 128s14.3 32 32 32l208 0 0-64L32 96zM192 288c-17.7 0-32 14.3-32 32s14.3 32 32 32l64 0c17.7 0 32-14.3 32-32s-14.3-32-32-32l-64 0zm-64-64c0 17.7 14.3 32 32 32l48 0c17.7 0 32-14.3 32-32s-14.3-32-32-32l-48 0c-17.7 0-32 14.3-32 32zm96 160c-17.7 0-32 14.3-32 32s14.3 32 32 32l64 0c17.7 0 32-14.3 32-32s-14.3-32-32-32l-64 0zm88-96l-.6 0c5.4 9.4 8.6 20.3 8.6 32c0 13.2-4 25.4-10.8 35.6c24.9 8.7 42.8 32.5 42.8 60.4c0 11.7-3.1 22.6-8.6 32l8.6 0c88.4 0 160-71.6 160-160l0-61.7c0-42.4-16.9-83.1-46.9-113.1l-11.6-11.6C429.5 77.5 396.9 64 363 64l-27 0c-35.3 0-64 28.7-64 64l0 88c0 22.1 17.9 40 40 40s40-17.9 40-40l0-56c0-8.8 7.2-16 16-16s16 7.2 16 16l0 56c0 39.8-32.2 72-72 72z" }, "regular": { "last_modified": 1684766193, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M64 128l177.6 0c-1 5.2-1.6 10.5-1.6 16l0 16-32 0L64 160c-8.8 0-16-7.2-16-16s7.2-16 16-16zm224 16c0-17.7 14.3-32 32-32c0 0 0 0 0 0l24 0c66.3 0 120 53.7 120 120l0 48c0 52.5-33.7 97.1-80.7 113.4c.5-3.1 .7-6.2 .7-9.4c0-20-9.2-37.9-23.6-49.7c4.9-9 7.6-19.4 7.6-30.3c0-15.1-5.3-29-14-40c8.8-11 14-24.9 14-40l0-40c0-13.3-10.7-24-24-24s-24 10.7-24 24l0 40c0 8.8-7.2 16-16 16s-16-7.2-16-16l0-40 0-40zm32-80s0 0 0 0c-18 0-34.6 6-48 16L64 80C28.7 80 0 108.7 0 144s28.7 64 64 64l82 0c-1.3 5.1-2 10.5-2 16c0 25.3 14.7 47.2 36 57.6c-2.6 7-4 14.5-4 22.4c0 20 9.2 37.9 23.6 49.7c-4.9 9-7.6 19.4-7.6 30.3c0 35.3 28.7 64 64 64l64 0 24 0c92.8 0 168-75.2 168-168l0-48c0-92.8-75.2-168-168-168l-24 0zM256 400c-8.8 0-16-7.2-16-16s7.2-16 16-16l48 0 16 0c8.8 0 16 7.2 16 16s-7.2 16-16 16l-64 0zM240 224c0 5.5 .7 10.9 2 16l-2 0-32 0c-8.8 0-16-7.2-16-16s7.2-16 16-16l32 0 0 16zm24 64l40 0c8.8 0 16 7.2 16 16s-7.2 16-16 16l-48 0-16 0c-8.8 0-16-7.2-16-16s7.2-16 16-16l24 0z" } }, "free": ["regular", "solid"] }, "hand-point-right": { "aliases": { "unicodes": { "secondary": ["10f0a4"] } }, "changes": [ "2.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0", "6.4.1" ], "ligatures": [], "search": { "terms": ["finger", "forward", "hand-o-right", "next", "point", "right"] }, "styles": ["solid", "regular"], "unicode": "f0a4", "label": "Hand Point Right", "voted": false, "svg": { "solid": { "last_modified": 1684766194, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M480 96c17.7 0 32 14.3 32 32s-14.3 32-32 32l-208 0 0-64 208 0zM320 288c17.7 0 32 14.3 32 32s-14.3 32-32 32l-64 0c-17.7 0-32-14.3-32-32s14.3-32 32-32l64 0zm64-64c0 17.7-14.3 32-32 32l-48 0c-17.7 0-32-14.3-32-32s14.3-32 32-32l48 0c17.7 0 32 14.3 32 32zM288 384c17.7 0 32 14.3 32 32s-14.3 32-32 32l-64 0c-17.7 0-32-14.3-32-32s14.3-32 32-32l64 0zm-88-96l.6 0c-5.4 9.4-8.6 20.3-8.6 32c0 13.2 4 25.4 10.8 35.6C177.9 364.3 160 388.1 160 416c0 11.7 3.1 22.6 8.6 32l-8.6 0C71.6 448 0 376.4 0 288l0-61.7c0-42.4 16.9-83.1 46.9-113.1l11.6-11.6C82.5 77.5 115.1 64 149 64l27 0c35.3 0 64 28.7 64 64l0 88c0 22.1-17.9 40-40 40s-40-17.9-40-40l0-56c0-8.8-7.2-16-16-16s-16 7.2-16 16l0 56c0 39.8 32.2 72 72 72z" }, "regular": { "last_modified": 1684766194, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M448 128l-177.6 0c1 5.2 1.6 10.5 1.6 16l0 16 32 0 144 0c8.8 0 16-7.2 16-16s-7.2-16-16-16zM224 144c0-17.7-14.3-32-32-32c0 0 0 0 0 0l-24 0c-66.3 0-120 53.7-120 120l0 48c0 52.5 33.7 97.1 80.7 113.4c-.5-3.1-.7-6.2-.7-9.4c0-20 9.2-37.9 23.6-49.7c-4.9-9-7.6-19.4-7.6-30.3c0-15.1 5.3-29 14-40c-8.8-11-14-24.9-14-40l0-40c0-13.3 10.7-24 24-24s24 10.7 24 24l0 40c0 8.8 7.2 16 16 16s16-7.2 16-16l0-40 0-40zM192 64s0 0 0 0c18 0 34.6 6 48 16l208 0c35.3 0 64 28.7 64 64s-28.7 64-64 64l-82 0c1.3 5.1 2 10.5 2 16c0 25.3-14.7 47.2-36 57.6c2.6 7 4 14.5 4 22.4c0 20-9.2 37.9-23.6 49.7c4.9 9 7.6 19.4 7.6 30.3c0 35.3-28.7 64-64 64l-64 0-24 0C75.2 448 0 372.8 0 280l0-48C0 139.2 75.2 64 168 64l24 0zm64 336c8.8 0 16-7.2 16-16s-7.2-16-16-16l-48 0-16 0c-8.8 0-16 7.2-16 16s7.2 16 16 16l64 0zm16-176c0 5.5-.7 10.9-2 16l2 0 32 0c8.8 0 16-7.2 16-16s-7.2-16-16-16l-32 0 0 16zm-24 64l-40 0c-8.8 0-16 7.2-16 16s7.2 16 16 16l48 0 16 0c8.8 0 16-7.2 16-16s-7.2-16-16-16l-24 0z" } }, "free": ["regular", "solid"] }, "hand-point-up": { "aliases": { "unicodes": { "composite": ["261d"], "secondary": ["10f0a6"] } }, "changes": ["2.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "finger", "hand", "hand-o-up", "index", "index pointing up", "point", "up" ] }, "styles": ["solid", "regular"], "unicode": "f0a6", "label": "Hand Point Up", "voted": false, "svg": { "solid": { "last_modified": 1684766194, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M32 32C32 14.3 46.3 0 64 0S96 14.3 96 32V240H32V32zM224 192c0-17.7 14.3-32 32-32s32 14.3 32 32v64c0 17.7-14.3 32-32 32s-32-14.3-32-32V192zm-64-64c17.7 0 32 14.3 32 32v48c0 17.7-14.3 32-32 32s-32-14.3-32-32V160c0-17.7 14.3-32 32-32zm160 96c0-17.7 14.3-32 32-32s32 14.3 32 32v64c0 17.7-14.3 32-32 32s-32-14.3-32-32V224zm-96 88l0-.6c9.4 5.4 20.3 8.6 32 8.6c13.2 0 25.4-4 35.6-10.8c8.7 24.9 32.5 42.8 60.4 42.8c11.7 0 22.6-3.1 32-8.6V352c0 88.4-71.6 160-160 160H162.3c-42.4 0-83.1-16.9-113.1-46.9L37.5 453.5C13.5 429.5 0 396.9 0 363V336c0-35.3 28.7-64 64-64h88c22.1 0 40 17.9 40 40s-17.9 40-40 40H96c-8.8 0-16 7.2-16 16s7.2 16 16 16h56c39.8 0 72-32.2 72-72z" }, "regular": { "last_modified": 1684766194, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M64 64V241.6c5.2-1 10.5-1.6 16-1.6H96V208 64c0-8.8-7.2-16-16-16s-16 7.2-16 16zM80 288c-17.7 0-32 14.3-32 32c0 0 0 0 0 0v24c0 66.3 53.7 120 120 120h48c52.5 0 97.1-33.7 113.4-80.7c-3.1 .5-6.2 .7-9.4 .7c-20 0-37.9-9.2-49.7-23.6c-9 4.9-19.4 7.6-30.3 7.6c-15.1 0-29-5.3-40-14c-11 8.8-24.9 14-40 14H120c-13.3 0-24-10.7-24-24s10.7-24 24-24h40c8.8 0 16-7.2 16-16s-7.2-16-16-16H120 80zM0 320s0 0 0 0c0-18 6-34.6 16-48V64C16 28.7 44.7 0 80 0s64 28.7 64 64v82c5.1-1.3 10.5-2 16-2c25.3 0 47.2 14.7 57.6 36c7-2.6 14.5-4 22.4-4c20 0 37.9 9.2 49.7 23.6c9-4.9 19.4-7.6 30.3-7.6c35.3 0 64 28.7 64 64v64 24c0 92.8-75.2 168-168 168H168C75.2 512 0 436.8 0 344V320zm336-64c0-8.8-7.2-16-16-16s-16 7.2-16 16v48 16c0 8.8 7.2 16 16 16s16-7.2 16-16V256zM160 240c5.5 0 10.9 .7 16 2v-2V208c0-8.8-7.2-16-16-16s-16 7.2-16 16v32h16zm64 24v40c0 8.8 7.2 16 16 16s16-7.2 16-16V256 240c0-8.8-7.2-16-16-16s-16 7.2-16 16v24z" } }, "free": ["regular", "solid"] }, "hand-pointer": { "aliases": { "unicodes": { "secondary": ["10f25a"] } }, "changes": ["4.4.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["arrow", "cursor", "select"] }, "styles": ["solid", "regular"], "unicode": "f25a", "label": "Hand Pointer", "voted": false, "svg": { "solid": { "last_modified": 1684766194, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M128 40c0-22.1 17.9-40 40-40s40 17.9 40 40V188.2c8.5-7.6 19.7-12.2 32-12.2c20.6 0 38.2 13 45 31.2c8.8-9.3 21.2-15.2 35-15.2c25.3 0 46 19.5 47.9 44.3c8.5-7.7 19.8-12.3 32.1-12.3c26.5 0 48 21.5 48 48v48 16 48c0 70.7-57.3 128-128 128l-16 0H240l-.1 0h-5.2c-5 0-9.9-.3-14.7-1c-55.3-5.6-106.2-34-140-79L8 336c-13.3-17.7-9.7-42.7 8-56s42.7-9.7 56 8l56 74.7V40zM240 304c0-8.8-7.2-16-16-16s-16 7.2-16 16v96c0 8.8 7.2 16 16 16s16-7.2 16-16V304zm48-16c-8.8 0-16 7.2-16 16v96c0 8.8 7.2 16 16 16s16-7.2 16-16V304c0-8.8-7.2-16-16-16zm80 16c0-8.8-7.2-16-16-16s-16 7.2-16 16v96c0 8.8 7.2 16 16 16s16-7.2 16-16V304z" }, "regular": { "last_modified": 1684766194, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M160 64c0-8.8 7.2-16 16-16s16 7.2 16 16V200c0 10.3 6.6 19.5 16.4 22.8s20.6-.1 26.8-8.3c3-3.9 7.6-6.4 12.8-6.4c8.8 0 16 7.2 16 16c0 10.3 6.6 19.5 16.4 22.8s20.6-.1 26.8-8.3c3-3.9 7.6-6.4 12.8-6.4c7.8 0 14.3 5.6 15.7 13c1.6 8.2 7.3 15.1 15.1 18s16.7 1.6 23.3-3.6c2.7-2.1 6.1-3.4 9.9-3.4c8.8 0 16 7.2 16 16l0 16V392c0 39.8-32.2 72-72 72H272 212.3h-.9c-37.4 0-72.4-18.7-93.2-49.9L50.7 312.9c-4.9-7.4-2.9-17.3 4.4-22.2s17.3-2.9 22.2 4.4L116 353.2c5.9 8.8 16.8 12.7 26.9 9.7s17-12.4 17-23V320 64zM176 0c-35.3 0-64 28.7-64 64V261.7C91.2 238 55.5 232.8 28.5 250.7C-.9 270.4-8.9 310.1 10.8 339.5L78.3 440.8c29.7 44.5 79.6 71.2 133.1 71.2h.9H272h56c66.3 0 120-53.7 120-120V288l0-16c0-35.3-28.7-64-64-64c-4.5 0-8.8 .5-13 1.3c-11.7-15.4-30.2-25.3-51-25.3c-6.9 0-13.5 1.1-19.7 3.1C288.7 170.7 269.6 160 248 160c-2.7 0-5.4 .2-8 .5V64c0-35.3-28.7-64-64-64zm48 304c0-8.8-7.2-16-16-16s-16 7.2-16 16v96c0 8.8 7.2 16 16 16s16-7.2 16-16V304zm48-16c-8.8 0-16 7.2-16 16v96c0 8.8 7.2 16 16 16s16-7.2 16-16V304c0-8.8-7.2-16-16-16zm80 16c0-8.8-7.2-16-16-16s-16 7.2-16 16v96c0 8.8 7.2 16 16 16s16-7.2 16-16V304z" } }, "free": ["regular", "solid"] }, "hand-scissors": { "aliases": { "unicodes": { "secondary": ["10f257"] } }, "changes": ["4.4.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["cut", "game", "roshambo"] }, "styles": ["solid", "regular"], "unicode": "f257", "label": "Hand Scissors", "voted": false, "svg": { "solid": { "last_modified": 1684766194, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M40 208c-22.1 0-40 17.9-40 40s17.9 40 40 40l180.2 0c-7.6 8.5-12.2 19.7-12.2 32c0 25.3 19.5 46 44.3 47.9c-7.7 8.5-12.3 19.8-12.3 32.1c0 26.5 21.5 48 48 48l32 0 64 0c70.7 0 128-57.3 128-128l0-113.1c0-40.2-16-78.8-44.4-107.3C444.8 76.8 413.9 64 381.7 64L336 64c-21.3 0-39.3 13.9-45.6 33.1l74.5 23.7c8.4 2.7 13.1 11.7 10.4 20.1s-11.7 13.1-20.1 10.4L288 129.9l0 .1L84 65.8C62.9 59.2 40.5 70.9 33.8 92s5.1 43.5 26.2 50.2L269.5 208 40 208z" }, "regular": { "last_modified": 1684766194, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M.2 276.3c-1.2-35.3 26.4-65 61.7-66.2l3.3-.1L57 208.1C22.5 200.5 .7 166.3 8.3 131.8S50.2 75.5 84.7 83.2l173 38.3c2.3-2.9 4.7-5.7 7.1-8.5l18.4-20.3C299.9 74.5 323.5 64 348.3 64l10.2 0c54.1 0 104.1 28.7 131.3 75.4l1.5 2.6c13.6 23.2 20.7 49.7 20.7 76.6L512 344c0 66.3-53.7 120-120 120l-8 0-96 0c-35.3 0-64-28.7-64-64c0-2.8 .2-5.6 .5-8.3c-19.4-11-32.5-31.8-32.5-55.7c0-.8 0-1.6 0-2.4L66.4 338c-35.3 1.2-65-26.4-66.2-61.7zm63.4-18.2c-8.8 .3-15.7 7.7-15.4 16.5s7.7 15.7 16.5 15.4l161.5-5.6c9.8-.3 18.7 5.3 22.7 14.2s2.2 19.3-4.5 26.4c-2.8 2.9-4.4 6.7-4.4 11c0 8.8 7.2 16 16 16c9.1 0 17.4 5.1 21.5 13.3s3.2 17.9-2.3 25.1c-2 2.7-3.2 6-3.2 9.6c0 8.8 7.2 16 16 16l96 0 8 0c39.8 0 72-32.2 72-72l0-125.4c0-18.4-4.9-36.5-14.2-52.4l-1.5-2.6c-18.6-32-52.8-51.6-89.8-51.6l-10.2 0c-11.3 0-22 4.8-29.6 13.1l-17.5-15.9 17.5 15.9-18.4 20.3c-.6 .6-1.1 1.3-1.7 1.9l57 13.2c8.6 2 14 10.6 12 19.2s-10.6 14-19.2 12l-85.6-19.7L74.3 130c-8.6-1.9-17.2 3.5-19.1 12.2s3.5 17.2 12.2 19.1l187.5 41.6c10.2 2.3 17.8 10.9 18.7 21.4l.1 1c.6 6.6-1.5 13.1-5.8 18.1s-10.6 7.9-17.2 8.2L63.6 258.1z" } }, "free": ["regular", "solid"] }, "hand-sparkles": { "aliases": { "unicodes": { "secondary": ["10e05d"] } }, "changes": [ "5.13.0", "5.14.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0", "6.4.1" ], "ligatures": [], "search": { "terms": ["clean", "covid-19", "hygiene", "magic", "palm", "soap", "wash"] }, "styles": ["solid"], "unicode": "e05d", "label": "Hand Sparkles", "voted": false, "svg": { "solid": { "last_modified": 1684766193, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M320 0c17.7 0 32 14.3 32 32V240c0 8.8 7.2 16 16 16s16-7.2 16-16V64c0-17.7 14.3-32 32-32s32 14.3 32 32V240c0 8.8 7.2 16 16 16s16-7.2 16-16V128c0-17.7 14.3-32 32-32s32 14.3 32 32V323.1c-11.9 4.8-21.3 14.9-25 27.8l-8.9 31.2L478.9 391C460.6 396.3 448 413 448 432c0 18.9 12.5 35.6 30.6 40.9C448.4 497.4 409.9 512 368 512H348.8c-59.6 0-116.9-22.9-160-64L76.4 341c-16-15.2-16.6-40.6-1.4-56.6s40.6-16.6 56.6-1.4l60.5 57.6c0-1.5-.1-3.1-.1-4.6V64c0-17.7 14.3-32 32-32s32 14.3 32 32V240c0 8.8 7.2 16 16 16s16-7.2 16-16V32c0-17.7 14.3-32 32-32zm-7.3 326.6c-1.1-3.9-4.7-6.6-8.7-6.6s-7.6 2.7-8.7 6.6L288 352l-25.4 7.3c-3.9 1.1-6.6 4.7-6.6 8.7s2.7 7.6 6.6 8.7L288 384l7.3 25.4c1.1 3.9 4.7 6.6 8.7 6.6s7.6-2.7 8.7-6.6L320 384l25.4-7.3c3.9-1.1 6.6-4.7 6.6-8.7s-2.7-7.6-6.6-8.7L320 352l-7.3-25.4zM104 120l48.3 13.8c4.6 1.3 7.7 5.5 7.7 10.2s-3.1 8.9-7.7 10.2L104 168 90.2 216.3c-1.3 4.6-5.5 7.7-10.2 7.7s-8.9-3.1-10.2-7.7L56 168 7.7 154.2C3.1 152.9 0 148.7 0 144s3.1-8.9 7.7-10.2L56 120 69.8 71.7C71.1 67.1 75.3 64 80 64s8.9 3.1 10.2 7.7L104 120zM584 408l48.3 13.8c4.6 1.3 7.7 5.5 7.7 10.2s-3.1 8.9-7.7 10.2L584 456l-13.8 48.3c-1.3 4.6-5.5 7.7-10.2 7.7s-8.9-3.1-10.2-7.7L536 456l-48.3-13.8c-4.6-1.3-7.7-5.5-7.7-10.2s3.1-8.9 7.7-10.2L536 408l13.8-48.3c1.3-4.6 5.5-7.7 10.2-7.7s8.9 3.1 10.2 7.7L584 408z" } }, "free": ["solid"] }, "hand-spock": { "aliases": { "unicodes": { "composite": ["1f596"], "secondary": ["10f259"] } }, "changes": [ "4.4.0", "5.0.0", "5.12.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0", "6.4.1" ], "ligatures": [], "search": { "terms": [ "finger", "hand", "live long", "palm", "prosper", "salute", "spock", "star trek", "vulcan", "vulcan salute" ] }, "styles": ["solid", "regular"], "unicode": "f259", "label": "Hand Spock", "voted": false, "svg": { "solid": { "last_modified": 1684766194, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M246.9 23.7C242.3 6.6 224.8-3.5 207.7 1.1s-27.2 22.1-22.6 39.2L238 237.8c2.5 9.2-4.5 18.2-14 18.2c-6.4 0-12-4.2-13.9-10.3L166.6 102.7c-5.1-16.9-23-26.4-39.9-21.3s-26.4 23-21.3 39.9l62.8 206.4c2.4 7.9-7.2 13.8-13.2 8.1L99.6 283c-16-15.2-41.3-14.6-56.6 1.4s-14.6 41.3 1.4 56.6L156.8 448c43.1 41.1 100.4 64 160 64h10.9 8.2c.1 0 .1-.1 .1-.1v0c0-.1 .1-.1 .1-.1c58.3-3.5 108.6-43.2 125.3-99.7l81.2-275c5-16.9-4.7-34.7-21.6-39.8s-34.7 4.7-39.8 21.6L443.5 247.1c-1.6 5.3-6.4 8.9-12 8.9c-7.9 0-13.8-7.3-12.2-15.1l36-170.3c3.7-17.3-7.4-34.3-24.7-37.9s-34.3 7.4-37.9 24.7L355.1 235.1c-2.6 12.2-13.3 20.9-25.8 20.9c-11.9 0-22.4-8-25.4-19.5l-57-212.8z" }, "regular": { "last_modified": 1684766194, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M170.2 80.8C161 47 180.8 12 214.6 2.4c34-9.6 69.4 10.2 79 44.2l30.3 107.1L337.1 84c6.6-34.7 40.1-57.5 74.8-50.9c31.4 6 53 33.9 52 64.9c10-2.6 20.8-2.8 31.5-.1c34.3 8.6 55.1 43.3 46.6 77.6L486.7 397.2C469.8 464.7 409.2 512 339.6 512c-11.2 0-22.5 0-33.7 0c-56.9 0-112.2-19-157.2-53.9l-92-71.6c-27.9-21.7-32.9-61.9-11.2-89.8s61.9-32.9 89.8-11.2l17 13.2L100.5 167.5c-13-32.9 3.2-70.1 36-83c11.1-4.4 22.7-5.4 33.7-3.7zm77.1-21.2c-2.4-8.5-11.2-13.4-19.7-11s-13.4 11.2-11 19.7l54.8 182.4c3.5 12.3-3.3 25.2-15.4 29.3s-25.3-2-30-13.9L174.9 138.1c-3.2-8.2-12.5-12.3-20.8-9s-12.3 12.5-9 20.8l73.3 185.6c12 30.3-23.7 57-49.4 37l-63.1-49.1c-7-5.4-17-4.2-22.5 2.8s-4.2 17 2.8 22.5l92 71.6c36.5 28.4 81.4 43.8 127.7 43.8c11.2 0 22.5 0 33.7 0c47.5 0 89-32.4 100.5-78.5l55.4-221.6c2.1-8.6-3.1-17.3-11.6-19.4s-17.3 3.1-19.4 11.6l-26 104C435.6 271.8 425 280 413 280c-16.5 0-28.9-15-25.8-31.2L415.7 99c1.7-8.7-4-17.1-12.7-18.7s-17.1 4-18.7 12.7L352.5 260c-2.2 11.6-12.4 20-24.2 20c-11 0-20.7-7.3-23.7-17.9L247.4 59.6z" } }, "free": ["regular", "solid"] }, "handcuffs": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "arrest", "criminal", "handcuffs", "jail", "lock", "police", "wrist" ] }, "styles": ["solid"], "unicode": "e4f8", "label": "Handcuffs", "voted": false, "svg": { "solid": { "last_modified": 1684766193, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M240 32a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zM192 48a32 32 0 1 1 0 64 32 32 0 1 1 0-64zm-32 80c17.7 0 32 14.3 32 32h8c13.3 0 24 10.7 24 24v16c0 1.7-.2 3.4-.5 5.1C280.3 229.6 320 286.2 320 352c0 88.4-71.6 160-160 160S0 440.4 0 352c0-65.8 39.7-122.4 96.5-146.9c-.4-1.6-.5-3.3-.5-5.1V184c0-13.3 10.7-24 24-24h8c0-17.7 14.3-32 32-32zm0 320a96 96 0 1 0 0-192 96 96 0 1 0 0 192zm192-96c0-25.9-5.1-50.5-14.4-73.1c16.9-32.9 44.8-59.1 78.9-73.9c-.4-1.6-.5-3.3-.5-5.1V184c0-13.3 10.7-24 24-24h8c0-17.7 14.3-32 32-32s32 14.3 32 32h8c13.3 0 24 10.7 24 24v16c0 1.7-.2 3.4-.5 5.1C600.3 229.6 640 286.2 640 352c0 88.4-71.6 160-160 160c-62 0-115.8-35.3-142.4-86.9c9.3-22.5 14.4-47.2 14.4-73.1zm224 0a96 96 0 1 0 -192 0 96 96 0 1 0 192 0zM368 0a32 32 0 1 1 0 64 32 32 0 1 1 0-64zm80 48a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" } }, "free": ["solid"] }, "hands": { "aliases": { "names": ["sign-language", "signing"], "unicodes": { "secondary": ["10f2a7"] } }, "changes": [ "4.6.0", "5.0.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["Translate", "asl", "deaf", "hands"] }, "styles": ["solid"], "unicode": "f2a7", "label": "Hands", "voted": false, "svg": { "solid": { "last_modified": 1684766193, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M544 160l-.1 72.6c-.1 52.2-24 101-64 133.1c.1-1.9 .1-3.8 .1-5.7v-8c0-71.8-37-138.6-97.9-176.7l-60.2-37.6c-8.6-5.4-17.9-8.4-27.3-9.4L248.7 48.8c-6.6-11.5-2.7-26.2 8.8-32.8s26.2-2.7 32.8 8.8l78 135.1c3.3 5.7 10.7 7.7 16.4 4.4s7.7-10.7 4.4-16.4l-62-107.4c-6.6-11.5-2.7-26.2 8.8-32.8S362 5 368.6 16.5l68 117.8 0 0 0 0 43.3 75L480 160c0-17.7 14.4-32 32-32s32 14.4 32 32zM243.9 88.5L268.5 131c-13.9 4.5-26.4 13.7-34.7 27c-.9 1.4-1.7 2.9-2.5 4.4l-28.9-50c-6.6-11.5-2.7-26.2 8.8-32.8s26.2-2.7 32.8 8.8zm-46.4 63.7l26.8 46.4c.6 6 2.1 11.8 4.3 17.4H224 210.7l0 0H179l-23-39.8c-6.6-11.5-2.7-26.2 8.8-32.8s26.2-2.7 32.8 8.8zM260.9 175c9.4-15 29.1-19.5 44.1-10.2l60.2 37.6C416.7 234.7 448 291.2 448 352v8c0 83.9-68.1 152-152 152H120c-13.3 0-24-10.7-24-24s10.7-24 24-24h92c6.6 0 12-5.4 12-12s-5.4-12-12-12H88c-13.3 0-24-10.7-24-24s10.7-24 24-24H212c6.6 0 12-5.4 12-12s-5.4-12-12-12H56c-13.3 0-24-10.7-24-24s10.7-24 24-24H212c6.6 0 12-5.4 12-12s-5.4-12-12-12H88c-13.3 0-24-10.7-24-24s10.7-24 24-24H224l0 0 0 0h93.2L271 219.1c-15-9.4-19.5-29.1-10.2-44.1z" } }, "free": ["solid"] }, "hands-asl-interpreting": { "aliases": { "names": [ "american-sign-language-interpreting", "asl-interpreting", "hands-american-sign-language-interpreting" ], "unicodes": { "secondary": ["10f2a3"] } }, "changes": ["4.6.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["asl", "deaf", "finger", "hand", "interpret", "speak"] }, "styles": ["solid"], "unicode": "f2a3", "label": "Hands Asl Interpreting", "voted": false, "svg": { "solid": { "last_modified": 1684766193, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M156.6 46.3c7.9-15.8 1.5-35-14.3-42.9s-35-1.5-42.9 14.3L13.5 189.4C4.6 207.2 0 226.8 0 246.7V256c0 70.7 57.3 128 128 128h72 8v-.3c35.2-2.7 65.4-22.8 82.1-51.7c8.8-15.3 3.6-34.9-11.7-43.7s-34.9-3.6-43.7 11.7c-7 12-19.9 20-34.7 20c-22.1 0-40-17.9-40-40s17.9-40 40-40c14.8 0 27.7 8 34.7 20c8.8 15.3 28.4 20.5 43.7 11.7s20.5-28.4 11.7-43.7c-12.8-22.1-33.6-39.1-58.4-47.1l80.8-22c17-4.6 27.1-22.2 22.5-39.3s-22.2-27.1-39.3-22.5L194.9 124.6l81.6-68c13.6-11.3 15.4-31.5 4.1-45.1S249.1-3.9 235.5 7.4L133.6 92.3l23-46zM483.4 465.7c-7.9 15.8-1.5 35 14.3 42.9s35 1.5 42.9-14.3l85.9-171.7c8.9-17.8 13.5-37.4 13.5-57.2V256c0-70.7-57.3-128-128-128H440h-8v.3c-35.2 2.7-65.4 22.8-82.1 51.7c-8.9 15.3-3.6 34.9 11.7 43.7s34.9 3.6 43.7-11.7c7-12 19.9-20 34.7-20c22.1 0 40 17.9 40 40s-17.9 40-40 40c-14.8 0-27.7-8-34.7-20c-8.9-15.3-28.4-20.5-43.7-11.7s-20.5 28.4-11.7 43.7c12.8 22.1 33.6 39.1 58.4 47.1l-80.8 22c-17.1 4.7-27.1 22.2-22.5 39.3s22.2 27.1 39.3 22.5l100.7-27.5-81.6 68c-13.6 11.3-15.4 31.5-4.1 45.1s31.5 15.4 45.1 4.1l101.9-84.9-23 46z" } }, "free": ["solid"] }, "hands-bound": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["abduction", "bound", "handcuff", "wrist"] }, "styles": ["solid"], "unicode": "e4f9", "label": "Hands Bound", "voted": false, "svg": { "solid": { "last_modified": 1684766194, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M96 32C96 14.3 81.7 0 64 0S32 14.3 32 32V96v59.1 .7V192v21.9c0 14.2 5.1 27.9 14.3 38.7L131.6 352H128c-13.3 0-24 10.7-24 24s10.7 24 24 24h32H288h64H480h32c13.3 0 24-10.7 24-24s-10.7-24-24-24h-3.6l85.3-99.5c9.2-10.8 14.3-24.5 14.3-38.7V192 155.8v-.7V96 32c0-17.7-14.3-32-32-32s-32 14.3-32 32V96v48.8l-69.3 92.4c-5.7 7.6-16.1 9.6-24.2 4.8c-9.7-5.7-12.1-18.7-5.1-27.5L473 180c10.8-13.5 8.9-33.3-4.4-44.5s-33-9.8-44.5 3.2l-46.7 52.5C361 209.7 352 233.4 352 258.1V320v32H288V320 258.1c0-24.6-9-48.4-25.4-66.8l-46.7-52.5c-11.5-13-31.3-14.4-44.5-3.2s-15.2 30.9-4.4 44.5l27.6 34.5c7 8.8 4.7 21.8-5.1 27.5c-8.1 4.8-18.6 2.7-24.2-4.8L96 144.8V96 32zm64 448v32H288V480h64v32H480V480h32c13.3 0 24-10.7 24-24s-10.7-24-24-24H480 352 288 160 128c-13.3 0-24 10.7-24 24s10.7 24 24 24h32z" } }, "free": ["solid"] }, "hands-bubbles": { "aliases": { "names": ["hands-wash"], "unicodes": { "secondary": ["10e05e"] } }, "changes": [ "5.13.0", "5.14.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0", "6.4.1" ], "ligatures": [], "search": { "terms": ["covid-19", "hygiene", "soap", "wash"] }, "styles": ["solid"], "unicode": "e05e", "label": "Hands Bubbles", "voted": false, "svg": { "solid": { "last_modified": 1684766194, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M416 64a32 32 0 1 0 0-64 32 32 0 1 0 0 64zm96 128a32 32 0 1 0 0-64 32 32 0 1 0 0 64zM160 464a48 48 0 1 0 -96 0 48 48 0 1 0 96 0zM32 160l.1 72.6c.1 52.2 24 101 64 133.1c-.1-1.9-.1-3.8-.1-5.7v-8c0-71.8 37-138.6 97.9-176.7l60.2-37.6c8.6-5.4 17.9-8.4 27.3-9.4l45.9-79.5c6.6-11.5 2.7-26.2-8.8-32.8s-26.2-2.7-32.8 8.8l-78 135.1c-3.3 5.7-10.7 7.7-16.4 4.4s-7.7-10.7-4.4-16.4l62-107.4c6.6-11.5 2.7-26.2-8.8-32.8S214 5 207.4 16.5l-68 117.8 0 0 0 0-43.3 75L96 160c0-17.7-14.4-32-32-32s-32 14.4-32 32zM332.1 88.5L307.5 131c13.9 4.5 26.4 13.7 34.7 27c.9 1.5 1.7 2.9 2.5 4.4l28.9-50c6.6-11.5 2.7-26.2-8.8-32.8s-26.2-2.7-32.8 8.8zm46.4 63.7l-26.8 46.4c-.6 6-2.1 11.8-4.3 17.4H352h13.3l0 0H397l23-39.8c6.6-11.5 2.7-26.2-8.8-32.8s-26.2-2.7-32.8 8.8zM315.1 175c-9.4-15-29.1-19.5-44.1-10.2l-60.2 37.6C159.3 234.7 128 291.2 128 352v8c0 8.9 .8 17.6 2.2 26.1c35.4 8.2 61.8 40 61.8 77.9c0 6.3-.7 12.5-2.1 18.4C215.1 501 246.3 512 280 512H456c13.3 0 24-10.7 24-24s-10.7-24-24-24H364c-6.6 0-12-5.4-12-12s5.4-12 12-12H488c13.3 0 24-10.7 24-24s-10.7-24-24-24H364c-6.6 0-12-5.4-12-12s5.4-12 12-12H520c13.3 0 24-10.7 24-24s-10.7-24-24-24H364c-6.6 0-12-5.4-12-12s5.4-12 12-12H488c13.3 0 24-10.7 24-24s-10.7-24-24-24H352l0 0 0 0H258.8L305 219.1c15-9.4 19.5-29.1 10.2-44.1z" } }, "free": ["solid"] }, "hands-clapping": { "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["applause", "clap", "clapping hands", "hand"] }, "styles": ["solid"], "unicode": "e1a8", "label": "Hands Clapping", "voted": false, "svg": { "solid": { "last_modified": 1684766193, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M336 16V80c0 8.8-7.2 16-16 16s-16-7.2-16-16V16c0-8.8 7.2-16 16-16s16 7.2 16 16zm-98.7 7.1l32 48c4.9 7.4 2.9 17.3-4.4 22.2s-17.3 2.9-22.2-4.4l-32-48c-4.9-7.4-2.9-17.3 4.4-22.2s17.3-2.9 22.2 4.4zM135 119c9.4-9.4 24.6-9.4 33.9 0L292.7 242.7c10.1 10.1 27.3 2.9 27.3-11.3V192c0-17.7 14.3-32 32-32s32 14.3 32 32V345.6c0 57.1-30 110-78.9 139.4c-64 38.4-145.8 28.3-198.5-24.4L7 361c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l53 53c6.1 6.1 16 6.1 22.1 0s6.1-16 0-22.1L23 265c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l93 93c6.1 6.1 16 6.1 22.1 0s6.1-16 0-22.1L55 185c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l117 117c6.1 6.1 16 6.1 22.1 0s6.1-16 0-22.1l-93-93c-9.4-9.4-9.4-24.6 0-33.9zM433.1 484.9c-24.2 14.5-50.9 22.1-77.7 23.1c48.1-39.6 76.6-99 76.6-162.4l0-98.1c8.2-.1 16-6.4 16-16V192c0-17.7 14.3-32 32-32s32 14.3 32 32V345.6c0 57.1-30 110-78.9 139.4zM424.9 18.7c7.4 4.9 9.3 14.8 4.4 22.2l-32 48c-4.9 7.4-14.8 9.3-22.2 4.4s-9.3-14.8-4.4-22.2l32-48c4.9-7.4 14.8-9.3 22.2-4.4z" } }, "free": ["solid"] }, "hands-holding": { "aliases": { "unicodes": { "secondary": ["10f4c2"] } }, "changes": ["5.0.9", "6.0.0-beta1", "6.1.2", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["carry", "hold", "lift"] }, "styles": ["solid"], "unicode": "f4c2", "label": "Hands Holding", "voted": false, "svg": { "solid": { "last_modified": 1684766194, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M80 104c0-22.1-17.9-40-40-40S0 81.9 0 104v56 64V325.5c0 25.5 10.1 49.9 28.1 67.9L128 493.3c12 12 28.3 18.7 45.3 18.7H240c26.5 0 48-21.5 48-48V385.1c0-29.7-11.8-58.2-32.8-79.2l-25.3-25.3 0 0-15.2-15.2-32-32c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l32 32 15.2 15.2c11 11 9.2 29.2-3.7 37.8c-9.7 6.5-22.7 5.2-31-3.1L98.7 309.5c-12-12-18.7-28.3-18.7-45.3V224 144 104zm480 0v40 80 40.2c0 17-6.7 33.3-18.7 45.3l-51.1 51.1c-8.3 8.3-21.3 9.6-31 3.1c-12.9-8.6-14.7-26.9-3.7-37.8l15.2-15.2 32-32c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-32 32-15.2 15.2 0 0-25.3 25.3c-21 21-32.8 49.5-32.8 79.2V464c0 26.5 21.5 48 48 48h66.7c17 0 33.3-6.7 45.3-18.7l99.9-99.9c18-18 28.1-42.4 28.1-67.9V224 160 104c0-22.1-17.9-40-40-40s-40 17.9-40 40z" } }, "free": ["solid"] }, "hands-holding-child": { "changes": ["6.1.0", "6.1.2", "6.2.0", "6.3.0", "6.4.0", "6.4.1"], "ligatures": [], "search": { "terms": ["care", "give", "help", "hold", "protect"] }, "styles": ["solid"], "unicode": "e4fa", "label": "Hands Holding Child", "voted": false, "svg": { "solid": { "last_modified": 1684766194, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M320 0a40 40 0 1 1 0 80 40 40 0 1 1 0-80zm44.7 164.3L375.8 253c1.6 13.2-7.7 25.1-20.8 26.8s-25.1-7.7-26.8-20.8l-4.4-35h-7.6l-4.4 35c-1.6 13.2-13.6 22.5-26.8 20.8s-22.5-13.6-20.8-26.8l11.1-88.8L255.5 181c-10.1 8.6-25.3 7.3-33.8-2.8s-7.3-25.3 2.8-33.8l27.9-23.6C271.3 104.8 295.3 96 320 96s48.7 8.8 67.6 24.7l27.9 23.6c10.1 8.6 11.4 23.7 2.8 33.8s-23.7 11.4-33.8 2.8l-19.8-16.7zM40 64c22.1 0 40 17.9 40 40v40 80 40.2c0 17 6.7 33.3 18.7 45.3l51.1 51.1c8.3 8.3 21.3 9.6 31 3.1c12.9-8.6 14.7-26.9 3.7-37.8l-15.2-15.2-32-32c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l32 32 15.2 15.2 0 0 25.3 25.3c21 21 32.8 49.5 32.8 79.2V464c0 26.5-21.5 48-48 48H173.3c-17 0-33.3-6.7-45.3-18.7L28.1 393.4C10.1 375.4 0 351 0 325.5V224 160 104C0 81.9 17.9 64 40 64zm560 0c22.1 0 40 17.9 40 40v56 64V325.5c0 25.5-10.1 49.9-28.1 67.9L512 493.3c-12 12-28.3 18.7-45.3 18.7H400c-26.5 0-48-21.5-48-48V385.1c0-29.7 11.8-58.2 32.8-79.2l25.3-25.3 0 0 15.2-15.2 32-32c12.5-12.5 32.8-12.5 45.3 0s12.5 32.8 0 45.3l-32 32-15.2 15.2c-11 11-9.2 29.2 3.7 37.8c9.7 6.5 22.7 5.2 31-3.1l51.1-51.1c12-12 18.7-28.3 18.7-45.3V224 144 104c0-22.1 17.9-40 40-40z" } }, "free": ["solid"] }, "hands-holding-circle": { "changes": ["6.1.0", "6.1.2", "6.2.0", "6.3.0", "6.4.0", "6.4.1"], "ligatures": [], "search": { "terms": ["circle", "gift", "protection"] }, "styles": ["solid"], "unicode": "e4fb", "label": "Hands Holding Circle", "voted": false, "svg": { "solid": { "last_modified": 1684766193, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M320 0a128 128 0 1 1 0 256A128 128 0 1 1 320 0zM40 64c22.1 0 40 17.9 40 40v40 80 40.2c0 17 6.7 33.3 18.7 45.3l51.1 51.1c8.3 8.3 21.3 9.6 31 3.1c12.9-8.6 14.7-26.9 3.7-37.8l-15.2-15.2-32-32c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l32 32 15.2 15.2 0 0 25.3 25.3c21 21 32.8 49.5 32.8 79.2V464c0 26.5-21.5 48-48 48H173.3c-17 0-33.3-6.7-45.3-18.7L28.1 393.4C10.1 375.4 0 351 0 325.5V224 160 104C0 81.9 17.9 64 40 64zm560 0c22.1 0 40 17.9 40 40v56 64V325.5c0 25.5-10.1 49.9-28.1 67.9L512 493.3c-12 12-28.3 18.7-45.3 18.7H400c-26.5 0-48-21.5-48-48V385.1c0-29.7 11.8-58.2 32.8-79.2l25.3-25.3 0 0 15.2-15.2 32-32c12.5-12.5 32.8-12.5 45.3 0s12.5 32.8 0 45.3l-32 32-15.2 15.2c-11 11-9.2 29.2 3.7 37.8c9.7 6.5 22.7 5.2 31-3.1l51.1-51.1c12-12 18.7-28.3 18.7-45.3V224 144 104c0-22.1 17.9-40 40-40z" } }, "free": ["solid"] }, "hands-praying": { "aliases": { "names": ["praying-hands"], "unicodes": { "secondary": ["10f684"] } }, "changes": ["5.3.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["kneel", "preach", "religion", "worship"] }, "styles": ["solid"], "unicode": "f684", "label": "Hands Praying", "voted": false, "svg": { "solid": { "last_modified": 1684766194, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M351.2 4.8c3.2-2 6.6-3.3 10-4.1c4.7-1 9.6-.9 14.1 .1c7.7 1.8 14.8 6.5 19.4 13.6L514.6 194.2c8.8 13.1 13.4 28.6 13.4 44.4v73.5c0 6.9 4.4 13 10.9 15.2l79.2 26.4C631.2 358 640 370.2 640 384v96c0 9.9-4.6 19.3-12.5 25.4s-18.1 8.1-27.7 5.5L431 465.9c-56-14.9-95-65.7-95-123.7V224c0-17.7 14.3-32 32-32s32 14.3 32 32v80c0 8.8 7.2 16 16 16s16-7.2 16-16V219.1c0-7-1.8-13.8-5.3-19.8L340.3 48.1c-1.7-3-2.9-6.1-3.6-9.3c-1-4.7-1-9.6 .1-14.1c1.9-8 6.8-15.2 14.3-19.9zm-62.4 0c7.5 4.6 12.4 11.9 14.3 19.9c1.1 4.6 1.2 9.4 .1 14.1c-.7 3.2-1.9 6.3-3.6 9.3L213.3 199.3c-3.5 6-5.3 12.9-5.3 19.8V304c0 8.8 7.2 16 16 16s16-7.2 16-16V224c0-17.7 14.3-32 32-32s32 14.3 32 32V342.3c0 58-39 108.7-95 123.7l-168.7 45c-9.6 2.6-19.9 .5-27.7-5.5S0 490 0 480V384c0-13.8 8.8-26 21.9-30.4l79.2-26.4c6.5-2.2 10.9-8.3 10.9-15.2V238.5c0-15.8 4.7-31.2 13.4-44.4L245.2 14.5c4.6-7.1 11.7-11.8 19.4-13.6c4.6-1.1 9.4-1.2 14.1-.1c3.5 .8 6.9 2.1 10 4.1z" } }, "free": ["solid"] }, "handshake": { "aliases": { "unicodes": { "secondary": ["10f2b5"] } }, "changes": [ "4.7.0", "5.0.0", "5.0.9", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0", "6.4.1" ], "ligatures": [], "search": { "terms": ["agreement", "greeting", "meeting", "partnership"] }, "styles": ["solid", "regular"], "unicode": "f2b5", "label": "Handshake", "voted": false, "svg": { "solid": { "last_modified": 1684766194, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M323.4 85.2l-96.8 78.4c-16.1 13-19.2 36.4-7 53.1c12.9 17.8 38 21.3 55.3 7.8l99.3-77.2c7-5.4 17-4.2 22.5 2.8s4.2 17-2.8 22.5l-20.9 16.2L512 316.8V128h-.7l-3.9-2.5L434.8 79c-15.3-9.8-33.2-15-51.4-15c-21.8 0-43 7.5-60 21.2zm22.8 124.4l-51.7 40.2C263 274.4 217.3 268 193.7 235.6c-22.2-30.5-16.6-73.1 12.7-96.8l83.2-67.3c-11.6-4.9-24.1-7.4-36.8-7.4C234 64 215.7 69.6 200 80l-72 48V352h28.2l91.4 83.4c19.6 17.9 49.9 16.5 67.8-3.1c5.5-6.1 9.2-13.2 11.1-20.6l17 15.6c19.5 17.9 49.9 16.6 67.8-2.9c4.5-4.9 7.8-10.6 9.9-16.5c19.4 13 45.8 10.3 62.1-7.5c17.9-19.5 16.6-49.9-2.9-67.8l-134.2-123zM16 128c-8.8 0-16 7.2-16 16V352c0 17.7 14.3 32 32 32H64c17.7 0 32-14.3 32-32V128H16zM48 320a16 16 0 1 1 0 32 16 16 0 1 1 0-32zM544 128V352c0 17.7 14.3 32 32 32h32c17.7 0 32-14.3 32-32V144c0-8.8-7.2-16-16-16H544zm32 208a16 16 0 1 1 32 0 16 16 0 1 1 -32 0z" }, "regular": { "last_modified": 1684766194, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M272.2 64.6l-51.1 51.1c-15.3 4.2-29.5 11.9-41.5 22.5L153 161.9C142.8 171 129.5 176 115.8 176H96V304c20.4 .6 39.8 8.9 54.3 23.4l35.6 35.6 7 7 0 0L219.9 397c6.2 6.2 16.4 6.2 22.6 0c1.7-1.7 3-3.7 3.7-5.8c2.8-7.7 9.3-13.5 17.3-15.3s16.4 .6 22.2 6.5L296.5 393c11.6 11.6 30.4 11.6 41.9 0c5.4-5.4 8.3-12.3 8.6-19.4c.4-8.8 5.6-16.6 13.6-20.4s17.3-3 24.4 2.1c9.4 6.7 22.5 5.8 30.9-2.6c9.4-9.4 9.4-24.6 0-33.9L340.1 243l-35.8 33c-27.3 25.2-69.2 25.6-97 .9c-31.7-28.2-32.4-77.4-1.6-106.5l70.1-66.2C303.2 78.4 339.4 64 377.1 64c36.1 0 71 13.3 97.9 37.2L505.1 128H544h40 40c8.8 0 16 7.2 16 16V352c0 17.7-14.3 32-32 32H576c-11.8 0-22.2-6.4-27.7-16H463.4c-3.4 6.7-7.9 13.1-13.5 18.7c-17.1 17.1-40.8 23.8-63 20.1c-3.6 7.3-8.5 14.1-14.6 20.2c-27.3 27.3-70 30-100.4 8.1c-25.1 20.8-62.5 19.5-86-4.1L159 404l-7-7-35.6-35.6c-5.5-5.5-12.7-8.7-20.4-9.3C96 369.7 81.6 384 64 384H32c-17.7 0-32-14.3-32-32V144c0-8.8 7.2-16 16-16H56 96h19.8c2 0 3.9-.7 5.3-2l26.5-23.6C175.5 77.7 211.4 64 248.7 64H259c4.4 0 8.9 .2 13.2 .6zM544 320V176H496c-5.9 0-11.6-2.2-15.9-6.1l-36.9-32.8c-18.2-16.2-41.7-25.1-66.1-25.1c-25.4 0-49.8 9.7-68.3 27.1l-70.1 66.2c-10.3 9.8-10.1 26.3 .5 35.7c9.3 8.3 23.4 8.1 32.5-.3l71.9-66.4c9.7-9 24.9-8.4 33.9 1.4s8.4 24.9-1.4 33.9l-.8 .8 74.4 74.4c10 10 16.5 22.3 19.4 35.1H544zM64 336a16 16 0 1 0 -32 0 16 16 0 1 0 32 0zm528 16a16 16 0 1 0 0-32 16 16 0 1 0 0 32z" } }, "free": ["regular", "solid"] }, "handshake-angle": { "aliases": { "names": ["hands-helping"], "unicodes": { "secondary": ["10f4c4"] } }, "changes": ["5.0.9", "6.0.0-beta1", "6.1.2", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["aid", "assistance", "handshake", "partnership", "volunteering"] }, "styles": ["solid"], "unicode": "f4c4", "label": "Handshake Angle", "voted": false, "svg": { "solid": { "last_modified": 1684766193, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M544 248v3.3l69.7-69.7c21.9-21.9 21.9-57.3 0-79.2L535.6 24.4c-21.9-21.9-57.3-21.9-79.2 0L416.3 64.5c-2.7-.3-5.5-.5-8.3-.5H296c-37.1 0-67.6 28-71.6 64H224V248c0 22.1 17.9 40 40 40s40-17.9 40-40V176c0 0 0-.1 0-.1V160l16 0 136 0c0 0 0 0 .1 0H464c44.2 0 80 35.8 80 80v8zM336 192v56c0 39.8-32.2 72-72 72s-72-32.2-72-72V129.4c-35.9 6.2-65.8 32.3-76 68.2L99.5 255.2 26.3 328.4c-21.9 21.9-21.9 57.3 0 79.2l78.1 78.1c21.9 21.9 57.3 21.9 79.2 0l37.7-37.7c.9 0 1.8 .1 2.7 .1H384c26.5 0 48-21.5 48-48c0-5.6-1-11-2.7-16H432c26.5 0 48-21.5 48-48c0-12.8-5-24.4-13.2-33c25.7-5 45.1-27.6 45.2-54.8v-.4c-.1-30.8-25.1-55.8-56-55.8c0 0 0 0 0 0l-120 0z" } }, "free": ["solid"] }, "handshake-simple": { "aliases": { "names": ["handshake-alt"], "unicodes": { "composite": ["1f91d"], "secondary": ["10f4c6"] } }, "changes": ["5.0.9", "6.0.0-beta1", "6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "agreement", "greeting", "hand", "handshake", "meeting", "partnership", "shake" ] }, "styles": ["solid"], "unicode": "f4c6", "label": "Handshake Simple", "voted": false, "svg": { "solid": { "last_modified": 1684766193, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M323.4 85.2l-96.8 78.4c-16.1 13-19.2 36.4-7 53.1c12.9 17.8 38 21.3 55.3 7.8l99.3-77.2c7-5.4 17-4.2 22.5 2.8s4.2 17-2.8 22.5l-20.9 16.2L550.2 352H592c26.5 0 48-21.5 48-48V176c0-26.5-21.5-48-48-48H516h-4-.7l-3.9-2.5L434.8 79c-15.3-9.8-33.2-15-51.4-15c-21.8 0-43 7.5-60 21.2zm22.8 124.4l-51.7 40.2C263 274.4 217.3 268 193.7 235.6c-22.2-30.5-16.6-73.1 12.7-96.8l83.2-67.3c-11.6-4.9-24.1-7.4-36.8-7.4C234 64 215.7 69.6 200 80l-72 48H48c-26.5 0-48 21.5-48 48V304c0 26.5 21.5 48 48 48H156.2l91.4 83.4c19.6 17.9 49.9 16.5 67.8-3.1c5.5-6.1 9.2-13.2 11.1-20.6l17 15.6c19.5 17.9 49.9 16.6 67.8-2.9c4.5-4.9 7.8-10.6 9.9-16.5c19.4 13 45.8 10.3 62.1-7.5c17.9-19.5 16.6-49.9-2.9-67.8l-134.2-123z" } }, "free": ["solid"] }, "handshake-simple-slash": { "aliases": { "names": ["handshake-alt-slash"], "unicodes": { "secondary": ["10e05f"] } }, "changes": [ "5.13.0", "5.14.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0", "6.4.1" ], "ligatures": [], "search": { "terms": ["broken", "covid-19", "social distance"] }, "styles": ["solid"], "unicode": "e05f", "label": "Handshake Simple Slash", "voted": false, "svg": { "solid": { "last_modified": 1684766194, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7l-135-105.8c-1.1-11.3-6.3-22.3-15.3-30.7l-134.2-123-23.4 18.2-26-20.3 77.2-60.1c7-5.4 17-4.2 22.5 2.8s4.2 17-2.8 22.5l-20.9 16.2L550.2 352H592c26.5 0 48-21.5 48-48V176c0-26.5-21.5-48-48-48H516h-4-.7l-3.9-2.5L434.8 79c-15.3-9.8-33.2-15-51.4-15c-21.8 0-43 7.5-60 21.2l-89.7 72.6-25.8-20.3 81.8-66.2c-11.6-4.9-24.1-7.4-36.8-7.4C234 64 215.7 69.6 200 80l-35.5 23.7L38.8 5.1zM413.6 421.9L41.2 128.5C17.9 131.8 0 151.8 0 176V304c0 26.5 21.5 48 48 48H156.2l91.4 83.4c19.6 17.9 49.9 16.5 67.8-3.1c5.5-6.1 9.2-13.2 11.1-20.6l17 15.6c19.5 17.9 49.9 16.6 67.8-2.9c.8-.8 1.5-1.7 2.2-2.6z" } }, "free": ["solid"] }, "handshake-slash": { "aliases": { "unicodes": { "secondary": ["10e060"] } }, "changes": [ "5.13.0", "5.14.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0", "6.4.1" ], "ligatures": [], "search": { "terms": ["broken", "covid-19", "social distance"] }, "styles": ["solid"], "unicode": "e060", "label": "Handshake Slash", "voted": false, "svg": { "solid": { "last_modified": 1684766194, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7l-135-105.8c-1.1-11.3-6.3-22.3-15.3-30.7l-134.2-123-23.4 18.2-26-20.3 77.2-60.1c7-5.4 17-4.2 22.5 2.8s4.2 17-2.8 22.5l-20.9 16.2L512 316.8V128h-.7l-3.9-2.5L434.8 79c-15.3-9.8-33.2-15-51.4-15c-21.8 0-43 7.5-60 21.2l-89.7 72.6-25.8-20.3 81.8-66.2c-11.6-4.9-24.1-7.4-36.8-7.4C234 64 215.7 69.6 200 80l-35.5 23.7L38.8 5.1zM413.6 421.9L128 196.8V352h28.2l91.4 83.4c19.6 17.9 49.9 16.5 67.8-3.1c5.5-6.1 9.2-13.2 11.1-20.6l17 15.6c19.5 17.9 49.9 16.6 67.8-2.9c.8-.8 1.5-1.7 2.2-2.6zM96 171.6L40.6 128H16c-8.8 0-16 7.2-16 16V352c0 17.7 14.3 32 32 32H64c17.7 0 32-14.3 32-32V171.6zM48 320a16 16 0 1 1 0 32 16 16 0 1 1 0-32zM544 128V352c0 17.7 14.3 32 32 32h32c17.7 0 32-14.3 32-32V144c0-8.8-7.2-16-16-16H544zm32 208a16 16 0 1 1 32 0 16 16 0 1 1 -32 0z" } }, "free": ["solid"] }, "hanukiah": { "aliases": { "unicodes": { "composite": ["1f54e"], "secondary": ["10f6e6"] } }, "changes": ["5.4.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "candelabrum", "candle", "candlestick", "hanukkah", "jewish", "judaism", "light", "menorah", "religion" ] }, "styles": ["solid"], "unicode": "f6e6", "label": "Hanukiah", "voted": false, "svg": { "solid": { "last_modified": 1684767443, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M314.2 3.3C309.1 12.1 296 36.6 296 56c0 13.3 10.7 24 24 24s24-10.7 24-24c0-19.4-13.1-43.9-18.2-52.7C324.6 1.2 322.4 0 320 0s-4.6 1.2-5.8 3.3zm-288 48C21.1 60.1 8 84.6 8 104c0 13.3 10.7 24 24 24s24-10.7 24-24c0-19.4-13.1-43.9-18.2-52.7C36.6 49.2 34.4 48 32 48s-4.6 1.2-5.8 3.3zM88 104c0 13.3 10.7 24 24 24s24-10.7 24-24c0-19.4-13.1-43.9-18.2-52.7c-1.2-2.1-3.4-3.3-5.8-3.3s-4.6 1.2-5.8 3.3C101.1 60.1 88 84.6 88 104zm82.2-52.7C165.1 60.1 152 84.6 152 104c0 13.3 10.7 24 24 24s24-10.7 24-24c0-19.4-13.1-43.9-18.2-52.7c-1.2-2.1-3.4-3.3-5.8-3.3s-4.6 1.2-5.8 3.3zM216 104c0 13.3 10.7 24 24 24s24-10.7 24-24c0-19.4-13.1-43.9-18.2-52.7c-1.2-2.1-3.4-3.3-5.8-3.3s-4.6 1.2-5.8 3.3C229.1 60.1 216 84.6 216 104zM394.2 51.3C389.1 60.1 376 84.6 376 104c0 13.3 10.7 24 24 24s24-10.7 24-24c0-19.4-13.1-43.9-18.2-52.7c-1.2-2.1-3.4-3.3-5.8-3.3s-4.6 1.2-5.8 3.3zM440 104c0 13.3 10.7 24 24 24s24-10.7 24-24c0-19.4-13.1-43.9-18.2-52.7c-1.2-2.1-3.4-3.3-5.8-3.3s-4.6 1.2-5.8 3.3C453.1 60.1 440 84.6 440 104zm82.2-52.7C517.1 60.1 504 84.6 504 104c0 13.3 10.7 24 24 24s24-10.7 24-24c0-19.4-13.1-43.9-18.2-52.7c-1.2-2.1-3.4-3.3-5.8-3.3s-4.6 1.2-5.8 3.3zM584 104c0 13.3 10.7 24 24 24s24-10.7 24-24c0-19.4-13.1-43.9-18.2-52.7c-1.2-2.1-3.4-3.3-5.8-3.3s-4.6 1.2-5.8 3.3C597.1 60.1 584 84.6 584 104zM112 160c-8.8 0-16 7.2-16 16v96 16h32V272 176c0-8.8-7.2-16-16-16zm64 0c-8.8 0-16 7.2-16 16v96 16h32V272 176c0-8.8-7.2-16-16-16zm64 0c-8.8 0-16 7.2-16 16v96 16h32V272 176c0-8.8-7.2-16-16-16zm160 0c-8.8 0-16 7.2-16 16v96 16h32V272 176c0-8.8-7.2-16-16-16zm64 0c-8.8 0-16 7.2-16 16v96 16h32V272 176c0-8.8-7.2-16-16-16zm64 0c-8.8 0-16 7.2-16 16v96 16h32V272 176c0-8.8-7.2-16-16-16zM352 144c0-17.7-14.3-32-32-32s-32 14.3-32 32V320H96c-17.7 0-32-14.3-32-32V192c0-17.7-14.3-32-32-32s-32 14.3-32 32v96c0 53 43 96 96 96H288v64H160c-17.7 0-32 14.3-32 32s14.3 32 32 32H320 480c17.7 0 32-14.3 32-32s-14.3-32-32-32H352V384H544c53 0 96-43 96-96V192c0-17.7-14.3-32-32-32s-32 14.3-32 32v96c0 17.7-14.3 32-32 32H352V144z" } }, "free": ["solid"] }, "hard-drive": { "aliases": { "names": ["hdd"], "unicodes": { "composite": ["1f5b4"], "secondary": ["10f0a0"] } }, "changes": [ "2.0.0", "5.0.0", "5.10.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Hard Disk", "cpu", "hard drive", "harddrive", "machine", "save", "storage" ] }, "styles": ["solid", "regular"], "unicode": "f0a0", "label": "Hard Drive", "voted": false, "svg": { "solid": { "last_modified": 1684767342, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 96C0 60.7 28.7 32 64 32H448c35.3 0 64 28.7 64 64V280.4c-17-15.2-39.4-24.4-64-24.4H64c-24.6 0-47 9.2-64 24.4V96zM64 288H448c35.3 0 64 28.7 64 64v64c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V352c0-35.3 28.7-64 64-64zM320 416a32 32 0 1 0 0-64 32 32 0 1 0 0 64zm128-32a32 32 0 1 0 -64 0 32 32 0 1 0 64 0z" }, "regular": { "last_modified": 1684767342, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M64 80c-8.8 0-16 7.2-16 16V258c5.1-1.3 10.5-2 16-2H448c5.5 0 10.9 .7 16 2V96c0-8.8-7.2-16-16-16H64zM48 320v96c0 8.8 7.2 16 16 16H448c8.8 0 16-7.2 16-16V320c0-8.8-7.2-16-16-16H64c-8.8 0-16 7.2-16 16zM0 320V96C0 60.7 28.7 32 64 32H448c35.3 0 64 28.7 64 64V320v96c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V320zm280 48a24 24 0 1 1 48 0 24 24 0 1 1 -48 0zm120-24a24 24 0 1 1 0 48 24 24 0 1 1 0-48z" } }, "free": ["regular", "solid"] }, "hashnode": { "changes": ["6.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e499", "label": "Hashnode", "voted": false, "svg": { "brands": { "last_modified": 1660014472, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M35.19 171.1C-11.72 217.1-11.72 294 35.19 340.9L171.1 476.8C217.1 523.7 294 523.7 340.9 476.8L476.8 340.9C523.7 294 523.7 217.1 476.8 171.1L340.9 35.19C294-11.72 217.1-11.72 171.1 35.19L35.19 171.1zM315.5 315.5C282.6 348.3 229.4 348.3 196.6 315.5C163.7 282.6 163.7 229.4 196.6 196.6C229.4 163.7 282.6 163.7 315.5 196.6C348.3 229.4 348.3 282.6 315.5 315.5z" } }, "free": ["brands"] }, "hashtag": { "aliases": { "unicodes": { "composite": ["f292"], "primary": ["f292"], "secondary": ["1023", "10f292"] } }, "changes": ["4.5.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "Number Sign", "Twitter", "instagram", "pound", "social media", "tag" ] }, "styles": ["solid"], "unicode": "23", "label": "Hashtag", "voted": false, "svg": { "solid": { "last_modified": 1684767244, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M181.3 32.4c17.4 2.9 29.2 19.4 26.3 36.8L197.8 128h95.1l11.5-69.3c2.9-17.4 19.4-29.2 36.8-26.3s29.2 19.4 26.3 36.8L357.8 128H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H347.1L325.8 320H384c17.7 0 32 14.3 32 32s-14.3 32-32 32H315.1l-11.5 69.3c-2.9 17.4-19.4 29.2-36.8 26.3s-29.2-19.4-26.3-36.8l9.8-58.7H155.1l-11.5 69.3c-2.9 17.4-19.4 29.2-36.8 26.3s-29.2-19.4-26.3-36.8L90.2 384H32c-17.7 0-32-14.3-32-32s14.3-32 32-32h68.9l21.3-128H64c-17.7 0-32-14.3-32-32s14.3-32 32-32h68.9l11.5-69.3c2.9-17.4 19.4-29.2 36.8-26.3zM187.1 192L165.8 320h95.1l21.3-128H187.1z" } }, "free": ["solid"] }, "hat-cowboy": { "aliases": { "unicodes": { "secondary": ["10f8c0"] } }, "changes": ["5.11.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "buckaroo", "horse", "jackeroo", "john b.", "old west", "pardner", "ranch", "rancher", "rodeo", "western", "wrangler" ] }, "styles": ["solid"], "unicode": "f8c0", "label": "Hat Cowboy", "voted": false, "svg": { "solid": { "last_modified": 1684767602, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M320 64c14.4 0 22.3-7 30.8-14.4C360.4 41.1 370.7 32 392 32c49.3 0 84.4 152.2 97.9 221.9C447.8 272.1 390.9 288 320 288s-127.8-15.9-169.9-34.1C163.6 184.2 198.7 32 248 32c21.3 0 31.6 9.1 41.2 17.6C297.7 57 305.6 64 320 64zM111.1 270.7c47.2 24.5 117.5 49.3 209 49.3s161.8-24.8 208.9-49.3c24.8-12.9 49.8-28.3 70.1-47.7c7.9-7.9 20.2-9.2 29.6-3.3c9.5 5.9 13.5 17.9 9.9 28.5c-13.5 37.7-38.4 72.3-66.1 100.6C523.7 398.9 443.6 448 320 448s-203.6-49.1-252.5-99.2C39.8 320.4 14.9 285.8 1.4 248.1c-3.6-10.6 .4-22.6 9.9-28.5c9.5-5.9 21.7-4.5 29.6 3.3c20.4 19.4 45.3 34.8 70.1 47.7z" } }, "free": ["solid"] }, "hat-cowboy-side": { "aliases": { "unicodes": { "secondary": ["10f8c1"] } }, "changes": ["5.11.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "buckaroo", "horse", "jackeroo", "john b.", "old west", "pardner", "ranch", "rancher", "rodeo", "western", "wrangler" ] }, "styles": ["solid"], "unicode": "f8c1", "label": "Hat Cowboy Side", "voted": false, "svg": { "solid": { "last_modified": 1684767602, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M152.7 135.9l-10.4 57.2c6.8-.7 13.6-1.1 20.5-1.1h10.7c39.4 0 77.8 12.1 110.1 34.7L562.4 421.8l35.1 24.6c24.4-6 42.5-28.1 42.5-54.4c0-75.8-94.7-126.6-134.6-144.7L474 83.9C468.2 53.8 441.8 32 411.1 32h-2.7c-5.6 0-11.1 .7-16.5 2.2L199.2 85.5c-23.9 6.4-42 26-46.5 50.4zM0 384c0 35.3 28.7 64 64 64H544L265.3 252.9c-26.9-18.8-58.9-28.9-91.8-28.9H162.9c-60.6 0-116 34.2-143.1 88.4L13.5 325C4.6 342.7 0 362.3 0 382.2V384z" } }, "free": ["solid"] }, "hat-wizard": { "aliases": { "unicodes": { "secondary": ["10f6e8"] } }, "changes": ["5.4.0", "5.11.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "Dungeons & Dragons", "accessory", "buckle", "clothing", "d&d", "dnd", "fantasy", "halloween", "head", "holiday", "mage", "magic", "pointy", "witch" ] }, "styles": ["solid"], "unicode": "f6e8", "label": "Hat Wizard", "voted": false, "svg": { "solid": { "last_modified": 1684767602, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M64 416L168.6 180.7c15.3-34.4 40.3-63.5 72-83.7l146.9-94c3-1.9 6.5-2.9 10-2.9C407.7 0 416 8.3 416 18.6v1.6c0 2.6-.5 5.1-1.4 7.5L354.8 176.9c-1.9 4.7-2.8 9.7-2.8 14.7c0 5.5 1.2 11 3.4 16.1L448 416H240.9l11.8-35.4 40.4-13.5c6.5-2.2 10.9-8.3 10.9-15.2s-4.4-13-10.9-15.2l-40.4-13.5-13.5-40.4C237 276.4 230.9 272 224 272s-13 4.4-15.2 10.9l-13.5 40.4-40.4 13.5C148.4 339 144 345.1 144 352s4.4 13 10.9 15.2l40.4 13.5L207.1 416H64zM279.6 141.5c-1.1-3.3-4.1-5.5-7.6-5.5s-6.5 2.2-7.6 5.5l-6.7 20.2-20.2 6.7c-3.3 1.1-5.5 4.1-5.5 7.6s2.2 6.5 5.5 7.6l20.2 6.7 6.7 20.2c1.1 3.3 4.1 5.5 7.6 5.5s6.5-2.2 7.6-5.5l6.7-20.2 20.2-6.7c3.3-1.1 5.5-4.1 5.5-7.6s-2.2-6.5-5.5-7.6l-20.2-6.7-6.7-20.2zM32 448H480c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32z" } }, "free": ["solid"] }, "head-side-cough": { "aliases": { "unicodes": { "secondary": ["10e061"] } }, "changes": ["5.13.0", "5.14.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["cough", "covid-19", "germs", "lungs", "respiratory", "sick"] }, "styles": ["solid"], "unicode": "e061", "label": "Head Side Cough", "voted": false, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M0 224.2C0 100.6 100.2 0 224 0h24c95.2 0 181.2 69.3 197.3 160.2c2.3 13 6.8 25.7 15.1 36l42 52.6c6.2 7.8 9.6 17.4 9.6 27.4c0 24.2-19.6 43.8-43.8 43.8H448v0 32L339.2 365.6c-11 1.4-19.2 10.7-19.2 21.8c0 11.6 9 21.2 20.6 21.9L448 416v16c0 26.5-21.5 48-48 48H320v8c0 13.3-10.7 24-24 24H256v0H96c-17.7 0-32-14.3-32-32V407.3c0-16.7-6.9-32.5-17.1-45.8C16.6 322.4 0 274.1 0 224.2zm352-.2a32 32 0 1 0 0-64 32 32 0 1 0 0 64zM464 384a24 24 0 1 1 48 0 24 24 0 1 1 -48 0zm152-24a24 24 0 1 1 0 48 24 24 0 1 1 0-48zM592 480a24 24 0 1 1 48 0 24 24 0 1 1 -48 0zM552 312a24 24 0 1 1 0 48 24 24 0 1 1 0-48zm40-24a24 24 0 1 1 48 0 24 24 0 1 1 -48 0zM552 408a24 24 0 1 1 0 48 24 24 0 1 1 0-48z" } }, "free": ["solid"] }, "head-side-cough-slash": { "aliases": { "unicodes": { "secondary": ["10e062"] } }, "changes": ["5.13.0", "5.14.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["cough", "covid-19", "germs", "lungs", "respiratory", "sick"] }, "styles": ["solid"], "unicode": "e062", "label": "Head Side Cough Slash", "voted": false, "svg": { "solid": { "last_modified": 1684766751, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M448 325.8l44 34.5c8.1 1.4 14.8 6.8 18 14.1L552.9 408c10.6 .4 19.5 7.6 22.2 17.4l39.1 30.6c.6 0 1.2-.1 1.8-.1c11.1 0 20.4 7.5 23.2 17.8h-3.9c6.2 8.5 6.4 20.4-.4 29c-8.2 10.4-23.3 12.3-33.7 4.1L9.2 42.9C-1.2 34.7-3.1 19.6 5.1 9.2S28.4-3.1 38.8 5.1L89.6 44.9C127 16.7 173.5 0 224 0h24c95.2 0 181.2 69.3 197.3 160.2c2.3 13 6.8 25.7 15.1 36l42 52.6c6.2 7.8 9.6 17.4 9.6 27.4c0 24.2-19.6 43.8-43.8 43.8H448v0 5.8zM0 224.2c0-38.7 9.8-75.1 27.1-106.9L341.8 365.3l-2.5 .3c-11 1.4-19.2 10.7-19.2 21.8c0 11.6 9 21.2 20.6 21.9l62 3.9 43 33.9C439.3 466.2 421.2 480 400 480H320v8c0 13.3-10.7 24-24 24H256v0H96c-17.7 0-32-14.3-32-32V407.3c0-16.7-6.9-32.5-17.1-45.8C16.6 322.4 0 274.1 0 224.2zM616 360a24 24 0 1 1 0 48 24 24 0 1 1 0-48zm-64-48a24 24 0 1 1 0 48 24 24 0 1 1 0-48zm40-24a24 24 0 1 1 48 0 24 24 0 1 1 -48 0z" } }, "free": ["solid"] }, "head-side-mask": { "aliases": { "unicodes": { "secondary": ["10e063"] } }, "changes": ["5.13.0", "5.14.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "breath", "coronavirus", "covid-19", "filter", "flu", "infection", "pandemic", "respirator", "virus" ] }, "styles": ["solid"], "unicode": "e063", "label": "Head Side Mask", "voted": false, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M32 224.2c0-22.2 3.2-43.6 9.2-63.9L262.2 321c-4 9.5-6.2 20-6.2 31V512H128c-17.7 0-32-14.3-32-32V407.3c0-16.7-6.9-32.5-17.1-45.8C48.6 322.4 32 274.1 32 224.2zm248.3 70.4L53 129.3C88.7 53 166.2 0 256 0h24c95.2 0 181.2 69.3 197.3 160.2c2.3 13 6.8 25.7 15.1 36l42 52.6c5.4 6.7 8.6 14.8 9.4 23.2H336c-21.7 0-41.3 8.6-55.7 22.6zM336 304H534l0 0h10l-19.7 64H368c-8.8 0-16 7.2-16 16s7.2 16 16 16H514.5l-9.8 32H368c-8.8 0-16 7.2-16 16s7.2 16 16 16H494.8l-.9 2.8c-8.3 26.9-33.1 45.2-61.2 45.2H288V352c0-14 6-26.7 15.6-35.4c0 0 0 0 0 0c8.5-7.8 19.9-12.6 32.4-12.6zm48-80a32 32 0 1 0 0-64 32 32 0 1 0 0 64z" } }, "free": ["solid"] }, "head-side-virus": { "aliases": { "unicodes": { "secondary": ["10e064"] } }, "changes": ["5.13.0", "5.14.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "cold", "coronavirus", "covid-19", "flu", "infection", "pandemic", "sick" ] }, "styles": ["solid"], "unicode": "e064", "label": "Head Side Virus", "voted": false, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 224.2C0 100.6 100.2 0 224 0h24c95.2 0 181.2 69.3 197.3 160.2c2.3 13 6.8 25.7 15.1 36l42 52.6c6.2 7.8 9.6 17.4 9.6 27.4c0 24.2-19.6 43.8-43.8 43.8H448v64c0 35.3-28.7 64-64 64H320v32c0 17.7-14.3 32-32 32H96c-17.7 0-32-14.3-32-32V407.3c0-16.7-6.9-32.5-17.1-45.8C16.6 322.4 0 274.1 0 224.2zM224 64c-8.8 0-16 7.2-16 16c0 33-39.9 49.5-63.2 26.2c-6.2-6.2-16.4-6.2-22.6 0s-6.2 16.4 0 22.6C145.5 152.1 129 192 96 192c-8.8 0-16 7.2-16 16s7.2 16 16 16c33 0 49.5 39.9 26.2 63.2c-6.2 6.2-6.2 16.4 0 22.6s16.4 6.2 22.6 0C168.1 286.5 208 303 208 336c0 8.8 7.2 16 16 16s16-7.2 16-16c0-33 39.9-49.5 63.2-26.2c6.2 6.2 16.4 6.2 22.6 0s6.2-16.4 0-22.6C302.5 263.9 319 224 352 224c8.8 0 16-7.2 16-16s-7.2-16-16-16c-33 0-49.5-39.9-26.2-63.2c6.2-6.2 6.2-16.4 0-22.6s-16.4-6.2-22.6 0C279.9 129.5 240 113 240 80c0-8.8-7.2-16-16-16zm-24 96a24 24 0 1 1 0 48 24 24 0 1 1 0-48zm40 80a16 16 0 1 1 32 0 16 16 0 1 1 -32 0z" } }, "free": ["solid"] }, "heading": { "aliases": { "names": ["header"], "unicodes": { "secondary": ["10f1dc"] } }, "changes": [ "4.1.0", "5.0.0", "5.9.0", "5.10.1", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["format", "header", "text", "title"] }, "styles": ["solid"], "unicode": "f1dc", "label": "Heading", "voted": false, "svg": { "solid": { "last_modified": 1684767247, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M0 64C0 46.3 14.3 32 32 32H80h48c17.7 0 32 14.3 32 32s-14.3 32-32 32H112V208H336V96H320c-17.7 0-32-14.3-32-32s14.3-32 32-32h48 48c17.7 0 32 14.3 32 32s-14.3 32-32 32H400V240 416h16c17.7 0 32 14.3 32 32s-14.3 32-32 32H368 320c-17.7 0-32-14.3-32-32s14.3-32 32-32h16V272H112V416h16c17.7 0 32 14.3 32 32s-14.3 32-32 32H80 32c-17.7 0-32-14.3-32-32s14.3-32 32-32H48V240 96H32C14.3 96 0 81.7 0 64z" } }, "free": ["solid"] }, "headphones": { "aliases": { "unicodes": { "composite": ["1f3a7"], "secondary": ["10f025"] } }, "changes": ["1.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "audio", "earbud", "headphone", "listen", "music", "sound", "speaker" ] }, "styles": ["solid"], "unicode": "f025", "label": "Headphones", "voted": false, "svg": { "solid": { "last_modified": 1684766676, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 80C149.9 80 62.4 159.4 49.6 262c9.4-3.8 19.6-6 30.4-6c26.5 0 48 21.5 48 48V432c0 26.5-21.5 48-48 48c-44.2 0-80-35.8-80-80V384 336 288C0 146.6 114.6 32 256 32s256 114.6 256 256v48 48 16c0 44.2-35.8 80-80 80c-26.5 0-48-21.5-48-48V304c0-26.5 21.5-48 48-48c10.8 0 21 2.1 30.4 6C449.6 159.4 362.1 80 256 80z" } }, "free": ["solid"] }, "headphones-simple": { "aliases": { "names": ["headphones-alt"], "unicodes": { "secondary": ["10f58f"] } }, "changes": ["5.1.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["audio", "listen", "music", "sound", "speaker"] }, "styles": ["solid"], "unicode": "f58f", "label": "Headphones Simple", "voted": true, "svg": { "solid": { "last_modified": 1684766677, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 80C141.1 80 48 173.1 48 288V392c0 13.3-10.7 24-24 24s-24-10.7-24-24V288C0 146.6 114.6 32 256 32s256 114.6 256 256V392c0 13.3-10.7 24-24 24s-24-10.7-24-24V288c0-114.9-93.1-208-208-208zM80 352c0-35.3 28.7-64 64-64h16c17.7 0 32 14.3 32 32V448c0 17.7-14.3 32-32 32H144c-35.3 0-64-28.7-64-64V352zm288-64c35.3 0 64 28.7 64 64v64c0 35.3-28.7 64-64 64H352c-17.7 0-32-14.3-32-32V320c0-17.7 14.3-32 32-32h16z" } }, "free": ["solid"] }, "headset": { "aliases": { "unicodes": { "secondary": ["10f590"] } }, "changes": ["5.1.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "audio", "gamer", "gaming", "listen", "live chat", "microphone", "shot caller", "sound", "support", "telemarketer" ] }, "styles": ["solid"], "unicode": "f590", "label": "Headset", "voted": true, "svg": { "solid": { "last_modified": 1684766676, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 48C141.1 48 48 141.1 48 256v40c0 13.3-10.7 24-24 24s-24-10.7-24-24V256C0 114.6 114.6 0 256 0S512 114.6 512 256V400.1c0 48.6-39.4 88-88.1 88L313.6 488c-8.3 14.3-23.8 24-41.6 24H240c-26.5 0-48-21.5-48-48s21.5-48 48-48h32c17.8 0 33.3 9.7 41.6 24l110.4 .1c22.1 0 40-17.9 40-40V256c0-114.9-93.1-208-208-208zM144 208h16c17.7 0 32 14.3 32 32V352c0 17.7-14.3 32-32 32H144c-35.3 0-64-28.7-64-64V272c0-35.3 28.7-64 64-64zm224 0c35.3 0 64 28.7 64 64v48c0 35.3-28.7 64-64 64H352c-17.7 0-32-14.3-32-32V240c0-17.7 14.3-32 32-32h16z" } }, "free": ["solid"] }, "heart": { "aliases": { "unicodes": { "composite": [ "1f499", "1f49a", "1f49b", "1f49c", "1f5a4", "1f90d", "1f90e", "1f9e1", "2665", "2764", "f08a" ], "secondary": ["10f004"] } }, "changes": [ "1.0.0", "5.0.0", "5.0.9", "5.10.1", "5.10.2", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "black", "black heart", "blue", "blue heart", "brown", "brown heart", "card", "evil", "favorite", "game", "green", "green heart", "heart", "heart suit", "like", "love", "orange", "orange heart", "purple", "purple heart", "red heart", "relationship", "valentine", "white", "white heart", "wicked", "yellow", "yellow heart" ] }, "styles": ["solid", "regular"], "unicode": "f004", "label": "Heart", "voted": false, "svg": { "solid": { "last_modified": 1684767552, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M47.6 300.4L228.3 469.1c7.5 7 17.4 10.9 27.7 10.9s20.2-3.9 27.7-10.9L464.4 300.4c30.4-28.3 47.6-68 47.6-109.5v-5.8c0-69.9-50.5-129.5-119.4-141C347 36.5 300.6 51.4 268 84L256 96 244 84c-32.6-32.6-79-47.5-124.6-39.9C50.5 55.6 0 115.2 0 185.1v5.8c0 41.5 17.2 81.2 47.6 109.5z" }, "regular": { "last_modified": 1684767552, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M225.8 468.2l-2.5-2.3L48.1 303.2C17.4 274.7 0 234.7 0 192.8v-3.3c0-70.4 50-130.8 119.2-144C158.6 37.9 198.9 47 231 69.6c9 6.4 17.4 13.8 25 22.3c4.2-4.8 8.7-9.2 13.5-13.3c3.7-3.2 7.5-6.2 11.5-9c0 0 0 0 0 0C313.1 47 353.4 37.9 392.8 45.4C462 58.6 512 119.1 512 189.5v3.3c0 41.9-17.4 81.9-48.1 110.4L288.7 465.9l-2.5 2.3c-8.2 7.6-19 11.9-30.2 11.9s-22-4.2-30.2-11.9zM239.1 145c-.4-.3-.7-.7-1-1.1l-17.8-20c0 0-.1-.1-.1-.1c0 0 0 0 0 0c-23.1-25.9-58-37.7-92-31.2C81.6 101.5 48 142.1 48 189.5v3.3c0 28.5 11.9 55.8 32.8 75.2L256 430.7 431.2 268c20.9-19.4 32.8-46.7 32.8-75.2v-3.3c0-47.3-33.6-88-80.1-96.9c-34-6.5-69 5.4-92 31.2c0 0 0 0-.1 .1s0 0-.1 .1l-17.8 20c-.3 .4-.7 .7-1 1.1c-4.5 4.5-10.6 7-16.9 7s-12.4-2.5-16.9-7z" } }, "free": ["regular", "solid"] }, "heart-circle-bolt": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["cardiogram", "ekg", "electric", "heart", "love", "pacemaker"] }, "styles": ["solid"], "unicode": "e4fc", "label": "Heart Circle Bolt", "voted": false, "svg": { "solid": { "last_modified": 1684767551, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M47.6 300.4L228.3 469.1c7.5 7 17.4 10.9 27.7 10.9s20.2-3.9 27.7-10.9l2.6-2.4C267.2 438.6 256 404.6 256 368c0-97.2 78.8-176 176-176c28.3 0 55 6.7 78.7 18.5c.9-6.5 1.3-13 1.3-19.6v-5.8c0-69.9-50.5-129.5-119.4-141C347 36.5 300.6 51.4 268 84L256 96 244 84c-32.6-32.6-79-47.5-124.6-39.9C50.5 55.6 0 115.2 0 185.1v5.8c0 41.5 17.2 81.2 47.6 109.5zM432 512a144 144 0 1 0 0-288 144 144 0 1 0 0 288zm47.9-225c4.3 3.7 5.4 9.9 2.6 14.9L452.4 356H488c5.2 0 9.8 3.3 11.4 8.2s-.1 10.3-4.2 13.4l-96 72c-4.5 3.4-10.8 3.2-15.1-.6s-5.4-9.9-2.6-14.9L411.6 380H376c-5.2 0-9.8-3.3-11.4-8.2s.1-10.3 4.2-13.4l96-72c4.5-3.4 10.8-3.2 15.1 .6z" } }, "free": ["solid"] }, "heart-circle-check": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["favorite", "heart", "love", "not affected", "ok", "okay"] }, "styles": ["solid"], "unicode": "e4fd", "label": "Heart Circle Check", "voted": false, "svg": { "solid": { "last_modified": 1684767552, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M47.6 300.4L228.3 469.1c7.5 7 17.4 10.9 27.7 10.9s20.2-3.9 27.7-10.9l2.6-2.4C267.2 438.6 256 404.6 256 368c0-97.2 78.8-176 176-176c28.3 0 55 6.7 78.7 18.5c.9-6.5 1.3-13 1.3-19.6v-5.8c0-69.9-50.5-129.5-119.4-141C347 36.5 300.6 51.4 268 84L256 96 244 84c-32.6-32.6-79-47.5-124.6-39.9C50.5 55.6 0 115.2 0 185.1v5.8c0 41.5 17.2 81.2 47.6 109.5zM576 368a144 144 0 1 0 -288 0 144 144 0 1 0 288 0zm-76.7-43.3c6.2 6.2 6.2 16.4 0 22.6l-72 72c-6.2 6.2-16.4 6.2-22.6 0l-40-40c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0L416 385.4l60.7-60.7c6.2-6.2 16.4-6.2 22.6 0z" } }, "free": ["solid"] }, "heart-circle-exclamation": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["favorite", "heart", "love"] }, "styles": ["solid"], "unicode": "e4fe", "label": "Heart Circle Exclamation", "voted": false, "svg": { "solid": { "last_modified": 1684767551, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M47.6 300.4L228.3 469.1c7.5 7 17.4 10.9 27.7 10.9s20.2-3.9 27.7-10.9l2.6-2.4C267.2 438.6 256 404.6 256 368c0-97.2 78.8-176 176-176c28.3 0 55 6.7 78.7 18.5c.9-6.5 1.3-13 1.3-19.6v-5.8c0-69.9-50.5-129.5-119.4-141C347 36.5 300.6 51.4 268 84L256 96 244 84c-32.6-32.6-79-47.5-124.6-39.9C50.5 55.6 0 115.2 0 185.1v5.8c0 41.5 17.2 81.2 47.6 109.5zM432 512a144 144 0 1 0 0-288 144 144 0 1 0 0 288zm0-96a24 24 0 1 1 0 48 24 24 0 1 1 0-48zm0-144c8.8 0 16 7.2 16 16v80c0 8.8-7.2 16-16 16s-16-7.2-16-16V288c0-8.8 7.2-16 16-16z" } }, "free": ["solid"] }, "heart-circle-minus": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["favorite", "heart", "love"] }, "styles": ["solid"], "unicode": "e4ff", "label": "Heart Circle Minus", "voted": false, "svg": { "solid": { "last_modified": 1684767553, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M47.6 300.4L228.3 469.1c7.5 7 17.4 10.9 27.7 10.9s20.2-3.9 27.7-10.9l2.6-2.4C267.2 438.6 256 404.6 256 368c0-97.2 78.8-176 176-176c28.3 0 55 6.7 78.7 18.5c.9-6.5 1.3-13 1.3-19.6v-5.8c0-69.9-50.5-129.5-119.4-141C347 36.5 300.6 51.4 268 84L256 96 244 84c-32.6-32.6-79-47.5-124.6-39.9C50.5 55.6 0 115.2 0 185.1v5.8c0 41.5 17.2 81.2 47.6 109.5zM576 368a144 144 0 1 0 -288 0 144 144 0 1 0 288 0zm-64 0c0 8.8-7.2 16-16 16H368c-8.8 0-16-7.2-16-16s7.2-16 16-16H496c8.8 0 16 7.2 16 16z" } }, "free": ["solid"] }, "heart-circle-plus": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["favorite", "heart", "love"] }, "styles": ["solid"], "unicode": "e500", "label": "Heart Circle Plus", "voted": false, "svg": { "solid": { "last_modified": 1684767552, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M47.6 300.4L228.3 469.1c7.5 7 17.4 10.9 27.7 10.9s20.2-3.9 27.7-10.9l2.6-2.4C267.2 438.6 256 404.6 256 368c0-97.2 78.8-176 176-176c28.3 0 55 6.7 78.7 18.5c.9-6.5 1.3-13 1.3-19.6v-5.8c0-69.9-50.5-129.5-119.4-141C347 36.5 300.6 51.4 268 84L256 96 244 84c-32.6-32.6-79-47.5-124.6-39.9C50.5 55.6 0 115.2 0 185.1v5.8c0 41.5 17.2 81.2 47.6 109.5zM432 512a144 144 0 1 0 0-288 144 144 0 1 0 0 288zm16-208v48h48c8.8 0 16 7.2 16 16s-7.2 16-16 16H448v48c0 8.8-7.2 16-16 16s-16-7.2-16-16V384H368c-8.8 0-16-7.2-16-16s7.2-16 16-16h48V304c0-8.8 7.2-16 16-16s16 7.2 16 16z" } }, "free": ["solid"] }, "heart-circle-xmark": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["favorite", "heart", "love"] }, "styles": ["solid"], "unicode": "e501", "label": "Heart Circle Xmark", "voted": false, "svg": { "solid": { "last_modified": 1684767552, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M47.6 300.4L228.3 469.1c7.5 7 17.4 10.9 27.7 10.9s20.2-3.9 27.7-10.9l2.6-2.4C267.2 438.6 256 404.6 256 368c0-97.2 78.8-176 176-176c28.3 0 55 6.7 78.7 18.5c.9-6.5 1.3-13 1.3-19.6v-5.8c0-69.9-50.5-129.5-119.4-141C347 36.5 300.6 51.4 268 84L256 96 244 84c-32.6-32.6-79-47.5-124.6-39.9C50.5 55.6 0 115.2 0 185.1v5.8c0 41.5 17.2 81.2 47.6 109.5zM432 512a144 144 0 1 0 0-288 144 144 0 1 0 0 288zm59.3-180.7L454.6 368l36.7 36.7c6.2 6.2 6.2 16.4 0 22.6s-16.4 6.2-22.6 0L432 390.6l-36.7 36.7c-6.2 6.2-16.4 6.2-22.6 0s-6.2-16.4 0-22.6L409.4 368l-36.7-36.7c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0L432 345.4l36.7-36.7c6.2-6.2 16.4-6.2 22.6 0s6.2 16.4 0 22.6z" } }, "free": ["solid"] }, "heart-crack": { "aliases": { "names": ["heart-broken"], "unicodes": { "composite": ["1f494"], "secondary": ["10f7a9"] } }, "changes": [ "5.6.0", "5.10.2", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "break", "breakup", "broken", "broken heart", "crushed", "dislike", "dumped", "grief", "love", "lovesick", "relationship", "sad" ] }, "styles": ["solid"], "unicode": "f7a9", "label": "Heart Crack", "voted": true, "svg": { "solid": { "last_modified": 1684767553, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M119.4 44.1c23.3-3.9 46.8-1.9 68.6 5.3l49.8 77.5-75.4 75.4c-1.5 1.5-2.4 3.6-2.3 5.8s1 4.2 2.6 5.7l112 104c2.9 2.7 7.4 2.9 10.5 .3s3.8-7 1.7-10.4l-60.4-98.1 90.7-75.6c2.6-2.1 3.5-5.7 2.4-8.8L296.8 61.8c28.5-16.7 62.4-23.2 95.7-17.6C461.5 55.6 512 115.2 512 185.1v5.8c0 41.5-17.2 81.2-47.6 109.5L283.7 469.1c-7.5 7-17.4 10.9-27.7 10.9s-20.2-3.9-27.7-10.9L47.6 300.4C17.2 272.1 0 232.4 0 190.9v-5.8c0-69.9 50.5-129.5 119.4-141z" } }, "free": ["solid"] }, "heart-pulse": { "aliases": { "names": ["heartbeat"], "unicodes": { "secondary": ["10f21e"] } }, "changes": [ "4.3.0", "5.0.0", "5.0.7", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["ekg", "electrocardiogram", "health", "lifeline", "vital signs"] }, "styles": ["solid"], "unicode": "f21e", "label": "Heart Pulse", "voted": false, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M228.3 469.1L47.6 300.4c-4.2-3.9-8.2-8.1-11.9-12.4h87c22.6 0 43-13.6 51.7-34.5l10.5-25.2 49.3 109.5c3.8 8.5 12.1 14 21.4 14.1s17.8-5 22-13.3L320 253.7l1.7 3.4c9.5 19 28.9 31 50.1 31H476.3c-3.7 4.3-7.7 8.5-11.9 12.4L283.7 469.1c-7.5 7-17.4 10.9-27.7 10.9s-20.2-3.9-27.7-10.9zM503.7 240h-132c-3 0-5.8-1.7-7.2-4.4l-23.2-46.3c-4.1-8.1-12.4-13.3-21.5-13.3s-17.4 5.1-21.5 13.3l-41.4 82.8L205.9 158.2c-3.9-8.7-12.7-14.3-22.2-14.1s-18.1 5.9-21.8 14.8l-31.8 76.3c-1.2 3-4.2 4.9-7.4 4.9H16c-2.6 0-5 .4-7.3 1.1C3 225.2 0 208.2 0 190.9v-5.8c0-69.9 50.5-129.5 119.4-141C165 36.5 211.4 51.4 244 84l12 12 12-12c32.6-32.6 79-47.5 124.6-39.9C461.5 55.6 512 115.2 512 185.1v5.8c0 16.9-2.8 33.5-8.3 49.1z" } }, "free": ["solid"] }, "helicopter": { "aliases": { "unicodes": { "composite": ["1f681"], "secondary": ["10f533"] } }, "changes": [ "5.0.13", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "airwolf", "apache", "chopper", "flight", "fly", "helicopter", "travel", "vehicle" ] }, "styles": ["solid"], "unicode": "f533", "label": "Helicopter", "voted": true, "svg": { "solid": { "last_modified": 1684767637, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M128 32c0-17.7 14.3-32 32-32H544c17.7 0 32 14.3 32 32s-14.3 32-32 32H384v64h32c88.4 0 160 71.6 160 160v64c0 17.7-14.3 32-32 32H384 320c-20.1 0-39.1-9.5-51.2-25.6l-71.4-95.2c-3.5-4.7-8.3-8.3-13.7-10.5L47.2 198.1c-9.5-3.8-16.7-12-19.2-22L5 83.9C2.4 73.8 10.1 64 20.5 64H48c10.1 0 19.6 4.7 25.6 12.8L112 128H320V64H160c-17.7 0-32-14.3-32-32zM384 320H512V288c0-53-43-96-96-96H384V320zM630.6 425.4c12.5 12.5 12.5 32.8 0 45.3l-3.9 3.9c-24 24-56.6 37.5-90.5 37.5H256c-17.7 0-32-14.3-32-32s14.3-32 32-32H536.2c17 0 33.3-6.7 45.3-18.7l3.9-3.9c12.5-12.5 32.8-12.5 45.3 0z" } }, "free": ["solid"] }, "helicopter-symbol": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["chopper", "helicopter", "landing pad", "whirlybird"] }, "styles": ["solid"], "unicode": "e502", "label": "Helicopter Symbol", "voted": false, "svg": { "solid": { "last_modified": 1684767489, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M445.3 224H510C495.6 108.2 403.8 16.4 288 2V66.7C368.4 80.1 431.9 143.6 445.3 224zM510 288H445.3C431.9 368.4 368.4 431.9 288 445.4V510c115.8-14.4 207.6-106.2 222-222zM2 288C16.4 403.8 108.2 495.6 224 510V445.4C143.6 431.9 80.1 368.4 66.7 288H2zm0-64H66.7C80.1 143.6 143.6 80.1 224 66.7V2C108.2 16.4 16.4 108.2 2 224zm206-64c0-17.7-14.3-32-32-32s-32 14.3-32 32V352c0 17.7 14.3 32 32 32s32-14.3 32-32V288h96v64c0 17.7 14.3 32 32 32s32-14.3 32-32V160c0-17.7-14.3-32-32-32s-32 14.3-32 32v64H208V160z" } }, "free": ["solid"] }, "helmet-safety": { "aliases": { "names": ["hard-hat", "hat-hard"], "unicodes": { "secondary": ["10f807"] } }, "changes": ["5.7.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["construction", "hardhat", "helmet", "safety"] }, "styles": ["solid"], "unicode": "f807", "label": "Helmet Safety", "voted": true, "svg": { "solid": { "last_modified": 1684767602, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M256 32c-17.7 0-32 14.3-32 32v2.3 99.6c0 5.6-4.5 10.1-10.1 10.1c-3.6 0-7-1.9-8.8-5.1L157.1 87C83 123.5 32 199.8 32 288v64H544l0-66.4c-.9-87.2-51.7-162.4-125.1-198.6l-48 83.9c-1.8 3.2-5.2 5.1-8.8 5.1c-5.6 0-10.1-4.5-10.1-10.1V66.3 64c0-17.7-14.3-32-32-32H256zM16.6 384C7.4 384 0 391.4 0 400.6c0 4.7 2 9.2 5.8 11.9C27.5 428.4 111.8 480 288 480s260.5-51.6 282.2-67.5c3.8-2.8 5.8-7.2 5.8-11.9c0-9.2-7.4-16.6-16.6-16.6H16.6z" } }, "free": ["solid"] }, "helmet-un": { "changes": ["6.1.0", "6.1.2", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["helmet", "united nations"] }, "styles": ["solid"], "unicode": "e503", "label": "Helmet Un", "voted": false, "svg": { "solid": { "last_modified": 1684767443, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M479.5 224C471.2 98.9 367.2 0 240 0C107.5 0 0 107.5 0 240v56.3C0 344.8 39.2 384 87.7 384H200h14.9L343.5 505.4c4.5 4.2 10.4 6.6 16.5 6.6h96c13.3 0 24-10.7 24-24s-10.7-24-24-24H369.5l-1.5-1.5V288h80 32c17.7 0 32-14.3 32-32s-14.3-32-32-32h-.5zM320 417.2l-78-73.7L274.4 288H320V417.2zM285.3 103.1l34.7 52V112c0-8.8 7.2-16 16-16s16 7.2 16 16v96c0 7.1-4.6 13.3-11.4 15.3s-14-.6-17.9-6.4l-34.7-52V208c0 8.8-7.2 16-16 16s-16-7.2-16-16V112c0-7.1 4.6-13.3 11.4-15.3s14 .6 17.9 6.4zM160 112v64c0 8.8 7.2 16 16 16s16-7.2 16-16V112c0-8.8 7.2-16 16-16s16 7.2 16 16v64c0 26.5-21.5 48-48 48s-48-21.5-48-48V112c0-8.8 7.2-16 16-16s16 7.2 16 16z" } }, "free": ["solid"] }, "highlighter": { "aliases": { "unicodes": { "secondary": ["10f591"] } }, "changes": [ "5.1.0", "5.10.1", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["edit", "marker", "sharpie", "update", "write"] }, "styles": ["solid"], "unicode": "f591", "label": "Highlighter", "voted": true, "svg": { "solid": { "last_modified": 1684767368, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M315 315l158.4-215L444.1 70.6 229 229 315 315zm-187 5l0 0V248.3c0-15.3 7.2-29.6 19.5-38.6L420.6 8.4C428 2.9 437 0 446.2 0c11.4 0 22.4 4.5 30.5 12.6l54.8 54.8c8.1 8.1 12.6 19 12.6 30.5c0 9.2-2.9 18.2-8.4 25.6L334.4 396.5c-9 12.3-23.4 19.5-38.6 19.5H224l-25.4 25.4c-12.5 12.5-32.8 12.5-45.3 0l-50.7-50.7c-12.5-12.5-12.5-32.8 0-45.3L128 320zM7 466.3l63-63 70.6 70.6-31 31c-4.5 4.5-10.6 7-17 7H24c-13.3 0-24-10.7-24-24v-4.7c0-6.4 2.5-12.5 7-17z" } }, "free": ["solid"] }, "hill-avalanche": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["mudslide", "snow", "winter"] }, "styles": ["solid"], "unicode": "e507", "label": "Hill Avalanche", "voted": false, "svg": { "solid": { "last_modified": 1684767662, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M439.7 401.9c34.2 23.1 81.1 19.5 111.4-10.8c34.4-34.4 34.4-90.1 0-124.4c-27.8-27.8-69.5-33.1-102.6-16c-11.8 6.1-16.4 20.6-10.3 32.3s20.6 16.4 32.3 10.3c15.1-7.8 34-5.3 46.6 7.3c15.6 15.6 15.6 40.9 0 56.6s-40.9 15.6-56.6 0l-81.7-81.7C401.2 261.3 416 236.4 416 208c0-33.9-21.1-62.9-50.9-74.5c1.9-6.8 2.9-14 2.9-21.5c0-44.2-35.8-80-80-80c-27.3 0-51.5 13.7-65.9 34.6C216.3 46.6 197.9 32 176 32c-26.5 0-48 21.5-48 48c0 4 .5 7.9 1.4 11.6L439.7 401.9zM480 64a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zm0 128a32 32 0 1 0 0-64 32 32 0 1 0 0 64zM68.3 87C43.1 61.8 0 79.7 0 115.3V432c0 44.2 35.8 80 80 80H396.7c35.6 0 53.5-43.1 28.3-68.3L68.3 87z" } }, "free": ["solid"] }, "hill-rockslide": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["mudslide"] }, "styles": ["solid"], "unicode": "e508", "label": "Hill Rockslide", "voted": false, "svg": { "solid": { "last_modified": 1684767661, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M252.4 103.8l27 48c2.8 5 8.2 8.2 13.9 8.2l53.3 0c5.8 0 11.1-3.1 13.9-8.2l27-48c2.7-4.9 2.7-10.8 0-15.7l-27-48c-2.8-5-8.2-8.2-13.9-8.2H293.4c-5.8 0-11.1 3.1-13.9 8.2l-27 48c-2.7 4.9-2.7 10.8 0 15.7zM68.3 87C43.1 61.8 0 79.7 0 115.3V432c0 44.2 35.8 80 80 80H396.7c35.6 0 53.5-43.1 28.3-68.3L68.3 87zM504.2 403.6c4.9 2.7 10.8 2.7 15.7 0l48-27c5-2.8 8.2-8.2 8.2-13.9V309.4c0-5.8-3.1-11.1-8.2-13.9l-48-27c-4.9-2.7-10.8-2.7-15.7 0l-48 27c-5 2.8-8.2 8.2-8.2 13.9v53.3c0 5.8 3.1 11.1 8.2 13.9l48 27zM192 64a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zM384 288a32 32 0 1 0 0-64 32 32 0 1 0 0 64z" } }, "free": ["solid"] }, "hippo": { "aliases": { "unicodes": { "composite": ["1f99b"], "secondary": ["10f6ed"] } }, "changes": [ "5.4.0", "5.10.1", "6.0.0-beta1", "6.1.2", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["animal", "fauna", "hippo", "hippopotamus", "hungry", "mammal"] }, "styles": ["solid"], "unicode": "f6ed", "label": "Hippo", "voted": false, "svg": { "solid": { "last_modified": 1684768130, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M407 47c9.4-9.4 24.6-9.4 33.9 0l17.2 17.2c1.9-.1 3.9-.2 5.8-.2h32c11.2 0 21.9 2.3 31.6 6.5L543 55c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9L564 101.9c7.6 12.2 12 26.7 12 42.1c0 10.2 7.4 18.8 16.7 23c27.9 12.5 47.3 40.5 47.3 73c0 26.2-12.6 49.4-32 64v32c0 8.8-7.2 16-16 16H560c-8.8 0-16-7.2-16-16V320H480v16c0 8.8-7.2 16-16 16H432c-8.8 0-16-7.2-16-16V318.4c-11.8-2.4-22.7-7.4-32-14.4c-1.5-1.1-2.9-2.3-4.3-3.5c-17-14.7-27.7-36.4-27.7-60.5c0-8.8-7.2-16-16-16s-16 7.2-16 16c0 44.7 26.2 83.2 64 101.2V352c0 17.7 14.3 32 32 32h32v64c0 17.7-14.3 32-32 32H352c-17.7 0-32-14.3-32-32V372c-19.8 7.7-41.4 12-64 12s-44.2-4.3-64-12v76c0 17.7-14.3 32-32 32H96c-17.7 0-32-14.3-32-32V329.1L45.9 369.7c-5.4 12.1-19.6 17.6-31.7 12.2S-3.3 362.4 2.1 350.3L24 300.9c5.3-11.9 8-24.7 8-37.7C32 155.7 117.2 68 223.8 64.1l.2-.1h7.2H256h32c41.7 0 83.4 12.1 117.2 25.7c1.7-1.8 3.5-3.6 5.3-5.2L407 81c-9.4-9.4-9.4-24.6 0-33.9zm73 185a24 24 0 1 0 -48 0 24 24 0 1 0 48 0zm88 24a24 24 0 1 0 0-48 24 24 0 1 0 0 48zM480 144a16 16 0 1 0 -32 0 16 16 0 1 0 32 0zm48 16a16 16 0 1 0 0-32 16 16 0 1 0 0 32z" } }, "free": ["solid"] }, "hips": { "changes": ["5.0.5"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f452", "label": "Hips", "voted": false, "svg": { "brands": { "last_modified": 1660014475, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M251.6 157.6c0-1.9-.9-2.8-2.8-2.8h-40.9c-1.6 0-2.7 1.4-2.7 2.8v201.8c0 1.4 1.1 2.8 2.7 2.8h40.9c1.9 0 2.8-.9 2.8-2.8zM156.5 168c-16.1-11.8-36.3-17.9-60.3-18-18.1-.1-34.6 3.7-49.8 11.4V80.2c0-1.8-.9-2.7-2.8-2.7H2.7c-1.8 0-2.7.9-2.7 2.7v279.2c0 1.9.9 2.8 2.7 2.8h41c1.9 0 2.8-.9 2.8-2.8V223.3c0-.8-2.8-27 45.8-27 48.5 0 45.8 26.1 45.8 27v122.6c0 9 7.3 16.3 16.4 16.3h27.3c1.8 0 2.7-.9 2.7-2.8V223.3c0-23.4-9.3-41.8-28-55.3zm478.4 110.1c-6.8-15.7-18.4-27-34.9-34.1l-57.6-25.3c-8.6-3.6-9.2-11.2-2.6-16.1 7.4-5.5 44.3-13.9 84 6.8 1.7 1 4-.3 4-2.4v-44.7c0-1.3-.6-2.1-1.9-2.6-17.7-6.6-36.1-9.9-55.1-9.9-26.5 0-45.3 5.8-58.5 15.4-.5.4-28.4 20-22.7 53.7 3.4 19.6 15.8 34.2 37.2 43.6l53.6 23.5c11.6 5.1 15.2 13.3 12.2 21.2-3.7 9.1-13.2 13.6-36.5 13.6-24.3 0-44.7-8.9-58.4-19.1-2.1-1.4-4.4.2-4.4 2.3v34.4c0 10.4 4.9 17.3 14.6 20.7 15.6 5.5 31.6 8.2 48.2 8.2 12.7 0 25.8-1.2 36.3-4.3.7-.3 36-8.9 45.6-45.8 3.5-13.5 2.4-26.5-3.1-39.1zM376.2 149.8c-31.7 0-104.2 20.1-104.2 103.5v183.5c0 .8.6 2.7 2.7 2.7h40.9c1.9 0 2.8-.9 2.8-2.7V348c16.5 12.7 35.8 19.1 57.7 19.1 60.5 0 108.7-48.5 108.7-108.7.1-60.3-48.2-108.6-108.6-108.6zm0 170.9c-17.2 0-31.9-6.1-44-18.2-12.2-12.2-18.2-26.8-18.2-44 0-34.5 27.6-62.2 62.2-62.2 34.5 0 62.2 27.6 62.2 62.2.1 34.3-27.3 62.2-62.2 62.2zM228.3 72.5c-15.9 0-28.8 12.9-28.9 28.9 0 15.6 12.7 28.9 28.9 28.9s28.9-13.1 28.9-28.9c0-16.2-13-28.9-28.9-28.9z" } }, "free": ["brands"] }, "hire-a-helper": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3b0", "label": "HireAHelper", "voted": false, "svg": { "brands": { "last_modified": 1660014481, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M443.1 0H71.9C67.9 37.3 37.4 67.8 0 71.7v371.5c37.4 4.9 66 32.4 71.9 68.8h372.2c3-36.4 32.5-65.8 67.9-69.8V71.7c-36.4-5.9-65-35.3-68.9-71.7zm-37 404.9c-36.3 0-18.8-2-55.1-2-35.8 0-21 2-56.1 2-5.9 0-4.9-8.2 0-9.8 22.8-7.6 22.9-10.2 24.6-12.8 10.4-15.6 5.9-83 5.9-113 0-5.3-6.4-12.8-13.8-12.8H200.4c-7.4 0-13.8 7.5-13.8 12.8 0 30-4.5 97.4 5.9 113 1.7 2.5 1.8 5.2 24.6 12.8 4.9 1.6 6 9.8 0 9.8-35.1 0-20.3-2-56.1-2-36.3 0-18.8 2-55.1 2-7.9 0-5.8-10.8 0-10.8 10.2-3.4 13.5-3.5 21.7-13.8 7.7-12.9 7.9-44.4 7.9-127.8V151.3c0-22.2-12.2-28.3-28.6-32.4-8.8-2.2-4-11.8 1-11.8 36.5 0 20.6 2 57.1 2 32.7 0 16.5-2 49.2-2 3.3 0 8.5 8.3 1 10.8-4.9 1.6-27.6 3.7-27.6 39.3 0 45.6-.2 55.8 1 68.8 0 1.3 2.3 12.8 12.8 12.8h109.2c10.5 0 12.8-11.5 12.8-12.8 1.2-13 1-23.2 1-68.8 0-35.6-22.7-37.7-27.6-39.3-7.5-2.5-2.3-10.8 1-10.8 32.7 0 16.5 2 49.2 2 36.5 0 20.6-2 57.1-2 4.9 0 9.9 9.6 1 11.8-16.4 4.1-28.6 10.3-28.6 32.4v101.2c0 83.4.1 114.9 7.9 127.8 8.2 10.2 11.4 10.4 21.7 13.8 5.8 0 7.8 10.8 0 10.8z" } }, "free": ["brands"] }, "hive": { "changes": ["5.15.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e07f", "label": "Hive Blockchain Network", "voted": false, "svg": { "brands": { "last_modified": 1660014473, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M260.353,254.878,131.538,33.1a2.208,2.208,0,0,0-3.829.009L.3,254.887A2.234,2.234,0,0,0,.3,257.122L129.116,478.9a2.208,2.208,0,0,0,3.83-.009L260.358,257.113A2.239,2.239,0,0,0,260.353,254.878Zm39.078-25.713a2.19,2.19,0,0,0,1.9,1.111h66.509a2.226,2.226,0,0,0,1.9-3.341L259.115,33.111a2.187,2.187,0,0,0-1.9-1.111H190.707a2.226,2.226,0,0,0-1.9,3.341ZM511.7,254.886,384.9,33.112A2.2,2.2,0,0,0,382.99,32h-66.6a2.226,2.226,0,0,0-1.906,3.34L440.652,256,314.481,476.66a2.226,2.226,0,0,0,1.906,3.34h66.6a2.2,2.2,0,0,0,1.906-1.112L511.7,257.114A2.243,2.243,0,0,0,511.7,254.886ZM366.016,284.917H299.508a2.187,2.187,0,0,0-1.9,1.111l-108.8,190.631a2.226,2.226,0,0,0,1.9,3.341h66.509a2.187,2.187,0,0,0,1.9-1.111l108.8-190.631A2.226,2.226,0,0,0,366.016,284.917Z" } }, "free": ["brands"] }, "hockey-puck": { "aliases": { "unicodes": { "secondary": ["10f453"] } }, "changes": ["5.0.5", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["ice", "nhl", "sport"] }, "styles": ["solid"], "unicode": "f453", "label": "Hockey Puck", "voted": false, "svg": { "solid": { "last_modified": 1684767071, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 256C114.6 256 0 213 0 160s114.6-96 256-96s256 43 256 96s-114.6 96-256 96zm192.3 1.8c24.7-9.3 46.9-21 63.7-35.6V352c0 53-114.6 96-256 96S0 405 0 352V222.3c16.8 14.6 39 26.3 63.7 35.6C114.5 276.9 182.5 288 256 288s141.5-11.1 192.3-30.2z" } }, "free": ["solid"] }, "holly-berry": { "aliases": { "unicodes": { "secondary": ["10f7aa"] } }, "changes": ["5.6.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "catwoman", "christmas", "decoration", "flora", "halle", "holiday", "ororo munroe", "plant", "storm", "xmas" ] }, "styles": ["solid"], "unicode": "f7aa", "label": "Holly Berry", "voted": false, "svg": { "solid": { "last_modified": 1684768130, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 96a48 48 0 1 0 0-96 48 48 0 1 0 0 96zm-80 96a48 48 0 1 0 0-96 48 48 0 1 0 0 96zM276.8 383.8c1 .1 2.1 .2 3.2 .2c39.8 0 72 32.2 72 72v22.7c0 16.4 16 27.9 31.6 22.8l12.8-4.3c18-6 37.3-6.5 55.6-1.5l19.4 5.3c17.9 4.9 34.4-11.6 29.5-29.5L495.6 452c-5-18.3-4.4-37.6 1.5-55.6l4.3-12.8c5.2-15.5-6.4-31.6-22.8-31.6c-34.6 0-62.7-28.1-62.7-62.7v-32c0-16.4-16-27.9-31.6-22.8l-12.8 4.3c-18 6-37.3 6.5-55.6 1.5l-29.6-8.1c-2.9-.8-5.9-1-8.7-.7c4.2 9.7 5.8 20.8 3.7 32.3L275 298.7c-1.5 8.4-1.4 17 .5 25.3l5.3 23.9c2.8 12.7 1.1 25.2-4 35.9zM127.6 234.5c-15.5-5.2-31.6 6.4-31.6 22.8v32C96 323.9 67.9 352 33.3 352c-16.4 0-27.9 16-22.8 31.6l4.3 12.8c6 18 6.5 37.3 1.5 55.6l-5.3 19.4C6.2 489.4 22.6 505.8 40.5 501L60 495.6c18.3-5 37.6-4.5 55.6 1.5l12.8 4.3c15.5 5.2 31.6-6.4 31.6-22.8v-32c0-34.6 28.1-62.7 62.7-62.7c16.4 0 27.9-16 22.8-31.6l-4.3-12.8c-6-18-6.5-37.3-1.5-55.6l5.3-19.4c4.9-17.9-11.6-34.4-29.5-29.5L196 240.4c-18.3 5-37.6 4.4-55.6-1.5l-12.8-4.3zM384 144a48 48 0 1 0 -96 0 48 48 0 1 0 96 0z" } }, "free": ["solid"] }, "hooli": { "changes": ["5.0.0", "5.7.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f427", "label": "Hooli", "voted": false, "svg": { "brands": { "last_modified": 1660014483, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M144.5 352l38.3.8c-13.2-4.6-26-10.2-38.3-16.8zm57.7-5.3v5.3l-19.4.8c36.5 12.5 69.9 14.2 94.7 7.2-19.9.2-45.8-2.6-75.3-13.3zm408.9-115.2c15.9 0 28.9-12.9 28.9-28.9s-12.9-24.5-28.9-24.5c-15.9 0-28.9 8.6-28.9 24.5s12.9 28.9 28.9 28.9zm-29 120.5H640V241.5h-57.9zm-73.7 0h57.9V156.7L508.4 184zm-31-119.4c-18.2-18.2-50.4-17.1-50.4-17.1s-32.3-1.1-50.4 17.1c-18.2 18.2-16.8 33.9-16.8 52.6s-1.4 34.3 16.8 52.5 50.4 17.1 50.4 17.1 32.3 1.1 50.4-17.1c18.2-18.2 16.8-33.8 16.8-52.5-.1-18.8 1.3-34.5-16.8-52.6zm-39.8 71.9c0 3.6-1.8 12.5-10.7 12.5s-10.7-8.9-10.7-12.5v-40.4c0-8.7 7.3-10.9 10.7-10.9s10.7 2.1 10.7 10.9zm-106.2-71.9c-18.2-18.2-50.4-17.1-50.4-17.1s-32.2-1.1-50.4 17.1c-1.9 1.9-3.7 3.9-5.3 6-38.2-29.6-72.5-46.5-102.1-61.1v-20.7l-22.5 10.6c-54.4-22.1-89-18.2-97.3.1 0 0-24.9 32.8 61.8 110.8V352h57.9v-28.6c-6.5-4.2-13-8.7-19.4-13.6-14.8-11.2-27.4-21.6-38.4-31.4v-31c13.1 14.7 30.5 31.4 53.4 50.3l4.5 3.6v-29.8c0-6.9 1.7-18.2 10.8-18.2s10.6 6.9 10.6 15V317c18 12.2 37.3 22.1 57.7 29.6v-93.9c0-18.7-13.4-37.4-40.6-37.4-15.8-.1-30.5 8.2-38.5 21.9v-54.3c41.9 20.9 83.9 46.5 99.9 58.3-10.2 14.6-9.3 28.1-9.3 43.7 0 18.7-1.4 34.3 16.8 52.5s50.4 17.1 50.4 17.1 32.3 1.1 50.4-17.1c18.2-18.2 16.7-33.8 16.7-52.5 0-18.5 1.5-34.2-16.7-52.3zM65.2 184v63.3c-48.7-54.5-38.9-76-35.2-79.1 13.5-11.4 37.5-8 64.4 2.1zm226.5 120.5c0 3.6-1.8 12.5-10.7 12.5s-10.7-8.9-10.7-12.5v-40.4c0-8.7 7.3-10.9 10.7-10.9s10.7 2.1 10.7 10.9z" } }, "free": ["brands"] }, "hornbill": { "changes": ["5.1.0", "5.8.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f592", "label": "Hornbill", "voted": false, "svg": { "brands": { "last_modified": 1660014462, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M76.38 370.3a37.8 37.8 0 1 1-32.07-32.42c-78.28-111.35 52-190.53 52-190.53-5.86 43-8.24 91.16-8.24 91.16-67.31 41.49.93 64.06 39.81 72.87a140.38 140.38 0 0 0 131.66 91.94c1.92 0 3.77-.21 5.67-.28l.11 18.86c-99.22 1.39-158.7-29.14-188.94-51.6zm108-327.7A37.57 37.57 0 0 0 181 21.45a37.95 37.95 0 1 0-31.17 54.22c-22.55 29.91-53.83 89.57-52.42 190l21.84-.15c0-.9-.14-1.77-.14-2.68A140.42 140.42 0 0 1 207 132.71c8-37.71 30.7-114.3 73.8-44.29 0 0 48.14 2.38 91.18 8.24 0 0-77.84-128-187.59-54.06zm304.19 134.17a37.94 37.94 0 1 0-53.84-28.7C403 126.13 344.89 99 251.28 100.33l.14 22.5c2.7-.15 5.39-.41 8.14-.41a140.37 140.37 0 0 1 130.49 88.76c39.1 9 105.06 31.58 38.46 72.54 0 0-2.34 48.13-8.21 91.16 0 0 133.45-81.16 49-194.61a37.45 37.45 0 0 0 19.31-3.5zM374.06 436.24c21.43-32.46 46.42-89.69 45.14-179.66l-19.52.14c.08 2.06.3 4.07.3 6.15a140.34 140.34 0 0 1-91.39 131.45c-8.85 38.95-31.44 106.66-72.77 39.49 0 0-48.12-2.34-91.19-8.22 0 0 79.92 131.34 191.9 51a37.5 37.5 0 0 0 3.64 14 37.93 37.93 0 1 0 33.89-54.29z" } }, "free": ["brands"] }, "horse": { "aliases": { "unicodes": { "composite": ["1f40e"], "secondary": ["10f6f0"] } }, "changes": ["5.4.0", "5.10.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "equestrian", "equus", "fauna", "horse", "mammmal", "mare", "neigh", "pony", "racehorse", "racing" ] }, "styles": ["solid"], "unicode": "f6f0", "label": "Horse", "voted": false, "svg": { "solid": { "last_modified": 1684768131, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M448 238.1V160h16l9.8 19.6c12.5 25.1 42.2 36.4 68.3 26c20.5-8.2 33.9-28 33.9-50.1V80c0-19.1-8.4-36.3-21.7-48H560c8.8 0 16-7.2 16-16s-7.2-16-16-16H480 448C377.3 0 320 57.3 320 128H224 203.2 148.8c-30.7 0-57.6 16.3-72.5 40.8C33.2 174.5 0 211.4 0 256v56c0 13.3 10.7 24 24 24s24-10.7 24-24V256c0-13.4 6.6-25.2 16.7-32.5c1.6 13 6.3 25.4 13.6 36.4l28.2 42.4c8.3 12.4 6.4 28.7-1.2 41.6c-16.5 28-20.6 62.2-10 93.9l17.5 52.4c4.4 13.1 16.6 21.9 30.4 21.9h33.7c21.8 0 37.3-21.4 30.4-42.1l-20.8-62.5c-2.1-6.4-.5-13.4 4.3-18.2l12.7-12.7c13.2-13.2 20.6-31.1 20.6-49.7c0-2.3-.1-4.6-.3-6.9l84 24c4.1 1.2 8.2 2.1 12.3 2.8V480c0 17.7 14.3 32 32 32h32c17.7 0 32-14.3 32-32V315.7c19.2-19.2 31.5-45.7 32-75.7h0v-1.9zM496 64a16 16 0 1 1 0 32 16 16 0 1 1 0-32z" } }, "free": ["solid"] }, "horse-head": { "aliases": { "unicodes": { "secondary": ["10f7ab"] } }, "changes": ["5.6.0", "5.10.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["equus", "fauna", "mammmal", "mare", "neigh", "pony"] }, "styles": ["solid"], "unicode": "f7ab", "label": "Horse Head", "voted": false, "svg": { "solid": { "last_modified": 1684768130, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M64 464V316.9c0-108.4 68.3-205.1 170.5-241.3L404.2 15.5C425.6 7.9 448 23.8 448 46.4c0 11-5.5 21.2-14.6 27.3L400 96c48.1 0 91.2 29.8 108.1 74.9l48.6 129.5c11.8 31.4 4.1 66.8-19.6 90.5c-16 16-37.8 25.1-60.5 25.1h-3.4c-26.1 0-50.9-11.6-67.6-31.7l-32.3-38.7c-11.7 4.1-24.2 6.4-37.3 6.4l-.1 0 0 0c-6.3 0-12.5-.5-18.6-1.5c-3.6-.6-7.2-1.4-10.7-2.3l0 0c-28.9-7.8-53.1-26.8-67.8-52.2c-4.4-7.6-14.2-10.3-21.9-5.8s-10.3 14.2-5.8 21.9c24 41.5 68.3 70 119.3 71.9l47.2 70.8c4 6.1 6.2 13.2 6.2 20.4c0 20.3-16.5 36.8-36.8 36.8H112c-26.5 0-48-21.5-48-48zM392 224a24 24 0 1 0 0-48 24 24 0 1 0 0 48z" } }, "free": ["solid"] }, "hospital": { "aliases": { "names": ["hospital-alt", "hospital-wide"], "unicodes": { "composite": ["1f3e5", "f47d"], "primary": ["f47d"], "secondary": ["10f0f8", "10f47d"] } }, "changes": [ "3.0.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "building", "covid-19", "doctor", "emergency room", "hospital", "medical center", "medicine" ] }, "styles": ["solid", "regular"], "unicode": "f0f8", "label": "Hospital", "voted": false, "svg": { "solid": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M192 48c0-26.5 21.5-48 48-48H400c26.5 0 48 21.5 48 48V512H368V432c0-26.5-21.5-48-48-48s-48 21.5-48 48v80H192V48zM48 96H160V512H48c-26.5 0-48-21.5-48-48V320H80c8.8 0 16-7.2 16-16s-7.2-16-16-16H0V224H80c8.8 0 16-7.2 16-16s-7.2-16-16-16H0V144c0-26.5 21.5-48 48-48zm544 0c26.5 0 48 21.5 48 48v48H560c-8.8 0-16 7.2-16 16s7.2 16 16 16h80v64H560c-8.8 0-16 7.2-16 16s7.2 16 16 16h80V464c0 26.5-21.5 48-48 48H480V96H592zM312 64c-8.8 0-16 7.2-16 16v24H272c-8.8 0-16 7.2-16 16v16c0 8.8 7.2 16 16 16h24v24c0 8.8 7.2 16 16 16h16c8.8 0 16-7.2 16-16V152h24c8.8 0 16-7.2 16-16V120c0-8.8-7.2-16-16-16H344V80c0-8.8-7.2-16-16-16H312z" }, "regular": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M232 0c-39.8 0-72 32.2-72 72v8H72C32.2 80 0 112.2 0 152V440c0 39.8 32.2 72 72 72h.2 .2 .2 .2 .2H73h.2 .2 .2 .2 .2 .2 .2 .2 .2 .2H75h.2 .2 .2 .2 .2 .2 .2 .2 .2 .2H77h.2 .2 .2 .2 .2 .2 .2 .2 .2 .2H79h.2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2H82h.2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2H85h.2 .2 .2 .2H86h.2 .2 .2 .2H87h.2 .2 .2 .2H88h.2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2H98h.2 .2 .2 .2H99h.2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2v0H456h8v0H568c39.8 0 72-32.2 72-72V152c0-39.8-32.2-72-72-72H480V72c0-39.8-32.2-72-72-72H232zM480 128h88c13.3 0 24 10.7 24 24v40H536c-13.3 0-24 10.7-24 24s10.7 24 24 24h56v48H536c-13.3 0-24 10.7-24 24s10.7 24 24 24h56V440c0 13.3-10.7 24-24 24H480V336 128zM72 128h88V464h-.1-.2-.2-.2H159h-.2-.2-.2H158h-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2H154h-.2-.2-.2H153h-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2H150h-.2-.2-.2H149h-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2H146h-.2-.2-.2H145h-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2H142h-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2H139h-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2H136h-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2H133h-.2-.2-.2-.2-.2-.2-.2-.2H131h-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2H128h-.2-.2-.2-.2-.2-.2-.2-.2H126h-.2-.2-.2-.2-.2-.2-.2-.2H124h-.2-.2-.2-.2-.2-.2-.2-.2H122h-.2-.2-.2-.2-.2-.2-.2-.2H120h-.2-.2-.2-.2-.2-.2-.2-.2H118h-.2-.2-.2-.2-.2-.2-.2-.2H116h-.2-.2-.2-.2-.2-.2-.2-.2H114h-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2H111h-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2H108h-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2H105h-.2-.2-.2-.2H104h-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2H100h-.2-.2-.2-.2H99h-.2-.2-.2-.2H98h-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2H88h-.2-.2-.2-.2H87h-.2-.2-.2-.2H86h-.2-.2-.2-.2H85h-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2H82h-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2H79h-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2H77h-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2H75h-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2H73h-.2-.2-.2-.2-.2H72c-13.2 0-24-10.7-24-24V336h56c13.3 0 24-10.7 24-24s-10.7-24-24-24H48V240h56c13.3 0 24-10.7 24-24s-10.7-24-24-24H48V152c0-13.3 10.7-24 24-24zM208 72c0-13.3 10.7-24 24-24H408c13.3 0 24 10.7 24 24V336 464H368V400c0-26.5-21.5-48-48-48s-48 21.5-48 48v64H208V72zm88 24v24H272c-8.8 0-16 7.2-16 16v16c0 8.8 7.2 16 16 16h24v24c0 8.8 7.2 16 16 16h16c8.8 0 16-7.2 16-16V168h24c8.8 0 16-7.2 16-16V136c0-8.8-7.2-16-16-16H344V96c0-8.8-7.2-16-16-16H312c-8.8 0-16 7.2-16 16z" } }, "free": ["regular", "solid"] }, "hospital-user": { "aliases": { "unicodes": { "secondary": ["10f80d"] } }, "changes": [ "5.7.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["covid-19", "doctor", "network", "patient", "primary care"] }, "styles": ["solid"], "unicode": "f80d", "label": "Hospital User", "voted": false, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M48 0C21.5 0 0 21.5 0 48V256H144c8.8 0 16 7.2 16 16s-7.2 16-16 16H0v64H144c8.8 0 16 7.2 16 16s-7.2 16-16 16H0v80c0 26.5 21.5 48 48 48H265.9c-6.3-10.2-9.9-22.2-9.9-35.1c0-46.9 25.8-87.8 64-109.2V271.8 48c0-26.5-21.5-48-48-48H48zM152 64h16c8.8 0 16 7.2 16 16v24h24c8.8 0 16 7.2 16 16v16c0 8.8-7.2 16-16 16H184v24c0 8.8-7.2 16-16 16H152c-8.8 0-16-7.2-16-16V152H112c-8.8 0-16-7.2-16-16V120c0-8.8 7.2-16 16-16h24V80c0-8.8 7.2-16 16-16zM512 272a80 80 0 1 0 -160 0 80 80 0 1 0 160 0zM288 477.1c0 19.3 15.6 34.9 34.9 34.9H541.1c19.3 0 34.9-15.6 34.9-34.9c0-51.4-41.7-93.1-93.1-93.1H381.1c-51.4 0-93.1 41.7-93.1 93.1z" } }, "free": ["solid"] }, "hot-tub-person": { "aliases": { "names": ["hot-tub"], "unicodes": { "secondary": ["10f593"] } }, "changes": ["5.1.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["jacuzzi", "spa"] }, "styles": ["solid"], "unicode": "f593", "label": "Hot Tub Person", "voted": false, "svg": { "solid": { "last_modified": 1684767621, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M272 24c0-13.3-10.7-24-24-24s-24 10.7-24 24v5.2c0 34 14.4 66.4 39.7 89.2l16.4 14.8c15.2 13.7 23.8 33.1 23.8 53.5V200c0 13.3 10.7 24 24 24s24-10.7 24-24V186.8c0-34-14.4-66.4-39.7-89.2L295.8 82.8C280.7 69.1 272 49.7 272 29.2V24zM0 320v16V448c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V320c0-35.3-28.7-64-64-64H277.3c-13.8 0-27.3-4.5-38.4-12.8l-85.3-64C137 166.7 116.8 160 96 160c-53 0-96 43-96 96v64zm128 16v96c0 8.8-7.2 16-16 16s-16-7.2-16-16V336c0-8.8 7.2-16 16-16s16 7.2 16 16zm80-16c8.8 0 16 7.2 16 16v96c0 8.8-7.2 16-16 16s-16-7.2-16-16V336c0-8.8 7.2-16 16-16zm112 16v96c0 8.8-7.2 16-16 16s-16-7.2-16-16V336c0-8.8 7.2-16 16-16s16 7.2 16 16zm80-16c8.8 0 16 7.2 16 16v96c0 8.8-7.2 16-16 16s-16-7.2-16-16V336c0-8.8 7.2-16 16-16zM360 0c-13.3 0-24 10.7-24 24v5.2c0 34 14.4 66.4 39.7 89.2l16.4 14.8c15.2 13.7 23.8 33.1 23.8 53.5V200c0 13.3 10.7 24 24 24s24-10.7 24-24V186.8c0-34-14.4-66.4-39.7-89.2L407.8 82.8C392.7 69.1 384 49.7 384 29.2V24c0-13.3-10.7-24-24-24zM64 128A64 64 0 1 0 64 0a64 64 0 1 0 0 128z" } }, "free": ["solid"] }, "hotdog": { "aliases": { "unicodes": { "composite": ["1f32d"], "secondary": ["10f80f"] } }, "changes": ["5.7.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "bun", "chili", "frankfurt", "frankfurter", "hot dog", "hotdog", "kosher", "polish", "sandwich", "sausage", "vienna", "weiner" ] }, "styles": ["solid"], "unicode": "f80f", "label": "Hotdog", "voted": false, "svg": { "solid": { "last_modified": 1684767419, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M488.6 23.4c31.2 31.2 31.2 81.9 0 113.1l-352 352c-31.2 31.2-81.9 31.2-113.1 0s-31.2-81.9 0-113.1l352-352c31.2-31.2 81.9-31.2 113.1 0zM443.3 92.7c-6.2-6.2-16.4-6.2-22.6 0c-12.5 12.5-23.8 15.1-37.5 17.6l-2.5 .4c-13.8 2.5-31.6 5.6-48 22c-16.7 16.7-20.9 36-24.1 50.9l0 0v0l-.2 1c-3.4 15.6-6 26.4-15.7 36.1s-20.5 12.3-36.1 15.7l-1 .2c-14.9 3.2-34.2 7.4-50.9 24.1s-20.9 36-24.1 50.9l-.2 1c-3.4 15.6-6 26.4-15.7 36.1c-9.2 9.2-18 10.8-32.7 13.4l0 0-.9 .2c-15.6 2.8-34.9 6.9-54.4 26.4c-6.2 6.2-6.2 16.4 0 22.6s16.4 6.2 22.6 0c12.5-12.5 23.8-15.1 37.5-17.6l2.5-.4c13.8-2.5 31.6-5.6 48-22c16.7-16.7 20.9-36 24.1-50.9l.2-1c3.4-15.6 6-26.4 15.7-36.1s20.5-12.3 36.1-15.7l1-.2c14.9-3.2 34.2-7.4 50.9-24.1s20.9-36 24.1-50.9l.2-1c3.4-15.6 6-26.4 15.7-36.1c9.2-9.2 18-10.8 32.7-13.4l.9-.2c15.6-2.8 34.9-6.9 54.4-26.4c6.2-6.2 6.2-16.4 0-22.6zM191.2 479.2l288-288L495 207c10.9 10.9 17 25.6 17 41s-6.1 30.1-17 41L289 495c-10.9 10.9-25.6 17-41 17s-30.1-6.1-41-17l-15.8-15.8zM17 305C6.1 294.1 0 279.4 0 264s6.1-30.1 17-41L223 17C233.9 6.1 248.6 0 264 0s30.1 6.1 41 17l15.8 15.8-288 288L17 305z" } }, "free": ["solid"] }, "hotel": { "aliases": { "unicodes": { "composite": ["1f3e8"], "secondary": ["10f594"] } }, "changes": [ "5.1.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "building", "hotel", "inn", "lodging", "motel", "resort", "travel" ] }, "styles": ["solid"], "unicode": "f594", "label": "Hotel", "voted": false, "svg": { "solid": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 32C0 14.3 14.3 0 32 0H480c17.7 0 32 14.3 32 32s-14.3 32-32 32V448c17.7 0 32 14.3 32 32s-14.3 32-32 32H304V464c0-26.5-21.5-48-48-48s-48 21.5-48 48v48H32c-17.7 0-32-14.3-32-32s14.3-32 32-32V64C14.3 64 0 49.7 0 32zm96 80v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V112c0-8.8-7.2-16-16-16H112c-8.8 0-16 7.2-16 16zM240 96c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V112c0-8.8-7.2-16-16-16H240zm112 16v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V112c0-8.8-7.2-16-16-16H368c-8.8 0-16 7.2-16 16zM112 192c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V208c0-8.8-7.2-16-16-16H112zm112 16v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V208c0-8.8-7.2-16-16-16H240c-8.8 0-16 7.2-16 16zm144-16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V208c0-8.8-7.2-16-16-16H368zM328 384c13.3 0 24.3-10.9 21-23.8c-10.6-41.5-48.2-72.2-93-72.2s-82.5 30.7-93 72.2c-3.3 12.8 7.8 23.8 21 23.8H328z" } }, "free": ["solid"] }, "hotjar": { "changes": ["5.0.0", "6.4.1"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3b1", "label": "Hotjar", "voted": false, "svg": { "brands": { "last_modified": 1688044785, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M361.5 0c0 131.6-80.7 176.8-140.2 209.4c-.6 .3-1.1 .6-1.6 .9c-53.8 30.2-88.7 49.8-89.6 122H32C32 200.8 112.7 155.6 172.2 123C227 93.2 262.5 73 262.5 0h98.9zM301 302.6c54.8-29.8 90.3-50 90.3-123h98c0 131.6-80.7 176.7-140.2 209.4c-54.8 29.8-90.3 50-90.3 123h-98c0-131.6 80.7-176.8 140.2-209.4z" } }, "free": ["brands"] }, "hourglass": { "aliases": { "names": ["hourglass-empty"], "unicodes": { "composite": ["23f3", "f250"], "secondary": ["10f254"] } }, "changes": [ "4.4.0", "5.0.0", "5.10.1", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.1.2", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "hour", "hourglass", "hourglass not done", "minute", "sand", "stopwatch", "time", "timer" ] }, "styles": ["solid", "regular"], "unicode": "f254", "label": "Hourglass", "voted": false, "svg": { "solid": { "last_modified": 1684767327, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M0 32C0 14.3 14.3 0 32 0H64 320h32c17.7 0 32 14.3 32 32s-14.3 32-32 32V75c0 42.4-16.9 83.1-46.9 113.1L237.3 256l67.9 67.9c30 30 46.9 70.7 46.9 113.1v11c17.7 0 32 14.3 32 32s-14.3 32-32 32H320 64 32c-17.7 0-32-14.3-32-32s14.3-32 32-32V437c0-42.4 16.9-83.1 46.9-113.1L146.7 256 78.9 188.1C48.9 158.1 32 117.4 32 75V64C14.3 64 0 49.7 0 32zM96 64V75c0 25.5 10.1 49.9 28.1 67.9L192 210.7l67.9-67.9c18-18 28.1-42.4 28.1-67.9V64H96zm0 384H288V437c0-25.5-10.1-49.9-28.1-67.9L192 301.3l-67.9 67.9c-18 18-28.1 42.4-28.1 67.9v11z" }, "regular": { "last_modified": 1684767327, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M24 0C10.7 0 0 10.7 0 24S10.7 48 24 48h8V67c0 40.3 16 79 44.5 107.5L158.1 256 76.5 337.5C48 366 32 404.7 32 445v19H24c-13.3 0-24 10.7-24 24s10.7 24 24 24H360c13.3 0 24-10.7 24-24s-10.7-24-24-24h-8V445c0-40.3-16-79-44.5-107.5L225.9 256l81.5-81.5C336 146 352 107.3 352 67V48h8c13.3 0 24-10.7 24-24s-10.7-24-24-24H24zM192 289.9l81.5 81.5C293 391 304 417.4 304 445v19H80V445c0-27.6 11-54 30.5-73.5L192 289.9zm0-67.9l-81.5-81.5C91 121 80 94.6 80 67V48H304V67c0 27.6-11 54-30.5 73.5L192 222.1z" } }, "free": ["regular", "solid"] }, "hourglass-end": { "aliases": { "names": ["hourglass-3"], "unicodes": { "composite": ["231b"], "secondary": ["10f253"] } }, "changes": [ "4.4.0", "5.0.0", "5.10.1", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "hour", "hourglass done", "minute", "sand", "stopwatch", "time", "timer" ] }, "styles": ["solid"], "unicode": "f253", "label": "Hourglass End", "voted": false, "svg": { "solid": { "last_modified": 1684767328, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M32 0C14.3 0 0 14.3 0 32S14.3 64 32 64V75c0 42.4 16.9 83.1 46.9 113.1L146.7 256 78.9 323.9C48.9 353.9 32 394.6 32 437v11c-17.7 0-32 14.3-32 32s14.3 32 32 32H64 320h32c17.7 0 32-14.3 32-32s-14.3-32-32-32V437c0-42.4-16.9-83.1-46.9-113.1L237.3 256l67.9-67.9c30-30 46.9-70.7 46.9-113.1V64c17.7 0 32-14.3 32-32s-14.3-32-32-32H320 64 32zM96 75V64H288V75c0 25.5-10.1 49.9-28.1 67.9L192 210.7l-67.9-67.9C106.1 124.9 96 100.4 96 75z" } }, "free": ["solid"] }, "hourglass-half": { "aliases": { "names": ["hourglass-2"], "unicodes": { "secondary": ["10f252"] } }, "changes": [ "4.4.0", "5.0.0", "5.10.1", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.1.2", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["hour", "minute", "sand", "stopwatch", "time"] }, "styles": ["solid", "regular"], "unicode": "f252", "label": "Hourglass Half", "voted": false, "svg": { "solid": { "last_modified": 1684767328, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M32 0C14.3 0 0 14.3 0 32S14.3 64 32 64V75c0 42.4 16.9 83.1 46.9 113.1L146.7 256 78.9 323.9C48.9 353.9 32 394.6 32 437v11c-17.7 0-32 14.3-32 32s14.3 32 32 32H64 320h32c17.7 0 32-14.3 32-32s-14.3-32-32-32V437c0-42.4-16.9-83.1-46.9-113.1L237.3 256l67.9-67.9c30-30 46.9-70.7 46.9-113.1V64c17.7 0 32-14.3 32-32s-14.3-32-32-32H320 64 32zM96 75V64H288V75c0 19-5.6 37.4-16 53H112c-10.3-15.6-16-34-16-53zm16 309c3.5-5.3 7.6-10.3 12.1-14.9L192 301.3l67.9 67.9c4.6 4.6 8.6 9.6 12.1 14.9H112z" }, "regular": { "last_modified": 1684767328, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M0 24C0 10.7 10.7 0 24 0H360c13.3 0 24 10.7 24 24s-10.7 24-24 24h-8V67c0 40.3-16 79-44.5 107.5L225.9 256l81.5 81.5C336 366 352 404.7 352 445v19h8c13.3 0 24 10.7 24 24s-10.7 24-24 24H24c-13.3 0-24-10.7-24-24s10.7-24 24-24h8V445c0-40.3 16-79 44.5-107.5L158.1 256 76.5 174.5C48 146 32 107.3 32 67V48H24C10.7 48 0 37.3 0 24zM110.5 371.5c-3.9 3.9-7.5 8.1-10.7 12.5H284.2c-3.2-4.4-6.8-8.6-10.7-12.5L192 289.9l-81.5 81.5zM284.2 128C297 110.4 304 89 304 67V48H80V67c0 22.1 7 43.4 19.8 61H284.2z" } }, "free": ["regular", "solid"] }, "hourglass-start": { "aliases": { "names": ["hourglass-1"], "unicodes": { "secondary": ["10f251"] } }, "changes": [ "4.4.0", "5.0.0", "5.10.1", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["hour", "minute", "sand", "stopwatch", "time"] }, "styles": ["solid"], "unicode": "f251", "label": "Hourglass Start", "voted": false, "svg": { "solid": { "last_modified": 1684767328, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M32 0C14.3 0 0 14.3 0 32S14.3 64 32 64V75c0 42.4 16.9 83.1 46.9 113.1L146.7 256 78.9 323.9C48.9 353.9 32 394.6 32 437v11c-17.7 0-32 14.3-32 32s14.3 32 32 32H64 320h32c17.7 0 32-14.3 32-32s-14.3-32-32-32V437c0-42.4-16.9-83.1-46.9-113.1L237.3 256l67.9-67.9c30-30 46.9-70.7 46.9-113.1V64c17.7 0 32-14.3 32-32s-14.3-32-32-32H320 64 32zM288 437v11H96V437c0-25.5 10.1-49.9 28.1-67.9L192 301.3l67.9 67.9c18 18 28.1 42.4 28.1 67.9z" } }, "free": ["solid"] }, "house": { "aliases": { "names": ["home", "home-alt", "home-lg-alt"], "unicodes": { "composite": ["1f3e0", "f80a", "f80c"], "primary": ["f80a", "f80c"], "secondary": ["10f015", "10f80a", "10f80c"] } }, "changes": [ "1.0.0", "5.0.0", "5.7.0", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.1.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["abode", "building", "home", "house", "main", "residence"] }, "styles": ["solid"], "unicode": "f015", "label": "House", "voted": false, "svg": { "solid": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M575.8 255.5c0 18-15 32.1-32 32.1h-32l.7 160.2c0 2.7-.2 5.4-.5 8.1V472c0 22.1-17.9 40-40 40H456c-1.1 0-2.2 0-3.3-.1c-1.4 .1-2.8 .1-4.2 .1H416 392c-22.1 0-40-17.9-40-40V448 384c0-17.7-14.3-32-32-32H256c-17.7 0-32 14.3-32 32v64 24c0 22.1-17.9 40-40 40H160 128.1c-1.5 0-3-.1-4.5-.2c-1.2 .1-2.4 .2-3.6 .2H104c-22.1 0-40-17.9-40-40V360c0-.9 0-1.9 .1-2.8V287.6H32c-18 0-32-14-32-32.1c0-9 3-17 10-24L266.4 8c7-7 15-8 22-8s15 2 21 7L564.8 231.5c8 7 12 15 11 24z" } }, "free": ["solid"] }, "house-chimney": { "aliases": { "names": ["home-lg"], "unicodes": { "composite": ["f80b"], "primary": ["f80b"], "secondary": ["10f80b"] } }, "changes": [ "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "abode", "building", "chimney", "house", "main", "residence", "smokestack" ] }, "styles": ["solid"], "unicode": "e3af", "label": "House Chimney", "voted": false, "svg": { "solid": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M543.8 287.6c17 0 32-14 32-32.1c1-9-3-17-11-24L512 185V64c0-17.7-14.3-32-32-32H448c-17.7 0-32 14.3-32 32v36.7L309.5 7c-6-5-14-7-21-7s-15 1-22 8L10 231.5c-7 7-10 15-10 24c0 18 14 32.1 32 32.1h32v69.7c-.1 .9-.1 1.8-.1 2.8V472c0 22.1 17.9 40 40 40h16c1.2 0 2.4-.1 3.6-.2c1.5 .1 3 .2 4.5 .2H160h24c22.1 0 40-17.9 40-40V448 384c0-17.7 14.3-32 32-32h64c17.7 0 32 14.3 32 32v64 24c0 22.1 17.9 40 40 40h24 32.5c1.4 0 2.8 0 4.2-.1c1.1 .1 2.2 .1 3.3 .1h16c22.1 0 40-17.9 40-40V455.8c.3-2.6 .5-5.3 .5-8.1l-.7-160.2h32z" } }, "free": ["solid"] }, "house-chimney-crack": { "aliases": { "names": ["house-damage"], "unicodes": { "secondary": ["10f6f1"] } }, "changes": [ "5.4.0", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "building", "devastation", "disaster", "earthquake", "home", "insurance" ] }, "styles": ["solid"], "unicode": "f6f1", "label": "House Chimney Crack", "voted": false, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M575.8 255.5c0 18-15 32.1-32 32.1h-32l.7 160.2c.2 35.5-28.5 64.3-64 64.3H326.4L288 448l80.8-67.3c7.8-6.5 7.6-18.6-.4-24.9L250.6 263.2c-14.6-11.5-33.8 7-22.8 22L288 368l-85.5 71.2c-6.1 5-7.5 13.8-3.5 20.5L230.4 512H128.1c-35.3 0-64-28.7-64-64V287.6H32c-18 0-32-14-32-32.1c0-9 3-17 10-24L266.4 8c7-7 15-8 22-8s15 2 21 7L416 100.7V64c0-17.7 14.3-32 32-32h32c17.7 0 32 14.3 32 32V185l52.8 46.4c8 7 12 15 11 24z" } }, "free": ["solid"] }, "house-chimney-medical": { "aliases": { "names": ["clinic-medical"], "unicodes": { "secondary": ["10f7f2"] } }, "changes": [ "5.7.0", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "covid-19", "doctor", "general practitioner", "hospital", "infirmary", "medicine", "office", "outpatient" ] }, "styles": ["solid"], "unicode": "f7f2", "label": "House Chimney Medical", "voted": false, "svg": { "solid": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M575.8 255.5c0 18-15 32.1-32 32.1h-32l.7 160.2c.2 35.5-28.5 64.3-64 64.3H128.1c-35.3 0-64-28.7-64-64V287.6H32c-18 0-32-14-32-32.1c0-9 3-17 10-24L266.4 8c7-7 15-8 22-8s15 2 21 7L416 100.7V64c0-17.7 14.3-32 32-32h32c17.7 0 32 14.3 32 32V185l52.8 46.4c8 7 12 15 11 24zM272 192c-8.8 0-16 7.2-16 16v48H208c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h48v48c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V320h48c8.8 0 16-7.2 16-16V272c0-8.8-7.2-16-16-16H320V208c0-8.8-7.2-16-16-16H272z" } }, "free": ["solid"] }, "house-chimney-user": { "aliases": { "unicodes": { "secondary": ["10e065"] } }, "changes": [ "5.13.0", "5.14.0", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.1.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["covid-19", "home", "isolation", "quarantine"] }, "styles": ["solid"], "unicode": "e065", "label": "House Chimney User", "voted": false, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M543.8 287.6c17 0 32-14 32-32.1c1-9-3-17-11-24L512 185V64c0-17.7-14.3-32-32-32H448c-17.7 0-32 14.3-32 32v36.7L309.5 7c-6-5-14-7-21-7s-15 1-22 8L10 231.5c-7 7-10 15-10 24c0 18 14 32.1 32 32.1h32V448c0 35.3 28.7 64 64 64H448.5c35.5 0 64.2-28.8 64-64.3l-.7-160.2h32zM288 160a64 64 0 1 1 0 128 64 64 0 1 1 0-128zM176 400c0-44.2 35.8-80 80-80h64c44.2 0 80 35.8 80 80c0 8.8-7.2 16-16 16H192c-8.8 0-16-7.2-16-16z" } }, "free": ["solid"] }, "house-chimney-window": { "aliases": { "unicodes": { "secondary": ["10e00d"] } }, "changes": [ "5.12.0", "5.14.0", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["abode", "building", "family", "home", "residence"] }, "styles": ["solid"], "unicode": "e00d", "label": "House Chimney Window", "voted": false, "svg": { "solid": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M575.8 255.5c0 18-15 32.1-32 32.1h-32l.7 160.2c.2 35.5-28.5 64.3-64 64.3H128.1c-35.3 0-64-28.7-64-64V287.6H32c-18 0-32-14-32-32.1c0-9 3-17 10-24L266.4 8c7-7 15-8 22-8s15 2 21 7L416 100.7V64c0-17.7 14.3-32 32-32h32c17.7 0 32 14.3 32 32V185l52.8 46.4c8 7 12 15 11 24zM248 192c-13.3 0-24 10.7-24 24v80c0 13.3 10.7 24 24 24h80c13.3 0 24-10.7 24-24V216c0-13.3-10.7-24-24-24H248z" } }, "free": ["solid"] }, "house-circle-check": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["abode", "home", "house", "not affected", "ok", "okay"] }, "styles": ["solid"], "unicode": "e509", "label": "House Circle Check", "voted": false, "svg": { "solid": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M320.7 352c8.1-89.7 83.5-160 175.3-160c8.9 0 17.6 .7 26.1 1.9L309.5 7c-6-5-14-7-21-7s-15 1-22 8L10 231.5c-7 7-10 15-10 24c0 18 14 32.1 32 32.1h32v69.7c-.1 .9-.1 1.8-.1 2.8V472c0 22.1 17.9 40 40 40h16c1.2 0 2.4-.1 3.6-.2c1.5 .1 3 .2 4.5 .2H160h24c22.1 0 40-17.9 40-40V448 384c0-17.7 14.3-32 32-32h64l.7 0zM640 368a144 144 0 1 0 -288 0 144 144 0 1 0 288 0zm-76.7-43.3c6.2 6.2 6.2 16.4 0 22.6l-72 72c-6.2 6.2-16.4 6.2-22.6 0l-40-40c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0L480 385.4l60.7-60.7c6.2-6.2 16.4-6.2 22.6 0z" } }, "free": ["solid"] }, "house-circle-exclamation": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["abode", "affected", "home", "house"] }, "styles": ["solid"], "unicode": "e50a", "label": "House Circle Exclamation", "voted": false, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M320.7 352c8.1-89.7 83.5-160 175.3-160c8.9 0 17.6 .7 26.1 1.9L309.5 7c-6-5-14-7-21-7s-15 1-22 8L10 231.5c-7 7-10 15-10 24c0 18 14 32.1 32 32.1h32v69.7c-.1 .9-.1 1.8-.1 2.8V472c0 22.1 17.9 40 40 40h16c1.2 0 2.4-.1 3.6-.2c1.5 .1 3 .2 4.5 .2H160h24c22.1 0 40-17.9 40-40V448 384c0-17.7 14.3-32 32-32h64l.7 0zM496 512a144 144 0 1 0 0-288 144 144 0 1 0 0 288zm0-96a24 24 0 1 1 0 48 24 24 0 1 1 0-48zm0-144c8.8 0 16 7.2 16 16v80c0 8.8-7.2 16-16 16s-16-7.2-16-16V288c0-8.8 7.2-16 16-16z" } }, "free": ["solid"] }, "house-circle-xmark": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["abode", "destroy", "home", "house"] }, "styles": ["solid"], "unicode": "e50b", "label": "House Circle Xmark", "voted": false, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M320.7 352c8.1-89.7 83.5-160 175.3-160c8.9 0 17.6 .7 26.1 1.9L309.5 7c-6-5-14-7-21-7s-15 1-22 8L10 231.5c-7 7-10 15-10 24c0 18 14 32.1 32 32.1h32v69.7c-.1 .9-.1 1.8-.1 2.8V472c0 22.1 17.9 40 40 40h16c1.2 0 2.4-.1 3.6-.2c1.5 .1 3 .2 4.5 .2H160h24c22.1 0 40-17.9 40-40V448 384c0-17.7 14.3-32 32-32h64l.7 0zM496 512a144 144 0 1 0 0-288 144 144 0 1 0 0 288zm59.3-180.7L518.6 368l36.7 36.7c6.2 6.2 6.2 16.4 0 22.6s-16.4 6.2-22.6 0L496 390.6l-36.7 36.7c-6.2 6.2-16.4 6.2-22.6 0s-6.2-16.4 0-22.6L473.4 368l-36.7-36.7c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0L496 345.4l36.7-36.7c6.2-6.2 16.4-6.2 22.6 0s6.2 16.4 0 22.6z" } }, "free": ["solid"] }, "house-crack": { "changes": [ "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "building", "devastation", "disaster", "earthquake", "home", "insurance" ] }, "styles": ["solid"], "unicode": "e3b1", "label": "House Crack", "voted": false, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M543.8 287.6c17 0 32-14 32-32.1c1-9-3-17-11-24L309.5 7c-6-5-14-7-21-7s-15 1-22 8L10 231.5c-7 7-10 15-10 24c0 18 14 32.1 32 32.1h32V448c0 35.3 28.7 64 64 64H230.4l-31.3-52.2c-4.1-6.8-2.6-15.5 3.5-20.5L288 368l-60.2-82.8c-10.9-15 8.2-33.5 22.8-22l117.9 92.6c8 6.3 8.2 18.4 .4 24.9L288 448l38.4 64H448.5c35.5 0 64.2-28.8 64-64.3l-.7-160.2h32z" } }, "free": ["solid"] }, "house-fire": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["burn", "emergency", "home"] }, "styles": ["solid"], "unicode": "e50c", "label": "House Fire", "voted": false, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M288 350.1l0 1.9H256c-17.7 0-32 14.3-32 32v64 24c0 22.1-17.9 40-40 40H160 128.1c-1.5 0-3-.1-4.5-.2c-1.2 .1-2.4 .2-3.6 .2H104c-22.1 0-40-17.9-40-40V360c0-.9 0-1.9 .1-2.8V287.6H32c-18 0-32-14-32-32.1c0-9 3-17 10-24L266.4 8c7-7 15-8 22-8s15 2 21 7L447.3 128.1c-12.3-1-25 3-34.8 11.7c-35.4 31.6-65.6 67.7-87.3 102.8C304.3 276.5 288 314.9 288 350.1zM453.5 163.8c19.7 17.8 38.2 37 55.5 57.7c7.9-9.9 16.8-20.7 26.5-29.5c5.6-5.1 14.4-5.1 20 0c24.7 22.7 45.6 52.7 60.4 81.1c14.5 28 24.2 58.8 24.2 79C640 440 568.7 512 480 512c-89.7 0-160-72.1-160-159.8c0-26.4 12.7-60.7 32.4-92.6c20-32.4 48.1-66.1 81.4-95.8c2.8-2.5 6.4-3.8 10-3.7c3.5 0 7 1.3 9.8 3.8zM530 433c30-21 38-63 20-96c-2-4-4-8-7-12l-36 42s-58-74-62-79c-30 37-45 58-45 82c0 49 36 78 81 78c18 0 34-5 49-15z" } }, "free": ["solid"] }, "house-flag": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["camp", "home"] }, "styles": ["solid"], "unicode": "e50d", "label": "House Flag", "voted": false, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M480 0c-17.7 0-32 14.3-32 32V192 512h64V192H624c8.8 0 16-7.2 16-16V48c0-8.8-7.2-16-16-16H512c0-17.7-14.3-32-32-32zM416 159L276.8 39.7c-12-10.3-29.7-10.3-41.7 0l-224 192C1 240.4-2.7 254.5 2 267.1S18.6 288 32 288H64V480c0 17.7 14.3 32 32 32h64c17.7 0 32-14.3 32-32V384c0-17.7 14.3-32 32-32h64c17.7 0 32 14.3 32 32v96c0 17.7 14.3 32 32 32h64.7l.2 0h-1V159z" } }, "free": ["solid"] }, "house-flood-water": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["damage", "flood", "water"] }, "styles": ["solid"], "unicode": "e50e", "label": "House Flood Water", "voted": false, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M306.8 6.1C295.6-2 280.4-2 269.2 6.1l-176 128c-11.2 8.2-15.9 22.6-11.6 35.8S98.1 192 112 192h16v73c1.7 1 3.3 2 4.9 3.1c18 12.4 40.1 20.3 59.2 20.3c21.1 0 42-8.5 59.2-20.3c22.1-15.5 51.6-15.5 73.7 0c18.4 12.7 39.6 20.3 59.2 20.3c19 0 41.2-7.9 59.2-20.3c1.5-1 3-2 4.5-2.9l-.3-73.2H464c13.9 0 26.1-8.9 30.4-22.1s-.4-27.6-11.6-35.8l-176-128zM269.5 309.9C247 325.4 219.5 336 192 336c-26.9 0-55.3-10.8-77.4-26.1l0 0c-11.9-8.5-28.1-7.8-39.2 1.7c-14.4 11.9-32.5 21-50.6 25.2c-17.2 4-27.9 21.2-23.9 38.4s21.2 27.9 38.4 23.9c24.5-5.7 44.9-16.5 58.2-25C126.5 389.7 159 400 192 400c31.9 0 60.6-9.9 80.4-18.9c5.8-2.7 11.1-5.3 15.6-7.7c4.5 2.4 9.7 5.1 15.6 7.7c19.8 9 48.5 18.9 80.4 18.9c33 0 65.5-10.3 94.5-25.8c13.4 8.4 33.7 19.3 58.2 25c17.2 4 34.4-6.7 38.4-23.9s-6.7-34.4-23.9-38.4c-18.1-4.2-36.2-13.3-50.6-25.2c-11.1-9.5-27.3-10.1-39.2-1.7l0 0C439.4 325.2 410.9 336 384 336c-27.5 0-55-10.6-77.5-26.1c-11.1-7.9-25.9-7.9-37 0zM384 448c-27.5 0-55-10.6-77.5-26.1c-11.1-7.9-25.9-7.9-37 0C247 437.4 219.5 448 192 448c-26.9 0-55.3-10.8-77.4-26.1l0 0c-11.9-8.5-28.1-7.8-39.2 1.7c-14.4 11.9-32.5 21-50.6 25.2c-17.2 4-27.9 21.2-23.9 38.4s21.2 27.9 38.4 23.9c24.5-5.7 44.9-16.5 58.2-25C126.5 501.7 159 512 192 512c31.9 0 60.6-9.9 80.4-18.9c5.8-2.7 11.1-5.3 15.6-7.7c4.5 2.4 9.7 5.1 15.6 7.7c19.8 9 48.5 18.9 80.4 18.9c33 0 65.5-10.3 94.5-25.8c13.4 8.4 33.7 19.3 58.2 25c17.2 4 34.4-6.7 38.4-23.9s-6.7-34.4-23.9-38.4c-18.1-4.2-36.2-13.3-50.6-25.2c-11.1-9.4-27.3-10.1-39.2-1.7l0 0C439.4 437.2 410.9 448 384 448z" } }, "free": ["solid"] }, "house-flood-water-circle-arrow-right": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["damage", "flood", "water"] }, "styles": ["solid"], "unicode": "e50f", "label": "House Flood Water Circle Arrow Right", "voted": false, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M288 144A144 144 0 1 0 0 144a144 144 0 1 0 288 0zM140.7 76.7c6.2-6.2 16.4-6.2 22.6 0l56 56c6.2 6.2 6.2 16.4 0 22.6l-56 56c-6.2 6.2-16.4 6.2-22.6 0s-6.2-16.4 0-22.6L169.4 160H80c-8.8 0-16-7.2-16-16s7.2-16 16-16h89.4L140.7 99.3c-6.2-6.2-6.2-16.4 0-22.6zM320 144c0 57.3-27.4 108.2-69.8 140.3c11.8-3.6 23-9.4 33-16.2c22.1-15.5 51.6-15.5 73.7 0c18.4 12.7 39.6 20.3 59.2 20.3c19 0 41.2-7.9 59.2-20.3c23.8-16.7 55.8-15.4 78.1 3.4c2.1 1.7 4.2 3.3 6.5 4.9l-.3-84.4H576c13.9 0 26.1-8.9 30.4-22.1s-.4-27.6-11.6-35.8l-176-128C407.6-2 392.4-2 381.2 6.1L301 64.4c12.1 23.9 19 50.9 19 79.6zm18.5 165.9c-11.1-7.9-25.9-7.9-37 0C279 325.4 251.5 336 224 336c-26.9 0-55.3-10.8-77.4-26.1l0 0c-11.9-8.5-28.1-7.8-39.2 1.7c-14.4 11.9-32.5 21-50.6 25.2c-17.2 4-27.9 21.2-23.9 38.4s21.2 27.9 38.4 23.9c24.5-5.7 44.9-16.5 58.2-25C158.5 389.7 191 400 224 400c31.9 0 60.6-9.9 80.4-18.9c5.8-2.7 11.1-5.3 15.6-7.7c4.5 2.4 9.7 5.1 15.6 7.7c19.8 9 48.6 18.9 80.4 18.9c33 0 65.5-10.3 94.5-25.8c13.4 8.4 33.7 19.3 58.2 25c17.2 4 34.4-6.7 38.4-23.9s-6.7-34.4-23.9-38.4c-18.1-4.2-36.2-13.3-50.6-25.2c-11.1-9.5-27.3-10.1-39.2-1.7l0 0C471.4 325.2 442.9 336 416 336c-27.5 0-55-10.6-77.5-26.1zm0 112c-11.1-7.9-25.9-7.9-37 0C279 437.4 251.5 448 224 448c-26.9 0-55.3-10.8-77.4-26.1l0 0c-11.9-8.5-28.1-7.8-39.2 1.7c-14.4 11.9-32.5 21-50.6 25.2c-17.2 4-27.9 21.2-23.9 38.4s21.2 27.9 38.4 23.9c24.5-5.7 44.9-16.5 58.2-25C158.5 501.7 191 512 224 512c31.9 0 60.6-9.9 80.4-18.9c5.8-2.7 11.1-5.3 15.6-7.7c4.5 2.4 9.7 5.1 15.6 7.7c19.8 9 48.6 18.9 80.4 18.9c33 0 65.5-10.3 94.5-25.8c13.4 8.4 33.7 19.3 58.2 25c17.2 4 34.4-6.7 38.4-23.9s-6.7-34.4-23.9-38.4c-18.1-4.2-36.2-13.3-50.6-25.2c-11.1-9.4-27.3-10.1-39.2-1.7l0 0C471.4 437.2 442.9 448 416 448c-27.5 0-55-10.6-77.5-26.1z" } }, "free": ["solid"] }, "house-laptop": { "aliases": { "names": ["laptop-house"], "unicodes": { "secondary": ["10e066"] } }, "changes": [ "5.13.0", "5.14.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "computer", "covid-19", "device", "office", "remote", "work from home" ] }, "styles": ["solid"], "unicode": "e066", "label": "House Laptop", "voted": false, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M218.3 8.5c12.3-11.3 31.2-11.3 43.4 0l208 192c6.7 6.2 10.3 14.8 10.3 23.5H336c-19.1 0-36.3 8.4-48 21.7V208c0-8.8-7.2-16-16-16H208c-8.8 0-16 7.2-16 16v64c0 8.8 7.2 16 16 16h64V416H112c-26.5 0-48-21.5-48-48V256H32c-13.2 0-25-8.1-29.8-20.3s-1.6-26.2 8.1-35.2l208-192zM352 304V448H544V304H352zm-48-16c0-17.7 14.3-32 32-32H560c17.7 0 32 14.3 32 32V448h32c8.8 0 16 7.2 16 16c0 26.5-21.5 48-48 48H544 352 304c-26.5 0-48-21.5-48-48c0-8.8 7.2-16 16-16h32V288z" } }, "free": ["solid"] }, "house-lock": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["closed", "home", "house", "lockdown", "quarantine"] }, "styles": ["solid"], "unicode": "e510", "label": "House Lock", "voted": false, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M384 480c0 11.7 3.1 22.6 8.6 32H392c-22.1 0-40-17.9-40-40V448 384c0-17.7-14.3-32-32-32H256c-17.7 0-32 14.3-32 32v64 24c0 22.1-17.9 40-40 40H160 128.1c-1.5 0-3-.1-4.5-.2c-1.2 .1-2.4 .2-3.6 .2H104c-22.1 0-40-17.9-40-40V360c0-.9 0-1.9 .1-2.8V287.6H32c-18 0-32-14-32-32.1c0-9 3-17 10-24L266.4 8c7-7 15-8 22-8s15 2 21 7L490.7 166.3C447.2 181.7 416 223.2 416 272v24.6c-19.1 11.1-32 31.7-32 55.4V480zM528 240c-17.7 0-32 14.3-32 32v48h64V272c0-17.7-14.3-32-32-32zm-80 32c0-44.2 35.8-80 80-80s80 35.8 80 80v48c17.7 0 32 14.3 32 32V480c0 17.7-14.3 32-32 32H448c-17.7 0-32-14.3-32-32V352c0-17.7 14.3-32 32-32V272z" } }, "free": ["solid"] }, "house-medical": { "changes": [ "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.1.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "covid-19", "doctor", "facility", "general practitioner", "health", "hospital", "infirmary", "medicine", "office", "outpatient" ] }, "styles": ["solid"], "unicode": "e3b2", "label": "House Medical", "voted": false, "svg": { "solid": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M543.8 287.6c17 0 32-14 32-32.1c1-9-3-17-11-24L309.5 7c-6-5-14-7-21-7s-15 1-22 8L10 231.5c-7 7-10 15-10 24c0 18 14 32.1 32 32.1h32V448c0 35.3 28.7 64 64 64H448.5c35.5 0 64.2-28.8 64-64.3l-.7-160.2h32zM256 208c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v48h48c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H320v48c0 8.8-7.2 16-16 16H272c-8.8 0-16-7.2-16-16V320H208c-8.8 0-16-7.2-16-16V272c0-8.8 7.2-16 16-16h48V208z" } }, "free": ["solid"] }, "house-medical-circle-check": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["clinic", "hospital", "not affected", "ok", "okay"] }, "styles": ["solid"], "unicode": "e511", "label": "House Medical Circle Check", "voted": false, "svg": { "solid": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M320 368c0 59.5 29.5 112.1 74.8 144H128.1c-35.3 0-64-28.7-64-64V287.6H32c-18 0-32-14-32-32.1c0-9 3-17 10-24L266.4 8c7-7 15-8 22-8s15 2 21 7L522.1 193.9c-8.5-1.3-17.3-1.9-26.1-1.9c-54.7 0-103.5 24.9-135.8 64H320V208c0-8.8-7.2-16-16-16H272c-8.8 0-16 7.2-16 16v48H208c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h48v48c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16zm32 0a144 144 0 1 1 288 0 144 144 0 1 1 -288 0zm211.3-43.3c-6.2-6.2-16.4-6.2-22.6 0L480 385.4l-28.7-28.7c-6.2-6.2-16.4-6.2-22.6 0s-6.2 16.4 0 22.6l40 40c6.2 6.2 16.4 6.2 22.6 0l72-72c6.2-6.2 6.2-16.4 0-22.6z" } }, "free": ["solid"] }, "house-medical-circle-exclamation": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["affected", "clinic", "hospital"] }, "styles": ["solid"], "unicode": "e512", "label": "House Medical Circle Exclamation", "voted": false, "svg": { "solid": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M320 368c0 59.5 29.5 112.1 74.8 144H128.1c-35.3 0-64-28.7-64-64V287.6H32c-18 0-32-14-32-32.1c0-9 3-17 10-24L266.4 8c7-7 15-8 22-8s15 2 21 7L522.1 193.9c-8.5-1.3-17.3-1.9-26.1-1.9c-54.7 0-103.5 24.9-135.8 64H320V208c0-8.8-7.2-16-16-16H272c-8.8 0-16 7.2-16 16v48H208c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h48v48c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16zM496 224a144 144 0 1 1 0 288 144 144 0 1 1 0-288zm0 240a24 24 0 1 0 0-48 24 24 0 1 0 0 48zm0-192c-8.8 0-16 7.2-16 16v80c0 8.8 7.2 16 16 16s16-7.2 16-16V288c0-8.8-7.2-16-16-16z" } }, "free": ["solid"] }, "house-medical-circle-xmark": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["clinic", "destroy", "hospital"] }, "styles": ["solid"], "unicode": "e513", "label": "House Medical Circle Xmark", "voted": false, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M320 368c0 59.5 29.5 112.1 74.8 144H128.1c-35.3 0-64-28.7-64-64V287.6H32c-18 0-32-14-32-32.1c0-9 3-17 10-24L266.4 8c7-7 15-8 22-8s15 2 21 7L522.1 193.9c-8.5-1.3-17.3-1.9-26.1-1.9c-54.7 0-103.5 24.9-135.8 64H320V208c0-8.8-7.2-16-16-16H272c-8.8 0-16 7.2-16 16v48H208c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h48v48c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16zM496 224a144 144 0 1 1 0 288 144 144 0 1 1 0-288zm22.6 144l36.7-36.7c6.2-6.2 6.2-16.4 0-22.6s-16.4-6.2-22.6 0L496 345.4l-36.7-36.7c-6.2-6.2-16.4-6.2-22.6 0s-6.2 16.4 0 22.6L473.4 368l-36.7 36.7c-6.2 6.2-6.2 16.4 0 22.6s16.4 6.2 22.6 0L496 390.6l36.7 36.7c6.2 6.2 16.4 6.2 22.6 0s6.2-16.4 0-22.6L518.6 368z" } }, "free": ["solid"] }, "house-medical-flag": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["clinic", "hospital", "mash"] }, "styles": ["solid"], "unicode": "e514", "label": "House Medical Flag", "voted": false, "svg": { "solid": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M480 0c17.7 0 32 14.3 32 32H624c8.8 0 16 7.2 16 16V176c0 8.8-7.2 16-16 16H512V512H448V192 32c0-17.7 14.3-32 32-32zM276.8 39.7L416 159V512h1l-.2 0H96c-17.7 0-32-14.3-32-32V288H32c-13.4 0-25.4-8.3-30-20.9s-1-26.7 9.2-35.4l224-192c12-10.3 29.7-10.3 41.7 0zM224 208v48H176c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h48v48c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V320h48c8.8 0 16-7.2 16-16V272c0-8.8-7.2-16-16-16H288V208c0-8.8-7.2-16-16-16H240c-8.8 0-16 7.2-16 16z" } }, "free": ["solid"] }, "house-signal": { "aliases": { "unicodes": { "secondary": ["10e012"] } }, "changes": [ "5.12.0", "5.14.0", "6.0.0-beta1", "6.0.0-beta3", "6.1.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "abode", "building", "connect", "family", "home", "residence", "smart home", "wifi" ] }, "styles": ["solid"], "unicode": "e012", "label": "House Signal", "voted": false, "svg": { "solid": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M357.7 8.5c-12.3-11.3-31.2-11.3-43.4 0l-208 192c-9.4 8.6-12.7 22-8.5 34c87.1 25.3 155.6 94.2 180.3 181.6H464c26.5 0 48-21.5 48-48V256h32c13.2 0 25-8.1 29.8-20.3s1.6-26.2-8.1-35.2l-208-192zM288 208c0-8.8 7.2-16 16-16h64c8.8 0 16 7.2 16 16v64c0 8.8-7.2 16-16 16H304c-8.8 0-16-7.2-16-16V208zM24 256c-13.3 0-24 10.7-24 24s10.7 24 24 24c101.6 0 184 82.4 184 184c0 13.3 10.7 24 24 24s24-10.7 24-24c0-128.1-103.9-232-232-232zm8 256a32 32 0 1 0 0-64 32 32 0 1 0 0 64zM0 376c0 13.3 10.7 24 24 24c48.6 0 88 39.4 88 88c0 13.3 10.7 24 24 24s24-10.7 24-24c0-75.1-60.9-136-136-136c-13.3 0-24 10.7-24 24z" } }, "free": ["solid"] }, "house-tsunami": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["damage", "flood", "tidal wave", "wave"] }, "styles": ["solid"], "unicode": "e515", "label": "House Tsunami", "voted": false, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M80.8 136.5C104.9 93.8 152.6 64 209 64c16.9 0 33.1 2.7 48.2 7.7c16.8 5.5 34.9-3.6 40.4-20.4s-3.6-34.9-20.4-40.4C255.8 3.8 232.8 0 209 0C95.2 0 0 88 0 200c0 91.6 53.5 172.1 142.2 194.1c13.4 3.8 27.5 5.9 42.2 5.9c.7 0 1.4 0 2.1-.1c1.8 0 3.7 .1 5.5 .1l0 0c31.9 0 60.6-9.9 80.4-18.9c5.8-2.7 11.1-5.3 15.6-7.7c4.5 2.4 9.7 5.1 15.6 7.7c19.8 9 48.5 18.9 80.4 18.9c33 0 65.5-10.3 94.5-25.8c13.4 8.4 33.7 19.3 58.2 25c17.2 4 34.4-6.7 38.4-23.9s-6.7-34.4-23.9-38.4c-18.1-4.2-36.2-13.3-50.6-25.2c-11.1-9.5-27.3-10.1-39.2-1.7l0 0C439.4 325.2 410.9 336 384 336c-27.5 0-55-10.6-77.5-26.1c-11.1-7.9-25.9-7.9-37 0c-22.4 15.5-49.9 26.1-77.4 26.1c0 0-.1 0-.1 0c-12.4 0-24-1.5-34.9-4.3C121.6 320.2 96 287 96 248c0-48.5 39.5-88 88.4-88c13.5 0 26.1 3 37.5 8.3c16 7.5 35.1 .6 42.5-15.5s.6-35.1-15.5-42.5C229.3 101.1 207.4 96 184.4 96c-40 0-76.4 15.4-103.6 40.5zm252-18.1c-8.1 6-12.8 15.5-12.8 25.6V265c1.6 1 3.3 2 4.8 3.1c18.4 12.7 39.6 20.3 59.2 20.3c19 0 41.2-7.9 59.2-20.3c23.8-16.7 55.8-15.3 78.1 3.4c10.6 8.8 24.2 15.6 37.3 18.6c5.8 1.4 11.2 3.4 16.2 6.2c.7-2.7 1.1-5.5 1.1-8.4l-.4-144c0-10-4.7-19.4-12.7-25.5l-95.5-72c-11.4-8.6-27.1-8.6-38.5 0l-96 72zM384 448c-27.5 0-55-10.6-77.5-26.1c-11.1-7.9-25.9-7.9-37 0C247 437.4 219.5 448 192 448c-26.9 0-55.3-10.8-77.4-26.1l0 0c-11.9-8.5-28.1-7.8-39.2 1.7c-14.4 11.9-32.5 21-50.6 25.2c-17.2 4-27.9 21.2-23.9 38.4s21.2 27.9 38.4 23.9c24.5-5.7 44.9-16.5 58.2-25C126.5 501.7 159 512 192 512c31.9 0 60.6-9.9 80.4-18.9c5.8-2.7 11.1-5.3 15.6-7.7c4.5 2.4 9.7 5.1 15.6 7.7c19.8 9 48.5 18.9 80.4 18.9c33 0 65.5-10.3 94.5-25.8c13.4 8.4 33.7 19.3 58.2 25c17.2 4 34.4-6.7 38.4-23.9s-6.7-34.4-23.9-38.4c-18.1-4.2-36.2-13.3-50.6-25.2c-11.1-9.4-27.3-10.1-39.2-1.7l0 0C439.4 437.2 410.9 448 384 448z" } }, "free": ["solid"] }, "house-user": { "aliases": { "names": ["home-user"] }, "changes": [ "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.1.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["house"] }, "styles": ["solid"], "unicode": "e1b0", "label": "House User", "voted": false, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M575.8 255.5c0 18-15 32.1-32 32.1h-32l.7 160.2c.2 35.5-28.5 64.3-64 64.3H128.1c-35.3 0-64-28.7-64-64V287.6H32c-18 0-32-14-32-32.1c0-9 3-17 10-24L266.4 8c7-7 15-8 22-8s15 2 21 7L564.8 231.5c8 7 12 15 11 24zM352 224a64 64 0 1 0 -128 0 64 64 0 1 0 128 0zm-96 96c-44.2 0-80 35.8-80 80c0 8.8 7.2 16 16 16H384c8.8 0 16-7.2 16-16c0-44.2-35.8-80-80-80H256z" } }, "free": ["solid"] }, "houzz": { "changes": ["4.4.0", "5.0.0", "5.0.9", "5.8.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f27c", "label": "Houzz", "voted": false, "svg": { "brands": { "last_modified": 1660014472, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M275.9 330.7H171.3V480H17V32h109.5v104.5l305.1 85.6V480H275.9z" } }, "free": ["brands"] }, "hryvnia-sign": { "aliases": { "names": ["hryvnia"], "unicodes": { "composite": ["20b4"], "secondary": ["10f6f2"] } }, "changes": [ "5.4.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["Hryvnia Sign", "currency"] }, "styles": ["solid"], "unicode": "f6f2", "label": "Hryvnia Sign", "voted": true, "svg": { "solid": { "last_modified": 1684766476, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M121.9 116.2C138.3 103.1 158.7 96 179.6 96H223c27.1 0 49 21.9 49 49c0 11.5-4 22.4-11.1 31H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H155.5l-50.6 28.9c-1.7 1-3.4 2-5.1 3.1H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H52.3c-2.8 9.9-4.3 20.4-4.3 31c0 62.4 50.6 113 113 113h43.4c35.5 0 70-12.1 97.7-34.3L308 441c13.8-11 16-31.2 5-45s-31.2-16-45-5l-5.9 4.7c-16.4 13.1-36.7 20.2-57.7 20.2H161c-27.1 0-49-21.9-49-49c0-11.5 4-22.4 11.1-31H352c17.7 0 32-14.3 32-32s-14.3-32-32-32H228.5l50.6-28.9c1.7-1 3.4-2 5.1-3.1H352c17.7 0 32-14.3 32-32s-14.3-32-32-32H331.7c2.8-10 4.3-20.4 4.3-31c0-62.4-50.6-113-113-113H179.6c-35.5 0-70 12.1-97.7 34.3L76 71c-13.8 11-16 31.2-5 45s31.2 16 45 5l5.9-4.7z" } }, "free": ["solid"] }, "html5": { "changes": ["3.1.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f13b", "label": "HTML 5 Logo", "voted": false, "svg": { "brands": { "last_modified": 1660014464, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M0 32l34.9 395.8L191.5 480l157.6-52.2L384 32H0zm308.2 127.9H124.4l4.1 49.4h175.6l-13.6 148.4-97.9 27v.3h-1.1l-98.7-27.3-6-75.8h47.7L138 320l53.5 14.5 53.7-14.5 6-62.2H84.3L71.5 112.2h241.1l-4.4 47.7z" } }, "free": ["brands"] }, "hubspot": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3b2", "label": "HubSpot", "voted": false, "svg": { "brands": { "last_modified": 1660014466, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M267.4 211.6c-25.1 23.7-40.8 57.3-40.8 94.6 0 29.3 9.7 56.3 26 78L203.1 434c-4.4-1.6-9.1-2.5-14-2.5-10.8 0-20.9 4.2-28.5 11.8-7.6 7.6-11.8 17.8-11.8 28.6s4.2 20.9 11.8 28.5c7.6 7.6 17.8 11.6 28.5 11.6 10.8 0 20.9-3.9 28.6-11.6 7.6-7.6 11.8-17.8 11.8-28.5 0-4.2-.6-8.2-1.9-12.1l50-50.2c22 16.9 49.4 26.9 79.3 26.9 71.9 0 130-58.3 130-130.2 0-65.2-47.7-119.2-110.2-128.7V116c17.5-7.4 28.2-23.8 28.2-42.9 0-26.1-20.9-47.9-47-47.9S311.2 47 311.2 73.1c0 19.1 10.7 35.5 28.2 42.9v61.2c-15.2 2.1-29.6 6.7-42.7 13.6-27.6-20.9-117.5-85.7-168.9-124.8 1.2-4.4 2-9 2-13.8C129.8 23.4 106.3 0 77.4 0 48.6 0 25.2 23.4 25.2 52.2c0 28.9 23.4 52.3 52.2 52.3 9.8 0 18.9-2.9 26.8-7.6l163.2 114.7zm89.5 163.6c-38.1 0-69-30.9-69-69s30.9-69 69-69 69 30.9 69 69-30.9 69-69 69z" } }, "free": ["brands"] }, "hurricane": { "aliases": { "unicodes": { "secondary": ["10f751"] } }, "changes": [ "5.5.0", "5.10.1", "6.0.0-beta1", "6.1.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "coriolis effect", "eye", "storm", "tropical cyclone", "typhoon" ] }, "styles": ["solid"], "unicode": "f751", "label": "Hurricane", "voted": false, "svg": { "solid": { "last_modified": 1684767661, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M0 208C0 104.4 75.7 18.5 174.9 2.6C184 1.2 192 8.6 192 17.9V81.2c0 8.4 6.5 15.3 14.7 16.5C307 112.5 384 199 384 303.4c0 103.6-75.7 189.5-174.9 205.4c-9.2 1.5-17.1-5.9-17.1-15.2V430.2c0-8.4-6.5-15.3-14.7-16.5C77 398.9 0 312.4 0 208zm288 48A96 96 0 1 0 96 256a96 96 0 1 0 192 0zm-96-32a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" } }, "free": ["solid"] }, "i": { "aliases": { "unicodes": { "composite": ["69"] } }, "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Latin Capital Letter I", "Latin Small Letter I", "letter"] }, "styles": ["solid"], "unicode": "49", "label": "I", "voted": false, "svg": { "solid": { "last_modified": 1684767247, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M32 32C14.3 32 0 46.3 0 64S14.3 96 32 96h96V416H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H288c17.7 0 32-14.3 32-32s-14.3-32-32-32H192V96h96c17.7 0 32-14.3 32-32s-14.3-32-32-32H160 32z" } }, "free": ["solid"] }, "i-cursor": { "aliases": { "unicodes": { "secondary": ["10f246"] } }, "changes": ["4.4.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["editing", "i-beam", "type", "writing"] }, "styles": ["solid"], "unicode": "f246", "label": "I Cursor", "voted": false, "svg": { "solid": { "last_modified": 1684767247, "raw": "", "viewBox": [0, 0, 256, 512], "width": 256, "height": 512, "path": "M.1 29.3C-1.4 47 11.7 62.4 29.3 63.9l8 .7C70.5 67.3 96 95 96 128.3V224H64c-17.7 0-32 14.3-32 32s14.3 32 32 32H96v95.7c0 33.3-25.5 61-58.7 63.8l-8 .7C11.7 449.6-1.4 465 .1 482.7s16.9 30.7 34.5 29.2l8-.7c34.1-2.8 64.2-18.9 85.4-42.9c21.2 24 51.2 40.1 85.4 42.9l8 .7c17.6 1.5 33.1-11.6 34.5-29.2s-11.6-33.1-29.2-34.5l-8-.7C185.5 444.7 160 417 160 383.7V288h32c17.7 0 32-14.3 32-32s-14.3-32-32-32H160V128.3c0-33.3 25.5-61 58.7-63.8l8-.7c17.6-1.5 30.7-16.9 29.2-34.5S239-1.4 221.3 .1l-8 .7C179.2 3.6 149.2 19.7 128 43.7c-21.2-24-51.2-40-85.4-42.9l-8-.7C17-1.4 1.6 11.7 .1 29.3z" } }, "free": ["solid"] }, "ice-cream": { "aliases": { "unicodes": { "composite": ["1f368"], "secondary": ["10f810"] } }, "changes": [ "5.7.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta2", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "chocolate", "cone", "cream", "dessert", "frozen", "ice", "ice cream", "scoop", "sorbet", "sweet", "vanilla", "yogurt" ] }, "styles": ["solid"], "unicode": "f810", "label": "Ice Cream", "voted": false, "svg": { "solid": { "last_modified": 1684767419, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M367.1 160c.6-5.3 .9-10.6 .9-16C368 64.5 303.5 0 224 0S80 64.5 80 144c0 5.4 .3 10.7 .9 16H80c-26.5 0-48 21.5-48 48s21.5 48 48 48h53.5 181H368c26.5 0 48-21.5 48-48s-21.5-48-48-48h-.9zM96 288L200.8 497.7c4.4 8.8 13.3 14.3 23.2 14.3s18.8-5.5 23.2-14.3L352 288H96z" } }, "free": ["solid"] }, "icicles": { "aliases": { "unicodes": { "secondary": ["10f7ad"] } }, "changes": ["5.6.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["cold", "frozen", "hanging", "ice", "seasonal", "sharp"] }, "styles": ["solid"], "unicode": "f7ad", "label": "Icicles", "voted": false, "svg": { "solid": { "last_modified": 1684767662, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M75.8 304.8L1 35.7c-.7-2.5-1-5-1-7.5C0 12.6 12.6 0 28.2 0H482.4C498.8 0 512 13.2 512 29.6c0 1.6-.1 3.3-.4 4.9L434.6 496.1c-1.5 9.2-9.5 15.9-18.8 15.9c-9.2 0-17.1-6.6-18.7-15.6L336 160 307.2 303.9c-1.9 9.3-10.1 16.1-19.6 16.1c-9.2 0-17.2-6.2-19.4-15.1L240 192 210.6 368.2c-1.5 9.1-9.4 15.8-18.6 15.8s-17.1-6.7-18.6-15.8L144 192 115.9 304.3c-2.3 9.2-10.6 15.7-20.1 15.7c-9.3 0-17.5-6.2-20-15.2z" } }, "free": ["solid"] }, "icons": { "aliases": { "names": ["heart-music-camera-bolt"], "unicodes": { "secondary": ["10f86d"] } }, "changes": ["5.9.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["bolt", "emoji", "heart", "image", "music", "photo", "symbols"] }, "styles": ["solid"], "unicode": "f86d", "label": "Icons", "voted": false, "svg": { "solid": { "last_modified": 1684767368, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M500.3 7.3C507.7 13.3 512 22.4 512 32V176c0 26.5-28.7 48-64 48s-64-21.5-64-48s28.7-48 64-48V71L352 90.2V208c0 26.5-28.7 48-64 48s-64-21.5-64-48s28.7-48 64-48V64c0-15.3 10.8-28.4 25.7-31.4l160-32c9.4-1.9 19.1 .6 26.6 6.6zM74.7 304l11.8-17.8c5.9-8.9 15.9-14.2 26.6-14.2h61.7c10.7 0 20.7 5.3 26.6 14.2L213.3 304H240c26.5 0 48 21.5 48 48V464c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V352c0-26.5 21.5-48 48-48H74.7zM192 408a48 48 0 1 0 -96 0 48 48 0 1 0 96 0zM478.7 278.3L440.3 368H496c6.7 0 12.6 4.1 15 10.4s.6 13.3-4.4 17.7l-128 112c-5.6 4.9-13.9 5.3-19.9 .9s-8.2-12.4-5.3-19.2L391.7 400H336c-6.7 0-12.6-4.1-15-10.4s-.6-13.3 4.4-17.7l128-112c5.6-4.9 13.9-5.3 19.9-.9s8.2 12.4 5.3 19.2zm-339-59.2c-6.5 6.5-17 6.5-23 0L19.9 119.2c-28-29-26.5-76.9 5-103.9c27-23.5 68.4-19 93.4 6.5l10 10.5 9.5-10.5c25-25.5 65.9-30 93.9-6.5c31 27 32.5 74.9 4.5 103.9l-96.4 99.9z" } }, "free": ["solid"] }, "id-badge": { "aliases": { "unicodes": { "secondary": ["10f2c1"] } }, "changes": [ "4.7.0", "5.0.0", "5.0.3", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["address", "contact", "identification", "license", "profile"] }, "styles": ["solid", "regular"], "unicode": "f2c1", "label": "Id Badge", "voted": false, "svg": { "solid": { "last_modified": 1684767620, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M64 0C28.7 0 0 28.7 0 64V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V64c0-35.3-28.7-64-64-64H64zm96 320h64c44.2 0 80 35.8 80 80c0 8.8-7.2 16-16 16H96c-8.8 0-16-7.2-16-16c0-44.2 35.8-80 80-80zm-32-96a64 64 0 1 1 128 0 64 64 0 1 1 -128 0zM144 64h96c8.8 0 16 7.2 16 16s-7.2 16-16 16H144c-8.8 0-16-7.2-16-16s7.2-16 16-16z" }, "regular": { "last_modified": 1684767620, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M256 48V64c0 17.7-14.3 32-32 32H160c-17.7 0-32-14.3-32-32V48H64c-8.8 0-16 7.2-16 16V448c0 8.8 7.2 16 16 16H320c8.8 0 16-7.2 16-16V64c0-8.8-7.2-16-16-16H256zM0 64C0 28.7 28.7 0 64 0H320c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V64zM160 320h64c44.2 0 80 35.8 80 80c0 8.8-7.2 16-16 16H96c-8.8 0-16-7.2-16-16c0-44.2 35.8-80 80-80zm-32-96a64 64 0 1 1 128 0 64 64 0 1 1 -128 0z" } }, "free": ["regular", "solid"] }, "id-card": { "aliases": { "names": ["drivers-license"], "unicodes": { "composite": ["f2c3"], "secondary": ["10f2c2"] } }, "changes": [ "4.7.0", "5.0.0", "5.0.3", "5.8.0", "5.10.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "contact", "demographics", "document", "identification", "issued", "profile", "registration" ] }, "styles": ["solid", "regular"], "unicode": "f2c2", "label": "Id Card", "voted": false, "svg": { "solid": { "last_modified": 1684767620, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M0 96l576 0c0-35.3-28.7-64-64-64H64C28.7 32 0 60.7 0 96zm0 32V416c0 35.3 28.7 64 64 64H512c35.3 0 64-28.7 64-64V128H0zM64 405.3c0-29.5 23.9-53.3 53.3-53.3H234.7c29.5 0 53.3 23.9 53.3 53.3c0 5.9-4.8 10.7-10.7 10.7H74.7c-5.9 0-10.7-4.8-10.7-10.7zM176 192a64 64 0 1 1 0 128 64 64 0 1 1 0-128zm176 16c0-8.8 7.2-16 16-16H496c8.8 0 16 7.2 16 16s-7.2 16-16 16H368c-8.8 0-16-7.2-16-16zm0 64c0-8.8 7.2-16 16-16H496c8.8 0 16 7.2 16 16s-7.2 16-16 16H368c-8.8 0-16-7.2-16-16zm0 64c0-8.8 7.2-16 16-16H496c8.8 0 16 7.2 16 16s-7.2 16-16 16H368c-8.8 0-16-7.2-16-16z" }, "regular": { "last_modified": 1684767620, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M528 160V416c0 8.8-7.2 16-16 16H320c0-44.2-35.8-80-80-80H176c-44.2 0-80 35.8-80 80H64c-8.8 0-16-7.2-16-16V160H528zM64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H512c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zM272 256a64 64 0 1 0 -128 0 64 64 0 1 0 128 0zm104-48c-13.3 0-24 10.7-24 24s10.7 24 24 24h80c13.3 0 24-10.7 24-24s-10.7-24-24-24H376zm0 96c-13.3 0-24 10.7-24 24s10.7 24 24 24h80c13.3 0 24-10.7 24-24s-10.7-24-24-24H376z" } }, "free": ["regular", "solid"] }, "id-card-clip": { "aliases": { "names": ["id-card-alt"], "unicodes": { "secondary": ["10f47f"] } }, "changes": ["5.0.7", "5.10.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "contact", "demographics", "document", "identification", "issued", "profile" ] }, "styles": ["solid"], "unicode": "f47f", "label": "Id Card Clip", "voted": false, "svg": { "solid": { "last_modified": 1684767620, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M256 0h64c17.7 0 32 14.3 32 32V96c0 17.7-14.3 32-32 32H256c-17.7 0-32-14.3-32-32V32c0-17.7 14.3-32 32-32zM64 64H192v48c0 26.5 21.5 48 48 48h96c26.5 0 48-21.5 48-48V64H512c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128C0 92.7 28.7 64 64 64zM176 437.3c0 5.9 4.8 10.7 10.7 10.7H389.3c5.9 0 10.7-4.8 10.7-10.7c0-29.5-23.9-53.3-53.3-53.3H229.3c-29.5 0-53.3 23.9-53.3 53.3zM288 352a64 64 0 1 0 0-128 64 64 0 1 0 0 128z" } }, "free": ["solid"] }, "ideal": { "changes": ["5.12.0", "5.14.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e013", "label": "iDeal", "voted": true, "svg": { "brands": { "last_modified": 1660014462, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M125.61,165.48a49.07,49.07,0,1,0,49.06,49.06A49.08,49.08,0,0,0,125.61,165.48ZM86.15,425.84h78.94V285.32H86.15Zm151.46-211.6c0-20-10-22.53-18.74-22.53H204.82V237.5h14.05C228.62,237.5,237.61,234.69,237.61,214.24Zm201.69,46V168.93h22.75V237.5h33.69C486.5,113.08,388.61,86.19,299.67,86.19H204.84V169h14c25.6,0,41.5,17.35,41.5,45.26,0,28.81-15.52,46-41.5,46h-14V425.88h94.83c144.61,0,194.94-67.16,196.72-165.64Zm-109.75,0H273.3V169h54.43v22.73H296v10.58h30V225H296V237.5h33.51Zm74.66,0-5.16-17.67H369.31l-5.18,17.67H340.47L368,168.92h32.35l27.53,91.34ZM299.65,32H32V480H299.65c161.85,0,251-79.73,251-224.52C550.62,172,518,32,299.65,32Zm0,426.92H53.07V53.07H299.65c142.1,0,229.9,64.61,229.9,202.41C529.55,389.57,448.55,458.92,299.65,458.92Zm83.86-264.85L376,219.88H392.4l-7.52-25.81Z" } }, "free": ["brands"] }, "igloo": { "aliases": { "unicodes": { "secondary": ["10f7ae"] } }, "changes": [ "5.6.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["dome", "dwelling", "eskimo", "home", "house", "ice", "snow"] }, "styles": ["solid"], "unicode": "f7ae", "label": "Igloo", "voted": false, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M320 33.8V160H48.5C100.2 82.8 188.1 32 288 32c10.8 0 21.5 .6 32 1.8zM352 160V39.1C424.9 55.7 487.2 99.8 527.5 160H352zM29.9 192H96V320H0c0-46 10.8-89.4 29.9-128zM192 320H128V192H448V320H384v32H576v80c0 26.5-21.5 48-48 48H352V352c0-35.3-28.7-64-64-64s-64 28.7-64 64V480H48c-26.5 0-48-21.5-48-48V352H192V320zm288 0V192h66.1c19.2 38.6 29.9 82 29.9 128H480z" } }, "free": ["solid"] }, "image": { "aliases": { "unicodes": { "secondary": ["10f03e"] } }, "changes": [ "1.0.0", "5.0.0", "5.10.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["album", "landscape", "photo", "picture"] }, "styles": ["solid", "regular"], "unicode": "f03e", "label": "Image", "voted": false, "svg": { "solid": { "last_modified": 1684767343, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 96C0 60.7 28.7 32 64 32H448c35.3 0 64 28.7 64 64V416c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V96zM323.8 202.5c-4.5-6.6-11.9-10.5-19.8-10.5s-15.4 3.9-19.8 10.5l-87 127.6L170.7 297c-4.6-5.7-11.5-9-18.7-9s-14.2 3.3-18.7 9l-64 80c-5.8 7.2-6.9 17.1-2.9 25.4s12.4 13.6 21.6 13.6h96 32H424c8.9 0 17.1-4.9 21.2-12.8s3.6-17.4-1.4-24.7l-120-176zM112 192a48 48 0 1 0 0-96 48 48 0 1 0 0 96z" }, "regular": { "last_modified": 1684767343, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M448 80c8.8 0 16 7.2 16 16V415.8l-5-6.5-136-176c-4.5-5.9-11.6-9.3-19-9.3s-14.4 3.4-19 9.3L202 340.7l-30.5-42.7C167 291.7 159.8 288 152 288s-15 3.7-19.5 10.1l-80 112L48 416.3l0-.3V96c0-8.8 7.2-16 16-16H448zM64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zm80 192a48 48 0 1 0 0-96 48 48 0 1 0 0 96z" } }, "free": ["regular", "solid"] }, "image-portrait": { "aliases": { "names": ["portrait"], "unicodes": { "secondary": ["10f3e0"] } }, "changes": ["5.0.0", "5.0.3", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["id", "image", "photo", "picture", "selfie"] }, "styles": ["solid"], "unicode": "f3e0", "label": "Image Portrait", "voted": false, "svg": { "solid": { "last_modified": 1684767341, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M384 64c0-35.3-28.7-64-64-64H64C28.7 0 0 28.7 0 64V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64l0-384zM128 192a64 64 0 1 1 128 0 64 64 0 1 1 -128 0zM80 356.6c0-37.9 30.7-68.6 68.6-68.6h86.9c37.9 0 68.6 30.7 68.6 68.6c0 15.1-12.3 27.4-27.4 27.4H107.4C92.3 384 80 371.7 80 356.6z" } }, "free": ["solid"] }, "images": { "aliases": { "unicodes": { "secondary": ["10f302"] } }, "changes": [ "1.0.0", "5.0.0", "5.10.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["album", "landscape", "photo", "picture"] }, "styles": ["solid", "regular"], "unicode": "f302", "label": "Images", "voted": false, "svg": { "solid": { "last_modified": 1684767342, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M160 32c-35.3 0-64 28.7-64 64V320c0 35.3 28.7 64 64 64H512c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H160zM396 138.7l96 144c4.9 7.4 5.4 16.8 1.2 24.6S480.9 320 472 320H328 280 200c-9.2 0-17.6-5.3-21.6-13.6s-2.9-18.2 2.9-25.4l64-80c4.6-5.7 11.4-9 18.7-9s14.2 3.3 18.7 9l17.3 21.6 56-84C360.5 132 368 128 376 128s15.5 4 20 10.7zM192 128a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zM48 120c0-13.3-10.7-24-24-24S0 106.7 0 120V344c0 75.1 60.9 136 136 136H456c13.3 0 24-10.7 24-24s-10.7-24-24-24H136c-48.6 0-88-39.4-88-88V120z" }, "regular": { "last_modified": 1684767342, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M160 80H512c8.8 0 16 7.2 16 16V320c0 8.8-7.2 16-16 16H490.8L388.1 178.9c-4.4-6.8-12-10.9-20.1-10.9s-15.7 4.1-20.1 10.9l-52.2 79.8-12.4-16.9c-4.5-6.2-11.7-9.8-19.4-9.8s-14.8 3.6-19.4 9.8L175.6 336H160c-8.8 0-16-7.2-16-16V96c0-8.8 7.2-16 16-16zM96 96V320c0 35.3 28.7 64 64 64H512c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H160c-35.3 0-64 28.7-64 64zM48 120c0-13.3-10.7-24-24-24S0 106.7 0 120V344c0 75.1 60.9 136 136 136H456c13.3 0 24-10.7 24-24s-10.7-24-24-24H136c-48.6 0-88-39.4-88-88V120zm208 24a32 32 0 1 0 -64 0 32 32 0 1 0 64 0z" } }, "free": ["regular", "solid"] }, "imdb": { "changes": ["4.7.0", "5.0.0", "6.1.2"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f2d8", "label": "IMDB", "voted": false, "svg": { "brands": { "last_modified": 1660014465, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M89.5 323.6H53.93V186.2H89.5V323.6zM156.1 250.5L165.2 186.2H211.5V323.6H180.5V230.9L167.1 323.6H145.8L132.8 232.9L132.7 323.6H101.5V186.2H147.6C148.1 194.5 150.4 204.3 151.9 215.6L156.1 250.5zM223.7 323.6V186.2H250.3C267.3 186.2 277.3 187.1 283.3 188.6C289.4 190.3 294 192.8 297.2 196.5C300.3 199.8 302.3 203.1 303 208.5C303.9 212.9 304.4 221.6 304.4 234.7V282.9C304.4 295.2 303.7 303.4 302.5 307.6C301.4 311.7 299.4 315 296.5 317.3C293.7 319.7 290.1 321.4 285.8 322.3C281.6 323.1 275.2 323.6 266.7 323.6H223.7zM259.2 209.7V299.1C264.3 299.1 267.5 298.1 268.6 296.8C269.7 294.8 270.4 289.2 270.4 280.1V226.8C270.4 220.6 270.3 216.6 269.7 214.8C269.4 213 268.5 211.8 267.1 210.1C265.7 210.1 263 209.7 259.2 209.7V209.7zM316.5 323.6V186.2H350.6V230.1C353.5 227.7 356.7 225.2 360.1 223.5C363.7 222 368.9 221.1 372.9 221.1C377.7 221.1 381.8 221.9 385.2 223.3C388.6 224.8 391.2 226.8 393.2 229.5C394.9 232.1 395.9 234.8 396.3 237.3C396.7 239.9 396.1 245.3 396.1 253.5V292.1C396.1 300.3 396.3 306.4 395.3 310.5C394.2 314.5 391.5 318.1 387.5 320.1C383.4 324 378.6 325.4 372.9 325.4C368.9 325.4 363.7 324.5 360.2 322.9C356.7 321.1 353.5 318.4 350.6 314.9L348.5 323.6L316.5 323.6zM361.6 302.9C362.3 301.1 362.6 296.9 362.6 290.4V255C362.6 249.4 362.3 245.5 361.5 243.8C360.8 241.9 357.8 241.1 355.7 241.1C353.7 241.1 352.3 241.9 351.6 243.4C351 244.9 350.6 248.8 350.6 255V291.4C350.6 297.5 351 301.4 351.8 303C352.4 304.7 353.9 305.5 355.9 305.5C358.1 305.5 360.1 304.7 361.6 302.9L361.6 302.9zM418.4 32.04C434.1 33.27 447.1 47.28 447.1 63.92V448.1C447.1 464.5 435.2 478.5 418.9 479.1C418.6 479.1 418.4 480 418.1 480H29.88C29.6 480 29.32 479.1 29.04 479.9C13.31 478.5 1.093 466.1 0 449.7L.0186 61.78C1.081 45.88 13.82 33.09 30.26 31.1H417.7C417.9 31.1 418.2 32.01 418.4 32.04L418.4 32.04zM30.27 41.26C19 42.01 10.02 51.01 9.257 62.4V449.7C9.63 455.1 11.91 460.2 15.7 464C19.48 467.9 24.51 470.3 29.89 470.7H418.1C429.6 469.7 438.7 459.1 438.7 448.1V63.91C438.7 58.17 436.6 52.65 432.7 48.45C428.8 44.24 423.4 41.67 417.7 41.26L30.27 41.26z" } }, "free": ["brands"] }, "inbox": { "aliases": { "unicodes": { "secondary": ["10f01c"] } }, "changes": ["1.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["archive", "desk", "email", "mail", "message"] }, "styles": ["solid"], "unicode": "f01c", "label": "Inbox", "voted": false, "svg": { "solid": { "last_modified": 1684767390, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M121 32C91.6 32 66 52 58.9 80.5L1.9 308.4C.6 313.5 0 318.7 0 323.9V416c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V323.9c0-5.2-.6-10.4-1.9-15.5l-57-227.9C446 52 420.4 32 391 32H121zm0 64H391l48 192H387.8c-12.1 0-23.2 6.8-28.6 17.7l-14.3 28.6c-5.4 10.8-16.5 17.7-28.6 17.7H195.8c-12.1 0-23.2-6.8-28.6-17.7l-14.3-28.6c-5.4-10.8-16.5-17.7-28.6-17.7H73L121 96z" } }, "free": ["solid"] }, "indent": { "aliases": { "unicodes": { "secondary": ["10f03c"] } }, "changes": [ "1.0.0", "5.0.0", "5.9.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["align", "justify", "paragraph", "tab"] }, "styles": ["solid"], "unicode": "f03c", "label": "Indent", "voted": false, "svg": { "solid": { "last_modified": 1684767206, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M0 64C0 46.3 14.3 32 32 32H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32C14.3 96 0 81.7 0 64zM192 192c0-17.7 14.3-32 32-32H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H224c-17.7 0-32-14.3-32-32zm32 96H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H224c-17.7 0-32-14.3-32-32s14.3-32 32-32zM0 448c0-17.7 14.3-32 32-32H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32-14.3-32-32zM127.8 268.6L25.8 347.9C15.3 356.1 0 348.6 0 335.3V176.7c0-13.3 15.3-20.8 25.8-12.6l101.9 79.3c8.2 6.4 8.2 18.9 0 25.3z" } }, "free": ["solid"] }, "indian-rupee-sign": { "aliases": { "names": ["indian-rupee", "inr"] }, "changes": ["6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Indian Rupee Sign", "currency"] }, "styles": ["solid"], "unicode": "e1bc", "label": "Indian Rupee Sign", "voted": false, "svg": { "solid": { "last_modified": 1684766475, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M0 64C0 46.3 14.3 32 32 32H96h16H288c17.7 0 32 14.3 32 32s-14.3 32-32 32H231.8c9.6 14.4 16.7 30.6 20.7 48H288c17.7 0 32 14.3 32 32s-14.3 32-32 32H252.4c-13.2 58.3-61.9 103.2-122.2 110.9L274.6 422c14.4 10.3 17.7 30.3 7.4 44.6s-30.3 17.7-44.6 7.4L13.4 314C2.1 306-2.7 291.5 1.5 278.2S18.1 256 32 256h80c32.8 0 61-19.7 73.3-48H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H185.3C173 115.7 144.8 96 112 96H96 32C14.3 96 0 81.7 0 64z" } }, "free": ["solid"] }, "industry": { "aliases": { "unicodes": { "secondary": ["10f275"] } }, "changes": [ "4.4.0", "5.0.0", "5.10.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "building", "factory", "industrial", "manufacturing", "mill", "warehouse" ] }, "styles": ["solid"], "unicode": "f275", "label": "Industry", "voted": false, "svg": { "solid": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M64 32C46.3 32 32 46.3 32 64V304v48 80c0 26.5 21.5 48 48 48H496c26.5 0 48-21.5 48-48V304 152.2c0-18.2-19.4-29.7-35.4-21.1L352 215.4V152.2c0-18.2-19.4-29.7-35.4-21.1L160 215.4V64c0-17.7-14.3-32-32-32H64z" } }, "free": ["solid"] }, "infinity": { "aliases": { "unicodes": { "composite": ["221e", "267e"], "secondary": ["10f534"] } }, "changes": [ "5.0.13", "5.3.0", "5.10.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Infinity", "eternity", "forever", "infinity", "math", "unbounded", "universal" ] }, "styles": ["solid"], "unicode": "f534", "label": "Infinity", "voted": true, "svg": { "solid": { "last_modified": 1684767244, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M0 241.1C0 161 65 96 145.1 96c38.5 0 75.4 15.3 102.6 42.5L320 210.7l72.2-72.2C419.5 111.3 456.4 96 494.9 96C575 96 640 161 640 241.1v29.7C640 351 575 416 494.9 416c-38.5 0-75.4-15.3-102.6-42.5L320 301.3l-72.2 72.2C220.5 400.7 183.6 416 145.1 416C65 416 0 351 0 270.9V241.1zM274.7 256l-72.2-72.2c-15.2-15.2-35.9-23.8-57.4-23.8C100.3 160 64 196.3 64 241.1v29.7c0 44.8 36.3 81.1 81.1 81.1c21.5 0 42.2-8.5 57.4-23.8L274.7 256zm90.5 0l72.2 72.2c15.2 15.2 35.9 23.8 57.4 23.8c44.8 0 81.1-36.3 81.1-81.1V241.1c0-44.8-36.3-81.1-81.1-81.1c-21.5 0-42.2 8.5-57.4 23.8L365.3 256z" } }, "free": ["solid"] }, "info": { "aliases": { "unicodes": { "secondary": ["10f129"] } }, "changes": [ "3.1.0", "5.0.0", "5.10.1", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["details", "help", "information", "more", "support"] }, "styles": ["solid"], "unicode": "f129", "label": "Info", "voted": false, "svg": { "solid": { "last_modified": 1684767248, "raw": "", "viewBox": [0, 0, 192, 512], "width": 192, "height": 512, "path": "M48 80a48 48 0 1 1 96 0A48 48 0 1 1 48 80zM0 224c0-17.7 14.3-32 32-32H96c17.7 0 32 14.3 32 32V448h32c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H64V256H32c-17.7 0-32-14.3-32-32z" } }, "free": ["solid"] }, "instagram": { "changes": ["4.6.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f16d", "label": "Instagram", "voted": false, "svg": { "brands": { "last_modified": 1660014466, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M224.1 141c-63.6 0-114.9 51.3-114.9 114.9s51.3 114.9 114.9 114.9S339 319.5 339 255.9 287.7 141 224.1 141zm0 189.6c-41.1 0-74.7-33.5-74.7-74.7s33.5-74.7 74.7-74.7 74.7 33.5 74.7 74.7-33.6 74.7-74.7 74.7zm146.4-194.3c0 14.9-12 26.8-26.8 26.8-14.9 0-26.8-12-26.8-26.8s12-26.8 26.8-26.8 26.8 12 26.8 26.8zm76.1 27.2c-1.7-35.9-9.9-67.7-36.2-93.9-26.2-26.2-58-34.4-93.9-36.2-37-2.1-147.9-2.1-184.9 0-35.8 1.7-67.6 9.9-93.9 36.1s-34.4 58-36.2 93.9c-2.1 37-2.1 147.9 0 184.9 1.7 35.9 9.9 67.7 36.2 93.9s58 34.4 93.9 36.2c37 2.1 147.9 2.1 184.9 0 35.9-1.7 67.7-9.9 93.9-36.2 26.2-26.2 34.4-58 36.2-93.9 2.1-37 2.1-147.8 0-184.8zM398.8 388c-7.8 19.6-22.9 34.7-42.6 42.6-29.5 11.7-99.5 9-132.1 9s-102.7 2.6-132.1-9c-19.6-7.8-34.7-22.9-42.6-42.6-11.7-29.5-9-99.5-9-132.1s-2.6-102.7 9-132.1c7.8-19.6 22.9-34.7 42.6-42.6 29.5-11.7 99.5-9 132.1-9s102.7-2.6 132.1 9c19.6 7.8 34.7 22.9 42.6 42.6 11.7 29.5 9 99.5 9 132.1s2.7 102.7-9 132.1z" } }, "free": ["brands"] }, "instalod": { "changes": ["5.15.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e081", "label": "InstaLOD", "voted": false, "svg": { "brands": { "last_modified": 1660014477, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M153.384,480H387.113L502.554,275.765,204.229,333.211ZM504.726,240.078,387.113,32H155.669L360.23,267.9ZM124.386,48.809,7.274,256,123.236,461.154,225.627,165.561Z" } }, "free": ["brands"] }, "intercom": { "changes": ["5.6.0"], "ligatures": [], "search": { "terms": ["app", "customer", "messenger"] }, "styles": ["brands"], "unicode": "f7af", "label": "Intercom", "voted": false, "svg": { "brands": { "last_modified": 1660014458, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M392 32H56C25.1 32 0 57.1 0 88v336c0 30.9 25.1 56 56 56h336c30.9 0 56-25.1 56-56V88c0-30.9-25.1-56-56-56zm-108.3 82.1c0-19.8 29.9-19.8 29.9 0v199.5c0 19.8-29.9 19.8-29.9 0V114.1zm-74.6-7.5c0-19.8 29.9-19.8 29.9 0v216.5c0 19.8-29.9 19.8-29.9 0V106.6zm-74.7 7.5c0-19.8 29.9-19.8 29.9 0v199.5c0 19.8-29.9 19.8-29.9 0V114.1zM59.7 144c0-19.8 29.9-19.8 29.9 0v134.3c0 19.8-29.9 19.8-29.9 0V144zm323.4 227.8c-72.8 63-241.7 65.4-318.1 0-15-12.8 4.4-35.5 19.4-22.7 65.9 55.3 216.1 53.9 279.3 0 14.9-12.9 34.3 9.8 19.4 22.7zm5.2-93.5c0 19.8-29.9 19.8-29.9 0V144c0-19.8 29.9-19.8 29.9 0v134.3z" } }, "free": ["brands"] }, "internet-explorer": { "changes": ["4.4.0", "5.0.0"], "ligatures": [], "search": { "terms": ["browser", "ie"] }, "styles": ["brands"], "unicode": "f26b", "label": "Internet-explorer", "voted": false, "svg": { "brands": { "last_modified": 1660014460, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M483.049 159.706c10.855-24.575 21.424-60.438 21.424-87.871 0-72.722-79.641-98.371-209.673-38.577-107.632-7.181-211.221 73.67-237.098 186.457 30.852-34.862 78.271-82.298 121.977-101.158C125.404 166.85 79.128 228.002 43.992 291.725 23.246 329.651 0 390.94 0 436.747c0 98.575 92.854 86.5 180.251 42.006 31.423 15.43 66.559 15.573 101.695 15.573 97.124 0 184.249-54.294 216.814-146.022H377.927c-52.509 88.593-196.819 52.996-196.819-47.436H509.9c6.407-43.581-1.655-95.715-26.851-141.162zM64.559 346.877c17.711 51.15 53.703 95.871 100.266 123.304-88.741 48.94-173.267 29.096-100.266-123.304zm115.977-108.873c2-55.151 50.276-94.871 103.98-94.871 53.418 0 101.981 39.72 103.981 94.871H180.536zm184.536-187.6c21.425-10.287 48.563-22.003 72.558-22.003 31.422 0 54.274 21.717 54.274 53.722 0 20.003-7.427 49.007-14.569 67.867-26.28-42.292-65.986-81.584-112.263-99.586z" } }, "free": ["brands"] }, "invision": { "changes": ["5.6.0"], "ligatures": [], "search": { "terms": ["app", "design", "interface"] }, "styles": ["brands"], "unicode": "f7b0", "label": "InVision", "voted": false, "svg": { "brands": { "last_modified": 1660014481, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M407.4 32H40.6C18.2 32 0 50.2 0 72.6v366.8C0 461.8 18.2 480 40.6 480h366.8c22.4 0 40.6-18.2 40.6-40.6V72.6c0-22.4-18.2-40.6-40.6-40.6zM176.1 145.6c.4 23.4-22.4 27.3-26.6 27.4-14.9 0-27.1-12-27.1-27 .1-35.2 53.1-35.5 53.7-.4zM332.8 377c-65.6 0-34.1-74-25-106.6 14.1-46.4-45.2-59-59.9.7l-25.8 103.3H177l8.1-32.5c-31.5 51.8-94.6 44.4-94.6-4.3.1-14.3.9-14 23-104.1H81.7l9.7-35.6h76.4c-33.6 133.7-32.6 126.9-32.9 138.2 0 20.9 40.9 13.5 57.4-23.2l19.8-79.4h-32.3l9.7-35.6h68.8l-8.9 40.5c40.5-75.5 127.9-47.8 101.8 38-14.2 51.1-14.6 50.7-14.9 58.8 0 15.5 17.5 22.6 31.8-16.9L386 325c-10.5 36.7-29.4 52-53.2 52z" } }, "free": ["brands"] }, "ioxhost": { "changes": ["4.2.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f208", "label": "ioxhost", "voted": false, "svg": { "brands": { "last_modified": 1660014476, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M616 160h-67.3C511.2 70.7 422.9 8 320 8 183 8 72 119 72 256c0 16.4 1.6 32.5 4.7 48H24c-13.3 0-24 10.8-24 24 0 13.3 10.7 24 24 24h67.3c37.5 89.3 125.8 152 228.7 152 137 0 248-111 248-248 0-16.4-1.6-32.5-4.7-48H616c13.3 0 24-10.8 24-24 0-13.3-10.7-24-24-24zm-96 96c0 110.5-89.5 200-200 200-75.7 0-141.6-42-175.5-104H424c13.3 0 24-10.8 24-24 0-13.3-10.7-24-24-24H125.8c-3.8-15.4-5.8-31.4-5.8-48 0-110.5 89.5-200 200-200 75.7 0 141.6 42 175.5 104H216c-13.3 0-24 10.8-24 24 0 13.3 10.7 24 24 24h298.2c3.8 15.4 5.8 31.4 5.8 48zm-304-24h208c13.3 0 24 10.7 24 24 0 13.2-10.7 24-24 24H216c-13.3 0-24-10.7-24-24 0-13.2 10.7-24 24-24z" } }, "free": ["brands"] }, "italic": { "aliases": { "unicodes": { "secondary": ["10f033"] } }, "changes": [ "1.0.0", "5.0.0", "5.9.0", "5.10.1", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["edit", "emphasis", "font", "format", "text", "type"] }, "styles": ["solid"], "unicode": "f033", "label": "Italic", "voted": false, "svg": { "solid": { "last_modified": 1684767246, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M128 64c0-17.7 14.3-32 32-32H352c17.7 0 32 14.3 32 32s-14.3 32-32 32H293.3L160 416h64c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H90.7L224 96H160c-17.7 0-32-14.3-32-32z" } }, "free": ["solid"] }, "itch-io": { "changes": ["5.8.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f83a", "label": "itch.io", "voted": false, "svg": { "brands": { "last_modified": 1660014472, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M71.92 34.77C50.2 47.67 7.4 96.84 7 109.73v21.34c0 27.06 25.29 50.84 48.25 50.84 27.57 0 50.54-22.85 50.54-50 0 27.12 22.18 50 49.76 50s49-22.85 49-50c0 27.12 23.59 50 51.16 50h.5c27.57 0 51.16-22.85 51.16-50 0 27.12 21.47 50 49 50s49.76-22.85 49.76-50c0 27.12 23 50 50.54 50 23 0 48.25-23.78 48.25-50.84v-21.34c-.4-12.9-43.2-62.07-64.92-75C372.56 32.4 325.76 32 256 32S91.14 33.1 71.92 34.77zm132.32 134.39c-22 38.4-77.9 38.71-99.85.25-13.17 23.14-43.17 32.07-56 27.66-3.87 40.15-13.67 237.13 17.73 269.15 80 18.67 302.08 18.12 379.76 0 31.65-32.27 21.32-232 17.75-269.15-12.92 4.44-42.88-4.6-56-27.66-22 38.52-77.85 38.1-99.85-.24-7.1 12.49-23.05 28.94-51.76 28.94a57.54 57.54 0 0 1-51.75-28.94zm-41.58 53.77c16.47 0 31.09 0 49.22 19.78a436.91 436.91 0 0 1 88.18 0C318.22 223 332.85 223 349.31 223c52.33 0 65.22 77.53 83.87 144.45 17.26 62.15-5.52 63.67-33.95 63.73-42.15-1.57-65.49-32.18-65.49-62.79-39.25 6.43-101.93 8.79-155.55 0 0 30.61-23.34 61.22-65.49 62.79-28.42-.06-51.2-1.58-33.94-63.73 18.67-67 31.56-144.45 83.88-144.45zM256 270.79s-44.38 40.77-52.35 55.21l29-1.17v25.32c0 1.55 21.34.16 23.33.16 11.65.54 23.31 1 23.31-.16v-25.28l29 1.17c-8-14.48-52.35-55.24-52.35-55.24z" } }, "free": ["brands"] }, "itunes": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3b4", "label": "iTunes", "voted": false, "svg": { "brands": { "last_modified": 1660014468, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M223.6 80.3C129 80.3 52.5 157 52.5 251.5S129 422.8 223.6 422.8s171.2-76.7 171.2-171.2c0-94.6-76.7-171.3-171.2-171.3zm79.4 240c-3.2 13.6-13.5 21.2-27.3 23.8-12.1 2.2-22.2 2.8-31.9-5-11.8-10-12-26.4-1.4-36.8 8.4-8 20.3-9.6 38-12.8 3-.5 5.6-1.2 7.7-3.7 3.2-3.6 2.2-2 2.2-80.8 0-5.6-2.7-7.1-8.4-6.1-4 .7-91.9 17.1-91.9 17.1-5 1.1-6.7 2.6-6.7 8.3 0 116.1.5 110.8-1.2 118.5-2.1 9-7.6 15.8-14.9 19.6-8.3 4.6-23.4 6.6-31.4 5.2-21.4-4-28.9-28.7-14.4-42.9 8.4-8 20.3-9.6 38-12.8 3-.5 5.6-1.2 7.7-3.7 5-5.7.9-127 2.6-133.7.4-2.6 1.5-4.8 3.5-6.4 2.1-1.7 5.8-2.7 6.7-2.7 101-19 113.3-21.4 115.1-21.4 5.7-.4 9 3 9 8.7-.1 170.6.4 161.4-1 167.6zM345.2 32H102.8C45.9 32 0 77.9 0 134.8v242.4C0 434.1 45.9 480 102.8 480h242.4c57 0 102.8-45.9 102.8-102.8V134.8C448 77.9 402.1 32 345.2 32zM223.6 444c-106.3 0-192.5-86.2-192.5-192.5S117.3 59 223.6 59s192.5 86.2 192.5 192.5S329.9 444 223.6 444z" } }, "free": ["brands"] }, "itunes-note": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3b5", "label": "Itunes Note", "voted": false, "svg": { "brands": { "last_modified": 1660014476, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M381.9 388.2c-6.4 27.4-27.2 42.8-55.1 48-24.5 4.5-44.9 5.6-64.5-10.2-23.9-20.1-24.2-53.4-2.7-74.4 17-16.2 40.9-19.5 76.8-25.8 6-1.1 11.2-2.5 15.6-7.4 6.4-7.2 4.4-4.1 4.4-163.2 0-11.2-5.5-14.3-17-12.3-8.2 1.4-185.7 34.6-185.7 34.6-10.2 2.2-13.4 5.2-13.4 16.7 0 234.7 1.1 223.9-2.5 239.5-4.2 18.2-15.4 31.9-30.2 39.5-16.8 9.3-47.2 13.4-63.4 10.4-43.2-8.1-58.4-58-29.1-86.6 17-16.2 40.9-19.5 76.8-25.8 6-1.1 11.2-2.5 15.6-7.4 10.1-11.5 1.8-256.6 5.2-270.2.8-5.2 3-9.6 7.1-12.9 4.2-3.5 11.8-5.5 13.4-5.5 204-38.2 228.9-43.1 232.4-43.1 11.5-.8 18.1 6 18.1 17.6.2 344.5 1.1 326-1.8 338.5z" } }, "free": ["brands"] }, "j": { "aliases": { "unicodes": { "composite": ["6a"] } }, "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Latin Capital Letter J", "Latin Small Letter J", "letter"] }, "styles": ["solid"], "unicode": "4a", "label": "J", "voted": false, "svg": { "solid": { "last_modified": 1684767245, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M288 32c17.7 0 32 14.3 32 32V320c0 88.4-71.6 160-160 160S0 408.4 0 320V288c0-17.7 14.3-32 32-32s32 14.3 32 32v32c0 53 43 96 96 96s96-43 96-96V64c0-17.7 14.3-32 32-32z" } }, "free": ["solid"] }, "jar": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["jam", "jelly", "storage"] }, "styles": ["solid"], "unicode": "e516", "label": "Jar", "voted": false, "svg": { "solid": { "last_modified": 1684767418, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M32 32C32 14.3 46.3 0 64 0H256c17.7 0 32 14.3 32 32s-14.3 32-32 32H64C46.3 64 32 49.7 32 32zM0 160c0-35.3 28.7-64 64-64H256c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V160zm96 64c-17.7 0-32 14.3-32 32v96c0 17.7 14.3 32 32 32H224c17.7 0 32-14.3 32-32V256c0-17.7-14.3-32-32-32H96z" } }, "free": ["solid"] }, "jar-wheat": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["flour", "storage"] }, "styles": ["solid"], "unicode": "e517", "label": "Jar Wheat", "voted": false, "svg": { "solid": { "last_modified": 1684767421, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M32 32C32 14.3 46.3 0 64 0H256c17.7 0 32 14.3 32 32s-14.3 32-32 32H64C46.3 64 32 49.7 32 32zM0 160c0-35.3 28.7-64 64-64H256c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V160zm112 0H69.8c-3.2 0-5.8 2.6-5.8 5.8C64 198 90 224 122.2 224H144h32 21.8c32.1 0 58.2-26 58.2-58.2c0-3.2-2.6-5.8-5.8-5.8H208c-19.1 0-36.3 8.4-48 21.7c-11.7-13.3-28.9-21.7-48-21.7zm48 117.7c-11.7-13.3-28.9-21.7-48-21.7H69.8c-3.2 0-5.8 2.6-5.8 5.8C64 294 90 320 122.2 320H144h32 21.8c32.1 0 58.2-26 58.2-58.2c0-3.2-2.6-5.8-5.8-5.8H208c-19.1 0-36.3 8.4-48 21.7zM112 352H69.8c-3.2 0-5.8 2.6-5.8 5.8C64 390 90 416 122.2 416H144v32c0 8.8 7.2 16 16 16s16-7.2 16-16V416h21.8c32.1 0 58.2-26 58.2-58.2c0-3.2-2.6-5.8-5.8-5.8H208c-19.1 0-36.3 8.4-48 21.7c-11.7-13.3-28.9-21.7-48-21.7z" } }, "free": ["solid"] }, "java": { "changes": ["5.0.10", "5.7.0", "5.8.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f4e4", "label": "Java", "voted": false, "svg": { "brands": { "last_modified": 1660014481, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M277.74 312.9c9.8-6.7 23.4-12.5 23.4-12.5s-38.7 7-77.2 10.2c-47.1 3.9-97.7 4.7-123.1 1.3-60.1-8 33-30.1 33-30.1s-36.1-2.4-80.6 19c-52.5 25.4 130 37 224.5 12.1zm-85.4-32.1c-19-42.7-83.1-80.2 0-145.8C296 53.2 242.84 0 242.84 0c21.5 84.5-75.6 110.1-110.7 162.6-23.9 35.9 11.7 74.4 60.2 118.2zm114.6-176.2c.1 0-175.2 43.8-91.5 140.2 24.7 28.4-6.5 54-6.5 54s62.7-32.4 33.9-72.9c-26.9-37.8-47.5-56.6 64.1-121.3zm-6.1 270.5a12.19 12.19 0 0 1-2 2.6c128.3-33.7 81.1-118.9 19.8-97.3a17.33 17.33 0 0 0-8.2 6.3 70.45 70.45 0 0 1 11-3c31-6.5 75.5 41.5-20.6 91.4zM348 437.4s14.5 11.9-15.9 21.2c-57.9 17.5-240.8 22.8-291.6.7-18.3-7.9 16-19 26.8-21.3 11.2-2.4 17.7-2 17.7-2-20.3-14.3-131.3 28.1-56.4 40.2C232.84 509.4 401 461.3 348 437.4zM124.44 396c-78.7 22 47.9 67.4 148.1 24.5a185.89 185.89 0 0 1-28.2-13.8c-44.7 8.5-65.4 9.1-106 4.5-33.5-3.8-13.9-15.2-13.9-15.2zm179.8 97.2c-78.7 14.8-175.8 13.1-233.3 3.6 0-.1 11.8 9.7 72.4 13.6 92.2 5.9 233.8-3.3 237.1-46.9 0 0-6.4 16.5-76.2 29.7zM260.64 353c-59.2 11.4-93.5 11.1-136.8 6.6-33.5-3.5-11.6-19.7-11.6-19.7-86.8 28.8 48.2 61.4 169.5 25.9a60.37 60.37 0 0 1-21.1-12.8z" } }, "free": ["brands"] }, "jedi": { "aliases": { "unicodes": { "secondary": ["10f669"] } }, "changes": ["5.3.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["crest", "force", "sith", "skywalker", "star wars", "yoda"] }, "styles": ["solid"], "unicode": "f669", "label": "Jedi", "voted": false, "svg": { "solid": { "last_modified": 1684767603, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M246 315.7l-21.2-31.9c-2.1-3.2-1.7-7.4 1-10.1s6.9-3.1 10.1-1l29.5 19.7c2.1 1.4 4.9 0 5-2.6L279.7 8c.1-4.5 3.8-8 8.3-8s8.1 3.5 8.3 8l9.4 281.9c.1 2.5 2.9 3.9 5 2.6l29.5-19.7c3.2-2.1 7.4-1.7 10.1 1s3.1 6.9 1 10.1L330 315.7c-1.3 1.9-.2 4.5 2 4.9l37.6 7.5c3.7 .7 6.4 4 6.4 7.8s-2.7 7.1-6.4 7.8L332 351.4c-2.2 .4-3.3 3-2 4.9l21.2 31.9c2.1 3.2 1.7 7.4-1 10.1s-6.9 3.1-10.1 1l-26.3-17.6c-2.2-1.4-5.1 .2-5 2.8l2.1 61.5C370.6 435.2 416 382.9 416 320c0-37-15.7-70.4-40.8-93.7c-7-6.5-6.5-18.6 1-24.4C410.1 175.5 432 134.3 432 88c0-16.8-2.9-33-8.2-48c-4.6-13 10.2-30 21.4-22c53.5 38 92.7 94.8 107.8 160.7c.5 2.1-.2 4.3-1.7 5.9l-28.4 28.4c-4 4-1.2 10.9 4.5 10.9h26c3.4 0 6.2 2.6 6.3 6c.1 3.3 .2 6.6 .2 10c0 17.5-1.7 34.7-4.8 51.3c-.2 1.2-.9 2.4-1.7 3.3l-46.5 46.5c-4 4-1.2 10.9 4.5 10.9H526c4.6 0 7.7 4.8 5.7 9C487.2 450.5 394.8 512 288 512S88.8 450.5 44.3 361c-2.1-4.2 1-9 5.7-9H64.5c5.7 0 8.6-6.9 4.5-10.9L22.6 294.6c-.9-.9-1.5-2-1.7-3.3C17.7 274.7 16 257.5 16 240c0-3.3 .1-6.7 .2-10c.1-3.4 2.9-6 6.3-6h26c5.7 0 8.6-6.9 4.5-10.9L24.6 184.6c-1.5-1.5-2.2-3.8-1.7-5.9C38.1 112.8 77.3 56 130.8 18c11.3-8 26 8.9 21.4 22c-5.3 15-8.2 31.2-8.2 48c0 46.3 21.9 87.5 55.8 113.9c7.5 5.8 8 17.9 1 24.4C175.7 249.6 160 283 160 320c0 62.9 45.4 115.2 105.1 126l2.1-61.5c.1-2.6-2.8-4.2-5-2.8l-26.3 17.6c-3.2 2.1-7.4 1.7-10.1-1s-3.1-6.9-1-10.1L246 356.3c1.3-1.9 .2-4.5-2-4.9l-37.6-7.5c-3.7-.7-6.4-4-6.4-7.8s2.7-7.1 6.4-7.8l37.6-7.5c2.2-.4 3.3-3 2-4.9z" } }, "free": ["solid"] }, "jedi-order": { "changes": ["5.0.12", "5.7.0"], "ligatures": [], "search": { "terms": ["star wars"] }, "styles": ["brands"], "unicode": "f50e", "label": "Jedi Order", "voted": false, "svg": { "brands": { "last_modified": 1660014466, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M398.5 373.6c95.9-122.1 17.2-233.1 17.2-233.1 45.4 85.8-41.4 170.5-41.4 170.5 105-171.5-60.5-271.5-60.5-271.5 96.9 72.7-10.1 190.7-10.1 190.7 85.8 158.4-68.6 230.1-68.6 230.1s-.4-16.9-2.2-85.7c4.3 4.5 34.5 36.2 34.5 36.2l-24.2-47.4 62.6-9.1-62.6-9.1 20.2-55.5-31.4 45.9c-2.2-87.7-7.8-305.1-7.9-306.9v-2.4 1-1 2.4c0 1-5.6 219-7.9 306.9l-31.4-45.9 20.2 55.5-62.6 9.1 62.6 9.1-24.2 47.4 34.5-36.2c-1.8 68.8-2.2 85.7-2.2 85.7s-154.4-71.7-68.6-230.1c0 0-107-118.1-10.1-190.7 0 0-165.5 99.9-60.5 271.5 0 0-86.8-84.8-41.4-170.5 0 0-78.7 111 17.2 233.1 0 0-26.2-16.1-49.4-77.7 0 0 16.9 183.3 222 185.7h4.1c205-2.4 222-185.7 222-185.7-23.6 61.5-49.9 77.7-49.9 77.7z" } }, "free": ["brands"] }, "jenkins": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3b6", "label": "Jenkis", "voted": false, "svg": { "brands": { "last_modified": 1660014461, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M487.1 425c-1.4-11.2-19-23.1-28.2-31.9-5.1-5-29-23.1-30.4-29.9-1.4-6.6 9.7-21.5 13.3-28.9 5.1-10.7 8.8-23.7 11.3-32.6 18.8-66.1 20.7-156.9-6.2-211.2-10.2-20.6-38.6-49-56.4-62.5-42-31.7-119.6-35.3-170.1-16.6-14.1 5.2-27.8 9.8-40.1 17.1-33.1 19.4-68.3 32.5-78.1 71.6-24.2 10.8-31.5 41.8-30.3 77.8.2 7 4.1 15.8 2.7 22.4-.7 3.3-5.2 7.6-6.1 9.8-11.6 27.7-2.3 64 11.1 83.7 8.1 11.9 21.5 22.4 39.2 25.2.7 10.6 3.3 19.7 8.2 30.4 3.1 6.8 14.7 19 10.4 27.7-2.2 4.4-21 13.8-27.3 17.6C89 407.2 73.7 415 54.2 429c-12.6 9-32.3 10.2-29.2 31.1 2.1 14.1 10.1 31.6 14.7 45.8.7 2 1.4 4.1 2.1 6h422c4.9-15.3 9.7-30.9 14.6-47.2 3.4-11.4 10.2-27.8 8.7-39.7zM205.9 33.7c1.8-.5 3.4.7 4.9 2.4-.2 5.2-5.4 5.1-8.9 6.8-5.4 6.7-13.4 9.8-20 17.2-6.8 7.5-14.4 27.7-23.4 30-4.5 1.1-9.7-.8-13.6-.5-10.4.7-17.7 6-28.3 7.5 13.6-29.9 56.1-54 89.3-63.4zm-104.8 93.6c13.5-14.9 32.1-24.1 54.8-25.9 11.7 29.7-8.4 65-.9 97.6 2.3 9.9 10.2 25.4-2.4 25.7.3-28.3-34.8-46.3-61.3-29.6-1.8-21.5-4.9-51.7 9.8-67.8zm36.7 200.2c-1-4.1-2.7-12.9-2.3-15.1 1.6-8.7 17.1-12.5 11-24.7-11.3-.1-13.8 10.2-24.1 11.3-26.7 2.6-45.6-35.4-44.4-58.4 1-19.5 17.6-38.2 40.1-35.8 16 1.8 21.4 19.2 24.5 34.7 9.2.5 22.5-.4 26.9-7.6-.6-17.5-8.8-31.6-8.2-47.7 1-30.3 17.5-57.6 4.8-87.4 13.6-30.9 53.5-55.3 83.1-70 36.6-18.3 94.9-3.7 129.3 15.8 19.7 11.1 34.4 32.7 48.3 50.7-19.5-5.8-36.1 4.2-33.1 20.3 16.3-14.9 44.2-.2 52.5 16.4 7.9 15.8 7.8 39.3 9 62.8 2.9 57-10.4 115.9-39.1 157.1-7.7 11-14.1 23-24.9 30.6-26 18.2-65.4 34.7-99.2 23.4-44.7-15-65-44.8-89.5-78.8.7 18.7 13.8 34.1 26.8 48.4 11.3 12.5 25 26.6 39.7 32.4-12.3-2.9-31.1-3.8-36.2 7.2-28.6-1.9-55.1-4.8-68.7-24.2-10.6-15.4-21.4-41.4-26.3-61.4zm222 124.1c4.1-3 11.1-2.9 17.4-3.6-5.4-2.7-13-3.7-19.3-2.2-.1-4.2-2-6.8-3.2-10.2 10.6-3.8 35.5-28.5 49.6-20.3 6.7 3.9 9.5 26.2 10.1 37 .4 9-.8 18-4.5 22.8-18.8-.6-35.8-2.8-50.7-7 .9-6.1-1-12.1.6-16.5zm-17.2-20c-16.8.8-26-1.2-38.3-10.8.2-.8 1.4-.5 1.5-1.4 18 8 40.8-3.3 59-4.9-7.9 5.1-14.6 11.6-22.2 17.1zm-12.1 33.2c-1.6-9.4-3.5-12-2.8-20.2 25-16.6 29.7 28.6 2.8 20.2zM226 438.6c-11.6-.7-48.1-14-38.5-23.7 9.4 6.5 27.5 4.9 41.3 7.3.8 4.4-2.8 10.2-2.8 16.4zM57.7 497.1c-4.3-12.7-9.2-25.1-14.8-36.9 30.8-23.8 65.3-48.9 102.2-63.5 2.8-1.1 23.2 25.4 26.2 27.6 16.5 11.7 37 21 56.2 30.2 1.2 8.8 3.9 20.2 8.7 35.5.7 2.3 1.4 4.7 2.2 7.2H57.7zm240.6 5.7h-.8c.3-.2.5-.4.8-.5v.5zm7.5-5.7c2.1-1.4 4.3-2.8 6.4-4.3 1.1 1.4 2.2 2.8 3.2 4.3h-9.6zm15.1-24.7c-10.8 7.3-20.6 18.3-33.3 25.2-6 3.3-27 11.7-33.4 10.2-3.6-.8-3.9-5.3-5.4-9.5-3.1-9-10.1-23.4-10.8-37-.8-17.2-2.5-46 16-42.4 14.9 2.9 32.3 9.7 43.9 16.1 7.1 3.9 11.1 8.6 21.9 9.5-.1 1.4-.1 2.8-.2 4.3-5.9 3.9-15.3 3.8-21.8 7.1 9.5.4 17 2.7 23.5 5.9-.1 3.4-.3 7-.4 10.6zm53.4 24.7h-14c-.1-3.2-2.8-5.8-6.1-5.8s-5.9 2.6-6.1 5.8h-17.4c-2.8-4.4-5.7-8.6-8.9-12.5 2.1-2.2 4-4.7 6-6.9 9 3.7 14.8-4.9 21.7-4.2 7.9.8 14.2 11.7 25.4 11l-.6 12.6zm8.7 0c.2-4 .4-7.8.6-11.5 15.6-7.3 29 1.3 35.7 11.5H383zm83.4-37c-2.3 11.2-5.8 24-9.9 37.1-.2-.1-.4-.1-.6-.1H428c.6-1.1 1.2-2.2 1.9-3.3-2.6-6.1-9-8.7-10.9-15.5 12.1-22.7 6.5-93.4-24.2-78.5 4.3-6.3 15.6-11.5 20.8-19.3 13 10.4 20.8 20.3 33.2 31.4 6.8 6 20 13.3 21.4 23.1.8 5.5-2.6 18.9-3.8 25.1zM222.2 130.5c5.4-14.9 27.2-34.7 45-32 7.7 1.2 18 8.2 12.2 17.7-30.2-7-45.2 12.6-54.4 33.1-8.1-2-4.9-13.1-2.8-18.8zm184.1 63.1c8.2-3.6 22.4-.7 29.6-5.3-4.2-11.5-10.3-21.4-9.3-37.7.5 0 1 0 1.4.1 6.8 14.2 12.7 29.2 21.4 41.7-5.7 13.5-43.6 25.4-43.1 1.2zm20.4-43zm-117.2 45.7c-6.8-10.9-19-32.5-14.5-45.3 6.5 11.9 8.6 24.4 17.8 33.3 4.1 4 12.2 9 8.2 20.2-.9 2.7-7.8 8.6-11.7 9.7-14.4 4.3-47.9.9-36.6-17.1 11.9.7 27.9 7.8 36.8-.8zm27.3 70c3.8 6.6 1.4 18.7 12.1 20.6 20.2 3.4 43.6-12.3 58.1-17.8 9-15.2-.8-20.7-8.9-30.5-16.6-20-38.8-44.8-38-74.7 6.7-4.9 7.3 7.4 8.2 9.7 8.7 20.3 30.4 46.2 46.3 63.5 3.9 4.3 10.3 8.4 11 11.2 2.1 8.2-5.4 18-4.5 23.5-21.7 13.9-45.8 29.1-81.4 25.6-7.4-6.7-10.3-21.4-2.9-31.1zm-201.3-9.2c-6.8-3.9-8.4-21-16.4-21.4-11.4-.7-9.3 22.2-9.3 35.5-7.8-7.1-9.2-29.1-3.5-40.3-6.6-3.2-9.5 3.6-13.1 5.9 4.7-34.1 49.8-15.8 42.3 20.3zm299.6 28.8c-10.1 19.2-24.4 40.4-54 41-.6-6.2-1.1-15.6 0-19.4 22.7-2.2 36.6-13.7 54-21.6zm-141.9 12.4c18.9 9.9 53.6 11 79.3 10.2 1.4 5.6 1.3 12.6 1.4 19.4-33 1.8-72-6.4-80.7-29.6zm92.2 46.7c-1.7 4.3-5.3 9.3-9.8 11.1-12.1 4.9-45.6 8.7-62.4-.3-10.7-5.7-17.5-18.5-23.4-26-2.8-3.6-16.9-12.9-.2-12.9 13.1 32.7 58 29 95.8 28.1z" } }, "free": ["brands"] }, "jet-fighter": { "aliases": { "names": ["fighter-jet"], "unicodes": { "secondary": ["10f0fb"] } }, "changes": [ "3.0.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "airforce", "airplane", "airport", "fast", "fly", "goose", "marines", "maverick", "military", "plane", "quick", "top gun", "transportation", "travel" ] }, "styles": ["solid"], "unicode": "f0fb", "label": "Jet Fighter", "voted": false, "svg": { "solid": { "last_modified": 1684767636, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M160 24c0-13.3 10.7-24 24-24H296c13.3 0 24 10.7 24 24s-10.7 24-24 24H280L384 192H500.4c7.7 0 15.3 1.4 22.5 4.1L625 234.4c9 3.4 15 12 15 21.6s-6 18.2-15 21.6L522.9 315.9c-7.2 2.7-14.8 4.1-22.5 4.1H384L280 464h16c13.3 0 24 10.7 24 24s-10.7 24-24 24H184c-13.3 0-24-10.7-24-24s10.7-24 24-24h8V320H160l-54.6 54.6c-6 6-14.1 9.4-22.6 9.4H64c-17.7 0-32-14.3-32-32V288c-17.7 0-32-14.3-32-32s14.3-32 32-32V160c0-17.7 14.3-32 32-32H82.7c8.5 0 16.6 3.4 22.6 9.4L160 192h32V48h-8c-13.3 0-24-10.7-24-24zM80 240c-8.8 0-16 7.2-16 16s7.2 16 16 16h64c8.8 0 16-7.2 16-16s-7.2-16-16-16H80z" } }, "free": ["solid"] }, "jet-fighter-up": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "airforce", "airplane", "airport", "fast", "fly", "goose", "marines", "maverick", "military", "plane", "quick", "top gun", "transportation", "travel" ] }, "styles": ["solid"], "unicode": "e518", "label": "Jet Fighter Up", "voted": false, "svg": { "solid": { "last_modified": 1684767636, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M270.7 9.7C268.2 3.8 262.4 0 256 0s-12.2 3.8-14.7 9.7L197.2 112.6c-3.4 8-5.2 16.5-5.2 25.2v77l-144 84V280c0-13.3-10.7-24-24-24s-24 10.7-24 24v56 32 24c0 13.3 10.7 24 24 24s24-10.7 24-24v-8H192v32.7L133.5 468c-3.5 3-5.5 7.4-5.5 12v16c0 8.8 7.2 16 16 16h96V448c0-8.8 7.2-16 16-16s16 7.2 16 16v64h96c8.8 0 16-7.2 16-16V480c0-4.6-2-9-5.5-12L320 416.7V384H464v8c0 13.3 10.7 24 24 24s24-10.7 24-24V368 336 280c0-13.3-10.7-24-24-24s-24 10.7-24 24v18.8l-144-84v-77c0-8.7-1.8-17.2-5.2-25.2L270.7 9.7z" } }, "free": ["solid"] }, "jira": { "changes": ["5.6.0"], "ligatures": [], "search": { "terms": ["atlassian"] }, "styles": ["brands"], "unicode": "f7b1", "label": "Jira", "voted": true, "svg": { "brands": { "last_modified": 1660014465, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M490 241.7C417.1 169 320.6 71.8 248.5 0 83 164.9 6 241.7 6 241.7c-7.9 7.9-7.9 20.7 0 28.7C138.8 402.7 67.8 331.9 248.5 512c379.4-378 15.7-16.7 241.5-241.7 8-7.9 8-20.7 0-28.6zm-241.5 90l-76-75.7 76-75.7 76 75.7-76 75.7z" } }, "free": ["brands"] }, "joget": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3b7", "label": "Joget", "voted": false, "svg": { "brands": { "last_modified": 1660014475, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M378.1 45C337.6 19.9 292.6 8 248.2 8 165 8 83.8 49.9 36.9 125.9c-71.9 116.6-35.6 269.3 81 341.2s269.3 35.6 341.2-80.9c71.9-116.6 35.6-269.4-81-341.2zm51.8 323.2c-40.4 65.5-110.4 101.5-182 101.5-6.8 0-13.6-.4-20.4-1-9-13.6-19.9-33.3-23.7-42.4-5.7-13.7-27.2-45.6 31.2-67.1 51.7-19.1 176.7-16.5 208.8-17.6-4 9-8.6 17.9-13.9 26.6zm-200.8-86.3c-55.5-1.4-81.7-20.8-58.5-48.2s51.1-40.7 68.9-51.2c17.9-10.5 27.3-33.7-23.6-29.7C87.3 161.5 48.6 252.1 37.6 293c-8.8-49.7-.1-102.7 28.5-149.1C128 43.4 259.6 12.2 360.1 74.1c74.8 46.1 111.2 130.9 99.3 212.7-24.9-.5-179.3-3.6-230.3-4.9zm183.8-54.8c-22.7-6-57 11.3-86.7 27.2-29.7 15.8-31.1 8.2-31.1 8.2s40.2-28.1 50.7-34.5 31.9-14 13.4-24.6c-3.2-1.8-6.7-2.7-10.4-2.7-17.8 0-41.5 18.7-67.5 35.6-31.5 20.5-65.3 31.3-65.3 31.3l169.5-1.6 46.5-23.4s3.6-9.5-19.1-15.5z" } }, "free": ["brands"] }, "joint": { "aliases": { "unicodes": { "secondary": ["10f595"] } }, "changes": ["5.1.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "blunt", "cannabis", "doobie", "drugs", "marijuana", "roach", "smoke", "smoking", "spliff" ] }, "styles": ["solid"], "unicode": "f595", "label": "Joint", "voted": false, "svg": { "solid": { "last_modified": 1684766751, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M448 32c0-17.7-14.3-32-32-32s-32 14.3-32 32V43c0 55.2 21.9 108.1 60.9 147.1l21 21c9 9 14.1 21.2 14.1 33.9v11c0 17.7 14.3 32 32 32s32-14.3 32-32V245c0-29.7-11.8-58.2-32.8-79.2l-21-21C463.2 117.8 448 81.2 448 43V32zM576 256c0 17.7 14.3 32 32 32s32-14.3 32-32V245c0-55.2-21.9-108.1-60.9-147.1l-21-21c-9-9-14.1-21.2-14.1-33.9V32c0-17.7-14.3-32-32-32s-32 14.3-32 32V43c0 29.7 11.8 58.2 32.8 79.2l21 21c27 27 42.2 63.6 42.2 101.8v11zM229.8 360c-4.7-2.3-10-2.7-15.2-2c-37.8 5.6-75.2 14.3-106.9 22.8C81.3 388 58.3 395.1 42 400.4c-8.2 2.7-14.7 4.9-19.2 6.5c-2.3 .8-4 1.4-5.2 1.8l-1.3 .5C6.8 412.5 0 421.4 0 432s6.8 19.5 16.3 22.7l1.3 .5c1.2 .4 3 1.1 5.2 1.8c4.5 1.6 11 3.8 19.2 6.5c16.3 5.4 39.2 12.5 65.7 19.6C160.3 497.3 228.8 512 288 512h67.3c4.1 0 6.3-5.1 3.6-8.3L256.5 380.8c-7.4-8.9-16.5-15.9-26.7-20.8zM445 512h19 51.3c4.1 0 6.3-5.1 3.6-8.3L416.5 380.8C401.3 362.5 378.8 352 355 352H336 288c-1.1 0-2.3 0-3.4 0c-4.1 0-6.2 5.1-3.5 8.3L383.5 483.2C398.7 501.5 421.2 512 445 512zm-3.9-151.7L543.5 483.2c14.6 17.5 35.9 27.9 58.6 28.7c21.1-1.1 37.9-18.6 37.9-39.9V392c0-22.1-17.9-40-40-40H444.7c-4.1 0-6.3 5.1-3.6 8.3z" } }, "free": ["solid"] }, "joomla": { "changes": ["4.1.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f1aa", "label": "Joomla Logo", "voted": false, "svg": { "brands": { "last_modified": 1660014459, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M.6 92.1C.6 58.8 27.4 32 60.4 32c30 0 54.5 21.9 59.2 50.2 32.6-7.6 67.1.6 96.5 30l-44.3 44.3c-20.5-20.5-42.6-16.3-55.4-3.5-14.3 14.3-14.3 37.9 0 52.2l99.5 99.5-44 44.3c-87.7-87.2-49.7-49.7-99.8-99.7-26.8-26.5-35-64.8-24.8-98.9C20.4 144.6.6 120.7.6 92.1zm129.5 116.4l44.3 44.3c10-10 89.7-89.7 99.7-99.8 14.3-14.3 37.6-14.3 51.9 0 12.8 12.8 17 35-3.5 55.4l44 44.3c31.2-31.2 38.5-67.6 28.9-101.2 29.2-4.1 51.9-29.2 51.9-59.5 0-33.2-26.8-60.1-59.8-60.1-30.3 0-55.4 22.5-59.5 51.6-33.8-9.9-71.7-1.5-98.3 25.1-18.3 19.1-71.1 71.5-99.6 99.9zm266.3 152.2c8.2-32.7-.9-68.5-26.3-93.9-11.8-12.2 5 4.7-99.5-99.7l-44.3 44.3 99.7 99.7c14.3 14.3 14.3 37.6 0 51.9-12.8 12.8-35 17-55.4-3.5l-44 44.3c27.6 30.2 68 38.8 102.7 28 5.5 27.4 29.7 48.1 58.9 48.1 33 0 59.8-26.8 59.8-60.1 0-30.2-22.5-55-51.6-59.1zm-84.3-53.1l-44-44.3c-87 86.4-50.4 50.4-99.7 99.8-14.3 14.3-37.6 14.3-51.9 0-13.1-13.4-16.9-35.3 3.2-55.4l-44-44.3c-30.2 30.2-38 65.2-29.5 98.3-26.7 6-46.2 29.9-46.2 58.2C0 453.2 26.8 480 59.8 480c28.6 0 52.5-19.8 58.6-46.7 32.7 8.2 68.5-.6 94.2-26 32.1-32 12.2-12.4 99.5-99.7z" } }, "free": ["brands"] }, "js": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3b8", "label": "JavaScript (JS)", "voted": false, "svg": { "brands": { "last_modified": 1660014462, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M0 32v448h448V32H0zm243.8 349.4c0 43.6-25.6 63.5-62.9 63.5-33.7 0-53.2-17.4-63.2-38.5l34.3-20.7c6.6 11.7 12.6 21.6 27.1 21.6 13.8 0 22.6-5.4 22.6-26.5V237.7h42.1v143.7zm99.6 63.5c-39.1 0-64.4-18.6-76.7-43l34.3-19.8c9 14.7 20.8 25.6 41.5 25.6 17.4 0 28.6-8.7 28.6-20.8 0-14.4-11.4-19.5-30.7-28l-10.5-4.5c-30.4-12.9-50.5-29.2-50.5-63.5 0-31.6 24.1-55.6 61.6-55.6 26.8 0 46 9.3 59.8 33.7L368 290c-7.2-12.9-15-18-27.1-18-12.3 0-20.1 7.8-20.1 18 0 12.6 7.8 17.7 25.9 25.6l10.5 4.5c35.8 15.3 55.9 31 55.9 66.2 0 37.8-29.8 58.6-69.7 58.6z" } }, "free": ["brands"] }, "jsfiddle": { "changes": ["4.1.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f1cc", "label": "jsFiddle", "voted": false, "svg": { "brands": { "last_modified": 1660014472, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M510.634 237.462c-4.727-2.621-5.664-5.748-6.381-10.776-2.352-16.488-3.539-33.619-9.097-49.095-35.895-99.957-153.99-143.386-246.849-91.646-27.37 15.25-48.971 36.369-65.493 63.903-3.184-1.508-5.458-2.71-7.824-3.686-30.102-12.421-59.049-10.121-85.331 9.167-25.531 18.737-36.422 44.548-32.676 76.408.355 3.025-1.967 7.621-4.514 9.545-39.712 29.992-56.031 78.065-41.902 124.615 13.831 45.569 57.514 79.796 105.608 81.433 30.291 1.031 60.637.546 90.959.539 84.041-.021 168.09.531 252.12-.48 52.664-.634 96.108-36.873 108.212-87.293 11.54-48.074-11.144-97.3-56.832-122.634zm21.107 156.88c-18.23 22.432-42.343 35.253-71.28 35.65-56.874.781-113.767.23-170.652.23 0 .7-163.028.159-163.728.154-43.861-.332-76.739-19.766-95.175-59.995-18.902-41.245-4.004-90.848 34.186-116.106 9.182-6.073 12.505-11.566 10.096-23.136-5.49-26.361 4.453-47.956 26.42-62.981 22.987-15.723 47.422-16.146 72.034-3.083 10.269 5.45 14.607 11.564 22.198-2.527 14.222-26.399 34.557-46.727 60.671-61.294 97.46-54.366 228.37 7.568 230.24 132.697.122 8.15 2.412 12.428 9.848 15.894 57.56 26.829 74.456 96.122 35.142 144.497zm-87.789-80.499c-5.848 31.157-34.622 55.096-66.666 55.095-16.953-.001-32.058-6.545-44.079-17.705-27.697-25.713-71.141-74.98-95.937-93.387-20.056-14.888-41.99-12.333-60.272 3.782-49.996 44.071 15.859 121.775 67.063 77.188 4.548-3.96 7.84-9.543 12.744-12.844 8.184-5.509 20.766-.884 13.168 10.622-17.358 26.284-49.33 38.197-78.863 29.301-28.897-8.704-48.84-35.968-48.626-70.179 1.225-22.485 12.364-43.06 35.414-55.965 22.575-12.638 46.369-13.146 66.991 2.474C295.68 280.7 320.467 323.97 352.185 343.47c24.558 15.099 54.254 7.363 68.823-17.506 28.83-49.209-34.592-105.016-78.868-63.46-3.989 3.744-6.917 8.932-11.41 11.72-10.975 6.811-17.333-4.113-12.809-10.353 20.703-28.554 50.464-40.44 83.271-28.214 31.429 11.714 49.108 44.366 42.76 78.186z" } }, "free": ["brands"] }, "jug-detergent": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["detergent", "laundry", "soap", "wash"] }, "styles": ["solid"], "unicode": "e519", "label": "Jug Detergent", "voted": false, "svg": { "solid": { "last_modified": 1684767441, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M96 24c0-13.3 10.7-24 24-24h80c13.3 0 24 10.7 24 24V48h8c13.3 0 24 10.7 24 24s-10.7 24-24 24H88C74.7 96 64 85.3 64 72s10.7-24 24-24h8V24zM0 256c0-70.7 57.3-128 128-128H256c70.7 0 128 57.3 128 128V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V256zm256 0v96c0 17.7 14.3 32 32 32s32-14.3 32-32V256c0-17.7-14.3-32-32-32s-32 14.3-32 32z" } }, "free": ["solid"] }, "k": { "aliases": { "unicodes": { "composite": ["6b"] } }, "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Latin Capital Letter K", "Latin Small Letter K", "letter"] }, "styles": ["solid"], "unicode": "4b", "label": "K", "voted": false, "svg": { "solid": { "last_modified": 1684767247, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M311 86.3c12.3-12.7 12-32.9-.7-45.2s-32.9-12-45.2 .7l-155.2 160L64 249V64c0-17.7-14.3-32-32-32S0 46.3 0 64V328 448c0 17.7 14.3 32 32 32s32-14.3 32-32V341l64.7-66.7 133 192c10.1 14.5 30 18.1 44.5 8.1s18.1-30 8.1-44.5L174.1 227.4 311 86.3z" } }, "free": ["solid"] }, "kaaba": { "aliases": { "unicodes": { "composite": ["1f54b"], "secondary": ["10f66b"] } }, "changes": [ "5.3.0", "6.0.0-beta1", "6.0.0-beta3", "6.1.2", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Muslim", "building", "cube", "islam", "kaaba", "muslim", "religion" ] }, "styles": ["solid"], "unicode": "f66b", "label": "Kaaba", "voted": false, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M60 120l228 71.2L516 120 288 48.8 60 120zM278.5 1.5c6.2-1.9 12.9-1.9 19.1 0l256 80C566.9 85.6 576 98 576 112v16 0 21.2L292.8 237.7c-3.1 1-6.4 1-9.5 0L0 149.2V128 112C0 98 9.1 85.6 22.5 81.5l256-80zm23.9 266.8L576 182.8v46.5l-52.8 16.5c-8.4 2.6-13.1 11.6-10.5 20s11.6 13.1 20 10.5L576 262.8V400c0 14-9.1 26.4-22.5 30.5l-256 80c-6.2 1.9-12.9 1.9-19.1 0l-256-80C9.1 426.4 0 414 0 400V262.8l43.2 13.5c8.4 2.6 17.4-2.1 20-10.5s-2.1-17.4-10.5-20L0 229.2V182.8l273.7 85.5c9.3 2.9 19.3 2.9 28.6 0zm-185.5-2.6c-8.4-2.6-17.4 2.1-20 10.5s2.1 17.4 10.5 20l64 20c8.4 2.6 17.4-2.1 20-10.5s-2.1-17.4-10.5-20l-64-20zm352 30.5c8.4-2.6 13.1-11.6 10.5-20s-11.6-13.1-20-10.5l-64 20c-8.4 2.6-13.1 11.6-10.5 20s11.6 13.1 20 10.5l64-20zm-224 9.5c-8.4-2.6-17.4 2.1-20 10.5s2.1 17.4 10.5 20l38.5 12c9.3 2.9 19.3 2.9 28.6 0l38.5-12c8.4-2.6 13.1-11.6 10.5-20s-11.6-13.1-20-10.5l-38.5 12c-3.1 1-6.4 1-9.5 0l-38.5-12z" } }, "free": ["solid"] }, "kaggle": { "changes": ["5.2.0", "5.8.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f5fa", "label": "Kaggle", "voted": true, "svg": { "brands": { "last_modified": 1660014463, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M304.2 501.5L158.4 320.3 298.2 185c2.6-2.7 1.7-10.5-5.3-10.5h-69.2c-3.5 0-7 1.8-10.5 5.3L80.9 313.5V7.5q0-7.5-7.5-7.5H21.5Q14 0 14 7.5v497q0 7.5 7.5 7.5h51.9q7.5 0 7.5-7.5v-109l30.8-29.3 110.5 140.6c3 3.5 6.5 5.3 10.5 5.3h66.9q5.25 0 6-3z" } }, "free": ["brands"] }, "key": { "aliases": { "unicodes": { "composite": ["1f511"], "secondary": ["10f084"] } }, "changes": [ "1.0.0", "5.0.0", "5.10.1", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["key", "lock", "password", "private", "secret", "unlock"] }, "styles": ["solid"], "unicode": "f084", "label": "Key", "voted": false, "svg": { "solid": { "last_modified": 1684767368, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M336 352c97.2 0 176-78.8 176-176S433.2 0 336 0S160 78.8 160 176c0 18.7 2.9 36.8 8.3 53.7L7 391c-4.5 4.5-7 10.6-7 17v80c0 13.3 10.7 24 24 24h80c13.3 0 24-10.7 24-24V448h40c13.3 0 24-10.7 24-24V384h40c6.4 0 12.5-2.5 17-7l33.3-33.3c16.9 5.4 35 8.3 53.7 8.3zM376 96a40 40 0 1 1 0 80 40 40 0 1 1 0-80z" } }, "free": ["solid"] }, "keybase": { "changes": ["5.0.11", "5.8.0", "5.10.2", "5.11.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f4f5", "label": "Keybase", "voted": true, "svg": { "brands": { "last_modified": 1660014473, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M286.17 419a18 18 0 1 0 18 18 18 18 0 0 0-18-18zm111.92-147.6c-9.5-14.62-39.37-52.45-87.26-73.71q-9.1-4.06-18.38-7.27a78.43 78.43 0 0 0-47.88-104.13c-12.41-4.1-23.33-6-32.41-5.77-.6-2-1.89-11 9.4-35L198.66 32l-5.48 7.56c-8.69 12.06-16.92 23.55-24.34 34.89a51 51 0 0 0-8.29-1.25c-41.53-2.45-39-2.33-41.06-2.33-50.61 0-50.75 52.12-50.75 45.88l-2.36 36.68c-1.61 27 19.75 50.21 47.63 51.85l8.93.54a214 214 0 0 0-46.29 35.54C14 304.66 14 374 14 429.77v33.64l23.32-29.8a148.6 148.6 0 0 0 14.56 37.56c5.78 10.13 14.87 9.45 19.64 7.33 4.21-1.87 10-6.92 3.75-20.11a178.29 178.29 0 0 1-15.76-53.13l46.82-59.83-24.66 74.11c58.23-42.4 157.38-61.76 236.25-38.59 34.2 10.05 67.45.69 84.74-23.84.72-1 1.2-2.16 1.85-3.22a156.09 156.09 0 0 1 2.8 28.43c0 23.3-3.69 52.93-14.88 81.64-2.52 6.46 1.76 14.5 8.6 15.74 7.42 1.57 15.33-3.1 18.37-11.15C429 443 434 414 434 382.32c0-38.58-13-77.46-35.91-110.92zM142.37 128.58l-15.7-.93-1.39 21.79 13.13.78a93 93 0 0 0 .32 19.57l-22.38-1.34a12.28 12.28 0 0 1-11.76-12.79L107 119c1-12.17 13.87-11.27 13.26-11.32l29.11 1.73a144.35 144.35 0 0 0-7 19.17zm148.42 172.18a10.51 10.51 0 0 1-14.35-1.39l-9.68-11.49-34.42 27a8.09 8.09 0 0 1-11.13-1.08l-15.78-18.64a7.38 7.38 0 0 1 1.34-10.34l34.57-27.18-14.14-16.74-17.09 13.45a7.75 7.75 0 0 1-10.59-1s-3.72-4.42-3.8-4.53a7.38 7.38 0 0 1 1.37-10.34L214 225.19s-18.51-22-18.6-22.14a9.56 9.56 0 0 1 1.74-13.42 10.38 10.38 0 0 1 14.3 1.37l81.09 96.32a9.58 9.58 0 0 1-1.74 13.44zM187.44 419a18 18 0 1 0 18 18 18 18 0 0 0-18-18z" } }, "free": ["brands"] }, "keyboard": { "aliases": { "unicodes": { "composite": ["2328"], "secondary": ["10f11c"] } }, "changes": ["3.1.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "accessory", "computer", "edit", "input", "keyboard", "text", "type", "write" ] }, "styles": ["solid", "regular"], "unicode": "f11c", "label": "Keyboard", "voted": false, "svg": { "solid": { "last_modified": 1684767342, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M64 64C28.7 64 0 92.7 0 128V384c0 35.3 28.7 64 64 64H512c35.3 0 64-28.7 64-64V128c0-35.3-28.7-64-64-64H64zm16 64h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V144c0-8.8 7.2-16 16-16zM64 240c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V240zm16 80h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V336c0-8.8 7.2-16 16-16zm80-176c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16V144zm16 80h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16V240c0-8.8 7.2-16 16-16zM160 336c0-8.8 7.2-16 16-16H400c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16V336zM272 128h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H272c-8.8 0-16-7.2-16-16V144c0-8.8 7.2-16 16-16zM256 240c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H272c-8.8 0-16-7.2-16-16V240zM368 128h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H368c-8.8 0-16-7.2-16-16V144c0-8.8 7.2-16 16-16zM352 240c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H368c-8.8 0-16-7.2-16-16V240zM464 128h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H464c-8.8 0-16-7.2-16-16V144c0-8.8 7.2-16 16-16zM448 240c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H464c-8.8 0-16-7.2-16-16V240zm16 80h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H464c-8.8 0-16-7.2-16-16V336c0-8.8 7.2-16 16-16z" }, "regular": { "last_modified": 1684767342, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M64 112c-8.8 0-16 7.2-16 16V384c0 8.8 7.2 16 16 16H512c8.8 0 16-7.2 16-16V128c0-8.8-7.2-16-16-16H64zM0 128C0 92.7 28.7 64 64 64H512c35.3 0 64 28.7 64 64V384c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128zM176 320H400c8.8 0 16 7.2 16 16v16c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16V336c0-8.8 7.2-16 16-16zm-72-72c0-8.8 7.2-16 16-16h16c8.8 0 16 7.2 16 16v16c0 8.8-7.2 16-16 16H120c-8.8 0-16-7.2-16-16V248zm16-96h16c8.8 0 16 7.2 16 16v16c0 8.8-7.2 16-16 16H120c-8.8 0-16-7.2-16-16V168c0-8.8 7.2-16 16-16zm64 96c0-8.8 7.2-16 16-16h16c8.8 0 16 7.2 16 16v16c0 8.8-7.2 16-16 16H200c-8.8 0-16-7.2-16-16V248zm16-96h16c8.8 0 16 7.2 16 16v16c0 8.8-7.2 16-16 16H200c-8.8 0-16-7.2-16-16V168c0-8.8 7.2-16 16-16zm64 96c0-8.8 7.2-16 16-16h16c8.8 0 16 7.2 16 16v16c0 8.8-7.2 16-16 16H280c-8.8 0-16-7.2-16-16V248zm16-96h16c8.8 0 16 7.2 16 16v16c0 8.8-7.2 16-16 16H280c-8.8 0-16-7.2-16-16V168c0-8.8 7.2-16 16-16zm64 96c0-8.8 7.2-16 16-16h16c8.8 0 16 7.2 16 16v16c0 8.8-7.2 16-16 16H360c-8.8 0-16-7.2-16-16V248zm16-96h16c8.8 0 16 7.2 16 16v16c0 8.8-7.2 16-16 16H360c-8.8 0-16-7.2-16-16V168c0-8.8 7.2-16 16-16zm64 96c0-8.8 7.2-16 16-16h16c8.8 0 16 7.2 16 16v16c0 8.8-7.2 16-16 16H440c-8.8 0-16-7.2-16-16V248zm16-96h16c8.8 0 16 7.2 16 16v16c0 8.8-7.2 16-16 16H440c-8.8 0-16-7.2-16-16V168c0-8.8 7.2-16 16-16z" } }, "free": ["regular", "solid"] }, "keycdn": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3ba", "label": "KeyCDN", "voted": false, "svg": { "brands": { "last_modified": 1660014472, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M63.8 409.3l60.5-59c32.1 42.8 71.1 66 126.6 67.4 30.5.7 60.3-7 86.4-22.4 5.1 5.3 18.5 19.5 20.9 22-32.2 20.7-69.6 31.1-108.1 30.2-43.3-1.1-84.6-16.7-117.7-44.4.3-.6-38.2 37.5-38.6 37.9 9.5 29.8-13.1 62.4-46.3 62.4C20.7 503.3 0 481.7 0 454.9c0-34.3 33.1-56.6 63.8-45.6zm354.9-252.4c19.1 31.3 29.6 67.4 28.7 104-1.1 44.8-19 87.5-48.6 121 .3.3 23.8 25.2 24.1 25.5 9.6-1.3 19.2 2 25.9 9.1 11.3 12 10.9 30.9-1.1 42.4-12 11.3-30.9 10.9-42.4-1.1-6.7-7-9.4-16.8-7.6-26.3-24.9-26.6-44.4-47.2-44.4-47.2 42.7-34.1 63.3-79.6 64.4-124.2.7-28.9-7.2-57.2-21.1-82.2l22.1-21zM104 53.1c6.7 7 9.4 16.8 7.6 26.3l45.9 48.1c-4.7 3.8-13.3 10.4-22.8 21.3-25.4 28.5-39.6 64.8-40.7 102.9-.7 28.9 6.1 57.2 20 82.4l-22 21.5C72.7 324 63.1 287.9 64.2 250.9c1-44.6 18.3-87.6 47.5-121.1l-25.3-26.4c-9.6 1.3-19.2-2-25.9-9.1-11.3-12-10.9-30.9 1.1-42.4C73.5 40.7 92.2 41 104 53.1zM464.9 8c26 0 47.1 22.4 47.1 48.3S490.9 104 464.9 104c-6.3.1-14-1.1-15.9-1.8l-62.9 59.7c-32.7-43.6-76.7-65.9-126.9-67.2-30.5-.7-60.3 6.8-86.2 22.4l-21.1-22C184.1 74.3 221.5 64 260 64.9c43.3 1.1 84.6 16.7 117.7 44.6l41.1-38.6c-1.5-4.7-2.2-9.6-2.2-14.5C416.5 29.7 438.9 8 464.9 8zM256.7 113.4c5.5 0 10.9.4 16.4 1.1 78.1 9.8 133.4 81.1 123.8 159.1-9.8 78.1-81.1 133.4-159.1 123.8-78.1-9.8-133.4-81.1-123.8-159.2 9.3-72.4 70.1-124.6 142.7-124.8zm-59 119.4c.6 22.7 12.2 41.8 32.4 52.2l-11 51.7h73.7l-11-51.7c20.1-10.9 32.1-29 32.4-52.2-.4-32.8-25.8-57.5-58.3-58.3-32.1.8-57.3 24.8-58.2 58.3zM256 160" } }, "free": ["brands"] }, "khanda": { "aliases": { "unicodes": { "composite": ["262c"], "secondary": ["10f66d"] } }, "changes": ["5.3.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Adi Shakti", "chakkar", "sikh", "sikhism", "sword"] }, "styles": ["solid"], "unicode": "f66d", "label": "Khanda", "voted": false, "svg": { "solid": { "last_modified": 1684767602, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M245.8 3.7c5.9-4.9 14.6-4.9 20.5 0l48 40c5.9 4.9 7.5 13.2 3.8 19.9l0 0 0 0 0 0 0 0-.1 .1-.3 .6c-.3 .5-.7 1.3-1.2 2.3c-1 2-2.6 5-4.4 8.6c-.5 .9-.9 1.9-1.4 2.9C344.9 97.4 368 134 368 176s-23.1 78.6-57.3 97.8c.5 1 1 2 1.4 2.9c1.8 3.7 3.3 6.6 4.4 8.6c.5 1 .9 1.8 1.2 2.3l.3 .6 .1 .1 0 0 0 0c3.6 6.7 2 15-3.8 19.9L272 343.5v19.8l35.6-24.5 41.1-28.2c42.8-29.4 68.4-78 68.4-130c0-31.1-9.2-61.6-26.5-87.5l-2.8-4.2c-4-6-3.5-14 1.3-19.5s12.7-7 19.2-3.7L401.1 80c7.2-14.3 7.2-14.3 7.2-14.3l0 0 0 0 .1 0 .3 .2 1 .5c.8 .4 2 1.1 3.5 1.9c2.9 1.7 7 4.1 11.8 7.3c9.6 6.4 22.5 16.1 35.4 29c25.7 25.7 52.7 65.6 52.7 119.3c0 53.1-26.4 100.5-51.2 133.6c-12.6 16.7-25.1 30.3-34.5 39.7c-4.7 4.7-8.7 8.4-11.5 10.9c-1.4 1.3-2.5 2.2-3.3 2.9l-.9 .8-.3 .2-.1 .1 0 0 0 0s0 0-10.2-12.3l10.2 12.3c-5.1 4.3-12.4 4.9-18.2 1.6l-75.6-43-32.7 22.5 45.5 31.3c1.8-.4 3.7-.7 5.7-.7c13.3 0 24 10.7 24 24s-10.7 24-24 24c-12.2 0-22.3-9.1-23.8-21L272 423.4v28.9c9.6 5.5 16 15.9 16 27.7c0 17.7-14.3 32-32 32s-32-14.3-32-32c0-11.8 6.4-22.2 16-27.7V424.1l-40.3 27.7C197.8 463.3 187.9 472 176 472c-13.3 0-24-10.7-24-24s10.7-24 24-24c2.2 0 4.4 .3 6.5 .9l45.8-31.5-32.7-22.5-75.6 43c-5.8 3.3-13 2.7-18.2-1.6L112 400c-10.2 12.3-10.2 12.3-10.3 12.3l0 0 0 0-.1-.1-.3-.2-.9-.8c-.8-.7-1.9-1.7-3.3-2.9c-2.8-2.5-6.7-6.2-11.5-10.9c-9.4-9.4-21.9-23-34.5-39.7C26.4 324.5 0 277.1 0 224c0-53.7 26.9-93.6 52.7-119.3c12.9-12.9 25.8-22.6 35.4-29C93 72.5 97 70 99.9 68.4c1.5-.8 2.6-1.5 3.5-1.9l1-.5 .3-.2 .1 0 0 0 0 0s0 0 7.2 14.3l-7.2-14.3c6.5-3.2 14.3-1.7 19.2 3.7s5.3 13.4 1.3 19.5l-2.8 4.2C105.2 119 96 149.5 96 180.6c0 51.9 25.6 100.6 68.4 130l41.1 28.2L240 362.6V343.5l-42.2-35.2c-5.9-4.9-7.5-13.2-3.8-19.9l0 0 0 0 0 0 .1-.1 .3-.6c.3-.5 .7-1.3 1.2-2.3c1-2 2.6-5 4.4-8.6c.5-.9 .9-1.9 1.4-2.9C167.1 254.6 144 218 144 176s23.1-78.6 57.3-97.8c-.5-1-1-2-1.4-2.9c-1.8-3.7-3.3-6.6-4.4-8.6c-.5-1-.9-1.8-1.2-2.3l-.3-.6-.1-.1 0 0 0 0 0 0c-3.6-6.7-2-15 3.8-19.9l48-40zM220.2 122.9c-17 11.5-28.2 31-28.2 53.1s11.2 41.6 28.2 53.1C227 210.2 232 190.9 232 176s-5-34.2-11.8-53.1zm71.5 106.2c17-11.5 28.2-31 28.2-53.1s-11.2-41.6-28.2-53.1C285 141.8 280 161.1 280 176s5 34.2 11.8 53.1z" } }, "free": ["solid"] }, "kickstarter": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3bb", "label": "Kickstarter", "voted": false, "svg": { "brands": { "last_modified": 1660014476, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M400 480H48c-26.4 0-48-21.6-48-48V80c0-26.4 21.6-48 48-48h352c26.4 0 48 21.6 48 48v352c0 26.4-21.6 48-48 48zM199.6 178.5c0-30.7-17.6-45.1-39.7-45.1-25.8 0-40 19.8-40 44.5v154.8c0 25.8 13.7 45.6 40.5 45.6 21.5 0 39.2-14 39.2-45.6v-41.8l60.6 75.7c12.3 14.9 39 16.8 55.8 0 14.6-15.1 14.8-36.8 4-50.4l-49.1-62.8 40.5-58.7c9.4-13.5 9.5-34.5-5.6-49.1-16.4-15.9-44.6-17.3-61.4 7l-44.8 64.7v-38.8z" } }, "free": ["brands"] }, "kickstarter-k": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3bc", "label": "Kickstarter K", "voted": false, "svg": { "brands": { "last_modified": 1660014464, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M147.3 114.4c0-56.2-32.5-82.4-73.4-82.4C26.2 32 0 68.2 0 113.4v283c0 47.3 25.3 83.4 74.9 83.4 39.8 0 72.4-25.6 72.4-83.4v-76.5l112.1 138.3c22.7 27.2 72.1 30.7 103.2 0 27-27.6 27.3-67.4 7.4-92.2l-90.8-114.8 74.9-107.4c17.4-24.7 17.5-63.1-10.4-89.8-30.3-29-82.4-31.6-113.6 12.8L147.3 185v-70.6z" } }, "free": ["brands"] }, "kip-sign": { "changes": ["6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Kip Sign", "currency"] }, "styles": ["solid"], "unicode": "e1c4", "label": "Kip Sign", "voted": false, "svg": { "solid": { "last_modified": 1684766474, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M340.8 88.3c13.4-11.5 15-31.7 3.5-45.1s-31.7-15-45.1-3.5L128 186.4V64c0-17.7-14.3-32-32-32S64 46.3 64 64V224H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H64V448c0 17.7 14.3 32 32 32s32-14.3 32-32V325.6L299.2 472.3c13.4 11.5 33.6 9.9 45.1-3.5s9.9-33.6-3.5-45.1L182.5 288H352c17.7 0 32-14.3 32-32s-14.3-32-32-32H182.5L340.8 88.3z" } }, "free": ["solid"] }, "kit-medical": { "aliases": { "names": ["first-aid"], "unicodes": { "secondary": ["10f479"] } }, "changes": ["5.0.7", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["emergency", "emt", "health", "medical", "rescue"] }, "styles": ["solid"], "unicode": "f479", "label": "Kit Medical", "voted": false, "svg": { "solid": { "last_modified": 1684767442, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H96V32H64zm64 0V480H448V32H128zM512 480c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H480V480h32zM256 176c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v48h48c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H320v48c0 8.8-7.2 16-16 16H272c-8.8 0-16-7.2-16-16V288H208c-8.8 0-16-7.2-16-16V240c0-8.8 7.2-16 16-16h48V176z" } }, "free": ["solid"] }, "kitchen-set": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["chef", "cook", "cup", "kitchen", "pan", "pot", "skillet"] }, "styles": ["solid"], "unicode": "e51a", "label": "Kitchen Set", "voted": false, "svg": { "solid": { "last_modified": 1684767420, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M240 144A96 96 0 1 0 48 144a96 96 0 1 0 192 0zm44.4 32C269.9 240.1 212.5 288 144 288C64.5 288 0 223.5 0 144S64.5 0 144 0c68.5 0 125.9 47.9 140.4 112h71.8c8.8-9.8 21.6-16 35.8-16H496c26.5 0 48 21.5 48 48s-21.5 48-48 48H392c-14.2 0-27-6.2-35.8-16H284.4zM144 80a64 64 0 1 1 0 128 64 64 0 1 1 0-128zM400 240c13.3 0 24 10.7 24 24v8h96c13.3 0 24 10.7 24 24s-10.7 24-24 24H280c-13.3 0-24-10.7-24-24s10.7-24 24-24h96v-8c0-13.3 10.7-24 24-24zM288 464V352H512V464c0 26.5-21.5 48-48 48H336c-26.5 0-48-21.5-48-48zM48 320h80 16 32c26.5 0 48 21.5 48 48s-21.5 48-48 48H160c0 17.7-14.3 32-32 32H64c-17.7 0-32-14.3-32-32V336c0-8.8 7.2-16 16-16zm128 64c8.8 0 16-7.2 16-16s-7.2-16-16-16H160v32h16zM24 464H200c13.3 0 24 10.7 24 24s-10.7 24-24 24H24c-13.3 0-24-10.7-24-24s10.7-24 24-24z" } }, "free": ["solid"] }, "kiwi-bird": { "aliases": { "unicodes": { "secondary": ["10f535"] } }, "changes": [ "5.0.13", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["bird", "fauna", "new zealand"] }, "styles": ["solid"], "unicode": "f535", "label": "Kiwi Bird", "voted": false, "svg": { "solid": { "last_modified": 1684768130, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M291.2 388.4c31.2-18.8 64.7-36.4 101.1-36.4H448c4.6 0 9.1-.2 13.6-.7l85.3 121.9c4 5.7 11.3 8.2 17.9 6.1s11.2-8.3 11.2-15.3V224c0-70.7-57.3-128-128-128H392.3c-36.4 0-69.9-17.6-101.1-36.4C262.3 42.1 228.3 32 192 32C86 32 0 118 0 224c0 71.1 38.6 133.1 96 166.3V456c0 13.3 10.7 24 24 24s24-10.7 24-24V410c15.3 3.9 31.4 6 48 6c5.4 0 10.7-.2 16-.7V456c0 13.3 10.7 24 24 24s24-10.7 24-24V405.1c12.4-4.4 24.2-10 35.2-16.7zM448 200a24 24 0 1 1 0 48 24 24 0 1 1 0-48z" } }, "free": ["solid"] }, "korvue": { "changes": ["5.0.2"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f42f", "label": "KORVUE", "voted": false, "svg": { "brands": { "last_modified": 1660014458, "raw": "", "viewBox": [0, 0, 446, 512], "width": 446, "height": 512, "path": "M386.5 34h-327C26.8 34 0 60.8 0 93.5v327.1C0 453.2 26.8 480 59.5 480h327.1c33 0 59.5-26.8 59.5-59.5v-327C446 60.8 419.2 34 386.5 34zM87.1 120.8h96v116l61.8-116h110.9l-81.2 132H87.1v-132zm161.8 272.1l-65.7-113.6v113.6h-96V262.1h191.5l88.6 130.8H248.9z" } }, "free": ["brands"] }, "l": { "aliases": { "unicodes": { "composite": ["6c"] } }, "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Latin Capital Letter L", "Latin Small Letter L", "letter"] }, "styles": ["solid"], "unicode": "4c", "label": "L", "voted": false, "svg": { "solid": { "last_modified": 1684767247, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M64 32c17.7 0 32 14.3 32 32V416H288c17.7 0 32 14.3 32 32s-14.3 32-32 32H64c-17.7 0-32-14.3-32-32V64c0-17.7 14.3-32 32-32z" } }, "free": ["solid"] }, "land-mine-on": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["bomb", "danger", "explosion", "war"] }, "styles": ["solid"], "unicode": "e51b", "label": "Land Mine On", "voted": false, "svg": { "solid": { "last_modified": 1684767443, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M344 24V168c0 13.3-10.7 24-24 24s-24-10.7-24-24V24c0-13.3 10.7-24 24-24s24 10.7 24 24zM192 320c0-17.7 14.3-32 32-32H416c17.7 0 32 14.3 32 32v32H192V320zm-77.3 90.5c8.1-16.3 24.8-26.5 42.9-26.5H482.3c18.2 0 34.8 10.3 42.9 26.5l27.6 55.2C563.5 487 548 512 524.2 512H115.8c-23.8 0-39.3-25-28.6-46.3l27.6-55.2zM36.3 138.3c7.5-10.9 22.5-13.6 33.4-6.1l104 72c10.9 7.5 13.6 22.5 6.1 33.4s-22.5 13.6-33.4 6.1l-104-72c-10.9-7.5-13.6-22.5-6.1-33.4zm534.1-6.1c10.9-7.5 25.8-4.8 33.4 6.1s4.8 25.8-6.1 33.4l-104 72c-10.9 7.5-25.8 4.8-33.4-6.1s-4.8-25.8 6.1-33.4l104-72z" } }, "free": ["solid"] }, "landmark": { "aliases": { "unicodes": { "composite": ["1f3db"], "secondary": ["10f66f"] } }, "changes": [ "5.3.0", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.1.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "building", "classical", "historic", "memorable", "monument", "museum", "politics" ] }, "styles": ["solid"], "unicode": "f66f", "label": "Landmark", "voted": false, "svg": { "solid": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M240.1 4.2c9.8-5.6 21.9-5.6 31.8 0l171.8 98.1L448 104l0 .9 47.9 27.4c12.6 7.2 18.8 22 15.1 36s-16.4 23.8-30.9 23.8H32c-14.5 0-27.2-9.8-30.9-23.8s2.5-28.8 15.1-36L64 104.9V104l4.4-1.6L240.1 4.2zM64 224h64V416h40V224h64V416h48V224h64V416h40V224h64V420.3c.6 .3 1.2 .7 1.8 1.1l48 32c11.7 7.8 17 22.4 12.9 35.9S494.1 512 480 512H32c-14.1 0-26.5-9.2-30.6-22.7s1.1-28.1 12.9-35.9l48-32c.6-.4 1.2-.7 1.8-1.1V224z" } }, "free": ["solid"] }, "landmark-dome": { "aliases": { "names": ["landmark-alt"], "unicodes": { "secondary": ["10f752"] } }, "changes": [ "5.5.0", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.1.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["building", "historic", "memorable", "monument", "politics"] }, "styles": ["solid"], "unicode": "f752", "label": "Landmark Dome", "voted": false, "svg": { "solid": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M248 0h16c13.3 0 24 10.7 24 24V34.7C368.4 48.1 431.9 111.6 445.3 192H448c17.7 0 32 14.3 32 32s-14.3 32-32 32H64c-17.7 0-32-14.3-32-32s14.3-32 32-32h2.7C80.1 111.6 143.6 48.1 224 34.7V24c0-13.3 10.7-24 24-24zM64 288h64V416h40V288h64V416h48V288h64V416h40V288h64V420.3c.6 .3 1.2 .7 1.7 1.1l48 32c11.7 7.8 17 22.4 12.9 35.9S494.1 512 480 512H32c-14.1 0-26.5-9.2-30.6-22.7s1.1-28.1 12.9-35.9l48-32c.6-.4 1.2-.7 1.8-1.1V288z" } }, "free": ["solid"] }, "landmark-flag": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["capitol", "flag", "landmark", "memorial"] }, "styles": ["solid"], "unicode": "e51c", "label": "Landmark Flag", "voted": false, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M272 0h80c8.8 0 16 7.2 16 16V80c0 8.8-7.2 16-16 16H272v32H464c17.7 0 32 14.3 32 32s-14.3 32-32 32H48c-17.7 0-32-14.3-32-32s14.3-32 32-32H240V16c0-8.8 7.2-16 16-16h16zM64 224h64V416h40V224h64V416h48V224h64V416h40V224h64V420.3c.6 .3 1.2 .7 1.8 1.1l48 32c11.7 7.8 17 22.4 12.9 35.9S494.1 512 480 512H32c-14.1 0-26.5-9.2-30.6-22.7s1.1-28.1 12.9-35.9l48-32c.6-.4 1.2-.7 1.8-1.1V224z" } }, "free": ["solid"] }, "language": { "aliases": { "unicodes": { "secondary": ["10f1ab"] } }, "changes": [ "4.1.0", "5.0.0", "5.10.2", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "dialect", "idiom", "localize", "speech", "translate", "vernacular" ] }, "styles": ["solid"], "unicode": "f1ab", "label": "Language", "voted": false, "svg": { "solid": { "last_modified": 1684767207, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M0 128C0 92.7 28.7 64 64 64H256h48 16H576c35.3 0 64 28.7 64 64V384c0 35.3-28.7 64-64 64H320 304 256 64c-35.3 0-64-28.7-64-64V128zm320 0V384H576V128H320zM178.3 175.9c-3.2-7.2-10.4-11.9-18.3-11.9s-15.1 4.7-18.3 11.9l-64 144c-4.5 10.1 .1 21.9 10.2 26.4s21.9-.1 26.4-10.2l8.9-20.1h73.6l8.9 20.1c4.5 10.1 16.3 14.6 26.4 10.2s14.6-16.3 10.2-26.4l-64-144zM160 233.2L179 276H141l19-42.8zM448 164c11 0 20 9 20 20v4h44 16c11 0 20 9 20 20s-9 20-20 20h-2l-1.6 4.5c-8.9 24.4-22.4 46.6-39.6 65.4c.9 .6 1.8 1.1 2.7 1.6l18.9 11.3c9.5 5.7 12.5 18 6.9 27.4s-18 12.5-27.4 6.9l-18.9-11.3c-4.5-2.7-8.8-5.5-13.1-8.5c-10.6 7.5-21.9 14-34 19.4l-3.6 1.6c-10.1 4.5-21.9-.1-26.4-10.2s.1-21.9 10.2-26.4l3.6-1.6c6.4-2.9 12.6-6.1 18.5-9.8l-12.2-12.2c-7.8-7.8-7.8-20.5 0-28.3s20.5-7.8 28.3 0l14.6 14.6 .5 .5c12.4-13.1 22.5-28.3 29.8-45H448 376c-11 0-20-9-20-20s9-20 20-20h52v-4c0-11 9-20 20-20z" } }, "free": ["solid"] }, "laptop": { "aliases": { "unicodes": { "composite": ["1f4bb"], "secondary": ["10f109"] } }, "changes": [ "3.0.0", "5.0.0", "5.2.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "computer", "cpu", "dell", "demo", "device", "laptop", "mac", "macbook", "machine", "pc", "personal" ] }, "styles": ["solid"], "unicode": "f109", "label": "Laptop", "voted": false, "svg": { "solid": { "last_modified": 1684767343, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M128 32C92.7 32 64 60.7 64 96V352h64V96H512V352h64V96c0-35.3-28.7-64-64-64H128zM19.2 384C8.6 384 0 392.6 0 403.2C0 445.6 34.4 480 76.8 480H563.2c42.4 0 76.8-34.4 76.8-76.8c0-10.6-8.6-19.2-19.2-19.2H19.2z" } }, "free": ["solid"] }, "laptop-code": { "aliases": { "unicodes": { "secondary": ["10f5fc"] } }, "changes": ["5.2.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "computer", "cpu", "dell", "demo", "develop", "device", "mac", "macbook", "machine", "pc" ] }, "styles": ["solid"], "unicode": "f5fc", "label": "Laptop Code", "voted": false, "svg": { "solid": { "last_modified": 1684767343, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M64 96c0-35.3 28.7-64 64-64H512c35.3 0 64 28.7 64 64V352H512V96H128V352H64V96zM0 403.2C0 392.6 8.6 384 19.2 384H620.8c10.6 0 19.2 8.6 19.2 19.2c0 42.4-34.4 76.8-76.8 76.8H76.8C34.4 480 0 445.6 0 403.2zM281 209l-31 31 31 31c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-48-48c-9.4-9.4-9.4-24.6 0-33.9l48-48c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9zM393 175l48 48c9.4 9.4 9.4 24.6 0 33.9l-48 48c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l31-31-31-31c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0z" } }, "free": ["solid"] }, "laptop-file": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["computer", "education", "laptop", "learning", "remote work"] }, "styles": ["solid"], "unicode": "e51d", "label": "Laptop File", "voted": false, "svg": { "solid": { "last_modified": 1684767342, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M128 0C92.7 0 64 28.7 64 64V288H19.2C8.6 288 0 296.6 0 307.2C0 349.6 34.4 384 76.8 384H320V288H128V64H448V96h64V64c0-35.3-28.7-64-64-64H128zM512 128H400c-26.5 0-48 21.5-48 48V464c0 26.5 21.5 48 48 48H592c26.5 0 48-21.5 48-48V256H544c-17.7 0-32-14.3-32-32V128zm32 0v96h96l-96-96z" } }, "free": ["solid"] }, "laptop-medical": { "aliases": { "unicodes": { "secondary": ["10f812"] } }, "changes": ["5.7.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "computer", "device", "ehr", "electronic health records", "history" ] }, "styles": ["solid"], "unicode": "f812", "label": "Laptop Medical", "voted": false, "svg": { "solid": { "last_modified": 1684767342, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M64 96c0-35.3 28.7-64 64-64H512c35.3 0 64 28.7 64 64V352H512V96H128V352H64V96zM0 403.2C0 392.6 8.6 384 19.2 384H620.8c10.6 0 19.2 8.6 19.2 19.2c0 42.4-34.4 76.8-76.8 76.8H76.8C34.4 480 0 445.6 0 403.2zM288 160c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v48h48c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H352v48c0 8.8-7.2 16-16 16H304c-8.8 0-16-7.2-16-16V272H240c-8.8 0-16-7.2-16-16V224c0-8.8 7.2-16 16-16h48V160z" } }, "free": ["solid"] }, "laravel": { "changes": ["5.0.0", "5.0.3", "5.11.2"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3bd", "label": "Laravel", "voted": false, "svg": { "brands": { "last_modified": 1660014475, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M504.4,115.83a5.72,5.72,0,0,0-.28-.68,8.52,8.52,0,0,0-.53-1.25,6,6,0,0,0-.54-.71,9.36,9.36,0,0,0-.72-.94c-.23-.22-.52-.4-.77-.6a8.84,8.84,0,0,0-.9-.68L404.4,55.55a8,8,0,0,0-8,0L300.12,111h0a8.07,8.07,0,0,0-.88.69,7.68,7.68,0,0,0-.78.6,8.23,8.23,0,0,0-.72.93c-.17.24-.39.45-.54.71a9.7,9.7,0,0,0-.52,1.25c-.08.23-.21.44-.28.68a8.08,8.08,0,0,0-.28,2.08V223.18l-80.22,46.19V63.44a7.8,7.8,0,0,0-.28-2.09c-.06-.24-.2-.45-.28-.68a8.35,8.35,0,0,0-.52-1.24c-.14-.26-.37-.47-.54-.72a9.36,9.36,0,0,0-.72-.94,9.46,9.46,0,0,0-.78-.6,9.8,9.8,0,0,0-.88-.68h0L115.61,1.07a8,8,0,0,0-8,0L11.34,56.49h0a6.52,6.52,0,0,0-.88.69,7.81,7.81,0,0,0-.79.6,8.15,8.15,0,0,0-.71.93c-.18.25-.4.46-.55.72a7.88,7.88,0,0,0-.51,1.24,6.46,6.46,0,0,0-.29.67,8.18,8.18,0,0,0-.28,2.1v329.7a8,8,0,0,0,4,6.95l192.5,110.84a8.83,8.83,0,0,0,1.33.54c.21.08.41.2.63.26a7.92,7.92,0,0,0,4.1,0c.2-.05.37-.16.55-.22a8.6,8.6,0,0,0,1.4-.58L404.4,400.09a8,8,0,0,0,4-6.95V287.88l92.24-53.11a8,8,0,0,0,4-7V117.92A8.63,8.63,0,0,0,504.4,115.83ZM111.6,17.28h0l80.19,46.15-80.2,46.18L31.41,63.44Zm88.25,60V278.6l-46.53,26.79-33.69,19.4V123.5l46.53-26.79Zm0,412.78L23.37,388.5V77.32L57.06,96.7l46.52,26.8V338.68a6.94,6.94,0,0,0,.12.9,8,8,0,0,0,.16,1.18h0a5.92,5.92,0,0,0,.38.9,6.38,6.38,0,0,0,.42,1v0a8.54,8.54,0,0,0,.6.78,7.62,7.62,0,0,0,.66.84l0,0c.23.22.52.38.77.58a8.93,8.93,0,0,0,.86.66l0,0,0,0,92.19,52.18Zm8-106.17-80.06-45.32,84.09-48.41,92.26-53.11,80.13,46.13-58.8,33.56Zm184.52,4.57L215.88,490.11V397.8L346.6,323.2l45.77-26.15Zm0-119.13L358.68,250l-46.53-26.79V131.79l33.69,19.4L392.37,178Zm8-105.28-80.2-46.17,80.2-46.16,80.18,46.15Zm8,105.28V178L455,151.19l33.68-19.4v91.39h0Z" } }, "free": ["brands"] }, "lari-sign": { "changes": ["6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Lari Sign", "currency"] }, "styles": ["solid"], "unicode": "e1c8", "label": "Lari Sign", "voted": false, "svg": { "solid": { "last_modified": 1684766476, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M144 32c17.7 0 32 14.3 32 32V96.7c5.3-.4 10.6-.7 16-.7s10.7 .2 16 .7V64c0-17.7 14.3-32 32-32s32 14.3 32 32v49.4c54.9 25.2 95.8 75.5 108.2 136.2c3.5 17.3-7.7 34.2-25 37.7s-34.2-7.7-37.7-25c-6.1-29.9-22.5-55.9-45.4-74.3V256c0 17.7-14.3 32-32 32s-32-14.3-32-32V161c-5.2-.7-10.6-1-16-1s-10.8 .3-16 1v95c0 17.7-14.3 32-32 32s-32-14.3-32-32V188.1C82.7 211.5 64 247.6 64 288c0 70.7 57.3 128 128 128H352c17.7 0 32 14.3 32 32s-14.3 32-32 32H192 32c-17.7 0-32-14.3-32-32s14.3-32 32-32H48.9C18.5 382 0 337.2 0 288c0-77.5 45.9-144.3 112-174.6V64c0-17.7 14.3-32 32-32z" } }, "free": ["solid"] }, "lastfm": { "changes": ["4.2.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f202", "label": "last.fm", "voted": false, "svg": { "brands": { "last_modified": 1660014483, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M225.8 367.1l-18.8-51s-30.5 34-76.2 34c-40.5 0-69.2-35.2-69.2-91.5 0-72.1 36.4-97.9 72.1-97.9 66.5 0 74.8 53.3 100.9 134.9 18.8 56.9 54 102.6 155.4 102.6 72.7 0 122-22.3 122-80.9 0-72.9-62.7-80.6-115-92.1-25.8-5.9-33.4-16.4-33.4-34 0-19.9 15.8-31.7 41.6-31.7 28.2 0 43.4 10.6 45.7 35.8l58.6-7c-4.7-52.8-41.1-74.5-100.9-74.5-52.8 0-104.4 19.9-104.4 83.9 0 39.9 19.4 65.1 68 76.8 44.9 10.6 79.8 13.8 79.8 45.7 0 21.7-21.1 30.5-61 30.5-59.2 0-83.9-31.1-97.9-73.9-32-96.8-43.6-163-161.3-163C45.7 113.8 0 168.3 0 261c0 89.1 45.7 137.2 127.9 137.2 66.2 0 97.9-31.1 97.9-31.1z" } }, "free": ["brands"] }, "layer-group": { "aliases": { "unicodes": { "secondary": ["10f5fd"] } }, "changes": ["5.2.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["arrange", "develop", "layers", "map", "stack"] }, "styles": ["solid"], "unicode": "f5fd", "label": "Layer Group", "voted": false, "svg": { "solid": { "last_modified": 1684767552, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M264.5 5.2c14.9-6.9 32.1-6.9 47 0l218.6 101c8.5 3.9 13.9 12.4 13.9 21.8s-5.4 17.9-13.9 21.8l-218.6 101c-14.9 6.9-32.1 6.9-47 0L45.9 149.8C37.4 145.8 32 137.3 32 128s5.4-17.9 13.9-21.8L264.5 5.2zM476.9 209.6l53.2 24.6c8.5 3.9 13.9 12.4 13.9 21.8s-5.4 17.9-13.9 21.8l-218.6 101c-14.9 6.9-32.1 6.9-47 0L45.9 277.8C37.4 273.8 32 265.3 32 256s5.4-17.9 13.9-21.8l53.2-24.6 152 70.2c23.4 10.8 50.4 10.8 73.8 0l152-70.2zm-152 198.2l152-70.2 53.2 24.6c8.5 3.9 13.9 12.4 13.9 21.8s-5.4 17.9-13.9 21.8l-218.6 101c-14.9 6.9-32.1 6.9-47 0L45.9 405.8C37.4 401.8 32 393.3 32 384s5.4-17.9 13.9-21.8l53.2-24.6 152 70.2c23.4 10.8 50.4 10.8 73.8 0z" } }, "free": ["solid"] }, "leaf": { "aliases": { "unicodes": { "secondary": ["10f06c"] } }, "changes": [ "1.0.0", "5.0.0", "5.0.9", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["eco", "flora", "nature", "plant", "vegan"] }, "styles": ["solid"], "unicode": "f06c", "label": "Leaf", "voted": false, "svg": { "solid": { "last_modified": 1684768130, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M272 96c-78.6 0-145.1 51.5-167.7 122.5c33.6-17 71.5-26.5 111.7-26.5h88c8.8 0 16 7.2 16 16s-7.2 16-16 16H288 216s0 0 0 0c-16.6 0-32.7 1.9-48.2 5.4c-25.9 5.9-50 16.4-71.4 30.7c0 0 0 0 0 0C38.3 298.8 0 364.9 0 440v16c0 13.3 10.7 24 24 24s24-10.7 24-24V440c0-48.7 20.7-92.5 53.8-123.2C121.6 392.3 190.3 448 272 448l1 0c132.1-.7 239-130.9 239-291.4c0-42.6-7.5-83.1-21.1-119.6c-2.6-6.9-12.7-6.6-16.2-.1C455.9 72.1 418.7 96 376 96L272 96z" } }, "free": ["solid"] }, "leanpub": { "changes": ["4.3.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f212", "label": "Leanpub", "voted": false, "svg": { "brands": { "last_modified": 1660014462, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M386.539 111.485l15.096 248.955-10.979-.275c-36.232-.824-71.64 8.783-102.657 27.997-31.016-19.214-66.424-27.997-102.657-27.997-45.564 0-82.07 10.705-123.516 27.723L93.117 129.6c28.546-11.803 61.484-18.115 92.226-18.115 41.173 0 73.836 13.175 102.657 42.544 27.723-28.271 59.013-41.721 98.539-42.544zM569.07 448c-25.526 0-47.485-5.215-70.542-15.645-34.31-15.645-69.993-24.978-107.871-24.978-38.977 0-74.934 12.901-102.657 40.623-27.723-27.723-63.68-40.623-102.657-40.623-37.878 0-73.561 9.333-107.871 24.978C55.239 442.236 32.731 448 8.303 448H6.93L49.475 98.859C88.726 76.626 136.486 64 181.775 64 218.83 64 256.984 71.685 288 93.095 319.016 71.685 357.17 64 394.225 64c45.289 0 93.049 12.626 132.3 34.859L569.07 448zm-43.368-44.741l-34.036-280.246c-30.742-13.999-67.248-21.41-101.009-21.41-38.428 0-74.385 12.077-102.657 38.702-28.272-26.625-64.228-38.702-102.657-38.702-33.761 0-70.267 7.411-101.009 21.41L50.298 403.259c47.211-19.487 82.894-33.486 135.045-33.486 37.604 0 70.817 9.606 102.657 29.644 31.84-20.038 65.052-29.644 102.657-29.644 52.151 0 87.834 13.999 135.045 33.486z" } }, "free": ["brands"] }, "left-long": { "aliases": { "names": ["long-arrow-alt-left"], "unicodes": { "secondary": ["10f30a"] } }, "changes": ["5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["back", "long-arrow-left", "previous"] }, "styles": ["solid"], "unicode": "f30a", "label": "Left Long", "voted": false, "svg": { "solid": { "last_modified": 1684766330, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M177.5 414c-8.8 3.8-19 2-26-4.6l-144-136C2.7 268.9 0 262.6 0 256s2.7-12.9 7.5-17.4l144-136c7-6.6 17.2-8.4 26-4.6s14.5 12.5 14.5 22l0 72 288 0c17.7 0 32 14.3 32 32l0 64c0 17.7-14.3 32-32 32l-288 0 0 72c0 9.6-5.7 18.2-14.5 22z" } }, "free": ["solid"] }, "left-right": { "aliases": { "names": ["arrows-alt-h"], "unicodes": { "composite": ["2194"], "secondary": ["10f337"] } }, "changes": ["5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "arrow", "arrows-h", "expand", "horizontal", "landscape", "left-right arrow", "resize", "wide" ] }, "styles": ["solid"], "unicode": "f337", "label": "Left Right", "voted": false, "svg": { "solid": { "last_modified": 1684766331, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M504.3 273.6c4.9-4.5 7.7-10.9 7.7-17.6s-2.8-13-7.7-17.6l-112-104c-7-6.5-17.2-8.2-25.9-4.4s-14.4 12.5-14.4 22l0 56-192 0 0-56c0-9.5-5.7-18.2-14.4-22s-18.9-2.1-25.9 4.4l-112 104C2.8 243 0 249.3 0 256s2.8 13 7.7 17.6l112 104c7 6.5 17.2 8.2 25.9 4.4s14.4-12.5 14.4-22l0-56 192 0 0 56c0 9.5 5.7 18.2 14.4 22s18.9 2.1 25.9-4.4l112-104z" } }, "free": ["solid"] }, "lemon": { "aliases": { "unicodes": { "composite": ["1f34b"], "secondary": ["10f094"] } }, "changes": ["1.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["citrus", "fruit", "lemon", "lemonade", "lime", "tart"] }, "styles": ["solid", "regular"], "unicode": "f094", "label": "Lemon", "voted": false, "svg": { "solid": { "last_modified": 1684767420, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M448 96c0-35.3-28.7-64-64-64c-6.6 0-13 1-19 2.9c-22.5 7-48.1 14.9-71 9c-75.2-19.1-156.4 11-213.7 68.3S-7.2 250.8 11.9 326c5.8 22.9-2 48.4-9 71C1 403 0 409.4 0 416c0 35.3 28.7 64 64 64c6.6 0 13-1 19.1-2.9c22.5-7 48.1-14.9 71-9c75.2 19.1 156.4-11 213.7-68.3s87.5-138.5 68.3-213.7c-5.8-22.9 2-48.4 9-71c1.9-6 2.9-12.4 2.9-19.1zM212.5 127.4c-54.6 16-101.1 62.5-117.1 117.1C92.9 253 84 257.8 75.5 255.4S62.2 244 64.6 235.5c19.1-65.1 73.7-119.8 138.9-138.9c8.5-2.5 17.4 2.4 19.9 10.9s-2.4 17.4-10.9 19.9z" }, "regular": { "last_modified": 1684767420, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M368 80c-3.2 0-6.2 .4-8.9 1.3C340 86.8 313 91.9 284.8 84.6C227.4 69.7 160.2 92 110.1 142.1S37.7 259.4 52.6 316.8c7.3 28.2 2.2 55.2-3.3 74.3c-.8 2.8-1.3 5.8-1.3 8.9c0 17.7 14.3 32 32 32c3.2 0 6.2-.4 8.9-1.3c19.1-5.5 46.1-10.7 74.3-3.3c57.4 14.9 124.6-7.4 174.7-57.5s72.4-117.3 57.5-174.7c-7.3-28.2-2.2-55.2 3.3-74.3c.8-2.8 1.3-5.8 1.3-8.9c0-17.7-14.3-32-32-32zm0-48c44.2 0 80 35.8 80 80c0 7.7-1.1 15.2-3.1 22.3c-4.6 15.8-7.1 32.9-3 48.9c20.1 77.6-10.9 161.5-70 220.7s-143.1 90.2-220.7 70c-16-4.1-33-1.6-48.9 3c-7.1 2-14.6 3.1-22.3 3.1c-44.2 0-80-35.8-80-80c0-7.7 1.1-15.2 3.1-22.3c4.6-15.8 7.1-32.9 3-48.9C-14 251.3 17 167.3 76.2 108.2S219.3 18 296.8 38.1c16 4.1 33 1.6 48.9-3c7.1-2 14.6-3.1 22.3-3.1zM246.7 167c-52 15.2-96.5 59.7-111.7 111.7c-3.7 12.7-17.1 20-29.8 16.3s-20-17.1-16.3-29.8c19.8-67.7 76.6-124.5 144.3-144.3c12.7-3.7 26.1 3.6 29.8 16.3s-3.6 26.1-16.3 29.8z" } }, "free": ["regular", "solid"] }, "less": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f41d", "label": "Less", "voted": false, "svg": { "brands": { "last_modified": 1660014471, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M612.7 219c0-20.5 3.2-32.6 3.2-54.6 0-34.2-12.6-45.2-40.5-45.2h-20.5v24.2h6.3c14.2 0 17.3 4.7 17.3 22.1 0 16.3-1.6 32.6-1.6 51.5 0 24.2 7.9 33.6 23.6 37.3v1.6c-15.8 3.7-23.6 13.1-23.6 37.3 0 18.9 1.6 34.2 1.6 51.5 0 17.9-3.7 22.6-17.3 22.6v.5h-6.3V393h20.5c27.8 0 40.5-11 40.5-45.2 0-22.6-3.2-34.2-3.2-54.6 0-11 6.8-22.6 27.3-23.6v-27.3c-20.5-.7-27.3-12.3-27.3-23.3zm-105.6 32c-15.8-6.3-30.5-10-30.5-20.5 0-7.9 6.3-12.6 17.9-12.6s22.1 4.7 33.6 13.1l21-27.8c-13.1-10-31-20.5-55.2-20.5-35.7 0-59.9 20.5-59.9 49.4 0 25.7 22.6 38.9 41.5 46.2 16.3 6.3 32.1 11.6 32.1 22.1 0 7.9-6.3 13.1-20.5 13.1-13.1 0-26.3-5.3-40.5-16.3l-21 30.5c15.8 13.1 39.9 22.1 59.9 22.1 42 0 64.6-22.1 64.6-51s-22.5-41-43-47.8zm-358.9 59.4c-3.7 0-8.4-3.2-8.4-13.1V119.1H65.2c-28.4 0-41 11-41 45.2 0 22.6 3.2 35.2 3.2 54.6 0 11-6.8 22.6-27.3 23.6v27.3c20.5.5 27.3 12.1 27.3 23.1 0 19.4-3.2 31-3.2 53.6 0 34.2 12.6 45.2 40.5 45.2h20.5v-24.2h-6.3c-13.1 0-17.3-5.3-17.3-22.6s1.6-32.1 1.6-51.5c0-24.2-7.9-33.6-23.6-37.3v-1.6c15.8-3.7 23.6-13.1 23.6-37.3 0-18.9-1.6-34.2-1.6-51.5s3.7-22.1 17.3-22.1H93v150.8c0 32.1 11 53.1 43.1 53.1 10 0 17.9-1.6 23.6-3.7l-5.3-34.2c-3.1.8-4.6.8-6.2.8zM379.9 251c-16.3-6.3-31-10-31-20.5 0-7.9 6.3-12.6 17.9-12.6 11.6 0 22.1 4.7 33.6 13.1l21-27.8c-13.1-10-31-20.5-55.2-20.5-35.7 0-59.9 20.5-59.9 49.4 0 25.7 22.6 38.9 41.5 46.2 16.3 6.3 32.1 11.6 32.1 22.1 0 7.9-6.3 13.1-20.5 13.1-13.1 0-26.3-5.3-40.5-16.3l-20.5 30.5c15.8 13.1 39.9 22.1 59.9 22.1 42 0 64.6-22.1 64.6-51 .1-28.9-22.5-41-43-47.8zm-155-68.8c-38.4 0-75.1 32.1-74.1 82.5 0 52 34.2 82.5 79.3 82.5 18.9 0 39.9-6.8 56.2-17.9l-15.8-27.8c-11.6 6.8-22.6 10-34.2 10-21 0-37.3-10-41.5-34.2H290c.5-3.7 1.6-11 1.6-19.4.6-42.6-22.6-75.7-66.7-75.7zm-30 66.2c3.2-21 15.8-31 30.5-31 18.9 0 26.3 13.1 26.3 31h-56.8z" } }, "free": ["brands"] }, "less-than": { "aliases": { "unicodes": { "composite": ["f536"], "primary": ["f536"], "secondary": ["103c", "10f536"] } }, "changes": ["5.0.13", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Less-Than Sign", "arithmetic", "compare", "math"] }, "styles": ["solid"], "unicode": "3c", "label": "Less Than", "voted": true, "svg": { "solid": { "last_modified": 1684767245, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M380.6 81.7c7.9 15.8 1.5 35-14.3 42.9L103.6 256 366.3 387.4c15.8 7.9 22.2 27.1 14.3 42.9s-27.1 22.2-42.9 14.3l-320-160C6.8 279.2 0 268.1 0 256s6.8-23.2 17.7-28.6l320-160c15.8-7.9 35-1.5 42.9 14.3z" } }, "free": ["solid"] }, "less-than-equal": { "aliases": { "unicodes": { "secondary": ["10f537"] } }, "changes": ["5.0.13", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["arithmetic", "compare", "math"] }, "styles": ["solid"], "unicode": "f537", "label": "Less Than Equal", "voted": true, "svg": { "solid": { "last_modified": 1684767246, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M395.9 93.7c16.4-6.6 24.4-25.2 17.8-41.6s-25.2-24.4-41.6-17.8l-320 128C40 167.1 32 178.9 32 192s8 24.9 20.1 29.7l320 128c16.4 6.6 35-1.4 41.6-17.8s-1.4-35-17.8-41.6L150.2 192 395.9 93.7zM32 416c-17.7 0-32 14.3-32 32s14.3 32 32 32H416c17.7 0 32-14.3 32-32s-14.3-32-32-32H32z" } }, "free": ["solid"] }, "life-ring": { "aliases": { "unicodes": { "secondary": ["10f1cd"] } }, "changes": [ "4.1.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["coast guard", "help", "overboard", "save", "support"] }, "styles": ["solid", "regular"], "unicode": "f1cd", "label": "Life Ring", "voted": false, "svg": { "solid": { "last_modified": 1684767636, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M367.2 412.5C335.9 434.9 297.5 448 256 448s-79.9-13.1-111.2-35.5l58-58c15.8 8.6 34 13.5 53.3 13.5s37.4-4.9 53.3-13.5l58 58zm90.7 .8c33.8-43.4 54-98 54-157.3s-20.2-113.9-54-157.3c9-12.5 7.9-30.1-3.4-41.3S425.8 45 413.3 54C369.9 20.2 315.3 0 256 0S142.1 20.2 98.7 54c-12.5-9-30.1-7.9-41.3 3.4S45 86.2 54 98.7C20.2 142.1 0 196.7 0 256s20.2 113.9 54 157.3c-9 12.5-7.9 30.1 3.4 41.3S86.2 467 98.7 458c43.4 33.8 98 54 157.3 54s113.9-20.2 157.3-54c12.5 9 30.1 7.9 41.3-3.4s12.4-28.8 3.4-41.3zm-45.5-46.1l-58-58c8.6-15.8 13.5-34 13.5-53.3s-4.9-37.4-13.5-53.3l58-58C434.9 176.1 448 214.5 448 256s-13.1 79.9-35.5 111.2zM367.2 99.5l-58 58c-15.8-8.6-34-13.5-53.3-13.5s-37.4 4.9-53.3 13.5l-58-58C176.1 77.1 214.5 64 256 64s79.9 13.1 111.2 35.5zM157.5 309.3l-58 58C77.1 335.9 64 297.5 64 256s13.1-79.9 35.5-111.2l58 58c-8.6 15.8-13.5 34-13.5 53.3s4.9 37.4 13.5 53.3zM208 256a48 48 0 1 1 96 0 48 48 0 1 1 -96 0z" }, "regular": { "last_modified": 1684767636, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M385.1 419.1C349.7 447.2 304.8 464 256 464s-93.7-16.8-129.1-44.9l80.4-80.4c14.3 8.4 31 13.3 48.8 13.3s34.5-4.8 48.8-13.3l80.4 80.4zm68.1 .2C489.9 374.9 512 318.1 512 256s-22.1-118.9-58.8-163.3L465 81c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0L419.3 58.8C374.9 22.1 318.1 0 256 0S137.1 22.1 92.7 58.8L81 47c-9.4-9.4-24.6-9.4-33.9 0s-9.4 24.6 0 33.9L58.8 92.7C22.1 137.1 0 193.9 0 256s22.1 118.9 58.8 163.3L47 431c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l11.8-11.8C137.1 489.9 193.9 512 256 512s118.9-22.1 163.3-58.8L431 465c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9l-11.8-11.8zm-34.1-34.1l-80.4-80.4c8.4-14.3 13.3-31 13.3-48.8s-4.8-34.5-13.3-48.8l80.4-80.4C447.2 162.3 464 207.2 464 256s-16.8 93.7-44.9 129.1zM385.1 92.9l-80.4 80.4c-14.3-8.4-31-13.3-48.8-13.3s-34.5 4.8-48.8 13.3L126.9 92.9C162.3 64.8 207.2 48 256 48s93.7 16.8 129.1 44.9zM173.3 304.8L92.9 385.1C64.8 349.7 48 304.8 48 256s16.8-93.7 44.9-129.1l80.4 80.4c-8.4 14.3-13.3 31-13.3 48.8s4.8 34.5 13.3 48.8zM208 256a48 48 0 1 1 96 0 48 48 0 1 1 -96 0z" } }, "free": ["regular", "solid"] }, "lightbulb": { "aliases": { "unicodes": { "composite": ["1f4a1"], "secondary": ["10f0eb"] } }, "changes": [ "3.0.0", "5.0.0", "5.3.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ " comic", " electric", " idea", " innovation", " inspiration", " light", " light bulb", " bulb", "bulb", "comic", "electric", "energy", "idea", "inspiration", "mechanical" ] }, "styles": ["solid", "regular"], "unicode": "f0eb", "label": "Lightbulb", "voted": false, "svg": { "solid": { "last_modified": 1684767444, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M272 384c9.6-31.9 29.5-59.1 49.2-86.2l0 0c5.2-7.1 10.4-14.2 15.4-21.4c19.8-28.5 31.4-63 31.4-100.3C368 78.8 289.2 0 192 0S16 78.8 16 176c0 37.3 11.6 71.9 31.4 100.3c5 7.2 10.2 14.3 15.4 21.4l0 0c19.8 27.1 39.7 54.4 49.2 86.2H272zM192 512c44.2 0 80-35.8 80-80V416H112v16c0 44.2 35.8 80 80 80zM112 176c0 8.8-7.2 16-16 16s-16-7.2-16-16c0-61.9 50.1-112 112-112c8.8 0 16 7.2 16 16s-7.2 16-16 16c-44.2 0-80 35.8-80 80z" }, "regular": { "last_modified": 1684767444, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M297.2 248.9C311.6 228.3 320 203.2 320 176c0-70.7-57.3-128-128-128S64 105.3 64 176c0 27.2 8.4 52.3 22.8 72.9c3.7 5.3 8.1 11.3 12.8 17.7l0 0c12.9 17.7 28.3 38.9 39.8 59.8c10.4 19 15.7 38.8 18.3 57.5H109c-2.2-12-5.9-23.7-11.8-34.5c-9.9-18-22.2-34.9-34.5-51.8l0 0 0 0c-5.2-7.1-10.4-14.2-15.4-21.4C27.6 247.9 16 213.3 16 176C16 78.8 94.8 0 192 0s176 78.8 176 176c0 37.3-11.6 71.9-31.4 100.3c-5 7.2-10.2 14.3-15.4 21.4l0 0 0 0c-12.3 16.8-24.6 33.7-34.5 51.8c-5.9 10.8-9.6 22.5-11.8 34.5H226.4c2.6-18.7 7.9-38.6 18.3-57.5c11.5-20.9 26.9-42.1 39.8-59.8l0 0 0 0 0 0c4.7-6.4 9-12.4 12.7-17.7zM192 128c-26.5 0-48 21.5-48 48c0 8.8-7.2 16-16 16s-16-7.2-16-16c0-44.2 35.8-80 80-80c8.8 0 16 7.2 16 16s-7.2 16-16 16zm0 384c-44.2 0-80-35.8-80-80V416H272v16c0 44.2-35.8 80-80 80z" } }, "free": ["regular", "solid"] }, "line": { "changes": ["5.0.0", "6.3.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3c0", "label": "Line", "voted": false, "svg": { "brands": { "last_modified": 1672840969, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M311 196.8v81.3c0 2.1-1.6 3.7-3.7 3.7h-13c-1.3 0-2.4-.7-3-1.5l-37.3-50.3v48.2c0 2.1-1.6 3.7-3.7 3.7h-13c-2.1 0-3.7-1.6-3.7-3.7V196.9c0-2.1 1.6-3.7 3.7-3.7h12.9c1.1 0 2.4 .6 3 1.6l37.3 50.3V196.9c0-2.1 1.6-3.7 3.7-3.7h13c2.1-.1 3.8 1.6 3.8 3.5zm-93.7-3.7h-13c-2.1 0-3.7 1.6-3.7 3.7v81.3c0 2.1 1.6 3.7 3.7 3.7h13c2.1 0 3.7-1.6 3.7-3.7V196.8c0-1.9-1.6-3.7-3.7-3.7zm-31.4 68.1H150.3V196.8c0-2.1-1.6-3.7-3.7-3.7h-13c-2.1 0-3.7 1.6-3.7 3.7v81.3c0 1 .3 1.8 1 2.5c.7 .6 1.5 1 2.5 1h52.2c2.1 0 3.7-1.6 3.7-3.7v-13c0-1.9-1.6-3.7-3.5-3.7zm193.7-68.1H327.3c-1.9 0-3.7 1.6-3.7 3.7v81.3c0 1.9 1.6 3.7 3.7 3.7h52.2c2.1 0 3.7-1.6 3.7-3.7V265c0-2.1-1.6-3.7-3.7-3.7H344V247.7h35.5c2.1 0 3.7-1.6 3.7-3.7V230.9c0-2.1-1.6-3.7-3.7-3.7H344V213.5h35.5c2.1 0 3.7-1.6 3.7-3.7v-13c-.1-1.9-1.7-3.7-3.7-3.7zM512 93.4V419.4c-.1 51.2-42.1 92.7-93.4 92.6H92.6C41.4 511.9-.1 469.8 0 418.6V92.6C.1 41.4 42.2-.1 93.4 0H419.4c51.2 .1 92.7 42.1 92.6 93.4zM441.6 233.5c0-83.4-83.7-151.3-186.4-151.3s-186.4 67.9-186.4 151.3c0 74.7 66.3 137.4 155.9 149.3c21.8 4.7 19.3 12.7 14.4 42.1c-.8 4.7-3.8 18.4 16.1 10.1s107.3-63.2 146.5-108.2c27-29.7 39.9-59.8 39.9-93.1z" } }, "free": ["brands"] }, "lines-leaning": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "canted", "domino", "falling", "resilience", "resilient", "tipped" ] }, "styles": ["solid"], "unicode": "e51e", "label": "Lines Leaning", "voted": false, "svg": { "solid": { "last_modified": 1684767205, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M190.4 74.1c5.6-16.8-3.5-34.9-20.2-40.5s-34.9 3.5-40.5 20.2l-128 384c-5.6 16.8 3.5 34.9 20.2 40.5s34.9-3.5 40.5-20.2l128-384zm70.9-41.7c-17.4-2.9-33.9 8.9-36.8 26.3l-64 384c-2.9 17.4 8.9 33.9 26.3 36.8s33.9-8.9 36.8-26.3l64-384c2.9-17.4-8.9-33.9-26.3-36.8zM352 32c-17.7 0-32 14.3-32 32V448c0 17.7 14.3 32 32 32s32-14.3 32-32V64c0-17.7-14.3-32-32-32z" } }, "free": ["solid"] }, "link": { "aliases": { "names": ["chain"], "unicodes": { "composite": ["1f517"], "secondary": ["10f0c1"] } }, "changes": [ "2.0.0", "5.0.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["attach", "attachment", "chain", "connect", "lin", "link"] }, "styles": ["solid"], "unicode": "f0c1", "label": "Link", "voted": false, "svg": { "solid": { "last_modified": 1684767366, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M579.8 267.7c56.5-56.5 56.5-148 0-204.5c-50-50-128.8-56.5-186.3-15.4l-1.6 1.1c-14.4 10.3-17.7 30.3-7.4 44.6s30.3 17.7 44.6 7.4l1.6-1.1c32.1-22.9 76-19.3 103.8 8.6c31.5 31.5 31.5 82.5 0 114L422.3 334.8c-31.5 31.5-82.5 31.5-114 0c-27.9-27.9-31.5-71.8-8.6-103.8l1.1-1.6c10.3-14.4 6.9-34.4-7.4-44.6s-34.4-6.9-44.6 7.4l-1.1 1.6C206.5 251.2 213 330 263 380c56.5 56.5 148 56.5 204.5 0L579.8 267.7zM60.2 244.3c-56.5 56.5-56.5 148 0 204.5c50 50 128.8 56.5 186.3 15.4l1.6-1.1c14.4-10.3 17.7-30.3 7.4-44.6s-30.3-17.7-44.6-7.4l-1.6 1.1c-32.1 22.9-76 19.3-103.8-8.6C74 372 74 321 105.5 289.5L217.7 177.2c31.5-31.5 82.5-31.5 114 0c27.9 27.9 31.5 71.8 8.6 103.9l-1.1 1.6c-10.3 14.4-6.9 34.4 7.4 44.6s34.4 6.9 44.6-7.4l1.1-1.6C433.5 260.8 427 182 377 132c-56.5-56.5-148-56.5-204.5 0L60.2 244.3z" } }, "free": ["solid"] }, "link-slash": { "aliases": { "names": ["chain-broken", "chain-slash", "unlink"], "unicodes": { "secondary": ["10f127"] } }, "changes": [ "3.1.0", "5.0.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["attachment", "chain", "chain-broken", "remove"] }, "styles": ["solid"], "unicode": "f127", "label": "Link Slash", "voted": false, "svg": { "solid": { "last_modified": 1684767366, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7L489.3 358.2l90.5-90.5c56.5-56.5 56.5-148 0-204.5c-50-50-128.8-56.5-186.3-15.4l-1.6 1.1c-14.4 10.3-17.7 30.3-7.4 44.6s30.3 17.7 44.6 7.4l1.6-1.1c32.1-22.9 76-19.3 103.8 8.6c31.5 31.5 31.5 82.5 0 114l-96 96-31.9-25C430.9 239.6 420.1 175.1 377 132c-52.2-52.3-134.5-56.2-191.3-11.7L38.8 5.1zM239 162c30.1-14.9 67.7-9.9 92.8 15.3c20 20 27.5 48.3 21.7 74.5L239 162zM406.6 416.4L220.9 270c-2.1 39.8 12.2 80.1 42.2 110c38.9 38.9 94.4 51 143.6 36.3zm-290-228.5L60.2 244.3c-56.5 56.5-56.5 148 0 204.5c50 50 128.8 56.5 186.3 15.4l1.6-1.1c14.4-10.3 17.7-30.3 7.4-44.6s-30.3-17.7-44.6-7.4l-1.6 1.1c-32.1 22.9-76 19.3-103.8-8.6C74 372 74 321 105.5 289.5l61.8-61.8-50.6-39.9z" } }, "free": ["solid"] }, "linkedin": { "changes": ["1.0.0", "5.0.0"], "ligatures": [], "search": { "terms": ["linkedin-square"] }, "styles": ["brands"], "unicode": "f08c", "label": "LinkedIn", "voted": false, "svg": { "brands": { "last_modified": 1660014466, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M416 32H31.9C14.3 32 0 46.5 0 64.3v383.4C0 465.5 14.3 480 31.9 480H416c17.6 0 32-14.5 32-32.3V64.3c0-17.8-14.4-32.3-32-32.3zM135.4 416H69V202.2h66.5V416zm-33.2-243c-21.3 0-38.5-17.3-38.5-38.5S80.9 96 102.2 96c21.2 0 38.5 17.3 38.5 38.5 0 21.3-17.2 38.5-38.5 38.5zm282.1 243h-66.4V312c0-24.8-.5-56.7-34.5-56.7-34.6 0-39.9 27-39.9 54.9V416h-66.4V202.2h63.7v29.2h.9c8.9-16.8 30.6-34.5 62.9-34.5 67.2 0 79.7 44.3 79.7 101.9V416z" } }, "free": ["brands"] }, "linkedin-in": { "changes": ["2.0.0", "5.0.0", "5.4.1", "5.8.0", "5.8.1"], "ligatures": [], "search": { "terms": ["linkedin"] }, "styles": ["brands"], "unicode": "f0e1", "label": "LinkedIn In", "voted": false, "svg": { "brands": { "last_modified": 1660014479, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M100.28 448H7.4V148.9h92.88zM53.79 108.1C24.09 108.1 0 83.5 0 53.8a53.79 53.79 0 0 1 107.58 0c0 29.7-24.1 54.3-53.79 54.3zM447.9 448h-92.68V302.4c0-34.7-.7-79.2-48.29-79.2-48.29 0-55.69 37.7-55.69 76.7V448h-92.78V148.9h89.08v40.8h1.3c12.4-23.5 42.69-48.3 87.88-48.3 94 0 111.28 61.9 111.28 142.3V448z" } }, "free": ["brands"] }, "linode": { "changes": ["4.7.0", "5.0.0", "6.0.0-beta1"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f2b8", "label": "Linode", "voted": false, "svg": { "brands": { "last_modified": 1660014472, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M366.036,186.867l-59.5,36.871-.838,36.871-29.329-19.273-39.384,24.3c2.238,55.211,2.483,59.271,2.51,59.5l-97.2,65.359L127.214,285.748l108.1-62.01L195.09,197.761l-75.417,38.547L98.723,93.015,227.771,43.574,136.432,0,10.737,39.385,38.39,174.3l41.9,32.681L48.445,222.062,69.394,323.457,98.723,351.11,77.774,363.679l16.76,78.769L160.733,512c-10.8-74.842-11.658-78.641-11.725-78.773l77.925-55.3c16.759-12.57,15.083-10.894,15.083-10.894l.838,24.3,33.519,28.491-.838-77.093,46.927-33.519,26.815-18.435-2.514,36.033,25.139,17.6,6.7-74.579,58.657-43.575Z" } }, "free": ["brands"] }, "linux": { "changes": ["3.2.0", "5.0.0"], "ligatures": [], "search": { "terms": ["tux"] }, "styles": ["brands"], "unicode": "f17c", "label": "Linux", "voted": false, "svg": { "brands": { "last_modified": 1660014467, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M220.8 123.3c1 .5 1.8 1.7 3 1.7 1.1 0 2.8-.4 2.9-1.5.2-1.4-1.9-2.3-3.2-2.9-1.7-.7-3.9-1-5.5-.1-.4.2-.8.7-.6 1.1.3 1.3 2.3 1.1 3.4 1.7zm-21.9 1.7c1.2 0 2-1.2 3-1.7 1.1-.6 3.1-.4 3.5-1.6.2-.4-.2-.9-.6-1.1-1.6-.9-3.8-.6-5.5.1-1.3.6-3.4 1.5-3.2 2.9.1 1 1.8 1.5 2.8 1.4zM420 403.8c-3.6-4-5.3-11.6-7.2-19.7-1.8-8.1-3.9-16.8-10.5-22.4-1.3-1.1-2.6-2.1-4-2.9-1.3-.8-2.7-1.5-4.1-2 9.2-27.3 5.6-54.5-3.7-79.1-11.4-30.1-31.3-56.4-46.5-74.4-17.1-21.5-33.7-41.9-33.4-72C311.1 85.4 315.7.1 234.8 0 132.4-.2 158 103.4 156.9 135.2c-1.7 23.4-6.4 41.8-22.5 64.7-18.9 22.5-45.5 58.8-58.1 96.7-6 17.9-8.8 36.1-6.2 53.3-6.5 5.8-11.4 14.7-16.6 20.2-4.2 4.3-10.3 5.9-17 8.3s-14 6-18.5 14.5c-2.1 3.9-2.8 8.1-2.8 12.4 0 3.9.6 7.9 1.2 11.8 1.2 8.1 2.5 15.7.8 20.8-5.2 14.4-5.9 24.4-2.2 31.7 3.8 7.3 11.4 10.5 20.1 12.3 17.3 3.6 40.8 2.7 59.3 12.5 19.8 10.4 39.9 14.1 55.9 10.4 11.6-2.6 21.1-9.6 25.9-20.2 12.5-.1 26.3-5.4 48.3-6.6 14.9-1.2 33.6 5.3 55.1 4.1.6 2.3 1.4 4.6 2.5 6.7v.1c8.3 16.7 23.8 24.3 40.3 23 16.6-1.3 34.1-11 48.3-27.9 13.6-16.4 36-23.2 50.9-32.2 7.4-4.5 13.4-10.1 13.9-18.3.4-8.2-4.4-17.3-15.5-29.7zM223.7 87.3c9.8-22.2 34.2-21.8 44-.4 6.5 14.2 3.6 30.9-4.3 40.4-1.6-.8-5.9-2.6-12.6-4.9 1.1-1.2 3.1-2.7 3.9-4.6 4.8-11.8-.2-27-9.1-27.3-7.3-.5-13.9 10.8-11.8 23-4.1-2-9.4-3.5-13-4.4-1-6.9-.3-14.6 2.9-21.8zM183 75.8c10.1 0 20.8 14.2 19.1 33.5-3.5 1-7.1 2.5-10.2 4.6 1.2-8.9-3.3-20.1-9.6-19.6-8.4.7-9.8 21.2-1.8 28.1 1 .8 1.9-.2-5.9 5.5-15.6-14.6-10.5-52.1 8.4-52.1zm-13.6 60.7c6.2-4.6 13.6-10 14.1-10.5 4.7-4.4 13.5-14.2 27.9-14.2 7.1 0 15.6 2.3 25.9 8.9 6.3 4.1 11.3 4.4 22.6 9.3 8.4 3.5 13.7 9.7 10.5 18.2-2.6 7.1-11 14.4-22.7 18.1-11.1 3.6-19.8 16-38.2 14.9-3.9-.2-7-1-9.6-2.1-8-3.5-12.2-10.4-20-15-8.6-4.8-13.2-10.4-14.7-15.3-1.4-4.9 0-9 4.2-12.3zm3.3 334c-2.7 35.1-43.9 34.4-75.3 18-29.9-15.8-68.6-6.5-76.5-21.9-2.4-4.7-2.4-12.7 2.6-26.4v-.2c2.4-7.6.6-16-.6-23.9-1.2-7.8-1.8-15 .9-20 3.5-6.7 8.5-9.1 14.8-11.3 10.3-3.7 11.8-3.4 19.6-9.9 5.5-5.7 9.5-12.9 14.3-18 5.1-5.5 10-8.1 17.7-6.9 8.1 1.2 15.1 6.8 21.9 16l19.6 35.6c9.5 19.9 43.1 48.4 41 68.9zm-1.4-25.9c-4.1-6.6-9.6-13.6-14.4-19.6 7.1 0 14.2-2.2 16.7-8.9 2.3-6.2 0-14.9-7.4-24.9-13.5-18.2-38.3-32.5-38.3-32.5-13.5-8.4-21.1-18.7-24.6-29.9s-3-23.3-.3-35.2c5.2-22.9 18.6-45.2 27.2-59.2 2.3-1.7.8 3.2-8.7 20.8-8.5 16.1-24.4 53.3-2.6 82.4.6-20.7 5.5-41.8 13.8-61.5 12-27.4 37.3-74.9 39.3-112.7 1.1.8 4.6 3.2 6.2 4.1 4.6 2.7 8.1 6.7 12.6 10.3 12.4 10 28.5 9.2 42.4 1.2 6.2-3.5 11.2-7.5 15.9-9 9.9-3.1 17.8-8.6 22.3-15 7.7 30.4 25.7 74.3 37.2 95.7 6.1 11.4 18.3 35.5 23.6 64.6 3.3-.1 7 .4 10.9 1.4 13.8-35.7-11.7-74.2-23.3-84.9-4.7-4.6-4.9-6.6-2.6-6.5 12.6 11.2 29.2 33.7 35.2 59 2.8 11.6 3.3 23.7.4 35.7 16.4 6.8 35.9 17.9 30.7 34.8-2.2-.1-3.2 0-4.2 0 3.2-10.1-3.9-17.6-22.8-26.1-19.6-8.6-36-8.6-38.3 12.5-12.1 4.2-18.3 14.7-21.4 27.3-2.8 11.2-3.6 24.7-4.4 39.9-.5 7.7-3.6 18-6.8 29-32.1 22.9-76.7 32.9-114.3 7.2zm257.4-11.5c-.9 16.8-41.2 19.9-63.2 46.5-13.2 15.7-29.4 24.4-43.6 25.5s-26.5-4.8-33.7-19.3c-4.7-11.1-2.4-23.1 1.1-36.3 3.7-14.2 9.2-28.8 9.9-40.6.8-15.2 1.7-28.5 4.2-38.7 2.6-10.3 6.6-17.2 13.7-21.1.3-.2.7-.3 1-.5.8 13.2 7.3 26.6 18.8 29.5 12.6 3.3 30.7-7.5 38.4-16.3 9-.3 15.7-.9 22.6 5.1 9.9 8.5 7.1 30.3 17.1 41.6 10.6 11.6 14 19.5 13.7 24.6zM173.3 148.7c2 1.9 4.7 4.5 8 7.1 6.6 5.2 15.8 10.6 27.3 10.6 11.6 0 22.5-5.9 31.8-10.8 4.9-2.6 10.9-7 14.8-10.4s5.9-6.3 3.1-6.6-2.6 2.6-6 5.1c-4.4 3.2-9.7 7.4-13.9 9.8-7.4 4.2-19.5 10.2-29.9 10.2s-18.7-4.8-24.9-9.7c-3.1-2.5-5.7-5-7.7-6.9-1.5-1.4-1.9-4.6-4.3-4.9-1.4-.1-1.8 3.7 1.7 6.5z" } }, "free": ["brands"] }, "lira-sign": { "aliases": { "unicodes": { "composite": ["20a4"], "secondary": ["10f195"] } }, "changes": [ "4.0.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["Lira Sign", "currency"] }, "styles": ["solid"], "unicode": "f195", "label": "Lira Sign", "voted": false, "svg": { "solid": { "last_modified": 1684766475, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M112 160.4c0-35.5 28.8-64.4 64.4-64.4c6.9 0 13.8 1.1 20.4 3.3l81.2 27.1c16.8 5.6 34.9-3.5 40.5-20.2s-3.5-34.9-20.2-40.5L217 38.6c-13.1-4.4-26.8-6.6-40.6-6.6C105.5 32 48 89.5 48 160.4V192H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H48v32H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H46c-2.2 10.5-6.1 20.6-11.7 29.9L4.6 431.5c-5.9 9.9-6.1 22.2-.4 32.2S20.5 480 32 480H288c17.7 0 32-14.3 32-32s-14.3-32-32-32H88.5l.7-1.1c11.6-19.3 18.9-40.7 21.6-62.9H224c17.7 0 32-14.3 32-32s-14.3-32-32-32H112V256H224c17.7 0 32-14.3 32-32s-14.3-32-32-32H112V160.4z" } }, "free": ["solid"] }, "list": { "aliases": { "names": ["list-squares"], "unicodes": { "secondary": ["10f03a"] } }, "changes": [ "1.0.0", "5.0.0", "5.9.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "checklist", "completed", "done", "finished", "ol", "todo", "ul" ] }, "styles": ["solid"], "unicode": "f03a", "label": "List", "voted": false, "svg": { "solid": { "last_modified": 1684767207, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M40 48C26.7 48 16 58.7 16 72v48c0 13.3 10.7 24 24 24H88c13.3 0 24-10.7 24-24V72c0-13.3-10.7-24-24-24H40zM192 64c-17.7 0-32 14.3-32 32s14.3 32 32 32H480c17.7 0 32-14.3 32-32s-14.3-32-32-32H192zm0 160c-17.7 0-32 14.3-32 32s14.3 32 32 32H480c17.7 0 32-14.3 32-32s-14.3-32-32-32H192zm0 160c-17.7 0-32 14.3-32 32s14.3 32 32 32H480c17.7 0 32-14.3 32-32s-14.3-32-32-32H192zM16 232v48c0 13.3 10.7 24 24 24H88c13.3 0 24-10.7 24-24V232c0-13.3-10.7-24-24-24H40c-13.3 0-24 10.7-24 24zM40 368c-13.3 0-24 10.7-24 24v48c0 13.3 10.7 24 24 24H88c13.3 0 24-10.7 24-24V392c0-13.3-10.7-24-24-24H40z" } }, "free": ["solid"] }, "list-check": { "aliases": { "names": ["tasks"], "unicodes": { "secondary": ["10f0ae"] } }, "changes": [ "2.0.0", "5.0.0", "5.9.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "checklist", "downloading", "downloads", "loading", "progress", "project management", "settings", "to do" ] }, "styles": ["solid"], "unicode": "f0ae", "label": "List Check", "voted": false, "svg": { "solid": { "last_modified": 1684767206, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M152.1 38.2c9.9 8.9 10.7 24 1.8 33.9l-72 80c-4.4 4.9-10.6 7.8-17.2 7.9s-12.9-2.4-17.6-7L7 113C-2.3 103.6-2.3 88.4 7 79s24.6-9.4 33.9 0l22.1 22.1 55.1-61.2c8.9-9.9 24-10.7 33.9-1.8zm0 160c9.9 8.9 10.7 24 1.8 33.9l-72 80c-4.4 4.9-10.6 7.8-17.2 7.9s-12.9-2.4-17.6-7L7 273c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l22.1 22.1 55.1-61.2c8.9-9.9 24-10.7 33.9-1.8zM224 96c0-17.7 14.3-32 32-32H480c17.7 0 32 14.3 32 32s-14.3 32-32 32H256c-17.7 0-32-14.3-32-32zm0 160c0-17.7 14.3-32 32-32H480c17.7 0 32 14.3 32 32s-14.3 32-32 32H256c-17.7 0-32-14.3-32-32zM160 416c0-17.7 14.3-32 32-32H480c17.7 0 32 14.3 32 32s-14.3 32-32 32H192c-17.7 0-32-14.3-32-32zM48 368a48 48 0 1 1 0 96 48 48 0 1 1 0-96z" } }, "free": ["solid"] }, "list-ol": { "aliases": { "names": ["list-1-2", "list-numeric"], "unicodes": { "secondary": ["10f0cb"] } }, "changes": [ "2.0.0", "5.0.0", "5.9.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "checklist", "completed", "done", "finished", "numbers", "ol", "todo", "ul" ] }, "styles": ["solid"], "unicode": "f0cb", "label": "List Ol", "voted": false, "svg": { "solid": { "last_modified": 1684767207, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M24 56c0-13.3 10.7-24 24-24H80c13.3 0 24 10.7 24 24V176h16c13.3 0 24 10.7 24 24s-10.7 24-24 24H40c-13.3 0-24-10.7-24-24s10.7-24 24-24H56V80H48C34.7 80 24 69.3 24 56zM86.7 341.2c-6.5-7.4-18.3-6.9-24 1.2L51.5 357.9c-7.7 10.8-22.7 13.3-33.5 5.6s-13.3-22.7-5.6-33.5l11.1-15.6c23.7-33.2 72.3-35.6 99.2-4.9c21.3 24.4 20.8 60.9-1.1 84.7L86.8 432H120c13.3 0 24 10.7 24 24s-10.7 24-24 24H32c-9.5 0-18.2-5.6-22-14.4s-2.1-18.9 4.3-25.9l72-78c5.3-5.8 5.4-14.6 .3-20.5zM224 64H480c17.7 0 32 14.3 32 32s-14.3 32-32 32H224c-17.7 0-32-14.3-32-32s14.3-32 32-32zm0 160H480c17.7 0 32 14.3 32 32s-14.3 32-32 32H224c-17.7 0-32-14.3-32-32s14.3-32 32-32zm0 160H480c17.7 0 32 14.3 32 32s-14.3 32-32 32H224c-17.7 0-32-14.3-32-32s14.3-32 32-32z" } }, "free": ["solid"] }, "list-ul": { "aliases": { "names": ["list-dots"], "unicodes": { "secondary": ["10f0ca"] } }, "changes": [ "2.0.0", "5.0.0", "5.9.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "checklist", "completed", "done", "finished", "ol", "todo", "ul" ] }, "styles": ["solid"], "unicode": "f0ca", "label": "List Ul", "voted": false, "svg": { "solid": { "last_modified": 1684767206, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M64 144a48 48 0 1 0 0-96 48 48 0 1 0 0 96zM192 64c-17.7 0-32 14.3-32 32s14.3 32 32 32H480c17.7 0 32-14.3 32-32s-14.3-32-32-32H192zm0 160c-17.7 0-32 14.3-32 32s14.3 32 32 32H480c17.7 0 32-14.3 32-32s-14.3-32-32-32H192zm0 160c-17.7 0-32 14.3-32 32s14.3 32 32 32H480c17.7 0 32-14.3 32-32s-14.3-32-32-32H192zM64 464a48 48 0 1 0 0-96 48 48 0 1 0 0 96zm48-208a48 48 0 1 0 -96 0 48 48 0 1 0 96 0z" } }, "free": ["solid"] }, "litecoin-sign": { "changes": ["6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["currency"] }, "styles": ["solid"], "unicode": "e1d3", "label": "Litecoin Sign", "voted": true, "svg": { "solid": { "last_modified": 1684766475, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M128 64c0-17.7-14.3-32-32-32S64 46.3 64 64V213.6L23.2 225.2c-17 4.9-26.8 22.6-22 39.6s22.6 26.8 39.6 22L64 280.1V448c0 17.7 14.3 32 32 32H352c17.7 0 32-14.3 32-32s-14.3-32-32-32H128V261.9l136.8-39.1c17-4.9 26.8-22.6 22-39.6s-22.6-26.8-39.6-22L128 195.3V64z" } }, "free": ["solid"] }, "location-arrow": { "aliases": { "unicodes": { "secondary": ["10f124"] } }, "changes": [ "3.1.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "address", "compass", "coordinate", "direction", "gps", "map", "navigation", "place" ] }, "styles": ["solid"], "unicode": "f124", "label": "Location Arrow", "voted": false, "svg": { "solid": { "last_modified": 1684767489, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M429.6 92.1c4.9-11.9 2.1-25.6-7-34.7s-22.8-11.9-34.7-7l-352 144c-14.2 5.8-22.2 20.8-19.3 35.8s16.1 25.8 31.4 25.8H224V432c0 15.3 10.8 28.4 25.8 31.4s30-5.1 35.8-19.3l144-352z" } }, "free": ["solid"] }, "location-crosshairs": { "aliases": { "names": ["location"], "unicodes": { "secondary": ["10f601"] } }, "changes": [ "5.2.0", "5.11.0", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "address", "coordinate", "direction", "gps", "location", "map", "navigation", "place", "where" ] }, "styles": ["solid"], "unicode": "f601", "label": "Location Crosshairs", "voted": false, "svg": { "solid": { "last_modified": 1684767489, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 0c17.7 0 32 14.3 32 32V66.7C368.4 80.1 431.9 143.6 445.3 224H480c17.7 0 32 14.3 32 32s-14.3 32-32 32H445.3C431.9 368.4 368.4 431.9 288 445.3V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V445.3C143.6 431.9 80.1 368.4 66.7 288H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H66.7C80.1 143.6 143.6 80.1 224 66.7V32c0-17.7 14.3-32 32-32zM128 256a128 128 0 1 0 256 0 128 128 0 1 0 -256 0zm128-80a80 80 0 1 1 0 160 80 80 0 1 1 0-160z" } }, "free": ["solid"] }, "location-dot": { "aliases": { "names": ["map-marker-alt"], "unicodes": { "secondary": ["10f3c5"] } }, "changes": [ "5.0.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "address", "coordinates", "destination", "gps", "localize", "location", "map", "navigation", "paper", "pin", "place", "point of interest", "position", "route", "travel" ] }, "styles": ["solid"], "unicode": "f3c5", "label": "Location Dot", "voted": false, "svg": { "solid": { "last_modified": 1684767488, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M215.7 499.2C267 435 384 279.4 384 192C384 86 298 0 192 0S0 86 0 192c0 87.4 117 243 168.3 307.2c12.3 15.3 35.1 15.3 47.4 0zM192 128a64 64 0 1 1 0 128 64 64 0 1 1 0-128z" } }, "free": ["solid"] }, "location-pin": { "aliases": { "names": ["map-marker"], "unicodes": { "secondary": ["10f041"] } }, "changes": [ "1.0.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "address", "coordinates", "destination", "gps", "localize", "location", "map", "navigation", "paper", "pin", "place", "point of interest", "position", "route", "travel" ] }, "styles": ["solid"], "unicode": "f041", "label": "Location Pin", "voted": false, "svg": { "solid": { "last_modified": 1684767489, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M384 192c0 87.4-117 243-168.3 307.2c-12.3 15.3-35.1 15.3-47.4 0C117 435 0 279.4 0 192C0 86 86 0 192 0S384 86 384 192z" } }, "free": ["solid"] }, "location-pin-lock": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["closed", "lockdown", "map", "quarantine"] }, "styles": ["solid"], "unicode": "e51f", "label": "Location Pin Lock", "voted": false, "svg": { "solid": { "last_modified": 1684767489, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M215.7 499.2c11-13.8 25.1-31.7 40.3-52.3V352c0-23.7 12.9-44.4 32-55.4V272c0-55.6 40.5-101.7 93.6-110.5C367 70 287.7 0 192 0C86 0 0 86 0 192c0 87.4 117 243 168.3 307.2c12.3 15.3 35.1 15.3 47.4 0zM192 128a64 64 0 1 1 0 128 64 64 0 1 1 0-128zM400 240c17.7 0 32 14.3 32 32v48H368V272c0-17.7 14.3-32 32-32zm-80 32v48c-17.7 0-32 14.3-32 32V480c0 17.7 14.3 32 32 32H480c17.7 0 32-14.3 32-32V352c0-17.7-14.3-32-32-32V272c0-44.2-35.8-80-80-80s-80 35.8-80 80z" } }, "free": ["solid"] }, "lock": { "aliases": { "unicodes": { "composite": ["1f512"], "secondary": ["10f023"] } }, "changes": [ "1.0.0", "5.0.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "admin", "closed", "lock", "locked", "open", "password", "private", "protect", "security" ] }, "styles": ["solid"], "unicode": "f023", "label": "Lock", "voted": false, "svg": { "solid": { "last_modified": 1684767368, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M144 144v48H304V144c0-44.2-35.8-80-80-80s-80 35.8-80 80zM80 192V144C80 64.5 144.5 0 224 0s144 64.5 144 144v48h16c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V256c0-35.3 28.7-64 64-64H80z" } }, "free": ["solid"] }, "lock-open": { "aliases": { "unicodes": { "secondary": ["10f3c1"] } }, "changes": [ "3.1.0", "5.0.0", "5.0.1", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "admin", "lock", "open", "password", "private", "protect", "security", "unlock" ] }, "styles": ["solid"], "unicode": "f3c1", "label": "Lock Open", "voted": false, "svg": { "solid": { "last_modified": 1684767367, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M352 144c0-44.2 35.8-80 80-80s80 35.8 80 80v48c0 17.7 14.3 32 32 32s32-14.3 32-32V144C576 64.5 511.5 0 432 0S288 64.5 288 144v48H64c-35.3 0-64 28.7-64 64V448c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V256c0-35.3-28.7-64-64-64H352V144z" } }, "free": ["solid"] }, "locust": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["horde", "infestation", "locust", "plague", "swarm"] }, "styles": ["solid"], "unicode": "e520", "label": "Locust", "voted": false, "svg": { "solid": { "last_modified": 1684768130, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M312 32c-13.3 0-24 10.7-24 24s10.7 24 24 24h16c98.7 0 180.6 71.4 197 165.4c-9-3.5-18.8-5.4-29-5.4H431.8l-41.8-97.5c-3.4-7.9-10.8-13.4-19.3-14.4s-17 2.7-22.1 9.6l-40.9 55.5-21.7-50.7c-3.3-7.8-10.5-13.2-18.9-14.3s-16.7 2.3-22 8.9l-240 304c-8.2 10.4-6.4 25.5 4 33.7s25.5 6.4 33.7-4l79.4-100.5 43 16.4-40.5 55c-7.9 10.7-5.6 25.7 5.1 33.6s25.7 5.6 33.6-5.1L215.1 400h74.5l-29.3 42.3c-7.5 10.9-4.8 25.8 6.1 33.4s25.8 4.8 33.4-6.1L348 400h80.4l38.8 67.9c6.6 11.5 21.2 15.5 32.7 8.9s15.5-21.2 8.9-32.7L483.6 400H496c44.1 0 79.8-35.7 80-79.7c0-.1 0-.2 0-.3V280C576 143 465 32 328 32H312zm50.5 168l17.1 40H333l29.5-40zm-87.7 38.1l-1.4 1.9H225.1l32.7-41.5 16.9 39.5zM88.8 240C57.4 240 32 265.4 32 296.8c0 15.5 6.3 30 16.9 40.4L126.7 240H88.8zM496 288a16 16 0 1 1 0 32 16 16 0 1 1 0-32z" } }, "free": ["solid"] }, "lungs": { "aliases": { "unicodes": { "composite": ["1fac1"], "secondary": ["10f604"] } }, "changes": ["5.2.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "air", "breath", "covid-19", "exhalation", "inhalation", "lungs", "organ", "respiration", "respiratory" ] }, "styles": ["solid"], "unicode": "f604", "label": "Lungs", "voted": false, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M320 0c17.7 0 32 14.3 32 32V164.1c0 16.4 8.4 31.7 22.2 40.5l9.8 6.2V165.3C384 127 415 96 453.3 96c21.7 0 42.8 10.2 55.8 28.8c15.4 22.1 44.3 65.4 71 116.9c26.5 50.9 52.4 112.5 59.6 170.3c.2 1.3 .2 2.6 .2 4v7c0 49.1-39.8 89-89 89c-7.3 0-14.5-.9-21.6-2.7l-72.7-18.2C414 480.5 384 442.1 384 398V325l90.5 57.6c7.5 4.7 17.3 2.5 22.1-4.9s2.5-17.3-4.9-22.1L384 287.1v-.4l-44.1-28.1c-7.3-4.6-13.9-10.1-19.9-16.1c-5.9 6-12.6 11.5-19.9 16.1L256 286.7 161.2 347l-13.5 8.6c0 0 0 0-.1 0c-7.4 4.8-9.6 14.6-4.8 22.1c4.7 7.5 14.6 9.7 22.1 4.9l91.1-58V398c0 44.1-30 82.5-72.7 93.1l-72.7 18.2c-7.1 1.8-14.3 2.7-21.6 2.7c-49.1 0-89-39.8-89-89v-7c0-1.3 .1-2.7 .2-4c7.2-57.9 33.1-119.4 59.6-170.3c26.8-51.5 55.6-94.8 71-116.9c13-18.6 34-28.8 55.8-28.8C225 96 256 127 256 165.3v45.5l9.8-6.2c13.8-8.8 22.2-24.1 22.2-40.5V32c0-17.7 14.3-32 32-32z" } }, "free": ["solid"] }, "lungs-virus": { "aliases": { "unicodes": { "secondary": ["10e067"] } }, "changes": ["5.13.0", "5.14.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "breath", "coronavirus", "covid-19", "flu", "infection", "pandemic", "respiratory", "sick" ] }, "styles": ["solid"], "unicode": "e067", "label": "Lungs Virus", "voted": false, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M320 0c17.7 0 32 14.3 32 32V156.2c-8.5-7.6-19.7-12.2-32-12.2s-23.5 4.6-32 12.2V32c0-17.7 14.3-32 32-32zM444.5 195.5c-16.4-16.4-41.8-18.5-60.5-6.1V165.3C384 127 415 96 453.3 96c21.7 0 42.8 10.2 55.8 28.8c15.4 22.1 44.3 65.4 71 116.9c26.5 50.9 52.4 112.5 59.6 170.3c.2 1.3 .2 2.6 .2 4v7c0 49.1-39.8 89-89 89c-7.3 0-14.5-.9-21.6-2.7l-72.7-18.2c-20.9-5.2-38.7-17.1-51.5-32.9c14 1.5 28.5-3 39.2-13.8l-22.6-22.6 22.6 22.6c18.7-18.7 18.7-49.1 0-67.9c-1.1-1.1-1.4-2-1.5-2.5c-.1-.8-.1-1.8 .4-2.9s1.2-1.9 1.8-2.3c.5-.3 1.3-.8 2.9-.8c26.5 0 48-21.5 48-48s-21.5-48-48-48c-1.6 0-2.4-.4-2.9-.8c-.6-.4-1.3-1.2-1.8-2.3s-.5-2.2-.4-2.9c.1-.6 .4-1.4 1.5-2.5c18.7-18.7 18.7-49.1 0-67.9zM421.8 421.8c-6.2 6.2-16.4 6.2-22.6 0C375.9 398.5 336 415 336 448c0 8.8-7.2 16-16 16s-16-7.2-16-16c0-33-39.9-49.5-63.2-26.2c-6.2 6.2-16.4 6.2-22.6 0s-6.2-16.4 0-22.6C241.5 375.9 225 336 192 336c-8.8 0-16-7.2-16-16s7.2-16 16-16c33 0 49.5-39.9 26.2-63.2c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0C264.1 241.5 304 225 304 192c0-8.8 7.2-16 16-16s16 7.2 16 16c0 33 39.9 49.5 63.2 26.2c6.2-6.2 16.4-6.2 22.6 0s6.2 16.4 0 22.6C398.5 264.1 415 304 448 304c8.8 0 16 7.2 16 16s-7.2 16-16 16c-33 0-49.5 39.9-26.2 63.2c6.2 6.2 6.2 16.4 0 22.6zM183.3 491.2l-72.7 18.2c-7.1 1.8-14.3 2.7-21.6 2.7c-49.1 0-89-39.8-89-89v-7c0-1.3 .1-2.7 .2-4c7.2-57.9 33.1-119.4 59.6-170.3c26.8-51.5 55.6-94.8 71-116.9c13-18.6 34-28.8 55.8-28.8C225 96 256 127 256 165.3v24.1c-18.6-12.4-44-10.3-60.5 6.1c-18.7 18.7-18.7 49.1 0 67.9c1.1 1.1 1.4 2 1.5 2.5c.1 .8 .1 1.8-.4 2.9s-1.2 1.9-1.8 2.3c-.5 .3-1.3 .8-2.9 .8c-26.5 0-48 21.5-48 48s21.5 48 48 48c1.6 0 2.4 .4 2.9 .8c.6 .4 1.3 1.2 1.8 2.3s.5 2.2 .4 2.9c-.1 .6-.4 1.4-1.5 2.5c-18.7 18.7-18.7 49.1 0 67.9c10.7 10.7 25.3 15.3 39.2 13.8c-12.8 15.9-30.6 27.7-51.5 32.9zM296 320a24 24 0 1 0 0-48 24 24 0 1 0 0 48zm72 32a16 16 0 1 0 -32 0 16 16 0 1 0 32 0z" } }, "free": ["solid"] }, "lyft": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3c3", "label": "lyft", "voted": false, "svg": { "brands": { "last_modified": 1660014478, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 81.1h77.8v208.7c0 33.1 15 52.8 27.2 61-12.7 11.1-51.2 20.9-80.2-2.8C7.8 334 0 310.7 0 289V81.1zm485.9 173.5v-22h23.8v-76.8h-26.1c-10.1-46.3-51.2-80.7-100.3-80.7-56.6 0-102.7 46-102.7 102.7V357c16 2.3 35.4-.3 51.7-14 17.1-14 24.8-37.2 24.8-59v-6.7h38.8v-76.8h-38.8v-23.3c0-34.6 52.2-34.6 52.2 0v77.1c0 56.6 46 102.7 102.7 102.7v-76.5c-14.5 0-26.1-11.7-26.1-25.9zm-294.3-99v113c0 15.4-23.8 15.4-23.8 0v-113H91v132.7c0 23.8 8 54 45 63.9 37 9.8 58.2-10.6 58.2-10.6-2.1 13.4-14.5 23.3-34.9 25.3-15.5 1.6-35.2-3.6-45-7.8v70.3c25.1 7.5 51.5 9.8 77.6 4.7 47.1-9.1 76.8-48.4 76.8-100.8V155.1h-77.1v.5z" } }, "free": ["brands"] }, "m": { "aliases": { "unicodes": { "composite": ["6d"] } }, "changes": ["6.0.0-beta1", "6.2.0", "6.2.1", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Latin Capital Letter M", "Latin Small Letter M", "letter"] }, "styles": ["solid"], "unicode": "4d", "label": "M", "voted": false, "svg": { "solid": { "last_modified": 1684767244, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M22.7 33.4c13.5-4.1 28.1 1.1 35.9 12.9L224 294.3 389.4 46.2c7.8-11.7 22.4-17 35.9-12.9S448 49.9 448 64V448c0 17.7-14.3 32-32 32s-32-14.3-32-32V169.7L250.6 369.8c-5.9 8.9-15.9 14.2-26.6 14.2s-20.7-5.3-26.6-14.2L64 169.7V448c0 17.7-14.3 32-32 32s-32-14.3-32-32V64C0 49.9 9.2 37.5 22.7 33.4z" } }, "free": ["solid"] }, "magento": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3c4", "label": "Magento", "voted": false, "svg": { "brands": { "last_modified": 1660014469, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M445.7 127.9V384l-63.4 36.5V164.7L223.8 73.1 65.2 164.7l.4 255.9L2.3 384V128.1L224.2 0l221.5 127.9zM255.6 420.5L224 438.9l-31.8-18.2v-256l-63.3 36.6.1 255.9 94.9 54.9 95.1-54.9v-256l-63.4-36.6v255.9z" } }, "free": ["brands"] }, "magnet": { "aliases": { "unicodes": { "composite": ["1f9f2"], "secondary": ["10f076"] } }, "changes": [ "1.0.0", "5.0.0", "5.8.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Attract", "attraction", "horseshoe", "lodestone", "magnet", "magnetic", "tool" ] }, "styles": ["solid"], "unicode": "f076", "label": "Magnet", "voted": false, "svg": { "solid": { "last_modified": 1684767366, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M0 160v96C0 379.7 100.3 480 224 480s224-100.3 224-224V160H320v96c0 53-43 96-96 96s-96-43-96-96V160H0zm0-32H128V64c0-17.7-14.3-32-32-32H32C14.3 32 0 46.3 0 64v64zm320 0H448V64c0-17.7-14.3-32-32-32H352c-17.7 0-32 14.3-32 32v64z" } }, "free": ["solid"] }, "magnifying-glass": { "aliases": { "names": ["search"], "unicodes": { "composite": ["1f50d"], "secondary": ["10f002"] } }, "changes": ["1.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "bigger", "enlarge", "find", "glass", "magnify", "magnifying", "magnifying glass tilted left", "preview", "search", "tool", "zoom" ] }, "styles": ["solid"], "unicode": "f002", "label": "Magnifying Glass", "voted": false, "svg": { "solid": { "last_modified": 1684767390, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M416 208c0 45.9-14.9 88.3-40 122.7L502.6 457.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L330.7 376c-34.4 25.2-76.8 40-122.7 40C93.1 416 0 322.9 0 208S93.1 0 208 0S416 93.1 416 208zM208 352a144 144 0 1 0 0-288 144 144 0 1 0 0 288z" } }, "free": ["solid"] }, "magnifying-glass-arrow-right": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["find", "next", "search"] }, "styles": ["solid"], "unicode": "e521", "label": "Magnifying Glass Arrow Right", "voted": false, "svg": { "solid": { "last_modified": 1684767393, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M416 208c0 45.9-14.9 88.3-40 122.7L502.6 457.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L330.7 376c-34.4 25.2-76.8 40-122.7 40C93.1 416 0 322.9 0 208S93.1 0 208 0S416 93.1 416 208zM241 119c-9.4-9.4-24.6-9.4-33.9 0s-9.4 24.6 0 33.9l31 31H120c-13.3 0-24 10.7-24 24s10.7 24 24 24H238.1l-31 31c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l72-72c9.4-9.4 9.4-24.6 0-33.9l-72-72z" } }, "free": ["solid"] }, "magnifying-glass-chart": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ " data", " graph", " intelligence", "analysis", "chart", "market" ] }, "styles": ["solid"], "unicode": "e522", "label": "Magnifying Glass Chart", "voted": false, "svg": { "solid": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M416 208c0 45.9-14.9 88.3-40 122.7L502.6 457.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L330.7 376c-34.4 25.2-76.8 40-122.7 40C93.1 416 0 322.9 0 208S93.1 0 208 0S416 93.1 416 208zm-312 8v64c0 13.3 10.7 24 24 24s24-10.7 24-24l0-64c0-13.3-10.7-24-24-24s-24 10.7-24 24zm80-96V280c0 13.3 10.7 24 24 24s24-10.7 24-24V120c0-13.3-10.7-24-24-24s-24 10.7-24 24zm80 64v96c0 13.3 10.7 24 24 24s24-10.7 24-24V184c0-13.3-10.7-24-24-24s-24 10.7-24 24z" } }, "free": ["solid"] }, "magnifying-glass-dollar": { "aliases": { "names": ["search-dollar"], "unicodes": { "secondary": ["10f688"] } }, "changes": ["5.3.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "bigger", "enlarge", "find", "magnify", "money", "preview", "zoom" ] }, "styles": ["solid"], "unicode": "f688", "label": "Magnifying Glass Dollar", "voted": false, "svg": { "solid": { "last_modified": 1684767389, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M416 208c0 45.9-14.9 88.3-40 122.7L502.6 457.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L330.7 376c-34.4 25.2-76.8 40-122.7 40C93.1 416 0 322.9 0 208S93.1 0 208 0S416 93.1 416 208zM228 104c0-11-9-20-20-20s-20 9-20 20v14c-7.6 1.7-15.2 4.4-22.2 8.5c-13.9 8.3-25.9 22.8-25.8 43.9c.1 20.3 12 33.1 24.7 40.7c11 6.6 24.7 10.8 35.6 14l1.7 .5c12.6 3.8 21.8 6.8 28 10.7c5.1 3.2 5.8 5.4 5.9 8.2c.1 5-1.8 8-5.9 10.5c-5 3.1-12.9 5-21.4 4.7c-11.1-.4-21.5-3.9-35.1-8.5c-2.3-.8-4.7-1.6-7.2-2.4c-10.5-3.5-21.8 2.2-25.3 12.6s2.2 21.8 12.6 25.3c1.9 .6 4 1.3 6.1 2.1l0 0 0 0c8.3 2.9 17.9 6.2 28.2 8.4V312c0 11 9 20 20 20s20-9 20-20V298.2c8-1.7 16-4.5 23.2-9c14.3-8.9 25.1-24.1 24.8-45c-.3-20.3-11.7-33.4-24.6-41.6c-11.5-7.2-25.9-11.6-37.1-15l-.7-.2c-12.8-3.9-21.9-6.7-28.3-10.5c-5.2-3.1-5.3-4.9-5.3-6.7c0-3.7 1.4-6.5 6.2-9.3c5.4-3.2 13.6-5.1 21.5-5c9.6 .1 20.2 2.2 31.2 5.2c10.7 2.8 21.6-3.5 24.5-14.2s-3.5-21.6-14.2-24.5c-6.5-1.7-13.7-3.4-21.1-4.7V104z" } }, "free": ["solid"] }, "magnifying-glass-location": { "aliases": { "names": ["search-location"], "unicodes": { "secondary": ["10f689"] } }, "changes": ["5.3.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["bigger", "enlarge", "find", "magnify", "preview", "zoom"] }, "styles": ["solid"], "unicode": "f689", "label": "Magnifying Glass Location", "voted": false, "svg": { "solid": { "last_modified": 1684767393, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M416 208c0 45.9-14.9 88.3-40 122.7L502.6 457.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L330.7 376c-34.4 25.2-76.8 40-122.7 40C93.1 416 0 322.9 0 208S93.1 0 208 0S416 93.1 416 208zM288 176c0-44.2-35.8-80-80-80s-80 35.8-80 80c0 48.8 46.5 111.6 68.6 138.6c6 7.3 16.8 7.3 22.7 0c22.1-27 68.6-89.8 68.6-138.6zm-112 0a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z" } }, "free": ["solid"] }, "magnifying-glass-minus": { "aliases": { "names": ["search-minus"], "unicodes": { "secondary": ["10f010"] } }, "changes": [ "1.0.0", "5.0.0", "5.0.13", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["minify", "negative", "smaller", "zoom", "zoom out"] }, "styles": ["solid"], "unicode": "f010", "label": "Magnifying Glass Minus", "voted": false, "svg": { "solid": { "last_modified": 1684767389, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M416 208c0 45.9-14.9 88.3-40 122.7L502.6 457.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L330.7 376c-34.4 25.2-76.8 40-122.7 40C93.1 416 0 322.9 0 208S93.1 0 208 0S416 93.1 416 208zM136 184c-13.3 0-24 10.7-24 24s10.7 24 24 24H280c13.3 0 24-10.7 24-24s-10.7-24-24-24H136z" } }, "free": ["solid"] }, "magnifying-glass-plus": { "aliases": { "names": ["search-plus"], "unicodes": { "secondary": ["10f00e"] } }, "changes": ["1.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["bigger", "enlarge", "magnify", "positive", "zoom", "zoom in"] }, "styles": ["solid"], "unicode": "f00e", "label": "Magnifying Glass Plus", "voted": false, "svg": { "solid": { "last_modified": 1684767389, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M416 208c0 45.9-14.9 88.3-40 122.7L502.6 457.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L330.7 376c-34.4 25.2-76.8 40-122.7 40C93.1 416 0 322.9 0 208S93.1 0 208 0S416 93.1 416 208zM184 296c0 13.3 10.7 24 24 24s24-10.7 24-24V232h64c13.3 0 24-10.7 24-24s-10.7-24-24-24H232V120c0-13.3-10.7-24-24-24s-24 10.7-24 24v64H120c-13.3 0-24 10.7-24 24s10.7 24 24 24h64v64z" } }, "free": ["solid"] }, "mailchimp": { "changes": ["5.1.0", "5.7.0", "5.8.0", "5.8.2"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f59e", "label": "Mailchimp", "voted": true, "svg": { "brands": { "last_modified": 1660014481, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M330.61 243.52a36.15 36.15 0 0 1 9.3 0c1.66-3.83 1.95-10.43.45-17.61-2.23-10.67-5.25-17.14-11.48-16.13s-6.47 8.74-4.24 19.42c1.26 6 3.49 11.14 6 14.32zM277.05 252c4.47 2 7.2 3.26 8.28 2.13 1.89-1.94-3.48-9.39-12.12-13.09a31.44 31.44 0 0 0-30.61 3.68c-3 2.18-5.81 5.22-5.41 7.06.85 3.74 10-2.71 22.6-3.48 7-.44 12.8 1.75 17.26 3.71zm-9 5.13c-9.07 1.42-15 6.53-13.47 10.1.9.34 1.17.81 5.21-.81a37 37 0 0 1 18.72-1.95c2.92.34 4.31.52 4.94-.49 1.46-2.22-5.71-8-15.39-6.85zm54.17 17.1c3.38-6.87-10.9-13.93-14.3-7s10.92 13.88 14.32 6.97zm15.66-20.47c-7.66-.13-7.95 15.8-.26 15.93s7.98-15.81.28-15.96zm-218.79 78.9c-1.32.31-6 1.45-8.47-2.35-5.2-8 11.11-20.38 3-35.77-9.1-17.47-27.82-13.54-35.05-5.54-8.71 9.6-8.72 23.54-5 24.08 4.27.57 4.08-6.47 7.38-11.63a12.83 12.83 0 0 1 17.85-3.72c11.59 7.59 1.37 17.76 2.28 28.62 1.39 16.68 18.42 16.37 21.58 9a2.08 2.08 0 0 0-.2-2.33c.03.89.68-1.3-3.35-.39zm299.72-17.07c-3.35-11.73-2.57-9.22-6.78-20.52 2.45-3.67 15.29-24-3.07-43.25-10.4-10.92-33.9-16.54-41.1-18.54-1.5-11.39 4.65-58.7-21.52-83 20.79-21.55 33.76-45.29 33.73-65.65-.06-39.16-48.15-51-107.42-26.47l-12.55 5.33c-.06-.05-22.71-22.27-23.05-22.57C169.5-18-41.77 216.81 25.78 273.85l14.76 12.51a72.49 72.49 0 0 0-4.1 33.5c3.36 33.4 36 60.42 67.53 60.38 57.73 133.06 267.9 133.28 322.29 3 1.74-4.47 9.11-24.61 9.11-42.38s-10.09-25.27-16.53-25.27zm-316 48.16c-22.82-.61-47.46-21.15-49.91-45.51-6.17-61.31 74.26-75.27 84-12.33 4.54 29.64-4.67 58.49-34.12 57.81zM84.3 249.55C69.14 252.5 55.78 261.09 47.6 273c-4.88-4.07-14-12-15.59-15-13.01-24.85 14.24-73 33.3-100.21C112.42 90.56 186.19 39.68 220.36 48.91c5.55 1.57 23.94 22.89 23.94 22.89s-34.15 18.94-65.8 45.35c-42.66 32.85-74.89 80.59-94.2 132.4zM323.18 350.7s-35.74 5.3-69.51-7.07c6.21-20.16 27 6.1 96.4-13.81 15.29-4.38 35.37-13 51-25.35a102.85 102.85 0 0 1 7.12 24.28c3.66-.66 14.25-.52 11.44 18.1-3.29 19.87-11.73 36-25.93 50.84A106.86 106.86 0 0 1 362.55 421a132.45 132.45 0 0 1-20.34 8.58c-53.51 17.48-108.3-1.74-126-43a66.33 66.33 0 0 1-3.55-9.74c-7.53-27.2-1.14-59.83 18.84-80.37 1.23-1.31 2.48-2.85 2.48-4.79a8.45 8.45 0 0 0-1.92-4.54c-7-10.13-31.19-27.4-26.33-60.83 3.5-24 24.49-40.91 44.07-39.91l5 .29c8.48.5 15.89 1.59 22.88 1.88 11.69.5 22.2-1.19 34.64-11.56 4.2-3.5 7.57-6.54 13.26-7.51a17.45 17.45 0 0 1 13.6 2.24c10 6.64 11.4 22.73 11.92 34.49.29 6.72 1.1 23 1.38 27.63.63 10.67 3.43 12.17 9.11 14 3.19 1.05 6.15 1.83 10.51 3.06 13.21 3.71 21 7.48 26 12.31a16.38 16.38 0 0 1 4.74 9.29c1.56 11.37-8.82 25.4-36.31 38.16-46.71 21.68-93.68 14.45-100.48 13.68-20.15-2.71-31.63 23.32-19.55 41.15 22.64 33.41 122.4 20 151.37-21.35.69-1 .12-1.59-.73-1-41.77 28.58-97.06 38.21-128.46 26-4.77-1.85-14.73-6.44-15.94-16.67 43.6 13.49 71 .74 71 .74s2.03-2.79-.56-2.53zm-68.47-5.7zm-83.4-187.5c16.74-19.35 37.36-36.18 55.83-45.63a.73.73 0 0 1 1 1c-1.46 2.66-4.29 8.34-5.19 12.65a.75.75 0 0 0 1.16.79c11.49-7.83 31.48-16.22 49-17.3a.77.77 0 0 1 .52 1.38 41.86 41.86 0 0 0-7.71 7.74.75.75 0 0 0 .59 1.19c12.31.09 29.66 4.4 41 10.74.76.43.22 1.91-.64 1.72-69.55-15.94-123.08 18.53-134.5 26.83a.76.76 0 0 1-1-1.12z" } }, "free": ["brands"] }, "manat-sign": { "changes": ["6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Manat Sign", "currency"] }, "styles": ["solid"], "unicode": "e1d5", "label": "Manat Sign", "voted": false, "svg": { "solid": { "last_modified": 1684766476, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M192 32c-17.7 0-32 14.3-32 32V98.7C69.2 113.9 0 192.9 0 288V448c0 17.7 14.3 32 32 32s32-14.3 32-32V288c0-59.6 40.8-109.8 96-124V448c0 17.7 14.3 32 32 32s32-14.3 32-32V164c55.2 14.2 96 64.3 96 124V448c0 17.7 14.3 32 32 32s32-14.3 32-32V288c0-95.1-69.2-174.1-160-189.3V64c0-17.7-14.3-32-32-32z" } }, "free": ["solid"] }, "mandalorian": { "changes": ["5.0.12", "5.8.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f50f", "label": "Mandalorian", "voted": false, "svg": { "brands": { "last_modified": 1660014470, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M232.27 511.89c-1-3.26-1.69-15.83-1.39-24.58.55-15.89 1-24.72 1.4-28.76.64-6.2 2.87-20.72 3.28-21.38.6-1 .4-27.87-.24-33.13-.31-2.58-.63-11.9-.69-20.73-.13-16.47-.53-20.12-2.73-24.76-1.1-2.32-1.23-3.84-1-11.43a92.38 92.38 0 0 0-.34-12.71c-2-13-3.46-27.7-3.25-33.9s.43-7.15 2.06-9.67c3.05-4.71 6.51-14 8.62-23.27 2.26-9.86 3.88-17.18 4.59-20.74a109.54 109.54 0 0 1 4.42-15.05c2.27-6.25 2.49-15.39.37-15.39-.3 0-1.38 1.22-2.41 2.71s-4.76 4.8-8.29 7.36c-8.37 6.08-11.7 9.39-12.66 12.58s-1 7.23-.16 7.76c.34.21 1.29 2.4 2.11 4.88a28.83 28.83 0 0 1 .72 15.36c-.39 1.77-1 5.47-1.46 8.23s-1 6.46-1.25 8.22a9.85 9.85 0 0 1-1.55 4.26c-1 1-1.14.91-2.05-.53a14.87 14.87 0 0 1-1.44-4.75c-.25-1.74-1.63-7.11-3.08-11.93-3.28-10.9-3.52-16.15-1-21a14.24 14.24 0 0 0 1.67-4.61c0-2.39-2.2-5.32-7.41-9.89-7-6.18-8.63-7.92-10.23-11.3-1.71-3.6-3.06-4.06-4.54-1.54-1.78 3-2.6 9.11-3 22l-.34 12.19 2 2.25c3.21 3.7 12.07 16.45 13.78 19.83 3.41 6.74 4.34 11.69 4.41 23.56s.95 22.75 2 24.71c.36.66.51 1.35.34 1.52s.41 2.09 1.29 4.27a38.14 38.14 0 0 1 2.06 9 91 91 0 0 0 1.71 10.37c2.23 9.56 2.77 14.08 2.39 20.14-.2 3.27-.53 11.07-.73 17.32-1.31 41.76-1.85 58-2 61.21-.12 2-.39 11.51-.6 21.07-.36 16.3-1.3 27.37-2.42 28.65-.64.73-8.07-4.91-12.52-9.49-3.75-3.87-4-4.79-2.83-9.95.7-3 2.26-18.29 3.33-32.62.36-4.78.81-10.5 1-12.71.83-9.37 1.66-20.35 2.61-34.78.56-8.46 1.33-16.44 1.72-17.73s.89-9.89 1.13-19.11l.43-16.77-2.26-4.3c-1.72-3.28-4.87-6.94-13.22-15.34-6-6.07-11.84-12.3-12.91-13.85l-1.95-2.81.75-10.9c1.09-15.71 1.1-48.57 0-59.06l-.89-8.7-3.28-4.52c-5.86-8.08-5.8-7.75-6.22-33.27-.1-6.07-.38-11.5-.63-12.06-.83-1.87-3.05-2.66-8.54-3.05-8.86-.62-11-1.9-23.85-14.55-6.15-6-12.34-12-13.75-13.19-2.81-2.42-2.79-2-.56-9.63l1.35-4.65-1.69-3a32.22 32.22 0 0 0-2.59-4.07c-1.33-1.51-5.5-10.89-6-13.49a4.24 4.24 0 0 1 .87-3.9c2.23-2.86 3.4-5.68 4.45-10.73 2.33-11.19 7.74-26.09 10.6-29.22 3.18-3.47 7.7-1 9.41 5 1.34 4.79 1.37 9.79.1 18.55a101.2 101.2 0 0 0-1 11.11c0 4 .19 4.69 2.25 7.39 3.33 4.37 7.73 7.41 15.2 10.52a18.67 18.67 0 0 1 4.72 2.85c11.17 10.72 18.62 16.18 22.95 16.85 5.18.8 8 4.54 10 13.39 1.31 5.65 4 11.14 5.46 11.14a9.38 9.38 0 0 0 3.33-1.39c2-1.22 2.25-1.73 2.25-4.18a132.88 132.88 0 0 0-2-17.84c-.37-1.66-.78-4.06-.93-5.35s-.61-3.85-1-5.69c-2.55-11.16-3.65-15.46-4.1-16-1.55-2-4.08-10.2-4.93-15.92-1.64-11.11-4-14.23-12.91-17.39A43.15 43.15 0 0 1 165.24 78c-1.15-1-4-3.22-6.35-5.06s-4.41-3.53-4.6-3.76a22.7 22.7 0 0 0-2.69-2c-6.24-4.22-8.84-7-11.26-12l-2.44-5-.22-13-.22-13 6.91-6.55c3.95-3.75 8.48-7.35 10.59-8.43 3.31-1.69 4.45-1.89 11.37-2 8.53-.19 10.12 0 11.66 1.56s1.36 6.4-.29 8.5a6.66 6.66 0 0 0-1.34 2.32c0 .58-2.61 4.91-5.42 9a30.39 30.39 0 0 0-2.37 6.82c20.44 13.39 21.55 3.77 14.07 29L194 66.92c3.11-8.66 6.47-17.26 8.61-26.22.29-7.63-12-4.19-15.4-8.68-2.33-5.93 3.13-14.18 6.06-19.2 1.6-2.34 6.62-4.7 8.82-4.15.88.22 4.16-.35 7.37-1.28a45.3 45.3 0 0 1 7.55-1.68 29.57 29.57 0 0 0 6-1.29c3.65-1.11 4.5-1.17 6.35-.4a29.54 29.54 0 0 0 5.82 1.36 18.18 18.18 0 0 1 6 1.91 22.67 22.67 0 0 0 5 2.17c2.51.68 3 .57 7.05-1.67l4.35-2.4L268.32 5c10.44-.4 10.81-.47 15.26-2.68L288.16 0l2.46 1.43c1.76 1 3.14 2.73 4.85 6 2.36 4.51 2.38 4.58 1.37 7.37-.88 2.44-.89 3.3-.1 6.39a35.76 35.76 0 0 0 2.1 5.91 13.55 13.55 0 0 1 1.31 4c.31 4.33 0 5.3-2.41 6.92-2.17 1.47-7 7.91-7 9.34a14.77 14.77 0 0 1-1.07 3c-5 11.51-6.76 13.56-14.26 17-9.2 4.2-12.3 5.19-16.21 5.19-3.1 0-4 .25-4.54 1.26a18.33 18.33 0 0 1-4.09 3.71 13.62 13.62 0 0 0-4.38 4.78 5.89 5.89 0 0 1-2.49 2.91 6.88 6.88 0 0 0-2.45 1.71 67.62 67.62 0 0 1-7 5.38c-3.33 2.34-6.87 5-7.87 6A7.27 7.27 0 0 1 224 100a5.76 5.76 0 0 0-2.13 1.65c-1.31 1.39-1.49 2.11-1.14 4.6a36.45 36.45 0 0 0 1.42 5.88c1.32 3.8 1.31 7.86 0 10.57s-.89 6.65 1.35 9.59c2 2.63 2.16 4.56.71 8.84a33.45 33.45 0 0 0-1.06 8.91c0 4.88.22 6.28 1.46 8.38s1.82 2.48 3.24 2.32c2-.23 2.3-1.05 4.71-12.12 2.18-10 3.71-11.92 13.76-17.08 2.94-1.51 7.46-4 10-5.44s6.79-3.69 9.37-4.91a40.09 40.09 0 0 0 15.22-11.67c7.11-8.79 10-16.22 12.85-33.3a18.37 18.37 0 0 1 2.86-7.73 20.39 20.39 0 0 0 2.89-7.31c1-5.3 2.85-9.08 5.58-11.51 4.7-4.18 6-1.09 4.59 10.87-.46 3.86-1.1 10.33-1.44 14.38l-.61 7.36 4.45 4.09 4.45 4.09.11 8.42c.06 4.63.47 9.53.92 10.89l.82 2.47-6.43 6.28c-8.54 8.33-12.88 13.93-16.76 21.61-1.77 3.49-3.74 7.11-4.38 8-2.18 3.11-6.46 13-8.76 20.26l-2.29 7.22-7 6.49c-3.83 3.57-8 7.25-9.17 8.17-3.05 2.32-4.26 5.15-4.26 10a14.62 14.62 0 0 0 1.59 7.26 42 42 0 0 1 2.09 4.83 9.28 9.28 0 0 0 1.57 2.89c1.4 1.59 1.92 16.12.83 23.22-.68 4.48-3.63 12-4.7 12-1.79 0-4.06 9.27-5.07 20.74-.18 2-.62 5.94-1 8.7s-1 10-1.35 16.05c-.77 12.22-.19 18.77 2 23.15 3.41 6.69.52 12.69-11 22.84l-4 3.49.07 5.19a40.81 40.81 0 0 0 1.14 8.87c4.61 16 4.73 16.92 4.38 37.13-.46 26.4-.26 40.27.63 44.15a61.31 61.31 0 0 1 1.08 7c.17 2 .66 5.33 1.08 7.36.47 2.26.78 11 .79 22.74v19.06l-1.81 2.63c-2.71 3.91-15.11 13.54-15.49 12.29zm29.53-45.11c-.18-.3-.33-6.87-.33-14.59 0-14.06-.89-27.54-2.26-34.45-.4-2-.81-9.7-.9-17.06-.15-11.93-1.4-24.37-2.64-26.38-.66-1.07-3-17.66-3-21.3 0-4.23 1-6 5.28-9.13s4.86-3.14 5.48-.72c.28 1.1 1.45 5.62 2.6 10 3.93 15.12 4.14 16.27 4.05 21.74-.1 5.78-.13 6.13-1.74 17.73-1 7.07-1.17 12.39-1 28.43.17 19.4-.64 35.73-2 41.27-.71 2.78-2.8 5.48-3.43 4.43zm-71-37.58a101 101 0 0 1-1.73-10.79 100.5 100.5 0 0 0-1.73-10.79 37.53 37.53 0 0 1-1-6.49c-.31-3.19-.91-7.46-1.33-9.48-1-4.79-3.35-19.35-3.42-21.07 0-.74-.34-4.05-.7-7.36-.67-6.21-.84-27.67-.22-28.29 1-1 6.63 2.76 11.33 7.43l5.28 5.25-.45 6.47c-.25 3.56-.6 10.23-.78 14.83s-.49 9.87-.67 11.71-.61 9.36-.94 16.72c-.79 17.41-1.94 31.29-2.65 32a.62.62 0 0 1-1-.14zm-87.18-266.59c21.07 12.79 17.84 14.15 28.49 17.66 13 4.29 18.87 7.13 23.15 16.87C111.6 233.28 86.25 255 78.55 268c-31 52-6 101.59 62.75 87.21-14.18 29.23-78 28.63-98.68-4.9-24.68-39.95-22.09-118.3 61-187.66zm210.79 179c56.66 6.88 82.32-37.74 46.54-89.23 0 0-26.87-29.34-64.28-68 3-15.45 9.49-32.12 30.57-53.82 89.2 63.51 92 141.61 92.46 149.36 4.3 70.64-78.7 91.18-105.29 61.71z" } }, "free": ["brands"] }, "map": { "aliases": { "unicodes": { "composite": ["1f5fa", "f278"], "secondary": ["10f279"] } }, "changes": [ "4.4.0", "5.0.0", "5.1.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "address", "coordinates", "destination", "gps", "localize", "location", "map", "navigation", "paper", "pin", "place", "point of interest", "position", "route", "travel", "world", "world map" ] }, "styles": ["solid", "regular"], "unicode": "f279", "label": "Map", "voted": false, "svg": { "solid": { "last_modified": 1684767488, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M384 476.1L192 421.2V35.9L384 90.8V476.1zm32-1.2V88.4L543.1 37.5c15.8-6.3 32.9 5.3 32.9 22.3V394.6c0 9.8-6 18.6-15.1 22.3L416 474.8zM15.1 95.1L160 37.2V423.6L32.9 474.5C17.1 480.8 0 469.2 0 452.2V117.4c0-9.8 6-18.6 15.1-22.3z" }, "regular": { "last_modified": 1684767488, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M565.6 36.2C572.1 40.7 576 48.1 576 56V392c0 10-6.2 18.9-15.5 22.4l-168 64c-5.2 2-10.9 2.1-16.1 .3L192.5 417.5l-160 61c-7.4 2.8-15.7 1.8-22.2-2.7S0 463.9 0 456V120c0-10 6.1-18.9 15.5-22.4l168-64c5.2-2 10.9-2.1 16.1-.3L383.5 94.5l160-61c7.4-2.8 15.7-1.8 22.2 2.7zM48 136.5V421.2l120-45.7V90.8L48 136.5zM360 422.7V137.3l-144-48V374.7l144 48zm48-1.5l120-45.7V90.8L408 136.5V421.2z" } }, "free": ["regular", "solid"] }, "map-location": { "aliases": { "names": ["map-marked"], "unicodes": { "secondary": ["10f59f"] } }, "changes": [ "5.1.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "address", "coordinates", "destination", "gps", "localize", "location", "map", "navigation", "paper", "pin", "place", "point of interest", "position", "route", "travel" ] }, "styles": ["solid"], "unicode": "f59f", "label": "Map Location", "voted": false, "svg": { "solid": { "last_modified": 1684767489, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M302.8 312C334.9 271.9 408 174.6 408 120C408 53.7 354.3 0 288 0S168 53.7 168 120c0 54.6 73.1 151.9 105.2 192c7.7 9.6 22 9.6 29.6 0zM416 503l144.9-58c9.1-3.6 15.1-12.5 15.1-22.3V152c0-17-17.1-28.6-32.9-22.3l-116 46.4c-.5 1.2-1 2.5-1.5 3.7c-2.9 6.8-6.1 13.7-9.6 20.6V503zM15.1 187.3C6 191 0 199.8 0 209.6V480.4c0 17 17.1 28.6 32.9 22.3L160 451.8V200.4c-3.5-6.9-6.7-13.8-9.6-20.6c-5.6-13.2-10.4-27.4-12.8-41.5l-122.6 49zM384 255c-20.5 31.3-42.3 59.6-56.2 77c-20.5 25.6-59.1 25.6-79.6 0c-13.9-17.4-35.7-45.7-56.2-77V449.4l192 54.9V255z" } }, "free": ["solid"] }, "map-location-dot": { "aliases": { "names": ["map-marked-alt"], "unicodes": { "secondary": ["10f5a0"] } }, "changes": [ "5.1.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "address", "coordinates", "destination", "gps", "localize", "location", "map", "navigation", "paper", "pin", "place", "point of interest", "position", "route", "travel" ] }, "styles": ["solid"], "unicode": "f5a0", "label": "Map Location Dot", "voted": false, "svg": { "solid": { "last_modified": 1684767489, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M408 120c0 54.6-73.1 151.9-105.2 192c-7.7 9.6-22 9.6-29.6 0C241.1 271.9 168 174.6 168 120C168 53.7 221.7 0 288 0s120 53.7 120 120zm8 80.4c3.5-6.9 6.7-13.8 9.6-20.6c.5-1.2 1-2.5 1.5-3.7l116-46.4C558.9 123.4 576 135 576 152V422.8c0 9.8-6 18.6-15.1 22.3L416 503V200.4zM137.6 138.3c2.4 14.1 7.2 28.3 12.8 41.5c2.9 6.8 6.1 13.7 9.6 20.6V451.8L32.9 502.7C17.1 509 0 497.4 0 480.4V209.6c0-9.8 6-18.6 15.1-22.3l122.6-49zM327.8 332c13.9-17.4 35.7-45.7 56.2-77V504.3L192 449.4V255c20.5 31.3 42.3 59.6 56.2 77c20.5 25.6 59.1 25.6 79.6 0zM288 152a40 40 0 1 0 0-80 40 40 0 1 0 0 80z" } }, "free": ["solid"] }, "map-pin": { "aliases": { "unicodes": { "composite": ["1f4cd"], "secondary": ["10f276"] } }, "changes": [ "4.4.0", "5.0.0", "5.2.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "address", "agree", "coordinates", "destination", "gps", "localize", "location", "map", "marker", "navigation", "pin", "place", "position", "pushpin", "round pushpin", "travel" ] }, "styles": ["solid"], "unicode": "f276", "label": "Map Pin", "voted": false, "svg": { "solid": { "last_modified": 1684767488, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M16 144a144 144 0 1 1 288 0A144 144 0 1 1 16 144zM160 80c8.8 0 16-7.2 16-16s-7.2-16-16-16c-53 0-96 43-96 96c0 8.8 7.2 16 16 16s16-7.2 16-16c0-35.3 28.7-64 64-64zM128 480V317.1c10.4 1.9 21.1 2.9 32 2.9s21.6-1 32-2.9V480c0 17.7-14.3 32-32 32s-32-14.3-32-32z" } }, "free": ["solid"] }, "markdown": { "changes": ["5.2.0", "5.7.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f60f", "label": "Markdown", "voted": true, "svg": { "brands": { "last_modified": 1660014480, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M593.8 59.1H46.2C20.7 59.1 0 79.8 0 105.2v301.5c0 25.5 20.7 46.2 46.2 46.2h547.7c25.5 0 46.2-20.7 46.1-46.1V105.2c0-25.4-20.7-46.1-46.2-46.1zM338.5 360.6H277v-120l-61.5 76.9-61.5-76.9v120H92.3V151.4h61.5l61.5 76.9 61.5-76.9h61.5v209.2zm135.3 3.1L381.5 256H443V151.4h61.5V256H566z" } }, "free": ["brands"] }, "marker": { "aliases": { "unicodes": { "secondary": ["10f5a1"] } }, "changes": ["5.1.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["design", "edit", "sharpie", "update", "write"] }, "styles": ["solid"], "unicode": "f5a1", "label": "Marker", "voted": true, "svg": { "solid": { "last_modified": 1684767368, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M481 31C445.1-4.8 386.9-4.8 351 31l-15 15L322.9 33C294.8 4.9 249.2 4.9 221.1 33L135 119c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0L255 66.9c9.4-9.4 24.6-9.4 33.9 0L302.1 80 186.3 195.7 316.3 325.7 481 161c35.9-35.9 35.9-94.1 0-129.9zM293.7 348.3L163.7 218.3 99.5 282.5c-48 48-80.8 109.2-94.1 175.8l-5 25c-1.6 7.9 .9 16 6.6 21.7s13.8 8.1 21.7 6.6l25-5c66.6-13.3 127.8-46.1 175.8-94.1l64.2-64.2z" } }, "free": ["solid"] }, "mars": { "aliases": { "unicodes": { "composite": ["2642"], "secondary": ["10f222"] } }, "changes": ["4.3.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["gender", "male", "male sign", "man"] }, "styles": ["solid"], "unicode": "f222", "label": "Mars", "voted": false, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M289.8 46.8c3.7-9 12.5-14.8 22.2-14.8H424c13.3 0 24 10.7 24 24V168c0 9.7-5.8 18.5-14.8 22.2s-19.3 1.7-26.2-5.2l-33.4-33.4L321 204.2c19.5 28.4 31 62.7 31 99.8c0 97.2-78.8 176-176 176S0 401.2 0 304s78.8-176 176-176c37 0 71.4 11.4 99.8 31l52.6-52.6L295 73c-6.9-6.9-8.9-17.2-5.2-26.2zM400 80l0 0h0v0zM176 416a112 112 0 1 0 0-224 112 112 0 1 0 0 224z" } }, "free": ["solid"] }, "mars-and-venus": { "aliases": { "unicodes": { "composite": ["26a5"], "secondary": ["10f224"] } }, "changes": [ "4.3.0", "5.0.0", "5.11.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Male and Female Sign", "female", "gender", "intersex", "male", "transgender" ] }, "styles": ["solid"], "unicode": "f224", "label": "Mars And Venus", "voted": false, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M337.8 14.8C341.5 5.8 350.3 0 360 0H472c13.3 0 24 10.7 24 24V136c0 9.7-5.8 18.5-14.8 22.2s-19.3 1.7-26.2-5.2l-39-39-24.7 24.7C407 163.3 416 192.6 416 224c0 80.2-59.1 146.7-136.1 158.2c0 .6 .1 1.2 .1 1.8v.4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .3 .4 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3h24c13.3 0 24 10.7 24 24s-10.7 24-24 24H280v.2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0l-24 0-24 0v0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0-.1-.1-.1-.1-.1-.1-.1-.1-.1-.1V486 486v-.1-.1-.1-.1-.1-.1-.1-.1-.1-.1-.1-.1-.1V485 485v-.1-.1-.1-.1-.1-.1-.1-.1-.1-.1-.1V484v-.1-.1-.1-.1-.1-.1-.1-.1-.1-.1V483v-.1-.1-.1-.1-.1-.1-.1-.1-.1-.1-.1-.1-.1-.1-.1-.1-.1-.1-.1V481v-.1-.1-.1-.1-.1-.1-.1-.1V480v-.1-.1-.1-.1-.1-.1-.1V479v-.1-.1-.1-.1-.1-.1-.1V478v-.1-.1-.1-.1-.1-.1V477v-.1-.1-.1-.1-.1-.1V476v-.1-.1-.1-.1-.1-.1V475v-.1-.2-.2-.2-.2-.2V474v-.2-.2-.2-.2-.2V473v-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2V470v-.2-.2-.2-.2-.2V469v-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2V467v-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2V463v-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2V459v-.2-.2-.2-.2-.2-.2-.2-.2V457v-.2-.2-.2-.2V456H208c-13.3 0-24-10.7-24-24s10.7-24 24-24h24v-.3-.3-.3-.3-.3-.3-.3-.3-.3-.3-.3-.3-.3-.3V403v-.3-.3V402v-.3-.3V401v-.3-.3V400v-.3-.3-.3-.3-.3-.3-.3-.3-.3-.3-.3-.3-.3-.4-.3-.4-.4-.4-.4V393v-.4-.4-.4-.4-.4-.4-.4-.4-.4-.4-.4-.4-.4V388v-.4-.4-.4-.4-.4-.4-.4-.4-.4-.4V384c0-.6 0-1.2 .1-1.8C155.1 370.7 96 304.2 96 224c0-88.4 71.6-160 160-160c39.6 0 75.9 14.4 103.8 38.2L382.1 80 343 41c-6.9-6.9-8.9-17.2-5.2-26.2zM448 48l0 0h0v0zM256 488h24c0 13.3-10.7 24-24 24s-24-10.7-24-24h24zm96-264a96 96 0 1 0 -192 0 96 96 0 1 0 192 0z" } }, "free": ["solid"] }, "mars-and-venus-burst": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["gender", "violence"] }, "styles": ["solid"], "unicode": "e523", "label": "Mars And Venus Burst", "voted": false, "svg": { "solid": { "last_modified": 1684767533, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M504 0c-9.7 0-18.5 5.8-22.2 14.8s-1.7 19.3 5.2 26.2l39 39-22.2 22.2C475.9 78.4 439.6 64 400 64c-88.4 0-160 71.6-160 160c0 80.2 59.1 146.7 136.1 158.2c0 .6-.1 1.2-.1 1.8v.4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .4 .3 .4 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3 .3H352c-13.3 0-24 10.7-24 24s10.7 24 24 24h24v.2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .2 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 .1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0l24 0H376c0 13.3 10.7 24 24 24s24-10.7 24-24H400l24 0v0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0-.1-.1-.1-.1-.1-.1-.1-.1-.1-.1V486 486v-.1-.1-.1-.1-.1-.1-.1-.1-.1-.1-.1-.1-.1V485 485v-.1-.1-.1-.1-.1-.1-.1-.1-.1-.1-.1V484v-.1-.1-.1-.1-.1-.1-.1-.1-.1-.1V483v-.1-.1-.1-.1-.1-.1-.1-.1-.1-.1-.1-.1-.1-.1-.1-.1-.1-.1-.1V481v-.1-.1-.1-.1-.1-.1-.1-.1V480v-.1-.1-.1-.1-.1-.1-.1V479v-.1-.1-.1-.1-.1-.1-.1V478v-.1-.1-.1-.1-.1-.1V477v-.1-.1-.1-.1-.1-.1V476v-.1-.1-.1-.1-.1-.1V475v-.1-.2-.2-.2-.2-.2V474v-.2-.2-.2-.2-.2V473v-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2V470v-.2-.2-.2-.2-.2V469v-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2V467v-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2V463v-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2-.2V459v-.2-.2-.2-.2-.2-.2-.2-.2V457v-.2-.2-.2-.2V456h24c13.3 0 24-10.7 24-24s-10.7-24-24-24H424v-.3-.3-.3-.3-.3-.3-.3-.3-.3-.3-.3-.3-.3-.3V403v-.3-.3V402v-.3-.3V401v-.3-.3V400v-.3-.3-.3-.3-.3-.3-.3-.3-.3-.3-.3-.3-.3-.4-.3-.4-.4-.4-.4V393v-.4-.4-.4-.4-.4-.4-.4-.4-.4-.4-.4-.4-.4V388v-.4-.4-.4-.4-.4-.4-.4-.4-.4-.4V384c0-.6 0-1.2-.1-1.8c77-11.6 136.1-78 136.1-158.2c0-31.4-9-60.7-24.7-85.4L560 113.9l39 39c6.9 6.9 17.2 8.9 26.2 5.2s14.8-12.5 14.8-22.2V24c0-13.3-10.7-24-24-24H504zM400 128a96 96 0 1 1 0 192 96 96 0 1 1 0-192zM190.9 18.1C188.4 12 182.6 8 176 8s-12.4 4-14.9 10.1l-29.4 74L55.6 68.9c-6.3-1.9-13.1 .2-17.2 5.3s-4.6 12.2-1.4 17.9l39.5 69.1L10.9 206.4c-5.4 3.7-8 10.3-6.5 16.7s6.7 11.2 13.1 12.2l78.7 12.2L90.6 327c-.5 6.5 3.1 12.7 9 15.5s12.9 1.8 17.8-2.6L176 286.1l58.6 53.9c4.1 3.8 9.9 5.1 15.2 3.6C223.6 310.8 208 269.2 208 224c0-60.8 28.3-115 72.4-150.2L220.3 92.1l-29.4-74z" } }, "free": ["solid"] }, "mars-double": { "aliases": { "unicodes": { "composite": ["26a3"], "secondary": ["10f227"] } }, "changes": ["4.3.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Doubled Male Sign", "gay", "gender", "male", "men"] }, "styles": ["solid"], "unicode": "f227", "label": "Mars Double", "voted": false, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M312 32c-9.7 0-18.5 5.8-22.2 14.8s-1.7 19.3 5.2 26.2l33.4 33.4L275.8 159c-28.4-19.5-62.7-31-99.8-31C78.8 128 0 206.8 0 304s78.8 176 176 176s176-78.8 176-176c0-37-11.4-71.4-31-99.8l52.6-52.6L407 185c6.9 6.9 17.2 8.9 26.2 5.2s14.8-12.5 14.8-22.2V56c0-13.3-10.7-24-24-24H312zm88 48h0v0l0 0zM64 304a112 112 0 1 1 224 0A112 112 0 1 1 64 304zM368 480c97.2 0 176-78.8 176-176c0-37-11.4-71.4-31-99.8l52.6-52.6L599 185c6.9 6.9 17.2 8.9 26.2 5.2s14.8-12.5 14.8-22.2V56c0-13.3-10.7-24-24-24H504c-9.7 0-18.5 5.8-22.2 14.8c-1.2 2.9-1.8 6-1.8 9l0 .2v.2c0 6.2 2.5 12.2 7 16.8l33.4 33.4L480 146.7V168c0 22.6-13.6 43.1-34.6 51.7c-.8 .3-1.7 .7-2.5 1C465.7 241.2 480 270.9 480 304c0 61.9-50.1 112-112 112c-5.4 0-10.8-.4-16-1.1c-12.9 20.4-29.1 38.3-48.1 53.1c19.8 7.8 41.4 12 64 12z" } }, "free": ["solid"] }, "mars-stroke": { "aliases": { "unicodes": { "composite": ["26a6"], "secondary": ["10f229"] } }, "changes": ["4.3.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Male with Stroke Sign", "gender", "transgender"] }, "styles": ["solid"], "unicode": "f229", "label": "Mars Stroke", "voted": false, "svg": { "solid": { "last_modified": 1684766751, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M376 0c-9.7 0-18.5 5.8-22.2 14.8s-1.7 19.3 5.2 26.2l33.4 33.4L370.3 96.4 345 71c-9.4-9.4-24.6-9.4-33.9 0s-9.4 24.6 0 33.9l25.4 25.4L307.8 159c-28.4-19.5-62.7-31-99.8-31c-97.2 0-176 78.8-176 176s78.8 176 176 176s176-78.8 176-176c0-37-11.4-71.4-31-99.8l28.6-28.6L407 201c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9l-25.4-25.4 22.1-22.1L471 153c6.9 6.9 17.2 8.9 26.2 5.2s14.8-12.5 14.8-22.2V24c0-13.3-10.7-24-24-24H376zm88 48h0v0l0 0zM96 304a112 112 0 1 1 224 0A112 112 0 1 1 96 304z" } }, "free": ["solid"] }, "mars-stroke-right": { "aliases": { "names": ["mars-stroke-h"], "unicodes": { "composite": ["26a9"], "secondary": ["10f22b"] } }, "changes": [ "4.3.0", "5.0.0", "5.11.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["Horizontal Male with Stroke Sign", "gender"] }, "styles": ["solid"], "unicode": "f22b", "label": "Mars Stroke Right", "voted": false, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M208 368a112 112 0 1 0 0-224 112 112 0 1 0 0 224zm174.4-88C370.7 365.8 297.1 432 208 432c-97.2 0-176-78.8-176-176s78.8-176 176-176c89.1 0 162.7 66.2 174.4 152H416V176c0-13.3 10.7-24 24-24s24 10.7 24 24v56h32V176c0-9.7 5.8-18.5 14.8-22.2s19.3-1.7 26.2 5.2l80 80c9.4 9.4 9.4 24.6 0 33.9l-80 80c-6.9 6.9-17.2 8.9-26.2 5.2s-14.8-12.5-14.8-22.2V280H464v56c0 13.3-10.7 24-24 24s-24-10.7-24-24V280H382.4z" } }, "free": ["solid"] }, "mars-stroke-up": { "aliases": { "names": ["mars-stroke-v"], "unicodes": { "composite": ["26a8"], "secondary": ["10f22a"] } }, "changes": [ "4.3.0", "5.0.0", "5.11.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["Vertical Male with Stroke Sign", "gender"] }, "styles": ["solid"], "unicode": "f22a", "label": "Mars Stroke Up", "voted": false, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M148.7 4.7c6.2-6.2 16.4-6.2 22.6 0l64 64c4.6 4.6 5.9 11.5 3.5 17.4s-8.3 9.9-14.8 9.9H184v24h32c13.3 0 24 10.7 24 24s-10.7 24-24 24H184v24c0 .6 0 1.2-.1 1.8c77 11.6 136.1 78 136.1 158.2c0 88.4-71.6 160-160 160S0 440.4 0 352c0-80.2 59.1-146.7 136.1-158.2c0-.6-.1-1.2-.1-1.8V168H104c-13.3 0-24-10.7-24-24s10.7-24 24-24h32V96H96c-6.5 0-12.3-3.9-14.8-9.9s-1.1-12.9 3.5-17.4l64-64zM256 352A96 96 0 1 0 64 352a96 96 0 1 0 192 0z" } }, "free": ["solid"] }, "martini-glass": { "aliases": { "names": ["glass-martini-alt"], "unicodes": { "composite": ["1f378"], "secondary": ["10f57b"] } }, "changes": ["5.1.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "alcohol", "bar", "beverage", "cocktail", "cocktail glass", "drink", "glass", "liquor" ] }, "styles": ["solid"], "unicode": "f57b", "label": "Martini Glass", "voted": false, "svg": { "solid": { "last_modified": 1684767420, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M32 0C19.1 0 7.4 7.8 2.4 19.8s-2.2 25.7 6.9 34.9L224 269.3V448H160c-17.7 0-32 14.3-32 32s14.3 32 32 32h96 96c17.7 0 32-14.3 32-32s-14.3-32-32-32H288V269.3L502.6 54.6c9.2-9.2 11.9-22.9 6.9-34.9S492.9 0 480 0H32zM173.3 128l-64-64H402.7l-64 64H173.3z" } }, "free": ["solid"] }, "martini-glass-citrus": { "aliases": { "names": ["cocktail"], "unicodes": { "secondary": ["10f561"] } }, "changes": ["5.1.0", "5.10.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "alcohol", "beverage", "drink", "gin", "glass", "margarita", "martini", "vodka" ] }, "styles": ["solid"], "unicode": "f561", "label": "Martini Glass Citrus", "voted": false, "svg": { "solid": { "last_modified": 1684767420, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M432 240c53 0 96-43 96-96s-43-96-96-96c-35.5 0-66.6 19.3-83.2 48H296.2C316 40.1 369.3 0 432 0c79.5 0 144 64.5 144 144s-64.5 144-144 144c-27.7 0-53.5-7.8-75.5-21.3l35.4-35.4c12.2 5.6 25.8 8.7 40.1 8.7zM1.8 142.8C5.5 133.8 14.3 128 24 128H392c9.7 0 18.5 5.8 22.2 14.8s1.7 19.3-5.2 26.2l-177 177V464h64c13.3 0 24 10.7 24 24s-10.7 24-24 24H208 120c-13.3 0-24-10.7-24-24s10.7-24 24-24h64V345.9L7 169c-6.9-6.9-8.9-17.2-5.2-26.2z" } }, "free": ["solid"] }, "martini-glass-empty": { "aliases": { "names": ["glass-martini"], "unicodes": { "secondary": ["10f000"] } }, "changes": [ "1.0.0", "5.0.0", "5.1.0", "5.10.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["alcohol", "bar", "beverage", "drink", "liquor"] }, "styles": ["solid"], "unicode": "f000", "label": "Martini Glass Empty", "voted": false, "svg": { "solid": { "last_modified": 1684767420, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M32 0C19.1 0 7.4 7.8 2.4 19.8s-2.2 25.7 6.9 34.9L224 269.3V448H160c-17.7 0-32 14.3-32 32s14.3 32 32 32h96 96c17.7 0 32-14.3 32-32s-14.3-32-32-32H288V269.3L502.6 54.6c9.2-9.2 11.9-22.9 6.9-34.9S492.9 0 480 0H32zM256 210.7L109.3 64H402.7L256 210.7z" } }, "free": ["solid"] }, "mask": { "aliases": { "unicodes": { "secondary": ["10f6fa"] } }, "changes": ["5.4.0", "5.10.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "carnivale", "costume", "disguise", "halloween", "secret", "super hero" ] }, "styles": ["solid"], "unicode": "f6fa", "label": "Mask", "voted": false, "svg": { "solid": { "last_modified": 1684767601, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M288 64C64 64 0 160 0 272S80 448 176 448h8.4c24.2 0 46.4-13.7 57.2-35.4l23.2-46.3c4.4-8.8 13.3-14.3 23.2-14.3s18.8 5.5 23.2 14.3l23.2 46.3c10.8 21.7 33 35.4 57.2 35.4H400c96 0 176-64 176-176s-64-208-288-208zM96 256a64 64 0 1 1 128 0A64 64 0 1 1 96 256zm320-64a64 64 0 1 1 0 128 64 64 0 1 1 0-128z" } }, "free": ["solid"] }, "mask-face": { "changes": ["6.0.0-beta1", "6.0.0", "6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "breath", "coronavirus", "covid-19", "filter", "flu", "infection", "pandemic", "respirator", "virus" ] }, "styles": ["solid"], "unicode": "e1d7", "label": "Mask Face", "voted": false, "svg": { "solid": { "last_modified": 1684766749, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M320 64c-27.2 0-53.8 8-76.4 23.1l-37.1 24.8c-15.8 10.5-34.3 16.1-53.3 16.1H144 128 56c-30.9 0-56 25.1-56 56v85c0 55.1 37.5 103.1 90.9 116.4l108 27C233.8 435 275.4 448 320 448s86.2-13 121.1-35.5l108-27C602.5 372.1 640 324.1 640 269V184c0-30.9-25.1-56-56-56H512 496h-9.2c-19 0-37.5-5.6-53.3-16.1L396.4 87.1C373.8 72 347.2 64 320 64zM132.3 346.3l-29.8-7.4C70.5 330.9 48 302.1 48 269V184c0-4.4 3.6-8 8-8H96v48c0 45.1 13.4 87.2 36.3 122.3zm405.1-7.4l-29.8 7.4c23-35.2 36.3-77.2 36.3-122.3V176h40c4.4 0 8 3.6 8 8v85c0 33-22.5 61.8-54.5 69.9zM192 208c0-8.8 7.2-16 16-16H432c8.8 0 16 7.2 16 16s-7.2 16-16 16H208c-8.8 0-16-7.2-16-16zm16 48H432c8.8 0 16 7.2 16 16s-7.2 16-16 16H208c-8.8 0-16-7.2-16-16s7.2-16 16-16zm16 80c0-8.8 7.2-16 16-16H400c8.8 0 16 7.2 16 16s-7.2 16-16 16H240c-8.8 0-16-7.2-16-16z" } }, "free": ["solid"] }, "mask-ventilator": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["breath", "gas", "mask", "oxygen", "respirator", "ventilator"] }, "styles": ["solid"], "unicode": "e524", "label": "Mask Ventilator", "voted": false, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M159.1 176C139.4 219.2 128 264.7 128 300.8c0 15.9 2.2 31.4 6.3 46l-31.8-7.9C70.5 330.9 48 302.1 48 269V184c0-4.4 3.6-8 8-8H159.1zm26-48H56c-30.9 0-56 25.1-56 56v85c0 55.1 37.5 103.1 90.9 116.4l71.3 17.8c22.7 30.5 55.4 54.1 93.8 66.6V393.3c-19.7-16.4-32-40.3-32-66.9c0-49.5 43-134.4 96-134.4c52.5 0 96 84.9 96 134.4c0 26.7-12.4 50.4-32 66.8v76.6c38-12.6 70.6-36 93.5-66.4l71.6-17.9C602.5 372.1 640 324.1 640 269V184c0-30.9-25.1-56-56-56H454.5C419.7 73.8 372.1 32 320 32c-52.6 0-100.2 41.8-134.9 96zm295.6 48H584c4.4 0 8 3.6 8 8v85c0 33-22.5 61.8-54.5 69.9l-31.8 8c4.2-14.7 6.4-30.1 6.4-46.1c0-36.1-11.6-81.6-31.3-124.8zM288 320V512h64V320c0-17.7-14.3-32-32-32s-32 14.3-32 32z" } }, "free": ["solid"] }, "masks-theater": { "aliases": { "names": ["theater-masks"], "unicodes": { "composite": ["1f3ad"], "secondary": ["10f630"] } }, "changes": ["5.2.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "art", "comedy", "mask", "perform", "performing", "performing arts", "theater", "theatre", "tragedy" ] }, "styles": ["solid"], "unicode": "f630", "label": "Masks Theater", "voted": false, "svg": { "solid": { "last_modified": 1684767601, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M74.6 373.2c41.7 36.1 108 82.5 166.1 73.7c6.1-.9 12.1-2.5 18-4.5c-9.2-12.3-17.3-24.4-24.2-35.4c-21.9-35-28.8-75.2-25.9-113.6c-20.6 4.1-39.2 13-54.7 25.4c-6.5 5.2-16.3 1.3-14.8-7c6.4-33.5 33-60.9 68.2-66.3c2.6-.4 5.3-.7 7.9-.8l19.4-131.3c2-13.8 8-32.7 25-45.9C278.2 53.2 310.5 37 363.2 32.2c-.8-.7-1.6-1.4-2.4-2.1C340.6 14.5 288.4-11.5 175.7 5.6S20.5 63 5.7 83.9C0 91.9-.8 102 .6 111.8L24.8 276.1c5.5 37.3 21.5 72.6 49.8 97.2zm87.7-219.6c4.4-3.1 10.8-2 11.8 3.3c.1 .5 .2 1.1 .3 1.6c3.2 21.8-11.6 42-33.1 45.3s-41.5-11.8-44.7-33.5c-.1-.5-.1-1.1-.2-1.6c-.6-5.4 5.2-8.4 10.3-6.7c9 3 18.8 3.9 28.7 2.4s19.1-5.3 26.8-10.8zM261.6 390c29.4 46.9 79.5 110.9 137.6 119.7s124.5-37.5 166.1-73.7c28.3-24.5 44.3-59.8 49.8-97.2l24.2-164.3c1.4-9.8 .6-19.9-5.1-27.9c-14.8-20.9-57.3-61.2-170-78.3S299.4 77.2 279.2 92.8c-7.8 6-11.5 15.4-12.9 25.2L242.1 282.3c-5.5 37.3-.4 75.8 19.6 107.7zM404.5 235.3c-7.7-5.5-16.8-9.3-26.8-10.8s-19.8-.6-28.7 2.4c-5.1 1.7-10.9-1.3-10.3-6.7c.1-.5 .1-1.1 .2-1.6c3.2-21.8 23.2-36.8 44.7-33.5s36.3 23.5 33.1 45.3c-.1 .5-.2 1.1-.3 1.6c-1 5.3-7.4 6.4-11.8 3.3zm136.2 15.5c-1 5.3-7.4 6.4-11.8 3.3c-7.7-5.5-16.8-9.3-26.8-10.8s-19.8-.6-28.7 2.4c-5.1 1.7-10.9-1.3-10.3-6.7c.1-.5 .1-1.1 .2-1.6c3.2-21.8 23.2-36.8 44.7-33.5s36.3 23.5 33.1 45.3c-.1 .5-.2 1.1-.3 1.6zM530 350.2c-19.6 44.7-66.8 72.5-116.8 64.9s-87.1-48.2-93-96.7c-1-8.3 8.9-12.1 15.2-6.7c23.9 20.8 53.6 35.3 87 40.3s66.1 .1 94.9-12.8c7.6-3.4 16 3.2 12.6 10.9z" } }, "free": ["solid"] }, "mastodon": { "changes": ["5.0.11", "5.8.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f4f6", "label": "Mastodon", "voted": true, "svg": { "brands": { "last_modified": 1660014459, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M433 179.11c0-97.2-63.71-125.7-63.71-125.7-62.52-28.7-228.56-28.4-290.48 0 0 0-63.72 28.5-63.72 125.7 0 115.7-6.6 259.4 105.63 289.1 40.51 10.7 75.32 13 103.33 11.4 50.81-2.8 79.32-18.1 79.32-18.1l-1.7-36.9s-36.31 11.4-77.12 10.1c-40.41-1.4-83-4.4-89.63-54a102.54 102.54 0 0 1-.9-13.9c85.63 20.9 158.65 9.1 178.75 6.7 56.12-6.7 105-41.3 111.23-72.9 9.8-49.8 9-121.5 9-121.5zm-75.12 125.2h-46.63v-114.2c0-49.7-64-51.6-64 6.9v62.5h-46.33V197c0-58.5-64-56.6-64-6.9v114.2H90.19c0-122.1-5.2-147.9 18.41-175 25.9-28.9 79.82-30.8 103.83 6.1l11.6 19.5 11.6-19.5c24.11-37.1 78.12-34.8 103.83-6.1 23.71 27.3 18.4 53 18.4 175z" } }, "free": ["brands"] }, "mattress-pillow": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["air mattress", "mattress", "pillow", "rest", "sleep"] }, "styles": ["solid"], "unicode": "e525", "label": "Mattress Pillow", "voted": false, "svg": { "solid": { "last_modified": 1684767443, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M256 64H64C28.7 64 0 92.7 0 128V384c0 35.3 28.7 64 64 64H256V64zm32 384H576c35.3 0 64-28.7 64-64V128c0-35.3-28.7-64-64-64H288V448zM64 160c0-17.7 14.3-32 32-32h64c17.7 0 32 14.3 32 32V352c0 17.7-14.3 32-32 32H96c-17.7 0-32-14.3-32-32V160z" } }, "free": ["solid"] }, "maxcdn": { "changes": ["3.1.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f136", "label": "MaxCDN", "voted": false, "svg": { "brands": { "last_modified": 1660014468, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M461.1 442.7h-97.4L415.6 200c2.3-10.2.9-19.5-4.4-25.7-5-6.1-13.7-9.6-24.2-9.6h-49.3l-59.5 278h-97.4l59.5-278h-83.4l-59.5 278H0l59.5-278-44.6-95.4H387c39.4 0 75.3 16.3 98.3 44.9 23.3 28.6 31.8 67.4 23.6 105.9l-47.8 222.6z" } }, "free": ["brands"] }, "maximize": { "aliases": { "names": ["expand-arrows-alt"], "unicodes": { "secondary": ["10f31e"] } }, "changes": ["5.0.0", "5.8.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["bigger", "enlarge", "fullscreen", "move", "resize"] }, "styles": ["solid"], "unicode": "f31e", "label": "Maximize", "voted": false, "svg": { "solid": { "last_modified": 1684766331, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M200 32H56C42.7 32 32 42.7 32 56V200c0 9.7 5.8 18.5 14.8 22.2s19.3 1.7 26.2-5.2l40-40 79 79-79 79L73 295c-6.9-6.9-17.2-8.9-26.2-5.2S32 302.3 32 312V456c0 13.3 10.7 24 24 24H200c9.7 0 18.5-5.8 22.2-14.8s1.7-19.3-5.2-26.2l-40-40 79-79 79 79-40 40c-6.9 6.9-8.9 17.2-5.2 26.2s12.5 14.8 22.2 14.8H456c13.3 0 24-10.7 24-24V312c0-9.7-5.8-18.5-14.8-22.2s-19.3-1.7-26.2 5.2l-40 40-79-79 79-79 40 40c6.9 6.9 17.2 8.9 26.2 5.2s14.8-12.5 14.8-22.2V56c0-13.3-10.7-24-24-24H312c-9.7 0-18.5 5.8-22.2 14.8s-1.7 19.3 5.2 26.2l40 40-79 79-79-79 40-40c6.9-6.9 8.9-17.2 5.2-26.2S209.7 32 200 32z" } }, "free": ["solid"] }, "mdb": { "changes": ["5.11.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f8ca", "label": "Material Design for Bootstrap", "voted": false, "svg": { "brands": { "last_modified": 1660014474, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M17.37 160.41L7 352h43.91l5.59-79.83L84.43 352h44.71l25.54-77.43 4.79 77.43H205l-12.79-191.59H146.7L106 277.74 63.67 160.41zm281 0h-47.9V352h47.9s95 .8 94.2-95.79c-.78-94.21-94.18-95.78-94.18-95.78zm-1.2 146.46V204.78s46 4.27 46.8 50.57-46.78 51.54-46.78 51.54zm238.29-74.24a56.16 56.16 0 0 0 8-38.31c-5.34-35.76-55.08-34.32-55.08-34.32h-51.9v191.58H482s87 4.79 87-63.85c0-43.14-33.52-55.08-33.52-55.08zm-51.9-31.94s13.57-1.59 16 9.59c1.43 6.66-4 12-4 12h-12v-21.57zm-.1 109.46l.1-24.92V267h.08s41.58-4.73 41.19 22.43c-.33 25.65-41.35 20.74-41.35 20.74z" } }, "free": ["brands"] }, "medal": { "aliases": { "unicodes": { "composite": ["1f3c5"], "secondary": ["10f5a2"] } }, "changes": ["5.1.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["award", "medal", "ribbon", "sports medal", "star", "trophy"] }, "styles": ["solid"], "unicode": "f5a2", "label": "Medal", "voted": true, "svg": { "solid": { "last_modified": 1684767602, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M4.1 38.2C1.4 34.2 0 29.4 0 24.6C0 11 11 0 24.6 0H133.9c11.2 0 21.7 5.9 27.4 15.5l68.5 114.1c-48.2 6.1-91.3 28.6-123.4 61.9L4.1 38.2zm503.7 0L405.6 191.5c-32.1-33.3-75.2-55.8-123.4-61.9L350.7 15.5C356.5 5.9 366.9 0 378.1 0H487.4C501 0 512 11 512 24.6c0 4.8-1.4 9.6-4.1 13.6zM80 336a176 176 0 1 1 352 0A176 176 0 1 1 80 336zm184.4-94.9c-3.4-7-13.3-7-16.8 0l-22.4 45.4c-1.4 2.8-4 4.7-7 5.1L168 298.9c-7.7 1.1-10.7 10.5-5.2 16l36.3 35.4c2.2 2.2 3.2 5.2 2.7 8.3l-8.6 49.9c-1.3 7.6 6.7 13.5 13.6 9.9l44.8-23.6c2.7-1.4 6-1.4 8.7 0l44.8 23.6c6.9 3.6 14.9-2.2 13.6-9.9l-8.6-49.9c-.5-3 .5-6.1 2.7-8.3l36.3-35.4c5.6-5.4 2.5-14.8-5.2-16l-50.1-7.3c-3-.4-5.7-2.4-7-5.1l-22.4-45.4z" } }, "free": ["solid"] }, "medapps": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3c6", "label": "MedApps", "voted": false, "svg": { "brands": { "last_modified": 1660014464, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M118.3 238.4c3.5-12.5 6.9-33.6 13.2-33.6 8.3 1.8 9.6 23.4 18.6 36.6 4.6-23.5 5.3-85.1 14.1-86.7 9-.7 19.7 66.5 22 77.5 9.9 4.1 48.9 6.6 48.9 6.6 1.9 7.3-24 7.6-40 7.8-4.6 14.8-5.4 27.7-11.4 28-4.7.2-8.2-28.8-17.5-49.6l-9.4 65.5c-4.4 13-15.5-22.5-21.9-39.3-3.3-.1-62.4-1.6-47.6-7.8l31-5zM228 448c21.2 0 21.2-32 0-32H92c-21.2 0-21.2 32 0 32h136zm-24 64c21.2 0 21.2-32 0-32h-88c-21.2 0-21.2 32 0 32h88zm34.2-141.5c3.2-18.9 5.2-36.4 11.9-48.8 7.9-14.7 16.1-28.1 24-41 24.6-40.4 45.9-75.2 45.9-125.5C320 69.6 248.2 0 160 0S0 69.6 0 155.2c0 50.2 21.3 85.1 45.9 125.5 7.9 12.9 16 26.3 24 41 6.7 12.5 8.7 29.8 11.9 48.9 3.5 21 36.1 15.7 32.6-5.1-3.6-21.7-5.6-40.7-15.3-58.6C66.5 246.5 33 211.3 33 155.2 33 87.3 90 32 160 32s127 55.3 127 123.2c0 56.1-33.5 91.3-66.1 151.6-9.7 18-11.7 37.4-15.3 58.6-3.4 20.6 29 26.4 32.6 5.1z" } }, "free": ["brands"] }, "medium": { "aliases": { "names": ["medium-m"], "unicodes": { "composite": ["f3c7"] } }, "changes": ["4.3.0", "5.0.0", "6.0.0-beta1"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f23a", "label": "Medium", "voted": false, "svg": { "brands": { "last_modified": 1660014460, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M180.5,74.262C80.813,74.262,0,155.633,0,256S80.819,437.738,180.5,437.738,361,356.373,361,256,280.191,74.262,180.5,74.262Zm288.25,10.646c-49.845,0-90.245,76.619-90.245,171.095s40.406,171.1,90.251,171.1,90.251-76.619,90.251-171.1H559C559,161.5,518.6,84.908,468.752,84.908Zm139.506,17.821c-17.526,0-31.735,68.628-31.735,153.274s14.2,153.274,31.735,153.274S640,340.631,640,256C640,171.351,625.785,102.729,608.258,102.729Z" } }, "free": ["brands"] }, "medrt": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3c8", "label": "MRT", "voted": false, "svg": { "brands": { "last_modified": 1660014460, "raw": "", "viewBox": [0, 0, 544, 512], "width": 544, "height": 512, "path": "M113.7 256c0 121.8 83.9 222.8 193.5 241.1-18.7 4.5-38.2 6.9-58.2 6.9C111.4 504 0 393 0 256S111.4 8 248.9 8c20.1 0 39.6 2.4 58.2 6.9C197.5 33.2 113.7 134.2 113.7 256m297.4 100.3c-77.7 55.4-179.6 47.5-240.4-14.6 5.5 14.1 12.7 27.7 21.7 40.5 61.6 88.2 182.4 109.3 269.7 47 87.3-62.3 108.1-184.3 46.5-272.6-9-12.9-19.3-24.3-30.5-34.2 37.4 78.8 10.7 178.5-67 233.9m-218.8-244c-1.4 1-2.7 2.1-4 3.1 64.3-17.8 135.9 4 178.9 60.5 35.7 47 42.9 106.6 24.4 158 56.7-56.2 67.6-142.1 22.3-201.8-50-65.5-149.1-74.4-221.6-19.8M296 224c-4.4 0-8-3.6-8-8v-40c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8v40c0 4.4-3.6 8-8 8h-40c-4.4 0-8 3.6-8 8v48c0 4.4 3.6 8 8 8h40c4.4 0 8 3.6 8 8v40c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8v-40c0-4.4 3.6-8 8-8h40c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8h-40z" } }, "free": ["brands"] }, "meetup": { "changes": ["4.7.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f2e0", "label": "Meetup", "voted": false, "svg": { "brands": { "last_modified": 1660014478, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M99 414.3c1.1 5.7-2.3 11.1-8 12.3-5.4 1.1-10.9-2.3-12-8-1.1-5.4 2.3-11.1 7.7-12.3 5.4-1.2 11.1 2.3 12.3 8zm143.1 71.4c-6.3 4.6-8 13.4-3.7 20 4.6 6.6 13.4 8.3 20 3.7 6.3-4.6 8-13.4 3.4-20-4.2-6.5-13.1-8.3-19.7-3.7zm-86-462.3c6.3-1.4 10.3-7.7 8.9-14-1.1-6.6-7.4-10.6-13.7-9.1-6.3 1.4-10.3 7.7-9.1 14 1.4 6.6 7.6 10.6 13.9 9.1zM34.4 226.3c-10-6.9-23.7-4.3-30.6 6-6.9 10-4.3 24 5.7 30.9 10 7.1 23.7 4.6 30.6-5.7 6.9-10.4 4.3-24.1-5.7-31.2zm272-170.9c10.6-6.3 13.7-20 7.7-30.3-6.3-10.6-19.7-14-30-7.7s-13.7 20-7.4 30.6c6 10.3 19.4 13.7 29.7 7.4zm-191.1 58c7.7-5.4 9.4-16 4.3-23.7s-15.7-9.4-23.1-4.3c-7.7 5.4-9.4 16-4.3 23.7 5.1 7.8 15.6 9.5 23.1 4.3zm372.3 156c-7.4 1.7-12.3 9.1-10.6 16.9 1.4 7.4 8.9 12.3 16.3 10.6 7.4-1.4 12.3-8.9 10.6-16.6-1.5-7.4-8.9-12.3-16.3-10.9zm39.7-56.8c-1.1-5.7-6.6-9.1-12-8-5.7 1.1-9.1 6.9-8 12.6 1.1 5.4 6.6 9.1 12.3 8 5.4-1.5 9.1-6.9 7.7-12.6zM447 138.9c-8.6 6-10.6 17.7-4.9 26.3 5.7 8.6 17.4 10.6 26 4.9 8.3-6 10.3-17.7 4.6-26.3-5.7-8.7-17.4-10.9-25.7-4.9zm-6.3 139.4c26.3 43.1 15.1 100-26.3 129.1-17.4 12.3-37.1 17.7-56.9 17.1-12 47.1-69.4 64.6-105.1 32.6-1.1.9-2.6 1.7-3.7 2.9-39.1 27.1-92.3 17.4-119.4-22.3-9.7-14.3-14.6-30.6-15.1-46.9-65.4-10.9-90-94-41.1-139.7-28.3-46.9.6-107.4 53.4-114.9C151.6 70 234.1 38.6 290.1 82c67.4-22.3 136.3 29.4 130.9 101.1 41.1 12.6 52.8 66.9 19.7 95.2zm-70 74.3c-3.1-20.6-40.9-4.6-43.1-27.1-3.1-32 43.7-101.1 40-128-3.4-24-19.4-29.1-33.4-29.4-13.4-.3-16.9 2-21.4 4.6-2.9 1.7-6.6 4.9-11.7-.3-6.3-6-11.1-11.7-19.4-12.9-12.3-2-17.7 2-26.6 9.7-3.4 2.9-12 12.9-20 9.1-3.4-1.7-15.4-7.7-24-11.4-16.3-7.1-40 4.6-48.6 20-12.9 22.9-38 113.1-41.7 125.1-8.6 26.6 10.9 48.6 36.9 47.1 11.1-.6 18.3-4.6 25.4-17.4 4-7.4 41.7-107.7 44.6-112.6 2-3.4 8.9-8 14.6-5.1 5.7 3.1 6.9 9.4 6 15.1-1.1 9.7-28 70.9-28.9 77.7-3.4 22.9 26.9 26.6 38.6 4 3.7-7.1 45.7-92.6 49.4-98.3 4.3-6.3 7.4-8.3 11.7-8 3.1 0 8.3.9 7.1 10.9-1.4 9.4-35.1 72.3-38.9 87.7-4.6 20.6 6.6 41.4 24.9 50.6 11.4 5.7 62.5 15.7 58.5-11.1zm5.7 92.3c-10.3 7.4-12.9 22-5.7 32.6 7.1 10.6 21.4 13.1 32 6 10.6-7.4 13.1-22 6-32.6-7.4-10.6-21.7-13.5-32.3-6z" } }, "free": ["brands"] }, "megaport": { "changes": ["5.1.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f5a3", "label": "Megaport", "voted": false, "svg": { "brands": { "last_modified": 1660014469, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M214.5 209.6v66.2l33.5 33.5 33.3-33.3v-66.4l-33.4-33.4zM248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm145.1 414.4L367 441.6l-26-19.2v-65.5l-33.4-33.4-33.4 33.4v65.5L248 441.6l-26.1-19.2v-65.5l-33.4-33.4-33.5 33.4v65.5l-26.1 19.2-26.1-19.2v-87l59.5-59.5V188l59.5-59.5V52.9l26.1-19.2L274 52.9v75.6l59.5 59.5v87.6l59.7 59.7v87.1z" } }, "free": ["brands"] }, "memory": { "aliases": { "unicodes": { "secondary": ["10f538"] } }, "changes": ["5.0.13", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["DIMM", "RAM", "hardware", "storage", "technology"] }, "styles": ["solid"], "unicode": "f538", "label": "Memory", "voted": true, "svg": { "solid": { "last_modified": 1684767343, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M64 64C28.7 64 0 92.7 0 128v7.4c0 6.8 4.4 12.6 10.1 16.3C23.3 160.3 32 175.1 32 192s-8.7 31.7-21.9 40.3C4.4 236 0 241.8 0 248.6V320H576V248.6c0-6.8-4.4-12.6-10.1-16.3C552.7 223.7 544 208.9 544 192s8.7-31.7 21.9-40.3c5.7-3.7 10.1-9.5 10.1-16.3V128c0-35.3-28.7-64-64-64H64zM576 352H0v64c0 17.7 14.3 32 32 32H80V416c0-8.8 7.2-16 16-16s16 7.2 16 16v32h96V416c0-8.8 7.2-16 16-16s16 7.2 16 16v32h96V416c0-8.8 7.2-16 16-16s16 7.2 16 16v32h96V416c0-8.8 7.2-16 16-16s16 7.2 16 16v32h48c17.7 0 32-14.3 32-32V352zM192 160v64c0 17.7-14.3 32-32 32s-32-14.3-32-32V160c0-17.7 14.3-32 32-32s32 14.3 32 32zm128 0v64c0 17.7-14.3 32-32 32s-32-14.3-32-32V160c0-17.7 14.3-32 32-32s32 14.3 32 32zm128 0v64c0 17.7-14.3 32-32 32s-32-14.3-32-32V160c0-17.7 14.3-32 32-32s32 14.3 32 32z" } }, "free": ["solid"] }, "mendeley": { "changes": ["5.6.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f7b3", "label": "Mendeley", "voted": true, "svg": { "brands": { "last_modified": 1660014466, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M624.6 325.2c-12.3-12.4-29.7-19.2-48.4-17.2-43.3-1-49.7-34.9-37.5-98.8 22.8-57.5-14.9-131.5-87.4-130.8-77.4.7-81.7 82-130.9 82-48.1 0-54-81.3-130.9-82-72.9-.8-110.1 73.3-87.4 130.8 12.2 63.9 5.8 97.8-37.5 98.8-21.2-2.3-37 6.5-53 22.5-19.9 19.7-19.3 94.8 42.6 102.6 47.1 5.9 81.6-42.9 61.2-87.8-47.3-103.7 185.9-106.1 146.5-8.2-.1.1-.2.2-.3.4-26.8 42.8 6.8 97.4 58.8 95.2 52.1 2.1 85.4-52.6 58.8-95.2-.1-.2-.2-.3-.3-.4-39.4-97.9 193.8-95.5 146.5 8.2-4.6 10-6.7 21.3-5.7 33 4.9 53.4 68.7 74.1 104.9 35.2 17.8-14.8 23.1-65.6 0-88.3zm-303.9-19.1h-.6c-43.4 0-62.8-37.5-62.8-62.8 0-34.7 28.2-62.8 62.8-62.8h.6c34.7 0 62.8 28.1 62.8 62.8 0 25-19.2 62.8-62.8 62.8z" } }, "free": ["brands"] }, "menorah": { "aliases": { "unicodes": { "secondary": ["10f676"] } }, "changes": ["5.3.0", "5.4.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["candle", "hanukkah", "jewish", "judaism", "light"] }, "styles": ["solid"], "unicode": "f676", "label": "Menorah", "voted": false, "svg": { "solid": { "last_modified": 1684767444, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M20.8 7.4C22.8 2.9 27.1 0 32 0s9.2 2.9 11.2 7.4L61.3 49.7c1.8 4.1 2.7 8.6 2.7 13.1V64c0 17.7-14.3 32-32 32S0 81.7 0 64V62.8c0-4.5 .9-8.9 2.7-13.1L20.8 7.4zm96 0C118.8 2.9 123.1 0 128 0s9.2 2.9 11.2 7.4l18.2 42.4c1.8 4.1 2.7 8.6 2.7 13.1V64c0 17.7-14.3 32-32 32s-32-14.3-32-32V62.8c0-4.5 .9-8.9 2.7-13.1L116.8 7.4zm77.8 42.4L212.8 7.4C214.8 2.9 219.1 0 224 0s9.2 2.9 11.2 7.4l18.2 42.4c1.8 4.1 2.7 8.6 2.7 13.1V64c0 17.7-14.3 32-32 32s-32-14.3-32-32V62.8c0-4.5 .9-8.9 2.7-13.1zM308.8 7.4C310.8 2.9 315.1 0 320 0s9.2 2.9 11.2 7.4l18.2 42.4c1.8 4.1 2.7 8.6 2.7 13.1V64c0 17.7-14.3 32-32 32s-32-14.3-32-32V62.8c0-4.5 .9-8.9 2.7-13.1L308.8 7.4zm77.8 42.4L404.8 7.4C406.8 2.9 411.1 0 416 0s9.2 2.9 11.2 7.4l18.2 42.4c1.8 4.1 2.7 8.6 2.7 13.1V64c0 17.7-14.3 32-32 32s-32-14.3-32-32V62.8c0-4.5 .9-8.9 2.7-13.1zM500.8 7.4C502.8 2.9 507.1 0 512 0s9.2 2.9 11.2 7.4l18.2 42.4c1.8 4.1 2.7 8.6 2.7 13.1V64c0 17.7-14.3 32-32 32s-32-14.3-32-32V62.8c0-4.5 .9-8.9 2.7-13.1L500.8 7.4zm77.8 42.4L596.8 7.4C598.8 2.9 603.1 0 608 0s9.2 2.9 11.2 7.4l18.2 42.4c1.8 4.1 2.7 8.6 2.7 13.1V64c0 17.7-14.3 32-32 32s-32-14.3-32-32V62.8c0-4.5 .9-8.9 2.7-13.1zM32 128c17.7 0 32 14.3 32 32V288c0 17.7 14.3 32 32 32H288V160c0-17.7 14.3-32 32-32s32 14.3 32 32V320H544c17.7 0 32-14.3 32-32V160c0-17.7 14.3-32 32-32s32 14.3 32 32V288c0 53-43 96-96 96H352v64H480c17.7 0 32 14.3 32 32s-14.3 32-32 32H320 160c-17.7 0-32-14.3-32-32s14.3-32 32-32H288V384H96c-53 0-96-43-96-96V160c0-17.7 14.3-32 32-32zm96 0c17.7 0 32 14.3 32 32v96 32H96V256 160c0-17.7 14.3-32 32-32zm96 0c17.7 0 32 14.3 32 32v96 32H192V256 160c0-17.7 14.3-32 32-32zm192 0c17.7 0 32 14.3 32 32v96 32H384V256 160c0-17.7 14.3-32 32-32zm96 0c17.7 0 32 14.3 32 32v96 32H480V256 160c0-17.7 14.3-32 32-32z" } }, "free": ["solid"] }, "mercury": { "aliases": { "unicodes": { "composite": ["263f"], "secondary": ["10f223"] } }, "changes": [ "4.3.0", "5.0.0", "5.11.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["Mercury", "gender", "hybrid", "transgender"] }, "styles": ["solid"], "unicode": "f223", "label": "Mercury", "voted": false, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M72.1 7C85.8-4 106-1.8 117 12c17.6 22 44.7 36 75 36s57.3-14 75-36c11.1-13.8 31.2-16 45-5s16 31.2 5 45c-7.8 9.7-16.6 18.4-26.4 26.1C337.3 109.7 368 163.3 368 224c0 89.1-66.2 162.7-152 174.4V424h32c13.3 0 24 10.7 24 24s-10.7 24-24 24H216v16c0 13.3-10.7 24-24 24s-24-10.7-24-24V472H136c-13.3 0-24-10.7-24-24s10.7-24 24-24h32V398.4C82.2 386.7 16 313.1 16 224c0-60.7 30.7-114.3 77.5-145.9C83.7 70.5 74.9 61.7 67.1 52c-11.1-13.8-8.8-33.9 5-45zM80 224a112 112 0 1 0 224 0A112 112 0 1 0 80 224z" } }, "free": ["solid"] }, "message": { "aliases": { "names": ["comment-alt"], "unicodes": { "secondary": ["10f27a"] } }, "changes": [ "4.4.0", "5.0.0", "5.10.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "bubble", "chat", "commenting", "conversation", "feedback", "message", "note", "notification", "sms", "speech", "texting" ] }, "styles": ["solid", "regular"], "unicode": "f27a", "label": "Message", "voted": false, "svg": { "solid": { "last_modified": 1684767393, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M64 0C28.7 0 0 28.7 0 64V352c0 35.3 28.7 64 64 64h96v80c0 6.1 3.4 11.6 8.8 14.3s11.9 2.1 16.8-1.5L309.3 416H448c35.3 0 64-28.7 64-64V64c0-35.3-28.7-64-64-64H64z" }, "regular": { "last_modified": 1684767393, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M160 368c26.5 0 48 21.5 48 48v16l72.5-54.4c8.3-6.2 18.4-9.6 28.8-9.6H448c8.8 0 16-7.2 16-16V64c0-8.8-7.2-16-16-16H64c-8.8 0-16 7.2-16 16V352c0 8.8 7.2 16 16 16h96zm48 124l-.2 .2-5.1 3.8-17.1 12.8c-4.8 3.6-11.3 4.2-16.8 1.5s-8.8-8.2-8.8-14.3V474.7v-6.4V468v-4V416H112 64c-35.3 0-64-28.7-64-64V64C0 28.7 28.7 0 64 0H448c35.3 0 64 28.7 64 64V352c0 35.3-28.7 64-64 64H309.3L208 492z" } }, "free": ["regular", "solid"] }, "meta": { "changes": ["6.0.0", "6.1.2"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e49b", "label": "Meta", "voted": false, "svg": { "brands": { "last_modified": 1660014475, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M640 317.9C640 409.2 600.6 466.4 529.7 466.4C467.1 466.4 433.9 431.8 372.8 329.8L341.4 277.2C333.1 264.7 326.9 253 320.2 242.2C300.1 276 273.1 325.2 273.1 325.2C206.1 441.8 168.5 466.4 116.2 466.4C43.42 466.4 0 409.1 0 320.5C0 177.5 79.78 42.4 183.9 42.4C234.1 42.4 277.7 67.08 328.7 131.9C365.8 81.8 406.8 42.4 459.3 42.4C558.4 42.4 640 168.1 640 317.9H640zM287.4 192.2C244.5 130.1 216.5 111.7 183 111.7C121.1 111.7 69.22 217.8 69.22 321.7C69.22 370.2 87.7 397.4 118.8 397.4C149 397.4 167.8 378.4 222 293.6C222 293.6 246.7 254.5 287.4 192.2V192.2zM531.2 397.4C563.4 397.4 578.1 369.9 578.1 322.5C578.1 198.3 523.8 97.08 454.9 97.08C421.7 97.08 393.8 123 360 175.1C369.4 188.9 379.1 204.1 389.3 220.5L426.8 282.9C485.5 377 500.3 397.4 531.2 397.4L531.2 397.4z" } }, "free": ["brands"] }, "meteor": { "aliases": { "unicodes": { "composite": ["2604"], "secondary": ["10f753"] } }, "changes": ["5.5.0", "5.12.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["armageddon", "asteroid", "comet", "shooting star", "space"] }, "styles": ["solid"], "unicode": "f753", "label": "Meteor", "voted": false, "svg": { "solid": { "last_modified": 1684767662, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M493.7 .9L299.4 75.6l2.3-29.3c1-12.8-12.8-21.5-24-15.1L101.3 133.4C38.6 169.7 0 236.6 0 309C0 421.1 90.9 512 203 512c72.4 0 139.4-38.6 175.7-101.3L480.8 234.3c6.5-11.1-2.2-25-15.1-24l-29.3 2.3L511.1 18.3c.6-1.5 .9-3.2 .9-4.8C512 6 506 0 498.5 0c-1.7 0-3.3 .3-4.8 .9zM192 192a128 128 0 1 1 0 256 128 128 0 1 1 0-256zm0 96a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zm16 96a16 16 0 1 0 0-32 16 16 0 1 0 0 32z" } }, "free": ["solid"] }, "microblog": { "changes": ["5.12.0", "5.14.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e01a", "label": "Micro.blog", "voted": true, "svg": { "brands": { "last_modified": 1660014464, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M399.36,362.23c29.49-34.69,47.1-78.34,47.1-125.79C446.46,123.49,346.86,32,224,32S1.54,123.49,1.54,236.44,101.14,440.87,224,440.87a239.28,239.28,0,0,0,79.44-13.44,7.18,7.18,0,0,1,8.12,2.56c18.58,25.09,47.61,42.74,79.89,49.92a4.42,4.42,0,0,0,5.22-3.43,4.37,4.37,0,0,0-.85-3.62,87,87,0,0,1,3.69-110.69ZM329.52,212.4l-57.3,43.49L293,324.75a6.5,6.5,0,0,1-9.94,7.22L224,290.92,164.94,332a6.51,6.51,0,0,1-9.95-7.22l20.79-68.86-57.3-43.49a6.5,6.5,0,0,1,3.8-11.68l71.88-1.51,23.66-67.92a6.5,6.5,0,0,1,12.28,0l23.66,67.92,71.88,1.51a6.5,6.5,0,0,1,3.88,11.68Z" } }, "free": ["brands"] }, "microchip": { "aliases": { "unicodes": { "secondary": ["10f2db"] } }, "changes": ["4.7.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["cpu", "hardware", "processor", "technology"] }, "styles": ["solid"], "unicode": "f2db", "label": "Microchip", "voted": false, "svg": { "solid": { "last_modified": 1684767343, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M176 24c0-13.3-10.7-24-24-24s-24 10.7-24 24V64c-35.3 0-64 28.7-64 64H24c-13.3 0-24 10.7-24 24s10.7 24 24 24H64v56H24c-13.3 0-24 10.7-24 24s10.7 24 24 24H64v56H24c-13.3 0-24 10.7-24 24s10.7 24 24 24H64c0 35.3 28.7 64 64 64v40c0 13.3 10.7 24 24 24s24-10.7 24-24V448h56v40c0 13.3 10.7 24 24 24s24-10.7 24-24V448h56v40c0 13.3 10.7 24 24 24s24-10.7 24-24V448c35.3 0 64-28.7 64-64h40c13.3 0 24-10.7 24-24s-10.7-24-24-24H448V280h40c13.3 0 24-10.7 24-24s-10.7-24-24-24H448V176h40c13.3 0 24-10.7 24-24s-10.7-24-24-24H448c0-35.3-28.7-64-64-64V24c0-13.3-10.7-24-24-24s-24 10.7-24 24V64H280V24c0-13.3-10.7-24-24-24s-24 10.7-24 24V64H176V24zM160 128H352c17.7 0 32 14.3 32 32V352c0 17.7-14.3 32-32 32H160c-17.7 0-32-14.3-32-32V160c0-17.7 14.3-32 32-32zm192 32H160V352H352V160z" } }, "free": ["solid"] }, "microphone": { "aliases": { "unicodes": { "secondary": ["10f130"] } }, "changes": [ "3.1.0", "5.0.0", "5.0.13", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "address", "audio", "information", "podcast", "public", "record", "sing", "sound", "voice" ] }, "styles": ["solid"], "unicode": "f130", "label": "Microphone", "voted": false, "svg": { "solid": { "last_modified": 1684766676, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M192 0C139 0 96 43 96 96V256c0 53 43 96 96 96s96-43 96-96V96c0-53-43-96-96-96zM64 216c0-13.3-10.7-24-24-24s-24 10.7-24 24v40c0 89.1 66.2 162.7 152 174.4V464H120c-13.3 0-24 10.7-24 24s10.7 24 24 24h72 72c13.3 0 24-10.7 24-24s-10.7-24-24-24H216V430.4c85.8-11.7 152-85.3 152-174.4V216c0-13.3-10.7-24-24-24s-24 10.7-24 24v40c0 70.7-57.3 128-128 128s-128-57.3-128-128V216z" } }, "free": ["solid"] }, "microphone-lines": { "aliases": { "names": ["microphone-alt"], "unicodes": { "composite": ["1f399"], "secondary": ["10f3c9"] } }, "changes": ["5.0.0", "5.0.13", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "audio", "mic", "microphone", "music", "podcast", "record", "sing", "sound", "studio", "studio microphone", "voice" ] }, "styles": ["solid"], "unicode": "f3c9", "label": "Microphone Lines", "voted": false, "svg": { "solid": { "last_modified": 1684766676, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M96 96V256c0 53 43 96 96 96s96-43 96-96H208c-8.8 0-16-7.2-16-16s7.2-16 16-16h80V192H208c-8.8 0-16-7.2-16-16s7.2-16 16-16h80V128H208c-8.8 0-16-7.2-16-16s7.2-16 16-16h80c0-53-43-96-96-96S96 43 96 96zM320 240v16c0 70.7-57.3 128-128 128s-128-57.3-128-128V216c0-13.3-10.7-24-24-24s-24 10.7-24 24v40c0 89.1 66.2 162.7 152 174.4V464H120c-13.3 0-24 10.7-24 24s10.7 24 24 24h72 72c13.3 0 24-10.7 24-24s-10.7-24-24-24H216V430.4c85.8-11.7 152-85.3 152-174.4V216c0-13.3-10.7-24-24-24s-24 10.7-24 24v24z" } }, "free": ["solid"] }, "microphone-lines-slash": { "aliases": { "names": ["microphone-alt-slash"], "unicodes": { "secondary": ["10f539"] } }, "changes": ["5.0.13", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "audio", "disable", "mute", "podcast", "record", "sing", "sound", "voice" ] }, "styles": ["solid"], "unicode": "f539", "label": "Microphone Lines Slash", "voted": false, "svg": { "solid": { "last_modified": 1684766677, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7L472.1 344.7c15.2-26 23.9-56.3 23.9-88.7V216c0-13.3-10.7-24-24-24s-24 10.7-24 24v24 16c0 21.2-5.1 41.1-14.2 58.7L416 300.8V256H358.9l-34.5-27c2.9-3.1 7-5 11.6-5h80V192H336c-8.8 0-16-7.2-16-16s7.2-16 16-16h80V128H336c-8.8 0-16-7.2-16-16s7.2-16 16-16h80c0-53-43-96-96-96s-96 43-96 96v54.3L38.8 5.1zm362.5 407l-43.1-33.9C346.1 382 333.3 384 320 384c-70.7 0-128-57.3-128-128v-8.7L144.7 210c-.5 1.9-.7 3.9-.7 6v40c0 89.1 66.2 162.7 152 174.4V464H248c-13.3 0-24 10.7-24 24s10.7 24 24 24h72 72c13.3 0 24-10.7 24-24s-10.7-24-24-24H344V430.4c20.4-2.8 39.7-9.1 57.3-18.2z" } }, "free": ["solid"] }, "microphone-slash": { "aliases": { "unicodes": { "secondary": ["10f131"] } }, "changes": [ "3.1.0", "5.0.0", "5.0.13", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "audio", "disable", "mute", "podcast", "record", "sing", "sound", "voice" ] }, "styles": ["solid"], "unicode": "f131", "label": "Microphone Slash", "voted": false, "svg": { "solid": { "last_modified": 1684766677, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7L472.1 344.7c15.2-26 23.9-56.3 23.9-88.7V216c0-13.3-10.7-24-24-24s-24 10.7-24 24v40c0 21.2-5.1 41.1-14.2 58.7L416 300.8V96c0-53-43-96-96-96s-96 43-96 96v54.3L38.8 5.1zM344 430.4c20.4-2.8 39.7-9.1 57.3-18.2l-43.1-33.9C346.1 382 333.3 384 320 384c-70.7 0-128-57.3-128-128v-8.7L144.7 210c-.5 1.9-.7 3.9-.7 6v40c0 89.1 66.2 162.7 152 174.4V464H248c-13.3 0-24 10.7-24 24s10.7 24 24 24h72 72c13.3 0 24-10.7 24-24s-10.7-24-24-24H344V430.4z" } }, "free": ["solid"] }, "microscope": { "aliases": { "unicodes": { "composite": ["1f52c"], "secondary": ["10f610"] } }, "changes": ["5.2.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "covid-19", "electron", "lens", "microscope", "optics", "science", "shrink", "testing", "tool" ] }, "styles": ["solid"], "unicode": "f610", "label": "Microscope", "voted": false, "svg": { "solid": { "last_modified": 1684766751, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M160 32c0-17.7 14.3-32 32-32h32c17.7 0 32 14.3 32 32c17.7 0 32 14.3 32 32V288c0 17.7-14.3 32-32 32c0 17.7-14.3 32-32 32H192c-17.7 0-32-14.3-32-32c-17.7 0-32-14.3-32-32V64c0-17.7 14.3-32 32-32zM32 448H320c70.7 0 128-57.3 128-128s-57.3-128-128-128V128c106 0 192 86 192 192c0 49.2-18.5 94-48.9 128H480c17.7 0 32 14.3 32 32s-14.3 32-32 32H320 32c-17.7 0-32-14.3-32-32s14.3-32 32-32zm80-64H304c8.8 0 16 7.2 16 16s-7.2 16-16 16H112c-8.8 0-16-7.2-16-16s7.2-16 16-16z" } }, "free": ["solid"] }, "microsoft": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3ca", "label": "Microsoft", "voted": true, "svg": { "brands": { "last_modified": 1660014481, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M0 32h214.6v214.6H0V32zm233.4 0H448v214.6H233.4V32zM0 265.4h214.6V480H0V265.4zm233.4 0H448V480H233.4V265.4z" } }, "free": ["brands"] }, "mill-sign": { "changes": ["6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Mill Sign", "currency"] }, "styles": ["solid"], "unicode": "e1ed", "label": "Mill Sign", "voted": false, "svg": { "solid": { "last_modified": 1684766475, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M302.1 42.8c5.9-16.6-2.7-35-19.4-40.9s-35 2.7-40.9 19.4L208 116.1c-5.7 4-11.1 8.5-16 13.5C171.7 108.9 143.3 96 112 96c-19.5 0-37.8 5-53.7 13.7C52.5 101.4 42.9 96 32 96C14.3 96 0 110.3 0 128v80V416c0 17.7 14.3 32 32 32s32-14.3 32-32V208c0-26.5 21.5-48 48-48s48 21.5 48 48v42.5L81.9 469.2c-5.9 16.6 2.7 35 19.4 40.9s35-2.7 40.9-19.4l21.4-60C168.9 441 179.6 448 192 448c17.7 0 32-14.3 32-32V261.5l35.7-100c3.9-1 8.1-1.6 12.3-1.6c26.5 0 48 21.5 48 48V416c0 17.7 14.3 32 32 32s32-14.3 32-32V208c0-58.2-44.3-106-101.1-111.5l19.2-53.8z" } }, "free": ["solid"] }, "minimize": { "aliases": { "names": ["compress-arrows-alt"], "unicodes": { "secondary": ["10f78c"] } }, "changes": ["5.6.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "collapse", "fullscreen", "minimize", "move", "resize", "shrink", "smaller" ] }, "styles": ["solid"], "unicode": "f78c", "label": "Minimize", "voted": true, "svg": { "solid": { "last_modified": 1684766331, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M456 224H312c-13.3 0-24-10.7-24-24V56c0-9.7 5.8-18.5 14.8-22.2s19.3-1.7 26.2 5.2l40 40L442.3 5.7C446 2 450.9 0 456 0s10 2 13.7 5.7l36.7 36.7C510 46 512 50.9 512 56s-2 10-5.7 13.7L433 143l40 40c6.9 6.9 8.9 17.2 5.2 26.2s-12.5 14.8-22.2 14.8zm0 64c9.7 0 18.5 5.8 22.2 14.8s1.7 19.3-5.2 26.2l-40 40 73.4 73.4c3.6 3.6 5.7 8.5 5.7 13.7s-2 10-5.7 13.7l-36.7 36.7C466 510 461.1 512 456 512s-10-2-13.7-5.7L369 433l-40 40c-6.9 6.9-17.2 8.9-26.2 5.2s-14.8-12.5-14.8-22.2V312c0-13.3 10.7-24 24-24H456zm-256 0c13.3 0 24 10.7 24 24V456c0 9.7-5.8 18.5-14.8 22.2s-19.3 1.7-26.2-5.2l-40-40L69.7 506.3C66 510 61.1 512 56 512s-10-2-13.7-5.7L5.7 469.7C2 466 0 461.1 0 456s2-10 5.7-13.7L79 369 39 329c-6.9-6.9-8.9-17.2-5.2-26.2s12.5-14.8 22.2-14.8H200zM56 224c-9.7 0-18.5-5.8-22.2-14.8s-1.7-19.3 5.2-26.2l40-40L5.7 69.7C2 66 0 61.1 0 56s2-10 5.7-13.7L42.3 5.7C46 2 50.9 0 56 0s10 2 13.7 5.7L143 79l40-40c6.9-6.9 17.2-8.9 26.2-5.2s14.8 12.5 14.8 22.2V200c0 13.3-10.7 24-24 24H56z" } }, "free": ["solid"] }, "minus": { "aliases": { "names": ["subtract"], "unicodes": { "composite": ["2013", "2212", "2796"], "secondary": ["10f068"] } }, "changes": ["1.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "En Dash", "Minus Sign", "collapse", "delete", "hide", "math", "minify", "minus", "negative", "remove", "sign", "trash", "−" ] }, "styles": ["solid"], "unicode": "f068", "label": "Minus", "voted": false, "svg": { "solid": { "last_modified": 1684767245, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M432 256c0 17.7-14.3 32-32 32L48 288c-17.7 0-32-14.3-32-32s14.3-32 32-32l352 0c17.7 0 32 14.3 32 32z" } }, "free": ["solid"] }, "mitten": { "aliases": { "unicodes": { "secondary": ["10f7b5"] } }, "changes": ["5.6.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "clothing", "cold", "glove", "hands", "knitted", "seasonal", "warmth" ] }, "styles": ["solid"], "unicode": "f7b5", "label": "Mitten", "voted": false, "svg": { "solid": { "last_modified": 1684767603, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M352 384H64L5.4 178.9C1.8 166.4 0 153.4 0 140.3C0 62.8 62.8 0 140.3 0h3.4c66 0 123.5 44.9 139.5 108.9l31.4 125.8 17.6-20.1C344.8 200.2 362.9 192 382 192h2.8c34.9 0 63.3 28.3 63.3 63.3c0 15.9-6 31.2-16.8 42.9L352 384zM32 448c0-17.7 14.3-32 32-32H352c17.7 0 32 14.3 32 32v32c0 17.7-14.3 32-32 32H64c-17.7 0-32-14.3-32-32V448z" } }, "free": ["solid"] }, "mix": { "changes": ["5.0.0", "5.0.3"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3cb", "label": "Mix", "voted": false, "svg": { "brands": { "last_modified": 1660014477, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M0 64v348.9c0 56.2 88 58.1 88 0V174.3c7.9-52.9 88-50.4 88 6.5v175.3c0 57.9 96 58 96 0V240c5.3-54.7 88-52.5 88 4.3v23.8c0 59.9 88 56.6 88 0V64H0z" } }, "free": ["brands"] }, "mixcloud": { "changes": ["4.5.0", "5.0.0", "6.1.2"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f289", "label": "Mixcloud", "voted": false, "svg": { "brands": { "last_modified": 1660014459, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M212.98 346.566H179.789V195.114L185.973 173.47H175.262L137.127 346.566H76.1069L37.7323 173.47H27.276L33.1913 195.114V346.566H0V165H65.6506L102.248 338.096H110.747L147.329 165H212.98L212.98 346.566ZM544.459 283.589L458.434 345.655V307.534L531.329 255.776L458.434 204.017V165.896L544.459 228.231H553.721L640 165.896V204.017L566.866 255.776L640 307.549V345.655L553.721 283.589H544.459ZM430.157 272.311H248.113V239.255H430.157V272.311Z" } }, "free": ["brands"] }, "mixer": { "changes": ["5.12.1", "5.14.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e056", "label": "Mixer", "voted": true, "svg": { "brands": { "last_modified": 1660014466, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M114.57,76.07a45.71,45.71,0,0,0-67.51-6.41c-17.58,16.18-19,43.52-4.75,62.77l91.78,123L41.76,379.58c-14.23,19.25-13.11,46.59,4.74,62.77A45.71,45.71,0,0,0,114,435.94L242.89,262.7a12.14,12.14,0,0,0,0-14.23ZM470.24,379.58,377.91,255.45l91.78-123c14.22-19.25,12.83-46.59-4.75-62.77a45.71,45.71,0,0,0-67.51,6.41l-128,172.12a12.14,12.14,0,0,0,0,14.23L398,435.94a45.71,45.71,0,0,0,67.51,6.41C483.35,426.17,484.47,398.83,470.24,379.58Z" } }, "free": ["brands"] }, "mizuni": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3cc", "label": "Mizuni", "voted": false, "svg": { "brands": { "last_modified": 1660014469, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M248 8C111 8 0 119.1 0 256c0 137 111 248 248 248s248-111 248-248C496 119.1 385 8 248 8zm-80 351.9c-31.4 10.6-58.8 27.3-80 48.2V136c0-22.1 17.9-40 40-40s40 17.9 40 40v223.9zm120-9.9c-12.9-2-26.2-3.1-39.8-3.1-13.8 0-27.2 1.1-40.2 3.1V136c0-22.1 17.9-40 40-40s40 17.9 40 40v214zm120 57.7c-21.2-20.8-48.6-37.4-80-48V136c0-22.1 17.9-40 40-40s40 17.9 40 40v271.7z" } }, "free": ["brands"] }, "mobile": { "aliases": { "names": ["mobile-android", "mobile-phone"], "unicodes": { "composite": ["1f4f1"], "secondary": ["10f3ce"] } }, "changes": ["5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "android", "call", "cell", "cell phone", "device", "mobile", "mobile phone", "number", "phone", "screen", "telephone", "text" ] }, "styles": ["solid"], "unicode": "f3ce", "label": "Mobile", "voted": false, "svg": { "solid": { "last_modified": 1684767342, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M80 0C44.7 0 16 28.7 16 64V448c0 35.3 28.7 64 64 64H304c35.3 0 64-28.7 64-64V64c0-35.3-28.7-64-64-64H80zm80 432h64c8.8 0 16 7.2 16 16s-7.2 16-16 16H160c-8.8 0-16-7.2-16-16s7.2-16 16-16z" } }, "free": ["solid"] }, "mobile-button": { "aliases": { "unicodes": { "secondary": ["10f10b"] } }, "changes": ["3.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "apple", "call", "cell phone", "device", "iphone", "number", "screen", "telephone" ] }, "styles": ["solid"], "unicode": "f10b", "label": "Mobile Button", "voted": false, "svg": { "solid": { "last_modified": 1684767342, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M80 0C44.7 0 16 28.7 16 64V448c0 35.3 28.7 64 64 64H304c35.3 0 64-28.7 64-64V64c0-35.3-28.7-64-64-64H80zM192 400a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" } }, "free": ["solid"] }, "mobile-retro": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["cellphone", "cellular", "phone"] }, "styles": ["solid"], "unicode": "e527", "label": "Mobile Retro", "voted": false, "svg": { "solid": { "last_modified": 1684767343, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M0 64C0 28.7 28.7 0 64 0H256c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V64zm64 96v64c0 17.7 14.3 32 32 32H224c17.7 0 32-14.3 32-32V160c0-17.7-14.3-32-32-32H96c-17.7 0-32 14.3-32 32zM80 352a24 24 0 1 0 0-48 24 24 0 1 0 0 48zm24 56a24 24 0 1 0 -48 0 24 24 0 1 0 48 0zm56-56a24 24 0 1 0 0-48 24 24 0 1 0 0 48zm24 56a24 24 0 1 0 -48 0 24 24 0 1 0 48 0zm56-56a24 24 0 1 0 0-48 24 24 0 1 0 0 48zm24 56a24 24 0 1 0 -48 0 24 24 0 1 0 48 0zM128 48c-8.8 0-16 7.2-16 16s7.2 16 16 16h64c8.8 0 16-7.2 16-16s-7.2-16-16-16H128z" } }, "free": ["solid"] }, "mobile-screen": { "aliases": { "names": ["mobile-android-alt"], "unicodes": { "secondary": ["10f3cf"] } }, "changes": ["5.0.0", "6.0.0-beta1", "6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "android", "call", "cell phone", "device", "number", "screen", "telephone", "text" ] }, "styles": ["solid"], "unicode": "f3cf", "label": "Mobile Screen", "voted": false, "svg": { "solid": { "last_modified": 1684767342, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M16 64C16 28.7 44.7 0 80 0H304c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H80c-35.3 0-64-28.7-64-64V64zM144 448c0 8.8 7.2 16 16 16h64c8.8 0 16-7.2 16-16s-7.2-16-16-16H160c-8.8 0-16 7.2-16 16zM304 64H80V384H304V64z" } }, "free": ["solid"] }, "mobile-screen-button": { "aliases": { "names": ["mobile-alt"], "unicodes": { "secondary": ["10f3cd"] } }, "changes": ["5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "apple", "call", "cell phone", "device", "iphone", "number", "screen", "telephone" ] }, "styles": ["solid"], "unicode": "f3cd", "label": "Mobile Screen Button", "voted": false, "svg": { "solid": { "last_modified": 1684767342, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M16 64C16 28.7 44.7 0 80 0H304c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H80c-35.3 0-64-28.7-64-64V64zM224 448a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zM304 64H80V384H304V64z" } }, "free": ["solid"] }, "modx": { "changes": ["4.5.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f285", "label": "MODX", "voted": false, "svg": { "brands": { "last_modified": 1660014482, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M356 241.8l36.7 23.7V480l-133-83.8L356 241.8zM440 75H226.3l-23 37.8 153.5 96.5L440 75zm-89 142.8L55.2 32v214.5l46 29L351 217.8zM97 294.2L8 437h213.7l125-200.5L97 294.2z" } }, "free": ["brands"] }, "monero": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3d0", "label": "Monero", "voted": false, "svg": { "brands": { "last_modified": 1660014483, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M352 384h108.4C417 455.9 338.1 504 248 504S79 455.9 35.6 384H144V256.2L248 361l104-105v128zM88 336V128l159.4 159.4L408 128v208h74.8c8.5-25.1 13.2-52 13.2-80C496 119 385 8 248 8S0 119 0 256c0 28 4.6 54.9 13.2 80H88z" } }, "free": ["brands"] }, "money-bill": { "aliases": { "unicodes": { "secondary": ["10f0d6"] } }, "changes": [ "2.0.0", "5.0.0", "5.0.13", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "buy", "cash", "checkout", "money", "payment", "price", "purchase" ] }, "styles": ["solid"], "unicode": "f0d6", "label": "Money Bill", "voted": false, "svg": { "solid": { "last_modified": 1684766476, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M64 64C28.7 64 0 92.7 0 128V384c0 35.3 28.7 64 64 64H512c35.3 0 64-28.7 64-64V128c0-35.3-28.7-64-64-64H64zm64 320H64V320c35.3 0 64 28.7 64 64zM64 192V128h64c0 35.3-28.7 64-64 64zM448 384c0-35.3 28.7-64 64-64v64H448zm64-192c-35.3 0-64-28.7-64-64h64v64zM288 160a96 96 0 1 1 0 192 96 96 0 1 1 0-192z" } }, "free": ["solid"] }, "money-bill-1": { "aliases": { "names": ["money-bill-alt"], "unicodes": { "secondary": ["10f3d1"] } }, "changes": [ "5.0.0", "5.0.13", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "buy", "cash", "checkout", "money", "payment", "price", "purchase" ] }, "styles": ["solid", "regular"], "unicode": "f3d1", "label": "Money Bill 1", "voted": false, "svg": { "solid": { "last_modified": 1684766475, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M64 64C28.7 64 0 92.7 0 128V384c0 35.3 28.7 64 64 64H512c35.3 0 64-28.7 64-64V128c0-35.3-28.7-64-64-64H64zm64 320H64V320c35.3 0 64 28.7 64 64zM64 192V128h64c0 35.3-28.7 64-64 64zM448 384c0-35.3 28.7-64 64-64v64H448zm64-192c-35.3 0-64-28.7-64-64h64v64zM176 256a112 112 0 1 1 224 0 112 112 0 1 1 -224 0zm76-48c0 9.7 6.9 17.7 16 19.6V276h-4c-11 0-20 9-20 20s9 20 20 20h24 24c11 0 20-9 20-20s-9-20-20-20h-4V208c0-11-9-20-20-20H272c-11 0-20 9-20 20z" }, "regular": { "last_modified": 1684766475, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M112 112c0 35.3-28.7 64-64 64V336c35.3 0 64 28.7 64 64H464c0-35.3 28.7-64 64-64V176c-35.3 0-64-28.7-64-64H112zM0 128C0 92.7 28.7 64 64 64H512c35.3 0 64 28.7 64 64V384c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128zM176 256a112 112 0 1 1 224 0 112 112 0 1 1 -224 0zm80-48c0 8.8 7.2 16 16 16v64h-8c-8.8 0-16 7.2-16 16s7.2 16 16 16h24 24c8.8 0 16-7.2 16-16s-7.2-16-16-16h-8V208c0-8.8-7.2-16-16-16H272c-8.8 0-16 7.2-16 16z" } }, "free": ["regular", "solid"] }, "money-bill-1-wave": { "aliases": { "names": ["money-bill-wave-alt"], "unicodes": { "secondary": ["10f53b"] } }, "changes": [ "5.0.13", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "buy", "cash", "checkout", "money", "payment", "price", "purchase" ] }, "styles": ["solid"], "unicode": "f53b", "label": "Money Bill 1 Wave", "voted": true, "svg": { "solid": { "last_modified": 1684766474, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M0 112.5V422.3c0 18 10.1 35 27 41.3c87 32.5 174 10.3 261-11.9c79.8-20.3 159.6-40.7 239.3-18.9c23 6.3 48.7-9.5 48.7-33.4V89.7c0-18-10.1-35-27-41.3C462 15.9 375 38.1 288 60.3C208.2 80.6 128.4 100.9 48.7 79.1C25.6 72.8 0 88.6 0 112.5zM128 416H64V352c35.3 0 64 28.7 64 64zM64 224V160h64c0 35.3-28.7 64-64 64zM448 352c0-35.3 28.7-64 64-64v64H448zm64-192c-35.3 0-64-28.7-64-64h64v64zM384 256c0 61.9-43 112-96 112s-96-50.1-96-112s43-112 96-112s96 50.1 96 112zM252 208c0 9.7 6.9 17.7 16 19.6V276h-4c-11 0-20 9-20 20s9 20 20 20h24 24c11 0 20-9 20-20s-9-20-20-20h-4V208c0-11-9-20-20-20H272c-11 0-20 9-20 20z" } }, "free": ["solid"] }, "money-bill-transfer": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "bank", "conversion", "deposit", "money", "transfer", "withdrawal" ] }, "styles": ["solid"], "unicode": "e528", "label": "Money Bill Transfer", "voted": false, "svg": { "solid": { "last_modified": 1684766476, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M535 41c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l64 64c4.5 4.5 7 10.6 7 17s-2.5 12.5-7 17l-64 64c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l23-23L384 112c-13.3 0-24-10.7-24-24s10.7-24 24-24l174.1 0L535 41zM105 377l-23 23L256 400c13.3 0 24 10.7 24 24s-10.7 24-24 24L81.9 448l23 23c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0L7 441c-4.5-4.5-7-10.6-7-17s2.5-12.5 7-17l64-64c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9zM96 64H337.9c-3.7 7.2-5.9 15.3-5.9 24c0 28.7 23.3 52 52 52l117.4 0c-4 17 .6 35.5 13.8 48.8c20.3 20.3 53.2 20.3 73.5 0L608 169.5V384c0 35.3-28.7 64-64 64H302.1c3.7-7.2 5.9-15.3 5.9-24c0-28.7-23.3-52-52-52l-117.4 0c4-17-.6-35.5-13.8-48.8c-20.3-20.3-53.2-20.3-73.5 0L32 342.5V128c0-35.3 28.7-64 64-64zm64 64H96v64c35.3 0 64-28.7 64-64zM544 320c-35.3 0-64 28.7-64 64h64V320zM320 352a96 96 0 1 0 0-192 96 96 0 1 0 0 192z" } }, "free": ["solid"] }, "money-bill-trend-up": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["bank", "bonds", "inflation", "market", "stocks", "trade"] }, "styles": ["solid"], "unicode": "e529", "label": "Money Bill Trend Up", "voted": false, "svg": { "solid": { "last_modified": 1684766476, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M470.7 9.4c3 3.1 5.3 6.6 6.9 10.3s2.4 7.8 2.4 12.2l0 .1v0 96c0 17.7-14.3 32-32 32s-32-14.3-32-32V109.3L310.6 214.6c-11.8 11.8-30.8 12.6-43.5 1.7L176 138.1 84.8 216.3c-13.4 11.5-33.6 9.9-45.1-3.5s-9.9-33.6 3.5-45.1l112-96c12-10.3 29.7-10.3 41.7 0l89.5 76.7L370.7 64H352c-17.7 0-32-14.3-32-32s14.3-32 32-32h96 0c8.8 0 16.8 3.6 22.6 9.3l.1 .1zM0 304c0-26.5 21.5-48 48-48H464c26.5 0 48 21.5 48 48V464c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V304zM48 416v48H96c0-26.5-21.5-48-48-48zM96 304H48v48c26.5 0 48-21.5 48-48zM464 416c-26.5 0-48 21.5-48 48h48V416zM416 304c0 26.5 21.5 48 48 48V304H416zm-96 80a64 64 0 1 0 -128 0 64 64 0 1 0 128 0z" } }, "free": ["solid"] }, "money-bill-wave": { "aliases": { "unicodes": { "secondary": ["10f53a"] } }, "changes": [ "5.0.13", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "buy", "cash", "checkout", "money", "payment", "price", "purchase" ] }, "styles": ["solid"], "unicode": "f53a", "label": "Money Bill Wave", "voted": true, "svg": { "solid": { "last_modified": 1684766476, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M0 112.5V422.3c0 18 10.1 35 27 41.3c87 32.5 174 10.3 261-11.9c79.8-20.3 159.6-40.7 239.3-18.9c23 6.3 48.7-9.5 48.7-33.4V89.7c0-18-10.1-35-27-41.3C462 15.9 375 38.1 288 60.3C208.2 80.6 128.4 100.9 48.7 79.1C25.6 72.8 0 88.6 0 112.5zM288 352c-44.2 0-80-43-80-96s35.8-96 80-96s80 43 80 96s-35.8 96-80 96zM64 352c35.3 0 64 28.7 64 64H64V352zm64-208c0 35.3-28.7 64-64 64V144h64zM512 304v64H448c0-35.3 28.7-64 64-64zM448 96h64v64c-35.3 0-64-28.7-64-64z" } }, "free": ["solid"] }, "money-bill-wheat": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "agribusiness", "agriculture", "farming", "food", "livelihood", "subsidy" ] }, "styles": ["solid"], "unicode": "e52a", "label": "Money Bill Wheat", "voted": false, "svg": { "solid": { "last_modified": 1684766475, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M176 0c44.2 0 80 35.8 80 80c0 8.8-7.2 16-16 16c-44.2 0-80-35.8-80-80c0-8.8 7.2-16 16-16zM56 16h48c13.3 0 24 10.7 24 24s-10.7 24-24 24H56C42.7 64 32 53.3 32 40s10.7-24 24-24zM24 88H136c13.3 0 24 10.7 24 24s-10.7 24-24 24H24c-13.3 0-24-10.7-24-24S10.7 88 24 88zm8 96c0-13.3 10.7-24 24-24h48c13.3 0 24 10.7 24 24s-10.7 24-24 24H56c-13.3 0-24-10.7-24-24zM272 16c0-8.8 7.2-16 16-16c44.2 0 80 35.8 80 80c0 8.8-7.2 16-16 16c-44.2 0-80-35.8-80-80zM400 0c44.2 0 80 35.8 80 80c0 8.8-7.2 16-16 16c-44.2 0-80-35.8-80-80c0-8.8 7.2-16 16-16zm80 144c0 44.2-35.8 80-80 80c-8.8 0-16-7.2-16-16c0-44.2 35.8-80 80-80c8.8 0 16 7.2 16 16zM352 128c8.8 0 16 7.2 16 16c0 44.2-35.8 80-80 80c-8.8 0-16-7.2-16-16c0-44.2 35.8-80 80-80zm-96 16c0 44.2-35.8 80-80 80c-8.8 0-16-7.2-16-16c0-44.2 35.8-80 80-80c8.8 0 16 7.2 16 16zM0 304c0-26.5 21.5-48 48-48H464c26.5 0 48 21.5 48 48V464c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V304zM48 416v48H96c0-26.5-21.5-48-48-48zM96 304H48v48c26.5 0 48-21.5 48-48zM464 416c-26.5 0-48 21.5-48 48h48V416zM416 304c0 26.5 21.5 48 48 48V304H416zm-96 80a64 64 0 1 0 -128 0 64 64 0 1 0 128 0z" } }, "free": ["solid"] }, "money-bills": { "changes": [ "6.0.0-beta1", "6.0.0-beta3", "6.1.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["atm", "cash", "money", "moolah"] }, "styles": ["solid"], "unicode": "e1f3", "label": "Money Bills", "voted": false, "svg": { "solid": { "last_modified": 1684766476, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M96 96V320c0 35.3 28.7 64 64 64H576c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H160c-35.3 0-64 28.7-64 64zm64 160c35.3 0 64 28.7 64 64H160V256zM224 96c0 35.3-28.7 64-64 64V96h64zM576 256v64H512c0-35.3 28.7-64 64-64zM512 96h64v64c-35.3 0-64-28.7-64-64zM288 208a80 80 0 1 1 160 0 80 80 0 1 1 -160 0zM48 120c0-13.3-10.7-24-24-24S0 106.7 0 120V360c0 66.3 53.7 120 120 120H520c13.3 0 24-10.7 24-24s-10.7-24-24-24H120c-39.8 0-72-32.2-72-72V120z" } }, "free": ["solid"] }, "money-check": { "aliases": { "unicodes": { "secondary": ["10f53c"] } }, "changes": [ "5.0.13", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "bank check", "buy", "checkout", "cheque", "money", "payment", "price", "purchase" ] }, "styles": ["solid"], "unicode": "f53c", "label": "Money Check", "voted": true, "svg": { "solid": { "last_modified": 1684766476, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M64 64C28.7 64 0 92.7 0 128V384c0 35.3 28.7 64 64 64H512c35.3 0 64-28.7 64-64V128c0-35.3-28.7-64-64-64H64zm48 160H272c8.8 0 16 7.2 16 16s-7.2 16-16 16H112c-8.8 0-16-7.2-16-16s7.2-16 16-16zM96 336c0-8.8 7.2-16 16-16H464c8.8 0 16 7.2 16 16s-7.2 16-16 16H112c-8.8 0-16-7.2-16-16zM376 160h80c13.3 0 24 10.7 24 24v48c0 13.3-10.7 24-24 24H376c-13.3 0-24-10.7-24-24V184c0-13.3 10.7-24 24-24z" } }, "free": ["solid"] }, "money-check-dollar": { "aliases": { "names": ["money-check-alt"], "unicodes": { "secondary": ["10f53d"] } }, "changes": [ "5.0.13", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "bank check", "buy", "checkout", "cheque", "money", "payment", "price", "purchase" ] }, "styles": ["solid"], "unicode": "f53d", "label": "Money Check Dollar", "voted": true, "svg": { "solid": { "last_modified": 1684766476, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M64 64C28.7 64 0 92.7 0 128V384c0 35.3 28.7 64 64 64H512c35.3 0 64-28.7 64-64V128c0-35.3-28.7-64-64-64H64zM272 192H496c8.8 0 16 7.2 16 16s-7.2 16-16 16H272c-8.8 0-16-7.2-16-16s7.2-16 16-16zM256 304c0-8.8 7.2-16 16-16H496c8.8 0 16 7.2 16 16s-7.2 16-16 16H272c-8.8 0-16-7.2-16-16zM164 152v13.9c7.5 1.2 14.6 2.9 21.1 4.7c10.7 2.8 17 13.8 14.2 24.5s-13.8 17-24.5 14.2c-11-2.9-21.6-5-31.2-5.2c-7.9-.1-16 1.8-21.5 5c-4.8 2.8-6.2 5.6-6.2 9.3c0 1.8 .1 3.5 5.3 6.7c6.3 3.8 15.5 6.7 28.3 10.5l.7 .2c11.2 3.4 25.6 7.7 37.1 15c12.9 8.1 24.3 21.3 24.6 41.6c.3 20.9-10.5 36.1-24.8 45c-7.2 4.5-15.2 7.3-23.2 9V360c0 11-9 20-20 20s-20-9-20-20V345.4c-10.3-2.2-20-5.5-28.2-8.4l0 0 0 0c-2.1-.7-4.1-1.4-6.1-2.1c-10.5-3.5-16.1-14.8-12.6-25.3s14.8-16.1 25.3-12.6c2.5 .8 4.9 1.7 7.2 2.4c13.6 4.6 24 8.1 35.1 8.5c8.6 .3 16.5-1.6 21.4-4.7c4.1-2.5 6-5.5 5.9-10.5c0-2.9-.8-5-5.9-8.2c-6.3-4-15.4-6.9-28-10.7l-1.7-.5c-10.9-3.3-24.6-7.4-35.6-14c-12.7-7.7-24.6-20.5-24.7-40.7c-.1-21.1 11.8-35.7 25.8-43.9c6.9-4.1 14.5-6.8 22.2-8.5V152c0-11 9-20 20-20s20 9 20 20z" } }, "free": ["solid"] }, "monument": { "aliases": { "unicodes": { "secondary": ["10f5a6"] } }, "changes": [ "5.1.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["building", "historic", "landmark", "memorable"] }, "styles": ["solid"], "unicode": "f5a6", "label": "Monument", "voted": false, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M180.7 4.7c6.2-6.2 16.4-6.2 22.6 0l80 80c2.5 2.5 4.1 5.8 4.6 9.3l40.2 322H55.9L96.1 94c.4-3.5 2-6.8 4.6-9.3l80-80zM152 272c-13.3 0-24 10.7-24 24s10.7 24 24 24h80c13.3 0 24-10.7 24-24s-10.7-24-24-24H152zM32 448H352c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32z" } }, "free": ["solid"] }, "moon": { "aliases": { "unicodes": { "composite": ["1f319", "23fe"], "secondary": ["10f186"] } }, "changes": [ "3.2.0", "5.0.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Power Sleep Symbol", "contrast", "crescent", "crescent moon", "dark", "lunar", "moon", "night" ] }, "styles": ["solid", "regular"], "unicode": "f186", "label": "Moon", "voted": false, "svg": { "solid": { "last_modified": 1684767661, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M223.5 32C100 32 0 132.3 0 256S100 480 223.5 480c60.6 0 115.5-24.2 155.8-63.4c5-4.9 6.3-12.5 3.1-18.7s-10.1-9.7-17-8.5c-9.8 1.7-19.8 2.6-30.1 2.6c-96.9 0-175.5-78.8-175.5-176c0-65.8 36-123.1 89.3-153.3c6.1-3.5 9.2-10.5 7.7-17.3s-7.3-11.9-14.3-12.5c-6.3-.5-12.6-.8-19-.8z" }, "regular": { "last_modified": 1684767661, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M144.7 98.7c-21 34.1-33.1 74.3-33.1 117.3c0 98 62.8 181.4 150.4 211.7c-12.4 2.8-25.3 4.3-38.6 4.3C126.6 432 48 353.3 48 256c0-68.9 39.4-128.4 96.8-157.3zm62.1-66C91.1 41.2 0 137.9 0 256C0 379.7 100 480 223.5 480c47.8 0 92-15 128.4-40.6c1.9-1.3 3.7-2.7 5.5-4c4.8-3.6 9.4-7.4 13.9-11.4c2.7-2.4 5.3-4.8 7.9-7.3c5-4.9 6.3-12.5 3.1-18.7s-10.1-9.7-17-8.5c-3.7 .6-7.4 1.2-11.1 1.6c-5 .5-10.1 .9-15.3 1c-1.2 0-2.5 0-3.7 0c-.1 0-.2 0-.3 0c-96.8-.2-175.2-78.9-175.2-176c0-54.8 24.9-103.7 64.1-136c1-.9 2.1-1.7 3.2-2.6c4-3.2 8.2-6.2 12.5-9c3.1-2 6.3-4 9.6-5.8c6.1-3.5 9.2-10.5 7.7-17.3s-7.3-11.9-14.3-12.5c-3.6-.3-7.1-.5-10.7-.6c-2.7-.1-5.5-.1-8.2-.1c-3.3 0-6.5 .1-9.8 .2c-2.3 .1-4.6 .2-6.9 .4z" } }, "free": ["regular", "solid"] }, "mortar-pestle": { "aliases": { "unicodes": { "secondary": ["10f5a7"] } }, "changes": ["5.1.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "crush", "culinary", "grind", "medical", "mix", "pharmacy", "prescription", "spices" ] }, "styles": ["solid"], "unicode": "f5a7", "label": "Mortar Pestle", "voted": false, "svg": { "solid": { "last_modified": 1684767421, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M504.3 11.1C493.3-1.6 474.5-3.7 461 6.2L252.3 160H397.3L502.6 54.6c11.8-11.8 12.6-30.8 1.6-43.5zM32 192c-17.7 0-32 14.3-32 32s14.3 32 32 32c0 82.5 43.4 147.7 123.9 176.2c-11.1 13.9-19.4 30.3-23.9 48.1C127.6 497.4 142.3 512 160 512H352c17.7 0 32.4-14.6 28.1-31.7c-4.5-17.8-12.8-34.1-23.9-48.1C436.6 403.7 480 338.5 480 256c17.7 0 32-14.3 32-32s-14.3-32-32-32H32z" } }, "free": ["solid"] }, "mosque": { "aliases": { "unicodes": { "composite": ["1f54c"], "secondary": ["10f678"] } }, "changes": [ "5.3.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Muslim", "building", "islam", "landmark", "mosque", "muslim", "religion" ] }, "styles": ["solid"], "unicode": "f678", "label": "Mosque", "voted": false, "svg": { "solid": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M400 0c5 0 9.8 2.4 12.8 6.4c34.7 46.3 78.1 74.9 133.5 111.5l0 0 0 0c5.2 3.4 10.5 7 16 10.6c28.9 19.2 45.7 51.7 45.7 86.1c0 28.6-11.3 54.5-29.8 73.4H221.8c-18.4-19-29.8-44.9-29.8-73.4c0-34.4 16.7-66.9 45.7-86.1c5.4-3.6 10.8-7.1 16-10.6l0 0 0 0C309.1 81.3 352.5 52.7 387.2 6.4c3-4 7.8-6.4 12.8-6.4zM288 512V440c0-13.3-10.7-24-24-24s-24 10.7-24 24v72H192c-17.7 0-32-14.3-32-32V352c0-17.7 14.3-32 32-32H608c17.7 0 32 14.3 32 32V480c0 17.7-14.3 32-32 32H560V440c0-13.3-10.7-24-24-24s-24 10.7-24 24v72H448V454c0-19-8.4-37-23-49.2L400 384l-25 20.8C360.4 417 352 435 352 454v58H288zM70.4 5.2c5.7-4.3 13.5-4.3 19.2 0l16 12C139.8 42.9 160 83.2 160 126v2H0v-2C0 83.2 20.2 42.9 54.4 17.2l16-12zM0 160H160V296.6c-19.1 11.1-32 31.7-32 55.4V480c0 9.6 2.1 18.6 5.8 26.8c-6.6 3.4-14 5.2-21.8 5.2H48c-26.5 0-48-21.5-48-48V176 160z" } }, "free": ["solid"] }, "mosquito": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["bite", "bug", "mosquito", "west nile"] }, "styles": ["solid"], "unicode": "e52b", "label": "Mosquito", "voted": false, "svg": { "solid": { "last_modified": 1684768130, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M463.7 505.9c9.8-8.9 10.7-24.3 2.1-34.3l-42.1-49 0-54.7c0-5.5-1.8-10.8-5.1-15.1L352 266.3l0-.3L485.4 387.8C542.4 447.6 640 405.2 640 320.6c0-47.9-34-88.3-79.4-94.2l-153-23.9 40.8-40.9c7.8-7.8 9.4-20.1 3.9-29.8L428.5 90.1l38.2-50.9c8-10.6 6.1-25.9-4.3-34.1s-25.2-6.3-33.2 4.4l-48 63.9c-5.9 7.9-6.6 18.6-1.7 27.2L402.2 140 352 190.3l0-38.2c0-14.9-10.2-27.4-24-31l0-57.2c0-4.4-3.6-8-8-8s-8 3.6-8 8l0 57.2c-13.8 3.6-24 16.1-24 31l0 38.1L237.8 140l22.6-39.5c4.9-8.6 4.2-19.3-1.7-27.2l-48-63.9c-8-10.6-22.8-12.6-33.2-4.4s-12.2 23.5-4.3 34.1l38.2 50.9-23.9 41.7c-5.5 9.7-3.9 22 3.9 29.8l40.8 40.9-153 23.9C34 232.3 0 272.7 0 320.6c0 84.6 97.6 127 154.6 67.1L288 266l0 .3-66.5 86.4c-3.3 4.3-5.1 9.6-5.1 15.1l0 54.7-42.1 49c-8.6 10.1-7.7 25.5 2.1 34.3s24.7 7.9 33.4-2.1l48-55.9c3.8-4.4 5.9-10.2 5.9-16.1l0-55.4L288 344.7l0 63.1c0 17.7 14.3 32 32 32s32-14.3 32-32l0-63.1 24.3 31.6 0 55.4c0 5.9 2.1 11.7 5.9 16.1l48 55.9c8.6 10.1 23.6 11 33.4 2.1z" } }, "free": ["solid"] }, "mosquito-net": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["bite", "malaria", "mosquito", "net"] }, "styles": ["solid"], "unicode": "e52c", "label": "Mosquito Net", "voted": false, "svg": { "solid": { "last_modified": 1684768130, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M168.8 462.3c-7.9-4-11.1-13.6-7.2-21.5L192 380.2l0-44.2c0-4.2 1.7-8.3 4.7-11.3L256 265.4V242.2L139.2 344C87.8 395.3 0 358.9 0 286.3c0-41.1 30.6-75.8 71.4-80.9l159.9-23.9-49.6-41.3c-5.1-4.2-7-11.1-4.9-17.4l13.9-41.7-29-58.1c-4-7.9-.7-17.5 7.2-21.5s17.5-.7 21.5 7.2l32 64c1.9 3.8 2.2 8.2 .9 12.2l-12.5 37.6L256 160.5V137.9c0-14.9 10.1-27.3 23.8-31V63.7c0-4.5 3.7-8.2 8.2-8.2s8.2 3.7 8.2 8.2V107c13.7 3.6 23.8 16.1 23.8 31v22.6l45.4-37.8L352.8 85.1c-1.3-4-1-8.4 .9-12.2l32-64c4-7.9 13.6-11.1 21.5-7.2s11.1 13.6 7.2 21.5l-29 58.1 13.9 41.7c2.1 6.2 .1 13.1-4.9 17.4l-49.6 41.3 159.9 23.9c22.5 2.8 41.8 14.6 54.7 31.4c-2.7 2.6-5.2 5.4-7.3 8.6c-8.6-12.9-23.3-21.5-40-21.5s-31.4 8.5-40 21.5c-8.6-12.9-23.3-21.5-40-21.5c-21.7 0-40 14.3-45.9 34.1c-10.7 3.2-19.8 10.1-25.9 19.2l-40.2-35v23.1l32.4 32.4c-.3 2-.4 4.1-.4 6.2c0 16.7 8.5 31.4 21.5 40c-4 2.6-7.5 5.9-10.6 9.5L320 310.6v50c0 17.7-14.3 32-32 32s-32-14.3-32-32v-50l-32 32 0 41.4c0 2.5-.6 4.9-1.7 7.2l-32 64c-4 7.9-13.6 11.1-21.5 7.2zM512 256c8.8 0 16 7.2 16 16v16h48V272c0-8.8 7.2-16 16-16s16 7.2 16 16v16h16c8.8 0 16 7.2 16 16s-7.2 16-16 16H608v48h16c8.8 0 16 7.2 16 16s-7.2 16-16 16H608v48h16c8.8 0 16 7.2 16 16s-7.2 16-16 16H608v16c0 8.8-7.2 16-16 16s-16-7.2-16-16V480H528v16c0 8.8-7.2 16-16 16s-16-7.2-16-16V480H448v16c0 8.8-7.2 16-16 16s-16-7.2-16-16V480H400c-8.8 0-16-7.2-16-16s7.2-16 16-16h16V400H400c-8.8 0-16-7.2-16-16s7.2-16 16-16h16V320H400c-8.8 0-16-7.2-16-16s7.2-16 16-16h16V272c0-8.8 7.2-16 16-16s16 7.2 16 16v16h48V272c0-8.8 7.2-16 16-16zm16 112h48V320H528v48zm0 80h48V400H528v48zM448 320v48h48V320H448zm0 80v48h48V400H448z" } }, "free": ["solid"] }, "motorcycle": { "aliases": { "unicodes": { "composite": ["1f3cd"], "secondary": ["10f21c"] } }, "changes": [ "4.3.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "bike", "machine", "motorcycle", "racing", "transportation", "vehicle" ] }, "styles": ["solid"], "unicode": "f21c", "label": "Motorcycle", "voted": false, "svg": { "solid": { "last_modified": 1684767650, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M280 32c-13.3 0-24 10.7-24 24s10.7 24 24 24h57.7l16.4 30.3L256 192l-45.3-45.3c-12-12-28.3-18.7-45.3-18.7H64c-17.7 0-32 14.3-32 32v32h96c88.4 0 160 71.6 160 160c0 11-1.1 21.7-3.2 32h70.4c-2.1-10.3-3.2-21-3.2-32c0-52.2 25-98.6 63.7-127.8l15.4 28.6C402.4 276.3 384 312 384 352c0 70.7 57.3 128 128 128s128-57.3 128-128s-57.3-128-128-128c-13.5 0-26.5 2.1-38.7 6L418.2 128H480c17.7 0 32-14.3 32-32V64c0-17.7-14.3-32-32-32H459.6c-7.5 0-14.7 2.6-20.5 7.4L391.7 78.9l-14-26c-7-12.9-20.5-21-35.2-21H280zM462.7 311.2l28.2 52.2c6.3 11.7 20.9 16 32.5 9.7s16-20.9 9.7-32.5l-28.2-52.2c2.3-.3 4.7-.4 7.1-.4c35.3 0 64 28.7 64 64s-28.7 64-64 64s-64-28.7-64-64c0-15.5 5.5-29.7 14.7-40.8zM187.3 376c-9.5 23.5-32.5 40-59.3 40c-35.3 0-64-28.7-64-64s28.7-64 64-64c26.9 0 49.9 16.5 59.3 40h66.4C242.5 268.8 190.5 224 128 224C57.3 224 0 281.3 0 352s57.3 128 128 128c62.5 0 114.5-44.8 125.8-104H187.3zM128 384a32 32 0 1 0 0-64 32 32 0 1 0 0 64z" } }, "free": ["solid"] }, "mound": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["barrier", "hill", "pitcher", "speedbump"] }, "styles": ["solid"], "unicode": "e52d", "label": "Mound", "voted": false, "svg": { "solid": { "last_modified": 1684767442, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M144.1 179.2C173.8 127.7 228.6 96 288 96s114.2 31.7 143.9 83.2L540.4 368c12.3 21.3-3.1 48-27.7 48H63.3c-24.6 0-40-26.6-27.7-48L144.1 179.2z" } }, "free": ["solid"] }, "mountain": { "aliases": { "unicodes": { "composite": ["1f3d4"], "secondary": ["10f6fc"] } }, "changes": ["5.4.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "cold", "glacier", "hiking", "hill", "landscape", "mountain", "snow", "snow-capped mountain", "travel", "view" ] }, "styles": ["solid"], "unicode": "f6fc", "label": "Mountain", "voted": false, "svg": { "solid": { "last_modified": 1684768130, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 32c12.5 0 24.1 6.4 30.8 17L503.4 394.4c5.6 8.9 8.6 19.2 8.6 29.7c0 30.9-25 55.9-55.9 55.9H55.9C25 480 0 455 0 424.1c0-10.5 3-20.8 8.6-29.7L225.2 49c6.6-10.6 18.3-17 30.8-17zm65 192L256 120.4 176.9 246.5l18.3 24.4c6.4 8.5 19.2 8.5 25.6 0l25.6-34.1c6-8.1 15.5-12.8 25.6-12.8h49z" } }, "free": ["solid"] }, "mountain-city": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["location", "rural", "urban"] }, "styles": ["solid"], "unicode": "e52e", "label": "Mountain City", "voted": false, "svg": { "solid": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M336 0c-26.5 0-48 21.5-48 48v92.1l71.4 118.4c2.5-1.6 5.4-2.5 8.6-2.5h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16h-3.5l73.8 122.4c12.4 20.6 12.9 46.3 1.2 67.3c-.4 .8-.9 1.6-1.4 2.3H592c26.5 0 48-21.5 48-48V240c0-26.5-21.5-48-48-48H568V120c0-13.3-10.7-24-24-24s-24 10.7-24 24v72H480V48c0-26.5-21.5-48-48-48H336zm32 64h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H368c-8.8 0-16-7.2-16-16V80c0-8.8 7.2-16 16-16zM352 176c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H368c-8.8 0-16-7.2-16-16V176zm160 96c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H528c-8.8 0-16-7.2-16-16V272zm16 80h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H528c-8.8 0-16-7.2-16-16V368c0-8.8 7.2-16 16-16zM224 188.9L283.8 288H223l-48 64-24.6-41.2L224 188.9zm29.4-44.2C247.1 134.3 236 128 224 128s-23.1 6.3-29.4 16.7L5.1 458.9c-6.5 10.8-6.7 24.3-.7 35.3S22 512 34.5 512H413.5c12.5 0 24-6.8 30.1-17.8s5.8-24.5-.7-35.3L253.4 144.7z" } }, "free": ["solid"] }, "mountain-sun": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["country", "hiking", "landscape", "rural", "travel", "view"] }, "styles": ["solid"], "unicode": "e52f", "label": "Mountain Sun", "voted": false, "svg": { "solid": { "last_modified": 1684768130, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M560 160A80 80 0 1 0 560 0a80 80 0 1 0 0 160zM55.9 512H381.1h75H578.9c33.8 0 61.1-27.4 61.1-61.1c0-11.2-3.1-22.2-8.9-31.8l-132-216.3C495 196.1 487.8 192 480 192s-15 4.1-19.1 10.7l-48.2 79L286.8 81c-6.6-10.6-18.3-17-30.8-17s-24.1 6.4-30.8 17L8.6 426.4C3 435.3 0 445.6 0 456.1C0 487 25 512 55.9 512z" } }, "free": ["solid"] }, "mug-hot": { "aliases": { "unicodes": { "composite": ["2615"], "secondary": ["10f7b6"] } }, "changes": ["5.6.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "beverage", "caliente", "cocoa", "coffee", "cup", "drink", "holiday", "hot", "hot beverage", "hot chocolate", "steam", "steaming", "tea", "warmth" ] }, "styles": ["solid"], "unicode": "f7b6", "label": "Mug Hot", "voted": false, "svg": { "solid": { "last_modified": 1684767420, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M88 0C74.7 0 64 10.7 64 24c0 38.9 23.4 59.4 39.1 73.1l1.1 1C120.5 112.3 128 119.9 128 136c0 13.3 10.7 24 24 24s24-10.7 24-24c0-38.9-23.4-59.4-39.1-73.1l-1.1-1C119.5 47.7 112 40.1 112 24c0-13.3-10.7-24-24-24zM32 192c-17.7 0-32 14.3-32 32V416c0 53 43 96 96 96H288c53 0 96-43 96-96h16c61.9 0 112-50.1 112-112s-50.1-112-112-112H352 32zm352 64h16c26.5 0 48 21.5 48 48s-21.5 48-48 48H384V256zM224 24c0-13.3-10.7-24-24-24s-24 10.7-24 24c0 38.9 23.4 59.4 39.1 73.1l1.1 1C232.5 112.3 240 119.9 240 136c0 13.3 10.7 24 24 24s24-10.7 24-24c0-38.9-23.4-59.4-39.1-73.1l-1.1-1C231.5 47.7 224 40.1 224 24z" } }, "free": ["solid"] }, "mug-saucer": { "aliases": { "names": ["coffee"], "unicodes": { "secondary": ["10f0f4"] } }, "changes": ["3.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "beverage", "breakfast", "cafe", "drink", "fall", "morning", "mug", "seasonal", "tea" ] }, "styles": ["solid"], "unicode": "f0f4", "label": "Mug Saucer", "voted": false, "svg": { "solid": { "last_modified": 1684767418, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M96 64c0-17.7 14.3-32 32-32H448h64c70.7 0 128 57.3 128 128s-57.3 128-128 128H480c0 53-43 96-96 96H192c-53 0-96-43-96-96V64zM480 224h32c35.3 0 64-28.7 64-64s-28.7-64-64-64H480V224zM32 416H544c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32z" } }, "free": ["solid"] }, "music": { "aliases": { "unicodes": { "composite": ["1f3b5"], "secondary": ["10f001"] } }, "changes": [ "1.0.0", "5.0.0", "5.2.0", "5.11.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "lyrics", "melody", "music", "musical note", "note", "sing", "sound" ] }, "styles": ["solid"], "unicode": "f001", "label": "Music", "voted": false, "svg": { "solid": { "last_modified": 1684766675, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M499.1 6.3c8.1 6 12.9 15.6 12.9 25.7v72V368c0 44.2-43 80-96 80s-96-35.8-96-80s43-80 96-80c11.2 0 22 1.6 32 4.6V147L192 223.8V432c0 44.2-43 80-96 80s-96-35.8-96-80s43-80 96-80c11.2 0 22 1.6 32 4.6V200 128c0-14.1 9.3-26.6 22.8-30.7l320-96c9.7-2.9 20.2-1.1 28.3 5z" } }, "free": ["solid"] }, "n": { "aliases": { "unicodes": { "composite": ["6e"] } }, "changes": ["6.0.0-beta1", "6.2.0", "6.2.1", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "Latin Capital Letter N", "Latin Small Letter N", "letter", "nay", "no" ] }, "styles": ["solid"], "unicode": "4e", "label": "N", "voted": false, "svg": { "solid": { "last_modified": 1684767245, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M21.1 33.9c12.7-4.6 26.9-.7 35.5 9.6L320 359.6V64c0-17.7 14.3-32 32-32s32 14.3 32 32V448c0 13.5-8.4 25.5-21.1 30.1s-26.9 .7-35.5-9.6L64 152.4V448c0 17.7-14.3 32-32 32s-32-14.3-32-32V64C0 50.5 8.4 38.5 21.1 33.9z" } }, "free": ["solid"] }, "naira-sign": { "changes": ["6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Naira Sign", "currency"] }, "styles": ["solid"], "unicode": "e1f6", "label": "Naira Sign", "voted": false, "svg": { "solid": { "last_modified": 1684766475, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M122.6 46.3c-7.8-11.7-22.4-17-35.9-12.9S64 49.9 64 64V256H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H64V448c0 17.7 14.3 32 32 32s32-14.3 32-32V320H228.2l97.2 145.8c7.8 11.7 22.4 17 35.9 12.9s22.7-16.5 22.7-30.6V320h32c17.7 0 32-14.3 32-32s-14.3-32-32-32H384V64c0-17.7-14.3-32-32-32s-32 14.3-32 32V256H262.5L122.6 46.3zM305.1 320H320v22.3L305.1 320zM185.5 256H128V169.7L185.5 256z" } }, "free": ["solid"] }, "napster": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3d2", "label": "Napster", "voted": false, "svg": { "brands": { "last_modified": 1660014480, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M298.3 373.6c-14.2 13.6-31.3 24.1-50.4 30.5-19-6.4-36.2-16.9-50.3-30.5h100.7zm44-199.6c20-16.9 43.6-29.2 69.6-36.2V299c0 219.4-328 217.6-328 .3V137.7c25.9 6.9 49.6 19.6 69.5 36.4 56.8-40 132.5-39.9 188.9-.1zm-208.8-58.5c64.4-60 164.3-60.1 228.9-.2-7.1 3.5-13.9 7.3-20.6 11.5-58.7-30.5-129.2-30.4-187.9.1-6.3-4-13.9-8.2-20.4-11.4zM43.8 93.2v69.3c-58.4 36.5-58.4 121.1.1 158.3 26.4 245.1 381.7 240.3 407.6 1.5l.3-1.7c58.7-36.3 58.9-121.7.2-158.2V93.2c-17.3.5-34 3-50.1 7.4-82-91.5-225.5-91.5-307.5.1-16.3-4.4-33.1-7-50.6-7.5zM259.2 352s36-.3 61.3-1.5c10.2-.5 21.1-4 25.5-6.5 26.3-15.1 25.4-39.2 26.2-47.4-79.5-.6-99.9-3.9-113 55.4zm-135.5-55.3c.8 8.2-.1 32.3 26.2 47.4 4.4 2.5 15.2 6 25.5 6.5 25.3 1.1 61.3 1.5 61.3 1.5-13.2-59.4-33.7-56.1-113-55.4zm169.1 123.4c-3.2-5.3-6.9-7.3-6.9-7.3-24.8 7.3-52.2 6.9-75.9 0 0 0-2.9 1.5-6.4 6.6-2.8 4.1-3.7 9.6-3.7 9.6 29.1 17.6 67.1 17.6 96.2 0-.1-.1-.3-4-3.3-8.9z" } }, "free": ["brands"] }, "neos": { "changes": ["5.2.0", "5.8.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f612", "label": "Neos", "voted": true, "svg": { "brands": { "last_modified": 1660014473, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M415.44 512h-95.11L212.12 357.46v91.1L125.69 512H28V29.82L68.47 0h108.05l123.74 176.13V63.45L386.69 0h97.69v461.5zM38.77 35.27V496l72-52.88V194l215.5 307.64h84.79l52.35-38.17h-78.27L69 13zm82.54 466.61l80-58.78v-101l-79.76-114.4v220.94L49 501.89h72.34zM80.63 10.77l310.6 442.57h82.37V10.77h-79.75v317.56L170.91 10.77zM311 191.65l72 102.81V15.93l-72 53v122.72z" } }, "free": ["brands"] }, "network-wired": { "aliases": { "unicodes": { "secondary": ["10f6ff"] } }, "changes": ["5.4.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["computer", "connect", "ethernet", "internet", "intranet"] }, "styles": ["solid"], "unicode": "f6ff", "label": "Network Wired", "voted": true, "svg": { "solid": { "last_modified": 1684767551, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M256 64H384v64H256V64zM240 0c-26.5 0-48 21.5-48 48v96c0 26.5 21.5 48 48 48h48v32H32c-17.7 0-32 14.3-32 32s14.3 32 32 32h96v32H80c-26.5 0-48 21.5-48 48v96c0 26.5 21.5 48 48 48H240c26.5 0 48-21.5 48-48V368c0-26.5-21.5-48-48-48H192V288H448v32H400c-26.5 0-48 21.5-48 48v96c0 26.5 21.5 48 48 48H560c26.5 0 48-21.5 48-48V368c0-26.5-21.5-48-48-48H512V288h96c17.7 0 32-14.3 32-32s-14.3-32-32-32H352V192h48c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48H240zM96 448V384H224v64H96zm320-64H544v64H416V384z" } }, "free": ["solid"] }, "neuter": { "aliases": { "unicodes": { "composite": ["26b2"], "secondary": ["10f22c"] } }, "changes": [ "4.3.0", "5.0.0", "5.11.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["Neuter", "gender"] }, "styles": ["solid"], "unicode": "f22c", "label": "Neuter", "voted": false, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M80 176a112 112 0 1 1 224 0A112 112 0 1 1 80 176zM224 349.1c81.9-15 144-86.8 144-173.1C368 78.8 289.2 0 192 0S16 78.8 16 176c0 86.3 62.1 158.1 144 173.1V480c0 17.7 14.3 32 32 32s32-14.3 32-32V349.1z" } }, "free": ["solid"] }, "newspaper": { "aliases": { "unicodes": { "composite": ["1f4f0"], "secondary": ["10f1ea"] } }, "changes": ["4.2.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "article", "editorial", "headline", "journal", "journalism", "news", "newspaper", "paper", "press" ] }, "styles": ["solid", "regular"], "unicode": "f1ea", "label": "Newspaper", "voted": false, "svg": { "solid": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M96 96c0-35.3 28.7-64 64-64H448c35.3 0 64 28.7 64 64V416c0 35.3-28.7 64-64 64H80c-44.2 0-80-35.8-80-80V128c0-17.7 14.3-32 32-32s32 14.3 32 32V400c0 8.8 7.2 16 16 16s16-7.2 16-16V96zm64 24v80c0 13.3 10.7 24 24 24H296c13.3 0 24-10.7 24-24V120c0-13.3-10.7-24-24-24H184c-13.3 0-24 10.7-24 24zm208-8c0 8.8 7.2 16 16 16h48c8.8 0 16-7.2 16-16s-7.2-16-16-16H384c-8.8 0-16 7.2-16 16zm0 96c0 8.8 7.2 16 16 16h48c8.8 0 16-7.2 16-16s-7.2-16-16-16H384c-8.8 0-16 7.2-16 16zM160 304c0 8.8 7.2 16 16 16H432c8.8 0 16-7.2 16-16s-7.2-16-16-16H176c-8.8 0-16 7.2-16 16zm0 96c0 8.8 7.2 16 16 16H432c8.8 0 16-7.2 16-16s-7.2-16-16-16H176c-8.8 0-16 7.2-16 16z" }, "regular": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M168 80c-13.3 0-24 10.7-24 24V408c0 8.4-1.4 16.5-4.1 24H440c13.3 0 24-10.7 24-24V104c0-13.3-10.7-24-24-24H168zM72 480c-39.8 0-72-32.2-72-72V112C0 98.7 10.7 88 24 88s24 10.7 24 24V408c0 13.3 10.7 24 24 24s24-10.7 24-24V104c0-39.8 32.2-72 72-72H440c39.8 0 72 32.2 72 72V408c0 39.8-32.2 72-72 72H72zM176 136c0-13.3 10.7-24 24-24h96c13.3 0 24 10.7 24 24v80c0 13.3-10.7 24-24 24H200c-13.3 0-24-10.7-24-24V136zm200-24h32c13.3 0 24 10.7 24 24s-10.7 24-24 24H376c-13.3 0-24-10.7-24-24s10.7-24 24-24zm0 80h32c13.3 0 24 10.7 24 24s-10.7 24-24 24H376c-13.3 0-24-10.7-24-24s10.7-24 24-24zM200 272H408c13.3 0 24 10.7 24 24s-10.7 24-24 24H200c-13.3 0-24-10.7-24-24s10.7-24 24-24zm0 80H408c13.3 0 24 10.7 24 24s-10.7 24-24 24H200c-13.3 0-24-10.7-24-24s10.7-24 24-24z" } }, "free": ["regular", "solid"] }, "nfc-directional": { "changes": ["6.1.0"], "ligatures": [], "search": { "terms": [ "connect", "data", "near field communication", "nfc", "scan", "signal", "transfer", "wireless" ] }, "styles": ["brands"], "unicode": "e530", "label": "NFC Directional", "voted": false, "svg": { "brands": { "last_modified": 1660014475, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M211.8 488.6C213.4 491.1 213.9 494.2 213.2 497.1C212.6 500 210.8 502.6 208.3 504.2C205.7 505.8 202.7 506.3 199.7 505.7C138.3 491.8 84.1 455.8 47.53 404.5C10.97 353.2-5.395 290.3 1.57 227.7C8.536 165 38.34 107.2 85.29 65.21C132.2 23.2 193-.0131 256 0C257.5 0 258.1 .2931 260.3 .8627C261.7 1.432 262.1 2.267 264 3.319C265.1 4.371 265.9 5.619 266.5 6.993C267 8.367 267.3 9.839 267.3 11.32V112.3L291.8 86.39C292.8 85.31 294 84.44 295.4 83.84C296.7 83.23 298.2 82.9 299.7 82.86C301.2 82.81 302.6 83.06 304 83.59C305.4 84.12 306.7 84.92 307.8 85.94C308.8 86.96 309.7 88.18 310.3 89.54C310.9 90.89 311.3 92.35 311.3 93.84C311.3 95.32 311.1 96.8 310.6 98.18C310 99.57 309.2 100.8 308.2 101.9L264.2 148.5C263.1 149.6 261.9 150.5 260.5 151.1C259 151.7 257.5 152 255.1 152C254.5 152 252.9 151.7 251.5 151.1C250.1 150.5 248.8 149.6 247.8 148.5L203.7 101.9C201.7 99.74 200.6 96.83 200.7 93.84C200.7 90.84 202 87.1 204.2 85.94C206.4 83.88 209.3 82.77 212.3 82.86C215.3 82.94 218.1 84.21 220.2 86.39L244.7 112.4V22.89C188.3 25.64 134.9 48.73 94.23 87.87C53.58 127 28.49 179.6 23.61 235.8C18.73 292 34.38 348.1 67.68 393.7C100.1 439.2 149.7 471.2 204.7 483.6C207.6 484.3 210.2 486.1 211.8 488.6L211.8 488.6zM171.4 126.1C170.6 127.4 169.5 128.5 168.3 129.3C147.8 143.2 131.1 161.9 119.5 183.8C107.9 205.7 101.8 230.1 101.8 254.9C101.8 279.7 107.9 304.1 119.5 325.1C131.1 347.9 147.8 366.6 168.3 380.5C170.8 382.2 172.5 384.8 173 387.8C173.6 390.7 172.1 393.8 171.3 396.2C169.6 398.7 166.1 400.4 164 400.1C161.1 401.5 158 400.9 155.6 399.2C132 383.2 112.8 361.7 99.46 336.5C86.15 311.4 79.19 283.4 79.19 254.9C79.19 226.5 86.15 198.4 99.46 173.3C112.8 148.1 132 126.6 155.6 110.6C156.8 109.8 158.2 109.2 159.6 108.8C161.1 108.5 162.6 108.5 164.1 108.8C165.5 109 166.9 109.6 168.2 110.4C169.5 111.2 170.5 112.3 171.4 113.5C172.2 114.7 172.8 116.1 173.1 117.6C173.4 119.1 173.4 120.6 173.1 122C172.8 123.5 172.3 124.9 171.4 126.1H171.4zM340.9 383.5C341.7 382.3 342.8 381.2 343.1 380.4V380.3C364.4 366.3 381.1 347.6 392.7 325.7C404.2 303.9 410.2 279.5 410.2 254.8C410.2 230.1 404.2 205.7 392.7 183.8C381.1 161.1 364.4 143.3 343.1 129.3C342.8 128.5 341.7 127.4 340.9 126.2C340.1 124.9 339.5 123.5 339.3 122.1C338.1 120.6 339 119.1 339.3 117.7C339.6 116.2 340.2 114.8 341 113.6C341.9 112.4 342.1 111.3 344.2 110.5C345.4 109.7 346.8 109.2 348.3 108.9C349.8 108.6 351.2 108.6 352.7 108.9C354.2 109.2 355.5 109.8 356.8 110.7C380.2 126.7 399.5 148.2 412.7 173.3C426 198.4 432.1 226.4 432.1 254.8C432.1 283.3 426 311.3 412.7 336.4C399.5 361.5 380.2 383 356.8 399C355.5 399.9 354.2 400.5 352.7 400.8C351.2 401.1 349.8 401.1 348.3 400.8C346.8 400.5 345.4 399.1 344.2 399.2C342.1 398.4 341.9 397.3 341 396.1C340.2 394.9 339.6 393.5 339.3 392C339 390.6 338.1 389.1 339.3 387.6C339.5 386.2 340.1 384.8 340.9 383.5V383.5zM312.3 6.307C368.5 19.04 418.7 50.28 455 95.01C485.4 132.6 504.6 178 510.3 226C515.9 274 507.9 322.7 487.1 366.3C466.2 409.9 433.5 446.8 392.6 472.6C351.7 498.3 304.4 512 256 512C254.5 512 253.1 511.7 251.7 511.1C250.3 510.6 249.1 509.7 248 508.7C246.1 507.6 246.1 506.4 245.6 505C245 503.6 244.7 502.2 244.7 500.7V401.5L220.2 427.5C218.1 429.7 215.3 430.1 212.3 431.1C209.3 431.2 206.4 430 204.2 427.1C202 425.9 200.7 423.1 200.7 420.1C200.6 417.1 201.7 414.2 203.7 412L247.8 365.4C249.1 363.2 252.9 362 255.1 362C259.1 362 262 363.2 264.2 365.4L308.2 412C310.3 414.2 311.4 417.1 311.3 420.1C311.2 423.1 309.9 425.9 307.8 427.1C305.6 430 302.7 431.2 299.7 431.1C296.7 430.1 293.8 429.7 291.8 427.5L267.3 401.6V489.1C323.7 486.3 377.1 463.3 417.8 424.1C458.5 384.1 483.6 332.4 488.5 276.2C493.3 219.1 477.7 163.9 444.4 118.3C411.1 72.75 362.4 40.79 307.4 28.36C305.9 28.03 304.6 27.42 303.3 26.57C302.1 25.71 301.1 24.63 300.3 23.37C299.5 22.12 298.1 20.72 298.7 19.26C298.5 17.8 298.5 16.3 298.8 14.85C299.2 13.41 299.8 12.04 300.6 10.82C301.5 9.61 302.6 8.577 303.8 7.784C305.1 6.99 306.5 6.451 307.9 6.198C309.4 5.945 310.9 5.982 312.3 6.307L312.3 6.307zM353.1 256.1C353.1 287.5 335.6 317.2 303.8 339.6C301.7 341.1 299 341.9 296.4 341.6C293.7 341.4 291.2 340.3 289.4 338.4L219.3 268.6C217.1 266.5 215.1 263.6 215.9 260.6C215.9 257.6 217.1 254.7 219.2 252.6C221.4 250.5 224.2 249.3 227.2 249.3C230.2 249.3 233.1 250.5 235.2 252.6L298.3 315.4C319.1 298.3 330.5 277.5 330.5 256.1C330.5 232.2 316.4 209.1 290.8 191C288.3 189.3 286.7 186.7 286.2 183.7C285.7 180.8 286.3 177.7 288.1 175.3C289.8 172.8 292.4 171.2 295.4 170.7C298.3 170.2 301.4 170.8 303.8 172.6C335.6 195 353.1 224.7 353.1 256.1V256.1zM216.7 341.5C213.7 342 210.7 341.3 208.2 339.6C176.5 317.2 158.1 287.5 158.1 256.1C158.1 224.7 176.5 195 208.2 172.6C210.4 171 213.1 170.3 215.7 170.5C218.4 170.8 220.8 171.9 222.7 173.8L292.8 243.6C294.9 245.7 296.1 248.6 296.1 251.6C296.1 254.6 294.1 257.4 292.8 259.6C290.7 261.7 287.8 262.9 284.9 262.9C281.9 262.9 278.1 261.7 276.9 259.6L213.8 196.7C192.9 214 181.6 234.7 181.6 256.1C181.6 279.1 195.7 303.1 221.3 321.1C223.7 322.9 225.4 325.5 225.9 328.5C226.4 331.4 225.7 334.4 224 336.9C222.3 339.3 219.6 341 216.7 341.5L216.7 341.5z" } }, "free": ["brands"] }, "nfc-symbol": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "connect", "data", "near field communication", "nfc", "scan", "signal", "transfer", "wireless" ] }, "styles": ["brands"], "unicode": "e531", "label": "Nfc Symbol", "voted": false, "svg": { "brands": { "last_modified": 1660014471, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M392.9 32.43C400.6 31.1 408.6 32.89 414.1 37.41C498.2 96.14 544 173.7 544 255.1C544 338.2 498.2 415.9 414.1 474.6C409.3 478.6 402.4 480.5 395.5 479.9C388.5 479.3 382 476.3 377.1 471.4L193.7 288.7C188.1 283.2 185 275.7 184.1 267.8C184.1 260 188.1 252.5 193.6 246.9C199.2 241.4 206.7 238.2 214.5 238.2C222.4 238.2 229.9 241.3 235.4 246.8L400.5 411.2C455.1 366.5 484.8 312 484.8 255.1C484.8 193.5 447.9 132.9 380.9 85.76C374.5 81.24 370.1 74.35 368.8 66.62C367.4 58.89 369.2 50.94 373.8 44.53C378.3 38.12 385.2 33.77 392.9 32.43V32.43zM186.9 479.6C179.2 480.9 171.3 479.1 164.8 474.6C81.67 415.9 35.84 338.2 35.84 255.1C35.84 173.7 81.67 96.14 164.8 37.41C170.5 33.4 177.4 31.53 184.4 32.12C191.3 32.71 197.8 35.72 202.7 40.63L386.1 223.3C391.7 228.8 394.8 236.3 394.8 244.2C394.9 251.1 391.8 259.5 386.2 265.1C380.7 270.6 373.2 273.8 365.3 273.8C357.5 273.8 349.1 270.7 344.4 265.2L179.3 100.7C124.7 145.9 95.03 199.9 95.03 255.1C95.03 318.5 131.9 379.1 198.1 426.2C205.4 430.8 209.7 437.6 211.1 445.4C212.4 453.1 210.6 461.1 206.1 467.5C201.6 473.9 194.7 478.2 186.9 479.6V479.6z" } }, "free": ["brands"] }, "nimblr": { "changes": ["5.1.0", "5.8.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f5a8", "label": "Nimblr", "voted": false, "svg": { "brands": { "last_modified": 1660014479, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M246.6 299.29c15.57 0 27.15 11.46 27.15 27s-11.62 27-27.15 27c-15.7 0-27.15-11.57-27.15-27s11.55-27 27.15-27zM113 326.25c0-15.61 11.68-27 27.15-27s27.15 11.46 27.15 27-11.47 27-27.15 27c-15.44 0-27.15-11.31-27.15-27M191.76 159C157 159 89.45 178.77 59.25 227L14 0v335.48C14 433.13 93.61 512 191.76 512s177.76-78.95 177.76-176.52S290.13 159 191.76 159zm0 308.12c-73.27 0-132.51-58.9-132.51-131.59s59.24-131.59 132.51-131.59 132.51 58.86 132.51 131.54S265 467.07 191.76 467.07z" } }, "free": ["brands"] }, "node": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f419", "label": "Node.js", "voted": true, "svg": { "brands": { "last_modified": 1660014477, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M316.3 452c-2.1 0-4.2-.6-6.1-1.6L291 439c-2.9-1.6-1.5-2.2-.5-2.5 3.8-1.3 4.6-1.6 8.7-4 .4-.2 1-.1 1.4.1l14.8 8.8c.5.3 1.3.3 1.8 0L375 408c.5-.3.9-.9.9-1.6v-66.7c0-.7-.3-1.3-.9-1.6l-57.8-33.3c-.5-.3-1.2-.3-1.8 0l-57.8 33.3c-.6.3-.9 1-.9 1.6v66.7c0 .6.4 1.2.9 1.5l15.8 9.1c8.6 4.3 13.9-.8 13.9-5.8v-65.9c0-.9.7-1.7 1.7-1.7h7.3c.9 0 1.7.7 1.7 1.7v65.9c0 11.5-6.2 18-17.1 18-3.3 0-6 0-13.3-3.6l-15.2-8.7c-3.7-2.2-6.1-6.2-6.1-10.5v-66.7c0-4.3 2.3-8.4 6.1-10.5l57.8-33.4c3.7-2.1 8.5-2.1 12.1 0l57.8 33.4c3.7 2.2 6.1 6.2 6.1 10.5v66.7c0 4.3-2.3 8.4-6.1 10.5l-57.8 33.4c-1.7 1.1-3.8 1.7-6 1.7zm46.7-65.8c0-12.5-8.4-15.8-26.2-18.2-18-2.4-19.8-3.6-19.8-7.8 0-3.5 1.5-8.1 14.8-8.1 11.9 0 16.3 2.6 18.1 10.6.2.8.8 1.3 1.6 1.3h7.5c.5 0 .9-.2 1.2-.5.3-.4.5-.8.4-1.3-1.2-13.8-10.3-20.2-28.8-20.2-16.5 0-26.3 7-26.3 18.6 0 12.7 9.8 16.1 25.6 17.7 18.9 1.9 20.4 4.6 20.4 8.3 0 6.5-5.2 9.2-17.4 9.2-15.3 0-18.7-3.8-19.8-11.4-.1-.8-.8-1.4-1.7-1.4h-7.5c-.9 0-1.7.7-1.7 1.7 0 9.7 5.3 21.3 30.6 21.3 18.5 0 29-7.2 29-19.8zm54.5-50.1c0 6.1-5 11.1-11.1 11.1s-11.1-5-11.1-11.1c0-6.3 5.2-11.1 11.1-11.1 6-.1 11.1 4.8 11.1 11.1zm-1.8 0c0-5.2-4.2-9.3-9.4-9.3-5.1 0-9.3 4.1-9.3 9.3 0 5.2 4.2 9.4 9.3 9.4 5.2-.1 9.4-4.3 9.4-9.4zm-4.5 6.2h-2.6c-.1-.6-.5-3.8-.5-3.9-.2-.7-.4-1.1-1.3-1.1h-2.2v5h-2.4v-12.5h4.3c1.5 0 4.4 0 4.4 3.3 0 2.3-1.5 2.8-2.4 3.1 1.7.1 1.8 1.2 2.1 2.8.1 1 .3 2.7.6 3.3zm-2.8-8.8c0-1.7-1.2-1.7-1.8-1.7h-2v3.5h1.9c1.6 0 1.9-1.1 1.9-1.8zM137.3 191c0-2.7-1.4-5.1-3.7-6.4l-61.3-35.3c-1-.6-2.2-.9-3.4-1h-.6c-1.2 0-2.3.4-3.4 1L3.7 184.6C1.4 185.9 0 188.4 0 191l.1 95c0 1.3.7 2.5 1.8 3.2 1.1.7 2.5.7 3.7 0L42 268.3c2.3-1.4 3.7-3.8 3.7-6.4v-44.4c0-2.6 1.4-5.1 3.7-6.4l15.5-8.9c1.2-.7 2.4-1 3.7-1 1.3 0 2.6.3 3.7 1l15.5 8.9c2.3 1.3 3.7 3.8 3.7 6.4v44.4c0 2.6 1.4 5.1 3.7 6.4l36.4 20.9c1.1.7 2.6.7 3.7 0 1.1-.6 1.8-1.9 1.8-3.2l.2-95zM472.5 87.3v176.4c0 2.6-1.4 5.1-3.7 6.4l-61.3 35.4c-2.3 1.3-5.1 1.3-7.4 0l-61.3-35.4c-2.3-1.3-3.7-3.8-3.7-6.4v-70.8c0-2.6 1.4-5.1 3.7-6.4l61.3-35.4c2.3-1.3 5.1-1.3 7.4 0l15.3 8.8c1.7 1 3.9-.3 3.9-2.2v-94c0-2.8 3-4.6 5.5-3.2l36.5 20.4c2.3 1.2 3.8 3.7 3.8 6.4zm-46 128.9c0-.7-.4-1.3-.9-1.6l-21-12.2c-.6-.3-1.3-.3-1.9 0l-21 12.2c-.6.3-.9.9-.9 1.6v24.3c0 .7.4 1.3.9 1.6l21 12.1c.6.3 1.3.3 1.8 0l21-12.1c.6-.3.9-.9.9-1.6v-24.3zm209.8-.7c2.3-1.3 3.7-3.8 3.7-6.4V192c0-2.6-1.4-5.1-3.7-6.4l-60.9-35.4c-2.3-1.3-5.1-1.3-7.4 0l-61.3 35.4c-2.3 1.3-3.7 3.8-3.7 6.4v70.8c0 2.7 1.4 5.1 3.7 6.4l60.9 34.7c2.2 1.3 5 1.3 7.3 0l36.8-20.5c2.5-1.4 2.5-5 0-6.4L550 241.6c-1.2-.7-1.9-1.9-1.9-3.2v-22.2c0-1.3.7-2.5 1.9-3.2l19.2-11.1c1.1-.7 2.6-.7 3.7 0l19.2 11.1c1.1.7 1.9 1.9 1.9 3.2v17.4c0 2.8 3.1 4.6 5.6 3.2l36.7-21.3zM559 219c-.4.3-.7.7-.7 1.2v13.6c0 .5.3 1 .7 1.2l11.8 6.8c.4.3 1 .3 1.4 0L584 235c.4-.3.7-.7.7-1.2v-13.6c0-.5-.3-1-.7-1.2l-11.8-6.8c-.4-.3-1-.3-1.4 0L559 219zm-254.2 43.5v-70.4c0-2.6-1.6-5.1-3.9-6.4l-61.1-35.2c-2.1-1.2-5-1.4-7.4 0l-61.1 35.2c-2.3 1.3-3.9 3.7-3.9 6.4v70.4c0 2.8 1.9 5.2 4 6.4l61.2 35.2c2.4 1.4 5.2 1.3 7.4 0l61-35.2c1.8-1 3.1-2.7 3.6-4.7.1-.5.2-1.1.2-1.7zm-74.3-124.9l-.8.5h1.1l-.3-.5zm76.2 130.2l-.4-.7v.9l.4-.2z" } }, "free": ["brands"] }, "node-js": { "changes": ["5.0.0", "5.0.3"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3d3", "label": "Node.js JS", "voted": false, "svg": { "brands": { "last_modified": 1660014460, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M224 508c-6.7 0-13.5-1.8-19.4-5.2l-61.7-36.5c-9.2-5.2-4.7-7-1.7-8 12.3-4.3 14.8-5.2 27.9-12.7 1.4-.8 3.2-.5 4.6.4l47.4 28.1c1.7 1 4.1 1 5.7 0l184.7-106.6c1.7-1 2.8-3 2.8-5V149.3c0-2.1-1.1-4-2.9-5.1L226.8 37.7c-1.7-1-4-1-5.7 0L36.6 144.3c-1.8 1-2.9 3-2.9 5.1v213.1c0 2 1.1 4 2.9 4.9l50.6 29.2c27.5 13.7 44.3-2.4 44.3-18.7V167.5c0-3 2.4-5.3 5.4-5.3h23.4c2.9 0 5.4 2.3 5.4 5.3V378c0 36.6-20 57.6-54.7 57.6-10.7 0-19.1 0-42.5-11.6l-48.4-27.9C8.1 389.2.7 376.3.7 362.4V149.3c0-13.8 7.4-26.8 19.4-33.7L204.6 9c11.7-6.6 27.2-6.6 38.8 0l184.7 106.7c12 6.9 19.4 19.8 19.4 33.7v213.1c0 13.8-7.4 26.7-19.4 33.7L243.4 502.8c-5.9 3.4-12.6 5.2-19.4 5.2zm149.1-210.1c0-39.9-27-50.5-83.7-58-57.4-7.6-63.2-11.5-63.2-24.9 0-11.1 4.9-25.9 47.4-25.9 37.9 0 51.9 8.2 57.7 33.8.5 2.4 2.7 4.2 5.2 4.2h24c1.5 0 2.9-.6 3.9-1.7s1.5-2.6 1.4-4.1c-3.7-44.1-33-64.6-92.2-64.6-52.7 0-84.1 22.2-84.1 59.5 0 40.4 31.3 51.6 81.8 56.6 60.5 5.9 65.2 14.8 65.2 26.7 0 20.6-16.6 29.4-55.5 29.4-48.9 0-59.6-12.3-63.2-36.6-.4-2.6-2.6-4.5-5.3-4.5h-23.9c-3 0-5.3 2.4-5.3 5.3 0 31.1 16.9 68.2 97.8 68.2 58.4-.1 92-23.2 92-63.4z" } }, "free": ["brands"] }, "not-equal": { "aliases": { "unicodes": { "secondary": ["10f53e"] } }, "changes": ["5.0.13", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["arithmetic", "compare", "math"] }, "styles": ["solid"], "unicode": "f53e", "label": "Not Equal", "voted": true, "svg": { "solid": { "last_modified": 1684767246, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M369.8 37.4c14.7 9.8 18.7 29.7 8.9 44.4L337.1 144H400c17.7 0 32 14.3 32 32s-14.3 32-32 32H294.5l-64 96H400c17.7 0 32 14.3 32 32s-14.3 32-32 32H187.8l-65.2 97.7c-9.8 14.7-29.7 18.7-44.4 8.9s-18.7-29.7-8.9-44.4L110.9 368H48c-17.7 0-32-14.3-32-32s14.3-32 32-32H153.5l64-96H48c-17.7 0-32-14.3-32-32s14.3-32 32-32H260.2l65.2-97.7c9.8-14.7 29.7-18.7 44.4-8.9z" } }, "free": ["solid"] }, "notdef": { "changes": ["6.0.0-beta1", "6.2.0", "6.2.1", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["close", "missing"] }, "styles": ["solid"], "unicode": "e1fe", "label": "Notdef", "voted": false, "svg": { "solid": { "last_modified": 1684767244, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M64 390.3L153.5 256 64 121.7V390.3zM102.5 448H281.5L192 313.7 102.5 448zm128-192L320 390.3V121.7L230.5 256zM281.5 64H102.5L192 198.3 281.5 64zM0 48C0 21.5 21.5 0 48 0H336c26.5 0 48 21.5 48 48V464c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V48z" } }, "free": ["solid"] }, "note-sticky": { "aliases": { "names": ["sticky-note"], "unicodes": { "composite": ["f24a"], "secondary": ["10f249"] } }, "changes": [ "4.4.0", "5.0.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.2.1", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["message", "note", "paper", "reminder", "sticker"] }, "styles": ["solid", "regular"], "unicode": "f249", "label": "Note Sticky", "voted": false, "svg": { "solid": { "last_modified": 1684767389, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H288V368c0-26.5 21.5-48 48-48H448V96c0-35.3-28.7-64-64-64H64zM448 352H402.7 336c-8.8 0-16 7.2-16 16v66.7V480l32-32 64-64 32-32z" }, "regular": { "last_modified": 1684767389, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M64 80c-8.8 0-16 7.2-16 16V416c0 8.8 7.2 16 16 16H288V352c0-17.7 14.3-32 32-32h80V96c0-8.8-7.2-16-16-16H64zM288 480H64c-35.3 0-64-28.7-64-64V96C0 60.7 28.7 32 64 32H384c35.3 0 64 28.7 64 64V320v5.5c0 17-6.7 33.3-18.7 45.3l-90.5 90.5c-12 12-28.3 18.7-45.3 18.7H288z" } }, "free": ["regular", "solid"] }, "notes-medical": { "aliases": { "unicodes": { "secondary": ["10f481"] } }, "changes": ["5.0.7", "6.0.0-beta1", "6.2.0", "6.2.1", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["clipboard", "doctor", "ehr", "health", "history", "records"] }, "styles": ["solid"], "unicode": "f481", "label": "Notes Medical", "voted": false, "svg": { "solid": { "last_modified": 1684767392, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M96 352V96c0-35.3 28.7-64 64-64H416c35.3 0 64 28.7 64 64V293.5c0 17-6.7 33.3-18.7 45.3l-58.5 58.5c-12 12-28.3 18.7-45.3 18.7H160c-35.3 0-64-28.7-64-64zM272 128c-8.8 0-16 7.2-16 16v48H208c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h48v48c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V256h48c8.8 0 16-7.2 16-16V208c0-8.8-7.2-16-16-16H320V144c0-8.8-7.2-16-16-16H272zm24 336c13.3 0 24 10.7 24 24s-10.7 24-24 24H136C60.9 512 0 451.1 0 376V152c0-13.3 10.7-24 24-24s24 10.7 24 24l0 224c0 48.6 39.4 88 88 88H296z" } }, "free": ["solid"] }, "npm": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3d4", "label": "npm", "voted": false, "svg": { "brands": { "last_modified": 1660014461, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M288 288h-32v-64h32v64zm288-128v192H288v32H160v-32H0V160h576zm-416 32H32v128h64v-96h32v96h32V192zm160 0H192v160h64v-32h64V192zm224 0H352v128h64v-96h32v96h32v-96h32v96h32V192z" } }, "free": ["brands"] }, "ns8": { "changes": ["5.0.0", "5.15.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3d5", "label": "NS8", "voted": false, "svg": { "brands": { "last_modified": 1660014464, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M104.324,269.172h26.067V242.994H104.324Zm52.466-26.178-.055-26.178v-.941a39.325,39.325,0,0,0-78.644.941v.166h26.4v-.166a12.98,12.98,0,0,1,25.956,0v26.178Zm52.356,25.846a91.1,91.1,0,0,1-91.1,91.1h-.609a91.1,91.1,0,0,1-91.1-91.1H0v.166A117.33,117.33,0,0,0,117.44,386.28h.775A117.331,117.331,0,0,0,235.49,268.84V242.828H209.146Zm-157.233,0a65.362,65.362,0,0,0,130.723,0H156.292a39.023,39.023,0,0,1-78.035,0V242.883H51.968v-26.62A65.42,65.42,0,0,1,182.8,217.48v25.293h26.344V217.48a91.761,91.761,0,0,0-183.522,0v25.4H51.913Zm418.4-71.173c13.67,0,24.573,6.642,30.052,18.264l.719,1.549,23.245-11.511-.609-1.439c-8.025-19.26-28.5-31.27-53.407-31.27-23.134,0-43.611,11.4-50.972,28.447-.123,26.876-.158,23.9,0,24.85,4.7,11.013,14.555,19.37,28.668,24.241a102.033,102.033,0,0,0,19.813,3.984c5.479.72,10.626,1.384,15.829,3.1,6.364,2.1,10.46,5.257,12.84,9.851v9.851c-3.708,7.527-13.781,12.342-25.791,12.342-14.334,0-25.956-6.918-31.933-19.039l-.72-1.494L415.026,280.9l.553,1.439c7.915,19.426,29.609,32.044,55.289,32.044,23.632,0,44.608-11.4,52.3-28.447l.166-25.9-.166-.664c-4.87-11.014-15.219-19.647-28.944-24.241-7.693-2.712-14.335-3.6-20.7-4.427a83.777,83.777,0,0,1-14.832-2.878c-6.31-1.937-10.4-5.092-12.619-9.63v-8.412C449.45,202.427,458.969,197.667,470.315,197.667ZM287.568,311.344h26.067v-68.4H287.568Zm352.266-53.3c-2.933-6.254-8.3-12.01-15.441-16.714A37.99,37.99,0,0,0,637.4,226l.166-25.347-.166-.664C630.038,184,610.667,173.26,589.25,173.26S548.461,184,541.1,199.992l-.166,25.347.166.664a39.643,39.643,0,0,0,13.006,15.331c-7.2,4.7-12.508,10.46-15.441,16.714l-.166,28.889.166.72c7.582,15.994,27.893,26.731,50.585,26.731s43.057-10.737,50.584-26.731l.166-28.89Zm-73.22-50.806c3.6-6.31,12.563-10.516,22.58-10.516s19.038,4.206,22.636,10.516v13.725c-3.542,6.2-12.563,10.349-22.636,10.349s-19.094-4.15-22.58-10.349Zm47.319,72.169c-3.764,6.641-13.338,10.9-24.683,10.9-11.125,0-20.976-4.372-24.684-10.9V263.25c3.708-6.309,13.5-10.515,24.684-10.515,11.345,0,20.919,4.15,24.683,10.515ZM376.4,265.962l-59.827-89.713h-29v40.623h26.51v.387l62.539,94.085H402.3V176.249H376.4Z" } }, "free": ["brands"] }, "nutritionix": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3d6", "label": "Nutritionix", "voted": false, "svg": { "brands": { "last_modified": 1660014459, "raw": "", "viewBox": [0, 0, 400, 512], "width": 400, "height": 512, "path": "M88 8.1S221.4-.1 209 112.5c0 0 19.1-74.9 103-40.6 0 0-17.7 74-88 56 0 0 14.6-54.6 66.1-56.6 0 0-39.9-10.3-82.1 48.8 0 0-19.8-94.5-93.6-99.7 0 0 75.2 19.4 77.6 107.5 0 .1-106.4 7-104-119.8zm312 315.6c0 48.5-9.7 95.3-32 132.3-42.2 30.9-105 48-168 48-62.9 0-125.8-17.1-168-48C9.7 419 0 372.2 0 323.7 0 275.3 17.7 229 40 192c42.2-30.9 97.1-48.6 160-48.6 63 0 117.8 17.6 160 48.6 22.3 37 40 83.3 40 131.7zM120 428c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zM192 428c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zM264 428c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zM336 428c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm0-66.2c0-15.5-12.5-28-28-28s-28 12.5-28 28 12.5 28 28 28 28-12.5 28-28zm24-39.6c-4.8-22.3-7.4-36.9-16-56-38.8-19.9-90.5-32-144-32S94.8 180.1 56 200c-8.8 19.5-11.2 33.9-16 56 42.2-7.9 98.7-14.8 160-14.8s117.8 6.9 160 14.8z" } }, "free": ["brands"] }, "o": { "aliases": { "unicodes": { "composite": ["6f"] } }, "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Latin Capital Letter O", "Latin Small Letter O", "letter"] }, "styles": ["solid"], "unicode": "4f", "label": "O", "voted": false, "svg": { "solid": { "last_modified": 1684767245, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M224 96a160 160 0 1 0 0 320 160 160 0 1 0 0-320zM448 256A224 224 0 1 1 0 256a224 224 0 1 1 448 0z" } }, "free": ["solid"] }, "object-group": { "aliases": { "unicodes": { "secondary": ["10f247"] } }, "changes": [ "4.4.0", "5.0.0", "5.10.1", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["combine", "copy", "design", "merge", "select"] }, "styles": ["solid", "regular"], "unicode": "f247", "label": "Object Group", "voted": false, "svg": { "solid": { "last_modified": 1684767367, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M32 119.4C12.9 108.4 0 87.7 0 64C0 28.7 28.7 0 64 0c23.7 0 44.4 12.9 55.4 32H456.6C467.6 12.9 488.3 0 512 0c35.3 0 64 28.7 64 64c0 23.7-12.9 44.4-32 55.4V392.6c19.1 11.1 32 31.7 32 55.4c0 35.3-28.7 64-64 64c-23.7 0-44.4-12.9-55.4-32H119.4c-11.1 19.1-31.7 32-55.4 32c-35.3 0-64-28.7-64-64c0-23.7 12.9-44.4 32-55.4V119.4zM456.6 96H119.4c-5.6 9.7-13.7 17.8-23.4 23.4V392.6c9.7 5.6 17.8 13.7 23.4 23.4H456.6c5.6-9.7 13.7-17.8 23.4-23.4V119.4c-9.7-5.6-17.8-13.7-23.4-23.4zM128 160c0-17.7 14.3-32 32-32H288c17.7 0 32 14.3 32 32v96c0 17.7-14.3 32-32 32H160c-17.7 0-32-14.3-32-32V160zM256 320h32c35.3 0 64-28.7 64-64V224h64c17.7 0 32 14.3 32 32v96c0 17.7-14.3 32-32 32H288c-17.7 0-32-14.3-32-32V320z" }, "regular": { "last_modified": 1684767367, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M48 115.8C38.2 107 32 94.2 32 80c0-26.5 21.5-48 48-48c14.2 0 27 6.2 35.8 16H460.2c8.8-9.8 21.6-16 35.8-16c26.5 0 48 21.5 48 48c0 14.2-6.2 27-16 35.8V396.2c9.8 8.8 16 21.6 16 35.8c0 26.5-21.5 48-48 48c-14.2 0-27-6.2-35.8-16H115.8c-8.8 9.8-21.6 16-35.8 16c-26.5 0-48-21.5-48-48c0-14.2 6.2-27 16-35.8V115.8zM125.3 96c-4.8 13.6-15.6 24.4-29.3 29.3V386.7c13.6 4.8 24.4 15.6 29.3 29.3H450.7c4.8-13.6 15.6-24.4 29.3-29.3V125.3c-13.6-4.8-24.4-15.6-29.3-29.3H125.3zm2.7 64c0-17.7 14.3-32 32-32H288c17.7 0 32 14.3 32 32v96c0 17.7-14.3 32-32 32H160c-17.7 0-32-14.3-32-32V160zM256 320h32c35.3 0 64-28.7 64-64V224h64c17.7 0 32 14.3 32 32v96c0 17.7-14.3 32-32 32H288c-17.7 0-32-14.3-32-32V320z" } }, "free": ["regular", "solid"] }, "object-ungroup": { "aliases": { "unicodes": { "secondary": ["10f248"] } }, "changes": [ "4.4.0", "5.0.0", "5.10.1", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["copy", "design", "merge", "select", "separate"] }, "styles": ["solid", "regular"], "unicode": "f248", "label": "Object Ungroup", "voted": false, "svg": { "solid": { "last_modified": 1684767367, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M32 119.4C12.9 108.4 0 87.7 0 64C0 28.7 28.7 0 64 0c23.7 0 44.4 12.9 55.4 32H328.6C339.6 12.9 360.3 0 384 0c35.3 0 64 28.7 64 64c0 23.7-12.9 44.4-32 55.4V232.6c19.1 11.1 32 31.7 32 55.4c0 35.3-28.7 64-64 64c-23.7 0-44.4-12.9-55.4-32H119.4c-11.1 19.1-31.7 32-55.4 32c-35.3 0-64-28.7-64-64c0-23.7 12.9-44.4 32-55.4V119.4zM119.4 96c-5.6 9.7-13.7 17.8-23.4 23.4V232.6c9.7 5.6 17.8 13.7 23.4 23.4H328.6c5.6-9.7 13.7-17.8 23.4-23.4V119.4c-9.7-5.6-17.8-13.7-23.4-23.4H119.4zm192 384c-11.1 19.1-31.7 32-55.4 32c-35.3 0-64-28.7-64-64c0-23.7 12.9-44.4 32-55.4V352h64v40.6c9.7 5.6 17.8 13.7 23.4 23.4H520.6c5.6-9.7 13.7-17.8 23.4-23.4V279.4c-9.7-5.6-17.8-13.7-23.4-23.4h-46c-5.4-15.4-14.6-28.9-26.5-39.6V192h72.6c11.1-19.1 31.7-32 55.4-32c35.3 0 64 28.7 64 64c0 23.7-12.9 44.4-32 55.4V392.6c19.1 11.1 32 31.7 32 55.4c0 35.3-28.7 64-64 64c-23.7 0-44.4-12.9-55.4-32H311.4z" }, "regular": { "last_modified": 1684767367, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M48.2 66.8c-.1-.8-.2-1.7-.2-2.5c0-.1 0-.1 0-.2c0-8.8 7.2-16 16-16c.9 0 1.9 .1 2.8 .2C74.3 49.5 80 56.1 80 64c0 8.8-7.2 16-16 16c-7.9 0-14.5-5.7-15.8-13.2zM0 64c0 26.9 16.5 49.9 40 59.3V228.7C16.5 238.1 0 261.1 0 288c0 35.3 28.7 64 64 64c26.9 0 49.9-16.5 59.3-40H324.7c9.5 23.5 32.5 40 59.3 40c35.3 0 64-28.7 64-64c0-26.9-16.5-49.9-40-59.3V123.3c23.5-9.5 40-32.5 40-59.3c0-35.3-28.7-64-64-64c-26.9 0-49.9 16.5-59.3 40H123.3C113.9 16.5 90.9 0 64 0C28.7 0 0 28.7 0 64zm368 0a16 16 0 1 1 32 0 16 16 0 1 1 -32 0zM324.7 88c6.5 16 19.3 28.9 35.3 35.3V228.7c-16 6.5-28.9 19.3-35.3 35.3H123.3c-6.5-16-19.3-28.9-35.3-35.3V123.3c16-6.5 28.9-19.3 35.3-35.3H324.7zM384 272a16 16 0 1 1 0 32 16 16 0 1 1 0-32zM80 288c0 7.9-5.7 14.5-13.2 15.8c-.8 .1-1.7 .2-2.5 .2l-.2 0c-8.8 0-16-7.2-16-16c0-.9 .1-1.9 .2-2.8C49.5 277.7 56.1 272 64 272c8.8 0 16 7.2 16 16zm391.3-40h45.4c6.5 16 19.3 28.9 35.3 35.3V388.7c-16 6.5-28.9 19.3-35.3 35.3H315.3c-6.5-16-19.3-28.9-35.3-35.3V352H232v36.7c-23.5 9.5-40 32.5-40 59.3c0 35.3 28.7 64 64 64c26.9 0 49.9-16.5 59.3-40H516.7c9.5 23.5 32.5 40 59.3 40c35.3 0 64-28.7 64-64c0-26.9-16.5-49.9-40-59.3V283.3c23.5-9.5 40-32.5 40-59.3c0-35.3-28.7-64-64-64c-26.9 0-49.9 16.5-59.3 40H448v16.4c9.8 8.8 17.8 19.5 23.3 31.6zm88.9-26.7a16 16 0 1 1 31.5 5.5 16 16 0 1 1 -31.5-5.5zM271.8 450.7a16 16 0 1 1 -31.5-5.5 16 16 0 1 1 31.5 5.5zm301.5 13c-7.5-1.3-13.2-7.9-13.2-15.8c0-8.8 7.2-16 16-16c7.9 0 14.5 5.7 15.8 13.2l0 .1c.1 .9 .2 1.8 .2 2.7c0 8.8-7.2 16-16 16c-.9 0-1.9-.1-2.8-.2z" } }, "free": ["regular", "solid"] }, "octopus-deploy": { "changes": ["5.15.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e082", "label": "Octopus Deploy", "voted": false, "svg": { "brands": { "last_modified": 1660014464, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M455.6,349.2c-45.891-39.09-36.67-77.877-16.095-128.11C475.16,134.04,415.967,34.14,329.93,8.3,237.04-19.6,134.252,24.341,99.677,117.147a180.862,180.862,0,0,0-10.988,73.544c1.733,29.543,14.717,52.97,24.09,80.3,17.2,50.161-28.1,92.743-66.662,117.582-46.806,30.2-36.319,39.857-8.428,41.858,23.378,1.68,44.478-4.548,65.265-15.045,9.2-4.647,40.687-18.931,45.13-28.588C135.9,413.388,111.122,459.5,126.621,488.9c19.1,36.229,67.112-31.77,76.709-45.812,8.591-12.572,42.963-81.279,63.627-46.926,18.865,31.361,8.6,76.391,35.738,104.622,32.854,34.2,51.155-18.312,51.412-44.221.163-16.411-6.1-95.852,29.9-59.944C405.428,418,436.912,467.8,472.568,463.642c38.736-4.516-22.123-67.967-28.262-78.695,5.393,4.279,53.665,34.128,53.818,9.52C498.234,375.678,468.039,359.8,455.6,349.2Z" } }, "free": ["brands"] }, "odnoklassniki": { "changes": ["4.4.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f263", "label": "Odnoklassniki", "voted": false, "svg": { "brands": { "last_modified": 1660014471, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M275.1 334c-27.4 17.4-65.1 24.3-90 26.9l20.9 20.6 76.3 76.3c27.9 28.6-17.5 73.3-45.7 45.7-19.1-19.4-47.1-47.4-76.3-76.6L84 503.4c-28.2 27.5-73.6-17.6-45.4-45.7 19.4-19.4 47.1-47.4 76.3-76.3l20.6-20.6c-24.6-2.6-62.9-9.1-90.6-26.9-32.6-21-46.9-33.3-34.3-59 7.4-14.6 27.7-26.9 54.6-5.7 0 0 36.3 28.9 94.9 28.9s94.9-28.9 94.9-28.9c26.9-21.1 47.1-8.9 54.6 5.7 12.4 25.7-1.9 38-34.5 59.1zM30.3 129.7C30.3 58 88.6 0 160 0s129.7 58 129.7 129.7c0 71.4-58.3 129.4-129.7 129.4s-129.7-58-129.7-129.4zm66 0c0 35.1 28.6 63.7 63.7 63.7s63.7-28.6 63.7-63.7c0-35.4-28.6-64-63.7-64s-63.7 28.6-63.7 64z" } }, "free": ["brands"] }, "odysee": { "changes": ["6.2.1", "6.3.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e5c6", "label": "Odysee", "voted": false, "svg": { "brands": { "last_modified": 1667828915, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M406.7 463c-42.3 30.8-94.4 49-150.7 49C144.9 512 50.3 441.2 14.9 342.2c2.4 1.7 5.9 3.6 7.9 4.4c16.3 7.4 40.1-5.4 62.9-28.7c6.9-6.9 14.4-12.4 22.8-17.3c18.3-11.9 37.6-20.8 58.4-27.2c0 0 22.3 34.2 43.1 74.8s-22.3 54-27.2 54c-.3 0-.8 0-1.5-.1c-11-.5-70-3-56 51.1c14.9 57.4 97.5 36.6 139.6 8.9s31.7-118.3 31.7-118.3c41.1-6.4 54 37.1 57.9 59.4c.8 4.6 1.1 9.9 1.4 15.5c1.1 21.2 2.3 45.6 35.3 46.4c5.3 0 10.6-.8 15.5-2zm-95.3-23.7c-2-.5-3.5-2.5-3-5c1-2.5 3-3.5 5-3s3.5 3 3 5s-2.5 3.5-5 3zm-207-95.6c1.5-.5 3.5 1 4 3c0 2-1 4-3 4c-1.5 .5-3.5-1-4-3c-.5-1.5 1-3.5 3-4zM451.8 421C489.3 376.4 512 318.8 512 256c0-67.5-26.1-128.9-68.8-174.7c-.1 23.5-6.1 48.2-16.8 69.2c-11.9 20.3-49 58.9-69.8 78.7c-.7 .3-1.1 .9-1.5 1.4c-.2 .2-.3 .4-.5 .6c-5 6.9-4 16.8 3 21.8c21.3 15.8 56.4 45.6 59.4 72.8c3.5 34.9 27.9 75.6 34.2 86.2l0 0c.8 1.3 1.3 2.1 1.4 2.4c0 2.2-.4 4.3-.8 6.5zM390.7 251c-.5 3 1 5.9 4 6.4s5.9-1 6.4-4s-1-5.9-4-6.4c-3-1-5.9 1-6.4 4zm61.4-60.9l-11.4 5.4-3 12.9-5.4-11.4-12.9-3 11.4-5.4 3-12.9 5.4 11.4 12.9 3zM395.5 41.3c-16.2 8.2-22.1 32.8-29 61.4l0 0c-.3 1.4-.7 2.8-1 4.2c-9.5 38.5-30.6 37.6-41.7 37.2c-1.1 0-2-.1-2.9-.1c-5.1 0-6-4-8.9-17.1c-2.6-12.1-6.9-32-17.9-63.6C271.4-2.5 211.4 13.9 165.9 41.1C110.6 74.2 131.5 143 146.1 190.5c.7 2.2 1.4 4.4 2 6.6c-4 4-13.8 7.5-26 11.9c-12.1 4.3-26.6 9.5-40.3 16.9C47.9 243.9 11.5 274.9 2 288.5C.7 277.8 0 267 0 256C0 114.6 114.6 0 256 0c51.4 0 99.4 15.2 139.5 41.3zM58.9 189.6c-1.5-2-4.5-3-6.4-1.5s-3 4.5-1.5 6.4s4.5 3 6.4 1.5c2.5-1.5 3-4.5 1.5-6.4zM327.3 64.9c2-1.5 5-.5 6.4 1.5c1.5 2.5 1 5.4-1.5 6.4c-2 1.5-5 .5-6.4-1.5s-.5-5 1.5-6.4zM95.1 105c-.5 1.5 .5 3 2 3c1.5 .5 3-.5 3-2c.5-1.5-.5-3-2-3s-3 .5-3 2zm84.7-.5c-3.5-43.1 37.1-54 37.1-54c44.1-15.4 56 5.9 66.4 37.6s3 42.6-38.6 58.9s-61.9-4.5-64.9-42.6zm89.6 14.9h1c2.5 0 5-2 5-5c2-6.9 1-14.4-2-20.8c-1.5-2-4-3.5-6.4-2.5c-3 1-4.5 4-3.5 6.9c2 4.5 3 9.9 1.5 14.9c-.5 3 1.5 5.9 4.5 6.4zm-9.9-41.6c-2 0-4-1-5-3s-2-3.5-3-5c-2-2-2-5.4 0-7.4s5.4-2 7.4 0c2 2.5 3.5 5 5 7.4s.5 5.9-2.5 7.4c-.6 0-1 .2-1.3 .3c-.2 .1-.4 .2-.6 .2z" } }, "free": ["brands"] }, "oil-can": { "aliases": { "unicodes": { "secondary": ["10f613"] } }, "changes": [ "5.2.0", "5.10.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["auto", "crude", "gasoline", "grease", "lubricate", "petroleum"] }, "styles": ["solid"], "unicode": "f613", "label": "Oil Can", "voted": false, "svg": { "solid": { "last_modified": 1684767488, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M320 128c17.7 0 32-14.3 32-32s-14.3-32-32-32H192c-17.7 0-32 14.3-32 32s14.3 32 32 32h32v32H144 96 48c-26.5 0-48 21.5-48 48v64.8c0 19 11.2 36.2 28.5 43.9l67.5 30V368c0 26.5 21.5 48 48 48H403.1c18.4 0 35.8-7.9 48-21.7L633.5 187.7c12.3-13.9-.3-35.4-18.4-31.5L448 192l-50.5-25.2c-8.9-4.4-18.7-6.8-28.6-6.8H288V128h32zM96 208v86.1L48 272.8V208H96z" } }, "free": ["solid"] }, "oil-well": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["drill", "oil", "rig"] }, "styles": ["solid"], "unicode": "e532", "label": "Oil Well", "voted": false, "svg": { "solid": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M528.3 61.3c-11.4-42.7-55.3-68-98-56.6L414.9 8.8C397.8 13.4 387.7 31 392.3 48l24.5 91.4L308.5 167.5l-6.3-18.1C297.7 136.6 285.6 128 272 128s-25.7 8.6-30.2 21.4l-13.6 39L96 222.6V184c0-13.3-10.7-24-24-24s-24 10.7-24 24V448H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H544c17.7 0 32-14.3 32-32s-14.3-32-32-32H406.7L340 257.5l-62.2 16.1L305.3 352H238.7L265 277l-74.6 19.3L137.3 448H96V288.8l337.4-87.5 25.2 94c4.6 17.1 22.1 27.2 39.2 22.6l15.5-4.1c42.7-11.4 68-55.3 56.6-98L528.3 61.3zM205.1 448l11.2-32H327.7l11.2 32H205.1z" } }, "free": ["solid"] }, "old-republic": { "changes": ["5.0.12"], "ligatures": [], "search": { "terms": ["politics", "star wars"] }, "styles": ["brands"], "unicode": "f510", "label": "Old Republic", "voted": false, "svg": { "brands": { "last_modified": 1660014460, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M235.76 10.23c7.5-.31 15-.28 22.5-.09 3.61.14 7.2.4 10.79.73 4.92.27 9.79 1.03 14.67 1.62 2.93.43 5.83.98 8.75 1.46 7.9 1.33 15.67 3.28 23.39 5.4 12.24 3.47 24.19 7.92 35.76 13.21 26.56 12.24 50.94 29.21 71.63 49.88 20.03 20.09 36.72 43.55 48.89 69.19 1.13 2.59 2.44 5.1 3.47 7.74 2.81 6.43 5.39 12.97 7.58 19.63 4.14 12.33 7.34 24.99 9.42 37.83.57 3.14 1.04 6.3 1.4 9.47.55 3.83.94 7.69 1.18 11.56.83 8.34.84 16.73.77 25.1-.07 4.97-.26 9.94-.75 14.89-.24 3.38-.51 6.76-.98 10.12-.39 2.72-.63 5.46-1.11 8.17-.9 5.15-1.7 10.31-2.87 15.41-4.1 18.5-10.3 36.55-18.51 53.63-15.77 32.83-38.83 62.17-67.12 85.12a246.503 246.503 0 0 1-56.91 34.86c-6.21 2.68-12.46 5.25-18.87 7.41-3.51 1.16-7.01 2.38-10.57 3.39-6.62 1.88-13.29 3.64-20.04 5-4.66.91-9.34 1.73-14.03 2.48-5.25.66-10.5 1.44-15.79 1.74-6.69.66-13.41.84-20.12.81-6.82.03-13.65-.12-20.45-.79-3.29-.23-6.57-.5-9.83-.95-2.72-.39-5.46-.63-8.17-1.11-4.12-.72-8.25-1.37-12.35-2.22-4.25-.94-8.49-1.89-12.69-3.02-8.63-2.17-17.08-5.01-25.41-8.13-10.49-4.12-20.79-8.75-30.64-14.25-2.14-1.15-4.28-2.29-6.35-3.57-11.22-6.58-21.86-14.1-31.92-22.34-34.68-28.41-61.41-66.43-76.35-108.7-3.09-8.74-5.71-17.65-7.8-26.68-1.48-6.16-2.52-12.42-3.58-18.66-.4-2.35-.61-4.73-.95-7.09-.6-3.96-.75-7.96-1.17-11.94-.8-9.47-.71-18.99-.51-28.49.14-3.51.34-7.01.7-10.51.31-3.17.46-6.37.92-9.52.41-2.81.65-5.65 1.16-8.44.7-3.94 1.3-7.9 2.12-11.82 3.43-16.52 8.47-32.73 15.26-48.18 1.15-2.92 2.59-5.72 3.86-8.59 8.05-16.71 17.9-32.56 29.49-47.06 20-25.38 45.1-46.68 73.27-62.47 7.5-4.15 15.16-8.05 23.07-11.37 15.82-6.88 32.41-11.95 49.31-15.38 3.51-.67 7.04-1.24 10.56-1.85 2.62-.47 5.28-.7 7.91-1.08 3.53-.53 7.1-.68 10.65-1.04 2.46-.24 4.91-.36 7.36-.51m8.64 24.41c-9.23.1-18.43.99-27.57 2.23-7.3 1.08-14.53 2.6-21.71 4.3-13.91 3.5-27.48 8.34-40.46 14.42-10.46 4.99-20.59 10.7-30.18 17.22-4.18 2.92-8.4 5.8-12.34 9.03-5.08 3.97-9.98 8.17-14.68 12.59-2.51 2.24-4.81 4.7-7.22 7.06-28.22 28.79-48.44 65.39-57.5 104.69-2.04 8.44-3.54 17.02-4.44 25.65-1.1 8.89-1.44 17.85-1.41 26.8.11 7.14.38 14.28 1.22 21.37.62 7.12 1.87 14.16 3.2 21.18 1.07 4.65 2.03 9.32 3.33 13.91 6.29 23.38 16.5 45.7 30.07 65.75 8.64 12.98 18.78 24.93 29.98 35.77 16.28 15.82 35.05 29.04 55.34 39.22 7.28 3.52 14.66 6.87 22.27 9.63 5.04 1.76 10.06 3.57 15.22 4.98 11.26 3.23 22.77 5.6 34.39 7.06 2.91.29 5.81.61 8.72.9 13.82 1.08 27.74 1 41.54-.43 4.45-.6 8.92-.99 13.35-1.78 3.63-.67 7.28-1.25 10.87-2.1 4.13-.98 8.28-1.91 12.36-3.07 26.5-7.34 51.58-19.71 73.58-36.2 15.78-11.82 29.96-25.76 42.12-41.28 3.26-4.02 6.17-8.31 9.13-12.55 3.39-5.06 6.58-10.25 9.6-15.54 2.4-4.44 4.74-8.91 6.95-13.45 5.69-12.05 10.28-24.62 13.75-37.49 2.59-10.01 4.75-20.16 5.9-30.45 1.77-13.47 1.94-27.1 1.29-40.65-.29-3.89-.67-7.77-1-11.66-2.23-19.08-6.79-37.91-13.82-55.8-5.95-15.13-13.53-29.63-22.61-43.13-12.69-18.8-28.24-35.68-45.97-49.83-25.05-20-54.47-34.55-85.65-42.08-7.78-1.93-15.69-3.34-23.63-4.45-3.91-.59-7.85-.82-11.77-1.24-7.39-.57-14.81-.72-22.22-.58zM139.26 83.53c13.3-8.89 28.08-15.38 43.3-20.18-3.17 1.77-6.44 3.38-9.53 5.29-11.21 6.68-21.52 14.9-30.38 24.49-6.8 7.43-12.76 15.73-17.01 24.89-3.29 6.86-5.64 14.19-6.86 21.71-.93 4.85-1.3 9.81-1.17 14.75.13 13.66 4.44 27.08 11.29 38.82 5.92 10.22 13.63 19.33 22.36 27.26 4.85 4.36 10.24 8.09 14.95 12.6 2.26 2.19 4.49 4.42 6.43 6.91 2.62 3.31 4.89 6.99 5.99 11.1.9 3.02.66 6.2.69 9.31.02 4.1-.04 8.2.03 12.3.14 3.54-.02 7.09.11 10.63.08 2.38.02 4.76.05 7.14.16 5.77.06 11.53.15 17.3.11 2.91.02 5.82.13 8.74.03 1.63.13 3.28-.03 4.91-.91.12-1.82.18-2.73.16-10.99 0-21.88-2.63-31.95-6.93-6-2.7-11.81-5.89-17.09-9.83-5.75-4.19-11.09-8.96-15.79-14.31-6.53-7.24-11.98-15.39-16.62-23.95-1.07-2.03-2.24-4.02-3.18-6.12-1.16-2.64-2.62-5.14-3.67-7.82-4.05-9.68-6.57-19.94-8.08-30.31-.49-4.44-1.09-8.88-1.2-13.35-.7-15.73.84-31.55 4.67-46.82 2.12-8.15 4.77-16.18 8.31-23.83 6.32-14.2 15.34-27.18 26.3-38.19 6.28-6.2 13.13-11.84 20.53-16.67zm175.37-20.12c2.74.74 5.41 1.74 8.09 2.68 6.36 2.33 12.68 4.84 18.71 7.96 13.11 6.44 25.31 14.81 35.82 24.97 10.2 9.95 18.74 21.6 25.14 34.34 1.28 2.75 2.64 5.46 3.81 8.26 6.31 15.1 10 31.26 11.23 47.57.41 4.54.44 9.09.45 13.64.07 11.64-1.49 23.25-4.3 34.53-1.97 7.27-4.35 14.49-7.86 21.18-3.18 6.64-6.68 13.16-10.84 19.24-6.94 10.47-15.6 19.87-25.82 27.22-10.48 7.64-22.64 13.02-35.4 15.38-3.51.69-7.08 1.08-10.66 1.21-1.85.06-3.72.16-5.56-.1-.28-2.15 0-4.31-.01-6.46-.03-3.73.14-7.45.1-11.17.19-7.02.02-14.05.21-21.07.03-2.38-.03-4.76.03-7.14.17-5.07-.04-10.14.14-15.21.1-2.99-.24-6.04.51-8.96.66-2.5 1.78-4.86 3.09-7.08 4.46-7.31 11.06-12.96 17.68-18.26 5.38-4.18 10.47-8.77 15.02-13.84 7.68-8.37 14.17-17.88 18.78-28.27 2.5-5.93 4.52-12.1 5.55-18.46.86-4.37 1.06-8.83 1.01-13.27-.02-7.85-1.4-15.65-3.64-23.17-1.75-5.73-4.27-11.18-7.09-16.45-3.87-6.93-8.65-13.31-13.96-19.2-9.94-10.85-21.75-19.94-34.6-27.1-1.85-1.02-3.84-1.82-5.63-2.97zm-100.8 58.45c.98-1.18 1.99-2.33 3.12-3.38-.61.93-1.27 1.81-1.95 2.68-3.1 3.88-5.54 8.31-7.03 13.06-.87 3.27-1.68 6.6-1.73 10-.07 2.52-.08 5.07.32 7.57 1.13 7.63 4.33 14.85 8.77 21.12 2 2.7 4.25 5.27 6.92 7.33 1.62 1.27 3.53 2.09 5.34 3.05 3.11 1.68 6.32 3.23 9.07 5.48 2.67 2.09 4.55 5.33 4.4 8.79-.01 73.67 0 147.34-.01 221.02 0 1.35-.08 2.7.04 4.04.13 1.48.82 2.83 1.47 4.15.86 1.66 1.78 3.34 3.18 4.62.85.77 1.97 1.4 3.15 1.24 1.5-.2 2.66-1.35 3.45-2.57.96-1.51 1.68-3.16 2.28-4.85.76-2.13.44-4.42.54-6.63.14-4.03-.02-8.06.14-12.09.03-5.89.03-11.77.06-17.66.14-3.62.03-7.24.11-10.86.15-4.03-.02-8.06.14-12.09.03-5.99.03-11.98.07-17.97.14-3.62.02-7.24.11-10.86.14-3.93-.02-7.86.14-11.78.03-5.99.03-11.98.06-17.97.16-3.94-.01-7.88.19-11.82.29 1.44.13 2.92.22 4.38.19 3.61.42 7.23.76 10.84.32 3.44.44 6.89.86 10.32.37 3.1.51 6.22.95 9.31.57 4.09.87 8.21 1.54 12.29 1.46 9.04 2.83 18.11 5.09 26.99 1.13 4.82 2.4 9.61 4 14.3 2.54 7.9 5.72 15.67 10.31 22.62 1.73 2.64 3.87 4.98 6.1 7.21.27.25.55.51.88.71.6.25 1.31-.07 1.7-.57.71-.88 1.17-1.94 1.7-2.93 4.05-7.8 8.18-15.56 12.34-23.31.7-1.31 1.44-2.62 2.56-3.61 1.75-1.57 3.84-2.69 5.98-3.63 2.88-1.22 5.9-2.19 9.03-2.42 6.58-.62 13.11.75 19.56 1.85 3.69.58 7.4 1.17 11.13 1.41 3.74.1 7.48.05 11.21-.28 8.55-.92 16.99-2.96 24.94-6.25 5.3-2.24 10.46-4.83 15.31-7.93 11.46-7.21 21.46-16.57 30.04-27.01 1.17-1.42 2.25-2.9 3.46-4.28-1.2 3.24-2.67 6.37-4.16 9.48-1.25 2.9-2.84 5.61-4.27 8.42-5.16 9.63-11.02 18.91-17.75 27.52-4.03 5.21-8.53 10.05-13.33 14.57-6.64 6.05-14.07 11.37-22.43 14.76-8.21 3.37-17.31 4.63-26.09 3.29-3.56-.58-7.01-1.69-10.41-2.88-2.79-.97-5.39-2.38-8.03-3.69-3.43-1.71-6.64-3.81-9.71-6.08 2.71 3.06 5.69 5.86 8.7 8.61 4.27 3.76 8.74 7.31 13.63 10.23 3.98 2.45 8.29 4.4 12.84 5.51 1.46.37 2.96.46 4.45.6-1.25 1.1-2.63 2.04-3.99 2.98-9.61 6.54-20.01 11.86-30.69 16.43-20.86 8.7-43.17 13.97-65.74 15.34-4.66.24-9.32.36-13.98.36-4.98-.11-9.97-.13-14.92-.65-11.2-.76-22.29-2.73-33.17-5.43-10.35-2.71-20.55-6.12-30.3-10.55-8.71-3.86-17.12-8.42-24.99-13.79-1.83-1.31-3.74-2.53-5.37-4.08 6.6-1.19 13.03-3.39 18.99-6.48 5.74-2.86 10.99-6.66 15.63-11.07 2.24-2.19 4.29-4.59 6.19-7.09-3.43 2.13-6.93 4.15-10.62 5.78-4.41 2.16-9.07 3.77-13.81 5.02-5.73 1.52-11.74 1.73-17.61 1.14-8.13-.95-15.86-4.27-22.51-8.98-4.32-2.94-8.22-6.43-11.96-10.06-9.93-10.16-18.2-21.81-25.66-33.86-3.94-6.27-7.53-12.75-11.12-19.22-1.05-2.04-2.15-4.05-3.18-6.1 2.85 2.92 5.57 5.97 8.43 8.88 8.99 8.97 18.56 17.44 29.16 24.48 7.55 4.9 15.67 9.23 24.56 11.03 3.11.73 6.32.47 9.47.81 2.77.28 5.56.2 8.34.3 5.05.06 10.11.04 15.16-.16 3.65-.16 7.27-.66 10.89-1.09 2.07-.25 4.11-.71 6.14-1.2 3.88-.95 8.11-.96 11.83.61 4.76 1.85 8.44 5.64 11.38 9.71 2.16 3.02 4.06 6.22 5.66 9.58 1.16 2.43 2.46 4.79 3.55 7.26 1 2.24 2.15 4.42 3.42 6.52.67 1.02 1.4 2.15 2.62 2.55 1.06-.75 1.71-1.91 2.28-3.03 2.1-4.16 3.42-8.65 4.89-13.05 2.02-6.59 3.78-13.27 5.19-20.02 2.21-9.25 3.25-18.72 4.54-28.13.56-3.98.83-7.99 1.31-11.97.87-10.64 1.9-21.27 2.24-31.94.08-1.86.24-3.71.25-5.57.01-4.35.25-8.69.22-13.03-.01-2.38-.01-4.76 0-7.13.05-5.07-.2-10.14-.22-15.21-.2-6.61-.71-13.2-1.29-19.78-.73-5.88-1.55-11.78-3.12-17.51-2.05-7.75-5.59-15.03-9.8-21.82-3.16-5.07-6.79-9.88-11.09-14.03-3.88-3.86-8.58-7.08-13.94-8.45-1.5-.41-3.06-.45-4.59-.64.07-2.99.7-5.93 1.26-8.85 1.59-7.71 3.8-15.3 6.76-22.6 1.52-4.03 3.41-7.9 5.39-11.72 3.45-6.56 7.62-12.79 12.46-18.46zm31.27 1.7c.35-.06.71-.12 1.07-.19.19 1.79.09 3.58.1 5.37v38.13c-.01 1.74.13 3.49-.15 5.22-.36-.03-.71-.05-1.06-.05-.95-3.75-1.72-7.55-2.62-11.31-.38-1.53-.58-3.09-1.07-4.59-1.7-.24-3.43-.17-5.15-.2-5.06-.01-10.13 0-15.19-.01-1.66-.01-3.32.09-4.98-.03-.03-.39-.26-.91.16-1.18 1.28-.65 2.72-.88 4.06-1.35 3.43-1.14 6.88-2.16 10.31-3.31 1.39-.48 2.9-.72 4.16-1.54.04-.56.02-1.13-.05-1.68-1.23-.55-2.53-.87-3.81-1.28-3.13-1.03-6.29-1.96-9.41-3.02-1.79-.62-3.67-1-5.41-1.79-.03-.37-.07-.73-.11-1.09 5.09-.19 10.2.06 15.3-.12 3.36-.13 6.73.08 10.09-.07.12-.39.26-.77.37-1.16 1.08-4.94 2.33-9.83 3.39-14.75zm5.97-.2c.36.05.72.12 1.08.2.98 3.85 1.73 7.76 2.71 11.61.36 1.42.56 2.88 1.03 4.27 2.53.18 5.07-.01 7.61.05 5.16.12 10.33.12 15.49.07.76-.01 1.52.03 2.28.08-.04.36-.07.72-.1 1.08-1.82.83-3.78 1.25-5.67 1.89-3.73 1.23-7.48 2.39-11.22 3.57-.57.17-1.12.42-1.67.64-.15.55-.18 1.12-.12 1.69.87.48 1.82.81 2.77 1.09 4.88 1.52 9.73 3.14 14.63 4.6.38.13.78.27 1.13.49.4.27.23.79.15 1.18-1.66.13-3.31.03-4.97.04-5.17.01-10.33-.01-15.5.01-1.61.03-3.22-.02-4.82.21-.52 1.67-.72 3.42-1.17 5.11-.94 3.57-1.52 7.24-2.54 10.78-.36.01-.71.02-1.06.06-.29-1.73-.15-3.48-.15-5.22v-38.13c.02-1.78-.08-3.58.11-5.37zM65.05 168.33c1.12-2.15 2.08-4.4 3.37-6.46-1.82 7.56-2.91 15.27-3.62 23-.8 7.71-.85 15.49-.54 23.23 1.05 19.94 5.54 39.83 14.23 57.88 2.99 5.99 6.35 11.83 10.5 17.11 6.12 7.47 12.53 14.76 19.84 21.09 4.8 4.1 9.99 7.78 15.54 10.8 3.27 1.65 6.51 3.39 9.94 4.68 5.01 2.03 10.19 3.61 15.42 4.94 3.83.96 7.78 1.41 11.52 2.71 5 1.57 9.47 4.61 13.03 8.43 4.93 5.23 8.09 11.87 10.2 18.67.99 2.9 1.59 5.91 2.17 8.92.15.75.22 1.52.16 2.29-6.5 2.78-13.26 5.06-20.26 6.18-4.11.78-8.29.99-12.46 1.08-10.25.24-20.47-1.76-30.12-5.12-3.74-1.42-7.49-2.85-11.03-4.72-8.06-3.84-15.64-8.7-22.46-14.46-2.92-2.55-5.83-5.13-8.4-8.03-9.16-9.83-16.3-21.41-21.79-33.65-2.39-5.55-4.61-11.18-6.37-16.96-1.17-3.94-2.36-7.89-3.26-11.91-.75-2.94-1.22-5.95-1.87-8.92-.46-2.14-.69-4.32-1.03-6.48-.85-5.43-1.28-10.93-1.33-16.43.11-6.18.25-12.37 1.07-18.5.4-2.86.67-5.74 1.15-8.6.98-5.7 2.14-11.37 3.71-16.93 3.09-11.65 7.48-22.95 12.69-33.84zm363.73-6.44c1.1 1.66 1.91 3.48 2.78 5.26 2.1 4.45 4.24 8.9 6.02 13.49 7.61 18.76 12.3 38.79 13.04 59.05.02 1.76.07 3.52.11 5.29.13 9.57-1.27 19.09-3.18 28.45-.73 3.59-1.54 7.17-2.58 10.69-4.04 14.72-10 29-18.41 41.78-8.21 12.57-19.01 23.55-31.84 31.41-5.73 3.59-11.79 6.64-18.05 9.19-5.78 2.19-11.71 4.03-17.8 5.11-6.4 1.05-12.91 1.52-19.4 1.23-7.92-.48-15.78-2.07-23.21-4.85-1.94-.8-3.94-1.46-5.84-2.33-.21-1.51.25-2.99.53-4.46 1.16-5.74 3.03-11.36 5.7-16.58 2.37-4.51 5.52-8.65 9.46-11.9 2.43-2.05 5.24-3.61 8.16-4.83 3.58-1.5 7.47-1.97 11.24-2.83 7.23-1.71 14.37-3.93 21.15-7 10.35-4.65 19.71-11.38 27.65-19.46 1.59-1.61 3.23-3.18 4.74-4.87 3.37-3.76 6.71-7.57 9.85-11.53 7.48-10.07 12.82-21.59 16.71-33.48 1.58-5.3 3.21-10.6 4.21-16.05.63-2.87 1.04-5.78 1.52-8.68.87-6.09 1.59-12.22 1.68-18.38.12-6.65.14-13.32-.53-19.94-.73-7.99-1.87-15.96-3.71-23.78z" } }, "free": ["brands"] }, "om": { "aliases": { "unicodes": { "composite": ["1f549"], "secondary": ["10f679"] } }, "changes": ["5.3.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "Hindu", "buddhism", "hinduism", "jainism", "mantra", "om", "religion" ] }, "styles": ["solid"], "unicode": "f679", "label": "Om", "voted": false, "svg": { "solid": { "last_modified": 1684767603, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M379.3 4.7c-6.2-6.2-16.4-6.2-22.6 0l-16 16c-6.2 6.2-6.2 16.4 0 22.6l16 16c6.2 6.2 16.4 6.2 22.6 0l16-16c6.2-6.2 6.2-16.4 0-22.6l-16-16zM115.2 169.6c8-6 17.9-9.6 28.8-9.6c26.5 0 48 21.5 48 48s-21.5 48-48 48H109.8c-7.6 0-13.8 6.2-13.8 13.8c0 1.5 .2 2.9 .7 4.4l8 24c4.4 13.1 16.6 21.9 30.4 21.9H144h16c35.3 0 64 28.7 64 64s-28.7 64-64 64c-50.8 0-82.7-21.5-102.2-42.8c-9.9-10.8-16.6-21.6-20.9-29.7c-2.1-4-3.6-7.3-4.5-9.6c-.5-1.1-.8-2-1-2.5l-.2-.5 0-.1c-2.6-7.8-10.7-12.3-18.7-10.5C4.4 354.2-.9 361.8 .1 370L16 368C.1 370 .1 370 .1 370l0 0 0 0 0 .1 .1 .4c0 .3 .1 .8 .2 1.3c.2 1.1 .4 2.7 .8 4.6c.8 3.9 2 9.4 3.9 15.9c3.8 13 10.3 30.4 21.3 48C48.7 476.2 89.4 512 160 512c70.7 0 128-57.3 128-128c0-23.3-6.2-45.2-17.1-64h22.6c25.5 0 49.9-10.1 67.9-28.1l26.5-26.5c6-6 14.1-9.4 22.6-9.4H416c17.7 0 32 14.3 32 32v96c0 17.7-14.3 32-32 32c-25.7 0-41.4-12.5-51.2-25.6c-5-6.7-8.4-13.4-10.5-18.6c-1.1-2.5-1.8-4.6-2.2-6c-.2-.7-.4-1.2-.5-1.5l-.1-.3 0 0c0 0 0 0 0 0c-1.9-7.3-8.6-12.4-16.2-12.1c-7.6 .3-13.9 5.9-15.1 13.4L336 368c-15.8-2.6-15.8-2.6-15.8-2.6l0 0 0 0 0 .1-.1 .3c0 .3-.1 .6-.2 1.1c-.1 .9-.3 2.1-.4 3.6c-.3 3-.6 7.3-.6 12.4c0 10.1 1.1 23.9 5.8 38.1c4.8 14.3 13.4 29.3 28.6 40.7C368.7 473.3 389.3 480 416 480c53 0 96-43 96-96V288c0-53-43-96-96-96h-5.5c-25.5 0-49.9 10.1-67.9 28.1l-26.5 26.5c-6 6-14.1 9.4-22.6 9.4H245.2c6.9-14.5 10.8-30.8 10.8-48c0-61.9-50.1-112-112-112c-25.2 0-48.5 8.3-67.2 22.4c-14.1 10.6-17 30.7-6.4 44.8s30.7 17 44.8 6.4zM280.9 66.7c-6-4-14-3.5-19.5 1.3s-7 12.7-3.7 19.2L272 80c-14.3 7.2-14.3 7.2-14.3 7.2l0 0 0 0 0 .1 .1 .2 .4 .7c.3 .6 .8 1.4 1.4 2.4c1.2 2 2.9 4.8 5.1 8.2c4.4 6.7 11.1 15.5 20 24.4C302.4 141.1 330.3 160 368 160c31.2 0 56.6-10.4 73.9-20.2c8.7-5 15.6-9.9 20.4-13.8c2.4-1.9 4.3-3.6 5.7-4.9c.7-.6 1.3-1.2 1.7-1.6l.6-.5 .2-.2 .1-.1 0 0 0 0c0 0 0 0-22.6-22.6l22.6 22.6c12.5-12.5 12.5-32.8 0-45.3c-12.4-12.4-32.6-12.5-45.1-.2c-.1 .1-.2 .2-.5 .4c-.5 .5-1.5 1.3-2.8 2.4c-2.7 2.2-6.8 5.2-12.1 8.2C399.4 90.4 384.8 96 368 96c-20.8 0-42.4-7-59.5-14.6c-8.4-3.7-15.4-7.5-20.3-10.3c-2.4-1.4-4.3-2.5-5.6-3.3c-.6-.4-1.1-.7-1.4-.9l-.3-.2 0 0 0 0 0 0z" } }, "free": ["solid"] }, "opencart": { "changes": ["4.4.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f23d", "label": "OpenCart", "voted": false, "svg": { "brands": { "last_modified": 1660014471, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M423.3 440.7c0 25.3-20.3 45.6-45.6 45.6s-45.8-20.3-45.8-45.6 20.6-45.8 45.8-45.8c25.4 0 45.6 20.5 45.6 45.8zm-253.9-45.8c-25.3 0-45.6 20.6-45.6 45.8s20.3 45.6 45.6 45.6 45.8-20.3 45.8-45.6-20.5-45.8-45.8-45.8zm291.7-270C158.9 124.9 81.9 112.1 0 25.7c34.4 51.7 53.3 148.9 373.1 144.2 333.3-5 130 86.1 70.8 188.9 186.7-166.7 319.4-233.9 17.2-233.9z" } }, "free": ["brands"] }, "openid": { "changes": ["4.1.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f19b", "label": "OpenID", "voted": false, "svg": { "brands": { "last_modified": 1660014477, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M271.5 432l-68 32C88.5 453.7 0 392.5 0 318.2c0-71.5 82.5-131 191.7-144.3v43c-71.5 12.5-124 53-124 101.3 0 51 58.5 93.3 135.7 103v-340l68-33.2v384zM448 291l-131.3-28.5 36.8-20.7c-19.5-11.5-43.5-20-70-24.8v-43c46.2 5.5 87.7 19.5 120.3 39.3l35-19.8L448 291z" } }, "free": ["brands"] }, "opera": { "changes": ["4.4.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f26a", "label": "Opera", "voted": false, "svg": { "brands": { "last_modified": 1660014472, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M313.9 32.7c-170.2 0-252.6 223.8-147.5 355.1 36.5 45.4 88.6 75.6 147.5 75.6 36.3 0 70.3-11.1 99.4-30.4-43.8 39.2-101.9 63-165.3 63-3.9 0-8 0-11.9-.3C104.6 489.6 0 381.1 0 248 0 111 111 0 248 0h.8c63.1.3 120.7 24.1 164.4 63.1-29-19.4-63.1-30.4-99.3-30.4zm101.8 397.7c-40.9 24.7-90.7 23.6-132-5.8 56.2-20.5 97.7-91.6 97.7-176.6 0-84.7-41.2-155.8-97.4-176.6 41.8-29.2 91.2-30.3 132.9-5 105.9 98.7 105.5 265.7-1.2 364z" } }, "free": ["brands"] }, "optin-monster": { "changes": ["4.4.0", "5.0.0", "5.7.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f23c", "label": "Optin Monster", "voted": false, "svg": { "brands": { "last_modified": 1660014469, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M572.6 421.4c5.6-9.5 4.7-15.2-5.4-11.6-3-4.9-7-9.5-11.1-13.8 2.9-9.7-.7-14.2-10.8-9.2-4.6-3.2-10.3-6.5-15.9-9.2 0-15.1-11.6-11.6-17.6-5.7-10.4-1.5-18.7-.3-26.8 5.7.3-6.5.3-13 .3-19.7 12.6 0 40.2-11 45.9-36.2 1.4-6.8 1.6-13.8-.3-21.9-3-13.5-14.3-21.3-25.1-25.7-.8-5.9-7.6-14.3-14.9-15.9s-12.4 4.9-14.1 10.3c-8.5 0-19.2 2.8-21.1 8.4-5.4-.5-11.1-1.4-16.8-1.9 2.7-1.9 5.4-3.5 8.4-4.6 5.4-9.2 14.6-11.4 25.7-11.6V256c19.5-.5 43-5.9 53.8-18.1 12.7-13.8 14.6-37.3 12.4-55.1-2.4-17.3-9.7-37.6-24.6-48.1-8.4-5.9-21.6-.8-22.7 9.5-2.2 19.6 1.2 30-38.6 25.1-10.3-23.8-24.6-44.6-42.7-60C341 49.6 242.9 55.5 166.4 71.7c19.7 4.6 41.1 8.6 59.7 16.5-26.2 2.4-52.7 11.3-76.2 23.2-32.8 17-44 29.9-56.7 42.4 14.9-2.2 28.9-5.1 43.8-3.8-9.7 5.4-18.4 12.2-26.5 20-25.8.9-23.8-5.3-26.2-25.9-1.1-10.5-14.3-15.4-22.7-9.7-28.1 19.9-33.5 79.9-12.2 103.5 10.8 12.2 35.1 17.3 54.9 17.8-.3 1.1-.3 1.9-.3 2.7 10.8.5 19.5 2.7 24.6 11.6 3 1.1 5.7 2.7 8.1 4.6-5.4.5-11.1 1.4-16.5 1.9-3.3-6.6-13.7-8.1-21.1-8.1-1.6-5.7-6.5-12.2-14.1-10.3-6.8 1.9-14.1 10-14.9 15.9-22.5 9.5-30.1 26.8-25.1 47.6 5.3 24.8 33 36.2 45.9 36.2v19.7c-6.6-5-14.3-7.5-26.8-5.7-5.5-5.5-17.3-10.1-17.3 5.7-5.9 2.7-11.4 5.9-15.9 9.2-9.8-4.9-13.6-1.7-11.1 9.2-4.1 4.3-7.8 8.6-11.1 13.8-10.2-3.7-11 2.2-5.4 11.6-1.1 3.5-1.6 7-1.9 10.8-.5 31.6 44.6 64 73.5 65.1 17.3.5 34.6-8.4 43-23.5 113.2 4.9 226.7 4.1 340.2 0 8.1 15.1 25.4 24.3 42.7 23.5 29.2-1.1 74.3-33.5 73.5-65.1.2-3.7-.7-7.2-1.7-10.7zm-73.8-254c1.1-3 2.4-8.4 2.4-14.6 0-5.9 6.8-8.1 14.1-.8 11.1 11.6 14.9 40.5 13.8 51.1-4.1-13.6-13-29-30.3-35.7zm-4.6 6.7c19.5 6.2 28.6 27.6 29.7 48.9-1.1 2.7-3 5.4-4.9 7.6-5.7 5.9-15.4 10-26.2 12.2 4.3-21.3.3-47.3-12.7-63 4.9-.8 10.9-2.4 14.1-5.7zm-24.1 6.8c13.8 11.9 20 39.2 14.1 63.5-4.1.5-8.1.8-11.6.8-1.9-21.9-6.8-44-14.3-64.6 3.7.3 8.1.3 11.8.3zM47.5 203c-1.1-10.5 2.4-39.5 13.8-51.1 7-7.3 14.1-5.1 14.1.8 0 6.2 1.4 11.6 2.4 14.6-17.3 6.8-26.2 22.2-30.3 35.7zm9.7 27.6c-1.9-2.2-3.5-4.9-4.9-7.6 1.4-21.3 10.3-42.7 29.7-48.9 3.2 3.2 9.2 4.9 14.1 5.7-13 15.7-17 41.6-12.7 63-10.8-2.2-20.5-6-26.2-12.2zm47.9 14.6c-4.1 0-8.1-.3-12.7-.8-4.6-18.6-1.9-38.9 5.4-53v.3l12.2-5.1c4.9-1.9 9.7-3.8 14.9-4.9-10.7 19.7-17.4 41.3-19.8 63.5zm184-162.7c41.9 0 76.2 34 76.2 75.9 0 42.2-34.3 76.2-76.2 76.2s-76.2-34-76.2-76.2c0-41.8 34.3-75.9 76.2-75.9zm115.6 174.3c-.3 17.8-7 48.9-23 57-13.2 6.6-6.5-7.5-16.5-58.1 13.3.3 26.6.3 39.5 1.1zm-54-1.6c.8 4.9 3.8 40.3-1.6 41.9-11.6 3.5-40 4.3-51.1-1.1-4.1-3-4.6-35.9-4.3-41.1v.3c18.9-.3 38.1-.3 57 0zM278.3 309c-13 3.5-41.6 4.1-54.6-1.6-6.5-2.7-3.8-42.4-1.9-51.6 19.2-.5 38.4-.5 57.8-.8v.3c1.1 8.3 3.3 51.2-1.3 53.7zm-106.5-51.1c12.2-.8 24.6-1.4 36.8-1.6-2.4 15.4-3 43.5-4.9 52.2-1.1 6.8-4.3 6.8-9.7 4.3-21.9-9.8-27.6-35.2-22.2-54.9zm-35.4 31.3c7.8-1.1 15.7-1.9 23.5-2.7 1.6 6.2 3.8 11.9 7 17.6 10 17 44 35.7 45.1 7 6.2 14.9 40.8 12.2 54.9 10.8 15.7-1.4 23.8-1.4 26.8-14.3 12.4 4.3 30.8 4.1 44 3 11.3-.8 20.8-.5 24.6-8.9 1.1 5.1 1.9 11.6 4.6 16.8 10.8 21.3 37.3 1.4 46.8-31.6 8.6.8 17.6 1.9 26.5 2.7-.4 1.3-3.8 7.3 7.3 11.6-47.6 47-95.7 87.8-163.2 107-63.2-20.8-112.1-59.5-155.9-106.5 9.6-3.4 10.4-8.8 8-12.5zm-21.6 172.5c-3.8 17.8-21.9 29.7-39.7 28.9-19.2-.8-46.5-17-59.2-36.5-2.7-31.1 43.8-61.3 66.2-54.6 14.9 4.3 27.8 30.8 33.5 54 0 3-.3 5.7-.8 8.2zm-8.7-66c-.5-13.5-.5-27-.3-40.5h.3c2.7-1.6 5.7-3.8 7.8-6.5 6.5-1.6 13-5.1 15.1-9.2 3.3-7.1-7-7.5-5.4-12.4 2.7-1.1 5.7-2.2 7.8-3.5 29.2 29.2 58.6 56.5 97.3 77-36.8 11.3-72.4 27.6-105.9 47-1.2-18.6-7.7-35.9-16.7-51.9zm337.6 64.6c-103 3.5-206.2 4.1-309.4 0 0 .3 0 .3-.3.3v-.3h.3c35.1-21.6 72.2-39.2 112.4-50.8 11.6 5.1 23 9.5 34.9 13.2 2.2.8 2.2.8 4.3 0 14.3-4.1 28.4-9.2 42.2-15.4 41.5 11.7 78.8 31.7 115.6 53zm10.5-12.4c-35.9-19.5-73-35.9-111.9-47.6 38.1-20 71.9-47.3 103.5-76.7 2.2 1.4 4.6 2.4 7.6 3.2 0 .8.3 1.9.5 2.4-4.6 2.7-7.8 6.2-5.9 10.3 2.2 3.8 8.6 7.6 15.1 8.9 2.4 2.7 5.1 5.1 8.1 6.8 0 13.8-.3 27.6-.8 41.3l.3-.3c-9.3 15.9-15.5 37-16.5 51.7zm105.9 6.2c-12.7 19.5-40 35.7-59.2 36.5-19.3.9-40.5-13.2-40.5-37 5.7-23.2 18.9-49.7 33.5-54 22.7-6.9 69.2 23.4 66.2 54.5zM372.9 75.2c-3.8-72.1-100.8-79.7-126-23.5 44.6-24.3 90.3-15.7 126 23.5zM74.8 407.1c-15.7 1.6-49.5 25.4-49.5 43.2 0 11.6 15.7 19.5 32.2 14.9 12.2-3.2 31.1-17.6 35.9-27.3 6-11.6-3.7-32.7-18.6-30.8zm215.9-176.2c28.6 0 51.9-21.6 51.9-48.4 0-36.1-40.5-58.1-72.2-44.3 9.5 3 16.5 11.6 16.5 21.6 0 23.3-33.3 32-46.5 11.3-7.3 34.1 19.4 59.8 50.3 59.8zM68 474.1c.5 6.5 12.2 12.7 21.6 9.5 6.8-2.7 14.6-10.5 17.3-16.2 3-7-1.1-20-9.7-18.4-8.9 1.6-29.7 16.7-29.2 25.1zm433.2-67c-14.9-1.9-24.6 19.2-18.9 30.8 4.9 9.7 24.1 24.1 36.2 27.3 16.5 4.6 32.2-3.2 32.2-14.9 0-17.8-33.8-41.6-49.5-43.2zM478.8 449c-8.4-1.6-12.4 11.3-9.5 18.4 2.4 5.7 10.3 13.5 17.3 16.2 9.2 3.2 21.1-3 21.3-9.5.9-8.4-20.2-23.5-29.1-25.1z" } }, "free": ["brands"] }, "orcid": { "changes": ["5.11.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f8d2", "label": "ORCID", "voted": false, "svg": { "brands": { "last_modified": 1660014481, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M294.75 188.19h-45.92V342h47.47c67.62 0 83.12-51.34 83.12-76.91 0-41.64-26.54-76.9-84.67-76.9zM256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm-80.79 360.76h-29.84v-207.5h29.84zm-14.92-231.14a19.57 19.57 0 1 1 19.57-19.57 19.64 19.64 0 0 1-19.57 19.57zM300 369h-81V161.26h80.6c76.73 0 110.44 54.83 110.44 103.85C410 318.39 368.38 369 300 369z" } }, "free": ["brands"] }, "osi": { "changes": ["5.0.0", "5.8.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f41a", "label": "Open Source Initiative", "voted": false, "svg": { "brands": { "last_modified": 1660014470, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M8 266.44C10.3 130.64 105.4 34 221.8 18.34c138.8-18.6 255.6 75.8 278 201.1 21.3 118.8-44 230-151.6 274-9.3 3.8-14.4 1.7-18-7.7q-26.7-69.45-53.4-139c-3.1-8.1-1-13.2 7-16.8 24.2-11 39.3-29.4 43.3-55.8a71.47 71.47 0 0 0-64.5-82.2c-39-3.4-71.8 23.7-77.5 59.7-5.2 33 11.1 63.7 41.9 77.7 9.6 4.4 11.5 8.6 7.8 18.4q-26.85 69.9-53.7 139.9c-2.6 6.9-8.3 9.3-15.5 6.5-52.6-20.3-101.4-61-130.8-119-24.9-49.2-25.2-87.7-26.8-108.7zm20.9-1.9c.4 6.6.6 14.3 1.3 22.1 6.3 71.9 49.6 143.5 131 183.1 3.2 1.5 4.4.8 5.6-2.3q22.35-58.65 45-117.3c1.3-3.3.6-4.8-2.4-6.7-31.6-19.9-47.3-48.5-45.6-86 1-21.6 9.3-40.5 23.8-56.3 30-32.7 77-39.8 115.5-17.6a91.64 91.64 0 0 1 45.2 90.4c-3.6 30.6-19.3 53.9-45.7 69.8-2.7 1.6-3.5 2.9-2.3 6q22.8 58.8 45.2 117.7c1.2 3.1 2.4 3.8 5.6 2.3 35.5-16.6 65.2-40.3 88.1-72 34.8-48.2 49.1-101.9 42.3-161-13.7-117.5-119.4-214.8-255.5-198-106.1 13-195.3 102.5-197.1 225.8z" } }, "free": ["brands"] }, "otter": { "aliases": { "unicodes": { "composite": ["1f9a6"], "secondary": ["10f700"] } }, "changes": [ "5.4.0", "6.0.0-beta1", "6.0.0-beta2", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "animal", "badger", "fauna", "fishing", "fur", "mammal", "marten", "otter", "playful" ] }, "styles": ["solid"], "unicode": "f700", "label": "Otter", "voted": false, "svg": { "solid": { "last_modified": 1684768130, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M181.5 197.1l12.9 6.4c5.9 3 12.4 4.5 19.1 4.5c23.5 0 42.6-19.1 42.6-42.6V144c0-35.3-28.7-64-64-64H128c-35.3 0-64 28.7-64 64v21.4c0 23.5 19.1 42.6 42.6 42.6c6.6 0 13.1-1.5 19.1-4.5l12.9-6.4 8.4-4.2L135.1 185c-4.5-3-7.1-8-7.1-13.3V168c0-13.3 10.7-24 24-24h16c13.3 0 24 10.7 24 24v3.7c0 5.3-2.7 10.3-7.1 13.3l-11.8 7.9 8.4 4.2zm-8.6 49.4L160 240l-12.9 6.4c-12.6 6.3-26.5 9.6-40.5 9.6c-3.6 0-7.1-.2-10.6-.6v.6c0 35.3 28.7 64 64 64h64c17.7 0 32 14.3 32 32s-14.3 32-32 32H384V336 320c0-23.7 12.9-44.4 32-55.4c9.4-5.4 20.3-8.6 32-8.6V240c0-26.5 21.5-48 48-48c8.8 0 16 7.2 16 16v32 16 48c0 8.8 7.2 16 16 16s16-7.2 16-16V204.3c0-48.2-30.8-91-76.6-106.3l-8.5-2.8c-8-2.7-12.6-11.1-10.4-19.3s10.3-13.2 18.6-11.6l19.9 4C576 86.1 640 164.2 640 254.9l0 1.1h0c0 123.7-100.3 224-224 224h-1.1H256h-.6C132 480 32 380 32 256.6V256 216.8c-10.1-14.6-16-32.3-16-51.4V144l0-1.4C6.7 139.3 0 130.5 0 120c0-13.3 10.7-24 24-24h2.8C44.8 58.2 83.3 32 128 32h64c44.7 0 83.2 26.2 101.2 64H296c13.3 0 24 10.7 24 24c0 10.5-6.7 19.3-16 22.6l0 1.4v21.4c0 1.4 0 2.8-.1 4.3c12-6.2 25.7-9.6 40.1-9.6h8c17.7 0 32 14.3 32 32s-14.3 32-32 32h-8c-13.3 0-24 10.7-24 24v8h56.4c-15.2 17-24.4 39.4-24.4 64H320c-42.3 0-78.2-27.4-91-65.3c-5.1 .9-10.3 1.3-15.6 1.3c-14.1 0-27.9-3.3-40.5-9.6zM96 128a16 16 0 1 1 0 32 16 16 0 1 1 0-32zm112 16a16 16 0 1 1 32 0 16 16 0 1 1 -32 0z" } }, "free": ["solid"] }, "outdent": { "aliases": { "names": ["dedent"], "unicodes": { "secondary": ["10f03b"] } }, "changes": [ "1.0.0", "5.0.0", "5.9.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["align", "justify", "paragraph", "tab"] }, "styles": ["solid"], "unicode": "f03b", "label": "Outdent", "voted": false, "svg": { "solid": { "last_modified": 1684767206, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M0 64C0 46.3 14.3 32 32 32H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32C14.3 96 0 81.7 0 64zM192 192c0-17.7 14.3-32 32-32H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H224c-17.7 0-32-14.3-32-32zm32 96H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H224c-17.7 0-32-14.3-32-32s14.3-32 32-32zM0 448c0-17.7 14.3-32 32-32H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32-14.3-32-32zM.2 268.6c-8.2-6.4-8.2-18.9 0-25.3l101.9-79.3c10.5-8.2 25.8-.7 25.8 12.6V335.3c0 13.3-15.3 20.8-25.8 12.6L.2 268.6z" } }, "free": ["solid"] }, "p": { "aliases": { "unicodes": { "composite": ["70"] } }, "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Latin Capital Letter P", "Latin Small Letter P", "letter"] }, "styles": ["solid"], "unicode": "50", "label": "P", "voted": false, "svg": { "solid": { "last_modified": 1684767246, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M0 96C0 60.7 28.7 32 64 32h96c88.4 0 160 71.6 160 160s-71.6 160-160 160H64v96c0 17.7-14.3 32-32 32s-32-14.3-32-32V320 96zM64 288h96c53 0 96-43 96-96s-43-96-96-96H64V288z" } }, "free": ["solid"] }, "padlet": { "changes": ["6.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e4a0", "label": "Padlet", "voted": false, "svg": { "brands": { "last_modified": 1660014473, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M297.9 0L298 .001C305.6 .1078 312.4 4.72 315.5 11.78L447.5 320.3L447.8 320.2L448 320.6L445.2 330.6L402.3 488.6C398.6 504.8 382.6 514.9 366.5 511.2L298.1 495.6L229.6 511.2C213.5 514.9 197.5 504.8 193.8 488.6L150.9 330.6L148.2 320.6L148.3 320.2L280.4 11.78C283.4 4.797 290.3 .1837 297.9 .0006L297.9 0zM160.1 322.1L291.1 361.2L298 483.7L305.9 362.2L436.5 322.9L436.7 322.8L305.7 347.9L297.1 27.72L291.9 347.9L160.1 322.1zM426 222.6L520.4 181.6H594.2L437.2 429.2L468.8 320.2L426 222.6zM597.5 181.4L638.9 257.6C642.9 265.1 635 273.5 627.3 269.8L579.7 247.1L597.5 181.4zM127.3 318.5L158.7 430L1.61 154.5C-4.292 144.1 7.128 132.5 17.55 138.3L169.4 222.5L127.3 318.5z" } }, "free": ["brands"] }, "page4": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3d7", "label": "page4 Corporation", "voted": false, "svg": { "brands": { "last_modified": 1660014472, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M248 504C111 504 0 393 0 256S111 8 248 8c20.9 0 41.3 2.6 60.7 7.5L42.3 392H248v112zm0-143.6V146.8L98.6 360.4H248zm96 31.6v92.7c45.7-19.2 84.5-51.7 111.4-92.7H344zm57.4-138.2l-21.2 8.4 21.2 8.3v-16.7zm-20.3 54.5c-6.7 0-8 6.3-8 12.9v7.7h16.2v-10c0-5.9-2.3-10.6-8.2-10.6zM496 256c0 37.3-8.2 72.7-23 104.4H344V27.3C433.3 64.8 496 153.1 496 256zM360.4 143.6h68.2V96h-13.9v32.6h-13.9V99h-13.9v29.6h-12.7V96h-13.9v47.6zm68.1 185.3H402v-11c0-15.4-5.6-25.2-20.9-25.2-15.4 0-20.7 10.6-20.7 25.9v25.3h68.2v-15zm0-103l-68.2 29.7V268l68.2 29.5v-16.6l-14.4-5.7v-26.5l14.4-5.9v-16.9zm-4.8-68.5h-35.6V184H402v-12.2h11c8.6 15.8 1.3 35.3-18.6 35.3-22.5 0-28.3-25.3-15.5-37.7l-11.6-10.6c-16.2 17.5-12.2 63.9 27.1 63.9 34 0 44.7-35.9 29.3-65.3z" } }, "free": ["brands"] }, "pagelines": { "changes": ["4.0.0", "5.0.0"], "ligatures": [], "search": { "terms": ["eco", "flora", "leaf", "leaves", "nature", "plant", "tree"] }, "styles": ["brands"], "unicode": "f18c", "label": "Pagelines", "voted": false, "svg": { "brands": { "last_modified": 1660014479, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M384 312.7c-55.1 136.7-187.1 54-187.1 54-40.5 81.8-107.4 134.4-184.6 134.7-16.1 0-16.6-24.4 0-24.4 64.4-.3 120.5-42.7 157.2-110.1-41.1 15.9-118.6 27.9-161.6-82.2 109-44.9 159.1 11.2 178.3 45.5 9.9-24.4 17-50.9 21.6-79.7 0 0-139.7 21.9-149.5-98.1 119.1-47.9 152.6 76.7 152.6 76.7 1.6-16.7 3.3-52.6 3.3-53.4 0 0-106.3-73.7-38.1-165.2 124.6 43 61.4 162.4 61.4 162.4.5 1.6.5 23.8 0 33.4 0 0 45.2-89 136.4-57.5-4.2 134-141.9 106.4-141.9 106.4-4.4 27.4-11.2 53.4-20 77.5 0 0 83-91.8 172-20z" } }, "free": ["brands"] }, "pager": { "aliases": { "unicodes": { "composite": ["1f4df"], "secondary": ["10f815"] } }, "changes": ["5.7.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["beeper", "cell phone", "communication", "page", "pager"] }, "styles": ["solid"], "unicode": "f815", "label": "Pager", "voted": false, "svg": { "solid": { "last_modified": 1684767343, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 128C0 92.7 28.7 64 64 64H448c35.3 0 64 28.7 64 64V384c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128zm64 32v64c0 17.7 14.3 32 32 32H416c17.7 0 32-14.3 32-32V160c0-17.7-14.3-32-32-32H96c-17.7 0-32 14.3-32 32zM80 320c-13.3 0-24 10.7-24 24s10.7 24 24 24h56c13.3 0 24-10.7 24-24s-10.7-24-24-24H80zm136 0c-13.3 0-24 10.7-24 24s10.7 24 24 24h48c13.3 0 24-10.7 24-24s-10.7-24-24-24H216z" } }, "free": ["solid"] }, "paint-roller": { "aliases": { "unicodes": { "secondary": ["10f5aa"] } }, "changes": ["5.1.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "acrylic", "art", "brush", "color", "fill", "paint", "pigment", "watercolor" ] }, "styles": ["solid"], "unicode": "f5aa", "label": "Paint Roller", "voted": false, "svg": { "solid": { "last_modified": 1684767367, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 64C0 28.7 28.7 0 64 0H352c35.3 0 64 28.7 64 64v64c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V64zM160 352c0-17.7 14.3-32 32-32V304c0-44.2 35.8-80 80-80H416c17.7 0 32-14.3 32-32V160 69.5c37.3 13.2 64 48.7 64 90.5v32c0 53-43 96-96 96H272c-8.8 0-16 7.2-16 16v16c17.7 0 32 14.3 32 32V480c0 17.7-14.3 32-32 32H192c-17.7 0-32-14.3-32-32V352z" } }, "free": ["solid"] }, "paintbrush": { "aliases": { "names": ["paint-brush"], "unicodes": { "composite": ["1f58c"], "secondary": ["10f1fc"] } }, "changes": [ "4.2.0", "5.0.0", "5.1.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "acrylic", "art", "brush", "color", "fill", "paint", "paintbrush", "painting", "pigment", "watercolor" ] }, "styles": ["solid"], "unicode": "f1fc", "label": "Paintbrush", "voted": false, "svg": { "solid": { "last_modified": 1684767368, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M339.3 367.1c27.3-3.9 51.9-19.4 67.2-42.9L568.2 74.1c12.6-19.5 9.4-45.3-7.6-61.2S517.7-4.4 499.1 9.6L262.4 187.2c-24 18-38.2 46.1-38.4 76.1L339.3 367.1zm-19.6 25.4l-116-104.4C143.9 290.3 96 339.6 96 400c0 3.9 .2 7.8 .6 11.6C98.4 429.1 86.4 448 68.8 448H64c-17.7 0-32 14.3-32 32s14.3 32 32 32H208c61.9 0 112-50.1 112-112c0-2.5-.1-5-.2-7.5z" } }, "free": ["solid"] }, "palette": { "aliases": { "unicodes": { "composite": ["1f3a8"], "secondary": ["10f53f"] } }, "changes": ["5.0.13", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "acrylic", "art", "artist palette", "brush", "color", "fill", "museum", "paint", "painting", "palette", "pigment", "watercolor" ] }, "styles": ["solid"], "unicode": "f53f", "label": "Palette", "voted": true, "svg": { "solid": { "last_modified": 1684767367, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M512 256c0 .9 0 1.8 0 2.7c-.4 36.5-33.6 61.3-70.1 61.3H344c-26.5 0-48 21.5-48 48c0 3.4 .4 6.7 1 9.9c2.1 10.2 6.5 20 10.8 29.9c6.1 13.8 12.1 27.5 12.1 42c0 31.8-21.6 60.7-53.4 62c-3.5 .1-7 .2-10.6 .2C114.6 512 0 397.4 0 256S114.6 0 256 0S512 114.6 512 256zM128 288a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zm0-96a32 32 0 1 0 0-64 32 32 0 1 0 0 64zM288 96a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zm96 96a32 32 0 1 0 0-64 32 32 0 1 0 0 64z" } }, "free": ["solid"] }, "palfed": { "changes": ["5.0.0", "5.0.3"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3d8", "label": "Palfed", "voted": false, "svg": { "brands": { "last_modified": 1660014467, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M384.9 193.9c0-47.4-55.2-44.2-95.4-29.8-1.3 39.4-2.5 80.7-3 119.8.7 2.8 2.6 6.2 15.1 6.2 36.8 0 83.4-42.8 83.3-96.2zm-194.5 72.2c.2 0 6.5-2.7 11.2-2.7 26.6 0 20.7 44.1-14.4 44.1-21.5 0-37.1-18.1-37.1-43 0-42 42.9-95.6 100.7-126.5 1-12.4 3-22 10.5-28.2 11.2-9 26.6-3.5 29.5 11.1 72.2-22.2 135.2 1 135.2 72 0 77.9-79.3 152.6-140.1 138.2-.1 39.4.9 74.4 2.7 100v.2c.2 3.4.6 12.5-5.3 19.1-9.6 10.6-33.4 10-36.4-22.3-4.1-44.4.2-206.1 1.4-242.5-21.5 15-58.5 50.3-58.5 75.9.2 2.5.4 4 .6 4.6zM8 181.1s-.1 37.4 38.4 37.4h30l22.4 217.2s0 44.3 44.7 44.3h288.9s44.7-.4 44.7-44.3l22.4-217.2h30s38.4 1.2 38.4-37.4c0 0 .1-37.4-38.4-37.4h-30.1c-7.3-25.6-30.2-74.3-119.4-74.3h-28V50.3s-2.7-18.4-21.1-18.4h-85.8s-21.1 0-21.1 18.4v19.1h-28.1s-105 4.2-120.5 74.3h-29S8 142.5 8 181.1z" } }, "free": ["brands"] }, "pallet": { "aliases": { "unicodes": { "secondary": ["10f482"] } }, "changes": ["5.0.7", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["archive", "box", "inventory", "shipping", "warehouse"] }, "styles": ["solid"], "unicode": "f482", "label": "Pallet", "voted": false, "svg": { "solid": { "last_modified": 1684767442, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M32 320c-17.7 0-32 14.3-32 32s14.3 32 32 32H64v64H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H96 320 544h64c17.7 0 32-14.3 32-32s-14.3-32-32-32H576V384h32c17.7 0 32-14.3 32-32s-14.3-32-32-32H544 320 96 32zm96 64H288v64H128V384zm224 0H512v64H352V384z" } }, "free": ["solid"] }, "panorama": { "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["image", "landscape", "photo", "wide"] }, "styles": ["solid"], "unicode": "e209", "label": "Panorama", "voted": false, "svg": { "solid": { "last_modified": 1684767342, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M45.6 32C20.4 32 0 52.4 0 77.6V434.4C0 459.6 20.4 480 45.6 480c5.1 0 10-.8 14.7-2.4C74.6 472.8 177.6 440 320 440s245.4 32.8 259.6 37.6c4.7 1.6 9.7 2.4 14.7 2.4c25.2 0 45.6-20.4 45.6-45.6V77.6C640 52.4 619.6 32 594.4 32c-5 0-10 .8-14.7 2.4C565.4 39.2 462.4 72 320 72S74.6 39.2 60.4 34.4C55.6 32.8 50.7 32 45.6 32zM96 160a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm272 0c7.9 0 15.4 3.9 19.8 10.5L512.3 353c5.4 8 5.6 18.4 .4 26.5s-14.7 12.3-24.2 10.7C442.7 382.4 385.2 376 320 376c-65.6 0-123.4 6.5-169.3 14.4c-9.8 1.7-19.7-2.9-24.7-11.5s-4.3-19.4 1.9-27.2L197.3 265c4.6-5.7 11.4-9 18.7-9s14.2 3.3 18.7 9l26.4 33.1 87-127.6c4.5-6.6 11.9-10.5 19.8-10.5z" } }, "free": ["solid"] }, "paper-plane": { "aliases": { "unicodes": { "composite": ["f1d9"], "secondary": ["10f1d8"] } }, "changes": [ "4.1.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.2.1", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["air", "float", "fold", "mail", "paper", "send"] }, "styles": ["solid", "regular"], "unicode": "f1d8", "label": "Paper Plane", "voted": false, "svg": { "solid": { "last_modified": 1684767389, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M498.1 5.6c10.1 7 15.4 19.1 13.5 31.2l-64 416c-1.5 9.7-7.4 18.2-16 23s-18.9 5.4-28 1.6L284 427.7l-68.5 74.1c-8.9 9.7-22.9 12.9-35.2 8.1S160 493.2 160 480V396.4c0-4 1.5-7.8 4.2-10.7L331.8 202.8c5.8-6.3 5.6-16-.4-22s-15.7-6.4-22-.7L106 360.8 17.7 316.6C7.1 311.3 .3 300.7 0 288.9s5.9-22.8 16.1-28.7l448-256c10.7-6.1 23.9-5.5 34 1.4z" }, "regular": { "last_modified": 1684767389, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M16.1 260.2c-22.6 12.9-20.5 47.3 3.6 57.3L160 376V479.3c0 18.1 14.6 32.7 32.7 32.7c9.7 0 18.9-4.3 25.1-11.8l62-74.3 123.9 51.6c18.9 7.9 40.8-4.5 43.9-24.7l64-416c1.9-12.1-3.4-24.3-13.5-31.2s-23.3-7.5-34-1.4l-448 256zm52.1 25.5L409.7 90.6 190.1 336l1.2 1L68.2 285.7zM403.3 425.4L236.7 355.9 450.8 116.6 403.3 425.4z" } }, "free": ["regular", "solid"] }, "paperclip": { "aliases": { "unicodes": { "composite": ["1f4ce"], "secondary": ["10f0c6"] } }, "changes": [ "2.0.0", "5.0.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "attach", "attachment", "connect", "link", "papercli", "paperclip" ] }, "styles": ["solid"], "unicode": "f0c6", "label": "Paperclip", "voted": false, "svg": { "solid": { "last_modified": 1684767367, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M364.2 83.8c-24.4-24.4-64-24.4-88.4 0l-184 184c-42.1 42.1-42.1 110.3 0 152.4s110.3 42.1 152.4 0l152-152c10.9-10.9 28.7-10.9 39.6 0s10.9 28.7 0 39.6l-152 152c-64 64-167.6 64-231.6 0s-64-167.6 0-231.6l184-184c46.3-46.3 121.3-46.3 167.6 0s46.3 121.3 0 167.6l-176 176c-28.6 28.6-75 28.6-103.6 0s-28.6-75 0-103.6l144-144c10.9-10.9 28.7-10.9 39.6 0s10.9 28.7 0 39.6l-144 144c-6.7 6.7-6.7 17.7 0 24.4s17.7 6.7 24.4 0l176-176c24.4-24.4 24.4-64 0-88.4z" } }, "free": ["solid"] }, "parachute-box": { "aliases": { "unicodes": { "secondary": ["10f4cd"] } }, "changes": [ "5.0.9", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["aid", "assistance", "goods", "relief", "rescue", "supplies"] }, "styles": ["solid"], "unicode": "f4cd", "label": "Parachute Box", "voted": false, "svg": { "solid": { "last_modified": 1684766475, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M383.5 192c.3-5.3 .5-10.6 .5-16c0-51-15.9-96-40.2-127.6C319.5 16.9 288.2 0 256 0s-63.5 16.9-87.8 48.4C143.9 80 128 125 128 176c0 5.4 .2 10.7 .5 16H240V320H208c-7 0-13.7 1.5-19.7 4.2L68.2 192H96.5c-.3-5.3-.5-10.6-.5-16c0-64 22.2-121.2 57.1-159.3C62 49.3 18.6 122.6 4.2 173.6C1.5 183.1 9 192 18.9 192h6L165.2 346.3c-3.3 6.5-5.2 13.9-5.2 21.7v96c0 26.5 21.5 48 48 48h96c26.5 0 48-21.5 48-48V368c0-7.8-1.9-15.2-5.2-21.7L487.1 192h6c9.9 0 17.4-8.9 14.7-18.4C493.4 122.6 450 49.3 358.9 16.7C393.8 54.8 416 112.1 416 176c0 5.4-.2 10.7-.5 16h28.3L323.7 324.2c-6-2.7-12.7-4.2-19.7-4.2H272V192H383.5z" } }, "free": ["solid"] }, "paragraph": { "aliases": { "unicodes": { "composite": ["b6"], "secondary": ["10f1dd"] } }, "changes": [ "4.1.0", "5.0.0", "5.9.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["Pilcrow Sign", "edit", "format", "text", "writing"] }, "styles": ["solid"], "unicode": "f1dd", "label": "Paragraph", "voted": false, "svg": { "solid": { "last_modified": 1684767245, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M192 32h64H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H384l0 352c0 17.7-14.3 32-32 32s-32-14.3-32-32l0-352H288V448c0 17.7-14.3 32-32 32s-32-14.3-32-32V352H192c-88.4 0-160-71.6-160-160s71.6-160 160-160z" } }, "free": ["solid"] }, "passport": { "aliases": { "unicodes": { "secondary": ["10f5ab"] } }, "changes": ["5.1.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["document", "id", "identification", "issued", "travel"] }, "styles": ["solid"], "unicode": "f5ab", "label": "Passport", "voted": false, "svg": { "solid": { "last_modified": 1684767392, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M0 64C0 28.7 28.7 0 64 0H384c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V64zM183 278.8c-27.9-13.2-48.4-39.4-53.7-70.8h39.1c1.6 30.4 7.7 53.8 14.6 70.8zm41.3 9.2l-.3 0-.3 0c-2.4-3.5-5.7-8.9-9.1-16.5c-6-13.6-12.4-34.3-14.2-63.5h47.1c-1.8 29.2-8.1 49.9-14.2 63.5c-3.4 7.6-6.7 13-9.1 16.5zm40.7-9.2c6.8-17.1 12.9-40.4 14.6-70.8h39.1c-5.3 31.4-25.8 57.6-53.7 70.8zM279.6 176c-1.6-30.4-7.7-53.8-14.6-70.8c27.9 13.2 48.4 39.4 53.7 70.8H279.6zM223.7 96l.3 0 .3 0c2.4 3.5 5.7 8.9 9.1 16.5c6 13.6 12.4 34.3 14.2 63.5H200.5c1.8-29.2 8.1-49.9 14.2-63.5c3.4-7.6 6.7-13 9.1-16.5zM183 105.2c-6.8 17.1-12.9 40.4-14.6 70.8H129.3c5.3-31.4 25.8-57.6 53.7-70.8zM352 192A128 128 0 1 0 96 192a128 128 0 1 0 256 0zM112 384c-8.8 0-16 7.2-16 16s7.2 16 16 16H336c8.8 0 16-7.2 16-16s-7.2-16-16-16H112z" } }, "free": ["solid"] }, "paste": { "aliases": { "names": ["file-clipboard"], "unicodes": { "secondary": ["10f0ea"] } }, "changes": [ "2.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.2.1", "6.3.0", "6.4.0", "6.4.1" ], "ligatures": [], "search": { "terms": ["clipboard", "copy", "document", "paper"] }, "styles": ["solid", "regular"], "unicode": "f0ea", "label": "Paste", "voted": false, "svg": { "solid": { "last_modified": 1684767393, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M160 0c-23.7 0-44.4 12.9-55.4 32H48C21.5 32 0 53.5 0 80V400c0 26.5 21.5 48 48 48H192V176c0-44.2 35.8-80 80-80h48V80c0-26.5-21.5-48-48-48H215.4C204.4 12.9 183.7 0 160 0zM272 128c-26.5 0-48 21.5-48 48V448v16c0 26.5 21.5 48 48 48H464c26.5 0 48-21.5 48-48V256H416c-17.7 0-32-14.3-32-32V128H320 272zM160 40a24 24 0 1 1 0 48 24 24 0 1 1 0-48zm256 88v96h96l-96-96z" }, "regular": { "last_modified": 1684767393, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M80 96v16c0 17.7 14.3 32 32 32h60.8c16.6-28.7 47.6-48 83.2-48h62c-7.1-27.6-32.2-48-62-48H215.4C211.6 20.9 188.2 0 160 0s-51.6 20.9-55.4 48H64C28.7 48 0 76.7 0 112V384c0 35.3 28.7 64 64 64h96V400H64c-8.8 0-16-7.2-16-16V112c0-8.8 7.2-16 16-16H80zm64-40a16 16 0 1 1 32 0 16 16 0 1 1 -32 0zM256 464c-8.8 0-16-7.2-16-16V192c0-8.8 7.2-16 16-16H384v48c0 17.7 14.3 32 32 32h48V448c0 8.8-7.2 16-16 16H256zm192 48c35.3 0 64-28.7 64-64V227.9c0-12.7-5.1-24.9-14.1-33.9l-51.9-51.9c-9-9-21.2-14.1-33.9-14.1H256c-35.3 0-64 28.7-64 64V448c0 35.3 28.7 64 64 64H448z" } }, "free": ["regular", "solid"] }, "patreon": { "changes": ["5.0.0", "5.0.3"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3d9", "label": "Patreon", "voted": false, "svg": { "brands": { "last_modified": 1660014470, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M512 194.8c0 101.3-82.4 183.8-183.8 183.8-101.7 0-184.4-82.4-184.4-183.8 0-101.6 82.7-184.3 184.4-184.3C429.6 10.5 512 93.2 512 194.8zM0 501.5h90v-491H0v491z" } }, "free": ["brands"] }, "pause": { "aliases": { "unicodes": { "composite": ["23f8"], "secondary": ["10f04c"] } }, "changes": [ "1.0.0", "5.0.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "bar", "double", "hold", "pause", "pause button", "vertical", "wait" ] }, "styles": ["solid"], "unicode": "f04c", "label": "Pause", "voted": false, "svg": { "solid": { "last_modified": 1684766676, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M48 64C21.5 64 0 85.5 0 112V400c0 26.5 21.5 48 48 48H80c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48H48zm192 0c-26.5 0-48 21.5-48 48V400c0 26.5 21.5 48 48 48h32c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48H240z" } }, "free": ["solid"] }, "paw": { "aliases": { "unicodes": { "secondary": ["10f1b0"] } }, "changes": [ "4.1.0", "5.0.0", "6.0.0-beta1", "6.1.2", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["animal", "cat", "dog", "pet", "print"] }, "styles": ["solid"], "unicode": "f1b0", "label": "Paw", "voted": false, "svg": { "solid": { "last_modified": 1684768131, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M226.5 92.9c14.3 42.9-.3 86.2-32.6 96.8s-70.1-15.6-84.4-58.5s.3-86.2 32.6-96.8s70.1 15.6 84.4 58.5zM100.4 198.6c18.9 32.4 14.3 70.1-10.2 84.1s-59.7-.9-78.5-33.3S-2.7 179.3 21.8 165.3s59.7 .9 78.5 33.3zM69.2 401.2C121.6 259.9 214.7 224 256 224s134.4 35.9 186.8 177.2c3.6 9.7 5.2 20.1 5.2 30.5v1.6c0 25.8-20.9 46.7-46.7 46.7c-11.5 0-22.9-1.4-34-4.2l-88-22c-15.3-3.8-31.3-3.8-46.6 0l-88 22c-11.1 2.8-22.5 4.2-34 4.2C84.9 480 64 459.1 64 433.3v-1.6c0-10.4 1.6-20.8 5.2-30.5zM421.8 282.7c-24.5-14-29.1-51.7-10.2-84.1s54-47.3 78.5-33.3s29.1 51.7 10.2 84.1s-54 47.3-78.5 33.3zM310.1 189.7c-32.3-10.6-46.9-53.9-32.6-96.8s52.1-69.1 84.4-58.5s46.9 53.9 32.6 96.8s-52.1 69.1-84.4 58.5z" } }, "free": ["solid"] }, "paypal": { "changes": ["4.2.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f1ed", "label": "Paypal", "voted": false, "svg": { "brands": { "last_modified": 1660014471, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M111.4 295.9c-3.5 19.2-17.4 108.7-21.5 134-.3 1.8-1 2.5-3 2.5H12.3c-7.6 0-13.1-6.6-12.1-13.9L58.8 46.6c1.5-9.6 10.1-16.9 20-16.9 152.3 0 165.1-3.7 204 11.4 60.1 23.3 65.6 79.5 44 140.3-21.5 62.6-72.5 89.5-140.1 90.3-43.4.7-69.5-7-75.3 24.2zM357.1 152c-1.8-1.3-2.5-1.8-3 1.3-2 11.4-5.1 22.5-8.8 33.6-39.9 113.8-150.5 103.9-204.5 103.9-6.1 0-10.1 3.3-10.9 9.4-22.6 140.4-27.1 169.7-27.1 169.7-1 7.1 3.5 12.9 10.6 12.9h63.5c8.6 0 15.7-6.3 17.4-14.9.7-5.4-1.1 6.1 14.4-91.3 4.6-22 14.3-19.7 29.3-19.7 71 0 126.4-28.8 142.9-112.3 6.5-34.8 4.6-71.4-23.8-92.6z" } }, "free": ["brands"] }, "peace": { "aliases": { "unicodes": { "composite": ["262e"], "secondary": ["10f67c"] } }, "changes": [ "5.3.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "peace", "peace symbol", "serenity", "tranquility", "truce", "war" ] }, "styles": ["solid"], "unicode": "f67c", "label": "Peace", "voted": false, "svg": { "solid": { "last_modified": 1684767601, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M224 445.3V323.5l-94.3 77.1c26.1 22.8 58.5 38.7 94.3 44.7zM89.2 351.1L224 240.8V66.7C133.2 81.9 64 160.9 64 256c0 34.6 9.2 67.1 25.2 95.1zm293.1 49.5L288 323.5V445.3c35.7-6 68.1-21.9 94.3-44.7zm40.6-49.5c16-28 25.2-60.5 25.2-95.1c0-95.1-69.2-174.1-160-189.3V240.8L422.8 351.1zM0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256z" } }, "free": ["solid"] }, "pen": { "aliases": { "unicodes": { "composite": ["1f58a"], "secondary": ["10f304"] } }, "changes": [ "5.0.0", "5.1.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["ballpoint", "design", "edit", "pen", "update", "write"] }, "styles": ["solid"], "unicode": "f304", "label": "Pen", "voted": false, "svg": { "solid": { "last_modified": 1684767367, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M362.7 19.3L314.3 67.7 444.3 197.7l48.4-48.4c25-25 25-65.5 0-90.5L453.3 19.3c-25-25-65.5-25-90.5 0zm-71 71L58.6 323.5c-10.4 10.4-18 23.3-22.2 37.4L1 481.2C-1.5 489.7 .8 498.8 7 505s15.3 8.5 23.7 6.1l120.3-35.4c14.1-4.2 27-11.8 37.4-22.2L421.7 220.3 291.7 90.3z" } }, "free": ["solid"] }, "pen-clip": { "aliases": { "names": ["pen-alt"], "unicodes": { "secondary": ["10f305"] } }, "changes": [ "5.0.0", "5.1.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["design", "edit", "update", "write"] }, "styles": ["solid"], "unicode": "f305", "label": "Pen Clip", "voted": false, "svg": { "solid": { "last_modified": 1684767368, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M453.3 19.3l39.4 39.4c25 25 25 65.5 0 90.5l-52.1 52.1 0 0-1-1 0 0-16-16-96-96-17-17 52.1-52.1c25-25 65.5-25 90.5 0zM241 114.9c-9.4-9.4-24.6-9.4-33.9 0L105 217c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9L173.1 81c28.1-28.1 73.7-28.1 101.8 0L288 94.1l17 17 96 96 16 16 1 1-17 17L229.5 412.5c-48 48-109.2 80.8-175.8 94.1l-25 5c-7.9 1.6-16-.9-21.7-6.6s-8.1-13.8-6.6-21.7l5-25c13.3-66.6 46.1-127.8 94.1-175.8L254.1 128 241 114.9z" } }, "free": ["solid"] }, "pen-fancy": { "aliases": { "unicodes": { "composite": ["1f58b", "2712"], "secondary": ["10f5ac"] } }, "changes": ["5.1.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "black nib", "design", "edit", "fountain", "fountain pen", "nib", "pen", "update", "write" ] }, "styles": ["solid"], "unicode": "f5ac", "label": "Pen Fancy", "voted": false, "svg": { "solid": { "last_modified": 1684767367, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M373.5 27.1C388.5 9.9 410.2 0 433 0c43.6 0 79 35.4 79 79c0 22.8-9.9 44.6-27.1 59.6L277.7 319l-10.3-10.3-64-64L193 234.3 373.5 27.1zM170.3 256.9l10.4 10.4 64 64 10.4 10.4-19.2 83.4c-3.9 17.1-16.9 30.7-33.8 35.4L24.4 510.3l95.4-95.4c2.6 .7 5.4 1.1 8.3 1.1c17.7 0 32-14.3 32-32s-14.3-32-32-32s-32 14.3-32 32c0 2.9 .4 5.6 1.1 8.3L1.7 487.6 51.5 310c4.7-16.9 18.3-29.9 35.4-33.8l83.4-19.2z" } }, "free": ["solid"] }, "pen-nib": { "aliases": { "unicodes": { "composite": ["2711"], "secondary": ["10f5ad"] } }, "changes": ["5.1.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["design", "edit", "fountain pen", "update", "write"] }, "styles": ["solid"], "unicode": "f5ad", "label": "Pen Nib", "voted": true, "svg": { "solid": { "last_modified": 1684767366, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M368.4 18.3L312.7 74.1 437.9 199.3l55.7-55.7c21.9-21.9 21.9-57.3 0-79.2L447.6 18.3c-21.9-21.9-57.3-21.9-79.2 0zM288 94.6l-9.2 2.8L134.7 140.6c-19.9 6-35.7 21.2-42.3 41L3.8 445.8c-3.8 11.3-1 23.9 7.3 32.4L164.7 324.7c-3-6.3-4.7-13.3-4.7-20.7c0-26.5 21.5-48 48-48s48 21.5 48 48s-21.5 48-48 48c-7.4 0-14.4-1.7-20.7-4.7L33.7 500.9c8.6 8.3 21.1 11.2 32.4 7.3l264.3-88.6c19.7-6.6 35-22.4 41-42.3l43.2-144.1 2.8-9.2L288 94.6z" } }, "free": ["solid"] }, "pen-ruler": { "aliases": { "names": ["pencil-ruler"], "unicodes": { "secondary": ["10f5ae"] } }, "changes": ["5.1.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["design", "draft", "draw", "pencil"] }, "styles": ["solid"], "unicode": "f5ae", "label": "Pen Ruler", "voted": false, "svg": { "solid": { "last_modified": 1684767368, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M469.3 19.3l23.4 23.4c25 25 25 65.5 0 90.5l-56.4 56.4L322.3 75.7l56.4-56.4c25-25 65.5-25 90.5 0zM44.9 353.2L299.7 98.3 413.7 212.3 158.8 467.1c-6.7 6.7-15.1 11.6-24.2 14.2l-104 29.7c-8.4 2.4-17.4 .1-23.6-6.1s-8.5-15.2-6.1-23.6l29.7-104c2.6-9.2 7.5-17.5 14.2-24.2zM249.4 103.4L103.4 249.4 16 161.9c-18.7-18.7-18.7-49.1 0-67.9L94.1 16c18.7-18.7 49.1-18.7 67.9 0l19.8 19.8c-.3 .3-.7 .6-1 .9l-64 64c-6.2 6.2-6.2 16.4 0 22.6s16.4 6.2 22.6 0l64-64c.3-.3 .6-.7 .9-1l45.1 45.1zM408.6 262.6l45.1 45.1c-.3 .3-.7 .6-1 .9l-64 64c-6.2 6.2-6.2 16.4 0 22.6s16.4 6.2 22.6 0l64-64c.3-.3 .6-.7 .9-1L496 350.1c18.7 18.7 18.7 49.1 0 67.9L417.9 496c-18.7 18.7-49.1 18.7-67.9 0l-87.4-87.4L408.6 262.6z" } }, "free": ["solid"] }, "pen-to-square": { "aliases": { "names": ["edit"], "unicodes": { "secondary": ["10f044"] } }, "changes": [ "1.0.0", "5.0.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["edit", "pen", "pencil", "update", "write"] }, "styles": ["solid", "regular"], "unicode": "f044", "label": "Pen To Square", "voted": false, "svg": { "solid": { "last_modified": 1684767368, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M471.6 21.7c-21.9-21.9-57.3-21.9-79.2 0L362.3 51.7l97.9 97.9 30.1-30.1c21.9-21.9 21.9-57.3 0-79.2L471.6 21.7zm-299.2 220c-6.1 6.1-10.8 13.6-13.5 21.9l-29.6 88.8c-2.9 8.6-.6 18.1 5.8 24.6s15.9 8.7 24.6 5.8l88.8-29.6c8.2-2.7 15.7-7.4 21.9-13.5L437.7 172.3 339.7 74.3 172.4 241.7zM96 64C43 64 0 107 0 160V416c0 53 43 96 96 96H352c53 0 96-43 96-96V320c0-17.7-14.3-32-32-32s-32 14.3-32 32v96c0 17.7-14.3 32-32 32H96c-17.7 0-32-14.3-32-32V160c0-17.7 14.3-32 32-32h96c17.7 0 32-14.3 32-32s-14.3-32-32-32H96z" }, "regular": { "last_modified": 1684767368, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M441 58.9L453.1 71c9.4 9.4 9.4 24.6 0 33.9L424 134.1 377.9 88 407 58.9c9.4-9.4 24.6-9.4 33.9 0zM209.8 256.2L344 121.9 390.1 168 255.8 302.2c-2.9 2.9-6.5 5-10.4 6.1l-58.5 16.7 16.7-58.5c1.1-3.9 3.2-7.5 6.1-10.4zM373.1 25L175.8 222.2c-8.7 8.7-15 19.4-18.3 31.1l-28.6 100c-2.4 8.4-.1 17.4 6.1 23.6s15.2 8.5 23.6 6.1l100-28.6c11.8-3.4 22.5-9.7 31.1-18.3L487 138.9c28.1-28.1 28.1-73.7 0-101.8L474.9 25C446.8-3.1 401.2-3.1 373.1 25zM88 64C39.4 64 0 103.4 0 152V424c0 48.6 39.4 88 88 88H360c48.6 0 88-39.4 88-88V312c0-13.3-10.7-24-24-24s-24 10.7-24 24V424c0 22.1-17.9 40-40 40H88c-22.1 0-40-17.9-40-40V152c0-22.1 17.9-40 40-40H200c13.3 0 24-10.7 24-24s-10.7-24-24-24H88z" } }, "free": ["regular", "solid"] }, "pencil": { "aliases": { "names": ["pencil-alt"], "unicodes": { "composite": ["270f", "f040"], "primary": ["f040"], "secondary": ["10f040", "10f303"] } }, "changes": [ "1.0.0", "5.0.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.2.1", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Lower Left Pencil", "design", "draw", "edit", "lead", "pencil", "update", "write" ] }, "styles": ["solid"], "unicode": "f303", "label": "Pencil", "voted": false, "svg": { "solid": { "last_modified": 1684767368, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M410.3 231l11.3-11.3-33.9-33.9-62.1-62.1L291.7 89.8l-11.3 11.3-22.6 22.6L58.6 322.9c-10.4 10.4-18 23.3-22.2 37.4L1 480.7c-2.5 8.4-.2 17.5 6.1 23.7s15.3 8.5 23.7 6.1l120.3-35.4c14.1-4.2 27-11.8 37.4-22.2L387.7 253.7 410.3 231zM160 399.4l-9.1 22.7c-4 3.1-8.5 5.4-13.3 6.9L59.4 452l23-78.1c1.4-4.9 3.8-9.4 6.9-13.3l22.7-9.1v32c0 8.8 7.2 16 16 16h32zM362.7 18.7L348.3 33.2 325.7 55.8 314.3 67.1l33.9 33.9 62.1 62.1 33.9 33.9 11.3-11.3 22.6-22.6 14.5-14.5c25-25 25-65.5 0-90.5L453.3 18.7c-25-25-65.5-25-90.5 0zm-47.4 168l-144 144c-6.2 6.2-16.4 6.2-22.6 0s-6.2-16.4 0-22.6l144-144c6.2-6.2 16.4-6.2 22.6 0s6.2 16.4 0 22.6z" } }, "free": ["solid"] }, "people-arrows": { "aliases": { "names": ["people-arrows-left-right"], "unicodes": { "secondary": ["10e068"] } }, "changes": [ "5.13.0", "5.14.0", "6.0.0-beta1", "6.1.2", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "distance", "isolation", "separate", "social distancing", "users-people" ] }, "styles": ["solid"], "unicode": "e068", "label": "People Arrows", "voted": false, "svg": { "solid": { "last_modified": 1684767533, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M64 64a64 64 0 1 1 128 0A64 64 0 1 1 64 64zM25.9 233.4C29.3 191.9 64 160 105.6 160h44.8c27 0 51 13.4 65.5 34.1c-2.7 1.9-5.2 4-7.5 6.3l-64 64c-21.9 21.9-21.9 57.3 0 79.2L192 391.2V464c0 26.5-21.5 48-48 48H112c-26.5 0-48-21.5-48-48V348.3c-26.5-9.5-44.7-35.8-42.2-65.6l4.1-49.3zM448 64a64 64 0 1 1 128 0A64 64 0 1 1 448 64zM431.6 200.4c-2.3-2.3-4.9-4.4-7.5-6.3c14.5-20.7 38.6-34.1 65.5-34.1h44.8c41.6 0 76.3 31.9 79.7 73.4l4.1 49.3c2.5 29.8-15.7 56.1-42.2 65.6V464c0 26.5-21.5 48-48 48H496c-26.5 0-48-21.5-48-48V391.2l47.6-47.6c21.9-21.9 21.9-57.3 0-79.2l-64-64zM272 240v32h96V240c0-9.7 5.8-18.5 14.8-22.2s19.3-1.7 26.2 5.2l64 64c9.4 9.4 9.4 24.6 0 33.9l-64 64c-6.9 6.9-17.2 8.9-26.2 5.2s-14.8-12.5-14.8-22.2V336H272v32c0 9.7-5.8 18.5-14.8 22.2s-19.3 1.7-26.2-5.2l-64-64c-9.4-9.4-9.4-24.6 0-33.9l64-64c6.9-6.9 17.2-8.9 26.2-5.2s14.8 12.5 14.8 22.2z" } }, "free": ["solid"] }, "people-carry-box": { "aliases": { "names": ["people-carry"], "unicodes": { "secondary": ["10f4ce"] } }, "changes": ["5.0.9", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["users-people"] }, "styles": ["solid"], "unicode": "f4ce", "label": "People Carry Box", "voted": false, "svg": { "solid": { "last_modified": 1684767532, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M80 48a48 48 0 1 1 96 0A48 48 0 1 1 80 48zm64 193.7v65.1l51 51c7.1 7.1 11.8 16.2 13.4 26.1l15.2 90.9c2.9 17.4-8.9 33.9-26.3 36.8s-33.9-8.9-36.8-26.3l-14.3-85.9L66.8 320C54.8 308 48 291.7 48 274.7V186.6c0-32.4 26.2-58.6 58.6-58.6c24.1 0 46.5 12 59.9 32l47.4 71.1 10.1 5V160c0-17.7 14.3-32 32-32H384c17.7 0 32 14.3 32 32v76.2l10.1-5L473.5 160c13.3-20 35.8-32 59.9-32c32.4 0 58.6 26.2 58.6 58.6v88.1c0 17-6.7 33.3-18.7 45.3l-79.4 79.4-14.3 85.9c-2.9 17.4-19.4 29.2-36.8 26.3s-29.2-19.4-26.3-36.8l15.2-90.9c1.6-9.9 6.3-19 13.4-26.1l51-51V241.7l-19 28.5c-4.6 7-11 12.6-18.5 16.3l-59.6 29.8c-2.4 1.3-4.9 2.2-7.6 2.8c-2.6 .6-5.3 .9-7.9 .8H256.7c-2.5 .1-5-.2-7.5-.7c-2.9-.6-5.6-1.6-8.1-3l-59.5-29.8c-7.5-3.7-13.8-9.4-18.5-16.3l-19-28.5zM2.3 468.1L50.1 348.6l49.2 49.2-37.6 94c-6.6 16.4-25.2 24.4-41.6 17.8S-4.3 484.5 2.3 468.1zM512 0a48 48 0 1 1 0 96 48 48 0 1 1 0-96zm77.9 348.6l47.8 119.5c6.6 16.4-1.4 35-17.8 41.6s-35-1.4-41.6-17.8l-37.6-94 49.2-49.2z" } }, "free": ["solid"] }, "people-group": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["family", "group", "team"] }, "styles": ["solid"], "unicode": "e533", "label": "People Group", "voted": false, "svg": { "solid": { "last_modified": 1684767533, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M72 88a56 56 0 1 1 112 0A56 56 0 1 1 72 88zM64 245.7C54 256.9 48 271.8 48 288s6 31.1 16 42.3V245.7zm144.4-49.3C178.7 222.7 160 261.2 160 304c0 34.3 12 65.8 32 90.5V416c0 17.7-14.3 32-32 32H96c-17.7 0-32-14.3-32-32V389.2C26.2 371.2 0 332.7 0 288c0-61.9 50.1-112 112-112h32c24 0 46.2 7.5 64.4 20.3zM448 416V394.5c20-24.7 32-56.2 32-90.5c0-42.8-18.7-81.3-48.4-107.7C449.8 183.5 472 176 496 176h32c61.9 0 112 50.1 112 112c0 44.7-26.2 83.2-64 101.2V416c0 17.7-14.3 32-32 32H480c-17.7 0-32-14.3-32-32zm8-328a56 56 0 1 1 112 0A56 56 0 1 1 456 88zM576 245.7v84.7c10-11.3 16-26.1 16-42.3s-6-31.1-16-42.3zM320 32a64 64 0 1 1 0 128 64 64 0 1 1 0-128zM240 304c0 16.2 6 31 16 42.3V261.7c-10 11.3-16 26.1-16 42.3zm144-42.3v84.7c10-11.3 16-26.1 16-42.3s-6-31.1-16-42.3zM448 304c0 44.7-26.2 83.2-64 101.2V448c0 17.7-14.3 32-32 32H288c-17.7 0-32-14.3-32-32V405.2c-37.8-18-64-56.5-64-101.2c0-61.9 50.1-112 112-112h32c61.9 0 112 50.1 112 112z" } }, "free": ["solid"] }, "people-line": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["group", "need"] }, "styles": ["solid"], "unicode": "e534", "label": "People Line", "voted": false, "svg": { "solid": { "last_modified": 1684767533, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M360 72a40 40 0 1 0 -80 0 40 40 0 1 0 80 0zM144 208a40 40 0 1 0 0-80 40 40 0 1 0 0 80zM32 416c-17.7 0-32 14.3-32 32s14.3 32 32 32H608c17.7 0 32-14.3 32-32s-14.3-32-32-32H32zM496 208a40 40 0 1 0 0-80 40 40 0 1 0 0 80zM200 313.5l26.9 49.9c6.3 11.7 20.8 16 32.5 9.8s16-20.8 9.8-32.5l-36.3-67.5c1.7-1.7 3.2-3.6 4.3-5.8L264 217.5V272c0 17.7 14.3 32 32 32h48c17.7 0 32-14.3 32-32V217.5l26.9 49.9c1.2 2.2 2.6 4.1 4.3 5.8l-36.3 67.5c-6.3 11.7-1.9 26.2 9.8 32.5s26.2 1.9 32.5-9.8L440 313.5V352c0 17.7 14.3 32 32 32h48c17.7 0 32-14.3 32-32V313.5l26.9 49.9c6.3 11.7 20.8 16 32.5 9.8s16-20.8 9.8-32.5l-37.9-70.3c-15.3-28.5-45.1-46.3-77.5-46.3H486.2c-16.3 0-31.9 4.5-45.4 12.6l-33.6-62.3c-15.3-28.5-45.1-46.3-77.5-46.3H310.2c-32.4 0-62.1 17.8-77.5 46.3l-33.6 62.3c-13.5-8.1-29.1-12.6-45.4-12.6H134.2c-32.4 0-62.1 17.8-77.5 46.3L18.9 340.6c-6.3 11.7-1.9 26.2 9.8 32.5s26.2 1.9 32.5-9.8L88 313.5V352c0 17.7 14.3 32 32 32h48c17.7 0 32-14.3 32-32V313.5z" } }, "free": ["solid"] }, "people-pulling": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["forced return", "yanking"] }, "styles": ["solid"], "unicode": "e535", "label": "People Pulling", "voted": false, "svg": { "solid": { "last_modified": 1684767532, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M80 96A48 48 0 1 0 80 0a48 48 0 1 0 0 96zM64 128c-35.3 0-64 28.7-64 64V320c0 17.7 14.3 32 32 32c9.8 0 18.5-4.4 24.4-11.2L80.4 485.3c2.9 17.4 19.4 29.2 36.8 26.3s29.2-19.4 26.3-36.8L123.1 352h15.7l30 134.9c3.8 17.3 20.9 28.1 38.2 24.3s28.1-20.9 24.3-38.2l-57.3-258 116.3 53.8c.5 .3 1.1 .5 1.6 .7c8.6 3.6 18 3.1 25.9-.7c3.4-1.6 6.6-3.9 9.3-6.7c3.1-3.2 5.5-7 7.1-11.4c.1-.3 .2-.7 .3-1l2.5-7.5c5.7-17.1 18.3-30.9 34.7-38.2l8-3.5c1-.4 1.9-.8 2.9-1.2l-16.9 63.5c-5.6 21.1-.1 43.6 14.7 59.7l70.7 77.1 22 88.1c4.3 17.1 21.7 27.6 38.8 23.3s27.6-21.7 23.3-38.8l-23-92.1c-1.9-7.8-5.8-14.9-11.2-20.8l-49.5-54 19.3-65.5 9.6 23c4.4 10.6 12.5 19.3 22.8 24.5l26.7 13.3c15.8 7.9 35 1.5 42.9-14.3s1.5-35-14.3-42.9L537 232.7l-15.3-36.8C504.5 154.8 464.3 128 419.7 128c-22.8 0-45.3 4.8-66.1 14l-8 3.5c-24.4 10.9-44.6 29-58.1 51.6L157.3 136.9C144.7 131 130.9 128 117 128H64zM464 96a48 48 0 1 0 0-96 48 48 0 1 0 0 96zM349.7 335.6l-25 62.4-59.4 59.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L372.3 441c4.6-4.6 8.2-10.1 10.6-16.1l14.5-36.2-40.7-44.4c-2.5-2.7-4.8-5.6-7-8.6z" } }, "free": ["solid"] }, "people-robbery": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["criminal", "hands up", "looting", "robbery", "steal"] }, "styles": ["solid"], "unicode": "e536", "label": "People Robbery", "voted": false, "svg": { "solid": { "last_modified": 1684767533, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M488.2 59.1C478.1 99.6 441.7 128 400 128s-78.1-28.4-88.2-68.9L303 24.2C298.8 7.1 281.4-3.3 264.2 1S236.7 22.6 241 39.8l8.7 34.9c11 44 40.2 79.6 78.3 99.6V480c0 17.7 14.3 32 32 32s32-14.3 32-32V352h16V480c0 17.7 14.3 32 32 32s32-14.3 32-32V174.3c38.1-20 67.3-55.6 78.3-99.6L559 39.8c4.3-17.1-6.1-34.5-23.3-38.8S501.2 7.1 497 24.2l-8.7 34.9zM400 96a48 48 0 1 0 0-96 48 48 0 1 0 0 96zM80 96A48 48 0 1 0 80 0a48 48 0 1 0 0 96zm-8 32c-35.3 0-64 28.7-64 64v96l0 .6V480c0 17.7 14.3 32 32 32s32-14.3 32-32V352H88V480c0 17.7 14.3 32 32 32s32-14.3 32-32V252.7l13 20.5c5.9 9.2 16.1 14.9 27 14.9h48c17.7 0 32-14.3 32-32s-14.3-32-32-32H209.6l-37.4-58.9C157.6 142 132.1 128 104.7 128H72z" } }, "free": ["solid"] }, "people-roof": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["family", "group", "manage", "people", "safe", "shelter"] }, "styles": ["solid"], "unicode": "e537", "label": "People Roof", "voted": false, "svg": { "solid": { "last_modified": 1684767533, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M335.5 4l288 160c15.4 8.6 21 28.1 12.4 43.5s-28.1 21-43.5 12.4L320 68.6 47.5 220c-15.4 8.6-34.9 3-43.5-12.4s-3-34.9 12.4-43.5L304.5 4c9.7-5.4 21.4-5.4 31.1 0zM320 160a40 40 0 1 1 0 80 40 40 0 1 1 0-80zM144 256a40 40 0 1 1 0 80 40 40 0 1 1 0-80zm312 40a40 40 0 1 1 80 0 40 40 0 1 1 -80 0zM226.9 491.4L200 441.5V480c0 17.7-14.3 32-32 32H120c-17.7 0-32-14.3-32-32V441.5L61.1 491.4c-6.3 11.7-20.8 16-32.5 9.8s-16-20.8-9.8-32.5l37.9-70.3c15.3-28.5 45.1-46.3 77.5-46.3h19.5c16.3 0 31.9 4.5 45.4 12.6l33.6-62.3c15.3-28.5 45.1-46.3 77.5-46.3h19.5c32.4 0 62.1 17.8 77.5 46.3l33.6 62.3c13.5-8.1 29.1-12.6 45.4-12.6h19.5c32.4 0 62.1 17.8 77.5 46.3l37.9 70.3c6.3 11.7 1.9 26.2-9.8 32.5s-26.2 1.9-32.5-9.8L552 441.5V480c0 17.7-14.3 32-32 32H472c-17.7 0-32-14.3-32-32V441.5l-26.9 49.9c-6.3 11.7-20.8 16-32.5 9.8s-16-20.8-9.8-32.5l36.3-67.5c-1.7-1.7-3.2-3.6-4.3-5.8L376 345.5V400c0 17.7-14.3 32-32 32H296c-17.7 0-32-14.3-32-32V345.5l-26.9 49.9c-1.2 2.2-2.6 4.1-4.3 5.8l36.3 67.5c6.3 11.7 1.9 26.2-9.8 32.5s-26.2 1.9-32.5-9.8z" } }, "free": ["solid"] }, "pepper-hot": { "aliases": { "unicodes": { "composite": ["1f336"], "secondary": ["10f816"] } }, "changes": ["5.7.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "buffalo wings", "capsicum", "chili", "chilli", "habanero", "hot", "hot pepper", "jalapeno", "mexican", "pepper", "spicy", "tabasco", "vegetable" ] }, "styles": ["solid"], "unicode": "f816", "label": "Pepper Hot", "voted": true, "svg": { "solid": { "last_modified": 1684767420, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M428.3 3c11.6-6.4 26.2-2.3 32.6 9.3l4.8 8.7c19.3 34.7 19.8 75.7 3.4 110C495.8 159.6 512 197.9 512 240c0 18.5-3.1 36.3-8.9 52.8c-6.1 17.3-28.5 16.3-36.8-.1l-11.7-23.4c-4.1-8.1-12.4-13.3-21.5-13.3H360c-13.3 0-24-10.7-24-24V152c0-13.3-10.7-24-24-24l-17.1 0c-21.3 0-30-23.9-10.8-32.9C304.7 85.4 327.7 80 352 80c28.3 0 54.8 7.3 77.8 20.2c5.5-18.2 3.7-38.4-6-55.8L419 35.7c-6.4-11.6-2.3-26.2 9.3-32.6zM171.2 345.5L264 160l40 0v80c0 26.5 21.5 48 48 48h76.2l23.9 47.8C372.3 443.9 244.3 512 103.2 512H44.4C19.9 512 0 492.1 0 467.6c0-20.8 14.5-38.8 34.8-43.3l49.8-11.1c37.6-8.4 69.5-33.2 86.7-67.7z" } }, "free": ["solid"] }, "perbyte": { "changes": ["5.15.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e083", "label": "PerByte", "voted": false, "svg": { "brands": { "last_modified": 1660014462, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M305.314,284.578H246.6V383.3h58.711q24.423,0,38.193-13.77t13.77-36.11q0-21.826-14.032-35.335T305.314,284.578ZM149.435,128.7H90.724v98.723h58.711q24.42,0,38.19-13.773t13.77-36.107q0-21.826-14.029-35.338T149.435,128.7ZM366.647,32H81.353A81.445,81.445,0,0,0,0,113.352V398.647A81.445,81.445,0,0,0,81.353,480H366.647A81.445,81.445,0,0,0,448,398.647V113.352A81.445,81.445,0,0,0,366.647,32Zm63.635,366.647a63.706,63.706,0,0,1-63.635,63.635H81.353a63.706,63.706,0,0,1-63.635-63.635V113.352A63.706,63.706,0,0,1,81.353,49.718H366.647a63.706,63.706,0,0,1,63.635,63.634ZM305.314,128.7H246.6v98.723h58.711q24.423,0,38.193-13.773t13.77-36.107q0-21.826-14.032-35.338T305.314,128.7Z" } }, "free": ["brands"] }, "percent": { "aliases": { "names": ["percentage"], "unicodes": { "composite": ["f295", "f541"], "primary": ["f295", "f541"], "secondary": ["1025", "10f295", "10f541"] } }, "changes": ["4.5.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "Percent Sign", "discount", "fraction", "proportion", "rate", "ratio" ] }, "styles": ["solid"], "unicode": "25", "label": "Percent", "voted": true, "svg": { "solid": { "last_modified": 1684767244, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M374.6 118.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-320 320c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l320-320zM128 128A64 64 0 1 0 0 128a64 64 0 1 0 128 0zM384 384a64 64 0 1 0 -128 0 64 64 0 1 0 128 0z" } }, "free": ["solid"] }, "periscope": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3da", "label": "Periscope", "voted": false, "svg": { "brands": { "last_modified": 1660014469, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M370 63.6C331.4 22.6 280.5 0 226.6 0 111.9 0 18.5 96.2 18.5 214.4c0 75.1 57.8 159.8 82.7 192.7C137.8 455.5 192.6 512 226.6 512c41.6 0 112.9-94.2 120.9-105 24.6-33.1 82-118.3 82-192.6 0-56.5-21.1-110.1-59.5-150.8zM226.6 493.9c-42.5 0-190-167.3-190-279.4 0-107.4 83.9-196.3 190-196.3 100.8 0 184.7 89 184.7 196.3.1 112.1-147.4 279.4-184.7 279.4zM338 206.8c0 59.1-51.1 109.7-110.8 109.7-100.6 0-150.7-108.2-92.9-181.8v.4c0 24.5 20.1 44.4 44.8 44.4 24.7 0 44.8-19.9 44.8-44.4 0-18.2-11.1-33.8-26.9-40.7 76.6-19.2 141 39.3 141 112.4z" } }, "free": ["brands"] }, "person": { "aliases": { "names": ["male"], "unicodes": { "composite": ["1f9cd"], "secondary": ["10f183"] } }, "changes": [ "3.2.0", "5.0.0", "6.0.0-beta1", "6.1.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["man", "person standing", "stand", "standing", "woman"] }, "styles": ["solid"], "unicode": "f183", "label": "Person", "voted": false, "svg": { "solid": { "last_modified": 1684767533, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M112 48a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zm40 304V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V256.9L59.4 304.5c-9.1 15.1-28.8 20-43.9 10.9s-20-28.8-10.9-43.9l58.3-97c17.4-28.9 48.6-46.6 82.3-46.6h29.7c33.7 0 64.9 17.7 82.3 46.6l58.3 97c9.1 15.1 4.2 34.8-10.9 43.9s-34.8 4.2-43.9-10.9L232 256.9V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V352H152z" } }, "free": ["solid"] }, "person-arrow-down-to-line": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["ground", "indigenous", "native"] }, "styles": ["solid"], "unicode": "e538", "label": "Person Arrow Down To Line", "voted": false, "svg": { "solid": { "last_modified": 1684767531, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M192 96a48 48 0 1 0 0-96 48 48 0 1 0 0 96zm-8 352V352h16v96H184zm-64 0H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H152h80H608c17.7 0 32-14.3 32-32s-14.3-32-32-32H264V256.9l28.6 47.5c9.1 15.1 28.8 20 43.9 10.9s20-28.8 10.9-43.9l-58.3-97c-17.4-28.9-48.6-46.6-82.3-46.6H177.1c-33.7 0-64.9 17.7-82.3 46.6l-58.3 97c-9.1 15.1-4.2 34.8 10.9 43.9s34.8 4.2 43.9-10.9L120 256.9V448zM464 64V306.7l-25.4-25.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l80 80c12.5 12.5 32.8 12.5 45.3 0l80-80c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L528 306.7V64c0-17.7-14.3-32-32-32s-32 14.3-32 32z" } }, "free": ["solid"] }, "person-arrow-up-from-line": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["population", "rise"] }, "styles": ["solid"], "unicode": "e539", "label": "Person Arrow Up From Line", "voted": false, "svg": { "solid": { "last_modified": 1684767533, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M192 96a48 48 0 1 0 0-96 48 48 0 1 0 0 96zm-8 352V352h16v96H184zm-64 0H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H152h80H608c17.7 0 32-14.3 32-32s-14.3-32-32-32H264V256.9l28.6 47.5c9.1 15.1 28.8 20 43.9 10.9s20-28.8 10.9-43.9l-58.3-97c-17.4-28.9-48.6-46.6-82.3-46.6H177.1c-33.7 0-64.9 17.7-82.3 46.6l-58.3 97c-9.1 15.1-4.2 34.8 10.9 43.9s34.8 4.2 43.9-10.9L120 256.9V448zM598.6 121.4l-80-80c-12.5-12.5-32.8-12.5-45.3 0l-80 80c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L464 141.3 464 384c0 17.7 14.3 32 32 32s32-14.3 32-32V141.3l25.4 25.4c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3z" } }, "free": ["solid"] }, "person-biking": { "aliases": { "names": ["biking"], "unicodes": { "composite": ["1f6b4"], "secondary": ["10f84a"] } }, "changes": [ "5.9.0", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "bicycle", "bike", "biking", "cyclist", "pedal", "person biking", "summer", "wheel" ] }, "styles": ["solid"], "unicode": "f84a", "label": "Person Biking", "voted": false, "svg": { "solid": { "last_modified": 1684767649, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M400 96a48 48 0 1 0 0-96 48 48 0 1 0 0 96zm27.2 64l-61.8-48.8c-17.3-13.6-41.7-13.8-59.1-.3l-83.1 64.2c-30.7 23.8-28.5 70.8 4.3 91.6L288 305.1V416c0 17.7 14.3 32 32 32s32-14.3 32-32V288c0-10.7-5.3-20.7-14.2-26.6L295 232.9l60.3-48.5L396 217c5.7 4.5 12.7 7 20 7h64c17.7 0 32-14.3 32-32s-14.3-32-32-32H427.2zM56 384a72 72 0 1 1 144 0A72 72 0 1 1 56 384zm200 0A128 128 0 1 0 0 384a128 128 0 1 0 256 0zm184 0a72 72 0 1 1 144 0 72 72 0 1 1 -144 0zm200 0a128 128 0 1 0 -256 0 128 128 0 1 0 256 0z" } }, "free": ["solid"] }, "person-booth": { "aliases": { "unicodes": { "secondary": ["10f756"] } }, "changes": ["5.5.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["changing room", "curtain", "vote", "voting"] }, "styles": ["solid"], "unicode": "f756", "label": "Person Booth", "voted": false, "svg": { "solid": { "last_modified": 1684767532, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M256 32c0-17.7-14.3-32-32-32s-32 14.3-32 32V192h64V32zm320 0c0-17.7-14.3-32-32-32s-32 14.3-32 32V480c0 17.7 14.3 32 32 32s32-14.3 32-32V32zM224 512c17.7 0 32-14.3 32-32V320H192V480c0 17.7 14.3 32 32 32zM320 0c-9.3 0-18.1 4-24.2 11s-8.8 16.3-7.5 25.5l31.2 218.6L288.6 409.7c-3.5 17.3 7.8 34.2 25.1 37.7s34.2-7.8 37.7-25.1l.7-3.6c1.3 16.4 15.1 29.4 31.9 29.4c17.7 0 32-14.3 32-32c0 17.7 14.3 32 32 32s32-14.3 32-32V32c0-17.7-14.3-32-32-32H320zM112 80A48 48 0 1 0 16 80a48 48 0 1 0 96 0zm0 261.3V269.3l4.7 4.7c9 9 21.2 14.1 33.9 14.1H224c17.7 0 32-14.3 32-32s-14.3-32-32-32H157.3l-41.6-41.6c-14.3-14.3-33.8-22.4-54-22.4C27.6 160 0 187.6 0 221.6v55.7l0 .9V480c0 17.7 14.3 32 32 32s32-14.3 32-32V384l32 42.7V480c0 17.7 14.3 32 32 32s32-14.3 32-32V421.3c0-10.4-3.4-20.5-9.6-28.8L112 341.3z" } }, "free": ["solid"] }, "person-breastfeeding": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["baby", "child", "infant", "mother", "nutrition", "sustenance"] }, "styles": ["solid"], "unicode": "e53a", "label": "Person Breastfeeding", "voted": false, "svg": { "solid": { "last_modified": 1684767532, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M224 0a80 80 0 1 1 0 160A80 80 0 1 1 224 0zM436.8 382.8L373.5 462c-16.6 20.7-46.8 24.1-67.5 7.5c-17.6-14.1-22.7-38.1-13.5-57.7l-.8-.1c-38.9-5.6-74.3-25.1-99.7-54.8V320c0-17.7-14.3-32-32-32s-32 14.3-32 32v48c0 .8 0 1.6 .1 2.4l101.4 50.7c23.7 11.9 33.3 40.7 21.5 64.4s-40.7 33.3-64.4 21.5L27.2 427.3c-1.1-.5-2.2-1.1-3.3-1.7c-4.9-2.8-9.2-6.4-12.6-10.6c-4.6-5.4-7.8-11.7-9.6-18.4c-3.3-12-1.9-25.2 4.8-36.6c.6-1.1 1.3-2.2 2-3.2L75.6 256.1c26.7-40.1 71.7-64.1 119.8-64.1h75.2c46.5 0 90.1 22.5 117.2 60.3l50.7 70.9c2.2 3 4 6.1 5.5 9.4c2.9 6.7 4.3 13.8 4 20.8c-.3 10.6-4.2 21-11.2 29.4zM320 332a44 44 0 1 0 -88 0 44 44 0 1 0 88 0z" } }, "free": ["solid"] }, "person-burst": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["abuse", "accident", "crash", "explode", "violence"] }, "styles": ["solid"], "unicode": "e53b", "label": "Person Burst", "voted": false, "svg": { "solid": { "last_modified": 1684767531, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M480 96a48 48 0 1 0 0-96 48 48 0 1 0 0 96zm-8 384V352h16V480c0 17.7 14.3 32 32 32s32-14.3 32-32V256.9l28.6 47.5c9.1 15.1 28.8 20 43.9 10.9s20-28.8 10.9-43.9l-58.3-97c-17.4-28.9-48.6-46.6-82.3-46.6H465.1c-33.7 0-64.9 17.7-82.3 46.6l-58.3 97c-9.1 15.1-4.2 34.8 10.9 43.9s34.8 4.2 43.9-10.9L408 256.9V480c0 17.7 14.3 32 32 32s32-14.3 32-32zM190.9 18.1C188.4 12 182.6 8 176 8s-12.4 4-14.9 10.1l-29.4 74L55.6 68.9c-6.3-1.9-13.1 .2-17.2 5.3s-4.6 12.2-1.4 17.9l39.5 69.1L10.9 206.4c-5.4 3.7-8 10.3-6.5 16.7s6.7 11.2 13.1 12.2l78.7 12.2L90.6 327c-.5 6.5 3.1 12.7 9 15.5s12.9 1.8 17.8-2.6L176 286.1l58.6 53.9c4.8 4.4 11.9 5.5 17.8 2.6s9.5-9 9-15.5l-5.6-79.4 50.5-7.8 24.4-40.5-55.2-38L315 92.2c3.3-5.7 2.7-12.8-1.4-17.9s-10.9-7.2-17.2-5.3L220.3 92.1l-29.4-74z" } }, "free": ["solid"] }, "person-cane": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["aging", "cane", "elderly", "old", "staff"] }, "styles": ["solid"], "unicode": "e53c", "label": "Person Cane", "voted": false, "svg": { "solid": { "last_modified": 1684767532, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M272 48a48 48 0 1 0 -96 0 48 48 0 1 0 96 0zm-8 187.3l47.4 57.1c11.3 13.6 31.5 15.5 45.1 4.2s15.5-31.5 4.2-45.1l-73.7-88.9c-18.2-22-45.3-34.7-73.9-34.7H177.1c-33.7 0-64.9 17.7-82.3 46.6l-58.3 97c-9.1 15.1-4.2 34.8 10.9 43.9s34.8 4.2 43.9-10.9L120 256.9V480c0 17.7 14.3 32 32 32s32-14.3 32-32V352h16V480c0 17.7 14.3 32 32 32s32-14.3 32-32V235.3zM352 376c0-4.4 3.6-8 8-8s8 3.6 8 8V488c0 13.3 10.7 24 24 24s24-10.7 24-24V376c0-30.9-25.1-56-56-56s-56 25.1-56 56v8c0 13.3 10.7 24 24 24s24-10.7 24-24v-8z" } }, "free": ["solid"] }, "person-chalkboard": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "blackboard", "instructor", "keynote", "lesson", "presentation", "teacher" ] }, "styles": ["solid"], "unicode": "e53d", "label": "Person Chalkboard", "voted": false, "svg": { "solid": { "last_modified": 1684767532, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M192 96a48 48 0 1 0 0-96 48 48 0 1 0 0 96zm-8 384V352h16V480c0 17.7 14.3 32 32 32s32-14.3 32-32V192h56 64 16c17.7 0 32-14.3 32-32s-14.3-32-32-32H384V64H576V256H384V224H320v48c0 26.5 21.5 48 48 48H592c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48H368c-26.5 0-48 21.5-48 48v80H243.1 177.1c-33.7 0-64.9 17.7-82.3 46.6l-58.3 97c-9.1 15.1-4.2 34.8 10.9 43.9s34.8 4.2 43.9-10.9L120 256.9V480c0 17.7 14.3 32 32 32s32-14.3 32-32z" } }, "free": ["solid"] }, "person-circle-check": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["approved", "not affected", "ok", "okay"] }, "styles": ["solid"], "unicode": "e53e", "label": "Person Circle Check", "voted": false, "svg": { "solid": { "last_modified": 1684767531, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M112 48a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zm40 304V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V256.9L59.4 304.5c-9.1 15.1-28.8 20-43.9 10.9s-20-28.8-10.9-43.9l58.3-97c17.4-28.9 48.6-46.6 82.3-46.6h29.7c33.7 0 64.9 17.7 82.3 46.6l44.9 74.7c-16.1 17.6-28.6 38.5-36.6 61.5c-1.9-1.8-3.5-3.9-4.9-6.3L232 256.9V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V352H152zm136 16a144 144 0 1 1 288 0 144 144 0 1 1 -288 0zm211.3-43.3c-6.2-6.2-16.4-6.2-22.6 0L416 385.4l-28.7-28.7c-6.2-6.2-16.4-6.2-22.6 0s-6.2 16.4 0 22.6l40 40c6.2 6.2 16.4 6.2 22.6 0l72-72c6.2-6.2 6.2-16.4 0-22.6z" } }, "free": ["solid"] }, "person-circle-exclamation": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["affected", "alert", "lost", "missing"] }, "styles": ["solid"], "unicode": "e53f", "label": "Person Circle Exclamation", "voted": false, "svg": { "solid": { "last_modified": 1684767531, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M112 48a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zm40 304V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V256.9L59.4 304.5c-9.1 15.1-28.8 20-43.9 10.9s-20-28.8-10.9-43.9l58.3-97c17.4-28.9 48.6-46.6 82.3-46.6h29.7c33.7 0 64.9 17.7 82.3 46.6l44.9 74.7c-16.1 17.6-28.6 38.5-36.6 61.5c-1.9-1.8-3.5-3.9-4.9-6.3L232 256.9V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V352H152zM432 224a144 144 0 1 1 0 288 144 144 0 1 1 0-288zm0 240a24 24 0 1 0 0-48 24 24 0 1 0 0 48zm0-192c-8.8 0-16 7.2-16 16v80c0 8.8 7.2 16 16 16s16-7.2 16-16V288c0-8.8-7.2-16-16-16z" } }, "free": ["solid"] }, "person-circle-minus": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["delete", "remove"] }, "styles": ["solid"], "unicode": "e540", "label": "Person Circle Minus", "voted": false, "svg": { "solid": { "last_modified": 1684767532, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M112 48a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zm40 304V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V256.9L59.4 304.5c-9.1 15.1-28.8 20-43.9 10.9s-20-28.8-10.9-43.9l58.3-97c17.4-28.9 48.6-46.6 82.3-46.6h29.7c33.7 0 64.9 17.7 82.3 46.6l44.9 74.7c-16.1 17.6-28.6 38.5-36.6 61.5c-1.9-1.8-3.5-3.9-4.9-6.3L232 256.9V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V352H152zm136 16a144 144 0 1 1 288 0 144 144 0 1 1 -288 0zm224 0c0-8.8-7.2-16-16-16H368c-8.8 0-16 7.2-16 16s7.2 16 16 16H496c8.8 0 16-7.2 16-16z" } }, "free": ["solid"] }, "person-circle-plus": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["add", "found"] }, "styles": ["solid"], "unicode": "e541", "label": "Person Circle Plus", "voted": false, "svg": { "solid": { "last_modified": 1684767532, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M112 48a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zm40 304V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V256.9L59.4 304.5c-9.1 15.1-28.8 20-43.9 10.9s-20-28.8-10.9-43.9l58.3-97c17.4-28.9 48.6-46.6 82.3-46.6h29.7c33.7 0 64.9 17.7 82.3 46.6l44.9 74.7c-16.1 17.6-28.6 38.5-36.6 61.5c-1.9-1.8-3.5-3.9-4.9-6.3L232 256.9V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V352H152zM432 224a144 144 0 1 1 0 288 144 144 0 1 1 0-288zm16 80c0-8.8-7.2-16-16-16s-16 7.2-16 16v48H368c-8.8 0-16 7.2-16 16s7.2 16 16 16h48v48c0 8.8 7.2 16 16 16s16-7.2 16-16V384h48c8.8 0 16-7.2 16-16s-7.2-16-16-16H448V304z" } }, "free": ["solid"] }, "person-circle-question": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["lost", "missing"] }, "styles": ["solid"], "unicode": "e542", "label": "Person Circle Question", "voted": false, "svg": { "solid": { "last_modified": 1684767532, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M112 48a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zm40 304V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V256.9L59.4 304.5c-9.1 15.1-28.8 20-43.9 10.9s-20-28.8-10.9-43.9l58.3-97c17.4-28.9 48.6-46.6 82.3-46.6h29.7c33.7 0 64.9 17.7 82.3 46.6l44.9 74.7c-16.1 17.6-28.6 38.5-36.6 61.5c-1.9-1.8-3.5-3.9-4.9-6.3L232 256.9V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V352H152zM432 224a144 144 0 1 1 0 288 144 144 0 1 1 0-288zm0 240a24 24 0 1 0 0-48 24 24 0 1 0 0 48zM368 321.6V328c0 8.8 7.2 16 16 16s16-7.2 16-16v-6.4c0-5.3 4.3-9.6 9.6-9.6h40.5c7.7 0 13.9 6.2 13.9 13.9c0 5.2-2.9 9.9-7.4 12.3l-32 16.8c-5.3 2.8-8.6 8.2-8.6 14.2V384c0 8.8 7.2 16 16 16s16-7.2 16-16v-5.1l23.5-12.3c15.1-7.9 24.5-23.6 24.5-40.6c0-25.4-20.6-45.9-45.9-45.9H409.6c-23 0-41.6 18.6-41.6 41.6z" } }, "free": ["solid"] }, "person-circle-xmark": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["dead", "removed"] }, "styles": ["solid"], "unicode": "e543", "label": "Person Circle Xmark", "voted": false, "svg": { "solid": { "last_modified": 1684767532, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M112 48a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zm40 304V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V256.9L59.4 304.5c-9.1 15.1-28.8 20-43.9 10.9s-20-28.8-10.9-43.9l58.3-97c17.4-28.9 48.6-46.6 82.3-46.6h29.7c33.7 0 64.9 17.7 82.3 46.6l44.9 74.7c-16.1 17.6-28.6 38.5-36.6 61.5c-1.9-1.8-3.5-3.9-4.9-6.3L232 256.9V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V352H152zM432 224a144 144 0 1 1 0 288 144 144 0 1 1 0-288zm59.3 107.3c6.2-6.2 6.2-16.4 0-22.6s-16.4-6.2-22.6 0L432 345.4l-36.7-36.7c-6.2-6.2-16.4-6.2-22.6 0s-6.2 16.4 0 22.6L409.4 368l-36.7 36.7c-6.2 6.2-6.2 16.4 0 22.6s16.4 6.2 22.6 0L432 390.6l36.7 36.7c6.2 6.2 16.4 6.2 22.6 0s6.2-16.4 0-22.6L454.6 368l36.7-36.7z" } }, "free": ["solid"] }, "person-digging": { "aliases": { "names": ["digging"], "unicodes": { "secondary": ["10f85e"] } }, "changes": ["5.9.0", "6.0.0-beta1", "6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["bury", "construction", "debris", "dig", "men at work"] }, "styles": ["solid"], "unicode": "f85e", "label": "Person Digging", "voted": false, "svg": { "solid": { "last_modified": 1684767532, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M208 64a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zM9.8 214.8c5.1-12.2 19.1-18 31.4-12.9L60.7 210l22.9-38.1C99.9 144.6 129.3 128 161 128c51.4 0 97 32.9 113.3 81.7l34.6 103.7 79.3 33.1 34.2-45.6c6.4-8.5 16.6-13.3 27.2-12.8s20.3 6.4 25.8 15.5l96 160c5.9 9.9 6.1 22.2 .4 32.2s-16.3 16.2-27.8 16.2H288c-11.1 0-21.4-5.7-27.2-15.2s-6.4-21.2-1.4-31.1l16-32c5.4-10.8 16.5-17.7 28.6-17.7h32l22.5-30L22.8 246.2c-12.2-5.1-18-19.1-12.9-31.4zm82.8 91.8l112 48c11.8 5 19.4 16.6 19.4 29.4v96c0 17.7-14.3 32-32 32s-32-14.3-32-32V405.1l-60.6-26-37 111c-5.6 16.8-23.7 25.8-40.5 20.2S-3.9 486.6 1.6 469.9l48-144 11-33 32 13.7z" } }, "free": ["solid"] }, "person-dots-from-line": { "aliases": { "names": ["diagnoses"], "unicodes": { "secondary": ["10f470"] } }, "changes": ["5.0.7", "5.7.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["allergy", "diagnosis"] }, "styles": ["solid"], "unicode": "f470", "label": "Person Dots From Line", "voted": false, "svg": { "solid": { "last_modified": 1684767531, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M288 176A88 88 0 1 0 288 0a88 88 0 1 0 0 176zM78.7 372.9c15-12.5 50-34.4 97.3-50.1V432H400V322.7c47.3 15.8 82.3 37.7 97.3 50.1c20.4 17 50.6 14.2 67.6-6.1s14.2-50.6-6.1-67.6c-12-10-30.1-22.5-53.2-35C497.2 278.4 481.7 288 464 288c-26.5 0-48-21.5-48-48c0-4.3 .6-8.4 1.6-12.4C379.1 215.9 335.3 208 288 208c-60.2 0-114.9 12.9-160 29.9c0 .7 0 1.4 0 2.1c0 26.5-21.5 48-48 48c-11.8 0-22.7-4.3-31-11.4c-13.1 8.1-23.7 15.9-31.7 22.5c-20.4 17-23.1 47.2-6.1 67.6s47.2 23.1 67.6 6.1zM24 464c-13.3 0-24 10.7-24 24s10.7 24 24 24H552c13.3 0 24-10.7 24-24s-10.7-24-24-24H24zM224 280a24 24 0 1 1 48 0 24 24 0 1 1 -48 0zm104 56a24 24 0 1 1 0 48 24 24 0 1 1 0-48zM96 240a16 16 0 1 0 -32 0 16 16 0 1 0 32 0zm368 16a16 16 0 1 0 0-32 16 16 0 1 0 0 32z" } }, "free": ["solid"] }, "person-dress": { "aliases": { "names": ["female"], "unicodes": { "secondary": ["10f182"] } }, "changes": [ "3.2.0", "5.0.0", "6.0.0-beta1", "6.1.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["man", "skirt", "woman"] }, "styles": ["solid"], "unicode": "f182", "label": "Person Dress", "voted": false, "svg": { "solid": { "last_modified": 1684767532, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M160 0a48 48 0 1 1 0 96 48 48 0 1 1 0-96zM88 384H70.2c-10.9 0-18.6-10.7-15.2-21.1L93.3 248.1 59.4 304.5c-9.1 15.1-28.8 20-43.9 10.9s-20-28.8-10.9-43.9l53.6-89.2c20.3-33.7 56.7-54.3 96-54.3h11.6c39.3 0 75.7 20.6 96 54.3l53.6 89.2c9.1 15.1 4.2 34.8-10.9 43.9s-34.8 4.2-43.9-10.9l-33.9-56.3L265 362.9c3.5 10.4-4.3 21.1-15.2 21.1H232v96c0 17.7-14.3 32-32 32s-32-14.3-32-32V384H152v96c0 17.7-14.3 32-32 32s-32-14.3-32-32V384z" } }, "free": ["solid"] }, "person-dress-burst": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["abuse", "accident", "crash", "explode", "violence"] }, "styles": ["solid"], "unicode": "e544", "label": "Person Dress Burst", "voted": false, "svg": { "solid": { "last_modified": 1684767532, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M528 48a48 48 0 1 0 -96 0 48 48 0 1 0 96 0zM390.2 384H408v96c0 17.7 14.3 32 32 32s32-14.3 32-32V384h16v96c0 17.7 14.3 32 32 32s32-14.3 32-32V384h17.8c10.9 0 18.6-10.7 15.2-21.1L546.7 248.1l33.9 56.3c9.1 15.1 28.8 20 43.9 10.9s20-28.8 10.9-43.9l-53.6-89.2c-20.2-33.7-56.7-54.3-96-54.3H474.2c-39.3 0-75.7 20.6-96 54.3l-53.6 89.2c-9.1 15.1-4.2 34.8 10.9 43.9s34.8 4.2 43.9-10.9l33.9-56.3L375 362.9c-3.5 10.4 4.3 21.1 15.2 21.1zM190.9 18.1C188.4 12 182.6 8 176 8s-12.4 4-14.9 10.1l-29.4 74L55.6 68.9c-6.3-1.9-13.1 .2-17.2 5.3s-4.6 12.2-1.4 17.9l39.5 69.1L10.9 206.4c-5.4 3.7-8 10.3-6.5 16.7s6.7 11.2 13.1 12.2l78.7 12.2L90.6 327c-.5 6.5 3.1 12.7 9 15.5s12.9 1.8 17.8-2.6L176 286.1l58.6 53.9c4.8 4.4 11.9 5.5 17.8 2.6s9.5-9 9-15.5l-5.6-79.4 50.5-7.8 24.4-40.5-55.2-38L315 92.2c3.3-5.7 2.7-12.8-1.4-17.9s-10.9-7.2-17.2-5.3L220.3 92.1l-29.4-74z" } }, "free": ["solid"] }, "person-drowning": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["drown", "emergency", "swim"] }, "styles": ["solid"], "unicode": "e545", "label": "Person Drowning", "voted": false, "svg": { "solid": { "last_modified": 1684767533, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M192 64c0-17.7-14.3-32-32-32s-32 14.3-32 32V96.2c0 54.1 23.5 104 62.2 138.3l-21 146.7c7.8 2.1 15.5 3.3 22.8 3.3c21.1 0 42-8.5 59.2-20.3c22.1-15.5 51.6-15.5 73.7 0c12.4 8.5 26.1 14.8 39.7 18l17.7-97.6c10.7-1.2 21.3-3.1 31.9-5.5l105-23.9c17.2-3.9 28-21.1 24.1-38.3s-21.1-28-38.3-24.1L400 216.6c-41 9.3-83.7 7.5-123.7-5.2c-50.2-16-84.3-62.6-84.3-115.3V64zM320 192a64 64 0 1 0 0-128 64 64 0 1 0 0 128zM306.5 389.9c-11.1-7.9-25.9-7.9-37 0C247 405.4 219.5 416 192 416c-26.9 0-55.3-10.8-77.4-26.1l0 0c-11.9-8.5-28.1-7.8-39.2 1.7c-14.4 11.9-32.5 21-50.6 25.2c-17.2 4-27.9 21.2-23.9 38.4s21.2 27.9 38.4 23.9c24.5-5.7 44.9-16.5 58.2-25C126.5 469.7 159 480 192 480c31.9 0 60.6-9.9 80.4-18.9c5.8-2.7 11.1-5.3 15.6-7.7c4.5 2.4 9.7 5.1 15.6 7.7c19.8 9 48.5 18.9 80.4 18.9c33 0 65.5-10.3 94.5-25.8c13.4 8.4 33.7 19.3 58.2 25c17.2 4 34.4-6.7 38.4-23.9s-6.7-34.4-23.9-38.4c-18.1-4.2-36.2-13.3-50.6-25.2c-11.1-9.4-27.3-10.1-39.2-1.7l0 0C439.4 405.2 410.9 416 384 416c-27.5 0-55-10.6-77.5-26.1z" } }, "free": ["solid"] }, "person-falling": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["accident", "fall", "trip"] }, "styles": ["solid"], "unicode": "e546", "label": "Person Falling", "voted": false, "svg": { "solid": { "last_modified": 1684767531, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M288 0c17.7 0 32 14.3 32 32l0 9.8c0 54.6-27.9 104.6-72.5 133.6l.2 .3L304.5 256l87.5 0c15.1 0 29.3 7.1 38.4 19.2l43.2 57.6c10.6 14.1 7.7 34.2-6.4 44.8s-34.2 7.7-44.8-6.4L384 320l-96 0h-1.4l92.3 142.6c9.6 14.8 5.4 34.6-9.5 44.3s-34.6 5.4-44.3-9.5L164.5 249.2c-2.9 9.2-4.5 19-4.5 29l0 73.8c0 17.7-14.3 32-32 32s-32-14.3-32-32V278.2c0-65.1 39.6-123.7 100.1-147.9C232.3 115.8 256 80.8 256 41.8l0-9.8c0-17.7 14.3-32 32-32zM112 32a48 48 0 1 1 0 96 48 48 0 1 1 0-96z" } }, "free": ["solid"] }, "person-falling-burst": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["accident", "crash", "death", "fall", "homicide", "murder"] }, "styles": ["solid"], "unicode": "e547", "label": "Person Falling Burst", "voted": false, "svg": { "solid": { "last_modified": 1684767531, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M256 32c0-17.7-14.3-32-32-32s-32 14.3-32 32l0 9.8c0 39-23.7 74-59.9 88.4C71.6 154.5 32 213 32 278.2V352c0 17.7 14.3 32 32 32s32-14.3 32-32l0-73.8c0-10 1.6-19.8 4.5-29L261.1 497.4c9.6 14.8 29.4 19.1 44.3 9.5s19.1-29.4 9.5-44.3L222.6 320H224l80 0 38.4 51.2c10.6 14.1 30.7 17 44.8 6.4s17-30.7 6.4-44.8l-43.2-57.6C341.3 263.1 327.1 256 312 256l-71.5 0-56.8-80.2-.2-.3c44.7-29 72.5-79 72.5-133.6l0-9.8zM96 80A48 48 0 1 0 0 80a48 48 0 1 0 96 0zM464 286.1l58.6 53.9c4.8 4.4 11.9 5.5 17.8 2.6s9.5-9 9-15.5l-5.6-79.4 78.7-12.2c6.5-1 11.7-5.9 13.1-12.2s-1.1-13-6.5-16.7l-65.6-45.1L603 92.2c3.3-5.7 2.7-12.8-1.4-17.9s-10.9-7.2-17.2-5.3L508.3 92.1l-29.4-74C476.4 12 470.6 8 464 8s-12.4 4-14.9 10.1l-29.4 74L343.6 68.9c-6.3-1.9-13.1 .2-17.2 5.3s-4.6 12.2-1.4 17.9l39.5 69.1-65.6 45.1c-5.4 3.7-8 10.3-6.5 16.7c.1 .3 .1 .6 .2 .8l19.4 0c20.1 0 39.2 7.5 53.8 20.8l18.4 2.9L383 265.3l36.2 48.3c2.1 2.8 3.9 5.7 5.5 8.6L464 286.1z" } }, "free": ["solid"] }, "person-half-dress": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["gender", "man", "restroom", "transgender", "woman"] }, "styles": ["solid"], "unicode": "e548", "label": "Person Half Dress", "voted": false, "svg": { "solid": { "last_modified": 1684767533, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M160 0a48 48 0 1 1 0 96 48 48 0 1 1 0-96zm8 352V128h6.9c33.7 0 64.9 17.7 82.3 46.6l58.3 97c9.1 15.1 4.2 34.8-10.9 43.9s-34.8 4.2-43.9-10.9L232 256.9V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V352h0zM58.2 182.3c19.9-33.1 55.3-53.5 93.8-54.3V384h0v96c0 17.7-14.3 32-32 32s-32-14.3-32-32V384H70.2c-10.9 0-18.6-10.7-15.2-21.1L93.3 248.1 59.4 304.5c-9.1 15.1-28.8 20-43.9 10.9s-20-28.8-10.9-43.9l53.6-89.2z" } }, "free": ["solid"] }, "person-harassing": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["abuse", "scream", "shame", "shout", "yell"] }, "styles": ["solid"], "unicode": "e549", "label": "Person Harassing", "voted": false, "svg": { "solid": { "last_modified": 1684767531, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M192 96a48 48 0 1 0 0-96 48 48 0 1 0 0 96zM59.4 304.5L88 256.9V480c0 17.7 14.3 32 32 32s32-14.3 32-32V352h16V480c0 17.7 14.3 32 32 32s32-14.3 32-32V235.3l47.4 57.1c11.3 13.6 31.5 15.5 45.1 4.2s15.5-31.5 4.2-45.1l-73.7-88.9c-18.2-22-45.3-34.7-73.9-34.7H145.1c-33.7 0-64.9 17.7-82.3 46.6l-58.3 97c-9.1 15.1-4.2 34.8 10.9 43.9s34.8 4.2 43.9-10.9zM480 240a48 48 0 1 0 -96 0 48 48 0 1 0 96 0zM464 344v58.7l-41.4-41.4c-7.3-7.3-17.6-10.6-27.8-9s-18.9 8.1-23.5 17.3l-48 96c-7.9 15.8-1.5 35 14.3 42.9s35 1.5 42.9-14.3L408.8 438l54.7 54.7c12.4 12.4 29.1 19.3 46.6 19.3c36.4 0 65.9-29.5 65.9-65.9V344c0-30.9-25.1-56-56-56s-56 25.1-56 56zM288 48c0 8.8 7.2 16 16 16h56c8.8 0 16-7.2 16-16s-7.2-16-16-16H304c-8.8 0-16 7.2-16 16zm-.8 49.7c-7.9-4-17.5-.7-21.5 7.2s-.7 17.5 7.2 21.5l48 24c7.9 4 17.5 .7 21.5-7.2s.7-17.5-7.2-21.5l-48-24z" } }, "free": ["solid"] }, "person-hiking": { "aliases": { "names": ["hiking"], "unicodes": { "secondary": ["10f6ec"] } }, "changes": ["5.4.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "autumn", "fall", "hike", "mountain", "outdoors", "summer", "walk" ] }, "styles": ["solid"], "unicode": "f6ec", "label": "Person Hiking", "voted": false, "svg": { "solid": { "last_modified": 1684767532, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M192 48a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zm51.3 182.7L224.2 307l49.7 49.7c9 9 14.1 21.2 14.1 33.9V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V397.3l-73.9-73.9c-15.8-15.8-22.2-38.6-16.9-60.3l20.4-84c8.3-34.1 42.7-54.9 76.7-46.4c19 4.8 35.6 16.4 46.4 32.7L305.1 208H336V184c0-13.3 10.7-24 24-24s24 10.7 24 24v55.8c0 .1 0 .2 0 .2s0 .2 0 .2V488c0 13.3-10.7 24-24 24s-24-10.7-24-24V272H296.6c-16 0-31-8-39.9-21.4l-13.3-20zM81.1 471.9L117.3 334c3 4.2 6.4 8.2 10.1 11.9l41.9 41.9L142.9 488.1c-4.5 17.1-22 27.3-39.1 22.8s-27.3-22-22.8-39.1zm55.5-346L101.4 266.5c-3 12.1-14.9 19.9-27.2 17.9l-47.9-8c-14-2.3-22.9-16.3-19.2-30L31.9 155c9.5-34.8 41.1-59 77.2-59h4.2c15.6 0 27.1 14.7 23.3 29.8z" } }, "free": ["solid"] }, "person-military-pointing": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["army", "customs", "guard"] }, "styles": ["solid"], "unicode": "e54a", "label": "Person Military Pointing", "voted": false, "svg": { "solid": { "last_modified": 1684767531, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M246.9 14.1C234 15.2 224 26 224 39c0 13.8 11.2 25 25 25H400c8.8 0 16-7.2 16-16V17.4C416 8 408 .7 398.7 1.4L246.9 14.1zM240 112c0 44.2 35.8 80 80 80s80-35.8 80-80c0-5.5-.6-10.8-1.6-16H241.6c-1 5.2-1.6 10.5-1.6 16zM72 224c-22.1 0-40 17.9-40 40s17.9 40 40 40H224v89.4L386.8 230.5c-13.3-4.3-27.3-6.5-41.6-6.5H240 72zm345.7 20.9L246.6 416H416V369.7l53.6 90.6c11.2 19 35.8 25.3 54.8 14.1s25.3-35.8 14.1-54.8L462.3 290.8c-11.2-18.9-26.6-34.5-44.6-45.9zM224 448v32c0 17.7 14.3 32 32 32H384c17.7 0 32-14.3 32-32V448H224z" } }, "free": ["solid"] }, "person-military-rifle": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["armed forces", "army", "military", "rifle", "war"] }, "styles": ["solid"], "unicode": "e54b", "label": "Person Military Rifle", "voted": false, "svg": { "solid": { "last_modified": 1684767532, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M160 39c0-13 10-23.8 22.9-24.9L334.7 1.4C344 .7 352 8 352 17.4V48c0 8.8-7.2 16-16 16H185c-13.8 0-25-11.2-25-25zm17.6 57H334.4c1 5.2 1.6 10.5 1.6 16c0 44.2-35.8 80-80 80s-80-35.8-80-80c0-5.5 .6-10.8 1.6-16zm228 364.3L352 369.7V480c0 1.3-.1 2.5-.2 3.8L177.5 234.9c16.6-7.1 34.6-10.9 53.3-10.9h50.4c15.9 0 31.3 2.8 45.8 7.9L421.9 67.7c-7.7-4.4-10.3-14.2-5.9-21.9s14.2-10.3 21.9-5.9l13.9 8 13.9 8c7.7 4.4 10.3 14.2 5.9 21.9L416 173.9l1.6 .9c15.3 8.8 20.6 28.4 11.7 43.7L392.6 282c2 2.8 3.9 5.8 5.7 8.8l76.1 128.8c11.2 19 4.9 43.5-14.1 54.8s-43.5 4.9-54.8-14.1zM320 512H192c-17.7 0-32-14.3-32-32V369.7l-53.6 90.6c-11.2 19-35.8 25.3-54.8 14.1s-25.3-35.8-14.1-54.8l76.1-128.8c9.4-15.8 21.7-29.3 36-40L331.1 510c-3.5 1.3-7.2 2-11.1 2zM296 320a24 24 0 1 0 0-48 24 24 0 1 0 0 48z" } }, "free": ["solid"] }, "person-military-to-person": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["civilian", "coordination", "military"] }, "styles": ["solid"], "unicode": "e54c", "label": "Person Military To Person", "voted": false, "svg": { "solid": { "last_modified": 1684767532, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M71 12.5c-8.6 1-15 8.2-15 16.8c0 9.3 7.5 16.8 16.7 16.9H184.1c8.8-.1 15.9-7.2 15.9-16V16c0-9.5-8.3-17-17.8-15.9L71 12.5zM189.5 78.1H66.5C64.9 83.8 64 89.8 64 96c0 35.3 28.7 64 64 64s64-28.7 64-64c0-6.2-.9-12.2-2.5-17.9zM32 256v32c0 17.7 14.3 32 32 32H192c1.8 0 3.5-.1 5.2-.4L53 208.6C40.1 220.3 32 237.2 32 256zm190.2 42.5c1.1-3.3 1.8-6.8 1.8-10.5V256c0-35.3-28.7-64-64-64H96c-3.7 0-7.4 .3-10.9 .9L222.2 298.5zM384 160a64 64 0 1 0 0-128 64 64 0 1 0 0 128zm-32 32c-35.3 0-64 28.7-64 64v32c0 17.7 14.3 32 32 32H448c17.7 0 32-14.3 32-32V256c0-35.3-28.7-64-64-64H352zM215.8 450.1c5.2-4.6 8.2-11.1 8.2-18.1s-3-13.5-8.2-18.1l-64-56c-7.1-6.2-17.1-7.7-25.7-3.8S112 366.6 112 376v32l-88 0c-13.3 0-24 10.7-24 24s10.7 24 24 24l88 0v32c0 9.4 5.5 18 14.1 21.9s18.6 2.4 25.7-3.8l64-56zM288 431.9c0 6.9 2.9 13.5 8.1 18.1l64 56.4c7.1 6.2 17.1 7.8 25.7 3.9s14.1-12.4 14.1-21.9l0-32.4 88 0c13.3 0 24-10.7 24-24s-10.7-24-24-24l-88 0 0-32c0-9.4-5.5-18-14.1-21.9s-18.6-2.4-25.7 3.8l-64 56c-5.2 4.5-8.2 11.1-8.2 18z" } }, "free": ["solid"] }, "person-praying": { "aliases": { "names": ["pray"], "unicodes": { "composite": ["1f6d0"], "secondary": ["10f683"] } }, "changes": ["5.3.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["kneel", "place of worship", "religion", "thank", "worship"] }, "styles": ["solid"], "unicode": "f683", "label": "Person Praying", "voted": false, "svg": { "solid": { "last_modified": 1684767531, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M352 64A64 64 0 1 0 224 64a64 64 0 1 0 128 0zM232.7 264l22.9 31.5c6.5 8.9 16.3 14.7 27.2 16.1s21.9-1.7 30.4-8.7l88-72c17.1-14 19.6-39.2 5.6-56.3s-39.2-19.6-56.3-5.6l-55.2 45.2-26.2-36C253.6 156.7 228.6 144 202 144c-30.9 0-59.2 17.1-73.6 44.4L79.8 280.9c-20.2 38.5-9.4 85.9 25.6 111.8L158.6 432H72c-22.1 0-40 17.9-40 40s17.9 40 40 40H280c17.3 0 32.6-11.1 38-27.5s-.3-34.4-14.2-44.7L187.7 354l45-90z" } }, "free": ["solid"] }, "person-pregnant": { "changes": ["6.0.0-beta1", "6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["baby", "birth", "child", "pregnant", "pregnant woman", "woman"] }, "styles": ["solid"], "unicode": "e31e", "label": "Person Pregnant", "voted": false, "svg": { "solid": { "last_modified": 1684767532, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M192 0a48 48 0 1 1 0 96 48 48 0 1 1 0-96zM120 383c-13.8-3.6-24-16.1-24-31V296.9l-4.6 7.6c-9.1 15.1-28.8 20-43.9 10.9s-20-28.8-10.9-43.9l58.3-97c15-24.9 40.3-41.5 68.7-45.6c4.1-.6 8.2-1 12.5-1h1.1 12.5H192c1.4 0 2.8 .1 4.1 .3c35.7 2.9 65.4 29.3 72.1 65l6.1 32.5c44.3 8.6 77.7 47.5 77.7 94.3v32c0 17.7-14.3 32-32 32H304 264v96c0 17.7-14.3 32-32 32s-32-14.3-32-32V384h-8-8v96c0 17.7-14.3 32-32 32s-32-14.3-32-32V383z" } }, "free": ["solid"] }, "person-rays": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["affected", "focus", "shine"] }, "styles": ["solid"], "unicode": "e54d", "label": "Person Rays", "voted": false, "svg": { "solid": { "last_modified": 1684767533, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M208 48a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zm40 304V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V256.9l-28.6 47.5c-9.1 15.1-28.8 20-43.9 10.9s-20-28.8-10.9-43.9l58.3-97c17.4-28.9 48.6-46.6 82.3-46.6h29.7c33.7 0 64.9 17.7 82.3 46.6l58.3 97c9.1 15.1 4.2 34.8-10.9 43.9s-34.8 4.2-43.9-10.9L328 256.9V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V352H248zM7 7C16.4-2.3 31.6-2.3 41 7l80 80c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0L7 41C-2.3 31.6-2.3 16.4 7 7zM471 7c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-80 80c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9L471 7zM7 505c-9.4-9.4-9.4-24.6 0-33.9l80-80c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9L41 505c-9.4 9.4-24.6 9.4-33.9 0zm464 0l-80-80c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l80 80c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0z" } }, "free": ["solid"] }, "person-rifle": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["army", "combatant", "gun", "military", "rifle", "war"] }, "styles": ["solid"], "unicode": "e54e", "label": "Person Rifle", "voted": false, "svg": { "solid": { "last_modified": 1684767532, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M265.2 192c25.4 0 49.8 7.1 70.8 19.9V512H144V337.7L90.4 428.3c-11.2 19-35.8 25.3-54.8 14.1s-25.3-35.8-14.1-54.8L97.7 258.8c24.5-41.4 69-66.8 117.1-66.8h50.4zM160 80a80 80 0 1 1 160 0A80 80 0 1 1 160 80zM448 0c8.8 0 16 7.2 16 16V132.3c9.6 5.5 16 15.9 16 27.7V269.3l16-5.3V208c0-8.8 7.2-16 16-16h16c8.8 0 16 7.2 16 16v84.5c0 6.9-4.4 13-10.9 15.2L480 325.3V352h48c8.8 0 16 7.2 16 16v16c0 8.8-7.2 16-16 16H484l23 92.1c2.5 10.1-5.1 19.9-15.5 19.9H432c-8.8 0-16-7.2-16-16V400H400c-17.7 0-32-14.3-32-32V224c0-17.7 14.3-32 32-32V160c0-11.8 6.4-22.2 16-27.7V32c-8.8 0-16-7.2-16-16s7.2-16 16-16h16 16z" } }, "free": ["solid"] }, "person-running": { "aliases": { "names": ["running"], "unicodes": { "composite": ["1f3c3"], "secondary": ["10f70c"] } }, "changes": ["5.4.0", "5.11.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["exit", "flee", "marathon", "person running", "race", "running"] }, "styles": ["solid"], "unicode": "f70c", "label": "Person Running", "voted": true, "svg": { "solid": { "last_modified": 1684767532, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M320 48a48 48 0 1 0 -96 0 48 48 0 1 0 96 0zM125.7 175.5c9.9-9.9 23.4-15.5 37.5-15.5c1.9 0 3.8 .1 5.6 .3L137.6 254c-9.3 28 1.7 58.8 26.8 74.5l86.2 53.9-25.4 88.8c-4.9 17 5 34.7 22 39.6s34.7-5 39.6-22l28.7-100.4c5.9-20.6-2.6-42.6-20.7-53.9L238 299l30.9-82.4 5.1 12.3C289 264.7 323.9 288 362.7 288H384c17.7 0 32-14.3 32-32s-14.3-32-32-32H362.7c-12.9 0-24.6-7.8-29.5-19.7l-6.3-15c-14.6-35.1-44.1-61.9-80.5-73.1l-48.7-15c-11.1-3.4-22.7-5.2-34.4-5.2c-31 0-60.8 12.3-82.7 34.3L57.4 153.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l23.1-23.1zM91.2 352H32c-17.7 0-32 14.3-32 32s14.3 32 32 32h69.6c19 0 36.2-11.2 43.9-28.5L157 361.6l-9.5-6c-17.5-10.9-30.5-26.8-37.9-44.9L91.2 352z" } }, "free": ["solid"] }, "person-shelter": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["house", "inside", "roof", "safe", "safety", "shelter"] }, "styles": ["solid"], "unicode": "e54f", "label": "Person Shelter", "voted": false, "svg": { "solid": { "last_modified": 1684767532, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M271.9 4.2c-9.8-5.6-21.9-5.6-31.8 0l-224 128C6.2 137.9 0 148.5 0 160V480c0 17.7 14.3 32 32 32s32-14.3 32-32V178.6L256 68.9 448 178.6V480c0 17.7 14.3 32 32 32s32-14.3 32-32V160c0-11.5-6.2-22.1-16.1-27.8l-224-128zM256 208a40 40 0 1 0 0-80 40 40 0 1 0 0 80zm-8 280V400h16v88c0 13.3 10.7 24 24 24s24-10.7 24-24V313.5l26.9 49.9c6.3 11.7 20.8 16 32.5 9.8s16-20.8 9.8-32.5l-37.9-70.3c-15.3-28.5-45.1-46.3-77.5-46.3H246.2c-32.4 0-62.1 17.8-77.5 46.3l-37.9 70.3c-6.3 11.7-1.9 26.2 9.8 32.5s26.2 1.9 32.5-9.8L200 313.5V488c0 13.3 10.7 24 24 24s24-10.7 24-24z" } }, "free": ["solid"] }, "person-skating": { "aliases": { "names": ["skating"], "unicodes": { "secondary": ["10f7c5"] } }, "changes": ["5.6.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["figure skating", "ice", "olympics", "rink", "skate", "winter"] }, "styles": ["solid"], "unicode": "f7c5", "label": "Person Skating", "voted": false, "svg": { "solid": { "last_modified": 1684767532, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M352 48a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zM128 128c0-17.7 14.3-32 32-32H319.4c43.6 0 64.6 53.4 32.8 83.1l-74.4 69.4 60.2 60.2c9 9 14.1 21.2 14.1 33.9V416c0 17.7-14.3 32-32 32s-32-14.3-32-32V349.3l-77.9-77.8c-26.6-26.6-24.6-70.3 4.3-94.4l20.4-17H160c-17.7 0-32-14.3-32-32zM81.4 353.4l86.9-86.9c4.6 10 11 19.3 19.3 27.5l21.8 21.8-82.7 82.7c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3zm322.5 95.1c8.6 2.1 13.8 10.8 11.6 19.4l-.4 1.7c-6.2 24.9-28.6 42.4-54.3 42.4H272c-8.8 0-16-7.2-16-16s7.2-16 16-16h88.8c11 0 20.6-7.5 23.3-18.2l.4-1.7c2.1-8.6 10.8-13.8 19.4-11.6zM135.2 478.3l-6.2 3.1c-21.6 10.8-47.6 6.6-64.6-10.5L4.7 411.3c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0l59.6 59.6c7.3 7.3 18.5 9.1 27.7 4.5l6.2-3.1c7.9-4 17.5-.7 21.5 7.2s.7 17.5-7.2 21.5z" } }, "free": ["solid"] }, "person-skiing": { "aliases": { "names": ["skiing"], "unicodes": { "composite": ["26f7"], "secondary": ["10f7c9"] } }, "changes": ["5.6.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["downhill", "olympics", "ski", "skier", "snow", "winter"] }, "styles": ["solid"], "unicode": "f7c9", "label": "Person Skiing", "voted": false, "svg": { "solid": { "last_modified": 1684767532, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M380.7 48a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zM2.7 268.9c6.1-11.8 20.6-16.3 32.4-10.2L232.7 361.3l46.2-69.2-75.1-75.1c-14.6-14.6-20.4-33.9-18.4-52.1l108.8 52 39.3 39.3c16.2 16.2 18.7 41.5 6 60.6L289.8 391l128.7 66.8c13.6 7.1 29.8 7.2 43.6 .3l15.2-7.6c11.9-5.9 26.3-1.1 32.2 10.7s1.1 26.3-10.7 32.2l-15.2 7.6c-27.5 13.7-59.9 13.5-87.2-.7L12.9 301.3C1.2 295.2-3.4 280.7 2.7 268.9zM118.9 65.6L137 74.2l8.7-17.4c4-7.9 13.6-11.1 21.5-7.2s11.1 13.6 7.2 21.5l-8.5 16.9 54.7 26.2c1.5-.7 3.1-1.4 4.7-2.1l83.4-33.4c34.2-13.7 72.8 4.2 84.5 39.2l17.1 51.2 52.1 26.1c15.8 7.9 22.2 27.1 14.3 42.9s-27.1 22.2-42.9 14.3l-58.1-29c-11.4-5.7-20-15.7-24.1-27.8l-5.8-17.3-27.3 12.1-6.8 3-6.7-3.2L151.5 116.7l-9.2 18.4c-4 7.9-13.6 11.1-21.5 7.2s-11.1-13.6-7.2-21.5l9-18-17.6-8.4c-8-3.8-11.3-13.4-7.5-21.3s13.4-11.3 21.3-7.5z" } }, "free": ["solid"] }, "person-skiing-nordic": { "aliases": { "names": ["skiing-nordic"], "unicodes": { "secondary": ["10f7ca"] } }, "changes": ["5.6.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["cross country", "olympics", "winter"] }, "styles": ["solid"], "unicode": "f7ca", "label": "Person Skiing Nordic", "voted": false, "svg": { "solid": { "last_modified": 1684767532, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M336 96a48 48 0 1 0 0-96 48 48 0 1 0 0 96zM227.2 160c1.9 0 3.8 .1 5.6 .3L201.6 254c-9.3 28 1.7 58.8 26.8 74.5l86.2 53.9L291.3 464H202.8l41.1-88.1-32.4-20.3c-7.8-4.9-14.7-10.7-20.6-17.3L132.2 464H99.7l54.2-257.6c4.6-1.5 9-4.1 12.7-7.8l23.1-23.1c9.9-9.9 23.4-15.5 37.5-15.5zM121.4 198.6c.4 .4 .8 .8 1.3 1.2L67 464H24c-13.3 0-24 10.7-24 24s10.7 24 24 24H159.3c.4 0 .9 0 1.3 0H319.3c.5 0 1 0 1.4 0H504c39.8 0 72-32.2 72-72v-8c0-13.3-10.7-24-24-24s-24 10.7-24 24v8c0 13.3-10.7 24-24 24H434.6l27.6-179.3c10.5-5.2 17.8-16.1 17.8-28.7c0-17.7-14.3-32-32-32H426.7c-12.9 0-24.6-7.8-29.5-19.7l-6.3-15c-14.6-35.1-44.1-61.9-80.5-73.1l-48.7-15c-11.1-3.4-22.7-5.2-34.4-5.2c-31 0-60.8 12.3-82.7 34.3l-23.1 23.1c-12.5 12.5-12.5 32.8 0 45.3zm308 89.4L402.3 464H357.8l21.6-75.6c5.9-20.6-2.6-42.6-20.7-53.9L302 299l30.9-82.4 5.1 12.3C353 264.7 387.9 288 426.7 288h2.7z" } }, "free": ["solid"] }, "person-snowboarding": { "aliases": { "names": ["snowboarding"], "unicodes": { "composite": ["1f3c2"], "secondary": ["10f7ce"] } }, "changes": ["5.6.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["olympics", "ski", "snow", "snowboard", "snowboarder", "winter"] }, "styles": ["solid"], "unicode": "f7ce", "label": "Person Snowboarding", "voted": false, "svg": { "solid": { "last_modified": 1684767531, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M209.7 3.4c15.8-7.9 35-1.5 42.9 14.3l25 50 42.4 8.5c19.5 3.9 37.8 12.3 53.5 24.5l126.1 98.1c14 10.9 16.5 31 5.6 44.9s-31 16.5-44.9 5.6l-72.1-56.1-71.5 31.8 33.1 27.6c23.2 19.3 33.5 50 26.7 79.4l-17.4 75.2c-2.2 9.4-8.2 16.8-16.1 21l86.5 33.1c4.6 1.8 9.4 2.6 14.3 2.6H472c13.3 0 24 10.7 24 24s-10.7 24-24 24H443.8c-10.8 0-21.4-2-31.5-5.8L60.1 371.3c-11.5-4.4-22-11.2-30.8-20L7 329c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l22.4 22.4c4 4 8.7 7.1 14 9.1l22.4 8.6c-.8-1.6-1.5-3.2-2.1-4.9c-5.6-16.8 3.5-34.9 20.2-40.5L192 264.9l0-53.2c0-24.2 13.7-46.4 35.4-57.2l45.2-22.6-7.5-1.5c-19.4-3.9-35.9-16.5-44.7-34.1l-25-50c-7.9-15.8-1.5-35 14.3-42.9zM139 350.1l159 60.9c-2.1-5.6-2.6-11.9-1.1-18.2l17.4-75.2c1.4-5.9-.7-12-5.3-15.9l-52.8-44 0 18.8c0 20.7-13.2 39-32.8 45.5L139 350.1zM432 0a48 48 0 1 1 0 96 48 48 0 1 1 0-96z" } }, "free": ["solid"] }, "person-swimming": { "aliases": { "names": ["swimmer"], "unicodes": { "composite": ["1f3ca"], "secondary": ["10f5c4"] } }, "changes": ["5.1.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["ocean", "person swimming", "pool", "sea", "swim", "water"] }, "styles": ["solid"], "unicode": "f5c4", "label": "Person Swimming", "voted": false, "svg": { "solid": { "last_modified": 1684767531, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M309.5 178.4L447.9 297.1c-1.6 .9-3.2 2-4.8 3c-18 12.4-40.1 20.3-59.2 20.3c-19.6 0-40.8-7.7-59.2-20.3c-22.1-15.5-51.6-15.5-73.7 0c-17.1 11.8-38 20.3-59.2 20.3c-10.1 0-21.1-2.2-31.9-6.2C163.1 193.2 262.2 96 384 96h64c17.7 0 32 14.3 32 32s-14.3 32-32 32H384c-26.9 0-52.3 6.6-74.5 18.4zM160 160A64 64 0 1 1 32 160a64 64 0 1 1 128 0zM306.5 325.9C329 341.4 356.5 352 384 352c26.9 0 55.4-10.8 77.4-26.1l0 0c11.9-8.5 28.1-7.8 39.2 1.7c14.4 11.9 32.5 21 50.6 25.2c17.2 4 27.9 21.2 23.9 38.4s-21.2 27.9-38.4 23.9c-24.5-5.7-44.9-16.5-58.2-25C449.5 405.7 417 416 384 416c-31.9 0-60.6-9.9-80.4-18.9c-5.8-2.7-11.1-5.3-15.6-7.7c-4.5 2.4-9.7 5.1-15.6 7.7c-19.8 9-48.5 18.9-80.4 18.9c-33 0-65.5-10.3-94.5-25.8c-13.4 8.4-33.7 19.3-58.2 25c-17.2 4-34.4-6.7-38.4-23.9s6.7-34.4 23.9-38.4c18.1-4.2 36.2-13.3 50.6-25.2c11.1-9.4 27.3-10.1 39.2-1.7l0 0C136.7 341.2 165.1 352 192 352c27.5 0 55-10.6 77.5-26.1c11.1-7.9 25.9-7.9 37 0z" } }, "free": ["solid"] }, "person-through-window": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "door", "exit", "forced entry", "leave", "robbery", "steal", "window" ] }, "styles": ["solid"], "unicode": "e5a9", "label": "Person Through Window", "voted": false, "svg": { "solid": { "last_modified": 1684767531, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M64 64l224 0 0 9.8c0 39-23.7 74-59.9 88.4C167.6 186.5 128 245 128 310.2l0 73.8s0 0 0 0H64V64zm288 0l224 0V384H508.3l-3.7-4.5-75.2-90.2c-9.1-10.9-22.6-17.3-36.9-17.3l-71.1 0-41-63.1c-.3-.5-.6-1-1-1.4c44.7-29 72.5-79 72.5-133.6l0-9.8zm73 320H379.2l42.7 64H592c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48H48C21.5 0 0 21.5 0 48V400c0 26.5 21.5 48 48 48H308.2l33.2 49.8c9.8 14.7 29.7 18.7 44.4 8.9s18.7-29.7 8.9-44.4L310.5 336l74.6 0 40 48zm-159.5 0H192s0 0 0 0l0-73.8c0-10.2 1.6-20.1 4.7-29.5L265.5 384zM192 128a48 48 0 1 0 -96 0 48 48 0 1 0 96 0z" } }, "free": ["solid"] }, "person-walking": { "aliases": { "names": ["walking"], "unicodes": { "composite": ["1f6b6"], "secondary": ["10f554"] } }, "changes": ["5.0.13", "6.0.0-beta1", "6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "crosswalk", "exercise", "hike", "move", "person walking", "walk", "walking" ] }, "styles": ["solid"], "unicode": "f554", "label": "Person Walking", "voted": true, "svg": { "solid": { "last_modified": 1684767532, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M160 48a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zM126.5 199.3c-1 .4-1.9 .8-2.9 1.2l-8 3.5c-16.4 7.3-29 21.2-34.7 38.2l-2.6 7.8c-5.6 16.8-23.7 25.8-40.5 20.2s-25.8-23.7-20.2-40.5l2.6-7.8c11.4-34.1 36.6-61.9 69.4-76.5l8-3.5c20.8-9.2 43.3-14 66.1-14c44.6 0 84.8 26.8 101.9 67.9L281 232.7l21.4 10.7c15.8 7.9 22.2 27.1 14.3 42.9s-27.1 22.2-42.9 14.3L247 287.3c-10.3-5.2-18.4-13.8-22.8-24.5l-9.6-23-19.3 65.5 49.5 54c5.4 5.9 9.2 13 11.2 20.8l23 92.1c4.3 17.1-6.1 34.5-23.3 38.8s-34.5-6.1-38.8-23.3l-22-88.1-70.7-77.1c-14.8-16.1-20.3-38.6-14.7-59.7l16.9-63.5zM68.7 398l25-62.4c2.1 3 4.5 5.8 7 8.6l40.7 44.4-14.5 36.2c-2.4 6-6 11.5-10.6 16.1L54.6 502.6c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L68.7 398z" } }, "free": ["solid"] }, "person-walking-arrow-loop-left": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["population return", "return"] }, "styles": ["solid"], "unicode": "e551", "label": "Person Walking Arrow Loop Left", "voted": false, "svg": { "solid": { "last_modified": 1684767531, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M208 96a48 48 0 1 0 0-96 48 48 0 1 0 0 96zM123.7 200.5c1-.4 1.9-.8 2.9-1.2l-16.9 63.5c-5.6 21.1-.1 43.6 14.7 59.7l70.7 77.1 22 88.1c4.3 17.1 21.7 27.6 38.8 23.3s27.6-21.7 23.3-38.8l-23-92.1c-1.9-7.8-5.8-14.9-11.2-20.8l-49.5-54 19.3-65.5 9.6 23c4.4 10.6 12.5 19.3 22.8 24.5l26.7 13.3c15.8 7.9 35 1.5 42.9-14.3s1.5-35-14.3-42.9L281 232.7l-15.3-36.8C248.5 154.8 208.3 128 163.7 128c-22.8 0-45.3 4.8-66.1 14l-8 3.5c-32.9 14.6-58.1 42.4-69.4 76.5l-2.6 7.8c-5.6 16.8 3.5 34.9 20.2 40.5s34.9-3.5 40.5-20.2l2.6-7.8c5.7-17.1 18.3-30.9 34.7-38.2l8-3.5zm-30 135.1L68.7 398 9.4 457.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L116.3 441c4.6-4.6 8.2-10.1 10.6-16.1l14.5-36.2-40.7-44.4c-2.5-2.7-4.8-5.6-7-8.6zm347.7 119c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L461.3 384H480c88.4 0 160-71.6 160-160s-71.6-160-160-160L352 64c-17.7 0-32 14.3-32 32s14.3 32 32 32l128 0c53 0 96 43 96 96s-43 96-96 96H461.3l25.4-25.4c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-80 80c-12.5 12.5-12.5 32.8 0 45.3l80 80z" } }, "free": ["solid"] }, "person-walking-arrow-right": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["exit", "internally displaced", "leave", "refugee"] }, "styles": ["solid"], "unicode": "e552", "label": "Person Walking Arrow Right", "voted": false, "svg": { "solid": { "last_modified": 1684767531, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M208 96a48 48 0 1 0 0-96 48 48 0 1 0 0 96zM123.7 200.5c1-.4 1.9-.8 2.9-1.2l-16.9 63.5c-5.6 21.1-.1 43.6 14.7 59.7l70.7 77.1 22 88.1c4.3 17.1 21.7 27.6 38.8 23.3s27.6-21.7 23.3-38.8l-23-92.1c-1.9-7.8-5.8-14.9-11.2-20.8l-49.5-54 19.3-65.5 9.6 23c4.4 10.6 12.5 19.3 22.8 24.5l26.7 13.3c15.8 7.9 35 1.5 42.9-14.3s1.5-35-14.3-42.9L281 232.7l-15.3-36.8C248.5 154.8 208.3 128 163.7 128c-22.8 0-45.3 4.8-66.1 14l-8 3.5c-32.9 14.6-58.1 42.4-69.4 76.5l-2.6 7.8c-5.6 16.8 3.5 34.9 20.2 40.5s34.9-3.5 40.5-20.2l2.6-7.8c5.7-17.1 18.3-30.9 34.7-38.2l8-3.5zm-30 135.1L68.7 398 9.4 457.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L116.3 441c4.6-4.6 8.2-10.1 10.6-16.1l14.5-36.2-40.7-44.4c-2.5-2.7-4.8-5.6-7-8.6zM550.6 153.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L530.7 224H384c-17.7 0-32 14.3-32 32s14.3 32 32 32H530.7l-25.4 25.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l80-80c12.5-12.5 12.5-32.8 0-45.3l-80-80z" } }, "free": ["solid"] }, "person-walking-dashed-line-arrow-right": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["exit", "refugee"] }, "styles": ["solid"], "unicode": "e553", "label": "Person Walking Dashed Line Arrow Right", "voted": false, "svg": { "solid": { "last_modified": 1684767532, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M208 96a48 48 0 1 0 0-96 48 48 0 1 0 0 96zM123.7 200.5c1-.4 1.9-.8 2.9-1.2l-16.9 63.5c-5.6 21.1-.1 43.6 14.7 59.7l70.7 77.1 22 88.1c4.3 17.1 21.7 27.6 38.8 23.3s27.6-21.7 23.3-38.8l-23-92.1c-1.9-7.8-5.8-14.9-11.2-20.8l-49.5-54 19.3-65.5 9.6 23c4.4 10.6 12.5 19.3 22.8 24.5l26.7 13.3c15.8 7.9 35 1.5 42.9-14.3s1.5-35-14.3-42.9L281 232.7l-15.3-36.8C248.5 154.8 208.3 128 163.7 128c-22.8 0-45.3 4.8-66.1 14l-8 3.5c-32.9 14.6-58.1 42.4-69.4 76.5l-2.6 7.8c-5.6 16.8 3.5 34.9 20.2 40.5s34.9-3.5 40.5-20.2l2.6-7.8c5.7-17.1 18.3-30.9 34.7-38.2l8-3.5zm-30 135.1L68.7 398 9.4 457.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L116.3 441c4.6-4.6 8.2-10.1 10.6-16.1l14.5-36.2-40.7-44.4c-2.5-2.7-4.8-5.6-7-8.6zM550.6 153.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L530.7 224H384c-17.7 0-32 14.3-32 32s14.3 32 32 32H530.7l-25.4 25.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l80-80c12.5-12.5 12.5-32.8 0-45.3l-80-80zM392 0c-13.3 0-24 10.7-24 24V72c0 13.3 10.7 24 24 24s24-10.7 24-24V24c0-13.3-10.7-24-24-24zm24 152c0-13.3-10.7-24-24-24s-24 10.7-24 24v16c0 13.3 10.7 24 24 24s24-10.7 24-24V152zM392 320c-13.3 0-24 10.7-24 24v16c0 13.3 10.7 24 24 24s24-10.7 24-24V344c0-13.3-10.7-24-24-24zm24 120c0-13.3-10.7-24-24-24s-24 10.7-24 24v48c0 13.3 10.7 24 24 24s24-10.7 24-24V440z" } }, "free": ["solid"] }, "person-walking-luggage": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "bag", "baggage", "briefcase", "carry-on", "deployment", "rolling" ] }, "styles": ["solid"], "unicode": "e554", "label": "Person Walking Luggage", "voted": false, "svg": { "solid": { "last_modified": 1684767531, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M432 96a48 48 0 1 0 0-96 48 48 0 1 0 0 96zM347.7 200.5c1-.4 1.9-.8 2.9-1.2l-16.9 63.5c-5.6 21.1-.1 43.6 14.7 59.7l70.7 77.1 22 88.1c4.3 17.1 21.7 27.6 38.8 23.3s27.6-21.7 23.3-38.8l-23-92.1c-1.9-7.8-5.8-14.9-11.2-20.8l-49.5-54 19.3-65.5 9.6 23c4.4 10.6 12.5 19.3 22.8 24.5l26.7 13.3c15.8 7.9 35 1.5 42.9-14.3s1.5-35-14.3-42.9L505 232.7l-15.3-36.8C472.5 154.8 432.3 128 387.7 128c-22.8 0-45.3 4.8-66.1 14l-8 3.5c-32.9 14.6-58.1 42.4-69.4 76.5l-2.6 7.8c-5.6 16.8 3.5 34.9 20.2 40.5s34.9-3.5 40.5-20.2l2.6-7.8c5.7-17.1 18.3-30.9 34.7-38.2l8-3.5zm-30 135.1l-25 62.4-59.4 59.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L340.3 441c4.6-4.6 8.2-10.1 10.6-16.1l14.5-36.2-40.7-44.4c-2.5-2.7-4.8-5.6-7-8.6zM256 274.1c-7.7-4.4-17.4-1.8-21.9 5.9l-32 55.4L147.7 304c-15.3-8.8-34.9-3.6-43.7 11.7L40 426.6c-8.8 15.3-3.6 34.9 11.7 43.7l55.4 32c15.3 8.8 34.9 3.6 43.7-11.7l64-110.9c1.5-2.6 2.6-5.2 3.3-8L261.9 296c4.4-7.7 1.8-17.4-5.9-21.9z" } }, "free": ["solid"] }, "person-walking-with-cane": { "aliases": { "names": ["blind"], "unicodes": { "secondary": ["10f29d"] } }, "changes": [ "4.6.0", "5.0.0", "5.11.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["blind", "cane"] }, "styles": ["solid"], "unicode": "f29d", "label": "Person Walking With Cane", "voted": false, "svg": { "solid": { "last_modified": 1684767531, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M176 96a48 48 0 1 0 0-96 48 48 0 1 0 0 96zm-8.4 32c-36.4 0-69.6 20.5-85.9 53.1L35.4 273.7c-7.9 15.8-1.5 35 14.3 42.9s35 1.5 42.9-14.3L128 231.6v43.2c0 17 6.7 33.3 18.7 45.3L224 397.3V480c0 17.7 14.3 32 32 32s32-14.3 32-32V390.6c0-12.7-5.1-24.9-14.1-33.9L224 306.7V213.3l70.4 93.9c10.6 14.1 30.7 17 44.8 6.4s17-30.7 6.4-44.8L268.8 166.4C250.7 142.2 222.2 128 192 128H167.6zM128.3 346.8L97 472.2c-4.3 17.1 6.1 34.5 23.3 38.8s34.5-6.1 38.8-23.3l22-88.2-52.8-52.8zM450.8 505.1c5 7.3 15 9.1 22.3 4s9.1-15 4-22.3L358.9 316.1c-2.8 3.8-6.1 7.3-10.1 10.3c-5 3.8-10.5 6.4-16.2 7.9L450.8 505.1z" } }, "free": ["solid"] }, "peseta-sign": { "changes": ["6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Peseta Sign", "currency"] }, "styles": ["solid"], "unicode": "e221", "label": "Peseta Sign", "voted": false, "svg": { "solid": { "last_modified": 1684766476, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M64 32C46.3 32 32 46.3 32 64v96c-17.7 0-32 14.3-32 32s14.3 32 32 32l0 96V448c0 17.7 14.3 32 32 32s32-14.3 32-32V352h96c77.4 0 142-55 156.8-128H352c17.7 0 32-14.3 32-32s-14.3-32-32-32h-3.2C334 87 269.4 32 192 32H64zM282.5 160H96V96h96c41.8 0 77.4 26.7 90.5 64zM96 224H282.5c-13.2 37.3-48.7 64-90.5 64H96V224z" } }, "free": ["solid"] }, "peso-sign": { "changes": ["6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Peso Sign", "currency"] }, "styles": ["solid"], "unicode": "e222", "label": "Peso Sign", "voted": false, "svg": { "solid": { "last_modified": 1684766474, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M64 32C46.3 32 32 46.3 32 64v64c-17.7 0-32 14.3-32 32s14.3 32 32 32l0 32c-17.7 0-32 14.3-32 32s14.3 32 32 32l0 64v96c0 17.7 14.3 32 32 32s32-14.3 32-32V384h80c68.4 0 127.7-39 156.8-96H352c17.7 0 32-14.3 32-32s-14.3-32-32-32h-.7c.5-5.3 .7-10.6 .7-16s-.2-10.7-.7-16h.7c17.7 0 32-14.3 32-32s-14.3-32-32-32H332.8C303.7 71 244.4 32 176 32H64zm190.4 96H96V96h80c30.5 0 58.2 12.2 78.4 32zM96 192H286.9c.7 5.2 1.1 10.6 1.1 16s-.4 10.8-1.1 16H96V192zm158.4 96c-20.2 19.8-47.9 32-78.4 32H96V288H254.4z" } }, "free": ["solid"] }, "phabricator": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3db", "label": "Phabricator", "voted": false, "svg": { "brands": { "last_modified": 1660014465, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M323 262.1l-.1-13s21.7-19.8 21.1-21.2l-9.5-20c-.6-1.4-29.5-.5-29.5-.5l-9.4-9.3s.2-28.5-1.2-29.1l-20.1-9.2c-1.4-.6-20.7 21-20.7 21l-13.1-.2s-20.5-21.4-21.9-20.8l-20 8.3c-1.4.5.2 28.9.2 28.9l-9.1 9.1s-29.2-.9-29.7.4l-8.1 19.8c-.6 1.4 21 21 21 21l.1 12.9s-21.7 19.8-21.1 21.2l9.5 20c.6 1.4 29.5.5 29.5.5l9.4 9.3s-.2 31.8 1.2 32.3l20.1 8.3c1.4.6 20.7-23.5 20.7-23.5l13.1.2s20.5 23.8 21.8 23.3l20-7.5c1.4-.6-.2-32.1-.2-32.1l9.1-9.1s29.2.9 29.7-.5l8.1-19.8c.7-1.1-20.9-20.7-20.9-20.7zm-44.9-8.7c.7 17.1-12.8 31.6-30.1 32.4-17.3.8-32.1-12.5-32.8-29.6-.7-17.1 12.8-31.6 30.1-32.3 17.3-.8 32.1 12.5 32.8 29.5zm201.2-37.9l-97-97-.1.1c-75.1-73.3-195.4-72.8-269.8 1.6-50.9 51-27.8 27.9-95.7 95.3-22.3 22.3-22.3 58.7 0 81 69.9 69.4 46.4 46 97.4 97l.1-.1c75.1 73.3 195.4 72.9 269.8-1.6 51-50.9 27.9-27.9 95.3-95.3 22.3-22.3 22.3-58.7 0-81zM140.4 363.8c-59.6-59.5-59.6-156 0-215.5 59.5-59.6 156-59.5 215.6 0 59.5 59.5 59.6 156 0 215.6-59.6 59.5-156 59.4-215.6-.1z" } }, "free": ["brands"] }, "phoenix-framework": { "changes": ["5.0.0", "5.0.3"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3dc", "label": "Phoenix Framework", "voted": false, "svg": { "brands": { "last_modified": 1660014473, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M212.9 344.3c3.8-.1 22.8-1.4 25.6-2.2-2.4-2.6-43.6-1-68-49.6-4.3-8.6-7.5-17.6-6.4-27.6 2.9-25.5 32.9-30 52-18.5 36 21.6 63.3 91.3 113.7 97.5 37 4.5 84.6-17 108.2-45.4-.6-.1-.8-.2-1-.1-.4.1-.8.2-1.1.3-33.3 12.1-94.3 9.7-134.7-14.8-37.6-22.8-53.1-58.7-51.8-74.6 1.8-21.3 22.9-23.2 35.9-19.6 14.4 3.9 24.4 17.6 38.9 27.4 15.6 10.4 32.9 13.7 51.3 10.3 14.9-2.7 34.4-12.3 36.5-14.5-1.1-.1-1.8-.1-2.5-.2-6.2-.6-12.4-.8-18.5-1.7C279.8 194.5 262.1 47.4 138.5 37.9 94.2 34.5 39.1 46 2.2 72.9c-.8.6-1.5 1.2-2.2 1.8.1.2.1.3.2.5.8 0 1.6-.1 2.4-.2 6.3-1 12.5-.8 18.7.3 23.8 4.3 47.7 23.1 55.9 76.5 5.3 34.3-.7 50.8 8 86.1 19 77.1 91 107.6 127.7 106.4zM75.3 64.9c-.9-1-.9-1.2-1.3-2 12.1-2.6 24.2-4.1 36.6-4.8-1.1 14.7-22.2 21.3-35.3 6.8zm196.9 350.5c-42.8 1.2-92-26.7-123.5-61.4-4.6-5-16.8-20.2-18.6-23.4l.4-.4c6.6 4.1 25.7 18.6 54.8 27 24.2 7 48.1 6.3 71.6-3.3 22.7-9.3 41-.5 43.1 2.9-18.5 3.8-20.1 4.4-24 7.9-5.1 4.4-4.6 11.7 7 17.2 26.2 12.4 63-2.8 97.2 25.4 2.4 2 8.1 7.8 10.1 10.7-.1.2-.3.3-.4.5-4.8-1.5-16.4-7.5-40.2-9.3-24.7-2-46.3 5.3-77.5 6.2zm174.8-252c16.4-5.2 41.3-13.4 66.5-3.3 16.1 6.5 26.2 18.7 32.1 34.6 3.5 9.4 5.1 19.7 5.1 28.7-.2 0-.4 0-.6.1-.2-.4-.4-.9-.5-1.3-5-22-29.9-43.8-67.6-29.9-50.2 18.6-130.4 9.7-176.9-48-.7-.9-2.4-1.7-1.3-3.2.1-.2 2.1.6 3 1.3 18.1 13.4 38.3 21.9 60.3 26.2 30.5 6.1 54.6 2.9 79.9-5.2zm102.7 117.5c-32.4.2-33.8 50.1-103.6 64.4-18.2 3.7-38.7 4.6-44.9 4.2v-.4c2.8-1.5 14.7-2.6 29.7-16.6 7.9-7.3 15.3-15.1 22.8-22.9 19.5-20.2 41.4-42.2 81.9-39 23.1 1.8 29.3 8.2 36.1 12.7.3.2.4.5.7.9-.5 0-.7.1-.9 0-7-2.7-14.3-3.3-21.8-3.3zm-12.3-24.1c-.1.2-.1.4-.2.6-28.9-4.4-48-7.9-68.5 4-17 9.9-31.4 20.5-62 24.4-27.1 3.4-45.1 2.4-66.1-8-.3-.2-.6-.4-1-.6 0-.2.1-.3.1-.5 24.9 3.8 36.4 5.1 55.5-5.8 22.3-12.9 40.1-26.6 71.3-31 29.6-4.1 51.3 2.5 70.9 16.9zM268.6 97.3c-.6-.6-1.1-1.2-2.1-2.3 7.6 0 29.7-1.2 53.4 8.4 19.7 8 32.2 21 50.2 32.9 11.1 7.3 23.4 9.3 36.4 8.1 4.3-.4 8.5-1.2 12.8-1.7.4-.1.9 0 1.5.3-.6.4-1.2.9-1.8 1.2-8.1 4-16.7 6.3-25.6 7.1-26.1 2.6-50.3-3.7-73.4-15.4-19.3-9.9-36.4-22.9-51.4-38.6zM640 335.7c-3.5 3.1-22.7 11.6-42.7 5.3-12.3-3.9-19.5-14.9-31.6-24.1-10-7.6-20.9-7.9-28.1-8.4.6-.8.9-1.2 1.2-1.4 14.8-9.2 30.5-12.2 47.3-6.5 12.5 4.2 19.2 13.5 30.4 24.2 10.8 10.4 21 9.9 23.1 10.5.1-.1.2 0 .4.4zm-212.5 137c2.2 1.2 1.6 1.5 1.5 2-18.5-1.4-33.9-7.6-46.8-22.2-21.8-24.7-41.7-27.9-48.6-29.7.5-.2.8-.4 1.1-.4 13.1.1 26.1.7 38.9 3.9 25.3 6.4 35 25.4 41.6 35.3 3.2 4.8 7.3 8.3 12.3 11.1z" } }, "free": ["brands"] }, "phoenix-squadron": { "changes": ["5.0.12", "5.8.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f511", "label": "Phoenix Squadron", "voted": false, "svg": { "brands": { "last_modified": 1660014479, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M96 63.38C142.49 27.25 201.55 7.31 260.51 8.81c29.58-.38 59.11 5.37 86.91 15.33-24.13-4.63-49-6.34-73.38-2.45C231.17 27 191 48.84 162.21 80.87c5.67-1 10.78-3.67 16-5.86 18.14-7.87 37.49-13.26 57.23-14.83 19.74-2.13 39.64-.43 59.28 1.92-14.42 2.79-29.12 4.57-43 9.59-34.43 11.07-65.27 33.16-86.3 62.63-13.8 19.71-23.63 42.86-24.67 67.13-.35 16.49 5.22 34.81 19.83 44a53.27 53.27 0 0 0 37.52 6.74c15.45-2.46 30.07-8.64 43.6-16.33 11.52-6.82 22.67-14.55 32-24.25 3.79-3.22 2.53-8.45 2.62-12.79-2.12-.34-4.38-1.11-6.3.3a203 203 0 0 1-35.82 15.37c-20 6.17-42.16 8.46-62.1.78 12.79 1.73 26.06.31 37.74-5.44 20.23-9.72 36.81-25.2 54.44-38.77a526.57 526.57 0 0 1 88.9-55.31c25.71-12 52.94-22.78 81.57-24.12-15.63 13.72-32.15 26.52-46.78 41.38-14.51 14-27.46 29.5-40.11 45.18-3.52 4.6-8.95 6.94-13.58 10.16a150.7 150.7 0 0 0-51.89 60.1c-9.33 19.68-14.5 41.85-11.77 63.65 1.94 13.69 8.71 27.59 20.9 34.91 12.9 8 29.05 8.07 43.48 5.1 32.8-7.45 61.43-28.89 81-55.84 20.44-27.52 30.52-62.2 29.16-96.35-.52-7.5-1.57-15-1.66-22.49 8 19.48 14.82 39.71 16.65 60.83 2 14.28.75 28.76-1.62 42.9-1.91 11-5.67 21.51-7.78 32.43a165 165 0 0 0 39.34-81.07 183.64 183.64 0 0 0-14.21-104.64c20.78 32 32.34 69.58 35.71 107.48.49 12.73.49 25.51 0 38.23A243.21 243.21 0 0 1 482 371.34c-26.12 47.34-68 85.63-117.19 108-78.29 36.23-174.68 31.32-248-14.68A248.34 248.34 0 0 1 25.36 366 238.34 238.34 0 0 1 0 273.08v-31.34C3.93 172 40.87 105.82 96 63.38m222 80.33a79.13 79.13 0 0 0 16-4.48c5-1.77 9.24-5.94 10.32-11.22-8.96 4.99-17.98 9.92-26.32 15.7z" } }, "free": ["brands"] }, "phone": { "aliases": { "unicodes": { "composite": ["1f4de", "1f57b"], "secondary": ["10f095"] } }, "changes": [ "2.0.0", "5.0.0", "5.10.1", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Left Hand Telephone Receiver", "call", "earphone", "number", "phone", "receiver", "support", "telephone", "telephone receiver", "voice" ] }, "styles": ["solid"], "unicode": "f095", "label": "Phone", "voted": false, "svg": { "solid": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M164.9 24.6c-7.7-18.6-28-28.5-47.4-23.2l-88 24C12.1 30.2 0 46 0 64C0 311.4 200.6 512 448 512c18 0 33.8-12.1 38.6-29.5l24-88c5.3-19.4-4.6-39.7-23.2-47.4l-96-40c-16.3-6.8-35.2-2.1-46.3 11.6L304.7 368C234.3 334.7 177.3 277.7 144 207.3L193.3 167c13.7-11.2 18.4-30 11.6-46.3l-40-96z" } }, "free": ["solid"] }, "phone-flip": { "aliases": { "names": ["phone-alt"], "unicodes": { "composite": ["1f57d"], "secondary": ["10f879"] } }, "changes": [ "5.9.0", "5.10.1", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Right Hand Telephone Receiver", "call", "earphone", "number", "support", "telephone", "voice" ] }, "styles": ["solid"], "unicode": "f879", "label": "Phone Flip", "voted": false, "svg": { "solid": { "last_modified": 1684767391, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M347.1 24.6c7.7-18.6 28-28.5 47.4-23.2l88 24C499.9 30.2 512 46 512 64c0 247.4-200.6 448-448 448c-18 0-33.8-12.1-38.6-29.5l-24-88c-5.3-19.4 4.6-39.7 23.2-47.4l96-40c16.3-6.8 35.2-2.1 46.3 11.6L207.3 368c70.4-33.3 127.4-90.3 160.7-160.7L318.7 167c-13.7-11.2-18.4-30-11.6-46.3l40-96z" } }, "free": ["solid"] }, "phone-slash": { "aliases": { "unicodes": { "secondary": ["10f3dd"] } }, "changes": [ "5.0.0", "5.0.9", "6.0.0-beta1", "6.2.0", "6.2.1", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "call", "cancel", "earphone", "mute", "number", "support", "telephone", "voice" ] }, "styles": ["solid"], "unicode": "f3dd", "label": "Phone Slash", "voted": false, "svg": { "solid": { "last_modified": 1684767390, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M228.9 24.6c-7.7-18.6-28-28.5-47.4-23.2l-88 24C76.1 30.2 64 46 64 64c0 107.4 37.8 206 100.8 283.1L9.2 469.1c-10.4 8.2-12.3 23.3-4.1 33.7s23.3 12.3 33.7 4.1l592-464c10.4-8.2 12.3-23.3 4.1-33.7s-23.3-12.3-33.7-4.1L253 278c-17.8-21.5-32.9-45.2-45-70.7L257.3 167c13.7-11.2 18.4-30 11.6-46.3l-40-96zm96.8 319l-91.3 72C310.7 476 407.1 512 512 512c18 0 33.8-12.1 38.6-29.5l24-88c5.3-19.4-4.6-39.7-23.2-47.4l-96-40c-16.3-6.8-35.2-2.1-46.3 11.6L368.7 368c-15-7.1-29.3-15.2-43-24.3z" } }, "free": ["solid"] }, "phone-volume": { "aliases": { "names": ["volume-control-phone"], "unicodes": { "secondary": ["10f2a0"] } }, "changes": [ "4.6.0", "5.0.0", "5.0.3", "5.7.0", "6.0.0-beta1", "6.2.0", "6.2.1", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "call", "earphone", "number", "sound", "support", "telephone", "voice", "volume-control-phone" ] }, "styles": ["solid"], "unicode": "f2a0", "label": "Phone Volume", "voted": false, "svg": { "solid": { "last_modified": 1684767390, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M280 0C408.1 0 512 103.9 512 232c0 13.3-10.7 24-24 24s-24-10.7-24-24c0-101.6-82.4-184-184-184c-13.3 0-24-10.7-24-24s10.7-24 24-24zm8 192a32 32 0 1 1 0 64 32 32 0 1 1 0-64zm-32-72c0-13.3 10.7-24 24-24c75.1 0 136 60.9 136 136c0 13.3-10.7 24-24 24s-24-10.7-24-24c0-48.6-39.4-88-88-88c-13.3 0-24-10.7-24-24zM117.5 1.4c19.4-5.3 39.7 4.6 47.4 23.2l40 96c6.8 16.3 2.1 35.2-11.6 46.3L144 207.3c33.3 70.4 90.3 127.4 160.7 160.7L345 318.7c11.2-13.7 30-18.4 46.3-11.6l96 40c18.6 7.7 28.5 28 23.2 47.4l-24 88C481.8 499.9 466 512 448 512C200.6 512 0 311.4 0 64C0 46 12.1 30.2 29.5 25.4l88-24z" } }, "free": ["solid"] }, "photo-film": { "aliases": { "names": ["photo-video"], "unicodes": { "secondary": ["10f87c"] } }, "changes": ["5.9.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["av", "film", "image", "library", "media"] }, "styles": ["solid"], "unicode": "f87c", "label": "Photo Film", "voted": false, "svg": { "solid": { "last_modified": 1684767342, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M256 0H576c35.3 0 64 28.7 64 64V288c0 35.3-28.7 64-64 64H256c-35.3 0-64-28.7-64-64V64c0-35.3 28.7-64 64-64zM476 106.7C471.5 100 464 96 456 96s-15.5 4-20 10.7l-56 84L362.7 169c-4.6-5.7-11.5-9-18.7-9s-14.2 3.3-18.7 9l-64 80c-5.8 7.2-6.9 17.1-2.9 25.4s12.4 13.6 21.6 13.6h80 48H552c8.9 0 17-4.9 21.2-12.7s3.7-17.3-1.2-24.6l-96-144zM336 96a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zM64 128h96V384v32c0 17.7 14.3 32 32 32H320c17.7 0 32-14.3 32-32V384H512v64c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V192c0-35.3 28.7-64 64-64zm8 64c-8.8 0-16 7.2-16 16v16c0 8.8 7.2 16 16 16H88c8.8 0 16-7.2 16-16V208c0-8.8-7.2-16-16-16H72zm0 104c-8.8 0-16 7.2-16 16v16c0 8.8 7.2 16 16 16H88c8.8 0 16-7.2 16-16V312c0-8.8-7.2-16-16-16H72zm0 104c-8.8 0-16 7.2-16 16v16c0 8.8 7.2 16 16 16H88c8.8 0 16-7.2 16-16V416c0-8.8-7.2-16-16-16H72zm336 16v16c0 8.8 7.2 16 16 16h16c8.8 0 16-7.2 16-16V416c0-8.8-7.2-16-16-16H424c-8.8 0-16 7.2-16 16z" } }, "free": ["solid"] }, "php": { "changes": ["5.0.5"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f457", "label": "PHP", "voted": true, "svg": { "brands": { "last_modified": 1660014462, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M320 104.5c171.4 0 303.2 72.2 303.2 151.5S491.3 407.5 320 407.5c-171.4 0-303.2-72.2-303.2-151.5S148.7 104.5 320 104.5m0-16.8C143.3 87.7 0 163 0 256s143.3 168.3 320 168.3S640 349 640 256 496.7 87.7 320 87.7zM218.2 242.5c-7.9 40.5-35.8 36.3-70.1 36.3l13.7-70.6c38 0 63.8-4.1 56.4 34.3zM97.4 350.3h36.7l8.7-44.8c41.1 0 66.6 3 90.2-19.1 26.1-24 32.9-66.7 14.3-88.1-9.7-11.2-25.3-16.7-46.5-16.7h-70.7L97.4 350.3zm185.7-213.6h36.5l-8.7 44.8c31.5 0 60.7-2.3 74.8 10.7 14.8 13.6 7.7 31-8.3 113.1h-37c15.4-79.4 18.3-86 12.7-92-5.4-5.8-17.7-4.6-47.4-4.6l-18.8 96.6h-36.5l32.7-168.6zM505 242.5c-8 41.1-36.7 36.3-70.1 36.3l13.7-70.6c38.2 0 63.8-4.1 56.4 34.3zM384.2 350.3H421l8.7-44.8c43.2 0 67.1 2.5 90.2-19.1 26.1-24 32.9-66.7 14.3-88.1-9.7-11.2-25.3-16.7-46.5-16.7H417l-32.8 168.7z" } }, "free": ["brands"] }, "pied-piper": { "changes": ["4.6.0", "5.0.0", "5.0.10", "5.12.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f2ae", "label": "Pied Piper Logo", "voted": false, "svg": { "brands": { "last_modified": 1660014473, "raw": "", "viewBox": [0, 0, 480, 512], "width": 480, "height": 512, "path": "M455.93,23.2C429.23,30,387.79,51.69,341.35,90.66A206,206,0,0,0,240,64C125.13,64,32,157.12,32,272s93.13,208,208,208,208-93.13,208-208a207.25,207.25,0,0,0-58.75-144.81,155.35,155.35,0,0,0-17,27.4A176.16,176.16,0,0,1,417.1,272c0,97.66-79.44,177.11-177.09,177.11a175.81,175.81,0,0,1-87.63-23.4c82.94-107.33,150.79-37.77,184.31-226.65,5.79-32.62,28-94.26,126.23-160.18C471,33.45,465.35,20.8,455.93,23.2ZM125,406.4A176.66,176.66,0,0,1,62.9,272C62.9,174.34,142.35,94.9,240,94.9a174,174,0,0,1,76.63,17.75C250.64,174.76,189.77,265.52,125,406.4Z" } }, "free": ["brands"] }, "pied-piper-alt": { "changes": ["4.1.0", "5.0.0", "5.7.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f1a8", "label": "Alternate Pied Piper Logo (Old)", "voted": false, "svg": { "brands": { "last_modified": 1660014477, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M244 246c-3.2-2-6.3-2.9-10.1-2.9-6.6 0-12.6 3.2-19.3 3.7l1.7 4.9zm135.9 197.9c-19 0-64.1 9.5-79.9 19.8l6.9 45.1c35.7 6.1 70.1 3.6 106-9.8-4.8-10-23.5-55.1-33-55.1zM340.8 177c6.6 2.8 11.5 9.2 22.7 22.1 2-1.4 7.5-5.2 7.5-8.6 0-4.9-11.8-13.2-13.2-23 11.2-5.7 25.2-6 37.6-8.9 68.1-16.4 116.3-52.9 146.8-116.7C548.3 29.3 554 16.1 554.6 2l-2 2.6c-28.4 50-33 63.2-81.3 100-31.9 24.4-69.2 40.2-106.6 54.6l-6.3-.3v-21.8c-19.6 1.6-19.7-14.6-31.6-23-18.7 20.6-31.6 40.8-58.9 51.1-12.7 4.8-19.6 10-25.9 21.8 34.9-16.4 91.2-13.5 98.8-10zM555.5 0l-.6 1.1-.3.9.6-.6zm-59.2 382.1c-33.9-56.9-75.3-118.4-150-115.5l-.3-6c-1.1-13.5 32.8 3.2 35.1-31l-14.4 7.2c-19.8-45.7-8.6-54.3-65.5-54.3-14.7 0-26.7 1.7-41.4 4.6 2.9 18.6 2.2 36.7-10.9 50.3l19.5 5.5c-1.7 3.2-2.9 6.3-2.9 9.8 0 21 42.8 2.9 42.8 33.6 0 18.4-36.8 60.1-54.9 60.1-8 0-53.7-50-53.4-60.1l.3-4.6 52.3-11.5c13-2.6 12.3-22.7-2.9-22.7-3.7 0-43.1 9.2-49.4 10.6-2-5.2-7.5-14.1-13.8-14.1-3.2 0-6.3 3.2-9.5 4-9.2 2.6-31 2.9-21.5 20.1L15.9 298.5c-5.5 1.1-8.9 6.3-8.9 11.8 0 6 5.5 10.9 11.5 10.9 8 0 131.3-28.4 147.4-32.2 2.6 3.2 4.6 6.3 7.8 8.6 20.1 14.4 59.8 85.9 76.4 85.9 24.1 0 58-22.4 71.3-41.9 3.2-4.3 6.9-7.5 12.4-6.9.6 13.8-31.6 34.2-33 43.7-1.4 10.2-1 35.2-.3 41.1 26.7 8.1 52-3.6 77.9-2.9 4.3-21 10.6-41.9 9.8-63.5l-.3-9.5c-1.4-34.2-10.9-38.5-34.8-58.6-1.1-1.1-2.6-2.6-3.7-4 2.2-1.4 1.1-1 4.6-1.7 88.5 0 56.3 183.6 111.5 229.9 33.1-15 72.5-27.9 103.5-47.2-29-25.6-52.6-45.7-72.7-79.9zm-196.2 46.1v27.2l11.8-3.4-2.9-23.8zm-68.7-150.4l24.1 61.2 21-13.8-31.3-50.9zm84.4 154.9l2 12.4c9-1.5 58.4-6.6 58.4-14.1 0-1.4-.6-3.2-.9-4.6-26.8 0-36.9 3.8-59.5 6.3z" } }, "free": ["brands"] }, "pied-piper-hat": { "changes": ["5.0.10"], "ligatures": [], "search": { "terms": ["clothing"] }, "styles": ["brands"], "unicode": "f4e5", "label": "Pied Piper Hat (Old)", "voted": false, "svg": { "brands": { "last_modified": 1660014464, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M640 24.9c-80.8 53.6-89.4 92.5-96.4 104.4-6.7 12.2-11.7 60.3-23.3 83.6-11.7 23.6-54.2 42.2-66.1 50-11.7 7.8-28.3 38.1-41.9 64.2-108.1-4.4-167.4 38.8-259.2 93.6 29.4-9.7 43.3-16.7 43.3-16.7 94.2-36 139.3-68.3 281.1-49.2 1.1 0 1.9.6 2.8.8 3.9 2.2 5.3 6.9 3.1 10.8l-53.9 95.8c-2.5 4.7-7.8 7.2-13.1 6.1-126.8-23.8-226.9 17.3-318.9 18.6C24.1 488 0 453.4 0 451.8c0-1.1.6-1.7 1.7-1.7 0 0 38.3 0 103.1-15.3C178.4 294.5 244 245.4 315.4 245.4c0 0 71.7 0 90.6 61.9 22.8-39.7 28.3-49.2 28.3-49.2 5.3-9.4 35-77.2 86.4-141.4 51.5-64 90.4-79.9 119.3-91.8z" } }, "free": ["brands"] }, "pied-piper-pp": { "changes": ["4.1.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f1a7", "label": "Pied Piper PP Logo (Old)", "voted": false, "svg": { "brands": { "last_modified": 1660014471, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M205.3 174.6c0 21.1-14.2 38.1-31.7 38.1-7.1 0-12.8-1.2-17.2-3.7v-68c4.4-2.7 10.1-4.2 17.2-4.2 17.5 0 31.7 16.9 31.7 37.8zm52.6 67c-7.1 0-12.8 1.5-17.2 4.2v68c4.4 2.5 10.1 3.7 17.2 3.7 17.4 0 31.7-16.9 31.7-37.8 0-21.1-14.3-38.1-31.7-38.1zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zM185 255.1c41 0 74.2-35.6 74.2-79.6 0-44-33.2-79.6-74.2-79.6-12 0-24.1 3.2-34.6 8.8h-45.7V311l51.8-10.1v-50.6c8.6 3.1 18.1 4.8 28.5 4.8zm158.4 25.3c0-44-33.2-79.6-73.9-79.6-3.2 0-6.4.2-9.6.7-3.7 12.5-10.1 23.8-19.2 33.4-13.8 15-32.2 23.8-51.8 24.8V416l51.8-10.1v-50.6c8.6 3.2 18.2 4.7 28.7 4.7 40.8 0 74-35.6 74-79.6z" } }, "free": ["brands"] }, "piggy-bank": { "aliases": { "unicodes": { "secondary": ["10f4d3"] } }, "changes": [ "5.0.9", "5.10.2", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["bank", "save", "savings"] }, "styles": ["solid"], "unicode": "f4d3", "label": "Piggy Bank", "voted": false, "svg": { "solid": { "last_modified": 1684766475, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M400 96l0 .7c-5.3-.4-10.6-.7-16-.7H256c-16.5 0-32.5 2.1-47.8 6c-.1-2-.2-4-.2-6c0-53 43-96 96-96s96 43 96 96zm-16 32c3.5 0 7 .1 10.4 .3c4.2 .3 8.4 .7 12.6 1.3C424.6 109.1 450.8 96 480 96h11.5c10.4 0 18 9.8 15.5 19.9l-13.8 55.2c15.8 14.8 28.7 32.8 37.5 52.9H544c17.7 0 32 14.3 32 32v96c0 17.7-14.3 32-32 32H512c-9.1 12.1-19.9 22.9-32 32v64c0 17.7-14.3 32-32 32H416c-17.7 0-32-14.3-32-32V448H256v32c0 17.7-14.3 32-32 32H192c-17.7 0-32-14.3-32-32V416c-34.9-26.2-58.7-66.3-63.2-112H68c-37.6 0-68-30.4-68-68s30.4-68 68-68h4c13.3 0 24 10.7 24 24s-10.7 24-24 24H68c-11 0-20 9-20 20s9 20 20 20H99.2c12.1-59.8 57.7-107.5 116.3-122.8c12.9-3.4 26.5-5.2 40.5-5.2H384zm64 136a24 24 0 1 0 -48 0 24 24 0 1 0 48 0z" } }, "free": ["solid"] }, "pills": { "aliases": { "unicodes": { "secondary": ["10f484"] } }, "changes": ["5.0.7", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["drugs", "medicine", "prescription", "tablets"] }, "styles": ["solid"], "unicode": "f484", "label": "Pills", "voted": false, "svg": { "solid": { "last_modified": 1684766751, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M112 96c-26.5 0-48 21.5-48 48V256h96V144c0-26.5-21.5-48-48-48zM0 144C0 82.1 50.1 32 112 32s112 50.1 112 112V368c0 61.9-50.1 112-112 112S0 429.9 0 368V144zM554.9 399.4c-7.1 12.3-23.7 13.1-33.8 3.1L333.5 214.9c-10-10-9.3-26.7 3.1-33.8C360 167.7 387.1 160 416 160c88.4 0 160 71.6 160 160c0 28.9-7.7 56-21.1 79.4zm-59.5 59.5C472 472.3 444.9 480 416 480c-88.4 0-160-71.6-160-160c0-28.9 7.7-56 21.1-79.4c7.1-12.3 23.7-13.1 33.8-3.1L498.5 425.1c10 10 9.3 26.7-3.1 33.8z" } }, "free": ["solid"] }, "pinterest": { "changes": ["2.0.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f0d2", "label": "Pinterest", "voted": false, "svg": { "brands": { "last_modified": 1660014461, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M496 256c0 137-111 248-248 248-25.6 0-50.2-3.9-73.4-11.1 10.1-16.5 25.2-43.5 30.8-65 3-11.6 15.4-59 15.4-59 8.1 15.4 31.7 28.5 56.8 28.5 74.8 0 128.7-68.8 128.7-154.3 0-81.9-66.9-143.2-152.9-143.2-107 0-163.9 71.8-163.9 150.1 0 36.4 19.4 81.7 50.3 96.1 4.7 2.2 7.2 1.2 8.3-3.3.8-3.4 5-20.3 6.9-28.1.6-2.5.3-4.7-1.7-7.1-10.1-12.5-18.3-35.3-18.3-56.6 0-54.7 41.4-107.6 112-107.6 60.9 0 103.6 41.5 103.6 100.9 0 67.1-33.9 113.6-78 113.6-24.3 0-42.6-20.1-36.7-44.8 7-29.5 20.5-61.3 20.5-82.6 0-19-10.2-34.9-31.4-34.9-24.9 0-44.9 25.7-44.9 60.2 0 22 7.4 36.8 7.4 36.8s-24.5 103.8-29 123.2c-5 21.4-3 51.6-.9 71.2C65.4 450.9 0 361.1 0 256 0 119 111 8 248 8s248 111 248 248z" } }, "free": ["brands"] }, "pinterest-p": { "changes": ["4.3.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f231", "label": "Pinterest P", "voted": false, "svg": { "brands": { "last_modified": 1660014464, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M204 6.5C101.4 6.5 0 74.9 0 185.6 0 256 39.6 296 63.6 296c9.9 0 15.6-27.6 15.6-35.4 0-9.3-23.7-29.1-23.7-67.8 0-80.4 61.2-137.4 140.4-137.4 68.1 0 118.5 38.7 118.5 109.8 0 53.1-21.3 152.7-90.3 152.7-24.9 0-46.2-18-46.2-43.8 0-37.8 26.4-74.4 26.4-113.4 0-66.2-93.9-54.2-93.9 25.8 0 16.8 2.1 35.4 9.6 50.7-13.8 59.4-42 147.9-42 209.1 0 18.9 2.7 37.5 4.5 56.4 3.4 3.8 1.7 3.4 6.9 1.5 50.4-69 48.6-82.5 71.4-172.8 12.3 23.4 44.1 36 69.3 36 106.2 0 153.9-103.5 153.9-196.8C384 71.3 298.2 6.5 204 6.5z" } }, "free": ["brands"] }, "pix": { "changes": ["6.0.0-beta2"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e43a", "label": "Pix", "voted": true, "svg": { "brands": { "last_modified": 1660014458, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M242.4 292.5C247.8 287.1 257.1 287.1 262.5 292.5L339.5 369.5C353.7 383.7 372.6 391.5 392.6 391.5H407.7L310.6 488.6C280.3 518.1 231.1 518.1 200.8 488.6L103.3 391.2H112.6C132.6 391.2 151.5 383.4 165.7 369.2L242.4 292.5zM262.5 218.9C256.1 224.4 247.9 224.5 242.4 218.9L165.7 142.2C151.5 127.1 132.6 120.2 112.6 120.2H103.3L200.7 22.76C231.1-7.586 280.3-7.586 310.6 22.76L407.8 119.9H392.6C372.6 119.9 353.7 127.7 339.5 141.9L262.5 218.9zM112.6 142.7C126.4 142.7 139.1 148.3 149.7 158.1L226.4 234.8C233.6 241.1 243 245.6 252.5 245.6C261.9 245.6 271.3 241.1 278.5 234.8L355.5 157.8C365.3 148.1 378.8 142.5 392.6 142.5H430.3L488.6 200.8C518.9 231.1 518.9 280.3 488.6 310.6L430.3 368.9H392.6C378.8 368.9 365.3 363.3 355.5 353.5L278.5 276.5C264.6 262.6 240.3 262.6 226.4 276.6L149.7 353.2C139.1 363 126.4 368.6 112.6 368.6H80.78L22.76 310.6C-7.586 280.3-7.586 231.1 22.76 200.8L80.78 142.7H112.6z" } }, "free": ["brands"] }, "pizza-slice": { "aliases": { "unicodes": { "secondary": ["10f818"] } }, "changes": ["5.7.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "cheese", "chicago", "italian", "mozzarella", "new york", "pepperoni", "pie", "slice", "teenage mutant ninja turtles", "tomato" ] }, "styles": ["solid"], "unicode": "f818", "label": "Pizza Slice", "voted": true, "svg": { "solid": { "last_modified": 1684767421, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M169.7 .9c-22.8-1.6-41.9 14-47.5 34.7L110.4 80c.5 0 1.1 0 1.6 0c176.7 0 320 143.3 320 320c0 .5 0 1.1 0 1.6l44.4-11.8c20.8-5.5 36.3-24.7 34.7-47.5C498.5 159.5 352.5 13.5 169.7 .9zM399.8 410.2c.1-3.4 .2-6.8 .2-10.2c0-159.1-128.9-288-288-288c-3.4 0-6.8 .1-10.2 .2L.5 491.9c-1.5 5.5 .1 11.4 4.1 15.4s9.9 5.6 15.4 4.1L399.8 410.2zM176 208a32 32 0 1 1 0 64 32 32 0 1 1 0-64zm64 128a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zM96 384a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z" } }, "free": ["solid"] }, "place-of-worship": { "aliases": { "unicodes": { "secondary": ["10f67f"] } }, "changes": [ "5.3.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["building", "church", "holy", "mosque", "synagogue"] }, "styles": ["solid"], "unicode": "f67f", "label": "Place Of Worship", "voted": false, "svg": { "solid": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M224 109.3V217.6L183.3 242c-14.5 8.7-23.3 24.3-23.3 41.2V512h96V416c0-35.3 28.7-64 64-64s64 28.7 64 64v96h96V283.2c0-16.9-8.8-32.5-23.3-41.2L416 217.6V109.3c0-8.5-3.4-16.6-9.4-22.6L331.3 11.3c-6.2-6.2-16.4-6.2-22.6 0L233.4 86.6c-6 6-9.4 14.1-9.4 22.6zM24.9 330.3C9.5 338.8 0 354.9 0 372.4V464c0 26.5 21.5 48 48 48h80V273.6L24.9 330.3zM592 512c26.5 0 48-21.5 48-48V372.4c0-17.5-9.5-33.6-24.9-42.1L512 273.6V512h80z" } }, "free": ["solid"] }, "plane": { "aliases": { "unicodes": { "secondary": ["10f072"] } }, "changes": [ "1.0.0", "5.0.0", "5.0.13", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0", "6.4.1" ], "ligatures": [], "search": { "terms": [ "airplane", "airport", "destination", "fly", "location", "mode", "travel", "trip" ] }, "styles": ["solid"], "unicode": "f072", "label": "Plane", "voted": false, "svg": { "solid": { "last_modified": 1684767636, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M482.3 192c34.2 0 93.7 29 93.7 64c0 36-59.5 64-93.7 64l-116.6 0L265.2 495.9c-5.7 10-16.3 16.1-27.8 16.1l-56.2 0c-10.6 0-18.3-10.2-15.4-20.4l49-171.6L112 320 68.8 377.6c-3 4-7.8 6.4-12.8 6.4l-42 0c-7.8 0-14-6.3-14-14c0-1.3 .2-2.6 .5-3.9L32 256 .5 145.9c-.4-1.3-.5-2.6-.5-3.9c0-7.8 6.3-14 14-14l42 0c5 0 9.8 2.4 12.8 6.4L112 192l102.9 0-49-171.6C162.9 10.2 170.6 0 181.2 0l56.2 0c11.5 0 22.1 6.2 27.8 16.1L365.7 192l116.6 0z" } }, "free": ["solid"] }, "plane-arrival": { "aliases": { "unicodes": { "composite": ["1f6ec"], "secondary": ["10f5af"] } }, "changes": [ "5.1.0", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "aeroplane", "airplane", "airplane arrival", "airport", "arrivals", "arriving", "destination", "fly", "land", "landing", "location", "mode", "travel", "trip" ] }, "styles": ["solid"], "unicode": "f5af", "label": "Plane Arrival", "voted": false, "svg": { "solid": { "last_modified": 1684767637, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M.3 166.9L0 68C0 57.7 9.5 50.1 19.5 52.3l35.6 7.9c10.6 2.3 19.2 9.9 23 20L96 128l127.3 37.6L181.8 20.4C178.9 10.2 186.6 0 197.2 0h40.1c11.6 0 22.2 6.2 27.9 16.3l109 193.8 107.2 31.7c15.9 4.7 30.8 12.5 43.7 22.8l34.4 27.6c24 19.2 18.1 57.3-10.7 68.2c-41.2 15.6-86.2 18.1-128.8 7L121.7 289.8c-11.1-2.9-21.2-8.7-29.3-16.9L9.5 189.4c-5.9-6-9.3-14-9.3-22.5zM32 448H608c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32zm96-80a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm128-16a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" } }, "free": ["solid"] }, "plane-circle-check": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "airplane", "airport", "flight", "fly", "not affected", "ok", "okay", "travel" ] }, "styles": ["solid"], "unicode": "e555", "label": "Plane Circle Check", "voted": false, "svg": { "solid": { "last_modified": 1684767637, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M256 0c-35 0-64 59.5-64 93.7v84.6L8.1 283.4c-5 2.8-8.1 8.2-8.1 13.9v65.5c0 10.6 10.2 18.3 20.4 15.4l171.6-49 0 70.9-57.6 43.2c-4 3-6.4 7.8-6.4 12.8v42c0 7.8 6.3 14 14 14c1.3 0 2.6-.2 3.9-.5L256 480l110.1 31.5c1.3 .4 2.6 .5 3.9 .5c6 0 11.1-3.7 13.1-9C344.5 470.7 320 422.2 320 368c0-60.6 30.6-114 77.1-145.6L320 178.3V93.7C320 59.5 292 0 256 0zM640 368a144 144 0 1 0 -288 0 144 144 0 1 0 288 0zm-76.7-43.3c6.2 6.2 6.2 16.4 0 22.6l-72 72c-6.2 6.2-16.4 6.2-22.6 0l-40-40c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0L480 385.4l60.7-60.7c6.2-6.2 16.4-6.2 22.6 0z" } }, "free": ["solid"] }, "plane-circle-exclamation": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["affected", "airplane", "airport", "flight", "fly", "travel"] }, "styles": ["solid"], "unicode": "e556", "label": "Plane Circle Exclamation", "voted": false, "svg": { "solid": { "last_modified": 1684767637, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M256 0c-35 0-64 59.5-64 93.7v84.6L8.1 283.4c-5 2.8-8.1 8.2-8.1 13.9v65.5c0 10.6 10.2 18.3 20.4 15.4l171.6-49 0 70.9-57.6 43.2c-4 3-6.4 7.8-6.4 12.8v42c0 7.8 6.3 14 14 14c1.3 0 2.6-.2 3.9-.5L256 480l110.1 31.5c1.3 .4 2.6 .5 3.9 .5c6 0 11.1-3.7 13.1-9C344.5 470.7 320 422.2 320 368c0-60.6 30.6-114 77.1-145.6L320 178.3V93.7C320 59.5 292 0 256 0zM496 512a144 144 0 1 0 0-288 144 144 0 1 0 0 288zm0-96a24 24 0 1 1 0 48 24 24 0 1 1 0-48zm0-144c8.8 0 16 7.2 16 16v80c0 8.8-7.2 16-16 16s-16-7.2-16-16V288c0-8.8 7.2-16 16-16z" } }, "free": ["solid"] }, "plane-circle-xmark": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["airplane", "airport", "destroy", "flight", "fly", "travel"] }, "styles": ["solid"], "unicode": "e557", "label": "Plane Circle Xmark", "voted": false, "svg": { "solid": { "last_modified": 1684767636, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M256 0c-35 0-64 59.5-64 93.7v84.6L8.1 283.4c-5 2.8-8.1 8.2-8.1 13.9v65.5c0 10.6 10.2 18.3 20.4 15.4l171.6-49 0 70.9-57.6 43.2c-4 3-6.4 7.8-6.4 12.8v42c0 7.8 6.3 14 14 14c1.3 0 2.6-.2 3.9-.5L256 480l110.1 31.5c1.3 .4 2.6 .5 3.9 .5c6 0 11.1-3.7 13.1-9C344.5 470.7 320 422.2 320 368c0-60.6 30.6-114 77.1-145.6L320 178.3V93.7C320 59.5 292 0 256 0zM496 512a144 144 0 1 0 0-288 144 144 0 1 0 0 288zm59.3-180.7L518.6 368l36.7 36.7c6.2 6.2 6.2 16.4 0 22.6s-16.4 6.2-22.6 0L496 390.6l-36.7 36.7c-6.2 6.2-16.4 6.2-22.6 0s-6.2-16.4 0-22.6L473.4 368l-36.7-36.7c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0L496 345.4l36.7-36.7c6.2-6.2 16.4-6.2 22.6 0s6.2 16.4 0 22.6z" } }, "free": ["solid"] }, "plane-departure": { "aliases": { "unicodes": { "composite": ["1f6eb"], "secondary": ["10f5b0"] } }, "changes": [ "5.1.0", "5.8.0", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "aeroplane", "airplane", "airplane departure", "airport", "check-in", "departing", "departure", "departures", "destination", "fly", "location", "mode", "take off", "taking off", "travel", "trip" ] }, "styles": ["solid"], "unicode": "f5b0", "label": "Plane Departure", "voted": false, "svg": { "solid": { "last_modified": 1684767637, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M381 114.9L186.1 41.8c-16.7-6.2-35.2-5.3-51.1 2.7L89.1 67.4C78 73 77.2 88.5 87.6 95.2l146.9 94.5L136 240 77.8 214.1c-8.7-3.9-18.8-3.7-27.3 .6L18.3 230.8c-9.3 4.7-11.8 16.8-5 24.7l73.1 85.3c6.1 7.1 15 11.2 24.3 11.2H248.4c5 0 9.9-1.2 14.3-3.4L535.6 212.2c46.5-23.3 82.5-63.3 100.8-112C645.9 75 627.2 48 600.2 48H542.8c-20.2 0-40.2 4.8-58.2 14L381 114.9zM0 480c0 17.7 14.3 32 32 32H608c17.7 0 32-14.3 32-32s-14.3-32-32-32H32c-17.7 0-32 14.3-32 32z" } }, "free": ["solid"] }, "plane-lock": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "airplane", "airport", "closed", "flight", "fly", "lockdown", "quarantine", "travel" ] }, "styles": ["solid"], "unicode": "e558", "label": "Plane Lock", "voted": false, "svg": { "solid": { "last_modified": 1684767637, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M192 93.7C192 59.5 221 0 256 0c36 0 64 59.5 64 93.7v84.6l101.8 58.2C418 247.6 416 259.6 416 272v24.6c-17.9 10.4-30.3 29.1-31.8 50.9L320 329.1V400l57.6 43.2c4 3 6.4 7.8 6.4 12.8v24 18c0 7.8-6.3 14-14 14c-1.3 0-2.6-.2-3.9-.5L256 480 145.9 511.5c-1.3 .4-2.6 .5-3.9 .5c-7.8 0-14-6.3-14-14V456c0-5 2.4-9.8 6.4-12.8L192 400l0-70.9-171.6 49C10.2 381.1 0 373.4 0 362.8V297.3c0-5.7 3.1-11 8.1-13.9L192 178.3V93.7zM528 240c-17.7 0-32 14.3-32 32v48h64V272c0-17.7-14.3-32-32-32zm-80 32c0-44.2 35.8-80 80-80s80 35.8 80 80v48c17.7 0 32 14.3 32 32V480c0 17.7-14.3 32-32 32H448c-17.7 0-32-14.3-32-32V352c0-17.7 14.3-32 32-32V272z" } }, "free": ["solid"] }, "plane-slash": { "aliases": { "unicodes": { "secondary": ["10e069"] } }, "changes": [ "5.13.0", "5.14.0", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "airplane mode", "airport", "canceled", "covid-19", "delayed", "grounded", "travel" ] }, "styles": ["solid"], "unicode": "e069", "label": "Plane Slash", "voted": false, "svg": { "solid": { "last_modified": 1684767637, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M514.3 192c34.2 0 93.7 29 93.7 64c0 36-59.5 64-93.7 64H440.6L630.8 469.1c10.4 8.2 12.3 23.3 4.1 33.7s-23.3 12.3-33.7 4.1L9.2 42.9C-1.2 34.7-3.1 19.6 5.1 9.2S28.4-3.1 38.8 5.1L238.1 161.3 197.8 20.4C194.9 10.2 202.6 0 213.2 0h56.2c11.5 0 22.1 6.2 27.8 16.1L397.7 192l116.6 0zM41.5 128.7l321 252.9L297.2 495.9c-5.7 10-16.3 16.1-27.8 16.1l-56.2 0c-10.6 0-18.3-10.2-15.4-20.4l49-171.6H144l-43.2 57.6c-3 4-7.8 6.4-12.8 6.4H46c-7.8 0-14-6.3-14-14c0-1.3 .2-2.6 .5-3.9L64 256 32.5 145.9c-.4-1.3-.5-2.6-.5-3.9c0-6.2 4-11.4 9.5-13.3z" } }, "free": ["solid"] }, "plane-up": { "changes": [ "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.1.0", "6.2.0", "6.3.0", "6.4.0", "6.4.1" ], "ligatures": [], "search": { "terms": [ "airplane", "airport", "internet", "signal", "sky", "wifi", "wireless" ] }, "styles": ["solid"], "unicode": "e22d", "label": "Plane Up", "voted": false, "svg": { "solid": { "last_modified": 1684767637, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M192 93.7C192 59.5 221 0 256 0c36 0 64 59.5 64 93.7l0 66.3L497.8 278.5c8.9 5.9 14.2 15.9 14.2 26.6v56.7c0 10.9-10.7 18.6-21.1 15.2L320 320v80l57.6 43.2c4 3 6.4 7.8 6.4 12.8v42c0 7.8-6.3 14-14 14c-1.3 0-2.6-.2-3.9-.5L256 480 145.9 511.5c-1.3 .4-2.6 .5-3.9 .5c-7.8 0-14-6.3-14-14V456c0-5 2.4-9.8 6.4-12.8L192 400V320L21.1 377C10.7 380.4 0 372.7 0 361.8V305.1c0-10.7 5.3-20.7 14.2-26.6L192 160V93.7z" } }, "free": ["solid"] }, "plant-wilt": { "changes": ["6.1.0", "6.1.2", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["drought", "planting", "vegetation", "wilt"] }, "styles": ["solid"], "unicode": "e5aa", "label": "Plant Wilt", "voted": false, "svg": { "solid": { "last_modified": 1684768130, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M288 120c0-30.9 25.1-56 56-56s56 25.1 56 56v13c-29.3 10-48 34.5-48 70.1c0 27.9 25.3 74.8 66 111.6c3.8 3.5 8.9 5.3 14 5.3s10.2-1.8 14-5.3c40.7-36.8 66-83.7 66-111.6c0-35.6-18.7-60.2-48-70.1V120C464 53.7 410.3 0 344 0S224 53.7 224 120v21.8C207.3 133 188.2 128 168 128c-66.3 0-120 53.7-120 120v13c-29.3 10-48 34.5-48 70.1C0 359 25.3 405.9 66 442.7c3.8 3.5 8.9 5.3 14 5.3s10.2-1.8 14-5.3c40.7-36.8 66-83.7 66-111.6c0-35.6-18.7-60.2-48-70.1V248c0-30.9 25.1-56 56-56s56 25.1 56 56v32V480c0 17.7 14.3 32 32 32s32-14.3 32-32V280 248 120z" } }, "free": ["solid"] }, "plate-wheat": { "changes": ["6.1.0", "6.1.2", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["bowl", "hunger", "rations", "wheat"] }, "styles": ["solid"], "unicode": "e55a", "label": "Plate Wheat", "voted": false, "svg": { "solid": { "last_modified": 1684767420, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M176 32c44.2 0 80 35.8 80 80v16c0 8.8-7.2 16-16 16c-44.2 0-80-35.8-80-80V48c0-8.8 7.2-16 16-16zM56 64h48c13.3 0 24 10.7 24 24s-10.7 24-24 24H56c-13.3 0-24-10.7-24-24s10.7-24 24-24zM24 136H136c13.3 0 24 10.7 24 24s-10.7 24-24 24H24c-13.3 0-24-10.7-24-24s10.7-24 24-24zm8 96c0-13.3 10.7-24 24-24h48c13.3 0 24 10.7 24 24s-10.7 24-24 24H56c-13.3 0-24-10.7-24-24zM272 48c0-8.8 7.2-16 16-16c44.2 0 80 35.8 80 80v16c0 8.8-7.2 16-16 16c-44.2 0-80-35.8-80-80V48zM400 32c44.2 0 80 35.8 80 80v16c0 8.8-7.2 16-16 16c-44.2 0-80-35.8-80-80V48c0-8.8 7.2-16 16-16zm80 160v16c0 44.2-35.8 80-80 80c-8.8 0-16-7.2-16-16V256c0-44.2 35.8-80 80-80c8.8 0 16 7.2 16 16zM352 176c8.8 0 16 7.2 16 16v16c0 44.2-35.8 80-80 80c-8.8 0-16-7.2-16-16V256c0-44.2 35.8-80 80-80zm-96 16v16c0 44.2-35.8 80-80 80c-8.8 0-16-7.2-16-16V256c0-44.2 35.8-80 80-80c8.8 0 16 7.2 16 16zM3.5 347.6C1.6 332.9 13 320 27.8 320H484.2c14.8 0 26.2 12.9 24.4 27.6C502.3 397.8 464.2 437 416 446v2c0 17.7-14.3 32-32 32H128c-17.7 0-32-14.3-32-32v-2c-48.2-9-86.3-48.2-92.5-98.4z" } }, "free": ["solid"] }, "play": { "aliases": { "unicodes": { "composite": ["25b6"], "secondary": ["10f04b"] } }, "changes": [ "1.0.0", "5.0.0", "5.10.2", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "arrow", "audio", "music", "play", "play button", "playing", "right", "sound", "start", "triangle", "video" ] }, "styles": ["solid"], "unicode": "f04b", "label": "Play", "voted": false, "svg": { "solid": { "last_modified": 1684766675, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M73 39c-14.8-9.1-33.4-9.4-48.5-.9S0 62.6 0 80V432c0 17.4 9.4 33.4 24.5 41.9s33.7 8.1 48.5-.9L361 297c14.3-8.7 23-24.2 23-41s-8.7-32.2-23-41L73 39z" } }, "free": ["solid"] }, "playstation": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3df", "label": "PlayStation", "voted": false, "svg": { "brands": { "last_modified": 1660014471, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M570.9 372.3c-11.3 14.2-38.8 24.3-38.8 24.3L327 470.2v-54.3l150.9-53.8c17.1-6.1 19.8-14.8 5.8-19.4-13.9-4.6-39.1-3.3-56.2 2.9L327 381.1v-56.4c23.2-7.8 47.1-13.6 75.7-16.8 40.9-4.5 90.9.6 130.2 15.5 44.2 14 49.2 34.7 38 48.9zm-224.4-92.5v-139c0-16.3-3-31.3-18.3-35.6-11.7-3.8-19 7.1-19 23.4v347.9l-93.8-29.8V32c39.9 7.4 98 24.9 129.2 35.4C424.1 94.7 451 128.7 451 205.2c0 74.5-46 102.8-104.5 74.6zM43.2 410.2c-45.4-12.8-53-39.5-32.3-54.8 19.1-14.2 51.7-24.9 51.7-24.9l134.5-47.8v54.5l-96.8 34.6c-17.1 6.1-19.7 14.8-5.8 19.4 13.9 4.6 39.1 3.3 56.2-2.9l46.4-16.9v48.8c-51.6 9.3-101.4 7.3-153.9-10z" } }, "free": ["brands"] }, "plug": { "aliases": { "unicodes": { "composite": ["1f50c"], "secondary": ["10f1e6"] } }, "changes": [ "4.2.0", "5.0.0", "5.12.0", "6.0.0-beta1", "6.1.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "connect", "electric", "electric plug", "electricity", "online", "plug", "power" ] }, "styles": ["solid"], "unicode": "f1e6", "label": "Plug", "voted": false, "svg": { "solid": { "last_modified": 1684767443, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M96 0C78.3 0 64 14.3 64 32v96h64V32c0-17.7-14.3-32-32-32zM288 0c-17.7 0-32 14.3-32 32v96h64V32c0-17.7-14.3-32-32-32zM32 160c-17.7 0-32 14.3-32 32s14.3 32 32 32v32c0 77.4 55 142 128 156.8V480c0 17.7 14.3 32 32 32s32-14.3 32-32V412.8C297 398 352 333.4 352 256V224c17.7 0 32-14.3 32-32s-14.3-32-32-32H32z" } }, "free": ["solid"] }, "plug-circle-bolt": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["electric", "electricity", "plug", "power"] }, "styles": ["solid"], "unicode": "e55b", "label": "Plug Circle Bolt", "voted": false, "svg": { "solid": { "last_modified": 1684767442, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M96 0C78.3 0 64 14.3 64 32v96h64V32c0-17.7-14.3-32-32-32zM288 0c-17.7 0-32 14.3-32 32v96h64V32c0-17.7-14.3-32-32-32zM32 160c-17.7 0-32 14.3-32 32s14.3 32 32 32v32c0 77.4 55 142 128 156.8V480c0 17.7 14.3 32 32 32s32-14.3 32-32V412.8c12.3-2.5 24.1-6.4 35.1-11.5c-2.1-10.8-3.1-21.9-3.1-33.3c0-80.3 53.8-148 127.3-169.2c.5-2.2 .7-4.5 .7-6.8c0-17.7-14.3-32-32-32H32zM432 512a144 144 0 1 0 0-288 144 144 0 1 0 0 288zm47.9-225c4.3 3.7 5.4 9.9 2.6 14.9L452.4 356H488c5.2 0 9.8 3.3 11.4 8.2s-.1 10.3-4.2 13.4l-96 72c-4.5 3.4-10.8 3.2-15.1-.6s-5.4-9.9-2.6-14.9L411.6 380H376c-5.2 0-9.8-3.3-11.4-8.2s.1-10.3 4.2-13.4l96-72c4.5-3.4 10.8-3.2 15.1 .6z" } }, "free": ["solid"] }, "plug-circle-check": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "electric", "electricity", "not affected", "ok", "okay", "plug", "power" ] }, "styles": ["solid"], "unicode": "e55c", "label": "Plug Circle Check", "voted": false, "svg": { "solid": { "last_modified": 1684767442, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M96 0C78.3 0 64 14.3 64 32v96h64V32c0-17.7-14.3-32-32-32zM288 0c-17.7 0-32 14.3-32 32v96h64V32c0-17.7-14.3-32-32-32zM32 160c-17.7 0-32 14.3-32 32s14.3 32 32 32v32c0 77.4 55 142 128 156.8V480c0 17.7 14.3 32 32 32s32-14.3 32-32V412.8c12.3-2.5 24.1-6.4 35.1-11.5c-2.1-10.8-3.1-21.9-3.1-33.3c0-80.3 53.8-148 127.3-169.2c.5-2.2 .7-4.5 .7-6.8c0-17.7-14.3-32-32-32H32zM576 368a144 144 0 1 0 -288 0 144 144 0 1 0 288 0zm-76.7-43.3c6.2 6.2 6.2 16.4 0 22.6l-72 72c-6.2 6.2-16.4 6.2-22.6 0l-40-40c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0L416 385.4l60.7-60.7c6.2-6.2 16.4-6.2 22.6 0z" } }, "free": ["solid"] }, "plug-circle-exclamation": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["affected", "electric", "electricity", "plug", "power"] }, "styles": ["solid"], "unicode": "e55d", "label": "Plug Circle Exclamation", "voted": false, "svg": { "solid": { "last_modified": 1684767441, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M96 0C78.3 0 64 14.3 64 32v96h64V32c0-17.7-14.3-32-32-32zM288 0c-17.7 0-32 14.3-32 32v96h64V32c0-17.7-14.3-32-32-32zM32 160c-17.7 0-32 14.3-32 32s14.3 32 32 32v32c0 77.4 55 142 128 156.8V480c0 17.7 14.3 32 32 32s32-14.3 32-32V412.8c12.3-2.5 24.1-6.4 35.1-11.5c-2.1-10.8-3.1-21.9-3.1-33.3c0-80.3 53.8-148 127.3-169.2c.5-2.2 .7-4.5 .7-6.8c0-17.7-14.3-32-32-32H32zM432 512a144 144 0 1 0 0-288 144 144 0 1 0 0 288zm0-96a24 24 0 1 1 0 48 24 24 0 1 1 0-48zm0-144c8.8 0 16 7.2 16 16v80c0 8.8-7.2 16-16 16s-16-7.2-16-16V288c0-8.8 7.2-16 16-16z" } }, "free": ["solid"] }, "plug-circle-minus": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["electric", "electricity", "plug", "power"] }, "styles": ["solid"], "unicode": "e55e", "label": "Plug Circle Minus", "voted": false, "svg": { "solid": { "last_modified": 1684767441, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M96 0C78.3 0 64 14.3 64 32v96h64V32c0-17.7-14.3-32-32-32zM288 0c-17.7 0-32 14.3-32 32v96h64V32c0-17.7-14.3-32-32-32zM32 160c-17.7 0-32 14.3-32 32s14.3 32 32 32v32c0 77.4 55 142 128 156.8V480c0 17.7 14.3 32 32 32s32-14.3 32-32V412.8c12.3-2.5 24.1-6.4 35.1-11.5c-2.1-10.8-3.1-21.9-3.1-33.3c0-80.3 53.8-148 127.3-169.2c.5-2.2 .7-4.5 .7-6.8c0-17.7-14.3-32-32-32H32zM576 368a144 144 0 1 0 -288 0 144 144 0 1 0 288 0zm-64 0c0 8.8-7.2 16-16 16H368c-8.8 0-16-7.2-16-16s7.2-16 16-16H496c8.8 0 16 7.2 16 16z" } }, "free": ["solid"] }, "plug-circle-plus": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["electric", "electricity", "plug", "power"] }, "styles": ["solid"], "unicode": "e55f", "label": "Plug Circle Plus", "voted": false, "svg": { "solid": { "last_modified": 1684767442, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M96 0C78.3 0 64 14.3 64 32v96h64V32c0-17.7-14.3-32-32-32zM288 0c-17.7 0-32 14.3-32 32v96h64V32c0-17.7-14.3-32-32-32zM32 160c-17.7 0-32 14.3-32 32s14.3 32 32 32v32c0 77.4 55 142 128 156.8V480c0 17.7 14.3 32 32 32s32-14.3 32-32V412.8c12.3-2.5 24.1-6.4 35.1-11.5c-2.1-10.8-3.1-21.9-3.1-33.3c0-80.3 53.8-148 127.3-169.2c.5-2.2 .7-4.5 .7-6.8c0-17.7-14.3-32-32-32H32zM432 512a144 144 0 1 0 0-288 144 144 0 1 0 0 288zm16-208v48h48c8.8 0 16 7.2 16 16s-7.2 16-16 16H448v48c0 8.8-7.2 16-16 16s-16-7.2-16-16V384H368c-8.8 0-16-7.2-16-16s7.2-16 16-16h48V304c0-8.8 7.2-16 16-16s16 7.2 16 16z" } }, "free": ["solid"] }, "plug-circle-xmark": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["destroy", "electric", "electricity", "outage", "plug", "power"] }, "styles": ["solid"], "unicode": "e560", "label": "Plug Circle Xmark", "voted": false, "svg": { "solid": { "last_modified": 1684767442, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M96 0C78.3 0 64 14.3 64 32v96h64V32c0-17.7-14.3-32-32-32zM288 0c-17.7 0-32 14.3-32 32v96h64V32c0-17.7-14.3-32-32-32zM32 160c-17.7 0-32 14.3-32 32s14.3 32 32 32v32c0 77.4 55 142 128 156.8V480c0 17.7 14.3 32 32 32s32-14.3 32-32V412.8c12.3-2.5 24.1-6.4 35.1-11.5c-2.1-10.8-3.1-21.9-3.1-33.3c0-80.3 53.8-148 127.3-169.2c.5-2.2 .7-4.5 .7-6.8c0-17.7-14.3-32-32-32H32zM432 512a144 144 0 1 0 0-288 144 144 0 1 0 0 288zm59.3-180.7L454.6 368l36.7 36.7c6.2 6.2 6.2 16.4 0 22.6s-16.4 6.2-22.6 0L432 390.6l-36.7 36.7c-6.2 6.2-16.4 6.2-22.6 0s-6.2-16.4 0-22.6L409.4 368l-36.7-36.7c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0L432 345.4l36.7-36.7c6.2-6.2 16.4-6.2 22.6 0s6.2 16.4 0 22.6z" } }, "free": ["solid"] }, "plus": { "aliases": { "names": ["add"], "unicodes": { "composite": ["2795", "f067"], "primary": ["f067"], "secondary": ["102b", "10f067"] } }, "changes": [ "1.0.0", "5.0.0", "5.0.13", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "+", "Plus Sign", "add", "create", "expand", "math", "new", "plus", "positive", "shape", "sign" ] }, "styles": ["solid"], "unicode": "2b", "label": "Plus", "voted": false, "svg": { "solid": { "last_modified": 1684767245, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M256 80c0-17.7-14.3-32-32-32s-32 14.3-32 32V224H48c-17.7 0-32 14.3-32 32s14.3 32 32 32H192V432c0 17.7 14.3 32 32 32s32-14.3 32-32V288H400c17.7 0 32-14.3 32-32s-14.3-32-32-32H256V80z" } }, "free": ["solid"] }, "plus-minus": { "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Plus-Minus Sign", "add", "math", "subtract"] }, "styles": ["solid"], "unicode": "e43c", "label": "Plus Minus", "voted": false, "svg": { "solid": { "last_modified": 1684767244, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M224 32c0-17.7-14.3-32-32-32s-32 14.3-32 32V144H48c-17.7 0-32 14.3-32 32s14.3 32 32 32H160V320c0 17.7 14.3 32 32 32s32-14.3 32-32V208H336c17.7 0 32-14.3 32-32s-14.3-32-32-32H224V32zM0 480c0 17.7 14.3 32 32 32H352c17.7 0 32-14.3 32-32s-14.3-32-32-32H32c-17.7 0-32 14.3-32 32z" } }, "free": ["solid"] }, "podcast": { "aliases": { "unicodes": { "secondary": ["10f2ce"] } }, "changes": ["4.7.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["audio", "broadcast", "music", "sound"] }, "styles": ["solid"], "unicode": "f2ce", "label": "Podcast", "voted": false, "svg": { "solid": { "last_modified": 1684766675, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M319.4 372c48.5-31.3 80.6-85.9 80.6-148c0-97.2-78.8-176-176-176S48 126.8 48 224c0 62.1 32.1 116.6 80.6 148c1.2 17.3 4 38 7.2 57.1l.2 1C56 395.8 0 316.5 0 224C0 100.3 100.3 0 224 0S448 100.3 448 224c0 92.5-56 171.9-136 206.1l.2-1.1c3.1-19.2 6-39.8 7.2-57zm-2.3-38.1c-1.6-5.7-3.9-11.1-7-16.2c-5.8-9.7-13.5-17-21.9-22.4c19.5-17.6 31.8-43 31.8-71.3c0-53-43-96-96-96s-96 43-96 96c0 28.3 12.3 53.8 31.8 71.3c-8.4 5.4-16.1 12.7-21.9 22.4c-3.1 5.1-5.4 10.5-7 16.2C99.8 307.5 80 268 80 224c0-79.5 64.5-144 144-144s144 64.5 144 144c0 44-19.8 83.5-50.9 109.9zM224 312c32.9 0 64 8.6 64 43.8c0 33-12.9 104.1-20.6 132.9c-5.1 19-24.5 23.4-43.4 23.4s-38.2-4.4-43.4-23.4c-7.8-28.5-20.6-99.7-20.6-132.8c0-35.1 31.1-43.8 64-43.8zm0-144a56 56 0 1 1 0 112 56 56 0 1 1 0-112z" } }, "free": ["solid"] }, "poo": { "aliases": { "unicodes": { "composite": ["1f4a9"], "secondary": ["10f2fe"] } }, "changes": ["5.0.0", "5.0.9", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "crap", "dung", "face", "monster", "pile of poo", "poo", "poop", "shit", "smile", "turd" ] }, "styles": ["solid"], "unicode": "f2fe", "label": "Poo", "voted": false, "svg": { "solid": { "last_modified": 1684767602, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M268.9 .9c-5.5-.7-11 1.4-14.5 5.7s-4.6 10.1-2.8 15.4c2.8 8.2 4.3 16.9 4.3 26.1c0 44.1-35.7 79.9-79.8 80H160c-35.3 0-64 28.7-64 64c0 19.1 8.4 36.3 21.7 48H104c-39.8 0-72 32.2-72 72c0 23.2 11 43.8 28 57c-34.1 5.7-60 35.3-60 71c0 39.8 32.2 72 72 72H440c39.8 0 72-32.2 72-72c0-35.7-25.9-65.3-60-71c17-13.2 28-33.8 28-57c0-39.8-32.2-72-72-72H394.3c13.3-11.7 21.7-28.9 21.7-48c0-35.3-28.7-64-64-64h-5.5c3.5-10 5.5-20.8 5.5-32c0-48.6-36.2-88.8-83.1-95.1zM192 256a32 32 0 1 1 0 64 32 32 0 1 1 0-64zm96 32a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm64 108.3c0 2.4-.7 4.8-2.2 6.7c-8.2 10.5-39.5 45-93.8 45s-85.6-34.6-93.8-45c-1.5-1.9-2.2-4.3-2.2-6.7c0-6.8 5.5-12.3 12.3-12.3H339.7c6.8 0 12.3 5.5 12.3 12.3z" } }, "free": ["solid"] }, "poo-storm": { "aliases": { "names": ["poo-bolt"], "unicodes": { "secondary": ["10f75a"] } }, "changes": ["5.5.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "bolt", "cloud", "euphemism", "lightning", "mess", "poop", "shit", "turd" ] }, "styles": ["solid"], "unicode": "f75a", "label": "Poo Storm", "voted": false, "svg": { "solid": { "last_modified": 1684767662, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M236.9 .2c-5.5-.7-11 1.4-14.5 5.7s-4.6 10.1-2.8 15.3c2.8 8.2 4.3 16.9 4.3 26.1c0 21.7-8.5 37.2-21.9 47.6c-13.8 10.8-34 17-57.8 17H128c-35.3 0-64 28.7-64 64c0 12.2 3.4 23.5 9.3 33.2C31.7 216.2 0 252.4 0 296c0 41 28 75.4 65.8 85.2c-5.3-18.5 1-38.5 16.2-50.7l160-128c17.6-14.1 42.6-14 60.2 .2s22.8 38.6 12.8 58.8L285.7 320H304c20.4 0 38.5 12.9 45.3 32.1c3.7 10.6 3.5 21.8 0 31.9H360c48.6 0 88-39.4 88-88c0-43.6-31.7-79.8-73.3-86.8c5.9-9.7 9.3-21.1 9.3-33.2c0-35.3-28.7-64-64-64h-1.4c.9-5.4 1.4-10.9 1.4-16.6c0-48.7-36.1-88.9-83.1-95.2zm45.1 227.4c-5.8-4.7-14.2-4.7-20.1-.1l-160 128c-5.3 4.2-7.4 11.4-5.1 17.8s8.3 10.7 15.1 10.7h70.1L129.7 488.8c-3.4 6.7-1.6 14.9 4.3 19.6s14.2 4.7 20.1 .1l160-128c5.3-4.2 7.4-11.4 5.1-17.8s-8.3-10.7-15.1-10.7H233.9l52.4-104.8c3.4-6.7 1.6-14.9-4.3-19.6z" } }, "free": ["solid"] }, "poop": { "aliases": { "unicodes": { "secondary": ["10f619"] } }, "changes": ["5.2.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0", "6.4.1"], "ligatures": [], "search": { "terms": ["crap", "poop", "shit", "smile", "turd"] }, "styles": ["solid"], "unicode": "f619", "label": "Poop", "voted": false, "svg": { "solid": { "last_modified": 1684767602, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M254.4 6.6c3.5-4.3 9-6.5 14.5-5.7C315.8 7.2 352 47.4 352 96c0 11.2-1.9 22-5.5 32H352c35.3 0 64 28.7 64 64c0 19.1-8.4 36.3-21.7 48H408c39.8 0 72 32.2 72 72c0 23.2-11 43.8-28 57c34.1 5.7 60 35.3 60 71c0 39.8-32.2 72-72 72H72c-39.8 0-72-32.2-72-72c0-35.7 25.9-65.3 60-71c-17-13.2-28-33.8-28-57c0-39.8 32.2-72 72-72h13.7C104.4 228.3 96 211.1 96 192c0-35.3 28.7-64 64-64h16.2c44.1-.1 79.8-35.9 79.8-80c0-9.2-1.5-17.9-4.3-26.1c-1.8-5.2-.8-11.1 2.8-15.4z" } }, "free": ["solid"] }, "power-off": { "aliases": { "unicodes": { "composite": ["23fb"], "secondary": ["10f011"] } }, "changes": [ "1.0.0", "5.0.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["Power Symbol", "cancel", "computer", "on", "reboot", "restart"] }, "styles": ["solid"], "unicode": "f011", "label": "Power Off", "voted": false, "svg": { "solid": { "last_modified": 1684767551, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M288 32c0-17.7-14.3-32-32-32s-32 14.3-32 32V256c0 17.7 14.3 32 32 32s32-14.3 32-32V32zM143.5 120.6c13.6-11.3 15.4-31.5 4.1-45.1s-31.5-15.4-45.1-4.1C49.7 115.4 16 181.8 16 256c0 132.5 107.5 240 240 240s240-107.5 240-240c0-74.2-33.8-140.6-86.6-184.6c-13.6-11.3-33.8-9.4-45.1 4.1s-9.4 33.8 4.1 45.1c38.9 32.3 63.5 81 63.5 135.4c0 97.2-78.8 176-176 176s-176-78.8-176-176c0-54.4 24.7-103.1 63.5-135.4z" } }, "free": ["solid"] }, "prescription": { "aliases": { "unicodes": { "secondary": ["10f5b1"] } }, "changes": ["5.1.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["drugs", "medical", "medicine", "pharmacy", "rx"] }, "styles": ["solid"], "unicode": "f5b1", "label": "Prescription", "voted": false, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M32 0C14.3 0 0 14.3 0 32V192v96c0 17.7 14.3 32 32 32s32-14.3 32-32V224h50.7l128 128L137.4 457.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L288 397.3 393.4 502.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L333.3 352 438.6 246.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L288 306.7l-85.8-85.8C251.4 209.1 288 164.8 288 112C288 50.1 237.9 0 176 0H32zM176 160H64V64H176c26.5 0 48 21.5 48 48s-21.5 48-48 48z" } }, "free": ["solid"] }, "prescription-bottle": { "aliases": { "unicodes": { "secondary": ["10f485"] } }, "changes": ["5.0.7", "6.0.0-beta1", "6.2.0", "6.2.1", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["drugs", "medical", "medicine", "pharmacy", "rx"] }, "styles": ["solid"], "unicode": "f485", "label": "Prescription Bottle", "voted": false, "svg": { "solid": { "last_modified": 1684766751, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M0 32C0 14.3 14.3 0 32 0H352c17.7 0 32 14.3 32 32V64c0 17.7-14.3 32-32 32H32C14.3 96 0 81.7 0 64V32zm32 96H352V448c0 35.3-28.7 64-64 64H96c-35.3 0-64-28.7-64-64V416H144c8.8 0 16-7.2 16-16s-7.2-16-16-16H32V320H144c8.8 0 16-7.2 16-16s-7.2-16-16-16H32V224H144c8.8 0 16-7.2 16-16s-7.2-16-16-16H32V128z" } }, "free": ["solid"] }, "prescription-bottle-medical": { "aliases": { "names": ["prescription-bottle-alt"], "unicodes": { "secondary": ["10f486"] } }, "changes": ["5.0.7", "6.0.0-beta1", "6.2.0", "6.2.1", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["drugs", "medical", "medicine", "pharmacy", "rx"] }, "styles": ["solid"], "unicode": "f486", "label": "Prescription Bottle Medical", "voted": false, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M0 32C0 14.3 14.3 0 32 0H352c17.7 0 32 14.3 32 32V64c0 17.7-14.3 32-32 32H32C14.3 96 0 81.7 0 64V32zm32 96H352V448c0 35.3-28.7 64-64 64H96c-35.3 0-64-28.7-64-64V128zM160 240v48H112c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h48v48c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V352h48c8.8 0 16-7.2 16-16V304c0-8.8-7.2-16-16-16H224V240c0-8.8-7.2-16-16-16H176c-8.8 0-16 7.2-16 16z" } }, "free": ["solid"] }, "print": { "aliases": { "unicodes": { "composite": ["1f5a8", "1f5b6", "2399"], "secondary": ["10f02f"] } }, "changes": [ "1.0.0", "5.0.0", "5.3.0", "5.11.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Print Screen Symbol", "Printer Icon", "business", "computer", "copy", "document", "office", "paper", "printer" ] }, "styles": ["solid"], "unicode": "f02f", "label": "Print", "voted": false, "svg": { "solid": { "last_modified": 1684767341, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M128 0C92.7 0 64 28.7 64 64v96h64V64H354.7L384 93.3V160h64V93.3c0-17-6.7-33.3-18.7-45.3L400 18.7C388 6.7 371.7 0 354.7 0H128zM384 352v32 64H128V384 368 352H384zm64 32h32c17.7 0 32-14.3 32-32V256c0-35.3-28.7-64-64-64H64c-35.3 0-64 28.7-64 64v96c0 17.7 14.3 32 32 32H64v64c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V384zM432 248a24 24 0 1 1 0 48 24 24 0 1 1 0-48z" } }, "free": ["solid"] }, "product-hunt": { "changes": ["4.5.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f288", "label": "Product Hunt", "voted": false, "svg": { "brands": { "last_modified": 1660014473, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M326.3 218.8c0 20.5-16.7 37.2-37.2 37.2h-70.3v-74.4h70.3c20.5 0 37.2 16.7 37.2 37.2zM504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-128.1-37.2c0-47.9-38.9-86.8-86.8-86.8H169.2v248h49.6v-74.4h70.3c47.9 0 86.8-38.9 86.8-86.8z" } }, "free": ["brands"] }, "pump-medical": { "aliases": { "unicodes": { "secondary": ["10e06a"] } }, "changes": ["5.13.0", "5.14.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "anti-bacterial", "clean", "covid-19", "disinfect", "hygiene", "medical grade", "sanitizer", "soap" ] }, "styles": ["solid"], "unicode": "e06a", "label": "Pump Medical", "voted": false, "svg": { "solid": { "last_modified": 1684767444, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M128 32v96H256V96h60.1c4.2 0 8.3 1.7 11.3 4.7l33.9 33.9c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L372.7 55.4c-15-15-35.4-23.4-56.6-23.4H256c0-17.7-14.3-32-32-32H160c-17.7 0-32 14.3-32 32zM117.4 160c-33.3 0-61 25.5-63.8 58.7L35 442.7C31.9 480 61.3 512 98.8 512H285.2c37.4 0 66.9-32 63.8-69.3l-18.7-224c-2.8-33.2-30.5-58.7-63.8-58.7H117.4zM216 280v32h32c13.3 0 24 10.7 24 24s-10.7 24-24 24H216v32c0 13.3-10.7 24-24 24s-24-10.7-24-24V360H136c-13.3 0-24-10.7-24-24s10.7-24 24-24h32V280c0-13.3 10.7-24 24-24s24 10.7 24 24z" } }, "free": ["solid"] }, "pump-soap": { "aliases": { "unicodes": { "secondary": ["10e06b"] } }, "changes": ["5.13.0", "5.14.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "anti-bacterial", "clean", "covid-19", "disinfect", "hygiene", "sanitizer", "soap" ] }, "styles": ["solid"], "unicode": "e06b", "label": "Pump Soap", "voted": false, "svg": { "solid": { "last_modified": 1684767441, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M128 32v96H256V96h60.1c4.2 0 8.3 1.7 11.3 4.7l33.9 33.9c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L372.7 55.4c-15-15-35.4-23.4-56.6-23.4H256c0-17.7-14.3-32-32-32H160c-17.7 0-32 14.3-32 32zM117.4 160c-33.3 0-61 25.5-63.8 58.7L35 442.7C31.9 480 61.3 512 98.8 512H285.2c37.4 0 66.9-32 63.8-69.3l-18.7-224c-2.8-33.2-30.5-58.7-63.8-58.7H117.4zM256 360c0 35.3-28.7 56-64 56s-64-20.7-64-56c0-32.5 37-80.9 50.9-97.9c3.2-3.9 8.1-6.1 13.1-6.1s9.9 2.2 13.1 6.1C219 279.1 256 327.5 256 360z" } }, "free": ["solid"] }, "pushed": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3e1", "label": "Pushed", "voted": false, "svg": { "brands": { "last_modified": 1660014459, "raw": "", "viewBox": [0, 0, 432, 512], "width": 432, "height": 512, "path": "M407 111.9l-98.5-9 14-33.4c10.4-23.5-10.8-40.4-28.7-37L22.5 76.9c-15.1 2.7-26 18.3-21.4 36.6l105.1 348.3c6.5 21.3 36.7 24.2 47.7 7l35.3-80.8 235.2-231.3c16.4-16.8 4.3-42.9-17.4-44.8zM297.6 53.6c5.1-.7 7.5 2.5 5.2 7.4L286 100.9 108.6 84.6l189-31zM22.7 107.9c-3.1-5.1 1-10 6.1-9.1l248.7 22.7-96.9 230.7L22.7 107.9zM136 456.4c-2.6 4-7.9 3.1-9.4-1.2L43.5 179.7l127.7 197.6c-7 15-35.2 79.1-35.2 79.1zm272.8-314.5L210.1 337.3l89.7-213.7 106.4 9.7c4 1.1 5.7 5.3 2.6 8.6z" } }, "free": ["brands"] }, "puzzle-piece": { "aliases": { "unicodes": { "composite": ["1f9e9"], "secondary": ["10f12e"] } }, "changes": [ "3.1.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0", "6.4.1" ], "ligatures": [], "search": { "terms": [ "add-on", "addon", "clue", "game", "interlocking", "jigsaw", "piece", "puzzle", "puzzle piece", "section" ] }, "styles": ["solid"], "unicode": "f12e", "label": "Puzzle Piece", "voted": false, "svg": { "solid": { "last_modified": 1684767071, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M192 104.8c0-9.2-5.8-17.3-13.2-22.8C167.2 73.3 160 61.3 160 48c0-26.5 28.7-48 64-48s64 21.5 64 48c0 13.3-7.2 25.3-18.8 34c-7.4 5.5-13.2 13.6-13.2 22.8v0c0 12.8 10.4 23.2 23.2 23.2H336c26.5 0 48 21.5 48 48v56.8c0 12.8 10.4 23.2 23.2 23.2v0c9.2 0 17.3-5.8 22.8-13.2c8.7-11.6 20.7-18.8 34-18.8c26.5 0 48 28.7 48 64s-21.5 64-48 64c-13.3 0-25.3-7.2-34-18.8c-5.5-7.4-13.6-13.2-22.8-13.2v0c-12.8 0-23.2 10.4-23.2 23.2V464c0 26.5-21.5 48-48 48H279.2c-12.8 0-23.2-10.4-23.2-23.2v0c0-9.2 5.8-17.3 13.2-22.8c11.6-8.7 18.8-20.7 18.8-34c0-26.5-28.7-48-64-48s-64 21.5-64 48c0 13.3 7.2 25.3 18.8 34c7.4 5.5 13.2 13.6 13.2 22.8v0c0 12.8-10.4 23.2-23.2 23.2H48c-26.5 0-48-21.5-48-48V343.2C0 330.4 10.4 320 23.2 320v0c9.2 0 17.3 5.8 22.8 13.2C54.7 344.8 66.7 352 80 352c26.5 0 48-28.7 48-64s-21.5-64-48-64c-13.3 0-25.3 7.2-34 18.8C40.5 250.2 32.4 256 23.2 256v0C10.4 256 0 245.6 0 232.8V176c0-26.5 21.5-48 48-48H168.8c12.8 0 23.2-10.4 23.2-23.2v0z" } }, "free": ["solid"] }, "python": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3e2", "label": "Python", "voted": false, "svg": { "brands": { "last_modified": 1660014462, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M439.8 200.5c-7.7-30.9-22.3-54.2-53.4-54.2h-40.1v47.4c0 36.8-31.2 67.8-66.8 67.8H172.7c-29.2 0-53.4 25-53.4 54.3v101.8c0 29 25.2 46 53.4 54.3 33.8 9.9 66.3 11.7 106.8 0 26.9-7.8 53.4-23.5 53.4-54.3v-40.7H226.2v-13.6h160.2c31.1 0 42.6-21.7 53.4-54.2 11.2-33.5 10.7-65.7 0-108.6zM286.2 404c11.1 0 20.1 9.1 20.1 20.3 0 11.3-9 20.4-20.1 20.4-11 0-20.1-9.2-20.1-20.4.1-11.3 9.1-20.3 20.1-20.3zM167.8 248.1h106.8c29.7 0 53.4-24.5 53.4-54.3V91.9c0-29-24.4-50.7-53.4-55.6-35.8-5.9-74.7-5.6-106.8.1-45.2 8-53.4 24.7-53.4 55.6v40.7h106.9v13.6h-147c-31.1 0-58.3 18.7-66.8 54.2-9.8 40.7-10.2 66.1 0 108.6 7.6 31.6 25.7 54.2 56.8 54.2H101v-48.8c0-35.3 30.5-66.4 66.8-66.4zm-6.7-142.6c-11.1 0-20.1-9.1-20.1-20.3.1-11.3 9-20.4 20.1-20.4 11 0 20.1 9.2 20.1 20.4s-9 20.3-20.1 20.3z" } }, "free": ["brands"] }, "q": { "aliases": { "unicodes": { "composite": ["71"] } }, "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Latin Capital Letter Q", "Latin Small Letter Q", "letter"] }, "styles": ["solid"], "unicode": "51", "label": "Q", "voted": false, "svg": { "solid": { "last_modified": 1684767247, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M64 256c0 88.4 71.6 160 160 160c28.9 0 56-7.7 79.4-21.1l-72-86.4c-11.3-13.6-9.5-33.8 4.1-45.1s33.8-9.5 45.1 4.1l70.9 85.1C371.9 325.8 384 292.3 384 256c0-88.4-71.6-160-160-160S64 167.6 64 256zM344.9 444.6C310 467 268.5 480 224 480C100.3 480 0 379.7 0 256S100.3 32 224 32s224 100.3 224 224c0 56.1-20.6 107.4-54.7 146.7l47.3 56.8c11.3 13.6 9.5 33.8-4.1 45.1s-33.8 9.5-45.1-4.1l-46.6-55.9z" } }, "free": ["solid"] }, "qq": { "changes": ["4.1.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f1d6", "label": "QQ", "voted": false, "svg": { "brands": { "last_modified": 1660014481, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M433.754 420.445c-11.526 1.393-44.86-52.741-44.86-52.741 0 31.345-16.136 72.247-51.051 101.786 16.842 5.192 54.843 19.167 45.803 34.421-7.316 12.343-125.51 7.881-159.632 4.037-34.122 3.844-152.316 8.306-159.632-4.037-9.045-15.25 28.918-29.214 45.783-34.415-34.92-29.539-51.059-70.445-51.059-101.792 0 0-33.334 54.134-44.859 52.741-5.37-.65-12.424-29.644 9.347-99.704 10.261-33.024 21.995-60.478 40.144-105.779C60.683 98.063 108.982.006 224 0c113.737.006 163.156 96.133 160.264 214.963 18.118 45.223 29.912 72.85 40.144 105.778 21.768 70.06 14.716 99.053 9.346 99.704z" } }, "free": ["brands"] }, "qrcode": { "aliases": { "unicodes": { "secondary": ["10f029"] } }, "changes": [ "1.0.0", "5.0.0", "5.10.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["barcode", "info", "information", "scan"] }, "styles": ["solid"], "unicode": "f029", "label": "Qrcode", "voted": false, "svg": { "solid": { "last_modified": 1684766474, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M0 80C0 53.5 21.5 32 48 32h96c26.5 0 48 21.5 48 48v96c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80zM64 96v64h64V96H64zM0 336c0-26.5 21.5-48 48-48h96c26.5 0 48 21.5 48 48v96c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V336zm64 16v64h64V352H64zM304 32h96c26.5 0 48 21.5 48 48v96c0 26.5-21.5 48-48 48H304c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48zm80 64H320v64h64V96zM256 304c0-8.8 7.2-16 16-16h64c8.8 0 16 7.2 16 16s7.2 16 16 16h32c8.8 0 16-7.2 16-16s7.2-16 16-16s16 7.2 16 16v96c0 8.8-7.2 16-16 16H368c-8.8 0-16-7.2-16-16s-7.2-16-16-16s-16 7.2-16 16v64c0 8.8-7.2 16-16 16H272c-8.8 0-16-7.2-16-16V304zM368 480a16 16 0 1 1 0-32 16 16 0 1 1 0 32zm64 0a16 16 0 1 1 0-32 16 16 0 1 1 0 32z" } }, "free": ["solid"] }, "question": { "aliases": { "unicodes": { "composite": ["2753", "2754", "f128"], "primary": ["f128"], "secondary": ["103f", "10f128"] } }, "changes": ["3.1.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "?", "Question Mark", "help", "information", "mark", "outlined", "punctuation", "question", "red question mark", "support", "unknown", "white question mark" ] }, "styles": ["solid"], "unicode": "3f", "label": "Question", "voted": false, "svg": { "solid": { "last_modified": 1684767246, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M80 160c0-35.3 28.7-64 64-64h32c35.3 0 64 28.7 64 64v3.6c0 21.8-11.1 42.1-29.4 53.8l-42.2 27.1c-25.2 16.2-40.4 44.1-40.4 74V320c0 17.7 14.3 32 32 32s32-14.3 32-32v-1.4c0-8.2 4.2-15.8 11-20.2l42.2-27.1c36.6-23.6 58.8-64.1 58.8-107.7V160c0-70.7-57.3-128-128-128H144C73.3 32 16 89.3 16 160c0 17.7 14.3 32 32 32s32-14.3 32-32zm80 320a40 40 0 1 0 0-80 40 40 0 1 0 0 80z" } }, "free": ["solid"] }, "quinscape": { "changes": ["5.0.5", "5.7.0", "5.8.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f459", "label": "QuinScape", "voted": false, "svg": { "brands": { "last_modified": 1660014471, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M313.6 474.6h-1a158.1 158.1 0 0 1 0-316.2c94.9 0 168.2 83.1 157 176.6 4 5.1 8.2 9.6 11.2 15.3 13.4-30.3 20.3-62.4 20.3-97.7C501.1 117.5 391.6 8 256.5 8S12 117.5 12 252.6s109.5 244.6 244.5 244.6a237.36 237.36 0 0 0 70.4-10.1c-5.2-3.5-8.9-8.1-13.3-12.5zm-.1-.1l.4.1zm78.4-168.9a99.2 99.2 0 1 0 99.2 99.2 99.18 99.18 0 0 0-99.2-99.2z" } }, "free": ["brands"] }, "quora": { "changes": ["4.7.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f2c4", "label": "Quora", "voted": false, "svg": { "brands": { "last_modified": 1660014460, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M440.5 386.7h-29.3c-1.5 13.5-10.5 30.8-33 30.8-20.5 0-35.3-14.2-49.5-35.8 44.2-34.2 74.7-87.5 74.7-153C403.5 111.2 306.8 32 205 32 105.3 32 7.3 111.7 7.3 228.7c0 134.1 131.3 221.6 249 189C276 451.3 302 480 351.5 480c81.8 0 90.8-75.3 89-93.3zM297 329.2C277.5 300 253.3 277 205.5 277c-30.5 0-54.3 10-69 22.8l12.2 24.3c6.2-3 13-4 19.8-4 35.5 0 53.7 30.8 69.2 61.3-10 3-20.7 4.2-32.7 4.2-75 0-107.5-53-107.5-156.7C97.5 124.5 130 71 205 71c76.2 0 108.7 53.5 108.7 157.7.1 41.8-5.4 75.6-16.7 100.5z" } }, "free": ["brands"] }, "quote-left": { "aliases": { "names": ["quote-left-alt"], "unicodes": { "composite": ["201c"], "secondary": ["10f10d"] } }, "changes": [ "3.0.0", "5.0.0", "5.0.9", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Left Double Quotation Mark", "mention", "note", "phrase", "text", "type" ] }, "styles": ["solid"], "unicode": "f10d", "label": "Quote Left", "voted": false, "svg": { "solid": { "last_modified": 1684767244, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M0 216C0 149.7 53.7 96 120 96h8c17.7 0 32 14.3 32 32s-14.3 32-32 32h-8c-30.9 0-56 25.1-56 56v8h64c35.3 0 64 28.7 64 64v64c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V320 288 216zm256 0c0-66.3 53.7-120 120-120h8c17.7 0 32 14.3 32 32s-14.3 32-32 32h-8c-30.9 0-56 25.1-56 56v8h64c35.3 0 64 28.7 64 64v64c0 35.3-28.7 64-64 64H320c-35.3 0-64-28.7-64-64V320 288 216z" } }, "free": ["solid"] }, "quote-right": { "aliases": { "names": ["quote-right-alt"], "unicodes": { "composite": ["201d"], "secondary": ["10f10e"] } }, "changes": [ "3.0.0", "5.0.0", "5.0.9", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Right Double Quotation Mark", "mention", "note", "phrase", "text", "type" ] }, "styles": ["solid"], "unicode": "f10e", "label": "Quote Right", "voted": false, "svg": { "solid": { "last_modified": 1684767246, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M448 296c0 66.3-53.7 120-120 120h-8c-17.7 0-32-14.3-32-32s14.3-32 32-32h8c30.9 0 56-25.1 56-56v-8H320c-35.3 0-64-28.7-64-64V160c0-35.3 28.7-64 64-64h64c35.3 0 64 28.7 64 64v32 32 72zm-256 0c0 66.3-53.7 120-120 120H64c-17.7 0-32-14.3-32-32s14.3-32 32-32h8c30.9 0 56-25.1 56-56v-8H64c-35.3 0-64-28.7-64-64V160c0-35.3 28.7-64 64-64h64c35.3 0 64 28.7 64 64v32 32 72z" } }, "free": ["solid"] }, "r": { "aliases": { "unicodes": { "composite": ["72"] } }, "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Latin Capital Letter R", "Latin Small Letter R", "letter"] }, "styles": ["solid"], "unicode": "52", "label": "R", "voted": false, "svg": { "solid": { "last_modified": 1684767246, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M64 32C28.7 32 0 60.7 0 96V288 448c0 17.7 14.3 32 32 32s32-14.3 32-32V320h95.3L261.8 466.4c10.1 14.5 30.1 18 44.6 7.9s18-30.1 7.9-44.6L230.1 309.5C282.8 288.1 320 236.4 320 176c0-79.5-64.5-144-144-144H64zM176 256H64V96H176c44.2 0 80 35.8 80 80s-35.8 80-80 80z" } }, "free": ["solid"] }, "r-project": { "changes": ["5.0.11", "5.0.12"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f4f7", "label": "R Project", "voted": true, "svg": { "brands": { "last_modified": 1660014477, "raw": "", "viewBox": [0, 0, 581, 512], "width": 581, "height": 512, "path": "M581 226.6C581 119.1 450.9 32 290.5 32S0 119.1 0 226.6C0 322.4 103.3 402 239.4 418.1V480h99.1v-61.5c24.3-2.7 47.6-7.4 69.4-13.9L448 480h112l-67.4-113.7c54.5-35.4 88.4-84.9 88.4-139.7zm-466.8 14.5c0-73.5 98.9-133 220.8-133s211.9 40.7 211.9 133c0 50.1-26.5 85-70.3 106.4-2.4-1.6-4.7-2.9-6.4-3.7-10.2-5.2-27.8-10.5-27.8-10.5s86.6-6.4 86.6-92.7-90.6-87.9-90.6-87.9h-199V361c-74.1-21.5-125.2-67.1-125.2-119.9zm225.1 38.3v-55.6c57.8 0 87.8-6.8 87.8 27.3 0 36.5-38.2 28.3-87.8 28.3zm-.9 72.5H365c10.8 0 18.9 11.7 24 19.2-16.1 1.9-33 2.8-50.6 2.9v-22.1z" } }, "free": ["brands"] }, "radiation": { "aliases": { "unicodes": { "secondary": ["10f7b9"] } }, "changes": [ "5.6.0", "5.8.2", "5.11.0", "5.11.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "danger", "dangerous", "deadly", "hazard", "nuclear", "radioactive", "warning" ] }, "styles": ["solid"], "unicode": "f7b9", "label": "Radiation", "voted": true, "svg": { "solid": { "last_modified": 1684766751, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M216 186.7c-23.9 13.8-40 39.7-40 69.3L32 256C14.3 256-.2 241.6 2 224.1C10.7 154 47.8 92.7 101.3 52c14.1-10.7 33.8-5.3 42.7 10l72 124.7zM256 336c14.6 0 28.2-3.9 40-10.7l72 124.8c8.8 15.3 3.7 35.1-12.6 41.9c-30.6 12.9-64.2 20-99.4 20s-68.9-7.1-99.4-20c-16.3-6.9-21.4-26.6-12.6-41.9l72-124.8c11.8 6.8 25.4 10.7 40 10.7zm224-80l-144 0c0-29.6-16.1-55.5-40-69.3L368 62c8.8-15.3 28.6-20.7 42.7-10c53.6 40.7 90.6 102 99.4 172.1c2.2 17.5-12.4 31.9-30 31.9zM256 208a48 48 0 1 1 0 96 48 48 0 1 1 0-96z" } }, "free": ["solid"] }, "radio": { "aliases": { "unicodes": { "composite": ["1f4fb"], "secondary": ["10f8d7"] } }, "changes": ["5.11.0", "6.0.0-beta1", "6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "am", "broadcast", "fm", "frequency", "music", "news", "radio", "receiver", "transmitter", "tuner", "video" ] }, "styles": ["solid"], "unicode": "f8d7", "label": "Radio", "voted": false, "svg": { "solid": { "last_modified": 1684766675, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M494.8 47c12.7-3.7 20-17.1 16.3-29.8S494-2.8 481.2 1L51.7 126.9c-9.4 2.7-17.9 7.3-25.1 13.2C10.5 151.7 0 170.6 0 192v4V304 448c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V192c0-35.3-28.7-64-64-64H218.5L494.8 47zM368 240a80 80 0 1 1 0 160 80 80 0 1 1 0-160zM80 256c0-8.8 7.2-16 16-16h96c8.8 0 16 7.2 16 16s-7.2 16-16 16H96c-8.8 0-16-7.2-16-16zM64 320c0-8.8 7.2-16 16-16H208c8.8 0 16 7.2 16 16s-7.2 16-16 16H80c-8.8 0-16-7.2-16-16zm16 64c0-8.8 7.2-16 16-16h96c8.8 0 16 7.2 16 16s-7.2 16-16 16H96c-8.8 0-16-7.2-16-16z" } }, "free": ["solid"] }, "rainbow": { "aliases": { "unicodes": { "composite": ["1f308"], "secondary": ["10f75b"] } }, "changes": ["5.5.0", "5.10.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["gold", "leprechaun", "prism", "rain", "rainbow", "sky"] }, "styles": ["solid"], "unicode": "f75b", "label": "Rainbow", "voted": false, "svg": { "solid": { "last_modified": 1684767662, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M320 96C178.6 96 64 210.6 64 352v96c0 17.7-14.3 32-32 32s-32-14.3-32-32V352C0 175.3 143.3 32 320 32s320 143.3 320 320v96c0 17.7-14.3 32-32 32s-32-14.3-32-32V352C576 210.6 461.4 96 320 96zm0 192c-35.3 0-64 28.7-64 64v96c0 17.7-14.3 32-32 32s-32-14.3-32-32V352c0-70.7 57.3-128 128-128s128 57.3 128 128v96c0 17.7-14.3 32-32 32s-32-14.3-32-32V352c0-35.3-28.7-64-64-64zM160 352v96c0 17.7-14.3 32-32 32s-32-14.3-32-32V352c0-123.7 100.3-224 224-224s224 100.3 224 224v96c0 17.7-14.3 32-32 32s-32-14.3-32-32V352c0-88.4-71.6-160-160-160s-160 71.6-160 160z" } }, "free": ["solid"] }, "ranking-star": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["chart", "first place", "podium", "rank", "win"] }, "styles": ["solid"], "unicode": "e561", "label": "Ranking Star", "voted": false, "svg": { "solid": { "last_modified": 1684767070, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M353.8 54.1L330.2 6.3c-3.9-8.3-16.1-8.6-20.4 0L286.2 54.1l-52.3 7.5c-9.3 1.4-13.3 12.9-6.4 19.8l38 37-9 52.1c-1.4 9.3 8.2 16.5 16.8 12.2l46.9-24.8 46.6 24.4c8.6 4.3 18.3-2.9 16.8-12.2l-9-52.1 38-36.6c6.8-6.8 2.9-18.3-6.4-19.8l-52.3-7.5zM256 256c-17.7 0-32 14.3-32 32V480c0 17.7 14.3 32 32 32H384c17.7 0 32-14.3 32-32V288c0-17.7-14.3-32-32-32H256zM32 320c-17.7 0-32 14.3-32 32V480c0 17.7 14.3 32 32 32H160c17.7 0 32-14.3 32-32V352c0-17.7-14.3-32-32-32H32zm416 96v64c0 17.7 14.3 32 32 32H608c17.7 0 32-14.3 32-32V416c0-17.7-14.3-32-32-32H480c-17.7 0-32 14.3-32 32z" } }, "free": ["solid"] }, "raspberry-pi": { "changes": ["5.6.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f7bb", "label": "Raspberry Pi", "voted": true, "svg": { "brands": { "last_modified": 1660014465, "raw": "", "viewBox": [0, 0, 407, 512], "width": 407, "height": 512, "path": "M372 232.5l-3.7-6.5c.1-46.4-21.4-65.3-46.5-79.7 7.6-2 15.4-3.6 17.6-13.2 13.1-3.3 15.8-9.4 17.1-15.8 3.4-2.3 14.8-8.7 13.6-19.7 6.4-4.4 10-10.1 8.1-18.1 6.9-7.5 8.7-13.7 5.8-19.4 8.3-10.3 4.6-15.6 1.1-20.9 6.2-11.2.7-23.2-16.6-21.2-6.9-10.1-21.9-7.8-24.2-7.8-2.6-3.2-6-6-16.5-4.7-6.8-6.1-14.4-5-22.3-2.1-9.3-7.3-15.5-1.4-22.6.8C271.6.6 269 5.5 263.5 7.6c-12.3-2.6-16.1 3-22 8.9l-6.9-.1c-18.6 10.8-27.8 32.8-31.1 44.1-3.3-11.3-12.5-33.3-31.1-44.1l-6.9.1c-5.9-5.9-9.7-11.5-22-8.9-5.6-2-8.1-7-19.4-3.4-4.6-1.4-8.9-4.4-13.9-4.3-2.6.1-5.5 1-8.7 3.5-7.9-3-15.5-4-22.3 2.1-10.5-1.3-14 1.4-16.5 4.7-2.3 0-17.3-2.3-24.2 7.8C21.2 16 15.8 28 22 39.2c-3.5 5.4-7.2 10.7 1.1 20.9-2.9 5.7-1.1 11.9 5.8 19.4-1.8 8 1.8 13.7 8.1 18.1-1.2 11 10.2 17.4 13.6 19.7 1.3 6.4 4 12.4 17.1 15.8 2.2 9.5 10 11.2 17.6 13.2-25.1 14.4-46.6 33.3-46.5 79.7l-3.7 6.5c-28.8 17.2-54.7 72.7-14.2 117.7 2.6 14.1 7.1 24.2 11 35.4 5.9 45.2 44.5 66.3 54.6 68.8 14.9 11.2 30.8 21.8 52.2 29.2C159 504.2 181 512 203 512h1c22.1 0 44-7.8 64.2-28.4 21.5-7.4 37.3-18 52.2-29.2 10.2-2.5 48.7-23.6 54.6-68.8 3.9-11.2 8.4-21.3 11-35.4 40.6-45.1 14.7-100.5-14-117.7zm-22.2-8c-1.5 18.7-98.9-65.1-82.1-67.9 45.7-7.5 83.6 19.2 82.1 67.9zm-43 93.1c-24.5 15.8-59.8 5.6-78.8-22.8s-14.6-64.2 9.9-80c24.5-15.8 59.8-5.6 78.8 22.8s14.6 64.2-9.9 80zM238.9 29.3c.8 4.2 1.8 6.8 2.9 7.6 5.4-5.8 9.8-11.7 16.8-17.3 0 3.3-1.7 6.8 2.5 9.4 3.7-5 8.8-9.5 15.5-13.3-3.2 5.6-.6 7.3 1.2 9.6 5.1-4.4 10-8.8 19.4-12.3-2.6 3.1-6.2 6.2-2.4 9.8 5.3-3.3 10.6-6.6 23.1-8.9-2.8 3.1-8.7 6.3-5.1 9.4 6.6-2.5 14-4.4 22.1-5.4-3.9 3.2-7.1 6.3-3.9 8.8 7.1-2.2 16.9-5.1 26.4-2.6l-6 6.1c-.7.8 14.1.6 23.9.8-3.6 5-7.2 9.7-9.3 18.2 1 1 5.8.4 10.4 0-4.7 9.9-12.8 12.3-14.7 16.6 2.9 2.2 6.8 1.6 11.2.1-3.4 6.9-10.4 11.7-16 17.3 1.4 1 3.9 1.6 9.7.9-5.2 5.5-11.4 10.5-18.8 15 1.3 1.5 5.8 1.5 10 1.6-6.7 6.5-15.3 9.9-23.4 14.2 4 2.7 6.9 2.1 10 2.1-5.7 4.7-15.4 7.1-24.4 10 1.7 2.7 3.4 3.4 7.1 4.1-9.5 5.3-23.2 2.9-27 5.6.9 2.7 3.6 4.4 6.7 5.8-15.4.9-57.3-.6-65.4-32.3 15.7-17.3 44.4-37.5 93.7-62.6-38.4 12.8-73 30-102 53.5-34.3-15.9-10.8-55.9 5.8-71.8zm-34.4 114.6c24.2-.3 54.1 17.8 54 34.7-.1 15-21 27.1-53.8 26.9-32.1-.4-53.7-15.2-53.6-29.8 0-11.9 26.2-32.5 53.4-31.8zm-123-12.8c3.7-.7 5.4-1.5 7.1-4.1-9-2.8-18.7-5.3-24.4-10 3.1 0 6 .7 10-2.1-8.1-4.3-16.7-7.7-23.4-14.2 4.2-.1 8.7 0 10-1.6-7.4-4.5-13.6-9.5-18.8-15 5.8.7 8.3.1 9.7-.9-5.6-5.6-12.7-10.4-16-17.3 4.3 1.5 8.3 2 11.2-.1-1.9-4.2-10-6.7-14.7-16.6 4.6.4 9.4 1 10.4 0-2.1-8.5-5.8-13.3-9.3-18.2 9.8-.1 24.6 0 23.9-.8l-6-6.1c9.5-2.5 19.3.4 26.4 2.6 3.2-2.5-.1-5.6-3.9-8.8 8.1 1.1 15.4 2.9 22.1 5.4 3.5-3.1-2.3-6.3-5.1-9.4 12.5 2.3 17.8 5.6 23.1 8.9 3.8-3.6.2-6.7-2.4-9.8 9.4 3.4 14.3 7.9 19.4 12.3 1.7-2.3 4.4-4 1.2-9.6 6.7 3.8 11.8 8.3 15.5 13.3 4.1-2.6 2.5-6.2 2.5-9.4 7 5.6 11.4 11.5 16.8 17.3 1.1-.8 2-3.4 2.9-7.6 16.6 15.9 40.1 55.9 6 71.8-29-23.5-63.6-40.7-102-53.5 49.3 25 78 45.3 93.7 62.6-8 31.8-50 33.2-65.4 32.3 3.1-1.4 5.8-3.2 6.7-5.8-4-2.8-17.6-.4-27.2-5.6zm60.1 24.1c16.8 2.8-80.6 86.5-82.1 67.9-1.5-48.7 36.5-75.5 82.1-67.9zM38.2 342c-23.7-18.8-31.3-73.7 12.6-98.3 26.5-7 9 107.8-12.6 98.3zm91 98.2c-13.3 7.9-45.8 4.7-68.8-27.9-15.5-27.4-13.5-55.2-2.6-63.4 16.3-9.8 41.5 3.4 60.9 25.6 16.9 20 24.6 55.3 10.5 65.7zm-26.4-119.7c-24.5-15.8-28.9-51.6-9.9-80s54.3-38.6 78.8-22.8 28.9 51.6 9.9 80c-19.1 28.4-54.4 38.6-78.8 22.8zM205 496c-29.4 1.2-58.2-23.7-57.8-32.3-.4-12.7 35.8-22.6 59.3-22 23.7-1 55.6 7.5 55.7 18.9.5 11-28.8 35.9-57.2 35.4zm58.9-124.9c.2 29.7-26.2 53.8-58.8 54-32.6.2-59.2-23.8-59.4-53.4v-.6c-.2-29.7 26.2-53.8 58.8-54 32.6-.2 59.2 23.8 59.4 53.4v.6zm82.2 42.7c-25.3 34.6-59.6 35.9-72.3 26.3-13.3-12.4-3.2-50.9 15.1-72 20.9-23.3 43.3-38.5 58.9-26.6 10.5 10.3 16.7 49.1-1.7 72.3zm22.9-73.2c-21.5 9.4-39-105.3-12.6-98.3 43.9 24.7 36.3 79.6 12.6 98.3z" } }, "free": ["brands"] }, "ravelry": { "changes": ["4.7.0", "5.0.0", "5.15.1"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f2d9", "label": "Ravelry", "voted": false, "svg": { "brands": { "last_modified": 1660014466, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M498.252,234.223c-1.208-10.34-1.7-20.826-3.746-31a310.306,310.306,0,0,0-9.622-36.6,184.068,184.068,0,0,0-30.874-57.5,251.154,251.154,0,0,0-18.818-21.689,237.362,237.362,0,0,0-47.113-36.116A240.8,240.8,0,0,0,331.356,26.65c-11.018-3.1-22.272-5.431-33.515-7.615-6.78-1.314-13.749-1.667-20.627-2.482-.316-.036-.6-.358-.9-.553q-16.143.009-32.288.006c-2.41.389-4.808.925-7.236,1.15a179.331,179.331,0,0,0-34.256,7.1,221.5,221.5,0,0,0-39.768,16.355,281.385,281.385,0,0,0-38.08,24.158c-6.167,4.61-12.268,9.36-17.974,14.518C96.539,88.494,86.34,97.72,76.785,107.555a243.878,243.878,0,0,0-33.648,43.95,206.488,206.488,0,0,0-20.494,44.6,198.2,198.2,0,0,0-7.691,34.759A201.13,201.13,0,0,0,13.4,266.385a299.716,299.716,0,0,0,4.425,40.24,226.865,226.865,0,0,0,16.73,53.3,210.543,210.543,0,0,0,24,39.528,213.589,213.589,0,0,0,26.358,28.416A251.313,251.313,0,0,0,126.7,458.455a287.831,287.831,0,0,0,55.9,25.277,269.5,269.5,0,0,0,40.641,9.835c6.071,1.01,12.275,1.253,18.412,1.873a4.149,4.149,0,0,1,1.19.56h32.289c2.507-.389,5-.937,7.527-1.143,16.336-1.332,32.107-5.335,47.489-10.717A219.992,219.992,0,0,0,379.1,460.322c9.749-6.447,19.395-13.077,28.737-20.1,5.785-4.348,10.988-9.5,16.3-14.457,3.964-3.7,7.764-7.578,11.51-11.5a232.162,232.162,0,0,0,31.427-41.639c9.542-16.045,17.355-32.905,22.3-50.926,2.859-10.413,4.947-21.045,7.017-31.652,1.032-5.279,1.251-10.723,1.87-16.087.036-.317.358-.6.552-.9V236.005A9.757,9.757,0,0,1,498.252,234.223Zm-161.117-1.15s-16.572-2.98-28.47-2.98c-27.2,0-33.57,14.9-33.57,37.04V360.8H201.582V170.062H275.1v31.931c8.924-26.822,26.771-36.189,62.04-36.189Z" } }, "free": ["brands"] }, "react": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f41b", "label": "React", "voted": false, "svg": { "brands": { "last_modified": 1660014472, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M418.2 177.2c-5.4-1.8-10.8-3.5-16.2-5.1.9-3.7 1.7-7.4 2.5-11.1 12.3-59.6 4.2-107.5-23.1-123.3-26.3-15.1-69.2.6-112.6 38.4-4.3 3.7-8.5 7.6-12.5 11.5-2.7-2.6-5.5-5.2-8.3-7.7-45.5-40.4-91.1-57.4-118.4-41.5-26.2 15.2-34 60.3-23 116.7 1.1 5.6 2.3 11.1 3.7 16.7-6.4 1.8-12.7 3.8-18.6 5.9C38.3 196.2 0 225.4 0 255.6c0 31.2 40.8 62.5 96.3 81.5 4.5 1.5 9 3 13.6 4.3-1.5 6-2.8 11.9-4 18-10.5 55.5-2.3 99.5 23.9 114.6 27 15.6 72.4-.4 116.6-39.1 3.5-3.1 7-6.3 10.5-9.7 4.4 4.3 9 8.4 13.6 12.4 42.8 36.8 85.1 51.7 111.2 36.6 27-15.6 35.8-62.9 24.4-120.5-.9-4.4-1.9-8.9-3-13.5 3.2-.9 6.3-1.9 9.4-2.9 57.7-19.1 99.5-50 99.5-81.7 0-30.3-39.4-59.7-93.8-78.4zM282.9 92.3c37.2-32.4 71.9-45.1 87.7-36 16.9 9.7 23.4 48.9 12.8 100.4-.7 3.4-1.4 6.7-2.3 10-22.2-5-44.7-8.6-67.3-10.6-13-18.6-27.2-36.4-42.6-53.1 3.9-3.7 7.7-7.2 11.7-10.7zM167.2 307.5c5.1 8.7 10.3 17.4 15.8 25.9-15.6-1.7-31.1-4.2-46.4-7.5 4.4-14.4 9.9-29.3 16.3-44.5 4.6 8.8 9.3 17.5 14.3 26.1zm-30.3-120.3c14.4-3.2 29.7-5.8 45.6-7.8-5.3 8.3-10.5 16.8-15.4 25.4-4.9 8.5-9.7 17.2-14.2 26-6.3-14.9-11.6-29.5-16-43.6zm27.4 68.9c6.6-13.8 13.8-27.3 21.4-40.6s15.8-26.2 24.4-38.9c15-1.1 30.3-1.7 45.9-1.7s31 .6 45.9 1.7c8.5 12.6 16.6 25.5 24.3 38.7s14.9 26.7 21.7 40.4c-6.7 13.8-13.9 27.4-21.6 40.8-7.6 13.3-15.7 26.2-24.2 39-14.9 1.1-30.4 1.6-46.1 1.6s-30.9-.5-45.6-1.4c-8.7-12.7-16.9-25.7-24.6-39s-14.8-26.8-21.5-40.6zm180.6 51.2c5.1-8.8 9.9-17.7 14.6-26.7 6.4 14.5 12 29.2 16.9 44.3-15.5 3.5-31.2 6.2-47 8 5.4-8.4 10.5-17 15.5-25.6zm14.4-76.5c-4.7-8.8-9.5-17.6-14.5-26.2-4.9-8.5-10-16.9-15.3-25.2 16.1 2 31.5 4.7 45.9 8-4.6 14.8-10 29.2-16.1 43.4zM256.2 118.3c10.5 11.4 20.4 23.4 29.6 35.8-19.8-.9-39.7-.9-59.5 0 9.8-12.9 19.9-24.9 29.9-35.8zM140.2 57c16.8-9.8 54.1 4.2 93.4 39 2.5 2.2 5 4.6 7.6 7-15.5 16.7-29.8 34.5-42.9 53.1-22.6 2-45 5.5-67.2 10.4-1.3-5.1-2.4-10.3-3.5-15.5-9.4-48.4-3.2-84.9 12.6-94zm-24.5 263.6c-4.2-1.2-8.3-2.5-12.4-3.9-21.3-6.7-45.5-17.3-63-31.2-10.1-7-16.9-17.8-18.8-29.9 0-18.3 31.6-41.7 77.2-57.6 5.7-2 11.5-3.8 17.3-5.5 6.8 21.7 15 43 24.5 63.6-9.6 20.9-17.9 42.5-24.8 64.5zm116.6 98c-16.5 15.1-35.6 27.1-56.4 35.3-11.1 5.3-23.9 5.8-35.3 1.3-15.9-9.2-22.5-44.5-13.5-92 1.1-5.6 2.3-11.2 3.7-16.7 22.4 4.8 45 8.1 67.9 9.8 13.2 18.7 27.7 36.6 43.2 53.4-3.2 3.1-6.4 6.1-9.6 8.9zm24.5-24.3c-10.2-11-20.4-23.2-30.3-36.3 9.6.4 19.5.6 29.5.6 10.3 0 20.4-.2 30.4-.7-9.2 12.7-19.1 24.8-29.6 36.4zm130.7 30c-.9 12.2-6.9 23.6-16.5 31.3-15.9 9.2-49.8-2.8-86.4-34.2-4.2-3.6-8.4-7.5-12.7-11.5 15.3-16.9 29.4-34.8 42.2-53.6 22.9-1.9 45.7-5.4 68.2-10.5 1 4.1 1.9 8.2 2.7 12.2 4.9 21.6 5.7 44.1 2.5 66.3zm18.2-107.5c-2.8.9-5.6 1.8-8.5 2.6-7-21.8-15.6-43.1-25.5-63.8 9.6-20.4 17.7-41.4 24.5-62.9 5.2 1.5 10.2 3.1 15 4.7 46.6 16 79.3 39.8 79.3 58 0 19.6-34.9 44.9-84.8 61.4zm-149.7-15c25.3 0 45.8-20.5 45.8-45.8s-20.5-45.8-45.8-45.8c-25.3 0-45.8 20.5-45.8 45.8s20.5 45.8 45.8 45.8z" } }, "free": ["brands"] }, "reacteurope": { "changes": ["5.5.0", "5.8.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f75d", "label": "ReactEurope", "voted": false, "svg": { "brands": { "last_modified": 1660014460, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M250.6 211.74l5.8-4.1 5.8 4.1-2.1-6.8 5.7-4.3-7.1-.1-2.3-6.8-2.3 6.8-7.2.1 5.7 4.3zm63.7 0l5.8-4.1 5.8 4.1-2.1-6.8 5.7-4.3-7.2-.1-2.3-6.8-2.3 6.8-7.2.1 5.7 4.3zm-91.3 50.5h-3.4c-4.8 0-3.8 4-3.8 12.1 0 4.7-2.3 6.1-5.8 6.1s-5.8-1.4-5.8-6.1v-36.6c0-4.7 2.3-6.1 5.8-6.1s5.8 1.4 5.8 6.1c0 7.2-.7 10.5 3.8 10.5h3.4c4.7-.1 3.8-3.9 3.8-12.3 0-9.9-6.7-14.1-16.8-14.1h-.2c-10.1 0-16.8 4.2-16.8 14.1V276c0 10.4 6.7 14.1 16.8 14.1h.2c10.1 0 16.8-3.8 16.8-14.1 0-9.86 1.1-13.76-3.8-13.76zm-80.7 17.4h-14.7v-19.3H139c2.5 0 3.8-1.3 3.8-3.8v-2.1c0-2.5-1.3-3.8-3.8-3.8h-11.4v-18.3H142c2.5 0 3.8-1.3 3.8-3.8v-2.1c0-2.5-1.3-3.8-3.8-3.8h-21.7c-2.4-.1-3.7 1.3-3.7 3.8v59.1c0 2.5 1.3 3.8 3.8 3.8h21.9c2.5 0 3.8-1.3 3.8-3.8v-2.1c0-2.5-1.3-3.8-3.8-3.8zm-42-18.5c4.6-2 7.3-6 7.3-12.4v-11.9c0-10.1-6.7-14.1-16.8-14.1H77.4c-2.5 0-3.8 1.3-3.8 3.8v59.1c0 2.5 1.3 3.8 3.8 3.8h3.4c2.5 0 3.8-1.3 3.8-3.8v-22.9h5.6l7.4 23.5a4.1 4.1 0 0 0 4.3 3.2h3.3c2.8 0 4-1.8 3.2-4.4zm-3.8-14c0 4.8-2.5 6.1-6.1 6.1h-5.8v-20.9h5.8c3.6 0 6.1 1.3 6.1 6.1zM176 226a3.82 3.82 0 0 0-4.2-3.4h-6.9a3.68 3.68 0 0 0-4 3.4l-11 59.2c-.5 2.7.9 4.1 3.4 4.1h3a3.74 3.74 0 0 0 4.1-3.5l1.8-11.3h12.2l1.8 11.3a3.74 3.74 0 0 0 4.1 3.5h3.5c2.6 0 3.9-1.4 3.4-4.1zm-12.3 39.3l4.7-29.7 4.7 29.7zm89.3 20.2v-53.2h7.5c2.5 0 3.8-1.3 3.8-3.8v-2.1c0-2.5-1.3-3.8-3.8-3.8h-25.8c-2.5 0-3.8 1.3-3.8 3.8v2.1c0 2.5 1.3 3.8 3.8 3.8h7.3v53.2c0 2.5 1.3 3.8 3.8 3.8h3.4c2.5.04 3.8-1.3 3.8-3.76zm248-.8h-19.4V258h16.1a1.89 1.89 0 0 0 2-2v-.8a1.89 1.89 0 0 0-2-2h-16.1v-25.8h19.1a1.89 1.89 0 0 0 2-2v-.8a1.77 1.77 0 0 0-2-1.9h-22.2a1.62 1.62 0 0 0-2 1.8v63a1.81 1.81 0 0 0 2 1.9H501a1.81 1.81 0 0 0 2-1.9v-.8a1.84 1.84 0 0 0-2-1.96zm-93.1-62.9h-.8c-10.1 0-15.3 4.7-15.3 14.1V276c0 9.3 5.2 14.1 15.3 14.1h.8c10.1 0 15.3-4.8 15.3-14.1v-40.1c0-9.36-5.2-14.06-15.3-14.06zm10.2 52.4c-.1 8-3 11.1-10.5 11.1s-10.5-3.1-10.5-11.1v-36.6c0-7.9 3-11.1 10.5-11.1s10.5 3.2 10.5 11.1zm-46.5-14.5c6.1-1.6 9.2-6.1 9.2-13.3v-9.7c0-9.4-5.2-14.1-15.3-14.1h-13.7a1.81 1.81 0 0 0-2 1.9v63a1.81 1.81 0 0 0 2 1.9h1.2a1.74 1.74 0 0 0 1.9-1.9v-26.9h11.6l10.4 27.2a2.32 2.32 0 0 0 2.3 1.5h1.5c1.4 0 2-1 1.5-2.3zm-6.4-3.9H355v-28.5h10.2c7.5 0 10.5 3.1 10.5 11.1v6.4c0 7.84-3 11.04-10.5 11.04zm85.9-33.1h-13.7a1.62 1.62 0 0 0-2 1.8v63a1.81 1.81 0 0 0 2 1.9h1.2a1.74 1.74 0 0 0 1.9-1.9v-26.1h10.6c10.1 0 15.3-4.8 15.3-14.1v-10.5c0-9.4-5.2-14.1-15.3-14.1zm10.2 22.8c0 7.9-3 11.1-10.5 11.1h-10.2v-29.2h10.2c7.5-.1 10.5 3.1 10.5 11zM259.5 308l-2.3-6.8-2.3 6.8-7.1.1 5.7 4.3-2.1 6.8 5.8-4.1 5.8 4.1-2.1-6.8 5.7-4.3zm227.6-136.1a364.42 364.42 0 0 0-35.6-11.3c19.6-78 11.6-134.7-22.3-153.9C394.7-12.66 343.3 11 291 61.94q5.1 4.95 10.2 10.2c82.5-80 119.6-53.5 120.9-52.8 22.4 12.7 36 55.8 15.5 137.8a587.83 587.83 0 0 0-84.6-13C281.1 43.64 212.4 2 170.8 2 140 2 127 23 123.2 29.74c-18.1 32-13.3 84.2.1 133.8-70.5 20.3-120.7 54.1-120.3 95 .5 59.6 103.2 87.8 122.1 92.8-20.5 81.9-10.1 135.6 22.3 153.9 28 15.8 75.1 6 138.2-55.2q-5.1-4.95-10.2-10.2c-82.5 80-119.7 53.5-120.9 52.8-22.3-12.6-36-55.6-15.5-137.9 12.4 2.9 41.8 9.5 84.6 13 71.9 100.4 140.6 142 182.1 142 30.8 0 43.8-21 47.6-27.7 18-31.9 13.3-84.1-.1-133.8 152.3-43.8 156.2-130.2 33.9-176.3zM135.9 36.84c2.9-5.1 11.9-20.3 34.9-20.3 36.8 0 98.8 39.6 163.3 126.2a714 714 0 0 0-93.9.9 547.76 547.76 0 0 1 42.2-52.4Q277.3 86 272.2 81a598.25 598.25 0 0 0-50.7 64.2 569.69 569.69 0 0 0-84.4 14.6c-.2-1.4-24.3-82.2-1.2-123zm304.8 438.3c-2.9 5.1-11.8 20.3-34.9 20.3-36.7 0-98.7-39.4-163.3-126.2a695.38 695.38 0 0 0 93.9-.9 547.76 547.76 0 0 1-42.2 52.4q5.1 5.25 10.2 10.2a588.47 588.47 0 0 0 50.7-64.2c47.3-4.7 80.3-13.5 84.4-14.6 22.7 84.4 4.5 117 1.2 123zm9.1-138.6c-3.6-11.9-7.7-24.1-12.4-36.4a12.67 12.67 0 0 1-10.7-5.7l-.1.1a19.61 19.61 0 0 1-5.4 3.6c5.7 14.3 10.6 28.4 14.7 42.2a535.3 535.3 0 0 1-72 13c3.5-5.3 17.2-26.2 32.2-54.2a24.6 24.6 0 0 1-6-3.2c-1.1 1.2-3.6 4.2-10.9 4.2-6.2 11.2-17.4 30.9-33.9 55.2a711.91 711.91 0 0 1-112.4 1c-7.9-11.2-21.5-31.1-36.8-57.8a21 21 0 0 1-3-1.5c-1.9 1.6-3.9 3.2-12.6 3.2 6.3 11.2 17.5 30.7 33.8 54.6a548.81 548.81 0 0 1-72.2-11.7q5.85-21 14.1-42.9c-3.2 0-5.4.2-8.4-1a17.58 17.58 0 0 1-6.9 1c-4.9 13.4-9.1 26.5-12.7 39.4C-31.7 297-12.1 216 126.7 175.64c3.6 11.9 7.7 24.1 12.4 36.4 10.4 0 12.9 3.4 14.4 5.3a12 12 0 0 1 2.3-2.2c-5.8-14.7-10.9-29.2-15.2-43.3 7-1.8 32.4-8.4 72-13-15.9 24.3-26.7 43.9-32.8 55.3a14.22 14.22 0 0 1 6.4 8 23.42 23.42 0 0 1 10.2-8.4c6.5-11.7 17.9-31.9 34.8-56.9a711.72 711.72 0 0 1 112.4-1c31.5 44.6 28.9 48.1 42.5 64.5a21.42 21.42 0 0 1 10.4-7.4c-6.4-11.4-17.6-31-34.3-55.5 40.4 4.1 65 10 72.2 11.7-4 14.4-8.9 29.2-14.6 44.2a20.74 20.74 0 0 1 6.8 4.3l.1.1a12.72 12.72 0 0 1 8.9-5.6c4.9-13.4 9.2-26.6 12.8-39.5a359.71 359.71 0 0 1 34.5 11c106.1 39.9 74 87.9 72.6 90.4-19.8 35.1-80.1 55.2-105.7 62.5zm-114.4-114h-1.2a1.74 1.74 0 0 0-1.9 1.9v49.8c0 7.9-2.6 11.1-10.1 11.1s-10.1-3.1-10.1-11.1v-49.8a1.69 1.69 0 0 0-1.9-1.9H309a1.81 1.81 0 0 0-2 1.9v51.5c0 9.6 5 14.1 15.1 14.1h.4c10.1 0 15.1-4.6 15.1-14.1v-51.5a2 2 0 0 0-2.2-1.9zM321.7 308l-2.3-6.8-2.3 6.8-7.1.1 5.7 4.3-2.1 6.8 5.8-4.1 5.8 4.1-2.1-6.8 5.7-4.3zm-31.1 7.4l-2.3-6.8-2.3 6.8-7.1.1 5.7 4.3-2.1 6.8 5.8-4.1 5.8 4.1-2.1-6.8 5.7-4.3zm5.1-30.8h-19.4v-26.7h16.1a1.89 1.89 0 0 0 2-2v-.8a1.89 1.89 0 0 0-2-2h-16.1v-25.8h19.1a1.89 1.89 0 0 0 2-2v-.8a1.77 1.77 0 0 0-2-1.9h-22.2a1.81 1.81 0 0 0-2 1.9v63a1.81 1.81 0 0 0 2 1.9h22.5a1.77 1.77 0 0 0 2-1.9v-.8a1.83 1.83 0 0 0-2-2.06zm-7.4-99.4L286 192l-7.1.1 5.7 4.3-2.1 6.8 5.8-4.1 5.8 4.1-2.1-6.8 5.7-4.3-7.1-.1z" } }, "free": ["brands"] }, "readme": { "changes": ["5.0.9", "5.0.10"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f4d5", "label": "ReadMe", "voted": false, "svg": { "brands": { "last_modified": 1660014464, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M528.3 46.5H388.5c-48.1 0-89.9 33.3-100.4 80.3-10.6-47-52.3-80.3-100.4-80.3H48c-26.5 0-48 21.5-48 48v245.8c0 26.5 21.5 48 48 48h89.7c102.2 0 132.7 24.4 147.3 75 .7 2.8 5.2 2.8 6 0 14.7-50.6 45.2-75 147.3-75H528c26.5 0 48-21.5 48-48V94.6c0-26.4-21.3-47.9-47.7-48.1zM242 311.9c0 1.9-1.5 3.5-3.5 3.5H78.2c-1.9 0-3.5-1.5-3.5-3.5V289c0-1.9 1.5-3.5 3.5-3.5h160.4c1.9 0 3.5 1.5 3.5 3.5v22.9zm0-60.9c0 1.9-1.5 3.5-3.5 3.5H78.2c-1.9 0-3.5-1.5-3.5-3.5v-22.9c0-1.9 1.5-3.5 3.5-3.5h160.4c1.9 0 3.5 1.5 3.5 3.5V251zm0-60.9c0 1.9-1.5 3.5-3.5 3.5H78.2c-1.9 0-3.5-1.5-3.5-3.5v-22.9c0-1.9 1.5-3.5 3.5-3.5h160.4c1.9 0 3.5 1.5 3.5 3.5v22.9zm259.3 121.7c0 1.9-1.5 3.5-3.5 3.5H337.5c-1.9 0-3.5-1.5-3.5-3.5v-22.9c0-1.9 1.5-3.5 3.5-3.5h160.4c1.9 0 3.5 1.5 3.5 3.5v22.9zm0-60.9c0 1.9-1.5 3.5-3.5 3.5H337.5c-1.9 0-3.5-1.5-3.5-3.5V228c0-1.9 1.5-3.5 3.5-3.5h160.4c1.9 0 3.5 1.5 3.5 3.5v22.9zm0-60.9c0 1.9-1.5 3.5-3.5 3.5H337.5c-1.9 0-3.5-1.5-3.5-3.5v-22.8c0-1.9 1.5-3.5 3.5-3.5h160.4c1.9 0 3.5 1.5 3.5 3.5V190z" } }, "free": ["brands"] }, "rebel": { "changes": ["4.1.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f1d0", "label": "Rebel Alliance", "voted": false, "svg": { "brands": { "last_modified": 1660014463, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256.5 504C117.2 504 9 387.8 13.2 249.9 16 170.7 56.4 97.7 129.7 49.5c.3 0 1.9-.6 1.1.8-5.8 5.5-111.3 129.8-14.1 226.4 49.8 49.5 90 2.5 90 2.5 38.5-50.1-.6-125.9-.6-125.9-10-24.9-45.7-40.1-45.7-40.1l28.8-31.8c24.4 10.5 43.2 38.7 43.2 38.7.8-29.6-21.9-61.4-21.9-61.4L255.1 8l44.3 50.1c-20.5 28.8-21.9 62.6-21.9 62.6 13.8-23 43.5-39.3 43.5-39.3l28.5 31.8c-27.4 8.9-45.4 39.9-45.4 39.9-15.8 28.5-27.1 89.4.6 127.3 32.4 44.6 87.7-2.8 87.7-2.8 102.7-91.9-10.5-225-10.5-225-6.1-5.5.8-2.8.8-2.8 50.1 36.5 114.6 84.4 116.2 204.8C500.9 400.2 399 504 256.5 504z" } }, "free": ["brands"] }, "receipt": { "aliases": { "unicodes": { "composite": ["1f9fe"], "secondary": ["10f543"] } }, "changes": [ "5.0.13", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "accounting", "bookkeeping", "check", "evidence", "invoice", "money", "pay", "proof", "receipt", "table" ] }, "styles": ["solid"], "unicode": "f543", "label": "Receipt", "voted": true, "svg": { "solid": { "last_modified": 1684766475, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M14 2.2C22.5-1.7 32.5-.3 39.6 5.8L80 40.4 120.4 5.8c9-7.7 22.3-7.7 31.2 0L192 40.4 232.4 5.8c9-7.7 22.3-7.7 31.2 0L304 40.4 344.4 5.8c7.1-6.1 17.1-7.5 25.6-3.6s14 12.4 14 21.8V488c0 9.4-5.5 17.9-14 21.8s-18.5 2.5-25.6-3.6L304 471.6l-40.4 34.6c-9 7.7-22.3 7.7-31.2 0L192 471.6l-40.4 34.6c-9 7.7-22.3 7.7-31.2 0L80 471.6 39.6 506.2c-7.1 6.1-17.1 7.5-25.6 3.6S0 497.4 0 488V24C0 14.6 5.5 6.1 14 2.2zM96 144c-8.8 0-16 7.2-16 16s7.2 16 16 16H288c8.8 0 16-7.2 16-16s-7.2-16-16-16H96zM80 352c0 8.8 7.2 16 16 16H288c8.8 0 16-7.2 16-16s-7.2-16-16-16H96c-8.8 0-16 7.2-16 16zM96 240c-8.8 0-16 7.2-16 16s7.2 16 16 16H288c8.8 0 16-7.2 16-16s-7.2-16-16-16H96z" } }, "free": ["solid"] }, "record-vinyl": { "aliases": { "unicodes": { "secondary": ["10f8d9"] } }, "changes": ["5.11.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["LP", "album", "analog", "music", "phonograph", "sound"] }, "styles": ["solid"], "unicode": "f8d9", "label": "Record Vinyl", "voted": false, "svg": { "solid": { "last_modified": 1684766677, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm256-96a96 96 0 1 1 0 192 96 96 0 1 1 0-192zm0 224a128 128 0 1 0 0-256 128 128 0 1 0 0 256zm0-96a32 32 0 1 0 0-64 32 32 0 1 0 0 64z" } }, "free": ["solid"] }, "rectangle-ad": { "aliases": { "names": ["ad"], "unicodes": { "secondary": ["10f641"] } }, "changes": [ "5.3.0", "5.10.2", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["advertisement", "media", "newspaper", "promotion", "publicity"] }, "styles": ["solid"], "unicode": "f641", "label": "Rectangle Ad", "voted": false, "svg": { "solid": { "last_modified": 1684766476, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H512c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zM229.5 173.3l72 144c5.9 11.9 1.1 26.3-10.7 32.2s-26.3 1.1-32.2-10.7L253.2 328H162.8l-5.4 10.7c-5.9 11.9-20.3 16.7-32.2 10.7s-16.7-20.3-10.7-32.2l72-144c4.1-8.1 12.4-13.3 21.5-13.3s17.4 5.1 21.5 13.3zM208 237.7L186.8 280h42.3L208 237.7zM392 256a24 24 0 1 0 0 48 24 24 0 1 0 0-48zm24-43.9V184c0-13.3 10.7-24 24-24s24 10.7 24 24v96 48c0 13.3-10.7 24-24 24c-6.6 0-12.6-2.7-17-7c-9.4 4.5-19.9 7-31 7c-39.8 0-72-32.2-72-72s32.2-72 72-72c8.4 0 16.5 1.4 24 4.1z" } }, "free": ["solid"] }, "rectangle-list": { "aliases": { "names": ["list-alt"], "unicodes": { "secondary": ["10f022"] } }, "changes": [ "1.0.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "checklist", "completed", "done", "finished", "ol", "todo", "ul" ] }, "styles": ["solid", "regular"], "unicode": "f022", "label": "Rectangle List", "voted": false, "svg": { "solid": { "last_modified": 1684767206, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M0 96C0 60.7 28.7 32 64 32H512c35.3 0 64 28.7 64 64V416c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V96zM128 288a32 32 0 1 0 0-64 32 32 0 1 0 0 64zm32-128a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zM128 384a32 32 0 1 0 0-64 32 32 0 1 0 0 64zm96-248c-13.3 0-24 10.7-24 24s10.7 24 24 24H448c13.3 0 24-10.7 24-24s-10.7-24-24-24H224zm0 96c-13.3 0-24 10.7-24 24s10.7 24 24 24H448c13.3 0 24-10.7 24-24s-10.7-24-24-24H224zm0 96c-13.3 0-24 10.7-24 24s10.7 24 24 24H448c13.3 0 24-10.7 24-24s-10.7-24-24-24H224z" }, "regular": { "last_modified": 1684767206, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M64 80c-8.8 0-16 7.2-16 16V416c0 8.8 7.2 16 16 16H512c8.8 0 16-7.2 16-16V96c0-8.8-7.2-16-16-16H64zM0 96C0 60.7 28.7 32 64 32H512c35.3 0 64 28.7 64 64V416c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V96zm96 64a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm104 0c0-13.3 10.7-24 24-24H448c13.3 0 24 10.7 24 24s-10.7 24-24 24H224c-13.3 0-24-10.7-24-24zm0 96c0-13.3 10.7-24 24-24H448c13.3 0 24 10.7 24 24s-10.7 24-24 24H224c-13.3 0-24-10.7-24-24zm0 96c0-13.3 10.7-24 24-24H448c13.3 0 24 10.7 24 24s-10.7 24-24 24H224c-13.3 0-24-10.7-24-24zm-72-64a32 32 0 1 1 0-64 32 32 0 1 1 0 64zM96 352a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z" } }, "free": ["regular", "solid"] }, "rectangle-xmark": { "aliases": { "names": ["rectangle-times", "times-rectangle", "window-close"], "unicodes": { "composite": ["f2d4"], "secondary": ["10f410"] } }, "changes": [ "4.7.0", "5.0.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["browser", "cancel", "computer", "development"] }, "styles": ["solid", "regular"], "unicode": "f410", "label": "Rectangle Xmark", "voted": false, "svg": { "solid": { "last_modified": 1684767551, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zM175 175c9.4-9.4 24.6-9.4 33.9 0l47 47 47-47c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-47 47 47 47c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-47-47-47 47c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l47-47-47-47c-9.4-9.4-9.4-24.6 0-33.9z" }, "regular": { "last_modified": 1684767551, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M64 80c-8.8 0-16 7.2-16 16V416c0 8.8 7.2 16 16 16H448c8.8 0 16-7.2 16-16V96c0-8.8-7.2-16-16-16H64zM0 96C0 60.7 28.7 32 64 32H448c35.3 0 64 28.7 64 64V416c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V96zm175 79c9.4-9.4 24.6-9.4 33.9 0l47 47 47-47c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-47 47 47 47c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-47-47-47 47c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l47-47-47-47c-9.4-9.4-9.4-24.6 0-33.9z" } }, "free": ["regular", "solid"] }, "recycle": { "aliases": { "unicodes": { "composite": ["2672", "267a", "267b"], "secondary": ["10f1b8"] } }, "changes": ["4.1.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "Recycling Symbol For Generic Materials", "Universal Recycling Symbol", "Waste", "compost", "garbage", "recycle", "recycling symbol", "reuse", "trash" ] }, "styles": ["solid"], "unicode": "f1b8", "label": "Recycle", "voted": false, "svg": { "solid": { "last_modified": 1684766330, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M174.7 45.1C192.2 17 223 0 256 0s63.8 17 81.3 45.1l38.6 61.7 27-15.6c8.4-4.9 18.9-4.2 26.6 1.7s11.1 15.9 8.6 25.3l-23.4 87.4c-3.4 12.8-16.6 20.4-29.4 17l-87.4-23.4c-9.4-2.5-16.3-10.4-17.6-20s3.4-19.1 11.8-23.9l28.4-16.4L283 79c-5.8-9.3-16-15-27-15s-21.2 5.7-27 15l-17.5 28c-9.2 14.8-28.6 19.5-43.6 10.5c-15.3-9.2-20.2-29.2-10.7-44.4l17.5-28zM429.5 251.9c15-9 34.4-4.3 43.6 10.5l24.4 39.1c9.4 15.1 14.4 32.4 14.6 50.2c.3 53.1-42.7 96.4-95.8 96.4L320 448v32c0 9.7-5.8 18.5-14.8 22.2s-19.3 1.7-26.2-5.2l-64-64c-9.4-9.4-9.4-24.6 0-33.9l64-64c6.9-6.9 17.2-8.9 26.2-5.2s14.8 12.5 14.8 22.2v32l96.2 0c17.6 0 31.9-14.4 31.8-32c0-5.9-1.7-11.7-4.8-16.7l-24.4-39.1c-9.5-15.2-4.7-35.2 10.7-44.4zm-364.6-31L36 204.2c-8.4-4.9-13.1-14.3-11.8-23.9s8.2-17.5 17.6-20l87.4-23.4c12.8-3.4 26 4.2 29.4 17L182 241.2c2.5 9.4-.9 19.3-8.6 25.3s-18.2 6.6-26.6 1.7l-26.5-15.3L68.8 335.3c-3.1 5-4.8 10.8-4.8 16.7c-.1 17.6 14.2 32 31.8 32l32.2 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-32.2 0C42.7 448-.3 404.8 0 351.6c.1-17.8 5.1-35.1 14.6-50.2l50.3-80.5z" } }, "free": ["solid"] }, "red-river": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3e3", "label": "red river", "voted": false, "svg": { "brands": { "last_modified": 1660014479, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M353.2 32H94.8C42.4 32 0 74.4 0 126.8v258.4C0 437.6 42.4 480 94.8 480h258.4c52.4 0 94.8-42.4 94.8-94.8V126.8c0-52.4-42.4-94.8-94.8-94.8zM144.9 200.9v56.3c0 27-21.9 48.9-48.9 48.9V151.9c0-13.2 10.7-23.9 23.9-23.9h154.2c0 27-21.9 48.9-48.9 48.9h-56.3c-12.3-.6-24.6 11.6-24 24zm176.3 72h-56.3c-12.3-.6-24.6 11.6-24 24v56.3c0 27-21.9 48.9-48.9 48.9V247.9c0-13.2 10.7-23.9 23.9-23.9h154.2c0 27-21.9 48.9-48.9 48.9z" } }, "free": ["brands"] }, "reddit": { "changes": ["4.1.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f1a1", "label": "reddit Logo", "voted": false, "svg": { "brands": { "last_modified": 1660014475, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M201.5 305.5c-13.8 0-24.9-11.1-24.9-24.6 0-13.8 11.1-24.9 24.9-24.9 13.6 0 24.6 11.1 24.6 24.9 0 13.6-11.1 24.6-24.6 24.6zM504 256c0 137-111 248-248 248S8 393 8 256 119 8 256 8s248 111 248 248zm-132.3-41.2c-9.4 0-17.7 3.9-23.8 10-22.4-15.5-52.6-25.5-86.1-26.6l17.4-78.3 55.4 12.5c0 13.6 11.1 24.6 24.6 24.6 13.8 0 24.9-11.3 24.9-24.9s-11.1-24.9-24.9-24.9c-9.7 0-18 5.8-22.1 13.8l-61.2-13.6c-3-.8-6.1 1.4-6.9 4.4l-19.1 86.4c-33.2 1.4-63.1 11.3-85.5 26.8-6.1-6.4-14.7-10.2-24.1-10.2-34.9 0-46.3 46.9-14.4 62.8-1.1 5-1.7 10.2-1.7 15.5 0 52.6 59.2 95.2 132 95.2 73.1 0 132.3-42.6 132.3-95.2 0-5.3-.6-10.8-1.9-15.8 31.3-16 19.8-62.5-14.9-62.5zM302.8 331c-18.2 18.2-76.1 17.9-93.6 0-2.2-2.2-6.1-2.2-8.3 0-2.5 2.5-2.5 6.4 0 8.6 22.8 22.8 87.3 22.8 110.2 0 2.5-2.2 2.5-6.1 0-8.6-2.2-2.2-6.1-2.2-8.3 0zm7.7-75c-13.6 0-24.6 11.1-24.6 24.9 0 13.6 11.1 24.6 24.6 24.6 13.8 0 24.9-11.1 24.9-24.6 0-13.8-11-24.9-24.9-24.9z" } }, "free": ["brands"] }, "reddit-alien": { "changes": ["4.5.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f281", "label": "reddit Alien", "voted": false, "svg": { "brands": { "last_modified": 1660014471, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M440.3 203.5c-15 0-28.2 6.2-37.9 15.9-35.7-24.7-83.8-40.6-137.1-42.3L293 52.3l88.2 19.8c0 21.6 17.6 39.2 39.2 39.2 22 0 39.7-18.1 39.7-39.7s-17.6-39.7-39.7-39.7c-15.4 0-28.7 9.3-35.3 22l-97.4-21.6c-4.9-1.3-9.7 2.2-11 7.1L246.3 177c-52.9 2.2-100.5 18.1-136.3 42.8-9.7-10.1-23.4-16.3-38.4-16.3-55.6 0-73.8 74.6-22.9 100.1-1.8 7.9-2.6 16.3-2.6 24.7 0 83.8 94.4 151.7 210.3 151.7 116.4 0 210.8-67.9 210.8-151.7 0-8.4-.9-17.2-3.1-25.1 49.9-25.6 31.5-99.7-23.8-99.7zM129.4 308.9c0-22 17.6-39.7 39.7-39.7 21.6 0 39.2 17.6 39.2 39.7 0 21.6-17.6 39.2-39.2 39.2-22 .1-39.7-17.6-39.7-39.2zm214.3 93.5c-36.4 36.4-139.1 36.4-175.5 0-4-3.5-4-9.7 0-13.7 3.5-3.5 9.7-3.5 13.2 0 27.8 28.5 120 29 149 0 3.5-3.5 9.7-3.5 13.2 0 4.1 4 4.1 10.2.1 13.7zm-.8-54.2c-21.6 0-39.2-17.6-39.2-39.2 0-22 17.6-39.7 39.2-39.7 22 0 39.7 17.6 39.7 39.7-.1 21.5-17.7 39.2-39.7 39.2z" } }, "free": ["brands"] }, "redhat": { "changes": ["5.6.0", "5.8.2"], "ligatures": [], "search": { "terms": ["linux", "operating system", "os"] }, "styles": ["brands"], "unicode": "f7bc", "label": "Redhat", "voted": true, "svg": { "brands": { "last_modified": 1660014482, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M341.52 285.56c33.65 0 82.34-6.94 82.34-47 .22-6.74.86-1.82-20.88-96.24-4.62-19.15-8.68-27.84-42.31-44.65-26.09-13.34-82.92-35.37-99.73-35.37-15.66 0-20.2 20.17-38.87 20.17-18 0-31.31-15.06-48.12-15.06-16.14 0-26.66 11-34.78 33.62-27.5 77.55-26.28 74.27-26.12 78.27 0 24.8 97.64 106.11 228.47 106.11M429 254.84c4.65 22 4.65 24.35 4.65 27.25 0 37.66-42.33 58.56-98 58.56-125.74.08-235.91-73.65-235.91-122.33a49.55 49.55 0 0 1 4.06-19.72C58.56 200.86 0 208.93 0 260.63c0 84.67 200.63 189 359.49 189 121.79 0 152.51-55.08 152.51-98.58 0-34.21-29.59-73.05-82.93-96.24" } }, "free": ["brands"] }, "registered": { "aliases": { "unicodes": { "composite": ["ae"], "secondary": ["10f25d"] } }, "changes": [ "4.4.0", "5.0.0", "5.10.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["copyright", "mark", "r", "registered", "trademark"] }, "styles": ["solid", "regular"], "unicode": "f25d", "label": "Registered", "voted": false, "svg": { "solid": { "last_modified": 1684767246, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM160 152c0-13.3 10.7-24 24-24h88c44.2 0 80 35.8 80 80c0 28-14.4 52.7-36.3 67l34.1 75.1c5.5 12.1 .1 26.3-11.9 31.8s-26.3 .1-31.8-11.9L268.9 288H208v72c0 13.3-10.7 24-24 24s-24-10.7-24-24V264 152zm48 88h64c17.7 0 32-14.3 32-32s-14.3-32-32-32H208v64z" }, "regular": { "last_modified": 1684767246, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 48a208 208 0 1 1 0 416 208 208 0 1 1 0-416zm0 464A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM160 152V264v96c0 13.3 10.7 24 24 24s24-10.7 24-24V288h60.9l37.2 81.9c5.5 12.1 19.7 17.4 31.8 11.9s17.4-19.7 11.9-31.8L315.7 275c21.8-14.3 36.3-39 36.3-67c0-44.2-35.8-80-80-80H184c-13.3 0-24 10.7-24 24zm48 88V176h64c17.7 0 32 14.3 32 32s-14.3 32-32 32H208z" } }, "free": ["regular", "solid"] }, "renren": { "changes": ["3.2.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f18b", "label": "Renren", "voted": false, "svg": { "brands": { "last_modified": 1660014467, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M214 169.1c0 110.4-61 205.4-147.6 247.4C30 373.2 8 317.7 8 256.6 8 133.9 97.1 32.2 214 12.5v156.6zM255 504c-42.9 0-83.3-11-118.5-30.4C193.7 437.5 239.9 382.9 255 319c15.5 63.9 61.7 118.5 118.8 154.7C338.7 493 298.3 504 255 504zm190.6-87.5C359 374.5 298 279.6 298 169.1V12.5c116.9 19.7 206 121.4 206 244.1 0 61.1-22 116.6-58.4 159.9z" } }, "free": ["brands"] }, "repeat": { "aliases": { "unicodes": { "composite": ["1f501"], "secondary": ["10f363"] } }, "changes": ["5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "arrow", "clockwise", "flip", "reload", "repeat", "repeat button", "rewind", "switch" ] }, "styles": ["solid"], "unicode": "f363", "label": "Repeat", "voted": false, "svg": { "solid": { "last_modified": 1684766331, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 224c0 17.7 14.3 32 32 32s32-14.3 32-32c0-53 43-96 96-96H320v32c0 12.9 7.8 24.6 19.8 29.6s25.7 2.2 34.9-6.9l64-64c12.5-12.5 12.5-32.8 0-45.3l-64-64c-9.2-9.2-22.9-11.9-34.9-6.9S320 19.1 320 32V64H160C71.6 64 0 135.6 0 224zm512 64c0-17.7-14.3-32-32-32s-32 14.3-32 32c0 53-43 96-96 96H192V352c0-12.9-7.8-24.6-19.8-29.6s-25.7-2.2-34.9 6.9l-64 64c-12.5 12.5-12.5 32.8 0 45.3l64 64c9.2 9.2 22.9 11.9 34.9 6.9s19.8-16.6 19.8-29.6V448H352c88.4 0 160-71.6 160-160z" } }, "free": ["solid"] }, "reply": { "aliases": { "names": ["mail-reply"], "unicodes": { "composite": ["f112"], "secondary": ["10f3e5"] } }, "changes": [ "3.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.2.1", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["mail", "message", "respond"] }, "styles": ["solid"], "unicode": "f3e5", "label": "Reply", "voted": false, "svg": { "solid": { "last_modified": 1684766332, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M205 34.8c11.5 5.1 19 16.6 19 29.2v64H336c97.2 0 176 78.8 176 176c0 113.3-81.5 163.9-100.2 174.1c-2.5 1.4-5.3 1.9-8.1 1.9c-10.9 0-19.7-8.9-19.7-19.7c0-7.5 4.3-14.4 9.8-19.5c9.4-8.8 22.2-26.4 22.2-56.7c0-53-43-96-96-96H224v64c0 12.6-7.4 24.1-19 29.2s-25 3-34.4-5.4l-160-144C3.9 225.7 0 217.1 0 208s3.9-17.7 10.6-23.8l160-144c9.4-8.5 22.9-10.6 34.4-5.4z" } }, "free": ["solid"] }, "reply-all": { "aliases": { "names": ["mail-reply-all"], "unicodes": { "secondary": ["10f122"] } }, "changes": [ "3.1.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.2.1", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["mail", "message", "respond"] }, "styles": ["solid"], "unicode": "f122", "label": "Reply All", "voted": false, "svg": { "solid": { "last_modified": 1684766331, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M209.4 39.5c-9.1-9.6-24.3-10-33.9-.9L33.8 173.2c-19.9 18.9-19.9 50.7 0 69.6L175.5 377.4c9.6 9.1 24.8 8.7 33.9-.9s8.7-24.8-.9-33.9L66.8 208 208.5 73.4c9.6-9.1 10-24.3 .9-33.9zM352 64c0-12.6-7.4-24.1-19-29.2s-25-3-34.4 5.4l-160 144c-6.7 6.1-10.6 14.7-10.6 23.8s3.9 17.7 10.6 23.8l160 144c9.4 8.5 22.9 10.6 34.4 5.4s19-16.6 19-29.2V288h32c53 0 96 43 96 96c0 30.4-12.8 47.9-22.2 56.7c-5.5 5.1-9.8 12-9.8 19.5c0 10.9 8.8 19.7 19.7 19.7c2.8 0 5.6-.6 8.1-1.9C494.5 467.9 576 417.3 576 304c0-97.2-78.8-176-176-176H352V64z" } }, "free": ["solid"] }, "replyd": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3e6", "label": "replyd", "voted": false, "svg": { "brands": { "last_modified": 1660014461, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M320 480H128C57.6 480 0 422.4 0 352V160C0 89.6 57.6 32 128 32h192c70.4 0 128 57.6 128 128v192c0 70.4-57.6 128-128 128zM193.4 273.2c-6.1-2-11.6-3.1-16.4-3.1-7.2 0-13.5 1.9-18.9 5.6-5.4 3.7-9.6 9-12.8 15.8h-1.1l-4.2-18.3h-28v138.9h36.1v-89.7c1.5-5.4 4.4-9.8 8.7-13.2 4.3-3.4 9.8-5.1 16.2-5.1 4.6 0 9.8 1 15.6 3.1l4.8-34zm115.2 103.4c-3.2 2.4-7.7 4.8-13.7 7.1-6 2.3-12.8 3.5-20.4 3.5-12.2 0-21.1-3-26.5-8.9-5.5-5.9-8.5-14.7-9-26.4h83.3c.9-4.8 1.6-9.4 2.1-13.9.5-4.4.7-8.6.7-12.5 0-10.7-1.6-19.7-4.7-26.9-3.2-7.2-7.3-13-12.5-17.2-5.2-4.3-11.1-7.3-17.8-9.2-6.7-1.8-13.5-2.8-20.6-2.8-21.1 0-37.5 6.1-49.2 18.3s-17.5 30.5-17.5 55c0 22.8 5.2 40.7 15.6 53.7 10.4 13.1 26.8 19.6 49.2 19.6 10.7 0 20.9-1.5 30.4-4.6 9.5-3.1 17.1-6.8 22.6-11.2l-12-23.6zm-21.8-70.3c3.8 5.4 5.3 13.1 4.6 23.1h-51.7c.9-9.4 3.7-17 8.2-22.6 4.5-5.6 11.5-8.5 21-8.5 8.2-.1 14.1 2.6 17.9 8zm79.9 2.5c4.1 3.9 9.4 5.8 16.1 5.8 7 0 12.6-1.9 16.7-5.8s6.1-9.1 6.1-15.6-2-11.6-6.1-15.4c-4.1-3.8-9.6-5.7-16.7-5.7-6.7 0-12 1.9-16.1 5.7-4.1 3.8-6.1 8.9-6.1 15.4s2 11.7 6.1 15.6zm0 100.5c4.1 3.9 9.4 5.8 16.1 5.8 7 0 12.6-1.9 16.7-5.8s6.1-9.1 6.1-15.6-2-11.6-6.1-15.4c-4.1-3.8-9.6-5.7-16.7-5.7-6.7 0-12 1.9-16.1 5.7-4.1 3.8-6.1 8.9-6.1 15.4 0 6.6 2 11.7 6.1 15.6z" } }, "free": ["brands"] }, "republican": { "aliases": { "unicodes": { "secondary": ["10f75e"] } }, "changes": ["5.5.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "american", "conservative", "election", "elephant", "politics", "republican party", "right", "right-wing", "usa" ] }, "styles": ["solid"], "unicode": "f75e", "label": "Republican", "voted": false, "svg": { "solid": { "last_modified": 1684767602, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M0 192C0 103.6 71.6 32 160 32H384c88.4 0 160 71.6 160 160v64H0V192zm415.9-64c-2.4 0-4.7 1.3-5.7 3.4l-12.6 24.6-28.2 4c-2.4 .3-4.4 2-5.2 4.2s-.1 4.7 1.6 6.3l20.4 19.2-4.8 27.1c-.4 2.3 .6 4.7 2.5 6s4.6 1.6 6.7 .5l25.2-12.8 25.2 12.8c2.2 1.1 4.8 .9 6.7-.5s3-3.7 2.5-6l-4.8-27.1L466 170.5c1.7-1.6 2.4-4.1 1.6-6.3s-2.8-3.9-5.2-4.2l-28.2-4-12.6-24.6c-1.1-2.1-3.3-3.4-5.7-3.4zm-138.3 3.4c-1.1-2.1-3.3-3.4-5.7-3.4s-4.7 1.3-5.7 3.4l-12.6 24.6-28.2 4c-2.4 .3-4.4 2-5.2 4.2s-.1 4.7 1.6 6.3l20.4 19.2-4.8 27.1c-.4 2.3 .6 4.7 2.5 6s4.6 1.6 6.7 .5l25.2-12.8 25.2 12.8c2.2 1.1 4.8 .9 6.7-.5s3-3.7 2.5-6l-4.8-27.1L322 170.5c1.7-1.6 2.4-4.1 1.6-6.3s-2.8-3.9-5.2-4.2l-28.2-4-12.6-24.6zM127.9 128c-2.4 0-4.7 1.3-5.7 3.4l-12.6 24.6-28.2 4c-2.4 .3-4.4 2-5.2 4.2s-.1 4.7 1.6 6.3l20.4 19.2-4.8 27.1c-.4 2.3 .6 4.7 2.5 6s4.6 1.6 6.7 .5l25.2-12.8 25.2 12.8c2.2 1.1 4.8 .9 6.7-.5s3-3.7 2.5-6l-4.8-27.1L178 170.5c1.7-1.6 2.4-4.1 1.6-6.3s-2.8-3.9-5.2-4.2l-28.2-4-12.6-24.6c-1.1-2.1-3.3-3.4-5.7-3.4zm.1 160H320h96 32 64 32v32 80c0 8.8 7.2 16 16 16s16-7.2 16-16V352c0-17.7 14.3-32 32-32s32 14.3 32 32v48c0 44.2-35.8 80-80 80s-80-35.8-80-80V352H448v32 64c0 17.7-14.3 32-32 32H352c-17.7 0-32-14.3-32-32V384H128v64c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32V384 288H128z" } }, "free": ["solid"] }, "researchgate": { "changes": ["5.0.11"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f4f8", "label": "Researchgate", "voted": true, "svg": { "brands": { "last_modified": 1660014473, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M0 32v448h448V32H0zm262.2 334.4c-6.6 3-33.2 6-50-14.2-9.2-10.6-25.3-33.3-42.2-63.6-8.9 0-14.7 0-21.4-.6v46.4c0 23.5 6 21.2 25.8 23.9v8.1c-6.9-.3-23.1-.8-35.6-.8-13.1 0-26.1.6-33.6.8v-8.1c15.5-2.9 22-1.3 22-23.9V225c0-22.6-6.4-21-22-23.9V193c25.8 1 53.1-.6 70.9-.6 31.7 0 55.9 14.4 55.9 45.6 0 21.1-16.7 42.2-39.2 47.5 13.6 24.2 30 45.6 42.2 58.9 7.2 7.8 17.2 14.7 27.2 14.7v7.3zm22.9-135c-23.3 0-32.2-15.7-32.2-32.2V167c0-12.2 8.8-30.4 34-30.4s30.4 17.9 30.4 17.9l-10.7 7.2s-5.5-12.5-19.7-12.5c-7.9 0-19.7 7.3-19.7 19.7v26.8c0 13.4 6.6 23.3 17.9 23.3 14.1 0 21.5-10.9 21.5-26.8h-17.9v-10.7h30.4c0 20.5 4.7 49.9-34 49.9zm-116.5 44.7c-9.4 0-13.6-.3-20-.8v-69.7c6.4-.6 15-.6 22.5-.6 23.3 0 37.2 12.2 37.2 34.5 0 21.9-15 36.6-39.7 36.6z" } }, "free": ["brands"] }, "resolving": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3e7", "label": "Resolving", "voted": false, "svg": { "brands": { "last_modified": 1660014467, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M281.2 278.2c46-13.3 49.6-23.5 44-43.4L314 195.5c-6.1-20.9-18.4-28.1-71.1-12.8L54.7 236.8l28.6 98.6 197.9-57.2zM248.5 8C131.4 8 33.2 88.7 7.2 197.5l221.9-63.9c34.8-10.2 54.2-11.7 79.3-8.2 36.3 6.1 52.7 25 61.4 55.2l10.7 37.8c8.2 28.1 1 50.6-23.5 73.6-19.4 17.4-31.2 24.5-61.4 33.2L203 351.8l220.4 27.1 9.7 34.2-48.1 13.3-286.8-37.3 23 80.2c36.8 22 80.3 34.7 126.3 34.7 137 0 248.5-111.4 248.5-248.3C497 119.4 385.5 8 248.5 8zM38.3 388.6L0 256.8c0 48.5 14.3 93.4 38.3 131.8z" } }, "free": ["brands"] }, "restroom": { "aliases": { "unicodes": { "secondary": ["10f7bd"] } }, "changes": ["5.6.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["bathroom", "toilet", "water closet", "wc"] }, "styles": ["solid"], "unicode": "f7bd", "label": "Restroom", "voted": true, "svg": { "solid": { "last_modified": 1684767532, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M80 48a48 48 0 1 1 96 0A48 48 0 1 1 80 48zm40 304V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V325.2c-8.1 9.2-21.1 13.2-33.5 9.4c-16.9-5.3-26.3-23.2-21-40.1l30.9-99.1C44.9 155.3 82 128 124 128h8c42 0 79.1 27.3 91.6 67.4l30.9 99.1c5.3 16.9-4.1 34.8-21 40.1c-12.4 3.9-25.4-.2-33.5-9.4V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V352H120zM320 0c13.3 0 24 10.7 24 24V488c0 13.3-10.7 24-24 24s-24-10.7-24-24V24c0-13.3 10.7-24 24-24zM464 48a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zM440 480V384H422.2c-10.9 0-18.6-10.7-15.2-21.1l9-26.9c-3.2 0-6.4-.5-9.5-1.5c-16.9-5.3-26.3-23.2-21-40.1l29.7-95.2C428.4 156.9 467.6 128 512 128s83.6 28.9 96.8 71.2l29.7 95.2c5.3 16.9-4.1 34.8-21 40.1c-3.2 1-6.4 1.5-9.5 1.5l9 26.9c3.5 10.4-4.3 21.1-15.2 21.1H584v96c0 17.7-14.3 32-32 32s-32-14.3-32-32V384H504v96c0 17.7-14.3 32-32 32s-32-14.3-32-32z" } }, "free": ["solid"] }, "retweet": { "aliases": { "unicodes": { "secondary": ["10f079"] } }, "changes": ["1.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["refresh", "reload", "share", "swap"] }, "styles": ["solid"], "unicode": "f079", "label": "Retweet", "voted": false, "svg": { "solid": { "last_modified": 1684766329, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M272 416c17.7 0 32-14.3 32-32s-14.3-32-32-32H160c-17.7 0-32-14.3-32-32V192h32c12.9 0 24.6-7.8 29.6-19.8s2.2-25.7-6.9-34.9l-64-64c-12.5-12.5-32.8-12.5-45.3 0l-64 64c-9.2 9.2-11.9 22.9-6.9 34.9s16.6 19.8 29.6 19.8l32 0 0 128c0 53 43 96 96 96H272zM304 96c-17.7 0-32 14.3-32 32s14.3 32 32 32l112 0c17.7 0 32 14.3 32 32l0 128H416c-12.9 0-24.6 7.8-29.6 19.8s-2.2 25.7 6.9 34.9l64 64c12.5 12.5 32.8 12.5 45.3 0l64-64c9.2-9.2 11.9-22.9 6.9-34.9s-16.6-19.8-29.6-19.8l-32 0V192c0-53-43-96-96-96L304 96z" } }, "free": ["solid"] }, "rev": { "changes": ["5.1.0", "5.1.1", "5.8.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f5b2", "label": "Rev.io", "voted": false, "svg": { "brands": { "last_modified": 1660014478, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M289.67 274.89a65.57 65.57 0 1 1-65.56-65.56 65.64 65.64 0 0 1 65.56 65.56zm139.55-5.05h-.13a204.69 204.69 0 0 0-74.32-153l-45.38 26.2a157.07 157.07 0 0 1 71.81 131.84C381.2 361.5 310.73 432 224.11 432S67 361.5 67 274.88c0-81.88 63-149.27 143-156.43v39.12l108.77-62.79L210 32v38.32c-106.7 7.25-191 96-191 204.57 0 111.59 89.12 202.29 200.06 205v.11h210.16V269.84z" } }, "free": ["brands"] }, "ribbon": { "aliases": { "unicodes": { "composite": ["1f397"], "secondary": ["10f4d6"] } }, "changes": ["5.0.9", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "badge", "cause", "celebration", "lapel", "pin", "reminder", "reminder ribbon", "ribbon" ] }, "styles": ["solid"], "unicode": "f4d6", "label": "Ribbon", "voted": false, "svg": { "solid": { "last_modified": 1684767602, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M333.2 322.8l0 0-133.9-146 0 0L146 118.6c7.8-5.1 37-22.6 78-22.6s70.2 17.4 78 22.6L245.7 180l85.6 93.4 27.4-29.8c16.3-17.7 25.3-40.9 25.3-65V149.1c0-19-5.6-37.5-16.1-53.3L327.8 35.6C312.9 13.4 287.9 0 261.2 0h-76c-25.8 0-50.1 12.5-65.1 33.5L81.9 87C70.3 103.2 64 122.8 64 142.8V164c0 23.2 8.4 45.6 23.6 63.1l56 64.2 0 0 83.3 95.6 0 0 91.8 105.3c10 11.5 26.8 14.3 40 6.8l54.5-31.1c17.8-10.2 21.6-34.3 7.7-49.4l-87.7-95.7zM205.2 410.6l-83.3-95.6L27.1 418.5c-13.9 15.1-10.1 39.2 7.7 49.4l55.1 31.5c13 7.4 29.3 4.9 39.4-6.1l75.9-82.6z" } }, "free": ["solid"] }, "right-from-bracket": { "aliases": { "names": ["sign-out-alt"], "unicodes": { "secondary": ["10f2f5"] } }, "changes": ["5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["arrow", "exit", "leave", "log out", "logout", "sign-out"] }, "styles": ["solid"], "unicode": "f2f5", "label": "Right From Bracket", "voted": false, "svg": { "solid": { "last_modified": 1684766332, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M377.9 105.9L500.7 228.7c7.2 7.2 11.3 17.1 11.3 27.3s-4.1 20.1-11.3 27.3L377.9 406.1c-6.4 6.4-15 9.9-24 9.9c-18.7 0-33.9-15.2-33.9-33.9l0-62.1-128 0c-17.7 0-32-14.3-32-32l0-64c0-17.7 14.3-32 32-32l128 0 0-62.1c0-18.7 15.2-33.9 33.9-33.9c9 0 17.6 3.6 24 9.9zM160 96L96 96c-17.7 0-32 14.3-32 32l0 256c0 17.7 14.3 32 32 32l64 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-64 0c-53 0-96-43-96-96L0 128C0 75 43 32 96 32l64 0c17.7 0 32 14.3 32 32s-14.3 32-32 32z" } }, "free": ["solid"] }, "right-left": { "aliases": { "names": ["exchange-alt"], "unicodes": { "secondary": ["10f362"] } }, "changes": ["5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "arrow", "arrows", "exchange", "reciprocate", "return", "swap", "transfer" ] }, "styles": ["solid"], "unicode": "f362", "label": "Right Left", "voted": false, "svg": { "solid": { "last_modified": 1684766328, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M32 96l320 0V32c0-12.9 7.8-24.6 19.8-29.6s25.7-2.2 34.9 6.9l96 96c6 6 9.4 14.1 9.4 22.6s-3.4 16.6-9.4 22.6l-96 96c-9.2 9.2-22.9 11.9-34.9 6.9s-19.8-16.6-19.8-29.6V160L32 160c-17.7 0-32-14.3-32-32s14.3-32 32-32zM480 352c17.7 0 32 14.3 32 32s-14.3 32-32 32H160v64c0 12.9-7.8 24.6-19.8 29.6s-25.7 2.2-34.9-6.9l-96-96c-6-6-9.4-14.1-9.4-22.6s3.4-16.6 9.4-22.6l96-96c9.2-9.2 22.9-11.9 34.9-6.9s19.8 16.6 19.8 29.6l0 64H480z" } }, "free": ["solid"] }, "right-long": { "aliases": { "names": ["long-arrow-alt-right"], "unicodes": { "secondary": ["10f30b"] } }, "changes": ["5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["forward", "long-arrow-right", "next"] }, "styles": ["solid"], "unicode": "f30b", "label": "Right Long", "voted": false, "svg": { "solid": { "last_modified": 1684766329, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M334.5 414c8.8 3.8 19 2 26-4.6l144-136c4.8-4.5 7.5-10.8 7.5-17.4s-2.7-12.9-7.5-17.4l-144-136c-7-6.6-17.2-8.4-26-4.6s-14.5 12.5-14.5 22l0 72L32 192c-17.7 0-32 14.3-32 32l0 64c0 17.7 14.3 32 32 32l288 0 0 72c0 9.6 5.7 18.2 14.5 22z" } }, "free": ["solid"] }, "right-to-bracket": { "aliases": { "names": ["sign-in-alt"], "unicodes": { "secondary": ["10f2f6"] } }, "changes": ["5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "arrow", "enter", "join", "log in", "login", "sign in", "sign up", "sign-in", "signin", "signup" ] }, "styles": ["solid"], "unicode": "f2f6", "label": "Right To Bracket", "voted": false, "svg": { "solid": { "last_modified": 1684766331, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M217.9 105.9L340.7 228.7c7.2 7.2 11.3 17.1 11.3 27.3s-4.1 20.1-11.3 27.3L217.9 406.1c-6.4 6.4-15 9.9-24 9.9c-18.7 0-33.9-15.2-33.9-33.9l0-62.1L32 320c-17.7 0-32-14.3-32-32l0-64c0-17.7 14.3-32 32-32l128 0 0-62.1c0-18.7 15.2-33.9 33.9-33.9c9 0 17.6 3.6 24 9.9zM352 416l64 0c17.7 0 32-14.3 32-32l0-256c0-17.7-14.3-32-32-32l-64 0c-17.7 0-32-14.3-32-32s14.3-32 32-32l64 0c53 0 96 43 96 96l0 256c0 53-43 96-96 96l-64 0c-17.7 0-32-14.3-32-32s14.3-32 32-32z" } }, "free": ["solid"] }, "ring": { "aliases": { "unicodes": { "secondary": ["10f70b"] } }, "changes": ["5.4.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "Dungeons & Dragons", "Gollum", "band", "binding", "d&d", "dnd", "engagement", "fantasy", "gold", "jewelry", "marriage", "precious" ] }, "styles": ["solid"], "unicode": "f70b", "label": "Ring", "voted": false, "svg": { "solid": { "last_modified": 1684767603, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M64 208c0 7.8 4.4 18.7 17.1 30.3C126.5 214.1 188.9 200 256 200s129.5 14.1 174.9 38.3C443.6 226.7 448 215.8 448 208c0-12.3-10.8-32-47.9-50.6C364.9 139.8 314 128 256 128s-108.9 11.8-144.1 29.4C74.8 176 64 195.7 64 208zm192 40c-47 0-89.3 7.6-122.9 19.7C166.3 280.2 208.8 288 256 288s89.7-7.8 122.9-20.3C345.3 255.6 303 248 256 248zM0 208c0-49.6 39.4-85.8 83.3-107.8C129.1 77.3 190.3 64 256 64s126.9 13.3 172.7 36.2c43.9 22 83.3 58.2 83.3 107.8v96c0 49.6-39.4 85.8-83.3 107.8C382.9 434.7 321.7 448 256 448s-126.9-13.3-172.7-36.2C39.4 389.8 0 353.6 0 304V208z" } }, "free": ["solid"] }, "road": { "aliases": { "unicodes": { "composite": ["1f6e3"], "secondary": ["10f018"] } }, "changes": [ "1.0.0", "5.0.0", "5.2.0", "6.0.0-beta1", "6.0.0-beta3", "6.1.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "highway", "map", "motorway", "pavement", "road", "route", "street", "travel" ] }, "styles": ["solid"], "unicode": "f018", "label": "Road", "voted": false, "svg": { "solid": { "last_modified": 1684767489, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M256 32H181.2c-27.1 0-51.3 17.1-60.3 42.6L3.1 407.2C1.1 413 0 419.2 0 425.4C0 455.5 24.5 480 54.6 480H256V416c0-17.7 14.3-32 32-32s32 14.3 32 32v64H521.4c30.2 0 54.6-24.5 54.6-54.6c0-6.2-1.1-12.4-3.1-18.2L455.1 74.6C446 49.1 421.9 32 394.8 32H320V96c0 17.7-14.3 32-32 32s-32-14.3-32-32V32zm64 192v64c0 17.7-14.3 32-32 32s-32-14.3-32-32V224c0-17.7 14.3-32 32-32s32 14.3 32 32z" } }, "free": ["solid"] }, "road-barrier": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["block", "border", "no entry", "roadblock"] }, "styles": ["solid"], "unicode": "e562", "label": "Road Barrier", "voted": false, "svg": { "solid": { "last_modified": 1684767443, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M32 32C14.3 32 0 46.3 0 64V448c0 17.7 14.3 32 32 32s32-14.3 32-32V266.3L149.2 96H64V64c0-17.7-14.3-32-32-32zM405.2 96H330.8l-5.4 10.7L234.8 288h74.3l5.4-10.7L405.2 96zM362.8 288h74.3l5.4-10.7L533.2 96H458.8l-5.4 10.7L362.8 288zM202.8 96l-5.4 10.7L106.8 288h74.3l5.4-10.7L277.2 96H202.8zm288 192H576V448c0 17.7 14.3 32 32 32s32-14.3 32-32V64c0-17.7-14.3-32-32-32s-32 14.3-32 32v53.7L490.8 288z" } }, "free": ["solid"] }, "road-bridge": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["bridge", "infrastructure", "road", "travel"] }, "styles": ["solid"], "unicode": "e563", "label": "Road Bridge", "voted": false, "svg": { "solid": { "last_modified": 1684767489, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M352 0H608c17.7 0 32 14.3 32 32V480c0 17.7-14.3 32-32 32H352c-17.7 0-32-14.3-32-32V32c0-17.7 14.3-32 32-32zM480 200c-13.3 0-24 10.7-24 24v64c0 13.3 10.7 24 24 24s24-10.7 24-24V224c0-13.3-10.7-24-24-24zm24 184c0-13.3-10.7-24-24-24s-24 10.7-24 24v64c0 13.3 10.7 24 24 24s24-10.7 24-24V384zM480 40c-13.3 0-24 10.7-24 24v64c0 13.3 10.7 24 24 24s24-10.7 24-24V64c0-13.3-10.7-24-24-24zM32 96H288v64H248v64h40v96c-53 0-96 43-96 96v64c0 17.7-14.3 32-32 32H128c-17.7 0-32-14.3-32-32V416c0-53-43-96-96-96V224H72V160H32c-17.7 0-32-14.3-32-32s14.3-32 32-32zm168 64H120v64h80V160z" } }, "free": ["solid"] }, "road-circle-check": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "freeway", "highway", "not affected", "ok", "okay", "pavement", "road" ] }, "styles": ["solid"], "unicode": "e564", "label": "Road Circle Check", "voted": false, "svg": { "solid": { "last_modified": 1684767489, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M213.2 32H288V96c0 17.7 14.3 32 32 32s32-14.3 32-32V32h74.8c27.1 0 51.3 17.1 60.3 42.6l42.7 120.6c-10.9-2.1-22.2-3.2-33.8-3.2c-59.5 0-112.1 29.6-144 74.8V224c0-17.7-14.3-32-32-32s-32 14.3-32 32v64c0 17.7 14.3 32 32 32c2.3 0 4.6-.3 6.8-.7c-4.5 15.5-6.8 31.8-6.8 48.7c0 5.4 .2 10.7 .7 16l-.7 0c-17.7 0-32 14.3-32 32v64H86.6C56.5 480 32 455.5 32 425.4c0-6.2 1.1-12.4 3.1-18.2L152.9 74.6C162 49.1 186.1 32 213.2 32zM352 368a144 144 0 1 1 288 0 144 144 0 1 1 -288 0zm211.3-43.3c-6.2-6.2-16.4-6.2-22.6 0L480 385.4l-28.7-28.7c-6.2-6.2-16.4-6.2-22.6 0s-6.2 16.4 0 22.6l40 40c6.2 6.2 16.4 6.2 22.6 0l72-72c6.2-6.2 6.2-16.4 0-22.6z" } }, "free": ["solid"] }, "road-circle-exclamation": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["affected", "freeway", "highway", "pavement", "road"] }, "styles": ["solid"], "unicode": "e565", "label": "Road Circle Exclamation", "voted": false, "svg": { "solid": { "last_modified": 1684767488, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M213.2 32H288V96c0 17.7 14.3 32 32 32s32-14.3 32-32V32h74.8c27.1 0 51.3 17.1 60.3 42.6l42.7 120.6c-10.9-2.1-22.2-3.2-33.8-3.2c-59.5 0-112.1 29.6-144 74.8V224c0-17.7-14.3-32-32-32s-32 14.3-32 32v64c0 17.7 14.3 32 32 32c2.3 0 4.6-.3 6.8-.7c-4.5 15.5-6.8 31.8-6.8 48.7c0 5.4 .2 10.7 .7 16l-.7 0c-17.7 0-32 14.3-32 32v64H86.6C56.5 480 32 455.5 32 425.4c0-6.2 1.1-12.4 3.1-18.2L152.9 74.6C162 49.1 186.1 32 213.2 32zM496 224a144 144 0 1 1 0 288 144 144 0 1 1 0-288zm0 240a24 24 0 1 0 0-48 24 24 0 1 0 0 48zm0-192c-8.8 0-16 7.2-16 16v80c0 8.8 7.2 16 16 16s16-7.2 16-16V288c0-8.8-7.2-16-16-16z" } }, "free": ["solid"] }, "road-circle-xmark": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["destroy", "freeway", "highway", "pavement", "road"] }, "styles": ["solid"], "unicode": "e566", "label": "Road Circle Xmark", "voted": false, "svg": { "solid": { "last_modified": 1684767489, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M213.2 32H288V96c0 17.7 14.3 32 32 32s32-14.3 32-32V32h74.8c27.1 0 51.3 17.1 60.3 42.6l42.7 120.6c-10.9-2.1-22.2-3.2-33.8-3.2c-59.5 0-112.1 29.6-144 74.8V224c0-17.7-14.3-32-32-32s-32 14.3-32 32v64c0 17.7 14.3 32 32 32c2.3 0 4.6-.3 6.8-.7c-4.5 15.5-6.8 31.8-6.8 48.7c0 5.4 .2 10.7 .7 16l-.7 0c-17.7 0-32 14.3-32 32v64H86.6C56.5 480 32 455.5 32 425.4c0-6.2 1.1-12.4 3.1-18.2L152.9 74.6C162 49.1 186.1 32 213.2 32zM496 224a144 144 0 1 1 0 288 144 144 0 1 1 0-288zm22.6 144l36.7-36.7c6.2-6.2 6.2-16.4 0-22.6s-16.4-6.2-22.6 0L496 345.4l-36.7-36.7c-6.2-6.2-16.4-6.2-22.6 0s-6.2 16.4 0 22.6L473.4 368l-36.7 36.7c-6.2 6.2-6.2 16.4 0 22.6s16.4 6.2 22.6 0L496 390.6l36.7 36.7c6.2 6.2 16.4 6.2 22.6 0s6.2-16.4 0-22.6L518.6 368z" } }, "free": ["solid"] }, "road-lock": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "closed", "freeway", "highway", "lockdown", "pavement", "quarantine", "road" ] }, "styles": ["solid"], "unicode": "e567", "label": "Road Lock", "voted": false, "svg": { "solid": { "last_modified": 1684767489, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M288 32H213.2c-27.1 0-51.3 17.1-60.3 42.6L35.1 407.2c-2.1 5.9-3.1 12-3.1 18.2C32 455.5 56.5 480 86.6 480H288V416c0-17.7 14.3-32 32-32s32 14.3 32 32v64h32V352c0-23.7 12.9-44.4 32-55.4V272c0-58.3 44.6-106.2 101.5-111.5L487.1 74.6C478 49.1 453.9 32 426.8 32H352V96c0 17.7-14.3 32-32 32s-32-14.3-32-32V32zm64 192v64c0 17.7-14.3 32-32 32s-32-14.3-32-32V224c0-17.7 14.3-32 32-32s32 14.3 32 32zm176 16c17.7 0 32 14.3 32 32v48H496V272c0-17.7 14.3-32 32-32zm-80 32v48c-17.7 0-32 14.3-32 32V480c0 17.7 14.3 32 32 32H608c17.7 0 32-14.3 32-32V352c0-17.7-14.3-32-32-32V272c0-44.2-35.8-80-80-80s-80 35.8-80 80z" } }, "free": ["solid"] }, "road-spikes": { "changes": ["6.1.0", "6.1.2", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["barrier", "roadblock", "spikes"] }, "styles": ["solid"], "unicode": "e568", "label": "Road Spikes", "voted": false, "svg": { "solid": { "last_modified": 1684767443, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M64 116.8c0-15.8 20.5-22 29.3-8.9L192 256V116.8c0-15.8 20.5-22 29.3-8.9L320 256V116.8c0-15.8 20.5-22 29.3-8.9L448 256V116.8c0-15.8 20.5-22 29.3-8.9L606.8 302.2c14.2 21.3-1.1 49.7-26.6 49.7H512 448 384 320 256 192 64V116.8zM32 384H608c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32z" } }, "free": ["solid"] }, "robot": { "aliases": { "unicodes": { "composite": ["1f916"], "secondary": ["10f544"] } }, "changes": ["5.0.13", "5.12.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "android", "automate", "computer", "cyborg", "face", "monster", "robot" ] }, "styles": ["solid"], "unicode": "f544", "label": "Robot", "voted": true, "svg": { "solid": { "last_modified": 1684767601, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M320 0c17.7 0 32 14.3 32 32V96H472c39.8 0 72 32.2 72 72V440c0 39.8-32.2 72-72 72H168c-39.8 0-72-32.2-72-72V168c0-39.8 32.2-72 72-72H288V32c0-17.7 14.3-32 32-32zM208 384c-8.8 0-16 7.2-16 16s7.2 16 16 16h32c8.8 0 16-7.2 16-16s-7.2-16-16-16H208zm96 0c-8.8 0-16 7.2-16 16s7.2 16 16 16h32c8.8 0 16-7.2 16-16s-7.2-16-16-16H304zm96 0c-8.8 0-16 7.2-16 16s7.2 16 16 16h32c8.8 0 16-7.2 16-16s-7.2-16-16-16H400zM264 256a40 40 0 1 0 -80 0 40 40 0 1 0 80 0zm152 40a40 40 0 1 0 0-80 40 40 0 1 0 0 80zM48 224H64V416H48c-26.5 0-48-21.5-48-48V272c0-26.5 21.5-48 48-48zm544 0c26.5 0 48 21.5 48 48v96c0 26.5-21.5 48-48 48H576V224h16z" } }, "free": ["solid"] }, "rocket": { "aliases": { "unicodes": { "secondary": ["10f135"] } }, "changes": [ "3.1.0", "5.0.0", "5.7.0", "5.12.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["aircraft", "app", "jet", "launch", "nasa", "space"] }, "styles": ["solid"], "unicode": "f135", "label": "Rocket", "voted": false, "svg": { "solid": { "last_modified": 1684767636, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M156.6 384.9L125.7 354c-8.5-8.5-11.5-20.8-7.7-32.2c3-8.9 7-20.5 11.8-33.8L24 288c-8.6 0-16.6-4.6-20.9-12.1s-4.2-16.7 .2-24.1l52.5-88.5c13-21.9 36.5-35.3 61.9-35.3l82.3 0c2.4-4 4.8-7.7 7.2-11.3C289.1-4.1 411.1-8.1 483.9 5.3c11.6 2.1 20.6 11.2 22.8 22.8c13.4 72.9 9.3 194.8-111.4 276.7c-3.5 2.4-7.3 4.8-11.3 7.2v82.3c0 25.4-13.4 49-35.3 61.9l-88.5 52.5c-7.4 4.4-16.6 4.5-24.1 .2s-12.1-12.2-12.1-20.9V380.8c-14.1 4.9-26.4 8.9-35.7 11.9c-11.2 3.6-23.4 .5-31.8-7.8zM384 168a40 40 0 1 0 0-80 40 40 0 1 0 0 80z" } }, "free": ["solid"] }, "rocketchat": { "changes": ["5.0.0", "5.4.2", "5.8.0", "5.15.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3e8", "label": "Rocket.Chat", "voted": false, "svg": { "brands": { "last_modified": 1660014481, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M284.046,224.8a34.114,34.114,0,1,0,34.317,34.113A34.217,34.217,0,0,0,284.046,224.8Zm-110.45,0a34.114,34.114,0,1,0,34.317,34.113A34.217,34.217,0,0,0,173.6,224.8Zm220.923,0a34.114,34.114,0,1,0,34.317,34.113A34.215,34.215,0,0,0,394.519,224.8Zm153.807-55.319c-15.535-24.172-37.31-45.57-64.681-63.618-52.886-34.817-122.374-54-195.666-54a405.975,405.975,0,0,0-72.032,6.357,238.524,238.524,0,0,0-49.51-36.588C99.684-11.7,40.859.711,11.135,11.421A14.291,14.291,0,0,0,5.58,34.782C26.542,56.458,61.222,99.3,52.7,138.252c-33.142,33.9-51.112,74.776-51.112,117.337,0,43.372,17.97,84.248,51.112,118.148,8.526,38.956-26.154,81.816-47.116,103.491a14.284,14.284,0,0,0,5.555,23.34c29.724,10.709,88.549,23.147,155.324-10.2a238.679,238.679,0,0,0,49.51-36.589A405.972,405.972,0,0,0,288,460.14c73.313,0,142.8-19.159,195.667-53.975,27.371-18.049,49.145-39.426,64.679-63.619,17.309-26.923,26.07-55.916,26.07-86.125C574.394,225.4,565.634,196.43,548.326,169.485ZM284.987,409.9a345.65,345.65,0,0,1-89.446-11.5l-20.129,19.393a184.366,184.366,0,0,1-37.138,27.585,145.767,145.767,0,0,1-52.522,14.87c.983-1.771,1.881-3.563,2.842-5.356q30.258-55.68,16.325-100.078c-32.992-25.962-52.778-59.2-52.778-95.4,0-83.1,104.254-150.469,232.846-150.469s232.867,67.373,232.867,150.469C517.854,342.525,413.6,409.9,284.987,409.9Z" } }, "free": ["brands"] }, "rockrms": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3e9", "label": "Rockrms", "voted": false, "svg": { "brands": { "last_modified": 1660014461, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm157.4 419.5h-90l-112-131.3c-17.9-20.4-3.9-56.1 26.6-56.1h75.3l-84.6-99.3-84.3 98.9h-90L193.5 67.2c14.4-18.4 41.3-17.3 54.5 0l157.7 185.1c19 22.8 2 57.2-27.6 56.1-.6 0-74.2.2-74.2.2l101.5 118.9z" } }, "free": ["brands"] }, "rotate": { "aliases": { "names": ["sync-alt"], "unicodes": { "composite": ["1f504"], "secondary": ["10f2f1"] } }, "changes": ["5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "anticlockwise", "arrow", "counterclockwise", "counterclockwise arrows button", "exchange", "refresh", "reload", "rotate", "swap", "withershins" ] }, "styles": ["solid"], "unicode": "f2f1", "label": "Rotate", "voted": false, "svg": { "solid": { "last_modified": 1684766329, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M142.9 142.9c62.2-62.2 162.7-62.5 225.3-1L327 183c-6.9 6.9-8.9 17.2-5.2 26.2s12.5 14.8 22.2 14.8H463.5c0 0 0 0 0 0H472c13.3 0 24-10.7 24-24V72c0-9.7-5.8-18.5-14.8-22.2s-19.3-1.7-26.2 5.2L413.4 96.6c-87.6-86.5-228.7-86.2-315.8 1C73.2 122 55.6 150.7 44.8 181.4c-5.9 16.7 2.9 34.9 19.5 40.8s34.9-2.9 40.8-19.5c7.7-21.8 20.2-42.3 37.8-59.8zM16 312v7.6 .7V440c0 9.7 5.8 18.5 14.8 22.2s19.3 1.7 26.2-5.2l41.6-41.6c87.6 86.5 228.7 86.2 315.8-1c24.4-24.4 42.1-53.1 52.9-83.7c5.9-16.7-2.9-34.9-19.5-40.8s-34.9 2.9-40.8 19.5c-7.7 21.8-20.2 42.3-37.8 59.8c-62.2 62.2-162.7 62.5-225.3 1L185 329c6.9-6.9 8.9-17.2 5.2-26.2s-12.5-14.8-22.2-14.8H48.4h-.7H40c-13.3 0-24 10.7-24 24z" } }, "free": ["solid"] }, "rotate-left": { "aliases": { "names": ["rotate-back", "rotate-backward", "undo-alt"], "unicodes": { "secondary": ["10f2ea"] } }, "changes": ["5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["back", "control z", "exchange", "oops", "return", "swap"] }, "styles": ["solid"], "unicode": "f2ea", "label": "Rotate Left", "voted": false, "svg": { "solid": { "last_modified": 1684766331, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M48.5 224H40c-13.3 0-24-10.7-24-24V72c0-9.7 5.8-18.5 14.8-22.2s19.3-1.7 26.2 5.2L98.6 96.6c87.6-86.5 228.7-86.2 315.8 1c87.5 87.5 87.5 229.3 0 316.8s-229.3 87.5-316.8 0c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0c62.5 62.5 163.8 62.5 226.3 0s62.5-163.8 0-226.3c-62.2-62.2-162.7-62.5-225.3-1L185 183c6.9 6.9 8.9 17.2 5.2 26.2s-12.5 14.8-22.2 14.8H48.5z" } }, "free": ["solid"] }, "rotate-right": { "aliases": { "names": ["redo-alt", "rotate-forward"], "unicodes": { "secondary": ["10f2f9"] } }, "changes": ["5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["forward", "refresh", "reload", "repeat"] }, "styles": ["solid"], "unicode": "f2f9", "label": "Rotate Right", "voted": false, "svg": { "solid": { "last_modified": 1684766329, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M463.5 224H472c13.3 0 24-10.7 24-24V72c0-9.7-5.8-18.5-14.8-22.2s-19.3-1.7-26.2 5.2L413.4 96.6c-87.6-86.5-228.7-86.2-315.8 1c-87.5 87.5-87.5 229.3 0 316.8s229.3 87.5 316.8 0c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0c-62.5 62.5-163.8 62.5-226.3 0s-62.5-163.8 0-226.3c62.2-62.2 162.7-62.5 225.3-1L327 183c-6.9 6.9-8.9 17.2-5.2 26.2s12.5 14.8 22.2 14.8H463.5z" } }, "free": ["solid"] }, "route": { "aliases": { "unicodes": { "secondary": ["10f4d7"] } }, "changes": [ "5.0.9", "5.2.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["directions", "navigation", "travel"] }, "styles": ["solid"], "unicode": "f4d7", "label": "Route", "voted": false, "svg": { "solid": { "last_modified": 1684767489, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M512 96c0 50.2-59.1 125.1-84.6 155c-3.8 4.4-9.4 6.1-14.5 5H320c-17.7 0-32 14.3-32 32s14.3 32 32 32h96c53 0 96 43 96 96s-43 96-96 96H139.6c8.7-9.9 19.3-22.6 30-36.8c6.3-8.4 12.8-17.6 19-27.2H416c17.7 0 32-14.3 32-32s-14.3-32-32-32H320c-53 0-96-43-96-96s43-96 96-96h39.8c-21-31.5-39.8-67.7-39.8-96c0-53 43-96 96-96s96 43 96 96zM117.1 489.1c-3.8 4.3-7.2 8.1-10.1 11.3l-1.8 2-.2-.2c-6 4.6-14.6 4-20-1.8C59.8 473 0 402.5 0 352c0-53 43-96 96-96s96 43 96 96c0 30-21.1 67-43.5 97.9c-10.7 14.7-21.7 28-30.8 38.5l-.6 .7zM128 352a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zM416 128a32 32 0 1 0 0-64 32 32 0 1 0 0 64z" } }, "free": ["solid"] }, "rss": { "aliases": { "names": ["feed"], "unicodes": { "secondary": ["10f09e"] } }, "changes": ["2.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["blog", "feed", "journal", "news", "writing"] }, "styles": ["solid"], "unicode": "f09e", "label": "Rss", "voted": false, "svg": { "solid": { "last_modified": 1684766675, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M0 64C0 46.3 14.3 32 32 32c229.8 0 416 186.2 416 416c0 17.7-14.3 32-32 32s-32-14.3-32-32C384 253.6 226.4 96 32 96C14.3 96 0 81.7 0 64zM0 416a64 64 0 1 1 128 0A64 64 0 1 1 0 416zM32 160c159.1 0 288 128.9 288 288c0 17.7-14.3 32-32 32s-32-14.3-32-32c0-123.7-100.3-224-224-224c-17.7 0-32-14.3-32-32s14.3-32 32-32z" } }, "free": ["solid"] }, "ruble-sign": { "aliases": { "names": ["rouble", "rub", "ruble"], "unicodes": { "composite": ["20bd"], "secondary": ["10f158"] } }, "changes": [ "4.0.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["Ruble Sign", "currency"] }, "styles": ["solid"], "unicode": "f158", "label": "Ruble Sign", "voted": false, "svg": { "solid": { "last_modified": 1684766475, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M96 32C78.3 32 64 46.3 64 64V256H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H64v32H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H64v32c0 17.7 14.3 32 32 32s32-14.3 32-32V416H288c17.7 0 32-14.3 32-32s-14.3-32-32-32H128V320H240c79.5 0 144-64.5 144-144s-64.5-144-144-144H96zM240 256H128V96H240c44.2 0 80 35.8 80 80s-35.8 80-80 80z" } }, "free": ["solid"] }, "rug": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["blanket", "carpet", "rug", "textile"] }, "styles": ["solid"], "unicode": "e569", "label": "Rug", "voted": false, "svg": { "solid": { "last_modified": 1684767441, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M24 64H56 80V88v88 80 80 88 24H56 24c-13.3 0-24-10.7-24-24s10.7-24 24-24h8V360H24c-13.3 0-24-10.7-24-24s10.7-24 24-24h8V280H24c-13.3 0-24-10.7-24-24s10.7-24 24-24h8V200H24c-13.3 0-24-10.7-24-24s10.7-24 24-24h8V112H24C10.7 112 0 101.3 0 88S10.7 64 24 64zm88 0H528V448H112V64zM640 88c0 13.3-10.7 24-24 24h-8v40h8c13.3 0 24 10.7 24 24s-10.7 24-24 24h-8v32h8c13.3 0 24 10.7 24 24s-10.7 24-24 24h-8v32h8c13.3 0 24 10.7 24 24s-10.7 24-24 24h-8v40h8c13.3 0 24 10.7 24 24s-10.7 24-24 24H584 560V424 336 256 176 88 64h24 32c13.3 0 24 10.7 24 24z" } }, "free": ["solid"] }, "ruler": { "aliases": { "unicodes": { "composite": ["1f4cf"], "secondary": ["10f545"] } }, "changes": ["5.0.13", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "design", "draft", "length", "measure", "planning", "ruler", "straight edge", "straight ruler" ] }, "styles": ["solid"], "unicode": "f545", "label": "Ruler", "voted": true, "svg": { "solid": { "last_modified": 1684767367, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M177.9 494.1c-18.7 18.7-49.1 18.7-67.9 0L17.9 401.9c-18.7-18.7-18.7-49.1 0-67.9l50.7-50.7 48 48c6.2 6.2 16.4 6.2 22.6 0s6.2-16.4 0-22.6l-48-48 41.4-41.4 48 48c6.2 6.2 16.4 6.2 22.6 0s6.2-16.4 0-22.6l-48-48 41.4-41.4 48 48c6.2 6.2 16.4 6.2 22.6 0s6.2-16.4 0-22.6l-48-48 41.4-41.4 48 48c6.2 6.2 16.4 6.2 22.6 0s6.2-16.4 0-22.6l-48-48 50.7-50.7c18.7-18.7 49.1-18.7 67.9 0l92.1 92.1c18.7 18.7 18.7 49.1 0 67.9L177.9 494.1z" } }, "free": ["solid"] }, "ruler-combined": { "aliases": { "unicodes": { "secondary": ["10f546"] } }, "changes": ["5.0.13", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["design", "draft", "length", "measure", "planning"] }, "styles": ["solid"], "unicode": "f546", "label": "Ruler Combined", "voted": true, "svg": { "solid": { "last_modified": 1684767366, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M.2 468.9C2.7 493.1 23.1 512 48 512l96 0 320 0c26.5 0 48-21.5 48-48l0-96c0-26.5-21.5-48-48-48l-48 0 0 80c0 8.8-7.2 16-16 16s-16-7.2-16-16l0-80-64 0 0 80c0 8.8-7.2 16-16 16s-16-7.2-16-16l0-80-64 0 0 80c0 8.8-7.2 16-16 16s-16-7.2-16-16l0-80-80 0c-8.8 0-16-7.2-16-16s7.2-16 16-16l80 0 0-64-80 0c-8.8 0-16-7.2-16-16s7.2-16 16-16l80 0 0-64-80 0c-8.8 0-16-7.2-16-16s7.2-16 16-16l80 0 0-48c0-26.5-21.5-48-48-48L48 0C21.5 0 0 21.5 0 48L0 368l0 96c0 1.7 .1 3.3 .2 4.9z" } }, "free": ["solid"] }, "ruler-horizontal": { "aliases": { "unicodes": { "secondary": ["10f547"] } }, "changes": ["5.0.13", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["design", "draft", "length", "measure", "planning"] }, "styles": ["solid"], "unicode": "f547", "label": "Ruler Horizontal", "voted": true, "svg": { "solid": { "last_modified": 1684767368, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M0 336c0 26.5 21.5 48 48 48l544 0c26.5 0 48-21.5 48-48l0-160c0-26.5-21.5-48-48-48l-64 0 0 80c0 8.8-7.2 16-16 16s-16-7.2-16-16l0-80-64 0 0 80c0 8.8-7.2 16-16 16s-16-7.2-16-16l0-80-64 0 0 80c0 8.8-7.2 16-16 16s-16-7.2-16-16l0-80-64 0 0 80c0 8.8-7.2 16-16 16s-16-7.2-16-16l0-80-64 0 0 80c0 8.8-7.2 16-16 16s-16-7.2-16-16l0-80-64 0c-26.5 0-48 21.5-48 48L0 336z" } }, "free": ["solid"] }, "ruler-vertical": { "aliases": { "unicodes": { "secondary": ["10f548"] } }, "changes": ["5.0.13", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["design", "draft", "length", "measure", "planning"] }, "styles": ["solid"], "unicode": "f548", "label": "Ruler Vertical", "voted": true, "svg": { "solid": { "last_modified": 1684767366, "raw": "", "viewBox": [0, 0, 256, 512], "width": 256, "height": 512, "path": "M0 48C0 21.5 21.5 0 48 0H208c26.5 0 48 21.5 48 48V96H176c-8.8 0-16 7.2-16 16s7.2 16 16 16h80v64H176c-8.8 0-16 7.2-16 16s7.2 16 16 16h80v64H176c-8.8 0-16 7.2-16 16s7.2 16 16 16h80v64H176c-8.8 0-16 7.2-16 16s7.2 16 16 16h80v48c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V48z" } }, "free": ["solid"] }, "rupee-sign": { "aliases": { "names": ["rupee"], "unicodes": { "composite": ["20a8"], "secondary": ["10f156"] } }, "changes": [ "3.2.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["Rupee Sign", "currency"] }, "styles": ["solid"], "unicode": "f156", "label": "Rupee Sign", "voted": false, "svg": { "solid": { "last_modified": 1684766475, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M0 64C0 46.3 14.3 32 32 32h80c79.5 0 144 64.5 144 144c0 58.8-35.2 109.3-85.7 131.7l51.4 128.4c6.6 16.4-1.4 35-17.8 41.6s-35-1.4-41.6-17.8L106.3 320H64V448c0 17.7-14.3 32-32 32s-32-14.3-32-32V288 64zM64 256h48c44.2 0 80-35.8 80-80s-35.8-80-80-80H64V256zm256.5 16.4c-.9 6 0 8.7 .4 9.8c.4 1.1 1.4 2.6 4.2 4.9c7.2 5.7 18.7 10 37.9 16.8l1.3 .5c16 5.6 38.7 13.6 55.7 28.1c9.5 8.1 17.9 18.6 23.1 32.3c5.1 13.7 6.1 28.5 3.8 44c-4.2 28.1-20.5 49.3-43.8 60.9c-22.1 11-48.1 12.5-73.2 8l-.2 0 0 0c-9.3-1.8-20.5-5.7-29.3-9c-6-2.3-12.6-4.9-17.7-6.9l0 0c-2.5-1-4.6-1.8-6.3-2.5c-16.5-6.4-24.6-25-18.2-41.4s24.9-24.6 41.4-18.2c2.6 1 5.2 2 7.9 3.1l0 0c4.8 1.9 9.8 3.9 15.4 6c8.8 3.3 15.3 5.4 18.7 6c15.7 2.8 26.7 .8 32.9-2.3c5-2.5 8-6 9.1-13c1-6.9 .2-10.5-.5-12.3c-.6-1.7-1.8-3.6-4.5-5.9c-6.9-5.8-18.2-10.4-36.9-17l-3-1.1c-15.5-5.4-37-13-53.3-25.9c-9.5-7.5-18.3-17.6-23.7-31c-5.5-13.4-6.6-28-4.4-43.2c8.4-57.1 67-78 116.9-68.9c6.9 1.3 27.3 5.8 35.4 8.4c16.9 5.2 26.3 23.2 21.1 40.1s-23.2 26.3-40.1 21.1c-4.7-1.4-22.3-5.5-27.9-6.5c-14.6-2.7-25.8-.4-32.6 3.2c-6.3 3.3-8.9 7.6-9.5 12z" } }, "free": ["solid"] }, "rupiah-sign": { "changes": ["6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["currency"] }, "styles": ["solid"], "unicode": "e23d", "label": "Rupiah Sign", "voted": false, "svg": { "solid": { "last_modified": 1684766475, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 64C0 46.3 14.3 32 32 32h80c79.5 0 144 64.5 144 144c0 58.8-35.2 109.3-85.7 131.7l51.4 128.4c6.6 16.4-1.4 35-17.8 41.6s-35-1.4-41.6-17.8L106.3 320H64V448c0 17.7-14.3 32-32 32s-32-14.3-32-32V288 64zM64 256h48c44.2 0 80-35.8 80-80s-35.8-80-80-80H64V256zm256-96h80c61.9 0 112 50.1 112 112s-50.1 112-112 112H352v96c0 17.7-14.3 32-32 32s-32-14.3-32-32V352 192c0-17.7 14.3-32 32-32zm80 160c26.5 0 48-21.5 48-48s-21.5-48-48-48H352v96h48z" } }, "free": ["solid"] }, "rust": { "changes": ["5.13.1", "5.14.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e07a", "label": "Rust", "voted": true, "svg": { "brands": { "last_modified": 1660014463, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M508.52,249.75,486.7,236.24c-.17-2-.34-3.93-.55-5.88l18.72-17.5a7.35,7.35,0,0,0-2.44-12.25l-24-9c-.54-1.88-1.08-3.78-1.67-5.64l15-20.83a7.35,7.35,0,0,0-4.79-11.54l-25.42-4.15c-.9-1.73-1.79-3.45-2.73-5.15l10.68-23.42a7.35,7.35,0,0,0-6.95-10.39l-25.82.91q-1.79-2.22-3.61-4.4L439,81.84A7.36,7.36,0,0,0,430.16,73L405,78.93q-2.17-1.83-4.4-3.61l.91-25.82a7.35,7.35,0,0,0-10.39-7L367.7,53.23c-1.7-.94-3.43-1.84-5.15-2.73L358.4,25.08a7.35,7.35,0,0,0-11.54-4.79L326,35.26c-1.86-.59-3.75-1.13-5.64-1.67l-9-24a7.35,7.35,0,0,0-12.25-2.44l-17.5,18.72c-1.95-.21-3.91-.38-5.88-.55L262.25,3.48a7.35,7.35,0,0,0-12.5,0L236.24,25.3c-2,.17-3.93.34-5.88.55L212.86,7.13a7.35,7.35,0,0,0-12.25,2.44l-9,24c-1.89.55-3.79,1.08-5.66,1.68l-20.82-15a7.35,7.35,0,0,0-11.54,4.79l-4.15,25.41c-1.73.9-3.45,1.79-5.16,2.73L120.88,42.55a7.35,7.35,0,0,0-10.39,7l.92,25.81c-1.49,1.19-3,2.39-4.42,3.61L81.84,73A7.36,7.36,0,0,0,73,81.84L78.93,107c-1.23,1.45-2.43,2.93-3.62,4.41l-25.81-.91a7.42,7.42,0,0,0-6.37,3.26,7.35,7.35,0,0,0-.57,7.13l10.66,23.41c-.94,1.7-1.83,3.43-2.73,5.16L25.08,153.6a7.35,7.35,0,0,0-4.79,11.54l15,20.82c-.59,1.87-1.13,3.77-1.68,5.66l-24,9a7.35,7.35,0,0,0-2.44,12.25l18.72,17.5c-.21,1.95-.38,3.91-.55,5.88L3.48,249.75a7.35,7.35,0,0,0,0,12.5L25.3,275.76c.17,2,.34,3.92.55,5.87L7.13,299.13a7.35,7.35,0,0,0,2.44,12.25l24,9c.55,1.89,1.08,3.78,1.68,5.65l-15,20.83a7.35,7.35,0,0,0,4.79,11.54l25.42,4.15c.9,1.72,1.79,3.45,2.73,5.14L42.56,391.12a7.35,7.35,0,0,0,.57,7.13,7.13,7.13,0,0,0,6.37,3.26l25.83-.91q1.77,2.22,3.6,4.4L73,430.16A7.36,7.36,0,0,0,81.84,439L107,433.07q2.18,1.83,4.41,3.61l-.92,25.82a7.35,7.35,0,0,0,10.39,6.95l23.43-10.68c1.69.94,3.42,1.83,5.14,2.73l4.15,25.42a7.34,7.34,0,0,0,11.54,4.78l20.83-15c1.86.6,3.76,1.13,5.65,1.68l9,24a7.36,7.36,0,0,0,12.25,2.44l17.5-18.72c1.95.21,3.92.38,5.88.55l13.51,21.82a7.35,7.35,0,0,0,12.5,0l13.51-21.82c2-.17,3.93-.34,5.88-.56l17.5,18.73a7.36,7.36,0,0,0,12.25-2.44l9-24c1.89-.55,3.78-1.08,5.65-1.68l20.82,15a7.34,7.34,0,0,0,11.54-4.78l4.15-25.42c1.72-.9,3.45-1.79,5.15-2.73l23.42,10.68a7.35,7.35,0,0,0,10.39-6.95l-.91-25.82q2.22-1.79,4.4-3.61L430.16,439a7.36,7.36,0,0,0,8.84-8.84L433.07,405q1.83-2.17,3.61-4.4l25.82.91a7.23,7.23,0,0,0,6.37-3.26,7.35,7.35,0,0,0,.58-7.13L458.77,367.7c.94-1.7,1.83-3.43,2.73-5.15l25.42-4.15a7.35,7.35,0,0,0,4.79-11.54l-15-20.83c.59-1.87,1.13-3.76,1.67-5.65l24-9a7.35,7.35,0,0,0,2.44-12.25l-18.72-17.5c.21-1.95.38-3.91.55-5.87l21.82-13.51a7.35,7.35,0,0,0,0-12.5Zm-151,129.08A13.91,13.91,0,0,0,341,389.51l-7.64,35.67A187.51,187.51,0,0,1,177,424.44l-7.64-35.66a13.87,13.87,0,0,0-16.46-10.68l-31.51,6.76a187.38,187.38,0,0,1-16.26-19.21H258.3c1.72,0,2.89-.29,2.89-1.91V309.55c0-1.57-1.17-1.91-2.89-1.91H213.47l.05-34.35H262c4.41,0,23.66,1.28,29.79,25.87,1.91,7.55,6.17,32.14,9.06,40,2.89,8.82,14.6,26.46,27.1,26.46H407a187.3,187.3,0,0,1-17.34,20.09Zm25.77,34.49A15.24,15.24,0,1,1,368,398.08h.44A15.23,15.23,0,0,1,383.24,413.32Zm-225.62-.68a15.24,15.24,0,1,1-15.25-15.25h.45A15.25,15.25,0,0,1,157.62,412.64ZM69.57,234.15l32.83-14.6a13.88,13.88,0,0,0,7.06-18.33L102.69,186h26.56V305.73H75.65A187.65,187.65,0,0,1,69.57,234.15ZM58.31,198.09a15.24,15.24,0,0,1,15.23-15.25H74a15.24,15.24,0,1,1-15.67,15.24Zm155.16,24.49.05-35.32h63.26c3.28,0,23.07,3.77,23.07,18.62,0,12.29-15.19,16.7-27.68,16.7ZM399,306.71c-9.8,1.13-20.63-4.12-22-10.09-5.78-32.49-15.39-39.4-30.57-51.4,18.86-11.95,38.46-29.64,38.46-53.26,0-25.52-17.49-41.59-29.4-49.48-16.76-11-35.28-13.23-40.27-13.23H116.32A187.49,187.49,0,0,1,221.21,70.06l23.47,24.6a13.82,13.82,0,0,0,19.6.44l26.26-25a187.51,187.51,0,0,1,128.37,91.43l-18,40.57A14,14,0,0,0,408,220.43l34.59,15.33a187.12,187.12,0,0,1,.4,32.54H423.71c-1.91,0-2.69,1.27-2.69,3.13v8.82C421,301,409.31,305.58,399,306.71ZM240,60.21A15.24,15.24,0,0,1,255.21,45h.45A15.24,15.24,0,1,1,240,60.21ZM436.84,214a15.24,15.24,0,1,1,0-30.48h.44a15.24,15.24,0,0,1-.44,30.48Z" } }, "free": ["brands"] }, "s": { "aliases": { "unicodes": { "composite": ["73"] } }, "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Latin Capital Letter S", "Latin Small Letter S", "letter"] }, "styles": ["solid"], "unicode": "53", "label": "S", "voted": false, "svg": { "solid": { "last_modified": 1684767245, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M99.1 105.4C79 114 68.2 127.2 65.2 144.8c-2.4 14.1-.7 23.2 2 29.4c2.8 6.3 7.9 12.4 16.7 18.6c19.2 13.4 48.3 22.1 84.9 32.5c1 .3 1.9 .6 2.9 .8c32.7 9.3 72 20.6 100.9 40.7c15.7 10.9 29.9 25.5 38.6 45.1c8.8 19.8 10.8 42 6.6 66.3c-7.3 42.5-35.3 71.7-71.8 87.3c-35.4 15.2-79.1 17.9-123.7 10.9l-.2 0 0 0c-24-3.9-62.7-17.1-87.6-25.6c-4.8-1.7-9.2-3.1-12.8-4.3C5.1 440.8-3.9 422.7 1.6 405.9s23.7-25.8 40.5-20.3c4.9 1.6 10.2 3.4 15.9 5.4c25.4 8.6 56.4 19.2 74.4 22.1c36.8 5.7 67.5 2.5 88.5-6.5c20.1-8.6 30.8-21.8 33.9-39.4c2.4-14.1 .7-23.2-2-29.4c-2.8-6.3-7.9-12.4-16.7-18.6c-19.2-13.4-48.3-22.1-84.9-32.5c-1-.3-1.9-.6-2.9-.8c-32.7-9.3-72-20.6-100.9-40.7c-15.7-10.9-29.9-25.5-38.6-45.1c-8.8-19.8-10.8-42-6.6-66.3l31.5 5.5L2.1 133.9C9.4 91.4 37.4 62.2 73.9 46.6c35.4-15.2 79.1-17.9 123.7-10.9c13 2 52.4 9.6 66.6 13.4c17.1 4.5 27.2 22.1 22.7 39.2s-22.1 27.2-39.2 22.7c-11.2-3-48.1-10.2-60.1-12l4.9-31.5-4.9 31.5c-36.9-5.8-67.5-2.5-88.6 6.5z" } }, "free": ["solid"] }, "sack-dollar": { "aliases": { "unicodes": { "composite": ["1f4b0"], "secondary": ["10f81d"] } }, "changes": [ "5.7.0", "5.10.2", "6.0.0-beta1", "6.0.0-beta3", "6.1.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "bag", "burlap", "cash", "dollar", "money", "money bag", "moneybag", "robber", "santa", "usd" ] }, "styles": ["solid"], "unicode": "f81d", "label": "Sack Dollar", "voted": true, "svg": { "solid": { "last_modified": 1684766476, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M320 96H192L144.6 24.9C137.5 14.2 145.1 0 157.9 0H354.1c12.8 0 20.4 14.2 13.3 24.9L320 96zM192 128H320c3.8 2.5 8.1 5.3 13 8.4C389.7 172.7 512 250.9 512 416c0 53-43 96-96 96H96c-53 0-96-43-96-96C0 250.9 122.3 172.7 179 136.4l0 0 0 0c4.8-3.1 9.2-5.9 13-8.4zm84 88c0-11-9-20-20-20s-20 9-20 20v14c-7.6 1.7-15.2 4.4-22.2 8.5c-13.9 8.3-25.9 22.8-25.8 43.9c.1 20.3 12 33.1 24.7 40.7c11 6.6 24.7 10.8 35.6 14l1.7 .5c12.6 3.8 21.8 6.8 28 10.7c5.1 3.2 5.8 5.4 5.9 8.2c.1 5-1.8 8-5.9 10.5c-5 3.1-12.9 5-21.4 4.7c-11.1-.4-21.5-3.9-35.1-8.5c-2.3-.8-4.7-1.6-7.2-2.4c-10.5-3.5-21.8 2.2-25.3 12.6s2.2 21.8 12.6 25.3c1.9 .6 4 1.3 6.1 2.1l0 0 0 0c8.3 2.9 17.9 6.2 28.2 8.4V424c0 11 9 20 20 20s20-9 20-20V410.2c8-1.7 16-4.5 23.2-9c14.3-8.9 25.1-24.1 24.8-45c-.3-20.3-11.7-33.4-24.6-41.6c-11.5-7.2-25.9-11.6-37.1-15l0 0-.7-.2c-12.8-3.9-21.9-6.7-28.3-10.5c-5.2-3.1-5.3-4.9-5.3-6.7c0-3.7 1.4-6.5 6.2-9.3c5.4-3.2 13.6-5.1 21.5-5c9.6 .1 20.2 2.2 31.2 5.2c10.7 2.8 21.6-3.5 24.5-14.2s-3.5-21.6-14.2-24.5c-6.5-1.7-13.7-3.4-21.1-4.7V216z" } }, "free": ["solid"] }, "sack-xmark": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["bag", "burlap", "rations"] }, "styles": ["solid"], "unicode": "e56a", "label": "Sack Xmark", "voted": false, "svg": { "solid": { "last_modified": 1684766476, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M192 96H320l47.4-71.1C374.5 14.2 366.9 0 354.1 0H157.9c-12.8 0-20.4 14.2-13.3 24.9L192 96zm128 32H192c-3.8 2.5-8.1 5.3-13 8.4l0 0 0 0C122.3 172.7 0 250.9 0 416c0 53 43 96 96 96H416c53 0 96-43 96-96c0-165.1-122.3-243.3-179-279.6c-4.8-3.1-9.2-5.9-13-8.4zM289.9 336l47 47c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-47-47-47 47c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l47-47-47-47c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l47 47 47-47c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-47 47z" } }, "free": ["solid"] }, "safari": { "changes": ["4.4.0", "5.0.0", "5.12.0"], "ligatures": [], "search": { "terms": ["browser"] }, "styles": ["brands"], "unicode": "f267", "label": "Safari", "voted": false, "svg": { "brands": { "last_modified": 1660014479, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M274.69,274.69l-37.38-37.38L166,346ZM256,8C119,8,8,119,8,256S119,504,256,504,504,393,504,256,393,8,256,8ZM411.85,182.79l14.78-6.13A8,8,0,0,1,437.08,181h0a8,8,0,0,1-4.33,10.46L418,197.57a8,8,0,0,1-10.45-4.33h0A8,8,0,0,1,411.85,182.79ZM314.43,94l6.12-14.78A8,8,0,0,1,331,74.92h0a8,8,0,0,1,4.33,10.45l-6.13,14.78a8,8,0,0,1-10.45,4.33h0A8,8,0,0,1,314.43,94ZM256,60h0a8,8,0,0,1,8,8V84a8,8,0,0,1-8,8h0a8,8,0,0,1-8-8V68A8,8,0,0,1,256,60ZM181,74.92a8,8,0,0,1,10.46,4.33L197.57,94a8,8,0,1,1-14.78,6.12l-6.13-14.78A8,8,0,0,1,181,74.92Zm-63.58,42.49h0a8,8,0,0,1,11.31,0L140,128.72A8,8,0,0,1,140,140h0a8,8,0,0,1-11.31,0l-11.31-11.31A8,8,0,0,1,117.41,117.41ZM60,256h0a8,8,0,0,1,8-8H84a8,8,0,0,1,8,8h0a8,8,0,0,1-8,8H68A8,8,0,0,1,60,256Zm40.15,73.21-14.78,6.13A8,8,0,0,1,74.92,331h0a8,8,0,0,1,4.33-10.46L94,314.43a8,8,0,0,1,10.45,4.33h0A8,8,0,0,1,100.15,329.21Zm4.33-136h0A8,8,0,0,1,94,197.57l-14.78-6.12A8,8,0,0,1,74.92,181h0a8,8,0,0,1,10.45-4.33l14.78,6.13A8,8,0,0,1,104.48,193.24ZM197.57,418l-6.12,14.78a8,8,0,0,1-14.79-6.12l6.13-14.78A8,8,0,1,1,197.57,418ZM264,444a8,8,0,0,1-8,8h0a8,8,0,0,1-8-8V428a8,8,0,0,1,8-8h0a8,8,0,0,1,8,8Zm67-6.92h0a8,8,0,0,1-10.46-4.33L314.43,418a8,8,0,0,1,4.33-10.45h0a8,8,0,0,1,10.45,4.33l6.13,14.78A8,8,0,0,1,331,437.08Zm63.58-42.49h0a8,8,0,0,1-11.31,0L372,383.28A8,8,0,0,1,372,372h0a8,8,0,0,1,11.31,0l11.31,11.31A8,8,0,0,1,394.59,394.59ZM286.25,286.25,110.34,401.66,225.75,225.75,401.66,110.34ZM437.08,331h0a8,8,0,0,1-10.45,4.33l-14.78-6.13a8,8,0,0,1-4.33-10.45h0A8,8,0,0,1,418,314.43l14.78,6.12A8,8,0,0,1,437.08,331ZM444,264H428a8,8,0,0,1-8-8h0a8,8,0,0,1,8-8h16a8,8,0,0,1,8,8h0A8,8,0,0,1,444,264Z" } }, "free": ["brands"] }, "sailboat": { "changes": [ "6.0.0-beta2", "6.0.0-beta3", "6.1.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["dinghy", "mast", "sailboat", "sailing", "yacht"] }, "styles": ["solid"], "unicode": "e445", "label": "Sailboat", "voted": false, "svg": { "solid": { "last_modified": 1684767637, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M256 16c0-7 4.5-13.2 11.2-15.3s13.9 .4 17.9 6.1l224 320c3.4 4.9 3.8 11.3 1.1 16.6s-8.2 8.6-14.2 8.6H272c-8.8 0-16-7.2-16-16V16zM212.1 96.5c7 1.9 11.9 8.2 11.9 15.5V336c0 8.8-7.2 16-16 16H80c-5.7 0-11-3-13.8-8s-2.9-11-.1-16l128-224c3.6-6.3 11-9.4 18-7.5zM5.7 404.3C2.8 394.1 10.5 384 21.1 384H554.9c10.6 0 18.3 10.1 15.4 20.3l-4 14.3C550.7 473.9 500.4 512 443 512H133C75.6 512 25.3 473.9 9.7 418.7l-4-14.3z" } }, "free": ["solid"] }, "salesforce": { "changes": ["5.8.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f83b", "label": "Salesforce", "voted": false, "svg": { "brands": { "last_modified": 1660014464, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M248.89 245.64h-26.35c.69-5.16 3.32-14.12 13.64-14.12 6.75 0 11.97 3.82 12.71 14.12zm136.66-13.88c-.47 0-14.11-1.77-14.11 20s13.63 20 14.11 20c13 0 14.11-13.54 14.11-20 0-21.76-13.66-20-14.11-20zm-243.22 23.76a8.63 8.63 0 0 0-3.29 7.29c0 4.78 2.08 6.05 3.29 7.05 4.7 3.7 15.07 2.12 20.93.95v-16.94c-5.32-1.07-16.73-1.96-20.93 1.65zM640 232c0 87.58-80 154.39-165.36 136.43-18.37 33-70.73 70.75-132.2 41.63-41.16 96.05-177.89 92.18-213.81-5.17C8.91 428.78-50.19 266.52 53.36 205.61 18.61 126.18 76 32 167.67 32a124.24 124.24 0 0 1 98.56 48.7c20.7-21.4 49.4-34.81 81.15-34.81 42.34 0 79 23.52 98.8 58.57C539 63.78 640 132.69 640 232zm-519.55 31.8c0-11.76-11.69-15.17-17.87-17.17-5.27-2.11-13.41-3.51-13.41-8.94 0-9.46 17-6.66 25.17-2.12 0 0 1.17.71 1.64-.47.24-.7 2.36-6.58 2.59-7.29a1.13 1.13 0 0 0-.7-1.41c-12.33-7.63-40.7-8.51-40.7 12.7 0 12.46 11.49 15.44 17.88 17.17 4.72 1.58 13.17 3 13.17 8.7 0 4-3.53 7.06-9.17 7.06a31.76 31.76 0 0 1-19-6.35c-.47-.23-1.42-.71-1.65.71l-2.4 7.47c-.47.94.23 1.18.23 1.41 1.75 1.4 10.3 6.59 22.82 6.59 13.17 0 21.4-7.06 21.4-18.11zm32-42.58c-10.13 0-18.66 3.17-21.4 5.18a1 1 0 0 0-.24 1.41l2.59 7.06a1 1 0 0 0 1.18.7c.65 0 6.8-4 16.93-4 4 0 7.06.71 9.18 2.36 3.6 2.8 3.06 8.29 3.06 10.58-4.79-.3-19.11-3.44-29.41 3.76a16.92 16.92 0 0 0-7.34 14.54c0 5.9 1.51 10.4 6.59 14.35 12.24 8.16 36.28 2 38.1 1.41 1.58-.32 3.53-.66 3.53-1.88v-33.88c.04-4.61.32-21.64-22.78-21.64zM199 200.24a1.11 1.11 0 0 0-1.18-1.18H188a1.11 1.11 0 0 0-1.17 1.18v79a1.11 1.11 0 0 0 1.17 1.18h9.88a1.11 1.11 0 0 0 1.18-1.18zm55.75 28.93c-2.1-2.31-6.79-7.53-17.65-7.53-3.51 0-14.16.23-20.7 8.94-6.35 7.63-6.58 18.11-6.58 21.41 0 3.12.15 14.26 7.06 21.17 2.64 2.91 9.06 8.23 22.81 8.23 10.82 0 16.47-2.35 18.58-3.76.47-.24.71-.71.24-1.88l-2.35-6.83a1.26 1.26 0 0 0-1.41-.7c-2.59.94-6.35 2.82-15.29 2.82-17.42 0-16.85-14.74-16.94-16.7h37.17a1.23 1.23 0 0 0 1.17-.94c-.29 0 2.07-14.7-6.09-24.23zm36.69 52.69c13.17 0 21.41-7.06 21.41-18.11 0-11.76-11.7-15.17-17.88-17.17-4.14-1.66-13.41-3.38-13.41-8.94 0-3.76 3.29-6.35 8.47-6.35a38.11 38.11 0 0 1 16.7 4.23s1.18.71 1.65-.47c.23-.7 2.35-6.58 2.58-7.29a1.13 1.13 0 0 0-.7-1.41c-7.91-4.9-16.74-4.94-20.23-4.94-12 0-20.46 7.29-20.46 17.64 0 12.46 11.48 15.44 17.87 17.17 6.11 2 13.17 3.26 13.17 8.7 0 4-3.52 7.06-9.17 7.06a31.8 31.8 0 0 1-19-6.35 1 1 0 0 0-1.65.71l-2.35 7.52c-.47.94.23 1.18.23 1.41 1.72 1.4 10.33 6.59 22.79 6.59zM357.09 224c0-.71-.24-1.18-1.18-1.18h-11.76c0-.14.94-8.94 4.47-12.47 4.16-4.15 11.76-1.64 12-1.64 1.17.47 1.41 0 1.64-.47l2.83-7.77c.7-.94 0-1.17-.24-1.41-5.09-2-17.35-2.87-24.46 4.24-5.48 5.48-7 13.92-8 19.52h-8.47a1.28 1.28 0 0 0-1.17 1.18l-1.42 7.76c0 .7.24 1.17 1.18 1.17h8.23c-8.51 47.9-8.75 50.21-10.35 55.52-1.08 3.62-3.29 6.9-5.88 7.76-.09 0-3.88 1.68-9.64-.24 0 0-.94-.47-1.41.71-.24.71-2.59 6.82-2.83 7.53s0 1.41.47 1.41c5.11 2 13 1.77 17.88 0 6.28-2.28 9.72-7.89 11.53-12.94 2.75-7.71 2.81-9.79 11.76-59.74h12.23a1.29 1.29 0 0 0 1.18-1.18zm53.39 16c-.56-1.68-5.1-18.11-25.17-18.11-15.25 0-23 10-25.16 18.11-1 3-3.18 14 0 23.52.09.3 4.41 18.12 25.16 18.12 14.95 0 22.9-9.61 25.17-18.12 3.21-9.61 1.01-20.52 0-23.52zm45.4-16.7c-5-1.65-16.62-1.9-22.11 5.41v-4.47a1.11 1.11 0 0 0-1.18-1.17h-9.4a1.11 1.11 0 0 0-1.18 1.17v55.28a1.12 1.12 0 0 0 1.18 1.18h9.64a1.12 1.12 0 0 0 1.18-1.18v-27.77c0-2.91.05-11.37 4.46-15.05 4.9-4.9 12-3.36 13.41-3.06a1.57 1.57 0 0 0 1.41-.94 74 74 0 0 0 3.06-8 1.16 1.16 0 0 0-.47-1.41zm46.81 54.1l-2.12-7.29c-.47-1.18-1.41-.71-1.41-.71-4.23 1.82-10.15 1.89-11.29 1.89-4.64 0-17.17-1.13-17.17-19.76 0-6.23 1.85-19.76 16.47-19.76a34.85 34.85 0 0 1 11.52 1.65s.94.47 1.18-.71c.94-2.59 1.64-4.47 2.59-7.53.23-.94-.47-1.17-.71-1.17-11.59-3.87-22.34-2.53-27.76 0-1.59.74-16.23 6.49-16.23 27.52 0 2.9-.58 30.11 28.94 30.11a44.45 44.45 0 0 0 15.52-2.83 1.3 1.3 0 0 0 .47-1.42zm53.87-39.52c-.8-3-5.37-16.23-22.35-16.23-16 0-23.52 10.11-25.64 18.59a38.58 38.58 0 0 0-1.65 11.76c0 25.87 18.84 29.4 29.88 29.4 10.82 0 16.46-2.35 18.58-3.76.47-.24.71-.71.24-1.88l-2.36-6.83a1.26 1.26 0 0 0-1.41-.7c-2.59.94-6.35 2.82-15.29 2.82-17.42 0-16.85-14.74-16.93-16.7h37.16a1.25 1.25 0 0 0 1.18-.94c-.24-.01.94-7.07-1.41-15.54zm-23.29-6.35c-10.33 0-13 9-13.64 14.12H546c-.88-11.92-7.62-14.13-12.73-14.13z" } }, "free": ["brands"] }, "sass": { "changes": ["5.0.0", "5.8.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f41e", "label": "Sass", "voted": false, "svg": { "brands": { "last_modified": 1660014464, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M301.84 378.92c-.3.6-.6 1.08 0 0zm249.13-87a131.16 131.16 0 0 0-58 13.5c-5.9-11.9-12-22.3-13-30.1-1.2-9.1-2.5-14.5-1.1-25.3s7.7-26.1 7.6-27.2-1.4-6.6-14.3-6.7-24 2.5-25.29 5.9a122.83 122.83 0 0 0-5.3 19.1c-2.3 11.7-25.79 53.5-39.09 75.3-4.4-8.5-8.1-16-8.9-22-1.2-9.1-2.5-14.5-1.1-25.3s7.7-26.1 7.6-27.2-1.4-6.6-14.29-6.7-24 2.5-25.3 5.9-2.7 11.4-5.3 19.1-33.89 77.3-42.08 95.4c-4.2 9.2-7.8 16.6-10.4 21.6-.4.8-.7 1.3-.9 1.7.3-.5.5-1 .5-.8-2.2 4.3-3.5 6.7-3.5 6.7v.1c-1.7 3.2-3.6 6.1-4.5 6.1-.6 0-1.9-8.4.3-19.9 4.7-24.2 15.8-61.8 15.7-63.1-.1-.7 2.1-7.2-7.3-10.7-9.1-3.3-12.4 2.2-13.2 2.2s-1.4 2-1.4 2 10.1-42.4-19.39-42.4c-18.4 0-44 20.2-56.58 38.5-7.9 4.3-25 13.6-43 23.5-6.9 3.8-14 7.7-20.7 11.4-.5-.5-.9-1-1.4-1.5-35.79-38.2-101.87-65.2-99.07-116.5 1-18.7 7.5-67.8 127.07-127.4 98-48.8 176.35-35.4 189.84-5.6 19.4 42.5-41.89 121.6-143.66 133-38.79 4.3-59.18-10.7-64.28-16.3-5.3-5.9-6.1-6.2-8.1-5.1-3.3 1.8-1.2 7 0 10.1 3 7.9 15.5 21.9 36.79 28.9 18.7 6.1 64.18 9.5 119.17-11.8 61.78-23.8 109.87-90.1 95.77-145.6C386.52 18.32 293-.18 204.57 31.22c-52.69 18.7-109.67 48.1-150.66 86.4-48.69 45.6-56.48 85.3-53.28 101.9 11.39 58.9 92.57 97.3 125.06 125.7-1.6.9-3.1 1.7-4.5 2.5-16.29 8.1-78.18 40.5-93.67 74.7-17.5 38.8 2.9 66.6 16.29 70.4 41.79 11.6 84.58-9.3 107.57-43.6s20.2-79.1 9.6-99.5c-.1-.3-.3-.5-.4-.8 4.2-2.5 8.5-5 12.8-7.5 8.29-4.9 16.39-9.4 23.49-13.3-4 10.8-6.9 23.8-8.4 42.6-1.8 22 7.3 50.5 19.1 61.7 5.2 4.9 11.49 5 15.39 5 13.8 0 20-11.4 26.89-25 8.5-16.6 16-35.9 16-35.9s-9.4 52.2 16.3 52.2c9.39 0 18.79-12.1 23-18.3v.1s.2-.4.7-1.2c1-1.5 1.5-2.4 1.5-2.4v-.3c3.8-6.5 12.1-21.4 24.59-46 16.2-31.8 31.69-71.5 31.69-71.5a201.24 201.24 0 0 0 6.2 25.8c2.8 9.5 8.7 19.9 13.4 30-3.8 5.2-6.1 8.2-6.1 8.2a.31.31 0 0 0 .1.2c-3 4-6.4 8.3-9.9 12.5-12.79 15.2-28 32.6-30 37.6-2.4 5.9-1.8 10.3 2.8 13.7 3.4 2.6 9.4 3 15.69 2.5 11.5-.8 19.6-3.6 23.5-5.4a82.2 82.2 0 0 0 20.19-10.6c12.5-9.2 20.1-22.4 19.4-39.8-.4-9.6-3.5-19.2-7.3-28.2 1.1-1.6 2.3-3.3 3.4-5C434.8 301.72 450.1 270 450.1 270a201.24 201.24 0 0 0 6.2 25.8c2.4 8.1 7.09 17 11.39 25.7-18.59 15.1-30.09 32.6-34.09 44.1-7.4 21.3-1.6 30.9 9.3 33.1 4.9 1 11.9-1.3 17.1-3.5a79.46 79.46 0 0 0 21.59-11.1c12.5-9.2 24.59-22.1 23.79-39.6-.3-7.9-2.5-15.8-5.4-23.4 15.7-6.6 36.09-10.2 62.09-7.2 55.68 6.5 66.58 41.3 64.48 55.8s-13.8 22.6-17.7 25-5.1 3.3-4.8 5.1c.5 2.6 2.3 2.5 5.6 1.9 4.6-.8 29.19-11.8 30.29-38.7 1.6-34-31.09-71.4-89-71.1zm-429.18 144.7c-18.39 20.1-44.19 27.7-55.28 21.3C54.61 451 59.31 421.42 82 400c13.8-13 31.59-25 43.39-32.4 2.7-1.6 6.6-4 11.4-6.9.8-.5 1.2-.7 1.2-.7.9-.6 1.9-1.1 2.9-1.7 8.29 30.4.3 57.2-19.1 78.3zm134.36-91.4c-6.4 15.7-19.89 55.7-28.09 53.6-7-1.8-11.3-32.3-1.4-62.3 5-15.1 15.6-33.1 21.9-40.1 10.09-11.3 21.19-14.9 23.79-10.4 3.5 5.9-12.2 49.4-16.2 59.2zm111 53c-2.7 1.4-5.2 2.3-6.4 1.6-.9-.5 1.1-2.4 1.1-2.4s13.9-14.9 19.4-21.7c3.2-4 6.9-8.7 10.89-13.9 0 .5.1 1 .1 1.6-.13 17.9-17.32 30-25.12 34.8zm85.58-19.5c-2-1.4-1.7-6.1 5-20.7 2.6-5.7 8.59-15.3 19-24.5a36.18 36.18 0 0 1 1.9 10.8c-.1 22.5-16.2 30.9-25.89 34.4z" } }, "free": ["brands"] }, "satellite": { "aliases": { "unicodes": { "composite": ["1f6f0"], "secondary": ["10f7bf"] } }, "changes": [ "5.6.0", "5.10.1", "5.12.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["communications", "hardware", "orbit", "satellite", "space"] }, "styles": ["solid"], "unicode": "f7bf", "label": "Satellite", "voted": true, "svg": { "solid": { "last_modified": 1684766676, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M233 7c-9.4-9.4-24.6-9.4-33.9 0l-96 96c-9.4 9.4-9.4 24.6 0 33.9l89.4 89.4-15.5 15.5C152.3 230.4 124.9 224 96 224c-31.7 0-61.5 7.7-87.8 21.2c-9 4.7-10.3 16.7-3.1 23.8L112.7 376.7 96.3 393.1c-2.6-.7-5.4-1.1-8.3-1.1c-17.7 0-32 14.3-32 32s14.3 32 32 32s32-14.3 32-32c0-2.9-.4-5.6-1.1-8.3l16.4-16.4L242.9 506.9c7.2 7.2 19.2 5.9 23.8-3.1C280.3 477.5 288 447.7 288 416c0-28.9-6.4-56.3-17.8-80.9l15.5-15.5L375 409c9.4 9.4 24.6 9.4 33.9 0l96-96c9.4-9.4 9.4-24.6 0-33.9l-89.4-89.4 55-55c12.5-12.5 12.5-32.8 0-45.3l-48-48c-12.5-12.5-32.8-12.5-45.3 0l-55 55L233 7zm159 351l-72.4-72.4 62.1-62.1L454.1 296 392 358.1zM226.3 192.4L153.9 120 216 57.9l72.4 72.4-62.1 62.1z" } }, "free": ["solid"] }, "satellite-dish": { "aliases": { "unicodes": { "composite": ["1f4e1"], "secondary": ["10f7c0"] } }, "changes": ["5.6.0", "5.12.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "SETI", "antenna", "communications", "dish", "hardware", "radar", "receiver", "satellite", "satellite antenna", "saucer", "signal", "space" ] }, "styles": ["solid"], "unicode": "f7c0", "label": "Satellite Dish", "voted": true, "svg": { "solid": { "last_modified": 1684766676, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M192 32c0-17.7 14.3-32 32-32C383.1 0 512 128.9 512 288c0 17.7-14.3 32-32 32s-32-14.3-32-32C448 164.3 347.7 64 224 64c-17.7 0-32-14.3-32-32zM60.6 220.6L164.7 324.7l28.4-28.4c-.7-2.6-1.1-5.4-1.1-8.3c0-17.7 14.3-32 32-32s32 14.3 32 32s-14.3 32-32 32c-2.9 0-5.6-.4-8.3-1.1l-28.4 28.4L291.4 451.4c14.5 14.5 11.8 38.8-7.3 46.3C260.5 506.9 234.9 512 208 512C93.1 512 0 418.9 0 304c0-26.9 5.1-52.5 14.4-76.1c7.5-19 31.8-21.8 46.3-7.3zM224 96c106 0 192 86 192 192c0 17.7-14.3 32-32 32s-32-14.3-32-32c0-70.7-57.3-128-128-128c-17.7 0-32-14.3-32-32s14.3-32 32-32z" } }, "free": ["solid"] }, "scale-balanced": { "aliases": { "names": ["balance-scale"], "unicodes": { "composite": ["2696"], "secondary": ["10f24e"] } }, "changes": [ "4.4.0", "5.0.0", "5.0.13", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Libra", "balance", "balance scale", "balanced", "justice", "law", "legal", "measure", "rule", "scale", "weight", "zodiac" ] }, "styles": ["solid"], "unicode": "f24e", "label": "Scale Balanced", "voted": false, "svg": { "solid": { "last_modified": 1684767601, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M384 32H512c17.7 0 32 14.3 32 32s-14.3 32-32 32H398.4c-5.2 25.8-22.9 47.1-46.4 57.3V448H512c17.7 0 32 14.3 32 32s-14.3 32-32 32H320 128c-17.7 0-32-14.3-32-32s14.3-32 32-32H288V153.3c-23.5-10.3-41.2-31.6-46.4-57.3H128c-17.7 0-32-14.3-32-32s14.3-32 32-32H256c14.6-19.4 37.8-32 64-32s49.4 12.6 64 32zm55.6 288H584.4L512 195.8 439.6 320zM512 416c-62.9 0-115.2-34-126-78.9c-2.6-11 1-22.3 6.7-32.1l95.2-163.2c5-8.6 14.2-13.8 24.1-13.8s19.1 5.3 24.1 13.8l95.2 163.2c5.7 9.8 9.3 21.1 6.7 32.1C627.2 382 574.9 416 512 416zM126.8 195.8L54.4 320H199.3L126.8 195.8zM.9 337.1c-2.6-11 1-22.3 6.7-32.1l95.2-163.2c5-8.6 14.2-13.8 24.1-13.8s19.1 5.3 24.1 13.8l95.2 163.2c5.7 9.8 9.3 21.1 6.7 32.1C242 382 189.7 416 126.8 416S11.7 382 .9 337.1z" } }, "free": ["solid"] }, "scale-unbalanced": { "aliases": { "names": ["balance-scale-left"], "unicodes": { "secondary": ["10f515"] } }, "changes": [ "5.0.13", "5.9.0", "5.12.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["justice", "legal", "measure", "unbalanced", "weight"] }, "styles": ["solid"], "unicode": "f515", "label": "Scale Unbalanced", "voted": true, "svg": { "solid": { "last_modified": 1684767602, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M522.1 62.4c16.8-5.6 25.8-23.7 20.2-40.5S518.6-3.9 501.9 1.6l-113 37.7C375 15.8 349.3 0 320 0c-44.2 0-80 35.8-80 80c0 3 .2 5.9 .5 8.8L117.9 129.6c-16.8 5.6-25.8 23.7-20.2 40.5s23.7 25.8 40.5 20.2l135.5-45.2c4.5 3.2 9.3 5.9 14.4 8.2V480c0 17.7 14.3 32 32 32H512c17.7 0 32-14.3 32-32s-14.3-32-32-32H352V153.3c21-9.2 37.2-27 44.2-49l125.9-42zM439.6 288L512 163.8 584.4 288H439.6zM512 384c62.9 0 115.2-34 126-78.9c2.6-11-1-22.3-6.7-32.1L536.1 109.8c-5-8.6-14.2-13.8-24.1-13.8s-19.1 5.3-24.1 13.8L392.7 273.1c-5.7 9.8-9.3 21.1-6.7 32.1C396.8 350 449.1 384 512 384zM129.2 291.8L201.6 416H56.7l72.4-124.2zM3.2 433.1C14 478 66.3 512 129.2 512s115.2-34 126-78.9c2.6-11-1-22.3-6.7-32.1L153.2 237.8c-5-8.6-14.2-13.8-24.1-13.8s-19.1 5.3-24.1 13.8L9.9 401.1c-5.7 9.8-9.3 21.1-6.7 32.1z" } }, "free": ["solid"] }, "scale-unbalanced-flip": { "aliases": { "names": ["balance-scale-right"], "unicodes": { "secondary": ["10f516"] } }, "changes": [ "5.0.13", "5.9.0", "5.12.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["justice", "legal", "measure", "unbalanced", "weight"] }, "styles": ["solid"], "unicode": "f516", "label": "Scale Unbalanced Flip", "voted": true, "svg": { "solid": { "last_modified": 1684767602, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M117.9 62.4c-16.8-5.6-25.8-23.7-20.2-40.5s23.7-25.8 40.5-20.2l113 37.7C265 15.8 290.7 0 320 0c44.2 0 80 35.8 80 80c0 3-.2 5.9-.5 8.8l122.6 40.9c16.8 5.6 25.8 23.7 20.2 40.5s-23.7 25.8-40.5 20.2L366.4 145.2c-4.5 3.2-9.3 5.9-14.4 8.2V480c0 17.7-14.3 32-32 32H128c-17.7 0-32-14.3-32-32s14.3-32 32-32H288V153.3c-21-9.2-37.2-27-44.2-49l-125.9-42zM200.4 288L128 163.8 55.6 288H200.4zM128 384C65.1 384 12.8 350 2 305.1c-2.6-11 1-22.3 6.7-32.1l95.2-163.2c5-8.6 14.2-13.8 24.1-13.8s19.1 5.3 24.1 13.8l95.2 163.2c5.7 9.8 9.3 21.1 6.7 32.1C243.2 350 190.9 384 128 384zm382.8-92.2L438.4 416H583.3L510.8 291.8zm126 141.3C626 478 573.7 512 510.8 512s-115.2-34-126-78.9c-2.6-11 1-22.3 6.7-32.1l95.2-163.2c5-8.6 14.2-13.8 24.1-13.8s19.1 5.3 24.1 13.8l95.2 163.2c5.7 9.8 9.3 21.1 6.7 32.1z" } }, "free": ["solid"] }, "schlix": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3ea", "label": "SCHLIX", "voted": false, "svg": { "brands": { "last_modified": 1660014469, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M350.5 157.7l-54.2-46.1 73.4-39 78.3 44.2-97.5 40.9zM192 122.1l45.7-28.2 34.7 34.6-55.4 29-25-35.4zm-65.1 6.6l31.9-22.1L176 135l-36.7 22.5-12.4-28.8zm-23.3 88.2l-8.8-34.8 29.6-18.3 13.1 35.3-33.9 17.8zm-21.2-83.7l23.9-18.1 8.9 24-26.7 18.3-6.1-24.2zM59 206.5l-3.6-28.4 22.3-15.5 6.1 28.7L59 206.5zm-30.6 16.6l20.8-12.8 3.3 33.4-22.9 12-1.2-32.6zM1.4 268l19.2-10.2.4 38.2-21 8.8L1.4 268zm59.1 59.3l-28.3 8.3-1.6-46.8 25.1-10.7 4.8 49.2zM99 263.2l-31.1 13-5.2-40.8L90.1 221l8.9 42.2zM123.2 377l-41.6 5.9-8.1-63.5 35.2-10.8 14.5 68.4zm28.5-139.9l21.2 57.1-46.2 13.6-13.7-54.1 38.7-16.6zm85.7 230.5l-70.9-3.3-24.3-95.8 55.2-8.6 40 107.7zm-84.9-279.7l42.2-22.4 28 45.9-50.8 21.3-19.4-44.8zm41 94.9l61.3-18.7 52.8 86.6-79.8 11.3-34.3-79.2zm51.4-85.6l67.3-28.8 65.5 65.4-88.6 26.2-44.2-62.8z" } }, "free": ["brands"] }, "school": { "aliases": { "unicodes": { "composite": ["1f3eb"], "secondary": ["10f549"] } }, "changes": [ "5.0.13", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.1.0", "6.2.0", "6.2.1", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "building", "education", "learn", "school", "student", "teacher" ] }, "styles": ["solid"], "unicode": "f549", "label": "School", "voted": true, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M337.8 5.4C327-1.8 313-1.8 302.2 5.4L166.3 96H48C21.5 96 0 117.5 0 144V464c0 26.5 21.5 48 48 48H592c26.5 0 48-21.5 48-48V144c0-26.5-21.5-48-48-48H473.7L337.8 5.4zM256 416c0-35.3 28.7-64 64-64s64 28.7 64 64v96H256V416zM96 192h32c8.8 0 16 7.2 16 16v64c0 8.8-7.2 16-16 16H96c-8.8 0-16-7.2-16-16V208c0-8.8 7.2-16 16-16zm400 16c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v64c0 8.8-7.2 16-16 16H512c-8.8 0-16-7.2-16-16V208zM96 320h32c8.8 0 16 7.2 16 16v64c0 8.8-7.2 16-16 16H96c-8.8 0-16-7.2-16-16V336c0-8.8 7.2-16 16-16zm400 16c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v64c0 8.8-7.2 16-16 16H512c-8.8 0-16-7.2-16-16V336zM232 176a88 88 0 1 1 176 0 88 88 0 1 1 -176 0zm88-48c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16s-7.2-16-16-16H336V144c0-8.8-7.2-16-16-16z" } }, "free": ["solid"] }, "school-circle-check": { "changes": ["6.1.0", "6.2.0", "6.2.1", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["not affected", "ok", "okay", "schoolhouse"] }, "styles": ["solid"], "unicode": "e56b", "label": "School Circle Check", "voted": false, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M337.8 5.4C327-1.8 313-1.8 302.2 5.4L166.3 96H48C21.5 96 0 117.5 0 144V464c0 26.5 21.5 48 48 48H320v0H256V416c0-35.3 28.7-64 64-64l.3 0h.5c3.4-37.7 18.7-72.1 42.2-99.1C350.2 260 335.6 264 320 264c-48.6 0-88-39.4-88-88s39.4-88 88-88s88 39.4 88 88c0 18.3-5.6 35.3-15.1 49.4c29-21 64.6-33.4 103.1-33.4c59.5 0 112.1 29.6 144 74.8V144c0-26.5-21.5-48-48-48H473.7L337.8 5.4zM96 192h32c8.8 0 16 7.2 16 16v64c0 8.8-7.2 16-16 16H96c-8.8 0-16-7.2-16-16V208c0-8.8 7.2-16 16-16zm0 128h32c8.8 0 16 7.2 16 16v64c0 8.8-7.2 16-16 16H96c-8.8 0-16-7.2-16-16V336c0-8.8 7.2-16 16-16zM320 128c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16s-7.2-16-16-16H336V144c0-8.8-7.2-16-16-16zM640 368a144 144 0 1 0 -288 0 144 144 0 1 0 288 0zm-99.3-43.3c6.2-6.2 16.4-6.2 22.6 0s6.2 16.4 0 22.6l-72 72c-6.2 6.2-16.4 6.2-22.6 0l-40-40c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0L480 385.4l60.7-60.7z" } }, "free": ["solid"] }, "school-circle-exclamation": { "changes": ["6.1.0", "6.2.0", "6.2.1", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["affected", "schoolhouse"] }, "styles": ["solid"], "unicode": "e56c", "label": "School Circle Exclamation", "voted": false, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M337.8 5.4C327-1.8 313-1.8 302.2 5.4L166.3 96H48C21.5 96 0 117.5 0 144V464c0 26.5 21.5 48 48 48H320v0H256V416c0-35.3 28.7-64 64-64l.3 0h.5c3.4-37.7 18.7-72.1 42.2-99.1C350.2 260 335.6 264 320 264c-48.6 0-88-39.4-88-88s39.4-88 88-88s88 39.4 88 88c0 18.3-5.6 35.3-15.1 49.4c29-21 64.6-33.4 103.1-33.4c59.5 0 112.1 29.6 144 74.8V144c0-26.5-21.5-48-48-48H473.7L337.8 5.4zM96 192h32c8.8 0 16 7.2 16 16v64c0 8.8-7.2 16-16 16H96c-8.8 0-16-7.2-16-16V208c0-8.8 7.2-16 16-16zm0 128h32c8.8 0 16 7.2 16 16v64c0 8.8-7.2 16-16 16H96c-8.8 0-16-7.2-16-16V336c0-8.8 7.2-16 16-16zM320 128c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16s-7.2-16-16-16H336V144c0-8.8-7.2-16-16-16zM496 512a144 144 0 1 0 0-288 144 144 0 1 0 0 288zm0-96a24 24 0 1 1 0 48 24 24 0 1 1 0-48zm0-144c8.8 0 16 7.2 16 16v80c0 8.8-7.2 16-16 16s-16-7.2-16-16V288c0-8.8 7.2-16 16-16z" } }, "free": ["solid"] }, "school-circle-xmark": { "changes": ["6.1.0", "6.2.0", "6.2.1", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["destroy", "schoolhouse"] }, "styles": ["solid"], "unicode": "e56d", "label": "School Circle Xmark", "voted": false, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M337.8 5.4C327-1.8 313-1.8 302.2 5.4L166.3 96H48C21.5 96 0 117.5 0 144V464c0 26.5 21.5 48 48 48H320v0H256V416c0-35.3 28.7-64 64-64l.3 0h.5c3.4-37.7 18.7-72.1 42.2-99.1C350.2 260 335.6 264 320 264c-48.6 0-88-39.4-88-88s39.4-88 88-88s88 39.4 88 88c0 18.3-5.6 35.3-15.1 49.4c29-21 64.6-33.4 103.1-33.4c59.5 0 112.1 29.6 144 74.8V144c0-26.5-21.5-48-48-48H473.7L337.8 5.4zM96 192h32c8.8 0 16 7.2 16 16v64c0 8.8-7.2 16-16 16H96c-8.8 0-16-7.2-16-16V208c0-8.8 7.2-16 16-16zm0 128h32c8.8 0 16 7.2 16 16v64c0 8.8-7.2 16-16 16H96c-8.8 0-16-7.2-16-16V336c0-8.8 7.2-16 16-16zM320 128c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16s-7.2-16-16-16H336V144c0-8.8-7.2-16-16-16zM496 512a144 144 0 1 0 0-288 144 144 0 1 0 0 288zm22.6-144l36.7 36.7c6.2 6.2 6.2 16.4 0 22.6s-16.4 6.2-22.6 0L496 390.6l-36.7 36.7c-6.2 6.2-16.4 6.2-22.6 0s-6.2-16.4 0-22.6L473.4 368l-36.7-36.7c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0L496 345.4l36.7-36.7c6.2-6.2 16.4-6.2 22.6 0s6.2 16.4 0 22.6L518.6 368z" } }, "free": ["solid"] }, "school-flag": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["educate", "flag", "school", "schoolhouse"] }, "styles": ["solid"], "unicode": "e56e", "label": "School Flag", "voted": false, "svg": { "solid": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M288 0H400c8.8 0 16 7.2 16 16V80c0 8.8-7.2 16-16 16H320.7l89.6 64H512c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H336V400c0-26.5-21.5-48-48-48s-48 21.5-48 48V512H64c-35.3 0-64-28.7-64-64V224c0-35.3 28.7-64 64-64H165.7L256 95.5V32c0-17.7 14.3-32 32-32zm48 240a48 48 0 1 0 -96 0 48 48 0 1 0 96 0zM80 224c-8.8 0-16 7.2-16 16v64c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V240c0-8.8-7.2-16-16-16H80zm368 16v64c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V240c0-8.8-7.2-16-16-16H464c-8.8 0-16 7.2-16 16zM80 352c-8.8 0-16 7.2-16 16v64c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V368c0-8.8-7.2-16-16-16H80zm384 0c-8.8 0-16 7.2-16 16v64c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V368c0-8.8-7.2-16-16-16H464z" } }, "free": ["solid"] }, "school-lock": { "changes": ["6.1.0", "6.2.0", "6.2.1", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["closed", "lockdown", "quarantine", "schoolhouse"] }, "styles": ["solid"], "unicode": "e56f", "label": "School Lock", "voted": false, "svg": { "solid": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M302.2 5.4c10.7-7.2 24.8-7.2 35.5 0L473.7 96H592c26.5 0 48 21.5 48 48V272c0-61.9-50.1-112-112-112s-112 50.1-112 112v24.6c-19.1 11.1-32 31.7-32 55.4H320.3l-.3 0c-35.3 0-64 28.7-64 64v96h64v0H48c-26.5 0-48-21.5-48-48V144c0-26.5 21.5-48 48-48H166.3L302.2 5.4zM80 208v64c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V208c0-8.8-7.2-16-16-16H96c-8.8 0-16 7.2-16 16zm0 128v64c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V336c0-8.8-7.2-16-16-16H96c-8.8 0-16 7.2-16 16zm240-72a88 88 0 1 0 0-176 88 88 0 1 0 0 176zm16-120v16h16c8.8 0 16 7.2 16 16s-7.2 16-16 16H320c-8.8 0-16-7.2-16-16V144c0-8.8 7.2-16 16-16s16 7.2 16 16zm192 96c-17.7 0-32 14.3-32 32v48h64V272c0-17.7-14.3-32-32-32zm-80 32c0-44.2 35.8-80 80-80s80 35.8 80 80v48c17.7 0 32 14.3 32 32V480c0 17.7-14.3 32-32 32H448c-17.7 0-32-14.3-32-32V352c0-17.7 14.3-32 32-32V272z" } }, "free": ["solid"] }, "scissors": { "aliases": { "names": ["cut"], "unicodes": { "composite": ["2700", "2702", "2704"], "secondary": ["10f0c4"] } }, "changes": [ "2.0.0", "5.0.0", "5.1.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Black Safety Scissors", "White Scissors", "clip", "cutting", "scissors", "snip", "tool" ] }, "styles": ["solid"], "unicode": "f0c4", "label": "Scissors", "voted": false, "svg": { "solid": { "last_modified": 1684767368, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 192l-39.5-39.5c4.9-12.6 7.5-26.2 7.5-40.5C224 50.1 173.9 0 112 0S0 50.1 0 112s50.1 112 112 112c14.3 0 27.9-2.7 40.5-7.5L192 256l-39.5 39.5c-12.6-4.9-26.2-7.5-40.5-7.5C50.1 288 0 338.1 0 400s50.1 112 112 112s112-50.1 112-112c0-14.3-2.7-27.9-7.5-40.5L499.2 76.8c7.1-7.1 7.1-18.5 0-25.6c-28.3-28.3-74.1-28.3-102.4 0L256 192zm22.6 150.6L396.8 460.8c28.3 28.3 74.1 28.3 102.4 0c7.1-7.1 7.1-18.5 0-25.6L342.6 278.6l-64 64zM64 112a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zm48 240a48 48 0 1 1 0 96 48 48 0 1 1 0-96z" } }, "free": ["solid"] }, "screenpal": { "changes": ["6.1.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e570", "label": "Screenpal", "voted": false, "svg": { "brands": { "last_modified": 1660014465, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M233.5 22.49C233.5 10.07 243.6 0 256 0C268.4 0 278.5 10.07 278.5 22.49C278.5 34.91 268.4 44.98 256 44.98C243.6 44.98 233.5 34.91 233.5 22.49zM313.4 259C313.4 290.7 287.7 316.4 256 316.4C224.3 316.4 198.6 290.7 198.6 259C198.6 227.3 224.3 201.6 256 201.6C287.7 201.6 313.4 227.3 313.4 259zM337.2 350C359.5 330.1 373.7 302.7 377.1 273H496.6C493.1 334.4 466.2 392.2 421.4 434.4C376.7 476.6 317.5 500.2 256 500.2C194.5 500.2 135.3 476.6 90.56 434.4C45.83 392.2 18.94 334.4 15.39 273H135.1C138.5 302.7 152.7 330.1 175 350C197.3 369.9 226.2 380.9 256.1 380.9C285.1 380.9 314.8 369.9 337.2 350zM73.14 140.3C73.54 152.7 63.81 163.1 51.39 163.5C38.97 163.9 28.59 154.2 28.18 141.8C27.78 129.3 37.52 118.9 49.94 118.5C62.35 118.1 72.74 127.9 73.14 140.3zM438.9 141C438.9 128.6 448.9 118.5 461.4 118.5C473.8 118.5 483.8 128.6 483.8 141C483.8 153.5 473.8 163.5 461.4 163.5C448.9 163.5 438.9 153.5 438.9 141zM317.9 95.27C300.6 109.1 278.7 118.1 256 118.1C233.3 118.1 211.4 109.1 194.1 95.27C176.8 80.55 165.3 60.18 161.7 37.78C176.8 31.37 192.5 26.52 208.6 23.31C208.6 35.88 213.6 47.93 222.5 56.82C231.4 65.7 243.4 70.7 256 70.7C268.6 70.7 280.6 65.7 289.5 56.82C298.4 47.93 303.4 35.88 303.4 23.31C319.5 26.52 335.2 31.37 350.3 37.78C346.7 60.18 335.2 80.55 317.9 95.27H317.9zM82.78 231C61.42 238.6 38.06 238.4 16.86 230.4C18.82 214.1 22.46 198.1 27.71 182.5C33.1 185.6 39.05 187.6 45.22 188.5C51.39 189.3 57.67 188.9 63.68 187.3C69.69 185.6 75.33 182.9 80.27 179.1C85.21 175.3 89.36 170.6 92.47 165.2C95.58 159.8 97.61 153.8 98.42 147.7C99.23 141.5 98.83 135.2 97.22 129.2C95.61 123.2 92.83 117.6 89.04 112.6C85.25 107.7 80.53 103.5 75.14 100.4C85.96 88.11 98.01 76.94 111.1 67.07C128.7 81.42 140.6 101.6 144.7 123.9C148.8 146.2 144.8 169.3 133.5 188.9C122.1 208.5 104.1 223.4 82.78 231V231zM429.2 231.1C407.9 223.5 389.9 208.5 378.5 188.9C367.2 169.3 363.3 146.2 367.4 123.9C371.5 101.7 383.4 81.54 400.9 67.19C414 77.04 426.1 88.21 436.9 100.5C426.2 106.9 418.5 117.2 415.4 129.3C412.2 141.3 413.1 154.1 420.2 164.9C426.4 175.7 436.6 183.6 448.6 186.9C460.6 190.2 473.5 188.6 484.3 182.6C489.6 198.1 493.2 214.2 495.2 230.4C473.1 238.5 450.6 238.7 429.2 231.1L429.2 231.1z" } }, "free": ["brands"] }, "screwdriver": { "aliases": { "unicodes": { "composite": ["1fa9b"], "secondary": ["10f54a"] } }, "changes": ["5.0.13", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "admin", "fix", "mechanic", "repair", "screw", "screwdriver", "settings", "tool" ] }, "styles": ["solid"], "unicode": "f54a", "label": "Screwdriver", "voted": true, "svg": { "solid": { "last_modified": 1684767602, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M465 7c-8.5-8.5-22-9.4-31.6-2.1l-104 80c-5.9 4.5-9.4 11.6-9.4 19v54.1l-85.6 85.6c6.7 4.2 13 9.3 18.8 15.1s10.9 12.2 15.1 18.8L353.9 192H408c7.5 0 14.5-3.5 19-9.4l80-104c7.4-9.6 6.5-23.1-2.1-31.6L465 7zM121.4 281.4l-112 112c-12.5 12.5-12.5 32.8 0 45.3l64 64c12.5 12.5 32.8 12.5 45.3 0l112-112c30.2-30.2 30.2-79.1 0-109.3s-79.1-30.2-109.3 0z" } }, "free": ["solid"] }, "screwdriver-wrench": { "aliases": { "names": ["tools"], "unicodes": { "secondary": ["10f7d9"] } }, "changes": ["5.6.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "admin", "fix", "repair", "screwdriver", "settings", "tools", "wrench" ] }, "styles": ["solid"], "unicode": "f7d9", "label": "Screwdriver Wrench", "voted": true, "svg": { "solid": { "last_modified": 1684767602, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M78.6 5C69.1-2.4 55.6-1.5 47 7L7 47c-8.5 8.5-9.4 22-2.1 31.6l80 104c4.5 5.9 11.6 9.4 19 9.4h54.1l109 109c-14.7 29-10 65.4 14.3 89.6l112 112c12.5 12.5 32.8 12.5 45.3 0l64-64c12.5-12.5 12.5-32.8 0-45.3l-112-112c-24.2-24.2-60.6-29-89.6-14.3l-109-109V104c0-7.5-3.5-14.5-9.4-19L78.6 5zM19.9 396.1C7.2 408.8 0 426.1 0 444.1C0 481.6 30.4 512 67.9 512c18 0 35.3-7.2 48-19.9L233.7 374.3c-7.8-20.9-9-43.6-3.6-65.1l-61.7-61.7L19.9 396.1zM512 144c0-10.5-1.1-20.7-3.2-30.5c-2.4-11.2-16.1-14.1-24.2-6l-63.9 63.9c-3 3-7.1 4.7-11.3 4.7H352c-8.8 0-16-7.2-16-16V102.6c0-4.2 1.7-8.3 4.7-11.3l63.9-63.9c8.1-8.1 5.2-21.8-6-24.2C388.7 1.1 378.5 0 368 0C288.5 0 224 64.5 224 144l0 .8 85.3 85.3c36-9.1 75.8 .5 104 28.7L429 274.5c49-23 83-72.8 83-130.5zM56 432a24 24 0 1 1 48 0 24 24 0 1 1 -48 0z" } }, "free": ["solid"] }, "scribd": { "changes": ["4.5.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f28a", "label": "Scribd", "voted": false, "svg": { "brands": { "last_modified": 1660014477, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M42.3 252.7c-16.1-19-24.7-45.9-24.8-79.9 0-100.4 75.2-153.1 167.2-153.1 98.6-1.6 156.8 49 184.3 70.6l-50.5 72.1-37.3-24.6 26.9-38.6c-36.5-24-79.4-36.5-123-35.8-50.7-.8-111.7 27.2-111.7 76.2 0 18.7 11.2 20.7 28.6 15.6 23.3-5.3 41.9.6 55.8 14 26.4 24.3 23.2 67.6-.7 91.9-29.2 29.5-85.2 27.3-114.8-8.4zm317.7 5.9c-15.5-18.8-38.9-29.4-63.2-28.6-38.1-2-71.1 28-70.5 67.2-.7 16.8 6 33 18.4 44.3 14.1 13.9 33 19.7 56.3 14.4 17.4-5.1 28.6-3.1 28.6 15.6 0 4.3-.5 8.5-1.4 12.7-16.7 40.9-59.5 64.4-121.4 64.4-51.9.2-102.4-16.4-144.1-47.3l33.7-39.4-35.6-27.4L0 406.3l15.4 13.8c52.5 46.8 120.4 72.5 190.7 72.2 51.4 0 94.4-10.5 133.6-44.1 57.1-51.4 54.2-149.2 20.3-189.6z" } }, "free": ["brands"] }, "scroll": { "aliases": { "unicodes": { "composite": ["1f4dc"], "secondary": ["10f70e"] } }, "changes": ["5.4.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "Dungeons & Dragons", "announcement", "d&d", "dnd", "fantasy", "paper", "script", "scroll" ] }, "styles": ["solid"], "unicode": "f70e", "label": "Scroll", "voted": false, "svg": { "solid": { "last_modified": 1684767392, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M0 80v48c0 17.7 14.3 32 32 32H48 96V80c0-26.5-21.5-48-48-48S0 53.5 0 80zM112 32c10 13.4 16 30 16 48V384c0 35.3 28.7 64 64 64s64-28.7 64-64v-5.3c0-32.4 26.3-58.7 58.7-58.7H480V128c0-53-43-96-96-96H112zM464 480c61.9 0 112-50.1 112-112c0-8.8-7.2-16-16-16H314.7c-14.7 0-26.7 11.9-26.7 26.7V384c0 53-43 96-96 96H368h96z" } }, "free": ["solid"] }, "scroll-torah": { "aliases": { "names": ["torah"], "unicodes": { "secondary": ["10f6a0"] } }, "changes": [ "5.3.0", "5.7.0", "5.9.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["book", "jewish", "judaism", "religion", "scroll"] }, "styles": ["solid"], "unicode": "f6a0", "label": "Scroll Torah", "voted": false, "svg": { "solid": { "last_modified": 1684767393, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M96 480V32C96 14.3 74.5 0 48 0S0 14.3 0 32V480c0 17.7 21.5 32 48 32s48-14.3 48-32zM512 32H128V480H512V32zM592 0c-26.5 0-48 14.3-48 32V480c0 17.7 21.5 32 48 32s48-14.3 48-32V32c0-17.7-21.5-32-48-32zM196 313.7c0-3.2 .9-6.4 2.5-9.2L226.7 256l-28.3-48.5c-1.6-2.8-2.5-6-2.5-9.2c0-10.1 8.2-18.3 18.3-18.3H271l31.4-53.9c3.6-6.3 10.3-10.1 17.6-10.1s13.9 3.8 17.6 10.1L369 180h56.7c10.1 0 18.3 8.2 18.3 18.3c0 3.2-.9 6.4-2.5 9.2L413.3 256l28.3 48.5c1.6 2.8 2.5 6 2.5 9.2c0 10.1-8.2 18.3-18.3 18.3H369l-31.4 53.9c-3.6 6.3-10.3 10.1-17.6 10.1s-13.9-3.8-17.6-10.1L271 332H214.3c-10.1 0-18.3-8.2-18.3-18.3zm124 54.7L341.2 332H298.8L320 368.4zM254.5 256l30.3 52h70.4l30.3-52-30.3-52H284.8l-30.3 52zm144.9 23.8L383 308h32.8l-16.4-28.2zM415.8 204H383l16.4 28.2L415.8 204zM320 143.6L298.8 180h42.4L320 143.6zM224.2 204l16.4 28.2L257 204H224.2zM257 308l-16.4-28.2L224.2 308H257z" } }, "free": ["solid"] }, "sd-card": { "aliases": { "unicodes": { "secondary": ["10f7c2"] } }, "changes": ["5.6.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["image", "memory", "photo", "save"] }, "styles": ["solid"], "unicode": "f7c2", "label": "Sd Card", "voted": true, "svg": { "solid": { "last_modified": 1684767341, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M320 0H141.3C124.3 0 108 6.7 96 18.7L18.7 96C6.7 108 0 124.3 0 141.3V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V64c0-35.3-28.7-64-64-64zM160 88v48c0 13.3-10.7 24-24 24s-24-10.7-24-24V88c0-13.3 10.7-24 24-24s24 10.7 24 24zm80 0v48c0 13.3-10.7 24-24 24s-24-10.7-24-24V88c0-13.3 10.7-24 24-24s24 10.7 24 24zm80 0v48c0 13.3-10.7 24-24 24s-24-10.7-24-24V88c0-13.3 10.7-24 24-24s24 10.7 24 24z" } }, "free": ["solid"] }, "searchengin": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3eb", "label": "Searchengin", "voted": false, "svg": { "brands": { "last_modified": 1660014467, "raw": "", "viewBox": [0, 0, 460, 512], "width": 460, "height": 512, "path": "M220.6 130.3l-67.2 28.2V43.2L98.7 233.5l54.7-24.2v130.3l67.2-209.3zm-83.2-96.7l-1.3 4.7-15.2 52.9C80.6 106.7 52 145.8 52 191.5c0 52.3 34.3 95.9 83.4 105.5v53.6C57.5 340.1 0 272.4 0 191.6c0-80.5 59.8-147.2 137.4-158zm311.4 447.2c-11.2 11.2-23.1 12.3-28.6 10.5-5.4-1.8-27.1-19.9-60.4-44.4-33.3-24.6-33.6-35.7-43-56.7-9.4-20.9-30.4-42.6-57.5-52.4l-9.7-14.7c-24.7 16.9-53 26.9-81.3 28.7l2.1-6.6 15.9-49.5c46.5-11.9 80.9-54 80.9-104.2 0-54.5-38.4-102.1-96-107.1V32.3C254.4 37.4 320 106.8 320 191.6c0 33.6-11.2 64.7-29 90.4l14.6 9.6c9.8 27.1 31.5 48 52.4 57.4s32.2 9.7 56.8 43c24.6 33.2 42.7 54.9 44.5 60.3s.7 17.3-10.5 28.5zm-9.9-17.9c0-4.4-3.6-8-8-8s-8 3.6-8 8 3.6 8 8 8 8-3.6 8-8z" } }, "free": ["brands"] }, "section": { "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Section Sign", "law", "legal", "silcrow"] }, "styles": ["solid"], "unicode": "e447", "label": "Section", "voted": true, "svg": { "solid": { "last_modified": 1684767245, "raw": "", "viewBox": [0, 0, 256, 512], "width": 256, "height": 512, "path": "M64.9 96C67.1 84.4 73.7 76.2 86 70.6c13.8-6.2 34.8-8.9 61.2-4.5c8.8 1.4 36.1 7.1 44.1 9.3c17 4.8 34.7-5.1 39.5-22.2s-5.1-34.7-22.2-39.5c-11.1-3.1-41-9.2-50.9-10.8C123-2.7 88.3-.6 59.7 12.3C29.9 25.8 7.5 50.9 1.6 86.5c-.1 .5-.2 1.1-.2 1.6c-2.2 19.7 .3 37.9 8.1 54.1c7.7 16.1 19.4 28 32 36.9c.6 .5 1.3 .9 2 1.4C22.3 194.2 6.5 215.1 1.7 243c-.1 .6-.2 1.1-.2 1.7c-2.3 19.3 .4 37.1 8.4 53c7.9 15.6 19.8 27 32.3 35.5c22.4 15.2 51.9 24 75.4 31l0 0 3.7 1.1c27.2 8.2 46.9 14.6 59.4 23.8c5.5 4 8.2 7.6 9.5 10.9c1.3 3.2 2.6 8.6 .9 18.1c-1.7 10.1-7.7 18-20.7 23.5c-14 6-35.4 8.5-62 4.4c-12.8-2.1-35.1-9.7-54.1-16.2l0 0c-4.3-1.5-8.5-2.9-12.3-4.2C25.3 420 7.2 429.1 1.6 445.8s3.5 34.9 20.3 40.5c2.6 .8 5.7 1.9 9.2 3.1c18.6 6.3 48.5 16.6 67.3 19.6l0 0 .2 0c34.5 5.4 68.8 3.4 97.2-8.7c29.4-12.6 52.5-36.5 58.5-71.5c3.3-19.3 1.9-37.4-5-53.9c-6.3-15-16.4-26.4-27.6-35.2c16.5-13.9 28.5-33.2 32.6-58.2c3.2-19.8 1.9-38.3-4.8-55.1c-6.7-16.8-17.8-29.4-30.2-39c-22.8-17.6-53.6-27.4-77.7-35l-1.4-.5c-27.4-8.7-47.8-15.3-61.5-25c-6.1-4.4-9.5-8.5-11.4-12.4c-1.8-3.7-3.2-9.3-2.3-18.5zm76.7 208.5c-.2-.1-.4-.1-.6-.2l-1.4-.4c-27.4-8.2-47.9-14.5-61.7-23.8c-6.2-4.2-9.3-7.9-11-11.3c-1.5-3-2.9-7.7-2.1-15.7c1.9-9.7 7.9-17.3 20.5-22.7c14-6 35.4-8.5 62.1-4.3l16.4 2.6c6.3 2.9 11.7 6 16.2 9.5c5.5 4.2 8.4 8.2 10 12.2c1.6 4 2.8 10.4 1.1 20.9c-2.4 14.7-12.8 26.4-37.1 31l-12.4 2.3z" } }, "free": ["solid"] }, "seedling": { "aliases": { "names": ["sprout"], "unicodes": { "composite": ["1f331"], "secondary": ["10f4d8"] } }, "changes": ["5.0.9", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "environment", "flora", "grow", "plant", "sapling", "seedling", "vegan", "young" ] }, "styles": ["solid"], "unicode": "f4d8", "label": "Seedling", "voted": false, "svg": { "solid": { "last_modified": 1684768130, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M512 32c0 113.6-84.6 207.5-194.2 222c-7.1-53.4-30.6-101.6-65.3-139.3C290.8 46.3 364 0 448 0h32c17.7 0 32 14.3 32 32zM0 96C0 78.3 14.3 64 32 64H64c123.7 0 224 100.3 224 224v32V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V320C100.3 320 0 219.7 0 96z" } }, "free": ["solid"] }, "sellcast": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": ["eercast"] }, "styles": ["brands"], "unicode": "f2da", "label": "Sellcast", "voted": false, "svg": { "brands": { "last_modified": 1660014477, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M353.4 32H94.7C42.6 32 0 74.6 0 126.6v258.7C0 437.4 42.6 480 94.7 480h258.7c52.1 0 94.7-42.6 94.7-94.6V126.6c0-52-42.6-94.6-94.7-94.6zm-50 316.4c-27.9 48.2-89.9 64.9-138.2 37.2-22.9 39.8-54.9 8.6-42.3-13.2l15.7-27.2c5.9-10.3 19.2-13.9 29.5-7.9 18.6 10.8-.1-.1 18.5 10.7 27.6 15.9 63.4 6.3 79.4-21.3 15.9-27.6 6.3-63.4-21.3-79.4-17.8-10.2-.6-.4-18.6-10.6-24.6-14.2-3.4-51.9 21.6-37.5 18.6 10.8-.1-.1 18.5 10.7 48.4 28 65.1 90.3 37.2 138.5zm21.8-208.8c-17 29.5-16.3 28.8-19 31.5-6.5 6.5-16.3 8.7-26.5 3.6-18.6-10.8.1.1-18.5-10.7-27.6-15.9-63.4-6.3-79.4 21.3s-6.3 63.4 21.3 79.4c0 0 18.5 10.6 18.6 10.6 24.6 14.2 3.4 51.9-21.6 37.5-18.6-10.8.1.1-18.5-10.7-48.2-27.8-64.9-90.1-37.1-138.4 27.9-48.2 89.9-64.9 138.2-37.2l4.8-8.4c14.3-24.9 52-3.3 37.7 21.5z" } }, "free": ["brands"] }, "sellsy": { "changes": ["4.3.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f213", "label": "Sellsy", "voted": false, "svg": { "brands": { "last_modified": 1660014464, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M539.71 237.308c3.064-12.257 4.29-24.821 4.29-37.384C544 107.382 468.618 32 376.076 32c-77.22 0-144.634 53.012-163.02 127.781-15.322-13.176-34.934-20.53-55.157-20.53-46.271 0-83.962 37.69-83.962 83.961 0 7.354.92 15.015 3.065 22.369-42.9 20.225-70.785 63.738-70.785 111.234C6.216 424.843 61.68 480 129.401 480h381.198c67.72 0 123.184-55.157 123.184-123.184.001-56.384-38.916-106.025-94.073-119.508zM199.88 401.554c0 8.274-7.048 15.321-15.321 15.321H153.61c-8.274 0-15.321-7.048-15.321-15.321V290.626c0-8.273 7.048-15.321 15.321-15.321h30.949c8.274 0 15.321 7.048 15.321 15.321v110.928zm89.477 0c0 8.274-7.048 15.321-15.322 15.321h-30.949c-8.274 0-15.321-7.048-15.321-15.321V270.096c0-8.274 7.048-15.321 15.321-15.321h30.949c8.274 0 15.322 7.048 15.322 15.321v131.458zm89.477 0c0 8.274-7.047 15.321-15.321 15.321h-30.949c-8.274 0-15.322-7.048-15.322-15.321V238.84c0-8.274 7.048-15.321 15.322-15.321h30.949c8.274 0 15.321 7.048 15.321 15.321v162.714zm87.027 0c0 8.274-7.048 15.321-15.322 15.321h-28.497c-8.274 0-15.321-7.048-15.321-15.321V176.941c0-8.579 7.047-15.628 15.321-15.628h28.497c8.274 0 15.322 7.048 15.322 15.628v224.613z" } }, "free": ["brands"] }, "server": { "aliases": { "unicodes": { "secondary": ["10f233"] } }, "changes": ["4.3.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["computer", "cpu", "database", "hardware", "network"] }, "styles": ["solid"], "unicode": "f233", "label": "Server", "voted": false, "svg": { "solid": { "last_modified": 1684767343, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M64 32C28.7 32 0 60.7 0 96v64c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zm280 72a24 24 0 1 1 0 48 24 24 0 1 1 0-48zm48 24a24 24 0 1 1 48 0 24 24 0 1 1 -48 0zM64 288c-35.3 0-64 28.7-64 64v64c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V352c0-35.3-28.7-64-64-64H64zm280 72a24 24 0 1 1 0 48 24 24 0 1 1 0-48zm56 24a24 24 0 1 1 48 0 24 24 0 1 1 -48 0z" } }, "free": ["solid"] }, "servicestack": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3ec", "label": "Servicestack", "voted": false, "svg": { "brands": { "last_modified": 1660014465, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M88 216c81.7 10.2 273.7 102.3 304 232H0c99.5-8.1 184.5-137 88-232zm32-152c32.3 35.6 47.7 83.9 46.4 133.6C249.3 231.3 373.7 321.3 400 448h96C455.3 231.9 222.8 79.5 120 64z" } }, "free": ["brands"] }, "shapes": { "aliases": { "names": ["triangle-circle-square"], "unicodes": { "secondary": ["10f61f"] } }, "changes": [ "5.2.0", "5.12.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["blocks", "build", "circle", "square", "triangle"] }, "styles": ["solid"], "unicode": "f61f", "label": "Shapes", "voted": false, "svg": { "solid": { "last_modified": 1684767368, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M315.4 15.5C309.7 5.9 299.2 0 288 0s-21.7 5.9-27.4 15.5l-96 160c-5.9 9.9-6.1 22.2-.4 32.2s16.3 16.2 27.8 16.2H384c11.5 0 22.2-6.2 27.8-16.2s5.5-22.3-.4-32.2l-96-160zM288 312V456c0 22.1 17.9 40 40 40H472c22.1 0 40-17.9 40-40V312c0-22.1-17.9-40-40-40H328c-22.1 0-40 17.9-40 40zM128 512a128 128 0 1 0 0-256 128 128 0 1 0 0 256z" } }, "free": ["solid"] }, "share": { "aliases": { "names": ["arrow-turn-right", "mail-forward"], "unicodes": { "secondary": ["10f064"] } }, "changes": [ "1.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.2.1", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["forward", "save", "send", "social"] }, "styles": ["solid"], "unicode": "f064", "label": "Share", "voted": false, "svg": { "solid": { "last_modified": 1684766328, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M307 34.8c-11.5 5.1-19 16.6-19 29.2v64H176C78.8 128 0 206.8 0 304C0 417.3 81.5 467.9 100.2 478.1c2.5 1.4 5.3 1.9 8.1 1.9c10.9 0 19.7-8.9 19.7-19.7c0-7.5-4.3-14.4-9.8-19.5C108.8 431.9 96 414.4 96 384c0-53 43-96 96-96h96v64c0 12.6 7.4 24.1 19 29.2s25 3 34.4-5.4l160-144c6.7-6.1 10.6-14.7 10.6-23.8s-3.8-17.7-10.6-23.8l-160-144c-9.4-8.5-22.9-10.6-34.4-5.4z" } }, "free": ["solid"] }, "share-from-square": { "aliases": { "names": ["share-square"], "unicodes": { "composite": ["f045"], "secondary": ["10f14d"] } }, "changes": [ "3.1.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.2.1", "6.3.0", "6.4.0", "6.4.1" ], "ligatures": [], "search": { "terms": ["forward", "save", "send", "social"] }, "styles": ["solid", "regular"], "unicode": "f14d", "label": "Share From Square", "voted": false, "svg": { "solid": { "last_modified": 1684766329, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M352 224H305.5c-45 0-81.5 36.5-81.5 81.5c0 22.3 10.3 34.3 19.2 40.5c6.8 4.7 12.8 12 12.8 20.3c0 9.8-8 17.8-17.8 17.8h-2.5c-2.4 0-4.8-.4-7.1-1.4C210.8 374.8 128 333.4 128 240c0-79.5 64.5-144 144-144h80V34.7C352 15.5 367.5 0 386.7 0c8.6 0 16.8 3.2 23.2 8.9L548.1 133.3c7.6 6.8 11.9 16.5 11.9 26.7s-4.3 19.9-11.9 26.7l-139 125.1c-5.9 5.3-13.5 8.2-21.4 8.2H384c-17.7 0-32-14.3-32-32V224zM80 96c-8.8 0-16 7.2-16 16V432c0 8.8 7.2 16 16 16H400c8.8 0 16-7.2 16-16V384c0-17.7 14.3-32 32-32s32 14.3 32 32v48c0 44.2-35.8 80-80 80H80c-44.2 0-80-35.8-80-80V112C0 67.8 35.8 32 80 32h48c17.7 0 32 14.3 32 32s-14.3 32-32 32H80z" }, "regular": { "last_modified": 1684766329, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M400 255.4V240 208c0-8.8-7.2-16-16-16H352 336 289.5c-50.9 0-93.9 33.5-108.3 79.6c-3.3-9.4-5.2-19.8-5.2-31.6c0-61.9 50.1-112 112-112h48 16 32c8.8 0 16-7.2 16-16V80 64.6L506 160 400 255.4zM336 240h16v48c0 17.7 14.3 32 32 32h3.7c7.9 0 15.5-2.9 21.4-8.2l139-125.1c7.6-6.8 11.9-16.5 11.9-26.7s-4.3-19.9-11.9-26.7L409.9 8.9C403.5 3.2 395.3 0 386.7 0C367.5 0 352 15.5 352 34.7V80H336 304 288c-88.4 0-160 71.6-160 160c0 60.4 34.6 99.1 63.9 120.9c5.9 4.4 11.5 8.1 16.7 11.2c4.4 2.7 8.5 4.9 11.9 6.6c3.4 1.7 6.2 3 8.2 3.9c2.2 1 4.6 1.4 7.1 1.4h2.5c9.8 0 17.8-8 17.8-17.8c0-7.8-5.3-14.7-11.6-19.5l0 0c-.4-.3-.7-.5-1.1-.8c-1.7-1.1-3.4-2.5-5-4.1c-.8-.8-1.7-1.6-2.5-2.6s-1.6-1.9-2.4-2.9c-1.8-2.5-3.5-5.3-5-8.5c-2.6-6-4.3-13.3-4.3-22.4c0-36.1 29.3-65.5 65.5-65.5H304h32zM72 32C32.2 32 0 64.2 0 104V440c0 39.8 32.2 72 72 72H408c39.8 0 72-32.2 72-72V376c0-13.3-10.7-24-24-24s-24 10.7-24 24v64c0 13.3-10.7 24-24 24H72c-13.3 0-24-10.7-24-24V104c0-13.3 10.7-24 24-24h64c13.3 0 24-10.7 24-24s-10.7-24-24-24H72z" } }, "free": ["regular", "solid"] }, "share-nodes": { "aliases": { "names": ["share-alt"], "unicodes": { "secondary": ["10f1e0"] } }, "changes": [ "4.1.0", "5.0.0", "6.0.0-beta1", "6.0.0", "6.1.2", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["forward", "save", "send", "social"] }, "styles": ["solid"], "unicode": "f1e0", "label": "Share Nodes", "voted": false, "svg": { "solid": { "last_modified": 1684767553, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M352 224c53 0 96-43 96-96s-43-96-96-96s-96 43-96 96c0 4 .2 8 .7 11.9l-94.1 47C145.4 170.2 121.9 160 96 160c-53 0-96 43-96 96s43 96 96 96c25.9 0 49.4-10.2 66.6-26.9l94.1 47c-.5 3.9-.7 7.8-.7 11.9c0 53 43 96 96 96s96-43 96-96s-43-96-96-96c-25.9 0-49.4 10.2-66.6 26.9l-94.1-47c.5-3.9 .7-7.8 .7-11.9s-.2-8-.7-11.9l94.1-47C302.6 213.8 326.1 224 352 224z" } }, "free": ["solid"] }, "sheet-plastic": { "changes": ["6.1.0", "6.1.2", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "plastic", "plastic wrap", "protect", "tarp", "tarpaulin", "waterproof" ] }, "styles": ["solid"], "unicode": "e571", "label": "Sheet Plastic", "voted": false, "svg": { "solid": { "last_modified": 1684767444, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M0 448c0 35.3 28.7 64 64 64H224V384c0-17.7 14.3-32 32-32H384V64c0-35.3-28.7-64-64-64H64C28.7 0 0 28.7 0 64V448zM171.3 75.3l-96 96c-6.2 6.2-16.4 6.2-22.6 0s-6.2-16.4 0-22.6l96-96c6.2-6.2 16.4-6.2 22.6 0s6.2 16.4 0 22.6zm96 32l-160 160c-6.2 6.2-16.4 6.2-22.6 0s-6.2-16.4 0-22.6l160-160c6.2-6.2 16.4-6.2 22.6 0s6.2 16.4 0 22.6zM384 384H256V512L384 384z" } }, "free": ["solid"] }, "shekel-sign": { "aliases": { "names": ["ils", "shekel", "sheqel", "sheqel-sign"], "unicodes": { "composite": ["20aa"], "secondary": ["10f20b"] } }, "changes": [ "4.2.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["New Sheqel Sign", "currency", "ils", "money"] }, "styles": ["solid"], "unicode": "f20b", "label": "Shekel Sign", "voted": true, "svg": { "solid": { "last_modified": 1684766474, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M32 32C14.3 32 0 46.3 0 64V448c0 17.7 14.3 32 32 32s32-14.3 32-32V96H192c35.3 0 64 28.7 64 64V320c0 17.7 14.3 32 32 32s32-14.3 32-32V160c0-70.7-57.3-128-128-128H32zM320 480c70.7 0 128-57.3 128-128V64c0-17.7-14.3-32-32-32s-32 14.3-32 32V352c0 35.3-28.7 64-64 64H192V192c0-17.7-14.3-32-32-32s-32 14.3-32 32V448c0 17.7 14.3 32 32 32H320z" } }, "free": ["solid"] }, "shield": { "aliases": { "names": ["shield-blank"], "unicodes": { "composite": ["1f6e1"], "secondary": ["10f132"] } }, "changes": [ "3.1.0", "5.0.0", "5.10.2", "6.0.0-beta1", "6.1.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "achievement", "armor", "award", "block", "cleric", "defend", "defense", "holy", "paladin", "protect", "safety", "security", "shield", "weapon", "winner" ] }, "styles": ["solid"], "unicode": "f132", "label": "Shield", "voted": false, "svg": { "solid": { "last_modified": 1684767601, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 0c4.6 0 9.2 1 13.4 2.9L457.7 82.8c22 9.3 38.4 31 38.3 57.2c-.5 99.2-41.3 280.7-213.6 363.2c-16.7 8-36.1 8-52.8 0C57.3 420.7 16.5 239.2 16 140c-.1-26.2 16.3-47.9 38.3-57.2L242.7 2.9C246.8 1 251.4 0 256 0z" } }, "free": ["solid"] }, "shield-cat": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["animal", "feline", "pet", "protect", "safety", "veterinary"] }, "styles": ["solid"], "unicode": "e572", "label": "Shield Cat", "voted": false, "svg": { "solid": { "last_modified": 1684767602, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M269.4 2.9C265.2 1 260.7 0 256 0s-9.2 1-13.4 2.9L54.3 82.8c-22 9.3-38.4 31-38.3 57.2c.5 99.2 41.3 280.7 213.6 363.2c16.7 8 36.1 8 52.8 0C454.7 420.7 495.5 239.2 496 140c.1-26.2-16.3-47.9-38.3-57.2L269.4 2.9zM160 154.4c0-5.8 4.7-10.4 10.4-10.4h.2c3.4 0 6.5 1.6 8.5 4.3l40 53.3c3 4 7.8 6.4 12.8 6.4h48c5 0 9.8-2.4 12.8-6.4l40-53.3c2-2.7 5.2-4.3 8.5-4.3h.2c5.8 0 10.4 4.7 10.4 10.4V272c0 53-43 96-96 96s-96-43-96-96V154.4zM216 288a16 16 0 1 0 0-32 16 16 0 1 0 0 32zm96-16a16 16 0 1 0 -32 0 16 16 0 1 0 32 0z" } }, "free": ["solid"] }, "shield-dog": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["animal", "canine", "pet", "protect", "safety", "veterinary"] }, "styles": ["solid"], "unicode": "e573", "label": "Shield Dog", "voted": false, "svg": { "solid": { "last_modified": 1684767602, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M269.4 2.9C265.2 1 260.7 0 256 0s-9.2 1-13.4 2.9L54.3 82.8c-22 9.3-38.4 31-38.3 57.2c.5 99.2 41.3 280.7 213.6 363.2c16.7 8 36.1 8 52.8 0C454.7 420.7 495.5 239.2 496 140c.1-26.2-16.3-47.9-38.3-57.2L269.4 2.9zM160.9 286.2c4.8 1.2 9.9 1.8 15.1 1.8c35.3 0 64-28.7 64-64V160h44.2c12.1 0 23.2 6.8 28.6 17.7L320 192h64c8.8 0 16 7.2 16 16v32c0 44.2-35.8 80-80 80H272v50.7c0 7.3-5.9 13.3-13.3 13.3c-1.8 0-3.6-.4-5.2-1.1l-98.7-42.3c-6.6-2.8-10.8-9.3-10.8-16.4c0-2.8 .6-5.5 1.9-8l15-30zM160 160h40 8v32 32c0 17.7-14.3 32-32 32s-32-14.3-32-32V176c0-8.8 7.2-16 16-16zm128 48a16 16 0 1 0 -32 0 16 16 0 1 0 32 0z" } }, "free": ["solid"] }, "shield-halved": { "aliases": { "names": ["shield-alt"], "unicodes": { "secondary": ["10f3ed"] } }, "changes": ["5.0.0", "6.0.0-beta1", "6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "achievement", "armor", "award", "block", "cleric", "defend", "defense", "holy", "paladin", "security", "shield", "weapon", "winner" ] }, "styles": ["solid"], "unicode": "f3ed", "label": "Shield Halved", "voted": false, "svg": { "solid": { "last_modified": 1684767602, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 0c4.6 0 9.2 1 13.4 2.9L457.7 82.8c22 9.3 38.4 31 38.3 57.2c-.5 99.2-41.3 280.7-213.6 363.2c-16.7 8-36.1 8-52.8 0C57.3 420.7 16.5 239.2 16 140c-.1-26.2 16.3-47.9 38.3-57.2L242.7 2.9C246.8 1 251.4 0 256 0zm0 66.8V444.8C394 378 431.1 230.1 432 141.4L256 66.8l0 0z" } }, "free": ["solid"] }, "shield-heart": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["love", "protect", "safe", "safety", "shield"] }, "styles": ["solid"], "unicode": "e574", "label": "Shield Heart", "voted": false, "svg": { "solid": { "last_modified": 1684767601, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M269.4 2.9C265.2 1 260.7 0 256 0s-9.2 1-13.4 2.9L54.3 82.8c-22 9.3-38.4 31-38.3 57.2c.5 99.2 41.3 280.7 213.6 363.2c16.7 8 36.1 8 52.8 0C454.7 420.7 495.5 239.2 496 140c.1-26.2-16.3-47.9-38.3-57.2L269.4 2.9zM144 221.3c0-33.8 27.4-61.3 61.3-61.3c16.2 0 31.8 6.5 43.3 17.9l7.4 7.4 7.4-7.4c11.5-11.5 27.1-17.9 43.3-17.9c33.8 0 61.3 27.4 61.3 61.3c0 16.2-6.5 31.8-17.9 43.3l-82.7 82.7c-6.2 6.2-16.4 6.2-22.6 0l-82.7-82.7c-11.5-11.5-17.9-27.1-17.9-43.3z" } }, "free": ["solid"] }, "shield-virus": { "aliases": { "unicodes": { "secondary": ["10e06c"] } }, "changes": ["5.13.0", "5.14.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "antibodies", "barrier", "coronavirus", "covid-19", "flu", "health", "infection", "pandemic", "protect", "safety", "vaccine" ] }, "styles": ["solid"], "unicode": "e06c", "label": "Shield Virus", "voted": false, "svg": { "solid": { "last_modified": 1684767602, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M269.4 2.9C265.2 1 260.7 0 256 0s-9.2 1-13.4 2.9L54.3 82.8c-22 9.3-38.4 31-38.3 57.2c.5 99.2 41.3 280.7 213.6 363.2c16.7 8 36.1 8 52.8 0C454.7 420.7 495.5 239.2 496 140c.1-26.2-16.3-47.9-38.3-57.2L269.4 2.9zM256 112c8.8 0 16 7.2 16 16c0 33 39.9 49.5 63.2 26.2c6.2-6.2 16.4-6.2 22.6 0s6.2 16.4 0 22.6C334.5 200.1 351 240 384 240c8.8 0 16 7.2 16 16s-7.2 16-16 16c-33 0-49.5 39.9-26.2 63.2c6.2 6.2 6.2 16.4 0 22.6s-16.4 6.2-22.6 0C311.9 334.5 272 351 272 384c0 8.8-7.2 16-16 16s-16-7.2-16-16c0-33-39.9-49.5-63.2-26.2c-6.2 6.2-16.4 6.2-22.6 0s-6.2-16.4 0-22.6C177.5 311.9 161 272 128 272c-8.8 0-16-7.2-16-16s7.2-16 16-16c33 0 49.5-39.9 26.2-63.2c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0C200.1 177.5 240 161 240 128c0-8.8 7.2-16 16-16zM232 256a24 24 0 1 0 0-48 24 24 0 1 0 0 48zm72 32a16 16 0 1 0 -32 0 16 16 0 1 0 32 0z" } }, "free": ["solid"] }, "ship": { "aliases": { "unicodes": { "composite": ["1f6a2"], "secondary": ["10f21a"] } }, "changes": [ "4.3.0", "5.0.0", "5.10.2", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["boat", "passenger", "sea", "ship", "water"] }, "styles": ["solid"], "unicode": "f21a", "label": "Ship", "voted": false, "svg": { "solid": { "last_modified": 1684767637, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M192 32c0-17.7 14.3-32 32-32H352c17.7 0 32 14.3 32 32V64h48c26.5 0 48 21.5 48 48V240l44.4 14.8c23.1 7.7 29.5 37.5 11.5 53.9l-101 92.6c-16.2 9.4-34.7 15.1-50.9 15.1c-19.6 0-40.8-7.7-59.2-20.3c-22.1-15.5-51.6-15.5-73.7 0c-17.1 11.8-38 20.3-59.2 20.3c-16.2 0-34.7-5.7-50.9-15.1l-101-92.6c-18-16.5-11.6-46.2 11.5-53.9L96 240V112c0-26.5 21.5-48 48-48h48V32zM160 218.7l107.8-35.9c13.1-4.4 27.3-4.4 40.5 0L416 218.7V128H160v90.7zM306.5 421.9C329 437.4 356.5 448 384 448c26.9 0 55.4-10.8 77.4-26.1l0 0c11.9-8.5 28.1-7.8 39.2 1.7c14.4 11.9 32.5 21 50.6 25.2c17.2 4 27.9 21.2 23.9 38.4s-21.2 27.9-38.4 23.9c-24.5-5.7-44.9-16.5-58.2-25C449.5 501.7 417 512 384 512c-31.9 0-60.6-9.9-80.4-18.9c-5.8-2.7-11.1-5.3-15.6-7.7c-4.5 2.4-9.7 5.1-15.6 7.7c-19.8 9-48.5 18.9-80.4 18.9c-33 0-65.5-10.3-94.5-25.8c-13.4 8.4-33.7 19.3-58.2 25c-17.2 4-34.4-6.7-38.4-23.9s6.7-34.4 23.9-38.4c18.1-4.2 36.2-13.3 50.6-25.2c11.1-9.4 27.3-10.1 39.2-1.7l0 0C136.7 437.2 165.1 448 192 448c27.5 0 55-10.6 77.5-26.1c11.1-7.9 25.9-7.9 37 0z" } }, "free": ["solid"] }, "shirt": { "aliases": { "names": ["t-shirt", "tshirt"], "unicodes": { "composite": ["1f455"], "secondary": ["10f553"] } }, "changes": [ "5.0.13", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0", "6.4.1" ], "ligatures": [], "search": { "terms": [ "clothing", "fashion", "garment", "shirt", "short sleeve", "t-shirt", "tshirt" ] }, "styles": ["solid"], "unicode": "f553", "label": "Shirt", "voted": true, "svg": { "solid": { "last_modified": 1684767070, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M211.8 0c7.8 0 14.3 5.7 16.7 13.2C240.8 51.9 277.1 80 320 80s79.2-28.1 91.5-66.8C413.9 5.7 420.4 0 428.2 0h12.6c22.5 0 44.2 7.9 61.5 22.3L628.5 127.4c6.6 5.5 10.7 13.5 11.4 22.1s-2.1 17.1-7.8 23.6l-56 64c-11.4 13.1-31.2 14.6-44.6 3.5L480 197.7V448c0 35.3-28.7 64-64 64H224c-35.3 0-64-28.7-64-64V197.7l-51.5 42.9c-13.3 11.1-33.1 9.6-44.6-3.5l-56-64c-5.7-6.5-8.5-15-7.8-23.6s4.8-16.6 11.4-22.1L137.7 22.3C155 7.9 176.7 0 199.2 0h12.6z" } }, "free": ["solid"] }, "shirtsinbulk": { "changes": ["4.3.0", "5.0.0", "5.7.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f214", "label": "Shirts in Bulk", "voted": false, "svg": { "brands": { "last_modified": 1660014478, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M100 410.3l30.6 13.4 4.4-9.9-30.6-13.4zm39.4 17.5l30.6 13.4 4.4-9.9-30.6-13.4zm172.1-14l4.4 9.9 30.6-13.4-4.4-9.9zM179.1 445l30.3 13.7 4.4-9.9-30.3-13.4zM60.4 392.8L91 406.2l4.4-9.6-30.6-13.7zm211.4 38.5l4.4 9.9 30.6-13.4-4.4-9.9zm-39.3 17.5l4.4 9.9 30.6-13.7-4.4-9.6zm118.4-52.2l4.4 9.6 30.6-13.4-4.4-9.9zM170 46.6h-33.5v10.5H170zm-47.2 0H89.2v10.5h33.5zm-47.3 0H42.3v10.5h33.3zm141.5 0h-33.2v10.5H217zm94.5 0H278v10.5h33.5zm47.3 0h-33.5v10.5h33.5zm-94.6 0H231v10.5h33.2zm141.5 0h-33.3v10.5h33.3zM52.8 351.1H42v33.5h10.8zm70-215.9H89.2v10.5h33.5zm-70 10.6h22.8v-10.5H42v33.5h10.8zm168.9 228.6c50.5 0 91.3-40.8 91.3-91.3 0-50.2-40.8-91.3-91.3-91.3-50.2 0-91.3 41.1-91.3 91.3 0 50.5 41.1 91.3 91.3 91.3zm-48.2-111.1c0-25.4 29.5-31.8 49.6-31.8 16.9 0 29.2 5.8 44.3 12l-8.8 16.9h-.9c-6.4-9.9-24.8-13.1-35.6-13.1-9 0-29.8 1.8-29.8 14.9 0 21.6 78.5-10.2 78.5 37.9 0 25.4-31.5 31.2-51 31.2-18.1 0-32.4-2.9-47.2-12.2l9-18.4h.9c6.1 12.2 23.6 14.9 35.9 14.9 8.7 0 32.7-1.2 32.7-14.3 0-26.1-77.6 6.3-77.6-38zM52.8 178.4H42V212h10.8zm342.4 206.2H406v-33.5h-10.8zM52.8 307.9H42v33.5h10.8zM0 3.7v406l221.7 98.6L448 409.7V3.7zm418.8 387.1L222 476.5 29.2 390.8V120.7h389.7v270.1zm0-299.3H29.2V32.9h389.7v58.6zm-366 130.1H42v33.5h10.8zm0 43.2H42v33.5h10.8zM170 135.2h-33.5v10.5H170zm225.2 163.1H406v-33.5h-10.8zm0-43.2H406v-33.5h-10.8zM217 135.2h-33.2v10.5H217zM395.2 212H406v-33.5h-10.8zm0 129.5H406V308h-10.8zm-131-206.3H231v10.5h33.2zm47.3 0H278v10.5h33.5zm83.7 33.6H406v-33.5h-33.5v10.5h22.8zm-36.4-33.6h-33.5v10.5h33.5z" } }, "free": ["brands"] }, "shoe-prints": { "aliases": { "unicodes": { "secondary": ["10f54b"] } }, "changes": ["5.0.13", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["feet", "footprints", "steps", "walk"] }, "styles": ["solid"], "unicode": "f54b", "label": "Shoe Prints", "voted": true, "svg": { "solid": { "last_modified": 1684767601, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M416 0C352.3 0 256 32 256 32V160c48 0 76 16 104 32s56 32 104 32c56.4 0 176-16 176-96S512 0 416 0zM128 96c0 35.3 28.7 64 64 64h32V32H192c-35.3 0-64 28.7-64 64zM288 512c96 0 224-48 224-128s-119.6-96-176-96c-48 0-76 16-104 32s-56 32-104 32V480s96.3 32 160 32zM0 416c0 35.3 28.7 64 64 64H96V352H64c-35.3 0-64 28.7-64 64z" } }, "free": ["solid"] }, "shop": { "aliases": { "names": ["store-alt"], "unicodes": { "secondary": ["10f54f"] } }, "changes": [ "5.0.13", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "bodega", "building", "buy", "market", "purchase", "shopping", "store" ] }, "styles": ["solid"], "unicode": "f54f", "label": "Shop", "voted": true, "svg": { "solid": { "last_modified": 1684766475, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M36.8 192H603.2c20.3 0 36.8-16.5 36.8-36.8c0-7.3-2.2-14.4-6.2-20.4L558.2 21.4C549.3 8 534.4 0 518.3 0H121.7c-16 0-31 8-39.9 21.4L6.2 134.7c-4 6.1-6.2 13.2-6.2 20.4C0 175.5 16.5 192 36.8 192zM64 224V384v80c0 26.5 21.5 48 48 48H336c26.5 0 48-21.5 48-48V384 224H320V384H128V224H64zm448 0V480c0 17.7 14.3 32 32 32s32-14.3 32-32V224H512z" } }, "free": ["solid"] }, "shop-lock": { "changes": ["6.0.0", "6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "bodega", "building", "buy", "closed", "lock", "lockdown", "market", "purchase", "quarantine", "shop", "shopping", "store" ] }, "styles": ["solid"], "unicode": "e4a5", "label": "Shop Lock", "voted": false, "svg": { "solid": { "last_modified": 1684766476, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M36.8 192H449.6c20.2-19.8 47.9-32 78.4-32c30.5 0 58.1 12.2 78.3 31.9c18.9-1.6 33.7-17.4 33.7-36.7c0-7.3-2.2-14.4-6.2-20.4L558.2 21.4C549.3 8 534.4 0 518.3 0H121.7c-16 0-31 8-39.9 21.4L6.2 134.7c-4 6.1-6.2 13.2-6.2 20.4C0 175.5 16.5 192 36.8 192zM384 224H320V384H128V224H64V384v80c0 26.5 21.5 48 48 48H336c26.5 0 48-21.5 48-48V384 352 224zm144 16c17.7 0 32 14.3 32 32v48H496V272c0-17.7 14.3-32 32-32zm-80 32v48c-17.7 0-32 14.3-32 32V480c0 17.7 14.3 32 32 32H608c17.7 0 32-14.3 32-32V352c0-17.7-14.3-32-32-32V272c0-44.2-35.8-80-80-80s-80 35.8-80 80z" } }, "free": ["solid"] }, "shop-slash": { "aliases": { "names": ["store-alt-slash"], "unicodes": { "secondary": ["10e070"] } }, "changes": [ "5.13.0", "5.14.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["building", "buy", "closed", "covid-19", "purchase", "shopping"] }, "styles": ["solid"], "unicode": "e070", "label": "Shop Slash", "voted": false, "svg": { "solid": { "last_modified": 1684766476, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7l-54.8-43V224H512V376L384 275.7V224H320v1.5L277.2 192H603.2c20.3 0 36.8-16.5 36.8-36.8c0-7.3-2.2-14.4-6.2-20.4L558.2 21.4C549.3 8 534.4 0 518.3 0H121.7c-16 0-31 8-39.9 21.4L74.1 32.8 38.8 5.1zM36.8 192h85L21 112.5 6.2 134.7c-4 6.1-6.2 13.2-6.2 20.4C0 175.5 16.5 192 36.8 192zM320 384H128V224H64V384v80c0 26.5 21.5 48 48 48H336c26.5 0 48-21.5 48-48V398.5l-64-50.4V384z" } }, "free": ["solid"] }, "shopify": { "changes": ["5.12.1", "5.14.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e057", "label": "Shopify", "voted": false, "svg": { "brands": { "last_modified": 1660014473, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M388.32,104.1a4.66,4.66,0,0,0-4.4-4c-2,0-37.23-.8-37.23-.8s-21.61-20.82-29.62-28.83V503.2L442.76,472S388.72,106.5,388.32,104.1ZM288.65,70.47a116.67,116.67,0,0,0-7.21-17.61C271,32.85,255.42,22,237,22a15,15,0,0,0-4,.4c-.4-.8-1.2-1.2-1.6-2C223.4,11.63,213,7.63,200.58,8c-24,.8-48,18-67.25,48.83-13.61,21.62-24,48.84-26.82,70.06-27.62,8.4-46.83,14.41-47.23,14.81-14,4.4-14.41,4.8-16,18-1.2,10-38,291.82-38,291.82L307.86,504V65.67a41.66,41.66,0,0,0-4.4.4S297.86,67.67,288.65,70.47ZM233.41,87.69c-16,4.8-33.63,10.4-50.84,15.61,4.8-18.82,14.41-37.63,25.62-50,4.4-4.4,10.41-9.61,17.21-12.81C232.21,54.86,233.81,74.48,233.41,87.69ZM200.58,24.44A27.49,27.49,0,0,1,215,28c-6.4,3.2-12.81,8.41-18.81,14.41-15.21,16.42-26.82,42-31.62,66.45-14.42,4.41-28.83,8.81-42,12.81C131.33,83.28,163.75,25.24,200.58,24.44ZM154.15,244.61c1.6,25.61,69.25,31.22,73.25,91.66,2.8,47.64-25.22,80.06-65.65,82.47-48.83,3.2-75.65-25.62-75.65-25.62l10.4-44s26.82,20.42,48.44,18.82c14-.8,19.22-12.41,18.81-20.42-2-33.62-57.24-31.62-60.84-86.86-3.2-46.44,27.22-93.27,94.47-97.68,26-1.6,39.23,4.81,39.23,4.81L221.4,225.39s-17.21-8-37.63-6.4C154.15,221,153.75,239.8,154.15,244.61ZM249.42,82.88c0-12-1.6-29.22-7.21-43.63,18.42,3.6,27.22,24,31.23,36.43Q262.63,78.68,249.42,82.88Z" } }, "free": ["brands"] }, "shopware": { "changes": ["5.1.0", "5.8.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f5b5", "label": "Shopware", "voted": false, "svg": { "brands": { "last_modified": 1660014483, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M403.5 455.41A246.17 246.17 0 0 1 256 504C118.81 504 8 393 8 256 8 118.81 119 8 256 8a247.39 247.39 0 0 1 165.7 63.5 3.57 3.57 0 0 1-2.86 6.18A418.62 418.62 0 0 0 362.13 74c-129.36 0-222.4 53.47-222.4 155.35 0 109 92.13 145.88 176.83 178.73 33.64 13 65.4 25.36 87 41.59a3.58 3.58 0 0 1 0 5.72zM503 233.09a3.64 3.64 0 0 0-1.27-2.44c-51.76-43-93.62-60.48-144.48-60.48-84.13 0-80.25 52.17-80.25 53.63 0 42.6 52.06 62 112.34 84.49 31.07 11.59 63.19 23.57 92.68 39.93a3.57 3.57 0 0 0 5-1.82A249 249 0 0 0 503 233.09z" } }, "free": ["brands"] }, "shower": { "aliases": { "unicodes": { "composite": ["1f6bf"], "secondary": ["10f2cc"] } }, "changes": [ "4.7.0", "5.0.0", "5.12.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["bath", "clean", "faucet", "shower", "water"] }, "styles": ["solid"], "unicode": "f2cc", "label": "Shower", "voted": false, "svg": { "solid": { "last_modified": 1684767441, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M64 131.9C64 112.1 80.1 96 99.9 96c9.5 0 18.6 3.8 25.4 10.5l16.2 16.2c-21 38.9-17.4 87.5 10.9 123L151 247c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0L345 121c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0l-1.3 1.3c-35.5-28.3-84.2-31.9-123-10.9L170.5 61.3C151.8 42.5 126.4 32 99.9 32C44.7 32 0 76.7 0 131.9V448c0 17.7 14.3 32 32 32s32-14.3 32-32V131.9zM256 352a32 32 0 1 0 0-64 32 32 0 1 0 0 64zm64 64a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zm0-128a32 32 0 1 0 0-64 32 32 0 1 0 0 64zm64 64a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zm0-128a32 32 0 1 0 0-64 32 32 0 1 0 0 64zm64 64a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zm32-32a32 32 0 1 0 0-64 32 32 0 1 0 0 64z" } }, "free": ["solid"] }, "shrimp": { "aliases": { "unicodes": { "composite": ["1f990"] } }, "changes": ["6.0.0-beta2", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "allergy", "crustacean", "prawn", "seafood", "shellfish", "shrimp", "tail" ] }, "styles": ["solid"], "unicode": "e448", "label": "Shrimp", "voted": false, "svg": { "solid": { "last_modified": 1684767419, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M64 32C28.7 32 0 60.7 0 96s28.7 64 64 64h1c3.7 88.9 77 160 167 160h56V128H264 88.8 64c-17.7 0-32-14.3-32-32s14.3-32 32-32H464c8.8 0 16-7.2 16-16s-7.2-16-16-16H64zM224 456c0 13.3 10.7 24 24 24h72V407.8l-64.1-22.4c-12.5-4.4-26.2 2.2-30.6 14.7s2.2 26.2 14.7 30.6l4.5 1.6C233 433.9 224 443.9 224 456zm128 23.3c36.4-3.3 69.5-17.6 96.1-39.6l-86.5-34.6c-3 1.8-6.2 3.2-9.6 4.3v69.9zM472.6 415c24.6-30.3 39.4-68.9 39.4-111c0-12.3-1.3-24.3-3.7-35.9L382.8 355.1c.8 3.4 1.2 7 1.2 10.6c0 4.6-.7 9-1.9 13.1L472.6 415zM336 128H320V320h18.3c9.9 0 19.1 3.2 26.6 8.5l133.5-92.4C471.8 172.6 409.1 128 336 128zM168 192a24 24 0 1 1 48 0 24 24 0 1 1 -48 0z" } }, "free": ["solid"] }, "shuffle": { "aliases": { "names": ["random"], "unicodes": { "composite": ["1f500"], "secondary": ["10f074"] } }, "changes": ["1.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "arrow", "arrows", "crossed", "shuffle", "shuffle tracks button", "sort", "swap", "switch", "transfer" ] }, "styles": ["solid"], "unicode": "f074", "label": "Shuffle", "voted": false, "svg": { "solid": { "last_modified": 1684766331, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M403.8 34.4c12-5 25.7-2.2 34.9 6.9l64 64c6 6 9.4 14.1 9.4 22.6s-3.4 16.6-9.4 22.6l-64 64c-9.2 9.2-22.9 11.9-34.9 6.9s-19.8-16.6-19.8-29.6V160H352c-10.1 0-19.6 4.7-25.6 12.8L284 229.3 244 176l31.2-41.6C293.3 110.2 321.8 96 352 96h32V64c0-12.9 7.8-24.6 19.8-29.6zM164 282.7L204 336l-31.2 41.6C154.7 401.8 126.2 416 96 416H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H96c10.1 0 19.6-4.7 25.6-12.8L164 282.7zm274.6 188c-9.2 9.2-22.9 11.9-34.9 6.9s-19.8-16.6-19.8-29.6V416H352c-30.2 0-58.7-14.2-76.8-38.4L121.6 172.8c-6-8.1-15.5-12.8-25.6-12.8H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H96c30.2 0 58.7 14.2 76.8 38.4L326.4 339.2c6 8.1 15.5 12.8 25.6 12.8h32V320c0-12.9 7.8-24.6 19.8-29.6s25.7-2.2 34.9 6.9l64 64c6 6 9.4 14.1 9.4 22.6s-3.4 16.6-9.4 22.6l-64 64z" } }, "free": ["solid"] }, "shuttle-space": { "aliases": { "names": ["space-shuttle"], "unicodes": { "secondary": ["10f197"] } }, "changes": [ "4.1.0", "5.0.0", "5.10.2", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "astronaut", "machine", "nasa", "rocket", "space", "transportation" ] }, "styles": ["solid"], "unicode": "f197", "label": "Shuttle Space", "voted": false, "svg": { "solid": { "last_modified": 1684767637, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M130 480c40.6 0 80.4-11 115.2-31.9L352 384l-224 0 0 96h2zM352 128L245.2 63.9C210.4 43 170.6 32 130 32h-2v96l224 0zM96 128l0-96H80C53.5 32 32 53.5 32 80v48h8c-22.1 0-40 17.9-40 40v16V328v16c0 22.1 17.9 40 40 40H32v48c0 26.5 21.5 48 48 48H96l0-96h8c26.2 0 49.4-12.6 64-32H456c69.3 0 135-22.7 179.2-81.6c6.4-8.5 6.4-20.3 0-28.8C591 182.7 525.3 160 456 160H168c-14.6-19.4-37.8-32-64-32l-8 0zM512 243.6v24.9c0 19.6-15.9 35.6-35.6 35.6c-2.5 0-4.4-2-4.4-4.4V212.4c0-2.5 2-4.4 4.4-4.4c19.6 0 35.6 15.9 35.6 35.6z" } }, "free": ["solid"] }, "sign-hanging": { "aliases": { "names": ["sign"], "unicodes": { "secondary": ["10f4d9"] } }, "changes": [ "5.0.9", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["directions", "real estate", "signage", "wayfinding"] }, "styles": ["solid"], "unicode": "f4d9", "label": "Sign Hanging", "voted": false, "svg": { "solid": { "last_modified": 1684767488, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M96 0c17.7 0 32 14.3 32 32V64l352 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-352 0V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V128H32C14.3 128 0 113.7 0 96S14.3 64 32 64H64V32C64 14.3 78.3 0 96 0zm96 160H448c17.7 0 32 14.3 32 32V352c0 17.7-14.3 32-32 32H192c-17.7 0-32-14.3-32-32V192c0-17.7 14.3-32 32-32z" } }, "free": ["solid"] }, "signal": { "aliases": { "names": ["signal-5", "signal-perfect"], "unicodes": { "composite": ["1f4f6"], "secondary": ["10f012"] } }, "changes": [ "1.0.0", "5.0.0", "5.3.0", "5.10.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "antenna", "antenna bars", "bar", "bars", "cell", "graph", "mobile", "online", "phone", "reception", "status" ] }, "styles": ["solid"], "unicode": "f012", "label": "Signal", "voted": false, "svg": { "solid": { "last_modified": 1684766676, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M576 0c17.7 0 32 14.3 32 32V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V32c0-17.7 14.3-32 32-32zM448 96c17.7 0 32 14.3 32 32V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V128c0-17.7 14.3-32 32-32zM352 224V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V224c0-17.7 14.3-32 32-32s32 14.3 32 32zM192 288c17.7 0 32 14.3 32 32V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V320c0-17.7 14.3-32 32-32zM96 416v64c0 17.7-14.3 32-32 32s-32-14.3-32-32V416c0-17.7 14.3-32 32-32s32 14.3 32 32z" } }, "free": ["solid"] }, "signature": { "aliases": { "unicodes": { "secondary": ["10f5b7"] } }, "changes": [ "5.1.0", "5.6.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["John Hancock", "cursive", "name", "writing"] }, "styles": ["solid"], "unicode": "f5b7", "label": "Signature", "voted": true, "svg": { "solid": { "last_modified": 1684767368, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M192 128c0-17.7 14.3-32 32-32s32 14.3 32 32v7.8c0 27.7-2.4 55.3-7.1 82.5l-84.4 25.3c-40.6 12.2-68.4 49.6-68.4 92v71.9c0 40 32.5 72.5 72.5 72.5c26 0 50-13.9 62.9-36.5l13.9-24.3c26.8-47 46.5-97.7 58.4-150.5l94.4-28.3-12.5 37.5c-3.3 9.8-1.6 20.5 4.4 28.8s15.7 13.3 26 13.3H544c17.7 0 32-14.3 32-32s-14.3-32-32-32H460.4l18-53.9c3.8-11.3 .9-23.8-7.4-32.4s-20.7-11.8-32.2-8.4L316.4 198.1c2.4-20.7 3.6-41.4 3.6-62.3V128c0-53-43-96-96-96s-96 43-96 96v32c0 17.7 14.3 32 32 32s32-14.3 32-32V128zm-9.2 177l49-14.7c-10.4 33.8-24.5 66.4-42.1 97.2l-13.9 24.3c-1.5 2.6-4.3 4.3-7.4 4.3c-4.7 0-8.5-3.8-8.5-8.5V335.6c0-14.1 9.3-26.6 22.8-30.7zM24 368c-13.3 0-24 10.7-24 24s10.7 24 24 24H64.3c-.2-2.8-.3-5.6-.3-8.5V368H24zm592 48c13.3 0 24-10.7 24-24s-10.7-24-24-24H305.9c-6.7 16.3-14.2 32.3-22.3 48H616z" } }, "free": ["solid"] }, "signs-post": { "aliases": { "names": ["map-signs"], "unicodes": { "secondary": ["10f277"] } }, "changes": [ "4.4.0", "5.0.0", "5.2.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["directions", "directory", "map", "signage", "wayfinding"] }, "styles": ["solid"], "unicode": "f277", "label": "Signs Post", "voted": false, "svg": { "solid": { "last_modified": 1684767489, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M224 32H64C46.3 32 32 46.3 32 64v64c0 17.7 14.3 32 32 32H441.4c4.2 0 8.3-1.7 11.3-4.7l48-48c6.2-6.2 6.2-16.4 0-22.6l-48-48c-3-3-7.1-4.7-11.3-4.7H288c0-17.7-14.3-32-32-32s-32 14.3-32 32zM480 256c0-17.7-14.3-32-32-32H288V192H224v32H70.6c-4.2 0-8.3 1.7-11.3 4.7l-48 48c-6.2 6.2-6.2 16.4 0 22.6l48 48c3 3 7.1 4.7 11.3 4.7H448c17.7 0 32-14.3 32-32V256zM288 480V384H224v96c0 17.7 14.3 32 32 32s32-14.3 32-32z" } }, "free": ["solid"] }, "sim-card": { "aliases": { "unicodes": { "secondary": ["10f7c4"] } }, "changes": [ "5.6.0", "5.8.2", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "hard drive", "hardware", "portable", "storage", "technology", "tiny" ] }, "styles": ["solid"], "unicode": "f7c4", "label": "Sim Card", "voted": true, "svg": { "solid": { "last_modified": 1684767341, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M64 0H242.7c17 0 33.3 6.7 45.3 18.7L365.3 96c12 12 18.7 28.3 18.7 45.3V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V64C0 28.7 28.7 0 64 0zM96 192c-17.7 0-32 14.3-32 32v32h64V192H96zM64 352h80 96 80V288H240 144 64v64zM320 224c0-17.7-14.3-32-32-32H256v64h64V224zM160 192v64h64V192H160zM288 448c17.7 0 32-14.3 32-32V384H256v64h32zM160 384v64h64V384H160zM64 416c0 17.7 14.3 32 32 32h32V384H64v32z" } }, "free": ["solid"] }, "simplybuilt": { "changes": ["4.3.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f215", "label": "SimplyBuilt", "voted": false, "svg": { "brands": { "last_modified": 1660014465, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M481.2 64h-106c-14.5 0-26.6 11.8-26.6 26.3v39.6H163.3V90.3c0-14.5-12-26.3-26.6-26.3h-106C16.1 64 4.3 75.8 4.3 90.3v331.4c0 14.5 11.8 26.3 26.6 26.3h450.4c14.8 0 26.6-11.8 26.6-26.3V90.3c-.2-14.5-12-26.3-26.7-26.3zM149.8 355.8c-36.6 0-66.4-29.7-66.4-66.4 0-36.9 29.7-66.6 66.4-66.6 36.9 0 66.6 29.7 66.6 66.6 0 36.7-29.7 66.4-66.6 66.4zm212.4 0c-36.9 0-66.6-29.7-66.6-66.6 0-36.6 29.7-66.4 66.6-66.4 36.6 0 66.4 29.7 66.4 66.4 0 36.9-29.8 66.6-66.4 66.6z" } }, "free": ["brands"] }, "sink": { "aliases": { "unicodes": { "secondary": ["10e06d"] } }, "changes": [ "5.13.0", "5.13.1", "5.14.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["bathroom", "covid-19", "faucet", "kitchen", "wash"] }, "styles": ["solid"], "unicode": "e06d", "label": "Sink", "voted": false, "svg": { "solid": { "last_modified": 1684767443, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M288 96c0-17.7 14.3-32 32-32s32 14.3 32 32s14.3 32 32 32s32-14.3 32-32c0-53-43-96-96-96s-96 43-96 96V288H160V264c0-30.9-25.1-56-56-56H56c-13.3 0-24 10.7-24 24s10.7 24 24 24h48c4.4 0 8 3.6 8 8v24H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H256 480c17.7 0 32-14.3 32-32s-14.3-32-32-32H400V264c0-4.4 3.6-8 8-8h56c13.3 0 24-10.7 24-24s-10.7-24-24-24H408c-30.9 0-56 25.1-56 56v24H288V96zM480 416V384H32v32c0 53 43 96 96 96H384c53 0 96-43 96-96z" } }, "free": ["solid"] }, "sistrix": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3ee", "label": "SISTRIX", "voted": false, "svg": { "brands": { "last_modified": 1660014480, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M448 449L301.2 300.2c20-27.9 31.9-62.2 31.9-99.2 0-93.1-74.7-168.9-166.5-168.9C74.7 32 0 107.8 0 200.9s74.7 168.9 166.5 168.9c39.8 0 76.3-14.2 105-37.9l146 148.1 30.5-31zM166.5 330.8c-70.6 0-128.1-58.3-128.1-129.9S95.9 71 166.5 71s128.1 58.3 128.1 129.9-57.4 129.9-128.1 129.9z" } }, "free": ["brands"] }, "sitemap": { "aliases": { "unicodes": { "secondary": ["10f0e8"] } }, "changes": [ "2.0.0", "5.0.0", "5.0.13", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "directory", "hierarchy", "ia", "information architecture", "organization" ] }, "styles": ["solid"], "unicode": "f0e8", "label": "Sitemap", "voted": false, "svg": { "solid": { "last_modified": 1684767207, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M208 80c0-26.5 21.5-48 48-48h64c26.5 0 48 21.5 48 48v64c0 26.5-21.5 48-48 48h-8v40H464c30.9 0 56 25.1 56 56v32h8c26.5 0 48 21.5 48 48v64c0 26.5-21.5 48-48 48H464c-26.5 0-48-21.5-48-48V368c0-26.5 21.5-48 48-48h8V288c0-4.4-3.6-8-8-8H312v40h8c26.5 0 48 21.5 48 48v64c0 26.5-21.5 48-48 48H256c-26.5 0-48-21.5-48-48V368c0-26.5 21.5-48 48-48h8V280H112c-4.4 0-8 3.6-8 8v32h8c26.5 0 48 21.5 48 48v64c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V368c0-26.5 21.5-48 48-48h8V288c0-30.9 25.1-56 56-56H264V192h-8c-26.5 0-48-21.5-48-48V80z" } }, "free": ["solid"] }, "sith": { "changes": ["5.0.12"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f512", "label": "Sith", "voted": false, "svg": { "brands": { "last_modified": 1660014472, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M0 32l69.71 118.75-58.86-11.52 69.84 91.03a146.741 146.741 0 0 0 0 51.45l-69.84 91.03 58.86-11.52L0 480l118.75-69.71-11.52 58.86 91.03-69.84c17.02 3.04 34.47 3.04 51.48 0l91.03 69.84-11.52-58.86L448 480l-69.71-118.78 58.86 11.52-69.84-91.03c3.03-17.01 3.04-34.44 0-51.45l69.84-91.03-58.86 11.52L448 32l-118.75 69.71 11.52-58.9-91.06 69.87c-8.5-1.52-17.1-2.29-25.71-2.29s-17.21.78-25.71 2.29l-91.06-69.87 11.52 58.9L0 32zm224 99.78c31.8 0 63.6 12.12 87.85 36.37 48.5 48.5 48.49 127.21 0 175.7s-127.2 48.46-175.7-.03c-48.5-48.5-48.49-127.21 0-175.7 24.24-24.25 56.05-36.34 87.85-36.34zm0 36.66c-22.42 0-44.83 8.52-61.92 25.61-34.18 34.18-34.19 89.68 0 123.87s89.65 34.18 123.84 0c34.18-34.18 34.19-89.68 0-123.87-17.09-17.09-39.5-25.61-61.92-25.61z" } }, "free": ["brands"] }, "sitrox": { "changes": ["6.0.0-beta2"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e44a", "label": "Sitrox", "voted": false, "svg": { "brands": { "last_modified": 1660014459, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M212.439 0.00846128V0H448V128H64C64 57.6008 141.755 0.475338 212.439 0.00846128ZM237.256 192V192.007C307.135 192.475 384 249.6 384 320H210.809V319.995C140.915 319.563 64 262.424 64 192H237.256ZM235.565 511.993C306.251 511.521 384 454.399 384 384H0V512H235.565V511.993Z" } }, "free": ["brands"] }, "sketch": { "changes": ["5.6.0", "5.8.0"], "ligatures": [], "search": { "terms": ["app", "design", "interface"] }, "styles": ["brands"], "unicode": "f7c6", "label": "Sketch", "voted": false, "svg": { "brands": { "last_modified": 1660014462, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M27.5 162.2L9 187.1h90.5l6.9-130.7-78.9 105.8zM396.3 45.7L267.7 32l135.7 147.2-7.1-133.5zM112.2 218.3l-11.2-22H9.9L234.8 458zm2-31.2h284l-81.5-88.5L256.3 33zm297.3 9.1L277.6 458l224.8-261.7h-90.9zM415.4 69L406 56.4l.9 17.3 6.1 113.4h90.3zM113.5 93.5l-4.6 85.6L244.7 32 116.1 45.7zm287.7 102.7h-290l42.4 82.9L256.3 480l144.9-283.8z" } }, "free": ["brands"] }, "skull": { "aliases": { "unicodes": { "composite": ["1f480"], "secondary": ["10f54c"] } }, "changes": [ "5.0.13", "5.10.2", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "bones", "death", "face", "fairy tale", "monster", "skeleton", "skull", "x-ray", "yorick" ] }, "styles": ["solid"], "unicode": "f54c", "label": "Skull", "voted": true, "svg": { "solid": { "last_modified": 1684767582, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M416 398.9c58.5-41.1 96-104.1 96-174.9C512 100.3 397.4 0 256 0S0 100.3 0 224c0 70.7 37.5 133.8 96 174.9c0 .4 0 .7 0 1.1v64c0 26.5 21.5 48 48 48h48V464c0-8.8 7.2-16 16-16s16 7.2 16 16v48h64V464c0-8.8 7.2-16 16-16s16 7.2 16 16v48h48c26.5 0 48-21.5 48-48V400c0-.4 0-.7 0-1.1zM96 256a64 64 0 1 1 128 0A64 64 0 1 1 96 256zm256-64a64 64 0 1 1 0 128 64 64 0 1 1 0-128z" } }, "free": ["solid"] }, "skull-crossbones": { "aliases": { "unicodes": { "composite": ["1f571", "2620"], "secondary": ["10f714"] } }, "changes": [ "5.4.0", "5.10.2", "6.0.0-beta1", "6.0.0-beta3", "6.1.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Black Skull and Crossbones", "Dungeons & Dragons", "alert", "bones", "crossbones", "d&d", "danger", "dangerous area", "dead", "deadly", "death", "dnd", "face", "fantasy", "halloween", "holiday", "jolly-roger", "monster", "pirate", "poison", "skeleton", "skull", "skull and crossbones", "warning" ] }, "styles": ["solid"], "unicode": "f714", "label": "Skull Crossbones", "voted": false, "svg": { "solid": { "last_modified": 1684767582, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M368 128c0 44.4-25.4 83.5-64 106.4V256c0 17.7-14.3 32-32 32H176c-17.7 0-32-14.3-32-32V234.4c-38.6-23-64-62.1-64-106.4C80 57.3 144.5 0 224 0s144 57.3 144 128zM168 176a32 32 0 1 0 0-64 32 32 0 1 0 0 64zm144-32a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zM3.4 273.7c7.9-15.8 27.1-22.2 42.9-14.3L224 348.2l177.7-88.8c15.8-7.9 35-1.5 42.9 14.3s1.5 35-14.3 42.9L295.6 384l134.8 67.4c15.8 7.9 22.2 27.1 14.3 42.9s-27.1 22.2-42.9 14.3L224 419.8 46.3 508.6c-15.8 7.9-35 1.5-42.9-14.3s-1.5-35 14.3-42.9L152.4 384 17.7 316.6C1.9 308.7-4.5 289.5 3.4 273.7z" } }, "free": ["solid"] }, "skyatlas": { "changes": ["4.3.0", "5.0.0", "5.0.3"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f216", "label": "skyatlas", "voted": false, "svg": { "brands": { "last_modified": 1660014461, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M640 329.3c0 65.9-52.5 114.4-117.5 114.4-165.9 0-196.6-249.7-359.7-249.7-146.9 0-147.1 212.2 5.6 212.2 42.5 0 90.9-17.8 125.3-42.5 5.6-4.1 16.9-16.3 22.8-16.3s10.9 5 10.9 10.9c0 7.8-13.1 19.1-18.7 24.1-40.9 35.6-100.3 61.2-154.7 61.2-83.4.1-154-59-154-144.9s67.5-149.1 152.8-149.1c185.3 0 222.5 245.9 361.9 245.9 99.9 0 94.8-139.7 3.4-139.7-17.5 0-35 11.6-46.9 11.6-8.4 0-15.9-7.2-15.9-15.6 0-11.6 5.3-23.7 5.3-36.3 0-66.6-50.9-114.7-116.9-114.7-53.1 0-80 36.9-88.8 36.9-6.2 0-11.2-5-11.2-11.2 0-5.6 4.1-10.3 7.8-14.4 25.3-28.8 64.7-43.7 102.8-43.7 79.4 0 139.1 58.4 139.1 137.8 0 6.9-.3 13.7-1.2 20.6 11.9-3.1 24.1-4.7 35.9-4.7 60.7 0 111.9 45.3 111.9 107.2z" } }, "free": ["brands"] }, "skype": { "changes": ["3.2.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f17e", "label": "Skype", "voted": false, "svg": { "brands": { "last_modified": 1660014475, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M424.7 299.8c2.9-14 4.7-28.9 4.7-43.8 0-113.5-91.9-205.3-205.3-205.3-14.9 0-29.7 1.7-43.8 4.7C161.3 40.7 137.7 32 112 32 50.2 32 0 82.2 0 144c0 25.7 8.7 49.3 23.3 68.2-2.9 14-4.7 28.9-4.7 43.8 0 113.5 91.9 205.3 205.3 205.3 14.9 0 29.7-1.7 43.8-4.7 19 14.6 42.6 23.3 68.2 23.3 61.8 0 112-50.2 112-112 .1-25.6-8.6-49.2-23.2-68.1zm-194.6 91.5c-65.6 0-120.5-29.2-120.5-65 0-16 9-30.6 29.5-30.6 31.2 0 34.1 44.9 88.1 44.9 25.7 0 42.3-11.4 42.3-26.3 0-18.7-16-21.6-42-28-62.5-15.4-117.8-22-117.8-87.2 0-59.2 58.6-81.1 109.1-81.1 55.1 0 110.8 21.9 110.8 55.4 0 16.9-11.4 31.8-30.3 31.8-28.3 0-29.2-33.5-75-33.5-25.7 0-42 7-42 22.5 0 19.8 20.8 21.8 69.1 33 41.4 9.3 90.7 26.8 90.7 77.6 0 59.1-57.1 86.5-112 86.5z" } }, "free": ["brands"] }, "slack": { "aliases": { "names": ["slack-hash"], "unicodes": { "composite": ["f3ef"] } }, "changes": ["4.1.0", "5.0.0", "5.7.0"], "ligatures": [], "search": { "terms": ["anchor", "hash", "hashtag"] }, "styles": ["brands"], "unicode": "f198", "label": "Slack Logo", "voted": false, "svg": { "brands": { "last_modified": 1660014460, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M94.12 315.1c0 25.9-21.16 47.06-47.06 47.06S0 341 0 315.1c0-25.9 21.16-47.06 47.06-47.06h47.06v47.06zm23.72 0c0-25.9 21.16-47.06 47.06-47.06s47.06 21.16 47.06 47.06v117.84c0 25.9-21.16 47.06-47.06 47.06s-47.06-21.16-47.06-47.06V315.1zm47.06-188.98c-25.9 0-47.06-21.16-47.06-47.06S139 32 164.9 32s47.06 21.16 47.06 47.06v47.06H164.9zm0 23.72c25.9 0 47.06 21.16 47.06 47.06s-21.16 47.06-47.06 47.06H47.06C21.16 243.96 0 222.8 0 196.9s21.16-47.06 47.06-47.06H164.9zm188.98 47.06c0-25.9 21.16-47.06 47.06-47.06 25.9 0 47.06 21.16 47.06 47.06s-21.16 47.06-47.06 47.06h-47.06V196.9zm-23.72 0c0 25.9-21.16 47.06-47.06 47.06-25.9 0-47.06-21.16-47.06-47.06V79.06c0-25.9 21.16-47.06 47.06-47.06 25.9 0 47.06 21.16 47.06 47.06V196.9zM283.1 385.88c25.9 0 47.06 21.16 47.06 47.06 0 25.9-21.16 47.06-47.06 47.06-25.9 0-47.06-21.16-47.06-47.06v-47.06h47.06zm0-23.72c-25.9 0-47.06-21.16-47.06-47.06 0-25.9 21.16-47.06 47.06-47.06h117.84c25.9 0 47.06 21.16 47.06 47.06 0 25.9-21.16 47.06-47.06 47.06H283.1z" } }, "free": ["brands"] }, "slash": { "aliases": { "unicodes": { "secondary": ["10f715"] } }, "changes": ["5.4.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["cancel", "close", "mute", "off", "stop", "x"] }, "styles": ["solid"], "unicode": "f715", "label": "Slash", "voted": true, "svg": { "solid": { "last_modified": 1684767552, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M5.1 9.2C13.3-1.2 28.4-3.1 38.8 5.1l592 464c10.4 8.2 12.3 23.3 4.1 33.7s-23.3 12.3-33.7 4.1L9.2 42.9C-1.2 34.7-3.1 19.6 5.1 9.2z" } }, "free": ["solid"] }, "sleigh": { "aliases": { "unicodes": { "secondary": ["10f7cc"] } }, "changes": [ "5.6.0", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "christmas", "claus", "fly", "holiday", "santa", "sled", "snow", "xmas" ] }, "styles": ["solid"], "unicode": "f7cc", "label": "Sleigh", "voted": false, "svg": { "solid": { "last_modified": 1684767649, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M32 32C14.3 32 0 46.3 0 64S14.3 96 32 96V256c0 53 43 96 96 96v32h64V352H384v32h64V352c53 0 96-43 96-96V160c17.7 0 32-14.3 32-32s-14.3-32-32-32H512 480c-17.7 0-32 14.3-32 32v41.3c0 30.2-24.5 54.7-54.7 54.7c-75.5 0-145.6-38.9-185.6-102.9l-4.3-6.9C174.2 67.6 125 37.6 70.7 32.7c-2.2-.5-4.4-.7-6.7-.7H55 32zM640 384c0-17.7-14.3-32-32-32s-32 14.3-32 32v8c0 13.3-10.7 24-24 24H64c-17.7 0-32 14.3-32 32s14.3 32 32 32H552c48.6 0 88-39.4 88-88v-8z" } }, "free": ["solid"] }, "sliders": { "aliases": { "names": ["sliders-h"], "unicodes": { "secondary": ["10f1de"] } }, "changes": [ "4.1.0", "5.0.0", "5.0.11", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["adjust", "settings", "sliders", "toggle"] }, "styles": ["solid"], "unicode": "f1de", "label": "Sliders", "voted": false, "svg": { "solid": { "last_modified": 1684767367, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 416c0 17.7 14.3 32 32 32l54.7 0c12.3 28.3 40.5 48 73.3 48s61-19.7 73.3-48L480 448c17.7 0 32-14.3 32-32s-14.3-32-32-32l-246.7 0c-12.3-28.3-40.5-48-73.3-48s-61 19.7-73.3 48L32 384c-17.7 0-32 14.3-32 32zm128 0a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zM320 256a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm32-80c-32.8 0-61 19.7-73.3 48L32 224c-17.7 0-32 14.3-32 32s14.3 32 32 32l246.7 0c12.3 28.3 40.5 48 73.3 48s61-19.7 73.3-48l54.7 0c17.7 0 32-14.3 32-32s-14.3-32-32-32l-54.7 0c-12.3-28.3-40.5-48-73.3-48zM192 128a32 32 0 1 1 0-64 32 32 0 1 1 0 64zm73.3-64C253 35.7 224.8 16 192 16s-61 19.7-73.3 48L32 64C14.3 64 0 78.3 0 96s14.3 32 32 32l86.7 0c12.3 28.3 40.5 48 73.3 48s61-19.7 73.3-48L480 128c17.7 0 32-14.3 32-32s-14.3-32-32-32L265.3 64z" } }, "free": ["solid"] }, "slideshare": { "changes": ["4.2.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f1e7", "label": "Slideshare", "voted": false, "svg": { "brands": { "last_modified": 1660014465, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M187.7 153.7c-34 0-61.7 25.7-61.7 57.7 0 31.7 27.7 57.7 61.7 57.7s61.7-26 61.7-57.7c0-32-27.7-57.7-61.7-57.7zm143.4 0c-34 0-61.7 25.7-61.7 57.7 0 31.7 27.7 57.7 61.7 57.7 34.3 0 61.7-26 61.7-57.7.1-32-27.4-57.7-61.7-57.7zm156.6 90l-6 4.3V49.7c0-27.4-20.6-49.7-46-49.7H76.6c-25.4 0-46 22.3-46 49.7V248c-2-1.4-4.3-2.9-6.3-4.3-15.1-10.6-25.1 4-16 17.7 18.3 22.6 53.1 50.3 106.3 72C58.3 525.1 252 555.7 248.9 457.5c0-.7.3-56.6.3-96.6 5.1 1.1 9.4 2.3 13.7 3.1 0 39.7.3 92.8.3 93.5-3.1 98.3 190.6 67.7 134.3-124 53.1-21.7 88-49.4 106.3-72 9.1-13.8-.9-28.3-16.1-17.8zm-30.5 19.2c-68.9 37.4-128.3 31.1-160.6 29.7-23.7-.9-32.6 9.1-33.7 24.9-10.3-7.7-18.6-15.5-20.3-17.1-5.1-5.4-13.7-8-27.1-7.7-31.7 1.1-89.7 7.4-157.4-28V72.3c0-34.9 8.9-45.7 40.6-45.7h317.7c30.3 0 40.9 12.9 40.9 45.7v190.6z" } }, "free": ["brands"] }, "smog": { "aliases": { "unicodes": { "secondary": ["10f75f"] } }, "changes": ["5.5.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["dragon", "fog", "haze", "pollution", "smoke", "weather"] }, "styles": ["solid"], "unicode": "f75f", "label": "Smog", "voted": false, "svg": { "solid": { "last_modified": 1684767662, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M32 144c0 79.5 64.5 144 144 144H299.3c22.6 19.9 52.2 32 84.7 32s62.1-12.1 84.7-32H496c61.9 0 112-50.1 112-112s-50.1-112-112-112c-10.7 0-21 1.5-30.8 4.3C443.8 27.7 401.1 0 352 0c-32.6 0-62.4 12.2-85.1 32.3C242.1 12.1 210.5 0 176 0C96.5 0 32 64.5 32 144zM616 368H280c-13.3 0-24 10.7-24 24s10.7 24 24 24H616c13.3 0 24-10.7 24-24s-10.7-24-24-24zm-64 96H440c-13.3 0-24 10.7-24 24s10.7 24 24 24H552c13.3 0 24-10.7 24-24s-10.7-24-24-24zm-192 0H24c-13.3 0-24 10.7-24 24s10.7 24 24 24H360c13.3 0 24-10.7 24-24s-10.7-24-24-24zM224 392c0-13.3-10.7-24-24-24H96c-13.3 0-24 10.7-24 24s10.7 24 24 24H200c13.3 0 24-10.7 24-24z" } }, "free": ["solid"] }, "smoking": { "aliases": { "unicodes": { "composite": ["1f6ac"], "secondary": ["10f48d"] } }, "changes": ["5.0.7", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "cancer", "cigarette", "nicotine", "smoking", "smoking status", "tobacco" ] }, "styles": ["solid"], "unicode": "f48d", "label": "Smoking", "voted": true, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M448 32V43c0 38.2 15.2 74.8 42.2 101.8l21 21c21 21 32.8 49.5 32.8 79.2v11c0 17.7-14.3 32-32 32s-32-14.3-32-32V245c0-12.7-5.1-24.9-14.1-33.9l-21-21C405.9 151.1 384 98.1 384 43V32c0-17.7 14.3-32 32-32s32 14.3 32 32zM576 256V245c0-38.2-15.2-74.8-42.2-101.8l-21-21c-21-21-32.8-49.5-32.8-79.2V32c0-17.7 14.3-32 32-32s32 14.3 32 32V43c0 12.7 5.1 24.9 14.1 33.9l21 21c39 39 60.9 91.9 60.9 147.1v11c0 17.7-14.3 32-32 32s-32-14.3-32-32zM0 416c0-35.3 28.7-64 64-64H416c17.7 0 32 14.3 32 32v96c0 17.7-14.3 32-32 32H64c-35.3 0-64-28.7-64-64V416zm224 0v32H384V416H224zm288-64c17.7 0 32 14.3 32 32v96c0 17.7-14.3 32-32 32s-32-14.3-32-32V384c0-17.7 14.3-32 32-32zm96 0c17.7 0 32 14.3 32 32v96c0 17.7-14.3 32-32 32s-32-14.3-32-32V384c0-17.7 14.3-32 32-32z" } }, "free": ["solid"] }, "snapchat": { "aliases": { "names": ["snapchat-ghost"], "unicodes": { "composite": ["f2ac"] } }, "changes": ["4.6.0", "5.0.0", "6.0.0-beta1"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f2ab", "label": "Snapchat", "voted": false, "svg": { "brands": { "last_modified": 1660014463, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M496.926,366.6c-3.373-9.176-9.8-14.086-17.112-18.153-1.376-.806-2.641-1.451-3.72-1.947-2.182-1.128-4.414-2.22-6.634-3.373-22.8-12.09-40.609-27.341-52.959-45.42a102.889,102.889,0,0,1-9.089-16.12c-1.054-3.013-1-4.724-.248-6.287a10.221,10.221,0,0,1,2.914-3.038c3.918-2.591,7.96-5.22,10.7-6.993,4.885-3.162,8.754-5.667,11.246-7.44,9.362-6.547,15.909-13.5,20-21.278a42.371,42.371,0,0,0,2.1-35.191c-6.2-16.318-21.613-26.449-40.287-26.449a55.543,55.543,0,0,0-11.718,1.24c-1.029.224-2.059.459-3.063.72.174-11.16-.074-22.94-1.066-34.534-3.522-40.758-17.794-62.123-32.674-79.16A130.167,130.167,0,0,0,332.1,36.443C309.515,23.547,283.91,17,256,17S202.6,23.547,180,36.443a129.735,129.735,0,0,0-33.281,26.783c-14.88,17.038-29.152,38.44-32.673,79.161-.992,11.594-1.24,23.435-1.079,34.533-1-.26-2.021-.5-3.051-.719a55.461,55.461,0,0,0-11.717-1.24c-18.687,0-34.125,10.131-40.3,26.449a42.423,42.423,0,0,0,2.046,35.228c4.105,7.774,10.652,14.731,20.014,21.278,2.48,1.736,6.361,4.24,11.246,7.44,2.641,1.711,6.5,4.216,10.28,6.72a11.054,11.054,0,0,1,3.3,3.311c.794,1.624.818,3.373-.36,6.6a102.02,102.02,0,0,1-8.94,15.785c-12.077,17.669-29.363,32.648-51.434,44.639C32.355,348.608,20.2,352.75,15.069,366.7c-3.868,10.528-1.339,22.506,8.494,32.6a49.137,49.137,0,0,0,12.4,9.387,134.337,134.337,0,0,0,30.342,12.139,20.024,20.024,0,0,1,6.126,2.741c3.583,3.137,3.075,7.861,7.849,14.78a34.468,34.468,0,0,0,8.977,9.127c10.019,6.919,21.278,7.353,33.207,7.811,10.776.41,22.989.881,36.939,5.481,5.778,1.91,11.78,5.605,18.736,9.92C194.842,480.951,217.707,495,255.973,495s61.292-14.123,78.118-24.428c6.907-4.24,12.872-7.9,18.489-9.758,13.949-4.613,26.163-5.072,36.939-5.481,11.928-.459,23.187-.893,33.206-7.812a34.584,34.584,0,0,0,10.218-11.16c3.434-5.84,3.348-9.919,6.572-12.771a18.971,18.971,0,0,1,5.753-2.629A134.893,134.893,0,0,0,476.02,408.71a48.344,48.344,0,0,0,13.019-10.193l.124-.149C498.389,388.5,500.708,376.867,496.926,366.6Zm-34.013,18.277c-20.745,11.458-34.533,10.23-45.259,17.137-9.114,5.865-3.72,18.513-10.342,23.076-8.134,5.617-32.177-.4-63.239,9.858-25.618,8.469-41.961,32.822-88.038,32.822s-62.036-24.3-88.076-32.884c-31-10.255-55.092-4.241-63.239-9.858-6.609-4.563-1.24-17.211-10.341-23.076-10.739-6.907-24.527-5.679-45.26-17.075-13.206-7.291-5.716-11.8-1.314-13.937,75.143-36.381,87.133-92.552,87.666-96.719.645-5.046,1.364-9.014-4.191-14.148-5.369-4.96-29.189-19.7-35.8-24.316-10.937-7.638-15.748-15.264-12.2-24.638,2.48-6.485,8.531-8.928,14.879-8.928a27.643,27.643,0,0,1,5.965.67c12,2.6,23.659,8.617,30.392,10.242a10.749,10.749,0,0,0,2.48.335c3.6,0,4.86-1.811,4.612-5.927-.768-13.132-2.628-38.725-.558-62.644,2.84-32.909,13.442-49.215,26.04-63.636,6.051-6.932,34.484-36.976,88.857-36.976s82.88,29.92,88.931,36.827c12.611,14.421,23.225,30.727,26.04,63.636,2.071,23.919.285,49.525-.558,62.644-.285,4.327,1.017,5.927,4.613,5.927a10.648,10.648,0,0,0,2.48-.335c6.745-1.624,18.4-7.638,30.4-10.242a27.641,27.641,0,0,1,5.964-.67c6.386,0,12.4,2.48,14.88,8.928,3.546,9.374-1.24,17-12.189,24.639-6.609,4.612-30.429,19.343-35.8,24.315-5.568,5.134-4.836,9.1-4.191,14.149.533,4.228,12.511,60.4,87.666,96.718C468.629,373.011,476.119,377.524,462.913,384.877Z" } }, "free": ["brands"] }, "snowflake": { "aliases": { "unicodes": { "composite": ["2744", "2746"], "secondary": ["10f2dc"] } }, "changes": [ "4.7.0", "5.0.0", "5.5.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Heavy Chevron Snowflake", "cold", "precipitation", "rain", "snow", "snowfall", "snowflake", "winter" ] }, "styles": ["solid", "regular"], "unicode": "f2dc", "label": "Snowflake", "voted": false, "svg": { "solid": { "last_modified": 1684767662, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M224 0c17.7 0 32 14.3 32 32V62.1l15-15c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-49 49v70.3l61.4-35.8 17.7-66.1c3.4-12.8 16.6-20.4 29.4-17s20.4 16.6 17 29.4l-5.2 19.3 23.6-13.8c15.3-8.9 34.9-3.7 43.8 11.5s3.8 34.9-11.5 43.8l-25.3 14.8 21.7 5.8c12.8 3.4 20.4 16.6 17 29.4s-16.6 20.4-29.4 17l-67.7-18.1L287.5 256l60.9 35.5 67.7-18.1c12.8-3.4 26 4.2 29.4 17s-4.2 26-17 29.4l-21.7 5.8 25.3 14.8c15.3 8.9 20.4 28.5 11.5 43.8s-28.5 20.4-43.8 11.5l-23.6-13.8 5.2 19.3c3.4 12.8-4.2 26-17 29.4s-26-4.2-29.4-17l-17.7-66.1L256 311.7v70.3l49 49c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-15-15V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V449.9l-15 15c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l49-49V311.7l-61.4 35.8-17.7 66.1c-3.4 12.8-16.6 20.4-29.4 17s-20.4-16.6-17-29.4l5.2-19.3L48.1 395.6c-15.3 8.9-34.9 3.7-43.8-11.5s-3.7-34.9 11.5-43.8l25.3-14.8-21.7-5.8c-12.8-3.4-20.4-16.6-17-29.4s16.6-20.4 29.4-17l67.7 18.1L160.5 256 99.6 220.5 31.9 238.6c-12.8 3.4-26-4.2-29.4-17s4.2-26 17-29.4l21.7-5.8L15.9 171.6C.6 162.7-4.5 143.1 4.4 127.9s28.5-20.4 43.8-11.5l23.6 13.8-5.2-19.3c-3.4-12.8 4.2-26 17-29.4s26 4.2 29.4 17l17.7 66.1L192 200.3V129.9L143 81c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l15 15V32c0-17.7 14.3-32 32-32z" }, "regular": { "last_modified": 1684767662, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M224 0c13.3 0 24 10.7 24 24V70.1l23-23c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-57 57v76.5l66.2-38.2 20.9-77.8c3.4-12.8 16.6-20.4 29.4-17s20.4 16.6 17 29.4L373 142.2l37.1-21.4c11.5-6.6 26.2-2.7 32.8 8.8s2.7 26.2-8.8 32.8L397 183.8l31.5 8.4c12.8 3.4 20.4 16.6 17 29.4s-16.6 20.4-29.4 17l-77.8-20.9L272 256l66.2 38.2 77.8-20.9c12.8-3.4 26 4.2 29.4 17s-4.2 26-17 29.4L397 328.2l37.1 21.4c11.5 6.6 15.4 21.3 8.8 32.8s-21.3 15.4-32.8 8.8L373 369.8l8.4 31.5c3.4 12.8-4.2 26-17 29.4s-26-4.2-29.4-17l-20.9-77.8L248 297.6v76.5l57 57c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-23-23V488c0 13.3-10.7 24-24 24s-24-10.7-24-24V441.9l-23 23c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l57-57V297.6l-66.2 38.2-20.9 77.8c-3.4 12.8-16.6 20.4-29.4 17s-20.4-16.6-17-29.4L75 369.8 37.9 391.2c-11.5 6.6-26.2 2.7-32.8-8.8s-2.7-26.2 8.8-32.8L51 328.2l-31.5-8.4c-12.8-3.4-20.4-16.6-17-29.4s16.6-20.4 29.4-17l77.8 20.9L176 256l-66.2-38.2L31.9 238.6c-12.8 3.4-26-4.2-29.4-17s4.2-26 17-29.4L51 183.8 13.9 162.4c-11.5-6.6-15.4-21.3-8.8-32.8s21.3-15.4 32.8-8.8L75 142.2l-8.4-31.5c-3.4-12.8 4.2-26 17-29.4s26 4.2 29.4 17l20.9 77.8L200 214.4V137.9L143 81c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l23 23V24c0-13.3 10.7-24 24-24z" } }, "free": ["regular", "solid"] }, "snowman": { "aliases": { "unicodes": { "composite": ["2603", "26c4"], "secondary": ["10f7d0"] } }, "changes": ["5.6.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "cold", "decoration", "frost", "frosty", "holiday", "snow", "snowman", "snowman without snow" ] }, "styles": ["solid"], "unicode": "f7d0", "label": "Snowman", "voted": false, "svg": { "solid": { "last_modified": 1684767603, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M341.1 140.6c-2 3.9-1.6 8.6 1.2 12c7 8.5 12.9 18.1 17.2 28.4L408 160.2V120c0-13.3 10.7-24 24-24s24 10.7 24 24v19.6l22.5-9.7c12.2-5.2 26.3 .4 31.5 12.6s-.4 26.3-12.6 31.5l-56 24-73.6 31.5c-.5 9.5-2.1 18.6-4.8 27.3c-1.2 3.8-.1 8 2.8 10.8C396.7 296.9 416 338.2 416 384c0 44.7-18.3 85-47.8 114.1c-9.9 9.7-23.7 13.9-37.5 13.9H181.3c-13.9 0-27.7-4.2-37.5-13.9C114.3 469 96 428.7 96 384c0-45.8 19.3-87.1 50.1-116.3c2.9-2.8 4-6.9 2.8-10.8c-2.7-8.7-4.3-17.9-4.8-27.3L70.5 198.1l-56-24C2.4 168.8-3.3 154.7 1.9 142.5s19.3-17.8 31.5-12.6L56 139.6V120c0-13.3 10.7-24 24-24s24 10.7 24 24v40.2L152.6 181c4.3-10.3 10.1-19.9 17.2-28.4c2.8-3.4 3.3-8.1 1.2-12C164 127.2 160 112.1 160 96c0-53 43-96 96-96s96 43 96 96c0 16.1-4 31.2-10.9 44.6zM224 96a16 16 0 1 0 0-32 16 16 0 1 0 0 32zm48 128a16 16 0 1 0 -32 0 16 16 0 1 0 32 0zm-16 80a16 16 0 1 0 0-32 16 16 0 1 0 0 32zm16 48a16 16 0 1 0 -32 0 16 16 0 1 0 32 0zM288 96a16 16 0 1 0 0-32 16 16 0 1 0 0 32zm-48 24v3.2c0 3.2 .8 6.3 2.3 9l9 16.9c.9 1.7 2.7 2.8 4.7 2.8s3.8-1.1 4.7-2.8l9-16.9c1.5-2.8 2.3-5.9 2.3-9V120c0-8.8-7.2-16-16-16s-16 7.2-16 16z" } }, "free": ["solid"] }, "snowplow": { "aliases": { "unicodes": { "secondary": ["10f7d2"] } }, "changes": [ "5.6.0", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["clean up", "cold", "road", "storm", "winter"] }, "styles": ["solid"], "unicode": "f7d2", "label": "Snowplow", "voted": false, "svg": { "solid": { "last_modified": 1684767650, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M298.9 64l68.6 160H256l-64-64V64H298.9zM445.1 242.7l-87.4-204C347.6 15.3 324.5 0 298.9 0H176c-26.5 0-48 21.5-48 48V160H96c-17.7 0-32 14.3-32 32V298.8C26.2 316.8 0 355.3 0 400c0 61.9 50.1 112 112 112H368c61.9 0 112-50.1 112-112c0-17.2-3.9-33.5-10.8-48H512v50.7c0 17 6.7 33.3 18.7 45.3l54.6 54.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L576 402.7V320 235.2L633 164c11-13.8 8.8-33.9-5-45s-33.9-8.8-45 5l-57 71.2c-9.1 11.3-14 25.4-14 40V288H448V256.7c.1-2.4-.2-4.8-.6-7.1s-1.2-4.7-2.2-6.8zM368 352c26.5 0 48 21.5 48 48s-21.5 48-48 48H112c-26.5 0-48-21.5-48-48s21.5-48 48-48H368zM144 400a24 24 0 1 0 -48 0 24 24 0 1 0 48 0zm216 24a24 24 0 1 0 0-48 24 24 0 1 0 0 48zm-56-24a24 24 0 1 0 -48 0 24 24 0 1 0 48 0zM200 424a24 24 0 1 0 0-48 24 24 0 1 0 0 48z" } }, "free": ["solid"] }, "soap": { "aliases": { "unicodes": { "composite": ["1f9fc"], "secondary": ["10e06e"] } }, "changes": ["5.13.0", "5.14.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "bar", "bathing", "bubbles", "clean", "cleaning", "covid-19", "hygiene", "lather", "soap", "soapdish", "wash" ] }, "styles": ["solid"], "unicode": "e06e", "label": "Soap", "voted": false, "svg": { "solid": { "last_modified": 1684767444, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M208 96a48 48 0 1 0 0-96 48 48 0 1 0 0 96zM320 256a64 64 0 1 0 0-128 64 64 0 1 0 0 128zM416 32a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zm0 160c0 27.6-11.7 52.5-30.4 70.1C422.1 275.7 448 310.8 448 352c0 53-43 96-96 96H160c-53 0-96-43-96-96s43-96 96-96h88.4c-15.2-17-24.4-39.4-24.4-64H96c-53 0-96 43-96 96V416c0 53 43 96 96 96H416c53 0 96-43 96-96V288c0-53-43-96-96-96zM160 288c-35.3 0-64 28.7-64 64s28.7 64 64 64H352c35.3 0 64-28.7 64-64s-28.7-64-64-64H320 160z" } }, "free": ["solid"] }, "socks": { "aliases": { "unicodes": { "composite": ["1f9e6"], "secondary": ["10f696"] } }, "changes": ["5.3.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "business socks", "business time", "clothing", "feet", "flight of the conchords", "socks", "stocking", "wednesday" ] }, "styles": ["solid"], "unicode": "f696", "label": "Socks", "voted": false, "svg": { "solid": { "last_modified": 1684767602, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M175.2 476.6c-9.7-18-15.2-38.7-15.2-60.6c0-40.3 19-78.2 51.2-102.4l64-48c8.1-6 12.8-15.5 12.8-25.6V96H128V240c0 20.1-9.5 39.1-25.6 51.2l-64 48C14.2 357.3 0 385.8 0 416c0 53 43 96 96 96c20.8 0 41-6.7 57.6-19.2l21.6-16.2zM128 64H288V48c0-14.5 3.9-28.2 10.7-39.9C291 3 281.9 0 272 0H176c-26.5 0-48 21.5-48 48V64zM320 96V240c0 20.1-9.5 39.1-25.6 51.2l-64 48C206.2 357.3 192 385.8 192 416c0 53 43 96 96 96c20.8 0 41-6.7 57.6-19.2l115.2-86.4C493 382.2 512 344.3 512 304V96H320zM512 64V48c0-26.5-21.5-48-48-48H368c-26.5 0-48 21.5-48 48V64H512z" } }, "free": ["solid"] }, "solar-panel": { "aliases": { "unicodes": { "secondary": ["10f5ba"] } }, "changes": ["5.1.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["clean", "eco-friendly", "energy", "green", "sun"] }, "styles": ["solid"], "unicode": "f5ba", "label": "Solar Panel", "voted": false, "svg": { "solid": { "last_modified": 1684767662, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M122.2 0C91.7 0 65.5 21.5 59.5 51.4L8.3 307.4C.4 347 30.6 384 71 384H288v64H224c-17.7 0-32 14.3-32 32s14.3 32 32 32H416c17.7 0 32-14.3 32-32s-14.3-32-32-32H352V384H569c40.4 0 70.7-36.9 62.8-76.6l-51.2-256C574.5 21.5 548.3 0 517.8 0H122.2zM260.9 64H379.1l10.4 104h-139L260.9 64zM202.3 168H101.4L122.2 64h90.4L202.3 168zM91.8 216H197.5L187.1 320H71L91.8 216zm153.9 0H394.3l10.4 104-169.4 0 10.4-104zm196.8 0H548.2L569 320h-116L442.5 216zm96-48H437.7L427.3 64h90.4l31.4-6.3L517.8 64l20.8 104z" } }, "free": ["solid"] }, "sort": { "aliases": { "names": ["unsorted"], "unicodes": { "secondary": ["10f0dc"] } }, "changes": [ "2.0.0", "5.0.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["filter", "order"] }, "styles": ["solid"], "unicode": "f0dc", "label": "Sort", "voted": false, "svg": { "solid": { "last_modified": 1684766331, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M137.4 41.4c12.5-12.5 32.8-12.5 45.3 0l128 128c9.2 9.2 11.9 22.9 6.9 34.9s-16.6 19.8-29.6 19.8H32c-12.9 0-24.6-7.8-29.6-19.8s-2.2-25.7 6.9-34.9l128-128zm0 429.3l-128-128c-9.2-9.2-11.9-22.9-6.9-34.9s16.6-19.8 29.6-19.8H288c12.9 0 24.6 7.8 29.6 19.8s2.2 25.7-6.9 34.9l-128 128c-12.5 12.5-32.8 12.5-45.3 0z" } }, "free": ["solid"] }, "sort-down": { "aliases": { "names": ["sort-desc"], "unicodes": { "secondary": ["10f0dd"] } }, "changes": [ "2.0.0", "5.0.0", "5.10.1", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["arrow", "descending", "filter", "order", "sort-desc"] }, "styles": ["solid"], "unicode": "f0dd", "label": "Sort Down", "voted": false, "svg": { "solid": { "last_modified": 1684766332, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M182.6 470.6c-12.5 12.5-32.8 12.5-45.3 0l-128-128c-9.2-9.2-11.9-22.9-6.9-34.9s16.6-19.8 29.6-19.8H288c12.9 0 24.6 7.8 29.6 19.8s2.2 25.7-6.9 34.9l-128 128z" } }, "free": ["solid"] }, "sort-up": { "aliases": { "names": ["sort-asc"], "unicodes": { "secondary": ["10f0de"] } }, "changes": [ "2.0.0", "5.0.0", "5.10.1", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["arrow", "ascending", "filter", "order", "sort-asc"] }, "styles": ["solid"], "unicode": "f0de", "label": "Sort Up", "voted": false, "svg": { "solid": { "last_modified": 1684766330, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M182.6 41.4c-12.5-12.5-32.8-12.5-45.3 0l-128 128c-9.2 9.2-11.9 22.9-6.9 34.9s16.6 19.8 29.6 19.8H288c12.9 0 24.6-7.8 29.6-19.8s2.2-25.7-6.9-34.9l-128-128z" } }, "free": ["solid"] }, "soundcloud": { "changes": ["4.1.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f1be", "label": "SoundCloud", "voted": false, "svg": { "brands": { "last_modified": 1660014468, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M111.4 256.3l5.8 65-5.8 68.3c-.3 2.5-2.2 4.4-4.4 4.4s-4.2-1.9-4.2-4.4l-5.6-68.3 5.6-65c0-2.2 1.9-4.2 4.2-4.2 2.2 0 4.1 2 4.4 4.2zm21.4-45.6c-2.8 0-4.7 2.2-5 5l-5 105.6 5 68.3c.3 2.8 2.2 5 5 5 2.5 0 4.7-2.2 4.7-5l5.8-68.3-5.8-105.6c0-2.8-2.2-5-4.7-5zm25.5-24.1c-3.1 0-5.3 2.2-5.6 5.3l-4.4 130 4.4 67.8c.3 3.1 2.5 5.3 5.6 5.3 2.8 0 5.3-2.2 5.3-5.3l5.3-67.8-5.3-130c0-3.1-2.5-5.3-5.3-5.3zM7.2 283.2c-1.4 0-2.2 1.1-2.5 2.5L0 321.3l4.7 35c.3 1.4 1.1 2.5 2.5 2.5s2.2-1.1 2.5-2.5l5.6-35-5.6-35.6c-.3-1.4-1.1-2.5-2.5-2.5zm23.6-21.9c-1.4 0-2.5 1.1-2.5 2.5l-6.4 57.5 6.4 56.1c0 1.7 1.1 2.8 2.5 2.8s2.5-1.1 2.8-2.5l7.2-56.4-7.2-57.5c-.3-1.4-1.4-2.5-2.8-2.5zm25.3-11.4c-1.7 0-3.1 1.4-3.3 3.3L47 321.3l5.8 65.8c.3 1.7 1.7 3.1 3.3 3.1 1.7 0 3.1-1.4 3.1-3.1l6.9-65.8-6.9-68.1c0-1.9-1.4-3.3-3.1-3.3zm25.3-2.2c-1.9 0-3.6 1.4-3.6 3.6l-5.8 70 5.8 67.8c0 2.2 1.7 3.6 3.6 3.6s3.6-1.4 3.9-3.6l6.4-67.8-6.4-70c-.3-2.2-2-3.6-3.9-3.6zm241.4-110.9c-1.1-.8-2.8-1.4-4.2-1.4-2.2 0-4.2.8-5.6 1.9-1.9 1.7-3.1 4.2-3.3 6.7v.8l-3.3 176.7 1.7 32.5 1.7 31.7c.3 4.7 4.2 8.6 8.9 8.6s8.6-3.9 8.6-8.6l3.9-64.2-3.9-177.5c-.4-3-2-5.8-4.5-7.2zm-26.7 15.3c-1.4-.8-2.8-1.4-4.4-1.4s-3.1.6-4.4 1.4c-2.2 1.4-3.6 3.9-3.6 6.7l-.3 1.7-2.8 160.8s0 .3 3.1 65.6v.3c0 1.7.6 3.3 1.7 4.7 1.7 1.9 3.9 3.1 6.4 3.1 2.2 0 4.2-1.1 5.6-2.5 1.7-1.4 2.5-3.3 2.5-5.6l.3-6.7 3.1-58.6-3.3-162.8c-.3-2.8-1.7-5.3-3.9-6.7zm-111.4 22.5c-3.1 0-5.8 2.8-5.8 6.1l-4.4 140.6 4.4 67.2c.3 3.3 2.8 5.8 5.8 5.8 3.3 0 5.8-2.5 6.1-5.8l5-67.2-5-140.6c-.2-3.3-2.7-6.1-6.1-6.1zm376.7 62.8c-10.8 0-21.1 2.2-30.6 6.1-6.4-70.8-65.8-126.4-138.3-126.4-17.8 0-35 3.3-50.3 9.4-6.1 2.2-7.8 4.4-7.8 9.2v249.7c0 5 3.9 8.6 8.6 9.2h218.3c43.3 0 78.6-35 78.6-78.3.1-43.6-35.2-78.9-78.5-78.9zm-296.7-60.3c-4.2 0-7.5 3.3-7.8 7.8l-3.3 136.7 3.3 65.6c.3 4.2 3.6 7.5 7.8 7.5 4.2 0 7.5-3.3 7.5-7.5l3.9-65.6-3.9-136.7c-.3-4.5-3.3-7.8-7.5-7.8zm-53.6-7.8c-3.3 0-6.4 3.1-6.4 6.7l-3.9 145.3 3.9 66.9c.3 3.6 3.1 6.4 6.4 6.4 3.6 0 6.4-2.8 6.7-6.4l4.4-66.9-4.4-145.3c-.3-3.6-3.1-6.7-6.7-6.7zm26.7 3.4c-3.9 0-6.9 3.1-6.9 6.9L227 321.3l3.9 66.4c.3 3.9 3.1 6.9 6.9 6.9s6.9-3.1 6.9-6.9l4.2-66.4-4.2-141.7c0-3.9-3-6.9-6.9-6.9z" } }, "free": ["brands"] }, "sourcetree": { "changes": ["5.6.0", "5.8.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f7d3", "label": "Sourcetree", "voted": true, "svg": { "brands": { "last_modified": 1660014480, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M427.2 203c0-112.1-90.9-203-203-203C112.1-.2 21.2 90.6 21 202.6A202.86 202.86 0 0 0 161.5 396v101.7a14.3 14.3 0 0 0 14.3 14.3h96.4a14.3 14.3 0 0 0 14.3-14.3V396.1A203.18 203.18 0 0 0 427.2 203zm-271.6 0c0-90.8 137.3-90.8 137.3 0-.1 89.9-137.3 91-137.3 0z" } }, "free": ["brands"] }, "spa": { "aliases": { "unicodes": { "secondary": ["10f5bb"] } }, "changes": ["5.1.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["flora", "massage", "mindfulness", "plant", "wellness"] }, "styles": ["solid"], "unicode": "f5bb", "label": "Spa", "voted": false, "svg": { "solid": { "last_modified": 1684767443, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M183.1 235.3c33.7 20.7 62.9 48.1 85.8 80.5c7 9.9 13.4 20.3 19.1 31c5.7-10.8 12.1-21.1 19.1-31c22.9-32.4 52.1-59.8 85.8-80.5C437.6 207.8 490.1 192 546 192h9.9c11.1 0 20.1 9 20.1 20.1C576 360.1 456.1 480 308.1 480H288 267.9C119.9 480 0 360.1 0 212.1C0 201 9 192 20.1 192H30c55.9 0 108.4 15.8 153.1 43.3zM301.5 37.6c15.7 16.9 61.1 71.8 84.4 164.6c-38 21.6-71.4 50.8-97.9 85.6c-26.5-34.8-59.9-63.9-97.9-85.6c23.2-92.8 68.6-147.7 84.4-164.6C278 33.9 282.9 32 288 32s10 1.9 13.5 5.6z" } }, "free": ["solid"] }, "space-awesome": { "changes": ["6.1.2"], "ligatures": [], "search": { "terms": ["adventure", "rocket", "ship", "shuttle"] }, "styles": ["brands"], "unicode": "e5ac", "label": "Space Awesome", "voted": false, "svg": { "brands": { "last_modified": 1660014463, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M96 256H128V512H0V352H32V320H64V288H96V256zM512 352V512H384V256H416V288H448V320H480V352H512zM320 64H352V448H320V416H192V448H160V64H192V32H224V0H288V32H320V64zM288 128H224V192H288V128z" } }, "free": ["brands"] }, "spaghetti-monster-flying": { "aliases": { "names": ["pastafarianism"], "unicodes": { "secondary": ["10f67b"] } }, "changes": ["5.3.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["agnosticism", "atheism", "flying spaghetti monster", "fsm"] }, "styles": ["solid"], "unicode": "f67b", "label": "Spaghetti Monster Flying", "voted": false, "svg": { "solid": { "last_modified": 1684767603, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M208 64a16 16 0 1 0 -32 0 16 16 0 1 0 32 0zm48 0c0 16.2-6 31.1-16 42.3l15.6 31.2c18.7-6 39.9-9.5 64.4-9.5s45.8 3.5 64.4 9.5L400 106.3C390 95.1 384 80.2 384 64c0-35.3 28.7-64 64-64s64 28.7 64 64s-28.7 64-64 64c-1.7 0-3.4-.1-5.1-.2L427.8 158c21.1 13.6 37.7 30.2 51.4 46.4c7.1 8.3 13.5 16.6 19.3 24l1.4 1.8c6.3 8.1 11.6 14.8 16.7 20.4C527.3 262.3 532.7 264 536 264c2.5 0 4.3-.6 7.1-3.3c3.7-3.5 7.1-8.8 12.5-17.4l.6-.9c4.6-7.4 11-17.6 19.4-25.7c9.7-9.3 22.9-16.7 40.4-16.7c13.3 0 24 10.7 24 24s-10.7 24-24 24c-2.5 0-4.3 .6-7.1 3.3c-3.7 3.5-7.1 8.8-12.5 17.4l-.6 .9c-4.6 7.4-11 17.6-19.4 25.7c-9.7 9.3-22.9 16.7-40.4 16.7c-18.5 0-32.9-8.5-44.3-18.6c-3.1 4-6.6 8.3-10.5 12.7c1.4 4.3 2.8 8.5 4 12.5c.9 3 1.8 5.8 2.6 8.6c3 9.8 5.5 18.2 8.6 25.9c3.9 9.8 7.4 15.4 10.8 18.5c2.6 2.4 5.9 4.3 12.8 4.3c8.7 0 16.9-4.2 33.7-13.2c15-8 35.7-18.8 62.3-18.8c13.3 0 24 10.7 24 24s-10.7 24-24 24c-13.4 0-24.7 5.2-39.7 13.2c-1 .6-2.1 1.1-3.2 1.7C559.9 414 541.4 424 520 424c-18.4 0-33.6-6.1-45.5-17.2c-11.1-10.3-17.9-23.7-22.7-36c-3.6-9-6.7-19.1-9.5-28.5c-16.4 12.3-36.1 23.6-58.9 31.3c3.6 10.8 8.4 23.5 14.4 36.2c7.5 15.9 16.2 30.4 25.8 40.5C433 460.5 441.2 464 448 464c13.3 0 24 10.7 24 24s-10.7 24-24 24c-25.2 0-45-13.5-59.5-28.8c-14.5-15.4-25.7-34.9-34.2-53c-8-17-14.1-33.8-18.3-46.9c-5.2 .4-10.6 .6-16 .6s-10.8-.2-16-.6c-4.2 13-10.3 29.9-18.3 46.9c-8.5 18.1-19.8 37.6-34.2 53C237 498.5 217.2 512 192 512c-13.3 0-24-10.7-24-24s10.7-24 24-24c6.8 0 15-3.5 24.5-13.7c9.5-10.1 18.3-24.6 25.8-40.5c5.9-12.6 10.7-25.4 14.4-36.2c-22.8-7.7-42.5-19-58.9-31.3c-2.9 9.4-6 19.5-9.5 28.5c-4.8 12.2-11.6 25.6-22.7 36C153.6 417.9 138.4 424 120 424c-21.4 0-39.9-10-53.1-17.1l0 0c-1.1-.6-2.2-1.2-3.2-1.7c-15-8-26.3-13.2-39.7-13.2c-13.3 0-24-10.7-24-24s10.7-24 24-24c26.6 0 47.3 10.8 62.3 18.8c16.8 9 25 13.2 33.7 13.2c6.8 0 10.2-1.9 12.8-4.3c3.4-3.2 7-8.8 10.8-18.5c3-7.7 5.6-16.1 8.6-25.9c.8-2.7 1.7-5.6 2.6-8.6c1.2-4 2.6-8.2 4-12.5c-3.9-4.5-7.4-8.8-10.5-12.7C136.9 303.5 122.5 312 104 312c-17.5 0-30.7-7.4-40.4-16.7c-8.4-8.1-14.8-18.3-19.4-25.7l-.6-.9c-5.4-8.6-8.8-13.9-12.5-17.4c-2.8-2.7-4.6-3.3-7.1-3.3c-13.3 0-24-10.7-24-24s10.7-24 24-24c17.5 0 30.7 7.4 40.4 16.7c8.4 8.1 14.8 18.3 19.4 25.7l.6 .9c5.4 8.6 8.8 13.9 12.5 17.4c2.8 2.7 4.6 3.3 7.1 3.3c3.3 0 8.7-1.7 19.4-13.4c5.1-5.6 10.4-12.3 16.7-20.4l1.4-1.8c5.8-7.4 12.2-15.7 19.3-24c13.8-16.2 30.3-32.8 51.4-46.4l-15.1-30.2c-1.7 .1-3.4 .2-5.1 .2c-35.3 0-64-28.7-64-64s28.7-64 64-64s64 28.7 64 64zm208 0a16 16 0 1 0 -32 0 16 16 0 1 0 32 0z" } }, "free": ["solid"] }, "speakap": { "changes": ["5.0.0", "5.4.0", "5.8.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3f3", "label": "Speakap", "voted": false, "svg": { "brands": { "last_modified": 1660014473, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M64 391.78C-15.41 303.59-8 167.42 80.64 87.64s224.8-73 304.21 15.24 72 224.36-16.64 304.14c-18.74 16.87 64 43.09 42 52.26-82.06 34.21-253.91 35-346.23-67.5zm213.31-211.6l38.5-40.86c-9.61-8.89-32-26.83-76.17-27.6-52.33-.91-95.86 28.3-96.77 80-.2 11.33.29 36.72 29.42 54.83 34.46 21.42 86.52 21.51 86 52.26-.37 21.28-26.42 25.81-38.59 25.6-3-.05-30.23-.46-47.61-24.62l-40 42.61c28.16 27 59 32.62 83.49 33.05 10.23.18 96.42.33 97.84-81 .28-15.81-2.07-39.72-28.86-56.59-34.36-21.64-85-19.45-84.43-49.75.41-23.25 31-25.37 37.53-25.26.43 0 26.62.26 39.62 17.37z" } }, "free": ["brands"] }, "speaker-deck": { "changes": ["5.8.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f83c", "label": "Speaker Deck", "voted": false, "svg": { "brands": { "last_modified": 1660014470, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M213.86 296H100a100 100 0 0 1 0-200h132.84a40 40 0 0 1 0 80H98c-26.47 0-26.45 40 0 40h113.82a100 100 0 0 1 0 200H40a40 40 0 0 1 0-80h173.86c26.48 0 26.46-40 0-40zM298 416a120.21 120.21 0 0 0 51.11-80h64.55a19.83 19.83 0 0 0 19.66-20V196a19.83 19.83 0 0 0-19.66-20H296.42a60.77 60.77 0 0 0 0-80h136.93c43.44 0 78.65 35.82 78.65 80v160c0 44.18-35.21 80-78.65 80z" } }, "free": ["brands"] }, "spell-check": { "aliases": { "unicodes": { "secondary": ["10f891"] } }, "changes": ["5.9.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["dictionary", "edit", "editor", "grammar", "text"] }, "styles": ["solid"], "unicode": "f891", "label": "Spell Check", "voted": false, "svg": { "solid": { "last_modified": 1684767247, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M112 0C99.1 0 87.4 7.8 82.5 19.7l-66.7 160-13.3 32c-6.8 16.3 .9 35 17.2 41.8s35-.9 41.8-17.2L66.7 224h90.7l5.1 12.3c6.8 16.3 25.5 24 41.8 17.2s24-25.5 17.2-41.8l-13.3-32-66.7-160C136.6 7.8 124.9 0 112 0zm18.7 160H93.3L112 115.2 130.7 160zM256 32v96 96c0 17.7 14.3 32 32 32h80c44.2 0 80-35.8 80-80c0-23.1-9.8-43.8-25.4-58.4c6-11.2 9.4-24 9.4-37.6c0-44.2-35.8-80-80-80H288c-17.7 0-32 14.3-32 32zm96 64H320V64h32c8.8 0 16 7.2 16 16s-7.2 16-16 16zm-32 64h32 16c8.8 0 16 7.2 16 16s-7.2 16-16 16H320V160zM566.6 310.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L352 434.7l-73.4-73.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l96 96c12.5 12.5 32.8 12.5 45.3 0l192-192z" } }, "free": ["solid"] }, "spider": { "aliases": { "unicodes": { "composite": ["1f577"], "secondary": ["10f717"] } }, "changes": ["5.4.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "arachnid", "bug", "charlotte", "crawl", "eight", "halloween", "insect", "spider" ] }, "styles": ["solid"], "unicode": "f717", "label": "Spider", "voted": true, "svg": { "solid": { "last_modified": 1684768131, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M158.4 32.6c4.8-12.4-1.4-26.3-13.8-31s-26.3 1.4-31 13.8L81.1 100c-7.9 20.7-3 44.1 12.7 59.7l57.4 57.4L70.8 190.3c-2.4-.8-4.3-2.7-5.1-5.1L46.8 128.4C42.6 115.8 29 109 16.4 113.2S-3 131 1.2 143.6l18.9 56.8c5.6 16.7 18.7 29.8 35.4 35.4L116.1 256 55.6 276.2c-16.7 5.6-29.8 18.7-35.4 35.4L1.2 368.4C-3 381 3.8 394.6 16.4 398.8s26.2-2.6 30.4-15.2l18.9-56.8c.8-2.4 2.7-4.3 5.1-5.1l80.4-26.8L93.7 352.3C78.1 368 73.1 391.4 81.1 412l32.5 84.6c4.8 12.4 18.6 18.5 31 13.8s18.5-18.6 13.8-31l-32.5-84.6c-1.1-3-.4-6.3 1.8-8.5L160 353.9c1 52.1 43.6 94.1 96 94.1s95-41.9 96-94.1l32.3 32.3c2.2 2.2 2.9 5.6 1.8 8.5l-32.5 84.6c-4.8 12.4 1.4 26.3 13.8 31s26.3-1.4 31-13.8L430.9 412c7.9-20.7 3-44.1-12.7-59.7l-57.4-57.4 80.4 26.8c2.4 .8 4.3 2.7 5.1 5.1l18.9 56.8c4.2 12.6 17.8 19.4 30.4 15.2s19.4-17.8 15.2-30.4l-18.9-56.8c-5.6-16.7-18.7-29.8-35.4-35.4L395.9 256l60.5-20.2c16.7-5.6 29.8-18.7 35.4-35.4l18.9-56.8c4.2-12.6-2.6-26.2-15.2-30.4s-26.2 2.6-30.4 15.2l-18.9 56.8c-.8 2.4-2.7 4.3-5.1 5.1l-80.4 26.8 57.4-57.4c15.6-15.6 20.6-39 12.7-59.7L398.4 15.4C393.6 3 379.8-3.2 367.4 1.6s-18.5 18.6-13.8 31l32.5 84.6c1.1 3 .4 6.3-1.8 8.5L336 174.1V160c0-31.8-18.6-59.3-45.5-72.2c-9.1-4.4-18.5 3.3-18.5 13.4V112c0 8.8-7.2 16-16 16s-16-7.2-16-16V101.2c0-10.1-9.4-17.7-18.5-13.4C194.6 100.7 176 128.2 176 160v14.1l-48.3-48.3c-2.2-2.2-2.9-5.6-1.8-8.5l32.5-84.6z" } }, "free": ["solid"] }, "spinner": { "aliases": { "unicodes": { "secondary": ["10f110"] } }, "changes": [ "3.0.0", "5.0.0", "5.10.2", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["circle", "loading", "progress"] }, "styles": ["solid"], "unicode": "f110", "label": "Spinner", "voted": false, "svg": { "solid": { "last_modified": 1684767551, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M304 48a48 48 0 1 0 -96 0 48 48 0 1 0 96 0zm0 416a48 48 0 1 0 -96 0 48 48 0 1 0 96 0zM48 304a48 48 0 1 0 0-96 48 48 0 1 0 0 96zm464-48a48 48 0 1 0 -96 0 48 48 0 1 0 96 0zM142.9 437A48 48 0 1 0 75 369.1 48 48 0 1 0 142.9 437zm0-294.2A48 48 0 1 0 75 75a48 48 0 1 0 67.9 67.9zM369.1 437A48 48 0 1 0 437 369.1 48 48 0 1 0 369.1 437z" } }, "free": ["solid"] }, "splotch": { "aliases": { "unicodes": { "secondary": ["10f5bc"] } }, "changes": ["5.1.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Ink", "blob", "blotch", "glob", "stain"] }, "styles": ["solid"], "unicode": "f5bc", "label": "Splotch", "voted": false, "svg": { "solid": { "last_modified": 1684767366, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M208.5 62.3l28.1-36.9C248.8 9.4 267.8 0 288 0c28.5 0 53.6 18.7 61.8 46l17.8 59.4c10.3 34.4 36.1 62 69.8 74.6l39.8 14.9c20.9 7.9 34.8 27.9 34.8 50.2c0 16.9-7.9 32.8-21.5 42.9l-67.3 50.5c-24.3 18.2-37.2 47.9-33.8 78.1l2.5 22.7c4.3 38.7-26 72.6-65 72.6c-14.8 0-29.3-5.1-40.8-14.3l-55.4-44.3c-4.5-3.6-9.3-6.7-14.5-9.2c-15.8-7.9-33.7-10.4-51-7.3L82.4 451.9C47.8 458.2 16 431.6 16 396.5c0-13.2 4.7-26 13.1-36.2l11.2-13.4c14.6-17.4 22.6-39.4 22.6-62.1c0-18.8-5.5-37.2-15.8-53L8.8 173.5C3.1 164.7 0 154.4 0 143.9c0-33.4 30.1-58.8 63-53.2l51.3 8.7c35.9 6.1 72.2-8.2 94.2-37.1z" } }, "free": ["solid"] }, "spoon": { "aliases": { "names": ["utensil-spoon"], "unicodes": { "composite": ["1f944", "f1b1"], "secondary": ["10f2e5"] } }, "changes": [ "5.0.0", "5.10.2", "6.0.0-beta1", "6.0.0-beta2", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "cutlery", "dining", "scoop", "silverware", "spoon", "tableware" ] }, "styles": ["solid"], "unicode": "f2e5", "label": "Spoon", "voted": false, "svg": { "solid": { "last_modified": 1684767421, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M245.8 220.9c-14.5-17.6-21.8-39.2-21.8-60.8C224 80 320 0 416 0c53 0 96 43 96 96c0 96-80 192-160.2 192c-21.6 0-43.2-7.3-60.8-21.8L54.6 502.6c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L245.8 220.9z" } }, "free": ["solid"] }, "spotify": { "changes": ["4.1.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f1bc", "label": "Spotify", "voted": false, "svg": { "brands": { "last_modified": 1660014469, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M248 8C111.1 8 0 119.1 0 256s111.1 248 248 248 248-111.1 248-248S384.9 8 248 8zm100.7 364.9c-4.2 0-6.8-1.3-10.7-3.6-62.4-37.6-135-39.2-206.7-24.5-3.9 1-9 2.6-11.9 2.6-9.7 0-15.8-7.7-15.8-15.8 0-10.3 6.1-15.2 13.6-16.8 81.9-18.1 165.6-16.5 237 26.2 6.1 3.9 9.7 7.4 9.7 16.5s-7.1 15.4-15.2 15.4zm26.9-65.6c-5.2 0-8.7-2.3-12.3-4.2-62.5-37-155.7-51.9-238.6-29.4-4.8 1.3-7.4 2.6-11.9 2.6-10.7 0-19.4-8.7-19.4-19.4s5.2-17.8 15.5-20.7c27.8-7.8 56.2-13.6 97.8-13.6 64.9 0 127.6 16.1 177 45.5 8.1 4.8 11.3 11 11.3 19.7-.1 10.8-8.5 19.5-19.4 19.5zm31-76.2c-5.2 0-8.4-1.3-12.9-3.9-71.2-42.5-198.5-52.7-280.9-29.7-3.6 1-8.1 2.6-12.9 2.6-13.2 0-23.3-10.3-23.3-23.6 0-13.6 8.4-21.3 17.4-23.9 35.2-10.3 74.6-15.2 117.5-15.2 73 0 149.5 15.2 205.4 47.8 7.8 4.5 12.9 10.7 12.9 22.6 0 13.6-11 23.3-23.2 23.3z" } }, "free": ["brands"] }, "spray-can": { "aliases": { "unicodes": { "secondary": ["10f5bd"] } }, "changes": ["5.1.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Paint", "aerosol", "design", "graffiti", "tag"] }, "styles": ["solid"], "unicode": "f5bd", "label": "Spray Can", "voted": false, "svg": { "solid": { "last_modified": 1684767368, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M128 0h64c17.7 0 32 14.3 32 32v96H96V32c0-17.7 14.3-32 32-32zM0 256c0-53 43-96 96-96H224c53 0 96 43 96 96V464c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V256zm240 80A80 80 0 1 0 80 336a80 80 0 1 0 160 0zM256 64a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zM384 32a32 32 0 1 1 0 64 32 32 0 1 1 0-64zm64 32a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm32 64a32 32 0 1 1 0 64 32 32 0 1 1 0-64zM448 256a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zM384 128a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" } }, "free": ["solid"] }, "spray-can-sparkles": { "aliases": { "names": ["air-freshener"], "unicodes": { "secondary": ["10f5d0"] } }, "changes": [ "5.2.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["car", "clean", "deodorize", "fresh", "pine", "scent"] }, "styles": ["solid"], "unicode": "f5d0", "label": "Spray Can Sparkles", "voted": false, "svg": { "solid": { "last_modified": 1684767489, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M96 32v96H224V32c0-17.7-14.3-32-32-32H128C110.3 0 96 14.3 96 32zm0 128c-53 0-96 43-96 96V464c0 26.5 21.5 48 48 48H272c26.5 0 48-21.5 48-48V256c0-53-43-96-96-96H96zm64 96a80 80 0 1 1 0 160 80 80 0 1 1 0-160zM384 48c0-1.4-1-3-2.2-3.6L352 32 339.6 2.2C339 1 337.4 0 336 0s-3 1-3.6 2.2L320 32 290.2 44.4C289 45 288 46.6 288 48c0 1.4 1 3 2.2 3.6L320 64l12.4 29.8C333 95 334.6 96 336 96s3-1 3.6-2.2L352 64l29.8-12.4C383 51 384 49.4 384 48zm76.4 45.8C461 95 462.6 96 464 96s3-1 3.6-2.2L480 64l29.8-12.4C511 51 512 49.4 512 48c0-1.4-1-3-2.2-3.6L480 32 467.6 2.2C467 1 465.4 0 464 0s-3 1-3.6 2.2L448 32 418.2 44.4C417 45 416 46.6 416 48c0 1.4 1 3 2.2 3.6L448 64l12.4 29.8zm7.2 100.4c-.6-1.2-2.2-2.2-3.6-2.2s-3 1-3.6 2.2L448 224l-29.8 12.4c-1.2 .6-2.2 2.2-2.2 3.6c0 1.4 1 3 2.2 3.6L448 256l12.4 29.8c.6 1.2 2.2 2.2 3.6 2.2s3-1 3.6-2.2L480 256l29.8-12.4c1.2-.6 2.2-2.2 2.2-3.6c0-1.4-1-3-2.2-3.6L480 224l-12.4-29.8zM448 144c0-1.4-1-3-2.2-3.6L416 128 403.6 98.2C403 97 401.4 96 400 96s-3 1-3.6 2.2L384 128l-29.8 12.4c-1.2 .6-2.2 2.2-2.2 3.6c0 1.4 1 3 2.2 3.6L384 160l12.4 29.8c.6 1.2 2.2 2.2 3.6 2.2s3-1 3.6-2.2L416 160l29.8-12.4c1.2-.6 2.2-2.2 2.2-3.6z" } }, "free": ["solid"] }, "square": { "aliases": { "unicodes": { "composite": ["25a0", "25fb", "25fc", "f096"], "secondary": ["10f0c8"] } }, "changes": [ "2.0.0", "5.0.0", "5.10.1", "5.10.2", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Black Square", "black medium square", "block", "box", "geometric", "shape", "square", "white medium square" ] }, "styles": ["solid", "regular"], "unicode": "f0c8", "label": "Square", "voted": false, "svg": { "solid": { "last_modified": 1684767552, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M0 96C0 60.7 28.7 32 64 32H384c35.3 0 64 28.7 64 64V416c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V96z" }, "regular": { "last_modified": 1684767552, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M384 80c8.8 0 16 7.2 16 16V416c0 8.8-7.2 16-16 16H64c-8.8 0-16-7.2-16-16V96c0-8.8 7.2-16 16-16H384zM64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64z" } }, "free": ["regular", "solid"] }, "square-arrow-up-right": { "aliases": { "names": ["external-link-square"], "unicodes": { "secondary": ["10f14c"] } }, "changes": ["3.1.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["diagonal", "new", "open", "send", "share"] }, "styles": ["solid"], "unicode": "f14c", "label": "Square Arrow Up Right", "voted": false, "svg": { "solid": { "last_modified": 1684766331, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M384 32c35.3 0 64 28.7 64 64V416c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V96C0 60.7 28.7 32 64 32H384zM160 144c-13.3 0-24 10.7-24 24s10.7 24 24 24h94.1L119 327c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l135-135V328c0 13.3 10.7 24 24 24s24-10.7 24-24V168c0-13.3-10.7-24-24-24H160z" } }, "free": ["solid"] }, "square-behance": { "aliases": { "names": ["behance-square"] }, "changes": ["4.1.0", "5.0.0", "5.0.3", "6.1.2"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f1b5", "label": "Behance Square", "voted": false, "svg": { "brands": { "last_modified": 1660014463, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M186.5 293c0 19.3-14 25.4-31.2 25.4h-45.1v-52.9h46c18.6.1 30.3 7.8 30.3 27.5zm-7.7-82.3c0-17.7-13.7-21.9-28.9-21.9h-39.6v44.8H153c15.1 0 25.8-6.6 25.8-22.9zm132.3 23.2c-18.3 0-30.5 11.4-31.7 29.7h62.2c-1.7-18.5-11.3-29.7-30.5-29.7zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zM271.7 185h77.8v-18.9h-77.8V185zm-43 110.3c0-24.1-11.4-44.9-35-51.6 17.2-8.2 26.2-17.7 26.2-37 0-38.2-28.5-47.5-61.4-47.5H68v192h93.1c34.9-.2 67.6-16.9 67.6-55.9zM380 280.5c0-41.1-24.1-75.4-67.6-75.4-42.4 0-71.1 31.8-71.1 73.6 0 43.3 27.3 73 71.1 73 33.2 0 54.7-14.9 65.1-46.8h-33.7c-3.7 11.9-18.6 18.1-30.2 18.1-22.4 0-34.1-13.1-34.1-35.3h100.2c.1-2.3.3-4.8.3-7.2z" } }, "free": ["brands"] }, "square-caret-down": { "aliases": { "names": ["caret-square-down"], "unicodes": { "secondary": ["10f150"] } }, "changes": ["3.2.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "arrow", "caret-square-o-down", "dropdown", "expand", "menu", "more", "triangle" ] }, "styles": ["solid", "regular"], "unicode": "f150", "label": "Square Caret Down", "voted": false, "svg": { "solid": { "last_modified": 1684766332, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M384 480c35.3 0 64-28.7 64-64l0-320c0-35.3-28.7-64-64-64L64 32C28.7 32 0 60.7 0 96L0 416c0 35.3 28.7 64 64 64l320 0zM224 352c-6.7 0-13-2.8-17.6-7.7l-104-112c-6.5-7-8.2-17.2-4.4-25.9s12.5-14.4 22-14.4l208 0c9.5 0 18.2 5.7 22 14.4s2.1 18.9-4.4 25.9l-104 112c-4.5 4.9-10.9 7.7-17.6 7.7z" }, "regular": { "last_modified": 1684766332, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M384 432c8.8 0 16-7.2 16-16l0-320c0-8.8-7.2-16-16-16L64 80c-8.8 0-16 7.2-16 16l0 320c0 8.8 7.2 16 16 16l320 0zm64-16c0 35.3-28.7 64-64 64L64 480c-35.3 0-64-28.7-64-64L0 96C0 60.7 28.7 32 64 32l320 0c35.3 0 64 28.7 64 64l0 320zM224 352c-6.7 0-13-2.8-17.6-7.7l-104-112c-6.5-7-8.2-17.2-4.4-25.9s12.5-14.4 22-14.4l208 0c9.5 0 18.2 5.7 22 14.4s2.1 18.9-4.4 25.9l-104 112c-4.5 4.9-10.9 7.7-17.6 7.7z" } }, "free": ["regular", "solid"] }, "square-caret-left": { "aliases": { "names": ["caret-square-left"], "unicodes": { "secondary": ["10f191"] } }, "changes": ["4.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["arrow", "back", "caret-square-o-left", "previous", "triangle"] }, "styles": ["solid", "regular"], "unicode": "f191", "label": "Square Caret Left", "voted": false, "svg": { "solid": { "last_modified": 1684766331, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M0 416c0 35.3 28.7 64 64 64l320 0c35.3 0 64-28.7 64-64l0-320c0-35.3-28.7-64-64-64L64 32C28.7 32 0 60.7 0 96L0 416zM128 256c0-6.7 2.8-13 7.7-17.6l112-104c7-6.5 17.2-8.2 25.9-4.4s14.4 12.5 14.4 22l0 208c0 9.5-5.7 18.2-14.4 22s-18.9 2.1-25.9-4.4l-112-104c-4.9-4.5-7.7-10.9-7.7-17.6z" }, "regular": { "last_modified": 1684766331, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M48 416c0 8.8 7.2 16 16 16l320 0c8.8 0 16-7.2 16-16l0-320c0-8.8-7.2-16-16-16L64 80c-8.8 0-16 7.2-16 16l0 320zm16 64c-35.3 0-64-28.7-64-64L0 96C0 60.7 28.7 32 64 32l320 0c35.3 0 64 28.7 64 64l0 320c0 35.3-28.7 64-64 64L64 480zm64-224c0-6.7 2.8-13 7.7-17.6l112-104c7-6.5 17.2-8.2 25.9-4.4s14.4 12.5 14.4 22l0 208c0 9.5-5.7 18.2-14.4 22s-18.9 2.1-25.9-4.4l-112-104c-4.9-4.5-7.7-10.9-7.7-17.6z" } }, "free": ["regular", "solid"] }, "square-caret-right": { "aliases": { "names": ["caret-square-right"], "unicodes": { "secondary": ["10f152"] } }, "changes": ["3.2.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["arrow", "caret-square-o-right", "forward", "next", "triangle"] }, "styles": ["solid", "regular"], "unicode": "f152", "label": "Square Caret Right", "voted": false, "svg": { "solid": { "last_modified": 1684766332, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M448 96c0-35.3-28.7-64-64-64L64 32C28.7 32 0 60.7 0 96L0 416c0 35.3 28.7 64 64 64l320 0c35.3 0 64-28.7 64-64l0-320zM320 256c0 6.7-2.8 13-7.7 17.6l-112 104c-7 6.5-17.2 8.2-25.9 4.4s-14.4-12.5-14.4-22l0-208c0-9.5 5.7-18.2 14.4-22s18.9-2.1 25.9 4.4l112 104c4.9 4.5 7.7 10.9 7.7 17.6z" }, "regular": { "last_modified": 1684766332, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M400 96c0-8.8-7.2-16-16-16L64 80c-8.8 0-16 7.2-16 16l0 320c0 8.8 7.2 16 16 16l320 0c8.8 0 16-7.2 16-16l0-320zM384 32c35.3 0 64 28.7 64 64l0 320c0 35.3-28.7 64-64 64L64 480c-35.3 0-64-28.7-64-64L0 96C0 60.7 28.7 32 64 32l320 0zM320 256c0 6.7-2.8 13-7.7 17.6l-112 104c-7 6.5-17.2 8.2-25.9 4.4s-14.4-12.5-14.4-22l0-208c0-9.5 5.7-18.2 14.4-22s18.9-2.1 25.9 4.4l112 104c4.9 4.5 7.7 10.9 7.7 17.6z" } }, "free": ["regular", "solid"] }, "square-caret-up": { "aliases": { "names": ["caret-square-up"], "unicodes": { "secondary": ["10f151"] } }, "changes": ["3.2.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["arrow", "caret-square-o-up", "collapse", "triangle", "upload"] }, "styles": ["solid", "regular"], "unicode": "f151", "label": "Square Caret Up", "voted": false, "svg": { "solid": { "last_modified": 1684766331, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zM224 160c6.7 0 13 2.8 17.6 7.7l104 112c6.5 7 8.2 17.2 4.4 25.9s-12.5 14.4-22 14.4H120c-9.5 0-18.2-5.7-22-14.4s-2.1-18.9 4.4-25.9l104-112c4.5-4.9 10.9-7.7 17.6-7.7z" }, "regular": { "last_modified": 1684766331, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M64 80c-8.8 0-16 7.2-16 16l0 320c0 8.8 7.2 16 16 16l320 0c8.8 0 16-7.2 16-16l0-320c0-8.8-7.2-16-16-16L64 80zM0 96C0 60.7 28.7 32 64 32l320 0c35.3 0 64 28.7 64 64l0 320c0 35.3-28.7 64-64 64L64 480c-35.3 0-64-28.7-64-64L0 96zm224 64c6.7 0 13 2.8 17.6 7.7l104 112c6.5 7 8.2 17.2 4.4 25.9s-12.5 14.4-22 14.4l-208 0c-9.5 0-18.2-5.7-22-14.4s-2.1-18.9 4.4-25.9l104-112c4.5-4.9 10.9-7.7 17.6-7.7z" } }, "free": ["regular", "solid"] }, "square-check": { "aliases": { "names": ["check-square"], "unicodes": { "composite": ["2611", "2705", "f046"], "secondary": ["10f14a"] } }, "changes": [ "3.1.0", "5.0.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "accept", "agree", "box", "button", "check", "check box with check", "check mark button", "checkmark", "confirm", "correct", "done", "mark", "ok", "select", "success", "tick", "todo", "yes", "✓" ] }, "styles": ["solid", "regular"], "unicode": "f14a", "label": "Square Check", "voted": false, "svg": { "solid": { "last_modified": 1684767553, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zM337 209L209 337c-9.4 9.4-24.6 9.4-33.9 0l-64-64c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l47 47L303 175c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9z" }, "regular": { "last_modified": 1684767553, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M64 80c-8.8 0-16 7.2-16 16V416c0 8.8 7.2 16 16 16H384c8.8 0 16-7.2 16-16V96c0-8.8-7.2-16-16-16H64zM0 96C0 60.7 28.7 32 64 32H384c35.3 0 64 28.7 64 64V416c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V96zM337 209L209 337c-9.4 9.4-24.6 9.4-33.9 0l-64-64c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l47 47L303 175c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9z" } }, "free": ["regular", "solid"] }, "square-dribbble": { "aliases": { "names": ["dribbble-square"] }, "changes": ["5.0.0", "6.1.2"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f397", "label": "Dribbble Square", "voted": false, "svg": { "brands": { "last_modified": 1660014477, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M90.2 228.2c8.9-42.4 37.4-77.7 75.7-95.7 3.6 4.9 28 38.8 50.7 79-64 17-120.3 16.8-126.4 16.7zM314.6 154c-33.6-29.8-79.3-41.1-122.6-30.6 3.8 5.1 28.6 38.9 51 80 48.6-18.3 69.1-45.9 71.6-49.4zM140.1 364c40.5 31.6 93.3 36.7 137.3 18-2-12-10-53.8-29.2-103.6-55.1 18.8-93.8 56.4-108.1 85.6zm98.8-108.2c-3.4-7.8-7.2-15.5-11.1-23.2C159.6 253 93.4 252.2 87.4 252c0 1.4-.1 2.8-.1 4.2 0 35.1 13.3 67.1 35.1 91.4 22.2-37.9 67.1-77.9 116.5-91.8zm34.9 16.3c17.9 49.1 25.1 89.1 26.5 97.4 30.7-20.7 52.5-53.6 58.6-91.6-4.6-1.5-42.3-12.7-85.1-5.8zm-20.3-48.4c4.8 9.8 8.3 17.8 12 26.8 45.5-5.7 90.7 3.4 95.2 4.4-.3-32.3-11.8-61.9-30.9-85.1-2.9 3.9-25.8 33.2-76.3 53.9zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-64 176c0-88.2-71.8-160-160-160S64 167.8 64 256s71.8 160 160 160 160-71.8 160-160z" } }, "free": ["brands"] }, "square-envelope": { "aliases": { "names": ["envelope-square"], "unicodes": { "secondary": ["10f199"] } }, "changes": ["4.1.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "e-mail", "email", "letter", "mail", "message", "notification", "support" ] }, "styles": ["solid"], "unicode": "f199", "label": "Square Envelope", "voted": false, "svg": { "solid": { "last_modified": 1684767389, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zM218 271.7L64.2 172.4C66 156.4 79.5 144 96 144H352c16.5 0 30 12.4 31.8 28.4L230 271.7c-1.8 1.2-3.9 1.8-6 1.8s-4.2-.6-6-1.8zm29.4 26.9L384 210.4V336c0 17.7-14.3 32-32 32H96c-17.7 0-32-14.3-32-32V210.4l136.6 88.2c7 4.5 15.1 6.9 23.4 6.9s16.4-2.4 23.4-6.9z" } }, "free": ["solid"] }, "square-facebook": { "aliases": { "names": ["facebook-square"] }, "changes": ["1.0.0", "5.0.0", "5.8.2", "6.1.2"], "ligatures": [], "search": { "terms": ["social network"] }, "styles": ["brands"], "unicode": "f082", "label": "Facebook Square", "voted": false, "svg": { "brands": { "last_modified": 1660014467, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M400 32H48A48 48 0 0 0 0 80v352a48 48 0 0 0 48 48h137.25V327.69h-63V256h63v-54.64c0-62.15 37-96.48 93.67-96.48 27.14 0 55.52 4.84 55.52 4.84v61h-31.27c-30.81 0-40.42 19.12-40.42 38.73V256h68.78l-11 71.69h-57.78V480H400a48 48 0 0 0 48-48V80a48 48 0 0 0-48-48z" } }, "free": ["brands"] }, "square-font-awesome": { "changes": ["5.0.0", "5.0.1", "6.0.0-beta1", "6.1.2"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e5ad", "label": "Font Awesome in Square", "voted": false, "svg": { "brands": { "last_modified": 1660014480, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M384.5,32.5h-320c-35.3,0-64,28.7-64,64v320c0,35.3,28.7,64,64,64h320c35.3,0,64-28.7,64-64v-320 C448.5,61.2,419.8,32.5,384.5,32.5z M336.5,312.5c-31.6,11.2-41.2,16-59.8,16c-31.4,0-43.2-16-74.6-16c-10.2,0-18.2,1.6-25.6,4v-32 c7.4-2.2,15.4-4,25.6-4c31.2,0,43.2,16,74.6,16c10.2,0,17.8-1.4,27.8-4.6v-96c-10,3.2-17.6,4.6-27.8,4.6c-31.4,0-43.2-16-74.6-16 c-25.4,0-37.4,10.4-57.6,14.4v153.6c0,8.8-7.2,16-16,16c-8.8,0-16-7.2-16-16v-192c0-8.8,7.2-16,16-16c8.8,0,16,7.2,16,16v6.4 c20.2-4,32.2-14.4,57.6-14.4c31.2,0,43.2,16,74.6,16c18.6,0,28.2-4.8,59.8-16V312.5z" } }, "free": ["brands"] }, "square-font-awesome-stroke": { "aliases": { "names": ["font-awesome-alt"] }, "changes": ["5.0.0", "6.0.0-beta1"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f35c", "label": "Font Awesome in Square with Stroke Outline", "voted": false, "svg": { "brands": { "last_modified": 1660014479, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M201.6,152c-25.4,0-37.4,10.4-57.6,14.4V160c0-8.8-7.2-16-16-16s-16,7.2-16,16v192c0,0.8,0.1,1.6,0.2,2.4 c0.1,0.4,0.1,0.8,0.2,1.2c1.6,7.1,8,12.4,15.6,12.4s14-5.3,15.6-12.4c0.1-0.4,0.2-0.8,0.2-1.2c0.1-0.8,0.2-1.6,0.2-2.4V198.4 c4-0.8,7.7-1.8,11.2-3c14.3-4.7,26-11.4,46.4-11.4c31.4,0,43.2,16,74.6,16c8.9,0,15.9-1.1,24.2-3.5c1.2-0.3,2.4-0.7,3.6-1.1v96 c-10,3.2-17.6,4.6-27.8,4.6c-31.4,0-43.4-16-74.6-16c-10.2,0-18.2,1.8-25.6,4v32c7.4-2.4,15.4-4,25.6-4c31.4,0,43.2,16,74.6,16 c18.6,0,28.2-4.8,59.8-16V152c-31.6,11.2-41.2,16-59.8,16C244.8,168,232.8,152,201.6,152z M384,32H64C28.7,32,0,60.7,0,96v320 c0,35.3,28.7,64,64,64h320c35.3,0,64-28.7,64-64V96C448,60.7,419.3,32,384,32z M416,416c0,17.6-14.4,32-32,32H64 c-17.6,0-32-14.4-32-32V96c0-17.6,14.4-32,32-32h320c17.6,0,32,14.4,32,32V416z" } }, "free": ["brands"] }, "square-full": { "aliases": { "unicodes": { "composite": [ "1f7e5", "1f7e6", "1f7e7", "1f7e8", "1f7e9", "1f7ea", "1f7eb", "2b1b", "2b1c" ], "secondary": ["10f45c"] } }, "changes": [ "5.0.5", "5.10.2", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "black large square", "block", "blue", "blue square", "box", "brown", "brown square", "geometric", "green", "green square", "orange", "orange square", "purple", "purple square", "red", "red square", "shape", "square", "white large square", "yellow", "yellow square" ] }, "styles": ["solid", "regular"], "unicode": "f45c", "label": "Square Full", "voted": false, "svg": { "solid": { "last_modified": 1684767551, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 0H512V512H0V0z" }, "regular": { "last_modified": 1684767551, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M464 48V464H48V48H464zM48 0H0V48 464v48H48 464h48V464 48 0H464 48z" } }, "free": ["regular", "solid"] }, "square-git": { "aliases": { "names": ["git-square"] }, "changes": ["4.1.0", "5.0.0", "5.8.2", "6.1.2"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f1d2", "label": "Git Square", "voted": false, "svg": { "brands": { "last_modified": 1660014463, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M100.59 334.24c48.57 3.31 58.95 2.11 58.95 11.94 0 20-65.55 20.06-65.55 1.52.01-5.09 3.29-9.4 6.6-13.46zm27.95-116.64c-32.29 0-33.75 44.47-.75 44.47 32.51 0 31.71-44.47.75-44.47zM448 80v352a48 48 0 0 1-48 48H48a48 48 0 0 1-48-48V80a48 48 0 0 1 48-48h352a48 48 0 0 1 48 48zm-227 69.31c0 14.49 8.38 22.88 22.86 22.88 14.74 0 23.13-8.39 23.13-22.88S258.62 127 243.88 127c-14.48 0-22.88 7.84-22.88 22.31zM199.18 195h-49.55c-25-6.55-81.56-4.85-81.56 46.75 0 18.8 9.4 32 21.85 38.11C74.23 294.23 66.8 301 66.8 310.6c0 6.87 2.79 13.22 11.18 16.76-8.9 8.4-14 14.48-14 25.92C64 373.35 81.53 385 127.52 385c44.22 0 69.87-16.51 69.87-45.73 0-36.67-28.23-35.32-94.77-39.38l8.38-13.43c17 4.74 74.19 6.23 74.19-42.43 0-11.69-4.83-19.82-9.4-25.67l23.38-1.78zm84.34 109.84l-13-1.78c-3.82-.51-4.07-1-4.07-5.09V192.52h-52.6l-2.79 20.57c15.75 5.55 17 4.86 17 10.17V298c0 5.62-.31 4.58-17 6.87v20.06h72.42zM384 315l-6.87-22.37c-40.93 15.37-37.85-12.41-37.85-16.73v-60.72h37.85v-25.41h-35.82c-2.87 0-2 2.52-2-38.63h-24.18c-2.79 27.7-11.68 38.88-34 41.42v22.62c20.47 0 19.82-.85 19.82 2.54v66.57c0 28.72 11.43 40.91 41.67 40.91 14.45 0 30.45-4.83 41.38-10.2z" } }, "free": ["brands"] }, "square-github": { "aliases": { "names": ["github-square"] }, "changes": ["1.0.0", "5.0.0", "6.1.2"], "ligatures": [], "search": { "terms": ["octocat"] }, "styles": ["brands"], "unicode": "f092", "label": "GitHub Square", "voted": false, "svg": { "brands": { "last_modified": 1660014473, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM277.3 415.7c-8.4 1.5-11.5-3.7-11.5-8 0-5.4.2-33 .2-55.3 0-15.6-5.2-25.5-11.3-30.7 37-4.1 76-9.2 76-73.1 0-18.2-6.5-27.3-17.1-39 1.7-4.3 7.4-22-1.7-45-13.9-4.3-45.7 17.9-45.7 17.9-13.2-3.7-27.5-5.6-41.6-5.6-14.1 0-28.4 1.9-41.6 5.6 0 0-31.8-22.2-45.7-17.9-9.1 22.9-3.5 40.6-1.7 45-10.6 11.7-15.6 20.8-15.6 39 0 63.6 37.3 69 74.3 73.1-4.8 4.3-9.1 11.7-10.6 22.3-9.5 4.3-33.8 11.7-48.3-13.9-9.1-15.8-25.5-17.1-25.5-17.1-16.2-.2-1.1 10.2-1.1 10.2 10.8 5 18.4 24.2 18.4 24.2 9.7 29.7 56.1 19.7 56.1 19.7 0 13.9.2 36.5.2 40.6 0 4.3-3 9.5-11.5 8-66-22.1-112.2-84.9-112.2-158.3 0-91.8 70.2-161.5 162-161.5S388 165.6 388 257.4c.1 73.4-44.7 136.3-110.7 158.3zm-98.1-61.1c-1.9.4-3.7-.4-3.9-1.7-.2-1.5 1.1-2.8 3-3.2 1.9-.2 3.7.6 3.9 1.9.3 1.3-1 2.6-3 3zm-9.5-.9c0 1.3-1.5 2.4-3.5 2.4-2.2.2-3.7-.9-3.7-2.4 0-1.3 1.5-2.4 3.5-2.4 1.9-.2 3.7.9 3.7 2.4zm-13.7-1.1c-.4 1.3-2.4 1.9-4.1 1.3-1.9-.4-3.2-1.9-2.8-3.2.4-1.3 2.4-1.9 4.1-1.5 2 .6 3.3 2.1 2.8 3.4zm-12.3-5.4c-.9 1.1-2.8.9-4.3-.6-1.5-1.3-1.9-3.2-.9-4.1.9-1.1 2.8-.9 4.3.6 1.3 1.3 1.8 3.3.9 4.1zm-9.1-9.1c-.9.6-2.6 0-3.7-1.5s-1.1-3.2 0-3.9c1.1-.9 2.8-.2 3.7 1.3 1.1 1.5 1.1 3.3 0 4.1zm-6.5-9.7c-.9.9-2.4.4-3.5-.6-1.1-1.3-1.3-2.8-.4-3.5.9-.9 2.4-.4 3.5.6 1.1 1.3 1.3 2.8.4 3.5zm-6.7-7.4c-.4.9-1.7 1.1-2.8.4-1.3-.6-1.9-1.7-1.5-2.6.4-.6 1.5-.9 2.8-.4 1.3.7 1.9 1.8 1.5 2.6z" } }, "free": ["brands"] }, "square-gitlab": { "aliases": { "names": ["gitlab-square"] }, "changes": ["6.1.2"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e5ae", "label": "Square Gitlab", "voted": false, "svg": { "brands": { "last_modified": 1660014473, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M48 32H400C426.5 32 448 53.5 448 80V432C448 458.5 426.5 480 400 480H48C21.5 480 0 458.5 0 432V80C0 53.5 21.5 32 48 32zM382.1 224.9L337.5 108.5C336.6 106.2 334.9 104.2 332.9 102.9C331.3 101.9 329.5 101.3 327.7 101.1C325.9 100.9 324 101.2 322.3 101.8C320.6 102.5 319 103.5 317.8 104.9C316.6 106.3 315.7 107.9 315.2 109.7L285 201.9H162.1L132.9 109.7C132.4 107.9 131.4 106.3 130.2 104.9C128.1 103.6 127.4 102.5 125.7 101.9C123.1 101.2 122.1 100.1 120.3 101.1C118.5 101.3 116.7 101.9 115.1 102.9C113.1 104.2 111.5 106.2 110.6 108.5L65.94 224.9L65.47 226.1C59.05 242.9 58.26 261.3 63.22 278.6C68.18 295.9 78.62 311.1 92.97 321.9L93.14 322L93.52 322.3L161.4 373.2L215.6 414.1C217.1 415.1 220.9 416.9 223.9 416.9C226.9 416.9 229.9 415.1 232.3 414.1L286.4 373.2L354.8 322L355 321.9C369.4 311 379.8 295.8 384.8 278.6C389.7 261.3 388.1 242.9 382.5 226.1L382.1 224.9z" } }, "free": ["brands"] }, "square-google-plus": { "aliases": { "names": ["google-plus-square"] }, "changes": ["2.0.0", "5.0.0", "6.1.2"], "ligatures": [], "search": { "terms": ["social network"] }, "styles": ["brands"], "unicode": "f0d4", "label": "Google Plus Square", "voted": false, "svg": { "brands": { "last_modified": 1660014470, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM164 356c-55.3 0-100-44.7-100-100s44.7-100 100-100c27 0 49.5 9.8 67 26.2l-27.1 26.1c-7.4-7.1-20.3-15.4-39.8-15.4-34.1 0-61.9 28.2-61.9 63.2 0 34.9 27.8 63.2 61.9 63.2 39.6 0 54.4-28.5 56.8-43.1H164v-34.4h94.4c1 5 1.6 10.1 1.6 16.6 0 57.1-38.3 97.6-96 97.6zm220-81.8h-29v29h-29.2v-29h-29V245h29v-29H355v29h29v29.2z" } }, "free": ["brands"] }, "square-h": { "aliases": { "names": ["h-square"], "unicodes": { "secondary": ["10f0fd"] } }, "changes": ["3.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["directions", "emergency", "hospital", "hotel", "letter", "map"] }, "styles": ["solid"], "unicode": "f0fd", "label": "Square H", "voted": false, "svg": { "solid": { "last_modified": 1684767245, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zM336 152V256 360c0 13.3-10.7 24-24 24s-24-10.7-24-24V280H160l0 80c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-208c0-13.3 10.7-24 24-24s24 10.7 24 24v80H288V152c0-13.3 10.7-24 24-24s24 10.7 24 24z" } }, "free": ["solid"] }, "square-hacker-news": { "aliases": { "names": ["hacker-news-square"] }, "changes": ["5.0.0", "6.1.2"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3af", "label": "Hacker News Square", "voted": false, "svg": { "brands": { "last_modified": 1660014480, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM21.2 229.2H21c.1-.1.2-.3.3-.4 0 .1 0 .3-.1.4zm218 53.9V384h-31.4V281.3L128 128h37.3c52.5 98.3 49.2 101.2 59.3 125.6 12.3-27 5.8-24.4 60.6-125.6H320l-80.8 155.1z" } }, "free": ["brands"] }, "square-instagram": { "aliases": { "names": ["instagram-square"] }, "changes": ["5.12.1", "5.14.0", "6.1.2"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e055", "label": "Instagram Square", "voted": true, "svg": { "brands": { "last_modified": 1660014480, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M224,202.66A53.34,53.34,0,1,0,277.36,256,53.38,53.38,0,0,0,224,202.66Zm124.71-41a54,54,0,0,0-30.41-30.41c-21-8.29-71-6.43-94.3-6.43s-73.25-1.93-94.31,6.43a54,54,0,0,0-30.41,30.41c-8.28,21-6.43,71.05-6.43,94.33S91,329.26,99.32,350.33a54,54,0,0,0,30.41,30.41c21,8.29,71,6.43,94.31,6.43s73.24,1.93,94.3-6.43a54,54,0,0,0,30.41-30.41c8.35-21,6.43-71.05,6.43-94.33S357.1,182.74,348.75,161.67ZM224,338a82,82,0,1,1,82-82A81.9,81.9,0,0,1,224,338Zm85.38-148.3a19.14,19.14,0,1,1,19.13-19.14A19.1,19.1,0,0,1,309.42,189.74ZM400,32H48A48,48,0,0,0,0,80V432a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V80A48,48,0,0,0,400,32ZM382.88,322c-1.29,25.63-7.14,48.34-25.85,67s-41.4,24.63-67,25.85c-26.41,1.49-105.59,1.49-132,0-25.63-1.29-48.26-7.15-67-25.85s-24.63-41.42-25.85-67c-1.49-26.42-1.49-105.61,0-132,1.29-25.63,7.07-48.34,25.85-67s41.47-24.56,67-25.78c26.41-1.49,105.59-1.49,132,0,25.63,1.29,48.33,7.15,67,25.85s24.63,41.42,25.85,67.05C384.37,216.44,384.37,295.56,382.88,322Z" } }, "free": ["brands"] }, "square-js": { "aliases": { "names": ["js-square"] }, "changes": ["5.0.0", "5.0.3", "6.1.2"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3b9", "label": "JavaScript (JS) Square", "voted": false, "svg": { "brands": { "last_modified": 1660014482, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM243.8 381.4c0 43.6-25.6 63.5-62.9 63.5-33.7 0-53.2-17.4-63.2-38.5l34.3-20.7c6.6 11.7 12.6 21.6 27.1 21.6 13.8 0 22.6-5.4 22.6-26.5V237.7h42.1v143.7zm99.6 63.5c-39.1 0-64.4-18.6-76.7-43l34.3-19.8c9 14.7 20.8 25.6 41.5 25.6 17.4 0 28.6-8.7 28.6-20.8 0-14.4-11.4-19.5-30.7-28l-10.5-4.5c-30.4-12.9-50.5-29.2-50.5-63.5 0-31.6 24.1-55.6 61.6-55.6 26.8 0 46 9.3 59.8 33.7L368 290c-7.2-12.9-15-18-27.1-18-12.3 0-20.1 7.8-20.1 18 0 12.6 7.8 17.7 25.9 25.6l10.5 4.5c35.8 15.3 55.9 31 55.9 66.2 0 37.8-29.8 58.6-69.7 58.6z" } }, "free": ["brands"] }, "square-lastfm": { "aliases": { "names": ["lastfm-square"] }, "changes": ["4.2.0", "5.0.0", "5.0.11", "6.1.2"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f203", "label": "last.fm Square", "voted": false, "svg": { "brands": { "last_modified": 1660014466, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-92.2 312.9c-63.4 0-85.4-28.6-97.1-64.1-16.3-51-21.5-84.3-63-84.3-22.4 0-45.1 16.1-45.1 61.2 0 35.2 18 57.2 43.3 57.2 28.6 0 47.6-21.3 47.6-21.3l11.7 31.9s-19.8 19.4-61.2 19.4c-51.3 0-79.9-30.1-79.9-85.8 0-57.9 28.6-92 82.5-92 73.5 0 80.8 41.4 100.8 101.9 8.8 26.8 24.2 46.2 61.2 46.2 24.9 0 38.1-5.5 38.1-19.1 0-19.9-21.8-22-49.9-28.6-30.4-7.3-42.5-23.1-42.5-48 0-40 32.3-52.4 65.2-52.4 37.4 0 60.1 13.6 63 46.6l-36.7 4.4c-1.5-15.8-11-22.4-28.6-22.4-16.1 0-26 7.3-26 19.8 0 11 4.8 17.6 20.9 21.3 32.7 7.1 71.8 12 71.8 57.5.1 36.7-30.7 50.6-76.1 50.6z" } }, "free": ["brands"] }, "square-minus": { "aliases": { "names": ["minus-square"], "unicodes": { "composite": ["f147"], "secondary": ["10f146"] } }, "changes": [ "3.1.0", "5.0.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "collapse", "delete", "hide", "minify", "negative", "remove", "shape", "trash" ] }, "styles": ["solid", "regular"], "unicode": "f146", "label": "Square Minus", "voted": false, "svg": { "solid": { "last_modified": 1684767553, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zm88 200H296c13.3 0 24 10.7 24 24s-10.7 24-24 24H152c-13.3 0-24-10.7-24-24s10.7-24 24-24z" }, "regular": { "last_modified": 1684767553, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M64 80c-8.8 0-16 7.2-16 16V416c0 8.8 7.2 16 16 16H384c8.8 0 16-7.2 16-16V96c0-8.8-7.2-16-16-16H64zM0 96C0 60.7 28.7 32 64 32H384c35.3 0 64 28.7 64 64V416c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V96zM152 232H296c13.3 0 24 10.7 24 24s-10.7 24-24 24H152c-13.3 0-24-10.7-24-24s10.7-24 24-24z" } }, "free": ["regular", "solid"] }, "square-nfi": { "changes": ["6.1.0", "6.1.2", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["non-food item", "supplies"] }, "styles": ["solid"], "unicode": "e576", "label": "Square Nfi", "voted": false, "svg": { "solid": { "last_modified": 1684767443, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M0 96C0 60.7 28.7 32 64 32H384c35.3 0 64 28.7 64 64V416c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V96zm75.7 64.6C68.8 162.5 64 168.8 64 176V336c0 8.8 7.2 16 16 16s16-7.2 16-16V233.8l66.3 110.5c3.7 6.2 11.1 9.1 18 7.2s11.7-8.2 11.7-15.4V176c0-8.8-7.2-16-16-16s-16 7.2-16 16V278.2L93.7 167.8c-3.7-6.2-11.1-9.1-18-7.2zM224 176v64 96c0 8.8 7.2 16 16 16s16-7.2 16-16V256h48c8.8 0 16-7.2 16-16s-7.2-16-16-16H256V192h48c8.8 0 16-7.2 16-16s-7.2-16-16-16H240c-8.8 0-16 7.2-16 16zm160 0c0-8.8-7.2-16-16-16s-16 7.2-16 16V336c0 8.8 7.2 16 16 16s16-7.2 16-16V176z" } }, "free": ["solid"] }, "square-odnoklassniki": { "aliases": { "names": ["odnoklassniki-square"] }, "changes": ["4.4.0", "5.0.0", "6.1.2"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f264", "label": "Odnoklassniki Square", "voted": false, "svg": { "brands": { "last_modified": 1660014472, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M184.2 177.1c0-22.1 17.9-40 39.8-40s39.8 17.9 39.8 40c0 22-17.9 39.8-39.8 39.8s-39.8-17.9-39.8-39.8zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-305.1 97.1c0 44.6 36.4 80.9 81.1 80.9s81.1-36.2 81.1-80.9c0-44.8-36.4-81.1-81.1-81.1s-81.1 36.2-81.1 81.1zm174.5 90.7c-4.6-9.1-17.3-16.8-34.1-3.6 0 0-22.7 18-59.3 18s-59.3-18-59.3-18c-16.8-13.2-29.5-5.5-34.1 3.6-7.9 16.1 1.1 23.7 21.4 37 17.3 11.1 41.2 15.2 56.6 16.8l-12.9 12.9c-18.2 18-35.5 35.5-47.7 47.7-17.6 17.6 10.7 45.8 28.4 28.6l47.7-47.9c18.2 18.2 35.7 35.7 47.7 47.9 17.6 17.2 46-10.7 28.6-28.6l-47.7-47.7-13-12.9c15.5-1.6 39.1-5.9 56.2-16.8 20.4-13.3 29.3-21 21.5-37z" } }, "free": ["brands"] }, "square-parking": { "aliases": { "names": ["parking"], "unicodes": { "composite": ["1f17f"], "secondary": ["10f540"] } }, "changes": [ "5.0.13", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["auto", "car", "garage", "meter", "parking"] }, "styles": ["solid"], "unicode": "f540", "label": "Square Parking", "voted": true, "svg": { "solid": { "last_modified": 1684767489, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zM192 256h48c17.7 0 32-14.3 32-32s-14.3-32-32-32H192v64zm48 64H192v32c0 17.7-14.3 32-32 32s-32-14.3-32-32V288 168c0-22.1 17.9-40 40-40h72c53 0 96 43 96 96s-43 96-96 96z" } }, "free": ["solid"] }, "square-pen": { "aliases": { "names": ["pen-square", "pencil-square"], "unicodes": { "secondary": ["10f14b"] } }, "changes": [ "3.1.0", "5.0.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["edit", "pencil-square", "update", "write"] }, "styles": ["solid"], "unicode": "f14b", "label": "Square Pen", "voted": false, "svg": { "solid": { "last_modified": 1684767366, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zM325.8 139.7l14.4 14.4c15.6 15.6 15.6 40.9 0 56.6l-21.4 21.4-71-71 21.4-21.4c15.6-15.6 40.9-15.6 56.6 0zM119.9 289L225.1 183.8l71 71L190.9 359.9c-4.1 4.1-9.2 7-14.9 8.4l-60.1 15c-5.5 1.4-11.2-.2-15.2-4.2s-5.6-9.7-4.2-15.2l15-60.1c1.4-5.6 4.3-10.8 8.4-14.9z" } }, "free": ["solid"] }, "square-person-confined": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["captivity", "confined"] }, "styles": ["solid"], "unicode": "e577", "label": "Square Person Confined", "voted": false, "svg": { "solid": { "last_modified": 1684767532, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zm96 112a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zm80 104c0-30.9 25.1-56 56-56s56 25.1 56 56V350.1c0 36.4-29.5 65.9-65.9 65.9c-17.5 0-34.3-6.9-46.6-19.3L184.8 342l-28.1 56.3c-7.9 15.8-27.1 22.2-42.9 14.3s-22.2-27.1-14.3-42.9l48-96c4.6-9.2 13.3-15.6 23.5-17.3s20.5 1.7 27.8 9L240 306.7V248z" } }, "free": ["solid"] }, "square-phone": { "aliases": { "names": ["phone-square"], "unicodes": { "secondary": ["10f098"] } }, "changes": ["2.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["call", "earphone", "number", "support", "telephone", "voice"] }, "styles": ["solid"], "unicode": "f098", "label": "Square Phone", "voted": false, "svg": { "solid": { "last_modified": 1684767389, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zm90.7 96.7c9.7-2.6 19.9 2.3 23.7 11.6l20 48c3.4 8.2 1 17.6-5.8 23.2L168 231.7c16.6 35.2 45.1 63.7 80.3 80.3l20.2-24.7c5.6-6.8 15-9.2 23.2-5.8l48 20c9.3 3.9 14.2 14 11.6 23.7l-12 44C336.9 378 329 384 320 384C196.3 384 96 283.7 96 160c0-9 6-16.9 14.7-19.3l44-12z" } }, "free": ["solid"] }, "square-phone-flip": { "aliases": { "names": ["phone-square-alt"], "unicodes": { "secondary": ["10f87b"] } }, "changes": ["5.9.0", "5.10.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["call", "earphone", "number", "support", "telephone", "voice"] }, "styles": ["solid"], "unicode": "f87b", "label": "Square Phone Flip", "voted": false, "svg": { "solid": { "last_modified": 1684767392, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M384 32c35.3 0 64 28.7 64 64V416c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V96C0 60.7 28.7 32 64 32H384zm-90.7 96.7c-9.7-2.6-19.9 2.3-23.7 11.6l-20 48c-3.4 8.2-1 17.6 5.8 23.2L280 231.7c-16.6 35.2-45.1 63.7-80.3 80.3l-20.2-24.7c-5.6-6.8-15-9.2-23.2-5.8l-48 20c-9.3 3.9-14.2 14-11.6 23.7l12 44C111.1 378 119 384 128 384c123.7 0 224-100.3 224-224c0-9-6-16.9-14.7-19.3l-44-12z" } }, "free": ["solid"] }, "square-pied-piper": { "aliases": { "names": ["pied-piper-square"] }, "changes": ["5.12.0", "5.14.0", "6.1.2"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e01e", "label": "Pied Piper Square Logo (Old)", "voted": false, "svg": { "brands": { "last_modified": 1660014467, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M32 419L0 479.2l.8-328C.8 85.3 54 32 120 32h327.2c-93 28.9-189.9 94.2-253.9 168.6C122.7 282 82.6 338 32 419M448 32S305.2 98.8 261.6 199.1c-23.2 53.6-28.9 118.1-71 158.6-28.9 27.8-69.8 38.2-105.3 56.3-23.2 12-66.4 40.5-84.9 66h328.4c66 0 119.3-53.3 119.3-119.2-.1 0-.1-328.8-.1-328.8z" } }, "free": ["brands"] }, "square-pinterest": { "aliases": { "names": ["pinterest-square"] }, "changes": ["2.0.0", "5.0.0", "6.1.2"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f0d3", "label": "Pinterest Square", "voted": false, "svg": { "brands": { "last_modified": 1660014471, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M448 80v352c0 26.5-21.5 48-48 48H154.4c9.8-16.4 22.4-40 27.4-59.3 3-11.5 15.3-58.4 15.3-58.4 8 15.3 31.4 28.2 56.3 28.2 74.1 0 127.4-68.1 127.4-152.7 0-81.1-66.2-141.8-151.4-141.8-106 0-162.2 71.1-162.2 148.6 0 36 19.2 80.8 49.8 95.1 4.7 2.2 7.1 1.2 8.2-3.3.8-3.4 5-20.1 6.8-27.8.6-2.5.3-4.6-1.7-7-10.1-12.3-18.3-34.9-18.3-56 0-54.2 41-106.6 110.9-106.6 60.3 0 102.6 41.1 102.6 99.9 0 66.4-33.5 112.4-77.2 112.4-24.1 0-42.1-19.9-36.4-44.4 6.9-29.2 20.3-60.7 20.3-81.8 0-53-75.5-45.7-75.5 25 0 21.7 7.3 36.5 7.3 36.5-31.4 132.8-36.1 134.5-29.6 192.6l2.2.8H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48z" } }, "free": ["brands"] }, "square-plus": { "aliases": { "names": ["plus-square"], "unicodes": { "composite": ["f196"], "secondary": ["10f0fe"] } }, "changes": [ "3.0.0", "5.0.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["add", "create", "expand", "new", "positive", "shape"] }, "styles": ["solid", "regular"], "unicode": "f0fe", "label": "Square Plus", "voted": false, "svg": { "solid": { "last_modified": 1684767552, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zM200 344V280H136c-13.3 0-24-10.7-24-24s10.7-24 24-24h64V168c0-13.3 10.7-24 24-24s24 10.7 24 24v64h64c13.3 0 24 10.7 24 24s-10.7 24-24 24H248v64c0 13.3-10.7 24-24 24s-24-10.7-24-24z" }, "regular": { "last_modified": 1684767552, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M64 80c-8.8 0-16 7.2-16 16V416c0 8.8 7.2 16 16 16H384c8.8 0 16-7.2 16-16V96c0-8.8-7.2-16-16-16H64zM0 96C0 60.7 28.7 32 64 32H384c35.3 0 64 28.7 64 64V416c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V96zM200 344V280H136c-13.3 0-24-10.7-24-24s10.7-24 24-24h64V168c0-13.3 10.7-24 24-24s24 10.7 24 24v64h64c13.3 0 24 10.7 24 24s-10.7 24-24 24H248v64c0 13.3-10.7 24-24 24s-24-10.7-24-24z" } }, "free": ["regular", "solid"] }, "square-poll-horizontal": { "aliases": { "names": ["poll-h"], "unicodes": { "secondary": ["10f682"] } }, "changes": [ "5.3.0", "5.10.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "chart", "graph", "results", "survey", "trend", "vote", "voting" ] }, "styles": ["solid"], "unicode": "f682", "label": "Square Poll Horizontal", "voted": false, "svg": { "solid": { "last_modified": 1684767207, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M448 96c0-35.3-28.7-64-64-64L64 32C28.7 32 0 60.7 0 96L0 416c0 35.3 28.7 64 64 64l320 0c35.3 0 64-28.7 64-64l0-320zM256 160c0 17.7-14.3 32-32 32l-96 0c-17.7 0-32-14.3-32-32s14.3-32 32-32l96 0c17.7 0 32 14.3 32 32zm64 64c17.7 0 32 14.3 32 32s-14.3 32-32 32l-192 0c-17.7 0-32-14.3-32-32s14.3-32 32-32l192 0zM192 352c0 17.7-14.3 32-32 32l-32 0c-17.7 0-32-14.3-32-32s14.3-32 32-32l32 0c17.7 0 32 14.3 32 32z" } }, "free": ["solid"] }, "square-poll-vertical": { "aliases": { "names": ["poll"], "unicodes": { "secondary": ["10f681"] } }, "changes": [ "5.3.0", "5.10.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "chart", "graph", "results", "survey", "trend", "vote", "voting" ] }, "styles": ["solid"], "unicode": "f681", "label": "Square Poll Vertical", "voted": false, "svg": { "solid": { "last_modified": 1684767207, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zm64 192c17.7 0 32 14.3 32 32v96c0 17.7-14.3 32-32 32s-32-14.3-32-32V256c0-17.7 14.3-32 32-32zm64-64c0-17.7 14.3-32 32-32s32 14.3 32 32V352c0 17.7-14.3 32-32 32s-32-14.3-32-32V160zM320 288c17.7 0 32 14.3 32 32v32c0 17.7-14.3 32-32 32s-32-14.3-32-32V320c0-17.7 14.3-32 32-32z" } }, "free": ["solid"] }, "square-reddit": { "aliases": { "names": ["reddit-square"] }, "changes": ["4.1.0", "5.0.0", "6.1.2"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f1a2", "label": "reddit Square", "voted": false, "svg": { "brands": { "last_modified": 1660014481, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M283.2 345.5c2.7 2.7 2.7 6.8 0 9.2-24.5 24.5-93.8 24.6-118.4 0-2.7-2.4-2.7-6.5 0-9.2 2.4-2.4 6.5-2.4 8.9 0 18.7 19.2 81 19.6 100.5 0 2.4-2.3 6.6-2.3 9 0zm-91.3-53.8c0-14.9-11.9-26.8-26.5-26.8-14.9 0-26.8 11.9-26.8 26.8 0 14.6 11.9 26.5 26.8 26.5 14.6 0 26.5-11.9 26.5-26.5zm90.7-26.8c-14.6 0-26.5 11.9-26.5 26.8 0 14.6 11.9 26.5 26.5 26.5 14.9 0 26.8-11.9 26.8-26.5 0-14.9-11.9-26.8-26.8-26.8zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-99.7 140.6c-10.1 0-19 4.2-25.6 10.7-24.1-16.7-56.5-27.4-92.5-28.6l18.7-84.2 59.5 13.4c0 14.6 11.9 26.5 26.5 26.5 14.9 0 26.8-12.2 26.8-26.8 0-14.6-11.9-26.8-26.8-26.8-10.4 0-19.3 6.2-23.8 14.9l-65.7-14.6c-3.3-.9-6.5 1.5-7.4 4.8l-20.5 92.8c-35.7 1.5-67.8 12.2-91.9 28.9-6.5-6.8-15.8-11-25.9-11-37.5 0-49.8 50.4-15.5 67.5-1.2 5.4-1.8 11-1.8 16.7 0 56.5 63.7 102.3 141.9 102.3 78.5 0 142.2-45.8 142.2-102.3 0-5.7-.6-11.6-2.1-17 33.6-17.2 21.2-67.2-16.1-67.2z" } }, "free": ["brands"] }, "square-root-variable": { "aliases": { "names": ["square-root-alt"], "unicodes": { "secondary": ["10f698"] } }, "changes": ["5.3.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["arithmetic", "calculus", "division", "math"] }, "styles": ["solid"], "unicode": "f698", "label": "Square Root Variable", "voted": false, "svg": { "solid": { "last_modified": 1684767245, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M282.6 78.1c8-27.3 33-46.1 61.4-46.1H544c17.7 0 32 14.3 32 32s-14.3 32-32 32H344L238.7 457c-3.6 12.3-14.1 21.2-26.8 22.8s-25.1-4.6-31.5-15.6L77.6 288H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H77.6c22.8 0 43.8 12.1 55.3 31.8l65.2 111.8L282.6 78.1zM393.4 233.4c12.5-12.5 32.8-12.5 45.3 0L480 274.7l41.4-41.4c12.5-12.5 32.8-12.5 45.3 0s12.5 32.8 0 45.3L525.3 320l41.4 41.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L480 365.3l-41.4 41.4c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L434.7 320l-41.4-41.4c-12.5-12.5-12.5-32.8 0-45.3z" } }, "free": ["solid"] }, "square-rss": { "aliases": { "names": ["rss-square"], "unicodes": { "secondary": ["10f143"] } }, "changes": ["3.1.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["blog", "feed", "journal", "news", "writing"] }, "styles": ["solid"], "unicode": "f143", "label": "Square Rss", "voted": false, "svg": { "solid": { "last_modified": 1684766676, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zM96 136c0-13.3 10.7-24 24-24c137 0 248 111 248 248c0 13.3-10.7 24-24 24s-24-10.7-24-24c0-110.5-89.5-200-200-200c-13.3 0-24-10.7-24-24zm0 96c0-13.3 10.7-24 24-24c83.9 0 152 68.1 152 152c0 13.3-10.7 24-24 24s-24-10.7-24-24c0-57.4-46.6-104-104-104c-13.3 0-24-10.7-24-24zm0 120a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z" } }, "free": ["solid"] }, "square-share-nodes": { "aliases": { "names": ["share-alt-square"], "unicodes": { "secondary": ["10f1e1"] } }, "changes": [ "4.1.0", "5.0.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["forward", "save", "send", "social"] }, "styles": ["solid"], "unicode": "f1e1", "label": "Square Share Nodes", "voted": false, "svg": { "solid": { "last_modified": 1684767551, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zM384 160c0 35.3-28.7 64-64 64c-15.4 0-29.5-5.4-40.6-14.5L194.1 256l85.3 46.5c11-9.1 25.2-14.5 40.6-14.5c35.3 0 64 28.7 64 64s-28.7 64-64 64s-64-28.7-64-64c0-2.5 .1-4.9 .4-7.3L174.5 300c-11.7 12.3-28.2 20-46.5 20c-35.3 0-64-28.7-64-64s28.7-64 64-64c18.3 0 34.8 7.7 46.5 20l81.9-44.7c-.3-2.4-.4-4.9-.4-7.3c0-35.3 28.7-64 64-64s64 28.7 64 64z" } }, "free": ["solid"] }, "square-snapchat": { "aliases": { "names": ["snapchat-square"] }, "changes": ["4.6.0", "5.0.0", "6.0.0-beta1", "6.1.2"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f2ad", "label": "Snapchat Square", "voted": false, "svg": { "brands": { "last_modified": 1660014480, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M384,32H64A64,64,0,0,0,0,96V416a64,64,0,0,0,64,64H384a64,64,0,0,0,64-64V96A64,64,0,0,0,384,32Zm-3.907,319.309-.083.1a32.364,32.364,0,0,1-8.717,6.823,90.26,90.26,0,0,1-20.586,8.2,12.694,12.694,0,0,0-3.852,1.76c-2.158,1.909-2.1,4.64-4.4,8.55a23.137,23.137,0,0,1-6.84,7.471c-6.707,4.632-14.244,4.923-22.23,5.23-7.214.274-15.39.581-24.729,3.669-3.761,1.245-7.753,3.694-12.377,6.533-11.265,6.9-26.68,16.353-52.3,16.353s-40.925-9.4-52.106-16.279c-4.657-2.888-8.675-5.362-12.543-6.64-9.339-3.08-17.516-3.4-24.729-3.67-7.986-.307-15.523-.6-22.231-5.229a23.085,23.085,0,0,1-6.01-6.11c-3.2-4.632-2.855-7.8-5.254-9.895a13.428,13.428,0,0,0-4.1-1.834,89.986,89.986,0,0,1-20.313-8.127,32.905,32.905,0,0,1-8.3-6.284c-6.583-6.757-8.276-14.776-5.686-21.824,3.436-9.338,11.571-12.111,19.4-16.262,14.776-8.027,26.348-18.055,34.433-29.884a68.236,68.236,0,0,0,5.985-10.567c.789-2.158.772-3.329.241-4.416a7.386,7.386,0,0,0-2.208-2.217c-2.532-1.676-5.113-3.353-6.882-4.5-3.27-2.141-5.868-3.818-7.529-4.98-6.267-4.383-10.65-9.04-13.4-14.245a28.4,28.4,0,0,1-1.369-23.584c4.134-10.924,14.469-17.706,26.978-17.706a37.141,37.141,0,0,1,7.845.83c.689.15,1.37.307,2.042.482-.108-7.43.058-15.357.722-23.119,2.358-27.261,11.912-41.589,21.874-52.994a86.836,86.836,0,0,1,22.28-17.931C188.254,100.383,205.312,96,224,96s35.828,4.383,50.944,13.016a87.169,87.169,0,0,1,22.239,17.9c9.961,11.406,19.516,25.709,21.874,52.995a231.194,231.194,0,0,1,.713,23.118c.673-.174,1.362-.332,2.051-.481a37.131,37.131,0,0,1,7.844-.83c12.5,0,22.82,6.782,26.971,17.706a28.37,28.37,0,0,1-1.4,23.559c-2.74,5.2-7.123,9.861-13.39,14.244-1.668,1.187-4.258,2.864-7.529,4.981-1.835,1.187-4.541,2.947-7.164,4.682a6.856,6.856,0,0,0-1.951,2.034c-.506,1.046-.539,2.191.166,4.208a69.015,69.015,0,0,0,6.085,10.792c8.268,12.1,20.188,22.313,35.454,30.407,1.486.772,2.98,1.5,4.441,2.258.722.332,1.569.763,2.491,1.3,4.9,2.723,9.2,6.01,11.455,12.153C387.821,336.915,386.269,344.7,380.093,351.309Zm-16.719-18.461c-50.313-24.314-58.332-61.918-58.689-64.749-.431-3.379-.921-6.035,2.806-9.472,3.594-3.328,19.541-13.19,23.965-16.278,7.33-5.114,10.534-10.219,8.16-16.495-1.66-4.316-5.686-5.976-9.961-5.976a18.5,18.5,0,0,0-3.993.448c-8.035,1.743-15.838,5.769-20.354,6.857a7.1,7.1,0,0,1-1.66.224c-2.408,0-3.279-1.071-3.088-3.968.564-8.783,1.759-25.925.373-41.937-1.884-22.032-8.99-32.948-17.432-42.6-4.051-4.624-23.135-24.654-59.536-24.654S168.53,134.359,164.479,139c-8.434,9.654-15.531,20.57-17.432,42.6-1.386,16.013-.141,33.147.373,41.937.166,2.756-.68,3.968-3.088,3.968a7.1,7.1,0,0,1-1.66-.224c-4.507-1.087-12.31-5.113-20.346-6.856a18.494,18.494,0,0,0-3.993-.449c-4.25,0-8.3,1.636-9.961,5.977-2.374,6.276.847,11.381,8.168,16.494,4.425,3.088,20.371,12.958,23.966,16.279,3.719,3.437,3.237,6.093,2.805,9.471-.356,2.79-8.384,40.394-58.689,64.749-2.946,1.428-7.96,4.45.88,9.331,13.88,7.628,23.111,6.807,30.3,11.43,6.093,3.927,2.5,12.394,6.923,15.449,5.454,3.76,21.583-.266,42.335,6.6,17.433,5.744,28.116,22.015,58.963,22.015s41.788-16.3,58.938-21.973c20.795-6.865,36.89-2.839,42.336-6.6,4.433-3.055.822-11.522,6.923-15.448,7.181-4.624,16.411-3.8,30.3-11.472C371.36,337.355,366.346,334.333,363.374,332.848Z" } }, "free": ["brands"] }, "square-steam": { "aliases": { "names": ["steam-square"] }, "changes": ["4.1.0", "5.0.0", "6.1.2"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f1b7", "label": "Steam Square", "voted": false, "svg": { "brands": { "last_modified": 1660014474, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M185.2 356.5c7.7-18.5-1-39.7-19.6-47.4l-29.5-12.2c11.4-4.3 24.3-4.5 36.4.5 12.2 5.1 21.6 14.6 26.7 26.7 5 12.2 5 25.6-.1 37.7-10.5 25.1-39.4 37-64.6 26.5-11.6-4.8-20.4-13.6-25.4-24.2l28.5 11.8c18.6 7.8 39.9-.9 47.6-19.4zM400 32H48C21.5 32 0 53.5 0 80v160.7l116.6 48.1c12-8.2 26.2-12.1 40.7-11.3l55.4-80.2v-1.1c0-48.2 39.3-87.5 87.6-87.5s87.6 39.3 87.6 87.5c0 49.2-40.9 88.7-89.6 87.5l-79 56.3c1.6 38.5-29.1 68.8-65.7 68.8-31.8 0-58.5-22.7-64.5-52.7L0 319.2V432c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-99.7 222.5c-32.2 0-58.4-26.1-58.4-58.3s26.2-58.3 58.4-58.3 58.4 26.2 58.4 58.3-26.2 58.3-58.4 58.3zm.1-14.6c24.2 0 43.9-19.6 43.9-43.8 0-24.2-19.6-43.8-43.9-43.8-24.2 0-43.9 19.6-43.9 43.8 0 24.2 19.7 43.8 43.9 43.8z" } }, "free": ["brands"] }, "square-threads": { "changes": ["6.4.1", "6.4.2"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e619", "label": "Square Threads", "voted": false, "svg": { "brands": { "last_modified": 1690904784, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zM294.2 244.3c19.5 9.3 33.7 23.5 41.2 40.9c10.4 24.3 11.4 63.9-20.2 95.4c-24.2 24.1-53.5 35-95.1 35.3h-.2c-46.8-.3-82.8-16.1-106.9-46.8C91.5 341.8 80.4 303.7 80 256v-.1-.1c.4-47.7 11.5-85.7 33-113.1c24.2-30.7 60.2-46.5 106.9-46.8h.2c46.9 .3 83.3 16 108.2 46.6c12.3 15.1 21.3 33.3 27 54.4l-26.9 7.2c-4.7-17.2-11.9-31.9-21.4-43.6c-19.4-23.9-48.7-36.1-87-36.4c-38 .3-66.8 12.5-85.5 36.2c-17.5 22.3-26.6 54.4-26.9 95.5c.3 41.1 9.4 73.3 26.9 95.5c18.7 23.8 47.4 36 85.5 36.2c34.3-.3 56.9-8.4 75.8-27.3c21.5-21.5 21.1-47.9 14.2-64c-4-9.4-11.4-17.3-21.3-23.3c-2.4 18-7.9 32.2-16.5 43.2c-11.4 14.5-27.7 22.4-48.4 23.5c-15.7 .9-30.8-2.9-42.6-10.7c-13.9-9.2-22-23.2-22.9-39.5c-1.7-32.2 23.8-55.3 63.5-57.6c14.1-.8 27.3-.2 39.5 1.9c-1.6-9.9-4.9-17.7-9.8-23.4c-6.7-7.8-17.1-11.8-30.8-11.9h-.4c-11 0-26 3.1-35.6 17.6l-23-15.8c12.8-19.4 33.6-30.1 58.5-30.1h.6c41.8 .3 66.6 26.3 69.1 71.8c1.4 .6 2.8 1.2 4.2 1.9l.1 .5zm-71.8 67.5c17-.9 36.4-7.6 39.7-48.8c-8.8-1.9-18.6-2.9-29-2.9c-3.2 0-6.4 .1-9.6 .3c-28.6 1.6-38.1 15.5-37.4 27.9c.9 16.7 19 24.5 36.4 23.6l-.1-.1z" } }, "free": ["brands"] }, "square-tumblr": { "aliases": { "names": ["tumblr-square"] }, "changes": ["3.2.0", "5.0.0", "6.1.2"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f174", "label": "Tumblr Square", "voted": false, "svg": { "brands": { "last_modified": 1660014463, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-82.3 364.2c-8.5 9.1-31.2 19.8-60.9 19.8-75.5 0-91.9-55.5-91.9-87.9v-90h-29.7c-3.4 0-6.2-2.8-6.2-6.2v-42.5c0-4.5 2.8-8.5 7.1-10 38.8-13.7 50.9-47.5 52.7-73.2.5-6.9 4.1-10.2 10-10.2h44.3c3.4 0 6.2 2.8 6.2 6.2v72h51.9c3.4 0 6.2 2.8 6.2 6.2v51.1c0 3.4-2.8 6.2-6.2 6.2h-52.1V321c0 21.4 14.8 33.5 42.5 22.4 3-1.2 5.6-2 8-1.4 2.2.5 3.6 2.1 4.6 4.9l13.8 40.2c1 3.2 2 6.7-.3 9.1z" } }, "free": ["brands"] }, "square-twitter": { "aliases": { "names": ["twitter-square"] }, "changes": ["1.0.0", "5.0.0", "6.1.2", "6.4.2"], "ligatures": [], "search": { "terms": ["social network", "tweet"] }, "styles": ["brands"], "unicode": "f081", "label": "Square Twitter", "voted": false, "svg": { "brands": { "last_modified": 1690904784, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zM351.3 199.3v0c0 86.7-66 186.6-186.6 186.6c-37.2 0-71.7-10.8-100.7-29.4c5.3 .6 10.4 .8 15.8 .8c30.7 0 58.9-10.4 81.4-28c-28.8-.6-53-19.5-61.3-45.5c10.1 1.5 19.2 1.5 29.6-1.2c-30-6.1-52.5-32.5-52.5-64.4v-.8c8.7 4.9 18.9 7.9 29.6 8.3c-9-6-16.4-14.1-21.5-23.6s-7.8-20.2-7.7-31c0-12.2 3.2-23.4 8.9-33.1c32.3 39.8 80.8 65.8 135.2 68.6c-9.3-44.5 24-80.6 64-80.6c18.9 0 35.9 7.9 47.9 20.7c14.8-2.8 29-8.3 41.6-15.8c-4.9 15.2-15.2 28-28.8 36.1c13.2-1.4 26-5.1 37.8-10.2c-8.9 13.1-20.1 24.7-32.9 34c.2 2.8 .2 5.7 .2 8.5z" } }, "free": ["brands"] }, "square-up-right": { "aliases": { "names": ["external-link-square-alt"], "unicodes": { "composite": ["2197"], "secondary": ["10f360"] } }, "changes": ["5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "arrow", "diagonal", "direction", "external-link-square", "intercardinal", "new", "northeast", "open", "share", "up-right arrow" ] }, "styles": ["solid"], "unicode": "f360", "label": "Square Up Right", "voted": false, "svg": { "solid": { "last_modified": 1684766332, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M384 32c35.3 0 64 28.7 64 64V416c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V96C0 60.7 28.7 32 64 32H384zM320 313.4V176c0-8.8-7.2-16-16-16H166.6c-12.5 0-22.6 10.1-22.6 22.6c0 6 2.4 11.8 6.6 16L184 232l-66.3 66.3C114 302 112 306.9 112 312s2 10 5.7 13.7l36.7 36.7c3.6 3.6 8.5 5.7 13.7 5.7s10-2 13.7-5.7L248 296l33.4 33.4c4.2 4.2 10 6.6 16 6.6c12.5 0 22.6-10.1 22.6-22.6z" } }, "free": ["solid"] }, "square-viadeo": { "aliases": { "names": ["viadeo-square"] }, "changes": ["4.6.0", "5.0.0", "5.7.0", "6.1.2"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f2aa", "label": "Viadeo Square", "voted": false, "svg": { "brands": { "last_modified": 1660014478, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM280.7 381.2c-42.4 46.2-120 46.6-162.4 0-68-73.6-19.8-196.1 81.2-196.1 13.3 0 26.6 2.1 39.1 6.7-4.3 8.4-7.3 17.6-8.4 27.1-9.7-4.1-20.2-6-30.7-6-48.8 0-84.6 41.7-84.6 88.9 0 43 28.5 78.7 69.5 85.9 61.5-24 72.9-117.6 72.9-175 0-7.3 0-14.8-.6-22.1-11.2-32.9-26.6-64.6-44.2-94.5 27.1 18.3 41.9 62.5 44.2 94.1v.4c7.7 22.5 11.8 46.2 11.8 70 0 54.1-21.9 99-68.3 128.2l-2.4.2c50 1 86.2-38.6 86.2-87.2 0-12.2-2.1-24.3-6.9-35.7 9.5-1.9 18.5-5.6 26.4-10.5 15.3 36.6 12.6 87.3-22.8 125.6zM309 233.7c-13.3 0-25.1-7.1-34.4-16.1 21.9-12 49.6-30.7 62.3-53 1.5-3 4.1-8.6 4.5-12-12.5 27.9-44.2 49.8-73.9 56.7-4.7-7.3-7.5-15.5-7.5-24.3 0-10.3 5.2-24.1 12.9-31.6 21.6-20.5 53-8.5 72.4-50 32.5 46.2 13.1 130.3-36.3 130.3z" } }, "free": ["brands"] }, "square-vimeo": { "aliases": { "names": ["vimeo-square"] }, "changes": ["4.0.0", "5.0.0", "6.1.2"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f194", "label": "Vimeo Square", "voted": false, "svg": { "brands": { "last_modified": 1660014474, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-16.2 149.6c-1.4 31.1-23.2 73.8-65.3 127.9-43.5 56.5-80.3 84.8-110.4 84.8-18.7 0-34.4-17.2-47.3-51.6-25.2-92.3-35.9-146.4-56.7-146.4-2.4 0-10.8 5-25.1 15.1L64 192c36.9-32.4 72.1-68.4 94.1-70.4 24.9-2.4 40.2 14.6 46 51.1 20.5 129.6 29.6 149.2 66.8 90.5 13.4-21.2 20.6-37.2 21.5-48.3 3.4-32.8-25.6-30.6-45.2-22.2 15.7-51.5 45.8-76.5 90.1-75.1 32.9 1 48.4 22.4 46.5 64z" } }, "free": ["brands"] }, "square-virus": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "coronavirus", "covid-19", "disease", "flu", "infection", "pandemic" ] }, "styles": ["solid"], "unicode": "e578", "label": "Square Virus", "voted": false, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zM223.8 93.7c13.3 0 24 10.7 24 24c0 29.3 35.4 43.9 56.1 23.2c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9c-20.7 20.7-6 56.1 23.2 56.1c13.3 0 24 10.7 24 24s-10.7 24-24 24c-29.3 0-43.9 35.4-23.2 56.1c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0c-20.7-20.7-56.1-6-56.1 23.2c0 13.3-10.7 24-24 24s-24-10.7-24-24c0-29.3-35.4-43.9-56.1-23.2c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9c20.7-20.7 6-56.1-23.2-56.1c-13.3 0-24-10.7-24-24s10.7-24 24-24c29.3 0 43.9-35.4 23.2-56.1c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0c20.7 20.7 56.1 6 56.1-23.2c0-13.3 10.7-24 24-24zM192 256a32 32 0 1 0 0-64 32 32 0 1 0 0 64zm88 32a24 24 0 1 0 -48 0 24 24 0 1 0 48 0z" } }, "free": ["solid"] }, "square-whatsapp": { "aliases": { "names": ["whatsapp-square"] }, "changes": ["5.0.0", "6.1.2"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f40c", "label": "What's App Square", "voted": false, "svg": { "brands": { "last_modified": 1660014460, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M224 122.8c-72.7 0-131.8 59.1-131.9 131.8 0 24.9 7 49.2 20.2 70.1l3.1 5-13.3 48.6 49.9-13.1 4.8 2.9c20.2 12 43.4 18.4 67.1 18.4h.1c72.6 0 133.3-59.1 133.3-131.8 0-35.2-15.2-68.3-40.1-93.2-25-25-58-38.7-93.2-38.7zm77.5 188.4c-3.3 9.3-19.1 17.7-26.7 18.8-12.6 1.9-22.4.9-47.5-9.9-39.7-17.2-65.7-57.2-67.7-59.8-2-2.6-16.2-21.5-16.2-41s10.2-29.1 13.9-33.1c3.6-4 7.9-5 10.6-5 2.6 0 5.3 0 7.6.1 2.4.1 5.7-.9 8.9 6.8 3.3 7.9 11.2 27.4 12.2 29.4s1.7 4.3.3 6.9c-7.6 15.2-15.7 14.6-11.6 21.6 15.3 26.3 30.6 35.4 53.9 47.1 4 2 6.3 1.7 8.6-1 2.3-2.6 9.9-11.6 12.5-15.5 2.6-4 5.3-3.3 8.9-2 3.6 1.3 23.1 10.9 27.1 12.9s6.6 3 7.6 4.6c.9 1.9.9 9.9-2.4 19.1zM400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM223.9 413.2c-26.6 0-52.7-6.7-75.8-19.3L64 416l22.5-82.2c-13.9-24-21.2-51.3-21.2-79.3C65.4 167.1 136.5 96 223.9 96c42.4 0 82.2 16.5 112.2 46.5 29.9 30 47.9 69.8 47.9 112.2 0 87.4-72.7 158.5-160.1 158.5z" } }, "free": ["brands"] }, "square-x-twitter": { "changes": ["6.4.2"], "ligatures": [], "search": { "terms": [" elon", " x", "twitter"] }, "styles": ["brands"], "unicode": "e61a", "label": "Square X Twitter", "voted": false, "svg": { "brands": { "last_modified": 1690904784, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zm297.1 84L257.3 234.6 379.4 396H283.8L209 298.1 123.3 396H75.8l111-126.9L69.7 116h98l67.7 89.5L313.6 116h47.5zM323.3 367.6L153.4 142.9H125.1L296.9 367.6h26.3z" } }, "free": ["brands"] }, "square-xing": { "aliases": { "names": ["xing-square"] }, "changes": ["3.2.0", "5.0.0", "6.1.2"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f169", "label": "Xing Square", "voted": false, "svg": { "brands": { "last_modified": 1660014469, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM140.4 320.2H93.8c-5.5 0-8.7-5.3-6-10.3l49.3-86.7c.1 0 .1-.1 0-.2l-31.4-54c-3-5.6.2-10.1 6-10.1h46.6c5.2 0 9.5 2.9 12.9 8.7l31.9 55.3c-1.3 2.3-18 31.7-50.1 88.2-3.5 6.2-7.7 9.1-12.6 9.1zm219.7-214.1L257.3 286.8v.2l65.5 119c2.8 5.1.1 10.1-6 10.1h-46.6c-5.5 0-9.7-2.9-12.9-8.7l-66-120.3c2.3-4.1 36.8-64.9 103.4-182.3 3.3-5.8 7.4-8.7 12.5-8.7h46.9c5.7-.1 8.8 4.7 6 10z" } }, "free": ["brands"] }, "square-xmark": { "aliases": { "names": ["times-square", "xmark-square"], "unicodes": { "composite": ["274e"], "secondary": ["10f2d3"] } }, "changes": [ "4.7.0", "5.0.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "close", "cross", "cross mark button", "incorrect", "mark", "notice", "notification", "notify", "problem", "square", "window", "wrong", "x", "×" ] }, "styles": ["solid"], "unicode": "f2d3", "label": "Square Xmark", "voted": false, "svg": { "solid": { "last_modified": 1684767551, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zm79 143c9.4-9.4 24.6-9.4 33.9 0l47 47 47-47c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-47 47 47 47c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-47-47-47 47c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l47-47-47-47c-9.4-9.4-9.4-24.6 0-33.9z" } }, "free": ["solid"] }, "square-youtube": { "aliases": { "names": ["youtube-square"], "unicodes": { "composite": ["f166"] } }, "changes": ["5.0.3", "6.1.2"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f431", "label": "YouTube Square", "voted": false, "svg": { "brands": { "last_modified": 1660014476, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M186.8 202.1l95.2 54.1-95.2 54.1V202.1zM448 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h352c26.5 0 48 21.5 48 48zm-42 176.3s0-59.6-7.6-88.2c-4.2-15.8-16.5-28.2-32.2-32.4C337.9 128 224 128 224 128s-113.9 0-142.2 7.7c-15.7 4.2-28 16.6-32.2 32.4-7.6 28.5-7.6 88.2-7.6 88.2s0 59.6 7.6 88.2c4.2 15.8 16.5 27.7 32.2 31.9C110.1 384 224 384 224 384s113.9 0 142.2-7.7c15.7-4.2 28-16.1 32.2-31.9 7.6-28.5 7.6-88.1 7.6-88.1z" } }, "free": ["brands"] }, "squarespace": { "changes": ["5.1.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f5be", "label": "Squarespace", "voted": true, "svg": { "brands": { "last_modified": 1660014472, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M186.12 343.34c-9.65 9.65-9.65 25.29 0 34.94 9.65 9.65 25.29 9.65 34.94 0L378.24 221.1c19.29-19.29 50.57-19.29 69.86 0s19.29 50.57 0 69.86L293.95 445.1c19.27 19.29 50.53 19.31 69.82.04l.04-.04 119.25-119.24c38.59-38.59 38.59-101.14 0-139.72-38.59-38.59-101.15-38.59-139.72 0l-157.22 157.2zm244.53-104.8c-9.65-9.65-25.29-9.65-34.93 0l-157.2 157.18c-19.27 19.29-50.53 19.31-69.82.05l-.05-.05c-9.64-9.64-25.27-9.65-34.92-.01l-.01.01c-9.65 9.64-9.66 25.28-.02 34.93l.02.02c38.58 38.57 101.14 38.57 139.72 0l157.2-157.2c9.65-9.65 9.65-25.29.01-34.93zm-261.99 87.33l157.18-157.18c9.64-9.65 9.64-25.29 0-34.94-9.64-9.64-25.27-9.64-34.91 0L133.72 290.93c-19.28 19.29-50.56 19.3-69.85.01l-.01-.01c-19.29-19.28-19.31-50.54-.03-69.84l.03-.03L218.03 66.89c-19.28-19.29-50.55-19.3-69.85-.02l-.02.02L28.93 186.14c-38.58 38.59-38.58 101.14 0 139.72 38.6 38.59 101.13 38.59 139.73.01zm-87.33-52.4c9.64 9.64 25.27 9.64 34.91 0l157.21-157.19c19.28-19.29 50.55-19.3 69.84-.02l.02.02c9.65 9.65 25.29 9.65 34.93 0 9.65-9.65 9.65-25.29 0-34.93-38.59-38.59-101.13-38.59-139.72 0L81.33 238.54c-9.65 9.64-9.65 25.28-.01 34.93h.01z" } }, "free": ["brands"] }, "stack-exchange": { "changes": ["4.0.0", "5.0.0", "5.0.3"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f18d", "label": "Stack Exchange", "voted": false, "svg": { "brands": { "last_modified": 1660014467, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M17.7 332.3h412.7v22c0 37.7-29.3 68-65.3 68h-19L259.3 512v-89.7H83c-36 0-65.3-30.3-65.3-68v-22zm0-23.6h412.7v-85H17.7v85zm0-109.4h412.7v-85H17.7v85zM365 0H83C47 0 17.7 30.3 17.7 67.7V90h412.7V67.7C430.3 30.3 401 0 365 0z" } }, "free": ["brands"] }, "stack-overflow": { "changes": ["3.2.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f16c", "label": "Stack Overflow", "voted": false, "svg": { "brands": { "last_modified": 1660014479, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M290.7 311L95 269.7 86.8 309l195.7 41zm51-87L188.2 95.7l-25.5 30.8 153.5 128.3zm-31.2 39.7L129.2 179l-16.7 36.5L293.7 300zM262 32l-32 24 119.3 160.3 32-24zm20.5 328h-200v39.7h200zm39.7 80H42.7V320h-40v160h359.5V320h-40z" } }, "free": ["brands"] }, "stackpath": { "changes": ["5.8.2"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f842", "label": "Stackpath", "voted": false, "svg": { "brands": { "last_modified": 1660014482, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M244.6 232.4c0 8.5-4.26 20.49-21.34 20.49h-19.61v-41.47h19.61c17.13 0 21.34 12.36 21.34 20.98zM448 32v448H0V32zM151.3 287.84c0-21.24-12.12-34.54-46.72-44.85-20.57-7.41-26-10.91-26-18.63s7-14.61 20.41-14.61c14.09 0 20.79 8.45 20.79 18.35h30.7l.19-.57c.5-19.57-15.06-41.65-51.12-41.65-23.37 0-52.55 10.75-52.55 38.29 0 19.4 9.25 31.29 50.74 44.37 17.26 6.15 21.91 10.4 21.91 19.48 0 15.2-19.13 14.23-19.47 14.23-20.4 0-25.65-9.1-25.65-21.9h-30.8l-.18.56c-.68 31.32 28.38 45.22 56.63 45.22 29.98 0 51.12-13.55 51.12-38.29zm125.38-55.63c0-25.3-18.43-45.46-53.42-45.46h-51.78v138.18h32.17v-47.36h19.61c30.25 0 53.42-15.95 53.42-45.36zM297.94 325L347 186.78h-31.09L268 325zm106.52-138.22h-31.09L325.46 325h29.94z" } }, "free": ["brands"] }, "staff-snake": { "aliases": { "names": ["rod-asclepius", "rod-snake", "staff-aesculapius"] }, "changes": ["6.1.0", "6.1.2", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["asclepius", "asklepian", "health", "serpent", "wellness"] }, "styles": ["solid"], "unicode": "e579", "label": "Staff Snake", "voted": false, "svg": { "solid": { "last_modified": 1684766751, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M222.6 43.2l-.1 4.8H288c53 0 96 43 96 96s-43 96-96 96H248V160h40c8.8 0 16-7.2 16-16s-7.2-16-16-16H248 220l-4.5 144H256c53 0 96 43 96 96s-43 96-96 96H240V384h16c8.8 0 16-7.2 16-16s-7.2-16-16-16H213l-3.1 99.5L208.5 495l0 1c-.3 8.9-7.6 16-16.5 16s-16.2-7.1-16.5-16l0-1-1-31H136c-22.1 0-40-17.9-40-40s17.9-40 40-40h36l-1-32H152c-53 0-96-43-96-96c0-47.6 34.6-87.1 80-94.7V256c0 8.8 7.2 16 16 16h16.5L164 128H136 122.6c-9 18.9-28.3 32-50.6 32H56c-30.9 0-56-25.1-56-56S25.1 48 56 48h8 8 89.5l-.1-4.8L161 32c0-.7 0-1.3 0-1.9c.5-16.6 14.1-30 31-30s30.5 13.4 31 30c0 .6 0 1.3 0 1.9l-.4 11.2zM64 112a16 16 0 1 0 0-32 16 16 0 1 0 0 32z" } }, "free": ["solid"] }, "stairs": { "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["exit", "steps", "up"] }, "styles": ["solid"], "unicode": "e289", "label": "Stairs", "voted": true, "svg": { "solid": { "last_modified": 1684767621, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M384 64c0-17.7 14.3-32 32-32H544c17.7 0 32 14.3 32 32s-14.3 32-32 32H448v96c0 17.7-14.3 32-32 32H320v96c0 17.7-14.3 32-32 32H192v96c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32h96V320c0-17.7 14.3-32 32-32h96V192c0-17.7 14.3-32 32-32h96V64z" } }, "free": ["solid"] }, "stamp": { "aliases": { "unicodes": { "secondary": ["10f5bf"] } }, "changes": [ "5.1.0", "5.10.2", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["art", "certificate", "imprint", "rubber", "seal"] }, "styles": ["solid"], "unicode": "f5bf", "label": "Stamp", "voted": false, "svg": { "solid": { "last_modified": 1684767368, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M312 201.8c0-17.4 9.2-33.2 19.9-47C344.5 138.5 352 118.1 352 96c0-53-43-96-96-96s-96 43-96 96c0 22.1 7.5 42.5 20.1 58.8c10.7 13.8 19.9 29.6 19.9 47c0 29.9-24.3 54.2-54.2 54.2H112C50.1 256 0 306.1 0 368c0 20.9 13.4 38.7 32 45.3V464c0 26.5 21.5 48 48 48H432c26.5 0 48-21.5 48-48V413.3c18.6-6.6 32-24.4 32-45.3c0-61.9-50.1-112-112-112H366.2c-29.9 0-54.2-24.3-54.2-54.2zM416 416v32H96V416H416z" } }, "free": ["solid"] }, "stapler": { "changes": ["6.1.2", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["desktop", "milton", "office", "paperclip", "staple"] }, "styles": ["solid"], "unicode": "e5af", "label": "Stapler", "voted": false, "svg": { "solid": { "last_modified": 1684767366, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M640 299.3V304 432c0 26.5-21.5 48-48 48H512 448 64c-17.7 0-32-14.3-32-32s14.3-32 32-32H448V368H96c-17.7 0-32-14.3-32-32V219.4L33.8 214C14.2 210.5 0 193.5 0 173.7c0-8.9 2.9-17.5 8.2-24.6l35.6-47.5C76.7 57.8 128.2 32 182.9 32c27 0 53.6 6.3 77.8 18.4L586.9 213.5C619.5 229.7 640 263 640 299.3zM448 304V288L128 230.9V304H448z" } }, "free": ["solid"] }, "star": { "aliases": { "unicodes": { "composite": ["2b50", "f006"], "secondary": ["10f005"] } }, "changes": [ "1.0.0", "5.0.0", "5.10.2", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "achievement", "award", "favorite", "important", "night", "rating", "score", "star" ] }, "styles": ["solid", "regular"], "unicode": "f005", "label": "Star", "voted": false, "svg": { "solid": { "last_modified": 1684767552, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M316.9 18C311.6 7 300.4 0 288.1 0s-23.4 7-28.8 18L195 150.3 51.4 171.5c-12 1.8-22 10.2-25.7 21.7s-.7 24.2 7.9 32.7L137.8 329 113.2 474.7c-2 12 3 24.2 12.9 31.3s23 8 33.8 2.3l128.3-68.5 128.3 68.5c10.8 5.7 23.9 4.9 33.8-2.3s14.9-19.3 12.9-31.3L438.5 329 542.7 225.9c8.6-8.5 11.7-21.2 7.9-32.7s-13.7-19.9-25.7-21.7L381.2 150.3 316.9 18z" }, "regular": { "last_modified": 1684767552, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M287.9 0c9.2 0 17.6 5.2 21.6 13.5l68.6 141.3 153.2 22.6c9 1.3 16.5 7.6 19.3 16.3s.5 18.1-5.9 24.5L433.6 328.4l26.2 155.6c1.5 9-2.2 18.1-9.6 23.5s-17.3 6-25.3 1.7l-137-73.2L151 509.1c-8.1 4.3-17.9 3.7-25.3-1.7s-11.2-14.5-9.7-23.5l26.2-155.6L31.1 218.2c-6.5-6.4-8.7-15.9-5.9-24.5s10.3-14.9 19.3-16.3l153.2-22.6L266.3 13.5C270.4 5.2 278.7 0 287.9 0zm0 79L235.4 187.2c-3.5 7.1-10.2 12.1-18.1 13.3L99 217.9 184.9 303c5.5 5.5 8.1 13.3 6.8 21L171.4 443.7l105.2-56.2c7.1-3.8 15.6-3.8 22.6 0l105.2 56.2L384.2 324.1c-1.3-7.7 1.2-15.5 6.8-21l85.9-85.1L358.6 200.5c-7.8-1.2-14.6-6.1-18.1-13.3L287.9 79z" } }, "free": ["regular", "solid"] }, "star-and-crescent": { "aliases": { "unicodes": { "composite": ["262a"], "secondary": ["10f699"] } }, "changes": ["5.3.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Muslim", "islam", "muslim", "religion", "star and crescent"] }, "styles": ["solid"], "unicode": "f699", "label": "Star And Crescent", "voted": false, "svg": { "solid": { "last_modified": 1684767603, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 256C0 114.6 114.6 0 256 0c33 0 64.6 6.3 93.6 17.7c7.4 2.9 11.5 10.7 9.8 18.4s-8.8 13-16.7 12.4c-4.8-.3-9.7-.5-14.6-.5c-114.9 0-208 93.1-208 208s93.1 208 208 208c4.9 0 9.8-.2 14.6-.5c7.9-.5 15 4.7 16.7 12.4s-2.4 15.5-9.8 18.4C320.6 505.7 289 512 256 512C114.6 512 0 397.4 0 256zM375.4 137.4c3.5-7.1 13.7-7.1 17.2 0l31.5 63.8c1.4 2.8 4.1 4.8 7.2 5.3l70.4 10.2c7.9 1.1 11 10.8 5.3 16.4l-50.9 49.6c-2.3 2.2-3.3 5.4-2.8 8.5l12 70.1c1.3 7.8-6.9 13.8-13.9 10.1l-63-33.1c-2.8-1.5-6.1-1.5-8.9 0l-63 33.1c-7 3.7-15.3-2.3-13.9-10.1l12-70.1c.5-3.1-.5-6.3-2.8-8.5L261 233.1c-5.7-5.6-2.6-15.2 5.3-16.4l70.4-10.2c3.1-.5 5.8-2.4 7.2-5.3l31.5-63.8z" } }, "free": ["solid"] }, "star-half": { "aliases": { "unicodes": { "composite": ["f123"], "secondary": ["10f089"] } }, "changes": [ "1.0.0", "5.0.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "achievement", "award", "rating", "score", "star-half-empty", "star-half-full" ] }, "styles": ["solid", "regular"], "unicode": "f089", "label": "Star Half", "voted": false, "svg": { "solid": { "last_modified": 1684767551, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M288 0c-12.2 .1-23.3 7-28.6 18L195 150.3 51.4 171.5c-12 1.8-22 10.2-25.7 21.7s-.7 24.2 7.9 32.7L137.8 329 113.2 474.7c-2 12 3 24.2 12.9 31.3s23 8 33.8 2.3L288 439.8V0zM429.9 512c1.1 .1 2.1 .1 3.2 0h-3.2z" }, "regular": { "last_modified": 1684767551, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M293.3 .6c10.9 2.5 18.6 12.2 18.6 23.4V408.7c0 8.9-4.9 17-12.7 21.2L151 509.1c-8.1 4.3-17.9 3.7-25.3-1.7s-11.2-14.5-9.7-23.5l26.2-155.6L31.1 218.2c-6.5-6.4-8.7-15.9-5.9-24.5s10.3-14.9 19.3-16.3l153.2-22.6L266.3 13.5c4.9-10.1 16.1-15.4 27-12.9zM263.9 128.4l-28.6 58.8c-3.5 7.1-10.2 12.1-18.1 13.3L99 217.9 184.9 303c5.5 5.5 8.1 13.3 6.8 21L171.4 443.7l92.5-49.4V128.4z" } }, "free": ["regular", "solid"] }, "star-half-stroke": { "aliases": { "names": ["star-half-alt"], "unicodes": { "secondary": ["10f5c0"] } }, "changes": [ "5.1.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "achievement", "award", "rating", "score", "star-half-empty", "star-half-full" ] }, "styles": ["solid", "regular"], "unicode": "f5c0", "label": "Star Half Stroke", "voted": true, "svg": { "solid": { "last_modified": 1684767552, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M320 376.4l.1-.1 26.4 14.1 85.2 45.5-16.5-97.6-4.8-28.7 20.7-20.5 70.1-69.3-96.1-14.2-29.3-4.3-12.9-26.6L320.1 86.9l-.1 .3V376.4zm175.1 98.3c2 12-3 24.2-12.9 31.3s-23 8-33.8 2.3L320.1 439.8 191.8 508.3C181 514 167.9 513.1 158 506s-14.9-19.3-12.9-31.3L169.8 329 65.6 225.9c-8.6-8.5-11.7-21.2-7.9-32.7s13.7-19.9 25.7-21.7L227 150.3 291.4 18c5.4-11 16.5-18 28.8-18s23.4 7 28.8 18l64.3 132.3 143.6 21.2c12 1.8 22 10.2 25.7 21.7s.7 24.2-7.9 32.7L470.5 329l24.6 145.7z" }, "regular": { "last_modified": 1684767552, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M341.5 13.5C337.5 5.2 329.1 0 319.9 0s-17.6 5.2-21.6 13.5L229.7 154.8 76.5 177.5c-9 1.3-16.5 7.6-19.3 16.3s-.5 18.1 5.9 24.5L174.2 328.4 148 483.9c-1.5 9 2.2 18.1 9.7 23.5s17.3 6 25.3 1.7l137-73.2 137 73.2c8.1 4.3 17.9 3.7 25.3-1.7s11.2-14.5 9.7-23.5L465.6 328.4 576.8 218.2c6.5-6.4 8.7-15.9 5.9-24.5s-10.3-14.9-19.3-16.3L410.1 154.8 341.5 13.5zM320 384.7V79.1l52.5 108.1c3.5 7.1 10.2 12.1 18.1 13.3l118.3 17.5L423 303c-5.5 5.5-8.1 13.3-6.8 21l20.2 119.6L331.2 387.5c-3.5-1.9-7.4-2.8-11.2-2.8z" } }, "free": ["regular", "solid"] }, "star-of-david": { "aliases": { "unicodes": { "composite": ["2721"], "secondary": ["10f69a"] } }, "changes": [ "5.3.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "David", "Jew", "Jewish", "jewish", "judaism", "religion", "star", "star of David" ] }, "styles": ["solid"], "unicode": "f69a", "label": "Star Of David", "voted": false, "svg": { "solid": { "last_modified": 1684767602, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M404.2 309.5L383.1 344h42.3l-21.1-34.5zM371.4 256l-54-88H194.6l-54 88 54 88H317.4l54-88zm65.7 0l53.4 87c3.6 5.9 5.5 12.7 5.5 19.6c0 20.7-16.8 37.4-37.4 37.4H348.7l-56.2 91.5C284.8 504.3 270.9 512 256 512s-28.8-7.7-36.6-20.5L163.3 400H53.4C32.8 400 16 383.2 16 362.6c0-6.9 1.9-13.7 5.5-19.6l53.4-87L21.5 169c-3.6-5.9-5.5-12.7-5.5-19.6C16 128.8 32.8 112 53.4 112H163.3l56.2-91.5C227.2 7.7 241.1 0 256 0s28.8 7.7 36.6 20.5L348.7 112H458.6c20.7 0 37.4 16.8 37.4 37.4c0 6.9-1.9 13.7-5.5 19.6l-53.4 87zm-54-88l21.1 34.5L425.4 168H383.1zM283 112L256 68l-27 44h54zM128.9 168H86.6l21.1 34.5L128.9 168zM107.8 309.5L86.6 344h42.3l-21.1-34.5zM229 400l27 44 27-44H229z" } }, "free": ["solid"] }, "star-of-life": { "aliases": { "unicodes": { "secondary": ["10f621"] } }, "changes": ["5.2.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["doctor", "emt", "first aid", "health", "medical"] }, "styles": ["solid"], "unicode": "f621", "label": "Star Of Life", "voted": false, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M208 32c0-17.7 14.3-32 32-32h32c17.7 0 32 14.3 32 32V172.9l122-70.4c15.3-8.8 34.9-3.6 43.7 11.7l16 27.7c8.8 15.3 3.6 34.9-11.7 43.7L352 256l122 70.4c15.3 8.8 20.5 28.4 11.7 43.7l-16 27.7c-8.8 15.3-28.4 20.6-43.7 11.7L304 339.1V480c0 17.7-14.3 32-32 32H240c-17.7 0-32-14.3-32-32V339.1L86 409.6c-15.3 8.8-34.9 3.6-43.7-11.7l-16-27.7c-8.8-15.3-3.6-34.9 11.7-43.7L160 256 38 185.6c-15.3-8.8-20.5-28.4-11.7-43.7l16-27.7C51.1 98.8 70.7 93.6 86 102.4l122 70.4V32z" } }, "free": ["solid"] }, "staylinked": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3f5", "label": "StayLinked", "voted": false, "svg": { "brands": { "last_modified": 1660014463, "raw": "", "viewBox": [0, 0, 440, 512], "width": 440, "height": 512, "path": "M382.7 292.5l2.7 2.7-170-167.3c-3.5-3.5-9.7-3.7-13.8-.5L144.3 171c-4.2 3.2-4.6 8.7-1.1 12.2l68.1 64.3c3.6 3.5 9.9 3.7 14 .5l.1-.1c4.1-3.2 10.4-3 14 .5l84 81.3c3.6 3.5 3.2 9-.9 12.2l-93.2 74c-4.2 3.3-10.5 3.1-14.2-.4L63.2 268c-3.5-3.5-9.7-3.7-13.9-.5L3.5 302.4c-4.2 3.2-4.7 8.7-1.2 12.2L211 510.7s7.4 6.8 17.3-.8l198-163.9c4-3.2 4.4-8.7.7-12.2zm54.5-83.4L226.7 2.5c-1.5-1.2-8-5.5-16.3 1.1L3.6 165.7c-4.2 3.2-4.8 8.7-1.2 12.2l42.3 41.7 171.7 165.1c3.7 3.5 10.1 3.7 14.3.4l50.2-38.8-.3-.3 7.7-6c4.2-3.2 4.6-8.7.9-12.2l-57.1-54.4c-3.6-3.5-10-3.7-14.2-.5l-.1.1c-4.2 3.2-10.5 3.1-14.2-.4L109 180.8c-3.6-3.5-3.1-8.9 1.1-12.2l92.2-71.5c4.1-3.2 10.3-3 13.9.5l160.4 159c3.7 3.5 10 3.7 14.1.5l45.8-35.8c4.1-3.2 4.4-8.7.7-12.2z" } }, "free": ["brands"] }, "steam": { "changes": ["4.1.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f1b6", "label": "Steam", "voted": false, "svg": { "brands": { "last_modified": 1660014477, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M496 256c0 137-111.2 248-248.4 248-113.8 0-209.6-76.3-239-180.4l95.2 39.3c6.4 32.1 34.9 56.4 68.9 56.4 39.2 0 71.9-32.4 70.2-73.5l84.5-60.2c52.1 1.3 95.8-40.9 95.8-93.5 0-51.6-42-93.5-93.7-93.5s-93.7 42-93.7 93.5v1.2L176.6 279c-15.5-.9-30.7 3.4-43.5 12.1L0 236.1C10.2 108.4 117.1 8 247.6 8 384.8 8 496 119 496 256zM155.7 384.3l-30.5-12.6a52.79 52.79 0 0 0 27.2 25.8c26.9 11.2 57.8-1.6 69-28.4 5.4-13 5.5-27.3.1-40.3-5.4-13-15.5-23.2-28.5-28.6-12.9-5.4-26.7-5.2-38.9-.6l31.5 13c19.8 8.2 29.2 30.9 20.9 50.7-8.3 19.9-31 29.2-50.8 21zm173.8-129.9c-34.4 0-62.4-28-62.4-62.3s28-62.3 62.4-62.3 62.4 28 62.4 62.3-27.9 62.3-62.4 62.3zm.1-15.6c25.9 0 46.9-21 46.9-46.8 0-25.9-21-46.8-46.9-46.8s-46.9 21-46.9 46.8c.1 25.8 21.1 46.8 46.9 46.8z" } }, "free": ["brands"] }, "steam-symbol": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3f6", "label": "Steam Symbol", "voted": false, "svg": { "brands": { "last_modified": 1660014458, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M395.5 177.5c0 33.8-27.5 61-61 61-33.8 0-61-27.3-61-61s27.3-61 61-61c33.5 0 61 27.2 61 61zm52.5.2c0 63-51 113.8-113.7 113.8L225 371.3c-4 43-40.5 76.8-84.5 76.8-40.5 0-74.7-28.8-83-67L0 358V250.7L97.2 290c15.1-9.2 32.2-13.3 52-11.5l71-101.7c.5-62.3 51.5-112.8 114-112.8C397 64 448 115 448 177.7zM203 363c0-34.7-27.8-62.5-62.5-62.5-4.5 0-9 .5-13.5 1.5l26 10.5c25.5 10.2 38 39 27.7 64.5-10.2 25.5-39.2 38-64.7 27.5-10.2-4-20.5-8.3-30.7-12.2 10.5 19.7 31.2 33.2 55.2 33.2 34.7 0 62.5-27.8 62.5-62.5zm207.5-185.3c0-42-34.3-76.2-76.2-76.2-42.3 0-76.5 34.2-76.5 76.2 0 42.2 34.3 76.2 76.5 76.2 41.9.1 76.2-33.9 76.2-76.2z" } }, "free": ["brands"] }, "sterling-sign": { "aliases": { "names": ["gbp", "pound-sign"], "unicodes": { "composite": ["a3"], "secondary": ["10f154"] } }, "changes": [ "3.2.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["Pound Sign", "currency"] }, "styles": ["solid"], "unicode": "f154", "label": "Sterling Sign", "voted": false, "svg": { "solid": { "last_modified": 1684766476, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M112 160.4c0-35.5 28.8-64.4 64.4-64.4c6.9 0 13.8 1.1 20.4 3.3l81.2 27.1c16.8 5.6 34.9-3.5 40.5-20.2s-3.5-34.9-20.2-40.5L217 38.6c-13.1-4.4-26.8-6.6-40.6-6.6C105.5 32 48 89.5 48 160.4V224H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H48v44.5c0 17.4-4.7 34.5-13.7 49.4L4.6 431.5c-5.9 9.9-6.1 22.2-.4 32.2S20.5 480 32 480H288c17.7 0 32-14.3 32-32s-14.3-32-32-32H88.5l.7-1.1C104.1 390 112 361.5 112 332.5V288H224c17.7 0 32-14.3 32-32s-14.3-32-32-32H112V160.4z" } }, "free": ["solid"] }, "stethoscope": { "aliases": { "unicodes": { "composite": ["1fa7a"], "secondary": ["10f0f1"] } }, "changes": [ "3.0.0", "5.0.0", "5.0.7", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "covid-19", "diagnosis", "doctor", "general practitioner", "heart", "hospital", "infirmary", "medicine", "office", "outpatient", "stethoscope" ] }, "styles": ["solid"], "unicode": "f0f1", "label": "Stethoscope", "voted": false, "svg": { "solid": { "last_modified": 1684766751, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M142.4 21.9c5.6 16.8-3.5 34.9-20.2 40.5L96 71.1V192c0 53 43 96 96 96s96-43 96-96V71.1l-26.1-8.7c-16.8-5.6-25.8-23.7-20.2-40.5s23.7-25.8 40.5-20.2l26.1 8.7C334.4 19.1 352 43.5 352 71.1V192c0 77.2-54.6 141.6-127.3 156.7C231 404.6 278.4 448 336 448c61.9 0 112-50.1 112-112V265.3c-28.3-12.3-48-40.5-48-73.3c0-44.2 35.8-80 80-80s80 35.8 80 80c0 32.8-19.7 61-48 73.3V336c0 97.2-78.8 176-176 176c-92.9 0-168.9-71.9-175.5-163.1C87.2 334.2 32 269.6 32 192V71.1c0-27.5 17.6-52 43.8-60.7l26.1-8.7c16.8-5.6 34.9 3.5 40.5 20.2zM480 224a32 32 0 1 0 0-64 32 32 0 1 0 0 64z" } }, "free": ["solid"] }, "sticker-mule": { "changes": ["5.0.0", "5.7.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3f7", "label": "Sticker Mule", "voted": false, "svg": { "brands": { "last_modified": 1660014475, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M561.7 199.6c-1.3.3.3 0 0 0zm-6.2-77.4c-7.7-22.3-5.1-7.2-13.4-36.9-1.6-6.5-3.6-14.5-6.2-20-4.4-8.7-4.6-7.5-4.6-9.5 0-5.3 30.7-45.3 19-46.9-5.7-.6-12.2 11.6-20.6 17-8.6 4.2-8 5-10.3 5-2.6 0-5.7-3-6.2-5-2-5.7 1.9-25.9-3.6-25.9-3.6 0-12.3 24.8-17 25.8-5.2 1.3-27.9-11.4-75.1 18-25.3 13.2-86.9 65.2-87 65.3-6.7 4.7-20 4.7-35.5 16-44.4 30.1-109.6 9.4-110.7 9-110.6-26.8-128-15.2-159 11.5-20.8 17.9-23.7 36.5-24.2 38.9-4.2 20.4 5.2 48.3 6.7 64.3 1.8 19.3-2.7 17.7 7.7 98.3.5 1 4.1 0 5.1 1.5 0 8.4-3.8 12.1-4.1 13-1.5 4.5-1.5 10.5 0 16 2.3 8.2 8.2 37.2 8.2 46.9 0 41.8.4 44 2.6 49.4 3.9 10 12.5 9.1 17 12 3.1 3.5-.5 8.5 1 12.5.5 2 3.6 4 6.2 5 9.2 3.6 27 .3 29.9-2.5 1.6-1.5.5-4.5 3.1-5 5.1 0 10.8-.5 14.4-2.5 5.1-2.5 4.1-6 1.5-10.5-.4-.8-7-13.3-9.8-16-2.1-2-5.1-3-7.2-4.5-5.8-4.9-10.3-19.4-10.3-19.5-4.6-19.4-10.3-46.3-4.1-66.8 4.6-17.2 39.5-87.7 39.6-87.8 4.1-6.5 17-11.5 27.3-7 6 1.9 19.3 22 65.4 30.9 47.9 8.7 97.4-2 112.2-2 2.8 2-1.9 13-.5 38.9 0 26.4-.4 13.7-4.1 29.9-2.2 9.7 3.4 23.2-1.5 46.9-1.4 9.8-9.9 32.7-8.2 43.4.5 1 1 2 1.5 3.5.5 4.5 1.5 8.5 4.6 10 7.3 3.6 12-3.5 9.8 11.5-.7 3.1-2.6 12 1.5 15 4.4 3.7 30.6 3.4 36.5.5 2.6-1.5 1.6-4.5 6.4-7.4 1.9-.9 11.3-.4 11.3-6.5.3-1.8-9.2-19.9-9.3-20-2.6-3.5-9.2-4.5-11.3-8-6.9-10.1-1.7-52.6.5-59.4 3-11 5.6-22.4 8.7-32.4 11-42.5 10.3-50.6 16.5-68.3.8-1.8 6.4-23.1 10.3-29.9 9.3-17 21.7-32.4 33.5-47.4 18-22.9 34-46.9 52-69.8 6.1-7 8.2-13.7 18-8 10.8 5.7 21.6 7 31.9 17 14.6 12.8 10.2 18.2 11.8 22.9 1.5 5 7.7 10.5 14.9 9.5 10.4-2 13-2.5 13.4-2.5 2.6-.5 5.7-5 7.2-8 3.1-5.5 7.2-9 7.2-16.5 0-7.7-.4-2.8-20.6-52.9z" } }, "free": ["brands"] }, "stop": { "aliases": { "unicodes": { "composite": ["23f9"], "secondary": ["10f04d"] } }, "changes": [ "1.0.0", "5.0.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["block", "box", "square", "stop", "stop button"] }, "styles": ["solid"], "unicode": "f04d", "label": "Stop", "voted": false, "svg": { "solid": { "last_modified": 1684766675, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M0 128C0 92.7 28.7 64 64 64H320c35.3 0 64 28.7 64 64V384c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128z" } }, "free": ["solid"] }, "stopwatch": { "aliases": { "unicodes": { "composite": ["23f1"], "secondary": ["10f2f2"] } }, "changes": [ "5.0.0", "5.10.2", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["clock", "reminder", "stopwatch", "time"] }, "styles": ["solid"], "unicode": "f2f2", "label": "Stopwatch", "voted": false, "svg": { "solid": { "last_modified": 1684767328, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M176 0c-17.7 0-32 14.3-32 32s14.3 32 32 32h16V98.4C92.3 113.8 16 200 16 304c0 114.9 93.1 208 208 208s208-93.1 208-208c0-41.8-12.3-80.7-33.5-113.2l24.1-24.1c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L355.7 143c-28.1-23-62.2-38.8-99.7-44.6V64h16c17.7 0 32-14.3 32-32s-14.3-32-32-32H224 176zm72 192V320c0 13.3-10.7 24-24 24s-24-10.7-24-24V192c0-13.3 10.7-24 24-24s24 10.7 24 24z" } }, "free": ["solid"] }, "stopwatch-20": { "aliases": { "unicodes": { "secondary": ["10e06f"] } }, "changes": [ "5.13.0", "5.14.0", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "ABCs", "countdown", "covid-19", "happy birthday", "i will survive", "reminder", "seconds", "time", "timer" ] }, "styles": ["solid"], "unicode": "e06f", "label": "Stopwatch 20", "voted": false, "svg": { "solid": { "last_modified": 1684767327, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M176 0c-17.7 0-32 14.3-32 32s14.3 32 32 32h16V98.4C92.3 113.8 16 200 16 304c0 114.9 93.1 208 208 208s208-93.1 208-208c0-41.8-12.3-80.7-33.5-113.2l24.1-24.1c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L355.7 143c-28.1-23-62.2-38.8-99.7-44.6V64h16c17.7 0 32-14.3 32-32s-14.3-32-32-32H176zM288 204c28.7 0 52 23.3 52 52v96c0 28.7-23.3 52-52 52s-52-23.3-52-52V256c0-28.7 23.3-52 52-52zm-12 52v96c0 6.6 5.4 12 12 12s12-5.4 12-12V256c0-6.6-5.4-12-12-12s-12 5.4-12 12zM159.5 244c-5.4 0-10.2 3.5-11.9 8.6l-.6 1.7c-3.5 10.5-14.8 16.1-25.3 12.6s-16.1-14.8-12.6-25.3l.6-1.7c7.2-21.5 27.2-35.9 49.8-35.9c29 0 52.5 23.5 52.5 52.5v2.2c0 13.4-4.9 26.4-13.8 36.4l-39 43.9c-6.2 7-10 15.7-10.9 24.9H192c11 0 20 9 20 20s-9 20-20 20H128c-11 0-20-9-20-20V368.3c0-20.6 7.5-40.4 21.2-55.8l39-43.9c2.4-2.7 3.7-6.2 3.7-9.8v-2.2c0-6.9-5.6-12.5-12.5-12.5z" } }, "free": ["solid"] }, "store": { "aliases": { "unicodes": { "secondary": ["10f54e"] } }, "changes": [ "5.0.13", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "bodega", "building", "buy", "market", "purchase", "shopping", "store" ] }, "styles": ["solid"], "unicode": "f54e", "label": "Store", "voted": true, "svg": { "solid": { "last_modified": 1684766474, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M547.6 103.8L490.3 13.1C485.2 5 476.1 0 466.4 0H109.6C99.9 0 90.8 5 85.7 13.1L28.3 103.8c-29.6 46.8-3.4 111.9 51.9 119.4c4 .5 8.1 .8 12.1 .8c26.1 0 49.3-11.4 65.2-29c15.9 17.6 39.1 29 65.2 29c26.1 0 49.3-11.4 65.2-29c15.9 17.6 39.1 29 65.2 29c26.2 0 49.3-11.4 65.2-29c16 17.6 39.1 29 65.2 29c4.1 0 8.1-.3 12.1-.8c55.5-7.4 81.8-72.5 52.1-119.4zM499.7 254.9l-.1 0c-5.3 .7-10.7 1.1-16.2 1.1c-12.4 0-24.3-1.9-35.4-5.3V384H128V250.6c-11.2 3.5-23.2 5.4-35.6 5.4c-5.5 0-11-.4-16.3-1.1l-.1 0c-4.1-.6-8.1-1.3-12-2.3V384v64c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V384 252.6c-4 1-8 1.8-12.3 2.3z" } }, "free": ["solid"] }, "store-slash": { "aliases": { "unicodes": { "secondary": ["10e071"] } }, "changes": [ "5.13.0", "5.14.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["building", "buy", "closed", "covid-19", "purchase", "shopping"] }, "styles": ["solid"], "unicode": "e071", "label": "Store Slash", "voted": false, "svg": { "solid": { "last_modified": 1684766476, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7l-86.8-68V384 252.6c-4 1-8 1.8-12.3 2.3l-.1 0c-5.3 .7-10.7 1.1-16.2 1.1c-12.4 0-24.3-1.9-35.4-5.3V350.9L301.2 210.7c7-4.4 13.3-9.7 18.8-15.7c15.9 17.6 39.1 29 65.2 29c26.2 0 49.3-11.4 65.2-29c16 17.6 39.1 29 65.2 29c4.1 0 8.1-.3 12.1-.8c55.5-7.4 81.8-72.5 52.1-119.4L522.3 13.1C517.2 5 508.1 0 498.4 0H141.6c-9.7 0-18.8 5-23.9 13.1l-22.7 36L38.8 5.1zm73.4 218.1c4 .5 8.1 .8 12.1 .8c11 0 21.4-2 31-5.6L48.9 134.5c-6.1 40.6 19.5 82.8 63.3 88.7zM160 384V250.6c-11.2 3.5-23.2 5.4-35.6 5.4c-5.5 0-11-.4-16.3-1.1l-.1 0c-4.1-.6-8.1-1.3-12-2.3V384v64c0 35.3 28.7 64 64 64H480c12.9 0 24.8-3.8 34.9-10.3L365.5 384H160z" } }, "free": ["solid"] }, "strava": { "changes": ["5.0.0", "5.0.1", "5.7.0", "5.8.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f428", "label": "Strava", "voted": false, "svg": { "brands": { "last_modified": 1660014459, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M158.4 0L7 292h89.2l62.2-116.1L220.1 292h88.5zm150.2 292l-43.9 88.2-44.6-88.2h-67.6l112.2 220 111.5-220z" } }, "free": ["brands"] }, "street-view": { "aliases": { "unicodes": { "secondary": ["10f21d"] } }, "changes": [ "4.3.0", "5.0.0", "5.2.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["directions", "location", "map", "navigation"] }, "styles": ["solid"], "unicode": "f21d", "label": "Street View", "voted": false, "svg": { "solid": { "last_modified": 1684767489, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M320 64A64 64 0 1 0 192 64a64 64 0 1 0 128 0zm-96 96c-35.3 0-64 28.7-64 64v48c0 17.7 14.3 32 32 32h1.8l11.1 99.5c1.8 16.2 15.5 28.5 31.8 28.5h38.7c16.3 0 30-12.3 31.8-28.5L318.2 304H320c17.7 0 32-14.3 32-32V224c0-35.3-28.7-64-64-64H224zM132.3 394.2c13-2.4 21.7-14.9 19.3-27.9s-14.9-21.7-27.9-19.3c-32.4 5.9-60.9 14.2-82 24.8c-10.5 5.3-20.3 11.7-27.8 19.6C6.4 399.5 0 410.5 0 424c0 21.4 15.5 36.1 29.1 45c14.7 9.6 34.3 17.3 56.4 23.4C130.2 504.7 190.4 512 256 512s125.8-7.3 170.4-19.6c22.1-6.1 41.8-13.8 56.4-23.4c13.7-8.9 29.1-23.6 29.1-45c0-13.5-6.4-24.5-14-32.6c-7.5-7.9-17.3-14.3-27.8-19.6c-21-10.6-49.5-18.9-82-24.8c-13-2.4-25.5 6.3-27.9 19.3s6.3 25.5 19.3 27.9c30.2 5.5 53.7 12.8 69 20.5c3.2 1.6 5.8 3.1 7.9 4.5c3.6 2.4 3.6 7.2 0 9.6c-8.8 5.7-23.1 11.8-43 17.3C374.3 457 318.5 464 256 464s-118.3-7-157.7-17.9c-19.9-5.5-34.2-11.6-43-17.3c-3.6-2.4-3.6-7.2 0-9.6c2.1-1.4 4.8-2.9 7.9-4.5c15.3-7.7 38.8-14.9 69-20.5z" } }, "free": ["solid"] }, "strikethrough": { "aliases": { "unicodes": { "secondary": ["10f0cc"] } }, "changes": [ "2.0.0", "5.0.0", "5.9.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["cancel", "edit", "font", "format", "text", "type"] }, "styles": ["solid"], "unicode": "f0cc", "label": "Strikethrough", "voted": false, "svg": { "solid": { "last_modified": 1684767247, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M161.3 144c3.2-17.2 14-30.1 33.7-38.6c21.1-9 51.8-12.3 88.6-6.5c11.9 1.9 48.8 9.1 60.1 12c17.1 4.5 34.6-5.6 39.2-22.7s-5.6-34.6-22.7-39.2c-14.3-3.8-53.6-11.4-66.6-13.4c-44.7-7-88.3-4.2-123.7 10.9c-36.5 15.6-64.4 44.8-71.8 87.3c-.1 .6-.2 1.1-.2 1.7c-2.8 23.9 .5 45.6 10.1 64.6c4.5 9 10.2 16.9 16.7 23.9H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H480c17.7 0 32-14.3 32-32s-14.3-32-32-32H270.1c-.1 0-.3-.1-.4-.1l-1.1-.3c-36-10.8-65.2-19.6-85.2-33.1c-9.3-6.3-15-12.6-18.2-19.1c-3.1-6.1-5.2-14.6-3.8-27.4zM348.9 337.2c2.7 6.5 4.4 15.8 1.9 30.1c-3 17.6-13.8 30.8-33.9 39.4c-21.1 9-51.7 12.3-88.5 6.5c-18-2.9-49.1-13.5-74.4-22.1c-5.6-1.9-11-3.7-15.9-5.4c-16.8-5.6-34.9 3.5-40.5 20.3s3.5 34.9 20.3 40.5c3.6 1.2 7.9 2.7 12.7 4.3l0 0 0 0c24.9 8.5 63.6 21.7 87.6 25.6l0 0 .2 0c44.7 7 88.3 4.2 123.7-10.9c36.5-15.6 64.4-44.8 71.8-87.3c3.6-21 2.7-40.4-3.1-58.1H335.1c7 5.6 11.4 11.2 13.9 17.2z" } }, "free": ["solid"] }, "stripe": { "changes": ["5.0.0", "5.0.3"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f429", "label": "Stripe", "voted": false, "svg": { "brands": { "last_modified": 1660014472, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M165 144.7l-43.3 9.2-.2 142.4c0 26.3 19.8 43.3 46.1 43.3 14.6 0 25.3-2.7 31.2-5.9v-33.8c-5.7 2.3-33.7 10.5-33.7-15.7V221h33.7v-37.8h-33.7zm89.1 51.6l-2.7-13.1H213v153.2h44.3V233.3c10.5-13.8 28.2-11.1 33.9-9.3v-40.8c-6-2.1-26.7-6-37.1 13.1zm92.3-72.3l-44.6 9.5v36.2l44.6-9.5zM44.9 228.3c0-6.9 5.8-9.6 15.1-9.7 13.5 0 30.7 4.1 44.2 11.4v-41.8c-14.7-5.8-29.4-8.1-44.1-8.1-36 0-60 18.8-60 50.2 0 49.2 67.5 41.2 67.5 62.4 0 8.2-7.1 10.9-17 10.9-14.7 0-33.7-6.1-48.6-14.2v40c16.5 7.1 33.2 10.1 48.5 10.1 36.9 0 62.3-15.8 62.3-47.8 0-52.9-67.9-43.4-67.9-63.4zM640 261.6c0-45.5-22-81.4-64.2-81.4s-67.9 35.9-67.9 81.1c0 53.5 30.3 78.2 73.5 78.2 21.2 0 37.1-4.8 49.2-11.5v-33.4c-12.1 6.1-26 9.8-43.6 9.8-17.3 0-32.5-6.1-34.5-26.9h86.9c.2-2.3.6-11.6.6-15.9zm-87.9-16.8c0-20 12.3-28.4 23.4-28.4 10.9 0 22.5 8.4 22.5 28.4zm-112.9-64.6c-17.4 0-28.6 8.2-34.8 13.9l-2.3-11H363v204.8l44.4-9.4.1-50.2c6.4 4.7 15.9 11.2 31.4 11.2 31.8 0 60.8-23.2 60.8-79.6.1-51.6-29.3-79.7-60.5-79.7zm-10.6 122.5c-10.4 0-16.6-3.8-20.9-8.4l-.3-66c4.6-5.1 11-8.8 21.2-8.8 16.2 0 27.4 18.2 27.4 41.4.1 23.9-10.9 41.8-27.4 41.8zm-126.7 33.7h44.6V183.2h-44.6z" } }, "free": ["brands"] }, "stripe-s": { "changes": ["5.0.1", "5.8.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f42a", "label": "Stripe S", "voted": false, "svg": { "brands": { "last_modified": 1660014475, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M155.3 154.6c0-22.3 18.6-30.9 48.4-30.9 43.4 0 98.5 13.3 141.9 36.7V26.1C298.3 7.2 251.1 0 203.8 0 88.1 0 11 60.4 11 161.4c0 157.9 216.8 132.3 216.8 200.4 0 26.4-22.9 34.9-54.7 34.9-47.2 0-108.2-19.5-156.1-45.5v128.5a396.09 396.09 0 0 0 156 32.4c118.6 0 200.3-51 200.3-153.6 0-170.2-218-139.7-218-203.9z" } }, "free": ["brands"] }, "stroopwafel": { "aliases": { "unicodes": { "secondary": ["10f551"] } }, "changes": ["5.0.13", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["caramel", "cookie", "dessert", "sweets", "waffle"] }, "styles": ["solid"], "unicode": "f551", "label": "Stroopwafel", "voted": false, "svg": { "solid": { "last_modified": 1684767420, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zM312.6 63.7c-6.2-6.2-16.4-6.2-22.6 0L256 97.6 222.1 63.7c-6.2-6.2-16.4-6.2-22.6 0s-6.2 16.4 0 22.6l33.9 33.9-45.3 45.3-56.6-56.6c-6.2-6.2-16.4-6.2-22.6 0s-6.2 16.4 0 22.6l56.6 56.6-45.3 45.3L86.3 199.4c-6.2-6.2-16.4-6.2-22.6 0s-6.2 16.4 0 22.6L97.6 256 63.7 289.9c-6.2 6.2-6.2 16.4 0 22.6s16.4 6.2 22.6 0l33.9-33.9 45.3 45.3-56.6 56.6c-6.2 6.2-6.2 16.4 0 22.6s16.4 6.2 22.6 0l56.6-56.6 45.3 45.3-33.9 33.9c-6.2 6.2-6.2 16.4 0 22.6s16.4 6.2 22.6 0L256 414.4l33.9 33.9c6.2 6.2 16.4 6.2 22.6 0s6.2-16.4 0-22.6l-33.9-33.9 45.3-45.3 56.6 56.6c6.2 6.2 16.4 6.2 22.6 0s6.2-16.4 0-22.6l-56.6-56.6 45.3-45.3 33.9 33.9c6.2 6.2 16.4 6.2 22.6 0s6.2-16.4 0-22.6L414.4 256l33.9-33.9c6.2-6.2 6.2-16.4 0-22.6s-16.4-6.2-22.6 0l-33.9 33.9-45.3-45.3 56.6-56.6c6.2-6.2 6.2-16.4 0-22.6s-16.4-6.2-22.6 0l-56.6 56.6-45.3-45.3 33.9-33.9c6.2-6.2 6.2-16.4 0-22.6zM142.9 256l45.3-45.3L233.4 256l-45.3 45.3L142.9 256zm67.9 67.9L256 278.6l45.3 45.3L256 369.1l-45.3-45.3zM278.6 256l45.3-45.3L369.1 256l-45.3 45.3L278.6 256zm22.6-67.9L256 233.4l-45.3-45.3L256 142.9l45.3 45.3z" } }, "free": ["solid"] }, "stubber": { "changes": ["6.2.1", "6.3.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e5c7", "label": "Stubber", "voted": false, "svg": { "brands": { "last_modified": 1667828915, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M136.5 294.2l58.8 22.9c9.1-36.8 25.4-61.1 55-61.1c49.4 0 71.4 63.6 142.4 63.6c15.6 0 35.9-2.8 55.3-13.3V368c0 61.8-50.4 112-112.3 112H0l41.8-56L0 368l41.7-56L0 256.1l41.8-56L0 144.1 41.8 88 0 32H335.7C397.6 32 448 82.3 448 144.1v51.3c-9.2 36.3-25.9 60.6-55 60.6c-49.6 0-71.6-63.5-142.4-63.5c-35.9 0-95.2 14.6-114.1 101.6h0z" } }, "free": ["brands"] }, "studiovinari": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3f8", "label": "Studio Vinari", "voted": false, "svg": { "brands": { "last_modified": 1660014473, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M480.3 187.7l4.2 28v28l-25.1 44.1-39.8 78.4-56.1 67.5-79.1 37.8-17.7 24.5-7.7 12-9.6 4s17.3-63.6 19.4-63.6c2.1 0 20.3.7 20.3.7l66.7-38.6-92.5 26.1-55.9 36.8-22.8 28-6.6 1.4 20.8-73.6 6.9-5.5 20.7 12.9 88.3-45.2 56.8-51.5 14.8-68.4-125.4 23.3 15.2-18.2-173.4-53.3 81.9-10.5-166-122.9L133.5 108 32.2 0l252.9 126.6-31.5-38L378 163 234.7 64l18.7 38.4-49.6-18.1L158.3 0l194.6 122L310 66.2l108 96.4 12-8.9-21-16.4 4.2-37.8L451 89.1l29.2 24.7 11.5 4.2-7 6.2 8.5 12-13.1 7.4-10.3 20.2 10.5 23.9z" } }, "free": ["brands"] }, "stumbleupon": { "changes": ["4.1.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f1a4", "label": "StumbleUpon Logo", "voted": false, "svg": { "brands": { "last_modified": 1660014473, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M502.9 266v69.7c0 62.1-50.3 112.4-112.4 112.4-61.8 0-112.4-49.8-112.4-111.3v-70.2l34.3 16 51.1-15.2V338c0 14.7 12 26.5 26.7 26.5S417 352.7 417 338v-72h85.9zm-224.7-58.2l34.3 16 51.1-15.2V173c0-60.5-51.1-109-112.1-109-60.8 0-112.1 48.2-112.1 108.2v162.4c0 14.9-12 26.7-26.7 26.7S86 349.5 86 334.6V266H0v69.7C0 397.7 50.3 448 112.4 448c61.6 0 112.4-49.5 112.4-110.8V176.9c0-14.7 12-26.7 26.7-26.7s26.7 12 26.7 26.7v30.9z" } }, "free": ["brands"] }, "stumbleupon-circle": { "changes": ["4.1.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f1a3", "label": "StumbleUpon Circle", "voted": false, "svg": { "brands": { "last_modified": 1660014460, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 177.5c-9.8 0-17.8 8-17.8 17.8v106.9c0 40.9-33.9 73.9-74.9 73.9-41.4 0-74.9-33.5-74.9-74.9v-46.5h57.3v45.8c0 10 8 17.8 17.8 17.8s17.8-7.9 17.8-17.8V200.1c0-40 34.2-72.1 74.7-72.1 40.7 0 74.7 32.3 74.7 72.6v23.7l-34.1 10.1-22.9-10.7v-20.6c.1-9.6-7.9-17.6-17.7-17.6zm167.6 123.6c0 41.4-33.5 74.9-74.9 74.9-41.2 0-74.9-33.2-74.9-74.2V263l22.9 10.7 34.1-10.1v47.1c0 9.8 8 17.6 17.8 17.6s17.8-7.9 17.8-17.6v-48h57.3c-.1 45.9-.1 46.4-.1 46.4z" } }, "free": ["brands"] }, "subscript": { "aliases": { "unicodes": { "secondary": ["10f12c"] } }, "changes": [ "3.1.0", "5.0.0", "5.9.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["edit", "font", "format", "text", "type"] }, "styles": ["solid"], "unicode": "f12c", "label": "Subscript", "voted": false, "svg": { "solid": { "last_modified": 1684767246, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M32 64C14.3 64 0 78.3 0 96s14.3 32 32 32H47.3l89.6 128L47.3 384H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H64c10.4 0 20.2-5.1 26.2-13.6L176 311.8l85.8 122.6c6 8.6 15.8 13.6 26.2 13.6h32c17.7 0 32-14.3 32-32s-14.3-32-32-32H304.7L215.1 256l89.6-128H320c17.7 0 32-14.3 32-32s-14.3-32-32-32H288c-10.4 0-20.2 5.1-26.2 13.6L176 200.2 90.2 77.6C84.2 69.1 74.4 64 64 64H32zM480 320c0-11.1-5.7-21.4-15.2-27.2s-21.2-6.4-31.1-1.4l-32 16c-15.8 7.9-22.2 27.1-14.3 42.9C393 361.5 404.3 368 416 368v80c-17.7 0-32 14.3-32 32s14.3 32 32 32h32 32c17.7 0 32-14.3 32-32s-14.3-32-32-32V320z" } }, "free": ["solid"] }, "suitcase": { "aliases": { "unicodes": { "composite": ["1f9f3"], "secondary": ["10f0f2"] } }, "changes": [ "3.0.0", "5.0.0", "5.0.9", "6.0.0-beta1", "6.1.2", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "baggage", "luggage", "move", "packing", "suitcase", "travel", "trip" ] }, "styles": ["solid"], "unicode": "f0f2", "label": "Suitcase", "voted": false, "svg": { "solid": { "last_modified": 1684767443, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M176 56V96H336V56c0-4.4-3.6-8-8-8H184c-4.4 0-8 3.6-8 8zM128 96V56c0-30.9 25.1-56 56-56H328c30.9 0 56 25.1 56 56V96v32V480H128V128 96zM64 96H96V480H64c-35.3 0-64-28.7-64-64V160c0-35.3 28.7-64 64-64zM448 480H416V96h32c35.3 0 64 28.7 64 64V416c0 35.3-28.7 64-64 64z" } }, "free": ["solid"] }, "suitcase-medical": { "aliases": { "names": ["medkit"], "unicodes": { "secondary": ["10f0fa"] } }, "changes": ["3.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "first aid", "firstaid", "health", "help", "medical", "supply", "support" ] }, "styles": ["solid"], "unicode": "f0fa", "label": "Suitcase Medical", "voted": false, "svg": { "solid": { "last_modified": 1684767442, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M184 48H328c4.4 0 8 3.6 8 8V96H176V56c0-4.4 3.6-8 8-8zm-56 8V96v32V480H384V128 96 56c0-30.9-25.1-56-56-56H184c-30.9 0-56 25.1-56 56zM96 96H64C28.7 96 0 124.7 0 160V416c0 35.3 28.7 64 64 64H96V96zM416 480h32c35.3 0 64-28.7 64-64V160c0-35.3-28.7-64-64-64H416V480zM224 208c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v48h48c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H288v48c0 8.8-7.2 16-16 16H240c-8.8 0-16-7.2-16-16V320H176c-8.8 0-16-7.2-16-16V272c0-8.8 7.2-16 16-16h48V208z" } }, "free": ["solid"] }, "suitcase-rolling": { "aliases": { "unicodes": { "secondary": ["10f5c1"] } }, "changes": ["5.1.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["baggage", "luggage", "move", "suitcase", "travel", "trip"] }, "styles": ["solid"], "unicode": "f5c1", "label": "Suitcase Rolling", "voted": false, "svg": { "solid": { "last_modified": 1684767441, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M144 56c0-4.4 3.6-8 8-8h80c4.4 0 8 3.6 8 8v72H144V56zm176 72H288V56c0-30.9-25.1-56-56-56H152C121.1 0 96 25.1 96 56v72H64c-35.3 0-64 28.7-64 64V416c0 35.3 28.7 64 64 64c0 17.7 14.3 32 32 32s32-14.3 32-32H256c0 17.7 14.3 32 32 32s32-14.3 32-32c35.3 0 64-28.7 64-64V192c0-35.3-28.7-64-64-64zM112 224H272c8.8 0 16 7.2 16 16s-7.2 16-16 16H112c-8.8 0-16-7.2-16-16s7.2-16 16-16zm0 128H272c8.8 0 16 7.2 16 16s-7.2 16-16 16H112c-8.8 0-16-7.2-16-16s7.2-16 16-16z" } }, "free": ["solid"] }, "sun": { "aliases": { "unicodes": { "composite": ["2600"], "secondary": ["10f185"] } }, "changes": [ "3.2.0", "5.0.0", "5.5.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "bright", "brighten", "contrast", "day", "lighter", "rays", "sol", "solar", "star", "sun", "sunny", "weather" ] }, "styles": ["solid", "regular"], "unicode": "f185", "label": "Sun", "voted": false, "svg": { "solid": { "last_modified": 1684767661, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M361.5 1.2c5 2.1 8.6 6.6 9.6 11.9L391 121l107.9 19.8c5.3 1 9.8 4.6 11.9 9.6s1.5 10.7-1.6 15.2L446.9 256l62.3 90.3c3.1 4.5 3.7 10.2 1.6 15.2s-6.6 8.6-11.9 9.6L391 391 371.1 498.9c-1 5.3-4.6 9.8-9.6 11.9s-10.7 1.5-15.2-1.6L256 446.9l-90.3 62.3c-4.5 3.1-10.2 3.7-15.2 1.6s-8.6-6.6-9.6-11.9L121 391 13.1 371.1c-5.3-1-9.8-4.6-11.9-9.6s-1.5-10.7 1.6-15.2L65.1 256 2.8 165.7c-3.1-4.5-3.7-10.2-1.6-15.2s6.6-8.6 11.9-9.6L121 121 140.9 13.1c1-5.3 4.6-9.8 9.6-11.9s10.7-1.5 15.2 1.6L256 65.1 346.3 2.8c4.5-3.1 10.2-3.7 15.2-1.6zM160 256a96 96 0 1 1 192 0 96 96 0 1 1 -192 0zm224 0a128 128 0 1 0 -256 0 128 128 0 1 0 256 0z" }, "regular": { "last_modified": 1684767661, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M375.7 19.7c-1.5-8-6.9-14.7-14.4-17.8s-16.1-2.2-22.8 2.4L256 61.1 173.5 4.2c-6.7-4.6-15.3-5.5-22.8-2.4s-12.9 9.8-14.4 17.8l-18.1 98.5L19.7 136.3c-8 1.5-14.7 6.9-17.8 14.4s-2.2 16.1 2.4 22.8L61.1 256 4.2 338.5c-4.6 6.7-5.5 15.3-2.4 22.8s9.8 13 17.8 14.4l98.5 18.1 18.1 98.5c1.5 8 6.9 14.7 14.4 17.8s16.1 2.2 22.8-2.4L256 450.9l82.5 56.9c6.7 4.6 15.3 5.5 22.8 2.4s12.9-9.8 14.4-17.8l18.1-98.5 98.5-18.1c8-1.5 14.7-6.9 17.8-14.4s2.2-16.1-2.4-22.8L450.9 256l56.9-82.5c4.6-6.7 5.5-15.3 2.4-22.8s-9.8-12.9-17.8-14.4l-98.5-18.1L375.7 19.7zM269.6 110l65.6-45.2 14.4 78.3c1.8 9.8 9.5 17.5 19.3 19.3l78.3 14.4L402 242.4c-5.7 8.2-5.7 19 0 27.2l45.2 65.6-78.3 14.4c-9.8 1.8-17.5 9.5-19.3 19.3l-14.4 78.3L269.6 402c-8.2-5.7-19-5.7-27.2 0l-65.6 45.2-14.4-78.3c-1.8-9.8-9.5-17.5-19.3-19.3L64.8 335.2 110 269.6c5.7-8.2 5.7-19 0-27.2L64.8 176.8l78.3-14.4c9.8-1.8 17.5-9.5 19.3-19.3l14.4-78.3L242.4 110c8.2 5.7 19 5.7 27.2 0zM256 368a112 112 0 1 0 0-224 112 112 0 1 0 0 224zM192 256a64 64 0 1 1 128 0 64 64 0 1 1 -128 0z" } }, "free": ["regular", "solid"] }, "sun-plant-wilt": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["arid", "droop", "drought"] }, "styles": ["solid"], "unicode": "e57a", "label": "Sun Plant Wilt", "voted": false, "svg": { "solid": { "last_modified": 1684768131, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M160 0c-6.3 0-12 3.7-14.6 9.5L120.6 64.9 63.9 43.2c-5.9-2.3-12.6-.8-17 3.6s-5.9 11.1-3.6 17l21.7 56.7L9.5 145.4C3.7 148 0 153.7 0 160s3.7 12 9.5 14.6l55.4 24.8L43.2 256.1c-2.3 5.9-.8 12.6 3.6 17s11.1 5.9 17 3.6l56.7-21.7 24.8 55.4c2.6 5.8 8.3 9.5 14.6 9.5s12-3.7 14.6-9.5l24.8-55.4 56.7 21.7c5.9 2.3 12.6 .8 17-3.6s5.9-11.1 3.6-17l-21.7-56.7 55.4-24.8c5.8-2.6 9.5-8.3 9.5-14.6s-3.7-12-9.5-14.6l-55.4-24.8 21.7-56.7c2.3-5.9 .8-12.6-3.6-17s-11.1-5.9-17-3.6L199.4 64.9 174.6 9.5C172 3.7 166.3 0 160 0zm0 96a64 64 0 1 1 0 128 64 64 0 1 1 0-128zm32 64a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zm312 16c0-17.7 14.3-32 32-32s32 14.3 32 32v53.4c-14.8 7.7-24 23.1-24 44.6c0 16.8 16 44 37.4 67.2c5.8 6.2 15.5 6.2 21.2 0C624 318 640 290.7 640 274c0-21.5-9.2-37-24-44.6V176c0-44.2-35.8-80-80-80s-80 35.8-80 80v22.7c-9.8-4.3-20.6-6.7-32-6.7c-44.2 0-80 35.8-80 80v21.4c-14.8 7.7-24 23.1-24 44.6c0 16.8 16 44 37.4 67.2c5.8 6.2 15.5 6.2 21.2 0C400 382 416 354.7 416 338c0-21.5-9.2-37-24-44.6V272c0-17.7 14.3-32 32-32s32 14.3 32 32v8V448H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H608c17.7 0 32-14.3 32-32s-14.3-32-32-32H504V280v-8V176z" } }, "free": ["solid"] }, "superpowers": { "changes": ["4.7.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f2dd", "label": "Superpowers", "voted": false, "svg": { "brands": { "last_modified": 1660014467, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M448 32c-83.3 11-166.8 22-250 33-92 12.5-163.3 86.7-169 180-3.3 55.5 18 109.5 57.8 148.2L0 480c83.3-11 166.5-22 249.8-33 91.8-12.5 163.3-86.8 168.7-179.8 3.5-55.5-18-109.5-57.7-148.2L448 32zm-79.7 232.3c-4.2 79.5-74 139.2-152.8 134.5-79.5-4.7-140.7-71-136.3-151 4.5-79.2 74.3-139.3 153-134.5 79.3 4.7 140.5 71 136.1 151z" } }, "free": ["brands"] }, "superscript": { "aliases": { "unicodes": { "secondary": ["10f12b"] } }, "changes": [ "3.1.0", "5.0.0", "5.9.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["edit", "exponential", "font", "format", "text", "type"] }, "styles": ["solid"], "unicode": "f12b", "label": "Superscript", "voted": false, "svg": { "solid": { "last_modified": 1684767245, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M480 32c0-11.1-5.7-21.4-15.2-27.2s-21.2-6.4-31.1-1.4l-32 16c-15.8 7.9-22.2 27.1-14.3 42.9C393 73.5 404.3 80 416 80v80c-17.7 0-32 14.3-32 32s14.3 32 32 32h32 32c17.7 0 32-14.3 32-32s-14.3-32-32-32V32zM32 64C14.3 64 0 78.3 0 96s14.3 32 32 32H47.3l89.6 128L47.3 384H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H64c10.4 0 20.2-5.1 26.2-13.6L176 311.8l85.8 122.6c6 8.6 15.8 13.6 26.2 13.6h32c17.7 0 32-14.3 32-32s-14.3-32-32-32H304.7L215.1 256l89.6-128H320c17.7 0 32-14.3 32-32s-14.3-32-32-32H288c-10.4 0-20.2 5.1-26.2 13.6L176 200.2 90.2 77.6C84.2 69.1 74.4 64 64 64H32z" } }, "free": ["solid"] }, "supple": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f3f9", "label": "Supple", "voted": false, "svg": { "brands": { "last_modified": 1660014463, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M640 262.5c0 64.1-109 116.1-243.5 116.1-24.8 0-48.6-1.8-71.1-5 7.7.4 15.5.6 23.4.6 134.5 0 243.5-56.9 243.5-127.1 0-29.4-19.1-56.4-51.2-78 60 21.1 98.9 55.1 98.9 93.4zM47.7 227.9c-.1-70.2 108.8-127.3 243.3-127.6 7.9 0 15.6.2 23.3.5-22.5-3.2-46.3-4.9-71-4.9C108.8 96.3-.1 148.5 0 212.6c.1 38.3 39.1 72.3 99.3 93.3-32.3-21.5-51.5-48.6-51.6-78zm60.2 39.9s10.5 13.2 29.3 13.2c17.9 0 28.4-11.5 28.4-25.1 0-28-40.2-25.1-40.2-39.7 0-5.4 5.3-9.1 12.5-9.1 5.7 0 11.3 2.6 11.3 6.6v3.9h14.2v-7.9c0-12.1-15.4-16.8-25.4-16.8-16.5 0-28.5 10.2-28.5 24.1 0 26.6 40.2 25.4 40.2 39.9 0 6.6-5.8 10.1-12.3 10.1-11.9 0-20.7-10.1-20.7-10.1l-8.8 10.9zm120.8-73.6v54.4c0 11.3-7.1 17.8-17.8 17.8-10.7 0-17.8-6.5-17.8-17.7v-54.5h-15.8v55c0 18.9 13.4 31.9 33.7 31.9 20.1 0 33.4-13 33.4-31.9v-55h-15.7zm34.4 85.4h15.8v-29.5h15.5c16 0 27.2-11.5 27.2-28.1s-11.2-27.8-27.2-27.8h-39.1v13.4h7.8v72zm15.8-43v-29.1h12.9c8.7 0 13.7 5.7 13.7 14.4 0 8.9-5.1 14.7-14 14.7h-12.6zm57 43h15.8v-29.5h15.5c16 0 27.2-11.5 27.2-28.1s-11.2-27.8-27.2-27.8h-39.1v13.4h7.8v72zm15.7-43v-29.1h12.9c8.7 0 13.7 5.7 13.7 14.4 0 8.9-5 14.7-14 14.7h-12.6zm57.1 34.8c0 5.8 2.4 8.2 8.2 8.2h37.6c5.8 0 8.2-2.4 8.2-8.2v-13h-14.3v5.2c0 1.7-1 2.6-2.6 2.6h-18.6c-1.7 0-2.6-1-2.6-2.6v-61.2c0-5.7-2.4-8.2-8.2-8.2H401v13.4h5.2c1.7 0 2.6 1 2.6 2.6v61.2zm63.4 0c0 5.8 2.4 8.2 8.2 8.2H519c5.7 0 8.2-2.4 8.2-8.2v-13h-14.3v5.2c0 1.7-1 2.6-2.6 2.6h-19.7c-1.7 0-2.6-1-2.6-2.6v-20.3h27.7v-13.4H488v-22.4h19.2c1.7 0 2.6 1 2.6 2.6v5.2H524v-13c0-5.7-2.5-8.2-8.2-8.2h-51.6v13.4h7.8v63.9zm58.9-76v5.9h1.6v-5.9h2.7v-1.2h-7v1.2h2.7zm5.7-1.2v7.1h1.5v-5.7l2.3 5.7h1.3l2.3-5.7v5.7h1.5v-7.1h-2.3l-2.1 5.1-2.1-5.1h-2.4z" } }, "free": ["brands"] }, "suse": { "changes": ["5.6.0", "5.8.0"], "ligatures": [], "search": { "terms": ["linux", "operating system", "os"] }, "styles": ["brands"], "unicode": "f7d6", "label": "Suse", "voted": true, "svg": { "brands": { "last_modified": 1660014461, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M471.08 102.66s-.3 18.3-.3 20.3c-9.1-3-74.4-24.1-135.7-26.3-51.9-1.8-122.8-4.3-223 57.3-19.4 12.4-73.9 46.1-99.6 109.7C7 277-.12 307 7 335.06a111 111 0 0 0 16.5 35.7c17.4 25 46.6 41.6 78.1 44.4 44.4 3.9 78.1-16 90-53.3 8.2-25.8 0-63.6-31.5-82.9-25.6-15.7-53.3-12.1-69.2-1.6-13.9 9.2-21.8 23.5-21.6 39.2.3 27.8 24.3 42.6 41.5 42.6a49 49 0 0 0 15.8-2.7c6.5-1.8 13.3-6.5 13.3-14.9 0-12.1-11.6-14.8-16.8-13.9-2.9.5-4.5 2-11.8 2.4-2-.2-12-3.1-12-14V316c.2-12.3 13.2-18 25.5-16.9 32.3 2.8 47.7 40.7 28.5 65.7-18.3 23.7-76.6 23.2-99.7-20.4-26-49.2 12.7-111.2 87-98.4 33.2 5.7 83.6 35.5 102.4 104.3h45.9c-5.7-17.6-8.9-68.3 42.7-68.3 56.7 0 63.9 39.9 79.8 68.3H460c-12.8-18.3-21.7-38.7-18.9-55.8 5.6-33.8 39.7-18.4 82.4-17.4 66.5.4 102.1-27 103.1-28 3.7-3.1 6.5-15.8 7-17.7 1.3-5.1-3.2-2.4-3.2-2.4-8.7 5.2-30.5 15.2-50.9 15.6-25.3.5-76.2-25.4-81.6-28.2-.3-.4.1 1.2-11-25.5 88.4 58.3 118.3 40.5 145.2 21.7.8-.6 4.3-2.9 3.6-5.7-13.8-48.1-22.4-62.7-34.5-69.6-37-21.6-125-34.7-129.2-35.3.1-.1-.9-.3-.9.7zm60.4 72.8a37.54 37.54 0 0 1 38.9-36.3c33.4 1.2 48.8 42.3 24.4 65.2-24.2 22.7-64.4 4.6-63.3-28.9zm38.6-25.3a26.27 26.27 0 1 0 25.4 27.2 26.19 26.19 0 0 0-25.4-27.2zm4.3 28.8c-15.4 0-15.4-15.6 0-15.6s15.4 15.64 0 15.64z" } }, "free": ["brands"] }, "swatchbook": { "aliases": { "unicodes": { "secondary": ["10f5c3"] } }, "changes": [ "5.1.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["Pantone", "color", "design", "hue", "palette"] }, "styles": ["solid"], "unicode": "f5c3", "label": "Swatchbook", "voted": false, "svg": { "solid": { "last_modified": 1684767368, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 32C0 14.3 14.3 0 32 0H160c17.7 0 32 14.3 32 32V416c0 53-43 96-96 96s-96-43-96-96V32zM223.6 425.9c.3-3.3 .4-6.6 .4-9.9V154l75.4-75.4c12.5-12.5 32.8-12.5 45.3 0l90.5 90.5c12.5 12.5 12.5 32.8 0 45.3L223.6 425.9zM182.8 512l192-192H480c17.7 0 32 14.3 32 32V480c0 17.7-14.3 32-32 32H182.8zM128 64H64v64h64V64zM64 192v64h64V192H64zM96 440a24 24 0 1 0 0-48 24 24 0 1 0 0 48z" } }, "free": ["solid"] }, "swift": { "changes": ["5.11.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f8e1", "label": "Swift", "voted": false, "svg": { "brands": { "last_modified": 1660014473, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M448 156.09c0-4.51-.08-9-.2-13.52a196.31 196.31 0 0 0-2.58-29.42 99.62 99.62 0 0 0-9.22-28A94.08 94.08 0 0 0 394.84 44a99.17 99.17 0 0 0-28-9.22 195 195 0 0 0-29.43-2.59c-4.51-.12-9-.17-13.52-.2H124.14c-4.51 0-9 .08-13.52.2-2.45.07-4.91.15-7.37.27a171.68 171.68 0 0 0-22.06 2.32 103.06 103.06 0 0 0-21.21 6.1q-3.46 1.45-6.81 3.12a94.66 94.66 0 0 0-18.39 12.32c-1.88 1.61-3.69 3.28-5.43 5A93.86 93.86 0 0 0 12 85.17a99.45 99.45 0 0 0-9.22 28 196.31 196.31 0 0 0-2.54 29.4c-.13 4.51-.18 9-.21 13.52v199.83c0 4.51.08 9 .21 13.51a196.08 196.08 0 0 0 2.58 29.42 99.3 99.3 0 0 0 9.22 28A94.31 94.31 0 0 0 53.17 468a99.47 99.47 0 0 0 28 9.21 195 195 0 0 0 29.43 2.59c4.5.12 9 .17 13.52.2H323.91c4.51 0 9-.08 13.52-.2a196.59 196.59 0 0 0 29.44-2.59 99.57 99.57 0 0 0 28-9.21A94.22 94.22 0 0 0 436 426.84a99.3 99.3 0 0 0 9.22-28 194.79 194.79 0 0 0 2.59-29.42c.12-4.5.17-9 .2-13.51V172.14c-.01-5.35-.01-10.7-.01-16.05zm-69.88 241c-20-38.93-57.23-29.27-76.31-19.47-1.72 1-3.48 2-5.25 3l-.42.25c-39.5 21-92.53 22.54-145.85-.38A234.64 234.64 0 0 1 45 290.12a230.63 230.63 0 0 0 39.17 23.37c56.36 26.4 113 24.49 153 0-57-43.85-104.6-101-141.09-147.22a197.09 197.09 0 0 1-18.78-25.9c43.7 40 112.7 90.22 137.48 104.12-52.57-55.49-98.89-123.94-96.72-121.74 82.79 83.42 159.18 130.59 159.18 130.59 2.88 1.58 5 2.85 6.73 4a127.44 127.44 0 0 0 4.16-12.47c13.22-48.33-1.66-103.58-35.31-149.2C329.61 141.75 375 229.34 356.4 303.42c-.44 1.73-.95 3.4-1.44 5.09 38.52 47.4 28.04 98.17 23.13 88.59z" } }, "free": ["brands"] }, "symfony": { "changes": ["5.8.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f83d", "label": "Symfony", "voted": false, "svg": { "brands": { "last_modified": 1660014468, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm133.74 143.54c-11.47.41-19.4-6.45-19.77-16.87-.27-9.18 6.68-13.44 6.53-18.85-.23-6.55-10.16-6.82-12.87-6.67-39.78 1.29-48.59 57-58.89 113.85 21.43 3.15 36.65-.72 45.14-6.22 12-7.75-3.34-15.72-1.42-24.56 4-18.16 32.55-19 32 5.3-.36 17.86-25.92 41.81-77.6 35.7-10.76 59.52-18.35 115-58.2 161.72-29 34.46-58.4 39.82-71.58 40.26-24.65.85-41-12.31-41.58-29.84-.56-17 14.45-26.26 24.31-26.59 21.89-.75 30.12 25.67 14.88 34-12.09 9.71.11 12.61 2.05 12.55 10.42-.36 17.34-5.51 22.18-9 24-20 33.24-54.86 45.35-118.35 8.19-49.66 17-78 18.23-82-16.93-12.75-27.08-28.55-49.85-34.72-15.61-4.23-25.12-.63-31.81 7.83-7.92 10-5.29 23 2.37 30.7l12.63 14c15.51 17.93 24 31.87 20.8 50.62-5.06 29.93-40.72 52.9-82.88 39.94-36-11.11-42.7-36.56-38.38-50.62 7.51-24.15 42.36-11.72 34.62 13.6-2.79 8.6-4.92 8.68-6.28 13.07-4.56 14.77 41.85 28.4 51-1.39 4.47-14.52-5.3-21.71-22.25-39.85-28.47-31.75-16-65.49 2.95-79.67C204.23 140.13 251.94 197 262 205.29c37.17-109 100.53-105.46 102.43-105.53 25.16-.81 44.19 10.59 44.83 28.65.25 7.69-4.17 22.59-19.52 23.13z" } }, "free": ["brands"] }, "synagogue": { "aliases": { "unicodes": { "composite": ["1f54d"], "secondary": ["10f69b"] } }, "changes": [ "5.3.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Jew", "Jewish", "building", "jewish", "judaism", "religion", "star of david", "synagogue", "temple" ] }, "styles": ["solid"], "unicode": "f69b", "label": "Synagogue", "voted": false, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M309.8 3.7c5.9-4.9 14.6-4.9 20.5 0l121 100.8C469.5 119.7 480 142.2 480 166V280.1 512H464 352V416c0-17.7-14.3-32-32-32s-32 14.3-32 32v96H176 160V280.1 166c0-23.7 10.5-46.3 28.8-61.5L309.8 3.7zM512 512V244.5l28.1-31.2c3-3.4 7.4-5.3 11.9-5.3s8.9 1.9 11.9 5.3l63.8 70.9c7.9 8.8 12.3 20.3 12.3 32.1V448c0 35.3-28.7 64-64 64H512zM128 244.5V512H64c-35.3 0-64-28.7-64-64V316.3c0-11.9 4.4-23.3 12.3-32.1l63.8-70.9c3-3.4 7.4-5.3 11.9-5.3s8.9 1.9 11.9 5.3L128 244.5zM327 124.3c-3.1-5.4-10.9-5.4-13.9 0l-15.9 28.1-32.3-.3c-6.2-.1-10.1 6.7-7 12.1L274.3 192l-16.4 27.8c-3.2 5.4 .7 12.1 7 12.1l32.3-.3L313 259.7c3.1 5.4 10.9 5.4 13.9 0l15.9-28.1 32.3 .3c6.2 .1 10.1-6.7 7-12.1L365.7 192l16.4-27.8c3.2-5.4-.7-12.1-7-12.1l-32.3 .3L327 124.3z" } }, "free": ["solid"] }, "syringe": { "aliases": { "unicodes": { "composite": ["1f489"], "secondary": ["10f48e"] } }, "changes": ["5.0.7", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "covid-19", "doctor", "immunizations", "medical", "medicine", "needle", "shot", "sick", "syringe", "vaccinate", "vaccine" ] }, "styles": ["solid"], "unicode": "f48e", "label": "Syringe", "voted": false, "svg": { "solid": { "last_modified": 1684766749, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M441 7l32 32 32 32c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-15-15L417.9 128l55 55c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-72-72L295 73c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l55 55L422.1 56 407 41c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0zM210.3 155.7l61.1-61.1c.3 .3 .6 .7 1 1l16 16 56 56 56 56 16 16c.3 .3 .6 .6 1 1l-191 191c-10.5 10.5-24.7 16.4-39.6 16.4H97.9L41 505c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l57-57V325.3c0-14.9 5.9-29.1 16.4-39.6l43.3-43.3 57 57c6.2 6.2 16.4 6.2 22.6 0s6.2-16.4 0-22.6l-57-57 41.4-41.4 57 57c6.2 6.2 16.4 6.2 22.6 0s6.2-16.4 0-22.6l-57-57z" } }, "free": ["solid"] }, "t": { "aliases": { "unicodes": { "composite": ["74"] } }, "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Latin Capital Letter T", "Latin Small Letter T", "letter"] }, "styles": ["solid"], "unicode": "54", "label": "T", "voted": false, "svg": { "solid": { "last_modified": 1684767244, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M32 32C14.3 32 0 46.3 0 64S14.3 96 32 96H160V448c0 17.7 14.3 32 32 32s32-14.3 32-32V96H352c17.7 0 32-14.3 32-32s-14.3-32-32-32H192 32z" } }, "free": ["solid"] }, "table": { "aliases": { "unicodes": { "secondary": ["10f0ce"] } }, "changes": [ "2.0.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["data", "excel", "spreadsheet"] }, "styles": ["solid"], "unicode": "f0ce", "label": "Table", "voted": false, "svg": { "solid": { "last_modified": 1684767207, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M64 256V160H224v96H64zm0 64H224v96H64V320zm224 96V320H448v96H288zM448 256H288V160H448v96zM64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64z" } }, "free": ["solid"] }, "table-cells": { "aliases": { "names": ["th"], "unicodes": { "secondary": ["10f00a"] } }, "changes": [ "1.0.0", "5.0.0", "5.7.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["blocks", "boxes", "grid", "squares"] }, "styles": ["solid"], "unicode": "f00a", "label": "Table Cells", "voted": false, "svg": { "solid": { "last_modified": 1684767206, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zm88 64v64H64V96h88zm56 0h88v64H208V96zm240 0v64H360V96h88zM64 224h88v64H64V224zm232 0v64H208V224h88zm64 0h88v64H360V224zM152 352v64H64V352h88zm56 0h88v64H208V352zm240 0v64H360V352h88z" } }, "free": ["solid"] }, "table-cells-large": { "aliases": { "names": ["th-large"], "unicodes": { "secondary": ["10f009"] } }, "changes": [ "1.0.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["blocks", "boxes", "grid", "squares"] }, "styles": ["solid"], "unicode": "f009", "label": "Table Cells Large", "voted": false, "svg": { "solid": { "last_modified": 1684767206, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M448 96V224H288V96H448zm0 192V416H288V288H448zM224 224H64V96H224V224zM64 288H224V416H64V288zM64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64z" } }, "free": ["solid"] }, "table-columns": { "aliases": { "names": ["columns"], "unicodes": { "secondary": ["10f0db"] } }, "changes": [ "2.0.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["browser", "dashboard", "organize", "panes", "split"] }, "styles": ["solid"], "unicode": "f0db", "label": "Table Columns", "voted": false, "svg": { "solid": { "last_modified": 1684767207, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 96C0 60.7 28.7 32 64 32H448c35.3 0 64 28.7 64 64V416c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V96zm64 64V416H224V160H64zm384 0H288V416H448V160z" } }, "free": ["solid"] }, "table-list": { "aliases": { "names": ["th-list"], "unicodes": { "secondary": ["10f00b"] } }, "changes": [ "1.0.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "checklist", "completed", "done", "finished", "ol", "todo", "ul" ] }, "styles": ["solid"], "unicode": "f00b", "label": "Table List", "voted": false, "svg": { "solid": { "last_modified": 1684767205, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 96C0 60.7 28.7 32 64 32H448c35.3 0 64 28.7 64 64V416c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V96zm64 0v64h64V96H64zm384 0H192v64H448V96zM64 224v64h64V224H64zm384 0H192v64H448V224zM64 352v64h64V352H64zm384 0H192v64H448V352z" } }, "free": ["solid"] }, "table-tennis-paddle-ball": { "aliases": { "names": ["ping-pong-paddle-ball", "table-tennis"], "unicodes": { "composite": ["1f3d3"], "secondary": ["10f45d"] } }, "changes": ["5.0.5", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["ball", "bat", "game", "paddle", "ping pong", "table tennis"] }, "styles": ["solid"], "unicode": "f45d", "label": "Table Tennis Paddle Ball", "voted": false, "svg": { "solid": { "last_modified": 1684767070, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M480 288c-50.1 0-93.6 28.8-114.6 70.8L132.9 126.3l.6-.6 60.1-60.1c87.5-87.5 229.3-87.5 316.8 0c67.1 67.1 82.7 166.3 46.8 248.3C535.8 297.6 509 288 480 288zM113.3 151.9L354.1 392.7c-1.4 7.5-2.1 15.3-2.1 23.3c0 23.2 6.2 44.9 16.9 63.7c-3 .2-6.1 .3-9.2 .3H357c-33.9 0-66.5-13.5-90.5-37.5l-9.8-9.8c-13.1-13.1-34.6-12.4-46.8 1.7L152.2 501c-5.8 6.7-14.2 10.7-23 11s-17.5-3.1-23.8-9.4l-32-32c-6.3-6.3-9.7-14.9-9.4-23.8s4.3-17.2 11-23l66.6-57.7c14-12.2 14.8-33.7 1.7-46.8l-9.8-9.8c-24-24-37.5-56.6-37.5-90.5v-2.7c0-22.8 6.1-44.9 17.3-64.3zM480 320a96 96 0 1 1 0 192 96 96 0 1 1 0-192z" } }, "free": ["solid"] }, "tablet": { "aliases": { "names": ["tablet-android"], "unicodes": { "secondary": ["10f3fb"] } }, "changes": ["5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["device", "kindle", "screen"] }, "styles": ["solid"], "unicode": "f3fb", "label": "Tablet", "voted": false, "svg": { "solid": { "last_modified": 1684767341, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M64 0C28.7 0 0 28.7 0 64V448c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V64c0-35.3-28.7-64-64-64H64zM176 432h96c8.8 0 16 7.2 16 16s-7.2 16-16 16H176c-8.8 0-16-7.2-16-16s7.2-16 16-16z" } }, "free": ["solid"] }, "tablet-button": { "aliases": { "unicodes": { "secondary": ["10f10a"] } }, "changes": ["3.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["apple", "device", "ipad", "kindle", "screen"] }, "styles": ["solid"], "unicode": "f10a", "label": "Tablet Button", "voted": false, "svg": { "solid": { "last_modified": 1684767343, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M64 0C28.7 0 0 28.7 0 64V448c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V64c0-35.3-28.7-64-64-64H64zM224 400a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" } }, "free": ["solid"] }, "tablet-screen-button": { "aliases": { "names": ["tablet-alt"], "unicodes": { "secondary": ["10f3fa"] } }, "changes": ["5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["apple", "device", "ipad", "kindle", "screen"] }, "styles": ["solid"], "unicode": "f3fa", "label": "Tablet Screen Button", "voted": false, "svg": { "solid": { "last_modified": 1684767343, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M0 64C0 28.7 28.7 0 64 0H384c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V64zM256 448a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zM384 64H64V384H384V64z" } }, "free": ["solid"] }, "tablets": { "aliases": { "unicodes": { "secondary": ["10f490"] } }, "changes": ["5.0.7", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["drugs", "medicine", "pills", "prescription"] }, "styles": ["solid"], "unicode": "f490", "label": "Tablets", "voted": false, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M614.3 247c16.3-25 25.7-54.9 25.7-87C640 71.6 568.4 0 480 0c-32.1 0-61.9 9.4-87 25.7c-7.9 5.2-8.5 16.2-1.8 22.9L591.4 248.8c6.7 6.7 17.8 6.2 22.9-1.8zM567 294.3c7.9-5.2 8.5-16.2 1.8-22.9L368.6 71.2c-6.7-6.7-17.8-6.2-22.9 1.8c-16.3 25-25.7 54.9-25.7 87c0 88.4 71.6 160 160 160c32.1 0 61.9-9.4 87-25.7zM301.5 368H18.5c-9.5 0-16.9 8.2-15 17.5C18.9 457.8 83.1 512 160 512s141.1-54.2 156.5-126.5c2-9.3-5.5-17.5-15-17.5zm0-32c9.5 0 16.9-8.2 15-17.5C301.1 246.2 236.9 192 160 192S18.9 246.2 3.5 318.5c-2 9.3 5.5 17.5 15 17.5H301.5z" } }, "free": ["solid"] }, "tachograph-digital": { "aliases": { "names": ["digital-tachograph"], "unicodes": { "secondary": ["10f566"] } }, "changes": ["5.1.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["data", "distance", "speed", "tachometer"] }, "styles": ["solid"], "unicode": "f566", "label": "Tachograph Digital", "voted": true, "svg": { "solid": { "last_modified": 1684767343, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M64 64C28.7 64 0 92.7 0 128V384c0 35.3 28.7 64 64 64H576c35.3 0 64-28.7 64-64V128c0-35.3-28.7-64-64-64H64zm32 64H320c17.7 0 32 14.3 32 32v64c0 17.7-14.3 32-32 32H96c-17.7 0-32-14.3-32-32V160c0-17.7 14.3-32 32-32zM64 368c0-8.8 7.2-16 16-16H336c8.8 0 16 7.2 16 16s-7.2 16-16 16H80c-8.8 0-16-7.2-16-16zm320 0c0-8.8 7.2-16 16-16H560c8.8 0 16 7.2 16 16s-7.2 16-16 16H400c-8.8 0-16-7.2-16-16zM80 288a16 16 0 1 1 0 32 16 16 0 1 1 0-32zm48 16a16 16 0 1 1 32 0 16 16 0 1 1 -32 0zm80-16a16 16 0 1 1 0 32 16 16 0 1 1 0-32zm48 16a16 16 0 1 1 32 0 16 16 0 1 1 -32 0zm80-16a16 16 0 1 1 0 32 16 16 0 1 1 0-32z" } }, "free": ["solid"] }, "tag": { "aliases": { "unicodes": { "composite": ["1f3f7"], "secondary": ["10f02b"] } }, "changes": [ "1.0.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["discount", "labe", "label", "price", "shopping"] }, "styles": ["solid"], "unicode": "f02b", "label": "Tag", "voted": false, "svg": { "solid": { "last_modified": 1684766475, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M0 80V229.5c0 17 6.7 33.3 18.7 45.3l176 176c25 25 65.5 25 90.5 0L418.7 317.3c25-25 25-65.5 0-90.5l-176-176c-12-12-28.3-18.7-45.3-18.7H48C21.5 32 0 53.5 0 80zm112 32a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" } }, "free": ["solid"] }, "tags": { "aliases": { "unicodes": { "secondary": ["10f02c"] } }, "changes": [ "1.0.0", "5.0.0", "5.10.2", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["discount", "label", "price", "shopping"] }, "styles": ["solid"], "unicode": "f02c", "label": "Tags", "voted": false, "svg": { "solid": { "last_modified": 1684766475, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M345 39.1L472.8 168.4c52.4 53 52.4 138.2 0 191.2L360.8 472.9c-9.3 9.4-24.5 9.5-33.9 .2s-9.5-24.5-.2-33.9L438.6 325.9c33.9-34.3 33.9-89.4 0-123.7L310.9 72.9c-9.3-9.4-9.2-24.6 .2-33.9s24.6-9.2 33.9 .2zM0 229.5V80C0 53.5 21.5 32 48 32H197.5c17 0 33.3 6.7 45.3 18.7l168 168c25 25 25 65.5 0 90.5L277.3 442.7c-25 25-65.5 25-90.5 0l-168-168C6.7 262.7 0 246.5 0 229.5zM144 144a32 32 0 1 0 -64 0 32 32 0 1 0 64 0z" } }, "free": ["solid"] }, "tape": { "aliases": { "unicodes": { "secondary": ["10f4db"] } }, "changes": ["5.0.9", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["design", "package", "sticky"] }, "styles": ["solid"], "unicode": "f4db", "label": "Tape", "voted": false, "svg": { "solid": { "last_modified": 1684767367, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M380.8 416c41.5-40.7 67.2-97.3 67.2-160C448 132.3 347.7 32 224 32S0 132.3 0 256S100.3 480 224 480H544c17.7 0 32-14.3 32-32s-14.3-32-32-32H380.8zM224 160a96 96 0 1 1 0 192 96 96 0 1 1 0-192zm64 96a64 64 0 1 0 -128 0 64 64 0 1 0 128 0z" } }, "free": ["solid"] }, "tarp": { "changes": ["6.1.0", "6.1.2", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["protection", "tarp", "tent", "waterproof"] }, "styles": ["solid"], "unicode": "e57b", "label": "Tarp", "voted": false, "svg": { "solid": { "last_modified": 1684767442, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M576 128c0-35.3-28.7-64-64-64H64C28.7 64 0 92.7 0 128V384c0 35.3 28.7 64 64 64l352 0 0-128c0-17.7 14.3-32 32-32H576V128zM448 448L576 320H448l0 128zM96 128a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" } }, "free": ["solid"] }, "tarp-droplet": { "changes": ["6.1.0", "6.1.2", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["protection", "tarp", "tent", "waterproof"] }, "styles": ["solid"], "unicode": "e57c", "label": "Tarp Droplet", "voted": false, "svg": { "solid": { "last_modified": 1684767442, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M288 160c-35.3 0-64-26.9-64-60c0-24 33.7-70.1 52.2-93.5c6.1-7.7 17.5-7.7 23.6 0C318.3 29.9 352 76 352 100c0 33.1-28.7 60-64 60zM64 128H197.5c13.2 37.3 48.7 64 90.5 64s77.4-26.7 90.5-64H512c35.3 0 64 28.7 64 64V352H448c-17.7 0-32 14.3-32 32l0 128L64 512c-35.3 0-64-28.7-64-64V192c0-35.3 28.7-64 64-64zM448 512l0-128H576L448 512zM96 256a32 32 0 1 0 0-64 32 32 0 1 0 0 64z" } }, "free": ["solid"] }, "taxi": { "aliases": { "names": ["cab"], "unicodes": { "composite": ["1f696"], "secondary": ["10f1ba"] } }, "changes": [ "4.1.0", "5.0.0", "5.1.0", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "cab", "cabbie", "car", "car service", "lyft", "machine", "oncoming", "oncoming taxi", "taxi", "transportation", "travel", "uber", "vehicle" ] }, "styles": ["solid"], "unicode": "f1ba", "label": "Taxi", "voted": false, "svg": { "solid": { "last_modified": 1684767650, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M192 0c-17.7 0-32 14.3-32 32V64c0 .1 0 .1 0 .2c-38.6 2.2-72.3 27.3-85.2 64.1L39.6 228.8C16.4 238.4 0 261.3 0 288V432v48c0 17.7 14.3 32 32 32H64c17.7 0 32-14.3 32-32V432H416v48c0 17.7 14.3 32 32 32h32c17.7 0 32-14.3 32-32V432 288c0-26.7-16.4-49.6-39.6-59.2L437.2 128.3c-12.9-36.8-46.6-62-85.2-64.1c0-.1 0-.1 0-.2V32c0-17.7-14.3-32-32-32H192zM165.4 128H346.6c13.6 0 25.7 8.6 30.2 21.4L402.9 224H109.1l26.1-74.6c4.5-12.8 16.6-21.4 30.2-21.4zM96 288a32 32 0 1 1 0 64 32 32 0 1 1 0-64zm288 32a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z" } }, "free": ["solid"] }, "teamspeak": { "changes": ["5.0.11", "5.1.0", "5.8.0", "6.4.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f4f9", "label": "Teamspeak", "voted": true, "svg": { "brands": { "last_modified": 1678906824, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M152.8 37.2c-32.2 38.1-56.1 82.6-69.9 130.5c0 .2-.1 .3-.1 .5C43.5 184.4 16 223 16 268c0 59.6 48.4 108 108 108s108-48.4 108-108c0-53.5-38.9-97.9-90-106.5c15.7-41.8 40.4-79.6 72.3-110.7c1.8-1.6 4-2.6 6.3-3.1c37.2-11.5 76.7-13.3 114.8-5.2C454.7 67.6 534 180.7 517.1 301.3c-8.4 62.6-38.6 112.7-87.7 151.4c-50.1 39.7-107.5 54.3-170.2 52.2l-24-1c12.4 2.8 25 4.9 37.6 6.3c40.7 4.2 81.4 2.1 120.1-12.5c94-35.5 149.3-102.3 162.9-202.5c4.8-52.6-5.8-105.4-30.8-152C454.6 11.3 290.8-38.4 159 32c-2.4 1.4-4.5 3.1-6.3 5.2zM309.4 433.9c-2.1 11.5-4.2 21.9-14.6 31.3c53.2-1 123.2-29.2 161.8-97.1c39.7-69.9 37.6-139.9-6.3-207.8C413.8 105 360.5 77.9 293.7 73.7c1.5 2.3 3.2 4.4 5.2 6.3l5.2 6.3c25.1 31.3 37.6 67.9 42.8 107.5c2.1 15.7-1 30.3-13.6 41.8c-4.2 3.1-5.2 6.3-4.2 10.4l7.3 17.7L365.7 318c5.2 11.5 4.2 19.8-6.3 28.2c-3.2 2.5-6.7 4.6-10.4 6.3l-18.8 8.4 3.1 13.6c3.1 6.3 1 12.5-3.1 17.7c-2.5 2.4-3.8 5.9-3.1 9.4c2.1 11.5-2.1 19.8-12.5 25.1c-2.1 1-4.2 5.2-5.2 7.3zm-133.6-3.1c16.7 11.5 34.5 20.9 53.2 26.1c24 5.2 41.8-6.3 44.9-30.3c1-8.4 5.2-14.6 12.5-17.7c7.3-4.2 8.4-7.3 2.1-13.6l-9.4-8.4 13.6-4.2c6.3-2.1 7.3-5.2 5.2-11.5c-1.4-3-2.4-6.2-3.1-9.4c-3.1-14.6-2.1-15.7 11.5-18.8c8.4-3.1 15.7-6.3 21.9-12.5c3.1-2.1 3.1-4.2 1-8.4l-16.7-30.3c-1-1.9-2.1-3.8-3.1-5.7c-6.4-11.7-13-23.6-15.7-37.1c-2.1-9.4-1-17.7 8.4-24c5.2-4.2 8.4-9.4 8.4-16.7c-.4-10.1-1.5-20.3-3.1-30.3c-6.3-37.6-23-68.9-51.2-95c-5.2-4.2-9.4-6.3-16.7-4.2L203.9 91.5c2 1.2 4 2.4 6 3.6l0 0c6.3 3.7 12.2 7.3 17 12.1c30.3 26.1 41.8 61.6 45.9 100.2c1 8.4 0 16.7-7.3 21.9c-8.4 5.2-10.4 12.5-7.3 20.9c4.9 13.2 10.4 26 16.7 38.6L291.6 318c-6.3 8.4-13.6 11.5-21.9 14.6c-12.5 3.1-14.6 7.3-10.4 20.9c.6 1.5 1.4 2.8 2.1 4.2c2.1 5.2 1 8.4-4.2 10.4l-12.5 3.1 5.2 4.2 4.2 4.2c4.2 5.2 4.2 8.4-2.1 10.4c-7.3 4.2-11.5 9.4-11.5 17.7c0 12.5-7.3 19.8-18.8 24c-3.8 1-7.6 1.5-11.5 1l-34.5-2.1z" } }, "free": ["brands"] }, "teeth": { "aliases": { "unicodes": { "secondary": ["10f62e"] } }, "changes": ["5.2.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["bite", "dental", "dentist", "gums", "mouth", "smile", "tooth"] }, "styles": ["solid"], "unicode": "f62e", "label": "Teeth", "voted": false, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M0 128C0 75 43 32 96 32H480c53 0 96 43 96 96V384c0 53-43 96-96 96H96c-53 0-96-43-96-96V128zm176 48v56c0 13.3 10.7 24 24 24h48c13.3 0 24-10.7 24-24V176c0-26.5-21.5-48-48-48s-48 21.5-48 48zm176-48c-26.5 0-48 21.5-48 48v56c0 13.3 10.7 24 24 24h48c13.3 0 24-10.7 24-24V176c0-26.5-21.5-48-48-48zM48 208v24c0 13.3 10.7 24 24 24h48c13.3 0 24-10.7 24-24V208c0-26.5-21.5-48-48-48s-48 21.5-48 48zM96 384c26.5 0 48-21.5 48-48V312c0-13.3-10.7-24-24-24H72c-13.3 0-24 10.7-24 24v24c0 26.5 21.5 48 48 48zm80-48c0 26.5 21.5 48 48 48s48-21.5 48-48V312c0-13.3-10.7-24-24-24H200c-13.3 0-24 10.7-24 24v24zm176 48c26.5 0 48-21.5 48-48V312c0-13.3-10.7-24-24-24H328c-13.3 0-24 10.7-24 24v24c0 26.5 21.5 48 48 48zm80-176v24c0 13.3 10.7 24 24 24h48c13.3 0 24-10.7 24-24V208c0-26.5-21.5-48-48-48s-48 21.5-48 48zm48 176c26.5 0 48-21.5 48-48V312c0-13.3-10.7-24-24-24H456c-13.3 0-24 10.7-24 24v24c0 26.5 21.5 48 48 48z" } }, "free": ["solid"] }, "teeth-open": { "aliases": { "unicodes": { "secondary": ["10f62f"] } }, "changes": ["5.2.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["dental", "dentist", "gums bite", "mouth", "smile", "tooth"] }, "styles": ["solid"], "unicode": "f62f", "label": "Teeth Open", "voted": false, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M96 32C43 32 0 75 0 128v64c0 35.3 28.7 64 64 64H512c35.3 0 64-28.7 64-64V128c0-53-43-96-96-96H96zM224 96c26.5 0 48 21.5 48 48v56c0 13.3-10.7 24-24 24H200c-13.3 0-24-10.7-24-24V144c0-26.5 21.5-48 48-48zm80 48c0-26.5 21.5-48 48-48s48 21.5 48 48v56c0 13.3-10.7 24-24 24H328c-13.3 0-24-10.7-24-24V144zM96 128c26.5 0 48 21.5 48 48v24c0 13.3-10.7 24-24 24H72c-13.3 0-24-10.7-24-24V176c0-26.5 21.5-48 48-48zm336 48c0-26.5 21.5-48 48-48s48 21.5 48 48v24c0 13.3-10.7 24-24 24H456c-13.3 0-24-10.7-24-24V176zM96 480H480c53 0 96-43 96-96V352c0-35.3-28.7-64-64-64H64c-35.3 0-64 28.7-64 64v32c0 53 43 96 96 96zm0-64c-26.5 0-48-21.5-48-48V344c0-13.3 10.7-24 24-24h48c13.3 0 24 10.7 24 24v24c0 26.5-21.5 48-48 48zm80-48V344c0-13.3 10.7-24 24-24h48c13.3 0 24 10.7 24 24v24c0 26.5-21.5 48-48 48s-48-21.5-48-48zm176 48c-26.5 0-48-21.5-48-48V344c0-13.3 10.7-24 24-24h48c13.3 0 24 10.7 24 24v24c0 26.5-21.5 48-48 48zm80-48V344c0-13.3 10.7-24 24-24h48c13.3 0 24 10.7 24 24v24c0 26.5-21.5 48-48 48s-48-21.5-48-48z" } }, "free": ["solid"] }, "telegram": { "aliases": { "names": ["telegram-plane"], "unicodes": { "composite": ["f3fe"], "secondary": ["10f3fe"] } }, "changes": ["4.7.0", "5.0.0", "6.0.0-beta1"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f2c6", "label": "Telegram", "voted": false, "svg": { "brands": { "last_modified": 1660014460, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M248,8C111.033,8,0,119.033,0,256S111.033,504,248,504,496,392.967,496,256,384.967,8,248,8ZM362.952,176.66c-3.732,39.215-19.881,134.378-28.1,178.3-3.476,18.584-10.322,24.816-16.948,25.425-14.4,1.326-25.338-9.517-39.287-18.661-21.827-14.308-34.158-23.215-55.346-37.177-24.485-16.135-8.612-25,5.342-39.5,3.652-3.793,67.107-61.51,68.335-66.746.153-.655.3-3.1-1.154-4.384s-3.59-.849-5.135-.5q-3.283.746-104.608,69.142-14.845,10.194-26.894,9.934c-8.855-.191-25.888-5.006-38.551-9.123-15.531-5.048-27.875-7.717-26.8-16.291q.84-6.7,18.45-13.7,108.446-47.248,144.628-62.3c68.872-28.647,83.183-33.623,92.511-33.789,2.052-.034,6.639.474,9.61,2.885a10.452,10.452,0,0,1,3.53,6.716A43.765,43.765,0,0,1,362.952,176.66Z" } }, "free": ["brands"] }, "temperature-arrow-down": { "aliases": { "names": ["temperature-down"], "unicodes": { "secondary": ["10e03f"] } }, "changes": [ "5.12.0", "5.14.0", "6.0.0-beta1", "6.1.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "air conditioner", "cold", "heater", "mercury", "thermometer", "winter" ] }, "styles": ["solid"], "unicode": "e03f", "label": "Temperature Arrow Down", "voted": false, "svg": { "solid": { "last_modified": 1684767662, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M128 112c0-26.5 21.5-48 48-48s48 21.5 48 48V276.5c0 17.3 7.1 31.9 15.3 42.5C249.8 332.6 256 349.5 256 368c0 44.2-35.8 80-80 80s-80-35.8-80-80c0-18.5 6.2-35.4 16.7-48.9c8.2-10.6 15.3-25.2 15.3-42.5V112zM176 0C114.1 0 64 50.1 64 112V276.4c0 .1-.1 .3-.2 .6c-.2 .6-.8 1.6-1.7 2.8C43.2 304.2 32 334.8 32 368c0 79.5 64.5 144 144 144s144-64.5 144-144c0-33.2-11.2-63.8-30.1-88.1c-.9-1.2-1.5-2.2-1.7-2.8c-.1-.3-.2-.5-.2-.6V112C288 50.1 237.9 0 176 0zm0 416c26.5 0 48-21.5 48-48c0-20.9-13.4-38.7-32-45.3V272c0-8.8-7.2-16-16-16s-16 7.2-16 16v50.7c-18.6 6.6-32 24.4-32 45.3c0 26.5 21.5 48 48 48zm336-64H480V64c0-17.7-14.3-32-32-32s-32 14.3-32 32V352H384c-12.9 0-24.6 7.8-29.6 19.8s-2.2 25.7 6.9 34.9l64 64c6 6 14.1 9.4 22.6 9.4s16.6-3.4 22.6-9.4l64-64c9.2-9.2 11.9-22.9 6.9-34.9s-16.6-19.8-29.6-19.8z" } }, "free": ["solid"] }, "temperature-arrow-up": { "aliases": { "names": ["temperature-up"], "unicodes": { "secondary": ["10e040"] } }, "changes": [ "5.12.0", "5.14.0", "6.0.0-beta1", "6.1.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "air conditioner", "cold", "heater", "mercury", "thermometer", "winter" ] }, "styles": ["solid"], "unicode": "e040", "label": "Temperature Arrow Up", "voted": false, "svg": { "solid": { "last_modified": 1684767661, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M128 112c0-26.5 21.5-48 48-48s48 21.5 48 48V276.5c0 17.3 7.1 31.9 15.3 42.5C249.8 332.6 256 349.5 256 368c0 44.2-35.8 80-80 80s-80-35.8-80-80c0-18.5 6.2-35.4 16.7-48.9c8.2-10.6 15.3-25.2 15.3-42.5V112zM176 0C114.1 0 64 50.1 64 112V276.4c0 .1-.1 .3-.2 .6c-.2 .6-.8 1.6-1.7 2.8C43.2 304.2 32 334.8 32 368c0 79.5 64.5 144 144 144s144-64.5 144-144c0-33.2-11.2-63.8-30.1-88.1c-.9-1.2-1.5-2.2-1.7-2.8c-.1-.3-.2-.5-.2-.6V112C288 50.1 237.9 0 176 0zm0 416c26.5 0 48-21.5 48-48c0-20.9-13.4-38.7-32-45.3V112c0-8.8-7.2-16-16-16s-16 7.2-16 16V322.7c-18.6 6.6-32 24.4-32 45.3c0 26.5 21.5 48 48 48zM480 160h32c12.9 0 24.6-7.8 29.6-19.8s2.2-25.7-6.9-34.9l-64-64c-12.5-12.5-32.8-12.5-45.3 0l-64 64c-9.2 9.2-11.9 22.9-6.9 34.9s16.6 19.8 29.6 19.8h32V448c0 17.7 14.3 32 32 32s32-14.3 32-32V160z" } }, "free": ["solid"] }, "temperature-empty": { "aliases": { "names": ["temperature-0", "thermometer-0", "thermometer-empty"], "unicodes": { "secondary": ["10f2cb"] } }, "changes": ["4.7.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["cold", "mercury", "status", "temperature"] }, "styles": ["solid"], "unicode": "f2cb", "label": "Temperature Empty", "voted": false, "svg": { "solid": { "last_modified": 1684767662, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M112 112c0-26.5 21.5-48 48-48s48 21.5 48 48V276.5c0 17.3 7.1 31.9 15.3 42.5C233.8 332.6 240 349.5 240 368c0 44.2-35.8 80-80 80s-80-35.8-80-80c0-18.5 6.2-35.4 16.7-48.9c8.2-10.6 15.3-25.2 15.3-42.5V112zM160 0C98.1 0 48 50.2 48 112V276.5c0 .1-.1 .3-.2 .6c-.2 .6-.8 1.6-1.7 2.8C27.2 304.2 16 334.8 16 368c0 79.5 64.5 144 144 144s144-64.5 144-144c0-33.2-11.2-63.8-30.1-88.1c-.9-1.2-1.5-2.2-1.7-2.8c-.1-.3-.2-.5-.2-.6V112C272 50.2 221.9 0 160 0zm0 416a48 48 0 1 0 0-96 48 48 0 1 0 0 96z" } }, "free": ["solid"] }, "temperature-full": { "aliases": { "names": ["temperature-4", "thermometer-4", "thermometer-full"], "unicodes": { "secondary": ["10f2c7"] } }, "changes": ["4.7.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["fever", "hot", "mercury", "status", "temperature"] }, "styles": ["solid"], "unicode": "f2c7", "label": "Temperature Full", "voted": false, "svg": { "solid": { "last_modified": 1684767661, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M160 64c-26.5 0-48 21.5-48 48V276.5c0 17.3-7.1 31.9-15.3 42.5C86.2 332.6 80 349.5 80 368c0 44.2 35.8 80 80 80s80-35.8 80-80c0-18.5-6.2-35.4-16.7-48.9c-8.2-10.6-15.3-25.2-15.3-42.5V112c0-26.5-21.5-48-48-48zM48 112C48 50.2 98.1 0 160 0s112 50.1 112 112V276.5c0 .1 .1 .3 .2 .6c.2 .6 .8 1.6 1.7 2.8c18.9 24.4 30.1 55 30.1 88.1c0 79.5-64.5 144-144 144S16 447.5 16 368c0-33.2 11.2-63.8 30.1-88.1c.9-1.2 1.5-2.2 1.7-2.8c.1-.3 .2-.5 .2-.6V112zM208 368c0 26.5-21.5 48-48 48s-48-21.5-48-48c0-20.9 13.4-38.7 32-45.3V112c0-8.8 7.2-16 16-16s16 7.2 16 16V322.7c18.6 6.6 32 24.4 32 45.3z" } }, "free": ["solid"] }, "temperature-half": { "aliases": { "names": ["temperature-2", "thermometer-2", "thermometer-half"], "unicodes": { "composite": ["1f321"], "secondary": ["10f2c9"] } }, "changes": ["4.7.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["mercury", "status", "temperature", "thermometer", "weather"] }, "styles": ["solid"], "unicode": "f2c9", "label": "Temperature Half", "voted": false, "svg": { "solid": { "last_modified": 1684767662, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M160 64c-26.5 0-48 21.5-48 48V276.5c0 17.3-7.1 31.9-15.3 42.5C86.2 332.6 80 349.5 80 368c0 44.2 35.8 80 80 80s80-35.8 80-80c0-18.5-6.2-35.4-16.7-48.9c-8.2-10.6-15.3-25.2-15.3-42.5V112c0-26.5-21.5-48-48-48zM48 112C48 50.2 98.1 0 160 0s112 50.1 112 112V276.5c0 .1 .1 .3 .2 .6c.2 .6 .8 1.6 1.7 2.8c18.9 24.4 30.1 55 30.1 88.1c0 79.5-64.5 144-144 144S16 447.5 16 368c0-33.2 11.2-63.8 30.1-88.1c.9-1.2 1.5-2.2 1.7-2.8c.1-.3 .2-.5 .2-.6V112zM208 368c0 26.5-21.5 48-48 48s-48-21.5-48-48c0-20.9 13.4-38.7 32-45.3V208c0-8.8 7.2-16 16-16s16 7.2 16 16V322.7c18.6 6.6 32 24.4 32 45.3z" } }, "free": ["solid"] }, "temperature-high": { "aliases": { "unicodes": { "secondary": ["10f769"] } }, "changes": ["5.5.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["cook", "covid-19", "mercury", "summer", "thermometer", "warm"] }, "styles": ["solid"], "unicode": "f769", "label": "Temperature High", "voted": false, "svg": { "solid": { "last_modified": 1684767662, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M416 64a32 32 0 1 1 0 64 32 32 0 1 1 0-64zm0 128A96 96 0 1 0 416 0a96 96 0 1 0 0 192zM96 112c0-26.5 21.5-48 48-48s48 21.5 48 48V276.5c0 17.3 7.1 31.9 15.3 42.5C217.8 332.6 224 349.5 224 368c0 44.2-35.8 80-80 80s-80-35.8-80-80c0-18.5 6.2-35.4 16.7-48.9C88.9 308.4 96 293.8 96 276.5V112zM144 0C82.1 0 32 50.2 32 112V276.5c0 .1-.1 .3-.2 .6c-.2 .6-.8 1.6-1.7 2.8C11.2 304.2 0 334.8 0 368c0 79.5 64.5 144 144 144s144-64.5 144-144c0-33.2-11.2-63.8-30.1-88.1c-.9-1.2-1.5-2.2-1.7-2.8c-.1-.3-.2-.5-.2-.6V112C256 50.2 205.9 0 144 0zm0 416c26.5 0 48-21.5 48-48c0-20.9-13.4-38.7-32-45.3V112c0-8.8-7.2-16-16-16s-16 7.2-16 16V322.7c-18.6 6.6-32 24.4-32 45.3c0 26.5 21.5 48 48 48z" } }, "free": ["solid"] }, "temperature-low": { "aliases": { "unicodes": { "secondary": ["10f76b"] } }, "changes": ["5.5.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["cold", "cool", "covid-19", "mercury", "thermometer", "winter"] }, "styles": ["solid"], "unicode": "f76b", "label": "Temperature Low", "voted": false, "svg": { "solid": { "last_modified": 1684767661, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M448 96a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zM320 96a96 96 0 1 1 192 0A96 96 0 1 1 320 96zM144 64c-26.5 0-48 21.5-48 48V276.5c0 17.3-7.1 31.9-15.3 42.5C70.2 332.6 64 349.5 64 368c0 44.2 35.8 80 80 80s80-35.8 80-80c0-18.5-6.2-35.4-16.7-48.9c-8.2-10.6-15.3-25.2-15.3-42.5V112c0-26.5-21.5-48-48-48zM32 112C32 50.2 82.1 0 144 0s112 50.1 112 112V276.5c0 .1 .1 .3 .2 .6c.2 .6 .8 1.6 1.7 2.8c18.9 24.4 30.1 55 30.1 88.1c0 79.5-64.5 144-144 144S0 447.5 0 368c0-33.2 11.2-63.8 30.1-88.1c.9-1.2 1.5-2.2 1.7-2.8c.1-.3 .2-.5 .2-.6V112zM192 368c0 26.5-21.5 48-48 48s-48-21.5-48-48c0-20.9 13.4-38.7 32-45.3V272c0-8.8 7.2-16 16-16s16 7.2 16 16v50.7c18.6 6.6 32 24.4 32 45.3z" } }, "free": ["solid"] }, "temperature-quarter": { "aliases": { "names": ["temperature-1", "thermometer-1", "thermometer-quarter"], "unicodes": { "secondary": ["10f2ca"] } }, "changes": ["4.7.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["mercury", "status", "temperature"] }, "styles": ["solid"], "unicode": "f2ca", "label": "Temperature Quarter", "voted": false, "svg": { "solid": { "last_modified": 1684767662, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M160 64c-26.5 0-48 21.5-48 48V276.5c0 17.3-7.1 31.9-15.3 42.5C86.2 332.6 80 349.5 80 368c0 44.2 35.8 80 80 80s80-35.8 80-80c0-18.5-6.2-35.4-16.7-48.9c-8.2-10.6-15.3-25.2-15.3-42.5V112c0-26.5-21.5-48-48-48zM48 112C48 50.2 98.1 0 160 0s112 50.1 112 112V276.5c0 .1 .1 .3 .2 .6c.2 .6 .8 1.6 1.7 2.8c18.9 24.4 30.1 55 30.1 88.1c0 79.5-64.5 144-144 144S16 447.5 16 368c0-33.2 11.2-63.8 30.1-88.1c.9-1.2 1.5-2.2 1.7-2.8c.1-.3 .2-.5 .2-.6V112zM208 368c0 26.5-21.5 48-48 48s-48-21.5-48-48c0-20.9 13.4-38.7 32-45.3V272c0-8.8 7.2-16 16-16s16 7.2 16 16v50.7c18.6 6.6 32 24.4 32 45.3z" } }, "free": ["solid"] }, "temperature-three-quarters": { "aliases": { "names": ["temperature-3", "thermometer-3", "thermometer-three-quarters"], "unicodes": { "secondary": ["10f2c8"] } }, "changes": ["4.7.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["mercury", "status", "temperature"] }, "styles": ["solid"], "unicode": "f2c8", "label": "Temperature Three Quarters", "voted": false, "svg": { "solid": { "last_modified": 1684767661, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M160 64c-26.5 0-48 21.5-48 48V276.5c0 17.3-7.1 31.9-15.3 42.5C86.2 332.6 80 349.5 80 368c0 44.2 35.8 80 80 80s80-35.8 80-80c0-18.5-6.2-35.4-16.7-48.9c-8.2-10.6-15.3-25.2-15.3-42.5V112c0-26.5-21.5-48-48-48zM48 112C48 50.2 98.1 0 160 0s112 50.1 112 112V276.5c0 .1 .1 .3 .2 .6c.2 .6 .8 1.6 1.7 2.8c18.9 24.4 30.1 55 30.1 88.1c0 79.5-64.5 144-144 144S16 447.5 16 368c0-33.2 11.2-63.8 30.1-88.1c.9-1.2 1.5-2.2 1.7-2.8c.1-.3 .2-.5 .2-.6V112zM208 368c0 26.5-21.5 48-48 48s-48-21.5-48-48c0-20.9 13.4-38.7 32-45.3V144c0-8.8 7.2-16 16-16s16 7.2 16 16V322.7c18.6 6.6 32 24.4 32 45.3z" } }, "free": ["solid"] }, "tencent-weibo": { "changes": ["4.1.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f1d5", "label": "Tencent Weibo", "voted": false, "svg": { "brands": { "last_modified": 1660014468, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M72.3 495.8c1.4 19.9-27.6 22.2-29.7 2.9C31 368.8 73.7 259.2 144 185.5c-15.6-34 9.2-77.1 50.6-77.1 30.3 0 55.1 24.6 55.1 55.1 0 44-49.5 70.8-86.9 45.1-65.7 71.3-101.4 169.8-90.5 287.2zM192 .1C66.1.1-12.3 134.3 43.7 242.4 52.4 259.8 79 246.9 70 229 23.7 136.4 91 29.8 192 29.8c75.4 0 136.9 61.4 136.9 136.9 0 90.8-86.9 153.9-167.7 133.1-19.1-4.1-25.6 24.4-6.6 29.1 110.7 23.2 204-60 204-162.3C358.6 74.7 284 .1 192 .1z" } }, "free": ["brands"] }, "tenge-sign": { "aliases": { "names": ["tenge"], "unicodes": { "composite": ["20b8"], "secondary": ["10f7d7"] } }, "changes": [ "5.6.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["Tenge Sign", "currency"] }, "styles": ["solid"], "unicode": "f7d7", "label": "Tenge Sign", "voted": true, "svg": { "solid": { "last_modified": 1684766475, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M0 64C0 46.3 14.3 32 32 32H352c17.7 0 32 14.3 32 32s-14.3 32-32 32H32C14.3 96 0 81.7 0 64zM0 192c0-17.7 14.3-32 32-32H192 352c17.7 0 32 14.3 32 32s-14.3 32-32 32H224V448c0 17.7-14.3 32-32 32s-32-14.3-32-32V224H32c-17.7 0-32-14.3-32-32z" } }, "free": ["solid"] }, "tent": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["bivouac", "campground", "refugee", "shelter", "tent"] }, "styles": ["solid"], "unicode": "e57d", "label": "Tent", "voted": false, "svg": { "solid": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M269.4 6C280.5-2 295.5-2 306.6 6l224 160c7.4 5.3 12.2 13.5 13.2 22.5l32 288c1 9-1.9 18.1-8 24.9s-14.7 10.7-23.8 10.7H416L288 288V512H32c-9.1 0-17.8-3.9-23.8-10.7s-9-15.8-8-24.9l32-288c1-9 5.8-17.2 13.2-22.5L269.4 6z" } }, "free": ["solid"] }, "tent-arrow-down-to-line": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["permanent", "refugee", "shelter"] }, "styles": ["solid"], "unicode": "e57e", "label": "Tent Arrow Down To Line", "voted": false, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M241.8 111.9c8.9 9.9 8.1 25-1.8 33.9l-80 72c-9.1 8.2-23 8.2-32.1 0l-80-72c-9.9-8.9-10.7-24-1.8-33.9s24-10.7 33.9-1.8l39.9 36L120 24c0-13.3 10.7-24 24-24s24 10.7 24 24l0 122.1 39.9-36c9.9-8.9 25-8.1 33.9 1.8zm122.8 22.6c11.5-8.7 27.3-8.7 38.8 0l168 128c6.6 5 11 12.5 12.3 20.7l24 160 .7 4.7c17.5 .2 31.6 14.4 31.6 32c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H159.6l.7-4.7 24-160c1.2-8.2 5.6-15.7 12.3-20.7l168-128zM384 448h76.8L384 320V448z" } }, "free": ["solid"] }, "tent-arrow-left-right": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["refugee", "shelter", "transition"] }, "styles": ["solid"], "unicode": "e57f", "label": "Tent Arrow Left Right", "voted": false, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M488.1 6.2c-9.9-8.9-25-8.1-33.9 1.8s-8.1 25 1.8 33.9L489.5 72 86.5 72l33.5-30.2c9.9-8.9 10.7-24 1.8-33.9S97.8-2.7 87.9 6.2l-80 72C2.9 82.7 0 89.2 0 96s2.9 13.3 7.9 17.8l80 72c9.9 8.9 25 8.1 33.9-1.8s8.1-25-1.8-33.9L86.5 120l402.9 0-33.5 30.2c-9.9 8.9-10.7 24-1.8 33.9s24 10.7 33.9 1.8l80-72c5.1-4.6 7.9-11 7.9-17.8s-2.9-13.3-7.9-17.8l-80-72zM307.4 166.5c-11.5-8.7-27.3-8.7-38.8 0l-168 128c-6.6 5-11 12.5-12.3 20.7l-24 160c-1.4 9.2 1.3 18.6 7.4 25.6S86.7 512 96 512H288V352l96 160h96c9.3 0 18.2-4.1 24.2-11.1s8.8-16.4 7.4-25.6l-24-160c-1.2-8.2-5.6-15.7-12.3-20.7l-168-128z" } }, "free": ["solid"] }, "tent-arrow-turn-left": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["refugee", "shelter", "temporary"] }, "styles": ["solid"], "unicode": "e580", "label": "Tent Arrow Turn Left", "voted": false, "svg": { "solid": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M120.1 41.8c9.9-8.9 10.7-24 1.8-33.9S97.8-2.7 87.9 6.2l-80 72C2.9 82.7 0 89.2 0 96s2.9 13.3 7.9 17.8l80 72c9.9 8.9 25 8.1 33.9-1.8s8.1-25-1.8-33.9L86.5 120 456 120c39.8 0 72 32.2 72 72v40c0 13.3 10.7 24 24 24s24-10.7 24-24V192c0-66.3-53.7-120-120-120L86.5 72l33.5-30.2zM307.4 166.5c-11.5-8.7-27.3-8.7-38.8 0l-168 128c-6.6 5-11 12.5-12.3 20.7l-24 160c-1.4 9.2 1.3 18.6 7.4 25.6S86.7 512 96 512H288V352l96 160h96c9.3 0 18.2-4.1 24.2-11.1s8.8-16.4 7.4-25.6l-24-160c-1.2-8.2-5.6-15.7-12.3-20.7l-168-128z" } }, "free": ["solid"] }, "tent-arrows-down": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["refugee", "shelter", "spontaneous"] }, "styles": ["solid"], "unicode": "e581", "label": "Tent Arrows Down", "voted": false, "svg": { "solid": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M209.8 111.9c-8.9-9.9-24-10.7-33.9-1.8l-39.9 36L136 24c0-13.3-10.7-24-24-24S88 10.7 88 24l0 122.1-39.9-36c-9.9-8.9-25-8.1-33.9 1.8s-8.1 25 1.8 33.9l80 72c9.1 8.2 23 8.2 32.1 0l80-72c9.9-8.9 10.7-24 1.8-33.9zm352 0c-8.9-9.9-24-10.7-33.9-1.8l-39.9 36V24c0-13.3-10.7-24-24-24s-24 10.7-24 24V146.1l-39.9-36c-9.9-8.9-25-8.1-33.9 1.8s-8.1 25 1.8 33.9l80 72c9.1 8.2 23 8.2 32.1 0l80-72c9.9-8.9 10.7-24 1.8-33.9zM307.4 166.5c-11.5-8.7-27.3-8.7-38.8 0l-168 128c-6.6 5-11 12.5-12.3 20.7l-24 160c-1.4 9.2 1.3 18.6 7.4 25.6S86.7 512 96 512H288V352l96 160h96c9.3 0 18.2-4.1 24.2-11.1s8.8-16.4 7.4-25.6l-24-160c-1.2-8.2-5.6-15.7-12.3-20.7l-168-128z" } }, "free": ["solid"] }, "tents": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["bivouac", "campground", "refugee", "shelter", "tent"] }, "styles": ["solid"], "unicode": "e582", "label": "Tents", "voted": false, "svg": { "solid": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M396.6 6.5L235.8 129.1c9.6 1.8 18.9 5.8 27 12l168 128c13.2 10.1 22 24.9 24.5 41.4l6.2 41.5H608c9.3 0 18.2-4.1 24.2-11.1s8.8-16.4 7.4-25.6l-24-160c-1.2-8.2-5.6-15.7-12.3-20.7l-168-128c-11.5-8.7-27.3-8.7-38.8 0zm-153.2 160c-11.5-8.7-27.3-8.7-38.8 0l-168 128c-6.6 5-11 12.5-12.3 20.7l-24 160c-1.4 9.2 1.3 18.6 7.4 25.6S22.7 512 32 512H224V352l96 160h96c9.3 0 18.2-4.1 24.2-11.1s8.8-16.4 7.4-25.6l-24-160c-1.2-8.2-5.6-15.7-12.3-20.7l-168-128z" } }, "free": ["solid"] }, "terminal": { "aliases": { "unicodes": { "secondary": ["10f120"] } }, "changes": [ "3.1.0", "5.0.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "code", "coding", "command", "console", "development", "prompt", "terminal" ] }, "styles": ["solid"], "unicode": "f120", "label": "Terminal", "voted": false, "svg": { "solid": { "last_modified": 1684767552, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M9.4 86.6C-3.1 74.1-3.1 53.9 9.4 41.4s32.8-12.5 45.3 0l192 192c12.5 12.5 12.5 32.8 0 45.3l-192 192c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L178.7 256 9.4 86.6zM256 416H544c17.7 0 32 14.3 32 32s-14.3 32-32 32H256c-17.7 0-32-14.3-32-32s14.3-32 32-32z" } }, "free": ["solid"] }, "text-height": { "aliases": { "unicodes": { "secondary": ["10f034"] } }, "changes": [ "1.0.0", "5.0.0", "5.9.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["edit", "font", "format", "text", "type"] }, "styles": ["solid"], "unicode": "f034", "label": "Text Height", "voted": false, "svg": { "solid": { "last_modified": 1684767248, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M64 128V96h64l0 320H96c-17.7 0-32 14.3-32 32s14.3 32 32 32H224c17.7 0 32-14.3 32-32s-14.3-32-32-32H192l0-320h64v32c0 17.7 14.3 32 32 32s32-14.3 32-32V80c0-26.5-21.5-48-48-48H160 48C21.5 32 0 53.5 0 80v48c0 17.7 14.3 32 32 32s32-14.3 32-32zM502.6 41.4c-12.5-12.5-32.8-12.5-45.3 0l-64 64c-9.2 9.2-11.9 22.9-6.9 34.9s16.6 19.8 29.6 19.8h32V352H416c-12.9 0-24.6 7.8-29.6 19.8s-2.2 25.7 6.9 34.9l64 64c12.5 12.5 32.8 12.5 45.3 0l64-64c9.2-9.2 11.9-22.9 6.9-34.9s-16.6-19.8-29.6-19.8H512V160h32c12.9 0 24.6-7.8 29.6-19.8s2.2-25.7-6.9-34.9l-64-64z" } }, "free": ["solid"] }, "text-slash": { "aliases": { "names": ["remove-format"], "unicodes": { "secondary": ["10f87d"] } }, "changes": ["5.9.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["cancel", "font", "format", "remove", "style", "text"] }, "styles": ["solid"], "unicode": "f87d", "label": "Text Slash", "voted": false, "svg": { "solid": { "last_modified": 1684767246, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7L355.7 253.5 400.2 96H503L497 120.2c-4.3 17.1 6.1 34.5 23.3 38.8s34.5-6.1 38.8-23.3l11-44.1C577.6 61.3 554.7 32 523.5 32H376.1h-.3H204.5c-22 0-41.2 15-46.6 36.4l-6.3 25.2L38.8 5.1zm168 131.7c.1-.3 .2-.7 .3-1L217 96H333.7L301.3 210.8l-94.5-74.1zM243.3 416H192c-17.7 0-32 14.3-32 32s14.3 32 32 32H352c17.7 0 32-14.3 32-32s-14.3-32-32-32H309.8l17.6-62.1L272.9 311 243.3 416z" } }, "free": ["solid"] }, "text-width": { "aliases": { "unicodes": { "secondary": ["10f035"] } }, "changes": [ "1.0.0", "5.0.0", "5.9.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["edit", "font", "format", "text", "type"] }, "styles": ["solid"], "unicode": "f035", "label": "Text Width", "voted": false, "svg": { "solid": { "last_modified": 1684767246, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M64 128V96H192l0 128H176c-17.7 0-32 14.3-32 32s14.3 32 32 32h96c17.7 0 32-14.3 32-32s-14.3-32-32-32H256l0-128H384v32c0 17.7 14.3 32 32 32s32-14.3 32-32V80c0-26.5-21.5-48-48-48H224 48C21.5 32 0 53.5 0 80v48c0 17.7 14.3 32 32 32s32-14.3 32-32zM9.4 361.4c-12.5 12.5-12.5 32.8 0 45.3l64 64c9.2 9.2 22.9 11.9 34.9 6.9s19.8-16.6 19.8-29.6V416H320v32c0 12.9 7.8 24.6 19.8 29.6s25.7 2.2 34.9-6.9l64-64c12.5-12.5 12.5-32.8 0-45.3l-64-64c-9.2-9.2-22.9-11.9-34.9-6.9s-19.8 16.6-19.8 29.6v32H128V320c0-12.9-7.8-24.6-19.8-29.6s-25.7-2.2-34.9 6.9l-64 64z" } }, "free": ["solid"] }, "the-red-yeti": { "changes": ["5.3.0", "5.7.0", "5.8.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f69d", "label": "The Red Yeti", "voted": false, "svg": { "brands": { "last_modified": 1660014480, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M488.23 241.7l20.7 7.1c-9.6-23.9-23.9-37-31.7-44.8l7.1-18.2c.2 0 12.3-27.8-2.5-30.7-.6-11.3-6.6-27-18.4-27-7.6-10.6-17.7-12.3-30.7-5.9a122.2 122.2 0 0 0-25.3 16.5c-5.3-6.4-3 .4-3-29.8-37.1-24.3-45.4-11.7-74.8 3l.5.5a239.36 239.36 0 0 0-68.4-13.3c-5.5-8.7-18.6-19.1-25.1-25.1l24.8 7.1c-5.5-5.5-26.8-12.9-34.2-15.2 18.2-4.1 29.8-20.8 42.5-33-34.9-10.1-67.9-5.9-97.9 11.8l12-44.2L182 0c-31.6 24.2-33 41.9-33.7 45.5-.9-2.4-6.3-19.6-15.2-27a35.12 35.12 0 0 0-.5 25.3c3 8.4 5.9 14.8 8.4 18.9-16-3.3-28.3-4.9-49.2 0h-3.7l33 14.3a194.26 194.26 0 0 0-46.7 67.4l-1.7 8.4 1.7 1.7 7.6-4.7c-3.3 11.6-5.3 19.4-6.6 25.8a200.18 200.18 0 0 0-27.8 40.3c-15 1-31.8 10.8-40.3 14.3l3 3.4 28.8 1c-.5 1-.7 2.2-1.2 3.2-7.3 6.4-39.8 37.7-33 80.7l20.2-22.4c.5 1.7.7 3.4 1.2 5.2 0 25.5.4 89.6 64.9 150.5 43.6 40 96 60.2 157.5 60.2 121.7 0 223-87.3 223-211.5 6.8-9.7-1.2 3 16.7-25.1l13 14.3 2.5-.5A181.84 181.84 0 0 0 495 255a44.74 44.74 0 0 0-6.8-13.3zM398 111.2l-.5 21.9c5.5 18.1 16.9 17.2 22.4 17.2l-3.4-4.7 22.4-5.4a242.44 242.44 0 0 1-27 0c12.8-2.1 33.3-29 43-11.3 3.4 7.6 6.4 17.2 9.3 27.8l1.7-5.9a56.38 56.38 0 0 1-1.7-15.2c5.4.5 8.8 3.4 9.3 10.1.5 6.4 1.7 14.8 3.4 25.3l4.7-11.3c4.6 0 4.5-3.6-2.5 20.7-20.9-8.7-35.1-8.4-46.5-8.4l18.2-16c-25.3 8.2-33 10.8-54.8 20.9-1.1-5.4-5-13.5-16-19.9-3.2 3.8-2.8.9-.7 14.8h-2.5a62.32 62.32 0 0 0-8.4-23.1l4.2-3.4c8.4-7.1 11.8-14.3 10.6-21.9-.5-6.4-5.4-13.5-13.5-20.7 5.6-3.4 15.2-.4 28.3 8.5zm-39.6-10.1c2.7 1.9 11.4 5.4 18.9 17.2 4.2 8.4 4 9.8 3.4 11.1-.5 2.4-.5 4.3-3 7.1-1.7 2.5-5.4 4.7-11.8 7.6-7.6-13-16.5-23.6-27.8-31.2zM91 143.1l1.2-1.7c1.2-2.9 4.2-7.6 9.3-15.2l2.5-3.4-13 12.3 5.4-4.7-10.1 9.3-4.2 1.2c12.3-24.1 23.1-41.3 32.5-50.2 9.3-9.3 16-16 20.2-19.4l-6.4 1.2c-11.3-4.2-19.4-7.1-24.8-8.4 2.5-.5 3.7-.5 3.2-.5 10.3 0 17.5.5 20.9 1.2a52.35 52.35 0 0 0 16 2.5l.5-1.7-8.4-35.8 13.5 29a42.89 42.89 0 0 0 5.9-14.3c1.7-6.4 5.4-13 10.1-19.4s7.6-10.6 9.3-11.3a234.68 234.68 0 0 0-6.4 25.3l-1.7 7.1-.5 4.7 2.5 2.5C190.4 39.9 214 34 239.8 34.5l21.1.5c-11.8 13.5-27.8 21.9-48.5 24.8a201.26 201.26 0 0 1-23.4 2.9l-.2-.5-2.5-1.2a20.75 20.75 0 0 0-14 2c-2.5-.2-4.9-.5-7.1-.7l-2.5 1.7.5 1.2c2 .2 3.9.5 6.2.7l-2 3.4 3.4-.5-10.6 11.3c-4.2 3-5.4 6.4-4.2 9.3l5.4-3.4h1.2a39.4 39.4 0 0 1 25.3-15.2v-3c6.4.5 13 1 19.4 1.2 6.4 0 8.4.5 5.4 1.2a189.6 189.6 0 0 1 20.7 13.5c13.5 10.1 23.6 21.9 30 35.4 8.8 18.2 13.5 37.1 13.5 56.6a141.13 141.13 0 0 1-3 28.3 209.91 209.91 0 0 1-16 46l2.5.5c18.2-19.7 41.9-16 49.2-16l-6.4 5.9 22.4 17.7-1.7 30.7c-5.4-12.3-16.5-21.1-33-27.8 16.5 14.8 23.6 21.1 21.9 20.2-4.8-2.8-3.5-1.9-10.8-3.7 4.1 4.1 17.5 18.8 18.2 20.7l.2.2-.2.2c0 1.8 1.6-1.2-14 22.9-75.2-15.3-106.27-42.7-141.2-63.2l11.8 1.2c-11.8-18.5-15.6-17.7-38.4-26.1L149 225c-8.8-3-18.2-3-28.3.5l7.6-10.6-1.2-1.7c-14.9 4.3-19.8 9.2-22.6 11.3-1.1-5.5-2.8-12.4-12.3-28.8l-1.2 27-13.2-5c1.5-25.2 5.4-50.5 13.2-74.6zm276.5 330c-49.9 25-56.1 22.4-59 23.9-29.8-11.8-50.9-31.7-63.5-58.8l30 16.5c-9.8-9.3-18.3-16.5-38.4-44.3l11.8 23.1-17.7-7.6c14.2 21.1 23.5 51.7 66.6 73.5-120.8 24.2-199-72.1-200.9-74.3a262.57 262.57 0 0 0 35.4 24.8c3.4 1.7 7.1 2.5 10.1 1.2l-16-20.7c9.2 4.2 9.5 4.5 69.1 29-42.5-20.7-73.8-40.8-93.2-60.2-.5 6.4-1.2 10.1-1.2 10.1a80.25 80.25 0 0 1 20.7 26.6c-39-18.9-57.6-47.6-71.3-82.6 49.9 55.1 118.9 37.5 120.5 37.1 34.8 16.4 69.9 23.6 113.9 10.6 3.3 0 20.3 17 25.3 39.1l4.2-3-2.5-23.6c9 9 24.9 22.6 34.4 13-15.6-5.3-23.5-9.5-29.5-31.7 4.6 4.2 7.6 9 27.8 15l1.2-1.2-10.5-14.2c11.7-4.8-3.5 1 32-10.8 4.3 34.3 9 49.2.7 89.5zm115.3-214.4l-2.5.5 3 9.3c-3.5 5.9-23.7 44.3-71.6 79.7-39.5 29.8-76.6 39.1-80.9 40.3l-7.6-7.1-1.2 3 14.3 16-7.1-4.7 3.4 4.2h-1.2l-21.9-13.5 9.3 26.6-19-27.9-1.2 2.5 7.6 29c-6.1-8.2-21-32.6-56.8-39.6l32.5 21.2a214.82 214.82 0 0 1-93.2-6.4c-4.2-1.2-8.9-2.5-13.5-4.2l1.2-3-44.8-22.4 26.1 22.4c-57.7 9.1-113-25.4-126.4-83.4l-2.5-16.4-22.27 22.3c19.5-57.5 25.6-57.9 51.4-70.1-9.1-5.3-1.6-3.3-38.4-9.3 15.8-5.8 33-15.4 73 5.2a18.5 18.5 0 0 1 3.7-1.7c.6-3.2.4-.8 1-11.8 3.9 10 3.6 8.7 3 9.3l1.7.5c12.7-6.5 8.9-4.5 17-8.9l-5.4 13.5 22.3-5.8-8.4 8.4 2.5 2.5c4.5-1.8 30.3 3.4 40.8 16l-23.6-2.5c39.4 23 51.5 54 55.8 69.6l1.7-1.2c-2.8-22.3-12.4-33.9-16-40.1 4.2 5 39.2 34.6 110.4 46-11.3-.5-23.1 5.4-34.9 18.9l46.7-20.2-9.3 21.9c7.6-10.1 14.8-23.6 21.2-39.6v-.5l1.2-3-1.2 16c13.5-41.8 25.3-78.5 35.4-109.7l13.5-27.8v-2l-5.4-4.2h10.1l5.9 4.2 2.5-1.2-3.4-16 12.3 18.9 41.8-20.2-14.8 13 .5 2.9 17.7-.5a184 184 0 0 1 33 4.2l-23.6 2.5-1.2 3 26.6 23.1a254.21 254.21 0 0 1 27 32c-11.2-3.3-10.3-3.4-21.2-3.4l12.3 32.5zm-6.1-71.3l-3.9 13-14.3-11.8zm-254.8 7.1c1.7 10.6 4.7 17.7 8.8 21.9-9.3 6.6-27.5 13.9-46.5 16l.5 1.2a50.22 50.22 0 0 0 24.8-2.5l-7.1 13c4.2-1.7 10.1-7.1 17.7-14.8 11.9-5.5 12.7-5.1 20.2-16-12.7-6.4-15.7-13.7-18.4-18.8zm3.7-102.3c-6.4-3.4-10.6 3-12.3 18.9s2.5 29.5 11.8 39.6 18.2 10.6 26.1 3 3.4-23.6-11.3-47.7a39.57 39.57 0 0 0-14.27-13.8zm-4.7 46.3c5.4 2.2 10.5 1.9 12.3-10.6v-4.7l-1.2.5c-4.3-3.1-2.5-4.5-1.7-6.2l.5-.5c-.9-1.2-5-8.1-12.5 4.7-.5-13.5.5-21.9 3-24.8 1.2-2.5 4.7-1.2 11.3 4.2 6.4 5.4 11.3 16 15.2 32.5 6.5 28-19.8 26.2-26.9 4.9zm-45-5.5c1.6.3 9.3-1.1 9.3-14.8h-.5c-5.4-1.1-2.2-5.5-.7-5.9-1.7-3-3.4-4.2-5.4-4.7-8.1 0-11.6 12.7-8.1 21.2a7.51 7.51 0 0 0 5.43 4.2zM216 82.9l-2.5.5.5 3a48.94 48.94 0 0 1 26.1 5.9c-2.5-5.5-10-14.3-28.3-14.3l.5 2.5zm-71.8 49.4c21.7 16.8 16.5 21.4 46.5 23.6l-2.9-4.7a42.67 42.67 0 0 0 14.8-28.3c1.7-16-1.2-29.5-8.8-41.3l13-7.6a2.26 2.26 0 0 0-.5-1.7 14.21 14.21 0 0 0-13.5 1.7c-12.7 6.7-28 20.9-29 22.4-1.7 1.7-3.4 5.9-5.4 13.5a99.61 99.61 0 0 0-2.9 23.6c-4.7-8-10.5-6.4-19.9-5.9l7.1 7.6c-16.5 0-23.3 15.4-23.6 16 6.8 0 4.6-7.6 30-12.3-4.3-6.3-3.3-5-4.9-6.6zm18.7-18.7c1.2-7.6 3.4-13 6.4-17.2 5.4-6.4 10.6-10.1 16-11.8 4.2-1.7 7.1 1.2 10.1 9.3a72.14 72.14 0 0 1 3 25.3c-.5 9.3-3.4 17.2-8.4 23.1-2.9 3.4-5.4 5.9-6.4 7.6a39.21 39.21 0 0 1-11.3-.5l-7.1-3.4-5.4-6.4c.8-10 1.3-18.8 3.1-26zm42 56.1c-34.8 14.4-34.7 14-36.1 14.3-20.8 4.7-19-24.4-18.9-24.8l5.9-1.2-.5-2.5c-20.2-2.6-31 4.2-32.5 4.9.5.5 3 3.4 5.9 9.3 4.2-6.4 8.8-10.1 15.2-10.6a83.47 83.47 0 0 0 1.7 33.7c.1.5 2.6 17.4 27.5 24.1 11.3 3 27 1.2 48.9-5.4l-9.2.5c-4.2-14.8-6.4-24.8-5.9-29.5 11.3-8.8 21.9-11.3 30.7-7.6h2.5l-11.8-7.6-7.1.5c-5.9 1.2-12.3 4.2-19.4 8.4z" } }, "free": ["brands"] }, "themeco": { "changes": ["5.1.0", "5.8.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f5c6", "label": "Themeco", "voted": false, "svg": { "brands": { "last_modified": 1660014462, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M202.9 8.43c9.9-5.73 26-5.82 35.95-.21L430 115.85c10 5.6 18 19.44 18 30.86V364c0 11.44-8.06 25.29-18 31L238.81 503.74c-9.93 5.66-26 5.57-35.85-.21L17.86 395.12C8 389.34 0 375.38 0 364V146.71c0-11.44 8-25.36 17.91-31.08zm-77.4 199.83c-15.94 0-31.89.14-47.83.14v101.45H96.8V280h28.7c49.71 0 49.56-71.74 0-71.74zm140.14 100.29l-30.73-34.64c37-7.51 34.8-65.23-10.87-65.51-16.09 0-32.17-.14-48.26-.14v101.59h19.13v-33.91h18.41l29.56 33.91h22.76zm-41.59-82.32c23.34 0 23.26 32.46 0 32.46h-29.13v-32.46zm-95.56-1.6c21.18 0 21.11 38.85 0 38.85H96.18v-38.84zm192.65-18.25c-68.46 0-71 105.8 0 105.8 69.48-.01 69.41-105.8 0-105.8zm0 17.39c44.12 0 44.8 70.86 0 70.86s-44.43-70.86 0-70.86z" } }, "free": ["brands"] }, "themeisle": { "changes": ["4.6.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f2b2", "label": "ThemeIsle", "voted": false, "svg": { "brands": { "last_modified": 1660014472, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M208 88.286c0-10 6.286-21.714 17.715-21.714 11.142 0 17.714 11.714 17.714 21.714 0 10.285-6.572 21.714-17.714 21.714C214.286 110 208 98.571 208 88.286zm304 160c0 36.001-11.429 102.286-36.286 129.714-22.858 24.858-87.428 61.143-120.857 70.572l-1.143.286v32.571c0 16.286-12.572 30.571-29.143 30.571-10 0-19.429-5.714-24.572-14.286-5.427 8.572-14.856 14.286-24.856 14.286-10 0-19.429-5.714-24.858-14.286-5.142 8.572-14.571 14.286-24.57 14.286-10.286 0-19.429-5.714-24.858-14.286-5.143 8.572-14.571 14.286-24.571 14.286-18.857 0-29.429-15.714-29.429-32.857-16.286 12.285-35.715 19.428-56.571 19.428-22 0-43.429-8.285-60.286-22.857 10.285-.286 20.571-2.286 30.285-5.714-20.857-5.714-39.428-18.857-52-36.286 21.37 4.645 46.209 1.673 67.143-11.143-22-22-56.571-58.857-68.572-87.428C1.143 321.714 0 303.714 0 289.429c0-49.714 20.286-160 86.286-160 10.571 0 18.857 4.858 23.143 14.857a158.792 158.792 0 0 1 12-15.428c2-2.572 5.714-5.429 7.143-8.286 7.999-12.571 11.714-21.142 21.714-34C182.571 45.428 232 17.143 285.143 17.143c6 0 12 .285 17.714 1.143C313.714 6.571 328.857 0 344.572 0c14.571 0 29.714 6 40 16.286.857.858 1.428 2.286 1.428 3.428 0 3.714-10.285 13.429-12.857 16.286 4.286 1.429 15.714 6.858 15.714 12 0 2.857-2.857 5.143-4.571 7.143 31.429 27.714 49.429 67.143 56.286 108 4.286-5.143 10.285-8.572 17.143-8.572 10.571 0 20.857 7.144 28.571 14.001C507.143 187.143 512 221.714 512 248.286zM188 89.428c0 18.286 12.571 37.143 32.286 37.143 19.714 0 32.285-18.857 32.285-37.143 0-18-12.571-36.857-32.285-36.857-19.715 0-32.286 18.858-32.286 36.857zM237.714 194c0-19.714 3.714-39.143 8.571-58.286-52.039 79.534-13.531 184.571 68.858 184.571 21.428 0 42.571-7.714 60-20 2-7.429 3.714-14.857 3.714-22.572 0-14.286-6.286-21.428-20.572-21.428-4.571 0-9.143.857-13.429 1.714-63.343 12.668-107.142 3.669-107.142-63.999zm-41.142 254.858c0-11.143-8.858-20.857-20.286-20.857-11.429 0-20 9.715-20 20.857v32.571c0 11.143 8.571 21.142 20 21.142 11.428 0 20.286-9.715 20.286-21.142v-32.571zm49.143 0c0-11.143-8.572-20.857-20-20.857-11.429 0-20.286 9.715-20.286 20.857v32.571c0 11.143 8.857 21.142 20.286 21.142 11.428 0 20-10 20-21.142v-32.571zm49.713 0c0-11.143-8.857-20.857-20.285-20.857-11.429 0-20.286 9.715-20.286 20.857v32.571c0 11.143 8.857 21.142 20.286 21.142 11.428 0 20.285-9.715 20.285-21.142v-32.571zm49.715 0c0-11.143-8.857-20.857-20.286-20.857-11.428 0-20.286 9.715-20.286 20.857v32.571c0 11.143 8.858 21.142 20.286 21.142 11.429 0 20.286-10 20.286-21.142v-32.571zM421.714 286c-30.857 59.142-90.285 102.572-158.571 102.572-96.571 0-160.571-84.572-160.571-176.572 0-16.857 2-33.429 6-49.714-20 33.715-29.714 72.572-29.714 111.429 0 60.286 24.857 121.715 71.429 160.857 5.143-9.714 14.857-16.286 26-16.286 10 0 19.428 5.714 24.571 14.286 5.429-8.571 14.571-14.286 24.858-14.286 10 0 19.428 5.714 24.571 14.286 5.429-8.571 14.857-14.286 24.858-14.286 10 0 19.428 5.714 24.857 14.286 5.143-8.571 14.571-14.286 24.572-14.286 10.857 0 20.857 6.572 25.714 16 43.427-36.286 68.569-92 71.426-148.286zm10.572-99.714c0-53.714-34.571-105.714-92.572-105.714-30.285 0-58.571 15.143-78.857 36.857C240.862 183.812 233.41 254 302.286 254c28.805 0 97.357-28.538 84.286 36.857 28.857-26 45.714-65.714 45.714-104.571z" } }, "free": ["brands"] }, "thermometer": { "aliases": { "unicodes": { "secondary": ["10f491"] } }, "changes": ["5.0.7", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["covid-19", "mercury", "status", "temperature"] }, "styles": ["solid"], "unicode": "f491", "label": "Thermometer", "voted": false, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M96 382.1V293.3c0-14.9 5.9-29.1 16.4-39.6l27.3-27.3 57 57c6.2 6.2 16.4 6.2 22.6 0s6.2-16.4 0-22.6l-57-57 41.4-41.4 57 57c6.2 6.2 16.4 6.2 22.6 0s6.2-16.4 0-22.6l-57-57 41.4-41.4 57 57c6.2 6.2 16.4 6.2 22.6 0s6.2-16.4 0-22.6l-57-57 45.5-45.5C355.2 10.9 381.4 0 408.8 0C465.8 0 512 46.2 512 103.2c0 27.4-10.9 53.6-30.2 73L258.3 399.6c-10.5 10.5-24.7 16.4-39.6 16.4H129.9L41 505c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l89-89z" } }, "free": ["solid"] }, "think-peaks": { "changes": ["5.4.2", "5.8.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f731", "label": "Think Peaks", "voted": false, "svg": { "brands": { "last_modified": 1660014468, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M465.4 409.4l87.1-150.2-32-.3-55.1 95L259.2 0 23 407.4l32 .3L259.2 55.6zm-355.3-44.1h32.1l117.4-202.5L463 511.9l32.5.1-235.8-404.6z" } }, "free": ["brands"] }, "threads": { "changes": ["6.4.1", "6.4.2"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e618", "label": "Threads", "voted": false, "svg": { "brands": { "last_modified": 1690904784, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M331.5 235.7c2.2 .9 4.2 1.9 6.3 2.8c29.2 14.1 50.6 35.2 61.8 61.4c15.7 36.5 17.2 95.8-30.3 143.2c-36.2 36.2-80.3 52.5-142.6 53h-.3c-70.2-.5-124.1-24.1-160.4-70.2c-32.3-41-48.9-98.1-49.5-169.6V256v-.2C17 184.3 33.6 127.2 65.9 86.2C102.2 40.1 156.2 16.5 226.4 16h.3c70.3 .5 124.9 24 162.3 69.9c18.4 22.7 32 50 40.6 81.7l-40.4 10.8c-7.1-25.8-17.8-47.8-32.2-65.4c-29.2-35.8-73-54.2-130.5-54.6c-57 .5-100.1 18.8-128.2 54.4C72.1 146.1 58.5 194.3 58 256c.5 61.7 14.1 109.9 40.3 143.3c28 35.6 71.2 53.9 128.2 54.4c51.4-.4 85.4-12.6 113.7-40.9c32.3-32.2 31.7-71.8 21.4-95.9c-6.1-14.2-17.1-26-31.9-34.9c-3.7 26.9-11.8 48.3-24.7 64.8c-17.1 21.8-41.4 33.6-72.7 35.3c-23.6 1.3-46.3-4.4-63.9-16c-20.8-13.8-33-34.8-34.3-59.3c-2.5-48.3 35.7-83 95.2-86.4c21.1-1.2 40.9-.3 59.2 2.8c-2.4-14.8-7.3-26.6-14.6-35.2c-10-11.7-25.6-17.7-46.2-17.8H227c-16.6 0-39 4.6-53.3 26.3l-34.4-23.6c19.2-29.1 50.3-45.1 87.8-45.1h.8c62.6 .4 99.9 39.5 103.7 107.7l-.2 .2zm-156 68.8c1.3 25.1 28.4 36.8 54.6 35.3c25.6-1.4 54.6-11.4 59.5-73.2c-13.2-2.9-27.8-4.4-43.4-4.4c-4.8 0-9.6 .1-14.4 .4c-42.9 2.4-57.2 23.2-56.2 41.8l-.1 .1z" } }, "free": ["brands"] }, "thumbs-down": { "aliases": { "unicodes": { "composite": ["1f44e", "f088"], "secondary": ["10f165"] } }, "changes": [ "3.2.0", "5.0.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "-1", "disagree", "disapprove", "dislike", "down", "hand", "social", "thumb", "thumbs down", "thumbs-o-down" ] }, "styles": ["solid", "regular"], "unicode": "f165", "label": "Thumbs Down", "voted": false, "svg": { "solid": { "last_modified": 1684766193, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M313.4 479.1c26-5.2 42.9-30.5 37.7-56.5l-2.3-11.4c-5.3-26.7-15.1-52.1-28.8-75.2H464c26.5 0 48-21.5 48-48c0-18.5-10.5-34.6-25.9-42.6C497 236.6 504 223.1 504 208c0-23.4-16.8-42.9-38.9-47.1c4.4-7.3 6.9-15.8 6.9-24.9c0-21.3-13.9-39.4-33.1-45.6c.7-3.3 1.1-6.8 1.1-10.4c0-26.5-21.5-48-48-48H294.5c-19 0-37.5 5.6-53.3 16.1L202.7 73.8C176 91.6 160 121.6 160 153.7V192v48 24.9c0 29.2 13.3 56.7 36 75l7.4 5.9c26.5 21.2 44.6 51 51.2 84.2l2.3 11.4c5.2 26 30.5 42.9 56.5 37.7zM32 384H96c17.7 0 32-14.3 32-32V128c0-17.7-14.3-32-32-32H32C14.3 96 0 110.3 0 128V352c0 17.7 14.3 32 32 32z" }, "regular": { "last_modified": 1684766193, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M323.8 477.2c-38.2 10.9-78.1-11.2-89-49.4l-5.7-20c-3.7-13-10.4-25-19.5-35l-51.3-56.4c-8.9-9.8-8.2-25 1.6-33.9s25-8.2 33.9 1.6l51.3 56.4c14.1 15.5 24.4 34 30.1 54.1l5.7 20c3.6 12.7 16.9 20.1 29.7 16.5s20.1-16.9 16.5-29.7l-5.7-20c-5.7-19.9-14.7-38.7-26.6-55.5c-5.2-7.3-5.8-16.9-1.7-24.9s12.3-13 21.3-13L448 288c8.8 0 16-7.2 16-16c0-6.8-4.3-12.7-10.4-15c-7.4-2.8-13-9-14.9-16.7s.1-15.8 5.3-21.7c2.5-2.8 4-6.5 4-10.6c0-7.8-5.6-14.3-13-15.7c-8.2-1.6-15.1-7.3-18-15.2s-1.6-16.7 3.6-23.3c2.1-2.7 3.4-6.1 3.4-9.9c0-6.7-4.2-12.6-10.2-14.9c-11.5-4.5-17.7-16.9-14.4-28.8c.4-1.3 .6-2.8 .6-4.3c0-8.8-7.2-16-16-16H286.5c-12.6 0-25 3.7-35.5 10.7l-61.7 41.1c-11 7.4-25.9 4.4-33.3-6.7s-4.4-25.9 6.7-33.3l61.7-41.1c18.4-12.3 40-18.8 62.1-18.8H384c34.7 0 62.9 27.6 64 62c14.6 11.7 24 29.7 24 50c0 4.5-.5 8.8-1.3 13c15.4 11.7 25.3 30.2 25.3 51c0 6.5-1 12.8-2.8 18.7C504.8 238.3 512 254.3 512 272c0 35.3-28.6 64-64 64l-92.3 0c4.7 10.4 8.7 21.2 11.8 32.2l5.7 20c10.9 38.2-11.2 78.1-49.4 89zM32 384c-17.7 0-32-14.3-32-32V128c0-17.7 14.3-32 32-32H96c17.7 0 32 14.3 32 32V352c0 17.7-14.3 32-32 32H32z" } }, "free": ["regular", "solid"] }, "thumbs-up": { "aliases": { "unicodes": { "composite": ["1f44d", "f087"], "secondary": ["10f164"] } }, "changes": [ "3.2.0", "5.0.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "+1", "agree", "approve", "favorite", "hand", "like", "ok", "okay", "social", "success", "thumb", "thumbs up", "thumbs-o-up", "up", "yes", "you got it dude" ] }, "styles": ["solid", "regular"], "unicode": "f164", "label": "Thumbs Up", "voted": false, "svg": { "solid": { "last_modified": 1684766193, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M313.4 32.9c26 5.2 42.9 30.5 37.7 56.5l-2.3 11.4c-5.3 26.7-15.1 52.1-28.8 75.2H464c26.5 0 48 21.5 48 48c0 18.5-10.5 34.6-25.9 42.6C497 275.4 504 288.9 504 304c0 23.4-16.8 42.9-38.9 47.1c4.4 7.3 6.9 15.8 6.9 24.9c0 21.3-13.9 39.4-33.1 45.6c.7 3.3 1.1 6.8 1.1 10.4c0 26.5-21.5 48-48 48H294.5c-19 0-37.5-5.6-53.3-16.1l-38.5-25.7C176 420.4 160 390.4 160 358.3V320 272 247.1c0-29.2 13.3-56.7 36-75l7.4-5.9c26.5-21.2 44.6-51 51.2-84.2l2.3-11.4c5.2-26 30.5-42.9 56.5-37.7zM32 192H96c17.7 0 32 14.3 32 32V448c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32V224c0-17.7 14.3-32 32-32z" }, "regular": { "last_modified": 1684766193, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M323.8 34.8c-38.2-10.9-78.1 11.2-89 49.4l-5.7 20c-3.7 13-10.4 25-19.5 35l-51.3 56.4c-8.9 9.8-8.2 25 1.6 33.9s25 8.2 33.9-1.6l51.3-56.4c14.1-15.5 24.4-34 30.1-54.1l5.7-20c3.6-12.7 16.9-20.1 29.7-16.5s20.1 16.9 16.5 29.7l-5.7 20c-5.7 19.9-14.7 38.7-26.6 55.5c-5.2 7.3-5.8 16.9-1.7 24.9s12.3 13 21.3 13L448 224c8.8 0 16 7.2 16 16c0 6.8-4.3 12.7-10.4 15c-7.4 2.8-13 9-14.9 16.7s.1 15.8 5.3 21.7c2.5 2.8 4 6.5 4 10.6c0 7.8-5.6 14.3-13 15.7c-8.2 1.6-15.1 7.3-18 15.1s-1.6 16.7 3.6 23.3c2.1 2.7 3.4 6.1 3.4 9.9c0 6.7-4.2 12.6-10.2 14.9c-11.5 4.5-17.7 16.9-14.4 28.8c.4 1.3 .6 2.8 .6 4.3c0 8.8-7.2 16-16 16H286.5c-12.6 0-25-3.7-35.5-10.7l-61.7-41.1c-11-7.4-25.9-4.4-33.3 6.7s-4.4 25.9 6.7 33.3l61.7 41.1c18.4 12.3 40 18.8 62.1 18.8H384c34.7 0 62.9-27.6 64-62c14.6-11.7 24-29.7 24-50c0-4.5-.5-8.8-1.3-13c15.4-11.7 25.3-30.2 25.3-51c0-6.5-1-12.8-2.8-18.7C504.8 273.7 512 257.7 512 240c0-35.3-28.6-64-64-64l-92.3 0c4.7-10.4 8.7-21.2 11.8-32.2l5.7-20c10.9-38.2-11.2-78.1-49.4-89zM32 192c-17.7 0-32 14.3-32 32V448c0 17.7 14.3 32 32 32H96c17.7 0 32-14.3 32-32V224c0-17.7-14.3-32-32-32H32z" } }, "free": ["regular", "solid"] }, "thumbtack": { "aliases": { "names": ["thumb-tack"], "unicodes": { "composite": ["1f4cc", "1f588"], "secondary": ["10f08d"] } }, "changes": [ "1.0.0", "5.0.0", "5.10.2", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Black Pushpin", "coordinates", "location", "marker", "pin", "pushpin", "thumb-tack" ] }, "styles": ["solid"], "unicode": "f08d", "label": "Thumbtack", "voted": false, "svg": { "solid": { "last_modified": 1684767366, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M32 32C32 14.3 46.3 0 64 0H320c17.7 0 32 14.3 32 32s-14.3 32-32 32H290.5l11.4 148.2c36.7 19.9 65.7 53.2 79.5 94.7l1 3c3.3 9.8 1.6 20.5-4.4 28.8s-15.7 13.3-26 13.3H32c-10.3 0-19.9-4.9-26-13.3s-7.7-19.1-4.4-28.8l1-3c13.8-41.5 42.8-74.8 79.5-94.7L93.5 64H64C46.3 64 32 49.7 32 32zM160 384h64v96c0 17.7-14.3 32-32 32s-32-14.3-32-32V384z" } }, "free": ["solid"] }, "ticket": { "aliases": { "unicodes": { "composite": ["1f39f"], "secondary": ["10f145"] } }, "changes": [ "3.1.0", "5.0.0", "5.10.1", "5.10.2", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "admission", "admission tickets", "movie", "pass", "support", "ticket" ] }, "styles": ["solid"], "unicode": "f145", "label": "Ticket", "voted": false, "svg": { "solid": { "last_modified": 1684766475, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M64 64C28.7 64 0 92.7 0 128v64c0 8.8 7.4 15.7 15.7 18.6C34.5 217.1 48 235 48 256s-13.5 38.9-32.3 45.4C7.4 304.3 0 311.2 0 320v64c0 35.3 28.7 64 64 64H512c35.3 0 64-28.7 64-64V320c0-8.8-7.4-15.7-15.7-18.6C541.5 294.9 528 277 528 256s13.5-38.9 32.3-45.4c8.3-2.9 15.7-9.8 15.7-18.6V128c0-35.3-28.7-64-64-64H64zm64 112l0 160c0 8.8 7.2 16 16 16H432c8.8 0 16-7.2 16-16V176c0-8.8-7.2-16-16-16H144c-8.8 0-16 7.2-16 16zM96 160c0-17.7 14.3-32 32-32H448c17.7 0 32 14.3 32 32V352c0 17.7-14.3 32-32 32H128c-17.7 0-32-14.3-32-32V160z" } }, "free": ["solid"] }, "ticket-simple": { "aliases": { "names": ["ticket-alt"], "unicodes": { "secondary": ["10f3ff"] } }, "changes": [ "5.0.0", "5.10.2", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0", "6.4.1" ], "ligatures": [], "search": { "terms": ["movie", "pass", "support", "ticket"] }, "styles": ["solid"], "unicode": "f3ff", "label": "Ticket Simple", "voted": false, "svg": { "solid": { "last_modified": 1684766474, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M0 128C0 92.7 28.7 64 64 64H512c35.3 0 64 28.7 64 64v64c0 8.8-7.4 15.7-15.7 18.6C541.5 217.1 528 235 528 256s13.5 38.9 32.3 45.4c8.3 2.9 15.7 9.8 15.7 18.6v64c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V320c0-8.8 7.4-15.7 15.7-18.6C34.5 294.9 48 277 48 256s-13.5-38.9-32.3-45.4C7.4 207.7 0 200.8 0 192V128z" } }, "free": ["solid"] }, "tiktok": { "changes": ["5.13.1", "5.14.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e07b", "label": "TikTok", "voted": true, "svg": { "brands": { "last_modified": 1660014467, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M448,209.91a210.06,210.06,0,0,1-122.77-39.25V349.38A162.55,162.55,0,1,1,185,188.31V278.2a74.62,74.62,0,1,0,52.23,71.18V0l88,0a121.18,121.18,0,0,0,1.86,22.17h0A122.18,122.18,0,0,0,381,102.39a121.43,121.43,0,0,0,67,20.14Z" } }, "free": ["brands"] }, "timeline": { "changes": ["6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["chronological", "deadline", "history", "linear"] }, "styles": ["solid"], "unicode": "e29c", "label": "Timeline", "voted": true, "svg": { "solid": { "last_modified": 1684767206, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M128 72a24 24 0 1 1 0 48 24 24 0 1 1 0-48zm32 97.3c28.3-12.3 48-40.5 48-73.3c0-44.2-35.8-80-80-80S48 51.8 48 96c0 32.8 19.7 61 48 73.3V224H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H288v54.7c-28.3 12.3-48 40.5-48 73.3c0 44.2 35.8 80 80 80s80-35.8 80-80c0-32.8-19.7-61-48-73.3V288H608c17.7 0 32-14.3 32-32s-14.3-32-32-32H544V169.3c28.3-12.3 48-40.5 48-73.3c0-44.2-35.8-80-80-80s-80 35.8-80 80c0 32.8 19.7 61 48 73.3V224H160V169.3zM488 96a24 24 0 1 1 48 0 24 24 0 1 1 -48 0zM320 392a24 24 0 1 1 0 48 24 24 0 1 1 0-48z" } }, "free": ["solid"] }, "toggle-off": { "aliases": { "unicodes": { "secondary": ["10f204"] } }, "changes": [ "4.2.0", "5.0.0", "6.0.0-beta1", "6.0.0", "6.1.2", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["button", "off", "on", "switch"] }, "styles": ["solid"], "unicode": "f204", "label": "Toggle Off", "voted": false, "svg": { "solid": { "last_modified": 1684767368, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M384 128c70.7 0 128 57.3 128 128s-57.3 128-128 128H192c-70.7 0-128-57.3-128-128s57.3-128 128-128H384zM576 256c0-106-86-192-192-192H192C86 64 0 150 0 256S86 448 192 448H384c106 0 192-86 192-192zM192 352a96 96 0 1 0 0-192 96 96 0 1 0 0 192z" } }, "free": ["solid"] }, "toggle-on": { "aliases": { "unicodes": { "secondary": ["10f205"] } }, "changes": [ "4.2.0", "5.0.0", "6.0.0-beta1", "6.0.0", "6.1.2", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["button", "off", "on", "switch"] }, "styles": ["solid"], "unicode": "f205", "label": "Toggle On", "voted": false, "svg": { "solid": { "last_modified": 1684767368, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M192 64C86 64 0 150 0 256S86 448 192 448H384c106 0 192-86 192-192s-86-192-192-192H192zm192 96a96 96 0 1 1 0 192 96 96 0 1 1 0-192z" } }, "free": ["solid"] }, "toilet": { "aliases": { "unicodes": { "composite": ["1f6bd"], "secondary": ["10f7d8"] } }, "changes": ["5.6.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "bathroom", "flush", "john", "loo", "pee", "plumbing", "poop", "porcelain", "potty", "restroom", "throne", "toile", "toilet", "washroom", "waste", "wc" ] }, "styles": ["solid"], "unicode": "f7d8", "label": "Toilet", "voted": true, "svg": { "solid": { "last_modified": 1684767442, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M24 0C10.7 0 0 10.7 0 24S10.7 48 24 48h8V196.9c-1.9 1.4-3.8 2.9-5.6 4.4C10.9 214.5 0 232.9 0 256c0 46.9 14.3 84.1 37 112.5c14.2 17.7 31.1 31.3 48.5 41.8L65.6 469.9c-3.3 9.8-1.6 20.5 4.4 28.8s15.7 13.3 26 13.3H352c10.3 0 19.9-4.9 26-13.3s7.7-19.1 4.4-28.8l-19.8-59.5c17.4-10.5 34.3-24.1 48.5-41.8c22.7-28.4 37-65.5 37-112.5c0-23.1-10.9-41.5-26.4-54.6c-1.8-1.5-3.7-3-5.6-4.4V48h8c13.3 0 24-10.7 24-24s-10.7-24-24-24H24zM384 256.3c0 1-.3 2.6-3.8 5.6c-4.8 4.1-14 9-29.3 13.4C320.5 284 276.1 288 224 288s-96.5-4-126.9-12.8c-15.3-4.4-24.5-9.3-29.3-13.4c-3.5-3-3.8-4.6-3.8-5.6l0-.3 0-.1c0-1 0-2.5 3.8-5.8c4.8-4.1 14-9 29.3-13.4C127.5 228 171.9 224 224 224s96.5 4 126.9 12.8c15.3 4.4 24.5 9.3 29.3 13.4c3.8 3.2 3.8 4.8 3.8 5.8l0 .1 0 .3zM328.2 384l-.2 .5 0-.5h.2zM112 64h32c8.8 0 16 7.2 16 16s-7.2 16-16 16H112c-8.8 0-16-7.2-16-16s7.2-16 16-16z" } }, "free": ["solid"] }, "toilet-paper": { "aliases": { "unicodes": { "composite": ["1f9fb"], "secondary": ["10f71e"] } }, "changes": ["5.4.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "bathroom", "covid-19", "halloween", "holiday", "lavatory", "paper towels", "prank", "privy", "restroom", "roll", "roll of paper", "toilet", "toilet paper", "wipe" ] }, "styles": ["solid"], "unicode": "f71e", "label": "Toilet Paper", "voted": false, "svg": { "solid": { "last_modified": 1684767442, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M444.2 0C397.2 49.6 384 126.5 384 192c0 158.8-27.3 247-42.7 283.9c-10 24-33.2 36.1-55.4 36.1H48c-11.5 0-22.2-6.2-27.8-16.2s-5.6-22.3 .4-32.2c9.8-17.7 15.4-38.2 20.5-57.7C52.3 362.8 64 293.5 64 192C64 86 107 0 160 0H444.2zM512 384c-53 0-96-86-96-192S459 0 512 0s96 86 96 192s-43 192-96 192zm0-128c17.7 0 32-28.7 32-64s-14.3-64-32-64s-32 28.7-32 64s14.3 64 32 64zM144 208a16 16 0 1 0 -32 0 16 16 0 1 0 32 0zm64 0a16 16 0 1 0 -32 0 16 16 0 1 0 32 0zm48 16a16 16 0 1 0 0-32 16 16 0 1 0 0 32zm80-16a16 16 0 1 0 -32 0 16 16 0 1 0 32 0z" } }, "free": ["solid"] }, "toilet-paper-slash": { "aliases": { "unicodes": { "secondary": ["10e072"] } }, "changes": ["5.13.0", "5.14.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "bathroom", "covid-19", "halloween", "holiday", "lavatory", "leaves", "prank", "privy", "restroom", "roll", "toilet", "trouble", "ut oh", "wipe" ] }, "styles": ["solid"], "unicode": "e072", "label": "Toilet Paper Slash", "voted": false, "svg": { "solid": { "last_modified": 1684767442, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7l-109.7-86C569.9 374 608 291.9 608 192C608 86 565 0 512 0s-96 86-96 192c0 49.1 9.2 93.9 24.4 127.9l-59-46.2c1.6-24.8 2.6-52 2.6-81.6c0-65.5 13.2-142.4 60.2-192H160c-24.8 0-47.4 18.8-64.4 49.6L38.8 5.1zM367.3 385.4L66.5 148.4C64.9 162.4 64 177 64 192c0 101.5-11.7 170.8-23 213.9c-5.1 19.4-10.7 39.9-20.5 57.7c-5.9 9.9-6.1 22.1-.4 32.2S36.5 512 48 512H285.9c22.3 0 45.4-12.1 55.4-36.1c7.4-17.7 17.5-47.2 26-90.6zM544 192c0 35.3-14.3 64-32 64s-32-28.7-32-64s14.3-64 32-64s32 28.7 32 64z" } }, "free": ["solid"] }, "toilet-portable": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["outhouse", "toilet"] }, "styles": ["solid"], "unicode": "e583", "label": "Toilet Portable", "voted": false, "svg": { "solid": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M0 32V64H320V32c0-17.7-14.3-32-32-32H32C14.3 0 0 14.3 0 32zM24 96H0v24V488c0 13.3 10.7 24 24 24s24-10.7 24-24v-8H272v8c0 13.3 10.7 24 24 24s24-10.7 24-24V120 96H296 24zM256 240v64c0 8.8-7.2 16-16 16s-16-7.2-16-16V240c0-8.8 7.2-16 16-16s16 7.2 16 16z" } }, "free": ["solid"] }, "toilets-portable": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["outhouse", "toilet"] }, "styles": ["solid"], "unicode": "e584", "label": "Toilets Portable", "voted": false, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M32 0H224c17.7 0 32 14.3 32 32V64H0V32C0 14.3 14.3 0 32 0zM0 96H24 232h24v24V488c0 13.3-10.7 24-24 24s-24-10.7-24-24v-8H48v8c0 13.3-10.7 24-24 24s-24-10.7-24-24V120 96zM192 224c-8.8 0-16 7.2-16 16v64c0 8.8 7.2 16 16 16s16-7.2 16-16V240c0-8.8-7.2-16-16-16zM352 0H544c17.7 0 32 14.3 32 32V64H320V32c0-17.7 14.3-32 32-32zM320 96h24H552h24v24V488c0 13.3-10.7 24-24 24s-24-10.7-24-24v-8H368v8c0 13.3-10.7 24-24 24s-24-10.7-24-24V120 96zM512 224c-8.8 0-16 7.2-16 16v64c0 8.8 7.2 16 16 16s16-7.2 16-16V240c0-8.8-7.2-16-16-16z" } }, "free": ["solid"] }, "toolbox": { "aliases": { "unicodes": { "composite": ["1f9f0"], "secondary": ["10f552"] } }, "changes": ["5.0.13", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "admin", "chest", "container", "fix", "mechanic", "repair", "settings", "tool", "toolbox", "tools" ] }, "styles": ["solid"], "unicode": "f552", "label": "Toolbox", "voted": true, "svg": { "solid": { "last_modified": 1684767442, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M176 88v40H336V88c0-4.4-3.6-8-8-8H184c-4.4 0-8 3.6-8 8zm-48 40V88c0-30.9 25.1-56 56-56H328c30.9 0 56 25.1 56 56v40h28.1c12.7 0 24.9 5.1 33.9 14.1l51.9 51.9c9 9 14.1 21.2 14.1 33.9V304H384V288c0-17.7-14.3-32-32-32s-32 14.3-32 32v16H192V288c0-17.7-14.3-32-32-32s-32 14.3-32 32v16H0V227.9c0-12.7 5.1-24.9 14.1-33.9l51.9-51.9c9-9 21.2-14.1 33.9-14.1H128zM0 416V336H128v16c0 17.7 14.3 32 32 32s32-14.3 32-32V336H320v16c0 17.7 14.3 32 32 32s32-14.3 32-32V336H512v80c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64z" } }, "free": ["solid"] }, "tooth": { "aliases": { "unicodes": { "composite": ["1f9b7"], "secondary": ["10f5c9"] } }, "changes": ["5.1.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "bicuspid", "dental", "dentist", "molar", "mouth", "teeth", "tooth" ] }, "styles": ["solid"], "unicode": "f5c9", "label": "Tooth", "voted": true, "svg": { "solid": { "last_modified": 1684766751, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M186.1 52.1C169.3 39.1 148.7 32 127.5 32C74.7 32 32 74.7 32 127.5v6.2c0 15.8 3.7 31.3 10.7 45.5l23.5 47.1c4.5 8.9 7.6 18.4 9.4 28.2l36.7 205.8c2 11.2 11.6 19.4 22.9 19.8s21.4-7.4 24-18.4l28.9-121.3C192.2 323.7 207 312 224 312s31.8 11.7 35.8 28.3l28.9 121.3c2.6 11.1 12.7 18.8 24 18.4s20.9-8.6 22.9-19.8l36.7-205.8c1.8-9.8 4.9-19.3 9.4-28.2l23.5-47.1c7.1-14.1 10.7-29.7 10.7-45.5v-2.1c0-55-44.6-99.6-99.6-99.6c-24.1 0-47.4 8.8-65.6 24.6l-3.2 2.8 19.5 15.2c7 5.4 8.2 15.5 2.8 22.5s-15.5 8.2-22.5 2.8l-24.4-19-37-28.8z" } }, "free": ["solid"] }, "torii-gate": { "aliases": { "unicodes": { "composite": ["26e9"], "secondary": ["10f6a1"] } }, "changes": [ "5.3.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "building", "religion", "shinto", "shinto shrine", "shintoism", "shrine" ] }, "styles": ["solid"], "unicode": "f6a1", "label": "Torii Gate", "voted": false, "svg": { "solid": { "last_modified": 1684766828, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 80c0 26.5 21.5 48 48 48H64v64h64V128h96v64h64V128h96v64h64V128h16c26.5 0 48-21.5 48-48V13.4C512 6 506 0 498.6 0c-1.7 0-3.4 .3-5 1l-49 19.6C425.7 28.1 405.5 32 385.2 32H126.8c-20.4 0-40.5-3.9-59.4-11.4L18.4 1c-1.6-.6-3.3-1-5-1C6 0 0 6 0 13.4V80zM64 288V480c0 17.7 14.3 32 32 32s32-14.3 32-32V288H384V480c0 17.7 14.3 32 32 32s32-14.3 32-32V288h32c17.7 0 32-14.3 32-32s-14.3-32-32-32H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H64z" } }, "free": ["solid"] }, "tornado": { "aliases": { "unicodes": { "composite": ["1f32a"], "secondary": ["10f76f"] } }, "changes": [ "5.5.0", "5.10.2", "6.0.0-beta1", "6.1.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "cloud", "cyclone", "dorothy", "landspout", "tornado", "toto", "twister", "vortext", "waterspout", "weather", "whirlwind" ] }, "styles": ["solid"], "unicode": "f76f", "label": "Tornado", "voted": false, "svg": { "solid": { "last_modified": 1684767661, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M0 32V45.6C0 62.7 1.7 79.6 5 96H357.8c3.2-6.9 7.5-13.3 13-18.8l38.6-38.6c4.2-4.2 6.6-10 6.6-16C416 10.1 405.9 0 393.4 0H32C14.3 0 0 14.3 0 32zm352.2 96H13.6c12.2 35.9 32.3 68.7 58.8 96H412l-47.2-62.9c-7.3-9.7-11.6-21.2-12.6-33.1zm-226 138.2l116.4 68.5c8.2 4.8 15.8 10.7 22.5 17.3H445c2-9.8 3-19.9 3-30.1c0-23-5.3-45.5-15.3-65.9H110.2c5.2 3.6 10.5 7 16 10.2zM288 384c10.3 21.4 13.8 45.5 9.9 69l-5.9 35.7c-2 12.2 7.4 23.4 19.8 23.4c5.3 0 10.4-2.1 14.2-5.9l78.2-78.2c12.8-12.8 23.1-27.7 30.4-43.9H288z" } }, "free": ["solid"] }, "tower-broadcast": { "aliases": { "names": ["broadcast-tower"], "unicodes": { "secondary": ["10f519"] } }, "changes": ["5.0.13", "6.0.0-beta1", "6.2.0", "6.2.1", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "airwaves", "antenna", "communication", "emergency", "radio", "reception", "waves" ] }, "styles": ["solid"], "unicode": "f519", "label": "Tower Broadcast", "voted": true, "svg": { "solid": { "last_modified": 1684766675, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M80.3 44C69.8 69.9 64 98.2 64 128s5.8 58.1 16.3 84c6.6 16.4-1.3 35-17.7 41.7s-35-1.3-41.7-17.7C7.4 202.6 0 166.1 0 128S7.4 53.4 20.9 20C27.6 3.6 46.2-4.3 62.6 2.3S86.9 27.6 80.3 44zM555.1 20C568.6 53.4 576 89.9 576 128s-7.4 74.6-20.9 108c-6.6 16.4-25.3 24.3-41.7 17.7S489.1 228.4 495.7 212c10.5-25.9 16.3-54.2 16.3-84s-5.8-58.1-16.3-84C489.1 27.6 497 9 513.4 2.3s35 1.3 41.7 17.7zM352 128c0 23.7-12.9 44.4-32 55.4V480c0 17.7-14.3 32-32 32s-32-14.3-32-32V183.4c-19.1-11.1-32-31.7-32-55.4c0-35.3 28.7-64 64-64s64 28.7 64 64zM170.6 76.8C163.8 92.4 160 109.7 160 128s3.8 35.6 10.6 51.2c7.1 16.2-.3 35.1-16.5 42.1s-35.1-.3-42.1-16.5c-10.3-23.6-16-49.6-16-76.8s5.7-53.2 16-76.8c7.1-16.2 25.9-23.6 42.1-16.5s23.6 25.9 16.5 42.1zM464 51.2c10.3 23.6 16 49.6 16 76.8s-5.7 53.2-16 76.8c-7.1 16.2-25.9 23.6-42.1 16.5s-23.6-25.9-16.5-42.1c6.8-15.6 10.6-32.9 10.6-51.2s-3.8-35.6-10.6-51.2c-7.1-16.2 .3-35.1 16.5-42.1s35.1 .3 42.1 16.5z" } }, "free": ["solid"] }, "tower-cell": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "airwaves", "antenna", "communication", "radio", "reception", "waves" ] }, "styles": ["solid"], "unicode": "e585", "label": "Tower Cell", "voted": false, "svg": { "solid": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M62.6 2.3C46.2-4.3 27.6 3.6 20.9 20C7.4 53.4 0 89.9 0 128s7.4 74.6 20.9 108c6.6 16.4 25.3 24.3 41.7 17.7S86.9 228.4 80.3 212C69.8 186.1 64 157.8 64 128s5.8-58.1 16.3-84C86.9 27.6 79 9 62.6 2.3zm450.8 0C497 9 489.1 27.6 495.7 44C506.2 69.9 512 98.2 512 128s-5.8 58.1-16.3 84c-6.6 16.4 1.3 35 17.7 41.7s35-1.3 41.7-17.7c13.5-33.4 20.9-69.9 20.9-108s-7.4-74.6-20.9-108C548.4 3.6 529.8-4.3 513.4 2.3zM340.1 165.2c7.5-10.5 11.9-23.3 11.9-37.2c0-35.3-28.7-64-64-64s-64 28.7-64 64c0 13.9 4.4 26.7 11.9 37.2L98.9 466.8c-7.3 16.1-.2 35.1 15.9 42.4s35.1 .2 42.4-15.9L177.7 448H398.3l20.6 45.2c7.3 16.1 26.3 23.2 42.4 15.9s23.2-26.3 15.9-42.4L340.1 165.2zM369.2 384H206.8l14.5-32H354.7l14.5 32zM288 205.3L325.6 288H250.4L288 205.3zM163.3 73.6c5.3-12.1-.2-26.3-12.4-31.6s-26.3 .2-31.6 12.4C109.5 77 104 101.9 104 128s5.5 51 15.3 73.6c5.3 12.1 19.5 17.7 31.6 12.4s17.7-19.5 12.4-31.6C156 165.8 152 147.4 152 128s4-37.8 11.3-54.4zM456.7 54.4c-5.3-12.1-19.5-17.7-31.6-12.4s-17.7 19.5-12.4 31.6C420 90.2 424 108.6 424 128s-4 37.8-11.3 54.4c-5.3 12.1 .2 26.3 12.4 31.6s26.3-.2 31.6-12.4C466.5 179 472 154.1 472 128s-5.5-51-15.3-73.6z" } }, "free": ["solid"] }, "tower-observation": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["fire tower", "view"] }, "styles": ["solid"], "unicode": "e586", "label": "Tower Observation", "voted": false, "svg": { "solid": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M241.7 3.4c9-4.5 19.6-4.5 28.6 0l160 80c15.8 7.9 22.2 27.1 14.3 42.9C439 137.5 427.7 144 416 144v80c0 17.7-14.3 32-32 32h-4.9l32 192H480c17.7 0 32 14.3 32 32s-14.3 32-32 32H384.5c-.4 0-.8 0-1.1 0H128.6c-.4 0-.8 0-1.1 0H32c-17.7 0-32-14.3-32-32s14.3-32 32-32h68.9l32-192H128c-17.7 0-32-14.3-32-32V144c-11.7 0-23-6.5-28.6-17.7c-7.9-15.8-1.5-35 14.3-42.9l160-80zM314.5 448L256 399.2 197.5 448h117zM197.8 256l-4.7 28.3L256 336.8l62.9-52.5L314.2 256H197.8zm-13.9 83.2l-11.2 67L218.5 368l-34.6-28.8zM293.5 368l45.8 38.1-11.2-67L293.5 368zM176 128c-8.8 0-16 7.2-16 16s7.2 16 16 16H336c8.8 0 16-7.2 16-16s-7.2-16-16-16H176z" } }, "free": ["solid"] }, "tractor": { "aliases": { "unicodes": { "composite": ["1f69c"], "secondary": ["10f722"] } }, "changes": [ "5.4.0", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["agriculture", "farm", "tractor", "vehicle"] }, "styles": ["solid"], "unicode": "f722", "label": "Tractor", "voted": false, "svg": { "solid": { "last_modified": 1684767649, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M96 64c0-35.3 28.7-64 64-64H266.3c26.2 0 49.7 15.9 59.4 40.2L373.7 160H480V126.2c0-24.8 5.8-49.3 16.9-71.6l2.5-5c7.9-15.8 27.1-22.2 42.9-14.3s22.2 27.1 14.3 42.9l-2.5 5c-6.7 13.3-10.1 28-10.1 42.9V160h56c22.1 0 40 17.9 40 40v45.4c0 16.5-8.5 31.9-22.6 40.7l-43.3 27.1c-14.2-5.9-29.8-9.2-46.1-9.2c-39.3 0-74.1 18.9-96 48H352c0 17.7-14.3 32-32 32h-8.2c-1.7 4.8-3.7 9.5-5.8 14.1l5.8 5.8c12.5 12.5 12.5 32.8 0 45.3l-22.6 22.6c-12.5 12.5-32.8 12.5-45.3 0l-5.8-5.8c-4.6 2.2-9.3 4.1-14.1 5.8V480c0 17.7-14.3 32-32 32H160c-17.7 0-32-14.3-32-32v-8.2c-4.8-1.7-9.5-3.7-14.1-5.8l-5.8 5.8c-12.5 12.5-32.8 12.5-45.3 0L40.2 449.1c-12.5-12.5-12.5-32.8 0-45.3l5.8-5.8c-2.2-4.6-4.1-9.3-5.8-14.1H32c-17.7 0-32-14.3-32-32V320c0-17.7 14.3-32 32-32h8.2c1.7-4.8 3.7-9.5 5.8-14.1l-5.8-5.8c-12.5-12.5-12.5-32.8 0-45.3l22.6-22.6c9-9 21.9-11.5 33.1-7.6V192 160 64zm170.3 0H160v96h32H304.7L266.3 64zM176 256a80 80 0 1 0 0 160 80 80 0 1 0 0-160zM528 448a24 24 0 1 0 0-48 24 24 0 1 0 0 48zm0 64c-48.6 0-88-39.4-88-88c0-29.8 14.8-56.1 37.4-72c14.3-10.1 31.8-16 50.6-16c2.7 0 5.3 .1 7.9 .3c44.9 4 80.1 41.7 80.1 87.7c0 48.6-39.4 88-88 88z" } }, "free": ["solid"] }, "trade-federation": { "changes": ["5.0.12"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f513", "label": "Trade Federation", "voted": false, "svg": { "brands": { "last_modified": 1660014465, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M248 8.8c-137 0-248 111-248 248s111 248 248 248 248-111 248-248-111-248-248-248zm0 482.8c-129.7 0-234.8-105.1-234.8-234.8S118.3 22 248 22s234.8 105.1 234.8 234.8S377.7 491.6 248 491.6zm155.1-328.5v-46.8H209.3V198H54.2l36.7 46h117.7v196.8h48.8V245h83.3v-47h-83.3v-34.8h145.7zm-73.3 45.1v23.9h-82.9v197.4h-26.8V232.1H96.3l-20.1-23.9h143.9v-80.6h171.8V152h-145v56.2zm-161.3-69l-12.4-20.7 2.1 23.8-23.5 5.4 23.3 5.4-2.1 24 12.3-20.5 22.2 9.5-15.7-18.1 15.8-18.1zm-29.6-19.7l9.3-11.5-12.7 5.9-8-12.4 1.7 13.9-14.3 3.8 13.7 2.7-.8 14.7 6.8-12.2 13.8 5.3zm165.4 145.2l-13.1 5.6-7.3-12.2 1.3 14.2-13.9 3.2 13.9 3.2-1.2 14.2 7.3-12.2 13.1 5.5-9.4-10.7zm106.9-77.2l-20.9 9.1-12-19.6 2.2 22.7-22.3 5.4 22.2 4.9-1.8 22.9 11.5-19.6 21.2 8.8-15.1-17zM248 29.9c-125.3 0-226.9 101.6-226.9 226.9S122.7 483.7 248 483.7s226.9-101.6 226.9-226.9S373.3 29.9 248 29.9zM342.6 196v51h-83.3v195.7h-52.7V245.9H89.9l-40-49.9h157.4v-81.6h197.8v50.7H259.4V196zM248 43.2c60.3 0 114.8 25 153.6 65.2H202.5V190H45.1C73.1 104.8 153.4 43.2 248 43.2zm0 427.1c-117.9 0-213.6-95.6-213.6-213.5 0-21.2 3.1-41.8 8.9-61.1L87.1 252h114.7v196.8h64.6V253h83.3v-62.7h-83.2v-19.2h145.6v-50.8c30.8 37 49.3 84.6 49.3 136.5.1 117.9-95.5 213.5-213.4 213.5zM178.8 275l-11-21.4 1.7 24.5-23.7 3.9 23.8 5.9-3.7 23.8 13-20.9 21.5 10.8-15.8-18.8 16.9-17.1z" } }, "free": ["brands"] }, "trademark": { "aliases": { "unicodes": { "composite": ["2122"], "secondary": ["10f25c"] } }, "changes": ["4.4.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "copyright", "mark", "register", "symbol", "tm", "trade mark", "trademark" ] }, "styles": ["solid"], "unicode": "f25c", "label": "Trademark", "voted": false, "svg": { "solid": { "last_modified": 1684767246, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M345.6 108.8c-8.3-11-22.7-15.5-35.7-11.2S288 114.2 288 128V384c0 17.7 14.3 32 32 32s32-14.3 32-32V224l86.4 115.2c6 8.1 15.5 12.8 25.6 12.8s19.6-4.7 25.6-12.8L576 224V384c0 17.7 14.3 32 32 32s32-14.3 32-32V128c0-13.8-8.8-26-21.9-30.4s-27.5 .1-35.7 11.2L464 266.7 345.6 108.8zM0 128c0 17.7 14.3 32 32 32H96V384c0 17.7 14.3 32 32 32s32-14.3 32-32V160h64c17.7 0 32-14.3 32-32s-14.3-32-32-32H32C14.3 96 0 110.3 0 128z" } }, "free": ["solid"] }, "traffic-light": { "aliases": { "unicodes": { "composite": ["1f6a6"], "secondary": ["10f637"] } }, "changes": [ "5.2.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "direction", "light", "road", "signal", "traffic", "travel", "vertical traffic light" ] }, "styles": ["solid"], "unicode": "f637", "label": "Traffic Light", "voted": false, "svg": { "solid": { "last_modified": 1684767488, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M64 0C28.7 0 0 28.7 0 64V352c0 88.4 71.6 160 160 160s160-71.6 160-160V64c0-35.3-28.7-64-64-64H64zm96 416a48 48 0 1 1 0-96 48 48 0 1 1 0 96zm48-176a48 48 0 1 1 -96 0 48 48 0 1 1 96 0zm-48-80a48 48 0 1 1 0-96 48 48 0 1 1 0 96z" } }, "free": ["solid"] }, "trailer": { "aliases": { "unicodes": { "secondary": ["10e041"] } }, "changes": [ "5.12.0", "5.14.0", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["carry", "haul", "moving", "travel"] }, "styles": ["solid"], "unicode": "e041", "label": "Trailer", "voted": true, "svg": { "solid": { "last_modified": 1684767649, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M48 32C21.5 32 0 53.5 0 80V336c0 26.5 21.5 48 48 48H65.1c7.8-54.3 54.4-96 110.9-96s103.1 41.7 110.9 96H488h8H608c17.7 0 32-14.3 32-32s-14.3-32-32-32H544V80c0-26.5-21.5-48-48-48H48zM80 96c8.8 0 16 7.2 16 16l0 131.2c-11.4 5.9-22.2 12.9-32 21V112c0-8.8 7.2-16 16-16zm96 128c-5.4 0-10.7 .2-16 .7L160 112c0-8.8 7.2-16 16-16s16 7.2 16 16l0 112.7c-5.3-.5-10.6-.7-16-.7zm80 19.2L256 112c0-8.8 7.2-16 16-16s16 7.2 16 16l0 152.2c-9.8-8.1-20.6-15.2-32-21zM368 96c8.8 0 16 7.2 16 16l0 192c0 8.8-7.2 16-16 16s-16-7.2-16-16l0-192c0-8.8 7.2-16 16-16zm112 16l0 192c0 8.8-7.2 16-16 16s-16-7.2-16-16l0-192c0-8.8 7.2-16 16-16s16 7.2 16 16zM176 480a80 80 0 1 0 0-160 80 80 0 1 0 0 160zm0-112a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" } }, "free": ["solid"] }, "train": { "aliases": { "unicodes": { "composite": ["1f686"], "secondary": ["10f238"] } }, "changes": [ "4.3.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["bullet", "commute", "locomotive", "railway", "subway", "train"] }, "styles": ["solid"], "unicode": "f238", "label": "Train", "voted": false, "svg": { "solid": { "last_modified": 1684767650, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M96 0C43 0 0 43 0 96V352c0 48 35.2 87.7 81.1 94.9l-46 46C28.1 499.9 33.1 512 43 512H82.7c8.5 0 16.6-3.4 22.6-9.4L160 448H288l54.6 54.6c6 6 14.1 9.4 22.6 9.4H405c10 0 15-12.1 7.9-19.1l-46-46c46-7.1 81.1-46.9 81.1-94.9V96c0-53-43-96-96-96H96zM64 96c0-17.7 14.3-32 32-32H352c17.7 0 32 14.3 32 32v96c0 17.7-14.3 32-32 32H96c-17.7 0-32-14.3-32-32V96zM224 288a48 48 0 1 1 0 96 48 48 0 1 1 0-96z" } }, "free": ["solid"] }, "train-subway": { "aliases": { "names": ["subway"], "unicodes": { "secondary": ["10f239"] } }, "changes": [ "4.3.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["machine", "railway", "train", "transportation", "vehicle"] }, "styles": ["solid"], "unicode": "f239", "label": "Train Subway", "voted": false, "svg": { "solid": { "last_modified": 1684767649, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M96 0C43 0 0 43 0 96V352c0 48 35.2 87.7 81.1 94.9l-46 46C28.1 499.9 33.1 512 43 512H82.7c8.5 0 16.6-3.4 22.6-9.4L160 448H288l54.6 54.6c6 6 14.1 9.4 22.6 9.4H405c10 0 15-12.1 7.9-19.1l-46-46c46-7.1 81.1-46.9 81.1-94.9V96c0-53-43-96-96-96H96zM64 128c0-17.7 14.3-32 32-32h80c17.7 0 32 14.3 32 32v96c0 17.7-14.3 32-32 32H96c-17.7 0-32-14.3-32-32V128zM272 96h80c17.7 0 32 14.3 32 32v96c0 17.7-14.3 32-32 32H272c-17.7 0-32-14.3-32-32V128c0-17.7 14.3-32 32-32zM64 352a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm288-32a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" } }, "free": ["solid"] }, "train-tram": { "aliases": { "unicodes": { "composite": ["1f68a"] } }, "changes": [ "5.6.0", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.1.2", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "crossing", "machine", "mountains", "seasonal", "tram", "transportation", "trolleybus" ] }, "styles": ["solid"], "unicode": "e5b4", "label": "Train Tram", "voted": false, "svg": { "solid": { "last_modified": 1684767649, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M86.8 48c-12.2 0-23.6 5.5-31.2 15L42.7 79C34.5 89.3 19.4 91 9 82.7S-3 59.4 5.3 49L18 33C34.7 12.2 60 0 86.8 0H361.2c26.7 0 52 12.2 68.7 33l12.8 16c8.3 10.4 6.6 25.5-3.8 33.7s-25.5 6.6-33.7-3.7L392.5 63c-7.6-9.5-19.1-15-31.2-15H248V96h40c53 0 96 43 96 96V352c0 30.6-14.3 57.8-36.6 75.4l65.5 65.5c7.1 7.1 2.1 19.1-7.9 19.1H365.3c-8.5 0-16.6-3.4-22.6-9.4L288 448H160l-54.6 54.6c-6 6-14.1 9.4-22.6 9.4H43c-10 0-15-12.1-7.9-19.1l65.5-65.5C78.3 409.8 64 382.6 64 352V192c0-53 43-96 96-96h40V48H86.8zM160 160c-17.7 0-32 14.3-32 32v32c0 17.7 14.3 32 32 32H288c17.7 0 32-14.3 32-32V192c0-17.7-14.3-32-32-32H160zm32 192a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zm96 32a32 32 0 1 0 0-64 32 32 0 1 0 0 64z" } }, "free": ["solid"] }, "transgender": { "aliases": { "names": ["transgender-alt"], "unicodes": { "composite": ["26a7"], "secondary": ["10f225"] } }, "changes": ["4.3.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "female", "gender", "intersex", "male", "transgender", "transgender symbol" ] }, "styles": ["solid"], "unicode": "f225", "label": "Transgender", "voted": false, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M112 0c6.5 0 12.3 3.9 14.8 9.9s1.1 12.9-3.5 17.4l-31 31L112 78.1l7-7c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-7 7 15.2 15.2C187.7 107.6 220.5 96 256 96s68.3 11.6 94.9 31.2l68.8-68.8-31-31c-4.6-4.6-5.9-11.5-3.5-17.4s8.3-9.9 14.8-9.9h96c8.8 0 16 7.2 16 16v96c0 6.5-3.9 12.3-9.9 14.8s-12.9 1.1-17.4-3.5l-31-31-68.8 68.8C404.4 187.7 416 220.5 416 256c0 80.2-59 146.6-136 158.2V432h16c13.3 0 24 10.7 24 24s-10.7 24-24 24H280v8c0 13.3-10.7 24-24 24s-24-10.7-24-24v-8H216c-13.3 0-24-10.7-24-24s10.7-24 24-24h16V414.2C155 402.6 96 336.2 96 256c0-35.5 11.6-68.3 31.2-94.9L112 145.9l-7 7c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l7-7L58.3 92.3l-31 31c-4.6 4.6-11.5 5.9-17.4 3.5S0 118.5 0 112V16C0 7.2 7.2 0 16 0h96zM352 256a96 96 0 1 0 -192 0 96 96 0 1 0 192 0z" } }, "free": ["solid"] }, "trash": { "aliases": { "unicodes": { "secondary": ["10f1f8"] } }, "changes": [ "4.2.0", "5.0.0", "5.7.0", "5.10.2", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["delete", "garbage", "hide", "remove"] }, "styles": ["solid"], "unicode": "f1f8", "label": "Trash", "voted": false, "svg": { "solid": { "last_modified": 1684767367, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M135.2 17.7L128 32H32C14.3 32 0 46.3 0 64S14.3 96 32 96H416c17.7 0 32-14.3 32-32s-14.3-32-32-32H320l-7.2-14.3C307.4 6.8 296.3 0 284.2 0H163.8c-12.1 0-23.2 6.8-28.6 17.7zM416 128H32L53.2 467c1.6 25.3 22.6 45 47.9 45H346.9c25.3 0 46.3-19.7 47.9-45L416 128z" } }, "free": ["solid"] }, "trash-arrow-up": { "aliases": { "names": ["trash-restore"], "unicodes": { "secondary": ["10f829"] } }, "changes": [ "5.7.0", "5.10.2", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "back", "control z", "delete", "garbage", "hide", "oops", "remove", "undo" ] }, "styles": ["solid"], "unicode": "f829", "label": "Trash Arrow Up", "voted": true, "svg": { "solid": { "last_modified": 1684767366, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M163.8 0H284.2c12.1 0 23.2 6.8 28.6 17.7L320 32h96c17.7 0 32 14.3 32 32s-14.3 32-32 32H32C14.3 96 0 81.7 0 64S14.3 32 32 32h96l7.2-14.3C140.6 6.8 151.7 0 163.8 0zM32 128H416L394.8 467c-1.6 25.3-22.6 45-47.9 45H101.1c-25.3 0-46.3-19.7-47.9-45L32 128zm192 64c-6.4 0-12.5 2.5-17 7l-80 80c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l39-39V408c0 13.3 10.7 24 24 24s24-10.7 24-24V273.9l39 39c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9l-80-80c-4.5-4.5-10.6-7-17-7z" } }, "free": ["solid"] }, "trash-can": { "aliases": { "names": ["trash-alt"], "unicodes": { "composite": ["f014"], "secondary": ["10f2ed"] } }, "changes": [ "5.0.0", "5.7.0", "5.10.2", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["delete", "garbage", "hide", "remove", "trash-o"] }, "styles": ["solid", "regular"], "unicode": "f2ed", "label": "Trash Can", "voted": false, "svg": { "solid": { "last_modified": 1684767368, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M135.2 17.7C140.6 6.8 151.7 0 163.8 0H284.2c12.1 0 23.2 6.8 28.6 17.7L320 32h96c17.7 0 32 14.3 32 32s-14.3 32-32 32H32C14.3 96 0 81.7 0 64S14.3 32 32 32h96l7.2-14.3zM32 128H416V448c0 35.3-28.7 64-64 64H96c-35.3 0-64-28.7-64-64V128zm96 64c-8.8 0-16 7.2-16 16V432c0 8.8 7.2 16 16 16s16-7.2 16-16V208c0-8.8-7.2-16-16-16zm96 0c-8.8 0-16 7.2-16 16V432c0 8.8 7.2 16 16 16s16-7.2 16-16V208c0-8.8-7.2-16-16-16zm96 0c-8.8 0-16 7.2-16 16V432c0 8.8 7.2 16 16 16s16-7.2 16-16V208c0-8.8-7.2-16-16-16z" }, "regular": { "last_modified": 1684767368, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M170.5 51.6L151.5 80h145l-19-28.4c-1.5-2.2-4-3.6-6.7-3.6H177.1c-2.7 0-5.2 1.3-6.7 3.6zm147-26.6L354.2 80H368h48 8c13.3 0 24 10.7 24 24s-10.7 24-24 24h-8V432c0 44.2-35.8 80-80 80H112c-44.2 0-80-35.8-80-80V128H24c-13.3 0-24-10.7-24-24S10.7 80 24 80h8H80 93.8l36.7-55.1C140.9 9.4 158.4 0 177.1 0h93.7c18.7 0 36.2 9.4 46.6 24.9zM80 128V432c0 17.7 14.3 32 32 32H336c17.7 0 32-14.3 32-32V128H80zm80 64V400c0 8.8-7.2 16-16 16s-16-7.2-16-16V192c0-8.8 7.2-16 16-16s16 7.2 16 16zm80 0V400c0 8.8-7.2 16-16 16s-16-7.2-16-16V192c0-8.8 7.2-16 16-16s16 7.2 16 16zm80 0V400c0 8.8-7.2 16-16 16s-16-7.2-16-16V192c0-8.8 7.2-16 16-16s16 7.2 16 16z" } }, "free": ["regular", "solid"] }, "trash-can-arrow-up": { "aliases": { "names": ["trash-restore-alt"], "unicodes": { "secondary": ["10f82a"] } }, "changes": [ "5.7.0", "5.10.2", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "back", "control z", "delete", "garbage", "hide", "oops", "remove", "undo" ] }, "styles": ["solid"], "unicode": "f82a", "label": "Trash Can Arrow Up", "voted": true, "svg": { "solid": { "last_modified": 1684767366, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M163.8 0H284.2c12.1 0 23.2 6.8 28.6 17.7L320 32h96c17.7 0 32 14.3 32 32s-14.3 32-32 32H32C14.3 96 0 81.7 0 64S14.3 32 32 32h96l7.2-14.3C140.6 6.8 151.7 0 163.8 0zM32 128H416V448c0 35.3-28.7 64-64 64H96c-35.3 0-64-28.7-64-64V128zm192 64c-6.4 0-12.5 2.5-17 7l-80 80c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l39-39V408c0 13.3 10.7 24 24 24s24-10.7 24-24V273.9l39 39c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9l-80-80c-4.5-4.5-10.6-7-17-7z" } }, "free": ["solid"] }, "tree": { "aliases": { "unicodes": { "composite": ["1f332"], "secondary": ["10f1bb"] } }, "changes": ["4.1.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "bark", "evergreen tree", "fall", "flora", "forest", "nature", "plant", "seasonal", "tree" ] }, "styles": ["solid"], "unicode": "f1bb", "label": "Tree", "voted": false, "svg": { "solid": { "last_modified": 1684768131, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M210.6 5.9L62 169.4c-3.9 4.2-6 9.8-6 15.5C56 197.7 66.3 208 79.1 208H104L30.6 281.4c-4.2 4.2-6.6 10-6.6 16C24 309.9 34.1 320 46.6 320H80L5.4 409.5C1.9 413.7 0 419 0 424.5c0 13 10.5 23.5 23.5 23.5H192v32c0 17.7 14.3 32 32 32s32-14.3 32-32V448H424.5c13 0 23.5-10.5 23.5-23.5c0-5.5-1.9-10.8-5.4-15L368 320h33.4c12.5 0 22.6-10.1 22.6-22.6c0-6-2.4-11.8-6.6-16L344 208h24.9c12.7 0 23.1-10.3 23.1-23.1c0-5.7-2.1-11.3-6-15.5L237.4 5.9C234 2.1 229.1 0 224 0s-10 2.1-13.4 5.9z" } }, "free": ["solid"] }, "tree-city": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["building", "city", "urban"] }, "styles": ["solid"], "unicode": "e587", "label": "Tree City", "voted": false, "svg": { "solid": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M288 48c0-26.5 21.5-48 48-48h96c26.5 0 48 21.5 48 48V192h40V120c0-13.3 10.7-24 24-24s24 10.7 24 24v72h24c26.5 0 48 21.5 48 48V464c0 26.5-21.5 48-48 48H432 336c-26.5 0-48-21.5-48-48V48zm64 32v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V80c0-8.8-7.2-16-16-16H368c-8.8 0-16 7.2-16 16zm16 80c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V176c0-8.8-7.2-16-16-16H368zM352 272v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V272c0-8.8-7.2-16-16-16H368c-8.8 0-16 7.2-16 16zm176-16c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V272c0-8.8-7.2-16-16-16H528zM512 368v32c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V368c0-8.8-7.2-16-16-16H528c-8.8 0-16 7.2-16 16zM224 160c0 6-1 11-2 16c20 14 34 38 34 64c0 45-36 80-80 80H160V480c0 18-15 32-32 32c-18 0-32-14-32-32V320H80c-45 0-80-35-80-80c0-26 13-50 33-64c-1-5-1-10-1-16c0-53 42-96 96-96c53 0 96 43 96 96z" } }, "free": ["solid"] }, "trello": { "changes": ["3.2.0", "5.0.0", "5.6.0"], "ligatures": [], "search": { "terms": ["atlassian"] }, "styles": ["brands"], "unicode": "f181", "label": "Trello", "voted": false, "svg": { "brands": { "last_modified": 1660014462, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M392.3 32H56.1C25.1 32 0 57.1 0 88c-.1 0 0-4 0 336 0 30.9 25.1 56 56 56h336.2c30.8-.2 55.7-25.2 55.7-56V88c.1-30.8-24.8-55.8-55.6-56zM197 371.3c-.2 14.7-12.1 26.6-26.9 26.6H87.4c-14.8.1-26.9-11.8-27-26.6V117.1c0-14.8 12-26.9 26.9-26.9h82.9c14.8 0 26.9 12 26.9 26.9v254.2zm193.1-112c0 14.8-12 26.9-26.9 26.9h-81c-14.8 0-26.9-12-26.9-26.9V117.2c0-14.8 12-26.9 26.8-26.9h81.1c14.8 0 26.9 12 26.9 26.9v142.1z" } }, "free": ["brands"] }, "triangle-exclamation": { "aliases": { "names": ["exclamation-triangle", "warning"], "unicodes": { "composite": ["26a0"], "secondary": ["10f071"] } }, "changes": [ "1.0.0", "5.0.0", "5.6.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "alert", "danger", "error", "important", "notice", "notification", "notify", "problem", "warnin", "warning" ] }, "styles": ["solid"], "unicode": "f071", "label": "Triangle Exclamation", "voted": false, "svg": { "solid": { "last_modified": 1684767244, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 32c14.2 0 27.3 7.5 34.5 19.8l216 368c7.3 12.4 7.3 27.7 .2 40.1S486.3 480 472 480H40c-14.3 0-27.6-7.7-34.7-20.1s-7-27.8 .2-40.1l216-368C228.7 39.5 241.8 32 256 32zm0 128c-13.3 0-24 10.7-24 24V296c0 13.3 10.7 24 24 24s24-10.7 24-24V184c0-13.3-10.7-24-24-24zm32 224a32 32 0 1 0 -64 0 32 32 0 1 0 64 0z" } }, "free": ["solid"] }, "trophy": { "aliases": { "unicodes": { "composite": ["1f3c6"], "secondary": ["10f091"] } }, "changes": [ "1.0.0", "5.0.0", "5.11.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "achievement", "award", "cup", "game", "prize", "trophy", "winner" ] }, "styles": ["solid"], "unicode": "f091", "label": "Trophy", "voted": false, "svg": { "solid": { "last_modified": 1684767601, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M400 0H176c-26.5 0-48.1 21.8-47.1 48.2c.2 5.3 .4 10.6 .7 15.8H24C10.7 64 0 74.7 0 88c0 92.6 33.5 157 78.5 200.7c44.3 43.1 98.3 64.8 138.1 75.8c23.4 6.5 39.4 26 39.4 45.6c0 20.9-17 37.9-37.9 37.9H192c-17.7 0-32 14.3-32 32s14.3 32 32 32H384c17.7 0 32-14.3 32-32s-14.3-32-32-32H357.9C337 448 320 431 320 410.1c0-19.6 15.9-39.2 39.4-45.6c39.9-11 93.9-32.7 138.2-75.8C542.5 245 576 180.6 576 88c0-13.3-10.7-24-24-24H446.4c.3-5.2 .5-10.4 .7-15.8C448.1 21.8 426.5 0 400 0zM48.9 112h84.4c9.1 90.1 29.2 150.3 51.9 190.6c-24.9-11-50.8-26.5-73.2-48.3c-32-31.1-58-76-63-142.3zM464.1 254.3c-22.4 21.8-48.3 37.3-73.2 48.3c22.7-40.3 42.8-100.5 51.9-190.6h84.4c-5.1 66.3-31.1 111.2-63 142.3z" } }, "free": ["solid"] }, "trowel": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["build", "construction", "tool"] }, "styles": ["solid"], "unicode": "e589", "label": "Trowel", "voted": false, "svg": { "solid": { "last_modified": 1684767441, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M343.9 213.4L245.3 312l65.4 65.4c7.9 7.9 11.1 19.4 8.4 30.3s-10.8 19.6-21.5 22.9l-256 80c-11.4 3.5-23.8 .5-32.2-7.9S-2.1 481.8 1.5 470.5l80-256c3.3-10.7 12-18.9 22.9-21.5s22.4 .5 30.3 8.4L200 266.7l98.6-98.6c-14.3-14.6-14.2-38 .3-52.5l95.4-95.4c26.9-26.9 70.5-26.9 97.5 0s26.9 70.5 0 97.5l-95.4 95.4c-14.5 14.5-37.9 14.6-52.5 .3z" } }, "free": ["solid"] }, "trowel-bricks": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["build", "construction", "reconstruction", "tool"] }, "styles": ["solid"], "unicode": "e58a", "label": "Trowel Bricks", "voted": false, "svg": { "solid": { "last_modified": 1684767444, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M240.8 4.8C250.3 10.6 256 20.9 256 32v72h89c3.6-13.8 16.1-24 31-24h88c26.5 0 48 21.5 48 48s-21.5 48-48 48H376c-14.9 0-27.4-10.2-31-24H256v72c0 11.1-5.7 21.4-15.2 27.2s-21.2 6.4-31.1 1.4l-192-96C6.8 151.2 0 140.1 0 128s6.8-23.2 17.7-28.6l192-96c9.9-5 21.7-4.4 31.1 1.4zM288 256c0-17.7 14.3-32 32-32H480c17.7 0 32 14.3 32 32v64c0 17.7-14.3 32-32 32H320c-17.7 0-32-14.3-32-32V256zM32 384h96c17.7 0 32 14.3 32 32v64c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32V416c0-17.7 14.3-32 32-32zm192 0H480c17.7 0 32 14.3 32 32v64c0 17.7-14.3 32-32 32H224c-17.7 0-32-14.3-32-32V416c0-17.7 14.3-32 32-32z" } }, "free": ["solid"] }, "truck": { "aliases": { "unicodes": { "composite": ["1f69a", "26df"], "secondary": ["10f0d1"] } }, "changes": [ "2.0.0", "5.0.0", "5.0.7", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.1.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Black Truck", "cargo", "delivery", "delivery truck", "shipping", "truck", "vehicle" ] }, "styles": ["solid"], "unicode": "f0d1", "label": "Truck", "voted": false, "svg": { "solid": { "last_modified": 1684767649, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M48 0C21.5 0 0 21.5 0 48V368c0 26.5 21.5 48 48 48H64c0 53 43 96 96 96s96-43 96-96H384c0 53 43 96 96 96s96-43 96-96h32c17.7 0 32-14.3 32-32s-14.3-32-32-32V288 256 237.3c0-17-6.7-33.3-18.7-45.3L512 114.7c-12-12-28.3-18.7-45.3-18.7H416V48c0-26.5-21.5-48-48-48H48zM416 160h50.7L544 237.3V256H416V160zM112 416a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zm368-48a48 48 0 1 1 0 96 48 48 0 1 1 0-96z" } }, "free": ["solid"] }, "truck-arrow-right": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["access", "fast", "shipping", "transport"] }, "styles": ["solid"], "unicode": "e58b", "label": "Truck Arrow Right", "voted": false, "svg": { "solid": { "last_modified": 1684767649, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M0 48C0 21.5 21.5 0 48 0H368c26.5 0 48 21.5 48 48V96h50.7c17 0 33.3 6.7 45.3 18.7L589.3 192c12 12 18.7 28.3 18.7 45.3V256v32 64c17.7 0 32 14.3 32 32s-14.3 32-32 32H576c0 53-43 96-96 96s-96-43-96-96H256c0 53-43 96-96 96s-96-43-96-96H48c-26.5 0-48-21.5-48-48V48zM416 256H544V237.3L466.7 160H416v96zM160 464a48 48 0 1 0 0-96 48 48 0 1 0 0 96zm368-48a48 48 0 1 0 -96 0 48 48 0 1 0 96 0zM257 95c-9.4-9.4-24.6-9.4-33.9 0s-9.4 24.6 0 33.9l39 39H96c-13.3 0-24 10.7-24 24s10.7 24 24 24H262.1l-39 39c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l80-80c9.4-9.4 9.4-24.6 0-33.9L257 95z" } }, "free": ["solid"] }, "truck-droplet": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["thirst", "truck", "water", "water supply"] }, "styles": ["solid"], "unicode": "e58c", "label": "Truck Droplet", "voted": false, "svg": { "solid": { "last_modified": 1684767649, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M0 48C0 21.5 21.5 0 48 0H368c26.5 0 48 21.5 48 48V96h50.7c17 0 33.3 6.7 45.3 18.7L589.3 192c12 12 18.7 28.3 18.7 45.3V256v32 64c17.7 0 32 14.3 32 32s-14.3 32-32 32H576c0 53-43 96-96 96s-96-43-96-96H256c0 53-43 96-96 96s-96-43-96-96H48c-26.5 0-48-21.5-48-48V48zM416 256H544V237.3L466.7 160H416v96zM160 464a48 48 0 1 0 0-96 48 48 0 1 0 0 96zm368-48a48 48 0 1 0 -96 0 48 48 0 1 0 96 0zM208 272c39.8 0 72-29.6 72-66c0-27-39.4-82.9-59.9-110.3c-6.1-8.2-18.1-8.2-24.2 0C175.4 123 136 179 136 206c0 36.5 32.2 66 72 66z" } }, "free": ["solid"] }, "truck-fast": { "aliases": { "names": ["shipping-fast"], "unicodes": { "secondary": ["10f48b"] } }, "changes": [ "5.0.7", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.1.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["express", "fedex", "mail", "overnight", "package", "ups"] }, "styles": ["solid"], "unicode": "f48b", "label": "Truck Fast", "voted": false, "svg": { "solid": { "last_modified": 1684767649, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M112 0C85.5 0 64 21.5 64 48V96H16c-8.8 0-16 7.2-16 16s7.2 16 16 16H64 272c8.8 0 16 7.2 16 16s-7.2 16-16 16H64 48c-8.8 0-16 7.2-16 16s7.2 16 16 16H64 240c8.8 0 16 7.2 16 16s-7.2 16-16 16H64 16c-8.8 0-16 7.2-16 16s7.2 16 16 16H64 208c8.8 0 16 7.2 16 16s-7.2 16-16 16H64V416c0 53 43 96 96 96s96-43 96-96H384c0 53 43 96 96 96s96-43 96-96h32c17.7 0 32-14.3 32-32s-14.3-32-32-32V288 256 237.3c0-17-6.7-33.3-18.7-45.3L512 114.7c-12-12-28.3-18.7-45.3-18.7H416V48c0-26.5-21.5-48-48-48H112zM544 237.3V256H416V160h50.7L544 237.3zM160 368a48 48 0 1 1 0 96 48 48 0 1 1 0-96zm272 48a48 48 0 1 1 96 0 48 48 0 1 1 -96 0z" } }, "free": ["solid"] }, "truck-field": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["supplies", "truck"] }, "styles": ["solid"], "unicode": "e58d", "label": "Truck Field", "voted": false, "svg": { "solid": { "last_modified": 1684767650, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M32 96c0-35.3 28.7-64 64-64H320c23.7 0 44.4 12.9 55.4 32h51.8c25.3 0 48.2 14.9 58.5 38l52.8 118.8c.5 1.1 .9 2.1 1.3 3.2H544c35.3 0 64 28.7 64 64v32c17.7 0 32 14.3 32 32s-14.3 32-32 32H576c0 53-43 96-96 96s-96-43-96-96H256c0 53-43 96-96 96s-96-43-96-96H32c-17.7 0-32-14.3-32-32s14.3-32 32-32V288c-17.7 0-32-14.3-32-32V160c0-17.7 14.3-32 32-32V96zM384 224h85.9l-42.7-96H384v96zM160 432a48 48 0 1 0 0-96 48 48 0 1 0 0 96zm368-48a48 48 0 1 0 -96 0 48 48 0 1 0 96 0z" } }, "free": ["solid"] }, "truck-field-un": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["supplies", "truck", "united nations"] }, "styles": ["solid"], "unicode": "e58e", "label": "Truck Field Un", "voted": false, "svg": { "solid": { "last_modified": 1684767649, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M96 32C60.7 32 32 60.7 32 96v32c-17.7 0-32 14.3-32 32v96c0 17.7 14.3 32 32 32v32c-17.7 0-32 14.3-32 32s14.3 32 32 32H64c0 53 43 96 96 96s96-43 96-96H384c0 53 43 96 96 96s96-43 96-96h32c17.7 0 32-14.3 32-32s-14.3-32-32-32V288c0-35.3-28.7-64-64-64h-4.2c-.4-1.1-.9-2.1-1.3-3.2L485.7 102c-10.3-23.1-33.2-38-58.5-38H375.4C364.4 44.9 343.7 32 320 32H96zm288 96h43.2l42.7 96H384V128zM112 384a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zm368-48a48 48 0 1 1 0 96 48 48 0 1 1 0-96zM253.3 135.1l34.7 52V144c0-8.8 7.2-16 16-16s16 7.2 16 16v96c0 7.1-4.6 13.3-11.4 15.3s-14-.6-17.9-6.4l-34.7-52V240c0 8.8-7.2 16-16 16s-16-7.2-16-16V144c0-7.1 4.6-13.3 11.4-15.3s14 .6 17.9 6.4zM128 144v64c0 8.8 7.2 16 16 16s16-7.2 16-16V144c0-8.8 7.2-16 16-16s16 7.2 16 16v64c0 26.5-21.5 48-48 48s-48-21.5-48-48V144c0-8.8 7.2-16 16-16s16 7.2 16 16z" } }, "free": ["solid"] }, "truck-front": { "changes": [ "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.1.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["shuttle", "truck", "van"] }, "styles": ["solid"], "unicode": "e2b7", "label": "Truck Front", "voted": false, "svg": { "solid": { "last_modified": 1684767650, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 80C0 35.8 35.8 0 80 0H432c44.2 0 80 35.8 80 80V368c0 26.2-12.6 49.4-32 64v48c0 17.7-14.3 32-32 32H416c-17.7 0-32-14.3-32-32V448H128v32c0 17.7-14.3 32-32 32H64c-17.7 0-32-14.3-32-32V432C12.6 417.4 0 394.2 0 368V80zm129.9 72.2L112 224H400l-17.9-71.8C378.5 138 365.7 128 351 128H161c-14.7 0-27.5 10-31 24.2zM128 320a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zm288 32a32 32 0 1 0 0-64 32 32 0 1 0 0 64z" } }, "free": ["solid"] }, "truck-medical": { "aliases": { "names": ["ambulance"], "unicodes": { "composite": ["1f691"], "secondary": ["10f0f9"] } }, "changes": [ "3.0.0", "5.0.0", "5.0.7", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "ambulance", "clinic", "covid-19", "emergency", "emt", "er", "help", "hospital", "mobile", "support", "vehicle" ] }, "styles": ["solid"], "unicode": "f0f9", "label": "Truck Medical", "voted": false, "svg": { "solid": { "last_modified": 1684767650, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M0 48C0 21.5 21.5 0 48 0H368c26.5 0 48 21.5 48 48V96h50.7c17 0 33.3 6.7 45.3 18.7L589.3 192c12 12 18.7 28.3 18.7 45.3V256v32 64c17.7 0 32 14.3 32 32s-14.3 32-32 32H576c0 53-43 96-96 96s-96-43-96-96H256c0 53-43 96-96 96s-96-43-96-96H48c-26.5 0-48-21.5-48-48V48zM416 256H544V237.3L466.7 160H416v96zM160 464a48 48 0 1 0 0-96 48 48 0 1 0 0 96zm368-48a48 48 0 1 0 -96 0 48 48 0 1 0 96 0zM176 80v48l-48 0c-8.8 0-16 7.2-16 16v32c0 8.8 7.2 16 16 16h48v48c0 8.8 7.2 16 16 16h32c8.8 0 16-7.2 16-16V192h48c8.8 0 16-7.2 16-16V144c0-8.8-7.2-16-16-16H240V80c0-8.8-7.2-16-16-16H192c-8.8 0-16 7.2-16 16z" } }, "free": ["solid"] }, "truck-monster": { "aliases": { "unicodes": { "secondary": ["10f63b"] } }, "changes": [ "5.2.0", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["offroad", "vehicle", "wheel"] }, "styles": ["solid"], "unicode": "f63b", "label": "Truck Monster", "voted": false, "svg": { "solid": { "last_modified": 1684767650, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M288 64v64H416L368 64H288zM419.2 25.6L496 128h80c17.7 0 32 14.3 32 32v64c17.7 0 32 14.3 32 32s-14.3 32-32 32c-29.2-38.9-75.7-64-128-64s-98.8 25.1-128 64H288c-29.2-38.9-75.7-64-128-64s-98.8 25.1-128 64c-17.7 0-32-14.3-32-32s14.3-32 32-32V160c0-17.7 14.3-32 32-32H224V48c0-26.5 21.5-48 48-48h96c20.1 0 39.1 9.5 51.2 25.6zM152 256h16c12.1 0 22.1 8.9 23.8 20.6c7.6 2.2 14.9 5.3 21.7 9c9.4-7 22.8-6.3 31.3 2.3l11.3 11.3c8.6 8.6 9.3 21.9 2.3 31.3c3.7 6.8 6.8 14.1 9 21.7c11.6 1.7 20.6 11.7 20.6 23.8v16c0 12.1-8.9 22.1-20.6 23.8c-2.2 7.6-5.3 14.9-9 21.7c7 9.4 6.3 22.8-2.3 31.3l-11.3 11.3c-8.6 8.6-21.9 9.3-31.3 2.2c-6.8 3.7-14.1 6.8-21.7 9C190.1 503.1 180.1 512 168 512H152c-12.1 0-22.1-8.9-23.8-20.6c-7.6-2.2-14.9-5.3-21.7-9c-9.4 7.1-22.8 6.3-31.3-2.2L63.8 468.9c-8.6-8.6-9.3-21.9-2.3-31.3c-3.7-6.9-6.8-14.1-9-21.8C40.9 414.1 32 404.1 32 392V376c0-12.1 8.9-22.1 20.6-23.8c2.2-7.6 5.3-14.9 9-21.8c-7-9.4-6.3-22.8 2.3-31.3l11.3-11.3c8.6-8.6 21.9-9.3 31.3-2.3c6.8-3.7 14.1-6.8 21.7-9c1.7-11.6 11.7-20.6 23.8-20.6zm8 176a48 48 0 1 0 0-96 48 48 0 1 0 0 96zM448.2 276.6c1.7-11.6 11.7-20.6 23.8-20.6h16c12.1 0 22.1 8.9 23.8 20.6c7.6 2.2 14.9 5.3 21.8 9c9.4-7 22.8-6.3 31.3 2.3l11.3 11.3c8.6 8.6 9.3 21.9 2.2 31.3c3.7 6.8 6.8 14.1 9 21.7c11.6 1.7 20.6 11.7 20.6 23.8v16c0 12.1-8.9 22.1-20.6 23.8c-2.2 7.6-5.3 14.9-9 21.7c7 9.4 6.3 22.8-2.2 31.3l-11.3 11.3c-8.6 8.6-21.9 9.3-31.3 2.2c-6.9 3.7-14.1 6.8-21.8 9C510.1 503.1 500.1 512 488 512H472c-12.1 0-22.1-8.9-23.8-20.6c-7.6-2.2-14.9-5.3-21.7-9c-9.4 7.1-22.8 6.3-31.3-2.2l-11.3-11.3c-8.6-8.6-9.3-21.9-2.2-31.3c-3.7-6.9-6.8-14.1-9-21.8C360.9 414.1 352 404.1 352 392V376c0-12.1 8.9-22.1 20.6-23.8c2.2-7.6 5.3-14.9 9-21.8c-7-9.4-6.3-22.8 2.2-31.3l11.3-11.3c8.6-8.6 21.9-9.3 31.3-2.3c6.8-3.7 14.1-6.8 21.7-9zM528 384a48 48 0 1 0 -96 0 48 48 0 1 0 96 0z" } }, "free": ["solid"] }, "truck-moving": { "aliases": { "unicodes": { "secondary": ["10f4df"] } }, "changes": [ "5.0.9", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["cargo", "inventory", "rental", "vehicle"] }, "styles": ["solid"], "unicode": "f4df", "label": "Truck Moving", "voted": false, "svg": { "solid": { "last_modified": 1684767649, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M64 32C28.7 32 0 60.7 0 96V304v80 16c0 44.2 35.8 80 80 80c26.2 0 49.4-12.6 64-32c14.6 19.4 37.8 32 64 32c44.2 0 80-35.8 80-80c0-5.5-.6-10.8-1.6-16H416h33.6c-1 5.2-1.6 10.5-1.6 16c0 44.2 35.8 80 80 80s80-35.8 80-80c0-5.5-.6-10.8-1.6-16H608c17.7 0 32-14.3 32-32V288 272 261.7c0-9.2-3.2-18.2-9-25.3l-58.8-71.8c-10.6-13-26.5-20.5-43.3-20.5H480V96c0-35.3-28.7-64-64-64H64zM585 256H480V192h48.8c2.4 0 4.7 1.1 6.2 2.9L585 256zM528 368a32 32 0 1 1 0 64 32 32 0 1 1 0-64zM176 400a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zM80 368a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" } }, "free": ["solid"] }, "truck-pickup": { "aliases": { "unicodes": { "composite": ["1f6fb"], "secondary": ["10f63c"] } }, "changes": [ "5.2.0", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "cargo", "pick-up", "pickup", "pickup truck", "truck", "vehicle" ] }, "styles": ["solid"], "unicode": "f63c", "label": "Truck Pickup", "voted": false, "svg": { "solid": { "last_modified": 1684767649, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M368.6 96l76.8 96H288V96h80.6zM224 80V192H64c-17.7 0-32 14.3-32 32v64c-17.7 0-32 14.3-32 32s14.3 32 32 32H65.1c-.7 5.2-1.1 10.6-1.1 16c0 61.9 50.1 112 112 112s112-50.1 112-112c0-5.4-.4-10.8-1.1-16h66.3c-.7 5.2-1.1 10.6-1.1 16c0 61.9 50.1 112 112 112s112-50.1 112-112c0-5.4-.4-10.8-1.1-16H608c17.7 0 32-14.3 32-32s-14.3-32-32-32V224c0-17.7-14.3-32-32-32H527.4L418.6 56c-12.1-15.2-30.5-24-50-24H272c-26.5 0-48 21.5-48 48zm0 288a48 48 0 1 1 -96 0 48 48 0 1 1 96 0zm288 0a48 48 0 1 1 -96 0 48 48 0 1 1 96 0z" } }, "free": ["solid"] }, "truck-plane": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["airplane", "plane", "transportation", "truck", "vehicle"] }, "styles": ["solid"], "unicode": "e58f", "label": "Truck Plane", "voted": false, "svg": { "solid": { "last_modified": 1684767637, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M200 0c-30.6 0-56 54.7-56 86.1V192.5L7.8 274.3C2.9 277.2 0 282.4 0 288v64c0 5.1 2.4 9.8 6.4 12.8s9.3 3.9 14.1 2.5l123.4-37v81.2l-50 40c-3.8 3-6 7.6-6 12.5v32c0 5.1 2.5 10 6.6 13s9.5 3.8 14.4 2.2L200 480.9 290.4 511c-1.6-4.7-2.4-9.8-2.4-15V463.4c-18.2-10.5-30.7-29.7-31.9-51.8l-.1-.1V408 325.5 184l0-1.1 0 0V86.1C256 54.7 231.5 0 200 0zm88 176V400c0 20.9 13.4 38.7 32 45.3V488c0 13.3 10.7 24 24 24h16c13.3 0 24-10.7 24-24V448H544v40c0 13.3 10.7 24 24 24h16c13.3 0 24-10.7 24-24V445.3c18.6-6.6 32-24.4 32-45.3V176c0-26.5-21.5-48-48-48H336c-26.5 0-48 21.5-48 48zm79.8 78.7c3.3-8.7 11.2-14.7 20.5-14.7H539.7c9.2 0 17.2 6 20.5 14.7L576 304H352l15.8-49.3zM568 352a24 24 0 1 1 0 48 24 24 0 1 1 0-48zM336 376a24 24 0 1 1 48 0 24 24 0 1 1 -48 0z" } }, "free": ["solid"] }, "truck-ramp-box": { "aliases": { "names": ["truck-loading"], "unicodes": { "secondary": ["10f4de"] } }, "changes": [ "5.0.9", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "box", "cargo", "delivery", "inventory", "moving", "rental", "vehicle" ] }, "styles": ["solid"], "unicode": "f4de", "label": "Truck Ramp Box", "voted": false, "svg": { "solid": { "last_modified": 1684767650, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M640 0V400c0 61.9-50.1 112-112 112c-61 0-110.5-48.7-112-109.3L48.4 502.9c-17.1 4.6-34.6-5.4-39.3-22.5s5.4-34.6 22.5-39.3L352 353.8V64c0-35.3 28.7-64 64-64H640zM576 400a48 48 0 1 0 -96 0 48 48 0 1 0 96 0zM23.1 207.7c-4.6-17.1 5.6-34.6 22.6-39.2l46.4-12.4 20.7 77.3c2.3 8.5 11.1 13.6 19.6 11.3l30.9-8.3c8.5-2.3 13.6-11.1 11.3-19.6l-20.7-77.3 46.4-12.4c17.1-4.6 34.6 5.6 39.2 22.6l41.4 154.5c4.6 17.1-5.6 34.6-22.6 39.2L103.7 384.9c-17.1 4.6-34.6-5.6-39.2-22.6L23.1 207.7z" } }, "free": ["solid"] }, "tty": { "aliases": { "names": ["teletype"], "unicodes": { "secondary": ["10f1e4"] } }, "changes": [ "4.2.0", "5.0.0", "5.7.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["communication", "deaf", "telephone", "teletypewriter", "text"] }, "styles": ["solid"], "unicode": "f1e4", "label": "Tty", "voted": false, "svg": { "solid": { "last_modified": 1684767390, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M38.3 241.3L15.1 200.6c-9.2-16.2-8.4-36.5 4.5-50C61.4 106.8 144.7 48 256 48s194.6 58.8 236.4 102.6c12.9 13.5 13.7 33.8 4.5 50l-23.1 40.7c-7.5 13.2-23.3 19.3-37.8 14.6l-81.1-26.6c-13.1-4.3-22-16.6-22-30.4V144c-49.6-18.1-104-18.1-153.6 0v54.8c0 13.8-8.9 26.1-22 30.4L76.1 255.8c-14.5 4.7-30.3-1.4-37.8-14.6zM32 336c0-8.8 7.2-16 16-16H80c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H48c-8.8 0-16-7.2-16-16V336zm0 96c0-8.8 7.2-16 16-16H80c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H48c-8.8 0-16-7.2-16-16V432zM144 320h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H144c-8.8 0-16-7.2-16-16V336c0-8.8 7.2-16 16-16zm80 16c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H240c-8.8 0-16-7.2-16-16V336zm112-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H336c-8.8 0-16-7.2-16-16V336c0-8.8 7.2-16 16-16zm80 16c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H432c-8.8 0-16-7.2-16-16V336zm16 80h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H432c-8.8 0-16-7.2-16-16V432c0-8.8 7.2-16 16-16zM128 432c0-8.8 7.2-16 16-16H368c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H144c-8.8 0-16-7.2-16-16V432z" } }, "free": ["solid"] }, "tumblr": { "changes": ["3.2.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f173", "label": "Tumblr", "voted": false, "svg": { "brands": { "last_modified": 1660014460, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M309.8 480.3c-13.6 14.5-50 31.7-97.4 31.7-120.8 0-147-88.8-147-140.6v-144H17.9c-5.5 0-10-4.5-10-10v-68c0-7.2 4.5-13.6 11.3-16 62-21.8 81.5-76 84.3-117.1.8-11 6.5-16.3 16.1-16.3h70.9c5.5 0 10 4.5 10 10v115.2h83c5.5 0 10 4.4 10 9.9v81.7c0 5.5-4.5 10-10 10h-83.4V360c0 34.2 23.7 53.6 68 35.8 4.8-1.9 9-3.2 12.7-2.2 3.5.9 5.8 3.4 7.4 7.9l22 64.3c1.8 5 3.3 10.6-.4 14.5z" } }, "free": ["brands"] }, "turkish-lira-sign": { "aliases": { "names": ["try", "turkish-lira"] }, "changes": ["6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Turkish Lira Sign", "currency"] }, "styles": ["solid"], "unicode": "e2bb", "label": "Turkish Lira Sign", "voted": false, "svg": { "solid": { "last_modified": 1684766474, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M96 32c17.7 0 32 14.3 32 32V99.3L247.2 65.2c17-4.9 34.7 5 39.6 22s-5 34.7-22 39.6L128 165.9v29.4l119.2-34.1c17-4.9 34.7 5 39.6 22s-5 34.7-22 39.6L128 261.9V416h63.8c68.2 0 124.4-53.5 127.8-121.6l.4-8c.9-17.7 15.9-31.2 33.6-30.4s31.2 15.9 30.4 33.6l-.4 8C378.5 399.8 294.1 480 191.8 480H96c-17.7 0-32-14.3-32-32V280.1l-23.2 6.6c-17 4.9-34.7-5-39.6-22s5-34.7 22-39.6L64 213.6V184.1l-23.2 6.6c-17 4.9-34.7-5-39.6-22s5-34.7 22-39.6L64 117.6V64c0-17.7 14.3-32 32-32z" } }, "free": ["solid"] }, "turn-down": { "aliases": { "names": ["level-down-alt"], "unicodes": { "composite": ["2935"], "secondary": ["10f3be"] } }, "changes": ["5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["arrow", "down", "level-down", "right arrow curving down"] }, "styles": ["solid"], "unicode": "f3be", "label": "Turn Down", "voted": false, "svg": { "solid": { "last_modified": 1684766328, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M350 334.5c3.8 8.8 2 19-4.6 26l-136 144c-4.5 4.8-10.8 7.5-17.4 7.5s-12.9-2.7-17.4-7.5l-136-144c-6.6-7-8.4-17.2-4.6-26s12.5-14.5 22-14.5h88l0-192c0-17.7-14.3-32-32-32H32C14.3 96 0 81.7 0 64V32C0 14.3 14.3 0 32 0l80 0c70.7 0 128 57.3 128 128l0 192h88c9.6 0 18.2 5.7 22 14.5z" } }, "free": ["solid"] }, "turn-up": { "aliases": { "names": ["level-up-alt"], "unicodes": { "composite": ["2934"], "secondary": ["10f3bf"] } }, "changes": ["5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["arrow", "level-up", "right arrow curving up"] }, "styles": ["solid"], "unicode": "f3bf", "label": "Turn Up", "voted": false, "svg": { "solid": { "last_modified": 1684766328, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M350 177.5c3.8-8.8 2-19-4.6-26l-136-144C204.9 2.7 198.6 0 192 0s-12.9 2.7-17.4 7.5l-136 144c-6.6 7-8.4 17.2-4.6 26s12.5 14.5 22 14.5h88l0 192c0 17.7-14.3 32-32 32H32c-17.7 0-32 14.3-32 32v32c0 17.7 14.3 32 32 32l80 0c70.7 0 128-57.3 128-128l0-192h88c9.6 0 18.2-5.7 22-14.5z" } }, "free": ["solid"] }, "tv": { "aliases": { "names": ["television", "tv-alt"], "unicodes": { "composite": ["f8e5"], "primary": ["f8e5"], "secondary": ["10f26c", "10f8e5"] } }, "changes": [ "4.4.0", "5.0.0", "5.11.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["computer", "display", "monitor", "television"] }, "styles": ["solid"], "unicode": "f26c", "label": "Tv", "voted": false, "svg": { "solid": { "last_modified": 1684767342, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M64 64V352H576V64H64zM0 64C0 28.7 28.7 0 64 0H576c35.3 0 64 28.7 64 64V352c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V64zM128 448H512c17.7 0 32 14.3 32 32s-14.3 32-32 32H128c-17.7 0-32-14.3-32-32s14.3-32 32-32z" } }, "free": ["solid"] }, "twitch": { "changes": ["4.2.0", "5.0.0", "5.12.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f1e8", "label": "Twitch", "voted": false, "svg": { "brands": { "last_modified": 1660014466, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M391.17,103.47H352.54v109.7h38.63ZM285,103H246.37V212.75H285ZM120.83,0,24.31,91.42V420.58H140.14V512l96.53-91.42h77.25L487.69,256V0ZM449.07,237.75l-77.22,73.12H294.61l-67.6,64v-64H140.14V36.58H449.07Z" } }, "free": ["brands"] }, "twitter": { "changes": ["2.0.0", "5.0.0"], "ligatures": [], "search": { "terms": ["social network", "tweet"] }, "styles": ["brands"], "unicode": "f099", "label": "Twitter", "voted": false, "svg": { "brands": { "last_modified": 1660014461, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z" } }, "free": ["brands"] }, "typo3": { "changes": ["5.0.1", "5.8.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f42b", "label": "Typo3", "voted": false, "svg": { "brands": { "last_modified": 1660014471, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M178.7 78.4c0-24.7 5.4-32.4 13.9-39.4-69.5 8.5-149.3 34-176.3 66.4-5.4 7.7-9.3 20.8-9.3 37.1C7 246 113.8 480 191.1 480c36.3 0 97.3-59.5 146.7-139-7 2.3-11.6 2.3-18.5 2.3-57.2 0-140.6-198.5-140.6-264.9zM301.5 32c-30.1 0-41.7 5.4-41.7 36.3 0 66.4 53.8 198.5 101.7 198.5 26.3 0 78.8-99.7 78.8-182.3 0-40.9-67-52.5-138.8-52.5z" } }, "free": ["brands"] }, "u": { "aliases": { "unicodes": { "composite": ["75"] } }, "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Latin Capital Letter U", "Latin Small Letter U", "letter"] }, "styles": ["solid"], "unicode": "55", "label": "U", "voted": false, "svg": { "solid": { "last_modified": 1684767245, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M32 32c17.7 0 32 14.3 32 32V288c0 70.7 57.3 128 128 128s128-57.3 128-128V64c0-17.7 14.3-32 32-32s32 14.3 32 32V288c0 106-86 192-192 192S0 394 0 288V64C0 46.3 14.3 32 32 32z" } }, "free": ["solid"] }, "uber": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f402", "label": "Uber", "voted": false, "svg": { "brands": { "last_modified": 1660014462, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M414.1 32H33.9C15.2 32 0 47.2 0 65.9V446c0 18.8 15.2 34 33.9 34H414c18.7 0 33.9-15.2 33.9-33.9V65.9C448 47.2 432.8 32 414.1 32zM237.6 391.1C163 398.6 96.4 344.2 88.9 269.6h94.4V290c0 3.7 3 6.8 6.8 6.8H258c3.7 0 6.8-3 6.8-6.8v-67.9c0-3.7-3-6.8-6.8-6.8h-67.9c-3.7 0-6.8 3-6.8 6.8v20.4H88.9c7-69.4 65.4-122.2 135.1-122.2 69.7 0 128.1 52.8 135.1 122.2 7.5 74.5-46.9 141.1-121.5 148.6z" } }, "free": ["brands"] }, "ubuntu": { "changes": ["5.6.0"], "ligatures": [], "search": { "terms": ["linux", "operating system", "os"] }, "styles": ["brands"], "unicode": "f7df", "label": "Ubuntu", "voted": true, "svg": { "brands": { "last_modified": 1660014472, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm52.7 93c8.8-15.2 28.3-20.5 43.5-11.7 15.3 8.8 20.5 28.3 11.7 43.6-8.8 15.2-28.3 20.5-43.5 11.7-15.3-8.9-20.5-28.4-11.7-43.6zM87.4 287.9c-17.6 0-31.9-14.3-31.9-31.9 0-17.6 14.3-31.9 31.9-31.9 17.6 0 31.9 14.3 31.9 31.9 0 17.6-14.3 31.9-31.9 31.9zm28.1 3.1c22.3-17.9 22.4-51.9 0-69.9 8.6-32.8 29.1-60.7 56.5-79.1l23.7 39.6c-51.5 36.3-51.5 112.5 0 148.8L172 370c-27.4-18.3-47.8-46.3-56.5-79zm228.7 131.7c-15.3 8.8-34.7 3.6-43.5-11.7-8.8-15.3-3.6-34.8 11.7-43.6 15.2-8.8 34.7-3.6 43.5 11.7 8.8 15.3 3.6 34.8-11.7 43.6zm.3-69.5c-26.7-10.3-56.1 6.6-60.5 35-5.2 1.4-48.9 14.3-96.7-9.4l22.5-40.3c57 26.5 123.4-11.7 128.9-74.4l46.1.7c-2.3 34.5-17.3 65.5-40.3 88.4zm-5.9-105.3c-5.4-62-71.3-101.2-128.9-74.4l-22.5-40.3c47.9-23.7 91.5-10.8 96.7-9.4 4.4 28.3 33.8 45.3 60.5 35 23.1 22.9 38 53.9 40.2 88.5l-46 .6z" } }, "free": ["brands"] }, "uikit": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f403", "label": "UIkit", "voted": false, "svg": { "brands": { "last_modified": 1660014465, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M443.9 128v256L218 512 0 384V169.7l87.6 45.1v117l133.5 75.5 135.8-75.5v-151l-101.1-57.6 87.6-53.1L443.9 128zM308.6 49.1L223.8 0l-88.6 54.8 86 47.3 87.4-53z" } }, "free": ["brands"] }, "umbraco": { "changes": ["5.11.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f8e8", "label": "Umbraco", "voted": false, "svg": { "brands": { "last_modified": 1660014472, "raw": "", "viewBox": [0, 0, 510, 512], "width": 510, "height": 512, "path": "M255.35 8C118.36 7.83 7.14 118.72 7 255.68c-.07 137 111 248.2 248 248.27 136.85 0 247.82-110.7 248-247.67S392.34 8.17 255.35 8zm145 266q-1.14 40.68-14 65t-43.51 35q-30.61 10.7-85.45 10.47h-4.6q-54.78.22-85.44-10.47t-43.52-35q-12.85-24.36-14-65a224.81 224.81 0 0 1 0-30.71 418.37 418.37 0 0 1 3.6-43.88c1.88-13.39 3.57-22.58 5.4-32 1-4.88 1.28-6.42 1.82-8.45a5.09 5.09 0 0 1 4.9-3.89h.69l32 5a5.07 5.07 0 0 1 4.16 5 5 5 0 0 1 0 .77l-1.7 8.78q-2.41 13.25-4.84 33.68a380.62 380.62 0 0 0-2.64 42.15q-.28 40.43 8.13 59.83a43.87 43.87 0 0 0 31.31 25.18A243 243 0 0 0 250 340.6h10.25a242.64 242.64 0 0 0 57.27-5.16 43.86 43.86 0 0 0 31.15-25.23q8.53-19.42 8.13-59.78a388 388 0 0 0-2.6-42.15q-2.48-20.38-4.89-33.68l-1.69-8.78a5 5 0 0 1 0-.77 5 5 0 0 1 4.2-5l32-5h.82a5 5 0 0 1 4.9 3.89c.55 2.05.81 3.57 1.83 8.45 1.82 9.62 3.52 18.78 5.39 32a415.71 415.71 0 0 1 3.61 43.88 228.06 228.06 0 0 1-.04 30.73z" } }, "free": ["brands"] }, "umbrella": { "aliases": { "unicodes": { "secondary": ["10f0e9"] } }, "changes": ["2.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["protection", "rain", "storm", "wet"] }, "styles": ["solid"], "unicode": "f0e9", "label": "Umbrella", "voted": false, "svg": { "solid": { "last_modified": 1684767661, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M288 0c17.7 0 32 14.3 32 32V49.7C451.8 63.4 557.7 161 573.9 285.9c2 15.6-17.3 24.4-27.8 12.7C532.1 283 504.8 272 480 272c-38.7 0-71 27.5-78.4 64.1c-1.7 8.7-8.7 15.9-17.6 15.9s-15.8-7.2-17.6-15.9C359 299.5 326.7 272 288 272s-71 27.5-78.4 64.1c-1.7 8.7-8.7 15.9-17.6 15.9s-15.8-7.2-17.6-15.9C167 299.5 134.7 272 96 272c-24.8 0-52.1 11-66.1 26.7C19.4 310.4 .1 301.5 2.1 285.9C18.3 161 124.2 63.4 256 49.7V32c0-17.7 14.3-32 32-32zm0 304c12.3 0 23.5 4.6 32 12.2V430.6c0 45-36.5 81.4-81.4 81.4c-30.8 0-59-17.4-72.8-45l-2.3-4.7c-7.9-15.8-1.5-35 14.3-42.9s35-1.5 42.9 14.3l2.3 4.7c3 5.9 9 9.6 15.6 9.6c9.6 0 17.4-7.8 17.4-17.4V316.2c8.5-7.6 19.7-12.2 32-12.2z" } }, "free": ["solid"] }, "umbrella-beach": { "aliases": { "unicodes": { "composite": ["1f3d6"], "secondary": ["10f5ca"] } }, "changes": ["5.1.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "beach", "beach with umbrella", "protection", "recreation", "sand", "shade", "summer", "sun", "umbrella" ] }, "styles": ["solid"], "unicode": "f5ca", "label": "Umbrella Beach", "voted": false, "svg": { "solid": { "last_modified": 1684767662, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M346.3 271.8l-60.1-21.9L214 448H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H544c17.7 0 32-14.3 32-32s-14.3-32-32-32H282.1l64.1-176.2zm121.1-.2l-3.3 9.1 67.7 24.6c18.1 6.6 38-4.2 39.6-23.4c6.5-78.5-23.9-155.5-80.8-208.5c2 8 3.2 16.3 3.4 24.8l.2 6c1.8 57-7.3 113.8-26.8 167.4zM462 99.1c-1.1-34.4-22.5-64.8-54.4-77.4c-.9-.4-1.9-.7-2.8-1.1c-33-11.7-69.8-2.4-93.1 23.8l-4 4.5C272.4 88.3 245 134.2 226.8 184l-3.3 9.1L434 269.7l3.3-9.1c18.1-49.8 26.6-102.5 24.9-155.5l-.2-6zM107.2 112.9c-11.1 15.7-2.8 36.8 15.3 43.4l71 25.8 3.3-9.1c19.5-53.6 49.1-103 87.1-145.5l4-4.5c6.2-6.9 13.1-13 20.5-18.2c-79.6 2.5-154.7 42.2-201.2 108z" } }, "free": ["solid"] }, "uncharted": { "changes": ["5.15.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e084", "label": "Uncharted Software", "voted": false, "svg": { "brands": { "last_modified": 1660014476, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M171.73,232.813A5.381,5.381,0,0,0,176.7,229.5,48.081,48.081,0,0,1,191.6,204.244c1.243-.828,1.657-2.484,1.657-4.141a4.22,4.22,0,0,0-2.071-3.312L74.429,128.473,148.958,85a9.941,9.941,0,0,0,4.968-8.281,9.108,9.108,0,0,0-4.968-8.281L126.6,55.6a9.748,9.748,0,0,0-9.523,0l-100.2,57.966a9.943,9.943,0,0,0-4.969,8.281V236.954a9.109,9.109,0,0,0,4.969,8.281L39.235,258.07a8.829,8.829,0,0,0,4.968,1.242,9.4,9.4,0,0,0,6.625-2.484,10.8,10.8,0,0,0,2.9-7.039V164.5L169.66,232.4A4.5,4.5,0,0,0,171.73,232.813ZM323.272,377.73a12.478,12.478,0,0,0-4.969,1.242l-74.528,43.062V287.882c0-2.9-2.9-5.8-6.211-4.555a53.036,53.036,0,0,1-28.984.414,4.86,4.86,0,0,0-6.21,4.555V421.619l-74.529-43.061a8.83,8.83,0,0,0-4.969-1.242,9.631,9.631,0,0,0-9.523,9.523v26.085a9.107,9.107,0,0,0,4.969,8.281l100.2,57.553A8.829,8.829,0,0,0,223.486,480a11.027,11.027,0,0,0,4.969-1.242l100.2-57.553a9.941,9.941,0,0,0,4.968-8.281V386.839C332.8,382.285,328.24,377.73,323.272,377.73ZM286.007,78a23,23,0,1,0-23-23A23,23,0,0,0,286.007,78Zm63.627-10.086a23,23,0,1,0,23,23A23,23,0,0,0,349.634,67.914ZM412.816,151.6a23,23,0,1,0-23-23A23,23,0,0,0,412.816,151.6Zm-63.182-9.2a23,23,0,1,0,23,23A23,23,0,0,0,349.634,142.4Zm-63.627,83.244a23,23,0,1,0-23-23A23,23,0,0,0,286.007,225.648Zm-62.074,36.358a23,23,0,1,0-23-23A23,23,0,0,0,223.933,262.006Zm188.883-82.358a23,23,0,1,0,23,23A23,23,0,0,0,412.816,179.648Zm0,72.272a23,23,0,1,0,23,23A23,23,0,0,0,412.816,251.92Z" } }, "free": ["brands"] }, "underline": { "aliases": { "unicodes": { "secondary": ["10f0cd"] } }, "changes": [ "2.0.0", "5.0.0", "5.9.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["edit", "emphasis", "format", "text", "writing"] }, "styles": ["solid"], "unicode": "f0cd", "label": "Underline", "voted": false, "svg": { "solid": { "last_modified": 1684767247, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M16 64c0-17.7 14.3-32 32-32h96c17.7 0 32 14.3 32 32s-14.3 32-32 32H128V224c0 53 43 96 96 96s96-43 96-96V96H304c-17.7 0-32-14.3-32-32s14.3-32 32-32h96c17.7 0 32 14.3 32 32s-14.3 32-32 32H384V224c0 88.4-71.6 160-160 160s-160-71.6-160-160V96H48C30.3 96 16 81.7 16 64zM0 448c0-17.7 14.3-32 32-32H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32-14.3-32-32z" } }, "free": ["solid"] }, "uniregistry": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f404", "label": "Uniregistry", "voted": false, "svg": { "brands": { "last_modified": 1660014466, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M192 480c39.5 0 76.2-11.8 106.8-32.2H85.3C115.8 468.2 152.5 480 192 480zm-89.1-193.1v-12.4H0v12.4c0 2.5 0 5 .1 7.4h103.1c-.2-2.4-.3-4.9-.3-7.4zm20.5 57H8.5c2.6 8.5 5.8 16.8 9.6 24.8h138.3c-12.9-5.7-24.1-14.2-33-24.8zm-17.7-34.7H1.3c.9 7.6 2.2 15 3.9 22.3h109.7c-4-6.9-7.2-14.4-9.2-22.3zm-2.8-69.3H0v17.3h102.9zm0-173.2H0v4.9h102.9zm0-34.7H0v2.5h102.9zm0 69.3H0v7.4h102.9zm0 104H0v14.8h102.9zm0-69.3H0v9.9h102.9zm0 34.6H0V183h102.9zm166.2 160.9h109.7c1.8-7.3 3.1-14.7 3.9-22.3H278.3c-2.1 7.9-5.2 15.4-9.2 22.3zm12-185.7H384V136H281.1zm0 37.2H384v-12.4H281.1zm0-74.3H384v-7.4H281.1zm0-76.7v2.5H384V32zm-203 410.9h227.7c11.8-8.7 22.7-18.6 32.2-29.7H44.9c9.6 11 21.4 21 33.2 29.7zm203-371.3H384v-4.9H281.1zm0 148.5H384v-14.8H281.1zM38.8 405.7h305.3c6.7-8.5 12.6-17.6 17.8-27.2H23c5.2 9.6 9.2 18.7 15.8 27.2zm188.8-37.1H367c3.7-8 5.8-16.2 8.5-24.8h-115c-8.8 10.7-20.1 19.2-32.9 24.8zm53.5-81.7c0 2.5-.1 5-.4 7.4h103.1c.1-2.5.2-4.9.2-7.4v-12.4H281.1zm0-29.7H384v-17.3H281.1z" } }, "free": ["brands"] }, "unity": { "changes": ["5.12.0", "5.14.0", "6.0.0-beta3"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e049", "label": "Unity 3D", "voted": true, "svg": { "brands": { "last_modified": 1660014481, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M243.583 91.6027L323.695 138.384C326.575 140.026 326.68 144.583 323.695 146.225L228.503 201.854C225.623 203.55 222.22 203.444 219.549 201.854L124.357 146.225C121.425 144.636 121.373 139.973 124.357 138.384L204.417 91.6027V0L0 119.417V358.252L78.3843 312.477V218.914C78.3319 215.576 82.2066 213.192 85.0865 214.993L180.279 270.622C183.159 272.318 184.782 275.338 184.782 278.464V389.669C184.834 393.007 180.959 395.391 178.079 393.589L97.9673 346.808L19.583 392.583L224 512L428.417 392.583L350.033 346.808L269.921 393.589C267.093 395.338 263.114 393.06 263.218 389.669V278.464C263.218 275.126 265.051 272.159 267.721 270.622L362.914 214.993C365.741 213.245 369.72 215.47 369.616 218.914V312.477L448 358.252V119.417L243.583 0V91.6027Z" } }, "free": ["brands"] }, "universal-access": { "aliases": { "unicodes": { "secondary": ["10f29a"] } }, "changes": [ "4.6.0", "5.0.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["users-people"] }, "styles": ["solid"], "unicode": "f29a", "label": "Universal Access", "voted": false, "svg": { "solid": { "last_modified": 1684767620, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 256a256 256 0 1 1 512 0A256 256 0 1 1 0 256zm161.5-86.1c-12.2-5.2-26.3 .4-31.5 12.6s.4 26.3 12.6 31.5l11.9 5.1c17.3 7.4 35.2 12.9 53.6 16.3v50.1c0 4.3-.7 8.6-2.1 12.6l-28.7 86.1c-4.2 12.6 2.6 26.2 15.2 30.4s26.2-2.6 30.4-15.2l24.4-73.2c1.3-3.8 4.8-6.4 8.8-6.4s7.6 2.6 8.8 6.4l24.4 73.2c4.2 12.6 17.8 19.4 30.4 15.2s19.4-17.8 15.2-30.4l-28.7-86.1c-1.4-4.1-2.1-8.3-2.1-12.6V235.5c18.4-3.5 36.3-8.9 53.6-16.3l11.9-5.1c12.2-5.2 17.8-19.3 12.6-31.5s-19.3-17.8-31.5-12.6L338.7 175c-26.1 11.2-54.2 17-82.7 17s-56.5-5.8-82.7-17l-11.9-5.1zM256 160a40 40 0 1 0 0-80 40 40 0 1 0 0 80z" } }, "free": ["solid"] }, "unlock": { "aliases": { "unicodes": { "composite": ["1f513"], "secondary": ["10f09c"] } }, "changes": [ "2.0.0", "5.0.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "admin", "lock", "open", "password", "private", "protect", "unlock", "unlocked" ] }, "styles": ["solid"], "unicode": "f09c", "label": "Unlock", "voted": false, "svg": { "solid": { "last_modified": 1684767368, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M144 144c0-44.2 35.8-80 80-80c31.9 0 59.4 18.6 72.3 45.7c7.6 16 26.7 22.8 42.6 15.2s22.8-26.7 15.2-42.6C331 33.7 281.5 0 224 0C144.5 0 80 64.5 80 144v48H64c-35.3 0-64 28.7-64 64V448c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V256c0-35.3-28.7-64-64-64H144V144z" } }, "free": ["solid"] }, "unlock-keyhole": { "aliases": { "names": ["unlock-alt"], "unicodes": { "secondary": ["10f13e"] } }, "changes": [ "3.1.0", "5.0.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["admin", "lock", "password", "private", "protect"] }, "styles": ["solid"], "unicode": "f13e", "label": "Unlock Keyhole", "voted": false, "svg": { "solid": { "last_modified": 1684767368, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M224 64c-44.2 0-80 35.8-80 80v48H384c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V256c0-35.3 28.7-64 64-64H80V144C80 64.5 144.5 0 224 0c57.5 0 107 33.7 130.1 82.3c7.6 16 .8 35.1-15.2 42.6s-35.1 .8-42.6-15.2C283.4 82.6 255.9 64 224 64zm32 320c17.7 0 32-14.3 32-32s-14.3-32-32-32H192c-17.7 0-32 14.3-32 32s14.3 32 32 32h64z" } }, "free": ["solid"] }, "unsplash": { "changes": ["5.13.1", "5.14.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e07c", "label": "Unsplash", "voted": false, "svg": { "brands": { "last_modified": 1660014474, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M448,230.17V480H0V230.17H141.13V355.09H306.87V230.17ZM306.87,32H141.13V156.91H306.87Z" } }, "free": ["brands"] }, "untappd": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f405", "label": "Untappd", "voted": false, "svg": { "brands": { "last_modified": 1660014481, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M401.3 49.9c-79.8 160.1-84.6 152.5-87.9 173.2l-5.2 32.8c-1.9 12-6.6 23.5-13.7 33.4L145.6 497.1c-7.6 10.6-20.4 16.2-33.4 14.6-40.3-5-77.8-32.2-95.3-68.5-5.7-11.8-4.5-25.8 3.1-36.4l148.9-207.9c7.1-9.9 16.4-18 27.2-23.7l29.3-15.5c18.5-9.8 9.7-11.9 135.6-138.9 1-4.8 1-7.3 3.6-8 3-.7 6.6-1 6.3-4.6l-.4-4.6c-.2-1.9 1.3-3.6 3.2-3.6 4.5-.1 13.2 1.2 25.6 10 12.3 8.9 16.4 16.8 17.7 21.1.6 1.8-.6 3.7-2.4 4.2l-4.5 1.1c-3.4.9-2.5 4.4-2.3 7.4.1 2.8-2.3 3.6-6.5 6.1zM230.1 36.4c3.4.9 2.5 4.4 2.3 7.4-.2 2.7 2.1 3.5 6.4 6 7.9 15.9 15.3 30.5 22.2 44 .7 1.3 2.3 1.5 3.3.5 11.2-12 24.6-26.2 40.5-42.6 1.3-1.4 1.4-3.5.1-4.9-8-8.2-16.5-16.9-25.6-26.1-1-4.7-1-7.3-3.6-8-3-.8-6.6-1-6.3-4.6.3-3.3 1.4-8.1-2.8-8.2-4.5-.1-13.2 1.1-25.6 10-12.3 8.9-16.4 16.8-17.7 21.1-1.4 4.2 3.6 4.6 6.8 5.4zM620 406.7L471.2 198.8c-13.2-18.5-26.6-23.4-56.4-39.1-11.2-5.9-14.2-10.9-30.5-28.9-1-1.1-2.9-.9-3.6.5-46.3 88.8-47.1 82.8-49 94.8-1.7 10.7-1.3 20 .3 29.8 1.9 12 6.6 23.5 13.7 33.4l148.9 207.9c7.6 10.6 20.2 16.2 33.1 14.7 40.3-4.9 78-32 95.7-68.6 5.4-11.9 4.3-25.9-3.4-36.6z" } }, "free": ["brands"] }, "up-down": { "aliases": { "names": ["arrows-alt-v"], "unicodes": { "composite": ["2195", "2b0d"], "secondary": ["10f338"] } }, "changes": ["5.0.0", "5.11.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "Up Down Black Arrow", "arrow", "arrows-v", "expand", "portrait", "resize", "tall", "up-down arrow", "vertical" ] }, "styles": ["solid"], "unicode": "f338", "label": "Up Down", "voted": false, "svg": { "solid": { "last_modified": 1684766328, "raw": "", "viewBox": [0, 0, 256, 512], "width": 256, "height": 512, "path": "M145.6 7.7C141 2.8 134.7 0 128 0s-13 2.8-17.6 7.7l-104 112c-6.5 7-8.2 17.2-4.4 25.9S14.5 160 24 160H80V352H24c-9.5 0-18.2 5.7-22 14.4s-2.1 18.9 4.4 25.9l104 112c4.5 4.9 10.9 7.7 17.6 7.7s13-2.8 17.6-7.7l104-112c6.5-7 8.2-17.2 4.4-25.9s-12.5-14.4-22-14.4H176V160h56c9.5 0 18.2-5.7 22-14.4s2.1-18.9-4.4-25.9l-104-112z" } }, "free": ["solid"] }, "up-down-left-right": { "aliases": { "names": ["arrows-alt"], "unicodes": { "secondary": ["10f0b2"] } }, "changes": ["2.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "arrow", "arrows", "bigger", "enlarge", "expand", "fullscreen", "move", "position", "reorder", "resize" ] }, "styles": ["solid"], "unicode": "f0b2", "label": "Up Down Left Right", "voted": false, "svg": { "solid": { "last_modified": 1684766330, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M278.6 9.4c-12.5-12.5-32.8-12.5-45.3 0l-64 64c-9.2 9.2-11.9 22.9-6.9 34.9s16.6 19.8 29.6 19.8h32v96H128V192c0-12.9-7.8-24.6-19.8-29.6s-25.7-2.2-34.9 6.9l-64 64c-12.5 12.5-12.5 32.8 0 45.3l64 64c9.2 9.2 22.9 11.9 34.9 6.9s19.8-16.6 19.8-29.6V288h96v96H192c-12.9 0-24.6 7.8-29.6 19.8s-2.2 25.7 6.9 34.9l64 64c12.5 12.5 32.8 12.5 45.3 0l64-64c9.2-9.2 11.9-22.9 6.9-34.9s-16.6-19.8-29.6-19.8H288V288h96v32c0 12.9 7.8 24.6 19.8 29.6s25.7 2.2 34.9-6.9l64-64c12.5-12.5 12.5-32.8 0-45.3l-64-64c-9.2-9.2-22.9-11.9-34.9-6.9s-19.8 16.6-19.8 29.6v32H288V128h32c12.9 0 24.6-7.8 29.6-19.8s2.2-25.7-6.9-34.9l-64-64z" } }, "free": ["solid"] }, "up-long": { "aliases": { "names": ["long-arrow-alt-up"], "unicodes": { "secondary": ["10f30c"] } }, "changes": ["5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["long-arrow-up", "upload"] }, "styles": ["solid"], "unicode": "f30c", "label": "Up Long", "voted": false, "svg": { "solid": { "last_modified": 1684766329, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M318 177.5c3.8-8.8 2-19-4.6-26l-136-144C172.9 2.7 166.6 0 160 0s-12.9 2.7-17.4 7.5l-136 144c-6.6 7-8.4 17.2-4.6 26S14.4 192 24 192H96l0 288c0 17.7 14.3 32 32 32h64c17.7 0 32-14.3 32-32l0-288h72c9.6 0 18.2-5.7 22-14.5z" } }, "free": ["solid"] }, "up-right-and-down-left-from-center": { "aliases": { "names": ["expand-alt"], "unicodes": { "secondary": ["10f424"] } }, "changes": [ "1.0.0", "5.0.0", "5.12.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["arrows", "bigger", "enlarge", "fullscreen", "resize"] }, "styles": ["solid"], "unicode": "f424", "label": "Up Right And Down Left From Center", "voted": false, "svg": { "solid": { "last_modified": 1684766328, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M344 0H488c13.3 0 24 10.7 24 24V168c0 9.7-5.8 18.5-14.8 22.2s-19.3 1.7-26.2-5.2l-39-39-87 87c-9.4 9.4-24.6 9.4-33.9 0l-32-32c-9.4-9.4-9.4-24.6 0-33.9l87-87L327 41c-6.9-6.9-8.9-17.2-5.2-26.2S334.3 0 344 0zM168 512H24c-13.3 0-24-10.7-24-24V344c0-9.7 5.8-18.5 14.8-22.2s19.3-1.7 26.2 5.2l39 39 87-87c9.4-9.4 24.6-9.4 33.9 0l32 32c9.4 9.4 9.4 24.6 0 33.9l-87 87 39 39c6.9 6.9 8.9 17.2 5.2 26.2s-12.5 14.8-22.2 14.8z" } }, "free": ["solid"] }, "up-right-from-square": { "aliases": { "names": ["external-link-alt"], "unicodes": { "secondary": ["10f35d"] } }, "changes": [ "5.0.0", "5.11.0", "6.0.0-beta1", "6.2.0", "6.2.1", "6.3.0", "6.4.0", "6.4.1" ], "ligatures": [], "search": { "terms": ["external-link", "new", "open", "share"] }, "styles": ["solid"], "unicode": "f35d", "label": "Up Right From Square", "voted": false, "svg": { "solid": { "last_modified": 1684766330, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M352 0c-12.9 0-24.6 7.8-29.6 19.8s-2.2 25.7 6.9 34.9L370.7 96 201.4 265.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L416 141.3l41.4 41.4c9.2 9.2 22.9 11.9 34.9 6.9s19.8-16.6 19.8-29.6V32c0-17.7-14.3-32-32-32H352zM80 32C35.8 32 0 67.8 0 112V432c0 44.2 35.8 80 80 80H400c44.2 0 80-35.8 80-80V320c0-17.7-14.3-32-32-32s-32 14.3-32 32V432c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V112c0-8.8 7.2-16 16-16H192c17.7 0 32-14.3 32-32s-14.3-32-32-32H80z" } }, "free": ["solid"] }, "upload": { "aliases": { "unicodes": { "secondary": ["10f093"] } }, "changes": ["1.0.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["hard drive", "import", "publish"] }, "styles": ["solid"], "unicode": "f093", "label": "Upload", "voted": false, "svg": { "solid": { "last_modified": 1684767342, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M288 109.3V352c0 17.7-14.3 32-32 32s-32-14.3-32-32V109.3l-73.4 73.4c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3l128-128c12.5-12.5 32.8-12.5 45.3 0l128 128c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L288 109.3zM64 352H192c0 35.3 28.7 64 64 64s64-28.7 64-64H448c35.3 0 64 28.7 64 64v32c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V416c0-35.3 28.7-64 64-64zM432 456a24 24 0 1 0 0-48 24 24 0 1 0 0 48z" } }, "free": ["solid"] }, "ups": { "changes": ["5.6.0", "5.8.0"], "ligatures": [], "search": { "terms": ["United Parcel Service", "package", "shipping"] }, "styles": ["brands"], "unicode": "f7e0", "label": "UPS", "voted": false, "svg": { "brands": { "last_modified": 1660014482, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M103.2 303c-5.2 3.6-32.6 13.1-32.6-19V180H37.9v102.6c0 74.9 80.2 51.1 97.9 39V180h-32.6zM4 74.82v220.9c0 103.7 74.9 135.2 187.7 184.1 112.4-48.9 187.7-80.2 187.7-184.1V74.82c-116.3-61.6-281.8-49.6-375.4 0zm358.1 220.9c0 86.6-53.2 113.6-170.4 165.3-117.5-51.8-170.5-78.7-170.5-165.3v-126.4c102.3-93.8 231.6-100 340.9-89.8zm-209.6-107.4v212.8h32.7v-68.7c24.4 7.3 71.7-2.6 71.7-78.5 0-97.4-80.7-80.92-104.4-65.6zm32.7 117.3v-100.3c8.4-4.2 38.4-12.7 38.4 49.3 0 67.9-36.4 51.8-38.4 51zm79.1-86.4c.1 47.3 51.6 42.5 52.2 70.4.6 23.5-30.4 23-50.8 4.9v30.1c36.2 21.5 81.9 8.1 83.2-33.5 1.7-51.5-54.1-46.6-53.4-73.2.6-20.3 30.6-20.5 48.5-2.2v-28.4c-28.5-22-79.9-9.2-79.7 31.9z" } }, "free": ["brands"] }, "usb": { "changes": ["4.5.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f287", "label": "USB", "voted": false, "svg": { "brands": { "last_modified": 1660014460, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M641.5 256c0 3.1-1.7 6.1-4.5 7.5L547.9 317c-1.4.8-2.8 1.4-4.5 1.4-1.4 0-3.1-.3-4.5-1.1-2.8-1.7-4.5-4.5-4.5-7.8v-35.6H295.7c25.3 39.6 40.5 106.9 69.6 106.9H392V354c0-5 3.9-8.9 8.9-8.9H490c5 0 8.9 3.9 8.9 8.9v89.1c0 5-3.9 8.9-8.9 8.9h-89.1c-5 0-8.9-3.9-8.9-8.9v-26.7h-26.7c-75.4 0-81.1-142.5-124.7-142.5H140.3c-8.1 30.6-35.9 53.5-69 53.5C32 327.3 0 295.3 0 256s32-71.3 71.3-71.3c33.1 0 61 22.8 69 53.5 39.1 0 43.9 9.5 74.6-60.4C255 88.7 273 95.7 323.8 95.7c7.5-20.9 27-35.6 50.4-35.6 29.5 0 53.5 23.9 53.5 53.5s-23.9 53.5-53.5 53.5c-23.4 0-42.9-14.8-50.4-35.6H294c-29.1 0-44.3 67.4-69.6 106.9h310.1v-35.6c0-3.3 1.7-6.1 4.5-7.8 2.8-1.7 6.4-1.4 8.9.3l89.1 53.5c2.8 1.1 4.5 4.1 4.5 7.2z" } }, "free": ["brands"] }, "user": { "aliases": { "unicodes": { "composite": ["1f464", "f2c0"], "secondary": ["10f007"] } }, "changes": [ "1.0.0", "5.0.0", "5.0.3", "5.0.11", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "adult", "bust", "bust in silhouette", "gender-neutral", "person", "profile", "silhouette", "unspecified gender", "users-people" ] }, "styles": ["solid", "regular"], "unicode": "f007", "label": "User", "voted": false, "svg": { "solid": { "last_modified": 1684767621, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M224 256A128 128 0 1 0 224 0a128 128 0 1 0 0 256zm-45.7 48C79.8 304 0 383.8 0 482.3C0 498.7 13.3 512 29.7 512H418.3c16.4 0 29.7-13.3 29.7-29.7C448 383.8 368.2 304 269.7 304H178.3z" }, "regular": { "last_modified": 1684767621, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M304 128a80 80 0 1 0 -160 0 80 80 0 1 0 160 0zM96 128a128 128 0 1 1 256 0A128 128 0 1 1 96 128zM49.3 464H398.7c-8.9-63.3-63.3-112-129-112H178.3c-65.7 0-120.1 48.7-129 112zM0 482.3C0 383.8 79.8 304 178.3 304h91.4C368.2 304 448 383.8 448 482.3c0 16.4-13.3 29.7-29.7 29.7H29.7C13.3 512 0 498.7 0 482.3z" } }, "free": ["regular", "solid"] }, "user-astronaut": { "aliases": { "unicodes": { "secondary": ["10f4fb"] } }, "changes": ["5.0.11", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["avatar", "clothing", "cosmonaut", "nasa", "space", "suit"] }, "styles": ["solid"], "unicode": "f4fb", "label": "User Astronaut", "voted": false, "svg": { "solid": { "last_modified": 1684767620, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M370.7 96.1C346.1 39.5 289.7 0 224 0S101.9 39.5 77.3 96.1C60.9 97.5 48 111.2 48 128v64c0 16.8 12.9 30.5 29.3 31.9C101.9 280.5 158.3 320 224 320s122.1-39.5 146.7-96.1c16.4-1.4 29.3-15.1 29.3-31.9V128c0-16.8-12.9-30.5-29.3-31.9zM336 144v16c0 53-43 96-96 96H208c-53 0-96-43-96-96V144c0-26.5 21.5-48 48-48H288c26.5 0 48 21.5 48 48zM189.3 162.7l-6-21.2c-.9-3.3-3.9-5.5-7.3-5.5s-6.4 2.2-7.3 5.5l-6 21.2-21.2 6c-3.3 .9-5.5 3.9-5.5 7.3s2.2 6.4 5.5 7.3l21.2 6 6 21.2c.9 3.3 3.9 5.5 7.3 5.5s6.4-2.2 7.3-5.5l6-21.2 21.2-6c3.3-.9 5.5-3.9 5.5-7.3s-2.2-6.4-5.5-7.3l-21.2-6zM112.7 316.5C46.7 342.6 0 407 0 482.3C0 498.7 13.3 512 29.7 512H128V448c0-17.7 14.3-32 32-32H288c17.7 0 32 14.3 32 32v64l98.3 0c16.4 0 29.7-13.3 29.7-29.7c0-75.3-46.7-139.7-112.7-165.8C303.9 338.8 265.5 352 224 352s-79.9-13.2-111.3-35.5zM176 448c-8.8 0-16 7.2-16 16v48h32V464c0-8.8-7.2-16-16-16zm96 32a16 16 0 1 0 0-32 16 16 0 1 0 0 32z" } }, "free": ["solid"] }, "user-check": { "aliases": { "unicodes": { "secondary": ["10f4fc"] } }, "changes": ["5.0.11", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["users-people"] }, "styles": ["solid"], "unicode": "f4fc", "label": "User Check", "voted": false, "svg": { "solid": { "last_modified": 1684767621, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M96 128a128 128 0 1 1 256 0A128 128 0 1 1 96 128zM0 482.3C0 383.8 79.8 304 178.3 304h91.4C368.2 304 448 383.8 448 482.3c0 16.4-13.3 29.7-29.7 29.7H29.7C13.3 512 0 498.7 0 482.3zM625 177L497 305c-9.4 9.4-24.6 9.4-33.9 0l-64-64c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l47 47L591 143c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9z" } }, "free": ["solid"] }, "user-clock": { "aliases": { "unicodes": { "secondary": ["10f4fd"] } }, "changes": ["5.0.11", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["users-people"] }, "styles": ["solid"], "unicode": "f4fd", "label": "User Clock", "voted": false, "svg": { "solid": { "last_modified": 1684767619, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M224 0a128 128 0 1 1 0 256A128 128 0 1 1 224 0zM178.3 304h91.4c20.6 0 40.4 3.5 58.8 9.9C323 331 320 349.1 320 368c0 59.5 29.5 112.1 74.8 144H29.7C13.3 512 0 498.7 0 482.3C0 383.8 79.8 304 178.3 304zM352 368a144 144 0 1 1 288 0 144 144 0 1 1 -288 0zm144-80c-8.8 0-16 7.2-16 16v64c0 8.8 7.2 16 16 16h48c8.8 0 16-7.2 16-16s-7.2-16-16-16H512V304c0-8.8-7.2-16-16-16z" } }, "free": ["solid"] }, "user-doctor": { "aliases": { "names": ["user-md"], "unicodes": { "secondary": ["10f0f0"] } }, "changes": [ "2.0.0", "5.0.0", "5.0.3", "5.0.7", "5.0.11", "6.0.0-beta1", "6.0.0-beta2", "6.1.2", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "covid-19", "health", "job", "medical", "nurse", "occupation", "physician", "profile", "surgeon", "worker" ] }, "styles": ["solid"], "unicode": "f0f0", "label": "User Doctor", "voted": false, "svg": { "solid": { "last_modified": 1684767620, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M224 256A128 128 0 1 0 224 0a128 128 0 1 0 0 256zm-96 55.2C54 332.9 0 401.3 0 482.3C0 498.7 13.3 512 29.7 512H418.3c16.4 0 29.7-13.3 29.7-29.7c0-81-54-149.4-128-171.1V362c27.6 7.1 48 32.2 48 62v40c0 8.8-7.2 16-16 16H336c-8.8 0-16-7.2-16-16s7.2-16 16-16V424c0-17.7-14.3-32-32-32s-32 14.3-32 32v24c8.8 0 16 7.2 16 16s-7.2 16-16 16H256c-8.8 0-16-7.2-16-16V424c0-29.8 20.4-54.9 48-62V304.9c-6-.6-12.1-.9-18.3-.9H178.3c-6.2 0-12.3 .3-18.3 .9v65.4c23.1 6.9 40 28.3 40 53.7c0 30.9-25.1 56-56 56s-56-25.1-56-56c0-25.4 16.9-46.8 40-53.7V311.2zM144 448a24 24 0 1 0 0-48 24 24 0 1 0 0 48z" } }, "free": ["solid"] }, "user-gear": { "aliases": { "names": ["user-cog"], "unicodes": { "secondary": ["10f4fe"] } }, "changes": ["5.0.11", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["users-people"] }, "styles": ["solid"], "unicode": "f4fe", "label": "User Gear", "voted": false, "svg": { "solid": { "last_modified": 1684767620, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M224 0a128 128 0 1 1 0 256A128 128 0 1 1 224 0zM178.3 304h91.4c11.8 0 23.4 1.2 34.5 3.3c-2.1 18.5 7.4 35.6 21.8 44.8c-16.6 10.6-26.7 31.6-20 53.3c4 12.9 9.4 25.5 16.4 37.6s15.2 23.1 24.4 33c15.7 16.9 39.6 18.4 57.2 8.7v.9c0 9.2 2.7 18.5 7.9 26.3H29.7C13.3 512 0 498.7 0 482.3C0 383.8 79.8 304 178.3 304zM436 218.2c0-7 4.5-13.3 11.3-14.8c10.5-2.4 21.5-3.7 32.7-3.7s22.2 1.3 32.7 3.7c6.8 1.5 11.3 7.8 11.3 14.8v30.6c7.9 3.4 15.4 7.7 22.3 12.8l24.9-14.3c6.1-3.5 13.7-2.7 18.5 2.4c7.6 8.1 14.3 17.2 20.1 27.2s10.3 20.4 13.5 31c2.1 6.7-1.1 13.7-7.2 17.2l-25 14.4c.4 4 .7 8.1 .7 12.3s-.2 8.2-.7 12.3l25 14.4c6.1 3.5 9.2 10.5 7.2 17.2c-3.3 10.6-7.8 21-13.5 31s-12.5 19.1-20.1 27.2c-4.8 5.1-12.5 5.9-18.5 2.4l-24.9-14.3c-6.9 5.1-14.3 9.4-22.3 12.8l0 30.6c0 7-4.5 13.3-11.3 14.8c-10.5 2.4-21.5 3.7-32.7 3.7s-22.2-1.3-32.7-3.7c-6.8-1.5-11.3-7.8-11.3-14.8V454.8c-8-3.4-15.6-7.7-22.5-12.9l-24.7 14.3c-6.1 3.5-13.7 2.7-18.5-2.4c-7.6-8.1-14.3-17.2-20.1-27.2s-10.3-20.4-13.5-31c-2.1-6.7 1.1-13.7 7.2-17.2l24.8-14.3c-.4-4.1-.7-8.2-.7-12.4s.2-8.3 .7-12.4L343.8 325c-6.1-3.5-9.2-10.5-7.2-17.2c3.3-10.6 7.7-21 13.5-31s12.5-19.1 20.1-27.2c4.8-5.1 12.4-5.9 18.5-2.4l24.8 14.3c6.9-5.1 14.5-9.4 22.5-12.9V218.2zm92.1 133.5a48.1 48.1 0 1 0 -96.1 0 48.1 48.1 0 1 0 96.1 0z" } }, "free": ["solid"] }, "user-graduate": { "aliases": { "unicodes": { "secondary": ["10f501"] } }, "changes": ["5.0.11", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["users-people"] }, "styles": ["solid"], "unicode": "f501", "label": "User Graduate", "voted": false, "svg": { "solid": { "last_modified": 1684767620, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M219.3 .5c3.1-.6 6.3-.6 9.4 0l200 40C439.9 42.7 448 52.6 448 64s-8.1 21.3-19.3 23.5L352 102.9V160c0 70.7-57.3 128-128 128s-128-57.3-128-128V102.9L48 93.3v65.1l15.7 78.4c.9 4.7-.3 9.6-3.3 13.3s-7.6 5.9-12.4 5.9H16c-4.8 0-9.3-2.1-12.4-5.9s-4.3-8.6-3.3-13.3L16 158.4V86.6C6.5 83.3 0 74.3 0 64C0 52.6 8.1 42.7 19.3 40.5l200-40zM111.9 327.7c10.5-3.4 21.8 .4 29.4 8.5l71 75.5c6.3 6.7 17 6.7 23.3 0l71-75.5c7.6-8.1 18.9-11.9 29.4-8.5C401 348.6 448 409.4 448 481.3c0 17-13.8 30.7-30.7 30.7H30.7C13.8 512 0 498.2 0 481.3c0-71.9 47-132.7 111.9-153.6z" } }, "free": ["solid"] }, "user-group": { "aliases": { "names": ["user-friends"], "unicodes": { "composite": ["1f465"], "secondary": ["10f500"] } }, "changes": ["5.0.11", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["bust", "busts in silhouette", "silhouette", "users-people"] }, "styles": ["solid"], "unicode": "f500", "label": "User Group", "voted": false, "svg": { "solid": { "last_modified": 1684767621, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M96 128a128 128 0 1 1 256 0A128 128 0 1 1 96 128zM0 482.3C0 383.8 79.8 304 178.3 304h91.4C368.2 304 448 383.8 448 482.3c0 16.4-13.3 29.7-29.7 29.7H29.7C13.3 512 0 498.7 0 482.3zM609.3 512H471.4c5.4-9.4 8.6-20.3 8.6-32v-8c0-60.7-27.1-115.2-69.8-151.8c2.4-.1 4.7-.2 7.1-.2h61.4C567.8 320 640 392.2 640 481.3c0 17-13.8 30.7-30.7 30.7zM432 256c-31 0-59-12.6-79.3-32.9C372.4 196.5 384 163.6 384 128c0-26.8-6.6-52.1-18.3-74.3C384.3 40.1 407.2 32 432 32c61.9 0 112 50.1 112 112s-50.1 112-112 112z" } }, "free": ["solid"] }, "user-injured": { "aliases": { "unicodes": { "secondary": ["10f728"] } }, "changes": ["5.4.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["users-people"] }, "styles": ["solid"], "unicode": "f728", "label": "User Injured", "voted": false, "svg": { "solid": { "last_modified": 1684767619, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M240 80H342.7c-7.9-19.5-20.4-36.5-36.2-49.9L240 80zm37.7-68.2C261.3 4.2 243.2 0 224 0c-53.7 0-99.7 33.1-118.7 80h81.4l91-68.2zM224 256c70.7 0 128-57.3 128-128c0-5.4-.3-10.8-1-16H97c-.7 5.2-1 10.6-1 16c0 70.7 57.3 128 128 128zM124 312.4c-9.7 3.1-19.1 7-28 11.7V512H243.7L181.5 408.2 124 312.4zm33-7.2L204.3 384H272c44.2 0 80 35.8 80 80c0 18-6 34.6-16 48h82.3c16.4 0 29.7-13.3 29.7-29.7C448 383.8 368.2 304 269.7 304H178.3c-7.2 0-14.3 .4-21.3 1.3zM0 482.3C0 498.7 13.3 512 29.7 512H64V345.4C24.9 378.1 0 427.3 0 482.3zM320 464c0-26.5-21.5-48-48-48H223.5l57.1 95.2C303 507.2 320 487.6 320 464z" } }, "free": ["solid"] }, "user-large": { "aliases": { "names": ["user-alt"], "unicodes": { "secondary": ["10f406"] } }, "changes": [ "5.0.0", "5.0.3", "5.0.11", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["users-people"] }, "styles": ["solid"], "unicode": "f406", "label": "User Large", "voted": false, "svg": { "solid": { "last_modified": 1684767619, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 288A144 144 0 1 0 256 0a144 144 0 1 0 0 288zm-94.7 32C72.2 320 0 392.2 0 481.3c0 17 13.8 30.7 30.7 30.7H481.3c17 0 30.7-13.8 30.7-30.7C512 392.2 439.8 320 350.7 320H161.3z" } }, "free": ["solid"] }, "user-large-slash": { "aliases": { "names": ["user-alt-slash"], "unicodes": { "secondary": ["10f4fa"] } }, "changes": ["5.0.11", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["users-people"] }, "styles": ["solid"], "unicode": "f4fa", "label": "User Large Slash", "voted": false, "svg": { "solid": { "last_modified": 1684767620, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7L381.9 274c48.5-23.2 82.1-72.7 82.1-130C464 64.5 399.5 0 320 0C250.4 0 192.4 49.3 178.9 114.9L38.8 5.1zM545.5 512H528L284.3 320h-59C136.2 320 64 392.2 64 481.3c0 17 13.8 30.7 30.7 30.7H545.3l.3 0z" } }, "free": ["solid"] }, "user-lock": { "aliases": { "unicodes": { "secondary": ["10f502"] } }, "changes": ["5.0.11", "5.9.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["users-people"] }, "styles": ["solid"], "unicode": "f502", "label": "User Lock", "voted": false, "svg": { "solid": { "last_modified": 1684767620, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M224 256A128 128 0 1 0 224 0a128 128 0 1 0 0 256zm-45.7 48C79.8 304 0 383.8 0 482.3C0 498.7 13.3 512 29.7 512H392.6c-5.4-9.4-8.6-20.3-8.6-32V352c0-2.1 .1-4.2 .3-6.3c-31-26-71-41.7-114.6-41.7H178.3zM528 240c17.7 0 32 14.3 32 32v48H496V272c0-17.7 14.3-32 32-32zm-80 32v48c-17.7 0-32 14.3-32 32V480c0 17.7 14.3 32 32 32H608c17.7 0 32-14.3 32-32V352c0-17.7-14.3-32-32-32V272c0-44.2-35.8-80-80-80s-80 35.8-80 80z" } }, "free": ["solid"] }, "user-minus": { "aliases": { "unicodes": { "secondary": ["10f503"] } }, "changes": ["5.0.11", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["delete", "negative", "remove"] }, "styles": ["solid"], "unicode": "f503", "label": "User Minus", "voted": false, "svg": { "solid": { "last_modified": 1684767621, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M96 128a128 128 0 1 1 256 0A128 128 0 1 1 96 128zM0 482.3C0 383.8 79.8 304 178.3 304h91.4C368.2 304 448 383.8 448 482.3c0 16.4-13.3 29.7-29.7 29.7H29.7C13.3 512 0 498.7 0 482.3zM472 200H616c13.3 0 24 10.7 24 24s-10.7 24-24 24H472c-13.3 0-24-10.7-24-24s10.7-24 24-24z" } }, "free": ["solid"] }, "user-ninja": { "aliases": { "unicodes": { "composite": ["1f977"], "secondary": ["10f504"] } }, "changes": ["5.0.11", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "assassin", "avatar", "dangerous", "deadly", "fighter", "hidden", "ninja", "sneaky", "stealth" ] }, "styles": ["solid"], "unicode": "f504", "label": "User Ninja", "voted": false, "svg": { "solid": { "last_modified": 1684767621, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M224 256c-57.2 0-105.6-37.5-122-89.3c-1.1 1.3-2.2 2.6-3.5 3.8c-15.8 15.8-38.8 20.7-53.6 22.1c-8.1 .8-14.6-5.7-13.8-13.8c1.4-14.7 6.3-37.8 22.1-53.6c5.8-5.8 12.6-10.1 19.6-13.4c-7-3.2-13.8-7.6-19.6-13.4C37.4 82.7 32.6 59.7 31.1 44.9c-.8-8.1 5.7-14.6 13.8-13.8c14.7 1.4 37.8 6.3 53.6 22.1c4.8 4.8 8.7 10.4 11.7 16.1C131.4 28.2 174.4 0 224 0c70.7 0 128 57.3 128 128s-57.3 128-128 128zM0 482.3C0 399.5 56.4 330 132.8 309.9c6-1.6 12.2 .9 15.9 5.8l62.5 83.3c6.4 8.5 19.2 8.5 25.6 0l62.5-83.3c3.7-4.9 9.9-7.4 15.9-5.8C391.6 330 448 399.5 448 482.3c0 16.4-13.3 29.7-29.7 29.7H29.7C13.3 512 0 498.7 0 482.3zM160 96c-8.8 0-16 7.2-16 16s7.2 16 16 16H288c8.8 0 16-7.2 16-16s-7.2-16-16-16H160z" } }, "free": ["solid"] }, "user-nurse": { "aliases": { "unicodes": { "secondary": ["10f82f"] } }, "changes": ["5.7.0", "5.12.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "covid-19", "doctor", "health", "md", "medical", "midwife", "physician", "practitioner", "surgeon", "worker" ] }, "styles": ["solid"], "unicode": "f82f", "label": "User Nurse", "voted": false, "svg": { "solid": { "last_modified": 1684767619, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M96 128V70.2c0-13.3 8.3-25.3 20.8-30l96-36c7.2-2.7 15.2-2.7 22.5 0l96 36c12.5 4.7 20.8 16.6 20.8 30V128h-.3c.2 2.6 .3 5.3 .3 8v40c0 70.7-57.3 128-128 128s-128-57.3-128-128V136c0-2.7 .1-5.4 .3-8H96zm48 48c0 44.2 35.8 80 80 80s80-35.8 80-80V160H144v16zM111.9 327.7c10.5-3.4 21.8 .4 29.4 8.5l71 75.5c6.3 6.7 17 6.7 23.3 0l71-75.5c7.6-8.1 18.9-11.9 29.4-8.5C401 348.6 448 409.4 448 481.3c0 17-13.8 30.7-30.7 30.7H30.7C13.8 512 0 498.2 0 481.3c0-71.9 47-132.7 111.9-153.6zM208 48V64H192c-4.4 0-8 3.6-8 8V88c0 4.4 3.6 8 8 8h16v16c0 4.4 3.6 8 8 8h16c4.4 0 8-3.6 8-8V96h16c4.4 0 8-3.6 8-8V72c0-4.4-3.6-8-8-8H240V48c0-4.4-3.6-8-8-8H216c-4.4 0-8 3.6-8 8z" } }, "free": ["solid"] }, "user-pen": { "aliases": { "names": ["user-edit"], "unicodes": { "secondary": ["10f4ff"] } }, "changes": ["5.0.11", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["users-people"] }, "styles": ["solid"], "unicode": "f4ff", "label": "User Pen", "voted": false, "svg": { "solid": { "last_modified": 1684767621, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M224 256A128 128 0 1 0 224 0a128 128 0 1 0 0 256zm-45.7 48C79.8 304 0 383.8 0 482.3C0 498.7 13.3 512 29.7 512H322.8c-3.1-8.8-3.7-18.4-1.4-27.8l15-60.1c2.8-11.3 8.6-21.5 16.8-29.7l40.3-40.3c-32.1-31-75.7-50.1-123.9-50.1H178.3zm435.5-68.3c-15.6-15.6-40.9-15.6-56.6 0l-29.4 29.4 71 71 29.4-29.4c15.6-15.6 15.6-40.9 0-56.6l-14.4-14.4zM375.9 417c-4.1 4.1-7 9.2-8.4 14.9l-15 60.1c-1.4 5.5 .2 11.2 4.2 15.2s9.7 5.6 15.2 4.2l60.1-15c5.6-1.4 10.8-4.3 14.9-8.4L576.1 358.7l-71-71L375.9 417z" } }, "free": ["solid"] }, "user-plus": { "aliases": { "unicodes": { "secondary": ["10f234"] } }, "changes": [ "4.3.0", "5.0.0", "5.0.3", "5.0.11", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["add", "avatar", "positive", "sign up", "signup", "team"] }, "styles": ["solid"], "unicode": "f234", "label": "User Plus", "voted": false, "svg": { "solid": { "last_modified": 1684767620, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M96 128a128 128 0 1 1 256 0A128 128 0 1 1 96 128zM0 482.3C0 383.8 79.8 304 178.3 304h91.4C368.2 304 448 383.8 448 482.3c0 16.4-13.3 29.7-29.7 29.7H29.7C13.3 512 0 498.7 0 482.3zM504 312V248H440c-13.3 0-24-10.7-24-24s10.7-24 24-24h64V136c0-13.3 10.7-24 24-24s24 10.7 24 24v64h64c13.3 0 24 10.7 24 24s-10.7 24-24 24H552v64c0 13.3-10.7 24-24 24s-24-10.7-24-24z" } }, "free": ["solid"] }, "user-secret": { "aliases": { "unicodes": { "composite": ["1f575"], "secondary": ["10f21b"] } }, "changes": [ "4.3.0", "5.0.0", "5.0.3", "5.0.11", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["detective", "sleuth", "spy", "users-people"] }, "styles": ["solid"], "unicode": "f21b", "label": "User Secret", "voted": false, "svg": { "solid": { "last_modified": 1684767620, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M224 16c-6.7 0-10.8-2.8-15.5-6.1C201.9 5.4 194 0 176 0c-30.5 0-52 43.7-66 89.4C62.7 98.1 32 112.2 32 128c0 14.3 25 27.1 64.6 35.9c-.4 4-.6 8-.6 12.1c0 17 3.3 33.2 9.3 48H45.4C38 224 32 230 32 237.4c0 1.7 .3 3.4 1 5l38.8 96.9C28.2 371.8 0 423.8 0 482.3C0 498.7 13.3 512 29.7 512H418.3c16.4 0 29.7-13.3 29.7-29.7c0-58.5-28.2-110.4-71.7-143L415 242.4c.6-1.6 1-3.3 1-5c0-7.4-6-13.4-13.4-13.4H342.7c6-14.8 9.3-31 9.3-48c0-4.1-.2-8.1-.6-12.1C391 155.1 416 142.3 416 128c0-15.8-30.7-29.9-78-38.6C324 43.7 302.5 0 272 0c-18 0-25.9 5.4-32.5 9.9c-4.8 3.3-8.8 6.1-15.5 6.1zm56 208H267.6c-16.5 0-31.1-10.6-36.3-26.2c-2.3-7-12.2-7-14.5 0c-5.2 15.6-19.9 26.2-36.3 26.2H168c-22.1 0-40-17.9-40-40V169.6c28.2 4.1 61 6.4 96 6.4s67.8-2.3 96-6.4V184c0 22.1-17.9 40-40 40zm-88 96l16 32L176 480 128 288l64 32zm128-32L272 480 240 352l16-32 64-32z" } }, "free": ["solid"] }, "user-shield": { "aliases": { "unicodes": { "secondary": ["10f505"] } }, "changes": ["5.0.11", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["protect", "safety"] }, "styles": ["solid"], "unicode": "f505", "label": "User Shield", "voted": false, "svg": { "solid": { "last_modified": 1684767620, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M224 256A128 128 0 1 0 224 0a128 128 0 1 0 0 256zm-45.7 48C79.8 304 0 383.8 0 482.3C0 498.7 13.3 512 29.7 512H418.3c1.8 0 3.5-.2 5.3-.5c-76.3-55.1-99.8-141-103.1-200.2c-16.1-4.8-33.1-7.3-50.7-7.3H178.3zm308.8-78.3l-120 48C358 277.4 352 286.2 352 296c0 63.3 25.9 168.8 134.8 214.2c5.9 2.5 12.6 2.5 18.5 0C614.1 464.8 640 359.3 640 296c0-9.8-6-18.6-15.1-22.3l-120-48c-5.7-2.3-12.1-2.3-17.8 0zM591.4 312c-3.9 50.7-27.2 116.7-95.4 149.7V273.8L591.4 312z" } }, "free": ["solid"] }, "user-slash": { "aliases": { "unicodes": { "secondary": ["10f506"] } }, "changes": ["5.0.11", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["ban", "delete", "remove"] }, "styles": ["solid"], "unicode": "f506", "label": "User Slash", "voted": false, "svg": { "solid": { "last_modified": 1684767620, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7L353.3 251.6C407.9 237 448 187.2 448 128C448 57.3 390.7 0 320 0C250.2 0 193.5 55.8 192 125.2L38.8 5.1zM264.3 304.3C170.5 309.4 96 387.2 96 482.3c0 16.4 13.3 29.7 29.7 29.7H514.3c3.9 0 7.6-.7 11-2.1l-261-205.6z" } }, "free": ["solid"] }, "user-tag": { "aliases": { "unicodes": { "secondary": ["10f507"] } }, "changes": ["5.0.11", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["users-people"] }, "styles": ["solid"], "unicode": "f507", "label": "User Tag", "voted": false, "svg": { "solid": { "last_modified": 1684767620, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M224 256A128 128 0 1 0 224 0a128 128 0 1 0 0 256zm-45.7 48C79.8 304 0 383.8 0 482.3C0 498.7 13.3 512 29.7 512H418.3c10 0 18.8-4.9 24.2-12.5l-99.2-99.2c-14.9-14.9-23.3-35.1-23.3-56.1v-33c-15.9-4.7-32.8-7.2-50.3-7.2H178.3zM384 224c-17.7 0-32 14.3-32 32v82.7c0 17 6.7 33.3 18.7 45.3L478.1 491.3c18.7 18.7 49.1 18.7 67.9 0l73.4-73.4c18.7-18.7 18.7-49.1 0-67.9L512 242.7c-12-12-28.3-18.7-45.3-18.7H384zm24 80a24 24 0 1 1 48 0 24 24 0 1 1 -48 0z" } }, "free": ["solid"] }, "user-tie": { "aliases": { "unicodes": { "secondary": ["10f508"] } }, "changes": [ "5.0.11", "6.0.0-beta1", "6.0.0-beta2", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "avatar", "business", "clothing", "formal", "professional", "suit" ] }, "styles": ["solid"], "unicode": "f508", "label": "User Tie", "voted": false, "svg": { "solid": { "last_modified": 1684767620, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M224 256A128 128 0 1 1 224 0a128 128 0 1 1 0 256zM209.1 359.2l-18.6-31c-6.4-10.7 1.3-24.2 13.7-24.2H224h19.7c12.4 0 20.1 13.6 13.7 24.2l-18.6 31 33.4 123.9 36-146.9c2-8.1 9.8-13.4 17.9-11.3c70.1 17.6 121.9 81 121.9 156.4c0 17-13.8 30.7-30.7 30.7H285.5c-2.1 0-4-.4-5.8-1.1l.3 1.1H168l.3-1.1c-1.8 .7-3.8 1.1-5.8 1.1H30.7C13.8 512 0 498.2 0 481.3c0-75.5 51.9-138.9 121.9-156.4c8.1-2 15.9 3.3 17.9 11.3l36 146.9 33.4-123.9z" } }, "free": ["solid"] }, "user-xmark": { "aliases": { "names": ["user-times"], "unicodes": { "secondary": ["10f235"] } }, "changes": [ "4.3.0", "5.0.0", "5.0.3", "5.0.11", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["archive", "delete", "remove", "x"] }, "styles": ["solid"], "unicode": "f235", "label": "User Xmark", "voted": false, "svg": { "solid": { "last_modified": 1684767621, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M96 128a128 128 0 1 1 256 0A128 128 0 1 1 96 128zM0 482.3C0 383.8 79.8 304 178.3 304h91.4C368.2 304 448 383.8 448 482.3c0 16.4-13.3 29.7-29.7 29.7H29.7C13.3 512 0 498.7 0 482.3zM471 143c9.4-9.4 24.6-9.4 33.9 0l47 47 47-47c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-47 47 47 47c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-47-47-47 47c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l47-47-47-47c-9.4-9.4-9.4-24.6 0-33.9z" } }, "free": ["solid"] }, "users": { "aliases": { "unicodes": { "secondary": ["10f0c0"] } }, "changes": [ "2.0.0", "5.0.0", "5.0.3", "5.0.11", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["users-people"] }, "styles": ["solid"], "unicode": "f0c0", "label": "Users", "voted": false, "svg": { "solid": { "last_modified": 1684767621, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M144 0a80 80 0 1 1 0 160A80 80 0 1 1 144 0zM512 0a80 80 0 1 1 0 160A80 80 0 1 1 512 0zM0 298.7C0 239.8 47.8 192 106.7 192h42.7c15.9 0 31 3.5 44.6 9.7c-1.3 7.2-1.9 14.7-1.9 22.3c0 38.2 16.8 72.5 43.3 96c-.2 0-.4 0-.7 0H21.3C9.6 320 0 310.4 0 298.7zM405.3 320c-.2 0-.4 0-.7 0c26.6-23.5 43.3-57.8 43.3-96c0-7.6-.7-15-1.9-22.3c13.6-6.3 28.7-9.7 44.6-9.7h42.7C592.2 192 640 239.8 640 298.7c0 11.8-9.6 21.3-21.3 21.3H405.3zM224 224a96 96 0 1 1 192 0 96 96 0 1 1 -192 0zM128 485.3C128 411.7 187.7 352 261.3 352H378.7C452.3 352 512 411.7 512 485.3c0 14.7-11.9 26.7-26.7 26.7H154.7c-14.7 0-26.7-11.9-26.7-26.7z" } }, "free": ["solid"] }, "users-between-lines": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["covered", "group", "people"] }, "styles": ["solid"], "unicode": "e591", "label": "Users Between Lines", "voted": false, "svg": { "solid": { "last_modified": 1684767620, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M0 24C0 10.7 10.7 0 24 0H616c13.3 0 24 10.7 24 24s-10.7 24-24 24H24C10.7 48 0 37.3 0 24zM0 488c0-13.3 10.7-24 24-24H616c13.3 0 24 10.7 24 24s-10.7 24-24 24H24c-13.3 0-24-10.7-24-24zM83.2 160a64 64 0 1 1 128 0 64 64 0 1 1 -128 0zM32 320c0-35.3 28.7-64 64-64h96c12.2 0 23.7 3.4 33.4 9.4c-37.2 15.1-65.6 47.2-75.8 86.6H64c-17.7 0-32-14.3-32-32zm461.6 32c-10.3-40.1-39.6-72.6-77.7-87.4c9.4-5.5 20.4-8.6 32.1-8.6h96c35.3 0 64 28.7 64 64c0 17.7-14.3 32-32 32H493.6zM391.2 290.4c32.1 7.4 58.1 30.9 68.9 61.6c3.5 10 5.5 20.8 5.5 32c0 17.7-14.3 32-32 32h-224c-17.7 0-32-14.3-32-32c0-11.2 1.9-22 5.5-32c10.5-29.7 35.3-52.8 66.1-60.9c7.8-2.1 16-3.1 24.5-3.1h96c7.4 0 14.7 .8 21.6 2.4zm44-130.4a64 64 0 1 1 128 0 64 64 0 1 1 -128 0zM321.6 96a80 80 0 1 1 0 160 80 80 0 1 1 0-160z" } }, "free": ["solid"] }, "users-gear": { "aliases": { "names": ["users-cog"], "unicodes": { "secondary": ["10f509"] } }, "changes": ["5.0.11", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["users-people"] }, "styles": ["solid"], "unicode": "f509", "label": "Users Gear", "voted": false, "svg": { "solid": { "last_modified": 1684767619, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M144 160A80 80 0 1 0 144 0a80 80 0 1 0 0 160zm368 0A80 80 0 1 0 512 0a80 80 0 1 0 0 160zM0 298.7C0 310.4 9.6 320 21.3 320H234.7c.2 0 .4 0 .7 0c-26.6-23.5-43.3-57.8-43.3-96c0-7.6 .7-15 1.9-22.3c-13.6-6.3-28.7-9.7-44.6-9.7H106.7C47.8 192 0 239.8 0 298.7zM320 320c24 0 45.9-8.8 62.7-23.3c2.5-3.7 5.2-7.3 8-10.7c2.7-3.3 5.7-6.1 9-8.3C410 262.3 416 243.9 416 224c0-53-43-96-96-96s-96 43-96 96s43 96 96 96zm65.4 60.2c-10.3-5.9-18.1-16.2-20.8-28.2H261.3C187.7 352 128 411.7 128 485.3c0 14.7 11.9 26.7 26.7 26.7H455.2c-2.1-5.2-3.2-10.9-3.2-16.4v-3c-1.3-.7-2.7-1.5-4-2.3l-2.6 1.5c-16.8 9.7-40.5 8-54.7-9.7c-4.5-5.6-8.6-11.5-12.4-17.6l-.1-.2-.1-.2-2.4-4.1-.1-.2-.1-.2c-3.4-6.2-6.4-12.6-9-19.3c-8.2-21.2 2.2-42.6 19-52.3l2.7-1.5c0-.8 0-1.5 0-2.3s0-1.5 0-2.3l-2.7-1.5zM533.3 192H490.7c-15.9 0-31 3.5-44.6 9.7c1.3 7.2 1.9 14.7 1.9 22.3c0 17.4-3.5 33.9-9.7 49c2.5 .9 4.9 2 7.1 3.3l2.6 1.5c1.3-.8 2.6-1.6 4-2.3v-3c0-19.4 13.3-39.1 35.8-42.6c7.9-1.2 16-1.9 24.2-1.9s16.3 .6 24.2 1.9c22.5 3.5 35.8 23.2 35.8 42.6v3c1.3 .7 2.7 1.5 4 2.3l2.6-1.5c16.8-9.7 40.5-8 54.7 9.7c2.3 2.8 4.5 5.8 6.6 8.7c-2.1-57.1-49-102.7-106.6-102.7zm91.3 163.9c6.3-3.6 9.5-11.1 6.8-18c-2.1-5.5-4.6-10.8-7.4-15.9l-2.3-4c-3.1-5.1-6.5-9.9-10.2-14.5c-4.6-5.7-12.7-6.7-19-3L574.4 311c-8.9-7.6-19.1-13.6-30.4-17.6v-21c0-7.3-4.9-13.8-12.1-14.9c-6.5-1-13.1-1.5-19.9-1.5s-13.4 .5-19.9 1.5c-7.2 1.1-12.1 7.6-12.1 14.9v21c-11.2 4-21.5 10-30.4 17.6l-18.2-10.5c-6.3-3.6-14.4-2.6-19 3c-3.7 4.6-7.1 9.5-10.2 14.6l-2.3 3.9c-2.8 5.1-5.3 10.4-7.4 15.9c-2.6 6.8 .5 14.3 6.8 17.9l18.2 10.5c-1 5.7-1.6 11.6-1.6 17.6s.6 11.9 1.6 17.5l-18.2 10.5c-6.3 3.6-9.5 11.1-6.8 17.9c2.1 5.5 4.6 10.7 7.4 15.8l2.4 4.1c3 5.1 6.4 9.9 10.1 14.5c4.6 5.7 12.7 6.7 19 3L449.6 457c8.9 7.6 19.2 13.6 30.4 17.6v21c0 7.3 4.9 13.8 12.1 14.9c6.5 1 13.1 1.5 19.9 1.5s13.4-.5 19.9-1.5c7.2-1.1 12.1-7.6 12.1-14.9v-21c11.2-4 21.5-10 30.4-17.6l18.2 10.5c6.3 3.6 14.4 2.6 19-3c3.7-4.6 7.1-9.4 10.1-14.5l2.4-4.2c2.8-5.1 5.3-10.3 7.4-15.8c2.6-6.8-.5-14.3-6.8-17.9l-18.2-10.5c1-5.7 1.6-11.6 1.6-17.5s-.6-11.9-1.6-17.6l18.2-10.5zM472 384a40 40 0 1 1 80 0 40 40 0 1 1 -80 0z" } }, "free": ["solid"] }, "users-line": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["group", "need", "people"] }, "styles": ["solid"], "unicode": "e592", "label": "Users Line", "voted": false, "svg": { "solid": { "last_modified": 1684767620, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M211.2 96a64 64 0 1 0 -128 0 64 64 0 1 0 128 0zM32 256c0 17.7 14.3 32 32 32h85.6c10.1-39.4 38.6-71.5 75.8-86.6c-9.7-6-21.2-9.4-33.4-9.4H96c-35.3 0-64 28.7-64 64zm461.6 32H576c17.7 0 32-14.3 32-32c0-35.3-28.7-64-64-64H448c-11.7 0-22.7 3.1-32.1 8.6c38.1 14.8 67.4 47.3 77.7 87.4zM391.2 226.4c-6.9-1.6-14.2-2.4-21.6-2.4h-96c-8.5 0-16.7 1.1-24.5 3.1c-30.8 8.1-55.6 31.1-66.1 60.9c-3.5 10-5.5 20.8-5.5 32c0 17.7 14.3 32 32 32h224c17.7 0 32-14.3 32-32c0-11.2-1.9-22-5.5-32c-10.8-30.7-36.8-54.2-68.9-61.6zM563.2 96a64 64 0 1 0 -128 0 64 64 0 1 0 128 0zM321.6 192a80 80 0 1 0 0-160 80 80 0 1 0 0 160zM32 416c-17.7 0-32 14.3-32 32s14.3 32 32 32H608c17.7 0 32-14.3 32-32s-14.3-32-32-32H32z" } }, "free": ["solid"] }, "users-rays": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["affected", "focused", "group", "people"] }, "styles": ["solid"], "unicode": "e593", "label": "Users Rays", "voted": false, "svg": { "solid": { "last_modified": 1684767620, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M41 7C31.6-2.3 16.4-2.3 7 7S-2.3 31.6 7 41l72 72c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9L41 7zM599 7L527 79c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l72-72c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0zM7 505c9.4 9.4 24.6 9.4 33.9 0l72-72c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0L7 471c-9.4 9.4-9.4 24.6 0 33.9zm592 0c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9l-72-72c-9.4-9.4-24.6-9.4-33.9 0s-9.4 24.6 0 33.9l72 72zM320 256a64 64 0 1 0 0-128 64 64 0 1 0 0 128zM212.1 336c-2.7 7.5-4.1 15.6-4.1 24c0 13.3 10.7 24 24 24H408c13.3 0 24-10.7 24-24c0-8.4-1.4-16.5-4.1-24c-.5-1.4-1-2.7-1.6-4c-9.4-22.3-29.8-38.9-54.3-43c-3.9-.7-7.9-1-12-1H280c-4.1 0-8.1 .3-12 1c-.8 .1-1.7 .3-2.5 .5c-24.9 5.1-45.1 23-53.4 46.5zM175.8 224a48 48 0 1 0 0-96 48 48 0 1 0 0 96zm-26.5 32C119.9 256 96 279.9 96 309.3c0 14.7 11.9 26.7 26.7 26.7h56.1c8-34.1 32.8-61.7 65.2-73.6c-7.5-4.1-16.2-6.4-25.3-6.4H149.3zm368 80c14.7 0 26.7-11.9 26.7-26.7c0-29.5-23.9-53.3-53.3-53.3H421.3c-9.2 0-17.8 2.3-25.3 6.4c32.4 11.9 57.2 39.5 65.2 73.6h56.1zM464 224a48 48 0 1 0 0-96 48 48 0 1 0 0 96z" } }, "free": ["solid"] }, "users-rectangle": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["focus", "group", "people", "reached"] }, "styles": ["solid"], "unicode": "e594", "label": "Users Rectangle", "voted": false, "svg": { "solid": { "last_modified": 1684767621, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M96 0C43 0 0 43 0 96V416c0 53 43 96 96 96H544c53 0 96-43 96-96V96c0-53-43-96-96-96H96zM64 96c0-17.7 14.3-32 32-32H544c17.7 0 32 14.3 32 32V416c0 17.7-14.3 32-32 32H96c-17.7 0-32-14.3-32-32V96zm159.8 80a48 48 0 1 0 -96 0 48 48 0 1 0 96 0zM96 309.3c0 14.7 11.9 26.7 26.7 26.7h56.1c8-34.1 32.8-61.7 65.2-73.6c-7.5-4.1-16.2-6.4-25.3-6.4H149.3C119.9 256 96 279.9 96 309.3zM461.2 336h56.1c14.7 0 26.7-11.9 26.7-26.7c0-29.5-23.9-53.3-53.3-53.3H421.3c-9.2 0-17.8 2.3-25.3 6.4c32.4 11.9 57.2 39.5 65.2 73.6zM372 289c-3.9-.7-7.9-1-12-1H280c-4.1 0-8.1 .3-12 1c-26 4.4-47.3 22.7-55.9 47c-2.7 7.5-4.1 15.6-4.1 24c0 13.3 10.7 24 24 24H408c13.3 0 24-10.7 24-24c0-8.4-1.4-16.5-4.1-24c-8.6-24.3-29.9-42.6-55.9-47zM512 176a48 48 0 1 0 -96 0 48 48 0 1 0 96 0zM320 256a64 64 0 1 0 0-128 64 64 0 1 0 0 128z" } }, "free": ["solid"] }, "users-slash": { "aliases": { "unicodes": { "secondary": ["10e073"] } }, "changes": ["5.13.0", "5.14.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["users-people"] }, "styles": ["solid"], "unicode": "e073", "label": "Users Slash", "voted": false, "svg": { "solid": { "last_modified": 1684767621, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7L440.6 320H618.7c11.8 0 21.3-9.6 21.3-21.3C640 239.8 592.2 192 533.3 192H490.7c-15.9 0-31 3.5-44.6 9.7c1.3 7.2 1.9 14.7 1.9 22.3c0 30.2-10.5 58-28 79.9l-25.2-19.7C408.1 267.7 416 246.8 416 224c0-53-43-96-96-96c-31.1 0-58.7 14.8-76.3 37.7l-40.6-31.8c13-14.2 20.9-33.1 20.9-53.9c0-44.2-35.8-80-80-80C116.3 0 91.9 14.1 77.5 35.5L38.8 5.1zM106.7 192C47.8 192 0 239.8 0 298.7C0 310.4 9.6 320 21.3 320H234.7c.2 0 .4 0 .7 0c-20.6-18.2-35.2-42.8-40.8-70.8L121.8 192H106.7zM261.3 352C187.7 352 128 411.7 128 485.3c0 14.7 11.9 26.7 26.7 26.7H485.3c10.5 0 19.5-6 23.9-14.8L324.9 352H261.3zM512 160A80 80 0 1 0 512 0a80 80 0 1 0 0 160z" } }, "free": ["solid"] }, "users-viewfinder": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["focus", "group", "people", "targeted"] }, "styles": ["solid"], "unicode": "e595", "label": "Users Viewfinder", "voted": false, "svg": { "solid": { "last_modified": 1684767620, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M48 48h88c13.3 0 24-10.7 24-24s-10.7-24-24-24H32C14.3 0 0 14.3 0 32V136c0 13.3 10.7 24 24 24s24-10.7 24-24V48zM175.8 224a48 48 0 1 0 0-96 48 48 0 1 0 0 96zm-26.5 32C119.9 256 96 279.9 96 309.3c0 14.7 11.9 26.7 26.7 26.7h56.1c8-34.1 32.8-61.7 65.2-73.6c-7.5-4.1-16.2-6.4-25.3-6.4H149.3zm368 80c14.7 0 26.7-11.9 26.7-26.7c0-29.5-23.9-53.3-53.3-53.3H421.3c-9.2 0-17.8 2.3-25.3 6.4c32.4 11.9 57.2 39.5 65.2 73.6h56.1zm-89.4 0c-8.6-24.3-29.9-42.6-55.9-47c-3.9-.7-7.9-1-12-1H280c-4.1 0-8.1 .3-12 1c-26 4.4-47.3 22.7-55.9 47c-2.7 7.5-4.1 15.6-4.1 24c0 13.3 10.7 24 24 24H408c13.3 0 24-10.7 24-24c0-8.4-1.4-16.5-4.1-24zM464 224a48 48 0 1 0 0-96 48 48 0 1 0 0 96zm-80-32a64 64 0 1 0 -128 0 64 64 0 1 0 128 0zM504 48h88v88c0 13.3 10.7 24 24 24s24-10.7 24-24V32c0-17.7-14.3-32-32-32H504c-13.3 0-24 10.7-24 24s10.7 24 24 24zM48 464V376c0-13.3-10.7-24-24-24s-24 10.7-24 24V480c0 17.7 14.3 32 32 32H136c13.3 0 24-10.7 24-24s-10.7-24-24-24H48zm456 0c-13.3 0-24 10.7-24 24s10.7 24 24 24H608c17.7 0 32-14.3 32-32V376c0-13.3-10.7-24-24-24s-24 10.7-24 24v88H504z" } }, "free": ["solid"] }, "usps": { "changes": ["5.6.0", "5.8.0"], "ligatures": [], "search": { "terms": ["american", "package", "shipping", "usa"] }, "styles": ["brands"], "unicode": "f7e1", "label": "United States Postal Service", "voted": false, "svg": { "brands": { "last_modified": 1660014469, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M460.3 241.7c25.8-41.3 15.2-48.8-11.7-48.8h-27c-.1 0-1.5-1.4-10.9 8-11.2 5.6-37.9 6.3-37.9 8.7 0 4.5 70.3-3.1 88.1 0 9.5 1.5-1.5 20.4-4.4 32-.5 4.5 2.4 2.3 3.8.1zm-112.1 22.6c64-21.3 97.3-23.9 102-26.2 4.4-2.9-4.4-6.6-26.2-5.8-51.7 2.2-137.6 37.1-172.6 53.9l-30.7-93.3h196.6c-2.7-28.2-152.9-22.6-337.9-22.6L27 415.8c196.4-97.3 258.9-130.3 321.2-151.5zM94.7 96c253.3 53.7 330 65.7 332.1 85.2 36.4 0 45.9 0 52.4 6.6 21.1 19.7-14.6 67.7-14.6 67.7-4.4 2.9-406.4 160.2-406.4 160.2h423.1L549 96z" } }, "free": ["brands"] }, "ussunnah": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f407", "label": "us-Sunnah Foundation", "voted": false, "svg": { "brands": { "last_modified": 1677678764, "raw": "", "viewBox": [0, 0, 482, 512], "width": 482, "height": 512, "path": "M481.9 268.1A240.9 240.9 0 1 1 .1 268a240.9 240.9 0 1 1 481.9 0zM24.5 268a216.5 216.5 0 1 0 432.9 0A216.5 216.5 0 1 0 24.5 268zm385.9 63.3c-12.7 0-21.6-1.9-26.7-5.9c-5.5-4.3-8.2-12.3-8.2-23.8V205.1c0-6.5-5.2-20.2-15.7-41.2c7 0 17-9.1 30-27.2V284.5c0 11 2.4 19.4 7 25.3c3.7 4.7 10.1 8.9 19 12.6c1.2 .4 2.6 .9 4.1 1.4c2.9 .9 6.3 2.1 10.3 3.5c-1.8 2.7-8.3 4-19.9 4zm-219 0c-1.3 2.4-3.6 5.5-6.8 9.4l-18.5 22.5c-1-6.1-4-13-9.3-20.6s-9.7-11.4-13.4-11.4h-8.3H53.6c3.3-5.3 4.9-8.8 4.9-10.8c0-2-.8-5.3-2.4-9.7c-1.5-4.4-2.4-8.5-2.4-12.4c0-7.4 2.1-13.9 6.3-19.3L80 253.4l-7.1-17.7L89 215.9l6.7 16.8 8-10.3c-1.8 6.4-2.6 12.3-2.6 17.7c0 4.2 2.8 13.3 8.3 27.3l16.2 40.7H135h8 .3c2.8 .4 7.7 5 14.6 13.9c1.8 2.4 4.3 5.8 7.7 10.2c1.4 1.9 2.9 3.9 4.6 6.1c1.3-2.3 2-4.6 2-7.1c0-2-1.3-6.6-4-13.4L163 304.1c-4-10.6-6.1-17.7-6.1-21.3c0-6.3 1.9-12.3 5.8-17.9c.5-.6 1-1.3 1.5-1.9c4.4-5.6 8.8-11.1 13.3-16.5c-1.1 4.6-1.7 8.7-1.7 12c0 3.7 1.7 9.9 5.1 18.8l7.9 20.4c1.9 4.7 3 8.2 3.7 10.3h17.6 8.3l-.9-2.6c-1.4-3.9-4-7-7.7-9.3l15.6-20.1 12.3 32h13.4L245 292.2c-1.5-3.9-4-7-7.7-9.3L253 262.8 270.3 308h13.4l-11.4-29.4c-1.5-3.9-4-7-7.7-9.3l15.6-20L302.6 308h10.3 8.3 7.6c1.5 0 3-1.1 4.5-3.1s2.2-4.1 2.2-6.3V205.1c0-6.5-4.5-20.3-13.7-41.2c5.4 0 14.1-9.1 26.2-27.2V300.2c0 7.2 .6 12 1.7 14.6c1.6 3.4 5.3 6.2 11.1 8.2c-3.9 5.6-8.7 8.5-14.5 8.5H321.1h-8.3H210.5h-19zM93.4 287.3c-2.7-6.7-4-11.7-4-15c-.6 1.2-2.4 3.7-5.4 7.6c-1.4 1.9-2.2 3.7-2.2 5.3c0 2.6 .8 5.7 2.2 9.3l5.6 13.9h0c5 0 9 0 11.9-.1l-8.2-20.9zm13.5-72.4c-3-5.2-7-9.3-11.9-11.9c-3.5-1.9-5.3-4.3-5.3-7.4c0-2.4 4.6-8.6 14-18.3c.2 3.8 1.9 7.6 4.9 11.2c3.1 3.6 4.6 7 4.6 10.1c0 2.6-2.1 8-6.2 16.3zm-27.6 0c-3-5.2-7-9.3-11.9-11.9c-3.5-1.9-5.3-4.3-5.3-7.4c0-2.4 4.6-8.6 14-18.3c.2 3.8 1.9 7.6 4.9 11.2c3.1 3.6 4.6 7 4.6 10.1c0 2.6-2.1 8-6.2 16.3zm87 27.5c-3-5.2-7-9.3-11.9-11.9c-3.5-1.9-5.3-4.3-5.3-7.4c0-2.4 4.6-8.6 14-18.3c.2 3.8 1.9 7.6 4.9 11.2c3.1 3.6 4.6 7 4.6 10.1c0 2.6-2.1 8-6.2 16.3z" } }, "free": ["brands"] }, "utensils": { "aliases": { "names": ["cutlery"], "unicodes": { "composite": ["1f374", "f0f5"], "secondary": ["10f2e7"] } }, "changes": [ "5.0.0", "6.0.0-beta1", "6.0.0-beta2", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "cooking", "cutlery", "dining", "dinner", "eat", "food", "fork", "fork and knife", "knife", "restaurant" ] }, "styles": ["solid"], "unicode": "f2e7", "label": "Utensils", "voted": false, "svg": { "solid": { "last_modified": 1684767419, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M416 0C400 0 288 32 288 176V288c0 35.3 28.7 64 64 64h32V480c0 17.7 14.3 32 32 32s32-14.3 32-32V352 240 32c0-17.7-14.3-32-32-32zM64 16C64 7.8 57.9 1 49.7 .1S34.2 4.6 32.4 12.5L2.1 148.8C.7 155.1 0 161.5 0 167.9c0 45.9 35.1 83.6 80 87.7V480c0 17.7 14.3 32 32 32s32-14.3 32-32V255.6c44.9-4.1 80-41.8 80-87.7c0-6.4-.7-12.8-2.1-19.1L191.6 12.5c-1.8-8-9.3-13.3-17.4-12.4S160 7.8 160 16V150.2c0 5.4-4.4 9.8-9.8 9.8c-5.1 0-9.3-3.9-9.8-9L127.9 14.6C127.2 6.3 120.3 0 112 0s-15.2 6.3-15.9 14.6L83.7 151c-.5 5.1-4.7 9-9.8 9c-5.4 0-9.8-4.4-9.8-9.8V16zm48.3 152l-.3 0-.3 0 .3-.7 .3 .7z" } }, "free": ["solid"] }, "v": { "aliases": { "unicodes": { "composite": ["76"] } }, "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Latin Capital Letter V", "Latin Small Letter V", "letter"] }, "styles": ["solid"], "unicode": "56", "label": "V", "voted": false, "svg": { "solid": { "last_modified": 1684767247, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M19.7 34.5c16.3-6.8 35 .9 41.8 17.2L192 364.8 322.5 51.7c6.8-16.3 25.5-24 41.8-17.2s24 25.5 17.2 41.8l-160 384c-5 11.9-16.6 19.7-29.5 19.7s-24.6-7.8-29.5-19.7L2.5 76.3c-6.8-16.3 .9-35 17.2-41.8z" } }, "free": ["solid"] }, "vaadin": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f408", "label": "Vaadin", "voted": false, "svg": { "brands": { "last_modified": 1660014460, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M224.5 140.7c1.5-17.6 4.9-52.7 49.8-52.7h98.6c20.7 0 32.1-7.8 32.1-21.6V54.1c0-12.2 9.3-22.1 21.5-22.1S448 41.9 448 54.1v36.5c0 42.9-21.5 62-66.8 62H280.7c-30.1 0-33 14.7-33 27.1 0 1.3-.1 2.5-.2 3.7-.7 12.3-10.9 22.2-23.4 22.2s-22.7-9.8-23.4-22.2c-.1-1.2-.2-2.4-.2-3.7 0-12.3-3-27.1-33-27.1H66.8c-45.3 0-66.8-19.1-66.8-62V54.1C0 41.9 9.4 32 21.6 32s21.5 9.9 21.5 22.1v12.3C43.1 80.2 54.5 88 75.2 88h98.6c44.8 0 48.3 35.1 49.8 52.7h.9zM224 456c11.5 0 21.4-7 25.7-16.3 1.1-1.8 97.1-169.6 98.2-171.4 11.9-19.6-3.2-44.3-27.2-44.3-13.9 0-23.3 6.4-29.8 20.3L224 362l-66.9-117.7c-6.4-13.9-15.9-20.3-29.8-20.3-24 0-39.1 24.6-27.2 44.3 1.1 1.9 97.1 169.6 98.2 171.4 4.3 9.3 14.2 16.3 25.7 16.3z" } }, "free": ["brands"] }, "van-shuttle": { "aliases": { "names": ["shuttle-van"], "unicodes": { "composite": ["1f690"], "secondary": ["10f5b6"] } }, "changes": [ "5.1.0", "6.0.0-beta1", "6.0.0-beta2", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "airport", "bus", "machine", "minibus", "public-transportation", "transportation", "travel", "vehicle" ] }, "styles": ["solid"], "unicode": "f5b6", "label": "Van Shuttle", "voted": false, "svg": { "solid": { "last_modified": 1684767650, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M64 104v88h96V96H72c-4.4 0-8 3.6-8 8zm482 88L465.1 96H384v96H546zm-226 0V96H224v96h96zM592 384H576c0 53-43 96-96 96s-96-43-96-96H256c0 53-43 96-96 96s-96-43-96-96H48c-26.5 0-48-21.5-48-48V104C0 64.2 32.2 32 72 32H192 352 465.1c18.9 0 36.8 8.3 49 22.8L625 186.5c9.7 11.5 15 26.1 15 41.2V336c0 26.5-21.5 48-48 48zm-64 0a48 48 0 1 0 -96 0 48 48 0 1 0 96 0zM160 432a48 48 0 1 0 0-96 48 48 0 1 0 0 96z" } }, "free": ["solid"] }, "vault": { "changes": ["6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["bank", "important", "lock", "money", "safe"] }, "styles": ["solid"], "unicode": "e2c5", "label": "Vault", "voted": false, "svg": { "solid": { "last_modified": 1684766475, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M64 0C28.7 0 0 28.7 0 64V416c0 35.3 28.7 64 64 64H80l16 32h64l16-32H400l16 32h64l16-32h16c35.3 0 64-28.7 64-64V64c0-35.3-28.7-64-64-64H64zM224 320a80 80 0 1 0 0-160 80 80 0 1 0 0 160zm0-240a160 160 0 1 1 0 320 160 160 0 1 1 0-320zM480 221.3V336c0 8.8-7.2 16-16 16s-16-7.2-16-16V221.3c-18.6-6.6-32-24.4-32-45.3c0-26.5 21.5-48 48-48s48 21.5 48 48c0 20.9-13.4 38.7-32 45.3z" } }, "free": ["solid"] }, "vector-square": { "aliases": { "unicodes": { "secondary": ["10f5cb"] } }, "changes": ["5.1.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["anchors", "lines", "object", "render", "shape"] }, "styles": ["solid"], "unicode": "f5cb", "label": "Vector Square", "voted": false, "svg": { "solid": { "last_modified": 1684767367, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M368 80h32v32H368V80zM352 32c-17.7 0-32 14.3-32 32H128c0-17.7-14.3-32-32-32H32C14.3 32 0 46.3 0 64v64c0 17.7 14.3 32 32 32V352c-17.7 0-32 14.3-32 32v64c0 17.7 14.3 32 32 32H96c17.7 0 32-14.3 32-32H320c0 17.7 14.3 32 32 32h64c17.7 0 32-14.3 32-32V384c0-17.7-14.3-32-32-32V160c17.7 0 32-14.3 32-32V64c0-17.7-14.3-32-32-32H352zM96 160c17.7 0 32-14.3 32-32H320c0 17.7 14.3 32 32 32V352c-17.7 0-32 14.3-32 32H128c0-17.7-14.3-32-32-32V160zM48 400H80v32H48V400zm320 32V400h32v32H368zM48 112V80H80v32H48z" } }, "free": ["solid"] }, "venus": { "aliases": { "unicodes": { "composite": ["2640"], "secondary": ["10f221"] } }, "changes": [ "4.3.0", "5.0.0", "5.11.0", "5.11.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["female", "female sign", "gender", "woman"] }, "styles": ["solid"], "unicode": "f221", "label": "Venus", "voted": false, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M80 176a112 112 0 1 1 224 0A112 112 0 1 1 80 176zM224 349.1c81.9-15 144-86.8 144-173.1C368 78.8 289.2 0 192 0S16 78.8 16 176c0 86.3 62.1 158.1 144 173.1V384H128c-17.7 0-32 14.3-32 32s14.3 32 32 32h32v32c0 17.7 14.3 32 32 32s32-14.3 32-32V448h32c17.7 0 32-14.3 32-32s-14.3-32-32-32H224V349.1z" } }, "free": ["solid"] }, "venus-double": { "aliases": { "unicodes": { "composite": ["26a2"], "secondary": ["10f226"] } }, "changes": ["4.3.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Doubled Female Sign", "female", "gender", "lesbian"] }, "styles": ["solid"], "unicode": "f226", "label": "Venus Double", "voted": false, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M192 288a112 112 0 1 0 0-224 112 112 0 1 0 0 224zM368 176c0 86.3-62.1 158.1-144 173.1V384h32c17.7 0 32 14.3 32 32s-14.3 32-32 32H224v32c0 17.7-14.3 32-32 32s-32-14.3-32-32V448H128c-17.7 0-32-14.3-32-32s14.3-32 32-32h32V349.1C78.1 334.1 16 262.3 16 176C16 78.8 94.8 0 192 0s176 78.8 176 176zM344 318c14.6-15.6 26.8-33.4 36-53c18.8 14.4 42.4 23 68 23c61.9 0 112-50.1 112-112s-50.1-112-112-112c-25.6 0-49.1 8.6-68 23c-9.3-19.5-21.5-37.4-36-53C373.1 12.6 409.1 0 448 0c97.2 0 176 78.8 176 176c0 86.3-62.1 158.1-144 173.1V384h32c17.7 0 32 14.3 32 32s-14.3 32-32 32H480v32c0 17.7-14.3 32-32 32s-32-14.3-32-32V448H384c-17.7 0-32-14.3-32-32s14.3-32 32-32h32V349.1c-26.6-4.9-51.1-15.7-72-31.1z" } }, "free": ["solid"] }, "venus-mars": { "aliases": { "unicodes": { "composite": ["26a4"], "secondary": ["10f228"] } }, "changes": ["4.3.0", "5.0.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "Interlocked Female and Male Sign", "female", "gender", "heterosexual", "male" ] }, "styles": ["solid"], "unicode": "f228", "label": "Venus Mars", "voted": false, "svg": { "solid": { "last_modified": 1684766751, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M176 288a112 112 0 1 0 0-224 112 112 0 1 0 0 224zM352 176c0 86.3-62.1 158.1-144 173.1V384h32c17.7 0 32 14.3 32 32s-14.3 32-32 32H208v32c0 17.7-14.3 32-32 32s-32-14.3-32-32V448H112c-17.7 0-32-14.3-32-32s14.3-32 32-32h32V349.1C62.1 334.1 0 262.3 0 176C0 78.8 78.8 0 176 0s176 78.8 176 176zM271.9 360.6c19.3-10.1 36.9-23.1 52.1-38.4c20 18.5 46.7 29.8 76.1 29.8c61.9 0 112-50.1 112-112s-50.1-112-112-112c-7.2 0-14.3 .7-21.1 2c-4.9-21.5-13-41.7-24-60.2C369.3 66 384.4 64 400 64c37 0 71.4 11.4 99.8 31l20.6-20.6L487 41c-6.9-6.9-8.9-17.2-5.2-26.2S494.3 0 504 0H616c13.3 0 24 10.7 24 24V136c0 9.7-5.8 18.5-14.8 22.2s-19.3 1.7-26.2-5.2l-33.4-33.4L545 140.2c19.5 28.4 31 62.7 31 99.8c0 97.2-78.8 176-176 176c-50.5 0-96-21.3-128.1-55.4z" } }, "free": ["solid"] }, "vest": { "aliases": { "unicodes": { "secondary": ["10e085"] } }, "changes": ["5.15.0", "5.15.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["biker", "fashion", "style"] }, "styles": ["solid"], "unicode": "e085", "label": "Vest", "voted": false, "svg": { "solid": { "last_modified": 1684767602, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M207.1 237.4L151.2 69.7C168.6 79.7 192.6 88 224 88s55.4-8.3 72.8-18.3L226.5 280.6c-1.6 4.9-2.5 10-2.5 15.2V464c0 26.5 21.5 48 48 48H400c26.5 0 48-21.5 48-48V270.5c0-9.5-2.8-18.7-8.1-26.6l-47.9-71.8c-5.3-7.9-8.1-17.1-8.1-26.6V128 54.3 48c0-26.5-21.5-48-48-48h-4.5c-.2 0-.4 0-.6 0c-.4 0-.8 0-1.2 0C311 0 295.7 9.7 285.7 18.8C276.4 27.2 257.2 40 224 40s-52.4-12.8-61.7-21.2C152.3 9.7 137 0 118.3 0c-.4 0-.8 0-1.2 0c-.2 0-.4 0-.6 0H112C85.5 0 64 21.5 64 48v6.3V128v17.5c0 9.5-2.8 18.7-8.1 26.6L8.1 243.9C2.8 251.8 0 261.1 0 270.5V464c0 26.5 21.5 48 48 48H176c9.9 0 19-3 26.7-8.1C195.9 492.2 192 478.5 192 464V295.8c0-8.6 1.4-17.1 4.1-25.3l11-33.1zM347.3 356.7l48 48c6.2 6.2 6.2 16.4 0 22.6s-16.4 6.2-22.6 0l-48-48c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0zm-294.6 48l48-48c6.2-6.2 16.4-6.2 22.6 0s6.2 16.4 0 22.6l-48 48c-6.2 6.2-16.4 6.2-22.6 0s-6.2-16.4 0-22.6z" } }, "free": ["solid"] }, "vest-patches": { "aliases": { "unicodes": { "secondary": ["10e086"] } }, "changes": ["5.15.0", "5.15.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["biker", "fashion", "style"] }, "styles": ["solid"], "unicode": "e086", "label": "Vest Patches", "voted": false, "svg": { "solid": { "last_modified": 1684767602, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M151.2 69.7l55.9 167.7-11 33.1c-2.7 8.2-4.1 16.7-4.1 25.3V464c0 14.5 3.9 28.2 10.7 39.9C195 509 185.9 512 176 512H48c-26.5 0-48-21.5-48-48V270.5c0-9.5 2.8-18.7 8.1-26.6l47.9-71.8c5.3-7.9 8.1-17.1 8.1-26.6V128 54.3 48C64 21.5 85.5 0 112 0h4.5c.2 0 .4 0 .6 0c.4 0 .8 0 1.2 0c18.8 0 34.1 9.7 44.1 18.8C171.6 27.2 190.8 40 224 40s52.4-12.8 61.7-21.2C295.7 9.7 311 0 329.7 0c.4 0 .8 0 1.2 0c.2 0 .4 0 .6 0H336c26.5 0 48 21.5 48 48v6.3V128v17.5c0 9.5 2.8 18.7 8.1 26.6l47.9 71.8c5.3 7.9 8.1 17.1 8.1 26.6V464c0 26.5-21.5 48-48 48H272c-26.5 0-48-21.5-48-48V295.8c0-5.2 .8-10.3 2.5-15.2L296.8 69.7C279.4 79.7 255.4 88 224 88s-55.4-8.3-72.8-18.3zM96 456a40 40 0 1 0 0-80 40 40 0 1 0 0 80zM63.5 255.5c-4.7 4.7-4.7 12.3 0 17L79 288 63.5 303.5c-4.7 4.7-4.7 12.3 0 17s12.3 4.7 17 0L96 305l15.5 15.5c4.7 4.7 12.3 4.7 17 0s4.7-12.3 0-17L113 288l15.5-15.5c4.7-4.7 4.7-12.3 0-17s-12.3-4.7-17 0L96 271 80.5 255.5c-4.7-4.7-12.3-4.7-17 0zM304 280v8 32c0 8.8 7.2 16 16 16h32 8c13.3 0 24-10.7 24-24s-10.7-24-24-24h-8v-8c0-13.3-10.7-24-24-24s-24 10.7-24 24z" } }, "free": ["solid"] }, "viacoin": { "changes": ["4.3.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f237", "label": "Viacoin", "voted": false, "svg": { "brands": { "last_modified": 1660014459, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M384 32h-64l-80.7 192h-94.5L64 32H0l48 112H0v48h68.5l13.8 32H0v48h102.8L192 480l89.2-208H384v-48h-82.3l13.8-32H384v-48h-48l48-112zM192 336l-27-64h54l-27 64z" } }, "free": ["brands"] }, "viadeo": { "changes": ["4.6.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f2a9", "label": "Viadeo", "voted": false, "svg": { "brands": { "last_modified": 1660014465, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M276.2 150.5v.7C258.3 98.6 233.6 47.8 205.4 0c43.3 29.2 67 100 70.8 150.5zm32.7 121.7c7.6 18.2 11 37.5 11 57 0 77.7-57.8 141-137.8 139.4l3.8-.3c74.2-46.7 109.3-118.6 109.3-205.1 0-38.1-6.5-75.9-18.9-112 1 11.7 1 23.7 1 35.4 0 91.8-18.1 241.6-116.6 280C95 455.2 49.4 398 49.4 329.2c0-75.6 57.4-142.3 135.4-142.3 16.8 0 33.7 3.1 49.1 9.6 1.7-15.1 6.5-29.9 13.4-43.3-19.9-7.2-41.2-10.7-62.5-10.7-161.5 0-238.7 195.9-129.9 313.7 67.9 74.6 192 73.9 259.8 0 56.6-61.3 60.9-142.4 36.4-201-12.7 8-27.1 13.9-42.2 17zM418.1 11.7c-31 66.5-81.3 47.2-115.8 80.1-12.4 12-20.6 34-20.6 50.5 0 14.1 4.5 27.1 12 38.8 47.4-11 98.3-46 118.2-90.7-.7 5.5-4.8 14.4-7.2 19.2-20.3 35.7-64.6 65.6-99.7 84.9 14.8 14.4 33.7 25.8 55 25.8 79 0 110.1-134.6 58.1-208.6z" } }, "free": ["brands"] }, "vial": { "aliases": { "unicodes": { "composite": ["1f9ea"], "secondary": ["10f492"] } }, "changes": ["5.0.7", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "ampule", "chemist", "chemistry", "experiment", "lab", "sample", "science", "test", "test tube" ] }, "styles": ["solid"], "unicode": "f492", "label": "Vial", "voted": false, "svg": { "solid": { "last_modified": 1684766751, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M342.6 9.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l9.4 9.4L28.1 342.6C10.1 360.6 0 385 0 410.5V416c0 53 43 96 96 96h5.5c25.5 0 49.9-10.1 67.9-28.1L448 205.3l9.4 9.4c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3l-32-32-96-96-32-32zM205.3 256L352 109.3 402.7 160l-96 96H205.3z" } }, "free": ["solid"] }, "vial-circle-check": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "ampule", "chemist", "chemistry", "not affected", "ok", "okay", "success", "test tube", "tube", "vaccine" ] }, "styles": ["solid"], "unicode": "e596", "label": "Vial Circle Check", "voted": false, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 64C0 46.3 14.3 32 32 32H96h64 64c17.7 0 32 14.3 32 32s-14.3 32-32 32V266.8c-20.2 28.6-32 63.5-32 101.2c0 25.2 5.3 49.1 14.8 70.8C189.5 463.7 160.6 480 128 480c-53 0-96-43-96-96V96C14.3 96 0 81.7 0 64zM96 96v96h64V96H96zM224 368a144 144 0 1 1 288 0 144 144 0 1 1 -288 0zm211.3-43.3c-6.2-6.2-16.4-6.2-22.6 0L352 385.4l-28.7-28.7c-6.2-6.2-16.4-6.2-22.6 0s-6.2 16.4 0 22.6l40 40c6.2 6.2 16.4 6.2 22.6 0l72-72c6.2-6.2 6.2-16.4 0-22.6z" } }, "free": ["solid"] }, "vial-virus": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "ampule", "coronavirus", "covid-19", "flue", "infection", "lab", "laboratory", "pandemic", "test", "test tube", "vaccine" ] }, "styles": ["solid"], "unicode": "e597", "label": "Vial Virus", "voted": false, "svg": { "solid": { "last_modified": 1684766751, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M32 32C14.3 32 0 46.3 0 64S14.3 96 32 96V384c0 53 43 96 96 96c28.6 0 54.2-12.5 71.8-32.3c.1-14.2 5.6-28.3 16.4-39.1c.2-.2 .1-.6-.2-.6c-30.9 0-56-25.1-56-56s25.1-56 56-56c.3 0 .4-.4 .2-.6c-21.9-21.9-21.9-57.3 0-79.2c2.4-2.4 5-4.6 7.8-6.5V96c17.7 0 32-14.3 32-32s-14.3-32-32-32H160 96 32zM96 192V96h64v96H96zM216 376c28.8 0 43.2 34.8 22.9 55.2c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0c20.4-20.4 55.2-5.9 55.2 22.9c0 13.3 10.7 24 24 24s24-10.7 24-24c0-28.8 34.8-43.2 55.2-22.9c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9C444.8 410.8 459.2 376 488 376c13.3 0 24-10.7 24-24s-10.7-24-24-24c-28.8 0-43.2-34.8-22.9-55.2c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0C410.8 259.2 376 244.8 376 216c0-13.3-10.7-24-24-24s-24 10.7-24 24c0 28.8-34.8 43.2-55.2 22.9c-9.4-9.4-24.6-9.4-33.9 0s-9.4 24.6 0 33.9c20.4 20.4 5.9 55.2-22.9 55.2c-13.3 0-24 10.7-24 24s10.7 24 24 24zm104-88a32 32 0 1 1 0 64 32 32 0 1 1 0-64zm40 96a24 24 0 1 1 48 0 24 24 0 1 1 -48 0z" } }, "free": ["solid"] }, "vials": { "aliases": { "unicodes": { "secondary": ["10f493"] } }, "changes": ["5.0.7", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "ampule", "experiment", "lab", "sample", "science", "test", "test tube" ] }, "styles": ["solid"], "unicode": "f493", "label": "Vials", "voted": false, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 64C0 46.3 14.3 32 32 32H88h48 56c17.7 0 32 14.3 32 32s-14.3 32-32 32V400c0 44.2-35.8 80-80 80s-80-35.8-80-80V96C14.3 96 0 81.7 0 64zM136 96H88V256h48V96zM288 64c0-17.7 14.3-32 32-32h56 48 56c17.7 0 32 14.3 32 32s-14.3 32-32 32V400c0 44.2-35.8 80-80 80s-80-35.8-80-80V96c-17.7 0-32-14.3-32-32zM424 96H376V256h48V96z" } }, "free": ["solid"] }, "viber": { "changes": ["5.0.0", "5.0.3"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f409", "label": "Viber", "voted": false, "svg": { "brands": { "last_modified": 1660014468, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M444 49.9C431.3 38.2 379.9.9 265.3.4c0 0-135.1-8.1-200.9 52.3C27.8 89.3 14.9 143 13.5 209.5c-1.4 66.5-3.1 191.1 117 224.9h.1l-.1 51.6s-.8 20.9 13 25.1c16.6 5.2 26.4-10.7 42.3-27.8 8.7-9.4 20.7-23.2 29.8-33.7 82.2 6.9 145.3-8.9 152.5-11.2 16.6-5.4 110.5-17.4 125.7-142 15.8-128.6-7.6-209.8-49.8-246.5zM457.9 287c-12.9 104-89 110.6-103 115.1-6 1.9-61.5 15.7-131.2 11.2 0 0-52 62.7-68.2 79-5.3 5.3-11.1 4.8-11-5.7 0-6.9.4-85.7.4-85.7-.1 0-.1 0 0 0-101.8-28.2-95.8-134.3-94.7-189.8 1.1-55.5 11.6-101 42.6-131.6 55.7-50.5 170.4-43 170.4-43 96.9.4 143.3 29.6 154.1 39.4 35.7 30.6 53.9 103.8 40.6 211.1zm-139-80.8c.4 8.6-12.5 9.2-12.9.6-1.1-22-11.4-32.7-32.6-33.9-8.6-.5-7.8-13.4.7-12.9 27.9 1.5 43.4 17.5 44.8 46.2zm20.3 11.3c1-42.4-25.5-75.6-75.8-79.3-8.5-.6-7.6-13.5.9-12.9 58 4.2 88.9 44.1 87.8 92.5-.1 8.6-13.1 8.2-12.9-.3zm47 13.4c.1 8.6-12.9 8.7-12.9.1-.6-81.5-54.9-125.9-120.8-126.4-8.5-.1-8.5-12.9 0-12.9 73.7.5 133 51.4 133.7 139.2zM374.9 329v.2c-10.8 19-31 40-51.8 33.3l-.2-.3c-21.1-5.9-70.8-31.5-102.2-56.5-16.2-12.8-31-27.9-42.4-42.4-10.3-12.9-20.7-28.2-30.8-46.6-21.3-38.5-26-55.7-26-55.7-6.7-20.8 14.2-41 33.3-51.8h.2c9.2-4.8 18-3.2 23.9 3.9 0 0 12.4 14.8 17.7 22.1 5 6.8 11.7 17.7 15.2 23.8 6.1 10.9 2.3 22-3.7 26.6l-12 9.6c-6.1 4.9-5.3 14-5.3 14s17.8 67.3 84.3 84.3c0 0 9.1.8 14-5.3l9.6-12c4.6-6 15.7-9.8 26.6-3.7 14.7 8.3 33.4 21.2 45.8 32.9 7 5.7 8.6 14.4 3.8 23.6z" } }, "free": ["brands"] }, "video": { "aliases": { "names": ["video-camera"], "unicodes": { "secondary": ["10f03d"] } }, "changes": [ "1.0.0", "5.0.0", "5.0.9", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["camera", "film", "movie", "record", "video-camera"] }, "styles": ["solid"], "unicode": "f03d", "label": "Video", "voted": false, "svg": { "solid": { "last_modified": 1684767341, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M0 128C0 92.7 28.7 64 64 64H320c35.3 0 64 28.7 64 64V384c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V128zM559.1 99.8c10.4 5.6 16.9 16.4 16.9 28.2V384c0 11.8-6.5 22.6-16.9 28.2s-23 5-32.9-1.6l-96-64L416 337.1V320 192 174.9l14.2-9.5 96-64c9.8-6.5 22.4-7.2 32.9-1.6z" } }, "free": ["solid"] }, "video-slash": { "aliases": { "unicodes": { "secondary": ["10f4e2"] } }, "changes": ["5.0.9", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["add", "create", "film", "new", "positive", "record", "video"] }, "styles": ["solid"], "unicode": "f4e2", "label": "Video Slash", "voted": false, "svg": { "solid": { "last_modified": 1684767341, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7l-86.4-67.7 13.8 9.2c9.8 6.5 22.4 7.2 32.9 1.6s16.9-16.4 16.9-28.2V128c0-11.8-6.5-22.6-16.9-28.2s-23-5-32.9 1.6l-96 64L448 174.9V192 320v5.8l-32-25.1V128c0-35.3-28.7-64-64-64H113.9L38.8 5.1zM407 416.7L32.3 121.5c-.2 2.1-.3 4.3-.3 6.5V384c0 35.3 28.7 64 64 64H352c23.4 0 43.9-12.6 55-31.3z" } }, "free": ["solid"] }, "vihara": { "aliases": { "unicodes": { "secondary": ["10f6a7"] } }, "changes": [ "5.3.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["buddhism", "buddhist", "building", "monastery"] }, "styles": ["solid"], "unicode": "f6a7", "label": "Vihara", "voted": false, "svg": { "solid": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M281 22L305.8 4.7c1.3-.9 2.7-1.8 4.1-2.4C313.1 .7 316.6 0 320 0s6.9 .7 10.1 2.2c1.4 .7 2.8 1.5 4.1 2.4L359 22C393 45.8 430.8 63.5 470.8 74.4l23 6.3c1.8 .5 3.6 1.1 5.2 2c3.2 1.7 5.9 4 8.1 6.8c3.8 4.9 5.6 11.3 4.7 17.8c-.4 2.8-1.2 5.4-2.5 7.8c-1.7 3.2-4 5.9-6.8 8.1c-4.3 3.2-9.6 5.1-15.1 4.9H480v56.1l6.4 5.1 5.2 4.1c21.1 16.7 45 29.6 70.5 38.1l28.9 9.6c1.6 .5 3.2 1.2 4.6 2c3.1 1.7 5.8 4.1 7.8 6.9s3.5 6.1 4.1 9.6c.5 2.7 .6 5.5 .1 8.3s-1.4 5.4-2.7 7.8c-1.7 3.1-4.1 5.8-6.9 7.8s-6.1 3.5-9.6 4.1c-1.6 .3-3.3 .4-5 .4H544v65.9c20.5 22.8 47.4 39.2 77.4 46.7C632 403 640 412.6 640 424c0 13.3-10.7 24-24 24H576v32c0 17.7-14.3 32-32 32s-32-14.3-32-32V448H352v32c0 17.7-14.3 32-32 32s-32-14.3-32-32V448H128v32c0 17.7-14.3 32-32 32s-32-14.3-32-32V448H24c-13.3 0-24-10.7-24-24c0-11.4 8-21 18.6-23.4c30-7.6 56.9-23.9 77.4-46.7V288H56.6c-1.7 0-3.4-.1-5-.4c-3.5-.7-6.8-2.1-9.6-4.1s-5.2-4.7-7-7.8c-1.3-2.4-2.3-5-2.7-7.8s-.4-5.6 .1-8.3c.7-3.5 2.1-6.8 4.1-9.6s4.7-5.2 7.8-6.9c1.4-.8 3-1.5 4.6-2l28.9-9.6c25.5-8.5 49.4-21.4 70.5-38.1l5.2-4.1 6.4-5.1V176 128h-7.5c-5.5 .1-10.8-1.7-15.1-4.9c-2.8-2.1-5.1-4.8-6.8-8.1c-1.2-2.4-2.1-5-2.5-7.8c-.9-6.5 .9-12.8 4.7-17.8c2.1-2.8 4.8-5.1 8.1-6.8c1.6-.8 3.4-1.5 5.2-2l23-6.3C209.2 63.5 247 45.8 281 22zM416 128H320 224v64h72 48 72V128zM160 288v64H296h24 24H480V288H344 320h0H296 160z" } }, "free": ["solid"] }, "vimeo": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f40a", "label": "Vimeo", "voted": false, "svg": { "brands": { "last_modified": 1660014466, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M403.2 32H44.8C20.1 32 0 52.1 0 76.8v358.4C0 459.9 20.1 480 44.8 480h358.4c24.7 0 44.8-20.1 44.8-44.8V76.8c0-24.7-20.1-44.8-44.8-44.8zM377 180.8c-1.4 31.5-23.4 74.7-66 129.4-44 57.2-81.3 85.8-111.7 85.8-18.9 0-34.8-17.4-47.9-52.3-25.5-93.3-36.4-148-57.4-148-2.4 0-10.9 5.1-25.4 15.2l-15.2-19.6c37.3-32.8 72.9-69.2 95.2-71.2 25.2-2.4 40.7 14.8 46.5 51.7 20.7 131.2 29.9 151 67.6 91.6 13.5-21.4 20.8-37.7 21.8-48.9 3.5-33.2-25.9-30.9-45.8-22.4 15.9-52.1 46.3-77.4 91.2-76 33.3.9 49 22.5 47.1 64.7z" } }, "free": ["brands"] }, "vimeo-v": { "changes": ["4.4.0", "5.0.0"], "ligatures": [], "search": { "terms": ["vimeo"] }, "styles": ["brands"], "unicode": "f27d", "label": "Vimeo", "voted": false, "svg": { "brands": { "last_modified": 1660014481, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M447.8 153.6c-2 43.6-32.4 103.3-91.4 179.1-60.9 79.2-112.4 118.8-154.6 118.8-26.1 0-48.2-24.1-66.3-72.3C100.3 250 85.3 174.3 56.2 174.3c-3.4 0-15.1 7.1-35.2 21.1L0 168.2c51.6-45.3 100.9-95.7 131.8-98.5 34.9-3.4 56.3 20.5 64.4 71.5 28.7 181.5 41.4 208.9 93.6 126.7 18.7-29.6 28.8-52.1 30.2-67.6 4.8-45.9-35.8-42.8-63.3-31 22-72.1 64.1-107.1 126.2-105.1 45.8 1.2 67.5 31.1 64.9 89.4z" } }, "free": ["brands"] }, "vine": { "changes": ["4.1.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f1ca", "label": "Vine", "voted": false, "svg": { "brands": { "last_modified": 1660014471, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M384 254.7v52.1c-18.4 4.2-36.9 6.1-52.1 6.1-36.9 77.4-103 143.8-125.1 156.2-14 7.9-27.1 8.4-42.7-.8C137 452 34.2 367.7 0 102.7h74.5C93.2 261.8 139 343.4 189.3 404.5c27.9-27.9 54.8-65.1 75.6-106.9-49.8-25.3-80.1-80.9-80.1-145.6 0-65.6 37.7-115.1 102.2-115.1 114.9 0 106.2 127.9 81.6 181.5 0 0-46.4 9.2-63.5-20.5 3.4-11.3 8.2-30.8 8.2-48.5 0-31.3-11.3-46.6-28.4-46.6-18.2 0-30.8 17.1-30.8 50 .1 79.2 59.4 118.7 129.9 101.9z" } }, "free": ["brands"] }, "virus": { "aliases": { "unicodes": { "secondary": ["10e074"] } }, "changes": [ "5.13.0", "5.14.0", "6.0.0-beta1", "6.1.0", "6.1.2", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "bug", "coronavirus", "covid-19", "flu", "health", "infection", "pandemic", "sick", "vaccine", "viral" ] }, "styles": ["solid"], "unicode": "e074", "label": "Virus", "voted": false, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M288 32c0-17.7-14.3-32-32-32s-32 14.3-32 32V43.5c0 49.9-60.3 74.9-95.6 39.6L120.2 75C107.7 62.5 87.5 62.5 75 75s-12.5 32.8 0 45.3l8.2 8.2C118.4 163.7 93.4 224 43.5 224H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H43.5c49.9 0 74.9 60.3 39.6 95.6L75 391.8c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l8.2-8.2c35.3-35.3 95.6-10.3 95.6 39.6V480c0 17.7 14.3 32 32 32s32-14.3 32-32V468.5c0-49.9 60.3-74.9 95.6-39.6l8.2 8.2c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3l-8.2-8.2c-35.3-35.3-10.3-95.6 39.6-95.6H480c17.7 0 32-14.3 32-32s-14.3-32-32-32H468.5c-49.9 0-74.9-60.3-39.6-95.6l8.2-8.2c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-8.2 8.2C348.3 118.4 288 93.4 288 43.5V32zM176 224a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zm128 56a24 24 0 1 1 0 48 24 24 0 1 1 0-48z" } }, "free": ["solid"] }, "virus-covid": { "changes": ["6.0.0", "6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "bug", "covid-19", "flu", "health", "infection", "pandemic", "vaccine", "viral", "virus" ] }, "styles": ["solid"], "unicode": "e4a8", "label": "Virus Covid", "voted": false, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M192 24c0-13.3 10.7-24 24-24h80c13.3 0 24 10.7 24 24s-10.7 24-24 24H280V81.6c30.7 4.2 58.8 16.3 82.3 34.1L386.1 92 374.8 80.6c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l56.6 56.6c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0L420 125.9l-23.8 23.8c17.9 23.5 29.9 51.7 34.1 82.3H464V216c0-13.3 10.7-24 24-24s24 10.7 24 24v80c0 13.3-10.7 24-24 24s-24-10.7-24-24V280H430.4c-4.2 30.7-16.3 58.8-34.1 82.3L420 386.1l11.3-11.3c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-56.6 56.6c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9L386.1 420l-23.8-23.8c-23.5 17.9-51.7 29.9-82.3 34.1V464h16c13.3 0 24 10.7 24 24s-10.7 24-24 24H216c-13.3 0-24-10.7-24-24s10.7-24 24-24h16V430.4c-30.7-4.2-58.8-16.3-82.3-34.1L125.9 420l11.3 11.3c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0L46.7 408.7c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0L92 386.1l23.8-23.8C97.9 338.8 85.8 310.7 81.6 280H48v16c0 13.3-10.7 24-24 24s-24-10.7-24-24V216c0-13.3 10.7-24 24-24s24 10.7 24 24v16H81.6c4.2-30.7 16.3-58.8 34.1-82.3L92 125.9 80.6 137.2c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l56.6-56.6c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9L125.9 92l23.8 23.8c23.5-17.9 51.7-29.9 82.3-34.1V48H216c-13.3 0-24-10.7-24-24zm48 200a48 48 0 1 0 -96 0 48 48 0 1 0 96 0zm64 104a24 24 0 1 0 0-48 24 24 0 1 0 0 48z" } }, "free": ["solid"] }, "virus-covid-slash": { "changes": ["6.0.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "bug", "covid-19", "flu", "health", "infection", "pandemic", "vaccine", "viral", "virus" ] }, "styles": ["solid"], "unicode": "e4a9", "label": "Virus Covid Slash", "voted": false, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7L472.1 344.7c11.4-19.5 19.1-41.4 22.3-64.7H528v16c0 13.3 10.7 24 24 24s24-10.7 24-24V216c0-13.3-10.7-24-24-24s-24 10.7-24 24v16H494.4c-4.2-30.7-16.3-58.8-34.1-82.3L484 125.9l11.3 11.3c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9L472.7 46.7c-9.4-9.4-24.6-9.4-33.9 0s-9.4 24.6 0 33.9L450.1 92l-23.8 23.8C402.8 97.9 374.7 85.8 344 81.6V48h16c13.3 0 24-10.7 24-24s-10.7-24-24-24H280c-13.3 0-24 10.7-24 24s10.7 24 24 24h16V81.6c-30.7 4.2-58.8 16.3-82.3 34.1L189.9 92l11.3-11.3c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0L134.1 79.8 38.8 5.1zM149.2 213.5c-1.5 6-2.7 12.2-3.5 18.5H112V216c0-13.3-10.7-24-24-24s-24 10.7-24 24v80c0 13.3 10.7 24 24 24s24-10.7 24-24V280h33.6c4.2 30.7 16.3 58.8 34.1 82.3L156 386.1l-11.3-11.3c-9.4-9.4-24.6-9.4-33.9 0s-9.4 24.6 0 33.9l56.6 56.6c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9L189.9 420l23.8-23.8c23.5 17.9 51.7 29.9 82.3 34.1V464H280c-13.3 0-24 10.7-24 24s10.7 24 24 24h80c13.3 0 24-10.7 24-24s-10.7-24-24-24H344V430.4c20.4-2.8 39.7-9.1 57.3-18.2L149.2 213.5z" } }, "free": ["solid"] }, "virus-slash": { "aliases": { "unicodes": { "secondary": ["10e075"] } }, "changes": [ "5.13.0", "5.14.0", "6.0.0-beta1", "6.1.2", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "bug", "coronavirus", "covid-19", "cure", "eliminate", "flu", "health", "infection", "pandemic", "sick", "vaccine", "viral" ] }, "styles": ["solid"], "unicode": "e075", "label": "Virus Slash", "voted": false, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7l-154.3-121c-2-30.1 20.8-60.1 56-60.1H544c17.7 0 32-14.3 32-32s-14.3-32-32-32H532.5c-49.9 0-74.9-60.3-39.6-95.6l8.2-8.2c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-8.2 8.2C412.3 118.4 352 93.4 352 43.5V32c0-17.7-14.3-32-32-32s-32 14.3-32 32V43.5c0 49.9-60.3 74.9-95.6 39.6L184.2 75c-12.5-12.5-32.8-12.5-45.3 0c-1.6 1.6-3.1 3.4-4.3 5.3L38.8 5.1zm225.8 177c6.9-3.9 14.9-6.1 23.4-6.1c26.5 0 48 21.5 48 48c0 4.4-.6 8.7-1.7 12.7l-69.7-54.6zM402 412.7L144.7 210c-9.5 8.5-22.2 14-37.2 14H96c-17.7 0-32 14.3-32 32s14.3 32 32 32h11.5c49.9 0 74.9 60.3 39.6 95.6l-8.2 8.2c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l8.2-8.2c35.3-35.3 95.6-10.3 95.6 39.6V480c0 17.7 14.3 32 32 32s32-14.3 32-32V468.5c0-31.2 23.6-52.7 50-55.7z" } }, "free": ["solid"] }, "viruses": { "aliases": { "unicodes": { "secondary": ["10e076"] } }, "changes": ["5.13.0", "5.14.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "bugs", "coronavirus", "covid-19", "flu", "health", "infection", "multiply", "pandemic", "sick", "spread", "vaccine", "viral" ] }, "styles": ["solid"], "unicode": "e076", "label": "Viruses", "voted": false, "svg": { "solid": { "last_modified": 1684766750, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M192 0c13.3 0 24 10.7 24 24V37.5c0 35.6 43.1 53.5 68.3 28.3l9.5-9.5c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-9.5 9.5C293 124.9 310.9 168 346.5 168H360c13.3 0 24 10.7 24 24s-10.7 24-24 24H346.5c-35.6 0-53.5 43.1-28.3 68.3l9.5 9.5c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-9.5-9.5C259.1 293 216 310.9 216 346.5V360c0 13.3-10.7 24-24 24s-24-10.7-24-24V346.5c0-35.6-43.1-53.5-68.3-28.3l-9.5 9.5c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l9.5-9.5C91 259.1 73.1 216 37.5 216H24c-13.3 0-24-10.7-24-24s10.7-24 24-24H37.5c35.6 0 53.5-43.1 28.3-68.3l-9.5-9.5c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l9.5 9.5C124.9 91 168 73.1 168 37.5V24c0-13.3 10.7-24 24-24zm48 224a16 16 0 1 0 0-32 16 16 0 1 0 0 32zm-48-64a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zm320 80c0 33 39.9 49.5 63.2 26.2c6.2-6.2 16.4-6.2 22.6 0s6.2 16.4 0 22.6C574.5 312.1 591 352 624 352c8.8 0 16 7.2 16 16s-7.2 16-16 16c-33 0-49.5 39.9-26.2 63.2c6.2 6.2 6.2 16.4 0 22.6s-16.4 6.2-22.6 0C551.9 446.5 512 463 512 496c0 8.8-7.2 16-16 16s-16-7.2-16-16c0-33-39.9-49.5-63.2-26.2c-6.2 6.2-16.4 6.2-22.6 0s-6.2-16.4 0-22.6C417.5 423.9 401 384 368 384c-8.8 0-16-7.2-16-16s7.2-16 16-16c33 0 49.5-39.9 26.2-63.2c-6.2-6.2-6.2-16.4 0-22.6s16.4-6.2 22.6 0C440.1 289.5 480 273 480 240c0-8.8 7.2-16 16-16s16 7.2 16 16zm0 112a32 32 0 1 0 -64 0 32 32 0 1 0 64 0z" } }, "free": ["solid"] }, "vk": { "changes": ["3.2.0", "5.0.0", "6.0.0-beta3"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f189", "label": "VK", "voted": false, "svg": { "brands": { "last_modified": 1660014481, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M31.4907 63.4907C0 94.9813 0 145.671 0 247.04V264.96C0 366.329 0 417.019 31.4907 448.509C62.9813 480 113.671 480 215.04 480H232.96C334.329 480 385.019 480 416.509 448.509C448 417.019 448 366.329 448 264.96V247.04C448 145.671 448 94.9813 416.509 63.4907C385.019 32 334.329 32 232.96 32H215.04C113.671 32 62.9813 32 31.4907 63.4907ZM75.6 168.267H126.747C128.427 253.76 166.133 289.973 196 297.44V168.267H244.16V242C273.653 238.827 304.64 205.227 315.093 168.267H363.253C359.313 187.435 351.46 205.583 340.186 221.579C328.913 237.574 314.461 251.071 297.733 261.227C316.41 270.499 332.907 283.63 346.132 299.751C359.357 315.873 369.01 334.618 374.453 354.747H321.44C316.555 337.262 306.614 321.61 292.865 309.754C279.117 297.899 262.173 290.368 244.16 288.107V354.747H238.373C136.267 354.747 78.0267 284.747 75.6 168.267Z" } }, "free": ["brands"] }, "vnv": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f40b", "label": "VNV", "voted": false, "svg": { "brands": { "last_modified": 1660014482, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M104.9 352c-34.1 0-46.4-30.4-46.4-30.4L2.6 210.1S-7.8 192 13 192h32.8c10.4 0 13.2 8.7 18.8 18.1l36.7 74.5s5.2 13.1 21.1 13.1 21.1-13.1 21.1-13.1l36.7-74.5c5.6-9.5 8.4-18.1 18.8-18.1h32.8c20.8 0 10.4 18.1 10.4 18.1l-55.8 111.5S174.2 352 140 352h-35.1zm395 0c-34.1 0-46.4-30.4-46.4-30.4l-55.9-111.5S387.2 192 408 192h32.8c10.4 0 13.2 8.7 18.8 18.1l36.7 74.5s5.2 13.1 21.1 13.1 21.1-13.1 21.1-13.1l36.8-74.5c5.6-9.5 8.4-18.1 18.8-18.1H627c20.8 0 10.4 18.1 10.4 18.1l-55.9 111.5S569.3 352 535.1 352h-35.2zM337.6 192c34.1 0 46.4 30.4 46.4 30.4l55.9 111.5s10.4 18.1-10.4 18.1h-32.8c-10.4 0-13.2-8.7-18.8-18.1l-36.7-74.5s-5.2-13.1-21.1-13.1c-15.9 0-21.1 13.1-21.1 13.1l-36.7 74.5c-5.6 9.4-8.4 18.1-18.8 18.1h-32.9c-20.8 0-10.4-18.1-10.4-18.1l55.9-111.5s12.2-30.4 46.4-30.4h35.1z" } }, "free": ["brands"] }, "voicemail": { "aliases": { "unicodes": { "secondary": ["10f897"] } }, "changes": ["5.9.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["answer", "inbox", "message", "phone"] }, "styles": ["solid"], "unicode": "f897", "label": "Voicemail", "voted": true, "svg": { "solid": { "last_modified": 1684767389, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M144 320a80 80 0 1 1 0-160 80 80 0 1 1 0 160zm119.8 0c15.3-22.9 24.2-50.4 24.2-80c0-79.5-64.5-144-144-144S0 160.5 0 240s64.5 144 144 144H496c79.5 0 144-64.5 144-144s-64.5-144-144-144s-144 64.5-144 144c0 29.6 8.9 57.1 24.2 80H263.8zM496 160a80 80 0 1 1 0 160 80 80 0 1 1 0-160z" } }, "free": ["solid"] }, "volcano": { "aliases": { "unicodes": { "composite": ["1f30b"], "secondary": ["10f770"] } }, "changes": [ "5.5.0", "5.10.2", "6.0.0-beta1", "6.1.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "caldera", "eruption", "lava", "magma", "mountain", "smoke", "volcano" ] }, "styles": ["solid"], "unicode": "f770", "label": "Volcano", "voted": false, "svg": { "solid": { "last_modified": 1684767662, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M160 144c-35.3 0-64-28.7-64-64s28.7-64 64-64c15.7 0 30 5.6 41.2 15C212.4 12.4 232.7 0 256 0s43.6 12.4 54.8 31C322 21.6 336.3 16 352 16c35.3 0 64 28.7 64 64s-28.7 64-64 64c-14.7 0-28.3-5-39.1-13.3l-32 48C275.3 187 266 192 256 192s-19.3-5-24.9-13.3l-32-48C188.3 139 174.7 144 160 144zM144 352l48.4-24.2c10.2-5.1 21.6-7.8 33-7.8c19.6 0 38.4 7.8 52.2 21.6l32.5 32.5c6.3 6.3 14.9 9.9 23.8 9.9c11.3 0 21.8-5.6 28-15l9.7-14.6-58.9-66.3c-9.1-10.2-22.2-16.1-35.9-16.1H235.1c-13.7 0-26.8 5.9-35.9 16.1l-59.9 67.4L144 352zm19.4-95.8c18.2-20.5 44.3-32.2 71.8-32.2h41.8c27.4 0 53.5 11.7 71.8 32.2l150.2 169c8.5 9.5 13.2 21.9 13.2 34.7c0 28.8-23.4 52.2-52.2 52.2H52.2C23.4 512 0 488.6 0 459.8c0-12.8 4.7-25.1 13.2-34.7l150.2-169z" } }, "free": ["solid"] }, "volleyball": { "aliases": { "names": ["volleyball-ball"], "unicodes": { "composite": ["1f3d0"], "secondary": ["10f45f"] } }, "changes": ["5.0.5", "5.8.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["ball", "beach", "game", "olympics", "sport", "volleyball"] }, "styles": ["solid"], "unicode": "f45f", "label": "Volleyball", "voted": false, "svg": { "solid": { "last_modified": 1684767071, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M511.8 267.4c-26.1 8.7-53.4 13.8-81 15.1c9.2-105.3-31.5-204.2-103.2-272.4C434.1 41.1 512 139.5 512 256c0 3.8-.1 7.6-.2 11.4zm-3.9 34.7c-5.8 32-17.6 62-34.2 88.7c-97.5 48.5-217.7 42.6-311.9-24.5c23.7-36.2 55.4-67.7 94.5-91.8c79.9 43.2 170.1 50.8 251.6 27.6zm-236-55.5c-2.5-90.9-41.1-172.7-101.9-231.7C196.8 5.2 225.8 0 256 0c2.7 0 5.3 0 7.9 .1c90.8 60.2 145.7 167.2 134.7 282.3c-43.1-2.4-86.4-14.1-126.8-35.9zM138 28.8c20.6 18.3 38.7 39.4 53.7 62.6C95.9 136.1 30.6 220.8 7.3 316.9C2.5 297.4 0 277 0 256C0 157.2 56 71.5 138 28.8zm69.6 90.5c19.5 38.6 31 81.9 32.3 127.7C162.5 294.6 110.9 368.9 90.2 451C66 430.4 45.6 405.4 30.4 377.2c6.7-108.7 71.9-209.9 177.1-257.9zM256 512c-50.7 0-98-14.7-137.8-40.2c5.6-27 14.8-53.1 27.4-77.7C232.2 454.6 338.1 468.8 433 441c-46 44-108.3 71-177 71z" } }, "free": ["solid"] }, "volume-high": { "aliases": { "names": ["volume-up"], "unicodes": { "composite": ["1f50a"], "secondary": ["10f028"] } }, "changes": [ "1.0.0", "5.0.0", "5.3.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "audio", "higher", "loud", "louder", "music", "sound", "speaker", "speaker high volume" ] }, "styles": ["solid"], "unicode": "f028", "label": "Volume High", "voted": false, "svg": { "solid": { "last_modified": 1684766676, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M533.6 32.5C598.5 85.3 640 165.8 640 256s-41.5 170.8-106.4 223.5c-10.3 8.4-25.4 6.8-33.8-3.5s-6.8-25.4 3.5-33.8C557.5 398.2 592 331.2 592 256s-34.5-142.2-88.7-186.3c-10.3-8.4-11.8-23.5-3.5-33.8s23.5-11.8 33.8-3.5zM473.1 107c43.2 35.2 70.9 88.9 70.9 149s-27.7 113.8-70.9 149c-10.3 8.4-25.4 6.8-33.8-3.5s-6.8-25.4 3.5-33.8C475.3 341.3 496 301.1 496 256s-20.7-85.3-53.2-111.8c-10.3-8.4-11.8-23.5-3.5-33.8s23.5-11.8 33.8-3.5zm-60.5 74.5C434.1 199.1 448 225.9 448 256s-13.9 56.9-35.4 74.5c-10.3 8.4-25.4 6.8-33.8-3.5s-6.8-25.4 3.5-33.8C393.1 284.4 400 271 400 256s-6.9-28.4-17.7-37.3c-10.3-8.4-11.8-23.5-3.5-33.8s23.5-11.8 33.8-3.5zM301.1 34.8C312.6 40 320 51.4 320 64V448c0 12.6-7.4 24-18.9 29.2s-25 3.1-34.4-5.3L131.8 352H64c-35.3 0-64-28.7-64-64V224c0-35.3 28.7-64 64-64h67.8L266.7 40.1c9.4-8.4 22.9-10.4 34.4-5.3z" } }, "free": ["solid"] }, "volume-low": { "aliases": { "names": ["volume-down"], "unicodes": { "composite": ["1f508"], "secondary": ["10f027"] } }, "changes": [ "1.0.0", "5.0.0", "5.3.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "audio", "lower", "music", "quieter", "soft", "sound", "speaker", "speaker low volume" ] }, "styles": ["solid"], "unicode": "f027", "label": "Volume Low", "voted": false, "svg": { "solid": { "last_modified": 1684766677, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M301.1 34.8C312.6 40 320 51.4 320 64V448c0 12.6-7.4 24-18.9 29.2s-25 3.1-34.4-5.3L131.8 352H64c-35.3 0-64-28.7-64-64V224c0-35.3 28.7-64 64-64h67.8L266.7 40.1c9.4-8.4 22.9-10.4 34.4-5.3zM412.6 181.5C434.1 199.1 448 225.9 448 256s-13.9 56.9-35.4 74.5c-10.3 8.4-25.4 6.8-33.8-3.5s-6.8-25.4 3.5-33.8C393.1 284.4 400 271 400 256s-6.9-28.4-17.7-37.3c-10.3-8.4-11.8-23.5-3.5-33.8s23.5-11.8 33.8-3.5z" } }, "free": ["solid"] }, "volume-off": { "aliases": { "unicodes": { "secondary": ["10f026"] } }, "changes": [ "1.0.0", "5.0.0", "5.3.0", "5.8.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["audio", "ban", "music", "mute", "quiet", "silent", "sound"] }, "styles": ["solid"], "unicode": "f026", "label": "Volume Off", "voted": false, "svg": { "solid": { "last_modified": 1684766676, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M320 64c0-12.6-7.4-24-18.9-29.2s-25-3.1-34.4 5.3L131.8 160H64c-35.3 0-64 28.7-64 64v64c0 35.3 28.7 64 64 64h67.8L266.7 471.9c9.4 8.4 22.9 10.4 34.4 5.3S320 460.6 320 448V64z" } }, "free": ["solid"] }, "volume-xmark": { "aliases": { "names": ["volume-mute", "volume-times"], "unicodes": { "secondary": ["10f6a9"] } }, "changes": ["5.3.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["audio", "music", "quiet", "sound", "speaker"] }, "styles": ["solid"], "unicode": "f6a9", "label": "Volume Xmark", "voted": true, "svg": { "solid": { "last_modified": 1684766675, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M301.1 34.8C312.6 40 320 51.4 320 64V448c0 12.6-7.4 24-18.9 29.2s-25 3.1-34.4-5.3L131.8 352H64c-35.3 0-64-28.7-64-64V224c0-35.3 28.7-64 64-64h67.8L266.7 40.1c9.4-8.4 22.9-10.4 34.4-5.3zM425 167l55 55 55-55c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9l-55 55 55 55c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-55-55-55 55c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l55-55-55-55c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0z" } }, "free": ["solid"] }, "vr-cardboard": { "aliases": { "unicodes": { "secondary": ["10f729"] } }, "changes": ["5.4.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["3d", "augment", "google", "reality", "virtual"] }, "styles": ["solid"], "unicode": "f729", "label": "Vr Cardboard", "voted": true, "svg": { "solid": { "last_modified": 1684767601, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M576 64H64C28.7 64 0 92.7 0 128V384c0 35.3 28.7 64 64 64H184.4c24.2 0 46.4-13.7 57.2-35.4l32-64c8.8-17.5 26.7-28.6 46.3-28.6s37.5 11.1 46.3 28.6l32 64c10.8 21.7 33 35.4 57.2 35.4H576c35.3 0 64-28.7 64-64V128c0-35.3-28.7-64-64-64zM96 240a64 64 0 1 1 128 0A64 64 0 1 1 96 240zm384-64a64 64 0 1 1 0 128 64 64 0 1 1 0-128z" } }, "free": ["solid"] }, "vuejs": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f41f", "label": "Vue.js", "voted": false, "svg": { "brands": { "last_modified": 1660014476, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M356.9 64.3H280l-56 88.6-48-88.6H0L224 448 448 64.3h-91.1zm-301.2 32h53.8L224 294.5 338.4 96.3h53.8L224 384.5 55.7 96.3z" } }, "free": ["brands"] }, "w": { "aliases": { "unicodes": { "composite": ["77"] } }, "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Latin Capital Letter W", "Latin Small Letter W", "letter"] }, "styles": ["solid"], "unicode": "57", "label": "W", "voted": false, "svg": { "solid": { "last_modified": 1684767247, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M20.8 34c16.5-6.2 35 2.2 41.2 18.7l110.2 294L257.3 55c4-13.7 16.5-23 30.7-23s26.7 9.4 30.7 23l85.1 291.7L514 52.8c6.2-16.5 24.6-24.9 41.2-18.7s24.9 24.7 18.7 41.2l-144 384c-4.8 12.9-17.4 21.3-31.2 20.7s-25.7-9.8-29.5-23L288 178.3 206.7 457c-3.9 13.2-15.8 22.5-29.5 23s-26.3-7.8-31.2-20.7L2 75.2C-4.2 58.7 4.2 40.2 20.8 34z" } }, "free": ["solid"] }, "walkie-talkie": { "aliases": { "unicodes": { "secondary": ["10f8ef"] } }, "changes": ["5.11.0", "6.0.0-beta1", "6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "communication", "copy", "intercom", "over", "portable", "radio", "two way radio" ] }, "styles": ["solid"], "unicode": "f8ef", "label": "Walkie Talkie", "voted": false, "svg": { "solid": { "last_modified": 1684766675, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M112 24c0-13.3-10.7-24-24-24S64 10.7 64 24V96H48C21.5 96 0 117.5 0 144V300.1c0 12.7 5.1 24.9 14.1 33.9l3.9 3.9c9 9 14.1 21.2 14.1 33.9V464c0 26.5 21.5 48 48 48H304c26.5 0 48-21.5 48-48V371.9c0-12.7 5.1-24.9 14.1-33.9l3.9-3.9c9-9 14.1-21.2 14.1-33.9V144c0-26.5-21.5-48-48-48H320c0-17.7-14.3-32-32-32s-32 14.3-32 32H224c0-17.7-14.3-32-32-32s-32 14.3-32 32H112V24zm0 136H272c8.8 0 16 7.2 16 16s-7.2 16-16 16H112c-8.8 0-16-7.2-16-16s7.2-16 16-16zm0 64H272c8.8 0 16 7.2 16 16s-7.2 16-16 16H112c-8.8 0-16-7.2-16-16s7.2-16 16-16zm0 64H272c8.8 0 16 7.2 16 16s-7.2 16-16 16H112c-8.8 0-16-7.2-16-16s7.2-16 16-16z" } }, "free": ["solid"] }, "wallet": { "aliases": { "unicodes": { "secondary": ["10f555"] } }, "changes": [ "5.0.13", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["billfold", "cash", "currency", "money"] }, "styles": ["solid"], "unicode": "f555", "label": "Wallet", "voted": true, "svg": { "solid": { "last_modified": 1684766476, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V192c0-35.3-28.7-64-64-64H80c-8.8 0-16-7.2-16-16s7.2-16 16-16H448c17.7 0 32-14.3 32-32s-14.3-32-32-32H64zM416 272a32 32 0 1 1 0 64 32 32 0 1 1 0-64z" } }, "free": ["solid"] }, "wand-magic": { "aliases": { "names": ["magic"], "unicodes": { "secondary": ["10f0d0"] } }, "changes": [ "2.0.0", "5.0.0", "5.1.0", "6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "autocomplete", "automatic", "mage", "magic", "spell", "wand", "witch", "wizard" ] }, "styles": ["solid"], "unicode": "f0d0", "label": "Wand Magic", "voted": false, "svg": { "solid": { "last_modified": 1684767366, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M14.1 463.3c-18.7-18.7-18.7-49.1 0-67.9L395.4 14.1c18.7-18.7 49.1-18.7 67.9 0l34.6 34.6c18.7 18.7 18.7 49.1 0 67.9L116.5 497.9c-18.7 18.7-49.1 18.7-67.9 0L14.1 463.3zM347.6 187.6l105-105L429.4 59.3l-105 105 23.3 23.3z" } }, "free": ["solid"] }, "wand-magic-sparkles": { "aliases": { "names": ["magic-wand-sparkles"] }, "changes": ["6.0.0-beta1", "6.0.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["auto", "magic", "magic wand", "trick", "witch", "wizard"] }, "styles": ["solid"], "unicode": "e2ca", "label": "Wand Magic Sparkles", "voted": false, "svg": { "solid": { "last_modified": 1684767368, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M234.7 42.7L197 56.8c-3 1.1-5 4-5 7.2s2 6.1 5 7.2l37.7 14.1L248.8 123c1.1 3 4 5 7.2 5s6.1-2 7.2-5l14.1-37.7L315 71.2c3-1.1 5-4 5-7.2s-2-6.1-5-7.2L277.3 42.7 263.2 5c-1.1-3-4-5-7.2-5s-6.1 2-7.2 5L234.7 42.7zM46.1 395.4c-18.7 18.7-18.7 49.1 0 67.9l34.6 34.6c18.7 18.7 49.1 18.7 67.9 0L529.9 116.5c18.7-18.7 18.7-49.1 0-67.9L495.3 14.1c-18.7-18.7-49.1-18.7-67.9 0L46.1 395.4zM484.6 82.6l-105 105-23.3-23.3 105-105 23.3 23.3zM7.5 117.2C3 118.9 0 123.2 0 128s3 9.1 7.5 10.8L64 160l21.2 56.5c1.7 4.5 6 7.5 10.8 7.5s9.1-3 10.8-7.5L128 160l56.5-21.2c4.5-1.7 7.5-6 7.5-10.8s-3-9.1-7.5-10.8L128 96 106.8 39.5C105.1 35 100.8 32 96 32s-9.1 3-10.8 7.5L64 96 7.5 117.2zm352 256c-4.5 1.7-7.5 6-7.5 10.8s3 9.1 7.5 10.8L416 416l21.2 56.5c1.7 4.5 6 7.5 10.8 7.5s9.1-3 10.8-7.5L480 416l56.5-21.2c4.5-1.7 7.5-6 7.5-10.8s-3-9.1-7.5-10.8L480 352l-21.2-56.5c-1.7-4.5-6-7.5-10.8-7.5s-9.1 3-10.8 7.5L416 352l-56.5 21.2z" } }, "free": ["solid"] }, "wand-sparkles": { "aliases": { "unicodes": { "secondary": ["10f72b"] } }, "changes": ["5.4.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "autocomplete", "automatic", "fantasy", "halloween", "holiday", "magic", "weapon", "witch", "wizard" ] }, "styles": ["solid"], "unicode": "f72b", "label": "Wand Sparkles", "voted": false, "svg": { "solid": { "last_modified": 1684767602, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M464 6.1c9.5-8.5 24-8.1 33 .9l8 8c9 9 9.4 23.5 .9 33l-85.8 95.9c-2.6 2.9-4.1 6.7-4.1 10.7V176c0 8.8-7.2 16-16 16H384.2c-4.6 0-8.9 1.9-11.9 5.3L100.7 500.9C94.3 508 85.3 512 75.8 512c-8.8 0-17.3-3.5-23.5-9.8L9.7 459.7C3.5 453.4 0 445 0 436.2c0-9.5 4-18.5 11.1-24.8l111.6-99.8c3.4-3 5.3-7.4 5.3-11.9V272c0-8.8 7.2-16 16-16h34.6c3.9 0 7.7-1.5 10.7-4.1L464 6.1zM432 288c3.6 0 6.7 2.4 7.7 5.8l14.8 51.7 51.7 14.8c3.4 1 5.8 4.1 5.8 7.7s-2.4 6.7-5.8 7.7l-51.7 14.8-14.8 51.7c-1 3.4-4.1 5.8-7.7 5.8s-6.7-2.4-7.7-5.8l-14.8-51.7-51.7-14.8c-3.4-1-5.8-4.1-5.8-7.7s2.4-6.7 5.8-7.7l51.7-14.8 14.8-51.7c1-3.4 4.1-5.8 7.7-5.8zM87.7 69.8l14.8 51.7 51.7 14.8c3.4 1 5.8 4.1 5.8 7.7s-2.4 6.7-5.8 7.7l-51.7 14.8L87.7 218.2c-1 3.4-4.1 5.8-7.7 5.8s-6.7-2.4-7.7-5.8L57.5 166.5 5.8 151.7c-3.4-1-5.8-4.1-5.8-7.7s2.4-6.7 5.8-7.7l51.7-14.8L72.3 69.8c1-3.4 4.1-5.8 7.7-5.8s6.7 2.4 7.7 5.8zM208 0c3.7 0 6.9 2.5 7.8 6.1l6.8 27.3 27.3 6.8c3.6 .9 6.1 4.1 6.1 7.8s-2.5 6.9-6.1 7.8l-27.3 6.8-6.8 27.3c-.9 3.6-4.1 6.1-7.8 6.1s-6.9-2.5-7.8-6.1l-6.8-27.3-27.3-6.8c-3.6-.9-6.1-4.1-6.1-7.8s2.5-6.9 6.1-7.8l27.3-6.8 6.8-27.3c.9-3.6 4.1-6.1 7.8-6.1z" } }, "free": ["solid"] }, "warehouse": { "aliases": { "unicodes": { "secondary": ["10f494"] } }, "changes": [ "5.0.7", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["building", "capacity", "garage", "inventory", "storage"] }, "styles": ["solid"], "unicode": "f494", "label": "Warehouse", "voted": false, "svg": { "solid": { "last_modified": 1684766827, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M0 488V171.3c0-26.2 15.9-49.7 40.2-59.4L308.1 4.8c7.6-3.1 16.1-3.1 23.8 0L599.8 111.9c24.3 9.7 40.2 33.3 40.2 59.4V488c0 13.3-10.7 24-24 24H568c-13.3 0-24-10.7-24-24V224c0-17.7-14.3-32-32-32H128c-17.7 0-32 14.3-32 32V488c0 13.3-10.7 24-24 24H24c-13.3 0-24-10.7-24-24zm488 24l-336 0c-13.3 0-24-10.7-24-24V432H512l0 56c0 13.3-10.7 24-24 24zM128 400V336H512v64H128zm0-96V224H512l0 80H128z" } }, "free": ["solid"] }, "watchman-monitoring": { "changes": ["5.15.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e087", "label": "Watchman Monitoring", "voted": false, "svg": { "brands": { "last_modified": 1660014478, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256,16C123.452,16,16,123.452,16,256S123.452,496,256,496,496,388.548,496,256,388.548,16,256,16ZM121.69,429.122C70.056,388.972,36.741,326.322,36.741,256a218.519,218.519,0,0,1,9.587-64.122l102.9-17.895-.121,10.967-13.943,2.013s-.144,12.5-.144,19.549a12.778,12.778,0,0,0,4.887,10.349l9.468,7.4Zm105.692-283.27,8.48-7.618s6.934-5.38-.143-9.344c-7.188-4.024-39.53-34.5-39.53-34.5-5.348-5.477-8.257-7.347-15.46,0,0,0-32.342,30.474-39.529,34.5-7.078,3.964-.144,9.344-.144,9.344l8.481,7.618-.048,4.369L75.982,131.045c39.644-56.938,105.532-94.3,180.018-94.3A218.754,218.754,0,0,1,420.934,111.77l-193.512,37.7Zm34.063,329.269-33.9-250.857,9.467-7.4a12.778,12.778,0,0,0,4.888-10.349c0-7.044-.144-19.549-.144-19.549l-13.943-2.013-.116-10.474,241.711,31.391A218.872,218.872,0,0,1,475.259,256C475.259,375.074,379.831,472.212,261.445,475.121Z" } }, "free": ["brands"] }, "water": { "aliases": { "unicodes": { "secondary": ["10f773"] } }, "changes": ["5.5.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["lake", "liquid", "ocean", "sea", "swim", "wet"] }, "styles": ["solid"], "unicode": "f773", "label": "Water", "voted": false, "svg": { "solid": { "last_modified": 1684767662, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M269.5 69.9c11.1-7.9 25.9-7.9 37 0C329 85.4 356.5 96 384 96c26.9 0 55.4-10.8 77.4-26.1l0 0c11.9-8.5 28.1-7.8 39.2 1.7c14.4 11.9 32.5 21 50.6 25.2c17.2 4 27.9 21.2 23.9 38.4s-21.2 27.9-38.4 23.9c-24.5-5.7-44.9-16.5-58.2-25C449.5 149.7 417 160 384 160c-31.9 0-60.6-9.9-80.4-18.9c-5.8-2.7-11.1-5.3-15.6-7.7c-4.5 2.4-9.7 5.1-15.6 7.7c-19.8 9-48.5 18.9-80.4 18.9c-33 0-65.5-10.3-94.5-25.8c-13.4 8.4-33.7 19.3-58.2 25c-17.2 4-34.4-6.7-38.4-23.9s6.7-34.4 23.9-38.4C42.8 92.6 61 83.5 75.3 71.6c11.1-9.5 27.3-10.1 39.2-1.7l0 0C136.7 85.2 165.1 96 192 96c27.5 0 55-10.6 77.5-26.1zm37 288C329 373.4 356.5 384 384 384c26.9 0 55.4-10.8 77.4-26.1l0 0c11.9-8.5 28.1-7.8 39.2 1.7c14.4 11.9 32.5 21 50.6 25.2c17.2 4 27.9 21.2 23.9 38.4s-21.2 27.9-38.4 23.9c-24.5-5.7-44.9-16.5-58.2-25C449.5 437.7 417 448 384 448c-31.9 0-60.6-9.9-80.4-18.9c-5.8-2.7-11.1-5.3-15.6-7.7c-4.5 2.4-9.7 5.1-15.6 7.7c-19.8 9-48.5 18.9-80.4 18.9c-33 0-65.5-10.3-94.5-25.8c-13.4 8.4-33.7 19.3-58.2 25c-17.2 4-34.4-6.7-38.4-23.9s6.7-34.4 23.9-38.4c18.1-4.2 36.2-13.3 50.6-25.2c11.1-9.4 27.3-10.1 39.2-1.7l0 0C136.7 373.2 165.1 384 192 384c27.5 0 55-10.6 77.5-26.1c11.1-7.9 25.9-7.9 37 0zm0-144C329 229.4 356.5 240 384 240c26.9 0 55.4-10.8 77.4-26.1l0 0c11.9-8.5 28.1-7.8 39.2 1.7c14.4 11.9 32.5 21 50.6 25.2c17.2 4 27.9 21.2 23.9 38.4s-21.2 27.9-38.4 23.9c-24.5-5.7-44.9-16.5-58.2-25C449.5 293.7 417 304 384 304c-31.9 0-60.6-9.9-80.4-18.9c-5.8-2.7-11.1-5.3-15.6-7.7c-4.5 2.4-9.7 5.1-15.6 7.7c-19.8 9-48.5 18.9-80.4 18.9c-33 0-65.5-10.3-94.5-25.8c-13.4 8.4-33.7 19.3-58.2 25c-17.2 4-34.4-6.7-38.4-23.9s6.7-34.4 23.9-38.4c18.1-4.2 36.2-13.3 50.6-25.2c11.1-9.5 27.3-10.1 39.2-1.7l0 0C136.7 229.2 165.1 240 192 240c27.5 0 55-10.6 77.5-26.1c11.1-7.9 25.9-7.9 37 0z" } }, "free": ["solid"] }, "water-ladder": { "aliases": { "names": ["ladder-water", "swimming-pool"], "unicodes": { "secondary": ["10f5c5"] } }, "changes": ["5.1.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["ladder", "recreation", "swim", "water"] }, "styles": ["solid"], "unicode": "f5c5", "label": "Water Ladder", "voted": false, "svg": { "solid": { "last_modified": 1684767070, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M128 127.7C128 74.9 170.9 32 223.7 32c48.3 0 89 36 95 83.9l1 8.2c2.2 17.5-10.2 33.5-27.8 35.7s-33.5-10.2-35.7-27.8l-1-8.2c-2-15.9-15.5-27.8-31.5-27.8c-17.5 0-31.7 14.2-31.7 31.7V224H384V127.7C384 74.9 426.9 32 479.7 32c48.3 0 89 36 95 83.9l1 8.2c2.2 17.5-10.2 33.5-27.8 35.7s-33.5-10.2-35.7-27.8l-1-8.2c-2-15.9-15.5-27.8-31.5-27.8c-17.5 0-31.7 14.2-31.7 31.7V361c-1.6 1-3.3 2-4.8 3.1c-18 12.4-40.1 20.3-59.2 20.3h0V288H192v96.5c-19 0-41.2-7.9-59.1-20.3c-1.6-1.1-3.2-2.2-4.9-3.1V127.7zM306.5 389.9C329 405.4 356.5 416 384 416c26.9 0 55.4-10.8 77.4-26.1l0 0c11.9-8.5 28.1-7.8 39.2 1.7c14.4 11.9 32.5 21 50.6 25.2c17.2 4 27.9 21.2 23.9 38.4s-21.2 27.9-38.4 23.9c-24.5-5.7-44.9-16.5-58.2-25C449.5 469.7 417 480 384 480c-31.9 0-60.6-9.9-80.4-18.9c-5.8-2.7-11.1-5.3-15.6-7.7c-4.5 2.4-9.7 5.1-15.6 7.7c-19.8 9-48.5 18.9-80.4 18.9c-33 0-65.5-10.3-94.5-25.8c-13.4 8.4-33.7 19.3-58.2 25c-17.2 4-34.4-6.7-38.4-23.9s6.7-34.4 23.9-38.4c18.1-4.2 36.2-13.3 50.6-25.2c11.1-9.4 27.3-10.1 39.2-1.7l0 0C136.7 405.2 165.1 416 192 416c27.5 0 55-10.6 77.5-26.1c11.1-7.9 25.9-7.9 37 0z" } }, "free": ["solid"] }, "wave-square": { "aliases": { "unicodes": { "secondary": ["10f83e"] } }, "changes": ["5.8.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["frequency", "pulse", "signal"] }, "styles": ["solid"], "unicode": "f83e", "label": "Wave Square", "voted": false, "svg": { "solid": { "last_modified": 1684766677, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M128 64c0-17.7 14.3-32 32-32H320c17.7 0 32 14.3 32 32V416h96V256c0-17.7 14.3-32 32-32H608c17.7 0 32 14.3 32 32s-14.3 32-32 32H512V448c0 17.7-14.3 32-32 32H320c-17.7 0-32-14.3-32-32V96H192V256c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32h96V64z" } }, "free": ["solid"] }, "waze": { "changes": ["5.8.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f83f", "label": "Waze", "voted": false, "svg": { "brands": { "last_modified": 1660014464, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M502.17 201.67C516.69 287.53 471.23 369.59 389 409.8c13 34.1-12.4 70.2-48.32 70.2a51.68 51.68 0 0 1-51.57-49c-6.44.19-64.2 0-76.33-.64A51.69 51.69 0 0 1 159 479.92c-33.86-1.36-57.95-34.84-47-67.92-37.21-13.11-72.54-34.87-99.62-70.8-13-17.28-.48-41.8 20.84-41.8 46.31 0 32.22-54.17 43.15-110.26C94.8 95.2 193.12 32 288.09 32c102.48 0 197.15 70.67 214.08 169.67zM373.51 388.28c42-19.18 81.33-56.71 96.29-102.14 40.48-123.09-64.15-228-181.71-228-83.45 0-170.32 55.42-186.07 136-9.53 48.91 5 131.35-68.75 131.35C58.21 358.6 91.6 378.11 127 389.54c24.66-21.8 63.87-15.47 79.83 14.34 14.22 1 79.19 1.18 87.9.82a51.69 51.69 0 0 1 78.78-16.42zM205.12 187.13c0-34.74 50.84-34.75 50.84 0s-50.84 34.74-50.84 0zm116.57 0c0-34.74 50.86-34.75 50.86 0s-50.86 34.75-50.86 0zm-122.61 70.69c-3.44-16.94 22.18-22.18 25.62-5.21l.06.28c4.14 21.42 29.85 44 64.12 43.07 35.68-.94 59.25-22.21 64.11-42.77 4.46-16.05 28.6-10.36 25.47 6-5.23 22.18-31.21 62-91.46 62.9-42.55 0-80.88-27.84-87.9-64.25z" } }, "free": ["brands"] }, "weebly": { "changes": ["5.1.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f5cc", "label": "Weebly", "voted": true, "svg": { "brands": { "last_modified": 1660014462, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M425.09 65.83c-39.88 0-73.28 25.73-83.66 64.33-18.16-58.06-65.5-64.33-84.95-64.33-19.78 0-66.8 6.28-85.28 64.33-10.38-38.6-43.45-64.33-83.66-64.33C38.59 65.83 0 99.72 0 143.03c0 28.96 4.18 33.27 77.17 233.48 22.37 60.57 67.77 69.35 92.74 69.35 39.23 0 70.04-19.46 85.93-53.98 15.89 34.83 46.69 54.29 85.93 54.29 24.97 0 70.36-9.1 92.74-69.67 76.55-208.65 77.5-205.58 77.5-227.2.63-48.32-36.01-83.47-86.92-83.47zm26.34 114.81l-65.57 176.44c-7.92 21.49-21.22 37.22-46.24 37.22-23.44 0-37.38-12.41-44.03-33.9l-39.28-117.42h-.95L216.08 360.4c-6.96 21.5-20.9 33.6-44.02 33.6-25.02 0-38.33-15.74-46.24-37.22L60.88 181.55c-5.38-14.83-7.92-23.91-7.92-34.5 0-16.34 15.84-29.36 38.33-29.36 18.69 0 31.99 11.8 36.11 29.05l44.03 139.82h.95l44.66-136.79c6.02-19.67 16.47-32.08 38.96-32.08s32.94 12.11 38.96 32.08l44.66 136.79h.95l44.03-139.82c4.12-17.25 17.42-29.05 36.11-29.05 22.17 0 38.33 13.32 38.33 35.71-.32 7.87-4.12 16.04-7.61 27.24z" } }, "free": ["brands"] }, "weibo": { "changes": ["3.2.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f18a", "label": "Weibo", "voted": false, "svg": { "brands": { "last_modified": 1660014476, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M407 177.6c7.6-24-13.4-46.8-37.4-41.7-22 4.8-28.8-28.1-7.1-32.8 50.1-10.9 92.3 37.1 76.5 84.8-6.8 21.2-38.8 10.8-32-10.3zM214.8 446.7C108.5 446.7 0 395.3 0 310.4c0-44.3 28-95.4 76.3-143.7C176 67 279.5 65.8 249.9 161c-4 13.1 12.3 5.7 12.3 6 79.5-33.6 140.5-16.8 114 51.4-3.7 9.4 1.1 10.9 8.3 13.1 135.7 42.3 34.8 215.2-169.7 215.2zm143.7-146.3c-5.4-55.7-78.5-94-163.4-85.7-84.8 8.6-148.8 60.3-143.4 116s78.5 94 163.4 85.7c84.8-8.6 148.8-60.3 143.4-116zM347.9 35.1c-25.9 5.6-16.8 43.7 8.3 38.3 72.3-15.2 134.8 52.8 111.7 124-7.4 24.2 29.1 37 37.4 12 31.9-99.8-55.1-195.9-157.4-174.3zm-78.5 311c-17.1 38.8-66.8 60-109.1 46.3-40.8-13.1-58-53.4-40.3-89.7 17.7-35.4 63.1-55.4 103.4-45.1 42 10.8 63.1 50.2 46 88.5zm-86.3-30c-12.9-5.4-30 .3-38 12.9-8.3 12.9-4.3 28 8.6 34 13.1 6 30.8.3 39.1-12.9 8-13.1 3.7-28.3-9.7-34zm32.6-13.4c-5.1-1.7-11.4.6-14.3 5.4-2.9 5.1-1.4 10.6 3.7 12.9 5.1 2 11.7-.3 14.6-5.4 2.8-5.2 1.1-10.9-4-12.9z" } }, "free": ["brands"] }, "weight-hanging": { "aliases": { "unicodes": { "secondary": ["10f5cd"] } }, "changes": ["5.1.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["anvil", "heavy", "measurement"] }, "styles": ["solid"], "unicode": "f5cd", "label": "Weight Hanging", "voted": false, "svg": { "solid": { "last_modified": 1684767443, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M224 96a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm122.5 32c3.5-10 5.5-20.8 5.5-32c0-53-43-96-96-96s-96 43-96 96c0 11.2 1.9 22 5.5 32H120c-22 0-41.2 15-46.6 36.4l-72 288c-3.6 14.3-.4 29.5 8.7 41.2S33.2 512 48 512H464c14.8 0 28.7-6.8 37.8-18.5s12.3-26.8 8.7-41.2l-72-288C433.2 143 414 128 392 128H346.5z" } }, "free": ["solid"] }, "weight-scale": { "aliases": { "names": ["weight"], "unicodes": { "secondary": ["10f496"] } }, "changes": ["5.0.7", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["health", "measurement", "scale", "weight"] }, "styles": ["solid"], "unicode": "f496", "label": "Weight Scale", "voted": false, "svg": { "solid": { "last_modified": 1684767443, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M128 176a128 128 0 1 1 256 0 128 128 0 1 1 -256 0zM391.8 64C359.5 24.9 310.7 0 256 0S152.5 24.9 120.2 64H64C28.7 64 0 92.7 0 128V448c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V128c0-35.3-28.7-64-64-64H391.8zM296 224c0-10.6-4.1-20.2-10.9-27.4l33.6-78.3c3.5-8.1-.3-17.5-8.4-21s-17.5 .3-21 8.4L255.7 184c-22 .1-39.7 18-39.7 40c0 22.1 17.9 40 40 40s40-17.9 40-40z" } }, "free": ["solid"] }, "weixin": { "changes": ["4.1.0", "5.0.0", "5.0.3"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f1d7", "label": "Weixin (WeChat)", "voted": false, "svg": { "brands": { "last_modified": 1660014478, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M385.2 167.6c6.4 0 12.6.3 18.8 1.1C387.4 90.3 303.3 32 207.7 32 100.5 32 13 104.8 13 197.4c0 53.4 29.3 97.5 77.9 131.6l-19.3 58.6 68-34.1c24.4 4.8 43.8 9.7 68.2 9.7 6.2 0 12.1-.3 18.3-.8-4-12.9-6.2-26.6-6.2-40.8-.1-84.9 72.9-154 165.3-154zm-104.5-52.9c14.5 0 24.2 9.7 24.2 24.4 0 14.5-9.7 24.2-24.2 24.2-14.8 0-29.3-9.7-29.3-24.2.1-14.7 14.6-24.4 29.3-24.4zm-136.4 48.6c-14.5 0-29.3-9.7-29.3-24.2 0-14.8 14.8-24.4 29.3-24.4 14.8 0 24.4 9.7 24.4 24.4 0 14.6-9.6 24.2-24.4 24.2zM563 319.4c0-77.9-77.9-141.3-165.4-141.3-92.7 0-165.4 63.4-165.4 141.3S305 460.7 397.6 460.7c19.3 0 38.9-5.1 58.6-9.9l53.4 29.3-14.8-48.6C534 402.1 563 363.2 563 319.4zm-219.1-24.5c-9.7 0-19.3-9.7-19.3-19.6 0-9.7 9.7-19.3 19.3-19.3 14.8 0 24.4 9.7 24.4 19.3 0 10-9.7 19.6-24.4 19.6zm107.1 0c-9.7 0-19.3-9.7-19.3-19.6 0-9.7 9.7-19.3 19.3-19.3 14.5 0 24.4 9.7 24.4 19.3.1 10-9.9 19.6-24.4 19.6z" } }, "free": ["brands"] }, "whatsapp": { "changes": ["4.3.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f232", "label": "What's App", "voted": false, "svg": { "brands": { "last_modified": 1660014465, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M380.9 97.1C339 55.1 283.2 32 223.9 32c-122.4 0-222 99.6-222 222 0 39.1 10.2 77.3 29.6 111L0 480l117.7-30.9c32.4 17.7 68.9 27 106.1 27h.1c122.3 0 224.1-99.6 224.1-222 0-59.3-25.2-115-67.1-157zm-157 341.6c-33.2 0-65.7-8.9-94-25.7l-6.7-4-69.8 18.3L72 359.2l-4.4-7c-18.5-29.4-28.2-63.3-28.2-98.2 0-101.7 82.8-184.5 184.6-184.5 49.3 0 95.6 19.2 130.4 54.1 34.8 34.9 56.2 81.2 56.1 130.5 0 101.8-84.9 184.6-186.6 184.6zm101.2-138.2c-5.5-2.8-32.8-16.2-37.9-18-5.1-1.9-8.8-2.8-12.5 2.8-3.7 5.6-14.3 18-17.6 21.8-3.2 3.7-6.5 4.2-12 1.4-32.6-16.3-54-29.1-75.5-66-5.7-9.8 5.7-9.1 16.3-30.3 1.8-3.7.9-6.9-.5-9.7-1.4-2.8-12.5-30.1-17.1-41.2-4.5-10.8-9.1-9.3-12.5-9.5-3.2-.2-6.9-.2-10.6-.2-3.7 0-9.7 1.4-14.8 6.9-5.1 5.6-19.4 19-19.4 46.3 0 27.3 19.9 53.7 22.6 57.4 2.8 3.7 39.1 59.7 94.8 83.8 35.2 15.2 49 16.5 66.6 13.9 10.7-1.6 32.8-13.4 37.4-26.4 4.6-13 4.6-24.1 3.2-26.4-1.3-2.5-5-3.9-10.5-6.6z" } }, "free": ["brands"] }, "wheat-awn": { "aliases": { "names": ["wheat-alt"] }, "changes": ["6.0.0-beta1", "6.1.0", "6.1.2", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["agriculture", "autumn", "fall", "farming", "grain"] }, "styles": ["solid"], "unicode": "e2cd", "label": "Wheat Awn", "voted": false, "svg": { "solid": { "last_modified": 1684768131, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M505 41c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0L383 95c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l88-88zM305.5 27.3c-6.2-6.2-16.4-6.2-22.6 0L271.5 38.6c-37.5 37.5-37.5 98.3 0 135.8l10.4 10.4-30.5 30.5c-3.4-27.3-15.5-53.8-36.5-74.8l-11.3-11.3c-6.2-6.2-16.4-6.2-22.6 0l-11.3 11.3c-37.5 37.5-37.5 98.3 0 135.8l10.4 10.4-30.5 30.5c-3.4-27.3-15.5-53.8-36.5-74.8L101.8 231c-6.2-6.2-16.4-6.2-22.6 0L67.9 242.3c-37.5 37.5-37.5 98.3 0 135.8l10.4 10.4L9.4 457.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l68.9-68.9 12.2 12.2c37.5 37.5 98.3 37.5 135.8 0l11.3-11.3c6.2-6.2 6.2-16.4 0-22.6l-11.3-11.3c-21.8-21.8-49.6-34.1-78.1-36.9l31.9-31.9 12.2 12.2c37.5 37.5 98.3 37.5 135.8 0l11.3-11.3c6.2-6.2 6.2-16.4 0-22.6l-11.3-11.3c-21.8-21.8-49.6-34.1-78.1-36.9l31.9-31.9 12.2 12.2c37.5 37.5 98.3 37.5 135.8 0L486.5 231c6.2-6.2 6.2-16.4 0-22.6L475.2 197c-5.2-5.2-10.6-9.8-16.4-13.9L505 137c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0l-59.4 59.4c-20.6-4.4-42-3.7-62.3 2.1c6.1-21.3 6.6-43.8 1.4-65.3L409 41c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0L329.1 52.9c-3.7-5-7.8-9.8-12.4-14.3L305.5 27.3z" } }, "free": ["solid"] }, "wheat-awn-circle-exclamation": { "changes": ["6.1.0", "6.1.2", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "affected", "famine", "food", "gluten", "hunger", "starve", "straw" ] }, "styles": ["solid"], "unicode": "e598", "label": "Wheat Awn Circle Exclamation", "voted": false, "svg": { "solid": { "last_modified": 1684768131, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M505 41c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0L383 95c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l88-88zM305.5 27.3c-6.2-6.2-16.4-6.2-22.6 0L271.5 38.6c-37.5 37.5-37.5 98.3 0 135.8l10.4 10.4-30.5 30.5c-3.4-27.3-15.5-53.8-36.5-74.8l-11.3-11.3c-6.2-6.2-16.4-6.2-22.6 0l-11.3 11.3c-37.5 37.5-37.5 98.3 0 135.8l10.4 10.4-30.5 30.5c-3.4-27.3-15.5-53.8-36.5-74.8L101.8 231c-6.2-6.2-16.4-6.2-22.6 0L67.9 242.3c-37.5 37.5-37.5 98.3 0 135.8l10.4 10.4L9.4 457.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l68.9-68.9 12.2 12.2c37.5 37.5 98.3 37.5 135.8 0l11.3-11.3c6.2-6.2 6.2-16.4 0-22.6l-11.3-11.3c-21.8-21.8-49.6-34.1-78.1-36.9l31.9-31.9 12.2 12.2c22.5 22.5 53.3 31.5 82.4 27c0-1 0-2.1 0-3.1c0-33.1 9.1-64.1 25-90.6c-15.5-8.7-32.5-13.8-49.8-15.5l31.9-31.9 12.2 12.2c6 6 12.6 11.1 19.7 15.2c27.5-34 67.3-57.5 112.6-63.8c-4.1-3.8-8.4-7.3-12.9-10.5L505 137c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0l-59.4 59.4c-20.6-4.4-42-3.7-62.3 2.1c6.1-21.3 6.6-43.8 1.4-65.3L409 41c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0L329.1 52.9c-3.7-5-7.8-9.8-12.4-14.3L305.5 27.3zM496 512a144 144 0 1 0 0-288 144 144 0 1 0 0 288zm0-96a24 24 0 1 1 0 48 24 24 0 1 1 0-48zm0-144c8.8 0 16 7.2 16 16v80c0 8.8-7.2 16-16 16s-16-7.2-16-16V288c0-8.8 7.2-16 16-16z" } }, "free": ["solid"] }, "wheelchair": { "aliases": { "unicodes": { "secondary": ["10f193"] } }, "changes": [ "4.0.0", "5.0.0", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["users-people"] }, "styles": ["solid"], "unicode": "f193", "label": "Wheelchair", "voted": false, "svg": { "solid": { "last_modified": 1684767532, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M192 96a48 48 0 1 0 0-96 48 48 0 1 0 0 96zM120.5 247.2c12.4-4.7 18.7-18.5 14-30.9s-18.5-18.7-30.9-14C43.1 225.1 0 283.5 0 352c0 88.4 71.6 160 160 160c61.2 0 114.3-34.3 141.2-84.7c6.2-11.7 1.8-26.2-9.9-32.5s-26.2-1.8-32.5 9.9C240 440 202.8 464 160 464C98.1 464 48 413.9 48 352c0-47.9 30.1-88.8 72.5-104.8zM259.8 176l-1.9-9.7c-4.5-22.3-24-38.3-46.8-38.3c-30.1 0-52.7 27.5-46.8 57l23.1 115.5c6 29.9 32.2 51.4 62.8 51.4h5.1c.4 0 .8 0 1.3 0h94.1c6.7 0 12.6 4.1 15 10.4L402 459.2c6 16.1 23.8 24.6 40.1 19.1l48-16c16.8-5.6 25.8-23.7 20.2-40.5s-23.7-25.8-40.5-20.2l-18.7 6.2-25.5-68c-11.7-31.2-41.6-51.9-74.9-51.9H282.2l-9.6-48H336c17.7 0 32-14.3 32-32s-14.3-32-32-32H259.8z" } }, "free": ["solid"] }, "wheelchair-move": { "aliases": { "names": ["wheelchair-alt"] }, "changes": ["6.0.0-beta1", "6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "access", "handicap", "impairment", "physical", "wheelchair symbol" ] }, "styles": ["solid"], "unicode": "e2ce", "label": "Wheelchair Move", "voted": false, "svg": { "solid": { "last_modified": 1684767531, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M320 48a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zM204.5 121.3c-5.4-2.5-11.7-1.9-16.4 1.7l-40.9 30.7c-14.1 10.6-34.2 7.7-44.8-6.4s-7.7-34.2 6.4-44.8l40.9-30.7c23.7-17.8 55.3-21 82.1-8.4l90.4 42.5c29.1 13.7 36.8 51.6 15.2 75.5L299.1 224h97.4c30.3 0 53 27.7 47.1 57.4L415.4 422.3c-3.5 17.3-20.3 28.6-37.7 25.1s-28.6-20.3-25.1-37.7L377 288H306.7c8.6 19.6 13.3 41.2 13.3 64c0 88.4-71.6 160-160 160S0 440.4 0 352s71.6-160 160-160c11.1 0 22 1.1 32.4 3.3l54.2-54.2-42.1-19.8zM160 448a96 96 0 1 0 0-192 96 96 0 1 0 0 192z" } }, "free": ["solid"] }, "whiskey-glass": { "aliases": { "names": ["glass-whiskey"], "unicodes": { "composite": ["1f943"], "secondary": ["10f7a0"] } }, "changes": ["5.6.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "alcohol", "bar", "beverage", "bourbon", "drink", "glass", "liquor", "neat", "rye", "scotch", "shot", "tumbler", "tumbler glass", "whisky" ] }, "styles": ["solid"], "unicode": "f7a0", "label": "Whiskey Glass", "voted": false, "svg": { "solid": { "last_modified": 1684767420, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M32 32c-9.3 0-18.1 4-24.2 11.1S-1 59.4 .3 68.6l50 342.9c5.7 39.3 39.4 68.5 79.2 68.5h253c39.7 0 73.4-29.1 79.2-68.5l50-342.9c1.3-9.2-1.4-18.5-7.5-25.5S489.3 32 480 32H32zM87.7 224L69 96H443L424.3 224H87.7z" } }, "free": ["solid"] }, "whmcs": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f40d", "label": "WHMCS", "voted": false, "svg": { "brands": { "last_modified": 1660014481, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M448 161v-21.3l-28.5-8.8-2.2-10.4 20.1-20.7L427 80.4l-29 7.5-7.2-7.5 7.5-28.2-19.1-11.6-21.3 21-10.7-3.2-7-26.4h-22.6l-6.2 26.4-12.1 3.2-19.7-21-19.4 11 8.1 27.7-8.1 8.4-28.5-7.5-11 19.1 20.7 21-2.9 10.4-28.5 7.8-.3 21.7 28.8 7.5 2.4 12.1-20.1 19.9 10.4 18.5 29.6-7.5 7.2 8.6-8.1 26.9 19.9 11.6 19.4-20.4 11.6 2.9 6.7 28.5 22.6.3 6.7-28.8 11.6-3.5 20.7 21.6 20.4-12.1-8.8-28 7.8-8.1 28.8 8.8 10.3-20.1-20.9-18.8 2.2-12.1 29.1-7zm-119.2 45.2c-31.3 0-56.8-25.4-56.8-56.8s25.4-56.8 56.8-56.8 56.8 25.4 56.8 56.8c0 31.5-25.4 56.8-56.8 56.8zm72.3 16.4l46.9 14.5V277l-55.1 13.4-4.1 22.7 38.9 35.3-19.2 37.9-54-16.7-14.6 15.2 16.7 52.5-38.3 22.7-38.9-40.5-21.7 6.6-12.6 54-42.4-.5-12.6-53.6-21.7-5.6-36.4 38.4-37.4-21.7 15.2-50.5-13.7-16.1-55.5 14.1-19.7-34.8 37.9-37.4-4.8-22.8-54-14.1.5-40.9L54 219.9l5.7-19.7-38.9-39.4L41.5 125l53.6 14.1 15.2-15.7-15.2-52 36.4-20.7 36.8 39.4L191 84l11.6-52H245l11.6 45.9L234 72l-6.3-1.7-3.3 5.7-11 19.1-3.3 5.6 4.6 4.6 17.2 17.4-.3 1-23.8 6.5-6.2 1.7-.1 6.4-.2 12.9C153.8 161.6 118 204 118 254.7c0 58.3 47.3 105.7 105.7 105.7 50.5 0 92.7-35.4 103.2-82.8l13.2.2 6.9.1 1.6-6.7 5.6-24 1.9-.6 17.1 17.8 4.7 4.9 5.8-3.4 20.4-12.1 5.8-3.5-2-6.5-6.8-21.2z" } }, "free": ["brands"] }, "wifi": { "aliases": { "names": ["wifi-3", "wifi-strong"], "unicodes": { "secondary": ["10f1eb"] } }, "changes": [ "4.2.0", "5.0.0", "5.3.0", "5.10.1", "5.11.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["connection", "hotspot", "internet", "network", "wireless"] }, "styles": ["solid"], "unicode": "f1eb", "label": "Wifi", "voted": false, "svg": { "solid": { "last_modified": 1684766676, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M54.2 202.9C123.2 136.7 216.8 96 320 96s196.8 40.7 265.8 106.9c12.8 12.2 33 11.8 45.2-.9s11.8-33-.9-45.2C549.7 79.5 440.4 32 320 32S90.3 79.5 9.8 156.7C-2.9 169-3.3 189.2 8.9 202s32.5 13.2 45.2 .9zM320 256c56.8 0 108.6 21.1 148.2 56c13.3 11.7 33.5 10.4 45.2-2.8s10.4-33.5-2.8-45.2C459.8 219.2 393 192 320 192s-139.8 27.2-190.5 72c-13.3 11.7-14.5 31.9-2.8 45.2s31.9 14.5 45.2 2.8c39.5-34.9 91.3-56 148.2-56zm64 160a64 64 0 1 0 -128 0 64 64 0 1 0 128 0z" } }, "free": ["solid"] }, "wikipedia-w": { "changes": ["4.4.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f266", "label": "Wikipedia W", "voted": false, "svg": { "brands": { "last_modified": 1660014476, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M640 51.2l-.3 12.2c-28.1.8-45 15.8-55.8 40.3-25 57.8-103.3 240-155.3 358.6H415l-81.9-193.1c-32.5 63.6-68.3 130-99.2 193.1-.3.3-15 0-15-.3C172 352.3 122.8 243.4 75.8 133.4 64.4 106.7 26.4 63.4.2 63.7c0-3.1-.3-10-.3-14.2h161.9v13.9c-19.2 1.1-52.8 13.3-43.3 34.2 21.9 49.7 103.6 240.3 125.6 288.6 15-29.7 57.8-109.2 75.3-142.8-13.9-28.3-58.6-133.9-72.8-160-9.7-17.8-36.1-19.4-55.8-19.7V49.8l142.5.3v13.1c-19.4.6-38.1 7.8-29.4 26.1 18.9 40 30.6 68.1 48.1 104.7 5.6-10.8 34.7-69.4 48.1-100.8 8.9-20.6-3.9-28.6-38.6-29.4.3-3.6 0-10.3.3-13.6 44.4-.3 111.1-.3 123.1-.6v13.6c-22.5.8-45.8 12.8-58.1 31.7l-59.2 122.8c6.4 16.1 63.3 142.8 69.2 156.7L559.2 91.8c-8.6-23.1-36.4-28.1-47.2-28.3V49.6l127.8 1.1.2.5z" } }, "free": ["brands"] }, "wind": { "aliases": { "unicodes": { "secondary": ["10f72e"] } }, "changes": ["5.4.0", "5.5.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["air", "blow", "breeze", "fall", "seasonal", "weather"] }, "styles": ["solid"], "unicode": "f72e", "label": "Wind", "voted": false, "svg": { "solid": { "last_modified": 1684767661, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M288 32c0 17.7 14.3 32 32 32h32c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H352c53 0 96-43 96-96s-43-96-96-96H320c-17.7 0-32 14.3-32 32zm64 352c0 17.7 14.3 32 32 32h32c53 0 96-43 96-96s-43-96-96-96H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H384c-17.7 0-32 14.3-32 32zM128 512h32c53 0 96-43 96-96s-43-96-96-96H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H160c17.7 0 32 14.3 32 32s-14.3 32-32 32H128c-17.7 0-32 14.3-32 32s14.3 32 32 32z" } }, "free": ["solid"] }, "window-maximize": { "aliases": { "unicodes": { "composite": ["1f5d6"], "secondary": ["10f2d0"] } }, "changes": [ "4.7.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["Maximize", "browser", "computer", "development", "expand"] }, "styles": ["solid", "regular"], "unicode": "f2d0", "label": "Window Maximize", "voted": false, "svg": { "solid": { "last_modified": 1684767206, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zM96 96H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H96c-17.7 0-32-14.3-32-32s14.3-32 32-32z" }, "regular": { "last_modified": 1684767206, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M.3 89.5C.1 91.6 0 93.8 0 96V224 416c0 35.3 28.7 64 64 64l384 0c35.3 0 64-28.7 64-64V224 96c0-35.3-28.7-64-64-64H64c-2.2 0-4.4 .1-6.5 .3c-9.2 .9-17.8 3.8-25.5 8.2C21.8 46.5 13.4 55.1 7.7 65.5c-3.9 7.3-6.5 15.4-7.4 24zM48 224H464l0 192c0 8.8-7.2 16-16 16L64 432c-8.8 0-16-7.2-16-16l0-192z" } }, "free": ["regular", "solid"] }, "window-minimize": { "aliases": { "unicodes": { "composite": ["1f5d5"], "secondary": ["10f2d1"] } }, "changes": [ "4.7.0", "5.0.0", "5.10.1", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["Minimize", "browser", "collapse", "computer", "development"] }, "styles": ["solid", "regular"], "unicode": "f2d1", "label": "Window Minimize", "voted": false, "svg": { "solid": { "last_modified": 1684767205, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M32 416c-17.7 0-32 14.3-32 32s14.3 32 32 32H480c17.7 0 32-14.3 32-32s-14.3-32-32-32H32z" }, "regular": { "last_modified": 1684767205, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M24 432c-13.3 0-24 10.7-24 24s10.7 24 24 24H488c13.3 0 24-10.7 24-24s-10.7-24-24-24H24z" } }, "free": ["regular", "solid"] }, "window-restore": { "aliases": { "unicodes": { "secondary": ["10f2d2"] } }, "changes": [ "4.7.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["browser", "computer", "development"] }, "styles": ["solid", "regular"], "unicode": "f2d2", "label": "Window Restore", "voted": false, "svg": { "solid": { "last_modified": 1684767207, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M432 64H208c-8.8 0-16 7.2-16 16V96H128V80c0-44.2 35.8-80 80-80H432c44.2 0 80 35.8 80 80V304c0 44.2-35.8 80-80 80H416V320h16c8.8 0 16-7.2 16-16V80c0-8.8-7.2-16-16-16zM0 192c0-35.3 28.7-64 64-64H320c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V192zm64 32c0 17.7 14.3 32 32 32H288c17.7 0 32-14.3 32-32s-14.3-32-32-32H96c-17.7 0-32 14.3-32 32z" }, "regular": { "last_modified": 1684767207, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M432 48H208c-17.7 0-32 14.3-32 32V96H128V80c0-44.2 35.8-80 80-80H432c44.2 0 80 35.8 80 80V304c0 44.2-35.8 80-80 80H416V336h16c17.7 0 32-14.3 32-32V80c0-17.7-14.3-32-32-32zM48 448c0 8.8 7.2 16 16 16H320c8.8 0 16-7.2 16-16V256H48V448zM64 128H320c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V192c0-35.3 28.7-64 64-64z" } }, "free": ["regular", "solid"] }, "windows": { "changes": ["3.2.0", "5.0.0"], "ligatures": [], "search": { "terms": ["microsoft", "operating system", "os"] }, "styles": ["brands"], "unicode": "f17a", "label": "Windows", "voted": false, "svg": { "brands": { "last_modified": 1660014478, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M0 93.7l183.6-25.3v177.4H0V93.7zm0 324.6l183.6 25.3V268.4H0v149.9zm203.8 28L448 480V268.4H203.8v177.9zm0-380.6v180.1H448V32L203.8 65.7z" } }, "free": ["brands"] }, "wine-bottle": { "aliases": { "unicodes": { "secondary": ["10f72f"] } }, "changes": ["5.4.0", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "alcohol", "beverage", "cabernet", "drink", "glass", "grapes", "merlot", "sauvignon" ] }, "styles": ["solid"], "unicode": "f72f", "label": "Wine Bottle", "voted": false, "svg": { "solid": { "last_modified": 1684767419, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M393.4 9.4c12.5-12.5 32.8-12.5 45.3 0l64 64c12.5 12.5 12.5 32.8 0 45.3c-11.8 11.8-30.7 12.5-43.2 1.9l-9.5 9.5-48.8 48.8c-9.2 9.2-11.5 22.9-8.6 35.6c9.4 40.9-1.9 85.6-33.8 117.5L197.3 493.3c-25 25-65.5 25-90.5 0l-88-88c-25-25-25-65.5 0-90.5L180.2 153.3c31.9-31.9 76.6-43.1 117.5-33.8c12.6 2.9 26.4 .5 35.5-8.6l48.8-48.8 9.5-9.5c-10.6-12.6-10-31.4 1.9-43.2zM99.3 347.3l65.4 65.4c6.2 6.2 16.4 6.2 22.6 0l97.4-97.4c6.2-6.2 6.2-16.4 0-22.6l-65.4-65.4c-6.2-6.2-16.4-6.2-22.6 0L99.3 324.7c-6.2 6.2-6.2 16.4 0 22.6z" } }, "free": ["solid"] }, "wine-glass": { "aliases": { "unicodes": { "composite": ["1f377"], "secondary": ["10f4e3"] } }, "changes": [ "5.0.9", "5.1.0", "5.10.1", "5.11.0", "5.11.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "alcohol", "bar", "beverage", "cabernet", "drink", "glass", "grapes", "merlot", "sauvignon", "wine", "wine glass" ] }, "styles": ["solid"], "unicode": "f4e3", "label": "Wine Glass", "voted": false, "svg": { "solid": { "last_modified": 1684767419, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M32.1 29.3C33.5 12.8 47.4 0 64 0H256c16.6 0 30.5 12.8 31.9 29.3l14 168.4c6 72-42.5 135.2-109.9 150.6V448h48c17.7 0 32 14.3 32 32s-14.3 32-32 32H160 80c-17.7 0-32-14.3-32-32s14.3-32 32-32h48V348.4C60.6 333 12.1 269.8 18.1 197.8l14-168.4zm56 98.7H231.9l-5.3-64H93.4l-5.3 64z" } }, "free": ["solid"] }, "wine-glass-empty": { "aliases": { "names": ["wine-glass-alt"], "unicodes": { "secondary": ["10f5ce"] } }, "changes": [ "5.1.0", "5.10.1", "5.11.0", "5.11.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0", "6.4.1" ], "ligatures": [], "search": { "terms": [ "alcohol", "beverage", "cabernet", "drink", "grapes", "merlot", "sauvignon" ] }, "styles": ["solid"], "unicode": "f5ce", "label": "Wine Glass Empty", "voted": false, "svg": { "solid": { "last_modified": 1684767418, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M64 0C47.4 0 33.5 12.8 32.1 29.3l-14 168.4c-6 72 42.5 135.2 109.9 150.6V448H80c-17.7 0-32 14.3-32 32s14.3 32 32 32h80 80c17.7 0 32-14.3 32-32s-14.3-32-32-32H192V348.4c67.4-15.4 115.9-78.6 109.9-150.6l-14-168.4C286.5 12.8 272.6 0 256 0H64zM81.9 203.1L93.4 64H226.6l11.6 139.1C242 248.8 205.9 288 160 288s-82-39.2-78.1-84.9z" } }, "free": ["solid"] }, "wirsindhandwerk": { "aliases": { "names": ["wsh"] }, "changes": ["6.0.0-beta1"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e2d0", "label": "wirsindhandwerk", "voted": false, "svg": { "brands": { "last_modified": 1660014464, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M50.77161,479.81213h83.36071V367.84741l-83.36071,47.009Zm329.04675,0h82.35022V414.85645l-82.35022-47.009Zm.00568-448V251.568L256.1759,179.1861,134.50378,251.568V31.81213H50.77161V392.60565L256.1759,270.31909,462.16858,392.60565V31.81213Z" } }, "free": ["brands"] }, "wix": { "changes": ["5.1.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f5cf", "label": "Wix", "voted": true, "svg": { "brands": { "last_modified": 1660014463, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M393.38 131.69c0 13.03 2.08 32.69-28.68 43.83-9.52 3.45-15.95 9.66-15.95 9.66 0-31 4.72-42.22 17.4-48.86 9.75-5.11 27.23-4.63 27.23-4.63zm-115.8 35.54l-34.24 132.66-28.48-108.57c-7.69-31.99-20.81-48.53-48.43-48.53-27.37 0-40.66 16.18-48.43 48.53L89.52 299.89 55.28 167.23C49.73 140.51 23.86 128.96 0 131.96l65.57 247.93s21.63 1.56 32.46-3.96c14.22-7.25 20.98-12.84 29.59-46.57 7.67-30.07 29.11-118.41 31.12-124.7 4.76-14.94 11.09-13.81 15.4 0 1.97 6.3 23.45 94.63 31.12 124.7 8.6 33.73 15.37 39.32 29.59 46.57 10.82 5.52 32.46 3.96 32.46 3.96l65.57-247.93c-24.42-3.07-49.82 8.93-55.3 35.27zm115.78 5.21s-4.1 6.34-13.46 11.57c-6.01 3.36-11.78 5.64-17.97 8.61-15.14 7.26-13.18 13.95-13.18 35.2v152.07s16.55 2.09 27.37-3.43c13.93-7.1 17.13-13.95 17.26-44.78V181.41l-.02.01v-8.98zm163.44 84.08L640 132.78s-35.11-5.98-52.5 9.85c-13.3 12.1-24.41 29.55-54.18 72.47-.47.73-6.25 10.54-13.07 0-29.29-42.23-40.8-60.29-54.18-72.47-17.39-15.83-52.5-9.85-52.5-9.85l83.2 123.74-82.97 123.36s36.57 4.62 53.95-11.21c11.49-10.46 17.58-20.37 52.51-70.72 6.81-10.52 12.57-.77 13.07 0 29.4 42.38 39.23 58.06 53.14 70.72 17.39 15.83 53.32 11.21 53.32 11.21L556.8 256.52z" } }, "free": ["brands"] }, "wizards-of-the-coast": { "changes": ["5.4.0"], "ligatures": [], "search": { "terms": [ "Dungeons & Dragons", "d&d", "dnd", "fantasy", "game", "gaming", "tabletop" ] }, "styles": ["brands"], "unicode": "f730", "label": "Wizards of the Coast", "voted": false, "svg": { "brands": { "last_modified": 1660014478, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M219.19 345.69c-1.9 1.38-11.07 8.44-.26 23.57 4.64 6.42 14.11 12.79 21.73 6.55 6.5-4.88 7.35-12.92.26-23.04-5.47-7.76-14.28-12.88-21.73-7.08zm336.75 75.94c-.34 1.7-.55 1.67.79 0 2.09-4.19 4.19-10.21 4.98-19.9 3.14-38.49-40.33-71.49-101.34-78.03-54.73-6.02-124.38 9.17-188.8 60.49l-.26 1.57c2.62 4.98 4.98 10.74 3.4 21.21l.79.26c63.89-58.4 131.19-77.25 184.35-73.85 58.4 3.67 100.03 34.04 100.03 68.08-.01 9.96-2.63 15.72-3.94 20.17zM392.28 240.42c.79 7.07 4.19 10.21 9.17 10.47 5.5.26 9.43-2.62 10.47-6.55.79-3.4 2.09-29.85 2.09-29.85s-11.26 6.55-14.93 10.47c-3.66 3.68-7.33 8.39-6.8 15.46zm-50.02-151.1C137.75 89.32 13.1 226.8.79 241.2c-1.05.52-1.31.79.79 1.31 60.49 16.5 155.81 81.18 196.13 202.16l1.05.26c55.25-69.92 140.88-128.05 236.99-128.05 80.92 0 130.15 42.16 130.15 80.39 0 18.33-6.55 33.52-22.26 46.35 0 .96-.2.79.79.79 14.66-10.74 27.5-28.8 27.5-48.18 0-22.78-12.05-38.23-12.05-38.23 7.07 7.07 10.74 16.24 10.74 16.24 5.76-40.85 26.97-62.32 26.97-62.32-2.36-9.69-6.81-17.81-6.81-17.81 7.59 8.12 14.4 27.5 14.4 41.37 0 10.47-3.4 22.78-12.57 31.95l.26.52c8.12-4.98 16.5-16.76 16.5-37.97 0-15.71-4.71-25.92-4.71-25.92 5.76-5.24 11.26-9.17 15.97-11.78.79 3.4 2.09 9.69 2.36 14.93 0 1.05.79 1.83 1.05 0 .79-5.76-.26-16.24-.26-16.5 6.02-3.14 9.69-4.45 9.69-4.45C617.74 176 489.43 89.32 342.26 89.32zm-99.24 289.62c-11.06 8.99-24.2 4.08-30.64-4.19-7.45-9.58-6.76-24.09 4.19-32.47 14.85-11.35 27.08-.49 31.16 5.5.28.39 12.13 16.57-4.71 31.16zm2.09-136.43l9.43-17.81 11.78 70.96-12.57 6.02-24.62-28.8 14.14-26.71 3.67 4.45-1.83-8.11zm18.59 117.58l-.26-.26c2.05-4.1-2.5-6.61-17.54-31.69-1.31-2.36-3.14-2.88-4.45-2.62l-.26-.52c7.86-5.76 15.45-10.21 25.4-15.71l.52.26c1.31 1.83 2.09 2.88 3.4 4.71l-.26.52c-1.05-.26-2.36-.79-5.24.26-2.09.79-7.86 3.67-12.31 7.59v1.31c1.57 2.36 3.93 6.55 5.76 9.69h.26c10.05-6.28 7.56-4.55 11.52-7.86h.26c.52 1.83.52 1.83 1.83 5.5l-.26.26c-3.06.61-4.65.34-11.52 5.5v.26c9.46 17.02 11.01 16.75 12.57 15.97l.26.26c-2.34 1.59-6.27 4.21-9.68 6.57zm55.26-32.47c-3.14 1.57-6.02 2.88-9.95 4.98l-.26-.26c1.29-2.59 1.16-2.71-11.78-32.47l-.26-.26c-.15 0-8.9 3.65-9.95 7.33h-.52l-1.05-5.76.26-.52c7.29-4.56 25.53-11.64 27.76-12.57l.52.26 3.14 4.98-.26.52c-3.53-1.76-7.35.76-12.31 2.62v.26c12.31 32.01 12.67 30.64 14.66 30.64v.25zm44.77-16.5c-4.19 1.05-5.24 1.31-9.69 2.88l-.26-.26.52-4.45c-1.05-3.4-3.14-11.52-3.67-13.62l-.26-.26c-3.4.79-8.9 2.62-12.83 3.93l-.26.26c.79 2.62 3.14 9.95 4.19 13.88.79 2.36 1.83 2.88 2.88 3.14v.52c-3.67 1.05-7.07 2.62-10.21 3.93l-.26-.26c1.05-1.31 1.05-2.88.26-4.98-1.05-3.14-8.12-23.83-9.17-27.23-.52-1.83-1.57-3.14-2.62-3.14v-.52c3.14-1.05 6.02-2.09 10.74-3.4l.26.26-.26 4.71c1.31 3.93 2.36 7.59 3.14 9.69h.26c3.93-1.31 9.43-2.88 12.83-3.93l.26-.26-2.62-9.43c-.52-1.83-1.05-3.4-2.62-3.93v-.26c4.45-1.05 7.33-1.83 10.74-2.36l.26.26c-1.05 1.31-1.05 2.88-.52 4.45 1.57 6.28 4.71 20.43 6.28 26.45.54 2.62 1.85 3.41 2.63 3.93zm32.21-6.81l-.26.26c-4.71.52-14.14 2.36-22.52 4.19l-.26-.26.79-4.19c-1.57-7.86-3.4-18.59-4.98-26.19-.26-1.83-.79-2.88-2.62-3.67l.79-.52c9.17-1.57 20.16-2.36 24.88-2.62l.26.26c.52 2.36.79 3.14 1.57 5.5l-.26.26c-1.14-1.14-3.34-3.2-16.24-.79l-.26.26c.26 1.57 1.05 6.55 1.57 9.95l.26.26c9.52-1.68 4.76-.06 10.74-2.36h.26c0 1.57-.26 1.83-.26 5.24h-.26c-4.81-1.03-2.15-.9-10.21 0l-.26.26c.26 2.09 1.57 9.43 2.09 12.57l.26.26c1.15.38 14.21-.65 16.24-4.71h.26c-.53 2.38-1.05 4.21-1.58 6.04zm10.74-44.51c-4.45 2.36-8.12 2.88-11 2.88-.25.02-11.41 1.09-17.54-9.95-6.74-10.79-.98-25.2 5.5-31.69 8.8-8.12 23.35-10.1 28.54-17.02 8.03-10.33-13.04-22.31-29.59-5.76l-2.62-2.88 5.24-16.24c25.59-1.57 45.2-3.04 50.02 16.24.79 3.14 0 9.43-.26 12.05 0 2.62-1.83 18.85-2.09 23.04-.52 4.19-.79 18.33-.79 20.69.26 2.36.52 4.19 1.57 5.5 1.57 1.83 5.76 1.83 5.76 1.83l-.79 4.71c-11.82-1.07-10.28-.59-20.43-1.05-3.22-5.15-2.23-3.28-4.19-7.86 0 .01-4.19 3.94-7.33 5.51zm37.18 21.21c-6.35-10.58-19.82-7.16-21.73 5.5-2.63 17.08 14.3 19.79 20.69 10.21l.26.26c-.52 1.83-1.83 6.02-1.83 6.28l-.52.52c-10.3 6.87-28.5-2.5-25.66-18.59 1.94-10.87 14.44-18.93 28.8-9.95l.26.52c0 1.06-.27 3.41-.27 5.25zm5.77-87.73v-6.55c.69 0 19.65 3.28 27.76 7.33l-1.57 17.54s10.21-9.43 15.45-10.74c5.24-1.57 14.93 7.33 14.93 7.33l-11.26 11.26c-12.07-6.35-19.59-.08-20.69.79-5.29 38.72-8.6 42.17 4.45 46.09l-.52 4.71c-17.55-4.29-18.53-4.5-36.92-7.33l.79-4.71c7.25 0 7.48-5.32 7.59-6.81 0 0 4.98-53.16 4.98-55.25-.02-2.87-4.99-3.66-4.99-3.66zm10.99 114.44c-8.12-2.09-14.14-11-10.74-20.69 3.14-9.43 12.31-12.31 18.85-10.21 9.17 2.62 12.83 11.78 10.74 19.38-2.61 8.9-9.42 13.87-18.85 11.52zm42.16 9.69c-2.36-.52-7.07-2.36-8.64-2.88v-.26l1.57-1.83c.59-8.24.59-7.27.26-7.59-4.82-1.81-6.66-2.36-7.07-2.36-1.31 1.83-2.88 4.45-3.67 5.5l-.79 3.4v.26c-1.31-.26-3.93-1.31-6.02-1.57v-.26l2.62-1.83c3.4-4.71 9.95-14.14 13.88-20.16v-2.09l.52-.26c2.09.79 5.5 2.09 7.59 2.88.48.48.18-1.87-1.05 25.14-.24 1.81.02 2.6.8 3.91zm-4.71-89.82c11.25-18.27 30.76-16.19 34.04-3.4L539.7 198c2.34-6.25-2.82-9.9-4.45-11.26l1.83-3.67c12.22 10.37 16.38 13.97 22.52 20.43-25.91 73.07-30.76 80.81-24.62 84.32l-1.83 4.45c-6.37-3.35-8.9-4.42-17.81-8.64l2.09-6.81c-.26-.26-3.93 3.93-9.69 3.67-19.06-1.3-22.89-31.75-9.67-52.9zm29.33 79.34c0-5.71-6.34-7.89-7.86-5.24-1.31 2.09 1.05 4.98 2.88 8.38 1.57 2.62 2.62 6.28 1.05 9.43-2.64 6.34-12.4 5.31-15.45-.79 0-.7-.27.09 1.83-4.71l.79-.26c-.57 5.66 6.06 9.61 8.38 4.98 1.05-2.09-.52-5.5-2.09-8.38-1.57-2.62-3.67-6.28-1.83-9.69 2.72-5.06 11.25-4.47 14.66 2.36v.52l-2.36 3.4zm21.21 13.36c-1.96-3.27-.91-2.14-4.45-4.71h-.26c-2.36 4.19-5.76 10.47-8.64 16.24-1.31 2.36-1.05 3.4-.79 3.93l-.26.26-5.76-4.45.26-.26 2.09-1.31c3.14-5.76 6.55-12.05 9.17-17.02v-.26c-2.64-1.98-1.22-1.51-6.02-1.83v-.26l3.14-3.4h.26c3.67 2.36 9.95 6.81 12.31 8.9l.26.26-1.31 3.91zm27.23-44.26l-2.88-2.88c.79-2.36 1.83-4.98 2.09-7.59.75-9.74-11.52-11.84-11.52-4.98 0 4.98 7.86 19.38 7.86 27.76 0 10.21-5.76 15.71-13.88 16.5-8.38.79-20.16-10.47-20.16-10.47l4.98-14.4 2.88 2.09c-2.97 17.8 17.68 20.37 13.35 5.24-1.06-4.02-18.75-34.2 2.09-38.23 13.62-2.36 23.04 16.5 23.04 16.5l-7.85 10.46zm35.62-10.21c-11-30.38-60.49-127.53-191.95-129.62-53.42-1.05-94.27 15.45-132.76 37.97l85.63-9.17-91.39 20.69 25.14 19.64-3.93-16.5c7.5-1.71 39.15-8.45 66.77-8.9l-22.26 80.39c13.61-.7 18.97-8.98 19.64-22.78l4.98-1.05.26 26.71c-22.46 3.21-37.3 6.69-49.49 9.95l13.09-43.21-61.54-36.66 2.36 8.12 10.21 4.98c6.28 18.59 19.38 56.56 20.43 58.66 1.95 4.28 3.16 5.78 12.05 4.45l1.05 4.98c-16.08 4.86-23.66 7.61-39.02 14.4l-2.36-4.71c4.4-2.94 8.73-3.94 5.5-12.83-23.7-62.5-21.48-58.14-22.78-59.44l2.36-4.45 33.52 67.3c-3.84-11.87 1.68 1.69-32.99-78.82l-41.9 88.51 4.71-13.88-35.88-42.16 27.76 93.48-11.78 8.38C95 228.58 101.05 231.87 93.23 231.52c-5.5-.26-13.62 5.5-13.62 5.5L74.63 231c30.56-23.53 31.62-24.33 58.4-42.68l4.19 7.07s-5.76 4.19-7.86 7.07c-5.9 9.28 1.67 13.28 61.8 75.68l-18.85-58.92 39.8-10.21 25.66 30.64 4.45-12.31-4.98-24.62 13.09-3.4.52 3.14 3.67-10.47-94.27 29.33 11.26-4.98-13.62-42.42 17.28-9.17 30.11 36.14 28.54-13.09c-1.41-7.47-2.47-14.5-4.71-19.64l17.28 13.88 4.71-2.09-59.18-42.68 23.08 11.5c18.98-6.07 25.23-7.47 32.21-9.69l2.62 11c-12.55 12.55 1.43 16.82 6.55 19.38l-13.62-61.01 12.05 28.28c4.19-1.31 7.33-2.09 7.33-2.09l2.62 8.64s-3.14 1.05-6.28 2.09l8.9 20.95 33.78-65.73-20.69 61.01c42.42-24.09 81.44-36.66 131.98-35.88 67.04 1.05 167.33 40.85 199.8 139.83.78 2.1-.01 2.63-.79.27zM203.48 152.43s1.83-.52 4.19-1.31l9.43 7.59c-.4 0-3.44-.25-11.26 2.36l-2.36-8.64zm143.76 38.5c-1.57-.6-26.46-4.81-33.26 20.69l21.73 17.02 11.53-37.71zM318.43 67.07c-58.4 0-106.05 12.05-114.96 14.4v.79c8.38 2.09 14.4 4.19 21.21 11.78l1.57.26c6.55-1.83 48.97-13.88 110.24-13.88 180.16 0 301.67 116.79 301.67 223.37v9.95c0 1.31.79 2.62 1.05.52.52-2.09.79-8.64.79-19.64.26-83.79-96.63-227.55-321.57-227.55zm211.06 169.68c1.31-5.76 0-12.31-7.33-13.09-9.62-1.13-16.14 23.79-17.02 33.52-.79 5.5-1.31 14.93 6.02 14.93 4.68-.01 9.72-.91 18.33-35.36zm-61.53 42.95c-2.62-.79-9.43-.79-12.57 10.47-1.83 6.81.52 13.35 6.02 14.66 3.67 1.05 8.9.52 11.78-10.74 2.62-9.94-1.83-13.61-5.23-14.39zM491 300.65c1.83.52 3.14 1.05 5.76 1.83 0-1.83.52-8.38.79-12.05-1.05 1.31-5.5 8.12-6.55 9.95v.27z" } }, "free": ["brands"] }, "wodu": { "changes": ["5.15.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "e088", "label": "Wodu", "voted": false, "svg": { "brands": { "last_modified": 1660014459, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M178.414 339.706H141.1L112.166 223.475h-.478L83.228 339.706H45.2L0 168.946H37.548L64.574 285.177h.478L94.707 168.946h35.157l29.178 117.667h.479L187.5 168.946h36.831zM271.4 212.713c38.984 0 64.1 25.828 64.1 65.291 0 39.222-25.111 65.05-64.1 65.05-38.743 0-63.855-25.828-63.855-65.05C207.547 238.541 232.659 212.713 271.4 212.713zm0 104.753c23.2 0 30.133-19.852 30.133-39.462 0-19.852-6.934-39.7-30.133-39.7-27.7 0-29.894 19.85-29.894 39.7C241.508 297.614 248.443 317.466 271.4 317.466zM435.084 323.922h-.478c-7.893 13.392-21.765 19.132-37.548 19.132-37.31 0-55.485-32.045-55.485-66.246 0-33.243 18.415-64.095 54.767-64.095 14.589 0 28.938 6.218 36.831 18.416h.24V168.946h33.96v170.76H435.084zM405.428 238.3c-22.24 0-29.894 19.134-29.894 39.463 0 19.371 8.848 39.7 29.894 39.7 22.482 0 29.178-19.613 29.178-39.94C434.606 257.436 427.432 238.3 405.428 238.3zM592.96 339.706H560.673V322.487h-.718c-8.609 13.87-23.436 20.567-37.786 20.567-36.113 0-45.2-20.328-45.2-50.941V216.061h33.959V285.9c0 20.329 5.979 30.372 21.765 30.372 18.415 0 26.306-10.283 26.306-35.393V216.061H592.96zM602.453 302.876H640v36.83H602.453z" } }, "free": ["brands"] }, "wolf-pack-battalion": { "changes": ["5.0.12", "5.8.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f514", "label": "Wolf Pack Battalion", "voted": false, "svg": { "brands": { "last_modified": 1660014459, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M267.73 471.53l10.56 15.84 5.28-12.32 5.28 7V512c21.06-7.92 21.11-66.86 25.51-97.21 4.62-31.89-.88-92.81 81.37-149.11-8.88-23.61-12-49.43-2.64-80.05C421 189 447 196.21 456.43 239.73l-30.35 8.36c11.15 23 17 46.76 13.2 72.14L412 313.18l-6.16 33.43-18.47-7-8.8 33.39-19.35-7 26.39 21.11 8.8-28.15L419 364.2l7-35.63 26.39 14.52c.25-20 7-58.06-8.8-84.45l26.39 5.28c4-22.07-2.38-39.21-7.92-56.74l22.43 9.68c-.44-25.07-29.94-56.79-61.58-58.5-20.22-1.09-56.74-25.17-54.1-51.9 2-19.87 17.45-42.62 43.11-49.7-44 36.51-9.68 67.3 5.28 73.46 4.4-11.44 17.54-69.08 0-130.2-40.39 22.87-89.65 65.1-93.2 147.79l-58 38.71-3.52 93.25L369.78 220l7 7-17.59 3.52-44 38.71-15.84-5.28-28.1 49.25-3.52 119.64 21.11 15.84-32.55 15.84-32.55-15.84 21.11-15.84-3.52-119.64-28.15-49.26-15.84 5.28-44-38.71-17.58-3.51 7-7 107.33 59.82-3.52-93.25-58.06-38.71C185 65.1 135.77 22.87 95.3 0c-17.54 61.12-4.4 118.76 0 130.2 15-6.16 49.26-36.95 5.28-73.46 25.66 7.08 41.15 29.83 43.11 49.7 2.63 26.74-33.88 50.81-54.1 51.9-31.65 1.72-61.15 33.44-61.59 58.51l22.43-9.68c-5.54 17.53-11.91 34.67-7.92 56.74l26.39-5.28c-15.76 26.39-9.05 64.43-8.8 84.45l26.39-14.52 7 35.63 24.63-5.28 8.8 28.15L153.35 366 134 373l-8.8-33.43-18.47 7-6.16-33.43-27.27 7c-3.82-25.38 2-49.1 13.2-72.14l-30.35-8.36c9.4-43.52 35.47-50.77 63.34-54.1 9.36 30.62 6.24 56.45-2.64 80.05 82.25 56.3 76.75 117.23 81.37 149.11 4.4 30.35 4.45 89.29 25.51 97.21v-29.83l5.28-7 5.28 12.32 10.56-15.84 11.44 21.11 11.43-21.1zm79.17-95L331.06 366c7.47-4.36 13.76-8.42 19.35-12.32-.6 7.22-.27 13.84-3.51 22.84zm28.15-49.26c-.4 10.94-.9 21.66-1.76 31.67-7.85-1.86-15.57-3.8-21.11-7 8.24-7.94 15.55-16.32 22.87-24.68zm24.63 5.28c0-13.43-2.05-24.21-5.28-33.43a235 235 0 0 1-18.47 27.27zm3.52-80.94c19.44 12.81 27.8 33.66 29.91 56.3-12.32-4.53-24.63-9.31-36.95-10.56 5.06-12 6.65-28.14 7-45.74zm-1.76-45.74c.81 14.3 1.84 28.82 1.76 42.23 19.22-8.11 29.78-9.72 44-14.08-10.61-18.96-27.2-25.53-45.76-28.16zM165.68 376.52L181.52 366c-7.47-4.36-13.76-8.42-19.35-12.32.6 7.26.27 13.88 3.51 22.88zm-28.15-49.26c.4 10.94.9 21.66 1.76 31.67 7.85-1.86 15.57-3.8 21.11-7-8.24-7.93-15.55-16.31-22.87-24.67zm-24.64 5.28c0-13.43 2-24.21 5.28-33.43a235 235 0 0 0 18.47 27.27zm-3.52-80.94c-19.44 12.81-27.8 33.66-29.91 56.3 12.32-4.53 24.63-9.31 37-10.56-5-12-6.65-28.14-7-45.74zm1.76-45.74c-.81 14.3-1.84 28.82-1.76 42.23-19.22-8.11-29.78-9.72-44-14.08 10.63-18.95 27.23-25.52 45.76-28.15z" } }, "free": ["brands"] }, "won-sign": { "aliases": { "names": ["krw", "won"], "unicodes": { "composite": ["20a9"], "secondary": ["10f159"] } }, "changes": [ "3.2.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["Won Sign", "currency"] }, "styles": ["solid"], "unicode": "f159", "label": "Won Sign", "voted": false, "svg": { "solid": { "last_modified": 1684766476, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M62.4 53.9C56.8 37.1 38.6 28.1 21.9 33.6S-3.9 57.4 1.6 74.1L51.6 224H32c-17.7 0-32 14.3-32 32s14.3 32 32 32H72.9l56.7 170.1c4.5 13.5 17.4 22.4 31.6 21.9s26.4-10.4 29.8-24.2L233 288h46L321 455.8c3.4 13.8 15.6 23.7 29.8 24.2s27.1-8.4 31.6-21.9L439.1 288H480c17.7 0 32-14.3 32-32s-14.3-32-32-32H460.4l50-149.9c5.6-16.8-3.5-34.9-20.2-40.5s-34.9 3.5-40.5 20.2L392.9 224H329L287 56.2C283.5 42 270.7 32 256 32s-27.5 10-31 24.2L183 224h-64L62.4 53.9zm78 234.1H167l-11.4 45.6L140.4 288zM249 224l7-28.1 7 28.1H249zm96 64h26.6l-15.2 45.6L345 288z" } }, "free": ["solid"] }, "wordpress": { "changes": ["4.1.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f19a", "label": "WordPress Logo", "voted": false, "svg": { "brands": { "last_modified": 1660014473, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M61.7 169.4l101.5 278C92.2 413 43.3 340.2 43.3 256c0-30.9 6.6-60.1 18.4-86.6zm337.9 75.9c0-26.3-9.4-44.5-17.5-58.7-10.8-17.5-20.9-32.4-20.9-49.9 0-19.6 14.8-37.8 35.7-37.8.9 0 1.8.1 2.8.2-37.9-34.7-88.3-55.9-143.7-55.9-74.3 0-139.7 38.1-177.8 95.9 5 .2 9.7.3 13.7.3 22.2 0 56.7-2.7 56.7-2.7 11.5-.7 12.8 16.2 1.4 17.5 0 0-11.5 1.3-24.3 2l77.5 230.4L249.8 247l-33.1-90.8c-11.5-.7-22.3-2-22.3-2-11.5-.7-10.1-18.2 1.3-17.5 0 0 35.1 2.7 56 2.7 22.2 0 56.7-2.7 56.7-2.7 11.5-.7 12.8 16.2 1.4 17.5 0 0-11.5 1.3-24.3 2l76.9 228.7 21.2-70.9c9-29.4 16-50.5 16-68.7zm-139.9 29.3l-63.8 185.5c19.1 5.6 39.2 8.7 60.1 8.7 24.8 0 48.5-4.3 70.6-12.1-.6-.9-1.1-1.9-1.5-2.9l-65.4-179.2zm183-120.7c.9 6.8 1.4 14 1.4 21.9 0 21.6-4 45.8-16.2 76.2l-65 187.9C426.2 403 468.7 334.5 468.7 256c0-37-9.4-71.8-26-102.1zM504 256c0 136.8-111.3 248-248 248C119.2 504 8 392.7 8 256 8 119.2 119.2 8 256 8c136.7 0 248 111.2 248 248zm-11.4 0c0-130.5-106.2-236.6-236.6-236.6C125.5 19.4 19.4 125.5 19.4 256S125.6 492.6 256 492.6c130.5 0 236.6-106.1 236.6-236.6z" } }, "free": ["brands"] }, "wordpress-simple": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f411", "label": "Wordpress Simple", "voted": false, "svg": { "brands": { "last_modified": 1660014459, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 8C119.3 8 8 119.2 8 256c0 136.7 111.3 248 248 248s248-111.3 248-248C504 119.2 392.7 8 256 8zM33 256c0-32.3 6.9-63 19.3-90.7l106.4 291.4C84.3 420.5 33 344.2 33 256zm223 223c-21.9 0-43-3.2-63-9.1l66.9-194.4 68.5 187.8c.5 1.1 1 2.1 1.6 3.1-23.1 8.1-48 12.6-74 12.6zm30.7-327.5c13.4-.7 25.5-2.1 25.5-2.1 12-1.4 10.6-19.1-1.4-18.4 0 0-36.1 2.8-59.4 2.8-21.9 0-58.7-2.8-58.7-2.8-12-.7-13.4 17.7-1.4 18.4 0 0 11.4 1.4 23.4 2.1l34.7 95.2L200.6 393l-81.2-241.5c13.4-.7 25.5-2.1 25.5-2.1 12-1.4 10.6-19.1-1.4-18.4 0 0-36.1 2.8-59.4 2.8-4.2 0-9.1-.1-14.4-.3C109.6 73 178.1 33 256 33c58 0 110.9 22.2 150.6 58.5-1-.1-1.9-.2-2.9-.2-21.9 0-37.4 19.1-37.4 39.6 0 18.4 10.6 33.9 21.9 52.3 8.5 14.8 18.4 33.9 18.4 61.5 0 19.1-7.3 41.2-17 72.1l-22.2 74.3-80.7-239.6zm81.4 297.2l68.1-196.9c12.7-31.8 17-57.2 17-79.9 0-8.2-.5-15.8-1.5-22.9 17.4 31.8 27.3 68.2 27.3 107 0 82.3-44.6 154.1-110.9 192.7z" } }, "free": ["brands"] }, "worm": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["dirt", "garden", "worm", "wriggle"] }, "styles": ["solid"], "unicode": "e599", "label": "Worm", "voted": false, "svg": { "solid": { "last_modified": 1684768131, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 96c0-53 43-96 96-96h38.4C439.9 0 480 40.1 480 89.6V176v16V376c0 75.1-60.9 136-136 136s-136-60.9-136-136V296c0-22.1-17.9-40-40-40s-40 17.9-40 40V464c0 26.5-21.5 48-48 48s-48-21.5-48-48V296c0-75.1 60.9-136 136-136s136 60.9 136 136v80c0 22.1 17.9 40 40 40s40-17.9 40-40V192H352c-53 0-96-43-96-96zm144-8a24 24 0 1 0 -48 0 24 24 0 1 0 48 0z" } }, "free": ["solid"] }, "wpbeginner": { "changes": ["4.6.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f297", "label": "WPBeginner", "voted": false, "svg": { "brands": { "last_modified": 1660014474, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M462.799 322.374C519.01 386.682 466.961 480 370.944 480c-39.602 0-78.824-17.687-100.142-50.04-6.887.356-22.702.356-29.59 0C219.848 462.381 180.588 480 141.069 480c-95.49 0-148.348-92.996-91.855-157.626C-29.925 190.523 80.479 32 256.006 32c175.632 0 285.87 158.626 206.793 290.374zm-339.647-82.972h41.529v-58.075h-41.529v58.075zm217.18 86.072v-23.839c-60.506 20.915-132.355 9.198-187.589-33.971l.246 24.897c51.101 46.367 131.746 57.875 187.343 32.913zm-150.753-86.072h166.058v-58.075H189.579v58.075z" } }, "free": ["brands"] }, "wpexplorer": { "changes": ["4.7.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f2de", "label": "WPExplorer", "voted": false, "svg": { "brands": { "last_modified": 1660014482, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M512 256c0 141.2-114.7 256-256 256C114.8 512 0 397.3 0 256S114.7 0 256 0s256 114.7 256 256zm-32 0c0-123.2-100.3-224-224-224C132.5 32 32 132.5 32 256s100.5 224 224 224 224-100.5 224-224zM160.9 124.6l86.9 37.1-37.1 86.9-86.9-37.1 37.1-86.9zm110 169.1l46.6 94h-14.6l-50-100-48.9 100h-14l51.1-106.9-22.3-9.4 6-14 68.6 29.1-6 14.3-16.5-7.1zm-11.8-116.3l68.6 29.4-29.4 68.3L230 246l29.1-68.6zm80.3 42.9l54.6 23.1-23.4 54.3-54.3-23.1 23.1-54.3z" } }, "free": ["brands"] }, "wpforms": { "changes": ["4.6.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f298", "label": "WPForms", "voted": false, "svg": { "brands": { "last_modified": 1660014469, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M448 75.2v361.7c0 24.3-19 43.2-43.2 43.2H43.2C19.3 480 0 461.4 0 436.8V75.2C0 51.1 18.8 32 43.2 32h361.7c24 0 43.1 18.8 43.1 43.2zm-37.3 361.6V75.2c0-3-2.6-5.8-5.8-5.8h-9.3L285.3 144 224 94.1 162.8 144 52.5 69.3h-9.3c-3.2 0-5.8 2.8-5.8 5.8v361.7c0 3 2.6 5.8 5.8 5.8h361.7c3.2.1 5.8-2.7 5.8-5.8zM150.2 186v37H76.7v-37h73.5zm0 74.4v37.3H76.7v-37.3h73.5zm11.1-147.3l54-43.7H96.8l64.5 43.7zm210 72.9v37h-196v-37h196zm0 74.4v37.3h-196v-37.3h196zm-84.6-147.3l64.5-43.7H232.8l53.9 43.7zM371.3 335v37.3h-99.4V335h99.4z" } }, "free": ["brands"] }, "wpressr": { "aliases": { "names": ["rendact"] }, "changes": ["5.4.2"], "ligatures": [], "search": { "terms": ["rendact"] }, "styles": ["brands"], "unicode": "f3e4", "label": "wpressr", "voted": false, "svg": { "brands": { "last_modified": 1660014476, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M248 8C111.03 8 0 119.03 0 256s111.03 248 248 248 248-111.03 248-248S384.97 8 248 8zm171.33 158.6c-15.18 34.51-30.37 69.02-45.63 103.5-2.44 5.51-6.89 8.24-12.97 8.24-23.02-.01-46.03.06-69.05-.05-5.12-.03-8.25 1.89-10.34 6.72-10.19 23.56-20.63 47-30.95 70.5-1.54 3.51-4.06 5.29-7.92 5.29-45.94-.01-91.87-.02-137.81 0-3.13 0-5.63-1.15-7.72-3.45-11.21-12.33-22.46-24.63-33.68-36.94-2.69-2.95-2.79-6.18-1.21-9.73 8.66-19.54 17.27-39.1 25.89-58.66 12.93-29.35 25.89-58.69 38.75-88.08 1.7-3.88 4.28-5.68 8.54-5.65 14.24.1 28.48.02 42.72.05 6.24.01 9.2 4.84 6.66 10.59-13.6 30.77-27.17 61.55-40.74 92.33-5.72 12.99-11.42 25.99-17.09 39-3.91 8.95 7.08 11.97 10.95 5.6.23-.37-1.42 4.18 30.01-67.69 1.36-3.1 3.41-4.4 6.77-4.39 15.21.08 30.43.02 45.64.04 5.56.01 7.91 3.64 5.66 8.75-8.33 18.96-16.71 37.9-24.98 56.89-4.98 11.43 8.08 12.49 11.28 5.33.04-.08 27.89-63.33 32.19-73.16 2.02-4.61 5.44-6.51 10.35-6.5 26.43.05 52.86 0 79.29.05 12.44.02 13.93-13.65 3.9-13.64-25.26.03-50.52.02-75.78.02-6.27 0-7.84-2.47-5.27-8.27 5.78-13.06 11.59-26.11 17.3-39.21 1.73-3.96 4.52-5.79 8.84-5.78 23.09.06 25.98.02 130.78.03 6.08-.01 8.03 2.79 5.62 8.27z" } }, "free": ["brands"] }, "wrench": { "aliases": { "unicodes": { "composite": ["1f527"], "secondary": ["10f0ad"] } }, "changes": [ "2.0.0", "5.0.0", "5.0.13", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "construction", "fix", "mechanic", "plumbing", "settings", "spanner", "tool", "update", "wrench" ] }, "styles": ["solid"], "unicode": "f0ad", "label": "Wrench", "voted": false, "svg": { "solid": { "last_modified": 1684767602, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M352 320c88.4 0 160-71.6 160-160c0-15.3-2.2-30.1-6.2-44.2c-3.1-10.8-16.4-13.2-24.3-5.3l-76.8 76.8c-3 3-7.1 4.7-11.3 4.7H336c-8.8 0-16-7.2-16-16V118.6c0-4.2 1.7-8.3 4.7-11.3l76.8-76.8c7.9-7.9 5.4-21.2-5.3-24.3C382.1 2.2 367.3 0 352 0C263.6 0 192 71.6 192 160c0 19.1 3.4 37.5 9.5 54.5L19.9 396.1C7.2 408.8 0 426.1 0 444.1C0 481.6 30.4 512 67.9 512c18 0 35.3-7.2 48-19.9L297.5 310.5c17 6.2 35.4 9.5 54.5 9.5zM80 408a24 24 0 1 1 0 48 24 24 0 1 1 0-48z" } }, "free": ["solid"] }, "x": { "aliases": { "unicodes": { "composite": ["78"] } }, "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Latin Capital Letter X", "Latin Small Letter X", "letter"] }, "styles": ["solid"], "unicode": "58", "label": "X", "voted": false, "svg": { "solid": { "last_modified": 1684767244, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M376.6 84.5c11.3-13.6 9.5-33.8-4.1-45.1s-33.8-9.5-45.1 4.1L192 206 56.6 43.5C45.3 29.9 25.1 28.1 11.5 39.4S-3.9 70.9 7.4 84.5L150.3 256 7.4 427.5c-11.3 13.6-9.5 33.8 4.1 45.1s33.8 9.5 45.1-4.1L192 306 327.4 468.5c11.3 13.6 31.5 15.4 45.1 4.1s15.4-31.5 4.1-45.1L233.7 256 376.6 84.5z" } }, "free": ["solid"] }, "x-ray": { "aliases": { "unicodes": { "secondary": ["10f497"] } }, "changes": ["5.0.7", "5.10.2", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "health", "medical", "radiological images", "radiology", "skeleton" ] }, "styles": ["solid"], "unicode": "f497", "label": "X Ray", "voted": false, "svg": { "solid": { "last_modified": 1684766751, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M0 64C0 46.3 14.3 32 32 32H480c17.7 0 32 14.3 32 32s-14.3 32-32 32V416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32V96C14.3 96 0 81.7 0 64zM256 96c-8.8 0-16 7.2-16 16v32H160c-8.8 0-16 7.2-16 16s7.2 16 16 16h80v48H128c-8.8 0-16 7.2-16 16s7.2 16 16 16H240v70.6L189.1 307c-5.2-2-10.6-3-16.2-3h-2.1c-23.6 0-42.8 19.2-42.8 42.8c0 9.6 3.2 18.9 9.1 26.4l18.2 23.2c9.7 12.4 24.6 19.6 40.3 19.6H316.4c15.7 0 30.6-7.2 40.3-19.6l18.2-23.2c5.9-7.5 9.1-16.8 9.1-26.4c0-23.6-19.2-42.8-42.8-42.8H339c-5.5 0-11 1-16.2 3L272 326.6V256H384c8.8 0 16-7.2 16-16s-7.2-16-16-16H272V176h80c8.8 0 16-7.2 16-16s-7.2-16-16-16H272V112c0-8.8-7.2-16-16-16zM208 352a16 16 0 1 1 0 32 16 16 0 1 1 0-32zm80 16a16 16 0 1 1 32 0 16 16 0 1 1 -32 0z" } }, "free": ["solid"] }, "x-twitter": { "changes": ["6.4.2"], "ligatures": [], "search": { "terms": [" elon", " twitter", " x"] }, "styles": ["brands"], "unicode": "e61b", "label": "X Twitter", "voted": false, "svg": { "brands": { "last_modified": 1690904784, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M389.2 48h70.6L305.6 224.2 487 464H345L233.7 318.6 106.5 464H35.8L200.7 275.5 26.8 48H172.4L272.9 180.9 389.2 48zM364.4 421.8h39.1L151.1 88h-42L364.4 421.8z" } }, "free": ["brands"] }, "xbox": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f412", "label": "Xbox", "voted": false, "svg": { "brands": { "last_modified": 1660014467, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M369.9 318.2c44.3 54.3 64.7 98.8 54.4 118.7-7.9 15.1-56.7 44.6-92.6 55.9-29.6 9.3-68.4 13.3-100.4 10.2-38.2-3.7-76.9-17.4-110.1-39C93.3 445.8 87 438.3 87 423.4c0-29.9 32.9-82.3 89.2-142.1 32-33.9 76.5-73.7 81.4-72.6 9.4 2.1 84.3 75.1 112.3 109.5zM188.6 143.8c-29.7-26.9-58.1-53.9-86.4-63.4-15.2-5.1-16.3-4.8-28.7 8.1-29.2 30.4-53.5 79.7-60.3 122.4-5.4 34.2-6.1 43.8-4.2 60.5 5.6 50.5 17.3 85.4 40.5 120.9 9.5 14.6 12.1 17.3 9.3 9.9-4.2-11-.3-37.5 9.5-64 14.3-39 53.9-112.9 120.3-194.4zm311.6 63.5C483.3 127.3 432.7 77 425.6 77c-7.3 0-24.2 6.5-36 13.9-23.3 14.5-41 31.4-64.3 52.8C367.7 197 427.5 283.1 448.2 346c6.8 20.7 9.7 41.1 7.4 52.3-1.7 8.5-1.7 8.5 1.4 4.6 6.1-7.7 19.9-31.3 25.4-43.5 7.4-16.2 15-40.2 18.6-58.7 4.3-22.5 3.9-70.8-.8-93.4zM141.3 43C189 40.5 251 77.5 255.6 78.4c.7.1 10.4-4.2 21.6-9.7 63.9-31.1 94-25.8 107.4-25.2-63.9-39.3-152.7-50-233.9-11.7-23.4 11.1-24 11.9-9.4 11.2z" } }, "free": ["brands"] }, "xing": { "changes": ["3.2.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f168", "label": "Xing", "voted": false, "svg": { "brands": { "last_modified": 1660014471, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M162.7 210c-1.8 3.3-25.2 44.4-70.1 123.5-4.9 8.3-10.8 12.5-17.7 12.5H9.8c-7.7 0-12.1-7.5-8.5-14.4l69-121.3c.2 0 .2-.1 0-.3l-43.9-75.6c-4.3-7.8.3-14.1 8.5-14.1H100c7.3 0 13.3 4.1 18 12.2l44.7 77.5zM382.6 46.1l-144 253v.3L330.2 466c3.9 7.1.2 14.1-8.5 14.1h-65.2c-7.6 0-13.6-4-18-12.2l-92.4-168.5c3.3-5.8 51.5-90.8 144.8-255.2 4.6-8.1 10.4-12.2 17.5-12.2h65.7c8 0 12.3 6.7 8.5 14.1z" } }, "free": ["brands"] }, "xmark": { "aliases": { "names": ["close", "multiply", "remove", "times"], "unicodes": { "composite": ["1f5d9", "2715", "2716", "274c", "d7"], "secondary": ["10f00d"] } }, "changes": [ "1.0.0", "5.0.0", "5.0.13", "5.11.0", "5.11.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "Cancellation X", "Multiplication Sign", "Multiplication X", "cancel", "close", "cross", "cross mark", "error", "exit", "incorrect", "mark", "multiplication", "multiply", "notice", "notification", "notify", "problem", "sign", "wrong", "x", "×" ] }, "styles": ["solid"], "unicode": "f00d", "label": "Xmark", "voted": false, "svg": { "solid": { "last_modified": 1684767245, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M342.6 150.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L192 210.7 86.6 105.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L146.7 256 41.4 361.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L192 301.3 297.4 406.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L237.3 256 342.6 150.6z" } }, "free": ["solid"] }, "xmarks-lines": { "changes": ["6.1.0", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["barricade", "barrier", "fence", "poison", "roadblock"] }, "styles": ["solid"], "unicode": "e59a", "label": "Xmarks Lines", "voted": false, "svg": { "solid": { "last_modified": 1684767443, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M32 32C14.3 32 0 46.3 0 64S14.3 96 32 96H608c17.7 0 32-14.3 32-32s-14.3-32-32-32H32zm0 384c-17.7 0-32 14.3-32 32s14.3 32 32 32H608c17.7 0 32-14.3 32-32s-14.3-32-32-32H32zM7 167c-9.4 9.4-9.4 24.6 0 33.9l55 55L7 311c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l55-55 55 55c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9l-55-55 55-55c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0l-55 55L41 167c-9.4-9.4-24.6-9.4-33.9 0zM265 167c-9.4-9.4-24.6-9.4-33.9 0s-9.4 24.6 0 33.9l55 55-55 55c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l55-55 55 55c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9l-55-55 55-55c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0l-55 55-55-55zM455 167c-9.4 9.4-9.4 24.6 0 33.9l55 55-55 55c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l55-55 55 55c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9l-55-55 55-55c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0l-55 55-55-55c-9.4-9.4-24.6-9.4-33.9 0z" } }, "free": ["solid"] }, "y": { "aliases": { "unicodes": { "composite": ["79"] } }, "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": [ "Latin Capital Letter Y", "Latin Small Letter Y", "letter", "yay", "yes" ] }, "styles": ["solid"], "unicode": "59", "label": "Y", "voted": false, "svg": { "solid": { "last_modified": 1684767245, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M58 45.4C47.8 31 27.8 27.7 13.4 38S-4.3 68.2 6 82.6L160 298.3V448c0 17.7 14.3 32 32 32s32-14.3 32-32V298.3L378 82.6c10.3-14.4 6.9-34.4-7.4-44.6S336.2 31 326 45.4L192 232.9 58 45.4z" } }, "free": ["solid"] }, "y-combinator": { "changes": ["4.4.0", "5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f23b", "label": "Y Combinator", "voted": false, "svg": { "brands": { "last_modified": 1660014473, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M448 32v448H0V32h448zM236 287.5L313.5 142h-32.7L235 233c-4.7 9.3-9 18.3-12.8 26.8L210 233l-45.2-91h-35l76.7 143.8v94.5H236v-92.8z" } }, "free": ["brands"] }, "yahoo": { "changes": ["4.1.0", "5.0.0", "5.0.3", "5.13.1"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f19e", "label": "Yahoo Logo", "voted": false, "svg": { "brands": { "last_modified": 1660014471, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M223.69,141.06,167,284.23,111,141.06H14.93L120.76,390.19,82.19,480h94.17L317.27,141.06Zm105.4,135.79a58.22,58.22,0,1,0,58.22,58.22A58.22,58.22,0,0,0,329.09,276.85ZM394.65,32l-93,223.47H406.44L499.07,32Z" } }, "free": ["brands"] }, "yammer": { "changes": ["5.8.0", "6.0.0-beta1"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f840", "label": "Yammer", "voted": false, "svg": { "brands": { "last_modified": 1660014461, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M500.676,159.486a12.779,12.779,0,0,0-6.4-8.282,13.954,13.954,0,0,0-10.078-1.125L457.8,156.7l-.043-.2-22.3,5.785-1.243.333-.608-2.17A369.037,369.037,0,0,0,347.538,4.289a14.1,14.1,0,0,0-19.784-.463l-102.9,102.747H24.947A24.9,24.9,0,0,0,0,131.417V380.38a24.963,24.963,0,0,0,24.918,24.9H224.986L328.072,508a13.667,13.667,0,0,0,19.327,0c.126-.126.249-.255.37-.385a368.025,368.025,0,0,0,69.577-107.374,403.45,403.45,0,0,0,17.3-50.8v-.028l20.406,5.336.029-.073L483.345,362a20.253,20.253,0,0,0,2.619.5,13.359,13.359,0,0,0,4.139-.072,13.5,13.5,0,0,0,10.515-9.924,415.855,415.855,0,0,0,.058-193.013ZM337.125,24.65l.013.014h-.013Zm-110.2,165.161L174.311,281.1a11.338,11.338,0,0,0-1.489,5.655v46.189a22.04,22.04,0,0,1-22.041,22h-3.4A22.068,22.068,0,0,1,125.3,332.962V287.294a11.532,11.532,0,0,0-1.388-5.51l-51.6-92.2a21.988,21.988,0,0,1,19.264-32.726h3.268a22.059,22.059,0,0,1,19.611,11.916l36.357,70.281,37.515-70.512a22.066,22.066,0,0,1,38.556-.695,21.7,21.7,0,0,1,0,21.967ZM337.145,24.673a348.147,348.147,0,0,1,75.8,141.335l.564,1.952-114.134,29.6V131.417a25.006,25.006,0,0,0-24.947-24.9H255.067Zm60.5,367.305v-.043l-.014.014a347.19,347.19,0,0,1-60.177,95.227l-82.2-81.893h19.177a24.978,24.978,0,0,0,24.947-24.9v-66.2l114.6,29.862A385.191,385.191,0,0,1,397.648,391.978Zm84-52.45.015.014-50.618-13.131L299.379,292.1V219.572l119.746-30.99,4.468-1.157,39.54-10.253,18.511-4.816A393,393,0,0,1,481.644,339.528Z" } }, "free": ["brands"] }, "yandex": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f413", "label": "Yandex", "voted": false, "svg": { "brands": { "last_modified": 1660014464, "raw": "", "viewBox": [0, 0, 256, 512], "width": 256, "height": 512, "path": "M153.1 315.8L65.7 512H2l96-209.8c-45.1-22.9-75.2-64.4-75.2-141.1C22.7 53.7 90.8 0 171.7 0H254v512h-55.1V315.8h-45.8zm45.8-269.3h-29.4c-44.4 0-87.4 29.4-87.4 114.6 0 82.3 39.4 108.8 87.4 108.8h29.4V46.5z" } }, "free": ["brands"] }, "yandex-international": { "changes": ["5.0.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f414", "label": "Yandex International", "voted": false, "svg": { "brands": { "last_modified": 1660014462, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M129.5 512V345.9L18.5 48h55.8l81.8 229.7L250.2 0h51.3L180.8 347.8V512h-51.3z" } }, "free": ["brands"] }, "yarn": { "changes": ["5.6.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f7e3", "label": "Yarn", "voted": true, "svg": { "brands": { "last_modified": 1660014474, "raw": "", "viewBox": [0, 0, 496, 512], "width": 496, "height": 512, "path": "M393.9 345.2c-39 9.3-48.4 32.1-104 47.4 0 0-2.7 4-10.4 5.8-13.4 3.3-63.9 6-68.5 6.1-12.4.1-19.9-3.2-22-8.2-6.4-15.3 9.2-22 9.2-22-8.1-5-9-9.9-9.8-8.1-2.4 5.8-3.6 20.1-10.1 26.5-8.8 8.9-25.5 5.9-35.3.8-10.8-5.7.8-19.2.8-19.2s-5.8 3.4-10.5-3.6c-6-9.3-17.1-37.3 11.5-62-1.3-10.1-4.6-53.7 40.6-85.6 0 0-20.6-22.8-12.9-43.3 5-13.4 7-13.3 8.6-13.9 5.7-2.2 11.3-4.6 15.4-9.1 20.6-22.2 46.8-18 46.8-18s12.4-37.8 23.9-30.4c3.5 2.3 16.3 30.6 16.3 30.6s13.6-7.9 15.1-5c8.2 16 9.2 46.5 5.6 65.1-6.1 30.6-21.4 47.1-27.6 57.5-1.4 2.4 16.5 10 27.8 41.3 10.4 28.6 1.1 52.7 2.8 55.3.8 1.4 13.7.8 36.4-13.2 12.8-7.9 28.1-16.9 45.4-17 16.7-.5 17.6 19.2 4.9 22.2zM496 256c0 136.9-111.1 248-248 248S0 392.9 0 256 111.1 8 248 8s248 111.1 248 248zm-79.3 75.2c-1.7-13.6-13.2-23-28-22.8-22 .3-40.5 11.7-52.8 19.2-4.8 3-8.9 5.2-12.4 6.8 3.1-44.5-22.5-73.1-28.7-79.4 7.8-11.3 18.4-27.8 23.4-53.2 4.3-21.7 3-55.5-6.9-74.5-1.6-3.1-7.4-11.2-21-7.4-9.7-20-13-22.1-15.6-23.8-1.1-.7-23.6-16.4-41.4 28-12.2.9-31.3 5.3-47.5 22.8-2 2.2-5.9 3.8-10.1 5.4h.1c-8.4 3-12.3 9.9-16.9 22.3-6.5 17.4.2 34.6 6.8 45.7-17.8 15.9-37 39.8-35.7 82.5-34 36-11.8 73-5.6 79.6-1.6 11.1 3.7 19.4 12 23.8 12.6 6.7 30.3 9.6 43.9 2.8 4.9 5.2 13.8 10.1 30 10.1 6.8 0 58-2.9 72.6-6.5 6.8-1.6 11.5-4.5 14.6-7.1 9.8-3.1 36.8-12.3 62.2-28.7 18-11.7 24.2-14.2 37.6-17.4 12.9-3.2 21-15.1 19.4-28.2z" } }, "free": ["brands"] }, "yelp": { "changes": ["4.2.0", "5.0.0", "5.7.0", "5.8.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f1e9", "label": "Yelp", "voted": false, "svg": { "brands": { "last_modified": 1660014483, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M42.9 240.32l99.62 48.61c19.2 9.4 16.2 37.51-4.5 42.71L30.5 358.45a22.79 22.79 0 0 1-28.21-19.6 197.16 197.16 0 0 1 9-85.32 22.8 22.8 0 0 1 31.61-13.21zm44 239.25a199.45 199.45 0 0 0 79.42 32.11A22.78 22.78 0 0 0 192.94 490l3.9-110.82c.7-21.3-25.5-31.91-39.81-16.1l-74.21 82.4a22.82 22.82 0 0 0 4.09 34.09zm145.34-109.92l58.81 94a22.93 22.93 0 0 0 34 5.5 198.36 198.36 0 0 0 52.71-67.61A23 23 0 0 0 364.17 370l-105.42-34.26c-20.31-6.5-37.81 15.8-26.51 33.91zm148.33-132.23a197.44 197.44 0 0 0-50.41-69.31 22.85 22.85 0 0 0-34 4.4l-62 91.92c-11.9 17.7 4.7 40.61 25.2 34.71L366 268.63a23 23 0 0 0 14.61-31.21zM62.11 30.18a22.86 22.86 0 0 0-9.9 32l104.12 180.44c11.7 20.2 42.61 11.9 42.61-11.4V22.88a22.67 22.67 0 0 0-24.5-22.8 320.37 320.37 0 0 0-112.33 30.1z" } }, "free": ["brands"] }, "yen-sign": { "aliases": { "names": ["cny", "jpy", "rmb", "yen"], "unicodes": { "composite": ["a5"], "secondary": ["10f157"] } }, "changes": [ "3.2.0", "5.0.0", "6.0.0-beta1", "6.0.0-beta3", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": ["Yen Sign", "currency"] }, "styles": ["solid"], "unicode": "f157", "label": "Yen Sign", "voted": false, "svg": { "solid": { "last_modified": 1684766475, "raw": "", "viewBox": [0, 0, 320, 512], "width": 320, "height": 512, "path": "M58.6 46.2C48.8 31.5 29 27.6 14.3 37.4S-4.4 67 5.4 81.7L100.2 224H48c-17.7 0-32 14.3-32 32s14.3 32 32 32h80v32H48c-17.7 0-32 14.3-32 32s14.3 32 32 32h80v64c0 17.7 14.3 32 32 32s32-14.3 32-32V384h80c17.7 0 32-14.3 32-32s-14.3-32-32-32H192V288h80c17.7 0 32-14.3 32-32s-14.3-32-32-32H219.8L314.6 81.7c9.8-14.7 5.8-34.6-8.9-44.4s-34.6-5.8-44.4 8.9L160 198.3 58.6 46.2z" } }, "free": ["solid"] }, "yin-yang": { "aliases": { "unicodes": { "composite": ["262f"], "secondary": ["10f6ad"] } }, "changes": [ "5.3.0", "5.10.2", "5.11.0", "5.11.1", "6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0" ], "ligatures": [], "search": { "terms": [ "daoism", "opposites", "religion", "tao", "taoism", "taoist", "yang", "yin", "yin yang" ] }, "styles": ["solid"], "unicode": "f6ad", "label": "Yin Yang", "voted": false, "svg": { "solid": { "last_modified": 1684767601, "raw": "", "viewBox": [0, 0, 512, 512], "width": 512, "height": 512, "path": "M256 64c53 0 96 43 96 96s-43 96-96 96s-96 43-96 96s43 96 96 96C150 448 64 362 64 256S150 64 256 64zm0 448A256 256 0 1 0 256 0a256 256 0 1 0 0 512zm32-352a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zM224 352a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z" } }, "free": ["solid"] }, "yoast": { "changes": ["4.6.0", "5.0.0", "5.0.3"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f2b1", "label": "Yoast", "voted": false, "svg": { "brands": { "last_modified": 1660014482, "raw": "", "viewBox": [0, 0, 448, 512], "width": 448, "height": 512, "path": "M91.3 76h186l-7 18.9h-179c-39.7 0-71.9 31.6-71.9 70.3v205.4c0 35.4 24.9 70.3 84 70.3V460H91.3C41.2 460 0 419.8 0 370.5V165.2C0 115.9 40.7 76 91.3 76zm229.1-56h66.5C243.1 398.1 241.2 418.9 202.2 459.3c-20.8 21.6-49.3 31.7-78.3 32.7v-51.1c49.2-7.7 64.6-49.9 64.6-75.3 0-20.1.6-12.6-82.1-223.2h61.4L218.2 299 320.4 20zM448 161.5V460H234c6.6-9.6 10.7-16.3 12.1-19.4h182.5V161.5c0-32.5-17.1-51.9-48.2-62.9l6.7-17.6c41.7 13.6 60.9 43.1 60.9 80.5z" } }, "free": ["brands"] }, "youtube": { "aliases": { "unicodes": { "composite": ["f16a"] } }, "changes": ["3.2.0", "5.0.0"], "ligatures": [], "search": { "terms": ["film", "video", "youtube-play", "youtube-square"] }, "styles": ["brands"], "unicode": "f167", "label": "YouTube", "voted": false, "svg": { "brands": { "last_modified": 1660014461, "raw": "", "viewBox": [0, 0, 576, 512], "width": 576, "height": 512, "path": "M549.655 124.083c-6.281-23.65-24.787-42.276-48.284-48.597C458.781 64 288 64 288 64S117.22 64 74.629 75.486c-23.497 6.322-42.003 24.947-48.284 48.597-11.412 42.867-11.412 132.305-11.412 132.305s0 89.438 11.412 132.305c6.281 23.65 24.787 41.5 48.284 47.821C117.22 448 288 448 288 448s170.78 0 213.371-11.486c23.497-6.321 42.003-24.171 48.284-47.821 11.412-42.867 11.412-132.305 11.412-132.305s0-89.438-11.412-132.305zm-317.51 213.508V175.185l142.739 81.205-142.739 81.201z" } }, "free": ["brands"] }, "z": { "aliases": { "unicodes": { "composite": ["7a"] } }, "changes": ["6.0.0-beta1", "6.2.0", "6.3.0", "6.4.0"], "ligatures": [], "search": { "terms": ["Latin Capital Letter Z", "Latin Small Letter Z", "letter"] }, "styles": ["solid"], "unicode": "5a", "label": "Z", "voted": false, "svg": { "solid": { "last_modified": 1684767246, "raw": "", "viewBox": [0, 0, 384, 512], "width": 384, "height": 512, "path": "M0 64C0 46.3 14.3 32 32 32H352c12.4 0 23.7 7.2 29 18.4s3.6 24.5-4.4 34.1L100.3 416H352c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-12.4 0-23.7-7.2-29-18.4s-3.6-24.5 4.4-34.1L283.7 96H32C14.3 96 0 81.7 0 64z" } }, "free": ["solid"] }, "zhihu": { "changes": ["5.2.0"], "ligatures": [], "search": { "terms": [] }, "styles": ["brands"], "unicode": "f63f", "label": "Zhihu", "voted": true, "svg": { "brands": { "last_modified": 1660014458, "raw": "", "viewBox": [0, 0, 640, 512], "width": 640, "height": 512, "path": "M170.54 148.13v217.54l23.43.01 7.71 26.37 42.01-26.37h49.53V148.13H170.54zm97.75 193.93h-27.94l-27.9 17.51-5.08-17.47-11.9-.04V171.75h72.82v170.31zm-118.46-94.39H97.5c1.74-27.1 2.2-51.59 2.2-73.46h51.16s1.97-22.56-8.58-22.31h-88.5c3.49-13.12 7.87-26.66 13.12-40.67 0 0-24.07 0-32.27 21.57-3.39 8.9-13.21 43.14-30.7 78.12 5.89-.64 25.37-1.18 36.84-22.21 2.11-5.89 2.51-6.66 5.14-14.53h28.87c0 10.5-1.2 66.88-1.68 73.44H20.83c-11.74 0-15.56 23.62-15.56 23.62h65.58C66.45 321.1 42.83 363.12 0 396.34c20.49 5.85 40.91-.93 51-9.9 0 0 22.98-20.9 35.59-69.25l53.96 64.94s7.91-26.89-1.24-39.99c-7.58-8.92-28.06-33.06-36.79-41.81L87.9 311.95c4.36-13.98 6.99-27.55 7.87-40.67h61.65s-.09-23.62-7.59-23.62v.01zm412.02-1.6c20.83-25.64 44.98-58.57 44.98-58.57s-18.65-14.8-27.38-4.06c-6 8.15-36.83 48.2-36.83 48.2l19.23 14.43zm-150.09-59.09c-9.01-8.25-25.91 2.13-25.91 2.13s39.52 55.04 41.12 57.45l19.46-13.73s-25.67-37.61-34.66-45.86h-.01zM640 258.35c-19.78 0-130.91.93-131.06.93v-101c4.81 0 12.42-.4 22.85-1.2 40.88-2.41 70.13-4 87.77-4.81 0 0 12.22-27.19-.59-33.44-3.07-1.18-23.17 4.58-23.17 4.58s-165.22 16.49-232.36 18.05c1.6 8.82 7.62 17.08 15.78 19.55 13.31 3.48 22.69 1.7 49.15.89 24.83-1.6 43.68-2.43 56.51-2.43v99.81H351.41s2.82 22.31 25.51 22.85h107.94v70.92c0 13.97-11.19 21.99-24.48 21.12-14.08.11-26.08-1.15-41.69-1.81 1.99 3.97 6.33 14.39 19.31 21.84 9.88 4.81 16.17 6.57 26.02 6.57 29.56 0 45.67-17.28 44.89-45.31v-73.32h122.36c9.68 0 8.7-23.78 8.7-23.78l.03-.01z" } }, "free": ["brands"] } } ================================================ FILE: vendor/wpmetabox/meta-box/css/heading.css ================================================ .rwmb-heading-wrapper { display: block; } .rwmb-heading-wrapper h4 { display: block; font-size: .75rem; line-height: 1.4; border-bottom: 1px solid rgb(230, 230, 230); text-transform: uppercase; padding: .75rem 0 .375rem; margin: 0 0 6px; } ================================================ FILE: vendor/wpmetabox/meta-box/css/icon.css ================================================ .rwmb-icon-select { display: flex; align-items: center; gap: 8px; } .rwmb-icon-select i { width: 16px; } .rwmb-icon-select svg { width: 16px; height: 16px; } ================================================ FILE: vendor/wpmetabox/meta-box/css/image-select.css ================================================ .rwmb-image-select { width: 80px; height: 80px; float: left; margin: 0 8px 8px 0; border: 3px solid #d8d8d8; border-radius: 4px; padding: 1px; cursor: pointer; --color: #2271b1; } .block-editor-page .rwmb-image-select { --color: var(--wp-admin-theme-color, #2271b1); } .rwmb-image-select img { width: 100%; height: 100%; object-fit: cover; } .rwmb-image-select:hover, .rwmb-image-select:has(:checked) { border-color: var(--color); } .rwmb-image_select.rwmb-image_select { display: none; } ================================================ FILE: vendor/wpmetabox/meta-box/css/image.css ================================================ .rwmb-image-item { position: relative; float: left; margin: 0 12px 12px 0; list-style: none; box-sizing: border-box; cursor: move; } .rwmb-image-item .rwmb-file-icon { width: 150px; height: 150px; margin-right: 0; } .rwmb-image-actions { position: absolute; z-index: 2; right: 8px; top: 8px; opacity: 0; transition: opacity .2s; color: #fff; } .rwmb-image-edit, .rwmb-image-delete { color: inherit; text-decoration: none; } .rwmb-image-actions a:hover { color: #fff; opacity: .8; } .rwmb-image-overlay { position: absolute; z-index: 1; top: 0; bottom: 0; left: 0; right: 0; background: #000; opacity: 0; transition: opacity .2s; } .rwmb-image-item:hover .rwmb-image-actions { opacity: 1; } .rwmb-image-item:hover .rwmb-image-overlay { opacity: .6; } .rwmb-image-item .rwmb-edit-media:after { display: none; } @media (max-width: 767px) { .rwmb-image-actions { opacity: 1; z-index: 99; } } ================================================ FILE: vendor/wpmetabox/meta-box/css/input-list.css ================================================ .rwmb-toggle-all-wrapper { margin-top: 0; } .rwmb-input-list { line-height: 1.8; } .rwmb-input-list.hidden { display: none; } .rwmb-input-list .rwmb-input-list { margin-left: 20px; } .rwmb-input-list > label { display: block; } .rwmb-input-list.rwmb-inline { line-height: inherit; display: flex; flex-wrap: wrap; gap: 6px 12px; } /* Media modal */ .attachment-details .compat-attachment-fields .rwmb-input-list > label > input { margin: 0 0.25rem 0 0; } .compat-attachment-fields .rwmb-input-list.rwmb-inline { gap: 10px; } ================================================ FILE: vendor/wpmetabox/meta-box/css/input.css ================================================ .rwmb-input-group { display: flex; align-items: stretch; } .rwmb-input-group-text { display: flex; align-items: center; padding: 0 8px; background: #f0f0f0; border: 1px solid #7e8993; border-radius: 4px; white-space: nowrap; } .rwmb-input-group-text:first-child, .rwmb-input-group input:not(:last-child) { border-top-right-radius: 0; border-bottom-right-radius: 0; } .rwmb-input-group-text:last-child, .rwmb-input-group input:not(:first-child) { border-top-left-radius: 0; border-bottom-left-radius: 0; } .rwmb-input-group input { margin: 0; } .rwmb-input-group.rwmb-input-group.rwmb-input-group :not(:first-child) { margin-left: -1px; } ================================================ FILE: vendor/wpmetabox/meta-box/css/jqueryui/core.css ================================================ /*! * jQuery UI CSS Framework 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors * Released under the MIT license. * http://jquery.org/license * * http://api.jqueryui.com/category/theming/ */ /* Layout helpers ----------------------------------*/ .ui-helper-hidden { display: none; } .ui-helper-hidden-accessible { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; } .ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } .ui-helper-clearfix:before, .ui-helper-clearfix:after { content: ""; display: table; border-collapse: collapse; } .ui-helper-clearfix:after { clear: both; } .ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; -ms-filter: "alpha(opacity=0)"; /* support: IE8 */ } .ui-front { z-index: 100; } /* Interaction Cues ----------------------------------*/ .ui-state-disabled { cursor: default !important; pointer-events: none; } /* Icons ----------------------------------*/ .ui-icon { display: inline-block; vertical-align: middle; margin-top: -.25em; position: relative; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } .ui-widget-icon-block { left: 50%; margin-left: -8px; display: block; } /* Misc visuals ----------------------------------*/ /* Overlays */ .ui-widget-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; } ================================================ FILE: vendor/wpmetabox/meta-box/css/jqueryui/datepicker.css ================================================ /*! * jQuery UI Datepicker 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors * Released under the MIT license. * http://jquery.org/license * * http://api.jqueryui.com/datepicker/#theming */ .ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; } .ui-datepicker .ui-datepicker-header { position: relative; padding: .2em 0; } .ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position: absolute; top: 2px; width: 1.8em; height: 1.8em; } .ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } .ui-datepicker .ui-datepicker-prev { left: 2px; } .ui-datepicker .ui-datepicker-next { right: 2px; } .ui-datepicker .ui-datepicker-prev-hover { left: 1px; } .ui-datepicker .ui-datepicker-next-hover { right: 1px; } .ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; } .ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; } .ui-datepicker .ui-datepicker-title select { font-size: 1em; margin: 1px 0; } .ui-datepicker select.ui-datepicker-month, .ui-datepicker select.ui-datepicker-year { width: 45%; } .ui-datepicker table { width: 100%; font-size: .9em; border-collapse: collapse; margin: 0 0 .4em; } .ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } .ui-datepicker td { border: 0; padding: 1px; } .ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; } .ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding: 0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } .ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width: auto; overflow: visible; } .ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float: left; } /* with multiple calendars */ .ui-datepicker.ui-datepicker-multi { width: auto; } .ui-datepicker-multi .ui-datepicker-group { float: left; } .ui-datepicker-multi .ui-datepicker-group table { width: 95%; margin: 0 auto .4em; } .ui-datepicker-multi-2 .ui-datepicker-group { width: 50%; } .ui-datepicker-multi-3 .ui-datepicker-group { width: 33.3%; } .ui-datepicker-multi-4 .ui-datepicker-group { width: 25%; } .ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header, .ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width: 0; } .ui-datepicker-multi .ui-datepicker-buttonpane { clear: left; } .ui-datepicker-row-break { clear: both; width: 100%; font-size: 0; } /* RTL support */ .ui-datepicker-rtl { direction: rtl; } .ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } .ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } .ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } .ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } .ui-datepicker-rtl .ui-datepicker-buttonpane { clear: right; } .ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } .ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current, .ui-datepicker-rtl .ui-datepicker-group { float: right; } .ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header, .ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width: 0; border-left-width: 1px; } /* Icons */ .ui-datepicker .ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; left: .5em; top: .3em; } ================================================ FILE: vendor/wpmetabox/meta-box/css/jqueryui/slider.css ================================================ /*! * jQuery UI Slider 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors * Released under the MIT license. * http://jquery.org/license * * http://api.jqueryui.com/slider/#theming */ .ui-slider { position: relative; text-align: left; } .ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: pointer; -ms-touch-action: none; touch-action: none; } .ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; } /* support: IE8 - See #6727 */ .ui-slider.ui-state-disabled .ui-slider-handle, .ui-slider.ui-state-disabled .ui-slider-range { filter: inherit; } .ui-slider-horizontal { height: .8em; } .ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; } .ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; } .ui-slider-horizontal .ui-slider-range-min { left: 0; } .ui-slider-horizontal .ui-slider-range-max { right: 0; } .ui-slider-vertical { width: .8em; height: 100px; } .ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; } .ui-slider-vertical .ui-slider-range { left: 0; width: 100%; } .ui-slider-vertical .ui-slider-range-min { bottom: 0; } .ui-slider-vertical .ui-slider-range-max { top: 0; } ================================================ FILE: vendor/wpmetabox/meta-box/css/jqueryui/theme.css ================================================ /*! * jQuery UI CSS Framework 1.13.2 * http://jqueryui.com * * Copyright jQuery Foundation and other contributors * Released under the MIT license. * http://jquery.org/license * * http://api.jqueryui.com/category/theming/ * * To view and modify this theme, visit http://jqueryui.com/themeroller/ */ /* Component containers ----------------------------------*/ .ui-widget { font-family: Arial,Helvetica,sans-serif/*{ffDefault}*/; font-size: 1em/*{fsDefault}*/; } .ui-widget .ui-widget { font-size: 1em; } .ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Arial,Helvetica,sans-serif/*{ffDefault}*/; font-size: 1em; } .ui-widget.ui-widget-content { border: 1px solid #c5c5c5/*{borderColorDefault}*/; } .ui-widget-content { border: 1px solid #dddddd/*{borderColorContent}*/; background: #ffffff/*{bgColorContent}*/ /*{bgImgUrlContent}*/ /*{bgContentXPos}*/ /*{bgContentYPos}*/ /*{bgContentRepeat}*/; color: #333333/*{fcContent}*/; } .ui-widget-content a { color: #333333/*{fcContent}*/; } .ui-widget-header { border: 1px solid #dddddd/*{borderColorHeader}*/; background: #e9e9e9/*{bgColorHeader}*/ /*{bgImgUrlHeader}*/ /*{bgHeaderXPos}*/ /*{bgHeaderYPos}*/ /*{bgHeaderRepeat}*/; color: #333333/*{fcHeader}*/; font-weight: bold; } .ui-widget-header a { color: #333333/*{fcHeader}*/; } /* Interaction states ----------------------------------*/ .ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default, .ui-button, /* We use html here because we need a greater specificity to make sure disabled works properly when clicked or hovered */ html .ui-button.ui-state-disabled:hover, html .ui-button.ui-state-disabled:active { border: 1px solid #c5c5c5/*{borderColorDefault}*/; background: #f6f6f6/*{bgColorDefault}*/ /*{bgImgUrlDefault}*/ /*{bgDefaultXPos}*/ /*{bgDefaultYPos}*/ /*{bgDefaultRepeat}*/; font-weight: normal/*{fwDefault}*/; color: #454545/*{fcDefault}*/; } .ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited, a.ui-button, a:link.ui-button, a:visited.ui-button, .ui-button { color: #454545/*{fcDefault}*/; text-decoration: none; } .ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus, .ui-button:hover, .ui-button:focus { border: 1px solid #cccccc/*{borderColorHover}*/; background: #ededed/*{bgColorHover}*/ /*{bgImgUrlHover}*/ /*{bgHoverXPos}*/ /*{bgHoverYPos}*/ /*{bgHoverRepeat}*/; font-weight: normal/*{fwDefault}*/; color: #2b2b2b/*{fcHover}*/; } .ui-state-hover a, .ui-state-hover a:hover, .ui-state-hover a:link, .ui-state-hover a:visited, .ui-state-focus a, .ui-state-focus a:hover, .ui-state-focus a:link, .ui-state-focus a:visited, a.ui-button:hover, a.ui-button:focus { color: #2b2b2b/*{fcHover}*/; text-decoration: none; } .ui-visual-focus { box-shadow: 0 0 3px 1px rgb(94, 158, 214); } .ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active, a.ui-button:active, .ui-button:active, .ui-button.ui-state-active:hover { border: 1px solid #003eff/*{borderColorActive}*/; background: #007fff/*{bgColorActive}*/ /*{bgImgUrlActive}*/ /*{bgActiveXPos}*/ /*{bgActiveYPos}*/ /*{bgActiveRepeat}*/; font-weight: normal/*{fwDefault}*/; color: #ffffff/*{fcActive}*/; } .ui-icon-background, .ui-state-active .ui-icon-background { border: #003eff/*{borderColorActive}*/; background-color: #ffffff/*{fcActive}*/; } .ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #ffffff/*{fcActive}*/; text-decoration: none; } /* Interaction Cues ----------------------------------*/ .ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight { border: 1px solid #dad55e/*{borderColorHighlight}*/; background: #fffa90/*{bgColorHighlight}*/ /*{bgImgUrlHighlight}*/ /*{bgHighlightXPos}*/ /*{bgHighlightYPos}*/ /*{bgHighlightRepeat}*/; color: #777620/*{fcHighlight}*/; } .ui-state-checked { border: 1px solid #dad55e/*{borderColorHighlight}*/; background: #fffa90/*{bgColorHighlight}*/; } .ui-state-highlight a, .ui-widget-content .ui-state-highlight a, .ui-widget-header .ui-state-highlight a { color: #777620/*{fcHighlight}*/; } .ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error { border: 1px solid #f1a899/*{borderColorError}*/; background: #fddfdf/*{bgColorError}*/ /*{bgImgUrlError}*/ /*{bgErrorXPos}*/ /*{bgErrorYPos}*/ /*{bgErrorRepeat}*/; color: #5f3f3f/*{fcError}*/; } .ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #5f3f3f/*{fcError}*/; } .ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #5f3f3f/*{fcError}*/; } .ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } .ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; -ms-filter: "alpha(opacity=70)"; /* support: IE8 */ font-weight: normal; } .ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; -ms-filter: "alpha(opacity=35)"; /* support: IE8 */ background-image: none; } .ui-state-disabled .ui-icon { -ms-filter: "alpha(opacity=35)"; /* support: IE8 - See #6059 */ } /* Icons ----------------------------------*/ /* states and images */ .ui-icon { width: 16px; height: 16px; } /* positioning */ /* Three classes needed to override `.ui-button:hover .ui-icon` */ .ui-icon-blank.ui-icon-blank.ui-icon-blank { background-image: none; } .ui-icon-caret-1-n { background-position: 0 0; } .ui-icon-caret-1-ne { background-position: -16px 0; } .ui-icon-caret-1-e { background-position: -32px 0; } .ui-icon-caret-1-se { background-position: -48px 0; } .ui-icon-caret-1-s { background-position: -65px 0; } .ui-icon-caret-1-sw { background-position: -80px 0; } .ui-icon-caret-1-w { background-position: -96px 0; } .ui-icon-caret-1-nw { background-position: -112px 0; } .ui-icon-caret-2-n-s { background-position: -128px 0; } .ui-icon-caret-2-e-w { background-position: -144px 0; } .ui-icon-triangle-1-n { background-position: 0 -16px; } .ui-icon-triangle-1-ne { background-position: -16px -16px; } .ui-icon-triangle-1-e { background-position: -32px -16px; } .ui-icon-triangle-1-se { background-position: -48px -16px; } .ui-icon-triangle-1-s { background-position: -65px -16px; } .ui-icon-triangle-1-sw { background-position: -80px -16px; } .ui-icon-triangle-1-w { background-position: -96px -16px; } .ui-icon-triangle-1-nw { background-position: -112px -16px; } .ui-icon-triangle-2-n-s { background-position: -128px -16px; } .ui-icon-triangle-2-e-w { background-position: -144px -16px; } .ui-icon-arrow-1-n { background-position: 0 -32px; } .ui-icon-arrow-1-ne { background-position: -16px -32px; } .ui-icon-arrow-1-e { background-position: -32px -32px; } .ui-icon-arrow-1-se { background-position: -48px -32px; } .ui-icon-arrow-1-s { background-position: -65px -32px; } .ui-icon-arrow-1-sw { background-position: -80px -32px; } .ui-icon-arrow-1-w { background-position: -96px -32px; } .ui-icon-arrow-1-nw { background-position: -112px -32px; } .ui-icon-arrow-2-n-s { background-position: -128px -32px; } .ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } .ui-icon-arrow-2-e-w { background-position: -160px -32px; } .ui-icon-arrow-2-se-nw { background-position: -176px -32px; } .ui-icon-arrowstop-1-n { background-position: -192px -32px; } .ui-icon-arrowstop-1-e { background-position: -208px -32px; } .ui-icon-arrowstop-1-s { background-position: -224px -32px; } .ui-icon-arrowstop-1-w { background-position: -240px -32px; } .ui-icon-arrowthick-1-n { background-position: 1px -48px; } .ui-icon-arrowthick-1-ne { background-position: -16px -48px; } .ui-icon-arrowthick-1-e { background-position: -32px -48px; } .ui-icon-arrowthick-1-se { background-position: -48px -48px; } .ui-icon-arrowthick-1-s { background-position: -64px -48px; } .ui-icon-arrowthick-1-sw { background-position: -80px -48px; } .ui-icon-arrowthick-1-w { background-position: -96px -48px; } .ui-icon-arrowthick-1-nw { background-position: -112px -48px; } .ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } .ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } .ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } .ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } .ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } .ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } .ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } .ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } .ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } .ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } .ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } .ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } .ui-icon-arrowreturn-1-w { background-position: -64px -64px; } .ui-icon-arrowreturn-1-n { background-position: -80px -64px; } .ui-icon-arrowreturn-1-e { background-position: -96px -64px; } .ui-icon-arrowreturn-1-s { background-position: -112px -64px; } .ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } .ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } .ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } .ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } .ui-icon-arrow-4 { background-position: 0 -80px; } .ui-icon-arrow-4-diag { background-position: -16px -80px; } .ui-icon-extlink { background-position: -32px -80px; } .ui-icon-newwin { background-position: -48px -80px; } .ui-icon-refresh { background-position: -64px -80px; } .ui-icon-shuffle { background-position: -80px -80px; } .ui-icon-transfer-e-w { background-position: -96px -80px; } .ui-icon-transferthick-e-w { background-position: -112px -80px; } .ui-icon-folder-collapsed { background-position: 0 -96px; } .ui-icon-folder-open { background-position: -16px -96px; } .ui-icon-document { background-position: -32px -96px; } .ui-icon-document-b { background-position: -48px -96px; } .ui-icon-note { background-position: -64px -96px; } .ui-icon-mail-closed { background-position: -80px -96px; } .ui-icon-mail-open { background-position: -96px -96px; } .ui-icon-suitcase { background-position: -112px -96px; } .ui-icon-comment { background-position: -128px -96px; } .ui-icon-person { background-position: -144px -96px; } .ui-icon-print { background-position: -160px -96px; } .ui-icon-trash { background-position: -176px -96px; } .ui-icon-locked { background-position: -192px -96px; } .ui-icon-unlocked { background-position: -208px -96px; } .ui-icon-bookmark { background-position: -224px -96px; } .ui-icon-tag { background-position: -240px -96px; } .ui-icon-home { background-position: 0 -112px; } .ui-icon-flag { background-position: -16px -112px; } .ui-icon-calendar { background-position: -32px -112px; } .ui-icon-cart { background-position: -48px -112px; } .ui-icon-pencil { background-position: -64px -112px; } .ui-icon-clock { background-position: -80px -112px; } .ui-icon-disk { background-position: -96px -112px; } .ui-icon-calculator { background-position: -112px -112px; } .ui-icon-zoomin { background-position: -128px -112px; } .ui-icon-zoomout { background-position: -144px -112px; } .ui-icon-search { background-position: -160px -112px; } .ui-icon-wrench { background-position: -176px -112px; } .ui-icon-gear { background-position: -192px -112px; } .ui-icon-heart { background-position: -208px -112px; } .ui-icon-star { background-position: -224px -112px; } .ui-icon-link { background-position: -240px -112px; } .ui-icon-cancel { background-position: 0 -128px; } .ui-icon-plus { background-position: -16px -128px; } .ui-icon-plusthick { background-position: -32px -128px; } .ui-icon-minus { background-position: -48px -128px; } .ui-icon-minusthick { background-position: -64px -128px; } .ui-icon-close { background-position: -80px -128px; } .ui-icon-closethick { background-position: -96px -128px; } .ui-icon-key { background-position: -112px -128px; } .ui-icon-lightbulb { background-position: -128px -128px; } .ui-icon-scissors { background-position: -144px -128px; } .ui-icon-clipboard { background-position: -160px -128px; } .ui-icon-copy { background-position: -176px -128px; } .ui-icon-contact { background-position: -192px -128px; } .ui-icon-image { background-position: -208px -128px; } .ui-icon-video { background-position: -224px -128px; } .ui-icon-script { background-position: -240px -128px; } .ui-icon-alert { background-position: 0 -144px; } .ui-icon-info { background-position: -16px -144px; } .ui-icon-notice { background-position: -32px -144px; } .ui-icon-help { background-position: -48px -144px; } .ui-icon-check { background-position: -64px -144px; } .ui-icon-bullet { background-position: -80px -144px; } .ui-icon-radio-on { background-position: -96px -144px; } .ui-icon-radio-off { background-position: -112px -144px; } .ui-icon-pin-w { background-position: -128px -144px; } .ui-icon-pin-s { background-position: -144px -144px; } .ui-icon-play { background-position: 0 -160px; } .ui-icon-pause { background-position: -16px -160px; } .ui-icon-seek-next { background-position: -32px -160px; } .ui-icon-seek-prev { background-position: -48px -160px; } .ui-icon-seek-end { background-position: -64px -160px; } .ui-icon-seek-start { background-position: -80px -160px; } /* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ .ui-icon-seek-first { background-position: -80px -160px; } .ui-icon-stop { background-position: -96px -160px; } .ui-icon-eject { background-position: -112px -160px; } .ui-icon-volume-off { background-position: -128px -160px; } .ui-icon-volume-on { background-position: -144px -160px; } .ui-icon-power { background-position: 0 -176px; } .ui-icon-signal-diag { background-position: -16px -176px; } .ui-icon-signal { background-position: -32px -176px; } .ui-icon-battery-0 { background-position: -48px -176px; } .ui-icon-battery-1 { background-position: -64px -176px; } .ui-icon-battery-2 { background-position: -80px -176px; } .ui-icon-battery-3 { background-position: -96px -176px; } .ui-icon-circle-plus { background-position: 0 -192px; } .ui-icon-circle-minus { background-position: -16px -192px; } .ui-icon-circle-close { background-position: -32px -192px; } .ui-icon-circle-triangle-e { background-position: -48px -192px; } .ui-icon-circle-triangle-s { background-position: -64px -192px; } .ui-icon-circle-triangle-w { background-position: -80px -192px; } .ui-icon-circle-triangle-n { background-position: -96px -192px; } .ui-icon-circle-arrow-e { background-position: -112px -192px; } .ui-icon-circle-arrow-s { background-position: -128px -192px; } .ui-icon-circle-arrow-w { background-position: -144px -192px; } .ui-icon-circle-arrow-n { background-position: -160px -192px; } .ui-icon-circle-zoomin { background-position: -176px -192px; } .ui-icon-circle-zoomout { background-position: -192px -192px; } .ui-icon-circle-check { background-position: -208px -192px; } .ui-icon-circlesmall-plus { background-position: 0 -208px; } .ui-icon-circlesmall-minus { background-position: -16px -208px; } .ui-icon-circlesmall-close { background-position: -32px -208px; } .ui-icon-squaresmall-plus { background-position: -48px -208px; } .ui-icon-squaresmall-minus { background-position: -64px -208px; } .ui-icon-squaresmall-close { background-position: -80px -208px; } .ui-icon-grip-dotted-vertical { background-position: 0 -224px; } .ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } .ui-icon-grip-solid-vertical { background-position: -32px -224px; } .ui-icon-grip-solid-horizontal { background-position: -48px -224px; } .ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } .ui-icon-grip-diagonal-se { background-position: -80px -224px; } /* Misc visuals ----------------------------------*/ /* Corner radius */ .ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { border-top-left-radius: 3px/*{cornerRadius}*/; } .ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { border-top-right-radius: 3px/*{cornerRadius}*/; } .ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { border-bottom-left-radius: 3px/*{cornerRadius}*/; } .ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { border-bottom-right-radius: 3px/*{cornerRadius}*/; } /* Overlays */ .ui-widget-overlay { background: #aaaaaa/*{bgColorOverlay}*/ /*{bgImgUrlOverlay}*/ /*{bgOverlayXPos}*/ /*{bgOverlayYPos}*/ /*{bgOverlayRepeat}*/; opacity: .3/*{opacityOverlay}*/; -ms-filter: "alpha(opacity=30)"/*{opacityFilterOverlay}*/; /* support: IE8 */ } .ui-widget-shadow { -webkit-box-shadow: 0/*{offsetLeftShadow}*/ 0/*{offsetTopShadow}*/ 5px/*{thicknessShadow}*/ #666666/*{bgColorShadow}*/; box-shadow: 0/*{offsetLeftShadow}*/ 0/*{offsetTopShadow}*/ 5px/*{thicknessShadow}*/ #666666/*{bgColorShadow}*/; } ================================================ FILE: vendor/wpmetabox/meta-box/css/key-value.css ================================================ .rwmb-key_value-clone { display: flex; align-items: center; gap: 8px; } .rwmb-key_value-clone input { flex: 1; } .rwmb-key_value-clone .remove-clone { position: static; } ================================================ FILE: vendor/wpmetabox/meta-box/css/map.css ================================================ .rwmb-map-canvas { width: 100%; height: 400px; margin-bottom: 10px; } /* Autocomplete style, copy from WordPress's common.css and forms.css */ input.ui-autocomplete-input.open { border-bottom-color: transparent; } .ui-autocomplete { padding: 0; margin: 0; list-style: none; position: absolute; z-index: 10000; border: 1px solid #5b9dd9; box-shadow: 0 1px 2px rgba( 30, 140, 190, 0.8 ); background-color: #fff; } .ui-autocomplete li { margin-bottom: 0; padding: 4px 10px; white-space: nowrap; text-align: left; cursor: pointer; } /* Colors for the wplink toolbar autocomplete. */ .ui-autocomplete .ui-state-focus { background-color: #ddd; } .ui-helper-hidden-accessible { border: 0; clip: rect(1px, 1px, 1px, 1px); -webkit-clip-path: inset(50%); clip-path: inset(50%); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; word-wrap: normal !important; /* many screen reader and browser combinations announce broken words as they would appear visually */ } ================================================ FILE: vendor/wpmetabox/meta-box/css/media.css ================================================ .rwmb-media-list { margin: 0; padding: 0; overflow: hidden; } .rwmb-edit-media, .rwmb-remove-media { color: inherit; text-decoration: none; } .rwmb-edit-media:after { content: "|"; color: #dcdcde; margin: 0 6px; } .rwmb-remove-media { color: #b32d2e; } ================================================ FILE: vendor/wpmetabox/meta-box/css/modal.css ================================================ .rwmb-modal-add-button { display: inline-block; margin-top: 6px; } body.rwmb-modal-show, body.rwmb-modal-show .interface-interface-skeleton__sidebar { overflow: hidden; } /* Mimic style of media modal */ .rwmb-modal { position: fixed; top: 30px; left: 30px; right: 30px; bottom: 30px; z-index: 160000; margin: auto; overflow: hidden; flex-direction: column; display: none; } .rwmb-modal[size="small"] { max-width: 600px; } .rwmb-modal-content { overflow: hidden; flex: 1; } iframe#rwmb-modal-iframe { width: 100%; height: 100%; border: none; overflow: hidden; } .rwmb-modal-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; min-height: 360px; background: #000; opacity: 0.7; z-index: 159900; display: none; } .rwmb-modal-title { background: #f0f0f1; border-bottom: 1px solid #c3c4c7; position: relative; } .rwmb-modal-title h2 { font-size: 22px; line-height: 50px; padding: 0 20px; margin: 0; } .rwmb-modal-close { position: absolute; top: 0; right: 0; width: 50px; height: 50px; font-size: 22px; line-height: 50px; margin: 0; padding: 0; border: none; background: none; color: #646970; z-index: 1000; cursor: pointer; outline: none; transition: color .1s ease-in-out; } .rwmb-modal-close:hover, .rwmb-modal-close:active { color: #135e96; } ================================================ FILE: vendor/wpmetabox/meta-box/css/oembed.css ================================================ .rwmb-oembed-wrapper .spinner { float: none; vertical-align: top; display: inline-block; } .rwmb-embed-media { margin-top: 1em; } .rwmb-embed-media iframe { max-width: 100%; } ================================================ FILE: vendor/wpmetabox/meta-box/css/osm-frontend.css ================================================ img.leaflet-marker-icon { margin-left: -12px; margin-top: -41px; } ================================================ FILE: vendor/wpmetabox/meta-box/css/osm.css ================================================ .rwmb-osm-canvas { width: 100%; height: 400px; margin-bottom: 10px; } /* Autocomplete style, copy from WordPress's common.css and forms.css */ input.ui-autocomplete-input.open { border-bottom-color: transparent; } .ui-autocomplete { padding: 0; margin: 0; list-style: none; position: absolute; z-index: 10000; border: 1px solid #5b9dd9; box-shadow: 0 1px 2px rgba( 30, 140, 190, 0.8 ); background-color: #fff; } .ui-autocomplete li { margin-bottom: 0; padding: 4px 10px; white-space: nowrap; text-align: left; cursor: pointer; } /* Colors for the wplink toolbar autocomplete. */ .ui-autocomplete .ui-state-focus { background-color: #ddd; } .ui-helper-hidden-accessible { border: 0; clip: rect(1px, 1px, 1px, 1px); -webkit-clip-path: inset(50%); clip-path: inset(50%); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; word-wrap: normal !important; /* many screen reader and browser combinations announce broken words as they would appear visually */ } ================================================ FILE: vendor/wpmetabox/meta-box/css/password.css ================================================ .rwmb-password-wrapper .rwmb-input { position: relative; } .rwmb-password-toggle { background: none; border: none; padding: 0; cursor: pointer; position: absolute; width: 36px; height: 36px; top: 0; right: 0; display: flex; align-items: center; justify-content: center; } .rwmb-password-toggle svg { width: 20px; height: 20px; fill: #2C3338; } ================================================ FILE: vendor/wpmetabox/meta-box/css/range.css ================================================ .rwmb-range-inner { display: flex; align-items: center; justify-content: space-between; } .rwmb-range { flex: 1; } .rwmb-range.rwmb-range, .rwmb-range.rwmb-range:hover { vertical-align: middle; padding: 0; border: none; } .rwmb-range-output { margin-left: 8px; } ================================================ FILE: vendor/wpmetabox/meta-box/css/select-advanced.css ================================================ .rwmb-field .select2-container { height: auto; min-width: 160px; max-width: 100%; } .select2-container .select2-selection--single, .select2-container .select2-selection--multiple, .select2-dropdown { border-color: #7e8993; } .select2-container .select2-selection--multiple { min-height: 30px; } .select2-container--open .select2-dropdown--below { border-top: 1px solid #7e8993; } .select2-container--open .select2-dropdown--above { border-bottom: 1px solid #7e8993; } .select2-container .select2-selection--single { height: 30px; } .select2-container .select2-selection--multiple .select2-selection__rendered { display: block; } .select2-container--default .select2-selection--single .select2-selection__rendered { line-height: 30px; } .select2-container--default .select2-selection--single .select2-selection__arrow { height: 28px; } .select2-results__option { margin-bottom: 0; } .select2-container .select2-search--inline { margin-bottom: 0; } .select2-container .select2-search--inline .select2-search__field { margin-top: 0; min-height: auto; } .select2-search--dropdown .select2-search__field { padding: 0 4px; min-height: 30px; } body > .select2-container { z-index: 999999; } @media (max-width: 782px) { .select2-container .select2-selection--single { height: 40px; } .select2-container--default .select2-selection--single .select2-selection__rendered { line-height: 40px; } .select2-container--default .select2-selection--single .select2-selection__arrow { height: 38px; } } ================================================ FILE: vendor/wpmetabox/meta-box/css/select-tree.css ================================================ .rwmb-select-tree .rwmb-select-tree { margin-top: 6px; } .rwmb-select-tree.hidden { display: none; } ================================================ FILE: vendor/wpmetabox/meta-box/css/select.css ================================================ .rwmb-select { min-width: 160px; } .rwmb-select.rwmb-select[multiple] { padding: 0; } .rwmb-select option { padding: 4px 8px; } .rwmb-select-all-none { display: block; margin-top: 5px; } ================================================ FILE: vendor/wpmetabox/meta-box/css/select2/select2.css ================================================ .select2-container { box-sizing: border-box; display: inline-block; margin: 0; position: relative; vertical-align: middle; } .select2-container .select2-selection--single { box-sizing: border-box; cursor: pointer; display: block; height: 28px; user-select: none; -webkit-user-select: none; } .select2-container .select2-selection--single .select2-selection__rendered { display: block; padding-left: 8px; padding-right: 20px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .select2-container .select2-selection--single .select2-selection__clear { position: relative; } .select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered { padding-right: 8px; padding-left: 20px; } .select2-container .select2-selection--multiple { box-sizing: border-box; cursor: pointer; display: block; min-height: 32px; user-select: none; -webkit-user-select: none; } .select2-container .select2-selection--multiple .select2-selection__rendered { display: inline-block; overflow: hidden; padding-left: 8px; text-overflow: ellipsis; white-space: nowrap; } .select2-container .select2-search--inline { float: left; } .select2-container .select2-search--inline .select2-search__field { box-sizing: border-box; border: none; font-size: 100%; margin-top: 5px; padding: 0; } .select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button { -webkit-appearance: none; } .select2-dropdown { background-color: white; border: 1px solid #aaa; border-radius: 4px; box-sizing: border-box; display: block; position: absolute; left: -100000px; width: 100%; z-index: 1051; } .select2-results { display: block; } .select2-results__options { list-style: none; margin: 0; padding: 0; } .select2-results__option { padding: 6px; user-select: none; -webkit-user-select: none; } .select2-results__option[aria-selected] { cursor: pointer; } .select2-container--open .select2-dropdown { left: 0; } .select2-container--open .select2-dropdown--above { border-bottom: none; border-bottom-left-radius: 0; border-bottom-right-radius: 0; } .select2-container--open .select2-dropdown--below { border-top: none; border-top-left-radius: 0; border-top-right-radius: 0; } .select2-search--dropdown { display: block; padding: 4px; } .select2-search--dropdown .select2-search__field { padding: 4px; width: 100%; box-sizing: border-box; } .select2-search--dropdown .select2-search__field::-webkit-search-cancel-button { -webkit-appearance: none; } .select2-search--dropdown.select2-search--hide { display: none; } .select2-close-mask { border: 0; margin: 0; padding: 0; display: block; position: fixed; left: 0; top: 0; min-height: 100%; min-width: 100%; height: auto; width: auto; opacity: 0; z-index: 99; background-color: #fff; filter: alpha(opacity=0); } .select2-hidden-accessible { border: 0 !important; clip: rect(0 0 0 0) !important; height: 1px !important; margin: -1px !important; overflow: hidden !important; padding: 0 !important; position: absolute !important; width: 1px !important; } .select2-container--default .select2-selection--single { background-color: #fff; border: 1px solid #aaa; border-radius: 4px; } .select2-container--default .select2-selection--single .select2-selection__rendered { color: #444; line-height: 28px; } .select2-container--default .select2-selection--single .select2-selection__clear { cursor: pointer; float: right; font-weight: bold; } .select2-container--default .select2-selection--single .select2-selection__placeholder { color: #999; } .select2-container--default .select2-selection--single .select2-selection__arrow { height: 26px; position: absolute; top: 1px; right: 1px; width: 20px; } .select2-container--default .select2-selection--single .select2-selection__arrow b { border-color: #888 transparent transparent transparent; border-style: solid; border-width: 5px 4px 0 4px; height: 0; left: 50%; margin-left: -4px; margin-top: -2px; position: absolute; top: 50%; width: 0; } .select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear { float: left; } .select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow { left: 1px; right: auto; } .select2-container--default.select2-container--disabled .select2-selection--single { background-color: #eee; cursor: default; } .select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear { display: none; } .select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b { border-color: transparent transparent #888 transparent; border-width: 0 4px 5px 4px; } .select2-container--default .select2-selection--multiple { background-color: white; border: 1px solid #aaa; border-radius: 4px; cursor: text; } .select2-container--default .select2-selection--multiple .select2-selection__rendered { box-sizing: border-box; list-style: none; margin: 0; padding: 0 5px; width: 100%; } .select2-container--default .select2-selection--multiple .select2-selection__rendered li { list-style: none; } .select2-container--default .select2-selection--multiple .select2-selection__placeholder { color: #999; margin-top: 5px; float: left; } .select2-container--default .select2-selection--multiple .select2-selection__clear { cursor: pointer; float: right; font-weight: bold; margin-top: 5px; margin-right: 10px; } .select2-container--default .select2-selection--multiple .select2-selection__choice { background-color: #e4e4e4; border: 1px solid #aaa; border-radius: 4px; cursor: default; float: left; margin-right: 5px; margin-top: 5px; padding: 0 5px; } .select2-container--default .select2-selection--multiple .select2-selection__choice__remove { color: #999; cursor: pointer; display: inline-block; font-weight: bold; margin-right: 2px; } .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover { color: #333; } .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline { float: right; } .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice { margin-left: 5px; margin-right: auto; } .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove { margin-left: 2px; margin-right: auto; } .select2-container--default.select2-container--focus .select2-selection--multiple { border: solid black 1px; outline: 0; } .select2-container--default.select2-container--disabled .select2-selection--multiple { background-color: #eee; cursor: default; } .select2-container--default.select2-container--disabled .select2-selection__choice__remove { display: none; } .select2-container--default.select2-container--open.select2-container--above .select2-selection--single, .select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple { border-top-left-radius: 0; border-top-right-radius: 0; } .select2-container--default.select2-container--open.select2-container--below .select2-selection--single, .select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple { border-bottom-left-radius: 0; border-bottom-right-radius: 0; } .select2-container--default .select2-search--dropdown .select2-search__field { border: 1px solid #aaa; } .select2-container--default .select2-search--inline .select2-search__field { background: transparent; border: none; outline: 0; box-shadow: none; -webkit-appearance: textfield; } .select2-container--default .select2-results > .select2-results__options { max-height: 200px; overflow-y: auto; } .select2-container--default .select2-results__option[role=group] { padding: 0; } .select2-container--default .select2-results__option[aria-disabled=true] { color: #999; } .select2-container--default .select2-results__option[aria-selected=true] { background-color: #ddd; } .select2-container--default .select2-results__option .select2-results__option { padding-left: 1em; } .select2-container--default .select2-results__option .select2-results__option .select2-results__group { padding-left: 0; } .select2-container--default .select2-results__option .select2-results__option .select2-results__option { margin-left: -1em; padding-left: 2em; } .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option { margin-left: -2em; padding-left: 3em; } .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { margin-left: -3em; padding-left: 4em; } .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { margin-left: -4em; padding-left: 5em; } .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { margin-left: -5em; padding-left: 6em; } .select2-container--default .select2-results__option--highlighted[aria-selected] { background-color: #5897fb; color: white; } .select2-container--default .select2-results__group { cursor: default; display: block; padding: 6px; } .select2-container--classic .select2-selection--single { background-color: #f7f7f7; border: 1px solid #aaa; border-radius: 4px; outline: 0; background-image: -webkit-linear-gradient(top, white 50%, #eeeeee 100%); background-image: -o-linear-gradient(top, white 50%, #eeeeee 100%); background-image: linear-gradient(to bottom, white 50%, #eeeeee 100%); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); } .select2-container--classic .select2-selection--single:focus { border: 1px solid #5897fb; } .select2-container--classic .select2-selection--single .select2-selection__rendered { color: #444; line-height: 28px; } .select2-container--classic .select2-selection--single .select2-selection__clear { cursor: pointer; float: right; font-weight: bold; margin-right: 10px; } .select2-container--classic .select2-selection--single .select2-selection__placeholder { color: #999; } .select2-container--classic .select2-selection--single .select2-selection__arrow { background-color: #ddd; border: none; border-left: 1px solid #aaa; border-top-right-radius: 4px; border-bottom-right-radius: 4px; height: 26px; position: absolute; top: 1px; right: 1px; width: 20px; background-image: -webkit-linear-gradient(top, #eeeeee 50%, #cccccc 100%); background-image: -o-linear-gradient(top, #eeeeee 50%, #cccccc 100%); background-image: linear-gradient(to bottom, #eeeeee 50%, #cccccc 100%); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0); } .select2-container--classic .select2-selection--single .select2-selection__arrow b { border-color: #888 transparent transparent transparent; border-style: solid; border-width: 5px 4px 0 4px; height: 0; left: 50%; margin-left: -4px; margin-top: -2px; position: absolute; top: 50%; width: 0; } .select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear { float: left; } .select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow { border: none; border-right: 1px solid #aaa; border-radius: 0; border-top-left-radius: 4px; border-bottom-left-radius: 4px; left: 1px; right: auto; } .select2-container--classic.select2-container--open .select2-selection--single { border: 1px solid #5897fb; } .select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow { background: transparent; border: none; } .select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b { border-color: transparent transparent #888 transparent; border-width: 0 4px 5px 4px; } .select2-container--classic.select2-container--open.select2-container--above .select2-selection--single { border-top: none; border-top-left-radius: 0; border-top-right-radius: 0; background-image: -webkit-linear-gradient(top, white 0%, #eeeeee 50%); background-image: -o-linear-gradient(top, white 0%, #eeeeee 50%); background-image: linear-gradient(to bottom, white 0%, #eeeeee 50%); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); } .select2-container--classic.select2-container--open.select2-container--below .select2-selection--single { border-bottom: none; border-bottom-left-radius: 0; border-bottom-right-radius: 0; background-image: -webkit-linear-gradient(top, #eeeeee 50%, white 100%); background-image: -o-linear-gradient(top, #eeeeee 50%, white 100%); background-image: linear-gradient(to bottom, #eeeeee 50%, white 100%); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0); } .select2-container--classic .select2-selection--multiple { background-color: white; border: 1px solid #aaa; border-radius: 4px; cursor: text; outline: 0; } .select2-container--classic .select2-selection--multiple:focus { border: 1px solid #5897fb; } .select2-container--classic .select2-selection--multiple .select2-selection__rendered { list-style: none; margin: 0; padding: 0 5px; } .select2-container--classic .select2-selection--multiple .select2-selection__clear { display: none; } .select2-container--classic .select2-selection--multiple .select2-selection__choice { background-color: #e4e4e4; border: 1px solid #aaa; border-radius: 4px; cursor: default; float: left; margin-right: 5px; margin-top: 5px; padding: 0 5px; } .select2-container--classic .select2-selection--multiple .select2-selection__choice__remove { color: #888; cursor: pointer; display: inline-block; font-weight: bold; margin-right: 2px; } .select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover { color: #555; } .select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice { float: right; } .select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice { margin-left: 5px; margin-right: auto; } .select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove { margin-left: 2px; margin-right: auto; } .select2-container--classic.select2-container--open .select2-selection--multiple { border: 1px solid #5897fb; } .select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple { border-top: none; border-top-left-radius: 0; border-top-right-radius: 0; } .select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple { border-bottom: none; border-bottom-left-radius: 0; border-bottom-right-radius: 0; } .select2-container--classic .select2-search--dropdown .select2-search__field { border: 1px solid #aaa; outline: 0; } .select2-container--classic .select2-search--inline .select2-search__field { outline: 0; box-shadow: none; } .select2-container--classic .select2-dropdown { background-color: white; border: 1px solid transparent; } .select2-container--classic .select2-dropdown--above { border-bottom: none; } .select2-container--classic .select2-dropdown--below { border-top: none; } .select2-container--classic .select2-results > .select2-results__options { max-height: 200px; overflow-y: auto; } .select2-container--classic .select2-results__option[role=group] { padding: 0; } .select2-container--classic .select2-results__option[aria-disabled=true] { color: grey; } .select2-container--classic .select2-results__option--highlighted[aria-selected] { background-color: #3875d7; color: white; } .select2-container--classic .select2-results__group { cursor: default; display: block; padding: 6px; } .select2-container--classic.select2-container--open .select2-dropdown { border-color: #5897fb; } ================================================ FILE: vendor/wpmetabox/meta-box/css/slider.css ================================================ .rwmb-slider-inner { display: flex; align-items: center; justify-content: space-between; } .rwmb-slider-ui { flex: 1; } .rwmb-slider-label { margin-left: 8px; } /* Fix slider handle being visible through jQuery panel */ .ui-slider .ui-slider-handle { z-index: 1; } ================================================ FILE: vendor/wpmetabox/meta-box/css/style-rtl.css ================================================ .rwmb-label, .rwmb-input{ float: right; } label.error{ padding-left: auto; padding-right: 3px; } .rwmb-button.remove-clone { right: auto; left: 0; } ================================================ FILE: vendor/wpmetabox/meta-box/css/style.css ================================================ /* Styles for 'normal' meta boxes -------------------------------------------------------------- */ /* Lower specificity so it field classes are applied */ :where(.rwmb-field) { display: flex; } .rwmb-field:not(:last-of-type) { margin: 0 0 12px; } .rwmb-label { width: 25%; } .rwmb-input { flex: 1; } .rwmb-label > label { font-weight: 600; } .rwmb-required { color: #dc3232; font-weight: bold; margin-left: 3px; } .rwmb-input h4 { margin: 0; } .rwmb-input input:not([size]), .rwmb-input-group, .rwmb-input select, .rwmb-input .select2-container, .rwmb-input textarea:not([cols]) { width: 100%; box-sizing: border-box; } .rwmb-input input[type="checkbox"], .rwmb-input input[type="radio"] { width: 1em; } .rwmb-input input[type="button"] { width: auto; } .rwmb-input input:not([type="checkbox"]):not([type="radio"]), .rwmb-input textarea, .rwmb-input select { max-width: 100%; margin-inline: 0; } .rwmb-textarea { resize: vertical; } /* Clone */ .rwmb-clone { min-height: 24px; margin-bottom: 12px; padding-right: 24px; position: relative; clear: both; background: #fff; } .rwmb-clone > input[type='radio'], .rwmb-clone > input[type='checkbox'] { margin: 6px 0 0 4px; } .rwmb-button.remove-clone { text-decoration: none; color: #ccc; display: inline-block; position: absolute; top: 0; right: 0; width: 20px; height: 20px; transition: color 200ms; } .rwmb-button.remove-clone .dashicons { font-size: 20px; } .rwmb-button.remove-clone:hover { color: #dc3232; } .remove-clone:focus { outline: 0; box-shadow: none; } .rwmb-button.add-clone { margin-top: 4px; } .rwmb-clone-icon { cursor: move; background: url(../img/drag_icon.gif) no-repeat; height: 23px; width: 15px; vertical-align: top; display: inline-block; position: absolute; left: 0; top: 0; } .rwmb-sort-clone { padding-left: 15px; } .rwmb-clone.rwmb-clone-template { display: none; } /* jQuery validation */ p.rwmb-error { color: #dc3232; margin: 4px 0; clear: both; } input.rwmb-error.rwmb-error, textarea.rwmb-error, select.rwmb-error { border-color: #dc3232; background: #ffebe8; } /* Utilities -------------------------------------------------------------- */ .rwmb-sortable-placeholder { background: #fcf8e3; border: 1px solid #faebcc; display: block; } /* Styles for 'side' meta boxes -------------------------------------------------------------- */ #side-sortables .rwmb-field { flex-direction: column; } #side-sortables .rwmb-label { width: 100%; margin-bottom: 4px; } /* Block editor */ .edit-post-meta-boxes-area.is-side .inside:has(.rwmb-meta-box) { padding-inline: 16px; } .edit-post-meta-boxes-area.is-side #poststuff .postbox:has(.rwmb-meta-box) h2.hndle { padding-left: 16px; font-weight: 500; color: #1e1e1e; } /* Mobile style */ @media (max-width: 782px) { .rwmb-field { flex-direction: column; } .rwmb-label { width: 100%; margin-bottom: 4px; } .rwmb-input input[type="radio"], .rwmb-input input[type="checkbox"] { width: 1.5625rem; } } /* Seamless style --------------------------------------------------------------*/ .rwmb-seamless { background: none; border: none; box-shadow: none; } .rwmb-seamless .inside.inside { padding-left: 0; padding-right: 0; } .postbox.rwmb-seamless .hndle, .postbox.rwmb-seamless .handlediv, .postbox.rwmb-seamless .postbox-header { display: none; } .rwmb-seamless .rwmb-clone { background: none; } /* CSS fixes --------------------------------------------------------------*/ /* Fix color picker field is hidden by the post editor at after_title position. https://metabox.io/support/topic/bug-color-picker-field-is-showed-below-the-title-field/ */ .postarea { position: relative; z-index: 0; } .rwmb-hidden-wrapper { display: none; } ================================================ FILE: vendor/wpmetabox/meta-box/css/switch.css ================================================ .rwmb-switch-label { --size: 13px; --padding: 2px; --color: var(--wp-admin-theme-color, #2271b1); cursor: pointer; position: relative; display: inline-block; background-color: #ccc; padding: var(--padding); border-radius: 3px; min-width: calc(var(--size) * 2 + var(--padding) * 2); height: calc(var(--size) + var(--padding) * 2); box-sizing: border-box; } .rwmb-switch.rwmb-switch { display: none; } .rwmb-switch:checked + .rwmb-switch-status .rwmb-switch-slider { background-color: var(--color); box-shadow: 0 0 1px var(--color); } .rwmb-switch:checked + .rwmb-switch-status .rwmb-switch-slider:before { left: calc(100% - var(--size) - var(--padding)); } .rwmb-switch:checked + .rwmb-switch-status .rwmb-switch-off { visibility: hidden; display: none; } .rwmb-switch:not(:checked) + .rwmb-switch-status .rwmb-switch-on { visibility: hidden; display: none; } .rwmb-switch-slider { position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0; z-index: 15; transition: .4s; } .rwmb-switch-slider:before { position: absolute; content: attr(title-before) ""; height: var(--size); width: var(--size); left: var(--padding); bottom: var(--padding); z-index: 99; background-color: white; transition: .4s; border-radius: 2px; } .rwmb-switch-label--square .rwmb-switch-slider { border-radius: 3px; } .rwmb-switch-label--rounded, .rwmb-switch-label--rounded .rwmb-switch-slider { border-radius: 99px; } .rwmb-switch-label--rounded .rwmb-switch-slider:before { border-radius: 50%; } .rwmb-switch-on, .rwmb-switch-off { display: inline-block; float: left; margin: 0 4px; color: #fff; text-transform: uppercase; font-size: 11px; position: relative; z-index: 20; line-height: var(--size); } .rwmb-switch-on { padding-right: calc(var(--size) + var(--padding)); } .rwmb-switch-off { padding-left: calc(var(--size) + var(--padding)); } /* Admin color schemes */ .admin-color-blue .rwmb-switch-label { --color: var(--wp-admin-theme-color, #e1a948); } .admin-color-coffee .rwmb-switch-label { --color: var(--wp-admin-theme-color, #c7a589); } .admin-color-ectoplasm .rwmb-switch-label { --color: var(--wp-admin-theme-color, #a3b745); } .admin-color-light .rwmb-switch-label { --color: var(--wp-admin-theme-color, #04a4cc); } .admin-color-midnight .rwmb-switch-label { --color: var(--wp-admin-theme-color, #e14d43); } .admin-color-modern .rwmb-switch-label { --color: var(--wp-admin-theme-color, #3858e9); } .admin-color-ocean .rwmb-switch-label { --color: var(--wp-admin-theme-color, #9ebaa0); } .admin-color-sunrise .rwmb-switch-label { --color: var(--wp-admin-theme-color, #dd823b); } ================================================ FILE: vendor/wpmetabox/meta-box/css/text-list.css ================================================ .rwmb-text_list-non-cloneable > .rwmb-input, .rwmb-text_list-clone { display: flex; flex-wrap: wrap; } .rwmb-text_list-non-cloneable > .rwmb-input > label, .rwmb-text_list-clone > label { margin: 0 10px 10px 0; flex: 1; } .rwmb-text_list-non-cloneable > .rwmb-input > label:last-child, .rwmb-text_list-clone > label:last-child { margin-right: 0; } .rwmb-text-list-label { font-weight: 600; display: block; margin-bottom: 3px; } ================================================ FILE: vendor/wpmetabox/meta-box/css/upload.css ================================================ .rwmb-upload-area { height: 200px; border: 4px dashed #ddd; display: flex; align-items: center; justify-content: center; text-align: center; } .rwmb-upload-inside h3 { font-size: 20px; line-height: 1.4; font-weight: 400; margin: 0; } .rwmb-upload-inside p { margin: .5em 0; } /* Progress bar */ .rwmb-progress { --height: 16px; margin-bottom: 12px; position: relative; z-index: 1; border-radius: 99px; background-color: #ddd; height: var(--height); line-height: var(--height); color: #fff; font-size: 11px; text-align: center; } .rwmb-progress:before { display: block; content: ""; position: absolute; width: calc(var(--value) * 1%); height: 100%; z-index: -1; background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); background-size: 16px 16px; background-color: var(--wp-admin-theme-color, #2271b1); border-radius: 99px 0 0 99px; } .rwmb-progress--completed:before { border-radius: 99px; animation: progress 1s linear infinite; } @keyframes progress { 0% { background-position: 0 0; } 100% { background-position: 16px 0px; } } ================================================ FILE: vendor/wpmetabox/meta-box/css/video.css ================================================ .rwmb-video-item { position: relative; float: left; margin: 0 12px 12px 0; list-style: none; width: 300px; box-sizing: border-box; } .rwmb-video-item video { width: auto; height: 100%; } .rwmb-video-item .rwmb-media-info { margin-top: 12px; } ================================================ FILE: vendor/wpmetabox/meta-box/css/wysiwyg.css ================================================ .rwmb-field .mceIframeContainer { background: #fff; } .rwmb-wysiwyg-clone { padding-top: 20px; } /* Fix style for Gutenberg */ .block-editor .wp-editor-wrap { box-sizing: content-box; } /* Fix fullscreen mode still shows admin menu */ div.mce-fullscreen { z-index: 999999; } ================================================ FILE: vendor/wpmetabox/meta-box/inc/autoloader.php ================================================ dirs[] = [ 'dir' => trailingslashit( $dir ), 'prefix' => $prefix, 'suffix' => $suffix, ]; } public function register() { spl_autoload_register( [ $this, 'autoload' ] ); } public function autoload( string $class_name ) { foreach ( $this->dirs as $dir ) { if ( ( $dir['prefix'] && ! str_starts_with( $class_name, $dir['prefix'] ) ) || ( $dir['suffix'] && ! str_ends_with( $class_name, $dir['suffix'] ) ) ) { continue; } $file = substr( $class_name, strlen( $dir['prefix'] ) ); if ( $dir['suffix'] && strlen( $file ) > strlen( $dir['suffix'] ) ) { $file = substr( $file, 0, - strlen( $dir['suffix'] ) ); } if ( function_exists( 'mb_strtolower' ) && function_exists( 'mb_detect_encoding' ) ) { $file = mb_strtolower( str_replace( '_', '-', $file ), mb_detect_encoding( $file ) ) . '.php'; } else { $file = strtolower( str_replace( '_', '-', $file ) ) . '.php'; } $file = $dir['dir'] . $file; $this->require( $file ); } } private function require( string $file ) { if ( file_exists( $file ) ) { require_once $file; } } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/clone.php ================================================ $sub_meta ) { $sub_field = $field; $sub_field['field_name'] = $field['field_name'] . "[{$index}]"; $attributes_id = $sub_field['attributes']['id'] ?? $sub_field['id']; if ( $index === 0 && $count > 1 ) { $sub_field['attributes']['id'] = $attributes_id . '_rwmb_template'; } if ( $index === 1 ) { $sub_field['attributes']['id'] = $attributes_id; } if ( $index > 1 ) { if ( isset( $sub_field['address_field'] ) ) { $sub_field['address_field'] = $field['address_field'] . "_{$index}"; } $sub_field['id'] = $field['id'] . "_{$index}"; if ( ! empty( $sub_field['attributes']['id'] ) ) { $sub_field['attributes']['id'] .= "_{$index}"; } } if ( in_array( $sub_field['type'], [ 'file', 'image' ], true ) ) { $sub_field['input_name'] = '_file_' . uniqid(); $sub_field['index_name'] .= "[{$index}]"; } elseif ( $field['multiple'] ) { $sub_field['field_name'] .= '[]'; } // Wrap field HTML in a div with class="rwmb-clone" if needed. $class = "rwmb-clone rwmb-{$field['type']}-clone"; $sort_icon = ''; if ( $field['sort_clone'] ) { $class .= ' rwmb-sort-clone'; $sort_icon = ""; } $class .= $index === 0 ? ' rwmb-clone-template' : ''; $input_html = "
      " . $sort_icon; // Call separated methods for displaying each type of field. $input_html .= RWMB_Field::call( $sub_field, 'html', $sub_meta ); $input_html = RWMB_Field::filter( 'html', $input_html, $sub_field, $sub_meta ); // Remove clone button. $input_html .= self::remove_clone_button( $sub_field ); $input_html .= '
      '; $field_html .= $input_html; } return $field_html; } /** * Set value of meta before saving into database * * @param mixed $new The submitted meta value. * @param mixed $old The existing meta value. * @param int $object_id The object ID. * @param array $field The field parameters. * * @return mixed */ public static function value( $new, $old, $object_id, array $field ) { if ( ! is_array( $new ) ) { $new = []; } if ( in_array( $field['type'], [ 'file', 'image' ], true ) ) { $new = RWMB_File_Field::clone_value( $new, $old, $object_id, $field ); } else { foreach ( $new as $key => $value ) { $old_value = $old[ $key ] ?? null; $value = RWMB_Field::call( $field, 'value', $value, $old_value, $object_id ); $new[ $key ] = RWMB_Field::filter( 'sanitize', $value, $field, $old_value, $object_id ); } } // Remove empty clones. $new = array_filter( $new, 'RWMB_Helpers_Value::is_valid_for_field' ); // Reset indexes. $new = array_values( $new ); return $new; } public static function add_clone_button( array $field ): string { if ( ! $field['clone'] ) { return ''; } $text = RWMB_Field::filter( 'add_clone_button_text', $field['add_button'], $field ); return '' . esc_html( $text ) . ''; } public static function remove_clone_button( array $field ): string { $text = RWMB_Field::filter( 'remove_clone_button_text', '', $field ); return '' . $text . ''; } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/core.php ================================================ add_context_hooks(); } public function plugin_links( array $links ): array { $links[] = '' . esc_html__( 'Docs', 'meta-box' ) . ''; $utc_timezone = new DateTimeZone( 'UTC' ); $now = new DateTime( 'now', $utc_timezone ); $sale_end = new DateTime( '2025-12-02 00:00:00', $utc_timezone ); if ( $now < $sale_end ) { $links[] = '' . esc_html__( 'Black Friday Sale', 'meta-box' ) . ''; } return $links; } public function register_meta_boxes() { $configs = apply_filters( 'rwmb_meta_boxes', [] ); $registry = rwmb_get_registry( 'meta_box' ); foreach ( $configs as $config ) { if ( ! is_array( $config ) || empty( $config ) ) { continue; } $meta_box = $registry->make( $config ); $meta_box->register_fields(); } } /** * WordPress will prevent post data saving if a page template has been selected that does not exist. * This is especially a problem when switching themes, and old page templates are in the post data. * Unset the page template if the page does not exist to allow the post to save. */ public function fix_page_template( WP_Post $post ) { $template = get_post_meta( $post->ID, '_wp_page_template', true ); $page_templates = wp_get_theme()->get_page_templates(); // If the template doesn't exists, remove the data to allow WordPress to save. if ( ! isset( $page_templates[ $template ] ) ) { delete_post_meta( $post->ID, '_wp_page_template' ); } } /** * Get registered meta boxes via a filter. * @deprecated No longer used. Keep for backward-compatibility with extensions. */ public static function get_meta_boxes(): array { $meta_boxes = rwmb_get_registry( 'meta_box' )->all(); return wp_list_pluck( $meta_boxes, 'meta_box' ); } public function add_context_hooks() { $hooks = [ 'edit_form_top', 'edit_form_after_title', 'edit_form_after_editor', 'edit_form_before_permalink', ]; foreach ( $hooks as $hook ) { add_action( $hook, [ $this, 'render_meta_boxes_for_context' ] ); } } public function render_meta_boxes_for_context( $post ) { $hook = current_filter(); $context = 'edit_form_top' === $hook ? 'form_top' : substr( $hook, 10 ); do_meta_boxes( null, $context, $post ); } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/field-registry.php ================================================ data[ $object_type ] ) ) { $this->data[ $object_type ] = []; } if ( empty( $this->data[ $object_type ][ $type ] ) ) { $this->data[ $object_type ][ $type ] = []; } $this->data[ $object_type ][ $type ][ $field['id'] ] = $field; do_action( 'rwmb_field_registered', $field, $type, $object_type ); } /** * Retrieve a field. * * @param string $id A meta box instance id. * @param string $type Post type|Taxonomy|'user'|Setting page which the field belongs to. * @param string $object_type Object type which the field belongs to. * * @return bool|array False or field configuration. */ public function get( $id, $type, $object_type = 'post' ) { return $this->data[ $object_type ][ $type ][ $id ] ?? false; } /** * Retrieve fields by object type. * * @param string $object_type Object type which the field belongs to. * * @return array List of fields. */ public function get_by_object_type( string $object_type = 'post' ): array { return $this->data[ $object_type ] ?? []; } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/field.php ================================================ ' . $html . ''; $outer_html .= $field['after']; $outer_html = self::filter( 'outer_html', $outer_html, $field, $meta ); echo $outer_html; // phpcs:ignore WordPress.Security.EscapeOutput } /** * Get field HTML. * * @param mixed $meta Meta value. * @param array $field Field parameters. * * @return string */ public static function html( $meta, $field ) { return ''; } protected static function begin_html( array $field ): string { $id = $field['attributes']['id'] ?? $field['id']; $required = $field['required'] || ! empty( $field['attributes']['required'] ); $required = $required ? '*' : ''; $label = $field['name'] ? sprintf( // Translators: %1$s - field ID, %2$s - field label, %3$s - required asterisk, %4$s - label description. '
      %4$s
      ', esc_attr( $id ), $field['name'], $required, static::label_description( $field ) ) : ''; $data_max_clone = is_numeric( $field['max_clone'] ) && $field['max_clone'] > 0 ? ' data-max-clone=' . $field['max_clone'] : ''; $data_min_clone = is_numeric( $field['min_clone'] ) && $field['min_clone'] > 0 ? ' data-min-clone=' . $field['min_clone'] : ''; $data_empty_start = $field['clone_empty_start'] ? ' data-clone-empty-start="1"' : ' data-clone-empty-start="0"'; $input_open = sprintf( '
      ', $data_min_clone, $data_max_clone, $data_empty_start ); return $label . $input_open; } protected static function end_html( array $field ): string { return RWMB_Clone::add_clone_button( $field ) . static::input_description( $field ) . '
      '; } protected static function label_description( array $field ): string { $id = $field['id'] ? ' id="' . esc_attr( $field['id'] ) . '-label-description"' : ''; return $field['label_description'] ? "{$field['label_description']}

      " : ''; } protected static function input_description( array $field ): string { $id = $field['id'] ? ' id="' . esc_attr( $field['id'] ) . '-description"' : ''; return $field['desc'] ? "{$field['desc']}

      " : ''; } /** * Get raw meta value. * * @param int $object_id Object ID. * @param array $field Field parameters. * @param array $args Arguments of {@see rwmb_meta()} helper. * * @return mixed */ public static function raw_meta( $object_id, $field, $args = [] ) { if ( empty( $field['id'] ) ) { return ''; } if ( isset( $field['storage'] ) ) { $storage = $field['storage']; } elseif ( isset( $args['object_type'] ) ) { $storage = rwmb_get_storage( $args['object_type'] ); } else { $storage = rwmb_get_storage( 'post' ); } if ( ! isset( $args['single'] ) ) { $args['single'] = $field['clone'] || ! $field['multiple']; } if ( $field['clone'] && $field['clone_as_multiple'] ) { $args['single'] = false; } $value = $storage->get( $object_id, $field['id'], $args ); $value = self::filter( 'raw_meta', $value, $field, $object_id, $args ); return $value; } /** * Get meta value. * * @param int $post_id Post ID. * @param bool $saved Whether the meta box is saved at least once. * @param array $field Field parameters. * * @return mixed */ public static function meta( $post_id, $saved, $field ) { /** * For special fields like 'divider', 'heading' which don't have ID, just return empty string * to prevent notice error when displaying fields. */ if ( empty( $field['id'] ) ) { return ''; } // Get raw meta. $raw_meta = self::call( $field, 'raw_meta', $post_id ); $single_std = self::call( 'get_single_std', $field ); $std = self::call( 'get_std', $field ); $saved = $saved && $field['save_field']; // Use $field['std'] only when the meta box hasn't been saved (i.e. the first time we run). $meta = $saved ? $raw_meta : $std; if ( ! $field['clone'] ) { return $meta; } // When a field is cloneable, it should always return an array. $meta = is_array( $raw_meta ) ? $raw_meta : []; if ( empty( $meta ) ) { $empty_meta = empty( $raw_meta ) ? [ null ] : $raw_meta; $std = $field['clone_empty_start'] ? [] : $std; $empty_std = $field['clone_empty_start'] ? [] : Arr::to_depth( $empty_meta, Arr::depth( $std ) ); $meta = $saved ? $empty_std : $std; } // 2. Always prepend a template array_unshift( $meta, $single_std ); return $meta; } /** * Process the submitted value before saving into the database. * * @param mixed $value The submitted value. * @param int $object_id The object ID. * @param array $field The field settings. */ public static function process_value( $value, $object_id, array $field ) { $old_value = self::call( $field, 'raw_meta', $object_id ); // Allow field class change the value. if ( $field['clone'] ) { $value = RWMB_Clone::value( $value, $old_value, $object_id, $field ); } else { $value = self::call( $field, 'value', $value, $old_value, $object_id ); $value = self::filter( 'sanitize', $value, $field, $old_value, $object_id ); } $value = self::filter( 'value', $value, $field, $old_value, $object_id ); return $value; } /** * Set value of meta before saving into database. * * @param mixed $new The submitted meta value. * @param mixed $old The existing meta value. * @param int $post_id The post ID. * @param array $field The field parameters. * * @return mixed */ public static function value( $new, $old, $post_id, $field ) { return $new; } /** * Save meta value. * * @param mixed $new The submitted meta value. * @param mixed $old The existing meta value. * @param int $post_id The post ID. * @param array $field The field parameters. */ public static function save( $new, $old, $post_id, $field ) { if ( empty( $field['id'] ) || ! $field['save_field'] ) { return; } $name = $field['id']; $storage = $field['storage']; // Remove post meta if it's empty. if ( ! RWMB_Helpers_Value::is_valid_for_field( $new ) ) { $storage->delete( $post_id, $name ); return; } // If field is cloneable AND not force to save as multiple rows, value is saved as a single row in the database. if ( $field['clone'] && ! $field['clone_as_multiple'] ) { $storage->update( $post_id, $name, $new ); return; } // Save cloned fields as multiple values instead serialized array. if ( ( $field['clone'] && $field['clone_as_multiple'] ) || $field['multiple'] ) { $storage->delete( $post_id, $name ); $new = (array) $new; foreach ( $new as $new_value ) { $storage->add( $post_id, $name, $new_value, false ); } return; } // Default: just update post meta. $storage->update( $post_id, $name, $new ); } /** * Normalize parameters for field. * * @param array|string $field Field settings. * @return array */ public static function normalize( $field ) { // Quick define text fields with "name" attribute only. if ( is_string( $field ) ) { $field = [ 'name' => $field, 'id' => sanitize_key( $field ), ]; } $field = wp_parse_args( $field, [ 'id' => '', 'name' => '', 'type' => 'text', 'label_description' => '', 'multiple' => false, 'std' => '', 'desc' => '', 'format' => '', 'before' => '', 'after' => '', 'field_name' => $field['id'] ?? '', 'placeholder' => '', 'save_field' => true, 'clone' => false, 'min_clone' => 0, 'max_clone' => 0, 'sort_clone' => false, 'add_button' => __( '+ Add more', 'meta-box' ), 'clone_default' => false, 'clone_as_multiple' => false, 'clone_empty_start' => false, 'class' => '', 'disabled' => false, 'required' => false, 'autofocus' => false, 'attributes' => [], 'sanitize_callback' => null, ] ); // Store the original ID to run correct filters for the cloneable field. if ( $field['clone'] ) { $field['_original_id'] = $field['id']; } if ( $field['clone_default'] ) { $field['attributes'] = wp_parse_args( $field['attributes'], [ 'data-default' => $field['std'], 'data-clone-default' => 'true', ] ); } return $field; } /** * Get the attributes for a field. * * @param array $field Field parameters. * @param mixed $value Meta value. * * @return array */ public static function get_attributes( $field, $value = null ) { $attributes = wp_parse_args( $field['attributes'], [ 'disabled' => $field['disabled'], 'autofocus' => $field['autofocus'], 'required' => $field['required'], 'id' => $field['id'], 'class' => '', 'name' => $field['field_name'], ] ); $attributes['class'] = trim( implode( ' ', array_merge( [ "rwmb-{$field['type']}" ], (array) $attributes['class'] ) ) ); $id = $attributes['id'] ?: $field['id']; if ( $field['name'] || $field['label_description'] ) { $attributes['aria-labelledby'] = "$id-label"; } if ( $field['desc'] ) { $attributes['aria-describedby'] = "$id-description"; } return $attributes; } public static function render_attributes( array $attributes ): string { $output = ''; $attributes = array_filter( $attributes, 'RWMB_Helpers_Value::is_valid_for_attribute' ); foreach ( $attributes as $key => $value ) { if ( is_array( $value ) ) { $value = wp_json_encode( $value ); } $output .= sprintf( ' %s="%s"', $key, esc_attr( $value ) ); } return $output; } /** * Get the field value. * The difference between this function and 'meta' function is 'meta' function always returns the escaped value * of the field saved in the database, while this function returns more meaningful value of the field, for ex.: * for file/image: return array of file/image information instead of file/image IDs. * * Each field can extend this function and add more data to the returned value. * See specific field classes for details. * * @param array $field Field parameters. * @param array $args Additional arguments. Rarely used. See specific fields for details. * @param ?int $post_id Post ID. * * @return mixed Field value */ public static function get_value( $field, $args = [], $post_id = null ) { // Some fields does not have ID like heading, custom HTML, etc. if ( empty( $field['id'] ) ) { return ''; } if ( ! $post_id ) { $post_id = get_the_ID(); } // Get raw meta value in the database, no escape. $value = self::call( $field, 'raw_meta', $post_id, $args ); // Make sure meta value is an array for cloneable and multiple fields. if ( $field['clone'] || $field['multiple'] ) { $value = is_array( $value ) && ! empty( $value ) ? $value : []; } return $value; } /** * Output the field value. * Depends on field value and field types, each field can extend this method to output its value in its own way * See specific field classes for details. * * Note: we don't echo the field value directly. We return the output HTML of field, which will be used in * rwmb_the_field function later. * * @use self::get_value() * @see rwmb_the_value() * * @param array $field Field parameters. * @param array $args Additional arguments. Rarely used. See specific fields for details. * @param int|null $post_id Post ID. null for current post. Optional. * * @return string HTML output of the field */ public static function the_value( $field, $args = [], $post_id = null ) { $value = self::call( 'get_value', $field, $args, $post_id ); if ( false === $value ) { return ''; } return self::call( 'format_value', $field, $value, $args, $post_id ); } /** * Format value for the helper functions. * * @param array $field Field parameters. * @param string|array $value The field meta value. * @param array $args Additional arguments. Rarely used. See specific fields for details. * @param int|null $post_id Post ID. null for current post. Optional. * * @return string */ public static function format_value( $field, $value, $args, $post_id ) { if ( ! $field['clone'] ) { return self::call( 'format_clone_value', $field, $value, $args, $post_id ); } $output = '
        '; foreach ( $value as $clone ) { $output .= '
      • ' . self::call( 'format_clone_value', $field, $clone, $args, $post_id ) . '
      • '; } $output .= '
      '; return $output; } /** * Format value for a clone. * * @param array $field Field parameters. * @param string|array $value The field meta value. * @param array $args Additional arguments. Rarely used. See specific fields for details. * @param int|null $post_id Post ID. null for current post. Optional. * * @return string */ public static function format_clone_value( $field, $value, $args, $post_id ) { if ( ! $field['multiple'] ) { return self::call( 'format_single_value', $field, $value, $args, $post_id ); } $output = '
        '; foreach ( $value as $single ) { $output .= '
      • ' . self::call( 'format_single_value', $field, $single, $args, $post_id ) . '
      • '; } $output .= '
      '; return $output; } /** * Format a single value for the helper functions. Sub-fields should overwrite this method if necessary. * * @param array $field Field parameters. * @param string $value The value. * @param array $args Additional arguments. Rarely used. See specific fields for details. * @param int|null $post_id Post ID. null for current post. Optional. * * @return string */ public static function format_single_value( $field, $value, $args, $post_id ) { return $value; } /** * Call a method of a field. */ public static function call() { $args = func_get_args(); $check = reset( $args ); // Params: method name, field, other params. if ( is_string( $check ) ) { $method = array_shift( $args ); $field = reset( $args ); // Keep field as 1st param. } else { // Params: field, method name, other params. $field = array_shift( $args ); $method = array_shift( $args ); if ( 'raw_meta' === $method ) { // Add field param after object id. array_splice( $args, 1, 0, [ $field ] ); } else { $args[] = $field; // Add field as last param. } } $class = RWMB_Helpers_Field::get_class( $field ); if ( method_exists( $class, $method ) ) { return call_user_func_array( [ $class, $method ], $args ); } _deprecated_function( esc_html( "$class::$method" ), '5.4.8' ); } /** * Apply various filters based on field type, id. * Filters: * - rwmb_{$name} * - rwmb_{$field['type']}_{$name} * - rwmb_{$field['id']}_{$name} * * @return mixed */ public static function filter() { $args = func_get_args(); // 3 first params must be: filter name, value, field. Other params will be used for filters. $name = array_shift( $args ); $value = array_shift( $args ); $field = array_shift( $args ); // List of filters. $filters = [ 'rwmb_' . $name, 'rwmb_' . $field['type'] . '_' . $name, ]; if ( $field['id'] ) { $field_id = $field['clone'] ? $field['_original_id'] : $field['id']; $filters[] = 'rwmb_' . $field_id . '_' . $name; } // Filter params: value, field, other params. Note: value is changed after each run. array_unshift( $args, $field ); foreach ( $filters as $filter ) { $filter_args = $args; array_unshift( $filter_args, $value ); $value = apply_filters_ref_array( $filter, $filter_args ); } return $value; } protected static function get_std( array $field ) { $depth = 0; if ( $field['multiple'] ) { ++$depth; } if ( $field['clone'] ) { ++$depth; } return Arr::to_depth( $field['std'], $depth ); } protected static function get_single_std( array $field ) { $depth = 0; if ( $field['multiple'] ) { ++$depth; } return Arr::to_depth( $field['std'], $depth ); } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/autocomplete.php ================================================ __( 'Delete', 'meta-box' ), ] ); } /** * Get field HTML. * * @param mixed $meta Meta value. * @param array $field Field parameters. * @return string */ public static function html( $meta, $field ) { if ( ! is_array( $meta ) ) { $meta = [ $meta ]; } // Filter out empty values in case the array started with empty or 0 values $meta = array_filter( $meta, function ( $index ) use ( $meta ) { return $meta[ $index ] !== ''; }, ARRAY_FILTER_USE_KEY ); $field = apply_filters( 'rwmb_autocomplete_field', $field, $meta ); $options = $field['options']; if ( is_array( $field['options'] ) ) { $options = []; foreach ( $field['options'] as $value => $label ) { $options[] = [ 'value' => (string) $value, 'label' => $label, ]; } $options = wp_json_encode( $options ); } // Input field that triggers autocomplete. // This field doesn't store field values, so it doesn't have "name" attribute. // The value(s) of the field is store in hidden input(s). See below. $html = sprintf( ' ', esc_attr( $field['field_name'] ), esc_attr( $options ) ); $html .= '
      '; // Each value is displayed with label and 'Delete' option. // The hidden input has to have ".rwmb-*" class to make clone work. $tpl = '
      %s
      %s
      '; if ( is_array( $field['options'] ) ) { foreach ( $field['options'] as $value => $label ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict if ( ! in_array( $value, $meta ) ) { continue; } $html .= sprintf( $tpl, esc_html( $label ), esc_html__( 'Delete', 'meta-box' ), esc_attr( $field['field_name'] ), esc_attr( $value ) ); } } else { $meta = array_filter( $meta ); foreach ( $meta as $value ) { $label = apply_filters( 'rwmb_autocomplete_result_label', $value, $field ); $html .= sprintf( $tpl, esc_html( $label ), esc_html__( 'Delete', 'meta-box' ), esc_attr( $field['field_name'] ), esc_attr( $value ) ); } } $html .= '
      '; // .rwmb-autocomplete-results. return $html; } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/background.php ================================================ 'color', 'id' => "{$field['id']}_color", 'field_name' => "{$field['field_name']}[color]", 'alpha_channel' => true, ] ); RWMB_Color_Field::admin_enqueue_scripts( $color ); RWMB_File_Input_Field::admin_enqueue_scripts(); } /** * Get field HTML. * * @param mixed $meta Meta value. * @param array $field Field settings. * * @return string */ public static function html( $meta, $field ) { $meta = wp_parse_args( $meta, [ 'color' => '', 'image' => '', 'repeat' => '', 'attachment' => '', 'position' => '', 'size' => '', ] ); $output = '
      '; // Color. $color = RWMB_Color_Field::normalize( [ 'type' => 'color', 'id' => "{$field['id']}_color", 'field_name' => "{$field['field_name']}[color]", 'alpha_channel' => true, ] ); $output .= RWMB_Color_Field::html( $meta['color'], $color ); $output .= '
      '; $output .= '
      '; // Image. $image = RWMB_File_Input_Field::normalize( [ 'type' => 'file_input', 'id' => "{$field['id']}_image", 'field_name' => "{$field['field_name']}[image]", 'placeholder' => __( 'Background Image', 'meta-box' ), ] ); $output .= RWMB_File_Input_Field::html( $meta['image'], $image ); $output .= '
      '; $output .= '
      '; // Repeat. $repeat = RWMB_Select_Field::normalize( [ 'type' => 'select', 'id' => "{$field['id']}_repeat", 'field_name' => "{$field['field_name']}[repeat]", 'placeholder' => esc_html__( '-- Repeat --', 'meta-box' ), 'options' => [ 'no-repeat' => esc_html__( 'No Repeat', 'meta-box' ), 'repeat' => esc_html__( 'Repeat All', 'meta-box' ), 'repeat-x' => esc_html__( 'Repeat Horizontally', 'meta-box' ), 'repeat-y' => esc_html__( 'Repeat Vertically', 'meta-box' ), 'inherit' => esc_html__( 'Inherit', 'meta-box' ), ], ] ); $output .= RWMB_Select_Field::html( $meta['repeat'], $repeat ); // Position. $position = RWMB_Select_Field::normalize( [ 'type' => 'select', 'id' => "{$field['id']}_position", 'field_name' => "{$field['field_name']}[position]", 'placeholder' => esc_html__( '-- Position --', 'meta-box' ), 'options' => [ 'top left' => esc_html__( 'Top Left', 'meta-box' ), 'top center' => esc_html__( 'Top Center', 'meta-box' ), 'top right' => esc_html__( 'Top Right', 'meta-box' ), 'center left' => esc_html__( 'Center Left', 'meta-box' ), 'center center' => esc_html__( 'Center Center', 'meta-box' ), 'center right' => esc_html__( 'Center Right', 'meta-box' ), 'bottom left' => esc_html__( 'Bottom Left', 'meta-box' ), 'bottom center' => esc_html__( 'Bottom Center', 'meta-box' ), 'bottom right' => esc_html__( 'Bottom Right', 'meta-box' ), ], ] ); $output .= RWMB_Select_Field::html( $meta['position'], $position ); // Attachment. $attachment = RWMB_Select_Field::normalize( [ 'type' => 'select', 'id' => "{$field['id']}_attachment", 'field_name' => "{$field['field_name']}[attachment]", 'placeholder' => esc_html__( '-- Attachment --', 'meta-box' ), 'options' => [ 'fixed' => esc_html__( 'Fixed', 'meta-box' ), 'scroll' => esc_html__( 'Scroll', 'meta-box' ), 'inherit' => esc_html__( 'Inherit', 'meta-box' ), ], ] ); $output .= RWMB_Select_Field::html( $meta['attachment'], $attachment ); // Size. $size = RWMB_Select_Field::normalize( [ 'type' => 'select', 'id' => "{$field['id']}_size", 'field_name' => "{$field['field_name']}[size]", 'placeholder' => esc_html__( '-- Size --', 'meta-box' ), 'options' => [ 'inherit' => esc_html__( 'Inherit', 'meta-box' ), 'cover' => esc_html__( 'Cover', 'meta-box' ), 'contain' => esc_html__( 'Contain', 'meta-box' ), ], ] ); $output .= RWMB_Select_Field::html( $meta['size'], $size ); $output .= '
      '; return $output; } /** * Format a single value for the helper functions. Sub-fields should overwrite this method if necessary. * * @param array $field Field parameters. * @param array $value The value. * @param array $args Additional arguments. Rarely used. See specific fields for details. * @param int|null $post_id Post ID. null for current post. Optional. * * @return string */ public static function format_single_value( $field, $value, $args, $post_id ) { if ( empty( $value ) ) { return ''; } $output = ''; $value = array_filter( $value ); foreach ( $value as $key => $subvalue ) { $subvalue = 'image' === $key ? 'url(' . esc_url( $subvalue ) . ')' : $subvalue; $output .= 'background-' . $key . ': ' . $subvalue . ';'; } return $output; } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/button-group.php ================================================ ', $field['inline'] ? 'rwmb-inline' : '' ); $output .= $walker->walk( $options, -1 ); $output .= ''; return $output; } /** * Normalize parameters for field. * * @param array $field Field parameters. * * @return array */ public static function normalize( $field ) { $field = parent::normalize( $field ); $field = wp_parse_args( $field, [ 'inline' => true, ] ); $field = $field['multiple'] ? RWMB_Multiple_Values_Field::normalize( $field ) : $field; $field = RWMB_Input_Field::normalize( $field ); $field['flatten'] = true; return $field; } /** * Get the attributes for a field. * * @param array $field Field parameters. * @param mixed $value Meta value. * * @return array */ public static function get_attributes( $field, $value = null ) { $attributes = RWMB_Input_Field::get_attributes( $field, $value ); $attributes['id'] = false; $attributes['type'] = $field['multiple'] ? 'checkbox' : 'radio'; $attributes['value'] = $value; return $attributes; } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/button.php ================================================ %s', self::render_attributes( $attributes ), $field['std'] ); } /** * Normalize parameters for field. * * @param array $field The field parameters. * @return array */ public static function normalize( $field ) { $field = wp_parse_args( $field, [ 'std' => __( 'Click me', 'meta-box' ), ] ); $field = parent::normalize( $field ); return $field; } /** * Get the attributes for a field. * * @param array $field The field parameters. * @param mixed $value The attribute value. * @return array */ public static function get_attributes( $field, $value = null ) { $attributes = parent::get_attributes( $field, $value ); $attributes = wp_parse_args( $attributes, [ 'type' => $field['type'], ] ); $attributes['class'] .= ' button hide-if-no-js'; return $attributes; } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/checkbox-list.php ================================================ ', self::render_attributes( $attributes ), checked( ! empty( $meta ), 1, false ) ); if ( $field['desc'] ) { $output = ""; } return $output; } protected static function input_description( array $field ): string { return ''; } /** * Format a single value for the helper functions. Sub-fields should overwrite this method if necessary. * * @param array $field Field parameters. * @param string $value The value. * @param array $args Additional arguments. Rarely used. See specific fields for details. * @param int|null $post_id Post ID. null for current post. Optional. * * @return string */ public static function format_single_value( $field, $value, $args, $post_id ) { return $value ? __( 'Yes', 'meta-box' ) : __( 'No', 'meta-box' ); } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/choice.php ================================================ true, 'options' => [], ] ); // Use callback: function_name format from Meta Box Builder. if ( isset( $field['_callback'] ) && is_callable( $field['_callback'] ) ) { $field['options'] = call_user_func( $field['_callback'] ); } return $field; } public static function transform_options( $options ): array { $transformed = []; $options = (array) $options; foreach ( $options as $value => $label ) { $option = is_array( $label ) ? $label : [ 'label' => (string) $label, 'value' => (string) $value, ]; if ( isset( $option['label'] ) && isset( $option['value'] ) ) { $transformed[ $option['value'] ] = (object) $option; } } return $transformed; } /** * Format a single value for the helper functions. Sub-fields should overwrite this method if necessary. * * @param array $field Field parameters. * @param string $value The value. * @param array $args Additional arguments. Rarely used. See specific fields for details. * @param int|null $post_id Post ID. null for current post. Optional. * * @return string */ public static function format_single_value( $field, $value, $args, $post_id ) { $options = self::transform_options( $field['options'] ); return isset( $options[ $value ] ) ? $options[ $value ]->label : ''; } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/color.php ================================================ false, 'js_options' => [], ] ); $field['js_options'] = wp_parse_args( $field['js_options'], [ 'defaultColor' => false, 'hide' => true, 'palettes' => true, ] ); $field = parent::normalize( $field ); return $field; } /** * Get the attributes for a field. * * @param array $field Field parameters. * @param mixed $value Meta value. * * @return array */ public static function get_attributes( $field, $value = null ) { $attributes = parent::get_attributes( $field, $value ); $attributes = wp_parse_args( $attributes, [ 'data-options' => wp_json_encode( $field['js_options'] ), ] ); $attributes['type'] = 'text'; if ( $field['alpha_channel'] ) { $attributes['data-alpha-enabled'] = 'true'; $attributes['data-alpha-color-type'] = 'hex'; } return $attributes; } /** * Format a single value for the helper functions. Sub-fields should overwrite this method if necessary. * * @param array $field Field parameters. * @param string $value The value. * @param array $args Additional arguments. Rarely used. See specific fields for details. * @param int|null $post_id Post ID. null for current post. Optional. * * @return string */ public static function format_single_value( $field, $value, $args, $post_id ) { return sprintf( "", $value ); } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/custom-html.php ================================================ '', 'oo' => '', '@' => '', "''" => "'". * * @var array */ protected static $date_formats = [ 'd' => 'j', 'dd' => 'd', 'oo' => 'z', 'D' => 'D', 'DD' => 'l', 'm' => 'n', 'mm' => 'm', 'M' => 'M', 'MM' => 'F', 'y' => 'y', 'yy' => 'Y', 'o' => 'z', ]; /** * Translate time format from jQuery UI time picker to PHP date(). * It's used to store timestamp value of the field. * Missing: 't' => '', T' => '', 'm' => '', 's' => ''. * * @var array */ protected static $time_formats = [ 'H' => 'G', 'HH' => 'H', 'h' => 'g', 'hh' => 'h', 'mm' => 'i', 'ss' => 's', 'l' => 'u', 'tt' => 'a', 'TT' => 'A', ]; public static function register_assets() { // jQueryUI base theme: https://github.com/jquery/jquery-ui/tree/1.13.2/themes/base $url = RWMB_CSS_URL . 'jqueryui'; wp_register_style( 'jquery-ui-core', "$url/core.css", [], '1.13.2' ); wp_style_add_data( 'jquery-ui-core', 'path', RWMB_CSS_DIR . 'jqueryui/core.css' ); wp_register_style( 'jquery-ui-theme', "$url/theme.css", [], '1.13.2' ); wp_style_add_data( 'jquery-ui-theme', 'path', RWMB_CSS_DIR . 'jqueryui/theme.css' ); wp_register_style( 'jquery-ui-datepicker', "$url/datepicker.css", [ 'jquery-ui-core', 'jquery-ui-theme' ], '1.13.2' ); wp_style_add_data( 'jquery-ui-datepicker', 'path', RWMB_CSS_DIR . 'jqueryui/datepicker.css' ); wp_register_style( 'jquery-ui-slider', "$url/slider.css", [ 'jquery-ui-core', 'jquery-ui-theme' ], '1.13.2' ); wp_style_add_data( 'jquery-ui-slider', 'path', RWMB_CSS_DIR . 'jqueryui/slider.css' ); // jQueryUI timepicker addon: https://github.com/trentrichardson/jQuery-Timepicker-Addon wp_register_style( 'jquery-ui-timepicker', "$url/jquery-ui-timepicker-addon.min.css", [ 'rwmb-date', 'jquery-ui-slider' ], '1.6.3' ); wp_style_add_data( 'jquery-ui-timepicker', 'path', RWMB_CSS_DIR . 'jqueryui/jquery-ui-timepicker-addon.min.css' ); wp_register_style( 'rwmb-date', RWMB_CSS_URL . 'date.css', [ 'jquery-ui-datepicker' ], RWMB_VER ); wp_style_add_data( 'rwmb-date', 'path', RWMB_CSS_DIR . 'date.css' ); // Scripts. $url = RWMB_JS_URL . 'jqueryui'; wp_register_script( 'jquery-ui-timepicker', "$url/jquery-ui-timepicker-addon.min.js", [ 'jquery-ui-datepicker', 'jquery-ui-slider' ], '1.6.3', true ); wp_register_script( 'jquery-ui-timepicker-slider', "$url/jquery-ui-sliderAccess.js", [ 'jquery-ui-datepicker', 'jquery-ui-slider' ], '0.3', true ); wp_register_script( 'jquery-ui-timepicker-i18n', "$url/jquery-ui-timepicker-addon-i18n.min.js", [ 'jquery-ui-timepicker' ], '1.6.3', true ); wp_register_script( 'rwmb-datetime', RWMB_JS_URL . 'datetime.js', [ 'jquery-ui-datepicker', 'jquery-ui-timepicker-i18n', 'underscore', 'jquery-ui-button', 'jquery-ui-timepicker-slider', 'rwmb' ], RWMB_VER, true ); wp_register_script( 'rwmb-date', RWMB_JS_URL . 'date.js', [ 'jquery-ui-datepicker', 'underscore', 'rwmb' ], RWMB_VER, true ); wp_register_script( 'rwmb-time', RWMB_JS_URL . 'time.js', [ 'jquery-ui-timepicker-i18n', 'jquery-ui-button', 'jquery-ui-timepicker-slider', 'rwmb' ], RWMB_VER, true ); $handles = [ 'datetime', 'time' ]; $locale = str_replace( '_', '-', get_user_locale() ); $locale_short = substr( $locale, 0, 2 ); $data = [ 'locale' => $locale, 'localeShort' => $locale_short, ]; foreach ( $handles as $handle ) { RWMB_Helpers_Field::localize_script_once( "rwmb-$handle", 'RWMB_' . ucfirst( $handle ), $data ); } } /** * Enqueue scripts and styles. */ public static function admin_enqueue_scripts() { self::register_assets(); wp_enqueue_style( 'jquery-ui-timepicker' ); wp_enqueue_script( 'rwmb-datetime' ); } /** * Get field HTML. * * @param mixed $meta The field meta value. * @param array $field The field parameters. * * @return string */ public static function html( $meta, $field ) { $output = ''; if ( $field['timestamp'] ) { $name = $field['field_name']; $field = wp_parse_args( [ 'field_name' => $name . '[formatted]' ], $field ); $timestamp = $meta['timestamp'] ?? 0; $output .= sprintf( '', esc_attr( $name . '[timestamp]' ), (int) $timestamp ); $meta = $meta['formatted'] ?? ''; } $output .= parent::html( $meta, $field ); if ( $field['inline'] ) { $output .= '
      '; } return $output; } /** * Calculates the timestamp from the datetime string and returns it if $field['timestamp'] is set or the datetime string if not. * * @param mixed $new The submitted meta value. * @param mixed $old The existing meta value. * @param int $post_id The post ID. * @param array $field The field parameters. * * @return string|int */ public static function value( $new, $old, $post_id, $field ) { if ( $field['timestamp'] ) { if ( is_array( $new ) ) { return $new['timestamp']; } if ( ! is_numeric( $new ) ) { return strtotime( $new ); } return $new; } if ( $field['save_format'] ) { // Fix 'c' and 'r' formats not containing WordPress timezone. $timezone = in_array( $field['save_format'], [ 'c', 'r' ], true ) ? wp_timezone() : null; $date = DateTimeImmutable::createFromFormat( $field['php_format'], $new, $timezone ); return $date === false ? $new : $date->format( $field['save_format'] ); } return $new; } /** * Get meta value. * * @param int $post_id The post ID. * @param bool $saved Whether the meta box is saved at least once. * @param array $field The field parameters. * * @return mixed */ public static function meta( $post_id, $saved, $field ) { $meta = parent::meta( $post_id, $saved, $field ); if ( $field['timestamp'] ) { return Arr::map( $meta, __CLASS__ . '::from_timestamp', $field ); } if ( $field['save_format'] && $meta ) { return Arr::map( $meta, __CLASS__ . '::from_save_format', $field ); } return $meta; } /** * Format meta value if set 'timestamp'. */ public static function from_timestamp( $meta, array $field ): array { return [ 'timestamp' => $meta ?: null, 'formatted' => $meta ? gmdate( $field['php_format'], intval( $meta ) ) : '', ]; } /** * Transform meta value from save format to the JS format. */ public static function from_save_format( $meta, array $field ): string { $formats = array_merge( [ $field['save_format'] => $field['save_format'], ], [ 'c' => DateTimeInterface::ATOM, 'r' => DateTimeInterface::RFC2822, ] ); $format = $formats[ $field['save_format'] ]; $date = DateTimeImmutable::createFromFormat( $format, (string) $meta ); return false === $date ? (string) $meta : $date->format( $field['php_format'] ); } /** * Normalize parameters for field. * * @param array $field The field parameters. * @return array */ public static function normalize( $field ) { $field = wp_parse_args( $field, [ 'timestamp' => false, 'inline' => false, 'js_options' => [], 'save_format' => '', 'autocomplete' => 'off', ] ); // Deprecate 'format', but keep it for backward compatible. // Use 'js_options' instead. $field['js_options'] = wp_parse_args( $field['js_options'], [ 'timeFormat' => 'HH:mm', 'separator' => ' ', 'dateFormat' => $field['format'] ?? 'yy-mm-dd', 'showButtonPanel' => true, 'changeYear' => true, 'yearRange' => '-100:+100', 'changeMonth' => true, 'oneLine' => true, 'stepMinute' => 5, 'controlType' => 'select', // select or slider 'addSliderAccess' => true, 'sliderAccessArgs' => [ 'touchonly' => true, // To show sliderAccess only on touch devices ], ] ); if ( $field['inline'] ) { $field['js_options'] = wp_parse_args( $field['js_options'], [ 'altFieldTimeOnly' => false ] ); } $field['php_format'] = static::get_php_format( $field['js_options'] ); $field = parent::normalize( $field ); return $field; } /** * Get the attributes for a field. * * @param array $field The field parameters. * @param mixed $value The meta value. * * @return array */ public static function get_attributes( $field, $value = null ) { $attributes = parent::get_attributes( $field, $value ); $attributes = wp_parse_args( $attributes, [ 'data-options' => wp_json_encode( $field['js_options'] ) ] ); $attributes['type'] = 'text'; return $attributes; } /** * Returns a date() compatible format string from the JavaScript format. * @link http://www.php.net/manual/en/function.date.php */ protected static function get_php_format( array $js_options ): string { return strtr( $js_options['dateFormat'], self::$date_formats ) . $js_options['separator'] . strtr( $js_options['timeFormat'], self::$time_formats ); } /** * Format a single value for the helper functions. Sub-fields should overwrite this method if necessary. * * @param array $field Field parameters. * @param string $value The value. * @param array $args Additional arguments. Rarely used. See specific fields for details. * @param int|null $post_id Post ID. null for current post. Optional. * * @return string */ public static function format_single_value( $field, $value, $args, $post_id ) { if ( $field['timestamp'] ) { $value = self::from_timestamp( $value, $field ); } else { $value = [ 'timestamp' => strtotime( $value ), 'formatted' => $value, ]; } return empty( $args['format'] ) ? $value['formatted'] : gmdate( $args['format'], $value['timestamp'] ); } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/divider.php ================================================ "; } public static function end_html( array $field ): string { return ''; } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/fieldset-text.php ================================================ %s

      '; if ( ! is_array( $field['options'] ) ) { return ''; } foreach ( $field['options'] as $key => $label ) { $value = $meta[ $key ] ?? ''; $field['attributes']['name'] = $field['field_name'] . "[{$key}]"; $html[] = sprintf( $tpl, $label, parent::html( $value, $field ) ); } $out = '
      ' . ( $field['desc'] ? '' . $field['desc'] . '' : '' ) . implode( ' ', $html ) . '
      '; return $out; } protected static function input_description( array $field ): string { return ''; } /** * Normalize parameters for field. * * @param array $field Field parameters. * * @return array */ public static function normalize( $field ) { $field = parent::normalize( $field ); $field['multiple'] = false; $field['attributes']['id'] = false; $field['attributes']['type'] = 'text'; return $field; } /** * Format value for the helper functions. * * @param array $field Field parameters. * @param string|array $value The field meta value. * @param array $args Additional arguments. Rarely used. See specific fields for details. * @param int|null $post_id Post ID. null for current post. Optional. * * @return string */ public static function format_value( $field, $value, $args, $post_id ) { $output = ''; foreach ( $field['options'] as $label ) { $output .= ""; } $output .= ''; if ( ! $field['clone'] ) { $output .= self::format_single_value( $field, $value, $args, $post_id ); } else { foreach ( $value as $subvalue ) { $output .= self::format_single_value( $field, $subvalue, $args, $post_id ); } } $output .= '
      $label
      '; return $output; } /** * Format a single value for the helper functions. Sub-fields should overwrite this method if necessary. * * @param array $field Field parameters. * @param array $value The value. * @param array $args Additional arguments. Rarely used. See specific fields for details. * @param int|null $post_id Post ID. null for current post. Optional. * * @return string */ public static function format_single_value( $field, $value, $args, $post_id ) { $output = ''; foreach ( $value as $subvalue ) { $output .= "$subvalue"; } $output .= ''; return $output; } /** * Since we're using an array of text fields, we need to check if all of them are empty. * Otherwise, there is no way to know if the field is empty or not. */ public static function value( $new, $old, $post_id, $field ) { $all_empty = empty( array_filter( (array) $new ) ); return $all_empty ? [] : $new; } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/file-input.php ================================================ esc_html__( 'Select File', 'meta-box' ), ] ); } /** * Get field HTML. * * @param mixed $meta Meta value. * @param array $field Field parameters. * * @return string */ public static function html( $meta, $field ) { $attributes = self::get_attributes( $field, $meta ); $meta_array = explode( '.', $meta ); $file_ext = strtolower( end( $meta_array ) ); $extensions = [ 'jpeg', 'jpg', 'png', 'gif' ]; return sprintf( '
      %s %s
      ', in_array( $file_ext, $extensions, true ) ? '' : 'rwmb-file-input-hidden', $meta, self::render_attributes( $attributes ), esc_html__( 'Select', 'meta-box' ), $meta ? '' : 'hidden', esc_html__( 'Remove', 'meta-box' ) ); } /** * Get the attributes for a field. * * @param array $field Field parameters. * @param mixed $value Meta value. * @return array */ public static function get_attributes( $field, $value = null ) { $attributes = parent::get_attributes( $field, $value ); $attributes['type'] = 'text'; return $attributes; } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/file-upload.php ================================================ 0, ] ); $field['js_options'] = wp_parse_args( $field['js_options'], [ 'maxFileSize' => $field['max_file_size'], ] ); return $field; } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/file.php ================================================ . */ class RWMB_File_Field extends RWMB_Field { public static function admin_enqueue_scripts() { wp_enqueue_style( 'rwmb-file', RWMB_CSS_URL . 'file.css', [], RWMB_VER ); wp_style_add_data( 'rwmb-file', 'path', RWMB_CSS_DIR . 'file.css' ); wp_enqueue_script( 'rwmb-file', RWMB_JS_URL . 'file.js', [ 'jquery-ui-sortable' ], RWMB_VER, true ); RWMB_Helpers_Field::localize_script_once( 'rwmb-file', 'rwmbFile', [ // Translators: %d is the number of files in singular form. 'maxFileUploadsSingle' => __( 'You may only upload maximum %d file', 'meta-box' ), // Translators: %d is the number of files in plural form. 'maxFileUploadsPlural' => __( 'You may only upload maximum %d files', 'meta-box' ), ] ); } public static function add_actions() { add_action( 'post_edit_form_tag', [ __CLASS__, 'post_edit_form_tag' ] ); add_action( 'wp_ajax_rwmb_delete_file', [ __CLASS__, 'ajax_delete_file' ] ); } public static function post_edit_form_tag() { echo ' enctype="multipart/form-data"'; } public static function ajax_delete_file() { $request = rwmb_request(); $field_id = (string) $request->filter_post( 'field_id' ); $type = str_contains( $request->filter_post( 'field_name' ), '[' ) ? 'child' : 'top'; check_ajax_referer( "rwmb-delete-file_{$field_id}" ); if ( 'child' === $type ) { $field_group = explode( '[', $request->filter_post( 'field_name' ) ); $field_id = $field_group[0]; // This is top parent field_id. } // Make sure the file to delete is in the custom field. $attachment = $request->post( 'attachment_id' ); $object_id = $request->filter_post( 'object_id' ); $object_type = (string) $request->filter_post( 'object_type' ); $field = rwmb_get_field_settings( $field_id, [ 'object_type' => $object_type ], $object_id ); $field_value = self::raw_meta( $object_id, $field ); if ( ! self::in_array_r( $attachment, $field_value ) ) { wp_send_json_error( __( 'Error: Invalid file', 'meta-box' ) ); } // Delete the file. if ( is_numeric( $attachment ) ) { $result = wp_delete_attachment( $attachment ); } else { $path = str_replace( home_url( '/' ), trailingslashit( ABSPATH ), $attachment ); $result = unlink( $path ); // phpcs:ignore WordPress.WP.AlternativeFunctions.unlink_unlink } if ( $result ) { wp_send_json_success(); } wp_send_json_error( __( 'Error: Cannot delete file', 'meta-box' ) ); } /** * Recursively search needle in haystack */ protected static function in_array_r( $needle, $haystack, $strict = false ): bool { foreach ( $haystack as $item ) { // phpcs:ignore Universal.Operators.StrictComparisons.LooseEqual if ( ( $strict ? $item === $needle : $item == $needle ) || ( is_array( $item ) && self::in_array_r( $needle, $item, $strict ) ) ) { return true; } } return false; } /** * Get field HTML. * * @param mixed $meta Meta value. * @param array $field Field parameters. * * @return string */ public static function html( $meta, $field ) { $meta = array_filter( (array) $meta ); $i18n_more = apply_filters( 'rwmb_file_add_string', _x( '+ Add new file', 'file upload', 'meta-box' ), $field ); $html = self::get_uploaded_files( $meta, $field ); // Show form upload. $attributes = self::get_attributes( $field, $meta ); $attributes['type'] = 'file'; $attributes['name'] = "{$field['input_name']}[]"; $attributes['class'] = 'rwmb-file-input'; /* * Use JavaScript to toggle 'required' attribute, because: * - Field might already have value (uploaded files). * - Be able to detect when uploading multiple files. */ if ( $attributes['required'] ) { $attributes['data-required'] = 1; $attributes['required'] = false; } // Upload new files. $html .= sprintf( '
      ', self::render_attributes( $attributes ) ); if ( 1 !== $field['max_file_uploads'] ) { $html .= sprintf( '%s', $i18n_more ); } $html .= '
      '; $html .= sprintf( '', $field['index_name'], $field['input_name'] ); return $html; } /** * Get HTML for uploaded files. * * @param array $files List of uploaded files. * @param array $field Field parameters. * @return string */ protected static function get_uploaded_files( $files, $field ) { $delete_nonce = wp_create_nonce( "rwmb-delete-file_{$field['id']}" ); $output = ''; foreach ( (array) $files as $k => $file ) { // Ignore deleted files (if users accidentally deleted files or uses `force_delete` without saving post). if ( get_attached_file( $file ) || $field['upload_dir'] ) { $output .= static::file_html( $file, $k, $field ); } } return sprintf( '
        %s
      ', $field['id'], $field['field_name'], $delete_nonce, $field['force_delete'] ? 1 : 0, $field['max_file_uploads'], $field['mime_type'], $output ); } /** * Get HTML for uploaded file. * * @param int $file Attachment (file) ID. * @param int $index File index. * @param array $field Field data. * @return string */ protected static function file_html( $file, $index, $field ) { $i18n_delete = apply_filters( 'rwmb_file_delete_string', _x( 'Delete', 'file upload', 'meta-box' ) ); $i18n_edit = apply_filters( 'rwmb_file_edit_string', _x( 'Edit', 'file upload', 'meta-box' ) ); $attributes = self::get_attributes( $field, $file ); if ( ! $file ) { return ''; } if ( $field['upload_dir'] ) { $data = self::file_info_custom_dir( $file, $field ); } else { $data = [ 'icon' => wp_get_attachment_image( $file, [ 48, 64 ], true ), 'name' => basename( get_attached_file( $file ) ), 'url' => wp_get_attachment_url( $file ), 'title' => get_the_title( $file ), 'edit_link' => '', ]; $edit_link = get_edit_post_link( $file ); if ( $edit_link ) { $data['edit_link'] = sprintf( '%s', $edit_link, $i18n_edit ); } } return sprintf( '
    • %s
      %s
      %s
      %s %s
    • ', $data['icon'], esc_url( $data['url'] ), esc_html( $data['title'] ), esc_html( $data['name'] ), $data['edit_link'], esc_attr( $file ), esc_html( $i18n_delete ), esc_attr( $attributes['name'] ), esc_attr( $index ), esc_attr( $file ) ); } protected static function file_info_custom_dir( string $file, array $field ): array { $path = wp_normalize_path( trailingslashit( $field['upload_dir'] ) . basename( $file ) ); $ext = pathinfo( $path, PATHINFO_EXTENSION ); $icon_url = wp_mime_type_icon( wp_ext2type( $ext ) ); $data = [ 'icon' => '', 'name' => basename( $path ), 'path' => $path, 'url' => $file, 'title' => preg_replace( '/\.[^.]+$/', '', basename( $path ) ), 'edit_link' => '', ]; return $data; } /** * Get meta values to save. * * @param mixed $new The submitted meta value. * @param mixed $old The existing meta value. * @param int $post_id The post ID. * @param array $field The field parameters. * * @return array|mixed */ public static function value( $new, $old, $post_id, $field ) { $input = $field['index'] ?? $field['input_name']; // @codingStandardsIgnoreLine if ( empty( $input ) || empty( $_FILES[ $input ] ) ) { return $new; } $new = array_filter( (array) $new ); $count = self::transform( $input ); for ( $i = 0; $i < $count; $i++ ) { $attachment = self::handle_upload( "{$input}_{$i}", $post_id, $field ); if ( $attachment && ! is_wp_error( $attachment ) ) { $new[] = $attachment; } } return $new; } /** * Get meta values to save for cloneable fields. * * @param array $new The submitted meta value. * @param array $old The existing meta value. * @param int $object_id The object ID. * @param array $field The field settings. * @param array $data_source Data source. Either $_POST or custom array. Used in group to get uploaded files. * * @return mixed */ public static function clone_value( $new, $old, $object_id, $field, $data_source = null ) { if ( ! $data_source ) { // @codingStandardsIgnoreLine $data_source = $_POST; } $indexes = $data_source[ "_index_{$field['id']}" ] ?? []; foreach ( $indexes as $key => $index ) { $field['index'] = $index; $old_value = $old[ $key ] ?? []; $value = $new[ $key ] ?? []; $value = self::value( $value, $old_value, $object_id, $field ); $new[ $key ] = self::filter( 'sanitize', $value, $field, $old_value, $object_id ); } return $new; } /** * Handle file upload. * Consider upload to Media Library or custom folder. * * @param string $file_id File ID in $_FILES when uploading. * @param int $post_id Post ID. * @param array $field Field settings. * * @return \WP_Error|int|string WP_Error if has error, attachment ID if upload in Media Library, URL to file if upload to custom folder. */ protected static function handle_upload( $file_id, $post_id, $field ) { return $field['upload_dir'] ? self::handle_upload_custom_dir( $file_id, $field ) : media_handle_upload( $file_id, $post_id ); } /** * Transform $_FILES from $_FILES['field']['key']['index'] to $_FILES['field_index']['key']. * * @param string $input_name The field input name. * * @return int The number of uploaded files. */ protected static function transform( $input_name ): int { // phpcs:disable foreach ( $_FILES[ $input_name ] as $key => $list ) { foreach ( $list as $index => $value ) { $file_key = sanitize_text_field( "{$input_name}_{$index}" ); if ( ! isset( $_FILES[ $file_key ] ) ) { $_FILES[ $file_key ] = []; } $_FILES[ $file_key ][ $key ] = $value; } } return count( $_FILES[ $input_name ]['name'] ); // phpcs:enable } /** * Normalize parameters for field. * * @param array $field Field parameters. * @return array */ public static function normalize( $field ) { $field = parent::normalize( $field ); $field = wp_parse_args( $field, [ 'std' => [], 'force_delete' => false, 'max_file_uploads' => 0, 'mime_type' => '', 'upload_dir' => '', 'unique_filename_callback' => null, ] ); $field['multiple'] = true; $field['input_name'] = "_file_{$field['id']}"; $field['index_name'] = "_index_{$field['id']}"; return $field; } /** * Get the field value. Return meaningful info of the files. * * @param array $field Field parameters. * @param array $args Not used for this field. * @param int|null $post_id Post ID. null for current post. Optional. * * @return mixed Full info of uploaded files */ public static function get_value( $field, $args = [], $post_id = null ) { $value = parent::get_value( $field, $args, $post_id ); if ( ! $field['clone'] ) { $value = static::files_info( $field, $value, $args ); } else { $return = []; foreach ( $value as $subvalue ) { $return[] = static::files_info( $field, $subvalue, $args ); } $value = $return; } if ( isset( $args['limit'] ) ) { $value = array_slice( $value, 0, intval( $args['limit'] ) ); } return $value; } /** * Get uploaded files information. * * @param array $field Field parameters. * @param array $files Files IDs. * @param array $args Additional arguments (for image size). * @return array */ public static function files_info( $field, $files, $args ) { $return = []; foreach ( (array) $files as $file ) { $info = static::file_info( $file, $args, $field ); if ( $info ) { $return[ $file ] = $info; } } return $return; } /** * Get uploaded file information. * * @param int $file Attachment file ID (post ID). Required. * @param array $args Array of arguments (for size). * @param array $field Field settings. * * @return array|bool False if file not found. Array of (id, name, path, url) on success. */ public static function file_info( $file, $args = [], $field = [] ) { if ( ! empty( $field['upload_dir'] ) ) { return self::file_info_custom_dir( $file, $field ); } $path = get_attached_file( $file ); if ( ! $path ) { return false; } return wp_parse_args( [ 'ID' => $file, 'name' => basename( $path ), 'path' => $path, 'url' => wp_get_attachment_url( $file ), 'title' => get_the_title( $file ), ], wp_get_attachment_metadata( $file ) ); } /** * Format a single value for the helper functions. Sub-fields should overwrite this method if necessary. * * @param array $field Field parameters. * @param array $value The value. * @param array $args Additional arguments. Rarely used. See specific fields for details. * @param int|null $post_id Post ID. null for current post. Optional. * * @return string */ public static function format_single_value( $field, $value, $args, $post_id ) { return sprintf( '%s', esc_url( $value['url'] ), esc_html( $value['title'] ) ); } /** * Handle upload for files in custom directory. * * @param string $file_id File ID in $_FILES when uploading. * @param array $field Field settings. * * @return string URL to uploaded file. */ public static function handle_upload_custom_dir( $file_id, $field ) { // @codingStandardsIgnoreStart if ( empty( $_FILES[ $file_id ] ) ) { return; } $file = $_FILES[ $file_id ]; // @codingStandardsIgnoreEnd // Use a closure to filter upload directory. Requires PHP >= 5.3.0. $filter_upload_dir = function ( $uploads ) use ( $field ) { $uploads['path'] = $field['upload_dir']; $uploads['url'] = self::convert_path_to_url( $field['upload_dir'] ); $uploads['subdir'] = ''; $uploads['basedir'] = $field['upload_dir']; return $uploads; }; // Make sure upload dir is inside WordPress. $upload_dir = wp_normalize_path( untrailingslashit( $field['upload_dir'] ) ); $root = wp_normalize_path( untrailingslashit( ABSPATH ) ); if ( ! str_starts_with( $upload_dir, $root ) ) { return; } // Let WordPress handle upload to the custom directory. add_filter( 'upload_dir', $filter_upload_dir ); $overrides = [ 'test_form' => false, 'unique_filename_callback' => $field['unique_filename_callback'], ]; $file_info = wp_handle_upload( $file, $overrides ); remove_filter( 'upload_dir', $filter_upload_dir ); return empty( $file_info['url'] ) ? null : $file_info['url']; } public static function convert_path_to_url( string $path ): string { $path = wp_normalize_path( untrailingslashit( $path ) ); $root = wp_normalize_path( untrailingslashit( ABSPATH ) ); $relative_path = str_replace( $root, '', $path ); return home_url( $relative_path ); } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/heading.php ================================================ %s', $attributes, $field['name'] ); } protected static function end_html( array $field ): string { return self::input_description( $field ); } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/icon.php ================================================ $field['icon_file'], 'icon_dir' => $field['icon_dir'], 'icon_css' => is_string( $field['icon_css'] ) ? $field['icon_css'] : '', ]; // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize $cache_key = md5( serialize( $params ) ) . '-icons'; $icons = wp_cache_get( $cache_key, self::CACHE_GROUP ); if ( false !== $icons ) { return $icons; } $data = self::parse_icon_data( $field ); // Reformat icons. $icons = []; foreach ( $data as $key => $icon ) { $icon = self::normalize_icon( $field, $key, $icon ); if ( is_numeric( key( $icon ) ) ) { $icons = array_merge( $icons, $icon ); continue; } $icons[] = $icon; } // Cache the result. wp_cache_set( $cache_key, $icons, self::CACHE_GROUP ); return $icons; } private static function parse_icon_data( array $field ): array { $keys = [ 'icon_file', 'icon_css', 'icon_dir', ]; foreach ( $keys as $key ) { if ( ! empty( $field[ $key ] ) && is_string( $field[ $key ] ) ) { return call_user_func( [ __CLASS__, "parse_$key" ], $field ); } } return []; } private static function parse_icon_file( array $field ): array { if ( ! file_exists( $field['icon_file'] ) ) { return []; } // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents $data = (string) file_get_contents( $field['icon_file'] ); $decoded = json_decode( $data, true ); // JSON file. if ( JSON_ERROR_NONE === json_last_error() ) { return $decoded; } // Text file: each icon on a line. return array_map( 'trim', explode( "\n", $data ) ); } private static function parse_icon_css( array $field ): array { // Parse local CSS file only. $file = self::url_to_path( $field['icon_css'] ); if ( ! file_exists( $file ) ) { return []; } // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents $css = (string) file_get_contents( $file ); preg_match_all( '/\.([^\s:]+):before/', $css, $matches ); if ( empty( $matches[1] ) ) { preg_match_all( '/\.([^\s:]+)/', $css, $matches ); } return $matches[1]; } private static function parse_icon_dir( array $field ): array { $dir = $field['icon_dir']; if ( ! is_dir( $dir ) ) { return []; } $icons = []; $files = glob( trailingslashit( $dir ) . '*.svg' ); foreach ( $files as $file ) { $filename = substr( basename( $file ), 0, -4 ); $icons[] = [ 'value' => $filename, 'label' => $filename, // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents 'svg' => file_get_contents( $file ), ]; } return $icons; } private static function normalize_icon( array $field, $key, $icon ): array { // Default: Font Awesome Free. if ( $field['icon_set'] === 'font-awesome-free' ) { $style = $icon['styles'][0]; return [ 'value' => "fa-{$style} fa-{$key}", 'label' => $icon['label'], 'svg' => $icon['svg'][ $style ]['raw'], ]; } // Font Awesome Pro. if ( $field['icon_set'] === 'font-awesome-pro' ) { $icons = []; foreach ( $icon['styles'] as $style ) { $icons[] = [ 'value' => "fa-{$style} fa-{$key}", 'label' => "{$icon[ 'label' ]} ({$style})", 'svg' => $icon['svg'][ $style ]['raw'], ]; } return $icons; } // JSON file: "icon-class": { "label": "Label", "svg": "" } or from `icon_dir`. if ( is_array( $icon ) ) { return [ 'value' => $icon['value'] ?? $key, 'label' => $icon['label'] ?? $key, 'svg' => $icon['svg'] ?? '', ]; } // JSON file: "icon-class": "Label" or "icon-class": "". if ( is_string( $key ) ) { $label = str_contains( $icon, ' $key, 'label' => $label, 'svg' => $svg, ]; } // Parse classes from CSS. if ( $field['icon_css'] && ! $field['icon_file'] ) { $icon = trim( $field['icon_base_class'] . ' ' . $icon ); } // Text file: each icon on a line. return [ 'value' => $icon, 'label' => $icon, 'svg' => '', ]; } private static function get_svg( array $field, string $value ): string { $file = trailingslashit( $field['icon_dir'] ) . $value . '.svg'; // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents return file_exists( $file ) ? file_get_contents( $file ) : ''; } private static function get_options( array $field ): array { $icons = self::get_icons( $field ); $options = []; foreach ( $icons as $icon ) { $svg = ! $icon['svg'] && $field['icon_dir'] ? self::get_svg( $field, $icon['value'] ) : $icon['svg']; $options[] = [ 'value' => $icon['value'], 'label' => $svg . $icon['label'], ]; } return $options; } /** * Normalize field settings. * * @param array $field Field settings. * @return array */ public static function normalize( $field ) { $field = wp_parse_args( $field, [ 'placeholder' => __( 'Select an icon', 'meta-box' ), 'icon_css' => '', 'icon_set' => '', 'icon_file' => '', 'icon_dir' => '', 'icon_base_class' => '', ] ); // Ensure absolute paths and URLs. $field['icon_file'] = self::ensure_absolute_path( $field['icon_file'] ); $field['icon_dir'] = self::ensure_absolute_path( $field['icon_dir'] ); if ( is_string( $field['icon_css'] ) && $field['icon_css'] ) { $field['icon_css'] = self::ensure_absolute_url( $field['icon_css'] ); } // Font Awesome Pro. // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedIf if ( $field['icon_set'] === 'font-awesome-pro' ) { } elseif ( $field['icon_file'] || $field['icon_dir'] || $field['icon_css'] ) { // Custom icon set. $field['icon_set'] = 'custom'; } else { // Font Awesome Free. $field['icon_set'] = 'font-awesome-free'; $field['icon_file'] = RWMB_DIR . 'css/fontawesome/icons.json'; } $field['options'] = self::get_options( $field ); $field = parent::normalize( $field ); return $field; } /** * Format value for the helper functions. * * @param array $field Field parameters. * @param string|array $value The field meta value. * @param array $args Additional arguments. Rarely used. See specific fields for details. * @param int|null $post_id Post ID. null for current post. Optional. * * @return string */ public static function format_single_value( $field, $value, $args, $post_id ) { // SVG from file. if ( $field['icon_dir'] ) { return self::get_svg( $field, $value ); } $icons = self::get_icons( $field ); // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict $key = array_search( $value, array_column( $icons, 'value' ) ); if ( false === $key ) { return ''; } // Embed SVG. if ( $icons[ $key ]['svg'] ) { return $icons[ $key ]['svg']; } // Render with class and use css. self::enqueue_icon_font_style( $field ); return sprintf( '', $value ); } private static function url_to_path( string $url ): string { return str_starts_with( $url, home_url( '/' ) ) ? str_replace( home_url( '/' ), trailingslashit( ABSPATH ), $url ) : ''; } private static function ensure_absolute_path( string $path ): string { if ( ! $path || file_exists( $path ) ) { return $path; } $root = wp_normalize_path( ABSPATH ); $path = wp_normalize_path( $path ); return str_starts_with( $path, $root ) ? $path : trailingslashit( $root ) . ltrim( $path, '/' ); } private static function ensure_absolute_url( string $url ): string { return filter_var( $url, FILTER_VALIDATE_URL ) ? $url : home_url( $url ); } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/image-advanced.php ================================================ 'thumbnail', ] ); $field = parent::normalize( $field ); $field['js_options'] = wp_parse_args( $field['js_options'], [ 'imageSize' => $field['image_size'], ] ); return $field; } /** * Get the field value. * * @param array $field Field parameters. * @param array $args Additional arguments. * @param ?int $post_id Post ID. * @return mixed */ public static function get_value( $field, $args = [], $post_id = null ) { return RWMB_Image_Field::get_value( $field, $args, $post_id ); } /** * Get uploaded file information. * * @param int $file Attachment image ID (post ID). Required. * @param array $args Array of arguments (for size). * @param array $field Field settings. * * @return array|bool False if file not found. Array of image info on success. */ public static function file_info( $file, $args = [], $field = [] ) { return RWMB_Image_Field::file_info( $file, $args, $field ); } /** * Format a single value for the helper functions. Sub-fields should overwrite this method if necessary. * * @param array $field Field parameters. * @param array $value The value. * @param array $args Additional arguments. Rarely used. See specific fields for details. * @param int|null $post_id Post ID. null for current post. Optional. * * @return string */ public static function format_single_value( $field, $value, $args, $post_id ) { return RWMB_Image_Field::format_single_value( $field, $value, $args, $post_id ); } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/image-select.php ================================================ $image ) { $attributes = self::get_attributes( $field, $value ); $html[] = sprintf( '', $image, self::render_attributes( $attributes ), // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict checked( in_array( $value, $meta ), true, false ) ); } return implode( ' ', $html ); } /** * Normalize parameters for field. * * @param array $field Field parameters. * @return array */ public static function normalize( $field ) { $field = parent::normalize( $field ); $field['options'] = $field['options'] ?? []; $field['field_name'] .= $field['multiple'] ? '[]' : ''; return $field; } /** * Get the attributes for a field. * * @param array $field Field parameters. * @param mixed $value Meta value. * @return array */ public static function get_attributes( $field, $value = null ) { $attributes = parent::get_attributes( $field, $value ); $attributes['id'] = false; $attributes['type'] = $field['multiple'] ? 'checkbox' : 'radio'; $attributes['value'] = $value; return $attributes; } /** * Format a single value for the helper functions. Sub-fields should overwrite this method if necessary. * * @param array $field Field parameters. * @param string $value The value. * @param array $args Additional arguments. Rarely used. See specific fields for details. * @param int|null $post_id Post ID. null for current post. Optional. * * @return string */ public static function format_single_value( $field, $value, $args, $post_id ) { return $value ? sprintf( '', esc_url( $field['options'][ $value ] ) ) : ''; } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/image-upload.php ================================================ . */ class RWMB_Image_Field extends RWMB_File_Field { public static function admin_enqueue_scripts() { parent::admin_enqueue_scripts(); wp_enqueue_media(); wp_enqueue_style( 'rwmb-image', RWMB_CSS_URL . 'image.css', [], RWMB_VER ); wp_style_add_data( 'rwmb-image', 'path', RWMB_CSS_DIR . 'image.css' ); } /** * Get HTML for uploaded file. * * @param int $file Attachment (file) ID. * @param int $index File index. * @param array $field Field data. * * @return string */ protected static function file_html( $file, $index, $field ) { $attributes = self::get_attributes( $field, $file ); $edit_link = get_edit_post_link( $file ); if ( $edit_link ) { $edit_link = sprintf( '', $edit_link ); } $attachment_image = is_numeric( $file ) ? wp_get_attachment_image( $file, $field['image_size'] ) : ''; return sprintf( '
    • %s
      %s
    • ', $attachment_image, $edit_link, esc_attr( $file ), esc_attr( $attributes['name'] ), esc_attr( $index ), esc_attr( $file ) ); } /** * Normalize field settings. * * @param array $field Field settings. * * @return array */ public static function normalize( $field ) { $field = parent::normalize( $field ); $field = wp_parse_args( $field, [ 'image_size' => 'thumbnail' ] ); $field['attributes'] = wp_parse_args( $field['attributes'], [ 'accept' => 'image/*' ] ); return $field; } /** * Format a single value for the helper functions. Sub-fields should overwrite this method if necessary. * * @param array $field Field parameters. * @param array $value The value. * @param array $args Additional arguments. Rarely used. See specific fields for details. * @param int|null $post_id Post ID. null for current post. Optional. * * @return string */ public static function format_single_value( $field, $value, $args, $post_id ) { $output = sprintf( '%s', esc_url( $value['url'] ), esc_attr( $value['alt'] ) ); // Link thumbnail to full size image? if ( ! empty( $args['link'] ) ) { $output = sprintf( '%s', esc_url( $value['full_url'] ), esc_attr( $value['title'] ), $output ); } return $output; } /** * Get uploaded file information. * * @param int $file Attachment image ID (post ID). Required. * @param array $args Array of arguments (for size). * @param array $field Field settings. * * @return array|bool False if file not found. Array of image info on success. */ public static function file_info( $file, $args = [], $field = [] ) { if ( ! empty( $field['upload_dir'] ) ) { return self::file_info_custom_dir( $file, $field ); } $path = get_attached_file( $file ); if ( ! $path ) { return false; } $args = wp_parse_args( $args, [ 'size' => 'thumbnail' ] ); $image = wp_get_attachment_image_src( $file, $args['size'] ); if ( ! $image ) { return false; } $attachment = get_post( $file ); $info = [ 'ID' => $file, 'name' => basename( $path ), 'path' => $path, 'url' => $image[0], 'full_url' => wp_get_attachment_url( $file ), 'title' => $attachment->post_title, 'caption' => $attachment->post_excerpt, 'description' => $attachment->post_content, 'alt' => get_post_meta( $file, '_wp_attachment_image_alt', true ), ]; if ( function_exists( 'wp_get_attachment_image_srcset' ) ) { $info['srcset'] = wp_get_attachment_image_srcset( $file, $args['size'] ); } $info = wp_parse_args( $info, self::get_image_meta_data( $file ) ); // Do not overwrite width and height by returned value of image meta. $info['width'] = $image[1]; $info['height'] = $image[2]; return $info; } /** * Get image meta data. * * @param int $attachment_id Attachment ID. * @return array */ protected static function get_image_meta_data( $attachment_id ) { $metadata = wp_get_attachment_metadata( $attachment_id ); if ( empty( $metadata['sizes'] ) ) { return $metadata; } $dir_url = dirname( wp_get_attachment_url( $attachment_id ) ); foreach ( $metadata['sizes'] as &$size ) { $size['url'] = "{$dir_url}/{$size['file']}"; } return $metadata; } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/input-list.php ================================================ ', $field['collapse'] ? ' rwmb-collapse' : '', $field['inline'] ? ' rwmb-inline' : '' ); $output .= $walker->walk( $options, $field['flatten'] ? -1 : 0 ); $output .= ''; return $output; } /** * Normalize parameters for field. * * @param array $field Field parameters. * @return array */ public static function normalize( $field ) { $field = $field['multiple'] ? RWMB_Multiple_Values_Field::normalize( $field ) : $field; $field = RWMB_Input_Field::normalize( $field ); $field = parent::normalize( $field ); $field = wp_parse_args( $field, [ 'collapse' => true, 'inline' => null, 'select_all_none' => false, ] ); $field['flatten'] = $field['multiple'] ? $field['flatten'] : true; $field['inline'] = ! $field['multiple'] && ! isset( $field['inline'] ) ? true : $field['inline']; return $field; } /** * Get the attributes for a field. * * @param array $field Field parameters. * @param mixed $value Meta value. * * @return array */ public static function get_attributes( $field, $value = null ) { $attributes = RWMB_Input_Field::get_attributes( $field, $value ); $attributes['id'] = false; $attributes['type'] = $field['multiple'] ? 'checkbox' : 'radio'; $attributes['value'] = $value; return $attributes; } /** * Get html for select all|none for multiple checkbox. * * @param array $field Field parameters. * @return string */ public static function get_select_all_html( $field ) { if ( $field['multiple'] && $field['select_all_none'] ) { return sprintf( '

      ', $field['id'], __( 'Toggle All', 'meta-box' ) ); } return ''; } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/input.php ================================================ fields. */ abstract class RWMB_Input_Field extends RWMB_Field { public static function admin_enqueue_scripts() { wp_enqueue_style( 'rwmb-input', RWMB_CSS_URL . 'input.css', [], RWMB_VER ); wp_style_add_data( 'rwmb-input', 'path', RWMB_CSS_DIR . 'input.css' ); } /** * Get field HTML. * * @param mixed $meta Meta value. * @param array $field Field parameters. * @return string */ public static function html( $meta, $field ) { $output = ''; if ( $field['prepend'] || $field['append'] ) { $output = '
      '; } if ( $field['prepend'] ) { $output .= '' . $field['prepend'] . ''; } $attributes = static::get_attributes( $field, $meta ); $output .= sprintf( '%s', self::render_attributes( $attributes ), self::datalist( $field ) ); if ( $field['append'] ) { $output .= '' . $field['append'] . ''; } if ( $field['prepend'] || $field['append'] ) { $output .= '
      '; } return $output; } /** * Normalize parameters for field. * * @param array $field Field parameters. * @return array */ public static function normalize( $field ) { $field = parent::normalize( $field ); $field = wp_parse_args( $field, [ 'autocomplete' => false, 'datalist' => false, 'readonly' => false, 'maxlength' => false, 'minlength' => false, 'pattern' => false, 'prepend' => '', 'append' => '', ] ); if ( $field['datalist'] ) { $field['datalist'] = wp_parse_args( $field['datalist'], [ 'id' => $field['id'] . '_list', 'options' => [], ] ); } return $field; } /** * Get the attributes for a field. * * @param array $field Field parameters. * @param mixed $value Meta value. * @return array */ public static function get_attributes( $field, $value = null ) { $attributes = parent::get_attributes( $field, $value ); $attributes = wp_parse_args( $attributes, [ 'autocomplete' => $field['autocomplete'], 'list' => $field['datalist'] ? $field['datalist']['id'] : false, 'readonly' => $field['readonly'], 'maxlength' => $field['maxlength'], 'minlength' => $field['minlength'], 'pattern' => $field['pattern'], 'value' => $value, 'placeholder' => $field['placeholder'], 'type' => $field['type'], ] ); if ( isset( $field['size'] ) ) { $attributes['size'] = $field['size']; } return $attributes; } protected static function datalist( array $field ): string { if ( empty( $field['datalist'] ) ) { return ''; } $datalist = $field['datalist']; $html = sprintf( '', $datalist['id'] ); foreach ( $datalist['options'] as $option ) { $html .= sprintf( '', $option ); } $html .= ''; return $html; } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/key-value.php ================================================ ', self::render_attributes( $attributes ) ); // Value. $val = isset( $meta[1] ) ? $meta[1] : ''; $attributes = self::get_attributes( $field, $val ); $attributes['placeholder'] = $field['placeholder']['value']; $html .= sprintf( '', self::render_attributes( $attributes ) ); return $html; } protected static function begin_html( array $field ): string { return parent::begin_html( $field ) . parent::input_description( $field ); } protected static function input_description( array $field ): string { return ''; } /** * Sanitize field value. * * @param mixed $new The submitted meta value. * @param mixed $old The existing meta value. * @param int $post_id The post ID. * @param array $field The field parameters. * * @return array */ public static function value( $new, $old, $post_id, $field ) { foreach ( $new as &$arr ) { if ( empty( $arr[0] ) && empty( $arr[1] ) ) { $arr = false; } } $new = array_filter( $new ); return $new; } /** * Normalize parameters for field. * * @param array $field Field parameters. * * @return array */ public static function normalize( $field ) { $field['clone'] = true; $field['multiple'] = true; $field = parent::normalize( $field ); $field['attributes']['type'] = 'text'; $field['placeholder'] = wp_parse_args( (array) $field['placeholder'], [ 'key' => __( 'Key', 'meta-box' ), 'value' => __( 'Value', 'meta-box' ), ] ); return $field; } /** * Format value for the helper functions. * * @param array $field Field parameters. * @param string|array $value The field meta value. * @param array $args Additional arguments. Rarely used. See specific fields for details. * @param int|null $post_id Post ID. null for current post. Optional. * * @return string */ public static function format_clone_value( $field, $value, $args, $post_id ) { return sprintf( ' %s', $value[0], $value[1] ); } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/map.php ================================================ $field['api_key'], 'language' => $field['language'], 'libraries' => 'places', ], 'https://maps.google.com/maps/api/js' ); /** * Allows developers load more libraries via a filter. * @link https://developers.google.com/maps/documentation/javascript/libraries */ $google_maps_url = apply_filters( 'rwmb_google_maps_url', $google_maps_url ); wp_register_script( 'google-maps', esc_url_raw( $google_maps_url ), [], RWMB_VER, true ); wp_enqueue_script( 'rwmb-map', RWMB_JS_URL . 'map.js', [ 'jquery-ui-autocomplete', 'google-maps' ], RWMB_VER, true ); RWMB_Helpers_Field::localize_script_once( 'rwmb-map', 'RWMB_Map', [ 'no_results_string' => __( 'No results found', 'meta-box' ), ] ); } /** * Get field HTML. * * @param mixed $meta Meta value. * @param array $field Field parameters. * * @return string */ public static function html( $meta, $field ) { $address = is_array( $field['address_field'] ) ? implode( ',', $field['address_field'] ) : $field['address_field']; $html = sprintf( '
      ', esc_attr( $address ) ); $attributes = self::get_attributes( $field, $meta ); $attributes['type'] = 'hidden'; $attributes['value'] = $meta; $html .= sprintf( '
      ', esc_attr( $field['std'] ), esc_attr( $field['region'] ), esc_attr( $field['marker_draggable'] ? 'true' : 'false' ), self::render_attributes( $attributes ) ); $html .= '
      '; return $html; } /** * Normalize parameters for field. * * @param array $field Field parameters. * * @return array */ public static function normalize( $field ) { $field = parent::normalize( $field ); $field = wp_parse_args( $field, [ 'std' => '', 'address_field' => '', 'language' => '', 'region' => '', 'marker_draggable' => true, // Default API key, required by Google Maps since June 2016. // Users should overwrite this key with their own key. 'api_key' => 'AIzaSyC1mUh87SGFyf133tpZQJa-s96p0tgnraQ', ] ); return $field; } /** * Get the field value. * The difference between this function and 'meta' function is 'meta' function always returns the escaped value * of the field saved in the database, while this function returns more meaningful value of the field. * * @param array $field Field parameters. * @param array $args Not used for this field. * @param int|null $post_id Post ID. null for current post. Optional. * * @return mixed Array(latitude, longitude, zoom) */ public static function get_value( $field, $args = [], $post_id = null ) { $value = parent::get_value( $field, $args, $post_id ); if ( is_array( $value ) ) { $location = []; foreach ( $value as $clone ) { list( $latitude, $longitude, $zoom ) = explode( ',', $clone . ',,' ); $location[] = compact( 'latitude', 'longitude', 'zoom' ); } return $location; } list( $latitude, $longitude, $zoom ) = explode( ',', $value . ',,' ); return compact( 'latitude', 'longitude', 'zoom' ); } /** * Format value before render map * @param array $field Field settings. * @param mixed $value Field value. * @param mixed $args Additional arguments. * @param mixed $post_id Post ID. * @return string */ public static function format_single_value( $field, $value, $args, $post_id ) { $args = wp_parse_args( $args, [ 'api_key' => $field['api_key'] ?? '', ] ); return self::render_map( $value, $args ); } /** * Render a map in the frontend. * * @param string $location The "latitude,longitude[,zoom]" location. * @param array $args Additional arguments for the map. * * @return string */ public static function render_map( $location, $args = [] ) { // For compatibility with previous version, or within groups. if ( is_string( $location ) ) { list( $latitude, $longitude, $zoom ) = explode( ',', $location . ',,' ); } else { // phpcs:ignore WordPress.PHP.DontExtract.extract_extract extract( $location ); } if ( ! $latitude || ! $longitude ) { return ''; } $args = wp_parse_args( $args, [ 'latitude' => $latitude, 'longitude' => $longitude, 'width' => '100%', 'height' => '480px', 'marker' => true, // Display marker? 'marker_title' => '', // Marker title, when hover. 'info_window' => '', // Content of info window (when click on marker). HTML allowed. 'js_options' => [], 'zoom' => $zoom, // Default API key, required by Google Maps since June 2016. // Users should overwrite this key with their own key. 'api_key' => 'AIzaSyC1mUh87SGFyf133tpZQJa-s96p0tgnraQ', ] ); $google_maps_url = add_query_arg( 'key', $args['api_key'], 'https://maps.google.com/maps/api/js' ); /* * Allows developers load more libraries via a filter. * @link https://developers.google.com/maps/documentation/javascript/libraries */ $google_maps_url = apply_filters( 'rwmb_google_maps_url', $google_maps_url ); wp_register_script( 'google-maps', esc_url_raw( $google_maps_url ), [], RWMB_VER, true ); wp_enqueue_script( 'rwmb-map-frontend', RWMB_JS_URL . 'map-frontend.js', [ 'google-maps', 'jquery' ], RWMB_VER, true ); /* * Google Maps options. * Option name is the same as specified in Google Maps documentation. * This array will be convert to Javascript Object and pass as map options. * @link https://developers.google.com/maps/documentation/javascript/reference */ $args['js_options'] = wp_parse_args( $args['js_options'], [ // Default to 'zoom' level set in admin, but can be overwritten. 'zoom' => $args['zoom'], // Map type, see https://developers.google.com/maps/documentation/javascript/reference#MapTypeId. 'mapTypeId' => 'ROADMAP', // Open Info Window 'openInfoWindow' => false, ] ); $output = sprintf( '
      ', esc_attr( wp_json_encode( $args ) ), esc_attr( $args['width'] ), esc_attr( $args['height'] ) ); return $output; } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/media.php ================================================ apply_filters( 'rwmb_media_add_string', _x( '+ Add Media', 'media', 'meta-box' ) ), 'single' => apply_filters( 'rwmb_media_single_files_string', _x( ' file', 'media', 'meta-box' ) ), 'multiple' => apply_filters( 'rwmb_media_multiple_files_string', _x( ' files', 'media', 'meta-box' ) ), 'remove' => apply_filters( 'rwmb_media_remove_string', _x( 'Remove', 'media', 'meta-box' ) ), 'edit' => apply_filters( 'rwmb_media_edit_string', _x( 'Edit', 'media', 'meta-box' ) ), 'view' => apply_filters( 'rwmb_media_view_string', _x( 'View', 'media', 'meta-box' ) ), 'noTitle' => _x( 'No Title', 'media', 'meta-box' ), 'loadingUrl' => admin_url( 'images/spinner.gif' ), 'extensions' => static::get_mime_extensions(), 'select' => apply_filters( 'rwmb_media_select_string', _x( 'Select Files', 'media', 'meta-box' ) ), 'or' => apply_filters( 'rwmb_media_or_string', _x( 'or', 'media', 'meta-box' ) ), 'uploadInstructions' => apply_filters( 'rwmb_media_upload_instructions_string', _x( 'Drop files here to upload', 'media', 'meta-box' ) ), ] ); } /** * Get meta value. * * @param int $post_id Post ID. * @param bool $saved Whether the meta box is saved at least once. * @param array $field Field parameters. * * @return mixed */ public static function meta( $post_id, $saved, $field ) { $meta = parent::meta( $post_id, $saved, $field ); /* * Update meta cache for all attachments, preparing for getting data for rendering in JS. * This reduces the number of queries for updating all attachments' meta. * @see get_attributes() */ $ids = (array) $meta; if ( $field['clone'] ) { foreach ( $ids as &$value ) { $value = (array) $value; } $ids = call_user_func_array( 'array_merge', $ids ); } update_meta_cache( 'post', $ids ); return $meta; } /** * Get field HTML. * * @param mixed $meta Meta value. * @param array $field Field parameters. * * @return string */ public static function html( $meta, $field ) { $attributes = static::get_attributes( $field, $meta ); $html = sprintf( '', self::render_attributes( $attributes ), esc_attr( wp_json_encode( $field['js_options'] ) ) ); return $html; } /** * Normalize parameters for field. * * @param array $field Field parameters. * * @return array */ public static function normalize( $field ) { $field = parent::normalize( $field ); $field = wp_parse_args( $field, [ 'std' => [], 'mime_type' => '', 'max_file_uploads' => 0, 'force_delete' => false, 'max_status' => true, 'js_options' => [], 'add_to' => 'end', ] ); $field['js_options'] = wp_parse_args( $field['js_options'], [ 'mimeType' => $field['mime_type'], 'maxFiles' => $field['max_file_uploads'], 'forceDelete' => $field['force_delete'], 'maxStatus' => $field['max_status'], 'addTo' => $field['add_to'], ] ); $field['multiple'] = true; return $field; } /** * Get the attributes for a field. * * @param array $field Field parameters. * @param mixed $value Meta value. * * @return array */ public static function get_attributes( $field, $value = null ) { $value = (array) $value; $attributes = parent::get_attributes( $field, $value ); $attributes['type'] = 'hidden'; $attributes['name'] = $field['clone'] ? str_replace( '[]', '', $attributes['name'] ) : $attributes['name']; $attributes['id'] = false; $attributes['value'] = implode( ',', $value ); $attributes['class'] .= ' rwmb-media'; // Add attachment details. $attachments = array_values( array_filter( array_map( 'wp_prepare_attachment_for_js', $value ) ) ); $attributes['data-attachments'] = wp_json_encode( $attachments ); if ( empty( $attachments ) ) { unset( $attributes['value'] ); } return $attributes; } protected static function get_mime_extensions(): array { $mime_types = wp_get_mime_types(); $extensions = []; foreach ( $mime_types as $ext => $mime ) { $ext = explode( '|', $ext ); $extensions[ $mime ] = $ext; $mime_parts = explode( '/', $mime ); if ( empty( $extensions[ $mime_parts[0] ] ) ) { $extensions[ $mime_parts[0] ] = []; } $extensions[ $mime_parts[0] ] = array_merge( $extensions[ $mime_parts[0] ], $ext ); $extensions[ $mime_parts[0] . '/*' ] = $extensions[ $mime_parts[0] ]; } return $extensions; } /** * Get meta values to save. * * @param mixed $new The submitted meta value. * @param mixed $old The existing meta value. * @param int $post_id The post ID. * @param array $field The field parameters. * * @return array */ public static function value( $new, $old, $post_id, $field ) { $new = wp_parse_id_list( $new ); if ( empty( $new ) ) { return []; } // Attach the uploaded images to the post if needed. global $wpdb; $ids = implode( ',', $new ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->posts SET post_parent=%d WHERE post_parent=0 AND ID IN ($ids)", $post_id ) ); return $new; } /** * Save meta value. * * @param mixed $new The submitted meta value. * @param mixed $old The existing meta value. * @param int $post_id The post ID. * @param array $field The field parameters. */ public static function save( $new, $old, $post_id, $field ) { if ( empty( $field['id'] ) || ! $field['save_field'] ) { return; } $storage = $field['storage']; $storage->delete( $post_id, $field['id'] ); parent::save( $new, [], $post_id, $field ); } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/multiple-values.php ================================================ . */ class RWMB_Number_Field extends RWMB_Input_Field { /** * Normalize parameters for field. * * @param array $field Field parameters. * * @return array */ public static function normalize( $field ) { $field = parent::normalize( $field ); $field = wp_parse_args( $field, [ 'step' => 1, 'min' => 0, 'max' => false, ] ); return $field; } /** * Get the attributes for a field. * * @param array $field Field parameters. * @param mixed $value Meta value. * * @return array */ public static function get_attributes( $field, $value = null ) { $attributes = parent::get_attributes( $field, $value ); $attributes = wp_parse_args( $attributes, [ 'step' => $field['step'], 'max' => $field['max'], 'min' => $field['min'], ] ); return $attributes; } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/object-choice.php ================================================ true, 'query_args' => [], 'field_type' => 'select_advanced', 'add_new' => false, 'ajax' => true, ] ); if ( 'select_advanced' !== $field['field_type'] ) { $field['ajax'] = false; } if ( 'checkbox_tree' === $field['field_type'] ) { $field['field_type'] = 'checkbox_list'; $field['flatten'] = false; } if ( 'radio_list' === $field['field_type'] ) { $field['field_type'] = 'radio'; } $field = call_user_func( [ self::get_type_class( $field ), 'normalize' ], $field ); return $field; } /** * Set ajax parameters. * * @param array $field Field settings. */ protected static function set_ajax_params( &$field ) { if ( ! $field['ajax'] ) { return; } if ( empty( $field['js_options']['ajax'] ) ) { $field['js_options']['ajax'] = []; } $field['js_options']['ajax'] = wp_parse_args( [ 'url' => admin_url( 'admin-ajax.php' ), ], $field['js_options']['ajax'] ); $field['js_options']['ajax_data'] = [ 'field' => [ 'id' => $field['id'], 'type' => $field['type'], 'query_args' => $field['query_args'], ], '_wpnonce' => wp_create_nonce( 'query' ), ]; } /** * Get the attributes for a field. * * @param array $field Field parameters. * @param mixed $value Meta value. * * @return array */ public static function get_attributes( $field, $value = null ) { $attributes = call_user_func( [ self::get_type_class( $field ), 'get_attributes' ], $field, $value ); if ( 'select_advanced' === $field['field_type'] ) { $attributes['class'] .= ' rwmb-select_advanced'; } elseif ( 'select' === $field['field_type'] ) { $attributes['class'] .= ' rwmb-select'; } return $attributes; } public static function admin_enqueue_scripts() { RWMB_Input_List_Field::admin_enqueue_scripts(); RWMB_Select_Field::admin_enqueue_scripts(); RWMB_Select_Tree_Field::admin_enqueue_scripts(); RWMB_Select_Advanced_Field::admin_enqueue_scripts(); // Field is the 1st param. $field = func_get_arg( 0 ); if ( empty( $field['add_new'] ) ) { return; } wp_enqueue_style( 'rwmb-modal', RWMB_CSS_URL . 'modal.css', [], RWMB_VER ); wp_style_add_data( 'rwmb-modal', 'path', RWMB_CSS_DIR . 'modal.css' ); wp_enqueue_script( 'rwmb-modal', RWMB_JS_URL . 'modal.js', [ 'jquery' ], RWMB_VER, true ); $type = $field['type'] === 'taxonomy_advanced' ? 'taxonomy' : $field['type']; wp_enqueue_script( "rwmb-$type", RWMB_JS_URL . "$type.js", [ 'jquery', 'rwmb-modal' ], RWMB_VER, true ); } /** * Get correct rendering class for the field. */ protected static function get_type_class( array $field ): string { return RWMB_Helpers_Field::get_class( [ 'type' => $field['field_type'] ] ); } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/oembed.php ================================================ __( 'Embed HTML not available.', 'meta-box' ), ] ); $field['attributes'] = wp_parse_args( $field['attributes'], [ 'data-not-available' => $field['not_available_string'], ] ); return $field; } public static function admin_enqueue_scripts() { wp_enqueue_style( 'rwmb-oembed', RWMB_CSS_URL . 'oembed.css', [], RWMB_VER ); wp_style_add_data( 'rwmb-oembed', 'path', RWMB_CSS_DIR . 'oembed.css' ); wp_enqueue_script( 'rwmb-oembed', RWMB_JS_URL . 'oembed.js', [ 'jquery', 'underscore', 'rwmb' ], RWMB_VER, true ); wp_localize_script( 'rwmb-oembed', 'rwmbOembed', [ 'nonce' => wp_create_nonce( 'oembed_get' ), ] ); } public static function add_actions() { add_action( 'wp_ajax_rwmb_get_embed', [ __CLASS__, 'ajax_get_embed' ] ); } public static function ajax_get_embed() { check_ajax_referer( 'oembed_get' ); $request = rwmb_request(); $url = (string) $request->filter_post( 'url', FILTER_SANITIZE_URL ); $not_available = (string) $request->post( 'not_available' ); wp_send_json_success( self::get_embed( $url, $not_available ) ); } /** * Get embed html from url. * * @param string $url URL. * @param string $not_available Not available string displayed to users. * @return string */ public static function get_embed( $url, $not_available = '' ) { /** * Set arguments for getting embedded HTML. * Without arguments, default width will be taken from global $content_width, which can break UI in the admin. * * @link https://github.com/rilwis/meta-box/issues/801 * @see WP_oEmbed::fetch() * @see WP_Embed::shortcode() * @see wp_embed_defaults() */ $args = []; if ( is_admin() ) { $args['width'] = 360; } // Try oembed first. $embed = wp_oembed_get( $url, $args ); // If no oembed provides found, try WordPress auto embed. if ( ! $embed ) { global $wp_embed; $temp = $wp_embed->return_false_on_fail; $wp_embed->return_false_on_fail = true; // Do not fallback to make a link. $embed = $wp_embed->shortcode( $args, $url ); $wp_embed->return_false_on_fail = $temp; } if ( $not_available ) { $not_available = '
      ' . wp_kses_post( $not_available ) . '
      '; } $not_available = apply_filters( 'rwmb_oembed_not_available_string', $not_available, $url ); return $embed ? $embed : $not_available; } /** * Get field HTML. * * @param mixed $meta Meta value. * @param array $field Field parameters. * @return string */ public static function html( $meta, $field ) { return parent::html( $meta, $field ) . sprintf( '
      %s
      ', $meta ? self::get_embed( $meta, $field['not_available_string'] ) : '' ); } /** * Get the attributes for a field. * * @param array $field Field parameters. * @param mixed $value Meta value. * * @return array */ public static function get_attributes( $field, $value = null ) { $attributes = parent::get_attributes( $field, $value ); $attributes['type'] = 'url'; return $attributes; } /** * Format a single value for the helper functions. Sub-fields should overwrite this method if necessary. * * @param array $field Field parameters. * @param string $value The value. * @param array $args Additional arguments. Rarely used. See specific fields for details. * @param int|null $post_id Post ID. null for current post. Optional. * * @return string */ public static function format_single_value( $field, $value, $args, $post_id ) { return self::get_embed( $value, $field['not_available_string'] ); } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/osm.php ================================================ __( 'No results found', 'meta-box' ), ] ); } /** * Get field HTML. * * @param mixed $meta Meta value. * @param array $field Field parameters. * * @return string */ public static function html( $meta, $field ) { $address = is_array( $field['address_field'] ) ? implode( ',', $field['address_field'] ) : $field['address_field']; $html = sprintf( '
      ', esc_attr( $address ) ); $attributes = self::get_attributes( $field, $meta ); $attributes['type'] = 'hidden'; $attributes['value'] = $meta; $html .= sprintf( '
      ', esc_attr( $field['std'] ), esc_attr( $field['region'] ), esc_attr( $field['language'] ), esc_attr( $field['marker_draggable'] ? 'true' : 'false' ), self::render_attributes( $attributes ) ); $html .= '
      '; return $html; } /** * Normalize parameters for field. * * @param array $field Field parameters. * * @return array */ public static function normalize( $field ) { $field = parent::normalize( $field ); $field = wp_parse_args( $field, [ 'std' => '', 'address_field' => '', 'language' => '', 'region' => '', 'marker_draggable' => true, ] ); return $field; } /** * Get the field value. * The difference between this function and 'meta' function is 'meta' function always returns the escaped value * of the field saved in the database, while this function returns more meaningful value of the field. * * @param array $field Field parameters. * @param array $args Not used for this field. * @param int|null $post_id Post ID. null for current post. Optional. * * @return mixed Array(latitude, longitude, zoom) */ public static function get_value( $field, $args = [], $post_id = null ) { $value = parent::get_value( $field, $args, $post_id ); if ( is_array( $value ) ) { $location = []; foreach ( $value as $clone ) { list( $latitude, $longitude, $zoom ) = explode( ',', $clone . ',,' ); $location[] = compact( 'latitude', 'longitude', 'zoom' ); } return $location; } list( $latitude, $longitude, $zoom ) = explode( ',', $value . ',,' ); return compact( 'latitude', 'longitude', 'zoom' ); } /** * Format value before render map * @param array $field Field settings. * @param mixed $value Field value. * @param mixed $args Additional arguments. * @param mixed $post_id Post ID. * @return string HTML. */ public static function format_single_value( $field, $value, $args, $post_id ) { return self::render_map( $value, $args ); } /** * Render a map in the frontend. * * @param string|array $location The "latitude,longitude[,zoom]" location. * @param array $args Additional arguments for the map. * * @return string */ public static function render_map( $location, $args = [] ) { // For compatibility with previous version, or within groups. if ( is_string( $location ) ) { list( $latitude, $longitude, $zoom ) = explode( ',', $location . ',,' ); } else { // phpcs:ignore WordPress.PHP.DontExtract.extract_extract extract( $location ); } if ( ! $latitude || ! $longitude ) { return ''; } $args = wp_parse_args( $args, [ 'latitude' => $latitude, 'longitude' => $longitude, 'width' => '100%', 'height' => '480px', 'marker' => true, // Display marker? 'marker_title' => '', // Marker title, when hover. 'info_window' => '', // Content of info window (when click on marker). HTML allowed. 'js_options' => [], 'zoom' => $zoom, ] ); self::enqueue_map_assets(); wp_enqueue_script( 'rwmb-osm-frontend', RWMB_JS_URL . 'osm-frontend.js', [ 'jquery', 'leaflet' ], RWMB_VER, true ); wp_enqueue_style( 'rwmb-osm-frontend', RWMB_CSS_URL . 'osm-frontend.css', [], RWMB_VER ); wp_style_add_data( 'rwmb-osm-frontend', 'path', RWMB_CSS_DIR . 'osm-frontend.css' ); /* * More Open Street Map options * @link https://leafletjs.com/reference-1.5.0.html#map-option */ $args['js_options'] = wp_parse_args( $args['js_options'], [ // Default to 'zoom' level set in admin, but can be overwritten. 'zoom' => $args['zoom'], ] ); $output = sprintf( '
      ', esc_attr( wp_json_encode( $args ) ), esc_attr( $args['width'] ), esc_attr( $args['height'] ) ); return $output; } private static function enqueue_map_assets() { wp_enqueue_style( 'leaflet', RWMB_JS_URL . 'leaflet/leaflet.css', [], '1.9.4' ); wp_style_add_data( 'leaflet', 'path', RWMB_JS_URL . 'leaflet/leaflet.css' ); wp_enqueue_script( 'leaflet', RWMB_JS_URL . 'leaflet/leaflet.js', [], '1.9.4', true ); wp_enqueue_style( 'leaflet-gesture-handling', RWMB_JS_URL . 'leaflet/leaflet-gesture-handling.min.css', [ 'leaflet' ], '1.2.2' ); wp_style_add_data( 'leaflet-gesture-handling', 'path', RWMB_JS_URL . 'leaflet/leaflet-gesture-handling.min.css' ); wp_enqueue_script( 'leaflet-gesture-handling', RWMB_JS_URL . 'leaflet/leaflet-gesture-handling.min.js', [ 'leaflet' ], '1.2.2', true ); } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/password.php ================================================ '; $output .= $button; return $output; } /** * Store secured password in the database. * * @param mixed $new The submitted meta value. * @param mixed $old The existing meta value. * @param int $post_id The post ID. * @param array $field The field parameters. * @return string */ public static function value( $new, $old, $post_id, $field ) { $new = $new !== $old ? wp_hash_password( $new ) : $new; return $new; } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/post.php ================================================ filter_post( 'field', FILTER_DEFAULT, FILTER_FORCE_ARRAY ); // Required for 'choice_label' filter. See self::filter(). $field['clone'] = false; $field['_original_id'] = $field['id']; // Search. $field['query_args']['s'] = $request->filter_post( 'term' ); // Pagination. if ( 'query:append' === $request->filter_post( '_type' ) ) { $field['query_args']['paged'] = $request->filter_post( 'page', FILTER_SANITIZE_NUMBER_INT ); } // Query the database. $items = self::query( null, $field ); $items = array_values( $items ); $items = apply_filters( 'rwmb_ajax_get_posts', $items, $field, $request ); $data = [ 'items' => $items ]; // More items for pagination. $limit = (int) $field['query_args']['posts_per_page']; if ( -1 !== $limit && count( $items ) === $limit ) { $data['more'] = true; } wp_send_json_success( $data ); } /** * Normalize parameters for field. * * @param array $field Field parameters. * @return array */ public static function normalize( $field ) { $field = wp_parse_args( $field, [ 'post_type' => 'post', 'parent' => false, 'query_args' => [], ] ); $field['post_type'] = (array) $field['post_type']; /* * Set default placeholder: * - If multiple post types: show 'Select a post'. * - If single post type: show 'Select a %post_type_name%'. */ $placeholder = __( 'Select a post', 'meta-box' ); if ( 1 === count( $field['post_type'] ) ) { $post_type = reset( $field['post_type'] ); $post_type_object = get_post_type_object( $post_type ); if ( ! empty( $post_type_object ) ) { // Translators: %s is the post singular label. $placeholder = sprintf( __( 'Select a %s', 'meta-box' ), strtolower( $post_type_object->labels->singular_name ) ); } } $field = wp_parse_args( $field, [ 'placeholder' => $placeholder, ] ); // Set parent option, which will change field name to `parent_id` to save as post parent. if ( $field['parent'] ) { $field['multiple'] = false; $field['field_name'] = 'parent_id'; } $field = parent::normalize( $field ); // Set default query args. $posts_per_page = $field['ajax'] ? 10 : -1; $field['query_args'] = wp_parse_args( $field['query_args'], [ 'post_type' => $field['post_type'], 'post_status' => 'publish', 'posts_per_page' => $posts_per_page, ] ); parent::set_ajax_params( $field ); return $field; } public static function query( $meta, array $field ): array { $args = wp_parse_args( $field['query_args'], [ 'no_found_rows' => true, 'update_post_meta_cache' => false, 'update_post_term_cache' => false, 'mb_field_id' => $field['id'], ] ); $meta = wp_parse_id_list( (array) $meta ); // Query only selected items. if ( ! empty( $field['ajax'] ) && ! empty( $meta ) ) { $args['posts_per_page'] = count( $meta ); $args['post__in'] = $meta; } // Get from cache to prevent same queries. $last_changed = wp_cache_get_last_changed( 'posts' ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize $key = md5( serialize( $args ) ); $cache_key = "$key:$last_changed"; $options = wp_cache_get( $cache_key, 'meta-box-post-field' ); if ( false !== $options ) { return $options; } // Only search by title. add_filter( 'posts_search', [ __CLASS__, 'search_by_title' ], 10, 2 ); $query = new WP_Query( $args ); remove_filter( 'posts_search', [ __CLASS__, 'search_by_title' ] ); $options = []; foreach ( $query->posts as $post ) { if ( ! current_user_can( 'read_post', $post ) ) { continue; } $label = $post->post_title ? $post->post_title : __( '(No title)', 'meta-box' ); $label = self::filter( 'choice_label', $label, $field, $post ); $options[ $post->ID ] = [ 'value' => $post->ID, 'label' => $label, 'parent' => $post->post_parent, ]; } // Cache the query. wp_cache_set( $cache_key, $options, 'meta-box-post-field' ); return $options; } /** * Only search posts by title. * WordPress searches by either title or content which is confused when users can't find their posts. * * @link https://developer.wordpress.org/reference/hooks/posts_search/ */ public static function search_by_title( $search, $wp_query ) { global $wpdb; if ( empty( $search ) ) { return $search; } $q = $wp_query->query_vars; $n = ! empty( $q['exact'] ) ? '' : '%'; $search = []; foreach ( (array) $q['search_terms'] as $term ) { $term = esc_sql( $wpdb->esc_like( $term ) ); $search[] = "($wpdb->posts.post_title LIKE '{$n}{$term}{$n}')"; } if ( empty( $search ) ) { return $search; } $search = ' AND (' . implode( ' AND ', $search ) . ') '; if ( ! is_user_logged_in() ) { $search .= " AND ($wpdb->posts.post_password = '') "; } return $search; } /** * Get meta value. * If field is cloneable, value is saved as a single entry in DB. * Otherwise value is saved as multiple entries (for backward compatibility). * * @see "save" method for better understanding * * @param int $post_id Post ID. * @param bool $saved Is the meta box saved. * @param array $field Field parameters. * * @return mixed */ public static function meta( $post_id, $saved, $field ) { return $field['parent'] ? wp_get_post_parent_id( $post_id ) : parent::meta( $post_id, $saved, $field ); } /** * Format a single value for the helper functions. Sub-fields should overwrite this method if necessary. * * @param array $field Field parameters. * @param int $value The value. * @param array $args Additional arguments. Rarely used. See specific fields for details. * @param ?int $post_id Post ID. null for current post. Optional. * * @return string */ public static function format_single_value( $field, $value, $args, $post_id ) { if ( empty( $value ) ) { return ''; } /** * Allow developers to change the value of the post. Used for WPML integration. * @var int|string $value The post ID. * @var array $field The field parameters. * @internal */ $value = apply_filters( '_rwmb_post_format_single_value', $value, $field ); $link = $args['link'] ?? 'view'; $text = get_the_title( $value ); if ( false === $link ) { return $text; } $url = get_permalink( $value ); if ( 'edit' === $link ) { $url = get_edit_post_link( $value ); } return sprintf( '%s', esc_url( $url ), wp_kses_post( $text ) ); } public static function add_new_form( array $field ): string { if ( ! current_user_can( 'edit_posts' ) ) { return ''; } if ( 1 !== count( $field['post_type'] ) ) { return ''; } $post_type = reset( $field['post_type'] ); if ( ! post_type_exists( $post_type ) ) { return ''; } $post_type_object = get_post_type_object( $post_type ); return sprintf( '%s', admin_url( $post_type === 'post' ? 'post-new.php' : 'post-new.php?post_type=' . $post_type ), esc_html( $post_type_object->labels->add_new_item ) ); } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/radio.php ================================================ %s %s ', parent::html( $meta, $field ), $meta ); } public static function admin_enqueue_scripts() { wp_enqueue_style( 'rwmb-range', RWMB_CSS_URL . 'range.css', [], RWMB_VER ); wp_style_add_data( 'rwmb-range', 'path', RWMB_CSS_DIR . 'range.css' ); wp_enqueue_script( 'rwmb-range', RWMB_JS_URL . 'range.js', [], RWMB_VER, true ); } /** * Normalize parameters for field. * * @param array $field Field parameters. * @return array */ public static function normalize( $field ) { $field = wp_parse_args( $field, [ 'max' => 10, ] ); $field = parent::normalize( $field ); return $field; } /** * Ensure number in range. * * @param mixed $new The submitted meta value. * @param mixed $old The existing meta value. * @param int $post_id The post ID. * @param array $field The field parameters. * * @return int */ public static function value( $new, $old, $post_id, $field ) { $new = (float) $new; $min = (float) $field['min']; $max = (float) $field['max']; if ( $new < $min ) { return $min; } if ( $new > $max ) { return $max; } return $new; } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/select-advanced.php ================================================ is_admin(), ]); } /** * Normalize parameters for field. * * @param array $field Field parameters. * @return array */ public static function normalize( $field ) { $field = wp_parse_args( $field, [ 'js_options' => [], 'placeholder' => __( 'Select an item', 'meta-box' ), ] ); $field = parent::normalize( $field ); $field['js_options'] = wp_parse_args( $field['js_options'], [ 'allowClear' => true, 'dropdownAutoWidth' => true, 'placeholder' => $field['placeholder'], 'width' => 'style', ] ); return $field; } /** * Get the attributes for a field. * * @param array $field Field parameters. * @param mixed $value Meta value. * @return array */ public static function get_attributes( $field, $value = null ) { $attributes = parent::get_attributes( $field, $value ); $attributes = wp_parse_args( $attributes, [ 'data-options' => wp_json_encode( $field['js_options'] ), ] ); return $attributes; } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/select-tree.php ================================================ walk( $options ) : ''; } public static function admin_enqueue_scripts() { parent::admin_enqueue_scripts(); wp_enqueue_style( 'rwmb-select-tree', RWMB_CSS_URL . 'select-tree.css', [ 'rwmb-select' ], RWMB_VER ); wp_style_add_data( 'rwmb-select-tree', 'path', RWMB_CSS_DIR . 'select-tree.css' ); wp_enqueue_script( 'rwmb-select-tree', RWMB_JS_URL . 'select-tree.js', [ 'rwmb-select' ], RWMB_VER, true ); } /** * Normalize parameters for field. * * @param array $field Field parameters. * @return array */ public static function normalize( $field ) { $field['multiple'] = true; $field['size'] = 0; $field = parent::normalize( $field ); return $field; } /** * Get the attributes for a field. * * @param array $field Field parameters. * @param mixed $value Meta value. * * @return array */ public static function get_attributes( $field, $value = null ) { $attributes = parent::get_attributes( $field, $value ); $attributes['multiple'] = false; $attributes['id'] = false; return $attributes; } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/select.php ================================================ ', self::render_attributes( $attributes ) ); if ( ! $field['multiple'] && $field['placeholder'] ) { $output .= ''; } $output .= $walker->walk( $options, $field['flatten'] ? -1 : 0 ); $output .= ''; $output .= self::get_select_all_html( $field ); return $output; } /** * Normalize parameters for field. * * @param array $field Field parameters. * @return array */ public static function normalize( $field ) { $field = parent::normalize( $field ); $field = $field['multiple'] ? RWMB_Multiple_Values_Field::normalize( $field ) : $field; $field = wp_parse_args( $field, [ 'select_all_none' => false, ] ); return $field; } /** * Get the attributes for a field. * * @param array $field Field parameters. * @param mixed $value Meta value. * * @return array */ public static function get_attributes( $field, $value = null ) { $attributes = parent::get_attributes( $field, $value ); $attributes = wp_parse_args( $attributes, [ 'multiple' => $field['multiple'], ] ); return $attributes; } /** * Get html for select all|none for multiple select. * * @param array $field Field parameters. * @return string */ public static function get_select_all_html( $field ) { if ( $field['multiple'] && $field['select_all_none'] ) { return ''; } return ''; } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/sidebar.php ================================================ __( 'Select a sidebar', 'meta-box' ), ] ); $field = parent::normalize( $field ); return $field; } public static function query( $meta, array $field ): array { global $wp_registered_sidebars; $options = []; foreach ( $wp_registered_sidebars as $sidebar ) { $options[ $sidebar['id'] ] = [ 'value' => $sidebar['id'], 'label' => $sidebar['name'], ]; } return $options; } /** * Format a single value for the helper functions. Sub-fields should overwrite this method if necessary. * * @param array $field Field parameters. * @param string $value The value. * @param array $args Additional arguments. Rarely used. See specific fields for details. * @param int|null $post_id Post ID. null for current post. Optional. * * @return string */ public static function format_single_value( $field, $value, $args, $post_id ) { if ( ! is_active_sidebar( $value ) ) { return ''; } ob_start(); dynamic_sidebar( $value ); return ob_get_clean(); } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/single-image.php ================================================ '', 'data-single-image' => 1, ] ); $field['attributes']['class'] .= ' rwmb-image_advanced'; $field['multiple'] = false; return $field; } /** * Get meta values to save. * * @param mixed $new The submitted meta value. * @param mixed $old The existing meta value. * @param int $post_id The post ID. * @param array $field The field parameters. * * @return array|mixed */ public static function value( $new, $old, $post_id, $field ) { return $new; } /** * Get the field value. Return meaningful info of the files. * * @param array $field Field parameters. * @param array $args Not used for this field. * @param int|null $post_id Post ID. null for current post. Optional. * * @return mixed Full info of uploaded files */ public static function get_value( $field, $args = [], $post_id = null ) { $value = RWMB_Field::get_value( $field, $args, $post_id ); if ( ! is_array( $value ) ) { return RWMB_Image_Field::file_info( $value, $args, $field ); } $return = []; foreach ( $value as $image_id ) { $return[] = RWMB_Image_Field::file_info( $image_id, $args, $field ); } return $return; } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/slider.php ================================================
      %s%s%s ', $field['id'], esc_attr( wp_json_encode( $field['js_options'] ) ), $field['prefix'], $meta, $field['suffix'], $meta, self::render_attributes( $attributes ) ); } /** * Normalize parameters for field. * * @param array $field Field parameters. * * @return array */ public static function normalize( $field ) { $field = parent::normalize( $field ); $field = wp_parse_args( $field, [ 'prefix' => '', 'suffix' => '', 'std' => '', 'js_options' => [], ] ); $field['js_options'] = wp_parse_args( $field['js_options'], [ 'range' => 'min', // range = 'min' will add a dark background to sliding part, better UI. 'value' => $field['std'], ] ); return $field; } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/switch.php ================================================
      ' . $field['on_label'] . ' ' . $field['off_label'] . '
      ', self::render_attributes( $attributes ), checked( ! empty( $meta ), 1, false ) ); return $output; } /** * Normalize parameters for field. * * @param array $field Field parameters. * * @return array */ public static function normalize( $field ) { $field = parent::normalize( $field ); $field = wp_parse_args( $field, [ 'style' => 'rounded', 'on_label' => '', 'off_label' => '', ] ); return $field; } /** * Get the attributes for a field. * * @param array $field The field parameters. * @param mixed $value The attribute value. * * @return array */ public static function get_attributes( $field, $value = null ) { $attributes = parent::get_attributes( $field, $value ); $attributes['type'] = 'checkbox'; return $attributes; } /** * Format a single value for the helper functions. Sub-fields should overwrite this method if necessary. * * @param array $field Field parameters. * @param string $value The value. * @param array $args Additional arguments. Rarely used. See specific fields for details. * @param int|null $post_id Post ID. null for current post. Optional. * * @return string */ public static function format_single_value( $field, $value, $args, $post_id ) { $on = $field['on_label'] ?: __( 'On', 'meta-box' ); $off = $field['off_label'] ?: __( 'Off', 'meta-box' ); return $value ? $on : $off; } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/taxonomy-advanced.php ================================================ $field['taxonomy'], 'include' => $term_ids, 'hide_empty' => false, ], $args ); $info = get_terms( $args ); $info = is_array( $info ) ? $info : []; return $field['multiple'] ? $info : reset( $info ); } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/taxonomy.php ================================================ filter_post( 'field', FILTER_DEFAULT, FILTER_FORCE_ARRAY ); // Required for 'choice_label' filter. See self::filter(). $field['clone'] = false; $field['_original_id'] = $field['id']; // Search. $field['query_args']['name__like'] = $request->filter_post( 'term' ); // Pagination. $limit = $field['query_args']['number'] ?? 0; $limit = (int) $limit; if ( 'query:append' === $request->filter_post( '_type' ) ) { $page = $request->filter_post( 'page', FILTER_SANITIZE_NUMBER_INT ); $field['query_args']['offset'] = $limit * ( $page - 1 ); } // Query the database. $items = self::query( null, $field ); $items = array_values( $items ); $items = apply_filters( 'rwmb_ajax_get_terms', $items, $field, $request ); $data = [ 'items' => $items ]; // More items for pagination. if ( $limit && count( $items ) === $limit ) { $data['more'] = true; } wp_send_json_success( $data ); } /** * Add default value for 'taxonomy' field. * * @param array $field Field parameters. * @return array */ public static function normalize( $field ) { // Backwards compatibility with field args. if ( isset( $field['options']['args'] ) ) { $field['query_args'] = $field['options']['args']; } if ( isset( $field['options']['taxonomy'] ) ) { $field['taxonomy'] = $field['options']['taxonomy']; } if ( isset( $field['options']['type'] ) ) { $field['field_type'] = $field['options']['type']; } // Set default field args. $field = wp_parse_args( $field, [ 'taxonomy' => 'category', 'query_args' => [], 'remove_default' => false, ] ); // Force taxonomy to be an array. $field['taxonomy'] = (array) $field['taxonomy']; /* * Set default placeholder: * - If multiple taxonomies: show 'Select a term'. * - If single taxonomy: show 'Select a %taxonomy_name%'. */ $placeholder = __( 'Select a term', 'meta-box' ); $taxonomy_name = self::get_taxonomy_singular_name( $field ); if ( $taxonomy_name ) { // Translators: %s is the taxonomy singular label. $placeholder = sprintf( __( 'Select a %s', 'meta-box' ), strtolower( $taxonomy_name ) ); } $field = wp_parse_args( $field, [ 'placeholder' => $placeholder, ] ); $field = parent::normalize( $field ); // Set default query args. $limit = $field['ajax'] ? 10 : 0; $field['query_args'] = wp_parse_args( $field['query_args'], [ 'taxonomy' => $field['taxonomy'], 'number' => $limit, ] ); parent::set_ajax_params( $field ); // Prevent cloning for taxonomy field, not for child fields (taxonomy_advanced). if ( 'taxonomy' === $field['type'] ) { $field['clone'] = false; } return $field; } public static function query( $meta, array $field ): array { $args = wp_parse_args( $field['query_args'], [ 'hide_empty' => false, 'count' => false, 'update_term_meta_cache' => false, ] ); $meta = wp_parse_id_list( (array) $meta ); // Query only selected items. if ( ! empty( $field['ajax'] ) && ! empty( $meta ) ) { $args['include'] = $meta; $args['number'] = count( $meta ); } $terms = get_terms( $args ); if ( ! is_array( $terms ) ) { return []; } $options = []; foreach ( $terms as $term ) { $label = $term->name ? $term->name : __( '(No title)', 'meta-box' ); $label = self::filter( 'choice_label', $label, $field, $term ); $options[ $term->term_id ] = [ 'value' => $term->term_id, 'label' => $label, 'parent' => $term->parent, ]; } return $options; } /** * Get meta values to save. * * @param mixed $new The submitted meta value. * @param mixed $old The existing meta value. * @param int $post_id The post ID. * @param array $field The field parameters. * * @return array */ public static function value( $new, $old, $post_id, $field ) { $new = (array) $new; $new[] = self::add_term( $field ); $new = array_filter( wp_parse_id_list( $new ) ); return $new; } /** * Save meta value. * * @param mixed $new The submitted meta value. * @param mixed $old The existing meta value. * @param int $post_id The post ID. * @param array $field The field parameters. */ public static function save( $new, $old, $post_id, $field ) { if ( empty( $field['id'] ) || ! $field['save_field'] ) { return; } foreach ( $field['taxonomy'] as $taxonomy ) { wp_set_object_terms( $post_id, $new, $taxonomy ); } } /** * Add new terms if users created some. * * @param array $field Field settings. * @return int|null Term ID if added successfully, null otherwise. */ protected static function add_term( $field ) { $term = rwmb_request()->post( $field['id'] . '_new' ); if ( ! $field['add_new'] || ! $term || 1 !== count( $field['taxonomy'] ) ) { return null; } $taxonomy = reset( $field['taxonomy'] ); $term = wp_insert_term( $term, $taxonomy ); if ( is_wp_error( $term ) ) { return null; } return $term['term_id'] ?? null; } /** * Get raw meta value. * * @param int $object_id Object ID. * @param array $field Field parameters. * @param array $args Arguments of {@see rwmb_meta()} helper. * * @return mixed */ public static function raw_meta( $object_id, $field, $args = [] ) { if ( empty( $field['id'] ) ) { return ''; } $meta = wp_get_object_terms( $object_id, $field['taxonomy'], [ 'orderby' => 'term_order', ] ); $meta = wp_list_pluck( $meta, 'term_id' ); return $field['multiple'] ? $meta : reset( $meta ); } /** * Get the field value. * Return list of post term objects. * * @param array $field Field parameters. * @param array $args Additional arguments. * @param ?int $post_id Post ID. * * @return array List of post term objects. */ public static function get_value( $field, $args = [], $post_id = null ) { if ( ! $post_id ) { $post_id = get_the_ID(); } $value = wp_get_object_terms( $post_id, $field['taxonomy'], [ 'orderby' => 'term_order', ] ); // Get single value if necessary. if ( ! $field['clone'] && ! $field['multiple'] ) { $value = reset( $value ); } return $value; } /** * Format a single value for the helper functions. * * @param array $field Field parameters. * @param WP_Term $value The term object. * @param array $args Additional arguments. Rarely used. See specific fields for details. * @param ?int $post_id Post ID. null for current post. Optional. * * @return string */ public static function format_single_value( $field, $value, $args, $post_id ) { if ( empty( $value ) ) { return ''; } $link = $args['link'] ?? 'view'; $text = $value->name; if ( false === $link ) { return $text; } $url = get_term_link( $value ); if ( 'edit' === $link ) { $url = get_edit_term_link( $value ); } return sprintf( '%s', esc_url( $url ), esc_html( $text ) ); } public static function add_new_form( array $field ): string { if ( ! current_user_can( 'edit_posts' ) ) { return ''; } // Only add new term if field has only one taxonomy. if ( 1 !== count( $field['taxonomy'] ) ) { return ''; } $taxonomy = reset( $field['taxonomy'] ); $taxonomy_object = get_taxonomy( $taxonomy ); if ( false === $taxonomy_object ) { return ''; } return sprintf( '%s', admin_url( 'edit-tags.php?taxonomy=' . $taxonomy_object->name ), esc_html( $taxonomy_object->labels->add_new_item ) ); } public static function admin_enqueue_scripts() { $field = func_get_arg( 0 ); parent::admin_enqueue_scripts( $field ); static::remove_default_meta_box( $field ); } protected static function remove_default_meta_box( array $field ) { if ( empty( $field['remove_default'] ) || ! function_exists( 'remove_meta_box' ) ) { return; } // Only run in admin. if ( ! is_admin() ) { return; } // Do nothing if in Ajax or Rest API. if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) { return; } if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) { return; } foreach ( $field['taxonomy'] as $taxonomy ) { $id = is_taxonomy_hierarchical( $taxonomy ) ? "{$taxonomy}div" : "tagsdiv-{$taxonomy}"; remove_meta_box( $id, null, 'side' ); } } protected static function get_taxonomy_singular_name( array $field ): string { if ( 1 !== count( $field['taxonomy'] ) ) { return ''; } $taxonomy = reset( $field['taxonomy'] ); $taxonomy_object = get_taxonomy( $taxonomy ); return false === $taxonomy_object ? '' : $taxonomy_object->labels->singular_name; } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/text-list.php ================================================ %s '; $attributes = self::get_attributes( $field, $meta ); $attributes['type'] = 'text'; $count = 0; foreach ( $field['options'] as $placeholder => $label ) { $attributes['value'] = $meta[ $count ] ?? ''; $attributes['placeholder'] = $placeholder; $html[] = sprintf( $input, $label, self::render_attributes( $attributes ) ); ++$count; } return implode( ' ', $html ); } /** * Normalize parameters for field. * * @param array $field Field parameters. * * @return array */ public static function normalize( $field ) { $field = parent::normalize( $field ); if ( ! $field['clone'] ) { $field['class'] .= ' rwmb-text_list-non-cloneable'; } return $field; } /** * Set value of meta before saving into database. * Do not save if all inputs has no value. * * @param mixed $new The submitted meta value. * @param mixed $old The existing meta value. * @param int $post_id The post ID. * @param array $field The field parameters. * * @return mixed */ public static function value( $new, $old, $post_id, $field ) { $filtered = array_filter( $new ); return count( $filtered ) ? $new : []; } /** * Format value for the helper functions. * * @param array $field Field parameters. * @param string|array $value The field meta value. * @param array $args Additional arguments. Rarely used. See specific fields for details. * @param int|null $post_id Post ID. null for current post. Optional. * * @return string */ public static function format_value( $field, $value, $args, $post_id ) { $output = ''; foreach ( $field['options'] as $label ) { $output .= ""; } $output .= ''; if ( ! $field['clone'] ) { $output .= self::format_single_value( $field, $value, $args, $post_id ); } else { foreach ( $value as $subvalue ) { $output .= self::format_single_value( $field, $subvalue, $args, $post_id ); } } $output .= '
      $label
      '; return $output; } /** * Format a single value for the helper functions. Sub-fields should overwrite this method if necessary. * * @param array $field Field parameters. * @param array $value The value. * @param array $args Additional arguments. Rarely used. See specific fields for details. * @param int|null $post_id Post ID. null for current post. Optional. * * @return string */ public static function format_single_value( $field, $value, $args, $post_id ) { $output = ''; foreach ( $value as $subvalue ) { $output .= "$subvalue"; } $output .= ''; return $output; } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/textarea.php ================================================ %s', self::render_attributes( $attributes ), esc_textarea( $meta ) ); } /** * Normalize parameters for field. * * @param array $field Field parameters. * @return array */ public static function normalize( $field ) { $field = parent::normalize( $field ); $field = wp_parse_args( $field, [ 'autocomplete' => false, 'cols' => false, 'rows' => 3, 'maxlength' => false, 'minlength' => false, 'wrap' => false, 'readonly' => false, ] ); return $field; } /** * Get the attributes for a field. * * @param array $field Field parameters. * @param mixed $value Meta value. * * @return array */ public static function get_attributes( $field, $value = null ) { $attributes = parent::get_attributes( $field, $value ); $attributes = wp_parse_args( $attributes, [ 'autocomplete' => $field['autocomplete'], 'cols' => $field['cols'], 'rows' => $field['rows'], 'maxlength' => $field['maxlength'], 'minlength' => $field['minlength'], 'wrap' => $field['wrap'], 'readonly' => $field['readonly'], 'placeholder' => $field['placeholder'], ] ); return $attributes; } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/time.php ================================================ filter_post( 'field', FILTER_DEFAULT, FILTER_FORCE_ARRAY ); // Required for 'choice_label' filter. See self::filter(). $field['clone'] = false; $field['_original_id'] = $field['id']; // Search. $term = (string) $request->filter_post( 'term' ); if ( $term ) { $field['query_args']['search'] = "*{$term}*"; } // Pagination. $limit = $field['query_args']['number'] ?? 0; $limit = (int) $limit; if ( $limit && 'query:append' === $request->filter_post( '_type' ) ) { $field['query_args']['paged'] = $request->filter_post( 'page', FILTER_SANITIZE_NUMBER_INT ); } // Query the database. $items = self::query( null, $field ); $items = array_values( $items ); $items = apply_filters( 'rwmb_ajax_get_users', $items, $field, $request ); $data = [ 'items' => $items ]; // More items for pagination. if ( $limit && count( $items ) === $limit ) { $data['more'] = true; } wp_send_json_success( $data ); } /** * Update object cache to make sure query method below always get the fresh list of users. * Unlike posts and terms, WordPress doesn't set 'last_changed' for users. * So we have to do it ourselves. * * @see clean_post_cache() */ public static function update_cache() { wp_cache_set( 'last_changed', microtime(), 'users' ); } /** * Normalize parameters for field. * * @param array $field Field parameters. * * @return array */ public static function normalize( $field ) { // Set default field args. $field = wp_parse_args( $field, [ 'placeholder' => __( 'Select a user', 'meta-box' ), 'query_args' => [], 'display_field' => 'display_name', ] ); $field = parent::normalize( $field ); // Set default query args. $limit = $field['ajax'] ? 10 : 0; $field['query_args'] = wp_parse_args( $field['query_args'], [ 'number' => $limit, ] ); parent::set_ajax_params( $field ); if ( $field['ajax'] ) { $field['js_options']['ajax_data']['field']['display_field'] = $field['display_field']; } return $field; } public static function query( $meta, array $field ): array { $display_field = $field['display_field']; $args = wp_parse_args( $field['query_args'], [ 'orderby' => $display_field, 'order' => 'asc', ] ); $args['fields'] = [ 'ID', 'user_login', 'user_nicename', 'user_url', 'user_registered', 'user_status', 'display_name', ]; $meta = wp_parse_id_list( (array) $meta ); // Query only selected items. if ( ! empty( $field['ajax'] ) && ! empty( $meta ) ) { $args['include'] = $meta; $args['number'] = count( $meta ); } // Get from cache to prevent same queries. $last_changed = wp_cache_get_last_changed( 'users' ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize $key = md5( serialize( $args ) ); $cache_key = "$key:$last_changed"; $options = wp_cache_get( $cache_key, 'meta-box-user-field' ); if ( false !== $options ) { return $options; } $users = get_users( $args ); $options = []; foreach ( $users as $user ) { $label = $user->$display_field ?? __( '(No title)', 'meta-box' ); $label = self::filter( 'choice_label', $label, $field, $user ); $options[ $user->ID ] = [ 'value' => $user->ID, 'label' => $label, ]; } // Cache the query. wp_cache_set( $cache_key, $options, 'meta-box-user-field' ); return $options; } /** * Format a single value for the helper functions. Sub-fields should overwrite this method if necessary. * * @param array $field Field parameters. * @param int $value User ID. * @param array $args Additional arguments. Rarely used. See specific fields for details. * @param int|null $post_id Post ID. null for current post. Optional. * * @return string */ public static function format_single_value( $field, $value, $args, $post_id ) { if ( empty( $value ) ) { return ''; } $link = $args['link'] ?? 'view'; $user = get_userdata( $value ); $display_field = $field['display_field']; $text = $user->$display_field; if ( false === $link ) { return $text; } $url = get_author_posts_url( $value ); if ( 'edit' === $link ) { $url = get_edit_user_link( $value ); } return sprintf( '%s', esc_url( $url ), esc_html( $text ) ); } public static function add_new_form( array $field ): string { if ( ! current_user_can( 'create_users' ) ) { return ''; } return sprintf( '%s', admin_url( 'user-new.php' ), esc_html__( 'Add New User', 'meta-box' ) ); } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/video.php ================================================ wp_get_video_extensions(), ] ); } /** * Normalize parameters for field. * * @param array $field Field parameters. * * @return array */ public static function normalize( $field ) { $field['mime_type'] = 'video'; $field = parent::normalize( $field ); return $field; } /** * Get uploaded file information. * * @param int $file_id Attachment image ID (post ID). Required. * @param array $args Array of arguments (for size). * @param array $field Field settings. * * @return array|bool False if file not found. Array of image info on success. */ public static function file_info( $file_id, $args = [], $field = [] ) { if ( ! get_attached_file( $file_id ) ) { return false; } $attachment = get_post( $file_id ); $url = wp_get_attachment_url( $attachment->ID ); $file_type = wp_check_filetype( $url, wp_get_mime_types() ); $data = [ 'ID' => $file_id, 'src' => $url, 'type' => $file_type['type'], 'title' => $attachment->post_title, 'caption' => $attachment->post_excerpt, 'description' => $attachment->post_content, ]; $data['meta'] = []; $meta = wp_get_attachment_metadata( $attachment->ID ); if ( ! empty( $meta ) ) { foreach ( wp_get_attachment_id3_keys( $attachment ) as $key => $label ) { if ( ! empty( $meta[ $key ] ) ) { $data['meta'][ $key ] = $meta[ $key ]; } } if ( ! empty( $meta['width'] ) && ! empty( $meta['height'] ) ) { $data['dimensions'] = [ 'width' => $meta['width'], 'height' => $meta['height'], ]; } else { $data['dimensions'] = [ 'width' => 640, 'height' => 360, ]; } } $thumb_id = get_post_thumbnail_id( $attachment->ID ); if ( ! empty( $thumb_id ) ) { list( $src, $width, $height ) = wp_get_attachment_image_src( $thumb_id, 'full' ); $data['image'] = compact( 'src', 'width', 'height' ); list( $src, $width, $height ) = wp_get_attachment_image_src( $thumb_id, 'thumbnail' ); $data['thumb'] = compact( 'src', 'width', 'height' ); } else { $src = wp_mime_type_icon( $attachment->ID ); $width = 48; $height = 64; $data['image'] = compact( 'src', 'width', 'height' ); $data['thumb'] = compact( 'src', 'width', 'height' ); } return $data; } /** * Format value for a clone. * * @param array $field Field parameters. * @param string|array $value The field meta value. * @param array $args Additional arguments. Rarely used. See specific fields for details. * @param int|null $post_id Post ID. null for current post. Optional. * * @return string */ public static function format_clone_value( $field, $value, $args, $post_id ) { $ids = implode( ',', wp_list_pluck( $value, 'ID' ) ); // Display single video. if ( 1 === count( $value ) ) { $video = reset( $value ); return wp_video_shortcode( [ 'src' => $video['src'], 'width' => $video['dimensions']['width'], 'height' => $video['dimensions']['height'], ] ); } // Display multiple videos in a playlist. return wp_playlist_shortcode( [ 'ids' => $ids, 'type' => 'video', ] ); } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/fields/wysiwyg.php ================================================ '; echo ''; return ob_get_clean(); } /** * Normalize parameters for field. * * @param array $field Field parameters. * @return array */ public static function normalize( $field ) { $field = parent::normalize( $field ); $field = wp_parse_args( $field, [ 'raw' => false, 'options' => [], ] ); $field['options'] = wp_parse_args( $field['options'], [ 'editor_class' => 'rwmb-wysiwyg', 'dfw' => true, // Use default WordPress full screen UI. ] ); // Keep the filter to be compatible with previous versions. $field['options'] = apply_filters( 'rwmb_wysiwyg_settings', $field['options'] ); return $field; } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/functions.php ================================================ 'post', 'type' => '', ] ); /** * Filter meta type from object type and object id. * * @var string Meta type, default is post type name. * @var string Object type. * @var ?string|?int Object id. */ $type = apply_filters( 'rwmb_meta_type', $args['type'], $args['object_type'], $object_id ); if ( ! $type ) { $type = get_post_type( $object_id ); } return rwmb_get_registry( 'field' )->get( $key, $type, $args['object_type'] ); } } if ( ! function_exists( 'rwmb_meta_legacy' ) ) { /** * Get post meta. * * @param string $key Meta key. Required. * @param array $args Array of arguments. Optional. * @param int|null $post_id Post ID. null for current post. Optional. * * @return mixed */ function rwmb_meta_legacy( $key, $args = [], $post_id = null ) { $args = wp_parse_args( $args, [ 'type' => 'text', 'multiple' => false, 'clone' => false, ] ); $field = [ 'id' => $key, 'type' => $args['type'], 'clone' => $args['clone'], 'multiple' => $args['multiple'], ]; $method = 'get_value'; switch ( $args['type'] ) { case 'taxonomy': case 'taxonomy_advanced': $field['taxonomy'] = $args['taxonomy']; break; case 'map': case 'osm': case 'oembed': $method = 'the_value'; break; } $field = RWMB_Field::call( 'normalize', $field ); return RWMB_Field::call( $method, $field, $args, $post_id ); } } if ( ! function_exists( 'rwmb_get_value' ) ) { /** * Get value of custom field. * This is used to replace old version of rwmb_meta key. * * @param string $field_id Field ID. Required. * @param array $args Additional arguments. Rarely used. See specific fields for details. * @param int|null $post_id Post ID. null for current post. Optional. * * @return mixed false if field doesn't exist. Field value otherwise. */ function rwmb_get_value( $field_id, $args = [], $post_id = null ) { $args = wp_parse_args( $args ); $field = rwmb_get_field_settings( $field_id, $args, $post_id ); // Get field value. $value = $field ? RWMB_Field::call( 'get_value', $field, $args, $post_id ) : false; /* * Allow developers to change the returned value of field. * For version < 4.8.2, the filter name was 'rwmb_get_field'. * * @param mixed $value Field value. * @param array $field Field parameters. * @param array $args Additional arguments. Rarely used. See specific fields for details. * @param int|null $post_id Post ID. null for current post. Optional. */ $value = apply_filters( 'rwmb_get_value', $value, $field, $args, $post_id ); return $value; } } if ( ! function_exists( 'rwmb_the_value' ) ) { /** * Display the value of a field * * @param string $field_id Field ID. Required. * @param array $args Additional arguments. Rarely used. See specific fields for details. * @param int|null $post_id Post ID. null for current post. Optional. * @param bool $echo Display field meta value? Default `true` which works in almost all cases. We use `false` for the [rwmb_meta] shortcode. * * @return string */ function rwmb_the_value( $field_id, $args = [], $post_id = null, $echo = true ) { $args = wp_parse_args( $args ); $field = rwmb_get_field_settings( $field_id, $args, $post_id ); if ( ! $field ) { return ''; } $output = RWMB_Field::call( 'the_value', $field, $args, $post_id ); /* * Allow developers to change the returned value of field. * For version < 4.8.2, the filter name was 'rwmb_get_field'. * * @param mixed $value Field HTML output. * @param array $field Field parameters. * @param array $args Additional arguments. Rarely used. See specific fields for details. * @param int|null $post_id Post ID. null for current post. Optional. */ $output = apply_filters( 'rwmb_the_value', $output, $field, $args, $post_id ); if ( $echo ) { echo $output; // phpcs:ignore WordPress.Security.EscapeOutput } return $output; } } if ( ! function_exists( 'rwmb_get_object_fields' ) ) { /** * Get defined meta fields for object. * * @param int|string $type_or_id Object ID or post type / taxonomy (for terms) / user (for users). * @param string $object_type Object type. Use post, term. * * @return array */ function rwmb_get_object_fields( $type_or_id, $object_type = 'post' ) { $meta_boxes = rwmb_get_registry( 'meta_box' )->get_by( [ 'object_type' => $object_type ] ); array_walk( $meta_boxes, 'rwmb_check_meta_box_supports', [ $object_type, $type_or_id ] ); $meta_boxes = array_filter( $meta_boxes ); $fields = []; foreach ( $meta_boxes as $meta_box ) { foreach ( $meta_box->fields as $field ) { $fields[ $field['id'] ] = $field; } } return $fields; } } if ( ! function_exists( 'rwmb_check_meta_box_supports' ) ) { /** * Check if a meta box supports an object. * * @param object $meta_box Meta Box object. * @param int $key Not used. * @param array $object_data Object data (type and ID). */ function rwmb_check_meta_box_supports( &$meta_box, $key, $object_data ) { list( $object_type, $type_or_id ) = $object_data; $type = null; $prop = null; switch ( $object_type ) { case 'post': $type = is_numeric( $type_or_id ) ? get_post_type( $type_or_id ) : $type_or_id; $prop = 'post_types'; break; case 'term': $type = $type_or_id; if ( is_numeric( $type_or_id ) ) { $term = get_term( $type_or_id ); $type = is_wp_error( $term ) || ! $term ? null : $term->taxonomy; } $prop = 'taxonomies'; break; case 'user': $type = 'user'; $prop = 'user'; break; case 'setting': $type = $type_or_id; $prop = 'settings_pages'; break; } if ( ! $type ) { $meta_box = false; return; } if ( isset( $meta_box->meta_box[ $prop ] ) && ! in_array( $type, $meta_box->meta_box[ $prop ], true ) ) { $meta_box = false; } } } if ( ! function_exists( 'rwmb_get_registry' ) ) { /** * Get the registry by type. * Always return the same instance of the registry. * * @param string $type Registry type. * * @return object */ function rwmb_get_registry( $type ) { static $data = []; $class = 'RWMB_' . RWMB_Helpers_String::title_case( $type ) . '_Registry'; if ( ! isset( $data[ $type ] ) ) { $data[ $type ] = new $class(); } return $data[ $type ]; } } if ( ! function_exists( 'rwmb_get_storage' ) ) { /** * Get storage instance. * * @param string $object_type Object type. Use post or term. * @param RW_Meta_Box $meta_box Meta box object. Optional. * @return RWMB_Storage_Interface */ function rwmb_get_storage( $object_type, $meta_box = null ) { $class = 'RWMB_' . RWMB_Helpers_String::title_case( $object_type ) . '_Storage'; $class = class_exists( $class ) ? $class : 'RWMB_Post_Storage'; $storage = rwmb_get_registry( 'storage' )->get( $class ); return apply_filters( 'rwmb_get_storage', $storage, $object_type, $meta_box ); } } if ( ! function_exists( 'rwmb_request' ) ) { /** * Get request object. * * @return RWMB_Request */ function rwmb_request() { static $request; if ( ! $request ) { $request = new RWMB_Request(); } return $request; } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/helpers/array.php ================================================ get_data( $handle, 'data' ) ) { wp_localize_script( $handle, $name, $data ); } } public static function add_inline_script_once( string $handle, string $text ) { if ( ! wp_scripts()->get_data( $handle, 'after' ) ) { wp_add_inline_script( $handle, $text ); } } public static function get_class( $field ): string { $type = self::get_type( $field ); $class = 'RWMB_' . RWMB_Helpers_String::title_case( $type ) . '_Field'; $class = apply_filters( 'rwmb_field_class', $class, $type ); return class_exists( $class ) ? $class : 'RWMB_Input_Field'; } private static function get_type( $field ): string { $type = $field['type'] ?? 'text'; $map = array_merge( [ $type => $type, ], [ 'file_advanced' => 'media', 'plupload_image' => 'image_upload', 'url' => 'text', ] ); return $map[ $type ]; } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/helpers/string.php ================================================ constants(); // PSR-4 autoload. $psr4_autoload = dirname( __DIR__ ) . '/vendor/autoload.php'; if ( file_exists( $psr4_autoload ) ) { require $psr4_autoload; } // Register autoload for classes. require_once RWMB_INC_DIR . 'autoloader.php'; $autoloader = new RWMB_Autoloader(); $autoloader->add( RWMB_INC_DIR, 'RW_' ); $autoloader->add( RWMB_INC_DIR, 'RWMB_' ); $autoloader->add( RWMB_INC_DIR . 'about', 'RWMB_' ); $autoloader->add( RWMB_INC_DIR . 'fields', 'RWMB_', '_Field' ); $autoloader->add( RWMB_INC_DIR . 'walkers', 'RWMB_Walker_' ); $autoloader->add( RWMB_INC_DIR . 'interfaces', 'RWMB_', '_Interface' ); $autoloader->add( RWMB_INC_DIR . 'storages', 'RWMB_', '_Storage' ); $autoloader->add( RWMB_INC_DIR . 'helpers', 'RWMB_Helpers_' ); $autoloader->add( RWMB_INC_DIR . 'update', 'RWMB_Update_' ); $autoloader->register(); // Plugin core. $core = new RWMB_Core(); $core->init(); $shortcode = new RWMB_Shortcode(); $shortcode->init(); // Validation module. new RWMB_Validation(); $sanitizer = new RWMB_Sanitizer(); $sanitizer->init(); $media_modal = new RWMB_Media_Modal(); $media_modal->init(); // Update. $update_option = null; $update_checker = null; if ( class_exists( '\MetaBox\Updater\Option' ) ) { $update_option = new \MetaBox\Updater\Option(); $update_checker = new \MetaBox\Updater\Checker( $update_option ); $update_checker->init(); $update_settings = new \MetaBox\Updater\Settings( $update_checker, $update_option ); $update_settings->init(); $update_notification = new \MetaBox\Updater\Notification( $update_checker, $update_option ); $update_notification->init(); } // WPML Compatibility. new \MetaBox\Integrations\WPML(); // Register categories for page builders. new \MetaBox\Integrations\Block(); new \MetaBox\Integrations\Bricks(); new \MetaBox\Integrations\Elementor(); new \MetaBox\Integrations\Oxygen(); if ( is_admin() ) { new \MetaBox\Dashboard\Dashboard( $update_checker, $update_option ); new \MetaBox\FeaturedPlugins(); } // Public functions. require_once RWMB_INC_DIR . 'functions.php'; } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/media-modal.php ================================================ all(); foreach ( $meta_boxes as $meta_box ) { if ( $this->is_in_modal( $meta_box->meta_box ) ) { $this->fields = array_merge( $this->fields, array_values( $meta_box->fields ) ); } } } /** * Add fields to the attachment edit popup. * * @param array $form_fields An array of attachment form fields. * @param WP_Post $post The WP_Post attachment object. * * @return mixed */ public function add_fields( $form_fields, $post ) { if ( empty( $post ) || $this->is_attachment_edit_screen() ) { return $form_fields; } foreach ( $this->fields as $field ) { $form_field = $field; $form_field['label'] = $field['name']; $form_field['input'] = 'html'; // Just ignore the field 'std' because there's no way to check it. $meta = RWMB_Field::call( $field, 'meta', $post->ID, true ); $form_field['value'] = $meta; $field['field_name'] = 'attachments[' . $post->ID . '][' . $field['field_name'] . ']'; ob_start(); $field['name'] = ''; // Don't show field label as it's already handled by WordPress. RWMB_Field::call( 'show', $field, true, $post->ID ); // For MB Custom Table to flush data from the cache to the database. do_action( 'rwmb_flush_data', $post->ID, $field, [] ); $form_field['html'] = ob_get_clean(); $form_fields[ $field['id'] ] = $form_field; } return $form_fields; } /** * Save custom fields. * * @param array $post An array of post data. * @param array $attachment An array of attachment metadata. * * @return array */ public function save_fields( $post, $attachment ) { foreach ( $this->fields as $field ) { $key = $field['id']; $old = RWMB_Field::call( $field, 'raw_meta', $post['ID'] ); $new = isset( $attachment[ $key ] ) ? $attachment[ $key ] : ''; $new = RWMB_Field::process_value( $new, $post['ID'], $field ); // Call defined method to save meta value, if there's no methods, call common one. RWMB_Field::call( $field, 'save', $new, $old, $post['ID'] ); // For MB Custom Table to flush data from the cache to the database. do_action( 'rwmb_flush_data', $post['ID'], $field, [] ); } return $post; } private function is_in_modal( array $meta_box ): bool { return in_array( 'attachment', $meta_box['post_types'], true ) && ! empty( $meta_box['media_modal'] ); } private function is_attachment_edit_screen(): bool { if ( ! function_exists( 'get_current_screen' ) ) { return false; } $screen = get_current_screen(); return $screen && $screen->id === 'attachment'; } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/meta-box-registry.php ================================================ add( $meta_box ); return $meta_box; } public function add( RW_Meta_Box $meta_box ) { $this->data[ $meta_box->id ] = $meta_box; } public function get( $id ) { return $this->data[ $id ] ?? false; } /** * Get meta boxes under some conditions. * * @param array $args Custom argument to get meta boxes by. */ public function get_by( array $args ): array { $meta_boxes = $this->data; foreach ( $meta_boxes as $index => $meta_box ) { foreach ( $args as $key => $value ) { $meta_box_key = 'object_type' === $key ? $meta_box->get_object_type() : $meta_box->$key; if ( $meta_box_key !== $value ) { unset( $meta_boxes[ $index ] ); continue 2; // Skip the meta box loop. } } } return $meta_boxes; } public function all() { return $this->data; } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/meta-box.php ================================================ meta_box = $meta_box; $this->meta_box['fields'] = static::normalize_fields( $meta_box['fields'], $this->get_storage() ); $this->meta_box = apply_filters( 'rwmb_meta_box_settings', $this->meta_box ); if ( $this->is_shown() ) { $this->global_hooks(); $this->object_hooks(); } } public function register_fields() { $field_registry = rwmb_get_registry( 'field' ); foreach ( $this->post_types as $post_type ) { foreach ( $this->fields as $field ) { $field_registry->add( $field, $post_type ); } } } public function is_shown(): bool { $show = apply_filters( 'rwmb_show', true, $this->meta_box ); return apply_filters( "rwmb_show_{$this->id}", $show, $this->meta_box ); } protected function global_hooks() { // Enqueue common styles and scripts. add_action( 'admin_enqueue_scripts', [ $this, 'enqueue' ] ); // Enqueue assets for the block editor only, just for previewing (submission forms, custom blocks). // Don't enqueue on frontend as front-end forms and blocks already call the enqueue() method. // TODO: Uncomment this when we have a way to enqueue assets for the block/site editor. // if ( is_admin() ) { // add_action( 'enqueue_block_assets', [ $this, 'enqueue' ] ); // } // Add additional actions for fields. foreach ( $this->fields as $field ) { RWMB_Field::call( $field, 'add_actions' ); } } /** * Specific hooks for meta box object. Default is 'post'. * This should be extended in subclasses to support meta fields for terms, user, settings pages, etc. */ protected function object_hooks() { // Add meta box. add_action( 'add_meta_boxes', [ $this, 'add_meta_boxes' ] ); // Hide meta box if it's set 'default_hidden'. add_filter( 'default_hidden_meta_boxes', [ $this, 'hide' ], 10, 2 ); // Save post meta. foreach ( $this->post_types as $post_type ) { if ( 'attachment' === $post_type ) { // Attachment uses other hooks. // @see wp_update_post(), wp_insert_attachment(). add_action( 'edit_attachment', [ $this, 'save_post' ] ); add_action( 'add_attachment', [ $this, 'save_post' ] ); } else { add_action( "save_post_{$post_type}", [ $this, 'save_post' ] ); } } } public function enqueue() { if ( is_admin() && ! $this->is_edit_screen() && ! $this->is_gutenberg_screen() ) { return; } wp_enqueue_style( 'rwmb', RWMB_CSS_URL . 'style.css', [], RWMB_VER ); wp_style_add_data( 'rwmb', 'path', RWMB_CSS_DIR . 'style.css' ); if ( is_rtl() ) { wp_enqueue_style( 'rwmb-rtl', RWMB_CSS_URL . 'style-rtl.css', [], RWMB_VER ); wp_style_add_data( 'rwmb-rtl', 'path', RWMB_CSS_DIR . 'style-rtl.css' ); } wp_enqueue_script( 'rwmb', RWMB_JS_URL . 'script.js', [ 'jquery' ], RWMB_VER, true ); // Load clone script conditionally. foreach ( $this->fields as $field ) { if ( $field['clone'] ) { wp_enqueue_script( 'rwmb-clone', RWMB_JS_URL . 'clone.js', [ 'jquery-ui-sortable' ], RWMB_VER, true ); break; } } // Enqueue scripts and styles for fields. foreach ( $this->fields as $field ) { RWMB_Field::call( $field, 'admin_enqueue_scripts' ); } // Auto save. if ( $this->autosave ) { wp_enqueue_script( 'rwmb-autosave', RWMB_JS_URL . 'autosave.js', [ 'jquery' ], RWMB_VER, true ); } /** * Allow developers to enqueue more scripts and styles * * @param RW_Meta_Box $object Meta Box object */ do_action( 'rwmb_enqueue_scripts', $this ); } private function is_gutenberg_screen(): bool { $screen = get_current_screen(); return in_array( $screen->base, [ 'site-editor', 'widgets' ], true ); } /** * Add meta box for multiple post types */ public function add_meta_boxes() { $screen = get_current_screen(); add_filter( "postbox_classes_{$screen->id}_{$this->id}", [ $this, 'postbox_classes' ] ); foreach ( $this->post_types as $post_type ) { add_meta_box( $this->id, $this->title, [ $this, 'show' ], $post_type, $this->context, $this->priority ); } } public function postbox_classes( array $classes ): array { if ( $this->closed ) { $classes[] = 'closed'; } $classes[] = "rwmb-{$this->style}"; return $classes; } public function hide( array $hidden, $screen ): array { if ( $this->is_edit_screen( $screen ) && $this->default_hidden ) { $hidden[] = $this->id; } return $hidden; } public function show() { if ( null === $this->object_id ) { $this->object_id = $this->get_current_object_id(); } $saved = $this->is_saved(); // Container. printf( '
      ', esc_attr( trim( "rwmb-meta-box {$this->class}" ) ), esc_attr( $this->autosave ? 'true' : 'false' ), esc_attr( $this->object_type ), esc_attr( $this->object_id ) ); wp_nonce_field( "rwmb-save-{$this->id}", "nonce_{$this->id}" ); // Allow users to add custom code before meta box content. // 1st action applies to all meta boxes. // 2nd action applies to only current meta box. do_action( 'rwmb_before', $this ); do_action( "rwmb_before_{$this->id}", $this ); foreach ( $this->fields as $field ) { RWMB_Field::call( 'show', $field, $saved, $this->object_id ); } $this->render_cleanup(); // Allow users to add custom code after meta box content. // 1st action applies to all meta boxes. // 2nd action applies to only current meta box. do_action( 'rwmb_after', $this ); do_action( "rwmb_after_{$this->id}", $this ); // End container. echo '
      '; } protected function get_cleanup_fields( $fields, $prefix = '' ) { $names = []; foreach ( $fields as $field ) { $field_id = $prefix . $field['id']; if ( ! empty( $field['fields'] ) ) { $suffix = $field['clone'] ? '.*.' : '.'; $names = array_merge( $names, $this->get_cleanup_fields( $field['fields'], $field_id . $suffix ) ); } if ( $field['clone'] ) { $names[] = $field_id; } } return $names; } protected function render_cleanup() { $names = $this->get_cleanup_fields( $this->fields ); echo ''; } /** * Save data from meta box * * @param int $object_id Object ID. */ public function save_post( $object_id ) { if ( ! $this->validate() ) { return; } $this->saved = true; $object_id = $this->get_real_object_id( $object_id ); $this->object_id = $object_id; // Before save action. do_action( 'rwmb_before_save_post', $object_id ); do_action( "rwmb_{$this->id}_before_save_post", $object_id ); array_map( [ $this, 'save_field' ], $this->fields ); // After save action. do_action( 'rwmb_after_save_post', $object_id ); do_action( "rwmb_{$this->id}_after_save_post", $object_id ); } public function save_field( array $field ) { $single = $field['clone'] || ! $field['multiple']; $default = $single ? '' : []; $old = RWMB_Field::call( $field, 'raw_meta', $this->object_id ); $new = rwmb_request()->post( $field['id'], $default ); $new = RWMB_Field::process_value( $new, $this->object_id, $field ); // Filter to allow the field to be modified. $field = RWMB_Field::filter( 'field', $field, $field, $new, $old ); // Call defined method to save meta value, if there's no methods, call common one. RWMB_Field::call( $field, 'save', $new, $old, $this->object_id ); RWMB_Field::filter( 'after_save_field', null, $field, $new, $old, $this->object_id ); } public function validate(): bool { $nonce = rwmb_request()->filter_post( "nonce_{$this->id}" ); return ! $this->saved && ( ! defined( 'DOING_AUTOSAVE' ) || $this->autosave ) && wp_verify_nonce( $nonce, "rwmb-save-{$this->id}" ); } public static function normalize( $meta_box ) { $default_title = __( 'Meta Box Title', 'meta-box' ); $meta_box = wp_parse_args( $meta_box, [ 'title' => $default_title, 'id' => ! empty( $meta_box['title'] ) ? sanitize_title( $meta_box['title'] ) : sanitize_title( $default_title ), 'context' => 'normal', 'priority' => 'high', 'post_types' => 'post', 'autosave' => false, 'default_hidden' => false, 'style' => 'default', 'class' => '', 'fields' => [], ] ); /** * Use 'post_types' for better understanding and fallback to 'pages' for previous versions. * @since 4.4.1 */ Arr::change_key( $meta_box, 'pages', 'post_types' ); // Make sure the post type is an array and is sanitized. $meta_box['post_types'] = array_filter( array_map( 'sanitize_key', Arr::from_csv( $meta_box['post_types'] ) ) ); return $meta_box; } public static function normalize_fields( array $fields, $storage = null ): array { foreach ( $fields as $k => $field ) { $field = RWMB_Field::call( 'normalize', $field ); // Allow to add default values for fields. $field = apply_filters( 'rwmb_normalize_field', $field ); $field = apply_filters( "rwmb_normalize_{$field['type']}_field", $field ); $field = apply_filters( "rwmb_normalize_{$field['id']}_field", $field ); $field['storage'] = $storage; $fields[ $k ] = $field; } return $fields; } /** * Check if meta box is saved before. * This helps to save empty value in meta fields (text, check box, etc.) and set the correct default values. */ public function is_saved() { foreach ( $this->fields as $field ) { if ( empty( $field['id'] ) ) { continue; } $value = RWMB_Field::call( $field, 'raw_meta', $this->object_id ); if ( false === $value ) { continue; } $single = ! $field['multiple']; if ( $field['clone'] ) { $single = ! $field['clone_as_multiple']; } if ( ( $single && '' !== $value ) || ( ! $single && is_array( $value ) && [] !== $value ) ) { return true; } } return false; } /** * Check if we're on the right edit screen. * * @param ?WP_Screen $screen Screen object. */ public function is_edit_screen( $screen = null ) { if ( ! ( $screen instanceof WP_Screen ) ) { $screen = get_current_screen(); } return in_array( $screen->base, [ 'post', 'upload' ], true ) && in_array( $screen->post_type, $this->post_types, true ); } public function __get( string $key ) { return $this->meta_box[ $key ] ?? false; } /** * Set the object ID. * * @param mixed $id Object ID. */ public function set_object_id( $id = null ) { $this->object_id = $id; } public function get_object_type(): string { return $this->object_type; } /** * Get storage object. * * @return RWMB_Storage_Interface */ public function get_storage() { return rwmb_get_storage( $this->object_type, $this ); } /** * Get current object id. * * @return int */ protected function get_current_object_id() { return get_the_ID(); } /** * Get real object ID when submitting. * * @param int $object_id Object ID. * @return int */ protected function get_real_object_id( $object_id ) { // Make sure meta is added to the post, not a revision. if ( 'post' !== $this->object_type ) { return $object_id; } $parent = wp_is_post_revision( $object_id ); return $parent ?: $object_id; } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/request.php ================================================ * * @link https://github.com/laravel/framework/blob/6.x/src/Illuminate/Http/Request.php * @link https://github.com/symfony/symfony/blob/4.4/src/Symfony/Component/HttpFoundation/ParameterBag.php */ class RWMB_Request { private $get_data = []; private $post_data = []; public function __construct() { // @codingStandardsIgnoreLine $this->get_data = $_GET; // @codingStandardsIgnoreLine $this->post_data = $_POST; // Cleanup data $this->post_data = $this->cleanup( $this->post_data ); } public function set_get_data( array $data ) { $this->get_data = array_merge( $this->get_data, $data ); } public function set_post_data( array $data ) { $this->post_data = array_merge( $this->post_data, $data ); } public function get( string $name, $default = null ) { return $this->get_data[ $name ] ?? $default; } public function post( string $name, $default = null ) { return $this->post_data[ $name ] ?? $default; } public function cleanup( array $data ) { $cleanups = $data['rwmb_cleanup'] ?? []; // Array of field ids if ( empty( $cleanups ) || ! is_array( $cleanups ) ) { return $data; } // Decode the JSON string for each cleanup item foreach ( $cleanups as $cleanup ) { $cleanup = json_decode( stripslashes( $cleanup ) ); if ( ! is_array( $cleanup ) ) { continue; } foreach ( $cleanup as $field_id ) { // Remove the field from the data Arr::remove_first( $data, $field_id ); } } return $data; } /** * Filter a GET parameter. * * @param string $name Parameter name. * @param int $filter FILTER_* constant. * @param mixed $options Filter options. * * @return mixed */ public function filter_get( string $name, $filter = FILTER_DEFAULT, $options = [] ) { $value = $this->get( $name ); return filter_var( $value, $filter, $options ); } /** * Filter a POST parameter. * * @param string $name Parameter name. * @param int $filter FILTER_* constant. * @param mixed $options Filter options. * * @return mixed */ public function filter_post( string $name, $filter = FILTER_DEFAULT, $options = [] ) { $value = $this->post( $name ); return filter_var( $value, $filter, $options ); } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/sanitizer.php ================================================ get_callback( $field ); return is_callable( $callback ) ? call_user_func( $callback, $value, $field, $old_value, $object_id ) : $value; } /** * Get sanitize callback for a field. * * @param array $field Field settings. * @return callable */ private function get_callback( $field ) { // User-defined callback. if ( is_callable( $field['sanitize_callback'] ) ) { return $field['sanitize_callback']; } $callbacks = [ 'autocomplete' => [ $this, 'sanitize_choice' ], 'background' => [ $this, 'sanitize_background' ], 'button_group' => [ $this, 'sanitize_choice' ], 'checkbox' => [ $this, 'sanitize_checkbox' ], 'checkbox_list' => [ $this, 'sanitize_choice' ], 'color' => [ $this, 'sanitize_color' ], 'date' => [ $this, 'sanitize_datetime' ], 'datetime' => [ $this, 'sanitize_datetime' ], 'email' => 'sanitize_email', 'fieldset_text' => [ $this, 'sanitize_text' ], 'file' => [ $this, 'sanitize_file' ], 'file_advanced' => [ $this, 'sanitize_object' ], 'file_input' => [ $this, 'sanitize_url' ], 'file_upload' => [ $this, 'sanitize_object' ], 'hidden' => 'sanitize_text_field', 'image' => [ $this, 'sanitize_file' ], 'image_advanced' => [ $this, 'sanitize_object' ], 'image_select' => [ $this, 'sanitize_choice' ], 'image_upload' => [ $this, 'sanitize_object' ], 'key_value' => [ $this, 'sanitize_text' ], 'map' => [ $this, 'sanitize_map' ], 'number' => [ $this, 'sanitize_number' ], 'oembed' => [ $this, 'sanitize_url' ], 'osm' => [ $this, 'sanitize_map' ], 'password' => 'sanitize_text_field', 'post' => [ $this, 'sanitize_object' ], 'radio' => [ $this, 'sanitize_choice' ], 'range' => [ $this, 'sanitize_number' ], 'select' => [ $this, 'sanitize_choice' ], 'select_advanced' => [ $this, 'sanitize_choice' ], 'sidebar' => [ $this, 'sanitize_text' ], 'single_image' => 'absint', 'slider' => [ $this, 'sanitize_slider' ], 'switch' => [ $this, 'sanitize_checkbox' ], 'taxonomy' => [ $this, 'sanitize_object' ], 'taxonomy_advanced' => [ $this, 'sanitize_taxonomy_advanced' ], 'text' => 'sanitize_text_field', 'text_list' => [ $this, 'sanitize_text' ], 'textarea' => 'wp_kses_post', 'time' => 'sanitize_text_field', 'url' => [ $this, 'sanitize_url' ], 'user' => [ $this, 'sanitize_object' ], 'video' => [ $this, 'sanitize_object' ], 'wysiwyg' => 'wp_kses_post', ]; $type = $field['type']; return $callbacks[ $type ] ?? null; } /** * Set the value of checkbox to 1 or 0 instead of 'checked' and empty string. * This prevents using default value once the checkbox has been unchecked. * * @link https://github.com/rilwis/meta-box/issues/6 * @param string $value Checkbox value. */ private function sanitize_checkbox( $value ): int { return (int) ! empty( $value ); } /** * Sanitize numeric value. * * @param string $value The number value. * @return string */ private function sanitize_number( $value ) { return is_numeric( $value ) ? $value : ''; } private function sanitize_color( string $value ): string { if ( str_contains( $value, 'hsl' ) ) { return wp_unslash( $value ); } if ( ! str_contains( $value, 'rgb' ) ) { return (string) sanitize_hex_color( $value ); } // rgba value. $red = ''; $green = ''; $blue = ''; $alpha = 1; if ( str_contains( $value, 'rgba' ) ) { sscanf( $value, 'rgba(%d,%d,%d,%f)', $red, $green, $blue, $alpha ); } else { sscanf( $value, 'rgb(%d,%d,%d)', $red, $green, $blue ); } return 'rgba(' . $red . ',' . $green . ',' . $blue . ',' . $alpha . ')'; } /** * Sanitize value for a choice field. * * @param string|array $value The submitted value. * @param array $field The field settings. * @return string|array */ private function sanitize_choice( $value, $field ) { $options = RWMB_Choice_Field::transform_options( $field['options'] ); $options = wp_list_pluck( $options, 'value' ); $value = wp_unslash( $value ); // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict return is_array( $value ) ? array_intersect( $value, $options ) : ( in_array( $value, $options ) ? $value : '' ); } /** * Sanitize object & media field. * * @param int|array $value The submitted value. * @return int|array */ private function sanitize_object( $value ) { return is_array( $value ) ? array_filter( array_map( 'absint', $value ) ) : ( $value ? absint( $value ) : '' ); } /** * Sanitize background field. * * @param array $value The submitted value. * @return array */ private function sanitize_background( $value ) { $value = wp_parse_args( $value, [ 'color' => '', 'image' => '', 'repeat' => '', 'attachment' => '', 'position' => '', 'size' => '', ] ); $value['color'] = $this->sanitize_color( $value['color'] ); $value['image'] = esc_url_raw( $value['image'] ); $value['repeat'] = in_array( $value['repeat'], [ 'no-repeat', 'repeat', 'repeat-x', 'repeat-y', 'inherit' ], true ) ? $value['repeat'] : ''; $value['position'] = in_array( $value['position'], [ 'top left', 'top center', 'top right', 'center left', 'center center', 'center right', 'bottom left', 'bottom center', 'bottom right' ], true ) ? $value['position'] : ''; $value['attachment'] = in_array( $value['attachment'], [ 'fixed', 'scroll', 'inherit' ], true ) ? $value['attachment'] : ''; $value['size'] = in_array( $value['size'], [ 'inherit', 'cover', 'contain' ], true ) ? $value['size'] : ''; return $value; } /** * Sanitize text field. * * @param string|array $value The submitted value. * @return string|array */ private function sanitize_text( $value ) { return is_array( $value ) ? array_map( __METHOD__, $value ) : sanitize_text_field( $value ); } /** * Sanitize file, image field. * * @param array $value The submitted value. * @param array $field The field settings. * @return array */ private function sanitize_file( $value, $field ) { return $field['upload_dir'] ? array_map( 'esc_url_raw', $value ) : $this->sanitize_object( $value ); } /** * Sanitize slider field. * * @param mixed $value The submitted value. * @param array $field The field settings. * @return string|int|float */ private function sanitize_slider( $value, $field ) { return true === $field['js_options']['range'] ? sanitize_text_field( $value ) : $this->sanitize_number( $value ); } /** * Sanitize datetime field. * * @param mixed $value The submitted value. * @param array $field The field settings. * @return float|string */ private function sanitize_datetime( $value, $field ) { return $field['timestamp'] ? (float) $value : sanitize_text_field( $value ); } private function sanitize_map( $value ): string { $value = sanitize_text_field( $value ); list( $latitude, $longitude, $zoom ) = explode( ',', $value . ',,' ); $latitude = (float) $latitude; $longitude = (float) $longitude; $zoom = (int) $zoom; return "$latitude,$longitude,$zoom"; } private function sanitize_taxonomy_advanced( $value ): string { return implode( ',', wp_parse_id_list( $value ) ); } private function sanitize_url( string $value ): string { return esc_url_raw( $value ); } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/shortcode.php ================================================ '', 'object_id' => null, 'attribute' => '', 'render_shortcodes' => 'true', ] ); Arr::change_key( $atts, 'post_id', 'object_id' ); Arr::change_key( $atts, 'meta_key', 'id' ); if ( empty( $atts['id'] ) ) { return ''; } $field_id = $atts['id']; $object_id = $atts['object_id']; unset( $atts['id'], $atts['object_id'] ); $value = $this->get_value( $field_id, $object_id, $atts ); $value = 'true' === $atts['render_shortcodes'] ? do_shortcode( $value ) : $value; $secure = apply_filters( 'rwmb_meta_shortcode_secure', true, $field_id, $atts, $object_id ); $secure = apply_filters( "rwmb_meta_shortcode_secure_{$field_id}", $secure, $atts, $object_id ); if ( $secure ) { $value = wp_kses_post( $value ); } return $value; } private function get_value( $field_id, $object_id, $atts ) { // If we pass object_id via shortcode, we need to make sure current user // has permission to view the object if ( ! is_null( $object_id ) ) { $has_object_permission = $this->check_object_permission( $object_id, $atts ); if ( ! $has_object_permission ) { return null; } } $attribute = $atts['attribute']; if ( ! $attribute ) { return rwmb_the_value( $field_id, $atts, $object_id, false ); } $value = rwmb_get_value( $field_id, $atts, $object_id ); if ( ! is_array( $value ) && ! is_object( $value ) ) { return $value; } if ( is_object( $value ) ) { return $value->$attribute; } if ( isset( $value[ $attribute ] ) ) { return $value[ $attribute ]; } $value = wp_list_pluck( $value, $attribute ); $value = implode( ',', array_filter( $value ) ); return $value; } private function check_object_permission( $object_id, $atts ) { // Skip checking if object_type is not post if ( isset( $atts['object_type'] ) && $atts['object_type'] !== 'post' ) { return true; } $post = get_post( $object_id ); if ( ! $post ) { return false; } // Skip checking if post status is publish AND no password is set if ( 'publish' === $post->post_status && ! post_password_required( $post ) ) { return true; } $object_type = get_post_type_object( $post->post_type ); if ( ! $object_type ) { return false; } $read_post = $object_type->cap->read_post; return current_user_can( $read_post, $object_id ); } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/storage-registry.php ================================================ storages[ $class_name ] ) ) { $this->storages[ $class_name ] = new $class_name(); } return $this->storages[ $class_name ]; } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/storages/base.php ================================================ object_type, $object_id, $meta_key, $single ); } /** * Add metadata * * @param int $object_id ID of the object metadata is for. * @param string $meta_key Metadata key. * @param mixed $meta_value Metadata value. Must be serializable if non-scalar. * @param bool $unique Optional, default is false. * Whether the specified metadata key should be unique for the object. * If true, and the object already has a value for the specified metadata key, * no change will be made. * @return int|false The meta ID on success, false on failure. * * @see add_metadata() */ public function add( $object_id, $meta_key, $meta_value, $unique = false ) { return add_metadata( $this->object_type, $object_id, $meta_key, $meta_value, $unique ); } /** * Update metadata. * * @param int $object_id ID of the object metadata is for. * @param string $meta_key Metadata key. * @param mixed $meta_value Metadata value. Must be serializable if non-scalar. * @param mixed $prev_value Optional. If specified, only update existing metadata entries with * the specified value. Otherwise, update all entries. * @return int|bool Meta ID if the key didn't exist, true on successful update, false on failure. * * @see update_metadata() */ public function update( $object_id, $meta_key, $meta_value, $prev_value = '' ) { return update_metadata( $this->object_type, $object_id, $meta_key, $meta_value, $prev_value ); } /** * Delete metadata. * * @param int $object_id ID of the object metadata is for. * @param string $meta_key Metadata key. * @param mixed $meta_value Optional. Metadata value. Must be serializable if non-scalar. If specified, only delete * metadata entries with this value. Otherwise, delete all entries with the specified meta_key. * Pass `null, `false`, or an empty string to skip this check. (For backward compatibility, * it is not possible to pass an empty string to delete those entries with an empty string * for a value). * @param bool $delete_all Optional, default is false. If true, delete matching metadata entries for all objects, * ignoring the specified object_id. Otherwise, only delete matching metadata entries for * the specified object_id. * @return bool True on successful delete, false on failure. * * @see delete_metadata() */ public function delete( $object_id, $meta_key, $meta_value = '', $delete_all = false ) { return delete_metadata( $this->object_type, $object_id, $meta_key, $meta_value, $delete_all ); } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/storages/post.php ================================================ and will be converted into JSON by JS. */ public function rules( RW_Meta_Box $meta_box ) { $settings = $meta_box->meta_box; if ( empty( $settings['validation'] ) ) { return; } $prefix = $settings['prefix'] ?? ''; // Get field ID prefix from the builder. $fields = $settings['fields']; $validation = $settings['validation']; $ids = wp_list_pluck( $fields, 'id' ); // Don't use array_column() as it doesn't preserve keys. // Add prefix for validation rules. foreach ( $validation as &$rules ) { $rules = array_combine( array_map( function ( $key ) use ( $fields, $prefix, $ids ) { $id = $prefix . $key; $index = array_search( $id, $ids, true ); if ( $index === false ) { return $id; } $field = $fields[ $index ]; if ( in_array( $field['type'], [ 'file', 'image' ], true ) ) { return $field['clone'] ? $field['index_name'] : $field['input_name']; } return $id; }, array_keys( $rules ) ), $rules ); } echo ''; } public function enqueue() { wp_enqueue_script( 'jquery-validation', RWMB_JS_URL . 'validation/jquery.validate.js', [ 'jquery' ], '1.20.0', true ); wp_enqueue_script( 'jquery-validation-additional-methods', RWMB_JS_URL . 'validation/additional-methods.js', [ 'jquery-validation' ], '1.20.0', true ); wp_enqueue_script( 'rwmb-validation', RWMB_JS_URL . 'validation/validation.js', [ 'jquery-validation-additional-methods', 'rwmb' ], RWMB_VER, true ); $locale = determine_locale(); $locale_short = substr( $locale, 0, 2 ); $locale = file_exists( RWMB_DIR . "js/validation/i18n/messages_$locale.js" ) ? $locale : $locale_short; if ( file_exists( RWMB_DIR . "js/validation/i18n/messages_$locale.js" ) ) { wp_enqueue_script( 'jquery-validation-i18n', RWMB_JS_URL . "validation/i18n/messages_$locale.js", [ 'jquery-validation-additional-methods' ], '1.20.0', true ); } RWMB_Helpers_Field::localize_script_once( 'rwmb-validation', 'rwmbValidation', [ 'message' => esc_html( apply_filters( 'rwmb_validation_message_string', __( 'Please correct the errors highlighted below and try again.', 'meta-box' ) ) ), ] ); } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/walkers/base.php ================================================ db_fields = [ 'id' => 'value', 'parent' => 'parent', ]; $this->field = $field; $this->meta = (array) $meta; } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/walkers/input-list.php ================================================ '; } /** * Ends the list of after the elements are added. * * @param string $output Passed by reference. Used to append additional content. * @param int $depth Depth of the item. * @param array $args An array of additional arguments. */ public function end_lvl( &$output, $depth = 0, $args = [] ) { $output .= ''; } /** * Start the element output. * * @param string $output Passed by reference. Used to append additional content. * @param object $object The data object. * @param int $depth Depth of the item. * @param array $args An array of additional arguments. * @param int $current_object_id ID of the current item. */ public function start_el( &$output, $object, $depth = 0, $args = [], $current_object_id = 0 ) { $attributes = RWMB_Field::call( 'get_attributes', $this->field, $object->value ); $output .= sprintf( '', RWMB_Field::render_attributes( $attributes ), // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict checked( in_array( $object->value, $this->meta ), true, false ), $object->label ); } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/walkers/select-tree.php ================================================ field = $field; $this->meta = (array) $meta; } /** * Display array of elements hierarchically. * * @param array $options An array of options. * * @return string */ public function walk( $options ) { $children = []; foreach ( $options as $option ) { $parent = $option->parent ?? 0; $children[ $parent ][] = $option; } $top_level = isset( $children[0] ) ? 0 : $options[0]->parent; return $this->display_level( $children, $top_level, true ); } /** * Display a hierarchy level. * * @param array $options An array of options. * @param int $parent_id Parent item ID. * @param bool $active Whether to show or hide. * * @return string */ public function display_level( $options, $parent_id = 0, $active = false ) { static $output_required = false; $field = $this->field; $walker = new RWMB_Walker_Select( $field, $this->meta ); $attributes = RWMB_Field::call( 'get_attributes', $field, $this->meta ); if ( $output_required ) { unset( $attributes['required'] ); } if ( ! empty( $attributes['required'] ) ) { $output_required = true; } $children = $options[ $parent_id ]; $output = sprintf( '
      '; foreach ( $children as $child ) { if ( isset( $options[ $child->value ] ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict $output .= $this->display_level( $options, $child->value, in_array( $child->value, $this->meta ) && $active ); } } $output .= '
      '; return $output; } } ================================================ FILE: vendor/wpmetabox/meta-box/inc/walkers/select.php ================================================ %s%s', esc_attr( $object->value ), // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict selected( in_array( $object->value, $this->meta ), true, false ), $indent, esc_html( $object->label ) ); } } ================================================ FILE: vendor/wpmetabox/meta-box/js/autocomplete.js ================================================ ( function ( $, rwmb, i18n ) { 'use strict'; /** * Transform an input into an autocomplete. */ function transform( e ) { var $this = $( this ), $search = $this.siblings( '.rwmb-autocomplete-search' ), $result = $this.siblings( '.rwmb-autocomplete-results' ), name = $this.attr( 'name' ); // If the function is called on cloning, then change the field name and clear all results if ( e.hasOwnProperty( 'type' ) && 'clone' == e.type ) { $result.html( '' ); } $search.removeClass( 'ui-autocomplete-input' ).autocomplete( { minLength: 0, source: $this.data( 'options' ), select: function ( event, ui ) { $result.append( '
      ' + '
      ' + ( typeof ui.item.excerpt !== 'undefined' ? ui.item.excerpt : ui.item.label ) + '
      ' + '
      ' + i18n.delete + '
      ' + '' + '
      ' ); // Reinitialize value. $search.val( '' ).trigger( 'change' ); return false; } } ); } function deleteSelection( e ) { e.preventDefault(); var $item = $( this ).parent(), $search = $item.parent().siblings( '.rwmb-autocomplete-search' ); $item.remove(); $search.trigger( 'change' ); } function init( e ) { $( e.target ).find( '.rwmb-autocomplete-wrapper input[type="hidden"]' ).each( transform ); } rwmb.$document .on( 'mb_ready', init ) .on( 'clone', '.rwmb-autocomplete', transform ) .on( 'click', '.rwmb-autocomplete-result .actions', deleteSelection ); } )( jQuery, rwmb, RWMB_Autocomplete ); ================================================ FILE: vendor/wpmetabox/meta-box/js/autosave.js ================================================ ( function ( $, document ) { 'use strict'; $( document ).ajaxSend( function ( event, xhr, settings ) { if ( ! Array.isArray( settings.data ) || -1 === settings.data.indexOf( 'wp_autosave' ) ) { return; } var inputSelectors = 'input[class*="rwmb"], textarea[class*="rwmb"], select[class*="rwmb"], button[class*="rwmb"], input[name^="nonce_"]'; $( '.rwmb-meta-box' ).each( function () { var $meta_box = $( this ); if ( true === $meta_box.data( 'autosave' ) ) { settings.data += '&' + $meta_box.find( inputSelectors ).serialize(); } } ); } ); } )( jQuery, document ); ================================================ FILE: vendor/wpmetabox/meta-box/js/button-group.js ================================================ ( function ( $, rwmb ) { 'use strict'; function setActiveClass() { var $this = $( this ), $input = $this.find( 'input' ), $label = $input.parent(); if ( $input.prop( 'checked' ) ) { $label.addClass( 'selected' ); } else { $label.removeClass( 'selected' ); } } function clickHandler() { var $this = $( this ), $input = $this.find( 'input' ), $label = $input.parent(), type = $input.attr( 'type' ), $allLabels = $this.parent().find( 'label' ); if ( ! $input.prop( 'checked' ) ) { $label.removeClass( 'selected' ); return; } $label.addClass( 'selected' ); if ( 'radio' === type ) { $allLabels.removeClass( 'selected' ); $label.addClass( 'selected' ); } } function init( e ) { $( e.target ).find( '.rwmb-button-input-list label' ).each( setActiveClass ); } rwmb.$document .on( 'mb_ready', init ) .on( 'click', '.rwmb-button-input-list label', clickHandler ) .on( 'clone', '.rwmb-button-input-list label', setActiveClass ); } )( jQuery, rwmb ); ================================================ FILE: vendor/wpmetabox/meta-box/js/clone.js ================================================ ( function ( $, rwmb ) { 'use strict'; // Object holds all methods related to fields' index when clone var cloneIndex = { /** * Set index for fields in a .rwmb-clone * @param $inputs .rwmb-clone element * @param index Index value */ set: function ( $inputs, index, count ) { $inputs.each( function () { var $field = $( this ); // Name attribute var name = this.name; if ( name && !$field.closest( '.rwmb-group-clone' ).length ) { $field.attr( 'name', cloneIndex.replace( index, name, '[', ']', false ) ); } // ID attribute var id = this.id; if ( id ) { id = id.replace( '_rwmb_template', '' ); // First clone takes the original ID if ( count === 2 ) { $field.attr( 'id', id ); } if ( count > 2 ) { $field.attr( 'id', cloneIndex.replace( index, id, '_', '', true, true ) ); } } $field.trigger( 'update_index', index ); } ); }, /** * Replace an attribute of a field with updated index * @param index New index value * @param value Attribute value * @param before String before returned value * @param after String after returned value * @param alternative Check if attribute does not contain any integer, will reset the attribute? * @param isEnd Check if we find string at the end? * @return string */ replace: function ( index, value, before, after, alternative, isEnd ) { before = before || ''; after = after || ''; if ( typeof alternative === 'undefined' ) { alternative = true; } var end = isEnd ? '$' : ''; var regex = new RegExp( cloneIndex.escapeRegex( before ) + '(\\d+)' + cloneIndex.escapeRegex( after ) + end ), newValue = before + index + after; return regex.test( value ) ? value.replace( regex, newValue ) : ( alternative ? value + newValue : value ); }, /** * Helper function to escape string in regular expression * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions * @param string * @return string */ escapeRegex: function ( string ) { return string.replace( /[.*+?^${}()|[\]\\]/g, "\\$&" ); }, /** * Helper function to create next index for clones * @param $container .rwmb-input container * @return integer */ nextIndex: function ( $container ) { var nextIndex = $container.data( 'next-index' ); // If we render cloneable fields via AJAX, the mb_ready event is not fired. // so nextIndex is undefined. In this case, we get the next index from the number of existing clones. if ( nextIndex === undefined ) { nextIndex = $container.children( '.rwmb-clone' ).length; } $container.data( 'next-index', nextIndex + 1 ); return nextIndex; } }; // Object holds all method related to fields' value when clone. var cloneValue = { setDefault: function () { var $field = $( this ); if ( true !== $field.data( 'clone-default' ) ) { return; } var type = $field.attr( 'type' ), defaultValue = $field.data( 'default' ); if ( 'radio' === type ) { $field.prop( 'checked', $field.val() === defaultValue ); } else if ( $field.hasClass( 'rwmb-checkbox' ) || $field.hasClass( 'rwmb-switch' ) ) { $field.prop( 'checked', !!defaultValue ); } else if ( $field.hasClass( 'rwmb-checkbox_list' ) ) { var value = $field.val(); $field.prop( 'checked', Array.isArray( defaultValue ) ? -1 !== defaultValue.indexOf( value ) : value == defaultValue ); } else if ( $field.is( 'select' ) ) { $field.find( 'option[value="' + defaultValue + '"]' ).prop( 'selected', true ); } else if ( !$field.hasClass( 'rwmb-hidden' ) ) { $field.val( defaultValue ); } }, clear: function () { const $field = $( this ), type = $field.attr( 'type' ); if ( 'radio' === type || 'checkbox' === type ) { $field.prop( 'checked', false ); } else if ( $field.is( 'select' ) ) { if ( $field.attr( 'multiple' ) ) { $field.find( 'option' ).prop( 'selected', false ); $field.val( null ).trigger( 'change' ); } else { $field.prop( 'selectedIndex', 0 ); } } else if ( !$field.hasClass( 'rwmb-hidden' ) ) { $field.val( '' ); } } }; /** * Clone fields * @param $container A div container which has all fields */ function clone( $container ) { var $last = $container.children( '.rwmb-clone' ).last(), $template = $container.children( '.rwmb-clone-template' ), $clone = $template.clone(), nextIndex = cloneIndex.nextIndex( $container ); // Add _rwmb_template suffix to ID of fields in template. // so that the first clone will take the original ID. $template.find( rwmb.inputSelectors ).each( function () { this.id = this.id.includes( '_rwmb_template' ) ? this.id : this.id + '_rwmb_template'; } ); // Clear fields' values. var $inputs = $clone.find( rwmb.inputSelectors ); let count = $container.children( '.rwmb-clone' ).length; // The first clone should keep the default values. if ( count > 1 ) { $inputs.each( cloneValue.clear ); } $clone = $clone.removeClass( 'rwmb-clone-template' ); // Remove validation errors. $clone.find( 'p.rwmb-error' ).remove(); // Insert clone. $clone.insertAfter( $last ); count++; // Trigger custom event for the clone instance. Required for Group extension to update sub fields. $clone.trigger( 'clone_instance', nextIndex ); // Set fields index. Must run before trigger clone event. cloneIndex.set( $inputs, nextIndex, count ); // Set fields' default values: do after index is set to prevent previous radio fields from unchecking. $inputs.each( cloneValue.setDefault ); // Trigger custom clone event. $inputs.trigger( 'clone', nextIndex ); // After cloning fields. $inputs.trigger( 'after_clone', nextIndex ); // Trigger custom change event for MB Blocks to update block attributes. $inputs.first().trigger( 'mb_change' ); } /** * Hide remove buttons when there's only 1 of them * * @param $container .rwmb-input container */ function toggleRemoveButtons( $container ) { const $clones = $container.children( '.rwmb-clone' ); let minClone = 1; let offset = 1; // Add the first clone if data-clone-empty-start = false const cloneEmptyStart = $container[ 0 ].dataset.cloneEmptyStart ?? 0; // If clone-empty-start is true, we need at least 1 item. if ( cloneEmptyStart == 1 ) { offset = 0; } if ( $container.data( 'min-clone' ) ) { minClone = parseInt( $container.data( 'min-clone' ) ); } $clones.children( '.remove-clone' ).toggle( $clones.length - offset > minClone ); // Recursive for nested groups. $container.find( '.rwmb-input' ).each( function () { toggleRemoveButtons( $( this ) ); } ); } /** * Toggle add button * Used with [data-max-clone] attribute. When max clone is reached, the add button is hid and vice versa * * @param $container .rwmb-input container */ function toggleAddButton( $container ) { var $button = $container.children( '.add-clone' ), maxClone = parseInt( $container.data( 'max-clone' ) ) + 1, numClone = $container.children( '.rwmb-clone' ).length; $button.toggle( isNaN( maxClone ) || ( maxClone && numClone < maxClone ) ); } function addClone( e ) { e.preventDefault(); var $container = $( this ).closest( '.rwmb-input' ); clone( $container ); toggleRemoveButtons( $container ); toggleAddButton( $container ); sortClones.apply( $container[ 0 ] ); } function removeClone( e ) { e.preventDefault(); var $this = $( this ), $container = $this.closest( '.rwmb-input' ); // Remove clone only if there are 2 or more of them if ( $container.children( '.rwmb-clone' ).length < 2 ) { return; } $this.parent().trigger( 'remove' ).remove(); toggleRemoveButtons( $container ); toggleAddButton( $container ); // Trigger custom change event for MB Blocks to update block attributes. $container.find( rwmb.inputSelectors ).first().trigger( 'mb_change' ); } /** * Sort clones. * Expect this = .rwmb-input element. */ function sortClones() { var $container = $( this ); if ( undefined !== $container.sortable( 'instance' ) ) { return; } if ( 0 === $container.children( '.rwmb-clone' ).length ) { return; } $container.sortable( { handle: '.rwmb-clone-icon', placeholder: ' rwmb-clone rwmb-sortable-placeholder', items: '> .rwmb-clone', start: function ( event, ui ) { // Make the placeholder has the same height as dragged item ui.placeholder.height( ui.item.outerHeight() ); }, stop: function ( event, ui ) { ui.item.trigger( 'mb_init_editors' ); ui.item.find( rwmb.inputSelectors ).first().trigger( 'mb_change' ); } } ); } function start() { var $container = $( this ); toggleRemoveButtons( $container ); toggleAddButton( $container ); $container.data( 'next-index', $container.children( '.rwmb-clone' ).length ); sortClones.apply( this ); } function init( e ) { $( e.target ).find( '.rwmb-input' ).each( start ); } rwmb.$document .on( 'mb_ready', init ) .on( 'click', '.add-clone', addClone ) .on( 'click', '.remove-clone', removeClone ); // Export for use outside. rwmb.cloneIndex = cloneIndex; rwmb.cloneValue = cloneValue; rwmb.sortClones = sortClones; rwmb.toggleRemoveButtons = toggleRemoveButtons; rwmb.toggleAddButton = toggleAddButton; }( jQuery, rwmb ) ); ================================================ FILE: vendor/wpmetabox/meta-box/js/color.js ================================================ ( function( $, rwmb ) { 'use strict'; /** * Transform an input into a color picker. */ function transform() { const $this = $( this ); const mode = $this.data( 'options' )[ 'mode' ]; const alpha = $this.data( 'alpha-enabled' ); function initChange() { if ( null !== mode && 'hex' !== mode && !alpha ) { const color = new Color( $this.iris( 'option', 'color' ) ); $this.val( color.toCSS( mode ) ); } triggerChange(); } function triggerChange() { $this.trigger( 'color:change' ).trigger( 'mb_change' ); } const $container = $this.closest( '.wp-picker-container' ), // Hack: the picker needs a small delay (learn from the Kirki plugin). options = $.extend( { change: function() { setTimeout( initChange, 20 ); }, clear: function() { setTimeout( triggerChange, 20 ); } }, $this.data( 'options' ) ); // Clone doesn't have input for color picker, we have to add the input and remove the color picker container if ( $container.length > 0 ) { $this.insertBefore( $container ); $container.remove(); } // Show color picker. $this.wpColorPicker( options ); } function init( e ) { $( e.target ).find( '.rwmb-color' ).each( transform ); } rwmb.$document .on( 'mb_ready', init ) .on( 'clone', '.rwmb-color', transform ); } )( jQuery, rwmb ); ================================================ FILE: vendor/wpmetabox/meta-box/js/date.js ================================================ ( function ( $, _, rwmb ) { 'use strict'; /** * Transform an input into a date picker. */ function transform() { let $this = $( this ), options = $this.data( 'options' ); let $inline = $this.siblings( '.rwmb-datetime-inline' ); if ( !$inline.length ) { $inline = $this.closest( '.rwmb-input-group' ).siblings( '.rwmb-datetime-inline' ); } let $timestamp = $this.siblings( '.rwmb-datetime-timestamp' ), current = $this.val(), $picker = $inline.length ? $inline : $this; $this.siblings( '.ui-datepicker-append' ).remove(); // Remove appended text options.onSelect = function () { $this.trigger( 'change' ); }; options.beforeShow = function ( i ) { if ( $( i ).prop( 'readonly' ) ) { return false; } }; if ( $timestamp.length ) { options.onClose = options.onSelect = function () { $timestamp.val( getTimestamp( $picker.datepicker( 'getDate' ) ) ); $this.trigger( 'change' ); }; $this.on( 'change', () => { if ( !$this.val() ) { $timestamp.val( '' ); } } ); } if ( !$inline.length ) { $this.removeClass( 'hasDatepicker' ).datepicker( options ); return; } options.altField = '#' + $this.attr( 'id' ); $this.on( 'keydown', _.debounce( function () { // if val is empty, return to allow empty datepicker input. if ( !$this.val() ) { return; } $picker .datepicker( 'setDate', $this.val() ) .find( '.ui-datepicker-current-day' ) .trigger( 'click' ); }, 600 ) ); $inline .removeClass( 'hasDatepicker' ) .empty() .prop( 'id', '' ) .datepicker( options ) .datepicker( 'setDate', current ); } /** * Convert date to Unix timestamp in milliseconds * @link http://stackoverflow.com/a/14006555/556258 * @param date * @return number */ function getTimestamp( date ) { if ( date === null ) { return ''; } var milliseconds = Date.UTC( date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds() ); return Math.floor( milliseconds / 1000 ); } function init( e ) { /** * WordPress sets localized data for jQuery UI datepicker at document ready. * Using setTimeout to ensure the code runs after the localized data is set. * @link https://wordpress.org/support/topic/inline-date-field-not-localization/ */ setTimeout( () => { $( e.target ).find( '.rwmb-date' ).each( transform ); }, 0 ); } rwmb.$document .on( 'mb_ready', init ) .on( 'clone', '.rwmb-date', transform ); } )( jQuery, _, rwmb ); ================================================ FILE: vendor/wpmetabox/meta-box/js/datetime.js ================================================ ( function ( $, _, rwmb, i18n ) { 'use strict'; /** * Transform an input into a datetime picker. */ function transform() { let $this = $( this ), options = $this.data( 'options' ); let $inline = $this.siblings( '.rwmb-datetime-inline' ); if ( !$inline.length ) { $inline = $this.closest( '.rwmb-input-group' ).siblings( '.rwmb-datetime-inline' ); } let $timestamp = $this.siblings( '.rwmb-datetime-timestamp' ), current = $this.val(), $picker = $inline.length ? $inline : $this; $this.siblings( '.ui-datepicker-append' ).remove(); // Remove appended text options.onSelect = function () { $this.trigger( 'change' ); }; options.beforeShow = function ( i ) { if ( $( i ).prop( 'readonly' ) ) { return false; } }; if ( $timestamp.length ) { options.onClose = options.onSelect = function () { $timestamp.val( getTimestamp( $picker.datetimepicker( 'getDate' ) ) ); $this.trigger( 'change' ); }; $this.on( 'change', () => { if ( !$this.val() ) { $timestamp.val( '' ); } } ); } if ( !$inline.length ) { $this.removeClass( 'hasDatepicker' ).datetimepicker( options ); return; } options.altField = '#' + $this.attr( 'id' ); $this.on( 'keydown', _.debounce( function () { // if val is empty, return to allow empty datepicker input. if ( !$this.val() ) { return; } $picker .datepicker( 'setDate', $this.val() ) .find( '.ui-datepicker-current-day' ) .trigger( 'click' ); }, 600 ) ); $inline .removeClass( 'hasDatepicker' ) .empty() .prop( 'id', '' ) .datetimepicker( options ) .datetimepicker( 'setDate', current ); } /** * Convert date to Unix timestamp in milliseconds * @link http://stackoverflow.com/a/14006555/556258 * @param date * @return number */ function getTimestamp( date ) { if ( date === null ) { return ''; } var milliseconds = Date.UTC( date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds() ); return Math.floor( milliseconds / 1000 ); } // Set language if available function setTimeI18n() { if ( $.timepicker.regional.hasOwnProperty( i18n.locale ) ) { $.timepicker.setDefaults( $.timepicker.regional[ i18n.locale ] ); } else if ( $.timepicker.regional.hasOwnProperty( i18n.localeShort ) ) { $.timepicker.setDefaults( $.timepicker.regional[ i18n.localeShort ] ); } } function init( e ) { /** * WordPress sets localized data for jQuery UI datepicker at document ready. * Using setTimeout to ensure the code runs after the localized data is set. * @link https://wordpress.org/support/topic/inline-date-field-not-localization/ */ setTimeout( () => { $( e.target ).find( '.rwmb-datetime' ).each( transform ); }, 0 ); } setTimeI18n(); rwmb.$document .on( 'mb_ready', init ) .on( 'clone', '.rwmb-datetime', transform ); } )( jQuery, _, rwmb, RWMB_Datetime ); ================================================ FILE: vendor/wpmetabox/meta-box/js/file-input.js ================================================ ( function ( $, rwmb ) { 'use strict'; var frame; function openSelectPopup( e ) { e.preventDefault(); var $el = $( this ); // Create a frame only if needed if ( ! frame ) { frame = wp.media( { className: 'media-frame rwmb-file-frame', multiple: false, title: rwmbFileInput.frameTitle } ); } // Open media uploader frame.open(); // Remove all attached 'select' event frame.off( 'select' ); // Handle selection frame.on( 'select', function () { var url = frame.state().get( 'selection' ).first().toJSON().url; $el.siblings( 'input' ).val( url ).trigger( 'change' ).siblings( 'a' ).removeClass( 'hidden' ); } ); } function changeValueInput( e ) { e.preventDefault(); var $el = $( this ), url = $el.val(), fileType = url.split( '.' ).pop().toLowerCase(), imageTypes = [ 'gif', 'jpeg', 'png', 'jpg' ], validImageTypes = imageTypes.includes( fileType ); if ( validImageTypes ) { $el.closest( '.rwmb-file-input-inner' ).siblings( '.rwmb-file-input-image' ).removeClass( 'rwmb-file-input-hidden' ).find( 'img' ).attr( 'src', url ); } else { $el.closest( '.rwmb-file-input-inner' ).siblings( '.rwmb-file-input-image' ).addClass( 'rwmb-file-input-hidden' ); } } function clearSelection( e ) { e.preventDefault(); $( this ).addClass( 'hidden' ).siblings( 'input' ).val( '' ).trigger( 'change' ); $( this ).closest( '.rwmb-file-input-inner' ).siblings( '.rwmb-file-input-image' ).addClass( 'rwmb-file-input-hidden' ); } function hideRemoveButtonWhenCloning() { $( this ).siblings( '.rwmb-file-input-remove' ).addClass( 'hidden' ); } rwmb.$document .on( 'click', '.rwmb-file-input-select', openSelectPopup ) .on( 'input change', '.rwmb-file_input', changeValueInput ) .on( 'click', '.rwmb-file-input-remove', clearSelection ) .on( 'clone', '.rwmb-file_input', hideRemoveButtonWhenCloning ); } )( jQuery, rwmb ); ================================================ FILE: vendor/wpmetabox/meta-box/js/file-upload.js ================================================ ( function ( $, wp, rwmb ) { 'use strict'; var views = rwmb.views = rwmb.views || {}, MediaField = views.MediaField, FileUploadField, UploadButton; FileUploadField = views.FileUploadField = MediaField.extend( { createAddButton: function () { this.addButton = new UploadButton( { controller: this.controller } ); } } ); UploadButton = views.UploadButton = Backbone.View.extend( { className: 'rwmb-upload-area', tagName: 'div', template: rwmb.template( `

      {{{ i18nRwmbMedia.uploadInstructions }}}

      {{{ i18nRwmbMedia.or }}}

      ` ), render: function () { this.$el.html( this.template( {} ) ); return this; }, initialize: function ( options ) { this.controller = options.controller; this.el.id = _.uniqueId( 'rwmb-upload-area-' ); this.render(); // Auto hide if you reach the max number of media this.listenTo( this.controller, 'change:full', function () { this.$el.toggle( !this.controller.get( 'full' ) ); } ); this.collection = this.controller.get( 'items' ); this.listenTo( this.collection, 'remove', function ( item ) { if ( item.get( 'file' ) !== undefined ) { this.uploader.uploader.removeFile( item.get( 'file' ) ); } const totalFiles = parseInt( this.uploader.uploader.getOption( 'totalFiles' ) ); this.uploader.uploader.setOption( 'totalFiles', totalFiles - 1 ); } ); }, // Initializes plupload using code from wp.Uploader (wp-includes/js/plupload/wp-plupload.js) initUploader: function ( $this ) { var self = this, $input = $this.closest( '.rwmb-input' ), $process = $input.find( '.rwmb-media-view .rwmb-media-progress' ), extensions = this.getExtensions().join( ',' ), maxFileSize = this.controller.get( 'maxFileSize' ), maxFiles = parseInt( this.controller.get( 'maxFiles' ) ), options = { container: this.el, dropzone: this.el, browser: this.$( '.rwmb-browse-button' ), params: { post_id: $( '#post_ID' ).val() }, added: function ( attachment ) { self.controller.get( 'items' ).add( [ attachment ] ); } }; // Initialize the plupload instance. this.uploader = new wp.Uploader( options ); var filters = this.uploader.uploader.getOption( 'filters' ); if ( maxFileSize ) { filters.max_file_size = maxFileSize; } if ( extensions ) { filters.mime_types = [ { title: i18nRwmbMedia.select, extensions: extensions } ]; } this.uploader.uploader.setOption( 'filters', filters ); this.uploader.uploader.setOption( 'totalFiles', 0 ); this.uploader.uploader.bind( 'FilesAdded', function ( up, files ) { const that = this, totalFiles = parseInt( that.getOption( 'totalFiles' ) ); $.each( files, function ( i, file ) { if ( maxFiles !== 0 && i >= maxFiles - totalFiles ) { up.removeFile( files[ i ] ); return; } $process.append( `
      ${ file.name } - ${ file.percent } %
      ` ); that.setOption( 'totalFiles', parseInt( that.getOption( 'totalFiles' ) ) + 1 ); } ); } ); const setWidth = ( file, value ) => $process.find( `#${ file.id }` ).attr( 'aria-valuenow', value ).css( '--value', value ).text( `${ file.name } - ${ value }%` ); this.uploader.uploader.bind( 'UploadProgress', ( up, file ) => setWidth( file, file.percent ).addClass( file.percent === 100 ? 'rwmb-progress--completed' : '' ) ); this.uploader.uploader.bind( 'FileUploaded', ( up, file ) => $process.find( `#${ file.id }` ).fadeOut( 'slow', function () { $( this ).remove(); } ) ); this.uploader.uploader.bind( 'Error', function ( up, err ) { if ( $input.find( '.rwmb-error' ).length === 0 ) { $input.append( '

      ' ); } const $error = $input.find( '.rwmb-error' ).empty().show(); $error.text( err.message ); setTimeout( function () { $error.fadeOut( "slow" ); }, 5000 ); } ); $this.data( 'uploader', this.uploader ); }, getExtensions: function () { var mimeTypes = this.controller.get( 'mimeType' ).split( ',' ), exts = []; _.each( mimeTypes, function ( current, index ) { if ( i18nRwmbMedia.extensions[ current ] ) { exts = exts.concat( i18nRwmbMedia.extensions[ current ] ); } } ); return exts; } } ); function initFileUpload() { var $this = $( this ), view = $this.data( 'view' ); if ( view ) { return; } view = new FileUploadField( { input: this } ); $this.siblings( '.rwmb-media-view' ).remove(); $this.after( view.el ); // Init progress view.$el.find( '.rwmb-media-list' ).after( '
      ' ); // Init uploader after view is inserted to make wp.Uploader works. view.addButton.initUploader( $this ); $this.data( 'view', view ); } function init( e ) { $( e.target ).find( '.rwmb-file_upload' ).each( initFileUpload ); } function removeFile( e ) { $( '.rwmb-media-progress #' + $( this ).data( 'file_id' ) ).remove(); } rwmb.$document .on( 'mb_ready', init ) .on( 'clone', '.rwmb-file_upload', initFileUpload ) .on( 'click', '.rwmb-file-actions .rwmb-remove-media', removeFile ); wp?.hooks?.addAction( 'mb_ready', 'meta-box/ready/file_upload', ref => { init( { target: ref } ); } ); } )( jQuery, wp, rwmb ); ================================================ FILE: vendor/wpmetabox/meta-box/js/file.js ================================================ ( function ( $, rwmb ) { 'use strict'; var file = {}; /** * Handles a click on add new file. * Expects `this` to equal the clicked element. * * @param event Click event. */ file.addHandler = function ( event ) { event.preventDefault(); var $this = $( this ), $clone = $this.prev().clone(); $clone.insertBefore( this ).val( '' ); var $fieldInput = $this.closest( '.rwmb-input' ); file.updateVisibility.call( $fieldInput.find( '.rwmb-files' ) ); file.setRequired.call( $fieldInput ); }; /** * Handles a click on delete new file. * Expects `this` to equal the clicked element. * * @param event Click event. */ file.deleteHandler = function ( event ) { event.preventDefault(); var $this = $( this ), $item = $this.closest( 'li' ), $uploaded = $this.closest( '.rwmb-files' ), $metaBox = $uploaded.closest( '.rwmb-meta-box' ); $item.remove(); file.updateVisibility.call( $uploaded ); file.setRequired.call( $uploaded.parent() ); if ( 1 > $uploaded.data( 'force_delete' ) ) { return; } $.post( ajaxurl, { action: 'rwmb_delete_file', _ajax_nonce: $uploaded.data( 'delete_nonce' ), field_id: $uploaded.data( 'field_id' ), field_name: $uploaded.data( 'field_name' ), object_type: $metaBox.data( 'object-type' ), object_id: $metaBox.data( 'object-id' ), attachment_id: $this.data( 'attachment_id' ) }, function ( response ) { if ( !response.success ) { alert( response.data ); } }, 'json' ); }; /** * Sort uploaded files. * Expects `this` to equal the uploaded file list. */ file.sort = function () { $( this ).sortable( { items: 'li', start: function ( event, ui ) { ui.placeholder.height( ui.helper.outerHeight() ); ui.placeholder.width( ui.helper.outerWidth() ); }, update: function ( event, ui ) { ui.item.find( rwmb.inputSelectors ).first().trigger( 'mb_change' ); } } ); }; /** * Update visibility of upload inputs and Add new file link. * Expect this equal to the uploaded file list. */ file.updateVisibility = function () { var $uploaded = $( this ), max = parseInt( $uploaded.data( 'max_file_uploads' ), 10 ), $new = $uploaded.siblings( '.rwmb-file-new' ), $add = $new.find( '.rwmb-file-add' ), numFiles = $uploaded.children().length, numInputs = $new.find( '.rwmb-file-input' ).length; $uploaded.toggle( 0 < numFiles ); if ( 0 === max ) { return; } $new.toggle( numFiles < max ); $add.toggle( numFiles + numInputs < max ); }; // Reset field when cloning. file.resetClone = function () { var $this = $( this ), $clone = $this.closest( '.rwmb-clone' ), $list = $clone.find( '.rwmb-files' ); $list.empty(); $clone.find( '.rwmb-file-new' ).each( function () { var inputName = '_file_' + rwmb.uniqid(), $key = $( this ).siblings( '.rwmb-file-index' ); $( this ).find( '.rwmb-file-input' ).attr( 'name', inputName + '[]' ).not( ':first' ).remove(); $key.val( inputName ); } ); file.updateVisibility.call( $list ); }; // Set 'required' attribute. 'this' is the wrapper field input. file.setRequired = function () { var $this = $( this ), $uploaded = $this.find( '.rwmb-files' ), $inputs = $this.find( '.rwmb-file-new input' ); $inputs.prop( 'required', false ); if ( $uploaded.children().length ) { return; } var $firstInput = $inputs.first(); if ( 1 === $firstInput.data( 'required' ) ) { $firstInput.prop( 'required', true ); } }; function init( e ) { var $el = $( e.target ), $uploaded = $el.find( '.rwmb-files' ); $uploaded.each( file.sort ); $uploaded.each( file.updateVisibility ); $el.find( '.rwmb-file-wrapper, .rwmb-image-wrapper' ).each( file.setRequired ); } rwmb.$document .on( 'mb_ready', init ) .on( 'click', '.rwmb-file-add', file.addHandler ) .on( 'click', '.rwmb-file-delete', file.deleteHandler ) .on( 'clone', '.rwmb-file-input', file.resetClone ); } )( jQuery, rwmb ); ================================================ FILE: vendor/wpmetabox/meta-box/js/icon.js ================================================ /** * Link: https://stackoverflow.com/questions/37386293/how-to-add-icon-in-select2 */ ( function ( $, rwmb ) { 'use strict'; const template = option => { if ( option.text.includes( '.*?<\/svg>/, '' ); return $( `${ option.text }` ); } return option.id ? $( `${ option.text }` ) : option.text; }; function initIconField( event, options ) { $( this ).select2( { ...options, templateResult: template, templateSelection: template, } ); } rwmb.$document .on( 'init_icon_field', '.rwmb-icon', initIconField ); } )( jQuery, rwmb ); ================================================ FILE: vendor/wpmetabox/meta-box/js/image-advanced.js ================================================ ( function ( $, rwmb ) { 'use strict'; var views = rwmb.views = rwmb.views || {}, MediaField = views.MediaField, MediaItem = views.MediaItem, MediaList = views.MediaList, ImageField; ImageField = views.ImageField = MediaField.extend( { createList: function () { this.list = new MediaList( { controller: this.controller, itemView: MediaItem.extend( { className: 'rwmb-image-item', template: rwmb.template( `
      <# if ( 'image' === data.type && data.sizes ) { #> <# if ( data.sizes[data.controller.imageSize] ) { #> <# } else { #> <# } #> <# } else { #> <# if ( data.image && data.image.src && data.image.src !== data.icon ) { #> <# } else { #> <# } #> <# } #>
      ` ), } ) } ); } } ); /** * Initialize image fields */ function initImageField() { var $this = $( this ), view = $this.data( 'view' ); if ( view ) { return; } view = new ImageField( { input: this } ); $this.siblings( '.rwmb-media-view' ).remove(); $this.after( view.el ); $this.data( 'view', view ); } function init( e ) { $( e.target ).find( '.rwmb-image_advanced' ).each( initImageField ); } rwmb.$document .on( 'mb_ready', init ) .on( 'clone', '.rwmb-image_advanced', initImageField ); wp?.hooks?.addAction( 'mb_ready', 'meta-box/ready/image_advanced', ref => { init( { target: ref } ); } ); } )( jQuery, rwmb ); ================================================ FILE: vendor/wpmetabox/meta-box/js/image-upload.js ================================================ ( function ( $, rwmb ) { 'use strict'; var views = rwmb.views = rwmb.views || {}, ImageField = views.ImageField, ImageUploadField, UploadButton = views.UploadButton; ImageUploadField = views.ImageUploadField = ImageField.extend( { createAddButton: function () { this.addButton = new UploadButton( {controller: this.controller} ); } } ); function initImageUpload() { var $this = $( this ), view = $this.data( 'view' ); if ( view ) { return; } view = new ImageUploadField( { input: this } ); $this.siblings( '.rwmb-media-view' ).remove(); $this.after( view.el ); // Init uploader after view is inserted to make wp.Uploader works. view.addButton.initUploader( $this ); $this.data( 'view', view ); } function init( e ) { $( e.target ).find( '.rwmb-image_upload, .rwmb-plupload_image' ).each( initImageUpload ); } rwmb.$document .on( 'mb_ready', init ) .on( 'clone', '.rwmb-image_upload, .rwmb-plupload_image', initImageUpload ) wp?.hooks?.addAction( 'mb_ready', 'meta-box/ready/image_upload', ref => { init( { target: ref } ); } ); } )( jQuery, rwmb ); ================================================ FILE: vendor/wpmetabox/meta-box/js/input-list.js ================================================ ( function ( $, rwmb ) { 'use strict'; function toggleTree() { var $this = $( this ), $children = $this.closest( 'label' ).next( 'fieldset' ); if ( $this.is( ':checked' ) ) { $children.removeClass( 'hidden' ); } else { $children.addClass( 'hidden' ).find( 'input' ).prop( 'checked', false ); } } function toggleAll( e ) { e.preventDefault(); var $this = $( this ), checked = $this.data( 'checked' ); if ( undefined === checked ) { checked = true; } $this.parent().siblings( '.rwmb-input-list' ).find( 'input' ).prop( 'checked', checked ).trigger( 'change' ); checked = !checked; $this.data( 'checked', checked ); } function init( e ) { $( e.target ).find( '.rwmb-input-list.rwmb-collapse input[type="checkbox"]' ).each( toggleTree ); } rwmb.$document .on( 'mb_ready', init ) .on( 'change', '.rwmb-input-list.rwmb-collapse input[type="checkbox"]', toggleTree ) .on( 'clone', '.rwmb-input-list.rwmb-collapse input[type="checkbox"]', toggleTree ) .on( 'click', '.rwmb-input-list-select-all-none', toggleAll ); } )( jQuery, rwmb ); ================================================ FILE: vendor/wpmetabox/meta-box/js/jqueryui/jquery-ui-sliderAccess.js ================================================ /* * jQuery UI Slider Access * By: Trent Richardson [http://trentrichardson.com] * Version 0.3 * Last Modified: 10/20/2012 * * Copyright 2011 Trent Richardson * Dual licensed under the MIT and GPL licenses. * http://trentrichardson.com/Impromptu/GPL-LICENSE.txt * http://trentrichardson.com/Impromptu/MIT-LICENSE.txt * */ (function($){ $.fn.extend({ sliderAccess: function(options){ options = options || {}; options.touchonly = options.touchonly !== undefined? options.touchonly : true; // by default only show it if touch device if(options.touchonly === true && !("ontouchend" in document)){ return $(this); } return $(this).each(function(i,obj){ var $t = $(this), o = $.extend({},{ where: 'after', step: $t.slider('option','step'), upIcon: 'ui-icon-plus', downIcon: 'ui-icon-minus', text: false, upText: '+', downText: '-', buttonset: true, buttonsetTag: 'span', isRTL: false }, options), $buttons = $('<'+ o.buttonsetTag +' class="ui-slider-access">'+ ''+ ''+ ''); $buttons.children('button').each(function(j, jobj){ var $jt = $(this); $jt.button({ text: o.text, icons: { primary: $jt.data('icon') } }) .click(function(e){ var step = $jt.data('step'), curr = $t.slider('value'), newval = curr += step*1, minval = $t.slider('option','min'), maxval = $t.slider('option','max'), slidee = $t.slider("option", "slide") || function(){}, stope = $t.slider("option", "stop") || function(){}; e.preventDefault(); if(newval < minval || newval > maxval){ return; } $t.slider('value', newval); slidee.call($t, null, { value: newval }); stope.call($t, null, { value: newval }); }); }); // before or after $t[o.where]($buttons); if(o.buttonset){ $buttons.removeClass('ui-corner-right').removeClass('ui-corner-left').buttonset(); $buttons.eq(0).addClass('ui-corner-left'); $buttons.eq(1).addClass('ui-corner-right'); } // adjust the width so we don't break the original layout var bOuterWidth = $buttons.css({ marginLeft: ((o.where === 'after' && !o.isRTL) || (o.where === 'before' && o.isRTL)? 10:0), marginRight: ((o.where === 'before' && !o.isRTL) || (o.where === 'after' && o.isRTL)? 10:0) }).outerWidth(true) + 5; var tOuterWidth = $t.outerWidth(true); $t.css('display','inline-block').width(tOuterWidth-bOuterWidth); }); } }); })(jQuery); ================================================ FILE: vendor/wpmetabox/meta-box/js/leaflet/leaflet.css ================================================ /* required styles */ .leaflet-pane, .leaflet-tile, .leaflet-marker-icon, .leaflet-marker-shadow, .leaflet-tile-container, .leaflet-pane > svg, .leaflet-pane > canvas, .leaflet-zoom-box, .leaflet-image-layer, .leaflet-layer { position: absolute; left: 0; top: 0; } .leaflet-container { overflow: hidden; } .leaflet-tile, .leaflet-marker-icon, .leaflet-marker-shadow { -webkit-user-select: none; -moz-user-select: none; user-select: none; -webkit-user-drag: none; } /* Prevents IE11 from highlighting tiles in blue */ .leaflet-tile::selection { background: transparent; } /* Safari renders non-retina tile on retina better with this, but Chrome is worse */ .leaflet-safari .leaflet-tile { image-rendering: -webkit-optimize-contrast; } /* hack that prevents hw layers "stretching" when loading new tiles */ .leaflet-safari .leaflet-tile-container { width: 1600px; height: 1600px; -webkit-transform-origin: 0 0; } .leaflet-marker-icon, .leaflet-marker-shadow { display: block; } /* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */ /* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */ .leaflet-container .leaflet-overlay-pane svg { max-width: none !important; max-height: none !important; } .leaflet-container .leaflet-marker-pane img, .leaflet-container .leaflet-shadow-pane img, .leaflet-container .leaflet-tile-pane img, .leaflet-container img.leaflet-image-layer, .leaflet-container .leaflet-tile { max-width: none !important; max-height: none !important; width: auto; padding: 0; } .leaflet-container img.leaflet-tile { /* See: https://bugs.chromium.org/p/chromium/issues/detail?id=600120 */ mix-blend-mode: plus-lighter; } .leaflet-container.leaflet-touch-zoom { -ms-touch-action: pan-x pan-y; touch-action: pan-x pan-y; } .leaflet-container.leaflet-touch-drag { -ms-touch-action: pinch-zoom; /* Fallback for FF which doesn't support pinch-zoom */ touch-action: none; touch-action: pinch-zoom; } .leaflet-container.leaflet-touch-drag.leaflet-touch-zoom { -ms-touch-action: none; touch-action: none; } .leaflet-container { -webkit-tap-highlight-color: transparent; } .leaflet-container a { -webkit-tap-highlight-color: rgba(51, 181, 229, 0.4); } .leaflet-tile { filter: inherit; visibility: hidden; } .leaflet-tile-loaded { visibility: inherit; } .leaflet-zoom-box { width: 0; height: 0; -moz-box-sizing: border-box; box-sizing: border-box; z-index: 800; } /* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */ .leaflet-overlay-pane svg { -moz-user-select: none; } .leaflet-pane { z-index: 400; } .leaflet-tile-pane { z-index: 200; } .leaflet-overlay-pane { z-index: 400; } .leaflet-shadow-pane { z-index: 500; } .leaflet-marker-pane { z-index: 600; } .leaflet-tooltip-pane { z-index: 650; } .leaflet-popup-pane { z-index: 700; } .leaflet-map-pane canvas { z-index: 100; } .leaflet-map-pane svg { z-index: 200; } .leaflet-vml-shape { width: 1px; height: 1px; } .lvml { behavior: url(#default#VML); display: inline-block; position: absolute; } /* control positioning */ .leaflet-control { position: relative; z-index: 800; pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */ pointer-events: auto; } .leaflet-top, .leaflet-bottom { position: absolute; z-index: 1000; pointer-events: none; } .leaflet-top { top: 0; } .leaflet-right { right: 0; } .leaflet-bottom { bottom: 0; } .leaflet-left { left: 0; } .leaflet-control { float: left; clear: both; } .leaflet-right .leaflet-control { float: right; } .leaflet-top .leaflet-control { margin-top: 10px; } .leaflet-bottom .leaflet-control { margin-bottom: 10px; } .leaflet-left .leaflet-control { margin-left: 10px; } .leaflet-right .leaflet-control { margin-right: 10px; } /* zoom and fade animations */ .leaflet-fade-anim .leaflet-popup { opacity: 0; -webkit-transition: opacity 0.2s linear; -moz-transition: opacity 0.2s linear; transition: opacity 0.2s linear; } .leaflet-fade-anim .leaflet-map-pane .leaflet-popup { opacity: 1; } .leaflet-zoom-animated { -webkit-transform-origin: 0 0; -ms-transform-origin: 0 0; transform-origin: 0 0; } svg.leaflet-zoom-animated { will-change: transform; } .leaflet-zoom-anim .leaflet-zoom-animated { -webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1); -moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1); transition: transform 0.25s cubic-bezier(0,0,0.25,1); } .leaflet-zoom-anim .leaflet-tile, .leaflet-pan-anim .leaflet-tile { -webkit-transition: none; -moz-transition: none; transition: none; } .leaflet-zoom-anim .leaflet-zoom-hide { visibility: hidden; } /* cursors */ .leaflet-interactive { cursor: pointer; } .leaflet-grab { cursor: -webkit-grab; cursor: -moz-grab; cursor: grab; } .leaflet-crosshair, .leaflet-crosshair .leaflet-interactive { cursor: crosshair; } .leaflet-popup-pane, .leaflet-control { cursor: auto; } .leaflet-dragging .leaflet-grab, .leaflet-dragging .leaflet-grab .leaflet-interactive, .leaflet-dragging .leaflet-marker-draggable { cursor: move; cursor: -webkit-grabbing; cursor: -moz-grabbing; cursor: grabbing; } /* marker & overlays interactivity */ .leaflet-marker-icon, .leaflet-marker-shadow, .leaflet-image-layer, .leaflet-pane > svg path, .leaflet-tile-container { pointer-events: none; } .leaflet-marker-icon.leaflet-interactive, .leaflet-image-layer.leaflet-interactive, .leaflet-pane > svg path.leaflet-interactive, svg.leaflet-image-layer.leaflet-interactive path { pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */ pointer-events: auto; } /* visual tweaks */ .leaflet-container { background: #ddd; outline-offset: 1px; } .leaflet-container a { color: #0078A8; } .leaflet-zoom-box { border: 2px dotted #38f; background: rgba(255,255,255,0.5); } /* general typography */ .leaflet-container { font-family: "Helvetica Neue", Arial, Helvetica, sans-serif; font-size: 12px; font-size: 0.75rem; line-height: 1.5; } /* general toolbar styles */ .leaflet-bar { box-shadow: 0 1px 5px rgba(0,0,0,0.65); border-radius: 4px; } .leaflet-bar a { background-color: #fff; border-bottom: 1px solid #ccc; width: 26px; height: 26px; line-height: 26px; display: block; text-align: center; text-decoration: none; color: black; } .leaflet-bar a, .leaflet-control-layers-toggle { background-position: 50% 50%; background-repeat: no-repeat; display: block; } .leaflet-bar a:hover, .leaflet-bar a:focus { background-color: #f4f4f4; } .leaflet-bar a:first-child { border-top-left-radius: 4px; border-top-right-radius: 4px; } .leaflet-bar a:last-child { border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; border-bottom: none; } .leaflet-bar a.leaflet-disabled { cursor: default; background-color: #f4f4f4; color: #bbb; } .leaflet-touch .leaflet-bar a { width: 30px; height: 30px; line-height: 30px; } .leaflet-touch .leaflet-bar a:first-child { border-top-left-radius: 2px; border-top-right-radius: 2px; } .leaflet-touch .leaflet-bar a:last-child { border-bottom-left-radius: 2px; border-bottom-right-radius: 2px; } /* zoom control */ .leaflet-control-zoom-in, .leaflet-control-zoom-out { font: bold 18px 'Lucida Console', Monaco, monospace; text-indent: 1px; } .leaflet-touch .leaflet-control-zoom-in, .leaflet-touch .leaflet-control-zoom-out { font-size: 22px; } /* layers control */ .leaflet-control-layers { box-shadow: 0 1px 5px rgba(0,0,0,0.4); background: #fff; border-radius: 5px; } .leaflet-control-layers-toggle { background-image: url(images/layers.png); width: 36px; height: 36px; } .leaflet-retina .leaflet-control-layers-toggle { background-image: url(images/layers-2x.png); background-size: 26px 26px; } .leaflet-touch .leaflet-control-layers-toggle { width: 44px; height: 44px; } .leaflet-control-layers .leaflet-control-layers-list, .leaflet-control-layers-expanded .leaflet-control-layers-toggle { display: none; } .leaflet-control-layers-expanded .leaflet-control-layers-list { display: block; position: relative; } .leaflet-control-layers-expanded { padding: 6px 10px 6px 6px; color: #333; background: #fff; } .leaflet-control-layers-scrollbar { overflow-y: scroll; overflow-x: hidden; padding-right: 5px; } .leaflet-control-layers-selector { margin-top: 2px; position: relative; top: 1px; } .leaflet-control-layers label { display: block; font-size: 13px; font-size: 1.08333em; } .leaflet-control-layers-separator { height: 0; border-top: 1px solid #ddd; margin: 5px -10px 5px -6px; } /* Default icon URLs */ .leaflet-default-icon-path { /* used only in path-guessing heuristic, see L.Icon.Default */ background-image: url(images/marker-icon.png); } /* attribution and scale controls */ .leaflet-container .leaflet-control-attribution { background: #fff; background: rgba(255, 255, 255, 0.8); margin: 0; } .leaflet-control-attribution, .leaflet-control-scale-line { padding: 0 5px; color: #333; line-height: 1.4; } .leaflet-control-attribution a { text-decoration: none; } .leaflet-control-attribution a:hover, .leaflet-control-attribution a:focus { text-decoration: underline; } .leaflet-attribution-flag { display: inline !important; vertical-align: baseline !important; width: 1em; height: 0.6669em; } .leaflet-left .leaflet-control-scale { margin-left: 5px; } .leaflet-bottom .leaflet-control-scale { margin-bottom: 5px; } .leaflet-control-scale-line { border: 2px solid #777; border-top: none; line-height: 1.1; padding: 2px 5px 1px; white-space: nowrap; -moz-box-sizing: border-box; box-sizing: border-box; background: rgba(255, 255, 255, 0.8); text-shadow: 1px 1px #fff; } .leaflet-control-scale-line:not(:first-child) { border-top: 2px solid #777; border-bottom: none; margin-top: -2px; } .leaflet-control-scale-line:not(:first-child):not(:last-child) { border-bottom: 2px solid #777; } .leaflet-touch .leaflet-control-attribution, .leaflet-touch .leaflet-control-layers, .leaflet-touch .leaflet-bar { box-shadow: none; } .leaflet-touch .leaflet-control-layers, .leaflet-touch .leaflet-bar { border: 2px solid rgba(0,0,0,0.2); background-clip: padding-box; } /* popup */ .leaflet-popup { position: absolute; text-align: center; margin-bottom: 20px; } .leaflet-popup-content-wrapper { padding: 1px; text-align: left; border-radius: 12px; } .leaflet-popup-content { margin: 13px 24px 13px 20px; line-height: 1.3; font-size: 13px; font-size: 1.08333em; min-height: 1px; } .leaflet-popup-content p { margin: 17px 0; margin: 1.3em 0; } .leaflet-popup-tip-container { width: 40px; height: 20px; position: absolute; left: 50%; margin-top: -1px; margin-left: -20px; overflow: hidden; pointer-events: none; } .leaflet-popup-tip { width: 17px; height: 17px; padding: 1px; margin: -10px auto 0; pointer-events: auto; -webkit-transform: rotate(45deg); -moz-transform: rotate(45deg); -ms-transform: rotate(45deg); transform: rotate(45deg); } .leaflet-popup-content-wrapper, .leaflet-popup-tip { background: white; color: #333; box-shadow: 0 3px 14px rgba(0,0,0,0.4); } .leaflet-container a.leaflet-popup-close-button { position: absolute; top: 0; right: 0; border: none; text-align: center; width: 24px; height: 24px; font: 16px/24px Tahoma, Verdana, sans-serif; color: #757575; text-decoration: none; background: transparent; } .leaflet-container a.leaflet-popup-close-button:hover, .leaflet-container a.leaflet-popup-close-button:focus { color: #585858; } .leaflet-popup-scrolled { overflow: auto; } .leaflet-oldie .leaflet-popup-content-wrapper { -ms-zoom: 1; } .leaflet-oldie .leaflet-popup-tip { width: 24px; margin: 0 auto; -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)"; filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678); } .leaflet-oldie .leaflet-control-zoom, .leaflet-oldie .leaflet-control-layers, .leaflet-oldie .leaflet-popup-content-wrapper, .leaflet-oldie .leaflet-popup-tip { border: 1px solid #999; } /* div icon */ .leaflet-div-icon { background: #fff; border: 1px solid #666; } /* Tooltip */ /* Base styles for the element that has a tooltip */ .leaflet-tooltip { position: absolute; padding: 6px; background-color: #fff; border: 1px solid #fff; border-radius: 3px; color: #222; white-space: nowrap; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; pointer-events: none; box-shadow: 0 1px 3px rgba(0,0,0,0.4); } .leaflet-tooltip.leaflet-interactive { cursor: pointer; pointer-events: auto; } .leaflet-tooltip-top:before, .leaflet-tooltip-bottom:before, .leaflet-tooltip-left:before, .leaflet-tooltip-right:before { position: absolute; pointer-events: none; border: 6px solid transparent; background: transparent; content: ""; } /* Directions */ .leaflet-tooltip-bottom { margin-top: 6px; } .leaflet-tooltip-top { margin-top: -6px; } .leaflet-tooltip-bottom:before, .leaflet-tooltip-top:before { left: 50%; margin-left: -6px; } .leaflet-tooltip-top:before { bottom: 0; margin-bottom: -12px; border-top-color: #fff; } .leaflet-tooltip-bottom:before { top: 0; margin-top: -12px; margin-left: -6px; border-bottom-color: #fff; } .leaflet-tooltip-left { margin-left: -6px; } .leaflet-tooltip-right { margin-left: 6px; } .leaflet-tooltip-left:before, .leaflet-tooltip-right:before { top: 50%; margin-top: -6px; } .leaflet-tooltip-left:before { right: 0; margin-right: -12px; border-left-color: #fff; } .leaflet-tooltip-right:before { left: 0; margin-left: -12px; border-right-color: #fff; } /* Printing */ @media print { /* Prevent printers from removing background-images of controls. */ .leaflet-control { -webkit-print-color-adjust: exact; print-color-adjust: exact; } } ================================================ FILE: vendor/wpmetabox/meta-box/js/leaflet/leaflet.js ================================================ /* @preserve * Leaflet 1.9.4, a JS library for interactive maps. https://leafletjs.com * (c) 2010-2023 Vladimir Agafonkin, (c) 2010-2011 CloudMade */ !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).leaflet={})}(this,function(t){"use strict";function l(t){for(var e,i,n=1,o=arguments.length;n=this.min.x&&i.x<=this.max.x&&e.y>=this.min.y&&i.y<=this.max.y},intersects:function(t){t=_(t);var e=this.min,i=this.max,n=t.min,t=t.max,o=t.x>=e.x&&n.x<=i.x,t=t.y>=e.y&&n.y<=i.y;return o&&t},overlaps:function(t){t=_(t);var e=this.min,i=this.max,n=t.min,t=t.max,o=t.x>e.x&&n.xe.y&&n.y=n.lat&&i.lat<=o.lat&&e.lng>=n.lng&&i.lng<=o.lng},intersects:function(t){t=g(t);var e=this._southWest,i=this._northEast,n=t.getSouthWest(),t=t.getNorthEast(),o=t.lat>=e.lat&&n.lat<=i.lat,t=t.lng>=e.lng&&n.lng<=i.lng;return o&&t},overlaps:function(t){t=g(t);var e=this._southWest,i=this._northEast,n=t.getSouthWest(),t=t.getNorthEast(),o=t.lat>e.lat&&n.late.lng&&n.lng","http://www.w3.org/2000/svg"===(Wt.firstChild&&Wt.firstChild.namespaceURI));function y(t){return 0<=navigator.userAgent.toLowerCase().indexOf(t)}var b={ie:pt,ielt9:mt,edge:n,webkit:ft,android:gt,android23:vt,androidStock:yt,opera:xt,chrome:wt,gecko:bt,safari:Pt,phantom:Lt,opera12:o,win:Tt,ie3d:Mt,webkit3d:zt,gecko3d:_t,any3d:Ct,mobile:Zt,mobileWebkit:St,mobileWebkit3d:Et,msPointer:kt,pointer:Ot,touch:Bt,touchNative:At,mobileOpera:It,mobileGecko:Rt,retina:Nt,passiveEvents:Dt,canvas:jt,svg:Ht,vml:!Ht&&function(){try{var t=document.createElement("div"),e=(t.innerHTML='',t.firstChild);return e.style.behavior="url(#default#VML)",e&&"object"==typeof e.adj}catch(t){return!1}}(),inlineSvg:Wt,mac:0===navigator.platform.indexOf("Mac"),linux:0===navigator.platform.indexOf("Linux")},Ft=b.msPointer?"MSPointerDown":"pointerdown",Ut=b.msPointer?"MSPointerMove":"pointermove",Vt=b.msPointer?"MSPointerUp":"pointerup",qt=b.msPointer?"MSPointerCancel":"pointercancel",Gt={touchstart:Ft,touchmove:Ut,touchend:Vt,touchcancel:qt},Kt={touchstart:function(t,e){e.MSPOINTER_TYPE_TOUCH&&e.pointerType===e.MSPOINTER_TYPE_TOUCH&&O(e);ee(t,e)},touchmove:ee,touchend:ee,touchcancel:ee},Yt={},Xt=!1;function Jt(t,e,i){return"touchstart"!==e||Xt||(document.addEventListener(Ft,$t,!0),document.addEventListener(Ut,Qt,!0),document.addEventListener(Vt,te,!0),document.addEventListener(qt,te,!0),Xt=!0),Kt[e]?(i=Kt[e].bind(this,i),t.addEventListener(Gt[e],i,!1),i):(console.warn("wrong event specified:",e),u)}function $t(t){Yt[t.pointerId]=t}function Qt(t){Yt[t.pointerId]&&(Yt[t.pointerId]=t)}function te(t){delete Yt[t.pointerId]}function ee(t,e){if(e.pointerType!==(e.MSPOINTER_TYPE_MOUSE||"mouse")){for(var i in e.touches=[],Yt)e.touches.push(Yt[i]);e.changedTouches=[e],t(e)}}var ie=200;function ne(t,i){t.addEventListener("dblclick",i);var n,o=0;function e(t){var e;1!==t.detail?n=t.detail:"mouse"===t.pointerType||t.sourceCapabilities&&!t.sourceCapabilities.firesTouchEvents||((e=Ne(t)).some(function(t){return t instanceof HTMLLabelElement&&t.attributes.for})&&!e.some(function(t){return t instanceof HTMLInputElement||t instanceof HTMLSelectElement})||((e=Date.now())-o<=ie?2===++n&&i(function(t){var e,i,n={};for(i in t)e=t[i],n[i]=e&&e.bind?e.bind(t):e;return(t=n).type="dblclick",n.detail=2,n.isTrusted=!1,n._simulated=!0,n}(t)):n=1,o=e))}return t.addEventListener("click",e),{dblclick:i,simDblclick:e}}var oe,se,re,ae,he,le,ue=we(["transform","webkitTransform","OTransform","MozTransform","msTransform"]),ce=we(["webkitTransition","transition","OTransition","MozTransition","msTransition"]),de="webkitTransition"===ce||"OTransition"===ce?ce+"End":"transitionend";function _e(t){return"string"==typeof t?document.getElementById(t):t}function pe(t,e){var i=t.style[e]||t.currentStyle&&t.currentStyle[e];return"auto"===(i=i&&"auto"!==i||!document.defaultView?i:(t=document.defaultView.getComputedStyle(t,null))?t[e]:null)?null:i}function P(t,e,i){t=document.createElement(t);return t.className=e||"",i&&i.appendChild(t),t}function T(t){var e=t.parentNode;e&&e.removeChild(t)}function me(t){for(;t.firstChild;)t.removeChild(t.firstChild)}function fe(t){var e=t.parentNode;e&&e.lastChild!==t&&e.appendChild(t)}function ge(t){var e=t.parentNode;e&&e.firstChild!==t&&e.insertBefore(t,e.firstChild)}function ve(t,e){return void 0!==t.classList?t.classList.contains(e):0<(t=xe(t)).length&&new RegExp("(^|\\s)"+e+"(\\s|$)").test(t)}function M(t,e){var i;if(void 0!==t.classList)for(var n=F(e),o=0,s=n.length;othis.options.maxZoom)?this.setZoom(t):this},panInsideBounds:function(t,e){this._enforcingBounds=!0;var i=this.getCenter(),t=this._limitCenter(i,this._zoom,g(t));return i.equals(t)||this.panTo(t,e),this._enforcingBounds=!1,this},panInside:function(t,e){var i=m((e=e||{}).paddingTopLeft||e.padding||[0,0]),n=m(e.paddingBottomRight||e.padding||[0,0]),o=this.project(this.getCenter()),t=this.project(t),s=this.getPixelBounds(),i=_([s.min.add(i),s.max.subtract(n)]),s=i.getSize();return i.contains(t)||(this._enforcingBounds=!0,n=t.subtract(i.getCenter()),i=i.extend(t).getSize().subtract(s),o.x+=n.x<0?-i.x:i.x,o.y+=n.y<0?-i.y:i.y,this.panTo(this.unproject(o),e),this._enforcingBounds=!1),this},invalidateSize:function(t){if(!this._loaded)return this;t=l({animate:!1,pan:!0},!0===t?{animate:!0}:t);var e=this.getSize(),i=(this._sizeChanged=!0,this._lastCenter=null,this.getSize()),n=e.divideBy(2).round(),o=i.divideBy(2).round(),n=n.subtract(o);return n.x||n.y?(t.animate&&t.pan?this.panBy(n):(t.pan&&this._rawPanBy(n),this.fire("move"),t.debounceMoveend?(clearTimeout(this._sizeTimer),this._sizeTimer=setTimeout(a(this.fire,this,"moveend"),200)):this.fire("moveend")),this.fire("resize",{oldSize:e,newSize:i})):this},stop:function(){return this.setZoom(this._limitZoom(this._zoom)),this.options.zoomSnap||this.fire("viewreset"),this._stop()},locate:function(t){var e,i;return t=this._locateOptions=l({timeout:1e4,watch:!1},t),"geolocation"in navigator?(e=a(this._handleGeolocationResponse,this),i=a(this._handleGeolocationError,this),t.watch?this._locationWatchId=navigator.geolocation.watchPosition(e,i,t):navigator.geolocation.getCurrentPosition(e,i,t)):this._handleGeolocationError({code:0,message:"Geolocation not supported."}),this},stopLocate:function(){return navigator.geolocation&&navigator.geolocation.clearWatch&&navigator.geolocation.clearWatch(this._locationWatchId),this._locateOptions&&(this._locateOptions.setView=!1),this},_handleGeolocationError:function(t){var e;this._container._leaflet_id&&(e=t.code,t=t.message||(1===e?"permission denied":2===e?"position unavailable":"timeout"),this._locateOptions.setView&&!this._loaded&&this.fitWorld(),this.fire("locationerror",{code:e,message:"Geolocation error: "+t+"."}))},_handleGeolocationResponse:function(t){if(this._container._leaflet_id){var e,i,n=new v(t.coords.latitude,t.coords.longitude),o=n.toBounds(2*t.coords.accuracy),s=this._locateOptions,r=(s.setView&&(e=this.getBoundsZoom(o),this.setView(n,s.maxZoom?Math.min(e,s.maxZoom):e)),{latlng:n,bounds:o,timestamp:t.timestamp});for(i in t.coords)"number"==typeof t.coords[i]&&(r[i]=t.coords[i]);this.fire("locationfound",r)}},addHandler:function(t,e){return e&&(e=this[t]=new e(this),this._handlers.push(e),this.options[t]&&e.enable()),this},remove:function(){if(this._initEvents(!0),this.options.maxBounds&&this.off("moveend",this._panInsideMaxBounds),this._containerId!==this._container._leaflet_id)throw new Error("Map container is being reused by another instance");try{delete this._container._leaflet_id,delete this._containerId}catch(t){this._container._leaflet_id=void 0,this._containerId=void 0}for(var t in void 0!==this._locationWatchId&&this.stopLocate(),this._stop(),T(this._mapPane),this._clearControlPos&&this._clearControlPos(),this._resizeRequest&&(r(this._resizeRequest),this._resizeRequest=null),this._clearHandlers(),this._loaded&&this.fire("unload"),this._layers)this._layers[t].remove();for(t in this._panes)T(this._panes[t]);return this._layers=[],this._panes=[],delete this._mapPane,delete this._renderer,this},createPane:function(t,e){e=P("div","leaflet-pane"+(t?" leaflet-"+t.replace("Pane","")+"-pane":""),e||this._mapPane);return t&&(this._panes[t]=e),e},getCenter:function(){return this._checkIfLoaded(),this._lastCenter&&!this._moved()?this._lastCenter.clone():this.layerPointToLatLng(this._getCenterLayerPoint())},getZoom:function(){return this._zoom},getBounds:function(){var t=this.getPixelBounds();return new s(this.unproject(t.getBottomLeft()),this.unproject(t.getTopRight()))},getMinZoom:function(){return void 0===this.options.minZoom?this._layersMinZoom||0:this.options.minZoom},getMaxZoom:function(){return void 0===this.options.maxZoom?void 0===this._layersMaxZoom?1/0:this._layersMaxZoom:this.options.maxZoom},getBoundsZoom:function(t,e,i){t=g(t),i=m(i||[0,0]);var n=this.getZoom()||0,o=this.getMinZoom(),s=this.getMaxZoom(),r=t.getNorthWest(),t=t.getSouthEast(),i=this.getSize().subtract(i),t=_(this.project(t,n),this.project(r,n)).getSize(),r=b.any3d?this.options.zoomSnap:1,a=i.x/t.x,i=i.y/t.y,t=e?Math.max(a,i):Math.min(a,i),n=this.getScaleZoom(t,n);return r&&(n=Math.round(n/(r/100))*(r/100),n=e?Math.ceil(n/r)*r:Math.floor(n/r)*r),Math.max(o,Math.min(s,n))},getSize:function(){return this._size&&!this._sizeChanged||(this._size=new p(this._container.clientWidth||0,this._container.clientHeight||0),this._sizeChanged=!1),this._size.clone()},getPixelBounds:function(t,e){t=this._getTopLeftPoint(t,e);return new f(t,t.add(this.getSize()))},getPixelOrigin:function(){return this._checkIfLoaded(),this._pixelOrigin},getPixelWorldBounds:function(t){return this.options.crs.getProjectedBounds(void 0===t?this.getZoom():t)},getPane:function(t){return"string"==typeof t?this._panes[t]:t},getPanes:function(){return this._panes},getContainer:function(){return this._container},getZoomScale:function(t,e){var i=this.options.crs;return e=void 0===e?this._zoom:e,i.scale(t)/i.scale(e)},getScaleZoom:function(t,e){var i=this.options.crs,t=(e=void 0===e?this._zoom:e,i.zoom(t*i.scale(e)));return isNaN(t)?1/0:t},project:function(t,e){return e=void 0===e?this._zoom:e,this.options.crs.latLngToPoint(w(t),e)},unproject:function(t,e){return e=void 0===e?this._zoom:e,this.options.crs.pointToLatLng(m(t),e)},layerPointToLatLng:function(t){t=m(t).add(this.getPixelOrigin());return this.unproject(t)},latLngToLayerPoint:function(t){return this.project(w(t))._round()._subtract(this.getPixelOrigin())},wrapLatLng:function(t){return this.options.crs.wrapLatLng(w(t))},wrapLatLngBounds:function(t){return this.options.crs.wrapLatLngBounds(g(t))},distance:function(t,e){return this.options.crs.distance(w(t),w(e))},containerPointToLayerPoint:function(t){return m(t).subtract(this._getMapPanePos())},layerPointToContainerPoint:function(t){return m(t).add(this._getMapPanePos())},containerPointToLatLng:function(t){t=this.containerPointToLayerPoint(m(t));return this.layerPointToLatLng(t)},latLngToContainerPoint:function(t){return this.layerPointToContainerPoint(this.latLngToLayerPoint(w(t)))},mouseEventToContainerPoint:function(t){return De(t,this._container)},mouseEventToLayerPoint:function(t){return this.containerPointToLayerPoint(this.mouseEventToContainerPoint(t))},mouseEventToLatLng:function(t){return this.layerPointToLatLng(this.mouseEventToLayerPoint(t))},_initContainer:function(t){t=this._container=_e(t);if(!t)throw new Error("Map container not found.");if(t._leaflet_id)throw new Error("Map container is already initialized.");S(t,"scroll",this._onScroll,this),this._containerId=h(t)},_initLayout:function(){var t=this._container,e=(this._fadeAnimated=this.options.fadeAnimation&&b.any3d,M(t,"leaflet-container"+(b.touch?" leaflet-touch":"")+(b.retina?" leaflet-retina":"")+(b.ielt9?" leaflet-oldie":"")+(b.safari?" leaflet-safari":"")+(this._fadeAnimated?" leaflet-fade-anim":"")),pe(t,"position"));"absolute"!==e&&"relative"!==e&&"fixed"!==e&&"sticky"!==e&&(t.style.position="relative"),this._initPanes(),this._initControlPos&&this._initControlPos()},_initPanes:function(){var t=this._panes={};this._paneRenderers={},this._mapPane=this.createPane("mapPane",this._container),Z(this._mapPane,new p(0,0)),this.createPane("tilePane"),this.createPane("overlayPane"),this.createPane("shadowPane"),this.createPane("markerPane"),this.createPane("tooltipPane"),this.createPane("popupPane"),this.options.markerZoomAnimation||(M(t.markerPane,"leaflet-zoom-hide"),M(t.shadowPane,"leaflet-zoom-hide"))},_resetView:function(t,e,i){Z(this._mapPane,new p(0,0));var n=!this._loaded,o=(this._loaded=!0,e=this._limitZoom(e),this.fire("viewprereset"),this._zoom!==e);this._moveStart(o,i)._move(t,e)._moveEnd(o),this.fire("viewreset"),n&&this.fire("load")},_moveStart:function(t,e){return t&&this.fire("zoomstart"),e||this.fire("movestart"),this},_move:function(t,e,i,n){void 0===e&&(e=this._zoom);var o=this._zoom!==e;return this._zoom=e,this._lastCenter=t,this._pixelOrigin=this._getNewPixelOrigin(t),n?i&&i.pinch&&this.fire("zoom",i):((o||i&&i.pinch)&&this.fire("zoom",i),this.fire("move",i)),this},_moveEnd:function(t){return t&&this.fire("zoomend"),this.fire("moveend")},_stop:function(){return r(this._flyToFrame),this._panAnim&&this._panAnim.stop(),this},_rawPanBy:function(t){Z(this._mapPane,this._getMapPanePos().subtract(t))},_getZoomSpan:function(){return this.getMaxZoom()-this.getMinZoom()},_panInsideMaxBounds:function(){this._enforcingBounds||this.panInsideBounds(this.options.maxBounds)},_checkIfLoaded:function(){if(!this._loaded)throw new Error("Set map center and zoom first.")},_initEvents:function(t){this._targets={};var e=t?k:S;e((this._targets[h(this._container)]=this)._container,"click dblclick mousedown mouseup mouseover mouseout mousemove contextmenu keypress keydown keyup",this._handleDOMEvent,this),this.options.trackResize&&e(window,"resize",this._onResize,this),b.any3d&&this.options.transform3DLimit&&(t?this.off:this.on).call(this,"moveend",this._onMoveEnd)},_onResize:function(){r(this._resizeRequest),this._resizeRequest=x(function(){this.invalidateSize({debounceMoveend:!0})},this)},_onScroll:function(){this._container.scrollTop=0,this._container.scrollLeft=0},_onMoveEnd:function(){var t=this._getMapPanePos();Math.max(Math.abs(t.x),Math.abs(t.y))>=this.options.transform3DLimit&&this._resetView(this.getCenter(),this.getZoom())},_findEventTargets:function(t,e){for(var i,n=[],o="mouseout"===e||"mouseover"===e,s=t.target||t.srcElement,r=!1;s;){if((i=this._targets[h(s)])&&("click"===e||"preclick"===e)&&this._draggableMoved(i)){r=!0;break}if(i&&i.listens(e,!0)){if(o&&!We(s,t))break;if(n.push(i),o)break}if(s===this._container)break;s=s.parentNode}return n=n.length||r||o||!this.listens(e,!0)?n:[this]},_isClickDisabled:function(t){for(;t&&t!==this._container;){if(t._leaflet_disable_click)return!0;t=t.parentNode}},_handleDOMEvent:function(t){var e,i=t.target||t.srcElement;!this._loaded||i._leaflet_disable_events||"click"===t.type&&this._isClickDisabled(i)||("mousedown"===(e=t.type)&&Me(i),this._fireDOMEvent(t,e))},_mouseEvents:["click","dblclick","mouseover","mouseout","contextmenu"],_fireDOMEvent:function(t,e,i){"click"===t.type&&((a=l({},t)).type="preclick",this._fireDOMEvent(a,a.type,i));var n=this._findEventTargets(t,e);if(i){for(var o=[],s=0;sthis.options.zoomAnimationThreshold)return!1;var n=this.getZoomScale(e),n=this._getCenterOffset(t)._divideBy(1-1/n);if(!0!==i.animate&&!this.getSize().contains(n))return!1;x(function(){this._moveStart(!0,i.noMoveStart||!1)._animateZoom(t,e,!0)},this)}return!0},_animateZoom:function(t,e,i,n){this._mapPane&&(i&&(this._animatingZoom=!0,this._animateToCenter=t,this._animateToZoom=e,M(this._mapPane,"leaflet-zoom-anim")),this.fire("zoomanim",{center:t,zoom:e,noUpdate:n}),this._tempFireZoomEvent||(this._tempFireZoomEvent=this._zoom!==this._animateToZoom),this._move(this._animateToCenter,this._animateToZoom,void 0,!0),setTimeout(a(this._onZoomTransitionEnd,this),250))},_onZoomTransitionEnd:function(){this._animatingZoom&&(this._mapPane&&z(this._mapPane,"leaflet-zoom-anim"),this._animatingZoom=!1,this._move(this._animateToCenter,this._animateToZoom,void 0,!0),this._tempFireZoomEvent&&this.fire("zoom"),delete this._tempFireZoomEvent,this.fire("move"),this._moveEnd(!0))}});function Ue(t){return new B(t)}var B=et.extend({options:{position:"topright"},initialize:function(t){c(this,t)},getPosition:function(){return this.options.position},setPosition:function(t){var e=this._map;return e&&e.removeControl(this),this.options.position=t,e&&e.addControl(this),this},getContainer:function(){return this._container},addTo:function(t){this.remove(),this._map=t;var e=this._container=this.onAdd(t),i=this.getPosition(),t=t._controlCorners[i];return M(e,"leaflet-control"),-1!==i.indexOf("bottom")?t.insertBefore(e,t.firstChild):t.appendChild(e),this._map.on("unload",this.remove,this),this},remove:function(){return this._map&&(T(this._container),this.onRemove&&this.onRemove(this._map),this._map.off("unload",this.remove,this),this._map=null),this},_refocusOnMap:function(t){this._map&&t&&0",e=document.createElement("div");return e.innerHTML=t,e.firstChild},_addItem:function(t){var e,i=document.createElement("label"),n=this._map.hasLayer(t.layer),n=(t.overlay?((e=document.createElement("input")).type="checkbox",e.className="leaflet-control-layers-selector",e.defaultChecked=n):e=this._createRadioElement("leaflet-base-layers_"+h(this),n),this._layerControlInputs.push(e),e.layerId=h(t.layer),S(e,"click",this._onInputClick,this),document.createElement("span")),o=(n.innerHTML=" "+t.name,document.createElement("span"));return i.appendChild(o),o.appendChild(e),o.appendChild(n),(t.overlay?this._overlaysList:this._baseLayersList).appendChild(i),this._checkDisabledLayers(),i},_onInputClick:function(){if(!this._preventClick){var t,e,i=this._layerControlInputs,n=[],o=[];this._handlingClick=!0;for(var s=i.length-1;0<=s;s--)t=i[s],e=this._getLayer(t.layerId).layer,t.checked?n.push(e):t.checked||o.push(e);for(s=0;se.options.maxZoom},_expandIfNotCollapsed:function(){return this._map&&!this.options.collapsed&&this.expand(),this},_expandSafely:function(){var t=this._section,e=(this._preventClick=!0,S(t,"click",O),this.expand(),this);setTimeout(function(){k(t,"click",O),e._preventClick=!1})}})),qe=B.extend({options:{position:"topleft",zoomInText:'',zoomInTitle:"Zoom in",zoomOutText:'',zoomOutTitle:"Zoom out"},onAdd:function(t){var e="leaflet-control-zoom",i=P("div",e+" leaflet-bar"),n=this.options;return this._zoomInButton=this._createButton(n.zoomInText,n.zoomInTitle,e+"-in",i,this._zoomIn),this._zoomOutButton=this._createButton(n.zoomOutText,n.zoomOutTitle,e+"-out",i,this._zoomOut),this._updateDisabled(),t.on("zoomend zoomlevelschange",this._updateDisabled,this),i},onRemove:function(t){t.off("zoomend zoomlevelschange",this._updateDisabled,this)},disable:function(){return this._disabled=!0,this._updateDisabled(),this},enable:function(){return this._disabled=!1,this._updateDisabled(),this},_zoomIn:function(t){!this._disabled&&this._map._zoomthis._map.getMinZoom()&&this._map.zoomOut(this._map.options.zoomDelta*(t.shiftKey?3:1))},_createButton:function(t,e,i,n,o){i=P("a",i,n);return i.innerHTML=t,i.href="#",i.title=e,i.setAttribute("role","button"),i.setAttribute("aria-label",e),Ie(i),S(i,"click",Re),S(i,"click",o,this),S(i,"click",this._refocusOnMap,this),i},_updateDisabled:function(){var t=this._map,e="leaflet-disabled";z(this._zoomInButton,e),z(this._zoomOutButton,e),this._zoomInButton.setAttribute("aria-disabled","false"),this._zoomOutButton.setAttribute("aria-disabled","false"),!this._disabled&&t._zoom!==t.getMinZoom()||(M(this._zoomOutButton,e),this._zoomOutButton.setAttribute("aria-disabled","true")),!this._disabled&&t._zoom!==t.getMaxZoom()||(M(this._zoomInButton,e),this._zoomInButton.setAttribute("aria-disabled","true"))}}),Ge=(A.mergeOptions({zoomControl:!0}),A.addInitHook(function(){this.options.zoomControl&&(this.zoomControl=new qe,this.addControl(this.zoomControl))}),B.extend({options:{position:"bottomleft",maxWidth:100,metric:!0,imperial:!0},onAdd:function(t){var e="leaflet-control-scale",i=P("div",e),n=this.options;return this._addScales(n,e+"-line",i),t.on(n.updateWhenIdle?"moveend":"move",this._update,this),t.whenReady(this._update,this),i},onRemove:function(t){t.off(this.options.updateWhenIdle?"moveend":"move",this._update,this)},_addScales:function(t,e,i){t.metric&&(this._mScale=P("div",e,i)),t.imperial&&(this._iScale=P("div",e,i))},_update:function(){var t=this._map,e=t.getSize().y/2,t=t.distance(t.containerPointToLatLng([0,e]),t.containerPointToLatLng([this.options.maxWidth,e]));this._updateScales(t)},_updateScales:function(t){this.options.metric&&t&&this._updateMetric(t),this.options.imperial&&t&&this._updateImperial(t)},_updateMetric:function(t){var e=this._getRoundNum(t);this._updateScale(this._mScale,e<1e3?e+" m":e/1e3+" km",e/t)},_updateImperial:function(t){var e,i,t=3.2808399*t;5280'+(b.inlineSvg?' ':"")+"Leaflet"},initialize:function(t){c(this,t),this._attributions={}},onAdd:function(t){for(var e in(t.attributionControl=this)._container=P("div","leaflet-control-attribution"),Ie(this._container),t._layers)t._layers[e].getAttribution&&this.addAttribution(t._layers[e].getAttribution());return this._update(),t.on("layeradd",this._addAttribution,this),this._container},onRemove:function(t){t.off("layeradd",this._addAttribution,this)},_addAttribution:function(t){t.layer.getAttribution&&(this.addAttribution(t.layer.getAttribution()),t.layer.once("remove",function(){this.removeAttribution(t.layer.getAttribution())},this))},setPrefix:function(t){return this.options.prefix=t,this._update(),this},addAttribution:function(t){return t&&(this._attributions[t]||(this._attributions[t]=0),this._attributions[t]++,this._update()),this},removeAttribution:function(t){return t&&this._attributions[t]&&(this._attributions[t]--,this._update()),this},_update:function(){if(this._map){var t,e=[];for(t in this._attributions)this._attributions[t]&&e.push(t);var i=[];this.options.prefix&&i.push(this.options.prefix),e.length&&i.push(e.join(", ")),this._container.innerHTML=i.join(' ')}}}),n=(A.mergeOptions({attributionControl:!0}),A.addInitHook(function(){this.options.attributionControl&&(new Ke).addTo(this)}),B.Layers=Ve,B.Zoom=qe,B.Scale=Ge,B.Attribution=Ke,Ue.layers=function(t,e,i){return new Ve(t,e,i)},Ue.zoom=function(t){return new qe(t)},Ue.scale=function(t){return new Ge(t)},Ue.attribution=function(t){return new Ke(t)},et.extend({initialize:function(t){this._map=t},enable:function(){return this._enabled||(this._enabled=!0,this.addHooks()),this},disable:function(){return this._enabled&&(this._enabled=!1,this.removeHooks()),this},enabled:function(){return!!this._enabled}})),ft=(n.addTo=function(t,e){return t.addHandler(e,this),this},{Events:e}),Ye=b.touch?"touchstart mousedown":"mousedown",Xe=it.extend({options:{clickTolerance:3},initialize:function(t,e,i,n){c(this,n),this._element=t,this._dragStartTarget=e||t,this._preventOutline=i},enable:function(){this._enabled||(S(this._dragStartTarget,Ye,this._onDown,this),this._enabled=!0)},disable:function(){this._enabled&&(Xe._dragging===this&&this.finishDrag(!0),k(this._dragStartTarget,Ye,this._onDown,this),this._enabled=!1,this._moved=!1)},_onDown:function(t){var e,i;this._enabled&&(this._moved=!1,ve(this._element,"leaflet-zoom-anim")||(t.touches&&1!==t.touches.length?Xe._dragging===this&&this.finishDrag():Xe._dragging||t.shiftKey||1!==t.which&&1!==t.button&&!t.touches||((Xe._dragging=this)._preventOutline&&Me(this._element),Le(),re(),this._moving||(this.fire("down"),i=t.touches?t.touches[0]:t,e=Ce(this._element),this._startPoint=new p(i.clientX,i.clientY),this._startPos=Pe(this._element),this._parentScale=Ze(e),i="mousedown"===t.type,S(document,i?"mousemove":"touchmove",this._onMove,this),S(document,i?"mouseup":"touchend touchcancel",this._onUp,this)))))},_onMove:function(t){var e;this._enabled&&(t.touches&&1e&&(i.push(t[n]),o=n);oe.max.x&&(i|=2),t.ye.max.y&&(i|=8),i}function ri(t,e,i,n){var o=e.x,e=e.y,s=i.x-o,r=i.y-e,a=s*s+r*r;return 0this._layersMaxZoom&&this.setZoom(this._layersMaxZoom),void 0===this.options.minZoom&&this._layersMinZoom&&this.getZoom()t.y!=n.y>t.y&&t.x<(n.x-i.x)*(t.y-i.y)/(n.y-i.y)+i.x&&(l=!l);return l||yi.prototype._containsPoint.call(this,t,!0)}});var wi=ci.extend({initialize:function(t,e){c(this,e),this._layers={},t&&this.addData(t)},addData:function(t){var e,i,n,o=d(t)?t:t.features;if(o){for(e=0,i=o.length;es.x&&(r=i.x+a-s.x+o.x),i.x-r-n.x<(a=0)&&(r=i.x-n.x),i.y+e+o.y>s.y&&(a=i.y+e-s.y+o.y),i.y-a-n.y<0&&(a=i.y-n.y),(r||a)&&(this.options.keepInView&&(this._autopanning=!0),t.fire("autopanstart").panBy([r,a]))))},_getAnchor:function(){return m(this._source&&this._source._getPopupAnchor?this._source._getPopupAnchor():[0,0])}})),Ii=(A.mergeOptions({closePopupOnClick:!0}),A.include({openPopup:function(t,e,i){return this._initOverlay(Bi,t,e,i).openOn(this),this},closePopup:function(t){return(t=arguments.length?t:this._popup)&&t.close(),this}}),o.include({bindPopup:function(t,e){return this._popup=this._initOverlay(Bi,this._popup,t,e),this._popupHandlersAdded||(this.on({click:this._openPopup,keypress:this._onKeyPress,remove:this.closePopup,move:this._movePopup}),this._popupHandlersAdded=!0),this},unbindPopup:function(){return this._popup&&(this.off({click:this._openPopup,keypress:this._onKeyPress,remove:this.closePopup,move:this._movePopup}),this._popupHandlersAdded=!1,this._popup=null),this},openPopup:function(t){return this._popup&&(this instanceof ci||(this._popup._source=this),this._popup._prepareOpen(t||this._latlng)&&this._popup.openOn(this._map)),this},closePopup:function(){return this._popup&&this._popup.close(),this},togglePopup:function(){return this._popup&&this._popup.toggle(this),this},isPopupOpen:function(){return!!this._popup&&this._popup.isOpen()},setPopupContent:function(t){return this._popup&&this._popup.setContent(t),this},getPopup:function(){return this._popup},_openPopup:function(t){var e;this._popup&&this._map&&(Re(t),e=t.layer||t.target,this._popup._source!==e||e instanceof fi?(this._popup._source=e,this.openPopup(t.latlng)):this._map.hasLayer(this._popup)?this.closePopup():this.openPopup(t.latlng))},_movePopup:function(t){this._popup.setLatLng(t.latlng)},_onKeyPress:function(t){13===t.originalEvent.keyCode&&this._openPopup(t)}}),Ai.extend({options:{pane:"tooltipPane",offset:[0,0],direction:"auto",permanent:!1,sticky:!1,opacity:.9},onAdd:function(t){Ai.prototype.onAdd.call(this,t),this.setOpacity(this.options.opacity),t.fire("tooltipopen",{tooltip:this}),this._source&&(this.addEventParent(this._source),this._source.fire("tooltipopen",{tooltip:this},!0))},onRemove:function(t){Ai.prototype.onRemove.call(this,t),t.fire("tooltipclose",{tooltip:this}),this._source&&(this.removeEventParent(this._source),this._source.fire("tooltipclose",{tooltip:this},!0))},getEvents:function(){var t=Ai.prototype.getEvents.call(this);return this.options.permanent||(t.preclick=this.close),t},_initLayout:function(){var t="leaflet-tooltip "+(this.options.className||"")+" leaflet-zoom-"+(this._zoomAnimated?"animated":"hide");this._contentNode=this._container=P("div",t),this._container.setAttribute("role","tooltip"),this._container.setAttribute("id","leaflet-tooltip-"+h(this))},_updateLayout:function(){},_adjustPan:function(){},_setPosition:function(t){var e,i=this._map,n=this._container,o=i.latLngToContainerPoint(i.getCenter()),i=i.layerPointToContainerPoint(t),s=this.options.direction,r=n.offsetWidth,a=n.offsetHeight,h=m(this.options.offset),l=this._getAnchor(),i="top"===s?(e=r/2,a):"bottom"===s?(e=r/2,0):(e="center"===s?r/2:"right"===s?0:"left"===s?r:i.xthis.options.maxZoom||nthis.options.maxZoom||void 0!==this.options.minZoom&&oi.max.x)||!e.wrapLat&&(t.yi.max.y))return!1}return!this.options.bounds||(e=this._tileCoordsToBounds(t),g(this.options.bounds).overlaps(e))},_keyToBounds:function(t){return this._tileCoordsToBounds(this._keyToTileCoords(t))},_tileCoordsToNwSe:function(t){var e=this._map,i=this.getTileSize(),n=t.scaleBy(i),i=n.add(i);return[e.unproject(n,t.z),e.unproject(i,t.z)]},_tileCoordsToBounds:function(t){t=this._tileCoordsToNwSe(t),t=new s(t[0],t[1]);return t=this.options.noWrap?t:this._map.wrapLatLngBounds(t)},_tileCoordsToKey:function(t){return t.x+":"+t.y+":"+t.z},_keyToTileCoords:function(t){var t=t.split(":"),e=new p(+t[0],+t[1]);return e.z=+t[2],e},_removeTile:function(t){var e=this._tiles[t];e&&(T(e.el),delete this._tiles[t],this.fire("tileunload",{tile:e.el,coords:this._keyToTileCoords(t)}))},_initTile:function(t){M(t,"leaflet-tile");var e=this.getTileSize();t.style.width=e.x+"px",t.style.height=e.y+"px",t.onselectstart=u,t.onmousemove=u,b.ielt9&&this.options.opacity<1&&C(t,this.options.opacity)},_addTile:function(t,e){var i=this._getTilePos(t),n=this._tileCoordsToKey(t),o=this.createTile(this._wrapCoords(t),a(this._tileReady,this,t));this._initTile(o),this.createTile.length<2&&x(a(this._tileReady,this,t,null,o)),Z(o,i),this._tiles[n]={el:o,coords:t,current:!0},e.appendChild(o),this.fire("tileloadstart",{tile:o,coords:t})},_tileReady:function(t,e,i){e&&this.fire("tileerror",{error:e,tile:i,coords:t});var n=this._tileCoordsToKey(t);(i=this._tiles[n])&&(i.loaded=+new Date,this._map._fadeAnimated?(C(i.el,0),r(this._fadeFrame),this._fadeFrame=x(this._updateOpacity,this)):(i.active=!0,this._pruneTiles()),e||(M(i.el,"leaflet-tile-loaded"),this.fire("tileload",{tile:i.el,coords:t})),this._noTilesToLoad()&&(this._loading=!1,this.fire("load"),b.ielt9||!this._map._fadeAnimated?x(this._pruneTiles,this):setTimeout(a(this._pruneTiles,this),250)))},_getTilePos:function(t){return t.scaleBy(this.getTileSize()).subtract(this._level.origin)},_wrapCoords:function(t){var e=new p(this._wrapX?H(t.x,this._wrapX):t.x,this._wrapY?H(t.y,this._wrapY):t.y);return e.z=t.z,e},_pxBoundsToTileRange:function(t){var e=this.getTileSize();return new f(t.min.unscaleBy(e).floor(),t.max.unscaleBy(e).ceil().subtract([1,1]))},_noTilesToLoad:function(){for(var t in this._tiles)if(!this._tiles[t].loaded)return!1;return!0}});var Di=Ni.extend({options:{minZoom:0,maxZoom:18,subdomains:"abc",errorTileUrl:"",zoomOffset:0,tms:!1,zoomReverse:!1,detectRetina:!1,crossOrigin:!1,referrerPolicy:!1},initialize:function(t,e){this._url=t,(e=c(this,e)).detectRetina&&b.retina&&0')}}catch(t){}return function(t){return document.createElement("<"+t+' xmlns="urn:schemas-microsoft.com:vml" class="lvml">')}}(),zt={_initContainer:function(){this._container=P("div","leaflet-vml-container")},_update:function(){this._map._animatingZoom||(Wi.prototype._update.call(this),this.fire("update"))},_initPath:function(t){var e=t._container=Vi("shape");M(e,"leaflet-vml-shape "+(this.options.className||"")),e.coordsize="1 1",t._path=Vi("path"),e.appendChild(t._path),this._updateStyle(t),this._layers[h(t)]=t},_addPath:function(t){var e=t._container;this._container.appendChild(e),t.options.interactive&&t.addInteractiveTarget(e)},_removePath:function(t){var e=t._container;T(e),t.removeInteractiveTarget(e),delete this._layers[h(t)]},_updateStyle:function(t){var e=t._stroke,i=t._fill,n=t.options,o=t._container;o.stroked=!!n.stroke,o.filled=!!n.fill,n.stroke?(e=e||(t._stroke=Vi("stroke")),o.appendChild(e),e.weight=n.weight+"px",e.color=n.color,e.opacity=n.opacity,n.dashArray?e.dashStyle=d(n.dashArray)?n.dashArray.join(" "):n.dashArray.replace(/( *, *)/g," "):e.dashStyle="",e.endcap=n.lineCap.replace("butt","flat"),e.joinstyle=n.lineJoin):e&&(o.removeChild(e),t._stroke=null),n.fill?(i=i||(t._fill=Vi("fill")),o.appendChild(i),i.color=n.fillColor||n.color,i.opacity=n.fillOpacity):i&&(o.removeChild(i),t._fill=null)},_updateCircle:function(t){var e=t._point.round(),i=Math.round(t._radius),n=Math.round(t._radiusY||i);this._setPath(t,t._empty()?"M0 0":"AL "+e.x+","+e.y+" "+i+","+n+" 0,23592600")},_setPath:function(t,e){t._path.v=e},_bringToFront:function(t){fe(t._container)},_bringToBack:function(t){ge(t._container)}},qi=b.vml?Vi:ct,Gi=Wi.extend({_initContainer:function(){this._container=qi("svg"),this._container.setAttribute("pointer-events","none"),this._rootGroup=qi("g"),this._container.appendChild(this._rootGroup)},_destroyContainer:function(){T(this._container),k(this._container),delete this._container,delete this._rootGroup,delete this._svgSize},_update:function(){var t,e,i;this._map._animatingZoom&&this._bounds||(Wi.prototype._update.call(this),e=(t=this._bounds).getSize(),i=this._container,this._svgSize&&this._svgSize.equals(e)||(this._svgSize=e,i.setAttribute("width",e.x),i.setAttribute("height",e.y)),Z(i,t.min),i.setAttribute("viewBox",[t.min.x,t.min.y,e.x,e.y].join(" ")),this.fire("update"))},_initPath:function(t){var e=t._path=qi("path");t.options.className&&M(e,t.options.className),t.options.interactive&&M(e,"leaflet-interactive"),this._updateStyle(t),this._layers[h(t)]=t},_addPath:function(t){this._rootGroup||this._initContainer(),this._rootGroup.appendChild(t._path),t.addInteractiveTarget(t._path)},_removePath:function(t){T(t._path),t.removeInteractiveTarget(t._path),delete this._layers[h(t)]},_updatePath:function(t){t._project(),t._update()},_updateStyle:function(t){var e=t._path,t=t.options;e&&(t.stroke?(e.setAttribute("stroke",t.color),e.setAttribute("stroke-opacity",t.opacity),e.setAttribute("stroke-width",t.weight),e.setAttribute("stroke-linecap",t.lineCap),e.setAttribute("stroke-linejoin",t.lineJoin),t.dashArray?e.setAttribute("stroke-dasharray",t.dashArray):e.removeAttribute("stroke-dasharray"),t.dashOffset?e.setAttribute("stroke-dashoffset",t.dashOffset):e.removeAttribute("stroke-dashoffset")):e.setAttribute("stroke","none"),t.fill?(e.setAttribute("fill",t.fillColor||t.color),e.setAttribute("fill-opacity",t.fillOpacity),e.setAttribute("fill-rule",t.fillRule||"evenodd")):e.setAttribute("fill","none"))},_updatePoly:function(t,e){this._setPath(t,dt(t._parts,e))},_updateCircle:function(t){var e=t._point,i=Math.max(Math.round(t._radius),1),n="a"+i+","+(Math.max(Math.round(t._radiusY),1)||i)+" 0 1,0 ",e=t._empty()?"M0 0":"M"+(e.x-i)+","+e.y+n+2*i+",0 "+n+2*-i+",0 ";this._setPath(t,e)},_setPath:function(t,e){t._path.setAttribute("d",e)},_bringToFront:function(t){fe(t._path)},_bringToBack:function(t){ge(t._path)}});function Ki(t){return b.svg||b.vml?new Gi(t):null}b.vml&&Gi.include(zt),A.include({getRenderer:function(t){t=(t=t.options.renderer||this._getPaneRenderer(t.options.pane)||this.options.renderer||this._renderer)||(this._renderer=this._createRenderer());return this.hasLayer(t)||this.addLayer(t),t},_getPaneRenderer:function(t){var e;return"overlayPane"!==t&&void 0!==t&&(void 0===(e=this._paneRenderers[t])&&(e=this._createRenderer({pane:t}),this._paneRenderers[t]=e),e)},_createRenderer:function(t){return this.options.preferCanvas&&Ui(t)||Ki(t)}});var Yi=xi.extend({initialize:function(t,e){xi.prototype.initialize.call(this,this._boundsToLatLngs(t),e)},setBounds:function(t){return this.setLatLngs(this._boundsToLatLngs(t))},_boundsToLatLngs:function(t){return[(t=g(t)).getSouthWest(),t.getNorthWest(),t.getNorthEast(),t.getSouthEast()]}});Gi.create=qi,Gi.pointsToPath=dt,wi.geometryToLayer=bi,wi.coordsToLatLng=Li,wi.coordsToLatLngs=Ti,wi.latLngToCoords=Mi,wi.latLngsToCoords=zi,wi.getFeature=Ci,wi.asFeature=Zi,A.mergeOptions({boxZoom:!0});var _t=n.extend({initialize:function(t){this._map=t,this._container=t._container,this._pane=t._panes.overlayPane,this._resetStateTimeout=0,t.on("unload",this._destroy,this)},addHooks:function(){S(this._container,"mousedown",this._onMouseDown,this)},removeHooks:function(){k(this._container,"mousedown",this._onMouseDown,this)},moved:function(){return this._moved},_destroy:function(){T(this._pane),delete this._pane},_resetState:function(){this._resetStateTimeout=0,this._moved=!1},_clearDeferredResetState:function(){0!==this._resetStateTimeout&&(clearTimeout(this._resetStateTimeout),this._resetStateTimeout=0)},_onMouseDown:function(t){if(!t.shiftKey||1!==t.which&&1!==t.button)return!1;this._clearDeferredResetState(),this._resetState(),re(),Le(),this._startPoint=this._map.mouseEventToContainerPoint(t),S(document,{contextmenu:Re,mousemove:this._onMouseMove,mouseup:this._onMouseUp,keydown:this._onKeyDown},this)},_onMouseMove:function(t){this._moved||(this._moved=!0,this._box=P("div","leaflet-zoom-box",this._container),M(this._container,"leaflet-crosshair"),this._map.fire("boxzoomstart")),this._point=this._map.mouseEventToContainerPoint(t);var t=new f(this._point,this._startPoint),e=t.getSize();Z(this._box,t.min),this._box.style.width=e.x+"px",this._box.style.height=e.y+"px"},_finish:function(){this._moved&&(T(this._box),z(this._container,"leaflet-crosshair")),ae(),Te(),k(document,{contextmenu:Re,mousemove:this._onMouseMove,mouseup:this._onMouseUp,keydown:this._onKeyDown},this)},_onMouseUp:function(t){1!==t.which&&1!==t.button||(this._finish(),this._moved&&(this._clearDeferredResetState(),this._resetStateTimeout=setTimeout(a(this._resetState,this),0),t=new s(this._map.containerPointToLatLng(this._startPoint),this._map.containerPointToLatLng(this._point)),this._map.fitBounds(t).fire("boxzoomend",{boxZoomBounds:t})))},_onKeyDown:function(t){27===t.keyCode&&(this._finish(),this._clearDeferredResetState(),this._resetState())}}),Ct=(A.addInitHook("addHandler","boxZoom",_t),A.mergeOptions({doubleClickZoom:!0}),n.extend({addHooks:function(){this._map.on("dblclick",this._onDoubleClick,this)},removeHooks:function(){this._map.off("dblclick",this._onDoubleClick,this)},_onDoubleClick:function(t){var e=this._map,i=e.getZoom(),n=e.options.zoomDelta,i=t.originalEvent.shiftKey?i-n:i+n;"center"===e.options.doubleClickZoom?e.setZoom(i):e.setZoomAround(t.containerPoint,i)}})),Zt=(A.addInitHook("addHandler","doubleClickZoom",Ct),A.mergeOptions({dragging:!0,inertia:!0,inertiaDeceleration:3400,inertiaMaxSpeed:1/0,easeLinearity:.2,worldCopyJump:!1,maxBoundsViscosity:0}),n.extend({addHooks:function(){var t;this._draggable||(t=this._map,this._draggable=new Xe(t._mapPane,t._container),this._draggable.on({dragstart:this._onDragStart,drag:this._onDrag,dragend:this._onDragEnd},this),this._draggable.on("predrag",this._onPreDragLimit,this),t.options.worldCopyJump&&(this._draggable.on("predrag",this._onPreDragWrap,this),t.on("zoomend",this._onZoomEnd,this),t.whenReady(this._onZoomEnd,this))),M(this._map._container,"leaflet-grab leaflet-touch-drag"),this._draggable.enable(),this._positions=[],this._times=[]},removeHooks:function(){z(this._map._container,"leaflet-grab"),z(this._map._container,"leaflet-touch-drag"),this._draggable.disable()},moved:function(){return this._draggable&&this._draggable._moved},moving:function(){return this._draggable&&this._draggable._moving},_onDragStart:function(){var t,e=this._map;e._stop(),this._map.options.maxBounds&&this._map.options.maxBoundsViscosity?(t=g(this._map.options.maxBounds),this._offsetLimit=_(this._map.latLngToContainerPoint(t.getNorthWest()).multiplyBy(-1),this._map.latLngToContainerPoint(t.getSouthEast()).multiplyBy(-1).add(this._map.getSize())),this._viscosity=Math.min(1,Math.max(0,this._map.options.maxBoundsViscosity))):this._offsetLimit=null,e.fire("movestart").fire("dragstart"),e.options.inertia&&(this._positions=[],this._times=[])},_onDrag:function(t){var e,i;this._map.options.inertia&&(e=this._lastTime=+new Date,i=this._lastPos=this._draggable._absPos||this._draggable._newPos,this._positions.push(i),this._times.push(e),this._prunePositions(e)),this._map.fire("move",t).fire("drag",t)},_prunePositions:function(t){for(;1e.max.x&&(t.x=this._viscousLimit(t.x,e.max.x)),t.y>e.max.y&&(t.y=this._viscousLimit(t.y,e.max.y)),this._draggable._newPos=this._draggable._startPos.add(t))},_onPreDragWrap:function(){var t=this._worldWidth,e=Math.round(t/2),i=this._initialWorldOffset,n=this._draggable._newPos.x,o=(n-e+i)%t+e-i,n=(n+e+i)%t-e-i,t=Math.abs(o+i)e.getMaxZoom()&&1 this.setCenter( { lat: position.coords.latitude, lng: position.coords.longitude } ) ); } }, initMarkerPosition: function () { const coordinate = this.$coordinate.val(); if ( coordinate ) { const location = coordinate.split( ',' ); this.setCenter( { lat: location[ 0 ], lng: location[ 1 ] } ); const zoom = location.length > 2 ? parseInt( location[ 2 ], 10 ) : 14; this.map.setZoom( zoom ); } else if ( this.addressField ) { this.geocodeAddress( false ); } }, // Add event listeners for 'click' & 'drag' addListeners: function () { var that = this; /* * Auto change the map when there's change in address fields. * Works only for multiple address fields as single address field has autocomplete functionality. */ if ( this.addressField.split( ',' ).length > 1 ) { var geocodeAddress = that.geocodeAddress.bind( that ); var addressFields = this.addressField.split( ',' ).forEach( function ( part ) { var $field = that.findAddressField( part ); if ( null !== $field ) { $field.on( 'change', geocodeAddress ); } } ); } google.maps.event.addListener( this.map, 'click', function ( event ) { that.marker.setPosition( event.latLng ); that.updateCoordinate( event.latLng ); } ); google.maps.event.addListener( this.map, 'zoom_changed', function ( event ) { that.updateCoordinate( that.marker.getPosition() ); } ); google.maps.event.addListener( this.marker, 'drag', function ( event ) { that.updateCoordinate( event.latLng ); } ); /** * Custom event to refresh maps when in hidden divs. * @see https://developers.google.com/maps/documentation/javascript/reference ('resize' Event) */ var refresh = that.refresh.bind( this ); $( window ).on( 'rwmb_map_refresh', refresh ); // Refresh on meta box hide and show rwmb.$document.on( 'postbox-toggled', refresh ); // Refresh on sorting meta boxes $( '.meta-box-sortables' ).on( 'sortstop', refresh ); }, refresh: function () { if ( !this.map ) { return; } var zoom = this.map.getZoom(), center = this.map.getCenter(); google.maps.event.trigger( this.map, 'resize' ); this.map.setZoom( zoom ); this.map.panTo( center ); }, // Autocomplete address autocomplete: function () { var that = this, $address = this.getAddressField(); if ( null === $address ) { return; } // If Meta Box Geo Location installed. Do not run autocomplete. if ( $( '.rwmb-geo-binding' ).length ) { var geocodeAddress = that.geocodeAddress.bind( that ); $address.on( 'selected_address', geocodeAddress ); return false; } $address.autocomplete( { source: function ( request, response ) { // if add region only search in that region var options = { 'input': request.term, 'componentRestrictions': { country: that.$canvas.data( 'region' ) } }; // Change Geocode to getPlacePredictions . autocomplete.getPlacePredictions( options, function ( results ) { if ( results == null || !results.length ) { response( [ { value: '', label: i18n.no_results_string } ] ); return; } response( results.map( function ( item ) { return { label: item.description, value: item.description, placeid: item.place_id, }; } ) ); } ); }, select: function ( event, ui ) { geocoder.geocode( { 'placeId': ui.item.placeid }, function ( responses, status ) { if ( status == 'OK' ) { const latLng = new google.maps.LatLng( responses[ 0 ].geometry.location.lat(), responses[ 0 ].geometry.location.lng() ); that.setCenter( latLng ); that.updateCoordinate( latLng ); } } ); } } ); }, // Update coordinate to input field updateCoordinate: function ( latLng ) { var zoom = this.map.getZoom(); this.$coordinate.val( latLng.lat() + ',' + latLng.lng() + ',' + zoom ).trigger( 'change' ); }, // Find coordinates by address geocodeAddress: function ( notify ) { var address = this.getAddress(), that = this; if ( !address ) { return; } if ( false !== notify ) { notify = true; } geocoder.geocode( { 'address': address }, function ( results, status ) { if ( status !== google.maps.GeocoderStatus.OK ) { if ( notify ) { alert( i18n.no_results_string ); } return; } that.setCenter( results[ 0 ].geometry.location ); that.updateCoordinate( results[ 0 ].geometry.location ); } ); }, // Get the address field. getAddressField: function () { // No address field or more than 1 address fields, ignore if ( !this.addressField || this.addressField.split( ',' ).length > 1 ) { return null; } return this.findAddressField( this.addressField ); }, // Get the address value for geocoding. getAddress: function () { var that = this; return this.addressField.split( ',' ) .map( function ( part ) { part = that.findAddressField( part ); return null === part ? '' : part.val(); } ) .join( ',' ).replace( /\n/g, ',' ).replace( /,,/g, ',' ); }, // Find address field based on its name attribute. Auto search inside groups when needed. findAddressField: function ( fieldName ) { let selector = `input[name="${ fieldName }"], select[name="${ fieldName }"]`; // Not in a group. let $address = $( selector ); if ( $address.length ) { return $address; } let $groupWrapper = this.$container.closest( '.rwmb-group-clone' ); if ( ! $groupWrapper.length ) { $groupWrapper = this.$container.closest( '.rwmb-group-wrapper' ); } if ( ! $groupWrapper.length ) { return null; } selector = `input[name*="${ fieldName }"], select[name*="${ fieldName }"]`; $address = $groupWrapper.find( selector ); if ( $address.length ) { return $address; } return null; } }; function createController() { var $this = $( this ), controller = $this.data( 'mapController' ); if ( controller ) { return; } controller = new MapField( $this ); controller.init(); $this.data( 'mapController', controller ); } function init( e ) { $( e.target ).find( '.rwmb-map-field' ).each( createController ); } function restart() { $( '.rwmb-map-field' ).each( createController ); } rwmb.$document .on( 'mb_ready', init ) .on( 'clone', '.rwmb-input', restart ); } )( jQuery, document, window, google, rwmb, RWMB_Map ); ================================================ FILE: vendor/wpmetabox/meta-box/js/media.js ================================================ ( function ( $, wp, _, rwmb, i18n ) { 'use strict'; /** * Mimic the wp.template() to be able to use with raw template string intead of a DOM element. * So it can be used in the iframed editor. * * @see https://codex.wordpress.org/Javascript_Reference/wp.template * @see https://core.trac.wordpress.org/browser/trunk/src/js/_enqueues/wp/util.js#L0 */ rwmb.template = _.memoize( function ( template ) { let compiled, options = { evaluate: /<#([\s\S]+?)#>/g, interpolate: /\{\{\{([\s\S]+?)\}\}\}/g, escape: /\{\{([^\}]+?)\}\}(?!\})/g, variable: 'data' }; return function ( data ) { compiled = compiled || _.template( template, options ); return compiled( data ); }; } ); var views = rwmb.views = rwmb.views || {}, models = rwmb.models = rwmb.models || {}, media = wp.media, MediaFrame = media.view.MediaFrame, MediaCollection, Controller, MediaField, MediaList, MediaItem, MediaButton, MediaStatus, EditMedia, MediaDetails, MediaLibrary, MediaSelect; MediaCollection = Backbone.Collection.extend( { model: wp.media.model.Attachment, initialize: function ( models, options ) { this.controller = options.controller || new models.Controller; this.on( 'add remove reset', function () { var max = this.controller.get( 'maxFiles' ); this.controller.set( 'length', this.length ); this.controller.set( 'full', max > 0 && this.length >= max ); } ); }, add: function ( models, options ) { var max = this.controller.get( 'maxFiles' ), left = max - this.length; if ( ! models || ( max > 0 && left <= 0 ) ) { return this; } if ( ! models.hasOwnProperty( 'length' ) ) { models = [models]; } else if ( models instanceof media.model.Attachments ) { models = models.models; } models = _.difference( models, this.models ); if ( left > 0 ) { models = _.first( models, left ); } Backbone.Collection.prototype.add.call( this, models, options ); }, remove: function ( models, options ) { // Don't remove models if event is not fired from MB plugin. if( ! $( event.target ).closest( '.rwmb-field, [data-class="rwmb-field"]' ).length ) { return; } models = Backbone.Collection.prototype.remove.call( this, models, options ); if ( this.controller.get( 'forceDelete' ) === true ) { models = ! _.isArray( models ) ? [models] : models; _.each( models, function ( model ) { model.destroy(); } ); } }, destroyAll: function () { _.each( _.clone( this.models ), function ( model ) { model.destroy(); } ); } } ); /*** * Controller Model * Manages data of media field and media models. Most of the media views will use this to manage the media */ Controller = models.Controller = Backbone.Model.extend( { //Default options defaults: { maxFiles: 0, ids: [], mimeType: '', forceDelete: false, maxStatus: true, length: 0 }, //Initialize Controller model initialize: function () { // All numbers, no 0 ids this.set( 'ids', _.without( _.map( this.get( 'ids' ), Number ), 0, - 1 ) ); // Create items collection this.set( 'items', new MediaCollection( [], {controller: this} ) ); // Listen for destroy event on controller, delete all models when triggered this.on( 'destroy', function () { if ( this.get( 'forceDelete' ) ) { this.get( 'items' ).destroyAll(); } } ); } } ); /*** * MediaField * Sets up media field view and subviews */ MediaField = views.MediaField = Backbone.View.extend( { className: 'rwmb-media-view', initialize: function ( options ) { var that = this, fieldName = options.input.name; this.$input = $( options.input ); if ( 1 != this.$input.attr( 'data-single-image' ) ) { fieldName += '[]'; } this.controller = new Controller( _.extend( { fieldName: fieldName, ids: this.$input.val().split( ',' ) }, this.$input.data( 'options' ) ) ); // Create views this.createList(); this.createAddButton(); this.createStatus(); this.render(); this.loadInitialAttachments(); // Listen for destroy event on input this.$input.on( 'remove', function () { that.controller.destroy(); } ); var collection = this.controller.get( 'items' ); this.$input.on( 'media:reset', function() { collection.reset(); } ); collection.on( 'all', _.debounce( function() { var ids = collection.pluck( 'id' ).join( ',' ); that.$input.val( ids ).trigger( 'change', [that.$( '.rwmb-media-input' )] ); }, 500 ) ); }, loadInitialAttachments: function () { if ( ! this.$input.val() ) { return; } let items = $( '
      ' ).html( this.$input.attr( 'data-attachments' ) ).text(), models = JSON.parse( items ).map( function( attachment ) { return wp.media.model.Attachment.create( attachment ); } ); this.controller.get( 'items' ).add( models ); }, // Creates media list createList: function () { this.list = new MediaList( {controller: this.controller} ); }, // Creates button that adds media createAddButton: function () { this.addButton = new MediaButton( {controller: this.controller} ); }, // Creates status createStatus: function () { this.status = new MediaStatus( {controller: this.controller} ); }, // Render field and adds sub fields render: function () { // Empty then add parts this.$el.empty().append( this.list.el, this.status.el, this.addButton.el ); } } ); /*** * Media List * lists media */ MediaList = views.MediaList = Backbone.View.extend( { tagName: 'ul', className: 'rwmb-media-list', initialize: function ( options ) { this.controller = options.controller; this.collection = this.controller.get( 'items' ); this.itemView = options.itemView || MediaItem; this.getItemView = _.memoize( function ( item ) { var itemView = new this.itemView( { model: item, controller: this.controller } ); this.listenToItemView( itemView ); return itemView; }, function ( item ) { return item.cid; } ); this.listenTo( this.collection, 'add', this.addItemView ); this.listenTo( this.collection, 'remove', this.removeItemView ); this.listenTo( this.collection, 'reset', this.resetItemViews ); // Sort items using helper 'clone' to prevent trigger click on the image, which means reselect. this.$el.sortable( { helper : 'clone', start: function ( event, ui ) { ui.placeholder.height( ui.helper.outerHeight() ); ui.placeholder.width( ui.helper.outerWidth() ); }, update: function( event, ui ) { ui.item.find( rwmb.inputSelectors ).first().trigger( 'mb_change' ); } } ); }, listenToItemView: function ( itemView ) { this.listenTo( itemView, 'click:remove', this.removeItem ); this.listenTo( itemView, 'click:switch', this.switchItem ); this.listenTo( itemView, 'click:edit', this.editItem ); }, addItemView: function ( item ) { var index = this.collection.indexOf( item ), itemEl = this.getItemView( item ).el, $children = this.$el.children(); if ( 0 >= index ) { this.$el.prepend( itemEl ); } else if ( $children.length <= index ) { this.$el.append( itemEl ) } else { $children.eq( index - 1 ).after( itemEl ); } }, // Remove item view removeItemView: function ( item ) { this.getItemView( item ).$el.detach(); }, removeItem: function ( item ) { this.collection.remove( item ); }, resetItemViews: function( items ){ var that = this; _.each( that.models, that.removeItemView ); items.each( that.addItemView ); }, switchItem: function ( item ) { if ( this._switchFrame ) { this._switchFrame.dispose(); } this._switchFrame = new MediaSelect( { multiple: false, editing: true, library: { type: this.controller.get( 'mimeType' ) }, edit: this.collection } ); // Refresh content when frame opens this._switchFrame.on( 'open', function() { var frameContent = this._switchFrame.content.get(); if ( frameContent && frameContent.collection ) { frameContent.collection.mirroring._hasMore = true; frameContent.collection.more(); } }, this ); this._switchFrame.on( 'select', function () { var selection = this._switchFrame.state().get( 'selection' ), collection = this.collection, index = collection.indexOf( item ); if ( ! _.isEmpty( selection ) ) { collection.remove( item ); collection.add( selection, {at: index} ); } }, this ); this._switchFrame.open(); return false; }, editItem: function ( item ) { if ( this._editFrame ) { this._editFrame.dispose(); } // Trigger the media frame to open the correct item. this._editFrame = new EditMedia( { frame: 'edit-attachments', controller: { gridRouter: new wp.media.view.MediaFrame.Manage.Router() }, library: this.collection, model: item } ); this._editFrame.open(); } } ); /*** * MediaStatus view. * Show number of selected/uploaded files and number of files remain if "maxStatus" parameter is true. */ MediaStatus = views.MediaStatus = Backbone.View.extend( { tagName: 'div', className: 'rwmb-media-status', template: rwmb.template( ` <# if ( data.maxFiles > 0 ) { #> {{{ data.length }}}/{{{ data.maxFiles }}} <# if ( 1 < data.maxFiles ) { #>{{{ i18nRwmbMedia.multiple }}}<# } else {#>{{{ i18nRwmbMedia.single }}}<# } #> <# } #> ` ), initialize: function ( options ) { this.controller = options.controller; // Auto hide if maxStatus is false if ( ! this.controller.get( 'maxStatus' ) ) { this.$el.hide(); return; } // Re-render if changes happen in controller this.listenTo( this.controller.get( 'items' ), 'update', this.render ); this.listenTo( this.controller.get( 'items' ), 'reset', this.render ); // Render this.render(); }, render: function () { this.$el.html( this.template( this.controller.toJSON() ) ); } } ); /*** * Media Button * Selects and adds media to controller */ MediaButton = views.MediaButton = Backbone.View.extend( { tagName: 'div', className: 'rwmb-media-add', template: rwmb.template( `{{{ data.text }}}` ), events: { 'click .button': function () { if ( this._frame ) { this._frame.dispose(); } var maxFiles = this.controller.get( 'maxFiles' ); this._frame = new MediaSelect( { multiple: maxFiles > 1 || maxFiles <= 0 ? 'add' : false, editing: true, library: { type: this.controller.get( 'mimeType' ) }, edit: this.collection } ); // Refresh content when frame opens this._frame.on( 'open', function() { var frameContent = this._frame.content.get(); if ( frameContent && frameContent.collection ) { frameContent.collection.mirroring._hasMore = true; frameContent.collection.more(); } }, this ); this._frame.on( 'select', function () { var selection = this._frame.state().get( 'selection' ); if ( this.controller.get( 'addTo' ) === 'beginning' ) { this.collection.add( selection.models, {at: 0} ); } else { this.collection.add( selection.models ); } }, this ); this._frame.open(); } }, render: function () { this.$el.html( this.template( {text: i18n.add} ) ); return this; }, initialize: function ( options ) { this.controller = options.controller; this.collection = this.controller.get( 'items' ); // Auto hide if you reach the max number of media this.listenTo( this.controller, 'change:full', function () { this.$el.toggle( ! this.controller.get( 'full' ) ); } ); this.render(); } } ); /*** * MediaItem * View for individual media items */ MediaItem = views.MediaItem = Backbone.View.extend( { tagName: 'li', className: 'rwmb-file', template: rwmb.template( `
      <# if ( data.sizes ) { #> <# if ( data.sizes.thumbnail ) { #> <# } else { #> <# } #> <# } else { #> <# if ( data.image && data.image.src && data.image.src !== data.icon ) { #> <# } else { #> <# } #> <# } #>
      ` ), initialize: function ( options ) { this.controller = options.controller; this.collection = this.controller.get( 'items' ); this.render(); this.listenTo( this.model, 'change', this.render ); this.$el.data( 'id', this.model.cid ); }, events: { 'click .rwmb-image-overlay': function ( e ) { e.preventDefault(); this.trigger( 'click:switch', this.model ); }, 'click .rwmb-remove-media': function ( e ) { e.preventDefault(); this.trigger( 'click:remove', this.model ); }, 'click .rwmb-edit-media': function ( e ) { e.preventDefault(); this.trigger( 'click:edit', this.model ); } }, render: function () { var data = this.model.toJSON(); data.controller = this.controller.toJSON(); this.$el.html( this.template( data ) ); return this; } } ); /** * Extend media frames to make things work right */ /** * MediaDetails * Custom version of TwoColumn view to prevent all video and audio from being unset */ MediaDetails = views.MediaDetails = media.view.Attachment.Details.TwoColumn.extend( { render: function () { var that = this; media.view.Attachment.Details.prototype.render.apply( this, arguments ); this.players = this.players || []; media.mixin.unsetPlayers.call( this ); this.$( 'audio, video' ).each( function ( i, elem ) { var el = media.view.MediaDetails.prepareSrc( elem ); that.players.push( new window.MediaElementPlayer( el, media.mixin.mejsSettings ) ); } ); } } ); /** * MediaLibrary * Custom version of Library to exclude already selected media in a media frame */ MediaLibrary = media.controller.Library.extend( { defaults: _.defaults( { multiple: 'add', filterable: 'all', priority: 100, syncSelection: false }, media.controller.Library.prototype.defaults ), activate: function () { var library = this.get( 'library' ), edit = this.frame.options.edit; if ( this.editLibrary && this.editLibrary !== edit ) { library.unobserve( this.editLibrary ); } // Accepts attachments that exist in the original library and // that do not exist in gallery's library. library.validator = function ( attachment ) { return ! ! this.mirroring.get( attachment.cid ) && ! edit.get( attachment.cid ) && media.model.Selection.prototype.validator.apply( this, arguments ); }; // Reset the library to ensure that all attachments are re-added // to the collection. Do so silently, as calling `observe` will // trigger the `reset` event. library.reset( library.mirroring.models, {silent: true} ); library.observe( edit ); this.editLibrary = edit; media.controller.Library.prototype.activate.apply( this, arguments ); } } ); /** * MediaSelect * Custom version of Select media frame that uses MediaLibrary */ MediaSelect = views.MediaSelect = MediaFrame.Select.extend( { /** * Create the default states on the frame. */ createStates: function () { var options = this.options; // Add reference so we know MediaFrame belongs to MB plugin. this.$el.attr( 'data-class', 'rwmb-field' ); if ( this.options.states ) { return; } // Add the default states. this.states.add( [ // Main states. new MediaLibrary( { library: media.query( options.library ), multiple: options.multiple, priority: 20 } ) ] ); } } ); /*** * EditMedia * Custom version of EditAttachments frame to prevent all video and audio from being unset */ EditMedia = views.EditMedia = MediaFrame.EditAttachments.extend( { /** * Content region rendering callback for the `edit-metadata` mode. * * @param {Object} contentRegion Basic object with a `view` property, which * should be set with the proper region view. */ editMetadataMode: function ( contentRegion ) { contentRegion.view = new MediaDetails( { controller: this, model: this.model } ); /** * Attach a subview to display fields added via the * `attachment_fields_to_edit` filter. */ contentRegion.view.views.set( '.attachment-compat', new media.view.AttachmentCompat( { controller: this, model: this.model } ) ); }, resetRoute: function() {} } ); function initMediaField() { var $this = $( this ), view = $this.data( 'view' ); if ( view ) { return; } view = new MediaField( { input: this } ); $this.siblings( '.rwmb-media-view' ).remove(); $this.after( view.el ); $this.data( 'view', view ); } function init( e ) { $( e.target ).find( '.rwmb-file_advanced' ).each( initMediaField ); } rwmb.$document .on( 'mb_ready', init ) .on( 'clone', '.rwmb-file_advanced', initMediaField ); wp?.hooks?.addAction( 'mb_ready', 'meta-box/ready/media', ref => { init( { target: ref } ); } ); } )( jQuery, wp, _, rwmb, i18nRwmbMedia ); ================================================ FILE: vendor/wpmetabox/meta-box/js/modal.js ================================================ ( $ => { 'use strict'; const $body = $( 'body' ); const defaultOptions = { wrapper: `

      `, markupIframe: '', markupOverlay: '
      ', hideElement: '', hideElementDefault: '#adminmenumain, #wpadminbar, #wpfooter, .row-actions, .form-wrap.edit-term-notes, #screen-meta-links, .wp-heading-inline, .wp-header-end, .page-title-action', callback: null, closeModalCallback: null, isBlockEditor: false, $objectId: null, $objectDisplay: null, isEdit: false, size: 'large', }; $.fn.rwmbModal = function ( options = {} ) { options = { ...defaultOptions, ...options }; if ( $( '.rwmb-modal' ).length === 0 ) { return; } // $this is the button that opens the modal const $this = $( this ), $modal = $( '.rwmb-modal' ); let $input = $this.closest( '.rwmb-input' ); if ( $input.find( '.rwmb-clone' ).length > 0 && $this.closest( '.rwmb-clone' ).length > 0 ) { $input = $this.closest( '.rwmb-clone' ); } $this.click( function ( e ) { e.preventDefault(); $modal.attr( 'size', options.size ); $modal.find( '.rwmb-modal-title h2' ).html( $this.html() ); $modal.find( '.rwmb-modal-content' ).html( options.markupIframe.replace( '{URL}', $this.attr( 'data-url' ) ) ); $( '#rwmb-modal-iframe' ).on( 'load', function () { const $contents = $( this ).contents(); options.isBlockEditor = $contents.find( 'body' ).hasClass( 'block-editor-page' ); $contents.find( options.hideElement ).hide(); $modal.find( '.rwmb-modal-title' ).css( 'background-color', '' ); if ( options.isBlockEditor ) { $modal.find( '.rwmb-modal-title' ).css( 'background-color', '#fff' ); } $contents .find( options.hideElementDefault ).hide().end() .find( '.rwmb-modal-add-button' ).parents('.rwmb-field').hide(); $contents.find( 'html' ).css( 'padding-top', 0 ).end() .find( '#wpcontent' ).css( 'margin-left', 0 ).end() .find( 'a' ).on( 'click', e => e.preventDefault() ); if ( options.callback !== null && typeof options.callback === 'function' ) { options.callback( $modal, $contents ); } $body.addClass( 'rwmb-modal-show' ); $( '.rwmb-modal-overlay' ).fadeIn( 'medium' ).css( 'display', 'flex' ); $modal.fadeIn( 'medium' ).css( 'display', 'flex' ); return false; } ); $( '.rwmb-modal-close' ).on( 'click', function ( event ) { if ( options.closeModalCallback !== null && typeof options.closeModalCallback === 'function' ) { options.closeModalCallback( $( '#rwmb-modal-iframe' ).contents(), $input ); } $modal.fadeOut( 'medium' ); $( '.rwmb-modal-overlay' ).fadeOut( 'medium' ); $body.removeClass( 'rwmb-modal-show' ); // If not add new if ( !options.$objectId || !options.$objectDisplay ) { $( this ).off( event ); return; } // Select, select advanced, select tree. const $select = $input.find( 'select' ); if ( $select.length > 0 ) { $select.prepend( $( '